├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── bug_report.yml │ └── config.yml ├── .gitignore ├── .vscode └── settings.json ├── LICENSE.md ├── README.md ├── assets ├── LWJGL │ ├── aarch │ │ ├── 2.9.4.json │ │ ├── 3.1.2.json │ │ ├── 3.1.6.json │ │ ├── 3.2.1.json │ │ ├── 3.2.2.json │ │ ├── 3.3.1.json │ │ └── 3.3.2.json │ └── aarch64 │ │ ├── 2.9.4.json │ │ ├── 3.1.2.json │ │ ├── 3.1.6.json │ │ ├── 3.2.1.json │ │ ├── 3.2.2.json │ │ ├── 3.3.1.json │ │ └── 3.3.2.json └── icons │ ├── microsoft.icns │ ├── microsoft.ico │ └── microsoft.png ├── package-lock.json ├── package.json ├── src ├── Authenticator │ ├── AZauth.ts │ ├── GUI │ │ ├── Electron.ts │ │ ├── NW.ts │ │ └── Terminal.ts │ ├── Microsoft.ts │ └── Mojang.ts ├── Index.ts ├── Launch.ts ├── Minecraft-Loader │ ├── index.ts │ ├── loader │ │ ├── fabric │ │ │ └── fabric.ts │ │ ├── forge │ │ │ └── forge.ts │ │ ├── legacyfabric │ │ │ └── legacyFabric.ts │ │ ├── neoForge │ │ │ └── neoForge.ts │ │ └── quilt │ │ │ └── quilt.ts │ └── patcher.ts ├── Minecraft │ ├── Minecraft-Arguments.ts │ ├── Minecraft-Assets.ts │ ├── Minecraft-Bundle.ts │ ├── Minecraft-Java.ts │ ├── Minecraft-Json.ts │ ├── Minecraft-Libraries.ts │ ├── Minecraft-Loader.ts │ └── Minecraft-Lwjgl-Native.ts ├── StatusServer │ ├── buffer.ts │ └── status.ts └── utils │ ├── Downloader.ts │ └── Index.ts ├── test ├── AZauth.js ├── index.js └── offline.js ├── tsconfig.json └── webfiles ├── index.php ├── instances ├── aynor │ └── README.md ├── hypixel │ └── README.md └── selvania │ └── README.md └── php ├── instances.php └── scandir.php /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: ['luuxis'] -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Signaler un bug 2 | description: Vous avez rencontré un bug? Signalez-le ici 3 | title: "[Bug] " 4 | labels: ["bug"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Un grand merci d'avance pour votre aide. Néanmoins, nous avons besoin d'un certain nombre d'informations, pour nous aider. 10 | - type: checkboxes 11 | attributes: 12 | label: "Liste des vérifications à faire avant de valider l'ouverture du signalement de bug" 13 | description: Assurez que vous avez complété ce qui suit, dans le cas contraire, votre rapport peut être refusé 14 | options: 15 | - label: J'ai réussi à reproduire le bug sur le Selvania Launcher (sans mes modifications) 16 | required: true 17 | - label: Mon code respecte la licence Creative Commons Zero v1.0 Universal 18 | required: true 19 | - label: Mon code respecte les conditions d'utilisation du Selvania Launcher 20 | required: true 21 | - label: J'arrive à reproduire le bug sur la dernière version du Selvania Launcher 22 | required: true 23 | - type: dropdown 24 | attributes: 25 | label: Système d'exploitation 26 | options: 27 | - Windows 28 | - macOS 29 | - Linux (Basé sur Debian/Ubuntu) 30 | - Linux (Autres) 31 | validations: 32 | required: true 33 | - type: input 34 | attributes: 35 | label: Version du système d'exploitation 36 | placeholder: "Exemple: Windows 11 Professionnel 21H2 Build 22000.739" 37 | validations: 38 | required: true 39 | - type: input 40 | attributes: 41 | label: Hash du commit sur lequel le bug est rencontré 42 | placeholder: 84d7881b67ecf6088205eca6723bfb19bf2a5f0d 43 | - type: textarea 44 | attributes: 45 | label: Comportement attendu 46 | description: Une description de ce qui devrait se passer 47 | placeholder: Le launcher devrait... 48 | validations: 49 | required: true 50 | - type: textarea 51 | attributes: 52 | label: Comportement actuel 53 | description: Une description de ce qui se passe avec le bug 54 | validations: 55 | required: true 56 | - type: textarea 57 | attributes: 58 | label: Instructions pour reproduire le but 59 | placeholder: | 60 | 1. Ouvrir le launcher 61 | 2. Aller dans le menu xyz 62 | 3. Cliquer sur abc 63 | 4. Observer 64 | validations: 65 | required: true 66 | - type: textarea 67 | attributes: 68 | label: Notes additionnelles 69 | placeholder: Détails supplémentaires concernant le bug, tout ce qui pourrait être utile 70 | validations: 71 | required: false 72 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Nous rejoindre sur Discord, pour toutes questions ou demandes 4 | url: http://discord.luuxis.fr 5 | about: Veuillez ne pas ouvrir d'issue autre que pour signaler des bugs 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | test/Minecraft 4 | test/*.json* 5 | webfiles/instances/* 6 | .DS_Store 7 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | "**/build": true, 4 | "**/node_modules": true, 5 | "**/package-lock.json": true 6 | } 7 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ##### v4 • **minecraft‑java‑core** 2 | [![License: CC‑BY‑NC 4.0](https://img.shields.io/badge/License-CC--BY--NC%204.0-yellow.svg)](https://creativecommons.org/licenses/by-nc/4.0/) 3 | ![stable version](https://img.shields.io/badge/stable_version-4.0.0-blue) 4 | 5 | **minecraft‑java‑core** is a **NodeJS/TypeScript** solution for launching both vanilla *and* modded Minecraft Java Edition without juggling JSON manifests, assets, libraries or Java runtimes yourself. Think of it as the *core* of an Electron/NW.js/CLI launcher. 6 | 7 | --- 8 | 9 | ### Getting support 10 | Need help or just want to chat? Join the community Discord! 11 | 12 |

13 | 14 | 15 | 16 |

17 | 18 | --- 19 | 20 | ### Installing 21 | 22 | ```bash 23 | npm i minecraft-java-core 24 | # or 25 | yarn add minecraft-java-core 26 | ``` 27 | 28 | *Requirements:* Node ≥ 18, TypeScript (only if you import *.ts*), 7‑Zip embedded binary. 29 | 30 | --- 31 | 32 | ### Standard Example (ESM) 33 | ```ts 34 | import { Launch, Microsoft } from 'minecraft-java-core'; 35 | 36 | // ⚠️ In production, perform auth **before** initialising the launcher 37 | // so you can handle refresh / error flows cleanly. 38 | const auth = await Microsoft.auth({ 39 | client_id: '00000000-0000-0000-0000-000000000000', 40 | type: 'terminal' // 'electron' | 'nwjs' 41 | }); 42 | 43 | const launcher = new Launch(); 44 | 45 | launcher.on('progress', p => console.log(`[DL] ${p}%`)) 46 | .on('data', line => process.stdout.write(line)) 47 | .on('close', () => console.log('Game exited.')); 48 | 49 | await launcher.launch({ 50 | root: './minecraft', 51 | authenticator: auth, 52 | version: '1.20.4', 53 | loader: { type: 'fabric', build: '0.15.9' }, 54 | memory: { min: '2G', max: '4G' } 55 | }); 56 | ``` 57 | 58 | --- 59 | 60 | ## Documentation 61 | 62 | ### Launch class 63 | 64 | | Function | Type | Description | 65 | |----------|---------|------------------------------------------------------------------------| 66 | | `launch` | Promise | Launches Minecraft with the given **`LaunchOptions`** (see below). | 67 | 68 | #### LaunchOptions 69 | 70 | | Parameter | Type | Description | Required | 71 | |-----------|------|-------------|----------| 72 | | `path` | String | Working directory where game files are stored (usually `.minecraft`). | ✔︎ | 73 | | `url` | String \| null | Custom version manifest base URL (only for mirror setups). | — | 74 | | `authenticator` | Object | Microsoft / Mojang / AZauth profile returned by the authenticator. | ✔︎ | 75 | | `timeout` | Integer | Network timeout in **milliseconds** for downloads. | — | 76 | | `version` | String | `'latest_release'`, `'latest_snapshot'`, `'1.21.1'`. | — | 77 | | `instance` | String \| null | Name of the instance if you manage multiple profiles. | — | 78 | | `detached` | Boolean | Detach the Java process from the launcher. | — | 79 | | `intelEnabledMac` | Boolean | Force Rosetta when running on Apple Silicon. | — | 80 | | `downloadFileMultiple` | Integer | Max parallel downloads. | — | 81 | | `loader.enable` | Boolean | Whether to install a mod‑loader (Forge/Fabric/…). | — | 82 | | `loader.type` | String \| null | `forge`, `neoforge`, `fabric`, `legacyfabric`, `quilt`. | — | 83 | | `loader.build` | String | Loader build tag (e.g. `latest`, `0.15.9`). | — | 84 | | `loader.path` | String | Destination folder for loader files. Defaults to `./loader`. | — | 85 | | `mcp` | String \| null | Path to MCP configuration for legacy mods. | — | 86 | | `verify` | Boolean | Verify SHA‑1 of downloaded files. | — | 87 | | `ignored` | Array | List of files to skip during verification. | — | 88 | | `JVM_ARGS` | Array | Extra JVM arguments. | — | 89 | | `GAME_ARGS` | Array | Extra Minecraft arguments. | — | 90 | | `java.path` | String \| null | Absolute path to Java runtime. | — | 91 | | `java.version` | String \| null | Force a specific Java version (e.g. `17`). | — | 92 | | `java.type` | String | `jre` or `jdk`. | — | 93 | | `screen.width` | Number \| null | Width of game window. | — | 94 | | `screen.height` | Number \| null | Height of game window. | — | 95 | | `screen.fullscreen` | Boolean | Start the game in fullscreen mode. | — | 96 | | `memory.min` | String | Minimum RAM (e.g. `1G`). | ✔︎ | 97 | | `memory.max` | String | Maximum RAM (e.g. `2G`). | ✔︎ | 98 | 99 | > **Recommendation:** Start with the minimal set (`authenticator`, `path`, `version`, `memory`) and gradually add overrides only when you need them. 100 | 101 | #### Default configuration 102 | 103 | Below is the complete **default** `LaunchOptions` object returned by 104 | `minecraft‑java‑core` when you don’t override any field. Use it as a quick 105 | reference for every available parameter and its default value. 106 | (Parameters marked *nullable* can be left `null`/`undefined` and the library 107 | will figure out sane values.) 108 | 109 | ```ts 110 | const defaultOptions = { 111 | url: null, // Optional custom manifest URL 112 | authenticator: null, // Microsoft/Mojang/AZauth profile 113 | timeout: 10000, // Network timeout in ms 114 | path: '.Minecraft', // Root directory (alias: root) 115 | version: 'latest_release', // Minecraft version (string or 'latest_…') 116 | instance: null, // Multi‑instance name (optional) 117 | detached: false, // Detach Java process from parent 118 | intelEnabledMac: false, // Rosetta toggle for Apple Silicon 119 | downloadFileMultiple: 5, // Parallel downloads 120 | 121 | loader: { 122 | path: './loader', // Where to install loaders 123 | type: null, // forge | neoforge | fabric | … 124 | build: 'latest', // Build number / tag 125 | enable: false, // Whether to install the loader 126 | }, 127 | 128 | mcp: null, // Path to MCP config (legacy mods) 129 | 130 | verify: false, // SHA‑1 check after download 131 | ignored: [], // Files to skip verification 132 | JVM_ARGS: [], // Extra JVM arguments 133 | GAME_ARGS: [], // Extra game arguments 134 | 135 | java: { 136 | path: null, // Custom JVM path 137 | version: null, // Explicit Java version 138 | type: 'jre', // jre | jdk 139 | }, 140 | 141 | screen: { 142 | width: null, 143 | height: null, 144 | fullscreen: false, 145 | }, 146 | 147 | memory: { 148 | min: '1G', 149 | max: '2G', 150 | }, 151 | } as const; 152 | ``` 153 | 154 | > **Note** : Any field you provide when calling `Launch.launch()` will be 155 | > merged on top of these defaults; you rarely need to specify more than 156 | > `authenticator`, `path`, `version` and `memory`. 157 | 158 | --- 159 | 160 | #### Events 161 | 162 | | Event Name | Payload | Description | 163 | |-------------|---------|--------------------------------------------------------------| 164 | | `data` | String | Raw output from the Java process. | 165 | | `progress` | Number | Global download progress percentage. | 166 | | `speed` | Number | Current download speed (kB/s). | 167 | | `estimated` | Number | Estimated time remaining (s). | 168 | | `extract` | String | Name of the file currently being extracted. | 169 | | `patch` | String | Loader patch currently applied. | 170 | | `close` | void | Emitted when the Java process exits. | 171 | | `error` | Error | Something went wrong. | 172 | 173 | --- 174 | 175 | ### Authentication *(built‑in)* 176 | 177 | * **Microsoft** — OAuth 2 Device Code flow via Xbox Live → XSTS → Minecraft. 178 | * **Mojang** *(legacy)* — classic Yggdrasil endpoint. 179 | * **AZauth** — community Yggdrasil‑compatible server. 180 | 181 | > The authenticator returns a profile object that you pass directly to `Launch.launch()`. 182 | 183 | --- 184 | 185 | ### Utilities 186 | 187 | * **Downloader** — resilient downloader with resume, integrity check & `progress`/`speed` events. 188 | * **Status** — simple TCP ping that returns MOTD, player count & latency. 189 | 190 | --- 191 | 192 | ### File structure (simplified) 193 | ``` 194 | src/ 195 | Authenticator/ Microsoft, Mojang, AZauth flows 196 | Minecraft/ Version JSON, assets, libraries, args builder 197 | Minecraft-Loader/ Forge, NeoForge, Fabric, Quilt, … installers 198 | StatusServer/ Server ping implementation 199 | utils/ Downloader & helpers 200 | Launch.ts Main entry point 201 | assets/ LWJGL native indexes 202 | ``` 203 | 204 | --- 205 | 206 | ### Contributors 207 | See the commit history for a full list. Special thanks to: 208 | 209 | * **Luuxis** — original author. 210 | * Community testers & issue reporters. 211 | 212 | --- 213 | 214 | ### License 215 | Released under **Creative Commons Attribution‑NonCommercial 4.0 International**. -------------------------------------------------------------------------------- /assets/LWJGL/aarch/2.9.4.json: -------------------------------------------------------------------------------- 1 | { 2 | "libraries": [ 3 | { 4 | "downloads": { 5 | "classifiers": { 6 | "natives-linux": { 7 | "path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar", 8 | "sha1": "f3c455b71c5146acb5f8a9513247fc06db182fd5", 9 | "size": 4521, 10 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-2.9.4/jinput-platform-2.0.5-natives-linux.jar" 11 | } 12 | } 13 | }, 14 | "extract": { 15 | "exclude": [ 16 | "META-INF/" 17 | ] 18 | }, 19 | "name": "net.java.jinput:jinput-platform:2.0.5", 20 | "natives": { 21 | "linux": "natives-linux" 22 | } 23 | }, 24 | { 25 | "downloads": { 26 | "artifact": { 27 | "path": "net/java/jinput/jinput/2.0.5/jinput-2.0.5.jar", 28 | "sha1": "c2e322bbec2345f1b93b96000f93e3a4c3b2bf96", 29 | "size": 216945, 30 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-2.9.4/jinput-2.0.5.jar" 31 | } 32 | }, 33 | "name": "net.java.jinput:jinput:2.0.5" 34 | }, 35 | { 36 | "downloads": { 37 | "artifact": { 38 | "path": "net/java/jutils/jutils/1.0.0/jutils-1.0.0.jar", 39 | "sha1": "e12fe1fda814bd348c1579329c86943d2cd3c6a6", 40 | "size": 7508, 41 | "url": "https://libraries.minecraft.net/net/java/jutils/jutils/1.0.0/jutils-1.0.0.jar" 42 | } 43 | }, 44 | "name": "net.java.jutils:jutils:1.0.0" 45 | }, 46 | { 47 | "downloads": { 48 | "artifact": { 49 | "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar", 50 | "sha1": "b04f3ee8f5e43fa3b162981b50bb72fe1acabb33", 51 | "size": 22, 52 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar" 53 | }, 54 | "classifiers": { 55 | "natives-linux": { 56 | "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar", 57 | "sha1": "fa483e540a9a753a5ffbb23dcf7879a5bf752611", 58 | "size": 475177, 59 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-2.9.4/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar" 60 | } 61 | } 62 | }, 63 | "extract": { 64 | "exclude": [ 65 | "META-INF/" 66 | ] 67 | }, 68 | "name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.4-nightly-20150209", 69 | "natives": { 70 | "linux": "natives-linux" 71 | } 72 | }, 73 | { 74 | "downloads": { 75 | "artifact": { 76 | "path": "org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209/lwjgl-2.9.4-nightly-20150209.jar", 77 | "sha1": "697517568c68e78ae0b4544145af031c81082dfe", 78 | "size": 1047168, 79 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209/lwjgl-2.9.4-nightly-20150209.jar" 80 | } 81 | }, 82 | "name": "org.lwjgl.lwjgl:lwjgl:2.9.4-nightly-20150209" 83 | }, 84 | { 85 | "downloads": { 86 | "artifact": { 87 | "path": "org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.jar", 88 | "sha1": "d51a7c040a721d13efdfbd34f8b257b2df882ad0", 89 | "size": 173887, 90 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-2.9.4/lwjgl_util-2.9.4-nightly-20150209.jar" 91 | } 92 | }, 93 | "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.4-nightly-20150209" 94 | } 95 | ] 96 | } -------------------------------------------------------------------------------- /assets/LWJGL/aarch/3.1.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "libraries": [ 3 | { 4 | "downloads": { 5 | "artifact": { 6 | "sha1": "d2df40234fd576e708feee78bccadaf02c5712a3", 7 | "size": 300107, 8 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-core.jar", 9 | "path": "org/lwjgl/lwjgl/3.1.6/lwjgl-3.1.6.jar" 10 | } 11 | }, 12 | "name": "org.lwjgl:lwjgl:3.1.6" 13 | }, 14 | { 15 | "downloads": { 16 | "artifact": { 17 | "sha1": "d2df40234fd576e708feee78bccadaf02c5712a3", 18 | "size": 300107, 19 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-core.jar", 20 | "path": "org/lwjgl/lwjgl/3.1.6/lwjgl-3.1.6.jar" 21 | }, 22 | "classifiers": { 23 | "natives-linux": { 24 | "sha1": "1d4e6397a4ba0df30f7477ee5ba308d4dad3387e", 25 | "size": 59165, 26 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-natives-linux-arm32.jar", 27 | "path": "org/lwjgl/lwjgl/3.1.6/lwjgl-3.1.6-natives-linux.jar" 28 | } 29 | } 30 | }, 31 | "name": "org.lwjgl:lwjgl:3.1.6", 32 | "natives": { 33 | "linux": "natives-linux" 34 | } 35 | }, 36 | { 37 | "downloads": { 38 | "artifact": { 39 | "sha1": "9b0884b8fc763ebf9abe2fd747feaf6bc6968d8c", 40 | "size": 39899, 41 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-jemalloc.jar", 42 | "path": "org/lwjgl/lwjgl-jemalloc/3.1.6/lwjgl-jemalloc-3.1.6.jar" 43 | } 44 | }, 45 | "name": "org.lwjgl:lwjgl-jemalloc:3.1.6" 46 | }, 47 | { 48 | "downloads": { 49 | "artifact": { 50 | "sha1": "9b0884b8fc763ebf9abe2fd747feaf6bc6968d8c", 51 | "size": 39899, 52 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-jemalloc.jar", 53 | "path": "org/lwjgl/lwjgl-jemalloc/3.1.6/lwjgl-jemalloc-3.1.6.jar" 54 | }, 55 | "classifiers": { 56 | "natives-linux": { 57 | "sha1": "e3c8c26f433efc2e135b9f02a275742825560bfc", 58 | "size": 134237, 59 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-jemalloc-natives-linux-arm32.jar", 60 | "path": "org/lwjgl/lwjgl-jemalloc/3.1.6/lwjgl-jemalloc-3.1.6-natives-linux.jar" 61 | } 62 | } 63 | }, 64 | "name": "org.lwjgl:lwjgl-jemalloc:3.1.6", 65 | "natives": { 66 | "linux": "natives-linux" 67 | } 68 | }, 69 | { 70 | "downloads": { 71 | "artifact": { 72 | "sha1": "71cbf1f0f60dc7a9c522c5b76e7e62453ca7c77c", 73 | "size": 78718, 74 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-openal.jar", 75 | "path": "org/lwjgl/lwjgl-openal/3.1.6/lwjgl-openal-3.1.6.jar" 76 | } 77 | }, 78 | "name": "org.lwjgl:lwjgl-openal:3.1.6" 79 | }, 80 | { 81 | "downloads": { 82 | "artifact": { 83 | "sha1": "71cbf1f0f60dc7a9c522c5b76e7e62453ca7c77c", 84 | "size": 78718, 85 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-openal.jar", 86 | "path": "org/lwjgl/lwjgl-openal/3.1.6/lwjgl-openal-3.1.6.jar" 87 | }, 88 | "classifiers": { 89 | "natives-linux": { 90 | "sha1": "fafb2af9deeb64b52a1642ae853493e1f13f98a2", 91 | "size": 398418, 92 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-openal-natives-linux-arm32.jar", 93 | "path": "org/lwjgl/lwjgl-openal/3.1.6/lwjgl-openal-3.1.6-natives-linux.jar" 94 | } 95 | } 96 | }, 97 | "name": "org.lwjgl:lwjgl-openal:3.1.6", 98 | "natives": { 99 | "linux": "natives-linux" 100 | } 101 | }, 102 | { 103 | "downloads": { 104 | "artifact": { 105 | "sha1": "9a6b6e74b41c15b70964a79a32d4a9b04f614d9f", 106 | "size": 830047, 107 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-opengl.jar", 108 | "path": "org/lwjgl/lwjgl-opengl/3.1.6/lwjgl-opengl-3.1.6.jar" 109 | } 110 | }, 111 | "name": "org.lwjgl:lwjgl-opengl:3.1.6" 112 | }, 113 | { 114 | "downloads": { 115 | "artifact": { 116 | "sha1": "9a6b6e74b41c15b70964a79a32d4a9b04f614d9f", 117 | "size": 830047, 118 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-opengl.jar", 119 | "path": "org/lwjgl/lwjgl-opengl/3.1.6/lwjgl-opengl-3.1.6.jar" 120 | }, 121 | "classifiers": { 122 | "natives-linux": { 123 | "sha1": "a7922f4e7be6aae0483432cac5ee7da7b0748346", 124 | "size": 65526, 125 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-opengl-natives-linux-arm32.jar", 126 | "path": "org/lwjgl/lwjgl-opengl/3.1.6/lwjgl-opengl-3.1.6-natives-linux.jar" 127 | } 128 | } 129 | }, 130 | "name": "org.lwjgl:lwjgl-opengl:3.1.6", 131 | "natives": { 132 | "linux": "natives-linux" 133 | } 134 | }, 135 | { 136 | "downloads": { 137 | "artifact": { 138 | "sha1": "f978d3bf16a4ba09dafeb3d5563786cb7002129c", 139 | "size": 114229, 140 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-glfw.jar", 141 | "path": "org/lwjgl/lwjgl-glfw/3.1.6/lwjgl-glfw-3.1.6.jar" 142 | } 143 | }, 144 | "name": "org.lwjgl:lwjgl-glfw:3.1.6" 145 | }, 146 | { 147 | "downloads": { 148 | "artifact": { 149 | "sha1": "f978d3bf16a4ba09dafeb3d5563786cb7002129c", 150 | "size": 114229, 151 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-glfw.jar", 152 | "path": "org/lwjgl/lwjgl-glfw/3.1.6/lwjgl-glfw-3.1.6.jar" 153 | }, 154 | "classifiers": { 155 | "natives-linux": { 156 | "sha1": "0c1dc55fed2fe336c256206a2b49fc54107115f5", 157 | "size": 80186, 158 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-glfw-natives-linux-arm32.jar", 159 | "path": "org/lwjgl/lwjgl-glfw/3.1.6/lwjgl-glfw-3.1.6-natives-linux.jar" 160 | } 161 | } 162 | }, 163 | "name": "org.lwjgl:lwjgl-glfw:3.1.6", 164 | "natives": { 165 | "linux": "natives-linux" 166 | } 167 | }, 168 | { 169 | "downloads": { 170 | "artifact": { 171 | "sha1": "bc9e649120027fc78cfebabc17b00ba50e16a86a", 172 | "size": 104372, 173 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-stb.jar", 174 | "path": "org/lwjgl/lwjgl-stb/3.1.6/lwjgl-stb-3.1.6.jar" 175 | } 176 | }, 177 | "name": "org.lwjgl:lwjgl-stb:3.1.6" 178 | }, 179 | { 180 | "downloads": { 181 | "artifact": { 182 | "sha1": "bc9e649120027fc78cfebabc17b00ba50e16a86a", 183 | "size": 104372, 184 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-stb.jar", 185 | "path": "org/lwjgl/lwjgl-stb/3.1.6/lwjgl-stb-3.1.6.jar" 186 | }, 187 | "classifiers": { 188 | "natives-linux": { 189 | "sha1": "bdf6e31bf49d466cc497444f1be31dbd522e108a", 190 | "size": 143311, 191 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-stb-natives-linux-arm32.jar", 192 | "path": "org/lwjgl/lwjgl-stb/3.1.6/lwjgl-stb-3.1.6-natives-linux.jar" 193 | } 194 | } 195 | }, 196 | "name": "org.lwjgl:lwjgl-stb:3.1.6", 197 | "natives": { 198 | "linux": "natives-linux" 199 | } 200 | } 201 | ] 202 | } -------------------------------------------------------------------------------- /assets/LWJGL/aarch/3.1.6.json: -------------------------------------------------------------------------------- 1 | { 2 | "libraries": [ 3 | { 4 | "downloads": { 5 | "artifact": { 6 | "sha1": "d2df40234fd576e708feee78bccadaf02c5712a3", 7 | "size": 300107, 8 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-core.jar", 9 | "path": "org/lwjgl/lwjgl/3.1.6/lwjgl-3.1.6.jar" 10 | } 11 | }, 12 | "name": "org.lwjgl:lwjgl:3.1.6" 13 | }, 14 | { 15 | "downloads": { 16 | "artifact": { 17 | "sha1": "d2df40234fd576e708feee78bccadaf02c5712a3", 18 | "size": 300107, 19 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-core.jar", 20 | "path": "org/lwjgl/lwjgl/3.1.6/lwjgl-3.1.6.jar" 21 | }, 22 | "classifiers": { 23 | "natives-linux": { 24 | "sha1": "1d4e6397a4ba0df30f7477ee5ba308d4dad3387e", 25 | "size": 59165, 26 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-natives-linux-arm32.jar", 27 | "path": "org/lwjgl/lwjgl/3.1.6/lwjgl-3.1.6-natives-linux.jar" 28 | } 29 | } 30 | }, 31 | "name": "org.lwjgl:lwjgl:3.1.6", 32 | "natives": { 33 | "linux": "natives-linux" 34 | } 35 | }, 36 | { 37 | "downloads": { 38 | "artifact": { 39 | "sha1": "9b0884b8fc763ebf9abe2fd747feaf6bc6968d8c", 40 | "size": 39899, 41 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-jemalloc.jar", 42 | "path": "org/lwjgl/lwjgl-jemalloc/3.1.6/lwjgl-jemalloc-3.1.6.jar" 43 | } 44 | }, 45 | "name": "org.lwjgl:lwjgl-jemalloc:3.1.6" 46 | }, 47 | { 48 | "downloads": { 49 | "artifact": { 50 | "sha1": "9b0884b8fc763ebf9abe2fd747feaf6bc6968d8c", 51 | "size": 39899, 52 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-jemalloc.jar", 53 | "path": "org/lwjgl/lwjgl-jemalloc/3.1.6/lwjgl-jemalloc-3.1.6.jar" 54 | }, 55 | "classifiers": { 56 | "natives-linux": { 57 | "sha1": "e3c8c26f433efc2e135b9f02a275742825560bfc", 58 | "size": 134237, 59 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-jemalloc-natives-linux-arm32.jar", 60 | "path": "org/lwjgl/lwjgl-jemalloc/3.1.6/lwjgl-jemalloc-3.1.6-natives-linux.jar" 61 | } 62 | } 63 | }, 64 | "name": "org.lwjgl:lwjgl-jemalloc:3.1.6", 65 | "natives": { 66 | "linux": "natives-linux" 67 | } 68 | }, 69 | { 70 | "downloads": { 71 | "artifact": { 72 | "sha1": "71cbf1f0f60dc7a9c522c5b76e7e62453ca7c77c", 73 | "size": 78718, 74 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-openal.jar", 75 | "path": "org/lwjgl/lwjgl-openal/3.1.6/lwjgl-openal-3.1.6.jar" 76 | } 77 | }, 78 | "name": "org.lwjgl:lwjgl-openal:3.1.6" 79 | }, 80 | { 81 | "downloads": { 82 | "artifact": { 83 | "sha1": "71cbf1f0f60dc7a9c522c5b76e7e62453ca7c77c", 84 | "size": 78718, 85 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-openal.jar", 86 | "path": "org/lwjgl/lwjgl-openal/3.1.6/lwjgl-openal-3.1.6.jar" 87 | }, 88 | "classifiers": { 89 | "natives-linux": { 90 | "sha1": "fafb2af9deeb64b52a1642ae853493e1f13f98a2", 91 | "size": 398418, 92 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-openal-natives-linux-arm32.jar", 93 | "path": "org/lwjgl/lwjgl-openal/3.1.6/lwjgl-openal-3.1.6-natives-linux.jar" 94 | } 95 | } 96 | }, 97 | "name": "org.lwjgl:lwjgl-openal:3.1.6", 98 | "natives": { 99 | "linux": "natives-linux" 100 | } 101 | }, 102 | { 103 | "downloads": { 104 | "artifact": { 105 | "sha1": "9a6b6e74b41c15b70964a79a32d4a9b04f614d9f", 106 | "size": 830047, 107 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-opengl.jar", 108 | "path": "org/lwjgl/lwjgl-opengl/3.1.6/lwjgl-opengl-3.1.6.jar" 109 | } 110 | }, 111 | "name": "org.lwjgl:lwjgl-opengl:3.1.6" 112 | }, 113 | { 114 | "downloads": { 115 | "artifact": { 116 | "sha1": "9a6b6e74b41c15b70964a79a32d4a9b04f614d9f", 117 | "size": 830047, 118 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-opengl.jar", 119 | "path": "org/lwjgl/lwjgl-opengl/3.1.6/lwjgl-opengl-3.1.6.jar" 120 | }, 121 | "classifiers": { 122 | "natives-linux": { 123 | "sha1": "a7922f4e7be6aae0483432cac5ee7da7b0748346", 124 | "size": 65526, 125 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-opengl-natives-linux-arm32.jar", 126 | "path": "org/lwjgl/lwjgl-opengl/3.1.6/lwjgl-opengl-3.1.6-natives-linux.jar" 127 | } 128 | } 129 | }, 130 | "name": "org.lwjgl:lwjgl-opengl:3.1.6", 131 | "natives": { 132 | "linux": "natives-linux" 133 | } 134 | }, 135 | { 136 | "downloads": { 137 | "artifact": { 138 | "sha1": "f978d3bf16a4ba09dafeb3d5563786cb7002129c", 139 | "size": 114229, 140 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-glfw.jar", 141 | "path": "org/lwjgl/lwjgl-glfw/3.1.6/lwjgl-glfw-3.1.6.jar" 142 | } 143 | }, 144 | "name": "org.lwjgl:lwjgl-glfw:3.1.6" 145 | }, 146 | { 147 | "downloads": { 148 | "artifact": { 149 | "sha1": "f978d3bf16a4ba09dafeb3d5563786cb7002129c", 150 | "size": 114229, 151 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-glfw.jar", 152 | "path": "org/lwjgl/lwjgl-glfw/3.1.6/lwjgl-glfw-3.1.6.jar" 153 | }, 154 | "classifiers": { 155 | "natives-linux": { 156 | "sha1": "0c1dc55fed2fe336c256206a2b49fc54107115f5", 157 | "size": 80186, 158 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-glfw-natives-linux-arm32.jar", 159 | "path": "org/lwjgl/lwjgl-glfw/3.1.6/lwjgl-glfw-3.1.6-natives-linux.jar" 160 | } 161 | } 162 | }, 163 | "name": "org.lwjgl:lwjgl-glfw:3.1.6", 164 | "natives": { 165 | "linux": "natives-linux" 166 | } 167 | }, 168 | { 169 | "downloads": { 170 | "artifact": { 171 | "sha1": "bc9e649120027fc78cfebabc17b00ba50e16a86a", 172 | "size": 104372, 173 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-stb.jar", 174 | "path": "org/lwjgl/lwjgl-stb/3.1.6/lwjgl-stb-3.1.6.jar" 175 | } 176 | }, 177 | "name": "org.lwjgl:lwjgl-stb:3.1.6" 178 | }, 179 | { 180 | "downloads": { 181 | "artifact": { 182 | "sha1": "bc9e649120027fc78cfebabc17b00ba50e16a86a", 183 | "size": 104372, 184 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-stb.jar", 185 | "path": "org/lwjgl/lwjgl-stb/3.1.6/lwjgl-stb-3.1.6.jar" 186 | }, 187 | "classifiers": { 188 | "natives-linux": { 189 | "sha1": "bdf6e31bf49d466cc497444f1be31dbd522e108a", 190 | "size": 143311, 191 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.1.6/lwjgl-stb-natives-linux-arm32.jar", 192 | "path": "org/lwjgl/lwjgl-stb/3.1.6/lwjgl-stb-3.1.6-natives-linux.jar" 193 | } 194 | } 195 | }, 196 | "name": "org.lwjgl:lwjgl-stb:3.1.6", 197 | "natives": { 198 | "linux": "natives-linux" 199 | } 200 | } 201 | ] 202 | } -------------------------------------------------------------------------------- /assets/LWJGL/aarch/3.2.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "libraries": [ 3 | { 4 | "downloads": { 5 | "artifact": { 6 | "sha1": "c1f8d244dda855a936e136844a5c80611a5f36fe", 7 | "size": 314536, 8 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.1/lwjgl-core.jar", 9 | "path": "org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1.jar" 10 | } 11 | }, 12 | "name": "org.lwjgl:lwjgl:3.2.1" 13 | }, 14 | { 15 | "downloads": { 16 | "artifact": { 17 | "sha1": "c1f8d244dda855a936e136844a5c80611a5f36fe", 18 | "size": 314536, 19 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.1/lwjgl-core.jar", 20 | "path": "org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1.jar" 21 | }, 22 | "classifiers": { 23 | "natives-linux": { 24 | "sha1": "a50f6e12091dccd4901e783b168b428f7653d254", 25 | "size": 65481, 26 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.1/lwjgl-natives-linux-arm32.jar", 27 | "path": "org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1-natives-linux.jar" 28 | } 29 | } 30 | }, 31 | "name": "org.lwjgl:lwjgl:3.2.1", 32 | "natives": { 33 | "linux": "natives-linux" 34 | } 35 | }, 36 | { 37 | "downloads": { 38 | "artifact": { 39 | "sha1": "f8f7801d8b82af7705f06c40bbea16b066479531", 40 | "size": 37712, 41 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.1/lwjgl-jemalloc.jar", 42 | "path": "org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1.jar" 43 | } 44 | }, 45 | "name": "org.lwjgl:lwjgl-jemalloc:3.2.1" 46 | }, 47 | { 48 | "downloads": { 49 | "artifact": { 50 | "sha1": "f8f7801d8b82af7705f06c40bbea16b066479531", 51 | "size": 37712, 52 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.1/lwjgl-jemalloc.jar", 53 | "path": "org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1.jar" 54 | }, 55 | "classifiers": { 56 | "natives-linux": { 57 | "sha1": "e19e402887625f15a982426156976badcdffaadc", 58 | "size": 134237, 59 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.1/lwjgl-jemalloc-natives-linux-arm32.jar", 60 | "path": "org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1-natives-linux.jar" 61 | } 62 | } 63 | }, 64 | "name": "org.lwjgl:lwjgl-jemalloc:3.2.1", 65 | "natives": { 66 | "linux": "natives-linux" 67 | } 68 | }, 69 | { 70 | "downloads": { 71 | "artifact": { 72 | "sha1": "3dcb4c151a8ccf65f50f4aee9f6ff30a79bb7439", 73 | "size": 79683, 74 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.1/lwjgl-openal.jar", 75 | "path": "org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1.jar" 76 | } 77 | }, 78 | "name": "org.lwjgl:lwjgl-openal:3.2.1" 79 | }, 80 | { 81 | "downloads": { 82 | "artifact": { 83 | "sha1": "3dcb4c151a8ccf65f50f4aee9f6ff30a79bb7439", 84 | "size": 79683, 85 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.1/lwjgl-openal.jar", 86 | "path": "org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1.jar" 87 | }, 88 | "classifiers": { 89 | "natives-linux": { 90 | "sha1": "0dce4b9a444fcb0a4e5b75ea758b0094049daea3", 91 | "size": 398418, 92 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.1/lwjgl-openal-natives-linux-arm32.jar", 93 | "path": "org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1-natives-linux.jar" 94 | } 95 | } 96 | }, 97 | "name": "org.lwjgl:lwjgl-openal:3.2.1", 98 | "natives": { 99 | "linux": "natives-linux" 100 | } 101 | }, 102 | { 103 | "downloads": { 104 | "artifact": { 105 | "sha1": "2350cc2bd1fe80e14ff2c39a81477b57dccfe09a", 106 | "size": 939248, 107 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.1/lwjgl-opengl.jar", 108 | "path": "org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1.jar" 109 | } 110 | }, 111 | "name": "org.lwjgl:lwjgl-opengl:3.2.1" 112 | }, 113 | { 114 | "downloads": { 115 | "artifact": { 116 | "sha1": "2350cc2bd1fe80e14ff2c39a81477b57dccfe09a", 117 | "size": 939248, 118 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.1/lwjgl-opengl.jar", 119 | "path": "org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1.jar" 120 | }, 121 | "classifiers": { 122 | "natives-linux": { 123 | "sha1": "a6d3ff86fe3e07bd055032e93ce3b8952574a427", 124 | "size": 56387, 125 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.1/lwjgl-opengl-natives-linux-arm32.jar", 126 | "path": "org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1-natives-linux.jar" 127 | } 128 | } 129 | }, 130 | "name": "org.lwjgl:lwjgl-opengl:3.2.1", 131 | "natives": { 132 | "linux": "natives-linux" 133 | } 134 | }, 135 | { 136 | "downloads": { 137 | "artifact": { 138 | "sha1": "f245bcd89c484e05b524c25ea9935b6aa1e6d7ac", 139 | "size": 116839, 140 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.1/lwjgl-glfw.jar", 141 | "path": "org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1.jar" 142 | } 143 | }, 144 | "name": "org.lwjgl:lwjgl-glfw:3.2.1" 145 | }, 146 | { 147 | "downloads": { 148 | "artifact": { 149 | "sha1": "f245bcd89c484e05b524c25ea9935b6aa1e6d7ac", 150 | "size": 116839, 151 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.1/lwjgl-glfw.jar", 152 | "path": "org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1.jar" 153 | }, 154 | "classifiers": { 155 | "natives-linux": { 156 | "sha1": "14533fb79a7077b2eb1d156067956d2da9f3403f", 157 | "size": 80186, 158 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.1/lwjgl-glfw-natives-linux-arm32.jar", 159 | "path": "org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1-natives-linux.jar" 160 | } 161 | } 162 | }, 163 | "name": "org.lwjgl:lwjgl-glfw:3.2.1", 164 | "natives": { 165 | "linux": "natives-linux" 166 | } 167 | }, 168 | { 169 | "downloads": { 170 | "artifact": { 171 | "sha1": "acd384013d30ea9ddddd805e9a5996b2b6058c5c", 172 | "size": 105432, 173 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.1/lwjgl-stb.jar", 174 | "path": "org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1.jar" 175 | } 176 | }, 177 | "name": "org.lwjgl:lwjgl-stb:3.2.1" 178 | }, 179 | { 180 | "downloads": { 181 | "artifact": { 182 | "sha1": "acd384013d30ea9ddddd805e9a5996b2b6058c5c", 183 | "size": 105432, 184 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.1/lwjgl-stb.jar", 185 | "path": "org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1.jar" 186 | }, 187 | "classifiers": { 188 | "natives-linux": { 189 | "sha1": "bc5bb97dbb328df0c82375637030f692a161d082", 190 | "size": 144685, 191 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.1/lwjgl-stb-natives-linux-arm32.jar", 192 | "path": "org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1-natives-linux.jar" 193 | } 194 | } 195 | }, 196 | "name": "org.lwjgl:lwjgl-stb:3.2.1", 197 | "natives": { 198 | "linux": "natives-linux" 199 | } 200 | } 201 | ] 202 | } -------------------------------------------------------------------------------- /assets/LWJGL/aarch/3.2.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "libraries": [ 3 | { 4 | "downloads": { 5 | "artifact": { 6 | "sha1": "16ea3934fca417368250d1ddac01a30c1809d317", 7 | "size": 318413, 8 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-core.jar", 9 | "path": "org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2.jar" 10 | } 11 | }, 12 | "name": "org.lwjgl:lwjgl:3.2.2" 13 | }, 14 | { 15 | "downloads": { 16 | "artifact": { 17 | "sha1": "16ea3934fca417368250d1ddac01a30c1809d317", 18 | "size": 318413, 19 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-core.jar", 20 | "path": "org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2.jar" 21 | }, 22 | "classifiers": { 23 | "natives-linux": { 24 | "sha1": "6bd0b37fef777a309936a72dc7f63126e8c79ea5", 25 | "size": 90296, 26 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-natives-linux-arm32.jar", 27 | "path": "org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2-natives-linux.jar" 28 | } 29 | } 30 | }, 31 | "name": "org.lwjgl:lwjgl:3.2.2", 32 | "natives": { 33 | "linux": "natives-linux" 34 | } 35 | }, 36 | { 37 | "downloads": { 38 | "artifact": { 39 | "sha1": "8224ae2e8fc6d8e1a0fc7d84dc917aa3c440620c", 40 | "size": 33790, 41 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-jemalloc.jar", 42 | "path": "org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2.jar" 43 | } 44 | }, 45 | "name": "org.lwjgl:lwjgl-jemalloc:3.2.2" 46 | }, 47 | { 48 | "downloads": { 49 | "artifact": { 50 | "sha1": "8224ae2e8fc6d8e1a0fc7d84dc917aa3c440620c", 51 | "size": 33790, 52 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-jemalloc.jar", 53 | "path": "org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2.jar" 54 | }, 55 | "classifiers": { 56 | "natives-linux": { 57 | "sha1": "9163a2a5559ef87bc13ead8fea84417ea3928748", 58 | "size": 134237, 59 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-jemalloc-natives-linux-arm32.jar", 60 | "path": "org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2-natives-linux.jar" 61 | } 62 | } 63 | }, 64 | "name": "org.lwjgl:lwjgl-jemalloc:3.2.2", 65 | "natives": { 66 | "linux": "natives-linux" 67 | } 68 | }, 69 | { 70 | "downloads": { 71 | "artifact": { 72 | "sha1": "304f0571fd5971621ee6da86a4c1e90f6f52e2ee", 73 | "size": 79582, 74 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-openal.jar", 75 | "path": "org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2.jar" 76 | } 77 | }, 78 | "name": "org.lwjgl:lwjgl-openal:3.2.2" 79 | }, 80 | { 81 | "downloads": { 82 | "artifact": { 83 | "sha1": "304f0571fd5971621ee6da86a4c1e90f6f52e2ee", 84 | "size": 79582, 85 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-openal.jar", 86 | "path": "org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2.jar" 87 | }, 88 | "classifiers": { 89 | "natives-linux": { 90 | "sha1": "ecbc981fdd996492a1f6334f003ed62e5a8c0cd5", 91 | "size": 398418, 92 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-openal-natives-linux-arm32.jar", 93 | "path": "org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2-natives-linux.jar" 94 | } 95 | } 96 | }, 97 | "name": "org.lwjgl:lwjgl-openal:3.2.2", 98 | "natives": { 99 | "linux": "natives-linux" 100 | } 101 | }, 102 | { 103 | "downloads": { 104 | "artifact": { 105 | "sha1": "9762ae928d02147e716cd82e929b74a97ea9600a", 106 | "size": 937609, 107 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-opengl.jar", 108 | "path": "org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2.jar" 109 | } 110 | }, 111 | "name": "org.lwjgl:lwjgl-opengl:3.2.2" 112 | }, 113 | { 114 | "downloads": { 115 | "artifact": { 116 | "sha1": "9762ae928d02147e716cd82e929b74a97ea9600a", 117 | "size": 937609, 118 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-opengl.jar", 119 | "path": "org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2.jar" 120 | }, 121 | "classifiers": { 122 | "natives-linux": { 123 | "sha1": "3af5599c74dd76dd8dbb567b3f9b4963a6abeed5", 124 | "size": 56388, 125 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-opengl-natives-linux-arm32.jar", 126 | "path": "org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2-natives-linux.jar" 127 | } 128 | } 129 | }, 130 | "name": "org.lwjgl:lwjgl-opengl:3.2.2", 131 | "natives": { 132 | "linux": "natives-linux" 133 | } 134 | }, 135 | { 136 | "downloads": { 137 | "artifact": { 138 | "sha1": "99e9a39fa8ed4167e3ff9e04d47eb32c9e69804d", 139 | "size": 108691, 140 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-glfw.jar", 141 | "path": "org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2.jar" 142 | } 143 | }, 144 | "name": "org.lwjgl:lwjgl-glfw:3.2.2" 145 | }, 146 | { 147 | "downloads": { 148 | "artifact": { 149 | "sha1": "99e9a39fa8ed4167e3ff9e04d47eb32c9e69804d", 150 | "size": 108691, 151 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-glfw.jar", 152 | "path": "org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2.jar" 153 | }, 154 | "classifiers": { 155 | "natives-linux": { 156 | "sha1": "4265f2fbe3b9d642591165165a17cf406cf7b98e", 157 | "size": 80186, 158 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-glfw-natives-linux-arm32.jar", 159 | "path": "org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2-natives-linux.jar" 160 | } 161 | } 162 | }, 163 | "name": "org.lwjgl:lwjgl-glfw:3.2.2", 164 | "natives": { 165 | "linux": "natives-linux" 166 | } 167 | }, 168 | { 169 | "downloads": { 170 | "artifact": { 171 | "sha1": "ea979b0af45b8e689f5f47c989aa8550c148d8a2", 172 | "size": 104075, 173 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-stb.jar", 174 | "path": "org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2.jar" 175 | } 176 | }, 177 | "name": "org.lwjgl:lwjgl-stb:3.2.2" 178 | }, 179 | { 180 | "downloads": { 181 | "artifact": { 182 | "sha1": "ea979b0af45b8e689f5f47c989aa8550c148d8a2", 183 | "size": 104075, 184 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-stb.jar", 185 | "path": "org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2.jar" 186 | }, 187 | "classifiers": { 188 | "natives-linux": { 189 | "sha1": "ec9d70aaebd0ff76dfeecf8f00b56118bf3706b1", 190 | "size": 149387, 191 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-stb-natives-linux-arm32.jar", 192 | "path": "org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2-natives-linux.jar" 193 | } 194 | } 195 | }, 196 | "name": "org.lwjgl:lwjgl-stb:3.2.2", 197 | "natives": { 198 | "linux": "natives-linux" 199 | } 200 | }, 201 | { 202 | "downloads": { 203 | "artifact": { 204 | "sha1": "a8c09f5b7fa24bd53ec329c231b566497a163d5b", 205 | "size": 5571, 206 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-tinyfd.jar", 207 | "path": "org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar" 208 | } 209 | }, 210 | "name": "org.lwjgl:lwjgl-tinyfd:3.2.2" 211 | }, 212 | { 213 | "downloads": { 214 | "artifact": { 215 | "sha1": "a8c09f5b7fa24bd53ec329c231b566497a163d5b", 216 | "size": 5571, 217 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-tinyfd.jar", 218 | "path": "org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar" 219 | }, 220 | "classifiers": { 221 | "natives-linux": { 222 | "sha1": "82d16054ada6633297a3108fb6d8bae98800c76f", 223 | "size": 41663, 224 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-tinyfd-natives-linux-arm32.jar", 225 | "path": "org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-linux.jar" 226 | } 227 | } 228 | }, 229 | "name": "org.lwjgl:lwjgl-tinyfd:3.2.2", 230 | "natives": { 231 | "linux": "natives-linux" 232 | } 233 | } 234 | ] 235 | } -------------------------------------------------------------------------------- /assets/LWJGL/aarch/3.3.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "libraries": [ 3 | { 4 | "downloads": { 5 | "artifact": { 6 | "sha1": "cbac1b8d30cb4795149c1ef540f912671a8616d0", 7 | "size": 128801, 8 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1.jar", 9 | "path": "org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1.jar" 10 | } 11 | }, 12 | "name": "org.lwjgl:lwjgl-glfw:3.3.1" 13 | }, 14 | { 15 | "downloads": { 16 | "artifact": { 17 | "sha1": "cbac1b8d30cb4795149c1ef540f912671a8616d0", 18 | "size": 128801, 19 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1.jar", 20 | "path": "org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1.jar" 21 | }, 22 | "classifiers": { 23 | "natives-linux": { 24 | "sha1": "816d935933f2dd743074c4e717cc25b55720f294", 25 | "size": 104027, 26 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-linux-arm32.jar", 27 | "path": "org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-linux.jar" 28 | }, 29 | "sources": { 30 | "sha1": "e502700e6a1a0d02bddb8b4ef85afcdc15c88358", 31 | "size": 125778, 32 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-sources.jar" 33 | } 34 | } 35 | }, 36 | "name": "org.lwjgl:lwjgl-glfw:3.3.1", 37 | "natives": { 38 | "linux": "natives-linux" 39 | } 40 | }, 41 | { 42 | "downloads": { 43 | "artifact": { 44 | "sha1": "a817bcf213db49f710603677457567c37d53e103", 45 | "size": 36601, 46 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1.jar", 47 | "path": "org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1.jar" 48 | } 49 | }, 50 | "name": "org.lwjgl:lwjgl-jemalloc:3.3.1" 51 | }, 52 | { 53 | "downloads": { 54 | "artifact": { 55 | "sha1": "a817bcf213db49f710603677457567c37d53e103", 56 | "size": 36601, 57 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1.jar", 58 | "path": "org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1.jar" 59 | }, 60 | "classifiers": { 61 | "natives-linux": { 62 | "sha1": "a96a6d6cb3876d7813fcee53c3c24f246aeba3b3", 63 | "size": 136157, 64 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-linux-arm32.jar", 65 | "path": "org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-linux.jar" 66 | }, 67 | "sources": { 68 | "sha1": "f5858d34e06053b1866858fed7a685cf0c6b5926", 69 | "size": 32306, 70 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-sources.jar" 71 | } 72 | } 73 | }, 74 | "name": "org.lwjgl:lwjgl-jemalloc:3.3.1", 75 | "natives": { 76 | "linux": "natives-linux" 77 | } 78 | }, 79 | { 80 | "downloads": { 81 | "artifact": { 82 | "sha1": "2623a6b8ae1dfcd880738656a9f0243d2e6840bd", 83 | "size": 88237, 84 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1.jar", 85 | "path": "org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1.jar" 86 | } 87 | }, 88 | "name": "org.lwjgl:lwjgl-openal:3.3.1" 89 | }, 90 | { 91 | "downloads": { 92 | "artifact": { 93 | "sha1": "2623a6b8ae1dfcd880738656a9f0243d2e6840bd", 94 | "size": 88237, 95 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1.jar", 96 | "path": "org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1.jar" 97 | }, 98 | "classifiers": { 99 | "natives-linux": { 100 | "sha1": "ffbe35d7fa5ec9b7eca136a7c71f24d4025a510b", 101 | "size": 400129, 102 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-linux-arm32.jar", 103 | "path": "org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-linux.jar" 104 | }, 105 | "sources": { 106 | "sha1": "9c563bf7c10b71c6609b9f96a7c7859bdf05d21f", 107 | "size": 85417, 108 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-sources.jar" 109 | } 110 | } 111 | }, 112 | "name": "org.lwjgl:lwjgl-openal:3.3.1", 113 | "natives": { 114 | "linux": "natives-linux" 115 | } 116 | }, 117 | { 118 | "downloads": { 119 | "artifact": { 120 | "sha1": "831a5533a21a5f4f81bbc51bb13e9899319b5411", 121 | "size": 921563, 122 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1.jar", 123 | "path": "org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1.jar" 124 | } 125 | }, 126 | "name": "org.lwjgl:lwjgl-opengl:3.3.1" 127 | }, 128 | { 129 | "downloads": { 130 | "artifact": { 131 | "sha1": "831a5533a21a5f4f81bbc51bb13e9899319b5411", 132 | "size": 921563, 133 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1.jar", 134 | "path": "org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1.jar" 135 | }, 136 | "classifiers": { 137 | "natives-linux": { 138 | "sha1": "e3550fa91097fd56e361b4370fa822220fef3595", 139 | "size": 58474, 140 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-linux-arm32.jar", 141 | "path": "org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-linux.jar" 142 | }, 143 | "sources": { 144 | "sha1": "1a827bc02651fa44d32f424c380edc6d53f94a62", 145 | "size": 1274449, 146 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-sources.jar" 147 | } 148 | } 149 | }, 150 | "name": "org.lwjgl:lwjgl-opengl:3.3.1", 151 | "natives": { 152 | "linux": "natives-linux" 153 | } 154 | }, 155 | { 156 | "downloads": { 157 | "artifact": { 158 | "sha1": "b119297cf8ed01f247abe8685857f8e7fcf5980f", 159 | "size": 112380, 160 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1.jar", 161 | "path": "org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1.jar" 162 | } 163 | }, 164 | "name": "org.lwjgl:lwjgl-stb:3.3.1" 165 | }, 166 | { 167 | "downloads": { 168 | "artifact": { 169 | "sha1": "b119297cf8ed01f247abe8685857f8e7fcf5980f", 170 | "size": 112380, 171 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1.jar", 172 | "path": "org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1.jar" 173 | }, 174 | "classifiers": { 175 | "natives-linux": { 176 | "sha1": "b08226bab162c06ae69337d8a1b0ee0a3fdf0b90", 177 | "size": 153889, 178 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-linux-arm32.jar", 179 | "path": "org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-linux.jar" 180 | }, 181 | "sources": { 182 | "sha1": "22cb295464f44068add8443204ec8c85fd379cbe", 183 | "size": 103489, 184 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-sources.jar" 185 | } 186 | } 187 | }, 188 | "name": "org.lwjgl:lwjgl-stb:3.3.1", 189 | "natives": { 190 | "linux": "natives-linux" 191 | } 192 | }, 193 | { 194 | "downloads": { 195 | "artifact": { 196 | "sha1": "0ff1914111ef2e3e0110ef2dabc8d8cdaad82347", 197 | "size": 6767, 198 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1.jar", 199 | "path": "org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1.jar" 200 | } 201 | }, 202 | "name": "org.lwjgl:lwjgl-tinyfd:3.3.1" 203 | }, 204 | { 205 | "downloads": { 206 | "artifact": { 207 | "sha1": "0ff1914111ef2e3e0110ef2dabc8d8cdaad82347", 208 | "size": 6767, 209 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1.jar", 210 | "path": "org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1.jar" 211 | }, 212 | "classifiers": { 213 | "natives-linux": { 214 | "sha1": "d53d331e859217a61298fcbcf8d79137f3df345c", 215 | "size": 48061, 216 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-linux-arm32.jar", 217 | "path": "org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1.jar" 218 | }, 219 | "sources": { 220 | "sha1": "4784c20508b51386ce9d572632524a5bf47ccb40", 221 | "size": 5530, 222 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-sources.jar" 223 | } 224 | } 225 | }, 226 | "name": "org.lwjgl:lwjgl-tinyfd:3.3.1", 227 | "natives": { 228 | "linux": "natives-linux" 229 | } 230 | }, 231 | { 232 | "downloads": { 233 | "artifact": { 234 | "sha1": "ae58664f88e18a9bb2c77b063833ca7aaec484cb", 235 | "size": 724243, 236 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1.jar", 237 | "path": "org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1.jar" 238 | } 239 | }, 240 | "name": "org.lwjgl:lwjgl:3.3.1" 241 | }, 242 | { 243 | "downloads": { 244 | "artifact": { 245 | "sha1": "ae58664f88e18a9bb2c77b063833ca7aaec484cb", 246 | "size": 724243, 247 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1.jar", 248 | "path": "org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1.jar" 249 | }, 250 | "classifiers": { 251 | "natives-linux": { 252 | "sha1": "41a3c1dd15d6b964eb8196dde69720a3e3e5e969", 253 | "size": 82374, 254 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-linux-arm32.jar", 255 | "path": "org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-linux.jar" 256 | }, 257 | "sources": { 258 | "sha1": "e918fb595d1ca293a68807a9da8b519ea348a67a", 259 | "size": 572854, 260 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-sources.jar" 261 | } 262 | } 263 | }, 264 | "name": "org.lwjgl:lwjgl:3.3.1", 265 | "natives": { 266 | "linux": "natives-linux" 267 | } 268 | } 269 | ] 270 | } -------------------------------------------------------------------------------- /assets/LWJGL/aarch/3.3.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "libraries": [ 3 | { 4 | "downloads": { 5 | "artifact": { 6 | "sha1": "757920418805fb90bfebb3d46b1d9e7669fca2eb", 7 | "size": 135828, 8 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-glfw/3.3.2/lwjgl-glfw-3.3.2.jar", 9 | "path": "org/lwjgl/lwjgl-glfw/3.3.2/lwjgl-glfw-3.3.2.jar" 10 | } 11 | }, 12 | "name": "org.lwjgl:lwjgl-glfw:3.3.2" 13 | }, 14 | { 15 | "downloads": { 16 | "artifact": { 17 | "sha1": "757920418805fb90bfebb3d46b1d9e7669fca2eb", 18 | "size": 135828, 19 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-glfw/3.3.2/lwjgl-glfw-3.3.2.jar", 20 | "path": "org/lwjgl/lwjgl-glfw/3.3.2/lwjgl-glfw-3.3.2.jar" 21 | }, 22 | "classifiers": { 23 | "natives-linux": { 24 | "sha1": "5907d9a6b7c44fb0612a63bb1cff5992588f65be", 25 | "size": 110067, 26 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-glfw/3.3.2/lwjgl-glfw-3.3.2-natives-linux-arm32.jar", 27 | "path": "org/lwjgl/lwjgl-glfw/3.3.2/lwjgl-glfw-3.3.2-natives-linux.jar" 28 | }, 29 | "sources": { 30 | "sha1": "0bdd2ae91adb35fd7809b7ecf2d677546b26fe4f", 31 | "size": 126160, 32 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-glfw/3.3.2/lwjgl-glfw-3.3.2-sources.jar" 33 | } 34 | } 35 | }, 36 | "name": "org.lwjgl:lwjgl-glfw:3.3.2", 37 | "natives": { 38 | "linux": "natives-linux" 39 | } 40 | }, 41 | { 42 | "downloads": { 43 | "artifact": { 44 | "sha1": "877e17e39ebcd58a9c956dc3b5b777813de0873a", 45 | "size": 43233, 46 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-jemalloc/3.3.2/lwjgl-jemalloc-3.3.2.jar", 47 | "path": "org/lwjgl/lwjgl-jemalloc/3.3.2/lwjgl-jemalloc-3.3.2.jar" 48 | } 49 | }, 50 | "name": "org.lwjgl:lwjgl-jemalloc:3.3.2" 51 | }, 52 | { 53 | "downloads": { 54 | "artifact": { 55 | "sha1": "877e17e39ebcd58a9c956dc3b5b777813de0873a", 56 | "size": 43233, 57 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-jemalloc/3.3.2/lwjgl-jemalloc-3.3.2.jar", 58 | "path": "org/lwjgl/lwjgl-jemalloc/3.3.2/lwjgl-jemalloc-3.3.2.jar" 59 | }, 60 | "classifiers": { 61 | "natives-linux": { 62 | "sha1": "9367437ce192e4d6f5725d53d85520644c0b0d6f", 63 | "size": 177571, 64 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-jemalloc/3.3.2/lwjgl-jemalloc-3.3.2-natives-linux-arm32.jar", 65 | "path": "org/lwjgl/lwjgl-jemalloc/3.3.2/lwjgl-jemalloc-3.3.2-natives-linux.jar" 66 | }, 67 | "sources": { 68 | "sha1": "1d953086a319cfb09d0703e50011849a95ab2277", 69 | "size": 32303, 70 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-jemalloc/3.3.2/lwjgl-jemalloc-3.3.2-sources.jar" 71 | } 72 | } 73 | }, 74 | "name": "org.lwjgl:lwjgl-jemalloc:3.3.2", 75 | "natives": { 76 | "linux": "natives-linux" 77 | } 78 | }, 79 | { 80 | "downloads": { 81 | "artifact": { 82 | "sha1": "ae5357ed6d934546d3533993ea84c0cfb75eed95", 83 | "size": 108230, 84 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-openal/3.3.2/lwjgl-openal-3.3.2.jar", 85 | "path": "org/lwjgl/lwjgl-openal/3.3.2/lwjgl-openal-3.3.2.jar" 86 | } 87 | }, 88 | "name": "org.lwjgl:lwjgl-openal:3.3.2" 89 | }, 90 | { 91 | "downloads": { 92 | "artifact": { 93 | "sha1": "ae5357ed6d934546d3533993ea84c0cfb75eed95", 94 | "size": 108230, 95 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-openal/3.3.2/lwjgl-openal-3.3.2.jar", 96 | "path": "org/lwjgl/lwjgl-openal/3.3.2/lwjgl-openal-3.3.2.jar" 97 | }, 98 | "classifiers": { 99 | "natives-linux": { 100 | "sha1": "7c82bbc33ef49ee4094b216c940db564b2998224", 101 | "size": 503352, 102 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-openal/3.3.2/lwjgl-openal-3.3.2-natives-linux-arm32.jar", 103 | "path": "org/lwjgl/lwjgl-openal/3.3.2/lwjgl-openal-3.3.2-natives-linux.jar" 104 | }, 105 | "sources": { 106 | "sha1": "534195bc70b8ff83c270c1d618cdafe76e9be2c4", 107 | "size": 100606, 108 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-openal/3.3.2/lwjgl-openal-3.3.2-sources.jar" 109 | } 110 | } 111 | }, 112 | "name": "org.lwjgl:lwjgl-openal:3.3.2", 113 | "natives": { 114 | "linux": "natives-linux" 115 | } 116 | }, 117 | { 118 | "downloads": { 119 | "artifact": { 120 | "sha1": "ee8e95be0b438602038bc1f02dc5e3d011b1b216", 121 | "size": 928871, 122 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-opengl/3.3.2/lwjgl-opengl-3.3.2.jar", 123 | "path": "org/lwjgl/lwjgl-opengl/3.3.2/lwjgl-opengl-3.3.2.jar" 124 | } 125 | }, 126 | "name": "org.lwjgl:lwjgl-opengl:3.3.2" 127 | }, 128 | { 129 | "downloads": { 130 | "artifact": { 131 | "sha1": "ee8e95be0b438602038bc1f02dc5e3d011b1b216", 132 | "size": 928871, 133 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-opengl/3.3.2/lwjgl-opengl-3.3.2.jar", 134 | "path": "org/lwjgl/lwjgl-opengl/3.3.2/lwjgl-opengl-3.3.2.jar" 135 | }, 136 | "classifiers": { 137 | "natives-linux": { 138 | "sha1": "821f9a2d1d583c44893f42b96f6977682b48a99b", 139 | "size": 59265, 140 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-opengl/3.3.2/lwjgl-opengl-3.3.2-natives-linux-arm32.jar", 141 | "path": "org/lwjgl/lwjgl-opengl/3.3.2/lwjgl-opengl-3.3.2-natives-linux.jar" 142 | }, 143 | "sources": { 144 | "sha1": "1301ff0d9814ac96d7020f5912d5f0f72c039fca", 145 | "size": 1275908, 146 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-opengl/3.3.2/lwjgl-opengl-3.3.2-sources.jar" 147 | } 148 | } 149 | }, 150 | "name": "org.lwjgl:lwjgl-opengl:3.3.2", 151 | "natives": { 152 | "linux": "natives-linux" 153 | } 154 | }, 155 | { 156 | "downloads": { 157 | "artifact": { 158 | "sha1": "a2550795014d622b686e9caac50b14baa87d2c70", 159 | "size": 118874, 160 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-stb/3.3.2/lwjgl-stb-3.3.2.jar", 161 | "path": "org/lwjgl/lwjgl-stb/3.3.2/lwjgl-stb-3.3.2.jar" 162 | } 163 | }, 164 | "name": "org.lwjgl:lwjgl-stb:3.3.2" 165 | }, 166 | { 167 | "downloads": { 168 | "artifact": { 169 | "sha1": "a2550795014d622b686e9caac50b14baa87d2c70", 170 | "size": 118874, 171 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-stb/3.3.2/lwjgl-stb-3.3.2.jar", 172 | "path": "org/lwjgl/lwjgl-stb/3.3.2/lwjgl-stb-3.3.2.jar" 173 | }, 174 | "classifiers": { 175 | "natives-linux": { 176 | "sha1": "ca9333da184aade20757151f4615f1e27ca521ae", 177 | "size": 154928, 178 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-stb/3.3.2/lwjgl-stb-3.3.2-natives-linux-arm32.jar", 179 | "path": "org/lwjgl/lwjgl-stb/3.3.2/lwjgl-stb-3.3.2-natives-linux.jar" 180 | }, 181 | "sources": { 182 | "sha1": "dda437f20ae0c920c1c744984b4093889982b994", 183 | "size": 103496, 184 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-stb/3.3.2/lwjgl-stb-3.3.2-sources.jar" 185 | } 186 | } 187 | }, 188 | "name": "org.lwjgl:lwjgl-stb:3.3.2", 189 | "natives": { 190 | "linux": "natives-linux" 191 | } 192 | }, 193 | { 194 | "downloads": { 195 | "artifact": { 196 | "sha1": "9f65c248dd77934105274fcf8351abb75b34327c", 197 | "size": 13404, 198 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-tinyfd/3.3.2/lwjgl-tinyfd-3.3.2.jar", 199 | "path": "org/lwjgl/lwjgl-tinyfd/3.3.2/lwjgl-tinyfd-3.3.2.jar" 200 | } 201 | }, 202 | "name": "org.lwjgl:lwjgl-tinyfd:3.3.2" 203 | }, 204 | { 205 | "downloads": { 206 | "artifact": { 207 | "sha1": "9f65c248dd77934105274fcf8351abb75b34327c", 208 | "size": 13404, 209 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-tinyfd/3.3.2/lwjgl-tinyfd-3.3.2.jar", 210 | "path": "org/lwjgl/lwjgl-tinyfd/3.3.2/lwjgl-tinyfd-3.3.2.jar" 211 | }, 212 | "classifiers": { 213 | "natives-linux": { 214 | "sha1": "807e220913aa0740449ff90d3b3d825cf5f359ed", 215 | "size": 48788, 216 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-tinyfd/3.3.2/lwjgl-tinyfd-3.3.2-natives-linux-arm32.jar", 217 | "path": "org/lwjgl/lwjgl-tinyfd/3.3.2/lwjgl-tinyfd-3.3.2.jar" 218 | }, 219 | "sources": { 220 | "sha1": "bd33407b8cdbac1161c759656034d283f4708051", 221 | "size": 5527, 222 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-tinyfd/3.3.2/lwjgl-tinyfd-3.3.2-sources.jar" 223 | } 224 | } 225 | }, 226 | "name": "org.lwjgl:lwjgl-tinyfd:3.3.2", 227 | "natives": { 228 | "linux": "natives-linux" 229 | } 230 | }, 231 | { 232 | "downloads": { 233 | "artifact": { 234 | "sha1": "4421d94af68e35dcaa31737a6fc59136a1e61b94", 235 | "size": 786196, 236 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2.jar", 237 | "path": "org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2.jar" 238 | } 239 | }, 240 | "name": "org.lwjgl:lwjgl:3.3.2" 241 | }, 242 | { 243 | "downloads": { 244 | "artifact": { 245 | "sha1": "4421d94af68e35dcaa31737a6fc59136a1e61b94", 246 | "size": 786196, 247 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2.jar", 248 | "path": "org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2.jar" 249 | }, 250 | "classifiers": { 251 | "natives-linux": { 252 | "sha1": "afcbfaaa46f217e98a6da4208550f71de1f2a225", 253 | "size": 89347, 254 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2-natives-linux-arm32.jar", 255 | "path": "org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2-natives-linux.jar" 256 | }, 257 | "sources": { 258 | "sha1": "aff949f8180d6d1e26a47c7a2bca8163f5b987fe", 259 | "size": 624340, 260 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2-sources.jar" 261 | } 262 | } 263 | }, 264 | "name": "org.lwjgl:lwjgl:3.3.2", 265 | "natives": { 266 | "linux": "natives-linux" 267 | } 268 | } 269 | ] 270 | } -------------------------------------------------------------------------------- /assets/LWJGL/aarch64/2.9.4.json: -------------------------------------------------------------------------------- 1 | { 2 | "libraries": [ 3 | { 4 | "downloads": { 5 | "classifiers": { 6 | "natives-linux": { 7 | "path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar", 8 | "sha1": "42b388ccb7c63cec4e9f24f4dddef33325f8b212", 9 | "size": 10932, 10 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-2.9.4/jinput-platform-2.0.5-natives-linux.jar" 11 | } 12 | } 13 | }, 14 | "extract": { 15 | "exclude": [ 16 | "META-INF/" 17 | ] 18 | }, 19 | "name": "net.java.jinput:jinput-platform:2.0.5", 20 | "natives": { 21 | "linux": "natives-linux" 22 | } 23 | }, 24 | { 25 | "downloads": { 26 | "artifact": { 27 | "path": "net/java/jinput/jinput/2.0.5/jinput-2.0.5.jar", 28 | "sha1": "47f50f20c60495069c5a3cab65f5f87b44c1069e", 29 | "size": 216970, 30 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-2.9.4/jinput-2.0.5.jar" 31 | } 32 | }, 33 | "name": "net.java.jinput:jinput:2.0.5" 34 | }, 35 | { 36 | "downloads": { 37 | "artifact": { 38 | "path": "net/java/jutils/jutils/1.0.0/jutils-1.0.0.jar", 39 | "sha1": "e12fe1fda814bd348c1579329c86943d2cd3c6a6", 40 | "size": 7508, 41 | "url": "https://libraries.minecraft.net/net/java/jutils/jutils/1.0.0/jutils-1.0.0.jar" 42 | } 43 | }, 44 | "name": "net.java.jutils:jutils:1.0.0" 45 | }, 46 | { 47 | "downloads": { 48 | "artifact": { 49 | "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar", 50 | "sha1": "b04f3ee8f5e43fa3b162981b50bb72fe1acabb33", 51 | "size": 22, 52 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar" 53 | }, 54 | "classifiers": { 55 | "natives-linux": { 56 | "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar", 57 | "sha1": "63ac7da0f4a4785c7eadc0f8edc1e9dcc4dd08cb", 58 | "size": 579979, 59 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-2.9.4/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar" 60 | } 61 | } 62 | }, 63 | "extract": { 64 | "exclude": [ 65 | "META-INF/" 66 | ] 67 | }, 68 | "name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.4-nightly-20150209", 69 | "natives": { 70 | "linux": "natives-linux" 71 | } 72 | }, 73 | { 74 | "downloads": { 75 | "artifact": { 76 | "path": "org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209/lwjgl-2.9.4-nightly-20150209.jar", 77 | "sha1": "697517568c68e78ae0b4544145af031c81082dfe", 78 | "size": 1047168, 79 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209/lwjgl-2.9.4-nightly-20150209.jar" 80 | } 81 | }, 82 | "name": "org.lwjgl.lwjgl:lwjgl:2.9.4-nightly-20150209" 83 | }, 84 | { 85 | "downloads": { 86 | "artifact": { 87 | "path": "org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.jar", 88 | "sha1": "d51a7c040a721d13efdfbd34f8b257b2df882ad0", 89 | "size": 173887, 90 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-2.9.4/lwjgl_util-2.9.4-nightly-20150209.jar" 91 | } 92 | }, 93 | "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.4-nightly-20150209" 94 | } 95 | ] 96 | } -------------------------------------------------------------------------------- /assets/LWJGL/aarch64/3.1.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "libraries": [ 3 | { 4 | "downloads": { 5 | "artifact": { 6 | "sha1": "55b9dbe63745835ddde8b4c22be8da6520e8274f", 7 | "size": 300107, 8 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-core.jar", 9 | "path": "org/lwjgl/lwjgl/3.1.6/lwjgl-3.1.6.jar" 10 | } 11 | }, 12 | "name": "org.lwjgl:lwjgl:3.1.6" 13 | }, 14 | { 15 | "downloads": { 16 | "artifact": { 17 | "sha1": "55b9dbe63745835ddde8b4c22be8da6520e8274f", 18 | "size": 300107, 19 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-core.jar", 20 | "path": "org/lwjgl/lwjgl/3.1.6/lwjgl-3.1.6.jar" 21 | }, 22 | "classifiers": { 23 | "natives-linux": { 24 | "sha1": "68c8151938f33c702528208d32084e1c18b2dc9e", 25 | "size": 54802, 26 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-natives-linux-arm64.jar", 27 | "path": "org/lwjgl/lwjgl/3.1.6/lwjgl-3.1.6-natives-linux.jar" 28 | } 29 | } 30 | }, 31 | "name": "org.lwjgl:lwjgl:3.1.6", 32 | "natives": { 33 | "linux": "natives-linux" 34 | } 35 | }, 36 | { 37 | "downloads": { 38 | "artifact": { 39 | "sha1": "6e9ee82494343aee0737c391e151d0147c992584", 40 | "size": 39899, 41 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-jemalloc.jar", 42 | "path": "org/lwjgl/lwjgl-jemalloc/3.1.6/lwjgl-jemalloc-3.1.6.jar" 43 | } 44 | }, 45 | "name": "org.lwjgl:lwjgl-jemalloc:3.1.6" 46 | }, 47 | { 48 | "downloads": { 49 | "artifact": { 50 | "sha1": "6e9ee82494343aee0737c391e151d0147c992584", 51 | "size": 39899, 52 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-jemalloc.jar", 53 | "path": "org/lwjgl/lwjgl-jemalloc/3.1.6/lwjgl-jemalloc-3.1.6.jar" 54 | }, 55 | "classifiers": { 56 | "natives-linux": { 57 | "sha1": "762d7d80c9cdf3a3f3fc80c8a5f86612255edfe0", 58 | "size": 156343, 59 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-jemalloc-patched-natives-linux-arm64.jar", 60 | "path": "org/lwjgl/lwjgl-jemalloc/3.1.6/lwjgl-jemalloc-3.1.6-natives-linux.jar" 61 | } 62 | } 63 | }, 64 | "name": "org.lwjgl:lwjgl-jemalloc:3.1.6", 65 | "natives": { 66 | "linux": "natives-linux" 67 | } 68 | }, 69 | { 70 | "downloads": { 71 | "artifact": { 72 | "sha1": "fa243387070b806da104e3746828968b07ca737f", 73 | "size": 78718, 74 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-openal.jar", 75 | "path": "org/lwjgl/lwjgl-openal/3.1.6/lwjgl-openal-3.1.6.jar" 76 | } 77 | }, 78 | "name": "org.lwjgl:lwjgl-openal:3.1.6" 79 | }, 80 | { 81 | "downloads": { 82 | "artifact": { 83 | "sha1": "fa243387070b806da104e3746828968b07ca737f", 84 | "size": 78718, 85 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-openal.jar", 86 | "path": "org/lwjgl/lwjgl-openal/3.1.6/lwjgl-openal-3.1.6.jar" 87 | }, 88 | "classifiers": { 89 | "natives-linux": { 90 | "sha1": "5d1f9e7c633044a5700f2a80454d2a717251f675", 91 | "size": 469432, 92 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-openal-natives-linux-arm64.jar", 93 | "path": "org/lwjgl/lwjgl-openal/3.1.6/lwjgl-openal-3.1.6-natives-linux.jar" 94 | } 95 | } 96 | }, 97 | "name": "org.lwjgl:lwjgl-openal:3.1.6", 98 | "natives": { 99 | "linux": "natives-linux" 100 | } 101 | }, 102 | { 103 | "downloads": { 104 | "artifact": { 105 | "sha1": "862a9e64741dfab2f3a48638ebd58c35ba5e43cd", 106 | "size": 830047, 107 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-opengl.jar", 108 | "path": "org/lwjgl/lwjgl-opengl/3.1.6/lwjgl-opengl-3.1.6.jar" 109 | } 110 | }, 111 | "name": "org.lwjgl:lwjgl-opengl:3.1.6" 112 | }, 113 | { 114 | "downloads": { 115 | "artifact": { 116 | "sha1": "862a9e64741dfab2f3a48638ebd58c35ba5e43cd", 117 | "size": 830047, 118 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-opengl.jar", 119 | "path": "org/lwjgl/lwjgl-opengl/3.1.6/lwjgl-opengl-3.1.6.jar" 120 | }, 121 | "classifiers": { 122 | "natives-linux": { 123 | "sha1": "f9dec4cedbe2d98a92dd933d030c7e3efa99411b", 124 | "size": 67010, 125 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-opengl-natives-linux-arm64.jar", 126 | "path": "org/lwjgl/lwjgl-opengl/3.1.6/lwjgl-opengl-3.1.6-natives-linux.jar" 127 | } 128 | } 129 | }, 130 | "name": "org.lwjgl:lwjgl-opengl:3.1.6", 131 | "natives": { 132 | "linux": "natives-linux" 133 | } 134 | }, 135 | { 136 | "downloads": { 137 | "artifact": { 138 | "sha1": "b3ae7bad5b7e7d771ba9423521fc10f4ed67bbab", 139 | "size": 114229, 140 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-glfw.jar", 141 | "path": "org/lwjgl/lwjgl-glfw/3.1.6/lwjgl-glfw-3.1.6.jar" 142 | } 143 | }, 144 | "name": "org.lwjgl:lwjgl-glfw:3.1.6" 145 | }, 146 | { 147 | "downloads": { 148 | "artifact": { 149 | "sha1": "b3ae7bad5b7e7d771ba9423521fc10f4ed67bbab", 150 | "size": 114229, 151 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-glfw.jar", 152 | "path": "org/lwjgl/lwjgl-glfw/3.1.6/lwjgl-glfw-3.1.6.jar" 153 | }, 154 | "classifiers": { 155 | "natives-linux": { 156 | "sha1": "645aeac6de1deb1b77c7cf3abe84674f77ef1aea", 157 | "size": 85072, 158 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-glfw-natives-linux-arm64.jar", 159 | "path": "org/lwjgl/lwjgl-glfw/3.1.6/lwjgl-glfw-3.1.6-natives-linux.jar" 160 | } 161 | } 162 | }, 163 | "name": "org.lwjgl:lwjgl-glfw:3.1.6", 164 | "natives": { 165 | "linux": "natives-linux" 166 | } 167 | }, 168 | { 169 | "downloads": { 170 | "artifact": { 171 | "sha1": "688e32efb1ad7a09b60f0f4b7131e3dc33b286ca", 172 | "size": 104372, 173 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-stb.jar", 174 | "path": "org/lwjgl/lwjgl-stb/3.1.6/lwjgl-stb-3.1.6.jar" 175 | } 176 | }, 177 | "name": "org.lwjgl:lwjgl-stb:3.1.6" 178 | }, 179 | { 180 | "downloads": { 181 | "artifact": { 182 | "sha1": "688e32efb1ad7a09b60f0f4b7131e3dc33b286ca", 183 | "size": 104372, 184 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-stb.jar", 185 | "path": "org/lwjgl/lwjgl-stb/3.1.6/lwjgl-stb-3.1.6.jar" 186 | }, 187 | "classifiers": { 188 | "natives-linux": { 189 | "sha1": "7852b75b40a470face01cbb9f37ebc5e715944bd", 190 | "size": 192935, 191 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-stb-natives-linux-arm64.jar", 192 | "path": "org/lwjgl/lwjgl-stb/3.1.6/lwjgl-stb-3.1.6-natives-linux.jar" 193 | } 194 | } 195 | }, 196 | "name": "org.lwjgl:lwjgl-stb:3.1.6", 197 | "natives": { 198 | "linux": "natives-linux" 199 | } 200 | } 201 | ] 202 | } -------------------------------------------------------------------------------- /assets/LWJGL/aarch64/3.1.6.json: -------------------------------------------------------------------------------- 1 | { 2 | "libraries": [ 3 | { 4 | "downloads": { 5 | "artifact": { 6 | "sha1": "55b9dbe63745835ddde8b4c22be8da6520e8274f", 7 | "size": 300107, 8 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-core.jar", 9 | "path": "org/lwjgl/lwjgl/3.1.6/lwjgl-3.1.6.jar" 10 | } 11 | }, 12 | "name": "org.lwjgl:lwjgl:3.1.6" 13 | }, 14 | { 15 | "downloads": { 16 | "artifact": { 17 | "sha1": "55b9dbe63745835ddde8b4c22be8da6520e8274f", 18 | "size": 300107, 19 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-core.jar", 20 | "path": "org/lwjgl/lwjgl/3.1.6/lwjgl-3.1.6.jar" 21 | }, 22 | "classifiers": { 23 | "natives-linux": { 24 | "sha1": "68c8151938f33c702528208d32084e1c18b2dc9e", 25 | "size": 54802, 26 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-natives-linux-arm64.jar", 27 | "path": "org/lwjgl/lwjgl/3.1.6/lwjgl-3.1.6-natives-linux.jar" 28 | } 29 | } 30 | }, 31 | "name": "org.lwjgl:lwjgl:3.1.6", 32 | "natives": { 33 | "linux": "natives-linux" 34 | } 35 | }, 36 | { 37 | "downloads": { 38 | "artifact": { 39 | "sha1": "6e9ee82494343aee0737c391e151d0147c992584", 40 | "size": 39899, 41 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-jemalloc.jar", 42 | "path": "org/lwjgl/lwjgl-jemalloc/3.1.6/lwjgl-jemalloc-3.1.6.jar" 43 | } 44 | }, 45 | "name": "org.lwjgl:lwjgl-jemalloc:3.1.6" 46 | }, 47 | { 48 | "downloads": { 49 | "artifact": { 50 | "sha1": "6e9ee82494343aee0737c391e151d0147c992584", 51 | "size": 39899, 52 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-jemalloc.jar", 53 | "path": "org/lwjgl/lwjgl-jemalloc/3.1.6/lwjgl-jemalloc-3.1.6.jar" 54 | }, 55 | "classifiers": { 56 | "natives-linux": { 57 | "sha1": "762d7d80c9cdf3a3f3fc80c8a5f86612255edfe0", 58 | "size": 156343, 59 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-jemalloc-patched-natives-linux-arm64.jar", 60 | "path": "org/lwjgl/lwjgl-jemalloc/3.1.6/lwjgl-jemalloc-3.1.6-natives-linux.jar" 61 | } 62 | } 63 | }, 64 | "name": "org.lwjgl:lwjgl-jemalloc:3.1.6", 65 | "natives": { 66 | "linux": "natives-linux" 67 | } 68 | }, 69 | { 70 | "downloads": { 71 | "artifact": { 72 | "sha1": "fa243387070b806da104e3746828968b07ca737f", 73 | "size": 78718, 74 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-openal.jar", 75 | "path": "org/lwjgl/lwjgl-openal/3.1.6/lwjgl-openal-3.1.6.jar" 76 | } 77 | }, 78 | "name": "org.lwjgl:lwjgl-openal:3.1.6" 79 | }, 80 | { 81 | "downloads": { 82 | "artifact": { 83 | "sha1": "fa243387070b806da104e3746828968b07ca737f", 84 | "size": 78718, 85 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-openal.jar", 86 | "path": "org/lwjgl/lwjgl-openal/3.1.6/lwjgl-openal-3.1.6.jar" 87 | }, 88 | "classifiers": { 89 | "natives-linux": { 90 | "sha1": "5d1f9e7c633044a5700f2a80454d2a717251f675", 91 | "size": 469432, 92 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-openal-natives-linux-arm64.jar", 93 | "path": "org/lwjgl/lwjgl-openal/3.1.6/lwjgl-openal-3.1.6-natives-linux.jar" 94 | } 95 | } 96 | }, 97 | "name": "org.lwjgl:lwjgl-openal:3.1.6", 98 | "natives": { 99 | "linux": "natives-linux" 100 | } 101 | }, 102 | { 103 | "downloads": { 104 | "artifact": { 105 | "sha1": "862a9e64741dfab2f3a48638ebd58c35ba5e43cd", 106 | "size": 830047, 107 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-opengl.jar", 108 | "path": "org/lwjgl/lwjgl-opengl/3.1.6/lwjgl-opengl-3.1.6.jar" 109 | } 110 | }, 111 | "name": "org.lwjgl:lwjgl-opengl:3.1.6" 112 | }, 113 | { 114 | "downloads": { 115 | "artifact": { 116 | "sha1": "862a9e64741dfab2f3a48638ebd58c35ba5e43cd", 117 | "size": 830047, 118 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-opengl.jar", 119 | "path": "org/lwjgl/lwjgl-opengl/3.1.6/lwjgl-opengl-3.1.6.jar" 120 | }, 121 | "classifiers": { 122 | "natives-linux": { 123 | "sha1": "f9dec4cedbe2d98a92dd933d030c7e3efa99411b", 124 | "size": 67010, 125 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-opengl-natives-linux-arm64.jar", 126 | "path": "org/lwjgl/lwjgl-opengl/3.1.6/lwjgl-opengl-3.1.6-natives-linux.jar" 127 | } 128 | } 129 | }, 130 | "name": "org.lwjgl:lwjgl-opengl:3.1.6", 131 | "natives": { 132 | "linux": "natives-linux" 133 | } 134 | }, 135 | { 136 | "downloads": { 137 | "artifact": { 138 | "sha1": "b3ae7bad5b7e7d771ba9423521fc10f4ed67bbab", 139 | "size": 114229, 140 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-glfw.jar", 141 | "path": "org/lwjgl/lwjgl-glfw/3.1.6/lwjgl-glfw-3.1.6.jar" 142 | } 143 | }, 144 | "name": "org.lwjgl:lwjgl-glfw:3.1.6" 145 | }, 146 | { 147 | "downloads": { 148 | "artifact": { 149 | "sha1": "b3ae7bad5b7e7d771ba9423521fc10f4ed67bbab", 150 | "size": 114229, 151 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-glfw.jar", 152 | "path": "org/lwjgl/lwjgl-glfw/3.1.6/lwjgl-glfw-3.1.6.jar" 153 | }, 154 | "classifiers": { 155 | "natives-linux": { 156 | "sha1": "645aeac6de1deb1b77c7cf3abe84674f77ef1aea", 157 | "size": 85072, 158 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-glfw-natives-linux-arm64.jar", 159 | "path": "org/lwjgl/lwjgl-glfw/3.1.6/lwjgl-glfw-3.1.6-natives-linux.jar" 160 | } 161 | } 162 | }, 163 | "name": "org.lwjgl:lwjgl-glfw:3.1.6", 164 | "natives": { 165 | "linux": "natives-linux" 166 | } 167 | }, 168 | { 169 | "downloads": { 170 | "artifact": { 171 | "sha1": "688e32efb1ad7a09b60f0f4b7131e3dc33b286ca", 172 | "size": 104372, 173 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-stb.jar", 174 | "path": "org/lwjgl/lwjgl-stb/3.1.6/lwjgl-stb-3.1.6.jar" 175 | } 176 | }, 177 | "name": "org.lwjgl:lwjgl-stb:3.1.6" 178 | }, 179 | { 180 | "downloads": { 181 | "artifact": { 182 | "sha1": "688e32efb1ad7a09b60f0f4b7131e3dc33b286ca", 183 | "size": 104372, 184 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-stb.jar", 185 | "path": "org/lwjgl/lwjgl-stb/3.1.6/lwjgl-stb-3.1.6.jar" 186 | }, 187 | "classifiers": { 188 | "natives-linux": { 189 | "sha1": "7852b75b40a470face01cbb9f37ebc5e715944bd", 190 | "size": 192935, 191 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.1.6/lwjgl-stb-natives-linux-arm64.jar", 192 | "path": "org/lwjgl/lwjgl-stb/3.1.6/lwjgl-stb-3.1.6-natives-linux.jar" 193 | } 194 | } 195 | }, 196 | "name": "org.lwjgl:lwjgl-stb:3.1.6", 197 | "natives": { 198 | "linux": "natives-linux" 199 | } 200 | } 201 | ] 202 | } -------------------------------------------------------------------------------- /assets/LWJGL/aarch64/3.2.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "libraries": [ 3 | { 4 | "downloads": { 5 | "artifact": { 6 | "sha1": "4add49f642c6f6d0bf51e1b6fea388d5101267b9", 7 | "size": 314115, 8 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.1/lwjgl-core.jar", 9 | "path": "org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1.jar" 10 | } 11 | }, 12 | "name": "org.lwjgl:lwjgl:3.2.1" 13 | }, 14 | { 15 | "downloads": { 16 | "artifact": { 17 | "sha1": "4add49f642c6f6d0bf51e1b6fea388d5101267b9", 18 | "size": 314115, 19 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.1/lwjgl-core.jar", 20 | "path": "org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1.jar" 21 | }, 22 | "classifiers": { 23 | "natives-linux": { 24 | "sha1": "03c691efeac999530f4b350312a5a9d85e52cf89", 25 | "size": 60186, 26 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.1/lwjgl-natives-linux-arm64.jar", 27 | "path": "org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1-natives-linux.jar" 28 | } 29 | } 30 | }, 31 | "name": "org.lwjgl:lwjgl:3.2.1", 32 | "natives": { 33 | "linux": "natives-linux" 34 | } 35 | }, 36 | { 37 | "downloads": { 38 | "artifact": { 39 | "sha1": "5621e055b542f6caab937b8346de5fd02105f9b2", 40 | "size": 37712, 41 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.1/lwjgl-jemalloc.jar", 42 | "path": "org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1.jar" 43 | } 44 | }, 45 | "name": "org.lwjgl:lwjgl-jemalloc:3.2.1" 46 | }, 47 | { 48 | "downloads": { 49 | "artifact": { 50 | "sha1": "5621e055b542f6caab937b8346de5fd02105f9b2", 51 | "size": 37712, 52 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.1/lwjgl-jemalloc.jar", 53 | "path": "org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1.jar" 54 | }, 55 | "classifiers": { 56 | "natives-linux": { 57 | "sha1": "762d7d80c9cdf3a3f3fc80c8a5f86612255edfe0", 58 | "size": 156343, 59 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.1/lwjgl-jemalloc-patched-natives-linux-arm64.jar", 60 | "path": "org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1-natives-linux.jar" 61 | } 62 | } 63 | }, 64 | "name": "org.lwjgl:lwjgl-jemalloc:3.2.1", 65 | "natives": { 66 | "linux": "natives-linux" 67 | } 68 | }, 69 | { 70 | "downloads": { 71 | "artifact": { 72 | "sha1": "b6ef8efb60c888a14feebcd09addc265f1eca1a2", 73 | "size": 79683, 74 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.1/lwjgl-openal.jar", 75 | "path": "org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1.jar" 76 | } 77 | }, 78 | "name": "org.lwjgl:lwjgl-openal:3.2.1" 79 | }, 80 | { 81 | "downloads": { 82 | "artifact": { 83 | "sha1": "b6ef8efb60c888a14feebcd09addc265f1eca1a2", 84 | "size": 79683, 85 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.1/lwjgl-openal.jar", 86 | "path": "org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1.jar" 87 | }, 88 | "classifiers": { 89 | "natives-linux": { 90 | "sha1": "222a583cbfdcc3a81d5d9ad807c3d68196c8ec52", 91 | "size": 469432, 92 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.1/lwjgl-openal-natives-linux-arm64.jar", 93 | "path": "org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1-natives-linux.jar" 94 | } 95 | } 96 | }, 97 | "name": "org.lwjgl:lwjgl-openal:3.2.1", 98 | "natives": { 99 | "linux": "natives-linux" 100 | } 101 | }, 102 | { 103 | "downloads": { 104 | "artifact": { 105 | "sha1": "282139e3a8d1402fc25e18eb6a05eb090a1e81b4", 106 | "size": 939248, 107 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.1/lwjgl-opengl.jar", 108 | "path": "org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1.jar" 109 | } 110 | }, 111 | "name": "org.lwjgl:lwjgl-opengl:3.2.1" 112 | }, 113 | { 114 | "downloads": { 115 | "artifact": { 116 | "sha1": "282139e3a8d1402fc25e18eb6a05eb090a1e81b4", 117 | "size": 939248, 118 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.1/lwjgl-opengl.jar", 119 | "path": "org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1.jar" 120 | }, 121 | "classifiers": { 122 | "natives-linux": { 123 | "sha1": "1d5e0092e54efd3f100f2c307261155573fa78f6", 124 | "size": 56110, 125 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.1/lwjgl-opengl-natives-linux-arm64.jar", 126 | "path": "org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1-natives-linux.jar" 127 | } 128 | } 129 | }, 130 | "name": "org.lwjgl:lwjgl-opengl:3.2.1", 131 | "natives": { 132 | "linux": "natives-linux" 133 | } 134 | }, 135 | { 136 | "downloads": { 137 | "artifact": { 138 | "sha1": "ccc4ba7e8521b5981343bcdbc3cf6492f35a5aa5", 139 | "size": 116839, 140 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.1/lwjgl-glfw.jar", 141 | "path": "org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1.jar" 142 | } 143 | }, 144 | "name": "org.lwjgl:lwjgl-glfw:3.2.1" 145 | }, 146 | { 147 | "downloads": { 148 | "artifact": { 149 | "sha1": "ccc4ba7e8521b5981343bcdbc3cf6492f35a5aa5", 150 | "size": 116839, 151 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.1/lwjgl-glfw.jar", 152 | "path": "org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1.jar" 153 | }, 154 | "classifiers": { 155 | "natives-linux": { 156 | "sha1": "d52b2a26fafb6d4eebeef74ee4f6c3ebd65004b2", 157 | "size": 85072, 158 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.1/lwjgl-glfw-natives-linux-arm64.jar", 159 | "path": "org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1-natives-linux.jar" 160 | } 161 | } 162 | }, 163 | "name": "org.lwjgl:lwjgl-glfw:3.2.1", 164 | "natives": { 165 | "linux": "natives-linux" 166 | } 167 | }, 168 | { 169 | "downloads": { 170 | "artifact": { 171 | "sha1": "e6898a15a8067c89771ae2949bea8f5ff7874fcc", 172 | "size": 105432, 173 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.1/lwjgl-stb.jar", 174 | "path": "org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1.jar" 175 | } 176 | }, 177 | "name": "org.lwjgl:lwjgl-stb:3.2.1" 178 | }, 179 | { 180 | "downloads": { 181 | "artifact": { 182 | "sha1": "e6898a15a8067c89771ae2949bea8f5ff7874fcc", 183 | "size": 105432, 184 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.1/lwjgl-stb.jar", 185 | "path": "org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1.jar" 186 | }, 187 | "classifiers": { 188 | "natives-linux": { 189 | "sha1": "b8f7ace2cb31887254bbcde88e0dc705f5de2c3f", 190 | "size": 193998, 191 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.1/lwjgl-stb-natives-linux-arm64.jar", 192 | "path": "org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1-natives-linux.jar" 193 | } 194 | } 195 | }, 196 | "name": "org.lwjgl:lwjgl-stb:3.2.1", 197 | "natives": { 198 | "linux": "natives-linux" 199 | } 200 | } 201 | ] 202 | } -------------------------------------------------------------------------------- /assets/LWJGL/aarch64/3.2.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "libraries": [ 3 | { 4 | "downloads": { 5 | "artifact": { 6 | "sha1": "360899386df83d6a8407844a94478607af937f97", 7 | "size": 318833, 8 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-core.jar", 9 | "path": "org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2.jar" 10 | } 11 | }, 12 | "name": "org.lwjgl:lwjgl:3.2.2" 13 | }, 14 | { 15 | "downloads": { 16 | "artifact": { 17 | "sha1": "360899386df83d6a8407844a94478607af937f97", 18 | "size": 318833, 19 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-core.jar", 20 | "path": "org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2.jar" 21 | }, 22 | "classifiers": { 23 | "natives-linux": { 24 | "sha1": "612efd57d12b2e48e554858eb35e7e2eb46ebb4c", 25 | "size": 87121, 26 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-natives-linux-arm64.jar", 27 | "path": "org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2-natives-linux.jar" 28 | } 29 | } 30 | }, 31 | "name": "org.lwjgl:lwjgl:3.2.2", 32 | "natives": { 33 | "linux": "natives-linux" 34 | } 35 | }, 36 | { 37 | "downloads": { 38 | "artifact": { 39 | "sha1": "cc04eec29b2fa8c298791af9800a3766d9617954", 40 | "size": 33790, 41 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-jemalloc.jar", 42 | "path": "org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2.jar" 43 | } 44 | }, 45 | "name": "org.lwjgl:lwjgl-jemalloc:3.2.2" 46 | }, 47 | { 48 | "downloads": { 49 | "artifact": { 50 | "sha1": "cc04eec29b2fa8c298791af9800a3766d9617954", 51 | "size": 33790, 52 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-jemalloc.jar", 53 | "path": "org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2.jar" 54 | }, 55 | "classifiers": { 56 | "natives-linux": { 57 | "sha1": "762d7d80c9cdf3a3f3fc80c8a5f86612255edfe0", 58 | "size": 156343, 59 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-jemalloc-patched-natives-linux-arm64.jar", 60 | "path": "org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2-natives-linux.jar" 61 | } 62 | } 63 | }, 64 | "name": "org.lwjgl:lwjgl-jemalloc:3.2.2", 65 | "natives": { 66 | "linux": "natives-linux" 67 | } 68 | }, 69 | { 70 | "downloads": { 71 | "artifact": { 72 | "sha1": "6dfce9dc6a9629c75b2ae01a8df7e7be80ba0261", 73 | "size": 79582, 74 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-openal.jar", 75 | "path": "org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2.jar" 76 | } 77 | }, 78 | "name": "org.lwjgl:lwjgl-openal:3.2.2" 79 | }, 80 | { 81 | "downloads": { 82 | "artifact": { 83 | "sha1": "6dfce9dc6a9629c75b2ae01a8df7e7be80ba0261", 84 | "size": 79582, 85 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-openal.jar", 86 | "path": "org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2.jar" 87 | }, 88 | "classifiers": { 89 | "natives-linux": { 90 | "sha1": "948e415b5b2a2c650c25b377a4a9f443b21ce92e", 91 | "size": 469432, 92 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-openal-natives-linux-arm64.jar", 93 | "path": "org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2-natives-linux.jar" 94 | } 95 | } 96 | }, 97 | "name": "org.lwjgl:lwjgl-openal:3.2.2", 98 | "natives": { 99 | "linux": "natives-linux" 100 | } 101 | }, 102 | { 103 | "downloads": { 104 | "artifact": { 105 | "sha1": "198bc2f72e0b2eb401eb6f5999aea52909b31ac4", 106 | "size": 937609, 107 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-opengl.jar", 108 | "path": "org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2.jar" 109 | } 110 | }, 111 | "name": "org.lwjgl:lwjgl-opengl:3.2.2" 112 | }, 113 | { 114 | "downloads": { 115 | "artifact": { 116 | "sha1": "198bc2f72e0b2eb401eb6f5999aea52909b31ac4", 117 | "size": 937609, 118 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-opengl.jar", 119 | "path": "org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2.jar" 120 | }, 121 | "classifiers": { 122 | "natives-linux": { 123 | "sha1": "bd40897077bf7d12f562da898b18ac2c68e1f9d7", 124 | "size": 56109, 125 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-opengl-natives-linux-arm64.jar", 126 | "path": "org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2-natives-linux.jar" 127 | } 128 | } 129 | }, 130 | "name": "org.lwjgl:lwjgl-opengl:3.2.2", 131 | "natives": { 132 | "linux": "natives-linux" 133 | } 134 | }, 135 | { 136 | "downloads": { 137 | "artifact": { 138 | "sha1": "155d175037efc76630940c197ca6dea2b17d7e18", 139 | "size": 108691, 140 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-glfw.jar", 141 | "path": "org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2.jar" 142 | } 143 | }, 144 | "name": "org.lwjgl:lwjgl-glfw:3.2.2" 145 | }, 146 | { 147 | "downloads": { 148 | "artifact": { 149 | "sha1": "155d175037efc76630940c197ca6dea2b17d7e18", 150 | "size": 108691, 151 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-glfw.jar", 152 | "path": "org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2.jar" 153 | }, 154 | "classifiers": { 155 | "natives-linux": { 156 | "sha1": "074ad243761147df0d060fbefc814614d2ff75cc", 157 | "size": 85072, 158 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-glfw-natives-linux-arm64.jar", 159 | "path": "org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2-natives-linux.jar" 160 | } 161 | } 162 | }, 163 | "name": "org.lwjgl:lwjgl-glfw:3.2.2", 164 | "natives": { 165 | "linux": "natives-linux" 166 | } 167 | }, 168 | { 169 | "downloads": { 170 | "artifact": { 171 | "sha1": "46a5735f3eb9d17eb5dcbdd5afa194066d2a6555", 172 | "size": 104075, 173 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-stb.jar", 174 | "path": "org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2.jar" 175 | } 176 | }, 177 | "name": "org.lwjgl:lwjgl-stb:3.2.2" 178 | }, 179 | { 180 | "downloads": { 181 | "artifact": { 182 | "sha1": "46a5735f3eb9d17eb5dcbdd5afa194066d2a6555", 183 | "size": 104075, 184 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-stb.jar", 185 | "path": "org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2.jar" 186 | }, 187 | "classifiers": { 188 | "natives-linux": { 189 | "sha1": "077efa7d7ea41b32df5c6078e912e724cccd06db", 190 | "size": 202038, 191 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-stb-natives-linux-arm64.jar", 192 | "path": "org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2-natives-linux.jar" 193 | } 194 | } 195 | }, 196 | "name": "org.lwjgl:lwjgl-stb:3.2.2", 197 | "natives": { 198 | "linux": "natives-linux" 199 | } 200 | }, 201 | { 202 | "downloads": { 203 | "artifact": { 204 | "sha1": "3a75b9811607633bf33c978f53964df1534a4bc1", 205 | "size": 5571, 206 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-tinyfd.jar", 207 | "path": "org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar" 208 | } 209 | }, 210 | "name": "org.lwjgl:lwjgl-tinyfd:3.2.2" 211 | }, 212 | { 213 | "downloads": { 214 | "artifact": { 215 | "sha1": "3a75b9811607633bf33c978f53964df1534a4bc1", 216 | "size": 5571, 217 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-tinyfd.jar", 218 | "path": "org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar" 219 | }, 220 | "classifiers": { 221 | "natives-linux": { 222 | "sha1": "37c744ca289b5d7ae155d79e39029488b3254e5b", 223 | "size": 37893, 224 | "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-tinyfd-natives-linux-arm64.jar", 225 | "path": "org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-linux.jar" 226 | } 227 | } 228 | }, 229 | "name": "org.lwjgl:lwjgl-tinyfd:3.2.2", 230 | "natives": { 231 | "linux": "natives-linux" 232 | } 233 | } 234 | ] 235 | } -------------------------------------------------------------------------------- /assets/LWJGL/aarch64/3.3.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "libraries": [ 3 | { 4 | "downloads": { 5 | "artifact": { 6 | "sha1": "757920418805fb90bfebb3d46b1d9e7669fca2eb", 7 | "size": 135828, 8 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-glfw/3.3.2/lwjgl-glfw-3.3.2.jar", 9 | "path": "org/lwjgl/lwjgl-glfw/3.3.2/lwjgl-glfw-3.3.2.jar" 10 | } 11 | }, 12 | "name": "org.lwjgl:lwjgl-glfw:3.3.2" 13 | }, 14 | { 15 | "downloads": { 16 | "artifact": { 17 | "sha1": "757920418805fb90bfebb3d46b1d9e7669fca2eb", 18 | "size": 135828, 19 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-glfw/3.3.2/lwjgl-glfw-3.3.2.jar", 20 | "path": "org/lwjgl/lwjgl-glfw/3.3.2/lwjgl-glfw-3.3.2.jar" 21 | }, 22 | "classifiers": { 23 | "natives-linux": { 24 | "sha1": "bc49e64bae0f7ff103a312ee8074a34c4eb034c7", 25 | "size": 120168, 26 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-glfw/3.3.2/lwjgl-glfw-3.3.2-natives-linux-arm64.jar", 27 | "path": "org/lwjgl/lwjgl-glfw/3.3.2/lwjgl-glfw-3.3.2-natives-linux.jar" 28 | }, 29 | "sources": { 30 | "sha1": "0bdd2ae91adb35fd7809b7ecf2d677546b26fe4f", 31 | "size": 126160, 32 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-glfw/3.3.2/lwjgl-glfw-3.3.2-sources.jar" 33 | } 34 | } 35 | }, 36 | "name": "org.lwjgl:lwjgl-glfw:3.3.2", 37 | "natives": { 38 | "linux": "natives-linux" 39 | } 40 | }, 41 | { 42 | "downloads": { 43 | "artifact": { 44 | "sha1": "877e17e39ebcd58a9c956dc3b5b777813de0873a", 45 | "size": 43233, 46 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-jemalloc/3.3.2/lwjgl-jemalloc-3.3.2.jar", 47 | "path": "org/lwjgl/lwjgl-jemalloc/3.3.2/lwjgl-jemalloc-3.3.2.jar" 48 | } 49 | }, 50 | "name": "org.lwjgl:lwjgl-jemalloc:3.3.2" 51 | }, 52 | { 53 | "downloads": { 54 | "artifact": { 55 | "sha1": "877e17e39ebcd58a9c956dc3b5b777813de0873a", 56 | "size": 43233, 57 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-jemalloc/3.3.2/lwjgl-jemalloc-3.3.2.jar", 58 | "path": "org/lwjgl/lwjgl-jemalloc/3.3.2/lwjgl-jemalloc-3.3.2.jar" 59 | }, 60 | "classifiers": { 61 | "natives-linux": { 62 | "sha1": "5249f18a9ae20ea86c5816bc3107a888ce7a17d2", 63 | "size": 206402, 64 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-jemalloc/3.3.2/lwjgl-jemalloc-3.3.2-natives-linux-arm64.jar", 65 | "path": "org/lwjgl/lwjgl-jemalloc/3.3.2/lwjgl-jemalloc-3.3.2-natives-linux.jar" 66 | }, 67 | "sources": { 68 | "sha1": "1d953086a319cfb09d0703e50011849a95ab2277", 69 | "size": 32303, 70 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-jemalloc/3.3.2/lwjgl-jemalloc-3.3.2-sources.jar" 71 | } 72 | } 73 | }, 74 | "name": "org.lwjgl:lwjgl-jemalloc:3.3.2", 75 | "natives": { 76 | "linux": "natives-linux" 77 | } 78 | }, 79 | { 80 | "downloads": { 81 | "artifact": { 82 | "sha1": "ae5357ed6d934546d3533993ea84c0cfb75eed95", 83 | "size": 108230, 84 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-openal/3.3.2/lwjgl-openal-3.3.2.jar", 85 | "path": "org/lwjgl/lwjgl-openal/3.3.2/lwjgl-openal-3.3.2.jar" 86 | } 87 | }, 88 | "name": "org.lwjgl:lwjgl-openal:3.3.2" 89 | }, 90 | { 91 | "downloads": { 92 | "artifact": { 93 | "sha1": "ae5357ed6d934546d3533993ea84c0cfb75eed95", 94 | "size": 108230, 95 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-openal/3.3.2/lwjgl-openal-3.3.2.jar", 96 | "path": "org/lwjgl/lwjgl-openal/3.3.2/lwjgl-openal-3.3.2.jar" 97 | }, 98 | "classifiers": { 99 | "natives-linux": { 100 | "sha1": "22408980cc579709feaf9acb807992d3ebcf693f", 101 | "size": 590865, 102 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-openal/3.3.2/lwjgl-openal-3.3.2-natives-linux-arm64.jar", 103 | "path": "org/lwjgl/lwjgl-openal/3.3.2/lwjgl-openal-3.3.2-natives-linux.jar" 104 | }, 105 | "sources": { 106 | "sha1": "534195bc70b8ff83c270c1d618cdafe76e9be2c4", 107 | "size": 100606, 108 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-openal/3.3.2/lwjgl-openal-3.3.2-sources.jar" 109 | } 110 | } 111 | }, 112 | "name": "org.lwjgl:lwjgl-openal:3.3.2", 113 | "natives": { 114 | "linux": "natives-linux" 115 | } 116 | }, 117 | { 118 | "downloads": { 119 | "artifact": { 120 | "sha1": "ee8e95be0b438602038bc1f02dc5e3d011b1b216", 121 | "size": 928871, 122 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-opengl/3.3.2/lwjgl-opengl-3.3.2.jar", 123 | "path": "org/lwjgl/lwjgl-opengl/3.3.2/lwjgl-opengl-3.3.2.jar" 124 | } 125 | }, 126 | "name": "org.lwjgl:lwjgl-opengl:3.3.2" 127 | }, 128 | { 129 | "downloads": { 130 | "artifact": { 131 | "sha1": "ee8e95be0b438602038bc1f02dc5e3d011b1b216", 132 | "size": 928871, 133 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-opengl/3.3.2/lwjgl-opengl-3.3.2.jar", 134 | "path": "org/lwjgl/lwjgl-opengl/3.3.2/lwjgl-opengl-3.3.2.jar" 135 | }, 136 | "classifiers": { 137 | "natives-linux": { 138 | "sha1": "bb9eb56da6d1d549d6a767218e675e36bc568eb9", 139 | "size": 58627, 140 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-opengl/3.3.2/lwjgl-opengl-3.3.2-natives-linux-arm64.jar", 141 | "path": "org/lwjgl/lwjgl-opengl/3.3.2/lwjgl-opengl-3.3.2-natives-linux.jar" 142 | }, 143 | "sources": { 144 | "sha1": "1301ff0d9814ac96d7020f5912d5f0f72c039fca", 145 | "size": 1275908, 146 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-opengl/3.3.2/lwjgl-opengl-3.3.2-sources.jar" 147 | } 148 | } 149 | }, 150 | "name": "org.lwjgl:lwjgl-opengl:3.3.2", 151 | "natives": { 152 | "linux": "natives-linux" 153 | } 154 | }, 155 | { 156 | "downloads": { 157 | "artifact": { 158 | "sha1": "a2550795014d622b686e9caac50b14baa87d2c70", 159 | "size": 118874, 160 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-stb/3.3.2/lwjgl-stb-3.3.2.jar", 161 | "path": "org/lwjgl/lwjgl-stb/3.3.2/lwjgl-stb-3.3.2.jar" 162 | } 163 | }, 164 | "name": "org.lwjgl:lwjgl-stb:3.3.2" 165 | }, 166 | { 167 | "downloads": { 168 | "artifact": { 169 | "sha1": "a2550795014d622b686e9caac50b14baa87d2c70", 170 | "size": 118874, 171 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-stb/3.3.2/lwjgl-stb-3.3.2.jar", 172 | "path": "org/lwjgl/lwjgl-stb/3.3.2/lwjgl-stb-3.3.2.jar" 173 | }, 174 | "classifiers": { 175 | "natives-linux": { 176 | "sha1": "11a380c37b0f03cb46db235e064528f84d736ff7", 177 | "size": 207419, 178 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-stb/3.3.2/lwjgl-stb-3.3.2-natives-linux-arm64.jar", 179 | "path": "org/lwjgl/lwjgl-stb/3.3.2/lwjgl-stb-3.3.2-natives-linux.jar" 180 | }, 181 | "sources": { 182 | "sha1": "dda437f20ae0c920c1c744984b4093889982b994", 183 | "size": 103496, 184 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-stb/3.3.2/lwjgl-stb-3.3.2-sources.jar" 185 | } 186 | } 187 | }, 188 | "name": "org.lwjgl:lwjgl-stb:3.3.2", 189 | "natives": { 190 | "linux": "natives-linux" 191 | } 192 | }, 193 | { 194 | "downloads": { 195 | "artifact": { 196 | "sha1": "9f65c248dd77934105274fcf8351abb75b34327c", 197 | "size": 13404, 198 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-tinyfd/3.3.2/lwjgl-tinyfd-3.3.2.jar", 199 | "path": "org/lwjgl/lwjgl-tinyfd/3.3.2/lwjgl-tinyfd-3.3.2.jar" 200 | } 201 | }, 202 | "name": "org.lwjgl:lwjgl-tinyfd:3.3.2" 203 | }, 204 | { 205 | "downloads": { 206 | "artifact": { 207 | "sha1": "9f65c248dd77934105274fcf8351abb75b34327c", 208 | "size": 13404, 209 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-tinyfd/3.3.2/lwjgl-tinyfd-3.3.2.jar", 210 | "path": "org/lwjgl/lwjgl-tinyfd/3.3.2/lwjgl-tinyfd-3.3.2.jar" 211 | }, 212 | "classifiers": { 213 | "natives-linux": { 214 | "sha1": "93f8c5bc1984963cd79109891fb5a9d1e580373e", 215 | "size": 43381, 216 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-tinyfd/3.3.2/lwjgl-tinyfd-3.3.2-natives-linux-arm64.jar", 217 | "path": "org/lwjgl/lwjgl-tinyfd/3.3.2/lwjgl-tinyfd-3.3.2.jar" 218 | }, 219 | "sources": { 220 | "sha1": "bd33407b8cdbac1161c759656034d283f4708051", 221 | "size": 5527, 222 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-tinyfd/3.3.2/lwjgl-tinyfd-3.3.2-sources.jar" 223 | } 224 | } 225 | }, 226 | "name": "org.lwjgl:lwjgl-tinyfd:3.3.2", 227 | "natives": { 228 | "linux": "natives-linux" 229 | } 230 | }, 231 | { 232 | "downloads": { 233 | "artifact": { 234 | "sha1": "4421d94af68e35dcaa31737a6fc59136a1e61b94", 235 | "size": 786196, 236 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2.jar", 237 | "path": "org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2.jar" 238 | } 239 | }, 240 | "name": "org.lwjgl:lwjgl:3.3.2" 241 | }, 242 | { 243 | "downloads": { 244 | "artifact": { 245 | "sha1": "4421d94af68e35dcaa31737a6fc59136a1e61b94", 246 | "size": 786196, 247 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2.jar", 248 | "path": "org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2.jar" 249 | }, 250 | "classifiers": { 251 | "natives-linux": { 252 | "sha1": "8bd89332c90a90e6bc4aa997a25c05b7db02c90a", 253 | "size": 90795, 254 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2-natives-linux-arm64.jar", 255 | "path": "org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2-natives-linux.jar" 256 | }, 257 | "sources": { 258 | "sha1": "aff949f8180d6d1e26a47c7a2bca8163f5b987fe", 259 | "size": 624340, 260 | "url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2-sources.jar" 261 | } 262 | } 263 | }, 264 | "name": "org.lwjgl:lwjgl:3.3.2", 265 | "natives": { 266 | "linux": "natives-linux" 267 | } 268 | } 269 | ] 270 | } -------------------------------------------------------------------------------- /assets/icons/microsoft.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luuxis/minecraft-java-core/fcde98fc853efa4a10412f0ff8b82a959acefc9e/assets/icons/microsoft.icns -------------------------------------------------------------------------------- /assets/icons/microsoft.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luuxis/minecraft-java-core/fcde98fc853efa4a10412f0ff8b82a959acefc9e/assets/icons/microsoft.ico -------------------------------------------------------------------------------- /assets/icons/microsoft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luuxis/minecraft-java-core/fcde98fc853efa4a10412f0ff8b82a959acefc9e/assets/icons/microsoft.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minecraft-java-core", 3 | "version": "4.1.3", 4 | "types": "./build/Index.d.ts", 5 | "exports": { 6 | ".": { 7 | "import": "./build/Index.js", 8 | "require": "./build/Index.js" 9 | } 10 | }, 11 | "description": "A library starting minecraft game NW.js and Electron.js", 12 | "scripts": { 13 | "dev": "rimraf ./build && tsc -w", 14 | "build": "rimraf ./build && tsc", 15 | "prepublishOnly": "npm i && npm run build" 16 | }, 17 | "engines": { 18 | "node": ">=18.0.0" 19 | }, 20 | "files": [ 21 | "assets/**", 22 | "build/**", 23 | "LICENSE", 24 | "README.md" 25 | ], 26 | "keywords": [ 27 | "Minecraft", 28 | "Launcher", 29 | "Node-Minecraft", 30 | "Game", 31 | "Minecraft-Launcher", 32 | "Forge", 33 | "Minecraft-Forge" 34 | ], 35 | "author": "Luuxis", 36 | "license": "CCANC", 37 | "dependencies": { 38 | "7zip-bin": "^5.2.0", 39 | "adm-zip": "^0.5.16", 40 | "node-7z": "^3.0.0", 41 | "prompt": "^1.3.0", 42 | "semver": "^7.7.2", 43 | "tslib": "^2.8.1" 44 | }, 45 | "devDependencies": { 46 | "@types/adm-zip": "^0.5.7", 47 | "@types/node": "^22.10.2", 48 | "@types/node-7z": "^2.1.10", 49 | "@types/node-fetch": "^2.6.12", 50 | "@types/semver": "^7.7.0", 51 | "rimraf": "^6.0.1", 52 | "typescript": "^5.7.2" 53 | }, 54 | "bugs": { 55 | "url": "https://github.com/luuxis/minecraft-java-core/issues" 56 | }, 57 | "homepage": "https://github.com/luuxis/minecraft-java-core#readme", 58 | "repository": { 59 | "type": "git", 60 | "url": "git+https://github.com/luuxis/minecraft-java-core.git" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Authenticator/AZauth.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is distributed under the CC-BY-NC 4.0 license: 3 | * https://creativecommons.org/licenses/by-nc/4.0/ 4 | * 5 | * Original author: Luuxis 6 | */ 7 | 8 | import { Buffer } from 'node:buffer'; 9 | 10 | // This interface defines the structure of the user object 11 | // returned by the AZauth service. You can adapt it to your needs. 12 | interface AZauthUser { 13 | access_token?: string; 14 | client_token?: string; 15 | uuid?: string; 16 | name?: string; 17 | user_properties?: string; 18 | user_info?: { 19 | id?: string; 20 | banned?: boolean; 21 | money?: number; 22 | role?: string; 23 | verified?: boolean; 24 | }; 25 | meta?: { 26 | online: boolean; 27 | type: string; 28 | }; 29 | profile?: { 30 | skins: Array<{ 31 | url: string; 32 | base64?: string; 33 | }>; 34 | }; 35 | // Error-related fields 36 | error?: boolean; 37 | reason?: string; 38 | message?: string; 39 | A2F?: boolean; 40 | } 41 | 42 | export default class AZauth { 43 | private url: string; 44 | private skinAPI: string; 45 | 46 | /** 47 | * The constructor prepares the authentication and skin URLs from the base URL. 48 | * @param url The base URL of the AZauth server 49 | */ 50 | constructor(url: string) { 51 | // '/api/auth' for authentication, '/api/skin-api/skins' for skin data 52 | this.url = new URL('/api/auth', url).toString(); 53 | this.skinAPI = new URL('/api/skin-api/skins', url).toString(); 54 | } 55 | 56 | /** 57 | * Authenticates a user using their username/email and password. 58 | * Optionally, a 2FA code can be provided. 59 | * 60 | * @param username The email or username for authentication 61 | * @param password The password 62 | * @param A2F Optional 2FA code 63 | * @returns A Promise that resolves to an AZauthUser object 64 | */ 65 | public async login(username: string, password: string, A2F: string | null = null): Promise { 66 | const response = await fetch(`${this.url}/authenticate`, { 67 | method: 'POST', 68 | headers: { 'Content-Type': 'application/json' }, 69 | body: JSON.stringify({ 70 | email: username, 71 | password, 72 | code: A2F 73 | }) 74 | }); 75 | 76 | const data = await response.json(); 77 | 78 | // If the server indicates that 2FA is required 79 | if (data.status === 'pending' && data.reason === '2fa') { 80 | return { A2F: true }; 81 | } 82 | 83 | // If the server returns an error status 84 | if (data.status === 'error') { 85 | return { 86 | error: true, 87 | reason: data.reason, 88 | message: data.message 89 | }; 90 | } 91 | 92 | // If authentication is successful, return the complete user object 93 | return { 94 | access_token: data.access_token, 95 | client_token: data.uuid, 96 | uuid: data.uuid, 97 | name: data.username, 98 | user_properties: '{}', 99 | user_info: { 100 | id: data.id, 101 | banned: data.banned, 102 | money: data.money, 103 | role: data.role, 104 | verified: data.email_verified 105 | }, 106 | meta: { 107 | online: false, 108 | type: 'AZauth' 109 | }, 110 | profile: { 111 | skins: [await this.skin(data.id)] 112 | } 113 | }; 114 | } 115 | 116 | /** 117 | * Verifies an existing session (e.g., for refreshing tokens). 118 | * @param user An AZauthUser object containing at least the access token 119 | * @returns A Promise that resolves to an updated AZauthUser object or an error object 120 | */ 121 | public async verify(user: AZauthUser): Promise { 122 | const response = await fetch(`${this.url}/verify`, { 123 | method: 'POST', 124 | headers: { 'Content-Type': 'application/json' }, 125 | body: JSON.stringify({ 126 | access_token: user.access_token 127 | }) 128 | }); 129 | 130 | const data = await response.json(); 131 | 132 | // If the server indicates an error 133 | if (data.status === 'error') { 134 | return { 135 | error: true, 136 | reason: data.reason, 137 | message: data.message 138 | }; 139 | } 140 | 141 | // Return the updated user session object 142 | return { 143 | access_token: data.access_token, 144 | client_token: data.uuid, 145 | uuid: data.uuid, 146 | name: data.username, 147 | user_properties: '{}', 148 | user_info: { 149 | id: data.id, 150 | banned: data.banned, 151 | money: data.money, 152 | role: data.role, 153 | verified: data.email_verified 154 | }, 155 | meta: { 156 | online: false, 157 | type: 'AZauth' 158 | }, 159 | profile: { 160 | skins: [await this.skin(data.id)] 161 | } 162 | }; 163 | } 164 | 165 | /** 166 | * Logs out a user from the AZauth service (invalidates the token). 167 | * @param user The AZauthUser object with a valid access token 168 | * @returns A Promise that resolves to true if logout is successful, otherwise false 169 | */ 170 | public async signout(user: AZauthUser): Promise { 171 | const response = await fetch(`${this.url}/logout`, { 172 | method: 'POST', 173 | headers: { 'Content-Type': 'application/json' }, 174 | body: JSON.stringify({ 175 | access_token: user.access_token 176 | }) 177 | }); 178 | 179 | const data = await response.json(); 180 | if (data.error) return false; 181 | return true; 182 | } 183 | 184 | /** 185 | * Retrieves the skin of a user by their ID (UUID). 186 | * If the skin exists, returns both the direct URL and a base64-encoded PNG. 187 | * If the skin doesn't exist, only the URL is returned. 188 | * 189 | * @param uuid The UUID or ID of the user 190 | * @returns A Promise resolving to an object with the skin URL (and optional base64 data) 191 | */ 192 | private async skin(uuid: string): Promise<{ url: string; base64?: string }> { 193 | let response = await fetch(`${this.skinAPI}/${uuid}`, { 194 | method: 'GET', 195 | headers: { 'Content-Type': 'application/json' } 196 | }); 197 | 198 | // If the skin is not found (404), return only the URL 199 | if (response.status === 404) { 200 | return { 201 | url: `${this.skinAPI}/${uuid}` 202 | }; 203 | } 204 | 205 | // Otherwise, convert the skin image to a base64-encoded string 206 | const arrayBuffer = await response.arrayBuffer(); 207 | const buffer = Buffer.from(arrayBuffer); 208 | return { 209 | url: `${this.skinAPI}/${uuid}`, 210 | base64: `data:image/png;base64,${buffer.toString('base64')}` 211 | }; 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /src/Authenticator/GUI/Electron.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is distributed under the CC-BY-NC 4.0 license: 3 | * https://creativecommons.org/licenses/by-nc/4.0/ 4 | * 5 | * Original author: Luuxis 6 | */ 7 | 8 | const path = require('path') 9 | const { app, BrowserWindow, session } = require('electron') 10 | 11 | const defaultProperties = { 12 | width: 1000, 13 | height: 650, 14 | resizable: false, 15 | center: true, 16 | icon: path.join(__dirname, '../../../assets/icons', `Microsoft.${(process.platform === 'win32') ? 'ico' : 'png'}`), 17 | } 18 | 19 | module.exports = async function (url: string) { 20 | await new Promise((resolve: any) => { 21 | app.whenReady().then(() => { 22 | session.defaultSession.cookies.get({ domain: 'live.com' }).then((cookies: any) => { 23 | for (let cookie of cookies) { 24 | let urlcookie = `http${cookie.secure ? "s" : ""}://${cookie.domain.replace(/$\./, "") + cookie.path}`; 25 | session.defaultSession.cookies.remove(urlcookie, cookie.name) 26 | } 27 | }) 28 | return resolve(); 29 | }) 30 | }) 31 | 32 | return new Promise(resolve => { 33 | app.whenReady().then(() => { 34 | const mainWindow = new BrowserWindow(defaultProperties) 35 | mainWindow.setMenu(null); 36 | mainWindow.loadURL(url); 37 | var loading = false; 38 | 39 | mainWindow.on("close", () => { 40 | if (!loading) resolve("cancel"); 41 | }) 42 | 43 | mainWindow.webContents.on("did-finish-load", () => { 44 | const loc = mainWindow.webContents.getURL(); 45 | if (loc.startsWith("https://login.live.com/oauth20_desktop.srf")) { 46 | const urlParams = new URLSearchParams(loc.substr(loc.indexOf("?") + 1)).get("code"); 47 | if (urlParams) { 48 | resolve(urlParams); 49 | loading = true; 50 | } else { 51 | resolve("cancel"); 52 | } 53 | try { 54 | mainWindow.close(); 55 | } catch { 56 | console.error("Failed to close window!"); 57 | } 58 | } 59 | }) 60 | }) 61 | }) 62 | } -------------------------------------------------------------------------------- /src/Authenticator/GUI/NW.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is distributed under the CC-BY-NC 4.0 license: 3 | * https://creativecommons.org/licenses/by-nc/4.0/ 4 | * 5 | * Original author: Luuxis 6 | */ 7 | 8 | import path from 'path'; 9 | 10 | const defaultProperties = { 11 | width: 1000, 12 | height: 650, 13 | resizable: false, 14 | position: "center", 15 | frame: true, 16 | icon: path.join(__dirname, '../../../assets/icons/Microsoft.png') 17 | } 18 | 19 | module.exports = async function (url: string) { 20 | await new Promise((resolve: any) => { 21 | //@ts-ignore 22 | nw.Window.get().cookies.getAll({ domain: "live.com" }, async (cookies) => { 23 | for await (let cookie of cookies) { 24 | let url = `http${cookie.secure ? "s" : ""}://${cookie.domain.replace(/$\./, "") + cookie.path}`; 25 | //@ts-ignore 26 | nw.Window.get().cookies.remove({ url: url, name: cookie.name }); 27 | } 28 | return resolve(); 29 | }); 30 | }); 31 | 32 | let code = await new Promise((resolve) => { 33 | //@ts-ignore 34 | nw.Window.open(url, defaultProperties, (Window: any) => { 35 | let interval = null; 36 | let code; 37 | interval = setInterval(() => { 38 | if (Window.window.document.location.href.startsWith("https://login.live.com/oauth20_desktop.srf")) { 39 | clearInterval(interval); 40 | try { 41 | code = Window.window.document.location.href.split("code=")[1].split("&")[0]; 42 | } catch (e) { 43 | code = "cancel"; 44 | } 45 | Window.close(); 46 | } 47 | }, 100); 48 | 49 | Window.on('closed', () => { 50 | if (!code) code = "cancel"; 51 | if (interval) clearInterval(interval); 52 | resolve(code); 53 | }); 54 | }); 55 | }); 56 | return code 57 | } -------------------------------------------------------------------------------- /src/Authenticator/GUI/Terminal.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is distributed under the CC-BY-NC 4.0 license: 3 | * https://creativecommons.org/licenses/by-nc/4.0/ 4 | * 5 | * Original author: Luuxis 6 | */ 7 | 8 | import prompt from 'prompt'; 9 | 10 | module.exports = async function (url: string) { 11 | console.log(`Open brosser ${url}`); 12 | prompt.start(); 13 | let result = await prompt.get(['copy-URL']); 14 | return result['copy-URL'].split("code=")[1].split("&")[0]; 15 | } -------------------------------------------------------------------------------- /src/Authenticator/Mojang.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is distributed under the CC-BY-NC 4.0 license: 3 | * https://creativecommons.org/licenses/by-nc/4.0/ 4 | * 5 | * Original author: Luuxis 6 | */ 7 | 8 | import crypto from 'crypto'; 9 | 10 | let api_url = 'https://authserver.mojang.com'; 11 | 12 | 13 | async function login(username: string, password?: string) { 14 | let UUID = crypto.randomBytes(16).toString('hex'); 15 | if (!password) { 16 | return { 17 | access_token: UUID, 18 | client_token: UUID, 19 | uuid: UUID, 20 | name: username, 21 | user_properties: '{}', 22 | meta: { 23 | online: false, 24 | type: 'Mojang' 25 | } 26 | } 27 | } 28 | 29 | let message = await fetch(`${api_url}/authenticate`, { 30 | method: 'POST', 31 | headers: { 32 | 'Content-Type': 'application/json' 33 | }, 34 | body: JSON.stringify({ 35 | agent: { 36 | name: "Minecraft", 37 | version: 1 38 | }, 39 | username, 40 | password, 41 | clientToken: UUID, 42 | requestUser: true 43 | }) 44 | }).then(res => res.json()); 45 | 46 | if (message.error) { 47 | return message; 48 | }; 49 | let user = { 50 | access_token: message.accessToken, 51 | client_token: message.clientToken, 52 | uuid: message.selectedProfile.id, 53 | name: message.selectedProfile.name, 54 | user_properties: '{}', 55 | meta: { 56 | online: true, 57 | type: 'Mojang' 58 | } 59 | } 60 | return user; 61 | } 62 | 63 | async function refresh(acc: any) { 64 | let message = await fetch(`${api_url}/refresh`, { 65 | method: 'POST', 66 | headers: { 67 | 'Content-Type': 'application/json' 68 | }, 69 | body: JSON.stringify({ 70 | accessToken: acc.access_token, 71 | clientToken: acc.client_token, 72 | requestUser: true 73 | }) 74 | }).then(res => res.json()); 75 | 76 | if (message.error) { 77 | return message; 78 | }; 79 | 80 | let user = { 81 | access_token: message.accessToken, 82 | client_token: message.clientToken, 83 | uuid: message.selectedProfile.id, 84 | name: message.selectedProfile.name, 85 | user_properties: '{}', 86 | meta: { 87 | online: true, 88 | type: 'Mojang' 89 | } 90 | } 91 | return user; 92 | } 93 | 94 | async function validate(acc: any) { 95 | let message = await fetch(`${api_url}/validate`, { 96 | method: 'POST', 97 | headers: { 98 | 'Content-Type': 'application/json' 99 | }, 100 | body: JSON.stringify({ 101 | accessToken: acc.access_token, 102 | clientToken: acc.client_token, 103 | }) 104 | }); 105 | 106 | if (message.status == 204) { 107 | return true; 108 | } else { 109 | return false; 110 | } 111 | } 112 | 113 | async function signout(acc: any) { 114 | let message = await fetch(`${api_url}/invalidate`, { 115 | method: 'POST', 116 | headers: { 117 | 'Content-Type': 'application/json' 118 | }, 119 | body: JSON.stringify({ 120 | accessToken: acc.access_token, 121 | clientToken: acc.client_token, 122 | }) 123 | }).then(res => res.text()); 124 | 125 | if (message == "") { 126 | return true; 127 | } else { 128 | return false; 129 | } 130 | } 131 | 132 | function ChangeAuthApi(url: string) { 133 | api_url = url 134 | } 135 | 136 | export { 137 | login as login, 138 | refresh as refresh, 139 | validate as validate, 140 | signout as signout, 141 | ChangeAuthApi as ChangeAuthApi 142 | } -------------------------------------------------------------------------------- /src/Index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is distributed under the CC-BY-NC 4.0 license: 3 | * https://creativecommons.org/licenses/by-nc/4.0/ 4 | * 5 | * Original author: Luuxis 6 | */ 7 | 8 | import AZauth from './Authenticator/AZauth.js'; 9 | import Launch from './Launch.js'; 10 | import Microsoft from './Authenticator/Microsoft.js'; 11 | import * as Mojang from './Authenticator/Mojang.js'; 12 | import Status from './StatusServer/status.js'; 13 | import Downloader from './utils/Downloader.js'; 14 | 15 | export { 16 | AZauth as AZauth, 17 | Launch as Launch, 18 | Microsoft as Microsoft, 19 | Mojang as Mojang, 20 | Status as Status, 21 | Downloader as Downloader 22 | }; -------------------------------------------------------------------------------- /src/Minecraft-Loader/loader/fabric/fabric.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is distributed under the CC-BY-NC 4.0 license: 3 | * https://creativecommons.org/licenses/by-nc/4.0/ 4 | * 5 | * Original author: Luuxis 6 | */ 7 | 8 | import { EventEmitter } from 'events'; 9 | import fs from 'fs'; 10 | import path from 'path'; 11 | 12 | import { getPathLibraries } from '../../../utils/Index.js'; 13 | import Downloader from '../../../utils/Downloader.js'; 14 | 15 | /** 16 | * Represents the options needed by the FabricMC class. 17 | * You can expand this if your code requires more specific fields. 18 | */ 19 | interface FabricOptions { 20 | path: string; // Base path to your game or library folder 21 | downloadFileMultiple?: number; // Max simultaneous downloads (if supported by Downloader) 22 | loader: { 23 | version: string; // Minecraft version 24 | build: string; // Fabric build (e.g. "latest", "recommended", or a specific version) 25 | }; 26 | } 27 | 28 | /** 29 | * Represents the Loader object that holds metadata URLs and JSON paths. 30 | * For instance, it might look like: 31 | * { 32 | * metaData: 'https://meta.fabricmc.net/v2/versions', 33 | * json: 'https://meta.fabricmc.net/v2/versions/loader/${version}/${build}/profile/json' 34 | * } 35 | */ 36 | interface LoaderObject { 37 | metaData: string; 38 | json: string; // Template string with placeholders like ${version} and ${build} 39 | } 40 | 41 | /** 42 | * Represents the structure of your metadata, including 43 | * game versions and loader builds. Adapt as needed. 44 | */ 45 | interface MetaData { 46 | game: Array<{ 47 | version: string; 48 | stable: boolean; 49 | }>; 50 | loader: Array<{ 51 | version: string; 52 | stable: boolean; 53 | }>; 54 | } 55 | 56 | /** 57 | * Structure of a library entry in the Fabric JSON manifest. 58 | * Extend this interface if you have additional fields like "rules", etc. 59 | */ 60 | interface FabricLibrary { 61 | name: string; 62 | url: string; 63 | rules?: Array; 64 | } 65 | 66 | /** 67 | * The JSON object returned by Fabric metadata endpoints. 68 | */ 69 | interface FabricJSON { 70 | libraries: FabricLibrary[]; 71 | [key: string]: any; 72 | } 73 | 74 | /** 75 | * This class handles downloading Fabric loader JSON metadata, 76 | * resolving the correct build, and downloading the required libraries. 77 | */ 78 | export default class FabricMC extends EventEmitter { 79 | private readonly options: FabricOptions; 80 | 81 | constructor(options: FabricOptions) { 82 | super(); 83 | this.options = options; 84 | } 85 | 86 | /** 87 | * Fetches the Fabric loader metadata to find the correct build for the given 88 | * Minecraft version. If the specified build is "latest" or "recommended", 89 | * it uses the first (most recent) entry. Otherwise, it looks up a specific build. 90 | * 91 | * @param Loader A LoaderObject describing metadata and json URL templates. 92 | * @returns A JSON object representing the Fabric loader profile, or an error object. 93 | */ 94 | public async downloadJson(Loader: LoaderObject): Promise { 95 | let buildInfo: { version: string; stable: boolean } | undefined; 96 | 97 | // Fetch the metadata 98 | let response = await fetch(Loader.metaData); 99 | let metaData: MetaData = await response.json(); 100 | 101 | // Check if the Minecraft version is supported 102 | const version = metaData.game.find(v => v.version === this.options.loader.version); 103 | if (!version) { 104 | return { error: `FabricMC doesn't support Minecraft ${this.options.loader.version}` }; 105 | } 106 | 107 | // Determine the loader build 108 | const availableBuilds = metaData.loader.map(b => b.version); 109 | if (this.options.loader.build === 'latest' || this.options.loader.build === 'recommended') { 110 | buildInfo = metaData.loader[0]; // The first entry is presumably the latest 111 | } else { 112 | buildInfo = metaData.loader.find(l => l.version === this.options.loader.build); 113 | } 114 | 115 | if (!buildInfo) { 116 | return { 117 | error: `Fabric Loader ${this.options.loader.build} not found, Available builds: ${availableBuilds.join(', ')}` 118 | }; 119 | } 120 | 121 | // Build the URL for the Fabric JSON using placeholders 122 | const url = Loader.json 123 | .replace('${build}', buildInfo.version) 124 | .replace('${version}', this.options.loader.version); 125 | 126 | // Fetch the Fabric loader JSON 127 | try { 128 | const result = await fetch(url); 129 | const fabricJson: FabricJSON = await result.json(); 130 | return fabricJson; 131 | } catch (err: any) { 132 | return { error: err.message || 'An error occurred while fetching Fabric JSON' }; 133 | } 134 | } 135 | 136 | /** 137 | * Downloads any missing libraries defined in the Fabric JSON manifest, 138 | * skipping those that already exist locally (or that have rules preventing download). 139 | * 140 | * @param fabricJson The Fabric JSON object with a `libraries` array. 141 | * @returns The same `libraries` array after downloading as needed. 142 | */ 143 | public async downloadLibraries(fabricJson: FabricJSON): Promise { 144 | const { libraries } = fabricJson; 145 | const downloader = new Downloader(); 146 | const downloadQueue: Array<{ 147 | url: string; 148 | folder: string; 149 | path: string; 150 | name: string; 151 | size: number; 152 | }> = []; 153 | 154 | let checkedLibraries = 0; 155 | let totalSize = 0; 156 | 157 | // Identify which libraries need downloading 158 | for (const lib of libraries) { 159 | // Skip if there are any rules that prevent downloading 160 | if (lib.rules) { 161 | this.emit('check', checkedLibraries++, libraries.length, 'libraries'); 162 | continue; 163 | } 164 | 165 | // Parse out the library path 166 | const libInfo = getPathLibraries(lib.name); 167 | const libFolderPath = path.resolve(this.options.path, 'libraries', libInfo.path); 168 | const libFilePath = path.resolve(libFolderPath, libInfo.name); 169 | 170 | // If the file doesn't exist locally, we prepare a download item 171 | if (!fs.existsSync(libFilePath)) { 172 | const libUrl = `${lib.url}${libInfo.path}/${libInfo.name}`; 173 | 174 | let sizeFile = 0; 175 | // Check if the file is accessible and retrieve its size 176 | const res = await downloader.checkURL(libUrl); 177 | if (res && typeof res === 'object' && 'status' in res && res.status === 200) { 178 | sizeFile = res.size; 179 | totalSize += res.size; 180 | } 181 | 182 | downloadQueue.push({ 183 | url: libUrl, 184 | folder: libFolderPath, 185 | path: libFilePath, 186 | name: libInfo.name, 187 | size: sizeFile 188 | }); 189 | } 190 | 191 | // Emit a "check" event for progress tracking 192 | this.emit('check', checkedLibraries++, libraries.length, 'libraries'); 193 | } 194 | 195 | // If there are files to download, do so now 196 | if (downloadQueue.length > 0) { 197 | downloader.on('progress', (downloaded: number, total: number) => { 198 | this.emit('progress', downloaded, total, 'libraries'); 199 | }); 200 | 201 | await downloader.downloadFileMultiple(downloadQueue, totalSize, this.options.downloadFileMultiple); 202 | } 203 | 204 | return libraries; 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /src/Minecraft-Loader/loader/legacyfabric/legacyFabric.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is distributed under the CC-BY-NC 4.0 license: 3 | * https://creativecommons.org/licenses/by-nc/4.0/ 4 | * 5 | * Original author: Luuxis 6 | */ 7 | 8 | import fs from 'fs'; 9 | import path from 'path'; 10 | import { EventEmitter } from 'events'; 11 | 12 | import { getPathLibraries } from '../../../utils/Index.js'; 13 | import Downloader from '../../../utils/Downloader.js'; 14 | 15 | /** 16 | * Represents the "loader" part of the user's options, containing version info for Minecraft and Fabric. 17 | */ 18 | interface FabricLoaderConfig { 19 | version: string; // e.g., "1.19.2" 20 | build: string; // e.g., "latest", "recommended" or a specific build like "0.14.8" 21 | } 22 | 23 | /** 24 | * Overall options passed to FabricMC. 25 | * Adjust or extend according to your project needs. 26 | */ 27 | interface FabricOptions { 28 | path: string; // Base path where libraries and files should be placed 29 | loader: FabricLoaderConfig; // Configuration for the Fabric loader 30 | downloadFileMultiple?: number; // Number of concurrent downloads (if your Downloader supports it) 31 | [key: string]: any; // Allow extra fields as needed 32 | } 33 | 34 | /** 35 | * This object typically references the metadata and JSON URLs for the Fabric API, 36 | * for example: 37 | * { 38 | * metaData: 'https://meta.fabricmc.net/v2/versions', 39 | * json: 'https://meta.fabricmc.net/v2/versions/loader/${version}/${build}/profile/json' 40 | * } 41 | */ 42 | interface LoaderObject { 43 | metaData: string; // URL to fetch general Fabric metadata 44 | json: string; // Template URL to fetch the final Fabric loader JSON 45 | } 46 | 47 | /** 48 | * Represents one library entry in the Fabric loader JSON. 49 | */ 50 | interface FabricLibrary { 51 | name: string; 52 | url: string; 53 | rules?: Array; 54 | } 55 | 56 | /** 57 | * Represents the final JSON object fetched for the Fabric loader, 58 | * containing an array of libraries. 59 | */ 60 | interface FabricJSON { 61 | libraries: FabricLibrary[]; 62 | [key: string]: any; // Extend or adapt based on actual structure 63 | } 64 | 65 | /** 66 | * A class that handles downloading the Fabric loader JSON metadata 67 | * and the libraries needed to launch Fabric. 68 | */ 69 | export default class FabricMC extends EventEmitter { 70 | private readonly options: FabricOptions; 71 | 72 | constructor(options: FabricOptions = { path: '', loader: { version: '', build: '' } }) { 73 | super(); 74 | this.options = options; 75 | } 76 | 77 | /** 78 | * Fetches metadata from the Fabric API to identify the correct build for the given version. 79 | * If the build is "latest" or "recommended", it picks the first entry from the loader array. 80 | * Otherwise, it tries to match the specific build requested by the user. 81 | * 82 | * @param Loader A LoaderObject with metaData and json URLs for Fabric. 83 | * @returns A FabricJSON object on success, or an error object. 84 | */ 85 | public async downloadJson(Loader: LoaderObject): Promise { 86 | let selectedBuild: { version: string } | undefined; 87 | 88 | // Fetch overall metadata 89 | const metaResponse = await fetch(Loader.metaData); 90 | const metaData = await metaResponse.json(); 91 | 92 | // Check if the requested Minecraft version is supported 93 | const versionExists = metaData.game.find((ver: any) => ver.version === this.options.loader.version); 94 | if (!versionExists) { 95 | return { error: `FabricMC doesn't support Minecraft ${this.options.loader.version}` }; 96 | } 97 | 98 | // Extract all possible loader builds 99 | const availableBuilds = metaData.loader.map((b: any) => b.version); 100 | 101 | // If user wants the "latest" or "recommended" build, use the first in the array 102 | if (this.options.loader.build === 'latest' || this.options.loader.build === 'recommended') { 103 | selectedBuild = metaData.loader[0]; 104 | } else { 105 | // Otherwise, search for a matching build 106 | selectedBuild = metaData.loader.find((loaderBuild: any) => loaderBuild.version === this.options.loader.build); 107 | } 108 | 109 | if (!selectedBuild) { 110 | return { 111 | error: `Fabric Loader ${this.options.loader.build} not found, Available builds: ${availableBuilds.join(', ')}` 112 | }; 113 | } 114 | 115 | // Construct the final URL for fetching the Fabric JSON 116 | const url = Loader.json 117 | .replace('${build}', selectedBuild.version) 118 | .replace('${version}', this.options.loader.version); 119 | 120 | // Fetch and parse the JSON 121 | try { 122 | const response = await fetch(url); 123 | const fabricJson: FabricJSON = await response.json(); 124 | return fabricJson; 125 | } catch (err: any) { 126 | return { error: err.message || 'Failed to fetch or parse Fabric loader JSON' }; 127 | } 128 | } 129 | 130 | /** 131 | * Iterates over the libraries in the Fabric JSON, checks if they exist locally, 132 | * and if not, downloads them. Skips libraries that have "rules" (usually platform-specific). 133 | * 134 | * @param json The Fabric loader JSON object with a "libraries" array. 135 | * @returns The same libraries array after downloads, or an error object if something fails. 136 | */ 137 | public async downloadLibraries(json: FabricJSON): Promise { 138 | const { libraries } = json; 139 | const downloader = new Downloader(); 140 | let pendingDownloads: Array<{ 141 | url: string; 142 | folder: string; 143 | path: string; 144 | name: string; 145 | size: number; 146 | }> = []; 147 | 148 | let checkedCount = 0; 149 | let totalSize = 0; 150 | 151 | // Evaluate each library for possible download 152 | for (const lib of libraries) { 153 | // Skip if library has rules that might disqualify it for this platform 154 | if (lib.rules) { 155 | this.emit('check', checkedCount++, libraries.length, 'libraries'); 156 | continue; 157 | } 158 | 159 | // Build the local file path 160 | const libInfo = getPathLibraries(lib.name); 161 | const libFolder = path.resolve(this.options.path, 'libraries', libInfo.path); 162 | const libFilePath = path.resolve(libFolder, libInfo.name); 163 | 164 | // If it doesn't exist, prepare to download 165 | if (!fs.existsSync(libFilePath)) { 166 | const libUrl = `${lib.url}${libInfo.path}/${libInfo.name}`; 167 | 168 | let fileSize = 0; 169 | // Check if the file is available and get its size 170 | const checkRes = await downloader.checkURL(libUrl); 171 | if (checkRes && typeof checkRes === 'object' && 'status' in checkRes && checkRes.status === 200) { 172 | fileSize = checkRes.size; 173 | totalSize += fileSize; 174 | } 175 | 176 | pendingDownloads.push({ 177 | url: libUrl, 178 | folder: libFolder, 179 | path: libFilePath, 180 | name: libInfo.name, 181 | size: fileSize 182 | }); 183 | } 184 | 185 | this.emit('check', checkedCount++, libraries.length, 'libraries'); 186 | } 187 | 188 | // Download all missing libraries in bulk 189 | if (pendingDownloads.length > 0) { 190 | downloader.on('progress', (downloaded: number, total: number) => { 191 | this.emit('progress', downloaded, total, 'libraries'); 192 | }); 193 | 194 | await downloader.downloadFileMultiple(pendingDownloads, totalSize, this.options.downloadFileMultiple); 195 | } 196 | 197 | return libraries; 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /src/Minecraft-Loader/loader/quilt/quilt.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is distributed under the CC-BY-NC 4.0 license: 3 | * https://creativecommons.org/licenses/by-nc/4.0/ 4 | * 5 | * Original author: Luuxis 6 | */ 7 | 8 | import fs from 'fs'; 9 | import path from 'path'; 10 | import { EventEmitter } from 'events'; 11 | 12 | import { getPathLibraries } from '../../../utils/Index.js'; 13 | import Downloader from '../../../utils/Downloader.js'; 14 | 15 | /** 16 | * Represents the Quilt loader configuration within the user's options. 17 | */ 18 | interface QuiltLoaderConfig { 19 | version: string; // e.g., "1.19.2" 20 | build: string; // e.g., "latest", "recommended", or a specific build ID 21 | } 22 | 23 | /** 24 | * The main options object passed to the Quilt class. 25 | * You can extend this as needed by your application. 26 | */ 27 | interface QuiltOptions { 28 | path: string; // Base path for storing downloaded libraries, etc. 29 | loader: QuiltLoaderConfig; // Loader configuration for Quilt 30 | downloadFileMultiple?: number; // Number of concurrent downloads 31 | [key: string]: any; // Allow additional fields as needed 32 | } 33 | 34 | /** 35 | * Describes the data needed for fetching Quilt metadata and loader JSON. 36 | * For example: 37 | * { 38 | * metaData: "https://meta.quiltmc.org/v3/versions", 39 | * json: "https://meta.quiltmc.org/v3/versions/loader/${version}/${build}/profile/json" 40 | * } 41 | */ 42 | interface LoaderObject { 43 | metaData: string; 44 | json: string; // URL pattern with placeholders like ${version} and ${build} 45 | } 46 | 47 | /** 48 | * A structure for one library entry in the Quilt loader JSON. 49 | */ 50 | interface QuiltLibrary { 51 | name: string; 52 | url: string; 53 | rules?: Array; 54 | } 55 | 56 | /** 57 | * The JSON object typically returned by the Quilt API, 58 | * containing an array of libraries and possibly other fields. 59 | */ 60 | interface QuiltJSON { 61 | libraries: QuiltLibrary[]; 62 | [key: string]: any; 63 | } 64 | 65 | /** 66 | * This class handles fetching the Quilt loader metadata, 67 | * identifying the appropriate build for a given Minecraft version, 68 | * and downloading required libraries. 69 | */ 70 | export default class Quilt extends EventEmitter { 71 | private readonly options: QuiltOptions; 72 | private versionMinecraft: string | undefined; 73 | 74 | constructor(options: QuiltOptions = { path: '', loader: { version: '', build: '' } }) { 75 | super(); 76 | this.options = options; 77 | } 78 | 79 | /** 80 | * Fetches the Quilt loader metadata to identify the correct build for the specified 81 | * Minecraft version. If "latest" or "recommended" is requested, picks the most 82 | * recent or stable build accordingly. 83 | * 84 | * @param Loader An object describing where to fetch Quilt metadata and JSON. 85 | * @returns A QuiltJSON object on success, or an error object if something fails. 86 | */ 87 | public async downloadJson(Loader: LoaderObject): Promise { 88 | let selectedBuild: any; 89 | 90 | // Fetch the metadata 91 | const metaResponse = await fetch(Loader.metaData); 92 | const metaData = await metaResponse.json(); 93 | 94 | // Check if the requested Minecraft version is supported 95 | const mcVersionExists = metaData.game.find((ver: any) => ver.version === this.options.loader.version); 96 | if (!mcVersionExists) { 97 | return { error: `QuiltMC doesn't support Minecraft ${this.options.loader.version}` }; 98 | } 99 | 100 | // Gather all available builds for this version 101 | const availableBuilds = metaData.loader.map((b: any) => b.version); 102 | 103 | // Determine which build to use 104 | if (this.options.loader.build === 'latest') { 105 | selectedBuild = metaData.loader[0]; 106 | } else if (this.options.loader.build === 'recommended') { 107 | // Attempt to find a build that isn't labeled "beta" 108 | selectedBuild = metaData.loader.find((b: any) => !b.version.includes('beta')); 109 | } else { 110 | // Otherwise, match a specific build 111 | selectedBuild = metaData.loader.find( 112 | (loaderItem: any) => loaderItem.version === this.options.loader.build 113 | ); 114 | } 115 | 116 | if (!selectedBuild) { 117 | return { 118 | error: `QuiltMC Loader ${this.options.loader.build} not found, Available builds: ${availableBuilds.join(', ')}` 119 | }; 120 | } 121 | 122 | // Build the URL for the Quilt loader profile JSON 123 | const url = Loader.json 124 | .replace('${build}', selectedBuild.version) 125 | .replace('${version}', this.options.loader.version); 126 | 127 | // Fetch the JSON profile 128 | try { 129 | const response = await fetch(url); 130 | const quiltJson: QuiltJSON = await response.json(); 131 | return quiltJson; 132 | } catch (err: any) { 133 | return { error: err.message || 'Failed to fetch or parse Quilt loader JSON' }; 134 | } 135 | } 136 | 137 | /** 138 | * Parses the Quilt JSON to determine which libraries need downloading, skipping 139 | * any that already exist or that are disqualified by "rules". Downloads them 140 | * in bulk using the Downloader utility. 141 | * 142 | * @param quiltJson A QuiltJSON object containing a list of libraries. 143 | * @returns The final list of libraries, or an error if something fails. 144 | */ 145 | public async downloadLibraries(quiltJson: QuiltJSON): Promise { 146 | const { libraries } = quiltJson; 147 | const downloader = new Downloader(); 148 | 149 | let filesToDownload: Array<{ 150 | url: string; 151 | folder: string; 152 | path: string; 153 | name: string; 154 | size: number; 155 | }> = []; 156 | 157 | let checkedLibraries = 0; 158 | let totalSize = 0; 159 | 160 | for (const lib of libraries) { 161 | // If rules exist, skip it (likely platform-specific logic) 162 | if (lib.rules) { 163 | this.emit('check', checkedLibraries++, libraries.length, 'libraries'); 164 | continue; 165 | } 166 | 167 | // Construct the local path where this library should reside 168 | const libInfo = getPathLibraries(lib.name); 169 | const libFolder = path.resolve(this.options.path, 'libraries', libInfo.path); 170 | const libFilePath = path.resolve(libFolder, libInfo.name); 171 | 172 | // If the library doesn't exist locally, prepare to download 173 | if (!fs.existsSync(libFilePath)) { 174 | const libUrl = `${lib.url}${libInfo.path}/${libInfo.name}`; 175 | 176 | let fileSize = 0; 177 | const checkResult = await downloader.checkURL(libUrl); 178 | 179 | if (checkResult && checkResult.status === 200) { 180 | fileSize = checkResult.size; 181 | totalSize += fileSize; 182 | } 183 | 184 | filesToDownload.push({ 185 | url: libUrl, 186 | folder: libFolder, 187 | path: libFilePath, 188 | name: libInfo.name, 189 | size: fileSize 190 | }); 191 | } 192 | 193 | 194 | // Emit a "check" event for each library 195 | this.emit('check', checkedLibraries++, libraries.length, 'libraries'); 196 | } 197 | 198 | // If there are libraries to download, proceed with the bulk download 199 | if (filesToDownload.length > 0) { 200 | downloader.on('progress', (downloaded: number, total: number) => { 201 | this.emit('progress', downloaded, total, 'libraries'); 202 | }); 203 | 204 | await downloader.downloadFileMultiple(filesToDownload, totalSize, this.options.downloadFileMultiple); 205 | } 206 | 207 | return libraries; 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /src/Minecraft-Loader/patcher.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is distributed under the CC-BY-NC 4.0 license: 3 | * https://creativecommons.org/licenses/by-nc/4.0/ 4 | * 5 | * Original author: Luuxis 6 | */ 7 | 8 | import { spawn } from 'child_process'; 9 | import fs from 'fs'; 10 | import path from 'path'; 11 | import { EventEmitter } from 'events'; 12 | import { getPathLibraries, getFileFromArchive } from '../utils/Index.js'; 13 | 14 | interface ForgePatcherOptions { 15 | path: string; 16 | loader: { 17 | type: string; 18 | }; 19 | } 20 | 21 | interface Config { 22 | java: string; 23 | minecraft: string; 24 | minecraftJson: string; 25 | } 26 | 27 | interface ProfileData { 28 | client: string; 29 | [key: string]: any; 30 | } 31 | 32 | interface Processor { 33 | jar: string; 34 | args: string[]; 35 | classpath: string[]; 36 | sides?: string[]; 37 | } 38 | 39 | export interface Profile { 40 | data: Record; 41 | processors?: any[]; 42 | libraries?: Array<{ name?: string }>; // The universal jar/libraries reference 43 | path?: string; 44 | } 45 | 46 | export default class ForgePatcher extends EventEmitter { 47 | private readonly options: ForgePatcherOptions; 48 | 49 | constructor(options: ForgePatcherOptions) { 50 | super(); 51 | this.options = options; 52 | } 53 | 54 | public async patcher(profile: Profile, config: Config, neoForgeOld: boolean = true): Promise { 55 | const { processors } = profile; 56 | 57 | for (const [_, processor] of Object.entries(processors)) { 58 | if (processor.sides && !processor.sides.includes('client')) continue; 59 | 60 | const jarInfo = getPathLibraries(processor.jar); 61 | const jarPath = path.resolve(this.options.path, 'libraries', jarInfo.path, jarInfo.name); 62 | 63 | const args = processor.args 64 | .map(arg => this.setArgument(arg, profile, config, neoForgeOld)) 65 | .map(arg => this.computePath(arg)); 66 | 67 | const classPaths = processor.classpath.map(cp => { 68 | const cpInfo = getPathLibraries(cp); 69 | return `"${path.join(this.options.path, 'libraries', cpInfo.path, cpInfo.name)}"`; 70 | }); 71 | 72 | const mainClass = await this.readJarManifest(jarPath); 73 | if (!mainClass) { 74 | this.emit('error', `Impossible de déterminer la classe principale dans le JAR: ${jarPath}`); 75 | continue; 76 | } 77 | 78 | await new Promise((resolve) => { 79 | const spawned = spawn( 80 | `"${path.resolve(config.java)}"`, 81 | [ 82 | '-classpath', 83 | [`"${jarPath}"`, ...classPaths].join(path.delimiter), 84 | mainClass, 85 | ...args 86 | ], 87 | { shell: true } 88 | ); 89 | 90 | spawned.stdout.on('data', data => { 91 | this.emit('patch', data.toString('utf-8')); 92 | }); 93 | 94 | spawned.stderr.on('data', data => { 95 | this.emit('patch', data.toString('utf-8')); 96 | }); 97 | 98 | spawned.on('close', code => { 99 | if (code !== 0) { 100 | this.emit('error', `Le patcher Forge s'est terminé avec le code ${code}`); 101 | } 102 | resolve(); 103 | }); 104 | }); 105 | } 106 | } 107 | 108 | public check(profile: Profile): boolean { 109 | const { processors } = profile; 110 | let files: string[] = []; 111 | 112 | for (const processor of Object.values(processors)) { 113 | if (processor.sides && !processor.sides.includes('client')) continue; 114 | 115 | processor.args.forEach(arg => { 116 | const finalArg = arg.replace('{', '').replace('}', ''); 117 | if (profile.data[finalArg]) { 118 | if (finalArg === 'BINPATCH') return; 119 | files.push(profile.data[finalArg].client); 120 | } 121 | }); 122 | } 123 | 124 | files = Array.from(new Set(files)); 125 | 126 | for (const file of files) { 127 | const lib = getPathLibraries(file.replace('[', '').replace(']', '')); 128 | const filePath = path.resolve(this.options.path, 'libraries', lib.path, lib.name); 129 | if (!fs.existsSync(filePath)) return false; 130 | } 131 | return true; 132 | } 133 | 134 | private setArgument(arg: string, profile: Profile, config: Config, neoForgeOld: boolean): string { 135 | const finalArg = arg.replace('{', '').replace('}', ''); 136 | 137 | const universalLib = profile.libraries.find(lib => { 138 | if (this.options.loader.type === 'forge') return lib.name.startsWith('net.minecraftforge:forge'); 139 | else return lib.name.startsWith(neoForgeOld ? 'net.neoforged:forge' : 'net.neoforged:neoforge'); 140 | }); 141 | 142 | if (profile.data[finalArg]) { 143 | if (finalArg === 'BINPATCH') { 144 | const jarInfo = getPathLibraries(profile.path || (universalLib?.name ?? '')); 145 | return `"${path.join(this.options.path, 'libraries', jarInfo.path, jarInfo.name).replace('.jar', '-clientdata.lzma')}"`; 146 | } 147 | return profile.data[finalArg].client; 148 | } 149 | 150 | return arg 151 | .replace('{SIDE}', 'client') 152 | .replace('{ROOT}', `"${path.dirname(path.resolve(this.options.path, 'forge'))}"`) 153 | .replace('{MINECRAFT_JAR}', `"${config.minecraft}"`) 154 | .replace('{MINECRAFT_VERSION}', `"${config.minecraftJson}"`) 155 | .replace('{INSTALLER}', `"${path.join(this.options.path, 'libraries')}"`) 156 | .replace('{LIBRARY_DIR}', `"${path.join(this.options.path, 'libraries')}"`); 157 | } 158 | 159 | private computePath(arg: string): string { 160 | if (arg.startsWith('[')) { 161 | const libInfo = getPathLibraries(arg.replace('[', '').replace(']', '')); 162 | return `"${path.join(this.options.path, 'libraries', libInfo.path, libInfo.name)}"`; 163 | } 164 | return arg; 165 | } 166 | 167 | private async readJarManifest(jarPath: string): Promise { 168 | const manifestContent = await getFileFromArchive(jarPath, 'META-INF/MANIFEST.MF'); 169 | if (!manifestContent) return null; 170 | 171 | const content = manifestContent.toString(); 172 | const mainClassLine = content.split('Main-Class: ')[1]; 173 | if (!mainClassLine) return null; 174 | return mainClassLine.split('\r\n')[0]; 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/Minecraft/Minecraft-Assets.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is distributed under the CC-BY-NC 4.0 license: 3 | * https://creativecommons.org/licenses/by-nc/4.0/ 4 | * 5 | * Original author: Luuxis 6 | */ 7 | import fs from 'fs'; 8 | 9 | /** 10 | * Represents the general structure of the options passed to MinecraftAssets. 11 | * You can expand or modify these fields as necessary for your specific use case. 12 | */ 13 | export interface MinecraftAssetsOptions { 14 | path: string; // Base path to the Minecraft data folder 15 | instance?: string; // Instance name (if using multi-instance setup) 16 | } 17 | 18 | /** 19 | * Represents a simplified version of the Minecraft version JSON structure. 20 | */ 21 | export interface VersionJSON { 22 | assetIndex?: { 23 | id: string; // e.g. "1.19" 24 | url: string; // URL where the asset index JSON can be fetched 25 | }; 26 | assets?: string; // e.g. "1.19" 27 | } 28 | 29 | /** 30 | * Represents a single asset object in the final array returned by getAssets(). 31 | */ 32 | export interface AssetItem { 33 | type: 'CFILE' | 'Assets'; 34 | path: string; 35 | content?: string; // Used if type = "CFILE" 36 | sha1?: string; // Used if type = "Assets" 37 | size?: number; // Used if type = "Assets" 38 | url?: string; // Used if type = "Assets" 39 | } 40 | 41 | /** 42 | * Class responsible for handling Minecraft asset index fetching 43 | * and optionally copying legacy assets to the correct directory. 44 | */ 45 | export default class MinecraftAssets { 46 | private assetIndex: { id: string; url: string } | undefined; 47 | private readonly options: MinecraftAssetsOptions; 48 | 49 | constructor(options: MinecraftAssetsOptions) { 50 | this.options = options; 51 | } 52 | 53 | /** 54 | * Fetches the asset index from the provided JSON object, then constructs 55 | * and returns an array of asset download objects. These can be processed 56 | * by a downloader to ensure all assets are present locally. 57 | * 58 | * @param versionJson A JSON object containing an "assetIndex" field. 59 | * @returns An array of AssetItem objects with download info. 60 | */ 61 | public async getAssets(versionJson: VersionJSON): Promise { 62 | this.assetIndex = versionJson.assetIndex; 63 | if (!this.assetIndex) { 64 | // If there's no assetIndex, there's nothing to download. 65 | return []; 66 | } 67 | 68 | // Fetch the asset index JSON from the remote URL 69 | let data; 70 | try { 71 | const response = await fetch(this.assetIndex.url); 72 | data = await response.json(); 73 | } catch (err: any) { 74 | throw new Error(`Failed to fetch asset index: ${err.message}`); 75 | } 76 | 77 | // First item is the index file itself, which we'll store locally 78 | const assetsArray: AssetItem[] = [ 79 | { 80 | type: 'CFILE', 81 | path: `assets/indexes/${this.assetIndex.id}.json`, 82 | content: JSON.stringify(data) 83 | } 84 | ]; 85 | 86 | // Convert the "objects" property into a list of individual assets 87 | const objects = Object.values(data.objects || {}); 88 | for (const obj of objects as Array<{ hash: string; size: number }>) { 89 | assetsArray.push({ 90 | type: 'Assets', 91 | sha1: obj.hash, 92 | size: obj.size, 93 | path: `assets/objects/${obj.hash.substring(0, 2)}/${obj.hash}`, 94 | url: `https://resources.download.minecraft.net/${obj.hash.substring(0, 2)}/${obj.hash}` 95 | }); 96 | } 97 | 98 | return assetsArray; 99 | } 100 | 101 | /** 102 | * Copies legacy assets (when using older versions of Minecraft) from 103 | * the main "objects" folder to a "resources" folder, preserving the 104 | * directory structure. 105 | * 106 | * @param versionJson A JSON object that has an "assets" property for the index name. 107 | */ 108 | public copyAssets(versionJson: VersionJSON): void { 109 | // Determine the legacy directory where resources should go 110 | let legacyDirectory = `${this.options.path}/resources`; 111 | if (this.options.instance) { 112 | legacyDirectory = `${this.options.path}/instances/${this.options.instance}/resources`; 113 | } 114 | 115 | // The path to the local asset index JSON 116 | const pathAssets = `${this.options.path}/assets/indexes/${versionJson.assets}.json`; 117 | if (!fs.existsSync(pathAssets)) { 118 | return; // Nothing to copy if the file doesn't exist 119 | } 120 | 121 | // Parse the asset index JSON 122 | let assetsData; 123 | try { 124 | assetsData = JSON.parse(fs.readFileSync(pathAssets, 'utf-8')); 125 | } catch (err: any) { 126 | throw new Error(`Failed to read assets index file: ${err.message}`); 127 | } 128 | 129 | // Each entry is [filePath, { hash, size }] 130 | const assetsEntries = Object.entries(assetsData.objects || {}); 131 | for (const [filePath, hashData] of assetsEntries) { 132 | const hashObj = hashData as { hash: string; size: number }; 133 | const fullHash = hashObj.hash; 134 | const subHash = fullHash.substring(0, 2); 135 | 136 | // Directory where the hashed file is stored 137 | const subAssetDir = `${this.options.path}/assets/objects/${subHash}`; 138 | 139 | // If needed, create the corresponding directories in the legacy folder 140 | const pathSegments = filePath.split('/'); 141 | pathSegments.pop(); // Remove the last segment (the filename itself) 142 | if (!fs.existsSync(`${legacyDirectory}/${pathSegments.join('/')}`)) { 143 | fs.mkdirSync(`${legacyDirectory}/${pathSegments.join('/')}`, { recursive: true }); 144 | } 145 | 146 | // Copy the file if it doesn't already exist in the legacy location 147 | const sourceFile = `${subAssetDir}/${fullHash}`; 148 | const targetFile = `${legacyDirectory}/${filePath}`; 149 | if (!fs.existsSync(targetFile)) { 150 | fs.copyFileSync(sourceFile, targetFile); 151 | } 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/Minecraft/Minecraft-Bundle.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is distributed under the CC-BY-NC 4.0 license: 3 | * https://creativecommons.org/licenses/by-nc/4.0/ 4 | * 5 | * Original author: Luuxis 6 | */ 7 | 8 | import fs from 'fs'; 9 | import path from 'path'; 10 | import { getFileHash } from '../utils/Index.js'; 11 | 12 | /** 13 | * Represents a single file or object that may need to be downloaded or checked. 14 | */ 15 | export interface BundleItem { 16 | type?: 'CFILE' | 'Assets' | string; // e.g., "CFILE" for direct content files 17 | path: string; // Local path where file is or should be stored 18 | folder?: string; // Directory path (derived from 'path') 19 | content?: string; // File content if type === "CFILE" 20 | sha1?: string; // Expected SHA-1 hash for the file 21 | size?: number; // Size in bytes if relevant 22 | url?: string; // Download URL if relevant 23 | } 24 | 25 | /** 26 | * Options for the MinecraftBundle class, indicating paths and ignored files. 27 | */ 28 | export interface MinecraftBundleOptions { 29 | path: string; // The main Minecraft directory or root path 30 | instance?: string; // Instance name, if working with multiple instances 31 | ignored: string[]; // Files or directories to ignore when cleaning 32 | } 33 | 34 | /** 35 | * This class manages checking, downloading, and cleaning up Minecraft files. 36 | * It compares local files with a provided bundle, identifies missing or 37 | * outdated files, and can remove extraneous files. 38 | */ 39 | export default class MinecraftBundle { 40 | private options: MinecraftBundleOptions; 41 | 42 | constructor(options: MinecraftBundleOptions) { 43 | this.options = options; 44 | } 45 | 46 | /** 47 | * Checks each item in the provided bundle to see if it needs to be 48 | * downloaded or updated (e.g., if hashes don't match). 49 | * 50 | * @param bundle Array of file items describing what needs to be on disk. 51 | * @returns Array of BundleItem objects that require downloading. 52 | */ 53 | public async checkBundle(bundle: BundleItem[]): Promise { 54 | const toDownload: BundleItem[] = []; 55 | 56 | for (const file of bundle) { 57 | if (!file.path) continue; 58 | 59 | // Convert path to absolute, consistent format 60 | file.path = path.resolve(this.options.path, file.path).replace(/\\/g, '/'); 61 | file.folder = file.path.split('/').slice(0, -1).join('/'); 62 | 63 | // If it's a direct content file (CFILE), we create/write the content immediately 64 | if (file.type === 'CFILE') { 65 | if (!fs.existsSync(file.folder)) { 66 | fs.mkdirSync(file.folder, { recursive: true, mode: 0o777 }); 67 | } 68 | fs.writeFileSync(file.path, file.content ?? '', { encoding: 'utf8', mode: 0o755 }); 69 | continue; 70 | } 71 | 72 | // If the file is supposed to have a certain hash, check it. 73 | if (fs.existsSync(file.path)) { 74 | // Build the instance path prefix for ignoring checks 75 | let replaceName = `${this.options.path}/`; 76 | if (this.options.instance) { 77 | replaceName = `${this.options.path}/instances/${this.options.instance}/`; 78 | } 79 | 80 | // If file is in "ignored" list, skip checks 81 | const relativePath = file.path.replace(replaceName, ''); 82 | if (this.options.ignored.includes(relativePath)) { 83 | continue; 84 | } 85 | 86 | // If the file has a hash and doesn't match, mark it for download 87 | if (file.sha1) { 88 | const localHash = await getFileHash(file.path); 89 | if (localHash !== file.sha1) { 90 | toDownload.push(file); 91 | } 92 | } 93 | } else { 94 | // The file doesn't exist at all, mark it for download 95 | toDownload.push(file); 96 | } 97 | } 98 | 99 | return toDownload; 100 | } 101 | 102 | /** 103 | * Calculates the total download size of all files in the bundle. 104 | * 105 | * @param bundle Array of items in the bundle (with a 'size' field). 106 | * @returns Sum of all file sizes in bytes. 107 | */ 108 | public async getTotalSize(bundle: BundleItem[]): Promise { 109 | let totalSize = 0; 110 | for (const file of bundle) { 111 | if (file.size) { 112 | totalSize += file.size; 113 | } 114 | } 115 | return totalSize; 116 | } 117 | 118 | /** 119 | * Removes files or directories that should not be present, i.e., those 120 | * not listed in the bundle and not in the "ignored" list. 121 | * If the file is a directory, it's removed recursively. 122 | * 123 | * @param bundle Array of BundleItems representing valid files. 124 | */ 125 | public async checkFiles(bundle: BundleItem[]): Promise { 126 | // If using instances, ensure the 'instances' directory exists 127 | let instancePath = ''; 128 | if (this.options.instance) { 129 | if (!fs.existsSync(`${this.options.path}/instances`)) { 130 | fs.mkdirSync(`${this.options.path}/instances`, { recursive: true }); 131 | } 132 | instancePath = `/instances/${this.options.instance}`; 133 | } 134 | 135 | // Gather all existing files in the relevant directory 136 | const allFiles = this.options.instance 137 | ? this.getFiles(`${this.options.path}${instancePath}`) 138 | : this.getFiles(this.options.path); 139 | 140 | // Also gather files from "loader" and "runtime" directories to ignore 141 | const ignoredFiles = [ 142 | ...this.getFiles(`${this.options.path}/loader`), 143 | ...this.getFiles(`${this.options.path}/runtime`) 144 | ]; 145 | 146 | // Convert custom ignored paths to actual file paths 147 | for (let ignoredPath of this.options.ignored) { 148 | ignoredPath = `${this.options.path}${instancePath}/${ignoredPath}`; 149 | if (fs.existsSync(ignoredPath)) { 150 | if (fs.statSync(ignoredPath).isDirectory()) { 151 | // If it's a directory, add all files within it 152 | ignoredFiles.push(...this.getFiles(ignoredPath)); 153 | } else { 154 | // If it's a single file, just add that file 155 | ignoredFiles.push(ignoredPath); 156 | } 157 | } 158 | } 159 | 160 | // Mark bundle paths as ignored (so we don't delete them) 161 | bundle.forEach(file => { 162 | ignoredFiles.push(file.path); 163 | }); 164 | 165 | // Filter out all ignored files from the main file list 166 | const filesToDelete = allFiles.filter(file => !ignoredFiles.includes(file)); 167 | 168 | // Remove each file or directory 169 | for (const filePath of filesToDelete) { 170 | try { 171 | const stats = fs.statSync(filePath); 172 | if (stats.isDirectory()) { 173 | fs.rmSync(filePath, { recursive: true }); 174 | } else { 175 | fs.unlinkSync(filePath); 176 | 177 | // Clean up empty folders going upward until we hit the main path 178 | let currentDir = path.dirname(filePath); 179 | while (true) { 180 | if (currentDir === this.options.path) break; 181 | const dirContents = fs.readdirSync(currentDir); 182 | if (dirContents.length === 0) { 183 | fs.rmSync(currentDir); 184 | } 185 | currentDir = path.dirname(currentDir); 186 | } 187 | } 188 | } catch { 189 | // If an error occurs (e.g. file locked or non-existent), skip it 190 | continue; 191 | } 192 | } 193 | } 194 | 195 | /** 196 | * Recursively gathers all files in a given directory path. 197 | * If a directory is empty, it is also added to the returned array. 198 | * 199 | * @param dirPath The starting directory path to walk. 200 | * @param collectedFiles Used internally to store file paths. 201 | * @returns The array of all file paths (and empty directories) under dirPath. 202 | */ 203 | private getFiles(dirPath: string, collectedFiles: string[] = []): string[] { 204 | if (fs.existsSync(dirPath)) { 205 | const entries = fs.readdirSync(dirPath); 206 | // If the directory is empty, store it as a "file" so it can be processed 207 | if (entries.length === 0) { 208 | collectedFiles.push(dirPath); 209 | } 210 | // Explore each child entry 211 | for (const entry of entries) { 212 | const fullPath = `${dirPath}/${entry}`; 213 | const stats = fs.statSync(fullPath); 214 | if (stats.isDirectory()) { 215 | this.getFiles(fullPath, collectedFiles); 216 | } else { 217 | collectedFiles.push(fullPath); 218 | } 219 | } 220 | } 221 | return collectedFiles; 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /src/Minecraft/Minecraft-Json.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is distributed under the CC-BY-NC 4.0 license: 3 | * https://creativecommons.org/licenses/by-nc/4.0/ 4 | * 5 | * Original author: Luuxis 6 | */ 7 | 8 | import os from 'os'; 9 | import MinecraftNativeLinuxARM from './Minecraft-Lwjgl-Native.js'; 10 | 11 | /** 12 | * Basic structure for options passed to the Json class. 13 | * Modify or expand based on your actual usage. 14 | */ 15 | export interface JsonOptions { 16 | version: string; // The targeted Minecraft version (e.g. "1.19", "latest_release", etc.) 17 | [key: string]: any; // Include any additional fields needed by your code 18 | } 19 | 20 | /** 21 | * Represents a single version entry from Mojang's version manifest. 22 | */ 23 | export interface VersionEntry { 24 | id: string; 25 | type: string; 26 | url: string; 27 | time: string; 28 | releaseTime: string; 29 | } 30 | 31 | /** 32 | * Structure of the Mojang version manifest (simplified). 33 | */ 34 | export interface MojangVersionManifest { 35 | latest: { 36 | release: string; 37 | snapshot: string; 38 | }; 39 | versions: VersionEntry[]; 40 | } 41 | 42 | /** 43 | * Structure returned by the getInfoVersion method on success. 44 | */ 45 | export interface GetInfoVersionResult { 46 | InfoVersion: VersionEntry; 47 | json: any; // The specific version JSON fetched from Mojang 48 | version: string; // The final resolved version (e.g., "1.19" if "latest_release" was given) 49 | } 50 | 51 | /** 52 | * Structure returned by getInfoVersion if an error occurs (version not found). 53 | */ 54 | export interface GetInfoVersionError { 55 | error: true; 56 | message: string; 57 | } 58 | 59 | /** 60 | * This class retrieves Minecraft version information from Mojang's 61 | * version manifest, and optionally processes the JSON for ARM-based Linux. 62 | */ 63 | export default class Json { 64 | private readonly options: JsonOptions; 65 | 66 | constructor(options: JsonOptions) { 67 | this.options = options; 68 | } 69 | 70 | /** 71 | * Fetches the Mojang version manifest, resolves the intended version (release, snapshot, etc.), 72 | * and returns the associated JSON object for that version. 73 | * If the system is Linux ARM, it will run additional processing on the JSON. 74 | * 75 | * @returns An object containing { InfoVersion, json, version }, or an error object. 76 | */ 77 | public async GetInfoVersion(): Promise { 78 | let { version } = this.options; 79 | 80 | // Fetch the version manifest 81 | const response = await fetch( 82 | `https://launchermeta.mojang.com/mc/game/version_manifest_v2.json?_t=${new Date().toISOString()}` 83 | ); 84 | const manifest: MojangVersionManifest = await response.json(); 85 | 86 | // Resolve "latest_release"/"latest_snapshot" shorthands 87 | if (version === 'latest_release' || version === 'r' || version === 'lr') { 88 | version = manifest.latest.release; 89 | } else if (version === 'latest_snapshot' || version === 's' || version === 'ls') { 90 | version = manifest.latest.snapshot; 91 | } 92 | 93 | // Find the matching version info from the manifest 94 | const matchedVersion = manifest.versions.find((v) => v.id === version); 95 | if (!matchedVersion) { 96 | return { 97 | error: true, 98 | message: `Minecraft ${version} is not found.` 99 | }; 100 | } 101 | 102 | // Fetch the detailed version JSON from Mojang 103 | const jsonResponse = await fetch(matchedVersion.url); 104 | let versionJson = await jsonResponse.json(); 105 | 106 | // If on Linux ARM, run additional processing 107 | if (os.platform() === 'linux' && os.arch().startsWith('arm')) { 108 | versionJson = await new MinecraftNativeLinuxARM(this.options).ProcessJson(versionJson); 109 | } 110 | 111 | return { 112 | InfoVersion: matchedVersion, 113 | json: versionJson, 114 | version 115 | }; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/Minecraft/Minecraft-Libraries.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is distributed under the CC-BY-NC 4.0 license: 3 | * https://creativecommons.org/licenses/by-nc/4.0/ 4 | * 5 | * Original author: Luuxis 6 | */ 7 | 8 | import os from 'os'; 9 | import fs from 'fs'; 10 | import AdmZip from 'adm-zip'; 11 | 12 | /** 13 | * Maps Node.js platforms to Mojang's naming scheme for OS in library natives. 14 | */ 15 | const MojangLib: Record = { 16 | win32: 'windows', 17 | darwin: 'osx', 18 | linux: 'linux' 19 | }; 20 | 21 | /** 22 | * Maps Node.js architecture strings to Mojang's arch replacements (e.g., "${arch}" => 64). 23 | */ 24 | const Arch: Record = { 25 | x32: '32', 26 | x64: '64', 27 | arm: '32', 28 | arm64: '64' 29 | }; 30 | 31 | /** 32 | * Represents a single library entry in the version JSON. 33 | * Adjust or extend this interface based on your actual JSON structure. 34 | */ 35 | interface MinecraftLibrary { 36 | name?: string; 37 | rules?: Array<{ 38 | os?: { name: string }; 39 | action?: string; 40 | }>; 41 | natives?: Record; 42 | downloads: { 43 | artifact?: { 44 | sha1: string; 45 | size: number; 46 | path: string; 47 | url: string; 48 | }; 49 | classifiers?: Record< 50 | string, 51 | { 52 | sha1: string; 53 | size: number; 54 | path: string; 55 | url: string; 56 | } 57 | >; 58 | }; 59 | } 60 | 61 | /** 62 | * Represents a Minecraft version JSON structure. 63 | * Extend this interface to reflect any additional fields you use. 64 | */ 65 | interface MinecraftVersionJSON { 66 | id: string; 67 | libraries: MinecraftLibrary[]; 68 | downloads: { 69 | client: { 70 | sha1: string; 71 | size: number; 72 | url: string; 73 | }; 74 | }; 75 | [key: string]: any; 76 | } 77 | 78 | /** 79 | * Represents an item in the optional "asset" array fetched from a custom URL. 80 | */ 81 | interface CustomAssetItem { 82 | path: string; 83 | hash: string; 84 | size: number; 85 | url: string; 86 | } 87 | 88 | /** 89 | * Represents the user-provided options for the Libraries class. 90 | * Adjust as needed for your codebase. 91 | */ 92 | interface LibrariesOptions { 93 | path: string; // Base path to the Minecraft folder 94 | instance?: string; // Instance name if using multi-instances 95 | [key: string]: any; // Other fields your code might need 96 | } 97 | 98 | /** 99 | * Represents a file or library entry that needs to be downloaded and stored. 100 | */ 101 | interface LibraryDownload { 102 | sha1?: string; 103 | size?: number; 104 | path: string; 105 | type: string; 106 | url?: string; 107 | content?: string; // For CFILE entries (JSON content) 108 | } 109 | 110 | /** 111 | * This class is responsible for: 112 | * - Gathering library download info from the version JSON 113 | * - Handling custom asset entries if provided 114 | * - Extracting native libraries for the current OS into the appropriate folder 115 | */ 116 | export default class Libraries { 117 | private json!: MinecraftVersionJSON; 118 | private readonly options: LibrariesOptions; 119 | 120 | constructor(options: LibrariesOptions) { 121 | this.options = options; 122 | } 123 | 124 | /** 125 | * Processes the provided Minecraft version JSON to build a list of libraries 126 | * that need to be downloaded (including the main client jar and the version JSON itself). 127 | * 128 | * @param json A MinecraftVersionJSON object (containing libraries, downloads, etc.) 129 | * @returns An array of LibraryDownload items describing each file. 130 | */ 131 | public async Getlibraries(json: MinecraftVersionJSON): Promise { 132 | this.json = json; 133 | const libraries: LibraryDownload[] = []; 134 | 135 | for (const lib of this.json.libraries) { 136 | let artifact: { sha1: string; size: number; path: string; url: string } | undefined; 137 | let type = 'Libraries'; 138 | 139 | if (lib.natives) { 140 | // If this library has OS natives, pick the correct classifier 141 | const classifiers = lib.downloads.classifiers; 142 | let native = lib.natives[MojangLib[os.platform()]] || lib.natives[os.platform()]; 143 | type = 'Native'; 144 | if (native) { 145 | // Replace "${arch}" if present, e.g. "natives-windows-${arch}" 146 | const archReplaced = native.replace('${arch}', Arch[os.arch()] || ''); 147 | artifact = classifiers ? classifiers[archReplaced] : undefined; 148 | } else { 149 | // No valid native for the current platform 150 | continue; 151 | } 152 | } else { 153 | // If there are rules restricting OS, skip if not matching 154 | if (lib.rules && lib.rules[0]?.os?.name) { 155 | if (lib.rules[0].os.name !== MojangLib[os.platform()]) { 156 | continue; 157 | } 158 | } 159 | artifact = lib.downloads.artifact; 160 | } 161 | 162 | if (!artifact) continue; 163 | 164 | libraries.push({ 165 | sha1: artifact.sha1, 166 | size: artifact.size, 167 | path: `libraries/${artifact.path}`, 168 | type: type, 169 | url: artifact.url 170 | }); 171 | } 172 | 173 | // Add the main Minecraft client JAR to the list 174 | libraries.push({ 175 | sha1: this.json.downloads.client.sha1, 176 | size: this.json.downloads.client.size, 177 | path: `versions/${this.json.id}/${this.json.id}.jar`, 178 | type: 'Libraries', 179 | url: this.json.downloads.client.url 180 | }); 181 | 182 | // Add the JSON file for this version as a "CFILE" 183 | libraries.push({ 184 | path: `versions/${this.json.id}/${this.json.id}.json`, 185 | type: 'CFILE', 186 | content: JSON.stringify(this.json) 187 | }); 188 | 189 | return libraries; 190 | } 191 | 192 | /** 193 | * Fetches custom assets or libraries from a remote URL if provided. 194 | * This method expects the response to be an array of objects with 195 | * "path", "hash", "size", and "url". 196 | * 197 | * @param url The remote URL that returns a JSON array of CustomAssetItem 198 | * @returns An array of LibraryDownload entries describing each item 199 | */ 200 | public async GetAssetsOthers(url: string | null): Promise { 201 | if (!url) return []; 202 | 203 | const response = await fetch(url); 204 | const data: CustomAssetItem[] = await response.json(); 205 | 206 | const assets: LibraryDownload[] = []; 207 | for (const asset of data) { 208 | if (!asset.path) continue; 209 | 210 | // The 'type' is deduced from the first part of the path 211 | const fileType = asset.path.split('/')[0]; 212 | assets.push({ 213 | sha1: asset.hash, 214 | size: asset.size, 215 | type: fileType, 216 | path: this.options.instance 217 | ? `instances/${this.options.instance}/${asset.path}` 218 | : asset.path, 219 | url: asset.url 220 | }); 221 | } 222 | return assets; 223 | } 224 | 225 | /** 226 | * Extracts native libraries from the downloaded jars (those marked type="Native") 227 | * and places them into the "natives" folder under "versions//natives". 228 | * 229 | * @param bundle An array of library entries (some of which may be natives) 230 | * @returns The paths of the native files that were extracted 231 | */ 232 | public async natives(bundle: LibraryDownload[]): Promise { 233 | // Gather only the native library files 234 | const natives = bundle 235 | .filter((item) => item.type === 'Native') 236 | .map((item) => `${item.path}`); 237 | 238 | if (natives.length === 0) { 239 | return []; 240 | } 241 | 242 | // Create the natives folder if it doesn't already exist 243 | const nativesFolder = `${this.options.path}/versions/${this.json.id}/natives`.replace(/\\/g, '/'); 244 | if (!fs.existsSync(nativesFolder)) { 245 | fs.mkdirSync(nativesFolder, { recursive: true, mode: 0o777 }); 246 | } 247 | 248 | // For each native jar, extract its contents (excluding META-INF) 249 | for (const native of natives) { 250 | // Load it as a zip 251 | const zip = new AdmZip(native); 252 | const entries = zip.getEntries(); 253 | 254 | for (const entry of entries) { 255 | if (entry.entryName.startsWith('META-INF')) { 256 | continue; 257 | } 258 | 259 | // Create subdirectories if needed 260 | if (entry.isDirectory) { 261 | fs.mkdirSync(`${nativesFolder}/${entry.entryName}`, { recursive: true, mode: 0o777 }); 262 | continue; 263 | } 264 | 265 | // Write the file to the natives folder 266 | fs.writeFileSync( 267 | `${nativesFolder}/${entry.entryName}`, 268 | zip.readFile(entry), 269 | { mode: 0o777 } 270 | ); 271 | } 272 | } 273 | return natives; 274 | } 275 | } 276 | -------------------------------------------------------------------------------- /src/Minecraft/Minecraft-Loader.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is distributed under the CC-BY-NC 4.0 license: 3 | * https://creativecommons.org/licenses/by-nc/4.0/ 4 | * 5 | * Original author: Luuxis 6 | */ 7 | 8 | import { EventEmitter } from 'events'; 9 | import path from 'path'; 10 | // Note: Adjust the import path according to your actual TypeScript setup. 11 | import LoaderDownloader, { LoaderType } from '../Minecraft-Loader/index.js'; 12 | 13 | /** 14 | * Describes the loader options, including a path and other configurations. 15 | * You can expand this interface if your real code requires more fields. 16 | */ 17 | interface LoaderOptions { 18 | path: string; // Base path for the Minecraft data or installation 19 | loader: { 20 | path?: string; // Path to store loader files (e.g. Forge, Fabric) 21 | type?: string; // Type of loader (forge, fabric, etc.) 22 | build?: string; // Build number if applicable (e.g., for Forge) 23 | }; 24 | downloadFileMultiple?: number; // If your downloader can handle multiple files 25 | } 26 | 27 | /** 28 | * Represents the MinecraftLoader class options, merging LoaderOptions 29 | * with any additional fields your code might require. 30 | */ 31 | interface MinecraftLoaderOptions extends LoaderOptions { 32 | // Additional fields that might be needed by your application 33 | [key: string]: any; 34 | } 35 | 36 | /** 37 | * A simple interface describing the JSON structure returned by loader installation. 38 | * Adjust to reflect the actual fields from your loader JSON. 39 | */ 40 | interface LoaderJSON { 41 | libraries: Array<{ 42 | loader?: string; 43 | name?: string; // Or any other required fields 44 | }>; 45 | arguments?: { 46 | game?: string[]; 47 | jvm?: string[]; 48 | }; 49 | mainClass?: string; 50 | [key: string]: any; 51 | } 52 | 53 | /** 54 | * This class manages the installation and argument-building for a Minecraft 55 | * mod loader (e.g. Forge, Fabric). It wraps a `loaderDownloader` and emits 56 | * the same events for progress, extraction, patching, etc. 57 | */ 58 | export default class MinecraftLoader extends EventEmitter { 59 | private options: MinecraftLoaderOptions; 60 | private loaderPath: string; 61 | 62 | constructor(options: MinecraftLoaderOptions) { 63 | super(); 64 | this.options = options; 65 | this.loaderPath = path.join(this.options.path, this.options.loader.path); 66 | } 67 | 68 | /** 69 | * Installs the loader for a given Minecraft version using a LoaderDownloader, 70 | * returning the loader's JSON on completion. This function emits several events 71 | * for progress reporting and patch notifications. 72 | * 73 | * @param version The Minecraft version (e.g. "1.19.2") 74 | * @param javaPath Path to the Java executable used by the loader for patching 75 | * @returns A Promise that resolves to the loader's JSON configuration 76 | */ 77 | public async GetLoader(version: string, javaPath: string): Promise { 78 | const loader = new LoaderDownloader({ 79 | path: this.loaderPath, 80 | downloadFileMultiple: this.options.downloadFileMultiple, 81 | loader: { 82 | type: this.options.loader.type as LoaderType, 83 | version: version, 84 | build: this.options.loader.build, 85 | config: { 86 | javaPath, 87 | minecraftJar: `${this.options.path}/versions/${version}/${version}.jar`, 88 | minecraftJson: `${this.options.path}/versions/${version}/${version}.json` 89 | } 90 | } 91 | }); 92 | 93 | return new Promise((resolve, reject) => { 94 | loader.install(); 95 | 96 | loader.on('json', (json: LoaderJSON) => { 97 | // Inject the loader path into each library if needed 98 | const modifiedJson = json; 99 | modifiedJson.libraries = modifiedJson.libraries.map(lib => { 100 | lib.loader = this.loaderPath; 101 | return lib; 102 | }); 103 | resolve(modifiedJson); 104 | }); 105 | 106 | loader.on('extract', (extract: any) => { 107 | // Forward the "extract" event 108 | this.emit('extract', extract); 109 | }); 110 | 111 | loader.on('progress', (progress: any, size: any, element: any) => { 112 | // Forward the "progress" event 113 | this.emit('progress', progress, size, element); 114 | }); 115 | 116 | loader.on('check', (progress: any, size: any, element: any) => { 117 | // Forward the "check" event 118 | this.emit('check', progress, size, element); 119 | }); 120 | 121 | loader.on('patch', (patch: any) => { 122 | // Forward the "patch" event 123 | this.emit('patch', patch); 124 | }); 125 | 126 | loader.on('error', (err: any) => { 127 | reject(err); 128 | }); 129 | }); 130 | } 131 | 132 | /** 133 | * Builds the game and JVM arguments based on the loader's JSON data. 134 | * This may involve placeholder replacements for the main class, library directories, etc. 135 | * 136 | * @param json The loader JSON previously returned by GetLoader (or null) 137 | * @param version The targeted Minecraft version (used for placeholder substitution) 138 | * @returns An object with `game`, `jvm`, and an optional `mainClass` property 139 | */ 140 | public async GetArguments(json: LoaderJSON | null, version: string): Promise<{ 141 | game: string[]; 142 | jvm: string[]; 143 | mainClass?: string; 144 | }> { 145 | // If no loader JSON is provided, return empty arrays 146 | if (json === null) { 147 | return { game: [], jvm: [] }; 148 | } 149 | 150 | const moddedArgs = json.arguments; 151 | // If no arguments field is present, return empty arrays 152 | if (!moddedArgs) return { game: [], jvm: [] }; 153 | 154 | const args: { 155 | game?: string[]; 156 | jvm?: string[]; 157 | mainClass?: string; 158 | } = {}; 159 | 160 | if (moddedArgs.game) { 161 | args.game = moddedArgs.game; 162 | } 163 | 164 | if (moddedArgs.jvm) { 165 | // Replace placeholders in the JVM arguments 166 | args.jvm = moddedArgs.jvm.map((jvmArg) => 167 | jvmArg 168 | .replace(/\${version_name}/g, version) 169 | .replace(/\${library_directory}/g, `${this.loaderPath}/libraries`) 170 | .replace(/\${classpath_separator}/g, process.platform === 'win32' ? ';' : ':') 171 | ); 172 | } 173 | 174 | args.mainClass = json.mainClass; 175 | return { 176 | game: args.game || [], 177 | jvm: args.jvm || [], 178 | mainClass: args.mainClass 179 | }; 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /src/Minecraft/Minecraft-Lwjgl-Native.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is distributed under the CC-BY-NC 4.0 license: 3 | * https://creativecommons.org/licenses/by-nc/4.0/ 4 | * 5 | * Original author: Luuxis 6 | */ 7 | 8 | import path from 'path'; 9 | import fs from 'fs'; 10 | import os from 'os'; 11 | 12 | /** 13 | * Minimal interface describing a single library entry in the version JSON. 14 | * Adjust as needed to reflect your actual library data structure. 15 | */ 16 | interface MinecraftLibrary { 17 | name: string; 18 | // You may include other fields like 'downloads', 'natives', etc. if needed 19 | } 20 | 21 | /** 22 | * Represents the structure of a Minecraft version JSON. 23 | * You can expand this interface based on your actual usage. 24 | */ 25 | interface MinecraftVersion { 26 | libraries: MinecraftLibrary[]; 27 | // Additional fields like 'id', 'mainClass', etc. can go here 28 | } 29 | 30 | /** 31 | * Options for constructing the MinecraftLoader, if needed. 32 | * Extend or remove fields to match your actual requirements. 33 | */ 34 | interface LoaderOptions { 35 | // Add any relevant configuration fields if needed 36 | [key: string]: unknown; 37 | } 38 | 39 | /** 40 | * This class modifies the version JSON for ARM-based Linux systems, 41 | * specifically handling LWJGL library replacements for versions 2.9.x or custom LWJGL versions. 42 | */ 43 | export default class MinecraftLoader { 44 | private options: LoaderOptions; 45 | 46 | constructor(options: LoaderOptions) { 47 | this.options = options; 48 | } 49 | 50 | /** 51 | * Processes a Minecraft version JSON, removing default JInput and LWJGL entries 52 | * if needed, then injecting ARM-compatible LWJGL libraries from local JSON files. 53 | * 54 | * @param version A MinecraftVersion object containing a list of libraries 55 | * @returns The same version object, but with updated libraries for ARM-based Linux 56 | */ 57 | public async ProcessJson(version: MinecraftVersion): Promise { 58 | // Maps Node's arm architecture to the expected LWJGL naming 59 | const archMapping: Record = { 60 | arm64: 'aarch64', 61 | arm: 'aarch' 62 | }; 63 | const currentArch = os.arch(); 64 | const mappedArch = archMapping[currentArch]; 65 | 66 | // If running on a non-ARM environment, or if the mapping doesn't exist, no changes are needed 67 | if (!mappedArch) { 68 | return version; 69 | } 70 | 71 | // Path to the directory containing LWJGL JSON files for ARM 72 | const pathLWJGL = path.join(__dirname, '../../assets/LWJGL', mappedArch); 73 | 74 | // Identify the version strings for JInput and LWJGL from the existing libraries 75 | const versionJinput = version.libraries.find(lib => 76 | lib.name.startsWith('net.java.jinput:jinput-platform:') || 77 | lib.name.startsWith('net.java.jinput:jinput:') 78 | )?.name.split(':').pop(); 79 | 80 | const versionLWJGL = version.libraries.find(lib => 81 | lib.name.startsWith('org.lwjgl:lwjgl:') || 82 | lib.name.startsWith('org.lwjgl.lwjgl:lwjgl:') 83 | )?.name.split(':').pop(); 84 | 85 | // Remove all JInput-related libraries if a JInput version is found 86 | if (versionJinput) { 87 | version.libraries = version.libraries.filter(lib => !lib.name.includes('jinput')); 88 | } 89 | 90 | // Remove all LWJGL-related libraries if an LWJGL version is found 91 | if (versionLWJGL) { 92 | version.libraries = version.libraries.filter(lib => !lib.name.includes('lwjgl')); 93 | 94 | // Inject ARM-compatible LWJGL libraries 95 | let lwjglJsonFile = versionLWJGL.includes('2.9') 96 | ? '2.9.4.json' 97 | : `${versionLWJGL}.json`; 98 | 99 | const lwjglPath = path.join(pathLWJGL, lwjglJsonFile); 100 | 101 | // Read the appropriate LWJGL JSON (e.g., "2.9.4.json" or ".json") 102 | const lwjglNativesContent = fs.readFileSync(lwjglPath, 'utf-8'); 103 | const lwjglNatives = JSON.parse(lwjglNativesContent) as MinecraftVersion; 104 | 105 | // Append the ARM-compatible libraries 106 | version.libraries.push(...lwjglNatives.libraries); 107 | } 108 | 109 | return version; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/StatusServer/buffer.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is distributed under the CC-BY-NC 4.0 license: 3 | * https://creativecommons.org/licenses/by-nc/4.0/ 4 | * 5 | * Original author: Luuxis 6 | */ 7 | 8 | function CustomBuffer(existingBuffer: any = Buffer.alloc(48)) { 9 | let buffer = existingBuffer; 10 | let offset = 0; 11 | 12 | this.writeletInt = (val: any) => { 13 | while (true) { 14 | if ((val & 0xFFFFFF80) == 0) { 15 | return this.writeUByte(val); 16 | } 17 | this.writeUByte(val & 0x7F | 0x80); 18 | val = val >>> 7; 19 | } 20 | }; 21 | 22 | this.writeString = (string: any) => { 23 | this.writeletInt(string.length); 24 | if (offset + string.length >= buffer.length) Buffer.concat([buffer, new Buffer(string.length)]); 25 | buffer.write(string, offset, string.length, "UTF-8"); 26 | offset += string.length; 27 | }; 28 | 29 | this.writeUShort = (val: any) => { 30 | this.writeUByte(val >> 8); 31 | this.writeUByte(val & 0xFF); 32 | }; 33 | 34 | this.writeUByte = (val: any) => { 35 | if (offset >= buffer.length) { 36 | buffer = Buffer.concat([buffer, new Buffer(50)]); 37 | } 38 | 39 | buffer.writeUInt8(val, offset++); 40 | }; 41 | 42 | this.readletInt = function () { 43 | let val = 0; 44 | let count = 0; 45 | 46 | while (true) { 47 | let i = buffer.readUInt8(offset++); 48 | val |= (i & 0x7F) << count++ * 7; 49 | if ((i & 0x80) != 128) break 50 | } 51 | return val; 52 | }; 53 | 54 | this.readString = () => { 55 | let length = this.readletInt(); 56 | let str = buffer.toString("UTF-8", offset, offset + length); 57 | offset += length; 58 | return str; 59 | }; 60 | 61 | this.buffer = () => { 62 | return buffer.slice(0, offset); 63 | }; 64 | 65 | this.offset = () => { 66 | return offset; 67 | }; 68 | } 69 | 70 | export default CustomBuffer -------------------------------------------------------------------------------- /src/StatusServer/status.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is distributed under the CC-BY-NC 4.0 license: 3 | * https://creativecommons.org/licenses/by-nc/4.0/ 4 | * 5 | * Original author: Luuxis 6 | */ 7 | 8 | import net from 'net' 9 | import createBuffer from './buffer.js'; 10 | 11 | function ping(server: any, port: any, callback: any, timeout: any, protocol: any = '') { 12 | let start: any = new Date(); 13 | let socket = net.connect({ 14 | port: port, 15 | host: server 16 | }, () => { 17 | let handshakeBuffer = new createBuffer(); 18 | 19 | handshakeBuffer.writeletInt(0); 20 | handshakeBuffer.writeletInt(protocol); 21 | handshakeBuffer.writeString(server); 22 | handshakeBuffer.writeUShort(port); 23 | handshakeBuffer.writeletInt(1); 24 | 25 | writePCBuffer(socket, handshakeBuffer); 26 | 27 | let setModeBuffer = new createBuffer(); 28 | 29 | setModeBuffer.writeletInt(0); 30 | 31 | writePCBuffer(socket, setModeBuffer); 32 | }); 33 | 34 | socket.setTimeout(timeout, () => { 35 | if (callback) callback(new Error("Socket timed out when connecting to " + server + ":" + port), null); 36 | socket.destroy(); 37 | }); 38 | 39 | let readingBuffer = Buffer.alloc(0); 40 | 41 | socket.on('data', data => { 42 | readingBuffer = Buffer.concat([readingBuffer, data]); 43 | 44 | let buffer = new createBuffer(readingBuffer); 45 | let length: any; 46 | 47 | try { 48 | length = buffer.readletInt(); 49 | } catch (err) { 50 | return; 51 | } 52 | 53 | if (readingBuffer.length < length - buffer.offset()) return; 54 | 55 | buffer.readletInt(); 56 | 57 | try { 58 | let end: any = new Date() 59 | let json = JSON.parse(buffer.readString()); 60 | callback(null, { 61 | error: false, 62 | ms: Math.round(end - start), 63 | version: json.version.name, 64 | playersConnect: json.players.online, 65 | playersMax: json.players.max 66 | }); 67 | } catch (err) { 68 | return callback(err, null); 69 | } 70 | 71 | socket.destroy(); 72 | }); 73 | 74 | socket.once('error', err => { 75 | if (callback) callback(err, null); 76 | socket.destroy(); 77 | }); 78 | }; 79 | 80 | function writePCBuffer(client: any, buffer: any) { 81 | let length = new createBuffer(); 82 | length.writeletInt(buffer.buffer().length); 83 | client.write(Buffer.concat([length.buffer(), buffer.buffer()])); 84 | } 85 | 86 | export default class status { 87 | ip: string 88 | port: number 89 | constructor(ip = '0.0.0.0', port = 25565) { 90 | this.ip = ip 91 | this.port = port 92 | } 93 | 94 | async getStatus() { 95 | return await new Promise((resolve, reject) => { 96 | ping(this.ip, this.port, (err: any, res: any) => { 97 | if (err) return reject({ error: err }); 98 | return resolve(res); 99 | }, 3000); 100 | }) 101 | } 102 | } -------------------------------------------------------------------------------- /src/utils/Downloader.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is distributed under the CC-BY-NC 4.0 license: 3 | * https://creativecommons.org/licenses/by-nc/4.0/ 4 | * 5 | * Original author: Luuxis 6 | */ 7 | 8 | import fs from 'fs'; 9 | import { EventEmitter } from 'events'; 10 | import { fromAnyReadable } from './Index.js'; 11 | 12 | /** 13 | * Describes a single file to be downloaded by the Downloader class. 14 | */ 15 | export interface DownloadOptions { 16 | /** The URL to download from */ 17 | url: string; 18 | /** Local path (including filename) where the file will be saved */ 19 | path: string; 20 | /** The total length of the file (in bytes), if known */ 21 | length?: number; 22 | /** Local folder in which the file's path resides */ 23 | folder: string; 24 | /** Optional type descriptor, used when emitting 'progress' events */ 25 | type?: string; 26 | } 27 | 28 | /** 29 | * A class responsible for downloading single or multiple files, 30 | * emitting events for progress, speed, estimated time, and errors. 31 | */ 32 | export default class Downloader extends EventEmitter { 33 | /** 34 | * Downloads a single file from the given URL to the specified local path. 35 | * Emits "progress" events with the number of bytes downloaded and total size. 36 | * 37 | * @param url - The remote URL to download from 38 | * @param dirPath - Local folder path where the file is saved 39 | * @param fileName - Name of the file (e.g., "mod.jar") 40 | */ 41 | public async downloadFile(url: string, dirPath: string, fileName: string): Promise { 42 | if (!fs.existsSync(dirPath)) { 43 | fs.mkdirSync(dirPath, { recursive: true }); 44 | } 45 | 46 | const writer = fs.createWriteStream(`${dirPath}/${fileName}`); 47 | const response = await fetch(url); 48 | 49 | const contentLength = response.headers.get('content-length'); 50 | const totalSize = contentLength ? parseInt(contentLength, 10) : 0; 51 | 52 | let downloaded = 0; 53 | 54 | return new Promise((resolve, reject) => { 55 | const body = fromAnyReadable(response.body as any); 56 | 57 | body.on('data', (chunk: Buffer) => { 58 | downloaded += chunk.length; 59 | // Emit progress with the current number of bytes vs. total size 60 | this.emit('progress', downloaded, totalSize); 61 | writer.write(chunk); 62 | }); 63 | 64 | body.on('end', () => { 65 | writer.end(); 66 | resolve(); 67 | }); 68 | 69 | body.on('error', (err: Error) => { 70 | writer.destroy(); 71 | this.emit('error', err); 72 | reject(err); 73 | }); 74 | }); 75 | } 76 | 77 | /** 78 | * Downloads multiple files concurrently (up to the specified limit). 79 | * Emits "progress" events with cumulative bytes downloaded vs. total size, 80 | * as well as "speed" and "estimated" events for speed and ETA calculations. 81 | * 82 | * @param files - An array of DownloadOptions describing each file 83 | * @param size - The total size (in bytes) of all files to be downloaded 84 | * @param limit - The maximum number of simultaneous downloads 85 | * @param timeout - A timeout in milliseconds for each fetch request 86 | */ 87 | public async downloadFileMultiple( 88 | files: DownloadOptions[], 89 | size: number, 90 | limit: number = 1, 91 | timeout: number = 10000 92 | ): Promise { 93 | if (limit > files.length) limit = files.length; 94 | 95 | let completed = 0; // Number of downloads completed 96 | let downloaded = 0; // Cumulative bytes downloaded 97 | let queued = 0; // Index of the next file to download 98 | 99 | let start = Date.now(); 100 | let before = 0; 101 | const speeds: number[] = []; 102 | 103 | const estimated = setInterval(() => { 104 | const duration = (Date.now() - start) / 1000; 105 | const chunkDownloaded = downloaded - before; 106 | if (speeds.length >= 5) speeds.shift(); 107 | speeds.push(chunkDownloaded / duration); 108 | 109 | const avgSpeed = speeds.reduce((a, b) => a + b, 0) / speeds.length; 110 | this.emit('speed', avgSpeed); 111 | 112 | const timeRemaining = (size - downloaded) / avgSpeed; 113 | this.emit('estimated', timeRemaining); 114 | 115 | start = Date.now(); 116 | before = downloaded; 117 | }, 500); 118 | 119 | const downloadNext = async (): Promise => { 120 | if (queued >= files.length) return; 121 | 122 | const file = files[queued++]; 123 | if (!fs.existsSync(file.folder)) { 124 | fs.mkdirSync(file.folder, { recursive: true, mode: 0o777 }); 125 | } 126 | 127 | const writer = fs.createWriteStream(file.path, { flags: 'w', mode: 0o777 }); 128 | const controller = new AbortController(); 129 | const timeoutId = setTimeout(() => controller.abort(), timeout); 130 | 131 | try { 132 | const response = await fetch(file.url, { signal: controller.signal }); 133 | 134 | clearTimeout(timeoutId); 135 | 136 | const stream = fromAnyReadable(response.body as any); 137 | 138 | stream.on('data', (chunk: Buffer) => { 139 | downloaded += chunk.length; 140 | this.emit('progress', downloaded, size, file.type); 141 | writer.write(chunk); 142 | }); 143 | 144 | stream.on('end', () => { 145 | writer.end(); 146 | completed++; 147 | downloadNext(); 148 | }); 149 | 150 | stream.on('error', (err) => { 151 | writer.destroy(); 152 | this.emit('error', err); 153 | completed++; 154 | downloadNext(); 155 | }); 156 | } catch (e) { 157 | clearTimeout(timeoutId); 158 | writer.destroy(); 159 | this.emit('error', e); 160 | completed++; 161 | downloadNext(); 162 | } 163 | }; 164 | 165 | // Start "limit" concurrent downloads 166 | for (let i = 0; i < limit; i++) { 167 | downloadNext(); 168 | } 169 | 170 | // Wait until all downloads complete 171 | return new Promise((resolve) => { 172 | const interval = setInterval(() => { 173 | if (completed === files.length) { 174 | clearInterval(estimated); 175 | clearInterval(interval); 176 | resolve(); 177 | } 178 | }, 100); 179 | }); 180 | } 181 | 182 | /** 183 | * Performs a HEAD request on the given URL to check if it is valid (status=200) 184 | * and retrieves the "content-length" if available. 185 | * 186 | * @param url The URL to check 187 | * @param timeout Time in ms before the request times out 188 | * @returns An object containing { size, status } or rejects with false 189 | */ 190 | public async checkURL( 191 | url: string, 192 | timeout: number = 10000 193 | ): Promise<{ size: number; status: number } | false> { 194 | const controller = new AbortController(); 195 | const timeoutId = setTimeout(() => controller.abort(), timeout); 196 | 197 | try { 198 | const res = await fetch(url, { 199 | method: 'HEAD', 200 | signal: controller.signal 201 | }); 202 | 203 | clearTimeout(timeoutId); 204 | 205 | if (res.status === 200) { 206 | const contentLength = res.headers.get('content-length'); 207 | const size = contentLength ? parseInt(contentLength, 10) : 0; 208 | return { size, status: 200 }; 209 | } 210 | return false; 211 | } catch (e: any) { 212 | clearTimeout(timeoutId); 213 | return false; 214 | } 215 | } 216 | 217 | 218 | 219 | /** 220 | * Tries each mirror in turn, constructing an URL (mirror + baseURL). If a valid 221 | * response is found (status=200), it returns the final URL and size. Otherwise, returns false. 222 | * 223 | * @param baseURL The relative path (e.g. "group/id/artifact.jar") 224 | * @param mirrors An array of possible mirror base URLs 225 | * @returns An object { url, size, status } if found, or false if all mirrors fail 226 | */ 227 | public async checkMirror( 228 | baseURL: string, 229 | mirrors: string[] 230 | ): Promise<{ url: string; size: number; status: number } | false> { 231 | 232 | for (const mirror of mirrors) { 233 | const testURL = `${mirror}/${baseURL}`; 234 | const res = await this.checkURL(testURL); 235 | 236 | if (res !== false && res.status === 200) { 237 | return { 238 | url: testURL, 239 | size: res.size, 240 | status: 200 241 | }; 242 | } 243 | } 244 | return false; 245 | } 246 | } 247 | -------------------------------------------------------------------------------- /test/AZauth.js: -------------------------------------------------------------------------------- 1 | const prompt = require('prompt') 2 | const { AZauth, Launch } = require('../build/Index'); 3 | const launch = new Launch(); 4 | const auth = new AZauth('https://nincraft.fr'); 5 | const fs = require('fs'); 6 | 7 | let mc 8 | async function login() { 9 | console.log('set your email or username'); 10 | prompt.start(); 11 | let { email } = await prompt.get(['email']); 12 | console.log('set your password'); 13 | let { password } = await prompt.get(['password']); 14 | let azauth = await auth.login(email, password); 15 | 16 | if (azauth.A2F) { 17 | console.log('set your 2FA code'); 18 | let { code } = await prompt.get(['code']); 19 | azauth = await auth.login(email, password, code); 20 | } 21 | 22 | if (azauth.error) { 23 | console.log(azauth); 24 | process.exit(1); 25 | } 26 | return azauth; 27 | } 28 | 29 | async function main() { 30 | if (!fs.existsSync('./AZauth.json')) { 31 | mc = await login(); 32 | fs.writeFileSync('./AZauth.json', JSON.stringify(mc, null, 4)); 33 | } else { 34 | mc = JSON.parse(fs.readFileSync('./AZauth.json')); 35 | 36 | if (!mc.access_token) { 37 | mc = await login(); 38 | fs.writeFileSync('./AZauth.json', JSON.stringify(mc, null, 4)); 39 | } else { 40 | mc = await auth.verify(mc); 41 | if (mc.error) mc = await login(); 42 | fs.writeFileSync('./AZauth.json', JSON.stringify(mc, null, 4)); 43 | } 44 | } 45 | 46 | let opt = { 47 | // url: 'https://luuxis.fr/api/user/893bbc-a0bc41-da8568-ef56dd-7f2df8/files', 48 | authenticator: mc, 49 | timeout: 10000, 50 | path: './Minecraft', 51 | version: '1.16.5', 52 | detached: false, 53 | intelEnabledMac: true, 54 | downloadFileMultiple: 10, 55 | 56 | loader: { 57 | type: 'forge', 58 | build: 'latest', 59 | enable: true 60 | }, 61 | 62 | verify: false, 63 | ignored: ['loader', 'options.txt'], 64 | args: [], 65 | 66 | javaPath: null, 67 | java: true, 68 | 69 | screen: { 70 | width: null, 71 | height: null, 72 | fullscreen: null, 73 | }, 74 | 75 | memory: { 76 | min: '2G', 77 | max: '4G' 78 | } 79 | } 80 | 81 | await launch.Launch(opt); 82 | 83 | launch.on('extract', extract => { 84 | console.log(extract); 85 | }); 86 | 87 | launch.on('progress', (progress, size, element) => { 88 | console.log(`Downloading ${element} ${Math.round((progress / size) * 100)}%`); 89 | }); 90 | 91 | launch.on('check', (progress, size, element) => { 92 | console.log(`Checking ${element} ${Math.round((progress / size) * 100)}%`); 93 | }); 94 | 95 | launch.on('estimated', (time) => { 96 | let hours = Math.floor(time / 3600); 97 | let minutes = Math.floor((time - hours * 3600) / 60); 98 | let seconds = Math.floor(time - hours * 3600 - minutes * 60); 99 | console.log(`${hours}h ${minutes}m ${seconds}s`); 100 | }) 101 | 102 | launch.on('speed', (speed) => { 103 | console.log(`${(speed / 1067008).toFixed(2)} Mb/s`) 104 | }) 105 | 106 | launch.on('patch', patch => { 107 | console.log(patch); 108 | }); 109 | 110 | launch.on('data', (e) => { 111 | console.log(e); 112 | }) 113 | 114 | launch.on('close', code => { 115 | console.log(code); 116 | }); 117 | 118 | launch.on('error', err => { 119 | console.log(err); 120 | }); 121 | } 122 | 123 | main() -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | const { Launch, Microsoft } = require('minecraft-java-core'); 2 | const launcher = new Launch(); 3 | 4 | const fs = require('fs'); 5 | let mc 6 | 7 | (async () => { 8 | if (!fs.existsSync('./account.json')) { 9 | mc = await new Microsoft().getAuth(); 10 | fs.writeFileSync('./account.json', JSON.stringify(mc, null, 4)); 11 | } else { 12 | mc = JSON.parse(fs.readFileSync('./account.json')); 13 | if (!mc.refresh_token) { 14 | mc = await new Microsoft().getAuth(); 15 | fs.writeFileSync('./account.json', JSON.stringify(mc, null, 4)); 16 | } else { 17 | mc = await new Microsoft().refresh(mc); 18 | if (mc.error) mc = await new Microsoft().getAuth(); 19 | fs.writeFileSync('./account.json', JSON.stringify(mc, null, 4)); 20 | } 21 | } 22 | 23 | await launcher.Launch({ 24 | path: './minecraft', 25 | authenticator: mc, 26 | version: '1.16.5', 27 | intelEnabledMac: true, 28 | instance: "test-instance", 29 | loader: { 30 | type: 'forge', 31 | build: 'latest', 32 | enable: true 33 | }, 34 | memory: { 35 | min: '2G', 36 | max: '4G' 37 | }, 38 | java: { 39 | path: null, 40 | version: null, 41 | type: 'jre', 42 | }, 43 | }); 44 | 45 | launcher.on('progress', (progress, size) => console.log(`[DL] ${((progress / size) * 100).toFixed(2)}%`)) 46 | .on('patch', pacth => process.stdout.write(pacth)) 47 | .on('data', line => process.stdout.write(line)) 48 | .on('close', () => console.log('Game exited.')); 49 | })(); 50 | -------------------------------------------------------------------------------- /test/offline.js: -------------------------------------------------------------------------------- 1 | const { Launch, Mojang } = require('minecraft-java-core'); 2 | const launcher = new Launch(); 3 | (async () => { 4 | await launcher.Launch({ 5 | path: './minecraft', 6 | authenticator: await Mojang.login('Luuxis'), 7 | version: '1.16.5', 8 | intelEnabledMac: true, 9 | bypassOffline: true, 10 | loader: { 11 | path: './', 12 | type: 'fabric', 13 | build: 'latest', 14 | enable: true 15 | }, 16 | memory: { 17 | min: '2G', 18 | max: '4G' 19 | } 20 | }); 21 | 22 | launcher.on('progress', (progress, size) => console.log(`[DL] ${((progress / size) * 100).toFixed(2)}%`)) 23 | .on('patch', pacth => process.stdout.write(pacth)) 24 | .on('data', line => process.stdout.write(line)) 25 | .on('close', () => console.log('Game exited.')); 26 | })(); 27 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "src/**/*" 4 | ], 5 | "compilerOptions": { 6 | "sourceMap": true, 7 | "target": "ES2020", 8 | "module": "CommonJS", 9 | "lib": [ 10 | "ES2021", 11 | "DOM" 12 | ], 13 | "declaration": true, 14 | "outDir": "build", 15 | "esModuleInterop": true 16 | } 17 | } -------------------------------------------------------------------------------- /webfiles/index.php: -------------------------------------------------------------------------------- 1 | $value, "url" => $url); 27 | } 28 | 29 | include 'php/instances.php'; 30 | echo str_replace("\\", "", json_encode($instance)); 31 | exit; 32 | } 33 | 34 | echo dirToArray("instances/$instance_param"); 35 | ?> -------------------------------------------------------------------------------- /webfiles/instances/aynor/README.md: -------------------------------------------------------------------------------- 1 | # files .minecraft 2 | 3 | -------------------------------------------------------------------------------- /webfiles/instances/hypixel/README.md: -------------------------------------------------------------------------------- 1 | # files .minecraft 2 | 3 | -------------------------------------------------------------------------------- /webfiles/instances/selvania/README.md: -------------------------------------------------------------------------------- 1 | # files .minecraft 2 | 3 | -------------------------------------------------------------------------------- /webfiles/php/instances.php: -------------------------------------------------------------------------------- 1 | array( 4 | "minecraft_version" => "1.16.5", 5 | "loadder_type" => "forge", 6 | "loadder_version" => "latest" 7 | ) 8 | )); 9 | 10 | $instance['hypixel'] = array_merge($instance['hypixel'], array( 11 | "loadder" => array( 12 | "minecraft_version" => "1.8.9", 13 | "loadder_type" => "forge", 14 | "loadder_version" => "latest" 15 | ) 16 | )); 17 | 18 | $instance['selvania'] = array_merge($instance['selvania'], array( 19 | "loadder" => array( 20 | "minecraft_version" => "latest_release", 21 | "loadder_type" => "none", 22 | "loadder_version" => "latest" 23 | ) 24 | )); 25 | ?> -------------------------------------------------------------------------------- /webfiles/php/scandir.php: -------------------------------------------------------------------------------- 1 | $value) { 33 | $hash = hash_file('sha1', $dir . "/" . $value); 34 | $size = filesize($dir . "/" . $value); 35 | $path = str_replace("$dir/", "", $dir . "/" . $value); 36 | 37 | $url_req = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH); 38 | $url = "http://$_SERVER[HTTP_HOST]$url_req$dir/$path"; 39 | $res[] = array("url" => $url, "size" => $size, "hash" => $hash, "path" => $path); 40 | } 41 | return str_replace("\\", "", json_encode($res)); 42 | } 43 | ?> --------------------------------------------------------------------------------