mirror of
https://github.com/bsgonzalezq/ps4-pkg-title-renamer.git
synced 2026-10-06 09:00:08 +02:00
PS5: use contentVersion as the version; 3-part version tags
- PS5 pkgs and game folders now use contentVersion (the game version including updates, e.g. 02.002.000 -> [v2.002.000]); masterVersion can stay at 01.00 when the game is at 2.002. masterVersion is only used when there's no contentVersion. - version_tag handles any number of parts: 01.000.000 -> v1.000.000. - db lines recorded for PS5 items with masterVersion (v1.3.0) are moved to the new version, keeping edits, instead of leaving stale lines. - README / usage / option help updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0811065298
commit
fc980f58e0
2 files changed
+24
-14
No files matched your search
@@ -461,13 +461,16 @@ Bloodborne/
|
||||
└── Bloodborne The Old Hunters [v1.00].pkg
|
||||
```
|
||||
|
||||
- **Version:** read from the PKG's `param.sfo`, and the field used depends on the type. Leading zeros are dropped, so `01.09` becomes `v1.09`:
|
||||
- **Version:** read from the PKG's `param.sfo`, or `param.json` for PS5. The field used depends on the type:
|
||||
|
||||
| Type | Field | Why |
|
||||
|---|---|---|
|
||||
| patch | `APP_VER` | the version the patch updates the game to. A patch's `VERSION` is usually `01.00` |
|
||||
| base game | `VERSION` | the version the base PKG was built at, e.g. `v1.07` for a base PKG that already contains updates. A base PKG's `APP_VER` is always `01.00` |
|
||||
| DLC | `VERSION` | DLC has no `APP_VER` |
|
||||
| PS5 PKG or game folder | `contentVersion` | the game version including updates, e.g. `02.002.000` gives `v2.002.000`. `masterVersion` is only used if there's no `contentVersion` |
|
||||
|
||||
Leading zeros of the first number are dropped, and the rest is kept as is: `01.09` becomes `v1.09`, and `01.000.000` becomes `v1.000.000`.
|
||||
- **Content ID:** the PKG's full content ID, `<region prefix>-<title ID>_00-<label>`. It's unique per PKG: each DLC has its own, and a base game and its patches share one. The prefix also shows the region: `UP` = USA, `EP` = EUR, `JP` = JPN, `HP` = Asia.
|
||||
- **Folders:** version, content ID and type are only added to `.pkg` files and to [game folders](#game-folders-ps5-and-dumped-ps4-games). A normal game folder holds several PKGs of different versions and types, so it only gets title, ID and region, and always keeps the game title, even with `--no-title`.
|
||||
- **`--no-title`:** removes the game title from `.pkg` file names and game folders only. It must be combined with `--add-id` or `--add-content-id`, so every file still says which game it belongs to. The script stops with an error otherwise. The name's first part is written without brackets, so names don't start with `[`, e.g. `CUSA00900 [v1.09] [patch].pkg`, or `v1.09 [CUSA00900] [patch].pkg` with `--order version`. A DLC keeps its own name, and a patch keeps a label you gave it in the db, so different DLC of the same game still get different names.
|
||||
@@ -513,11 +516,11 @@ The default order is `title,label,id,region,console,version,cid,type`. List the
|
||||
PS5 `.pkg` files, e.g. fpkgs, are renamed like PS4 PKGs, with the same parts and options:
|
||||
|
||||
```
|
||||
UP2103-PPSA03311_00-BOIREPENTANCEPS5.pkg -> The Binding of Isaac Repentance [PPSA03311] [PS5]/The Binding of Isaac Repentance [PPSA03311] [PS5] [v1.01] [base].pkg
|
||||
UP2103-PPSA03311_00-BOIREPENTANCEPS5.pkg -> The Binding of Isaac Repentance [PPSA03311] [PS5]/The Binding of Isaac Repentance [PPSA03311] [PS5] [v1.000.000] [base].pkg
|
||||
```
|
||||
|
||||
- **How they're read:** a PS5 PKG starts with `\x7fFIH` instead of PS4's `\x7fCNT`. The value at offset `0x58` points to a PS4-style metadata block inside it, whose entry `0x2000` is the game's `param.json`. The script jumps straight there and reads a few KB, however big the PKG is.
|
||||
- **What's used:** `titleId`, `contentId`, the English `titleName` and `masterVersion`, the same fields as PS5 game folders.
|
||||
- **What's used:** `titleId`, `contentId`, the English `titleName` and `contentVersion`, the same fields as PS5 game folders. `contentVersion` is the game's version including updates, e.g. `02.002.000` gives `[v2.002.000]`. The PKG's `masterVersion` can stay at `01.00` even when the game is at 2.002.
|
||||
- **Types:** so far only **base games** (content type `0x20`) are recognised. A PS5 patch or DLC PKG is reported as `PS5 pkg type 0x… not recognised yet` and left alone, until its type code is known.
|
||||
- **Separate from PS4:** a PS5 game has its own title ID (`PPSA…`), db entry and folder. It's never merged with the PS4 version of the same title. If two games would get the same folder name, e.g. `ELDEN RING` for both PS4 and PS5 in the default style, the second one is reported with a hint to use `--add-id` or `--add-console`, and nothing is moved into the other game's folder.
|
||||
|
||||
@@ -527,11 +530,11 @@ Besides PKG files, the script renames **extracted game folders**: a PS5 game, or
|
||||
|
||||
| Folder contains | Platform | Read from it |
|
||||
|---|---|---|
|
||||
| `sce_sys/param.json` | PS5 | `titleId`, `contentId`, the English `titleName` under `localizedParameters`, and `masterVersion` |
|
||||
| `sce_sys/param.json` | PS5 | `titleId`, `contentId`, the English `titleName` under `localizedParameters`, and `contentVersion` |
|
||||
| `sce_sys/param.sfo` | PS4 dump | the same fields as a PKG's `param.sfo`. The version is `VERSION`, like a PS4 base game |
|
||||
|
||||
```
|
||||
The Binding of Isaac Repentance 01.000 PPSA03311/ -> The Binding of Isaac Repentance [PPSA03311] [USA] [v1.01] [app]/
|
||||
The Binding of Isaac Repentance 01.000 PPSA03311/ -> The Binding of Isaac Repentance [PPSA03311] [USA] [v1.000.000] [app]/
|
||||
├── eboot.bin ├── eboot.bin (untouched)
|
||||
├── PPSA03311.complete ├── PPSA03311.complete (untouched)
|
||||
└── sce_sys/param.json └── sce_sys/param.json (untouched)
|
||||
@@ -693,7 +696,7 @@ Only to look up English names for Japanese/Korean/Chinese titles, and only once
|
||||
**Does it work with PS5 games?**
|
||||
Yes, with both kinds:
|
||||
- **PS5 `.pkg` files (fpkg):** read from the `param.json` inside them. Base games are supported so far. See [PS5 PKGs](#ps5-pkgs).
|
||||
- **Extracted PS5 game folders** (`sce_sys/param.json`): renamed as one item, e.g. `The Binding of Isaac Repentance [PPSA03311] [v1.01] [app]`, with their contents never touched. Dumped PS4 games stored as folders (`sce_sys/param.sfo`) work the same way. See [Game folders](#game-folders-ps5-and-dumped-ps4-games).
|
||||
- **Extracted PS5 game folders** (`sce_sys/param.json`): renamed as one item, e.g. `The Binding of Isaac Repentance [PPSA03311] [v1.000.000] [app]`, with their contents never touched. Dumped PS4 games stored as folders (`sce_sys/param.sfo`) work the same way. See [Game folders](#game-folders-ps5-and-dumped-ps4-games).
|
||||
|
||||
PS4 and PS5 versions of a game stay separate. Use `--add-console` to tag names `[PS4]` / `[PS5]`.
|
||||
|
||||
|
||||
+15
-8
@@ -35,7 +35,8 @@ The game title is always used, other parts are added as tags; the type tag is la
|
||||
--add-id title ID tag Bloodborne [CUSA00900] [patch].pkg
|
||||
--add-region region tag Bloodborne [USA] [patch].pkg
|
||||
--add-console console tag (db) Bloodborne [PS4] [patch].pkg
|
||||
--add-version version tag Bloodborne [v1.09] [patch].pkg (patch: APP_VER, base/DLC: VERSION)
|
||||
--add-version version tag Bloodborne [v1.09] [patch].pkg (PS4 patch: APP_VER, base/DLC: VERSION;
|
||||
PS5: contentVersion)
|
||||
--add-content-id content ID tag Bloodborne [UP9000-CUSA00900_00-BLOODBORNE000000] [patch].pkg
|
||||
--no-type no type tag Bloodborne [v1.09].pkg
|
||||
--no-title no game title in .pkg CUSA00900 [v1.09] [patch].pkg (needs --add-id or --add-content-id;
|
||||
@@ -46,7 +47,7 @@ The game title is always used, other parts are added as tags; the type tag is la
|
||||
parts: title,label,id,region,console,version,cid,type (listed first, rest keep default order)
|
||||
label = the DLC name, or a Title you edited in the db's PKGS section (works for base, patch and DLC)
|
||||
Game folders (PS5 sce_sys/param.json, PS4 dump sce_sys/param.sfo) are named like a pkg with
|
||||
type [app] and never entered: The Binding of Isaac Repentance [PPSA03311] [v1.01] [app]
|
||||
type [app] and never entered: The Binding of Isaac Repentance [PPSA03311] [v1.000.000] [app]
|
||||
Other folders: <title>[ <ID>][ <region>], always with the title; version, content ID and type
|
||||
go on .pkg files and game folders only. DLC keep their DLC title: The Old Hunters [CUSA00900] [dlc].pkg
|
||||
|
||||
@@ -466,6 +467,11 @@ def build_db(root, path, rebuild=False, offline=False):
|
||||
if kind == 'base' and old != key and old in db.pkgs and key not in db.pkgs:
|
||||
db.pkgs[key] = db.pkgs.pop(old) # recorded with APP_VER (01.00) by older versions
|
||||
print(f' ~ {pcid}|{old[2]} -> {ver} (base version is VERSION, not APP_VER)')
|
||||
if console == 'PS5' and key not in db.pkgs:
|
||||
olds = [k for k in db.pkgs if k[0] == pcid and k[1] == kind and k != key]
|
||||
if len(olds) == 1: # recorded with masterVersion by v1.3.0: keep the line (and edits)
|
||||
db.pkgs[key] = db.pkgs.pop(olds[0])
|
||||
print(f' ~ {pcid}|{olds[0][2]} -> {ver} (PS5 version is contentVersion)')
|
||||
if key not in db.pkgs:
|
||||
db.pkgs[key] = (gid, (db.dlc_title(pcid) or ptitle) if kind == 'dlc' else ptitle)
|
||||
new_pkgs += 1
|
||||
@@ -786,8 +792,9 @@ def _pkg_tuple(cid, sfo, kind):
|
||||
|
||||
|
||||
def ps5_version(params):
|
||||
"""The version of a PS5 game: masterVersion (contentVersion if there's none)."""
|
||||
return params.get('masterVersion') or params.get('contentVersion') or ''
|
||||
"""The version of a PS5 game: contentVersion, the game version including updates (e.g.
|
||||
02.002.000); masterVersion (the package's master version) only if there's no contentVersion."""
|
||||
return params.get('contentVersion') or params.get('masterVersion') or ''
|
||||
|
||||
|
||||
def _ps5_tuple(params, kind, cid=''):
|
||||
@@ -798,9 +805,9 @@ def _ps5_tuple(params, kind, cid=''):
|
||||
|
||||
|
||||
def version_tag(ver):
|
||||
"""'01.09' -> 'v1.09'."""
|
||||
m = re.fullmatch(r'0*(\d+)\.(\d+)', ver.strip())
|
||||
return f'v{m.group(1)}.{m.group(2)}' if m else (f'v{ver.strip()}' if ver.strip() else '')
|
||||
"""'01.09' -> 'v1.09', '01.000.000' -> 'v1.000.000' (leading zeros of the first part dropped)."""
|
||||
m = re.fullmatch(r'0*(\d+)((?:\.\d+)+)', ver.strip())
|
||||
return f'v{m.group(1)}{m.group(2)}' if m else (f'v{ver.strip()}' if ver.strip() else '')
|
||||
|
||||
|
||||
def pkg_name(info, db, style, unknown, ext='.pkg'):
|
||||
@@ -1466,7 +1473,7 @@ def main():
|
||||
'or --add-content-id; the first part loses its brackets, e.g. "CUSA00900 [v1.09] [patch].pkg"')
|
||||
ap.add_argument('--add-version', action='store_true',
|
||||
help='add the pkg version to .pkg names, e.g. "Bloodborne [v1.09] [patch].pkg" '
|
||||
'(patches: APP_VER; base games and DLC: VERSION)')
|
||||
'(PS4 patches: APP_VER; PS4 base games and DLC: VERSION; PS5: contentVersion)')
|
||||
ap.add_argument('--add-content-id', action='store_true',
|
||||
help='add the content ID to .pkg names, e.g. "Bloodborne [UP9000-CUSA00900_00-BLOODBORNE000000] [base].pkg"')
|
||||
ap.add_argument('--sep', default=' ', metavar='SEP',
|
||||
|
||||
Reference in new issue
Block a user