From 8eef021fa7bdbecb8b2fb921ce6c00f477899f77 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Wed, 24 Sep 2008 14:55:52 +0000 Subject: [PATCH] Simian: * Added lots of members to Agent, preparing for serialization * Added Clear() and Count to DoubleDictionary * Moved CreateCircuit and unassociatedAgents functionality out of Simian core and into UDPServer extension git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@2237 52acb1d6-8a22-11de-b505-999d5b087335 --- Programs/Simian/Agent.cs | 125 +++++++++++++++++--- Programs/Simian/DoubleDictionary.cs | 14 +++ Programs/Simian/Extensions/AvatarManager.cs | 101 +++++++++++++++- Programs/Simian/Extensions/UDPServer.cs | 58 ++++++++- Programs/Simian/Interfaces/IUDPProvider.cs | 2 +- 5 files changed, 275 insertions(+), 25 deletions(-) diff --git a/Programs/Simian/Agent.cs b/Programs/Simian/Agent.cs index ee4af900..5184c18c 100644 --- a/Programs/Simian/Agent.cs +++ b/Programs/Simian/Agent.cs @@ -9,28 +9,117 @@ namespace Simian { public class Agent { + // Account public UUID AgentID; - public UUID SessionID; - public UUID SecureSessionID; - public uint CircuitCode; public string FirstName; public string LastName; - public Avatar Avatar = new Avatar(); + public string PasswordHash; + public uint CreationTime; + public uint LastLoginTime; + public string AccessLevel; + public int GodLevel; public int Balance; - public bool Running; - public int TickFall; - public int TickJump; - public int TickLastPacketReceived; - public AgentManager.ControlFlags ControlFlags = AgentManager.ControlFlags.NONE; - public AnimationSet Animations = new AnimationSet(); - public Dictionary Inventory = new Dictionary(); - public Dictionary Library = new Dictionary(); - public Dictionary Wearables = new Dictionary(); - public byte[] VisualParams = new byte[218]; - // TODO: Replace byte with enum - public byte State; - public PrimFlags Flags; + + // Inventory public UUID InventoryRoot; - public UUID InventoryLibRoot; + public UUID InventoryLibraryRoot; + public UUID InventoryLibraryOwner; + + // Location + public ulong HomeRegionHandle; + public Vector3 HomePosition; + public Vector3 HomeLookAt; + public ulong CurrentRegionHandle; + public Vector3 CurrentPosition; + public Vector3 CurrentLookAt; + + // Profile + public UUID PartnerID; + public int ProfileCanDo; + public int ProfileWantDo; + public string ProfileAboutText; + public string ProfileFirstText; + public UUID ProfileImage; + public UUID ProfileFirstImage; + + // Appearance + public byte[] VisualParams; + public byte[] Texture; + public float Height; + public UUID ShapeItem; + public UUID ShapeAsset; + public UUID SkinItem; + public UUID SkinAsset; + public UUID HairItem; + public UUID HairAsset; + public UUID EyesItem; + public UUID EyesAsset; + public UUID ShirtItem; + public UUID ShirtAsset; + public UUID PantsItem; + public UUID PantsAsset; + public UUID ShoesItem; + public UUID ShoesAsset; + public UUID SocksItem; + public UUID SocksAsset; + public UUID JacketItem; + public UUID JacketAsset; + public UUID GlovesItem; + public UUID GlovesAsset; + public UUID UndershirtItem; + public UUID UndershirtAsset; + public UUID UnderpantsItem; + public UUID UnderpantsAsset; + public UUID SkirtItem; + public UUID SkirtAsset; + + // Temporary + [NonSerialized] + public Avatar Avatar = new Avatar(); + [NonSerialized] + public UUID SessionID; + [NonSerialized] + public UUID SecureSessionID; + [NonSerialized] + public uint CircuitCode; + [NonSerialized] + public bool Running; + [NonSerialized] + public int TickFall; + [NonSerialized] + public int TickJump; + [NonSerialized] + public int TickLastPacketReceived; + [NonSerialized] + public AgentManager.ControlFlags ControlFlags = AgentManager.ControlFlags.NONE; + [NonSerialized] + public AnimationSet Animations = new AnimationSet(); + [NonSerialized] + public Dictionary Inventory = new Dictionary(); + [NonSerialized] + public Dictionary Library = new Dictionary(); + // TODO: Replace byte with enum + [NonSerialized] + public byte State; + [NonSerialized] + public PrimFlags Flags; + + public string FullName + { + get + { + bool hasFirst = !String.IsNullOrEmpty(FirstName); + bool hasLast = !String.IsNullOrEmpty(LastName); + + if (hasFirst && hasLast) + return String.Format("{0} {1}", FirstName, LastName); + else if (hasFirst) + return FirstName; + else if (hasLast) + return LastName; + else + return String.Empty; + } + } } } diff --git a/Programs/Simian/DoubleDictionary.cs b/Programs/Simian/DoubleDictionary.cs index 15a33cbf..0beb6c3d 100644 --- a/Programs/Simian/DoubleDictionary.cs +++ b/Programs/Simian/DoubleDictionary.cs @@ -39,6 +39,20 @@ namespace Simian } } + public void Clear() + { + lock (syncObject) + { + Dictionary1.Clear(); + Dictionary2.Clear(); + } + } + + public int Count + { + get { return Dictionary1.Count; } + } + public bool TryGetValue(TKey1 key, out TValue value) { return Dictionary1.TryGetValue(key, out value); diff --git a/Programs/Simian/Extensions/AvatarManager.cs b/Programs/Simian/Extensions/AvatarManager.cs index e8c68b82..882da01d 100644 --- a/Programs/Simian/Extensions/AvatarManager.cs +++ b/Programs/Simian/Extensions/AvatarManager.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Threading; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenMetaverse.Packets; namespace Simian.Extensions @@ -190,18 +191,107 @@ namespace Simian.Extensions Server.UDP.SendPacket(agent.AgentID, update, PacketCategory.Asset); } + void ClearWearables(Agent agent) + { + agent.ShapeItem = UUID.Zero; + agent.ShapeAsset = UUID.Zero; + agent.SkinItem = UUID.Zero; + agent.SkinAsset = UUID.Zero; + agent.HairItem = UUID.Zero; + agent.HairAsset = UUID.Zero; + agent.EyesItem = UUID.Zero; + agent.EyesAsset = UUID.Zero; + agent.ShirtItem = UUID.Zero; + agent.ShirtAsset = UUID.Zero; + agent.PantsItem = UUID.Zero; + agent.PantsAsset = UUID.Zero; + agent.ShoesItem = UUID.Zero; + agent.ShoesAsset = UUID.Zero; + agent.SocksItem = UUID.Zero; + agent.SocksAsset = UUID.Zero; + agent.JacketItem = UUID.Zero; + agent.JacketAsset = UUID.Zero; + agent.GlovesItem = UUID.Zero; + agent.GlovesAsset = UUID.Zero; + agent.UndershirtItem = UUID.Zero; + agent.UndershirtAsset = UUID.Zero; + agent.UnderpantsItem = UUID.Zero; + agent.UnderpantsAsset = UUID.Zero; + agent.SkirtItem = UUID.Zero; + agent.SkirtAsset = UUID.Zero; + } + void AgentIsNowWearingHandler(Packet packet, Agent agent) { AgentIsNowWearingPacket wearing = (AgentIsNowWearingPacket)packet; Logger.DebugLog("Updating agent wearables"); + ClearWearables(agent); - lock (agent.Wearables) + for (int i = 0; i < wearing.WearableData.Length; i++) { - agent.Wearables.Clear(); + UUID assetID = UUID.Zero; + UUID itemID = wearing.WearableData[i].ItemID; - for (int i = 0; i < wearing.WearableData.Length; i++) - agent.Wearables[(WearableType)wearing.WearableData[i].WearableType] = wearing.WearableData[i].ItemID; + InventoryObject invObj; + if (agent.Inventory.TryGetValue(itemID, out invObj) && invObj is InventoryItem) + assetID = ((InventoryItem)invObj).AssetID; + + switch ((WearableType)wearing.WearableData[i].WearableType) + { + case WearableType.Shape: + agent.ShapeAsset = assetID; + agent.ShapeItem = itemID; + break; + case WearableType.Skin: + agent.SkinAsset = assetID; + agent.SkinItem = itemID; + break; + case WearableType.Hair: + agent.HairAsset = assetID; + agent.HairItem = itemID; + break; + case WearableType.Eyes: + agent.EyesAsset = assetID; + agent.EyesItem = itemID; + break; + case WearableType.Shirt: + agent.ShirtAsset = assetID; + agent.ShirtItem = itemID; + break; + case WearableType.Pants: + agent.PantsAsset = assetID; + agent.PantsItem = itemID; + break; + case WearableType.Shoes: + agent.ShoesAsset = assetID; + agent.ShoesItem = itemID; + break; + case WearableType.Socks: + agent.SocksAsset = assetID; + agent.SocksItem = itemID; + break; + case WearableType.Jacket: + agent.JacketAsset = assetID; + agent.JacketItem = itemID; + break; + case WearableType.Gloves: + agent.GlovesAsset = assetID; + agent.GlovesItem = itemID; + break; + case WearableType.Undershirt: + agent.UndershirtAsset = assetID; + agent.UndershirtItem = itemID; + break; + case WearableType.Underpants: + agent.UnderpantsAsset = assetID; + agent.UnderpantsItem = itemID; + break; + case WearableType.Skirt: + agent.SkirtAsset = assetID; + agent.SkirtItem = itemID; + break; + } } } @@ -215,6 +305,9 @@ namespace Simian.Extensions set.ObjectData.TextureEntry.Length); // Update agent visual params + if (agent.VisualParams == null) + agent.VisualParams = new byte[set.VisualParam.Length]; + for (int i = 0; i < set.VisualParam.Length; i++) agent.VisualParams[i] = set.VisualParam[i].ParamValue; diff --git a/Programs/Simian/Extensions/UDPServer.cs b/Programs/Simian/Extensions/UDPServer.cs index d0ab374f..05879897 100644 --- a/Programs/Simian/Extensions/UDPServer.cs +++ b/Programs/Simian/Extensions/UDPServer.cs @@ -123,6 +123,11 @@ namespace Simian return udpServer.RemoveClient(agent, endpoint); } + public uint CreateCircuit(Agent agent) + { + return udpServer.CreateCircuit(agent); + } + public void SendPacket(UUID agentID, Packet packet, PacketCategory category) { udpServer.SendPacket(agentID, packet, category); @@ -150,6 +155,10 @@ namespace Simian BlockingQueue packetInbox = new BlockingQueue(Settings.PACKET_INBOX_SIZE); /// DoubleDictionary clients = new DoubleDictionary(); + /// + Dictionary unassociatedAgents = new Dictionary(); + /// + int currentCircuitCode = 0; public UDPServer(int port, Simian server) : base(port) @@ -192,6 +201,19 @@ namespace Simian return clients.Remove(agent.AgentID, endpoint); } + public uint CreateCircuit(Agent agent) + { + uint circuitCode = (uint)Interlocked.Increment(ref currentCircuitCode); + + // Put this client in the list of clients that have not been associated with an IPEndPoint yet + lock (unassociatedAgents) + unassociatedAgents[circuitCode] = agent; + + Logger.Log("Created a circuit for " + agent.FirstName, Helpers.LogLevel.Info); + + return circuitCode; + } + public void BroadcastPacket(Packet packet, PacketCategory category) { clients.ForEach( @@ -478,7 +500,7 @@ namespace Simian UseCircuitCodePacket useCircuitCode = (UseCircuitCodePacket)packet; Agent agent; - if (server.CompleteAgentConnection(useCircuitCode.CircuitCode.Code, out agent)) + if (CompleteAgentConnection(useCircuitCode.CircuitCode.Code, out agent)) { AddClient(agent, address); if (clients.TryGetValue(agent.AgentID, out client)) @@ -532,7 +554,7 @@ namespace Simian { } - private void IncomingPacketHandler() + void IncomingPacketHandler() { IncomingPacket incomingPacket = new IncomingPacket(); Packet packet = null; @@ -616,5 +638,37 @@ namespace Simian } } } + + bool TryGetUnassociatedAgent(uint circuitCode, out Agent agent) + { + if (unassociatedAgents.TryGetValue(circuitCode, out agent)) + { + lock (unassociatedAgents) + unassociatedAgents.Remove(circuitCode); + + return true; + } + else + { + return false; + } + } + + bool CompleteAgentConnection(uint circuitCode, out Agent agent) + { + if (unassociatedAgents.TryGetValue(circuitCode, out agent)) + { + lock (server.Agents) + server.Agents[agent.AgentID] = agent; + lock (unassociatedAgents) + unassociatedAgents.Remove(circuitCode); + + return true; + } + else + { + return false; + } + } } } diff --git a/Programs/Simian/Interfaces/IUDPProvider.cs b/Programs/Simian/Interfaces/IUDPProvider.cs index 8ae50439..ced107f6 100644 --- a/Programs/Simian/Interfaces/IUDPProvider.cs +++ b/Programs/Simian/Interfaces/IUDPProvider.cs @@ -37,9 +37,9 @@ namespace Simian void AddClient(Agent agent, IPEndPoint endpoint); bool RemoveClient(Agent agent); bool RemoveClient(Agent agent, IPEndPoint endpoint); + uint CreateCircuit(Agent agent); void SendPacket(UUID agentID, Packet packet, PacketCategory category); - void BroadcastPacket(Packet packet, PacketCategory category); void RegisterPacketCallback(PacketType type, PacketCallback callback);