aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneBase.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneBase.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneBase.cs419
1 files changed, 419 insertions, 0 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
new file mode 100644
index 0000000..6d61e9f
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -0,0 +1,419 @@
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 OpenSim 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 System.Threading;
32using OpenMetaverse;
33using log4net;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications.Cache;
36using OpenSim.Region.Framework.Interfaces;
37
38namespace OpenSim.Region.Framework.Scenes
39{
40 public abstract class SceneBase : IScene
41 {
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43
44 #region Events
45
46 public event restart OnRestart;
47
48 #endregion
49
50 #region Fields
51
52 /// <value>
53 /// All the region modules attached to this scene.
54 /// </value>
55 public Dictionary<string, IRegionModule> Modules
56 {
57 get { return m_modules; }
58 }
59 protected Dictionary<string, IRegionModule> m_modules = new Dictionary<string, IRegionModule>();
60
61 /// <value>
62 /// The module interfaces available from this scene.
63 /// </value>
64 protected Dictionary<Type, List<object> > ModuleInterfaces = new Dictionary<Type, List<object> >();
65
66 protected Dictionary<string, object> ModuleAPIMethods = new Dictionary<string, object>();
67 protected Dictionary<string, ICommander> m_moduleCommanders = new Dictionary<string, ICommander>();
68
69 /// <value>
70 /// Registered classes that are capable of creating entities.
71 /// </value>
72 protected Dictionary<PCode, IEntityCreator> m_entityCreators = new Dictionary<PCode, IEntityCreator>();
73
74 //API module interfaces
75
76 /// <summary>
77 /// The last allocated local prim id. When a new local id is requested, the next number in the sequence is
78 /// dispensed.
79 /// </summary>
80 protected uint m_lastAllocatedLocalId = 720000;
81
82 private readonly Mutex _primAllocateMutex = new Mutex(false);
83
84 private readonly ClientManager m_clientManager = new ClientManager();
85
86 public ClientManager ClientManager
87 {
88 get { return m_clientManager; }
89 }
90
91 protected ulong m_regionHandle;
92 protected string m_regionName;
93 protected RegionInfo m_regInfo;
94
95 //public TerrainEngine Terrain;
96 public ITerrainChannel Heightmap;
97
98 /// <value>
99 /// Allows retrieval of land information for this scene.
100 /// </value>
101 public ILandChannel LandChannel;
102
103 /// <value>
104 /// Manage events that occur in this scene (avatar movement, script rez, etc.). Commonly used by region modules
105 /// to subscribe to scene events.
106 /// </value>
107 public EventManager EventManager
108 {
109 get { return m_eventManager; }
110 }
111 protected EventManager m_eventManager;
112
113 protected ScenePermissions m_permissions;
114 public ScenePermissions Permissions
115 {
116 get { return m_permissions; }
117 }
118
119 protected string m_datastore;
120
121 private AssetCache m_assetCache;
122
123 public AssetCache AssetCache
124 {
125 get { return m_assetCache; }
126 set { m_assetCache = value; }
127 }
128
129 protected RegionStatus m_regStatus;
130
131 public RegionStatus Region_Status
132 {
133 get { return m_regStatus; }
134 set { m_regStatus = value; }
135 }
136
137 #endregion
138
139 #region Update Methods
140
141 /// <summary>
142 /// Normally called once every frame/tick to let the world preform anything required (like running the physics simulation)
143 /// </summary>
144 public abstract void Update();
145
146 #endregion
147
148 #region Terrain Methods
149
150 /// <summary>
151 /// Loads the World heightmap
152 /// </summary>
153 public abstract void LoadWorldMap();
154
155 /// <summary>
156 /// Send the region heightmap to the client
157 /// </summary>
158 /// <param name="RemoteClient">Client to send to</param>
159 public virtual void SendLayerData(IClientAPI RemoteClient)
160 {
161 RemoteClient.SendLayerData(Heightmap.GetFloatsSerialised());
162 }
163
164 #endregion
165
166 #region Add/Remove Agent/Avatar
167
168 /// <summary>
169 /// Register the new client with the scene. The client starts off as a child agent - the later agent crossing
170 /// will promote it to a root agent during login.
171 /// </summary>
172 /// <param name="client"></param
173 public abstract void AddNewClient(IClientAPI client);
174
175 /// <summary>
176 /// Remove a client from the scene
177 /// </summary>
178 /// <param name="agentID"></param>
179 public abstract void RemoveClient(UUID agentID);
180
181 public abstract void CloseAllAgents(uint circuitcode);
182
183 #endregion
184
185 /// <summary>
186 ///
187 /// </summary>
188 /// <returns></returns>
189 public virtual RegionInfo RegionInfo
190 {
191 get { return m_regInfo; }
192 }
193
194 #region admin stuff
195
196 /// <summary>
197 /// Region Restart - Seconds till restart.
198 /// </summary>
199 /// <param name="seconds"></param>
200 public virtual void Restart(int seconds)
201 {
202 m_log.Error("[REGION]: passing Restart Message up the namespace");
203 restart handlerPhysicsCrash = OnRestart;
204 if (handlerPhysicsCrash != null)
205 handlerPhysicsCrash(RegionInfo);
206 }
207
208 public virtual bool PresenceChildStatus(UUID avatarID)
209 {
210 return false;
211 }
212
213 public abstract bool OtherRegionUp(RegionInfo thisRegion);
214
215 public virtual string GetSimulatorVersion()
216 {
217 return "OpenSimulator Server";
218 }
219
220 #endregion
221
222 #region Shutdown
223
224 /// <summary>
225 /// Tidy before shutdown
226 /// </summary>
227 public virtual void Close()
228 {
229 // Shut down all non shared modules.
230 foreach (IRegionModule module in Modules.Values)
231 {
232 if (!module.IsSharedModule)
233 {
234 module.Close();
235 }
236 }
237 Modules.Clear();
238
239 try
240 {
241 EventManager.TriggerShutdown();
242 }
243 catch (Exception e)
244 {
245 m_log.Error("[SCENE]: SceneBase.cs: Close() - Failed with exception " + e.ToString());
246 }
247 }
248
249 #endregion
250
251 /// <summary>
252 /// Returns a new unallocated local ID
253 /// </summary>
254 /// <returns>A brand new local ID</returns>
255 protected internal uint AllocateLocalId()
256 {
257 uint myID;
258
259 _primAllocateMutex.WaitOne();
260 myID = ++m_lastAllocatedLocalId;
261 _primAllocateMutex.ReleaseMutex();
262
263 return myID;
264 }
265
266 #region Module Methods
267
268 /// <summary>
269 /// Add a module to this scene.
270 /// </summary>
271 /// <param name="name"></param>
272 /// <param name="module"></param>
273 public void AddModule(string name, IRegionModule module)
274 {
275 if (!Modules.ContainsKey(name))
276 {
277 Modules.Add(name, module);
278 }
279 }
280
281 public void RegisterModuleCommander(ICommander commander)
282 {
283 lock (m_moduleCommanders)
284 {
285 m_moduleCommanders.Add(commander.Name, commander);
286 }
287 }
288
289 /// <summary>
290 /// Get a module commander
291 /// </summary>
292 /// <param name="name"></param>
293 /// <returns>The module commander, null if no module commander with that name was found</returns>
294 public ICommander GetCommander(string name)
295 {
296 lock (m_moduleCommanders)
297 {
298 if (m_moduleCommanders.ContainsKey(name))
299 return m_moduleCommanders[name];
300 }
301
302 return null;
303 }
304
305 public Dictionary<string, ICommander> GetCommanders()
306 {
307 return m_moduleCommanders;
308 }
309
310 /// <summary>
311 /// Register an interface to a region module. This allows module methods to be called directly as
312 /// well as via events. If there is already a module registered for this interface, it is not replaced
313 /// (is this the best behaviour?)
314 /// </summary>
315 /// <param name="mod"></param>
316 public void RegisterModuleInterface<M>(M mod)
317 {
318 if (!ModuleInterfaces.ContainsKey(typeof(M)))
319 {
320 List<Object> l = new List<Object>();
321 l.Add(mod);
322 ModuleInterfaces.Add(typeof(M), l);
323
324 if (mod is IEntityCreator)
325 {
326 IEntityCreator entityCreator = (IEntityCreator)mod;
327 foreach (PCode pcode in entityCreator.CreationCapabilities)
328 {
329 m_entityCreators[pcode] = entityCreator;
330 }
331 }
332 }
333 }
334
335 public void StackModuleInterface<M>(M mod)
336 {
337 List<Object> l;
338 if (ModuleInterfaces.ContainsKey(typeof(M)))
339 l = ModuleInterfaces[typeof(M)];
340 else
341 l = new List<Object>();
342
343 if (l.Contains(mod))
344 return;
345
346 l.Add(mod);
347
348 if (mod is IEntityCreator)
349 {
350 IEntityCreator entityCreator = (IEntityCreator)mod;
351 foreach (PCode pcode in entityCreator.CreationCapabilities)
352 {
353 m_entityCreators[pcode] = entityCreator;
354 }
355 }
356
357 ModuleInterfaces[typeof(M)] = l;
358 }
359
360 /// <summary>
361 /// For the given interface, retrieve the region module which implements it.
362 /// </summary>
363 /// <returns>null if there is no registered module implementing that interface</returns>
364 public T RequestModuleInterface<T>()
365 {
366 if (ModuleInterfaces.ContainsKey(typeof(T)))
367 {
368 return (T)ModuleInterfaces[typeof(T)][0];
369 }
370 else
371 {
372 return default(T);
373 }
374 }
375
376 /// <summary>
377 /// For the given interface, retrieve an array of region modules that implement it.
378 /// </summary>
379 /// <returns>an empty array if there are no registered modules implementing that interface</returns>
380 public T[] RequestModuleInterfaces<T>()
381 {
382 if (ModuleInterfaces.ContainsKey(typeof(T)))
383 {
384 List<T> ret = new List<T>();
385
386 foreach (Object o in ModuleInterfaces[typeof(T)])
387 ret.Add((T)o);
388 return ret.ToArray();
389 }
390 else
391 {
392 return new T[] { default(T) };
393 }
394 }
395
396 #endregion
397
398 /// <summary>
399 /// Shows various details about the sim based on the parameters supplied by the console command in openSimMain.
400 /// </summary>
401 /// <param name="showParams">What to show</param>
402 public virtual void Show(string[] showParams)
403 {
404 switch (showParams[0])
405 {
406 case "modules":
407 m_log.Error("The currently loaded modules in " + RegionInfo.RegionName + " are:");
408 foreach (IRegionModule module in Modules.Values)
409 {
410 if (!module.IsSharedModule)
411 {
412 m_log.Error("Region Module: " + module.Name);
413 }
414 }
415 break;
416 }
417 }
418 }
419}