From fc3f2483eed1a69349d1ba7f5c9b437d66816533 Mon Sep 17 00:00:00 2001 From: Koncord Date: Thu, 19 Oct 2017 10:24:17 +0800 Subject: [PATCH] [Server] Add manual Server Plugins sort --- apps/openmw-mp/Networking.cpp | 1 - apps/openmw-mp/Script/LuaState.cpp | 89 +++++++++++++++++--------- apps/openmw-mp/Script/LuaState.hpp | 3 +- apps/openmw-mp/Utils.cpp | 8 +-- apps/openmw-mp/main.cpp | 20 ++++++ files/tes3mp/tes3mp-server-default.cfg | 11 ++-- 6 files changed, 92 insertions(+), 40 deletions(-) diff --git a/apps/openmw-mp/Networking.cpp b/apps/openmw-mp/Networking.cpp index cbf062763..e99363224 100644 --- a/apps/openmw-mp/Networking.cpp +++ b/apps/openmw-mp/Networking.cpp @@ -54,7 +54,6 @@ Networking::Networking(RakNet::RakPeerInterface *peer) : mclient(nullptr) running = true; exitCode = 0; - luaState.loadMods(); serverPassword = TES3MP_DEFAULT_PASSW; diff --git a/apps/openmw-mp/Script/LuaState.cpp b/apps/openmw-mp/Script/LuaState.cpp index e20c5de2d..4d3835884 100644 --- a/apps/openmw-mp/Script/LuaState.cpp +++ b/apps/openmw-mp/Script/LuaState.cpp @@ -334,41 +334,51 @@ int CompVersion(const string &wishVersion, const string &depVersionFound) return 0; } -vector::iterator> loadOrderSolver(vector &mods) +void checkDependencies(const vector &mods, const ServerPluginInfo &spi, bool fatal = true) { - vector::iterator> notResolved; - vector::iterator> result; - - for (auto it = mods.begin(); it != mods.end(); ++it) + for (auto &dependency : spi.dependencies) { - for (auto &dependency : it->dependencies) - { - const std::string &depNameRequest = dependency.first; - const std::string &depVersionRequest = dependency.second; + const std::string &depNameRequest = dependency.first; + const std::string &depVersionRequest = dependency.second; - const auto &depEnvIt = find_if(mods.begin(), mods.end(), [&depNameRequest](const auto &val) { - return val.name == depNameRequest; - }); + const auto &depEnvIt = find_if(mods.begin(), mods.end(), [&depNameRequest](const auto &val) { + return val.name == depNameRequest; + }); - if (depEnvIt != mods.end()) + if (depEnvIt != mods.end()) + { + const string &depVersionFound = depEnvIt->version; + if (CompVersion(depVersionRequest, depVersionFound) != 0) { - const string &depVersionFound = depEnvIt->version; - if (CompVersion(depVersionRequest, depVersionFound) != 0) - { - stringstream sstr; - sstr << depNameRequest << ": version \"" << depVersionFound - << "\" is not applicable for \"" << it->name << "\" expected \"" - << depVersionRequest + "\""; + stringstream sstr; + sstr << depNameRequest << ": version \"" << depVersionFound << "\" is not applicable for \"" + << spi.name << "\" expected \"" << depVersionRequest + "\""; + if(fatal) throw runtime_error(sstr.str()); - } + else + LOG_MESSAGE_SIMPLE(Log::LOG_WARN, "%s", sstr.str().c_str()); } - else // dependency not found. - { - stringstream sstr; - sstr << depNameRequest + " \"" << depVersionRequest << "\" not found."; + } + else // dependency not found. + { + stringstream sstr; + sstr << depNameRequest + " \"" << depVersionRequest << "\" not found."; + if(fatal) throw runtime_error(sstr.str()); - } + else + LOG_MESSAGE_SIMPLE(Log::LOG_WARN, "%s", sstr.str().c_str()); } + } +} + +vector::iterator> loadOrderSolver(vector &mods) +{ + vector::iterator> notResolved; + vector::iterator> result; + + for (auto it = mods.begin(); it != mods.end(); ++it) + { + checkDependencies(mods, *it); if (it->dependencies.empty()) // if server plugin doesn't have any dependencies we can safely put it on result result.push_back(it); @@ -428,7 +438,7 @@ vector::iterator> loadOrderSolver(vector *list) { using namespace boost::filesystem; @@ -490,7 +500,28 @@ void LuaState::loadMods() } - auto sortedPluginList = loadOrderSolver(mods); + vector::iterator> sortedPluginList; + if(list != nullptr && !list->empty()) // manual sorted list + { + for(const auto &mssp : *list) + { + bool found = false; + for (auto it = mods.begin(); it != mods.end(); ++it) + { + if(it->name == mssp) + { + checkDependencies(mods, *it, false); // check dependencies, but do not throw exceptions + sortedPluginList.push_back(it); + found = true; + break; + } + } + if(!found) + throw runtime_error("Plugin: \"" + mssp + "\" not found"); + } + } + else + sortedPluginList = loadOrderSolver(mods); for(auto &&mod : sortedPluginList) { @@ -502,4 +533,4 @@ void LuaState::loadMods() } dataEnv["Core"]["LOADED_MODS"] = mods.size(); -} +} \ No newline at end of file diff --git a/apps/openmw-mp/Script/LuaState.hpp b/apps/openmw-mp/Script/LuaState.hpp index 7c5499716..94b6dbe85 100644 --- a/apps/openmw-mp/Script/LuaState.hpp +++ b/apps/openmw-mp/Script/LuaState.hpp @@ -36,7 +36,7 @@ public: void addGlobalCPath(const std::string &path); sol::table getCoreTable() { return dataEnv["Core"]; } sol::environment &getDataEnv(){ return dataEnv; } - void loadMods(); + void loadMods(std::vector *list = nullptr); CommandController &getCmdCtrl(); EventController &getEventCtrl(); @@ -58,5 +58,4 @@ private: std::unique_ptr objectCtrl; std::vector mods; - }; diff --git a/apps/openmw-mp/Utils.cpp b/apps/openmw-mp/Utils.cpp index d5d621e49..47784dfe1 100644 --- a/apps/openmw-mp/Utils.cpp +++ b/apps/openmw-mp/Utils.cpp @@ -11,7 +11,7 @@ const vector Utils::split(const string &str, int delimiter) string buffer; vector result; - for (auto symb:str) + for (const auto &symb : str) if (symb != delimiter) buffer += symb; else if (!buffer.empty()) @@ -30,10 +30,10 @@ ESM::Cell Utils::getCellFromDescription(std::string cellDescription) ESM::Cell cell; cell.blank(); - static std::regex exteriorCellPattern("^(-?\\d+), (-?\\d+)$"); - std::smatch baseMatch; + static regex exteriorCellPattern("^(-?\\d+), (-?\\d+)$"); + smatch baseMatch; - if (std::regex_match(cellDescription, baseMatch, exteriorCellPattern)) + if (regex_match(cellDescription, baseMatch, exteriorCellPattern)) { cell.mData.mFlags &= ~ESM::Cell::Interior; diff --git a/apps/openmw-mp/main.cpp b/apps/openmw-mp/main.cpp index 4e0ca3504..3324b828f 100644 --- a/apps/openmw-mp/main.cpp +++ b/apps/openmw-mp/main.cpp @@ -245,6 +245,26 @@ int main(int argc, char *argv[]) peer->SetMaximumIncomingConnections((unsigned short) (players)); Networking networking(peer); + + + + if(mgr.getBool("autoSort", "Plugins")) + networking.getState().loadMods(); + else + { + std::vector list; + + try + { + for (int i = 0;; ++i) + list.push_back(mgr.getString("Plugin" + to_string(i), "Plugins")); + } + catch(...) {} // Manager::getString throws runtime_error exception if setting is not exist + + networking.getState().loadMods(&list); + } + + networking.setServerPassword(passw); if (mgr.getBool("enabled", "MasterServer")) diff --git a/files/tes3mp/tes3mp-server-default.cfg b/files/tes3mp/tes3mp-server-default.cfg index b958bf893..854649731 100644 --- a/files/tes3mp/tes3mp-server-default.cfg +++ b/files/tes3mp/tes3mp-server-default.cfg @@ -7,12 +7,15 @@ hostname = My TES3MP server logLevel = 1 password = -[Plugins] -home = ~/local/openmw/tes3mp -plugins = server.lua - [MasterServer] enabled = true address = master.tes3mp.com port = 25560 rate = 1000 + +[Plugins] +home = ~/local/openmw/tes3mp +autoSort = true +# If autoSort is disabled, then use "Plugin[n] = [plugin-name]" for manual ordering +# Plugin0 = Core +# Plugin1 = Coop \ No newline at end of file