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 static ObjectUpdatePacket.ObjectDataBlock BuildUpdateBlock(Primitive obj, ulong regionHandle, byte state, PrimFlags flags) { byte[] objectData = BuildObjectData(obj.Position, obj.Rotation, obj.Velocity, obj.Acceleration, obj.AngularVelocity); ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); update.ClickAction = (byte)obj.ClickAction; update.CRC = 0; update.ExtraParams = new byte[0]; //FIXME: Need a serializer for ExtraParams update.Flags = (byte)flags; update.FullID = obj.ID; update.Gain = obj.SoundGain; update.ID = obj.LocalID; update.JointAxisOrAnchor = obj.JointAxisOrAnchor; update.JointPivot = obj.JointPivot; update.JointType = (byte)obj.Joint; update.Material = (byte)obj.PrimData.Material; update.MediaURL = Utils.StringToBytes(obj.MediaURL); update.NameValue = Utils.StringToBytes(NameValue.NameValuesToString(obj.NameValues)); update.ObjectData = objectData; update.OwnerID = obj.Properties.OwnerID; update.ParentID = obj.ParentID; update.PathBegin = Primitive.PackBeginCut(obj.PrimData.PathBegin); update.PathCurve = (byte)obj.PrimData.PathCurve; update.PathEnd = Primitive.PackEndCut(obj.PrimData.PathEnd); update.PathRadiusOffset = Primitive.PackPathTwist(obj.PrimData.PathRadiusOffset); update.PathRevolutions = Primitive.PackPathRevolutions(obj.PrimData.PathRevolutions); update.PathScaleX = Primitive.PackPathScale(obj.PrimData.PathScaleX); update.PathScaleY = Primitive.PackPathScale(obj.PrimData.PathScaleY); update.PathShearX = (byte)Primitive.PackPathShear(obj.PrimData.PathShearX); update.PathShearY = (byte)Primitive.PackPathShear(obj.PrimData.PathShearY); update.PathSkew = Primitive.PackPathTwist(obj.PrimData.PathSkew); update.PathTaperX = Primitive.PackPathTaper(obj.PrimData.PathTaperX); update.PathTaperY = Primitive.PackPathTaper(obj.PrimData.PathTaperY); update.PathTwist = Primitive.PackPathTwist(obj.PrimData.PathTwist); update.PathTwistBegin = Primitive.PackPathTwist(obj.PrimData.PathTwistBegin); update.PCode = (byte)obj.PrimData.PCode; update.ProfileBegin = Primitive.PackBeginCut(obj.PrimData.ProfileBegin); update.ProfileCurve = (byte)obj.PrimData.ProfileCurve; update.ProfileEnd = Primitive.PackEndCut(obj.PrimData.ProfileEnd); update.ProfileHollow = Primitive.PackProfileHollow(obj.PrimData.ProfileHollow); update.PSBlock = new byte[0]; // FIXME: update.TextColor = obj.TextColor.GetBytes(true); update.TextureAnim = obj.TextureAnim.GetBytes(); update.TextureEntry = obj.Textures == null ? new byte[0] : obj.Textures.ToBytes(); update.Radius = obj.SoundRadius; update.Scale = obj.Scale; update.Sound = obj.Sound; update.State = state; update.Text = Utils.StringToBytes(obj.Text); update.UpdateFlags = (uint)flags; update.Data = new byte[0]; // FIXME: return(update); }
public static ObjectUpdatePacket.ObjectDataBlock BuildUpdateBlock(Primitive obj, ulong regionHandle, PrimFlags flags) { byte[] objectData = BuildObjectData(obj.Position, obj.Rotation, obj.Velocity, obj.Acceleration, obj.AngularVelocity); ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); update.ClickAction = (byte)obj.ClickAction; update.CRC = 0; update.ExtraParams = obj.GetExtraParamsBytes(); update.Flags = (byte)flags; update.FullID = obj.ID; update.Gain = obj.SoundGain; update.ID = obj.LocalID; update.JointAxisOrAnchor = obj.JointAxisOrAnchor; update.JointPivot = obj.JointPivot; update.JointType = (byte)obj.Joint; update.Material = (byte)obj.PrimData.Material; update.MediaURL = Utils.StringToBytes(obj.MediaURL); update.NameValue = Utils.StringToBytes(NameValue.NameValuesToString(obj.NameValues)); update.ObjectData = objectData; update.OwnerID = (obj.Properties != null ? obj.Properties.OwnerID : UUID.Zero); update.ParentID = obj.ParentID; update.PathBegin = Primitive.PackBeginCut(obj.PrimData.PathBegin); update.PathCurve = (byte)obj.PrimData.PathCurve; update.PathEnd = Primitive.PackEndCut(obj.PrimData.PathEnd); update.PathRadiusOffset = Primitive.PackPathTwist(obj.PrimData.PathRadiusOffset); update.PathRevolutions = Primitive.PackPathRevolutions(obj.PrimData.PathRevolutions); update.PathScaleX = Primitive.PackPathScale(obj.PrimData.PathScaleX); update.PathScaleY = Primitive.PackPathScale(obj.PrimData.PathScaleY); update.PathShearX = (byte)Primitive.PackPathShear(obj.PrimData.PathShearX); update.PathShearY = (byte)Primitive.PackPathShear(obj.PrimData.PathShearY); update.PathSkew = Primitive.PackPathTwist(obj.PrimData.PathSkew); update.PathTaperX = Primitive.PackPathTaper(obj.PrimData.PathTaperX); update.PathTaperY = Primitive.PackPathTaper(obj.PrimData.PathTaperY); update.PathTwist = Primitive.PackPathTwist(obj.PrimData.PathTwist); update.PathTwistBegin = Primitive.PackPathTwist(obj.PrimData.PathTwistBegin); update.PCode = (byte)obj.PrimData.PCode; update.ProfileBegin = Primitive.PackBeginCut(obj.PrimData.ProfileBegin); update.ProfileCurve = (byte)obj.PrimData.ProfileCurve; update.ProfileEnd = Primitive.PackEndCut(obj.PrimData.ProfileEnd); update.ProfileHollow = Primitive.PackProfileHollow(obj.PrimData.ProfileHollow); update.PSBlock = obj.ParticleSys.GetBytes(); update.TextColor = obj.TextColor.GetBytes(true); update.TextureAnim = obj.TextureAnim.GetBytes(); update.TextureEntry = obj.Textures == null ? new byte[0] : obj.Textures.ToBytes(); update.Radius = obj.SoundRadius; update.Scale = obj.Scale; update.Sound = obj.Sound; update.State = obj.PrimData.State; update.Text = Utils.StringToBytes(obj.Text); update.UpdateFlags = (uint)flags; update.Data = obj.GenericData == null ? new byte[0] : obj.GenericData; return update; }
public static void SetupTemplate(string name) { FileInfo fInfo = new FileInfo(name); long numBytes = fInfo.Length; FileStream fStream = new FileStream(name, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fStream); byte[] data1 = br.ReadBytes((int)numBytes); br.Close(); fStream.Close(); libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock objdata = new ObjectUpdatePacket.ObjectDataBlock(); // new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i); SetDefaultPacketValues(objdata); objdata.TextureEntry = data1; objdata.UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24); objdata.PathCurve = 16; objdata.ProfileCurve = 1; objdata.PathScaleX = 100; objdata.PathScaleY = 100; objdata.ParentID = 0; objdata.OwnerID = LLUUID.Zero; objdata.Scale = new LLVector3(1, 1, 1); objdata.PCode = 47; System.Text.Encoding enc = System.Text.Encoding.ASCII; libsecondlife.LLVector3 pos = new LLVector3(objdata.ObjectData, 16); pos.X = 100f; objdata.ID = 8880000; objdata.NameValue = enc.GetBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User \0"); libsecondlife.LLVector3 pos2 = new LLVector3(100f, 100f, 23f); //objdata.FullID=user.AgentID; byte[] pb = pos.GetBytes(); Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length); Avatar.AvatarTemplate = objdata; }
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 ObjectUpdatePacket.ObjectDataBlock CreateObjectUpdateBlock(ISceneEntity entity, IScenePresence sendingTo) { Primitive prim; if (entity.RelativeRotation == INVALID_ROT) { m_log.Warn("Correcting an invalid rotation for " + entity.Name + " (" + entity.ID + ")"); entity.RelativeRotation = Quaternion.Identity; } #region LLPrimitive / Generic Support if (entity is LLPrimitive) { prim = ((LLPrimitive)entity).Prim; } else { prim = m_proxyPrim; prim.Position = entity.RelativePosition; prim.Rotation = entity.RelativeRotation; prim.Scale = entity.Scale; if (entity is ILinkable) { ILinkable parent = ((ILinkable)entity).Parent; if (parent != null) prim.ParentID = parent.LocalID; } if (entity is IPhysical) { IPhysical physical = (IPhysical)entity; prim.Velocity = physical.Velocity; prim.Acceleration = physical.Acceleration; prim.AngularVelocity = physical.AngularVelocity; } } #endregion LLPrimitive / Generic Support #region ObjectData byte[] objectData = new byte[60]; prim.Position.ToBytes(objectData, 0); prim.Velocity.ToBytes(objectData, 12); prim.Acceleration.ToBytes(objectData, 24); prim.Rotation.ToBytes(objectData, 36); prim.AngularVelocity.ToBytes(objectData, 48); #endregion ObjectData #region UpdateFlags PrimFlags flags; if (entity is LLPrimitive) { flags = m_permissions.GetFlagsFor(sendingTo, (LLPrimitive)entity); } else { flags = PrimFlags.CastShadows | PrimFlags.ObjectCopy | PrimFlags.ObjectTransfer | PrimFlags.ObjectYouOwner | PrimFlags.ObjectModify | PrimFlags.ObjectMove | PrimFlags.ObjectOwnerModify; } #endregion UpdateFlags #region Shape & Misc ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); update.ClickAction = (byte)prim.ClickAction; update.CRC = 0; update.ExtraParams = prim.GetExtraParamsBytes(); update.FullID = prim.ID; update.Gain = prim.SoundGain; update.ID = prim.LocalID; update.JointAxisOrAnchor = prim.JointAxisOrAnchor; update.JointPivot = prim.JointPivot; update.JointType = (byte)prim.Joint; update.Material = (byte)prim.PrimData.Material; update.MediaURL = (!String.IsNullOrEmpty(prim.MediaVersion)) ? Utils.StringToBytes(prim.MediaVersion) : Utils.StringToBytes(prim.MediaURL); update.ObjectData = objectData; update.OwnerID = (prim.Properties != null ? prim.Properties.OwnerID : UUID.Zero); update.ParentID = prim.ParentID; update.PathBegin = Primitive.PackBeginCut(prim.PrimData.PathBegin); update.PathCurve = (byte)prim.PrimData.PathCurve; update.PathEnd = Primitive.PackEndCut(prim.PrimData.PathEnd); update.PathRadiusOffset = Primitive.PackPathTwist(prim.PrimData.PathRadiusOffset); update.PathRevolutions = Primitive.PackPathRevolutions(prim.PrimData.PathRevolutions); update.PathScaleX = Primitive.PackPathScale(prim.PrimData.PathScaleX); update.PathScaleY = Primitive.PackPathScale(prim.PrimData.PathScaleY); update.PathShearX = (byte)Primitive.PackPathShear(prim.PrimData.PathShearX); update.PathShearY = (byte)Primitive.PackPathShear(prim.PrimData.PathShearY); update.PathSkew = Primitive.PackPathTwist(prim.PrimData.PathSkew); update.PathTaperX = Primitive.PackPathTaper(prim.PrimData.PathTaperX); update.PathTaperY = Primitive.PackPathTaper(prim.PrimData.PathTaperY); update.PathTwist = Primitive.PackPathTwist(prim.PrimData.PathTwist); update.PathTwistBegin = Primitive.PackPathTwist(prim.PrimData.PathTwistBegin); update.PCode = (byte)prim.PrimData.PCode; update.ProfileBegin = Primitive.PackBeginCut(prim.PrimData.ProfileBegin); update.ProfileCurve = (byte)prim.PrimData.ProfileCurve; update.ProfileEnd = Primitive.PackEndCut(prim.PrimData.ProfileEnd); update.ProfileHollow = Primitive.PackProfileHollow(prim.PrimData.ProfileHollow); update.PSBlock = prim.ParticleSys.GetBytes(); update.TextColor = prim.TextColor.GetBytes(true); update.TextureAnim = prim.TextureAnim.GetBytes(); update.TextureEntry = prim.Textures == null ? Utils.EmptyBytes : prim.Textures.GetBytes(); update.Radius = prim.SoundRadius; update.Scale = prim.Scale; update.State = prim.PrimData.State; update.Text = Utils.StringToBytes(prim.Text); update.UpdateFlags = (uint)flags; if (prim.PrimData.AttachmentPoint != AttachmentPoint.Default) update.NameValue = Utils.StringToBytes("AttachItemID STRING RW SV " + prim.Properties.ItemID); else update.NameValue = Utils.EmptyBytes; #endregion Shape & Misc if (update.PCode == 0) m_log.Warn("Sending ObjectUpdate with a PCode of 0 for entity " + entity.ID); #region Sound-Specific if (prim.Sound != UUID.Zero) { update.Sound = prim.Sound; update.OwnerID = prim.OwnerID; update.Gain = prim.SoundGain; update.Radius = prim.SoundRadius; update.Flags = (byte)prim.SoundFlags; } #endregion Sound-Specific #region PCode-Specific switch (prim.PrimData.PCode) { case PCode.Grass: case PCode.Tree: case PCode.NewTree: update.Data = new byte[1]; update.Data[0] = (byte)prim.TreeSpecies; break; default: if (prim.ScratchPad != null) { update.Data = new byte[prim.ScratchPad.Length]; Buffer.BlockCopy(prim.ScratchPad, 0, update.Data, 0, update.Data.Length); } else { update.Data = new byte[0]; } break; } #endregion PCode-Specific return update; }
private ObjectUpdatePacket.ObjectDataBlock CreateAvatarObjectUpdateBlock(IScenePresence presence, IScenePresence sendingTo) { byte[] objectData = new byte[76]; Vector4 collisionPlane = (presence is IPhysicalPresence) ? ((IPhysicalPresence)presence).CollisionPlane : Vector4.UnitW; if (collisionPlane == Vector4.Zero) collisionPlane = Vector4.UnitW; if (presence.RelativeRotation == INVALID_ROT) { m_log.Warn("Correcting an invalid rotation for " + presence.Name + " (" + presence.ID + ")"); presence.RelativeRotation = Quaternion.Identity; } collisionPlane.ToBytes(objectData, 0); presence.RelativePosition.ToBytes(objectData, 16); //data.Velocity.ToBytes(objectData, 28); //data.Acceleration.ToBytes(objectData, 40); presence.RelativeRotation.ToBytes(objectData, 52); //data.AngularVelocity.ToBytes(objectData, 64); string firstName, lastName; Util.GetFirstLastName(presence.Name, out firstName, out lastName); ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); update.Data = Utils.EmptyBytes; update.ExtraParams = new byte[1]; update.FullID = presence.ID; update.ID = presence.LocalID; update.Material = (byte)Material.Flesh; update.MediaURL = Utils.EmptyBytes; update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + firstName + "\nLastName STRING RW SV " + lastName + "\nTitle STRING RW SV " + String.Empty); // TODO: Support group title update.ObjectData = objectData; if (presence is ILinkable) { ILinkable linkable = (ILinkable)presence; if (linkable.Parent != null) update.ParentID = linkable.Parent.LocalID; } update.PathCurve = 16; update.PathScaleX = 100; update.PathScaleY = 100; update.PCode = (byte)PCode.Avatar; update.ProfileCurve = 1; update.PSBlock = Utils.EmptyBytes; update.Scale = presence.Scale; update.Text = Utils.EmptyBytes; update.TextColor = new byte[4]; update.TextureAnim = Utils.EmptyBytes; update.TextureEntry = Utils.EmptyBytes; // TODO: TextureEntry support update.UpdateFlags = (uint)(PrimFlags.CastShadows | PrimFlags.InventoryEmpty | PrimFlags.Money | PrimFlags.Physics); if (presence == sendingTo) update.UpdateFlags |= (uint)PrimFlags.ObjectYouOwner; return update; }
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); }
/// <summary> /// Used for new prims, or significant changes to existing prims (From OpenMetaverse, with edits) /// </summary> /// <param name="packet"></param> /// <param name="simulator"></param> private Packet UpdateHandler(Packet packet, IPEndPoint simulator) { ObjectUpdatePacket update = (ObjectUpdatePacket)packet; //UpdateDilation(simulator, update.RegionData.TimeDilation); for (int b = 0; b < update.ObjectData.Length; b++) { ObjectUpdatePacket.ObjectDataBlock block = update.ObjectData[b]; if (block.FullID == frame.AgentID) { Vector4 collisionPlane = Vector4.Zero; Vector3 position; Vector3 velocity; Vector3 acceleration; Quaternion rotation; Vector3 angularVelocity; //NameValue[] nameValues; //bool attachment = false; PCode pcode = (PCode)block.PCode; #region Decode Additional packed parameters in ObjectData int pos = 0; switch (block.ObjectData.Length) { case 76: // Collision normal for avatar collisionPlane = new Vector4(block.ObjectData, pos); pos += 16; goto case 60; case 60: // Position position = new Vector3(block.ObjectData, pos); pos += 12; // Velocity velocity = new Vector3(block.ObjectData, pos); pos += 12; // Acceleration acceleration = new Vector3(block.ObjectData, pos); pos += 12; // Rotation (theta) rotation = new Quaternion(block.ObjectData, pos, true); pos += 12; // Angular velocity (omega) angularVelocity = new Vector3(block.ObjectData, pos); pos += 12; break; case 48: // Collision normal for avatar collisionPlane = new Vector4(block.ObjectData, pos); pos += 16; goto case 32; case 32: // The data is an array of unsigned shorts // Position position = new Vector3( Utils.UInt16ToFloat(block.ObjectData, pos, -0.5f * 256.0f, 1.5f * 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 2, -0.5f * 256.0f, 1.5f * 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 3.0f * 256.0f)); pos += 6; // Velocity velocity = new Vector3( Utils.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f)); pos += 6; // Acceleration acceleration = new Vector3( Utils.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f)); pos += 6; // Rotation (theta) rotation = new Quaternion( Utils.UInt16ToFloat(block.ObjectData, pos, -1.0f, 1.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 2, -1.0f, 1.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 4, -1.0f, 1.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 6, -1.0f, 1.0f)); pos += 8; // Angular velocity (omega) angularVelocity = new Vector3( Utils.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f)); pos += 6; break; case 16: // The data is an array of single bytes (8-bit numbers) // Position position = new Vector3( Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); pos += 3; // Velocity velocity = new Vector3( Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); pos += 3; // Accleration acceleration = new Vector3( Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); pos += 3; // Rotation rotation = new Quaternion( Utils.ByteToFloat(block.ObjectData, pos, -1.0f, 1.0f), Utils.ByteToFloat(block.ObjectData, pos + 1, -1.0f, 1.0f), Utils.ByteToFloat(block.ObjectData, pos + 2, -1.0f, 1.0f), Utils.ByteToFloat(block.ObjectData, pos + 3, -1.0f, 1.0f)); pos += 4; // Angular Velocity angularVelocity = new Vector3( Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); pos += 3; break; default: //Logger.Log("Got an ObjectUpdate block with ObjectUpdate field length of " + //block.ObjectData.Length, Helpers.LogLevel.Warning, Client); continue; } #endregion mpos = position; //Console.WriteLine("mpos = " + mpos.ToString()); mid = block.ID; } } return(packet); }
public static ObjectUpdatePacket.ObjectDataBlock BuildUpdateBlock(Primitive prim, PrimFlags flags, uint crc) { byte[] objectData = new byte[60]; prim.Position.ToBytes(objectData, 0); prim.Velocity.ToBytes(objectData, 12); prim.Acceleration.ToBytes(objectData, 24); prim.Rotation.ToBytes(objectData, 36); prim.AngularVelocity.ToBytes(objectData, 48); ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); update.ClickAction = (byte)prim.ClickAction; update.CRC = crc; update.ExtraParams = prim.GetExtraParamsBytes(); update.Flags = (byte)flags; update.FullID = prim.ID; update.Gain = prim.SoundGain; update.ID = prim.LocalID; update.JointAxisOrAnchor = prim.JointAxisOrAnchor; update.JointPivot = prim.JointPivot; update.JointType = (byte)prim.Joint; update.Material = (byte)prim.PrimData.Material; update.MediaURL = Utils.StringToBytes(prim.MediaURL); update.NameValue = Utils.StringToBytes(NameValue.NameValuesToString(prim.NameValues)); update.ObjectData = objectData; update.OwnerID = (prim.Properties != null ? prim.Properties.OwnerID : UUID.Zero); update.ParentID = prim.ParentID; update.PathBegin = Primitive.PackBeginCut(prim.PrimData.PathBegin); update.PathCurve = (byte)prim.PrimData.PathCurve; update.PathEnd = Primitive.PackEndCut(prim.PrimData.PathEnd); update.PathRadiusOffset = Primitive.PackPathTwist(prim.PrimData.PathRadiusOffset); update.PathRevolutions = Primitive.PackPathRevolutions(prim.PrimData.PathRevolutions); update.PathScaleX = Primitive.PackPathScale(prim.PrimData.PathScaleX); update.PathScaleY = Primitive.PackPathScale(prim.PrimData.PathScaleY); update.PathShearX = (byte)Primitive.PackPathShear(prim.PrimData.PathShearX); update.PathShearY = (byte)Primitive.PackPathShear(prim.PrimData.PathShearY); update.PathSkew = Primitive.PackPathTwist(prim.PrimData.PathSkew); update.PathTaperX = Primitive.PackPathTaper(prim.PrimData.PathTaperX); update.PathTaperY = Primitive.PackPathTaper(prim.PrimData.PathTaperY); update.PathTwist = Primitive.PackPathTwist(prim.PrimData.PathTwist); update.PathTwistBegin = Primitive.PackPathTwist(prim.PrimData.PathTwistBegin); update.PCode = (byte)prim.PrimData.PCode; update.ProfileBegin = Primitive.PackBeginCut(prim.PrimData.ProfileBegin); update.ProfileCurve = (byte)prim.PrimData.ProfileCurve; update.ProfileEnd = Primitive.PackEndCut(prim.PrimData.ProfileEnd); update.ProfileHollow = Primitive.PackProfileHollow(prim.PrimData.ProfileHollow); update.PSBlock = prim.ParticleSys.GetBytes(); update.TextColor = prim.TextColor.GetBytes(true); update.TextureAnim = prim.TextureAnim.GetBytes(); update.TextureEntry = prim.Textures == null ? Utils.EmptyBytes : prim.Textures.GetBytes(); update.Radius = prim.SoundRadius; update.Scale = prim.Scale; update.Sound = prim.Sound; update.State = prim.PrimData.State; update.Text = Utils.StringToBytes(prim.Text); update.UpdateFlags = (uint)flags; switch (prim.PrimData.PCode) { case PCode.Grass: case PCode.Tree: case PCode.NewTree: update.Data = new byte[1]; update.Data[0] = (byte)prim.TreeSpecies; break; default: if (prim.ScratchPad != null) { update.Data = new byte[prim.ScratchPad.Length]; Buffer.BlockCopy(prim.ScratchPad, 0, update.Data, 0, update.Data.Length); } else { update.Data = new byte[0]; } break; } return update; }
public static void SetupTemplate(string name) { FileInfo fInfo = new FileInfo(name); long numBytes = fInfo.Length; FileStream fStream = new FileStream(name, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fStream); byte[] data1 = br.ReadBytes((int)numBytes); br.Close(); fStream.Close(); libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock objdata = new ObjectUpdatePacket.ObjectDataBlock(); // new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i); SetDefaultPacketValues(objdata); objdata.TextureEntry = data1; objdata.UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24); objdata.PathCurve = 16; objdata.ProfileCurve = 1; objdata.PathScaleX = 100; objdata.PathScaleY = 100; objdata.ParentID = 0; objdata.OwnerID = LLUUID.Zero; objdata.Scale = new LLVector3(1, 1, 1); objdata.PCode = 47; System.Text.Encoding enc = System.Text.Encoding.ASCII; libsecondlife.LLVector3 pos = new LLVector3(objdata.ObjectData, 16); pos.X = 100f; objdata.ID = 8880000; objdata.NameValue = enc.GetBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User \0"); libsecondlife.LLVector3 pos2 = new LLVector3(100f, 100f, 23f); //objdata.FullID=user.AgentID; byte[] pb = pos.GetBytes(); Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length); Avatar.AvatarTemplate = objdata; }
// Processes object update packets (Avatars and Objects entering drawing distance) private Packet ProcessObjectUpdate(Packet packet, IPEndPoint endpoint) { ObjectUpdatePacket update = (ObjectUpdatePacket)packet; for (int b = 0; b < update.ObjectData.Length; b++) { ObjectUpdatePacket.ObjectDataBlock block = update.ObjectData[b]; ObjectMovementUpdate objectupdate = new ObjectMovementUpdate(); NameValue[] nameValues; string firstname = ""; string lastname = ""; PCode pcode = (PCode)block.PCode; #region NameValue parsing string nameValue = Utils.BytesToString(block.NameValue); if (nameValue.Length > 0) { string[] lines = nameValue.Split('\n'); nameValues = new NameValue[lines.Length]; for (int i = 0; i < lines.Length; i++) { if (!String.IsNullOrEmpty(lines[i])) { NameValue nv = new NameValue(lines[i]); if (nv.Name == "FirstName") { firstname = nv.Value.ToString(); } if (nv.Name == "LastName") { lastname = nv.Value.ToString(); } nameValues[i] = nv; } } } else { nameValues = new NameValue[0]; } #endregion NameValue parsing #region Decode Object (primitive) parameters Primitive.ConstructionData data = new Primitive.ConstructionData(); data.State = block.State; data.Material = (Material)block.Material; data.PathCurve = (PathCurve)block.PathCurve; data.profileCurve = block.ProfileCurve; data.PathBegin = Primitive.UnpackBeginCut(block.PathBegin); data.PathEnd = Primitive.UnpackEndCut(block.PathEnd); data.PathScaleX = Primitive.UnpackPathScale(block.PathScaleX); data.PathScaleY = Primitive.UnpackPathScale(block.PathScaleY); data.PathShearX = Primitive.UnpackPathShear((sbyte)block.PathShearX); data.PathShearY = Primitive.UnpackPathShear((sbyte)block.PathShearY); data.PathTwist = Primitive.UnpackPathTwist(block.PathTwist); data.PathTwistBegin = Primitive.UnpackPathTwist(block.PathTwistBegin); data.PathRadiusOffset = Primitive.UnpackPathTwist(block.PathRadiusOffset); data.PathTaperX = Primitive.UnpackPathTaper(block.PathTaperX); data.PathTaperY = Primitive.UnpackPathTaper(block.PathTaperY); data.PathRevolutions = Primitive.UnpackPathRevolutions(block.PathRevolutions); data.PathSkew = Primitive.UnpackPathTwist(block.PathSkew); data.ProfileBegin = Primitive.UnpackBeginCut(block.ProfileBegin); data.ProfileEnd = Primitive.UnpackEndCut(block.ProfileEnd); data.ProfileHollow = Primitive.UnpackProfileHollow(block.ProfileHollow); data.PCode = pcode; #endregion #region Decode Additional packed parameters in ObjectData int pos = 0; switch (block.ObjectData.Length) { case 76: // Collision normal for avatar objectupdate.CollisionPlane = new Vector4(block.ObjectData, pos); pos += 16; goto case 60; case 60: // Position objectupdate.Position = new Vector3(block.ObjectData, pos); pos += 12; // Velocity objectupdate.Velocity = new Vector3(block.ObjectData, pos); pos += 12; // Acceleration objectupdate.Acceleration = new Vector3(block.ObjectData, pos); pos += 12; // Rotation (theta) objectupdate.Rotation = new Quaternion(block.ObjectData, pos, true); pos += 12; // Angular velocity (omega) objectupdate.AngularVelocity = new Vector3(block.ObjectData, pos); pos += 12; break; case 48: // Collision normal for avatar objectupdate.CollisionPlane = new Vector4(block.ObjectData, pos); pos += 16; goto case 32; case 32: // The data is an array of unsigned shorts // Position objectupdate.Position = new Vector3( Utils.UInt16ToFloat(block.ObjectData, pos, -0.5f * 256.0f, 1.5f * 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 2, -0.5f * 256.0f, 1.5f * 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 3.0f * 256.0f)); pos += 6; // Velocity objectupdate.Velocity = new Vector3( Utils.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f)); pos += 6; // Acceleration objectupdate.Acceleration = new Vector3( Utils.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f)); pos += 6; // Rotation (theta) objectupdate.Rotation = new Quaternion( Utils.UInt16ToFloat(block.ObjectData, pos, -1.0f, 1.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 2, -1.0f, 1.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 4, -1.0f, 1.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 6, -1.0f, 1.0f)); pos += 8; // Angular velocity (omega) objectupdate.AngularVelocity = new Vector3( Utils.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f)); pos += 6; break; case 16: // The data is an array of single bytes (8-bit numbers) // Position objectupdate.Position = new Vector3( Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); pos += 3; // Velocity objectupdate.Velocity = new Vector3( Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); pos += 3; // Accleration objectupdate.Acceleration = new Vector3( Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); pos += 3; // Rotation objectupdate.Rotation = new Quaternion( Utils.ByteToFloat(block.ObjectData, pos, -1.0f, 1.0f), Utils.ByteToFloat(block.ObjectData, pos + 1, -1.0f, 1.0f), Utils.ByteToFloat(block.ObjectData, pos + 2, -1.0f, 1.0f), Utils.ByteToFloat(block.ObjectData, pos + 3, -1.0f, 1.0f)); pos += 4; // Angular Velocity objectupdate.AngularVelocity = new Vector3( Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); pos += 3; break; default: SayToUser("ERROR: Got an ObjectUpdate block with ObjectUpdate field length of " + block.ObjectData.Length); continue; } #endregion // Determine the object type and create the appropriate class switch (pcode) { #region Prim and Foliage case PCode.Grass: case PCode.Tree: case PCode.NewTree: case PCode.Prim: break; #endregion Prim and Foliage #region Avatar case PCode.Avatar: if (block.FullID == this.frame.AgentID) { mylocalid = block.ID; StatusSetLocalID(mylocalid.ToString()); } #region Create an Avatar from the decoded data Avatar avatar = new Avatar(); if (Avatars.ContainsKey(block.ID)) { avatar = Avatars[block.ID]; } objectupdate.Avatar = true; // Textures objectupdate.Textures = new Primitive.TextureEntry(block.TextureEntry, 0, block.TextureEntry.Length); uint oldSeatID = avatar.ParentID; avatar.ID = block.FullID; avatar.LocalID = block.ID; avatar.CollisionPlane = objectupdate.CollisionPlane; avatar.Position = objectupdate.Position; avatar.Velocity = objectupdate.Velocity; avatar.Acceleration = objectupdate.Acceleration; avatar.Rotation = objectupdate.Rotation; avatar.AngularVelocity = objectupdate.AngularVelocity; avatar.NameValues = nameValues; avatar.PrimData = data; if (block.Data.Length > 0) { SayToUser("ERROR: Unexpected Data field for an avatar update, length " + block.Data.Length); } avatar.ParentID = block.ParentID; avatar.RegionHandle = update.RegionData.RegionHandle; // Textures avatar.Textures = objectupdate.Textures; // Save the avatar lock (Avatars) Avatars[block.ID] = avatar; // Fill up the translation dictionaries lock (AvatarIDtoUUID) AvatarIDtoUUID[block.ID] = block.FullID; lock (AvatarUUIDtoID) AvatarUUIDtoID[block.FullID] = block.ID; lock (AvatarUUIDToName) AvatarUUIDToName[block.FullID] = firstname + " " + lastname; lock (AvatarNameToUUID) AvatarNameToUUID[firstname + " " + lastname] = block.FullID; #endregion Create an Avatar from the decoded data break; #endregion Avatar case PCode.ParticleSystem: // ConsoleWriteLine("ERROR: Got a particle system update."); // // TODO: Create a callback for particle updates break; default: SayToUser("ERROR: Got an ObjectUpdate block with an unrecognized PCode " + pcode.ToString()); break; } } return(packet); }
private void Objects_OnObjectDataBlockUpdate(object sender, ObjectDataBlockUpdateEventArgs e) { Simulator simulator = e.Simulator; Primitive prim = e.Prim; var data = e.ConstructionData; ObjectUpdatePacket.ObjectDataBlock block = e.Block; var objectupdate0 = e.Update; if (!IsMaster(simulator)) { return; } // return; if (!objectupdate0.Avatar) { PrimtiveBlockUpdate(simulator, objectupdate0, prim, block, data); } else // this code only is usefull for avatars { prim.Flags = (PrimFlags)block.UpdateFlags; if ((prim.Flags & PrimFlags.ZlibCompressed) != 0) { Logger.Log("Got a ZlibCompressed ObjectMovementUpdate, implement me!", Helpers.LogLevel.Warning, client); } prim.NameValues = e.NameValues; prim.LocalID = block.ID; prim.ID = block.FullID; //NOTE this broke onSitChanged! prim.ParentID = block.ParentID; prim.RegionHandle = simulator.Handle; prim.Scale = block.Scale; prim.ClickAction = (ClickAction)block.ClickAction; prim.OwnerID = block.OwnerID; prim.MediaURL = Utils.BytesToString(block.MediaURL); prim.Text = Utils.BytesToString(block.Text); prim.TextColor = new Color4(block.TextColor, 0, false, true); // Sound information prim.Sound = block.Sound; prim.SoundFlags = (SoundFlags)block.Flags; prim.SoundGain = block.Gain; prim.SoundRadius = block.Radius; // Joint information prim.Joint = (JointType)block.JointType; prim.JointPivot = block.JointPivot; prim.JointAxisOrAnchor = block.JointAxisOrAnchor; // Object parameters prim.PrimData = data; // Textures, texture animations, particle system, and extra params //prim.Textures = objectupdate.Textures; prim.TextureAnim = new Primitive.TextureAnimation(block.TextureAnim, 0); prim.ParticleSys = new Primitive.ParticleSystem(block.PSBlock, 0); prim.SetExtraParamsFromBytes(block.ExtraParams, 0); // PCode-specific data switch (data.PCode) { case PCode.Grass: case PCode.Tree: case PCode.NewTree: if (block.Data.Length == 1) { prim.TreeSpecies = (Tree)block.Data[0]; } else { Logger.Log("Got a foliage update with an invalid TreeSpecies field", Helpers.LogLevel.Warning); } prim.ScratchPad = Utils.EmptyBytes; break; default: prim.ScratchPad = new byte[block.Data.Length]; if (block.Data.Length > 0) { Buffer.BlockCopy(block.Data, 0, prim.ScratchPad, 0, prim.ScratchPad.Length); } break; } // Packed parameters //prim.CollisionPlane = objectupdate.CollisionPlane; //prim.Position = objectupdate.Position; //prim.Velocity = objectupdate.Velocity; //prim.Acceleration = objectupdate.Acceleration; //prim.Rotation = objectupdate.Rotation; //prim.AngularVelocity = objectupdate.AngularVelocity; EnsureSelected(prim, simulator); Objects_OnPrimitiveUpdateReal(simulator, prim, objectupdate0, simulator.Handle, 0); } }
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); } } } } }
protected ObjectUpdatePacket.ObjectDataBlock CreateUpdateBlock() { ObjectUpdatePacket.ObjectDataBlock objupdate = new ObjectUpdatePacket.ObjectDataBlock(); this.SetDefaultPacketValues(objupdate); objupdate.UpdateFlags = 32 + 65536 + 131072 + 256 + 4 + 8 + 2048 + 524288 + 268435456; this.UpdatePacketShapeData(objupdate); byte[] pb = this.Pos.GetBytes(); Array.Copy(pb, 0, objupdate.ObjectData, 0, pb.Length); return objupdate; }