From 19d67dee95f9cb5344ad6752502541eae33dc04a Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Mon, 29 Nov 2021 01:14:37 +0100 Subject: [PATCH] Add GetPlayerIDByName, kick, say --- include/TConsole.h | 10 ++- include/TLuaEngine.h | 5 +- src/TConsole.cpp | 144 +++++++++++++++++++++++++++---------------- src/TLuaEngine.cpp | 22 ++++++- 4 files changed, 122 insertions(+), 59 deletions(-) diff --git a/include/TConsole.h b/include/TConsole.h index ab45eb0..110cfc9 100644 --- a/include/TConsole.h +++ b/include/TConsole.h @@ -16,11 +16,17 @@ public: void InitializeLuaConsole(TLuaEngine& Engine); void BackupOldLog(); Commandline& Internal() { return mCommandline; } - + private: + void RunAsCommand(const std::string& cmd, bool IgnoreNotACommand = false); void ChangeToLuaConsole(const std::string& LuaStateId); void ChangeToRegularConsole(); - + + void Command_Lua(const std::string& cmd); + void Command_Help(const std::string& cmd); + void Command_Kick(const std::string& cmd); + void Command_Say(const std::string& cmd); + Commandline mCommandline; std::vector mCachedLuaHistory; std::vector mCachedRegularHistory; diff --git a/include/TLuaEngine.h b/include/TLuaEngine.h index 87e0c0d..7e2cadf 100644 --- a/include/TLuaEngine.h +++ b/include/TLuaEngine.h @@ -83,7 +83,7 @@ public: void SetServer(TServer* Server) { mServer = Server; } static void WaitForAll(std::vector>& Results); - void ReportErrors(const std::vector >& Results); + void ReportErrors(const std::vector>& Results); bool HasState(TLuaStateId StateId); [[nodiscard]] std::shared_ptr EnqueueScript(TLuaStateId StateID, const TLuaChunk& Script); [[nodiscard]] std::shared_ptr EnqueueFunctionCall(TLuaStateId StateID, const std::string& FunctionName, const std::vector& Args); @@ -139,6 +139,7 @@ private: std::string Lua_GetPlayerName(int ID); sol::table Lua_GetPlayerVehicles(int ID); sol::table Lua_HttpCreateConnection(const std::string& host, uint16_t port); + int Lua_GetPlayerIDByName(const std::string& Name); std::string mName; std::atomic_bool& mShutdown; @@ -181,4 +182,4 @@ private: std::recursive_mutex mResultsToCheckMutex; }; -//std::any TriggerLuaEvent(const std::string& Event, bool local, TLuaPlugin* Caller, std::shared_ptr arg, bool Wait); +// std::any TriggerLuaEvent(const std::string& Event, bool local, TLuaPlugin* Caller, std::shared_ptr arg, bool Wait); diff --git a/src/TConsole.cpp b/src/TConsole.cpp index 10bd03d..3b91ea7 100644 --- a/src/TConsole.cpp +++ b/src/TConsole.cpp @@ -9,6 +9,10 @@ #include #include +static inline bool StringStartsWith(const std::string& What, const std::string& StartsWith) { + return What.size() >= StartsWith.size() && What.substr(0, StartsWith.size()) == StartsWith; +} + static inline std::string TrimString(std::string S) { S.erase(S.begin(), std::find_if(S.begin(), S.end(), [](unsigned char ch) { return !std::isspace(ch); @@ -122,6 +126,81 @@ void TConsole::ChangeToRegularConsole() { } } +void TConsole::Command_Lua(const std::string& cmd) { + if (cmd.size() > 3) { + auto NewStateId = cmd.substr(4); + beammp_assert(!NewStateId.empty()); + if (mLuaEngine->HasState(NewStateId)) { + ChangeToLuaConsole(NewStateId); + } else { + Application::Console().WriteRaw("Lua state '" + NewStateId + "' is not a known state. Didn't switch to Lua."); + } + } else { + ChangeToLuaConsole(mDefaultStateId); + } +} + +void TConsole::Command_Help(const std::string&) { + static constexpr const char* sHelpString = R"( + Commands: + help displays this help + exit shuts down the server + lua [state id] switches to lua, optionally into a specific state id's lua +)"; + Application::Console().WriteRaw("BeamMP-Server Console: " + std::string(sHelpString)); +} + +void TConsole::Command_Kick(const std::string& cmd) { + cmd.compare() +} + +void TConsole::Command_Say(const std::string& cmd) { +} + +void TConsole::RunAsCommand(const std::string& cmd, bool IgnoreNotACommand) { + auto FutureIsNonNil = + [](const std::shared_ptr& Future) { + if (!Future->Error) { + auto Type = Future->Result.get_type(); + return Type != sol::type::lua_nil && Type != sol::type::none; + } + return false; + }; + std::vector> NonNilFutures; + { // Futures scope + auto Futures = mLuaEngine->TriggerEvent("onConsoleInput", "", cmd); + TLuaEngine::WaitForAll(Futures); + size_t Count = 0; + for (auto& Future : Futures) { + if (!Future->Error) { + ++Count; + } + } + for (const auto& Future : Futures) { + if (FutureIsNonNil(Future)) { + NonNilFutures.push_back(Future); + } + } + } + if (NonNilFutures.size() == 0 && !IgnoreNotACommand) { + Application::Console().WriteRaw("Error: Unknown command: '" + cmd + "'"); + } else { + std::stringstream Reply; + if (NonNilFutures.size() > 1) { + for (size_t i = 0; i < NonNilFutures.size(); ++i) { + Reply << NonNilFutures[i]->StateId << ": \n" + << LuaAPI::LuaToString(NonNilFutures[i]->Result); + if (i < NonNilFutures.size() - 1) { + Reply << "\n"; + } + } + } else { + Reply << LuaAPI::LuaToString(NonNilFutures[0]->Result); + } + Application::Console().WriteRaw(Reply.str()); + } +} + TConsole::TConsole() { mCommandline.enable_history(); mCommandline.set_history_limit(20); @@ -155,60 +234,19 @@ TConsole::TConsole() { if (cmd == "exit") { beammp_info("gracefully shutting down"); Application::GracefullyShutdown(); - } else if (cmd.size() >= 3 && cmd.substr(0, 3) == "lua") { - if (cmd.size() > 3) { - auto NewStateId = cmd.substr(4); - beammp_assert(!NewStateId.empty()); - if (mLuaEngine->HasState(NewStateId)) { - ChangeToLuaConsole(NewStateId); - } else { - Application::Console().WriteRaw("Lua state '" + NewStateId + "' is not a known state. Didn't switch to Lua."); - } - } else { - ChangeToLuaConsole(mDefaultStateId); - } + } else if (StringStartsWith(cmd, "lua")) { + Command_Lua(cmd); + } else if (StringStartsWith(cmd, "help")) { + RunAsCommand(cmd, true); + Command_Help(cmd); + } else if (StringStartsWith(cmd, "kick")) { + RunAsCommand(cmd, true); + Command_Kick(cmd); + } else if (StringStartsWith(cmd, "say")) { + RunAsCommand(cmd, true); + Command_Say(cmd); } else if (!cmd.empty()) { - auto FutureIsNonNil = - [](const std::shared_ptr& Future) { - if (!Future->Error) { - auto Type = Future->Result.get_type(); - return Type != sol::type::lua_nil && Type != sol::type::none; - } - return false; - }; - std::vector> NonNilFutures; - { // Futures scope - auto Futures = mLuaEngine->TriggerEvent("onConsoleInput", "", cmd); - TLuaEngine::WaitForAll(Futures); - size_t Count = 0; - for (auto& Future : Futures) { - if (!Future->Error) { - ++Count; - } - } - for (const auto& Future : Futures) { - if (FutureIsNonNil(Future)) { - NonNilFutures.push_back(Future); - } - } - } - if (NonNilFutures.size() == 0) { - Application::Console().WriteRaw("Error: Unknown command: '" + cmd + "'"); - } else { - std::stringstream Reply; - if (NonNilFutures.size() > 1) { - for (size_t i = 0; i < NonNilFutures.size(); ++i) { - Reply << NonNilFutures[i]->StateId << ": \n" - << LuaAPI::LuaToString(NonNilFutures[i]->Result); - if (i < NonNilFutures.size() - 1) { - Reply << "\n"; - } - } - } else { - Reply << LuaAPI::LuaToString(NonNilFutures[0]->Result); - } - Application::Console().WriteRaw(Reply.str()); - } + RunAsCommand(cmd); } } } diff --git a/src/TLuaEngine.cpp b/src/TLuaEngine.cpp index 7c1a5d2..a835aae 100644 --- a/src/TLuaEngine.cpp +++ b/src/TLuaEngine.cpp @@ -184,7 +184,7 @@ void TLuaEngine::CollectAndInitPlugins() { if (!Dir.is_directory()) { beammp_error("\"" + Dir.path().string() + "\" is not a directory, skipping"); } else { - TLuaPluginConfig Config { Path.string() }; + TLuaPluginConfig Config { Path.stem().string() }; FindAndParseConfig(Path, Config); InitializePlugin(Path, Config); } @@ -213,7 +213,7 @@ void TLuaEngine::FindAndParseConfig(const fs::path& Folder, TLuaPluginConfig& Co beammp_debug("Plugin \"" + Folder.string() + "\" specified it wants LuaStateID \"" + ID + "\""); Config.StateId = ID; } else { - beammp_debug("LuaStateID empty, using randomized state ID"); + beammp_debug("LuaStateID empty, using plugin name"); } } } catch (const std::exception& e) { @@ -345,6 +345,21 @@ sol::table TLuaEngine::StateThreadData::Lua_GetPlayers() { return Result; } +int TLuaEngine::StateThreadData::Lua_GetPlayerIDByName(const std::string& Name) { + int Id = -1; + mEngine->mServer->ForEachClient([&Id, &Name](std::weak_ptr Client) -> bool { + if (!Client.expired()) { + auto locked = Client.lock(); + if (locked->GetName() == Name) { + Id = locked->GetID(); + return false; + } + } + return true; + }); + return Id; +} + std::string TLuaEngine::StateThreadData::Lua_GetPlayerName(int ID) { auto MaybeClient = GetClient(mEngine->Server(), ID); if (MaybeClient && !MaybeClient.value().expired()) { @@ -445,6 +460,9 @@ TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomi MPTable.set_function("TriggerClientEvent", &LuaAPI::MP::TriggerClientEvent); MPTable.set_function("GetPlayerCount", &LuaAPI::MP::GetPlayerCount); MPTable.set_function("IsPlayerConnected", &LuaAPI::MP::IsPlayerConnected); + MPTable.set_function("GetPlayerIDByName", [&](const std::string& Name) -> std::string { + return Lua_GetPlayerIDByName(Name); + }); MPTable.set_function("GetPlayerName", [&](int ID) -> std::string { return Lua_GetPlayerName(ID); });