#include "player_command.hpp" #include "fiber_pool.hpp" namespace big { player_all_component::player_all_component(player_command* parent, const std::string& name, const std::string& label, const std::string& description, std::optional num_args) : command(name + "all", label, description, num_args), m_parent(parent) { } void player_all_component::execute(const command_arguments& args, const std::shared_ptr ctx) { g_fiber_pool->queue_job([this, args, &ctx] { g_player_service->iterate([this, args, &ctx](const player_entry& player) { m_parent->execute(player.second, args, ctx); }); }); } std::optional player_all_component::parse_args(const std::vector& args, const std::shared_ptr ctx) { return m_parent->parse_args_p(args, ctx); } player_command::player_command(const std::string& name, const std::string& label, const std::string& description, std::optional num_args, bool make_all_version) : command(name, label, description, num_args.has_value() ? std::optional{num_args.value() + 1} : std::nullopt) { if (make_all_version) m_all_component = std::make_unique(this, name, label, description, num_args); } void player_command::execute(const command_arguments& args, const std::shared_ptr ctx) { g_fiber_pool->queue_job([this, args, ctx] { command_arguments new_args(m_num_args.value(), args); if (g_player_service->get_self()->id() == args.get(0)) { execute(g_player_service->get_self(), new_args, ctx); return; } for (auto& plyr : g_player_service->players()) { if (plyr.second->id() == args.get(0)) { execute(plyr.second, new_args, ctx); return; } } ctx->report_error(std::format("Tried to execute command {}, but a player with index {} was not found", m_name, args.get(0))); }); } std::optional player_command::parse_args(const std::vector& args, const std::shared_ptr ctx) { std::vector new_args; command_arguments result(m_num_args.value()); if (args[0] == "me" || args[0] == "self") { result.push(ctx->get_sender()->id()); } else { int plyr_id = -1; for (auto& plyr : g_player_service->players()) { if (stricmp(plyr.second->get_name(), args[0].c_str()) == 0) { plyr_id = plyr.second->id(); break; } } if (ctx->get_access_level() != CommandAccessLevel::ADMIN && (get_access_level() == CommandAccessLevel::TOXIC || get_access_level() == CommandAccessLevel::AGGRESSIVE) && plyr_id == self::id) { ctx->report_error("Permission denied, cannot call toxic commands on me"); return std::nullopt; } if (plyr_id == -1) { ctx->report_error(std::format("Cannot find player with name {} in command {}", args[0], m_name)); return std::nullopt; } result.push(plyr_id); } std::copy(++args.begin(), args.end(), new_args.begin()); // for (int i = 1; i < args.size(); i++) // new_args.push_back(args[i]); auto res = parse_args_p(new_args, ctx); // no value indicates a failure if (!res.has_value()) return std::nullopt; const auto alt_args = res.value(); for (auto i = 0u; i < alt_args.size(); ++i) result.push(alt_args.get(i)); return result; } void player_command::call(player_ptr player, const command_arguments& args, const std::shared_ptr ctx) { // TODO: Code duplication if (m_num_args.has_value() && args.size() != (m_num_args.value() - 1)) { ctx->report_error(std::format("Command {} called with the wrong number of arguments. Expected {}, got {}", m_name, m_num_args.value(), args.size())); return; } g_fiber_pool->queue_job([this, player, args, ctx] { if (player->is_valid()) execute(player, args, ctx); }); } }