From 735b4181facad352f845dc15ed3ef3bdc786d241 Mon Sep 17 00:00:00 2001 From: SecretsOTheP Date: Fri, 15 Mar 2013 03:27:45 -0400 Subject: [PATCH 1/3] Test --- zone/client.cpp | 106 ++++++++++++++++++++++++----------------- zone/client_packet.cpp | 77 ++++++++++++++++-------------- zone/merc.cpp | 11 ++++- 3 files changed, 113 insertions(+), 81 deletions(-) diff --git a/zone/client.cpp b/zone/client.cpp index 155047aa6..70126a0a6 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -1472,7 +1472,7 @@ void Client::SendSound(){//Makes a sound. memset(&x[64],0xffffffff,sizeof(uint32)); memcpy(outapp->pBuffer,x,outapp->size); QueuePacket(outapp); - DumpPacket(outapp); + //DumpPacket(outapp); safe_delete(outapp); } @@ -7137,68 +7137,76 @@ void Client::SendMercPersonalInfo() if (GetClientVersion() >= EQClientRoF) { - MercenaryDataUpdate_Struct* mdus = new MercenaryDataUpdate_Struct; - MercTemplate *mercData = &zone->merc_templates[GetMercInfo().MercTemplateID]; if (mercData) { + int i = 0; + int stancecount = 0; + stancecount += zone->merc_stance_list[GetMercInfo().MercTemplateID].size(); + + if (mercCount > 0) + { + EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryDataUpdate, sizeof(MercenaryDataUpdate_Struct) + (mercTypeCount * sizeof(MercenaryData_Struct)) + stancecount * sizeof(MercenaryStance_Struct)); + MercenaryDataUpdate_Struct* mdus = (MercenaryDataUpdate_Struct*)outapp->pBuffer; mdus->MercStatus = 0; mdus->MercCount = mercCount; - if (mercCount > 0) + mdus->MercData = new MercenaryData_Struct[mercCount]; + mdus->MercData[i].MercID = mercData->MercTemplateID; + mdus->MercData[i].MercType = mercData->MercType; + mdus->MercData[i].MercSubType = mercData->MercSubType; + mdus->MercData[i].PurchaseCost = Merc::CalcPurchaseCost(mercData->MercTemplateID, GetLevel(), 0); + mdus->MercData[i].UpkeepCost = Merc::CalcUpkeepCost(mercData->MercTemplateID, GetLevel(), 0); + mdus->MercData[i].Status = 0; + mdus->MercData[i].AltCurrencyCost = Merc::CalcPurchaseCost(mercData->MercTemplateID, GetLevel(), altCurrentType); + mdus->MercData[i].AltCurrencyUpkeep = Merc::CalcPurchaseCost(mercData->MercTemplateID, GetLevel(), altCurrentType); + mdus->MercData[i].AltCurrencyType = altCurrentType; + mdus->MercData[i].MercUnk01 = 0; + mdus->MercData[i].TimeLeft = GetMercInfo().MercTimerRemaining; //GetMercTimer().GetRemainingTime(); + mdus->MercData[i].MerchantSlot = i + 1; + mdus->MercData[i].MercUnk02 = 1; + mdus->MercData[i].StanceCount = zone->merc_stance_list[mercData->MercTemplateID].size(); + mdus->MercData[i].MercUnk03 = 0; + mdus->MercData[i].MercUnk04 = 1; + strn0cpy(mdus->MercData[i].MercName, GetMercInfo().merc_name , sizeof(mdus->MercData[i].MercName)); + uint32 stanceindex = 0; + if (mdus->MercData[i].StanceCount != 0) { - mdus->MercData = new MercenaryData_Struct[mercCount]; - mdus->MercData[i].MercID = mercData->MercTemplateID; - mdus->MercData[i].MercType = mercData->MercType; - mdus->MercData[i].MercSubType = mercData->MercSubType; - mdus->MercData[i].PurchaseCost = Merc::CalcPurchaseCost(mercData->MercTemplateID, GetLevel(), 0); - mdus->MercData[i].UpkeepCost = Merc::CalcUpkeepCost(mercData->MercTemplateID, GetLevel(), 0); - mdus->MercData[i].Status = 0; - mdus->MercData[i].AltCurrencyCost = Merc::CalcPurchaseCost(mercData->MercTemplateID, GetLevel(), altCurrentType); - mdus->MercData[i].AltCurrencyUpkeep = Merc::CalcPurchaseCost(mercData->MercTemplateID, GetLevel(), altCurrentType); - mdus->MercData[i].AltCurrencyType = altCurrentType; - mdus->MercData[i].MercUnk01 = 0; - mdus->MercData[i].TimeLeft = GetMercInfo().MercTimerRemaining; //GetMercTimer().GetRemainingTime(); - mdus->MercData[i].MerchantSlot = i + 1; - mdus->MercData[i].MercUnk02 = 1; - mdus->MercData[i].StanceCount = zone->merc_stance_list[mercData->MercTemplateID].size(); - mdus->MercData[i].MercUnk03 = 0; - mdus->MercData[i].MercUnk04 = 1; - strn0cpy(mdus->MercData[i].MercName, GetMercInfo().merc_name , sizeof(mdus->MercData[i].MercName)); - uint32 stanceindex = 0; - if (mdus->MercData[i].StanceCount != 0) + mdus->MercData[i].Stances = new MercenaryStance_Struct[mdus->MercData[i].StanceCount]; + list::iterator iter = zone->merc_stance_list[mercData->MercTemplateID].begin(); + while(iter != zone->merc_stance_list[mercData->MercTemplateID].end()) { - mdus->MercData[i].Stances = new MercenaryStance_Struct[mdus->MercData[i].StanceCount]; - list::iterator iter = zone->merc_stance_list[mercData->MercTemplateID].begin(); - while(iter != zone->merc_stance_list[mercData->MercTemplateID].end()) - { - mdus->MercData[i].Stances[stanceindex].StanceIndex = stanceindex; - mdus->MercData[i].Stances[stanceindex].Stance = (iter->StanceID); - stanceindex++; - iter++; - } + mdus->MercData[i].Stances[stanceindex].StanceIndex = stanceindex; + mdus->MercData[i].Stances[stanceindex].Stance = (iter->StanceID); + stanceindex++; + iter++; } + } - mdus->MercData[i].MercUnk05 = 1; - - EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryDataUpdate, 1); //Packet sizes are handled by the encoder. - outapp->pBuffer = (unsigned char*)mdus; - //DumpPacket(outapp); - FastQueuePacket(&outapp); + mdus->MercData[i].MercUnk05 = 1; + //DumpPacket(outapp); + FastQueuePacket(&outapp); + return; } } } else { - MercenaryMerchantList_Struct* mml = new MercenaryMerchantList_Struct; + int stancecount = 0; + stancecount += zone->merc_stance_list[GetMercInfo().MercTemplateID].size(); + + EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryDataResponse, sizeof(MercenaryMerchantList_Struct) + (mercTypeCount * sizeof(MercenaryGrade_Struct)) + (mercCount * sizeof(MercenaryListEntry_Struct)) + stancecount * sizeof(MercenaryStance_Struct)); //Packet sizes are handled by the encoder. + MercenaryMerchantList_Struct* mml = (MercenaryMerchantList_Struct*)outapp->pBuffer; MercTemplate *mercData = &zone->merc_templates[GetMercInfo().MercTemplateID]; + if(mercData) { if(mercTypeCount > 0) { mml->MercTypeCount = mercTypeCount; //We only should have one merc entry. mml->MercGrades = new MercenaryGrade_Struct[mercTypeCount]; // DBStringID for Type + mml->MercGrades[0].GradeCountEntry = 1; } mml->MercCount = mercCount; if(mercCount > 0) @@ -7234,17 +7242,25 @@ void Client::SendMercPersonalInfo() iter++; } } - - EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryDataResponse, 1); //Packet sizes are handled by the encoder. - outapp->pBuffer = (unsigned char*)mml; - // DumpPacket(outapp); FastQueuePacket(&outapp); } + else + { + safe_delete(outapp); + SendMercMerchantResponsePacket(0); + return; + } if (GetClientVersion() == EQClientSoD) { SendMercMerchantResponsePacket(0); } } + else + { + safe_delete(outapp); + SendMercMerchantResponsePacket(0); + return; + } } } @@ -7256,7 +7272,7 @@ void Client::SendClearMercInfo() nmhs->MercCount = 0; nmhs->MercID = 1; - DumpPacket(outapp); + //DumpPacket(outapp); FastQueuePacket(&outapp); } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index f4adef8ce..3d1bff42a 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -13496,8 +13496,6 @@ void Client::Handle_OP_MercenaryDataRequest(const EQApplicationPacket *app) //send info about your current merc(s) } - DumpPacket(app); - if(!RuleB(Mercs, AllowMercs)) { return; } @@ -13515,19 +13513,28 @@ void Client::Handle_OP_MercenaryDataRequest(const EQApplicationPacket *app) return; } - MercenaryMerchantList_Struct* mml = new MercenaryMerchantList_Struct; - mercTypeCount = tar->GetNumMercTypes(GetClientVersion()); mercCount = tar->GetNumMercs(GetClientVersion()); - std::list mercTypeList = tar->GetMercTypesList(GetClientVersion()); std::list mercDataList = tar->GetMercsList(GetClientVersion()); - mml->MercTypeCount = mercTypeCount; int i = 0; + int StanceCount = 0; + for(std::list::iterator mercListItr = mercDataList.begin(); mercListItr != mercDataList.end(); mercListItr++) + { + list::iterator siter = zone->merc_stance_list[mercListItr->MercTemplateID].begin(); + for(siter = zone->merc_stance_list[mercListItr->MercTemplateID].begin(); siter != zone->merc_stance_list[mercListItr->MercTemplateID].end(); siter++) + { + StanceCount++; + } + } + EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryDataResponse, sizeof(MercenaryMerchantList_Struct) + (mercTypeCount * sizeof(MercenaryGrade_Struct)) + (mercCount * sizeof(MercenaryListEntry_Struct)) + (StanceCount * sizeof(MercenaryStance_Struct))); + MercenaryMerchantList_Struct* mml = (MercenaryMerchantList_Struct*)outapp->pBuffer; + + mml->MercTypeCount = mercTypeCount; if(mercTypeCount > 0) { mml->MercGrades = new MercenaryGrade_Struct[mercTypeCount]; @@ -13540,50 +13547,50 @@ void Client::Handle_OP_MercenaryDataRequest(const EQApplicationPacket *app) if(mercCount > 0) { - mml->Mercs = new MercenaryListEntry_Struct[mercCount]; i = 0; - for(std::list::iterator mercListItr = mercDataList.begin(); mercListItr != mercDataList.end(); mercListItr++) + mml->Mercs = new MercenaryListEntry_Struct[mercCount]; + for(std::list::iterator mercListIter = mercDataList.begin(); mercListIter != mercDataList.end(); mercListIter++) { - mml->Mercs[i].MercID = mercListItr->MercTemplateID; - mml->Mercs[i].MercType = mercListItr->MercType; - mml->Mercs[i].MercSubType = mercListItr->MercSubType; - mml->Mercs[i].PurchaseCost = RuleB(Mercs, ChargeMercPurchaseCost) ? Merc::CalcPurchaseCost(mercListItr->MercTemplateID, GetLevel(), 0): 0; - mml->Mercs[i].UpkeepCost = RuleB(Mercs, ChargeMercUpkeepCost) ? Merc::CalcUpkeepCost(mercListItr->MercTemplateID, GetLevel(), 0): 0; + mml->Mercs[i].MercID = mercListIter->MercTemplateID; + mml->Mercs[i].MercType = mercListIter->MercType; + mml->Mercs[i].MercSubType = mercListIter->MercSubType; + mml->Mercs[i].PurchaseCost = RuleB(Mercs, ChargeMercPurchaseCost) ? Merc::CalcPurchaseCost(mercListIter->MercTemplateID, GetLevel(), 0): 0; + mml->Mercs[i].UpkeepCost = RuleB(Mercs, ChargeMercUpkeepCost) ? Merc::CalcUpkeepCost(mercListIter->MercTemplateID, GetLevel(), 0): 0; mml->Mercs[i].Status = 0; - mml->Mercs[i].AltCurrencyCost = RuleB(Mercs, ChargeMercPurchaseCost) ? Merc::CalcPurchaseCost(mercListItr->MercTemplateID, GetLevel(), altCurrentType): 0; - mml->Mercs[i].AltCurrencyUpkeep = RuleB(Mercs, ChargeMercUpkeepCost) ? Merc::CalcUpkeepCost(mercListItr->MercTemplateID, GetLevel(), altCurrentType): 0; + mml->Mercs[i].AltCurrencyCost = RuleB(Mercs, ChargeMercPurchaseCost) ? Merc::CalcPurchaseCost(mercListIter->MercTemplateID, GetLevel(), altCurrentType): 0; + mml->Mercs[i].AltCurrencyUpkeep = RuleB(Mercs, ChargeMercUpkeepCost) ? Merc::CalcUpkeepCost(mercListIter->MercTemplateID, GetLevel(), altCurrentType): 0; mml->Mercs[i].AltCurrencyType = altCurrentType; mml->Mercs[i].MercUnk01 = 0; mml->Mercs[i].TimeLeft = -1; mml->Mercs[i].MerchantSlot = i + 1; mml->Mercs[i].MercUnk02 = 1; - mml->Mercs[i].StanceCount = zone->merc_stance_list[mercListItr->MercTemplateID].size(); + int mercStanceCount = 0; + list::iterator iter = zone->merc_stance_list[mercListIter->MercTemplateID].begin(); + for(iter = zone->merc_stance_list[mercListIter->MercTemplateID].begin(); iter != zone->merc_stance_list[mercListIter->MercTemplateID].end(); iter++) + { + mercStanceCount++; + } + mml->Mercs[i].StanceCount = mercStanceCount; mml->Mercs[i].MercUnk03 = 519044964; mml->Mercs[i].MercUnk04 = 1; //mml->Mercs[i].MercName; int stanceindex = 0; - if(mml->Mercs[i].StanceCount != 0) + if(mercStanceCount > 0) { - mml->Mercs[i].Stances = new MercenaryStance_Struct[mml->Mercs[i].StanceCount]; - list::iterator iter = zone->merc_stance_list[mercListItr->MercTemplateID].begin(); - while(iter != zone->merc_stance_list[mercListItr->MercTemplateID].end()) + mml->Mercs[i].Stances = new MercenaryStance_Struct[mercStanceCount]; + list::iterator iter2 = zone->merc_stance_list[mercListIter->MercTemplateID].begin(); + while(iter2 != zone->merc_stance_list[mercListIter->MercTemplateID].end()) { mml->Mercs[i].Stances[stanceindex].StanceIndex = stanceindex; - mml->Mercs[i].Stances[stanceindex].Stance = (iter->StanceID); + mml->Mercs[i].Stances[stanceindex].Stance = (iter2->StanceID); stanceindex++; - iter++; + iter2++; } } i++; } } - - - EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryDataResponse, 1); //Packet sizes are handled by the encoder. - outapp->pBuffer = (unsigned char*)mml; - // DumpPacket(outapp); FastQueuePacket(&outapp); - } } @@ -13605,7 +13612,7 @@ void Client::Handle_OP_MercenaryHire(const EQApplicationPacket *app) uint32 merc_unk1 = mmrq->MercUnk01; uint32 merc_unk2 = mmrq->MercUnk02; - DumpPacket(app); + //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); @@ -13668,7 +13675,7 @@ 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); + //DumpPacket(app); if(MERC_DEBUG > 0) Message(7, "Mercenary Debug: Suspend ( %i ) received.", merc_suspend); @@ -13699,7 +13706,7 @@ void Client::Handle_OP_MercenaryCommand(const EQApplicationPacket *app) GetMercInfo().State = option; } - DumpPacket(app); + //DumpPacket(app); if(MERC_DEBUG > 0) Message(7, "Mercenary Debug: Command %i, Option %i received.", merc_command, option); @@ -13723,7 +13730,7 @@ void Client::Handle_OP_MercenaryDataUpdateRequest(const EQApplicationPacket *app return; } - DumpPacket(app); + //DumpPacket(app); if(MERC_DEBUG > 0) Message(7, "Mercenary Debug: Data Update Request Received."); @@ -13745,7 +13752,7 @@ void Client::Handle_OP_MercenaryDismiss(const EQApplicationPacket *app) return; } - DumpPacket(app); + //DumpPacket(app); uint8 Command = 0; if(app->size > 0) @@ -13765,7 +13772,7 @@ void Client::Handle_OP_MercenaryDismiss(const EQApplicationPacket *app) merc->Dismiss(); } - // Unsure if there is a server response to this packet + SendMercMerchantResponsePacket(10); } @@ -13780,7 +13787,7 @@ void Client::Handle_OP_MercenaryTimerRequest(const EQApplicationPacket *app) return; } - DumpPacket(app); + //DumpPacket(app); if(MERC_DEBUG > 0) Message(7, "Mercenary Debug: Timer Request received."); diff --git a/zone/merc.cpp b/zone/merc.cpp index 267cbfdda..18722cf52 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -5123,7 +5123,7 @@ bool Merc::Unsuspend(bool setMaxStats) { if(!mercOwner->IsGrouped()) { Group *g = new Group(mercOwner); - if(AddMercToGroup(this, g)) + if(g && AddMercToGroup(this, g)) { entity_list.AddGroup(g); database.SetGroupLeaderName(g->GetID(), mercOwner->GetName()); @@ -5134,6 +5134,15 @@ bool Merc::Unsuspend(bool setMaxStats) { loaded = true; } + else + { + if(MERC_DEBUG > 0) + mercOwner->Message(7, "Mercenary failed to join the group - Suspending"); + + Suspend(); + safe_delete(g); + return false; + } } else if (AddMercToGroup(this, mercOwner->GetGroup())) { From b8170df4986b983673a843c7217a7ecd9139bb2f Mon Sep 17 00:00:00 2001 From: SecretsOTheP Date: Sun, 17 Mar 2013 06:18:32 -0400 Subject: [PATCH 2/3] Hopefully fixed that pesky merc memleak and cleaned up mercs a tad. --- common/eq_packet_structs.h | 36 ++++++++++++++++++++++++-------- common/patches/RoF.cpp | 2 +- common/patches/SoD.cpp | 2 +- common/patches/Underfoot.cpp | 2 +- zone/client.cpp | 40 +++++++++++++++++++++++------------- zone/client_packet.cpp | 10 ++++----- zone/merc.cpp | 10 --------- zone/worldserver.cpp | 4 +--- 8 files changed, 63 insertions(+), 43 deletions(-) diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index 7b8ca52b0..1be8eddc5 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -27,6 +27,9 @@ //#include "../common/item_struct.h" static const uint32 BUFF_COUNT = 25; +static const uint32 MAX_MERC = 100; +static const uint32 MAX_MERC_GRADES = 10; +static const uint32 MAX_MERC_STANCES = 10; static const uint32 BLOCKED_BUFF_COUNT = 20; #include "eq_constants.h" @@ -4871,11 +4874,28 @@ struct ItemPreview_Struct /*026*/ uint8 unknown026[54]; }; -//Not an EQ packet, just a single int for the mercenary merchant structure. -struct MercenaryGrade_Struct { -uint32 GradeCountEntry; +// Used by specific packets +struct MercenaryList_Struct { +/*0000*/ uint32 MercID; // ID unique to each type of mercenary (probably a DB id) +/*0004*/ uint32 MercType; // From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300) +/*0008*/ uint32 MercSubType; // From dbstr_us.txt - 330020105^23^Race: Guktan
Type: Healer
Confidence: High
Proficiency: Apprentice, Tier V... +/*0012*/ uint32 PurchaseCost; // Purchase Cost (in gold) +/*0016*/ uint32 UpkeepCost; // Upkeep Cost (in gold) +/*0020*/ uint32 Status; // Required Account Status (Free = 0, Silver = 1, Gold = 2) at merchants - Seen 0 (suspended) or 1 (unsuspended) on hired mercs ? +/*0024*/ uint32 AltCurrencyCost; // Alternate Currency Purchase Cost? (all seen costs show N/A Bayle Mark) - Seen 0 +/*0028*/ uint32 AltCurrencyUpkeep; // Alternate Currency Upkeep Cost? (all seen costs show 1 Bayle Mark) - Seen 1 +/*0032*/ uint32 AltCurrencyType; // Alternate Currency Type? - 19^17^Bayle Mark^0 - Seen 19 +/*0036*/ uint8 MercUnk01; // Unknown (always see 0) +/*0037*/ int32 TimeLeft; // Unknown (always see -1 at merchant) - Seen 900000 (15 minutes in ms for newly hired merc) +/*0041*/ uint32 MerchantSlot; // Merchant Slot? Increments, but not always by 1 - May be for Merc Window Options (Seen 5, 36, 1 for active mercs)? +/*0045*/ uint32 MercUnk02; // Unknown (normally see 1, but sometimes 2 or 0) +/*0049*/ uint32 StanceCount; // Iterations of MercenaryStance_Struct - Normally 2 to 4 seen +/*0053*/ int32 MercUnk03; // Unknown (always 0 at merchant) - Seen on active merc: 93 a4 03 77, b8 ed 2f 26, 88 d5 8b c3, and 93 a4 ad 77 +/*0057*/ uint8 MercUnk04; // Seen 1 +/*0058*/ char MercName[1]; // Null Terminated Mercenary Name (00 at merchants) }; + // Used by MercenaryMerchantList_Struct struct MercenaryListEntry_Struct { /*0000*/ uint32 MercID; // ID unique to each type of mercenary (probably a DB id) @@ -4895,7 +4915,7 @@ struct MercenaryListEntry_Struct { /*0053*/ int32 MercUnk03; // Unknown (always 0 at merchant) - Seen on active merc: 93 a4 03 77, b8 ed 2f 26, 88 d5 8b c3, and 93 a4 ad 77 /*0057*/ uint8 MercUnk04; // Seen 1 /*0058*/ char MercName[1]; // Null Terminated Mercenary Name (00 at merchants) -/*0000*/ MercenaryStance_Struct* Stances; // Count Varies, but hard set to 5 max for now - From dbstr_us.txt - 1^24^Passive^0, 2^24^Balanced^0, etc (1 to 9 as of April 2012) +/*0000*/ MercenaryStance_Struct Stances[MAX_MERC_STANCES]; // Count Varies, but hard set to 5 max for now - From dbstr_us.txt - 1^24^Passive^0, 2^24^Balanced^0, etc (1 to 9 as of April 2012) }; // [OPCode: 0x27ac OP_MercenaryDataResponse] On Live as of April 2 2012 [Server->Client] @@ -4903,9 +4923,9 @@ struct MercenaryListEntry_Struct { // Sent by the server when browsing the Mercenary Merchant struct MercenaryMerchantList_Struct { /*0000*/ uint32 MercTypeCount; // Number of Merc Types to follow -/*0004*/ MercenaryGrade_Struct* MercGrades; // Count varies, but hard set to 3 max for now - From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300) +/*0004*/ uint32 MercGrades[MAX_MERC_GRADES]; // Count varies, but hard set to 3 max for now - From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300) /*0016*/ uint32 MercCount; // Number of MercenaryInfo_Struct to follow -/*0020*/ MercenaryListEntry_Struct* Mercs; // Data for individual mercenaries in the Merchant List +/*0020*/ MercenaryListEntry_Struct Mercs[MAX_MERC]; // Data for individual mercenaries in the Merchant List }; // [OPCode: 0x4dd9 OP_MercenaryDataRequest] On Live as of April 2 2012 [Client->Server] @@ -4935,7 +4955,7 @@ struct MercenaryData_Struct { /*0053*/ int32 MercUnk03; // Unknown (always 0 at merchant) - Seen on active merc: 93 a4 03 77, b8 ed 2f 26, 88 d5 8b c3, and 93 a4 ad 77 /*0057*/ uint8 MercUnk04; // Seen 1 /*0058*/ char MercName[64]; // Null Terminated Mercenary Name (00 at merchants) -/*0000*/ MercenaryStance_Struct* Stances; // Count Varies, but hard set to 2 for now - From dbstr_us.txt - 1^24^Passive^0, 2^24^Balanced^0, etc (1 to 9 as of April 2012) +/*0000*/ MercenaryStance_Struct Stances[MAX_MERC_STANCES]; // Count Varies, but hard set to 2 for now - From dbstr_us.txt - 1^24^Passive^0, 2^24^Balanced^0, etc (1 to 9 as of April 2012) /*0000*/ uint32 MercUnk05; // Seen 1 - Extra Merc Data field that differs from MercenaryListEntry_Struct // MercUnk05 may be a field that is at the end of the packet only, even if multiple mercs are listed (haven't seen examples of multiple mercs owned at once) }; @@ -4947,7 +4967,7 @@ struct MercenaryData_Struct { struct MercenaryDataUpdate_Struct { /*0000*/ int32 MercStatus; // Seen 0 with merc and -1 with no merc hired /*0004*/ uint32 MercCount; // Seen 1 with 1 merc hired and 0 with no merc hired -/*0008*/ MercenaryData_Struct* MercData; // Data for individual mercenaries in the Merchant List +/*0008*/ MercenaryData_Struct MercData[MAX_MERC]; // Data for individual mercenaries in the Merchant List }; // [OPCode: 0x6537] On Live as of April 2 2012 [Server->Client] diff --git a/common/patches/RoF.cpp b/common/patches/RoF.cpp index 0f5bcaa3f..1c56e27cd 100644 --- a/common/patches/RoF.cpp +++ b/common/patches/RoF.cpp @@ -2099,7 +2099,7 @@ ENCODE(OP_MercenaryDataResponse) { for(r = 0; r < emu->MercTypeCount; r++) { - VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->MercGrades[r].GradeCountEntry); + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->MercGrades[r]); } VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->MercCount); diff --git a/common/patches/SoD.cpp b/common/patches/SoD.cpp index 685595737..99e6cd8c0 100644 --- a/common/patches/SoD.cpp +++ b/common/patches/SoD.cpp @@ -1289,7 +1289,7 @@ ENCODE(OP_MercenaryDataResponse) { { if(emu->MercTypeCount > 0) { - VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->MercGrades[r].GradeCountEntry); + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->MercGrades[r]); } } VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->MercCount); diff --git a/common/patches/Underfoot.cpp b/common/patches/Underfoot.cpp index 656decd55..0da4f60c9 100644 --- a/common/patches/Underfoot.cpp +++ b/common/patches/Underfoot.cpp @@ -1297,7 +1297,7 @@ ENCODE(OP_MercenaryDataResponse) { for(r = 0; r < emu->MercTypeCount; r++) { - VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->MercGrades[r].GradeCountEntry); + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->MercGrades[r]); } VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->MercCount); diff --git a/zone/client.cpp b/zone/client.cpp index e8f661d78..425309810 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -1476,7 +1476,6 @@ void Client::SendSound(){//Makes a sound. memset(&x[64],0xffffffff,sizeof(uint32)); memcpy(outapp->pBuffer,x,outapp->size); QueuePacket(outapp); - //DumpPacket(outapp); safe_delete(outapp); } @@ -7149,13 +7148,17 @@ void Client::SendMercPersonalInfo() int stancecount = 0; stancecount += zone->merc_stance_list[GetMercInfo().MercTemplateID].size(); - if (mercCount > 0) + if(stancecount > MAX_MERC_STANCES || mercCount > MAX_MERC || mercTypeCount > MAX_MERC_GRADES) { - EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryDataUpdate, sizeof(MercenaryDataUpdate_Struct) + (mercTypeCount * sizeof(MercenaryData_Struct)) + stancecount * sizeof(MercenaryStance_Struct)); + SendMercMerchantResponsePacket(0); + return; + } + if (mercCount > 0 && mercCount) + { + EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryDataUpdate, sizeof(MercenaryDataUpdate_Struct)); MercenaryDataUpdate_Struct* mdus = (MercenaryDataUpdate_Struct*)outapp->pBuffer; mdus->MercStatus = 0; mdus->MercCount = mercCount; - mdus->MercData = new MercenaryData_Struct[mercCount]; mdus->MercData[i].MercID = mercData->MercTemplateID; mdus->MercData[i].MercType = mercData->MercType; mdus->MercData[i].MercSubType = mercData->MercSubType; @@ -7176,7 +7179,6 @@ void Client::SendMercPersonalInfo() uint32 stanceindex = 0; if (mdus->MercData[i].StanceCount != 0) { - mdus->MercData[i].Stances = new MercenaryStance_Struct[mdus->MercData[i].StanceCount]; list::iterator iter = zone->merc_stance_list[mercData->MercTemplateID].begin(); while(iter != zone->merc_stance_list[mercData->MercTemplateID].end()) { @@ -7188,7 +7190,6 @@ void Client::SendMercPersonalInfo() } mdus->MercData[i].MercUnk05 = 1; - //DumpPacket(outapp); FastQueuePacket(&outapp); return; } @@ -7199,7 +7200,16 @@ void Client::SendMercPersonalInfo() int stancecount = 0; stancecount += zone->merc_stance_list[GetMercInfo().MercTemplateID].size(); - EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryDataResponse, sizeof(MercenaryMerchantList_Struct) + (mercTypeCount * sizeof(MercenaryGrade_Struct)) + (mercCount * sizeof(MercenaryListEntry_Struct)) + stancecount * sizeof(MercenaryStance_Struct)); //Packet sizes are handled by the encoder. + if(mercCount > MAX_MERC || mercTypeCount > MAX_MERC_GRADES) + { + if (GetClientVersion() == EQClientSoD) + { + SendMercMerchantResponsePacket(0); + } + return; + } + + EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryDataResponse, sizeof(MercenaryMerchantList_Struct)); MercenaryMerchantList_Struct* mml = (MercenaryMerchantList_Struct*)outapp->pBuffer; MercTemplate *mercData = &zone->merc_templates[GetMercInfo().MercTemplateID]; @@ -7209,13 +7219,12 @@ void Client::SendMercPersonalInfo() if(mercTypeCount > 0) { mml->MercTypeCount = mercTypeCount; //We only should have one merc entry. - mml->MercGrades = new MercenaryGrade_Struct[mercTypeCount]; // DBStringID for Type - mml->MercGrades[0].GradeCountEntry = 1; + mml->MercGrades[i] = 1; } mml->MercCount = mercCount; if(mercCount > 0) { - mml->Mercs = new MercenaryListEntry_Struct[mercCount]; + mml->Mercs[i].MercID = mercData->MercTemplateID; mml->Mercs[i].MercType = mercData->MercType; mml->Mercs[i].MercSubType = mercData->MercSubType; @@ -7236,7 +7245,6 @@ void Client::SendMercPersonalInfo() int stanceindex = 0; if(mml->Mercs[i].StanceCount != 0) { - mml->Mercs[i].Stances = new MercenaryStance_Struct[mml->Mercs[i].StanceCount]; list::iterator iter = zone->merc_stance_list[mercData->MercTemplateID].begin(); while(iter != zone->merc_stance_list[mercData->MercTemplateID].end()) { @@ -7251,7 +7259,10 @@ void Client::SendMercPersonalInfo() else { safe_delete(outapp); - SendMercMerchantResponsePacket(0); + if (GetClientVersion() == EQClientSoD) + { + SendMercMerchantResponsePacket(0); + } return; } if (GetClientVersion() == EQClientSoD) @@ -7262,7 +7273,10 @@ void Client::SendMercPersonalInfo() else { safe_delete(outapp); + if (GetClientVersion() == EQClientSoD) + { SendMercMerchantResponsePacket(0); + } return; } } @@ -7275,8 +7289,6 @@ void Client::SendClearMercInfo() nmhs->MercStatus = -1; nmhs->MercCount = 0; nmhs->MercID = 1; - - //DumpPacket(outapp); FastQueuePacket(&outapp); } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 1949c7c59..e60f759bd 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -13515,6 +13515,9 @@ void Client::Handle_OP_MercenaryDataRequest(const EQApplicationPacket *app) mercTypeCount = tar->GetNumMercTypes(GetClientVersion()); mercCount = tar->GetNumMercs(GetClientVersion()); + if(mercCount > MAX_MERC) + return; + std::list mercTypeList = tar->GetMercTypesList(GetClientVersion()); std::list mercDataList = tar->GetMercsList(GetClientVersion()); @@ -13530,15 +13533,14 @@ void Client::Handle_OP_MercenaryDataRequest(const EQApplicationPacket *app) } } - EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryDataResponse, sizeof(MercenaryMerchantList_Struct) + (mercTypeCount * sizeof(MercenaryGrade_Struct)) + (mercCount * sizeof(MercenaryListEntry_Struct)) + (StanceCount * sizeof(MercenaryStance_Struct))); + EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryDataResponse, sizeof(MercenaryMerchantList_Struct)); MercenaryMerchantList_Struct* mml = (MercenaryMerchantList_Struct*)outapp->pBuffer; mml->MercTypeCount = mercTypeCount; if(mercTypeCount > 0) { - mml->MercGrades = new MercenaryGrade_Struct[mercTypeCount]; for(std::list::iterator mercTypeListItr = mercTypeList.begin(); mercTypeListItr != mercTypeList.end(); mercTypeListItr++) { - mml->MercGrades[i].GradeCountEntry = mercTypeListItr->Type; // DBStringID for Type + mml->MercGrades[i] = mercTypeListItr->Type; // DBStringID for Type i++; } } @@ -13547,7 +13549,6 @@ void Client::Handle_OP_MercenaryDataRequest(const EQApplicationPacket *app) if(mercCount > 0) { i = 0; - mml->Mercs = new MercenaryListEntry_Struct[mercCount]; for(std::list::iterator mercListIter = mercDataList.begin(); mercListIter != mercDataList.end(); mercListIter++) { mml->Mercs[i].MercID = mercListIter->MercTemplateID; @@ -13576,7 +13577,6 @@ void Client::Handle_OP_MercenaryDataRequest(const EQApplicationPacket *app) int stanceindex = 0; if(mercStanceCount > 0) { - mml->Mercs[i].Stances = new MercenaryStance_Struct[mercStanceCount]; list::iterator iter2 = zone->merc_stance_list[mercListIter->MercTemplateID].begin(); while(iter2 != zone->merc_stance_list[mercListIter->MercTemplateID].end()) { diff --git a/zone/merc.cpp b/zone/merc.cpp index 086a87211..8326b8b97 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -5886,24 +5886,18 @@ void Client::SendMercMerchantResponsePacket(int32 response_type) { EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryHire, sizeof(MercenaryMerchantResponse_Struct)); MercenaryMerchantResponse_Struct* mmr = (MercenaryMerchantResponse_Struct*)outapp->pBuffer; mmr->ResponseType = response_type; // send specified response type - - DumpPacket(outapp); FastQueuePacket(&outapp); } void Client::SendMercenaryUnknownPacket(uint8 type) { EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryUnknown1, 1); outapp->WriteUInt8(type); - - DumpPacket(outapp); FastQueuePacket(&outapp); } void Client::SendMercenaryUnsuspendPacket(uint8 type) { EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryUnsuspendResponse, 1); outapp->WriteUInt8(type); - - DumpPacket(outapp); FastQueuePacket(&outapp); } @@ -5911,8 +5905,6 @@ void Client::SendMercSuspendResponsePacket(uint32 suspended_time) { EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenarySuspendResponse, sizeof(SuspendMercenaryResponse_Struct)); SuspendMercenaryResponse_Struct* smr = (SuspendMercenaryResponse_Struct*)outapp->pBuffer; smr->SuspendTime = suspended_time; // Seen 0 (not suspended) or c9 c2 64 4f (suspended on Sat Mar 17 11:58:49 2012) - Unix Timestamp - - DumpPacket(outapp); FastQueuePacket(&outapp); } @@ -5930,8 +5922,6 @@ void Client::SendMercTimerPacket(int32 entity_id, int32 merc_state, int32 suspen mss->MercUnk01 = unk01; // Seen 180000 - 3 minutes in ms - Used for the unsuspend button refresh timer mss->MercState = merc_state; // Seen 5 (normal) or 1 (suspended) mss->SuspendedTime = suspended_time; // Seen 0 for not suspended or Unix Timestamp for suspended merc - - DumpPacket(outapp); FastQueuePacket(&outapp); } diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 486e6a02a..f7be0ac0b 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -392,7 +392,6 @@ void WorldServer::Process() { _log(ZONE__WORLD, "Error: WhoAllReturnStruct did not point to a valid client! " "id=%i, playerineqstring=%i, playersinzonestring=%i. Dumping WhoAllReturnStruct:", wars->id, wars->playerineqstring, wars->playersinzonestring); - //DumpPacket(pack); #endif } } @@ -495,7 +494,7 @@ void WorldServer::Process() { if (!(Zone::Bootup(zst->zoneid, zst->instanceid, zst->makestatic))) { SendChannelMessage(0, 0, 10, 0, 0, "%s:%i Zone::Bootup failed: %s", net.GetZoneAddress(), net.GetZonePort(), database.GetZoneName(zst->zoneid)); } - // Moved annoucement to ZoneBootup() - Quagmire + // Moved annoucement to ZoneBootup() // else // SendEmoteMessage(0, 0, 15, "Zone bootup: %s", zone->GetLongName()); break; @@ -1822,7 +1821,6 @@ void WorldServer::Process() { default: { cout << " Unknown ZSopcode:" << (int)pack->opcode; cout << " size:" << pack->size << endl; - //DumpPacket(pack->pBuffer, pack->size); break; } } From 9fbf9abd47c66d84274aa19b78f1fc8ec394002f Mon Sep 17 00:00:00 2001 From: SecretsOTheP Date: Sun, 17 Mar 2013 06:20:12 -0400 Subject: [PATCH 3/3] Forgot changelog :x --- changelog.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changelog.txt b/changelog.txt index 5a91b9e74..2fa5d5594 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,9 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 03/17/2013 == +Secrets: Fixed that pesky merc memleak. +Secrets: Bit of code cleanup regarding mercs. + == 03/15/2013 == Derision: RoF: Added ENCODE for Resurrect_struct (Accepting a rez should now work). Derision: Fixed a couple of memory leaks in Rez code.