diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index 864fd1abd..427314812 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -148,6 +148,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_INS_ACCOUNT_INSTANCE_LOCK_TIMES, "INSERT INTO account_instance_times (accountId, instanceId, releaseTime) VALUES (?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_MATCH_MAKER_RATING, "SELECT matchMakerRating, maxMMR FROM character_arena_stats WHERE guid = ? AND slot = ?", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_CHARACTER_COUNT, "SELECT account, COUNT(guid) FROM characters WHERE account = ? GROUP BY account", CONNECTION_ASYNC); + PrepareStatement(CHAR_UPD_NAME_BY_GUID, "UPDATE characters SET name = ? WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_DECLINED_NAME, "DELETE FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC); // Guild handling diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h index 7b5a17ed9..b4203cfdf 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.h +++ b/src/server/database/Database/Implementation/CharacterDatabase.h @@ -132,6 +132,7 @@ enum CharacterDatabaseStatements : uint32 CHAR_INS_ACCOUNT_INSTANCE_LOCK_TIMES, CHAR_SEL_MATCH_MAKER_RATING, CHAR_SEL_CHARACTER_COUNT, + CHAR_UPD_NAME_BY_GUID, CHAR_DEL_DECLINED_NAME, CHAR_INS_GUILD, diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp index 4bb6228bb..e8dad72fa 100644 --- a/src/server/scripts/Commands/cs_character.cpp +++ b/src/server/scripts/Commands/cs_character.cpp @@ -22,18 +22,19 @@ Comment: All character related commands Category: commandscripts EndScriptData */ +#include "ScriptMgr.h" #include "AccountMgr.h" #include "Chat.h" -#include "Implementation/CharacterDatabase.h" +#include "DatabaseEnv.h" +#include "DBCStores.h" +#include "Log.h" +#include "ObjectAccessor.h" #include "ObjectMgr.h" #include "Player.h" #include "PlayerDump.h" #include "ReputationMgr.h" -#include "ScriptMgr.h" - -#if AC_COMPILER == AC_COMPILER_GNU -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif +#include "World.h" +#include "WorldSession.h" using namespace Acore::ChatCommands; @@ -272,20 +273,21 @@ public: } } - static bool HandleCharacterTitlesCommand(ChatHandler* handler, char const* args) + static bool HandleCharacterTitlesCommand(ChatHandler* handler, Optional player) { - if (!*args) - return false; + if (!player) + player = PlayerIdentifier::FromTargetOrSelf(handler); - Player* target; - if (!handler->extractPlayerTarget((char*)args, &target)) + if (!player || !player->IsConnected()) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); return false; + } - if (!target) - return false; + Player const* target = player->GetConnectedPlayer(); LocaleConstant loc = handler->GetSessionDbcLocale(); - char const* targetName = target->GetName().c_str(); char const* knownStr = handler->GetAcoreString(LANG_KNOWN); // Search in CharTitles.dbc @@ -295,22 +297,24 @@ public: if (titleInfo && target->HasTitle(titleInfo)) { - std::string name = target->getGender() == GENDER_MALE ? titleInfo->nameMale[loc] : titleInfo->nameFemale[loc]; - if (name.empty()) + char const* name = target->getGender() == GENDER_MALE ? titleInfo->nameMale[loc] : titleInfo->nameFemale[loc]; + if (!*name) + name = (target->getGender() == GENDER_MALE ? titleInfo->nameMale[sWorld->GetDefaultDbcLocale()] : titleInfo->nameFemale[sWorld->GetDefaultDbcLocale()]); + + if (!*name) continue; - char const* activeStr = target && target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->bit_index - ? handler->GetAcoreString(LANG_ACTIVE) - : ""; + char const* activeStr = ""; + if (target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->bit_index) + activeStr = handler->GetAcoreString(LANG_ACTIVE); - char titleNameStr[80]; - snprintf(titleNameStr, 80, name.c_str(), targetName); + std::string titleName = Acore::StringFormat(name, player->GetName().c_str()); // send title in "id (idx:idx) - [namedlink locale]" format if (handler->GetSession()) - handler->PSendSysMessage(LANG_TITLE_LIST_CHAT, id, titleInfo->bit_index, id, titleNameStr, localeNames[loc], knownStr, activeStr); + handler->PSendSysMessage(LANG_TITLE_LIST_CHAT, id, titleInfo->bit_index, id, titleName.c_str(), localeNames[loc], knownStr, activeStr); else - handler->PSendSysMessage(LANG_TITLE_LIST_CONSOLE, id, titleInfo->bit_index, name.c_str(), localeNames[loc], knownStr, activeStr); + handler->PSendSysMessage(LANG_TITLE_LIST_CONSOLE, id, titleInfo->bit_index, name, localeNames[loc], knownStr, activeStr); } } @@ -318,51 +322,99 @@ public: } //rename characters - static bool HandleCharacterRenameCommand(ChatHandler* handler, char const* args) + static bool HandleCharacterRenameCommand(ChatHandler* handler, Optional player, Optional newNameV) { - char* nameStr = strtok((char*)args, " "); - char* reserveNameStr = strtok(nullptr, " "); - - if (!reserveNameStr && nameStr && atoi(nameStr) == 1) - { - reserveNameStr = nameStr; - nameStr = nullptr; - } - bool reserveName = reserveNameStr != nullptr && atoi(reserveNameStr) == 1; - - Player* target; - ObjectGuid targetGuid; - std::string targetName; - if (!handler->extractPlayerTarget(nameStr, &target, &targetGuid, &targetName)) + if (!player && newNameV) return false; - if (target) - { - // check online security - if (handler->HasLowerSecurity(target)) - return false; + if (!player) + player = PlayerIdentifier::FromTarget(handler); - handler->PSendSysMessage(LANG_RENAME_PLAYER, handler->GetNameLink(target).c_str()); - target->SetAtLoginFlag(AT_LOGIN_RENAME); + if (!player) + return false; + + if (handler->HasLowerSecurity(nullptr, player->GetGUID())) + return false; + + if (newNameV) + { + std::string newName{ *newNameV }; + if (!normalizePlayerName(newName)) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + if (ObjectMgr::CheckPlayerName(newName, true) != CHAR_NAME_SUCCESS) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + if (sObjectMgr->IsReservedName(newName)) + { + handler->SendSysMessage(LANG_RESERVED_NAME); + handler->SetSentErrorMessage(true); + return false; + } + + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_NAME); + stmt->setString(0, newName); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (result) + { + handler->PSendSysMessage(LANG_RENAME_PLAYER_ALREADY_EXISTS, newName.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + // Remove declined name from db + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME); + stmt->setUInt32(0, player->GetGUID().GetCounter()); + CharacterDatabase.Execute(stmt); + + if (Player* target = player->GetConnectedPlayer()) + { + target->SetName(newName); + + if (WorldSession* session = target->GetSession()) + session->KickPlayer("HandleCharacterRenameCommand GM Command renaming character"); + } + else + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_NAME_BY_GUID); + stmt->setString(0, newName); + stmt->setUInt32(1, player->GetGUID().GetCounter()); + CharacterDatabase.Execute(stmt); + } + + sWorld->UpdateGlobalNameData(player->GetGUID().GetCounter(), player->GetName().c_str(), newName); + sWorld->UpdateGlobalPlayerData(player->GetGUID().GetCounter(), PLAYER_UPDATE_DATA_NAME, newName); + + handler->PSendSysMessage(LANG_RENAME_PLAYER_WITH_NEW_NAME, player->GetName().c_str(), newName.c_str()); } else { - // check offline security - if (handler->HasLowerSecurity(nullptr, targetGuid)) - return false; + if (Player* target = player->GetConnectedPlayer()) + { + handler->PSendSysMessage(LANG_RENAME_PLAYER, handler->GetNameLink(target).c_str()); + target->SetAtLoginFlag(AT_LOGIN_RENAME); + } + else + { + // check offline security + if (handler->HasLowerSecurity(nullptr, player->GetGUID())) + return false; - std::string oldNameLink = handler->playerLink(targetName); - handler->PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), targetGuid.GetCounter()); + handler->PSendSysMessage(LANG_RENAME_PLAYER_GUID, handler->playerLink(*player).c_str(), player->GetGUID().GetCounter()); - auto* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); - stmt->setUInt16(0, uint16(AT_LOGIN_RENAME)); - stmt->setUInt32(1, targetGuid.GetCounter()); - CharacterDatabase.Execute(stmt); - } - - if (reserveName) - { - sObjectMgr->AddReservedPlayerName(targetName); + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); + stmt->setUInt16(0, uint16(AT_LOGIN_RENAME)); + stmt->setUInt32(1, player->GetGUID().GetCounter()); + CharacterDatabase.Execute(stmt); + } } return true; @@ -393,96 +445,90 @@ public: } // customize characters - static bool HandleCharacterCustomizeCommand(ChatHandler* handler, char const* args) + static bool HandleCharacterCustomizeCommand(ChatHandler* handler, Optional player) { - Player* target; - ObjectGuid targetGuid; - std::string targetName; - if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + if (!player) + player = PlayerIdentifier::FromTarget(handler); + if (!player) return false; - auto* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); - stmt->setUInt16(0, uint16(AT_LOGIN_CUSTOMIZE)); - if (target) + if (Player* target = player->GetConnectedPlayer()) { handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER, handler->GetNameLink(target).c_str()); target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE); - stmt->setUInt32(1, target->GetGUID().GetCounter()); } else { - std::string oldNameLink = handler->playerLink(targetName); - stmt->setUInt32(1, targetGuid.GetCounter()); - handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), targetGuid.GetCounter()); + handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, handler->playerLink(*player).c_str(), player->GetGUID().GetCounter()); + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); + stmt->setUInt16(0, static_cast(AT_LOGIN_CUSTOMIZE)); + stmt->setUInt32(1, player->GetGUID().GetCounter()); + CharacterDatabase.Execute(stmt); } - CharacterDatabase.Execute(stmt); return true; } - static bool HandleCharacterChangeFactionCommand(ChatHandler* handler, char const* args) + static bool HandleCharacterChangeFactionCommand(ChatHandler* handler, Optional player) { - Player* target; - ObjectGuid targetGuid; - std::string targetName; - - if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + if (!player) + player = PlayerIdentifier::FromTarget(handler); + if (!player) return false; - auto* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); - stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_FACTION)); - if (target) + if (Player* target = player->GetConnectedPlayer()) { handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER, handler->GetNameLink(target).c_str()); target->SetAtLoginFlag(AT_LOGIN_CHANGE_FACTION); - stmt->setUInt32(1, target->GetGUID().GetCounter()); } else { - std::string oldNameLink = handler->playerLink(targetName); - handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), targetGuid.GetCounter()); - stmt->setUInt32(1, targetGuid.GetCounter()); + handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, handler->playerLink(*player).c_str(), player->GetGUID().GetCounter()); + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); + stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_FACTION)); + stmt->setUInt32(1, player->GetGUID().GetCounter()); + CharacterDatabase.Execute(stmt); } - CharacterDatabase.Execute(stmt); return true; } - static bool HandleCharacterChangeRaceCommand(ChatHandler* handler, char const* args) + static bool HandleCharacterChangeRaceCommand(ChatHandler* handler, Optional player) { - Player* target; - ObjectGuid targetGuid; - std::string targetName; - if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + if (!player) + player = PlayerIdentifier::FromTarget(handler); + if (!player) return false; - auto* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); - stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_RACE)); - if (target) + if (Player* target = player->GetConnectedPlayer()) { - // TODO : add text into database handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER, handler->GetNameLink(target).c_str()); target->SetAtLoginFlag(AT_LOGIN_CHANGE_RACE); - stmt->setUInt32(1, target->GetGUID().GetCounter()); } else { - std::string oldNameLink = handler->playerLink(targetName); - // TODO : add text into database - handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), targetGuid.GetCounter()); - stmt->setUInt32(1, targetGuid.GetCounter()); + handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, handler->playerLink(*player).c_str(), player->GetGUID().GetCounter()); + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); + stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_RACE)); + stmt->setUInt32(1, player->GetGUID().GetCounter()); + CharacterDatabase.Execute(stmt); } - CharacterDatabase.Execute(stmt); return true; } - static bool HandleCharacterReputationCommand(ChatHandler* handler, char const* args) + static bool HandleCharacterReputationCommand(ChatHandler* handler, Optional player) { - Player* target; - if (!handler->extractPlayerTarget((char*)args, &target)) + if (!player) + player = PlayerIdentifier::FromTargetOrSelf(handler); + if (!player || !player->IsConnected()) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); return false; + } + Player const* target = player->GetConnectedPlayer(); LocaleConstant loc = handler->GetSessionDbcLocale(); FactionStateList const& targetFSL = target->GetReputationMgr().GetStateList(); @@ -531,16 +577,20 @@ public: * @param args the search string which either contains a player GUID or a part fo the character-name */ - static bool HandleCharacterDeletedListCommand(ChatHandler* handler, char const* args) + static bool HandleCharacterDeletedListCommand(ChatHandler* handler, Optional needleStr) { + std::string needle; + if (needleStr) + needle.assign(*needleStr); DeletedInfoList foundList; - if (!GetDeletedCharacterInfoList(foundList, args)) + if (!GetDeletedCharacterInfoList(foundList, needle)) return false; // if no characters have been found, output a warning if (foundList.empty()) { handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY); + handler->SetSentErrorMessage(true); return false; } @@ -560,59 +610,52 @@ public: * * @param args the search string which either contains a player GUID or a part of the character-name */ - static bool HandleCharacterDeletedRestoreCommand(ChatHandler* handler, char const* args) + static bool HandleCharacterDeletedRestoreCommand(ChatHandler* handler, std::string needle, Optional newCharName, Optional newAccount) { - // It is required to submit at least one argument - if (!*args) - return false; - - std::string searchString; - std::string newCharName; - uint32 newAccount = 0; - - // GCC by some strange reason fail build code without temporary variable - std::istringstream params(args); - params >> searchString >> newCharName >> newAccount; - DeletedInfoList foundList; - if (!GetDeletedCharacterInfoList(foundList, searchString)) + if (!GetDeletedCharacterInfoList(foundList, needle)) return false; if (foundList.empty()) { handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY); + handler->SetSentErrorMessage(true); return false; } handler->SendSysMessage(LANG_CHARACTER_DELETED_RESTORE); HandleCharacterDeletedListHelper(foundList, handler); - if (newCharName.empty()) + if (!newCharName) { // Drop nonexisting account cases for (DeletedInfoList::iterator itr = foundList.begin(); itr != foundList.end(); ++itr) HandleCharacterDeletedRestoreHelper(*itr, handler); + return true; } - else if (foundList.size() == 1 && normalizePlayerName(newCharName)) + + if (foundList.size() == 1) { + std::string newName{ *newCharName }; DeletedInfo delInfo = foundList.front(); // update name - delInfo.name = newCharName; + delInfo.name = newName; // if new account provided update deleted info - if (newAccount && newAccount != delInfo.accountId) + if (newAccount) { - delInfo.accountId = newAccount; - AccountMgr::GetName(newAccount, delInfo.accountName); + delInfo.accountId = newAccount->GetID(); + delInfo.accountName = newAccount->GetName(); } HandleCharacterDeletedRestoreHelper(delInfo, handler); + return true; } - else - handler->SendSysMessage(LANG_CHARACTER_DELETED_ERR_RENAME); - return true; + handler->SendSysMessage(LANG_CHARACTER_DELETED_ERR_RENAME); + handler->SetSentErrorMessage(true); + return false; } /** @@ -625,19 +668,16 @@ public: * * @param args the search string which either contains a player GUID or a part fo the character-name */ - static bool HandleCharacterDeletedDeleteCommand(ChatHandler* handler, char const* args) + static bool HandleCharacterDeletedDeleteCommand(ChatHandler* handler, std::string needle) { - // It is required to submit at least one argument - if (!*args) - return false; - DeletedInfoList foundList; - if (!GetDeletedCharacterInfoList(foundList, args)) + if (!GetDeletedCharacterInfoList(foundList, needle)) return false; if (foundList.empty()) { handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY); + handler->SetSentErrorMessage(true); return false; } @@ -662,25 +702,16 @@ public: * * @param args the search string which either contains a player GUID or a part of the character-name */ - static bool HandleCharacterDeletedPurgeCommand(ChatHandler* /*handler*/, char const* args) + static bool HandleCharacterDeletedPurgeCommand(ChatHandler* /*handler*/, Optional days) { - int32 keepDays = sWorld->getIntConfig(CONFIG_CHARDELETE_KEEP_DAYS); + int32 keepDays = static_cast(sWorld->getIntConfig(CONFIG_CHARDELETE_KEEP_DAYS)); - char* daysStr = strtok((char*)args, " "); - if (daysStr) - { - if (!isNumeric(daysStr)) - return false; - - keepDays = atoi(daysStr); - if (keepDays < 0) - return false; - } - // config option value 0 -> disabled and can't be used - else if (keepDays <= 0) + if (days) + keepDays = static_cast(*days); + else if (keepDays <= 0) // config option value 0 -> disabled and can't be used return false; - Player::DeleteOldCharacters(uint32(keepDays)); + Player::DeleteOldCharacters(static_cast(keepDays)); return true; } @@ -692,46 +723,22 @@ public: * * @param args the search string which either contains a player GUID or a part of the character-name */ - static bool HandleCharacterEraseCommand(ChatHandler* handler, char const* args) + static bool HandleCharacterEraseCommand(ChatHandler* handler, PlayerIdentifier player) { - if (!*args) - return false; - - char* characterName_str = strtok((char*)args, " "); - if (!characterName_str) - return false; - - std::string characterName = characterName_str; - if (!normalizePlayerName(characterName)) - return false; - - ObjectGuid characterGuid; uint32 accountId; - - Player* player = ObjectAccessor::FindPlayerByName(characterName); - if (player) + if (Player* target = player.GetConnectedPlayer()) { - characterGuid = player->GetGUID(); - accountId = player->GetSession()->GetAccountId(); - player->GetSession()->KickPlayer("HandleCharacterEraseCommand"); + accountId = target->GetSession()->GetAccountId(); + target->GetSession()->KickPlayer("HandleCharacterEraseCommand GM Command deleting character"); } else - { - characterGuid = sObjectMgr->GetPlayerGUIDByName(characterName); - if (!characterGuid) - { - handler->PSendSysMessage(LANG_NO_PLAYER, characterName.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - accountId = sObjectMgr->GetPlayerAccountIdByGUID(characterGuid.GetCounter()); - } + accountId = sObjectMgr->GetPlayerAccountIdByGUID(player.GetGUID().GetCounter()); std::string accountName; AccountMgr::GetName(accountId, accountName); - Player::DeleteFromDB(characterGuid.GetCounter(), accountId, true, true); - handler->PSendSysMessage(LANG_CHARACTER_DELETED, characterName.c_str(), characterGuid.GetCounter(), accountName.c_str(), accountId); + Player::DeleteFromDB(player.GetGUID().GetCounter(), accountId, true, true); + handler->PSendSysMessage(LANG_CHARACTER_DELETED, player.GetName().c_str(), player.GetGUID().GetCounter(), accountName.c_str(), accountId); return true; } @@ -761,53 +768,11 @@ public: return true; } - static bool HandlePDumpLoadCommand(ChatHandler* handler, char const* args) + static bool ValidatePDumpTarget(ChatHandler* handler, std::string& name, Optional characterName, Optional characterGUID) { - if (!*args) - return false; - - char* fileStr = strtok((char*)args, " "); - if (!fileStr) - return false; - - char* accountStr = strtok(nullptr, " "); - if (!accountStr) - return false; - - std::string accountName = accountStr; - if (!Utf8ToUpperOnlyLatin(accountName)) + if (characterName) { - handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - - uint32 accountId = AccountMgr::GetId(accountName); - if (!accountId) - { - accountId = atoi(accountStr); // use original string - if (!accountId) - { - handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - } - - if (!AccountMgr::GetName(accountId, accountName)) - { - handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - - char* guidStr = nullptr; - char* nameStr = strtok(nullptr, " "); - - std::string name; - if (nameStr) - { - name = nameStr; + name.assign(*characterName); // normalize the name if specified and check if it exists if (!normalizePlayerName(name)) { @@ -822,45 +787,42 @@ public: handler->SetSentErrorMessage(true); return false; } - - guidStr = strtok(nullptr, " "); } - ObjectGuid::LowType guid = 0; - - if (guidStr) + if (characterGUID) { - guid = uint32(atoi(guidStr)); - if (!guid) + if (sObjectMgr->GetPlayerAccountIdByGUID(*characterGUID)) { - handler->PSendSysMessage(LANG_INVALID_CHARACTER_GUID); - handler->SetSentErrorMessage(true); - return false; - } - - if (sObjectMgr->GetPlayerAccountIdByGUID(guid)) - { - handler->PSendSysMessage(LANG_CHARACTER_GUID_IN_USE, guid); + handler->PSendSysMessage(LANG_CHARACTER_GUID_IN_USE, *characterGUID); handler->SetSentErrorMessage(true); return false; } } - switch (PlayerDumpReader().LoadDump(fileStr, accountId, name, guid)) + return true; + } + + static bool HandlePDumpLoadCommand(ChatHandler* handler, std::string fileName, AccountIdentifier account, Optional characterName, Optional characterGUID) + { + std::string name; + if (!ValidatePDumpTarget(handler, name, characterName, characterGUID)) + return false; + + switch (PlayerDumpReader().LoadDump(fileName, account, name, characterGUID.value_or(0))) { case DUMP_SUCCESS: handler->PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS); break; case DUMP_FILE_OPEN_ERROR: - handler->PSendSysMessage(LANG_FILE_OPEN_FAIL, fileStr); + handler->PSendSysMessage(LANG_FILE_OPEN_FAIL, fileName.c_str()); handler->SetSentErrorMessage(true); return false; case DUMP_FILE_BROKEN: - handler->PSendSysMessage(LANG_DUMP_BROKEN, fileStr); + handler->PSendSysMessage(LANG_DUMP_BROKEN, fileName.c_str()); handler->SetSentErrorMessage(true); return false; case DUMP_TOO_MANY_CHARS: - handler->PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL, accountName.c_str(), accountId); + handler->PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL, account.GetName().c_str(), account.GetID()); handler->SetSentErrorMessage(true); return false; default: @@ -872,79 +834,15 @@ public: return true; } - static bool HandlePDumpWriteCommand(ChatHandler* handler, char const* args) + static bool HandlePDumpWriteCommand(ChatHandler* handler, std::string fileName, PlayerIdentifier player) { - if (!*args) - return false; - - char* fileStr = strtok((char*)args, " "); - char* playerStr = strtok(nullptr, " "); - - if (!fileStr && !playerStr) - { - QueryResult result = CharacterDatabase.PQuery("SELECT guid FROM characters"); - if (!result) - return true; - do - { - uint64 _guid = result->Fetch()[0].GetUInt64(); - char buff[20]; - sprintf(buff, "%u", (uint32)_guid); - switch(PlayerDumpWriter().WriteDump(buff, uint32(_guid))) - { - case DUMP_SUCCESS: - handler->PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS); - break; - case DUMP_FILE_OPEN_ERROR: - handler->PSendSysMessage(LANG_FILE_OPEN_FAIL, buff); - handler->SetSentErrorMessage(true); - return false; - case DUMP_CHARACTER_DELETED: - handler->PSendSysMessage(LANG_COMMAND_EXPORT_DELETED_CHAR); - handler->SetSentErrorMessage(true); - return false; - default: - handler->PSendSysMessage(LANG_COMMAND_EXPORT_FAILED); - handler->SetSentErrorMessage(true); - return false; - } - } while(result->NextRow()); - } - - if (!fileStr || !playerStr) - return false; - - ObjectGuid guid; - // character name can't start from number - if (isNumeric(playerStr)) - guid = ObjectGuid::Create(atoi(playerStr)); - else - { - std::string name = handler->extractPlayerNameFromLink(playerStr); - if (name.empty()) - { - handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); - handler->SetSentErrorMessage(true); - return false; - } - - guid = sObjectMgr->GetPlayerGUIDByName(name); - } - - if (!sObjectMgr->GetPlayerAccountIdByGUID(guid.GetCounter())) - { - handler->PSendSysMessage(LANG_PLAYER_NOT_FOUND); - handler->SetSentErrorMessage(true); - return false; - } - - switch (PlayerDumpWriter().WriteDump(fileStr, guid.GetCounter())) + switch (PlayerDumpWriter().WriteDump(fileName, player.GetGUID().GetCounter())) { case DUMP_SUCCESS: handler->PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS); break; case DUMP_FILE_OPEN_ERROR: - handler->PSendSysMessage(LANG_FILE_OPEN_FAIL, fileStr); + handler->PSendSysMessage(LANG_FILE_OPEN_FAIL, fileName.c_str()); handler->SetSentErrorMessage(true); return false; case DUMP_CHARACTER_DELETED: @@ -960,30 +858,20 @@ public: return true; } - static bool HandleCharacterCheckBankCommand(ChatHandler* handler, char const* /*args*/) + static bool HandleCharacterCheckBankCommand(ChatHandler* handler) { handler->GetSession()->SendShowBank(handler->GetSession()->GetPlayer()->GetGUID()); return true; } - static bool HandleCharacterCheckBagCommand(ChatHandler* handler, char const* args) + static bool HandleCharacterCheckBagCommand(ChatHandler* handler, uint8 BagSlot) { - if (!*args) - return false; + Player* target = handler->getSelectedPlayerOrSelf(); - char* Slot = strtok((char*)args, " "); - - if (!Slot) - return false; - - Player* player = handler->getSelectedPlayerOrSelf(); - - if (!player) + if (!target) return false; uint8 Counter = 0; - uint8 BagSlot = atoi(Slot); - switch (BagSlot) { case 2: @@ -1009,7 +897,7 @@ public: { for (uint32 i = 23; i < 39; i++) { - if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i)) + if (Item* item = target->GetItemByPos(INVENTORY_SLOT_BAG_0, i)) { Counter++; std::ostringstream ItemString; @@ -1021,11 +909,11 @@ public: } else { - if (Bag* bag = player->GetBagByPos(BagSlot)) + if (Bag* bag = target->GetBagByPos(BagSlot)) { for (uint32 i = 0; i < bag->GetBagSize(); i++) { - if (Item* item = player->GetItemByPos(BagSlot, i)) + if (Item* item = target->GetItemByPos(BagSlot, i)) { Counter++; std::ostringstream ItemString; @@ -1041,7 +929,7 @@ public: return true; } - static bool HandleCharacterCheckProfessionCommand(ChatHandler* handler, char const*) + static bool HandleCharacterCheckProfessionCommand(ChatHandler* handler) { Player* player = handler->getSelectedPlayerOrSelf();