diff options
author | Treeston <treeston.mmoc@gmail.com> | 2020-09-06 23:36:23 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2022-02-05 13:57:50 +0100 |
commit | 706163743d481e092111401752c9cbb056b35e69 (patch) | |
tree | eca161d19bec27a57de0e7e258019bd40b179149 /src | |
parent | ca498ffab23e9be7a4ffc6ea6adbfa3c01d5e6f6 (diff) |
[3.3.5] Scripts/Commands: .arena command conversion (PR #25407)
(cherry picked from commit b63d655e20a0facf14fc77798c52ea67d8551fa7)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Battlegrounds/ArenaTeam.cpp | 11 | ||||
-rw-r--r-- | src/server/game/Battlegrounds/ArenaTeam.h | 1 | ||||
-rw-r--r-- | src/server/game/Battlegrounds/ArenaTeamMgr.cpp | 26 | ||||
-rw-r--r-- | src/server/game/Battlegrounds/ArenaTeamMgr.h | 5 | ||||
-rw-r--r-- | src/server/game/Battlegrounds/enuminfo_ArenaTeam.cpp | 67 | ||||
-rw-r--r-- | src/server/game/Chat/Chat.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Chat/Chat.h | 1 | ||||
-rw-r--r-- | src/server/game/Chat/ChatCommands/ChatCommandTags.cpp | 93 | ||||
-rw-r--r-- | src/server/game/Chat/ChatCommands/ChatCommandTags.h | 99 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/Language.h | 2 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_arena.cpp | 214 |
11 files changed, 306 insertions, 215 deletions
diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp index f85546b1c73..9047f6d777e 100644 --- a/src/server/game/Battlegrounds/ArenaTeam.cpp +++ b/src/server/game/Battlegrounds/ArenaTeam.cpp @@ -46,8 +46,8 @@ ArenaTeam::~ArenaTeam() bool ArenaTeam::Create(ObjectGuid captainGuid, uint8 type, std::string const& teamName, uint32 backgroundColor, uint8 emblemStyle, uint32 emblemColor, uint8 borderStyle, uint32 borderColor) { - // Check if captain is present - if (!ObjectAccessor::FindPlayer(captainGuid)) + // Check if captain exists + if (!sCharacterCache->GetCharacterCacheByGuid(captainGuid)) return false; // Check if arena team name is already taken @@ -615,12 +615,9 @@ void ArenaTeam::FinishGame(int32 mod) // Update team's rank, start with rank 1 and increase until no team with more rating was found Stats.Rank = 1; - ArenaTeamMgr::ArenaTeamContainer::const_iterator i = sArenaTeamMgr->GetArenaTeamMapBegin(); - for (; i != sArenaTeamMgr->GetArenaTeamMapEnd(); ++i) - { - if (i->second->GetType() == Type && i->second->GetStats().Rating > Stats.Rating) + for (auto [teamId, team] : sArenaTeamMgr->GetArenaTeams()) + if (team->GetType() == Type && team->GetStats().Rating > Stats.Rating) ++Stats.Rank; - } } int32 ArenaTeam::WonAgainst(uint32 ownMMRating, uint32 opponentMMRating, int32& ratingChange) diff --git a/src/server/game/Battlegrounds/ArenaTeam.h b/src/server/game/Battlegrounds/ArenaTeam.h index fcd8b266cd4..e83154b5c29 100644 --- a/src/server/game/Battlegrounds/ArenaTeam.h +++ b/src/server/game/Battlegrounds/ArenaTeam.h @@ -73,6 +73,7 @@ enum ArenaTeamEvents ERR_ARENA_TEAM_DISBANDED_S = 9 // captain name + arena team name }; +// EnumUtils: DESCRIBE THIS enum ArenaTeamTypes { ARENA_TEAM_2v2 = 2, diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp index a85484a2331..51c811f3221 100644 --- a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp +++ b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp @@ -45,36 +45,30 @@ ArenaTeam* ArenaTeamMgr::GetArenaTeamById(uint32 arenaTeamId) const ArenaTeamContainer::const_iterator itr = ArenaTeamStore.find(arenaTeamId); if (itr != ArenaTeamStore.end()) return itr->second; - return nullptr; } -ArenaTeam* ArenaTeamMgr::GetArenaTeamByName(const std::string& arenaTeamName) const +ArenaTeam* ArenaTeamMgr::GetArenaTeamByName(std::string_view arenaTeamName) const { - std::string search = arenaTeamName; - std::transform(search.begin(), search.end(), search.begin(), ::toupper); - for (ArenaTeamContainer::const_iterator itr = ArenaTeamStore.begin(); itr != ArenaTeamStore.end(); ++itr) - { - std::string teamName = itr->second->GetName(); - std::transform(teamName.begin(), teamName.end(), teamName.begin(), ::toupper); - if (search == teamName) - return itr->second; - } + for (auto [teamId, team] : ArenaTeamStore) + if (StringEqualI(arenaTeamName, team->GetName())) + return team; return nullptr; } ArenaTeam* ArenaTeamMgr::GetArenaTeamByCaptain(ObjectGuid guid) const { - for (ArenaTeamContainer::const_iterator itr = ArenaTeamStore.begin(); itr != ArenaTeamStore.end(); ++itr) - if (itr->second->GetCaptain() == guid) - return itr->second; - + for (auto [teamId, team] : ArenaTeamStore) + if (team->GetCaptain() == guid) + return team; return nullptr; } void ArenaTeamMgr::AddArenaTeam(ArenaTeam* arenaTeam) { - ArenaTeamStore[arenaTeam->GetId()] = arenaTeam; + ArenaTeam*& team = ArenaTeamStore[arenaTeam->GetId()]; + ASSERT((team == nullptr) || (team == arenaTeam), "Duplicate arena team with ID %u", arenaTeam->GetId()); + team = arenaTeam; } void ArenaTeamMgr::RemoveArenaTeam(uint32 arenaTeamId) diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.h b/src/server/game/Battlegrounds/ArenaTeamMgr.h index f6b9a7b6dfc..4dc01e845dd 100644 --- a/src/server/game/Battlegrounds/ArenaTeamMgr.h +++ b/src/server/game/Battlegrounds/ArenaTeamMgr.h @@ -33,15 +33,14 @@ public: typedef std::unordered_map<uint32, ArenaTeam*> ArenaTeamContainer; ArenaTeam* GetArenaTeamById(uint32 arenaTeamId) const; - ArenaTeam* GetArenaTeamByName(std::string const& arenaTeamName) const; + ArenaTeam* GetArenaTeamByName(std::string_view arenaTeamName) const; ArenaTeam* GetArenaTeamByCaptain(ObjectGuid guid) const; void LoadArenaTeams(); void AddArenaTeam(ArenaTeam* arenaTeam); void RemoveArenaTeam(uint32 Id); - ArenaTeamContainer::iterator GetArenaTeamMapBegin() { return ArenaTeamStore.begin(); } - ArenaTeamContainer::iterator GetArenaTeamMapEnd() { return ArenaTeamStore.end(); } + ArenaTeamContainer const& GetArenaTeams() const { return ArenaTeamStore; } uint32 GenerateArenaTeamId(); void SetNextArenaTeamId(uint32 Id) { NextArenaTeamId = Id; } diff --git a/src/server/game/Battlegrounds/enuminfo_ArenaTeam.cpp b/src/server/game/Battlegrounds/enuminfo_ArenaTeam.cpp new file mode 100644 index 00000000000..30e7f229f0c --- /dev/null +++ b/src/server/game/Battlegrounds/enuminfo_ArenaTeam.cpp @@ -0,0 +1,67 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ArenaTeam.h" +#include "Define.h" +#include "SmartEnum.h" +#include <stdexcept> + +namespace Trinity::Impl::EnumUtilsImpl +{ + +/******************************************************************\ +|* data for enum 'ArenaTeamTypes' in 'ArenaTeam.h' auto-generated *| +\******************************************************************/ +template <> +TC_API_EXPORT EnumText EnumUtils<ArenaTeamTypes>::ToString(ArenaTeamTypes value) +{ + switch (value) + { + case ARENA_TEAM_2v2: return { "ARENA_TEAM_2v2", "ARENA_TEAM_2v2", "" }; + case ARENA_TEAM_3v3: return { "ARENA_TEAM_3v3", "ARENA_TEAM_3v3", "" }; + case ARENA_TEAM_5v5: return { "ARENA_TEAM_5v5", "ARENA_TEAM_5v5", "" }; + default: throw std::out_of_range("value"); + } +} + +template <> +TC_API_EXPORT size_t EnumUtils<ArenaTeamTypes>::Count() { return 3; } + +template <> +TC_API_EXPORT ArenaTeamTypes EnumUtils<ArenaTeamTypes>::FromIndex(size_t index) +{ + switch (index) + { + case 0: return ARENA_TEAM_2v2; + case 1: return ARENA_TEAM_3v3; + case 2: return ARENA_TEAM_5v5; + default: throw std::out_of_range("index"); + } +} + +template <> +TC_API_EXPORT size_t EnumUtils<ArenaTeamTypes>::ToIndex(ArenaTeamTypes value) +{ + switch (value) + { + case ARENA_TEAM_2v2: return 0; + case ARENA_TEAM_3v3: return 1; + case ARENA_TEAM_5v5: return 2; + default: throw std::out_of_range("value"); + } +} +} diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index ae2d0792f60..1601823a568 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -38,6 +38,8 @@ #include <boost/algorithm/string/replace.hpp> #include <sstream> +Player* ChatHandler::GetPlayer() { return m_session ? m_session->GetPlayer() : nullptr; } + // Lazy loading of the command table cache from commands and the // ScriptMgr should be thread safe since the player commands, // cli commands and ScriptMgr updates are all dispatched one after diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index 7abf8452a3a..3aeb1a6b702 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -41,6 +41,7 @@ class TC_GAME_API ChatHandler { public: WorldSession* GetSession() { return m_session; } + Player* GetPlayer(); explicit ChatHandler(WorldSession* session) : m_session(session), sentErrorMessage(false) { } virtual ~ChatHandler() { } diff --git a/src/server/game/Chat/ChatCommands/ChatCommandTags.cpp b/src/server/game/Chat/ChatCommands/ChatCommandTags.cpp new file mode 100644 index 00000000000..0f11f1cd66f --- /dev/null +++ b/src/server/game/Chat/ChatCommands/ChatCommandTags.cpp @@ -0,0 +1,93 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ChatCommandTags.h" + +#include "CharacterCache.h" +#include "Chat.h" +#include "ChatCommandArgs.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "Player.h" + +Optional<std::string_view> Trinity::ChatCommands::QuotedString::TryConsume(std::string_view args) +{ + if (args.empty()) + return std::nullopt; + if ((args[0] != '"') && (args[0] != '\'')) + return Trinity::Impl::ChatCommands::ArgInfo<std::string>::TryConsume(*this, args); + + char const QUOTE = args[0]; + for (size_t i = 1; i < args.length(); ++i) + { + if (args[i] == QUOTE) + { + auto [remainingToken, tail] = Trinity::Impl::ChatCommands::tokenize(args.substr(i + 1)); + if (remainingToken.empty()) // if this is not empty, then we did not consume the full token + return tail; + else + return std::nullopt; + } + + if (args[i] == '\\') + { + ++i; + if (!(i < args.length())) + break; + } + std::string::push_back(args[i]); + } + // if we reach this, we did not find a closing quote + return std::nullopt; +} + +Optional<std::string_view> Trinity::ChatCommands::PlayerIdentifier::TryConsume(std::string_view args) +{ + Variant<Hyperlink<player>, std::string_view> name; + Optional<std::string_view> next = Trinity::Impl::ChatCommands::ArgInfo<decltype(name)>::TryConsume(name, args); + if (!next) + return std::nullopt; + + _name = static_cast<std::string_view>(name); + normalizePlayerName(_name); + + if ((_player = ObjectAccessor::FindPlayerByName(_name))) + _guid = _player->GetGUID(); + else if (!(_guid = sCharacterCache->GetCharacterGuidByName(_name))) + return std::nullopt; + + return next; +} + +Trinity::ChatCommands::PlayerIdentifier::PlayerIdentifier(Player& player) + : _name(player.GetName()), _guid(player.GetGUID()), _player(&player) {} + +/*static*/ Optional<Trinity::ChatCommands::PlayerIdentifier> Trinity::ChatCommands::PlayerIdentifier::FromTarget(ChatHandler* handler) +{ + if (Player* player = handler->GetPlayer()) + if (Player* target = player->GetSelectedPlayer()) + return { *target }; + return std::nullopt; + +} + +/*static*/ Optional<Trinity::ChatCommands::PlayerIdentifier> Trinity::ChatCommands::PlayerIdentifier::FromSelf(ChatHandler* handler) +{ + if (Player* player = handler->GetPlayer()) + return { *player }; + return std::nullopt; +} diff --git a/src/server/game/Chat/ChatCommands/ChatCommandTags.h b/src/server/game/Chat/ChatCommands/ChatCommandTags.h index cf6df77da8d..19872430f1c 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommandTags.h +++ b/src/server/game/Chat/ChatCommands/ChatCommandTags.h @@ -21,6 +21,7 @@ #include "advstd.h" #include "ChatCommandHelpers.h" #include "Hyperlinks.h" +#include "ObjectGuid.h" #include "Optional.h" #include "Util.h" #include <cmath> @@ -33,6 +34,9 @@ #include <utility> #include <variant> +class ChatHandler; +class Player; + namespace Trinity::Impl::ChatCommands { struct ContainerTag {}; @@ -109,39 +113,82 @@ namespace Trinity::ChatCommands } }; + struct QuotedString : std::string, Trinity::Impl::ChatCommands::ContainerTag + { + using value_type = std::string; + + TC_GAME_API Optional<std::string_view> TryConsume(std::string_view args); + }; + + struct TC_GAME_API PlayerIdentifier : Trinity::Impl::ChatCommands::ContainerTag + { + using value_type = Player*; + + PlayerIdentifier() : _name(), _guid(), _player(nullptr) {} + PlayerIdentifier(Player& player); + + template <typename T> + operator std::enable_if_t<std::is_base_of_v<T, Player>, T*>() const { return static_cast<T*>(_player); } + operator value_type() const { return _player; } + operator ObjectGuid() { return _guid; } + Player* operator->() const { return _player; } + explicit operator bool() const { return (_player != nullptr); } + bool operator!() const { return (_player == nullptr); } + + std::string const& GetName() { return _name; } + ObjectGuid GetGUID() const { return _guid; } + Player* GetPlayer() const { return _player; } + + Optional<std::string_view> TryConsume(std::string_view args); + + static Optional<PlayerIdentifier> FromTarget(ChatHandler* handler); + static Optional<PlayerIdentifier> FromSelf(ChatHandler* handler); + static Optional<PlayerIdentifier> FromTargetOrSelf(ChatHandler* handler) + { + if (Optional<PlayerIdentifier> fromTarget = FromTarget(handler)) + return fromTarget; + else + return FromSelf(handler); + } + + private: + std::string _name; + ObjectGuid _guid; + Player* _player; + }; + template <typename linktag> struct Hyperlink : Trinity::Impl::ChatCommands::ContainerTag { using value_type = typename linktag::value_type; using storage_type = advstd::remove_cvref_t<value_type>; - public: - operator value_type() const { return val; } - value_type operator*() const { return val; } - storage_type const* operator->() const { return &val; } + operator value_type() const { return val; } + value_type operator*() const { return val; } + storage_type const* operator->() const { return &val; } - Optional<std::string_view> TryConsume(std::string_view args) - { - Trinity::Hyperlinks::HyperlinkInfo info = Trinity::Hyperlinks::ParseSingleHyperlink(args); - // invalid hyperlinks cannot be consumed - if (!info) - return std::nullopt; - - // check if we got the right tag - if (info.tag != linktag::tag()) - return std::nullopt; - - // store value - if (!linktag::StoreTo(val, info.data)) - return std::nullopt; - - // finally, skip any potential delimiters - auto [token, next] = Trinity::Impl::ChatCommands::tokenize(info.tail); - if (token.empty()) /* empty token = first character is delimiter, skip past it */ - return next; - else - return info.tail; - } + Optional<std::string_view> TryConsume(std::string_view args) + { + Trinity::Hyperlinks::HyperlinkInfo info = Trinity::Hyperlinks::ParseSingleHyperlink(args); + // invalid hyperlinks cannot be consumed + if (!info) + return std::nullopt; + + // check if we got the right tag + if (info.tag != linktag::tag()) + return std::nullopt; + + // store value + if (!linktag::StoreTo(val, info.data)) + return std::nullopt; + + // finally, skip any potential delimiters + auto [token, next] = Trinity::Impl::ChatCommands::tokenize(info.tail); + if (token.empty()) /* empty token = first character is delimiter, skip past it */ + return next; + else + return info.tail; + } private: storage_type val; diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 172cf6b700d..eb3cfb44ec9 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -804,7 +804,7 @@ enum TrinityStrings LANG_ARENA_ERROR_NAME_EXISTS = 858, LANG_ARENA_ERROR_SIZE = 859, LANG_ARENA_ERROR_COMBAT = 860, - LANG_AREAN_ERROR_NAME_NOT_FOUND = 861, + LANG_ARENA_ERROR_NAME_NOT_FOUND = 861, LANG_ARENA_ERROR_NOT_MEMBER = 862, LANG_ARENA_ERROR_CAPTAIN = 863, LANG_ARENA_CREATE = 864, diff --git a/src/server/scripts/Commands/cs_arena.cpp b/src/server/scripts/Commands/cs_arena.cpp index bd80a423662..1bcb04b99c0 100644 --- a/src/server/scripts/Commands/cs_arena.cpp +++ b/src/server/scripts/Commands/cs_arena.cpp @@ -33,6 +33,8 @@ EndScriptData */ #include "RBAC.h" #include "WorldSession.h" + +using namespace Trinity::ChatCommands; class arena_commandscript : public CommandScript { public: @@ -56,28 +58,8 @@ public: return commandTable; } - static bool HandleArenaCreateCommand(ChatHandler* handler, char const* args) + static bool HandleArenaCreateCommand(ChatHandler* handler, Optional<PlayerIdentifier> captain, QuotedString name, ArenaTeamTypes type) { - if (!*args) - return false; - - Player* target; - if (!handler->extractPlayerTarget(*args != '"' ? (char*)args : nullptr, &target)) - return false; - - char* tailStr = *args != '"' ? strtok(nullptr, "") : (char*)args; - if (!tailStr) - return false; - - char* name = handler->extractQuotedArg(tailStr); - if (!name) - return false; - - char* typeStr = strtok(nullptr, ""); - if (!typeStr) - return false; - - int8 type = atoi(typeStr); if (sArenaTeamMgr->GetArenaTeamByName(name)) { handler->PSendSysMessage(LANG_ARENA_ERROR_NAME_EXISTS, name); @@ -85,47 +67,36 @@ public: return false; } - if (type == 2 || type == 3 || type == 5 ) + if (!captain) + captain = PlayerIdentifier::FromTargetOrSelf(handler); + if (!captain) + return false; + + if (sCharacterCache->GetCharacterArenaTeamIdByGuid(captain->GetGUID(), type) != 0) { - if (sCharacterCache->GetCharacterArenaTeamIdByGuid(target->GetGUID(), type) != 0) - { - handler->PSendSysMessage(LANG_ARENA_ERROR_SIZE, target->GetName().c_str()); - handler->SetSentErrorMessage(true); - return false; - } + handler->PSendSysMessage(LANG_ARENA_ERROR_SIZE, captain->GetName().c_str()); + handler->SetSentErrorMessage(true); + return false; + } - ArenaTeam* arena = new ArenaTeam(); + ArenaTeam* arena = new ArenaTeam(); - if (!arena->Create(target->GetGUID(), type, name, 4293102085, 101, 4293253939, 4, 4284049911)) - { - delete arena; - handler->SendSysMessage(LANG_BAD_VALUE); - handler->SetSentErrorMessage(true); - return false; - } - - sArenaTeamMgr->AddArenaTeam(arena); - handler->PSendSysMessage(LANG_ARENA_CREATE, arena->GetName().c_str(), arena->GetId(), arena->GetType(), arena->GetCaptain().ToString().c_str()); - } - else + if (!arena->Create(captain->GetGUID(), type, name, 4293102085, 101, 4293253939, 4, 4284049911)) { + delete arena; handler->SendSysMessage(LANG_BAD_VALUE); handler->SetSentErrorMessage(true); return false; } + sArenaTeamMgr->AddArenaTeam(arena); + handler->PSendSysMessage(LANG_ARENA_CREATE, arena->GetName().c_str(), arena->GetId(), arena->GetType(), arena->GetCaptain().ToString().c_str()); + return true; } - static bool HandleArenaDisbandCommand(ChatHandler* handler, char const* args) + static bool HandleArenaDisbandCommand(ChatHandler* handler, uint32 teamId) { - if (!*args) - return false; - - uint32 teamId = atoul(args); - if (!teamId) - return false; - ArenaTeam* arena = sArenaTeamMgr->GetArenaTeamById(teamId); if (!arena) @@ -144,52 +115,25 @@ public: std::string name = arena->GetName(); arena->Disband(); - if (handler->GetSession()) - TC_LOG_DEBUG("bg.arena", "GameMaster: %s %s disbanded arena team type: %u [Id: %u].", - handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUID().ToString().c_str(), arena->GetType(), teamId); - else - TC_LOG_DEBUG("bg.arena", "Console: disbanded arena team type: %u [Id: %u].", arena->GetType(), teamId); - - delete(arena); + delete arena; handler->PSendSysMessage(LANG_ARENA_DISBAND, name.c_str(), teamId); return true; } - static bool HandleArenaRenameCommand(ChatHandler* handler, char const* _args) + static bool HandleArenaRenameCommand(ChatHandler* handler, QuotedString oldName, QuotedString newName) { - if (!*_args) - return false; - - char* args = (char *)_args; - - char const* oldArenaStr = handler->extractQuotedArg(args); - if (!oldArenaStr) - { - handler->SendSysMessage(LANG_BAD_VALUE); - handler->SetSentErrorMessage(true); - return false; - } - - char const* newArenaStr = handler->extractQuotedArg(strtok(nullptr, "")); - if (!newArenaStr) - { - handler->SendSysMessage(LANG_BAD_VALUE); - handler->SetSentErrorMessage(true); - return false; - } - - ArenaTeam* arena = sArenaTeamMgr->GetArenaTeamByName(oldArenaStr); + ArenaTeam* arena = sArenaTeamMgr->GetArenaTeamByName(oldName); if (!arena) { - handler->PSendSysMessage(LANG_AREAN_ERROR_NAME_NOT_FOUND, oldArenaStr); + handler->PSendSysMessage(LANG_ARENA_ERROR_NAME_NOT_FOUND, oldName.c_str()); handler->SetSentErrorMessage(true); return false; } - if (sArenaTeamMgr->GetArenaTeamByName(newArenaStr)) + if (sArenaTeamMgr->GetArenaTeamByName(newName)) { - handler->PSendSysMessage(LANG_ARENA_ERROR_NAME_EXISTS, oldArenaStr); + handler->PSendSysMessage(LANG_ARENA_ERROR_NAME_EXISTS, newName.c_str()); handler->SetSentErrorMessage(true); return false; } @@ -201,45 +145,22 @@ public: return false; } - if (!arena->SetName(newArenaStr)) + if (arena->SetName(newName)) + { + handler->PSendSysMessage(LANG_ARENA_RENAME, arena->GetId(), oldName.c_str(), newName.c_str()); + return true; + } + else { handler->SendSysMessage(LANG_BAD_VALUE); handler->SetSentErrorMessage(true); return false; } - - handler->PSendSysMessage(LANG_ARENA_RENAME, arena->GetId(), oldArenaStr, newArenaStr); - if (handler->GetSession()) - TC_LOG_DEBUG("bg.arena", "GameMaster: %s %s rename arena team \"%s\"[Id: %u] to \"%s\"", - handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUID().ToString().c_str(), oldArenaStr, arena->GetId(), newArenaStr); - else - TC_LOG_DEBUG("bg.arena", "Console: rename arena team \"%s\"[Id: %u] to \"%s\"", oldArenaStr, arena->GetId(), newArenaStr); - - return true; } - static bool HandleArenaCaptainCommand(ChatHandler* handler, char const* args) + static bool HandleArenaCaptainCommand(ChatHandler* handler, uint32 teamId, Optional<PlayerIdentifier> target) { - if (!*args) - return false; - - char* idStr; - char* nameStr; - handler->extractOptFirstArg((char*)args, &idStr, &nameStr); - if (!idStr) - return false; - - uint32 teamId = atoul(idStr); - if (!teamId) - return false; - - Player* target; - ObjectGuid targetGuid; - if (!handler->extractPlayerTarget(nameStr, &target, &targetGuid)) - return false; - ArenaTeam* arena = sArenaTeamMgr->GetArenaTeamById(teamId); - if (!arena) { handler->PSendSysMessage(LANG_ARENA_ERROR_NOT_FOUND, teamId); @@ -247,13 +168,6 @@ public: return false; } - if (!target) - { - handler->PSendSysMessage(LANG_PLAYER_NOT_EXIST_OR_OFFLINE, nameStr); - handler->SetSentErrorMessage(true); - return false; - } - if (arena->IsFighting()) { handler->SendSysMessage(LANG_ARENA_ERROR_COMBAT); @@ -261,49 +175,36 @@ public: return false; } - if (!arena->IsMember(targetGuid)) - { - handler->PSendSysMessage(LANG_ARENA_ERROR_NOT_MEMBER, nameStr, arena->GetName().c_str()); - handler->SetSentErrorMessage(true); + if (!target) + target = PlayerIdentifier::FromTargetOrSelf(handler); + if (!target) return false; - } - if (arena->GetCaptain() == targetGuid) + if (!arena->IsMember(target->GetGUID())) { - handler->PSendSysMessage(LANG_ARENA_ERROR_CAPTAIN, nameStr, arena->GetName().c_str()); + handler->PSendSysMessage(LANG_ARENA_ERROR_NOT_MEMBER, target->GetName().c_str(), arena->GetName().c_str()); handler->SetSentErrorMessage(true); return false; } - arena->SetCaptain(targetGuid); - - std::string oldCaptainName; - if (!sCharacterCache->GetCharacterNameByGuid(arena->GetCaptain(), oldCaptainName)) + if (arena->GetCaptain() == target->GetGUID()) { + handler->PSendSysMessage(LANG_ARENA_ERROR_CAPTAIN, target->GetName().c_str(), arena->GetName().c_str()); handler->SetSentErrorMessage(true); return false; } - handler->PSendSysMessage(LANG_ARENA_CAPTAIN, arena->GetName().c_str(), arena->GetId(), oldCaptainName.c_str(), target->GetName().c_str()); - if (handler->GetSession()) - TC_LOG_DEBUG("bg.arena", "GameMaster: %s %s promoted player: %s %s to leader of arena team \"%s\"[Id: %u]", - handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUID().ToString().c_str(), target->GetName().c_str(), target->GetGUID().ToString().c_str(), arena->GetName().c_str(), arena->GetId()); - else - TC_LOG_DEBUG("bg.arena", "Console: promoted player: %s %s to leader of arena team \"%s\"[Id: %u]", - target->GetName().c_str(), target->GetGUID().ToString().c_str(), arena->GetName().c_str(), arena->GetId()); + CharacterCacheEntry const* oldCaptainNameData = sCharacterCache->GetCharacterCacheByGuid(arena->GetCaptain()); + char const* oldCaptainName = oldCaptainNameData ? oldCaptainNameData->Name.c_str() : "<unknown>"; + + arena->SetCaptain(target->GetGUID()); + handler->PSendSysMessage(LANG_ARENA_CAPTAIN, arena->GetName().c_str(), arena->GetId(), oldCaptainName, target->GetName().c_str()); return true; } - static bool HandleArenaInfoCommand(ChatHandler* handler, char const* args) + static bool HandleArenaInfoCommand(ChatHandler* handler, uint32 teamId) { - if (!*args) - return false; - - uint32 teamId = atoul(args); - if (!teamId) - return false; - ArenaTeam* arena = sArenaTeamMgr->GetArenaTeamById(teamId); if (!arena) @@ -320,30 +221,19 @@ public: return true; } - static bool HandleArenaLookupCommand(ChatHandler* handler, char const* args) + static bool HandleArenaLookupCommand(ChatHandler* handler, Tail needle) { - if (!*args) + if (needle.empty()) return false; - std::string namepart = args; - std::wstring wnamepart; - - if (!Utf8toWStr(namepart, wnamepart)) - return false; - - wstrToLower(wnamepart); - bool found = false; - ArenaTeamMgr::ArenaTeamContainer::const_iterator i = sArenaTeamMgr->GetArenaTeamMapBegin(); - for (; i != sArenaTeamMgr->GetArenaTeamMapEnd(); ++i) + for (auto [teamId, team] : sArenaTeamMgr->GetArenaTeams()) { - ArenaTeam* arena = i->second; - - if (Utf8FitTo(arena->GetName(), wnamepart)) + if (StringContainsStringI(team->GetName(), needle)) { if (handler->GetSession()) { - handler->PSendSysMessage(LANG_ARENA_LOOKUP, arena->GetName().c_str(), arena->GetId(), arena->GetType(), arena->GetType()); + handler->PSendSysMessage(LANG_ARENA_LOOKUP, team->GetName().c_str(), team->GetId(), team->GetType(), team->GetType()); found = true; continue; } @@ -351,7 +241,7 @@ public: } if (!found) - handler->PSendSysMessage(LANG_AREAN_ERROR_NAME_NOT_FOUND, namepart.c_str()); + handler->PSendSysMessage(LANG_ARENA_ERROR_NAME_NOT_FOUND, std::string(needle).c_str()); return true; } |