forked from Mirrorlandia_minetest/minetest
Add "MINETEST_MOD_PATH" environment variable (#11515)
This adds an environment variable MINETEST_MOD_PATH. When it exists, Minetest will look there for mods in addition to ~/.minetest/mods/.
This commit is contained in:
parent
53e126ac49
commit
9fab5d594c
@ -682,11 +682,9 @@ function pkgmgr.preparemodlist(data)
|
|||||||
local game_mods = {}
|
local game_mods = {}
|
||||||
|
|
||||||
--read global mods
|
--read global mods
|
||||||
local modpath = core.get_modpath()
|
local modpaths = core.get_modpaths()
|
||||||
|
for _, modpath in ipairs(modpaths) do
|
||||||
if modpath ~= nil and
|
get_mods(modpath, global_mods)
|
||||||
modpath ~= "" then
|
|
||||||
get_mods(modpath,global_mods)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
for i=1,#global_mods,1 do
|
for i=1,#global_mods,1 do
|
||||||
|
@ -219,7 +219,13 @@ Package - content which is downloadable from the content db, may or may not be i
|
|||||||
* returns path to global user data,
|
* returns path to global user data,
|
||||||
the directory that contains user-provided mods, worlds, games, and texture packs.
|
the directory that contains user-provided mods, worlds, games, and texture packs.
|
||||||
* core.get_modpath() (possible in async calls)
|
* 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)
|
* core.get_clientmodpath() (possible in async calls)
|
||||||
* returns path to global client-side modpath
|
* returns path to global client-side modpath
|
||||||
* core.get_gamepath() (possible in async calls)
|
* core.get_gamepath() (possible in async calls)
|
||||||
|
@ -119,6 +119,9 @@ Display an interactive terminal over ncurses during execution.
|
|||||||
.TP
|
.TP
|
||||||
.B MINETEST_SUBGAME_PATH
|
.B MINETEST_SUBGAME_PATH
|
||||||
Colon delimited list of directories to search for games.
|
Colon delimited list of directories to search for games.
|
||||||
|
.TP
|
||||||
|
.B MINETEST_MOD_PATH
|
||||||
|
Colon delimited list of directories to search for mods.
|
||||||
|
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
Please report all bugs at https://github.com/minetest/minetest/issues.
|
Please report all bugs at https://github.com/minetest/minetest/issues.
|
||||||
|
@ -113,6 +113,10 @@ SubgameSpec findSubgame(const std::string &id)
|
|||||||
if (user != share || user_game)
|
if (user != share || user_game)
|
||||||
mods_paths.insert(user + DIR_DELIM + "mods");
|
mods_paths.insert(user + DIR_DELIM + "mods");
|
||||||
|
|
||||||
|
for (const std::string &mod_path : getEnvModPaths()) {
|
||||||
|
mods_paths.insert(mod_path);
|
||||||
|
}
|
||||||
|
|
||||||
// Get meta
|
// Get meta
|
||||||
std::string conf_path = game_path + DIR_DELIM + "game.conf";
|
std::string conf_path = game_path + DIR_DELIM + "game.conf";
|
||||||
Settings conf;
|
Settings conf;
|
||||||
@ -384,3 +388,13 @@ void loadGameConfAndInitWorld(const std::string &path, const std::string &name,
|
|||||||
if (new_game_settings)
|
if (new_game_settings)
|
||||||
delete game_settings;
|
delete game_settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> getEnvModPaths()
|
||||||
|
{
|
||||||
|
const char *c_mod_path = getenv("MINETEST_MOD_PATH");
|
||||||
|
std::vector<std::string> paths;
|
||||||
|
Strfnd search_paths(c_mod_path ? c_mod_path : "");
|
||||||
|
while (!search_paths.at_end())
|
||||||
|
paths.push_back(search_paths.next(PATH_DELIM));
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
@ -58,6 +58,8 @@ SubgameSpec findWorldSubgame(const std::string &world_path);
|
|||||||
|
|
||||||
std::set<std::string> getAvailableGameIds();
|
std::set<std::string> getAvailableGameIds();
|
||||||
std::vector<SubgameSpec> getAvailableGames();
|
std::vector<SubgameSpec> getAvailableGames();
|
||||||
|
// Get the list of paths to mods in the environment variable $MINETEST_MOD_PATH
|
||||||
|
std::vector<std::string> getEnvModPaths();
|
||||||
|
|
||||||
bool getWorldExists(const std::string &world_path);
|
bool getWorldExists(const std::string &world_path);
|
||||||
//! Try to get the displayed name of a world
|
//! Try to get the displayed name of a world
|
||||||
|
@ -502,6 +502,21 @@ int ModApiMainMenu::l_get_modpath(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
int ModApiMainMenu::l_get_modpaths(lua_State *L)
|
||||||
|
{
|
||||||
|
int index = 1;
|
||||||
|
lua_newtable(L);
|
||||||
|
ModApiMainMenu::l_get_modpath(L);
|
||||||
|
lua_rawseti(L, -2, index);
|
||||||
|
for (const std::string &component : getEnvModPaths()) {
|
||||||
|
index++;
|
||||||
|
lua_pushstring(L, component.c_str());
|
||||||
|
lua_rawseti(L, -2, index);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
int ModApiMainMenu::l_get_clientmodpath(lua_State *L)
|
int ModApiMainMenu::l_get_clientmodpath(lua_State *L)
|
||||||
{
|
{
|
||||||
@ -856,6 +871,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)
|
|||||||
API_FCT(get_mapgen_names);
|
API_FCT(get_mapgen_names);
|
||||||
API_FCT(get_user_path);
|
API_FCT(get_user_path);
|
||||||
API_FCT(get_modpath);
|
API_FCT(get_modpath);
|
||||||
|
API_FCT(get_modpaths);
|
||||||
API_FCT(get_clientmodpath);
|
API_FCT(get_clientmodpath);
|
||||||
API_FCT(get_gamepath);
|
API_FCT(get_gamepath);
|
||||||
API_FCT(get_texturepath);
|
API_FCT(get_texturepath);
|
||||||
@ -889,6 +905,7 @@ void ModApiMainMenu::InitializeAsync(lua_State *L, int top)
|
|||||||
API_FCT(get_mapgen_names);
|
API_FCT(get_mapgen_names);
|
||||||
API_FCT(get_user_path);
|
API_FCT(get_user_path);
|
||||||
API_FCT(get_modpath);
|
API_FCT(get_modpath);
|
||||||
|
API_FCT(get_modpaths);
|
||||||
API_FCT(get_clientmodpath);
|
API_FCT(get_clientmodpath);
|
||||||
API_FCT(get_gamepath);
|
API_FCT(get_gamepath);
|
||||||
API_FCT(get_texturepath);
|
API_FCT(get_texturepath);
|
||||||
|
@ -112,6 +112,8 @@ private:
|
|||||||
|
|
||||||
static int l_get_modpath(lua_State *L);
|
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_clientmodpath(lua_State *L);
|
||||||
|
|
||||||
static int l_get_gamepath(lua_State *L);
|
static int l_get_gamepath(lua_State *L);
|
||||||
|
@ -44,6 +44,7 @@ set (UNITTEST_CLIENT_SRCS
|
|||||||
|
|
||||||
set (TEST_WORLDDIR ${CMAKE_CURRENT_SOURCE_DIR}/test_world)
|
set (TEST_WORLDDIR ${CMAKE_CURRENT_SOURCE_DIR}/test_world)
|
||||||
set (TEST_SUBGAME_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../games/devtest)
|
set (TEST_SUBGAME_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../games/devtest)
|
||||||
|
set (TEST_MOD_PATH ${CMAKE_CURRENT_SOURCE_DIR}/test_mod)
|
||||||
|
|
||||||
configure_file(
|
configure_file(
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/test_config.h.in"
|
"${CMAKE_CURRENT_SOURCE_DIR}/test_config.h.in"
|
||||||
|
@ -4,3 +4,4 @@
|
|||||||
|
|
||||||
#define TEST_WORLDDIR "@TEST_WORLDDIR@"
|
#define TEST_WORLDDIR "@TEST_WORLDDIR@"
|
||||||
#define TEST_SUBGAME_PATH "@TEST_SUBGAME_PATH@"
|
#define TEST_SUBGAME_PATH "@TEST_SUBGAME_PATH@"
|
||||||
|
#define TEST_MOD_PATH "@TEST_MOD_PATH@"
|
||||||
|
1
src/unittest/test_mod/test_mod/init.lua
Normal file
1
src/unittest/test_mod/test_mod/init.lua
Normal file
@ -0,0 +1 @@
|
|||||||
|
-- deliberately empty
|
2
src/unittest/test_mod/test_mod/mod.conf
Normal file
2
src/unittest/test_mod/test_mod/mod.conf
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
name = test_mod
|
||||||
|
description = A mod doing nothing, to test if MINETEST_MOD_PATH is recognised
|
@ -48,14 +48,20 @@ static TestServerModManager g_test_instance;
|
|||||||
void TestServerModManager::runTests(IGameDef *gamedef)
|
void TestServerModManager::runTests(IGameDef *gamedef)
|
||||||
{
|
{
|
||||||
const char *saved_env_mt_subgame_path = getenv("MINETEST_SUBGAME_PATH");
|
const char *saved_env_mt_subgame_path = getenv("MINETEST_SUBGAME_PATH");
|
||||||
|
const char *saved_env_mt_mod_path = getenv("MINETEST_MOD_PATH");
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
{
|
{
|
||||||
std::string subgame_path("MINETEST_SUBGAME_PATH=");
|
std::string subgame_path("MINETEST_SUBGAME_PATH=");
|
||||||
subgame_path.append(TEST_SUBGAME_PATH);
|
subgame_path.append(TEST_SUBGAME_PATH);
|
||||||
_putenv(subgame_path.c_str());
|
_putenv(subgame_path.c_str());
|
||||||
|
|
||||||
|
std::string mod_path("MINETEST_MOD_PATH=");
|
||||||
|
mod_path.append(TEST_MOD_PATH);
|
||||||
|
_putenv(mod_path.c_str());
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
setenv("MINETEST_SUBGAME_PATH", TEST_SUBGAME_PATH, 1);
|
setenv("MINETEST_SUBGAME_PATH", TEST_SUBGAME_PATH, 1);
|
||||||
|
setenv("MINETEST_MOD_PATH", TEST_MOD_PATH, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEST(testCreation);
|
TEST(testCreation);
|
||||||
@ -75,12 +81,21 @@ void TestServerModManager::runTests(IGameDef *gamedef)
|
|||||||
if (saved_env_mt_subgame_path)
|
if (saved_env_mt_subgame_path)
|
||||||
subgame_path.append(saved_env_mt_subgame_path);
|
subgame_path.append(saved_env_mt_subgame_path);
|
||||||
_putenv(subgame_path.c_str());
|
_putenv(subgame_path.c_str());
|
||||||
|
|
||||||
|
std::string mod_path("MINETEST_MOD_PATH=");
|
||||||
|
if (saved_env_mt_mod_path)
|
||||||
|
mod_path.append(saved_env_mt_mod_path);
|
||||||
|
_putenv(mod_path.c_str());
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (saved_env_mt_subgame_path)
|
if (saved_env_mt_subgame_path)
|
||||||
setenv("MINETEST_SUBGAME_PATH", saved_env_mt_subgame_path, 1);
|
setenv("MINETEST_SUBGAME_PATH", saved_env_mt_subgame_path, 1);
|
||||||
else
|
else
|
||||||
unsetenv("MINETEST_SUBGAME_PATH");
|
unsetenv("MINETEST_SUBGAME_PATH");
|
||||||
|
if (saved_env_mt_mod_path)
|
||||||
|
setenv("MINETEST_MOD_PATH", saved_env_mt_mod_path, 1);
|
||||||
|
else
|
||||||
|
unsetenv("MINETEST_MOD_PATH");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,6 +104,7 @@ void TestServerModManager::testCreation()
|
|||||||
std::string path = std::string(TEST_WORLDDIR) + DIR_DELIM + "world.mt";
|
std::string path = std::string(TEST_WORLDDIR) + DIR_DELIM + "world.mt";
|
||||||
Settings world_config;
|
Settings world_config;
|
||||||
world_config.set("gameid", "devtest");
|
world_config.set("gameid", "devtest");
|
||||||
|
world_config.set("load_mod_test_mod", "true");
|
||||||
UASSERTEQ(bool, world_config.updateConfigFile(path.c_str()), true);
|
UASSERTEQ(bool, world_config.updateConfigFile(path.c_str()), true);
|
||||||
ServerModManager sm(TEST_WORLDDIR);
|
ServerModManager sm(TEST_WORLDDIR);
|
||||||
}
|
}
|
||||||
@ -119,16 +135,21 @@ void TestServerModManager::testGetMods()
|
|||||||
UASSERTEQ(bool, mods.empty(), false);
|
UASSERTEQ(bool, mods.empty(), false);
|
||||||
|
|
||||||
// Ensure we found basenodes mod (part of devtest)
|
// Ensure we found basenodes mod (part of devtest)
|
||||||
|
// and test_mod (for testing MINETEST_MOD_PATH).
|
||||||
bool default_found = false;
|
bool default_found = false;
|
||||||
|
bool test_mod_found = false;
|
||||||
for (const auto &m : mods) {
|
for (const auto &m : mods) {
|
||||||
if (m.name == "basenodes")
|
if (m.name == "basenodes")
|
||||||
default_found = true;
|
default_found = true;
|
||||||
|
if (m.name == "test_mod")
|
||||||
|
test_mod_found = true;
|
||||||
|
|
||||||
// Verify if paths are not empty
|
// Verify if paths are not empty
|
||||||
UASSERTEQ(bool, m.path.empty(), false);
|
UASSERTEQ(bool, m.path.empty(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
UASSERTEQ(bool, default_found, true);
|
UASSERTEQ(bool, default_found, true);
|
||||||
|
UASSERTEQ(bool, test_mod_found, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestServerModManager::testGetModspec()
|
void TestServerModManager::testGetModspec()
|
||||||
|
Loading…
Reference in New Issue
Block a user