37898e856b
Horizon no longer fetches anything of Minecraft from Mojang's servers. The client jar, version JSON, libraries and assets come from the user's official launcher install, and the server jar is one they downloaded themselves (--server-jar or HORIZON_SERVER_JAR). Every file is checked against checksums pinned in research-lock.json, and the prepared .local/ layout is byte-identical to the old downloads, so the harnesses and the native client are unchanged. CI keeps the offline checks on GitHub's runners; the vanilla comparisons and the mod build need the game, so they move to a manual job on a self-hosted runner that holds the maintainer's own copy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
76 lines
3.5 KiB
Python
76 lines
3.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Prepare/run a vanilla-rules Fabric server with pinned memory and simulation optimizers."""
|
|
|
|
import argparse
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import re
|
|
import shutil
|
|
import subprocess
|
|
|
|
try:
|
|
from . import lab, runtime
|
|
except ImportError:
|
|
import lab
|
|
import runtime
|
|
|
|
ROOT = lab.ROOT
|
|
|
|
|
|
def prepare(instance, baseline=False, server_jar=None):
|
|
lock, directory = lab.config()
|
|
launcher = lab.import_server(lock, directory, server_jar)
|
|
server, libraries = lab.unpack_server(launcher, directory, lock["minecraft"]["version"])
|
|
libraries = [server, *libraries, *runtime.fabric_libraries()]
|
|
pack_lock = json.loads((ROOT / "packs/mods.lock.json").read_text())
|
|
mods = pack_lock["projects"]
|
|
selection = ["fabric-api"] if baseline else ["fabric-api", "lithium", "ferrite-core"]
|
|
mod_dir = instance / "mods"
|
|
mod_dir.mkdir(parents=True, exist_ok=True)
|
|
for name in selection:
|
|
entry = mods[name]
|
|
source = runtime.fetch(entry["url"], ROOT / ".local/pack-cache" / entry["filename"],
|
|
entry["hashes"]["sha512"], "sha512")
|
|
shutil.copyfile(source, mod_dir / entry["filename"])
|
|
original = ROOT / "dist" / f"horizon-{pack_lock['pack_version']}.jar"
|
|
if not original.exists():
|
|
raise FileNotFoundError("Build the original mod first with tools/build_mod.py, or use the server starter ZIP")
|
|
runtime.install_original_mod(original, mod_dir)
|
|
return libraries
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("command", choices=["prepare", "run"])
|
|
parser.add_argument("--instance", type=Path, default=ROOT / ".local/server/optimized")
|
|
parser.add_argument("--heap", default="4G")
|
|
parser.add_argument("--server-jar", type=Path, help="the pinned server jar you downloaded yourself")
|
|
parser.add_argument("--baseline", action="store_true", help="Use a separate instance for the baseline")
|
|
parser.add_argument("--compact-headers", action="store_true", help="Enable Java 25 compact object headers for this server process")
|
|
parser.add_argument("--gc", choices=["default", "g1", "zgc"], default="default", help="Select a collector for this process; default leaves JVM policy in use")
|
|
args = parser.parse_args()
|
|
if not re.fullmatch(r"[1-9][0-9]*[MGmg]", args.heap):
|
|
parser.error("--heap must look like 4G")
|
|
instance = args.instance.resolve()
|
|
if args.baseline and args.instance == parser.get_default("instance"):
|
|
instance = ROOT / ".local/server/baseline"
|
|
libraries = prepare(instance, args.baseline, args.server_jar)
|
|
if args.command == "prepare":
|
|
print(f"Prepared server at {instance}. Read https://www.minecraft.net/eula before setting eula=true locally.")
|
|
return
|
|
eula = instance / "eula.txt"
|
|
if not eula.exists() or not re.search(r"(?m)^\s*eula\s*=\s*true\s*$", eula.read_text()):
|
|
if not eula.exists():
|
|
eula.write_text("# Read https://www.minecraft.net/eula then change this value yourself.\neula=false\n")
|
|
print(f"Server prepared. Read Minecraft's EULA and set eula=true in {eula} before running.")
|
|
return
|
|
subprocess.run(["java", *runtime.jvm_options(args.heap, args.compact_headers, args.gc),
|
|
"--enable-native-access=ALL-UNNAMED",
|
|
"-cp", os.pathsep.join(map(str, libraries)), "net.fabricmc.loader.impl.launch.knot.KnotServer",
|
|
"--nogui"], cwd=instance, check=True)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|