From d76a8bd34ac9899d8d90dc0594b09190ac04f315 Mon Sep 17 00:00:00 2001 From: Derision Date: Sun, 17 Mar 2013 10:09:13 +0000 Subject: [PATCH] EQExtractor2: Added SQL generation support for current Live client decoder. --- utils/EQExtractor2/EQExtractor2/ChangeLog.txt | 3 + .../EQExtractor2/EQExtractor2Form1.cs | 2 +- .../EQExtractor2/PatchMarch13-2013.cs | 258 +++++++++++++++++- 3 files changed, 261 insertions(+), 2 deletions(-) diff --git a/utils/EQExtractor2/EQExtractor2/ChangeLog.txt b/utils/EQExtractor2/EQExtractor2/ChangeLog.txt index 5a9813b76..be8d241dc 100644 --- a/utils/EQExtractor2/EQExtractor2/ChangeLog.txt +++ b/utils/EQExtractor2/EQExtractor2/ChangeLog.txt @@ -1,5 +1,8 @@ EQExtractor2 Changelog. All changes since the 1.0 release. +==03/17/2013== +Derision: Added SQL generation support to current Live client decoder. + ==03/16/2013== Derision: Added decoder to support packet dumps from current Live client. SQL generation NOT SUPPORTED YET. diff --git a/utils/EQExtractor2/EQExtractor2/EQExtractor2Form1.cs b/utils/EQExtractor2/EQExtractor2/EQExtractor2Form1.cs index c2f2edeb8..7f28f792a 100644 --- a/utils/EQExtractor2/EQExtractor2/EQExtractor2Form1.cs +++ b/utils/EQExtractor2/EQExtractor2/EQExtractor2Form1.cs @@ -18,7 +18,7 @@ namespace EQExtractor2 { public partial class EQExtractor2Form1 : Form { - string Version = "EQExtractor2 Version 2.6.1 SVN"; + string Version = "EQExtractor2 Version 2.6.2 SVN"; static int PacketsSeen = 0; static long BytesRead = 0; diff --git a/utils/EQExtractor2/EQExtractor2/PatchMarch13-2013.cs b/utils/EQExtractor2/EQExtractor2/PatchMarch13-2013.cs index 7db0a720c..a4bac3b81 100644 --- a/utils/EQExtractor2/EQExtractor2/PatchMarch13-2013.cs +++ b/utils/EQExtractor2/EQExtractor2/PatchMarch13-2013.cs @@ -17,7 +17,7 @@ namespace EQExtractor2.Patches PatchConfFileName = "patch_Mar13-2013.conf"; - SupportsSQLGeneration = false; + SupportsSQLGeneration = true; } override public List GetDoors() @@ -75,5 +75,261 @@ namespace EQExtractor2.Patches } return DoorList; } + + override public List GetSpawns() + { + List ZoneSpawns = new List(); + + List SpawnPackets = GetPacketsOfType("OP_ZoneEntry", PacketDirection.ServerToClient); + + foreach (byte[] SpawnPacket in SpawnPackets) + { + ZoneEntryStruct NewSpawn = new ZoneEntryStruct(); + + ByteStream Buffer = new ByteStream(SpawnPacket); + + NewSpawn.SpawnName = Buffer.ReadString(true); + + NewSpawn.SpawnName = Utils.MakeCleanName(NewSpawn.SpawnName); + + NewSpawn.SpawnID = Buffer.ReadUInt32(); + + NewSpawn.Level = Buffer.ReadByte(); + + float UnkSize = Buffer.ReadSingle(); + + NewSpawn.IsNPC = Buffer.ReadByte(); + + UInt32 Bitfield = Buffer.ReadUInt32(); + + NewSpawn.Gender = (Bitfield & 3); + + Byte OtherData = Buffer.ReadByte(); + + Buffer.SkipBytes(8); // Skip 8 unknown bytes + + NewSpawn.DestructableString1 = ""; + NewSpawn.DestructableString2 = ""; + NewSpawn.DestructableString3 = ""; + + if ((NewSpawn.IsNPC > 0) && ((OtherData & 1) > 0)) + { + // Destructable Objects + NewSpawn.DestructableString1 = Buffer.ReadString(false); + NewSpawn.DestructableString2 = Buffer.ReadString(false); + NewSpawn.DestructableString3 = Buffer.ReadString(false); + Buffer.SkipBytes(53); + } + + if ((OtherData & 4) > 0) + { + // Auras + Buffer.ReadString(false); + Buffer.ReadString(false); + Buffer.SkipBytes(54); + } + + NewSpawn.PropCount = Buffer.ReadByte(); + + if (NewSpawn.PropCount > 0) + NewSpawn.BodyType = Buffer.ReadUInt32(); + else + NewSpawn.BodyType = 0; + + + for (int j = 1; j < NewSpawn.PropCount; ++j) + Buffer.SkipBytes(4); + + Buffer.SkipBytes(1); // Skip HP % + NewSpawn.HairColor = Buffer.ReadByte(); + NewSpawn.BeardColor = Buffer.ReadByte(); + NewSpawn.EyeColor1 = Buffer.ReadByte(); + NewSpawn.EyeColor2 = Buffer.ReadByte(); + NewSpawn.HairStyle = Buffer.ReadByte(); + NewSpawn.Beard = Buffer.ReadByte(); + + NewSpawn.DrakkinHeritage = Buffer.ReadUInt32(); + NewSpawn.DrakkinTattoo = Buffer.ReadUInt32(); + NewSpawn.DrakkinDetails = Buffer.ReadUInt32(); + + NewSpawn.EquipChest2 = Buffer.ReadByte(); + + bool UseWorn = (NewSpawn.EquipChest2 == 255); + + Buffer.SkipBytes(2); // 2 Unknown bytes; + + NewSpawn.Helm = Buffer.ReadByte(); + + NewSpawn.Size = Buffer.ReadSingle(); + + NewSpawn.Face = Buffer.ReadByte(); + + NewSpawn.WalkSpeed = Buffer.ReadSingle(); + + NewSpawn.RunSpeed = Buffer.ReadSingle(); + + NewSpawn.Race = Buffer.ReadUInt32(); + + Buffer.SkipBytes(1); // Skip Holding + + NewSpawn.Deity = Buffer.ReadUInt32(); + + Buffer.SkipBytes(8); // Skip GuildID and GuildRank + + NewSpawn.Class = Buffer.ReadByte(); + + Buffer.SkipBytes(4); // Skip PVP, Standstate, Light, Flymode + + NewSpawn.LastName = Buffer.ReadString(true); + + Buffer.SkipBytes(6); + + NewSpawn.PetOwnerID = Buffer.ReadUInt32(); + + Buffer.SkipBytes(25); + + NewSpawn.MeleeTexture1 = 0; + NewSpawn.MeleeTexture2 = 0; + + if ((NewSpawn.IsNPC == 0) || NPCType.IsPlayableRace(NewSpawn.Race)) + { + for (int ColourSlot = 0; ColourSlot < 9; ++ColourSlot) + NewSpawn.SlotColour[ColourSlot] = Buffer.ReadUInt32(); + + for (int i = 0; i < 9; ++i) + { + NewSpawn.Equipment[i] = Buffer.ReadUInt32(); + + UInt32 Equip3 = Buffer.ReadUInt32(); + + UInt32 Equip2 = Buffer.ReadUInt32(); + + UInt32 Equip1 = Buffer.ReadUInt32(); + + UInt32 Equip0 = Buffer.ReadUInt32(); + } + + if (NewSpawn.Equipment[Constants.MATERIAL_CHEST] > 0) + { + NewSpawn.EquipChest2 = (byte)NewSpawn.Equipment[Constants.MATERIAL_CHEST]; + + } + + NewSpawn.ArmorTintRed = (byte)((NewSpawn.SlotColour[Constants.MATERIAL_CHEST] >> 16) & 0xff); + + NewSpawn.ArmorTintGreen = (byte)((NewSpawn.SlotColour[Constants.MATERIAL_CHEST] >> 8) & 0xff); + + NewSpawn.ArmorTintBlue = (byte)(NewSpawn.SlotColour[Constants.MATERIAL_CHEST] & 0xff); + + if (NewSpawn.Equipment[Constants.MATERIAL_PRIMARY] > 0) + NewSpawn.MeleeTexture1 = NewSpawn.Equipment[Constants.MATERIAL_PRIMARY]; + + if (NewSpawn.Equipment[Constants.MATERIAL_SECONDARY] > 0) + NewSpawn.MeleeTexture2 = NewSpawn.Equipment[Constants.MATERIAL_SECONDARY]; + + if (UseWorn) + NewSpawn.Helm = (byte)NewSpawn.Equipment[Constants.MATERIAL_HEAD]; + else + NewSpawn.Helm = 0; + + } + else + { + // Non playable race + + Buffer.SkipBytes(20); + + NewSpawn.MeleeTexture1 = Buffer.ReadUInt32(); + Buffer.SkipBytes(16); + NewSpawn.MeleeTexture2 = Buffer.ReadUInt32(); + Buffer.SkipBytes(16); + } + + if (NewSpawn.EquipChest2 == 255) + NewSpawn.EquipChest2 = 0; + + if (NewSpawn.Helm == 255) + NewSpawn.Helm = 0; + + UInt32 Position1 = Buffer.ReadUInt32(); + + UInt32 Position2 = Buffer.ReadUInt32(); + + UInt32 Position3 = Buffer.ReadUInt32(); + + UInt32 Position4 = Buffer.ReadUInt32(); + + UInt32 Position5 = Buffer.ReadUInt32(); + + UInt32 Position6 = Buffer.ReadUInt32(); + + NewSpawn.YPos = Utils.EQ19ToFloat((Int32)((Position5) & 0x7FFFF)); + + NewSpawn.ZPos = Utils.EQ19ToFloat((Int32)(Position3) & 0x7FFFF); + + NewSpawn.XPos = Utils.EQ19ToFloat((Int32)(Position4) & 0x7FFFF); + + NewSpawn.Heading = Utils.EQ19ToFloat((Int32)(Position2 >> 13) & 0xFFF); + + if ((OtherData & 16) > 0) + { + NewSpawn.Title = Buffer.ReadString(false); + } + + if ((OtherData & 32) > 0) + { + NewSpawn.Suffix = Buffer.ReadString(false); + } + + // unknowns + Buffer.SkipBytes(8); + + NewSpawn.IsMercenary = Buffer.ReadByte(); + + Buffer.SkipBytes(54); + + Debug.Assert(Buffer.GetPosition() == Buffer.Length(), "Length mismatch while parsing zone spawns"); + + ZoneSpawns.Add(NewSpawn); + } + + return ZoneSpawns; + } + + override public PositionUpdate Decode_OP_MobUpdate(byte[] MobUpdatePacket) + { + PositionUpdate PosUpdate = new PositionUpdate(); + + ByteStream Buffer = new ByteStream(MobUpdatePacket); + + PosUpdate.SpawnID = Buffer.ReadUInt16(); + + Buffer.SkipBytes(2); + + UInt32 Word1 = Buffer.ReadUInt32(); + + UInt32 Word2 = Buffer.ReadUInt32(); + + UInt16 Word3 = Buffer.ReadUInt16(); + + PosUpdate.p.y = Utils.EQ19ToFloat((Int32)(Word1 & 0x7FFFF)); + + // Z is in the top 13 bits of Word1 and the bottom 6 of Word2 + + UInt32 ZPart1 = Word1 >> 19; // ZPart1 now has low order bits of Z in bottom 13 bits + UInt32 ZPart2 = Word2 & 0x3F; // ZPart2 now has high order bits of Z in bottom 6 bits + + ZPart2 = ZPart2 << 13; + + PosUpdate.p.z = Utils.EQ19ToFloat((Int32)(ZPart1 | ZPart2)); + + PosUpdate.p.x = Utils.EQ19ToFloat((Int32)(Word2 >> 13) & 0x7FFFF); + + PosUpdate.p.heading = Utils.EQ19ToFloat((Int32)((Word3) & 0xFFF)); + + PosUpdate.HighRes = false; + + return PosUpdate; + } } } \ No newline at end of file