private void Handle_ObjUpdate(WoWReader wr, bool Compressed) { if (Compressed) { Int32 size = wr.ReadInt32(); byte[] decomped = Foole.Utils.Compression.Decompress(size, wr.ReadRemaining()); wr = new WoWReader(decomped); } WoWGuid guid; UInt32 blockCount; byte unk1; byte blockType; byte objTypeId; blockCount = wr.ReadUInt32(); unk1 = wr.ReadByte(); BoogieCore.Log(LogType.Error, "Got obj update with {0} blocks", blockCount); for (UInt32 i = 0; i < blockCount; i++) { blockType = wr.ReadByte(); #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "Block #{0}/{1} Type: {2}", i + 1, blockCount, blockType); #endif switch (blockType) { case 0: // Fields update { byte mask = wr.ReadByte(); if (mask == 0x00) { break; } guid = new WoWGuid(mask, wr.ReadBytes(WoWGuid.BitCount8(mask))); UpdateMask UpdateMask = new UpdateMask(); byte bc = wr.ReadByte(); // Block Count UpdateMask.SetCount((ushort)(bc * 32)); UpdateMask.SetMask(wr.ReadBytes(bc * 4), bc); #if (DEBUG) BoogieCore.Log(LogType.Error, "Field Update! FieldCount: {0}", UpdateMask.GetCount()); #endif UInt32[] Fields = new UInt32[UpdateMask.GetCount()]; Object obj = BoogieCore.World.getObject(guid); if (obj == null) { BoogieCore.Log(LogType.Error, "Object with the guid {0} not recognized in field update.", guid.GetOldGuid()); } for (ushort x = 0; x < UpdateMask.GetCount(); x++) { if (UpdateMask.GetBit(x)) { if (obj == null) // FixMe { wr.ReadUInt32(); } else { obj.Fields[x] = wr.ReadUInt32(); } } } // Update Player Class if these are Player Fields being changed. if (obj != null) { if (obj.GUID.GetOldGuid() == BoogieCore.Player.Character.GUID) { BoogieCore.Player.updatePlayer(obj); } } break; } case 1: // Movement Update { byte mask = wr.ReadByte(); if (mask == 0x00) { break; } guid = new WoWGuid(mask, wr.ReadBytes(WoWGuid.BitCount8(mask))); #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "Got Movement update for GUID {0}", BitConverter.ToUInt64(guid.GetNewGuid(), 0)); #endif UInt32 flags2 = 0, unk3; float posX = 0; float posY = 0; float posZ = 0; float facing = 0; float walkSpeed, runSpeed, backWalkSpeed, swimSpeed, backSwimSpeed, turnRate = 0; byte flags = wr.ReadByte(); if ((flags & 0x20) >= 1) { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags & 20)"); #endif flags2 = wr.ReadUInt32(); wr.ReadByte(); // 2.3.3 unk3 = wr.ReadUInt32(); } if ((flags & 0x40) >= 1) { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags & 40)"); #endif posX = wr.ReadSingle(); posY = wr.ReadSingle(); posZ = wr.ReadSingle(); facing = wr.ReadSingle(); #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "Position - X: {0} Y: {1} Z: {2} Orient: {3} ", posX, posY, posZ, facing); #endif if ((flags2 & 0x02000000) >= 1) // player being transported { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags2 & 0x02000000)"); #endif wr.ReadUInt32(); //guidlow wr.ReadUInt32(); //guidhigh wr.ReadSingle(); //x wr.ReadSingle(); //y wr.ReadSingle(); //z wr.ReadSingle(); //o wr.ReadSingle(); // unk } } if ((flags & 0x20) >= 1) { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags & 20)"); #endif wr.ReadSingle(); //unk if ((flags2 & 0x2000) >= 1) { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags & 2000)"); #endif wr.ReadSingle(); // pos unk1 wr.ReadSingle(); // pos unk1 wr.ReadSingle(); // pos unk1 wr.ReadSingle(); // pos unk1 //BoogieCore.Log(LogType.NeworkComms, "Position 2 - X: {0} Y: {1} Z: {2} Orient: {3} ", punk1, punk2, punk3, punk1); } } if ((flags & 0x20) >= 1) { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags & 20)"); #endif walkSpeed = wr.ReadSingle(); runSpeed = wr.ReadSingle(); backWalkSpeed = wr.ReadSingle(); swimSpeed = wr.ReadSingle(); backSwimSpeed = wr.ReadSingle(); wr.ReadSingle(); //unk1 wr.ReadSingle(); //unk2 turnRate = wr.ReadSingle(); //BoogieCore.Log(LogType.NeworkComms, "Speed - (flags & 0x20)"); } if ((flags & 0x20) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 0x20)"); if ((flags2 & 0x00400000) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags2 & 0x00400000)"); UInt32 splineFlags; splineFlags = wr.ReadUInt32(); if ((splineFlags & 0x00010000) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(splineFlags & 0x00010000)"); posX = wr.ReadSingle(); posY = wr.ReadSingle(); posZ = wr.ReadSingle(); //BoogieCore.Log(LogType.NeworkComms, "Position 3 - X: {0} Y: {1} Z: {2} Orient: {3} ", posX, posY, posZ, facing); } if ((splineFlags & 0x00020000) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(splineFlags & 0x00020000)"); wr.ReadUInt64(); } if ((splineFlags & 0x00040000) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(splineFlags & 0x00040000)"); float f; f = wr.ReadSingle(); } UInt32 time1, time2, splineCount, unk4; //1.8 time1 = wr.ReadUInt32(); time2 = wr.ReadUInt32(); unk4 = wr.ReadUInt32(); splineCount = wr.ReadUInt32(); //BoogieCore.Log(LogType.NeworkComms, "splineCount = {0}", splineCount); for (UInt32 j = 0; j < splineCount + 1; j++) { posX = wr.ReadSingle(); posY = wr.ReadSingle(); posZ = wr.ReadSingle(); //BoogieCore.Log(LogType.NeworkComms, "Position 4 - X: {0} Y: {1} Z: {2} Orient: {3} ", posX, posY, posZ, facing); } } } if ((flags & 0x8) >= 1) { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags & 8)"); #endif wr.ReadUInt32(); if ((flags & 0x10) >= 1) { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags & 10)"); #endif wr.ReadUInt32(); } } else if ((flags & 0x10) >= 1) { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags & 10)"); #endif wr.ReadUInt32(); } if ((flags & 0x2) >= 1) { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags & 0x2)"); #endif wr.ReadUInt32(); } break; } case 2: // ObjCreate case 3: // ObjCreate { byte mask = wr.ReadByte(); guid = new WoWGuid(mask, wr.ReadBytes(WoWGuid.BitCount8(mask))); objTypeId = wr.ReadByte(); #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "Got Object Create Mask: 0x{0:x2} GUID: {1} ObjTypeID: {2} ", mask, BitConverter.ToUInt64(guid.GetNewGuid(), 0), objTypeId); #endif UInt32 flags2 = 0, unk3; float posX = 0; float posY = 0; float posZ = 0; float facing = 0; float walkSpeed = 0, runSpeed = 0, backWalkSpeed = 0, swimSpeed = 0, backSwimSpeed = 0, turnRate = 0; byte flags = wr.ReadByte(); if ((flags & 0x20) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 20)"); flags2 = wr.ReadUInt32(); wr.ReadByte(); // 2.3.3 unk3 = wr.ReadUInt32(); } if ((flags & 0x40) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 40)"); posX = wr.ReadSingle(); posY = wr.ReadSingle(); posZ = wr.ReadSingle(); facing = wr.ReadSingle(); //BoogieCore.Log(LogType.NeworkComms, "Position - X: {0} Y: {1} Z: {2} Orient: {3} ", posX, posY, posZ, facing); if (((flags & 0x20) >= 1 && (flags2 & 0x0200) >= 1)) // player being transported { //BoogieCore.Log(LogType.NeworkComms, "(flags & 0x20 && flags2 & 0x0200)"); wr.ReadUInt32(); //guidlow wr.ReadUInt32(); //guidhigh wr.ReadSingle(); //x wr.ReadSingle(); //y wr.ReadSingle(); //z wr.ReadSingle(); //o wr.ReadSingle(); // unk } } if ((flags & 0x20) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 20)"); wr.ReadSingle(); //unk if ((flags2 & 0x2000) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 2000)"); wr.ReadSingle(); // pos unk1 wr.ReadSingle(); // pos unk1 wr.ReadSingle(); // pos unk1 wr.ReadSingle(); // pos unk1 //BoogieCore.Log(LogType.NeworkComms, "Position 2 - X: {0} Y: {1} Z: {2} Orient: {3} ", punk1, punk2, punk3, punk1); } } if ((flags & 0x20) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 20)"); walkSpeed = wr.ReadSingle(); runSpeed = wr.ReadSingle(); backWalkSpeed = wr.ReadSingle(); swimSpeed = wr.ReadSingle(); backSwimSpeed = wr.ReadSingle(); wr.ReadSingle(); //unk1 wr.ReadSingle(); //unk2 turnRate = wr.ReadSingle(); //BoogieCore.Log(LogType.NeworkComms, "Speed - (flags & 0x20)"); } if ((flags & 0x20) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 0x20)"); if ((flags2 & 0x08000000) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags2 & 0x00400000)"); UInt32 splineFlags; splineFlags = wr.ReadUInt32(); if ((splineFlags & 0x00010000) >= 1) { BoogieCore.Log(LogType.NeworkComms, "(splineFlags & 0x00010000)"); posX = wr.ReadSingle(); posY = wr.ReadSingle(); posZ = wr.ReadSingle(); BoogieCore.Log(LogType.NeworkComms, "Position 3 - X: {0} Y: {1} Z: {2} Orient: {3} ", posX, posY, posZ, facing); } if ((splineFlags & 0x00020000) >= 1) { BoogieCore.Log(LogType.NeworkComms, "(splineFlags & 0x00020000)"); wr.ReadUInt64(); } if ((splineFlags & 0x00040000) >= 1) { BoogieCore.Log(LogType.NeworkComms, "(splineFlags & 0x00040000)"); float f; f = wr.ReadSingle(); } UInt32 time1, time2, splineCount, unk4; //1.8 time1 = wr.ReadUInt32(); time2 = wr.ReadUInt32(); unk4 = wr.ReadUInt32(); splineCount = wr.ReadUInt32(); BoogieCore.Log(LogType.NeworkComms, "splineCount = {0}", splineCount); for (UInt32 j = 0; j < splineCount + 1; j++) { posX = wr.ReadSingle(); posY = wr.ReadSingle(); posZ = wr.ReadSingle(); //BoogieCore.Log(LogType.NeworkComms, "Position 4 - X: {0} Y: {1} Z: {2} Orient: {3} ", posX, posY, posZ, facing); } } } if ((flags & 0x8) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 8)"); wr.ReadUInt32(); if ((flags & 0x10) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 10)"); wr.ReadUInt32(); } } else if ((flags & 0x10) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 10)"); wr.ReadUInt32(); } if ((flags & 0x2) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 0x2)"); wr.ReadUInt32(); } UpdateMask UpdateMask = new UpdateMask(); byte bc = wr.ReadByte(); // Block Count //BoogieCore.Log(LogType.Error, "Block Count = {0}, Mask = {1}, flags = {2}, flags2 = {3}", bc * 32, mask, flags, flags2); UpdateMask.SetCount((ushort)(bc * 32)); UpdateMask.SetMask(wr.ReadBytes(bc * 4), bc); if (UpdateMask.GetCount() > 2500) { int count = UpdateMask.GetCount(); BoogieCore.Log(LogType.Error, "Bad mask count = {0} ! aborting parse", count); return; } //BoogieCore.Log(LogType.NeworkComms, "(ObjCreate) FieldCount: {0}", UpdateMask.GetCount()); UInt32[] Fields = new UInt32[UpdateMask.GetCount()]; for (ushort x = 0; x < UpdateMask.GetCount(); x++) { if (UpdateMask.GetBit(x)) { Fields[x] = wr.ReadUInt32(); } } if (!BoogieCore.world.objectExists(guid)) // Add new Object { UInt32 entryid = Fields[(int)UpdateFields.OBJECT_FIELD_ENTRY]; Object NewObj = new Object(); NewObj.GUID = guid; NewObj.coord = new Coordinate(posX, posY, posZ, facing); NewObj.Type = flags; NewObj.Fields = Fields; NewObj.walkSpeed = walkSpeed; NewObj.runSpeed = runSpeed; NewObj.backWalkSpeed = backWalkSpeed; NewObj.swimSpeed = swimSpeed; NewObj.backSwimSpeed = backSwimSpeed; NewObj.turnRate = turnRate; BoogieCore.world.newObject(NewObj, false); //MoveUpdateTimer.Enabled = true; if (objTypeId == 4) { QueryName(guid); BoogieCore.Log(LogType.NeworkComms, "Adding new Player {0}", BitConverter.ToUInt64(guid.GetNewGuid(), 0)); } if (objTypeId == 3 || objTypeId == 5) { BoogieCore.Log(LogType.System, "Querying for name of object with an entry of {0} and type of {1}", entryid, objTypeId); if (EntryList.ContainsKey(entryid) == false && EntryQueue.ContainsKey(entryid) == false) { EntryQueue.Add(entryid, true); if (objTypeId == 3) { WoWWriter wr2 = CreatureQuery(guid, entryid); Send(wr2.ToArray()); BoogieCore.Log(LogType.NeworkComms, "Adding new Unit {0}", BitConverter.ToUInt64(guid.GetNewGuid(), 0)); } if (objTypeId == 5) { WoWWriter wr2 = GameObjectQuery(guid, entryid); Send(wr2.ToArray()); BoogieCore.Log(LogType.NeworkComms, "Adding new GameObject {0}", BitConverter.ToUInt64(guid.GetNewGuid(), 0)); } } } } else // Update Existing Object { Object updateObj = BoogieCore.world.getObject(guid); updateObj.coord = new Coordinate(posX, posY, posZ, facing); updateObj.Type = flags; updateObj.Fields = Fields; BoogieCore.world.updateObject(updateObj); } break; } case 4: // Out Of Range update { UInt32 count = wr.ReadUInt32(); for (UInt32 j = 0; j < count; j++) { byte mask = wr.ReadByte(); guid = new WoWGuid(mask, wr.ReadBytes(WoWGuid.BitCount8(mask))); BoogieCore.world.delObject(guid); } break; } } } }