30using ChatSubCommandMap = std::map<std::string_view, Trinity::Impl::ChatCommands::ChatCommandNode, StringCompareLessI_T>;
34 switch (builder.
_data.index())
49 auto [data, size] = std::get<1>(builder.
_data);
62 if (builder._name.empty())
64 ASSERT(blank,
"Empty name command at top level is not permitted.");
72 for (
size_t i = 0, n = (tokens.size() - 1); i < n; ++i)
73 subMap = &((*subMap)[tokens[i]]._subCommands);
74 ((*subMap)[tokens.back()]).LoadFromBuilder(builder);
89 InvalidateCommandMap();
96 Field* fields = result->Fetch();
104 auto it = map->find(key);
105 if (it != map->end())
112 TC_LOG_ERROR(
"sql.sql",
"Table `command` contains data for non-existant command '{}'. Skipped.", name);
121 if (std::holds_alternative<std::string>(cmd->
_help))
122 TC_LOG_ERROR(
"sql.sql",
"Table `command` contains duplicate data for command '{}'. Skipped.", name);
124 if (std::holds_alternative<std::monostate>(cmd->
_help))
125 cmd->
_help.emplace<std::string>(help);
127 TC_LOG_ERROR(
"sql.sql",
"Table `command` contains legacy help text for command '{}', which uses `trinity_string`. Skipped.", name);
128 }
while (result->NextRow());
132 cmd.ResolveNames(std::string(name));
137 if (_invoker && std::holds_alternative<std::monostate>(_help))
138 TC_LOG_WARN(
"sql.sql",
"Table `command` is missing help text for command '{}'.", name);
141 for (
auto& [subToken, cmd] : _subCommands)
143 std::string subName(name);
145 subName.append(subToken);
146 cmd.ResolveNames(subName);
161 std::string areaName =
"Unknown";
162 std::string zoneName =
"Unknown";
166 areaName = area->AreaName[locale];
169 zoneName = zone->AreaName[locale];
172 sLog->OutCommand(session.
GetAccountId(),
"Command: {} [Player: {} ({}) (Account: {}) X: {} Y: {} Z: {} Map: {} ({}) Area: {} ({}) Zone: {} Selected: {} ({})]",
177 areaId, areaName, zoneName,
184 bool const hasInvoker = IsInvokerVisible(handler);
187 if (std::holds_alternative<TrinityStrings>(_help))
189 else if (std::holds_alternative<std::string>(_help))
199 for (
auto it = _subCommands.begin(); it != _subCommands.end(); ++it)
201 bool const subCommandHasSubCommand = it->second.HasVisibleSubCommands(handler);
202 if (!subCommandHasSubCommand && !it->second.IsInvokerVisible(handler))
226 decltype(
auto)
operator*()
const {
return _it.operator*(); }
227 decltype(
auto) operator->()
const {
return _it.operator->(); }
234 explicit operator bool()
const {
return (
_it !=
_end); }
235 bool operator!()
const {
return !
static_cast<bool>(*this); }
262 cmdStr.remove_prefix(1);
264 cmdStr.remove_suffix(1);
265 std::string_view oldTail = cmdStr;
266 while (!oldTail.empty())
269 auto [token, newTail] =
tokenize(oldTail);
370 else if (cmdStr.empty())
392 cmdStr.remove_prefix(1);
394 cmdStr.remove_suffix(1);
395 std::string_view oldTail = cmdStr;
396 while (!oldTail.empty())
399 auto [token, newTail] =
tokenize(oldTail);
412 std::vector<std::string> vec;
413 auto possibility = ([prefix = std::string_view(path), suffix = std::string_view(newTail)](std::string_view match)
421 vec.emplace_back(possibility(it1->first));
423 do vec.emplace_back(possibility(it2->first));
432 path.assign(it1->first);
442 if (!oldTail.empty())
455 auto possibility = ([prefix = std::string_view(path)](std::string_view match)
458 return std::string(match);
465 std::vector<std::string> vec;
467 vec.emplace_back(possibility(it->first));
483 for (
auto it = _subCommands.begin(); it != _subCommands.end(); ++it)
484 if (it->second.IsVisible(who))
491 if (result2.IsSuccessful())
493 else if (result2.HasErrorMessage())
495 if (result1.HasErrorMessage())
500 result1 = std::move(result2).GetErrorMessage();
static void LogCommandUsage(WorldSession const &session, uint32 permission, std::string_view cmdStr)
static ChatSubCommandMap COMMAND_MAP
std::map< std::string_view, Trinity::Impl::ChatCommands::ChatCommandNode, StringCompareLessI_T > ChatSubCommandMap
DB2Storage< AreaTableEntry > sAreaTableStore("AreaTable.db2", &AreaTableLoadInfo::Instance)
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
#define STRING_VIEW_FMT_ARG(str)
@ LANG_CMD_NO_HELP_AVAILABLE
@ LANG_SUBCMDS_LIST_ENTRY
@ LANG_SUBCMDS_LIST_ENTRY_ELLIPSIS
#define TC_LOG_ERROR(filterType__, message__,...)
#define TC_LOG_WARN(filterType__, message__,...)
TC_COMMON_API bool StringEqualI(std::string_view str1, std::string_view str2)
bool StringStartsWithI(std::string_view haystack, std::string_view needle)
static bool IsPlayerAccount(uint32 gmlevel)
ObjectGuid const & GetGUID() const
virtual bool HasPermission(uint32 permission) const
WorldSession * GetSession()
bool HasSentErrorMessage() const
void SetSentErrorMessage(bool val)
void PSendSysMessage(char const *fmt, Args &&... args)
virtual void SendSysMessage(std::string_view str, bool escapeCharacters=false)
Class used to access individual fields of database query result.
std::string_view GetStringView() const noexcept
char const * GetMapName() const
std::string ToString() const
Unit * GetSelectedUnit() const
void SendCommandHelp(ChatHandler &handler) const
static void LoadCommandsIntoMap(ChatCommandNode *blank, std::map< std::string_view, ChatCommandNode, StringCompareLessI_T > &map, std::span< ChatCommandBuilder const > commands)
std::map< std::string_view, ChatCommandNode, StringCompareLessI_T > _subCommands
std::variant< std::monostate, TrinityStrings, std::string > _help
static void LoadCommandMap()
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()
void ResolveNames(std::string name)
CommandPermissions _permission
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)
ObjectGuid GetTarget() const
constexpr uint32 GetMapId() const
std::string const & GetName() const
Player session in the World.
AccountTypes GetSecurity() const
LocaleConstant GetSessionDbcLocale() const
Player * GetPlayer() const
uint32 GetAccountId() const
TC_GAME_API std::vector< std::string > GetAutoCompletionsFor(ChatHandler const &handler, std::string_view cmd)
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
TokenizeResult tokenize(std::string_view args) noexcept
static constexpr char COMMAND_DELIMITER
TC_GAME_API char const * GetTrinityString(ChatHandler const *handler, TrinityStrings which)
TC_COMMON_API std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
std::string StringFormat(FormatString< Args... > fmt, Args &&... args) noexcept
Default TC string format function.
constexpr float GetPositionX() const
constexpr float GetPositionY() const
constexpr float GetPositionZ() const
Trinity::Impl::ChatCommands::CommandInvoker _invoker
Trinity::Impl::ChatCommands::CommandPermissions _permissions
std::variant< InvokerEntry, std::pair< ChatCommandBuilder const *, std::size_t > > _data
rbac::RBACPermissions RequiredPermission
ChatSubCommandMap::const_iterator _it
FilteredCommandListIterator(ChatSubCommandMap const &map, ChatHandler const &handler, std::string_view token)
std::string_view const _token
ChatSubCommandMap::const_iterator _end
FilteredCommandListIterator & operator++()
ChatHandler const & _handler