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.
49 lines
2.7 KiB
Python
49 lines
2.7 KiB
Python
import zipfile, io, json, tomllib, re, pickle, os, glob
|
|
def lenient_json(b):
|
|
s=b.decode("utf-8-sig",errors="replace")
|
|
try: return json.loads(s)
|
|
except Exception:
|
|
s2=re.sub(r'//[^\n]*','',s); s2=re.sub(r',(\s*[}\]])',r'\1',s2)
|
|
try: return json.loads(s2)
|
|
except Exception: return None
|
|
mods={} # modid -> dict(jar, version, deps, nested)
|
|
files=[] # (jar, path, json) for data recipe/tags + lang
|
|
lang={}; models=set(); errors=[]
|
|
def walk(z, jarname, nested=False):
|
|
names=z.namelist()
|
|
for t in ("META-INF/neoforge.mods.toml","META-INF/mods.toml"):
|
|
if t in names:
|
|
raw=z.read(t).decode("utf-8",errors="replace")
|
|
try: m=tomllib.loads(raw)
|
|
except Exception as e: errors.append((jarname,"toml",str(e))); m={}
|
|
for md in m.get("mods",[]):
|
|
mid=md.get("modId"); ver=str(md.get("version"))
|
|
if ver.startswith("${"):
|
|
mf=z.read("META-INF/MANIFEST.MF").decode(errors="replace") if "META-INF/MANIFEST.MF" in names else ""
|
|
mm=re.search(r'Implementation-Version: *(\S+)',mf); ver=mm.group(1) if mm else ver
|
|
deps=m.get("dependencies",{}).get(mid,[])
|
|
mods.setdefault(mid,[]).append(dict(jar=jarname,version=ver,deps=deps,nested=nested,file=t))
|
|
break
|
|
for n in names:
|
|
if n.startswith("META-INF/jarjar/") and n.endswith(".jar"):
|
|
try: walk(zipfile.ZipFile(io.BytesIO(z.read(n))), jarname+"!"+n.split("/")[-1], True)
|
|
except Exception as e: errors.append((jarname,n,str(e)))
|
|
elif n.startswith("data/") and n.endswith(".json"):
|
|
p=n.split("/")
|
|
if len(p)>=4 and (p[2] in("recipe","recipes") or (p[2]=="tags" and p[3] in("item","items","block","blocks"))):
|
|
j=lenient_json(z.read(n))
|
|
if j is None: errors.append((jarname,n,"badjson"))
|
|
files.append((jarname,n,j))
|
|
elif n.startswith("assets/") and n.endswith("lang/en_us.json"):
|
|
j=lenient_json(z.read(n))
|
|
if isinstance(j,dict):
|
|
for k,v in j.items():
|
|
if k.startswith(("item.","block.")) and k.count(".")==2: lang.setdefault(k,[]).append((jarname,v))
|
|
elif n.startswith("assets/") and "/models/item/" in n and n.endswith(".json"):
|
|
p=n.split("/"); models.add(p[1]+":"+"/".join(p[4:])[:-5])
|
|
jars=["base_minecraft.jar","base_neoforge.jar"]+sorted(glob.glob("jars/*.jar"))
|
|
for j in jars: walk(zipfile.ZipFile(j), os.path.basename(j))
|
|
pickle.dump(dict(mods=mods,files=files,lang=lang,models=models,errors=errors),open("data.pkl","wb"))
|
|
print(len(mods),len(files),len(lang),len(models),len(errors))
|
|
for e in errors[:20]: print(e)
|