From 19e936362aab3806a9554ab811be0562dcb41509 Mon Sep 17 00:00:00 2001 From: William Breathitt Gray Date: Fri, 16 Sep 2022 07:19:44 -0400 Subject: [PATCH] Add support for MINETEST_USERDATA environment variable (#12639) The MINETEST_USER_PATH environment variable can be used to define a custom path for Minetest user data. If MINETEST_USER_PATH is empty or unset, the HOME (or APPDATA on Windows) environment variable is used as the default user data path; this ensures backwards compatibility with existing user setups. --- README.md | 6 +++--- doc/minetest.6 | 3 +++ src/main.cpp | 2 +- src/porting.cpp | 44 +++++++++++++++++++++++++++++++++----------- 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 0bc5d4b42..32dacd348 100644 --- a/README.md +++ b/README.md @@ -98,15 +98,15 @@ Where each location is on each platform: * Windows installed: * `bin` = `C:\Program Files\Minetest\bin (Depends on the install location)` * `share` = `C:\Program Files\Minetest (Depends on the install location)` - * `user` = `%APPDATA%\Minetest` + * `user` = `%APPDATA%\Minetest` or `%MINETEST_USER_PATH%` * Linux installed: * `bin` = `/usr/bin` * `share` = `/usr/share/minetest` - * `user` = `~/.minetest` + * `user` = `~/.minetest` or `$MINETEST_USER_PATH` * macOS: * `bin` = `Contents/MacOS` * `share` = `Contents/Resources` - * `user` = `Contents/User OR ~/Library/Application Support/minetest` + * `user` = `Contents/User` or `~/Library/Application Support/minetest` or `$MINETEST_USER_PATH` Worlds can be found as separate folders in: `user/worlds/` diff --git a/doc/minetest.6 b/doc/minetest.6 index 27a3d0024..06062721e 100644 --- a/doc/minetest.6 +++ b/doc/minetest.6 @@ -124,6 +124,9 @@ Colon delimited list of directories to search for games. .TP .B MINETEST_MOD_PATH Colon delimited list of directories to search for mods. +.TP +.B MINETEST_USER_PATH +Path to Minetest user data directory. .SH BUGS Please report all bugs at https://github.com/minetest/minetest/issues. diff --git a/src/main.cpp b/src/main.cpp index fa4fd604f..401f289df 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -527,7 +527,7 @@ static bool create_userdata_path() } #else // Create user data directory - success = fs::CreateDir(porting::path_user); + success = fs::CreateAllDirs(porting::path_user); #endif return success; diff --git a/src/porting.cpp b/src/porting.cpp index 09627431c..f8bd74f9a 100644 --- a/src/porting.cpp +++ b/src/porting.cpp @@ -422,11 +422,18 @@ bool setSystemPaths() path_share += DIR_DELIM ".."; } - // Use "C:\Users\\AppData\Roaming\" - DWORD len = GetEnvironmentVariable("APPDATA", buf, sizeof(buf)); - FATAL_ERROR_IF(len == 0 || len > sizeof(buf), "Failed to get APPDATA"); + // Use %MINETEST_USER_PATH% + DWORD len = GetEnvironmentVariable("MINETEST_USER_PATH", buf, sizeof(buf)); + FATAL_ERROR_IF(len > sizeof(buf), "Failed to get MINETEST_USER_PATH (too large for buffer)"); + if (len == 0) { + // Use "C:\Users\\AppData\Roaming\" + len = GetEnvironmentVariable("APPDATA", buf, sizeof(buf)); + FATAL_ERROR_IF(len == 0 || len > sizeof(buf), "Failed to get APPDATA"); + path_user = std::string(buf) + DIR_DELIM + PROJECT_NAME_C; + } else { + path_user = std::string(buf); + } - path_user = std::string(buf) + DIR_DELIM + PROJECT_NAME_C; return true; } @@ -486,8 +493,13 @@ bool setSystemPaths() } #ifndef __ANDROID__ - path_user = std::string(getHomeOrFail()) + DIR_DELIM "." - + PROJECT_NAME; + const char *const minetest_user_path = getenv("MINETEST_USER_PATH"); + if (minetest_user_path && minetest_user_path[0] != '\0') { + path_user = std::string(minetest_user_path); + } else { + path_user = std::string(getHomeOrFail()) + DIR_DELIM "." + + PROJECT_NAME; + } #endif return true; @@ -510,9 +522,14 @@ bool setSystemPaths() } CFRelease(resources_url); - path_user = std::string(getHomeOrFail()) - + "/Library/Application Support/" - + PROJECT_NAME; + const char *const minetest_user_path = getenv("MINETEST_USER_PATH"); + if (minetest_user_path && minetest_user_path[0] != '\0') { + path_user = std::string(minetest_user_path); + } else { + path_user = std::string(getHomeOrFail()) + + "/Library/Application Support/" + + PROJECT_NAME; + } return true; } @@ -522,8 +539,13 @@ bool setSystemPaths() bool setSystemPaths() { path_share = STATIC_SHAREDIR; - path_user = std::string(getHomeOrFail()) + DIR_DELIM "." - + lowercase(PROJECT_NAME); + const char *const minetest_user_path = getenv("MINETEST_USER_PATH"); + if (minetest_user_path && minetest_user_path[0] != '\0') { + path_user = std::string(minetest_user_path); + } else { + path_user = std::string(getHomeOrFail()) + DIR_DELIM "." + + lowercase(PROJECT_NAME); + } return true; }