From 160ed4abe34702f3933863cb7b7916149af780b2 Mon Sep 17 00:00:00 2001 From: Shauren Date: Thu, 10 Apr 2025 16:58:39 +0200 Subject: Core/Commands: Allow non-const reference arguments in chat command handlers (cherry picked from commit f1141d363872bad3524beec29e2eca55d0a8b6ed) --- src/server/game/Chat/ChatCommands/ChatCommand.h | 22 ++++++++++++++++------ src/server/scripts/Commands/cs_ban.cpp | 2 +- 2 files changed, 17 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/server/game/Chat/ChatCommands/ChatCommand.h b/src/server/game/Chat/ChatCommands/ChatCommand.h index 80996348c66..b7783e4faa8 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommand.h +++ b/src/server/game/Chat/ChatCommands/ChatCommand.h @@ -114,8 +114,10 @@ namespace Trinity::Impl::ChatCommands } template struct HandlerToTuple { static_assert(Trinity::dependant_false_v, "Invalid command handler signature"); }; - template struct HandlerToTuple { using type = std::tuple...>; }; - template using TupleType = typename HandlerToTuple::type; + template struct HandlerToTuple { using type = std::tuple; }; + + template struct ValueTupleType { }; + template struct ValueTupleType> { using type = std::tuple...>; }; struct CommandInvoker { @@ -125,13 +127,14 @@ namespace Trinity::Impl::ChatCommands { _wrapper = [](void* handler, ChatHandler* chatHandler, std::string_view argsStr) { - using Tuple = TupleType; + using RefTuple = typename HandlerToTuple::type; + using ValueTuple = typename ValueTupleType::type; - Tuple arguments; + ValueTuple arguments; std::get<0>(arguments) = chatHandler; - ChatCommandResult result = ConsumeFromOffset(arguments, chatHandler, argsStr); + ChatCommandResult result = ConsumeFromOffset(arguments, chatHandler, argsStr); if (result) - return std::apply(reinterpret_cast(handler), std::move(arguments)); + return Invoke(reinterpret_cast(handler), arguments, std::make_index_sequence>{}); else { if (result.HasErrorMessage()) @@ -161,6 +164,13 @@ namespace Trinity::Impl::ChatCommands } private: + template + static constexpr bool Invoke(TypedHandler* handler, ValueTuple& arguments, std::index_sequence) + { + // Invoke command handler preserving original reference category of each argument + return std::invoke(handler, std::get(advstd::forward_like>(arguments))...); + } + using wrapper_func = bool(void*, ChatHandler*, std::string_view); wrapper_func* _wrapper; void* _handler; diff --git a/src/server/scripts/Commands/cs_ban.cpp b/src/server/scripts/Commands/cs_ban.cpp index 7af5a820ccc..b85bc48c326 100644 --- a/src/server/scripts/Commands/cs_ban.cpp +++ b/src/server/scripts/Commands/cs_ban.cpp @@ -368,7 +368,7 @@ public: return true; } - static bool HandleBanInfoIPCommand(ChatHandler* handler, std::string&& ip) + static bool HandleBanInfoIPCommand(ChatHandler* handler, std::string& ip) { if (!IsIPAddress(ip)) return false; -- cgit v1.2.3