From 606f366d7810022170c3fcc3642a3135b5f3deaf Mon Sep 17 00:00:00 2001 From: Ben C Date: Sat, 13 May 2023 18:55:59 -0400 Subject: [PATCH] [ALL] Add Prepatcher Warning --- .cargo/config.toml | 4 +++- owmods_cli/src/main.rs | 13 ++++++++-- owmods_core/src/mods/local.rs | 7 ++++++ owmods_core/src/toggle.rs | 23 ++++++++++++++---- owmods_gui/backend/src/commands.rs | 15 ++++++------ .../src/assets/translations/english.json | 2 ++ owmods_gui/frontend/src/commands.ts | 4 ++-- .../src/components/mods/local/LocalMods.tsx | 24 ++++++++++++++----- .../src/components/mods/local/ValidModRow.tsx | 13 ++++++++-- 9 files changed, 80 insertions(+), 25 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index f0ccbc9a..be2f5026 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,2 +1,4 @@ [alias] -xtask = "run --package xtask --" \ No newline at end of file +xtask = "run --package xtask --" +lint = "clippy --all-targets -- -D warnings" + diff --git a/owmods_cli/src/main.rs b/owmods_cli/src/main.rs index ed0b2992..06cf0ba0 100644 --- a/owmods_cli/src/main.rs +++ b/owmods_cli/src/main.rs @@ -306,12 +306,21 @@ async fn run_from_cli(cli: BaseCli) -> Result<()> { Commands::Enable { unique_name } | Commands::Disable { unique_name } => { let db = LocalDatabase::fetch(&config.owml_path)?; let enable = matches!(cli.command, Commands::Enable { unique_name: _ }); + let mut show_warnings_for: Vec = vec![]; if unique_name == "*" || unique_name == "all" { for local_mod in db.valid() { - toggle_mod(&local_mod.manifest.unique_name, &db, enable, false)?; + show_warnings_for.extend(toggle_mod( + &local_mod.manifest.unique_name, + &db, + enable, + false, + )?); } } else { - toggle_mod(unique_name, &db, enable, r)?; + show_warnings_for = toggle_mod(unique_name, &db, enable, r)?; + } + for mod_name in show_warnings_for { + warn!("========\n{mod_name} possibly modified game files.\nIn order to disable it completely, use the \"verify game files\" option in Steam / Epic.\nCheck {mod_name}'s readme for more information.\n========") } } Commands::LogServer { port } => { diff --git a/owmods_core/src/mods/local.rs b/owmods_core/src/mods/local.rs index 33e84396..d76c139c 100644 --- a/owmods_core/src/mods/local.rs +++ b/owmods_core/src/mods/local.rs @@ -17,6 +17,12 @@ pub struct LocalMod { pub manifest: ModManifest, } +impl LocalMod { + pub fn uses_pre_patcher(&self) -> bool { + self.manifest.patcher.is_some() + } +} + /// Represents a mod that completely failed to load #[typeshare] #[derive(Serialize, Clone)] @@ -157,6 +163,7 @@ pub struct ModManifest { pub conflicts: Option>, pub paths_to_preserve: Option>, pub warning: Option, + pub patcher: Option, } /// Represents a warning a mod wants to show to the user on start diff --git a/owmods_core/src/toggle.rs b/owmods_core/src/toggle.rs index d979c338..e605be6e 100644 --- a/owmods_core/src/toggle.rs +++ b/owmods_core/src/toggle.rs @@ -56,6 +56,11 @@ pub fn get_mod_enabled(mod_path: &Path) -> Result { /// Toggle a mod to a given enabled value. /// Also support applying this action recursively. /// +/// +/// ## Returns +/// +/// A list of mod names that were disabled and use pre patchers, and therefore **should alert the user to check the mod's README for instructions on how to fully disable it**. +/// /// ## Errors /// /// If we can't read/save to the config files of the mod or (if recursive is true) any of it's dependents. @@ -65,19 +70,27 @@ pub fn toggle_mod( local_db: &LocalDatabase, enabled: bool, recursive: bool, -) -> Result<()> { +) -> Result> { + let mut show_warnings_for: Vec = vec![]; + let local_mod = local_db .get_mod(unique_name) .ok_or_else(|| anyhow!("Mod {} not found", unique_name))?; let config_path = PathBuf::from(&local_mod.mod_path).join("config.json"); + + if !enabled && local_mod.uses_pre_patcher() { + show_warnings_for.push(local_mod.manifest.name.clone()); + } + if config_path.is_file() { let mut config = read_config(&config_path)?; config.enabled = enabled; write_config(&config, &config_path)?; } else { generate_config(&config_path)?; - toggle_mod(unique_name, local_db, enabled, recursive)?; + show_warnings_for.extend(toggle_mod(unique_name, local_db, enabled, recursive)?); } + if recursive { if let Some(deps) = local_mod.manifest.dependencies.as_ref() { for dep in deps.iter() { @@ -98,12 +111,12 @@ pub fn toggle_mod( } } if flag { - toggle_mod( + show_warnings_for.extend(toggle_mod( &dep_mod.manifest.unique_name, local_db, enabled, recursive, - )?; + )?); } } } else { @@ -112,7 +125,7 @@ pub fn toggle_mod( } } } - Ok(()) + Ok(show_warnings_for) } #[cfg(test)] diff --git a/owmods_gui/backend/src/commands.rs b/owmods_gui/backend/src/commands.rs index d0aa4039..9425960a 100644 --- a/owmods_gui/backend/src/commands.rs +++ b/owmods_gui/backend/src/commands.rs @@ -208,24 +208,25 @@ pub async fn toggle_mod( unique_name: &str, enabled: bool, state: tauri::State<'_, State>, -) -> Result { +) -> Result> { let db = state.local_db.read().await; - owmods_core::toggle::toggle_mod(unique_name, &db, enabled, false)?; - Ok(()) + let show_warnings_for = owmods_core::toggle::toggle_mod(unique_name, &db, enabled, false)?; + Ok(show_warnings_for) } #[tauri::command] -pub async fn toggle_all(enabled: bool, state: tauri::State<'_, State>) -> Result { +pub async fn toggle_all(enabled: bool, state: tauri::State<'_, State>) -> Result> { let local_db = state.local_db.read().await; + let mut show_warnings_for: Vec = vec![]; for local_mod in local_db.valid() { - owmods_core::toggle::toggle_mod( + show_warnings_for.extend(owmods_core::toggle::toggle_mod( &local_mod.manifest.unique_name, &local_db, enabled, false, - )?; + )?); } - Ok(()) + Ok(show_warnings_for) } #[tauri::command] diff --git a/owmods_gui/frontend/src/assets/translations/english.json b/owmods_gui/frontend/src/assets/translations/english.json index 41c3c801..4a2f6736 100644 --- a/owmods_gui/frontend/src/assets/translations/english.json +++ b/owmods_gui/frontend/src/assets/translations/english.json @@ -77,6 +77,8 @@ "Outdated": "This mod is outdated, consider updating (latest version is v$payload$)", "PLATFORM": "Platform: $platform$", "PRERELEASE_WARNING": "Prereleases are experimental versions of mods that may not work correctly. Are you sure you want to install?", + "PREPATCHER_WARNING": "$name$ possibly modified game files. In order to disable it completely, use the \"verify game files\" option in Steam / Epic. Check $name$'s readme for more information.", + "PREPATCHER_WARNING_TITLE": "Warning for $name$", "Pink": "Pink", "Purple": "Purple", "RAINBOW": "Rainbow Mode", diff --git a/owmods_gui/frontend/src/commands.ts b/owmods_gui/frontend/src/commands.ts index e5f5a7d5..1dc50c51 100644 --- a/owmods_gui/frontend/src/commands.ts +++ b/owmods_gui/frontend/src/commands.ts @@ -37,8 +37,8 @@ const commandInfo = { getLocalMod: $>("get_local_mod"), getRemoteMod: $>("get_remote_mod"), getLogLine: $>("get_game_message"), - toggleMod: $>("toggle_mod"), - toggleAll: $>("toggle_all"), + toggleMod: $>("toggle_mod"), + toggleAll: $>("toggle_all"), openModFolder: $("open_mod_folder"), openModReadme: $("open_mod_readme"), uninstallMod: $("uninstall_mod"), diff --git a/owmods_gui/frontend/src/components/mods/local/LocalMods.tsx b/owmods_gui/frontend/src/components/mods/local/LocalMods.tsx index 03866102..ba428756 100644 --- a/owmods_gui/frontend/src/components/mods/local/LocalMods.tsx +++ b/owmods_gui/frontend/src/components/mods/local/LocalMods.tsx @@ -7,6 +7,7 @@ import ModValidationModal, { import { useGetTranslation } from "@hooks"; import { memo, useCallback, useEffect, useRef, useState } from "react"; import UnsafeModRow from "./UnsafeModRow"; +import { dialog } from "@tauri-apps/api"; const LocalMods = memo(function LocalMods() { const validationModalRef = useRef(); @@ -20,12 +21,23 @@ const LocalMods = memo(function LocalMods() { commands.refreshLocalDb(); }, []); - const onToggleAll = useCallback((enabled: boolean) => { - commands - .toggleAll({ enabled }) - .then(() => commands.refreshLocalDb()) - .catch(console.warn); - }, []); + const onToggleAll = useCallback( + (enabled: boolean) => { + commands + .toggleAll({ enabled }) + .then((warnings) => { + commands.refreshLocalDb(); + for (const modName of warnings) { + dialog.message(getTranslation("PREPATCHER_WARNING", { name: modName }), { + type: "warning", + title: getTranslation("PREPATCHER_WARNING_TITLE", { name: modName }) + }); + } + }) + .catch(console.warn); + }, + [getTranslation] + ); const onSearch = (newFilter: string) => { if (activeTimeout !== null) { diff --git a/owmods_gui/frontend/src/components/mods/local/ValidModRow.tsx b/owmods_gui/frontend/src/components/mods/local/ValidModRow.tsx index dbfd9747..7dc4ed6e 100644 --- a/owmods_gui/frontend/src/components/mods/local/ValidModRow.tsx +++ b/owmods_gui/frontend/src/components/mods/local/ValidModRow.tsx @@ -5,6 +5,7 @@ import { confirm } from "@tauri-apps/api/dialog"; import { LocalMod, ModValidationError } from "@types"; import { memo, useCallback } from "react"; import LocalModRow from "./LocalModRow"; +import { dialog } from "@tauri-apps/api"; interface LocalModRowProps { mod: LocalMod; @@ -45,9 +46,17 @@ const ValidModRow = memo(function ValidModRow({ mod, onValidationClick }: LocalM uniqueName: mod.manifest.uniqueName, enabled: newVal }) - .then(() => commands.refreshLocalDb()); + .then((warnings) => { + commands.refreshLocalDb(); + for (const modName of warnings) { + dialog.message(getTranslation("PREPATCHER_WARNING", { name: modName }), { + type: "warning", + title: getTranslation("PREPATCHER_WARNING_TITLE", { name: modName }) + }); + } + }); }, - [mod.manifest.uniqueName] + [mod.manifest.uniqueName, getTranslation] ); const onOpen = useCallback(() => {