feat(Core/ItemHandler): Optional item recovery (#2442)

This commit is contained in:
IntelligentQuantum
2019-12-09 10:33:33 +03:30
committed by Stoabrogga
parent e337f1e38d
commit b6c0f58dda
8 changed files with 125 additions and 13 deletions
@@ -0,0 +1,10 @@
INSERT INTO `version_db_characters` (`sql_rev`) VALUES ('1575656087867346414');
CREATE TABLE IF NOT EXISTS `recovery_item` (
`Id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`Guid` int(11) unsigned NOT NULL DEFAULT 0,
`ItemEntry` mediumint(8) unsigned NOT NULL DEFAULT 0,
`Count` int(11) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`Id`),
KEY `idx_guid` (`Guid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
@@ -566,4 +566,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UPD_QUEST_TRACK_GM_COMPLETE, "UPDATE quest_tracker SET completed_by_gm = 1 WHERE id = ? AND character_guid = ? ORDER BY quest_accept_time DESC LIMIT 1", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_QUEST_TRACK_GM_COMPLETE, "UPDATE quest_tracker SET completed_by_gm = 1 WHERE id = ? AND character_guid = ? ORDER BY quest_accept_time DESC LIMIT 1", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_QUEST_TRACK_COMPLETE_TIME, "UPDATE quest_tracker SET quest_complete_time = NOW() WHERE id = ? AND character_guid = ? ORDER BY quest_accept_time DESC LIMIT 1", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_QUEST_TRACK_COMPLETE_TIME, "UPDATE quest_tracker SET quest_complete_time = NOW() WHERE id = ? AND character_guid = ? ORDER BY quest_accept_time DESC LIMIT 1", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_QUEST_TRACK_ABANDON_TIME, "UPDATE quest_tracker SET quest_abandon_time = NOW() WHERE id = ? AND character_guid = ? ORDER BY quest_accept_time DESC LIMIT 1", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_QUEST_TRACK_ABANDON_TIME, "UPDATE quest_tracker SET quest_abandon_time = NOW() WHERE id = ? AND character_guid = ? ORDER BY quest_accept_time DESC LIMIT 1", CONNECTION_ASYNC);
// Recovery Item
PrepareStatement(CHAR_INS_RECOVERY_ITEM, "INSERT INTO recovery_item (Guid, ItemEntry, Count) VALUES (?, ?, ?)", CONNECTION_SYNCH);
PrepareStatement(CHAR_DEL_RECOVERY_ITEM, "DELETE FROM recovery_item WHERE Guid = ? AND ItemEntry = ? ORDER BY Id DESC LIMIT 1", CONNECTION_ASYNC);
} }
@@ -500,6 +500,9 @@ enum CharacterDatabaseStatements
CHAR_UPD_QUEST_TRACK_COMPLETE_TIME, CHAR_UPD_QUEST_TRACK_COMPLETE_TIME,
CHAR_UPD_QUEST_TRACK_ABANDON_TIME, CHAR_UPD_QUEST_TRACK_ABANDON_TIME,
CHAR_INS_RECOVERY_ITEM,
CHAR_DEL_RECOVERY_ITEM,
MAX_CHARACTERDATABASE_STATEMENTS MAX_CHARACTERDATABASE_STATEMENTS
}; };
+33
View File
@@ -283,6 +283,8 @@ void WorldSession::HandleDestroyItemOpcode(WorldPacket & recvData)
return; return;
} }
recoveryItem(pItem);
if (count) if (count)
{ {
uint32 i_count = count; uint32 i_count = count;
@@ -699,6 +701,9 @@ void WorldSession::HandleSellItemOpcode(WorldPacket & recvData)
{ {
if (pProto->SellPrice > 0) if (pProto->SellPrice > 0)
{ {
if (sWorld->getBoolConfig(CONFIG_ITEMDELETE_VENDOR))
recoveryItem(pItem);
if (count < pItem->GetCount()) // need split items if (count < pItem->GetCount()) // need split items
{ {
Item* pNewItem = pItem->CloneItem(count, _player); Item* pNewItem = pItem->CloneItem(count, _player);
@@ -784,6 +789,14 @@ void WorldSession::HandleBuybackItem(WorldPacket & recvData)
_player->ItemAddedQuestCheck(pItem->GetEntry(), pItem->GetCount()); _player->ItemAddedQuestCheck(pItem->GetEntry(), pItem->GetCount());
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, pItem->GetEntry(), pItem->GetCount()); _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, pItem->GetEntry(), pItem->GetCount());
_player->StoreItem(dest, pItem, true); _player->StoreItem(dest, pItem, true);
if (sWorld->getBoolConfig(CONFIG_ITEMDELETE_VENDOR))
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_RECOVERY_ITEM);
stmt->setUInt32(0, _player->GetGUID());
stmt->setUInt32(1, pItem->GetEntry());
CharacterDatabase.Execute(stmt);
}
} }
else else
_player->SendEquipError(msg, pItem, NULL); _player->SendEquipError(msg, pItem, NULL);
@@ -1687,3 +1700,23 @@ bool WorldSession::CanUseBank(uint64 bankerGUID) const
return true; return true;
} }
bool WorldSession::recoveryItem(Item* pItem)
{
if (sWorld->getBoolConfig(CONFIG_ITEMDELETE_METHOD)
&& pItem->GetTemplate()->Quality >= sWorld->getIntConfig(CONFIG_ITEMDELETE_QUALITY)
&& pItem->GetTemplate()->ItemLevel >= sWorld->getIntConfig(CONFIG_ITEMDELETE_ITEM_LEVEL))
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_RECOVERY_ITEM);
stmt->setUInt32(0, pItem->GetOwnerGUID());
stmt->setUInt32(1, pItem->GetTemplate()->ItemId);
stmt->setUInt32(2, pItem->GetCount());
CharacterDatabase.Query(stmt);
return true;
}
return false;
}
+2
View File
@@ -952,6 +952,8 @@ class WorldSession
bool CanUseBank(uint64 bankerGUID = 0) const; bool CanUseBank(uint64 bankerGUID = 0) const;
bool recoveryItem(Item* pItem);
// EnumData helpers // EnumData helpers
bool IsLegitCharacterForAccount(uint32 lowGUID) bool IsLegitCharacterForAccount(uint32 lowGUID)
{ {
+6
View File
@@ -1192,6 +1192,12 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_CHARDELETE_MIN_LEVEL] = sConfigMgr->GetIntDefault("CharDelete.MinLevel", 0); m_int_configs[CONFIG_CHARDELETE_MIN_LEVEL] = sConfigMgr->GetIntDefault("CharDelete.MinLevel", 0);
m_int_configs[CONFIG_CHARDELETE_KEEP_DAYS] = sConfigMgr->GetIntDefault("CharDelete.KeepDays", 30); m_int_configs[CONFIG_CHARDELETE_KEEP_DAYS] = sConfigMgr->GetIntDefault("CharDelete.KeepDays", 30);
///- Load the ItemDelete related config options
m_bool_configs[CONFIG_ITEMDELETE_METHOD] = sConfigMgr->GetBoolDefault("ItemDelete.Method", 0);
m_bool_configs[CONFIG_ITEMDELETE_VENDOR] = sConfigMgr->GetBoolDefault("ItemDelete.Vendor", 0);
m_int_configs[CONFIG_ITEMDELETE_QUALITY] = sConfigMgr->GetIntDefault("ItemDelete.Quality", 3);
m_int_configs[CONFIG_ITEMDELETE_ITEM_LEVEL] = sConfigMgr->GetIntDefault("ItemDelete.ItemLevel", 80);
///- Read the "Data" directory from the config file ///- Read the "Data" directory from the config file
std::string dataPath = sConfigMgr->GetStringDefault("DataDir", "./"); std::string dataPath = sConfigMgr->GetStringDefault("DataDir", "./");
if (dataPath.empty() || (dataPath.at(dataPath.length()-1) != '/' && dataPath.at(dataPath.length()-1) != '\\')) if (dataPath.empty() || (dataPath.at(dataPath.length()-1) != '/' && dataPath.at(dataPath.length()-1) != '\\'))
+4
View File
@@ -171,6 +171,8 @@ enum WorldBoolConfigs
CONFIG_LFG_LOCATION_ALL, // Player can join LFG anywhere CONFIG_LFG_LOCATION_ALL, // Player can join LFG anywhere
CONFIG_PRELOAD_ALL_NON_INSTANCED_MAP_GRIDS, CONFIG_PRELOAD_ALL_NON_INSTANCED_MAP_GRIDS,
CONFIG_ALLOW_TWO_SIDE_INTERACTION_EMOTE, CONFIG_ALLOW_TWO_SIDE_INTERACTION_EMOTE,
CONFIG_ITEMDELETE_METHOD,
CONFIG_ITEMDELETE_VENDOR,
BOOL_CONFIG_VALUE_COUNT BOOL_CONFIG_VALUE_COUNT
}; };
@@ -344,6 +346,8 @@ enum WorldIntConfigs
CONFIG_AFK_PREVENT_LOGOUT, CONFIG_AFK_PREVENT_LOGOUT,
CONFIG_ICC_BUFF_HORDE, CONFIG_ICC_BUFF_HORDE,
CONFIG_ICC_BUFF_ALLIANCE, CONFIG_ICC_BUFF_ALLIANCE,
CONFIG_ITEMDELETE_QUALITY,
CONFIG_ITEMDELETE_ITEM_LEVEL,
INT_CONFIG_VALUE_COUNT INT_CONFIG_VALUE_COUNT
}; };
@@ -25,6 +25,7 @@
# NETWORK CONFIG # NETWORK CONFIG
# CONSOLE AND REMOTE ACCESS # CONSOLE AND REMOTE ACCESS
# CHARACTER DELETE OPTIONS # CHARACTER DELETE OPTIONS
# ITEM DELETE OPTIONS
# CUSTOM SERVER OPTIONS # CUSTOM SERVER OPTIONS
# #
################################################################################################### ###################################################################################################
@@ -2966,6 +2967,55 @@ CharDelete.KeepDays = 30
# #
################################################################################################### ###################################################################################################
###################################################################################################
# ITEM DELETE OPTIONS
#
# ItemDelete.Method
# Description: Item deletion behavior.
# Default: 0 - (Completely remove item from the database)
# 1 - (Save Item to database)
ItemDelete.Method = 0
#
# ItemDelete.Vendor
# Description: Saving items into database when the player sells items to vendor
# Default: 0 (disabled)
# 1 (enabled)
#
ItemDelete.Vendor = 0
#
# ItemDelete.Quality
# Description: Saving items into database that have quality greater or equal to ItemDelete.Quality
#
# ID | Color | Quality
# 0 | Grey | Poor
# 1 | White | Common
# 2 | Green | Uncommon
# 3 | Blue | Rare
# 4 | Purple| Epic
# 5 | Orange| Legendary
# 6 | Red | Artifact
# 7 | Gold | Bind to Account
#
# Default: 3
#
ItemDelete.Quality = 3
#
# ItemDelete.ItemLevel
# Description: Saving items into database that are Item Levels greater or equal to ItemDelete.ItemLevel
# Default: 80
#
ItemDelete.ItemLevel = 80
#
###################################################################################################
################################################################################################### ###################################################################################################
# CUSTOM SERVER OPTIONS # CUSTOM SERVER OPTIONS
# #