Port PSN pkg decryption to pure Python (drop Wine requirement)

This commit is contained in:
2026-09-07 22:45:00 -04:00
parent d458a9859c
commit 2ba24028a0
7 changed files with 330 additions and 35 deletions
+18 -13
View File
@@ -36,12 +36,14 @@ converts PlayStation 1 ISO/CUE/BIN rips into PSP `EBOOT.PBP` homebrew.
## Requirements
- Linux + Python 3
- `PySide6` — the only Python dependency (`pip install -r requirements.txt`)
- `PySide6` + `pycryptodome` (`pip install -r requirements.txt`)
- `7z` (p7zip) — used to peek/extract disc images from store archives
- `pkg2zip` (bundled in `data/bin/`, run via Wine on Linux) — decrypts
NoPayStation `.pkg` files (see [NoPayStation](#4-nopaystation))
- PPSSPP (optional) — to launch discs from the details panel
NoPayStation `.pkg` files are decrypted by the bundled **pure-Python
decryptor** (`app/pkg.py`) — no Wine or `pkg2zip` required
(see [NoPayStation](#4-nopaystation)).
## Install
```bash
@@ -105,8 +107,10 @@ Discs are matched by hash first (most precise), then serial, then filename.
to drawn art when they're absent.
- `data/nps/` — NoPayStation TSV lists (cached here on first store scan; drop
`PSP_GAMES.tsv` / `PSX_GAMES.tsv` manually to work offline).
- `data/bin/pkg2zip.exe` — bundled `pkg2zip` binary (MIT, by mmozeiko) used to
decrypt NoPayStation `.pkg` files; see `data/bin/ATTRIBUTION.md`.
- `data/bin/pkg2zip.exe` — bundled `pkg2zip` binary (MIT, by mmozeiko) kept
only as an optional fallback decryptor; the app normally uses its own
pure-Python decryptor (`app/pkg.py`) and never needs Wine.
See `data/bin/ATTRIBUTION.md`.
- State dir (`~/.local/state/psp-preserve/` by default, or `$XDG_STATE_HOME/psp-preserve`):
- `library.sqlite` — the catalog + library database.
- `covers/` — downloaded cover cache.
@@ -276,16 +280,17 @@ next to the source selector.
Requirements & behaviour:
1. `pkg2zip` decrypts the `.pkg` files (they're encrypted PSN packages, not
ZIPs). A copy ships in `data/bin/pkg2zip.exe` and runs via **Wine** on
Linux — just make sure Wine is installed. You can also put a native
`pkg2zip` on `PATH` or set its path in **Settings → Store**.
1. `.pkg` files are decrypted by the built-in **pure-Python decryptor**
(`app/pkg.py`, powered by `pycryptodome` for speed) — no Wine and no
`pkg2zip` install needed. A bundled `pkg2zip.exe` is kept as a fallback
only, and only runs if Python decryption fails and Wine is present.
2. Set **NoPayStation output dir** in **Settings → Store** (default
`$PSP_STATE_DIR/nps`).
3. Downloading a PSP game writes `PSP/<TITLE_ID>/EBOOT.PBP`; a PS1 Classic
writes `PSX/<TITLE_ID>/EBOOT.PBP`. Both then show up in the **Library**
(PS1 Classics under **PS1**, PSP games under **Games**) and can be copied to
the PSP like any other item.
3. Downloading a PSP game writes `PSP/<TITLE_ID>/EBOOT.PBP` (plus
`PSP-KEY.EDAT` / `CONTENT.DAT` when the package ships them); a PS1 Classic
writes `PSX/<TITLE_ID>/EBOOT.PBP` (+ `DOCUMENT.DAT` and `KEYS.BIN`). Both
then show up in the **Library** (PS1 Classics under **PS1**, PSP games
under **Games**) and can be copied to the PSP like any other item.
4. The TSV lists are cached in `data/nps/` and refreshed on each store scan
(drop the `.tsv` files there manually to work offline).