* 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
This commit is contained in:
John Hurliman
2008-09-24 14:55:52 +00:00
parent 48aa4a6c19
commit 8eef021fa7
5 changed files with 275 additions and 25 deletions

View File

@@ -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<UUID, InventoryObject> Inventory = new Dictionary<UUID, InventoryObject>();
public Dictionary<UUID, InventoryObject> Library = new Dictionary<UUID, InventoryObject>();
public Dictionary<WearableType, UUID> Wearables = new Dictionary<WearableType, UUID>();
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<UUID, InventoryObject> Inventory = new Dictionary<UUID, InventoryObject>();
[NonSerialized]
public Dictionary<UUID, InventoryObject> Library = new Dictionary<UUID, InventoryObject>();
// 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;
}
}
}
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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<IncomingPacket> packetInbox = new BlockingQueue<IncomingPacket>(Settings.PACKET_INBOX_SIZE);
/// <summary></summary>
DoubleDictionary<UUID, IPEndPoint, UDPClient> clients = new DoubleDictionary<UUID, IPEndPoint, UDPClient>();
/// <summary></summary>
Dictionary<uint, Agent> unassociatedAgents = new Dictionary<uint, Agent>();
/// <summary></summary>
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;
}
}
}
}

View File

@@ -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);