Add files via upload
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
DistantHorizons-2.1.2-a-1.20.1-forge-fabric.jar
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# Standalone config. Only read when ../instance.cfg is missing (i.e. not launched
|
||||||
|
# by Prism/MultiMC). Delete this file on a Prism-managed instance - the launcher's
|
||||||
|
# own instance.cfg and mmc-pack.json take priority and this is ignored.
|
||||||
|
[General]
|
||||||
|
|
||||||
|
# Shown in the launch banner. Any string.
|
||||||
|
name=My Modpack
|
||||||
|
|
||||||
|
# Minecraft version. Used to build the Fabric server jar URL.
|
||||||
|
MinecraftVersion=1.21.1
|
||||||
|
|
||||||
|
# Must be exactly "NeoForge" to get the NeoForge install path.
|
||||||
|
# Anything else falls through to the Fabric branch.
|
||||||
|
ModloaderName=NeoForge
|
||||||
|
|
||||||
|
# Modloader version, NOT the Minecraft version. This builds the NeoForge Maven URL
|
||||||
|
# and the libraries/net/neoforged/neoforge/<version>/ argfile path - a wrong value
|
||||||
|
# here means a 404 on download, or a "could not find main class" at startup.
|
||||||
|
ModloaderVersion=21.1.209
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
import sys, json, subprocess, configparser, shutil, os, urllib.request
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# User Variables
|
||||||
|
REPO_URL = ""
|
||||||
|
BRANCH = "main"
|
||||||
|
|
||||||
|
InstanceConfig = configparser.ConfigParser()
|
||||||
|
|
||||||
|
if Path("../instance.cfg").is_file():
|
||||||
|
# Launched by Prism/MultiMC - read the instance's own metadata
|
||||||
|
InstanceConfig.read("../instance.cfg")
|
||||||
|
with open("../mmc-pack.json", "r") as file:
|
||||||
|
Components = json.load(file)["components"]
|
||||||
|
# ponytail: match on uid, not list index - component order isn't guaranteed
|
||||||
|
Minecraft = next(c for c in Components if c["uid"] == "net.minecraft")
|
||||||
|
Modloader = next(c for c in Components
|
||||||
|
if c["uid"] != "net.minecraft" and not c.get("dependencyOnly"))
|
||||||
|
MinecraftVersion = Minecraft["version"]
|
||||||
|
ModloaderName = Modloader["cachedName"]
|
||||||
|
ModloaderVersion = Modloader["version"]
|
||||||
|
elif Path("env.txt").is_file():
|
||||||
|
# Standalone - same INI format, plus the versions mmc-pack.json would have given us
|
||||||
|
InstanceConfig.read("env.txt")
|
||||||
|
MinecraftVersion = InstanceConfig['General']['MinecraftVersion']
|
||||||
|
ModloaderName = InstanceConfig['General']['ModloaderName']
|
||||||
|
ModloaderVersion = InstanceConfig['General']['ModloaderVersion']
|
||||||
|
else:
|
||||||
|
sys.exit("* Found neither ../instance.cfg nor env.txt - cannot identify this instance.")
|
||||||
|
|
||||||
|
PackName = InstanceConfig['General']['name']
|
||||||
|
|
||||||
|
# Program Variables DO NOT TOUCH
|
||||||
|
MINGIT_URL = "https://github.com/git-for-windows/git/releases/download/v2.45.2.windows.1/MinGit-2.45.2-64-bit.zip"
|
||||||
|
MINGIT = Path(".mingit/cmd/git.exe")
|
||||||
|
|
||||||
|
print("****************************************")
|
||||||
|
print(f"* Launching {PackName}")
|
||||||
|
print(f"* {MinecraftVersion} / {ModloaderName} {ModloaderVersion}")
|
||||||
|
|
||||||
|
# ponytail: check the local MinGit before downloading - which() never sees it, it's not on PATH
|
||||||
|
GIT = shutil.which("git") or (str(MINGIT.resolve()) if MINGIT.is_file() else None)
|
||||||
|
if GIT is None:
|
||||||
|
if os.name != "nt":
|
||||||
|
sys.exit("* Git not found, please install Git!")
|
||||||
|
print("* Git not found, downloading and installing Git.")
|
||||||
|
urllib.request.urlretrieve(MINGIT_URL, "MinGit.zip")
|
||||||
|
shutil.unpack_archive("MinGit.zip", ".mingit")
|
||||||
|
Path("MinGit.zip").unlink()
|
||||||
|
GIT = str(MINGIT.resolve())
|
||||||
|
|
||||||
|
def git(*args):
|
||||||
|
with open("launchClient.log", "a") as log:
|
||||||
|
subprocess.run([GIT, *args], stdout=log, stderr=subprocess.STDOUT, check=True)
|
||||||
|
|
||||||
|
if Path(".git").is_dir():
|
||||||
|
print("* Detected git repo. Updating Pack!")
|
||||||
|
|
||||||
|
print("* * Fetching changes from upstream")
|
||||||
|
git("fetch", "origin")
|
||||||
|
|
||||||
|
# ponytail: reset straight to the remote - pull-down-only means local history never matters,
|
||||||
|
# and this can't produce a merge conflict the way fetch + merge could
|
||||||
|
print("* * Resetting local to match upstream")
|
||||||
|
git("reset", "--hard", f"origin/{BRANCH}")
|
||||||
|
|
||||||
|
# ponytail: clears leftovers that would block the reset. Respects .gitignore - no -x flag,
|
||||||
|
# so anything the game generates stays put as long as the repo ignores it
|
||||||
|
print("* * Clearing stale untracked pack files")
|
||||||
|
git("clean", "-fd")
|
||||||
|
|
||||||
|
print("* Pack Update Complete!")
|
||||||
|
else:
|
||||||
|
print("* No .git folder was found. Installing Pack!")
|
||||||
|
|
||||||
|
print("* * Cloning repo into temp folder")
|
||||||
|
tmp = Path("repo.tmp")
|
||||||
|
git("clone", "--branch", BRANCH, REPO_URL, str(tmp))
|
||||||
|
|
||||||
|
print("* * Copying repo out of temp and into current folder")
|
||||||
|
shutil.copytree(tmp, ".", dirs_exist_ok=True) # ponytail: merges like robocopy /E; move refuses existing dirs
|
||||||
|
shutil.rmtree(tmp)
|
||||||
|
|
||||||
|
print("* Pack Installation Complete!")
|
||||||
|
|
||||||
|
print("****************************************")
|
||||||
+152
@@ -0,0 +1,152 @@
|
|||||||
|
import sys, json, subprocess, configparser, shutil, os, platform, urllib.request
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# User Variables
|
||||||
|
MAXRAM = "8G"
|
||||||
|
MINRAM = "4G"
|
||||||
|
JVMARGS = ""
|
||||||
|
REPO_URL = ""
|
||||||
|
BRANCH = "main"
|
||||||
|
|
||||||
|
InstanceConfig = configparser.ConfigParser()
|
||||||
|
|
||||||
|
if Path("../instance.cfg").is_file():
|
||||||
|
# Launched by Prism/MultiMC - read the instance's own metadata
|
||||||
|
InstanceConfig.read("../instance.cfg")
|
||||||
|
with open("../mmc-pack.json", "r") as file:
|
||||||
|
Components = json.load(file)["components"]
|
||||||
|
# ponytail: match on uid, not list index - component order isn't guaranteed
|
||||||
|
Minecraft = next(c for c in Components if c["uid"] == "net.minecraft")
|
||||||
|
Modloader = next(c for c in Components
|
||||||
|
if c["uid"] != "net.minecraft" and not c.get("dependencyOnly"))
|
||||||
|
MinecraftVersion = Minecraft["version"]
|
||||||
|
ModloaderName = Modloader["cachedName"]
|
||||||
|
ModloaderVersion = Modloader["version"]
|
||||||
|
elif Path("env.txt").is_file():
|
||||||
|
# Standalone - same INI format, plus the versions mmc-pack.json would have given us
|
||||||
|
InstanceConfig.read("env.txt")
|
||||||
|
MinecraftVersion = InstanceConfig['General']['MinecraftVersion']
|
||||||
|
ModloaderName = InstanceConfig['General']['ModloaderName']
|
||||||
|
ModloaderVersion = InstanceConfig['General']['ModloaderVersion']
|
||||||
|
else:
|
||||||
|
sys.exit("* Found neither ../instance.cfg nor env.txt - cannot identify this instance.")
|
||||||
|
|
||||||
|
PackName = InstanceConfig['General']['name']
|
||||||
|
|
||||||
|
# Program Variables DO NOT TOUCH
|
||||||
|
MINGIT_URL = "https://github.com/git-for-windows/git/releases/download/v2.45.2.windows.1/MinGit-2.45.2-64-bit.zip"
|
||||||
|
MINGIT = Path(".mingit/cmd/git.exe")
|
||||||
|
|
||||||
|
IS_NEOFORGE = ModloaderName == "NeoForge"
|
||||||
|
SERVER_JAR = Path("server-installer.jar")
|
||||||
|
# ponytail: version-stamped path - a modloader bump makes this vanish and the install re-runs for free
|
||||||
|
ARGS_FILE = Path("libraries/net/neoforged/neoforge", ModloaderVersion,
|
||||||
|
"win_args.txt" if os.name == "nt" else "unix_args.txt")
|
||||||
|
SERVER_JAR_URL = (
|
||||||
|
f"https://maven.neoforged.net/releases/net/neoforged/neoforge/{ModloaderVersion}/neoforge-{ModloaderVersion}-installer.jar"
|
||||||
|
if IS_NEOFORGE else
|
||||||
|
f"https://meta.fabricmc.net/v2/versions/loader/{MinecraftVersion}/{ModloaderVersion}/1.0.1/server/jar"
|
||||||
|
)
|
||||||
|
|
||||||
|
JAVA_DIR = Path(".Java21")
|
||||||
|
JAVA = JAVA_DIR / "bin" / ("java.exe" if os.name == "nt" else "java")
|
||||||
|
# ponytail: Adoptium takes os/arch as path segments - build them instead of hardcoding windows/x64
|
||||||
|
JAVA_OS = {"Windows": "windows", "Linux": "linux"}[platform.system()]
|
||||||
|
JAVA_ARCH = {"AMD64": "x64", "x86_64": "x64"}[platform.machine()]
|
||||||
|
JAVA_URL = f"https://api.adoptium.net/v3/binary/latest/21/ga/{JAVA_OS}/{JAVA_ARCH}/jre/hotspot/normal/eclipse"
|
||||||
|
JAVA_ARCHIVE = "java.zip" if os.name == "nt" else "java.tar.gz"
|
||||||
|
|
||||||
|
print("****************************************")
|
||||||
|
print(f"* Launching {PackName} Server")
|
||||||
|
print(f"* {MinecraftVersion} / {ModloaderName} {ModloaderVersion}")
|
||||||
|
|
||||||
|
# ponytail: check the local MinGit before downloading - which() never sees it, it's not on PATH
|
||||||
|
GIT = shutil.which("git") or (str(MINGIT.resolve()) if MINGIT.is_file() else None)
|
||||||
|
if GIT is None:
|
||||||
|
if os.name != "nt":
|
||||||
|
sys.exit("* Git not found, please install Git!")
|
||||||
|
print("* Git not found, downloading and installing Git.")
|
||||||
|
urllib.request.urlretrieve(MINGIT_URL, "MinGit.zip")
|
||||||
|
shutil.unpack_archive("MinGit.zip", ".mingit")
|
||||||
|
Path("MinGit.zip").unlink()
|
||||||
|
GIT = str(MINGIT.resolve())
|
||||||
|
|
||||||
|
def git(*args):
|
||||||
|
with open("launchServer.log", "a") as log:
|
||||||
|
subprocess.run([GIT, *args], stdout=log, stderr=subprocess.STDOUT, check=True)
|
||||||
|
|
||||||
|
def AcceptEula():
|
||||||
|
eula = Path("eula.txt")
|
||||||
|
# ponytail: substring check, not a properties parse - the file has one setting
|
||||||
|
if eula.is_file() and "eula=true" in eula.read_text():
|
||||||
|
return
|
||||||
|
eula.write_text("eula=true\n")
|
||||||
|
|
||||||
|
if Path(".git").is_dir():
|
||||||
|
print("* Updating Modpack Server from Gitlab")
|
||||||
|
|
||||||
|
print("* * Fetching changes from upstream")
|
||||||
|
git("fetch", "origin")
|
||||||
|
|
||||||
|
print("* * Resetting local to match upstream")
|
||||||
|
git("reset", "--hard", f"origin/{BRANCH}")
|
||||||
|
|
||||||
|
print("* * Clearing stale untracked pack files")
|
||||||
|
git("clean", "-fd")
|
||||||
|
|
||||||
|
print("* Server Update Complete!")
|
||||||
|
else:
|
||||||
|
print("* Installing Modpack Server from Gitlab")
|
||||||
|
|
||||||
|
print("* * Cloning repo into temp folder")
|
||||||
|
tmp = Path("repo.tmp")
|
||||||
|
git("clone", "--branch", BRANCH, REPO_URL, str(tmp))
|
||||||
|
|
||||||
|
print("* * Copying repo out of temp and into current folder")
|
||||||
|
shutil.copytree(tmp, ".", dirs_exist_ok=True) # ponytail: merges like robocopy /E; move refuses existing dirs
|
||||||
|
shutil.rmtree(tmp)
|
||||||
|
|
||||||
|
print("* Server Installation Complete!")
|
||||||
|
|
||||||
|
print("****************************************")
|
||||||
|
print("* Setting up server runtime")
|
||||||
|
|
||||||
|
if not JAVA.is_file():
|
||||||
|
print("* * Downloading Java 21")
|
||||||
|
urllib.request.urlretrieve(JAVA_URL, JAVA_ARCHIVE)
|
||||||
|
print("* * Extracting Java 21")
|
||||||
|
shutil.unpack_archive(JAVA_ARCHIVE) # ponytail: replaces `tar -xf`, picks zip vs tar.gz by extension
|
||||||
|
Path(JAVA_ARCHIVE).unlink()
|
||||||
|
shutil.move(str(next(Path(".").glob("jdk-*"))), JAVA_DIR)
|
||||||
|
|
||||||
|
if IS_NEOFORGE:
|
||||||
|
if not ARGS_FILE.is_file():
|
||||||
|
print(f"* * Downloading {ModloaderName} installer")
|
||||||
|
urllib.request.urlretrieve(SERVER_JAR_URL, SERVER_JAR)
|
||||||
|
print(f"* * Installing {ModloaderName} server")
|
||||||
|
subprocess.run([str(JAVA), "-jar", str(SERVER_JAR), "--installServer", "."], check=True)
|
||||||
|
# NeoForge ships an @argfile instead of a runnable jar
|
||||||
|
LoaderArgs = [f"@{ARGS_FILE}"]
|
||||||
|
else:
|
||||||
|
if not SERVER_JAR.is_file():
|
||||||
|
print(f"* * Downloading {ModloaderName} server jar")
|
||||||
|
urllib.request.urlretrieve(SERVER_JAR_URL, SERVER_JAR)
|
||||||
|
LoaderArgs = ["-jar", str(SERVER_JAR)]
|
||||||
|
|
||||||
|
print("* Server runtime ready!")
|
||||||
|
|
||||||
|
ModsList = Path("NonServerFriendlyMods.txt")
|
||||||
|
if ModsList.is_file():
|
||||||
|
print("****************************************")
|
||||||
|
print("* Removing mods not friendly for servers")
|
||||||
|
for line in ModsList.read_text().splitlines():
|
||||||
|
if line.strip():
|
||||||
|
Path("mods", line.strip()).unlink(missing_ok=True)
|
||||||
|
print("* Removed problematic mods")
|
||||||
|
|
||||||
|
print("****************************************")
|
||||||
|
print("* Starting Modpack Server")
|
||||||
|
AcceptEula()
|
||||||
|
subprocess.run([str(JAVA), f"-Xms{MINRAM}", f"-Xmx{MAXRAM}", *JVMARGS.split(),
|
||||||
|
*LoaderArgs, "nogui"])
|
||||||
|
input("Press Enter to exit...")
|
||||||
Reference in New Issue
Block a user