From 0607ab6a79dcd9291f97d1b728a14ec977543cbc Mon Sep 17 00:00:00 2001 From: 1zuna Date: Wed, 27 Dec 2023 22:57:17 +0100 Subject: [PATCH] integrated custom mod states --- src-tauri/src/app/api.rs | 8 ++++-- src-tauri/src/app/gui.rs | 26 +++++++++-------- src-tauri/src/minecraft/prelauncher.rs | 39 ++++++++++---------------- src/lib/main/MainScreen.svelte | 34 ++++++++++++++-------- 4 files changed, 59 insertions(+), 48 deletions(-) diff --git a/src-tauri/src/app/api.rs b/src-tauri/src/app/api.rs index 190b5b6..2b959d6 100644 --- a/src-tauri/src/app/api.rs +++ b/src-tauri/src/app/api.rs @@ -223,7 +223,7 @@ pub struct LoaderMod { /// /// JSON struct of ModSource (the method to be used for downloading the mod) /// -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] #[serde(tag = "type")] pub enum ModSource { #[serde(rename = "skip")] @@ -232,6 +232,9 @@ pub enum ModSource { #[serde(rename = "repository")] #[serde(rename_all = "camelCase")] Repository { repository: String, artifact: String }, + #[serde(rename = "local")] + #[serde(rename_all = "camelCase")] + Local { file_name: String } } impl ModSource { @@ -239,7 +242,8 @@ impl ModSource { Ok( match self { ModSource::SkipAd { artifact_name, .. } => format!("{}.jar", artifact_name), - ModSource::Repository { repository: _repository, artifact } => get_maven_artifact_path(artifact)? + ModSource::Repository { repository: _repository, artifact } => get_maven_artifact_path(artifact)?, + ModSource::Local { file_name } => file_name.clone(), } ) } diff --git a/src-tauri/src/app/gui.rs b/src-tauri/src/app/gui.rs index c2d98f6..aecfddc 100644 --- a/src-tauri/src/app/gui.rs +++ b/src-tauri/src/app/gui.rs @@ -29,7 +29,7 @@ use crate::{LAUNCHER_DIRECTORY, minecraft::{launcher::{LauncherData, LaunchingPa use crate::app::api::{Branches, Changelog, ContentDelivery, News}; use crate::utils::percentage_of_total_memory; -use super::{api::{ApiEndpoints, Build, LoaderMod}, app_data::LauncherOptions}; +use super::{api::{ApiEndpoints, Build, LoaderMod, ModSource}, app_data::LauncherOptions}; struct RunnerInstance { terminator: tokio::sync::oneshot::Sender<()>, @@ -98,7 +98,7 @@ async fn request_builds(branch: &str) -> Result, String> { } #[tauri::command] -async fn request_mods(mc_version: &str, subsystem: &str) -> Result, String> { +async fn request_mods(branch: &str, mc_version: &str, subsystem: &str) -> Result, String> { let mods = ApiEndpoints::mods(&mc_version, &subsystem) .await .map_err(|e| format!("unable to request mods: {:?}", e))?; @@ -126,7 +126,7 @@ async fn login_microsoft(window: tauri::Window) -> Result Result, String> { +async fn get_custom_mods(branch: &str, mc_version: &str) -> Result, String> { let data = LAUNCHER_DIRECTORY.data_dir(); let mod_cache_path = data.join("custom_mods").join(format!("{}-{}", branch, mc_version)); @@ -138,12 +138,16 @@ async fn get_custom_mods(branch: String, mc_version: String) -> Result Result Result<(), String> { +async fn install_custom_mod(branch: &str, mc_version: &str, path: PathBuf) -> Result<(), String> { let data = LAUNCHER_DIRECTORY.data_dir(); let mod_cache_path = data.join("custom_mods").join(format!("{}-{}", branch, mc_version)); @@ -172,7 +176,7 @@ async fn install_custom_mod(branch: String, mc_version: String, path: PathBuf) - } #[tauri::command] -async fn delete_custom_mod(branch: String, mc_version: String, mod_name: String) -> Result<(), String> { +async fn delete_custom_mod(branch: &str, mc_version: &str, mod_name: &str) -> Result<(), String> { let data = LAUNCHER_DIRECTORY.data_dir(); let mod_cache_path = data.join("custom_mods").join(format!("{}-{}", branch, mc_version)); diff --git a/src-tauri/src/minecraft/prelauncher.rs b/src-tauri/src/minecraft/prelauncher.rs index 3709dff..c4d7461 100644 --- a/src-tauri/src/minecraft/prelauncher.rs +++ b/src-tauri/src/minecraft/prelauncher.rs @@ -59,8 +59,6 @@ pub(crate) async fn launch(launch_manifest: LaunchManifest, laun retrieve_and_copy_mods(&data_directory, &launch_manifest, &launch_manifest.mods, &progress, &window).await?; retrieve_and_copy_mods(&data_directory, &launch_manifest, &additional_mods, &progress, &window).await?; - copy_custom_mods(&data_directory, &launch_manifest, &progress).await?; - info!("Loading version profile..."); let manifest_url = match subsystem { LoaderSubsystem::Fabric { manifest, .. } => manifest @@ -110,10 +108,15 @@ pub(crate) async fn clear_mods(data: &Path, manifest: &LaunchManifest) -> Result pub async fn retrieve_and_copy_mods(data: &Path, manifest: &LaunchManifest, mods: &Vec, progress: &impl ProgressReceiver, window: &Arc>) -> Result<()> { let mod_cache_path = data.join("mod_cache"); - let mods_path = data.join("gameDir").join(&manifest.build.branch).join("mods"); + let mod_custom_path = data.join("custom_mods") + .join(format!("{}-{}", manifest.build.branch, manifest.build.mc_version)); + let mods_path = data.join("gameDir") + .join(&manifest.build.branch) + .join("mods"); fs::create_dir_all(&mod_cache_path).await?; fs::create_dir_all(&mods_path).await?; + fs::create_dir_all(&mod_custom_path).await?; // Download and copy mods let max = get_max(mods.len()); @@ -124,6 +127,13 @@ pub async fn retrieve_and_copy_mods(data: &Path, manifest: &LaunchManifest, mods continue; } + if let ModSource::Local { file_name } = ¤t_mod.source { + // Copy the mod. + fs::copy(mod_custom_path.join(file_name), mods_path.join(file_name)).await?; + progress.progress_update(ProgressUpdate::set_label(format!("Copied custom mod {}", current_mod.name))); + continue; + } + progress.progress_update(ProgressUpdate::set_label(format!("Downloading recommended mod {}", current_mod.name))); let current_mod_path = mod_cache_path.join(current_mod.source.get_path()?); @@ -170,7 +180,8 @@ pub async fn retrieve_and_copy_mods(data: &Path, manifest: &LaunchManifest, mods }).await?; fs::write(¤t_mod_path, retrieved_bytes).await?; - } + }, + _ => warn!("unsupported mod source: {:?}", current_mod.source), } } @@ -181,23 +192,3 @@ pub async fn retrieve_and_copy_mods(data: &Path, manifest: &LaunchManifest, mods Ok(()) } - -pub async fn copy_custom_mods(data: &Path, manifest: &LaunchManifest, progress: &impl ProgressReceiver) -> Result<()> { - let mod_cache_path = data.join("custom_mods").join(format!("{}-{}", manifest.build.branch, manifest.build.mc_version)); - let mods_path = data.join("gameDir").join(&manifest.build.branch).join("mods"); - - fs::create_dir_all(&mod_cache_path).await?; - fs::create_dir_all(&mods_path).await?; - - // Copy all mods from custom_mods to mods - let mut mods_read = fs::read_dir(&mod_cache_path).await?; - while let Some(entry) = mods_read.next_entry().await? { - if entry.file_type().await?.is_file() { - progress.progress_update(ProgressUpdate::set_label(format!("Copied custom mod {}", entry.file_name().to_str().unwrap_or_default()))); - fs::copy(entry.path(), mods_path.join(entry.file_name())).await?; - } - } - - Ok(()) - -} \ No newline at end of file diff --git a/src/lib/main/MainScreen.svelte b/src/lib/main/MainScreen.svelte index dce984d..afc2cbe 100644 --- a/src/lib/main/MainScreen.svelte +++ b/src/lib/main/MainScreen.svelte @@ -91,6 +91,7 @@ let mcVersion = {}; let mods = []; + let customMods = []; /// Request builds from API server function requestBuilds() { @@ -142,11 +143,12 @@ /// Request mods from API server function requestMods(branch, mcVersion, subsystem) { - invoke("request_mods", { mcVersion, subsystem }) + const branchOptions = options.branchOptions[branch]; + + invoke("request_mods", { branch, mcVersion, subsystem }) .then(result => { mods = result; - const branchOptions = options.branchOptions[branch]; if (branchOptions) { mods.forEach(mod => { mod.enabled = branchOptions.modStates[mod.name] ?? mod.enabled; @@ -154,6 +156,19 @@ } }) .catch(e => console.error(e)); + + invoke("get_custom_mods", { branch, mcVersion }) + .then(result => { + console.log("Fetched custom mods", result); + customMods = result; + + if (branchOptions) { + mods.forEach(mod => { + mod.enabled = branchOptions.customModStates[mod.name] ?? mod.enabled; + }); + } + }) + .catch(e => console.error(e)); } // Request branches from API server @@ -192,7 +207,7 @@ let build = getBuild(); console.debug("Running build", build); - await invoke("run_client", { buildId: build.buildId, accountData: options.currentAccount, options: options, mods: mods }); + await invoke("run_client", { buildId: build.buildId, accountData: options.currentAccount, options: options, mods: [...mods, ...customMods] }); } listen("client-exited", () => { @@ -270,20 +285,17 @@ {#each mods as m} - {#if !m.required} - - {/if} - + {/each}
- - - - + + {#each customMods as m} + + {/each}
{/if}