OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
LightShareModule.cs
Go to the documentation of this file.
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 
28 using System;
29 using System.Collections.Generic;
30 using System.Reflection;
31 using OpenMetaverse;
32 using OpenSim.Framework;
33 using OpenSim.Region.CoreModules.Framework.InterfaceCommander;
34 using OpenSim.Region.Framework.Interfaces;
35 using OpenSim.Region.Framework.Scenes;
36 using log4net;
37 using Nini.Config;
38 using Mono.Addins;
39 
40 namespace OpenSim.Region.CoreModules.World.LightShare
41 {
42  [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LightShareModule")]
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 
192  {
193  if (client == null)
194  return;
195 
196  if (m_enableWindlight)
197  {
198  if (m_scene.RegionInfo.WindlightSettings.valid)
199  {
200  List<byte[]> param = compileWindlightSettings(wl);
201  client.SendGenericMessage("Windlight", UUID.Random(), param);
202  }
203  else
204  {
205  List<byte[]> param = new List<byte[]>();
206  client.SendGenericMessage("WindlightReset", UUID.Random(), param);
207  }
208  }
209  }
210 
211  private void EventManager_OnMakeRootAgent(ScenePresence presence)
212  {
213  if (m_enableWindlight && m_scene.RegionInfo.WindlightSettings.valid)
214  m_log.Debug("[WINDLIGHT]: Sending windlight scene to new client");
215  SendProfileToClient(presence.ControllingClient);
216  }
217 
218  private void EventManager_OnSendNewWindlightProfileTargeted(RegionLightShareData wl, UUID pUUID)
219  {
220  IClientAPI client;
221  m_scene.TryGetClient(pUUID, out client);
222  SendProfileToClient(client, wl);
223  }
224 
225  private void EventManager_OnSaveNewWindlightProfile()
226  {
227  m_scene.ForEachRootClient(SendProfileToClient);
228  }
229 
230  #endregion
231 
232  #region ICommandableModule Members
233 
234  private void InstallCommands()
235  {
236  Command wlload = new Command("load", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleLoad, "Load windlight profile from the database and broadcast");
237  Command wlenable = new Command("enable", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleEnable, "Enable the windlight plugin");
238  Command wldisable = new Command("disable", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleDisable, "Disable the windlight plugin");
239 
240  m_commander.RegisterCommand("load", wlload);
241  m_commander.RegisterCommand("enable", wlenable);
242  m_commander.RegisterCommand("disable", wldisable);
243 
244  m_scene.RegisterModuleCommander(m_commander);
245  }
246 
247  private void HandleLoad(Object[] args)
248  {
249  if (!m_enableWindlight)
250  {
251  m_log.InfoFormat("[WINDLIGHT]: Cannot load windlight profile, module disabled. Use 'windlight enable' first.");
252  }
253  else
254  {
255  m_log.InfoFormat("[WINDLIGHT]: Loading Windlight profile from database");
256  m_scene.LoadWindlightProfile();
257  m_log.InfoFormat("[WINDLIGHT]: Load complete");
258  }
259  }
260 
261  private void HandleDisable(Object[] args)
262  {
263  m_log.InfoFormat("[WINDLIGHT]: Plugin now disabled");
264  m_enableWindlight = false;
265  }
266 
267  private void HandleEnable(Object[] args)
268  {
269  m_log.InfoFormat("[WINDLIGHT]: Plugin now enabled");
270  m_enableWindlight = true;
271  }
272 
277  private void EventManager_OnPluginConsole(string[] args)
278  {
279  if (args[0] == "windlight")
280  {
281  if (args.Length == 1)
282  {
283  m_commander.ProcessConsoleCommand("add", new string[0]);
284  return;
285  }
286 
287  string[] tmpArgs = new string[args.Length - 2];
288  int i;
289  for (i = 2; i < args.Length; i++)
290  {
291  tmpArgs[i - 2] = args[i];
292  }
293 
294  m_commander.ProcessConsoleCommand(args[1], tmpArgs);
295  }
296  }
297  #endregion
298 
299  }
300 }
301 
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
void SendProfileToClient(IClientAPI client, RegionLightShareData wl)
A single function call encapsulated in a class which enforces arguments when passing around as Object...
Definition: Command.cs:39
void Initialise(IConfigSource config)
This is called to initialize the region module. For shared modules, this is called exactly once...
A class to enable modules to register console and script commands, which enforces typing and valid in...
Definition: Commander.cs:41
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...