30using ChatSubCommandMap = std::map<std::string_view, Trinity::Impl::ChatCommands::ChatCommandNode, StringCompareLessI_T>;
34 if (std::holds_alternative<ChatCommandBuilder::InvokerEntry>(builder.
_data))
50 if (builder._name.empty())
52 ASSERT(blank,
"Empty name command at top level is not permitted.");
60 for (
size_t i = 0, n = (tokens.size() - 1); i < n; ++i)
61 subMap = &((*subMap)[tokens[i]]._subCommands);
62 ((*subMap)[tokens.back()]).LoadFromBuilder(builder);
77 InvalidateCommandMap();
84 Field* fields = result->Fetch();
92 auto it = map->find(key);
100 TC_LOG_ERROR(
"sql.sql",
"Table `command` contains data for non-existant command '{}'. Skipped.", name);
109 if (std::holds_alternative<std::string>(cmd->
_help))
110 TC_LOG_ERROR(
"sql.sql",
"Table `command` contains duplicate data for command '{}'. Skipped.", name);
112 if (std::holds_alternative<std::monostate>(cmd->
_help))
113 cmd->
_help.emplace<std::string>(help);
115 TC_LOG_ERROR(
"sql.sql",
"Table `command` contains legacy help text for command '{}', which uses `trinity_string`. Skipped.", name);
116 }
while (result->NextRow());
120 cmd.ResolveNames(std::string(name));
125 if (_invoker && std::holds_alternative<std::monostate>(_help))
126 TC_LOG_WARN(
"sql.sql",
"Table `command` is missing help text for command '{}'.", name);
129 for (
auto& [subToken, cmd] : _subCommands)
131 std::string subName(name);
133 subName.append(subToken);
134 cmd.ResolveNames(subName);
149 std::string areaName =
"Unknown";
150 std::string zoneName =
"Unknown";
154 areaName = area->AreaName[locale];
156 zoneName = zone->AreaName[locale];
159 sLog->OutCommand(session.
GetAccountId(),
"Command: {} [Player: {} ({}) (Account: {}) X: {} Y: {} Z: {} Map: {} ({}) Area: {} ({}) Zone: {} Selected: {} ({})]",
164 areaId, areaName, zoneName,
171 bool const hasInvoker = IsInvokerVisible(handler);
174 if (std::holds_alternative<TrinityStrings>(_help))
176 else if (std::holds_alternative<std::string>(_help))
186 for (
auto it = _subCommands.begin(); it != _subCommands.end(); ++it)
188 bool const subCommandHasSubCommand = it->second.HasVisibleSubCommands(handler);
189 if (!subCommandHasSubCommand && !it->second.IsInvokerVisible(handler))
213 decltype(
auto)
operator*()
const {
return _it.operator*(); }
214 decltype(
auto) operator->()
const {
return _it.operator->(); }
221 explicit operator bool()
const {
return (
_it !=
_end); }
222 bool operator!()
const {
return !
static_cast<bool>(*this); }
249 cmdStr.remove_prefix(1);
251 cmdStr.remove_suffix(1);
252 std::string_view oldTail = cmdStr;
253 while (!oldTail.empty())
256 auto [token, newTail] =
tokenize(oldTail);
357 else if (cmdStr.empty())
379 cmdStr.remove_prefix(1);
381 cmdStr.remove_suffix(1);
382 std::string_view oldTail = cmdStr;
383 while (!oldTail.empty())
386 auto [token, newTail] =
tokenize(oldTail);
399 std::vector<std::string> vec;
400 auto possibility = ([prefix = std::string_view(path), suffix = std::string_view(newTail)](std::string_view match)
412 vec.emplace_back(possibility(it1->first));
414 do vec.emplace_back(possibility(it2->first));
423 path.assign(it1->first);
433 if (!oldTail.empty())
446 auto possibility = ([prefix = std::string_view(path)](std::string_view match)
449 return std::string(match);
456 std::vector<std::string> vec;
458 vec.emplace_back(possibility(it->first));
474 for (
auto it = _subCommands.begin(); it != _subCommands.end(); ++it)
475 if (it->second.IsVisible(who))
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
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
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_WARN(filterType__,...)
#define TC_LOG_ERROR(filterType__,...)
bool StringEqualI(std::string_view a, std::string_view b)
bool StringStartsWithI(std::string_view haystack, std::string_view needle)
static bool IsPlayerAccount(uint32 gmlevel)
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
char const * GetMapName() const
std::string ToString() const
static ObjectGuid GetGUID(Object const *o)
Unit * GetSelectedUnit() const
void SendCommandHelp(ChatHandler &handler) const
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()
static void LoadCommandsIntoMap(ChatCommandNode *blank, std::map< std::string_view, ChatCommandNode, StringCompareLessI_T > &map, Trinity::ChatCommands::ChatCommandTable const &commands)
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
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)
std::vector< ChatCommandBuilder > ChatCommandTable
TC_GAME_API bool TryExecuteCommand(ChatHandler &handler, std::string_view cmd)
TC_GAME_API void InvalidateCommandMap()
TC_GAME_API void LoadCommandMap()
TokenizeResult tokenize(std::string_view args)
static constexpr char COMMAND_DELIMITER
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)
Default TC string format function.
float GetPositionZ() const
float GetPositionX() const
float GetPositionY() const
std::variant< InvokerEntry, SubCommandEntry > _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