diff options
Diffstat (limited to 'src/server')
-rw-r--r-- | src/server/game/Chat/Chat.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Chat/Chat.h | 8 | ||||
-rw-r--r-- | src/server/game/Chat/ChatCommands/ChatCommand.h | 70 | ||||
-rw-r--r-- | src/server/game/Chat/ChatCommands/ChatCommandArgs.cpp | 63 | ||||
-rw-r--r-- | src/server/game/Chat/ChatCommands/ChatCommandArgs.h | 158 | ||||
-rw-r--r-- | src/server/game/Chat/ChatCommands/ChatCommandHelpers.cpp | 30 | ||||
-rw-r--r-- | src/server/game/Chat/ChatCommands/ChatCommandHelpers.h | 45 | ||||
-rw-r--r-- | src/server/game/Chat/ChatCommands/ChatCommandTags.cpp | 32 | ||||
-rw-r--r-- | src/server/game/Chat/ChatCommands/ChatCommandTags.h | 37 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/Language.h | 33 | ||||
-rw-r--r-- | src/server/game/World/World.h | 4 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_gobject.cpp | 4 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_npc.cpp | 4 | ||||
-rw-r--r-- | src/server/worldserver/CommandLine/CliRunnable.cpp | 11 | ||||
-rw-r--r-- | src/server/worldserver/RemoteAccess/RASession.cpp | 6 | ||||
-rw-r--r-- | src/server/worldserver/RemoteAccess/RASession.h | 4 | ||||
-rw-r--r-- | src/server/worldserver/TCSoap/TCSoap.h | 4 |
17 files changed, 321 insertions, 198 deletions
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index ec572e72704..dc26c3cf0c7 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -175,7 +175,7 @@ bool ChatHandler::hasStringAbbr(const char* name, const char* part) return true; } -void ChatHandler::SendSysMessage(const char *str, bool escapeCharacters) +void ChatHandler::SendSysMessage(std::string_view str, bool escapeCharacters) { std::string msg{ str }; @@ -998,7 +998,7 @@ bool CliHandler::isAvailable(ChatCommand const& cmd) const return cmd.AllowConsole; } -void CliHandler::SendSysMessage(const char *str, bool /*escapeCharacters*/) +void CliHandler::SendSysMessage(std::string_view str, bool /*escapeCharacters*/) { m_print(m_callbackArg, str); m_print(m_callbackArg, "\r\n"); @@ -1155,7 +1155,7 @@ void AddonChannelCommandHandler::SendFailed() // f Command failed, no body } // m Command message, message in body -void AddonChannelCommandHandler::SendSysMessage(char const* str, bool escapeCharacters) +void AddonChannelCommandHandler::SendSysMessage(std::string_view str, bool escapeCharacters) { ASSERT(echo); if (!hadAck) diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index d46b58446c4..9aa32019ae2 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -49,7 +49,7 @@ class TC_GAME_API ChatHandler // function with different implementation for chat/console virtual char const* GetTrinityString(uint32 entry) const; - virtual void SendSysMessage(char const* str, bool escapeCharacters = false); + virtual void SendSysMessage(std::string_view str, bool escapeCharacters = false); void SendSysMessage(uint32 entry); @@ -138,14 +138,14 @@ class TC_GAME_API ChatHandler class TC_GAME_API CliHandler : public ChatHandler { public: - typedef void Print(void*, char const*); + using Print = void(void*, std::string_view); explicit CliHandler(void* callbackArg, Print* zprint) : m_callbackArg(callbackArg), m_print(zprint) { } // overwrite functions char const* GetTrinityString(uint32 entry) const override; bool isAvailable(ChatCommand const& cmd) const override; bool HasPermission(uint32 /*permission*/) const override { return true; } - void SendSysMessage(const char *str, bool escapeCharacters) override; + void SendSysMessage(std::string_view, bool escapeCharacters) override; bool ParseCommands(char const* str) override; std::string GetNameLink() const override; bool needReportToTarget(Player* chr) const override; @@ -164,7 +164,7 @@ class TC_GAME_API AddonChannelCommandHandler : public ChatHandler using ChatHandler::ChatHandler; bool ParseCommands(char const* str) override; - void SendSysMessage(char const* str, bool escapeCharacters) override; + void SendSysMessage(std::string_view, bool escapeCharacters) override; using ChatHandler::SendSysMessage; bool IsHumanReadable() const override { return humanReadable; } diff --git a/src/server/game/Chat/ChatCommands/ChatCommand.h b/src/server/game/Chat/ChatCommands/ChatCommand.h index 28d84629eea..7b36a72d2f4 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommand.h +++ b/src/server/game/Chat/ChatCommands/ChatCommand.h @@ -25,77 +25,72 @@ #include "Errors.h" #include "ObjectGuid.h" #include "Optional.h" +#include "StringFormat.h" #include <cstddef> #include <tuple> #include <type_traits> #include <vector> class ChatHandler; -class CommandArgs; namespace Trinity::Impl::ChatCommands { - template <typename T> - struct SingleConsumer - { - static Optional<std::string_view> TryConsumeTo(T& val, std::string_view args) - { - return ArgInfo<T>::TryConsume(val, args); - } - }; - - /* - for backwards compatibility, consumes the rest of the string - new code should use the Tail/WTail tags defined in ChatCommandTags - */ - template <> - struct SingleConsumer<char const*> - { - static Optional<std::string_view> TryConsumeTo(char const*& arg, std::string_view args) { arg = args.data(); return std::string_view(); } - }; - - // forward declaration // ConsumeFromOffset contains the bounds check for offset, then hands off to MultiConsumer // the call stack is MultiConsumer -> ConsumeFromOffset -> MultiConsumer -> ConsumeFromOffset etc - // MultiConsumer calls SingleConsumer in each iteration + // MultiConsumer goes into ArgInfo for parsing on each iteration template <typename Tuple, size_t offset> - Optional<std::string_view> ConsumeFromOffset(Tuple&, std::string_view args); + ChatCommandResult ConsumeFromOffset(Tuple&, ChatHandler const* handler, std::string_view args); template <typename Tuple, typename NextType, size_t offset> struct MultiConsumer { - static Optional<std::string_view> TryConsumeTo(Tuple& tuple, std::string_view args) + static ChatCommandResult TryConsumeTo(Tuple& tuple, ChatHandler const* handler, std::string_view args) { - if (Optional<std::string_view> next = SingleConsumer<NextType>::TryConsumeTo(std::get<offset>(tuple), args)) - return ConsumeFromOffset<Tuple, offset + 1>(tuple, *next); + ChatCommandResult next = ArgInfo<NextType>::TryConsume(std::get<offset>(tuple), handler, args); + if (next) + return ConsumeFromOffset<Tuple, offset + 1>(tuple, handler, *next); else - return std::nullopt; + return next; } }; template <typename Tuple, typename NestedNextType, size_t offset> struct MultiConsumer<Tuple, Optional<NestedNextType>, offset> { - static Optional<std::string_view> TryConsumeTo(Tuple& tuple, std::string_view args) + static ChatCommandResult TryConsumeTo(Tuple& tuple, ChatHandler const* handler, std::string_view args) { // try with the argument auto& myArg = std::get<offset>(tuple); myArg.emplace(); - if (Optional<std::string_view> next = SingleConsumer<NestedNextType>::TryConsumeTo(myArg.value(), args)) - if ((next = ConsumeFromOffset<Tuple, offset + 1>(tuple, *next))) - return next; + + ChatCommandResult result1 = ArgInfo<NestedNextType>::TryConsume(myArg.value(), handler, args); + if (result1) + if ((result1 = ConsumeFromOffset<Tuple, offset + 1>(tuple, handler, *result1))) + return result1; // try again omitting the argument myArg = std::nullopt; - return ConsumeFromOffset<Tuple, offset + 1>(tuple, args); + ChatCommandResult result2 = ConsumeFromOffset<Tuple, offset + 1>(tuple, handler, args); + if (result2) + return result2; + if (result1.HasErrorMessage() && result2.HasErrorMessage()) + { + return Trinity::StringFormat("%s \"%s\"\n%s \"%s\"", + GetTrinityString(handler, LANG_CMDPARSER_EITHER), result2.GetErrorMessage().c_str(), + GetTrinityString(handler, LANG_CMDPARSER_OR), result1.GetErrorMessage().c_str()); + } + else if (result1.HasErrorMessage()) + return result1; + else + return result2; } }; template <typename Tuple, size_t offset> - Optional<std::string_view> ConsumeFromOffset(Tuple& tuple, std::string_view args) + ChatCommandResult ConsumeFromOffset([[maybe_unused]] Tuple& tuple, [[maybe_unused]] ChatHandler const* handler, std::string_view args) { if constexpr (offset < std::tuple_size_v<Tuple>) - return MultiConsumer<Tuple, std::tuple_element_t<offset, Tuple>, offset>::TryConsumeTo(tuple, args); + return MultiConsumer<Tuple, std::tuple_element_t<offset, Tuple>, offset>::TryConsumeTo(tuple, handler, args); else if (!args.empty()) /* the entire string must be consumed */ return std::nullopt; else @@ -123,10 +118,15 @@ class TC_GAME_API ChatCommand Tuple arguments; std::get<0>(arguments) = chatHandler; - if (Trinity::Impl::ChatCommands::ConsumeFromOffset<Tuple, 1>(arguments, argsStr)) + Trinity::Impl::ChatCommands::ChatCommandResult result = Trinity::Impl::ChatCommands::ConsumeFromOffset<Tuple, 1>(arguments, chatHandler, argsStr); + if (result) return std::apply(reinterpret_cast<TypedHandler>(handler), std::move(arguments)); else + { + if (result.HasErrorMessage()) + Trinity::Impl::ChatCommands::SendErrorMessageToHandler(chatHandler, result.GetErrorMessage()); return false; + } }; _handler = reinterpret_cast<void*>(handler); } diff --git a/src/server/game/Chat/ChatCommands/ChatCommandArgs.cpp b/src/server/game/Chat/ChatCommands/ChatCommandArgs.cpp index 33db9d4bdf3..ca8fd888f1b 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommandArgs.cpp +++ b/src/server/game/Chat/ChatCommands/ChatCommandArgs.cpp @@ -23,6 +23,7 @@ #include "Util.h" using namespace Trinity::ChatCommands; +using ChatCommandResult = Trinity::Impl::ChatCommands::ChatCommandResult; struct AchievementVisitor { @@ -30,13 +31,14 @@ struct AchievementVisitor value_type operator()(Hyperlink<achievement> achData) const { return achData->Achievement; } value_type operator()(uint32 achId) const { return sAchievementStore.LookupEntry(achId); } }; -Optional<std::string_view> Trinity::Impl::ChatCommands::ArgInfo<AchievementEntry const*>::TryConsume(AchievementEntry const*& data, std::string_view args) +ChatCommandResult Trinity::Impl::ChatCommands::ArgInfo<AchievementEntry const*>::TryConsume(AchievementEntry const*& data, ChatHandler const* handler, std::string_view args) { Variant<Hyperlink<achievement>, uint32> val; - Optional<std::string_view> next = SingleConsumer<decltype(val)>::TryConsumeTo(val, args); - if (next) - if ((data = val.visit(AchievementVisitor()))) - return next; + ChatCommandResult result = ArgInfo<decltype(val)>::TryConsume(val, handler, args); + if (!result || (data = val.visit(AchievementVisitor()))) + return result; + if (uint32* id = std::get_if<uint32>(&val)) + return FormatTrinityString(handler, LANG_CMDPARSER_ACHIEVEMENT_NO_EXIST, *id); return std::nullopt; } @@ -46,13 +48,14 @@ struct CurrencyTypesVisitor value_type operator()(Hyperlink<currency> currency) const { return currency->Currency; } value_type operator()(uint32 currencyId) const { return sCurrencyTypesStore.LookupEntry(currencyId); } }; -Optional<std::string_view> Trinity::Impl::ChatCommands::ArgInfo<CurrencyTypesEntry const*>::TryConsume(CurrencyTypesEntry const*& data, std::string_view args) +ChatCommandResult Trinity::Impl::ChatCommands::ArgInfo<CurrencyTypesEntry const*>::TryConsume(CurrencyTypesEntry const*& data, ChatHandler const* handler, std::string_view args) { Variant<Hyperlink<currency>, uint32> val; - Optional<std::string_view> next = SingleConsumer<decltype(val)>::TryConsumeTo(val, args); - if (next) - if ((data = val.visit(CurrencyTypesVisitor()))) - return next; + ChatCommandResult result = ArgInfo<decltype(val)>::TryConsume(val, handler, args); + if (!result || (data = val.visit(CurrencyTypesVisitor()))) + return result; + if (uint32* id = std::get_if<uint32>(&val)) + return FormatTrinityString(handler, LANG_CMDPARSER_CURRENCY_NO_EXIST, *id); return std::nullopt; } @@ -60,16 +63,18 @@ struct GameTeleVisitor { using value_type = GameTele const*; value_type operator()(Hyperlink<tele> tele) const { return sObjectMgr->GetGameTele(tele); } - value_type operator()(std::string const& tele) const { return sObjectMgr->GetGameTele(tele); } + value_type operator()(std::string_view tele) const { return sObjectMgr->GetGameTele(tele); } }; -Optional<std::string_view> Trinity::Impl::ChatCommands::ArgInfo<GameTele const*>::TryConsume(GameTele const*& data, std::string_view args) +ChatCommandResult Trinity::Impl::ChatCommands::ArgInfo<GameTele const*>::TryConsume(GameTele const*& data, ChatHandler const* handler, std::string_view args) { - Variant<Hyperlink<tele>, std::string> val; - Optional<std::string_view> next = SingleConsumer<decltype(val)>::TryConsumeTo(val, args); - if (next) - if ((data = val.visit(GameTeleVisitor()))) - return next; - return std::nullopt; + Variant<Hyperlink<tele>, std::string_view> val; + ChatCommandResult result = ArgInfo<decltype(val)>::TryConsume(val, handler, args); + if (!result || (data = val.visit(GameTeleVisitor()))) + return result; + if (val.holds_alternative<Hyperlink<tele>>()) + return FormatTrinityString(handler, LANG_CMDPARSER_GAME_TELE_ID_NO_EXIST, static_cast<uint32>(std::get<Hyperlink<tele>>(val))); + else + return FormatTrinityString(handler, LANG_CMDPARSER_GAME_TELE_NO_EXIST, STRING_VIEW_FMT_ARG(std::get<std::string_view>(val))); } struct ItemTemplateVisitor @@ -78,13 +83,14 @@ struct ItemTemplateVisitor value_type operator()(Hyperlink<item> item) const { return item->Item; } value_type operator()(uint32 item) const { return sObjectMgr->GetItemTemplate(item); } }; -Optional<std::string_view> Trinity::Impl::ChatCommands::ArgInfo<ItemTemplate const*>::TryConsume(ItemTemplate const*& data, std::string_view args) +ChatCommandResult Trinity::Impl::ChatCommands::ArgInfo<ItemTemplate const*>::TryConsume(ItemTemplate const*& data, ChatHandler const* handler, std::string_view args) { Variant<Hyperlink<item>, uint32> val; - Optional<std::string_view> next = SingleConsumer<decltype(val)>::TryConsumeTo(val, args); - if (next) - if ((data = val.visit(ItemTemplateVisitor()))) - return next; + ChatCommandResult result = ArgInfo<decltype(val)>::TryConsume(val, handler, args); + if (!result || (data = val.visit(ItemTemplateVisitor()))) + return result; + if (uint32* id = std::get_if<uint32>(&val)) + return FormatTrinityString(handler, LANG_CMDPARSER_ITEM_NO_EXIST, *id); return std::nullopt; } @@ -103,12 +109,13 @@ struct SpellInfoVisitor value_type operator()(uint32 spellId) const { return sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE); } }; -Optional<std::string_view> Trinity::Impl::ChatCommands::ArgInfo<SpellInfo const*>::TryConsume(SpellInfo const*& data, std::string_view args) +ChatCommandResult Trinity::Impl::ChatCommands::ArgInfo<SpellInfo const*>::TryConsume(SpellInfo const*& data, ChatHandler const* handler, std::string_view args) { Variant<Hyperlink<apower>, Hyperlink<conduit>, Hyperlink<enchant>, Hyperlink<mawpower>, Hyperlink<pvptal>, Hyperlink<spell>, Hyperlink<talent>, Hyperlink<trade>, uint32> val; - Optional<std::string_view> next = SingleConsumer<decltype(val)>::TryConsumeTo(val, args); - if (next) - if ((data = val.visit(SpellInfoVisitor()))) - return next; + ChatCommandResult result = ArgInfo<decltype(val)>::TryConsume(val, handler, args); + if (!result || (data = val.visit(SpellInfoVisitor()))) + return result; + if (uint32* id = std::get_if<uint32>(&val)) + return FormatTrinityString(handler, LANG_CMDPARSER_SPELL_NO_EXIST, *id); return std::nullopt; } diff --git a/src/server/game/Chat/ChatCommands/ChatCommandArgs.h b/src/server/game/Chat/ChatCommands/ChatCommandArgs.h index 21f27b45752..b36456869d8 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommandArgs.h +++ b/src/server/game/Chat/ChatCommands/ChatCommandArgs.h @@ -22,6 +22,7 @@ #include "ChatCommandTags.h" #include "SmartEnum.h" #include "StringConvert.h" +#include "StringFormat.h" #include "Util.h" #include <charconv> #include <map> @@ -36,10 +37,13 @@ namespace Trinity::Impl::ChatCommands /************************** ARGUMENT HANDLERS *******************************************\ |* Define how to extract contents of a certain requested type from a string *| |* Must implement the following: *| - |* - TryConsume: T&, std::string_view -> Optional<std::string_view> *| - |* returns nullopt if no match, otherwise tail of argument string *| - |* - if nullopt is returned, state of T& is indeterminate *| - |* - otherwise, T& should be initialized to the intended return value *| + |* - TryConsume: T&, ChatHandler const*, std::string_view -> ChatCommandResult *| + |* - on match, returns tail of the provided argument string (as std::string_view) *| + |* - on specific error, returns error message (as std::string&& or char const*) *| + |* - on generic error, returns std::nullopt (this will print command usage) *| + |* *| + |* - if a match is returned, T& should be initialized to the matched value *| + |* - otherwise, the state of T& is indeterminate and caller will not use it *| |* *| \****************************************************************************************/ template <typename T, typename = void> @@ -49,7 +53,7 @@ namespace Trinity::Impl::ChatCommands template <typename T> struct ArgInfo<T, std::enable_if_t<std::is_integral_v<T> || std::is_floating_point_v<T>>> { - static Optional<std::string_view> TryConsume(T& val, std::string_view args) + static ChatCommandResult TryConsume(T& val, ChatHandler const* handler, std::string_view args) { auto [token, tail] = tokenize(args); if (token.empty()) @@ -58,23 +62,33 @@ namespace Trinity::Impl::ChatCommands if (Optional<T> v = StringTo<T>(token, 0)) val = *v; else - return std::nullopt; + return FormatTrinityString(handler, LANG_CMDPARSER_STRING_VALUE_INVALID, STRING_VIEW_FMT_ARG(token), GetTypeName<T>().c_str()); if constexpr (std::is_floating_point_v<T>) { if (!std::isfinite(val)) - return std::nullopt; + return FormatTrinityString(handler, LANG_CMDPARSER_STRING_VALUE_INVALID, STRING_VIEW_FMT_ARG(token), GetTypeName<T>().c_str()); } return tail; } }; + /* + for backwards compatibility, consumes the rest of the string + new code should use the Tail/WTail tags defined in ChatCommandTags + */ + template <> + struct ArgInfo<char const*, void> + { + static ChatCommandResult TryConsume(char const*& arg, ChatHandler const*, std::string_view args) { arg = args.data(); return std::string_view(); } + }; + // string_view template <> struct ArgInfo<std::string_view, void> { - static Optional<std::string_view> TryConsume(std::string_view& val, std::string_view args) + static ChatCommandResult TryConsume(std::string_view& val, ChatHandler const*, std::string_view args) { auto [token, next] = tokenize(args); if (token.empty()) @@ -88,10 +102,10 @@ namespace Trinity::Impl::ChatCommands template <> struct ArgInfo<std::string, void> { - static Optional<std::string_view> TryConsume(std::string& val, std::string_view args) + static ChatCommandResult TryConsume(std::string& val, ChatHandler const* handler, std::string_view args) { std::string_view view; - Optional<std::string_view> next = ArgInfo<std::string_view>::TryConsume(view, args); + ChatCommandResult next = ArgInfo<std::string_view>::TryConsume(view, handler, args); if (next) val.assign(view); return next; @@ -102,13 +116,18 @@ namespace Trinity::Impl::ChatCommands template <> struct ArgInfo<std::wstring, void> { - static Optional<std::string_view> TryConsume(std::wstring& val, std::string_view args) + static ChatCommandResult TryConsume(std::wstring& val, ChatHandler const* handler, std::string_view args) { std::string_view utf8view; - Optional<std::string_view> next = ArgInfo<std::string_view>::TryConsume(utf8view, args); + ChatCommandResult next = ArgInfo<std::string_view>::TryConsume(utf8view, handler, args); - if (next && Utf8toWStr(utf8view, val)) - return next; + if (next) + { + if (Utf8toWStr(utf8view, val)) + return next; + else + return GetTrinityString(handler, LANG_CMDPARSER_INVALID_UTF8); + } else return std::nullopt; } @@ -118,19 +137,18 @@ namespace Trinity::Impl::ChatCommands template <typename T> struct ArgInfo<T, std::enable_if_t<std::is_enum_v<T>>> { - static std::map<std::string, Optional<T>> MakeSearchMap() + using SearchMap = std::map<std::string_view, Optional<T>, StringCompareLessI_T>; + static SearchMap MakeSearchMap() { - std::map<std::string, Optional<T>> map; + SearchMap map; for (T val : EnumUtils::Iterate<T>()) { EnumText text = EnumUtils::ToString(val); - std::string title(text.Title); - strToLower(title); - std::string constant(text.Constant); - strToLower(constant); + std::string_view title(text.Title); + std::string_view constant(text.Constant); - auto [constantIt, constantNew] = map.try_emplace(constant, val); + auto [constantIt, constantNew] = map.try_emplace(title, val); if (!constantNew) constantIt->second = std::nullopt; @@ -144,21 +162,19 @@ namespace Trinity::Impl::ChatCommands return map; } - static inline std::map<std::string, Optional<T>> const SearchMap = MakeSearchMap(); + static inline SearchMap const _map = MakeSearchMap(); - static T const* Match(std::string s) + static T const* Match(std::string_view s) { - strToLower(s); - - auto it = SearchMap.lower_bound(s); - if (it == SearchMap.end() || !StringStartsWith(it->first, s)) // not a match + auto it = _map.lower_bound(s); + if (it == _map.end() || !StringStartsWithI(it->first, s)) // not a match return nullptr; - if (it->first != s) // we don't have an exact match - check if it is unique + if (!StringEqualI(it->first, s)) // we don't have an exact match - check if it is unique { auto it2 = it; ++it2; - if (it2 != SearchMap.end() && StringStartsWith(it2->first, s)) // not unique + if ((it2 != _map.end()) && StringStartsWithI(it2->first, s)) // not unique return nullptr; } @@ -168,31 +184,35 @@ namespace Trinity::Impl::ChatCommands return nullptr; } - static Optional<std::string_view> TryConsume(T& val, std::string_view args) + static ChatCommandResult TryConsume(T& val, ChatHandler const* handler, std::string_view args) { - std::string strVal; - Optional<std::string_view> next = ArgInfo<std::string>::TryConsume(strVal, args); - - if (next) + std::string_view strVal; + ChatCommandResult next1 = ArgInfo<std::string_view>::TryConsume(strVal, handler, args); + if (next1) { if (T const* match = Match(strVal)) { val = *match; - return next; + return next1; } } // Value not found. Try to parse arg as underlying type and cast it to enum type using U = std::underlying_type_t<T>; U uVal = 0; - next = ArgInfo<U>::TryConsume(uVal, args); - if (next && EnumUtils::IsValid<T>(uVal)) + if (ChatCommandResult next2 = ArgInfo<U>::TryConsume(uVal, handler, args)) { - val = static_cast<T>(uVal); - return next; + if (EnumUtils::IsValid<T>(uVal)) + { + val = static_cast<T>(uVal); + return next2; + } } - return std::nullopt; + if (next1) + return FormatTrinityString(handler, LANG_CMDPARSER_STRING_VALUE_INVALID, STRING_VIEW_FMT_ARG(strVal), GetTypeName<T>().c_str()); + else + return next1; } }; @@ -200,9 +220,9 @@ namespace Trinity::Impl::ChatCommands template <typename T> struct ArgInfo<T, std::enable_if_t<std::is_base_of_v<ContainerTag, T>>> { - static Optional<std::string_view> TryConsume(T& tag, std::string_view args) + static ChatCommandResult TryConsume(T& tag, ChatHandler const* handler, std::string_view args) { - return tag.TryConsume(args); + return tag.TryConsume(handler, args); } }; @@ -210,16 +230,16 @@ namespace Trinity::Impl::ChatCommands template <typename T> struct ArgInfo<std::vector<T>, void> { - static Optional<std::string_view> TryConsume(std::vector<T>& val, std::string_view args) + static ChatCommandResult TryConsume(std::vector<T>& val, ChatHandler const* handler, std::string_view args) { val.clear(); - Optional<std::string_view> next = ArgInfo<T>::TryConsume(val.emplace_back(), args); + ChatCommandResult next = ArgInfo<T>::TryConsume(val.emplace_back(), handler, args); if (!next) - return std::nullopt; + return next; - while (Optional<std::string_view> next2 = ArgInfo<T>::TryConsume(val.emplace_back(), *next)) - next = next2; + while (ChatCommandResult next2 = ArgInfo<T>::TryConsume(val.emplace_back(), handler, *next)) + next = std::move(next2); val.pop_back(); return next; @@ -230,12 +250,12 @@ namespace Trinity::Impl::ChatCommands template <typename T, size_t N> struct ArgInfo<std::array<T, N>, void> { - static Optional<std::string_view> TryConsume(std::array<T, N>& val, std::string_view args) + static ChatCommandResult TryConsume(std::array<T, N>& val, ChatHandler const* handler, std::string_view args) { - Optional<std::string_view> next = args; + ChatCommandResult next = args; for (T& t : val) - if (!(next = ArgInfo<T>::TryConsume(t, *next))) - return std::nullopt; + if (!(next = ArgInfo<T>::TryConsume(t, handler, *next))) + break; return next; } }; @@ -248,22 +268,36 @@ namespace Trinity::Impl::ChatCommands static constexpr size_t N = std::variant_size_v<V>; template <size_t I> - static Optional<std::string_view> TryAtIndex(Trinity::ChatCommands::Variant<Ts...>& val, [[maybe_unused]] std::string_view args) + static ChatCommandResult TryAtIndex([[maybe_unused]] Trinity::ChatCommands::Variant<Ts...>& val, [[maybe_unused]] ChatHandler const* handler, [[maybe_unused]] std::string_view args) { if constexpr (I < N) { - if (Optional<std::string_view> next = ArgInfo<std::variant_alternative_t<I, V>>::TryConsume(val.template emplace<I>(), args)) - return next; + ChatCommandResult thisResult = ArgInfo<std::variant_alternative_t<I, V>>::TryConsume(val.template emplace<I>(), handler, args); + if (thisResult) + return thisResult; else - return TryAtIndex<I + 1>(val, args); + { + ChatCommandResult nestedResult = TryAtIndex<I + 1>(val, handler, args); + if (!thisResult.HasErrorMessage()) + return nestedResult; + if (!nestedResult.HasErrorMessage()) + return thisResult; + if (StringStartsWith(nestedResult.GetErrorMessage(), "\"")) + return Trinity::StringFormat("\"%s\"\n%s %s", thisResult.GetErrorMessage().c_str(), GetTrinityString(handler, LANG_CMDPARSER_OR), nestedResult.GetErrorMessage().c_str()); + else + return Trinity::StringFormat("\"%s\"\n%s \"%s\"", thisResult.GetErrorMessage().c_str(), GetTrinityString(handler, LANG_CMDPARSER_OR), nestedResult.GetErrorMessage().c_str()); + } } else return std::nullopt; } - static Optional<std::string_view> TryConsume(Trinity::ChatCommands::Variant<Ts...>& val, std::string_view args) + static ChatCommandResult TryConsume(Trinity::ChatCommands::Variant<Ts...>& val, ChatHandler const* handler, std::string_view args) { - return TryAtIndex<0>(val, args); + ChatCommandResult result = TryAtIndex<0>(val, handler, args); + if (result.HasErrorMessage() && (result.GetErrorMessage().find('\n') != std::string::npos)) + return Trinity::StringFormat("%s %s", GetTrinityString(handler, LANG_CMDPARSER_EITHER), result.GetErrorMessage().c_str()); + return result; } }; @@ -271,35 +305,35 @@ namespace Trinity::Impl::ChatCommands template <> struct TC_GAME_API ArgInfo<AchievementEntry const*> { - static Optional<std::string_view> TryConsume(AchievementEntry const*&, std::string_view); + static ChatCommandResult TryConsume(AchievementEntry const*&, ChatHandler const*, std::string_view); }; // CurrencyTypesEntry* from numeric id or link template <> struct TC_GAME_API ArgInfo<CurrencyTypesEntry const*> { - static Optional<std::string_view> TryConsume(CurrencyTypesEntry const*&, std::string_view); + static ChatCommandResult TryConsume(CurrencyTypesEntry const*&, ChatHandler const*, std::string_view); }; // GameTele* from string name or link template <> struct TC_GAME_API ArgInfo<GameTele const*> { - static Optional<std::string_view> TryConsume(GameTele const*&, std::string_view); + static ChatCommandResult TryConsume(GameTele const*&, ChatHandler const*, std::string_view); }; // ItemTemplate* from numeric id or link template <> struct TC_GAME_API ArgInfo<ItemTemplate const*> { - static Optional<std::string_view> TryConsume(ItemTemplate const*&, std::string_view); + static ChatCommandResult TryConsume(ItemTemplate const*&, ChatHandler const*, std::string_view); }; // SpellInfo const* from spell id or link template <> struct TC_GAME_API ArgInfo<SpellInfo const*> { - static Optional<std::string_view> TryConsume(SpellInfo const*&, std::string_view); + static ChatCommandResult TryConsume(SpellInfo const*&, ChatHandler const*, std::string_view); }; } diff --git a/src/server/game/Chat/ChatCommands/ChatCommandHelpers.cpp b/src/server/game/Chat/ChatCommands/ChatCommandHelpers.cpp new file mode 100644 index 00000000000..ab64584a389 --- /dev/null +++ b/src/server/game/Chat/ChatCommands/ChatCommandHelpers.cpp @@ -0,0 +1,30 @@ +/* + * 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 "ChatCommandHelpers.h" +#include "Chat.h" + +void Trinity::Impl::ChatCommands::SendErrorMessageToHandler(ChatHandler* handler, std::string_view str) +{ + handler->SendSysMessage(str); + handler->SetSentErrorMessage(true); +} + +char const* Trinity::Impl::ChatCommands::GetTrinityString(ChatHandler const* handler, TrinityStrings which) +{ + return handler->GetTrinityString(which); +} diff --git a/src/server/game/Chat/ChatCommands/ChatCommandHelpers.h b/src/server/game/Chat/ChatCommands/ChatCommandHelpers.h index 712d0c37d48..afa5589e0b7 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommandHelpers.h +++ b/src/server/game/Chat/ChatCommands/ChatCommandHelpers.h @@ -18,8 +18,16 @@ #ifndef TRINITY_CHATCOMMANDHELPERS_H #define TRINITY_CHATCOMMANDHELPERS_H +#include "Define.h" +#include "Language.h" +#include "Optional.h" +#include "StringFormat.h" +#include <string> #include <string_view> #include <type_traits> +#include <variant> + +class ChatHandler; namespace Trinity::Impl::ChatCommands { @@ -82,6 +90,43 @@ namespace Trinity::Impl::ChatCommands template <std::size_t index, typename... Ts> using get_nth_t = typename get_nth<index, Ts...>::type; + + // this essentially models std::optional<std::string_view>, except it can also hold an error message + // it has std::string_view's bool conversion and dereference operators + // + // monostate <-> unspecified error, typically end-of-string reached or parsing failed + // std::string <-> specified error, typically character-not-found or invalid item link + // std::string_view <-> success, string_view is remaining argument string + struct ChatCommandResult + { + ChatCommandResult(std::nullopt_t) : _storage() {} + ChatCommandResult(std::string const&) = delete; + ChatCommandResult(std::string&& s) : _storage(std::in_place_type<std::string>, std::forward<std::string>(s)) {} + ChatCommandResult(char const* c) : _storage(std::in_place_type<std::string>, c) {} + ChatCommandResult(std::string_view s) : _storage(std::in_place_type<std::string_view>, s) {} + + ChatCommandResult(ChatCommandResult const&) = delete; + ChatCommandResult(ChatCommandResult&&) = default; + ChatCommandResult& operator=(ChatCommandResult const&) = delete; + ChatCommandResult& operator=(ChatCommandResult&&) = default; + + std::string_view operator*() const { return std::get<std::string_view>(_storage); } + bool IsSuccessful() const { return std::holds_alternative<std::string_view>(_storage); } + explicit operator bool() const { return IsSuccessful(); } + bool HasErrorMessage() const { return std::holds_alternative<std::string>(_storage); } + std::string const& GetErrorMessage() const { return std::get<std::string>(_storage); } + + private: + std::variant<std::monostate, std::string_view, std::string> _storage; + }; + + TC_GAME_API void SendErrorMessageToHandler(ChatHandler* handler, std::string_view str); + TC_GAME_API char const* GetTrinityString(ChatHandler const* handler, TrinityStrings which); + template <typename... Ts> + std::string FormatTrinityString(ChatHandler const* handler, TrinityStrings which, Ts&&... args) + { + return Trinity::StringFormat(GetTrinityString(handler, which), std::forward<Ts>(args)...); + } } #endif diff --git a/src/server/game/Chat/ChatCommands/ChatCommandTags.cpp b/src/server/game/Chat/ChatCommands/ChatCommandTags.cpp index 8c5917e086d..b5b29193312 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommandTags.cpp +++ b/src/server/game/Chat/ChatCommands/ChatCommandTags.cpp @@ -25,19 +25,21 @@ #include "ObjectMgr.h" #include "Player.h" -Optional<std::string_view> Trinity::ChatCommands::QuotedString::TryConsume(std::string_view args) +using namespace Trinity::Impl::ChatCommands; + +ChatCommandResult Trinity::ChatCommands::QuotedString::TryConsume(ChatHandler const* handler, 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); + return ArgInfo<std::string>::TryConsume(*this, handler, 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)); + auto [remainingToken, tail] = tokenize(args.substr(i + 1)); if (remainingToken.empty()) // if this is not empty, then we did not consume the full token return tail; else @@ -56,17 +58,17 @@ Optional<std::string_view> Trinity::ChatCommands::QuotedString::TryConsume(std:: return std::nullopt; } -Optional<std::string_view> Trinity::ChatCommands::AccountIdentifier::TryConsume(std::string_view args) +ChatCommandResult Trinity::ChatCommands::AccountIdentifier::TryConsume(ChatHandler const* handler, std::string_view args) { std::string_view text; - Optional<std::string_view> next = Trinity::Impl::ChatCommands::ArgInfo<std::string_view>::TryConsume(text, args); + ChatCommandResult next = ArgInfo<std::string_view>::TryConsume(text, handler, args); if (!next) - return std::nullopt; + return next; // first try parsing as account name _name.assign(text); if (!Utf8ToUpperOnlyLatin(_name)) - return std::nullopt; + return GetTrinityString(handler, LANG_CMDPARSER_INVALID_UTF8); _id = AccountMgr::GetId(_name); if (_id) // account with name exists, we are done return next; @@ -74,21 +76,21 @@ Optional<std::string_view> Trinity::ChatCommands::AccountIdentifier::TryConsume( // try parsing as account id instead Optional<uint32> id = Trinity::StringTo<uint32>(text, 10); if (!id) - return std::nullopt; + return FormatTrinityString(handler, LANG_CMDPARSER_ACCOUNT_NAME_NO_EXIST, STRING_VIEW_FMT_ARG(_name)); _id = *id; if (AccountMgr::GetName(_id, _name)) return next; else - return std::nullopt; + return FormatTrinityString(handler, LANG_CMDPARSER_ACCOUNT_ID_NO_EXIST, _id); } -Optional<std::string_view> Trinity::ChatCommands::PlayerIdentifier::TryConsume(std::string_view args) +ChatCommandResult Trinity::ChatCommands::PlayerIdentifier::TryConsume(ChatHandler const* handler, std::string_view args) { Variant<Hyperlink<player>, ObjectGuid::LowType, std::string_view> val; - Optional<std::string_view> next = Trinity::Impl::ChatCommands::ArgInfo<decltype(val)>::TryConsume(val, args); + ChatCommandResult next = ArgInfo<decltype(val)>::TryConsume(val, handler, args); if (!next) - return std::nullopt; + return next; if (val.holds_alternative<ObjectGuid::LowType>()) { @@ -96,7 +98,7 @@ Optional<std::string_view> Trinity::ChatCommands::PlayerIdentifier::TryConsume(s if ((_player = ObjectAccessor::FindPlayerByLowGUID(_guid.GetCounter()))) _name = _player->GetName(); else if (!sCharacterCache->GetCharacterNameByGuid(_guid, _name)) - return std::nullopt; + return FormatTrinityString(handler, LANG_CMDPARSER_CHAR_GUID_NO_EXIST, _guid.ToString().c_str()); return next; } else @@ -107,12 +109,12 @@ Optional<std::string_view> Trinity::ChatCommands::PlayerIdentifier::TryConsume(s _name.assign(val.get<std::string_view>()); if (!normalizePlayerName(_name)) - return std::nullopt; + return FormatTrinityString(handler, LANG_CMDPARSER_CHAR_NAME_INVALID, STRING_VIEW_FMT_ARG(_name)); if ((_player = ObjectAccessor::FindPlayerByName(_name))) _guid = _player->GetGUID(); else if (!(_guid = sCharacterCache->GetCharacterGuidByName(_name))) - return std::nullopt; + return FormatTrinityString(handler, LANG_CMDPARSER_CHAR_NAME_NO_EXIST, STRING_VIEW_FMT_ARG(_name)); return next; } } diff --git a/src/server/game/Chat/ChatCommands/ChatCommandTags.h b/src/server/game/Chat/ChatCommands/ChatCommandTags.h index 879d1559dfa..dca28d205e8 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommandTags.h +++ b/src/server/game/Chat/ChatCommands/ChatCommandTags.h @@ -41,7 +41,11 @@ class Player; namespace Trinity::Impl::ChatCommands { - struct ContainerTag {}; + struct ContainerTag + { + using ChatCommandResult = Trinity::Impl::ChatCommands::ChatCommandResult; + }; + template <typename T> struct tag_base<T, std::enable_if_t<std::is_base_of_v<ContainerTag, T>>> { @@ -71,8 +75,11 @@ namespace Trinity::ChatCommands |* Simple holder classes to differentiate between extraction methods *| |* Must inherit from Trinity::Impl::ChatCommands::ContainerTag *| |* Must implement the following: *| - |* - TryConsume: std::string_view -> Optional<std::string_view> *| - |* returns nullopt if no match, otherwise the tail of the provided argument string *| + |* - TryConsume: ChatHandler const*, std::string_view -> ChatCommandResult *| + |* - on match, returns tail of the provided argument string (as std::string_view) *| + |* - on specific error, returns error message (as std::string&& or char const*) *| + |* - on generic error, returns std::nullopt (this will print command usage) *| + |* *| |* - typedef value_type of type that is contained within the tag *| |* - cast operator to value_type *| |* *| @@ -83,15 +90,17 @@ namespace Trinity::ChatCommands { using value_type = void; - Optional<std::string_view> TryConsume(std::string_view args) const + ChatCommandResult TryConsume(ChatHandler const* handler, std::string_view args) const { - if (StringStartsWithI(args, _string)) + std::string_view start = args.substr(0, _string.length()); + if (StringEqualI(start, _string)) { auto [remainingToken, tail] = Trinity::Impl::ChatCommands::tokenize(args.substr(_string.length())); if (remainingToken.empty()) // if this is not empty, then we did not consume the full token return tail; + start = args.substr(0, _string.length() + remainingToken.length()); } - return std::nullopt; + return Trinity::Impl::ChatCommands::FormatTrinityString(handler, LANG_CMDPARSER_EXACT_SEQ_MISMATCH, STRING_VIEW_FMT_ARG(_string), STRING_VIEW_FMT_ARG(start)); } private: @@ -108,7 +117,7 @@ namespace Trinity::ChatCommands using std::string_view::operator=; - Optional<std::string_view> TryConsume(std::string_view args) + ChatCommandResult TryConsume(ChatHandler const*,std::string_view args) { std::string_view::operator=(args); return std::string_view(); @@ -121,12 +130,12 @@ namespace Trinity::ChatCommands using std::wstring::operator=; - Optional<std::string_view> TryConsume(std::string_view args) + ChatCommandResult TryConsume(ChatHandler const* handler, std::string_view args) { if (Utf8toWStr(args, *this)) return std::string_view(); else - return std::nullopt; + return Trinity::Impl::ChatCommands::GetTrinityString(handler, LANG_CMDPARSER_INVALID_UTF8); } }; @@ -134,7 +143,7 @@ namespace Trinity::ChatCommands { using value_type = std::string; - TC_GAME_API Optional<std::string_view> TryConsume(std::string_view args); + TC_GAME_API ChatCommandResult TryConsume(ChatHandler const* handler, std::string_view args); }; struct TC_GAME_API AccountIdentifier : Trinity::Impl::ChatCommands::ContainerTag @@ -148,7 +157,7 @@ namespace Trinity::ChatCommands uint32 GetID() const { return _id; } std::string const& GetName() const { return _name; } - Optional<std::string_view> TryConsume(std::string_view args); + ChatCommandResult TryConsume(ChatHandler const* handler, std::string_view args); private: uint32 _id; @@ -171,7 +180,7 @@ namespace Trinity::ChatCommands bool IsConnected() const { return (_player != nullptr); } Player* GetConnectedPlayer() const { return _player; } - Optional<std::string_view> TryConsume(std::string_view args); + ChatCommandResult TryConsume(ChatHandler const* handler, std::string_view args); static Optional<PlayerIdentifier> FromTarget(ChatHandler* handler); static Optional<PlayerIdentifier> FromSelf(ChatHandler* handler); @@ -199,7 +208,7 @@ namespace Trinity::ChatCommands value_type operator*() const { return val; } storage_type const* operator->() const { return &val; } - Optional<std::string_view> TryConsume(std::string_view args) + ChatCommandResult TryConsume(ChatHandler const* handler, std::string_view args) { Trinity::Hyperlinks::HyperlinkInfo info = Trinity::Hyperlinks::ParseSingleHyperlink(args); // invalid hyperlinks cannot be consumed @@ -212,7 +221,7 @@ namespace Trinity::ChatCommands // store value if (!linktag::StoreTo(val, info.data)) - return std::nullopt; + return Trinity::Impl::ChatCommands::GetTrinityString(handler, LANG_CMDPARSER_LINKDATA_INVALID); // finally, skip any potential delimiters auto [token, next] = Trinity::Impl::ChatCommands::tokenize(info.tail); diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index eb3cfb44ec9..99c4342a3bb 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -994,22 +994,23 @@ enum TrinityStrings // 1219-1499 - free // Command argument parsers - LANG_CMDPARSER_EITHER = 1500, // 3.3.5 RESERVED - LANG_CMDPARSER_OR = 1501, // 3.3.5 RESERVED - LANG_CMDPARSER_STRING_VALUE_INVALID = 1502, // 3.3.5 RESERVED - LANG_CMDPARSER_INVALID_UTF8 = 1503, // 3.3.5 RESERVED - LANG_CMDPARSER_LINKDATA_INVALID = 1504, // 3.3.5 RESERVED - LANG_CMDPARSER_ACCOUNT_NAME_NO_EXIST = 1505, // 3.3.5 RESERVED - LANG_CMDPARSER_ACCOUNT_ID_NO_EXIST = 1506, // 3.3.5 RESERVED - LANG_CMDPARSER_CHAR_GUID_NO_EXIST = 1507, // 3.3.5 RESERVED - LANG_CMDPARSER_CHAR_NAME_NO_EXIST = 1508, // 3.3.5 RESERVED - LANG_CMDPARSER_CHAR_NAME_INVALID = 1509, // 3.3.5 RESERVED - LANG_CMDPARSER_ACHIEVEMENT_NO_EXIST = 1510, // 3.3.5 RESERVED - LANG_CMDPARSER_GAME_TELE_ID_NO_EXIST = 1511, // 3.3.5 RESERVED - LANG_CMDPARSER_GAME_TELE_NO_EXIST = 1512, // 3.3.5 RESERVED - LANG_CMDPARSER_ITEM_NO_EXIST = 1513, // 3.3.5 RESERVED - LANG_CMDPARSER_SPELL_NO_EXIST = 1514, // 3.3.5 RESERVED - LANG_CMDPARSER_EXACT_SEQ_MISMATCH = 1515, // 3.3.5 RESERVED + LANG_CMDPARSER_EITHER = 1500, + LANG_CMDPARSER_OR = 1501, + LANG_CMDPARSER_STRING_VALUE_INVALID = 1502, + LANG_CMDPARSER_INVALID_UTF8 = 1503, + LANG_CMDPARSER_LINKDATA_INVALID = 1504, + LANG_CMDPARSER_ACCOUNT_NAME_NO_EXIST = 1505, + LANG_CMDPARSER_ACCOUNT_ID_NO_EXIST = 1506, + LANG_CMDPARSER_CHAR_GUID_NO_EXIST = 1507, + LANG_CMDPARSER_CHAR_NAME_NO_EXIST = 1508, + LANG_CMDPARSER_CHAR_NAME_INVALID = 1509, + LANG_CMDPARSER_ACHIEVEMENT_NO_EXIST = 1510, + LANG_CMDPARSER_GAME_TELE_ID_NO_EXIST = 1511, + LANG_CMDPARSER_GAME_TELE_NO_EXIST = 1512, + LANG_CMDPARSER_ITEM_NO_EXIST = 1513, + LANG_CMDPARSER_SPELL_NO_EXIST = 1514, + LANG_CMDPARSER_EXACT_SEQ_MISMATCH = 1515, + LANG_CMDPARSER_CURRENCY_NO_EXIST = 1516, // 1516-1998 - free LANG_DEBUG_AREATRIGGER_LEFT = 1999, diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 8d1efd74f0e..f3d18a0b989 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -562,8 +562,8 @@ enum RealmZone /// Storage class for commands issued for delayed execution struct TC_GAME_API CliCommandHolder { - typedef void(*Print)(void*, char const*); - typedef void(*CommandFinished)(void*, bool success); + using Print = void(*)(void*, std::string_view); + using CommandFinished = void(*)(void*, bool success); void* m_callbackArg; char* m_command; diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index f87498b76c5..34e8cae35a4 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -41,9 +41,7 @@ EndScriptData */ #include "PoolMgr.h" #include "RBAC.h" #include "WorldSession.h" -#include <boost/core/demangle.hpp> #include <sstream> -#include <typeinfo> using namespace Trinity::ChatCommands; @@ -574,7 +572,7 @@ public: handler->PSendSysMessage(LANG_GOINFO_SIZE, gameObjectInfo->size); handler->PSendSysMessage(LANG_OBJECTINFO_AIINFO, gameObjectInfo->AIName.c_str(), sObjectMgr->GetScriptName(gameObjectInfo->ScriptId).c_str()); if (GameObjectAI const* ai = thisGO ? thisGO->AI() : nullptr) - handler->PSendSysMessage(LANG_OBJECTINFO_AITYPE, boost::core::demangle(typeid(*ai).name()).c_str()); + handler->PSendSysMessage(LANG_OBJECTINFO_AITYPE, GetTypeName(*ai).c_str()); if (GameObjectDisplayInfoEntry const* modelInfo = sGameObjectDisplayInfoStore.LookupEntry(displayId)) handler->PSendSysMessage(LANG_GOINFO_MODEL, modelInfo->GeoBoxMax.X, modelInfo->GeoBoxMax.Y, modelInfo->GeoBoxMax.Z, modelInfo->GeoBoxMin.X, modelInfo->GeoBoxMin.Y, modelInfo->GeoBoxMin.Z); diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 6112f51c7a9..b2ad46337ef 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -45,8 +45,6 @@ EndScriptData */ #include "Transport.h" #include "World.h" #include "WorldSession.h" -#include <boost/core/demangle.hpp> -#include <typeinfo> using namespace Trinity::ChatCommands; using CreatureSpawnId = Variant<Hyperlink<creature>, ObjectGuid::LowType>; @@ -550,7 +548,7 @@ public: handler->PSendSysMessage(LANG_OBJECTINFO_AIINFO, target->GetAIName().c_str(), target->GetScriptName().c_str()); handler->PSendSysMessage(LANG_NPCINFO_REACTSTATE, DescribeReactState(target->GetReactState())); if (CreatureAI const* ai = target->AI()) - handler->PSendSysMessage(LANG_OBJECTINFO_AITYPE, boost::core::demangle(typeid(*ai).name()).c_str()); + handler->PSendSysMessage(LANG_OBJECTINFO_AITYPE, GetTypeName(*ai).c_str()); handler->PSendSysMessage(LANG_NPCINFO_FLAGS_EXTRA, cInfo->flags_extra); for (CreatureFlagsExtra flag : EnumUtils::Iterate<CreatureFlagsExtra>()) if (cInfo->flags_extra & flag) diff --git a/src/server/worldserver/CommandLine/CliRunnable.cpp b/src/server/worldserver/CommandLine/CliRunnable.cpp index 29981235cfb..b36e9edf9d1 100644 --- a/src/server/worldserver/CommandLine/CliRunnable.cpp +++ b/src/server/worldserver/CommandLine/CliRunnable.cpp @@ -97,18 +97,17 @@ int cli_hook_func() #endif -void utf8print(void* /*arg*/, char const* str) +void utf8print(void* /*arg*/, std::string_view str) { #if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS - wchar_t wtemp_buf[6000]; - size_t wtemp_len = 6000-1; - if (!Utf8toWStr(str, strlen(str), wtemp_buf, wtemp_len)) + std::wstring wbuf; + if (!Utf8toWStr(str, wbuf)) return; - wprintf(L"%s", wtemp_buf); + wprintf(L"%s", wbuf.c_str()); #else { - printf("%s", str); + printf(STRING_VIEW_FMT, STRING_VIEW_FMT_ARG(str)); fflush(stdout); } #endif diff --git a/src/server/worldserver/RemoteAccess/RASession.cpp b/src/server/worldserver/RemoteAccess/RASession.cpp index 1cd6bbfe01b..8e32177fdc4 100644 --- a/src/server/worldserver/RemoteAccess/RASession.cpp +++ b/src/server/worldserver/RemoteAccess/RASession.cpp @@ -91,7 +91,7 @@ void RASession::Start() _socket.close(); } -int RASession::Send(char const* data) +int RASession::Send(std::string_view data) { std::ostream os(&_writeBuffer); os << data; @@ -204,9 +204,9 @@ bool RASession::ProcessCommand(std::string& command) return false; } -void RASession::CommandPrint(void* callbackArg, char const* text) +void RASession::CommandPrint(void* callbackArg, std::string_view text) { - if (!text || !*text) + if (text.empty()) return; RASession* session = static_cast<RASession*>(callbackArg); diff --git a/src/server/worldserver/RemoteAccess/RASession.h b/src/server/worldserver/RemoteAccess/RASession.h index e775bed5e33..d499727ae9d 100644 --- a/src/server/worldserver/RemoteAccess/RASession.h +++ b/src/server/worldserver/RemoteAccess/RASession.h @@ -42,13 +42,13 @@ public: unsigned short GetRemotePort() const { return _socket.remote_endpoint().port(); } private: - int Send(char const* data); + int Send(std::string_view data); std::string ReadString(); bool CheckAccessLevel(const std::string& user); bool CheckPassword(const std::string& user, const std::string& pass); bool ProcessCommand(std::string& command); - static void CommandPrint(void* callbackArg, char const* text); + static void CommandPrint(void* callbackArg, std::string_view text); static void CommandFinished(void* callbackArg, bool); tcp::socket _socket; diff --git a/src/server/worldserver/TCSoap/TCSoap.h b/src/server/worldserver/TCSoap/TCSoap.h index e45d044983b..be680eb4ba2 100644 --- a/src/server/worldserver/TCSoap/TCSoap.h +++ b/src/server/worldserver/TCSoap/TCSoap.h @@ -38,7 +38,7 @@ class SOAPCommand { } - void appendToPrintBuffer(char const* msg) + void appendToPrintBuffer(std::string_view msg) { m_printBuffer += msg; } @@ -54,7 +54,7 @@ class SOAPCommand return m_success; } - static void print(void* callbackArg, char const* msg) + static void print(void* callbackArg, std::string_view msg) { ((SOAPCommand*)callbackArg)->appendToPrintBuffer(msg); } |