proper command parsing

This commit is contained in:
Lion Kortlepel 2022-02-15 16:06:59 +01:00
parent 8ff94a57d7
commit 548b2512cc
No known key found for this signature in database
GPG Key ID: 4322FF2B4C71259B
2 changed files with 74 additions and 41 deletions

View File

@ -26,13 +26,16 @@ private:
void ChangeToRegularConsole(); void ChangeToRegularConsole();
void HandleLuaInternalCommand(const std::string& cmd); void HandleLuaInternalCommand(const std::string& cmd);
void Command_Lua(const std::string& cmd); void Command_Lua(const std::string& cmd, const std::vector<std::string>& args);
void Command_Help(const std::string& cmd); void Command_Help(const std::string& cmd, const std::vector<std::string>& args);
void Command_Kick(const std::string& cmd); void Command_Kick(const std::string& cmd, const std::vector<std::string>& args);
void Command_Say(const std::string& cmd); void Command_List(const std::string& cmd, const std::vector<std::string>& args);
void Command_List(const std::string& cmd); void Command_Status(const std::string& cmd, const std::vector<std::string>& args);
void Command_Status(const std::string& cmd); void Command_Settings(const std::string& cmd, const std::vector<std::string>& args);
void Command_Settings(const std::string& cmd);
void Command_Say(const std::string& FullCommand);
bool ExpectArgsCount(const std::vector<std::string>& args, size_t n);
bool ExpectArgsCount(const std::vector<std::string>& args, size_t min, size_t max);
static std::tuple<std::string, std::vector<std::string>> ParseCommand(const std::string& cmd); static std::tuple<std::string, std::vector<std::string>> ParseCommand(const std::string& cmd);

View File

@ -133,21 +133,47 @@ void TConsole::ChangeToRegularConsole() {
} }
} }
void TConsole::Command_Lua(const std::string& cmd) { bool TConsole::ExpectArgsCount(const std::vector<std::string>& args, size_t n) {
if (cmd.size() > 3) { if (args.size() != n) {
auto NewStateId = cmd.substr(4); Application::Console().WriteRaw("Expected " + std::to_string(n) + " argument(s), instead got " + std::to_string(args.size()));
return false;
} else {
return true;
}
}
bool TConsole::ExpectArgsCount(const std::vector<std::string>& args, size_t min, size_t max) {
if (min == max) {
return ExpectArgsCount(args, min);
} else {
if (args.size() > max) {
Application::Console().WriteRaw("Too many arguments. At most " + std::to_string(max) + " arguments expected, got " + std::to_string(args.size()) + " instead.");
return false;
} else if (args.size() < min) {
Application::Console().WriteRaw("Too few arguments. At least " + std::to_string(max) + " arguments expected, got " + std::to_string(args.size()) + " instead.");
return false;
}
}
return true;
}
void TConsole::Command_Lua(const std::string& cmd, const std::vector<std::string>& args) {
if (!ExpectArgsCount(args, 0, 1)) {
}
if (args.size() == 1) {
auto NewStateId = args.at(0);
beammp_assert(!NewStateId.empty()); beammp_assert(!NewStateId.empty());
if (mLuaEngine->HasState(NewStateId)) { if (mLuaEngine->HasState(NewStateId)) {
ChangeToLuaConsole(NewStateId); ChangeToLuaConsole(NewStateId);
} else { } else {
Application::Console().WriteRaw("Lua state '" + NewStateId + "' is not a known state. Didn't switch to Lua."); Application::Console().WriteRaw("Lua state '" + NewStateId + "' is not a known state. Didn't switch to Lua.");
} }
} else { } else if (args.size() == 0) {
ChangeToLuaConsole(mDefaultStateId); ChangeToLuaConsole(mDefaultStateId);
} }
} }
void TConsole::Command_Help(const std::string&) { void TConsole::Command_Help(const std::string&, const std::vector<std::string>& args) {
static constexpr const char* sHelpString = R"( static constexpr const char* sHelpString = R"(
Commands: Commands:
help displays this help help displays this help
@ -161,7 +187,7 @@ void TConsole::Command_Help(const std::string&) {
Application::Console().WriteRaw("BeamMP-Server Console: " + std::string(sHelpString)); Application::Console().WriteRaw("BeamMP-Server Console: " + std::string(sHelpString));
} }
void TConsole::Command_Kick(const std::string& cmd) { void TConsole::Command_Kick(const std::string& cmd, const std::vector<std::string>& args) {
if (cmd.size() > 4) { if (cmd.size() > 4) {
auto Name = cmd.substr(5); auto Name = cmd.substr(5);
std::string Reason = "Kicked by server console"; std::string Reason = "Kicked by server console";
@ -201,7 +227,10 @@ std::tuple<std::string, std::vector<std::string>> TConsole::ParseCommand(const s
// It correctly splits arguments, including respecting single and double quotes, as well as backticks // It correctly splits arguments, including respecting single and double quotes, as well as backticks
auto End_i = CommandWithArgs.find_first_of(' '); auto End_i = CommandWithArgs.find_first_of(' ');
std::string Command = CommandWithArgs.substr(0, End_i); std::string Command = CommandWithArgs.substr(0, End_i);
std::string ArgsStr = CommandWithArgs.substr(End_i); std::string ArgsStr {};
if (End_i != std::string::npos) {
ArgsStr = CommandWithArgs.substr(End_i);
}
std::vector<std::string> Args; std::vector<std::string> Args;
char* PrevPtr = ArgsStr.data(); char* PrevPtr = ArgsStr.data();
char* Ptr = ArgsStr.data(); char* Ptr = ArgsStr.data();
@ -246,12 +275,12 @@ std::tuple<std::string, std::vector<std::string>> TConsole::ParseCommand(const s
return { Command, Args }; return { Command, Args };
} }
void TConsole::Command_Settings(const std::string& cmd) { void TConsole::Command_Settings(const std::string& cmd, const std::vector<std::string>& args) {
} }
void TConsole::Command_Say(const std::string& cmd) { void TConsole::Command_Say(const std::string& FullCmd) {
if (cmd.size() > 3) { if (FullCmd.size() > 3) {
auto Message = cmd.substr(4); auto Message = FullCmd.substr(4);
LuaAPI::MP::SendChatMessage(-1, Message); LuaAPI::MP::SendChatMessage(-1, Message);
if (!Application::Settings.LogChat) { if (!Application::Settings.LogChat) {
Application::Console().WriteRaw("Chat message sent!"); Application::Console().WriteRaw("Chat message sent!");
@ -259,7 +288,7 @@ void TConsole::Command_Say(const std::string& cmd) {
} }
} }
void TConsole::Command_List(const std::string&) { void TConsole::Command_List(const std::string&, const std::vector<std::string>& args) {
if (mLuaEngine->Server().ClientCount() == 0) { if (mLuaEngine->Server().ClientCount() == 0) {
Application::Console().WriteRaw("No players online."); Application::Console().WriteRaw("No players online.");
} else { } else {
@ -279,7 +308,7 @@ void TConsole::Command_List(const std::string&) {
} }
} }
void TConsole::Command_Status(const std::string&) { void TConsole::Command_Status(const std::string&, const std::vector<std::string>& args) {
std::stringstream Status; std::stringstream Status;
size_t CarCount = 0; size_t CarCount = 0;
@ -480,9 +509,10 @@ TConsole::TConsole() {
BackupOldLog(); BackupOldLog();
mCommandline.on_command = [this](Commandline& c) { mCommandline.on_command = [this](Commandline& c) {
try { try {
auto cmd = c.get_command(); auto TrimmedCmd = c.get_command();
cmd = TrimString(cmd); TrimmedCmd = TrimString(TrimmedCmd);
mCommandline.write(mCommandline.prompt() + cmd); auto [cmd, args] = ParseCommand(TrimmedCmd);
mCommandline.write(mCommandline.prompt() + TrimmedCmd);
if (mIsLuaConsole) { if (mIsLuaConsole) {
if (!mLuaEngine) { if (!mLuaEngine) {
beammp_info("Lua not started yet, please try again in a second"); beammp_info("Lua not started yet, please try again in a second");
@ -503,25 +533,25 @@ TConsole::TConsole() {
} else if (cmd == "exit") { } else if (cmd == "exit") {
beammp_info("gracefully shutting down"); beammp_info("gracefully shutting down");
Application::GracefullyShutdown(); Application::GracefullyShutdown();
} else if (StringStartsWith(cmd, "lua")) { } else if (cmd == "lua") {
Command_Lua(cmd); Command_Lua(cmd, args);
} else if (StringStartsWith(cmd, "help")) { } else if (cmd == "help") {
RunAsCommand(cmd, true); RunAsCommand(TrimmedCmd, true);
Command_Help(cmd); Command_Help(cmd, args);
} else if (StringStartsWith(cmd, "kick")) { } else if (cmd == "kick") {
RunAsCommand(cmd, true); RunAsCommand(TrimmedCmd, true);
Command_Kick(cmd); Command_Kick(cmd, args);
} else if (StringStartsWith(cmd, "say")) { } else if (cmd == "say") {
RunAsCommand(cmd, true); RunAsCommand(TrimmedCmd, true);
Command_Say(cmd); Command_Say(TrimmedCmd);
} else if (StringStartsWith(cmd, "list")) { } else if (cmd == "list") {
RunAsCommand(cmd, true); RunAsCommand(TrimmedCmd, true);
Command_List(cmd); Command_List(cmd, args);
} else if (StringStartsWith(cmd, "status")) { } else if (cmd == "status") {
RunAsCommand(cmd, true); RunAsCommand(TrimmedCmd, true);
Command_Status(cmd); Command_Status(cmd, args);
} else if (!cmd.empty()) { } else if (!cmd.empty()) {
RunAsCommand(cmd); RunAsCommand(TrimmedCmd);
} }
} }
} catch (const std::exception& e) { } catch (const std::exception& e) {