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 diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index e60f759bd..778d2fdd4 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -3540,13 +3540,11 @@ void Client::Handle_OP_WearChange(const EQApplicationPacket *app) { if (app->size != sizeof(WearChange_Struct)) { cout << "Wrong size: OP_WearChange, size=" << app->size << ", expected " << sizeof(WearChange_Struct) << endl; - //DumpPacket(app); + DumpPacket(app); return; } WearChange_Struct* wc=(WearChange_Struct*)app->pBuffer; - //printf("Wearchange:\n"); - //DumpPacket(app); if(wc->spawn_id != GetID()) return; @@ -3597,7 +3595,7 @@ void Client::Handle_OP_WhoAllRequest(const EQApplicationPacket *app) { if (app->size != sizeof(Who_All_Struct)) { cout << "Wrong size on OP_WhoAll. Got: " << app->size << ", Expected: " << sizeof(Who_All_Struct) << endl; - //DumpPacket(app); + DumpPacket(app); return; } Who_All_Struct* whoall = (Who_All_Struct*) app->pBuffer; @@ -3696,7 +3694,6 @@ void Client::Handle_OP_EndLootRequest(const EQApplicationPacket *app) Entity* entity = entity_list.GetID(*((uint16*)app->pBuffer)); if (entity == 0) { - //DumpPacket(app); Message(13, "Error: OP_EndLootRequest: Corpse not found (ent = 0)"); if(GetClientVersion() >= EQClientSoD) Corpse::SendEndLootErrorPacket(this); @@ -7388,27 +7385,6 @@ void Client::Handle_OP_Emote(const EQApplicationPacket *app) memcpy(out->message, name, len_name); memcpy(&out->message[len_name], in->message, len_msg); - //cout << "######### Outgoing emote packet" << endl; - //DumpPacket(outapp); - - /* - if (target && target->IsClient()) { - entity_list.QueueCloseClients(this, outapp, false, 100, target); - - cptr = outapp->pBuffer + 2; - - // not sure if live does this or not. thought it was a nice feature, but would take a lot to - // clean up grammatical and other errors. Maybe with a regex parser... - replacestr((char *)cptr, target->GetName(), "you"); - replacestr((char *)cptr, " he", " you"); - replacestr((char *)cptr, " she", " you"); - replacestr((char *)cptr, " him", " you"); - replacestr((char *)cptr, " her", " you"); - target->CastToClient()->QueuePacket(outapp); - - } - else - */ entity_list.QueueCloseClients(this, outapp, true, 100,0,true,FilterSocials); safe_delete(outapp); @@ -7429,7 +7405,6 @@ void Client::Handle_OP_Animation(const EQApplicationPacket *app) //might verify spawn ID, but it wouldent affect anything - // an emote (i.e., waving arm to say hello) DoAnim(s->action, s->value); return; @@ -7853,7 +7828,6 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app) if(Buyer) { Trader_EndTrader(); Message(13, "You cannot be a Trader and Buyer at the same time."); - DumpPacket(app); return; } @@ -7892,7 +7866,6 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app) if(!TradeItemsValid) { Trader_EndTrader(); - DumpPacket(app); return; } @@ -7948,7 +7921,6 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app) return; } - DumpPacket(app); return; } @@ -8127,8 +8099,6 @@ void Client::Handle_OP_ClientError(const EQApplicationPacket *app) ClientError_Struct* error = (ClientError_Struct*)app->pBuffer; LogFile->write(EQEMuLog::Error, "Client error: %s", error->character_name); LogFile->write(EQEMuLog::Error, "Error message:%s", error->message); - //if (EQDEBUG>=5) - // DumpPacket(app); return; } @@ -13610,9 +13580,6 @@ void Client::Handle_OP_MercenaryHire(const EQApplicationPacket *app) uint32 merchant_id = mmrq->MercMerchantID; uint32 merc_unk1 = mmrq->MercUnk01; uint32 merc_unk2 = mmrq->MercUnk02; - - //DumpPacket(app); - if(MERC_DEBUG > 0) Message(7, "Mercenary Debug: Template ID (%i), Merchant ID (%i), Unknown1 (%i), Unknown2 (%i)", merc_template_id, merchant_id, merc_unk1, merc_unk2); @@ -13674,7 +13641,6 @@ void Client::Handle_OP_MercenarySuspendRequest(const EQApplicationPacket *app) SuspendMercenary_Struct* sm = (SuspendMercenary_Struct*) app->pBuffer; uint32 merc_suspend = sm->SuspendMerc; // Seen 30 for suspending or unsuspending - //DumpPacket(app); if(MERC_DEBUG > 0) Message(7, "Mercenary Debug: Suspend ( %i ) received.", merc_suspend); @@ -13700,9 +13666,7 @@ void Client::Handle_OP_MercenaryCommand(const EQApplicationPacket *app) uint32 merc_command = mc->MercCommand; // Seen 0 (zone in with no merc or suspended), 1 (dismiss merc), 5 (normal state), 20 (unknown), 36 (zone in with merc) int32 option = mc->Option; // Seen -1 (zone in with no merc), 0 (setting to passive stance), 1 (normal or setting to balanced stance) - //DumpPacket(app); - - if(MERC_DEBUG > 0) + if(MERC_DEBUG > 0) Message(7, "Mercenary Debug: Command %i, Option %i received.", merc_command, option); if(!RuleB(Mercs, AllowMercs)) @@ -13754,8 +13718,6 @@ void Client::Handle_OP_MercenaryDataUpdateRequest(const EQApplicationPacket *app return; } - //DumpPacket(app); - if(MERC_DEBUG > 0) Message(7, "Mercenary Debug: Data Update Request Received."); @@ -13776,8 +13738,6 @@ void Client::Handle_OP_MercenaryDismiss(const EQApplicationPacket *app) return; } - //DumpPacket(app); - uint8 Command = 0; if(app->size > 0) { @@ -13811,8 +13771,6 @@ void Client::Handle_OP_MercenaryTimerRequest(const EQApplicationPacket *app) return; } - //DumpPacket(app); - if(MERC_DEBUG > 0) Message(7, "Mercenary Debug: Timer Request received."); diff --git a/zone/client_process.cpp b/zone/client_process.cpp index cb6456f8b..87afcf62a 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -930,7 +930,6 @@ void Client::BulkSendInventoryItems() { ptr += length; } } - //DumpPacket(outapp); QueuePacket(outapp); safe_delete(outapp); } @@ -1309,8 +1308,6 @@ void Client::OPMoveCoin(const EQApplicationPacket* app) int32 *from_bucket = 0, *to_bucket = 0; Mob* trader = trade->With(); - //DumpPacket(app); - // could just do a range, but this is clearer and explicit if ( diff --git a/zone/doors.cpp b/zone/doors.cpp index c33ebf6c3..53315f413 100644 --- a/zone/doors.cpp +++ b/zone/doors.cpp @@ -148,7 +148,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger) EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct)); MoveDoor_Struct* md = (MoveDoor_Struct*)outapp->pBuffer; - //DumpPacket(app); + md->doorid = door_id; ///////////////////////////////////////////////////////////////// //used_pawn: Locked doors! Rogue friendly too =) diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 51b7743fd..acfcab8ed 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -1980,7 +1980,6 @@ void Client::SendItemPacket(int16 slot_id, const ItemInst* inst, ItemPacketType #if EQDEBUG >= 9 DumpPacket(outapp); #endif - //DumpPacket(outapp); FastQueuePacket(&outapp); } diff --git a/zone/tasks.cpp b/zone/tasks.cpp index 545c276eb..56b9de4d4 100644 --- a/zone/tasks.cpp +++ b/zone/tasks.cpp @@ -840,7 +840,6 @@ void ClientTaskState::EnableTask(int CharID, int TaskCount, int *TaskList) { _log(TASKS__UPDATE, "New enabled task list "); for(unsigned int i=0; iunknown5 = 0; // 0 for task complete or failed. _log(TASKS__UPDATE, "TaskFailed"); - //DumpPacket(outapp); fflush(stdout); + _pkt(TASKS__PACKETS, outapp); QueuePacket(outapp); diff --git a/zone/tradeskills.cpp b/zone/tradeskills.cpp index 48d097d9a..30851b038 100644 --- a/zone/tradeskills.cpp +++ b/zone/tradeskills.cpp @@ -517,7 +517,7 @@ void Object::HandleAutoCombine(Client* user, const RecipeAutoCombine_Struct* rac outp->reply_code = 0x00000000; //success for finding it... user->QueuePacket(outapp); - //DumpPacket(outapp); + safe_delete(outapp); @@ -665,7 +665,6 @@ void Client::TradeskillSearchResults(const char *query, unsigned long qlen, reply->trivial = trivial; strn0cpy(reply->recipe_name, name, sizeof(reply->recipe_name)); - //DumpPacket(outapp); FastQueuePacket(&outapp); } mysql_free_result(result); @@ -1520,4 +1519,4 @@ bool Client::CanIncreaseTradeskill(SkillType tradeskill) { break; //Other skills unchecked and ability to increase assumed true } return true; -} \ No newline at end of file +} diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 241fc3c1d..79aee5662 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -1748,7 +1748,7 @@ bool ZoneDatabase::SaveMerc(Merc *merc) { } } - safe_delete(Query); + safe_delete_array(Query); if(!errorMessage.empty() || (Result && affectedRows != 1)) { if(owner && !errorMessage.empty()) @@ -1917,12 +1917,16 @@ bool ZoneDatabase::DeleteMerc(uint32 merc_id) { else TempCounter++; + safe_delete_array(Query); + if(!database.RunQuery(Query, MakeAnyLenString(&Query, "DELETE FROM mercs WHERE MercID = '%u'", merc_id), TempErrorMessageBuffer)) { errorMessage = std::string(TempErrorMessageBuffer); } else TempCounter++; + safe_delete_array(Query); + if(TempCounter == 2) Result = true; }