diff options
-rw-r--r-- | sql/updates/8048_characters_item_refund_instance.sql | 1 | ||||
-rw-r--r-- | src/game/Item.cpp | 5 | ||||
-rw-r--r-- | src/game/Item.h | 2 | ||||
-rw-r--r-- | src/game/ItemHandler.cpp | 147 | ||||
-rw-r--r-- | src/game/Player.cpp | 211 | ||||
-rw-r--r-- | src/game/Player.h | 7 |
6 files changed, 185 insertions, 188 deletions
diff --git a/sql/updates/8048_characters_item_refund_instance.sql b/sql/updates/8048_characters_item_refund_instance.sql new file mode 100644 index 00000000000..c873fc492d3 --- /dev/null +++ b/sql/updates/8048_characters_item_refund_instance.sql @@ -0,0 +1 @@ +ALTER TABLE `item_refund_instance` DROP COLUMN `count`; diff --git a/src/game/Item.cpp b/src/game/Item.cpp index 414ff1839fc..30023f511ab 100644 --- a/src/game/Item.cpp +++ b/src/game/Item.cpp @@ -1055,12 +1055,11 @@ void Item::BuildUpdate(UpdateDataMapType& data_map) ClearUpdateMask(false); } -void Item::SaveRefundDataToDB(uint32 count) +void Item::SaveRefundDataToDB() { std::ostringstream ss; - ss << "REPLACE INTO item_refund_instance VALUES("; + ss << "INSERT INTO item_refund_instance VALUES("; ss << GetGUIDLow() << ","; - ss << count << ", "; ss << GetRefundRecipient() << ","; ss << GetPaidMoney() << ","; ss << GetPaidExtendedCost(); diff --git a/src/game/Item.h b/src/game/Item.h index c3150dfeed9..b4112b3d132 100644 --- a/src/game/Item.h +++ b/src/game/Item.h @@ -243,7 +243,7 @@ class Item : public Object virtual bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result); virtual void DeleteFromDB(); void DeleteFromInventoryDB(); - void SaveRefundDataToDB(uint32 count); + void SaveRefundDataToDB(); void DeleteRefundDataFromDB(); bool IsBag() const { return GetProto()->InventoryType == INVTYPE_BAG; } diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp index a51a78b226e..626b748d3c6 100644 --- a/src/game/ItemHandler.cpp +++ b/src/game/ItemHandler.cpp @@ -1372,44 +1372,7 @@ void WorldSession::HandleItemRefundInfoRequest(WorldPacket& recv_data) return; } - // This function call unsets ITEM_FLAGS_REFUNDABLE if played time is over 2 hours. - item->UpdatePlayedTime(GetPlayer()); - - if (!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE)) - { - sLog.outDebug("Item refund: item not refundable!"); - return; - } - - if (GetPlayer()->GetGUIDLow() != item->GetRefundRecipient()) // Formerly refundable item got traded - { - sLog.outDebug("Item refund: item was traded!"); - item->SetNotRefundable(GetPlayer()); - return; - } - - ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(item->GetPaidExtendedCost()); - if (!iece) - { - sLog.outDebug("Item refund: cannot find extendedcost data."); - return; - } - - uint32 itemCount = item->GetCount(); - - WorldPacket data(SMSG_ITEM_REFUND_INFO_RESPONSE, 8+4+4+4+4*4+4*4+4+4); - data << uint64(guid); // item guid - data << uint32(item->GetPaidMoney() * itemCount); // money cost - data << uint32(iece->reqhonorpoints * itemCount); // honor point cost - data << uint32(iece->reqarenapoints * itemCount); // arena point cost - for (uint8 i = 0; i < 5; ++i) // item cost data - { - data << iece->reqitem[i]; - data << (iece->reqitemcount[i] * itemCount); - } - data << uint32(0); - data << uint32(GetPlayer()->GetTotalPlayedTime() - item->GetPlayedTime()); - SendPacket(&data); + GetPlayer()->SendRefundInfo(item); } void WorldSession::HandleItemRefund(WorldPacket &recv_data) @@ -1425,113 +1388,7 @@ void WorldSession::HandleItemRefund(WorldPacket &recv_data) return; } - if (!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE)) - { - sLog.outDebug("Item refund: item not refundable!"); - return; - } - - if (item->IsRefundExpired()) // item refund has expired - { - item->SetNotRefundable(GetPlayer()); - WorldPacket data(SMSG_ITEM_REFUND_RESULT, 8+4); - data << uint64(guid); // Guid - data << uint32(10); // Error! - SendPacket(&data); - return; - } - - if (GetPlayer()->GetGUIDLow() != item->GetRefundRecipient()) // Formerly refundable item got traded - { - sLog.outDebug("Item refund: item was traded!"); - item->SetNotRefundable(GetPlayer()); - return; - } - - ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(item->GetPaidExtendedCost()); - if (!iece) - { - sLog.outDebug("Item refund: cannot find extendedcost data."); - return; - } - - uint32 itemCount = item->GetCount(); // stacked refundable items. - uint32 moneyRefund = item->GetPaidMoney()*itemCount; - - bool store_error = false; - for (uint8 i = 0; i < 5; ++i) - { - uint32 count = iece->reqitemcount[i] * itemCount; - uint32 itemid = iece->reqitem[i]; - - if (count && itemid) - { - ItemPosCountVec dest; - uint8 msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemid, count); - if (msg != EQUIP_ERR_OK) - { - store_error = true; - break; - } - } - } - - if (store_error) - { - WorldPacket data(SMSG_ITEM_REFUND_RESULT, 8+4); - data << uint64(guid); // Guid - data << uint32(10); // Error! - SendPacket(&data); - return; - } - - WorldPacket data(SMSG_ITEM_REFUND_RESULT, 8+4+4+4+4+4*4+4*4); - data << uint64(guid); // item guid - data << uint32(0); // 0, or error code - data << uint32(moneyRefund); // money cost - data << uint32(iece->reqhonorpoints * itemCount); // honor point cost - data << uint32(iece->reqarenapoints * itemCount); // arena point cost - for (uint8 i = 0; i < 5; ++i) // item cost data - { - data << iece->reqitem[i]; - data << (iece->reqitemcount[i] * itemCount); - } - SendPacket(&data); - - // Delete any references to the refund data - item->SetNotRefundable(GetPlayer()); - - // Destroy item - _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); - - // Grant back extendedcost items - for (uint8 i = 0; i < 5; ++i) - { - uint32 count = iece->reqitemcount[i] * itemCount; - uint32 itemid = iece->reqitem[i]; - if (count && itemid) - { - ItemPosCountVec dest; - uint8 msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemid, count); - ASSERT(msg == EQUIP_ERR_OK) /// Already checked before - Item* it = _player->StoreNewItem(dest, itemid, true); - _player->SendNewItem(it, count, true, false, true); - } - } - - // Grant back money - if (moneyRefund) - _player->ModifyMoney(moneyRefund); - - // Grant back Honor points - uint32 honorRefund = iece->reqhonorpoints * itemCount; - if (honorRefund) - _player->ModifyHonorPoints(honorRefund); - - // Grant back Arena points - uint32 arenaRefund = iece->reqarenapoints * itemCount; - if (arenaRefund) - _player->ModifyArenaPoints(arenaRefund); + GetPlayer()->RefundItem(item); } /** diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 9467d3edbaf..ba3773df262 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -12013,19 +12013,17 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count) if (IsInventoryPos(dst)) { bool isRefundable = pSrcItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE); - if (isRefundable) - AlterRefundReferenceCount(pSrcItem->GetGUID(), pSrcItem->GetCount() - count); - + // change item amount before check (for unique max count check) pSrcItem->SetCount(pSrcItem->GetCount() - count); + + if (isRefundable) + SendRefundInfo(pSrcItem); ItemPosCountVec dest; uint8 msg = CanStoreItem(dstbag, dstslot, dest, pNewItem, false); if (msg != EQUIP_ERR_OK) { - if (isRefundable) - AlterRefundReferenceCount(pSrcItem->GetGUID(), pSrcItem->GetCount() + count); - delete pNewItem; pSrcItem->SetCount(pSrcItem->GetCount() + count); SendEquipError(msg, pSrcItem, NULL); @@ -12038,31 +12036,27 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count) StoreItem(dest, pNewItem, true); if (isRefundable) { - AddRefundReference(pNewItem->GetGUID(), count); pNewItem->SetPaidExtendedCost(pSrcItem->GetPaidExtendedCost()); pNewItem->SetPaidMoney(pSrcItem->GetPaidMoney()); pNewItem->SetRefundRecipient(GetGUIDLow()); pNewItem->SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, pSrcItem->GetPlayedTime()); pNewItem->SetFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE); - pNewItem->SaveRefundDataToDB(count); } } else if (IsBankPos (dst)) { bool isRefundable = pSrcItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE); - if (isRefundable) - AlterRefundReferenceCount(pSrcItem->GetGUID(), pSrcItem->GetCount() - count); - + // change item amount before check (for unique max count check) pSrcItem->SetCount(pSrcItem->GetCount() - count); + if (isRefundable) + SendRefundInfo(pSrcItem); + ItemPosCountVec dest; uint8 msg = CanBankItem(dstbag, dstslot, dest, pNewItem, false); if (msg != EQUIP_ERR_OK) { - if (isRefundable) - AlterRefundReferenceCount(pSrcItem->GetGUID(), pSrcItem->GetCount() + count); - delete pNewItem; pSrcItem->SetCount(pSrcItem->GetCount() + count); SendEquipError(msg, pSrcItem, NULL); @@ -12075,13 +12069,12 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count) BankItem(dest, pNewItem, true); if (isRefundable) { - AddRefundReference(pNewItem->GetGUID(), count); + AddRefundReference(pNewItem->GetGUID()); pNewItem->SetPaidExtendedCost(pSrcItem->GetPaidExtendedCost()); pNewItem->SetPaidMoney(pSrcItem->GetPaidMoney()); pNewItem->SetRefundRecipient(GetGUIDLow()); pNewItem->SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, pSrcItem->GetPlayedTime()); pNewItem->SetFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE); - pNewItem->SaveRefundDataToDB(count); } } else if (IsEquipmentPos (dst)) @@ -12275,6 +12268,7 @@ void Player::SwapItem(uint16 src, uint16 dst) pDstItem->SendUpdateToPlayer(this); } } + SendRefundInfo(pDstItem); return; } } @@ -16504,7 +16498,7 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff) else { QueryResult_AutoPtr result2 = CharacterDatabase.PQuery( - "SELECT count,player_guid,paidMoney,paidExtendedCost FROM `item_refund_instance` WHERE item_guid = '%u' AND player_guid = '%u' LIMIT 1", + "SELECT player_guid,paidMoney,paidExtendedCost FROM `item_refund_instance` WHERE item_guid = '%u' AND player_guid = '%u' LIMIT 1", item->GetGUIDLow(), GetGUIDLow()); if (!result2) { @@ -16516,10 +16510,10 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff) else { fields = result2->Fetch(); - item->SetRefundRecipient(fields[1].GetUInt32()); - item->SetPaidMoney(fields[2].GetUInt32()); - item->SetPaidExtendedCost(fields[3].GetUInt32()); - AddRefundReference(item->GetGUID(), fields[0].GetUInt32()); + item->SetRefundRecipient(fields[0].GetUInt32()); + item->SetPaidMoney(fields[1].GetUInt32()); + item->SetPaidExtendedCost(fields[2].GetUInt32()); + AddRefundReference(item->GetGUID()); } } } @@ -17654,14 +17648,14 @@ void Player::_SaveInventory() // the client auto counts down in real time after having received the initial played time on the first // SMSG_ITEM_REFUND_INFO_RESPONSE packet. // Item::UpdatePlayedTime is only called when needed, which is in DB saves, and item refund info requests. - std::map<uint64, uint32>::iterator i_next; - for (std::map<uint64, uint32>::iterator itr = m_refundableItems.begin(); itr!= m_refundableItems.end(); itr = i_next) + std::set<uint64>::iterator i_next; + for (std::set<uint64>::iterator itr = m_refundableItems.begin(); itr!= m_refundableItems.end(); itr = i_next) { // use copy iterator because itr may be invalid after operations in this loop i_next = itr; ++i_next; - Item* iPtr = GetItemByGuid(itr->first); + Item* iPtr = GetItemByGuid(*itr); if (iPtr) { iPtr->UpdatePlayedTime(this); @@ -17669,7 +17663,7 @@ void Player::_SaveInventory() } else { - sLog.outError("Can't find item guid " UI64FMTD " but is in refundable storage for player %u ! Removing.", itr->first, GetGUIDLow()); + sLog.outError("Can't find item guid " UI64FMTD " but is in refundable storage for player %u ! Removing.", *itr, GetGUIDLow()); m_refundableItems.erase(itr); } } @@ -19526,8 +19520,8 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint it->SetRefundRecipient(GetGUIDLow()); it->SetPaidMoney(price); it->SetPaidExtendedCost(crItem->ExtendedCost); - it->SaveRefundDataToDB(it->GetCount()); - AddRefundReference(it->GetGUID(), it->GetCount()); + it->SaveRefundDataToDB(); + AddRefundReference(it->GetGUID()); } } } @@ -19584,8 +19578,8 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint it->SetRefundRecipient(GetGUIDLow()); it->SetPaidMoney(price); it->SetPaidExtendedCost(crItem->ExtendedCost); - it->SaveRefundDataToDB(it->GetCount()); - AddRefundReference(it->GetGUID(), it->GetCount()); + it->SaveRefundDataToDB(); + AddRefundReference(it->GetGUID()); } } } @@ -23595,25 +23589,170 @@ void Player::SendDuelCountdown(uint32 counter) GetSession()->SendPacket(&data); } -void Player::AddRefundReference(uint64 it, uint32 stackCount) +void Player::AddRefundReference(uint64 it) { - m_refundableItems[it] = stackCount; + m_refundableItems.insert(it); } void Player::DeleteRefundReference(uint64 it) { - std::map<uint64,uint32>::iterator itr = m_refundableItems.find(it); + std::set<uint64>::iterator itr = m_refundableItems.find(it); if (itr != m_refundableItems.end()) { m_refundableItems.erase(itr); } } -void Player::AlterRefundReferenceCount(uint64 it, uint32 newCount) +void Player::SendRefundInfo(Item *item) { - std::map<uint64,uint32>::iterator itr = m_refundableItems.find(it); - if (itr != m_refundableItems.end()) + // This function call unsets ITEM_FLAGS_REFUNDABLE if played time is over 2 hours. + item->UpdatePlayedTime(this); + + if (!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE)) + { + sLog.outDebug("Item refund: item not refundable!"); + return; + } + + if (GetGUIDLow() != item->GetRefundRecipient()) // Formerly refundable item got traded { - itr->second = newCount; + sLog.outDebug("Item refund: item was traded!"); + item->SetNotRefundable(this); + return; + } + + ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(item->GetPaidExtendedCost()); + if (!iece) + { + sLog.outDebug("Item refund: cannot find extendedcost data."); + return; } + + uint32 itemCount = item->GetCount(); + + WorldPacket data(SMSG_ITEM_REFUND_INFO_RESPONSE, 8+4+4+4+4*4+4*4+4+4); + data << uint64(item->GetGUID()); // item guid + data << uint32(item->GetPaidMoney() * itemCount); // money cost + data << uint32(iece->reqhonorpoints * itemCount); // honor point cost + data << uint32(iece->reqarenapoints * itemCount); // arena point cost + for (uint8 i = 0; i < 5; ++i) // item cost data + { + data << iece->reqitem[i]; + data << (iece->reqitemcount[i] * itemCount); + } + data << uint32(0); + data << uint32(GetTotalPlayedTime() - item->GetPlayedTime()); + GetSession()->SendPacket(&data); +} + +void Player::RefundItem(Item *item) +{ + if (!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE)) + { + sLog.outDebug("Item refund: item not refundable!"); + return; + } + + if (item->IsRefundExpired()) // item refund has expired + { + item->SetNotRefundable(this); + WorldPacket data(SMSG_ITEM_REFUND_RESULT, 8+4); + data << uint64(item->GetGUID()); // Guid + data << uint32(10); // Error! + GetSession()->SendPacket(&data); + return; + } + + if (GetGUIDLow() != item->GetRefundRecipient()) // Formerly refundable item got traded + { + sLog.outDebug("Item refund: item was traded!"); + item->SetNotRefundable(this); + return; + } + + ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(item->GetPaidExtendedCost()); + if (!iece) + { + sLog.outDebug("Item refund: cannot find extendedcost data."); + return; + } + + uint32 itemCount = item->GetCount(); // stacked refundable items. + uint32 moneyRefund = item->GetPaidMoney()*itemCount; + + bool store_error = false; + for (uint8 i = 0; i < 5; ++i) + { + uint32 count = iece->reqitemcount[i] * itemCount; + uint32 itemid = iece->reqitem[i]; + + if (count && itemid) + { + ItemPosCountVec dest; + uint8 msg = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemid, count); + if (msg != EQUIP_ERR_OK) + { + store_error = true; + break; + } + } + } + + if (store_error) + { + WorldPacket data(SMSG_ITEM_REFUND_RESULT, 8+4); + data << uint64(item->GetGUID()); // Guid + data << uint32(10); // Error! + GetSession()->SendPacket(&data); + return; + } + + WorldPacket data(SMSG_ITEM_REFUND_RESULT, 8+4+4+4+4+4*4+4*4); + data << uint64(item->GetGUID()); // item guid + data << uint32(0); // 0, or error code + data << uint32(moneyRefund); // money cost + data << uint32(iece->reqhonorpoints * itemCount); // honor point cost + data << uint32(iece->reqarenapoints * itemCount); // arena point cost + for (uint8 i = 0; i < 5; ++i) // item cost data + { + data << iece->reqitem[i]; + data << (iece->reqitemcount[i] * itemCount); + } + GetSession()->SendPacket(&data); + + // Delete any references to the refund data + item->SetNotRefundable(this); + + // Destroy item + DestroyItem(item->GetBagSlot(), item->GetSlot(), true); + + // Grant back extendedcost items + for (uint8 i = 0; i < 5; ++i) + { + uint32 count = iece->reqitemcount[i] * itemCount; + uint32 itemid = iece->reqitem[i]; + if (count && itemid) + { + ItemPosCountVec dest; + uint8 msg = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemid, count); + ASSERT(msg == EQUIP_ERR_OK) /// Already checked before + Item* it = StoreNewItem(dest, itemid, true); + SendNewItem(it, count, true, false, true); + } + } + + // Grant back money + if (moneyRefund) + ModifyMoney(moneyRefund); + + // Grant back Honor points + uint32 honorRefund = iece->reqhonorpoints * itemCount; + if (honorRefund) + ModifyHonorPoints(honorRefund); + + // Grant back Arena points + uint32 arenaRefund = iece->reqarenapoints * itemCount; + if (arenaRefund) + ModifyArenaPoints(arenaRefund); + }
\ No newline at end of file diff --git a/src/game/Player.h b/src/game/Player.h index 06b05089c32..22af6a370ca 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1200,8 +1200,7 @@ class Player : public Unit, public GridObject<Player> uint8 _CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = NULL) const; uint8 _CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item *pItem = NULL, bool swap = false, uint32* no_space_count = NULL) const; - void AddRefundReference(uint64 it, uint32 stackCount); - void AlterRefundReferenceCount(uint64 it, uint32 newCount); + void AddRefundReference(uint64 it); void DeleteRefundReference(uint64 it); void ApplyEquipCooldown(Item * pItem); @@ -2589,7 +2588,9 @@ class Player : public Unit, public GridObject<Player> uint8 _CanStoreItem_InInventorySlots(uint8 slot_begin, uint8 slot_end, ItemPosCountVec& dest, ItemPrototype const *pProto, uint32& count, bool merge, Item *pSrcItem, uint8 skip_bag, uint8 skip_slot) const; Item* _StoreItem(uint16 pos, Item *pItem, uint32 count, bool clone, bool update); - std::map<uint64, uint32> m_refundableItems; + std::set<uint64> m_refundableItems; + void SendRefundInfo(Item* item); + void RefundItem(Item* item); void UpdateKnownCurrencies(uint32 itemId, bool apply); int32 CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool for_quest); |