From e3ecf0ddbe8c7dee45ea5892811292a9ab9a02b3 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 19 Jun 2020 19:55:40 +0100 Subject: [PATCH] add LSL_Integer osReplaceAgentEnvironment(LSL_Key agentkey, LSL_Integer transition, LSL_String environment). note this is a hack, we cant do the ll* one --- OpenSim/Framework/ViewerEnvironment.cs | 9 +- .../World/LightShare/EnvironmentModule.cs | 102 +++++++++++++++--- .../Interfaces/IEnvironmentModule.cs | 3 + .../Region/Framework/Scenes/ScenePresence.cs | 25 +++++ .../Shared/Api/Implementation/OSSL_Api.cs | 47 ++++++++ .../Shared/Api/Interface/IOSSL_Api.cs | 2 + .../Shared/Api/Runtime/OSSL_Stub.cs | 4 + 7 files changed, 174 insertions(+), 18 deletions(-) diff --git a/OpenSim/Framework/ViewerEnvironment.cs b/OpenSim/Framework/ViewerEnvironment.cs index 2952f23e4b..a4c7595209 100644 --- a/OpenSim/Framework/ViewerEnvironment.cs +++ b/OpenSim/Framework/ViewerEnvironment.cs @@ -1179,18 +1179,19 @@ namespace OpenSim.Framework IsLegacy = false; } - public void CycleFromOSD(OSD osd) + public bool CycleFromOSD(OSD osd) { OSDMap map = osd as OSDMap; if (map == null) - return; + return false; if(!map.TryGetValue("type", out OSD tmp)) - return; + return false; string type = tmp.AsString(); if(type != "daycycle") - return; + return false; Cycle = new DayCycle(); Cycle.FromOSD(map); + return true; } public OSD ToOSD() diff --git a/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs b/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs index 890ab1d998..aeada96691 100644 --- a/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs +++ b/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs @@ -255,14 +255,19 @@ namespace OpenSim.Region.CoreModules.World.LightShare public void WindlightRefresh(int interpolate, bool notforparcel = true) { List ls = null; - m_scene.ForEachClient(delegate (IClientAPI client) + m_scene.ForEachRootScenePresence(delegate (ScenePresence sp) { - if(!client.IsActive) + if(sp.IsInTransit || sp.IsNPC) + return; + + IClientAPI client = sp.ControllingClient; + + if (!client.IsActive) return; uint vflags = client.GetViewerCaps(); - if (notforparcel && (vflags & 0x8000) != 0 ) + if (notforparcel && (vflags & 0x8000) != 0) m_estateModule.HandleRegionInfoRequest(client); else if ((vflags & 0x4000) != 0) @@ -270,13 +275,50 @@ namespace OpenSim.Region.CoreModules.World.LightShare else { - if(ls == null) + if (ls == null) ls = MakeLightShareData(); SendLightShare(client, ls); } }); } + public void WindlightRefresh(IScenePresence isp, int interpolate) + { + List ls = null; + + IClientAPI client = isp.ControllingClient; + + if (!client.IsActive) + return; + + uint vflags = client.GetViewerCaps(); + + if ((vflags & 0x8000) != 0) + { + ScenePresence sp = isp as ScenePresence; + if(sp.Environment != null) + m_estateModule.HandleRegionInfoRequest(client); + else + { + 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); + else + 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) @@ -397,7 +439,7 @@ namespace OpenSim.Region.CoreModules.World.LightShare if (land != null && land.LandData != null) { land.StoreEnvironment(null); - WindlightRefresh(0, false); + WindlightRefresh(0); } } @@ -422,8 +464,17 @@ namespace OpenSim.Region.CoreModules.World.LightShare } } + ScenePresence sp = m_scene.GetScenePresence(agentID); + if (sp == null || sp.IsChildAgent || sp.IsNPC) + { + httpResponse.StatusCode = (int)HttpStatusCode.NotFound; + return; + } + ViewerEnvironment VEnv; - if (parcel == -1) + if(sp.Environment != null) + VEnv = sp.Environment; + else if (parcel == -1) VEnv = GetRegionEnvironment(); else { @@ -431,7 +482,12 @@ namespace OpenSim.Region.CoreModules.World.LightShare if (land != null && land.LandData != null && land.LandData.Environment != null) VEnv = land.LandData.Environment; else - VEnv = GetRegionEnvironment(); + { + OSD def = ViewerEnvironment.DefaultToOSD(regionID, parcel); + httpResponse.RawBuffer = OSDParser.SerializeLLSDXmlToBytes(def); + httpResponse.StatusCode = (int)HttpStatusCode.OK; + return; + } } OSDMap map = new OSDMap(); @@ -496,6 +552,7 @@ namespace OpenSim.Region.CoreModules.World.LightShare } } + ViewerEnvironment VEnv = m_scene.RegionEnvironment; ILandObject lchannel; if (parcel == -1) @@ -634,11 +691,16 @@ namespace OpenSim.Region.CoreModules.World.LightShare } ViewerEnvironment VEnv; - 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 (sp.Environment != null) + VEnv = sp.Environment; else - VEnv = GetRegionEnvironment(); + { + 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; + else + VEnv = GetRegionEnvironment(); + } OSD d = VEnv.ToWLOSD(UUID.Zero, regionID); string env = OSDParser.SerializeLLSDXmlString(d); @@ -680,6 +742,12 @@ namespace OpenSim.Region.CoreModules.World.LightShare 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) { @@ -691,13 +759,14 @@ namespace OpenSim.Region.CoreModules.World.LightShare ViewerEnvironment VEnv = new ViewerEnvironment(); OSD env = OSDParser.Deserialize(request.InputStream); VEnv.FromWLOSD(env); + StoreOnRegion(VEnv); - success = true; 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) { @@ -825,12 +894,17 @@ namespace OpenSim.Region.CoreModules.World.LightShare 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; - if(m_scene.RegionInfo.EstateSettings.AllowEnvironmentOverride) - m_eventQueue.WindlightRefreshEvent(1, client.AgentId); + m_eventQueue.WindlightRefreshEvent(1, client.AgentId); } private void UpdateEnvTime() diff --git a/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs b/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs index c97391a74b..78f1a15aa0 100644 --- a/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs @@ -37,6 +37,9 @@ namespace OpenSim.Region.Framework.Interfaces RegionLightShareData ToLightShare(); byte[] GetDefaultAssetData(int type); void WindlightRefresh(int interpolate, bool notforparcel = true); + void WindlightRefresh(IScenePresence sp, int interpolate); + + ViewerEnvironment GetRegionEnvironment(); float GetRegionDayFractionTime(); int GetRegionDayLength(); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 0457f322f3..27038e11a7 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -83,6 +83,31 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat("[SCENE PRESENCE]: Destructor called on {0}", Name); // } + + public int EnvironmentVersion = -1; + private ViewerEnvironment m_environment; + public ViewerEnvironment Environment + { + get + { + return m_environment; + } + set + { + m_environment = value; + if (value == null) + EnvironmentVersion = -1; + else + { + if(EnvironmentVersion <= 0) + EnvironmentVersion = 0x7000000; + else + ++EnvironmentVersion; + m_environment.version = EnvironmentVersion; + } + } + } + public void TriggerScenePresenceUpdated() { if (m_scene != null) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index dec427896b..8e9ac56fa7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -5882,5 +5882,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { return m_host.ClearObjectAnimations(); } + + public LSL_Integer osReplaceAgentEnvironment(LSL_Key agentkey, LSL_Integer transition, LSL_String environment) + { + m_host.AddScriptLPS(1); +// if(!string.IsNullOrEmpty(CheckThreatLevelTest(ThreatLevel.Moderate, "osReplaceAgentEnvironment"))) +// return -2; + + + if (!UUID.TryParse(agentkey, out UUID agentid)) + return -4; + + ScenePresence sp = World.GetScenePresence(agentid); + if(sp == null || sp.IsChildAgent || sp.IsNPC || sp.IsInTransit) + return -4; + + if(string.IsNullOrEmpty(environment) || environment == UUID.Zero.ToString()) + { + sp.Environment = null; + m_envModule.WindlightRefresh(sp, transition); + return 1; + } + + UUID envID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, environment); + if (envID == UUID.Zero) + return -3; + + AssetBase asset = World.AssetService.Get(envID.ToString()); + if(asset == null || asset.Type != (byte)AssetType.Settings) + return -3; + // cant use stupid broken asset flags for subtype + try + { + OSD oenv = OSDParser.Deserialize(asset.Data); + ViewerEnvironment VEnv = m_envModule.GetRegionEnvironment().Clone(); + if(!VEnv.CycleFromOSD(oenv)) + return -3; + sp.Environment = VEnv; + m_envModule.WindlightRefresh(sp, transition); + } + catch + { + sp.Environment = null; + m_envModule.WindlightRefresh(sp, transition); + return -9; + } + return 1; + } } } \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index fe5f56ca0c..98143dac8f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -578,5 +578,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_String osGetApparentTimeString(LSL_Integer format24); LSL_Float osGetApparentRegionTime(); LSL_String osGetApparentRegionTimeString(LSL_Integer format24); + + LSL_Integer osReplaceAgentEnvironment(LSL_Key agentkey, LSL_Integer transition, LSL_String environment); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 981646c70d..265439fbda 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -1502,5 +1502,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osGetApparentRegionTimeString(format24); } + public LSL_Integer osReplaceAgentEnvironment(LSL_Key agentkey, LSL_Integer transition, LSL_String environment) + { + return m_OSSL_Functions.osReplaceAgentEnvironment(agentkey, transition, environment); + } } }