AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
Acore::Impl::ChatCommands::ChatCommandNode Class Reference

#include "ChatCommand.h"

Public Member Functions

 ChatCommandNode ()
 

Static Public Member Functions

static void LoadCommandMap ()
 
static void InvalidateCommandMap ()
 
static bool TryExecuteCommand (ChatHandler &handler, std::string_view cmd)
 
static void SendCommandHelpFor (ChatHandler &handler, std::string_view cmd)
 
static std::vector< std::string > GetAutoCompletionsFor (ChatHandler const &handler, std::string_view cmd)
 

Private Types

using ChatCommandBuilder = Acore::ChatCommands::ChatCommandBuilder
 

Private Member Functions

void LoadFromBuilder (ChatCommandBuilder const &builder)
 
 ChatCommandNode (ChatCommandNode &&other)=default
 
void ResolveNames (std::string name)
 
void SendCommandHelp (ChatHandler &handler) const
 
bool IsVisible (ChatHandler const &who) const
 
bool IsInvokerVisible (ChatHandler const &who) const
 
bool HasVisibleSubCommands (ChatHandler const &who) const
 

Static Private Member Functions

static std::map< std::string_view, ChatCommandNode, StringCompareLessI_T > const & GetTopLevelMap ()
 
static void LoadCommandsIntoMap (ChatCommandNode *blank, std::map< std::string_view, Acore::Impl::ChatCommands::ChatCommandNode, StringCompareLessI_T > &map, Acore::ChatCommands::ChatCommandTable const &commands)
 

Private Attributes

std::string _name
 
CommandInvoker _invoker
 
CommandPermissions _permission
 
std::variant< std::monostate, AcoreStrings, std::string > _help
 
std::map< std::string_view, ChatCommandNode, StringCompareLessI_T_subCommands
 

Friends

struct FilteredCommandListIterator
 

Detailed Description

Member Typedef Documentation

◆ ChatCommandBuilder

Constructor & Destructor Documentation

◆ ChatCommandNode() [1/2]

Acore::Impl::ChatCommands::ChatCommandNode::ChatCommandNode ( )
inline
190: _name{}, _invoker {}, _permission{}, _help{}, _subCommands{} { }
std::string _name
Definition: ChatCommand.h:206
CommandInvoker _invoker
Definition: ChatCommand.h:207
std::variant< std::monostate, AcoreStrings, std::string > _help
Definition: ChatCommand.h:209
std::map< std::string_view, ChatCommandNode, StringCompareLessI_T > _subCommands
Definition: ChatCommand.h:210
CommandPermissions _permission
Definition: ChatCommand.h:208

◆ ChatCommandNode() [2/2]

Acore::Impl::ChatCommands::ChatCommandNode::ChatCommandNode ( ChatCommandNode &&  other)
privatedefault

Member Function Documentation

◆ GetAutoCompletionsFor()

std::vector< std::string > Acore::Impl::ChatCommands::ChatCommandNode::GetAutoCompletionsFor ( ChatHandler const &  handler,
std::string_view  cmd 
)
static
419{
420 std::string path;
421 ChatCommandNode const* cmd = nullptr;
422 ChatSubCommandMap const* map = &GetTopLevelMap();
423
424 while (!cmdStr.empty() && (cmdStr.front() == COMMAND_DELIMITER))
425 cmdStr.remove_prefix(1);
426
427 while (!cmdStr.empty() && (cmdStr.back() == COMMAND_DELIMITER))
428 cmdStr.remove_suffix(1);
429
430 std::string_view oldTail = cmdStr;
431 while (!oldTail.empty())
432 {
433 /* oldTail = token DELIMITER newTail */
434 auto [token, newTail] = tokenize(oldTail);
435 ASSERT(!token.empty());
436 FilteredCommandListIterator it1(*map, handler, token);
437 if (!it1)
438 break; /* no matching subcommands found */
439
440 if (!StringEqualI(it1->first, token))
441 { /* ok, so it1 points at a partially matching subcommand - let's see if there are others */
442 auto it2 = it1;
443 ++it2;
444
445 if (it2)
446 { /* there are multiple matching subcommands - terminate here and show possibilities */
447 std::vector<std::string> vec;
448 auto possibility = ([prefix = std::string_view(path), suffix = std::string_view(newTail)](std::string_view match)
449 {
450 if (prefix.empty())
451 {
452 return Acore::StringFormatFmt("{}{}{}", match, COMMAND_DELIMITER, suffix);
453 }
454 else
455 {
456 return Acore::StringFormatFmt("{}{}{}{}{}", prefix, COMMAND_DELIMITER, match, COMMAND_DELIMITER, suffix);
457 }
458 });
459
460 vec.emplace_back(possibility(it1->first));
461
462 do vec.emplace_back(possibility(it2->first));
463 while (++it2);
464
465 return vec;
466 }
467 }
468
469 /* now we matched exactly one subcommand, and it1 points to it; go down the rabbit hole */
470 if (path.empty())
471 path.assign(it1->first);
472 else
473 {
474 path = Acore::StringFormatFmt("{}{}{}", path, COMMAND_DELIMITER, it1->first);
475 }
476 cmd = &it1->second;
477 map = &cmd->_subCommands;
478
479 oldTail = newTail;
480 }
481
482 if (!oldTail.empty())
483 { /* there is some trailing text, leave it as is */
484 if (cmd)
485 { /* if we matched a command at some point, auto-complete it */
486 return { Acore::StringFormatFmt("{}{}{}", path, COMMAND_DELIMITER, oldTail) };
487 }
488 else
489 return {};
490 }
491 else
492 { /* offer all subcommands */
493 auto possibility = ([prefix = std::string_view(path)](std::string_view match)
494 {
495 if (prefix.empty())
496 return std::string(match);
497 else
498 {
499 return Acore::StringFormatFmt("{}{}{}", prefix, COMMAND_DELIMITER, match);
500 }
501 });
502
503 std::vector<std::string> vec;
504 for (FilteredCommandListIterator it(*map, handler, ""); it; ++it)
505 vec.emplace_back(possibility(it->first));
506 return vec;
507 }
508}
#define ASSERT
Definition: Errors.h:68
bool StringEqualI(std::string_view a, std::string_view b)
Definition: Util.cpp:588
std::map< std::string_view, Acore::Impl::ChatCommands::ChatCommandNode, StringCompareLessI_T > ChatSubCommandMap
Definition: ChatCommand.cpp:30
std::string StringFormatFmt(std::string_view fmt, Args &&... args)
Definition: StringFormat.h:44
static constexpr char COMMAND_DELIMITER
Definition: ChatCommandHelpers.h:38
TokenizeResult tokenize(std::string_view args)
Definition: ChatCommandHelpers.h:55
friend struct FilteredCommandListIterator
Definition: ChatCommand.h:180
static std::map< std::string_view, ChatCommandNode, StringCompareLessI_T > const & GetTopLevelMap()
Definition: ChatCommand.cpp:69
ChatCommandNode()
Definition: ChatCommand.h:190

References _subCommands, ASSERT, Acore::Impl::ChatCommands::COMMAND_DELIMITER, StringEqualI(), Acore::StringFormatFmt(), and Acore::Impl::ChatCommands::tokenize().

Referenced by Acore::ChatCommands::GetAutoCompletionsFor().

◆ GetTopLevelMap()

ChatSubCommandMap const & Acore::Impl::ChatCommands::ChatCommandNode::GetTopLevelMap ( )
staticprivate
70{
71 if (COMMAND_MAP.empty())
73
74 return COMMAND_MAP;
75}
static ChatSubCommandMap COMMAND_MAP
Definition: ChatCommand.cpp:68
static void LoadCommandMap()
Definition: ChatCommand.cpp:81

References COMMAND_MAP.

◆ HasVisibleSubCommands()

bool Acore::Impl::ChatCommands::ChatCommandNode::HasVisibleSubCommands ( ChatHandler const &  who) const
private
525{
526 for (auto it = _subCommands.begin(); it != _subCommands.end(); ++it)
527 if (it->second.IsVisible(who))
528 return true;
529
530 return false;
531}

Referenced by IsVisible().

◆ InvalidateCommandMap()

void Acore::Impl::ChatCommands::ChatCommandNode::InvalidateCommandMap ( )
static
77{
78 COMMAND_MAP.clear();
79}

References COMMAND_MAP.

Referenced by Acore::ChatCommands::InvalidateCommandMap().

◆ IsInvokerVisible()

bool Acore::Impl::ChatCommands::ChatCommandNode::IsInvokerVisible ( ChatHandler const &  who) const
private
511{
512 if (!_invoker)
513 return false;
514
516 return false;
517
519 return true;
520
521 return !who.IsConsole() && who.IsAvailable(_permission.RequiredLevel);
522}
uint32 RequiredLevel
Definition: ChatCommand.h:174
Acore::ChatCommands::Console AllowConsole
Definition: ChatCommand.h:175

References ChatHandler::IsAvailable(), ChatHandler::IsConsole(), Acore::ChatCommands::No, and Acore::ChatCommands::Yes.

Referenced by IsVisible(), and TryExecuteCommand().

◆ IsVisible()

bool Acore::Impl::ChatCommands::ChatCommandNode::IsVisible ( ChatHandler const &  who) const
inlineprivate
202{ return (IsInvokerVisible(who) || HasVisibleSubCommands(who)); }
bool HasVisibleSubCommands(ChatHandler const &who) const
Definition: ChatCommand.cpp:524
bool IsInvokerVisible(ChatHandler const &who) const
Definition: ChatCommand.cpp:510

References HasVisibleSubCommands(), and IsInvokerVisible().

◆ LoadCommandMap()

void Acore::Impl::ChatCommands::ChatCommandNode::LoadCommandMap ( )
static
82{
84 LoadCommandsIntoMap(nullptr, COMMAND_MAP, sScriptMgr->GetChatCommands());
85
86 if (PreparedQueryResult result = WorldDatabase.Query(WorldDatabase.GetPreparedStatement(WORLD_SEL_COMMANDS)))
87 {
88 do
89 {
90 Field* fields = result->Fetch();
91 std::string_view const name = fields[0].Get<std::string_view>();
92 std::string_view const help = fields[2].Get<std::string_view>();
93 uint32 const secLevel = fields[1].Get<uint8>();
94
95 ChatCommandNode* cmd = nullptr;
97
98 for (std::string_view key : Acore::Tokenize(name, COMMAND_DELIMITER, false))
99 {
100 auto it = map->find(key);
101 if (it != map->end())
102 {
103 cmd = &it->second;
104 map = &cmd->_subCommands;
105 }
106 else
107 {
108 LOG_ERROR("sql.sql", "Table `command` contains data for non-existant command '{}'. Skipped.", name);
109 cmd = nullptr;
110 break;
111 }
112 }
113
114 if (!cmd)
115 continue;
116
117 if (cmd->_invoker && (cmd->_permission.RequiredLevel != secLevel))
118 {
119 LOG_WARN("sql.sql", "Table `command` has permission {} for '{}' which does not match the core ({}). Overriding.",
120 secLevel, name, cmd->_permission.RequiredLevel);
121
122 cmd->_permission.RequiredLevel = secLevel;
123 }
124
125 if (std::holds_alternative<std::string>(cmd->_help))
126 LOG_ERROR("sql.sql", "Table `command` contains duplicate data for command '{}'. Skipped.", name);
127
128 if (std::holds_alternative<std::monostate>(cmd->_help))
129 cmd->_help.emplace<std::string>(help);
130 else
131 LOG_ERROR("sql.sql", "Table `command` contains legacy help text for command '{}', which uses `trinity_string`. Skipped.", name);
132 } while (result->NextRow());
133 }
134
135 for (auto& [name, cmd] : COMMAND_MAP)
136 cmd.ResolveNames(std::string(name));
137}
std::uint8_t uint8
Definition: Define.h:110
std::uint32_t uint32
Definition: Define.h:108
#define LOG_ERROR(filterType__,...)
Definition: Log.h:159
#define LOG_WARN(filterType__,...)
Definition: Log.h:163
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
std::shared_ptr< PreparedResultSet > PreparedQueryResult
Definition: DatabaseEnvFwd.h:46
@ WORLD_SEL_COMMANDS
Definition: WorldDatabase.h:84
#define sScriptMgr
Definition: ScriptMgr.h:2702
std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition: Tokenize.cpp:20
Class used to access individual fields of database query result.
Definition: Field.h:99
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition: Field.h:113
static void InvalidateCommandMap()
Definition: ChatCommand.cpp:76
static void LoadCommandsIntoMap(ChatCommandNode *blank, std::map< std::string_view, Acore::Impl::ChatCommands::ChatCommandNode, StringCompareLessI_T > &map, Acore::ChatCommands::ChatCommandTable const &commands)
Definition: ChatCommand.cpp:46

References Acore::Impl::ChatCommands::COMMAND_DELIMITER, COMMAND_MAP, Field::Get(), LOG_ERROR, LOG_WARN, sScriptMgr, Acore::Tokenize(), WORLD_SEL_COMMANDS, and WorldDatabase.

Referenced by Acore::ChatCommands::LoadCommandMap().

◆ LoadCommandsIntoMap()

void Acore::Impl::ChatCommands::ChatCommandNode::LoadCommandsIntoMap ( ChatCommandNode blank,
std::map< std::string_view, Acore::Impl::ChatCommands::ChatCommandNode, StringCompareLessI_T > &  map,
Acore::ChatCommands::ChatCommandTable const &  commands 
)
staticprivate
48{
49 for (ChatCommandBuilder const& builder : commands)
50 {
51 if (builder._name.empty())
52 {
53 ASSERT(blank, "Empty name command at top level is not permitted.");
54 blank->LoadFromBuilder(builder);
55 }
56 else
57 {
58 std::vector<std::string_view> const tokens = Acore::Tokenize(builder._name, COMMAND_DELIMITER, false);
59 ASSERT(!tokens.empty(), "Invalid command name '{}'.", builder._name);
60 ChatSubCommandMap* subMap = &map;
61 for (size_t i = 0, n = (tokens.size() - 1); i < n; ++i)
62 subMap = &((*subMap)[tokens[i]]._subCommands);
63 ((*subMap)[tokens.back()]).LoadFromBuilder(builder);
64 }
65 }
66}
void LoadFromBuilder(ChatCommandBuilder const &builder)
Definition: ChatCommand.cpp:32
Acore::ChatCommands::ChatCommandBuilder ChatCommandBuilder
Definition: ChatCommand.h:181

References ASSERT, Acore::Impl::ChatCommands::COMMAND_DELIMITER, LoadFromBuilder(), and Acore::Tokenize().

Referenced by LoadFromBuilder().

◆ LoadFromBuilder()

void Acore::Impl::ChatCommands::ChatCommandNode::LoadFromBuilder ( ChatCommandBuilder const &  builder)
private
33{
34 if (std::holds_alternative<ChatCommandBuilder::InvokerEntry>(builder._data))
35 {
36 ASSERT(!_invoker, "Duplicate blank sub-command.");
37 AcoreStrings help;
38 std::tie(_invoker, help, _permission) = *(std::get<ChatCommandBuilder::InvokerEntry>(builder._data));
39 if (help)
40 _help.emplace<AcoreStrings>(help);
41 }
42 else
43 LoadCommandsIntoMap(this, _subCommands, std::get<ChatCommandBuilder::SubCommandEntry>(builder._data));
44}
AcoreStrings
Definition: Language.h:29

References Acore::ChatCommands::ChatCommandBuilder::_data, _help, _invoker, _permission, _subCommands, ASSERT, and LoadCommandsIntoMap().

Referenced by LoadCommandsIntoMap().

◆ ResolveNames()

void Acore::Impl::ChatCommands::ChatCommandNode::ResolveNames ( std::string  name)
private
140{
141 if (_invoker && std::holds_alternative<std::monostate>(_help))
142 LOG_WARN("sql.sql", "Table `command` is missing help text for command '{}'.", name);
143
144 _name = name;
145
146 for (auto& [subToken, cmd] : _subCommands)
147 {
148 std::string subName(name);
149 subName.push_back(COMMAND_DELIMITER);
150 subName.append(subToken);
151 cmd.ResolveNames(subName);
152 }
153}

References Acore::Impl::ChatCommands::COMMAND_DELIMITER, and LOG_WARN.

◆ SendCommandHelp()

void Acore::Impl::ChatCommands::ChatCommandNode::SendCommandHelp ( ChatHandler handler) const
private
191{
192 bool const hasInvoker = IsInvokerVisible(handler);
193 if (hasInvoker)
194 {
195 if (std::holds_alternative<AcoreStrings>(_help))
196 handler.SendSysMessage(std::get<AcoreStrings>(_help));
197 else if (std::holds_alternative<std::string>(_help))
198 handler.SendSysMessage(std::get<std::string>(_help));
199 else
200 {
203 }
204 }
205
206 bool header = false;
207
208 for (auto it = _subCommands.begin(); it != _subCommands.end(); ++it)
209 {
210 bool const subCommandHasSubCommand = it->second.HasVisibleSubCommands(handler);
211
212 if (!subCommandHasSubCommand && !it->second.IsInvokerVisible(handler))
213 {
214 continue;
215 }
216
217 if (!header)
218 {
219 if (!hasInvoker)
220 {
222 }
223
225 header = true;
226 }
227
228 handler.PSendSysMessage(subCommandHasSubCommand ? LANG_SUBCMDS_LIST_ENTRY_ELLIPSIS : LANG_SUBCMDS_LIST_ENTRY, STRING_VIEW_FMT_ARG(it->second._name));
229 }
230}
#define STRING_VIEW_FMT_ARG(str)
Definition: Define.h:101
@ LANG_CMD_NO_HELP_AVAILABLE
Definition: Language.h:230
@ LANG_SUBCMDS_LIST
Definition: Language.h:40
@ LANG_SUBCMDS_LIST_ENTRY
Definition: Language.h:225
@ LANG_CMD_HELP_GENERIC
Definition: Language.h:229
@ LANG_SUBCMDS_LIST_ENTRY_ELLIPSIS
Definition: Language.h:226
void PSendSysMessage(char const *fmt, Args &&... args)
Definition: Chat.h:60
virtual void SendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition: Chat.cpp:103

References LANG_CMD_HELP_GENERIC, LANG_CMD_NO_HELP_AVAILABLE, LANG_SUBCMDS_LIST, LANG_SUBCMDS_LIST_ENTRY, LANG_SUBCMDS_LIST_ENTRY_ELLIPSIS, ChatHandler::PSendSysMessage(), ChatHandler::SendSysMessage(), and STRING_VIEW_FMT_ARG.

Referenced by SendCommandHelpFor(), and TryExecuteCommand().

◆ SendCommandHelpFor()

void Acore::Impl::ChatCommands::ChatCommandNode::SendCommandHelpFor ( ChatHandler handler,
std::string_view  cmd 
)
static
356{
357 ChatCommandNode const* cmd = nullptr;
358 ChatSubCommandMap const* map = &GetTopLevelMap();
359
360 for (std::string_view token : Acore::Tokenize(cmdStr, COMMAND_DELIMITER, false))
361 {
362 FilteredCommandListIterator it1(*map, handler, token);
363 if (!it1)
364 { /* no matching subcommands found */
365 if (cmd)
366 {
367 cmd->SendCommandHelp(handler);
369 }
370 else
372 return;
373 }
374
375 if (!StringEqualI(it1->first, token))
376 { /* ok, so it1 points at a partially matching subcommand - let's see if there are others */
377 auto it2 = it1;
378 ++it2;
379
380 if (it2)
381 { /* there are multiple matching subcommands - print possibilities and return */
382 if (cmd)
384 else
386
387 handler.PSendSysMessage(it1->second.HasVisibleSubCommands(handler) ? LANG_SUBCMDS_LIST_ENTRY_ELLIPSIS : LANG_SUBCMDS_LIST_ENTRY, STRING_VIEW_FMT_ARG(it1->first));
388 do
389 {
390 handler.PSendSysMessage(it2->second.HasVisibleSubCommands(handler) ? LANG_SUBCMDS_LIST_ENTRY_ELLIPSIS : LANG_SUBCMDS_LIST_ENTRY, STRING_VIEW_FMT_ARG(it2->first));
391 } while (++it2);
392
393 return;
394 }
395 }
396
397 cmd = &it1->second;
398 map = &cmd->_subCommands;
399 }
400
401 if (cmd)
402 cmd->SendCommandHelp(handler);
403 else if (cmdStr.empty())
404 {
405 FilteredCommandListIterator it(*map, handler, "");
406 if (!it)
407 return;
409 do
410 {
411 handler.PSendSysMessage(it->second.HasVisibleSubCommands(handler) ? LANG_SUBCMDS_LIST_ENTRY_ELLIPSIS : LANG_SUBCMDS_LIST_ENTRY, STRING_VIEW_FMT_ARG(it->second._name));
412 } while (++it);
413 }
414 else
416}
@ LANG_SUBCMD_INVALID
Definition: Language.h:227
@ LANG_AVAILABLE_CMDS
Definition: Language.h:41
@ LANG_CMD_AMBIGUOUS
Definition: Language.h:228
@ LANG_CMD_INVALID
Definition: Language.h:38
@ LANG_SUBCMD_AMBIGUOUS
Definition: Language.h:39

References _name, _subCommands, Acore::Impl::ChatCommands::COMMAND_DELIMITER, LANG_AVAILABLE_CMDS, LANG_CMD_AMBIGUOUS, LANG_CMD_INVALID, LANG_SUBCMD_AMBIGUOUS, LANG_SUBCMD_INVALID, LANG_SUBCMDS_LIST_ENTRY, LANG_SUBCMDS_LIST_ENTRY_ELLIPSIS, ChatHandler::PSendSysMessage(), SendCommandHelp(), ChatHandler::SendSysMessage(), STRING_VIEW_FMT_ARG, StringEqualI(), and Acore::Tokenize().

Referenced by Acore::ChatCommands::SendCommandHelpFor().

◆ TryExecuteCommand()

bool Acore::Impl::ChatCommands::ChatCommandNode::TryExecuteCommand ( ChatHandler handler,
std::string_view  cmd 
)
static
275{
276 ChatCommandNode const* cmd = nullptr;
277 ChatSubCommandMap const* map = &GetTopLevelMap();
278
279 while (!cmdStr.empty() && (cmdStr.front() == COMMAND_DELIMITER))
280 cmdStr.remove_prefix(1);
281
282 while (!cmdStr.empty() && (cmdStr.back() == COMMAND_DELIMITER))
283 cmdStr.remove_suffix(1);
284
285 std::string_view oldTail = cmdStr;
286 while (!oldTail.empty())
287 {
288 /* oldTail = token DELIMITER newTail */
289 auto [token, newTail] = tokenize(oldTail);
290 ASSERT(!token.empty());
291
292 FilteredCommandListIterator it1(*map, handler, token);
293 if (!it1)
294 break; /* no matching subcommands found */
295
296 if (!StringEqualI(it1->first, token))
297 { /* ok, so it1 points at a partially matching subcommand - let's see if there are others */
298 auto it2 = it1;
299 ++it2;
300
301 if (it2)
302 { /* there are multiple matching subcommands - print possibilities and return */
303 if (cmd)
305 else
307
308 handler.PSendSysMessage(it1->second.HasVisibleSubCommands(handler) ? LANG_SUBCMDS_LIST_ENTRY_ELLIPSIS : LANG_SUBCMDS_LIST_ENTRY, STRING_VIEW_FMT_ARG(it1->first));
309 do
310 {
311 handler.PSendSysMessage(it2->second.HasVisibleSubCommands(handler) ? LANG_SUBCMDS_LIST_ENTRY_ELLIPSIS : LANG_SUBCMDS_LIST_ENTRY, STRING_VIEW_FMT_ARG(it2->first));
312 } while (++it2);
313
314 return true;
315 }
316 }
317
318 /* now we matched exactly one subcommand, and it1 points to it; go down the rabbit hole */
319 cmd = &it1->second;
320 map = &cmd->_subCommands;
321
322 oldTail = newTail;
323 }
324
325 if (cmd)
326 { /* if we matched a command at some point, invoke it */
327 handler.SetSentErrorMessage(false);
328 if (cmd->IsInvokerVisible(handler) && cmd->_invoker(&handler, oldTail))
329 { /* invocation succeeded, log this */
330 if (!handler.IsConsole())
331 LogCommandUsage(*handler.GetSession(), cmdStr);
332 }
333 else if (!handler.HasSentErrorMessage()) /* invocation failed, we should show usage */
334 {
335 if (!sScriptMgr->CanExecuteCommand(handler, cmdStr))
336 {
337 return true;
338 }
339
340 cmd->SendCommandHelp(handler);
341 handler.SetSentErrorMessage(true);
342 }
343
344 return true;
345 }
346
347 if (!sScriptMgr->CanExecuteCommand(handler, cmdStr))
348 {
349 return true;
350 }
351
352 return false;
353}
static void LogCommandUsage(WorldSession const &session, std::string_view cmdStr)
Definition: ChatCommand.cpp:155
WorldSession * GetSession()
Definition: Chat.h:122
bool HasSentErrorMessage() const
Definition: Chat.h:117
void SetSentErrorMessage(bool val)
Definition: Chat.h:118
bool IsConsole() const
Definition: Chat.h:120

References _invoker, _name, _subCommands, ASSERT, Acore::Impl::ChatCommands::COMMAND_DELIMITER, ChatHandler::GetSession(), ChatHandler::HasSentErrorMessage(), ChatHandler::IsConsole(), IsInvokerVisible(), LANG_CMD_AMBIGUOUS, LANG_SUBCMD_AMBIGUOUS, LANG_SUBCMDS_LIST_ENTRY, LANG_SUBCMDS_LIST_ENTRY_ELLIPSIS, LogCommandUsage(), ChatHandler::PSendSysMessage(), SendCommandHelp(), ChatHandler::SetSentErrorMessage(), sScriptMgr, STRING_VIEW_FMT_ARG, StringEqualI(), and Acore::Impl::ChatCommands::tokenize().

Referenced by Acore::ChatCommands::TryExecuteCommand().

Friends And Related Function Documentation

◆ FilteredCommandListIterator

friend struct FilteredCommandListIterator
friend

Member Data Documentation

◆ _help

std::variant<std::monostate, AcoreStrings, std::string> Acore::Impl::ChatCommands::ChatCommandNode::_help
private

Referenced by LoadFromBuilder().

◆ _invoker

CommandInvoker Acore::Impl::ChatCommands::ChatCommandNode::_invoker
private

◆ _name

std::string Acore::Impl::ChatCommands::ChatCommandNode::_name
private

◆ _permission

CommandPermissions Acore::Impl::ChatCommands::ChatCommandNode::_permission
private

Referenced by LoadFromBuilder().

◆ _subCommands

std::map<std::string_view, ChatCommandNode, StringCompareLessI_T> Acore::Impl::ChatCommands::ChatCommandNode::_subCommands
private