Files
PixelPics/tools/update-vanilla-models.sh
T

64 lines
3.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# Regenerates the vanilla entity-model dump from a Minecraft CLIENT jar (26.x+ ships unobfuscated, no mappings
# needed). This is PixelPics' primary entity-model source; run it once per Minecraft update.
#
# Needs the version installed in the launcher (~/.minecraft/versions/<ver>/<ver>.json + jar + libraries) and a
# JDK (the dump runs as a source-file program): $JAVA, $JAVA_HOME or the JDK of `javac` on the PATH.
#
# Usage: tools/update-vanilla-models.sh 26.3 # -> src/main/resources/cem/ (bundled; rebuild jar)
# tools/update-vanilla-models.sh 26.4 <plugin-data-dir> # -> <dir>/vanilla_entity_models.json
# # (overrides the bundled copy, no rebuild)
set -euo pipefail
VER="${1:?usage: $0 <minecraft-version> [output-dir]}"
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
OUT_DIR="${2:-$ROOT/src/main/resources/cem}"
MC="${MINECRAFT_DIR:-$HOME/.minecraft}"
JSON="$MC/versions/$VER/$VER.json"
JAR="$MC/versions/$VER/$VER.jar"
[[ -f "$JSON" && -f "$JAR" ]] || { echo "Version $VER not found under $MC/versions (start it once in the launcher)"; exit 1; }
NEED="$(python3 -c 'import json,sys; print(json.load(open(sys.argv[1])).get("javaVersion", {}).get("majorVersion", 0))' "$JSON")"
is_jdk() { # a JDK (jdk.compiler) at least as new as the game's Java version
[[ -n "$1" && -x "$1" ]] && "$1" --list-modules 2>/dev/null | grep -q '^jdk.compiler@' &&
(( $("$1" --version 2>/dev/null | head -1 | grep -oE '[0-9]+' | head -1) >= NEED ))
}
JAVAC_JAVA="$(command -v javac >/dev/null && echo "$(dirname "$(readlink -f "$(command -v javac)")")/java" || true)"
for j in "${JAVA:-}" "${JAVA_HOME:+$JAVA_HOME/bin/java}" "$JAVAC_JAVA" "$(command -v java || true)"; do
if is_jdk "$j"; then JDK_JAVA="$j"; break; fi
done
[[ -n "${JDK_JAVA:-}" ]] || { echo "No JDK >= $NEED found (a JRE can't launch source files): set JAVA or JAVA_HOME"; exit 1; }
# Classpath: client jar + all libraries listed in the version json.
CP="$(python3 - "$JSON" "$MC" "$JAR" <<'EOF'
import json, os, sys
j = json.load(open(sys.argv[1])); mc = sys.argv[2]; cp = []
for lib in j.get("libraries", []):
a = lib.get("downloads", {}).get("artifact")
if a:
p = os.path.join(mc, "libraries", a["path"])
if os.path.exists(p): cp.append(p)
cp.append(sys.argv[3])
print(":".join(cp))
EOF
)"
# Scratch dir as working directory: the game's logger writes a logs/ folder there.
WORK="$(mktemp -d)"
trap 'rm -rf "$WORK"' EXIT
OUT="$WORK/vanilla_entity_models.json"
if ! (cd "$WORK" && "$JDK_JAVA" -cp "$CP" "$ROOT/tools/VanillaModelDump.java" "$OUT" > "$WORK/dump.log" 2>&1); then
cat "$WORK/dump.log"; echo "Dump failed"; exit 1
fi
grep -E "STDOUT|Exception" "$WORK/dump.log" | sed 's/.*STDOUT\]: //' || true
python3 - "$OUT" <<'EOF'
import json, sys
d = json.load(open(sys.argv[1]))
assert len(d['models']) > 100, 'dump looks incomplete'
print('version', d.get('version'), '-', len(d['models']), 'models,', len(d['entities']), 'entity types')
EOF
mkdir -p "$OUT_DIR"
install -m 644 "$OUT" "$OUT_DIR/vanilla_entity_models.json"
echo "Wrote $OUT_DIR/vanilla_entity_models.json"
echo "Note: the runtime resource pack must come from the same version (incl. assets/minecraft/font for text)."