OpenSimMirror/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs

1127 lines
43 KiB
C#

/*
* 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 System.Text;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
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 night day ratio
//private static readonly string m_defaultDayAssetID = "5646d39e-d3d7-6aff-ed71-30fc87d64a91";
// 3/1 night day ratio
private static readonly string m_defaultDayAssetID = "5646d39e-d3d7-6aff-ed71-30fc87d64a92";
private int m_regionEnvVersion = -1;
private double m_framets;
#region INonSharedRegionModule
public void Initialise(IConfigSource source)
{
IConfig config = source.Configs["ClientStack.LindenCaps"];
if (null == config)
return;
if (config.GetString("Cap_EnvironmentSettings", String.Empty) != "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 == null)
{
Enabled = false;
return;
}
m_eventQueue = m_scene.RequestModuleInterface<IEventQueue>();
if (m_eventQueue == null)
{
Enabled = false;
return;
}
m_assetService = m_scene.AssetService;
if (m_assetService == null)
{
Enabled = false;
return;
}
m_landChannel = m_scene.LandChannel;
if (m_landChannel == null)
{
Enabled = false;
return;
}
if (m_DefaultEnv == null)
{
AssetBase defEnv = m_assetService.Get(m_defaultDayAssetID);
if(defEnv != 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.WarnFormat("[Environment {0}]: failed to decode default environment asset: {1}", m_scene.Name, e.Message);
}
}
}
if (m_DefaultEnv == null)
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 ViewerEnvironment();
if(oenv is OSDArray)
VEnv.FromWLOSD(oenv);
else
VEnv.FromOSD(oenv);
scene.RegionEnvironment = VEnv;
m_regionEnvVersion = VEnv.version;
}
catch (Exception e)
{
m_log.ErrorFormat("[Environment {0}] failed to load initial Environment {1}", m_scene.Name, 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 == 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.ErrorFormat("[Environment {0}] failed to store Environment {1}", m_scene.Name, 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
{
if (ls == null)
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 != null && lo.LandData != null && lo.LandData.Environment != null)
lo.SendLandUpdateToClient(client);
m_estateModule.HandleRegionInfoRequest(client);
}
else if ((vflags & 0x4000) != 0)
m_eventQueue.WindlightRefreshEvent(interpolate, client.AgentId);
else
{
if (ls == null)
ls = MakeLightShareData();
SendLightShare(client, ls);
}
}
public void FromLightShare(RegionLightShareData ls)
{
if (!Enabled)
return;
ViewerEnvironment VEnv = new ViewerEnvironment();
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 == null)
return new RegionLightShareData();
ls = VEnv.ToLightShare();
}
catch (Exception e)
{
m_log.ErrorFormat("[{0}]: Unable to convert environment to lightShare, Exception: {1} - {2}",
Name, e.Message, e.StackTrace);
}
if(ls == null)
return new RegionLightShareData();
return ls;
}
#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 != null && land.LandData != null)
{
land.StoreEnvironment(null);
WindlightRefresh(0, false);
}
}
StringBuilder sb = LLSDxmlEncode.Start();
LLSDxmlEncode.AddMap(sb);
LLSDxmlEncode.AddElem("messageID", UUID.Zero, sb);
LLSDxmlEncode.AddElem("regionID", regionID, sb);
LLSDxmlEncode.AddElem("success", true, sb);
LLSDxmlEncode.AddEndMap(sb);
httpResponse.RawBuffer = Util.UTF8.GetBytes(LLSDxmlEncode.End(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);
}
}
ViewerEnvironment VEnv = null;
ScenePresence sp = m_scene.GetScenePresence(agentID);
if(sp != null && sp.Environment != null)
{
if (parcelid == -1)
VEnv = sp.Environment;
else
{
OSD def = ViewerEnvironment.DefaultToOSD(regionID, parcelid);
httpResponse.RawBuffer = OSDParser.SerializeLLSDXmlToBytes(def);
httpResponse.StatusCode = (int)HttpStatusCode.OK;
return;
}
}
else if (parcelid == -1)
VEnv = GetRegionEnvironment();
else
{
if (m_scene.RegionInfo.EstateSettings.AllowEnvironmentOverride)
{
ILandObject land = m_scene.LandChannel.GetLandObject(parcelid);
if(land != null && land.LandData != null && land.LandData.Environment != null)
VEnv = land.LandData.Environment;
}
if(VEnv == null)
{
OSD def = ViewerEnvironment.DefaultToOSD(regionID, parcelid);
httpResponse.RawBuffer = OSDParser.SerializeLLSDXmlToBytes(def);
httpResponse.StatusCode = (int)HttpStatusCode.OK;
return;
}
}
OSDMap map = new OSDMap();
OSDMap cenv = (OSDMap)VEnv.ToOSD();
cenv["parcel_id"] = parcelid;
cenv["region_id"] = regionID;
map["environment"] = cenv;
map["parcel_id"] = parcelid;
map["success"] = true;
string env = OSDParser.SerializeLLSDXmlString(map);
if (String.IsNullOrEmpty(env))
{
StringBuilder sb = LLSDxmlEncode.Start();
LLSDxmlEncode.AddArray(sb);
LLSDxmlEncode.AddMap(sb);
LLSDxmlEncode.AddElem("messageID", UUID.Zero, sb);
LLSDxmlEncode.AddElem("regionID", regionID, sb);
LLSDxmlEncode.AddEndMap(sb);
LLSDxmlEncode.AddEndArray(sb);
env = LLSDxmlEncode.End(sb);
}
httpResponse.RawBuffer = Util.UTF8NBGetbytes(env);
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;
StringBuilder sb = LLSDxmlEncode.Start();
ScenePresence sp = m_scene.GetScenePresence(agentID);
if (sp == 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 = m_scene.RegionEnvironment;
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 == null || lchannel.LandData == 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 OpenMetaverse.StructuredData.OSDMap)
{
OSDMap map = req as OpenMetaverse.StructuredData.OSDMap;
if(map.TryGetValue("environment", out OSD env))
{
if (VEnv == null)
// need a proper clone
VEnv = m_DefaultEnv.Clone();
OSDMap evmap = (OSDMap)env;
if(evmap.TryGetValue("day_asset", out OSD tmp) && !evmap.ContainsKey("day_cycle"))
{
string id = tmp.AsString();
AssetBase asset = m_assetService.Get(id);
if(asset == null || asset.Data == null || asset.Data.Length == 0)
{
httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
return;
}
try
{
OSD oenv = OSDParser.Deserialize(asset.Data);
VEnv.CycleFromOSD(oenv);
}
catch
{
httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
return;
}
}
VEnv.FromOSD(env);
if(lchannel == 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 == 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);
LLSDxmlEncode.AddMap(sb);
LLSDxmlEncode.AddElem("messageID", UUID.Zero, sb);
LLSDxmlEncode.AddElem("regionID", regionID, sb);
LLSDxmlEncode.AddElem("success", success, sb);
LLSDxmlEncode.AddEndMap(sb);
httpResponse.RawBuffer = Util.UTF8NBGetbytes(LLSDxmlEncode.End(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:
string response;
LLSDxmlEncode.AddMap(sb);
LLSDxmlEncode.AddElem("success", success, sb);
if(!success)
LLSDxmlEncode.AddElem("message", message, sb);
LLSDxmlEncode.AddEndMap(sb);
response = LLSDxmlEncode.End(sb);
httpResponse.RawBuffer = Util.UTF8NBGetbytes(response);
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 != null && sp.Environment != 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 != null && land.LandData != null && land.LandData.Environment != null)
VEnv = land.LandData.Environment;
}
if(VEnv == null)
VEnv = GetRegionEnvironment();
}
OSD d = VEnv.ToWLOSD(UUID.Zero, regionID);
string env = OSDParser.SerializeLLSDXmlString(d);
if (String.IsNullOrEmpty(env))
{
StringBuilder sb = LLSDxmlEncode.Start();
LLSDxmlEncode.AddArray(sb);
LLSDxmlEncode.AddMap(sb);
LLSDxmlEncode.AddElem("messageID", UUID.Zero, sb);
LLSDxmlEncode.AddElem("regionID", regionID, sb);
LLSDxmlEncode.AddEndMap(sb);
LLSDxmlEncode.AddEndArray(sb);
env = LLSDxmlEncode.End(sb);
}
response.RawBuffer = Util.UTF8NBGetbytes(env);
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 == null || sp.IsChildAgent || sp.IsNPC)
{
response.StatusCode = (int)HttpStatusCode.NotFound;
return;
}
if (sp.Environment != 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 != null && land.LandData != null && land.LandData.Environment != 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 ViewerEnvironment();
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:
StringBuilder sb = LLSDxmlEncode.Start();
LLSDxmlEncode.AddMap(sb);
LLSDxmlEncode.AddElem("messageID", UUID.Zero, sb);
LLSDxmlEncode.AddElem("regionID", regionID, sb);
LLSDxmlEncode.AddElem("success", success, sb);
if(!success)
LLSDxmlEncode.AddElem("fail_reason", fail_reason, sb);
LLSDxmlEncode.AddEndMap(sb);
response.RawBuffer = Util.UTF8NBGetbytes(LLSDxmlEncode.End(sb));
response.StatusCode = (int)HttpStatusCode.OK;
}
public byte[] GetDefaultAssetData(int type)
{
OSD osddata;
switch(type)
{
case 0:
SkyData sky = new SkyData();
sky.Name = "DefaultSky";
osddata = sky.ToOSD();
break;
case 1:
WaterData water = new WaterData();
water.Name = "DefaultWater";
osddata = water.ToOSD();
break;
case 2:
DayCycle day = new DayCycle();
day.Name="New Daycycle";
DayCycle.TrackEntry te = new DayCycle.TrackEntry();
WaterData dwater = new WaterData();
dwater.Name = "DefaultWater";
day.waterframes["DefaultWater"] = dwater;
te.time = 0;
te.frameName = "DefaultWater";
day.waterTrack.Add(te);
SkyData dsky = new SkyData();
dsky.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 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 List<byte[]>();
param.Add(mBlock);
return param;
}
public void SendLightShare(IClientAPI client, List<byte[]> param)
{
if(param == 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 != null)
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 != 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 == null ? m_DefaultEnv : m_scene.RegionEnvironment;
}
[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 == null ? m_DefaultEnv : m_scene.RegionEnvironment;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public ViewerEnvironment GetRegionEnvironment()
{
return m_scene.RegionEnvironment == null ? m_DefaultEnv : m_scene.RegionEnvironment;
}
[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(altitude, GetDayFractionTime(env), out Vector3 sundir, out Vector3 moondir,
out Quaternion sunrot, out Quaternion moonrot);
return sundir;
}
public Quaternion GetSunRot(ViewerEnvironment env, float altitude)
{
env.getPositions(altitude, GetDayFractionTime(env), out Vector3 sundir, out Vector3 moondir,
out Quaternion sunrot, out Quaternion moonrot);
return sunrot;
}
public Vector3 GetMoonDir(ViewerEnvironment env, float altitude)
{
env.getPositions(altitude, GetDayFractionTime(env), out Vector3 sundir, out Vector3 moondir,
out Quaternion sunrot, out Quaternion moonrot);
return moondir;
}
public Quaternion GetMoonRot(ViewerEnvironment env, float altitude)
{
env.getPositions(altitude, GetDayFractionTime(env), out Vector3 sundir, out Vector3 moondir,
out Quaternion sunrot, 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);
}
}
}