aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/World/LightShare
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/World/LightShare')
-rw-r--r--OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs224
-rw-r--r--OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs297
2 files changed, 521 insertions, 0 deletions
diff --git a/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs b/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs
new file mode 100644
index 0000000..c3cea7a
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs
@@ -0,0 +1,224 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using OpenMetaverse;
31using OpenSim.Framework;
32using OpenSim.Framework.Capabilities;
33using OpenSim.Framework.Servers.HttpServer;
34using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes;
36using log4net;
37using Nini.Config;
38using Mono.Addins;
39
40using Caps = OpenSim.Framework.Capabilities.Caps;
41
42
43namespace OpenSim.Region.CoreModules.World.LightShare
44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EnvironmentModule")]
46
47 public class EnvironmentModule : INonSharedRegionModule, IEnvironmentModule
48 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 private Scene m_scene = null;
52 private UUID regionID = UUID.Zero;
53 private static bool Enabled = false;
54
55 private static readonly string capsName = "EnvironmentSettings";
56 private static readonly string capsBase = "/CAPS/0020/";
57
58 private LLSDEnvironmentSetResponse setResponse = null;
59
60 #region INonSharedRegionModule
61 public void Initialise(IConfigSource source)
62 {
63 IConfig config = source.Configs["ClientStack.LindenCaps"];
64
65 if (null == config)
66 return;
67
68 if (config.GetString("Cap_EnvironmentSettings", String.Empty) != "localhost")
69 {
70 m_log.InfoFormat("[{0}]: Module is disabled.", Name);
71 return;
72 }
73
74 Enabled = true;
75
76 m_log.InfoFormat("[{0}]: Module is enabled.", Name);
77 }
78
79 public void Close()
80 {
81 }
82
83 public string Name
84 {
85 get { return "EnvironmentModule"; }
86 }
87
88 public Type ReplaceableInterface
89 {
90 get { return null; }
91 }
92
93 public void AddRegion(Scene scene)
94 {
95 if (!Enabled)
96 return;
97
98 scene.RegisterModuleInterface<IEnvironmentModule>(this);
99 m_scene = scene;
100 regionID = scene.RegionInfo.RegionID;
101 }
102
103 public void RegionLoaded(Scene scene)
104 {
105 if (!Enabled)
106 return;
107
108 setResponse = new LLSDEnvironmentSetResponse();
109 scene.EventManager.OnRegisterCaps += OnRegisterCaps;
110 }
111
112 public void RemoveRegion(Scene scene)
113 {
114 if (Enabled)
115 return;
116
117 scene.EventManager.OnRegisterCaps -= OnRegisterCaps;
118 m_scene = null;
119 }
120 #endregion
121
122 #region IEnvironmentModule
123 public void ResetEnvironmentSettings(UUID regionUUID)
124 {
125 if (!Enabled)
126 return;
127
128 m_scene.SimulationDataService.RemoveRegionEnvironmentSettings(regionUUID);
129 }
130 #endregion
131
132 #region Events
133 private void OnRegisterCaps(UUID agentID, Caps caps)
134 {
135 // m_log.DebugFormat("[{0}]: Register capability for agentID {1} in region {2}",
136 // Name, agentID, caps.RegionName);
137
138 string capsPath = capsBase + UUID.Random();
139
140 // Get handler
141 caps.RegisterHandler(
142 capsName,
143 new RestStreamHandler(
144 "GET",
145 capsPath,
146 (request, path, param, httpRequest, httpResponse)
147 => GetEnvironmentSettings(request, path, param, agentID, caps),
148 capsName,
149 agentID.ToString()));
150
151 // Set handler
152 caps.HttpListener.AddStreamHandler(
153 new RestStreamHandler(
154 "POST",
155 capsPath,
156 (request, path, param, httpRequest, httpResponse)
157 => SetEnvironmentSettings(request, path, param, agentID, caps),
158 capsName,
159 agentID.ToString()));
160 }
161 #endregion
162
163 private string GetEnvironmentSettings(string request, string path, string param,
164 UUID agentID, Caps caps)
165 {
166 // m_log.DebugFormat("[{0}]: Environment GET handle for agentID {1} in region {2}",
167 // Name, agentID, caps.RegionName);
168
169 string env = String.Empty;
170
171 try
172 {
173 env = m_scene.SimulationDataService.LoadRegionEnvironmentSettings(regionID);
174 }
175 catch (Exception e)
176 {
177 m_log.ErrorFormat("[{0}]: Unable to load environment settings for region {1}, Exception: {2} - {3}",
178 Name, caps.RegionName, e.Message, e.StackTrace);
179 }
180
181 if (String.IsNullOrEmpty(env))
182 env = EnvironmentSettings.EmptySettings(UUID.Zero, regionID);
183
184 return env;
185 }
186
187 private string SetEnvironmentSettings(string request, string path, string param,
188 UUID agentID, Caps caps)
189 {
190
191 // m_log.DebugFormat("[{0}]: Environment SET handle from agentID {1} in region {2}",
192 // Name, agentID, caps.RegionName);
193
194 setResponse.regionID = regionID;
195 setResponse.success = false;
196
197 if (!m_scene.Permissions.CanIssueEstateCommand(agentID, false))
198 {
199 setResponse.fail_reason = "Insufficient estate permissions, settings has not been saved.";
200 return LLSDHelpers.SerialiseLLSDReply(setResponse);
201 }
202
203 try
204 {
205 m_scene.SimulationDataService.StoreRegionEnvironmentSettings(regionID, request);
206 setResponse.success = true;
207
208 m_log.InfoFormat("[{0}]: New Environment settings has been saved from agentID {1} in region {2}",
209 Name, agentID, caps.RegionName);
210 }
211 catch (Exception e)
212 {
213 m_log.ErrorFormat("[{0}]: Environment settings has not been saved for region {1}, Exception: {2} - {3}",
214 Name, caps.RegionName, e.Message, e.StackTrace);
215
216 setResponse.success = false;
217 setResponse.fail_reason = String.Format("Environment Set for region {0} has failed, settings has not been saved.", caps.RegionName);
218 }
219
220 return LLSDHelpers.SerialiseLLSDReply(setResponse);
221 }
222 }
223}
224
diff --git a/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs b/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs
new file mode 100644
index 0000000..4e20196
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs
@@ -0,0 +1,297 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Region.CoreModules.Framework.InterfaceCommander;
34using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes;
36using log4net;
37using Nini.Config;
38using Mono.Addins;
39
40namespace OpenSim.Region.CoreModules.World.LightShare
41{
42 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LightShareModule")]
43 public class LightShareModule : INonSharedRegionModule, ILightShareModule, ICommandableModule
44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 private readonly Commander m_commander = new Commander("windlight");
47 private Scene m_scene;
48 private static bool m_enableWindlight;
49
50 #region ICommandableModule Members
51
52 public ICommander CommandInterface
53 {
54 get { return m_commander; }
55 }
56
57 #endregion
58
59 #region INonSharedRegionModule Members
60
61 public void Initialise(IConfigSource config)
62 {
63 try
64 {
65 m_enableWindlight = config.Configs["LightShare"].GetBoolean("enable_windlight", false);
66 }
67 catch (Exception)
68 {
69 m_log.Debug("[WINDLIGHT]: ini failure for enable_windlight - using default");
70 }
71
72 m_log.DebugFormat("[WINDLIGHT]: windlight module {0}", (m_enableWindlight ? "enabled" : "disabled"));
73 }
74
75 public void AddRegion(Scene scene)
76 {
77 if (!m_enableWindlight)
78 return;
79
80 m_scene = scene;
81 m_scene.RegisterModuleInterface<ILightShareModule>(this);
82 m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
83
84 m_scene.EventManager.OnMakeRootAgent += EventManager_OnMakeRootAgent;
85 m_scene.EventManager.OnSaveNewWindlightProfile += EventManager_OnSaveNewWindlightProfile;
86 m_scene.EventManager.OnSendNewWindlightProfileTargeted += EventManager_OnSendNewWindlightProfileTargeted;
87 m_scene.LoadWindlightProfile();
88
89 InstallCommands();
90 }
91
92 public void RemoveRegion(Scene scene)
93 {
94 if (!m_enableWindlight)
95 return;
96
97 m_scene.EventManager.OnPluginConsole -= EventManager_OnPluginConsole;
98
99 m_scene.EventManager.OnMakeRootAgent -= EventManager_OnMakeRootAgent;
100 m_scene.EventManager.OnSaveNewWindlightProfile -= EventManager_OnSaveNewWindlightProfile;
101 m_scene.EventManager.OnSendNewWindlightProfileTargeted -= EventManager_OnSendNewWindlightProfileTargeted;
102
103 m_scene = null;
104 }
105
106 public void Close()
107 {
108 }
109
110 public string Name
111 {
112 get { return "LightShareModule"; }
113 }
114
115 public void RegionLoaded(Scene scene)
116 {
117 }
118
119 public Type ReplaceableInterface
120 {
121 get { return null; }
122 }
123
124 #endregion
125
126 public static bool EnableWindlight
127 {
128 get
129 {
130 return m_enableWindlight;
131 }
132 set
133 {
134 }
135 }
136
137 #region events
138
139 private List<byte[]> compileWindlightSettings(RegionLightShareData wl)
140 {
141 byte[] mBlock = new Byte[249];
142 int pos = 0;
143
144 wl.waterColor.ToBytes(mBlock, 0); pos += 12;
145 Utils.FloatToBytes(wl.waterFogDensityExponent).CopyTo(mBlock, pos); pos += 4;
146 Utils.FloatToBytes(wl.underwaterFogModifier).CopyTo(mBlock, pos); pos += 4;
147 wl.reflectionWaveletScale.ToBytes(mBlock, pos); pos += 12;
148 Utils.FloatToBytes(wl.fresnelScale).CopyTo(mBlock, pos); pos += 4;
149 Utils.FloatToBytes(wl.fresnelOffset).CopyTo(mBlock, pos); pos += 4;
150 Utils.FloatToBytes(wl.refractScaleAbove).CopyTo(mBlock, pos); pos += 4;
151 Utils.FloatToBytes(wl.refractScaleBelow).CopyTo(mBlock, pos); pos += 4;
152 Utils.FloatToBytes(wl.blurMultiplier).CopyTo(mBlock, pos); pos += 4;
153 wl.bigWaveDirection.ToBytes(mBlock, pos); pos += 8;
154 wl.littleWaveDirection.ToBytes(mBlock, pos); pos += 8;
155 wl.normalMapTexture.ToBytes(mBlock, pos); pos += 16;
156 wl.horizon.ToBytes(mBlock, pos); pos += 16;
157 Utils.FloatToBytes(wl.hazeHorizon).CopyTo(mBlock, pos); pos += 4;
158 wl.blueDensity.ToBytes(mBlock, pos); pos += 16;
159 Utils.FloatToBytes(wl.hazeDensity).CopyTo(mBlock, pos); pos += 4;
160 Utils.FloatToBytes(wl.densityMultiplier).CopyTo(mBlock, pos); pos += 4;
161 Utils.FloatToBytes(wl.distanceMultiplier).CopyTo(mBlock, pos); pos += 4;
162 wl.sunMoonColor.ToBytes(mBlock, pos); pos += 16;
163 Utils.FloatToBytes(wl.sunMoonPosition).CopyTo(mBlock, pos); pos += 4;
164 wl.ambient.ToBytes(mBlock, pos); pos += 16;
165 Utils.FloatToBytes(wl.eastAngle).CopyTo(mBlock, pos); pos += 4;
166 Utils.FloatToBytes(wl.sunGlowFocus).CopyTo(mBlock, pos); pos += 4;
167 Utils.FloatToBytes(wl.sunGlowSize).CopyTo(mBlock, pos); pos += 4;
168 Utils.FloatToBytes(wl.sceneGamma).CopyTo(mBlock, pos); pos += 4;
169 Utils.FloatToBytes(wl.starBrightness).CopyTo(mBlock, pos); pos += 4;
170 wl.cloudColor.ToBytes(mBlock, pos); pos += 16;
171 wl.cloudXYDensity.ToBytes(mBlock, pos); pos += 12;
172 Utils.FloatToBytes(wl.cloudCoverage).CopyTo(mBlock, pos); pos += 4;
173 Utils.FloatToBytes(wl.cloudScale).CopyTo(mBlock, pos); pos += 4;
174 wl.cloudDetailXYDensity.ToBytes(mBlock, pos); pos += 12;
175 Utils.FloatToBytes(wl.cloudScrollX).CopyTo(mBlock, pos); pos += 4;
176 Utils.FloatToBytes(wl.cloudScrollY).CopyTo(mBlock, pos); pos += 4;
177 Utils.UInt16ToBytes(wl.maxAltitude).CopyTo(mBlock, pos); pos += 2;
178 mBlock[pos] = Convert.ToByte(wl.cloudScrollXLock); pos++;
179 mBlock[pos] = Convert.ToByte(wl.cloudScrollYLock); pos++;
180 mBlock[pos] = Convert.ToByte(wl.drawClassicClouds); pos++;
181 List<byte[]> param = new List<byte[]>();
182 param.Add(mBlock);
183 return param;
184 }
185
186 public void SendProfileToClient(IClientAPI client)
187 {
188 SendProfileToClient(client, m_scene.RegionInfo.WindlightSettings);
189 }
190
191 public void SendProfileToClient(IClientAPI client, RegionLightShareData wl)
192 {
193 if (m_enableWindlight)
194 {
195 if (m_scene.RegionInfo.WindlightSettings.valid)
196 {
197 List<byte[]> param = compileWindlightSettings(wl);
198 client.SendGenericMessage("Windlight", param);
199 }
200 else
201 {
202 List<byte[]> param = new List<byte[]>();
203 client.SendGenericMessage("WindlightReset", param);
204 }
205 }
206 }
207
208 private void EventManager_OnMakeRootAgent(ScenePresence presence)
209 {
210 m_log.Debug("[WINDLIGHT]: Sending windlight scene to new client");
211 SendProfileToClient(presence.ControllingClient);
212 }
213
214 private void EventManager_OnSendNewWindlightProfileTargeted(RegionLightShareData wl, UUID pUUID)
215 {
216 IClientAPI client;
217 m_scene.TryGetClient(pUUID, out client);
218 SendProfileToClient(client, wl);
219 }
220
221 private void EventManager_OnSaveNewWindlightProfile()
222 {
223 m_scene.ForEachRootClient(SendProfileToClient);
224 }
225
226 #endregion
227
228 #region ICommandableModule Members
229
230 private void InstallCommands()
231 {
232 Command wlload = new Command("load", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleLoad, "Load windlight profile from the database and broadcast");
233 Command wlenable = new Command("enable", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleEnable, "Enable the windlight plugin");
234 Command wldisable = new Command("disable", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleDisable, "Disable the windlight plugin");
235
236 m_commander.RegisterCommand("load", wlload);
237 m_commander.RegisterCommand("enable", wlenable);
238 m_commander.RegisterCommand("disable", wldisable);
239
240 m_scene.RegisterModuleCommander(m_commander);
241 }
242
243 private void HandleLoad(Object[] args)
244 {
245 if (!m_enableWindlight)
246 {
247 m_log.InfoFormat("[WINDLIGHT]: Cannot load windlight profile, module disabled. Use 'windlight enable' first.");
248 }
249 else
250 {
251 m_log.InfoFormat("[WINDLIGHT]: Loading Windlight profile from database");
252 m_scene.LoadWindlightProfile();
253 m_log.InfoFormat("[WINDLIGHT]: Load complete");
254 }
255 }
256
257 private void HandleDisable(Object[] args)
258 {
259 m_log.InfoFormat("[WINDLIGHT]: Plugin now disabled");
260 m_enableWindlight = false;
261 }
262
263 private void HandleEnable(Object[] args)
264 {
265 m_log.InfoFormat("[WINDLIGHT]: Plugin now enabled");
266 m_enableWindlight = true;
267 }
268
269 /// <summary>
270 /// Processes commandline input. Do not call directly.
271 /// </summary>
272 /// <param name="args">Commandline arguments</param>
273 private void EventManager_OnPluginConsole(string[] args)
274 {
275 if (args[0] == "windlight")
276 {
277 if (args.Length == 1)
278 {
279 m_commander.ProcessConsoleCommand("add", new string[0]);
280 return;
281 }
282
283 string[] tmpArgs = new string[args.Length - 2];
284 int i;
285 for (i = 2; i < args.Length; i++)
286 {
287 tmpArgs[i - 2] = args[i];
288 }
289
290 m_commander.ProcessConsoleCommand(args[1], tmpArgs);
291 }
292 }
293 #endregion
294
295 }
296}
297