Files
SirHumza--orbisRPC/scripts/gen_nametable.py
T
SirHumza cdb431cfa6 Names tiers, SFO parser, close-frame/diagnostics hardening
- detect: cost-tiered resolution; plugin path skips multi-MB app.db
  scan (game-process safety); payload tries pronunc, sfo, appxml,
  baked table, then app.db; sfo TITLE via app0/sce_sys paths
- sfo.c: bounds-checked PARAM.SFO parser + unit tests incl malformed
- nametable: generated fallback from title DB + generator script
- discord: malformed close frames reconnect loudly; one-time warning
  when artwork requested but no application_id configured
- ws comments de-BearSSLed; gitignore covers artifacts; drop .DS_Store,
  untrack test binary; README art claim corrected
2026-09-19 01:37:55 +02:00

67 lines
2.5 KiB
Python

#!/usr/bin/env python3
"""gen_nametable.py - build orbisrpc/nametable.h from config/titles.json.
titles.json maps TITLEID -> display name (extracted from the PS4's
/system_data/priv/mms/app.db tbl_appbrowse_* tables, or extended by hand).
The generated table is compiled in, so name lookup needs no filesystem
access and works inside any console sandbox.
Usage: python3 scripts/gen_nametable.py
"""
import json
import os
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SRC = os.path.join(ROOT, "config", "titles.json")
DST = os.path.join(ROOT, "orbisrpc", "nametable.h")
def c_escape(s):
out = []
for ch in s:
o = ord(ch)
if ch == '"':
out.append('\\"')
elif ch == "\\":
out.append("\\\\")
elif 32 <= o < 127:
out.append(ch)
else:
# octal: unlike \x, always stops after 3 digits, so a hex
# digit following the escape can never merge into it.
for b in ch.encode("utf-8"):
out.append("\\%03o" % b)
return "".join(out)
def main():
with open(SRC, encoding="utf-8") as fh:
titles = json.load(fh)
items = sorted(titles.items())
with open(DST, "w", encoding="utf-8") as fh:
fh.write("/* nametable.h - GENERATED by scripts/gen_nametable.py. Do not edit. */\n")
fh.write("#ifndef NAMETABLE_H\n#define NAMETABLE_H\n");
fh.write("#include <stddef.h>\n#include <string.h>\n")
fh.write("typedef struct { const char *id; const char *name; } nt_entry_t;\n")
fh.write("static const nt_entry_t g_nametable[] = {\n")
for tid, name in items:
fh.write(' { "%s", "%s" },\n' % (c_escape(tid), c_escape(name)))
fh.write("};\n")
fh.write("static const size_t g_nametable_count = sizeof g_nametable / sizeof g_nametable[0];\n")
fh.write("static int nametable_lookup(const char *tid, char *out, size_t cap){\n")
fh.write(" if(!tid || !out || cap == 0) return -1;\n")
fh.write(" for(size_t i = 0; i < g_nametable_count; i++){\n")
fh.write(" if(!strcmp(tid, g_nametable[i].id)){\n")
fh.write(" strncpy(out, g_nametable[i].name, cap - 1);\n")
fh.write(" out[cap - 1] = 0;\n")
fh.write(" return out[0] ? 0 : -1;\n")
fh.write(" }\n")
fh.write(" }\n")
fh.write(" return -1;\n")
fh.write("}\n#endif\n")
print("wrote %s with %d entries" % (DST, len(items)))
if __name__ == "__main__":
main()