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