[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;
exitCode = 0;
luaState.loadMods();
serverPassword = TES3MP_DEFAULT_PASSW;

@ -334,41 +334,51 @@ int CompVersion(const string &wishVersion, const string &depVersionFound)
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;
vector<vector<ServerPluginInfo>::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<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
result.push_back(it);
@ -428,7 +438,7 @@ vector<vector<ServerPluginInfo>::iterator> loadOrderSolver(vector<ServerPluginIn
return move(result);
}
void LuaState::loadMods()
void LuaState::loadMods(std::vector<std::string> *list)
{
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)
{
@ -502,4 +533,4 @@ void LuaState::loadMods()
}
dataEnv["Core"]["LOADED_MODS"] = mods.size();
}
}

@ -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<std::string> *list = nullptr);
CommandController &getCmdCtrl();
EventController &getEventCtrl();
@ -58,5 +58,4 @@ private:
std::unique_ptr<ObjectController> objectCtrl;
std::vector<ServerPluginInfo> mods;
};

@ -11,7 +11,7 @@ const vector<string> Utils::split(const string &str, int delimiter)
string buffer;
vector<string> 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;

@ -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<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);
if (mgr.getBool("enabled", "MasterServer"))

@ -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
Loading…
Cancel
Save