15 return {.
Key =
"target.immune", .Vars = {{
"token",
token}}};
18 return {.Key =
"target.ambiguous", .Vars = {{
"token",
token}, {
"count", std::to_string(
failure.Count)}}};
20 return {.Key =
"target.dead", .Vars = {{
"token",
token}}};
22 return {.Key =
"target.bot", .Vars = {{
"token",
token}}};
25 return {.Key =
"target.noMatch", .Vars = {{
"token",
token}}};
83 return std::unexpected(
ArgError{.
Key =
"cmd.badDuration", .Vars = {{
"token",
token}}});
96 return std::unexpected(
ArgError{.
Key =
"cmd.badSteamId", .Vars = {{
"token",
token}}});
101static std::expected<Args::Int, ArgError>
BindInt(
const std::string&
token)
104 if (!value || !std::in_range<int>(*value))
106 return std::unexpected(
ArgError{.
Key =
"cmd.badNumber", .Vars = {{
"token",
token}}});
111static std::expected<Args::U64, ArgError>
BindU64(
const std::string&
token)
116 return std::unexpected(
ArgError{.
Key =
"cmd.badNumber", .Vars = {{
"token",
token}}});
123static std::optional<ArgError>
Store(std::expected<T, ArgError>
parsed, std::vector<BoundArg>&
bound)
127 return std::move(
parsed.error());
139 std::vector<BoundArg>
bound;
148 bound.emplace_back(std::monostate{});
153 std::optional<ArgError>
failed;
184 std::vector<std::string>
rest(
tokens.begin() +
static_cast<std::ptrdiff_t
>(
i),
tokens.end());
193 return std::unexpected(std::move(*
failed));
The one thing command dispatch needs a running server for.
One connected player, owned by PlayerManager for the length of the connection.
int64_t SteamId() const noexcept
Static utilities for converting between SteamID formats (64-bit, SteamID2, SteamID3).
static std::string Join(const std::vector< std::string > &parts, std::string_view delimiter)
static bool IsNumeric(std::string_view str)
static std::expected< Args::Int, ArgError > BindInt(const std::string &token)
static std::expected< Args::Target, ArgError > BindTarget(ArgBinder &binder, const std::string &token, Player *caller)
static std::expected< Args::Duration, ArgError > BindDuration(const std::string &token)
static std::expected< Args::SteamId, ArgError > BindSteamId(const std::string &token)
std::optional< int64_t > ParseInt64(std::string_view text)
int ParseDuration(std::string_view text)
std::expected< std::vector< BoundArg >, ArgError > BindArgs(const CommandDefinition &def, std::span< const std::string > tokens, Player *caller, ArgBinder &binder)
static std::optional< ArgError > Store(std::expected< T, ArgError > parsed, std::vector< BoundArg > &bound)
static std::string ReadFile(const std::filesystem::path &path)
static std::expected< Args::PlayerOrSteamId, ArgError > BindPlayerOrSteamId(ArgBinder &binder, const std::string &token, Player *caller)
static std::expected< Args::Targets, ArgError > BindTargets(ArgBinder &binder, const std::string &token, Player *caller)
std::optional< uint64_t > ParseUInt64(std::string_view text)
@ Ambiguous
a name fragment matched more than one player
@ MultiNotAllowed
a multi-selector was used where the command takes a single target
@ Immune
matches existed, but the policy blocked all of them
ArgKind
Which binder runs for one declared argument.
static ArgError TargetKey(const TargetFailure &failure, const std::string &token)
static std::expected< Args::U64, ArgError > BindU64(const std::string &token)
A binding failure, as the key and tokens the reply is built from.
std::chrono::seconds Value
std::vector< Player * > Value
One command as the builder assembled it.
bool AllowMultiple
permit selectors (@all/@t/...) that match more than one player