diff options
Diffstat (limited to 'src/minecraft/launcher.rs')
| -rw-r--r-- | src/minecraft/launcher.rs | 91 |
1 files changed, 73 insertions, 18 deletions
diff --git a/src/minecraft/launcher.rs b/src/minecraft/launcher.rs index f7e3ecc..cfd6c85 100644 --- a/src/minecraft/launcher.rs +++ b/src/minecraft/launcher.rs | |||
| @@ -2,26 +2,39 @@ use std::process::Command; | |||
| 2 | 2 | ||
| 3 | use log::{debug, info}; | 3 | use log::{debug, info}; |
| 4 | 4 | ||
| 5 | use crate::{config::Config, errors::McError, minecraft::manifests::Version, platform::paths}; | 5 | use crate::{ |
| 6 | config::Config, | ||
| 7 | errors::McError, | ||
| 8 | minecraft::manifests::{Library, Version}, | ||
| 9 | platform::paths, | ||
| 10 | }; | ||
| 6 | 11 | ||
| 7 | /// Build the full classpath | 12 | /// Buduje classpath dla danej wersji Minecrafta |
| 8 | fn build_classpath(config: &Config, version: &Version) -> Result<String, McError> { | 13 | fn build_classpath( |
| 14 | config: &Config, | ||
| 15 | version: &Version, | ||
| 16 | ) -> Result<String, McError> { | ||
| 9 | let sep = if cfg!(windows) { ";" } else { ":" }; | 17 | let sep = if cfg!(windows) { ";" } else { ":" }; |
| 10 | let mut entries = Vec::new(); | 18 | let mut entries = Vec::new(); |
| 11 | 19 | ||
| 12 | for lib in &version.libraries { | 20 | for library in &version.libraries { |
| 13 | if let Some(artifact) = &lib.downloads.artifact { | 21 | if !library_allowed(library) { |
| 22 | continue; | ||
| 23 | } | ||
| 24 | if let Some(artifact) = &library.downloads.artifact { | ||
| 14 | let path = paths::library_file(config, &artifact.path)?; | 25 | let path = paths::library_file(config, &artifact.path)?; |
| 15 | entries.push(path.to_string_lossy().to_string()); | 26 | entries.push(path.to_string_lossy().to_string()); |
| 16 | } | 27 | } |
| 17 | } | 28 | } |
| 18 | 29 | ||
| 30 | // client.jar zawsze na końcu classpath | ||
| 19 | let client_jar = paths::client_jar(config, &version.id)?; | 31 | let client_jar = paths::client_jar(config, &version.id)?; |
| 20 | entries.push(client_jar.to_string_lossy().to_string()); | 32 | entries.push(client_jar.to_string_lossy().to_string()); |
| 33 | |||
| 21 | Ok(entries.join(sep)) | 34 | Ok(entries.join(sep)) |
| 22 | } | 35 | } |
| 23 | 36 | ||
| 24 | /// Launch Minecraft | 37 | /// Uruchamia Minecraft |
| 25 | pub fn launch(config: &Config, version: &Version) -> Result<(), McError> { | 38 | pub fn launch(config: &Config, version: &Version) -> Result<(), McError> { |
| 26 | let java = &config.java_path; | 39 | let java = &config.java_path; |
| 27 | let classpath = build_classpath(config, version)?; | 40 | let classpath = build_classpath(config, version)?; |
| @@ -34,26 +47,46 @@ pub fn launch(config: &Config, version: &Version) -> Result<(), McError> { | |||
| 34 | ))); | 47 | ))); |
| 35 | } | 48 | } |
| 36 | 49 | ||
| 50 | let asset_index_id = version | ||
| 51 | .asset_index | ||
| 52 | .as_ref() | ||
| 53 | .ok_or_else(|| { | ||
| 54 | McError::Runtime("Missing assetIndex in version.json".into()) | ||
| 55 | })? | ||
| 56 | .id | ||
| 57 | .clone(); | ||
| 58 | |||
| 37 | info!("Launching Minecraft {}", version.id); | 59 | info!("Launching Minecraft {}", version.id); |
| 38 | debug!("Classpath: {}", classpath); | 60 | debug!("Classpath: {}", classpath); |
| 39 | debug!("Natives: {}", natives_dir.display()); | 61 | debug!("Natives: {}", natives_dir.display()); |
| 62 | debug!("Asset index: {}", asset_index_id); | ||
| 63 | |||
| 64 | let mut cmd = Command::new(java); | ||
| 65 | |||
| 66 | // ===== JVM ARGUMENTS (muszą być na początku) ===== | ||
| 67 | cmd.arg(format!("-Xmx{}M", config.max_memory_mb)) | ||
| 68 | .arg(format!("-Djava.library.path={}", natives_dir.display())); | ||
| 40 | 69 | ||
| 41 | let status = Command::new(java) | 70 | for arg in &config.jvm_args { |
| 42 | .arg(format!("-Xmx{}M", config.max_memory_mb)) | 71 | cmd.arg(arg); |
| 43 | .arg(format!("-Djava.library.path={}", natives_dir.display())) | 72 | } |
| 44 | .arg("-cp") | 73 | |
| 74 | // ===== CLASSPATH + MAIN CLASS ===== | ||
| 75 | cmd.arg("-cp") | ||
| 45 | .arg(classpath) | 76 | .arg(classpath) |
| 46 | .arg(&version.main_class) | 77 | .arg(&version.main_class); |
| 47 | .arg("--username") | 78 | |
| 79 | // ===== ARGUMENTY GRY ===== | ||
| 80 | cmd.arg("--username") | ||
| 48 | .arg(&config.username) | 81 | .arg(&config.username) |
| 49 | .arg("--version") | 82 | .arg("--version") |
| 50 | .arg(&version.id) | 83 | .arg(&version.id) |
| 51 | .arg("--gameDir") | 84 | .arg("--gameDir") |
| 52 | .arg(paths::minecraft_root(config)) | 85 | .arg(paths::game_dir(config)) |
| 53 | .arg("--assetsDir") | 86 | .arg("--assetsDir") |
| 54 | .arg(paths::minecraft_root(config).join("assets")) | 87 | .arg(paths::assets_dir(config)) |
| 55 | .arg("--assetIndex") | 88 | .arg("--assetIndex") |
| 56 | .arg(&version.id) | 89 | .arg(&asset_index_id) |
| 57 | .arg("--uuid") | 90 | .arg("--uuid") |
| 58 | .arg(&config.uuid) | 91 | .arg(&config.uuid) |
| 59 | .arg("--userProperties") | 92 | .arg("--userProperties") |
| @@ -61,9 +94,9 @@ pub fn launch(config: &Config, version: &Version) -> Result<(), McError> { | |||
| 61 | .arg("--accessToken") | 94 | .arg("--accessToken") |
| 62 | .arg("0") | 95 | .arg("0") |
| 63 | .arg("--userType") | 96 | .arg("--userType") |
| 64 | .arg("legacy") | 97 | .arg("legacy"); // legacy dla starych kont, można później zmienić |
| 65 | .args(&config.jvm_args) | 98 | |
| 66 | .status()?; | 99 | let status = cmd.status()?; |
| 67 | 100 | ||
| 68 | if !status.success() { | 101 | if !status.success() { |
| 69 | return Err(McError::Process("Minecraft exited with error".into())); | 102 | return Err(McError::Process("Minecraft exited with error".into())); |
| @@ -71,3 +104,25 @@ pub fn launch(config: &Config, version: &Version) -> Result<(), McError> { | |||
| 71 | 104 | ||
| 72 | Ok(()) | 105 | Ok(()) |
| 73 | } | 106 | } |
| 107 | |||
| 108 | /// Sprawdza reguły bibliotek tak jak robi Mojang | ||
| 109 | fn library_allowed(lib: &Library) -> bool { | ||
| 110 | let rules = match &lib.rules { | ||
| 111 | | Some(r) => r, | ||
| 112 | | None => return true, | ||
| 113 | }; | ||
| 114 | |||
| 115 | let mut allowed = false; | ||
| 116 | |||
| 117 | for rule in rules { | ||
| 118 | let os_match = match &rule.os { | ||
| 119 | | Some(os) => os.name == "linux", | ||
| 120 | | None => true, | ||
| 121 | }; | ||
| 122 | if os_match { | ||
| 123 | allowed = rule.action == "allow"; | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | allowed | ||
| 128 | } | ||
