Core/ChatCommands: Add trinity_string support for chat command help

(cherry picked from commit 26c510775c)
This commit is contained in:
Treeston
2020-09-21 02:37:18 +02:00
committed by Shauren
parent 106c9b7541
commit 5e013a9996
6 changed files with 57 additions and 14 deletions

View File

@@ -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.');

View File

@@ -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)
{

View File

@@ -23,6 +23,7 @@
#include "ChatCommandTags.h"
#include "Define.h"
#include "Errors.h"
#include "Language.h"
#include "Optional.h"
#include "RBAC.h"
#include "StringFormat.h"
@@ -201,7 +202,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;
};
}
@@ -211,32 +212,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:

View File

@@ -418,7 +418,7 @@ enum TrinityStrings
LANG_COMMAND_CHEAT_WW = 362,
LANG_COMMAND_WHISPEROFFPLAYER = 363,
LANG_COMMAND_CHEAT_TAXINODES = 364,
LANG_COMMAND_ACHIEVEMENT_ADD_HELP = 365, // 3.3.5 RESERVED
LANG_COMMAND_ACHIEVEMENT_ADD_HELP = 365,
LANG_COMMAND_ACC_SET_ADDON_HELP = 366, // 3.3.5 RESERVED
LANG_COMMAND_ACC_SET_SEC_REGMAIL_HELP = 367, // 3.3.5 RESERVED
LANG_COMMAND_ACC_SET_SEC_EMAIL_HELP = 368, // 3.3.5 RESERVED

View File

@@ -1756,7 +1756,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));

View File

@@ -41,7 +41,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;
}