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