Added support for linked sets in Simian (unlinking is not yet supported). Moved static BuildFullUpdate and related functions to SimulationObject.cs
git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@2190 52acb1d6-8a22-11de-b505-999d5b087335
This commit is contained in:
@@ -220,7 +220,7 @@ namespace Simian.Extensions
|
||||
|
||||
//TODO: What is WearableData used for?
|
||||
|
||||
ObjectUpdatePacket update = Movement.BuildFullUpdate(agent.Avatar,
|
||||
ObjectUpdatePacket update = SimulationObject.BuildFullUpdate(agent.Avatar,
|
||||
NameValue.NameValuesToString(agent.Avatar.NameValues), Server.RegionHandle,
|
||||
agent.State, agent.Flags | PrimFlags.ObjectYouOwner);
|
||||
Server.UDP.SendPacket(agent.AgentID, update, PacketCategory.State);
|
||||
|
||||
@@ -97,6 +97,13 @@ namespace Simian.Extensions
|
||||
}
|
||||
|
||||
server.UDP.RemoveClient(agent);
|
||||
|
||||
//HACK: Notify everyone when someone logs off
|
||||
OfflineNotificationPacket offline = new OfflineNotificationPacket();
|
||||
offline.AgentBlock = new OfflineNotificationPacket.AgentBlockBlock[1];
|
||||
offline.AgentBlock[0] = new OfflineNotificationPacket.AgentBlockBlock();
|
||||
offline.AgentBlock[0].AgentID = agent.AgentID;
|
||||
server.UDP.BroadcastPacket(offline, PacketCategory.State);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,8 @@ namespace Simian.Extensions
|
||||
sendIM.MessageBlock.Timestamp = 0;
|
||||
sendIM.MessageBlock.Position = agent.Avatar.Position;
|
||||
|
||||
sendIM.AgentData.AgentID = agent.AgentID;
|
||||
|
||||
Server.UDP.SendPacket(recipient.AgentID, sendIM, PacketCategory.Transaction);
|
||||
|
||||
break;
|
||||
|
||||
@@ -338,7 +338,7 @@ namespace Simian.Extensions
|
||||
agent.State = update.AgentData.State;
|
||||
agent.Flags = (PrimFlags)update.AgentData.Flags;
|
||||
|
||||
ObjectUpdatePacket fullUpdate = BuildFullUpdate(agent.Avatar,
|
||||
ObjectUpdatePacket fullUpdate = SimulationObject.BuildFullUpdate(agent.Avatar,
|
||||
NameValue.NameValuesToString(agent.Avatar.NameValues), server.RegionHandle,
|
||||
agent.State, agent.Flags);
|
||||
|
||||
@@ -389,74 +389,5 @@ namespace Simian.Extensions
|
||||
heightWidth.HeightWidthBlock.Height, heightWidth.HeightWidthBlock.Width), Helpers.LogLevel.Info);
|
||||
}
|
||||
|
||||
public static ObjectUpdatePacket BuildFullUpdate(Primitive obj, string nameValues, ulong regionHandle,
|
||||
byte state, PrimFlags flags)
|
||||
{
|
||||
byte[] objectData = new byte[60];
|
||||
int pos = 0;
|
||||
obj.Position.GetBytes().CopyTo(objectData, pos);
|
||||
pos += 12;
|
||||
obj.Velocity.GetBytes().CopyTo(objectData, pos);
|
||||
pos += 12;
|
||||
obj.Acceleration.GetBytes().CopyTo(objectData, pos);
|
||||
pos += 12;
|
||||
obj.Rotation.GetBytes().CopyTo(objectData, pos);
|
||||
pos += 12;
|
||||
obj.AngularVelocity.GetBytes().CopyTo(objectData, pos);
|
||||
|
||||
ObjectUpdatePacket update = new ObjectUpdatePacket();
|
||||
update.RegionData.RegionHandle = regionHandle;
|
||||
update.RegionData.TimeDilation = UInt16.MaxValue;
|
||||
update.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
|
||||
update.ObjectData[0] = new ObjectUpdatePacket.ObjectDataBlock();
|
||||
update.ObjectData[0].ClickAction = (byte)obj.ClickAction;
|
||||
update.ObjectData[0].CRC = 0;
|
||||
update.ObjectData[0].ExtraParams = new byte[0]; //FIXME: Need a serializer for ExtraParams
|
||||
update.ObjectData[0].Flags = (byte)flags;
|
||||
update.ObjectData[0].FullID = obj.ID;
|
||||
update.ObjectData[0].Gain = obj.SoundGain;
|
||||
update.ObjectData[0].ID = obj.LocalID;
|
||||
update.ObjectData[0].JointAxisOrAnchor = obj.JointAxisOrAnchor;
|
||||
update.ObjectData[0].JointPivot = obj.JointPivot;
|
||||
update.ObjectData[0].JointType = (byte)obj.Joint;
|
||||
update.ObjectData[0].Material = (byte)obj.PrimData.Material;
|
||||
update.ObjectData[0].MediaURL = new byte[0]; // FIXME:
|
||||
update.ObjectData[0].NameValue = Utils.StringToBytes(nameValues);
|
||||
update.ObjectData[0].ObjectData = objectData;
|
||||
update.ObjectData[0].OwnerID = obj.Properties.OwnerID;
|
||||
update.ObjectData[0].ParentID = obj.ParentID;
|
||||
update.ObjectData[0].PathBegin = Primitive.PackBeginCut(obj.PrimData.PathBegin);
|
||||
update.ObjectData[0].PathCurve = (byte)obj.PrimData.PathCurve;
|
||||
update.ObjectData[0].PathEnd = Primitive.PackEndCut(obj.PrimData.PathEnd);
|
||||
update.ObjectData[0].PathRadiusOffset = Primitive.PackPathTwist(obj.PrimData.PathRadiusOffset);
|
||||
update.ObjectData[0].PathRevolutions = Primitive.PackPathRevolutions(obj.PrimData.PathRevolutions);
|
||||
update.ObjectData[0].PathScaleX = Primitive.PackPathScale(obj.PrimData.PathScaleX);
|
||||
update.ObjectData[0].PathScaleY = Primitive.PackPathScale(obj.PrimData.PathScaleY);
|
||||
update.ObjectData[0].PathShearX = (byte)Primitive.PackPathShear(obj.PrimData.PathShearX);
|
||||
update.ObjectData[0].PathShearY = (byte)Primitive.PackPathShear(obj.PrimData.PathShearY);
|
||||
update.ObjectData[0].PathSkew = Primitive.PackPathTwist(obj.PrimData.PathSkew);
|
||||
update.ObjectData[0].PathTaperX = Primitive.PackPathTaper(obj.PrimData.PathTaperX);
|
||||
update.ObjectData[0].PathTaperY = Primitive.PackPathTaper(obj.PrimData.PathTaperY);
|
||||
update.ObjectData[0].PathTwist = Primitive.PackPathTwist(obj.PrimData.PathTwist);
|
||||
update.ObjectData[0].PathTwistBegin = Primitive.PackPathTwist(obj.PrimData.PathTwistBegin);
|
||||
update.ObjectData[0].PCode = (byte)obj.PrimData.PCode;
|
||||
update.ObjectData[0].ProfileBegin = Primitive.PackBeginCut(obj.PrimData.ProfileBegin);
|
||||
update.ObjectData[0].ProfileCurve = (byte)obj.PrimData.ProfileCurve;
|
||||
update.ObjectData[0].ProfileEnd = Primitive.PackEndCut(obj.PrimData.ProfileEnd);
|
||||
update.ObjectData[0].ProfileHollow = Primitive.PackProfileHollow(obj.PrimData.ProfileHollow);
|
||||
update.ObjectData[0].PSBlock = new byte[0]; // FIXME:
|
||||
update.ObjectData[0].TextColor = obj.TextColor.GetBytes(true);
|
||||
update.ObjectData[0].TextureAnim = obj.TextureAnim.GetBytes();
|
||||
update.ObjectData[0].TextureEntry = obj.Textures.ToBytes();
|
||||
update.ObjectData[0].Radius = obj.SoundRadius;
|
||||
update.ObjectData[0].Scale = obj.Scale;
|
||||
update.ObjectData[0].Sound = obj.Sound;
|
||||
update.ObjectData[0].State = state;
|
||||
update.ObjectData[0].Text = Utils.StringToBytes(obj.Text);
|
||||
update.ObjectData[0].UpdateFlags = (uint)flags;
|
||||
update.ObjectData[0].Data = new byte[0]; // FIXME:
|
||||
|
||||
return update;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ namespace Simian.Extensions
|
||||
Server.UDP.RegisterPacketCallback(PacketType.ObjectAdd, new PacketCallback(ObjectAddHandler));
|
||||
Server.UDP.RegisterPacketCallback(PacketType.ObjectSelect, new PacketCallback(ObjectSelectHandler));
|
||||
Server.UDP.RegisterPacketCallback(PacketType.ObjectDeselect, new PacketCallback(ObjectDeselectHandler));
|
||||
Server.UDP.RegisterPacketCallback(PacketType.ObjectLink, new PacketCallback(ObjectLinkHandler));
|
||||
Server.UDP.RegisterPacketCallback(PacketType.ObjectDelink, new PacketCallback(ObjectDelinkHandler));
|
||||
Server.UDP.RegisterPacketCallback(PacketType.ObjectShape, new PacketCallback(ObjectShapeHandler));
|
||||
Server.UDP.RegisterPacketCallback(PacketType.DeRezObject, new PacketCallback(DeRezObjectHandler));
|
||||
Server.UDP.RegisterPacketCallback(PacketType.MultipleObjectUpdate, new PacketCallback(MultipleObjectUpdateHandler));
|
||||
@@ -40,7 +42,7 @@ namespace Simian.Extensions
|
||||
CompleteAgentMovementPacket complete = (CompleteAgentMovementPacket)packet;
|
||||
SceneObjects.ForEach(delegate(SimulationObject obj)
|
||||
{
|
||||
ObjectUpdatePacket update = Movement.BuildFullUpdate(obj.Prim, String.Empty, obj.Prim.RegionHandle, 0, obj.Prim.Flags);
|
||||
ObjectUpdatePacket update = SimulationObject.BuildFullUpdate(obj.Prim, String.Empty, obj.Prim.RegionHandle, 0, obj.Prim.Flags);
|
||||
Server.UDP.SendPacket(agent.AgentID, update, PacketCategory.State);
|
||||
});
|
||||
}
|
||||
@@ -178,12 +180,12 @@ namespace Simian.Extensions
|
||||
SceneObjects.Add(prim.LocalID, prim.ID, simObj);
|
||||
|
||||
// Send an update out to the creator
|
||||
ObjectUpdatePacket updateToOwner = Movement.BuildFullUpdate(prim, String.Empty, prim.RegionHandle, 0,
|
||||
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 = Movement.BuildFullUpdate(prim, String.Empty, prim.RegionHandle, 0,
|
||||
ObjectUpdatePacket updateToOthers = SimulationObject.BuildFullUpdate(prim, String.Empty, prim.RegionHandle, 0,
|
||||
prim.Flags);
|
||||
lock (Server.Agents)
|
||||
{
|
||||
@@ -241,6 +243,62 @@ namespace Simian.Extensions
|
||||
// TODO: Do we need this at all?
|
||||
}
|
||||
|
||||
void ObjectLinkHandler(Packet packet, Agent agent)
|
||||
{
|
||||
ObjectLinkPacket link = (ObjectLinkPacket)packet;
|
||||
List<SimulationObject> linkSet = new List<SimulationObject>();
|
||||
for (int i=0; i<link.ObjectData.Length; i++)
|
||||
{
|
||||
SimulationObject obj;
|
||||
if (!SceneObjects.TryGetValue(link.ObjectData[i].ObjectLocalID, out obj))
|
||||
{
|
||||
//TODO: send an error message
|
||||
return;
|
||||
}
|
||||
else if (obj.Prim.OwnerID != agent.AgentID)
|
||||
{
|
||||
//TODO: send an error message
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
linkSet.Add(obj);
|
||||
}
|
||||
}
|
||||
|
||||
ObjectUpdatePacket update = new ObjectUpdatePacket();
|
||||
update.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[linkSet.Count];
|
||||
for (int i = 0; i < linkSet.Count; i++)
|
||||
{
|
||||
update.ObjectData[i] = new ObjectUpdatePacket.ObjectDataBlock();
|
||||
|
||||
linkSet[i].LinkNumber = i + 1;
|
||||
update.ObjectData[i] = new ObjectUpdatePacket.ObjectDataBlock();
|
||||
update.ObjectData[i] = SimulationObject.BuildUpdateBlock(linkSet[i].Prim, String.Empty, Server.RegionHandle,
|
||||
linkSet[i].Prim.PrimData.State, linkSet[i].Prim.Flags);
|
||||
update.RegionData.RegionHandle = Server.RegionHandle;
|
||||
update.RegionData.TimeDilation = UInt16.MaxValue;
|
||||
|
||||
if (i == 0) update.ObjectData[i].ParentID = 0;
|
||||
else
|
||||
{
|
||||
update.ObjectData[i].ParentID = linkSet[0].Prim.LocalID;
|
||||
update.ObjectData[i].ObjectData = SimulationObject.BuildObjectData(
|
||||
linkSet[i].Prim.Position - linkSet[0].Prim.Position,
|
||||
linkSet[i].Prim.Rotation / linkSet[0].Prim.Rotation,
|
||||
Vector3.Zero, Vector3.Zero, Vector3.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
Server.UDP.BroadcastPacket(update, PacketCategory.State);
|
||||
}
|
||||
|
||||
void ObjectDelinkHandler(Packet packet, Agent agent)
|
||||
{
|
||||
ObjectDelinkPacket link = (ObjectDelinkPacket)packet;
|
||||
//TODO: Delink objects
|
||||
}
|
||||
|
||||
void ObjectShapeHandler(Packet packet, Agent agent)
|
||||
{
|
||||
ObjectShapePacket shape = (ObjectShapePacket)packet;
|
||||
@@ -272,7 +330,7 @@ namespace Simian.Extensions
|
||||
obj.Prim.PrimData.ProfileHollow = Primitive.UnpackProfileHollow(block.ProfileHollow);
|
||||
|
||||
// Send the update out to everyone
|
||||
ObjectUpdatePacket editedobj = Movement.BuildFullUpdate(obj.Prim, String.Empty, obj.Prim.RegionHandle, 0,
|
||||
ObjectUpdatePacket editedobj = SimulationObject.BuildFullUpdate(obj.Prim, String.Empty, obj.Prim.RegionHandle, 0,
|
||||
obj.Prim.Flags);
|
||||
Server.UDP.BroadcastPacket(editedobj, PacketCategory.State);
|
||||
}
|
||||
@@ -407,7 +465,7 @@ namespace Simian.Extensions
|
||||
}
|
||||
|
||||
// Send the update out to everyone
|
||||
ObjectUpdatePacket editedobj = Movement.BuildFullUpdate(obj.Prim, String.Empty, obj.Prim.RegionHandle, 0,
|
||||
ObjectUpdatePacket editedobj = SimulationObject.BuildFullUpdate(obj.Prim, String.Empty, obj.Prim.RegionHandle, 0,
|
||||
obj.Prim.Flags);
|
||||
Server.UDP.BroadcastPacket(editedobj, PacketCategory.State);
|
||||
}
|
||||
@@ -586,5 +644,6 @@ namespace Simian.Extensions
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace Simian.Extensions
|
||||
foreach (Agent otherAgent in server.Agents.Values)
|
||||
{
|
||||
// Send ObjectUpdate packets for this avatar
|
||||
ObjectUpdatePacket update = Movement.BuildFullUpdate(otherAgent.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);
|
||||
@@ -92,6 +92,13 @@ namespace Simian.Extensions
|
||||
|
||||
// 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)
|
||||
|
||||
@@ -375,6 +375,14 @@ namespace Simian
|
||||
UUID remove = client.Agent.AgentID;
|
||||
client.Shutdown();
|
||||
lock (server.Agents) server.Agents.Remove(remove);
|
||||
|
||||
//HACK: Notify everyone when someone is disconnected
|
||||
OfflineNotificationPacket offline = new OfflineNotificationPacket();
|
||||
offline.AgentBlock = new OfflineNotificationPacket.AgentBlockBlock[1];
|
||||
offline.AgentBlock[0] = new OfflineNotificationPacket.AgentBlockBlock();
|
||||
offline.AgentBlock[0].AgentID = client.Agent.AgentID;
|
||||
server.UDP.BroadcastPacket(offline, PacketCategory.State);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user