protected override void DeSerialise(byte[] buf, ref int o, int length) { SenderId = BinarySerializer.DeSerializeGuid(buf, ref o, length); SenderIsTrial = BinarySerializer.DeSerializeBool(buf, ref o, length); TextureEntry = BinarySerializer.DeSerializeTextureEntry(buf, ref o, length); int len = buf[o++]; // TODO: Decode visual params: Each byte appears to be a weight that needs to be scaled between the min and max values of the parameter identified by the index VisualParam = new byte[len]; Array.Copy(buf, o, VisualParam, 0, len); o += len; len = buf[o++]; for (int i = 0; i < len; i++) { AppearanceDatas.Add(new AppearanceData() { AppearanceVersion = buf[o++], CofVersion = BinarySerializer.DeSerializeInt32_Le(buf, ref o, length), Flags = BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length) }); } len = buf[o++]; for (int i = 0; i < len; i++) { HoverHeights.Add(BinarySerializer.DeSerializeVector3(buf, ref o, length)); } }
protected override void DeSerialise(byte[] buf, ref int o, int length) { byte nLocations = buf[o++]; for (byte i = 0; i < nLocations; i++) { Locations.Add(new CoarseLocation { Position = BinarySerializer.DeSerializeVector3Byte(buf, ref o, buf.Length) }); } int youIndex = BinarySerializer.DeSerializeInt16_Le(buf, ref o, buf.Length); int preyIndex = BinarySerializer.DeSerializeInt16_Le(buf, ref o, buf.Length); byte nAgents = buf[o++]; for (byte i = 0; i < nAgents; i++) { Guid guid = BinarySerializer.DeSerializeGuid(buf, ref o, length); if (i < nLocations) { Locations[i].AgentId = guid; } } if (youIndex > 0 && youIndex < nLocations - 1) { Locations[youIndex].IsYou = true; } if (preyIndex > 0 && preyIndex < nLocations - 1) { Locations[preyIndex].IsPrey = true; } }
protected override void DeSerialise(byte[] buf, ref int o, int length) { SoundId = BinarySerializer.DeSerializeGuid(buf, ref o, length); ObjectId = BinarySerializer.DeSerializeGuid(buf, ref o, length); OwnerId = BinarySerializer.DeSerializeGuid(buf, ref o, length); Gain = BinarySerializer.DeSerializeUInt32_Le(buf, ref o, buf.Length); SoundFlags = (SoundFlags)buf[o++]; }
protected override void DeSerialise(byte[] buf, ref int o, int length) { SoundId = BinarySerializer.DeSerializeGuid(buf, ref o, length); OwnerId = BinarySerializer.DeSerializeGuid(buf, ref o, length); ObjectId = BinarySerializer.DeSerializeGuid(buf, ref o, length); ParentId = BinarySerializer.DeSerializeGuid(buf, ref o, length); Handle = new RegionHandle(BinarySerializer.DeSerializeUInt64_Le(buf, ref o, length)); Position = BinarySerializer.DeSerializeVector3(buf, ref o, buf.Length); }
protected override void DeSerialise(byte[] buf, ref int o, int length) { byte nAgents = buf[o++]; for (byte i = 0; i < nAgents; i++) { Agents.Add(BinarySerializer.DeSerializeGuid(buf, ref o, length)); } }
protected override void DeSerialise(byte[] buf, ref int o, int length) { AgentId = BinarySerializer.DeSerializeGuid(buf, ref o, length); SessionId = BinarySerializer.DeSerializeGuid(buf, ref o, length); Position = BinarySerializer.DeSerializeVector3(buf, ref o, length); LookAt = BinarySerializer.DeSerializeVector3(buf, ref o, length); RegionHandle = new RegionHandle(BinarySerializer.DeSerializeUInt64_Le(buf, ref o, length)); TimeStamp = BinarySerializer.DeSerializeDateTime(buf, ref o, length); ChannelVersion = BinarySerializer.DeSerializeString(buf, ref o, length, 2); }
protected override void DeSerialise(byte[] buf, ref int o, int length) { AgentId = BinarySerializer.DeSerializeGuid(buf, ref o, length); FirstName = BinarySerializer.DeSerializeString(buf, ref o, length, 1); LastName = BinarySerializer.DeSerializeString(buf, ref o, length, 1); GroupTitle = BinarySerializer.DeSerializeString(buf, ref o, length, 1); ActiveGroupId = BinarySerializer.DeSerializeGuid(buf, ref o, length); GroupPowers = BinarySerializer.DeSerializeUInt64_Le(buf, ref o, length); GroupName = BinarySerializer.DeSerializeString(buf, ref o, length, 1); }
protected override void DeSerialise(byte[] buf, ref int o, int length) { AgentId = BinarySerializer.DeSerializeGuid(buf, ref o, length); SessionId = BinarySerializer.DeSerializeGuid(buf, ref o, length); byte nItems = buf[o++]; for (byte i = 0; i < nItems; i++) { InventoryItems.Add(BinarySerializer.DeSerializeGuid(buf, ref o, length)); } }
protected override void DeSerialise(byte[] buf, ref int o, int length) { FromName = BinarySerializer.DeSerializeString(buf, ref o, length, 1); SourceId = BinarySerializer.DeSerializeGuid(buf, ref o, length); OwnerId = BinarySerializer.DeSerializeGuid(buf, ref o, length); SourceType = (ChatSourceType)buf[o++]; ChatType = (ChatType)buf[o++]; AudibleLevel = (ChatAudibleLevel)buf[o++]; Position = BinarySerializer.DeSerializeVector3(buf, ref o, length); Message = BinarySerializer.DeSerializeString(buf, ref o, length, 2); }
protected override void DeSerialise(byte[] buf, ref int o, int length) { AgentId = BinarySerializer.DeSerializeGuid(buf, ref o, length); FirstName = BinarySerializer.DeSerializeString(buf, ref o, length, 1); LastName = BinarySerializer.DeSerializeString(buf, ref o, length, 1); GroupTitle = BinarySerializer.DeSerializeString(buf, ref o, length, 1); ActiveGroupId = BinarySerializer.DeSerializeGuid(buf, ref o, length); GroupPowers = BinarySerializer.DeSerializeUInt64_Le(buf, ref o, length); GroupName = BinarySerializer.DeSerializeString(buf, ref o, length, 1); Logger.LogDebug($"AgentDataUpdate: AgentId={AgentId}, FirstName={FirstName}, LastName={LastName}, GroupTitle={GroupTitle}, ActiveGroupId={ActiveGroupId}, GroupName={GroupName}"); }
protected override void DeSerialise(byte[] buf, ref int o, int length) { byte nSounds = buf[o++]; for (byte i = 0; i < nSounds; i++) { PreloadSoundMessage.SoundInfo si = new PreloadSoundMessage.SoundInfo { ObjectId = BinarySerializer.DeSerializeGuid(buf, ref o, length), OwnerId = BinarySerializer.DeSerializeGuid(buf, ref o, length), SoundId = BinarySerializer.DeSerializeGuid(buf, ref o, length) }; Sounds.Add(si); } }
protected override void DeSerialise(byte[] buf, ref int o, int length) { RegionFlags = (RegionFlags)BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length); SimAccess = (SimAccess)buf[o++]; SimName = BinarySerializer.DeSerializeString(buf, ref o, length, 1); SimOwner = BinarySerializer.DeSerializeGuid(buf, ref o, length); IsEstateManager = buf[o++] != 0; WaterHeight = BinarySerializer.DeSerializeFloat_Le(buf, ref o, length); BillableFactor = BinarySerializer.DeSerializeFloat_Le(buf, ref o, length); CacheId = BinarySerializer.DeSerializeGuid(buf, ref o, length); TerrainBase0 = BinarySerializer.DeSerializeGuid(buf, ref o, length); TerrainBase1 = BinarySerializer.DeSerializeGuid(buf, ref o, length); TerrainBase2 = BinarySerializer.DeSerializeGuid(buf, ref o, length); TerrainBase3 = BinarySerializer.DeSerializeGuid(buf, ref o, length); TerrainDetail0 = BinarySerializer.DeSerializeGuid(buf, ref o, length); TerrainDetail1 = BinarySerializer.DeSerializeGuid(buf, ref o, length); TerrainDetail2 = BinarySerializer.DeSerializeGuid(buf, ref o, length); TerrainDetail3 = BinarySerializer.DeSerializeGuid(buf, ref o, length); TerrainStartHeight00 = BinarySerializer.DeSerializeFloat_Le(buf, ref o, length); TerrainStartHeight01 = BinarySerializer.DeSerializeFloat_Le(buf, ref o, length); TerrainStartHeight10 = BinarySerializer.DeSerializeFloat_Le(buf, ref o, length); TerrainStartHeight11 = BinarySerializer.DeSerializeFloat_Le(buf, ref o, length); TerrainHeightRange00 = BinarySerializer.DeSerializeFloat_Le(buf, ref o, length); TerrainHeightRange01 = BinarySerializer.DeSerializeFloat_Le(buf, ref o, length); TerrainHeightRange10 = BinarySerializer.DeSerializeFloat_Le(buf, ref o, length); TerrainHeightRange11 = BinarySerializer.DeSerializeFloat_Le(buf, ref o, length); RegionId = BinarySerializer.DeSerializeGuid(buf, ref o, length); CpuClassId = BinarySerializer.DeSerializeInt32_Le(buf, ref o, length); CpuRatio = BinarySerializer.DeSerializeInt32_Le(buf, ref o, length); ColoName = BinarySerializer.DeSerializeString(buf, ref o, length, 1); ProductSku = BinarySerializer.DeSerializeString(buf, ref o, length, 1); ProductName = BinarySerializer.DeSerializeString(buf, ref o, length, 1); int n = buf[o++]; for (int i = 0; i < n; i++) { RegionInfo4 info = new RegionInfo4 { RegionFlagsExtended = BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length), RegionProtocols = BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length) }; RegionInfo4.Add(info); } }
protected override void DeSerialise(byte[] buf, ref int o, int length) { AgentId = BinarySerializer.DeSerializeGuid(buf, ref o, length); SessionId = BinarySerializer.DeSerializeGuid(buf, ref o, length); IsFromGroup = buf[o++] != 0; // TODO: Put this in BinarySerializer to make sure that it is consistent ToAgentId = BinarySerializer.DeSerializeGuid(buf, ref o, length); ParentEstateId = BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length); RegionId = BinarySerializer.DeSerializeGuid(buf, ref o, length); Position = BinarySerializer.DeSerializeVector3(buf, ref o, length); OnlineMode = (OnlineMode)buf[o++]; DialogType = (DialogType)buf[o++]; Id = BinarySerializer.DeSerializeGuid(buf, ref o, length); Timestamp = BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length); FromAgentName = BinarySerializer.DeSerializeString(buf, ref o, length, 1); MessageText = BinarySerializer.DeSerializeString(buf, ref o, length, 2); UInt16 len = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length); BinaryBucket = new byte[len]; Array.Copy(buf, o, BinaryBucket, 0, len); o += len; }
protected override void DeSerialise(byte[] buf, ref int o, int length) { RegionHandle = new RegionHandle(BinarySerializer.DeSerializeUInt64_Le(buf, ref o, length)); TimeDilation = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length); string logMessage = $"ObjectUpdateCompressed: RegionHandle={RegionHandle}, TimeDilation={TimeDilation}"; int nObjects = buf[o++]; for (int i = 0; i < nObjects; i++) { UInt32 len; ObjectUpdateMessage.ObjectData data = new ObjectUpdateMessage.ObjectData(); Objects.Add(data); data.UpdateFlags = (ObjectUpdateFlags)BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length); int compressedLength = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length); byte[] compressedData = new byte[compressedLength]; Array.Copy(buf, o, compressedData, 0, compressedLength); o += compressedLength; int compressedOffset = 0; logMessage += $"\n Object {i}: UpdateFlags={data.UpdateFlags}, Data({compressedData.Length})={BitConverter.ToString(compressedData)}"; data.FullId = BinarySerializer.DeSerializeGuid(compressedData, ref compressedOffset, compressedLength); data.LocalId = BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength); data.PCode = (PCode)compressedData[compressedOffset++]; data.State = compressedData[compressedOffset++]; data.Crc = BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength); data.Material = (MaterialType)compressedData[compressedOffset++]; data.ClickAction = (ClickAction)compressedData[compressedOffset++]; data.Scale = BinarySerializer.DeSerializeVector3(compressedData, ref compressedOffset, compressedLength); data.Position = BinarySerializer.DeSerializeVector3(compressedData, ref compressedOffset, compressedLength); data.Rotation = BinarySerializer.DeSerializeQuaternion(compressedData, ref compressedOffset, compressedLength); CompressedFlags compressedFlags = (CompressedFlags)BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength); data.OwnerId = BinarySerializer.DeSerializeGuid(compressedData, ref compressedOffset, compressedLength); logMessage += $"\n FullId={data.FullId}, LocalId={data.LocalId}, PCode={data.PCode}, State={data.State}, Crc={data.Crc}, Material={data.Material}, ClickAction={data.ClickAction}, Scale={data.Scale}, Position={data.Position}, Rotation={data.Rotation}, CompressedFlags=({compressedFlags})"; if ((compressedFlags & CompressedFlags.HasAngularVelocity) != 0) { data.AngularVelocity = BinarySerializer.DeSerializeVector3(compressedData, ref compressedOffset, compressedLength); logMessage += $", AngularVelocity={data.AngularVelocity}"; } data.ParentId = (compressedFlags & CompressedFlags.HasParent) != 0 ? BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength) : (uint)0; logMessage += $", ParentId={data.ParentId}"; if ((compressedFlags & CompressedFlags.Tree) != 0) { byte treeSpecies = compressedData[compressedOffset++]; logMessage += $", TreeSpecies={treeSpecies}"; } if ((compressedFlags & CompressedFlags.ScratchPad) != 0) { len = compressedData[compressedOffset++]; compressedOffset += (int)len; // TODO: These offsets and length should all be UInt32 logMessage += $", Scratchpad({len})"; } if ((compressedFlags & CompressedFlags.HasText) != 0) { data.Text = BinarySerializer.DeSerializeString(compressedData, ref compressedOffset, compressedLength, 0); data.TextColour = BinarySerializer.DeSerializeColor(compressedData, ref compressedOffset, compressedLength); logMessage += $", Text={data.Text}, TextColour={data.TextColour}"; } if ((compressedFlags & CompressedFlags.MediaURL) != 0) { data.MediaUrl = BinarySerializer.DeSerializeString(compressedData, ref compressedOffset, compressedLength, 0); logMessage += $", MediaUrl={data.MediaUrl}"; } if ((compressedFlags & CompressedFlags.HasParticles) != 0) { len = 86; logMessage += $", ParticleSystem({len})"; } byte nExtraParameters = compressedData[compressedOffset++]; for (int j = 0; j < nExtraParameters; j++) { if (j == 0) { logMessage += ", ExtraParameters=("; } ExtraParamType type = (ExtraParamType)BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, compressedLength); len = BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength); switch (type) { case ExtraParamType.Flexible: break; case ExtraParamType.Light: break; case ExtraParamType.Sculpt: break; case ExtraParamType.LightImage: break; case ExtraParamType.Mesh: break; default: throw new ArgumentOutOfRangeException(); } logMessage += $"{type}, "; compressedOffset += (int)len; // TODO: These offsets and length should all be UInt32 if (j == nExtraParameters - 1) { logMessage += ")"; } } if ((compressedFlags & CompressedFlags.HasSound) != 0) { data.SoundId = BinarySerializer.DeSerializeGuid(compressedData, ref compressedOffset, compressedLength); data.Gain = BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength); data.SoundFlags = (SoundFlags)compressedData[compressedOffset++]; data.Radius = BinarySerializer.DeSerializeFloat_Le(compressedData, ref compressedOffset, compressedLength); logMessage += $", SoundId={data.SoundId}, Gain={data.Gain}, SoundFlags={data.SoundFlags}, Radius={data.Radius}"; } if ((compressedFlags & CompressedFlags.HasNameValues) != 0) { data.NameValue = BinarySerializer.DeSerializeString(compressedData, ref compressedOffset, compressedLength, 0); logMessage += $", NameValue={data.NameValue}"; } data.PathCurve = (PathType)compressedData[compressedOffset++]; data.PathBegin = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * CUT_QUANTA; data.PathEnd = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * CUT_QUANTA; data.PathScaleX = compressedData[compressedOffset++] * SCALE_QUANTA; data.PathScaleY = compressedData[compressedOffset++] * SCALE_QUANTA; data.PathShearX = compressedData[compressedOffset++] * SHEAR_QUANTA; data.PathShearY = compressedData[compressedOffset++] * SHEAR_QUANTA; data.PathTwist = (sbyte)compressedData[compressedOffset++] * SCALE_QUANTA; data.PathTwistBegin = (sbyte)compressedData[compressedOffset++] * SCALE_QUANTA; data.PathRadiusOffset = (sbyte)compressedData[compressedOffset++] * SCALE_QUANTA; data.PathTaperX = (sbyte)compressedData[compressedOffset++] * TAPER_QUANTA; data.PathTaperY = (sbyte)compressedData[compressedOffset++] * TAPER_QUANTA; data.PathRevolutions = compressedData[compressedOffset++] * REV_QUANTA; data.PathSkew = (sbyte)compressedData[compressedOffset++] * SCALE_QUANTA; data.ProfileCurve = (ProfileType)compressedData[compressedOffset++]; data.ProfileBegin = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * CUT_QUANTA; data.ProfileEnd = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * CUT_QUANTA; data.ProfileHollow = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * HOLLOW_QUANTA; UInt32 textureEntryLength = BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, length); logMessage += $", textures({textureEntryLength})"; compressedOffset += (int)textureEntryLength; if ((compressedFlags & CompressedFlags.TextureAnimation) != 0) { TextureAnimation textureAnimation = new TextureAnimation() { Mode = (TextureAnimationMode)compressedData[compressedOffset++], Face = compressedData[compressedOffset++], SizeX = compressedData[compressedOffset++], SizeY = compressedData[compressedOffset++], Start = BinarySerializer.DeSerializeFloat_Le(compressedData, ref compressedOffset, length), Length = BinarySerializer.DeSerializeFloat_Le(compressedData, ref compressedOffset, length), Rate = BinarySerializer.DeSerializeFloat_Le(compressedData, ref compressedOffset, length) }; logMessage += ", TextureAnimation"; } data.IsAttachment = (compressedFlags & CompressedFlags.HasNameValues) != 0 && data.ParentId != 0; } //Logger.LogDebug(logMessage); }
protected override void DeSerialise(byte[] buf, ref int o, int length) { AgentId = BinarySerializer.DeSerializeGuid(buf, ref o, length); SessionId = BinarySerializer.DeSerializeGuid(buf, ref o, length); byte nEffects = buf[o++]; for (byte i = 0; i < nEffects; i++) { Guid effectId = BinarySerializer.DeSerializeGuid(buf, ref o, length); Guid agentId = BinarySerializer.DeSerializeGuid(buf, ref o, length); ViewerEffectType type = (ViewerEffectType)buf[o++]; float duration = BinarySerializer.DeSerializeFloat_Le(buf, ref o, length); Color color = BinarySerializer.DeSerializeColor(buf, ref o, length); byte typeDataLength = buf[o++]; ViewerEffect effect = null; switch (type) { case ViewerEffectType.Text: break; case ViewerEffectType.Icon: break; case ViewerEffectType.Connector: break; case ViewerEffectType.FlexibleObject: break; case ViewerEffectType.AnimalControls: break; case ViewerEffectType.LocalAnimationObject: break; case ViewerEffectType.Cloth: break; case ViewerEffectType.EffectBeam: case ViewerEffectType.EffectGlow: case ViewerEffectType.EffectPoint: case ViewerEffectType.EffectTrail: case ViewerEffectType.EffectSphere: case ViewerEffectType.EffectSpiral: case ViewerEffectType.EffectEdit: ViewerEffectSpiral spiralEffect = new ViewerEffectSpiral(); spiralEffect.SourceObjectId = BinarySerializer.DeSerializeGuid(buf, ref o, length); spiralEffect.TargetObjectId = BinarySerializer.DeSerializeGuid(buf, ref o, length); spiralEffect.PositionGlobal = BinarySerializer.DeSerializeVector3Double(buf, ref o, length); effect = spiralEffect; break; case ViewerEffectType.EffectLookAt: ViewerEffectLookAt lookAtEffect = new ViewerEffectLookAt(); lookAtEffect.SourceAvatarId = BinarySerializer.DeSerializeGuid(buf, ref o, length); lookAtEffect.TargetObjectId = BinarySerializer.DeSerializeGuid(buf, ref o, length); lookAtEffect.TargetPosition = BinarySerializer.DeSerializeVector3Double(buf, ref o, length); lookAtEffect.LookAtType = (ViewerEffectLookAtType)buf[o++]; effect = lookAtEffect; break; case ViewerEffectType.EffectPointAt: ViewerEffectPointAt pointAtEffect = new ViewerEffectPointAt(); pointAtEffect.SourceAvatarId = BinarySerializer.DeSerializeGuid(buf, ref o, length); pointAtEffect.TargetObjectId = BinarySerializer.DeSerializeGuid(buf, ref o, length); pointAtEffect.TargetPosition = BinarySerializer.DeSerializeVector3Double(buf, ref o, length); pointAtEffect.PointAtType = (ViewerEffectPointAtType)buf[o++]; effect = pointAtEffect; break; case ViewerEffectType.EffectVoiceViaualizer: break; case ViewerEffectType.NameTag: break; case ViewerEffectType.EffectBlob: break; default: throw new ArgumentOutOfRangeException(); } if (effect == null) { throw new NotImplementedException($"ViewerEffectMessage: ViewerEffect type {type} is not implemented."); } effect.Id = effectId; effect.AgentId = agentId; effect.EffectType = type; effect.Duration = duration; effect.Color = color; Effects.Add(effect); } }
public void AvatarAppearanceExample() { byte[] buffer = { 0x68, 0x00, 0xc2, 0x28, 0xd1, 0xcf, 0x4b, 0x5d, 0x4b, 0xa8, 0x84, 0xf4, 0x89, 0x9a, 0x07, 0x96, 0xaa, 0x97, // image_id (Default) 0x9f, 0xff, 0xff, 0x9f, 0xe1, 0x7f, // mask (Exception 0) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // image_id (Exception 0) 0xc0, 0x9e, 0x00, // mask (Exception 1) 0x3a, 0x36, 0x7d, 0x1c, 0xbe, 0xf1, 0x6d, 0x43, 0x75, 0x95, 0xe8, 0x8c, 0x1e, 0x3a, 0xad, 0xb3, // image_id (Exception 1) 0x00, // end 0x00, 0x00, 0x00, 0x00, // color (Default) 0x00, // end 0x00, 0x00, 0x80, 0x3f, // scale_s (Default) 0x00, // end 0x00, 0x00, 0x80, 0x3f, // scale_t (Default) 0x00, // end 0x00, 0x00, // offset_s (Default) 0x00, // end 0x00, 0x00, // offset_t (Default) 0x00, // end 0x00, // image_rot (Default) 0x00, // end 0x00, // bump (Default) 0x00, // end 0x00, // media_flags (Default) 0x00, // end 0x00, // glow (Default) 0x00, // end 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // material_id (Default) 0x00 // end }; int offset = 0; Guid a = BinarySerializer.DeSerializeGuid(new byte[] { 0xc2, 0x28, 0xd1, 0xcf, 0x4b, 0x5d, 0x4b, 0xa8, 0x84, 0xf4, 0x89, 0x9a, 0x07, 0x96, 0xaa, 0x97 }, ref offset, 16); offset = 0; Guid b = BinarySerializer.DeSerializeGuid(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, ref offset, 16); offset = 0; Guid c = BinarySerializer.DeSerializeGuid(new byte[] { 0x3a, 0x36, 0x7d, 0x1c, 0xbe, 0xf1, 0x6d, 0x43, 0x75, 0x95, 0xe8, 0x8c, 0x1e, 0x3a, 0xad, 0xb3 }, ref offset, 16); offset = 0; TextureEntry entry = BinarySerializer.DeSerializeTextureEntry(buffer, ref offset, buffer.Length); //for (int i = 0; i < entry.FaceTextures.Length; i++) //{ // TextureEntryFace face = entry.FaceTextures[i]; // UnityEngine.Debug.Log($"{i:x2}: {face.TextureId}"); //} //var s = string.Concat(entry.FaceTextures.Select(x => //{ // if (x.TextureId == a) return 'a'; // if (x.TextureId == b) return 'b'; // if (x.TextureId == c) return 'c'; // return ' '; //})); //UnityEngine.Debug.Log(s); Assert.AreEqual(b, entry.FaceTextures[0x00].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x01].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x02].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x03].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x04].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x05].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x06].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x07].TextureId); Assert.AreEqual(c, entry.FaceTextures[0x08].TextureId); Assert.AreEqual(c, entry.FaceTextures[0x09].TextureId); Assert.AreEqual(c, entry.FaceTextures[0x0a].TextureId); Assert.AreEqual(c, entry.FaceTextures[0x0b].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x0c].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x0d].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x0e].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x0f].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x10].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x11].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x12].TextureId); Assert.AreEqual(a, entry.FaceTextures[0x13].TextureId); Assert.AreEqual(c, entry.FaceTextures[0x14].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x15].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x16].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x17].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x18].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x19].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x1a].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x1b].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x1c].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x1d].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x1e].TextureId); Assert.AreEqual(b, entry.FaceTextures[0x1f].TextureId); }
protected override void DeSerialise(byte[] buf, ref int o, int length) { RegionHandle = new RegionHandle(BinarySerializer.DeSerializeUInt64_Le(buf, ref o, length)); TimeDilation = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length); int nObjects = buf[o++]; for (int i = 0; i < nObjects; i++) { int len; ObjectUpdateMessage.ObjectData data = new ObjectUpdateMessage.ObjectData(); Objects.Add(data); data.LocalId = BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length); data.State = buf[o++]; data.FullId = BinarySerializer.DeSerializeGuid(buf, ref o, length); data.Crc = BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length); data.PCode = (PCode)buf[o++]; data.Material = (MaterialType)buf[o++]; data.ClickAction = (ClickAction)buf[o++]; data.Scale = BinarySerializer.DeSerializeVector3(buf, ref o, buf.Length); data.MovementUpdate = DeSerializeMovementUpdate(buf, ref o, buf.Length); data.ParentId = BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length); data.UpdateFlags = (ObjectUpdateFlags)BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length); data.PathCurve = (PathType)buf[o++]; data.ProfileCurve = (ProfileType)buf[o++]; data.PathBegin = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length) * CUT_QUANTA; data.PathEnd = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length) * CUT_QUANTA; data.PathScaleX = buf[o++] * SCALE_QUANTA; data.PathScaleY = buf[o++] * SCALE_QUANTA; data.PathShearX = buf[o++] * SHEAR_QUANTA; data.PathShearY = buf[o++] * SHEAR_QUANTA; data.PathTwist = (sbyte)buf[o++] * SCALE_QUANTA; data.PathTwistBegin = (sbyte)buf[o++] * SCALE_QUANTA; data.PathRadiusOffset = (sbyte)buf[o++] * SCALE_QUANTA; data.PathTaperX = (sbyte)buf[o++] * TAPER_QUANTA; data.PathTaperY = (sbyte)buf[o++] * TAPER_QUANTA; data.PathRevolutions = buf[o++] * REV_QUANTA; data.PathSkew = (sbyte)buf[o++] * SCALE_QUANTA; data.ProfileBegin = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length) * CUT_QUANTA; data.ProfileEnd = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length) * CUT_QUANTA; data.ProfileHollow = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length) * HOLLOW_QUANTA; data.TextureEntry = BinarySerializer.DeSerializeTextureEntry(buf, ref o, length); data.TextureAnimation = BinarySerializer.DeSerializeTextureAnimation(buf, ref o, length); data.NameValue = BinarySerializer.DeSerializeString(buf, ref o, length, 2); len = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length); data.Data2 = new byte[len]; Array.Copy(buf, o, data.Data2, 0, len); o += len; data.Text = BinarySerializer.DeSerializeString(buf, ref o, length, 1); data.TextColour = BinarySerializer.DeSerializeColor(buf, ref o, length); data.MediaUrl = BinarySerializer.DeSerializeString(buf, ref o, length, 1); len = buf[o++]; data.ParticleSystemData = new byte[len]; Array.Copy(buf, o, data.ParticleSystemData, 0, len); o += len; len = buf[o++]; data.ExtraParameters = BinarySerializer.DeSerializeExtraParameters(buf, ref o, o + len); data.SoundId = BinarySerializer.DeSerializeGuid(buf, ref o, length); data.OwnerId = BinarySerializer.DeSerializeGuid(buf, ref o, length); data.Gain = BinarySerializer.DeSerializeUInt32_Le(buf, ref o, buf.Length); data.SoundFlags = (SoundFlags)buf[o++]; data.Radius = BinarySerializer.DeSerializeFloat_Le(buf, ref o, length); data.JointType = (JointType)buf[o++]; data.JointPivot = BinarySerializer.DeSerializeVector3(buf, ref o, buf.Length); data.JointAxisOrAnchor = BinarySerializer.DeSerializeVector3(buf, ref o, buf.Length); //Logger.LogDebug("ObjectUpdateMessage.DeSerialise", ToString()); } }
protected override void DeSerialise(byte[] buf, ref int o, int length) { RegionHandle = new RegionHandle(BinarySerializer.DeSerializeUInt64_Le(buf, ref o, length)); TimeDilation = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length); string logMessage = $"ObjectUpdateCompressed: RegionHandle={RegionHandle}, TimeDilation={TimeDilation}"; int nObjects = buf[o++]; for (int i = 0; i < nObjects; i++) { UInt32 len; ObjectUpdateMessage.ObjectData data = new ObjectUpdateMessage.ObjectData(); Objects.Add(data); data.UpdateFlags = (ObjectUpdateFlags)BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length); int compressedLength = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length); byte[] compressedData = new byte[compressedLength]; Array.Copy(buf, o, compressedData, 0, compressedLength); o += compressedLength; int compressedOffset = 0; logMessage += $"\n Object {i}: UpdateFlags={data.UpdateFlags}, Data({compressedData.Length})={BitConverter.ToString(compressedData)}"; data.FullId = BinarySerializer.DeSerializeGuid(compressedData, ref compressedOffset, compressedLength); data.LocalId = BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength); data.PCode = (PCode)compressedData[compressedOffset++]; data.State = compressedData[compressedOffset++]; data.Crc = BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength); data.Material = (MaterialType)compressedData[compressedOffset++]; data.ClickAction = (ClickAction)compressedData[compressedOffset++]; data.Scale = BinarySerializer.DeSerializeVector3(compressedData, ref compressedOffset, compressedLength); data.Position = BinarySerializer.DeSerializeVector3(compressedData, ref compressedOffset, compressedLength); data.Rotation = BinarySerializer.DeSerializeQuaternion(compressedData, ref compressedOffset, compressedLength); CompressedFlags compressedFlags = (CompressedFlags)BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength); data.OwnerId = BinarySerializer.DeSerializeGuid(compressedData, ref compressedOffset, compressedLength); logMessage += $"\n FullId={data.FullId}, LocalId={data.LocalId}, PCode={data.PCode}, State={data.State}, Crc={data.Crc}, Material={data.Material}, ClickAction={data.ClickAction}, Scale={data.Scale}, Position={data.Position}, Rotation={data.Rotation}, CompressedFlags=({compressedFlags})"; if ((compressedFlags & CompressedFlags.HasAngularVelocity) != 0) { data.AngularVelocity = BinarySerializer.DeSerializeVector3(compressedData, ref compressedOffset, compressedLength); logMessage += $", AngularVelocity={data.AngularVelocity}"; } data.ParentId = (compressedFlags & CompressedFlags.HasParent) != 0 ? BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength) : (uint)0; logMessage += $", ParentId={data.ParentId}"; if ((compressedFlags & CompressedFlags.Tree) != 0) { byte treeSpecies = compressedData[compressedOffset++]; logMessage += $", TreeSpecies={treeSpecies}"; } if ((compressedFlags & CompressedFlags.ScratchPad) != 0) { len = compressedData[compressedOffset++]; compressedOffset += (int)len; // TODO: These offsets and length should all be UInt32 logMessage += $", Scratchpad({len})"; } if ((compressedFlags & CompressedFlags.HasText) != 0) { data.Text = BinarySerializer.DeSerializeString(compressedData, ref compressedOffset, compressedLength, 0); data.TextColour = BinarySerializer.DeSerializeColor(compressedData, ref compressedOffset, compressedLength); logMessage += $", Text={data.Text}, TextColour={data.TextColour}"; } if ((compressedFlags & CompressedFlags.MediaURL) != 0) { data.MediaUrl = BinarySerializer.DeSerializeString(compressedData, ref compressedOffset, compressedLength, 0); logMessage += $", MediaUrl={data.MediaUrl}"; } if ((compressedFlags & CompressedFlags.HasParticles) != 0) { // TODO: Parse the particle system data. OpenMetaverse says that this is a BitPack of 86 bytes. len = 86; compressedOffset += (int)len; logMessage += $", ParticleSystem({len})"; } data.ExtraParameters = BinarySerializer.DeSerializeExtraParameters(compressedData, ref compressedOffset, compressedOffset + compressedLength); if ((compressedFlags & CompressedFlags.HasSound) != 0) { data.SoundId = BinarySerializer.DeSerializeGuid(compressedData, ref compressedOffset, compressedLength); data.Gain = BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength); data.SoundFlags = (SoundFlags)compressedData[compressedOffset++]; data.Radius = BinarySerializer.DeSerializeFloat_Le(compressedData, ref compressedOffset, compressedLength); logMessage += $", SoundId={data.SoundId}, Gain={data.Gain}, SoundFlags={data.SoundFlags}, Radius={data.Radius}"; } if ((compressedFlags & CompressedFlags.HasNameValues) != 0) { data.NameValue = BinarySerializer.DeSerializeString(compressedData, ref compressedOffset, compressedLength, 0); logMessage += $", NameValue={data.NameValue}"; } data.PathCurve = (PathType)compressedData[compressedOffset++]; data.PathBegin = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * CUT_QUANTA; data.PathEnd = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * CUT_QUANTA; data.PathScaleX = compressedData[compressedOffset++] * SCALE_QUANTA; data.PathScaleY = compressedData[compressedOffset++] * SCALE_QUANTA; data.PathShearX = compressedData[compressedOffset++] * SHEAR_QUANTA; data.PathShearY = compressedData[compressedOffset++] * SHEAR_QUANTA; data.PathTwist = (sbyte)compressedData[compressedOffset++] * SCALE_QUANTA; data.PathTwistBegin = (sbyte)compressedData[compressedOffset++] * SCALE_QUANTA; data.PathRadiusOffset = (sbyte)compressedData[compressedOffset++] * SCALE_QUANTA; data.PathTaperX = (sbyte)compressedData[compressedOffset++] * TAPER_QUANTA; data.PathTaperY = (sbyte)compressedData[compressedOffset++] * TAPER_QUANTA; data.PathRevolutions = compressedData[compressedOffset++] * REV_QUANTA; data.PathSkew = (sbyte)compressedData[compressedOffset++] * SCALE_QUANTA; data.ProfileCurve = (ProfileType)compressedData[compressedOffset++]; data.ProfileBegin = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * CUT_QUANTA; data.ProfileEnd = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * CUT_QUANTA; data.ProfileHollow = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * HOLLOW_QUANTA; data.TextureEntry = BinarySerializer.DeSerializeTextureEntry(compressedData, ref compressedOffset, compressedLength, true); logMessage += $", TextureEntry={data.TextureEntry}"; if ((compressedFlags & CompressedFlags.TextureAnimation) != 0) { data.TextureAnimation = BinarySerializer.DeSerializeTextureAnimation(compressedData, ref compressedOffset, compressedLength); logMessage += ", TextureAnimation"; } data.IsAttachment = (compressedFlags & CompressedFlags.HasNameValues) != 0 && data.ParentId != 0; } //Logger.LogDebug("ObjectUpdateCompressedMessage.DeSerialise", logMessage); }