mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-19 17:05:44 +01:00
Core/ChatCommands: Properly handle single-argument handlers (argument string discarded). Add special handling for on/off booleans.
This commit is contained in:
@@ -118,7 +118,7 @@ struct CommandArgsConsumerMulti
|
||||
static char const* TryConsumeTo(Tuple& tuple, char const* args)
|
||||
{
|
||||
if (char const* next = CommandArgsConsumerSingle<NextType>::TryConsumeTo(std::get<offset>(tuple), args))
|
||||
return CommandArgsConsumerNext<Tuple, offset>::GoNext(tuple, next);
|
||||
return CommandArgsConsumerNext<Tuple, offset+1>::GoNext(tuple, next);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
@@ -133,11 +133,11 @@ struct CommandArgsConsumerMulti<Tuple, Optional<NestedNextType>, offset>
|
||||
auto& myArg = std::get<offset>(tuple);
|
||||
myArg.emplace();
|
||||
if (char const* next = CommandArgsConsumerSingle<NestedNextType>::TryConsumeTo(*(myArg.get_ptr()), args))
|
||||
if ((next = CommandArgsConsumerNext<Tuple, offset>::GoNext(tuple, next)))
|
||||
if ((next = CommandArgsConsumerNext<Tuple, offset+1>::GoNext(tuple, next)))
|
||||
return next;
|
||||
// try again omitting the argument
|
||||
myArg = boost::none;
|
||||
if (char const* next = CommandArgsConsumerNext<Tuple, offset>::GoNext(tuple, args))
|
||||
if (char const* next = CommandArgsConsumerNext<Tuple, offset+1>::GoNext(tuple, args))
|
||||
return next;
|
||||
return nullptr;
|
||||
}
|
||||
@@ -148,13 +148,13 @@ struct CommandArgsConsumerNext<std::tuple<Ts...>, offset>
|
||||
{
|
||||
using tuple_type = std::tuple<Ts...>;
|
||||
|
||||
template <bool C = (offset + 1 < sizeof...(Ts))>
|
||||
template <bool C = (offset < sizeof...(Ts))>
|
||||
static std::enable_if_t<C, char const*> GoNext(tuple_type& tuple, char const* args)
|
||||
{
|
||||
return CommandArgsConsumerMulti<tuple_type, std::tuple_element_t<offset + 1, tuple_type>, offset + 1>::TryConsumeTo(tuple, args);
|
||||
return CommandArgsConsumerMulti<tuple_type, std::tuple_element_t<offset, tuple_type>, offset>::TryConsumeTo(tuple, args);
|
||||
}
|
||||
|
||||
template <bool C = (offset + 1 < sizeof...(Ts))>
|
||||
template <bool C = (offset < sizeof...(Ts))>
|
||||
static std::enable_if_t<!C, char const*> GoNext(tuple_type&, char const* args)
|
||||
{
|
||||
return args;
|
||||
@@ -192,7 +192,7 @@ class TC_GAME_API CommandArgs
|
||||
template <size_t offset = 0, typename T>
|
||||
bool TryConsumeToTuple(T& tuple)
|
||||
{
|
||||
if (char const* next = CommandArgsConsumerMulti<T, std::tuple_element_t<offset, T>, offset>::TryConsumeTo(tuple, _args))
|
||||
if (char const* next = CommandArgsConsumerNext<T, offset>::GoNext(tuple, _args))
|
||||
{
|
||||
_args = next;
|
||||
return true;
|
||||
|
||||
@@ -35,3 +35,18 @@ char const* Trinity::ChatCommands::ArgInfo<GameTele const*>::TryConsume(GameTele
|
||||
data = boost::apply_visitor(GameTeleVisitor(), val);
|
||||
return args;
|
||||
}
|
||||
|
||||
struct BoolVisitor
|
||||
{
|
||||
using value_type = bool;
|
||||
value_type operator()(uint32 i) const { return !!i; }
|
||||
value_type operator()(ExactSequence<'o', 'n'>) const { return true; }
|
||||
value_type operator()(ExactSequence<'o', 'f', 'f'>) const { return false; }
|
||||
};
|
||||
char const* Trinity::ChatCommands::ArgInfo<bool>::TryConsume(bool& data, char const* args)
|
||||
{
|
||||
Variant<uint32, ExactSequence<'o', 'n'>, ExactSequence<'o', 'f', 'f'>> val;
|
||||
if ((args = CommandArgsConsumerSingle<decltype(val)>::TryConsumeTo(val, args)))
|
||||
data = boost::apply_visitor(BoolVisitor(), val);
|
||||
return args;
|
||||
}
|
||||
|
||||
@@ -115,6 +115,13 @@ struct TC_GAME_API ArgInfo<GameTele const*>
|
||||
static char const* TryConsume(GameTele const*&, char const*);
|
||||
};
|
||||
|
||||
// bool from 1/0 or on/off
|
||||
template <>
|
||||
struct TC_GAME_API ArgInfo<bool>
|
||||
{
|
||||
static char const* TryConsume(bool&, char const*);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user