mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Load dependencies and description from mod.conf
This commit is contained in:
parent
dfc8198349
commit
71b2570f09
20 changed files with 237 additions and 140 deletions
74
src/mods.cpp
74
src/mods.cpp
|
@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include <cctype>
|
||||
#include <fstream>
|
||||
#include <json/json.h>
|
||||
#include <algorithm>
|
||||
#include "mods.h"
|
||||
#include "filesys.h"
|
||||
#include "log.h"
|
||||
|
@ -28,14 +29,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "porting.h"
|
||||
#include "convert_json.h"
|
||||
|
||||
static bool parseDependsLine(std::istream &is,
|
||||
std::string &dep, std::set<char> &symbols)
|
||||
bool parseDependsString(std::string &dep,
|
||||
std::unordered_set<char> &symbols)
|
||||
{
|
||||
std::getline(is, dep);
|
||||
dep = trim(dep);
|
||||
symbols.clear();
|
||||
size_t pos = dep.size();
|
||||
while(pos > 0 && !string_allowed(dep.substr(pos-1, 1), MODNAME_ALLOWED_CHARS)){
|
||||
while (pos > 0 && !string_allowed(dep.substr(pos-1, 1), MODNAME_ALLOWED_CHARS)) {
|
||||
// last character is a symbol, not part of the modname
|
||||
symbols.insert(dep[pos-1]);
|
||||
--pos;
|
||||
|
@ -60,28 +60,66 @@ void parseModContents(ModSpec &spec)
|
|||
|
||||
// Handle modpacks (defined by containing modpack.txt)
|
||||
std::ifstream modpack_is((spec.path+DIR_DELIM+"modpack.txt").c_str());
|
||||
if(modpack_is.good()){ //a modpack, recursively get the mods in it
|
||||
if (modpack_is.good()) { // a modpack, recursively get the mods in it
|
||||
modpack_is.close(); // We don't actually need the file
|
||||
spec.is_modpack = true;
|
||||
spec.modpack_content = getModsInPath(spec.path, true);
|
||||
|
||||
// modpacks have no dependencies; they are defined and
|
||||
// tracked separately for each mod in the modpack
|
||||
}
|
||||
else{ // not a modpack, parse the dependencies
|
||||
std::ifstream is((spec.path+DIR_DELIM+"depends.txt").c_str());
|
||||
while(is.good()){
|
||||
std::string dep;
|
||||
std::set<char> symbols;
|
||||
if(parseDependsLine(is, dep, symbols)){
|
||||
if(symbols.count('?') != 0){
|
||||
spec.optdepends.insert(dep);
|
||||
}
|
||||
else{
|
||||
spec.depends.insert(dep);
|
||||
|
||||
} else {
|
||||
// Attempt to load dependencies from mod.conf
|
||||
bool mod_conf_has_depends = false;
|
||||
if (info.exists("depends")) {
|
||||
mod_conf_has_depends = true;
|
||||
std::string dep = info.get("depends");
|
||||
dep.erase(std::remove_if(dep.begin(), dep.end(),
|
||||
static_cast<int(*)(int)>(&std::isspace)), dep.end());
|
||||
for (const auto &dependency : str_split(dep, ',')) {
|
||||
spec.depends.insert(dependency);
|
||||
}
|
||||
}
|
||||
|
||||
if (info.exists("optional_depends")) {
|
||||
mod_conf_has_depends = true;
|
||||
std::string dep = info.get("optional_depends");
|
||||
dep.erase(std::remove_if(dep.begin(), dep.end(),
|
||||
static_cast<int(*)(int)>(&std::isspace)), dep.end());
|
||||
for (const auto &dependency : str_split(dep, ',')) {
|
||||
spec.optdepends.insert(dependency);
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to depends.txt
|
||||
if (!mod_conf_has_depends) {
|
||||
std::vector<std::string> dependencies;
|
||||
|
||||
std::ifstream is((spec.path + DIR_DELIM + "depends.txt").c_str());
|
||||
while (is.good()) {
|
||||
std::string dep;
|
||||
std::getline(is, dep);
|
||||
dependencies.push_back(dep);
|
||||
}
|
||||
|
||||
for (auto &dependency : dependencies) {
|
||||
std::unordered_set<char> symbols;
|
||||
if (parseDependsString(dependency, symbols)) {
|
||||
if (symbols.count('?') != 0) {
|
||||
spec.optdepends.insert(dependency);
|
||||
} else {
|
||||
spec.depends.insert(dependency);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (info.exists("description")) {
|
||||
spec.desc = info.get("description");
|
||||
} else {
|
||||
std::ifstream is((spec.path + DIR_DELIM + "description.txt").c_str());
|
||||
spec.desc = std::string((std::istreambuf_iterator<char>(is)),
|
||||
std::istreambuf_iterator<char>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ struct ModSpec
|
|||
{
|
||||
std::string name;
|
||||
std::string path;
|
||||
std::string desc;
|
||||
|
||||
//if normal mod:
|
||||
std::unordered_set<std::string> depends;
|
||||
std::unordered_set<std::string> optdepends;
|
||||
|
@ -44,6 +46,7 @@ struct ModSpec
|
|||
|
||||
bool part_of_modpack = false;
|
||||
bool is_modpack = false;
|
||||
|
||||
// if modpack:
|
||||
std::map<std::string,ModSpec> modpack_content;
|
||||
ModSpec(const std::string &name_ = "", const std::string &path_ = ""):
|
||||
|
|
|
@ -257,56 +257,6 @@ int ModApiMainMenu::l_get_worlds(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
int ModApiMainMenu::l_get_games(lua_State *L)
|
||||
{
|
||||
std::vector<SubgameSpec> games = getAvailableGames();
|
||||
|
||||
lua_newtable(L);
|
||||
int top = lua_gettop(L);
|
||||
unsigned int index = 1;
|
||||
|
||||
for (const SubgameSpec &game : games) {
|
||||
lua_pushnumber(L,index);
|
||||
lua_newtable(L);
|
||||
int top_lvl2 = lua_gettop(L);
|
||||
|
||||
lua_pushstring(L,"id");
|
||||
lua_pushstring(L, game.id.c_str());
|
||||
lua_settable(L, top_lvl2);
|
||||
|
||||
lua_pushstring(L,"path");
|
||||
lua_pushstring(L, game.path.c_str());
|
||||
lua_settable(L, top_lvl2);
|
||||
|
||||
lua_pushstring(L,"gamemods_path");
|
||||
lua_pushstring(L, game.gamemods_path.c_str());
|
||||
lua_settable(L, top_lvl2);
|
||||
|
||||
lua_pushstring(L,"name");
|
||||
lua_pushstring(L, game.name.c_str());
|
||||
lua_settable(L, top_lvl2);
|
||||
|
||||
lua_pushstring(L,"menuicon_path");
|
||||
lua_pushstring(L, game.menuicon_path.c_str());
|
||||
lua_settable(L, top_lvl2);
|
||||
|
||||
lua_pushstring(L,"addon_mods_paths");
|
||||
lua_newtable(L);
|
||||
int table2 = lua_gettop(L);
|
||||
int internal_index=1;
|
||||
for (const std::string &addon_mods_path : game.addon_mods_paths) {
|
||||
lua_pushnumber(L,internal_index);
|
||||
lua_pushstring(L, addon_mods_path.c_str());
|
||||
lua_settable(L, table2);
|
||||
internal_index++;
|
||||
}
|
||||
lua_settable(L, top_lvl2);
|
||||
lua_settable(L, top);
|
||||
index++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/******************************************************************************/
|
||||
int ModApiMainMenu::l_get_favorites(lua_State *L)
|
||||
{
|
||||
|
@ -477,6 +427,103 @@ int ModApiMainMenu::l_delete_favorite(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
int ModApiMainMenu::l_get_games(lua_State *L)
|
||||
{
|
||||
std::vector<SubgameSpec> games = getAvailableGames();
|
||||
|
||||
lua_newtable(L);
|
||||
int top = lua_gettop(L);
|
||||
unsigned int index = 1;
|
||||
|
||||
for (const SubgameSpec &game : games) {
|
||||
lua_pushnumber(L, index);
|
||||
lua_newtable(L);
|
||||
int top_lvl2 = lua_gettop(L);
|
||||
|
||||
lua_pushstring(L, "id");
|
||||
lua_pushstring(L, game.id.c_str());
|
||||
lua_settable(L, top_lvl2);
|
||||
|
||||
lua_pushstring(L, "path");
|
||||
lua_pushstring(L, game.path.c_str());
|
||||
lua_settable(L, top_lvl2);
|
||||
|
||||
lua_pushstring(L, "gamemods_path");
|
||||
lua_pushstring(L, game.gamemods_path.c_str());
|
||||
lua_settable(L, top_lvl2);
|
||||
|
||||
lua_pushstring(L, "name");
|
||||
lua_pushstring(L, game.name.c_str());
|
||||
lua_settable(L, top_lvl2);
|
||||
|
||||
lua_pushstring(L, "menuicon_path");
|
||||
lua_pushstring(L, game.menuicon_path.c_str());
|
||||
lua_settable(L, top_lvl2);
|
||||
|
||||
lua_pushstring(L, "addon_mods_paths");
|
||||
lua_newtable(L);
|
||||
int table2 = lua_gettop(L);
|
||||
int internal_index = 1;
|
||||
for (const std::string &addon_mods_path : game.addon_mods_paths) {
|
||||
lua_pushnumber(L, internal_index);
|
||||
lua_pushstring(L, addon_mods_path.c_str());
|
||||
lua_settable(L, table2);
|
||||
internal_index++;
|
||||
}
|
||||
lua_settable(L, top_lvl2);
|
||||
lua_settable(L, top);
|
||||
index++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
int ModApiMainMenu::l_get_mod_info(lua_State *L)
|
||||
{
|
||||
std::string path = luaL_checkstring(L, 1);
|
||||
|
||||
ModSpec spec;
|
||||
spec.path = path;
|
||||
parseModContents(spec);
|
||||
|
||||
lua_newtable(L);
|
||||
|
||||
lua_pushstring(L, spec.name.c_str());
|
||||
lua_setfield(L, -2, "name");
|
||||
|
||||
lua_pushstring(L, spec.is_modpack ? "modpack" : "mod");
|
||||
lua_setfield(L, -2, "type");
|
||||
|
||||
lua_pushstring(L, spec.desc.c_str());
|
||||
lua_setfield(L, -2, "description");
|
||||
|
||||
lua_pushstring(L, spec.path.c_str());
|
||||
lua_setfield(L, -2, "path");
|
||||
|
||||
// Dependencies
|
||||
lua_newtable(L);
|
||||
int i = 1;
|
||||
for (const auto &dep : spec.depends) {
|
||||
lua_pushstring(L, dep.c_str());
|
||||
lua_rawseti(L, -2, i);
|
||||
i++;
|
||||
}
|
||||
lua_setfield(L, -2, "depends");
|
||||
|
||||
// Optional Dependencies
|
||||
lua_newtable(L);
|
||||
i = 1;
|
||||
for (const auto &dep : spec.optdepends) {
|
||||
lua_pushstring(L, dep.c_str());
|
||||
lua_rawseti(L, -2, i);
|
||||
i++;
|
||||
}
|
||||
lua_setfield(L, -2, "optional_depends");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
int ModApiMainMenu::l_show_keys_menu(lua_State *L)
|
||||
{
|
||||
|
@ -968,6 +1015,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)
|
|||
API_FCT(get_table_index);
|
||||
API_FCT(get_worlds);
|
||||
API_FCT(get_games);
|
||||
API_FCT(get_mod_info);
|
||||
API_FCT(start);
|
||||
API_FCT(close);
|
||||
API_FCT(get_favorites);
|
||||
|
|
|
@ -71,8 +71,6 @@ private:
|
|||
|
||||
static int l_get_worlds(lua_State *L);
|
||||
|
||||
static int l_get_games(lua_State *L);
|
||||
|
||||
static int l_get_mapgen_names(lua_State *L);
|
||||
|
||||
static int l_get_favorites(lua_State *L);
|
||||
|
@ -81,6 +79,12 @@ private:
|
|||
|
||||
static int l_gettext(lua_State *L);
|
||||
|
||||
//packages
|
||||
|
||||
static int l_get_games(lua_State *L);
|
||||
|
||||
static int l_get_mod_info(lua_State *L);
|
||||
|
||||
//gui
|
||||
|
||||
static int l_show_keys_menu(lua_State *L);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue