import argparse import logging import os import shutil import zipfile import requests class SolderPacker: def __init__(self, solder_dir: str, solder_url: str, solder_key: str): self.solder_dir = solder_dir self.solder_url = solder_url self.solder_key = solder_key def compress_jar(self, mod_slug: str, minecraft_version: str, mod_loader: str, mod_version: str, jar_path: str): export_path = f"{self.solder_dir}{os.sep}{mod_slug}" if not os.path.exists(export_path): os.makedirs(export_path) zip_path = f"{export_path}{os.sep}{mod_slug}-{minecraft_version}-{mod_loader}-{mod_version}.zip" if os.path.exists(zip_path): os.remove(zip_path) mod_zip = zipfile.ZipFile( file=zip_path, mode="w", compression=zipfile.ZIP_DEFLATED, compresslevel=9) mod_zip.write(jar_path, f"mods/{mod_slug}-{minecraft_version}-{mod_loader}-{mod_version}.jar") mod_zip.close() return zip_path def copy_zip(self, mod_slug: str, minecraft_version: str, mod_loader: str, mod_version: str, zip_src): export_path = f"{self.solder_dir}{os.sep}{mod_slug}" if not os.path.exists(export_path): os.makedirs(export_path) zip_path = f"{export_path}{os.sep}{mod_slug}-{minecraft_version}-{mod_loader}-{mod_version}.zip" shutil.copy(zip_src, zip_path) return zip_path def register_mod(self, mod_slug: str, mod_name: str, mod_author: str, mod_description: str, mod_url: str): resp = requests.get(f"{self.solder_url}/api/mod/{mod_slug}") if resp.status_code != 200: mod_data = { "name": mod_slug, "pretty_name": mod_name, "author": mod_author, "description": mod_description, "link": mod_url } resp = requests.post(f"{self.solder_url}/mod/create", cookies={"technic_solder_session": self.solder_key}, data=mod_data, headers={"Origin": self.solder_url, "Referer": f"{self.solder_url}/mod/create"}) if resp.status_code == 404: logging.debug("failed to register mod") return False resp = requests.get(f"{self.solder_url}/api/mod/{mod_slug}") return resp.json() else: logging.debug("mod already registered") def register_mod_version(self, mod_slug: str, minecraft_version: str, mod_loader: str, mod_version: str): resp = requests.get(f"{self.solder_url}/api/mod/{mod_slug}") if resp.status_code != 200: logging.debug("mod doesn't exist") return mod_id = resp.json()["id"] resp = requests.get(f"{self.solder_url}/api/mod/{mod_slug}/{mod_version}") if resp.status_code != 200: logging.debug("creating mod version") version_data = { "mod-id": mod_id, "add-version": f"{minecraft_version}-{mod_loader}-{mod_version}", "add-md5": "" } resp = requests.post(f"{self.solder_url}/mod/add-version", cookies={"technic_solder_session": self.solder_key}, data=version_data, headers={"Origin": self.solder_url, "X-Requested-With": "XMLHttpRequest"}) if resp.status_code != 200: logging.debug("failed to create mod version") else: logging.debug("created mod version") else: logging.debug("mod version already registered. updating hash") version_data = { "version-id": resp.json()["id"], "md5": "" } resp = requests.post(f"{self.solder_url}/mod/rehash", cookies={"technic_solder_session": self.solder_key}, data=version_data, headers={"Origin": self.solder_url, "X-Requested-With": "XMLHttpRequest"}) if resp.status_code != 200: logging.debug("failed to rehash mod version") else: logging.debug("rehashed mod version") def main(): try: argp = argparse.ArgumentParser() mod_data = argp.add_argument_group(title="Mod Data") mod_data.add_argument("-s", "--slug", help="Mod Slug") mod_data.add_argument("-n", "--name", help="Mod Name") mod_data.add_argument("-v", "--version", help="Mod Version") mod_data.add_argument("-a", "--author", help="Mod Author") mod_data.add_argument("-d", "--description", help="Mod Description") mod_data.add_argument("-u", "--url", help="Mod URL") mod_data.add_argument("-m", "--minecraft", type=str, help="Minecraft Version") mod_data.add_argument("-l", "--loader", type=str, choices=["forge", "fabric", "quilt"], default="forge", help="Mod Loader") argp.add_argument("-p", "--path", required=True, default=os.getcwd(), help="Export Path") solder_api = argp.add_argument_group(title="Solder API") solder_api.add_argument("-sa", "--api", default=os.environ.get("SOLDER_URL"), type=str, help="Solder instance URL") solder_api.add_argument("-sk", "--key", default=os.environ.get("SOLDER_KEY"), type=str, help="Solder API Key") input_type = argp.add_mutually_exclusive_group(required=True) input_type.add_argument("-j", "--jar", type=str, help="The jar file to package and upload as a mod.") input_type.add_argument("-z", "--zip", type=str, help="The zip file to upload.") argp.set_defaults() args = argp.parse_args() sp = SolderPacker(args.path, args.api, args.key) if args.jar: if not os.path.isfile(args.jar): print("Malformed JAR path") exit() sp.compress_jar(args.slug, args.minecraft, args.loader, args.version, args.jar) elif args.zip: if not os.path.isfile(args.zip): print("Malformed ZIP path") exit() sp.copy_zip(args.slug, args.minecraft, args.loader, args.version, args.zip) sp.register_mod(args.slug, args.name, args.author, args.description, args.url) sp.register_mod_version(args.slug, args.minecraft, args.loader, args.version) except KeyboardInterrupt: print("Packing cancelled") if __name__ == '__main__': main()