├── .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 | [](https://creativecommons.org/licenses/by-nc/4.0/)
3 | 
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 | ?>
--------------------------------------------------------------------------------