aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/OpenSim.RegionServer/Simulator/World.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/OpenSim.RegionServer/Simulator/World.cs')
-rw-r--r--OpenSim/OpenSim.RegionServer/Simulator/World.cs736
1 files changed, 736 insertions, 0 deletions
diff --git a/OpenSim/OpenSim.RegionServer/Simulator/World.cs b/OpenSim/OpenSim.RegionServer/Simulator/World.cs
new file mode 100644
index 0000000..150a092
--- /dev/null
+++ b/OpenSim/OpenSim.RegionServer/Simulator/World.cs
@@ -0,0 +1,736 @@
1/*
2* Copyright (c) Contributors, http://www.openmetaverse.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 libsecondlife;
30using libsecondlife.Packets;
31using System.Collections.Generic;
32using System.Text;
33using System.Reflection;
34using System.IO;
35using System.Threading;
36using OpenSim.Physics.Manager;
37using OpenSim.Framework.Interfaces;
38using OpenSim.Framework.Types;
39using OpenSim.Framework.Terrain;
40using OpenSim.Framework.Inventory;
41using OpenSim.RegionServer.Assets;
42
43using OpenSim.RegionServer.Scripting;
44using OpenSim.Terrain;
45using OpenSim.Framework.Console;
46using OpenSim.RegionServer.Client;
47
48
49namespace OpenSim.RegionServer.Simulator
50{
51 public partial class World : WorldBase, ILocalStorageReceiver, IScriptAPI
52 {
53 public object LockPhysicsEngine = new object();
54 public Dictionary<libsecondlife.LLUUID, Avatar> Avatars;
55 public Dictionary<libsecondlife.LLUUID, Primitive> Prims;
56 //public ScriptEngine Scripts;
57 public uint _localNumber = 0;
58 private PhysicsScene phyScene;
59 private float timeStep = 0.1f;
60 public ILocalStorage localStorage;
61 private Random Rand = new Random();
62 private uint _primCount = 702000;
63 private int storageCount;
64 private Dictionary<LLUUID, ScriptHandler> m_scriptHandlers;
65 private Dictionary<string, ScriptFactory> m_scripts;
66 private Mutex updateLock;
67 public string m_datastore;
68 public OpenSim.RegionServer.Simulator.ParcelManager parcelManager;
69
70 #region Properties
71 public PhysicsScene PhysScene
72 {
73 set
74 {
75 this.phyScene = value;
76 }
77 get
78 {
79 return (this.phyScene);
80 }
81 }
82 #endregion
83
84 #region Constructors
85 /// <summary>
86 /// Creates a new World class, and a region to go with it.
87 /// </summary>
88 /// <param name="clientThreads">Dictionary to contain client threads</param>
89 /// <param name="regionHandle">Region Handle for this region</param>
90 /// <param name="regionName">Region Name for this region</param>
91 public World(Dictionary<uint, ClientView> clientThreads, RegionInfo regInfo, ulong regionHandle, string regionName)
92 {
93 try
94 {
95 updateLock = new Mutex(false);
96 m_clientThreads = clientThreads;
97 m_regionHandle = regionHandle;
98 m_regionName = regionName;
99 m_regInfo = regInfo;
100
101 m_scriptHandlers = new Dictionary<LLUUID, ScriptHandler>();
102 m_scripts = new Dictionary<string, ScriptFactory>();
103
104 MainConsole.Instance.Notice("World.cs - creating new entitities instance");
105 Entities = new Dictionary<libsecondlife.LLUUID, Entity>();
106 Avatars = new Dictionary<LLUUID, Avatar>();
107 Prims = new Dictionary<LLUUID, Primitive>();
108
109 MainConsole.Instance.Notice("World.cs - creating LandMap");
110 TerrainManager = new TerrainManager(new SecondLife());
111 Terrain = new TerrainEngine();
112 Avatar.SetupTemplate("avatar-texture.dat");
113 // MainConsole.Instance.WriteLine("World.cs - Creating script engine instance");
114 // Initialise this only after the world has loaded
115 // Scripts = new ScriptEngine(this);
116 Avatar.LoadAnims();
117 this.SetDefaultScripts();
118 this.LoadScriptEngines();
119
120 }
121 catch (Exception e)
122 {
123 OpenSim.Framework.Console.MainConsole.Instance.Error("World.cs: Constructor failed with exception " + e.ToString());
124 }
125 }
126 #endregion
127
128 #region Script Methods
129 /// <summary>
130 /// Loads a new script into the specified entity
131 /// </summary>
132 /// <param name="entity">Entity to be scripted</param>
133 /// <param name="script">The script to load</param>
134 public void AddScript(Entity entity, Script script)
135 {
136 try
137 {
138 ScriptHandler scriptHandler = new ScriptHandler(script, entity, this);
139 m_scriptHandlers.Add(scriptHandler.ScriptId, scriptHandler);
140 }
141 catch (Exception e)
142 {
143 MainConsole.Instance.Warn("World.cs: AddScript() - Failed with exception " + e.ToString());
144 }
145 }
146
147 /// <summary>
148 /// Loads a new script into the specified entity, using a script loaded from a string.
149 /// </summary>
150 /// <param name="entity">The entity to be scripted</param>
151 /// <param name="scriptData">The string containing the script</param>
152 public void AddScript(Entity entity, string scriptData)
153 {
154 try
155 {
156 int scriptstart = 0;
157 int scriptend = 0;
158 string substring;
159 scriptstart = scriptData.LastIndexOf("<Script>");
160 scriptend = scriptData.LastIndexOf("</Script>");
161 substring = scriptData.Substring(scriptstart + 8, scriptend - scriptstart - 8);
162 substring = substring.Trim();
163 //Console.WriteLine("searching for script to add: " + substring);
164
165 ScriptFactory scriptFactory;
166 //Console.WriteLine("script string is " + substring);
167 if (substring.StartsWith("<ScriptEngine:"))
168 {
169 string substring1 = "";
170 string script = "";
171 // Console.WriteLine("searching for script engine");
172 substring1 = substring.Remove(0, 14);
173 int dev = substring1.IndexOf(',');
174 string sEngine = substring1.Substring(0, dev);
175 substring1 = substring1.Remove(0, dev + 1);
176 int end = substring1.IndexOf('>');
177 string sName = substring1.Substring(0, end);
178 //Console.WriteLine(" script info : " + sEngine + " , " + sName);
179 int startscript = substring.IndexOf('>');
180 script = substring.Remove(0, startscript + 1);
181 // Console.WriteLine("script data is " + script);
182 if (this.scriptEngines.ContainsKey(sEngine))
183 {
184 this.scriptEngines[sEngine].LoadScript(script, sName, entity.localid);
185 }
186 }
187 else if (this.m_scripts.TryGetValue(substring, out scriptFactory))
188 {
189 //Console.WriteLine("added script");
190 this.AddScript(entity, scriptFactory());
191 }
192 }
193 catch (Exception e)
194 {
195 MainConsole.Instance.Warn("World.cs: AddScript() - Failed with exception " + e.ToString());
196 }
197 }
198
199 #endregion
200
201 #region Update Methods
202 /// <summary>
203 /// Performs per-frame updates on the world, this should be the central world loop
204 /// </summary>
205 public override void Update()
206 {
207 updateLock.WaitOne();
208 try
209 {
210 if (this.phyScene.IsThreaded)
211 {
212 this.phyScene.GetResults();
213
214 }
215
216 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
217 {
218 Entities[UUID].addForces();
219 }
220
221 lock (this.LockPhysicsEngine)
222 {
223 this.phyScene.Simulate(timeStep);
224 }
225
226 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
227 {
228 Entities[UUID].update();
229 }
230
231 foreach (ScriptHandler scriptHandler in m_scriptHandlers.Values)
232 {
233 scriptHandler.OnFrame();
234 }
235 foreach (IScriptEngine scripteng in this.scriptEngines.Values)
236 {
237 scripteng.OnFrame();
238 }
239 //backup world data
240 this.storageCount++;
241 if (storageCount > 1200) //set to how often you want to backup
242 {
243 this.Backup();
244 storageCount = 0;
245 }
246 }
247 catch (Exception e)
248 {
249 MainConsole.Instance.Warn("World.cs: Update() - Failed with exception " + e.ToString());
250 }
251 updateLock.ReleaseMutex();
252 }
253
254 public bool Backup()
255 {
256 try
257 {
258 // Terrain backup routines
259 if (Terrain.tainted > 0)
260 {
261 Terrain.tainted = 0;
262 MainConsole.Instance.Notice("World.cs: Backup() - Terrain tainted, saving.");
263 localStorage.SaveMap(Terrain.getHeights1D());
264 MainConsole.Instance.Notice("World.cs: Backup() - Rebuilding world map image.");
265 Terrain.exportImage("map_" + m_regInfo.RegionName.ToLower() + ".png", "defaultstripe.png");
266 MainConsole.Instance.Notice("World.cs: Backup() - Terrain saved, informing Physics.");
267 phyScene.SetTerrain(Terrain.getHeights1D());
268
269 // Needs optimising to just send patches which have changed.
270 MainConsole.Instance.Notice("World.cs: Backup() - Terrain changed, informing Clients.");
271 foreach (ClientView client in m_clientThreads.Values)
272 {
273 this.SendLayerData(client);
274 }
275 }
276
277 // Primitive backup routines -- should only do if there's been a change.
278 MainConsole.Instance.Notice("World.cs: Backup() - Backing up Primitives");
279 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
280 {
281 Entities[UUID].BackUp();
282 }
283
284
285 //Parcel backup routines. Yay!
286 ParcelData[] parcels = new ParcelData[parcelManager.parcelList.Count];
287 int i = 0;
288 foreach(OpenSim.RegionServer.Simulator.Parcel parcel in parcelManager.parcelList.Values)
289 {
290 parcels[i] = parcel.parcelData;
291 i++;
292 }
293 localStorage.SaveParcels(parcels);
294
295
296 // Backup successful
297 return true;
298 }
299 catch (Exception e)
300 {
301 // Backup failed
302 OpenSim.Framework.Console.MainConsole.Instance.Error("World.cs: Backup() - Backup Failed with exception " + e.ToString());
303 return false;
304 }
305 }
306 #endregion
307
308 #region Setup Methods
309 /// <summary>
310 /// Loads a new storage subsystem from a named library
311 /// </summary>
312 /// <param name="dllName">Storage Library</param>
313 /// <returns>Successful or not</returns>
314 public bool LoadStorageDLL(string dllName)
315 {
316 try
317 {
318 Assembly pluginAssembly = Assembly.LoadFrom(dllName);
319 ILocalStorage store = null;
320
321 foreach (Type pluginType in pluginAssembly.GetTypes())
322 {
323 if (pluginType.IsPublic)
324 {
325 if (!pluginType.IsAbstract)
326 {
327 Type typeInterface = pluginType.GetInterface("ILocalStorage", true);
328
329 if (typeInterface != null)
330 {
331 ILocalStorage plug = (ILocalStorage)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
332 store = plug;
333
334 store.Initialise(this.m_datastore);
335 break;
336 }
337
338 typeInterface = null;
339 }
340 }
341 }
342 pluginAssembly = null;
343 this.localStorage = store;
344 return (store == null);
345 }
346 catch (Exception e)
347 {
348 MainConsole.Instance.Warn("World.cs: LoadStorageDLL() - Failed with exception " + e.ToString());
349 return false;
350 }
351 }
352
353 public void SetDefaultScripts()
354 {
355 this.m_scripts.Add("FollowRandomAvatar", delegate()
356 {
357 return new OpenSim.RegionServer.Scripting.FollowRandomAvatar();
358 });
359 }
360
361 #endregion
362
363 #region Regenerate Terrain
364
365 /// <summary>
366 /// Rebuilds the terrain using a procedural algorithm
367 /// </summary>
368 public void RegenerateTerrain()
369 {
370 try
371 {
372 Terrain.hills();
373
374 lock (this.LockPhysicsEngine)
375 {
376 this.phyScene.SetTerrain(Terrain.getHeights1D());
377 }
378 this.localStorage.SaveMap(this.Terrain.getHeights1D());
379
380 foreach (ClientView client in m_clientThreads.Values)
381 {
382 this.SendLayerData(client);
383 }
384
385 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
386 {
387 Entities[UUID].LandRenegerated();
388 }
389 }
390 catch (Exception e)
391 {
392 MainConsole.Instance.Warn("World.cs: RegenerateTerrain() - Failed with exception " + e.ToString());
393 }
394 }
395
396 /// <summary>
397 /// Rebuilds the terrain using a 2D float array
398 /// </summary>
399 /// <param name="newMap">256,256 float array containing heights</param>
400 public void RegenerateTerrain(float[,] newMap)
401 {
402 try
403 {
404 this.Terrain.setHeights2D(newMap);
405 lock (this.LockPhysicsEngine)
406 {
407 this.phyScene.SetTerrain(this.Terrain.getHeights1D());
408 }
409 this.localStorage.SaveMap(this.Terrain.getHeights1D());
410
411 foreach (ClientView client in m_clientThreads.Values)
412 {
413 this.SendLayerData(client);
414 }
415
416 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
417 {
418 Entities[UUID].LandRenegerated();
419 }
420 }
421 catch (Exception e)
422 {
423 MainConsole.Instance.Warn("World.cs: RegenerateTerrain() - Failed with exception " + e.ToString());
424 }
425 }
426
427 /// <summary>
428 /// Rebuilds the terrain assuming changes occured at a specified point[?]
429 /// </summary>
430 /// <param name="changes">???</param>
431 /// <param name="pointx">???</param>
432 /// <param name="pointy">???</param>
433 public void RegenerateTerrain(bool changes, int pointx, int pointy)
434 {
435 try
436 {
437 if (changes)
438 {
439 /* Dont save here, rely on tainting system instead */
440
441 foreach (ClientView client in m_clientThreads.Values)
442 {
443 this.SendLayerData(pointx, pointy, client);
444 }
445 }
446 }
447 catch (Exception e)
448 {
449 MainConsole.Instance.Warn("World.cs: RegenerateTerrain() - Failed with exception " + e.ToString());
450 }
451 }
452
453 #endregion
454
455 #region Load Terrain
456 /// <summary>
457 /// Loads the World heightmap
458 /// </summary>
459 public override void LoadWorldMap()
460 {
461 try
462 {
463 float[] map = this.localStorage.LoadWorld();
464 if (map == null)
465 {
466 if (string.IsNullOrEmpty(this.m_regInfo.TerrainFile))
467 {
468 Console.WriteLine("No default terrain, procedurally generating...");
469 this.Terrain.hills();
470
471 this.localStorage.SaveMap(this.Terrain.getHeights1D());
472 }
473 else
474 {
475 try
476 {
477 this.Terrain.loadFromFileF32(this.m_regInfo.TerrainFile);
478 this.Terrain *= this.m_regInfo.TerrainMultiplier;
479 }
480 catch (Exception e)
481 {
482 Console.WriteLine("Unable to load default terrain, procedurally generating instead...");
483 Terrain.hills();
484 }
485 this.localStorage.SaveMap(this.Terrain.getHeights1D());
486 }
487 }
488 else
489 {
490 this.Terrain.setHeights1D(map);
491 }
492 }
493 catch (Exception e)
494 {
495 MainConsole.Instance.Warn("World.cs: LoadWorldMap() - Failed with exception " + e.ToString());
496 }
497 }
498 #endregion
499
500 #region Primitives Methods
501
502 /// <summary>
503 /// Sends prims to a client
504 /// </summary>
505 /// <param name="RemoteClient">Client to send to</param>
506 public void GetInitialPrims(ClientView RemoteClient)
507 {
508 try
509 {
510 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
511 {
512 if (Entities[UUID] is Primitive)
513 {
514 Primitive primitive = Entities[UUID] as Primitive;
515 primitive.UpdateClient(RemoteClient);
516 }
517 }
518 }
519 catch (Exception e)
520 {
521 MainConsole.Instance.Warn("World.cs: GetInitialPrims() - Failed with exception " + e.ToString());
522 }
523 }
524
525 /// <summary>
526 /// Loads the World's objects
527 /// </summary>
528 public void LoadPrimsFromStorage()
529 {
530 try
531 {
532 MainConsole.Instance.Notice("World.cs: LoadPrimsFromStorage() - Loading primitives");
533 this.localStorage.LoadPrimitives(this);
534 }
535 catch (Exception e)
536 {
537 MainConsole.Instance.Warn("World.cs: LoadPrimsFromStorage() - Failed with exception " + e.ToString());
538 }
539 }
540
541 /// <summary>
542 /// Loads a specific object from storage
543 /// </summary>
544 /// <param name="prim">The object to load</param>
545 public void PrimFromStorage(PrimData prim)
546 {
547 try
548 {
549 if (prim.LocalID >= this._primCount)
550 {
551 _primCount = prim.LocalID + 1;
552 }
553 MainConsole.Instance.Notice("World.cs: PrimFromStorage() - Reloading prim (localId " + prim.LocalID + " ) from storage");
554 Primitive nPrim = new Primitive(m_clientThreads, m_regionHandle, this);
555 nPrim.CreateFromStorage(prim);
556 this.Entities.Add(nPrim.uuid, nPrim);
557 }
558 catch (Exception e)
559 {
560 MainConsole.Instance.Warn("World.cs: PrimFromStorage() - Failed with exception " + e.ToString());
561 }
562 }
563
564 public void AddNewPrim(Packet addPacket, ClientView agentClient)
565 {
566 AddNewPrim((ObjectAddPacket)addPacket, agentClient.AgentID);
567 }
568
569 public void AddNewPrim(ObjectAddPacket addPacket, LLUUID ownerID)
570 {
571 try
572 {
573 MainConsole.Instance.Notice("World.cs: AddNewPrim() - Creating new prim");
574 Primitive prim = new Primitive(m_clientThreads, m_regionHandle, this);
575 prim.CreateFromPacket(addPacket, ownerID, this._primCount);
576 PhysicsVector pVec = new PhysicsVector(prim.Pos.X, prim.Pos.Y, prim.Pos.Z);
577 PhysicsVector pSize = new PhysicsVector(0.255f, 0.255f, 0.255f);
578 if (OpenSim.RegionServer.Simulator.Avatar.PhysicsEngineFlying)
579 {
580 lock (this.LockPhysicsEngine)
581 {
582 prim.PhysActor = this.phyScene.AddPrim(pVec, pSize);
583 }
584 }
585
586 this.Entities.Add(prim.uuid, prim);
587 this._primCount++;
588 }
589 catch (Exception e)
590 {
591 MainConsole.Instance.Warn("World.cs: AddNewPrim() - Failed with exception " + e.ToString());
592 }
593 }
594
595 #endregion
596
597 #region Add/Remove Avatar Methods
598
599 public override Avatar AddViewerAgent(ClientView agentClient)
600 {
601 //register for events
602 agentClient.OnChatFromViewer += new ChatFromViewer(this.SimChat);
603 agentClient.OnRezObject += new RezObject(this.RezObject);
604 agentClient.OnModifyTerrain += new ModifyTerrain(this.ModifyTerrain);
605 agentClient.OnRegionHandShakeReply += new ClientView.GenericCall(this.SendLayerData);
606 agentClient.OnRequestWearables += new ClientView.GenericCall(this.GetInitialPrims);
607 agentClient.OnRequestAvatarsData += new ClientView.GenericCall(this.SendAvatarsToClient);
608 agentClient.OnLinkObjects += new LinkObjects(this.LinkObjects);
609 agentClient.OnAddPrim += new ClientView.GenericCall4(this.AddNewPrim);
610 agentClient.OnUpdatePrimShape += new ClientView.UpdateShape(this.UpdatePrimShape);
611
612 agentClient.OnObjectSelect += new ClientView.ObjectSelect(this.SelectPrim);
613 agentClient.OnUpdatePrimFlags += new ClientView.UpdatePrimFlags(this.UpdatePrimFlags);
614 agentClient.OnUpdatePrimTexture += new ClientView.UpdatePrimTexture(this.UpdatePrimTexture);
615 agentClient.OnUpdatePrimPosition += new ClientView.UpdatePrimVector(this.UpdatePrimPosition);
616 agentClient.OnUpdatePrimRotation += new ClientView.UpdatePrimRotation(this.UpdatePrimRotation);
617 agentClient.OnUpdatePrimScale += new ClientView.UpdatePrimVector(this.UpdatePrimScale);
618 agentClient.OnDeRezObject += new ClientView.GenericCall4(this.DeRezObject);
619
620 agentClient.OnParcelPropertiesRequest += new OpenSim.RegionServer.Simulator.ParcelPropertiesRequest(ParcelPropertiesRequest);
621 agentClient.OnParcelDivideRequest += new OpenSim.RegionServer.Simulator.ParcelDivideRequest(ParcelDivideRequest);
622 agentClient.OnParcelJoinRequest+=new OpenSim.RegionServer.Simulator.ParcelJoinRequest(ParcelJoinRequest);
623 agentClient.OnParcelPropertiesUpdateRequest += new OpenSim.RegionServer.Simulator.ParcelPropertiesUpdateRequest(ParcelPropertiesUpdateRequest);
624 Avatar newAvatar = null;
625 try
626 {
627 MainConsole.Instance.Notice("World.cs:AddViewerAgent() - Creating new avatar for remote viewer agent");
628 newAvatar = new Avatar(agentClient, this, m_regionName, m_clientThreads, m_regionHandle, true, 20);
629 MainConsole.Instance.Notice("World.cs:AddViewerAgent() - Adding new avatar to world");
630 MainConsole.Instance.Notice("World.cs:AddViewerAgent() - Starting RegionHandshake ");
631 newAvatar.SendRegionHandshake(this);
632 //if (!agentClient.m_child)
633 //{
634
635 PhysicsVector pVec = new PhysicsVector(newAvatar.Pos.X, newAvatar.Pos.Y, newAvatar.Pos.Z);
636 lock (this.LockPhysicsEngine)
637 {
638 newAvatar.PhysActor = this.phyScene.AddAvatar(pVec);
639 }
640 // }
641 lock (Entities)
642 {
643 if (!Entities.ContainsKey(agentClient.AgentID))
644 {
645 this.Entities.Add(agentClient.AgentID, newAvatar);
646 }
647 else
648 {
649 Entities[agentClient.AgentID] = newAvatar;
650 }
651 }
652 lock (Avatars)
653 {
654 if (Avatars.ContainsKey(agentClient.AgentID))
655 {
656 Avatars[agentClient.AgentID] = newAvatar;
657 }
658 else
659 {
660 this.Avatars.Add(agentClient.AgentID, newAvatar);
661 }
662 }
663 }
664 catch (Exception e)
665 {
666 MainConsole.Instance.Warn("World.cs: AddViewerAgent() - Failed with exception " + e.ToString());
667 }
668 return newAvatar;
669 }
670
671
672
673
674
675
676
677 public override void RemoveViewerAgent(ClientView agentClient)
678 {
679 try
680 {
681 lock (Entities)
682 {
683 Entities.Remove(agentClient.AgentID);
684 }
685 lock (Avatars)
686 {
687 Avatars.Remove(agentClient.AgentID);
688 }
689 if (agentClient.ClientAvatar.PhysActor != null)
690 {
691 this.phyScene.RemoveAvatar(agentClient.ClientAvatar.PhysActor);
692 }
693 }
694 catch (Exception e)
695 {
696 MainConsole.Instance.Warn("World.cs: RemoveViewerAgent() - Failed with exception " + e.ToString());
697 }
698 }
699 #endregion
700
701 #region Request Avatars List Methods
702 //The idea is to have a group of method that return a list of avatars meeting some requirement
703 // ie it could be all Avatars within a certain range of the calling prim/avatar.
704
705 public List<Avatar> RequestAvatarList()
706 {
707 List<Avatar> result = new List<Avatar>();
708
709 foreach (Avatar avatar in Avatars.Values)
710 {
711 result.Add(avatar);
712 }
713
714 return result;
715 }
716 #endregion
717
718 #region ShutDown
719 /// <summary>
720 /// Tidy before shutdown
721 /// </summary>
722 public override void Close()
723 {
724 try
725 {
726 this.localStorage.ShutDown();
727 }
728 catch (Exception e)
729 {
730 OpenSim.Framework.Console.MainConsole.Instance.Error("World.cs: Close() - Failed with exception " + e.ToString());
731 }
732 }
733 #endregion
734
735 }
736}