[Server] Add manual Server Plugins sort

new-script-api
Koncord 7 years ago
parent dffd3bfa7d
commit fc3f2483ee

@ -54,7 +54,6 @@ Networking::Networking(RakNet::RakPeerInterface *peer) : mclient(nullptr)
running = true; running = true;
exitCode = 0; exitCode = 0;
luaState.loadMods();
serverPassword = TES3MP_DEFAULT_PASSW; serverPassword = TES3MP_DEFAULT_PASSW;

@ -334,41 +334,51 @@ int CompVersion(const string &wishVersion, const string &depVersionFound)
return 0; return 0;
} }
vector<vector<ServerPluginInfo>::iterator> loadOrderSolver(vector<ServerPluginInfo> &mods) void checkDependencies(const vector<ServerPluginInfo> &mods, const ServerPluginInfo &spi, bool fatal = true)
{ {
vector<vector<ServerPluginInfo>::iterator> notResolved; for (auto &dependency : spi.dependencies)
vector<vector<ServerPluginInfo>::iterator> result;
for (auto it = mods.begin(); it != mods.end(); ++it)
{ {
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) { const auto &depEnvIt = find_if(mods.begin(), mods.end(), [&depNameRequest](const auto &val) {
return val.name == depNameRequest; 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; stringstream sstr;
if (CompVersion(depVersionRequest, depVersionFound) != 0) sstr << depNameRequest << ": version \"" << depVersionFound << "\" is not applicable for \""
{ << spi.name << "\" expected \"" << depVersionRequest + "\"";
stringstream sstr; if(fatal)
sstr << depNameRequest << ": version \"" << depVersionFound
<< "\" is not applicable for \"" << it->name << "\" expected \""
<< depVersionRequest + "\"";
throw runtime_error(sstr.str()); throw runtime_error(sstr.str());
} else
LOG_MESSAGE_SIMPLE(Log::LOG_WARN, "%s", sstr.str().c_str());
} }
else // dependency not found. }
{ else // dependency not found.
stringstream sstr; {
sstr << depNameRequest + " \"" << depVersionRequest << "\" not found."; stringstream sstr;
sstr << depNameRequest + " \"" << depVersionRequest << "\" not found.";
if(fatal)
throw runtime_error(sstr.str()); throw runtime_error(sstr.str());
} else
LOG_MESSAGE_SIMPLE(Log::LOG_WARN, "%s", sstr.str().c_str());
} }
}
}
vector<vector<ServerPluginInfo>::iterator> loadOrderSolver(vector<ServerPluginInfo> &mods)
{
vector<vector<ServerPluginInfo>::iterator> notResolved;
vector<vector<ServerPluginInfo>::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 if (it->dependencies.empty()) // if server plugin doesn't have any dependencies we can safely put it on result
result.push_back(it); result.push_back(it);
@ -428,7 +438,7 @@ vector<vector<ServerPluginInfo>::iterator> loadOrderSolver(vector<ServerPluginIn
return move(result); return move(result);
} }
void LuaState::loadMods() void LuaState::loadMods(std::vector<std::string> *list)
{ {
using namespace boost::filesystem; using namespace boost::filesystem;
@ -490,7 +500,28 @@ void LuaState::loadMods()
} }
auto sortedPluginList = loadOrderSolver(mods); vector<vector<ServerPluginInfo>::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) for(auto &&mod : sortedPluginList)
{ {
@ -502,4 +533,4 @@ void LuaState::loadMods()
} }
dataEnv["Core"]["LOADED_MODS"] = mods.size(); dataEnv["Core"]["LOADED_MODS"] = mods.size();
} }

@ -36,7 +36,7 @@ public:
void addGlobalCPath(const std::string &path); void addGlobalCPath(const std::string &path);
sol::table getCoreTable() { return dataEnv["Core"]; } sol::table getCoreTable() { return dataEnv["Core"]; }
sol::environment &getDataEnv(){ return dataEnv; } sol::environment &getDataEnv(){ return dataEnv; }
void loadMods(); void loadMods(std::vector<std::string> *list = nullptr);
CommandController &getCmdCtrl(); CommandController &getCmdCtrl();
EventController &getEventCtrl(); EventController &getEventCtrl();
@ -58,5 +58,4 @@ private:
std::unique_ptr<ObjectController> objectCtrl; std::unique_ptr<ObjectController> objectCtrl;
std::vector<ServerPluginInfo> mods; std::vector<ServerPluginInfo> mods;
}; };

@ -11,7 +11,7 @@ const vector<string> Utils::split(const string &str, int delimiter)
string buffer; string buffer;
vector<string> result; vector<string> result;
for (auto symb:str) for (const auto &symb : str)
if (symb != delimiter) if (symb != delimiter)
buffer += symb; buffer += symb;
else if (!buffer.empty()) else if (!buffer.empty())
@ -30,10 +30,10 @@ ESM::Cell Utils::getCellFromDescription(std::string cellDescription)
ESM::Cell cell; ESM::Cell cell;
cell.blank(); cell.blank();
static std::regex exteriorCellPattern("^(-?\\d+), (-?\\d+)$"); static regex exteriorCellPattern("^(-?\\d+), (-?\\d+)$");
std::smatch baseMatch; smatch baseMatch;
if (std::regex_match(cellDescription, baseMatch, exteriorCellPattern)) if (regex_match(cellDescription, baseMatch, exteriorCellPattern))
{ {
cell.mData.mFlags &= ~ESM::Cell::Interior; cell.mData.mFlags &= ~ESM::Cell::Interior;

@ -245,6 +245,26 @@ int main(int argc, char *argv[])
peer->SetMaximumIncomingConnections((unsigned short) (players)); peer->SetMaximumIncomingConnections((unsigned short) (players));
Networking networking(peer); Networking networking(peer);
if(mgr.getBool("autoSort", "Plugins"))
networking.getState().loadMods();
else
{
std::vector<std::string> 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); networking.setServerPassword(passw);
if (mgr.getBool("enabled", "MasterServer")) if (mgr.getBool("enabled", "MasterServer"))

@ -7,12 +7,15 @@ hostname = My TES3MP server
logLevel = 1 logLevel = 1
password = password =
[Plugins]
home = ~/local/openmw/tes3mp
plugins = server.lua
[MasterServer] [MasterServer]
enabled = true enabled = true
address = master.tes3mp.com address = master.tes3mp.com
port = 25560 port = 25560
rate = 1000 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
Loading…
Cancel
Save