clockwerk-opensim – Blame information for rev 1

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