Core/Player: Fix item refund exploit

This commit is contained in:
Machiavelli
2011-08-07 15:57:26 +02:00
parent 5429158b3f
commit 04c2f2929e
4 changed files with 28 additions and 15 deletions
+6 -5
View File
@@ -1130,12 +1130,13 @@ void Item::SaveRefundDataToDB()
CharacterDatabase.CommitTransaction(trans);
}
void Item::DeleteRefundDataFromDB()
void Item::DeleteRefundDataFromDB(SQLTransaction* trans)
{
CharacterDatabase.PExecute("DELETE FROM item_refund_instance WHERE item_guid = '%u'", GetGUIDLow());
if (trans && !trans->null())
(*trans)->PAppend("DELETE FROM item_refund_instance WHERE item_guid = '%u'", GetGUIDLow());
}
void Item::SetNotRefundable(Player *owner, bool changestate)
void Item::SetNotRefundable(Player *owner, bool changestate /*=true*/, SQLTransaction* trans /*=NULL*/)
{
if (!HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE))
return;
@@ -1144,11 +1145,11 @@ void Item::SetNotRefundable(Player *owner, bool changestate)
// Following is not applicable in the trading procedure
if (changestate)
SetState(ITEM_CHANGED, owner);
SetRefundRecipient(0);
SetPaidMoney(0);
SetPaidExtendedCost(0);
DeleteRefundDataFromDB();
DeleteRefundDataFromDB(trans);
owner->DeleteRefundReference(GetGUIDLow());
}
+2 -2
View File
@@ -251,7 +251,7 @@ class Item : public Object
static void DeleteFromInventoryDB(SQLTransaction& trans, uint32 itemGuid);
void DeleteFromInventoryDB(SQLTransaction& trans);
void SaveRefundDataToDB();
void DeleteRefundDataFromDB();
void DeleteRefundDataFromDB(SQLTransaction* trans);
Bag* ToBag() { if (IsBag()) return reinterpret_cast<Bag*>(this); else return NULL; }
const Bag* ToBag() const { if (IsBag()) return reinterpret_cast<const Bag*>(this); else return NULL; }
@@ -339,7 +339,7 @@ class Item : public Object
bool IsConjuredConsumable() const { return GetTemplate()->IsConjuredConsumable(); }
// Item Refund system
void SetNotRefundable(Player *owner, bool changestate = true);
void SetNotRefundable(Player *owner, bool changestate = true, SQLTransaction* trans = NULL);
void SetRefundRecipient(uint32 pGuidLow) { m_refundRecipient = pGuidLow; }
void SetPaidMoney(uint32 money) { m_paidMoney = money; }
void SetPaidExtendedCost(uint32 iece) { m_paidExtendedCost = iece; }
+18 -6
View File
@@ -7263,20 +7263,26 @@ void Player::SetArenaPoints(uint32 value)
AddKnownCurrency(ITEM_ARENA_POINTS_ID);
}
void Player::ModifyHonorPoints(int32 value)
void Player::ModifyHonorPoints(int32 value, SQLTransaction* trans /*=NULL*/)
{
int32 newValue = int32(GetHonorPoints()) + value;
if (newValue < 0)
newValue = 0;
SetHonorPoints(uint32(newValue));
if (trans && !trans->null())
(*trans)->PAppend("UPDATE characters SET totalHonorPoints=%u WHERE guid=%u", newValue, GetGUIDLow());
}
void Player::ModifyArenaPoints(int32 value)
void Player::ModifyArenaPoints(int32 value, SQLTransaction* trans /*=NULL*/)
{
int32 newValue = int32(GetArenaPoints()) + value;
if (newValue < 0)
newValue = 0;
SetArenaPoints(uint32(newValue));
if (trans && !trans->null())
(*trans)->PAppend("UPDATE characters SET arenaPoints=%u WHERE guid=%u", newValue, GetGUIDLow());
}
uint32 Player::GetGuildIdFromDB(uint64 guid)
@@ -24549,8 +24555,11 @@ void Player::RefundItem(Item *item)
uint32 moneyRefund = item->GetPaidMoney(); // item-> will be invalidated in DestroyItem
// Save all relevant data to DB to prevent desynchronisation exploits
SQLTransaction trans = CharacterDatabase.BeginTransaction();
// Delete any references to the refund data
item->SetNotRefundable(this);
item->SetNotRefundable(this, true, &trans);
// Destroy item
DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
@@ -24572,16 +24581,19 @@ void Player::RefundItem(Item *item)
// Grant back money
if (moneyRefund)
ModifyMoney(moneyRefund);
ModifyMoney(moneyRefund); // Saved in SaveInventoryAndGoldToDB
// Grant back Honor points
if (uint32 honorRefund = iece->reqhonorpoints)
ModifyHonorPoints(honorRefund);
ModifyHonorPoints(honorRefund, &trans);
// Grant back Arena points
if (uint32 arenaRefund = iece->reqarenapoints)
ModifyArenaPoints(arenaRefund);
ModifyArenaPoints(arenaRefund, &trans);
SaveInventoryAndGoldToDB(trans);
CharacterDatabase.CommitTransaction(trans);
}
void Player::SetRandomWinner(bool isWinner)
+2 -2
View File
@@ -2034,8 +2034,8 @@ class Player : public Unit, public GridObject<Player>
bool RewardHonor(Unit *pVictim, uint32 groupsize, int32 honor = -1, bool pvptoken = false);
uint32 GetHonorPoints() const { return GetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY); }
uint32 GetArenaPoints() const { return GetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY); }
void ModifyHonorPoints(int32 value);
void ModifyArenaPoints(int32 value);
void ModifyHonorPoints(int32 value, SQLTransaction* trans = NULL); //! If trans is specified, honor save query will be added to trans
void ModifyArenaPoints(int32 value, SQLTransaction* trans = NULL); //! If trans is specified, arena point save query will be added to trans
uint32 GetMaxPersonalArenaRatingRequirement(uint32 minarenaslot) const;
void SetHonorPoints(uint32 value);
void SetArenaPoints(uint32 value);