From aae0222f8154a32d71112a8a468412efa5b857da Mon Sep 17 00:00:00 2001 From: MW Date: Thu, 17 May 2007 10:24:10 +0000 Subject: More OO and abstract goodness for Gareth to drool over. Cleaned up the World class a bit and added a WorldBase class (that World now inherits from) --- OpenSim.RegionServer/OpenSim.RegionServer.csproj | 526 +++++++++++---------- .../OpenSim.RegionServer.dll.build | 179 +++---- OpenSim.RegionServer/PacketServer.cs | 5 + OpenSim.RegionServer/world/World.PacketHandlers.cs | 1 + OpenSim.RegionServer/world/World.cs | 302 +++++------- OpenSim.RegionServer/world/WorldBase.cs | 176 +++++++ 6 files changed, 662 insertions(+), 527 deletions(-) create mode 100644 OpenSim.RegionServer/world/WorldBase.cs (limited to 'OpenSim.RegionServer') diff --git a/OpenSim.RegionServer/OpenSim.RegionServer.csproj b/OpenSim.RegionServer/OpenSim.RegionServer.csproj index 47b269e..100622b 100644 --- a/OpenSim.RegionServer/OpenSim.RegionServer.csproj +++ b/OpenSim.RegionServer/OpenSim.RegionServer.csproj @@ -1,255 +1,271 @@ - - - Local - 8.0.50727 - 2.0 - {58019DB8-0000-0000-0000-000000000000} - Debug - AnyCPU - - - - OpenSim.RegionServer - JScript - Grid - IE50 - false - Library - - OpenSim.RegionServer - - - - - - False - 285212672 - False - - - TRACE - - False - 4096 - True - ../bin/ - False - False - False - 4 - - - - False - 285212672 - False - - - TRACE;DEBUG - - True - 4096 - False - ../bin/ - False - False - False - 4 - - - - - System.dll - False - - - System.Xml.dll - False - - - ..\bin\libsecondlife.dll - False - - - ..\bin\Axiom.MathLib.dll - False - - - ..\bin\Db4objects.Db4o.dll - False - - - - - OpenSim.Terrain.BasicTerrain - {9CBFE2C1-0000-0000-0000-000000000000} - {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - False - - - OpenSim.Framework - {7404933D-0000-0000-0000-000000000000} - {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - False - - - OpenSim.Framework.Console - {16759386-0000-0000-0000-000000000000} - {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - False - - - OpenSim.GenericConfig.Xml - {CAC10AC1-0000-0000-0000-000000000000} - {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - False - - - OpenSim.Physics.Manager - {DA1FDCE5-0000-0000-0000-000000000000} - {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - False - - - OpenSim.Servers - {111F9E8F-0000-0000-0000-000000000000} - {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - False - - - XMLRPC - {9A8B526E-0000-0000-0000-000000000000} - {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - False - - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - - - - - - - + + + Local + 8.0.50727 + 2.0 + {632E1BFD-0000-0000-0000-000000000000} + Debug + AnyCPU + + + + + OpenSim.RegionServer + JScript + Grid + IE50 + false + Library + + + OpenSim.RegionServer + + + + + + + False + 285212672 + False + + + TRACE;DEBUG + + + True + 4096 + False + ..\bin\ + False + False + False + 4 + + + + + False + 285212672 + False + + + TRACE + + + False + 4096 + True + ..\bin\ + False + False + False + 4 + + + + + + System.dll + False + + + + System.Xml.dll + False + + + ..\bin\libsecondlife.dll + False + + + ..\bin\Axiom.MathLib.dll + False + + + ..\bin\Db4objects.Db4o.dll + False + + + + + OpenSim.Terrain.BasicTerrain + {2270B8FE-0000-0000-0000-000000000000} + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + False + + + OpenSim.Framework + {8ACA2445-0000-0000-0000-000000000000} + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + False + + + OpenSim.Framework.Console + {A7CD0630-0000-0000-0000-000000000000} + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + False + + + OpenSim.GenericConfig.Xml + {E88EF749-0000-0000-0000-000000000000} + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + False + + + OpenSim.Physics.Manager + {8BE16150-0000-0000-0000-000000000000} + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + False + + + OpenSim.Servers + {8BB20F0A-0000-0000-0000-000000000000} + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + False + + + XMLRPC + {8E81D43C-0000-0000-0000-000000000000} + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + False + + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + SimClient.cs + Code + + + Code + SimClient.cs + + + Code + SimClient.cs + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + Avatar.cs + + + Code + + + Code + Avatar.cs + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + World.cs + + + Code + World.cs + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + + + + + + + + \ No newline at end of file diff --git a/OpenSim.RegionServer/OpenSim.RegionServer.dll.build b/OpenSim.RegionServer/OpenSim.RegionServer.dll.build index a8e6ea9..35985ac 100644 --- a/OpenSim.RegionServer/OpenSim.RegionServer.dll.build +++ b/OpenSim.RegionServer/OpenSim.RegionServer.dll.build @@ -1,89 +1,90 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenSim.RegionServer/PacketServer.cs b/OpenSim.RegionServer/PacketServer.cs index f0a1f52..098076e 100644 --- a/OpenSim.RegionServer/PacketServer.cs +++ b/OpenSim.RegionServer/PacketServer.cs @@ -49,6 +49,11 @@ namespace OpenSim } + public virtual void AddClientPacketHanlder(PacketType packetType, PacketMethod handler) + { + + } + public virtual void RegisterClientPacketHandlers() { if (this._localWorld != null) diff --git a/OpenSim.RegionServer/world/World.PacketHandlers.cs b/OpenSim.RegionServer/world/World.PacketHandlers.cs index 362bc14..175b777 100644 --- a/OpenSim.RegionServer/world/World.PacketHandlers.cs +++ b/OpenSim.RegionServer/world/World.PacketHandlers.cs @@ -15,6 +15,7 @@ namespace OpenSim.world { public partial class World { + public bool ModifyTerrain(SimClient simClient, Packet packet) { ModifyLandPacket modify = (ModifyLandPacket)packet; diff --git a/OpenSim.RegionServer/world/World.cs b/OpenSim.RegionServer/world/World.cs index 640ab81..72214d4 100644 --- a/OpenSim.RegionServer/world/World.cs +++ b/OpenSim.RegionServer/world/World.cs @@ -18,33 +18,39 @@ using OpenSim.Terrain; namespace OpenSim.world { - public partial class World : ILocalStorageReceiver, IScriptAPI + public partial class World : WorldBase, ILocalStorageReceiver, IScriptAPI { public object LockPhysicsEngine = new object(); - public Dictionary Entities; public Dictionary Avatars; public Dictionary Prims; //public ScriptEngine Scripts; - public TerrainEngine Terrain; //TODO: Replace TerrainManager with this. public uint _localNumber = 0; private PhysicsScene phyScene; private float timeStep = 0.1f; - private libsecondlife.TerrainManager TerrainManager; // To be referenced via TerrainEngine public ILocalStorage localStorage; private Random Rand = new Random(); private uint _primCount = 702000; private int storageCount; - private Dictionary m_clientThreads; private Dictionary m_scriptHandlers; private Dictionary m_scripts; - private ulong m_regionHandle; - private string m_regionName; - private InventoryCache _inventoryCache; - private AssetCache _assetCache; private Mutex updateLock; - private RegionInfo m_regInfo; public string m_datastore; + #region Properties + public PhysicsScene PhysScene + { + set + { + this.phyScene = value; + } + get + { + return (this.phyScene); + } + } + #endregion + + #region Constructors /// /// Creates a new World class, and a region to go with it. /// @@ -85,7 +91,9 @@ namespace OpenSim.world OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.CRITICAL,"World.cs: Constructor failed with exception " + e.ToString()); } } + #endregion + #region Script Methods /// /// Loads a new script into the specified entity /// @@ -156,37 +164,13 @@ namespace OpenSim.world } } - public InventoryCache InventoryCache - { - set - { - this._inventoryCache = value; - } - } - - public AssetCache AssetCache - { - set - { - this._assetCache = value; - } - } - public PhysicsScene PhysScene - { - set - { - this.phyScene = value; - } - get - { - return (this.phyScene); - } - } + #endregion + #region Update Methods /// /// Performs per-frame updates on the world, this should be the central world loop /// - public void Update() + public override void Update() { updateLock.WaitOne(); try @@ -235,6 +219,40 @@ namespace OpenSim.world updateLock.ReleaseMutex(); } + public bool Backup() + { + try + { + // Terrain backup routines + if (Terrain.tainted > 0) + { + Terrain.tainted = 0; + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs: Backup() - Terrain tainted, saving."); + localStorage.SaveMap(Terrain.getHeights1D()); + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs: Backup() - Terrain saved, informing Physics."); + phyScene.SetTerrain(Terrain.getHeights1D()); + } + + // Primitive backup routines + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs: Backup() - Backing up Primitives"); + foreach (libsecondlife.LLUUID UUID in Entities.Keys) + { + Entities[UUID].BackUp(); + } + + // Backup successful + return true; + } + catch (Exception e) + { + // Backup failed + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.HIGH, "World.cs: Backup() - Backup Failed with exception " + e.ToString()); + return false; + } + } + #endregion + + #region Setup Methods /// /// Loads a new storage subsystem from a named library /// @@ -279,6 +297,16 @@ namespace OpenSim.world } } + public void SetDefaultScripts() + { + this.m_scripts.Add("FollowRandomAvatar", delegate() + { + return new OpenSim.RegionServer.world.scripting.FollowRandomAvatar(); + }); + } + + #endregion + #region Regenerate Terrain /// @@ -375,10 +403,11 @@ namespace OpenSim.world #endregion + #region Load Terrain /// /// Loads the World heightmap /// - public void LoadWorldMap() + public override void LoadWorldMap() { try { @@ -400,6 +429,32 @@ namespace OpenSim.world OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM,"World.cs: LoadWorldMap() - Failed with exception " + e.ToString()); } } + #endregion + + #region Primitives Methods + + /// + /// Sends prims to a client + /// + /// Client to send to + public void GetInitialPrims(SimClient RemoteClient) + { + try + { + foreach (libsecondlife.LLUUID UUID in Entities.Keys) + { + if (Entities[UUID] is Primitive) + { + Primitive primitive = Entities[UUID] as Primitive; + primitive.UpdateClient(RemoteClient); + } + } + } + catch (Exception e) + { + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: GetInitialPrims() - Failed with exception " + e.ToString()); + } + } /// /// Loads the World's objects @@ -440,108 +495,37 @@ namespace OpenSim.world } } - /// - /// Tidy before shutdown - /// - public void Close() - { - try - { - this.localStorage.ShutDown(); - } - catch (Exception e) - { - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.HIGH,"World.cs: Close() - Failed with exception " + e.ToString()); - } - } - - /// - /// Send the region heightmap to the client - /// - /// Client to send to - public void SendLayerData(SimClient RemoteClient) + public void AddNewPrim(ObjectAddPacket addPacket, SimClient AgentClient) { try { - int[] patches = new int[4]; - - for (int y = 0; y < 16; y++) + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs: AddNewPrim() - Creating new prim"); + Primitive prim = new Primitive(m_clientThreads, m_regionHandle, this); + prim.CreateFromPacket(addPacket, AgentClient.AgentID, this._primCount); + PhysicsVector pVec = new PhysicsVector(prim.Pos.X, prim.Pos.Y, prim.Pos.Z); + PhysicsVector pSize = new PhysicsVector(0.255f, 0.255f, 0.255f); + if (OpenSim.world.Avatar.PhysicsEngineFlying) { - for (int x = 0; x < 16; x = x + 4) + lock (this.LockPhysicsEngine) { - patches[0] = x + 0 + y * 16; - patches[1] = x + 1 + y * 16; - patches[2] = x + 2 + y * 16; - patches[3] = x + 3 + y * 16; - - Packet layerpack = TerrainManager.CreateLandPacket(Terrain.getHeights1D(), patches); - RemoteClient.OutPacket(layerpack); + prim.PhysActor = this.phyScene.AddPrim(pVec, pSize); } } - } - catch (Exception e) - { - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM,"World.cs: SendLayerData() - Failed with exception " + e.ToString()); - } - } - - /// - /// Sends a specified patch to a client - /// - /// Patch coordinate (x) 0..16 - /// Patch coordinate (y) 0..16 - /// The client to send to - public void SendLayerData(int px, int py, SimClient RemoteClient) - { - try - { - int[] patches = new int[1]; - int patchx, patchy; - patchx = px / 16; - /* if (patchx > 12) - { - patchx = 12; - }*/ - patchy = py / 16; - patches[0] = patchx + 0 + patchy * 16; - //patches[1] = patchx + 1 + patchy * 16; - //patches[2] = patchx + 2 + patchy * 16; - //patches[3] = patchx + 3 + patchy * 16; - - Packet layerpack = TerrainManager.CreateLandPacket(Terrain.getHeights1D(), patches); - RemoteClient.OutPacket(layerpack); + this.Entities.Add(prim.uuid, prim); + this._primCount++; } catch (Exception e) { - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM,"World.cs: SendLayerData() - Failed with exception " + e.ToString()); + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: AddNewPrim() - Failed with exception " + e.ToString()); } } - /// - /// Sends prims to a client - /// - /// Client to send to - public void GetInitialPrims(SimClient RemoteClient) - { - try - { - foreach (libsecondlife.LLUUID UUID in Entities.Keys) - { - if (Entities[UUID] is Primitive) - { - Primitive primitive = Entities[UUID] as Primitive; - primitive.UpdateClient(RemoteClient); - } - } - } - catch (Exception e) - { - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM,"World.cs: GetInitialPrims() - Failed with exception " + e.ToString()); - } - } + #endregion + + #region Add/Remove Avatar Methods - public void AddViewerAgent(SimClient agentClient) + public override void AddViewerAgent(SimClient agentClient) { try { @@ -587,7 +571,7 @@ namespace OpenSim.world } } - public void RemoveViewerAgent(SimClient agentClient) + public override void RemoveViewerAgent(SimClient agentClient) { try { @@ -609,72 +593,24 @@ namespace OpenSim.world OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM,"World.cs: RemoveViewerAgent() - Failed with exception " + e.ToString()); } } + #endregion - public void AddNewPrim(ObjectAddPacket addPacket, SimClient AgentClient) - { - try - { - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW,"World.cs: AddNewPrim() - Creating new prim"); - Primitive prim = new Primitive(m_clientThreads, m_regionHandle, this); - prim.CreateFromPacket(addPacket, AgentClient.AgentID, this._primCount); - PhysicsVector pVec = new PhysicsVector(prim.Pos.X, prim.Pos.Y, prim.Pos.Z); - PhysicsVector pSize = new PhysicsVector(0.255f, 0.255f, 0.255f); - if (OpenSim.world.Avatar.PhysicsEngineFlying) - { - lock (this.LockPhysicsEngine) - { - prim.PhysActor = this.phyScene.AddPrim(pVec, pSize); - } - } - - this.Entities.Add(prim.uuid, prim); - this._primCount++; - } - catch (Exception e) - { - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM,"World.cs: AddNewPrim() - Failed with exception " + e.ToString()); - } - } - - public bool Backup() + #region ShutDown + /// + /// Tidy before shutdown + /// + public override void Close() { try { - // Terrain backup routines - if (Terrain.tainted > 0) - { - Terrain.tainted = 0; - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW,"World.cs: Backup() - Terrain tainted, saving."); - localStorage.SaveMap(Terrain.getHeights1D()); - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW,"World.cs: Backup() - Terrain saved, informing Physics."); - phyScene.SetTerrain(Terrain.getHeights1D()); - } - - // Primitive backup routines - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW,"World.cs: Backup() - Backing up Primitives"); - foreach (libsecondlife.LLUUID UUID in Entities.Keys) - { - Entities[UUID].BackUp(); - } - - // Backup successful - return true; + this.localStorage.ShutDown(); } catch (Exception e) { - // Backup failed - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.HIGH,"World.cs: Backup() - Backup Failed with exception " + e.ToString()); - return false; + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.HIGH, "World.cs: Close() - Failed with exception " + e.ToString()); } } - - public void SetDefaultScripts() - { - this.m_scripts.Add("FollowRandomAvatar", delegate() - { - return new OpenSim.RegionServer.world.scripting.FollowRandomAvatar(); - }); - } + #endregion } } diff --git a/OpenSim.RegionServer/world/WorldBase.cs b/OpenSim.RegionServer/world/WorldBase.cs new file mode 100644 index 0000000..b8c086d --- /dev/null +++ b/OpenSim.RegionServer/world/WorldBase.cs @@ -0,0 +1,176 @@ +using System; +using libsecondlife; +using libsecondlife.Packets; +using System.Collections.Generic; +using System.Text; +using System.Reflection; +using System.IO; +using System.Threading; +using OpenSim.Physics.Manager; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Terrain; +using OpenSim.Framework.Inventory; +using OpenSim.Assets; +using OpenSim.RegionServer.world.scripting; +using OpenSim.Terrain; + +namespace OpenSim.world +{ + public class WorldBase + { + public Dictionary Entities; + protected Dictionary m_clientThreads; + protected ulong m_regionHandle; + protected string m_regionName; + protected InventoryCache _inventoryCache; + protected AssetCache _assetCache; + protected RegionInfo m_regInfo; + + public TerrainEngine Terrain; //TODO: Replace TerrainManager with this. + protected libsecondlife.TerrainManager TerrainManager; // To be referenced via TerrainEngine + + #region Properties + public InventoryCache InventoryCache + { + set + { + this._inventoryCache = value; + } + } + + public AssetCache AssetCache + { + set + { + this._assetCache = value; + } + } + #endregion + + #region Constructors + public WorldBase() + { + + } + #endregion + + #region Setup Methods + /// + /// Register Packet handler Methods with the packet server (which will register them with the SimClient) + /// + /// + public virtual void RegisterPacketHandlers(PacketServer packetServer) + { + + } + #endregion + + #region Update Methods + /// + /// Normally called once every frame/tick to let the world preform anything required (like running the physics simulation) + /// + public virtual void Update() + { + + } + #endregion + + #region Terrain Methods + + /// + /// Loads the World heightmap + /// + public virtual void LoadWorldMap() + { + + } + + /// + /// Send the region heightmap to the client + /// + /// Client to send to + public virtual void SendLayerData(SimClient RemoteClient) + { + try + { + int[] patches = new int[4]; + + for (int y = 0; y < 16; y++) + { + for (int x = 0; x < 16; x = x + 4) + { + patches[0] = x + 0 + y * 16; + patches[1] = x + 1 + y * 16; + patches[2] = x + 2 + y * 16; + patches[3] = x + 3 + y * 16; + + Packet layerpack = TerrainManager.CreateLandPacket(Terrain.getHeights1D(), patches); + RemoteClient.OutPacket(layerpack); + } + } + } + catch (Exception e) + { + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: SendLayerData() - Failed with exception " + e.ToString()); + } + } + + /// + /// Sends a specified patch to a client + /// + /// Patch coordinate (x) 0..16 + /// Patch coordinate (y) 0..16 + /// The client to send to + public void SendLayerData(int px, int py, SimClient RemoteClient) + { + try + { + int[] patches = new int[1]; + int patchx, patchy; + patchx = px / 16; + patchy = py / 16; + + patches[0] = patchx + 0 + patchy * 16; + + Packet layerpack = TerrainManager.CreateLandPacket(Terrain.getHeights1D(), patches); + RemoteClient.OutPacket(layerpack); + } + catch (Exception e) + { + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: SendLayerData() - Failed with exception " + e.ToString()); + } + } + #endregion + + #region Add/Remove Agent/Avatar + /// + /// Add a new Agent's avatar + /// + /// + public virtual void AddViewerAgent(SimClient agentClient) + { + + } + + /// + /// Remove a Agent's avatar + /// + /// + public virtual void RemoveViewerAgent(SimClient agentClient) + { + + } + #endregion + + #region Shutdown + /// + /// Tidy before shutdown + /// + public virtual void Close() + { + + } + #endregion + } +} -- cgit v1.1