From 8a26011e7699946da4a95bda4270c54110194ec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Gonz=C3=A1lez?= <7822554+AlexTMjugador@users.noreply.github.com> Date: Fri, 13 Jun 2025 22:53:47 +0200 Subject: [PATCH] fix(app): make per-instance launch hooks clearable (#3757) * fix(app): make per-instance launch hooks clearable * chore(apps/app-frontend): fix Prettier lints --- Cargo.lock | 1 + .../ui/instance_settings/HooksSettings.vue | 5 ++--- packages/app-lib/Cargo.toml | 1 + packages/app-lib/src/api/profile/mod.rs | 19 ++++++++++++++----- packages/app-lib/src/launcher/mod.rs | 12 ++++++++---- packages/app-lib/src/state/settings.rs | 4 ++++ packages/app-lib/src/util/mod.rs | 12 ------------ 7 files changed, 30 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9cb8f0a1..2a1c0c54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8903,6 +8903,7 @@ dependencies = [ "serde", "serde_ini", "serde_json", + "serde_with", "sha1_smol", "sha2", "sqlx", diff --git a/apps/app-frontend/src/components/ui/instance_settings/HooksSettings.vue b/apps/app-frontend/src/components/ui/instance_settings/HooksSettings.vue index 13be55ce..c7de8bec 100644 --- a/apps/app-frontend/src/components/ui/instance_settings/HooksSettings.vue +++ b/apps/app-frontend/src/components/ui/instance_settings/HooksSettings.vue @@ -25,9 +25,8 @@ const editProfileObject = computed(() => { hooks?: Hooks } = {} - if (overrideHooks.value) { - editProfile.hooks = hooks.value - } + // When hooks are not overridden per-instance, we want to clear them + editProfile.hooks = overrideHooks.value ? hooks.value : {} return editProfile }) diff --git a/packages/app-lib/Cargo.toml b/packages/app-lib/Cargo.toml index 78f004a7..4f76e24a 100644 --- a/packages/app-lib/Cargo.toml +++ b/packages/app-lib/Cargo.toml @@ -9,6 +9,7 @@ bytes.workspace = true serde = { workspace = true, features = ["derive"] } serde_json.workspace = true serde_ini.workspace = true +serde_with.workspace = true sha1_smol.workspace = true sha2.workspace = true url = { workspace = true, features = ["serde"] } diff --git a/packages/app-lib/src/api/profile/mod.rs b/packages/app-lib/src/api/profile/mod.rs index b1c21207..995170ee 100644 --- a/packages/app-lib/src/api/profile/mod.rs +++ b/packages/app-lib/src/api/profile/mod.rs @@ -644,7 +644,6 @@ pub async fn run( /// Run Minecraft using a profile, and credentials for authentication /// Returns Arc pointer to RwLock to Child #[tracing::instrument(skip(credentials))] - pub async fn run_credentials( path: &str, credentials: &Credentials, @@ -662,7 +661,8 @@ pub async fn run_credentials( .hooks .pre_launch .as_ref() - .or(settings.hooks.pre_launch.as_ref()); + .or(settings.hooks.pre_launch.as_ref()) + .filter(|hook_command| !hook_command.is_empty()); if let Some(hook) = pre_launch_hooks { // TODO: hook parameters let mut cmd = hook.split(' '); @@ -692,7 +692,12 @@ pub async fn run_credentials( .clone() .unwrap_or(settings.extra_launch_args); - let wrapper = profile.hooks.wrapper.clone().or(settings.hooks.wrapper); + let wrapper = profile + .hooks + .wrapper + .clone() + .or(settings.hooks.wrapper) + .filter(|hook_command| !hook_command.is_empty()); let memory = profile.memory.unwrap_or(settings.memory); let resolution = @@ -704,8 +709,12 @@ pub async fn run_credentials( .unwrap_or(settings.custom_env_vars); // Post post exit hooks - let post_exit_hook = - profile.hooks.post_exit.clone().or(settings.hooks.post_exit); + let post_exit_hook = profile + .hooks + .post_exit + .clone() + .or(settings.hooks.post_exit) + .filter(|hook_command| !hook_command.is_empty()); // Any options.txt settings that we want set, add here let mut mc_set_options: Vec<(String, String)> = vec![]; diff --git a/packages/app-lib/src/launcher/mod.rs b/packages/app-lib/src/launcher/mod.rs index fafcbee2..d38ad38f 100644 --- a/packages/app-lib/src/launcher/mod.rs +++ b/packages/app-lib/src/launcher/mod.rs @@ -353,9 +353,11 @@ pub async fn install_minecraft( } } - let cp = wrap_ref_builder!(cp = processor.classpath.clone() => { - cp.push(processor.jar.clone()) - }); + let cp = { + let mut cp = processor.classpath.clone(); + cp.push(processor.jar.clone()); + cp + }; let child = Command::new(&java_version.path) .arg("-cp") @@ -578,7 +580,9 @@ pub async fn launch_minecraft( let args = version_info.arguments.clone().unwrap_or_default(); let mut command = match wrapper { Some(hook) => { - wrap_ref_builder!(it = Command::new(hook) => {it.arg(&java_version.path)}) + let mut command = Command::new(hook); + command.arg(&java_version.path); + command } None => Command::new(&java_version.path), }; diff --git a/packages/app-lib/src/state/settings.rs b/packages/app-lib/src/state/settings.rs index 89d7bc04..90d48028 100644 --- a/packages/app-lib/src/state/settings.rs +++ b/packages/app-lib/src/state/settings.rs @@ -247,9 +247,13 @@ pub struct WindowSize(pub u16, pub u16); /// Game initialization hooks #[derive(Serialize, Deserialize, Debug, Clone)] +#[serde_with::serde_as] pub struct Hooks { + #[serde_as(as = "serde_with::NoneAsEmptyString")] pub pre_launch: Option, + #[serde_as(as = "serde_with::NoneAsEmptyString")] pub wrapper: Option, + #[serde_as(as = "serde_with::NoneAsEmptyString")] pub post_exit: Option, } diff --git a/packages/app-lib/src/util/mod.rs b/packages/app-lib/src/util/mod.rs index 5a310291..492ffbe8 100644 --- a/packages/app-lib/src/util/mod.rs +++ b/packages/app-lib/src/util/mod.rs @@ -4,15 +4,3 @@ pub mod io; pub mod jre; pub mod platform; pub mod server_ping; - -/// Wrap a builder which uses a mut reference into one which outputs an owned value -macro_rules! wrap_ref_builder { - ($id:ident = $init:expr => $transform:block) => {{ - let mut it = $init; - { - let $id = &mut it; - $transform; - } - it - }}; -}