11#! /usr/bin/env bash
22# setup-ref.sh — Download, extract, and decompile the Minecraft server JAR.
33#
4+ # Decompilation uses VineFlower as the primary decompiler (best quality output).
5+ # Files that VineFlower fails to decompile are retried with CFR as a fallback.
6+ #
47# All output lives under mc-server-ref/<version>/:
58# server.jar — downloaded bundled launcher JAR
69# extracted/server.jar — unbundled server JAR (class files)
@@ -18,8 +21,10 @@ set -euo pipefail
1821
1922# ── Configuration ──────────────────────────────────────────────────────────────
2023MC_VERSION=" 26.1"
21- VINEFLOWER_VERSION=" 1.11.1 "
24+ VINEFLOWER_VERSION=" 1.11.2 "
2225VINEFLOWER_URL=" https://github.com/Vineflower/vineflower/releases/download/${VINEFLOWER_VERSION} /vineflower-${VINEFLOWER_VERSION} .jar"
26+ CFR_VERSION=" 0.152"
27+ CFR_URL=" https://github.com/leibnitz27/cfr/releases/download/${CFR_VERSION} /cfr-${CFR_VERSION} .jar"
2328VERSION_MANIFEST_URL=" https://piston-meta.mojang.com/mc/game/version_manifest_v2.json"
2429
2530PROJECT_ROOT=" $( cd " $( dirname " $0 " ) /.." && pwd) "
@@ -120,6 +125,17 @@ else
120125 ok " Downloaded VineFlower ($( du -h " ${VINEFLOWER_JAR} " | cut -f1) )"
121126fi
122127
128+ # ── Step 3b: Download CFR decompiler (fallback) ───────────────────────────────
129+ CFR_JAR=" ${REF_DIR} /cfr-${CFR_VERSION} .jar"
130+
131+ if [ -f " ${CFR_JAR} " ]; then
132+ ok " CFR ${CFR_VERSION} already exists, skipping download"
133+ else
134+ info " Downloading CFR ${CFR_VERSION} (fallback decompiler)..."
135+ curl -#L -o " ${CFR_JAR} " " ${CFR_URL} "
136+ ok " Downloaded CFR ($( du -h " ${CFR_JAR} " | cut -f1) )"
137+ fi
138+
123139# ── Step 4: Decompile ─────────────────────────────────────────────────────────
124140if [ -d " ${DECOMPILED_DIR} " ] && [ " $( find " ${DECOMPILED_DIR} " -name ' *.java' | head -1) " ]; then
125141 JAVA_COUNT=$( find " ${DECOMPILED_DIR} " -name ' *.java' | wc -l)
@@ -135,6 +151,43 @@ else
135151 ok " Decompiled ${JAVA_COUNT} Java files"
136152fi
137153
154+ # ── Step 4b: CFR fallback for VineFlower failures ─────────────────────────────
155+ FAILED_FILES=()
156+ while IFS= read -r -d ' ' file; do
157+ FAILED_FILES+=(" $file " )
158+ done < <( grep -rlZ " Couldn't be decompiled" " ${DECOMPILED_DIR} " 2> /dev/null || true)
159+
160+ if [ ${# FAILED_FILES[@]} -gt 0 ]; then
161+ info " Found ${# FAILED_FILES[@]} files that VineFlower failed to decompile, retrying with CFR..."
162+ CFR_TMP=$( mktemp -d)
163+ FIXED=0
164+
165+ for failed_file in " ${FAILED_FILES[@]} " ; do
166+ REL_PATH=" ${failed_file# " ${DECOMPILED_DIR} /" } "
167+ CLASS_NAME=" ${REL_PATH% .java} "
168+ CLASS_NAME=" ${CLASS_NAME// \/ / .} "
169+
170+ if java -jar " ${CFR_JAR} " --outputdir " ${CFR_TMP} " " ${INNER_JAR} " \
171+ --jarfilter " ${CLASS_NAME} " 2> /dev/null; then
172+ CFR_OUTPUT=" ${CFR_TMP} /${REL_PATH} "
173+ if [ -f " ${CFR_OUTPUT} " ] && ! grep -q " Couldn't be decompiled" " ${CFR_OUTPUT} " 2> /dev/null; then
174+ cp " ${CFR_OUTPUT} " " ${failed_file} "
175+ FIXED=$(( FIXED + 1 ))
176+ fi
177+ fi
178+ done
179+
180+ rm -rf " ${CFR_TMP} "
181+
182+ REMAINING=$(( ${# FAILED_FILES[@]} - FIXED))
183+ ok " CFR recovered ${FIXED} /${# FAILED_FILES[@]} files"
184+ if [ " ${REMAINING} " -gt 0 ]; then
185+ warn " ${REMAINING} files could not be decompiled by either tool"
186+ fi
187+ else
188+ ok " No VineFlower failures to recover"
189+ fi
190+
138191# ── Step 5: Run vanilla data generator ─────────────────────────────────────────
139192if [ -d " ${GENERATED_DIR} /reports" ]; then
140193 ok " Generated reports already exist, skipping data generation"
@@ -187,6 +240,7 @@ info "Setup complete! Directory layout:"
187240echo " "
188241echo " mc-server-ref/"
189242[ -f " ${VINEFLOWER_JAR} " ] && echo " ├── vineflower-${VINEFLOWER_VERSION} .jar"
243+ [ -f " ${CFR_JAR} " ] && echo " ├── cfr-${CFR_VERSION} .jar"
190244echo " ├── decompiled -> ${MC_VERSION} /decompiled"
191245echo " ├── generated -> ${MC_VERSION} /generated"
192246echo " ├── mc-extracted -> ${MC_VERSION} /mc-extracted"
0 commit comments