forked from mirror/openmw-tes3mp
[Server] Rename server "plugins"/"mods" into "modules" for clarity
The terms "plugins" and "mods" were used interchangeably to refer to collections of server scripts, which was bound to cause confusion later on, especially with client data files frequently being referred to as "plugins" and "mods" as well. Moreover, the server configuration file now starts its manual ordering with "Module1" for consistency with the pluginlist.json (soon to be dataFileList.json) of the CoreScripts.
This commit is contained in:
parent
d1ad0c91f8
commit
993cc3dfd6
6 changed files with 74 additions and 74 deletions
|
@ -24,8 +24,8 @@ void EventController::Init(LuaState &lua)
|
||||||
eventsTable["raise"] = [&lua](unsigned event, sol::table data) {
|
eventsTable["raise"] = [&lua](unsigned event, sol::table data) {
|
||||||
lua.getEventCtrl().raiseEvent(event, data);
|
lua.getEventCtrl().raiseEvent(event, data);
|
||||||
};
|
};
|
||||||
eventsTable["raiseSpecified"] = [&lua](unsigned event, const std::string &modname, sol::table data) {
|
eventsTable["raiseSpecified"] = [&lua](unsigned event, const std::string &moduleName, sol::table data) {
|
||||||
lua.getEventCtrl().raiseEvent(event, data, modname);
|
lua.getEventCtrl().raiseEvent(event, data, moduleName);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,15 +132,15 @@ Event EventController::createEvent()
|
||||||
return lastEvent++;
|
return lastEvent++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventController::raiseEvent(Event id, sol::table data, const string &modname)
|
void EventController::raiseEvent(Event id, sol::table data, const string &moduleName)
|
||||||
{
|
{
|
||||||
auto iter = events.find(id);
|
auto iter = events.find(id);
|
||||||
if (iter != events.end())
|
if (iter != events.end())
|
||||||
{
|
{
|
||||||
if (!modname.empty())
|
if (!moduleName.empty())
|
||||||
{
|
{
|
||||||
auto f = std::find_if (iter->second.begin(), iter->second.end(), [&modname](const auto &item){
|
auto f = std::find_if (iter->second.begin(), iter->second.end(), [&moduleName](const auto &item){
|
||||||
return item.first["ModName"]["name"] == modname;
|
return item.first["ModuleName"]["name"] == moduleName;
|
||||||
});
|
});
|
||||||
if (f != iter->second.end())
|
if (f != iter->second.end())
|
||||||
f->second.call(data); // call only specified mod
|
f->second.call(data); // call only specified mod
|
||||||
|
|
|
@ -140,7 +140,7 @@ public:
|
||||||
void registerEvent(int event, sol::environment &env, sol::function& func);
|
void registerEvent(int event, sol::environment &env, sol::function& func);
|
||||||
CallbackCollection& GetEvents(Event event);
|
CallbackCollection& GetEvents(Event event);
|
||||||
Event createEvent();
|
Event createEvent();
|
||||||
void raiseEvent(Event id, sol::table data, const std::string &modname = "");
|
void raiseEvent(Event id, sol::table data, const std::string &moduleName = "");
|
||||||
void stop(int event);
|
void stop(int event);
|
||||||
|
|
||||||
template<Event event, typename R = void, typename... Args>
|
template<Event event, typename R = void, typename... Args>
|
||||||
|
|
|
@ -101,14 +101,14 @@ LuaState::LuaState()
|
||||||
CommandController::Init(*this);
|
CommandController::Init(*this);
|
||||||
|
|
||||||
dataEnv = sol::environment(*lua, sol::create, lua->globals());
|
dataEnv = sol::environment(*lua, sol::create, lua->globals());
|
||||||
lua->set("Data", dataEnv); // plain global environment for communicating between mods
|
lua->set("Data", dataEnv); // plain global environment for communicating between modules
|
||||||
auto coreTable = dataEnv.create("Core");
|
auto coreTable = dataEnv.create("Core");
|
||||||
coreTable["VERSION"] = TES3MP_VERSION;
|
coreTable["VERSION"] = TES3MP_VERSION;
|
||||||
coreTable["PROTOCOL"] = TES3MP_PROTO_VERSION;
|
coreTable["PROTOCOL"] = TES3MP_PROTO_VERSION;
|
||||||
coreTable["loadedMods"] = coreTable.create();
|
coreTable["loadedModules"] = coreTable.create();
|
||||||
|
|
||||||
configEnv = sol::environment(*lua, sol::create, lua->globals());
|
configEnv = sol::environment(*lua, sol::create, lua->globals());
|
||||||
lua->set("Config", configEnv); // plain global environment for mod configuration
|
lua->set("Config", configEnv); // plain global environment for module configuration
|
||||||
|
|
||||||
// Enable a special Sol error handler for Windows, because exceptions aren't caught properly
|
// Enable a special Sol error handler for Windows, because exceptions aren't caught properly
|
||||||
// in main.cpp for it
|
// in main.cpp for it
|
||||||
|
@ -227,10 +227,10 @@ LuaState::LuaState()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
lua->set_function("setModname", [](const std::string &modname) {
|
lua->set_function("setModname", [](const std::string &modName) {
|
||||||
auto mc = mwmp::Networking::getPtr()->getMasterClient();
|
auto mc = mwmp::Networking::getPtr()->getMasterClient();
|
||||||
if (mc)
|
if (mc)
|
||||||
mc->SetModname(modname);
|
mc->SetModname(modName);
|
||||||
});
|
});
|
||||||
|
|
||||||
lua->set_function("setHostname", [](const std::string &hostname) {
|
lua->set_function("setHostname", [](const std::string &hostname) {
|
||||||
|
@ -281,24 +281,24 @@ LuaState::LuaState()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::environment LuaState::openScript(std::string homePath, std::string modname)
|
sol::environment LuaState::openScript(std::string homePath, std::string moduleName)
|
||||||
{
|
{
|
||||||
cout << "Loading file: " << homePath + "/mods/" + modname + "/main.lua" << endl;
|
cout << "Loading module: " << homePath + "/modules/" + moduleName + "/main.lua" << endl;
|
||||||
|
|
||||||
sol::environment env(*lua, sol::create, lua->globals());
|
sol::environment env(*lua, sol::create, lua->globals());
|
||||||
std::string package_path = env["package"]["path"];
|
std::string package_path = env["package"]["path"];
|
||||||
env["package"]["path"] = Utils::convertPath(homePath + "/mods/" + modname + "/?.lua") + ";" + package_path;
|
env["package"]["path"] = Utils::convertPath(homePath + "/modules/" + moduleName + "/?.lua") + ";" + package_path;
|
||||||
package_path = env["package"]["path"];
|
package_path = env["package"]["path"];
|
||||||
|
|
||||||
env.set_function("getDataFolder", [homePath, modname]() -> const string {
|
env.set_function("getDataFolder", [homePath, moduleName]() -> const string {
|
||||||
return homePath + "/data/" + modname + '/';
|
return homePath + "/data/" + moduleName + '/';
|
||||||
});
|
});
|
||||||
|
|
||||||
env.set_function("getModFolder", [homePath, modname]() -> const string {
|
env.set_function("getModuleFolder", [homePath, moduleName]() -> const string {
|
||||||
return homePath + "/mods/" + modname + '/';
|
return homePath + "/modules/" + moduleName + '/';
|
||||||
});
|
});
|
||||||
|
|
||||||
lua->script_file(homePath + "/mods/" + modname + "/main.lua", env);
|
lua->script_file(homePath + "/modules/" + moduleName + "/main.lua", env);
|
||||||
|
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
@ -386,25 +386,25 @@ int CompVersion(const string &wishVersion, const string &depVersionFound)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkDependencies(const vector<ServerPluginInfo> &mods, const ServerPluginInfo &spi, bool fatal = true)
|
void checkDependencies(const vector<ServerModuleInfo> &modules, const ServerModuleInfo &smi, bool fatal = true)
|
||||||
{
|
{
|
||||||
for (auto &dependency : spi.dependencies)
|
for (auto &dependency : smi.dependencies)
|
||||||
{
|
{
|
||||||
const std::string &depNameRequest = dependency.first;
|
const std::string &depNameRequest = dependency.first;
|
||||||
const std::string &depVersionRequest = dependency.second;
|
const std::string &depVersionRequest = dependency.second;
|
||||||
|
|
||||||
const auto &depEnvIt = find_if(mods.begin(), mods.end(), [&depNameRequest](const auto &val) {
|
const auto &depEnvIt = find_if(modules.begin(), modules.end(), [&depNameRequest](const auto &val) {
|
||||||
return val.name == depNameRequest;
|
return val.name == depNameRequest;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (depEnvIt != mods.end())
|
if (depEnvIt != modules.end())
|
||||||
{
|
{
|
||||||
const string &depVersionFound = depEnvIt->version;
|
const string &depVersionFound = depEnvIt->version;
|
||||||
if (CompVersion(depVersionRequest, depVersionFound) != 0)
|
if (CompVersion(depVersionRequest, depVersionFound) != 0)
|
||||||
{
|
{
|
||||||
stringstream sstr;
|
stringstream sstr;
|
||||||
sstr << depNameRequest << ": version \"" << depVersionFound << "\" is not applicable for \""
|
sstr << depNameRequest << ": version \"" << depVersionFound << "\" is not applicable for \""
|
||||||
<< spi.name << "\" expected \"" << depVersionRequest + "\"";
|
<< smi.name << "\" expected \"" << depVersionRequest + "\"";
|
||||||
if (fatal)
|
if (fatal)
|
||||||
throw runtime_error(sstr.str());
|
throw runtime_error(sstr.str());
|
||||||
else
|
else
|
||||||
|
@ -423,16 +423,16 @@ void checkDependencies(const vector<ServerPluginInfo> &mods, const ServerPluginI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<vector<ServerPluginInfo>::iterator> loadOrderSolver(vector<ServerPluginInfo> &mods)
|
vector<vector<ServerModuleInfo>::iterator> loadOrderSolver(vector<ServerModuleInfo> &modules)
|
||||||
{
|
{
|
||||||
vector<vector<ServerPluginInfo>::iterator> notResolved;
|
vector<vector<ServerModuleInfo>::iterator> notResolved;
|
||||||
vector<vector<ServerPluginInfo>::iterator> result;
|
vector<vector<ServerModuleInfo>::iterator> result;
|
||||||
|
|
||||||
for (auto it = mods.begin(); it != mods.end(); ++it)
|
for (auto it = modules.begin(); it != modules.end(); ++it)
|
||||||
{
|
{
|
||||||
checkDependencies(mods, *it);
|
checkDependencies(modules, *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 the server module doesn't have any dependencies, we can safely add it to the result
|
||||||
result.push_back(it);
|
result.push_back(it);
|
||||||
else
|
else
|
||||||
notResolved.push_back(it);
|
notResolved.push_back(it);
|
||||||
|
@ -449,9 +449,9 @@ vector<vector<ServerPluginInfo>::iterator> loadOrderSolver(vector<ServerPluginIn
|
||||||
return dep.first == a->name;
|
return dep.first == a->name;
|
||||||
});
|
});
|
||||||
if (found != result.end())
|
if (found != result.end())
|
||||||
continue; // if dependency already in correct order, otherwise hold plugin in unresolved
|
continue; // if the dependency is already in the correct order, otherwise hold it among the unresolved ones
|
||||||
|
|
||||||
// check if someone depends on this plugin
|
// check if any module depends on this one
|
||||||
found = find_if(notResolved.begin(), notResolved.end(), [&dep](auto &a) {
|
found = find_if(notResolved.begin(), notResolved.end(), [&dep](auto &a) {
|
||||||
return dep.first == a->name;
|
return dep.first == a->name;
|
||||||
});
|
});
|
||||||
|
@ -490,35 +490,35 @@ vector<vector<ServerPluginInfo>::iterator> loadOrderSolver(vector<ServerPluginIn
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaState::loadMods(const std::string &modDir, std::vector<std::string> *list)
|
void LuaState::loadModules(const std::string &moduleDir, std::vector<std::string> *list)
|
||||||
{
|
{
|
||||||
using namespace boost::filesystem;
|
using namespace boost::filesystem;
|
||||||
|
|
||||||
auto readConfig = [this](path homePath){
|
auto readConfig = [this](path homePath){
|
||||||
const auto mainScript = "main.lua";
|
const auto mainScript = "main.lua";
|
||||||
if (!is_directory(homePath / "mods"))
|
if (!is_directory(homePath / "modules"))
|
||||||
throw runtime_error(homePath.string() + ": No such directory.");
|
throw runtime_error(homePath.string() + ": No such directory.");
|
||||||
for (const auto &modDir : directory_iterator(homePath / "mods"))
|
for (const auto &moduleDir : directory_iterator(homePath / "modules"))
|
||||||
{
|
{
|
||||||
if (is_directory(modDir.status()) && exists(modDir.path() / mainScript))
|
if (is_directory(moduleDir.status()) && exists(moduleDir.path() / mainScript))
|
||||||
{
|
{
|
||||||
boost::property_tree::ptree pt;
|
boost::property_tree::ptree pt;
|
||||||
auto _path = homePath.string() + "/mods/" + modDir.path().filename().string();
|
auto _path = homePath.string() + "/modules/" + moduleDir.path().filename().string();
|
||||||
boost::property_tree::read_json(_path + "/modinfo.json", pt);
|
boost::property_tree::read_json(_path + "/moduleInfo.json", pt);
|
||||||
|
|
||||||
ServerPluginInfo modInfo;
|
ServerModuleInfo moduleInfo;
|
||||||
|
|
||||||
modInfo.path = make_pair(homePath.string(), modDir.path().filename().string());
|
moduleInfo.path = make_pair(homePath.string(), moduleDir.path().filename().string());
|
||||||
modInfo.author = pt.get<string>("author");
|
moduleInfo.author = pt.get<string>("author");
|
||||||
modInfo.version = pt.get<string>("version");
|
moduleInfo.version = pt.get<string>("version");
|
||||||
|
|
||||||
for (const auto &v : pt.get_child("dependencies"))
|
for (const auto &v : pt.get_child("dependencies"))
|
||||||
modInfo.dependencies.emplace_back(v.first, v.second.get_value<string>());
|
moduleInfo.dependencies.emplace_back(v.first, v.second.get_value<string>());
|
||||||
|
|
||||||
auto name = pt.get<string>("name");
|
auto name = pt.get<string>("name");
|
||||||
|
|
||||||
modInfo.name = name;
|
moduleInfo.name = name;
|
||||||
mods.push_back(move(modInfo));
|
modules.push_back(move(moduleInfo));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -531,7 +531,7 @@ void LuaState::loadMods(const std::string &modDir, std::vector<std::string> *lis
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
path envServerDir = modDir;
|
path envServerDir = moduleDir;
|
||||||
|
|
||||||
if (envServerDir.empty())
|
if (envServerDir.empty())
|
||||||
envServerDir = current_path();
|
envServerDir = current_path();
|
||||||
|
@ -540,37 +540,37 @@ void LuaState::loadMods(const std::string &modDir, std::vector<std::string> *lis
|
||||||
addGlobalCPath(envServerDir.string() + "/lib/?" + libExt);
|
addGlobalCPath(envServerDir.string() + "/lib/?" + libExt);
|
||||||
readConfig(envServerDir);
|
readConfig(envServerDir);
|
||||||
|
|
||||||
vector<vector<ServerPluginInfo>::iterator> sortedPluginList;
|
vector<vector<ServerModuleInfo>::iterator> sortedModuleList;
|
||||||
if (list != nullptr && !list->empty()) // manual sorted list
|
if (list != nullptr && !list->empty()) // manual sorted list
|
||||||
{
|
{
|
||||||
for (const auto &mssp : *list)
|
for (const auto &mssp : *list)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (auto it = mods.begin(); it != mods.end(); ++it)
|
for (auto it = modules.begin(); it != modules.end(); ++it)
|
||||||
{
|
{
|
||||||
if (it->name == mssp)
|
if (it->name == mssp)
|
||||||
{
|
{
|
||||||
checkDependencies(mods, *it, false); // check dependencies, but do not throw exceptions
|
checkDependencies(modules, *it, false); // check dependencies, but do not throw exceptions
|
||||||
sortedPluginList.push_back(it);
|
sortedModuleList.push_back(it);
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found)
|
if (!found)
|
||||||
throw runtime_error("Plugin: \"" + mssp + "\" not found");
|
throw runtime_error("Module: \"" + mssp + "\" not found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sortedPluginList = loadOrderSolver(mods);
|
sortedModuleList = loadOrderSolver(modules);
|
||||||
|
|
||||||
for (auto &&mod : sortedPluginList)
|
for (auto &&module : sortedModuleList)
|
||||||
{
|
{
|
||||||
mod->env = openScript(mod->path.first, mod->path.second);
|
module->env = openScript(module->path.first, module->path.second);
|
||||||
|
|
||||||
sol::table loaded = dataEnv["Core"]["loadedMods"];
|
sol::table loaded = dataEnv["Core"]["loadedModules"];
|
||||||
loaded.add(mod->name);
|
loaded.add(module->name);
|
||||||
cout << "modname: " << mod->name << endl;
|
cout << "moduleName: " << module->name << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
dataEnv["Core"]["LOADED_MODS"] = mods.size();
|
dataEnv["Core"]["LOADED_MODULES"] = modules.size();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,10 @@
|
||||||
class EventController;
|
class EventController;
|
||||||
//class TimerController;
|
//class TimerController;
|
||||||
|
|
||||||
struct ServerPluginInfo
|
struct ServerModuleInfo
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
std::pair<std::string, std::string> path; // homePath, modname
|
std::pair<std::string, std::string> path; // homePath, moduleName
|
||||||
std::string version;
|
std::string version;
|
||||||
std::string author;
|
std::string author;
|
||||||
std::vector<std::pair<std::string, std::string>> dependencies; // name, requestedVersion
|
std::vector<std::pair<std::string, std::string>> dependencies; // name, requestedVersion
|
||||||
|
@ -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(const std::string &path, std::vector<std::string> *list = nullptr);
|
void loadModules(const std::string &path, std::vector<std::string> *list = nullptr);
|
||||||
|
|
||||||
CommandController &getCmdCtrl();
|
CommandController &getCmdCtrl();
|
||||||
EventController &getEventCtrl();
|
EventController &getEventCtrl();
|
||||||
|
@ -46,7 +46,7 @@ public:
|
||||||
ActorController &getActorCtrl();
|
ActorController &getActorCtrl();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sol::environment openScript(std::string path, std::string modname);
|
sol::environment openScript(std::string path, std::string moduleName);
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<sol::state> lua;
|
std::shared_ptr<sol::state> lua;
|
||||||
sol::environment dataEnv;
|
sol::environment dataEnv;
|
||||||
|
@ -57,5 +57,5 @@ private:
|
||||||
std::unique_ptr<ActorController> actorCtrl;
|
std::unique_ptr<ActorController> actorCtrl;
|
||||||
std::unique_ptr<ObjectController> objectCtrl;
|
std::unique_ptr<ObjectController> objectCtrl;
|
||||||
|
|
||||||
std::vector<ServerPluginInfo> mods;
|
std::vector<ServerModuleInfo> modules;
|
||||||
};
|
};
|
||||||
|
|
|
@ -253,23 +253,23 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
Networking networking(peer);
|
Networking networking(peer);
|
||||||
|
|
||||||
string plugin_home = mgr.getString("home", "Plugins");
|
string moduleHome = mgr.getString("home", "Modules");
|
||||||
|
|
||||||
if (mgr.getBool("autoSort", "Plugins"))
|
if (mgr.getBool("autoSort", "Modules"))
|
||||||
networking.getState().loadMods(plugin_home);
|
networking.getState().loadModules(moduleHome);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::vector<std::string> list;
|
std::vector<std::string> list;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
for (int i = 0;; ++i)
|
for (int i = 1;; ++i)
|
||||||
list.push_back(mgr.getString("Plugin" + to_string(i), "Plugins"));
|
list.push_back(mgr.getString("Module" + to_string(i), "Modules"));
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{} // Manager::getString throws runtime_error exception if setting is not exist
|
{} // Manager::getString throws runtime_error exception if setting is not exist
|
||||||
|
|
||||||
networking.getState().loadMods(plugin_home, &list);
|
networking.getState().loadModules(moduleHome, &list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,9 @@ address = master.tes3mp.com
|
||||||
port = 25560
|
port = 25560
|
||||||
rate = 1000
|
rate = 1000
|
||||||
|
|
||||||
[Plugins]
|
[Modules]
|
||||||
home = ~/local/openmw/tes3mp
|
home = ~/local/openmw/tes3mp
|
||||||
autoSort = true
|
autoSort = true
|
||||||
# If autoSort is disabled, then use "Plugin[n] = [plugin-name]" for manual ordering
|
# If autoSort is disabled, then use "Module# = <name>" for manual ordering
|
||||||
# Plugin0 = Core
|
# Module1 = Core
|
||||||
# Plugin1 = Coop
|
# Module2 = Coop
|
||||||
|
|
Loading…
Reference in a new issue