static CallbackResult OnCharacterUpdate(byte[] data, CallbackResult prevResult) { lock (World.SyncRoot) { PacketReader reader = new PacketReader(data); if (reader.ReadByte() != 0x77) throw new Exception("Invalid packet passed to OnCharacterUpdate."); bool newCharacter = false; uint serial = reader.ReadUInt32(); RealCharacter chr = World.FindRealCharacter(serial); if (chr == null) { chr = new RealCharacter(serial); World.Add(chr); newCharacter = true; } chr.Graphic = reader.ReadUInt16(); chr.X = reader.ReadUInt16(); chr.Y = reader.ReadUInt16(); chr.Z = reader.ReadSByte(); chr.Direction = reader.ReadByte(); chr.Color = reader.ReadUInt16(); chr.Flags = reader.ReadByte(); chr.Notoriety = reader.ReadByte(); #if WORLDDEBUG Debug.WriteLine(String.Format("Character updated ({0}).", chr.Description), "World"); #endif if (newCharacter) characterAppeared.InvokeAsync(null, new CharacterAppearedEventArgs(serial)); ObjectChanged(serial, ObjectChangeType.CharUpdated); return CallbackResult.Normal; } }
static CallbackResult OnItemDetails(byte[] data, CallbackResult prevResult) { lock (World.SyncRoot) { PacketReader reader = new PacketReader(data); byte id = reader.ReadByte(); if (id != 0x1A) throw new Exception("Invalid packet passed to OnItemDetails."); ushort blockSize = reader.ReadUInt16(); if (blockSize != reader.Length) return CallbackResult.Normal; uint serial = reader.ReadUInt32(); bool isNew = false; RealItem item = World.FindRealItem(serial); if (item == null) { item = new RealItem(serial); World.Add(item); isNew = true; } ushort dispId = reader.ReadUInt16(); if ((serial & 0x80000000) != 0) { item.Amount = reader.ReadUInt16(); } if ((dispId & 0x8000) != 0) { dispId += reader.ReadByte(); } item.Graphic = (ushort)(dispId & 0x7FFF); ushort x = reader.ReadUInt16(); item.X = (ushort)(x & 0x7FFF); ushort y = reader.ReadUInt16(); item.Y = (ushort)(y & 0x3FFF); if ((x & 0x8000) != 0) { byte direction = reader.ReadByte(); } item.Z = reader.ReadSByte(); if ((y & 0x8000) != 0) { item.Color = reader.ReadUInt16(); } if ((y & 0x4000) != 0) { item.Flags = reader.ReadByte(); } item.Detach(); #if WORLDDEBUG Trace.WriteLine(String.Format("Item updated ({0}).", item.Description), "World"); #endif if (isNew) itemAdded.InvokeAsync(null, new ObjectChangedEventArgs(serial, ObjectChangeType.NewItem)); ObjectChanged(serial, ObjectChangeType.ItemUpdated); itemUpdated.InvokeAsync(null, new ObjectChangedEventArgs(item.Serial, ObjectChangeType.ItemUpdated)); return CallbackResult.Normal; } }
static CallbackResult OnCharacterInformation(byte[] data, CallbackResult prevResult) { lock (World.SyncRoot) { PacketReader reader = new PacketReader(data); if (reader.ReadByte() != 0x78) throw new Exception("Invalid packet passed to OnCharacterInformation."); ushort blockSize = reader.ReadUInt16(); if (data.Length != blockSize) Trace.WriteLine(String.Format("BlockSize ({0}) for dynamic packet 0x78 doesn't meet data lenght ({1}).", data.Length), "World"); bool newCharacter = false; uint serial = reader.ReadUInt32(); RealCharacter chr = World.FindRealCharacter(serial); if (chr == null) { chr = new RealCharacter(serial); World.Add(chr); newCharacter = true; } chr.Graphic = reader.ReadUInt16(); chr.X = reader.ReadUInt16(); chr.Y = reader.ReadUInt16(); chr.Z = reader.ReadSByte(); chr.Direction = reader.ReadByte(); chr.Color = reader.ReadUInt16(); chr.Flags = reader.ReadByte(); chr.Notoriety = reader.ReadByte(); if (newCharacter) characterAppeared.InvokeAsync(null, new CharacterAppearedEventArgs(serial)); ObjectChanged(serial, ObjectChangeType.CharUpdated); // Items while (reader.Offset < blockSize) { uint itemSerial = reader.ReadUInt32(); if (itemSerial == 0) return CallbackResult.Normal; bool isNew = false; RealItem item = World.FindRealItem(itemSerial); if (item == null) { item = new RealItem(itemSerial); World.Add(item); isNew = true; } item.Detach(); ushort graphic = reader.ReadUInt16(); item.Graphic = (ushort)(graphic & 0x7FFF); item.Layer = reader.ReadByte(); if ((graphic & 0x8000) != 0) { item.Color = reader.ReadUInt16(); } item.Container = chr.Serial; chr.Layers[item.Layer] = item.Serial; #if WORLDDEBUG Trace.WriteLine(String.Format("Item updated ({0}).", item.Description), "World"); #endif if (isNew) itemAdded.InvokeAsync(null, new ObjectChangedEventArgs(serial, ObjectChangeType.NewItem)); itemUpdated.InvokeAsync(null, new ObjectChangedEventArgs(serial, ObjectChangeType.ItemUpdated)); ObjectChanged(itemSerial, ObjectChangeType.ItemUpdated); } #if WORLDDEBUG Trace.WriteLine(String.Format("Character updated ({0}).", chr), "World"); #endif return CallbackResult.Normal; } }