1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123 |
- /*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- using System;
- using System.Collections.Generic;
- using System.Net;
- using System.Reflection;
- using OpenMetaverse;
- using OpenMetaverse.StructuredData;
- using OpenSim.Framework;
- using OpenSim.Framework.Servers.HttpServer;
- using OpenSim.Region.Framework.Interfaces;
- using OpenSim.Region.Framework.Scenes;
- using OpenSim.Services.Interfaces;
- using log4net;
- using Nini.Config;
- using Mono.Addins;
- using Caps = OpenSim.Framework.Capabilities.Caps;
- using OSDArray = OpenMetaverse.StructuredData.OSDArray;
- using OSDMap = OpenMetaverse.StructuredData.OSDMap;
- using MethodImplOptions = System.Runtime.CompilerServices.MethodImplOptions;
- namespace OpenSim.Region.CoreModules.World.LightShare
- {
- [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EnvironmentModule")]
- public class EnvironmentModule : INonSharedRegionModule, IEnvironmentModule
- {
- private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
- private Scene m_scene = null;
- private UUID regionID = UUID.Zero;
- private bool Enabled = false;
- private IEstateModule m_estateModule;
- private IEventQueue m_eventQueue;
- private IAssetService m_assetService;
- private ILandChannel m_landChannel;
- private static ViewerEnvironment m_DefaultEnv = null;
- // 1/1 day-to-night ratio
- //private static readonly string m_defaultDayAssetID = "5646d39e-d3d7-6aff-ed71-30fc87d64a91"; // Default Daycycle
- // 3/1 day-to-night ratio
- private static readonly string m_defaultDayAssetID = "5646d39e-d3d7-6aff-ed71-30fc87d64a92"; // Default Daycycle (More Daylight)
- private static UUID m_defaultDayAssetUUID = new("5646d39e-d3d7-6aff-ed71-30fc87d64a92");
- //private static string m_defaultSkyAssetID = "3ae23978-ac82-bcf3-a9cb-ba6e52dcb9ad";
- private static UUID m_defaultSkyAssetUUID = new("3ae23978-ac82-bcf3-a9cb-ba6e52dcb9ad");
- //private static string m_defaultWaterAssetID = "59d1a851-47e7-0e5f-1ed7-6b715154f41a";
- private static UUID m_defaultWaterAssetUUID = new("59d1a851-47e7-0e5f-1ed7-6b715154f41a");
- private int m_regionEnvVersion = -1;
- private double m_framets;
- #region INonSharedRegionModule
- public void Initialise(IConfigSource source)
- {
- IConfig config = source.Configs["ClientStack.LindenCaps"];
- if (config is null)
- return;
- if (!config.GetString("Cap_EnvironmentSettings", string.Empty).Equals("localhost"))
- {
- m_log.InfoFormat("[{0}]: Module is disabled.", Name);
- return;
- }
- Enabled = true;
- m_log.InfoFormat("[{0}]: Module is enabled.", Name);
- }
- public void Close()
- {
- }
- public string Name
- {
- get { return "EnvironmentModule"; }
- }
- public Type ReplaceableInterface
- {
- get { return null; }
- }
- public void AddRegion(Scene scene)
- {
- if (!Enabled)
- return;
- scene.RegisterModuleInterface<IEnvironmentModule>(this);
- m_scene = scene;
- regionID = scene.RegionInfo.RegionID;
- }
- public void RegionLoaded(Scene scene)
- {
- if (!Enabled)
- return;
- m_estateModule = scene.RequestModuleInterface<IEstateModule>();
- if (m_estateModule is null)
- {
- Enabled = false;
- return;
- }
- m_eventQueue = m_scene.RequestModuleInterface<IEventQueue>();
- if (m_eventQueue is null)
- {
- Enabled = false;
- return;
- }
- m_assetService = m_scene.AssetService;
- if (m_assetService is null)
- {
- Enabled = false;
- return;
- }
- m_landChannel = m_scene.LandChannel;
- if (m_landChannel is null)
- {
- Enabled = false;
- return;
- }
- if (m_DefaultEnv is null)
- {
- AssetBase defEnv = m_assetService.Get(m_defaultDayAssetID);
- if(defEnv is not null)
- {
- byte[] envData = defEnv.Data;
- try
- {
- OSD oenv = OSDParser.Deserialize(envData);
- m_DefaultEnv = new ViewerEnvironment();
- m_DefaultEnv.CycleFromOSD(oenv);
- }
- catch (Exception e)
- {
- m_DefaultEnv = null;
- m_log.Warn(string.Format("[Environment {0}] failed to decode default environment asset ", m_scene.Name), e);
- }
- }
- }
- m_DefaultEnv ??= new ViewerEnvironment();
- string senv = scene.SimulationDataService.LoadRegionEnvironmentSettings(scene.RegionInfo.RegionID);
- if(!string.IsNullOrEmpty(senv))
- {
- try
- {
- OSD oenv = OSDParser.Deserialize(senv);
- ViewerEnvironment VEnv = new();
- if (oenv is OSDArray)
- {
- VEnv.FromWLOSD(oenv);
- StoreOnRegion(VEnv);
- m_log.Info($"[Environment {m_scene.Name}] migrated WindLight environment settings to EEP");
- }
- else
- {
- VEnv.FromOSD(oenv);
- }
- scene.RegionEnvironment = VEnv;
- m_regionEnvVersion = VEnv.version;
- }
- catch (Exception e)
- {
- m_log.Error($"[Environment {m_scene.Name}] failed to load initial Environment {e.Message}");
- scene.RegionEnvironment = null;
- m_regionEnvVersion = -1;
- }
- }
- else
- {
- scene.RegionEnvironment = null;
- m_regionEnvVersion = -1;
- }
- m_framets = 0;
- UpdateEnvTime();
- scene.EventManager.OnRegisterCaps += OnRegisterCaps;
- scene.EventManager.OnFrame += UpdateEnvTime;
- scene.EventManager.OnAvatarEnteringNewParcel += OnAvatarEnteringNewParcel;
- }
- public void RemoveRegion(Scene scene)
- {
- if (!Enabled)
- return;
- scene.EventManager.OnRegisterCaps -= OnRegisterCaps;
- }
- #endregion
- #region IEnvironmentModule
- public void StoreOnRegion(ViewerEnvironment VEnv)
- {
- try
- {
- if (VEnv is null)
- {
- m_scene.SimulationDataService.RemoveRegionEnvironmentSettings(regionID);
- m_scene.RegionEnvironment = null;
- m_regionEnvVersion = -1;
- }
- else
- {
- m_regionEnvVersion++;
- VEnv.version = m_regionEnvVersion;
- OSD env = VEnv.ToOSD();
- //m_scene.SimulationDataService.StoreRegionEnvironmentSettings(regionID, OSDParser.SerializeLLSDXmlString(env));
- m_scene.SimulationDataService.StoreRegionEnvironmentSettings(regionID, OSDParser.SerializeLLSDNotationFull(env));
- m_scene.RegionEnvironment = VEnv;
- }
- m_framets = 0;
- UpdateEnvTime();
- }
- catch (Exception e)
- {
- m_log.Error($"[Environment {m_scene.Name}] failed to store Environment {e.Message}");
- }
- }
- public void ResetEnvironmentSettings(UUID regionUUID)
- {
- if (!Enabled)
- return;
- StoreOnRegion(null);
- WindlightRefresh(0);
- }
- public void WindlightRefresh(int interpolate, bool forRegion = true)
- {
- List<byte[]> ls = null;
- m_scene.ForEachRootScenePresence(delegate (ScenePresence sp)
- {
- if(sp.IsInTransit || sp.IsNPC)
- return;
-
- IClientAPI client = sp.ControllingClient;
- if (!client.IsActive)
- return;
- uint vflags = client.GetViewerCaps();
- if ((vflags & 0x8000) != 0)
- {
- if (forRegion)
- m_estateModule.HandleRegionInfoRequest(client);
- }
- else if ((vflags & 0x4000) != 0)
- m_eventQueue.WindlightRefreshEvent(interpolate, client.AgentId);
- else
- {
- ls ??= MakeLightShareData();
- SendLightShare(client, ls);
- }
- });
- }
- public void WindlightRefreshForced(IScenePresence isp, int interpolate)
- {
- List<byte[]> ls = null;
- IClientAPI client = isp.ControllingClient;
- if (!client.IsActive)
- return;
- uint vflags = client.GetViewerCaps();
- if ((vflags & 0x8000) != 0)
- {
- ScenePresence sp = isp as ScenePresence;
- ILandObject lo = m_scene.LandChannel.GetLandObject(sp.AbsolutePosition.X, sp.AbsolutePosition.Y);
- if (lo is not null && lo.LandData is not null && lo.LandData.Environment is not null)
- lo.SendLandUpdateToClient(client);
- m_estateModule.HandleRegionInfoRequest(client);
- }
- else if ((vflags & 0x4000) != 0)
- m_eventQueue.WindlightRefreshEvent(interpolate, client.AgentId);
- else
- {
- ls ??= MakeLightShareData();
- SendLightShare(client, ls);
- }
- }
- public void FromLightShare(RegionLightShareData ls)
- {
- if (!Enabled)
- return;
- ViewerEnvironment VEnv = new();
- VEnv.FromLightShare(ls);
- StoreOnRegion(VEnv);
- WindlightRefresh(0);
- }
- public RegionLightShareData ToLightShare()
- {
- if (!Enabled)
- return new RegionLightShareData();
- RegionLightShareData ls = null;
- try
- {
- ViewerEnvironment VEnv = m_scene.RegionEnvironment;
- if(VEnv is not null)
- ls = VEnv.ToLightShare();
- }
- catch (Exception e)
- {
- m_log.ErrorFormat("[{0}]: Unable to convert environment to lightShare, Exception: {1} - {2}",
- Name, e.Message, e.StackTrace);
- }
- return ls ?? new RegionLightShareData();
- }
- #endregion
- #region Events
- private void OnRegisterCaps(UUID agentID, Caps caps)
- {
- // m_log.DebugFormat("[{0}]: Register capability for agentID {1} in region {2}",
- // Name, agentID, caps.RegionName);
- caps.RegisterSimpleHandler("EnvironmentSettings",
- new SimpleStreamHandler("/" + UUID.Random(), delegate (IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
- {
- processEnv(httpRequest, httpResponse, agentID);
- }));
- //Extended
- caps.RegisterSimpleHandler("ExtEnvironment",
- new SimpleStreamHandler("/" + UUID.Random(), delegate (IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
- {
- processExtEnv(httpRequest, httpResponse, agentID, caps);
- }));
- }
- #endregion
- private void processEnv(IOSHttpRequest request, IOSHttpResponse response, UUID agentID)
- {
- switch (request.HttpMethod)
- {
- case "POST":
- SetEnvironmentSettings(request, response, agentID);
- return;
- case "GET":
- GetEnvironmentSettings(response, agentID);
- return;
- default:
- {
- response.StatusCode = (int)HttpStatusCode.MethodNotAllowed;
- return;
- }
- }
- }
- private void processExtEnv(IOSHttpRequest request, IOSHttpResponse response, UUID agentID, Caps caps)
- {
- switch(request.HttpMethod)
- {
- case "PUT":
- case "POST":
- SetExtEnvironmentSettings(request, response, agentID, caps);
- return;
- case "GET":
- GetExtEnvironmentSettings(request, response, agentID);
- return;
- case "DELETE":
- DeleteExtEnvironmentSettings(request, response, agentID);
- return;
- default:
- {
- response.StatusCode = (int)HttpStatusCode.MethodNotAllowed;
- return;
- }
- }
- }
- private void DeleteExtEnvironmentSettings(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID agentID)
- {
- int parcel = -1;
- if (httpRequest.Query.Count > 0)
- {
- if (httpRequest.Query.ContainsKey("parcelid"))
- {
- _ = Int32.TryParse((string)httpRequest.Query["parcelid"], out parcel);
- }
- }
- if(parcel == -1)
- {
- StoreOnRegion(null);
- WindlightRefresh(0);
- }
- else
- {
- ILandObject land = m_scene.LandChannel.GetLandObject(parcel);
- if (land is not null && land.LandData is not null)
- {
- land.StoreEnvironment(null);
- WindlightRefresh(0, false);
- }
- }
- osUTF8 sb = LLSDxmlEncode2.Start();
- LLSDxmlEncode2.AddMap(sb);
- LLSDxmlEncode2.AddElem("messageID", UUID.Zero, sb);
- LLSDxmlEncode2.AddElem("regionID", regionID, sb);
- LLSDxmlEncode2.AddElem("success", true, sb);
- LLSDxmlEncode2.AddEndMap(sb);
- httpResponse.RawBuffer = LLSDxmlEncode2.EndToBytes(sb);
- httpResponse.StatusCode = (int)HttpStatusCode.OK;
- }
- private void GetExtEnvironmentSettings(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID agentID)
- {
- int parcelid = -1;
- if (httpRequest.Query.Count > 0)
- {
- if (httpRequest.Query.ContainsKey("parcelid"))
- {
- _ = Int32.TryParse((string)httpRequest.Query["parcelid"], out parcelid);
- }
- }
- ScenePresence sp = m_scene.GetScenePresence(agentID);
- if (sp == null)
- {
- httpResponse.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
- httpResponse.AddHeader("Retry-After", "5");
- return;
- }
- ViewerEnvironment VEnv = null;
- if (sp.Environment is not null)
- VEnv = sp.Environment;
- else if (parcelid == -1)
- VEnv = GetRegionEnvironment();
- else
- {
- if (m_scene.RegionInfo.EstateSettings.AllowEnvironmentOverride)
- {
- ILandObject land = m_scene.LandChannel.GetLandObject(parcelid);
- if(land is not null && land.LandData is not null && land.LandData.Environment is not null)
- VEnv = land.LandData.Environment;
- }
- if(VEnv is null)
- {
- OSD def = ViewerEnvironment.DefaultToOSD(regionID, parcelid);
- httpResponse.RawBuffer = OSDParser.SerializeLLSDXmlToBytes(def);
- httpResponse.StatusCode = (int)HttpStatusCode.OK;
- return;
- }
- }
- byte[] envBytes = VEnv.ToCapBytes(regionID, parcelid);
- if(envBytes is null)
- {
- osUTF8 sb = LLSDxmlEncode2.Start();
- LLSDxmlEncode2.AddArray(sb);
- LLSDxmlEncode2.AddMap(sb);
- LLSDxmlEncode2.AddElem("messageID", UUID.Zero, sb);
- LLSDxmlEncode2.AddElem("regionID", regionID, sb);
- LLSDxmlEncode2.AddEndMap(sb);
- LLSDxmlEncode2.AddEndArray(sb);
- httpResponse.RawBuffer = LLSDxmlEncode2.EndToBytes(sb);
- }
- else
- httpResponse.RawBuffer = envBytes;
- httpResponse.StatusCode = (int)HttpStatusCode.OK;
- }
- private void SetExtEnvironmentSettings(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID agentID, Caps caps)
- {
- bool success = false;
- string message = "Could not process request";
- int parcel = -1;
- int track = -1;
- osUTF8 sb = LLSDxmlEncode2.Start();
- ScenePresence sp = m_scene.GetScenePresence(agentID);
- if (sp is null || sp.IsChildAgent || sp.IsNPC)
- {
- message = "Could not locate your avatar";
- goto Error;
- }
- if (httpRequest.Query.Count > 0)
- {
- if (httpRequest.Query.ContainsKey("parcelid"))
- {
- if (!Int32.TryParse((string)httpRequest.Query["parcelid"], out parcel))
- {
- message = "Failed to decode request";
- goto Error;
- }
- }
- if (httpRequest.Query.ContainsKey("trackno"))
- {
- if (!Int32.TryParse((string)httpRequest.Query["trackno"], out track))
- {
- message = "Failed to decode request";
- goto Error;
- }
- }
- if (track != -1)
- {
- message = "Environment Track not supported";
- goto Error;
- }
- }
- ViewerEnvironment VEnv;
- ILandObject lchannel;
- if (parcel == -1)
- {
- if (!m_scene.Permissions.CanIssueEstateCommand(agentID, false))
- {
- message = "Insufficient estate permissions, settings has not been saved.";
- goto Error;
- }
- VEnv = m_scene.RegionEnvironment;
- lchannel = null;
- }
- else
- {
- lchannel = m_landChannel.GetLandObject(parcel);
- if(lchannel is null || lchannel.LandData is null)
- {
- message = "Could not locate requested parcel";
- goto Error;
- }
- if (!m_scene.Permissions.CanEditParcelProperties(agentID, lchannel, GroupPowers.AllowEnvironment, true)) // wrong
- {
- message = "No permission to change parcel environment";
- goto Error;
- }
- VEnv = lchannel.LandData.Environment;
- }
- try
- {
- OSD req = OSDParser.Deserialize(httpRequest.InputStream);
- if(req is OSDMap map)
- {
- if(map.TryGetValue("environment", out OSD env))
- {
- // need a proper clone
- VEnv ??= m_DefaultEnv.Clone();
- OSDMap evmap = env as OSDMap;
- if(evmap.TryGetValue("day_asset", out OSD tmp) && !evmap.ContainsKey("day_cycle"))
- {
- string id = tmp.AsString();
- AssetBase asset = m_assetService.Get(id);
- if(asset is null || asset.Data is null || asset.Data.Length == 0)
- {
- httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
- return;
- }
- try
- {
- OSD oenv = OSDParser.Deserialize(asset.Data);
- evmap.TryGetValue("day_name", out tmp);
- if(tmp is OSDString)
- VEnv.FromAssetOSD(tmp.AsString(), oenv);
- else
- VEnv.FromAssetOSD(null, oenv);
- }
- catch
- {
- httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
- return;
- }
- }
- else
- VEnv.FromOSD(env);
- if(lchannel is null)
- {
- StoreOnRegion(VEnv);
- m_log.InfoFormat("[{0}]: ExtEnvironment region {1} settings from agentID {2} saved",
- Name, caps.RegionName, agentID);
- }
- else
- {
- lchannel.StoreEnvironment(VEnv);
- m_log.InfoFormat("[{0}]: ExtEnvironment parcel {1} of region {2} settings from agentID {3} saved",
- Name, parcel, caps.RegionName, agentID);
- }
- WindlightRefresh(0, lchannel is null);
- success = true;
- }
- }
- else if (req is OSDArray)
- {
- VEnv = new ViewerEnvironment();
- VEnv.FromWLOSD(req);
- StoreOnRegion(VEnv);
- success = true;
- WindlightRefresh(0);
- m_log.InfoFormat("[{0}]: ExtEnvironment region {1} settings from agentID {2} saved",
- Name, caps.RegionName, agentID);
- LLSDxmlEncode2.AddMap(sb);
- LLSDxmlEncode2.AddElem("messageID", UUID.Zero, sb);
- LLSDxmlEncode2.AddElem("regionID", regionID, sb);
- LLSDxmlEncode2.AddElem("success", success, sb);
- LLSDxmlEncode2.AddEndMap(sb);
- httpResponse.RawBuffer = LLSDxmlEncode2.EndToBytes(sb);
- httpResponse.StatusCode = (int)HttpStatusCode.OK;
- return;
- }
- }
- catch (Exception e)
- {
- m_log.ErrorFormat("[{0}]: ExtEnvironment settings not saved for region {1}, Exception: {2} - {3}",
- Name, caps.RegionName, e.Message, e.StackTrace);
- success = false;
- message = String.Format("ExtEnvironment Set for region {0} has failed, settings not saved.", caps.RegionName);
- }
- Error:
- LLSDxmlEncode2.AddMap(sb);
- LLSDxmlEncode2.AddElem("success", success, sb);
- if(!success)
- LLSDxmlEncode2.AddElem("message", message, sb);
- LLSDxmlEncode2.AddEndMap(sb);
- httpResponse.RawBuffer = LLSDxmlEncode2.EndToBytes(sb);
- httpResponse.StatusCode = (int)HttpStatusCode.OK;
- }
- private void GetEnvironmentSettings(IOSHttpResponse response, UUID agentID)
- {
- // m_log.DebugFormat("[{0}]: Environment GET handle for agentID {1} in region {2}",
- // Name, agentID, caps.RegionName);
- ViewerEnvironment VEnv = null;
- ScenePresence sp = m_scene.GetScenePresence(agentID);
- if (sp is null)
- {
- response.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
- response.AddHeader("Retry-After", "5");
- return;
- }
- if (sp.Environment is not null)
- VEnv = sp.Environment;
- else
- {
- if(m_scene.RegionInfo.EstateSettings.AllowEnvironmentOverride)
- {
- ILandObject land = m_scene.LandChannel.GetLandObject(sp.AbsolutePosition.X, sp.AbsolutePosition.Y);
- if (land is not null && land.LandData is not null && land.LandData.Environment is not null)
- VEnv = land.LandData.Environment;
- }
- }
- VEnv ??= GetRegionEnvironment();
- byte[] envBytes = VEnv.ToCapWLBytes(UUID.Zero, regionID);
- if(envBytes is null)
- {
- osUTF8 sb = LLSDxmlEncode2.Start();
- LLSDxmlEncode2.AddArray(sb);
- LLSDxmlEncode2.AddMap(sb);
- LLSDxmlEncode2.AddElem("messageID", UUID.Zero, sb);
- LLSDxmlEncode2.AddElem("regionID", regionID, sb);
- LLSDxmlEncode2.AddEndMap(sb);
- LLSDxmlEncode2.AddEndArray(sb);
- response.RawBuffer = LLSDxmlEncode2.EndToBytes(sb);
- }
- else
- response.RawBuffer = envBytes;
- response.StatusCode = (int)HttpStatusCode.OK;
- }
- private void SetEnvironmentSettings(IOSHttpRequest request, IOSHttpResponse response, UUID agentID)
- {
- // m_log.DebugFormat("[{0}]: Environment SET handle from agentID {1} in region {2}",
- // Name, agentID, caps.RegionName);
- bool success = false;
- string fail_reason = "";
- if (!m_scene.Permissions.CanIssueEstateCommand(agentID, false))
- {
- fail_reason = "Insufficient estate permissions, settings has not been saved.";
- goto Error;
- }
- ScenePresence sp = m_scene.GetScenePresence(agentID);
- if (sp is null || sp.IsChildAgent || sp.IsNPC)
- {
- response.StatusCode = (int)HttpStatusCode.NotFound;
- return;
- }
- if (sp.Environment is not null)
- {
- fail_reason = "The environment you see is a forced one. Disable if on control object or tp out and back to region";
- goto Error;
- }
- ILandObject land = m_scene.LandChannel.GetLandObject(sp.AbsolutePosition.X, sp.AbsolutePosition.Y);
- if (land is not null && land.LandData is not null && land.LandData.Environment is not null)
- {
- fail_reason = "The parcel where you are has own environment set. You need a updated viewer to change environment";
- goto Error;
- }
- try
- {
- ViewerEnvironment VEnv = new();
- OSD env = OSDParser.Deserialize(request.InputStream);
- VEnv.FromWLOSD(env);
- StoreOnRegion(VEnv);
- WindlightRefresh(0);
- m_log.InfoFormat("[{0}]: New Environment settings has been saved from agentID {1} in region {2}",
- Name, agentID, m_scene.Name);
- success = true;
- }
- catch (Exception e)
- {
- m_log.ErrorFormat("[{0}]: Environment settings has not been saved for region {1}, Exception: {2} - {3}",
- Name, m_scene.Name, e.Message, e.StackTrace);
- success = false;
- fail_reason = String.Format("Environment Set for region {0} has failed, settings not saved.", m_scene.Name);
- }
- Error:
- osUTF8 sb = LLSDxmlEncode2.Start();
- LLSDxmlEncode2.AddMap(sb);
- LLSDxmlEncode2.AddElem("messageID", UUID.Zero, sb);
- LLSDxmlEncode2.AddElem("regionID", regionID, sb);
- LLSDxmlEncode2.AddElem("success", success, sb);
- if(!success)
- LLSDxmlEncode2.AddElem("fail_reason", fail_reason, sb);
- LLSDxmlEncode2.AddEndMap(sb);
- response.RawBuffer = LLSDxmlEncode2.EndToBytes(sb);
- response.StatusCode = (int)HttpStatusCode.OK;
- }
- public byte[] GetDefaultAssetData(int type)
- {
- OSD osddata;
- switch(type)
- {
- case 0:
- SkyData sky = new() { Name = "DefaultSky" };
- osddata = sky.ToOSD();
- break;
- case 1:
- WaterData water = new() { Name = "DefaultWater" };
- osddata = water.ToOSD();
- break;
- case 2:
- DayCycle day = new() { Name="New Daycycle" };
- DayCycle.TrackEntry te = new();
- WaterData dwater = new(){ Name = "DefaultWater" };
- day.waterframes["DefaultWater"] = dwater;
- te.time = 0;
- te.frameName = "DefaultWater";
- day.waterTrack.Add(te);
- SkyData dsky = new() { Name = "DefaultSky" } ;
- day.skyframes["DefaultSky"] = dsky;
- te.time = 0;
- te.frameName = "DefaultSky";
- day.skyTrack0.Add(te);
- osddata = day.ToOSD();
- break;
- default:
- return null;
- }
- return OSDParser.SerializeLLSDNotationToBytes(osddata,true);
- }
- public UUID GetDefaultAsset(int type)
- {
- return type switch
- {
- 0 => m_defaultSkyAssetUUID,
- 1 => m_defaultWaterAssetUUID,
- 2 => m_defaultDayAssetUUID,
- _ => UUID.Zero,
- };
- }
- public List<byte[]> MakeLightShareData()
- {
- if(m_scene.RegionEnvironment == null)
- return null;
- RegionLightShareData wl = ToLightShare();
- byte[] mBlock = new Byte[249];
- int pos = 0;
- wl.waterColor.ToBytes(mBlock, 0); pos += 12;
- Utils.FloatToBytes(wl.waterFogDensityExponent).CopyTo(mBlock, pos); pos += 4;
- Utils.FloatToBytes(wl.underwaterFogModifier).CopyTo(mBlock, pos); pos += 4;
- wl.reflectionWaveletScale.ToBytes(mBlock, pos); pos += 12;
- Utils.FloatToBytes(wl.fresnelScale).CopyTo(mBlock, pos); pos += 4;
- Utils.FloatToBytes(wl.fresnelOffset).CopyTo(mBlock, pos); pos += 4;
- Utils.FloatToBytes(wl.refractScaleAbove).CopyTo(mBlock, pos); pos += 4;
- Utils.FloatToBytes(wl.refractScaleBelow).CopyTo(mBlock, pos); pos += 4;
- Utils.FloatToBytes(wl.blurMultiplier).CopyTo(mBlock, pos); pos += 4;
- wl.bigWaveDirection.ToBytes(mBlock, pos); pos += 8;
- wl.littleWaveDirection.ToBytes(mBlock, pos); pos += 8;
- wl.normalMapTexture.ToBytes(mBlock, pos); pos += 16;
- wl.horizon.ToBytes(mBlock, pos); pos += 16;
- Utils.FloatToBytes(wl.hazeHorizon).CopyTo(mBlock, pos); pos += 4;
- wl.blueDensity.ToBytes(mBlock, pos); pos += 16;
- Utils.FloatToBytes(wl.hazeDensity).CopyTo(mBlock, pos); pos += 4;
- Utils.FloatToBytes(wl.densityMultiplier).CopyTo(mBlock, pos); pos += 4;
- Utils.FloatToBytes(wl.distanceMultiplier).CopyTo(mBlock, pos); pos += 4;
- wl.sunMoonColor.ToBytes(mBlock, pos); pos += 16;
- Utils.FloatToBytes(wl.sunMoonPosition).CopyTo(mBlock, pos); pos += 4;
- wl.ambient.ToBytes(mBlock, pos); pos += 16;
- Utils.FloatToBytes(wl.eastAngle).CopyTo(mBlock, pos); pos += 4;
- Utils.FloatToBytes(wl.sunGlowFocus).CopyTo(mBlock, pos); pos += 4;
- Utils.FloatToBytes(wl.sunGlowSize).CopyTo(mBlock, pos); pos += 4;
- Utils.FloatToBytes(wl.sceneGamma).CopyTo(mBlock, pos); pos += 4;
- Utils.FloatToBytes(wl.starBrightness).CopyTo(mBlock, pos); pos += 4;
- wl.cloudColor.ToBytes(mBlock, pos); pos += 16;
- wl.cloudXYDensity.ToBytes(mBlock, pos); pos += 12;
- Utils.FloatToBytes(wl.cloudCoverage).CopyTo(mBlock, pos); pos += 4;
- Utils.FloatToBytes(wl.cloudScale).CopyTo(mBlock, pos); pos += 4;
- wl.cloudDetailXYDensity.ToBytes(mBlock, pos); pos += 12;
- Utils.FloatToBytes(wl.cloudScrollX).CopyTo(mBlock, pos); pos += 4;
- Utils.FloatToBytes(wl.cloudScrollY).CopyTo(mBlock, pos); pos += 4;
- Utils.UInt16ToBytes(wl.maxAltitude).CopyTo(mBlock, pos); pos += 2;
- mBlock[pos] = Convert.ToByte(wl.cloudScrollXLock); pos++;
- mBlock[pos] = Convert.ToByte(wl.cloudScrollYLock); pos++;
- mBlock[pos] = Convert.ToByte(wl.drawClassicClouds); // pos++;
- List<byte[]> param = new() { mBlock };
- return param;
- }
- public void SendLightShare(IClientAPI client, List<byte[]> param)
- {
- if(param is null || param.Count == 0)
- client.SendGenericMessage("WindlightReset", UUID.Random(), new List<byte[]>());
- else
- client.SendGenericMessage("Windlight", UUID.Random(), param);
- }
- private void OnAvatarEnteringNewParcel(ScenePresence sp, int localLandID, UUID regionID)
- {
- if (sp.Environment is not null || sp.IsNPC)
- return;
- if (!m_scene.RegionInfo.EstateSettings.AllowEnvironmentOverride)
- return;
- IClientAPI client = sp.ControllingClient;
- uint vflags = client.GetViewerCaps();
- if((vflags & 0x8000) != 0)
- return;
- m_eventQueue.WindlightRefreshEvent(1, client.AgentId);
- }
- private void UpdateEnvTime()
- {
- double now = Util.GetTimeStamp();
- if (now - m_framets < 2.5) // this will be a conf option
- return;
- m_framets = now;
- UpdateClientsSunTime();
- }
- private void UpdateClientsSunTime()
- {
- if(m_scene.GetNumberOfClients() == 0)
- return;
- //m_log.DebugFormat("{0} {1} {2} {3}", dayFrac, eepDayFrac, wldayFrac, Util.UnixTimeSinceEpoch_uS());
- m_scene.ForEachRootScenePresence(delegate (ScenePresence sp)
- {
- if(sp.IsDeleted || sp.IsInTransit || sp.IsNPC)
- return;
- ViewerEnvironment VEnv;
- if(sp.Environment is not null)
- VEnv = sp.Environment;
- else
- VEnv = GetEnvironment(sp.AbsolutePosition.X, sp.AbsolutePosition.Y);
- float dayFrac = GetDayFractionTime(VEnv);
- IClientAPI client = sp.ControllingClient;
- uint vflags = client.GetViewerCaps();
- if ((vflags & 0x8000) != 0)
- {
- client.SendViewerTime(Vector3.Zero, dayFrac * Utils.TWO_PI);
- return;
- }
- if (dayFrac <= 0.25f)
- dayFrac += 1.5f;
- else if (dayFrac > 0.75f)
- dayFrac += 0.5f;
- else if (dayFrac >= 0.333333f)
- dayFrac = 3f * dayFrac - 1f;
- else
- dayFrac = 3f * dayFrac + 1f;
- dayFrac = Utils.Clamp(dayFrac, 0, 2f);
- dayFrac *= Utils.PI;
- client.SendViewerTime(Vector3.Zero, dayFrac);
- });
- }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
- public ViewerEnvironment GetEnvironment(Vector3 pos)
- {
- ILandObject lo = m_landChannel.GetLandObject(pos.X, pos.Y);
- if (lo != null && lo.LandData != null && lo.LandData.Environment != null)
- return lo.LandData.Environment;
- return m_scene.RegionEnvironment ?? m_DefaultEnv;
- }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
- public ViewerEnvironment GetEnvironment(float x, float y)
- {
- ILandObject lo = m_landChannel.GetLandObject(x, y);
- if (lo != null && lo.LandData != null && lo.LandData.Environment != null)
- return lo.LandData.Environment;
- return m_scene.RegionEnvironment ?? m_DefaultEnv;
- }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
- public ViewerEnvironment GetRegionEnvironment()
- {
- return m_scene.RegionEnvironment ?? m_DefaultEnv;
- }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
- public float GetDayFractionTime(ViewerEnvironment env)
- {
- double dayfrac = env.DayLength;
- dayfrac = ((Util.UnixTimeSinceEpochSecs() + env.DayOffset) % dayfrac) / dayfrac;
- return (float)Utils.Clamp(dayfrac, 0, 1);
- }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
- public float GetRegionDayFractionTime()
- {
- return GetDayFractionTime(GetRegionEnvironment());
- }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
- public int GetDayLength(ViewerEnvironment env)
- {
- return env.DayLength;
- }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
- public int GetDayOffset(ViewerEnvironment env)
- {
- return env.DayOffset;
- }
- public Vector3 GetSunDir(ViewerEnvironment env, float altitude)
- {
- env.getPositions_sundir(altitude, GetDayFractionTime(env), out Vector3 sundir);
- return sundir;
- }
- public Quaternion GetSunRot(ViewerEnvironment env, float altitude)
- {
- env.getPositions_sunrot(altitude, GetDayFractionTime(env), out Quaternion sunrot);
- return sunrot;
- }
- public Vector3 GetMoonDir(ViewerEnvironment env, float altitude)
- {
- env.getPositions_moondir(altitude, GetDayFractionTime(env), out Vector3 moondir);
- return moondir;
- }
- public Quaternion GetMoonRot(ViewerEnvironment env, float altitude)
- {
- env.getPositions_moonrot(altitude, GetDayFractionTime(env), out Quaternion moonrot);
- return moonrot;
- }
- [System.Runtime.CompilerServices.MethodImpl(MethodImplOptions.AggressiveInlining)]
- public int GetRegionDayLength()
- {
- return GetRegionEnvironment().DayLength;
- }
- [System.Runtime.CompilerServices.MethodImpl(MethodImplOptions.AggressiveInlining)]
- public int GetRegionDayOffset()
- {
- return GetRegionEnvironment().DayOffset;
- }
- [System.Runtime.CompilerServices.MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Vector3 GetRegionSunDir(float altitude)
- {
- return GetSunDir(GetRegionEnvironment(), altitude);
- }
- [System.Runtime.CompilerServices.MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Quaternion GetRegionSunRot(float altitude)
- {
- return GetSunRot(GetRegionEnvironment(), altitude);
- }
- [System.Runtime.CompilerServices.MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Vector3 GetRegionMoonDir(float altitude)
- {
- return GetMoonDir(GetRegionEnvironment(), altitude);
- }
- [System.Runtime.CompilerServices.MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Quaternion GetRegionMoonRot(float altitude)
- {
- return GetMoonRot(GetRegionEnvironment(), altitude);
- }
- [System.Runtime.CompilerServices.MethodImpl(MethodImplOptions.AggressiveInlining)]
- public int GetDayLength(Vector3 pos)
- {
- return GetEnvironment(pos.X, pos.Y).DayLength;
- }
- [System.Runtime.CompilerServices.MethodImpl(MethodImplOptions.AggressiveInlining)]
- public int GetDayOffset(Vector3 pos)
- {
- return GetEnvironment(pos.X, pos.Y).DayOffset;
- }
- [System.Runtime.CompilerServices.MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Vector3 GetSunDir(Vector3 pos)
- {
- return GetSunDir(GetEnvironment(pos.X, pos.Y), pos.Z);
- }
- [System.Runtime.CompilerServices.MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Quaternion GetSunRot(Vector3 pos)
- {
- return GetSunRot(GetEnvironment(pos.X, pos.Y), pos.Z);
- }
- [System.Runtime.CompilerServices.MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Vector3 GetMoonDir(Vector3 pos)
- {
- return GetMoonDir(GetEnvironment(pos.X, pos.Y), pos.Z);
- }
- [System.Runtime.CompilerServices.MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Quaternion GetMoonRot(Vector3 pos)
- {
- return GetMoonRot(GetEnvironment(pos.X, pos.Y), pos.Z);
- }
- }
- }
|