diff --git a/README.md b/README.md index bcd1689..f73d82d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- orbisRPC + orbisRPC

# orbisRPC — Discord Rich Presence for PS4 (GoldHEN RPC) @@ -228,8 +228,6 @@ nanoDNS — then reboot. (This is the step most people miss.) - Some homebrew (Apollo Save Tool, Cheats Manager, Homebrew Store) isn't detected yet — under investigation. -- Hotspot/mobile connections can send oversized frames that Discord - rejects — use stable Wi-Fi/LAN if presence won't set. ## Building @@ -273,7 +271,8 @@ Build/test/CI details: [`docs/BUILDING.md`](docs/BUILDING.md). - **SirHumza** — project founder, daemon core. - **CyberMask367** — firmware coverage to 13.52, homebrew and retro games resolving, presence flags, tester wrangling. - Testers in `testers-chat` on DIscord — every log file that made a fix possible. -- [*PKG-ZONE*](https://pkg-zone.com) — metadata on ps4 hombrew apps used for resolving +- [OpenOrbis](https://github.com/OpenOrbis/OpenOrbis-PS4-Toolchain) - SDK/Toolchain used to make setup PKG +- [*PKG-ZONE*](https://pkg-zone.com) — used for resolving metadata on hombrew apps - [*PSX DATA CENTER*](https://psxdatacenter.com) — source used to make custom json list in [`config`](config/) for resolving retro games ## License diff --git a/config/icons/pslogo.png b/config/icons/pslogo.png deleted file mode 100644 index 14cac60..0000000 Binary files a/config/icons/pslogo.png and /dev/null differ diff --git a/scripts/add_custom_title.py b/scripts/add_custom_title.py new file mode 100644 index 0000000..5f0ffda --- /dev/null +++ b/scripts/add_custom_title.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python3 +"""Add an entry to config/custom.json (the community title list). + + python3 scripts/add_custom_title.py ask for id, name, art + python3 scripts/add_custom_title.py --list show every entry + python3 scripts/add_custom_title.py --remove ORPC00042 + +pkg-zone only carries the apps its own scraper knows about, and the retro +indexes are gated on retro prefixes. custom.json is the catch-all: a plain +TITLEID -> name map anyone can contribute to. + +Format matches the retro indexes so the payload reuses the same scanner: + + [{"id":"ORPC00042","name":"Some App","cover":"https://.../a.png"}] + +Compact separators are required. The scanner matches entries on the literal +byte run "id":"", so a space after the colon -- what you get from a +normal pretty-printer -- means the lookup never matches and the payload falls +back to the raw TITLEID with no error. save() below enforces this. + +"cover" is optional; without one the presence falls back to the default art. + +custom runs last in the chain, so TMDB stays authoritative for retail titles. +""" +import json +import os +import sys + +PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), + 'config', 'custom.json') + + +def load(): + try: + with open(PATH, encoding='utf-8') as f: + return json.load(f) + except (OSError, ValueError): + return [] + + +def save(entries): + """One entry per line so a contribution reads as a one-line diff. + + separators=(',', ':') is not cosmetic: the scanner matches entries on the + literal byte run "id":"", so a space after the colon -- what a + normal pretty-printer emits -- means the lookup never matches and the + payload falls back to the raw TITLEID with no error.""" + with open(PATH, 'w', encoding='utf-8', newline='\n') as f: + f.write('[\n') + for i, e in enumerate(entries): + tail = '' if i == len(entries) - 1 else ',' + f.write(' ' + json.dumps(e, ensure_ascii=False, + separators=(',', ':')) + tail + '\n') + f.write(']\n') + + +def main(): + argv = sys.argv[1:] + + if argv and argv[0] == '--list': + entries = load() + for e in entries: + art = e.get('cover', '') + print(' %-12s %s%s' % (e['id'], e['name'], + (' [%s]' % art) if art else '')) + print('%d entries' % len(entries)) + return + + if argv and argv[0] == '--remove': + if len(argv) < 2: + sys.exit('usage: add_custom_title.py --remove TITLEID') + tid = argv[1].upper() + entries = load() + kept = [e for e in entries if e['id'].upper() != tid] + if len(kept) == len(entries): + print('%s not in the list' % tid) + return + save(kept) + print('removed %s (%d entries left)' % (tid, len(kept))) + return + + if argv: + sys.exit('usage: add_custom_title.py [--list | --remove TITLEID]') + + # --- interactive add --------------------------------------------------- + tid = input('TITLEID: ').strip().upper() + name = input('Name: ').strip() + art = input('Cover URL (blank for none): ').strip() + + entry = {'id': tid, 'name': name} + if art: + entry['cover'] = art + + entries = [e for e in load() if e['id'].upper() != tid] + entries.append(entry) + save(entries) + + print('%s -> %s' % (tid, name)) + + +if __name__ == '__main__': + main() \ No newline at end of file