18#ifndef TRINITY_CHATCOMMAND_H
19#define TRINITY_CHATCOMMAND_H
48 struct ChatCommandBuilder;
58 template <
typename Tuple,
size_t offset>
61 template <
typename Tuple,
typename NextType,
size_t offset>
68 ConsumeFromOffset<Tuple, offset + 1>(next, tuple, handler, *next);
75 template <
typename Tuple,
typename NestedNextType,
size_t offset>
81 auto& myArg = std::get<offset>(tuple);
86 ConsumeFromOffset<Tuple, offset + 1>(result1, tuple, handler, *result1);
94 ConsumeFromOffset<Tuple, offset + 1>(result2, tuple, handler, args);
100 template <
typename Tuple,
size_t offset>
103 if constexpr (offset < std::tuple_size_v<Tuple>)
104 result =
MultiConsumer<Tuple, std::tuple_element_t<offset, Tuple>, offset>::TryConsumeTo(tuple, handler, args);
105 else if (!args.empty())
106 result = std::nullopt;
111 template <
typename T>
struct CommandInvokerTraits {
static_assert(Trinity::dependant_false_v<T>,
"Invalid command handler signature"); };
115 using Refs = std::tuple<Ts...>;
116 using Vals = std::tuple<std::remove_cvref_t<Ts>...>;
122 ConsumeFromOffset<Vals, 0>(result, arguments, chatHandler, argsStr);
124 return Invoke(
reinterpret_cast<Func*
>(handler), chatHandler, arguments, std::make_index_sequence<std::tuple_size_v<Vals>>{});
132 template <std::size_t... I>
136 return handler(chatHandler, std::get<I>(
advstd::forward_like<std::tuple_element_t<I, Refs>>(arguments))...);
145 template <
typename TypedHandler>
149 explicit operator bool()
const {
return (
_wrapper !=
nullptr); }
161 std::string argsStrCopy(argsStr);
162 return reinterpret_cast<bool(*)(
ChatHandler*,
char const*)
>(handler)(chatHandler, argsStrCopy.c_str());
194 static std::map<std::string_view, ChatCommandNode, StringCompareLessI_T>
const&
GetTopLevelMap();
195 static void LoadCommandsIntoMap(
ChatCommandNode* blank, std::map<std::string_view, ChatCommandNode, StringCompareLessI_T>& map, std::span<ChatCommandBuilder const> commands);
213 std::variant<std::monostate, TrinityStrings, std::string>
_help;
214 std::map<std::string_view, ChatCommandNode, StringCompareLessI_T>
_subCommands;
225 template <
typename T>
236 template <
typename TypedHandler>
241 template <
typename TypedHandler>
246 :
_name{ name },
_data{
std::in_place_index<1>, subCommands.data(), subCommands.size() }
249 [[deprecated(
"char const* parameters to command handlers are deprecated; convert this to a typed argument handler instead")]]
254 template <
typename TypedHandler>
255 [[deprecated(
"you are using the old-style command format; convert this to the new format ({ name, handler (not a pointer!), permission, Console::(Yes/No) })")]]
260 [[deprecated(
"you are using the old-style command format; convert this to the new format ({ name, subCommands })")]]
267 std::variant<InvokerEntry, std::pair<ChatCommandBuilder const*, std::size_t> >
_data;
std::optional< T > Optional
Optional helper class to wrap optional values within.
Role Based Access Control related classes definition.
void SendCommandHelp(ChatHandler &handler) const
ChatCommandNode(ChatCommandNode const &other)=delete
static void LoadCommandsIntoMap(ChatCommandNode *blank, std::map< std::string_view, ChatCommandNode, StringCompareLessI_T > &map, std::span< ChatCommandBuilder const > commands)
ChatCommandNode & operator=(ChatCommandNode &&other) noexcept=default
std::map< std::string_view, ChatCommandNode, StringCompareLessI_T > _subCommands
std::variant< std::monostate, TrinityStrings, std::string > _help
~ChatCommandNode()=default
ChatCommandNode(ChatCommandNode &&other) noexcept=default
static void LoadCommandMap()
ChatCommandNode()=default
bool HasVisibleSubCommands(ChatHandler const &who) const
static void SendCommandHelpFor(ChatHandler &handler, std::string_view cmd)
static void InvalidateCommandMap()
void LoadFromBuilder(ChatCommandBuilder const &builder)
static std::map< std::string_view, ChatCommandNode, StringCompareLessI_T > const & GetTopLevelMap()
bool IsVisible(ChatHandler const &who) const
void ResolveNames(std::string name)
CommandPermissions _permission
ChatCommandNode & operator=(ChatCommandNode const &other)=delete
bool IsInvokerVisible(ChatHandler const &who) const
static std::vector< std::string > GetAutoCompletionsFor(ChatHandler const &handler, std::string_view cmd)
static bool TryExecuteCommand(ChatHandler &handler, std::string_view cmd)
TC_GAME_API std::vector< std::string > GetAutoCompletionsFor(ChatHandler const &handler, std::string_view cmd)
ChatCommandBuilder const [] ChatCommandTable
TC_GAME_API void SendCommandHelpFor(ChatHandler &handler, std::string_view cmd)
TC_GAME_API bool TryExecuteCommand(ChatHandler &handler, std::string_view cmd)
TC_GAME_API void InvalidateCommandMap()
TC_GAME_API void LoadCommandMap()
TC_GAME_API void MergeChatCommandResults(ChatHandler const *handler, ChatCommandResult &result1, ChatCommandResult &result2) noexcept
void ConsumeFromOffset(ChatCommandResult &result, Tuple &, ChatHandler const *handler, std::string_view args) noexcept
TC_GAME_API void SendErrorMessageToHandler(ChatHandler *handler, std::string_view str)
constexpr decltype(auto) forward_like(U &&value) noexcept
InvokerEntry(T &handler, TrinityStrings help, rbac::RBACPermissions permission, Trinity::ChatCommands::Console allowConsole)
Trinity::Impl::ChatCommands::CommandInvoker _invoker
Trinity::Impl::ChatCommands::CommandPermissions _permissions
ChatCommandBuilder(std::string_view name, TypedHandler &handler, TrinityStrings help, rbac::RBACPermissions permission, Trinity::ChatCommands::Console allowConsole)
ChatCommandBuilder(char const *name, rbac::RBACPermissions permission, bool console, TypedHandler *handler, char const *)
ChatCommandBuilder(std::string_view name, TypedHandler &handler, rbac::RBACPermissions permission, Trinity::ChatCommands::Console allowConsole)
ChatCommandBuilder(char const *name, rbac::RBACPermissions, bool, std::nullptr_t, char const *, SubCommandEntry sub)
ChatCommandBuilder(std::string_view name, std::span< ChatCommandBuilder const > subCommands)
std::span< ChatCommandBuilder const > SubCommandEntry
ChatCommandBuilder(char const *name, bool(&handler)(ChatHandler *, char const *), rbac::RBACPermissions permission, Trinity::ChatCommands::Console allowConsole)
std::variant< InvokerEntry, std::pair< ChatCommandBuilder const *, std::size_t > > _data
bool IsSuccessful() const
std::string const & GetErrorMessage() const &
bool HasErrorMessage() const
static constexpr bool Invoke(Func *handler, ChatHandler *chatHandler, Vals &arguments, std::index_sequence< I... >) noexcept
bool(ChatHandler *, Ts...) Func
static bool Wrapper(void *handler, ChatHandler *chatHandler, std::string_view argsStr) noexcept
std::tuple< std::remove_cvref_t< Ts >... > Vals
std::add_pointer_t< bool(void *, ChatHandler *, std::string_view) noexcept > wrapper_func
static bool LegacyWrapper(void *handler, ChatHandler *chatHandler, std::string_view argsStr) noexcept
bool operator()(ChatHandler *chatHandler, std::string_view args) const
CommandInvoker(TypedHandler &handler)
CommandInvoker(bool(&handler)(ChatHandler *, char const *))
Trinity::ChatCommands::Console AllowConsole
CommandPermissions(rbac::RBACPermissions perm, Trinity::ChatCommands::Console console)
rbac::RBACPermissions RequiredPermission
static ChatCommandResult TryConsumeTo(Tuple &tuple, ChatHandler const *handler, std::string_view args) noexcept
static ChatCommandResult TryConsumeTo(Tuple &tuple, ChatHandler const *handler, std::string_view args) noexcept