diff options
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/game/Chat/ChatCommands/ChatCommandArgs.h | 76 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_go.cpp | 8 |
2 files changed, 43 insertions, 41 deletions
diff --git a/src/server/game/Chat/ChatCommands/ChatCommandArgs.h b/src/server/game/Chat/ChatCommands/ChatCommandArgs.h index 504f4d0dca3..bcfc336f7b3 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommandArgs.h +++ b/src/server/game/Chat/ChatCommands/ChatCommandArgs.h @@ -22,7 +22,10 @@ #include "ChatCommandTags.h" #include "SmartEnum.h" #include "Util.h" +#include <charconv> #include <map> +#include <string> +#include <string_view> struct GameTele; @@ -43,42 +46,26 @@ namespace ChatCommands template <typename T, typename = void> struct ArgInfo { static_assert(!std::is_same_v<T,T>, "Invalid command parameter type - see ChatCommandArgs.h for possible types"); }; -// catch-all for signed integral types +// catch-all for integral types template <typename T> -struct ArgInfo<T, std::enable_if_t<std::is_integral_v<T> && std::is_signed_v<T>>> +struct ArgInfo<T, std::enable_if_t<std::is_integral_v<T>>> { static char const* TryConsume(T& val, char const* args) { char const* next = args; - std::string token(args, Trinity::Impl::ChatCommands::tokenize(next)); - try - { - size_t processedChars = 0; - val = std::stoll(token, &processedChars, 0); - if (processedChars != token.length()) - return nullptr; - } - catch (...) { return nullptr; } - return next; - } -}; + std::string_view token(args, Trinity::Impl::ChatCommands::tokenize(next)); + + std::from_chars_result result; + if (StringStartsWith(token, "0x")) + result = std::from_chars(token.data() + 2, token.data() + token.length(), val, 16); + else if (StringStartsWith(token, "0b")) + result = std::from_chars(token.data() + 2, token.data() + token.length(), val, 2); + else + result = std::from_chars(token.data(), token.data() + token.length(), val, 10); + + if ((token.data() + token.length()) != result.ptr) + return nullptr; -// catch-all for unsigned integral types -template <typename T> -struct ArgInfo<T, std::enable_if_t<std::is_integral_v<T> && std::is_unsigned_v<T>>> -{ - static char const* TryConsume(T& val, char const* args) - { - char const* next = args; - std::string token(args, Trinity::Impl::ChatCommands::tokenize(next)); - try - { - size_t processedChars = 0; - val = std::stoull(token, &processedChars, 0); - if (processedChars != token.length()) - return nullptr; - } - catch (...) { return nullptr; } return next; } }; @@ -93,6 +80,7 @@ struct ArgInfo<T, std::enable_if_t<std::is_floating_point_v<T>>> std::string token(args, Trinity::Impl::ChatCommands::tokenize(next)); try { + // @todo replace this once libc++ supports double args to from_chars for required minimum size_t processedChars = 0; val = std::stold(token, &processedChars); if (processedChars != token.length()) @@ -103,16 +91,16 @@ struct ArgInfo<T, std::enable_if_t<std::is_floating_point_v<T>>> } }; -// string +// string_view template <> -struct ArgInfo<std::string, void> +struct ArgInfo<std::string_view, void> { - static char const* TryConsume(std::string& val, char const* args) + static char const* TryConsume(std::string_view& val, char const* args) { char const* next = args; if (size_t len = Trinity::Impl::ChatCommands::tokenize(next)) { - val.assign(args, len); + val = std::string_view(args, len); return next; } else @@ -120,19 +108,33 @@ struct ArgInfo<std::string, void> } }; +// string +template <> +struct ArgInfo<std::string, void> +{ + static char const* TryConsume(std::string& val, char const* args) + { + std::string_view view; + args = ArgInfo<std::string_view>::TryConsume(view, args); + if (args) + val.assign(view); + return args; + } +}; + // wstring template <> struct ArgInfo<std::wstring, void> { static char const* TryConsume(std::wstring& val, char const* args) { - std::string utf8Str; - char const* ret = ArgInfo<std::string>::TryConsume(utf8Str, args); + std::string_view utf8view; + char const* ret = ArgInfo<std::string_view>::TryConsume(utf8view, args); if (!ret) return nullptr; - if (!Utf8toWStr(utf8Str, val)) + if (!Utf8toWStr(utf8view, val)) return nullptr; return ret; diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp index 4ea253742f4..f782a972180 100644 --- a/src/server/scripts/Commands/cs_go.cpp +++ b/src/server/scripts/Commands/cs_go.cpp @@ -372,7 +372,7 @@ public: return DoTeleport(handler, loc); } - static bool HandleGoInstanceCommand(ChatHandler* handler, std::vector<std::string> const& labels) + static bool HandleGoInstanceCommand(ChatHandler* handler, std::vector<std::string_view> labels) { if (labels.empty()) return false; @@ -384,7 +384,7 @@ public: uint32 count = 0; std::string const& scriptName = sObjectMgr->GetScriptName(pair.second.ScriptId); char const* mapName = ASSERT_NOTNULL(sMapStore.LookupEntry(pair.first))->MapName[handler->GetSessionDbcLocale()]; - for (auto const& label : labels) + for (std::string_view label : labels) if (StringContainsStringI(scriptName, label)) ++count; @@ -457,7 +457,7 @@ public: return false; } - static bool HandleGoBossCommand(ChatHandler* handler, std::vector<std::string> const& needles) + static bool HandleGoBossCommand(ChatHandler* handler, std::vector<std::string_view> needles) { if (needles.empty()) return false; @@ -474,7 +474,7 @@ public: uint32 count = 0; std::string const& scriptName = sObjectMgr->GetScriptName(data.ScriptID); - for (auto const& label : needles) + for (std::string_view label : needles) if (StringContainsStringI(scriptName, label) || StringContainsStringI(data.Name, label)) ++count; |
