Core/Player: Fix item refund exploit
This commit is contained in:
@@ -1130,12 +1130,13 @@ void Item::SaveRefundDataToDB()
|
|||||||
CharacterDatabase.CommitTransaction(trans);
|
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))
|
if (!HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE))
|
||||||
return;
|
return;
|
||||||
@@ -1148,7 +1149,7 @@ void Item::SetNotRefundable(Player *owner, bool changestate)
|
|||||||
SetRefundRecipient(0);
|
SetRefundRecipient(0);
|
||||||
SetPaidMoney(0);
|
SetPaidMoney(0);
|
||||||
SetPaidExtendedCost(0);
|
SetPaidExtendedCost(0);
|
||||||
DeleteRefundDataFromDB();
|
DeleteRefundDataFromDB(trans);
|
||||||
|
|
||||||
owner->DeleteRefundReference(GetGUIDLow());
|
owner->DeleteRefundReference(GetGUIDLow());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ class Item : public Object
|
|||||||
static void DeleteFromInventoryDB(SQLTransaction& trans, uint32 itemGuid);
|
static void DeleteFromInventoryDB(SQLTransaction& trans, uint32 itemGuid);
|
||||||
void DeleteFromInventoryDB(SQLTransaction& trans);
|
void DeleteFromInventoryDB(SQLTransaction& trans);
|
||||||
void SaveRefundDataToDB();
|
void SaveRefundDataToDB();
|
||||||
void DeleteRefundDataFromDB();
|
void DeleteRefundDataFromDB(SQLTransaction* trans);
|
||||||
|
|
||||||
Bag* ToBag() { if (IsBag()) return reinterpret_cast<Bag*>(this); else return NULL; }
|
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; }
|
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(); }
|
bool IsConjuredConsumable() const { return GetTemplate()->IsConjuredConsumable(); }
|
||||||
|
|
||||||
// Item Refund system
|
// 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 SetRefundRecipient(uint32 pGuidLow) { m_refundRecipient = pGuidLow; }
|
||||||
void SetPaidMoney(uint32 money) { m_paidMoney = money; }
|
void SetPaidMoney(uint32 money) { m_paidMoney = money; }
|
||||||
void SetPaidExtendedCost(uint32 iece) { m_paidExtendedCost = iece; }
|
void SetPaidExtendedCost(uint32 iece) { m_paidExtendedCost = iece; }
|
||||||
|
|||||||
@@ -7263,20 +7263,26 @@ void Player::SetArenaPoints(uint32 value)
|
|||||||
AddKnownCurrency(ITEM_ARENA_POINTS_ID);
|
AddKnownCurrency(ITEM_ARENA_POINTS_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::ModifyHonorPoints(int32 value)
|
void Player::ModifyHonorPoints(int32 value, SQLTransaction* trans /*=NULL*/)
|
||||||
{
|
{
|
||||||
int32 newValue = int32(GetHonorPoints()) + value;
|
int32 newValue = int32(GetHonorPoints()) + value;
|
||||||
if (newValue < 0)
|
if (newValue < 0)
|
||||||
newValue = 0;
|
newValue = 0;
|
||||||
SetHonorPoints(uint32(newValue));
|
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;
|
int32 newValue = int32(GetArenaPoints()) + value;
|
||||||
if (newValue < 0)
|
if (newValue < 0)
|
||||||
newValue = 0;
|
newValue = 0;
|
||||||
SetArenaPoints(uint32(newValue));
|
SetArenaPoints(uint32(newValue));
|
||||||
|
|
||||||
|
if (trans && !trans->null())
|
||||||
|
(*trans)->PAppend("UPDATE characters SET arenaPoints=%u WHERE guid=%u", newValue, GetGUIDLow());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Player::GetGuildIdFromDB(uint64 guid)
|
uint32 Player::GetGuildIdFromDB(uint64 guid)
|
||||||
@@ -24549,8 +24555,11 @@ void Player::RefundItem(Item *item)
|
|||||||
|
|
||||||
uint32 moneyRefund = item->GetPaidMoney(); // item-> will be invalidated in DestroyItem
|
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
|
// Delete any references to the refund data
|
||||||
item->SetNotRefundable(this);
|
item->SetNotRefundable(this, true, &trans);
|
||||||
|
|
||||||
// Destroy item
|
// Destroy item
|
||||||
DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
|
DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
|
||||||
@@ -24572,16 +24581,19 @@ void Player::RefundItem(Item *item)
|
|||||||
|
|
||||||
// Grant back money
|
// Grant back money
|
||||||
if (moneyRefund)
|
if (moneyRefund)
|
||||||
ModifyMoney(moneyRefund);
|
ModifyMoney(moneyRefund); // Saved in SaveInventoryAndGoldToDB
|
||||||
|
|
||||||
// Grant back Honor points
|
// Grant back Honor points
|
||||||
if (uint32 honorRefund = iece->reqhonorpoints)
|
if (uint32 honorRefund = iece->reqhonorpoints)
|
||||||
ModifyHonorPoints(honorRefund);
|
ModifyHonorPoints(honorRefund, &trans);
|
||||||
|
|
||||||
// Grant back Arena points
|
// Grant back Arena points
|
||||||
if (uint32 arenaRefund = iece->reqarenapoints)
|
if (uint32 arenaRefund = iece->reqarenapoints)
|
||||||
ModifyArenaPoints(arenaRefund);
|
ModifyArenaPoints(arenaRefund, &trans);
|
||||||
|
|
||||||
|
SaveInventoryAndGoldToDB(trans);
|
||||||
|
|
||||||
|
CharacterDatabase.CommitTransaction(trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::SetRandomWinner(bool isWinner)
|
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);
|
bool RewardHonor(Unit *pVictim, uint32 groupsize, int32 honor = -1, bool pvptoken = false);
|
||||||
uint32 GetHonorPoints() const { return GetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY); }
|
uint32 GetHonorPoints() const { return GetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY); }
|
||||||
uint32 GetArenaPoints() const { return GetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY); }
|
uint32 GetArenaPoints() const { return GetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY); }
|
||||||
void ModifyHonorPoints(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);
|
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;
|
uint32 GetMaxPersonalArenaRatingRequirement(uint32 minarenaslot) const;
|
||||||
void SetHonorPoints(uint32 value);
|
void SetHonorPoints(uint32 value);
|
||||||
void SetArenaPoints(uint32 value);
|
void SetArenaPoints(uint32 value);
|
||||||
|
|||||||
Reference in New Issue
Block a user