from __future__ import annotations import hashlib import json import re import shutil import urllib.request import zipfile from pathlib import Path ROOT = Path(__file__).resolve().parents[1] BUILD_DIR = ROOT / "build" / "warium-port" ORIGINAL_JAR = BUILD_DIR / "Warium-1.2.7.jar" ORIGINAL_URL = "https://cdn.modrinth.com/data/xgjvEen1/versions/4oIhAhRz/Warium%201.2.7.jar" ORIGINAL_SHA1 = "528d81630a23fb4004e3abdd99b16bd225cd1e92" MODID = "crusty_chunks" def download_original() -> Path: BUILD_DIR.mkdir(parents=True, exist_ok=True) if not ORIGINAL_JAR.exists() or sha1(ORIGINAL_JAR) != ORIGINAL_SHA1: request = urllib.request.Request( ORIGINAL_URL, headers={"User-Agent": "MrSphay/Warium-NeoForge-Port/1.0"}, ) with urllib.request.urlopen(request) as response, ORIGINAL_JAR.open("wb") as out: shutil.copyfileobj(response, out) actual = sha1(ORIGINAL_JAR) if actual != ORIGINAL_SHA1: raise SystemExit(f"Original jar SHA1 mismatch: expected {ORIGINAL_SHA1}, got {actual}") return ORIGINAL_JAR def sha1(path: Path) -> str: digest = hashlib.sha1() with path.open("rb") as handle: for chunk in iter(lambda: handle.read(1024 * 1024), b""): digest.update(chunk) return digest.hexdigest() def clean_dir(path: Path) -> None: if path.exists(): shutil.rmtree(path) path.mkdir(parents=True, exist_ok=True) def safe_java_identifier(name: str, used: set[str]) -> str: ident = re.sub(r"[^a-zA-Z0-9_]", "_", name).upper() if not ident or ident[0].isdigit(): ident = "_" + ident if ident in JAVA_KEYWORDS: ident = ident + "_ENTRY" base = ident suffix = 2 while ident in used: ident = f"{base}_{suffix}" suffix += 1 used.add(ident) return ident def write_json(path: Path, data: object) -> None: path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps(data, indent=2, sort_keys=True) + "\n", encoding="utf-8") JAVA_KEYWORDS = { "ABSTRACT", "ASSERT", "BOOLEAN", "BREAK", "BYTE", "CASE", "CATCH", "CHAR", "CLASS", "CONST", "CONTINUE", "DEFAULT", "DO", "DOUBLE", "ELSE", "ENUM", "EXTENDS", "FINAL", "FINALLY", "FLOAT", "FOR", "GOTO", "IF", "IMPLEMENTS", "IMPORT", "INSTANCEOF", "INT", "INTERFACE", "LONG", "NATIVE", "NEW", "PACKAGE", "PRIVATE", "PROTECTED", "PUBLIC", "RETURN", "SHORT", "STATIC", "STRICTFP", "SUPER", "SWITCH", "SYNCHRONIZED", "THIS", "THROW", "THROWS", "TRANSIENT", "TRY", "VOID", "VOLATILE", "WHILE", }