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.cs1168
1 files changed, 593 insertions, 575 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index 74c9582..f5be7a7 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -1,575 +1,593 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the 12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 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 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 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 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. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using System.Threading; 31using System.Threading;
32using OpenMetaverse; 32using OpenMetaverse;
33using log4net; 33using log4net;
34using Nini.Config; 34using Nini.Config;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Framework.Console; 36using OpenSim.Framework.Console;
37 37
38using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
39using GridRegion = OpenSim.Services.Interfaces.GridRegion; 39using GridRegion = OpenSim.Services.Interfaces.GridRegion;
40 40
41namespace OpenSim.Region.Framework.Scenes 41namespace OpenSim.Region.Framework.Scenes
42{ 42{
43 public abstract class SceneBase : IScene 43 public abstract class SceneBase : IScene
44 { 44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45 protected static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 46 protected static readonly string LogHeader = "[SCENE]";
47 #region Events 47
48 48 #region Events
49 public event restart OnRestart; 49
50 50 public event restart OnRestart;
51 #endregion 51
52 52 #endregion
53 #region Fields 53
54 54 #region Fields
55 public string Name { get { return RegionInfo.RegionName; } } 55
56 56 public string Name { get { return RegionInfo.RegionName; } }
57 public IConfigSource Config 57
58 { 58 public IConfigSource Config
59 get { return GetConfig(); } 59 {
60 } 60 get { return GetConfig(); }
61 61 }
62 protected virtual IConfigSource GetConfig() 62
63 { 63 protected virtual IConfigSource GetConfig()
64 return null; 64 {
65 } 65 return null;
66 66 }
67 /// <value> 67
68 /// All the region modules attached to this scene. 68 /// <value>
69 /// </value> 69 /// All the region modules attached to this scene.
70 public Dictionary<string, IRegionModuleBase> RegionModules 70 /// </value>
71 { 71 public Dictionary<string, IRegionModuleBase> RegionModules
72 get { return m_regionModules; } 72 {
73 } 73 get { return m_regionModules; }
74 private Dictionary<string, IRegionModuleBase> m_regionModules = new Dictionary<string, IRegionModuleBase>(); 74 }
75 75 private Dictionary<string, IRegionModuleBase> m_regionModules = new Dictionary<string, IRegionModuleBase>();
76 /// <value> 76
77 /// The module interfaces available from this scene. 77 /// <value>
78 /// </value> 78 /// The module interfaces available from this scene.
79 protected Dictionary<Type, List<object>> ModuleInterfaces = new Dictionary<Type, List<object>>(); 79 /// </value>
80 80 protected Dictionary<Type, List<object>> ModuleInterfaces = new Dictionary<Type, List<object>>();
81 protected Dictionary<string, object> ModuleAPIMethods = new Dictionary<string, object>(); 81
82 82 protected Dictionary<string, object> ModuleAPIMethods = new Dictionary<string, object>();
83 /// <value> 83
84 /// The module commanders available from this scene 84 /// <value>
85 /// </value> 85 /// The module commanders available from this scene
86 protected Dictionary<string, ICommander> m_moduleCommanders = new Dictionary<string, ICommander>(); 86 /// </value>
87 87 protected Dictionary<string, ICommander> m_moduleCommanders = new Dictionary<string, ICommander>();
88 /// <value> 88
89 /// Registered classes that are capable of creating entities. 89 /// <value>
90 /// </value> 90 /// Registered classes that are capable of creating entities.
91 protected Dictionary<PCode, IEntityCreator> m_entityCreators = new Dictionary<PCode, IEntityCreator>(); 91 /// </value>
92 92 protected Dictionary<PCode, IEntityCreator> m_entityCreators = new Dictionary<PCode, IEntityCreator>();
93 /// <summary> 93
94 /// The last allocated local prim id. When a new local id is requested, the next number in the sequence is 94 /// <summary>
95 /// dispensed. 95 /// The last allocated local prim id. When a new local id is requested, the next number in the sequence is
96 /// </summary> 96 /// dispensed.
97 protected uint m_lastAllocatedLocalId = 720000; 97 /// </summary>
98 98 protected uint m_lastAllocatedLocalId = 720000;
99 private readonly Mutex _primAllocateMutex = new Mutex(false); 99
100 100 private readonly Mutex _primAllocateMutex = new Mutex(false);
101 protected readonly ClientManager m_clientManager = new ClientManager(); 101
102 102 protected readonly ClientManager m_clientManager = new ClientManager();
103 public bool LoginsEnabled 103
104 { 104 public bool LoginsEnabled
105 get 105 {
106 { 106 get
107 return m_loginsEnabled; 107 {
108 } 108 return m_loginsEnabled;
109 109 }
110 set 110
111 { 111 set
112 if (m_loginsEnabled != value) 112 {
113 { 113 if (m_loginsEnabled != value)
114 m_loginsEnabled = value; 114 {
115 EventManager.TriggerRegionLoginsStatusChange(this); 115 m_loginsEnabled = value;
116 } 116 EventManager.TriggerRegionLoginsStatusChange(this);
117 } 117 }
118 } 118 }
119 private bool m_loginsEnabled; 119 }
120 120 private bool m_loginsEnabled;
121 public bool Ready 121
122 { 122 public bool Ready
123 get 123 {
124 { 124 get
125 return m_ready; 125 {
126 } 126 return m_ready;
127 127 }
128 set 128
129 { 129 set
130 if (m_ready != value) 130 {
131 { 131 if (m_ready != value)
132 m_ready = value; 132 {
133 EventManager.TriggerRegionReadyStatusChange(this); 133 m_ready = value;
134 } 134 EventManager.TriggerRegionReadyStatusChange(this);
135 } 135 }
136 } 136 }
137 private bool m_ready; 137 }
138 138 private bool m_ready;
139 public float TimeDilation 139
140 { 140 public float TimeDilation
141 get { return 1.0f; } 141 {
142 } 142 get { return 1.0f; }
143 143 }
144 protected ulong m_regionHandle; 144
145 protected string m_regionName; 145 protected ulong m_regionHandle;
146 146 protected string m_regionName;
147 public ITerrainChannel Heightmap; 147
148 148 public ITerrainChannel Heightmap;
149 /// <value> 149
150 /// Allows retrieval of land information for this scene. 150 /// <value>
151 /// </value> 151 /// Allows retrieval of land information for this scene.
152 public ILandChannel LandChannel; 152 /// </value>
153 153 public ILandChannel LandChannel;
154 /// <value> 154
155 /// Manage events that occur in this scene (avatar movement, script rez, etc.). Commonly used by region modules 155 /// <value>
156 /// to subscribe to scene events. 156 /// Manage events that occur in this scene (avatar movement, script rez, etc.). Commonly used by region modules
157 /// </value> 157 /// to subscribe to scene events.
158 public EventManager EventManager 158 /// </value>
159 { 159 public EventManager EventManager
160 get { return m_eventManager; } 160 {
161 } 161 get { return m_eventManager; }
162 protected EventManager m_eventManager; 162 }
163 163 protected EventManager m_eventManager;
164 protected ScenePermissions m_permissions; 164
165 public ScenePermissions Permissions 165 protected ScenePermissions m_permissions;
166 { 166 public ScenePermissions Permissions
167 get { return m_permissions; } 167 {
168 } 168 get { return m_permissions; }
169 169 }
170 protected string m_datastore; 170
171 171 protected string m_datastore;
172 /* Used by the loadbalancer plugin on GForge */ 172
173 protected RegionStatus m_regStatus; 173 /* Used by the loadbalancer plugin on GForge */
174 public RegionStatus RegionStatus 174 protected RegionStatus m_regStatus;
175 { 175 public RegionStatus RegionStatus
176 get { return m_regStatus; } 176 {
177 set { m_regStatus = value; } 177 get { return m_regStatus; }
178 } 178 set { m_regStatus = value; }
179 179 }
180 #endregion 180
181 181 #endregion
182 public SceneBase(RegionInfo regInfo) 182
183 { 183 public SceneBase(RegionInfo regInfo)
184 RegionInfo = regInfo; 184 {
185 } 185 RegionInfo = regInfo;
186 186 }
187 #region Update Methods 187
188 188 #region Update Methods
189 /// <summary> 189
190 /// Called to update the scene loop by a number of frames and until shutdown. 190 /// <summary>
191 /// </summary> 191 /// Called to update the scene loop by a number of frames and until shutdown.
192 /// <param name="frames"> 192 /// </summary>
193 /// Number of frames to update. Exits on shutdown even if there are frames remaining. 193 /// <param name="frames">
194 /// If -1 then updates until shutdown. 194 /// Number of frames to update. Exits on shutdown even if there are frames remaining.
195 /// </param> 195 /// If -1 then updates until shutdown.
196 public abstract void Update(int frames); 196 /// </param>
197 197 public abstract void Update(int frames);
198 #endregion 198
199 199 #endregion
200 #region Terrain Methods 200
201 201 #region Terrain Methods
202 /// <summary> 202
203 /// Loads the World heightmap 203 /// <summary>
204 /// </summary> 204 /// Loads the World heightmap
205 public abstract void LoadWorldMap(); 205 /// </summary>
206 206 public abstract void LoadWorldMap();
207 /// <summary> 207
208 /// Send the region heightmap to the client 208 /// <summary>
209 /// </summary> 209 /// Send the region heightmap to the client
210 /// <param name="RemoteClient">Client to send to</param> 210 /// </summary>
211 public virtual void SendLayerData(IClientAPI RemoteClient) 211 /// <param name="RemoteClient">Client to send to</param>
212 { 212 public virtual void SendLayerData(IClientAPI RemoteClient)
213 RemoteClient.SendLayerData(Heightmap.GetFloatsSerialised()); 213 {
214 } 214 RemoteClient.SendLayerData(Heightmap.GetFloatsSerialised());
215 215 }
216 #endregion 216
217 217 #endregion
218 #region Add/Remove Agent/Avatar 218
219 219 #region Add/Remove Agent/Avatar
220 public abstract ISceneAgent AddNewClient(IClientAPI client, PresenceType type); 220
221 public abstract void RemoveClient(UUID agentID, bool closeChildAgents); 221 public abstract ISceneAgent AddNewAgent(IClientAPI client, PresenceType type);
222 222
223 public bool TryGetScenePresence(UUID agentID, out object scenePresence) 223 public abstract bool CloseAgent(UUID agentID, bool force);
224 { 224
225 scenePresence = null; 225 public bool TryGetScenePresence(UUID agentID, out object scenePresence)
226 ScenePresence sp = null; 226 {
227 if (TryGetScenePresence(agentID, out sp)) 227 scenePresence = null;
228 { 228 ScenePresence sp = null;
229 scenePresence = sp; 229 if (TryGetScenePresence(agentID, out sp))
230 return true; 230 {
231 } 231 scenePresence = sp;
232 232 return true;
233 return false; 233 }
234 } 234
235 235 return false;
236 /// <summary> 236 }
237 /// Try to get a scene presence from the scene 237
238 /// </summary> 238 /// <summary>
239 /// <param name="agentID"></param> 239 /// Try to get a scene presence from the scene
240 /// <param name="scenePresence">null if there is no scene presence with the given agent id</param> 240 /// </summary>
241 /// <returns>true if there was a scene presence with the given id, false otherwise.</returns> 241 /// <param name="agentID"></param>
242 public abstract bool TryGetScenePresence(UUID agentID, out ScenePresence scenePresence); 242 /// <param name="scenePresence">null if there is no scene presence with the given agent id</param>
243 243 /// <returns>true if there was a scene presence with the given id, false otherwise.</returns>
244 #endregion 244 public abstract bool TryGetScenePresence(UUID agentID, out ScenePresence scenePresence);
245 245
246 /// <summary> 246 #endregion
247 /// 247
248 /// </summary> 248 /// <summary>
249 /// <returns></returns> 249 ///
250 public virtual RegionInfo RegionInfo { get; private set; } 250 /// </summary>
251 251 /// <returns></returns>
252 #region admin stuff 252 public virtual RegionInfo RegionInfo { get; private set; }
253 253
254 public abstract void OtherRegionUp(GridRegion otherRegion); 254 #region admin stuff
255 255
256 public virtual string GetSimulatorVersion() 256 public abstract void OtherRegionUp(GridRegion otherRegion);
257 { 257
258 return "OpenSimulator Server"; 258 public virtual string GetSimulatorVersion()
259 } 259 {
260 260 return "OpenSimulator Server";
261 #endregion 261 }
262 262
263 #region Shutdown 263 #endregion
264 264
265 /// <summary> 265 #region Shutdown
266 /// Tidy before shutdown 266
267 /// </summary> 267 /// <summary>
268 public virtual void Close() 268 /// Tidy before shutdown
269 { 269 /// </summary>
270 try 270 public virtual void Close()
271 { 271 {
272 EventManager.TriggerShutdown(); 272 try
273 } 273 {
274 catch (Exception e) 274 EventManager.TriggerShutdown();
275 { 275 }
276 m_log.Error(string.Format("[SCENE]: SceneBase.cs: Close() - Failed with exception ", e)); 276 catch (Exception e)
277 } 277 {
278 } 278 m_log.Error(string.Format("[SCENE]: SceneBase.cs: Close() - Failed with exception ", e));
279 279 }
280 #endregion 280 }
281 281
282 /// <summary> 282 #endregion
283 /// Returns a new unallocated local ID 283
284 /// </summary> 284 /// <summary>
285 /// <returns>A brand new local ID</returns> 285 /// Returns a new unallocated local ID
286 public uint AllocateLocalId() 286 /// </summary>
287 { 287 /// <returns>A brand new local ID</returns>
288 uint myID; 288 public uint AllocateLocalId()
289 289 {
290 _primAllocateMutex.WaitOne(); 290 uint myID;
291 myID = ++m_lastAllocatedLocalId; 291
292 _primAllocateMutex.ReleaseMutex(); 292 _primAllocateMutex.WaitOne();
293 293 myID = ++m_lastAllocatedLocalId;
294 return myID; 294 _primAllocateMutex.ReleaseMutex();
295 } 295
296 296 return myID;
297 #region Module Methods 297 }
298 298
299 /// <summary> 299 public uint AllocatePresenceLocalId()
300 /// Add a region-module to this scene. TODO: This will replace AddModule in the future. 300 {
301 /// </summary> 301 uint myID;
302 /// <param name="name"></param> 302
303 /// <param name="module"></param> 303 _primAllocateMutex.WaitOne();
304 public void AddRegionModule(string name, IRegionModuleBase module) 304 myID = ++m_lastAllocatedLocalId;
305 { 305 ++m_lastAllocatedLocalId;
306 if (!RegionModules.ContainsKey(name)) 306 _primAllocateMutex.ReleaseMutex();
307 { 307
308 RegionModules.Add(name, module); 308 return myID;
309 } 309 }
310 } 310
311 311 #region Module Methods
312 public void RemoveRegionModule(string name) 312
313 { 313 /// <summary>
314 RegionModules.Remove(name); 314 /// Add a region-module to this scene. TODO: This will replace AddModule in the future.
315 } 315 /// </summary>
316 316 /// <param name="name"></param>
317 /// <summary> 317 /// <param name="module"></param>
318 /// Register a module commander. 318 public void AddRegionModule(string name, IRegionModuleBase module)
319 /// </summary> 319 {
320 /// <param name="commander"></param> 320 if (!RegionModules.ContainsKey(name))
321 public void RegisterModuleCommander(ICommander commander) 321 {
322 { 322 RegionModules.Add(name, module);
323 lock (m_moduleCommanders) 323 }
324 { 324 }
325 m_moduleCommanders.Add(commander.Name, commander); 325
326 } 326 public void RemoveRegionModule(string name)
327 } 327 {
328 328 RegionModules.Remove(name);
329 /// <summary> 329 }
330 /// Unregister a module commander and all its commands 330
331 /// </summary> 331 /// <summary>
332 /// <param name="name"></param> 332 /// Register a module commander.
333 public void UnregisterModuleCommander(string name) 333 /// </summary>
334 { 334 /// <param name="commander"></param>
335 lock (m_moduleCommanders) 335 public void RegisterModuleCommander(ICommander commander)
336 { 336 {
337 ICommander commander; 337 lock (m_moduleCommanders)
338 if (m_moduleCommanders.TryGetValue(name, out commander)) 338 {
339 m_moduleCommanders.Remove(name); 339 m_moduleCommanders.Add(commander.Name, commander);
340 } 340 }
341 } 341 }
342 342
343 /// <summary> 343 /// <summary>
344 /// Get a module commander 344 /// Unregister a module commander and all its commands
345 /// </summary> 345 /// </summary>
346 /// <param name="name"></param> 346 /// <param name="name"></param>
347 /// <returns>The module commander, null if no module commander with that name was found</returns> 347 public void UnregisterModuleCommander(string name)
348 public ICommander GetCommander(string name) 348 {
349 { 349 lock (m_moduleCommanders)
350 lock (m_moduleCommanders) 350 {
351 { 351 ICommander commander;
352 if (m_moduleCommanders.ContainsKey(name)) 352 if (m_moduleCommanders.TryGetValue(name, out commander))
353 return m_moduleCommanders[name]; 353 m_moduleCommanders.Remove(name);
354 } 354 }
355 355 }
356 return null; 356
357 } 357 /// <summary>
358 358 /// Get a module commander
359 public Dictionary<string, ICommander> GetCommanders() 359 /// </summary>
360 { 360 /// <param name="name"></param>
361 return m_moduleCommanders; 361 /// <returns>The module commander, null if no module commander with that name was found</returns>
362 } 362 public ICommander GetCommander(string name)
363 363 {
364 /// <summary> 364 lock (m_moduleCommanders)
365 /// Register an interface to a region module. This allows module methods to be called directly as 365 {
366 /// well as via events. If there is already a module registered for this interface, it is not replaced 366 if (m_moduleCommanders.ContainsKey(name))
367 /// (is this the best behaviour?) 367 return m_moduleCommanders[name];
368 /// </summary> 368 }
369 /// <param name="mod"></param> 369
370 public void RegisterModuleInterface<M>(M mod) 370 return null;
371 { 371 }
372// m_log.DebugFormat("[SCENE BASE]: Registering interface {0}", typeof(M)); 372
373 373 public Dictionary<string, ICommander> GetCommanders()
374 List<Object> l = null; 374 {
375 if (!ModuleInterfaces.TryGetValue(typeof(M), out l)) 375 return m_moduleCommanders;
376 { 376 }
377 l = new List<Object>(); 377
378 ModuleInterfaces.Add(typeof(M), l); 378 /// <summary>
379 } 379 /// Register an interface to a region module. This allows module methods to be called directly as
380 380 /// well as via events. If there is already a module registered for this interface, it is not replaced
381 if (l.Count > 0) 381 /// (is this the best behaviour?)
382 return; 382 /// </summary>
383 383 /// <param name="mod"></param>
384 l.Add(mod); 384 public void RegisterModuleInterface<M>(M mod)
385 385 {
386 if (mod is IEntityCreator) 386// m_log.DebugFormat("[SCENE BASE]: Registering interface {0}", typeof(M));
387 { 387
388 IEntityCreator entityCreator = (IEntityCreator)mod; 388 List<Object> l = null;
389 foreach (PCode pcode in entityCreator.CreationCapabilities) 389 if (!ModuleInterfaces.TryGetValue(typeof(M), out l))
390 { 390 {
391 m_entityCreators[pcode] = entityCreator; 391 l = new List<Object>();
392 } 392 ModuleInterfaces.Add(typeof(M), l);
393 } 393 }
394 } 394
395 395 if (l.Count > 0)
396 public void UnregisterModuleInterface<M>(M mod) 396 return;
397 { 397
398 List<Object> l; 398 l.Add(mod);
399 if (ModuleInterfaces.TryGetValue(typeof(M), out l)) 399
400 { 400 if (mod is IEntityCreator)
401 if (l.Remove(mod)) 401 {
402 { 402 IEntityCreator entityCreator = (IEntityCreator)mod;
403 if (mod is IEntityCreator) 403 foreach (PCode pcode in entityCreator.CreationCapabilities)
404 { 404 {
405 IEntityCreator entityCreator = (IEntityCreator)mod; 405 m_entityCreators[pcode] = entityCreator;
406 foreach (PCode pcode in entityCreator.CreationCapabilities) 406 }
407 { 407 }
408 m_entityCreators[pcode] = null; 408 }
409 } 409
410 } 410 public void UnregisterModuleInterface<M>(M mod)
411 } 411 {
412 } 412 List<Object> l;
413 } 413 if (ModuleInterfaces.TryGetValue(typeof(M), out l))
414 414 {
415 public void StackModuleInterface<M>(M mod) 415 if (l.Remove(mod))
416 { 416 {
417 List<Object> l; 417 if (mod is IEntityCreator)
418 if (ModuleInterfaces.ContainsKey(typeof(M))) 418 {
419 l = ModuleInterfaces[typeof(M)]; 419 IEntityCreator entityCreator = (IEntityCreator)mod;
420 else 420 foreach (PCode pcode in entityCreator.CreationCapabilities)
421 l = new List<Object>(); 421 {
422 422 m_entityCreators[pcode] = null;
423 if (l.Contains(mod)) 423 }
424 return; 424 }
425 425 }
426 l.Add(mod); 426 }
427 427 }
428 if (mod is IEntityCreator) 428
429 { 429 public void StackModuleInterface<M>(M mod)
430 IEntityCreator entityCreator = (IEntityCreator)mod; 430 {
431 foreach (PCode pcode in entityCreator.CreationCapabilities) 431 List<Object> l;
432 { 432 if (ModuleInterfaces.ContainsKey(typeof(M)))
433 m_entityCreators[pcode] = entityCreator; 433 l = ModuleInterfaces[typeof(M)];
434 } 434 else
435 } 435 l = new List<Object>();
436 436
437 ModuleInterfaces[typeof(M)] = l; 437 if (l.Contains(mod))
438 } 438 return;
439 439
440 /// <summary> 440 l.Add(mod);
441 /// For the given interface, retrieve the region module which implements it. 441
442 /// </summary> 442 if (mod is IEntityCreator)
443 /// <returns>null if there is no registered module implementing that interface</returns> 443 {
444 public T RequestModuleInterface<T>() 444 IEntityCreator entityCreator = (IEntityCreator)mod;
445 { 445 foreach (PCode pcode in entityCreator.CreationCapabilities)
446 if (ModuleInterfaces.ContainsKey(typeof(T)) && 446 {
447 (ModuleInterfaces[typeof(T)].Count > 0)) 447 m_entityCreators[pcode] = entityCreator;
448 return (T)ModuleInterfaces[typeof(T)][0]; 448 }
449 else 449 }
450 return default(T); 450
451 } 451 ModuleInterfaces[typeof(M)] = l;
452 452 }
453 /// <summary> 453
454 /// For the given interface, retrieve an array of region modules that implement it. 454 /// <summary>
455 /// </summary> 455 /// For the given interface, retrieve the region module which implements it.
456 /// <returns>an empty array if there are no registered modules implementing that interface</returns> 456 /// </summary>
457 public T[] RequestModuleInterfaces<T>() 457 /// <returns>null if there is no registered module implementing that interface</returns>
458 { 458 public T RequestModuleInterface<T>()
459 if (ModuleInterfaces.ContainsKey(typeof(T))) 459 {
460 { 460 if (ModuleInterfaces.ContainsKey(typeof(T)) &&
461 List<T> ret = new List<T>(); 461 (ModuleInterfaces[typeof(T)].Count > 0))
462 462 return (T)ModuleInterfaces[typeof(T)][0];
463 foreach (Object o in ModuleInterfaces[typeof(T)]) 463 else
464 ret.Add((T)o); 464 return default(T);
465 return ret.ToArray(); 465 }
466 } 466
467 else 467 /// <summary>
468 { 468 /// For the given interface, retrieve an array of region modules that implement it.
469 return new T[] {}; 469 /// </summary>
470 } 470 /// <returns>an empty array if there are no registered modules implementing that interface</returns>
471 } 471 public T[] RequestModuleInterfaces<T>()
472 472 {
473 #endregion 473 if (ModuleInterfaces.ContainsKey(typeof(T)))
474 474 {
475 /// <summary> 475 List<T> ret = new List<T>();
476 /// Call this from a region module to add a command to the OpenSim console. 476
477 /// </summary> 477 foreach (Object o in ModuleInterfaces[typeof(T)])
478 /// <param name="mod"></param> 478 ret.Add((T)o);
479 /// <param name="command"></param> 479 return ret.ToArray();
480 /// <param name="shorthelp"></param> 480 }
481 /// <param name="longhelp"></param> 481 else
482 /// <param name="callback"></param> 482 {
483 public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback) 483 return new T[] {};
484 { 484 }
485 AddCommand(module, command, shorthelp, longhelp, string.Empty, callback); 485 }
486 } 486
487 487 #endregion
488 /// <summary> 488
489 /// Call this from a region module to add a command to the OpenSim console. 489 /// <summary>
490 /// </summary> 490 /// Call this from a region module to add a command to the OpenSim console.
491 /// <param name="mod"> 491 /// </summary>
492 /// The use of IRegionModuleBase is a cheap trick to get a different method signature, 492 /// <param name="mod"></param>
493 /// though all new modules should be using interfaces descended from IRegionModuleBase anyway. 493 /// <param name="command"></param>
494 /// </param> 494 /// <param name="shorthelp"></param>
495 /// <param name="category"> 495 /// <param name="longhelp"></param>
496 /// Category of the command. This is the section under which it will appear when the user asks for help 496 /// <param name="callback"></param>
497 /// </param> 497 public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback)
498 /// <param name="command"></param> 498 {
499 /// <param name="shorthelp"></param> 499 AddCommand(module, command, shorthelp, longhelp, string.Empty, callback);
500 /// <param name="longhelp"></param> 500 }
501 /// <param name="callback"></param> 501
502 public void AddCommand( 502 /// <summary>
503 string category, IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback) 503 /// Call this from a region module to add a command to the OpenSim console.
504 { 504 /// </summary>
505 AddCommand(category, module, command, shorthelp, longhelp, string.Empty, callback); 505 /// <param name="mod">
506 } 506 /// The use of IRegionModuleBase is a cheap trick to get a different method signature,
507 507 /// though all new modules should be using interfaces descended from IRegionModuleBase anyway.
508 /// <summary> 508 /// </param>
509 /// Call this from a region module to add a command to the OpenSim console. 509 /// <param name="category">
510 /// </summary> 510 /// Category of the command. This is the section under which it will appear when the user asks for help
511 /// <param name="mod"></param> 511 /// </param>
512 /// <param name="command"></param> 512 /// <param name="command"></param>
513 /// <param name="shorthelp"></param> 513 /// <param name="shorthelp"></param>
514 /// <param name="longhelp"></param> 514 /// <param name="longhelp"></param>
515 /// <param name="descriptivehelp"></param> 515 /// <param name="callback"></param>
516 /// <param name="callback"></param> 516 public void AddCommand(
517 public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) 517 string category, IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback)
518 { 518 {
519 string moduleName = ""; 519 AddCommand(category, module, command, shorthelp, longhelp, string.Empty, callback);
520 520 }
521 if (module != null) 521
522 moduleName = module.Name; 522 /// <summary>
523 523 /// Call this from a region module to add a command to the OpenSim console.
524 AddCommand(moduleName, module, command, shorthelp, longhelp, descriptivehelp, callback); 524 /// </summary>
525 } 525 /// <param name="mod"></param>
526 526 /// <param name="command"></param>
527 /// <summary> 527 /// <param name="shorthelp"></param>
528 /// Call this from a region module to add a command to the OpenSim console. 528 /// <param name="longhelp"></param>
529 /// </summary> 529 /// <param name="descriptivehelp"></param>
530 /// <param name="category"> 530 /// <param name="callback"></param>
531 /// Category of the command. This is the section under which it will appear when the user asks for help 531 public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback)
532 /// </param> 532 {
533 /// <param name="mod"></param> 533 string moduleName = "";
534 /// <param name="command"></param> 534
535 /// <param name="shorthelp"></param> 535 if (module != null)
536 /// <param name="longhelp"></param> 536 moduleName = module.Name;
537 /// <param name="descriptivehelp"></param> 537
538 /// <param name="callback"></param> 538 AddCommand(moduleName, module, command, shorthelp, longhelp, descriptivehelp, callback);
539 public void AddCommand( 539 }
540 string category, IRegionModuleBase module, string command, 540
541 string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) 541 /// <summary>
542 { 542 /// Call this from a region module to add a command to the OpenSim console.
543 if (MainConsole.Instance == null) 543 /// </summary>
544 return; 544 /// <param name="category">
545 545 /// Category of the command. This is the section under which it will appear when the user asks for help
546 bool shared = false; 546 /// </param>
547 547 /// <param name="mod"></param>
548 if (module != null) 548 /// <param name="command"></param>
549 shared = module is ISharedRegionModule; 549 /// <param name="shorthelp"></param>
550 550 /// <param name="longhelp"></param>
551 MainConsole.Instance.Commands.AddCommand( 551 /// <param name="descriptivehelp"></param>
552 category, shared, command, shorthelp, longhelp, descriptivehelp, callback); 552 /// <param name="callback"></param>
553 } 553 public void AddCommand(
554 554 string category, IRegionModuleBase module, string command,
555 public virtual ISceneObject DeserializeObject(string representation) 555 string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback)
556 { 556 {
557 return null; 557 if (MainConsole.Instance == null)
558 } 558 return;
559 559
560 public virtual bool AllowScriptCrossings 560 bool shared = false;
561 { 561
562 get { return false; } 562 if (module != null)
563 } 563 shared = module is ISharedRegionModule;
564 564
565 public void Restart() 565 MainConsole.Instance.Commands.AddCommand(
566 { 566 category, shared, command, shorthelp, longhelp, descriptivehelp, callback);
567 // This has to be here to fire the event 567 }
568 restart handlerPhysicsCrash = OnRestart; 568
569 if (handlerPhysicsCrash != null) 569 public virtual ISceneObject DeserializeObject(string representation)
570 handlerPhysicsCrash(RegionInfo); 570 {
571 } 571 return null;
572 572 }
573 public abstract bool CheckClient(UUID agentID, System.Net.IPEndPoint ep); 573
574 } 574 public virtual bool AllowScriptCrossings
575} 575 {
576 get { return false; }
577 }
578
579 public virtual void Start()
580 {
581 }
582
583 public void Restart()
584 {
585 // This has to be here to fire the event
586 restart handlerPhysicsCrash = OnRestart;
587 if (handlerPhysicsCrash != null)
588 handlerPhysicsCrash(RegionInfo);
589 }
590
591 public abstract bool CheckClient(UUID agentID, System.Net.IPEndPoint ep);
592 }
593}