Add Reaper's Sky dedicated server deploy files
- server/mods.json: 59 server-safe mods pinned by sha1 (19 client-only excluded) - server/deploy.sh: idempotent Debian 13 installer (Java 21, NeoForge 21.1.248, mods, eula/server.properties, 8G run.sh) - server/build_mods.py: regenerate mods.json from the Prism instance - server/README.md: setup + ops guide
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Regenerate server/mods.json from the Prism instance's mods directory.
|
||||
|
||||
For every .jar in the pack instance it:
|
||||
- computes sha1
|
||||
- looks up the Modrinth download URL via the version_file API
|
||||
(aero-shadow-fix is CurseForge-only, pinned manually)
|
||||
- drops the 19 client-only mods
|
||||
and writes the server manifest to mods.json.
|
||||
|
||||
Usage: python3 build_mods.py
|
||||
"""
|
||||
import hashlib, json, os, subprocess, sys, time
|
||||
|
||||
INSTANCE = os.path.expanduser(
|
||||
"~/.local/share/PrismLauncher/instances/Reaper's Sky - dev/.minecraft/mods")
|
||||
OUT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "mods.json")
|
||||
MC_VERSION = "1.21.1"
|
||||
NEOFORGE_VERSION = "21.1.248"
|
||||
|
||||
CLIENT_ONLY = {
|
||||
"iris-neoforge-1.8.14-beta.1+mc1.21.1.jar",
|
||||
"EuphoriaPatcher-1.9.3-r5.8.1-neoforge.jar",
|
||||
"iris-flywheel-compat-NeoForge-2.3.1.jar",
|
||||
"sodium-neoforge-0.8.12+mc1.21.1.jar",
|
||||
"ImmediatelyFast-NeoForge-1.6.12+1.21.1.jar",
|
||||
"entityculling-neoforge-1.10.5-mc1.21.1.jar",
|
||||
"dynamic-fps-3.11.4+mc1.21.0-neoforge.jar",
|
||||
"MouseTweaks-neoforge-mc1.21-2.26.1.jar",
|
||||
"appleskin-neoforge-mc1.21-3.0.9.jar",
|
||||
"Controlling-neoforge-1.21.1-19.0.5.jar",
|
||||
"Searchables-neoforge-1.21.1-1.0.2.jar",
|
||||
"skinlayers3d-neoforge-1.11.2-mc1.21.1.jar",
|
||||
"xaerominimap-neoforge-1.21.1-26.4.2.jar",
|
||||
"xaeroworldmap-neoforge-1.21.1-1.44.2.jar",
|
||||
"Jade-1.21.1-NeoForge-15.10.6.jar",
|
||||
"jade-sable-compat-1.3.0.jar",
|
||||
"aero-shadow-fix.jar",
|
||||
"aeronautics-propeller-blur-1.0a.jar",
|
||||
"jei-1.21.1-neoforge-19.44.0.403.jar",
|
||||
}
|
||||
|
||||
CURSEFORGE_ONLY = {
|
||||
"aero-shadow-fix.jar": "https://www.curseforge.com/api/v1/mods/1641969/files/8589529/download",
|
||||
}
|
||||
|
||||
UA = "opencode-pack-builder/1.0"
|
||||
|
||||
|
||||
def sha1(path):
|
||||
h = hashlib.sha1()
|
||||
with open(path, "rb") as f:
|
||||
for chunk in iter(lambda: f.read(65536), b""):
|
||||
h.update(chunk)
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
def resolve(jar, digest):
|
||||
if jar in CURSEFORGE_ONLY:
|
||||
return CURSEFORGE_ONLY[jar]
|
||||
r = subprocess.run(
|
||||
["curl", "-s", "--max-time", "20", "-H", f"User-Agent: {UA}",
|
||||
f"https://api.modrinth.com/v2/version_file/{digest}?algorithm=sha1"],
|
||||
capture_output=True, text=True)
|
||||
try:
|
||||
return json.loads(r.stdout)["files"][0]["url"]
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
|
||||
def main():
|
||||
mods = []
|
||||
for jar in sorted(os.listdir(INSTANCE)):
|
||||
if not jar.endswith(".jar"):
|
||||
continue
|
||||
if jar in CLIENT_ONLY:
|
||||
print(f" skip (client-only): {jar}")
|
||||
continue
|
||||
digest = sha1(os.path.join(INSTANCE, jar))
|
||||
url = resolve(jar, digest)
|
||||
if not url:
|
||||
print(f" !! no URL for {jar} -- fix manually", file=sys.stderr)
|
||||
mods.append({"file": jar, "url": url, "sha1": digest})
|
||||
time.sleep(0.1)
|
||||
manifest = {"minecraft": MC_VERSION, "neoforge": NEOFORGE_VERSION, "mods": mods}
|
||||
with open(OUT, "w") as f:
|
||||
json.dump(manifest, f, indent=2)
|
||||
print(f"Wrote {len(mods)} server mods to {OUT}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user