Everything the next agent needs to run the Phase 2 optimisation loop on a machine that can launch the client: - analysis/client-perf/: LEVERS (ranked levers + corrections), BENCH-MATRIX (world, scenes, config IDs, blocks B0-B14 with decision rules), PLAYER-TUNING, SPAWN-TUNING, research briefs, the jar scanner and its output, observed default configs, and proposed-configs/ (build.py generates tiers and bench variants and fails on unknown keys; apply_variant.py applies a variant and merges options.txt). - analysis/client-perf/bench/onion-bench/: bench-world datapack (scene teleports, Create grid, mob pen, sound storm, 120 s teleport tour). - analysis/audit/: the static recipe/dependency audit, including gen_fixes.py, which generates the shipped Paxi datapack and was never tracked. - phase0/: per-machine measurement harness (Steam Deck, 7700K/1060, 6700K/1080 Ti). - .pi/journal.md: running work log; read it first. All of it is packwizignored, so nothing here ships to players.
69 lines
1.9 KiB
Python
69 lines
1.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Jar inspection without unzip/java.
|
|
|
|
jx.py ls JAR[!nested.jar...] [regex] list entries
|
|
jx.py cat JAR[!nested.jar...] entry print entry
|
|
jx.py str JAR[!nested.jar...] classregex strregex UTF8 constants of classes
|
|
"""
|
|
import io, re, struct, sys, zipfile
|
|
|
|
|
|
def open_jar(spec):
|
|
parts = spec.split("!")
|
|
z = zipfile.ZipFile(parts[0])
|
|
for p in parts[1:]:
|
|
z = zipfile.ZipFile(io.BytesIO(z.read(p)))
|
|
return z
|
|
|
|
|
|
def utf8_consts(data):
|
|
out = []
|
|
if data[:4] != b"\xca\xfe\xba\xbe":
|
|
return out
|
|
n = struct.unpack(">H", data[8:10])[0]
|
|
i, k = 10, 1
|
|
while k < n:
|
|
tag = data[i]
|
|
if tag == 1:
|
|
ln = struct.unpack(">H", data[i + 1:i + 3])[0]
|
|
out.append(data[i + 3:i + 3 + ln].decode("utf-8", "replace"))
|
|
i += 3 + ln
|
|
elif tag in (3, 4):
|
|
i += 5
|
|
elif tag in (5, 6):
|
|
i += 9; k += 1
|
|
elif tag in (7, 8, 16, 19, 20):
|
|
i += 3
|
|
elif tag in (9, 10, 11, 12, 17, 18):
|
|
i += 5
|
|
elif tag == 15:
|
|
i += 4
|
|
else:
|
|
break
|
|
k += 1
|
|
return out
|
|
|
|
|
|
def main():
|
|
cmd, spec = sys.argv[1], sys.argv[2]
|
|
z = open_jar(spec)
|
|
if cmd == "ls":
|
|
rx = re.compile(sys.argv[3]) if len(sys.argv) > 3 else None
|
|
for n in z.namelist():
|
|
if not rx or rx.search(n):
|
|
print(n)
|
|
elif cmd == "cat":
|
|
sys.stdout.write(z.read(sys.argv[3]).decode("utf-8", "replace"))
|
|
elif cmd == "str":
|
|
crx, srx = re.compile(sys.argv[3]), re.compile(sys.argv[4])
|
|
for n in z.namelist():
|
|
if n.endswith(".class") and crx.search(n):
|
|
hits = [s for s in utf8_consts(z.read(n)) if srx.search(s)]
|
|
if hits:
|
|
print("==", n)
|
|
for h in hits:
|
|
print(" ", repr(h))
|
|
|
|
|
|
main()
|