├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── examples ├── .minecraft │ ├── .gitignore │ └── versions │ │ └── 1.19.4 │ │ └── 1.19.4.json ├── create_classpath.rs ├── launch_from_dot_minecraft.rs └── parse_version_json.rs └── src ├── classpath.rs ├── lib.rs ├── manifest.rs └── rules.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /logs -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "itoa" 7 | version = "1.0.5" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" 10 | 11 | [[package]] 12 | name = "mc_bootstrap" 13 | version = "0.1.1" 14 | dependencies = [ 15 | "serde", 16 | "serde_json", 17 | "thiserror", 18 | ] 19 | 20 | [[package]] 21 | name = "proc-macro2" 22 | version = "1.0.49" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" 25 | dependencies = [ 26 | "unicode-ident", 27 | ] 28 | 29 | [[package]] 30 | name = "quote" 31 | version = "1.0.23" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" 34 | dependencies = [ 35 | "proc-macro2", 36 | ] 37 | 38 | [[package]] 39 | name = "ryu" 40 | version = "1.0.12" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" 43 | 44 | [[package]] 45 | name = "serde" 46 | version = "1.0.152" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" 49 | dependencies = [ 50 | "serde_derive", 51 | ] 52 | 53 | [[package]] 54 | name = "serde_derive" 55 | version = "1.0.152" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" 58 | dependencies = [ 59 | "proc-macro2", 60 | "quote", 61 | "syn", 62 | ] 63 | 64 | [[package]] 65 | name = "serde_json" 66 | version = "1.0.91" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" 69 | dependencies = [ 70 | "itoa", 71 | "ryu", 72 | "serde", 73 | ] 74 | 75 | [[package]] 76 | name = "syn" 77 | version = "1.0.107" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" 80 | dependencies = [ 81 | "proc-macro2", 82 | "quote", 83 | "unicode-ident", 84 | ] 85 | 86 | [[package]] 87 | name = "thiserror" 88 | version = "1.0.38" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" 91 | dependencies = [ 92 | "thiserror-impl", 93 | ] 94 | 95 | [[package]] 96 | name = "thiserror-impl" 97 | version = "1.0.38" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" 100 | dependencies = [ 101 | "proc-macro2", 102 | "quote", 103 | "syn", 104 | ] 105 | 106 | [[package]] 107 | name = "unicode-ident" 108 | version = "1.0.6" 109 | source = "registry+https://github.com/rust-lang/crates.io-index" 110 | checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" 111 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mc_bootstrap" 3 | version = "0.1.1" 4 | edition = "2021" 5 | description = "A library for launching Minecraft." 6 | license = "MIT" 7 | repository = "https://github.com/minecraft-rs/bootstrap" 8 | include = ["/src", "/examples"] 9 | 10 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 11 | 12 | [dependencies] 13 | serde = { version = "1.0.152", features = ["derive"] } 14 | serde_json = "1.0.91" 15 | thiserror = "1.0.38" 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MC Bootstrap 2 | 3 | Launch minecraft from rust. 4 | 5 | ## Usage 6 | 7 | Launch from .minecraft folder 8 | 9 | ```rust 10 | use mc_bootstrap::{ClientAuth, ClientBootstrap, ClientSettings, ClientVersion}; 11 | 12 | fn get_mc_dir() -> PathBuf { 13 | return PathBuf::from("/home/sammwy/.minecraft"); 14 | } 15 | 16 | fn get_java_path() -> PathBuf { 17 | return PathBuf::from("/usr/lib/jvm/java-16-openjdk/bin/java"); 18 | } 19 | 20 | fn main() { 21 | let bootstrap = ClientBootstrap::new(ClientSettings { 22 | assets: get_mc_dir().join("assets"), 23 | auth: ClientAuth { 24 | username: "Sammwy_".to_string(), 25 | access_token: None, 26 | uuid: None, 27 | }, 28 | game_dir: get_mc_dir(), 29 | java_bin: get_java_path(), 30 | libraries_dir: get_mc_dir().join("libraries"), 31 | manifest_file: get_mc_dir().join("versions").join("1.19.4").join("1.19.4.json"), 32 | natives_dir: get_mc_dir().join("versions").join("1.19.4").join("natives"), 33 | version: ClientVersion { 34 | version: "1.19.4".to_string(), 35 | version_type: "release".to_string(), 36 | }, 37 | version_jar_file: get_mc_dir().join("versions").join("1.19.4").join("1.19.4.jar"), 38 | }); 39 | 40 | bootstrap.launch().unwrap(); 41 | } 42 | ``` 43 | 44 | ## Contribution 45 | 46 | Feel free to contribute to the development of the library. 47 | -------------------------------------------------------------------------------- /examples/.minecraft/.gitignore: -------------------------------------------------------------------------------- 1 | assets/ 2 | libraries/ 3 | logs/ 4 | resourcepacks/ 5 | saves/ 6 | options.txt 7 | *.png 8 | *.jpg 9 | *.dat 10 | *.jar -------------------------------------------------------------------------------- /examples/.minecraft/versions/1.19.4/1.19.4.json: -------------------------------------------------------------------------------- 1 | { 2 | "arguments": { 3 | "game": [ 4 | "--username", 5 | "${auth_player_name}", 6 | "--version", 7 | "${version_name}", 8 | "--gameDir", 9 | "${game_directory}", 10 | "--assetsDir", 11 | "${assets_root}", 12 | "--assetIndex", 13 | "${assets_index_name}", 14 | "--uuid", 15 | "${auth_uuid}", 16 | "--accessToken", 17 | "${auth_access_token}", 18 | "--clientId", 19 | "${clientid}", 20 | "--xuid", 21 | "${auth_xuid}", 22 | "--userType", 23 | "${user_type}", 24 | "--versionType", 25 | "${version_type}", 26 | { 27 | "rules": [ 28 | { 29 | "action": "allow", 30 | "features": { 31 | "is_demo_user": true 32 | } 33 | } 34 | ], 35 | "value": "--demo" 36 | }, 37 | { 38 | "rules": [ 39 | { 40 | "action": "allow", 41 | "features": { 42 | "has_custom_resolution": true 43 | } 44 | } 45 | ], 46 | "value": [ 47 | "--width", 48 | "${resolution_width}", 49 | "--height", 50 | "${resolution_height}" 51 | ] 52 | } 53 | ], 54 | "jvm": [ 55 | { 56 | "rules": [ 57 | { 58 | "action": "allow", 59 | "os": { 60 | "name": "osx" 61 | } 62 | } 63 | ], 64 | "value": [ 65 | "-XstartOnFirstThread" 66 | ] 67 | }, 68 | { 69 | "rules": [ 70 | { 71 | "action": "allow", 72 | "os": { 73 | "name": "windows" 74 | } 75 | } 76 | ], 77 | "value": "-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump" 78 | }, 79 | { 80 | "rules": [ 81 | { 82 | "action": "allow", 83 | "os": { 84 | "name": "windows", 85 | "version": "^10\\." 86 | } 87 | } 88 | ], 89 | "value": [ 90 | "-Dos.name=Windows 10", 91 | "-Dos.version=10.0" 92 | ] 93 | }, 94 | { 95 | "rules": [ 96 | { 97 | "action": "allow", 98 | "os": { 99 | "arch": "x86" 100 | } 101 | } 102 | ], 103 | "value": "-Xss1M" 104 | }, 105 | "-Djava.library.path=${natives_directory}", 106 | "-Dminecraft.launcher.brand=${launcher_name}", 107 | "-Dminecraft.launcher.version=${launcher_version}", 108 | "-cp", 109 | "${classpath}" 110 | ] 111 | }, 112 | "assetIndex": { 113 | "id": "3", 114 | "sha1": "53488acb1e0c8953f5638bd0debfd6a0aedd40c1", 115 | "size": 410193, 116 | "totalSize": 560718967, 117 | "url": "https://piston-meta.mojang.com/v1/packages/53488acb1e0c8953f5638bd0debfd6a0aedd40c1/3.json" 118 | }, 119 | "assets": "3", 120 | "complianceLevel": 1, 121 | "downloads": { 122 | "client": { 123 | "sha1": "958928a560c9167687bea0cefeb7375da1e552a8", 124 | "size": 23476620, 125 | "url": "https://piston-data.mojang.com/v1/objects/958928a560c9167687bea0cefeb7375da1e552a8/client.jar" 126 | }, 127 | "client_mappings": { 128 | "sha1": "f14771b764f943c154d3a6fcb47694477e328148", 129 | "size": 7844191, 130 | "url": "https://piston-data.mojang.com/v1/objects/f14771b764f943c154d3a6fcb47694477e328148/client.txt" 131 | }, 132 | "server": { 133 | "sha1": "8f3112a1049751cc472ec13e397eade5336ca7ae", 134 | "size": 47515675, 135 | "url": "https://piston-data.mojang.com/v1/objects/8f3112a1049751cc472ec13e397eade5336ca7ae/server.jar" 136 | }, 137 | "server_mappings": { 138 | "sha1": "73c8bb982e420b33aad9632b482608c5c33e2d13", 139 | "size": 6043763, 140 | "url": "https://piston-data.mojang.com/v1/objects/73c8bb982e420b33aad9632b482608c5c33e2d13/server.txt" 141 | } 142 | }, 143 | "id": "1.19.4", 144 | "javaVersion": { 145 | "component": "java-runtime-gamma", 146 | "majorVersion": 17 147 | }, 148 | "libraries": [ 149 | { 150 | "downloads": { 151 | "artifact": { 152 | "path": "ca/weblite/java-objc-bridge/1.1/java-objc-bridge-1.1.jar", 153 | "sha1": "1227f9e0666314f9de41477e3ec277e542ed7f7b", 154 | "size": 1330045, 155 | "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.1/java-objc-bridge-1.1.jar" 156 | } 157 | }, 158 | "name": "ca.weblite:java-objc-bridge:1.1", 159 | "rules": [ 160 | { 161 | "action": "allow", 162 | "os": { 163 | "name": "osx" 164 | } 165 | } 166 | ] 167 | }, 168 | { 169 | "downloads": { 170 | "artifact": { 171 | "path": "com/github/oshi/oshi-core/6.2.2/oshi-core-6.2.2.jar", 172 | "sha1": "54f5efc19bca95d709d9a37d19ffcbba3d21c1a6", 173 | "size": 947865, 174 | "url": "https://libraries.minecraft.net/com/github/oshi/oshi-core/6.2.2/oshi-core-6.2.2.jar" 175 | } 176 | }, 177 | "name": "com.github.oshi:oshi-core:6.2.2" 178 | }, 179 | { 180 | "downloads": { 181 | "artifact": { 182 | "path": "com/google/code/gson/gson/2.10/gson-2.10.jar", 183 | "sha1": "dd9b193aef96e973d5a11ab13cd17430c2e4306b", 184 | "size": 286235, 185 | "url": "https://libraries.minecraft.net/com/google/code/gson/gson/2.10/gson-2.10.jar" 186 | } 187 | }, 188 | "name": "com.google.code.gson:gson:2.10" 189 | }, 190 | { 191 | "downloads": { 192 | "artifact": { 193 | "path": "com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar", 194 | "sha1": "1dcf1de382a0bf95a3d8b0849546c88bac1292c9", 195 | "size": 4617, 196 | "url": "https://libraries.minecraft.net/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar" 197 | } 198 | }, 199 | "name": "com.google.guava:failureaccess:1.0.1" 200 | }, 201 | { 202 | "downloads": { 203 | "artifact": { 204 | "path": "com/google/guava/guava/31.1-jre/guava-31.1-jre.jar", 205 | "sha1": "60458f877d055d0c9114d9e1a2efb737b4bc282c", 206 | "size": 2959479, 207 | "url": "https://libraries.minecraft.net/com/google/guava/guava/31.1-jre/guava-31.1-jre.jar" 208 | } 209 | }, 210 | "name": "com.google.guava:guava:31.1-jre" 211 | }, 212 | { 213 | "downloads": { 214 | "artifact": { 215 | "path": "com/ibm/icu/icu4j/71.1/icu4j-71.1.jar", 216 | "sha1": "9e7d3304c23f9ba5cb71915f7cce23231a57a445", 217 | "size": 13963762, 218 | "url": "https://libraries.minecraft.net/com/ibm/icu/icu4j/71.1/icu4j-71.1.jar" 219 | } 220 | }, 221 | "name": "com.ibm.icu:icu4j:71.1" 222 | }, 223 | { 224 | "downloads": { 225 | "artifact": { 226 | "path": "com/mojang/authlib/3.18.38/authlib-3.18.38.jar", 227 | "sha1": "016106b26bce62bda55bab42785b999e44d77ecb", 228 | "size": 118354, 229 | "url": "https://libraries.minecraft.net/com/mojang/authlib/3.18.38/authlib-3.18.38.jar" 230 | } 231 | }, 232 | "name": "com.mojang:authlib:3.18.38" 233 | }, 234 | { 235 | "downloads": { 236 | "artifact": { 237 | "path": "com/mojang/blocklist/1.0.10/blocklist-1.0.10.jar", 238 | "sha1": "5c685c5ffa94c4cd39496c7184c1d122e515ecef", 239 | "size": 964, 240 | "url": "https://libraries.minecraft.net/com/mojang/blocklist/1.0.10/blocklist-1.0.10.jar" 241 | } 242 | }, 243 | "name": "com.mojang:blocklist:1.0.10" 244 | }, 245 | { 246 | "downloads": { 247 | "artifact": { 248 | "path": "com/mojang/brigadier/1.0.18/brigadier-1.0.18.jar", 249 | "sha1": "c1ef1234282716483c92183f49bef47b1a89bfa9", 250 | "size": 77116, 251 | "url": "https://libraries.minecraft.net/com/mojang/brigadier/1.0.18/brigadier-1.0.18.jar" 252 | } 253 | }, 254 | "name": "com.mojang:brigadier:1.0.18" 255 | }, 256 | { 257 | "downloads": { 258 | "artifact": { 259 | "path": "com/mojang/datafixerupper/6.0.6/datafixerupper-6.0.6.jar", 260 | "sha1": "e38e20946530646e866db03b2b192883d0ea6e84", 261 | "size": 689986, 262 | "url": "https://libraries.minecraft.net/com/mojang/datafixerupper/6.0.6/datafixerupper-6.0.6.jar" 263 | } 264 | }, 265 | "name": "com.mojang:datafixerupper:6.0.6" 266 | }, 267 | { 268 | "downloads": { 269 | "artifact": { 270 | "path": "com/mojang/logging/1.1.1/logging-1.1.1.jar", 271 | "sha1": "832b8e6674a9b325a5175a3a6267dfaf34c85139", 272 | "size": 15343, 273 | "url": "https://libraries.minecraft.net/com/mojang/logging/1.1.1/logging-1.1.1.jar" 274 | } 275 | }, 276 | "name": "com.mojang:logging:1.1.1" 277 | }, 278 | { 279 | "downloads": { 280 | "artifact": { 281 | "path": "com/mojang/patchy/2.2.10/patchy-2.2.10.jar", 282 | "sha1": "da05971b07cbb379d002cf7eaec6a2048211fefc", 283 | "size": 4439, 284 | "url": "https://libraries.minecraft.net/com/mojang/patchy/2.2.10/patchy-2.2.10.jar" 285 | } 286 | }, 287 | "name": "com.mojang:patchy:2.2.10" 288 | }, 289 | { 290 | "downloads": { 291 | "artifact": { 292 | "path": "com/mojang/text2speech/1.16.7/text2speech-1.16.7.jar", 293 | "sha1": "ee4095669061d1fe4bce5fea23d69d1520bc2d58", 294 | "size": 12279, 295 | "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.16.7/text2speech-1.16.7.jar" 296 | } 297 | }, 298 | "name": "com.mojang:text2speech:1.16.7" 299 | }, 300 | { 301 | "downloads": { 302 | "artifact": { 303 | "path": "commons-codec/commons-codec/1.15/commons-codec-1.15.jar", 304 | "sha1": "49d94806b6e3dc933dacbd8acb0fdbab8ebd1e5d", 305 | "size": 353793, 306 | "url": "https://libraries.minecraft.net/commons-codec/commons-codec/1.15/commons-codec-1.15.jar" 307 | } 308 | }, 309 | "name": "commons-codec:commons-codec:1.15" 310 | }, 311 | { 312 | "downloads": { 313 | "artifact": { 314 | "path": "commons-io/commons-io/2.11.0/commons-io-2.11.0.jar", 315 | "sha1": "a2503f302b11ebde7ebc3df41daebe0e4eea3689", 316 | "size": 327135, 317 | "url": "https://libraries.minecraft.net/commons-io/commons-io/2.11.0/commons-io-2.11.0.jar" 318 | } 319 | }, 320 | "name": "commons-io:commons-io:2.11.0" 321 | }, 322 | { 323 | "downloads": { 324 | "artifact": { 325 | "path": "commons-logging/commons-logging/1.2/commons-logging-1.2.jar", 326 | "sha1": "4bfc12adfe4842bf07b657f0369c4cb522955686", 327 | "size": 61829, 328 | "url": "https://libraries.minecraft.net/commons-logging/commons-logging/1.2/commons-logging-1.2.jar" 329 | } 330 | }, 331 | "name": "commons-logging:commons-logging:1.2" 332 | }, 333 | { 334 | "downloads": { 335 | "artifact": { 336 | "path": "io/netty/netty-buffer/4.1.82.Final/netty-buffer-4.1.82.Final.jar", 337 | "sha1": "a544270cf1ae8b8077082f5036436a9a9971ea71", 338 | "size": 304664, 339 | "url": "https://libraries.minecraft.net/io/netty/netty-buffer/4.1.82.Final/netty-buffer-4.1.82.Final.jar" 340 | } 341 | }, 342 | "name": "io.netty:netty-buffer:4.1.82.Final" 343 | }, 344 | { 345 | "downloads": { 346 | "artifact": { 347 | "path": "io/netty/netty-codec/4.1.82.Final/netty-codec-4.1.82.Final.jar", 348 | "sha1": "b77200379acb345a9ffdece1c605e591ac3e4e0a", 349 | "size": 339155, 350 | "url": "https://libraries.minecraft.net/io/netty/netty-codec/4.1.82.Final/netty-codec-4.1.82.Final.jar" 351 | } 352 | }, 353 | "name": "io.netty:netty-codec:4.1.82.Final" 354 | }, 355 | { 356 | "downloads": { 357 | "artifact": { 358 | "path": "io/netty/netty-common/4.1.82.Final/netty-common-4.1.82.Final.jar", 359 | "sha1": "022d148e85c3f5ebdacc0ce1f5aabb1d420f73f3", 360 | "size": 653880, 361 | "url": "https://libraries.minecraft.net/io/netty/netty-common/4.1.82.Final/netty-common-4.1.82.Final.jar" 362 | } 363 | }, 364 | "name": "io.netty:netty-common:4.1.82.Final" 365 | }, 366 | { 367 | "downloads": { 368 | "artifact": { 369 | "path": "io/netty/netty-handler/4.1.82.Final/netty-handler-4.1.82.Final.jar", 370 | "sha1": "644041d1fa96a5d3130a29e8978630d716d76e38", 371 | "size": 538569, 372 | "url": "https://libraries.minecraft.net/io/netty/netty-handler/4.1.82.Final/netty-handler-4.1.82.Final.jar" 373 | } 374 | }, 375 | "name": "io.netty:netty-handler:4.1.82.Final" 376 | }, 377 | { 378 | "downloads": { 379 | "artifact": { 380 | "path": "io/netty/netty-resolver/4.1.82.Final/netty-resolver-4.1.82.Final.jar", 381 | "sha1": "38f665ae8dcd29032eea31245ba7806bed2e0fa8", 382 | "size": 37776, 383 | "url": "https://libraries.minecraft.net/io/netty/netty-resolver/4.1.82.Final/netty-resolver-4.1.82.Final.jar" 384 | } 385 | }, 386 | "name": "io.netty:netty-resolver:4.1.82.Final" 387 | }, 388 | { 389 | "downloads": { 390 | "artifact": { 391 | "path": "io/netty/netty-transport-classes-epoll/4.1.82.Final/netty-transport-classes-epoll-4.1.82.Final.jar", 392 | "sha1": "e7c7dd18deac93105797f30057c912651ea76521", 393 | "size": 142066, 394 | "url": "https://libraries.minecraft.net/io/netty/netty-transport-classes-epoll/4.1.82.Final/netty-transport-classes-epoll-4.1.82.Final.jar" 395 | } 396 | }, 397 | "name": "io.netty:netty-transport-classes-epoll:4.1.82.Final" 398 | }, 399 | { 400 | "downloads": { 401 | "artifact": { 402 | "path": "io/netty/netty-transport-native-epoll/4.1.82.Final/netty-transport-native-epoll-4.1.82.Final-linux-aarch_64.jar", 403 | "sha1": "476409d6255001ca53a55f65b01c13822f8dc93a", 404 | "size": 39489, 405 | "url": "https://libraries.minecraft.net/io/netty/netty-transport-native-epoll/4.1.82.Final/netty-transport-native-epoll-4.1.82.Final-linux-aarch_64.jar" 406 | } 407 | }, 408 | "name": "io.netty:netty-transport-native-epoll:4.1.82.Final:linux-aarch_64", 409 | "rules": [ 410 | { 411 | "action": "allow", 412 | "os": { 413 | "name": "linux" 414 | } 415 | } 416 | ] 417 | }, 418 | { 419 | "downloads": { 420 | "artifact": { 421 | "path": "io/netty/netty-transport-native-epoll/4.1.82.Final/netty-transport-native-epoll-4.1.82.Final-linux-x86_64.jar", 422 | "sha1": "c7350a71920f3ae9142945e25fed4846cce53374", 423 | "size": 37922, 424 | "url": "https://libraries.minecraft.net/io/netty/netty-transport-native-epoll/4.1.82.Final/netty-transport-native-epoll-4.1.82.Final-linux-x86_64.jar" 425 | } 426 | }, 427 | "name": "io.netty:netty-transport-native-epoll:4.1.82.Final:linux-x86_64", 428 | "rules": [ 429 | { 430 | "action": "allow", 431 | "os": { 432 | "name": "linux" 433 | } 434 | } 435 | ] 436 | }, 437 | { 438 | "downloads": { 439 | "artifact": { 440 | "path": "io/netty/netty-transport-native-unix-common/4.1.82.Final/netty-transport-native-unix-common-4.1.82.Final.jar", 441 | "sha1": "3e895b35ca1b8a0eca56cacff4c2dde5d2c6abce", 442 | "size": 43684, 443 | "url": "https://libraries.minecraft.net/io/netty/netty-transport-native-unix-common/4.1.82.Final/netty-transport-native-unix-common-4.1.82.Final.jar" 444 | } 445 | }, 446 | "name": "io.netty:netty-transport-native-unix-common:4.1.82.Final" 447 | }, 448 | { 449 | "downloads": { 450 | "artifact": { 451 | "path": "io/netty/netty-transport/4.1.82.Final/netty-transport-4.1.82.Final.jar", 452 | "sha1": "e431a218d91acb6476ccad5f5aafde50aa3945ca", 453 | "size": 485752, 454 | "url": "https://libraries.minecraft.net/io/netty/netty-transport/4.1.82.Final/netty-transport-4.1.82.Final.jar" 455 | } 456 | }, 457 | "name": "io.netty:netty-transport:4.1.82.Final" 458 | }, 459 | { 460 | "downloads": { 461 | "artifact": { 462 | "path": "it/unimi/dsi/fastutil/8.5.9/fastutil-8.5.9.jar", 463 | "sha1": "bb7ea75ecdb216654237830b3a96d87ad91f8cc5", 464 | "size": 23376043, 465 | "url": "https://libraries.minecraft.net/it/unimi/dsi/fastutil/8.5.9/fastutil-8.5.9.jar" 466 | } 467 | }, 468 | "name": "it.unimi.dsi:fastutil:8.5.9" 469 | }, 470 | { 471 | "downloads": { 472 | "artifact": { 473 | "path": "net/java/dev/jna/jna-platform/5.12.1/jna-platform-5.12.1.jar", 474 | "sha1": "097406a297c852f4a41e688a176ec675f72e8329", 475 | "size": 1356627, 476 | "url": "https://libraries.minecraft.net/net/java/dev/jna/jna-platform/5.12.1/jna-platform-5.12.1.jar" 477 | } 478 | }, 479 | "name": "net.java.dev.jna:jna-platform:5.12.1" 480 | }, 481 | { 482 | "downloads": { 483 | "artifact": { 484 | "path": "net/java/dev/jna/jna/5.12.1/jna-5.12.1.jar", 485 | "sha1": "b1e93a735caea94f503e95e6fe79bf9cdc1e985d", 486 | "size": 1866196, 487 | "url": "https://libraries.minecraft.net/net/java/dev/jna/jna/5.12.1/jna-5.12.1.jar" 488 | } 489 | }, 490 | "name": "net.java.dev.jna:jna:5.12.1" 491 | }, 492 | { 493 | "downloads": { 494 | "artifact": { 495 | "path": "net/sf/jopt-simple/jopt-simple/5.0.4/jopt-simple-5.0.4.jar", 496 | "sha1": "4fdac2fbe92dfad86aa6e9301736f6b4342a3f5c", 497 | "size": 78146, 498 | "url": "https://libraries.minecraft.net/net/sf/jopt-simple/jopt-simple/5.0.4/jopt-simple-5.0.4.jar" 499 | } 500 | }, 501 | "name": "net.sf.jopt-simple:jopt-simple:5.0.4" 502 | }, 503 | { 504 | "downloads": { 505 | "artifact": { 506 | "path": "org/apache/commons/commons-compress/1.21/commons-compress-1.21.jar", 507 | "sha1": "4ec95b60d4e86b5c95a0e919cb172a0af98011ef", 508 | "size": 1018316, 509 | "url": "https://libraries.minecraft.net/org/apache/commons/commons-compress/1.21/commons-compress-1.21.jar" 510 | } 511 | }, 512 | "name": "org.apache.commons:commons-compress:1.21" 513 | }, 514 | { 515 | "downloads": { 516 | "artifact": { 517 | "path": "org/apache/commons/commons-lang3/3.12.0/commons-lang3-3.12.0.jar", 518 | "sha1": "c6842c86792ff03b9f1d1fe2aab8dc23aa6c6f0e", 519 | "size": 587402, 520 | "url": "https://libraries.minecraft.net/org/apache/commons/commons-lang3/3.12.0/commons-lang3-3.12.0.jar" 521 | } 522 | }, 523 | "name": "org.apache.commons:commons-lang3:3.12.0" 524 | }, 525 | { 526 | "downloads": { 527 | "artifact": { 528 | "path": "org/apache/httpcomponents/httpclient/4.5.13/httpclient-4.5.13.jar", 529 | "sha1": "e5f6cae5ca7ecaac1ec2827a9e2d65ae2869cada", 530 | "size": 780321, 531 | "url": "https://libraries.minecraft.net/org/apache/httpcomponents/httpclient/4.5.13/httpclient-4.5.13.jar" 532 | } 533 | }, 534 | "name": "org.apache.httpcomponents:httpclient:4.5.13" 535 | }, 536 | { 537 | "downloads": { 538 | "artifact": { 539 | "path": "org/apache/httpcomponents/httpcore/4.4.15/httpcore-4.4.15.jar", 540 | "sha1": "7f2e0c573eaa7a74bac2e89b359e1f73d92a0a1d", 541 | "size": 328324, 542 | "url": "https://libraries.minecraft.net/org/apache/httpcomponents/httpcore/4.4.15/httpcore-4.4.15.jar" 543 | } 544 | }, 545 | "name": "org.apache.httpcomponents:httpcore:4.4.15" 546 | }, 547 | { 548 | "downloads": { 549 | "artifact": { 550 | "path": "org/apache/logging/log4j/log4j-api/2.19.0/log4j-api-2.19.0.jar", 551 | "sha1": "ea1b37f38c327596b216542bc636cfdc0b8036fa", 552 | "size": 317566, 553 | "url": "https://libraries.minecraft.net/org/apache/logging/log4j/log4j-api/2.19.0/log4j-api-2.19.0.jar" 554 | } 555 | }, 556 | "name": "org.apache.logging.log4j:log4j-api:2.19.0" 557 | }, 558 | { 559 | "downloads": { 560 | "artifact": { 561 | "path": "org/apache/logging/log4j/log4j-core/2.19.0/log4j-core-2.19.0.jar", 562 | "sha1": "3b6eeb4de4c49c0fe38a4ee27188ff5fee44d0bb", 563 | "size": 1864386, 564 | "url": "https://libraries.minecraft.net/org/apache/logging/log4j/log4j-core/2.19.0/log4j-core-2.19.0.jar" 565 | } 566 | }, 567 | "name": "org.apache.logging.log4j:log4j-core:2.19.0" 568 | }, 569 | { 570 | "downloads": { 571 | "artifact": { 572 | "path": "org/apache/logging/log4j/log4j-slf4j2-impl/2.19.0/log4j-slf4j2-impl-2.19.0.jar", 573 | "sha1": "5c04bfdd63ce9dceb2e284b81e96b6a70010ee10", 574 | "size": 27721, 575 | "url": "https://libraries.minecraft.net/org/apache/logging/log4j/log4j-slf4j2-impl/2.19.0/log4j-slf4j2-impl-2.19.0.jar" 576 | } 577 | }, 578 | "name": "org.apache.logging.log4j:log4j-slf4j2-impl:2.19.0" 579 | }, 580 | { 581 | "downloads": { 582 | "artifact": { 583 | "path": "org/joml/joml/1.10.5/joml-1.10.5.jar", 584 | "sha1": "22566d58af70ad3d72308bab63b8339906deb649", 585 | "size": 712082, 586 | "url": "https://libraries.minecraft.net/org/joml/joml/1.10.5/joml-1.10.5.jar" 587 | } 588 | }, 589 | "name": "org.joml:joml:1.10.5" 590 | }, 591 | { 592 | "downloads": { 593 | "artifact": { 594 | "path": "org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1.jar", 595 | "sha1": "cbac1b8d30cb4795149c1ef540f912671a8616d0", 596 | "size": 128801, 597 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1.jar" 598 | } 599 | }, 600 | "name": "org.lwjgl:lwjgl-glfw:3.3.1" 601 | }, 602 | { 603 | "downloads": { 604 | "artifact": { 605 | "path": "org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-linux.jar", 606 | "sha1": "81716978214ecbda15050ca394b06ef61501a49e", 607 | "size": 119817, 608 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-linux.jar" 609 | } 610 | }, 611 | "name": "org.lwjgl:lwjgl-glfw:3.3.1:natives-linux", 612 | "rules": [ 613 | { 614 | "action": "allow", 615 | "os": { 616 | "name": "linux" 617 | } 618 | } 619 | ] 620 | }, 621 | { 622 | "downloads": { 623 | "artifact": { 624 | "path": "org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-macos.jar", 625 | "sha1": "9ec4ce1fc8c85fdef03ef4ff2aace6f5775fb280", 626 | "size": 131655, 627 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-macos.jar" 628 | } 629 | }, 630 | "name": "org.lwjgl:lwjgl-glfw:3.3.1:natives-macos", 631 | "rules": [ 632 | { 633 | "action": "allow", 634 | "os": { 635 | "name": "osx" 636 | } 637 | } 638 | ] 639 | }, 640 | { 641 | "downloads": { 642 | "artifact": { 643 | "path": "org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-macos-arm64.jar", 644 | "sha1": "cac0d3f712a3da7641fa174735a5f315de7ffe0a", 645 | "size": 129077, 646 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-macos-arm64.jar" 647 | } 648 | }, 649 | "name": "org.lwjgl:lwjgl-glfw:3.3.1:natives-macos-arm64", 650 | "rules": [ 651 | { 652 | "action": "allow", 653 | "os": { 654 | "name": "osx" 655 | } 656 | } 657 | ] 658 | }, 659 | { 660 | "downloads": { 661 | "artifact": { 662 | "path": "org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-windows.jar", 663 | "sha1": "ed892f945cf7e79c8756796f32d00fa4ceaf573b", 664 | "size": 145512, 665 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-windows.jar" 666 | } 667 | }, 668 | "name": "org.lwjgl:lwjgl-glfw:3.3.1:natives-windows", 669 | "rules": [ 670 | { 671 | "action": "allow", 672 | "os": { 673 | "name": "windows" 674 | } 675 | } 676 | ] 677 | }, 678 | { 679 | "downloads": { 680 | "artifact": { 681 | "path": "org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-windows-arm64.jar", 682 | "sha1": "beda65ee503443e60aa196d58ed31f8d001dc22a", 683 | "size": 123808, 684 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-windows-arm64.jar" 685 | } 686 | }, 687 | "name": "org.lwjgl:lwjgl-glfw:3.3.1:natives-windows-arm64", 688 | "rules": [ 689 | { 690 | "action": "allow", 691 | "os": { 692 | "name": "windows" 693 | } 694 | } 695 | ] 696 | }, 697 | { 698 | "downloads": { 699 | "artifact": { 700 | "path": "org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-windows-x86.jar", 701 | "sha1": "b997e3391d6ce8f05487e7335d95c606043884a1", 702 | "size": 139251, 703 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-windows-x86.jar" 704 | } 705 | }, 706 | "name": "org.lwjgl:lwjgl-glfw:3.3.1:natives-windows-x86", 707 | "rules": [ 708 | { 709 | "action": "allow", 710 | "os": { 711 | "name": "windows" 712 | } 713 | } 714 | ] 715 | }, 716 | { 717 | "downloads": { 718 | "artifact": { 719 | "path": "org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1.jar", 720 | "sha1": "a817bcf213db49f710603677457567c37d53e103", 721 | "size": 36601, 722 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1.jar" 723 | } 724 | }, 725 | "name": "org.lwjgl:lwjgl-jemalloc:3.3.1" 726 | }, 727 | { 728 | "downloads": { 729 | "artifact": { 730 | "path": "org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-linux.jar", 731 | "sha1": "33dbb017b6ed6b25f993ad9d56741a49e7937718", 732 | "size": 166524, 733 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-linux.jar" 734 | } 735 | }, 736 | "name": "org.lwjgl:lwjgl-jemalloc:3.3.1:natives-linux", 737 | "rules": [ 738 | { 739 | "action": "allow", 740 | "os": { 741 | "name": "linux" 742 | } 743 | } 744 | ] 745 | }, 746 | { 747 | "downloads": { 748 | "artifact": { 749 | "path": "org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-macos.jar", 750 | "sha1": "56424dc8db3cfb8e7b594aa6d59a4f4387b7f544", 751 | "size": 117480, 752 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-macos.jar" 753 | } 754 | }, 755 | "name": "org.lwjgl:lwjgl-jemalloc:3.3.1:natives-macos", 756 | "rules": [ 757 | { 758 | "action": "allow", 759 | "os": { 760 | "name": "osx" 761 | } 762 | } 763 | ] 764 | }, 765 | { 766 | "downloads": { 767 | "artifact": { 768 | "path": "org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-macos-arm64.jar", 769 | "sha1": "e577b87d8ad2ade361aaea2fcf226c660b15dee8", 770 | "size": 103475, 771 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-macos-arm64.jar" 772 | } 773 | }, 774 | "name": "org.lwjgl:lwjgl-jemalloc:3.3.1:natives-macos-arm64", 775 | "rules": [ 776 | { 777 | "action": "allow", 778 | "os": { 779 | "name": "osx" 780 | } 781 | } 782 | ] 783 | }, 784 | { 785 | "downloads": { 786 | "artifact": { 787 | "path": "org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-windows.jar", 788 | "sha1": "948a89b76a16aa324b046ae9308891216ffce5f9", 789 | "size": 135585, 790 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-windows.jar" 791 | } 792 | }, 793 | "name": "org.lwjgl:lwjgl-jemalloc:3.3.1:natives-windows", 794 | "rules": [ 795 | { 796 | "action": "allow", 797 | "os": { 798 | "name": "windows" 799 | } 800 | } 801 | ] 802 | }, 803 | { 804 | "downloads": { 805 | "artifact": { 806 | "path": "org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-windows-arm64.jar", 807 | "sha1": "cae85c4edb219c88b6a0c26a87955ad98dc9519d", 808 | "size": 114250, 809 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-windows-arm64.jar" 810 | } 811 | }, 812 | "name": "org.lwjgl:lwjgl-jemalloc:3.3.1:natives-windows-arm64", 813 | "rules": [ 814 | { 815 | "action": "allow", 816 | "os": { 817 | "name": "windows" 818 | } 819 | } 820 | ] 821 | }, 822 | { 823 | "downloads": { 824 | "artifact": { 825 | "path": "org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-windows-x86.jar", 826 | "sha1": "fb476c8ec110e1c137ad3ce8a7f7bfe6b11c6324", 827 | "size": 110405, 828 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-windows-x86.jar" 829 | } 830 | }, 831 | "name": "org.lwjgl:lwjgl-jemalloc:3.3.1:natives-windows-x86", 832 | "rules": [ 833 | { 834 | "action": "allow", 835 | "os": { 836 | "name": "windows" 837 | } 838 | } 839 | ] 840 | }, 841 | { 842 | "downloads": { 843 | "artifact": { 844 | "path": "org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1.jar", 845 | "sha1": "2623a6b8ae1dfcd880738656a9f0243d2e6840bd", 846 | "size": 88237, 847 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1.jar" 848 | } 849 | }, 850 | "name": "org.lwjgl:lwjgl-openal:3.3.1" 851 | }, 852 | { 853 | "downloads": { 854 | "artifact": { 855 | "path": "org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-linux.jar", 856 | "sha1": "f906b6439f6daa66001182ea7727e3467a93681b", 857 | "size": 476825, 858 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-linux.jar" 859 | } 860 | }, 861 | "name": "org.lwjgl:lwjgl-openal:3.3.1:natives-linux", 862 | "rules": [ 863 | { 864 | "action": "allow", 865 | "os": { 866 | "name": "linux" 867 | } 868 | } 869 | ] 870 | }, 871 | { 872 | "downloads": { 873 | "artifact": { 874 | "path": "org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-macos.jar", 875 | "sha1": "3a57b8911835fb58b5e558d0ca0d28157e263d45", 876 | "size": 397196, 877 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-macos.jar" 878 | } 879 | }, 880 | "name": "org.lwjgl:lwjgl-openal:3.3.1:natives-macos", 881 | "rules": [ 882 | { 883 | "action": "allow", 884 | "os": { 885 | "name": "osx" 886 | } 887 | } 888 | ] 889 | }, 890 | { 891 | "downloads": { 892 | "artifact": { 893 | "path": "org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-macos-arm64.jar", 894 | "sha1": "23d55e7490b57495320f6c9e1936d78fd72c4ef8", 895 | "size": 346125, 896 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-macos-arm64.jar" 897 | } 898 | }, 899 | "name": "org.lwjgl:lwjgl-openal:3.3.1:natives-macos-arm64", 900 | "rules": [ 901 | { 902 | "action": "allow", 903 | "os": { 904 | "name": "osx" 905 | } 906 | } 907 | ] 908 | }, 909 | { 910 | "downloads": { 911 | "artifact": { 912 | "path": "org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-windows.jar", 913 | "sha1": "30a474d0e57193d7bc128849a3ab66bc9316fdb1", 914 | "size": 576872, 915 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-windows.jar" 916 | } 917 | }, 918 | "name": "org.lwjgl:lwjgl-openal:3.3.1:natives-windows", 919 | "rules": [ 920 | { 921 | "action": "allow", 922 | "os": { 923 | "name": "windows" 924 | } 925 | } 926 | ] 927 | }, 928 | { 929 | "downloads": { 930 | "artifact": { 931 | "path": "org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-windows-arm64.jar", 932 | "sha1": "40d65f1a7368a2aa47336f9cb69f5a190cf9975a", 933 | "size": 505234, 934 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-windows-arm64.jar" 935 | } 936 | }, 937 | "name": "org.lwjgl:lwjgl-openal:3.3.1:natives-windows-arm64", 938 | "rules": [ 939 | { 940 | "action": "allow", 941 | "os": { 942 | "name": "windows" 943 | } 944 | } 945 | ] 946 | }, 947 | { 948 | "downloads": { 949 | "artifact": { 950 | "path": "org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-windows-x86.jar", 951 | "sha1": "888349f7b1be6fbae58bf8edfb9ef12def04c4e3", 952 | "size": 520313, 953 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-windows-x86.jar" 954 | } 955 | }, 956 | "name": "org.lwjgl:lwjgl-openal:3.3.1:natives-windows-x86", 957 | "rules": [ 958 | { 959 | "action": "allow", 960 | "os": { 961 | "name": "windows" 962 | } 963 | } 964 | ] 965 | }, 966 | { 967 | "downloads": { 968 | "artifact": { 969 | "path": "org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1.jar", 970 | "sha1": "831a5533a21a5f4f81bbc51bb13e9899319b5411", 971 | "size": 921563, 972 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1.jar" 973 | } 974 | }, 975 | "name": "org.lwjgl:lwjgl-opengl:3.3.1" 976 | }, 977 | { 978 | "downloads": { 979 | "artifact": { 980 | "path": "org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-linux.jar", 981 | "sha1": "ab9ab6fde3743e3550fa5d46d785ecb45b047d99", 982 | "size": 79125, 983 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-linux.jar" 984 | } 985 | }, 986 | "name": "org.lwjgl:lwjgl-opengl:3.3.1:natives-linux", 987 | "rules": [ 988 | { 989 | "action": "allow", 990 | "os": { 991 | "name": "linux" 992 | } 993 | } 994 | ] 995 | }, 996 | { 997 | "downloads": { 998 | "artifact": { 999 | "path": "org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-macos.jar", 1000 | "sha1": "a0d12697ea019a7362eff26475b0531340e876a6", 1001 | "size": 40709, 1002 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-macos.jar" 1003 | } 1004 | }, 1005 | "name": "org.lwjgl:lwjgl-opengl:3.3.1:natives-macos", 1006 | "rules": [ 1007 | { 1008 | "action": "allow", 1009 | "os": { 1010 | "name": "osx" 1011 | } 1012 | } 1013 | ] 1014 | }, 1015 | { 1016 | "downloads": { 1017 | "artifact": { 1018 | "path": "org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-macos-arm64.jar", 1019 | "sha1": "eafe34b871d966292e8db0f1f3d6b8b110d4e91d", 1020 | "size": 41665, 1021 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-macos-arm64.jar" 1022 | } 1023 | }, 1024 | "name": "org.lwjgl:lwjgl-opengl:3.3.1:natives-macos-arm64", 1025 | "rules": [ 1026 | { 1027 | "action": "allow", 1028 | "os": { 1029 | "name": "osx" 1030 | } 1031 | } 1032 | ] 1033 | }, 1034 | { 1035 | "downloads": { 1036 | "artifact": { 1037 | "path": "org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-windows.jar", 1038 | "sha1": "c1807e9bd571402787d7e37e3029776ae2513bb8", 1039 | "size": 100205, 1040 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-windows.jar" 1041 | } 1042 | }, 1043 | "name": "org.lwjgl:lwjgl-opengl:3.3.1:natives-windows", 1044 | "rules": [ 1045 | { 1046 | "action": "allow", 1047 | "os": { 1048 | "name": "windows" 1049 | } 1050 | } 1051 | ] 1052 | }, 1053 | { 1054 | "downloads": { 1055 | "artifact": { 1056 | "path": "org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-windows-arm64.jar", 1057 | "sha1": "527d78f1e9056aff3ed02ce93019c73c5e8f1721", 1058 | "size": 82445, 1059 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-windows-arm64.jar" 1060 | } 1061 | }, 1062 | "name": "org.lwjgl:lwjgl-opengl:3.3.1:natives-windows-arm64", 1063 | "rules": [ 1064 | { 1065 | "action": "allow", 1066 | "os": { 1067 | "name": "windows" 1068 | } 1069 | } 1070 | ] 1071 | }, 1072 | { 1073 | "downloads": { 1074 | "artifact": { 1075 | "path": "org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-windows-x86.jar", 1076 | "sha1": "deef3eb9b178ff2ff3ce893cc72ae741c3a17974", 1077 | "size": 87463, 1078 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-windows-x86.jar" 1079 | } 1080 | }, 1081 | "name": "org.lwjgl:lwjgl-opengl:3.3.1:natives-windows-x86", 1082 | "rules": [ 1083 | { 1084 | "action": "allow", 1085 | "os": { 1086 | "name": "windows" 1087 | } 1088 | } 1089 | ] 1090 | }, 1091 | { 1092 | "downloads": { 1093 | "artifact": { 1094 | "path": "org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1.jar", 1095 | "sha1": "b119297cf8ed01f247abe8685857f8e7fcf5980f", 1096 | "size": 112380, 1097 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1.jar" 1098 | } 1099 | }, 1100 | "name": "org.lwjgl:lwjgl-stb:3.3.1" 1101 | }, 1102 | { 1103 | "downloads": { 1104 | "artifact": { 1105 | "path": "org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-linux.jar", 1106 | "sha1": "3ee7aec8686e52867677110415566a5342a80230", 1107 | "size": 227237, 1108 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-linux.jar" 1109 | } 1110 | }, 1111 | "name": "org.lwjgl:lwjgl-stb:3.3.1:natives-linux", 1112 | "rules": [ 1113 | { 1114 | "action": "allow", 1115 | "os": { 1116 | "name": "linux" 1117 | } 1118 | } 1119 | ] 1120 | }, 1121 | { 1122 | "downloads": { 1123 | "artifact": { 1124 | "path": "org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-macos.jar", 1125 | "sha1": "def8879b8d38a47a4cc1d48b1f9a7b772e51258e", 1126 | "size": 203582, 1127 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-macos.jar" 1128 | } 1129 | }, 1130 | "name": "org.lwjgl:lwjgl-stb:3.3.1:natives-macos", 1131 | "rules": [ 1132 | { 1133 | "action": "allow", 1134 | "os": { 1135 | "name": "osx" 1136 | } 1137 | } 1138 | ] 1139 | }, 1140 | { 1141 | "downloads": { 1142 | "artifact": { 1143 | "path": "org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-macos-arm64.jar", 1144 | "sha1": "fcf073ed911752abdca5f0b00a53cfdf17ff8e8b", 1145 | "size": 178408, 1146 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-macos-arm64.jar" 1147 | } 1148 | }, 1149 | "name": "org.lwjgl:lwjgl-stb:3.3.1:natives-macos-arm64", 1150 | "rules": [ 1151 | { 1152 | "action": "allow", 1153 | "os": { 1154 | "name": "osx" 1155 | } 1156 | } 1157 | ] 1158 | }, 1159 | { 1160 | "downloads": { 1161 | "artifact": { 1162 | "path": "org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-windows.jar", 1163 | "sha1": "86315914ac119efdb02dc9e8e978ade84f1702af", 1164 | "size": 256301, 1165 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-windows.jar" 1166 | } 1167 | }, 1168 | "name": "org.lwjgl:lwjgl-stb:3.3.1:natives-windows", 1169 | "rules": [ 1170 | { 1171 | "action": "allow", 1172 | "os": { 1173 | "name": "windows" 1174 | } 1175 | } 1176 | ] 1177 | }, 1178 | { 1179 | "downloads": { 1180 | "artifact": { 1181 | "path": "org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-windows-arm64.jar", 1182 | "sha1": "fde63cdd2605c00636721a6c8b961e41d1f6b247", 1183 | "size": 216848, 1184 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-windows-arm64.jar" 1185 | } 1186 | }, 1187 | "name": "org.lwjgl:lwjgl-stb:3.3.1:natives-windows-arm64", 1188 | "rules": [ 1189 | { 1190 | "action": "allow", 1191 | "os": { 1192 | "name": "windows" 1193 | } 1194 | } 1195 | ] 1196 | }, 1197 | { 1198 | "downloads": { 1199 | "artifact": { 1200 | "path": "org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-windows-x86.jar", 1201 | "sha1": "a8d41f419eecb430b7c91ea2ce2c5c451cae2091", 1202 | "size": 225147, 1203 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-windows-x86.jar" 1204 | } 1205 | }, 1206 | "name": "org.lwjgl:lwjgl-stb:3.3.1:natives-windows-x86", 1207 | "rules": [ 1208 | { 1209 | "action": "allow", 1210 | "os": { 1211 | "name": "windows" 1212 | } 1213 | } 1214 | ] 1215 | }, 1216 | { 1217 | "downloads": { 1218 | "artifact": { 1219 | "path": "org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1.jar", 1220 | "sha1": "0ff1914111ef2e3e0110ef2dabc8d8cdaad82347", 1221 | "size": 6767, 1222 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1.jar" 1223 | } 1224 | }, 1225 | "name": "org.lwjgl:lwjgl-tinyfd:3.3.1" 1226 | }, 1227 | { 1228 | "downloads": { 1229 | "artifact": { 1230 | "path": "org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-linux.jar", 1231 | "sha1": "a35110b9471bea8cde826ab297550ee8c22f5035", 1232 | "size": 45389, 1233 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-linux.jar" 1234 | } 1235 | }, 1236 | "name": "org.lwjgl:lwjgl-tinyfd:3.3.1:natives-linux", 1237 | "rules": [ 1238 | { 1239 | "action": "allow", 1240 | "os": { 1241 | "name": "linux" 1242 | } 1243 | } 1244 | ] 1245 | }, 1246 | { 1247 | "downloads": { 1248 | "artifact": { 1249 | "path": "org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-macos.jar", 1250 | "sha1": "78641a0fa5e9afa714adfdd152c357930c97a1ce", 1251 | "size": 44821, 1252 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-macos.jar" 1253 | } 1254 | }, 1255 | "name": "org.lwjgl:lwjgl-tinyfd:3.3.1:natives-macos", 1256 | "rules": [ 1257 | { 1258 | "action": "allow", 1259 | "os": { 1260 | "name": "osx" 1261 | } 1262 | } 1263 | ] 1264 | }, 1265 | { 1266 | "downloads": { 1267 | "artifact": { 1268 | "path": "org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-macos-arm64.jar", 1269 | "sha1": "972ecc17bad3571e81162153077b4d47b7b9eaa9", 1270 | "size": 41380, 1271 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-macos-arm64.jar" 1272 | } 1273 | }, 1274 | "name": "org.lwjgl:lwjgl-tinyfd:3.3.1:natives-macos-arm64", 1275 | "rules": [ 1276 | { 1277 | "action": "allow", 1278 | "os": { 1279 | "name": "osx" 1280 | } 1281 | } 1282 | ] 1283 | }, 1284 | { 1285 | "downloads": { 1286 | "artifact": { 1287 | "path": "org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-windows.jar", 1288 | "sha1": "a5d830475ec0958d9fdba1559efa99aef211e6ff", 1289 | "size": 127930, 1290 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-windows.jar" 1291 | } 1292 | }, 1293 | "name": "org.lwjgl:lwjgl-tinyfd:3.3.1:natives-windows", 1294 | "rules": [ 1295 | { 1296 | "action": "allow", 1297 | "os": { 1298 | "name": "windows" 1299 | } 1300 | } 1301 | ] 1302 | }, 1303 | { 1304 | "downloads": { 1305 | "artifact": { 1306 | "path": "org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-windows-arm64.jar", 1307 | "sha1": "83a5e780df610829ff3a737822b4f931cffecd91", 1308 | "size": 109139, 1309 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-windows-arm64.jar" 1310 | } 1311 | }, 1312 | "name": "org.lwjgl:lwjgl-tinyfd:3.3.1:natives-windows-arm64", 1313 | "rules": [ 1314 | { 1315 | "action": "allow", 1316 | "os": { 1317 | "name": "windows" 1318 | } 1319 | } 1320 | ] 1321 | }, 1322 | { 1323 | "downloads": { 1324 | "artifact": { 1325 | "path": "org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-windows-x86.jar", 1326 | "sha1": "842eedd876fae354abc308c98a263f6bbc9e8a4d", 1327 | "size": 110042, 1328 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-windows-x86.jar" 1329 | } 1330 | }, 1331 | "name": "org.lwjgl:lwjgl-tinyfd:3.3.1:natives-windows-x86", 1332 | "rules": [ 1333 | { 1334 | "action": "allow", 1335 | "os": { 1336 | "name": "windows" 1337 | } 1338 | } 1339 | ] 1340 | }, 1341 | { 1342 | "downloads": { 1343 | "artifact": { 1344 | "path": "org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1.jar", 1345 | "sha1": "ae58664f88e18a9bb2c77b063833ca7aaec484cb", 1346 | "size": 724243, 1347 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1.jar" 1348 | } 1349 | }, 1350 | "name": "org.lwjgl:lwjgl:3.3.1" 1351 | }, 1352 | { 1353 | "downloads": { 1354 | "artifact": { 1355 | "path": "org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-linux.jar", 1356 | "sha1": "1de885aba434f934201b99f2f1afb142036ac189", 1357 | "size": 110704, 1358 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-linux.jar" 1359 | } 1360 | }, 1361 | "name": "org.lwjgl:lwjgl:3.3.1:natives-linux", 1362 | "rules": [ 1363 | { 1364 | "action": "allow", 1365 | "os": { 1366 | "name": "linux" 1367 | } 1368 | } 1369 | ] 1370 | }, 1371 | { 1372 | "downloads": { 1373 | "artifact": { 1374 | "path": "org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-macos.jar", 1375 | "sha1": "fc6bb723dec2cd031557dccb2a95f0ab80acb9db", 1376 | "size": 55706, 1377 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-macos.jar" 1378 | } 1379 | }, 1380 | "name": "org.lwjgl:lwjgl:3.3.1:natives-macos", 1381 | "rules": [ 1382 | { 1383 | "action": "allow", 1384 | "os": { 1385 | "name": "osx" 1386 | } 1387 | } 1388 | ] 1389 | }, 1390 | { 1391 | "downloads": { 1392 | "artifact": { 1393 | "path": "org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-macos-arm64.jar", 1394 | "sha1": "71d0d5e469c9c95351eb949064497e3391616ac9", 1395 | "size": 42693, 1396 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-macos-arm64.jar" 1397 | } 1398 | }, 1399 | "name": "org.lwjgl:lwjgl:3.3.1:natives-macos-arm64", 1400 | "rules": [ 1401 | { 1402 | "action": "allow", 1403 | "os": { 1404 | "name": "osx" 1405 | } 1406 | } 1407 | ] 1408 | }, 1409 | { 1410 | "downloads": { 1411 | "artifact": { 1412 | "path": "org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-windows.jar", 1413 | "sha1": "0036c37f16ab611b3aa11f3bcf80b1d509b4ce6b", 1414 | "size": 159361, 1415 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-windows.jar" 1416 | } 1417 | }, 1418 | "name": "org.lwjgl:lwjgl:3.3.1:natives-windows", 1419 | "rules": [ 1420 | { 1421 | "action": "allow", 1422 | "os": { 1423 | "name": "windows" 1424 | } 1425 | } 1426 | ] 1427 | }, 1428 | { 1429 | "downloads": { 1430 | "artifact": { 1431 | "path": "org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-windows-arm64.jar", 1432 | "sha1": "0f46cadcf95675908fd3a550d63d9d709cb68998", 1433 | "size": 130064, 1434 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-windows-arm64.jar" 1435 | } 1436 | }, 1437 | "name": "org.lwjgl:lwjgl:3.3.1:natives-windows-arm64", 1438 | "rules": [ 1439 | { 1440 | "action": "allow", 1441 | "os": { 1442 | "name": "windows" 1443 | } 1444 | } 1445 | ] 1446 | }, 1447 | { 1448 | "downloads": { 1449 | "artifact": { 1450 | "path": "org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-windows-x86.jar", 1451 | "sha1": "3b14f4beae9dd39791ec9e12190a9380cd8a3ce6", 1452 | "size": 134695, 1453 | "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-windows-x86.jar" 1454 | } 1455 | }, 1456 | "name": "org.lwjgl:lwjgl:3.3.1:natives-windows-x86", 1457 | "rules": [ 1458 | { 1459 | "action": "allow", 1460 | "os": { 1461 | "name": "windows" 1462 | } 1463 | } 1464 | ] 1465 | }, 1466 | { 1467 | "downloads": { 1468 | "artifact": { 1469 | "path": "org/slf4j/slf4j-api/2.0.1/slf4j-api-2.0.1.jar", 1470 | "sha1": "f48d81adce2abf5ad3cfe463df517952749e03bc", 1471 | "size": 61388, 1472 | "url": "https://libraries.minecraft.net/org/slf4j/slf4j-api/2.0.1/slf4j-api-2.0.1.jar" 1473 | } 1474 | }, 1475 | "name": "org.slf4j:slf4j-api:2.0.1" 1476 | } 1477 | ], 1478 | "logging": { 1479 | "client": { 1480 | "argument": "-Dlog4j.configurationFile=${path}", 1481 | "file": { 1482 | "id": "client-1.12.xml", 1483 | "sha1": "bd65e7d2e3c237be76cfbef4c2405033d7f91521", 1484 | "size": 888, 1485 | "url": "https://piston-data.mojang.com/v1/objects/bd65e7d2e3c237be76cfbef4c2405033d7f91521/client-1.12.xml" 1486 | }, 1487 | "type": "log4j2-xml" 1488 | } 1489 | }, 1490 | "mainClass": "net.minecraft.client.main.Main", 1491 | "minimumLauncherVersion": 21, 1492 | "releaseTime": "2023-03-14T12:56:18+00:00", 1493 | "time": "2023-03-14T12:56:18+00:00", 1494 | "type": "release" 1495 | } -------------------------------------------------------------------------------- /examples/create_classpath.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | 3 | use mc_bootstrap::{classpath::create_classpath, manifest::read_manifest_from_file}; 4 | 5 | fn get_current_dir() -> PathBuf { 6 | let current_dir = std::env::current_dir().unwrap(); 7 | current_dir 8 | } 9 | 10 | fn get_mc_dir() -> PathBuf { 11 | return get_current_dir().join("examples").join(".minecraft"); 12 | } 13 | 14 | fn main() { 15 | let libs = get_mc_dir().join("libraries"); 16 | let jar = get_mc_dir().join("versions/1.19.4/1.19.4.jar"); 17 | let json = get_mc_dir().join("versions/1.19.4/1.19.4.json"); 18 | 19 | let manifest = read_manifest_from_file(json).unwrap(); 20 | let classpath = create_classpath(jar, libs, manifest.libraries); 21 | println!("{}", classpath); 22 | } 23 | -------------------------------------------------------------------------------- /examples/launch_from_dot_minecraft.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | 3 | use mc_bootstrap::{ClientAuth, ClientBootstrap, ClientSettings, ClientVersion}; 4 | 5 | fn get_mc_dir() -> PathBuf { 6 | return PathBuf::from("E:\\Workspaces\\downloader\\.minecraft"); 7 | } 8 | 9 | fn main() { 10 | let bootstrap = ClientBootstrap::new(ClientSettings { 11 | assets: get_mc_dir().join("assets"), 12 | auth: ClientAuth { 13 | username: "Sammwy_".to_string(), 14 | access_token: None, 15 | uuid: None, 16 | }, 17 | game_dir: get_mc_dir(), 18 | java_bin: PathBuf::from( 19 | "C:\\Program Files\\Eclipse Adoptium\\jdk-17.0.7.7-hotspot\\bin\\java.exe", 20 | ), 21 | libraries_dir: get_mc_dir().join("libraries"), 22 | manifest_file: get_mc_dir() 23 | .join("versions") 24 | .join("1.19.4") 25 | .join("1.19.4.json"), 26 | natives_dir: get_mc_dir().join("versions").join("1.19.4").join("natives"), 27 | version: ClientVersion { 28 | version: "1.19.4".to_string(), 29 | version_type: "release".to_string(), 30 | }, 31 | version_jar_file: get_mc_dir() 32 | .join("versions") 33 | .join("1.19.4") 34 | .join("1.19.4.jar"), 35 | }); 36 | 37 | bootstrap.launch().unwrap(); 38 | } 39 | -------------------------------------------------------------------------------- /examples/parse_version_json.rs: -------------------------------------------------------------------------------- 1 | use mc_bootstrap::manifest::read_manifest_from_str; 2 | 3 | fn main() { 4 | let manifest = 5 | read_manifest_from_str(include_str!("./.minecraft/versions/1.19.4/1.19.4.json")).unwrap(); 6 | 7 | println!("Asset index: {}", manifest.asset_index.id); 8 | println!("Assets: {}", manifest.assets); 9 | println!("Compilance Level: {}", manifest.compliance_level); 10 | println!("Jar: {}", manifest.downloads.client.url); 11 | println!("Java version: {}", manifest.java_version.major_version); 12 | println!("Libraries: {}", manifest.libraries.len()); 13 | println!("Main class: {}", manifest.main_class); 14 | println!("Launcher version: {}", manifest.minimum_launcher_version); 15 | println!("Release time: {}", manifest.release_time); 16 | println!("Time: {}", manifest.time); 17 | println!("Type: {}", manifest.version_type); 18 | } 19 | -------------------------------------------------------------------------------- /src/classpath.rs: -------------------------------------------------------------------------------- 1 | use std::path::{Path, PathBuf}; 2 | 3 | use crate::{manifest::Library, rules::is_all_rules_satisfied}; 4 | 5 | pub fn should_use_library(lib: &Library) -> bool { 6 | let rules_opt = &lib.rules; 7 | if !rules_opt.is_some() { 8 | return true; 9 | } 10 | 11 | let rules = rules_opt.as_ref().unwrap(); 12 | return is_all_rules_satisfied(rules); 13 | } 14 | 15 | pub fn create_classpath( 16 | jar_file: PathBuf, 17 | libraries_path: PathBuf, 18 | libraries: Vec, 19 | ) -> String { 20 | let mut classpath = jar_file.to_str().unwrap().to_string(); 21 | 22 | for lib in libraries.iter() { 23 | let should_use = should_use_library(lib); 24 | if should_use { 25 | let artifact = &lib.downloads.artifact; 26 | let lib_path = artifact.path.clone(); 27 | let fixed_lib_path = Path::new(&libraries_path).join(lib_path.replace("/", "\\")); 28 | classpath = format!("{};{}", classpath, fixed_lib_path.to_str().unwrap()); 29 | } 30 | } 31 | 32 | return classpath; 33 | } 34 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod classpath; 2 | pub mod manifest; 3 | pub mod rules; 4 | 5 | use manifest::{read_manifest_from_file, JvmArgument}; 6 | use rules::is_all_rules_satisfied; 7 | use std::{path::PathBuf, process::Command}; 8 | use thiserror::Error; 9 | 10 | #[derive(Error, Debug)] 11 | pub enum ClientBootstrapError { 12 | #[error("The game directory doesn't exist.")] 13 | GameDirNotExist, 14 | 15 | #[error("The java bin doesn't exist.")] 16 | JavaBinNotExist, 17 | 18 | #[error("The version file (.json) doesn't exist.")] 19 | VersionFileNotFound, 20 | 21 | #[error("An unexpected error has ocurred.")] 22 | UnknownError, 23 | 24 | #[error("{0}")] 25 | Json(#[from] serde_json::Error), 26 | } 27 | 28 | pub struct ClientAuth { 29 | pub access_token: Option, 30 | pub username: String, 31 | pub uuid: Option, 32 | } 33 | 34 | pub struct ClientVersion { 35 | pub version: String, 36 | pub version_type: String, 37 | } 38 | 39 | pub struct ClientSettings { 40 | pub assets: PathBuf, 41 | pub auth: ClientAuth, 42 | pub game_dir: PathBuf, 43 | pub java_bin: PathBuf, 44 | pub libraries_dir: PathBuf, 45 | pub manifest_file: PathBuf, 46 | pub natives_dir: PathBuf, 47 | pub version: ClientVersion, 48 | pub version_jar_file: PathBuf, 49 | } 50 | 51 | pub struct ClientBootstrap { 52 | pub settings: ClientSettings, 53 | } 54 | 55 | impl ClientBootstrap { 56 | pub fn new(settings: ClientSettings) -> Self { 57 | Self { settings } 58 | } 59 | 60 | pub fn get_assets_dir(&self) -> PathBuf { 61 | return self.settings.assets.clone(); 62 | } 63 | 64 | pub fn get_game_dir(&self) -> PathBuf { 65 | return self.settings.game_dir.clone(); 66 | } 67 | 68 | pub fn get_json_file(&self) -> PathBuf { 69 | return self.settings.manifest_file.clone(); 70 | } 71 | 72 | pub fn get_jar_file(&self) -> PathBuf { 73 | return self.settings.version_jar_file.clone(); 74 | } 75 | 76 | pub fn get_libs_dir(&self) -> PathBuf { 77 | return self.settings.libraries_dir.clone(); 78 | } 79 | 80 | pub fn get_natives_dir(&self) -> PathBuf { 81 | return self.settings.natives_dir.clone(); 82 | } 83 | 84 | pub fn build_args(&self) -> Result, ClientBootstrapError> { 85 | let auth = &self.settings.auth; 86 | let assets_dir = self.get_assets_dir(); 87 | let game_dir = self.get_game_dir(); 88 | let java_bin = self.settings.java_bin.clone(); 89 | let json_file = self.get_json_file(); 90 | let natives_dir = self.get_natives_dir(); 91 | let version = &self.settings.version; 92 | 93 | if !game_dir.is_dir() { 94 | return Err(ClientBootstrapError::GameDirNotExist); 95 | } 96 | 97 | if !java_bin.is_file() { 98 | return Err(ClientBootstrapError::JavaBinNotExist); 99 | } 100 | 101 | if !json_file.is_file() { 102 | return Err(ClientBootstrapError::VersionFileNotFound); 103 | } 104 | 105 | let manifest = read_manifest_from_file(json_file).unwrap(); 106 | 107 | let assets_index = &manifest.asset_index.id; 108 | let classpath = classpath::create_classpath( 109 | self.get_jar_file(), 110 | self.get_libs_dir(), 111 | manifest.libraries, 112 | ); 113 | 114 | let mut args: Vec = vec![]; 115 | 116 | for arg in manifest.arguments.jvm { 117 | match arg { 118 | JvmArgument::String(value) => { 119 | args.push(value); 120 | } 121 | JvmArgument::Struct { value, rules, .. } => { 122 | if !is_all_rules_satisfied(&rules) { 123 | continue; 124 | } 125 | 126 | if let Some(value) = value.as_str() { 127 | args.push(value.to_string()); 128 | } else if let Some(value_arr) = value.as_array() { 129 | for value in value_arr { 130 | if let Some(value) = value.as_str() { 131 | args.push(value.to_string()); 132 | } 133 | } 134 | } 135 | } 136 | } 137 | } 138 | 139 | args.push(manifest.main_class); 140 | 141 | for arg in manifest.arguments.game { 142 | match arg { 143 | JvmArgument::String(value) => { 144 | args.push(value); 145 | } 146 | JvmArgument::Struct { value, rules, .. } => { 147 | if !is_all_rules_satisfied(&rules) { 148 | continue; 149 | } 150 | 151 | if let Some(value) = value.as_str() { 152 | args.push(value.to_string()); 153 | } else if let Some(value_arr) = value.as_array() { 154 | for value in value_arr { 155 | if let Some(value) = value.as_str() { 156 | args.push(value.to_string()); 157 | } 158 | } 159 | } 160 | } 161 | } 162 | } 163 | 164 | args = args 165 | .iter() 166 | .map(|x| { 167 | x.replace("${assets_root}", &assets_dir.to_str().unwrap()) 168 | .replace("${game_directory}", &game_dir.to_str().unwrap()) 169 | .replace("${natives_directory}", &natives_dir.to_str().unwrap()) 170 | .replace("${launcher_name}", "minecraft-rs/bootstrap") 171 | .replace("${launcher_version}", "0.1.1") 172 | .replace( 173 | "${auth_access_token}", 174 | auth.access_token 175 | .clone() 176 | .unwrap_or("null".to_string()) 177 | .as_str(), 178 | ) 179 | .replace("${auth_player_name}", auth.username.as_str()) 180 | .replace( 181 | "${auth_uuid}", 182 | auth.uuid.clone().unwrap_or("null".to_string()).as_str(), 183 | ) 184 | .replace("${version_type}", &version.version_type) 185 | .replace("${version_name}", &version.version) 186 | .replace("${assets_index_name}", &assets_index) 187 | .replace("${user_properties}", "{}") 188 | .replace("${classpath}", &classpath) 189 | }) 190 | .collect(); 191 | 192 | return Ok(args); 193 | } 194 | 195 | pub fn launch(&self) -> Result { 196 | let args = self.build_args().unwrap(); 197 | 198 | let mut process = Command::new(&self.settings.java_bin) 199 | .args(args) 200 | .current_dir(&self.settings.game_dir) 201 | .spawn() 202 | .expect("command failed to start"); 203 | 204 | let status = process.wait().unwrap().code().unwrap(); 205 | return Ok(status); 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /src/manifest.rs: -------------------------------------------------------------------------------- 1 | use std::{fs, path::PathBuf}; 2 | 3 | use serde::{Deserialize, Serialize}; 4 | use thiserror::Error; 5 | 6 | #[derive(Debug, Deserialize, Serialize)] 7 | pub struct Rules { 8 | pub action: String, 9 | pub features: Option, 10 | pub os: Option, 11 | } 12 | 13 | #[derive(Debug, Deserialize, Serialize)] 14 | pub struct Features { 15 | pub is_demo_user: Option, 16 | pub has_custom_resolution: Option, 17 | pub is_quick_play_realms: Option, 18 | } 19 | 20 | #[derive(Debug, Deserialize, Serialize)] 21 | pub struct Os { 22 | pub arch: Option, 23 | pub name: Option, 24 | pub version: Option, 25 | } 26 | 27 | #[derive(Debug, Deserialize, Serialize)] 28 | pub struct Arguments { 29 | pub game: Vec, 30 | pub jvm: Vec, 31 | } 32 | 33 | #[derive(Debug, Deserialize, Serialize)] 34 | #[serde(untagged)] 35 | pub enum JvmArgument { 36 | String(String), 37 | Struct { 38 | rules: Vec, 39 | value: serde_json::Value, 40 | }, 41 | } 42 | 43 | #[derive(Debug, Deserialize, Serialize)] 44 | pub struct AssetIndex { 45 | pub id: String, 46 | pub sha1: String, 47 | pub size: u64, 48 | #[serde(rename = "totalSize")] 49 | pub total_size: u64, 50 | pub url: String, 51 | } 52 | 53 | #[derive(Debug, Deserialize, Serialize)] 54 | pub struct Downloads { 55 | pub client: DownloadItem, 56 | pub client_mappings: DownloadItem, 57 | pub server: DownloadItem, 58 | pub server_mappings: DownloadItem, 59 | } 60 | 61 | #[derive(Debug, Deserialize, Serialize)] 62 | pub struct DownloadItem { 63 | pub sha1: String, 64 | pub size: u64, 65 | pub url: String, 66 | } 67 | 68 | #[derive(Debug, Deserialize, Serialize)] 69 | pub struct JavaVersion { 70 | pub component: String, 71 | #[serde(rename = "majorVersion")] 72 | pub major_version: u32, 73 | } 74 | 75 | #[derive(Debug, Deserialize, Serialize)] 76 | pub struct Library { 77 | pub downloads: LibraryDownloads, 78 | pub name: String, 79 | pub rules: Option>, 80 | } 81 | 82 | #[derive(Debug, Deserialize, Serialize)] 83 | pub struct LibraryDownloads { 84 | pub artifact: LibraryArtifact, 85 | } 86 | 87 | #[derive(Debug, Deserialize, Serialize)] 88 | pub struct LibraryArtifact { 89 | pub path: String, 90 | pub sha1: String, 91 | pub size: u64, 92 | pub url: String, 93 | } 94 | 95 | #[derive(Debug, Deserialize, Serialize)] 96 | pub struct Logging { 97 | pub client: ClientLogging, 98 | } 99 | 100 | #[derive(Debug, Deserialize, Serialize)] 101 | pub struct ClientLogging { 102 | pub argument: String, 103 | pub file: ClientLogFile, 104 | #[serde(rename = "type")] 105 | pub log_type: String, 106 | } 107 | 108 | #[derive(Debug, Deserialize, Serialize)] 109 | pub struct ClientLogFile { 110 | pub id: String, 111 | pub sha1: String, 112 | pub size: u64, 113 | pub url: String, 114 | } 115 | 116 | #[derive(Debug, Deserialize, Serialize)] 117 | pub struct Manifest { 118 | pub arguments: Arguments, 119 | #[serde(rename = "assetIndex")] 120 | pub asset_index: AssetIndex, 121 | pub assets: String, 122 | #[serde(rename = "complianceLevel")] 123 | pub compliance_level: u32, 124 | pub downloads: Downloads, 125 | pub id: String, 126 | #[serde(rename = "javaVersion")] 127 | pub java_version: JavaVersion, 128 | pub libraries: Vec, 129 | pub logging: Logging, 130 | #[serde(rename = "mainClass")] 131 | pub main_class: String, 132 | #[serde(rename = "minimumLauncherVersion")] 133 | pub minimum_launcher_version: u32, 134 | #[serde(rename = "releaseTime")] 135 | pub release_time: String, 136 | pub time: String, 137 | #[serde(rename = "type")] 138 | pub version_type: String, 139 | } 140 | 141 | #[derive(Error, Debug)] 142 | pub enum ManifestError { 143 | #[error("The game directory doesn't exist.")] 144 | GameDirNotExist, 145 | 146 | #[error("The java bin doesn't exist.")] 147 | JavaBinNotExist, 148 | 149 | #[error("An unexpected error has ocurred.")] 150 | UnknownError, 151 | 152 | #[error("{0}")] 153 | IO(#[from] std::io::Error), 154 | 155 | #[error("{0}")] 156 | Json(#[from] serde_json::Error), 157 | } 158 | 159 | pub fn read_manifest_from_str(string: &str) -> Result { 160 | let manifest: Manifest = serde_json::from_str(&string)?; 161 | return Ok(manifest); 162 | } 163 | 164 | pub fn read_manifest_from_file(file: PathBuf) -> Result { 165 | let raw = fs::read_to_string(file)?; 166 | let manifest: Manifest = read_manifest_from_str(&raw)?; 167 | return Ok(manifest); 168 | } 169 | -------------------------------------------------------------------------------- /src/rules.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | 3 | use crate::manifest::Rules; 4 | 5 | pub fn is_rule_satisfied(rule: &Rules) -> bool { 6 | if rule.os.is_some() { 7 | let os = rule.os.as_ref().unwrap(); 8 | let target_os = &os.name; 9 | 10 | if target_os.is_some() { 11 | let target_os = target_os.as_ref().unwrap(); 12 | let current_os = env::consts::OS; 13 | 14 | if current_os != target_os { 15 | return false; 16 | } 17 | } 18 | } 19 | 20 | if rule.features.is_some() { 21 | let features = rule.features.as_ref().unwrap(); 22 | let custom_res = features.has_custom_resolution.unwrap_or(false); 23 | let demo = features.is_demo_user.unwrap_or(false); 24 | let quick_realms: bool = features.is_quick_play_realms.unwrap_or(false); 25 | 26 | if custom_res || demo || quick_realms { 27 | return false; 28 | } 29 | } 30 | 31 | return true; 32 | } 33 | 34 | pub fn is_all_rules_satisfied(rules: &Vec) -> bool { 35 | for rule in rules.iter() { 36 | let satisfied = is_rule_satisfied(rule); 37 | let use_lib = rule.action == "allow"; 38 | 39 | if satisfied && !use_lib { 40 | return false; 41 | } else if !satisfied && use_lib { 42 | return false; 43 | } 44 | } 45 | 46 | return true; 47 | } 48 | --------------------------------------------------------------------------------