From 860be444d706c31e9e96c564fc0274806c9e2882 Mon Sep 17 00:00:00 2001 From: Charles Danesi Date: Sun, 14 Dec 2025 07:57:39 -0500 Subject: [PATCH] initial commit --- .gitignore | 2 + README.md | 1 + example-config.json | 27 +++++++++++++ mod_updater.py | 92 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 example-config.json create mode 100644 mod_updater.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..75a29fb --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +downloads/** diff --git a/README.md b/README.md new file mode 100644 index 0000000..15934cb --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# mod-updater diff --git a/example-config.json b/example-config.json new file mode 100644 index 0000000..257268c --- /dev/null +++ b/example-config.json @@ -0,0 +1,27 @@ +{ + "server1": { + "mc_version": "1.21.10", + "loader": "fabric", + "mods": [ + "fabric-api", + "lithium", + "placeholder-api", + "rei", + "spark", + "simple-voice-chat" + ] + }, + "server2": { + "mc_version": "1.19.2", + "loader": "fabric", + "mods": [ + "dynmap", + "fabric-api", + "lithium", + "phosphor", + "placeholder-api", + "spark", + "simple-voice-chat" + ] + } +} diff --git a/mod_updater.py b/mod_updater.py new file mode 100644 index 0000000..59f122c --- /dev/null +++ b/mod_updater.py @@ -0,0 +1,92 @@ +import json +import os + +import requests + +CONFIG_FILE = "config.json" +OUTPUT_DIR = "downloads" + +MODRINTH_API = "https://api.modrinth.com/v2" + + +def load_config(): + with open(CONFIG_FILE, "r") as f: + return json.load(f) + + +def get_mod_project(mod_id): + """Fetch project info from Modrinth by slug or ID.""" + url = f"{MODRINTH_API}/project/{mod_id}" + r = requests.get(url) + if r.status_code != 200: + print(f"[!] Failed to get project: {mod_id}") + return None + return r.json() + + +def get_latest_version(project_id, mc_version, loader): + """Fetch latest version compatible with the MC version + loader.""" + url = f"{MODRINTH_API}/project/{project_id}/version" + params = {"game_versions": f'["{mc_version}"]', "loaders": f'["{loader}"]'} + r = requests.get(url, params=params) + if r.status_code != 200 or len(r.json()) == 0: + print(f"[!] No compatible versions for {project_id}") + return None + + # First entry is latest + return r.json()[0] + + +def download_file(url, dest): + r = requests.get(url, stream=True) + if r.status_code != 200: + print(f"[!] Failed to download: {url}") + return + with open(dest, "wb") as f: + for chunk in r.iter_content(8192): + f.write(chunk) + + +def update_server(name, settings): + mc_version = settings["mc_version"] + loader = settings["loader"] + mods = settings["mods"] + + print(f"\n=== Updating {name} ===") + out_dir = os.path.join(OUTPUT_DIR, name) + os.makedirs(out_dir, exist_ok=True) + + for mod in mods: + print(f"\n→ {mod}") + + project = get_mod_project(mod) + if not project: + continue + + project_id = project["id"] + version = get_latest_version(project_id, mc_version, loader) + if not version: + continue + + file_info = version["files"][0] + filename = file_info["filename"] + url = file_info["url"] + + dest = os.path.join(out_dir, filename) + print(f" Downloading {filename}...") + download_file(url, dest) + + print(f"\n✔ Finished {name}") + + +def main(): + config = load_config() + + for server_name, settings in config.items(): + update_server(server_name, settings) + + print("\nAll mods updated!") + + +if __name__ == "__main__": + main()