static uint AddToContainerData(PacketReader reader, out bool isNew) { uint serial = reader.ReadUInt32(); RealItem item = World.FindRealItem(serial); if (item == null) { item = new RealItem(serial); World.Add(item); isNew = true; } else { isNew = false; } item.Detach(); item.Graphic = reader.ReadUInt16(); byte unknown = reader.ReadByte(); item.Amount = reader.ReadUInt16(); item.X = reader.ReadUInt16(); item.Y = reader.ReadUInt16(); item.Z = 0; item.Container = reader.ReadUInt32(); item.Color = reader.ReadUInt16(); #if WORLDDEBUG Trace.WriteLine(String.Format("Item updated ({0}).", item.Description), "World"); #endif return serial; }
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 OnContainerContents(byte[] data, CallbackResult prevResult) { lock (World.SyncRoot) { Trace.WriteLine(String.Format("Populating container.."), "World"); PacketReader reader = new PacketReader(data); byte id = reader.ReadByte(); if (id != 0x3C) throw new Exception("Invalid packet passed to OnContainerContents."); ushort blockSize = reader.ReadUInt16(); if (blockSize != reader.Length) Trace.WriteLine(String.Format("BlockSize ({0}) for dynamic packet 0x3C doesn't meet data lenght ({1}).", blockSize, data.Length), "World"); ushort items = reader.ReadUInt16(); while (items > 0) { bool isNew; uint serial = AddToContainerData(reader, out isNew); if (isNew) itemAdded.InvokeAsync(null, new ObjectChangedEventArgs(serial, ObjectChangeType.NewItem)); itemUpdated.InvokeAsync(null, new ObjectChangedEventArgs(serial, ObjectChangeType.ItemUpdated)); ObjectChanged(serial, ObjectChangeType.ItemUpdated); items--; } return CallbackResult.Normal; } }
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 OnCharacterStatus(byte[] data, CallbackResult prevResult) { lock (World.SyncRoot) { PacketReader reader = new PacketReader(data); if (reader.ReadByte() != 0x11) throw new Exception("Invalid packet passed to OnCharacterStatus."); ushort blockSize = reader.ReadUInt16(); if (data.Length != blockSize) Trace.WriteLine(String.Format("BlockSize ({0}) for dynamic packet 0x11 doesn't meet data lenght ({1}).", blockSize, data.Length), "World"); uint serial = reader.ReadUInt32(); RealCharacter chr = World.FindRealCharacter(serial); if (chr == null) { Trace.WriteLine(String.Format("Cannot update status for unknown character (serial=0x{0:X8}).", serial), "World"); return CallbackResult.Normal; } chr.Name = reader.ReadAnsiString(30); chr.Hits = reader.ReadInt16(); chr.MaxHits = reader.ReadInt16(); chr.Renamable = reader.ReadByte() > 0; byte more = reader.ReadByte(); if (more > 0) { byte gender = reader.ReadByte(); chr.Strenght = reader.ReadInt16(); chr.Dexterity = reader.ReadInt16(); chr.Intelligence = reader.ReadInt16(); chr.Stamina = reader.ReadInt16(); chr.MaxStamina = reader.ReadInt16(); chr.Mana = reader.ReadInt16(); chr.MaxMana = reader.ReadInt16(); chr.Gold = reader.ReadInt32(); chr.Armor = reader.ReadUInt16(); chr.Weight = reader.ReadUInt16(); } #if WORLDDEBUG Trace.WriteLine(String.Format("Character status updated ({0}).", chr.Description), "World"); #endif ObjectChanged(serial, ObjectChangeType.CharUpdated, true); 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; } }