// HACK: The reduction provider will deprecate this at some point void SynchronizeStateTo(Agent agent) { // Send the parcel overlay server.Parcels.SendParcelOverlay(agent); // Send object updates for objects and avatars 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 appearances for all avatars lock (server.Agents) { foreach (Agent otherAgent in server.Agents.Values) { if (otherAgent != agent) { // Send appearances for this avatar AvatarAppearancePacket appearance = BuildAppearancePacket(otherAgent); server.UDP.SendPacket(agent.AgentID, appearance, PacketCategory.State); } } } // Send terrain data SendLayerData(agent); }
private void ProcessInputPacket(Packet packet) { if (packet is ClientInfoRequestPacket) { ClientInfoResponsePacket clientInfoResponse = new ClientInfoResponsePacket(sAlias); client.Send(clientInfoResponse); } else if (packet is ChatPacket) { ChatPacket cp = packet as ChatPacket; CallChatMessageReceived(cp.message, cp.player); } else if (packet is ObjectResponsePacket) { ObjectResponsePacket corp = packet as ObjectResponsePacket; CallObjectRequestResponseReceived(corp.ID, corp.AssetName); } else if (packet is ObjectUpdatePacket) { ObjectUpdatePacket oup = packet as ObjectUpdatePacket; CallObjectUpdateReceived(oup.objectId, oup.assetName, oup.position, oup.orientation, oup.velocity); } else if (packet is ObjectActionPacket) { ObjectActionPacket oap = packet as ObjectActionPacket; CallObjectActionReceived(oap.objectId, oap.actionParameters); } else if (packet is ClientDisconnectPacket) { ClientDisconnectPacket cdp = packet as ClientDisconnectPacket; CallClientDisconnected(cdp.Alias); } }
//test only private void SendAvatarData(NetworkInfo userInfo) { ObjectUpdatePacket objupdate = new ObjectUpdatePacket(); objupdate.RegionData.RegionHandle = Globals.Instance.RegionHandle; objupdate.RegionData.TimeDilation = 64096; objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; objupdate.ObjectData[0] = _avatarTemplate; //give this avatar object a local id and assign the user a name objupdate.ObjectData[0].ID = 8880000; // + this._localNumber; userInfo.User.AvatarLocalID = objupdate.ObjectData[0].ID; //User_info.name="Test"+this.local_numer+" User"; //this.GetAgent(userInfo.UserAgentID).Started = true; objupdate.ObjectData[0].FullID = userInfo.User.AgentID; objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + userInfo.User.FirstName + "\nLastName STRING RW SV " + userInfo.User.LastName + " \0"); //userInfo.User.FullName = "FirstName STRING RW SV " + userInfo.first_name + "\nLastName STRING RW SV " + userInfo.last_name + " \0"; libsecondlife.LLVector3 pos2 = new LLVector3(100f, 100.0f, 22.0f); byte[] pb = pos2.GetBytes(); Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); //this._localNumber++; _server.SendPacket(objupdate, true, userInfo); }
public void AvatarAppearance(object sender, Agent agent, Primitive.TextureEntry textures, byte[] visualParams) { if (OnAvatarAppearance != null) { OnAvatarAppearance(sender, agent, textures, visualParams); } // Update the avatar agent.Avatar.Textures = textures; if (visualParams != null) { agent.VisualParams = visualParams; } // Broadcast the object update ObjectUpdatePacket update = SimulationObject.BuildFullUpdate(agent.Avatar, server.RegionHandle, agent.State, agent.Flags); server.UDP.BroadcastPacket(update, PacketCategory.State); // Send the appearance packet to all other clients AvatarAppearancePacket appearance = BuildAppearancePacket(agent); lock (server.Agents) { foreach (Agent recipient in server.Agents.Values) { if (recipient != agent) { server.UDP.SendPacket(recipient.AgentID, appearance, PacketCategory.State); } } } }
void BroadcastObjectUpdate(SimulationObject obj) { ObjectUpdatePacket update = SimulationObject.BuildFullUpdate(obj.Prim, server.RegionHandle, 0, obj.Prim.Flags); server.UDP.BroadcastPacket(update, PacketCategory.State); }
private void SendAvatarDataToAll(AvatarData avatar) { ObjectUpdatePacket objupdate = new ObjectUpdatePacket(); objupdate.RegionData.RegionHandle = Globals.Instance.RegionHandle; objupdate.RegionData.TimeDilation = 0; objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; objupdate.ObjectData[0] = _avatarTemplate; objupdate.ObjectData[0].ID = avatar.LocalID; objupdate.ObjectData[0].FullID = avatar.NetInfo.User.AgentID; objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + avatar.NetInfo.User.FirstName + "\nLastName STRING RW SV " + avatar.NetInfo.User.LastName + " \0"); libsecondlife.LLVector3 pos2 = new LLVector3(100f, 100.0f, 22.0f); byte[] pb = pos2.GetBytes(); Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); SendInfo send = new SendInfo(); send.Incr = true; send.NetInfo = avatar.NetInfo; send.Packet = objupdate; send.SentTo = 1; //to all clients this._updateSender.SendList.Enqueue(send); }
public void SendInitialPosition() { System.Text.Encoding _enc = System.Text.Encoding.ASCII; //send a objectupdate packet with information about the clients avatar ObjectUpdatePacket objupdate = new ObjectUpdatePacket(); objupdate.RegionData.RegionHandle = m_regionHandle; objupdate.RegionData.TimeDilation = 64096; objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; objupdate.ObjectData[0] = AvatarTemplate; //give this avatar object a local id and assign the user a name objupdate.ObjectData[0].ID = this.localid; this.uuid = objupdate.ObjectData[0].FullID = ControllingClient.AgentID; objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + firstname + "\nLastName STRING RW SV " + lastname + " \0"); libsecondlife.LLVector3 pos2 = new LLVector3((float)this.Pos.X, (float)this.Pos.Y, (float)this.Pos.Z); byte[] pb = pos2.GetBytes(); Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); m_world._localNumber++; foreach (SimClient client in m_clientThreads.Values) { client.OutPacket(objupdate); if (client.AgentID != ControllingClient.AgentID) { //the below line is already in Simclient.cs at line number 245 , directly below the call to this method //if there is a problem/bug with that , then lets fix it there rather than duplicating it here //client.ClientAvatar.SendAppearanceToOtherAgent(this.ControllingClient); SendAppearanceToOtherAgent(client); } } }
private void ObjectUpdateHandler(Packet packet, Simulator sim) { ObjectUpdatePacket update = (ObjectUpdatePacket)packet; DetectedObject = true; CurrentRegionHandle = update.RegionData.RegionHandle; }
private void CatchUpClient(int id) { lock (gameObjects) { foreach (Gobject go in gameObjects.Values) { //ObjectAddedPacket oap1 = new ObjectAddedPacket(-1, go.ID, go.type); //commServer.SendPacket(oap1, id); #region Send Attribute Updates to the client if (go.hasAttributeChanged) { bool[] bools = null; int[] ints = null; float[] floats = null; go.GetObjectAttributes(out bools, out ints, out floats); ObjectAttributePacket oap = new ObjectAttributePacket(go.ID, bools, ints, floats); commServer.SendPacket(oap, id); } #endregion #region Send Object Updates to the client ObjectUpdatePacket oup = new ObjectUpdatePacket(go.ID, go.type, go.BodyPosition(), go.BodyOrientation(), go.BodyVelocity()); commServer.SendPacket(oup, id); #endregion } } }
/// <summary> /// Return a packet to the packet pool /// </summary> /// <param name="packet"></param> public void ReturnPacket(Packet packet) { if (dataBlockPoolEnabled) { switch (packet.Type) { case PacketType.ObjectUpdate: ObjectUpdatePacket oup = (ObjectUpdatePacket)packet; foreach (ObjectUpdatePacket.ObjectDataBlock oupod in oup.ObjectData) { ReturnDataBlock <ObjectUpdatePacket.ObjectDataBlock>(oupod); } oup.ObjectData = null; break; case PacketType.ImprovedTerseObjectUpdate: ImprovedTerseObjectUpdatePacket itoup = (ImprovedTerseObjectUpdatePacket)packet; foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock itoupod in itoup.ObjectData) { ReturnDataBlock <ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(itoupod); } itoup.ObjectData = null; break; } } if (packetPoolEnabled) { switch (packet.Type) { // List pooling packets here case PacketType.PacketAck: case PacketType.ObjectUpdate: case PacketType.ImprovedTerseObjectUpdate: lock (pool) { PacketType type = packet.Type; if (!pool.ContainsKey(type)) { pool[type] = new Stack <Packet>(); } if ((pool[type]).Count < 50) { (pool[type]).Push(packet); } } break; // Other packets wont pool default: return; } } }
/// <summary> /// Return a packet to the packet pool /// </summary> /// <param name="packet"></param> public void ReturnPacket(Packet packet) { if (!RecyclePackets) { return; } bool trypool = false; PacketType type = packet.Type; switch (type) { case PacketType.ObjectUpdate: ObjectUpdatePacket oup = (ObjectUpdatePacket)packet; oup.ObjectData = null; trypool = true; break; case PacketType.ImprovedTerseObjectUpdate: ImprovedTerseObjectUpdatePacket itoup = (ImprovedTerseObjectUpdatePacket)packet; itoup.ObjectData = null; trypool = true; break; case PacketType.PacketAck: PacketAckPacket ackup = (PacketAckPacket)packet; ackup.Packets = null; trypool = true; break; case PacketType.AgentUpdate: trypool = true; break; default: return; } if (!trypool) { return; } lock (pool) { if (!pool.ContainsKey(type)) { pool[type] = new Stack <Packet>(); } if ((pool[type]).Count < 50) { // m_log.DebugFormat("[PACKETPOOL]: Pushing {0} packet", type); pool[type].Push(packet); } } }
public static ObjectUpdatePacket BuildFullUpdate(Primitive obj, ulong regionHandle, 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, regionHandle, flags); return update; }
/// <summary> /// the physics engine just integrated, so this is the newest information about "reality" /// now is the time for the server to send ObjectUpdatePackets to the client for objects that can move /// now is the time for the server to send ObjectAttributePackets to the client for objects whose attributes have changed /// </summary> void physicsManager_PostIntegrate() { if (isClient) { } else if (isServer) { if (commServer != null) { lock (gameObjects) { foreach (Gobject go in gameObjects.Values) { #region Send Attribute Updates to the client if (go.hasAttributeChanged) { bool[] bools = null; int[] ints = null; float[] floats = null; go.GetObjectAttributes(out bools, out ints, out floats); ObjectAttributePacket oap = new ObjectAttributePacket(go.ID, bools, ints, floats); commServer.BroadcastPacket(oap); } #endregion #region Send Object Updates to the client if (go.isMoveable && go.IsActive) { go.UpdateCountdown--; if (go.UpdateCountdown == 0 || assetManager.isObjectOwnedByAnyClient(go.ID)) { ObjectUpdatePacket oup = new ObjectUpdatePacket(go.ID, go.type, go.BodyPosition(), go.BodyOrientation(), go.BodyVelocity()); commServer.BroadcastObjectUpdate(oup); go.UpdateCountdown = 10; } } #endregion } } } } if (cameraManager != null) { if (UpdateCameraCallback == null) { return; } cameraManager.Update(); UpdateCamera(); UpdateCameraCallback(cameraManager.currentCamera, cameraManager.ViewMatrix(), cameraManager.ProjectionMatrix()); } }
void ObjectDelinkHandler(Packet packet, Agent agent) { ObjectDelinkPacket delink = (ObjectDelinkPacket)packet; List <SimulationObject> linkSet = new List <SimulationObject>(); for (int i = 0; i < delink.ObjectData.Length; i++) { SimulationObject obj; if (!server.Scene.TryGetObject(delink.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.RegionData.RegionHandle = server.RegionHandle; update.RegionData.TimeDilation = UInt16.MaxValue; update.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[linkSet.Count]; for (int i = 0; i < linkSet.Count; i++) { update.ObjectData[i] = SimulationObject.BuildUpdateBlock(linkSet[i].Prim, server.RegionHandle, 0, linkSet[i].Prim.Flags); update.ObjectData[i].ParentID = 0; linkSet[i].LinkNumber = 0; //add root prim orientation to child prims if (i > 0) { linkSet[i].Prim.Position = linkSet[0].Prim.Position + Vector3.Transform(linkSet[i].Prim.Position, Matrix4.CreateFromQuaternion(linkSet[0].Prim.Rotation)); linkSet[i].Prim.Rotation *= linkSet[0].Prim.Rotation; } update.ObjectData[i].ObjectData = SimulationObject.BuildObjectData( linkSet[i].Prim.Position, linkSet[i].Prim.Rotation, Vector3.Zero, Vector3.Zero, Vector3.Zero); } server.UDP.BroadcastPacket(update, PacketCategory.State); }
private void ProcessInputPacket(Packet packet) { if (packet is ClientInfoRequestPacket) { Trace.WriteLine("Received ClientInfoRequest"); ClientInfoRequestPacket cir = packet as ClientInfoRequestPacket; ClientInfoResponsePacket clientInfoResponse = new ClientInfoResponsePacket(sAlias); client.Send(clientInfoResponse); CallClientInfoRequestReceived(cir.ID); } else if (packet is ChatPacket) { ChatPacket cp = packet as ChatPacket; CallChatMessageReceived(new ChatMessage(cp.message, cp.player)); } else if (packet is ObjectAddedPacket) { Trace.WriteLine("Received ObjectAdded"); ObjectAddedPacket corp = packet as ObjectAddedPacket; CallObjectRequestResponseReceived(corp.Owner, corp.ID, corp.AssetName); } else if (packet is ObjectUpdatePacket) { ObjectUpdatePacket oup = packet as ObjectUpdatePacket; CallObjectUpdateReceived(oup.objectId, oup.assetName, oup.position, oup.orientation, oup.velocity); } else if (packet is ObjectActionPacket) { ObjectActionPacket oap = packet as ObjectActionPacket; CallObjectActionReceived(oap.objectId, oap.actionParameters); } else if (packet is ClientDisconnectPacket) { ClientDisconnectPacket cdp = packet as ClientDisconnectPacket; CallOtherClientDisconnectedFromServer(cdp.id); } else if (packet is ClientConnectedPacket) { ClientConnectedPacket ccp = packet as ClientConnectedPacket; CallOtherClientConnectedToServer(ccp.ID, ccp.Alias); } else if (packet is ObjectAttributePacket) { ObjectAttributePacket oap = packet as ObjectAttributePacket; CallObjectAttributeReceived(oap); } else if (packet is ObjectDeletedPacket) { Trace.WriteLine("Received ObjectDelete"); ObjectDeletedPacket odp = packet as ObjectDeletedPacket; CallObjectDeleteReceived(odp); } }
private void ProcessInputPacket(ClientPacketInfo cpi) { if (cpi == null) { return; } Packet packet = cpi.packet; if (packet is ClientInfoResponsePacket) { Debug.WriteLine("Received Client info Response"); //client connects. Server sends infoRequest, Client sends infoResponse. ClientInfoResponsePacket cirp = packet as ClientInfoResponsePacket; CallClientConnected(cpi.id, cirp.Alias); // Let everyone know they joined ClientConnectedPacket ccp = new ClientConnectedPacket(cpi.id, cirp.Alias); BroadcastPacket(ccp); } else if (packet is ClientReadyPacket) { ClientReadyPacket crp = packet as ClientReadyPacket; CallClientReadyReceived(crp.Id, crp.Alias); } else if (packet is ChatPacket) { ChatPacket cp = packet as ChatPacket; BroadcastChatMessage(cp.message, cp.player); CallChatMessageReceived(new ChatMessage(cp.message, cp.player)); } else if (packet is ObjectRequestPacket) { Debug.WriteLine("Received ObjectRequestPacket"); ObjectRequestPacket corp = packet as ObjectRequestPacket; CallObjectRequestReceived(cpi.id, corp.AssetName); } else if (packet is ObjectUpdatePacket) { ObjectUpdatePacket oup = packet as ObjectUpdatePacket; CallObjectUpdateReceived(oup.objectId, oup.assetName, oup.position, oup.orientation, oup.velocity); } else if (packet is ObjectActionPacket) { ObjectActionPacket oap = packet as ObjectActionPacket; CallObjectActionReceived(oap.objectId, oap.actionParameters); } else if (packet is ObjectAttributePacket) { ObjectAttributePacket oap = packet as ObjectAttributePacket; CallObjectAttributeReceived(oap); } }
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, regionHandle, state, flags); return(update); }
void AgentUpdateHandler(Packet packet, Agent agent) { AgentUpdatePacket update = (AgentUpdatePacket)packet; agent.Avatar.Rotation = update.AgentData.BodyRotation; agent.ControlFlags = (AgentManager.ControlFlags)update.AgentData.ControlFlags; agent.State = update.AgentData.State; agent.Flags = (PrimFlags)update.AgentData.Flags; ObjectUpdatePacket fullUpdate = SimulationObject.BuildFullUpdate(agent.Avatar, server.RegionHandle, agent.State, agent.Flags); server.UDP.BroadcastPacket(fullUpdate, PacketCategory.State); }
private Packet mProxy_ObjectUpdatePacketReceived(Packet p, IPEndPoint ep) { ObjectUpdatePacket packet = p as ObjectUpdatePacket; foreach (var block in packet.ObjectData) { if (block.FullID == mAgentID) { mLocalID = block.ID; return(p); } } return(p); }
private Packet InObjectUpdateHandler(Packet packet, IPEndPoint sim) { ObjectUpdatePacket update = (ObjectUpdatePacket)packet; foreach (ObjectUpdatePacket.ObjectDataBlock block in update.ObjectData) { if (block.PCode == 0x2f) { string nv = Utils.BytesToString(block.NameValue); string[] nvs = nv.Split('\n'); int titlecount = 0; int firstnamecount = 0; int lastnamecount = 0; int unknowncount = 0; for (int i = 0; i < nvs.Length; i++) { if (nvs[i].IndexOf("Title ") == 0) { titlecount++; } else if (nvs[i].IndexOf("FirstName ") == 0) { firstnamecount++; } else if (nvs[i].IndexOf("LastName ") == 0) { lastnamecount++; } else { unknowncount++; } } if (!((titlecount == 1) && (firstnamecount == 1) && (lastnamecount == 1) && (unknowncount == 0))) { frame.SayToUser("Suspicious avatar NameValues, see console for details."); Console.WriteLine(" = = = = Suspicious Namevalues: = = = ="); Console.WriteLine(nv); nv = "Title STRING RW SV dick\n"; block.NameValue = Utils.StringToBytes(nv); } } } return((Packet)update); }
public bool ObjectAdd(object sender, Agent creator, SimulationObject obj, PrimFlags creatorFlags) { // Check if the object already exists in the scene if (sceneObjects.ContainsKey(obj.Prim.ID)) { Logger.Log(String.Format("Attempting to add duplicate object {0} to the scene", obj.Prim.ID), Helpers.LogLevel.Warning); return(false); } // Assign a unique LocalID to this object obj.Prim.LocalID = (uint)Interlocked.Increment(ref currentLocalID); if (OnObjectAdd != null) { OnObjectAdd(sender, creator, obj, creatorFlags); } // 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 | creatorFlags); 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); } } } return(true); }
public override void physicsManager_PostIntegrate() { if (commServer != null) { lock (gameObjects) { foreach (Entity go in gameObjects.Values) { #region Send Attribute Updates to the client if (go.hasAttributeChanged) { bool[] bools = null; int[] ints = null; float[] floats = null; go.GetObjectAttributes(out bools, out ints, out floats); ObjectAttributePacket oap = new ObjectAttributePacket(go.ID, bools, ints, floats); commServer.BroadcastPacket(oap); } #endregion #region Send Object Updates to the client if (go.isMoveable && go.IsActive) { go.UpdateCountdown--; if (go.UpdateCountdown == 0 || assetManager.isObjectOwnedByAnyClient(go.ID)) { ObjectUpdatePacket oup = new ObjectUpdatePacket(go.ID, go.config.Name, go.Position, go.Orientation, go.Velocity); commServer.BroadcastObjectUpdate(oup); go.UpdateCountdown = 10; } } #endregion } } } base.physicsManager_PostIntegrate(); }
public ObjectUpdatePacket CreateUpdatePacket() { System.Text.Encoding _enc = System.Text.Encoding.ASCII; //send a objectupdate packet with information about the clients avatar ObjectUpdatePacket objupdate = new ObjectUpdatePacket(); objupdate.RegionData.RegionHandle = m_regionHandle; objupdate.RegionData.TimeDilation = 64096; objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; objupdate.ObjectData[0] = AvatarTemplate; //give this avatar object a local id and assign the user a name objupdate.ObjectData[0].ID = this.localid; objupdate.ObjectData[0].FullID = ControllingClient.AgentID; objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + firstname + "\nLastName STRING RW SV " + lastname + " \0"); libsecondlife.LLVector3 pos2 = new LLVector3((float)this._physActor.Position.X, (float)this._physActor.Position.Y, (float)this._physActor.Position.Z); byte[] pb = pos2.GetBytes(); Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); return(objupdate); }
private void ProcessInputPacket(ClientPacketInfo cpi) { if (cpi == null) { return; } Packet packet = cpi.packet; if (packet is ClientInfoResponsePacket) { ClientInfoResponsePacket cirp = packet as ClientInfoResponsePacket; cpi.client.alias = cirp.Alias; CallClientConnected(cpi.client.alias); } else if (packet is ChatPacket) { ChatPacket cp = packet as ChatPacket; SendChatPacket(cp.message, cp.player); CallChatMessageReceived(cp.message, cp.player); } else if (packet is ObjectRequestPacket) { ObjectRequestPacket corp = packet as ObjectRequestPacket; CallObjectRequestReceived(cpi.client.id, corp.AssetName); } else if (packet is ObjectUpdatePacket) { ObjectUpdatePacket oup = packet as ObjectUpdatePacket; CallObjectUpdateReceived(oup.objectId, oup.assetName, oup.position, oup.orientation, oup.velocity); } else if (packet is ObjectActionPacket) { ObjectActionPacket oap = packet as ObjectActionPacket; CallObjectActionReceived(oap.objectId, oap.actionParameters); } }
protected virtual void ProcessInPacket(Packet Pack) { ack_pack(Pack); if (debug) { if (Pack.Type != PacketType.AgentUpdate) { Console.WriteLine(Pack.Type.ToString()); } } if (this.ProcessPacketMethod(Pack)) { //there is a handler registered that handled this packet type return; } else { System.Text.Encoding _enc = System.Text.Encoding.ASCII; switch (Pack.Type) { case PacketType.CompleteAgentMovement: if (this.m_child) { this.UpgradeClient(); } ClientAvatar.CompleteMovement(m_world); ClientAvatar.SendInitialPosition(); break; case PacketType.RegionHandshakeReply: m_world.SendLayerData(this); break; case PacketType.AgentWearablesRequest: ClientAvatar.SendInitialAppearance(); foreach (SimClient client in m_clientThreads.Values) { if (client.AgentID != this.AgentID) { ObjectUpdatePacket objupdate = client.ClientAvatar.CreateUpdatePacket(); this.OutPacket(objupdate); client.ClientAvatar.SendAppearanceToOtherAgent(this); } } m_world.GetInitialPrims(this); break; case PacketType.AgentIsNowWearing: AgentIsNowWearingPacket wear = (AgentIsNowWearingPacket)Pack; //Console.WriteLine(Pack.ToString()); break; case PacketType.AgentSetAppearance: AgentSetAppearancePacket appear = (AgentSetAppearancePacket)Pack; // Console.WriteLine(appear.ToString()); this.ClientAvatar.SetAppearance(appear); break; case PacketType.ObjectAdd: m_world.AddNewPrim((ObjectAddPacket)Pack, this); break; case PacketType.ObjectLink: OpenSim.Framework.Console.MainConsole.Instance.WriteLine(Pack.ToString()); ObjectLinkPacket link = (ObjectLinkPacket)Pack; uint parentprimid = 0; OpenSim.world.Primitive parentprim = null; if (link.ObjectData.Length > 1) { parentprimid = link.ObjectData[0].ObjectLocalID; foreach (Entity ent in m_world.Entities.Values) { if (ent.localid == parentprimid) { parentprim = (OpenSim.world.Primitive)ent; } } for (int i = 1; i < link.ObjectData.Length; i++) { foreach (Entity ent in m_world.Entities.Values) { if (ent.localid == link.ObjectData[i].ObjectLocalID) { ((OpenSim.world.Primitive)ent).MakeParent(parentprim); } } } } break; case PacketType.ObjectScale: OpenSim.Framework.Console.MainConsole.Instance.WriteLine(Pack.ToString()); break; case PacketType.ObjectShape: ObjectShapePacket shape = (ObjectShapePacket)Pack; for (int i = 0; i < shape.ObjectData.Length; i++) { foreach (Entity ent in m_world.Entities.Values) { if (ent.localid == shape.ObjectData[i].ObjectLocalID) { ((OpenSim.world.Primitive)ent).UpdateShape(shape.ObjectData[i]); } } } break; case PacketType.RequestImage: RequestImagePacket imageRequest = (RequestImagePacket)Pack; for (int i = 0; i < imageRequest.RequestImage.Length; i++) { m_assetCache.AddTextureRequest(this, imageRequest.RequestImage[i].Image); } break; case PacketType.TransferRequest: //Console.WriteLine("OpenSimClient.cs:ProcessInPacket() - Got transfer request"); TransferRequestPacket transfer = (TransferRequestPacket)Pack; m_assetCache.AddAssetRequest(this, transfer); break; case PacketType.AgentUpdate: ClientAvatar.HandleUpdate((AgentUpdatePacket)Pack); break; case PacketType.ObjectImage: ObjectImagePacket imagePack = (ObjectImagePacket)Pack; for (int i = 0; i < imagePack.ObjectData.Length; i++) { foreach (Entity ent in m_world.Entities.Values) { if (ent.localid == imagePack.ObjectData[i].ObjectLocalID) { ((OpenSim.world.Primitive)ent).UpdateTexture(imagePack.ObjectData[i].TextureEntry); } } } break; case PacketType.ObjectFlagUpdate: ObjectFlagUpdatePacket flags = (ObjectFlagUpdatePacket)Pack; foreach (Entity ent in m_world.Entities.Values) { if (ent.localid == flags.AgentData.ObjectLocalID) { ((OpenSim.world.Primitive)ent).UpdateObjectFlags(flags); } } break; case PacketType.AssetUploadRequest: AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack; this.UploadAssets.HandleUploadPacket(request, request.AssetBlock.TransactionID.Combine(this.SecureSessionID)); break; case PacketType.RequestXfer: //Console.WriteLine(Pack.ToString()); break; case PacketType.SendXferPacket: this.UploadAssets.HandleXferPacket((SendXferPacketPacket)Pack); break; case PacketType.CreateInventoryFolder: CreateInventoryFolderPacket invFolder = (CreateInventoryFolderPacket)Pack; m_inventoryCache.CreateNewInventoryFolder(this, invFolder.FolderData.FolderID, (ushort)invFolder.FolderData.Type, Util.FieldToString(invFolder.FolderData.Name), invFolder.FolderData.ParentID); //Console.WriteLine(Pack.ToString()); break; case PacketType.CreateInventoryItem: //Console.WriteLine(Pack.ToString()); CreateInventoryItemPacket createItem = (CreateInventoryItemPacket)Pack; if (createItem.InventoryBlock.TransactionID != LLUUID.Zero) { this.UploadAssets.CreateInventoryItem(createItem); } else { // Console.Write(Pack.ToString()); this.CreateInventoryItem(createItem); } break; case PacketType.FetchInventory: //Console.WriteLine("fetch item packet"); FetchInventoryPacket FetchInventory = (FetchInventoryPacket)Pack; m_inventoryCache.FetchInventory(this, FetchInventory); break; case PacketType.FetchInventoryDescendents: FetchInventoryDescendentsPacket Fetch = (FetchInventoryDescendentsPacket)Pack; m_inventoryCache.FetchInventoryDescendents(this, Fetch); break; case PacketType.UpdateInventoryItem: UpdateInventoryItemPacket update = (UpdateInventoryItemPacket)Pack; //Console.WriteLine(Pack.ToString()); for (int i = 0; i < update.InventoryData.Length; i++) { if (update.InventoryData[i].TransactionID != LLUUID.Zero) { AssetBase asset = m_assetCache.GetAsset(update.InventoryData[i].TransactionID.Combine(this.SecureSessionID)); if (asset != null) { // Console.WriteLine("updating inventory item, found asset" + asset.FullID.ToStringHyphenated() + " already in cache"); m_inventoryCache.UpdateInventoryItemAsset(this, update.InventoryData[i].ItemID, asset); } else { asset = this.UploadAssets.AddUploadToAssetCache(update.InventoryData[i].TransactionID); if (asset != null) { //Console.WriteLine("updating inventory item, adding asset" + asset.FullID.ToStringHyphenated() + " to cache"); m_inventoryCache.UpdateInventoryItemAsset(this, update.InventoryData[i].ItemID, asset); } else { //Console.WriteLine("trying to update inventory item, but asset is null"); } } } else { m_inventoryCache.UpdateInventoryItemDetails(this, update.InventoryData[i].ItemID, update.InventoryData[i]);; } } break; case PacketType.ViewerEffect: ViewerEffectPacket viewer = (ViewerEffectPacket)Pack; foreach (SimClient client in m_clientThreads.Values) { if (client.AgentID != this.AgentID) { viewer.AgentData.AgentID = client.AgentID; viewer.AgentData.SessionID = client.SessionID; client.OutPacket(viewer); } } break; case PacketType.RequestTaskInventory: // Console.WriteLine(Pack.ToString()); RequestTaskInventoryPacket requesttask = (RequestTaskInventoryPacket)Pack; ReplyTaskInventoryPacket replytask = new ReplyTaskInventoryPacket(); bool foundent = false; foreach (Entity ent in m_world.Entities.Values) { if (ent.localid == requesttask.InventoryData.LocalID) { replytask.InventoryData.TaskID = ent.uuid; replytask.InventoryData.Serial = 0; replytask.InventoryData.Filename = new byte[0]; foundent = true; } } if (foundent) { this.OutPacket(replytask); } break; case PacketType.UpdateTaskInventory: // Console.WriteLine(Pack.ToString()); UpdateTaskInventoryPacket updatetask = (UpdateTaskInventoryPacket)Pack; AgentInventory myinventory = this.m_inventoryCache.GetAgentsInventory(this.AgentID); if (myinventory != null) { if (updatetask.UpdateData.Key == 0) { if (myinventory.InventoryItems[updatetask.InventoryData.ItemID] != null) { if (myinventory.InventoryItems[updatetask.InventoryData.ItemID].Type == 7) { LLUUID noteaid = myinventory.InventoryItems[updatetask.InventoryData.ItemID].AssetID; AssetBase assBase = this.m_assetCache.GetAsset(noteaid); if (assBase != null) { foreach (Entity ent in m_world.Entities.Values) { if (ent.localid == updatetask.UpdateData.LocalID) { if (ent is OpenSim.world.Primitive) { this.m_world.AddScript(ent, Util.FieldToString(assBase.Data)); } } } } } } } } break; case PacketType.AgentAnimation: if (!m_child) { AgentAnimationPacket AgentAni = (AgentAnimationPacket)Pack; for (int i = 0; i < AgentAni.AnimationList.Length; i++) { if (AgentAni.AnimationList[i].StartAnim) { ClientAvatar.current_anim = AgentAni.AnimationList[i].AnimID; ClientAvatar.anim_seq = 1; ClientAvatar.SendAnimPack(); } } } break; case PacketType.ObjectSelect: ObjectSelectPacket incomingselect = (ObjectSelectPacket)Pack; for (int i = 0; i < incomingselect.ObjectData.Length; i++) { foreach (Entity ent in m_world.Entities.Values) { if (ent.localid == incomingselect.ObjectData[i].ObjectLocalID) { ((OpenSim.world.Primitive)ent).GetProperites(this); break; } } } break; } } }
private void PrimtiveBlockUpdate(Simulator simulator, ObjectMovementUpdate objectupdate0, Primitive prim,ObjectUpdatePacket.ObjectDataBlock block, Primitive.ConstructionData data) { bool isNewPrim = prim.Scale == Vector3.Zero && prim.Position == Vector3.Zero && prim.NameValues == null; if (prim.ID == UUID.Zero) { if (!simulator.Client.Settings.OBJECT_TRACKING) { throw new ArgumentException("Need to enable object tracking!!"); } SimObject O = GetSimObjectFromUUID(block.FullID); if (O == null) { Debug("PrimData ZERO for " + prim); if (block.ID > 0) { uint localID = block.ID; prim.LocalID = localID; prim.ID = block.FullID; // var p = simulator.Client.Objects.GetPrimitive(simulator, block.ID, block.FullID, false); // simulator.GetPrimitive( } } else { Debug("SimData ZERO for " + prim); uint localID = block.ID; prim.LocalID = localID; prim.ID = block.FullID; O.IsDebugging = true; } } // else { if (prim.RegionHandle == simulator.Handle && prim.ID != UUID.Zero) { if (!prim.PrimData.Equals(data) /* || prim.Scale != block.Scale || prim.Position != objectupdate.Position || prim.Rotation != objectupdate.Rotation || prim.ParentID != block.ParentID*/ ) { SimObject O = GetSimObjectFromUUID(prim.ID); if (O != null) { if (!isNewPrim) { Debug("PrimData changed for " + prim); O.PathFinding.RemoveCollisions(); } // the old OnNewPrim code will force the reindexing } else { //Debug("PrimData new for " + prim); O = GetSimObject(prim, simulator); return; } } if (!isNewPrim) { DeclareProperties(prim, prim.Properties, simulator); SendNewRegionEvent(SimEventType.DATA_UPDATE, "on-data-updated", prim); } //Objects_OnPrimitiveUpdate(simulator, prim, objectupdate0, simulator.Handle, 0); } else { //if (prim.RegionHandle == 0) // prim.RegionHandle = simulator.Handle; if (prim.ID != UUID.Zero) { SimObject O = GetSimObjectFromUUID(prim.ID); if (O != null && prim.Properties != null && prim.RegionHandle == simulator.Handle) { Objects_OnPrimitiveUpdateReal(simulator, prim, objectupdate0, simulator.Handle, 0); //O = GetSimObject(prim, simulator); } } } } }
private void UpdateHandler(Packet packet, Simulator simulator) { if (OnNewPrim != null || OnNewAvatar != null) { ObjectUpdatePacket update = (ObjectUpdatePacket)packet; foreach (ObjectUpdatePacket.ObjectDataBlock block in update.ObjectData) { if (block.PCode == (byte)PCode.Prim) { if (OnNewPrim != null) { // New prim spotted PrimObject prim = new PrimObject(Client); prim.Position = new LLVector3(block.ObjectData, 0); prim.Rotation = new LLQuaternion(block.ObjectData, 36, true); // TODO: Parse the rest of the ObjectData byte array fields prim.LocalID = block.ID; prim.State = block.State; prim.ID = block.FullID; prim.ParentID = block.ParentID; //block.OwnerID Sound-related prim.Material = block.Material; prim.PathCurve = block.PathCurve; prim.ProfileCurve = block.ProfileCurve; prim.PathBegin = PrimObject.PathBeginFloat(block.PathBegin); prim.PathEnd = PrimObject.PathEndFloat(block.PathEnd); prim.PathTaperX = PrimObject.PathScaleFloat(block.PathScaleX); prim.PathTaperY = PrimObject.PathScaleFloat(block.PathScaleY); prim.PathShearX = PrimObject.PathShearFloat(block.PathShearX); prim.PathShearY = PrimObject.PathShearFloat(block.PathShearY); prim.PathTwist = block.PathTwist; //PrimObject.PathTwistFloat(block.PathTwist); prim.PathTwistBegin = block.PathTwistBegin; //PrimObject.PathTwistFloat(block.PathTwistBegin); prim.PathRadiusOffset = PrimObject.PathRadiusOffsetFloat(block.PathRadiusOffset); //prim.PathTaperX = PrimObject.PathTaperFloat((byte)block.PathTaperX); //prim.PathTaperY = PrimObject.PathTaperFloat((byte)block.PathTaperY); prim.PathRevolutions = PrimObject.PathRevolutionsFloat(block.PathRevolutions); prim.PathSkew = PrimObject.PathSkewFloat((byte)block.PathSkew); prim.ProfileBegin = PrimObject.ProfileBeginFloat(block.ProfileBegin); prim.ProfileEnd = PrimObject.ProfileEndFloat(block.ProfileEnd); prim.ProfileHollow = block.ProfileHollow; prim.Name = Helpers.FieldToString(block.NameValue); //block.Data ? prim.Text = ASCIIEncoding.ASCII.GetString(block.Text); //block.TextColor LLColor4U of the hovering text //block.MediaURL Quicktime stream prim.Textures = new TextureEntry(block.TextureEntry, 0, block.TextureEntry.Length); prim.TextureAnim = new TextureAnimation(block.TextureAnim, 0); //block.JointType ? //block.JointPivot ? //block.JointAxisOrAnchor ? prim.ParticleSys = new ParticleSystem(block.PSBlock, 0); prim.SetExtraParamsFromBytes(block.ExtraParams, 0); prim.Scale = block.Scale; //block.Flags ? //block.UpdateFlags ? //block.ClickAction ? //block.Gain Sound-related //block.Sound Sound-related //block.Radius Sound-related if (OnNewPrim != null) { OnNewPrim(simulator, prim, update.RegionData.RegionHandle, update.RegionData.TimeDilation); } } } else if (block.PCode == (byte)PCode.Avatar) { if (OnNewAvatar != null) { Avatar avatar = new Avatar(); string FirstName = ""; string LastName = ""; string GroupName = ""; //avatar.CollisionPlane = new LLQuaternion(block.ObjectData, 0); avatar.Position = new LLVector3(block.ObjectData, 16); avatar.Rotation = new LLQuaternion(block.ObjectData, 52, true); // TODO: Parse the rest of the ObjectData byte array fields ParseAvName(Helpers.FieldToString(block.NameValue), ref FirstName, ref LastName, ref GroupName); avatar.ID = block.FullID; avatar.LocalID = block.ID; avatar.Name = FirstName + " " + LastName; avatar.GroupName = GroupName; avatar.Online = true; avatar.CurrentRegion = simulator.Region; avatar.Textures = new TextureEntry(block.TextureEntry, 0, block.TextureEntry.Length); if (FirstName == Client.Self.FirstName && LastName == Client.Self.LastName) { // Update our avatar Client.Self.LocalID = avatar.LocalID; Client.Self.Position = avatar.Position; Client.Self.Rotation = avatar.Rotation; } else { if (OnNewAvatar != null) { OnNewAvatar(simulator, avatar, update.RegionData.RegionHandle, update.RegionData.TimeDilation); } } } } else if (block.PCode == (byte)PCode.Grass) { // FIXME: Handle grass objects ; } else if (block.PCode == (byte)PCode.Tree) { // FIXME: Handle tree objects ; } else if (block.PCode == (byte)PCode.ParticleSystem) { ; } else { // FIXME: How many of the PCodes do we actually need to handle? ; } } } }
private void ObjectDataBlockUpdateHandler(Simulator simulator, Primitive prim, Primitive.ConstructionData constructionData, ObjectUpdatePacket.ObjectDataBlock block, ObjectUpdate update, NameValue[] nameValues) { // Note: We can't do membership or really much useful here since the // primitive doesn't have its information filled in quite yet. Instead, // we're forced to use the OnNew* events, which get called *after* all // the data has been filled in. //Console.WriteLine("Object: " + update.LocalID.ToString() + " - " + update.Position.ToString() + " " + update.Velocity.ToString()); }
public void SendFullUpdateToClient(SimClient remoteClient) { LLVector3 lPos; if (this._physActor != null && this.physicsEnabled) { PhysicsVector pPos = this._physActor.Position; lPos = new LLVector3(pPos.X, pPos.Y, pPos.Z); } else { lPos = this.Pos; } ObjectUpdatePacket outPacket = new ObjectUpdatePacket(); outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; outPacket.ObjectData[0] = this.CreateUpdateBlock(); byte[] pb = lPos.GetBytes(); Array.Copy(pb, 0, outPacket.ObjectData[0].ObjectData, 0, pb.Length); remoteClient.OutPacket(outPacket); }
public Packet inClo(Packet packet, IPEndPoint sim) { AvatarAppearancePacket appearance = (AvatarAppearancePacket)packet; //Console.WriteLine("1"); if (avclients.ContainsKey(appearance.Sender.ID)) { if (avclients[appearance.Sender.ID] != "") return packet; } //Console.WriteLine("2"); Primitive.TextureEntry te = new Primitive.TextureEntry(appearance.ObjectData.TextureEntry, 0, appearance.ObjectData.TextureEntry.Length); string client = ""; if (((te != null) && (te.FaceTextures != null)) && (te.FaceTextures.Length > 0)) { //Console.WriteLine("3"); for (int i = 0; i < te.FaceTextures.Length; i++) { string t = UUID.Zero.ToString(); try { t = te.FaceTextures[i].TextureID.ToString(); } catch (Exception) { } if (client == "") { if (uid2name.ContainsKey(new UUID(t))) { client = uid2name[new UUID(t)]; } } //Console.WriteLine("4"); } //Console.WriteLine("11"); if (avclients.ContainsKey(appearance.Sender.ID)) { //Console.WriteLine("41"); avclients[appearance.Sender.ID] = client; //writethis(".We found " + appearance.Sender.ID.ToString() + "'s client to be " + client, ConsoleColor.Red, ConsoleColor.White); } else { //Console.WriteLine("42"); avclients.Add(appearance.Sender.ID, client); //Console.WriteLine("5"); //writethis("We found " + appearance.Sender.ID.ToString() + "'s client to be " + client, ConsoleColor.Red, ConsoleColor.White); } if (blocks.ContainsKey(appearance.Sender.ID)) { ObjectUpdatePacket.ObjectDataBlock block; lock (blocks) { block = blocks[appearance.Sender.ID]; blocks.Remove(appearance.Sender.ID); } ObjectUpdatePacket oup = new ObjectUpdatePacket(); oup.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; oup.ObjectData[0] = modBlock(block); oup.RegionData = rb; oup.Header.Reliable = true; proxy.InjectPacket(oup, Direction.Incoming); } } updateList(); //Console.WriteLine("6"); return appearance; }
protected void DecodeParticleUpdate(ObjectUpdatePacket.ObjectDataBlock block) { // TODO: Handle ParticleSystem ObjectUpdate blocks // float bounce_b // Vector4 scale_range // Vector4 alpha_range // Vector3 vel_offset // float dist_begin_fadeout // float dist_end_fadeout // UUID image_uuid // long flags // byte createme // Vector3 diff_eq_alpha // Vector3 diff_eq_scale // byte max_particles // byte initial_particles // float kill_plane_z // Vector3 kill_plane_normal // float bounce_plane_z // Vector3 bounce_plane_normal // float spawn_range // float spawn_frequency // float spawn_frequency_range // Vector3 spawn_direction // float spawn_direction_range // float spawn_velocity // float spawn_velocity_range // float speed_limit // float wind_weight // Vector3 current_gravity // float gravity_weight // float global_lifetime // float individual_lifetime // float individual_lifetime_range // float alpha_decay // float scale_decay // float distance_death // float damp_motion_factor // Vector3 wind_diffusion_factor }
protected void UpdatePacketShapeData(ObjectUpdatePacket.ObjectDataBlock objectData) { objectData.OwnerID = this.primData.OwnerID; objectData.PCode = this.primData.PCode; objectData.PathBegin = this.primData.PathBegin; objectData.PathEnd = this.primData.PathEnd; objectData.PathScaleX = this.primData.PathScaleX; objectData.PathScaleY = this.primData.PathScaleY; objectData.PathShearX = this.primData.PathShearX; objectData.PathShearY = this.primData.PathShearY; objectData.PathSkew = this.primData.PathSkew; objectData.ProfileBegin = this.primData.ProfileBegin; objectData.ProfileEnd = this.primData.ProfileEnd; objectData.Scale = this.primData.Scale; objectData.PathCurve = this.primData.PathCurve; objectData.ProfileCurve = this.primData.ProfileCurve; objectData.ParentID = this.primData.ParentID; objectData.ProfileHollow = this.primData.ProfileHollow; objectData.PathRadiusOffset = this.primData.PathRadiusOffset; objectData.PathRevolutions = this.primData.PathRevolutions; objectData.PathTaperX = this.primData.PathTaperX; objectData.PathTaperY = this.primData.PathTaperY; objectData.PathTwist = this.primData.PathTwist; objectData.PathTwistBegin = this.primData.PathTwistBegin; }
protected void SetDefaultPacketValues(ObjectUpdatePacket.ObjectDataBlock objdata) { objdata.PSBlock = new byte[0]; objdata.ExtraParams = new byte[1]; objdata.MediaURL = new byte[0]; objdata.NameValue = new byte[0]; objdata.Text = new byte[0]; objdata.TextColor = new byte[4]; objdata.JointAxisOrAnchor = new LLVector3(0, 0, 0); objdata.JointPivot = new LLVector3(0, 0, 0); objdata.Material = 3; objdata.TextureAnim = new byte[0]; objdata.Sound = LLUUID.Zero; LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005")); this.primData.Texture = objdata.TextureEntry = ntex.ToBytes(); objdata.State = 0; objdata.Data = new byte[0]; objdata.ObjectData = new byte[60]; objdata.ObjectData[46] = 128; objdata.ObjectData[47] = 63; }
//test only private void SendAvatarData(NetworkInfo userInfo) { ObjectUpdatePacket objupdate = new ObjectUpdatePacket(); objupdate.RegionData.RegionHandle = Globals.Instance.RegionHandle; objupdate.RegionData.TimeDilation = 64096; objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; objupdate.ObjectData[0] = _avatarTemplate; //give this avatar object a local id and assign the user a name objupdate.ObjectData[0].ID = 8880000;// + this._localNumber; userInfo.User.AvatarLocalID = objupdate.ObjectData[0].ID; //User_info.name="Test"+this.local_numer+" User"; //this.GetAgent(userInfo.UserAgentID).Started = true; objupdate.ObjectData[0].FullID = userInfo.User.AgentID; objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + userInfo.User.FirstName + "\nLastName STRING RW SV " + userInfo.User.LastName + " \0"); //userInfo.User.FullName = "FirstName STRING RW SV " + userInfo.first_name + "\nLastName STRING RW SV " + userInfo.last_name + " \0"; libsecondlife.LLVector3 pos2 = new LLVector3(100f, 100.0f, 22.0f); byte[] pb = pos2.GetBytes(); Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); //this._localNumber++; _server.SendPacket(objupdate, true, userInfo); }
public ObjectUpdatePacket CreateUpdatePacket() { System.Text.Encoding _enc = System.Text.Encoding.ASCII; //send a objectupdate packet with information about the clients avatar ObjectUpdatePacket objupdate = new ObjectUpdatePacket(); objupdate.RegionData.RegionHandle = m_regionHandle; objupdate.RegionData.TimeDilation = 64096; objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; objupdate.ObjectData[0] = AvatarTemplate; //give this avatar object a local id and assign the user a name objupdate.ObjectData[0].ID = this.localid; objupdate.ObjectData[0].FullID = ControllingClient.AgentID; objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + firstname + "\nLastName STRING RW SV " + lastname + " \0"); libsecondlife.LLVector3 pos2 = new LLVector3((float)this._physActor.Position.X, (float)this._physActor.Position.Y, (float)this._physActor.Position.Z); byte[] pb = pos2.GetBytes(); Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); return objupdate; }
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 (!server.Scene.TryGetObject(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); } } for (int i = 0; i < linkSet.Count; i++) { linkSet[i].LinkNumber = i + 1; ObjectUpdatePacket update = new ObjectUpdatePacket(); update.RegionData.RegionHandle = server.RegionHandle; update.RegionData.TimeDilation = UInt16.MaxValue; update.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; update.ObjectData[0] = SimulationObject.BuildUpdateBlock(linkSet[i].Prim, server.RegionHandle, linkSet[i].Prim.PrimData.State, linkSet[i].Prim.Flags); if (linkSet[i].Prim.ParentID > 0) { //previously linked children SimulationObject parent; if (server.Scene.TryGetObject(linkSet[i].Prim.ParentID, out parent)) { //re-add old root orientation linkSet[i].Prim.Position = parent.Prim.Position + Vector3.Transform(linkSet[i].Prim.Position, Matrix4.CreateFromQuaternion(parent.Prim.Rotation)); linkSet[i].Prim.Rotation *= parent.Prim.Rotation; } } if (i > 0) { //subtract root prim orientation linkSet[i].Prim.Position = Vector3.Transform(linkSet[i].Prim.Position - linkSet[0].Prim.Position, Matrix4.CreateFromQuaternion(Quaternion.Identity / linkSet[0].Prim.Rotation)); linkSet[i].Prim.Rotation /= linkSet[0].Prim.Rotation; //set parent ID update.ObjectData[0].ParentID = linkSet[0].Prim.LocalID; } else { //root prim update.ObjectData[0].ParentID = 0; } update.ObjectData[0].ObjectData = SimulationObject.BuildObjectData( linkSet[i].Prim.Position, linkSet[i].Prim.Rotation, Vector3.Zero, Vector3.Zero, Vector3.Zero); server.UDP.BroadcastPacket(update, PacketCategory.State); } }
private void SendEntityPackets(QueuedInterestListEvent[] eventDatas, IScenePresence presence) { if (!(presence is LLAgent) || presence.InterestList == null) return; LLAgent agent = (LLAgent)presence; Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>(); Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); for (int i = 0; i < eventDatas.Length; i++) { EntityAddOrUpdateArgs e = (EntityAddOrUpdateArgs)eventDatas[i].Event.State; ISceneEntity entity = e.Entity; #region UpdateFlags to packet type conversion UpdateFlags updateFlags = e.UpdateFlags; LLUpdateFlags llUpdateFlags = (LLUpdateFlags)e.ExtraFlags; bool canUseImproved = true; if (updateFlags.HasFlag(UpdateFlags.FullUpdate) || updateFlags.HasFlag(UpdateFlags.Parent) || updateFlags.HasFlag(UpdateFlags.Scale) || updateFlags.HasFlag(UpdateFlags.Shape) || llUpdateFlags.HasFlag(LLUpdateFlags.PrimFlags) || llUpdateFlags.HasFlag(LLUpdateFlags.Text) || llUpdateFlags.HasFlag(LLUpdateFlags.NameValue) || llUpdateFlags.HasFlag(LLUpdateFlags.ExtraData) || llUpdateFlags.HasFlag(LLUpdateFlags.TextureAnim) || llUpdateFlags.HasFlag(LLUpdateFlags.Sound) || llUpdateFlags.HasFlag(LLUpdateFlags.Particles) || llUpdateFlags.HasFlag(LLUpdateFlags.Material) || llUpdateFlags.HasFlag(LLUpdateFlags.ClickAction) || llUpdateFlags.HasFlag(LLUpdateFlags.MediaURL) || llUpdateFlags.HasFlag(LLUpdateFlags.Joint)) { canUseImproved = false; } #endregion UpdateFlags to packet type conversion #region Block Construction if (!canUseImproved) { if (entity is IScenePresence) objectUpdateBlocks.Value.Add(CreateAvatarObjectUpdateBlock((IScenePresence)entity, presence)); else objectUpdateBlocks.Value.Add(CreateObjectUpdateBlock(entity, presence)); } else { terseUpdateBlocks.Value.Add(CreateTerseUpdateBlock(entity, llUpdateFlags.HasFlag(LLUpdateFlags.Textures))); } #endregion Block Construction // Unset CreateSelected after it has been sent once if (entity is LLPrimitive) { LLPrimitive prim = (LLPrimitive)entity; prim.Prim.Flags &= ~PrimFlags.CreateSelected; } } #region Packet Sending ushort timeDilation = (m_physics != null) ? Utils.FloatToUInt16(m_physics.TimeDilation, 0.0f, 1.0f) : UInt16.MaxValue; if (objectUpdateBlocks.IsValueCreated) { List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; ObjectUpdatePacket packet = new ObjectUpdatePacket(); packet.RegionData.RegionHandle = Util.PositionToRegionHandle(m_scene.MinPosition); packet.RegionData.TimeDilation = timeDilation; packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; for (int i = 0; i < blocks.Count; i++) packet.ObjectData[i] = blocks[i]; m_udp.SendPacket(agent, packet, ThrottleCategory.Task, true); } if (compressedUpdateBlocks.IsValueCreated) { List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; ObjectUpdateCompressedPacket packet = new ObjectUpdateCompressedPacket(); packet.RegionData.RegionHandle = Util.PositionToRegionHandle(m_scene.MinPosition); packet.RegionData.TimeDilation = timeDilation; packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count]; for (int i = 0; i < blocks.Count; i++) packet.ObjectData[i] = blocks[i]; m_udp.SendPacket(agent, packet, ThrottleCategory.Task, true); } if (terseUpdateBlocks.IsValueCreated) { List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); packet.RegionData.RegionHandle = Util.PositionToRegionHandle(m_scene.MinPosition); packet.RegionData.TimeDilation = timeDilation; packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; for (int i = 0; i < blocks.Count; i++) packet.ObjectData[i] = blocks[i]; m_udp.SendPacket(agent, packet, ThrottleCategory.Task, true); } #endregion Packet Sending }
public override void physicsManager_PreIntegrate() { lock (gameObjects) { #region Send Action Updates to the server foreach (int i in clientControlledObjects) { if (!gameObjects.ContainsKey(i)) { continue; } Entity go = gameObjects[i]; if (!go.actionManager.actionApplied) { continue; } if (go is RoverObject) { } object[] vals = go.actionManager.GetActionValues(); go.actionManager.ValueSwap(); commClient.SendObjectAction(go.ID, vals); } #endregion #region Process packets from the server List <object> ShouldRetry = new List <object>(); lock (MultiplayerUpdateQueue) { while (MultiplayerUpdateQueue.Count > 0) { Packet p = MultiplayerUpdateQueue[0] as Packet; MultiplayerUpdateQueue.RemoveAt(0); if (p is ObjectUpdatePacket) { #region Process Update Packets from the server ObjectUpdatePacket oup = p as ObjectUpdatePacket; if (!gameObjects.ContainsKey(oup.objectId)) { AddNewObject(oup.objectId, oup.assetName); ShouldRetry.Add(oup); continue; // TODO - Should we continue instead of not updating this frame? } // (can't yet due to AddNewObject waiting until the next integrate to actually add it) Entity go = gameObjects[oup.objectId]; if (go.hasNotDoneFirstInterpoladation) { go.Interpoladate(oup.position, oup.orientation, oup.velocity, 1.0f); // Server knows best! } else { go.Interpoladate(oup.position, oup.orientation, oup.velocity); // split realities 50/50 } #endregion } else if (p is ObjectAttributePacket) { #region Process Attribute Packets from the server ObjectAttributePacket oap = p as ObjectAttributePacket; if (gameObjects.ContainsKey(oap.objectId)) { Entity go = gameObjects[oap.objectId]; bool locallyOwnedAndOperated = false; if (go.OwningClientId == MyClientID) { locallyOwnedAndOperated = true; } go.SetObjectAttributes(oap.booleans, oap.ints, oap.floats, locallyOwnedAndOperated); } #endregion } } while (ShouldRetry.Count > 0) { MultiplayerUpdateQueue.Add(ShouldRetry[0]); ShouldRetry.RemoveAt(0); } } #endregion } }
void SendObjectPacket(SimulationObject obj, bool canUseCompressed, bool canUseImproved, PrimFlags creatorFlags, UpdateFlags updateFlags) { if (!canUseImproved && !canUseCompressed) { #region ObjectUpdate Logger.DebugLog("Sending ObjectUpdate"); if (sceneAgents.ContainsKey(obj.Prim.OwnerID)) { // Send an update out to the creator ObjectUpdatePacket updateToOwner = new ObjectUpdatePacket(); updateToOwner.RegionData.RegionHandle = regionHandle; updateToOwner.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue); updateToOwner.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; updateToOwner.ObjectData[0] = SimulationObject.BuildUpdateBlock(obj.Prim, obj.Prim.Flags | creatorFlags | PrimFlags.ObjectYouOwner, obj.CRC); udp.SendPacket(obj.Prim.OwnerID, updateToOwner, PacketCategory.State); } // Send an update out to everyone else ObjectUpdatePacket updateToOthers = new ObjectUpdatePacket(); updateToOthers.RegionData.RegionHandle = regionHandle; updateToOthers.RegionData.TimeDilation = UInt16.MaxValue; updateToOthers.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; updateToOthers.ObjectData[0] = SimulationObject.BuildUpdateBlock(obj.Prim, obj.Prim.Flags, obj.CRC); ForEachAgent( delegate(Agent recipient) { if (recipient.ID != obj.Prim.OwnerID) udp.SendPacket(recipient.ID, updateToOthers, PacketCategory.State); } ); #endregion ObjectUpdate } else if (!canUseImproved) { #region ObjectUpdateCompressed #region Size calculation and field serialization CompressedFlags flags = 0; int size = 84; byte[] textBytes = null; byte[] mediaURLBytes = null; byte[] particleBytes = null; byte[] extraParamBytes = null; byte[] nameValueBytes = null; byte[] textureBytes = null; byte[] textureAnimBytes = null; if ((updateFlags & UpdateFlags.AngularVelocity) != 0) { flags |= CompressedFlags.HasAngularVelocity; size += 12; } if ((updateFlags & UpdateFlags.ParentID) != 0) { flags |= CompressedFlags.HasParent; size += 4; } if ((updateFlags & UpdateFlags.ScratchPad) != 0) { switch (obj.Prim.PrimData.PCode) { case PCode.Grass: case PCode.Tree: case PCode.NewTree: flags |= CompressedFlags.Tree; size += 2; // Size byte plus one byte break; default: flags |= CompressedFlags.ScratchPad; size += 1 + obj.Prim.ScratchPad.Length; // Size byte plus bytes break; } } if ((updateFlags & UpdateFlags.Text) != 0) { flags |= CompressedFlags.HasText; textBytes = Utils.StringToBytes(obj.Prim.Text); size += textBytes.Length; // Null-terminated, no size byte size += 4; // Text color } if ((updateFlags & UpdateFlags.MediaURL) != 0) { flags |= CompressedFlags.MediaURL; mediaURLBytes = Utils.StringToBytes(obj.Prim.MediaURL); size += mediaURLBytes.Length; // Null-terminated, no size byte } if ((updateFlags & UpdateFlags.Particles) != 0) { flags |= CompressedFlags.HasParticles; particleBytes = obj.Prim.ParticleSys.GetBytes(); size += particleBytes.Length; // Should be exactly 86 bytes } // Extra Params extraParamBytes = obj.Prim.GetExtraParamsBytes(); size += extraParamBytes.Length; if ((updateFlags & UpdateFlags.Sound) != 0) { flags |= CompressedFlags.HasSound; size += 25; // SoundID, SoundGain, SoundFlags, SoundRadius } if ((updateFlags & UpdateFlags.NameValue) != 0) { flags |= CompressedFlags.HasNameValues; nameValueBytes = Utils.StringToBytes(NameValue.NameValuesToString(obj.Prim.NameValues)); size += nameValueBytes.Length; // Null-terminated, no size byte } size += 23; // PrimData size += 4; // Texture Length textureBytes = obj.Prim.Textures.GetBytes(); size += textureBytes.Length; // Texture Entry if ((updateFlags & UpdateFlags.TextureAnim) != 0) { flags |= CompressedFlags.TextureAnimation; size += 4; // TextureAnim Length textureAnimBytes = obj.Prim.TextureAnim.GetBytes(); size += textureAnimBytes.Length; // TextureAnim } #endregion Size calculation and field serialization #region Packet serialization int pos = 0; byte[] data = new byte[size]; // UUID obj.Prim.ID.ToBytes(data, 0); pos += 16; // LocalID Utils.UIntToBytes(obj.Prim.LocalID, data, pos); pos += 4; // PCode data[pos++] = (byte)obj.Prim.PrimData.PCode; // State data[pos++] = obj.Prim.PrimData.State; // CRC Utils.UIntToBytes(obj.CRC, data, pos); pos += 4; // Material data[pos++] = (byte)obj.Prim.PrimData.Material; // ClickAction data[pos++] = (byte)obj.Prim.ClickAction; // Scale obj.Prim.Scale.ToBytes(data, pos); pos += 12; // Position obj.Prim.Position.ToBytes(data, pos); pos += 12; // Rotation obj.Prim.Rotation.ToBytes(data, pos); pos += 12; // Compressed Flags Utils.UIntToBytes((uint)flags, data, pos); pos += 4; // OwnerID obj.Prim.OwnerID.ToBytes(data, pos); pos += 16; if ((flags & CompressedFlags.HasAngularVelocity) != 0) { obj.Prim.AngularVelocity.ToBytes(data, pos); pos += 12; } if ((flags & CompressedFlags.HasParent) != 0) { Utils.UIntToBytes(obj.Prim.ParentID, data, pos); pos += 4; } if ((flags & CompressedFlags.ScratchPad) != 0) { data[pos++] = (byte)obj.Prim.ScratchPad.Length; Buffer.BlockCopy(obj.Prim.ScratchPad, 0, data, pos, obj.Prim.ScratchPad.Length); pos += obj.Prim.ScratchPad.Length; } else if ((flags & CompressedFlags.Tree) != 0) { data[pos++] = 1; data[pos++] = (byte)obj.Prim.TreeSpecies; } if ((flags & CompressedFlags.HasText) != 0) { Buffer.BlockCopy(textBytes, 0, data, pos, textBytes.Length); pos += textBytes.Length; obj.Prim.TextColor.ToBytes(data, pos, false); pos += 4; } if ((flags & CompressedFlags.MediaURL) != 0) { Buffer.BlockCopy(mediaURLBytes, 0, data, pos, mediaURLBytes.Length); pos += mediaURLBytes.Length; } if ((flags & CompressedFlags.HasParticles) != 0) { Buffer.BlockCopy(particleBytes, 0, data, pos, particleBytes.Length); pos += particleBytes.Length; } // Extra Params Buffer.BlockCopy(extraParamBytes, 0, data, pos, extraParamBytes.Length); pos += extraParamBytes.Length; if ((flags & CompressedFlags.HasSound) != 0) { obj.Prim.Sound.ToBytes(data, pos); pos += 16; Utils.FloatToBytes(obj.Prim.SoundGain, data, pos); pos += 4; data[pos++] = (byte)obj.Prim.SoundFlags; Utils.FloatToBytes(obj.Prim.SoundRadius, data, pos); pos += 4; } if ((flags & CompressedFlags.HasNameValues) != 0) { Buffer.BlockCopy(nameValueBytes, 0, data, pos, nameValueBytes.Length); pos += nameValueBytes.Length; } // Path PrimData data[pos++] = (byte)obj.Prim.PrimData.PathCurve; Utils.UInt16ToBytes(Primitive.PackBeginCut(obj.Prim.PrimData.PathBegin), data, pos); pos += 2; Utils.UInt16ToBytes(Primitive.PackEndCut(obj.Prim.PrimData.PathEnd), data, pos); pos += 2; data[pos++] = Primitive.PackPathScale(obj.Prim.PrimData.PathScaleX); data[pos++] = Primitive.PackPathScale(obj.Prim.PrimData.PathScaleY); data[pos++] = (byte)Primitive.PackPathShear(obj.Prim.PrimData.PathShearX); data[pos++] = (byte)Primitive.PackPathShear(obj.Prim.PrimData.PathShearY); data[pos++] = (byte)Primitive.PackPathTwist(obj.Prim.PrimData.PathTwist); data[pos++] = (byte)Primitive.PackPathTwist(obj.Prim.PrimData.PathTwistBegin); data[pos++] = (byte)Primitive.PackPathTwist(obj.Prim.PrimData.PathRadiusOffset); data[pos++] = (byte)Primitive.PackPathTaper(obj.Prim.PrimData.PathTaperX); data[pos++] = (byte)Primitive.PackPathTaper(obj.Prim.PrimData.PathTaperY); data[pos++] = Primitive.PackPathRevolutions(obj.Prim.PrimData.PathRevolutions); data[pos++] = (byte)Primitive.PackPathTwist(obj.Prim.PrimData.PathSkew); // Profile PrimData data[pos++] = obj.Prim.PrimData.profileCurve; Utils.UInt16ToBytes(Primitive.PackBeginCut(obj.Prim.PrimData.ProfileBegin), data, pos); pos += 2; Utils.UInt16ToBytes(Primitive.PackEndCut(obj.Prim.PrimData.ProfileEnd), data, pos); pos += 2; Utils.UInt16ToBytes(Primitive.PackProfileHollow(obj.Prim.PrimData.ProfileHollow), data, pos); pos += 2; // Texture Length Utils.UIntToBytes((uint)textureBytes.Length, data, pos); pos += 4; // Texture Entry Buffer.BlockCopy(textureBytes, 0, data, pos, textureBytes.Length); pos += textureBytes.Length; if ((flags & CompressedFlags.TextureAnimation) != 0) { Utils.UIntToBytes((uint)textureAnimBytes.Length, data, pos); pos += 4; Buffer.BlockCopy(textureAnimBytes, 0, data, pos, textureAnimBytes.Length); pos += textureAnimBytes.Length; } #endregion Packet serialization #region Packet sending //Logger.DebugLog("Sending ObjectUpdateCompressed with " + flags.ToString()); if (sceneAgents.ContainsKey(obj.Prim.OwnerID)) { // Send an update out to the creator ObjectUpdateCompressedPacket updateToOwner = new ObjectUpdateCompressedPacket(); updateToOwner.RegionData.RegionHandle = regionHandle; updateToOwner.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue); updateToOwner.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[1]; updateToOwner.ObjectData[0] = new ObjectUpdateCompressedPacket.ObjectDataBlock(); updateToOwner.ObjectData[0].UpdateFlags = (uint)(obj.Prim.Flags | creatorFlags | PrimFlags.ObjectYouOwner); updateToOwner.ObjectData[0].Data = data; udp.SendPacket(obj.Prim.OwnerID, updateToOwner, PacketCategory.State); } // Send an update out to everyone else ObjectUpdateCompressedPacket updateToOthers = new ObjectUpdateCompressedPacket(); updateToOthers.RegionData.RegionHandle = regionHandle; updateToOthers.RegionData.TimeDilation = UInt16.MaxValue; updateToOthers.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[1]; updateToOthers.ObjectData[0] = new ObjectUpdateCompressedPacket.ObjectDataBlock(); updateToOthers.ObjectData[0].UpdateFlags = (uint)obj.Prim.Flags; updateToOthers.ObjectData[0].Data = data; ForEachAgent( delegate(Agent recipient) { if (recipient.ID != obj.Prim.OwnerID) udp.SendPacket(recipient.ID, updateToOthers, PacketCategory.State); } ); #endregion Packet sending #endregion ObjectUpdateCompressed } else { #region ImprovedTerseObjectUpdate //Logger.DebugLog("Sending ImprovedTerseObjectUpdate"); int pos = 0; byte[] data = new byte[(obj.Prim is Avatar ? 60 : 44)]; // LocalID Utils.UIntToBytes(obj.Prim.LocalID, data, pos); pos += 4; // Avatar/CollisionPlane data[pos++] = obj.Prim.PrimData.State; if (obj.Prim is Avatar) { data[pos++] = 1; obj.Prim.CollisionPlane.ToBytes(data, pos); pos += 16; } else { ++pos; } // Position obj.Prim.Position.ToBytes(data, pos); pos += 12; // Velocity Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Velocity.X, -128.0f, 128.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Velocity.Y, -128.0f, 128.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Velocity.Z, -128.0f, 128.0f), data, pos); pos += 2; // Acceleration Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Acceleration.X, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Acceleration.Y, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Acceleration.Z, -64.0f, 64.0f), data, pos); pos += 2; // Rotation Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Rotation.X, -1.0f, 1.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Rotation.Y, -1.0f, 1.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Rotation.Z, -1.0f, 1.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Rotation.W, -1.0f, 1.0f), data, pos); pos += 2; // Angular Velocity Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.AngularVelocity.X, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.AngularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.AngularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2; ImprovedTerseObjectUpdatePacket update = new ImprovedTerseObjectUpdatePacket(); update.RegionData.RegionHandle = RegionHandle; update.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue); update.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; update.ObjectData[0] = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock(); update.ObjectData[0].Data = data; if ((updateFlags & UpdateFlags.Textures) != 0) { byte[] textureBytes = obj.Prim.Textures.GetBytes(); byte[] textureEntry = new byte[textureBytes.Length + 4]; // Texture Length Utils.IntToBytes(textureBytes.Length, textureEntry, 0); // Texture Buffer.BlockCopy(textureBytes, 0, textureEntry, 4, textureBytes.Length); update.ObjectData[0].TextureEntry = textureEntry; } else { update.ObjectData[0].TextureEntry = Utils.EmptyBytes; } udp.BroadcastPacket(update, PacketCategory.State); #endregion ImprovedTerseObjectUpdate } }
public ObjectUpdatePacket.ObjectDataBlock modBlock(ObjectUpdatePacket.ObjectDataBlock block) { string FirstName = null; string LastName = null; string Title = null; string[] namevalues = Utils.BytesToString(block.NameValue).Split("\r\n".ToCharArray()); foreach (string line in namevalues) { NameValue namevalue = new NameValue(line); if (namevalue.Value != null) { if (namevalue.Name == "FirstName") { FirstName = Convert.ToString(namevalue.Value); if (avclients.ContainsKey(block.FullID)) { if (avclients[block.FullID] == "") { } else { if (form.Display()) FirstName = "(" + avclients[block.FullID] + ") " + FirstName; } namevalue.Value = FirstName; } else { blocks.Add(block.FullID, block); } } else if (namevalue.Name == "LastName") { LastName = Convert.ToString(namevalue.Value); } else if (namevalue.Name == "Title") { Title = Convert.ToString(namevalue.Value); } } } string newname = ""; if (FirstName != null) { if (newname != "") newname += "\r\n"; newname += "FirstName STRING RW SV " + FirstName; } if (LastName != null) { if (newname != "") newname += "\n"; newname += "LastName STRING RW SV " + LastName; } if (Title != null) { if (newname != "") newname += "\r\n"; newname += "Title STRING RW SV " + Title; } block.NameValue = Utils.StringToBytes(newname); //writethis("\n" + block.FullID.ToString() + "\n" + newname, ConsoleColor.White, ConsoleColor.Green); return block; }
protected static void SetDefaultPacketValues(ObjectUpdatePacket.ObjectDataBlock objdata) { objdata.PSBlock = new byte[0]; objdata.ExtraParams = new byte[1]; objdata.MediaURL = new byte[0]; objdata.NameValue = new byte[0]; objdata.Text = new byte[0]; objdata.TextColor = new byte[4]; objdata.JointAxisOrAnchor = new LLVector3(0, 0, 0); objdata.JointPivot = new LLVector3(0, 0, 0); objdata.Material = 4; objdata.TextureAnim = new byte[0]; objdata.Sound = LLUUID.Zero; LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005")); objdata.TextureEntry = ntex.ToBytes(); objdata.State = 0; objdata.Data = new byte[0]; objdata.ObjectData = new byte[76]; objdata.ObjectData[15] = 128; objdata.ObjectData[16] = 63; objdata.ObjectData[56] = 128; objdata.ObjectData[61] = 102; objdata.ObjectData[62] = 40; objdata.ObjectData[63] = 61; objdata.ObjectData[64] = 189; }
public void CreateFromStorage(PrimData store, LLVector3 posi, uint localID, bool newprim) { //need to clean this up as it shares a lot of code with CreateFromPacket() ObjectUpdatePacket objupdate = new ObjectUpdatePacket(); objupdate.RegionData.RegionHandle = m_regionHandle; objupdate.RegionData.TimeDilation = 64096; objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; this.primData = store; objupdate.ObjectData[0] = new ObjectUpdatePacket.ObjectDataBlock(); objupdate.ObjectData[0].PSBlock = new byte[0]; objupdate.ObjectData[0].ExtraParams = new byte[1]; objupdate.ObjectData[0].MediaURL = new byte[0]; objupdate.ObjectData[0].NameValue = new byte[0]; objupdate.ObjectData[0].Text = new byte[0]; objupdate.ObjectData[0].TextColor = new byte[4]; objupdate.ObjectData[0].JointAxisOrAnchor = new LLVector3(0, 0, 0); objupdate.ObjectData[0].JointPivot = new LLVector3(0, 0, 0); objupdate.ObjectData[0].Material = 3; objupdate.ObjectData[0].UpdateFlags = 32 + 65536 + 131072 + 256 + 4 + 8 + 2048 + 524288 + 268435456; objupdate.ObjectData[0].TextureAnim = new byte[0]; objupdate.ObjectData[0].Sound = LLUUID.Zero; if (store.Texture == null) { LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005")); objupdate.ObjectData[0].TextureEntry = ntex.ToBytes(); } else { objupdate.ObjectData[0].TextureEntry = store.Texture; } objupdate.ObjectData[0].State = 0; objupdate.ObjectData[0].Data = new byte[0]; objupdate.ObjectData[0].OwnerID = this.primData.OwnerID; objupdate.ObjectData[0].PCode = this.primData.PCode; objupdate.ObjectData[0].PathBegin = this.primData.PathBegin; objupdate.ObjectData[0].PathEnd = this.primData.PathEnd; objupdate.ObjectData[0].PathScaleX = this.primData.PathScaleX; objupdate.ObjectData[0].PathScaleY = this.primData.PathScaleY; objupdate.ObjectData[0].PathShearX = this.primData.PathShearX; objupdate.ObjectData[0].PathShearY = this.primData.PathShearY; objupdate.ObjectData[0].PathSkew = this.primData.PathSkew; objupdate.ObjectData[0].ProfileBegin = this.primData.ProfileBegin; objupdate.ObjectData[0].ProfileEnd = this.primData.ProfileEnd; objupdate.ObjectData[0].Scale = this.primData.Scale; objupdate.ObjectData[0].PathCurve = this.primData.PathCurve; objupdate.ObjectData[0].ProfileCurve = this.primData.ProfileCurve; objupdate.ObjectData[0].ParentID = 0; objupdate.ObjectData[0].ProfileHollow = this.primData.ProfileHollow; //finish off copying rest of shape data objupdate.ObjectData[0].PathRadiusOffset = this.primData.PathRadiusOffset; objupdate.ObjectData[0].PathRevolutions = this.primData.PathRevolutions; objupdate.ObjectData[0].PathTaperX = this.primData.PathTaperX; objupdate.ObjectData[0].PathTaperY = this.primData.PathTaperY; objupdate.ObjectData[0].PathTwist = this.primData.PathTwist; objupdate.ObjectData[0].PathTwistBegin = this.primData.PathTwistBegin; objupdate.ObjectData[0].ID = localID; // (uint)store.LocalID; objupdate.ObjectData[0].FullID = store.FullID; objupdate.ObjectData[0].ObjectData = new byte[60]; objupdate.ObjectData[0].ObjectData[46] = 128; objupdate.ObjectData[0].ObjectData[47] = 63; LLVector3 pos1 = posi; // store.Position; //update position byte[] pb = pos1.GetBytes(); Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 0, pb.Length); this.uuid = objupdate.ObjectData[0].FullID; this.localid = objupdate.ObjectData[0].ID; this.Pos = pos1; this.OurPacket = objupdate; if (newprim) { this.newPrimFlag = true; } }
/// <summary> /// Return a packet to the packet pool /// </summary> /// <param name="packet"></param> public void ReturnPacket(Packet packet) { if (RecycleDataBlocks) { switch (packet.Type) { case PacketType.ObjectUpdate: ObjectUpdatePacket oup = (ObjectUpdatePacket)packet; foreach (ObjectUpdatePacket.ObjectDataBlock oupod in oup.ObjectData) { ReturnDataBlock <ObjectUpdatePacket.ObjectDataBlock>(oupod); } oup.ObjectData = null; break; case PacketType.ImprovedTerseObjectUpdate: ImprovedTerseObjectUpdatePacket itoup = (ImprovedTerseObjectUpdatePacket)packet; foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock itoupod in itoup.ObjectData) { ReturnDataBlock <ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(itoupod); } itoup.ObjectData = null; break; } } if (RecyclePackets) { switch (packet.Type) { // List pooling packets here case PacketType.AgentUpdate: case PacketType.PacketAck: case PacketType.ObjectUpdate: case PacketType.ImprovedTerseObjectUpdate: lock (pool) { PacketType type = packet.Type; if (!pool.ContainsKey(type)) { pool[type] = new Stack <Packet>(); } if ((pool[type]).Count < 50) { // m_log.DebugFormat("[PACKETPOOL]: Pushing {0} packet", type); pool[type].Push(packet); } } break; // Other packets wont pool default: return; } } }
protected void FireOnObjectDataBlockUpdate(Simulator simulator, Primitive primitive, Primitive.ConstructionData data, ObjectUpdatePacket.ObjectDataBlock block, ObjectUpdate objectupdate, NameValue[] nameValue) { if (OnObjectDataBlockUpdate != null) { try { OnObjectDataBlockUpdate(simulator, primitive, data, block, objectupdate, nameValue); } catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } } }
public void CreateFromPacket(ObjectAddPacket addPacket, LLUUID agentID, uint localID) { ObjectUpdatePacket objupdate = new ObjectUpdatePacket(); objupdate.RegionData.RegionHandle = m_regionHandle; objupdate.RegionData.TimeDilation = 64096; objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; PrimData PData = new PrimData(); this.primData = PData; this.primData.CreationDate = (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; objupdate.ObjectData[0] = new ObjectUpdatePacket.ObjectDataBlock(); objupdate.ObjectData[0].PSBlock = new byte[0]; objupdate.ObjectData[0].ExtraParams = new byte[1]; objupdate.ObjectData[0].MediaURL = new byte[0]; objupdate.ObjectData[0].NameValue = new byte[0]; objupdate.ObjectData[0].Text = new byte[0]; objupdate.ObjectData[0].TextColor = new byte[4]; objupdate.ObjectData[0].JointAxisOrAnchor = new LLVector3(0, 0, 0); objupdate.ObjectData[0].JointPivot = new LLVector3(0, 0, 0); objupdate.ObjectData[0].Material = 3; objupdate.ObjectData[0].UpdateFlags = 32 + 65536 + 131072 + 256 + 4 + 8 + 2048 + 524288 + 268435456; objupdate.ObjectData[0].TextureAnim = new byte[0]; objupdate.ObjectData[0].Sound = LLUUID.Zero; LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005")); this.primData.Texture = objupdate.ObjectData[0].TextureEntry = ntex.ToBytes(); objupdate.ObjectData[0].State = 0; objupdate.ObjectData[0].Data = new byte[0]; PData.OwnerID = objupdate.ObjectData[0].OwnerID = agentID; PData.PCode = objupdate.ObjectData[0].PCode = addPacket.ObjectData.PCode; PData.PathBegin = objupdate.ObjectData[0].PathBegin = addPacket.ObjectData.PathBegin; PData.PathEnd = objupdate.ObjectData[0].PathEnd = addPacket.ObjectData.PathEnd; PData.PathScaleX = objupdate.ObjectData[0].PathScaleX = addPacket.ObjectData.PathScaleX; PData.PathScaleY = objupdate.ObjectData[0].PathScaleY = addPacket.ObjectData.PathScaleY; PData.PathShearX = objupdate.ObjectData[0].PathShearX = addPacket.ObjectData.PathShearX; PData.PathShearY = objupdate.ObjectData[0].PathShearY = addPacket.ObjectData.PathShearY; PData.PathSkew = objupdate.ObjectData[0].PathSkew = addPacket.ObjectData.PathSkew; PData.ProfileBegin = objupdate.ObjectData[0].ProfileBegin = addPacket.ObjectData.ProfileBegin; PData.ProfileEnd = objupdate.ObjectData[0].ProfileEnd = addPacket.ObjectData.ProfileEnd; PData.Scale = objupdate.ObjectData[0].Scale = addPacket.ObjectData.Scale; PData.PathCurve = objupdate.ObjectData[0].PathCurve = addPacket.ObjectData.PathCurve; PData.ProfileCurve = objupdate.ObjectData[0].ProfileCurve = addPacket.ObjectData.ProfileCurve; PData.ParentID = objupdate.ObjectData[0].ParentID = 0; PData.ProfileHollow = objupdate.ObjectData[0].ProfileHollow = addPacket.ObjectData.ProfileHollow; PData.PathRadiusOffset = objupdate.ObjectData[0].PathRadiusOffset = addPacket.ObjectData.PathRadiusOffset; PData.PathRevolutions = objupdate.ObjectData[0].PathRevolutions = addPacket.ObjectData.PathRevolutions; PData.PathTaperX = objupdate.ObjectData[0].PathTaperX = addPacket.ObjectData.PathTaperX; PData.PathTaperY = objupdate.ObjectData[0].PathTaperY = addPacket.ObjectData.PathTaperY; PData.PathTwist = objupdate.ObjectData[0].PathTwist = addPacket.ObjectData.PathTwist; PData.PathTwistBegin = objupdate.ObjectData[0].PathTwistBegin = addPacket.ObjectData.PathTwistBegin; objupdate.ObjectData[0].ID = (uint)(localID); objupdate.ObjectData[0].FullID = new LLUUID("edba7151-5857-acc5-b30b-f01efef" + (localID - 702000).ToString("00000")); objupdate.ObjectData[0].ObjectData = new byte[60]; objupdate.ObjectData[0].ObjectData[46] = 128; objupdate.ObjectData[0].ObjectData[47] = 63; LLVector3 pos1 = addPacket.ObjectData.RayEnd; //update position byte[] pb = pos1.GetBytes(); Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 0, pb.Length); this.newPrimFlag = true; this.primData.FullID = this.uuid = objupdate.ObjectData[0].FullID; this.localid = objupdate.ObjectData[0].ID; this.primData.Position = this.Pos = pos1; this.OurPacket = objupdate; }
ObjectUpdatePacket BuildFullUpdate(Agent agent, LLObject obj, byte state, uint flags) { byte[] objectData = new byte[60]; int pos = 0; agent.Avatar.Position.GetBytes().CopyTo(objectData, pos); pos += 12; agent.Avatar.Velocity.GetBytes().CopyTo(objectData, pos); pos += 12; agent.Avatar.Acceleration.GetBytes().CopyTo(objectData, pos); pos += 12; agent.Avatar.Rotation.GetBytes().CopyTo(objectData, pos); pos += 12; agent.Avatar.AngularVelocity.GetBytes().CopyTo(objectData, pos); ObjectUpdatePacket update = new ObjectUpdatePacket(); update.RegionData.RegionHandle = Server.RegionHandle; update.RegionData.TimeDilation = Helpers.FloatToByte(1f, 0f, 1f); update.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; update.ObjectData[0] = new ObjectUpdatePacket.ObjectDataBlock(); update.ObjectData[0].ClickAction = (byte)0; update.ObjectData[0].CRC = 0; update.ObjectData[0].ExtraParams = new byte[0]; update.ObjectData[0].Flags = 0; update.ObjectData[0].FullID = obj.ID; update.ObjectData[0].Gain = 0; update.ObjectData[0].ID = obj.LocalID; update.ObjectData[0].JointAxisOrAnchor = Vector3.Zero; update.ObjectData[0].JointPivot = Vector3.Zero; update.ObjectData[0].JointType = (byte)0; update.ObjectData[0].Material = (byte)3; update.ObjectData[0].MediaURL = new byte[0]; update.ObjectData[0].NameValue = Utils.StringToBytes(NameValue.NameValuesToString(agent.Avatar.NameValues)); update.ObjectData[0].ObjectData = objectData; update.ObjectData[0].OwnerID = UUID.Zero; update.ObjectData[0].ParentID = 0; update.ObjectData[0].PathBegin = 0; update.ObjectData[0].PathCurve = (byte)32; update.ObjectData[0].PathEnd = 0; update.ObjectData[0].PathRadiusOffset = (sbyte)0; update.ObjectData[0].PathRevolutions = (byte)0; update.ObjectData[0].PathScaleX = (byte)100; update.ObjectData[0].PathScaleY = (byte)150; update.ObjectData[0].PathShearX = (byte)0; update.ObjectData[0].PathShearY = (byte)0; update.ObjectData[0].PathSkew = (sbyte)0; update.ObjectData[0].PathTaperX = (sbyte)0; update.ObjectData[0].PathTaperY = (sbyte)0; update.ObjectData[0].PathTwist = (sbyte)0; update.ObjectData[0].PathTwistBegin = (sbyte)0; update.ObjectData[0].PCode = (byte)PCode.Avatar; update.ObjectData[0].ProfileBegin = 0; update.ObjectData[0].ProfileCurve = (byte)0; update.ObjectData[0].ProfileEnd = 0; update.ObjectData[0].ProfileHollow = 0; update.ObjectData[0].PSBlock = new byte[0]; update.ObjectData[0].TextColor = Vector3.Zero.GetBytes(); update.ObjectData[0].TextureAnim = new byte[0]; update.ObjectData[0].TextureEntry = new byte[63]; update.ObjectData[0].Radius = 0f; update.ObjectData[0].Scale = obj.Scale; update.ObjectData[0].Sound = UUID.Zero; update.ObjectData[0].State = state; update.ObjectData[0].Text = new byte[0]; update.ObjectData[0].UpdateFlags = flags; update.ObjectData[0].Data = new byte[0]; return update; }
public ObjectDataBlockUpdateEventArgs(Simulator simulator, Primitive prim, Primitive.ConstructionData constructionData, ObjectUpdatePacket.ObjectDataBlock block, ObjectMovementUpdate objectupdate, NameValue[] nameValues) { this.m_Simulator = simulator; this.m_Prim = prim; this.m_ConstructionData = constructionData; this.m_Block = block; this.m_Update = objectupdate; this.m_NameValues = nameValues; }
private void SendEntityPackets(QueuedInterestListEvent[] eventDatas, IScenePresence presence) { if (!(presence is LLAgent) || presence.InterestList == null) return; LLAgent agent = (LLAgent)presence; Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>(); Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); Lazy<List<ObjectUpdateCachedPacket.ObjectDataBlock>> cachedUpdateBlocks = new Lazy<List<ObjectUpdateCachedPacket.ObjectDataBlock>>(); for (int i = 0; i < eventDatas.Length; i++) { EntityAddOrUpdateArgs e = (EntityAddOrUpdateArgs)eventDatas[i].Event.State; ISceneEntity entity = e.Entity; #region Determine packet type UpdateFlags updateFlags = e.UpdateFlags; LLUpdateFlags llUpdateFlags = (LLUpdateFlags)e.ExtraFlags; LLPrimitive prim = entity as LLPrimitive; bool canUseCached = false; bool canUseTerse = true; DateTime lastSeen; if (CACHE_CHECK_ENABLED && prim != null && updateFlags.HasFlag(UpdateFlags.FullUpdate) && !llUpdateFlags.HasFlag(LLUpdateFlags.NoCachedUpdate) && m_recentAvatars.TryGetValue(presence.ID, out lastSeen) && lastSeen > prim.LastUpdated) { // This avatar was marked as leaving the same later than the last update // timestamp of this prim. Send a cache check canUseCached = true; } else if (updateFlags.HasFlag(UpdateFlags.FullUpdate) || updateFlags.HasFlag(UpdateFlags.Parent) || updateFlags.HasFlag(UpdateFlags.Scale) || updateFlags.HasFlag(UpdateFlags.Shape) || llUpdateFlags.HasFlag(LLUpdateFlags.PrimFlags) || llUpdateFlags.HasFlag(LLUpdateFlags.Text) || llUpdateFlags.HasFlag(LLUpdateFlags.NameValue) || llUpdateFlags.HasFlag(LLUpdateFlags.ExtraData) || llUpdateFlags.HasFlag(LLUpdateFlags.TextureAnim) || llUpdateFlags.HasFlag(LLUpdateFlags.Sound) || llUpdateFlags.HasFlag(LLUpdateFlags.Particles) || llUpdateFlags.HasFlag(LLUpdateFlags.Material) || llUpdateFlags.HasFlag(LLUpdateFlags.ClickAction) || llUpdateFlags.HasFlag(LLUpdateFlags.MediaURL) || llUpdateFlags.HasFlag(LLUpdateFlags.Joint)) { canUseTerse = false; } #endregion Determine packet type #region Block Construction if (canUseCached && prim != null) { cachedUpdateBlocks.Value.Add(new ObjectUpdateCachedPacket.ObjectDataBlock { CRC = prim.GetCrc(), ID = prim.LocalID }); } else if (!canUseTerse) { if (entity is IScenePresence) { IScenePresence thisPresence = (IScenePresence)entity; ObjectUpdatePacket.ObjectDataBlock block = CreateAvatarObjectUpdateBlock(thisPresence); block.UpdateFlags = (uint)GetUpdateFlags(thisPresence, presence); objectUpdateBlocks.Value.Add(block); } else if (prim != null) { ObjectUpdateCompressedPacket.ObjectDataBlock block = CreateCompressedObjectUpdateBlock(prim, prim.GetCrc()); block.UpdateFlags = (uint)GetUpdateFlags(prim, presence, m_permissions); compressedUpdateBlocks.Value.Add(block); // ObjectUpdateCompressed doesn't carry velocity or acceleration fields, so // we need to send a separate terse packet if this prim has a non-zero // velocity or acceleration if (prim.Velocity != Vector3.Zero || prim.Acceleration != Vector3.Zero) terseUpdateBlocks.Value.Add(CreateTerseUpdateBlock(entity, false)); //ObjectUpdatePacket.ObjectDataBlock block = CreateObjectUpdateBlock(prim); //block.UpdateFlags = (uint)GetUpdateFlags(prim, presence, m_permissions); //block.CRC = prim.GetCrc(); //objectUpdateBlocks.Value.Add(block); } else { // TODO: Create a generic representation for non-LLPrimitive entities? continue; } } else { terseUpdateBlocks.Value.Add(CreateTerseUpdateBlock(entity, llUpdateFlags.HasFlag(LLUpdateFlags.Textures))); } #endregion Block Construction // Unset CreateSelected after it has been sent once if (prim != null) prim.Prim.Flags &= ~PrimFlags.CreateSelected; } #region Packet Sending ushort timeDilation = (m_physics != null) ? Utils.FloatToUInt16(m_physics.TimeDilation, 0.0f, 1.0f) : UInt16.MaxValue; if (objectUpdateBlocks.IsValueCreated) { List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; ObjectUpdatePacket packet = new ObjectUpdatePacket(); packet.RegionData.RegionHandle = Util.PositionToRegionHandle(m_scene.MinPosition); packet.RegionData.TimeDilation = timeDilation; packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; for (int i = 0; i < blocks.Count; i++) packet.ObjectData[i] = blocks[i]; m_udp.SendPacket(agent, packet, ThrottleCategory.Task, true); } if (compressedUpdateBlocks.IsValueCreated) { List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; ObjectUpdateCompressedPacket packet = new ObjectUpdateCompressedPacket(); packet.RegionData.RegionHandle = Util.PositionToRegionHandle(m_scene.MinPosition); packet.RegionData.TimeDilation = timeDilation; packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count]; for (int i = 0; i < blocks.Count; i++) packet.ObjectData[i] = blocks[i]; m_udp.SendPacket(agent, packet, ThrottleCategory.Task, true); } if (terseUpdateBlocks.IsValueCreated) { List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); packet.RegionData.RegionHandle = Util.PositionToRegionHandle(m_scene.MinPosition); packet.RegionData.TimeDilation = timeDilation; packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; for (int i = 0; i < blocks.Count; i++) packet.ObjectData[i] = blocks[i]; m_udp.SendPacket(agent, packet, ThrottleCategory.Task, true); } if (cachedUpdateBlocks.IsValueCreated) { List<ObjectUpdateCachedPacket.ObjectDataBlock> blocks = cachedUpdateBlocks.Value; ObjectUpdateCachedPacket packet = new ObjectUpdateCachedPacket(); packet.RegionData.RegionHandle = Util.PositionToRegionHandle(m_scene.MinPosition); packet.RegionData.TimeDilation = timeDilation; packet.ObjectData = new ObjectUpdateCachedPacket.ObjectDataBlock[blocks.Count]; for (int i = 0; i < blocks.Count; i++) packet.ObjectData[i] = blocks[i]; m_udp.SendPacket(agent, packet, ThrottleCategory.Task, true); } #endregion Packet Sending }