From f656d185a3fdb0248a36f812e047592704c9981d Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Thu, 4 Sep 2008 21:09:44 +0000 Subject: [PATCH] * Removed unused AgentManager.AgentMovementCallback * Added Avatar.ControlFlags (not used by libomv directly) Simian: * Added ISceneProvider interface * Fixed ObjectSelect crash (due to a packet block not being filled out if the selected object was missing) * Simplified BuildFullUpdate() git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@2196 52acb1d6-8a22-11de-b505-999d5b087335 --- OpenMetaverse/AgentManager.cs | 10 --- OpenMetaverse/Avatar.cs | 3 + Programs/Simian/Extensions/AvatarManager.cs | 3 +- Programs/Simian/Extensions/Movement.cs | 3 +- Programs/Simian/Extensions/ObjectManager.cs | 95 +++++++------------- Programs/Simian/Extensions/SceneManager.cs | 95 +++++++++++++++++--- Programs/Simian/Interfaces/ISceneProvider.cs | 23 +++++ Programs/Simian/Simian.cs | 18 ++-- Programs/Simian/SimulationObject.cs | 13 ++- 9 files changed, 165 insertions(+), 98 deletions(-) create mode 100644 Programs/Simian/Interfaces/ISceneProvider.cs diff --git a/OpenMetaverse/AgentManager.cs b/OpenMetaverse/AgentManager.cs index ae0026ad..fac590d6 100644 --- a/OpenMetaverse/AgentManager.cs +++ b/OpenMetaverse/AgentManager.cs @@ -889,16 +889,6 @@ namespace OpenMetaverse public delegate void AvatarSitResponseCallback(UUID objectID, bool autoPilot, Vector3 cameraAtOffset, Vector3 cameraEyeOffset, bool forceMouselook, Vector3 sitPosition, Quaternion sitRotation); - /// - /// - /// - /// - /// - /// - /// - public delegate void AgentMovementCallback(Vector3 agentPosition, ulong regionHandle, - Vector3 agentLookAt, string simVersion); - #endregion Callbacks #region Events diff --git a/OpenMetaverse/Avatar.cs b/OpenMetaverse/Avatar.cs index 24757a66..dce43d4f 100644 --- a/OpenMetaverse/Avatar.cs +++ b/OpenMetaverse/Avatar.cs @@ -204,6 +204,9 @@ namespace OpenMetaverse /// Avatar interests including spoken languages, skills, and "want to" /// choices public Interests ProfileInterests; + /// Movement control flags for avatars. Typically not set or used by + /// clients. To move your avatar, use Client.Self.Movement instead + public AgentManager.ControlFlags ControlFlags; #endregion Public Members diff --git a/Programs/Simian/Extensions/AvatarManager.cs b/Programs/Simian/Extensions/AvatarManager.cs index 447cd5e3..55c7fbc3 100644 --- a/Programs/Simian/Extensions/AvatarManager.cs +++ b/Programs/Simian/Extensions/AvatarManager.cs @@ -221,8 +221,7 @@ namespace Simian.Extensions //TODO: What is WearableData used for? ObjectUpdatePacket update = SimulationObject.BuildFullUpdate(agent.Avatar, - NameValue.NameValuesToString(agent.Avatar.NameValues), Server.RegionHandle, - agent.State, agent.Flags | PrimFlags.ObjectYouOwner); + Server.RegionHandle, agent.State, agent.Flags | PrimFlags.ObjectYouOwner); Server.UDP.SendPacket(agent.AgentID, update, PacketCategory.State); // Send out this appearance to all other connected avatars diff --git a/Programs/Simian/Extensions/Movement.cs b/Programs/Simian/Extensions/Movement.cs index 88d55ce3..4009ab00 100644 --- a/Programs/Simian/Extensions/Movement.cs +++ b/Programs/Simian/Extensions/Movement.cs @@ -339,8 +339,7 @@ namespace Simian.Extensions agent.Flags = (PrimFlags)update.AgentData.Flags; ObjectUpdatePacket fullUpdate = SimulationObject.BuildFullUpdate(agent.Avatar, - NameValue.NameValuesToString(agent.Avatar.NameValues), server.RegionHandle, - agent.State, agent.Flags); + server.RegionHandle, agent.State, agent.Flags); server.UDP.BroadcastPacket(fullUpdate, PacketCategory.State); } diff --git a/Programs/Simian/Extensions/ObjectManager.cs b/Programs/Simian/Extensions/ObjectManager.cs index 1c13466b..7f42a990 100644 --- a/Programs/Simian/Extensions/ObjectManager.cs +++ b/Programs/Simian/Extensions/ObjectManager.cs @@ -10,8 +10,7 @@ namespace Simian.Extensions public class ObjectManager : ISimianExtension { Simian Server; - DoubleDictionary SceneObjects = new DoubleDictionary(); - int CurrentLocalID = 0; + public ObjectManager(Simian server) { @@ -29,24 +28,12 @@ namespace Simian.Extensions Server.UDP.RegisterPacketCallback(PacketType.DeRezObject, new PacketCallback(DeRezObjectHandler)); Server.UDP.RegisterPacketCallback(PacketType.MultipleObjectUpdate, new PacketCallback(MultipleObjectUpdateHandler)); Server.UDP.RegisterPacketCallback(PacketType.RequestObjectPropertiesFamily, new PacketCallback(RequestObjectPropertiesFamilyHandler)); - Server.UDP.RegisterPacketCallback(PacketType.CompleteAgentMovement, new PacketCallback(CompleteAgentMovementHandler)); //HACK: show prims } public void Stop() { } - //TODO: Add interest list instead of this hack - void CompleteAgentMovementHandler(Packet packet, Agent agent) - { - CompleteAgentMovementPacket complete = (CompleteAgentMovementPacket)packet; - SceneObjects.ForEach(delegate(SimulationObject obj) - { - ObjectUpdatePacket update = SimulationObject.BuildFullUpdate(obj.Prim, String.Empty, obj.Prim.RegionHandle, 0, obj.Prim.Flags); - Server.UDP.SendPacket(agent.AgentID, update, PacketCategory.State); - }); - } - void ObjectAddHandler(Packet packet, Agent agent) { ObjectAddPacket add = (ObjectAddPacket)packet; @@ -70,7 +57,7 @@ namespace Simian.Extensions if (add.ObjectData.RayTargetID != UUID.Zero) { SimulationObject obj; - if (SceneObjects.TryGetValue(add.ObjectData.RayTargetID, out obj)) + if (Server.Scene.TryGetObject(add.ObjectData.RayTargetID, out obj)) { // Test for a collision with the specified object position = ObjectCollisionTest(add.ObjectData.RayStart, add.ObjectData.RayEnd, obj); @@ -131,7 +118,6 @@ namespace Simian.Extensions // TODO: Security check prim.GroupID = add.AgentData.GroupID; prim.ID = UUID.Random(); - prim.LocalID = (uint)Interlocked.Increment(ref CurrentLocalID); prim.MediaURL = String.Empty; prim.OwnerID = agent.AgentID; prim.Position = position; @@ -176,25 +162,7 @@ namespace Simian.Extensions // Add this prim to the object database SimulationObject simObj = new SimulationObject(prim, Server); - - SceneObjects.Add(prim.LocalID, prim.ID, simObj); - - // Send an update out to the creator - ObjectUpdatePacket updateToOwner = SimulationObject.BuildFullUpdate(prim, String.Empty, prim.RegionHandle, 0, - prim.Flags | PrimFlags.CreateSelected | PrimFlags.ObjectYouOwner); - Server.UDP.SendPacket(agent.AgentID, updateToOwner, PacketCategory.State); - - // Send an update out to everyone else - ObjectUpdatePacket updateToOthers = SimulationObject.BuildFullUpdate(prim, String.Empty, prim.RegionHandle, 0, - prim.Flags); - lock (Server.Agents) - { - foreach (Agent recipient in Server.Agents.Values) - { - if (recipient != agent) - Server.UDP.SendPacket(recipient.AgentID, updateToOthers, PacketCategory.State); - } - } + Server.Scene.AddObject(agent, simObj); } void ObjectSelectHandler(Packet packet, Agent agent) @@ -209,7 +177,7 @@ namespace Simian.Extensions properties.ObjectData[i] = new ObjectPropertiesPacket.ObjectDataBlock(); SimulationObject obj; - if (SceneObjects.TryGetValue(select.ObjectData[i].ObjectLocalID, out obj)) + if (Server.Scene.TryGetObject(select.ObjectData[i].ObjectLocalID, out obj)) { properties.ObjectData[i].BaseMask = (uint)obj.Prim.Properties.Permissions.BaseMask; properties.ObjectData[i].CreationDate = Utils.DateTimeToUnixTime(obj.Prim.Properties.CreationDate); @@ -231,6 +199,23 @@ namespace Simian.Extensions properties.ObjectData[i].TextureID = new byte[0]; properties.ObjectData[i].TouchName = new byte[0]; } + else + { + Logger.Log("ObjectSelect sent for missing object " + select.ObjectData[i].ObjectLocalID, + Helpers.LogLevel.Warning); + + properties.ObjectData[i].Description = new byte[0]; + properties.ObjectData[i].Name = new byte[0]; + properties.ObjectData[i].SitName = new byte[0]; + properties.ObjectData[i].TextureID = new byte[0]; + properties.ObjectData[i].TouchName = new byte[0]; + + KillObjectPacket kill = new KillObjectPacket(); + kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; + kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); + kill.ObjectData[0].ID = select.ObjectData[i].ObjectLocalID; + Server.UDP.SendPacket(agent.AgentID, kill, PacketCategory.State); + } } Server.UDP.SendPacket(agent.AgentID, properties, PacketCategory.Transaction); @@ -250,7 +235,7 @@ namespace Simian.Extensions for (int i=0; i 0) { SimulationObject parent; - if (SceneObjects.TryGetValue(linkSet[i].Prim.ParentID, out parent)) + if (Server.Scene.TryGetObject(linkSet[i].Prim.ParentID, out parent)) { //re-add old root orientation linkSet[i].Prim.Position += parent.Prim.Position; @@ -319,7 +304,7 @@ namespace Simian.Extensions for (int i = 0; i < delink.ObjectData.Length; i++) { SimulationObject obj; - if (!SceneObjects.TryGetValue(delink.ObjectData[i].ObjectLocalID, out obj)) + if (!Server.Scene.TryGetObject(delink.ObjectData[i].ObjectLocalID, out obj)) { //TODO: send an error message return; @@ -344,7 +329,7 @@ namespace Simian.Extensions for (int i = 0; i < linkSet.Count; i++) { - update.ObjectData[i] = SimulationObject.BuildUpdateBlock(linkSet[i].Prim, String.Empty, + update.ObjectData[i] = SimulationObject.BuildUpdateBlock(linkSet[i].Prim, Server.RegionHandle, 0, linkSet[i].Prim.Flags); update.ObjectData[i].ParentID = 0; @@ -375,7 +360,7 @@ namespace Simian.Extensions ObjectShapePacket.ObjectDataBlock block = shape.ObjectData[i]; SimulationObject obj; - if (SceneObjects.TryGetValue(block.ObjectLocalID, out obj)) + if (Server.Scene.TryGetObject(block.ObjectLocalID, out obj)) { obj.Prim.PrimData.PathBegin = Primitive.UnpackBeginCut(block.PathBegin); obj.Prim.PrimData.PathCurve = (PathCurve)block.PathCurve; @@ -397,7 +382,7 @@ namespace Simian.Extensions obj.Prim.PrimData.ProfileHollow = Primitive.UnpackProfileHollow(block.ProfileHollow); // Send the update out to everyone - ObjectUpdatePacket editedobj = SimulationObject.BuildFullUpdate(obj.Prim, String.Empty, obj.Prim.RegionHandle, 0, + ObjectUpdatePacket editedobj = SimulationObject.BuildFullUpdate(obj.Prim, obj.Prim.RegionHandle, 0, obj.Prim.Flags); Server.UDP.BroadcastPacket(editedobj, PacketCategory.State); } @@ -421,7 +406,7 @@ namespace Simian.Extensions uint localID = derez.ObjectData[i].ObjectLocalID; SimulationObject obj; - if (SceneObjects.TryGetValue(localID, out obj)) + if (Server.Scene.TryGetObject(localID, out obj)) { switch (destination) { @@ -458,7 +443,7 @@ namespace Simian.Extensions Server.Inventory.CreateItem(agent, obj.Prim.Properties.Name, obj.Prim.Properties.Description, InventoryType.Object, AssetType.Object, obj.Prim.ID, trash.ID, PermissionMask.All, PermissionMask.All, agent.AgentID, obj.Prim.Properties.CreatorID, derez.AgentBlock.TransactionID, 0); - KillObject(obj); + Server.Scene.RemoveObject(obj); Logger.DebugLog(String.Format("Derezzed prim {0} to agent inventory trash", obj.Prim.LocalID)); } @@ -498,7 +483,7 @@ namespace Simian.Extensions MultipleObjectUpdatePacket.ObjectDataBlock block = update.ObjectData[i]; SimulationObject obj; - if (SceneObjects.TryGetValue(block.ObjectLocalID, out obj)) + if (Server.Scene.TryGetObject(block.ObjectLocalID, out obj)) { UpdateType type = (UpdateType)block.Type; bool linked = ((type & UpdateType.Linked) != 0); @@ -532,7 +517,7 @@ namespace Simian.Extensions } // Send the update out to everyone - ObjectUpdatePacket editedobj = SimulationObject.BuildFullUpdate(obj.Prim, String.Empty, obj.Prim.RegionHandle, 0, + ObjectUpdatePacket editedobj = SimulationObject.BuildFullUpdate(obj.Prim, obj.Prim.RegionHandle, 0, obj.Prim.Flags); Server.UDP.BroadcastPacket(editedobj, PacketCategory.State); } @@ -555,7 +540,7 @@ namespace Simian.Extensions ReportType type = (ReportType)request.ObjectData.RequestFlags; SimulationObject obj; - if (SceneObjects.TryGetValue(request.ObjectData.ObjectID, out obj)) + if (Server.Scene.TryGetObject(request.ObjectData.ObjectID, out obj)) { ObjectPropertiesFamilyPacket props = new ObjectPropertiesFamilyPacket(); props.ObjectData.BaseMask = (uint)obj.Prim.Properties.Permissions.BaseMask; @@ -584,18 +569,6 @@ namespace Simian.Extensions } } - void KillObject(SimulationObject obj) - { - SceneObjects.Remove(obj.Prim.LocalID, obj.Prim.ID); - - KillObjectPacket kill = new KillObjectPacket(); - kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; - kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); - kill.ObjectData[0].ID = obj.Prim.LocalID; - - Server.UDP.BroadcastPacket(kill, PacketCategory.State); - } - Vector3 FullSceneCollisionTest(Vector3 rayStart, Vector3 rayEnd) { // HACK: For now @@ -623,7 +596,7 @@ namespace Simian.Extensions if (obj.Prim.ParentID != 0) { SimulationObject parent; - if (SceneObjects.TryGetValue(obj.Prim.ParentID, out parent)) + if (Server.Scene.TryGetObject(obj.Prim.ParentID, out parent)) mesh = obj.GetWorldMesh(DetailLevel.Low, parent); } else diff --git a/Programs/Simian/Extensions/SceneManager.cs b/Programs/Simian/Extensions/SceneManager.cs index 3e953c77..c0e15c14 100644 --- a/Programs/Simian/Extensions/SceneManager.cs +++ b/Programs/Simian/Extensions/SceneManager.cs @@ -11,10 +11,15 @@ using OpenMetaverse.Packets; namespace Simian.Extensions { - public class SceneManager : ISimianExtension + public class SceneManager : ISimianExtension, ISceneProvider { Simian server; - int currentLocalID = 0; + DoubleDictionary sceneObjects = new DoubleDictionary(); + int currentLocalID = 1; + + public event ObjectAddedCallback OnObjectAdded; + public event ObjectRemovedCallback OnObjectRemoved; + public event ObjectUpdatedCallback OnObjectUpdated; public SceneManager(Simian server) { @@ -31,6 +36,63 @@ namespace Simian.Extensions { } + public void AddObject(Agent creator, SimulationObject obj) + { + // Assign a unique LocalID to this object + obj.Prim.LocalID = (uint)Interlocked.Increment(ref currentLocalID); + + // Add the object to the scene dictionary + sceneObjects.Add(obj.Prim.LocalID, obj.Prim.ID, obj); + + // Send an update out to the creator + ObjectUpdatePacket updateToOwner = SimulationObject.BuildFullUpdate(obj.Prim, server.RegionHandle, 0, + obj.Prim.Flags | PrimFlags.CreateSelected | PrimFlags.ObjectYouOwner); + server.UDP.SendPacket(creator.AgentID, updateToOwner, PacketCategory.State); + + // Send an update out to everyone else + ObjectUpdatePacket updateToOthers = SimulationObject.BuildFullUpdate(obj.Prim, server.RegionHandle, 0, + obj.Prim.Flags); + lock (server.Agents) + { + foreach (Agent recipient in server.Agents.Values) + { + if (recipient != creator) + server.UDP.SendPacket(recipient.AgentID, updateToOthers, PacketCategory.State); + } + } + } + + public void RemoveObject(SimulationObject obj) + { + sceneObjects.Remove(obj.Prim.LocalID, obj.Prim.ID); + + KillObjectPacket kill = new KillObjectPacket(); + kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; + kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); + kill.ObjectData[0].ID = obj.Prim.LocalID; + + server.UDP.BroadcastPacket(kill, PacketCategory.State); + } + + public bool TryGetObject(uint localID, out SimulationObject obj) + { + return sceneObjects.TryGetValue(localID, out obj); + } + + public bool TryGetObject(UUID id, out SimulationObject obj) + { + return sceneObjects.TryGetValue(id, out obj); + } + + public void ObjectUpdate(SimulationObject obj, byte state, PrimFlags flags) + { + // Something changed, build an update + ObjectUpdatePacket update = + SimulationObject.BuildFullUpdate(obj.Prim, server.RegionHandle, state, flags); + + server.UDP.BroadcastPacket(update, PacketCategory.State); + } + void CompleteAgentMovementHandler(Packet packet, Agent agent) { CompleteAgentMovementPacket request = (CompleteAgentMovementPacket)packet; @@ -74,13 +136,26 @@ namespace Simian.Extensions server.UDP.SendPacket(agent.AgentID, complete, PacketCategory.Transaction); + // Send updates and appearances for every avatar to this new avatar + SynchronizeStateTo(agent); + + //HACK: Notify everyone when someone logs on to the simulator + OnlineNotificationPacket online = new OnlineNotificationPacket(); + online.AgentBlock = new OnlineNotificationPacket.AgentBlockBlock[1]; + online.AgentBlock[0] = new OnlineNotificationPacket.AgentBlockBlock(); + online.AgentBlock[0].AgentID = agent.AgentID; + server.UDP.BroadcastPacket(online, PacketCategory.State); + } + + // HACK: The reduction provider will deprecate this at some point + void SynchronizeStateTo(Agent agent) + { lock (server.Agents) { foreach (Agent otherAgent in server.Agents.Values) { // Send ObjectUpdate packets for this avatar ObjectUpdatePacket update = SimulationObject.BuildFullUpdate(otherAgent.Avatar, - NameValue.NameValuesToString(otherAgent.Avatar.NameValues), server.RegionHandle, otherAgent.State, otherAgent.Flags); server.UDP.SendPacket(agent.AgentID, update, PacketCategory.State); @@ -90,15 +165,15 @@ namespace Simian.Extensions } } + sceneObjects.ForEach(delegate(SimulationObject obj) + { + ObjectUpdatePacket update = SimulationObject.BuildFullUpdate(obj.Prim, + obj.Prim.RegionHandle, 0, obj.Prim.Flags); + server.UDP.SendPacket(agent.AgentID, update, PacketCategory.State); + }); + // Send terrain data SendLayerData(agent); - - //HACK: Notify everyone when someone logs on to the simulator - OnlineNotificationPacket online = new OnlineNotificationPacket(); - online.AgentBlock = new OnlineNotificationPacket.AgentBlockBlock[1]; - online.AgentBlock[0] = new OnlineNotificationPacket.AgentBlockBlock(); - online.AgentBlock[0].AgentID = agent.AgentID; - server.UDP.BroadcastPacket(online, PacketCategory.State); } void LoadTerrain(string mapFile) diff --git a/Programs/Simian/Interfaces/ISceneProvider.cs b/Programs/Simian/Interfaces/ISceneProvider.cs new file mode 100644 index 00000000..7d83d381 --- /dev/null +++ b/Programs/Simian/Interfaces/ISceneProvider.cs @@ -0,0 +1,23 @@ +using System; +using OpenMetaverse; + +namespace Simian +{ + public delegate bool ObjectAddedCallback(SimulationObject obj); + public delegate bool ObjectRemovedCallback(SimulationObject obj); + public delegate void ObjectUpdatedCallback(SimulationObject obj); + // TODO: ObjectImpulseAppliedCallback + + public interface ISceneProvider + { + event ObjectAddedCallback OnObjectAdded; + event ObjectRemovedCallback OnObjectRemoved; + event ObjectUpdatedCallback OnObjectUpdated; + + void AddObject(Agent creator, SimulationObject obj); + void RemoveObject(SimulationObject obj); + bool TryGetObject(uint localID, out SimulationObject obj); + bool TryGetObject(UUID id, out SimulationObject obj); + void ObjectUpdate(SimulationObject obj, byte state, PrimFlags flags); + } +} diff --git a/Programs/Simian/Simian.cs b/Programs/Simian/Simian.cs index 058a8bf6..adaced48 100644 --- a/Programs/Simian/Simian.cs +++ b/Programs/Simian/Simian.cs @@ -19,12 +19,13 @@ namespace Simian public HttpServer HttpServer; public ulong RegionHandle; - public float[] Heightmap = new float[65536]; + public float[] Heightmap = new float[256 * 256]; public float WaterHeight = 35.0f; public Dictionary AssetStore = new Dictionary(); // Interfaces public IUDPProvider UDP; + public ISceneProvider Scene; public IAvatarProvider Avatars; public IInventoryProvider Inventory; public IMeshingProvider Mesher; @@ -119,21 +120,15 @@ namespace Simian void TryAssignToInterface(ISimianExtension extension) { if (extension is IUDPProvider) - { UDP = (IUDPProvider)extension; - } + else if (extension is ISceneProvider) + Scene = (ISceneProvider)extension; else if (extension is IAvatarProvider) - { Avatars = (IAvatarProvider)extension; - } else if (extension is IInventoryProvider) - { Inventory = (IInventoryProvider)extension; - } else if (extension is IMeshingProvider) - { Mesher = (IMeshingProvider)extension; - } } bool CheckInterfaces() @@ -143,6 +138,11 @@ namespace Simian Logger.Log("No IUDPProvider interface loaded", Helpers.LogLevel.Error); return false; } + else if (Scene == null) + { + Logger.Log("No ISceneProvider interface loaded", Helpers.LogLevel.Error); + return false; + } else if (Avatars == null) { Logger.Log("No IAvatarProvider interface loaded", Helpers.LogLevel.Error); diff --git a/Programs/Simian/SimulationObject.cs b/Programs/Simian/SimulationObject.cs index 097da5df..b2aef39d 100644 --- a/Programs/Simian/SimulationObject.cs +++ b/Programs/Simian/SimulationObject.cs @@ -8,8 +8,13 @@ namespace Simian { public class SimulationObject { + /// Reference to the primitive object this class wraps public Primitive Prim; + /// Link number, if this object is part of a linkset public int LinkNumber; + /// True when an avatar grabs this object. Stops movement and + /// rotation + public bool Frozen; protected Simian Server; protected SimpleMesh[] Meshes = new SimpleMesh[4]; @@ -95,14 +100,14 @@ namespace Simian } } - public static ObjectUpdatePacket BuildFullUpdate(Primitive obj, string nameValues, ulong regionHandle, + public static ObjectUpdatePacket BuildFullUpdate(Primitive obj, ulong regionHandle, byte state, PrimFlags flags) { ObjectUpdatePacket update = new ObjectUpdatePacket(); update.RegionData.RegionHandle = regionHandle; update.RegionData.TimeDilation = UInt16.MaxValue; update.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; - update.ObjectData[0] = BuildUpdateBlock(obj, nameValues, regionHandle, state, flags); + update.ObjectData[0] = BuildUpdateBlock(obj, regionHandle, state, flags); return update; } @@ -123,7 +128,7 @@ namespace Simian return objectData; } - public static ObjectUpdatePacket.ObjectDataBlock BuildUpdateBlock(Primitive obj, string nameValues, ulong regionHandle, + public static ObjectUpdatePacket.ObjectDataBlock BuildUpdateBlock(Primitive obj, ulong regionHandle, byte state, PrimFlags flags) { byte[] objectData = BuildObjectData(obj.Position, obj.Rotation, obj.Velocity, obj.Acceleration, obj.AngularVelocity); @@ -141,7 +146,7 @@ namespace Simian update.JointType = (byte)obj.Joint; update.Material = (byte)obj.PrimData.Material; update.MediaURL = new byte[0]; // FIXME: - update.NameValue = Utils.StringToBytes(nameValues); + update.NameValue = Utils.StringToBytes(NameValue.NameValuesToString(obj.NameValues)); update.ObjectData = objectData; update.OwnerID = obj.Properties.OwnerID; update.ParentID = obj.ParentID;