Scripts/ChatCommands: Constrain how char const* may be used as a command handler parameter. It may now only be used in the legacy configuration, as the only argument.

(cherry picked from commit 9fda67d016)
This commit is contained in:
Treeston
2020-09-20 15:01:46 +02:00
committed by Shauren
parent 46d4e2fa83
commit c13d7df72b
3 changed files with 21 additions and 21 deletions

View File

@@ -141,6 +141,14 @@ namespace Trinity::Impl::ChatCommands
};
_handler = reinterpret_cast<void*>(handler);
}
CommandInvoker(bool(&handler)(ChatHandler*, char const*))
{
_wrapper = [](void* handler, ChatHandler* chatHandler, std::string_view argsStr)
{
return reinterpret_cast<bool(*)(ChatHandler*, char const*)>(handler)(chatHandler, argsStr.empty() ? "" : argsStr.data());
};
_handler = reinterpret_cast<void*>(handler);
}
explicit operator bool() const { return (_wrapper != nullptr); }
bool operator()(ChatHandler* chatHandler, std::string_view args) const
@@ -215,17 +223,19 @@ namespace Trinity::ChatCommands
{}
ChatCommandBuilder(ChatCommandBuilder const&) = default;
/* deprecated: char const* parameters to command handlers */
[[deprecated]] ChatCommandBuilder(char const* name, bool(&handler)(ChatHandler*, char const*), rbac::RBACPermissions permission, Trinity::ChatCommands::Console allowConsole)
[[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) }
{}
/* deprecated: old-style command table format */
template <typename TypedHandler>
[[deprecated]] ChatCommandBuilder(char const* name, rbac::RBACPermissions permission, bool console, TypedHandler* handler, char const*)
[[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)) }
{}
[[deprecated]] ChatCommandBuilder(char const* name, rbac::RBACPermissions, bool, std::nullptr_t, char const*, std::vector <ChatCommandBuilder> const& sub)
[[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 }
{}
@@ -242,6 +252,6 @@ namespace Trinity::ChatCommands
}
// backwards compatibility with old patches
using ChatCommand [[deprecated]] = Trinity::ChatCommands::ChatCommandBuilder;
using ChatCommand [[deprecated("std::vector<ChatCommand> should be ChatCommandTable! (using namespace Trinity::ChatCommands)")]] = Trinity::ChatCommands::ChatCommandBuilder;
#endif

View File

@@ -74,16 +74,6 @@ namespace Trinity::Impl::ChatCommands
}
};
/*
for backwards compatibility, consumes the rest of the string
new code should use the Tail/WTail tags defined in ChatCommandTags
*/
template <>
struct ArgInfo<char const*, void>
{
static ChatCommandResult TryConsume(char const*& arg, ChatHandler const*, std::string_view args) { arg = (args.empty() ? "" : args.data()); return std::string_view(); }
};
// string_view
template <>
struct ArgInfo<std::string_view, void>

View File

@@ -111,11 +111,11 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPackets::Quest::QuestG
else
object = ObjectAccessor::FindPlayer(packet.QuestGiverGUID);
#define CLOSE_GOSSIP_CLEAR_SHARING_INFO() \
do { \
_player->PlayerTalkClass->SendCloseGossip(); \
_player->ClearQuestSharingInfo(); \
} while (0)
auto CLOSE_GOSSIP_CLEAR_SHARING_INFO = ([this]()
{
_player->PlayerTalkClass->SendCloseGossip();
_player->ClearQuestSharingInfo();
});
// no or incorrect quest giver
if (!object)