diff --git a/src-tauri/src/launch/helpers/command_generator.rs b/src-tauri/src/launch/helpers/command_generator.rs index 6c41406d1..83cf1ea58 100644 --- a/src-tauri/src/launch/helpers/command_generator.rs +++ b/src-tauri/src/launch/helpers/command_generator.rs @@ -6,7 +6,7 @@ use crate::instance::helpers::game_version::compare_game_versions; use crate::instance::helpers::misc::get_instance_subdir_paths; use crate::instance::models::misc::{InstanceError, InstanceSubdirType}; use crate::launch::helpers::file_validator::get_nonnative_library_paths; -use crate::launch::helpers::misc::{get_separator, replace_arguments}; +use crate::launch::helpers::misc::{check_virtual_assets, get_separator, replace_arguments}; use crate::launch::models::{LaunchError, LaunchingState}; use crate::launcher_config::models::*; use crate::utils::sys_info::get_memory_info; @@ -23,6 +23,7 @@ use tauri::{AppHandle, Manager}; #[derive(Serialize, Deserialize, Default)] pub struct LaunchArguments { // basic game params + pub game_assets: String, pub assets_root: String, pub assets_index_name: String, pub game_directory: String, @@ -167,8 +168,12 @@ pub async fn generate_launch_command( }; let arguments_value = LaunchArguments { + game_assets: assets_dir + .join("virtual/legacy") + .to_string_lossy() + .to_string(), assets_root: assets_dir.to_string_lossy().to_string(), - assets_index_name: client_info.asset_index.id, + assets_index_name: client_info.asset_index.id.clone(), game_directory: root_dir.to_string_lossy().to_string(), version_name: selected_instance.name.clone(), @@ -353,6 +358,8 @@ pub async fn generate_launch_command( .clone(), ); + check_virtual_assets(root_dir, assets_dir, &client_info.asset_index.id).await?; + if let Some(client_args) = &client_info.arguments { let client_game_args = client_args.to_game_arguments(&launch_feature)?; cmd.extend(replace_arguments(client_game_args, &map)); diff --git a/src-tauri/src/launch/helpers/misc.rs b/src-tauri/src/launch/helpers/misc.rs index 4e603fa33..5f585b873 100644 --- a/src-tauri/src/launch/helpers/misc.rs +++ b/src-tauri/src/launch/helpers/misc.rs @@ -1,6 +1,55 @@ +use futures::future::join_all; use lazy_static; use regex::Regex; use std::collections::HashMap; +use std::path::Path; +use tokio::fs; + +use crate::error::SJMCLResult; +use crate::instance::helpers::asset_index::AssetIndex; +use crate::storage::load_json_async; + +pub async fn check_virtual_assets( + root_dir: &Path, + assets_dir: &Path, + assets_index_name: &str, +) -> SJMCLResult<()> { + if assets_index_name != "legacy" && assets_index_name != "pre-1.6" { + return Ok(()); + } + let asset_index = + load_json_async::(&assets_dir.join(format!("indexes/{}.json", assets_index_name))) + .await?; + + let futs = asset_index + .objects + .into_iter() + .map(|(name, item)| async move { + let path_in_repo = format!("{}/{}", &item.hash[..2], item.hash); + let origin = assets_dir.join(format!("objects/{}", path_in_repo)); + let target = match assets_index_name { + "legacy" => assets_dir.join(format!("virtual/legacy/{}", name)), + "pre-1.6" => root_dir.join(format!("resources/{}", name)), + _ => unreachable!(), + }; + + if fs::try_exists(&origin).await? { + if !fs::try_exists(&target).await? { + copy_with_dirs(&origin, &target).await?; + } + } + Ok(()) + }); + let _: Vec> = join_all(futs).await; + Ok(()) +} + +async fn copy_with_dirs(origin: &Path, target: &Path) -> std::io::Result { + if let Some(parent) = target.parent() { + fs::create_dir_all(parent).await?; + } + fs::copy(origin, target).await +} pub fn replace_arguments(args: Vec, map: &HashMap) -> Vec { lazy_static::lazy_static!(