diff options
author | Treeston <treeston.mmoc@gmail.com> | 2020-09-21 02:37:18 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-21 02:37:18 +0200 |
commit | 26c510775c6a1995d81b16ad7459227381801dcc (patch) | |
tree | 049c60897f65b2ac005cfe03ef4f799d49db136d | |
parent | e11b466897752eb400428eafd05c7dbf08c562bf (diff) |
Core/ChatCommands: Add `trinity_string` support for chat command help
-rw-r--r-- | sql/updates/world/3.3.5/2020_09_21_00_world.sql | 6 | ||||
-rw-r--r-- | src/server/game/Chat/ChatCommands/ChatCommand.cpp | 23 | ||||
-rw-r--r-- | src/server/game/Chat/ChatCommands/ChatCommand.h | 36 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/Language.h | 3 | ||||
-rw-r--r-- | src/server/game/Scripting/ScriptMgr.cpp | 2 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_achievement.cpp | 2 |
6 files changed, 58 insertions, 14 deletions
diff --git a/sql/updates/world/3.3.5/2020_09_21_00_world.sql b/sql/updates/world/3.3.5/2020_09_21_00_world.sql new file mode 100644 index 00000000000..411524cc537 --- /dev/null +++ b/sql/updates/world/3.3.5/2020_09_21_00_world.sql @@ -0,0 +1,6 @@ +-- +DELETE FROM `command` WHERE `name` IN ('achievement','achievement add'); +DELETE FROM `trinity_string` WHERE `entry`=365; +INSERT INTO `trinity_string` (`entry`,`content_default`) VALUES +(365, '### USAGE: .achievement add <achievement> +Add an achievement, specified by ID or link, to the targeted player.'); diff --git a/src/server/game/Chat/ChatCommands/ChatCommand.cpp b/src/server/game/Chat/ChatCommands/ChatCommand.cpp index e4da5a04644..b37813ad528 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommand.cpp +++ b/src/server/game/Chat/ChatCommands/ChatCommand.cpp @@ -34,7 +34,10 @@ void Trinity::Impl::ChatCommands::ChatCommandNode::LoadFromBuilder(ChatCommandBu if (std::holds_alternative<ChatCommandBuilder::InvokerEntry>(builder._data)) { ASSERT(!_invoker, "Duplicate blank sub-command."); - std::tie(_invoker, _permission) = std::get<ChatCommandBuilder::InvokerEntry>(builder._data); + TrinityStrings help; + std::tie(_invoker, help, _permission) = *(std::get<ChatCommandBuilder::InvokerEntry>(builder._data)); + if (help) + _help.emplace<TrinityStrings>(help); } else LoadCommandsIntoMap(this, _subCommands, std::get<ChatCommandBuilder::SubCommandEntry>(builder._data)); @@ -103,7 +106,13 @@ static ChatSubCommandMap COMMAND_MAP; if (!cmd) continue; - cmd->_help.assign(help); + if (std::holds_alternative<std::string>(cmd->_help)) + TC_LOG_ERROR("sql.sql", "Table `command` contains duplicate data for command '" STRING_VIEW_FMT "'. Skipped.", STRING_VIEW_FMT_ARG(name)); + + if (std::holds_alternative<std::monostate>(cmd->_help)) + cmd->_help.emplace<std::string>(help); + else + TC_LOG_ERROR("sql.sql", "Table `command` contains legacy help text for command '" STRING_VIEW_FMT "', which uses `trinity_string`. Skipped.", STRING_VIEW_FMT_ARG(name)); } while (result->NextRow()); } @@ -113,7 +122,7 @@ static ChatSubCommandMap COMMAND_MAP; void Trinity::Impl::ChatCommands::ChatCommandNode::AssertCommandHelp(std::string_view name) const { - if (_invoker && _help.empty()) + if (_invoker && std::holds_alternative<std::monostate>(_help)) TC_LOG_WARN("sql.sql", "Table `command` is missing help text for (sub-)command '" STRING_VIEW_FMT "'.", STRING_VIEW_FMT_ARG(name)); for (auto const& [name, cmd] : _subCommands) @@ -154,7 +163,13 @@ static void LogCommandUsage(WorldSession const& session, uint32 permission, std: void Trinity::Impl::ChatCommands::ChatCommandNode::SendCommandHelp(ChatHandler& handler) const { if (IsInvokerVisible(handler)) - handler.SendSysMessage(_help); + { + if (std::holds_alternative<TrinityStrings>(_help)) + handler.SendSysMessage(std::get<TrinityStrings>(_help)); + else + handler.SendSysMessage(std::get<std::string>(_help)); + } + bool header = false; for (auto it = _subCommands.begin(); it != _subCommands.end(); ++it) { diff --git a/src/server/game/Chat/ChatCommands/ChatCommand.h b/src/server/game/Chat/ChatCommands/ChatCommand.h index e6fd93b9c11..c0dd194fa88 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommand.h +++ b/src/server/game/Chat/ChatCommands/ChatCommand.h @@ -23,6 +23,7 @@ #include "ChatCommandTags.h" #include "Define.h" #include "Errors.h" +#include "Language.h" #include "ObjectGuid.h" #include "Optional.h" #include "RBAC.h" @@ -202,7 +203,7 @@ namespace Trinity::Impl::ChatCommands CommandInvoker _invoker; CommandPermissions _permission; - std::string _help; + std::variant<std::monostate, TrinityStrings, std::string> _help; std::map<std::string_view, ChatCommandNode, StringCompareLessI_T> _subCommands; }; } @@ -212,32 +213,53 @@ namespace Trinity::ChatCommands struct ChatCommandBuilder { friend class Trinity::Impl::ChatCommands::ChatCommandNode; - using InvokerEntry = std::pair<Trinity::Impl::ChatCommands::CommandInvoker, Trinity::Impl::ChatCommands::CommandPermissions>; + struct InvokerEntry + { + template <typename T> + InvokerEntry(T& handler, TrinityStrings help, rbac::RBACPermissions permission, Trinity::ChatCommands::Console allowConsole) + : _invoker{ handler }, _help{ help }, _permissions{ permission, allowConsole } + {} + InvokerEntry(InvokerEntry const&) = default; + InvokerEntry(InvokerEntry&&) = default; + + Trinity::Impl::ChatCommands::CommandInvoker _invoker; + TrinityStrings _help; + Trinity::Impl::ChatCommands::CommandPermissions _permissions; + + auto operator*() const { return std::tie(_invoker, _help, _permissions); } + }; using SubCommandEntry = std::reference_wrapper<std::vector<ChatCommandBuilder> const>; + ChatCommandBuilder(ChatCommandBuilder&&) = default; + ChatCommandBuilder(ChatCommandBuilder const&) = default; + + template <typename TypedHandler> + ChatCommandBuilder(char const* name, TypedHandler& handler, TrinityStrings help, rbac::RBACPermissions permission, Trinity::ChatCommands::Console allowConsole) + : _name{ ASSERT_NOTNULL(name) }, _data{ std::in_place_type<InvokerEntry>, handler, help, permission, allowConsole } + {} + template <typename TypedHandler> ChatCommandBuilder(char const* name, TypedHandler& handler, rbac::RBACPermissions permission, Trinity::ChatCommands::Console allowConsole) - : _name{ ASSERT_NOTNULL(name) }, _data{ std::in_place_type<InvokerEntry>, std::piecewise_construct, std::forward_as_tuple(handler), std::forward_as_tuple(permission, allowConsole) } + : ChatCommandBuilder(name, handler, TrinityStrings(), permission, allowConsole) {} ChatCommandBuilder(char const* name, std::vector<ChatCommandBuilder> const& subCommands) : _name{ ASSERT_NOTNULL(name) }, _data{ std::in_place_type<SubCommandEntry>, subCommands } {} - ChatCommandBuilder(ChatCommandBuilder const&) = default; [[deprecated("char const* parameters to command handlers are deprecated; convert this to a typed argument handler instead")]] ChatCommandBuilder(char const* name, bool(&handler)(ChatHandler*, char const*), rbac::RBACPermissions permission, Trinity::ChatCommands::Console allowConsole) - : _name{ ASSERT_NOTNULL(name) }, _data{ std::in_place_type<InvokerEntry>, std::piecewise_construct, std::forward_as_tuple(handler), std::forward_as_tuple(permission, allowConsole) } + : ChatCommandBuilder(name, handler, TrinityStrings(), permission, allowConsole) {} template <typename TypedHandler> [[deprecated("you are using the old-style command format; convert this to the new format ({ name, handler (not a pointer!), permission, Console::(Yes/No) })")]] ChatCommandBuilder(char const* name, rbac::RBACPermissions permission, bool console, TypedHandler* handler, char const*) - : _name{ ASSERT_NOTNULL(name) }, _data{ std::in_place_type<InvokerEntry>, std::piecewise_construct, std::forward_as_tuple(*handler), std::forward_as_tuple(permission, static_cast<Trinity::ChatCommands::Console>(console)) } + : ChatCommandBuilder(name, *handler, TrinityStrings(), permission, static_cast<Trinity::ChatCommands::Console>(console)) {} [[deprecated("you are using the old-style command format; convert this to the new format ({ name, subCommands })")]] ChatCommandBuilder(char const* name, rbac::RBACPermissions, bool, std::nullptr_t, char const*, std::vector <ChatCommandBuilder> const& sub) - : _name{ ASSERT_NOTNULL(name) }, _data { std::in_place_type<SubCommandEntry>, sub } + : ChatCommandBuilder(name, sub) {} private: diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 2dda94ed002..f8ee146f5ba 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -408,7 +408,8 @@ enum TrinityStrings LANG_COMMAND_CHEAT_WW = 362, LANG_COMMAND_WHISPEROFFPLAYER = 363, LANG_COMMAND_CHEAT_TAXINODES = 364, - // Room for more level 2 365-399 not used + LANG_COMMAND_ACHIEVEMENT_ADD_HELP = 365, + // Room for more level 2 366-399 not used // level 3 chat LANG_SCRIPTS_RELOADED = 400, diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index 674c9c42ac0..8019735974d 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -1622,7 +1622,7 @@ Trinity::ChatCommands::ChatCommandTable ScriptMgr::GetChatCommands() { Trinity::ChatCommands::ChatCommandTable table; - FOR_SCRIPTS_RET(CommandScript, itr, end, table) + FOR_SCRIPTS(CommandScript, itr, end) { Trinity::ChatCommands::ChatCommandTable cmds = itr->second->GetCommands(); std::move(cmds.begin(), cmds.end(), std::back_inserter(table)); diff --git a/src/server/scripts/Commands/cs_achievement.cpp b/src/server/scripts/Commands/cs_achievement.cpp index 18a51845f8d..e4c57e8f6e1 100644 --- a/src/server/scripts/Commands/cs_achievement.cpp +++ b/src/server/scripts/Commands/cs_achievement.cpp @@ -40,7 +40,7 @@ public: { static ChatCommandTable commandTable = { - { "achievement add", HandleAchievementAddCommand, rbac::RBAC_PERM_COMMAND_ACHIEVEMENT_ADD, Console::No }, + { "achievement add", HandleAchievementAddCommand, LANG_COMMAND_ACHIEVEMENT_ADD_HELP ,rbac::RBAC_PERM_COMMAND_ACHIEVEMENT_ADD, Console::No }, }; return commandTable; } |