AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
ItemRecovery Namespace Reference

Functions

bool Save (Item const *item, uint32 count, RecoveryItemSource source, uint32 money=0, RecoveryItemLoot const &loot={ })
 
std::optional< RecoveryItem > Load (uint32 recoveryId)
 
bool Restore (RecoveryItem const &recovery, Player *owner)
 
void DeleteFromDB (CharacterDatabaseTransaction trans, uint32 recoveryId)
 
bool IsInBuyback (Player *player, RecoveryItem const &recovery)
 

Function Documentation

◆ DeleteFromDB()

void ItemRecovery::DeleteFromDB ( CharacterDatabaseTransaction  trans,
uint32  recoveryId 
)
193{
195 stmt->SetData(0, recoveryId);
196 trans->Append(stmt);
197
198 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_RECOVERY_ITEM_BY_RECOVERY_ID);
199 stmt->SetData(0, recoveryId);
200 trans->Append(stmt);
201}
@ CHAR_DEL_RECOVERY_ITEM_BY_RECOVERY_ID
Definition CharacterDatabase.h:526
@ CHAR_DEL_RECOVERY_ITEM_LOOT_BY_RECOVERY_ID
Definition CharacterDatabase.h:527
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition DatabaseEnv.cpp:21
Acore::Types::is_default< T > SetData(const uint8 index, T value)
Definition PreparedStatement.h:77
Definition PreparedStatement.h:157

References CHAR_DEL_RECOVERY_ITEM_BY_RECOVERY_ID, CHAR_DEL_RECOVERY_ITEM_LOOT_BY_RECOVERY_ID, CharacterDatabase, and PreparedStatementBase::SetData().

Referenced by Player::DeleteOldRecoveryItems(), and Restore().

◆ IsInBuyback()

bool ItemRecovery::IsInBuyback ( Player *  player,
RecoveryItem const &  recovery 
)
204{
205 for (uint32 slot = BUYBACK_SLOT_START; slot < BUYBACK_SLOT_END; ++slot)
206 if (Item* item = player->GetItemFromBuyBackSlot(slot))
207 if (item->GetGUID().GetCounter() == recovery.ItemGuid && item->GetEntry() == recovery.ItemEntry)
208 return true;
209
210 return false;
211}
std::uint32_t uint32
Definition Define.h:107
@ BUYBACK_SLOT_END
Definition Player.h:712
@ BUYBACK_SLOT_START
Definition Player.h:711
Definition Item.h:220
Item * GetItemFromBuyBackSlot(uint32 slot)
Definition PlayerStorage.cpp:4097

References BUYBACK_SLOT_END, BUYBACK_SLOT_START, Player::GetItemFromBuyBackSlot(), RecoveryItem::ItemEntry, and RecoveryItem::ItemGuid.

Referenced by item_commandscript::HandleItemRestoreCommand().

◆ Load()

std::optional< RecoveryItem > ItemRecovery::Load ( uint32  recoveryId)
112{
114 stmt->SetData(0, recoveryId);
115 PreparedQueryResult result = CharacterDatabase.Query(stmt);
116 if (!result)
117 return std::nullopt;
118
119 Field* fields = result->Fetch();
120
121 RecoveryItem recovery;
122 recovery.Id = fields[0].Get<uint32>();
123 recovery.OwnerGuid = fields[1].Get<uint32>();
124 recovery.ItemEntry = fields[2].Get<uint32>();
125 recovery.ItemGuid = fields[3].Get<uint32>();
126 recovery.Count = fields[4].Get<uint32>();
127 recovery.Source = RecoveryItemSource(fields[5].Get<uint8>());
128 recovery.Money = fields[6].Get<uint32>();
129 recovery.RandomPropertyId = fields[7].Get<int32>();
130 recovery.Enchantments = fields[8].Get<std::string>();
131 recovery.CreatorGuid = fields[9].Get<uint32>();
132 recovery.Bound = fields[10].Get<uint8>() != 0;
133 recovery.Loot = LoadLoot(recovery.Id);
134
135 return recovery;
136}
@ CHAR_SEL_RECOVERY_ITEM
Definition CharacterDatabase.h:521
std::shared_ptr< PreparedResultSet > PreparedQueryResult
Definition DatabaseEnvFwd.h:45
std::int32_t int32
Definition Define.h:103
std::uint8_t uint8
Definition Define.h:109
RecoveryItemSource
Definition ItemRecovery.h:32
Class used to access individual fields of database query result.
Definition Field.h:99
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition Field.h:113
Definition ItemRecovery.h:41
uint32 Count
Definition ItemRecovery.h:46
ObjectGuid::LowType OwnerGuid
Definition ItemRecovery.h:43
bool Bound
Definition ItemRecovery.h:52
std::string Enchantments
Definition ItemRecovery.h:50
uint32 Id
Definition ItemRecovery.h:42
RecoveryItemSource Source
Definition ItemRecovery.h:47
ObjectGuid::LowType CreatorGuid
Definition ItemRecovery.h:51
uint32 Money
Definition ItemRecovery.h:48
ObjectGuid::LowType ItemGuid
Definition ItemRecovery.h:45
RecoveryItemLoot Loot
Definition ItemRecovery.h:53
int32 RandomPropertyId
Definition ItemRecovery.h:49
uint32 ItemEntry
Definition ItemRecovery.h:44

References RecoveryItem::Bound, CHAR_SEL_RECOVERY_ITEM, CharacterDatabase, RecoveryItem::Count, RecoveryItem::CreatorGuid, RecoveryItem::Enchantments, Field::Get(), RecoveryItem::Id, RecoveryItem::ItemEntry, RecoveryItem::ItemGuid, RecoveryItem::Loot, RecoveryItem::Money, RecoveryItem::OwnerGuid, RecoveryItem::RandomPropertyId, PreparedStatementBase::SetData(), and RecoveryItem::Source.

Referenced by item_commandscript::HandleItemRestoreCommand().

◆ Restore()

bool ItemRecovery::Restore ( RecoveryItem const &  recovery,
Player *  owner 
)
139{
140 if (!sObjectMgr->GetItemTemplate(recovery.ItemEntry))
141 return false;
142
143 {
144 std::lock_guard<std::mutex> lock(RestoredIdsLock);
145 if (!RestoredIds.insert(recovery.Id).second)
146 return false;
147 }
148
149 // A zero id rolls a new random property, which only matters for legacy rows recorded without one
150 Item* item = Item::CreateItem(recovery.ItemEntry, recovery.Count, nullptr, false, uint32(recovery.RandomPropertyId));
151 if (!item)
152 {
153 std::lock_guard<std::mutex> lock(RestoredIdsLock);
154 RestoredIds.erase(recovery.Id);
155 return false;
156 }
157
158 // An online receiver takes this very object from the mail, and a soulbound item must already be theirs
159 item->SetOwnerGUID(ObjectGuid::Create<HighGuid::Player>(recovery.OwnerGuid));
160
161 // Item::SetEnchantment logs to and queues the item for its owner, who may be offline and does not hold it yet
162 std::vector<std::string_view> enchantments = Acore::Tokenize(recovery.Enchantments, ' ', false);
163 if (enchantments.size() == MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET)
164 {
165 for (EnchantmentSlot slot : RecoveryEnchantmentSlots)
166 {
168 if (Optional<uint32> enchantId = Acore::StringTo<uint32>(enchantments[field]); enchantId && *enchantId)
169 item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + field, *enchantId);
170 }
171 }
172
173 if (recovery.CreatorGuid)
174 item->SetGuidValue(ITEM_FIELD_CREATOR, ObjectGuid::Create<HighGuid::Player>(recovery.CreatorGuid));
175
176 // A bind-on-equip item would otherwise come back tradeable
177 if (recovery.Bound)
178 item->SetBinding(true);
179
180 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
181
182 item->SaveToDB(trans);
183 MailDraft("Recovered Item", "We recovered a lost item in the twisting nether and noted that it was yours.$B$BPlease find said object enclosed.")
184 .AddItem(item)
185 .SendMailTo(trans, MailReceiver(owner, recovery.OwnerGuid), MailSender(MAIL_CREATURE, 34337 /* The Postmaster */));
186
187 DeleteFromDB(trans, recovery.Id);
188 CharacterDatabase.CommitTransaction(trans);
189 return true;
190}
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
Definition DatabaseEnvFwd.h:69
#define MAX_ENCHANTMENT_OFFSET
Definition Item.h:197
@ ENCHANTMENT_ID_OFFSET
Definition Item.h:192
EnchantmentSlot
Definition Item.h:168
@ MAX_ENCHANTMENT_SLOT
Definition Item.h:183
@ MAIL_CREATURE
Definition Mail.h:39
#define sObjectMgr
Definition ObjectMgr.h:1731
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:24
@ ITEM_FIELD_CREATOR
Definition UpdateFields.h:37
@ ITEM_FIELD_ENCHANTMENT_1_1
Definition UpdateFields.h:43
static Item * CreateItem(uint32 item, uint32 count, Player const *player=nullptr, bool clone=false, uint32 randomPropertyId=0)
Definition Item.cpp:1099
virtual void SaveToDB(CharacterDatabaseTransaction trans)
Definition Item.cpp:337
void SetBinding(bool val)
Definition Item.h:235
void SetOwnerGUID(ObjectGuid guid)
Definition Item.h:232
Definition Mail.h:119
void SendMailTo(CharacterDatabaseTransaction trans, MailReceiver const &receiver, MailSender const &sender, MailCheckMask checked=MAIL_CHECK_MASK_NONE, uint32 deliver_delay=0, uint32 custom_expiration=0, bool deleteMailItemsFromDB=false, bool sendMail=true)
Definition Mail.cpp:187
MailDraft & AddItem(Item *item)
Definition Mail.cpp:95
Definition Mail.h:105
Definition Mail.h:83
void SetGuidValue(uint16 index, ObjectGuid value)
Definition Object.cpp:721
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:648
std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition Tokenize.cpp:20
void DeleteFromDB(CharacterDatabaseTransaction trans, uint32 recoveryId)
Definition ItemRecovery.cpp:192

References MailDraft::AddItem(), RecoveryItem::Bound, CharacterDatabase, RecoveryItem::Count, Item::CreateItem(), RecoveryItem::CreatorGuid, DeleteFromDB(), ENCHANTMENT_ID_OFFSET, RecoveryItem::Enchantments, RecoveryItem::Id, ITEM_FIELD_CREATOR, ITEM_FIELD_ENCHANTMENT_1_1, RecoveryItem::ItemEntry, MAIL_CREATURE, MAX_ENCHANTMENT_OFFSET, MAX_ENCHANTMENT_SLOT, RecoveryItem::OwnerGuid, RecoveryItem::RandomPropertyId, Item::SaveToDB(), MailDraft::SendMailTo(), Item::SetBinding(), Object::SetGuidValue(), Item::SetOwnerGUID(), Object::SetUInt32Value(), sObjectMgr, and Acore::Tokenize().

Referenced by item_commandscript::HandleItemRestoreCommand().

◆ Save()

bool ItemRecovery::Save ( Item const *  item,
uint32  count,
RecoveryItemSource  source,
uint32  money = 0,
RecoveryItemLoot const &  loot = { } 
)
70{
71 ItemTemplate const* proto = item->GetTemplate();
72 if (!sWorld->getBoolConfig(CONFIG_ITEMDELETE_METHOD)
73 || proto->Quality < sWorld->getIntConfig(CONFIG_ITEMDELETE_QUALITY)
74 || proto->ItemLevel < sWorld->getIntConfig(CONFIG_ITEMDELETE_ITEM_LEVEL))
75 return false;
76
77 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
78
79 uint8 index = 0;
81 stmt->SetData(index++, item->GetOwnerGUID().GetCounter());
82 stmt->SetData(index++, item->GetEntry());
83 stmt->SetData(index++, item->GetGUID().GetCounter());
84 stmt->SetData(index++, count);
85 stmt->SetData(index++, uint8(source));
86 stmt->SetData(index++, money);
87 stmt->SetData(index++, item->GetItemRandomPropertyId());
88 stmt->SetData(index++, item->GetEnchantmentsString());
89 stmt->SetData(index++, item->GetGuidValue(ITEM_FIELD_CREATOR).GetCounter());
90 stmt->SetData(index++, uint8(item->IsSoulBound()));
91 trans->Append(stmt);
92
93 std::map<uint32, uint32> lootCounts;
94 for (auto const& [itemEntry, itemCount] : loot)
95 lootCounts[itemEntry] += itemCount;
96
97 // recovery_item_loot has no auto-increment column, so LAST_INSERT_ID() keeps pointing at the row above
98 for (auto const& [itemEntry, itemCount] : lootCounts)
99 {
100 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_RECOVERY_ITEM_LOOT);
101 stmt->SetData(0, itemEntry);
102 stmt->SetData(1, itemCount);
103 trans->Append(stmt);
104 }
105
106 // Synchronous, so the row exists before a buyback of the same item tries to delete it
107 CharacterDatabase.DirectCommitTransaction(trans);
108 return true;
109}
@ CHAR_INS_RECOVERY_ITEM
Definition CharacterDatabase.h:519
@ CHAR_INS_RECOVERY_ITEM_LOOT
Definition CharacterDatabase.h:520
@ CONFIG_ITEMDELETE_METHOD
Definition WorldConfig.h:120
@ CONFIG_ITEMDELETE_QUALITY
Definition WorldConfig.h:359
@ CONFIG_ITEMDELETE_ITEM_LEVEL
Definition WorldConfig.h:360
#define sWorld
Definition World.h:337
Definition ItemTemplate.h:619
uint32 Quality
Definition ItemTemplate.h:626
uint32 ItemLevel
Definition ItemTemplate.h:635

References CHAR_INS_RECOVERY_ITEM, CHAR_INS_RECOVERY_ITEM_LOOT, CharacterDatabase, CONFIG_ITEMDELETE_ITEM_LEVEL, CONFIG_ITEMDELETE_METHOD, CONFIG_ITEMDELETE_QUALITY, ObjectGuid::GetCounter(), Item::GetEnchantmentsString(), Object::GetEntry(), Object::GetGUID(), Object::GetGuidValue(), Item::GetItemRandomPropertyId(), Item::GetOwnerGUID(), Item::GetTemplate(), Item::IsSoulBound(), ITEM_FIELD_CREATOR, ItemTemplate::ItemLevel, ItemTemplate::Quality, PreparedStatementBase::SetData(), and sWorld.

Referenced by WorldSession::DoLootRelease(), WorldSession::HandleDestroyItemOpcode(), and WorldSession::HandleSellItemOpcode().