diff --git a/Cargo.toml b/Cargo.toml index 14f3fb2b..1eda8a21 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,8 @@ tauri-plugin-stronghold = { git = "https://github.com/tauri-apps/plugins-workspa tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" } tauri-plugin-single-instance = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" } +interpulse = { version = "0.1" } + tracing = { version = "0.1" } tracing-subscriber = { version = "0.3", features = [ "chrono", @@ -59,6 +61,9 @@ tokio-stream = { version = "0.1", features = [ "fs" ] } async-recursion = { version = "1.1" } notify = { version = "6.1", default-features = false, features = [ "serde" ] } notify-debouncer-mini = { version = "0.4", default-features = false } +regex = { version = "1.10" } +sysinfo = { version = "0.30" } +sys-info = { version = "0.9" } [profile.dev] # Make compilation faster on macOS diff --git a/onelauncher/Cargo.toml b/onelauncher/Cargo.toml index b522b5c5..4f01eb9a 100644 --- a/onelauncher/Cargo.toml +++ b/onelauncher/Cargo.toml @@ -18,6 +18,8 @@ cli = [ "dep:indicatif" ] tauri = { workspace = true, optional = true } indicatif = { workspace = true, optional = true } +interpulse = { workspace = true } + tracing = { workspace = true } tracing-subscriber = { workspace = true } tracing-error = { workspace = true } @@ -41,6 +43,9 @@ sha1 = { workspace = true } discord-rich-presence = { workspace = true } notify = { workspace = true } notify-debouncer-mini = { workspace = true } +regex = { workspace = true } +sysinfo = { workspace = true } +sys-info = { workspace = true } [target.'cfg(windows)'.dependencies] winreg = { workspace = true } diff --git a/onelauncher/src/error.rs b/onelauncher/src/error.rs index 829d6247..005cbf8b 100644 --- a/onelauncher/src/error.rs +++ b/onelauncher/src/error.rs @@ -31,6 +31,10 @@ pub enum ErrorKind { #[error("failed to parse uuids: {0}")] UUIDError(#[from] uuid::Error), + /// Wrapper around [`interpulse::Error`] to handle interpulse errors. + #[error("metadata error: {0}")] + MetadataError(#[from] interpulse::Error), + /// Wrapper around [`serde_json::Error`] to handle Serde JSON parsing errors. #[error("failed to manage serialization of json: {0}")] SerdeError(#[from] serde_json::Error), diff --git a/onelauncher/src/game/minecraft.rs b/onelauncher/src/game/minecraft.rs index 217059f0..ae61228b 100644 --- a/onelauncher/src/game/minecraft.rs +++ b/onelauncher/src/game/minecraft.rs @@ -1,4 +1,7 @@ -use serde::{Deserialize, Serialize}; +use core::fmt; +use std::{collections::HashMap, marker::PhantomData}; + +use serde::{de::{self, SeqAccess, Visitor}, Deserialize, Deserializer, Serialize}; use serde_json::Value; #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] @@ -6,16 +9,17 @@ use serde_json::Value; pub struct MinecraftManifest { pub asset_index: AssetIndex, pub downloads: Downloads, - #[serde(rename = "id")] - pub version: String, pub java_version: JavaVersion, pub libraries: Vec, pub logging: Logging, pub main_class: String, - pub arguments: Arguments, pub release_time: String, + #[serde(rename = "id")] + pub version: String, #[serde(rename = "type")] pub release_type: ReleaseType, + #[serde(skip_serializing_if = "Option::is_none")] + pub minecraft_arguments } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] diff --git a/onelauncher/src/lib.rs b/onelauncher/src/lib.rs index 2e6fa70e..723f92f5 100644 --- a/onelauncher/src/lib.rs +++ b/onelauncher/src/lib.rs @@ -1,4 +1,4 @@ -#![warn(unused_import_braces)] +#![warn(unused_import_braces, missing_debug_implementations)] #![deny(unused_must_use)] pub mod auth; diff --git a/onelauncher/src/utils/mod.rs b/onelauncher/src/utils/mod.rs index 57a94ec7..26e01c88 100644 --- a/onelauncher/src/utils/mod.rs +++ b/onelauncher/src/utils/mod.rs @@ -1,3 +1,4 @@ pub mod dirs; pub mod file; pub mod http; +pub mod platform; diff --git a/onelauncher/src/utils/platform.rs b/onelauncher/src/utils/platform.rs new file mode 100644 index 00000000..ada4b4d8 --- /dev/null +++ b/onelauncher/src/utils/platform.rs @@ -0,0 +1,100 @@ +use interpulse::api::minecraft::{Os, OsRule}; +use regex::Regex; + +pub trait OsExt { + /// Get the OS of the current system + fn native() -> Self; + + /// Gets the OS + Arch of the current system + fn native_arch(java_arch: &str) -> Self; +} + +impl OsExt for Os { + fn native_arch(java_arch: &str) -> Self { + if std::env::consts::OS == "windows" { + if java_arch == "aarch64" { + Os::WindowsArm64 + } else { + Os::Windows + } + } else if std::env::consts::OS == "linux" { + if java_arch == "aarch64" { + Os::LinuxArm64 + } else if java_arch == "arm" { + Os::LinuxArm32 + } else { + Os::Linux + } + } else if std::env::consts::OS == "macos" { + if java_arch == "aarch64" { + Os::OsxArm64 + } else { + Os::Osx + } + } else { + Os::Unknown + } + } + + fn native() -> Self { + match std::env::consts::OS { + "windows" => Self::Windows, + "macos" => Self::Osx, + "linux" => Self::Linux, + _ => Self::Unknown, + } + } +} + +// Bit width +#[cfg(target_pointer_width = "64")] +pub const ARCH_WIDTH: &str = "64"; + +#[cfg(target_pointer_width = "32")] +pub const ARCH_WIDTH: &str = "32"; + +// Platform rule handling +pub fn os_rule( + rule: &OsRule, + java_arch: &str, + // Minecraft updated over 1.18.2 (supports MacOS Natively) + minecraft_updated: bool, +) -> bool { + let mut rule_match = true; + + if let Some(ref arch) = rule.arch { + rule_match &= !matches!(arch.as_str(), "x86" | "arm"); + } + + if let Some(name) = &rule.name { + if minecraft_updated + && (name != &Os::LinuxArm64 || name != &Os::LinuxArm32) + { + rule_match &= + &Os::native() == name || &Os::native_arch(java_arch) == name; + } else { + rule_match &= &Os::native_arch(java_arch) == name; + } + } + + if let Some(version) = &rule.version { + if let Ok(regex) = Regex::new(version.as_str()) { + rule_match &= + regex.is_match(&sys_info::os_release().unwrap_or_default()); + } + } + + rule_match +} + +pub fn classpath_separator(java_arch: &str) -> &'static str { + match Os::native_arch(java_arch) { + Os::Osx + | Os::OsxArm64 + | Os::Linux + | Os::LinuxArm32 + | Os::LinuxArm64 + | Os::Unknown => ":", + Os::Windows | Os::WindowsArm64 => ";", + } +} diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 2bb64d9d..156b51a9 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -16,6 +16,8 @@ tauri-build = { workspace = true } [dependencies] onelauncher = { path = "../onelauncher", features = [ "tauri" ] } +interpulse = { workspace = true, features = [ "bincode" ] } + tauri = { workspace = true } tauri-plugin-shell = { workspace = true } tauri-plugin-window-state = { workspace = true }