mirror of
https://github.com/drakmor/ShadowMountPlus.git
synced 2026-10-22 06:32:25 -05:00
Keep fakelib2 exclusive from global and emulator overlays
This commit is contained in:
1 parent
757f4514cc
commit
3190100de8
3 files changed
+43
-25
No files matched your search
@@ -79,11 +79,11 @@ Supported keys (all optional):
|
||||
- `legacy_mount_pfsc=1|0` (outer `.ffpfsc`; `1` selects the version 1.6 mount profile; default: `1`)
|
||||
- `nested_pfs_index_cache=1|0` (cache the containing PFS compressed-file index before attaching a nested image in legacy mode; default: `0`; optimized mode always requests it; the old `legacy_gddr5_cache` name remains accepted)
|
||||
- `backport_fakelib=1|0` (`1` mounts sandbox `fakelib` overlays for running games; default: `1`)
|
||||
- `update_emulators=1|0` (`1` updates all emulators with matching files in a game's own fakelib; default: `1`)
|
||||
- `update_emulators=1|0` (`1` updates all emulators with matching files in a game's own fakelib; `fakelib2` is excluded; default: `1`)
|
||||
- `emulators_path=<absolute_path>` (folder containing emulator update files; default: `/data/shadowmount/emus`)
|
||||
- `auto_update_ampr=1|0` (check for a new `libSceAmpr.sprx` 30 seconds after startup and every four hours; default: `0`)
|
||||
- `ampr_update_url=<http_or_https_url>` (AMPR emulator download URL; default: `https://github.com/drakmor/ampr_emu/releases/latest/download/libSceAmpr.sprx`)
|
||||
- `global_fakelib=1|0` (`1` enables the global fakelib overlay when the folder exists; default: `1`)
|
||||
- `global_fakelib=1|0` (`1` enables the global fakelib overlay when the folder exists; `fakelib2` remains exclusive; default: `1`)
|
||||
- `global_fakelib_path=<absolute_path>` (global fakelib folder; default: `/data/shadowmount/fakelib`)
|
||||
- `global_fakelib_priority=game|global` (overlay priority when both global and game fakelib exist; default: `game`)
|
||||
- `global_fakelib_exclude=<TITLE_ID>` (repeatable; disables the global fakelib overlay for matching titles)
|
||||
@@ -187,11 +187,11 @@ Backport overlay behavior:
|
||||
- The `backports` folder is ignored during normal game scanning.
|
||||
- A backport is applied automatically to the matching mounted game from any configured scan path.
|
||||
- If multiple scan paths provide the same title backport, the game's own scan path wins; otherwise scan path order is used.
|
||||
- ShadowMount+ checks the selected backport for `fakelib2` and then `fakelib`; if neither exists, it uses only `fakelib` from the original game source. The selected directory is mounted into the running game's sandbox `common/lib`.
|
||||
- If `update_emulators=1`, matching files from `emulators_path` replace files in the selected game fakelib. The cache is refreshed when its sources change and expires after seven days without a game launch.
|
||||
- ShadowMount+ checks the selected backport for `fakelib2` and then `fakelib`; if neither exists, it uses only `fakelib` from the original game source. The selected directory is mounted into the running game's sandbox `common/lib`. A backport `fakelib2` is always mounted directly and exclusively: neither emulator updates nor the global fakelib can replace or supplement it.
|
||||
- If `update_emulators=1`, matching files from `emulators_path` replace files in the selected game fakelib, except when `fakelib2` is selected. The cache is refreshed when its sources change and expires after seven days without a game launch.
|
||||
- With `auto_update_ampr=1`, ShadowMount+ checks for AMPR updates 30 seconds after startup and every four hours. It downloads a missing or newer emulator and displays a notification after a successful update.
|
||||
- The backport notification adds `Emulators updated` when emulator files are updated for the launched game.
|
||||
- If both global and per-game fakelib exist, they are combined in the game cache according to `global_fakelib_priority`. Without a per-game fakelib, the global folder is mounted directly.
|
||||
- If both global and per-game fakelib exist, they are combined in the game cache according to `global_fakelib_priority`, unless the selected backport contains `fakelib2`. Without a per-game fakelib, the global folder is mounted directly.
|
||||
- Use repeatable `global_fakelib_exclude=<TITLE_ID>` entries to skip the global fakelib for specific games without disabling per-game fakelib.
|
||||
- `backport_fakelib=0` disables the sandbox `fakelib` watcher, including global fakelib and emulator updates.
|
||||
- For `backport_fakelib` to work correctly, the standalone `BackPork` payload must be disabled. Running both at the same time will conflict.
|
||||
|
||||
+3
-2
@@ -135,7 +135,7 @@
|
||||
|
||||
# Updates for multiple emulators in the game fakelib:
|
||||
# 1/true/yes/on -> cache the game's fakelib before launch and replace matching
|
||||
# cached files from emulators_path
|
||||
# cached files from emulators_path; fakelib2 is never changed
|
||||
# 0/false/no/off -> disable emulator updates
|
||||
# Default: 1
|
||||
# update_emulators=1
|
||||
@@ -159,7 +159,8 @@
|
||||
# ampr_update_url=https://github.com/drakmor/ampr_emu/releases/latest/download/libSceAmpr.sprx
|
||||
|
||||
# Global fakelib overlay:
|
||||
# 1/true/yes/on -> use global fakelib for every tracked game when present
|
||||
# 1/true/yes/on -> use global fakelib for every tracked game when present;
|
||||
# fakelib2 always remains exclusive when present
|
||||
# 0/false/no/off -> do not use the global fakelib folder
|
||||
# Default: 1
|
||||
# global_fakelib=1
|
||||
|
||||
+35
-18
@@ -67,6 +67,12 @@ typedef struct {
|
||||
char emulators_path[MAX_PATH];
|
||||
} fakelib_cache_context_t;
|
||||
|
||||
typedef enum {
|
||||
FAKELIB_SOURCE_NONE = 0,
|
||||
FAKELIB_SOURCE_COMPOSABLE,
|
||||
FAKELIB_SOURCE_FAKELIB2,
|
||||
} fakelib_source_kind_t;
|
||||
|
||||
static fakelib_session_t g_fakelib_mount;
|
||||
static pthread_mutex_t g_fakelib_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_mutex_t g_fakelib_cache_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
@@ -207,7 +213,7 @@ static bool resolve_sandbox_mount_path(const char *title_id,
|
||||
return found;
|
||||
}
|
||||
|
||||
static bool resolve_game_fakelib_source_for_path(
|
||||
static fakelib_source_kind_t resolve_game_fakelib_source_for_path(
|
||||
const char *title_id, const char *game_path,
|
||||
char source_path[MAX_PATH]) {
|
||||
source_path[0] = '\0';
|
||||
@@ -219,10 +225,13 @@ static bool resolve_game_fakelib_source_for_path(
|
||||
const struct {
|
||||
const char *root;
|
||||
const char *directory;
|
||||
fakelib_source_kind_t kind;
|
||||
} candidates[] = {
|
||||
{has_backport ? backport_path : NULL, "fakelib2"},
|
||||
{has_backport ? backport_path : NULL, "fakelib"},
|
||||
{has_game ? game_path : NULL, "fakelib"},
|
||||
{has_backport ? backport_path : NULL, "fakelib2",
|
||||
FAKELIB_SOURCE_FAKELIB2},
|
||||
{has_backport ? backport_path : NULL, "fakelib",
|
||||
FAKELIB_SOURCE_COMPOSABLE},
|
||||
{has_game ? game_path : NULL, "fakelib", FAKELIB_SOURCE_COMPOSABLE},
|
||||
};
|
||||
struct stat st;
|
||||
for (size_t i = 0; i < sizeof(candidates) / sizeof(candidates[0]); ++i) {
|
||||
@@ -232,16 +241,17 @@ static bool resolve_game_fakelib_source_for_path(
|
||||
candidates[i].root, candidates[i].directory);
|
||||
if (written > 0 && (size_t)written < MAX_PATH &&
|
||||
stat(source_path, &st) == 0 && S_ISDIR(st.st_mode)) {
|
||||
return true;
|
||||
return candidates[i].kind;
|
||||
}
|
||||
}
|
||||
|
||||
source_path[0] = '\0';
|
||||
return false;
|
||||
return FAKELIB_SOURCE_NONE;
|
||||
}
|
||||
|
||||
static bool resolve_game_fakelib_source(const char *title_id,
|
||||
char source_path[MAX_PATH]) {
|
||||
static fakelib_source_kind_t
|
||||
resolve_game_fakelib_source(const char *title_id,
|
||||
char source_path[MAX_PATH]) {
|
||||
char game_path[MAX_PATH];
|
||||
if (!read_mount_link(title_id, game_path, sizeof(game_path)))
|
||||
game_path[0] = '\0';
|
||||
@@ -994,8 +1004,9 @@ static void prepare_title_cache(const char *title_id, const char *game_path) {
|
||||
return;
|
||||
|
||||
char game_source_path[MAX_PATH];
|
||||
if (!resolve_game_fakelib_source_for_path(title_id, game_path,
|
||||
game_source_path)) {
|
||||
fakelib_source_kind_t source_kind = resolve_game_fakelib_source_for_path(
|
||||
title_id, game_path, game_source_path);
|
||||
if (source_kind != FAKELIB_SOURCE_COMPOSABLE) {
|
||||
remove_title_cache(title_id);
|
||||
return;
|
||||
}
|
||||
@@ -1151,12 +1162,16 @@ void sm_fakelib_game_on_exec(pid_t pid, const char *title_id,
|
||||
}
|
||||
}
|
||||
|
||||
char game_source_path[MAX_PATH];
|
||||
char global_source_path[MAX_PATH];
|
||||
char mount_path[MAX_PATH];
|
||||
bool has_game = resolve_game_fakelib_source(title_id, game_source_path);
|
||||
bool has_global =
|
||||
resolve_global_fakelib_source(title_id, global_source_path);
|
||||
char game_source_path[MAX_PATH] = {0};
|
||||
char global_source_path[MAX_PATH] = {0};
|
||||
char mount_path[MAX_PATH] = {0};
|
||||
fakelib_source_kind_t source_kind =
|
||||
resolve_game_fakelib_source(title_id, game_source_path);
|
||||
bool has_game = source_kind != FAKELIB_SOURCE_NONE;
|
||||
bool allows_composition = source_kind != FAKELIB_SOURCE_FAKELIB2;
|
||||
bool has_global = allows_composition &&
|
||||
resolve_global_fakelib_source(title_id,
|
||||
global_source_path);
|
||||
if (!has_global && !has_game) {
|
||||
pthread_mutex_unlock(&g_fakelib_mutex);
|
||||
return;
|
||||
@@ -1168,7 +1183,7 @@ void sm_fakelib_game_on_exec(pid_t pid, const char *title_id,
|
||||
size_t emulator_file_count = 0;
|
||||
bool cache_resolved = false;
|
||||
bool cache_includes_global = false;
|
||||
if (has_game) {
|
||||
if (source_kind == FAKELIB_SOURCE_COMPOSABLE) {
|
||||
char cache_path[MAX_PATH];
|
||||
cache_resolved = resolve_cached_fakelib(
|
||||
title_id, game_source_path, cache_path, &emulator_file_count,
|
||||
@@ -1198,7 +1213,9 @@ void sm_fakelib_game_on_exec(pid_t pid, const char *title_id,
|
||||
sizeof(g_fakelib_mount.mount_path));
|
||||
|
||||
const char *source_path = has_game ? game_source_path : global_source_path;
|
||||
const char *label = has_game ? "game" : "global";
|
||||
const char *label = !allows_composition
|
||||
? "fakelib2"
|
||||
: (has_game ? "game" : "global");
|
||||
if (!track_fakelib_overlay(title_id, source_path, mount_path, label)) {
|
||||
(void)cleanup_fakelib_mount();
|
||||
pthread_mutex_unlock(&g_fakelib_mutex);
|
||||
|
||||
Reference in new issue
Block a user