EQExtractor2: Added SQL generation support for current Live client decoder.

This commit is contained in:
Derision 2013-03-17 10:09:13 +00:00
parent 7c264ad097
commit d76a8bd34a
3 changed files with 261 additions and 2 deletions

View File

@ -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.

View File

@ -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;

View File

@ -17,7 +17,7 @@ namespace EQExtractor2.Patches
PatchConfFileName = "patch_Mar13-2013.conf";
SupportsSQLGeneration = false;
SupportsSQLGeneration = true;
}
override public List<Door> GetDoors()
@ -75,5 +75,261 @@ namespace EQExtractor2.Patches
}
return DoorList;
}
override public List<ZoneEntryStruct> GetSpawns()
{
List<ZoneEntryStruct> ZoneSpawns = new List<ZoneEntryStruct>();
List<byte[]> 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;
}
}
}