1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
From d10ea2ad7efc2364a8a2007b4c6d3e85511e2f84 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Tue, 3 Aug 2021 01:00:23 +0200
Subject: [PATCH] Add environment variable MINETEST_MOD_PATH
This adds an environment variable MINETEST_MOD_PATH.
When it exists, Minetest will look there for mods
in addition to ~/.minetest/mods/. Mods can still be
installed to ~/.minetest/mods/ with the built-in installer.
With thanks to Liliana Marie Prikler.
---
builtin/mainmenu/pkgmgr.lua | 7 +++----
doc/menu_lua_api.txt | 8 +++++++-
src/content/subgames.cpp | 11 +++++++++++
src/script/lua_api/l_mainmenu.cpp | 23 +++++++++++++++++++++++
src/script/lua_api/l_mainmenu.h | 2 ++
5 files changed, 46 insertions(+), 5 deletions(-)
diff --git a/builtin/mainmenu/pkgmgr.lua b/builtin/mainmenu/pkgmgr.lua
index 787936e31..d8fba0ebe 100644
--- a/builtin/mainmenu/pkgmgr.lua
+++ b/builtin/mainmenu/pkgmgr.lua
@@ -682,10 +682,9 @@ function pkgmgr.preparemodlist(data)
local game_mods = {}
--read global mods
- local modpath = core.get_modpath()
-
- if modpath ~= nil and
- modpath ~= "" then
+ local modpaths = core.get_modpaths()
+ --XXX what was ‘modpath ~= ""’ and ‘modpath ~= nil’ for?
+ for _,modpath in ipairs(modpaths) do
get_mods(modpath,global_mods)
end
diff --git a/doc/menu_lua_api.txt b/doc/menu_lua_api.txt
index b3975bc1d..132444b14 100644
--- a/doc/menu_lua_api.txt
+++ b/doc/menu_lua_api.txt
@@ -218,7 +218,13 @@ Package - content which is downloadable from the content db, may or may not be i
* returns path to global user data,
the directory that contains user-provided mods, worlds, games, and texture packs.
* core.get_modpath() (possible in async calls)
- * returns path to global modpath
+ * returns path to global modpath, where mods can be installed
+* core.get_modpaths() (possible in async calls)
+ * returns list of paths to global modpaths, where mods have been installed
+
+ The difference with "core.get_modpath" is that no mods should be installed in these
+ directories by Minetest -- they might be read-only.
+
* core.get_clientmodpath() (possible in async calls)
* returns path to global client-side modpath
* core.get_gamepath() (possible in async calls)
diff --git a/src/content/subgames.cpp b/src/content/subgames.cpp
index e9dc609b0..d73f95a1f 100644
--- a/src/content/subgames.cpp
+++ b/src/content/subgames.cpp
@@ -61,6 +61,12 @@ std::string getSubgamePathEnv()
return subgame_path ? std::string(subgame_path) : "";
}
+std::string getModPathEnv()
+{
+ char *mod_path = getenv("MINETEST_MOD_PATH");
+ return mod_path ? std::string(mod_path) : "";
+}
+
SubgameSpec findSubgame(const std::string &id)
{
if (id.empty())
@@ -110,6 +116,11 @@ SubgameSpec findSubgame(const std::string &id)
std::set<std::string> mods_paths;
if (!user_game)
mods_paths.insert(share + DIR_DELIM + "mods");
+
+ Strfnd mod_search_paths(getModPathEnv());
+ while (!mod_search_paths.at_end())
+ mods_paths.insert(mod_search_paths.next(PATH_DELIM));
+
if (user != share || user_game)
mods_paths.insert(user + DIR_DELIM + "mods");
diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp
index 3e9709bde..903ac3a22 100644
--- a/src/script/lua_api/l_mainmenu.cpp
+++ b/src/script/lua_api/l_mainmenu.cpp
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_internal.h"
#include "common/c_content.h"
#include "cpp_api/s_async.h"
+#include "util/strfnd.h"
#include "gui/guiEngine.h"
#include "gui/guiMainMenu.h"
#include "gui/guiKeyChangeMenu.h"
@@ -502,6 +503,26 @@ int ModApiMainMenu::l_get_modpath(lua_State *L)
return 1;
}
+/******************************************************************************/
+int ModApiMainMenu::l_get_modpaths(lua_State *L)
+{
+ const char *c_modpath = getenv("MINETEST_MOD_PATH");
+ if (c_modpath == NULL)
+ c_modpath = "";
+ int index = 1;
+ lua_newtable(L);
+ Strfnd mod_search_paths{std::string(c_modpath)};
+ while (!mod_search_paths.at_end()) {
+ std::string component = mod_search_paths.next(PATH_DELIM);
+ lua_pushstring(L, component.c_str());
+ lua_rawseti(L, -2, index);
+ index++;
+ }
+ ModApiMainMenu::l_get_modpath(L);
+ lua_rawseti(L, -2, index);
+ return 1;
+}
+
/******************************************************************************/
int ModApiMainMenu::l_get_clientmodpath(lua_State *L)
{
@@ -949,6 +970,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)
API_FCT(get_mapgen_names);
API_FCT(get_user_path);
API_FCT(get_modpath);
+ API_FCT(get_modpaths);
API_FCT(get_clientmodpath);
API_FCT(get_gamepath);
API_FCT(get_texturepath);
@@ -983,6 +1005,7 @@ void ModApiMainMenu::InitializeAsync(lua_State *L, int top)
API_FCT(get_mapgen_names);
API_FCT(get_user_path);
API_FCT(get_modpath);
+ API_FCT(get_modpaths);
API_FCT(get_clientmodpath);
API_FCT(get_gamepath);
API_FCT(get_texturepath);
diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h
index 33ac9e721..a6a54a2cb 100644
--- a/src/script/lua_api/l_mainmenu.h
+++ b/src/script/lua_api/l_mainmenu.h
@@ -112,6 +112,8 @@ class ModApiMainMenu: public ModApiBase
static int l_get_modpath(lua_State *L);
+ static int l_get_modpaths(lua_State *L);
+
static int l_get_clientmodpath(lua_State *L);
static int l_get_gamepath(lua_State *L);
--
2.32.0
|