From c033b988ca43b388d014797a3c70e0fa8b7dac34 Mon Sep 17 00:00:00 2001 From: niklascfw Date: Thu, 12 Nov 2026 22:53:28 +0100 Subject: [PATCH] Update mode: stop deleting user-installed apps and sysmodules The update list deleted ~80 apps the pack never shipped (Goldleaf, linkalho, Moonlight, NX-Shell, ...), Downloader sysmodules (SysDVR, MissionControl, ldn_mitm, Fizeau), game title ID folders (mods/cheats), and user folders like "Patched Apps" or "games". Anything a user installed via OmniNX Downloader was wiped on every update. Update mode only runs on an existing OmniNX install, so the list now keeps only what the pack ships, components OmniNX dropped, and boot-relevant housekeeping. Foreign-pack leftovers stay in the clean list. Also drops 15 entries nested in deleted folders, a case-duplicate (themezernx) and a trailing-space path. tools/audit_update_list.py checks the list against the OmniNX repo. --- .../Data/DeletionLists.Generated.cs | 114 ---------------- source/deletion_lists_update.h | 124 ++---------------- tools/audit_update_list.py | 77 +++++++++++ 3 files changed, 87 insertions(+), 228 deletions(-) create mode 100644 tools/audit_update_list.py diff --git a/desktop/OmniNX.DesktopInstaller/Data/DeletionLists.Generated.cs b/desktop/OmniNX.DesktopInstaller/Data/DeletionLists.Generated.cs index 5dce541..baa7e4e 100644 --- a/desktop/OmniNX.DesktopInstaller/Data/DeletionLists.Generated.cs +++ b/desktop/OmniNX.DesktopInstaller/Data/DeletionLists.Generated.cs @@ -162,7 +162,6 @@ public static partial class DeletionLists @"atmosphere\contents\0000000000534C56", @"atmosphere\contents\00FF0000B378D640", @"atmosphere\contents\00FF0000636C6BFF", - @"atmosphere\contents\00FF0000A53BB665", @"atmosphere\contents\0100000000000008", @"atmosphere\contents\010000000000000D", @"atmosphere\contents\010000000000002B", @@ -173,21 +172,14 @@ public static partial class DeletionLists @"atmosphere\contents\010000000000003C", @"atmosphere\contents\0100000000000042", @"atmosphere\contents\0100000000000895", - @"atmosphere\contents\0100000000000F12", @"atmosphere\contents\0100000000001000", @"atmosphere\contents\0100000000001007", @"atmosphere\contents\0100000000001013", @"atmosphere\contents\010000000000DA7A", - @"atmosphere\contents\010000000000bd00", - @"atmosphere\contents\01006a800016e000", - @"atmosphere\contents\01009D901BC56000", - @"atmosphere\contents\0100A3900C3E2000", - @"atmosphere\contents\0100F43008C44000", @"atmosphere\contents\050000BADDAD0000", @"atmosphere\contents\4200000000000000", @"atmosphere\contents\420000000000000B", @"atmosphere\contents\420000000000000E", - @"atmosphere\contents\4200000000000010", @"atmosphere\contents\4200000000000FFF", @"atmosphere\contents\420000000007E51A", @"atmosphere\contents\420000000007E51B", @@ -197,14 +189,10 @@ public static partial class DeletionLists public static readonly string[] atmosphere_files_to_delete = { - @"atmosphere\config\exosphere.ini", - @"atmosphere\config\stratosphere.ini", @"atmosphere\hbl.nsp", @"atmosphere\package3", @"atmosphere\reboot_payload.bin", @"atmosphere\stratosphere.romfs", - @"atmosphere\kips\loader.kip", - @"atmosphere\kips\hoc.kip", }; public static readonly string[] bootloader_dirs_to_delete = @@ -231,14 +219,9 @@ public static partial class DeletionLists public static readonly string[] config_dirs_to_delete = { - @"config\aio-switch-updater", - @"config\blue_pack_updater", - @"config\kefir-updater", @"config\nx-hbmenu", @"config\quickntp", - @"config\sys-con", @"config\sys-patch", - @"config\uberhand", @"config\ultrahand", }; @@ -256,124 +239,32 @@ public static partial class DeletionLists @"switch\.packages\Package Manager", @"switch\.packages\RebootNX", @"switch\.overlays\.offload", - @"switch\90DNS_tester", - @"switch\aio-switch-updater", - @"switch\amsPLUS-downloader", - @"switch\appstore", - @"switch\AtmoXL-Titel-Installer", @"switch\Benchmark-Toolbox", @"switch\breeze", @"switch\cheats-updater", @"switch\chiaki", - @"switch\ChoiDujourNX", - @"switch\crash_ams", @"switch\Daybreak", @"switch\DNS-Block_Tester", @"switch\DNS_mitm Tester", - @"switch\EdiZon", - @"switch\Fizeau", - @"switch\FTPD", @"switch\Furmark-NX", - @"switch\fw-downloader", - @"switch\gamecard_installer", - @"switch\Goldleaf", - @"switch\haze", @"switch\JKSV", - @"switch\kefir-updater", - @"switch\ldnmitm_config", @"switch\Linkalho", - @"switch\Moonlight-Switch", - @"switch\Neumann", - @"switch\NX-Activity-Log", - @"switch\NX-Save-Sync", - @"switch\NX-Shell", - @"switch\NX-Update-Checker ", @"switch\NXGallery", - @"switch\NXRemoteLauncher", - @"switch\NXThemesInstaller", - @"switch\nxdumptool", - @"switch\nxmtp", - @"switch\Payload_launcher", - @"switch\Reboot", - @"switch\reboot_to_argonNX", - @"switch\reboot_to_hekate", - @"switch\Shutdown_System", @"switch\SimpleModAlchemist", @"switch\SimpleModDownloader", - @"switch\SimpleModManager", @"switch\sphaira", - @"switch\studious-pancake", - @"switch\Switch-Time", - @"switch\SwitchIdent", @"switch\Switch_themes_Installer", @"switch\swr-ini-tool", @"switch\Sys-Clk Manager", - @"switch\Sys-Con", - @"switch\sys-clk-manager", - @"switch\themezer-nx", @"switch\ThemezerNX", - @"switch\themezernx", @"switch\tinwoo", @"switch\Ultrahand-Reload", }; public static readonly string[] switch_files_to_delete = { - @"switch\90DNS_tester\90DNS_tester.nro", - @"switch\Benchmark-Toolbox\Benchmark-Toolbox.nro", - @"switch\breeze.nro", - @"switch\cheats-updater.nro", - @"switch\chiaki.nro", - @"switch\ChoiDujourNX.nro", - @"switch\daybreak.nro", - @"switch\DBI.nro", @"switch\DBI\DBI.nro", - @"switch\DBI\DBI_810_DE.nro", - @"switch\DBI\DBI_810_EN.nro", - @"switch\DBI\DBI_845_DE.nro", - @"switch\DBI\DBI_845_EN.nro", - @"switch\DBI\DBI_849_DE.nro", - @"switch\DBI\DBI_849_EN.nro", - @"switch\DBI_810_DE\DBI_810.nro", - @"switch\DBI_810_DE\DBI_810_DE.nro", - @"switch\DBI_810_EN\DBI_810_EN.nro", - @"switch\DBI_RU\DBI_RU.nro", @"switch\DBI\DBI_EN.nro", - @"switch\DBI_DE\DBI_DE.nro", - @"switch\DNS-Block_Tester\dns_tester.nro", - @"switch\DNS_mitm Tester.nro", - @"switch\EdiZon.nro", - @"switch\Fizeau.nro", - @"switch\Furmark-NX\Furmark-NX.nro", - @"switch\Goldleaf.nro", - @"switch\haze.nro", - @"switch\JKSV.nro", - @"switch\ldnmitm_config.nro", - @"switch\linkalho.nro", - @"switch\Moonlight-Switch.nro", - @"switch\Neumann.nro", - @"switch\NX-Shell.nro", - @"switch\NXGallery.nro", - @"switch\NXThemesInstaller.nro", - @"switch\nxdumptool.nro", - @"switch\nxtc.bin", - @"switch\reboot_to_payload.nro", - @"switch\SimpleModAlchemist\Simple_Mod_Alchemist.nro", - @"switch\SimpleModDownloader.nro", - @"switch\SimpleModManager.nro", - @"switch\sphaira.nro", - @"switch\swr-ini-tool\swr-ini-tool.nro", - @"switch\SwitchIdent.nro", - @"switch\Switch_themes_Installer\NXThemesInstaller.nro", - @"switch\Sys-Clk Manager\sys-clk-manager.nro", - @"switch\Sys-Con.nro", - @"switch\sys-clk-manager.nro", - @"switch\ThemezerNX\themezer-nx.nro", - @"switch\tinfoil.nro", - @"switch\tinfoil\tinfoil.nro", - @"switch\tinwoo.nro", - @"switch\tinwoo\tinwoo.nro", - @"switch\Ultrahand-Reload\Ultrahand-Reload.nro", @"switch\.packages\boot_package.ini", @"switch\.packages\package.ini", @"switch\.overlays\DNS-MITM_Manager.ovl", @@ -408,15 +299,10 @@ public static partial class DeletionLists public static readonly string[] misc_dirs_to_delete = { @"argon", - @"games", @"hwtest", - @"NSPs (Tools)", - @"Patched Apps", @"SaltySD\flags", - @"scripts", @"switch\tinfoil\db", @"themes\systemData", - @"tools", @"warmboot_mariko", }; diff --git a/source/deletion_lists_update.h b/source/deletion_lists_update.h index 876304f..67fbe2c 100644 --- a/source/deletion_lists_update.h +++ b/source/deletion_lists_update.h @@ -1,6 +1,16 @@ /* * OmniNX Installer - Deletion Lists for Update Mode * Selective deletion when OmniNX is already installed. + * + * Update mode only runs on an existing OmniNX install (manifest.ini), so this + * list only needs: + * - paths the current pack ships (removed first so the copy replaces them cleanly), + * - components OmniNX used to ship and dropped (e.g. sys-ticon), + * - boot-relevant housekeeping (logs, foreign exefs/kip patches, legacy boot files). + * Do NOT add apps, sysmodules or game title IDs a user can install on their own + * (e.g. via OmniNX Downloader); foreign-pack leftovers belong in the clean list. + * Check with: python3 tools/audit_update_list.py + * After editing, regenerate the desktop list: python3 tools/generate_deletion_lists.py */ #pragma once @@ -41,7 +51,6 @@ static const char* atmosphere_contents_dirs_to_delete[] = { "sd:/atmosphere/contents/0000000000534C56", "sd:/atmosphere/contents/00FF0000B378D640", "sd:/atmosphere/contents/00FF0000636C6BFF", - "sd:/atmosphere/contents/00FF0000A53BB665", "sd:/atmosphere/contents/0100000000000008", "sd:/atmosphere/contents/010000000000000D", "sd:/atmosphere/contents/010000000000002B", @@ -52,21 +61,14 @@ static const char* atmosphere_contents_dirs_to_delete[] = { "sd:/atmosphere/contents/010000000000003C", "sd:/atmosphere/contents/0100000000000042", "sd:/atmosphere/contents/0100000000000895", - "sd:/atmosphere/contents/0100000000000F12", "sd:/atmosphere/contents/0100000000001000", "sd:/atmosphere/contents/0100000000001007", "sd:/atmosphere/contents/0100000000001013", "sd:/atmosphere/contents/010000000000DA7A", - "sd:/atmosphere/contents/010000000000bd00", - "sd:/atmosphere/contents/01006a800016e000", - "sd:/atmosphere/contents/01009D901BC56000", - "sd:/atmosphere/contents/0100A3900C3E2000", - "sd:/atmosphere/contents/0100F43008C44000", "sd:/atmosphere/contents/050000BADDAD0000", "sd:/atmosphere/contents/4200000000000000", "sd:/atmosphere/contents/420000000000000B", "sd:/atmosphere/contents/420000000000000E", - "sd:/atmosphere/contents/4200000000000010", "sd:/atmosphere/contents/4200000000000FFF", "sd:/atmosphere/contents/420000000007E51A", "sd:/atmosphere/contents/420000000007E51B", @@ -77,14 +79,10 @@ static const char* atmosphere_contents_dirs_to_delete[] = { // Atmosphere files to delete static const char* atmosphere_files_to_delete[] = { - "sd:/atmosphere/config/exosphere.ini", - "sd:/atmosphere/config/stratosphere.ini", "sd:/atmosphere/hbl.nsp", "sd:/atmosphere/package3", "sd:/atmosphere/reboot_payload.bin", "sd:/atmosphere/stratosphere.romfs", - "sd:/atmosphere/kips/loader.kip", - "sd:/atmosphere/kips/hoc.kip", NULL }; @@ -114,14 +112,9 @@ static const char* bootloader_files_to_delete[] = { // Config directories to delete static const char* config_dirs_to_delete[] = { - "sd:/config/aio-switch-updater", - "sd:/config/blue_pack_updater", - "sd:/config/kefir-updater", "sd:/config/nx-hbmenu", "sd:/config/quickntp", - "sd:/config/sys-con", "sd:/config/sys-patch", - "sd:/config/uberhand", "sd:/config/ultrahand", NULL }; @@ -142,63 +135,24 @@ static const char* switch_dirs_to_delete[] = { "sd:/switch/.packages/Package Manager", "sd:/switch/.packages/RebootNX", "sd:/switch/.overlays/.offload", - "sd:/switch/90DNS_tester", - "sd:/switch/aio-switch-updater", - "sd:/switch/amsPLUS-downloader", - "sd:/switch/appstore", - "sd:/switch/AtmoXL-Titel-Installer", "sd:/switch/Benchmark-Toolbox", "sd:/switch/breeze", "sd:/switch/cheats-updater", "sd:/switch/chiaki", - "sd:/switch/ChoiDujourNX", - "sd:/switch/crash_ams", "sd:/switch/Daybreak", "sd:/switch/DNS-Block_Tester", "sd:/switch/DNS_mitm Tester", - "sd:/switch/EdiZon", - "sd:/switch/Fizeau", - "sd:/switch/FTPD", "sd:/switch/Furmark-NX", - "sd:/switch/fw-downloader", - "sd:/switch/gamecard_installer", - "sd:/switch/Goldleaf", - "sd:/switch/haze", "sd:/switch/JKSV", - "sd:/switch/kefir-updater", - "sd:/switch/ldnmitm_config", "sd:/switch/Linkalho", - "sd:/switch/Moonlight-Switch", - "sd:/switch/Neumann", - "sd:/switch/NX-Activity-Log", - "sd:/switch/NX-Save-Sync", - "sd:/switch/NX-Shell", - "sd:/switch/NX-Update-Checker ", "sd:/switch/NXGallery", - "sd:/switch/NXRemoteLauncher", - "sd:/switch/NXThemesInstaller", - "sd:/switch/nxdumptool", - "sd:/switch/nxmtp", - "sd:/switch/Payload_launcher", - "sd:/switch/Reboot", - "sd:/switch/reboot_to_argonNX", - "sd:/switch/reboot_to_hekate", - "sd:/switch/Shutdown_System", "sd:/switch/SimpleModAlchemist", "sd:/switch/SimpleModDownloader", - "sd:/switch/SimpleModManager", "sd:/switch/sphaira", - "sd:/switch/studious-pancake", - "sd:/switch/Switch-Time", - "sd:/switch/SwitchIdent", "sd:/switch/Switch_themes_Installer", "sd:/switch/swr-ini-tool", "sd:/switch/Sys-Clk Manager", - "sd:/switch/Sys-Con", - "sd:/switch/sys-clk-manager", - "sd:/switch/themezer-nx", "sd:/switch/ThemezerNX", - "sd:/switch/themezernx", "sd:/switch/tinwoo", "sd:/switch/Ultrahand-Reload", NULL @@ -206,61 +160,8 @@ static const char* switch_dirs_to_delete[] = { // Switch files (NRO) to delete static const char* switch_files_to_delete[] = { - "sd:/switch/90DNS_tester/90DNS_tester.nro", - "sd:/switch/Benchmark-Toolbox/Benchmark-Toolbox.nro", - "sd:/switch/breeze.nro", - "sd:/switch/cheats-updater.nro", - "sd:/switch/chiaki.nro", - "sd:/switch/ChoiDujourNX.nro", - "sd:/switch/daybreak.nro", - "sd:/switch/DBI.nro", "sd:/switch/DBI/DBI.nro", - "sd:/switch/DBI/DBI_810_DE.nro", - "sd:/switch/DBI/DBI_810_EN.nro", - "sd:/switch/DBI/DBI_845_DE.nro", - "sd:/switch/DBI/DBI_845_EN.nro", - "sd:/switch/DBI/DBI_849_DE.nro", - "sd:/switch/DBI/DBI_849_EN.nro", - "sd:/switch/DBI_810_DE/DBI_810.nro", - "sd:/switch/DBI_810_DE/DBI_810_DE.nro", - "sd:/switch/DBI_810_EN/DBI_810_EN.nro", - "sd:/switch/DBI_RU/DBI_RU.nro", "sd:/switch/DBI/DBI_EN.nro", - "sd:/switch/DBI_DE/DBI_DE.nro", - "sd:/switch/DNS-Block_Tester/dns_tester.nro", - "sd:/switch/DNS_mitm Tester.nro", - "sd:/switch/EdiZon.nro", - "sd:/switch/Fizeau.nro", - "sd:/switch/Furmark-NX/Furmark-NX.nro", - "sd:/switch/Goldleaf.nro", - "sd:/switch/haze.nro", - "sd:/switch/JKSV.nro", - "sd:/switch/ldnmitm_config.nro", - "sd:/switch/linkalho.nro", - "sd:/switch/Moonlight-Switch.nro", - "sd:/switch/Neumann.nro", - "sd:/switch/NX-Shell.nro", - "sd:/switch/NXGallery.nro", - "sd:/switch/NXThemesInstaller.nro", - "sd:/switch/nxdumptool.nro", - "sd:/switch/nxtc.bin", - "sd:/switch/reboot_to_payload.nro", - "sd:/switch/SimpleModAlchemist/Simple_Mod_Alchemist.nro", - "sd:/switch/SimpleModDownloader.nro", - "sd:/switch/SimpleModManager.nro", - "sd:/switch/sphaira.nro", - "sd:/switch/swr-ini-tool/swr-ini-tool.nro", - "sd:/switch/SwitchIdent.nro", - "sd:/switch/Switch_themes_Installer/NXThemesInstaller.nro", - "sd:/switch/Sys-Clk Manager/sys-clk-manager.nro", - "sd:/switch/Sys-Con.nro", - "sd:/switch/sys-clk-manager.nro", - "sd:/switch/ThemezerNX/themezer-nx.nro", - "sd:/switch/tinfoil.nro", - "sd:/switch/tinfoil/tinfoil.nro", - "sd:/switch/tinwoo.nro", - "sd:/switch/tinwoo/tinwoo.nro", - "sd:/switch/Ultrahand-Reload/Ultrahand-Reload.nro", "sd:/switch/.packages/boot_package.ini", "sd:/switch/.packages/package.ini", "sd:/switch/.overlays/DNS-MITM_Manager.ovl", @@ -297,15 +198,10 @@ static const char* root_files_to_delete[] = { // Miscellaneous directories to delete static const char* misc_dirs_to_delete[] = { "sd:/argon", - "sd:/games", "sd:/hwtest", - "sd:/NSPs (Tools)", - "sd:/Patched Apps", "sd:/SaltySD/flags", - "sd:/scripts", "sd:/switch/tinfoil/db", "sd:/themes/systemData", - "sd:/tools", "sd:/warmboot_mariko", NULL }; diff --git a/tools/audit_update_list.py b/tools/audit_update_list.py new file mode 100644 index 0000000..b0ec31b --- /dev/null +++ b/tools/audit_update_list.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +"""Audit source/deletion_lists_update.h against the OmniNX pack repo. + +Lists every update-mode deletion entry and whether the pack ships it now, +shipped it in the past, or never did. Entries under switch/ or config/ that +the pack never shipped are almost always user installs and should not be in +the update list (see the header comment in deletion_lists_update.h). + +usage: python3 tools/audit_update_list.py ../OmniNX +""" + +import re +import subprocess +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +UPDATE_H = ROOT / "source" / "deletion_lists_update.h" +PACK_PREFIX = re.compile(r"^(?:variants/[^/]+/(?:extras/hekate-ams-pro/)?|staging/)") + +# Not shipped as files, but reset on purpose during updates. +INTENTIONAL = { + "config/nx-hbmenu", # hbmenu settings (hbmenu.nro is shipped) + "config/sys-patch", # sys-patch settings (sys-patch is shipped) + "switch/tinfoil/db", # stale title DB cache +} + + +def pack_paths(repo: Path, all_history: bool) -> list[str]: + if all_history: + cmd = ["git", "-C", str(repo), "log", "--all", "--name-only", "--format=", "--", "variants", "staging"] + else: + cmd = ["git", "-C", str(repo), "ls-files", "variants", "staging"] + out = subprocess.run(cmd, check=True, capture_output=True, text=True).stdout + paths = set() + for line in out.splitlines(): + line = line.strip() + if line and PACK_PREFIX.match(line): + paths.add(PACK_PREFIX.sub("", line).lower()) + return sorted(paths) + + +def covered(paths: list[str], entry: str) -> bool: + return any(p == entry or p.startswith(entry + "/") for p in paths) + + +def main() -> int: + if len(sys.argv) != 2: + print(__doc__.strip()) + return 2 + repo = Path(sys.argv[1]) + current = pack_paths(repo, all_history=False) + history = pack_paths(repo, all_history=True) + + text = UPDATE_H.read_text(encoding="utf-8") + suspicious = 0 + for m in re.finditer(r"static const char\*\s+(\w+)\[\]\s*=\s*\{(.*?)\};", text, re.S): + for entry in re.findall(r'"sd:/([^"]+)"', m.group(2)): + e = entry.lower() + if covered(current, e): + state = "shipped" + elif covered(history, e): + state = "dropped" + else: + state = "never" + flag = "" + if state == "never" and e not in INTENTIONAL and (e.startswith("switch/") or e.startswith("config/")): + flag = " <-- user install? remove from update list" + suspicious += 1 + print(f"{state:8} {m.group(1):36} {entry}{flag}") + + print(f"\n{suspicious} suspicious entr{'y' if suspicious == 1 else 'ies'}") + return 1 if suspicious else 0 + + +if __name__ == "__main__": + sys.exit(main())