Core/Player: Fix item refund exploit
This commit is contained in:
@@ -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;
|
||||
@@ -1148,7 +1149,7 @@ void Item::SetNotRefundable(Player *owner, bool changestate)
|
||||
SetRefundRecipient(0);
|
||||
SetPaidMoney(0);
|
||||
SetPaidExtendedCost(0);
|
||||
DeleteRefundDataFromDB();
|
||||
DeleteRefundDataFromDB(trans);
|
||||
|
||||
owner->DeleteRefundReference(GetGUIDLow());
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user