From 63810d5c1b8ffdcbeff60e7981df36a708b51b9b Mon Sep 17 00:00:00 2001 From: JohnsonAskot Date: Sat, 7 Feb 2015 12:34:50 -0500 Subject: [PATCH] Exploit fixes Bind Wound was spammable via packet sending. You could buy a larger stack than the max StackSize of an item from merchants that had unlimited of those stackable items. --- zone/client.cpp | 10 +++++++--- zone/client_packet.cpp | 5 +++++ zone/client_process.cpp | 3 ++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/zone/client.cpp b/zone/client.cpp index 5cc5ae309..1889ecbf9 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -2471,11 +2471,13 @@ void Client::LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 bool Client::BindWound(Mob* bindmob, bool start, bool fail){ EQApplicationPacket* outapp = 0; - if(!fail) { + if(!fail) + { outapp = new EQApplicationPacket(OP_Bind_Wound, sizeof(BindWound_Struct)); BindWound_Struct* bind_out = (BindWound_Struct*) outapp->pBuffer; // Start bind - if(!bindwound_timer.Enabled()) { + if(!bindwound_timer.Enabled()) + { //make sure we actually have a bandage... and consume it. int16 bslot = m_inv.HasItemByUse(ItemTypeBandage, 1, invWhereWorn|invWherePersonal); if (bslot == INVALID_INDEX) { @@ -2521,7 +2523,9 @@ bool Client::BindWound(Mob* bindmob, bool start, bool fail){ ; // Binding self } } - } else { + } + else if (bindwound_timer.Check()) // Did the timer finish? No? Then why the hell do they get free hpz?! -Lecht + { // finish bind // disable complete timer bindwound_timer.Disable(); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 8ade0bc55..abc5734bd 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -12145,6 +12145,10 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) mp->quantity = prevcharges; } + // Item's stackable, but the quantity they want to buy exceeds the max stackable quantity. -Lecht + if (item->Stackable && mp->quantity > item->StackSize) + mp->quantity = item->StackSize; + EQApplicationPacket* outapp = new EQApplicationPacket(OP_ShopPlayerBuy, sizeof(Merchant_Sell_Struct)); Merchant_Sell_Struct* mpo = (Merchant_Sell_Struct*)outapp->pBuffer; mpo->quantity = mp->quantity; @@ -12171,6 +12175,7 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) mpo->price = SinglePrice; else mpo->price = SinglePrice * mp->quantity; + if (mpo->price < 0) { safe_delete(outapp); diff --git a/zone/client_process.cpp b/zone/client_process.cpp index bddc874c2..4c1475c95 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -239,7 +239,8 @@ bool Client::Process() { if(IsAIControlled()) AI_Process(); - if (bindwound_timer.Check() && bindwound_target != 0) { + // Don't reset the bindwound timer so we can check it in BindWound as well. -Lecht + if (bindwound_timer.Check(false) && bindwound_target != 0) { BindWound(bindwound_target, false); }