Load dependencies and description from mod.conf
This commit is contained in:
parent
dfc8198349
commit
71b2570f09
@ -271,34 +271,13 @@ function modmgr.render_modlist(render_list)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
function modmgr.get_dependencies(modfolder)
|
function modmgr.get_dependencies(path)
|
||||||
local toadd_hard = ""
|
if path == nil then
|
||||||
local toadd_soft = ""
|
return "", ""
|
||||||
if modfolder ~= nil then
|
|
||||||
local filename = modfolder ..
|
|
||||||
DIR_DELIM .. "depends.txt"
|
|
||||||
|
|
||||||
local hard_dependencies = {}
|
|
||||||
local soft_dependencies = {}
|
|
||||||
local dependencyfile = io.open(filename,"r")
|
|
||||||
if dependencyfile then
|
|
||||||
local dependency = dependencyfile:read("*l")
|
|
||||||
while dependency do
|
|
||||||
dependency = dependency:gsub("\r", "")
|
|
||||||
if string.sub(dependency, -1, -1) == "?" then
|
|
||||||
table.insert(soft_dependencies, string.sub(dependency, 1, -2))
|
|
||||||
else
|
|
||||||
table.insert(hard_dependencies, dependency)
|
|
||||||
end
|
|
||||||
dependency = dependencyfile:read()
|
|
||||||
end
|
|
||||||
dependencyfile:close()
|
|
||||||
end
|
|
||||||
toadd_hard = table.concat(hard_dependencies, ",")
|
|
||||||
toadd_soft = table.concat(soft_dependencies, ",")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return toadd_hard, toadd_soft
|
local info = core.get_mod_info(path)
|
||||||
|
return table.concat(info.depends, ","), table.concat(info.optional_depends, ",")
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@ -40,12 +40,11 @@ local function get_formspec(tabview, name, tabdata)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if selected_mod ~= nil then
|
if selected_mod ~= nil then
|
||||||
local modscreenshot = nil
|
|
||||||
|
|
||||||
--check for screenshot beeing available
|
--check for screenshot beeing available
|
||||||
local screenshotfilename = selected_mod.path .. DIR_DELIM .. "screenshot.png"
|
local screenshotfilename = selected_mod.path .. DIR_DELIM .. "screenshot.png"
|
||||||
local error = nil
|
local screenshotfile, error = io.open(screenshotfilename,"r")
|
||||||
local screenshotfile,error = io.open(screenshotfilename,"r")
|
|
||||||
|
local modscreenshot
|
||||||
if error == nil then
|
if error == nil then
|
||||||
screenshotfile:close()
|
screenshotfile:close()
|
||||||
modscreenshot = screenshotfilename
|
modscreenshot = screenshotfilename
|
||||||
@ -55,33 +54,20 @@ local function get_formspec(tabview, name, tabdata)
|
|||||||
modscreenshot = defaulttexturedir .. "no_screenshot.png"
|
modscreenshot = defaulttexturedir .. "no_screenshot.png"
|
||||||
end
|
end
|
||||||
|
|
||||||
retval = retval
|
|
||||||
.. "image[5.5,0;3,2;" .. core.formspec_escape(modscreenshot) .. "]"
|
|
||||||
.. "label[8.25,0.6;" .. selected_mod.name .. "]"
|
|
||||||
|
|
||||||
local descriptionlines = nil
|
|
||||||
error = nil
|
|
||||||
local descriptionfilename = selected_mod.path .. "description.txt"
|
|
||||||
local descriptionfile,error = io.open(descriptionfilename,"r")
|
|
||||||
if error == nil then
|
|
||||||
local descriptiontext = descriptionfile:read("*all")
|
|
||||||
|
|
||||||
descriptionlines = core.wrap_text(descriptiontext, 42, true)
|
|
||||||
descriptionfile:close()
|
|
||||||
else
|
|
||||||
descriptionlines = {}
|
|
||||||
descriptionlines[#descriptionlines + 1] = fgettext("No mod description available")
|
|
||||||
end
|
|
||||||
|
|
||||||
retval = retval ..
|
retval = retval ..
|
||||||
"label[5.5,1.7;".. fgettext("Mod Information:") .. "]" ..
|
"image[5.5,0;3,2;" .. core.formspec_escape(modscreenshot) .. "]" ..
|
||||||
"textlist[5.5,2.2;6.2,2.4;description;"
|
"label[8.25,0.6;" .. selected_mod.name .. "]" ..
|
||||||
|
"label[5.5,1.7;".. fgettext("Mod Information:") .. "]" ..
|
||||||
|
"textlist[5.5,2.2;6.2,2.4;description;"
|
||||||
|
|
||||||
for i=1,#descriptionlines,1 do
|
|
||||||
|
local info = core.get_mod_info(selected_mod.path)
|
||||||
|
local desc = info.description or fgettext("No mod description available")
|
||||||
|
local descriptionlines = core.wrap_text(desc, 42, true)
|
||||||
|
for i = 1, #descriptionlines do
|
||||||
retval = retval .. core.formspec_escape(descriptionlines[i]) .. ","
|
retval = retval .. core.formspec_escape(descriptionlines[i]) .. ","
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if selected_mod.is_modpack then
|
if selected_mod.is_modpack then
|
||||||
retval = retval .. ";0]" ..
|
retval = retval .. ";0]" ..
|
||||||
"button[9.9,4.65;2,1;btn_mod_mgr_rename_modpack;" ..
|
"button[9.9,4.65;2,1;btn_mod_mgr_rename_modpack;" ..
|
||||||
@ -90,7 +76,8 @@ local function get_formspec(tabview, name, tabdata)
|
|||||||
.. fgettext("Uninstall Selected Modpack") .. "]"
|
.. fgettext("Uninstall Selected Modpack") .. "]"
|
||||||
else
|
else
|
||||||
--show dependencies
|
--show dependencies
|
||||||
local toadd_hard, toadd_soft = modmgr.get_dependencies(selected_mod.path)
|
local toadd_hard = table.concat(info.depends, ",")
|
||||||
|
local toadd_soft = table.concat(info.optional_depends, ",")
|
||||||
if toadd_hard == "" and toadd_soft == "" then
|
if toadd_hard == "" and toadd_soft == "" then
|
||||||
retval = retval .. "," .. fgettext("No dependencies.")
|
retval = retval .. "," .. fgettext("No dependencies.")
|
||||||
else
|
else
|
||||||
|
@ -130,9 +130,8 @@ Mod directory structure
|
|||||||
|
|
||||||
mods
|
mods
|
||||||
|-- modname
|
|-- modname
|
||||||
| |-- depends.txt
|
| |-- mod.conf
|
||||||
| |-- screenshot.png
|
| |-- screenshot.png
|
||||||
| |-- description.txt
|
|
||||||
| |-- settingtypes.txt
|
| |-- settingtypes.txt
|
||||||
| |-- init.lua
|
| |-- init.lua
|
||||||
| |-- models
|
| |-- models
|
||||||
@ -145,12 +144,32 @@ Mod directory structure
|
|||||||
| `-- <custom data>
|
| `-- <custom data>
|
||||||
`-- another
|
`-- another
|
||||||
|
|
||||||
|
|
||||||
### modname
|
### modname
|
||||||
The location of this directory can be fetched by using
|
The location of this directory can be fetched by using
|
||||||
`minetest.get_modpath(modname)`.
|
`minetest.get_modpath(modname)`.
|
||||||
|
|
||||||
|
### mod.conf
|
||||||
|
A key-value store of mod details.
|
||||||
|
|
||||||
|
* `name` - the mod name. Allows Minetest to determine the mod name even if the
|
||||||
|
folder is wrongly named.
|
||||||
|
* `description` - Description of mod to be shown in the Mods tab of the mainmenu.
|
||||||
|
* `depends` - A comma separated list of dependencies. These are mods that must
|
||||||
|
be loaded before this mod.
|
||||||
|
* `optional_depends` - A comma separated list of optional dependencies.
|
||||||
|
Like a dependency, but no error if the mod doesn't exist.
|
||||||
|
|
||||||
|
Note: to support 0.4.x, please also provide depends.txt.
|
||||||
|
|
||||||
|
### `screenshot.png`
|
||||||
|
A screenshot shown in the mod manager within the main menu. It should
|
||||||
|
have an aspect ratio of 3:2 and a minimum size of 300×200 pixels.
|
||||||
|
|
||||||
### `depends.txt`
|
### `depends.txt`
|
||||||
|
**Deprecated:** you should use mod.conf instead.
|
||||||
|
|
||||||
|
This file is used if there are no dependencies in mod.conf.
|
||||||
|
|
||||||
List of mods that have to be loaded before loading this mod.
|
List of mods that have to be loaded before loading this mod.
|
||||||
|
|
||||||
A single line contains a single modname.
|
A single line contains a single modname.
|
||||||
@ -159,11 +178,11 @@ Optional dependencies can be defined by appending a question mark
|
|||||||
to a single modname. This means that if the specified mod
|
to a single modname. This means that if the specified mod
|
||||||
is missing, it does not prevent this mod from being loaded.
|
is missing, it does not prevent this mod from being loaded.
|
||||||
|
|
||||||
### `screenshot.png`
|
|
||||||
A screenshot shown in the mod manager within the main menu. It should
|
|
||||||
have an aspect ratio of 3:2 and a minimum size of 300×200 pixels.
|
|
||||||
|
|
||||||
### `description.txt`
|
### `description.txt`
|
||||||
|
**Deprecated:** you should use mod.conf instead.
|
||||||
|
|
||||||
|
This file is used if there is no description in mod.conf.
|
||||||
|
|
||||||
A file containing a description to be shown in the Mods tab of the mainmenu.
|
A file containing a description to be shown in the Mods tab of the mainmenu.
|
||||||
|
|
||||||
### `settingtypes.txt`
|
### `settingtypes.txt`
|
||||||
|
@ -111,7 +111,7 @@ core.get_screen_info()
|
|||||||
window_height = <current window height>
|
window_height = <current window height>
|
||||||
}
|
}
|
||||||
|
|
||||||
Games:
|
Packages:
|
||||||
core.get_game(index)
|
core.get_game(index)
|
||||||
^ returns {
|
^ returns {
|
||||||
id = <id>,
|
id = <id>,
|
||||||
@ -125,6 +125,15 @@ core.get_game(index)
|
|||||||
core.get_games() -> table of all games in upper format (possible in async calls)
|
core.get_games() -> table of all games in upper format (possible in async calls)
|
||||||
core.get_mapgen_names([include_hidden=false]) -> table of map generator algorithms
|
core.get_mapgen_names([include_hidden=false]) -> table of map generator algorithms
|
||||||
registered in the core (possible in async calls)
|
registered in the core (possible in async calls)
|
||||||
|
core.get_mod_info(path)
|
||||||
|
^ returns {
|
||||||
|
name = "name of mod",
|
||||||
|
type = "mod" or "modpack",
|
||||||
|
description = "description",
|
||||||
|
path = "path/to/mod",
|
||||||
|
depends = {"mod", "names"},
|
||||||
|
optional_depends = {"mod", "names"},
|
||||||
|
}
|
||||||
|
|
||||||
Favorites:
|
Favorites:
|
||||||
core.get_favorites(location) -> list of favorites (possible in async calls)
|
core.get_favorites(location) -> list of favorites (possible in async calls)
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
default
|
|
||||||
|
|
3
games/minimal/mods/bucket/mod.conf
Normal file
3
games/minimal/mods/bucket/mod.conf
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
name = bucket
|
||||||
|
description = Minimal bucket to place and pick up liquids
|
||||||
|
depends = default
|
2
games/minimal/mods/default/mod.conf
Normal file
2
games/minimal/mods/default/mod.conf
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
name = default
|
||||||
|
description = Minimal default, adds basic nodes
|
@ -1,2 +0,0 @@
|
|||||||
default
|
|
||||||
stairs
|
|
3
games/minimal/mods/experimental/mod.conf
Normal file
3
games/minimal/mods/experimental/mod.conf
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
name = experimental
|
||||||
|
description = Minimal mod to test features
|
||||||
|
depends = default, stairs
|
@ -1,2 +0,0 @@
|
|||||||
default
|
|
||||||
|
|
3
games/minimal/mods/give_initial_stuff/mod.conf
Normal file
3
games/minimal/mods/give_initial_stuff/mod.conf
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
name = give_initial_stuff
|
||||||
|
description = Gives items to players on join
|
||||||
|
depends = default
|
@ -1,2 +0,0 @@
|
|||||||
default
|
|
||||||
|
|
3
games/minimal/mods/legacy/mod.conf
Normal file
3
games/minimal/mods/legacy/mod.conf
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
name = legacy
|
||||||
|
description = Aliases allowing support for 0.3.x worlds
|
||||||
|
depends = default
|
@ -1 +0,0 @@
|
|||||||
default
|
|
3
games/minimal/mods/stairs/mod.conf
Normal file
3
games/minimal/mods/stairs/mod.conf
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
name = stairs
|
||||||
|
description = Adds stairs and slabs
|
||||||
|
depends = default
|
2
games/minimal/mods/test/mod.conf
Normal file
2
games/minimal/mods/test/mod.conf
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
name = test
|
||||||
|
description = Adds unit tests for the engine
|
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 <cctype>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
|
#include <algorithm>
|
||||||
#include "mods.h"
|
#include "mods.h"
|
||||||
#include "filesys.h"
|
#include "filesys.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
@ -28,14 +29,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "porting.h"
|
#include "porting.h"
|
||||||
#include "convert_json.h"
|
#include "convert_json.h"
|
||||||
|
|
||||||
static bool parseDependsLine(std::istream &is,
|
bool parseDependsString(std::string &dep,
|
||||||
std::string &dep, std::set<char> &symbols)
|
std::unordered_set<char> &symbols)
|
||||||
{
|
{
|
||||||
std::getline(is, dep);
|
|
||||||
dep = trim(dep);
|
dep = trim(dep);
|
||||||
symbols.clear();
|
symbols.clear();
|
||||||
size_t pos = dep.size();
|
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
|
// last character is a symbol, not part of the modname
|
||||||
symbols.insert(dep[pos-1]);
|
symbols.insert(dep[pos-1]);
|
||||||
--pos;
|
--pos;
|
||||||
@ -60,28 +60,66 @@ void parseModContents(ModSpec &spec)
|
|||||||
|
|
||||||
// Handle modpacks (defined by containing modpack.txt)
|
// Handle modpacks (defined by containing modpack.txt)
|
||||||
std::ifstream modpack_is((spec.path+DIR_DELIM+"modpack.txt").c_str());
|
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
|
modpack_is.close(); // We don't actually need the file
|
||||||
spec.is_modpack = true;
|
spec.is_modpack = true;
|
||||||
spec.modpack_content = getModsInPath(spec.path, true);
|
spec.modpack_content = getModsInPath(spec.path, true);
|
||||||
|
|
||||||
// modpacks have no dependencies; they are defined and
|
// modpacks have no dependencies; they are defined and
|
||||||
// tracked separately for each mod in the modpack
|
// tracked separately for each mod in the modpack
|
||||||
}
|
|
||||||
else{ // not a modpack, parse the dependencies
|
} else {
|
||||||
std::ifstream is((spec.path+DIR_DELIM+"depends.txt").c_str());
|
// Attempt to load dependencies from mod.conf
|
||||||
while(is.good()){
|
bool mod_conf_has_depends = false;
|
||||||
std::string dep;
|
if (info.exists("depends")) {
|
||||||
std::set<char> symbols;
|
mod_conf_has_depends = true;
|
||||||
if(parseDependsLine(is, dep, symbols)){
|
std::string dep = info.get("depends");
|
||||||
if(symbols.count('?') != 0){
|
dep.erase(std::remove_if(dep.begin(), dep.end(),
|
||||||
spec.optdepends.insert(dep);
|
static_cast<int(*)(int)>(&std::isspace)), dep.end());
|
||||||
}
|
for (const auto &dependency : str_split(dep, ',')) {
|
||||||
else{
|
spec.depends.insert(dependency);
|
||||||
spec.depends.insert(dep);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 name;
|
||||||
std::string path;
|
std::string path;
|
||||||
|
std::string desc;
|
||||||
|
|
||||||
//if normal mod:
|
//if normal mod:
|
||||||
std::unordered_set<std::string> depends;
|
std::unordered_set<std::string> depends;
|
||||||
std::unordered_set<std::string> optdepends;
|
std::unordered_set<std::string> optdepends;
|
||||||
@ -44,6 +46,7 @@ struct ModSpec
|
|||||||
|
|
||||||
bool part_of_modpack = false;
|
bool part_of_modpack = false;
|
||||||
bool is_modpack = false;
|
bool is_modpack = false;
|
||||||
|
|
||||||
// if modpack:
|
// if modpack:
|
||||||
std::map<std::string,ModSpec> modpack_content;
|
std::map<std::string,ModSpec> modpack_content;
|
||||||
ModSpec(const std::string &name_ = "", const std::string &path_ = ""):
|
ModSpec(const std::string &name_ = "", const std::string &path_ = ""):
|
||||||
|
@ -257,56 +257,6 @@ int ModApiMainMenu::l_get_worlds(lua_State *L)
|
|||||||
return 1;
|
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)
|
int ModApiMainMenu::l_get_favorites(lua_State *L)
|
||||||
{
|
{
|
||||||
@ -477,6 +427,103 @@ int ModApiMainMenu::l_delete_favorite(lua_State *L)
|
|||||||
return 0;
|
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)
|
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_table_index);
|
||||||
API_FCT(get_worlds);
|
API_FCT(get_worlds);
|
||||||
API_FCT(get_games);
|
API_FCT(get_games);
|
||||||
|
API_FCT(get_mod_info);
|
||||||
API_FCT(start);
|
API_FCT(start);
|
||||||
API_FCT(close);
|
API_FCT(close);
|
||||||
API_FCT(get_favorites);
|
API_FCT(get_favorites);
|
||||||
|
@ -71,8 +71,6 @@ private:
|
|||||||
|
|
||||||
static int l_get_worlds(lua_State *L);
|
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_mapgen_names(lua_State *L);
|
||||||
|
|
||||||
static int l_get_favorites(lua_State *L);
|
static int l_get_favorites(lua_State *L);
|
||||||
@ -81,6 +79,12 @@ private:
|
|||||||
|
|
||||||
static int l_gettext(lua_State *L);
|
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
|
//gui
|
||||||
|
|
||||||
static int l_show_keys_menu(lua_State *L);
|
static int l_show_keys_menu(lua_State *L);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user