diff options
| author | Mehmet Samet Duman <yongdohyun@projecttick.org> | 2026-04-02 18:43:51 +0300 |
|---|---|---|
| committer | Mehmet Samet Duman <yongdohyun@projecttick.org> | 2026-04-02 18:43:51 +0300 |
| commit | b85e90fc3480da0e6a48da73201a0b22488cc650 (patch) | |
| tree | 42b2e083e7d268747b01a03c0bedb48a9394585e /meta | |
| parent | 5c7048091e3a191e8a34f26852a8976b254e339b (diff) | |
| parent | f88d1f18953f9619444d56756702c7eb54580ab1 (diff) | |
| download | Project-Tick-b85e90fc3480da0e6a48da73201a0b22488cc650.tar.gz Project-Tick-b85e90fc3480da0e6a48da73201a0b22488cc650.zip | |
Add 'meta/' from commit 'f88d1f18953f9619444d56756702c7eb54580ab1'
git-subtree-dir: meta
git-subtree-mainline: 5c7048091e3a191e8a34f26852a8976b254e339b
git-subtree-split: f88d1f18953f9619444d56756702c7eb54580ab1
Diffstat (limited to 'meta')
62 files changed, 12960 insertions, 0 deletions
diff --git a/meta/.dockerignore b/meta/.dockerignore new file mode 100644 index 0000000000..373630e9e5 --- /dev/null +++ b/meta/.dockerignore @@ -0,0 +1,11 @@ +.git/ +.idea/ + +caches/ +.idea/ +__pycache__/ +public/ + +launcher/ +upstream/ +config/ diff --git a/meta/.envrc b/meta/.envrc new file mode 100644 index 0000000000..3550a30f2d --- /dev/null +++ b/meta/.envrc @@ -0,0 +1 @@ +use flake diff --git a/meta/.gitignore b/meta/.gitignore new file mode 100644 index 0000000000..7f7232ca89 --- /dev/null +++ b/meta/.gitignore @@ -0,0 +1,17 @@ +.idea/ + +# direnv / Nix +.direnv/ +.pre-commit-config.yaml + +result + +public/*/ + +caches/ +!caches/*/.keep +cache/ +__pycache__ +config.sh +launcher +upstream diff --git a/meta/COPYING b/meta/COPYING new file mode 100644 index 0000000000..d189af8385 --- /dev/null +++ b/meta/COPYING @@ -0,0 +1,52 @@ +Microsoft Public License (Ms-PL) + +This license governs use of the accompanying software. If you use the +software, you accept this license. If you do not accept the license, do not +use the software. + +1. Definitions +The terms "reproduce," "reproduction," "derivative works," and "distribution" +have the same meaning here as under U.S. copyright law. A "contribution" is +the original software, or any additions or changes to the software. A +"contributor" is any person that distributes its contribution under this +license. "Licensed patents" are a contributor's patent claims that read +directly on its contribution. + +2. Grant of Rights + (A) Copyright Grant- Subject to the terms of this license, including the + license conditions and limitations in section 3, each contributor grants + you a non-exclusive, worldwide, royalty-free copyright license to + reproduce its contribution, prepare derivative works of its contribution, + and distribute its contribution or any derivative works that you create. + + (B) Patent Grant- Subject to the terms of this license, including the + license conditions and limitations in section 3, each contributor grants + you a non-exclusive, worldwide, royalty-free license under its licensed + patents to make, have made, use, sell, offer for sale, import, and/or + otherwise dispose of its contribution in the software or derivative works + of the contribution in the software. + +3. Conditions and Limitations + (A) No Trademark License- This license does not grant you rights to use + any contributors' name, logo, or trademarks. + + (B) If you bring a patent claim against any contributor over patents that + you claim are infringed by the software, your patent license from such + contributor to the software ends automatically. + + (C) If you distribute any portion of the software, you must retain all + copyright, patent, trademark, and attribution notices that are present in + the software. + + (D) If you distribute any portion of the software in source code form, + you may do so only under this license by including a complete copy of + this license with your distribution. If you distribute any portion of the + software in compiled or object code form, you may only do so under a + license that complies with this license. + + (E) The software is licensed "as-is." You bear the risk of using it. The + contributors give no express warranties, guarantees, or conditions. You + may have additional consumer rights under your local laws which this + license cannot change. To the extent permitted under your local laws, the + contributors exclude the implied warranties of merchantability, fitness + for a particular purpose and non-infringement.
\ No newline at end of file diff --git a/meta/README.md b/meta/README.md new file mode 100644 index 0000000000..02b43e60f4 --- /dev/null +++ b/meta/README.md @@ -0,0 +1,37 @@ +# Prism Launcher Meta + +Scripts to generate jsons and jars that Prism Launcher will access. + +## Recommended Deployment + +Assuming you have a Flake-based NixOS configuration + +- Add Flake input: + + ```nix + { + inputs.prism-meta.url = "github:PrismLauncher/meta"; + } + ``` + +- Import NixOS module and configure + + ```nix + {inputs, ...}: { + imports = [inputs.prism-meta.nixosModules.default]; + services.blockgame-meta = { + enable = true; + settings = { + DEPLOY_TO_GIT = "true"; + GIT_AUTHOR_NAME = "Herpington Derpson"; + GIT_AUTHOR_EMAIL = "herpderp@derpmail.com"; + GIT_COMMITTER_NAME = "Herpington Derpson"; + GIT_COMMITTER_EMAIL = "herpderp@derpmail.com"; + }; + }; + } + ``` + +- Rebuild and activate! +- Trigger it `systemctl start blockgame-meta.service` +- Monitor it `journalctl -fu blockgame-meta.service` diff --git a/meta/caches/forge_cache/.keep b/meta/caches/forge_cache/.keep new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/meta/caches/forge_cache/.keep diff --git a/meta/caches/http_cache/.keep b/meta/caches/http_cache/.keep new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/meta/caches/http_cache/.keep diff --git a/meta/config.example.sh b/meta/config.example.sh new file mode 100644 index 0000000000..835059f3af --- /dev/null +++ b/meta/config.example.sh @@ -0,0 +1,13 @@ +export META_UPSTREAM_DIR=upstream +export META_LAUNCHER_DIR=launcher +export DEPLOY_TO_FOLDER=false +export DEPLOY_FOLDER=/app/public/v1 +export DEPLOY_FOLDER_USER=http +export DEPLOY_FOLDER_GROUP=http + +export DEPLOY_TO_GIT=true +export GIT_AUTHOR_NAME="Herpington Derpson" +export GIT_AUTHOR_EMAIL="herpderp@derpmail.com" +export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME" +export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL" +export GIT_SSH_COMMAND="ssh -i ${BASEDIR}/config/deploy.key" diff --git a/meta/flake.lock b/meta/flake.lock new file mode 100644 index 0000000000..6d54022b39 --- /dev/null +++ b/meta/flake.lock @@ -0,0 +1,92 @@ +{ + "nodes": { + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1751413152, + "narHash": "sha256-Tyw1RjYEsp5scoigs1384gIg6e0GoBVjms4aXFfRssQ=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "77826244401ea9de6e3bac47c2db46005e1f30b5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "git-hooks": { + "inputs": { + "flake-compat": [], + "gitignore": "gitignore", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1750779888, + "narHash": "sha256-wibppH3g/E2lxU43ZQHC5yA/7kIKLGxVEnsnVK1BtRg=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "16ec914f6fb6f599ce988427d9d94efddf25fe6d", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "git-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1751382304, + "narHash": "sha256-p+UruOjULI5lV16FkBqkzqgFasLqfx0bihLBeFHiZAs=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "d31a91c9b3bee464d054633d5f8b84e17a637862", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-parts": "flake-parts", + "git-hooks": "git-hooks", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/meta/flake.nix b/meta/flake.nix new file mode 100644 index 0000000000..aaacaa58e5 --- /dev/null +++ b/meta/flake.nix @@ -0,0 +1,35 @@ +{ + description = "Prism Launcher Metadata generation scripts"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + flake-parts = { + url = "github:hercules-ci/flake-parts"; + inputs.nixpkgs-lib.follows = "nixpkgs"; + }; + git-hooks = { + url = "github:cachix/git-hooks.nix"; + inputs.flake-compat.follows = ""; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = inputs: + inputs.flake-parts.lib.mkFlake + {inherit inputs;} + { + imports = [ + inputs.git-hooks.flakeModule + + ./nix/dev.nix + ./nix/nixos + ./nix/packages.nix + ]; + + # Supported systems. + systems = [ + "x86_64-linux" + "aarch64-linux" + ]; + }; +} diff --git a/meta/garnix.yaml b/meta/garnix.yaml new file mode 100644 index 0000000000..312815da5d --- /dev/null +++ b/meta/garnix.yaml @@ -0,0 +1,5 @@ +builds: + include: + - "checks.x86_64-linux.*" + - "devShells.*.*" + - "packages.*.*" diff --git a/meta/init.sh b/meta/init.sh new file mode 100644 index 0000000000..c9bfa8133f --- /dev/null +++ b/meta/init.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -ex + +if [ -f config.sh ]; then + source config.sh +fi + +export META_CACHE_DIR=${CACHE_DIRECTORY:-./caches} +export META_UPSTREAM_DIR=${META_UPSTREAM_DIR:-${STATE_DIRECTORY:-.}/upstream} +export META_LAUNCHER_DIR=${META_LAUNCHER_DIR:-${STATE_DIRECTORY:-.}/launcher} + +function init_repo { + # no op if target already exists + if [ -d "$1" ]; then + return 0 + fi + + # fail if no repo url is specified + if [ -z "$2" ]; then + echo "Can't initialize missing $1 directory. Please specify $3" >&2 + return 1 + fi + + git clone "$2" "$1" +} + +init_repo "$META_UPSTREAM_DIR" "$META_UPSTREAM_URL" "META_UPSTREAM_URL" +init_repo "$META_LAUNCHER_DIR" "$META_LAUNCHER_URL" "META_LAUNCHER_URL" diff --git a/meta/meta/__init__.py b/meta/meta/__init__.py new file mode 100644 index 0000000000..05cee3e7d7 --- /dev/null +++ b/meta/meta/__init__.py @@ -0,0 +1 @@ +"""Meta package of meta""" diff --git a/meta/meta/common/__init__.py b/meta/meta/common/__init__.py new file mode 100644 index 0000000000..04e3bdfbb0 --- /dev/null +++ b/meta/meta/common/__init__.py @@ -0,0 +1,125 @@ +import os +import os.path +import datetime +import hashlib +import sys +from urllib.parse import urlparse +from typing import Any, Optional, Callable + +import requests +from cachecontrol import CacheControl # type: ignore +from cachecontrol.caches import FileCache # type: ignore + +LAUNCHER_MAVEN = "https://files.prismlauncher.org/maven/%s" + + +def serialize_datetime(dt: datetime.datetime): + if dt.tzinfo is None: + return dt.replace(tzinfo=datetime.timezone.utc).isoformat() + + return dt.isoformat() + + +def cache_path(): + if "META_CACHE_DIR" in os.environ: + return os.environ["META_CACHE_DIR"] + return "cache" + + +def launcher_path(): + if "META_LAUNCHER_DIR" in os.environ: + return os.environ["META_LAUNCHER_DIR"] + return "launcher" + + +def upstream_path(): + if "META_UPSTREAM_DIR" in os.environ: + return os.environ["META_UPSTREAM_DIR"] + return "upstream" + + +def ensure_upstream_dir(path): + path = os.path.join(upstream_path(), path) + if not os.path.exists(path): + os.makedirs(path) + + +def ensure_component_dir(component_id: str): + path = os.path.join(launcher_path(), component_id) + if not os.path.exists(path): + os.makedirs(path) + + +def transform_maven_key(maven_key: str): + return maven_key.replace(":", ".") + + +def replace_old_launchermeta_url(url: str): + o = urlparse(url) + if o.netloc == "launchermeta.mojang.com": + return o._replace(netloc="piston-meta.mojang.com").geturl() + + return url + + +def get_all_bases(cls: type, bases: Optional[list[type]] = None): + bases = bases or [] + bases.append(cls) + for c in cls.__bases__: + get_all_bases(c, bases) + return tuple(bases) + + +def merge_dict(base: dict[Any, Any], overlay: dict[Any, Any]): + for k, v in base.items(): + if isinstance(v, dict): + merge_dict(v, overlay.setdefault(k, {})) # type: ignore + else: + if k not in overlay: + overlay[k] = v + + return overlay + + +def default_session(): + cache = FileCache(os.path.join(cache_path(), "http_cache")) + sess = CacheControl(requests.Session(), cache) + + sess.headers.update({"User-Agent": "PrismLauncherMeta/1.0"}) + + return sess + + +def remove_files(file_paths: list[str]) -> None: + for file_path in file_paths: + try: + if os.path.isfile(file_path): + os.remove(file_path) + except Exception as e: + print(e) + + +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + + +def file_hash( + filename: str, hashtype: Callable[[], "hashlib._Hash"], blocksize: int = 65536 +) -> str: + hashtype = hashtype() + with open(filename, "rb") as f: + for block in iter(lambda: f.read(blocksize), b""): + hashtype.update(block) + return hashtype.hexdigest() + + +def get_file_sha1_from_file(file_name: str, sha1_file: str) -> Optional[str]: + if os.path.isfile(sha1_file): + with open(sha1_file, "r") as file: + return file.read() + if not os.path.isfile(file_name): + return None + new_sha1 = file_hash(file_name, hashlib.sha1) + with open(sha1_file, "w") as file: + file.write(new_sha1) + return None diff --git a/meta/meta/common/fabric.py b/meta/meta/common/fabric.py new file mode 100644 index 0000000000..2a35695cf1 --- /dev/null +++ b/meta/meta/common/fabric.py @@ -0,0 +1,12 @@ +from os.path import join + +BASE_DIR = "fabric" + +JARS_DIR = join(BASE_DIR, "jars") +INSTALLER_INFO_DIR = join(BASE_DIR, "loader-installer-json") +META_DIR = join(BASE_DIR, "meta-v2") + +LOADER_COMPONENT = "net.fabricmc.fabric-loader" +INTERMEDIARY_COMPONENT = "net.fabricmc.intermediary" + +DATETIME_FORMAT_HTTP = "%a, %d %b %Y %H:%M:%S %Z" diff --git a/meta/meta/common/forge.py b/meta/meta/common/forge.py new file mode 100644 index 0000000000..3cf5c3d10f --- /dev/null +++ b/meta/meta/common/forge.py @@ -0,0 +1,22 @@ +from os.path import join, dirname + +from ..model import GradleSpecifier, make_launcher_library + +BASE_DIR = "forge" + +JARS_DIR = join(BASE_DIR, "jars") +INSTALLER_INFO_DIR = join(BASE_DIR, "installer_info") +INSTALLER_MANIFEST_DIR = join(BASE_DIR, "installer_manifests") +VERSION_MANIFEST_DIR = join(BASE_DIR, "version_manifests") +FILE_MANIFEST_DIR = join(BASE_DIR, "files_manifests") +DERIVED_INDEX_FILE = join(BASE_DIR, "derived_index.json") +LEGACYINFO_FILE = join(BASE_DIR, "legacyinfo.json") + +FORGE_COMPONENT = "net.minecraftforge" + +FORGEWRAPPER_LIBRARY = make_launcher_library( + GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "prism-2025-12-07"), + "4c4653d80409e7e968d3e3209196ffae778b7b4e", + 29731, +) +BAD_VERSIONS = ["1.12.2-14.23.5.2851"] diff --git a/meta/meta/common/http.py b/meta/meta/common/http.py new file mode 100644 index 0000000000..20f9d0d135 --- /dev/null +++ b/meta/meta/common/http.py @@ -0,0 +1,6 @@ +def download_binary_file(sess, path, url): + with open(path, "wb") as f: + r = sess.get(url) + r.raise_for_status() + for chunk in r.iter_content(chunk_size=128): + f.write(chunk) diff --git a/meta/meta/common/java.py b/meta/meta/common/java.py new file mode 100644 index 0000000000..8b83f65aa0 --- /dev/null +++ b/meta/meta/common/java.py @@ -0,0 +1,17 @@ +from os.path import join + +BASE_DIR = "java_runtime" + +RELEASE_FILE = join(BASE_DIR, "releases.json") +ADOPTIUM_DIR = join(BASE_DIR, "adoptium") +OPENJ9_DIR = join(BASE_DIR, "ibm") +AZUL_DIR = join(BASE_DIR, "azul") + +ADOPTIUM_VERSIONS_DIR = join(ADOPTIUM_DIR, "versions") +OPENJ9_VERSIONS_DIR = join(OPENJ9_DIR, "versions") +AZUL_VERSIONS_DIR = join(AZUL_DIR, "versions") + +JAVA_MINECRAFT_COMPONENT = "net.minecraft.java" +JAVA_ADOPTIUM_COMPONENT = "net.adoptium.java" +JAVA_OPENJ9_COMPONENT = "com.ibm.java" +JAVA_AZUL_COMPONENT = "com.azul.java" diff --git a/meta/meta/common/liteloader.py b/meta/meta/common/liteloader.py new file mode 100644 index 0000000000..7a6c19eb46 --- /dev/null +++ b/meta/meta/common/liteloader.py @@ -0,0 +1,7 @@ +from os.path import join + +BASE_DIR = "liteloader" + +VERSIONS_FILE = join(BASE_DIR, "versions.json") + +LITELOADER_COMPONENT = "com.mumfrey.liteloader" diff --git a/meta/meta/common/mojang-library-patches.json b/meta/meta/common/mojang-library-patches.json new file mode 100644 index 0000000000..d6386746b6 --- /dev/null +++ b/meta/meta/common/mojang-library-patches.json @@ -0,0 +1,4269 @@ +[ + { + "_comment": "Only allow osx-arm64 for existing LWJGL 3.3.2/3.3.3/3.3.6", + "match": [ + "org.lwjgl:lwjgl-freetype-natives-macos-arm64:3.3.2", + "org.lwjgl:lwjgl-glfw-natives-macos-arm64:3.3.2", + "org.lwjgl:lwjgl-jemalloc-natives-macos-arm64:3.3.2", + "org.lwjgl:lwjgl-openal-natives-macos-arm64:3.3.2", + "org.lwjgl:lwjgl-opengl-natives-macos-arm64:3.3.2", + "org.lwjgl:lwjgl-stb-natives-macos-arm64:3.3.2", + "org.lwjgl:lwjgl-tinyfd-natives-macos-arm64:3.3.2", + "org.lwjgl:lwjgl-natives-macos-arm64:3.3.2", + "org.lwjgl:lwjgl-freetype-natives-macos-arm64:3.3.3", + "org.lwjgl:lwjgl-glfw-natives-macos-arm64:3.3.3", + "org.lwjgl:lwjgl-jemalloc-natives-macos-arm64:3.3.3", + "org.lwjgl:lwjgl-openal-natives-macos-arm64:3.3.3", + "org.lwjgl:lwjgl-opengl-natives-macos-arm64:3.3.3", + "org.lwjgl:lwjgl-stb-natives-macos-arm64:3.3.3", + "org.lwjgl:lwjgl-tinyfd-natives-macos-arm64:3.3.3", + "org.lwjgl:lwjgl-natives-macos-arm64:3.3.3", + "org.lwjgl:lwjgl-freetype-natives-macos-arm64:3.3.6", + "org.lwjgl:lwjgl-glfw-natives-macos-arm64:3.3.6", + "org.lwjgl:lwjgl-jemalloc-natives-macos-arm64:3.3.6", + "org.lwjgl:lwjgl-openal-natives-macos-arm64:3.3.6", + "org.lwjgl:lwjgl-opengl-natives-macos-arm64:3.3.6", + "org.lwjgl:lwjgl-stb-natives-macos-arm64:3.3.6", + "org.lwjgl:lwjgl-tinyfd-natives-macos-arm64:3.3.6", + "org.lwjgl:lwjgl-natives-macos-arm64:3.3.6", + "org.lwjgl:lwjgl-freetype-natives-macos-arm64:3.4.1", + "org.lwjgl:lwjgl-glfw-natives-macos-arm64:3.4.1", + "org.lwjgl:lwjgl-jemalloc-natives-macos-arm64:3.4.1", + "org.lwjgl:lwjgl-openal-natives-macos-arm64:3.4.1", + "org.lwjgl:lwjgl-opengl-natives-macos-arm64:3.4.1", + "org.lwjgl:lwjgl-stb-natives-macos-arm64:3.4.1", + "org.lwjgl:lwjgl-tinyfd-natives-macos-arm64:3.4.1", + "org.lwjgl:lwjgl-natives-macos-arm64:3.4.1" + ], + "override": { + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + }, + { + "_comment": "Only allow windows-arm64 for existing LWJGL 3.3.2/3.3.3/3.3.6", + "match": [ + "org.lwjgl:lwjgl-freetype-natives-windows-arm64:3.3.2", + "org.lwjgl:lwjgl-glfw-natives-windows-arm64:3.3.2", + "org.lwjgl:lwjgl-jemalloc-natives-windows-arm64:3.3.2", + "org.lwjgl:lwjgl-openal-natives-windows-arm64:3.3.2", + "org.lwjgl:lwjgl-opengl-natives-windows-arm64:3.3.2", + "org.lwjgl:lwjgl-stb-natives-windows-arm64:3.3.2", + "org.lwjgl:lwjgl-tinyfd-natives-windows-arm64:3.3.2", + "org.lwjgl:lwjgl-natives-windows-arm64:3.3.2", + "org.lwjgl:lwjgl-freetype-natives-windows-arm64:3.3.3", + "org.lwjgl:lwjgl-glfw-natives-windows-arm64:3.3.3", + "org.lwjgl:lwjgl-jemalloc-natives-windows-arm64:3.3.3", + "org.lwjgl:lwjgl-openal-natives-windows-arm64:3.3.3", + "org.lwjgl:lwjgl-opengl-natives-windows-arm64:3.3.3", + "org.lwjgl:lwjgl-stb-natives-windows-arm64:3.3.3", + "org.lwjgl:lwjgl-tinyfd-natives-windows-arm64:3.3.3", + "org.lwjgl:lwjgl-natives-windows-arm64:3.3.3", + "org.lwjgl:lwjgl-freetype-natives-windows-arm64:3.3.6", + "org.lwjgl:lwjgl-glfw-natives-windows-arm64:3.3.6", + "org.lwjgl:lwjgl-jemalloc-natives-windows-arm64:3.3.6", + "org.lwjgl:lwjgl-openal-natives-windows-arm64:3.3.6", + "org.lwjgl:lwjgl-opengl-natives-windows-arm64:3.3.6", + "org.lwjgl:lwjgl-stb-natives-windows-arm64:3.3.6", + "org.lwjgl:lwjgl-tinyfd-natives-windows-arm64:3.3.6", + "org.lwjgl:lwjgl-natives-windows-arm64:3.3.6", + "org.lwjgl:lwjgl-freetype-natives-windows-arm64:3.4.1", + "org.lwjgl:lwjgl-glfw-natives-windows-arm64:3.4.1", + "org.lwjgl:lwjgl-jemalloc-natives-windows-arm64:3.4.1", + "org.lwjgl:lwjgl-openal-natives-windows-arm64:3.4.1", + "org.lwjgl:lwjgl-opengl-natives-windows-arm64:3.4.1", + "org.lwjgl:lwjgl-stb-natives-windows-arm64:3.4.1", + "org.lwjgl:lwjgl-tinyfd-natives-windows-arm64:3.4.1", + "org.lwjgl:lwjgl-natives-windows-arm64:3.4.1" + ], + "override": { + "rules": [ + { + "action": "allow", + "os": { + "name": "windows-arm64" + } + } + ] + } + }, + { + "_comment": "Add missing tinyfd to the broken LWJGL 3.2.2 variant", + "match": [ + "org.lwjgl:lwjgl:3.2.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "fcbe606c8f8da6f8f9a05e2c540eb1ee8632b0e9", + "size": 7092, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.2.2" + }, + { + "downloads": { + "artifact": { + "sha1": "fcbe606c8f8da6f8f9a05e2c540eb1ee8632b0e9", + "size": 7092, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar" + }, + "classifiers": { + "natives-linux": { + "sha1": "39e35b161c130635d9c8918ce04e887a30c5b687", + "size": 38804, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-linux.jar" + }, + "natives-macos": { + "sha1": "46d0798228b8a28e857a2a0f02310fd6ba2a4eab", + "size": 42136, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-macos.jar" + }, + "natives-windows": { + "sha1": "e9115958773644e863332a6a06488d26f9e1fc9f", + "size": 208314, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-windows.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.2.2", + "natives": { + "linux": "natives-linux", + "osx": "natives-macos", + "windows": "natives-windows" + } + } + ], + "patchAdditionalLibraries": true + }, + { + "_comment": "Add additional library just for osx-arm64. No override needed", + "match": [ + "ca.weblite:java-objc-bridge:1.0.0" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "369a83621e3c65496348491e533cb97fe5f2f37d", + "size": 91947, + "url": "https://github.com/MinecraftMachina/Java-Objective-C-Bridge/releases/download/1.1.0-mmachina.1/java-objc-bridge-1.1.jar" + } + }, + "name": "ca.weblite:java-objc-bridge:1.1.0-mmachina.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add additional classifiers for jinput-platform", + "match": [ + "net.java.jinput:jinput-platform:2.0.5" + ], + "override": { + "downloads": { + "classifiers": { + "natives-osx-arm64": { + "sha1": "5189eb40db3087fb11ca063b68fa4f4c20b199dd", + "size": 10031, + "url": "https://github.com/r58Playz/jinput-m1/raw/main/plugins/OSX/bin/jinput-platform-2.0.5.jar" + }, + "natives-linux-arm64": { + "sha1": "42b388ccb7c63cec4e9f24f4dddef33325f8b212", + "size": 10932, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-2.9.4/jinput-platform-2.0.5-natives-linux.jar" + }, + "natives-linux-arm32": { + "sha1": "f3c455b71c5146acb5f8a9513247fc06db182fd5", + "size": 4521, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-2.9.4/jinput-platform-2.0.5-natives-linux.jar" + } + } + }, + "natives": { + "linux-arm64": "natives-linux-arm64", + "linux-arm32": "natives-linux-arm32", + "osx-arm64": "natives-osx-arm64" + } + } + }, + { + "_comment": "Use a newer version on osx-arm64", + "match": [ + "com.mojang:text2speech:1.0.10", + "com.mojang:text2speech:1.5", + "com.mojang:text2speech:1.6", + "com.mojang:text2speech:1.7", + "com.mojang:text2speech:1.10.1", + "com.mojang:text2speech:1.10.3", + "com.mojang:text2speech:1.11.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "f378f889797edd7df8d32272c06ca80a1b6b0f58", + "size": 13164, + "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.11.3/text2speech-1.11.3.jar" + } + }, + "name": "com.mojang:text2speech:1.11.3", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl.lwjgl:lwjgl:2.9.3", + "org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20131120", + "org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20131017", + "org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20130708-debug3", + "org.lwjgl.lwjgl:lwjgl:2.9.1" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "697517568c68e78ae0b4544145af031c81082dfe", + "size": 1047168, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209/lwjgl-2.9.4-nightly-20150209.jar" + } + }, + "name": "org.lwjgl.lwjgl:lwjgl:2.9.4-nightly-20150209", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + }, + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl.lwjgl:lwjgl_util:2.9.3", + "org.lwjgl.lwjgl:lwjgl_util:2.9.1-nightly-20131120", + "org.lwjgl.lwjgl:lwjgl_util:2.9.1-nightly-20131017", + "org.lwjgl.lwjgl:lwjgl_util:2.9.1-nightly-20130708-debug3", + "org.lwjgl.lwjgl:lwjgl_util:2.9.1" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "d51a7c040a721d13efdfbd34f8b257b2df882ad0", + "size": 173887, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.jar" + } + }, + "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.4-nightly-20150209", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + }, + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl.lwjgl:lwjgl-platform:2.9.4-nightly-20150209", + "org.lwjgl.lwjgl:lwjgl-platform:2.9.3", + "org.lwjgl.lwjgl:lwjgl-platform:2.9.1-nightly-20131120", + "org.lwjgl.lwjgl:lwjgl-platform:2.9.1-nightly-20131017", + "org.lwjgl.lwjgl:lwjgl-platform:2.9.1-nightly-20130708-debug3", + "org.lwjgl.lwjgl:lwjgl-platform:2.9.1" + ], + "override": { + "downloads": { + "classifiers": { + "natives-osx-arm64": { + "sha1": "eff546c0b319d6ffc7a835652124c18089c67f36", + "size": 488316, + "url": "https://github.com/MinecraftMachina/lwjgl/releases/download/2.9.4-20150209-mmachina.2/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar" + }, + "natives-linux-arm64": { + "sha1": "63ac7da0f4a4785c7eadc0f8edc1e9dcc4dd08cb", + "size": 579979, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-2.9.4/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar" + }, + "natives-linux-arm32": { + "sha1": "fa483e540a9a753a5ffbb23dcf7879a5bf752611", + "size": 475177, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-2.9.4/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar" + } + } + }, + "natives": { + "linux-arm64": "natives-linux-arm64", + "linux-arm32": "natives-linux-arm32", + "osx-arm64": "natives-osx-arm64" + } + } + }, + { + "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl:lwjgl-glfw:3.2.2", + "org.lwjgl:lwjgl-glfw:3.2.1", + "org.lwjgl:lwjgl-glfw:3.1.6", + "org.lwjgl:lwjgl-glfw:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm32" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "155d175037efc76630940c197ca6dea2b17d7e18", + "size": 108691, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-glfw.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw:3.2.2-gman64.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "155d175037efc76630940c197ca6dea2b17d7e18", + "size": 108691, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-glfw.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "074ad243761147df0d060fbefc814614d2ff75cc", + "size": 85072, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-glfw-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-glfw:3.2.2-gman64.1", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "99e9a39fa8ed4167e3ff9e04d47eb32c9e69804d", + "size": 108691, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-glfw.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw:3.2.2-gman32.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "99e9a39fa8ed4167e3ff9e04d47eb32c9e69804d", + "size": 108691, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-glfw.jar" + }, + "classifiers": { + "natives-linux-arm32": { + "sha1": "4265f2fbe3b9d642591165165a17cf406cf7b98e", + "size": 80186, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-glfw-natives-linux-arm32.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-glfw:3.2.2-gman32.1", + "natives": { + "linux-arm32": "natives-linux-arm32" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "e9a101bca4fa30d26b21b526ff28e7c2d8927f1b", + "size": 130128, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-glfw.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw:3.3.1-mmachina.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "e9a101bca4fa30d26b21b526ff28e7c2d8927f1b", + "size": 130128, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-glfw.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "71d793d0a5a42e3dfe78eb882abc2523a2c6b496", + "size": 129076, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-glfw-natives-macos-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-glfw:3.3.1-mmachina.1", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.2.2", + "org.lwjgl:lwjgl-jemalloc:3.2.1", + "org.lwjgl:lwjgl-jemalloc:3.1.6", + "org.lwjgl:lwjgl-jemalloc:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm32" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "cc04eec29b2fa8c298791af9800a3766d9617954", + "size": 33790, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-jemalloc.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc:3.2.2-gman64.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "cc04eec29b2fa8c298791af9800a3766d9617954", + "size": 33790, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-jemalloc.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "762d7d80c9cdf3a3f3fc80c8a5f86612255edfe0", + "size": 156343, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-jemalloc-patched-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-jemalloc:3.2.2-gman64.2", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "8224ae2e8fc6d8e1a0fc7d84dc917aa3c440620c", + "size": 33790, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-jemalloc.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc:3.2.2-gman32.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "8224ae2e8fc6d8e1a0fc7d84dc917aa3c440620c", + "size": 33790, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-jemalloc.jar" + }, + "classifiers": { + "natives-linux-arm32": { + "sha1": "9163a2a5559ef87bc13ead8fea84417ea3928748", + "size": 134237, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-jemalloc-natives-linux-arm32.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-jemalloc:3.2.2-gman32.1", + "natives": { + "linux-arm32": "natives-linux-arm32" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "4fb94224378d3588d52d2beb172f2eeafea2d546", + "size": 36976, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-jemalloc.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc:3.3.1-mmachina.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "4fb94224378d3588d52d2beb172f2eeafea2d546", + "size": 36976, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-jemalloc.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "b0be721188d2e7195798780b1c5fe7eafe8091c1", + "size": 103478, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-jemalloc-natives-macos-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-jemalloc:3.3.1-mmachina.1", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl:lwjgl-openal:3.2.2", + "org.lwjgl:lwjgl-openal:3.2.1", + "org.lwjgl:lwjgl-openal:3.1.6", + "org.lwjgl:lwjgl-openal:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm32" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "6dfce9dc6a9629c75b2ae01a8df7e7be80ba0261", + "size": 79582, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-openal.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal:3.2.2-gman64.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "6dfce9dc6a9629c75b2ae01a8df7e7be80ba0261", + "size": 79582, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-openal.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "948e415b5b2a2c650c25b377a4a9f443b21ce92e", + "size": 469432, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-openal-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-openal:3.2.2-gman64.1", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "304f0571fd5971621ee6da86a4c1e90f6f52e2ee", + "size": 79582, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-openal.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal:3.2.2-gman32.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "304f0571fd5971621ee6da86a4c1e90f6f52e2ee", + "size": 79582, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-openal.jar" + }, + "classifiers": { + "natives-linux-arm32": { + "sha1": "ecbc981fdd996492a1f6334f003ed62e5a8c0cd5", + "size": 398418, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-openal-natives-linux-arm32.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-openal:3.2.2-gman32.1", + "natives": { + "linux-arm32": "natives-linux-arm32" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "d48e753d85916fc8a200ccddc709b36e3865cc4e", + "size": 88880, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-openal.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal:3.3.1-mmachina.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "d48e753d85916fc8a200ccddc709b36e3865cc4e", + "size": 88880, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-openal.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "6b80fc0b982a0723b141e88859c42d6f71bd723f", + "size": 346131, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-openal-natives-macos-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-openal:3.3.1-mmachina.1", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl:lwjgl-opengl:3.2.2", + "org.lwjgl:lwjgl-opengl:3.2.1", + "org.lwjgl:lwjgl-opengl:3.1.6", + "org.lwjgl:lwjgl-opengl:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm32" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "198bc2f72e0b2eb401eb6f5999aea52909b31ac4", + "size": 937609, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-opengl.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl:3.2.2-gman64.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "198bc2f72e0b2eb401eb6f5999aea52909b31ac4", + "size": 937609, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-opengl.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "bd40897077bf7d12f562da898b18ac2c68e1f9d7", + "size": 56109, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-opengl-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-opengl:3.2.2-gman64.1", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "9762ae928d02147e716cd82e929b74a97ea9600a", + "size": 937609, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-opengl.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl:3.2.2-gman32.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "9762ae928d02147e716cd82e929b74a97ea9600a", + "size": 937609, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-opengl.jar" + }, + "classifiers": { + "natives-linux-arm32": { + "sha1": "3af5599c74dd76dd8dbb567b3f9b4963a6abeed5", + "size": 56388, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-opengl-natives-linux-arm32.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-opengl:3.2.2-gman32.1", + "natives": { + "linux-arm32": "natives-linux-arm32" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "962c2a8d2a8cdd3b89de3d78d766ab5e2133c2f4", + "size": 929233, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-opengl.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl:3.3.1-mmachina.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "962c2a8d2a8cdd3b89de3d78d766ab5e2133c2f4", + "size": 929233, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-opengl.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "bb575058e0372f515587b5d2d04ff7db185f3ffe", + "size": 41667, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-opengl-natives-macos-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-opengl:3.3.1-mmachina.1", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl:lwjgl-stb:3.2.2", + "org.lwjgl:lwjgl-stb:3.2.1", + "org.lwjgl:lwjgl-stb:3.1.6", + "org.lwjgl:lwjgl-stb:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm32" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "46a5735f3eb9d17eb5dcbdd5afa194066d2a6555", + "size": 104075, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-stb.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb:3.2.2-gman64.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "46a5735f3eb9d17eb5dcbdd5afa194066d2a6555", + "size": 104075, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-stb.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "077efa7d7ea41b32df5c6078e912e724cccd06db", + "size": 202038, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-stb-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-stb:3.2.2-gman64.1", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "ea979b0af45b8e689f5f47c989aa8550c148d8a2", + "size": 104075, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-stb.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb:3.2.2-gman32.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "ea979b0af45b8e689f5f47c989aa8550c148d8a2", + "size": 104075, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-stb.jar" + }, + "classifiers": { + "natives-linux-arm32": { + "sha1": "ec9d70aaebd0ff76dfeecf8f00b56118bf3706b1", + "size": 149387, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-stb-natives-linux-arm32.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-stb:3.2.2-gman32.1", + "natives": { + "linux-arm32": "natives-linux-arm32" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "703e4b533e2542560e9f94d6d8bd148be1c1d572", + "size": 113273, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-stb.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb:3.3.1-mmachina.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "703e4b533e2542560e9f94d6d8bd148be1c1d572", + "size": 113273, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-stb.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "98f0ad956c754723ef354d50057cc30417ef376a", + "size": 178409, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-stb-natives-macos-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-stb:3.3.1-mmachina.1", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.2.2", + "org.lwjgl:lwjgl-tinyfd:3.2.1", + "org.lwjgl:lwjgl-tinyfd:3.1.6", + "org.lwjgl:lwjgl-tinyfd:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm32" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "3a75b9811607633bf33c978f53964df1534a4bc1", + "size": 5571, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-tinyfd.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.2.2-gman64.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "3a75b9811607633bf33c978f53964df1534a4bc1", + "size": 5571, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-tinyfd.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "37c744ca289b5d7ae155d79e39029488b3254e5b", + "size": 37893, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-tinyfd-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.2.2-gman64.1", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "a8c09f5b7fa24bd53ec329c231b566497a163d5b", + "size": 5571, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-tinyfd.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.2.2-gman32.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "a8c09f5b7fa24bd53ec329c231b566497a163d5b", + "size": 5571, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-tinyfd.jar" + }, + "classifiers": { + "natives-linux-arm32": { + "sha1": "82d16054ada6633297a3108fb6d8bae98800c76f", + "size": 41663, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-tinyfd-natives-linux-arm32.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.2.2-gman32.1", + "natives": { + "linux-arm32": "natives-linux-arm32" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "1203660b3131cbb8681b17ce6437412545be95e0", + "size": 6802, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-tinyfd.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.3.1-mmachina.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "1203660b3131cbb8681b17ce6437412545be95e0", + "size": 6802, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-tinyfd.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "015b931a2daba8f0c317d84c9d14e8e98ae56e0c", + "size": 41384, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-tinyfd-natives-macos-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.3.1-mmachina.1", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl:lwjgl:3.2.2", + "org.lwjgl:lwjgl:3.2.1", + "org.lwjgl:lwjgl:3.1.6", + "org.lwjgl:lwjgl:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm32" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "360899386df83d6a8407844a94478607af937f97", + "size": 318833, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-core.jar" + } + }, + "name": "org.lwjgl:lwjgl:3.2.2-gman64.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "360899386df83d6a8407844a94478607af937f97", + "size": 318833, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-core.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "612efd57d12b2e48e554858eb35e7e2eb46ebb4c", + "size": 87121, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl:3.2.2-gman64.1", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "16ea3934fca417368250d1ddac01a30c1809d317", + "size": 318413, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-core.jar" + } + }, + "name": "org.lwjgl:lwjgl:3.2.2-gman32.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "16ea3934fca417368250d1ddac01a30c1809d317", + "size": 318413, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-core.jar" + }, + "classifiers": { + "natives-linux-arm32": { + "sha1": "6bd0b37fef777a309936a72dc7f63126e8c79ea5", + "size": 90296, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-natives-linux-arm32.jar" + } + } + }, + "name": "org.lwjgl:lwjgl:3.2.2-gman32.1", + "natives": { + "linux-arm32": "natives-linux-arm32" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "8e664dd69ad7bbcf2053da23efc7848e39e498db", + "size": 719038, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl.jar" + } + }, + "name": "org.lwjgl:lwjgl:3.3.1-mmachina.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "8e664dd69ad7bbcf2053da23efc7848e39e498db", + "size": 719038, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "984df31fadaab86838877b112e5b4e4f68a00ccf", + "size": 42693, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-natives-macos-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl:3.3.1-mmachina.1", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Only allow osx-arm64 for existing LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-glfw-natives-macos-arm64:3.3.1", + "org.lwjgl:lwjgl-jemalloc-natives-macos-arm64:3.3.1", + "org.lwjgl:lwjgl-openal-natives-macos-arm64:3.3.1", + "org.lwjgl:lwjgl-opengl-natives-macos-arm64:3.3.1", + "org.lwjgl:lwjgl-stb-natives-macos-arm64:3.3.1", + "org.lwjgl:lwjgl-tinyfd-natives-macos-arm64:3.3.1", + "org.lwjgl:lwjgl-natives-macos-arm64:3.3.1" + ], + "override": { + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + }, + { + "_comment": "Only allow osx-arm64 for existing java-objc-bridge:1.1", + "match": [ + "ca.weblite:java-objc-bridge:1.1" + ], + "override": { + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + }, + { + "_comment": "Only allow windows-arm64 for existing LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-glfw-natives-windows-arm64:3.3.1", + "org.lwjgl:lwjgl-jemalloc-natives-windows-arm64:3.3.1", + "org.lwjgl:lwjgl-openal-natives-windows-arm64:3.3.1", + "org.lwjgl:lwjgl-opengl-natives-windows-arm64:3.3.1", + "org.lwjgl:lwjgl-stb-natives-windows-arm64:3.3.1", + "org.lwjgl:lwjgl-tinyfd-natives-windows-arm64:3.3.1", + "org.lwjgl:lwjgl-natives-windows-arm64:3.3.1" + ], + "override": { + "rules": [ + { + "action": "allow", + "os": { + "name": "windows-arm64" + } + } + ] + } + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-glfw:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "513eb39b866d0fe131a18d5c517087805433b029", + "size": 112350, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm64:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "749be48a9b86ee2c3a2da5fd77511208adcfb33b", + "size": 159993, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.3.1/lwjgl-jemalloc-patched-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm64:3.3.1-gman64.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-openal:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "cf4e303257e82981b8b2e31bba3d7f8f7b8f42b2", + "size": 470743, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm64:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-opengl:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "1c528fb258a6e63e8fceb4482d8db0f3af10a634", + "size": 57908, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm64:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-stb:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "8e8348a1813aad7f30aaf75ea197151ebb7beba9", + "size": 205491, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm64:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "964f628b7a82fd909def086c0dd9a4b84bb259ae", + "size": 42654, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm64:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "b597401014acb7196c76d97e15a6288f54f1f692", + "size": 86308, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl/lwjgl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm64:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-glfw:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "816d935933f2dd743074c4e717cc25b55720f294", + "size": 104027, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm32:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "a96a6d6cb3876d7813fcee53c3c24f246aeba3b3", + "size": 136157, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm32:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-openal:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "ffbe35d7fa5ec9b7eca136a7c71f24d4025a510b", + "size": 400129, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm32:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-opengl:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "e3550fa91097fd56e361b4370fa822220fef3595", + "size": 58474, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm32:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-stb:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "b08226bab162c06ae69337d8a1b0ee0a3fdf0b90", + "size": 153889, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm32:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "d53d331e859217a61298fcbcf8d79137f3df345c", + "size": 48061, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm32:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "41a3c1dd15d6b964eb8196dde69720a3e3e5e969", + "size": 82374, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl/lwjgl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm32:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-freetype:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "896e7d9b8f60d7273f3d491c69270afc67ece3ce", + "size": 1073374, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm64:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-glfw:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "bc49e64bae0f7ff103a312ee8074a34c4eb034c7", + "size": 120168, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm64:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "5249f18a9ae20ea86c5816bc3107a888ce7a17d2", + "size": 206402, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm64:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-openal:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "22408980cc579709feaf9acb807992d3ebcf693f", + "size": 590865, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm64:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-opengl:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "bb9eb56da6d1d549d6a767218e675e36bc568eb9", + "size": 58627, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm64:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-stb:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "11a380c37b0f03cb46db235e064528f84d736ff7", + "size": 207419, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm64:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "93f8c5bc1984963cd79109891fb5a9d1e580373e", + "size": 43381, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm64:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "8bd89332c90a90e6bc4aa997a25c05b7db02c90a", + "size": 90795, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl/lwjgl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm64:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-freetype:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "b7f77ceb951182659fd400437272aa7e96709968", + "size": 924657, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm32:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-glfw:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "5907d9a6b7c44fb0612a63bb1cff5992588f65be", + "size": 110067, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm32:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "9367437ce192e4d6f5725d53d85520644c0b0d6f", + "size": 177571, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm32:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-openal:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "7c82bbc33ef49ee4094b216c940db564b2998224", + "size": 503352, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm32:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-opengl:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "821f9a2d1d583c44893f42b96f6977682b48a99b", + "size": 59265, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm32:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-stb:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "ca9333da184aade20757151f4615f1e27ca521ae", + "size": 154928, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm32:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "807e220913aa0740449ff90d3b3d825cf5f359ed", + "size": 48788, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm32:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "afcbfaaa46f217e98a6da4208550f71de1f2a225", + "size": 89347, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl/lwjgl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm32:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-freetype:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "498965aac06c4a0d42df1fbef6bacd05bde7f974", + "size": 1093516, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm64:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-glfw:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "492a0f11f85b85899a6568f07511160c1b87cd38", + "size": 122159, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm64:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "eff8b86798191192fe2cba2dc2776109f30c239d", + "size": 209315, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm64:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-openal:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "ad8f302118a65bb8d615f8a2a680db58fb8f835e", + "size": 592963, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm64:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-opengl:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "2096f6b94b2d68745d858fbfe53aacf5f0c8074c", + "size": 58625, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm64:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-stb:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "ddc177afc2be1ee8d93684b11363b80589a13fe1", + "size": 207418, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm64:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "2823a8c955c758d0954d282888075019ef99cec7", + "size": 43864, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm64:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "f35d8b6ffe1ac1e3a5eb1d4e33de80f044ad5fd8", + "size": 91294, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl/lwjgl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm64:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-freetype:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "7dd3b1f751571adaf2c4dc882bc675a5d1e796e6", + "size": 942636, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm32:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-glfw:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "d9af485c32545b37dd5359b163161d42d7534dcf", + "size": 112560, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm32:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "109b6931880d02d4e65ced38928a16e41d19873e", + "size": 178324, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm32:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-openal:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "e1702aa09d20359d6cf5cb2999fa7685a785eca7", + "size": 505618, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm32:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-opengl:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "dbba17fc5ac0985d14a57c11f9537617d67b9952", + "size": 59263, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm32:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-stb:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "1ae28ff044699ff29b0e980ffabd73fba8a664b3", + "size": 154931, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm32:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "c2a0a05c82c4b9f69ded0b6ad5f417addea78ce2", + "size": 49495, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm32:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "2075c51a80f0ef0f22ba616ba54007ac2b0debd4", + "size": 89565, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl/lwjgl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm32:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-freetype:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "b5492439c7c9a596655d0d0e06801f93ec491e53", + "size": 1093516, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-glfw:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "b54023af492b4c2c72451f3a7aa0f385e9969474", + "size": 141056, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "1bc2e16e70df7f418d668c2984ac8066f1f6f5b1", + "size": 222196, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-openal:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "fd2c17603c63e8d543cb57d1db77ebd4574f3b7a", + "size": 656568, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-opengl:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "44de180f79e0b45c9e5bee10ca7540dcb5ddd373", + "size": 79414, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-stb:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "397f588f867e9c4faf1a34231344c9209dabc052", + "size": 256144, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "7806e57c3d9ea6b6a552c72f5e2597343c4d4138", + "size": 44504, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "9eeb8887b5e3aa672efd2e1b0973ffa5891a3151", + "size": 117172, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl/lwjgl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-freetype:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "3f6a1030be5efdcde35cb363c69810245eb59c5a", + "size": 1035183, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm32:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-glfw:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "671adf04a6bc4f792af13892e37f804be30b7070", + "size": 118670, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm32:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "c484cae39a718010dbc7931fe5e12664600a13c2", + "size": 176503, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm32:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-openal:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "7830af894fa110e65bf5075deb9183efbdbc50f5", + "size": 604338, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm32:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-opengl:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "ee815fbf454b916f13c10fff62e513eb09042ef0", + "size": 58633, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm32:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-stb:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "f47bac442afcb7fd014af7d90892024fe3c0d920", + "size": 191834, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm32:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "800ad2c9492a7ccadb23886c9e231f60c12a9037", + "size": 50599, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm32:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "2c9d698e76c3d0fe307d94cc6f428038492f25df", + "size": 88490, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl/lwjgl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm32:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-freetype:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "5eea88e3527bb5fd2d81cc03f2bece1c83eada1c", + "size": 1199082, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-riscv64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-glfw:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "dde300b71892fddae65e4c524760e650bc924bb2", + "size": 119447, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-riscv64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "9c76514b7725d5b8c5731f41218e97dcad3237b9", + "size": 197210, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-riscv64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-openal:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "35fc93e98cf43a51f8fdd2b7e46854cb3820532a", + "size": 640228, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-openal/lwjgl-openal-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-riscv64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-opengl:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "c55c0458e903df7bb688401273ad0e7c92c11068", + "size": 57863, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-riscv64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-stb:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "009dbfa917b9fc07459a726e72d9ea9e7178f9d3", + "size": 216086, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-stb/lwjgl-stb-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-riscv64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "0dfe4d23c5c5d92bf70a8bc50a964b0a6452add2", + "size": 46550, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-riscv64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "830923e74105b08d137413735525e2be80a421b8", + "size": 81930, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl/lwjgl-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-riscv64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-freetype:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "8f37d0da3386ff602ec54cd06626881895711041", + "size": 1093516, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-glfw:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "e5e87034c47118960746077dba46280e8de864b3", + "size": 141056, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "7891964dfb723209c6d02b0401432348fb707cc0", + "size": 222196, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-openal:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "3729b70cdd42df5571b075e051fa2fc8586dc538", + "size": 656568, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-opengl:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "61a4103e56bbaeb74ad3f19ec14299fd6891c4b0", + "size": 79414, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-stb:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "3bc107f901f931fea07cb0d80b1d74a34b806a2b", + "size": 256144, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "20771d2b4e01f5295156912ab62e170508aef618", + "size": 44504, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "46883f3b622d8b4d7f27b627ca3360cda3db0e0e", + "size": 117172, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl/lwjgl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-freetype:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "d0bb1ececfdd1e5b75ba75c22d0e075dafe695d1", + "size": 1035183, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm32:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-glfw:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "bb243e9a857c4301bf7d5e668538686eaa64101e", + "size": 118670, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm32:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "fc9ce35c94743e23855777cacaba34bc145da6ec", + "size": 176503, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm32:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-openal:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "6d4ac5f3d5bab7f2fadfd52c32177d9c12a43b49", + "size": 604338, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm32:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-opengl:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "172e575948234ff7920abf0d0083d25e37c91ba6", + "size": 58633, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm32:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-stb:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "8f753f3772863989f1172d2b84b4e56ed18e8c35", + "size": 191834, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm32:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "62cb99015923df821e2e7a2a5a1e51d1e307126c", + "size": 50599, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm32:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "1511ab1ffb1c8d8e00e2acb452663173ae09bca0", + "size": 88490, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl/lwjgl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm32:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-freetype:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "737708c27a49ba5884ef347565fcb9964e8d85a9", + "size": 1199082, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-riscv64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-glfw:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "d76ed6846bff9804cfd1adb84b068728645a097b", + "size": 119447, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-riscv64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "ac7be1f86e87df030e668c02df2dec27c44da32b", + "size": 197210, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-riscv64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-openal:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "652b9424f529dccc79694f2124709083d2712104", + "size": 640228, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-openal/lwjgl-openal-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-riscv64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-opengl:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "8a6f47236738e3c682e98e15a13cf0358c1da85c", + "size": 57863, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-riscv64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-stb:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "f1d8fe25d44e26c40f4dd4c48189323675467578", + "size": 216086, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-stb/lwjgl-stb-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-riscv64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "6aa204e5047e9f272c7271119105833cc0ddfd27", + "size": 46550, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-riscv64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "a43b5208883562d31b5a2de1810aa82e2f2bf0ba", + "size": 81930, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl/lwjgl-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-riscv64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Replace glfw from 3.3.1 with version from 3.3.2 to prevent stack smashing", + "match": [ + "org.lwjgl:lwjgl-glfw-natives-linux:3.3.1" + ], + "override": { + "downloads": { + "artifact": { + "sha1": "0766bb0e8e829598b1c8052fd8173c62af741c52", + "size": 115553, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-glfw/lwjgl-glfw-natives-linux.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux:3.3.2-lwjgl.1" + } + }, + { + "_comment": "Use newer JNA on macOS to prevent crashes due to faulty assertion", + "match": [ + "net.java.dev.jna:jna:5.6.0", + "net.java.dev.jna:jna:5.8.0", + "net.java.dev.jna:jna:5.9.0", + "net.java.dev.jna:jna:5.10.0", + "net.java.dev.jna:jna:5.12.1" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "osx" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "1200e7ebeedbe0d10062093f32925a912020e747", + "size": 1879325, + "url": "https://libraries.minecraft.net/net/java/dev/jna/jna/5.13.0/jna-5.13.0.jar" + } + }, + "name": "net.java.dev.jna:jna:5.13.0", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx" + } + }, + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use newer JNA on macOS to prevent crashes due to faulty assertion", + "match": [ + "net.java.dev.jna:jna-platform:5.6.0", + "net.java.dev.jna:jna-platform:5.8.0", + "net.java.dev.jna:jna-platform:5.9.0", + "net.java.dev.jna:jna-platform:5.10.0", + "net.java.dev.jna:jna-platform:5.12.1" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "osx" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "88e9a306715e9379f3122415ef4ae759a352640d", + "size": 1363209, + "url": "https://libraries.minecraft.net/net/java/dev/jna/jna-platform/5.13.0/jna-platform-5.13.0.jar" + } + }, + "name": "net.java.dev.jna:jna-platform:5.13.0", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx" + } + }, + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + } +] diff --git a/meta/meta/common/mojang-minecraft-experiments.json b/meta/meta/common/mojang-minecraft-experiments.json new file mode 100644 index 0000000000..2a6792a7b0 --- /dev/null +++ b/meta/meta/common/mojang-minecraft-experiments.json @@ -0,0 +1,159 @@ +{ + "experiments": [ + { + "id": "1_21_11_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.21.11", + "url": "https://piston-data.mojang.com/v1/objects/82332dfb17146de34cb7a36d2b910e3b2009191a/1_21_11_unobfuscated.zip" + }, + { + "id": "1_21_11-rc3_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.21.11_Release_Candidate_3", + "url": "https://piston-data.mojang.com/v1/objects/7abe399a1b3c07754c5dc3ec4e5c6f50ee03c10e/1_21_11-rc3_unobfuscated.zip" + }, + { + "id": "1_21_11-rc2_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.21.11_Release_Candidate_2", + "url": "https://piston-data.mojang.com/v1/objects/fb70de3ae3e19825622b7687d2fd783d78c4b05f/1_21_11-rc2_unobfuscated.zip" + }, + { + "id": "1_21_11-rc1_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.21.11_Release_Candidate_1", + "url": "https://piston-data.mojang.com/v1/objects/38712002b9d02061e662b69c44753a47d24da516/1_21_11-rc1_unobfuscated.zip" + }, + { + "id": "1_21_11-pre5_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.21.11_Pre-Release_5", + "url": "https://piston-data.mojang.com/v1/objects/931df659128f913ce356d6036c318c5d9a039e85/1_21_11-pre5_unobfuscated.zip" + }, + { + "id": "1_21_11-pre4_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.21.11_Pre-Release_4", + "url": "https://piston-data.mojang.com/v1/objects/834666571f1e1374923b73f4baec4203d44e9c0d/1_21_11-pre4_unobfuscated.zip" + }, + { + "id": "1_21_11-pre3_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.21.11_Pre-Release_3", + "url": "https://piston-data.mojang.com/v1/objects/7717a481468cc33d2414d82ee9c0450f56264db0/1_21_11-pre3_unobfuscated.zip" + }, + { + "id": "1_21_11-pre2_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.21.11_Pre-Release_2", + "url": "https://piston-data.mojang.com/v1/objects/528731e05b7be26c90fedf8f2ef6470abb0d1994/1_21_11-pre2_unobfuscated.zip" + }, + { + "id": "1_21_11-pre1_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.21.11_Pre-Release_1", + "url": "https://piston-data.mojang.com/v1/objects/f98a0c053a8246cce12f8f29f2ba4ce00872fd53/1_21_11-pre1_unobfuscated.zip" + }, + { + "id": "25w46a_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_25w46a", + "url": "https://piston-data.mojang.com/v1/objects/f9c5e4f9c1469296299635b498438e94d312f0c6/25w46a_unobfuscated.zip" + }, + { + "id": "25w45a_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_25w45a", + "url": "https://piston-data.mojang.com/v1/objects/de334d80d9ddc5abb94c611b8ad10f9125c4c421/25w45a_unobfuscated.zip" + }, + { + "id": "1_19_deep_dark_experimental_snapshot-1", + "wiki": "https://minecraft.wiki/w/Java_Edition_Deep_Dark_Experimental_Snapshot_1", + "url": "https://launcher.mojang.com/v1/objects/b1e589c1d6ed73519797214bc796e53f5429ac46/1_19_deep_dark_experimental_snapshot-1.zip" + }, + { + "id": "1_18_experimental-snapshot-7", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.18_Experimental_Snapshot_7", + "url": "https://launcher.mojang.com/v1/objects/ab4ecebb133f56dd4c4c4c3257f030a947ddea84/1_18_experimental-snapshot-7.zip" + }, + { + "id": "1_18_experimental-snapshot-6", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.18_Experimental_Snapshot_6", + "url": "https://launcher.mojang.com/v1/objects/4697c84c6a347d0b8766759d5b00bc5a00b1b858/1_18_experimental-snapshot-6.zip" + }, + { + "id": "1_18_experimental-snapshot-5", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.18_Experimental_Snapshot_5", + "url": "https://launcher.mojang.com/v1/objects/d9cb7f6fb4e440862adfb40a385d83e3f8d154db/1_18_experimental-snapshot-5.zip" + }, + { + "id": "1_18_experimental-snapshot-4", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.18_Experimental_Snapshot_4", + "url": "https://launcher.mojang.com/v1/objects/b92a360cbae2eb896a62964ad8c06c3493b6c390/1_18_experimental-snapshot-4.zip" + }, + { + "id": "1_18_experimental-snapshot-3", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.18_Experimental_Snapshot_3", + "url": "https://launcher.mojang.com/v1/objects/846648ff9fe60310d584061261de43010e5c722b/1_18_experimental-snapshot-3.zip" + }, + { + "id": "1_18_experimental-snapshot-2", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.18_Experimental_Snapshot_2", + "url": "https://launcher.mojang.com/v1/objects/0adfe4f321aa45248fc88ac888bed5556633e7fb/1_18_experimental-snapshot-2.zip" + }, + { + "id": "1_18_experimental-snapshot-1", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.18_Experimental_Snapshot_1", + "url": "https://launcher.mojang.com/v1/objects/231bba2a21e18b8c60976e1f6110c053b7b93226/1_18_experimental-snapshot-1.zip" + }, + { + "id": "1_16_combat-6", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_8c", + "url": "https://launcher.mojang.com/experiments/combat/ea08f7eb1f96cdc82464e27c0f95d23965083cfb/1_16_combat-6.zip" + }, + { + "id": "1_16_combat-5", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_8b", + "url": "https://launcher.mojang.com/experiments/combat/9b2b984d635d373564b50803807225c75d7fd447/1_16_combat-5.zip" + }, + { + "id": "1_16_combat-4", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_8", + "url": "https://archive.org/download/1-16-combat-4_202404/1_16_combat-4.zip" + }, + { + "id": "1_16_combat-3", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_7c", + "url": "https://launcher.mojang.com/experiments/combat/2557b99d95588505e988886220779087d7d6b1e9/1_16_combat-3.zip" + }, + { + "id": "1_16_combat-2", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_7b", + "url": "https://archive.org/download/Combat_Test_7ab/1_16_combat-2.zip" + }, + { + "id": "1_16_combat-1", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_7", + "url": "https://archive.org/download/Combat_Test_7ab/1_16_combat-1.zip" + }, + { + "id": "1_16_combat-0", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_6", + "url": "https://launcher.mojang.com/experiments/combat/5a8ceec8681ed96ab6ecb9607fb5d19c8a755559/1_16_combat-0.zip" + }, + { + "id": "1_15_combat-6", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_5", + "url": "https://launcher.mojang.com/experiments/combat/52263d42a626b40c947e523128f7a195ec5af76a/1_15_combat-6.zip" + }, + { + "id": "1_15_combat-1", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_4", + "url": "https://launcher.mojang.com/experiments/combat/ac11ea96f3bb2fa2b9b76ab1d20cacb1b1f7ef60/1_15_combat-1.zip" + }, + { + "id": "1_14_combat-3", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_3", + "url": "https://launcher.mojang.com/experiments/combat/0f209c9c84b81c7d4c88b4632155b9ae550beb89/1_14_combat-3.zip" + }, + { + "id": "1_14_combat-0", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_2", + "url": "https://launcher.mojang.com/experiments/combat/d164bb6ecc5fca9ac02878c85f11befae61ac1ca/1_14_combat-0.zip" + }, + { + "id": "1_14_combat-212796", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.14.3_-_Combat_Test", + "url": "https://launcher.mojang.com/experiments/combat/610f5c9874ba8926d5ae1bcce647e5f0e6e7c889/1_14_combat-212796.zip" + } + ] +} diff --git a/meta/meta/common/mojang-minecraft-legacy-override.json b/meta/meta/common/mojang-minecraft-legacy-override.json new file mode 100644 index 0000000000..d1d951d05f --- /dev/null +++ b/meta/meta/common/mojang-minecraft-legacy-override.json @@ -0,0 +1,585 @@ +{ + "versions": { + "1.5.2": { + "releaseTime": "2013-04-25T17:45:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.5.1": { + "releaseTime": "2013-03-20T12:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w12~": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.5": { + "releaseTime": "2013-03-07T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w10b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w10a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w09c": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w09b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w09a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w11a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w07a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w06a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w05b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w05a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w04a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w03a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w02b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w02a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w01b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w01a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.7": { + "releaseTime": "2012-12-28T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.6": { + "releaseTime": "2012-12-20T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w50b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w50a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w49a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.5": { + "releaseTime": "2012-11-20T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.4": { + "releaseTime": "2012-11-14T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.3": { + "releaseTime": "2012-11-01T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.2": { + "releaseTime": "2012-10-25T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.1": { + "releaseTime": "2012-10-23T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4": { + "releaseTime": "2012-10-19T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w42b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w42a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w41b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w41a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w40b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w40a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w39b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w39a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w38b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w38a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w37a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w36a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w34b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w34a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.3.2": { + "releaseTime": "2012-08-16T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w32a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.3.1": { + "releaseTime": "2012-08-01T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.3": { + "releaseTime": "2012-07-26T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w30e": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w30d": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w30c": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w30b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w30a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w27a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w26a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w25a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w24a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w23b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w23a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w22a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w21b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w21a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w19a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w18a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w17a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w16a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.2.5": { + "releaseTime": "2012-03-30T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.2.4": { + "releaseTime": "2012-03-22T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.2.3": { + "releaseTime": "2012-03-02T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.2.2": { + "releaseTime": "2012-03-01T00:00:01+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.2.1": { + "releaseTime": "2012-03-01T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.2": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w08a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w07a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w07b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w06a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w05b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w05a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w04a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w03a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.1": { + "releaseTime": "2012-01-12T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w01a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "11w50a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "11w49a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "11w48a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "11w47a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.0": { + "releaseTime": "2011-11-18T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.9-pre6": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.9-pre5": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.9-pre4": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.9-pre3": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.9-pre2": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.9-pre1": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.8.1": { + "releaseTime": "2011-09-19T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.8": { + "releaseTime": "2011-09-15T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.8-pre2": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.8-pre1-2": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.7.3": { + "releaseTime": "2011-07-08T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.7.2": { + "releaseTime": "2011-07-01T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.7": { + "releaseTime": "2011-06-30T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6.6": { + "releaseTime": "2011-05-31T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6.5": { + "releaseTime": "2011-05-28T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6.4": { + "releaseTime": "2011-05-26T00:00:04+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6.3": { + "releaseTime": "2011-05-26T00:00:03+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6.2": { + "releaseTime": "2011-05-26T00:00:02+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6.1": { + "releaseTime": "2011-05-26T00:00:01+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6": { + "releaseTime": "2011-05-26T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.5_01": { + "releaseTime": "2011-04-20T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.5": { + "releaseTime": "2011-04-19T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.4_01": { + "releaseTime": "2011-04-05T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.4": { + "releaseTime": "2011-03-31T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.3_01": { + "releaseTime": "2011-02-23T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.3b": { + "releaseTime": "2011-02-22T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.2_02": { + "releaseTime": "2011-01-21T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.2_01": { + "releaseTime": "2011-01-14T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.2": { + "releaseTime": "2011-01-13T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.1_02": { + "releaseTime": "2010-12-22T00:00:01+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.1_01": { + "releaseTime": "2010-12-22T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.0.2": { + "releaseTime": "2010-12-21T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.0_01": { + "releaseTime": "2010-12-20T00:00:01+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.0": { + "releaseTime": "2010-12-20T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.6": { + "releaseTime": "2010-12-03T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.5": { + "releaseTime": "2010-12-01T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.4_01": { + "releaseTime": "2010-11-30T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.3_04": { + "releaseTime": "2010-11-26T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.3_02": { + "releaseTime": "2010-11-25T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.3_01": { + "releaseTime": "2010-11-24T00:00:01+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.3": { + "releaseTime": "2010-11-24T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.2b": { + "releaseTime": "2010-11-10T00:00:01+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.2a": { + "releaseTime": "2010-11-10T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.1_01": { + "releaseTime": "2010-11-05T00:00:01+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.2.1": { + "releaseTime": "2010-11-05T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.2.0_02": { + "releaseTime": "2010-11-04T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.2.0_01": { + "releaseTime": "2010-10-31T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.2.0": { + "releaseTime": "2010-10-30T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.1.2_01": { + "releaseTime": "2010-09-23T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.1.2": { + "releaseTime": "2010-09-20T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.1.0": { + "releaseTime": "2010-09-13T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.0.17_04": { + "releaseTime": "2010-08-23T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.0.17_02": { + "releaseTime": "2010-08-20T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.0.16": { + "releaseTime": "2010-08-12T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.0.15": { + "releaseTime": "2010-08-04T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.0.14": { + "releaseTime": "2010-07-30T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.0.11": { + "releaseTime": "2010-07-23T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.0.5_01": { + "releaseTime": "2010-07-13T00:00:00+02:00", + "mainClass": "y", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.0.4": { + "releaseTime": "2010-07-09T00:00:00+02:00", + "mainClass": "ax", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "inf-20100618": { + "releaseTime": "2010-06-16T00:00:00+02:00", + "mainClass": "net.minecraft.client.d", + "appletClass": "net.minecraft.client.MinecraftApplet", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "c0.30_01c": { + "releaseTime": "2009-12-22T00:00:00+02:00", + "mainClass": "com.mojang.minecraft.l", + "appletClass": "com.mojang.minecraft.MinecraftApplet", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "c0.0.13a_03": { + "releaseTime": "2009-05-22T00:00:00+02:00", + "mainClass": "com.mojang.minecraft.c", + "appletClass": "com.mojang.minecraft.MinecraftApplet", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "c0.0.13a": { + "releaseTime": "2009-05-31T00:00:00+02:00", + "mainClass": "com.mojang.minecraft.Minecraft", + "appletClass": "com.mojang.minecraft.MinecraftApplet", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "c0.0.11a": { + "releaseTime": "2009-05-17T00:00:00+02:00", + "mainClass": "com.mojang.minecraft.Minecraft", + "appletClass": "com.mojang.minecraft.MinecraftApplet", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "rd-161348": { + "releaseTime": "2009-05-16T13:48:00+02:00", + "mainClass": "com.mojang.minecraft.RubyDung", + "+traits": ["no-texturepacks"] + }, + "rd-160052": { + "releaseTime": "2009-05-16T00:52:00+02:00", + "mainClass": "com.mojang.rubydung.RubyDung", + "+traits": ["no-texturepacks"] + }, + "rd-20090515": { + "mainClass": "com.mojang.rubydung.RubyDung", + "+traits": ["no-texturepacks"] + }, + "rd-132328": { + "releaseTime": "2009-05-13T23:28:00+02:00", + "mainClass": "com.mojang.rubydung.RubyDung", + "+traits": ["no-texturepacks"] + }, + "rd-132211": { + "releaseTime": "2009-05-13T22:11:00+02:00", + "mainClass": "com.mojang.rubydung.RubyDung", + "+traits": ["no-texturepacks"] + } + } +} diff --git a/meta/meta/common/mojang-minecraft-legacy-services.json b/meta/meta/common/mojang-minecraft-legacy-services.json new file mode 100644 index 0000000000..420d3f8c74 --- /dev/null +++ b/meta/meta/common/mojang-minecraft-legacy-services.json @@ -0,0 +1,218 @@ +[ + "c0.30_01c", + "inf-20100618", + "a1.0.4", + "a1.0.5_01", + "a1.0.11", + "a1.0.14", + "a1.0.15", + "a1.0.16", + "a1.0.17_02", + "a1.0.17_04", + "a1.1.0", + "a1.1.2", + "a1.1.2_01", + "a1.2.0", + "a1.2.0_01", + "a1.2.0_02", + "a1.2.1", + "a1.2.1_01", + "a1.2.2a", + "a1.2.2b", + "a1.2.3", + "a1.2.3_01", + "a1.2.3_02", + "a1.2.3_04", + "a1.2.4_01", + "a1.2.5", + "a1.2.6", + "b1.0", + "b1.0_01", + "b1.0.2", + "b1.1_01", + "b1.1_02", + "b1.2", + "b1.2_01", + "b1.2_02", + "b1.3b", + "b1.3_01", + "b1.4", + "b1.4_01", + "b1.5", + "b1.5_01", + "b1.6", + "b1.6.1", + "b1.6.2", + "b1.6.3", + "b1.6.4", + "b1.6.5", + "b1.6.6", + "b1.7", + "b1.7.2", + "b1.7.3", + "b1.8-pre1-2", + "b1.8-pre2", + "b1.8", + "b1.8.1", + "b1.9-pre1", + "b1.9-pre2", + "b1.9-pre3", + "b1.9-pre4", + "b1.9-pre5", + "b1.9-pre6", + "1.0", + "11w47a", + "11w48a", + "11w49a", + "11w50a", + "12w01a", + "1.1", + "12w03a", + "12w04a", + "12w05a", + "12w05b", + "12w06a", + "12w07b", + "12w07a", + "12w08a", + "1.2", + "1.2.1", + "1.2.2", + "1.2.3", + "1.2.4", + "1.2.5", + "12w16a", + "12w17a", + "12w18a", + "12w19a", + "12w21a", + "12w21b", + "12w22a", + "12w23a", + "12w23b", + "12w24a", + "12w25a", + "12w26a", + "12w27a", + "12w30a", + "12w30b", + "12w30c", + "12w30d", + "12w30e", + "1.3", + "1.3.1", + "12w32a", + "1.3.2", + "12w34a", + "12w34b", + "12w36a", + "12w37a", + "12w38a", + "12w38b", + "12w39a", + "12w39b", + "12w40a", + "12w40b", + "12w41a", + "12w41b", + "12w42a", + "12w42b", + "1.4", + "1.4.1", + "1.4.2", + "1.4.3", + "1.4.4", + "1.4.5", + "12w49a", + "12w50a", + "12w50b", + "1.4.6", + "1.4.7", + "13w01a", + "13w01b", + "13w02a", + "13w02b", + "13w03a", + "13w04a", + "13w05a", + "13w05b", + "13w06a", + "13w07a", + "13w11a", + "13w09a", + "13w09b", + "13w09c", + "13w10a", + "13w10b", + "1.5", + "13w12~", + "1.5.1", + "1.5.2", + "13w17a", + "13w18a", + "13w18b", + "13w18c", + "13w19a", + "13w21a", + "13w21b", + "13w22a", + "13w23a", + "13w23b", + "13w24a", + "13w24b", + "13w25a", + "13w25b", + "13w25c", + "13w26a", + "1.6", + "1.6.1", + "1.6.2", + "13w36a", + "13w36b", + "13w37a", + "1.6.3", + "13w37b", + "1.6.4", + "13w38a", + "13w38b", + "13w38c", + "13w39a", + "13w39b", + "13w41a", + "13w41b", + "13w42a", + "13w42b", + "13w43a", + "1.7", + "1.7.1", + "1.7.2", + "13w47a", + "13w47b", + "13w47c", + "13w47d", + "13w47e", + "13w48a", + "13w48b", + "13w49a", + "1.7.3", + "1.7.4", + "14w02a", + "14w02b", + "14w02c", + "14w03a", + "14w03b", + "14w04a", + "14w04b", + "14w05a", + "14w05b", + "14w06a", + "14w06b", + "14w07a", + "1.7.5", + "14w08a", + "14w10b", + "14w10c", + "1.7.6-pre1", + "1.7.6-pre2", + "14w11a" +] diff --git a/meta/meta/common/mojang-minecraft-old-snapshots.json b/meta/meta/common/mojang-minecraft-old-snapshots.json new file mode 100644 index 0000000000..24ee0ce8b8 --- /dev/null +++ b/meta/meta/common/mojang-minecraft-old-snapshots.json @@ -0,0 +1,604 @@ +{ + "old_snapshots": [ + { + "id": "1_2", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.2", + "url": "https://archive.org/download/Minecraft-JSONs/1.2.json", + "sha1": "a2064011425a5e5befd9dee5eeb4f968ddf5ac77", + "size": 3988919, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_2/minecraft.jar" + }, + { + "id": "11w47a", + "wiki": "https://minecraft.wiki/w/Java_Edition_11w47a", + "url": "https://archive.org/download/Minecraft-JSONs/11w47a.json", + "sha1": "4e327918708d22e7443fbadefb9831ca04af4b90", + "size": 2242242, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/11w47a/minecraft.jar" + }, + { + "id": "11w48a", + "wiki": "https://minecraft.wiki/w/Java_Edition_11w48a", + "url": "https://archive.org/download/Minecraft-JSONs/11w48a.json", + "sha1": "fede770abe88a19e844d99dda611a7d18184155a", + "size": 2242604, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/11w48a/minecraft.jar" + }, + { + "id": "11w49a", + "wiki": "https://minecraft.wiki/w/Java_Edition_11w49a", + "url": "https://archive.org/download/Minecraft-JSONs/11w49a.json", + "sha1": "6f92a726e6b8b64f66c7e4d236f983c278d5af54", + "size": 3510866, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/11w49a/minecraft.jar" + }, + { + "id": "11w50a", + "wiki": "https://minecraft.wiki/w/Java_Edition_11w50a", + "url": "https://archive.org/download/Minecraft-JSONs/11w50a.json", + "sha1": "f4981ba0fee00a16d8dc9ec87bf2c4fdb51e4b7c", + "size": 3509701, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/11w50a/minecraft.jar" + }, + { + "id": "12w01a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w01a", + "url": "https://archive.org/download/Minecraft-JSONs/12w01a.json", + "sha1": "653a9cf55884b6bc4dcf3c574331e04bd5ad1032", + "size": 3839447, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w01a/minecraft.jar" + }, + { + "id": "12w03a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w03a", + "url": "https://archive.org/download/Minecraft-JSONs/12w03a.json", + "sha1": "e581c7c9dd57cbf73f72b833be5eff6109187df0", + "size": 3875210, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w03a/minecraft.jar" + }, + { + "id": "12w04a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w04a", + "url": "https://archive.org/download/Minecraft-JSONs/12w04a.json", + "sha1": "4911c473e856ec8102b8419eb36d0f54dad029a0", + "size": 3911974, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w04a/minecraft.jar" + }, + { + "id": "12w05a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w05a", + "url": "https://archive.org/download/Minecraft-JSONs/12w05a.json", + "sha1": "28328e67b82564335aa8280095a0716a2eb790de", + "size": 3931639, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w05a/minecraft.jar" + }, + { + "id": "12w05b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w05b", + "url": "https://archive.org/download/Minecraft-JSONs/12w05b.json", + "sha1": "75fbc4a39a244d0f1eb842ff8385e992e2b47dd5", + "size": 3931694, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w05b/minecraft.jar" + }, + { + "id": "12w06a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w06a", + "url": "https://archive.org/download/Minecraft-JSONs/12w06a.json", + "sha1": "a8403c0d4c0cdb65722d864d9cf42663b8aab08b", + "size": 3934973, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w06a/minecraft.jar" + }, + { + "id": "12w07a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w07a", + "url": "https://archive.org/download/Minecraft-JSONs/12w07a.json", + "sha1": "e7ad115b29612b893972f0817030d993bc56fb7e", + "size": 3956252, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w07a/minecraft.jar" + }, + { + "id": "12w07b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w07b", + "url": "https://archive.org/download/Minecraft-JSONs/12w07b.json", + "sha1": "0eea35d588fc2cee5d397472aa3565f48c220217", + "size": 3956323, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w07b/minecraft.jar" + }, + { + "id": "12w08a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w08a", + "url": "https://archive.org/download/Minecraft-JSONs/12w08a.json", + "sha1": "db2fcfdd23526b0f381ef2f3f2fd049d36227230", + "size": 3981486, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w08a/minecraft.jar" + }, + { + "id": "12w16a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w16a", + "url": "https://archive.org/download/Minecraft-JSONs/12w16a.json", + "sha1": "6b0a9fe3ac275f79ac6d259f4279752274ec05f8", + "size": 4080437, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w16a/minecraft.jar" + }, + { + "id": "12w17a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w17a", + "url": "https://archive.org/download/Minecraft-JSONs/12w17a.json", + "sha1": "17d41f8a07e054040ba34e523593bdea7f0fb6ba", + "size": 4114768, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w17a/minecraft.jar" + }, + { + "id": "12w18a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w18a", + "url": "https://archive.org/download/Minecraft-JSONs/12w18a.json", + "sha1": "9e9ab992317048bee9158ad9d1e2bc758db2b4af", + "size": 4317820, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w18a/minecraft.zip/bin/minecraft.jar" + }, + { + "id": "12w19a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w19a", + "url": "https://archive.org/download/Minecraft-JSONs/12w19a.json", + "sha1": "474aaac9a8b1dcbf312a5c09c7eae4a6aa401225", + "size": 4343792, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w19a/minecraft.zip/bin/minecraft.jar" + }, + { + "id": "12w21a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w21a", + "url": "https://archive.org/download/Minecraft-JSONs/12w21a.json", + "sha1": "e755423a04b0efde01e035a9d651acadeba0aef9", + "size": 4409586, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w21a/minecraft.jar" + }, + { + "id": "12w21b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w21b", + "url": "https://archive.org/download/Minecraft-JSONs/12w21b.json", + "sha1": "84437ded4839b29d34f83e9f3bab07cc48980faf", + "size": 4499708, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w21b/minecraft.jar" + }, + { + "id": "12w22a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w22a", + "url": "https://archive.org/download/Minecraft-JSONs/12w22a.json", + "sha1": "3631a714cb465d39f5cb5c18aa23abf38031b359", + "size": 4542344, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w22a/minecraft.jar" + }, + { + "id": "12w23a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w23a", + "url": "https://archive.org/download/Minecraft-JSONs/12w23a.json", + "sha1": "4a5a8e3349ea2e9d67fa4dde6ec68d385bff46f0", + "size": 4543912, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w23a/minecraft.jar" + }, + { + "id": "12w23b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w23b", + "url": "https://archive.org/download/Minecraft-JSONs/12w23b.json", + "sha1": "e107667bcbb4443afc160a7eeb8f347acc9826f8", + "size": 4543928, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w23b/minecraft.jar" + }, + { + "id": "12w24a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w24a", + "url": "https://archive.org/download/Minecraft-JSONs/12w24a.json", + "sha1": "e479c425ffe6ca3512d97ad0e02a8cd85356bf83", + "size": 4540049, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w24a/minecraft.jar" + }, + { + "id": "12w25a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w25a", + "url": "https://archive.org/download/Minecraft-JSONs/12w25a.json", + "sha1": "eddf53994e40ecc44f582d4b47b9a441844909b6", + "size": 4556548, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w25a/minecraft.jar" + }, + { + "id": "12w26a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w26a", + "url": "https://archive.org/download/Minecraft-JSONs/12w26a.json", + "sha1": "2d1e782a4c4435fe921027ae464a272945cca925", + "size": 4573075, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w26a/minecraft.jar" + }, + { + "id": "12w27a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w27a", + "url": "https://archive.org/download/Minecraft-JSONs/12w27a.json", + "sha1": "5e69b80f9c757bdc8275c1f6ce7e71820fe6d79a", + "size": 4584956, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w27a/minecraft.jar" + }, + { + "id": "12w30a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w30a", + "url": "https://archive.org/download/Minecraft-JSONs/12w30a.json", + "sha1": "368215d7fd38ee3e829725e11b3f193d45801128", + "size": 4584574, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30a/minecraft.jar" + }, + { + "id": "12w30b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w30b", + "url": "https://archive.org/download/Minecraft-JSONs/12w30b.json", + "sha1": "9d1e450cdb300ec426b50762e031796a8349aa1c", + "size": 4584593, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30b/minecraft.jar" + }, + { + "id": "12w30c", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w30c", + "url": "https://archive.org/download/Minecraft-JSONs/12w30c.json", + "sha1": "92817a0c3f3c913ad68bdb082ac1f147db986282", + "size": 4584617, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30c/minecraft.jar" + }, + { + "id": "12w30d", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w30d", + "url": "https://archive.org/download/Minecraft-JSONs/12w30d.json", + "sha1": "a5e7508de2d3993cb5222d8e4f8415226745d6ff", + "size": 4585459, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30d/minecraft.jar" + }, + { + "id": "12w30e", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w30e", + "url": "https://archive.org/download/Minecraft-JSONs/12w30e.json", + "sha1": "1a37562cda14028dae15b331bfd36108e617a477", + "size": 4585506, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30e/minecraft.jar" + }, + { + "id": "12w32a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w32a", + "url": "https://archive.org/download/Minecraft-JSONs/12w32a.json", + "sha1": "13183e023c8918ed08c302c2fe1438f61b53d094", + "size": 4628354, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w32a/minecraft.jar" + }, + { + "id": "12w34a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w34a", + "url": "https://archive.org/download/Minecraft-JSONs/12w34a.json", + "sha1": "41769085c020f4651b5b5dd50a6f83be2b000b29", + "size": 4676139, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w34a/minecraft.jar" + }, + { + "id": "12w34b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w34b", + "url": "https://archive.org/download/Minecraft-JSONs/12w34b.json", + "sha1": "5fb51efc8f07ea57ffc2a02a7dac8a2835651b61", + "size": 4682004, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w34b/minecraft.jar" + }, + { + "id": "12w36a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w36a", + "url": "https://archive.org/download/Minecraft-JSONs/12w36a.json", + "sha1": "914bd89686c4621da327d50375a1edbdd9c177da", + "size": 4705667, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w36a/minecraft.jar" + }, + { + "id": "12w37a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w37a", + "url": "https://archive.org/download/Minecraft-JSONs/12w37a.json", + "sha1": "50ea0bac2c91b13c0881bbf99aad66a046533781", + "size": 4727781, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w37a/minecraft.jar" + }, + { + "id": "12w38a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w38a", + "url": "https://archive.org/download/Minecraft-JSONs/12w38a.json", + "sha1": "69e5a531fa615eb870345feb25f26126fe95586b", + "size": 4752649, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w38a/minecraft.jar" + }, + { + "id": "12w38b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w38b", + "url": "https://archive.org/download/Minecraft-JSONs/12w38b.json", + "sha1": "867505cb4934016bf46cb8c7833ef0eaef8d39d9", + "size": 4767044, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w38b/minecraft.jar" + }, + { + "id": "12w39a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w39a", + "url": "https://archive.org/download/Minecraft-JSONs/12w39a.json", + "sha1": "65247c02036156b9f34c17f7d8bb053641afd0e7", + "size": 4768937, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w39a/minecraft.jar" + }, + { + "id": "12w39b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w39b", + "url": "https://archive.org/download/Minecraft-JSONs/12w39b.json", + "sha1": "620d02bfd74204462a810874f83929d0b8b0b936", + "size": 4766448, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w39b/minecraft.jar" + }, + { + "id": "12w40a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w40a", + "url": "https://archive.org/download/Minecraft-JSONs/12w40a.json", + "sha1": "434652551e93fdfb4de30cbe64310037777f7eff", + "size": 4884173, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w40a/minecraft.jar" + }, + { + "id": "12w40b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w40b", + "url": "https://archive.org/download/Minecraft-JSONs/12w40b.json", + "sha1": "1612e0fa6062f764844c5a71ff89660c311f38ae", + "size": 4884732, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w40b/minecraft.jar" + }, + { + "id": "12w41a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w41a", + "url": "https://archive.org/download/Minecraft-JSONs/12w41a.json", + "sha1": "7327bcd4da0d194565d6ee732b1fa48e8b14b347", + "size": 4900512, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w41a/minecraft.jar" + }, + { + "id": "12w41b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w41b", + "url": "https://archive.org/download/Minecraft-JSONs/12w41b.json", + "sha1": "d73a5b6919d10689811c11d1c3debcd817050039", + "size": 4900976, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w41b/minecraft.jar" + }, + { + "id": "12w42a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w42a", + "url": "https://archive.org/download/Minecraft-JSONs/12w42a.json", + "sha1": "0b10f7afbd54392b387a23c34547cb0f30d48998", + "size": 4919860, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w42a/minecraft.jar" + }, + { + "id": "12w42b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w42b", + "url": "https://archive.org/download/Minecraft-JSONs/12w42b.json", + "sha1": "74024eab7588bd33dd53baa756fd4deb92557b0a", + "size": 4921744, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w42b/minecraft.jar" + }, + { + "id": "12w49a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w49a", + "url": "https://archive.org/download/Minecraft-JSONs/12w49a.json", + "sha1": "a5a4cf65cf89207eb6ad7371c9237973865eba81", + "size": 4990865, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w49a/minecraft.jar" + }, + { + "id": "12w50a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w50a", + "url": "https://archive.org/download/Minecraft-JSONs/12w50a.json", + "sha1": "96a6427720aef608a594ed1e0291e77cba398155", + "size": 5004175, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w50a/minecraft.jar" + }, + { + "id": "12w50b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w50b", + "url": "https://archive.org/download/Minecraft-JSONs/12w50b.json", + "sha1": "73dc6efe46fef478cc5ed123e711872450e193fd", + "size": 5005360, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w50b/minecraft.jar" + }, + { + "id": "13w01a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w01a", + "url": "https://archive.org/download/Minecraft-JSONs/13w01a.json", + "sha1": "e3256fe44cd7c6a1bf45570337e634b030589878", + "size": 5033591, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w01a/minecraft.jar" + }, + { + "id": "13w01b", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w01b", + "url": "https://archive.org/download/Minecraft-JSONs/13w01b.json", + "sha1": "87f9f88eb3dcc80dcf818e44af774ab7ff63eb66", + "size": 5035543, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w01b/minecraft.jar" + }, + { + "id": "13w02a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w02a", + "url": "https://archive.org/download/Minecraft-JSONs/13w02a.json", + "sha1": "e9a57e8d5dcddcc9d919054c19b10eb71fcc304e", + "size": 5499864, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w02a/minecraft.jar" + }, + { + "id": "13w02b", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w02b", + "url": "https://archive.org/download/Minecraft-JSONs/13w02b.json", + "sha1": "9289953c82ce69ec3d2e59a6044a9c900a99478f", + "size": 5363159, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w02b/minecraft.jar" + }, + { + "id": "13w03a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w03a", + "url": "https://archive.org/download/Minecraft-JSONs/13w03a.json", + "sha1": "6a2d3ffa88b7f5e0949f041193c6525d1c4cc22e", + "size": 6401672, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w03a/minecraft.jar" + }, + { + "id": "13w04a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w04a", + "url": "https://archive.org/download/Minecraft-JSONs/13w04a.json", + "sha1": "dff06285694aab7771682f949d51bca98ce52359", + "size": 6426112, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w04a/minecraft.jar" + }, + { + "id": "13w05a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w05a", + "url": "https://archive.org/download/Minecraft-JSONs/13w05a.json", + "sha1": "7808f090cb92afc8084545dd2ea305773bbd5e6e", + "size": 6442319, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w05a/minecraft.jar" + }, + { + "id": "13w05b", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w05b", + "url": "https://archive.org/download/Minecraft-JSONs/13w05b.json", + "sha1": "72074d7cb843229292f71ae917dcefbc0f01461d", + "size": 6442459, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w05b/minecraft.jar" + }, + { + "id": "13w06a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w06a", + "url": "https://archive.org/download/Minecraft-JSONs/13w06a.json", + "sha1": "da409ce9f9c910c08cc729aadc6f592b8ff813cb", + "size": 6445893, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w06a/minecraft.jar" + }, + { + "id": "13w07a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w07a", + "url": "https://archive.org/download/Minecraft-JSONs/13w07a.json", + "sha1": "61f7dad52c34838be7a1e7d37a2370ac847ab87a", + "size": 6510193, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w07a/minecraft.jar" + }, + { + "id": "13w09a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w09a", + "url": "https://archive.org/download/Minecraft-JSONs/13w09a.json", + "sha1": "9ac49c55ca76eedfc985fa245dd0682e08b34982", + "size": 5574252, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w09a/minecraft.jar" + }, + { + "id": "13w09b", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w09b", + "url": "https://archive.org/download/Minecraft-JSONs/13w09b.json", + "sha1": "635161d84725b1988f814c890fe5841ad99121e1", + "size": 5578604, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w09b/minecraft.jar" + }, + { + "id": "13w09c", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w09c", + "url": "https://archive.org/download/Minecraft-JSONs/13w09c.json", + "sha1": "1367ef1410c2ce7ac0f1c58727aa4883c8677469", + "size": 5533426, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w09c/minecraft.jar" + }, + { + "id": "13w10a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w10a", + "url": "https://archive.org/download/Minecraft-JSONs/13w10a.json", + "sha1": "9162bca3ba8a77da2cd26cda1e46ca89a44bac4a", + "size": 5534991, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w10a/minecraft.jar" + }, + { + "id": "13w10b", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w10b", + "url": "https://archive.org/download/Minecraft-JSONs/13w10b.json", + "sha1": "21e35ffe1772d1cf89aea653c7a883acb54b13a3", + "size": 5555235, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w10b/minecraft.jar" + }, + { + "id": "13w11a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w11a", + "url": "https://archive.org/download/Minecraft-JSONs/13w11a.json", + "sha1": "bec6c96bc4413ea3092428aba93d7425fe6a4ea9", + "size": 5556608, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w11a/minecraft.jar" + }, + { + "id": "13w12~", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w12~", + "url": "https://archive.org/download/Minecraft-JSONs/13w12~.json", + "sha1": "66d6c6b5205ae1e8f0ad3eb78ccf66500f39c0c7", + "size": 5561634, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w12_/minecraft.jar" + }, + { + "id": "b1_8-pre1", + "wiki": "https://minecraft.wiki/w/Java_Edition_b1.8-pre1-2", + "url": "https://archive.org/download/Minecraft-JSONs/b1.8-pre1-2.json", + "sha1": "6789c69ede3aedf83b800c76bea56855d38a0afc", + "size": 1893151, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_8-pre/minecraft.jar" + }, + { + "id": "b1_8-pre2", + "wiki": "https://minecraft.wiki/w/Java_Edition_b1.8-pre2", + "url": "https://archive.org/download/Minecraft-JSONs/b1.8-pre2.json", + "sha1": "44191f2895bf1e064269c9279778f2e3e9c3c9c7", + "size": 1897780, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_8-pre2/minecraft.jar" + }, + { + "id": "b1_9-pre1", + "wiki": "https://minecraft.wiki/w/Java_Edition_b1.9-pre1", + "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre1.json", + "sha1": "fdeef0129af130aa00702e53c37c5c4029b7d50e", + "size": 1966908, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre/minecraft.jar" + }, + { + "id": "b1_9-pre2", + "wiki": "https://minecraft.wiki/w/Java_Edition_b1.9-pre2", + "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre2.json", + "sha1": "b0d40cf43b625631af65e2a645c34b533251da0e", + "size": 1988123, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre2/minecraft.jar" + }, + { + "id": "b1_9-pre3", + "wiki": "https://minecraft.wiki/w/Java_Edition_b1.9-pre3", + "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre3.json", + "sha1": "5b7fe76a602b7511c97740e36dc25040ccb6e76b", + "size": 2087104, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre3/minecraft.jar" + }, + { + "id": "b1_9-pre4", + "wiki": "https://minecraft.wiki/w/Java_Edition_b1.9-pre4", + "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre4.json", + "sha1": "5c4831d9705f2e00e3cd993e89b822636492932a", + "size": 2147107, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre4/minecraft.jar" + }, + { + "id": "b1_9-pre5", + "wiki": "https://minecraft.wiki/w/Java_Edition_b1.9-pre5", + "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre5.json", + "sha1": "e109b297d2c4ee7a0bd6aed72f38f7e3185654cf", + "size": 2211261, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre5/minecraft.jar" + }, + { + "id": "b1_9-pre6", + "wiki": "https://minecraft.wiki/w/Java_Edition_b1.9-pre6", + "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre6.json", + "sha1": "f0983e65cd1c0768b0d1fec471ce4f69173b8126", + "size": 2239270, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre6/minecraft.jar" + } + ] +} diff --git a/meta/meta/common/mojang.py b/meta/meta/common/mojang.py new file mode 100644 index 0000000000..fe36c3c02b --- /dev/null +++ b/meta/meta/common/mojang.py @@ -0,0 +1,23 @@ +from os.path import join, dirname + +BASE_DIR = "mojang" + +VERSION_MANIFEST_FILE = join(BASE_DIR, "version_manifest_v2.json") +VERSIONS_DIR = join(BASE_DIR, "versions") +ASSETS_DIR = join(BASE_DIR, "assets") + +STATIC_EXPERIMENTS_FILE = join(dirname(__file__), "mojang-minecraft-experiments.json") +STATIC_OLD_SNAPSHOTS_FILE = join( + dirname(__file__), "mojang-minecraft-old-snapshots.json" +) +STATIC_OVERRIDES_FILE = join(dirname(__file__), "mojang-minecraft-legacy-override.json") +STATIC_LEGACY_SERVICES_FILE = join( + dirname(__file__), "mojang-minecraft-legacy-services.json" +) +LIBRARY_PATCHES_FILE = join(dirname(__file__), "mojang-library-patches.json") + +MINECRAFT_COMPONENT = "net.minecraft" +LWJGL_COMPONENT = "org.lwjgl" +LWJGL3_COMPONENT = "org.lwjgl3" + +JAVA_MANIFEST_FILE = join(BASE_DIR, "java_all.json") diff --git a/meta/meta/common/neoforge.py b/meta/meta/common/neoforge.py new file mode 100644 index 0000000000..83f4890e97 --- /dev/null +++ b/meta/meta/common/neoforge.py @@ -0,0 +1,14 @@ +from os.path import join + +from ..model import GradleSpecifier, make_launcher_library + +BASE_DIR = "neoforge" + +JARS_DIR = join(BASE_DIR, "jars") +INSTALLER_INFO_DIR = join(BASE_DIR, "installer_info") +INSTALLER_MANIFEST_DIR = join(BASE_DIR, "installer_manifests") +VERSION_MANIFEST_DIR = join(BASE_DIR, "version_manifests") +FILE_MANIFEST_DIR = join(BASE_DIR, "files_manifests") +DERIVED_INDEX_FILE = join(BASE_DIR, "derived_index.json") + +NEOFORGE_COMPONENT = "net.neoforged" diff --git a/meta/meta/common/quilt.py b/meta/meta/common/quilt.py new file mode 100644 index 0000000000..b8203898b0 --- /dev/null +++ b/meta/meta/common/quilt.py @@ -0,0 +1,44 @@ +from os.path import join +from .fabric import INTERMEDIARY_COMPONENT as FABRIC_INTERMEDIARY_COMPONENT + +# Right now Quilt recommends using Fabric's intermediary +USE_QUILT_MAPPINGS = False + +BASE_DIR = "quilt" + +JARS_DIR = join(BASE_DIR, "jars") +INSTALLER_INFO_DIR = join(BASE_DIR, "loader-installer-json") +META_DIR = join(BASE_DIR, "meta-v3") + +LOADER_COMPONENT = "org.quiltmc.quilt-loader" +INTERMEDIARY_COMPONENT = "org.quiltmc.hashed" + +if not USE_QUILT_MAPPINGS: + INTERMEDIARY_COMPONENT = FABRIC_INTERMEDIARY_COMPONENT + +DISABLE_BEACON_ARG = "-Dloader.disable_beacon=true" +DISABLE_BEACON_VERSIONS = { + "0.19.2-beta.3", + "0.19.2-beta.4", + "0.19.2-beta.5", + "0.19.2-beta.6", + "0.19.2-beta.7", + "0.19.2", + "0.19.3-beta.1", + "0.19.3", + "0.19.4", + "0.20.0-beta.1", + "0.20.0-beta.2", + "0.20.0-beta.3", + "0.20.0-beta.4", + "0.20.0-beta.5", + "0.20.0-beta.6", + "0.20.0-beta.7", + "0.20.0-beta.8", + "0.20.0-beta.9", + "0.20.0-beta.10", + "0.20.0-beta.11", + "0.20.0-beta.12", + "0.20.0-beta.13", + "0.20.0-beta.14", +} diff --git a/meta/meta/model/__init__.py b/meta/meta/model/__init__.py new file mode 100644 index 0000000000..203b367ed5 --- /dev/null +++ b/meta/meta/model/__init__.py @@ -0,0 +1,363 @@ +import copy +from datetime import datetime +from pathlib import Path +from typing import Optional, List, Dict, Any, Iterator + +import pydantic +from pydantic import Field, validator # type: ignore + +from ..common import ( + LAUNCHER_MAVEN, + serialize_datetime, + replace_old_launchermeta_url, + get_all_bases, + merge_dict, +) + +META_FORMAT_VERSION = 1 + + +class GradleSpecifier: + """ + A gradle specifier - a maven coordinate. Like one of these: + "org.lwjgl.lwjgl:lwjgl:2.9.0" + "net.java.jinput:jinput:2.0.5" + "net.minecraft:launchwrapper:1.5" + """ + + def __init__( + self, + group: str, + artifact: str, + version: str, + classifier: Optional[str] = None, + extension: Optional[str] = None, + ): + if extension is None: + extension = "jar" + self.group = group + self.artifact = artifact + self.version = version + self.classifier = classifier + self.extension = extension + + def __str__(self): + ext = "" + if self.extension != "jar": + ext = "@%s" % self.extension + if self.classifier: + return "%s:%s:%s:%s%s" % ( + self.group, + self.artifact, + self.version, + self.classifier, + ext, + ) + else: + return "%s:%s:%s%s" % (self.group, self.artifact, self.version, ext) + + def filename(self): + if self.classifier: + return "%s-%s-%s.%s" % ( + self.artifact, + self.version, + self.classifier, + self.extension, + ) + else: + return "%s-%s.%s" % (self.artifact, self.version, self.extension) + + def base(self): + return "%s/%s/%s/" % (self.group.replace(".", "/"), self.artifact, self.version) + + def path(self): + return self.base() + self.filename() + + def __repr__(self): + return f"GradleSpecifier('{self}')" + + def is_lwjgl(self): + return self.group in ( + "org.lwjgl", + "org.lwjgl.lwjgl", + "net.java.jinput", + "net.java.jutils", + ) + + def is_log4j(self): + return self.group == "org.apache.logging.log4j" + + def __eq__(self, other: Any): + if isinstance(other, GradleSpecifier): + return str(self) == str(other) + else: + return False + + def __lt__(self, other: "GradleSpecifier"): + return str(self) < str(other) + + def __gt__(self, other: "GradleSpecifier"): + return str(self) > str(other) + + def __hash__(self): + return hash(str(self)) + + @classmethod + def __get_validators__(cls): + yield cls.validate + + @classmethod + def from_string(cls, v: str): + ext_split = v.split("@") + + components = ext_split[0].split(":") + group = components[0] + artifact = components[1] + version = components[2] + + extension = None + if len(ext_split) == 2: + extension = ext_split[1] + + classifier = None + if len(components) == 4: + classifier = components[3] + return cls(group, artifact, version, classifier, extension) + + @classmethod + def validate(cls, v: "str | GradleSpecifier"): + if isinstance(v, cls): + return v + if isinstance(v, str): + return cls.from_string(v) + raise TypeError("Invalid type") + + +class MetaBase(pydantic.BaseModel): + def dict(self, **kwargs: Any) -> Dict[str, Any]: + for k in ["by_alias"]: + if k in kwargs: + del kwargs[k] + + return super(MetaBase, self).dict(by_alias=True, **kwargs) + + def json(self, **kwargs: Any) -> str: + for k in ["exclude_none", "sort_keys", "indent"]: + if k in kwargs: + del kwargs[k] + + return super(MetaBase, self).json( + exclude_none=True, sort_keys=True, by_alias=True, indent=4, **kwargs + ) + + def write(self, file_path: str): + Path(file_path).parent.mkdir(parents=True, exist_ok=True) + with open(file_path, "w") as f: + f.write(self.json()) + + def merge(self, other: "MetaBase"): + """ + Merge other object with self. + - Concatenates lists + - Combines sets + - Merges dictionaries (other takes priority) + - Recurses for all fields that are also MetaBase classes + - Overwrites for any other field type (int, string, ...) + """ + assert type(other) is type(self) + for key, field in self.__fields__.items(): + ours = getattr(self, key) + theirs = getattr(other, key) + if theirs is None: + continue + if ours is None: + setattr(self, key, theirs) + continue + + if isinstance(ours, list): + ours += theirs + elif isinstance(ours, set): + ours |= theirs + elif isinstance(ours, dict): + result = merge_dict(ours, copy.deepcopy(theirs)) # type: ignore + setattr(self, key, result) + elif MetaBase in get_all_bases(field.type_): + ours.merge(theirs) + else: + setattr(self, key, theirs) + + def __hash__(self): # type: ignore + return hash(self.json()) + + class Config: + allow_population_by_field_name = True + + json_encoders = {datetime: serialize_datetime, GradleSpecifier: str} + + +class Versioned(MetaBase): + @validator("format_version") + def format_version_must_be_supported(cls, v: int): + assert v <= META_FORMAT_VERSION + return v + + format_version: int = Field(META_FORMAT_VERSION, alias="formatVersion") + + +class MojangArtifactBase(MetaBase): + sha1: Optional[str] + size: Optional[int] + url: str + + +class MojangAssets(MojangArtifactBase): + @validator("url") + def validate_url(cls, v: str): + return replace_old_launchermeta_url(v) + + id: str + totalSize: int + + +class MojangArtifact(MojangArtifactBase): + path: Optional[str] + + +class MojangLibraryExtractRules(MetaBase): + """ + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "osx" + } + } + ] + """ + + exclude: List[str] # TODO maybe drop this completely? + + +class MojangLibraryDownloads(MetaBase): + artifact: Optional[MojangArtifact] + classifiers: Optional[Dict[Any, MojangArtifact]] + + +class OSRule(MetaBase): + @validator("name") + def name_must_be_os(cls, v: str): + assert v in [ + "osx", + "linux", + "windows", + "windows-arm64", + "osx-arm64", + "linux-arm64", + "linux-arm32", + "linux-riscv64", + ] + return v + + name: str + version: Optional[str] + + +class MojangRule(MetaBase): + @validator("action") + def action_must_be_allow_disallow(cls, v: str): + assert v in ["allow", "disallow"] + return v + + action: str + os: Optional[OSRule] + + +class MojangRules(MetaBase): + __root__: List[MojangRule] + + def __iter__(self) -> Iterator[MojangRule]: # type: ignore + return iter(self.__root__) + + def __getitem__(self, item: int) -> MojangRule: + return self.__root__[item] + + +class MojangLoggingArtifact(MojangArtifactBase): + id: str + + +class MojangLogging(MetaBase): + @validator("type") + def validate_type(cls, v): + assert v in ["log4j2-xml"] + return v + + file: MojangLoggingArtifact + argument: str + type: str + + +class Library(MetaBase): + extract: Optional[MojangLibraryExtractRules] + name: Optional[GradleSpecifier] + downloads: Optional[MojangLibraryDownloads] + natives: Optional[Dict[str, str]] + rules: Optional[MojangRules] + url: Optional[str] + mmcHint: Optional[str] = Field(None, alias="MMC-hint") + + +class JavaAgent(Library): + argument: Optional[str] + + +class Dependency(MetaBase): + uid: str + equals: Optional[str] + suggests: Optional[str] + + +class MetaVersion(Versioned): + name: str + version: str + uid: str + type: Optional[str] + order: Optional[int] + volatile: Optional[bool] + requires: Optional[List[Dependency]] + conflicts: Optional[List[Dependency]] + libraries: Optional[List[Library]] + asset_index: Optional[MojangAssets] = Field(alias="assetIndex") + maven_files: Optional[List[Library]] = Field(alias="mavenFiles") + main_jar: Optional[Library] = Field(alias="mainJar") + jar_mods: Optional[List[Library]] = Field(alias="jarMods") + main_class: Optional[str] = Field(alias="mainClass") + applet_class: Optional[str] = Field(alias="appletClass") + minecraft_arguments: Optional[str] = Field(alias="minecraftArguments") + release_time: Optional[datetime] = Field(alias="releaseTime") + compatible_java_majors: Optional[List[int]] = Field(alias="compatibleJavaMajors") + compatible_java_name: Optional[str] = Field(alias="compatibleJavaName") + java_agents: Optional[List[JavaAgent]] = Field(alias="+agents") + additional_traits: Optional[List[str]] = Field(alias="+traits") + additional_tweakers: Optional[List[str]] = Field(alias="+tweakers") + additional_jvm_args: Optional[List[str]] = Field(alias="+jvmArgs") + logging: Optional[MojangLogging] + + +class MetaPackage(Versioned): + name: str + uid: str + recommended: Optional[List[str]] + authors: Optional[List[str]] + description: Optional[str] + project_url: Optional[str] = Field(alias="projectUrl") + + +def make_launcher_library( + name: GradleSpecifier, hash: str, size: int, maven=LAUNCHER_MAVEN +): + artifact = MojangArtifact(url=maven % name.path(), sha1=hash, size=size) + return Library(name=name, downloads=MojangLibraryDownloads(artifact=artifact)) diff --git a/meta/meta/model/enum.py b/meta/meta/model/enum.py new file mode 100644 index 0000000000..08dda4bf4a --- /dev/null +++ b/meta/meta/model/enum.py @@ -0,0 +1,32 @@ +import enum + + +class StrEnum(str, enum.Enum): + """ + StrEnum is a Python ``enum.Enum`` that inherits from ``str``. The default + ``auto()`` behavior uses the member name as its value. + + Example usage:: + + class Example(StrEnum): + UPPER_CASE = auto() + lower_case = auto() + MixedCase = auto() + + assert Example.UPPER_CASE == "UPPER_CASE" + assert Example.lower_case == "lower_case" + assert Example.MixedCase == "MixedCase" + """ + + def __new__(cls, value, *args, **kwargs): + if not isinstance(value, (str, enum.auto)): + raise TypeError( + f"Values of StrEnums must be strings: {value!r} is a {type(value)}" + ) + return super().__new__(cls, value, *args, **kwargs) + + def __str__(self): + return str(self.value) + + def _generate_next_value_(name, *_): + return name diff --git a/meta/meta/model/fabric.py b/meta/meta/model/fabric.py new file mode 100644 index 0000000000..5cb0e9caab --- /dev/null +++ b/meta/meta/model/fabric.py @@ -0,0 +1,40 @@ +from datetime import datetime +from typing import Optional, List, Union + +from pydantic import Field + +from . import Library, MetaBase + + +class FabricInstallerArguments(MetaBase): + client: Optional[List[str]] + common: Optional[List[str]] + server: Optional[List[str]] + + +class FabricInstallerLaunchwrapper(MetaBase): + tweakers: FabricInstallerArguments + + +class FabricInstallerLibraries(MetaBase): + client: Optional[List[Library]] + common: Optional[List[Library]] + server: Optional[List[Library]] + + +class FabricMainClasses(MetaBase): + client: Optional[str] + common: Optional[str] + server: Optional[str] + + +class FabricInstallerDataV1(MetaBase): + version: int + libraries: FabricInstallerLibraries + main_class: Optional[Union[str, FabricMainClasses]] = Field(alias="mainClass") + arguments: Optional[FabricInstallerArguments] + launchwrapper: Optional[FabricInstallerLaunchwrapper] + + +class FabricJarInfo(MetaBase): + release_time: Optional[datetime] = Field(alias="releaseTime") diff --git a/meta/meta/model/forge.py b/meta/meta/model/forge.py new file mode 100644 index 0000000000..a59b87aa5c --- /dev/null +++ b/meta/meta/model/forge.py @@ -0,0 +1,365 @@ +from datetime import datetime +from typing import Optional, List, Dict + +from pydantic import Field + +from . import MetaBase, GradleSpecifier, Library +from .mojang import MojangVersion + + +class ForgeFile(MetaBase): + classifier: str + hash: str + extension: str + + def filename(self, long_version): + return "%s-%s-%s.%s" % ("forge", long_version, self.classifier, self.extension) + + def url(self, long_version): + return "https://maven.minecraftforge.net/net/minecraftforge/forge/%s/%s" % ( + long_version, + self.filename(long_version), + ) + + +class ForgeEntry(MetaBase): + long_version: str = Field(alias="longversion") + mc_version: str = Field(alias="mcversion") + version: str + build: int + branch: Optional[str] + latest: Optional[bool] + recommended: Optional[bool] + files: Optional[Dict[str, ForgeFile]] + + +class ForgeMCVersionInfo(MetaBase): + latest: Optional[str] + recommended: Optional[str] + versions: List[str] = Field([]) + + +class DerivedForgeIndex(MetaBase): + versions: Dict[str, ForgeEntry] = Field({}) + by_mc_version: Dict[str, ForgeMCVersionInfo] = Field({}, alias="by_mcversion") + + +class FMLLib( + MetaBase +): # old ugly stuff. Maybe merge this with Library or Library later + filename: str + checksum: str + ours: bool + + +class ForgeInstallerProfileInstallSection(MetaBase): + """ + "install": { + "profileName": "Forge", + "target":"Forge8.9.0.753", + "path":"net.minecraftforge:minecraftforge:8.9.0.753", + "version":"Forge 8.9.0.753", + "filePath":"minecraftforge-universal-1.6.1-8.9.0.753.jar", + "welcome":"Welcome to the simple Forge installer.", + "minecraft":"1.6.1", + "logo":"/big_logo.png", + "mirrorList": "http://files.minecraftforge.net/mirror-brand.list" + }, + "install": { + "profileName": "forge", + "target":"1.11-forge1.11-13.19.0.2141", + "path":"net.minecraftforge:forge:1.11-13.19.0.2141", + "version":"forge 1.11-13.19.0.2141", + "filePath":"forge-1.11-13.19.0.2141-universal.jar", + "welcome":"Welcome to the simple forge installer.", + "minecraft":"1.11", + "mirrorList" : "http://files.minecraftforge.net/mirror-brand.list", + "logo":"/big_logo.png", + "modList":"none" + }, + """ + + profile_name: str = Field(alias="profileName") + target: str + path: GradleSpecifier + version: str + file_path: str = Field(alias="filePath") + welcome: str + minecraft: str + logo: str + mirror_list: str = Field(alias="mirrorList") + mod_list: Optional[str] = Field(alias="modList") + + +class ForgeLibrary(Library): + url: Optional[str] + server_req: Optional[bool] = Field(alias="serverreq") + client_req: Optional[bool] = Field(alias="clientreq") + checksums: Optional[List[str]] + comment: Optional[str] + + +class ForgeVersionFile(MojangVersion): + libraries: Optional[List[ForgeLibrary]] # overrides Mojang libraries + inherits_from: Optional[str] = Field("inheritsFrom") + jar: Optional[str] + + +class ForgeOptional(MetaBase): + """ + "optionals": [ + { + "name": "Mercurius", + "client": true, + "server": true, + "default": true, + "inject": true, + "desc": "A mod that collects statistics about Minecraft and your system.<br>Useful for Forge to understand how Minecraft/Forge are used.", + "url": "http://www.minecraftforge.net/forum/index.php?topic=43278.0", + "artifact": "net.minecraftforge:MercuriusUpdater:1.11.2", + "maven": "http://maven.minecraftforge.net/" + } + ] + """ + + name: Optional[str] + client: Optional[bool] + server: Optional[bool] + default: Optional[bool] + inject: Optional[bool] + desc: Optional[str] + url: Optional[str] + artifact: Optional[GradleSpecifier] + maven: Optional[str] + + +class ForgeInstallerProfile(MetaBase): + install: ForgeInstallerProfileInstallSection + version_info: ForgeVersionFile = Field(alias="versionInfo") + optionals: Optional[List[ForgeOptional]] + + +class ForgeLegacyInfo(MetaBase): + release_time: Optional[datetime] = Field(alias="releaseTime") + size: Optional[int] + sha256: Optional[str] + sha1: Optional[str] + + +class ForgeLegacyInfoList(MetaBase): + number: Dict[str, ForgeLegacyInfo] = Field({}) + + +class DataSpec(MetaBase): + client: Optional[str] + server: Optional[str] + + +class ProcessorSpec(MetaBase): + jar: Optional[str] + classpath: Optional[List[str]] + args: Optional[List[str]] + outputs: Optional[Dict[str, str]] + sides: Optional[List[str]] + + +class ForgeInstallerProfileV2(MetaBase): + _comment: Optional[List[str]] + spec: Optional[int] + profile: Optional[str] + version: Optional[str] + icon: Optional[str] + json_data: Optional[str] = Field(alias="json") + path: Optional[GradleSpecifier] + logo: Optional[str] + minecraft: Optional[str] + welcome: Optional[str] + data: Optional[Dict[str, DataSpec]] + processors: Optional[List[ProcessorSpec]] + libraries: Optional[List[Library]] + mirror_list: Optional[str] = Field(alias="mirrorList") + server_jar_path: Optional[str] = Field(alias="serverJarPath") + + +class InstallerInfo(MetaBase): + sha1hash: Optional[str] + sha256hash: Optional[str] + size: Optional[int] + + +# A post-processed entry constructed from the reconstructed Forge version index +class ForgeVersion: + def __init__(self, entry: ForgeEntry): + self.build = entry.build + self.rawVersion = entry.version + self.mc_version = entry.mc_version + self.mc_version_sane = self.mc_version.replace("_pre", "-pre", 1) + self.branch = entry.branch + self.installer_filename = None + self.installer_url = None + self.universal_filename = None + self.universal_url = None + self.changelog_url = None + self.long_version = "%s-%s" % (self.mc_version, self.rawVersion) + if self.branch is not None: + self.long_version += "-%s" % self.branch + + # this comment's whole purpose is to say this: cringe + for classifier, file in entry.files.items(): + extension = file.extension + filename = file.filename(self.long_version) + url = file.url(self.long_version) + if (classifier == "installer") and (extension == "jar"): + self.installer_filename = filename + self.installer_url = url + if (classifier == "universal" or classifier == "client") and ( + extension == "jar" or extension == "zip" + ): + self.universal_filename = filename + self.universal_url = url + if (classifier == "changelog") and (extension == "txt"): + self.changelog_url = url + + def name(self): + return "Forge %d" % self.build + + def uses_installer(self): + if self.installer_url is None: + return False + if self.mc_version == "1.5.2": + return False + return True + + def filename(self): + if self.uses_installer(): + return self.installer_filename + return self.universal_filename + + def url(self): + if self.uses_installer(): + return self.installer_url + return self.universal_url + + def is_supported(self): + if self.url() is None: + return False + + foo = self.rawVersion.split(".") + if len(foo) < 1: + return False + + major_version = foo[0] + if not major_version.isnumeric(): + return False + + # majorVersion = int(majorVersionStr) + # if majorVersion >= 37: + # return False + + return True + + +def fml_libs_for_version(mc_version: str) -> List[FMLLib]: + argo_2_25 = FMLLib( + filename="argo-2.25.jar", + checksum="bb672829fde76cb163004752b86b0484bd0a7f4b", + ours=False, + ) + argo_small_3_2 = FMLLib( + filename="argo-small-3.2.jar", + checksum="58912ea2858d168c50781f956fa5b59f0f7c6b51", + ours=False, + ) + guava_12_0_1 = FMLLib( + filename="guava-12.0.1.jar", + checksum="b8e78b9af7bf45900e14c6f958486b6ca682195f", + ours=False, + ) + guava_14_0_rc3 = FMLLib( + filename="guava-14.0-rc3.jar", + checksum="931ae21fa8014c3ce686aaa621eae565fefb1a6a", + ours=False, + ) + asm_all_4_0 = FMLLib( + filename="asm-all-4.0.jar", + checksum="98308890597acb64047f7e896638e0d98753ae82", + ours=False, + ) + asm_all_4_1 = FMLLib( + filename="asm-all-4.1.jar", + checksum="054986e962b88d8660ae4566475658469595ef58", + ours=False, + ) + bcprov_jdk15on_147 = FMLLib( + filename="bcprov-jdk15on-147.jar", + checksum="b6f5d9926b0afbde9f4dbe3db88c5247be7794bb", + ours=False, + ) + bcprov_jdk15on_148 = FMLLib( + filename="bcprov-jdk15on-148.jar", + checksum="960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", + ours=True, + ) + scala_library = FMLLib( + filename="scala-library.jar", + checksum="458d046151ad179c85429ed7420ffb1eaf6ddf85", + ours=True, + ) + + deobfuscation_data_1_5 = FMLLib( + filename="deobfuscation_data_1.5.zip", + checksum="5f7c142d53776f16304c0bbe10542014abad6af8", + ours=False, + ) + + deobfuscation_data_1_5_1 = FMLLib( + filename="deobfuscation_data_1.5.1.zip", + checksum="22e221a0d89516c1f721d6cab056a7e37471d0a6", + ours=False, + ) + deobfuscation_data_1_5_2 = FMLLib( + filename="deobfuscation_data_1.5.2.zip", + checksum="446e55cd986582c70fcf12cb27bc00114c5adfd9", + ours=False, + ) + if mc_version == "1.3.2": + return [argo_2_25, guava_12_0_1, asm_all_4_0] + elif mc_version in [ + "1.4", + "1.4.1", + "1.4.2", + "1.4.3", + "1.4.4", + "1.4.5", + "1.4.6", + "1.4.7", + ]: + return [argo_2_25, guava_12_0_1, asm_all_4_0, bcprov_jdk15on_147] + elif mc_version == "1.5": + return [ + argo_small_3_2, + guava_14_0_rc3, + asm_all_4_1, + bcprov_jdk15on_148, + deobfuscation_data_1_5, + scala_library, + ] + elif mc_version == "1.5.1": + return [ + argo_small_3_2, + guava_14_0_rc3, + asm_all_4_1, + bcprov_jdk15on_148, + deobfuscation_data_1_5_1, + scala_library, + ] + elif mc_version == "1.5.2": + return [ + argo_small_3_2, + guava_14_0_rc3, + asm_all_4_1, + bcprov_jdk15on_148, + deobfuscation_data_1_5_2, + scala_library, + ] + return [] diff --git a/meta/meta/model/index.py b/meta/meta/model/index.py new file mode 100644 index 0000000000..c6d82e1aff --- /dev/null +++ b/meta/meta/model/index.py @@ -0,0 +1,46 @@ +from datetime import datetime +from typing import Optional, List + +from pydantic import Field + +from meta.model import Dependency, MetaBase, Versioned, MetaVersion + + +class MetaVersionIndexEntry(MetaBase): + version: str + type: Optional[str] + release_time: datetime = Field(alias="releaseTime") + requires: Optional[List[Dependency]] + conflicts: Optional[List[Dependency]] + recommended: Optional[bool] + volatile: Optional[bool] + sha256: str + + @classmethod + def from_meta_version(cls, v: MetaVersion, recommended: bool, sha256: str): + return cls( + version=v.version, + type=v.type, + release_time=v.release_time, + requires=v.requires, + conflicts=v.conflicts, + recommended=recommended, + volatile=v.volatile, + sha256=sha256, + ) + + +class MetaVersionIndex(Versioned): + name: str + uid: str + versions: List[MetaVersionIndexEntry] = Field([]) + + +class MetaPackageIndexEntry(MetaBase): + name: str + uid: str + sha256: str + + +class MetaPackageIndex(Versioned): + packages: List[MetaPackageIndexEntry] = Field([]) diff --git a/meta/meta/model/java.py b/meta/meta/model/java.py new file mode 100644 index 0000000000..c3efde9292 --- /dev/null +++ b/meta/meta/model/java.py @@ -0,0 +1,597 @@ +from . import ( + MetaBase, + MetaVersion, + Versioned, +) +from pydantic import Field +from datetime import datetime +from enum import IntEnum, Enum +from .enum import StrEnum +from typing import Optional, Any, NamedTuple, Generator +from urllib.parse import urlencode, urlparse, urlunparse +from functools import total_ordering + +# namedtuple to match the internal signature of urlunparse + + +class JavaRuntimeOS(StrEnum): + MacOsX64 = "mac-os-x64" + MacOsX86 = "mac-os-x86" # rare + MacOsArm64 = "mac-os-arm64" + # MacOsArm32 = "mac-os-arm32" # doesn't exist + LinuxX64 = "linux-x64" + LinuxX86 = "linux-x86" + LinuxArm64 = "linux-arm64" + LinuxArm32 = "linux-arm32" + LinuxRiscv64 = "linux-riscv64" + WindowsX64 = "windows-x64" + WindowsX86 = "windows-x86" + WindowsArm64 = "windows-arm64" + WindowsArm32 = "windows-arm32" + Unknown = "unknown" + + +class JavaRuntimeDownloadType(StrEnum): + Manifest = "manifest" + Archive = "archive" + + +@total_ordering +class JavaVersionMeta(MetaBase): + major: int + minor: int + security: int + build: Optional[int] = None + buildstr: Optional[str] = None + name: Optional[str] = None + + def __str__(self): + ver = f"{self.major}.{self.minor}.{self.security}" + if self.build is not None: + ver = f"{ver}+{self.build}" + if self.buildstr is not None: + ver = f"{ver}-{self.buildstr}" + return ver + + def to_tuple(self): + build = 0 + if self.build is not None: + build = self.build + return (self.major, self.minor, self.security, build, self.buildstr) + + def __eq__(self, other: Any): + return self.to_tuple() == other.to_tuple() + + def __lt__(self, other: "JavaVersionMeta"): + return self.to_tuple() < other.to_tuple() + + +class JavaChecksumType(StrEnum): + Sha1 = "sha1" + Sha256 = "sha256" + + +class JavaChecksumMeta(MetaBase): + type: JavaChecksumType + hash: str + + +class JavaPackageType(StrEnum): + Jre = "jre" + Jdk = "jdk" + + +class JavaRuntimeMeta(MetaBase): + name: str + vendor: str + url: str + release_time: datetime = Field(alias="releaseTime") + checksum: Optional[JavaChecksumMeta] + download_type: JavaRuntimeDownloadType = Field(alias="downloadType") + package_type: JavaPackageType = Field(alias="packageType") + version: JavaVersionMeta + runtime_os: JavaRuntimeOS = Field(alias="runtimeOS") + + +class JavaRuntimeVersion(MetaVersion): + runtimes: list[JavaRuntimeMeta] + + +class URLComponents(NamedTuple): + scheme: str + netloc: str + url: str + path: str + query: str + fragment: str + + +class APIQuery(MetaBase): + def to_query(self): + set_parts: dict[str, Any] = {} + for key, value in self.dict().items(): + if value is not None: + if isinstance(value, Enum): + set_parts[key] = value.value + elif isinstance(value, list): + if len(value) > 0: # type: ignore + set_parts[key] = value + elif isinstance(value, datetime): + set_parts[key] = value.isoformat() + else: + set_parts[key] = value + return urlencode(set_parts, doseq=True) + + +# Adoptx refers to both Adoptium (Eclipse Temurin) and AdoptOpenJDK (IBM Semeru Runtime Open Edition) +class AdoptxJvmImpl(StrEnum): + Hotspot = "hotspot" + OpenJ9 = "openj9" + + +class AdoptxVendor(StrEnum): + Eclipse = "eclipse" + Ibm = "ibm" + + +class AdoptxArchitecture(StrEnum): + X64 = "x64" + X86 = "x86" + X32 = "x32" + Ppc64 = "ppc64" + Ppc64le = "ppc64le" + S390x = "s390x" + Aarch64 = "aarch64" + Arm = "arm" + Sparcv9 = "sparcv9" + Riscv64 = "riscv64" + + +class AdoptxReleaseType(StrEnum): + GeneralAccess = "ga" + EarlyAccess = "ea" + + +class AdoptxSortMethod(StrEnum): + Default = "DEFAULT" + Date = "DATE" + + +class AdoptxSortOrder(StrEnum): + Asc = "ASC" + Desc = "DESC" + + +class AdoptxImageType(StrEnum): + Jdk = "jdk" + Jre = "jre" + Testimage = "testimage" + Debugimage = "debugimage" + Staticlibs = "staticlibs" + Sources = "sources" + Sbom = "sbom" + + +class AdoptxHeapSize(StrEnum): + Normal = "normal" + Large = "large" + + +class AdoptxProject(StrEnum): + Jdk = "jdk" + Valhalla = "valhalla" + Metropolis = "metropolis" + Jfr = "jfr" + Shenandoah = "shenandoah" + + +class AdoptxCLib(StrEnum): + Musl = "musl" + Glibc = "glibc" + + +class AdoptxOs(StrEnum): + Linux = "linux" + Windows = "windows" + Mac = "mac" + Solaris = "solaris" + Aix = "aix" + AlpineLinux = "alpine-linux" + + +ADOPTIUM_API_BASE = "https://api.adoptium.net" +OPENJ9_API_BASE = " https://api.adoptopenjdk.net" +ADOPTX_API_FEATURE_RELEASES = ( + f"{{base_url}}/v3/assets/feature_releases/{{feature_version}}/{{release_type}}" +) +# ?image_type={{image_type}}&heap_size={{heap_size}}&project={{project}}&vendor={{vendor}}&page_size={{page_size}}&page={{page}}&sort_method={{sort_method}}&sort_order={{sort_order}} +ADOPTX_API_AVAILABLE_RELEASES = f"{{base_url}}/v3/info/available_releases" + + +class AdoptxAPIFeatureReleasesQuery(APIQuery): + architecture: Optional[AdoptxArchitecture] = None + before: Optional[datetime] = None + c_lib: Optional[AdoptxCLib] = None + heap_size: Optional[AdoptxHeapSize] = AdoptxHeapSize.Normal + image_type: Optional[AdoptxImageType] = None + jvm_impl: Optional[AdoptxJvmImpl] = None + os: Optional[AdoptxOs] = None + vendor: Optional[AdoptxVendor] = None + page_size: int = 10 + page: int = 0 + project: Optional[AdoptxProject] = AdoptxProject.Jdk + sort_method: Optional[AdoptxSortMethod] = AdoptxSortMethod.Default + sort_order: Optional[AdoptxSortOrder] = AdoptxSortOrder.Desc + + +def adoptxAPIFeatureReleasesUrl( + base_url: str, + feature_version: int, + release_type: AdoptxReleaseType = AdoptxReleaseType.GeneralAccess, + query: AdoptxAPIFeatureReleasesQuery = AdoptxAPIFeatureReleasesQuery(), +): + url = urlparse( + ADOPTX_API_FEATURE_RELEASES.format( + base_url=base_url, + feature_version=feature_version, + release_type=release_type.value, + ) + ) + return urlunparse(url._replace(query=query.to_query())) + + +def adoptiumAPIFeatureReleasesUrl( + feature_version: int, + release_type: AdoptxReleaseType = AdoptxReleaseType.GeneralAccess, + query: AdoptxAPIFeatureReleasesQuery = AdoptxAPIFeatureReleasesQuery(), +): + return adoptxAPIFeatureReleasesUrl( + feature_version=feature_version, + release_type=release_type, + query=query, + base_url=ADOPTIUM_API_BASE, + ) + + +def openj9APIFeatureReleasesUrl( + feature_version: int, + release_type: AdoptxReleaseType = AdoptxReleaseType.GeneralAccess, + query: AdoptxAPIFeatureReleasesQuery = AdoptxAPIFeatureReleasesQuery(), +): + return adoptxAPIFeatureReleasesUrl( + feature_version=feature_version, + release_type=release_type, + query=query, + base_url=OPENJ9_API_BASE, + ) + + +class AdoptxAvailableReleases(MetaBase): + available_releases: list[int] + available_lts_releases: list[int] + most_recent_lts: Optional[int] + most_recent_feature_release: Optional[int] + most_recent_feature_version: Optional[int] + tip_version: Optional[int] + + +class AdoptxFile(MetaBase): + name: str + link: str + size: Optional[int] + + +class AdoptxPackage(AdoptxFile): + checksum: Optional[str] + checksum_link: Optional[str] + signature_link: Optional[str] + metadata_link: Optional[str] + # we intentionally omit download_count + + +class AdoptxBinary(MetaBase): + os: str + architecture: AdoptxArchitecture + image_type: AdoptxImageType + c_lib: Optional[AdoptxCLib] + jvm_impl: AdoptxJvmImpl + package: Optional[AdoptxPackage] + installer: Optional[AdoptxPackage] + heap_size: AdoptxHeapSize + updated_at: datetime + scm_ref: Optional[str] + project: AdoptxProject + # we intentionally omit download_count + + +class AdoptxVersion(MetaBase): + major: Optional[int] + minor: Optional[int] + security: Optional[int] + patch: Optional[int] + pre: Optional[str] + adopt_build_number: Optional[int] + semver: str + openjdk_version: str + build: Optional[int] + optional: Optional[str] + + +class AdoptxRelease(MetaBase): + release_id: str = Field(alias="id") + release_link: str + release_name: str + timestamp: datetime + updated_at: datetime + binaries: list[AdoptxBinary] + release_type: str + vendor: AdoptxVendor + version_data: AdoptxVersion + source: Optional[AdoptxFile] + release_notes: Optional[AdoptxFile] + # we intentionally omit download_count + + +class AdoptxReleases(MetaBase): + __root__: list[AdoptxRelease] + + def __iter__(self) -> Generator[tuple[str, AdoptxRelease], None, None]: + yield from ((str(i), val) for i, val in enumerate(self.__root__)) + + def __getitem__(self, item: int) -> AdoptxRelease: + return self.__root__[item] + + def append(self, rls: AdoptxRelease): + self.__root__.append(rls) + + +class AzulProduct(StrEnum): + Zulu = "zulu" + + +class AzulAvailabilityType(StrEnum): + SA = "SA" + CA = "CA" + NV = "NV" + _LA = "LA" + + +class AzulJavaPackageType(StrEnum): + Jdk = "jdk" + Jre = "jre" + + +class AzulReleaseType(StrEnum): + CPU = "CPU" + PSU = "PSU" + LU = "LU" + + +class AzulOs(StrEnum): + Linux = "linux" + Macos = "macos" + Qnx = "qnx" + Windows = "windows" + Solaris = "solaris" + + +class AzulLibCType(StrEnum): + Glibc = "glibc" + Uclibc = "uclibc" + Musl = "musl" + + +class AzulCPUGen(StrEnum): + V5 = "v5" + V6kV6kz = "v6k_v6kz" + V6t2 = "v6t2" + V7 = "v7" + V8 = "v8" + + +class AzulArch(StrEnum): + Arm = "arm" + X86 = "x86" + Mips = "mips" + Ppc = "ppc" + Sparcv9 = "sparcv9" + Sparc = "sparc" + + +class AzulHwBitness(IntEnum): + X32 = 32 + X64 = 64 + + +class AzulAbi(StrEnum): + HardFloat = "hard_float" + SoftFloat = "soft_float" + Spe = "spe" + Any = "any" + + +class AzulArchiveType(StrEnum): + Deb = "deb" + Rpm = "rpm" + Dmg = "dmg" + Targz = "tar.gz" + Zip = "zip" + Cab = "cab" + Msi = "msi" + + +class AzulReleaseStatus(StrEnum): + Eval = "eval" + Ea = "ea" + Ga = "ga" + Both = "both" + + +class AzulSupportTerm(StrEnum): + Sts = "sts" + Mts = "mts" + Lts = "lts" + + +class AzulCertifications(StrEnum): + Tck = "tck" + _Aqavit = "aqavit" + none = "none" + + +class AzulSignatureType(StrEnum): + Openpgp = "openpgp" + + +class AzulOsQueryParam(StrEnum): + Macos = "macos" + Windows = "windows" + Linux = "linux" + LinuxMusl = "linux-musl" + LinuxGlibc = "linux-glibc" + Qnx = "qnx" + Solaris = "solaris" + + +class AzulArchQueryParam(StrEnum): + X86 = "x86" + X64 = "x64" + Amd64 = "amd64" + I686 = "i686" + Arm = "arm" + Aarch64 = "aarch64" + Aarch32 = "aarch32" + Aarch32sf = "aarch32sf" + Aarch32hf = "aarch32hf" + Ppc = "ppc" + Ppc64 = "ppc64" + Ppc64hf = "ppc64hf" + Ppc32 = "ppc32" + Ppc32spe = "ppc32spe" + Ppc32hf = "ppc32hf" + Sparc = "sparc" + Sparc32 = "sparc32" + Sparcv9 = "sparcv9" + Sparcv9_64 = "sparcv9-64" + + +AZUL_API_BASE = "https://api.azul.com/metadata/v1" +AZUL_API_PACKAGES = f"{AZUL_API_BASE}/zulu/packages/" +AZUL_API_PACKAGE_DETAIL = f"{AZUL_API_BASE}/zulu/packages/{{package_uuid}}" + + +class AzulApiPackagesQuery(APIQuery): + java_version: Optional[str] = None + os: Optional[AzulOsQueryParam] = None + arch: Optional[AzulArchQueryParam] = None + archive_type: Optional[AzulArchiveType] = None + java_package_type: Optional[AzulJavaPackageType] = None + javafx_bundled: Optional[bool] = None + crac_supported: Optional[bool] = None + support_term: Optional[AzulSupportTerm] = None + release_type: Optional[AzulReleaseType] = None + latest: Optional[bool] = None + distro_version: Optional[str] = None + java_package_features: list[str] = [] + release_status: Optional[AzulReleaseStatus] = None + availability_types: list[AzulAvailabilityType] = [] + certifications: list[AzulCertifications] = [] + include_fields: list[str] = [] + page: int = 0 + page_size: int = 100 + + +def azulApiPackagesUrl(query: AzulApiPackagesQuery = AzulApiPackagesQuery()): + url = urlparse(AZUL_API_PACKAGES) + return urlunparse(url._replace(query=query.to_query())) + + +def azulApiPackageDetailUrl(package_uuid: str): + return AZUL_API_PACKAGE_DETAIL.format(package_uuid=package_uuid) + + +class ZuluSignatureDetail(MetaBase): + type: AzulSignatureType + url: str + details: dict[str, Any] + signature_index: int + signature: str + + +class ZuluPackageDetail(MetaBase): + package_uuid: str + name: Optional[str] + md5_hash: Optional[str] + sha256_hash: Optional[str] + build_date: datetime + last_modified: datetime + download_url: str + product: AzulProduct + availability_type: AzulAvailabilityType + java_version: list[int] + openjdk_build_number: Optional[int] + java_package_type: AzulJavaPackageType + javafx_bundled: bool + release_type: AzulReleaseType + os: AzulOs + lib_c_type: Optional[AzulLibCType] + cpu_gen: Optional[list[AzulCPUGen]] + arch: AzulArch + hw_bitness: AzulHwBitness + abi: AzulAbi + archive_type: AzulArchiveType + release_status: AzulReleaseStatus + support_term: AzulSupportTerm + certifications: Optional[list[AzulCertifications]] + latest: Optional[bool] + size: int + distro_version: list[int] + signatures: list[ZuluSignatureDetail] + + +class ZuluPackage(MetaBase): + package_uuid: str + name: Optional[str] + java_version: list[int] + openjdk_build_number: Optional[int] + latest: Optional[bool] + download_url: str + product: Optional[AzulProduct] + distro_version: list[int] + availability_type: Optional[AzulAvailabilityType] + + +class ZuluPackageList(MetaBase): + __root__: list[ZuluPackage] + + def __iter__(self) -> Generator[tuple[str, ZuluPackage], None, None]: + yield from ((str(i), val) for i, val in enumerate(self.__root__)) + + def __getitem__(self, item: int) -> ZuluPackage: + return self.__root__[item] + + def append(self, pkg: ZuluPackage): + self.__root__.append(pkg) + + +class ZuluPackagesDetail(MetaBase): + __root__: list[ZuluPackageDetail] + + def __iter__(self) -> Generator[tuple[str, ZuluPackageDetail], None, None]: + yield from ((str(i), val) for i, val in enumerate(self.__root__)) + + def __getitem__(self, item: int) -> ZuluPackageDetail: + return self.__root__[item] + + def append(self, pkg: ZuluPackageDetail): + self.__root__.append(pkg) + + +MOJANG_OS_NAMES = ["mac-os", "linux", "windows"] + +MOJANG_OS_ARCHITECTURES = [ + "x64", + "x86", + "arm64", + "arm32", +] diff --git a/meta/meta/model/liteloader.py b/meta/meta/model/liteloader.py new file mode 100644 index 0000000000..64cdaadd7e --- /dev/null +++ b/meta/meta/model/liteloader.py @@ -0,0 +1,112 @@ +from datetime import datetime +from typing import Optional, List, Dict, Any + +from pydantic import Field + +from . import Library, MetaBase + + +class LiteloaderDev(MetaBase): + fgVersion: Optional[str] + mappings: Optional[str] + mcp: Optional[str] + + +class LiteloaderRepo(MetaBase): + """ + "repo":{ + "stream":"RELEASE", + "type":"m2", + "url":"http://dl.liteloader.com/repo/", + "classifier":"" + }, + """ + + stream: str + type: str + url: str + classifier: str + + +class LiteloaderArtefact(MetaBase): + """ + "53639d52340479ccf206a04f5e16606f":{ + "tweakClass":"com.mumfrey.liteloader.launch.LiteLoaderTweaker", + "libraries":[ + { + "name":"net.minecraft:launchwrapper:1.5" + }, + { + "name":"net.sf.jopt-simple:jopt-simple:4.5" + }, + { + "name":"org.ow2.asm:asm-all:4.1" + } + ], + "stream":"RELEASE", + "file":"liteloader-1.5.2_01.jar", + "version":"1.5.2_01", + "md5":"53639d52340479ccf206a04f5e16606f", + "timestamp":"1367366420" + }, + """ + + tweakClass: str + libraries: List[Library] + stream: str + file: str + version: str + build: Optional[str] + md5: str + timestamp: str + srcJar: Optional[str] + mcpJar: Optional[str] + lastSuccessfulBuild: Optional[int] # only for snapshots + + +class LiteloaderArtefacts(MetaBase): + liteloader: Dict[str, LiteloaderArtefact] = Field(alias="com.mumfrey:liteloader") + libraries: Optional[List[Library]] + + +class LiteloaderEntry(MetaBase): + """ + "1.10.2":{ + "dev": { ... }, + "repo":{ ... }, + "artefacts":{ + "com.mumfrey:liteloader":{ }, + ... + }, + "snapshots":{ + ... + } + """ + + dev: Optional[LiteloaderDev] + repo: LiteloaderRepo + artefacts: Optional[LiteloaderArtefacts] + snapshots: Optional[LiteloaderArtefacts] + + +class LiteloaderMeta(MetaBase): + """ + "meta":{ + "description":"LiteLoader is a lightweight mod bootstrap designed to provide basic loader functionality for mods which don't need to modify game mechanics.", + "authors":"Mumfrey", + "url":"http://dl.liteloader.com", + "updated":"2017-02-22T11:34:07+00:00", + "updatedTime":1487763247 + }, + """ + + description: str + authors: str + url: str + updated: datetime + updated_time: int = Field(alias="updatedTime") + + +class LiteloaderIndex(MetaBase): + meta: LiteloaderMeta + versions: Dict[Any, LiteloaderEntry] diff --git a/meta/meta/model/mojang.py b/meta/meta/model/mojang.py new file mode 100644 index 0000000000..b3edfe21f9 --- /dev/null +++ b/meta/meta/model/mojang.py @@ -0,0 +1,344 @@ +from datetime import datetime +from typing import Optional, List, Dict, Any, Iterator +from .enum import StrEnum + +from pydantic import validator, Field + +from . import ( + MetaBase, + MojangArtifactBase, + MojangAssets, + MojangArtifact, + MojangLibraryDownloads, + MojangLogging, + Library, + MetaVersion, + GradleSpecifier, +) + +SUPPORTED_LAUNCHER_VERSION = 21 +SUPPORTED_COMPLIANCE_LEVEL = 1 +DEFAULT_JAVA_MAJOR = 8 # By default, we should recommend Java 8 if we don't know better +DEFAULT_JAVA_NAME = ( + "jre-legacy" # By default, we should recommend Java 8 if we don't know better +) +COMPATIBLE_JAVA_MAPPINGS = {16: [17]} +SUPPORTED_FEATURES = ["is_quick_play_multiplayer", "is_quick_play_singleplayer"] + +""" +Mojang index files look like this: +{ + "latest": { + "release": "1.11.2", + "snapshot": "17w06a" + }, + "versions": [ + ... + { + "id": "17w06a", + "releaseTime": "2017-02-08T13:16:29+00:00", + "time": "2017-02-08T13:17:20+00:00", + "type": "snapshot", + "url": "https://launchermeta.mojang.com/mc/game/7db0c61afa278d016cf1dae2fba0146edfbf2f8e/17w06a.json" + }, + ... + ] +} +""" + + +class MojangLatestVersion(MetaBase): + release: str + snapshot: str + + +class MojangIndexEntry(MetaBase): + id: Optional[str] + release_time: Optional[datetime] = Field(alias="releaseTime") + time: Optional[datetime] + type: Optional[str] + url: Optional[str] + sha1: Optional[str] + compliance_level: Optional[int] = Field(alias="complianceLevel") + + +class MojangIndex(MetaBase): + latest: MojangLatestVersion + versions: List[MojangIndexEntry] + + +class MojangIndexWrap: + def __init__(self, index: MojangIndex): + self.index = index + self.latest = index.latest + self.versions = dict((x.id, x) for x in index.versions) + + +class ExperimentEntry(MetaBase): + id: str + url: str + wiki: Optional[str] + + +class ExperimentIndex(MetaBase): + experiments: List[ExperimentEntry] + + +class ExperimentIndexWrap: + def __init__(self, index: ExperimentIndex): + self.index: ExperimentIndex = index + self.versions: Dict[str, ExperimentEntry] = dict( + (x.id, x) for x in index.experiments + ) + + +class OldSnapshotEntry(MetaBase): + id: str + url: str + wiki: Optional[str] + jar: str + sha1: str + size: int + + +class OldSnapshotIndex(MetaBase): + old_snapshots: List[OldSnapshotEntry] + + +class OldSnapshotIndexWrap: + def __init__(self, index: OldSnapshotIndex): + self.index: OldSnapshotIndex = index + self.versions: Dict[str, OldSnapshotEntry] = dict( + (x.id, x) for x in index.old_snapshots + ) + + +class LegacyOverrideEntry(MetaBase): + main_class: Optional[str] = Field(alias="mainClass") + applet_class: Optional[str] = Field(alias="appletClass") + release_time: Optional[datetime] = Field(alias="releaseTime") + additional_traits: Optional[List[str]] = Field(alias="+traits") + additional_jvm_args: Optional[List[str]] = Field(alias="+jvmArgs") + + def apply_onto_meta_version(self, meta_version: MetaVersion, legacy: bool = True): + # simply hard override classes + meta_version.main_class = self.main_class + meta_version.applet_class = self.applet_class + # if we have an updated release time (more correct than Mojang), use it + if self.release_time: + meta_version.release_time = self.release_time + + # add traits, if any + if self.additional_traits: + if not meta_version.additional_traits: + meta_version.additional_traits = [] + meta_version.additional_traits += self.additional_traits + + if self.additional_jvm_args: + if not meta_version.additional_jvm_args: + meta_version.additional_jvm_args = [] + meta_version.additional_jvm_args += self.additional_jvm_args + + if legacy: + # remove all libraries - they are not needed for legacy + meta_version.libraries = None + + +class LegacyOverrideIndex(MetaBase): + versions: Dict[str, LegacyOverrideEntry] + + +class LibraryPatch(MetaBase): + match: List[GradleSpecifier] + override: Optional[Library] + additionalLibraries: Optional[List[Library]] + patchAdditionalLibraries: bool = Field(False) + + def applies(self, target: Library) -> bool: + return target.name in self.match + + +class LibraryPatches(MetaBase): + __root__: List[LibraryPatch] + + def __iter__(self) -> Iterator[LibraryPatch]: + return iter(self.__root__) + + def __getitem__(self, item) -> LibraryPatch: + return self.__root__[item] + + +class LegacyServices(MetaBase): + __root__: List[str] + + def __iter__(self) -> Iterator[str]: + return iter(self.__root__) + + def __getitem__(self, item) -> str: + return self.__root__[item] + + +class MojangArguments(MetaBase): + game: Optional[List[Any]] # mixture of strings and objects + jvm: Optional[List[Any]] + + +class MojangJavaComponent(StrEnum): + JreLegacy = "jre-legacy" + Alpha = "java-runtime-alpha" + Beta = "java-runtime-beta" + Gamma = "java-runtime-gamma" + GammaSnapshot = "java-runtime-gamma-snapshot" + Exe = "minecraft-java-exe" + Delta = "java-runtime-delta" + Epsilon = "java-runtime-epsilon" + + +class JavaVersion(MetaBase): + component: MojangJavaComponent = MojangJavaComponent.JreLegacy + major_version: int = Field(8, alias="majorVersion") + + +class MojangJavaIndexAvailability(MetaBase): + group: int + progress: int + + +class MojangJavaIndexManifest(MetaBase): + sha1: str + size: int + url: str + + +class MojangJavaIndexVersion(MetaBase): + name: str + released: datetime + + +class MojangJavaRuntime(MetaBase): + availability: MojangJavaIndexAvailability + manifest: MojangJavaIndexManifest + version: MojangJavaIndexVersion + + +class MojangJavaIndexEntry(MetaBase): + __root__: dict[MojangJavaComponent, list[MojangJavaRuntime]] + + def __iter__(self) -> Iterator[MojangJavaComponent]: + return iter(self.__root__) + + def __getitem__(self, item) -> list[MojangJavaRuntime]: + return self.__root__[item] + + +class MojangJavaOsName(StrEnum): + Gamecore = "gamecore" + Linux = "linux" + Linuxi386 = "linux-i386" + MacOs = "mac-os" + MacOSArm64 = "mac-os-arm64" + WindowsArm64 = "windows-arm64" + WindowsX64 = "windows-x64" + WindowsX86 = "windows-x86" + + +class JavaIndex(MetaBase): + __root__: dict[MojangJavaOsName, MojangJavaIndexEntry] + + def __iter__(self) -> Iterator[MojangJavaOsName]: + return iter(self.__root__) + + def __getitem__(self, item) -> MojangJavaIndexEntry: + return self.__root__[item] + + +class MojangVersion(MetaBase): + @validator("minimum_launcher_version") + def validate_minimum_launcher_version(cls, v): + assert v <= SUPPORTED_LAUNCHER_VERSION + return v + + @validator("compliance_level") + def validate_compliance_level(cls, v): + assert v <= SUPPORTED_COMPLIANCE_LEVEL + return v + + id: str # TODO: optional? + arguments: Optional[MojangArguments] + asset_index: Optional[MojangAssets] = Field(alias="assetIndex") + assets: Optional[str] + downloads: Optional[Dict[str, MojangArtifactBase]] # TODO improve this? + libraries: Optional[List[Library]] # TODO: optional? + main_class: Optional[str] = Field(alias="mainClass") + applet_class: Optional[str] = Field(alias="appletClass") + processArguments: Optional[str] + minecraft_arguments: Optional[str] = Field(alias="minecraftArguments") + minimum_launcher_version: Optional[int] = Field(alias="minimumLauncherVersion") + release_time: Optional[datetime] = Field(alias="releaseTime") + time: Optional[datetime] + type: Optional[str] + inherits_from: Optional[str] = Field("inheritsFrom") + logging: Optional[Dict[str, MojangLogging]] # TODO improve this? + compliance_level: Optional[int] = Field(alias="complianceLevel") + javaVersion: Optional[JavaVersion] + + def to_meta_version(self, name: str, uid: str, version: str) -> MetaVersion: + main_jar = None + addn_traits = None + new_type = self.type + compatible_java_majors = None + if self.id: + client_download = self.downloads["client"] + artifact = MojangArtifact( + url=client_download.url, + sha1=client_download.sha1, + size=client_download.size, + ) + downloads = MojangLibraryDownloads(artifact=artifact) + main_jar = Library( + name=GradleSpecifier("com.mojang", "minecraft", self.id, "client"), + downloads=downloads, + ) + + if not self.compliance_level: # both == 0 and is None + pass + elif self.compliance_level == 1: + if not addn_traits: + addn_traits = [] + addn_traits.append("XR:Initial") + else: + raise Exception(f"Unsupported compliance level {self.compliance_level}") + + major = DEFAULT_JAVA_MAJOR + javaName = DEFAULT_JAVA_NAME + if ( + self.javaVersion is not None + ): # some versions don't have this. TODO: maybe maintain manual overrides + major = self.javaVersion.major_version + javaName = self.javaVersion.component + + compatible_java_majors = [major] + if ( + major in COMPATIBLE_JAVA_MAPPINGS + ): # add more compatible Java versions, e.g. 16 and 17 both work for MC 1.17 + compatible_java_majors += COMPATIBLE_JAVA_MAPPINGS[major] + + if new_type == "pending": # experiments from upstream are type=pending + new_type = "experiment" + + return MetaVersion( + name=name, + uid=uid, + version=version, + asset_index=self.asset_index, + libraries=self.libraries, + main_class=self.main_class, + minecraft_arguments=self.minecraft_arguments, + release_time=self.release_time, + type=new_type, + compatible_java_majors=compatible_java_majors, + compatible_java_name=javaName, + additional_traits=addn_traits, + main_jar=main_jar, + logging=(self.logging or {}).get("client"), + ) diff --git a/meta/meta/model/neoforge.py b/meta/meta/model/neoforge.py new file mode 100644 index 0000000000..ccdb325a23 --- /dev/null +++ b/meta/meta/model/neoforge.py @@ -0,0 +1,241 @@ +from datetime import datetime +from typing import Optional, List, Dict + +from pydantic import Field + +from . import MetaBase, GradleSpecifier, Library +from .mojang import MojangVersion + + +class NeoForgeFile(MetaBase): + artifact: str + classifier: str + extension: str + + def filename(self, long_version): + return "%s-%s-%s.%s" % ( + self.artifact, + long_version, + self.classifier, + self.extension, + ) + + def url(self, long_version): + return "https://maven.neoforged.net/releases/net/neoforged/%s/%s/%s" % ( + self.artifact, + long_version, + self.filename(long_version), + ) + + +class NeoForgeEntry(MetaBase): + artifact: str + long_version: str = Field(alias="longversion") + version: str + latest: Optional[bool] + recommended: Optional[bool] + files: Optional[Dict[str, NeoForgeFile]] + + +class NeoForgeMCVersionInfo(MetaBase): + latest: Optional[str] + recommended: Optional[str] + versions: List[str] = Field([]) + + +class DerivedNeoForgeIndex(MetaBase): + versions: Dict[str, NeoForgeEntry] = Field({}) + + +class FMLLib( + MetaBase +): # old ugly stuff. Maybe merge this with Library or Library later + filename: str + checksum: str + ours: bool + + +class NeoForgeInstallerProfileInstallSection(MetaBase): + """ + "install": { + "profileName": "NeoForge", + "target":"NeoForge8.9.0.753", + "path":"net.minecraftNeoForge:minecraftNeoForge:8.9.0.753", + "version":"NeoForge 8.9.0.753", + "filePath":"minecraftNeoForge-universal-1.6.1-8.9.0.753.jar", + "welcome":"Welcome to the simple NeoForge installer.", + "minecraft":"1.6.1", + "logo":"/big_logo.png", + "mirrorList": "http://files.minecraftNeoForge.net/mirror-brand.list" + }, + "install": { + "profileName": "NeoForge", + "target":"1.11-NeoForge1.11-13.19.0.2141", + "path":"net.minecraftNeoForge:NeoForge:1.11-13.19.0.2141", + "version":"NeoForge 1.11-13.19.0.2141", + "filePath":"NeoForge-1.11-13.19.0.2141-universal.jar", + "welcome":"Welcome to the simple NeoForge installer.", + "minecraft":"1.11", + "mirrorList" : "http://files.minecraftNeoForge.net/mirror-brand.list", + "logo":"/big_logo.png", + "modList":"none" + }, + """ + + profile_name: str = Field(alias="profileName") + target: str + path: GradleSpecifier + version: str + file_path: str = Field(alias="filePath") + welcome: str + minecraft: str + logo: str + mirror_list: str = Field(alias="mirrorList") + mod_list: Optional[str] = Field(alias="modList") + + +class NeoForgeLibrary(Library): + url: Optional[str] + server_req: Optional[bool] = Field(alias="serverreq") + client_req: Optional[bool] = Field(alias="clientreq") + checksums: Optional[List[str]] + comment: Optional[str] + + +class NeoForgeVersionFile(MojangVersion): + libraries: Optional[List[NeoForgeLibrary]] # overrides Mojang libraries + inherits_from: Optional[str] = Field("inheritsFrom") + jar: Optional[str] + + +class NeoForgeOptional(MetaBase): + """ + "optionals": [ + { + "name": "Mercurius", + "client": true, + "server": true, + "default": true, + "inject": true, + "desc": "A mod that collects statistics about Minecraft and your system.<br>Useful for NeoForge to understand how Minecraft/NeoForge are used.", + "url": "http://www.minecraftNeoForge.net/forum/index.php?topic=43278.0", + "artifact": "net.minecraftNeoForge:MercuriusUpdater:1.11.2", + "maven": "http://maven.minecraftNeoForge.net/" + } + ] + """ + + name: Optional[str] + client: Optional[bool] + server: Optional[bool] + default: Optional[bool] + inject: Optional[bool] + desc: Optional[str] + url: Optional[str] + artifact: Optional[GradleSpecifier] + maven: Optional[str] + + +class DataSpec(MetaBase): + client: Optional[str] + server: Optional[str] + + +class ProcessorSpec(MetaBase): + jar: Optional[str] + classpath: Optional[List[str]] + args: Optional[List[str]] + outputs: Optional[Dict[str, str]] + sides: Optional[List[str]] + + +class NeoForgeInstallerProfileV2(MetaBase): + _comment: Optional[List[str]] + spec: Optional[int] + profile: Optional[str] + version: Optional[str] + icon: Optional[str] + json_data: Optional[str] = Field(alias="json") + path: Optional[GradleSpecifier] + logo: Optional[str] + minecraft: Optional[str] + welcome: Optional[str] + data: Optional[Dict[str, DataSpec]] + processors: Optional[List[ProcessorSpec]] + libraries: Optional[List[Library]] + mirror_list: Optional[str] = Field(alias="mirrorList") + server_jar_path: Optional[str] = Field(alias="serverJarPath") + + +class InstallerInfo(MetaBase): + sha1hash: Optional[str] + sha256hash: Optional[str] + size: Optional[int] + + +# A post-processed entry constructed from the reconstructed NeoForge version index +class NeoForgeVersion: + def __init__(self, entry: NeoForgeEntry): + self.artifact = entry.artifact + self.rawVersion = entry.version + if self.artifact == "neoforge": + self.rawVersion = entry.long_version + + self.installer_filename = None + self.installer_url = None + self.universal_filename = None + self.universal_url = None + self.changelog_url = None + self.long_version = entry.long_version + + # this comment's whole purpose is to say this: cringe + for classifier, file in entry.files.items(): + extension = file.extension + filename = file.filename(self.long_version) + url = file.url(self.long_version) + print(url) + print(self.long_version) + if (classifier == "installer") and (extension == "jar"): + self.installer_filename = filename + self.installer_url = url + if (classifier == "universal" or classifier == "client") and ( + extension == "jar" or extension == "zip" + ): + self.universal_filename = filename + self.universal_url = url + if (classifier == "changelog") and (extension == "txt"): + self.changelog_url = url + + def name(self): + return "neoforge %d" % self.build + + def uses_installer(self): + return self.installer_url is not None + + def filename(self): + if self.uses_installer(): + return self.installer_filename + return self.universal_filename + + def url(self): + if self.uses_installer(): + return self.installer_url + return self.universal_url + + def is_supported(self): + if self.url() is None: + return False + + foo = self.rawVersion.split(".") + if len(foo) < 1: + return False + + major_version = foo[0] + if not major_version.isnumeric(): + return False + + # majorVersion = int(majorVersionStr) + # if majorVersion >= 37: + # return False + + return True diff --git a/meta/meta/run/__init__.py b/meta/meta/run/__init__.py new file mode 100644 index 0000000000..1bfe4f9ac8 --- /dev/null +++ b/meta/meta/run/__init__.py @@ -0,0 +1 @@ +"""Main scripts""" diff --git a/meta/meta/run/generate_fabric.py b/meta/meta/run/generate_fabric.py new file mode 100755 index 0000000000..7ca50dd6aa --- /dev/null +++ b/meta/meta/run/generate_fabric.py @@ -0,0 +1,143 @@ +import json +import os + +from meta.common import ( + ensure_component_dir, + launcher_path, + upstream_path, + transform_maven_key, +) +from meta.common.fabric import ( + JARS_DIR, + INSTALLER_INFO_DIR, + META_DIR, + INTERMEDIARY_COMPONENT, + LOADER_COMPONENT, +) +from meta.model import MetaVersion, Dependency, Library, MetaPackage, GradleSpecifier +from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses + +LAUNCHER_DIR = launcher_path() +UPSTREAM_DIR = upstream_path() + +ensure_component_dir(LOADER_COMPONENT) +ensure_component_dir(INTERMEDIARY_COMPONENT) + + +def load_jar_info(artifact_key) -> FabricJarInfo: + return FabricJarInfo.parse_file( + os.path.join(UPSTREAM_DIR, JARS_DIR, f"{artifact_key}.json") + ) + + +def load_installer_info(version) -> FabricInstallerDataV1: + return FabricInstallerDataV1.parse_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version}.json") + ) + + +def process_loader_version(entry) -> MetaVersion: + jar_info = load_jar_info(transform_maven_key(entry["maven"])) + installer_info = load_installer_info(entry["version"]) + + v = MetaVersion( + name="Fabric Loader", uid="net.fabricmc.fabric-loader", version=entry["version"] + ) + v.release_time = jar_info.release_time + v.requires = [Dependency(uid="net.fabricmc.intermediary")] + v.order = 10 + v.type = "release" + if isinstance(installer_info.main_class, FabricMainClasses): + v.main_class = installer_info.main_class.client + else: + v.main_class = installer_info.main_class + v.libraries = [] + v.libraries.extend(installer_info.libraries.common) + v.libraries.extend(installer_info.libraries.client) + loader_lib = Library( + name=GradleSpecifier.from_string(entry["maven"]), + url="https://maven.fabricmc.net", + ) + v.libraries.append(loader_lib) + return v + + +def process_intermediary_version(entry) -> MetaVersion: + jar_info = load_jar_info(transform_maven_key(entry["maven"])) + + v = MetaVersion( + name="Intermediary Mappings", + uid="net.fabricmc.intermediary", + version=entry["version"], + ) + v.release_time = jar_info.release_time + v.requires = [Dependency(uid="net.minecraft", equals=entry["version"])] + v.order = 11 + v.type = "release" + v.libraries = [] + v.volatile = True + intermediary_lib = Library( + name=GradleSpecifier.from_string(entry["maven"]), + url="https://maven.fabricmc.net", + ) + v.libraries.append(intermediary_lib) + return v + + +def main(): + recommended_loader_versions = [] + recommended_intermediary_versions = [] + + with open( + os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), "r", encoding="utf-8" + ) as f: + loader_version_index = json.load(f) + for entry in loader_version_index: + version = entry["version"] + print(f"Processing loader {version}") + + v = process_loader_version(entry) + + # Fabric Meta has a separate "stable" field, let's use that + if not recommended_loader_versions and entry["stable"]: + recommended_loader_versions.append(version) + + v.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, f"{v.version}.json")) + + with open( + os.path.join(UPSTREAM_DIR, META_DIR, "intermediary.json"), "r", encoding="utf-8" + ) as f: + intermediary_version_index = json.load(f) + for entry in intermediary_version_index: + version = entry["version"] + print(f"Processing intermediary {version}") + + v = process_intermediary_version(entry) + + recommended_intermediary_versions.append( + version + ) # all intermediaries are recommended + + v.write( + os.path.join(LAUNCHER_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json") + ) + + package = MetaPackage(uid=LOADER_COMPONENT, name="Fabric Loader") + package.recommended = recommended_loader_versions + package.description = ( + "Fabric Loader is a tool to load Fabric-compatible mods in game environments." + ) + package.project_url = "https://fabricmc.net" + package.authors = ["Fabric Developers"] + package.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, "package.json")) + + package = MetaPackage(uid=INTERMEDIARY_COMPONENT, name="Intermediary Mappings") + package.recommended = recommended_intermediary_versions + package.description = "Intermediary mappings allow using Fabric Loader with mods for Minecraft in a more compatible manner." + package.project_url = "https://fabricmc.net" + package.authors = ["Fabric Developers"] + package.write(os.path.join(LAUNCHER_DIR, INTERMEDIARY_COMPONENT, "package.json")) + + +if __name__ == "__main__": + main() diff --git a/meta/meta/run/generate_forge.py b/meta/meta/run/generate_forge.py new file mode 100755 index 0000000000..a01f503ebe --- /dev/null +++ b/meta/meta/run/generate_forge.py @@ -0,0 +1,467 @@ +import os +import re +from packaging import version as pversion +from operator import attrgetter +from typing import Collection + +from meta.common import ensure_component_dir, launcher_path, upstream_path, eprint +from meta.common.forge import ( + FORGE_COMPONENT, + INSTALLER_MANIFEST_DIR, + VERSION_MANIFEST_DIR, + DERIVED_INDEX_FILE, + LEGACYINFO_FILE, + INSTALLER_INFO_DIR, + BAD_VERSIONS, + FORGEWRAPPER_LIBRARY, +) +from meta.common.mojang import MINECRAFT_COMPONENT +from meta.model import ( + MetaVersion, + Dependency, + Library, + GradleSpecifier, + MojangLibraryDownloads, + MojangArtifact, + MetaPackage, +) +from meta.model.forge import ( + ForgeVersion, + ForgeInstallerProfile, + ForgeLegacyInfo, + fml_libs_for_version, + ForgeInstallerProfileV2, + InstallerInfo, + DerivedForgeIndex, + ForgeLegacyInfoList, +) +from meta.model.mojang import MojangVersion + +LAUNCHER_DIR = launcher_path() +UPSTREAM_DIR = upstream_path() + +ensure_component_dir(FORGE_COMPONENT) + + +# Construct a set of libraries out of a Minecraft version file, for filtering. +mc_version_cache = {} + + +def load_mc_version_filter(version: str): + if version in mc_version_cache: + return mc_version_cache[version] + v = MetaVersion.parse_file( + os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{version}.json") + ) + libs = set(map(attrgetter("name"), v.libraries)) + mc_version_cache[version] = libs + return libs + + +""" +Match a library coordinate to a set of library coordinates. + * Block those that pass completely. + * For others, block those with lower versions than in the set. +""" + + +def should_ignore_artifact(libs: Collection[GradleSpecifier], match: GradleSpecifier): + for ver in libs: + if ( + ver.group == match.group + and ver.artifact == match.artifact + and ver.classifier == match.classifier + ): + if ver.version == match.version: + # Everything is matched perfectly - this one will be ignored + return True + elif pversion.parse(ver.version) > pversion.parse(match.version): + return True + else: + # Otherwise it did not match - new version is higher and this is an upgrade + return False + # No match found in the set - we need to keep this + return False + + +def version_from_profile( + profile: ForgeInstallerProfile, version: ForgeVersion +) -> MetaVersion: + v = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) + mc_version = profile.install.minecraft + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] + v.main_class = profile.version_info.main_class + v.release_time = profile.version_info.time + + args = profile.version_info.minecraft_arguments + tweakers = [] + expression = re.compile(r"--tweakClass ([a-zA-Z0-9.]+)") + match = expression.search(args) + while match is not None: + tweakers.append(match.group(1)) + args = args[: match.start()] + args[match.end() :] + match = expression.search(args) + if len(tweakers) > 0: + args = args.strip() + v.additional_tweakers = tweakers + # v.minecraftArguments = args + + v.libraries = [] + mc_filter = load_mc_version_filter(mc_version) + for forge_lib in profile.version_info.libraries: + if ( + forge_lib.name.is_lwjgl() + or forge_lib.name.is_log4j() + or should_ignore_artifact(mc_filter, forge_lib.name) + ): + continue + + overridden_name = forge_lib.name + if overridden_name.group == "net.minecraftforge": + if overridden_name.artifact == "minecraftforge": + overridden_name.artifact = "forge" + overridden_name.version = "%s-%s" % ( + mc_version, + overridden_name.version, + ) + + overridden_name.classifier = "universal" + elif overridden_name.artifact == "forge": + overridden_name.classifier = "universal" + + overridden_lib = Library(name=overridden_name) + if forge_lib.url == "http://maven.minecraftforge.net/": + overridden_lib.url = "https://maven.minecraftforge.net/" + else: + overridden_lib.url = forge_lib.url + # if forge_lib.checksums and len(forge_lib.checksums) == 2: + # overridden_lib.mmcHint = "forge-pack-xz" + v.libraries.append(overridden_lib) + + v.order = 5 + return v + + +def version_from_modernized_installer( + installer: MojangVersion, version: ForgeVersion +) -> MetaVersion: + v = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) + mc_version = version.mc_version + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] + v.main_class = installer.main_class + v.release_time = installer.release_time + + args = installer.minecraft_arguments + tweakers = [] + expression = re.compile("--tweakClass ([a-zA-Z0-9.]+)") + match = expression.search(args) + while match is not None: + tweakers.append(match.group(1)) + args = args[: match.start()] + args[match.end() :] + match = expression.search(args) + if len(tweakers) > 0: + args = args.strip() + v.additional_tweakers = tweakers + # v.minecraftArguments = args + + v.libraries = [] + + mc_filter = load_mc_version_filter(mc_version) + for forge_lib in installer.libraries: + if ( + forge_lib.name.is_lwjgl() + or forge_lib.name.is_log4j() + or should_ignore_artifact(mc_filter, forge_lib.name) + ): + continue + + if forge_lib.name.group == "net.minecraftforge": + if forge_lib.name.artifact == "forge": + overridden_name = forge_lib.name + overridden_name.classifier = "universal" + forge_lib.downloads.artifact.path = overridden_name.path() + forge_lib.downloads.artifact.url = ( + "https://maven.minecraftforge.net/%s" % overridden_name.path() + ) + forge_lib.name = overridden_name + + elif forge_lib.name.artifact == "minecraftforge": + overridden_name = forge_lib.name + overridden_name.artifact = "forge" + overridden_name.classifier = "universal" + overridden_name.version = "%s-%s" % ( + mc_version, + overridden_name.version, + ) + forge_lib.downloads.artifact.path = overridden_name.path() + forge_lib.downloads.artifact.url = ( + "https://maven.minecraftforge.net/%s" % overridden_name.path() + ) + forge_lib.name = overridden_name + + v.libraries.append(forge_lib) + + v.order = 5 + return v + + +def version_from_legacy(info: ForgeLegacyInfo, version: ForgeVersion) -> MetaVersion: + v = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) + mc_version = version.mc_version_sane + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] + v.release_time = info.release_time + v.order = 5 + if fml_libs_for_version( + mc_version + ): # WHY, WHY DID I WASTE MY TIME REWRITING FMLLIBSMAPPING + v.additional_traits = ["legacyFML"] + + classifier = "client" + if "universal" in version.url(): + classifier = "universal" + + main_mod = Library( + name=GradleSpecifier( + "net.minecraftforge", "forge", version.long_version, classifier + ) + ) + main_mod.downloads = MojangLibraryDownloads() + main_mod.downloads.artifact = MojangArtifact( + url=version.url(), sha1=info.sha1, size=info.size + ) + main_mod.downloads.artifact.path = None + v.jar_mods = [main_mod] + return v + + +def version_from_build_system_installer( + installer: MojangVersion, profile: ForgeInstallerProfileV2, version: ForgeVersion +) -> MetaVersion: + v = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=version.mc_version_sane)] + v.main_class = "io.github.zekerzhayard.forgewrapper.installer.Main" + + # FIXME: Add the size and hash here + v.maven_files = [] + + # load the locally cached installer file info and use it to add the installer entry in the json + info = InstallerInfo.parse_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version.long_version}.json") + ) + installer_lib = Library( + name=GradleSpecifier( + "net.minecraftforge", "forge", version.long_version, "installer" + ) + ) + installer_lib.downloads = MojangLibraryDownloads() + installer_lib.downloads.artifact = MojangArtifact( + url="https://maven.minecraftforge.net/%s" % (installer_lib.name.path()), + sha1=info.sha1hash, + size=info.size, + ) + v.maven_files.append(installer_lib) + + for forge_lib in profile.libraries: + if forge_lib.name.is_log4j(): + continue + + if ( + forge_lib.name.group == "net.minecraftforge" + and forge_lib.name.artifact == "forge" + and forge_lib.name.classifier == "universal" + ): + forge_lib.downloads.artifact.url = ( + "https://maven.minecraftforge.net/%s" % forge_lib.name.path() + ) + v.maven_files.append(forge_lib) + + v.libraries = [] + + v.libraries.append(FORGEWRAPPER_LIBRARY) + + for forge_lib in installer.libraries: + if forge_lib.name.is_log4j(): + continue + + if forge_lib.name.group == "net.minecraftforge": + if forge_lib.name.artifact == "forge" and not forge_lib.name.classifier: + forge_lib.name.classifier = "launcher" + forge_lib.downloads.artifact.path = forge_lib.name.path() + forge_lib.downloads.artifact.url = ( + "https://maven.minecraftforge.net/%s" % forge_lib.name.path() + ) + forge_lib.name = forge_lib.name + # net.minecraftforge.forge:client doesn't exist??? (49.0.x) + if not len(forge_lib.downloads.artifact.url): + continue + v.libraries.append(forge_lib) + + v.release_time = installer.release_time + v.order = 5 + mc_args = ( + "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} " + "--assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} " + "--accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}" + ) + for arg in installer.arguments.game: + mc_args += f" {arg}" + if "--fml.forgeGroup" not in installer.arguments.game: + mc_args += f" --fml.forgeGroup net.minecraftforge" + if "--fml.forgeVersion" not in installer.arguments.game: + mc_args += f" --fml.forgeVersion {version.rawVersion}" + if "--fml.mcVersion" not in installer.arguments.game: + mc_args += f" --fml.mcVersion {version.mc_version}" + v.minecraft_arguments = mc_args + return v + + +def main(): + # load the locally cached version list + remote_versions = DerivedForgeIndex.parse_file( + os.path.join(UPSTREAM_DIR, DERIVED_INDEX_FILE) + ) + recommended_versions = [] + + legacy_info_list = ForgeLegacyInfoList.parse_file( + os.path.join(UPSTREAM_DIR, LEGACYINFO_FILE) + ) + legacy_versions = [ + "1.1", + "1.2.3", + "1.2.4", + "1.2.5", + "1.3.2", + "1.4.1", + "1.4.2", + "1.4.3", + "1.4.4", + "1.4.5", + "1.4.6", + "1.4.7", + "1.5", + "1.5.1", + "1.5.2", + "1.6.1", + "1.6.2", + "1.6.3", + "1.6.4", + "1.7.10", + "1.7.10-pre4", + "1.7.2", + "1.8", + "1.8.8", + "1.8.9", + "1.9", + "1.9.4", + "1.10", + "1.10.2", + "1.11", + "1.11.2", + "1.12", + "1.12.1", + "1.12.2", + ] + + for key, entry in remote_versions.versions.items(): + if entry.mc_version is None: + eprint("Skipping %s with invalid MC version" % key) + continue + + version = ForgeVersion(entry) + + if version.long_version in BAD_VERSIONS: + # Version 1.12.2-14.23.5.2851 is ultra cringe, I can't imagine why you would even spend one second on + # actually adding support for this version. + # It is cringe, because it's installer info is broken af + eprint(f"Skipping bad version {version.long_version}") + continue + + if version.url() is None: + eprint("Skipping %s with no valid files" % key) + continue + eprint("Processing Forge %s" % version.rawVersion) + version_elements = version.rawVersion.split(".") + if len(version_elements) < 1: + eprint("Skipping version %s with not enough version elements" % key) + continue + + major_version_str = version_elements[0] + if not major_version_str.isnumeric(): + eprint( + "Skipping version %s with non-numeric major version %s" + % (key, major_version_str) + ) + continue + + if entry.recommended: + recommended_versions.append(version.rawVersion) + + # If we do not have the corresponding Minecraft version, we ignore it + if not os.path.isfile( + os.path.join( + LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{version.mc_version_sane}.json" + ) + ): + eprint( + "Skipping %s with no corresponding Minecraft version %s" + % (key, version.mc_version_sane) + ) + continue + + # Path for new-style build system based installers + installer_version_filepath = os.path.join( + UPSTREAM_DIR, VERSION_MANIFEST_DIR, f"{version.long_version}.json" + ) + profile_filepath = os.path.join( + UPSTREAM_DIR, INSTALLER_MANIFEST_DIR, f"{version.long_version}.json" + ) + + eprint(installer_version_filepath) + if os.path.isfile(installer_version_filepath): + installer = MojangVersion.parse_file(installer_version_filepath) + if entry.mc_version in legacy_versions: + v = version_from_modernized_installer(installer, version) + else: + profile = ForgeInstallerProfileV2.parse_file(profile_filepath) + v = version_from_build_system_installer(installer, profile, version) + else: + if version.uses_installer(): + # If we do not have the Forge json, we ignore this version + if not os.path.isfile(profile_filepath): + eprint("Skipping %s with missing profile json" % key) + continue + profile = ForgeInstallerProfile.parse_file(profile_filepath) + v = version_from_profile(profile, version) + else: + # Generate json for legacy here + if version.mc_version_sane == "1.6.1": + continue + build = version.build + if ( + str(build).encode("utf-8").decode("utf8") + not in legacy_info_list.number + ): + eprint( + "Legacy build %d is missing in legacy info. Ignoring." % build + ) + continue + + v = version_from_legacy(legacy_info_list.number[str(build)], version) + + v.write(os.path.join(LAUNCHER_DIR, FORGE_COMPONENT, f"{v.version}.json")) + + recommended_versions.sort() + + print("Recommended versions:", recommended_versions) + + package = MetaPackage( + uid=FORGE_COMPONENT, + name="Forge", + project_url="https://www.minecraftforge.net/forum/", + ) + package.recommended = recommended_versions + package.write(os.path.join(LAUNCHER_DIR, FORGE_COMPONENT, "package.json")) + + +if __name__ == "__main__": + main() diff --git a/meta/meta/run/generate_java.py b/meta/meta/run/generate_java.py new file mode 100644 index 0000000000..9f23e3a4d3 --- /dev/null +++ b/meta/meta/run/generate_java.py @@ -0,0 +1,537 @@ +import copy +import datetime +import os +from typing import Optional +from functools import reduce + +from meta.common import ensure_component_dir, launcher_path, upstream_path + +from meta.common.java import ( + JAVA_MINECRAFT_COMPONENT, + JAVA_ADOPTIUM_COMPONENT, + JAVA_OPENJ9_COMPONENT, + JAVA_AZUL_COMPONENT, + ADOPTIUM_DIR, + ADOPTIUM_VERSIONS_DIR, + OPENJ9_DIR, + OPENJ9_VERSIONS_DIR, + AZUL_DIR, + AZUL_VERSIONS_DIR, +) +from meta.model import MetaPackage +from meta.model.java import ( + JavaRuntimeOS, + JavaRuntimeVersion, + JavaRuntimeMeta, + JavaVersionMeta, + JavaPackageType, + JavaChecksumMeta, + JavaChecksumType, + JavaRuntimeDownloadType, + AdoptxAvailableReleases, + AdoptxReleases, + AdoptxRelease, + AdoptxImageType, + AdoptxBinary, + ZuluPackageList, + ZuluPackageDetail, + AzulJavaPackageType, + AzulArch, +) + +from meta.common.mojang import ( + JAVA_MANIFEST_FILE, +) + +from meta.model.mojang import ( + JavaIndex, + MojangJavaComponent, + MojangJavaOsName, + MojangJavaRuntime, +) + +LAUNCHER_DIR = launcher_path() +UPSTREAM_DIR = upstream_path() + + +MOJANG_OS_ARCHITECTURES = [ + "x64", + "x86", + "arm64", + "arm32", + "riscv64", +] + +MOJANG_OS_ARCHITECTURE_TRANSLATIONS = { + 64: "x64", + 32: "x86", + "x32": "x86", + "i386": "x86", + "aarch64": "arm64", + "x86_64": "x64", + "arm": "arm32", + "riscv64": "riscv64", +} + + +def translate_arch(arch: str | int): + if isinstance(arch, str): + arch = arch.lower() + if arch in MOJANG_OS_ARCHITECTURES: + return arch + elif arch in MOJANG_OS_ARCHITECTURE_TRANSLATIONS: + return MOJANG_OS_ARCHITECTURE_TRANSLATIONS[arch] + else: + return None + + +MOJANG_OS_NAMES = [ + "mac-os", + "linux", + "windows", +] + +MOJANG_OS_TRANSLATIONS = { + "osx": "mac-os", + "mac": "mac-os", + "macos": "mac-os", +} + + +def translate_os(os: str): + os = os.lower() + if os in MOJANG_OS_NAMES: + return os + elif os in MOJANG_OS_TRANSLATIONS: + return MOJANG_OS_TRANSLATIONS[os] + else: + return None + + +def mojang_os_to_java_os(mojang_os: MojangJavaOsName) -> JavaRuntimeOS: + match mojang_os: + case MojangJavaOsName.Linux: + return JavaRuntimeOS.LinuxX64 + case MojangJavaOsName.Linuxi386: + return JavaRuntimeOS.LinuxX86 + case MojangJavaOsName.MacOs: + return JavaRuntimeOS.MacOsX64 + case MojangJavaOsName.MacOSArm64: + return JavaRuntimeOS.MacOsArm64 + case MojangJavaOsName.WindowsArm64: + return JavaRuntimeOS.WindowsArm64 + case MojangJavaOsName.WindowsX64: + return JavaRuntimeOS.WindowsX64 + case MojangJavaOsName.WindowsX86: + return JavaRuntimeOS.WindowsX86 + case _: + return JavaRuntimeOS.Unknown + + +def mojang_component_to_major(mojang_component: MojangJavaComponent) -> int: + match mojang_component: + case MojangJavaComponent.JreLegacy: + return 8 + case MojangJavaComponent.Alpha: + return 17 + case MojangJavaComponent.Beta: + return 17 + case MojangJavaComponent.Gamma: + return 17 + case MojangJavaComponent.GammaSnapshot: + return 17 + case MojangJavaComponent.Exe: + return 0 + case MojangJavaComponent.Delta: + return 21 + case MojangJavaComponent.Epsilon: + return 25 + case _: + return 0 + + +def mojang_runtime_to_java_runtime( + mojang_runtime: MojangJavaRuntime, + mojang_component: MojangJavaComponent, + runtime_os: JavaRuntimeOS, +) -> JavaRuntimeMeta: + major, _, trail = mojang_runtime.version.name.partition("u") + security, _, buildstr = trail.partition("-") + + if buildstr == "": + buildstr = None + + if major and security: + version_parts = [int(major), 0, int(security)] + else: + version_parts = [int(part) for part in mojang_runtime.version.name.split(".")] + + while len(version_parts) < 3: + version_parts.append(0) + + build = None + if len(version_parts) >= 4: + build = version_parts[3] + + version = JavaVersionMeta( + major=version_parts[0], + minor=version_parts[1], + security=version_parts[2], + build=build, + buildstr=buildstr, + name=mojang_runtime.version.name, + ) + return JavaRuntimeMeta( + name=mojang_component, + vendor="mojang", + url=mojang_runtime.manifest.url, + releaseTime=mojang_runtime.version.released, + checksum=JavaChecksumMeta( + type=JavaChecksumType.Sha1, hash=mojang_runtime.manifest.sha1 + ), + downloadType=JavaRuntimeDownloadType.Manifest, + packageType=JavaPackageType.Jre, + version=version, + runtime_os=runtime_os, + ) + + +def adoptx_release_binary_to_java_runtime( + rls: AdoptxRelease, + binary: AdoptxBinary, + runtime_os: JavaRuntimeOS, +) -> JavaRuntimeMeta: + assert binary.package is not None + + checksum = None + if binary.package.checksum is not None: + checksum = JavaChecksumMeta( + type=JavaChecksumType.Sha256, hash=binary.package.checksum + ) + + pkg_type = JavaPackageType(str(binary.image_type)) + + version = JavaVersionMeta( + major=rls.version_data.major if rls.version_data.major is not None else 0, + minor=rls.version_data.minor if rls.version_data.minor is not None else 0, + security=( + rls.version_data.security if rls.version_data.security is not None else 0 + ), + build=rls.version_data.build, + ) + + if rls.vendor == "eclipse": + rls_distribution = "temurin" + elif rls.vendor == "ibm": + rls_distribution = "semeru-open" + + rls_name = f"{rls.vendor}_{rls_distribution}_{binary.image_type}{version}" + return JavaRuntimeMeta( + name=rls_name, + vendor=rls.vendor, + url=binary.package.link, + releaseTime=rls.timestamp, + checksum=checksum, + downloadType=JavaRuntimeDownloadType.Archive, + packageType=pkg_type, + version=version, + runtime_os=runtime_os, + ) + + +def azul_package_to_java_runtime( + pkg: ZuluPackageDetail, runtime_os: JavaRuntimeOS +) -> JavaRuntimeMeta: + version_parts = copy.copy(pkg.java_version) + + build = None + while len(version_parts) < 3: + version_parts.append(0) + + if len(version_parts) >= 4: + build = version_parts[3] + + version = JavaVersionMeta( + major=version_parts[0], + minor=version_parts[1], + security=version_parts[2], + build=build, + ) + + pkg_type = JavaPackageType(str(pkg.java_package_type)) + + rls_name = f"azul_{pkg.product}_{pkg.java_package_type}{version}" + + checksum = None + if pkg.sha256_hash is not None: + checksum = JavaChecksumMeta(type=JavaChecksumType.Sha256, hash=pkg.sha256_hash) + + return JavaRuntimeMeta( + name=rls_name, + vendor="azul", + url=pkg.download_url, + releaseTime=pkg.build_date, + checksum=checksum, + downloadType=JavaRuntimeDownloadType.Archive, + packageType=pkg_type, + version=version, + runtime_os=runtime_os, + ) + + +def writeJavas(javas: dict[int, list[JavaRuntimeMeta]], uid: str): + def oldest_timestamp(a: datetime.datetime | None, b: datetime.datetime): + if a is None or a > b: + return b + return a + + ensure_component_dir(uid) + + # small hack to sort the versions after major + javas = dict(sorted(javas.items(), key=lambda item: item[0])) + timestamps: dict[int, datetime.datetime | None] = {} + prevDate: datetime.datetime | None = None + for major, runtimes in javas.items(): + releaseTime = reduce( + oldest_timestamp, + (runtime.release_time for runtime in runtimes), + None, + ) + if prevDate is not None and releaseTime < prevDate: + releaseTime = prevDate + datetime.timedelta(seconds=1) + prevDate = releaseTime + timestamps[major] = releaseTime + + for major, runtimes in javas.items(): + version_file = os.path.join(LAUNCHER_DIR, uid, f"java{major}.json") + java_version = JavaRuntimeVersion( + name=f"Java {major}", + uid=uid, + version=f"java{major}", + releaseTime=timestamps.get(major), + runtimes=runtimes, + ) + java_version.write(version_file) + + package = MetaPackage(uid=uid, name="Java Runtimes", recommended=[]) + package.write(os.path.join(LAUNCHER_DIR, uid, "package.json")) + + +def main(): + javas: dict[int, list[JavaRuntimeMeta]] = {} + extra_mojang_javas: dict[int, list[JavaRuntimeMeta]] = {} + + def add_java_runtime(runtime: JavaRuntimeMeta, major: int): + if major not in javas: + javas[major] = list[JavaRuntimeMeta]() + print(f"Registering runtime: {runtime.name} for Java {major}") + javas[major].append(runtime) + + # only add specific versions to the list + if ( + ( + runtime.runtime_os + in [JavaRuntimeOS.MacOsArm64, JavaRuntimeOS.WindowsArm64] + and major == 8 + ) + or ( + runtime.runtime_os + in [ + JavaRuntimeOS.WindowsArm32, + JavaRuntimeOS.LinuxArm32, + JavaRuntimeOS.LinuxArm64, + ] + and major in [8, 17, 21, 25] + ) + or ( + runtime.runtime_os + in [JavaRuntimeOS.LinuxX86, JavaRuntimeOS.LinuxRiscv64] + and major in [17, 21, 25] + ) + ): + if major not in extra_mojang_javas: + extra_mojang_javas[major] = list[JavaRuntimeMeta]() + extra_mojang_javas[major].append(runtime) + + print("Processing Adoptium Releases") + adoptium_path = os.path.join(UPSTREAM_DIR, ADOPTIUM_DIR, "available_releases.json") + if os.path.exists(adoptium_path): + adoptium_available_releases = AdoptxAvailableReleases.parse_file(adoptium_path) + for major in adoptium_available_releases.available_releases: + adoptium_releases = AdoptxReleases.parse_file( + os.path.join(UPSTREAM_DIR, ADOPTIUM_VERSIONS_DIR, f"java{major}.json") + ) + for _, rls in adoptium_releases: + for binary in rls.binaries: + if ( + binary.package is None + or binary.image_type is not AdoptxImageType.Jre + ): + continue + binary_arch = translate_arch(str(binary.architecture)) + binary_os = translate_os(str(binary.os)) + if binary_arch is None or binary_os is None: + print(f"Ignoring release for {binary.os} {binary.architecture}") + continue + + java_os = JavaRuntimeOS(f"{binary_os}-{binary_arch}") + runtime = adoptx_release_binary_to_java_runtime( + rls, binary, java_os + ) + add_java_runtime(runtime, major) + writeJavas(javas=javas, uid=JAVA_ADOPTIUM_COMPONENT) + javas = {} + + print("Processing OpenJ9 Releases") + openj9_path = os.path.join(UPSTREAM_DIR, OPENJ9_DIR, "available_releases.json") + if os.path.exists(openj9_path): + openj9_available_releases = AdoptxAvailableReleases.parse_file(openj9_path) + for major in openj9_available_releases.available_releases: + path = os.path.join(UPSTREAM_DIR, OPENJ9_VERSIONS_DIR, f"java{major}.json") + + if not os.path.exists(path): + continue + + openj9_releases = AdoptxReleases.parse_file(path) + for _, rls in openj9_releases: + for binary in rls.binaries: + if ( + binary.package is None + or binary.image_type is not AdoptxImageType.Jre + ): + continue + binary_arch = translate_arch(str(binary.architecture)) + binary_os = translate_os(str(binary.os)) + if binary_arch is None or binary_os is None: + print(f"Ignoring release for {binary.os} {binary.architecture}") + continue + + java_os = JavaRuntimeOS(f"{binary_os}-{binary_arch}") + runtime = adoptx_release_binary_to_java_runtime( + rls, binary, java_os + ) + add_java_runtime(runtime, major) + writeJavas(javas=javas, uid=JAVA_OPENJ9_COMPONENT) + javas = {} + + print("Processing Azul Packages") + azul_path = os.path.join(UPSTREAM_DIR, AZUL_DIR, "packages.json") + if os.path.exists(azul_path): + azul_packages = ZuluPackageList.parse_file(azul_path) + for _, pkg in azul_packages: + pkg_detail = ZuluPackageDetail.parse_file( + os.path.join( + UPSTREAM_DIR, AZUL_VERSIONS_DIR, f"{pkg.package_uuid}.json" + ) + ) + major = pkg_detail.java_version[0] + if major < 8 or pkg_detail.java_package_type is not AzulJavaPackageType.Jre: + continue # we will never need java versions less than 8 + + pkg_os = translate_os(str(pkg_detail.os)) + if pkg_detail.arch == AzulArch.Arm: + pkg_arch = translate_arch(f"{pkg_detail.arch}{pkg_detail.hw_bitness}") + elif pkg_detail.arch == AzulArch.X86: + pkg_arch = translate_arch(int(pkg_detail.hw_bitness)) + else: + pkg_arch = None + if pkg_arch is None or pkg_os is None: + print( + f"Ignoring release for {pkg_detail.os} {pkg_detail.arch}_{pkg_detail.hw_bitness}" + ) + continue + + java_os = JavaRuntimeOS(f"{pkg_os}-{pkg_arch}") + runtime = azul_package_to_java_runtime(pkg_detail, java_os) + add_java_runtime(runtime, major) + writeJavas(javas=javas, uid=JAVA_AZUL_COMPONENT) + javas = {} + + # constructs the missing mojang javas based on adoptium or azul (do not consider openj9 since it is for more niche cases) + def get_mojang_extra_java( + mojang_component: MojangJavaComponent, java_os: JavaRuntimeOS + ) -> JavaRuntimeMeta | None: + java_major = mojang_component_to_major(mojang_component) + if not java_major in extra_mojang_javas: + return None + posible_javas = list( + filter(lambda x: x.runtime_os == java_os, extra_mojang_javas[java_major]) + ) + if len(posible_javas) == 0: + return None + prefered_vendor = list(filter(lambda x: x.vendor != "azul", posible_javas)) + if len(prefered_vendor) == 0: + prefered_vendor = posible_javas + prefered_vendor.sort(key=lambda x: x.version, reverse=True) + runtime = prefered_vendor[0] + runtime.name = mojang_component + return runtime + + print("Processing Mojang Javas") + mojang_java_manifest = JavaIndex.parse_file( + os.path.join(UPSTREAM_DIR, JAVA_MANIFEST_FILE) + ) + # print(mojang_java_manifest) + for mojang_os_name in mojang_java_manifest: + if mojang_os_name == MojangJavaOsName.Gamecore: + continue # empty + java_os = mojang_os_to_java_os(mojang_os_name) + for comp in mojang_java_manifest[mojang_os_name]: + if comp == MojangJavaComponent.Exe: + continue # doesn't appear to be used and not marked with a full verison so I don't trust it + mojang_runtimes = mojang_java_manifest[mojang_os_name][comp] + if len(mojang_runtimes) == 0: + if mojang_os_name in [ + MojangJavaOsName.WindowsArm64, + MojangJavaOsName.MacOSArm64, + ]: + if comp in [MojangJavaComponent.Alpha, MojangJavaComponent.Beta]: + mojang_runtimes = mojang_java_manifest[mojang_os_name][ + MojangJavaComponent.Gamma + ] + elif ( + comp == MojangJavaComponent.JreLegacy + ): # arm version of win and mac is missing the legacy java + runtime = get_mojang_extra_java(comp, java_os) + if runtime != None: + add_java_runtime(runtime, mojang_component_to_major(comp)) + if ( + mojang_os_name == MojangJavaOsName.Linuxi386 + and comp != MojangJavaComponent.JreLegacy + ): # the linux x86 is missing all but legacy + runtime = get_mojang_extra_java(comp, java_os) + if runtime != None: + add_java_runtime(runtime, mojang_component_to_major(comp)) + for mojang_runtime in mojang_runtimes: + if comp == MojangJavaComponent.JreLegacy: + major = 8 + else: + major = int(mojang_runtime.version.name.partition(".")[0]) + runtime = mojang_runtime_to_java_runtime(mojang_runtime, comp, java_os) + add_java_runtime(runtime, major) + # mojang doesn't provide any versions for the following systems so borrow info from adoptium/azul (do not consider openj9 since it is for more niche cases) + for java_os in [ + JavaRuntimeOS.WindowsArm32, + JavaRuntimeOS.LinuxArm32, + JavaRuntimeOS.LinuxArm64, + JavaRuntimeOS.LinuxRiscv64, + ]: + for comp in [ + MojangJavaComponent.JreLegacy, + MojangJavaComponent.Alpha, + MojangJavaComponent.Beta, + MojangJavaComponent.Gamma, + MojangJavaComponent.GammaSnapshot, + MojangJavaComponent.Delta, + MojangJavaComponent.Epsilon, + ]: + runtime = get_mojang_extra_java(comp, java_os) + if runtime != None: + add_java_runtime(runtime, mojang_component_to_major(comp)) + + writeJavas(javas=javas, uid=JAVA_MINECRAFT_COMPONENT) + javas = {} + + +if __name__ == "__main__": + main() diff --git a/meta/meta/run/generate_liteloader.py b/meta/meta/run/generate_liteloader.py new file mode 100755 index 0000000000..2fe95fcc42 --- /dev/null +++ b/meta/meta/run/generate_liteloader.py @@ -0,0 +1,118 @@ +import os +from datetime import datetime +from typing import List, Tuple, Dict, Optional + +from meta.common import ensure_component_dir, launcher_path, upstream_path +from meta.common.liteloader import LITELOADER_COMPONENT, VERSIONS_FILE +from meta.common.mojang import MINECRAFT_COMPONENT +from meta.model import MetaVersion, GradleSpecifier, Library, MetaPackage, Dependency +from meta.model.liteloader import LiteloaderIndex, LiteloaderArtefact + +LAUNCHER_DIR = launcher_path() +UPSTREAM_DIR = upstream_path() + +ensure_component_dir(LITELOADER_COMPONENT) + + +def process_artefacts( + mc_version: str, artefacts: Dict[str, LiteloaderArtefact], is_snapshot: bool +) -> Tuple[List[MetaVersion], Optional[MetaVersion]]: + versions: List[MetaVersion] = [] + lookup: Dict[str, MetaVersion] = {} + latest_version = None + latest = None + for x, artefact in artefacts.items(): + if x == "latest": + latest_version = artefact.version + continue + v = MetaVersion( + name="LiteLoader", + uid=LITELOADER_COMPONENT, + version=artefact.version, + requires=[Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)], + release_time=datetime.utcfromtimestamp(int(artefact.timestamp)), + additional_tweakers=[artefact.tweakClass], + main_class="net.minecraft.launchwrapper.Launch", + order=10, + libraries=artefact.libraries, + type="release", + ) + + if is_snapshot: + v.type = "snapshot" + + # hack to make broken liteloader versions work + for lib in v.libraries: + if lib.name == GradleSpecifier("org.ow2.asm", "asm-all", "5.0.3"): + lib.url = "https://repo.maven.apache.org/maven2/" + if lib.name == GradleSpecifier("org.ow2.asm", "asm-all", "5.2"): + lib.url = "http://repo.liteloader.com/" + + liteloader_lib = Library( + name=GradleSpecifier("com.mumfrey", "liteloader", v.version), + url="http://dl.liteloader.com/versions/", + ) + if is_snapshot: + liteloader_lib.mmcHint = "always-stale" + v.libraries.append(liteloader_lib) + + versions.append(v) + lookup[v.version] = v + + if latest_version: + latest = lookup[latest_version] + return versions, latest + + +def process_versions(index: LiteloaderIndex) -> Tuple[List[MetaVersion], List[str]]: + all_versions: List[MetaVersion] = [] + recommended: List[str] = [] + for mcVersion, versionObject in index.versions.items(): + # ignore this for now. It should be a jar mod or something. + if mcVersion == "1.5.2": + continue + + latest_release = None + if versionObject.artefacts: + versions, latest_release = process_artefacts( + mcVersion, versionObject.artefacts.liteloader, False + ) + all_versions.extend(versions) + if versionObject.snapshots: + versions, latest_snapshot = process_artefacts( + mcVersion, versionObject.snapshots.liteloader, True + ) + all_versions.extend(versions) + + if latest_release: + recommended.append(latest_release.version) + + recommended.sort() + + all_versions.sort(key=lambda x: x.release_time, reverse=True) + return all_versions, recommended + + +def main(): + index = LiteloaderIndex.parse_file(os.path.join(UPSTREAM_DIR, VERSIONS_FILE)) + + all_versions, recommended = process_versions(index) + + for version in all_versions: + version.write( + os.path.join(LAUNCHER_DIR, LITELOADER_COMPONENT, f"{version.version}.json") + ) + + package = MetaPackage( + uid=LITELOADER_COMPONENT, + name="LiteLoader", + description=index.meta.description, + project_url=index.meta.url, + authors=[index.meta.authors], + recommended=recommended, + ) + package.write(os.path.join(LAUNCHER_DIR, LITELOADER_COMPONENT, "package.json")) + + +if __name__ == "__main__": + main() diff --git a/meta/meta/run/generate_mojang.py b/meta/meta/run/generate_mojang.py new file mode 100755 index 0000000000..9d2063263a --- /dev/null +++ b/meta/meta/run/generate_mojang.py @@ -0,0 +1,589 @@ +import copy +import hashlib +import re +import os +from collections import defaultdict, namedtuple +from operator import attrgetter +from pprint import pprint +from packaging import version as pversion +from typing import Optional, List + +from meta.common import ensure_component_dir, launcher_path, upstream_path +from meta.common.mojang import ( + STATIC_LEGACY_SERVICES_FILE, + VERSION_MANIFEST_FILE, + MINECRAFT_COMPONENT, + LWJGL3_COMPONENT, + LWJGL_COMPONENT, + STATIC_OVERRIDES_FILE, + VERSIONS_DIR, + LIBRARY_PATCHES_FILE, +) +from meta.model import ( + MetaVersion, + Library, + GradleSpecifier, + MojangLibraryDownloads, + MojangArtifact, + Dependency, + MetaPackage, + MojangRules, +) +from meta.model.mojang import ( + LegacyServices, + MojangIndexWrap, + MojangIndex, + MojangVersion, + LegacyOverrideIndex, + LibraryPatches, + SUPPORTED_FEATURES, +) + +APPLY_SPLIT_NATIVES_WORKAROUND = True + +LAUNCHER_DIR = launcher_path() +UPSTREAM_DIR = upstream_path() + +ensure_component_dir(MINECRAFT_COMPONENT) +ensure_component_dir(LWJGL_COMPONENT) +ensure_component_dir(LWJGL3_COMPONENT) + + +def map_log4j_artifact(version): + x = pversion.parse(version) + if x <= pversion.parse("2.0"): + return "2.0-beta9-fixed", "https://files.prismlauncher.org/maven/%s" + if x <= pversion.parse("2.17.1"): + return ( + "2.17.1", + "https://repo1.maven.org/maven2/%s", + ) # This is the only version that's patched (as of 2022/02/19) + return None, None + + +LOG4J_HASHES = { + "2.0-beta9-fixed": { + "log4j-api": { + "sha1": "b61eaf2e64d8b0277e188262a8b771bbfa1502b3", + "size": 107347, + }, + "log4j-core": { + "sha1": "677991ea2d7426f76309a73739cecf609679492c", + "size": 677588, + }, + }, + "2.17.1": { + "log4j-api": { + "sha1": "d771af8e336e372fb5399c99edabe0919aeaf5b2", + "size": 301872, + }, + "log4j-core": { + "sha1": "779f60f3844dadc3ef597976fcb1e5127b1f343d", + "size": 1790452, + }, + "log4j-slf4j18-impl": { + "sha1": "ca499d751f4ddd8afb016ef698c30be0da1d09f7", + "size": 21268, + }, + }, +} + +# We want versions that contain natives for all platforms. If there are multiple, pick the latest one +# LWJGL versions we want +PASS_VARIANTS = [ + "1fd0e4d1f0f7c97e8765a69d38225e1f27ee14ef", # 3.4.1 (2026-02-17 12:42:24+00:00) + "2b00f31688148fc95dbc8c8ef37308942cf0dce0", # 3.3.6 (2025-10-21 11:38:51+00:00) + "73974b3af2afeb5b272ffbadcd7963014387c84f", # 3.3.3 (2024-05-22 16:25:41+00:00) + "765b4ab443051d286bdbb1c19cd7dc86b0792dce", # 3.3.2 (2024-01-17 13:19:20+00:00) + "54c4fb1d6a96ac3007c947bf310c8bcf94a862be", # 3.3.1 (2023-04-20 11:55:19+00:00) split natives, with WoA natives + "ea4973ebc9eadf059f30f0958c89f330898bff51", # 3.2.2 (2019-07-04 14:41:05+00:00) will be patched, missing tinyfd + "235fc413bc4c76b269c207f7bca6464f1e1f1d80", # 3.2.1 (2019-02-13 16:12:08+00:00) + "deb1a436d806413207350735a00e04b54d113916", # 3.1.6 (2018-10-18 14:46:12+00:00) + "3e47f0f742fb759401754769fa59c508fd8fda75", # 3.1.2 (2018-06-21 12:57:11+00:00) + "a3f254df5a63a0a1635755733022029e8cfae1b3", # 2.9.4-nightly-20150209 (2016-12-20 14:05:34+00:00) + "879be09c0bd0d4bafc2ea4ea3d2ab8607a0d976c", # 2.9.3 (2015-01-30 11:58:24+00:00) + "8d4951d00253dfaa36a0faf1c8be541431861c30", # 2.9.1 (2014-05-22 14:44:33+00:00) + "cf58c9f92fed06cb041a7244c6b4b667e6d544cc", # 2.9.1-nightly-20131120 (2013-12-06 13:55:34+00:00) + "27dcadcba29a1a7127880ca1a77efa9ece866f24", # 2.9.0 (2013-09-06 12:31:58+00:00) +] + +# LWJGL versions we def. don't want! +BAD_VARIANTS = [ + "6f32ef730d05562ede7db0b845b72ea16dd239d5", # 3.3.3 (2024-05-29 12:04:43+00:00) missing os rule for freetype natives-macos-patch + "8a9b08f11271eb4de3b50e5d069949500b2c7bc1", # 3.3.3 (2024-04-03 11:49:39+00:00) seems to have a broken libfreetype for macOS x86_64 + "79bde9e46e9ad9accebda11e8293ed08d80dbdc3", # 3.3.2 (2023-08-30 11:24:35+00:00) does not have lwjgl-freetype + "8836c419f90f69a278b97d945a34af165c24ff60", # 3.3.1 (2022-05-18 13:51:54+00:00) split natives, with workaround, replaced by 23w26a + "3c624b94c06dbc4abae08fe6156d74abe4a2cca5", # 3.3.1 (2022-05-04 14:41:35+00:00) we already have a nice 3.3.1 + "e1106ca765798218323b7a6d7528050260ea9d88", # 3.3.1 (2022-05-04 14:41:35+00:00) doesn't use split natives + "90b3d9ca01058286c033b6b7ae7f6dc370a04015", # 3.2.2 (2022-03-31 14:53:25+00:00) only linux, windows + "d986df9598fa2bcf4a5baab5edf044548e66d011", # 3.2.2 (2021-12-10 03:36:38+00:00) only linux, windows + "4b73fccb9e5264c2068bdbc26f9651429abbf21a", # 3.2.2 (2021-08-25 14:41:57+00:00) only linux, windows + "090cec3577ecfe438b890b2a9410ea07aa725e16", # 3.2.2 (2021-04-07 14:04:09+00:00) only linux, windows + "ab463e9ebc6a36abf22f2aa27b219dd372ff5069", # 3.2.2 (2019-08-13 07:33:42+00:00) only linux, windows + "51d8ff5a7efc949b4ad2088930e151d6b88ba616", # 3.2.2 (2019-07-19 09:25:47+00:00) only linux, windows + "854649a5bd1455b89117593ae82ff90c8132cacf", # 3.2.1 (2019-04-18 11:05:19+00:00) only osx, windows + "89fcb489261b05f622e8052fe0b588b0cfe49c24", # 3.1.6 (2019-04-18 11:05:19+00:00) only linux + "f04052162b50fa1433f67e1a90bc79466c4ab776", # 2.9.0 (2013-10-21 16:34:47+00:00) only linux, windows + "6442fc475f501fbd0fc4244fd1c38c02d9ebaf7e", # 2.9.0 (2011-03-30 22:00:00+00:00) fine but newer variant available +] + + +def add_or_get_bucket(buckets, rules: Optional[MojangRules]) -> MetaVersion: + rule_hash = None + if rules: + rule_hash = hash(rules.json()) + + if rule_hash in buckets: + bucket = buckets[rule_hash] + else: + bucket = MetaVersion(name="LWJGL", version="undetermined", uid=LWJGL_COMPONENT) + bucket.type = "release" + buckets[rule_hash] = bucket + return bucket + + +def hash_lwjgl_version(lwjgl: MetaVersion): + lwjgl_copy = copy.deepcopy(lwjgl) + lwjgl_copy.release_time = None + return hashlib.sha1(lwjgl_copy.json().encode("utf-8", "strict")).hexdigest() + + +def sort_libs_by_name(library): + return library.name + + +LWJGLEntry = namedtuple("LWJGLEntry", ("version", "sha1")) + +lwjglVersionVariants = defaultdict(list) + + +def add_lwjgl_version(variants, lwjgl): + lwjgl_copy = copy.deepcopy(lwjgl) + libraries = list(lwjgl_copy.libraries) + libraries.sort(key=sort_libs_by_name) + lwjgl_copy.libraries = libraries + + version = lwjgl_copy.version + current_hash = hash_lwjgl_version(lwjgl_copy) + found = False + for variant in variants[version]: + existing_hash = variant.sha1 + if current_hash == existing_hash: + found = True + break + if not found: + print("!!! New variant for LWJGL version %s" % version) + variants[version].append(LWJGLEntry(version=lwjgl_copy, sha1=current_hash)) + + +def remove_paths_from_lib(lib): + if lib.downloads.artifact: + lib.downloads.artifact.path = None + if lib.downloads.classifiers: + for key, value in lib.downloads.classifiers.items(): + value.path = None + + +def adapt_new_style_arguments(arguments): + foo = [] + # we ignore the jvm arguments entirely. + # grab the strings, log the complex stuff + for arg in arguments.game: + if isinstance(arg, str): + if arg == "--clientId": + continue + if arg == "${clientid}": + continue + if arg == "--xuid": + continue + if arg == "${auth_xuid}": + continue + foo.append(arg) + else: + print("!!! Unrecognized structure in Minecraft game arguments:") + pprint(arg) + return " ".join(foo) + + +def adapt_new_style_arguments_to_traits(arguments): + foo = [] + # we ignore the jvm arguments entirely. + # grab the object, log the errors + for arg in arguments.game: + if isinstance(arg, dict): + for rule in arg["rules"]: + for k, v in rule["features"].items(): + if rule["action"] == "allow" and v and k in SUPPORTED_FEATURES: + foo.append(f"feature:{k}") + return foo + + +def is_macos_only(rules: Optional[MojangRules]): + allows_osx = False + allows_all = False + # print("Considering", specifier, "rules", rules) + if rules: + for rule in rules: + if rule.action == "allow" and rule.os and rule.os.name == "osx": + allows_osx = True + if rule.action == "allow" and not rule.os: + allows_all = True + if allows_osx and not allows_all: + return True + return False + + +def patch_library(lib: Library, patches: LibraryPatches) -> List[Library]: + to_patch = [lib] + + new_libraries = [] + while to_patch: + target = to_patch.pop(0) + + for patch in patches: + if patch.applies(target): + if patch.override: + target.merge(patch.override) + + if patch.additionalLibraries: + additional_copy = copy.deepcopy(patch.additionalLibraries) + new_libraries += list(dict.fromkeys(additional_copy)) + if patch.patchAdditionalLibraries: + to_patch += additional_copy + + return new_libraries + + +def process_single_variant(lwjgl_variant: MetaVersion, patches: LibraryPatches): + lwjgl_version = lwjgl_variant.version + v = copy.deepcopy(lwjgl_variant) + + new_libraries = [] + for lib in v.libraries: + new_libraries += patch_library(lib, patches) + v.libraries += list(dict.fromkeys(new_libraries)) + + if lwjgl_version[0] == "2": + filename = os.path.join(LAUNCHER_DIR, LWJGL_COMPONENT, f"{lwjgl_version}.json") + + v.name = "LWJGL 2" + v.uid = LWJGL_COMPONENT + v.conflicts = [Dependency(uid=LWJGL3_COMPONENT)] + elif lwjgl_version[0] == "3": + filename = os.path.join(LAUNCHER_DIR, LWJGL3_COMPONENT, f"{lwjgl_version}.json") + + v.name = "LWJGL 3" + v.uid = LWJGL3_COMPONENT + v.conflicts = [Dependency(uid=LWJGL_COMPONENT)] + # remove jutils and jinput from LWJGL 3 + # this is a dependency that Mojang kept in, but doesn't belong there anymore + filtered_libraries = list( + filter(lambda l: l.name.artifact not in ["jutils", "jinput"], v.libraries) + ) + v.libraries = filtered_libraries + else: + raise Exception("LWJGL version not recognized: %s" % v.version) + + v.volatile = True + v.order = -1 + good = True + for lib in v.libraries: + # skip libraries without natives or that we patched + if not lib.natives or lib in new_libraries: + continue + checked_dict = {"linux", "windows", "osx"} + if not checked_dict.issubset(lib.natives.keys()): + print("Missing system classifier!", v.version, lib.name, lib.natives.keys()) + good = False + break + if lib.downloads: + for entry in checked_dict: + baked_entry = lib.natives[entry] + if baked_entry not in lib.downloads.classifiers: + print( + "Missing download for classifier!", + v.version, + lib.name, + baked_entry, + lib.downloads.classifiers.keys(), + ) + good = False + break + if good: + v.write(filename) + else: + print("Skipped LWJGL", v.version) + + +def lib_is_split_native(lib: Library) -> bool: + if lib.name.classifier and lib.name.classifier.startswith("natives-"): + return True + return False + + +def version_has_split_natives(v: MojangVersion) -> bool: + for lib in v.libraries: + if lib_is_split_native(lib): + return True + return False + + +def main(): + # get the local version list + override_index = LegacyOverrideIndex.parse_file(STATIC_OVERRIDES_FILE) + legacy_services = LegacyServices.parse_file(STATIC_LEGACY_SERVICES_FILE) + library_patches = LibraryPatches.parse_file(LIBRARY_PATCHES_FILE) + + found_any_lwjgl3 = False + + for filename in os.listdir(os.path.join(UPSTREAM_DIR, VERSIONS_DIR)): + input_file = os.path.join(UPSTREAM_DIR, VERSIONS_DIR, filename) + if not input_file.endswith(".json"): + # skip non JSON files + continue + print("Processing", filename) + mojang_version = MojangVersion.parse_file(input_file) + v = mojang_version.to_meta_version( + "Minecraft", MINECRAFT_COMPONENT, mojang_version.id + ) + + libs_minecraft = [] + new_libs_minecraft = [] + is_lwjgl_3 = False + has_split_natives = version_has_split_natives(v) + buckets = {} + + for lib in v.libraries: + specifier = lib.name + + # generic fixes + remove_paths_from_lib(lib) + + if APPLY_SPLIT_NATIVES_WORKAROUND and lib_is_split_native(lib): + # merge classifier into artifact name to workaround bug in launcher + specifier.artifact += f"-{specifier.classifier}" + specifier.classifier = None + + if specifier.is_lwjgl(): + if has_split_natives: # implies lwjgl3 + bucket = add_or_get_bucket(buckets, None) + is_lwjgl_3 = True + found_any_lwjgl3 = True + bucket.version = specifier.version + if not bucket.libraries: + bucket.libraries = [] + bucket.libraries.append(lib) + bucket.release_time = v.release_time + else: + rules = None + if lib.rules: + rules = lib.rules + lib.rules = None + if is_macos_only(rules): + print( + "Candidate library ", + specifier, + " is only for macOS and is therefore ignored.", + ) + continue + bucket = add_or_get_bucket(buckets, rules) + if ( + specifier.group == "org.lwjgl.lwjgl" + and specifier.artifact == "lwjgl" + ): + bucket.version = specifier.version + if specifier.group == "org.lwjgl" and specifier.artifact == "lwjgl": + is_lwjgl_3 = True + found_any_lwjgl3 = True + bucket.version = specifier.version + if not bucket.libraries: + bucket.libraries = [] + bucket.libraries.append(lib) + bucket.release_time = v.release_time + # FIXME: workaround for insane log4j nonsense from December 2021. Probably needs adjustment. + elif lib.name.is_log4j(): + version_override, maven_override = map_log4j_artifact(lib.name.version) + + if version_override and maven_override: + if version_override not in LOG4J_HASHES: + raise Exception( + "ERROR: unhandled log4j version (overriden) %s!" + % version_override + ) + + if lib.name.artifact not in LOG4J_HASHES[version_override]: + raise Exception( + "ERROR: unhandled log4j artifact %s!" % lib.name.artifact + ) + + replacement_name = GradleSpecifier( + "org.apache.logging.log4j", lib.name.artifact, version_override + ) + artifact = MojangArtifact( + url=maven_override % (replacement_name.path()), + sha1=LOG4J_HASHES[version_override][lib.name.artifact]["sha1"], + size=LOG4J_HASHES[version_override][lib.name.artifact]["size"], + ) + + libs_minecraft.append( + Library( + name=replacement_name, + downloads=MojangLibraryDownloads(artifact=artifact), + ) + ) + else: + libs_minecraft.append(lib) + else: + new_libs_minecraft += patch_library(lib, library_patches) + libs_minecraft.append(lib) + if len(buckets) == 1: + for key in buckets: + lwjgl = buckets[key] + lwjgl.libraries = sorted(lwjgl.libraries, key=attrgetter("name")) + add_lwjgl_version(lwjglVersionVariants, lwjgl) + print("Found only candidate LWJGL", lwjgl.version, key) + else: + # multiple buckets for LWJGL. [None] is common to all, other keys are for different sets of rules + for key in buckets: + if key is None: + continue + lwjgl = buckets[key] + if None in buckets: + lwjgl.libraries = sorted( + lwjgl.libraries + buckets[None].libraries, + key=attrgetter("name"), + ) + else: + lwjgl.libraries = sorted(lwjgl.libraries, key=attrgetter("name")) + add_lwjgl_version(lwjglVersionVariants, lwjgl) + print("Found candidate LWJGL", lwjgl.version, key) + # remove the common bucket... + if None in buckets: + del buckets[None] + v.libraries = libs_minecraft + list(dict.fromkeys(new_libs_minecraft)) + + if is_lwjgl_3: + lwjgl_dependency = Dependency(uid=LWJGL3_COMPONENT) + else: + lwjgl_dependency = Dependency(uid=LWJGL_COMPONENT) + if len(buckets) == 1: + suggested_version = next(iter(buckets.values())).version + if is_lwjgl_3: + lwjgl_dependency.suggests = suggested_version + else: + lwjgl_dependency.suggests = "2.9.4-nightly-20150209" + else: + bad_versions = {"3.1.6", "3.2.1"} + our_versions = set() + + for lwjgl in iter(buckets.values()): + our_versions = our_versions.union({lwjgl.version}) + + if our_versions == bad_versions: + print("Found broken 3.1.6/3.2.1 combo, forcing LWJGL to 3.2.1") + suggested_version = "3.2.1" + lwjgl_dependency.suggests = suggested_version + else: + raise Exception( + "ERROR: cannot determine single suggested LWJGL version in %s" + % mojang_version.id + ) + + # if it uses LWJGL 3, add the trait that enables starting on first thread on macOS + if is_lwjgl_3: + if not v.additional_traits: + v.additional_traits = [] + v.additional_traits.append("FirstThreadOnMacOS") + v.requires = [lwjgl_dependency] + v.order = -2 + # process 1.13 arguments into previous version + if not mojang_version.minecraft_arguments and mojang_version.arguments: + v.minecraft_arguments = adapt_new_style_arguments(mojang_version.arguments) + if not v.additional_traits: + v.additional_traits = [] + v.additional_traits.extend( + adapt_new_style_arguments_to_traits(mojang_version.arguments) + ) + out_filename = os.path.join( + LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{v.version}.json" + ) + if v.version in override_index.versions: + override = override_index.versions[v.version] + override.apply_onto_meta_version(v) + if v.version in legacy_services: + if v.additional_traits == None: + v.additional_traits = [] + v.additional_traits.append("legacyServices") + + # 13w16a-13w23a require legacyLaunch and those + 13w23b require texturepacks + if re.match(r"13w[1,2]\d[a-c]", v.version) and 16 <= int(v.version[3:-1]) <= 23: + if v.additional_traits == None: + v.additional_traits = [] + if v.version != "13w23b": + v.additional_traits.append("legacyLaunch") + v.additional_traits.append("texturepacks") + + v.write(out_filename) + + for lwjglVersionVariant in lwjglVersionVariants: + decided_variant = None + passed_variants = 0 + unknown_variants = 0 + print( + "%d variant(s) for LWJGL %s:" + % (len(lwjglVersionVariants[lwjglVersionVariant]), lwjglVersionVariant) + ) + + for variant in lwjglVersionVariants[lwjglVersionVariant]: + if variant.sha1 in BAD_VARIANTS: + print("Variant %s ignored because it's marked as bad." % variant.sha1) + continue + if variant.sha1 in PASS_VARIANTS: + print("Variant %s accepted." % variant.sha1) + decided_variant = variant + passed_variants += 1 + continue + # print natives classifiers to decide which variant to use + n = [ + x.natives.keys() + for x in variant.version.libraries + if x.natives is not None + ] + print(n) + + print( + f' "{variant.sha1}", # {lwjglVersionVariant} ({variant.version.release_time})' + ) + unknown_variants += 1 + print("") + + if decided_variant and passed_variants == 1 and unknown_variants == 0: + process_single_variant(decided_variant.version, library_patches) + else: + raise Exception( + "No variant decided for version %s out of %d possible ones and %d unknown ones." + % (lwjglVersionVariant, passed_variants, unknown_variants) + ) + + lwjgl_package = MetaPackage(uid=LWJGL_COMPONENT, name="LWJGL 2") + lwjgl_package.write(os.path.join(LAUNCHER_DIR, LWJGL_COMPONENT, "package.json")) + + if found_any_lwjgl3: + lwjgl_package = MetaPackage(uid=LWJGL3_COMPONENT, name="LWJGL 3") + lwjgl_package.write( + os.path.join(LAUNCHER_DIR, LWJGL3_COMPONENT, "package.json") + ) + + mojang_index = MojangIndexWrap( + MojangIndex.parse_file(os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_FILE)) + ) + + minecraft_package = MetaPackage(uid=MINECRAFT_COMPONENT, name="Minecraft") + minecraft_package.recommended = [mojang_index.latest.release] + minecraft_package.write( + os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, "package.json") + ) + + +if __name__ == "__main__": + main() diff --git a/meta/meta/run/generate_neoforge.py b/meta/meta/run/generate_neoforge.py new file mode 100644 index 0000000000..de32256869 --- /dev/null +++ b/meta/meta/run/generate_neoforge.py @@ -0,0 +1,170 @@ +from copy import deepcopy +import os +import re +from operator import attrgetter +from typing import Collection + +from meta.common import ensure_component_dir, launcher_path, upstream_path, eprint +from meta.common.neoforge import ( + NEOFORGE_COMPONENT, + INSTALLER_MANIFEST_DIR, + VERSION_MANIFEST_DIR, + DERIVED_INDEX_FILE, + INSTALLER_INFO_DIR, +) +from meta.common.forge import FORGEWRAPPER_LIBRARY +from meta.common.mojang import MINECRAFT_COMPONENT +from meta.model import ( + MetaVersion, + Dependency, + Library, + GradleSpecifier, + MojangLibraryDownloads, + MojangArtifact, + MetaPackage, +) +from meta.model.neoforge import ( + NeoForgeVersion, + NeoForgeInstallerProfileV2, + InstallerInfo, + DerivedNeoForgeIndex, +) +from meta.model.mojang import MojangVersion + +LAUNCHER_DIR = launcher_path() +UPSTREAM_DIR = upstream_path() + +ensure_component_dir(NEOFORGE_COMPONENT) + + +def version_from_build_system_installer( + installer: MojangVersion, + profile: NeoForgeInstallerProfileV2, + version: NeoForgeVersion, +) -> MetaVersion: + v = MetaVersion(name="NeoForge", version=version.rawVersion, uid=NEOFORGE_COMPONENT) + v.main_class = "io.github.zekerzhayard.forgewrapper.installer.Main" + + # FIXME: Add the size and hash here + v.maven_files = [] + + # load the locally cached installer file info and use it to add the installer entry in the json + info = InstallerInfo.parse_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version.long_version}.json") + ) + installer_lib = Library( + name=GradleSpecifier( + "net.neoforged", version.artifact, version.long_version, "installer" + ) + ) + installer_lib.downloads = MojangLibraryDownloads() + installer_lib.downloads.artifact = MojangArtifact( + url="https://maven.neoforged.net/releases/%s" % (installer_lib.name.path()), + sha1=info.sha1hash, + size=info.size, + ) + v.maven_files.append(installer_lib) + + for forge_lib in profile.libraries: + if forge_lib.name.is_log4j(): + continue + + v.maven_files.append(forge_lib) + + v.libraries = [] + + v.libraries.append(FORGEWRAPPER_LIBRARY) + + for forge_lib in installer.libraries: + if forge_lib.name.is_log4j(): + continue + + v.libraries.append(forge_lib) + + v.release_time = installer.release_time + v.order = 5 + mc_args = ( + "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} " + "--assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} " + "--accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}" + ) + for arg in installer.arguments.game: + mc_args += f" {arg}" + v.minecraft_arguments = mc_args + return v + + +def main(): + # load the locally cached version list + remote_versions = DerivedNeoForgeIndex.parse_file( + os.path.join(UPSTREAM_DIR, DERIVED_INDEX_FILE) + ) + recommended_versions = [] + + for key, entry in remote_versions.versions.items(): + version = NeoForgeVersion(entry) + + if version.url() is None: + eprint("Skipping %s with no valid files" % key) + continue + eprint("Processing NeoForge %s" % version.rawVersion) + version_elements = version.rawVersion.split(".") + if len(version_elements) < 1: + eprint("Skipping version %s with not enough version elements" % key) + continue + + major_version_str = version_elements[0] + if not major_version_str.isnumeric(): + eprint( + "Skipping version %s with non-numeric major version %s" + % (key, major_version_str) + ) + continue + + if entry.recommended: + recommended_versions.append(version.rawVersion) + + # Path for new-style build system based installers + installer_version_filepath = os.path.join( + UPSTREAM_DIR, VERSION_MANIFEST_DIR, f"{version.long_version}.json" + ) + profile_filepath = os.path.join( + UPSTREAM_DIR, INSTALLER_MANIFEST_DIR, f"{version.long_version}.json" + ) + + eprint(installer_version_filepath) + assert os.path.isfile( + installer_version_filepath + ), f"version {installer_version_filepath} does not have installer version manifest" + installer = MojangVersion.parse_file(installer_version_filepath) + profile = NeoForgeInstallerProfileV2.parse_file(profile_filepath) + v = version_from_build_system_installer(installer, profile, version) + + # we can get the minecraft version from the profile json info, so let's just do that instead of hacky regex + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=profile.minecraft)] + # If we do not have the corresponding Minecraft version, we ignore it + if not os.path.isfile( + os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{profile.minecraft}.json") + ): + eprint( + "Skipping %s with no corresponding Minecraft version %s" + % (key, profile.minecraft) + ) + continue + v.write(os.path.join(LAUNCHER_DIR, NEOFORGE_COMPONENT, f"{v.version}.json")) + + recommended_versions.sort() + + print("Recommended versions:", recommended_versions) + + package = MetaPackage( + uid=NEOFORGE_COMPONENT, + name="NeoForge", + project_url="https://neoforged.net", + ) + package.recommended = recommended_versions + package.write(os.path.join(LAUNCHER_DIR, NEOFORGE_COMPONENT, "package.json")) + + +if __name__ == "__main__": + main() diff --git a/meta/meta/run/generate_quilt.py b/meta/meta/run/generate_quilt.py new file mode 100755 index 0000000000..01964d5864 --- /dev/null +++ b/meta/meta/run/generate_quilt.py @@ -0,0 +1,176 @@ +import json +import os +import sys + +from meta.common import ( + ensure_component_dir, + launcher_path, + upstream_path, + transform_maven_key, +) +from meta.common.quilt import ( + JARS_DIR, + INSTALLER_INFO_DIR, + META_DIR, + INTERMEDIARY_COMPONENT, + LOADER_COMPONENT, + USE_QUILT_MAPPINGS, + DISABLE_BEACON_ARG, + DISABLE_BEACON_VERSIONS, +) +from meta.model import MetaVersion, Dependency, Library, MetaPackage, GradleSpecifier +from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses + +LAUNCHER_DIR = launcher_path() +UPSTREAM_DIR = upstream_path() + +ensure_component_dir(LOADER_COMPONENT) +ensure_component_dir(INTERMEDIARY_COMPONENT) + + +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + + +def load_jar_info(artifact_key) -> FabricJarInfo: + return FabricJarInfo.parse_file( + os.path.join(UPSTREAM_DIR, JARS_DIR, f"{artifact_key}.json") + ) + + +def load_installer_info(version) -> FabricInstallerDataV1: + return FabricInstallerDataV1.parse_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version}.json") + ) + + +def process_loader_version(entry) -> (MetaVersion, bool): + should_recommend = ( + "-" not in entry["version"] + ) # Don't recommend pre releases as per SemVer + + jar_info = load_jar_info(transform_maven_key(entry["maven"])) + installer_info = load_installer_info(entry["version"]) + + v = MetaVersion(name="Quilt Loader", uid=LOADER_COMPONENT, version=entry["version"]) + v.release_time = jar_info.release_time + v.requires = [Dependency(uid=INTERMEDIARY_COMPONENT)] + v.order = 10 + v.type = "release" + if isinstance(installer_info.main_class, FabricMainClasses): + v.main_class = installer_info.main_class.client + else: + v.main_class = installer_info.main_class + v.libraries = [] + v.libraries.extend(installer_info.libraries.common) + v.libraries.extend(installer_info.libraries.client) + loader_lib = Library( + name=GradleSpecifier.from_string(entry["maven"]), + url="https://maven.quiltmc.org/repository/release", + ) + v.libraries.append(loader_lib) + + if entry["version"] in DISABLE_BEACON_VERSIONS: + if not v.additional_jvm_args: + v.additional_jvm_args = [] + v.additional_jvm_args.append(DISABLE_BEACON_ARG) + + return v, should_recommend + + +def process_intermediary_version(entry) -> MetaVersion: + jar_info = load_jar_info(transform_maven_key(entry["maven"])) + + v = MetaVersion( + name="Quilt Intermediary Mappings", + uid=INTERMEDIARY_COMPONENT, + version=entry["version"], + ) + v.release_time = jar_info.release_time + v.requires = [Dependency(uid="net.minecraft", equals=entry["version"])] + v.order = 11 + v.type = "release" + v.libraries = [] + v.volatile = True + intermediary_lib = Library( + name=GradleSpecifier.from_string(entry["maven"]), + url="https://maven.quiltmc.org/repository/release", + ) + v.libraries.append(intermediary_lib) + return v + + +def main(): + recommended_loader_versions = [] + recommended_intermediary_versions = [] + + with open( + os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), "r", encoding="utf-8" + ) as f: + loader_version_index = json.load(f) + for entry in loader_version_index: + version = entry["version"] + print(f"Processing loader {version}") + try: + v, should_recommend = process_loader_version(entry) + + if ( + not recommended_loader_versions and should_recommend + ): # newest stable loader is recommended + recommended_loader_versions.append(version) + + v.write( + os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, f"{v.version}.json") + ) + except Exception as e: + eprint("Failed to download %s" % version) + eprint("Error is %s" % e) + continue + + if USE_QUILT_MAPPINGS: + with open( + os.path.join(UPSTREAM_DIR, META_DIR, "hashed.json"), "r", encoding="utf-8" + ) as f: + intermediary_version_index = json.load(f) + for entry in intermediary_version_index: + version = entry["version"] + print(f"Processing intermediary {version}") + + try: + v = process_intermediary_version(entry) + + recommended_intermediary_versions.append( + version + ) # all intermediaries are recommended + + v.write( + os.path.join( + LAUNCHER_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json" + ) + ) + except Exception as e: + eprint("Failed to download %s" % version) + eprint("Error is %s" % e) + continue + package = MetaPackage(uid=LOADER_COMPONENT, name="Quilt Loader") + package.recommended = recommended_loader_versions + package.description = "The Quilt project is an open, community-driven modding toolchain designed primarily for Minecraft." + package.project_url = "https://quiltmc.org/" + package.authors = ["Quilt Project"] + package.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, "package.json")) + + if USE_QUILT_MAPPINGS: + package = MetaPackage( + uid=INTERMEDIARY_COMPONENT, name="Quilt Intermediary Mappings" + ) + package.recommended = recommended_intermediary_versions + package.description = "Intermediary mappings allow using Quilt Loader with mods for Minecraft in a more compatible manner." + package.project_url = "https://quiltmc.org/" + package.authors = ["Quilt Project"] + package.write( + os.path.join(LAUNCHER_DIR, INTERMEDIARY_COMPONENT, "package.json") + ) + + +if __name__ == "__main__": + main() diff --git a/meta/meta/run/index.py b/meta/meta/run/index.py new file mode 100755 index 0000000000..22abea8457 --- /dev/null +++ b/meta/meta/run/index.py @@ -0,0 +1,71 @@ +import hashlib +import os +from operator import attrgetter + +from meta.common import launcher_path, file_hash + + +from meta.model import MetaVersion, MetaPackage +from meta.model.index import ( + MetaPackageIndex, + MetaVersionIndex, + MetaVersionIndexEntry, + MetaPackageIndexEntry, +) + +LAUNCHER_DIR = launcher_path() + + +# ignore these files when indexing versions +ignore = {"index.json", "package.json", ".git", ".github"} + +# initialize output structures - package list level +packages = MetaPackageIndex() + +# walk through all the package folders +for package in sorted(os.listdir(LAUNCHER_DIR)): + if package in ignore: + continue + + sharedData = MetaPackage.parse_file( + os.path.join(LAUNCHER_DIR, package, "package.json") + ) + recommendedVersions = set() + if sharedData.recommended: + recommendedVersions = set(sharedData.recommended) + + # initialize output structures - version list level + versionList = MetaVersionIndex(uid=package, name=sharedData.name) + + # walk through all the versions of the package + for filename in os.listdir(LAUNCHER_DIR + "/%s" % package): + if filename in ignore: + continue + # parse and hash the version file + filepath = LAUNCHER_DIR + "/%s/%s" % (package, filename) + filehash = file_hash(filepath, hashlib.sha256) + versionFile = MetaVersion.parse_file(filepath) + is_recommended = versionFile.version in recommendedVersions + + versionEntry = MetaVersionIndexEntry.from_meta_version( + versionFile, is_recommended, filehash + ) + + versionList.versions.append(versionEntry) + + # sort the versions in descending order by time of release + versionList.versions = sorted( + versionList.versions, key=attrgetter("release_time"), reverse=True + ) + + # write the version index for the package + outFilePath = LAUNCHER_DIR + "/%s/index.json" % package + versionList.write(outFilePath) + + # insert entry into the package index + packageEntry = MetaPackageIndexEntry( + uid=package, name=sharedData.name, sha256=file_hash(outFilePath, hashlib.sha256) + ) + packages.packages.append(packageEntry) + +packages.write(os.path.join(LAUNCHER_DIR, "index.json")) diff --git a/meta/meta/run/update_fabric.py b/meta/meta/run/update_fabric.py new file mode 100755 index 0000000000..d19540b5e4 --- /dev/null +++ b/meta/meta/run/update_fabric.py @@ -0,0 +1,133 @@ +from collections import deque +from multiprocessing import Pool +import json +import os +import zipfile +from datetime import datetime + +import requests + +from meta.common import ( + upstream_path, + ensure_upstream_dir, + transform_maven_key, + default_session, +) +from meta.common.fabric import ( + JARS_DIR, + INSTALLER_INFO_DIR, + META_DIR, + DATETIME_FORMAT_HTTP, +) +from meta.model.fabric import FabricJarInfo + +UPSTREAM_DIR = upstream_path() + +ensure_upstream_dir(JARS_DIR) +ensure_upstream_dir(INSTALLER_INFO_DIR) +ensure_upstream_dir(META_DIR) + +sess = default_session() + + +def get_maven_url(maven_key, server, ext): + parts = maven_key.split(":", 3) + maven_ver_url = ( + server + parts[0].replace(".", "/") + "/" + parts[1] + "/" + parts[2] + "/" + ) + maven_url = maven_ver_url + parts[1] + "-" + parts[2] + ext + return maven_url + + +def get_json_file(path, url): + with open(path, "w", encoding="utf-8") as f: + r = sess.get(url) + r.raise_for_status() + version_json = r.json() + json.dump(version_json, f, sort_keys=True, indent=4) + return version_json + + +def head_file(url): + r = sess.head(url) + r.raise_for_status() + return r.headers + + +def get_binary_file(path, url): + r = sess.get(url) + r.raise_for_status() + with open(path, "wb") as f: + for chunk in r.iter_content(chunk_size=128): + f.write(chunk) + + +def compute_jar_file(path, url): + # These two approaches should result in the same metadata, except for the timestamp which might be a few minutes + # off for the fallback method + try: + # Let's not download a Jar file if we don't need to. + headers = head_file(url) + tstamp = datetime.strptime(headers["Last-Modified"], DATETIME_FORMAT_HTTP) + except requests.HTTPError: + # Just in case something changes in the future + print(f"Falling back to downloading jar for {url}") + + jar_path = path + ".jar" + get_binary_file(jar_path, url) + tstamp = datetime.fromtimestamp(0) + with zipfile.ZipFile(jar_path) as jar: + allinfo = jar.infolist() + for info in allinfo: + tstamp_new = datetime(*info.date_time) + if tstamp_new > tstamp: + tstamp = tstamp_new + + data = FabricJarInfo(release_time=tstamp) + data.write(path + ".json") + + +def compute_jar_file_concurrent(it): + print(f"Processing {it['version']} ") + jar_maven_url = get_maven_url(it["maven"], "https://maven.fabricmc.net/", ".jar") + compute_jar_file( + os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), + jar_maven_url, + ) + print(f"Processing {it['version']} Done") + + +def get_json_file_concurrent(it): + print(f"Downloading JAR info for loader {it['version']} ") + maven_url = get_maven_url(it["maven"], "https://maven.fabricmc.net/", ".json") + get_json_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{it['version']}.json"), + maven_url, + ) + print(f"Downloading JAR info for loader {it['version']} Done") + + +def main(): + # get the version list for each component we are interested in + for component in ["intermediary", "loader"]: + index = get_json_file( + os.path.join(UPSTREAM_DIR, META_DIR, f"{component}.json"), + "https://meta.fabricmc.net/v2/versions/" + component, + ) + with Pool(None) as pool: + deque(pool.imap_unordered(compute_jar_file_concurrent, index, 32), 0) + + # for each loader, download installer JSON file from maven + with open( + os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), "r", encoding="utf-8" + ) as loaderVersionIndexFile: + loader_version_index = json.load(loaderVersionIndexFile) + with Pool(None) as pool: + deque( + pool.imap_unordered(get_json_file_concurrent, loader_version_index, 32), + 0, + ) + + +if __name__ == "__main__": + main() diff --git a/meta/meta/run/update_forge.py b/meta/meta/run/update_forge.py new file mode 100755 index 0000000000..c74865b31f --- /dev/null +++ b/meta/meta/run/update_forge.py @@ -0,0 +1,419 @@ +""" +Get the source files necessary for generating Forge versions +""" + +import concurrent.futures +import copy +import hashlib +import json +import os +import re +import zipfile +from contextlib import suppress +from datetime import datetime +from pathlib import Path +from pprint import pprint + +from pydantic import ValidationError + +from meta.common import ( + upstream_path, + ensure_upstream_dir, + default_session, + remove_files, + eprint, + file_hash, + get_file_sha1_from_file, +) +from meta.common.forge import ( + JARS_DIR, + INSTALLER_INFO_DIR, + INSTALLER_MANIFEST_DIR, + VERSION_MANIFEST_DIR, + FILE_MANIFEST_DIR, + BAD_VERSIONS, + LEGACYINFO_FILE, +) +from meta.model.forge import ( + ForgeFile, + ForgeEntry, + ForgeMCVersionInfo, + ForgeLegacyInfoList, + DerivedForgeIndex, + ForgeVersion, + ForgeInstallerProfile, + ForgeInstallerProfileV2, + InstallerInfo, + ForgeLegacyInfo, +) +from meta.common.http import download_binary_file +from meta.model.mojang import MojangVersion + +UPSTREAM_DIR = upstream_path() + +ensure_upstream_dir(JARS_DIR) +ensure_upstream_dir(INSTALLER_INFO_DIR) +ensure_upstream_dir(INSTALLER_MANIFEST_DIR) +ensure_upstream_dir(VERSION_MANIFEST_DIR) +ensure_upstream_dir(FILE_MANIFEST_DIR) + +LEGACYINFO_PATH = os.path.join(UPSTREAM_DIR, LEGACYINFO_FILE) + +sess = default_session() + + +def get_single_forge_files_manifest(longversion): + print(f"Getting Forge manifest for {longversion}") + path_thing = UPSTREAM_DIR + "/forge/files_manifests/%s.json" % longversion + files_manifest_file = Path(path_thing) + from_file = False + if files_manifest_file.is_file(): + with open(path_thing, "r") as f: + files_json = json.load(f) + from_file = True + else: + file_url = ( + "https://files.minecraftforge.net/net/minecraftforge/forge/%s/meta.json" + % longversion + ) + r = sess.get(file_url) + r.raise_for_status() + files_json = r.json() + + ret_dict = dict() + + for classifier, extensionObj in files_json.get("classifiers").items(): + assert type(classifier) == str + assert type(extensionObj) == dict + + # assert len(extensionObj.items()) == 1 + index = 0 + count = 0 + while index < len(extensionObj.items()): + mutable_copy = copy.deepcopy(extensionObj) + extension, hashtype = mutable_copy.popitem() + if not type(classifier) == str: + pprint(classifier) + pprint(extensionObj) + if not type(hashtype) == str: + pprint(classifier) + pprint(extensionObj) + print( + "%s: Skipping missing hash for extension %s:" + % (longversion, extension) + ) + index += 1 + continue + assert type(classifier) == str + processed_hash = re.sub(r"\W", "", hashtype) + if not len(processed_hash) == 32: + print( + "%s: Skipping invalid hash for extension %s:" + % (longversion, extension) + ) + pprint(extensionObj) + index += 1 + continue + + file_obj = ForgeFile( + classifier=classifier, hash=processed_hash, extension=extension + ) + if count == 0: + ret_dict[classifier] = file_obj + index += 1 + count += 1 + else: + print( + "%s: Multiple objects detected for classifier %s:" + % (longversion, classifier) + ) + pprint(extensionObj) + assert False + + if not from_file: + with open(path_thing, "w", encoding="utf-8") as f: + json.dump(files_json, f, sort_keys=True, indent=4) + + return ret_dict + + +def process_forge_version(version, jar_path): + installer_info_path = ( + UPSTREAM_DIR + "/forge/installer_info/%s.json" % version.long_version + ) + profile_path = ( + UPSTREAM_DIR + "/forge/installer_manifests/%s.json" % version.long_version + ) + version_file_path = ( + UPSTREAM_DIR + "/forge/version_manifests/%s.json" % version.long_version + ) + + new_sha1 = None + sha1_file = jar_path + ".sha1" + fileSha1 = get_file_sha1_from_file(jar_path, sha1_file) + try: + rfile = sess.get(version.url() + ".sha1") + rfile.raise_for_status() + new_sha1 = rfile.text.strip() + if fileSha1 != new_sha1: + remove_files([jar_path, profile_path, installer_info_path, sha1_file]) + except Exception as e: + eprint("Failed to check sha1 %s" % version.url()) + eprint("Error is %s" % e) + + installer_refresh_required = not os.path.isfile(profile_path) or not os.path.isfile( + installer_info_path + ) + + if installer_refresh_required: + # grab the installer if it's not there + if not os.path.isfile(jar_path): + eprint("Downloading %s" % version.url()) + download_binary_file(sess, jar_path, version.url()) + if new_sha1 is None: + try: + rfile = sess.get(version.url() + ".sha1") + rfile.raise_for_status() + new_sha1 = rfile.text.strip() + except Exception as e: + eprint("Failed to download new sha1 %s" % version.url()) + eprint("Error is %s" % e) + if new_sha1 is not None: # this is in case the fetch failed + with open(sha1_file, "w") as file: + file.write(new_sha1) + + eprint("Processing %s" % version.url()) + # harvestables from the installer + if not os.path.isfile(profile_path): + print(jar_path) + with zipfile.ZipFile(jar_path) as jar: + with suppress(KeyError): + with jar.open("version.json") as profile_zip_entry: + version_data = profile_zip_entry.read() + + # Process: does it parse? + MojangVersion.parse_raw(version_data) + + with open(version_file_path, "wb") as versionJsonFile: + versionJsonFile.write(version_data) + versionJsonFile.close() + + with jar.open("install_profile.json") as profile_zip_entry: + install_profile_data = profile_zip_entry.read() + + # Process: does it parse? + is_parsable = False + exception = None + try: + ForgeInstallerProfile.parse_raw(install_profile_data) + is_parsable = True + except ValidationError as err: + exception = err + try: + ForgeInstallerProfileV2.parse_raw(install_profile_data) + is_parsable = True + except ValidationError as err: + exception = err + + if not is_parsable: + if version.is_supported(): + raise exception + else: + eprint( + "Version %s is not supported and won't be generated later." + % version.long_version + ) + + with open(profile_path, "wb") as profileFile: + profileFile.write(install_profile_data) + profileFile.close() + + # installer info v1 + if not os.path.isfile(installer_info_path): + installer_info = InstallerInfo() + installer_info.sha1hash = file_hash(jar_path, hashlib.sha1) + installer_info.sha256hash = file_hash(jar_path, hashlib.sha256) + installer_info.size = os.path.getsize(jar_path) + installer_info.write(installer_info_path) + + +def main(): + # get the remote version list fragments + r = sess.get( + "https://files.minecraftforge.net/net/minecraftforge/forge/maven-metadata.json" + ) + r.raise_for_status() + main_json = r.json() + assert type(main_json) == dict + + r = sess.get( + "https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json" + ) + r.raise_for_status() + promotions_json = r.json() + assert type(promotions_json) == dict + + promoted_key_expression = re.compile( + "(?P<mc>[^-]+)-(?P<promotion>(latest)|(recommended))(-(?P<branch>[a-zA-Z0-9\\.]+))?" + ) + + recommended_set = set() + + new_index = DerivedForgeIndex() + + # FIXME: does not fully validate that the file has not changed format + # NOTE: For some insane reason, the format of the versions here is special. It having a branch at the end means it + # affects that particular branch. + # We don't care about Forge having branches. + # Therefore we only use the short version part for later identification and filter out the branch-specific + # promotions (among other errors). + print("Processing promotions:") + for promoKey, shortversion in promotions_json.get("promos").items(): + match = promoted_key_expression.match(promoKey) + if not match: + print("Skipping promotion %s, the key did not parse:" % promoKey) + pprint(promoKey) + assert match + if not match.group("mc"): + print( + "Skipping promotion %s, because it has no Minecraft version." % promoKey + ) + continue + if match.group("branch"): + print("Skipping promotion %s, because it on a branch only." % promoKey) + continue + elif match.group("promotion") == "recommended": + recommended_set.add(shortversion) + print("%s added to recommended set" % shortversion) + elif match.group("promotion") == "latest": + pass + else: + assert False + + version_expression = re.compile( + "^(?P<mc>[0-9a-zA-Z_\\.]+)-(?P<ver>[0-9\\.]+\\.(?P<build>[0-9]+))(-(?P<branch>[a-zA-Z0-9\\.]+))?$" + ) + + print("") + print("Processing versions:") + for mc_version, value in main_json.items(): + assert type(mc_version) == str + assert type(value) == list + for long_version in value: + assert type(long_version) == str + match = version_expression.match(long_version) + if not match: + pprint(long_version) + assert match + assert match.group("mc") == mc_version + + files = get_single_forge_files_manifest(long_version) + + build = int(match.group("build")) + version = match.group("ver") + branch = match.group("branch") + + is_recommended = version in recommended_set + + entry = ForgeEntry( + long_version=long_version, + mc_version=mc_version, + version=version, + build=build, + branch=branch, + # NOTE: we add this later after the fact. The forge promotions file lies about these. + latest=False, + recommended=is_recommended, + files=files, + ) + new_index.versions[long_version] = entry + if not new_index.by_mc_version: + new_index.by_mc_version = dict() + if mc_version not in new_index.by_mc_version: + new_index.by_mc_version.setdefault(mc_version, ForgeMCVersionInfo()) + new_index.by_mc_version[mc_version].versions.append(long_version) + # NOTE: we add this later after the fact. The forge promotions file lies about these. + # if entry.latest: + # new_index.by_mc_version[mc_version].latest = long_version + if entry.recommended: + new_index.by_mc_version[mc_version].recommended = long_version + + print("") + print("Post processing promotions and adding missing 'latest':") + for mc_version, info in new_index.by_mc_version.items(): + latest_version = info.versions[-1] + info.latest = latest_version + new_index.versions[latest_version].latest = True + print("Added %s as latest for %s" % (latest_version, mc_version)) + + print("") + print("Dumping index files...") + + with open(UPSTREAM_DIR + "/forge/maven-metadata.json", "w", encoding="utf-8") as f: + json.dump(main_json, f, sort_keys=True, indent=4) + + with open(UPSTREAM_DIR + "/forge/promotions_slim.json", "w", encoding="utf-8") as f: + json.dump(promotions_json, f, sort_keys=True, indent=4) + + new_index.write(UPSTREAM_DIR + "/forge/derived_index.json") + + legacy_info_list = ForgeLegacyInfoList() + + print("Grabbing installers and dumping installer profiles...") + # get the installer jars - if needed - and get the installer profiles out of them + with concurrent.futures.ThreadPoolExecutor() as executor: + futures = [] + for key, entry in new_index.versions.items(): + eprint("Updating Forge %s" % key) + if entry.mc_version is None: + eprint("Skipping %d with invalid MC version" % entry.build) + continue + + version = ForgeVersion(entry) + if version.url() is None: + eprint("Skipping %d with no valid files" % version.build) + continue + if version.long_version in BAD_VERSIONS: + eprint(f"Skipping bad version {version.long_version}") + continue + + jar_path = os.path.join(UPSTREAM_DIR, JARS_DIR, version.filename()) + + if version.uses_installer(): + futures.append( + executor.submit(process_forge_version, version, jar_path) + ) + else: + # ignore the two versions without install manifests and jar mod class files + # TODO: fix those versions? + if version.mc_version_sane == "1.6.1": + continue + + # only gather legacy info if it's missing + if not os.path.isfile(LEGACYINFO_PATH): + # grab the jar/zip if it's not there + if not os.path.isfile(jar_path): + download_binary_file(sess, jar_path, version.url()) + # find the latest timestamp in the zip file + tstamp = datetime.fromtimestamp(0) + with zipfile.ZipFile(jar_path) as jar: + for info in jar.infolist(): + tstamp_new = datetime(*info.date_time) + if tstamp_new > tstamp: + tstamp = tstamp_new + legacy_info = ForgeLegacyInfo() + legacy_info.release_time = tstamp + legacy_info.sha1 = file_hash(jar_path, hashlib.sha1) + legacy_info.sha256 = file_hash(jar_path, hashlib.sha256) + legacy_info.size = os.path.getsize(jar_path) + legacy_info_list.number[key] = legacy_info + for f in futures: + f.result() + + # only write legacy info if it's missing + if not os.path.isfile(LEGACYINFO_PATH): + legacy_info_list.write(LEGACYINFO_PATH) + + +if __name__ == "__main__": + main() diff --git a/meta/meta/run/update_java.py b/meta/meta/run/update_java.py new file mode 100644 index 0000000000..80ca7b4a70 --- /dev/null +++ b/meta/meta/run/update_java.py @@ -0,0 +1,222 @@ +import os + +from meta.common import upstream_path, ensure_upstream_dir, default_session +from meta.common.java import ( + BASE_DIR, + ADOPTIUM_DIR, + OPENJ9_DIR, + AZUL_DIR, + ADOPTIUM_VERSIONS_DIR, + OPENJ9_VERSIONS_DIR, + AZUL_VERSIONS_DIR, +) +from meta.model.java import ( + ADOPTIUM_API_BASE, + OPENJ9_API_BASE, + ADOPTX_API_AVAILABLE_RELEASES, + adoptxAPIFeatureReleasesUrl, + adoptiumAPIFeatureReleasesUrl, + openj9APIFeatureReleasesUrl, + AdoptxJvmImpl, + AdoptxVendor, + AdoptxImageType, + AdoptxAPIFeatureReleasesQuery, + AdoptxAvailableReleases, + AdoptxRelease, + AdoptxReleases, + azulApiPackagesUrl, + AzulApiPackagesQuery, + ZuluPackage, + ZuluPackageList, + AzulArchiveType, + AzulReleaseStatus, + AzulAvailabilityType, + AzulJavaPackageType, + azulApiPackageDetailUrl, + ZuluPackageDetail, + ZuluPackagesDetail, +) + +UPSTREAM_DIR = upstream_path() + +ensure_upstream_dir(BASE_DIR) +ensure_upstream_dir(ADOPTIUM_DIR) +ensure_upstream_dir(OPENJ9_DIR) +ensure_upstream_dir(AZUL_DIR) +ensure_upstream_dir(ADOPTIUM_VERSIONS_DIR) +ensure_upstream_dir(OPENJ9_VERSIONS_DIR) +ensure_upstream_dir(AZUL_VERSIONS_DIR) + + +sess = default_session() + + +def main(): + print("Getting Adoptium Release Manifests ") + r = sess.get(ADOPTX_API_AVAILABLE_RELEASES.format(base_url=ADOPTIUM_API_BASE)) + r.raise_for_status() + + available = AdoptxAvailableReleases(**r.json()) + + available_releases_file = os.path.join( + UPSTREAM_DIR, ADOPTIUM_DIR, "available_releases.json" + ) + available.write(available_releases_file) + + for feature in available.available_releases: + print("Getting Manifests for Adoptium feature release:", feature) + + page_size = 10 + + releases_for_feature: list[AdoptxRelease] = [] + page = 0 + while True: + query = AdoptxAPIFeatureReleasesQuery( + image_type=AdoptxImageType.Jre, + page_size=page_size, + page=page, + jvm_impl=AdoptxJvmImpl.Hotspot, + vendor=AdoptxVendor.Eclipse, + ) + api_call = adoptiumAPIFeatureReleasesUrl(feature, query=query) + print("Fetching JRE Page:", page, api_call) + r_rls = sess.get(api_call) + if r_rls.status_code == 404: + break + else: + r_rls.raise_for_status() + + releases = list(AdoptxRelease(**rls) for rls in r_rls.json()) + releases_for_feature.extend(releases) + + if len(r_rls.json()) < page_size: + break + page += 1 + + print("Total Adoptium releases for feature:", len(releases_for_feature)) + releases = AdoptxReleases(__root__=releases_for_feature) + feature_file = os.path.join( + UPSTREAM_DIR, ADOPTIUM_VERSIONS_DIR, f"java{feature}.json" + ) + releases.write(feature_file) + + print("Getting OpenJ9 Release Manifests ") + r = sess.get(ADOPTX_API_AVAILABLE_RELEASES.format(base_url=OPENJ9_API_BASE)) + r.raise_for_status() + + available = AdoptxAvailableReleases(**r.json()) + + available_releases_file = os.path.join( + UPSTREAM_DIR, OPENJ9_DIR, "available_releases.json" + ) + available.write(available_releases_file) + + for feature in available.available_releases: + print("Getting Manifests for OpenJ9 feature release:", feature) + + page_size = 10 + + releases_for_feature: list[AdoptxRelease] = [] + page = 0 + while True: + query = AdoptxAPIFeatureReleasesQuery( + image_type=AdoptxImageType.Jre, + page_size=page_size, + page=page, + jvm_impl=AdoptxJvmImpl.OpenJ9, + vendor=AdoptxVendor.Ibm, + ) + api_call = openj9APIFeatureReleasesUrl(feature, query=query) + print("Fetching JRE Page:", page, api_call) + r_rls = sess.get(api_call) + if r_rls.status_code == 404: + break + else: + r_rls.raise_for_status() + + releases = list(AdoptxRelease(**rls) for rls in r_rls.json()) + releases_for_feature.extend(releases) + + if len(r_rls.json()) < page_size: + break + page += 1 + + print("Total OpenJ9 releases for feature:", len(releases_for_feature)) + releases = AdoptxReleases(__root__=releases_for_feature) + if len(releases_for_feature) == 0: + continue + feature_file = os.path.join( + UPSTREAM_DIR, OPENJ9_VERSIONS_DIR, f"java{feature}.json" + ) + releases.write(feature_file) + + print("Getting Azul Release Manifests") + zulu_packages: list[ZuluPackage] = [] + page = 1 + page_size = 100 + while True: + + query = AzulApiPackagesQuery( + archive_type=AzulArchiveType.Zip, + release_status=AzulReleaseStatus.Ga, + availability_types=[AzulAvailabilityType.CA], + java_package_type=AzulJavaPackageType.Jre, + javafx_bundled=False, + latest=True, + page=page, + page_size=page_size, + ) + api_call = azulApiPackagesUrl(query=query) + + print("Processing Page:", page, api_call) + + r = sess.get(api_call) + if r.status_code == 404: + break + else: + r.raise_for_status() + + packages = list(ZuluPackage(**pkg) for pkg in r.json()) + zulu_packages.extend(packages) + if len(packages) < page_size: + break + page += 1 + + print("Total Azul Packages:", len(zulu_packages)) + packages = ZuluPackageList(__root__=zulu_packages) + azul_manifest_file = os.path.join(UPSTREAM_DIR, AZUL_DIR, "packages.json") + packages.write(azul_manifest_file) + + azul_major_versions: dict[int, ZuluPackagesDetail] = {} + + for _, pkg in packages: + + major_version = pkg.java_version[0] + if major_version not in azul_major_versions: + azul_major_versions[major_version] = ZuluPackagesDetail(__root__=[]) + + pkg_file = os.path.join( + UPSTREAM_DIR, AZUL_VERSIONS_DIR, f"{pkg.package_uuid}.json" + ) + if os.path.exists(pkg_file) and os.path.isfile(pkg_file): + pkg_detail = ZuluPackageDetail.parse_file(pkg_file) + azul_major_versions[major_version].append(pkg_detail) + else: + + api_call = azulApiPackageDetailUrl(pkg.package_uuid) + print("Fetching Azul package manifest:", pkg.package_uuid) + r_pkg = sess.get(api_call) + r_pkg.raise_for_status() + + pkg_detail = ZuluPackageDetail(**r_pkg.json()) + pkg_detail.write(pkg_file) + azul_major_versions[major_version].append(pkg_detail) + + for major in azul_major_versions: + major_file = os.path.join(UPSTREAM_DIR, AZUL_VERSIONS_DIR, f"java{major}.json") + azul_major_versions[major].write(major_file) + + +if __name__ == "__main__": + main() +# diff --git a/meta/meta/run/update_liteloader.py b/meta/meta/run/update_liteloader.py new file mode 100755 index 0000000000..383644754d --- /dev/null +++ b/meta/meta/run/update_liteloader.py @@ -0,0 +1,37 @@ +import json +import os + +from meta.common import upstream_path, ensure_upstream_dir, default_session +from meta.common.liteloader import VERSIONS_FILE, BASE_DIR +from meta.model.liteloader import LiteloaderIndex + +UPSTREAM_DIR = upstream_path() + +ensure_upstream_dir(BASE_DIR) + +sess = default_session() + + +def main(): + # get the remote version list + r = sess.get("http://dl.liteloader.com/versions/versions.json") + r.raise_for_status() + + # make sure it's JSON + main_json = r.json() + + # make sure we understand the schema + remote_versions = LiteloaderIndex.parse_obj(main_json) + parsed = remote_versions.json() + original = json.dumps(main_json, sort_keys=True, indent=4) + assert parsed == original + + print("Successfully parsed index") + print(f"Last updated {remote_versions.meta.updated}") + + # save the json it to file + remote_versions.write(os.path.join(UPSTREAM_DIR, VERSIONS_FILE)) + + +if __name__ == "__main__": + main() diff --git a/meta/meta/run/update_mojang.py b/meta/meta/run/update_mojang.py new file mode 100755 index 0000000000..c05b15ce46 --- /dev/null +++ b/meta/meta/run/update_mojang.py @@ -0,0 +1,199 @@ +import concurrent.futures +import json +import os +import zipfile + +from meta.common import upstream_path, ensure_upstream_dir, default_session +from meta.common.http import download_binary_file +from meta.common.mojang import ( + BASE_DIR, + VERSION_MANIFEST_FILE, + VERSIONS_DIR, + ASSETS_DIR, + STATIC_EXPERIMENTS_FILE, + STATIC_OLD_SNAPSHOTS_FILE, + JAVA_MANIFEST_FILE, +) +from meta.model.mojang import ( + MojangIndexWrap, + MojangIndex, + ExperimentIndex, + ExperimentIndexWrap, + OldSnapshotIndexWrap, + OldSnapshotIndex, + JavaIndex, +) + +UPSTREAM_DIR = upstream_path() + +ensure_upstream_dir(BASE_DIR) +ensure_upstream_dir(VERSIONS_DIR) +ensure_upstream_dir(ASSETS_DIR) + +sess = default_session() + + +def fetch_zipped_version(path, url): + zip_path = f"{path}.zip" + download_binary_file(sess, zip_path, url) + with zipfile.ZipFile(zip_path) as z: + for info in z.infolist(): + if info.filename.endswith(".json"): + print(f"Found {info.filename} as version json") + version_json = json.load(z.open(info)) + break + + assert version_json + + version_json["type"] = "experiment" + + with open(path, "w", encoding="utf-8") as f: + json.dump(version_json, f, sort_keys=True, indent=4) + + return version_json + + +def fetch_modified_version(path, version): + r = sess.get(version.url) + r.raise_for_status() + version_json = r.json() + + version_json["releaseTime"] = version_json["releaseTime"] + "T00:00:00+02:00" + version_json["time"] = version_json["releaseTime"] + + downloads = { + "client": {"url": version.jar, "sha1": version.sha1, "size": version.size} + } + + version_json["downloads"] = downloads + version_json["type"] = "old_snapshot" + + with open(path, "w", encoding="utf-8") as f: + json.dump(version_json, f, sort_keys=True, indent=4) + + return version_json + + +def fetch_version(path, url): + r = sess.get(url) + r.raise_for_status() + version_json = r.json() + + with open(path, "w", encoding="utf-8") as f: + json.dump(version_json, f, sort_keys=True, indent=4) + + return version_json + + +MOJANG_JAVA_URL = "https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json" + + +def update_javas(): + r = sess.get(MOJANG_JAVA_URL) + r.raise_for_status() + + remote_javas = JavaIndex(__root__=r.json()) + + java_manifest_path = os.path.join(UPSTREAM_DIR, JAVA_MANIFEST_FILE) + + remote_javas.write(java_manifest_path) + + +def fetch_version_concurrent(remote_versions, x): + version = remote_versions.versions[x] + print( + "Updating " + + version.id + + " to timestamp " + + version.release_time.strftime("%s") + ) + fetch_version(os.path.join(UPSTREAM_DIR, VERSIONS_DIR, f"{x}.json"), version.url) + + +def fetch_modified_version_concurrent(old_snapshots, x): + version = old_snapshots.versions[x] + old_snapshots_path = os.path.join(UPSTREAM_DIR, VERSIONS_DIR, f"{x}.json") + + print("Updating old snapshot " + version.id) + if not os.path.isfile(old_snapshots_path): + fetch_modified_version(old_snapshots_path, version) + else: + print("Already have old snapshot " + version.id) + + +def main(): + # get the remote version list + r = sess.get("https://piston-meta.mojang.com/mc/game/version_manifest_v2.json") + r.raise_for_status() + + remote_versions = MojangIndexWrap(MojangIndex(**r.json())) + remote_ids = set(remote_versions.versions.keys()) + + version_manifest_path = os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_FILE) + + if os.path.exists(version_manifest_path): + # get the local version list + current_versions = MojangIndexWrap( + MojangIndex.parse_file(version_manifest_path) + ) + local_ids = set(current_versions.versions.keys()) + + # versions not present locally but present remotely are new + pending_ids = remote_ids.difference(local_ids) + + for x in local_ids: + remote_version = remote_versions.versions[x] + local_version = current_versions.versions[x] + if remote_version.time > local_version.time: + pending_ids.add(x) + else: + pending_ids = remote_ids + + with concurrent.futures.ThreadPoolExecutor() as executor: + futures = [ + executor.submit(fetch_version_concurrent, remote_versions, x) + for x in pending_ids + ] + for f in futures: + f.result() + + # deal with experimental snapshots separately + if os.path.exists(STATIC_EXPERIMENTS_FILE): + experiments = ExperimentIndexWrap( + ExperimentIndex.parse_file(STATIC_EXPERIMENTS_FILE) + ) + experiment_ids = set(experiments.versions.keys()) + + for x in experiment_ids: + version = experiments.versions[x] + experiment_path = os.path.join(UPSTREAM_DIR, VERSIONS_DIR, f"{x}.json") + + print("Updating experiment " + version.id) + if not os.path.isfile(experiment_path): + fetch_zipped_version(experiment_path, version.url) + else: + print("Already have experiment " + version.id) + + # deal with old snapshots + if os.path.exists(STATIC_OLD_SNAPSHOTS_FILE): + old_snapshots = OldSnapshotIndexWrap( + OldSnapshotIndex.parse_file(STATIC_OLD_SNAPSHOTS_FILE) + ) + old_snapshots_ids = set(old_snapshots.versions.keys()) + + with concurrent.futures.ThreadPoolExecutor() as executor: + futures = [ + executor.submit(fetch_modified_version_concurrent, old_snapshots, x) + for x in old_snapshots_ids + ] + for f in futures: + f.result() + + remote_versions.index.write(version_manifest_path) + + print("Getting Mojang Java runtime manfest") + update_javas() + + +if __name__ == "__main__": + main() diff --git a/meta/meta/run/update_neoforge.py b/meta/meta/run/update_neoforge.py new file mode 100644 index 0000000000..9957aad1bd --- /dev/null +++ b/meta/meta/run/update_neoforge.py @@ -0,0 +1,317 @@ +""" +Get the source files necessary for generating Forge versions +""" + +import concurrent.futures +import copy +import hashlib +import json +import os +import re +import zipfile +from contextlib import suppress +from datetime import datetime +from pathlib import Path +from pprint import pprint +import urllib.parse + +from pydantic import ValidationError + +from meta.common import ( + upstream_path, + ensure_upstream_dir, + default_session, + remove_files, + eprint, + file_hash, + get_file_sha1_from_file, +) +from meta.common.http import download_binary_file +from meta.common.neoforge import ( + JARS_DIR, + INSTALLER_INFO_DIR, + INSTALLER_MANIFEST_DIR, + VERSION_MANIFEST_DIR, + FILE_MANIFEST_DIR, +) +from meta.model.neoforge import ( + NeoForgeFile, + NeoForgeEntry, + NeoForgeMCVersionInfo, + DerivedNeoForgeIndex, + NeoForgeVersion, + NeoForgeInstallerProfileV2, + InstallerInfo, +) +from meta.model.mojang import MojangVersion + +UPSTREAM_DIR = upstream_path() + +ensure_upstream_dir(JARS_DIR) +ensure_upstream_dir(INSTALLER_INFO_DIR) +ensure_upstream_dir(INSTALLER_MANIFEST_DIR) +ensure_upstream_dir(VERSION_MANIFEST_DIR) +ensure_upstream_dir(FILE_MANIFEST_DIR) + +sess = default_session() + + +def find_nth(haystack, needle, n): + start = haystack.find(needle) + while start >= 0 and n > 1: + start = haystack.find(needle, start + len(needle)) + n -= 1 + return start + + +def get_single_forge_files_manifest(longversion, artifact: str): + print(f"Getting NeoForge manifest for {longversion}") + path_thing = UPSTREAM_DIR + "/neoforge/files_manifests/%s.json" % longversion + files_manifest_file = Path(path_thing) + from_file = False + if files_manifest_file.is_file(): + with open(path_thing, "r") as f: + files_json = json.load(f) + from_file = True + else: + file_url = ( + f"https://maven.neoforged.net/api/maven/details/releases/net%2Fneoforged%2F{artifact}%2F" + + urllib.parse.quote(longversion) + ) + r = sess.get(file_url) + r.raise_for_status() + files_json = r.json() + + ret_dict = dict() + + for file in files_json.get("files"): + assert type(file) == dict + name = file["name"] + prefix = f"{artifact}-{longversion}" + assert name.startswith( + prefix + ), f"{longversion} classifier {name} doesn't start with {prefix}" + file_name = name[len(prefix) :] + if file_name.startswith("-"): + file_name = file_name[1:] + if file_name.startswith("."): + continue + + classifier, ext = os.path.splitext(file_name) + + if ext in [".md5", ".sha1", ".sha256", ".sha512"]: + continue + + # assert len(extensionObj.items()) == 1 + file_obj = NeoForgeFile( + artifact=artifact, classifier=classifier, extension=ext[1:] + ) + ret_dict[classifier] = file_obj + + if not from_file: + Path(path_thing).parent.mkdir(parents=True, exist_ok=True) + with open(path_thing, "w", encoding="utf-8") as f: + json.dump(files_json, f, sort_keys=True, indent=4) + + return ret_dict + + +def process_neoforge_version(key, entry): + eprint("Updating NeoForge %s" % key) + + version = NeoForgeVersion(entry) + if version.url() is None: + eprint("Skipping %d with no valid files" % version.build) + return + if not version.uses_installer(): + eprint(f"version {version.long_version} does not use installer") + return + + jar_path = os.path.join(UPSTREAM_DIR, JARS_DIR, version.filename()) + + installer_info_path = ( + UPSTREAM_DIR + "/neoforge/installer_info/%s.json" % version.long_version + ) + profile_path = ( + UPSTREAM_DIR + "/neoforge/installer_manifests/%s.json" % version.long_version + ) + version_file_path = ( + UPSTREAM_DIR + "/neoforge/version_manifests/%s.json" % version.long_version + ) + + new_sha1 = None + sha1_file = jar_path + ".sha1" + fileSha1 = get_file_sha1_from_file(jar_path, sha1_file) + try: + rfile = sess.get(version.url() + ".sha1") + rfile.raise_for_status() + new_sha1 = rfile.text.strip() + if fileSha1 != new_sha1: + remove_files([jar_path, profile_path, installer_info_path, sha1_file]) + except Exception as e: + eprint("Failed to check sha1 %s" % version.url()) + eprint("Error is %s" % e) + + installer_refresh_required = not os.path.isfile(profile_path) or not os.path.isfile( + installer_info_path + ) + + if installer_refresh_required: + # grab the installer if it's not there + if not os.path.isfile(jar_path): + eprint("Downloading %s" % version.url()) + try: + Path(jar_path).parent.mkdir(parents=True, exist_ok=True) + download_binary_file(sess, jar_path, version.url()) + except Exception as e: + eprint("Failed to download %s" % version.url()) + eprint("Error is %s" % e) + return + if new_sha1 is None: + try: + rfile = sess.get(version.url() + ".sha1") + rfile.raise_for_status() + new_sha1 = rfile.text.strip() + except Exception as e: + eprint("Failed to download new sha1 %s" % version.url()) + eprint("Error is %s" % e) + if new_sha1 is not None: # this is in case the fetch failed + with open(sha1_file, "w") as file: + file.write(new_sha1) + + eprint("Processing %s" % version.url()) + # harvestables from the installer + if not os.path.isfile(profile_path): + print(jar_path) + with zipfile.ZipFile(jar_path) as jar: + with suppress(KeyError): + with jar.open("version.json") as profile_zip_entry: + version_data = profile_zip_entry.read() + + # Process: does it parse? + MojangVersion.parse_raw(version_data) + + Path(version_file_path).parent.mkdir(parents=True, exist_ok=True) + with open(version_file_path, "wb") as versionJsonFile: + versionJsonFile.write(version_data) + versionJsonFile.close() + + with jar.open("install_profile.json") as profile_zip_entry: + install_profile_data = profile_zip_entry.read() + + # Process: does it parse? + is_parsable = False + exception = None + try: + NeoForgeInstallerProfileV2.parse_raw(install_profile_data) + is_parsable = True + except ValidationError as err: + exception = err + + if not is_parsable: + if version.is_supported(): + raise exception + else: + eprint( + "Version %s is not supported and won't be generated later." + % version.long_version + ) + + Path(profile_path).parent.mkdir(parents=True, exist_ok=True) + with open(profile_path, "wb") as profileFile: + profileFile.write(install_profile_data) + profileFile.close() + + # installer info v1 + if not os.path.isfile(installer_info_path): + installer_info = InstallerInfo() + installer_info.sha1hash = file_hash(jar_path, hashlib.sha1) + installer_info.sha256hash = file_hash(jar_path, hashlib.sha256) + installer_info.size = os.path.getsize(jar_path) + installer_info.write(installer_info_path) + + +def main(): + # get the 1.20.1 remote version list fragments + r = sess.get( + "https://maven.neoforged.net/api/maven/versions/releases/net%2Fneoforged%2Fforge" + ) + r.raise_for_status() + main_json = r.json()["versions"] + assert type(main_json) == list + + # get the new remote version list fragments + r = sess.get( + "https://maven.neoforged.net/api/maven/versions/releases/net%2Fneoforged%2Fneoforge" + ) + r.raise_for_status() + new_main_json = r.json()["versions"] + assert type(new_main_json) == list + + main_json += new_main_json + + new_index = DerivedNeoForgeIndex() + + # let's keep the regex here to remove the 1.20.1- + version_expression = re.compile( + r"^(?P<mc>[0-9a-zA-Z_\.]+)-(?P<ver>[0-9\.]+\.(?P<build>[0-9]+))(-(?P<branch>[a-zA-Z0-9\.]+))?$" + ) + + print("") + print("Processing versions:") + for long_version in main_json: + assert type(long_version) == str + + legacyMatch = version_expression.match(long_version) + if legacyMatch: + version = legacyMatch.group("ver") + artifact = "forge" + else: + version = long_version + artifact = "neoforge" + + try: + files = get_single_forge_files_manifest(long_version, artifact) + except: + continue + + # TODO: what *is* recommended? + is_recommended = False + + entry = NeoForgeEntry( + artifact=artifact, + long_version=long_version, + version=version, + # NOTE: we add this later after the fact. The forge promotions file lies about these. + latest=False, + recommended=is_recommended, + files=files, + ) + new_index.versions[long_version] = entry + + if entry.recommended: + new_index.recommended = long_version + + print("") + print("Dumping index files...") + + with open( + UPSTREAM_DIR + "/neoforge/maven-metadata.json", "w", encoding="utf-8" + ) as f: + json.dump(main_json, f, sort_keys=True, indent=4) + + new_index.write(UPSTREAM_DIR + "/neoforge/derived_index.json") + + print("Grabbing installers and dumping installer profiles...") + # get the installer jars - if needed - and get the installer profiles out of them + with concurrent.futures.ThreadPoolExecutor() as executor: + futures = [ + executor.submit(process_neoforge_version, key, entry) + for key, entry in new_index.versions.items() + ] + for f in futures: + f.result() + + +if __name__ == "__main__": + main() diff --git a/meta/meta/run/update_quilt.py b/meta/meta/run/update_quilt.py new file mode 100755 index 0000000000..e694fd7b46 --- /dev/null +++ b/meta/meta/run/update_quilt.py @@ -0,0 +1,131 @@ +import concurrent.futures +import json +import os +import zipfile +from datetime import datetime + +from meta.common import ( + upstream_path, + ensure_upstream_dir, + transform_maven_key, + default_session, +) +from meta.common.quilt import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, USE_QUILT_MAPPINGS +from meta.model.fabric import FabricJarInfo + +UPSTREAM_DIR = upstream_path() + +ensure_upstream_dir(JARS_DIR) +ensure_upstream_dir(INSTALLER_INFO_DIR) +ensure_upstream_dir(META_DIR) + +sess = default_session() + + +def get_maven_url(maven_key, server, ext): + parts = maven_key.split(":", 3) + maven_ver_url = ( + server + parts[0].replace(".", "/") + "/" + parts[1] + "/" + parts[2] + "/" + ) + maven_url = maven_ver_url + parts[1] + "-" + parts[2] + ext + return maven_url + + +def get_json_file(path, url): + with open(path, "w", encoding="utf-8") as f: + r = sess.get(url) + r.raise_for_status() + print(f"QUILT DEBUG {r.headers}") + version_json = r.json() + json.dump(version_json, f, sort_keys=True, indent=4) + return version_json + + +def head_file(url): + r = sess.head(url) + r.raise_for_status() + return r.headers + + +def get_binary_file(path, url): + with open(path, "wb") as f: + r = sess.get(url) + r.raise_for_status() + for chunk in r.iter_content(chunk_size=128): + f.write(chunk) + + +def compute_jar_file(path, url): + # NOTE: Quilt Meta does not make any guarantees about Last-Modified. + # Always download the JAR file instead + jar_path = path + ".jar" + get_binary_file(jar_path, url) + tstamp = datetime.fromtimestamp(0) + with zipfile.ZipFile(jar_path) as jar: + allinfo = jar.infolist() + for info in allinfo: + tstamp_new = datetime(*info.date_time) + if tstamp_new > tstamp: + tstamp = tstamp_new + + data = FabricJarInfo(release_time=tstamp) + data.write(path + ".json") + + +def compute_jar_file_concurrent(component, it): + print(f"Processing {component} {it['version']} ") + jar_maven_url = get_maven_url( + it["maven"], "https://maven.quiltmc.org/repository/release/", ".jar" + ) + compute_jar_file( + os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), + jar_maven_url, + ) + print(f"Processing {component} {it['version']} Done") + + +def get_json_file_concurrent(it): + print(f"Downloading JAR info for loader {it['version']} ") + maven_url = get_maven_url( + it["maven"], "https://maven.quiltmc.org/repository/release/", ".json" + ) + get_json_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{it['version']}.json"), + maven_url, + ) + + +def main(): + # get the version list for each component we are interested in + components = ["loader"] + if USE_QUILT_MAPPINGS: + components.append("hashed") + for component in components: + index = get_json_file( + os.path.join(UPSTREAM_DIR, META_DIR, f"{component}.json"), + "https://meta.quiltmc.org/v3/versions/" + component, + ) + with concurrent.futures.ThreadPoolExecutor() as executor: + futures = [ + executor.submit(compute_jar_file_concurrent, component, it) + for it in index + ] + for f in futures: + f.result() + + # for each loader, download installer JSON file from maven + with open( + os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), "r", encoding="utf-8" + ) as loaderVersionIndexFile: + loader_version_index = json.load(loaderVersionIndexFile) + with concurrent.futures.ThreadPoolExecutor() as executor: + futures = [ + executor.submit(get_json_file_concurrent, it) + for it in loader_version_index + ] + for f in futures: + f.result() + + +if __name__ == "__main__": + main() diff --git a/meta/nix/dev.nix b/meta/nix/dev.nix new file mode 100644 index 0000000000..1ca4edfc91 --- /dev/null +++ b/meta/nix/dev.nix @@ -0,0 +1,35 @@ +{ + perSystem = { + config, + pkgs, + self', + ... + }: { + pre-commit.settings = { + excludes = ["flake.lock"]; + hooks = { + markdownlint.enable = true; + + alejandra.enable = true; + deadnix.enable = true; + nil.enable = true; + + black.enable = true; + }; + }; + + devShells.default = pkgs.mkShell { + shellHook = '' + ${config.pre-commit.installationScript} + ''; + + buildInputs = with pkgs; [ + poetry + ]; + + inputsFrom = [self'.packages.default]; + }; + + formatter = pkgs.alejandra; + }; +} diff --git a/meta/nix/nixos/default.nix b/meta/nix/nixos/default.nix new file mode 100644 index 0000000000..c4aa24174b --- /dev/null +++ b/meta/nix/nixos/default.nix @@ -0,0 +1,10 @@ +{self, ...}: { + flake.nixosModules = { + default = self.nixosModules.meta; + meta = { + imports = [self.nixosModules.metaBare]; + nixpkgs.overlays = [self.overlays.default]; + }; + metaBare = ./meta.nix; + }; +} diff --git a/meta/nix/nixos/meta.nix b/meta/nix/nixos/meta.nix new file mode 100644 index 0000000000..c03d4e6e01 --- /dev/null +++ b/meta/nix/nixos/meta.nix @@ -0,0 +1,70 @@ +{ + config, + lib, + pkgs, + ... +}: let + inherit (lib) getExe getExe' mkEnableOption mkIf mkOption mkPackageOption types; + + settingsFormat = pkgs.formats.keyValue {}; + + cfg = config.services.blockgame-meta; +in { + options.services.blockgame-meta = { + enable = mkEnableOption "blockgame-meta service"; + + package = mkPackageOption pkgs "blockgame-meta" {}; + + settings = mkOption { + type = types.submodule { + freeformType = settingsFormat.type; + options = { + DEPLOY_TO_S3 = mkOption { + type = types.str; + default = "false"; + }; + DEPLOY_TO_FOLDER = mkOption { + type = types.str; + default = "false"; + }; + DEPLOY_TO_GIT = mkOption { + type = types.str; + default = "false"; + }; + }; + }; + }; + }; + config = mkIf cfg.enable { + users.users."blockgame-meta" = { + isSystemUser = true; + group = "blockgame-meta"; + }; + + users.groups."blockgame-meta" = {}; + + systemd = { + services."blockgame-meta" = { + description = "blockgame metadata generator"; + after = ["network-online.target"]; + wants = ["network-online.target"]; + serviceConfig = { + EnvironmentFile = [(settingsFormat.generate "blockgame-meta.env" cfg.settings)]; + ExecStartPre = getExe' cfg.package "init"; + ExecStart = getExe cfg.package; + StateDirectory = "blockgame-meta"; + CacheDirectory = "blockgame-meta"; + User = "blockgame-meta"; + }; + }; + + timers."blockgame-meta" = { + timerConfig = { + OnCalendar = "hourly"; + RandomizedDelaySec = "5m"; + }; + wantedBy = ["timers.target"]; + }; + }; + }; +} diff --git a/meta/nix/packages.nix b/meta/nix/packages.nix new file mode 100644 index 0000000000..4af7b97e5b --- /dev/null +++ b/meta/nix/packages.nix @@ -0,0 +1,18 @@ +{inputs, ...}: { + imports = [inputs.flake-parts.flakeModules.easyOverlay]; + + perSystem = { + config, + final, + ... + }: { + packages = { + blockgame-meta = final.python3.pkgs.callPackage ./pkgs/blockgame-meta.nix {}; + default = config.packages.blockgame-meta; + }; + + overlayAttrs = { + inherit (config.packages) blockgame-meta; + }; + }; +} diff --git a/meta/nix/pkgs/blockgame-meta.nix b/meta/nix/pkgs/blockgame-meta.nix new file mode 100644 index 0000000000..8409c37cb4 --- /dev/null +++ b/meta/nix/pkgs/blockgame-meta.nix @@ -0,0 +1,70 @@ +{ + lib, + buildPythonApplication, + poetry-core, + bash, + cachecontrol, + requests, + filelock, + git, + openssh, + packaging, + pydantic_1, + python, + rsync, +}: +buildPythonApplication { + pname = "blockgame-meta"; + version = "unstable"; + + pyproject = true; + + src = with lib.fileset; + toSource { + root = ../../.; + fileset = unions (map (fileName: ../../${fileName}) [ + "meta" + "init.sh" + "pyproject.toml" + "poetry.lock" + "README.md" + "update.sh" + ]); + }; + + nativeBuildInputs = [ + poetry-core + ]; + + buildInputs = [ + bash + ]; + + propagatedBuildInputs = [ + cachecontrol + requests + filelock + packaging + pydantic_1 + ]; + + postInstall = '' + install -Dm755 $src/update.sh $out/bin/update + install -Dm755 $src/init.sh $out/bin/init + + wrapProgram $out/bin/update \ + --prefix PYTHONPATH : "$PYTHONPATH" \ + --prefix PATH : ${lib.makeBinPath [git openssh python rsync]} + + wrapProgram $out/bin/init \ + --prefix PATH : ${lib.makeBinPath [git openssh]} + ''; + + meta = with lib; { + description = "Metadata generator for blockgame launcher."; + platforms = platforms.linux; + license = licenses.mspl; + maintainers = with maintainers; [Scrumplex]; + mainProgram = "update"; + }; +} diff --git a/meta/poetry.lock b/meta/poetry.lock new file mode 100644 index 0000000000..8bfa4c06b8 --- /dev/null +++ b/meta/poetry.lock @@ -0,0 +1,352 @@ +# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand. + +[[package]] +name = "cachecontrol" +version = "0.14.2" +description = "httplib2 caching for requests" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "cachecontrol-0.14.2-py3-none-any.whl", hash = "sha256:ebad2091bf12d0d200dfc2464330db638c5deb41d546f6d7aca079e87290f3b0"}, + {file = "cachecontrol-0.14.2.tar.gz", hash = "sha256:7d47d19f866409b98ff6025b6a0fca8e4c791fb31abbd95f622093894ce903a2"}, +] + +[package.dependencies] +msgpack = ">=0.5.2,<2.0.0" +requests = ">=2.16.0" + +[package.extras] +dev = ["CacheControl[filecache,redis]", "build", "cherrypy", "codespell[tomli]", "furo", "mypy", "pytest", "pytest-cov", "ruff", "sphinx", "sphinx-copybutton", "tox", "types-redis", "types-requests"] +filecache = ["filelock (>=3.8.0)"] +redis = ["redis (>=2.10.5)"] + +[[package]] +name = "certifi" +version = "2024.2.2" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +groups = ["main"] +files = [ + {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, + {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +groups = ["main"] +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "filelock" +version = "3.16.1" +description = "A platform independent file lock." +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"}, + {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"}, +] + +[package.extras] +docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"] +typing = ["typing-extensions (>=4.12.2) ; python_version < \"3.11\""] + +[[package]] +name = "idna" +version = "3.7" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +groups = ["main"] +files = [ + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, +] + +[[package]] +name = "msgpack" +version = "1.0.8" +description = "MessagePack serializer" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "msgpack-1.0.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:505fe3d03856ac7d215dbe005414bc28505d26f0c128906037e66d98c4e95868"}, + {file = "msgpack-1.0.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6b7842518a63a9f17107eb176320960ec095a8ee3b4420b5f688e24bf50c53c"}, + {file = "msgpack-1.0.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:376081f471a2ef24828b83a641a02c575d6103a3ad7fd7dade5486cad10ea659"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e390971d082dba073c05dbd56322427d3280b7cc8b53484c9377adfbae67dc2"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e073efcba9ea99db5acef3959efa45b52bc67b61b00823d2a1a6944bf45982"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82d92c773fbc6942a7a8b520d22c11cfc8fd83bba86116bfcf962c2f5c2ecdaa"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9ee32dcb8e531adae1f1ca568822e9b3a738369b3b686d1477cbc643c4a9c128"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e3aa7e51d738e0ec0afbed661261513b38b3014754c9459508399baf14ae0c9d"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:69284049d07fce531c17404fcba2bb1df472bc2dcdac642ae71a2d079d950653"}, + {file = "msgpack-1.0.8-cp310-cp310-win32.whl", hash = "sha256:13577ec9e247f8741c84d06b9ece5f654920d8365a4b636ce0e44f15e07ec693"}, + {file = "msgpack-1.0.8-cp310-cp310-win_amd64.whl", hash = "sha256:e532dbd6ddfe13946de050d7474e3f5fb6ec774fbb1a188aaf469b08cf04189a"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9517004e21664f2b5a5fd6333b0731b9cf0817403a941b393d89a2f1dc2bd836"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d16a786905034e7e34098634b184a7d81f91d4c3d246edc6bd7aefb2fd8ea6ad"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2872993e209f7ed04d963e4b4fbae72d034844ec66bc4ca403329db2074377b"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c330eace3dd100bdb54b5653b966de7f51c26ec4a7d4e87132d9b4f738220ba"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83b5c044f3eff2a6534768ccfd50425939e7a8b5cf9a7261c385de1e20dcfc85"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1876b0b653a808fcd50123b953af170c535027bf1d053b59790eebb0aeb38950"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dfe1f0f0ed5785c187144c46a292b8c34c1295c01da12e10ccddfc16def4448a"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3528807cbbb7f315bb81959d5961855e7ba52aa60a3097151cb21956fbc7502b"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e2f879ab92ce502a1e65fce390eab619774dda6a6ff719718069ac94084098ce"}, + {file = "msgpack-1.0.8-cp311-cp311-win32.whl", hash = "sha256:26ee97a8261e6e35885c2ecd2fd4a6d38252246f94a2aec23665a4e66d066305"}, + {file = "msgpack-1.0.8-cp311-cp311-win_amd64.whl", hash = "sha256:eadb9f826c138e6cf3c49d6f8de88225a3c0ab181a9b4ba792e006e5292d150e"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:114be227f5213ef8b215c22dde19532f5da9652e56e8ce969bf0a26d7c419fee"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d661dc4785affa9d0edfdd1e59ec056a58b3dbb9f196fa43587f3ddac654ac7b"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d56fd9f1f1cdc8227d7b7918f55091349741904d9520c65f0139a9755952c9e8"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0726c282d188e204281ebd8de31724b7d749adebc086873a59efb8cf7ae27df3"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8db8e423192303ed77cff4dce3a4b88dbfaf43979d280181558af5e2c3c71afc"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99881222f4a8c2f641f25703963a5cefb076adffd959e0558dc9f803a52d6a58"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b5505774ea2a73a86ea176e8a9a4a7c8bf5d521050f0f6f8426afe798689243f"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ef254a06bcea461e65ff0373d8a0dd1ed3aa004af48839f002a0c994a6f72d04"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e1dd7839443592d00e96db831eddb4111a2a81a46b028f0facd60a09ebbdd543"}, + {file = "msgpack-1.0.8-cp312-cp312-win32.whl", hash = "sha256:64d0fcd436c5683fdd7c907eeae5e2cbb5eb872fafbc03a43609d7941840995c"}, + {file = "msgpack-1.0.8-cp312-cp312-win_amd64.whl", hash = "sha256:74398a4cf19de42e1498368c36eed45d9528f5fd0155241e82c4082b7e16cffd"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0ceea77719d45c839fd73abcb190b8390412a890df2f83fb8cf49b2a4b5c2f40"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1ab0bbcd4d1f7b6991ee7c753655b481c50084294218de69365f8f1970d4c151"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1cce488457370ffd1f953846f82323cb6b2ad2190987cd4d70b2713e17268d24"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3923a1778f7e5ef31865893fdca12a8d7dc03a44b33e2a5f3295416314c09f5d"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a22e47578b30a3e199ab067a4d43d790249b3c0587d9a771921f86250c8435db"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd739c9251d01e0279ce729e37b39d49a08c0420d3fee7f2a4968c0576678f77"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d3420522057ebab1728b21ad473aa950026d07cb09da41103f8e597dfbfaeb13"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5845fdf5e5d5b78a49b826fcdc0eb2e2aa7191980e3d2cfd2a30303a74f212e2"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a0e76621f6e1f908ae52860bdcb58e1ca85231a9b0545e64509c931dd34275a"}, + {file = "msgpack-1.0.8-cp38-cp38-win32.whl", hash = "sha256:374a8e88ddab84b9ada695d255679fb99c53513c0a51778796fcf0944d6c789c"}, + {file = "msgpack-1.0.8-cp38-cp38-win_amd64.whl", hash = "sha256:f3709997b228685fe53e8c433e2df9f0cdb5f4542bd5114ed17ac3c0129b0480"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f51bab98d52739c50c56658cc303f190785f9a2cd97b823357e7aeae54c8f68a"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:73ee792784d48aa338bba28063e19a27e8d989344f34aad14ea6e1b9bd83f596"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f9904e24646570539a8950400602d66d2b2c492b9010ea7e965025cb71d0c86d"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e75753aeda0ddc4c28dce4c32ba2f6ec30b1b02f6c0b14e547841ba5b24f753f"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5dbf059fb4b7c240c873c1245ee112505be27497e90f7c6591261c7d3c3a8228"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4916727e31c28be8beaf11cf117d6f6f188dcc36daae4e851fee88646f5b6b18"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7938111ed1358f536daf311be244f34df7bf3cdedb3ed883787aca97778b28d8"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:493c5c5e44b06d6c9268ce21b302c9ca055c1fd3484c25ba41d34476c76ee746"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273"}, + {file = "msgpack-1.0.8-cp39-cp39-win32.whl", hash = "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d"}, + {file = "msgpack-1.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011"}, + {file = "msgpack-1.0.8.tar.gz", hash = "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3"}, +] + +[[package]] +name = "packaging" +version = "25.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, + {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, +] + +[[package]] +name = "pydantic" +version = "1.10.26" +description = "Data validation and settings management using python type hints" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "pydantic-1.10.26-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f7ae36fa0ecef8d39884120f212e16c06bb096a38f523421278e2f39c1784546"}, + {file = "pydantic-1.10.26-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d95a76cf503f0f72ed7812a91de948440b2bf564269975738a4751e4fadeb572"}, + {file = "pydantic-1.10.26-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a943ce8e00ad708ed06a1d9df5b4fd28f5635a003b82a4908ece6f24c0b18464"}, + {file = "pydantic-1.10.26-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:465ad8edb29b15c10b779b16431fe8e77c380098badf6db367b7a1d3e572cf53"}, + {file = "pydantic-1.10.26-cp310-cp310-win_amd64.whl", hash = "sha256:80e6be6272839c8a7641d26ad569ab77772809dd78f91d0068dc0fc97f071945"}, + {file = "pydantic-1.10.26-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:116233e53889bcc536f617e38c1b8337d7fa9c280f0fd7a4045947515a785637"}, + {file = "pydantic-1.10.26-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c3cfdd361addb6eb64ccd26ac356ad6514cee06a61ab26b27e16b5ed53108f77"}, + {file = "pydantic-1.10.26-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0e4451951a9a93bf9a90576f3e25240b47ee49ab5236adccb8eff6ac943adf0f"}, + {file = "pydantic-1.10.26-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9858ed44c6bea5f29ffe95308db9e62060791c877766c67dd5f55d072c8612b5"}, + {file = "pydantic-1.10.26-cp311-cp311-win_amd64.whl", hash = "sha256:ac1089f723e2106ebde434377d31239e00870a7563245072968e5af5cc4d33df"}, + {file = "pydantic-1.10.26-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:468d5b9cacfcaadc76ed0a4645354ab6f263ec01a63fb6d05630ea1df6ae453f"}, + {file = "pydantic-1.10.26-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2c1b0b914be31671000ca25cf7ea17fcaaa68cfeadf6924529c5c5aa24b7ab1f"}, + {file = "pydantic-1.10.26-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15b13b9f8ba8867095769e1156e0d7fbafa1f65b898dd40fd1c02e34430973cb"}, + {file = "pydantic-1.10.26-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad7025ca324ae263d4313998e25078dcaec5f9ed0392c06dedb57e053cc8086b"}, + {file = "pydantic-1.10.26-cp312-cp312-win_amd64.whl", hash = "sha256:4482b299874dabb88a6c3759e3d85c6557c407c3b586891f7d808d8a38b66b9c"}, + {file = "pydantic-1.10.26-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1ae7913bb40a96c87e3d3f6fe4e918ef53bf181583de4e71824360a9b11aef1c"}, + {file = "pydantic-1.10.26-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8154c13f58d4de5d3a856bb6c909c7370f41fb876a5952a503af6b975265f4ba"}, + {file = "pydantic-1.10.26-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f8af0507bf6118b054a9765fb2e402f18a8b70c964f420d95b525eb711122d62"}, + {file = "pydantic-1.10.26-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dcb5a7318fb43189fde6af6f21ac7149c4bcbcfffc54bc87b5becddc46084847"}, + {file = "pydantic-1.10.26-cp313-cp313-win_amd64.whl", hash = "sha256:71cde228bc0600cf8619f0ee62db050d1880dcc477eba0e90b23011b4ee0f314"}, + {file = "pydantic-1.10.26-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:6b40730cc81d53d515dc0b8bb5c9b43fadb9bed46de4a3c03bd95e8571616dba"}, + {file = "pydantic-1.10.26-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c3bbb9c0eecdf599e4db9b372fa9cc55be12e80a0d9c6d307950a39050cb0e37"}, + {file = "pydantic-1.10.26-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc2e3fe7bc4993626ef6b6fa855defafa1d6f8996aa1caef2deb83c5ac4d043a"}, + {file = "pydantic-1.10.26-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:36d9e46b588aaeb1dcd2409fa4c467fe0b331f3cc9f227b03a7a00643704e962"}, + {file = "pydantic-1.10.26-cp314-cp314-win_amd64.whl", hash = "sha256:81ce3c8616d12a7be31b4aadfd3434f78f6b44b75adbfaec2fe1ad4f7f999b8c"}, + {file = "pydantic-1.10.26-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bc5c91a3b3106caf07ac6735ec6efad8ba37b860b9eb569923386debe65039ad"}, + {file = "pydantic-1.10.26-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:dde599e0388e04778480d57f49355c9cc7916de818bf674de5d5429f2feebfb6"}, + {file = "pydantic-1.10.26-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8be08b5cfe88e58198722861c7aab737c978423c3a27300911767931e5311d0d"}, + {file = "pydantic-1.10.26-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0141f4bafe5eda539d98c9755128a9ea933654c6ca4306b5059fc87a01a38573"}, + {file = "pydantic-1.10.26-cp38-cp38-win_amd64.whl", hash = "sha256:eb664305ffca8a9766a8629303bb596607d77eae35bb5f32ff9245984881b638"}, + {file = "pydantic-1.10.26-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:502b9d30d18a2dfaf81b7302f6ba0e5853474b1c96212449eb4db912cb604b7d"}, + {file = "pydantic-1.10.26-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0d8f6087bf697dec3bf7ffcd7fe8362674f16519f3151789f33cbe8f1d19fc15"}, + {file = "pydantic-1.10.26-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dd40a99c358419910c85e6f5d22f9c56684c25b5e7abc40879b3b4a52f34ae90"}, + {file = "pydantic-1.10.26-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ce3293b86ca9f4125df02ff0a70be91bc7946522467cbd98e7f1493f340616ba"}, + {file = "pydantic-1.10.26-cp39-cp39-win_amd64.whl", hash = "sha256:1a4e3062b71ab1d5df339ba12c48f9ed5817c5de6cb92a961dd5c64bb32e7b96"}, + {file = "pydantic-1.10.26-py3-none-any.whl", hash = "sha256:c43ad70dc3ce7787543d563792426a16fd7895e14be4b194b5665e36459dd917"}, + {file = "pydantic-1.10.26.tar.gz", hash = "sha256:8c6aa39b494c5af092e690127c283d84f363ac36017106a9e66cb33a22ac412e"}, +] + +[package.dependencies] +typing-extensions = ">=4.2.0" + +[package.extras] +dotenv = ["python-dotenv (>=0.10.4)"] +email = ["email-validator (>=1.0.3)"] + +[[package]] +name = "requests" +version = "2.32.4" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c"}, + {file = "requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset_normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "typing-extensions" +version = "4.11.0" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "typing_extensions-4.11.0-py3-none-any.whl", hash = "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"}, + {file = "typing_extensions-4.11.0.tar.gz", hash = "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0"}, +] + +[[package]] +name = "urllib3" +version = "2.2.1" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, + {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[metadata] +lock-version = "2.1" +python-versions = "^3.8" +content-hash = "2ed3cbaf03c118578cad2e4ea78c7baefeb741fae05c96472df8a4a59d97a9ae" diff --git a/meta/public/.keep b/meta/public/.keep new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/meta/public/.keep diff --git a/meta/pyproject.toml b/meta/pyproject.toml new file mode 100644 index 0000000000..295d05a859 --- /dev/null +++ b/meta/pyproject.toml @@ -0,0 +1,39 @@ +[tool.poetry] +name = "meta" +version = "0.0.1" +description = "Prism Launcher meta generator" +authors = ["Sefa Eyeoglu <contact@scrumplex.net>"] +license = "MS-PL" +readme = "README.md" +repository = "https://github.com/PrismLauncher/meta" +documentation = "https://github.com/PrismLauncher/meta" +keywords = ["metadata", "prism", "launcher"] + +[tool.poetry.scripts] +generateFabric = "meta.run.generate_fabric:main" +generateForge = "meta.run.generate_forge:main" +generateLiteloader = "meta.run.generate_liteloader:main" +generateMojang = "meta.run.generate_mojang:main" +generateNeoForge = "meta.run.generate_neoforge:main" +generateQuilt = "meta.run.generate_quilt:main" +generateJava = "meta.run.generate_java:main" +updateFabric = "meta.run.update_fabric:main" +updateForge = "meta.run.update_forge:main" +updateLiteloader = "meta.run.update_liteloader:main" +updateMojang = "meta.run.update_mojang:main" +updateNeoForge = "meta.run.update_neoforge:main" +updateQuilt = "meta.run.update_quilt:main" +updateJava = "meta.run.update_java:main" +index = "meta.run.index:main" + +[tool.poetry.dependencies] +python = "^3.8" +cachecontrol = "^0.14.0" +requests = "^2.31.0" +filelock = "^3.13.1" +packaging = "^25.0" +pydantic = "^1.10.13" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" diff --git a/meta/renovate.json b/meta/renovate.json new file mode 100644 index 0000000000..39a2b6e9a5 --- /dev/null +++ b/meta/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:base" + ] +} diff --git a/meta/update.sh b/meta/update.sh new file mode 100755 index 0000000000..15df54e2b0 --- /dev/null +++ b/meta/update.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash + +set -x + +if [ -f config.sh ]; then + source config.sh +fi + +export META_CACHE_DIR=${CACHE_DIRECTORY:-./caches} +export META_UPSTREAM_DIR=${META_UPSTREAM_DIR:-${STATE_DIRECTORY:-.}/upstream} +export META_LAUNCHER_DIR=${META_LAUNCHER_DIR:-${STATE_DIRECTORY:-.}/launcher} + +function fail_in() { + upstream_git reset --hard HEAD + exit 1 +} + +function fail_out() { + launcher_git reset --hard HEAD + exit 1 +} + +function upstream_git() { + git -C "${META_UPSTREAM_DIR}" "$@" +} + +function launcher_git() { + git -C "${META_LAUNCHER_DIR}" "$@" +} + +# make sure we *could* push to our repo + +currentDate=$(date -I) + +upstream_git reset --hard HEAD || exit 1 +upstream_git pull + +python -m meta.run.update_mojang || fail_in +python -m meta.run.update_forge || fail_in +python -m meta.run.update_neoforge || fail_in +python -m meta.run.update_fabric || fail_in +python -m meta.run.update_quilt || fail_in +python -m meta.run.update_liteloader || fail_in +python -m meta.run.update_java || fail_in + +if [ "${DEPLOY_TO_GIT}" = true ]; then + upstream_git add mojang/version_manifest_v2.json mojang/java_all.json mojang/versions/* || fail_in + upstream_git add forge/*.json forge/version_manifests/*.json forge/installer_manifests/*.json forge/files_manifests/*.json forge/installer_info/*.json forge/jars/*.sha1 || fail_in + upstream_git add neoforge/*.json neoforge/version_manifests/*.json neoforge/installer_manifests/*.json neoforge/files_manifests/*.json neoforge/installer_info/*.json neoforge/jars/*.sha1 || fail_in + upstream_git add fabric/loader-installer-json/*.json fabric/meta-v2/*.json fabric/jars/*.json || fail_in + upstream_git add quilt/loader-installer-json/*.json quilt/meta-v3/*.json quilt/jars/*.json || fail_in + upstream_git add liteloader/*.json || fail_in + upstream_git add java_runtime/adoptium/available_releases.json java_runtime/adoptium/versions/*.json java_runtime/azul/packages.json java_runtime/azul/versions/*.json java_runtime/ibm/available_releases.json java_runtime/ibm/versions/*.json || fail_in + if ! upstream_git diff --cached --exit-code; then + upstream_git commit -a -m "Update ${currentDate}" || fail_in + upstream_git push || exit 1 + fi +fi + +launcher_git reset --hard HEAD || exit 1 +launcher_git pull + +python -m meta.run.generate_mojang || fail_out +python -m meta.run.generate_forge || fail_out +python -m meta.run.generate_neoforge || fail_out +python -m meta.run.generate_fabric || fail_out +python -m meta.run.generate_quilt || fail_out +python -m meta.run.generate_liteloader || fail_out +python -m meta.run.generate_java || fail_out +python -m meta.run.index || fail_out + +if [ "${DEPLOY_TO_GIT}" = true ]; then + launcher_git add index.json org.lwjgl/* org.lwjgl3/* net.minecraft/* || fail_out + launcher_git add net.minecraftforge/* || fail_out + launcher_git add net.neoforged/* || fail_out + launcher_git add net.fabricmc.fabric-loader/* net.fabricmc.intermediary/* || fail_out + launcher_git add org.quiltmc.quilt-loader/* || fail_out # TODO: add Quilt hashed, once it is actually used + launcher_git add com.mumfrey.liteloader/* || fail_out + launcher_git add net.minecraft.java/* net.adoptium.java/* com.azul.java/* com.ibm.java/* || fail_out + + if ! launcher_git diff --cached --exit-code; then + launcher_git commit -a -m "Update ${currentDate}" || fail_out + launcher_git push || exit 1 + fi +fi + +if [ "${DEPLOY_TO_FOLDER}" = true ]; then + echo "Deploying to ${DEPLOY_FOLDER}" + rsync -rvog --chown="${DEPLOY_FOLDER_USER}:${DEPLOY_FOLDER_GROUP}" --exclude=.git "${META_LAUNCHER_DIR}/" "${DEPLOY_FOLDER}" +fi + +exit 0 |
