aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src-tauri/src/main.rs
diff options
context:
space:
mode:
authorHsiangNianian <i@jyunko.cn>2026-01-18 13:34:52 +0800
committerHsiangNianian <i@jyunko.cn>2026-01-18 13:34:52 +0800
commit02520ca62ac5e508e8748b2445171be64f459b6c (patch)
treea15a95be5f2f93385df36d6336f53b3f08d07a44 /src-tauri/src/main.rs
parent53df697ccf90cd13efc985c195dade48920cc0fa (diff)
downloadDropOut-02520ca62ac5e508e8748b2445171be64f459b6c.tar.gz
DropOut-02520ca62ac5e508e8748b2445171be64f459b6c.zip
fix(ci): improve pre-commit fmt hook configuration
- Add pass_filenames: false to fmt hook - Add -- separator for cargo fmt args - Manually format code with cargo fmt
Diffstat (limited to 'src-tauri/src/main.rs')
-rw-r--r--src-tauri/src/main.rs230
1 files changed, 163 insertions, 67 deletions
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index 4f9071f..6a230c9 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -296,7 +296,12 @@ async fn start_game(
.as_ref()
.ok_or("Version has no downloads information")?;
let client_jar = &downloads.client;
- let mut client_path = game_dir.join("versions");
+ // Use shared caches for versions if enabled
+ let mut client_path = if config.use_shared_caches {
+ app_handle.path().app_data_dir().unwrap().join("versions")
+ } else {
+ game_dir.join("versions")
+ };
client_path.push(&minecraft_version);
client_path.push(format!("{}.jar", minecraft_version));
@@ -309,11 +314,16 @@ async fn start_game(
// --- Libraries ---
println!("Processing libraries...");
- let libraries_dir = game_dir.join("libraries");
+ // Use shared caches for libraries if enabled
+ let libraries_dir = if config.use_shared_caches {
+ app_handle.path().app_data_dir().unwrap().join("libraries")
+ } else {
+ game_dir.join("libraries")
+ };
let mut native_libs_paths = Vec::new(); // Store paths to native jars for extraction
for lib in &version_details.libraries {
- if core::rules::is_library_allowed(&lib.rules) {
+ if core::rules::is_library_allowed(&lib.rules, Some(&config.feature_flags)) {
// 1. Standard Library - check for explicit downloads first
if let Some(downloads) = &lib.downloads {
if let Some(artifact) = &downloads.artifact {
@@ -336,39 +346,53 @@ async fn start_game(
// 2. Native Library (classifiers)
// e.g. "natives-linux": { ... }
if let Some(classifiers) = &downloads.classifiers {
- // Determine the key based on OS
- // Linux usually "natives-linux", Windows "natives-windows", Mac "natives-osx" (or macos)
- let os_key = if cfg!(target_os = "linux") {
- "natives-linux"
+ // Determine candidate keys based on OS and architecture
+ let arch = std::env::consts::ARCH;
+ let mut candidates: Vec<String> = Vec::new();
+ if cfg!(target_os = "linux") {
+ candidates.push("natives-linux".to_string());
+ candidates.push(format!("natives-linux-{}", arch));
+ if arch == "aarch64" {
+ candidates.push("natives-linux-arm64".to_string());
+ }
} else if cfg!(target_os = "windows") {
- "natives-windows"
+ candidates.push("natives-windows".to_string());
+ candidates.push(format!("natives-windows-{}", arch));
} else if cfg!(target_os = "macos") {
- "natives-osx" // or natives-macos? check json
- } else {
- ""
- };
-
- if let Some(native_artifact_value) = classifiers.get(os_key) {
- // Parse it as DownloadArtifact
- if let Ok(native_artifact) =
- serde_json::from_value::<core::game_version::DownloadArtifact>(
- native_artifact_value.clone(),
- )
- {
- let path_str = native_artifact.path.clone().unwrap(); // Natives usually have path
- let mut native_path = libraries_dir.clone();
- native_path.push(&path_str);
-
- download_tasks.push(core::downloader::DownloadTask {
- url: native_artifact.url,
- path: native_path.clone(),
- sha1: native_artifact.sha1,
- sha256: None,
- });
-
- native_libs_paths.push(native_path);
+ candidates.push("natives-osx".to_string());
+ candidates.push("natives-macos".to_string());
+ candidates.push(format!("natives-macos-{}", arch));
+ }
+
+ // Pick the first available classifier key
+ let mut chosen: Option<core::game_version::DownloadArtifact> = None;
+ for key in candidates {
+ if let Some(native_artifact_value) = classifiers.get(&key) {
+ if let Ok(artifact) =
+ serde_json::from_value::<core::game_version::DownloadArtifact>(
+ native_artifact_value.clone(),
+ )
+ {
+ chosen = Some(artifact);
+ break;
+ }
}
}
+
+ if let Some(native_artifact) = chosen {
+ let path_str = native_artifact.path.clone().unwrap(); // Natives usually have path
+ let mut native_path = libraries_dir.clone();
+ native_path.push(&path_str);
+
+ download_tasks.push(core::downloader::DownloadTask {
+ url: native_artifact.url,
+ path: native_path.clone(),
+ sha1: native_artifact.sha1,
+ sha256: None,
+ });
+
+ native_libs_paths.push(native_path);
+ }
}
} else {
// 3. Library without explicit downloads (mod loader libraries)
@@ -392,7 +416,12 @@ async fn start_game(
// --- Assets ---
println!("Fetching asset index...");
- let assets_dir = game_dir.join("assets");
+ // Use shared caches for assets if enabled
+ let assets_dir = if config.use_shared_caches {
+ app_handle.path().app_data_dir().unwrap().join("assets")
+ } else {
+ game_dir.join("assets")
+ };
let objects_dir = assets_dir.join("objects");
let indexes_dir = assets_dir.join("indexes");
@@ -523,7 +552,7 @@ async fn start_game(
// Add libraries
for lib in &version_details.libraries {
- if core::rules::is_library_allowed(&lib.rules) {
+ if core::rules::is_library_allowed(&lib.rules, Some(&config.feature_flags)) {
if let Some(downloads) = &lib.downloads {
// Standard library with explicit downloads
if let Some(artifact) = &downloads.artifact {
@@ -556,7 +585,13 @@ async fn start_game(
// First add arguments from version.json if available
if let Some(args_obj) = &version_details.arguments {
if let Some(jvm_args) = &args_obj.jvm {
- parse_jvm_arguments(jvm_args, &mut args, &natives_path, &classpath);
+ parse_jvm_arguments(
+ jvm_args,
+ &mut args,
+ &natives_path,
+ &classpath,
+ &config.feature_flags,
+ );
}
}
@@ -588,8 +623,18 @@ async fn start_game(
replacements.insert("${assets_index_name}", asset_index.id.clone());
replacements.insert("${auth_uuid}", account.uuid());
replacements.insert("${auth_access_token}", account.access_token());
- replacements.insert("${user_type}", "mojang".to_string());
- replacements.insert("${version_type}", "release".to_string());
+ // Set user_type dynamically: "msa" for Microsoft accounts, "legacy" for offline
+ let user_type = match &account {
+ core::auth::Account::Microsoft(_) => "msa",
+ core::auth::Account::Offline(_) => "legacy",
+ };
+ replacements.insert("${user_type}", user_type.to_string());
+ // Use version_type from version JSON if available, fallback to "release"
+ let version_type_str = version_details
+ .version_type
+ .clone()
+ .unwrap_or_else(|| "release".to_string());
+ replacements.insert("${version_type}", version_type_str);
replacements.insert("${user_properties}", "{}".to_string()); // Correctly pass empty JSON object for user properties
if let Some(minecraft_arguments) = &version_details.minecraft_arguments {
@@ -622,7 +667,10 @@ async fn start_game(
if let Ok(rules) = serde_json::from_value::<Vec<core::game_version::Rule>>(
rules_val.clone(),
) {
- core::rules::is_library_allowed(&Some(rules))
+ core::rules::is_library_allowed(
+ &Some(rules),
+ Some(&config.feature_flags),
+ )
} else {
true // Parse error, assume allow? or disallow.
}
@@ -815,6 +863,7 @@ fn parse_jvm_arguments(
args: &mut Vec<String>,
natives_path: &str,
classpath: &str,
+ feature_flags: &core::config::FeatureFlags,
) {
let mut replacements = std::collections::HashMap::new();
replacements.insert("${natives_directory}", natives_path.to_string());
@@ -840,7 +889,7 @@ fn parse_jvm_arguments(
if let Ok(rules) =
serde_json::from_value::<Vec<core::game_version::Rule>>(rules_val.clone())
{
- core::rules::is_library_allowed(&Some(rules))
+ core::rules::is_library_allowed(&Some(rules), Some(feature_flags))
} else {
false
}
@@ -1049,7 +1098,17 @@ async fn install_version(
.as_ref()
.ok_or("Version has no downloads information")?;
let client_jar = &downloads.client;
- let mut client_path = game_dir.join("versions");
+ // Use shared caches for versions if enabled
+ let mut client_path = if config.use_shared_caches {
+ window
+ .app_handle()
+ .path()
+ .app_data_dir()
+ .unwrap()
+ .join("versions")
+ } else {
+ game_dir.join("versions")
+ };
client_path.push(&minecraft_version);
client_path.push(format!("{}.jar", minecraft_version));
@@ -1061,10 +1120,20 @@ async fn install_version(
});
// --- Libraries ---
- let libraries_dir = game_dir.join("libraries");
+ // Use shared caches for libraries if enabled
+ let libraries_dir = if config.use_shared_caches {
+ window
+ .app_handle()
+ .path()
+ .app_data_dir()
+ .unwrap()
+ .join("libraries")
+ } else {
+ game_dir.join("libraries")
+ };
for lib in &version_details.libraries {
- if core::rules::is_library_allowed(&lib.rules) {
+ if core::rules::is_library_allowed(&lib.rules, Some(&config.feature_flags)) {
if let Some(downloads) = &lib.downloads {
if let Some(artifact) = &downloads.artifact {
let path_str = artifact
@@ -1085,34 +1154,51 @@ async fn install_version(
// Native Library (classifiers)
if let Some(classifiers) = &downloads.classifiers {
- let os_key = if cfg!(target_os = "linux") {
- "natives-linux"
+ // Determine candidate keys based on OS and architecture
+ let arch = std::env::consts::ARCH;
+ let mut candidates: Vec<String> = Vec::new();
+ if cfg!(target_os = "linux") {
+ candidates.push("natives-linux".to_string());
+ candidates.push(format!("natives-linux-{}", arch));
+ if arch == "aarch64" {
+ candidates.push("natives-linux-arm64".to_string());
+ }
} else if cfg!(target_os = "windows") {
- "natives-windows"
+ candidates.push("natives-windows".to_string());
+ candidates.push(format!("natives-windows-{}", arch));
} else if cfg!(target_os = "macos") {
- "natives-osx"
- } else {
- ""
- };
-
- if let Some(native_artifact_value) = classifiers.get(os_key) {
- if let Ok(native_artifact) =
- serde_json::from_value::<core::game_version::DownloadArtifact>(
- native_artifact_value.clone(),
- )
- {
- let path_str = native_artifact.path.clone().unwrap();
- let mut native_path = libraries_dir.clone();
- native_path.push(&path_str);
-
- download_tasks.push(core::downloader::DownloadTask {
- url: native_artifact.url,
- path: native_path.clone(),
- sha1: native_artifact.sha1,
- sha256: None,
- });
+ candidates.push("natives-osx".to_string());
+ candidates.push("natives-macos".to_string());
+ candidates.push(format!("natives-macos-{}", arch));
+ }
+
+ // Pick the first available classifier key
+ let mut chosen: Option<core::game_version::DownloadArtifact> = None;
+ for key in candidates {
+ if let Some(native_artifact_value) = classifiers.get(&key) {
+ if let Ok(artifact) =
+ serde_json::from_value::<core::game_version::DownloadArtifact>(
+ native_artifact_value.clone(),
+ )
+ {
+ chosen = Some(artifact);
+ break;
+ }
}
}
+
+ if let Some(native_artifact) = chosen {
+ let path_str = native_artifact.path.clone().unwrap();
+ let mut native_path = libraries_dir.clone();
+ native_path.push(&path_str);
+
+ download_tasks.push(core::downloader::DownloadTask {
+ url: native_artifact.url,
+ path: native_path.clone(),
+ sha1: native_artifact.sha1,
+ sha256: None,
+ });
+ }
}
} else {
// Library without explicit downloads (mod loader libraries)
@@ -1134,7 +1220,17 @@ async fn install_version(
}
// --- Assets ---
- let assets_dir = game_dir.join("assets");
+ // Use shared caches for assets if enabled
+ let assets_dir = if config.use_shared_caches {
+ window
+ .app_handle()
+ .path()
+ .app_data_dir()
+ .unwrap()
+ .join("assets")
+ } else {
+ game_dir.join("assets")
+ };
let objects_dir = assets_dir.join("objects");
let indexes_dir = assets_dir.join("indexes");