#!/usr/bin/env python3 import os, sys, shutil, requests, tempfile, glob, subprocess, argparse from termcolor import cprint from typing import Any parser = argparse.ArgumentParser(description="server script for FishPogPixelmon") parser.add_argument("--plugins", "-p", help="refreshes plugins", action="store_true") args = parser.parse_args() OS = sys.platform SERVER_DIR = os.getcwd() MOD_DOWNLOADER_URL = "https://github.com/Joshyx/ModpackDownloader/releases/download/v1.3/ModpackDownloader-1.3.jar" MODPACK_RELEASES_URL = "https://git.233hfd.com/api/v1/repos/joey/FishPogPixelmon/releases?limit=1" ARCLIGHT_URL = "https://github.com/IzzelAliz/Arclight/releases/download/1.16%2F1.0.24/arclight-forge-1.16.5-1.0.24.jar" ARCLIGHT_JAR = "arclight.jar" INSTANCE_DIR = os.path.join(str(os.getenv("HOME")), "pixelmon") DELETION_EXEMPTED_MODS = ["TrainerCommands-1.16.5-2.6.0.jar"] # main def __main__(): header() needs_mods_plugins = instance() if needs_mods_plugins: mods() if args.plugins: plugins() arclight() launch() # launcher def launch(): if input("launch server? [Y/n] ").lower() == "n": exit(0) os.chdir(f"{INSTANCE_DIR}/.minecraft") subprocess.run( [ "java", "--illegal-access=permit", "-Xmx30720M", "-Xms1024M", "-jar", ARCLIGHT_JAR, "--nogui", ] ) # arclight def arclight(): os.makedirs(f"{INSTANCE_DIR}/.minecraft", exist_ok=True) os.chdir(f"{INSTANCE_DIR}/.minecraft") if os.path.exists(os.path.join(f"{INSTANCE_DIR}/.minecraft", "arclight.jar")): return cprint("arclight.jar not found - downloading", "yellow") r = requests.get(ARCLIGHT_URL, allow_redirects=True) open("arclight.jar", "wb").write(r.content) f = open("eula.txt", "w") f.write("eula=true") f.close() # mods def mods(): os.chdir(INSTANCE_DIR) if not os.path.exists(os.path.join(INSTANCE_DIR, "downloader.jar")): cprint("downloader.jar not found - downloading", "yellow") r = requests.get(MOD_DOWNLOADER_URL, allow_redirects=True) open("downloader.jar", "wb").write(r.content) cprint("downloading mods. this may take a while, please wait.", "green") my_env = os.environ.copy() my_env["CURSEFORGE_API_KEY"] = "$2a$10$QbCxI6f4KxEs50QKwE2piu1t6oOA8ayOw27H9N/eaH3Sdp5NTWwvO" os.makedirs(os.path.join(INSTANCE_DIR, "mods")) subprocess.run(["java", "-jar", "downloader.jar", ".", "mods"], env=my_env) for file in glob.glob(os.path.join(INSTANCE_DIR, ".minecraft", "mods", "*")): if os.path.basename(file) in DELETION_EXEMPTED_MODS: continue os.remove(file) for file in glob.glob(os.path.join(INSTANCE_DIR, "mods", "mods", "*")): shutil.move(file, os.path.join(INSTANCE_DIR, ".minecraft", "mods", os.path.basename(file))) shutil.rmtree(os.path.join(INSTANCE_DIR, "mods")) cprint("mods downloaded successfully", "green") # plugins def plugins(): os.chdir(INSTANCE_DIR) os.makedirs(os.path.join(INSTANCE_DIR, ".minecraft", "plugins"), exist_ok=True) for file in glob.glob(os.path.join(INSTANCE_DIR, ".minecraft", "plugins", "*")): if file.endswith(".jar"): os.remove(file) for file in glob.glob(os.path.join(SERVER_DIR, "plugins", "*")): shutil.copy(file, os.path.join(INSTANCE_DIR, ".minecraft", "plugins", os.path.basename(file))) cprint("plugins copied successfully", "green") # multimc def instance(): unclean = False release = most_recent_release() if not os.path.exists(INSTANCE_DIR): unclean = True cprint("instance not found - downloading", "yellow") download_instance(release) version = "" if os.path.exists(f"{INSTANCE_DIR}/.version"): f = open(f"{INSTANCE_DIR}/.version", "r") version = f.read() if version != release["tag_name"]: unclean = True cprint("new update available! - downloading", "green") download_instance(release) cprint("instance is up to date", "green") return unclean def download_instance(release: dict[str, Any]): os.makedirs(os.path.join(INSTANCE_DIR, ".minecraft"), exist_ok=True) TMP = tempfile.mkdtemp() os.chdir(TMP) download_url = get_release_asset(release) r = requests.get(download_url, allow_redirects=True) open("instance.zip", "wb").write(r.content) shutil.unpack_archive("instance.zip", ".") os.remove("instance.zip") for file in glob.glob(os.path.join(TMP, "overrides", "*")): if file == os.path.join(TMP, "overrides", "options.txt") and os.path.exists( os.path.join(INSTANCE_DIR, ".minecraft", "options.txt") ): continue if os.path.exists(os.path.join(INSTANCE_DIR, ".minecraft", os.path.basename(file))): if os.path.isdir(os.path.join(INSTANCE_DIR, ".minecraft", os.path.basename(file))): shutil.rmtree(os.path.join(INSTANCE_DIR, ".minecraft", os.path.basename(file))) else: os.remove(os.path.join(INSTANCE_DIR, ".minecraft", os.path.basename(file))) shutil.move(file, os.path.join(INSTANCE_DIR, ".minecraft", os.path.basename(file))) shutil.rmtree(os.path.join(TMP, "overrides")) for file in glob.glob(os.path.join(TMP, "*")): if os.path.exists(os.path.join(INSTANCE_DIR, os.path.basename(file))): if os.path.isdir(os.path.join(INSTANCE_DIR, os.path.basename(file))): shutil.rmtree(os.path.join(INSTANCE_DIR, os.path.basename(file))) else: os.remove(os.path.join(INSTANCE_DIR, os.path.basename(file))) shutil.move(file, os.path.join(INSTANCE_DIR, os.path.basename(file))) os.chdir(INSTANCE_DIR) f = open(".version", "w") f.write(release["tag_name"]) f.close() # releases def most_recent_release() -> dict[str, Any]: r = requests.get(MODPACK_RELEASES_URL) releases: list[dict[str, Any]] = r.json() return releases[0] def most_recent_version(release: dict[str, Any]) -> str: return release["tag_name"] def get_release_asset(release: dict[str, Any]): return release["assets"][0]["browser_download_url"] # ascii art lol def header(): cprint( """ _______ __ __ _______ | _ ||__|.-----.| |--.| _ |.-----..-----. |. 1___|| ||__ --|| ||. 1 || _ || _ | |. __) |__||_____||__|__||. ____||_____||___ | |: | |: | |_____| |::.| |::.| `---' `---' _______ __ __ | _ ||__|.--.--..-----.| |.--------..-----..-----. |. 1 || ||_ _|| -__|| || || _ || | |. ____||__||__.__||_____||__||__|__|__||_____||__|__| |: | |::.| `---' """, "green", ) # run app __main__()