Files
plugin-helper/README.md
T
2026-07-01 11:44:03 -07:00

177 lines
6.5 KiB
Markdown

# plugin-helper
`plugin-helper` is an early Python CLI for managing Beat Saber plugins in BSManager installs.
The first implementation focuses on safe local workflows:
- discover BSManager instances
- scan existing `Plugins/` and `Libs/` files
- read checked-in registry and per-version lockfiles
- generate a machine-readable install plan from local release assets
- apply exactly that plan and record install state
- uninstall only files recorded in install state
Default BSManager instance roots:
```text
/home/pleb/Windows/Users/pleb/BSManager/BSInstances
/home/pleb/.local/share/BSManager/BSInstances
```
Override with `--instances-root` or `PLUGIN_HELPER_INSTANCES_ROOT`. To search
multiple explicit roots, separate them with `:`.
## Managing Multiple Installs
The helper is intended to manage both the local Linux BSManager install and the
mounted Windows install. Lockfiles and registry entries are shared by Beat Saber
version, but install state is target-specific. When the same instance name
exists under both roots, such as `1.44.1`, give each install profile its own
state directory.
Copy the example profile config and adjust paths if needed:
```sh
cp plugin-helper.toml.example plugin-helper.local.toml
```
`plugin-helper.local.toml` is ignored by git. The default example uses this
repo-local convention:
```text
.state/ local Linux BSManager state
.state-windows/ mounted Windows BSManager state
```
Examples:
```sh
PYTHONPATH=src python -m plugin_helper \
--profile linux \
installed --instance 1.44.1
PYTHONPATH=src python -m plugin_helper \
--profile windows \
installed --instance 1.44.1
```
Explicit `--instances-root` and `--state-dir` still work and override profile
values. Do not reuse the same state directory for both targets when their
instance names match. The current state layout is keyed by instance name, so
sharing one state directory would mix bootstrap records, generated plans,
backups, and installed file records for different game trees.
## Commands
For normal use, run the Textual menu from the repo root:
```sh
PYTHONPATH=src python -m plugin_helper menu
```
The menu reads `plugin-helper.local.toml` when present, shows each discovered
Beat Saber install with its resolved state directory, and lets you toggle
managed plugins with arrow keys and Space. In the plugin table, use `d` to
disable all currently enabled managed plugins and `e` to enable all currently
disabled managed plugins.
The individual subcommands are mostly for automation and debugging. If you use
them, prefer `--profile linux` or `--profile windows`. Pass `--state-dir`
directly only when you intentionally want to override profile state or use the
default live state outside this repo.
Install assets are currently expected to already exist locally, usually under:
```text
.state/instances/<instance>/downloads/<plugin-id>/
```
For a second target-specific state directory, copy or re-download the same
locked assets under that state root before planning. For example:
```text
.state-windows/instances/<instance>/downloads/<plugin-id>/
```
## Beat Saber Data Backups
`backup-userdata` copies the mounted Windows `UserData` folder and Beat Saber
Windows app data into the adjacent `../backups` repo. With the Windows mount at
`~/Windows`, the helper infers Beat Saber's Windows app data as:
```text
/home/pleb/Windows/Users/pleb/AppData/LocalLow/Hyperbolic Magnetism/Beat Saber
```
Example manual backup after mounting Windows:
```sh
PYTHONPATH=src python -m plugin_helper \
--instances-root /home/pleb/Windows/Users/pleb/BSManager/BSInstances \
backup-userdata \
--instance 1.44.1
```
By default the backup repo receives plain copied files under
`../backups/beat-saber/UserData` and `../backups/beat-saber/AppData`, plus
`../backups/beat-saber/backup-descriptor.json` describing the source paths from
the latest backup run. Use
`--appdata-path <path>` if the Windows profile path ever differs, `--no-appdata`
for a `UserData`-only sync, or `--backup-root <path>` to choose a different
destination.
`restore-userdata` copies those backup trees back into a target instance. It
moves the current `UserData` and AppData trees aside first as
`<name>.pre-restore-<timestamp>` snapshots. On Linux BSManager installs,
AppData is restored into the BSManager SharedContent Proton prefix unless
`--appdata-path` is provided. If `backup-descriptor.json` is present, its
`instance` field must match `--instance`.
Example restore into the local Linux instance:
```sh
PYTHONPATH=src python -m plugin_helper \
--instances-root /home/pleb/.local/share/BSManager/BSInstances \
restore-userdata \
--instance 1.44.1
```
The backup intentionally omits bulky/generated data:
- `UserData/BeatLeader/Replays`
- `UserData/BeatLeader/ReplayerCache`
- `UserData/BeatLeader/LeaderboardsCache`
- `UserData/BeatLeader/ReplayHeadersCache`
- `UserData/ScoreSaber/Replays`
- `UserData/BeatSaberPlus/Cache`
- `UserData/BeatSaverNotifier.json`
- `UserData/Accsaber/PlayerScoreCache.json`
- `UserData/NalulunaAvatars/cache`
- `UserData/SongDetailsCache.proto`
- `AppData/com.unity.addressables`
- `*.log`
Other large folders seen in the 1.44.1 `UserData` tree are
`Custom Campaigns`, `SongCore`, `AssetBundleLoadingTools`, `NalulunaMenu`, and
`NalulunaSkybox`. Those are not skipped by default because they can contain
custom content or non-obvious user choices rather than pure cache data.
## Operational notes
- BSManager can inherit launch arguments configured in Steam for Beat Saber.
Check both places before debugging black screens or startup hangs. Duplicating
arguments such as `--no-yeet fpfc` can make the game fail command-line
parsing after BSIPA and plugins have already loaded.
- BSIPA is managed as a first-class bootstrap phase. The `bootstrap` command
applies the locked `bsipa` root archive, runs `IPA.exe -n` through Proton, and
records every bootstrap-relevant file under root `IPA.exe*`, `winhttp.dll`,
`Libs/`, and `IPA/`, including backups created during patching.
- If an instance lockfile includes `bsipa`, ordinary plugin plans require a
recorded bootstrap state plus a `Logs/_latest.log` that shows BSIPA startup.
Use `bootstrap-check` before planning a batch when you want a quick gate.
- Use [`docs/SMOKETEST.md`](docs/SMOKETEST.md) after installing or removing a
plugin batch. It documents the short Proton/BSManager launch loop, IPA log
checks, and teardown commands.
- The 1.44.1 migration tracker lives in
[`docs/notes/install-and-verify-plugins-1.44.1.md`](docs/notes/install-and-verify-plugins-1.44.1.md).