mirror of
https://github.com/ow-mods/ow-mod-man.git
synced 2025-12-11 20:15:50 +01:00
[ALL] Add Prepatcher Warning
This commit is contained in:
parent
19dfbb800a
commit
606f366d78
@ -1,2 +1,4 @@
|
|||||||
[alias]
|
[alias]
|
||||||
xtask = "run --package xtask --"
|
xtask = "run --package xtask --"
|
||||||
|
lint = "clippy --all-targets -- -D warnings"
|
||||||
|
|
||||||
|
|||||||
@ -306,12 +306,21 @@ async fn run_from_cli(cli: BaseCli) -> Result<()> {
|
|||||||
Commands::Enable { unique_name } | Commands::Disable { unique_name } => {
|
Commands::Enable { unique_name } | Commands::Disable { unique_name } => {
|
||||||
let db = LocalDatabase::fetch(&config.owml_path)?;
|
let db = LocalDatabase::fetch(&config.owml_path)?;
|
||||||
let enable = matches!(cli.command, Commands::Enable { unique_name: _ });
|
let enable = matches!(cli.command, Commands::Enable { unique_name: _ });
|
||||||
|
let mut show_warnings_for: Vec<String> = vec![];
|
||||||
if unique_name == "*" || unique_name == "all" {
|
if unique_name == "*" || unique_name == "all" {
|
||||||
for local_mod in db.valid() {
|
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 {
|
} 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 } => {
|
Commands::LogServer { port } => {
|
||||||
|
|||||||
@ -17,6 +17,12 @@ pub struct LocalMod {
|
|||||||
pub manifest: ModManifest,
|
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
|
/// Represents a mod that completely failed to load
|
||||||
#[typeshare]
|
#[typeshare]
|
||||||
#[derive(Serialize, Clone)]
|
#[derive(Serialize, Clone)]
|
||||||
@ -157,6 +163,7 @@ pub struct ModManifest {
|
|||||||
pub conflicts: Option<Vec<String>>,
|
pub conflicts: Option<Vec<String>>,
|
||||||
pub paths_to_preserve: Option<Vec<String>>,
|
pub paths_to_preserve: Option<Vec<String>>,
|
||||||
pub warning: Option<ModWarning>,
|
pub warning: Option<ModWarning>,
|
||||||
|
pub patcher: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a warning a mod wants to show to the user on start
|
/// Represents a warning a mod wants to show to the user on start
|
||||||
|
|||||||
@ -56,6 +56,11 @@ pub fn get_mod_enabled(mod_path: &Path) -> Result<bool> {
|
|||||||
/// Toggle a mod to a given enabled value.
|
/// Toggle a mod to a given enabled value.
|
||||||
/// Also support applying this action recursively.
|
/// 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
|
/// ## Errors
|
||||||
///
|
///
|
||||||
/// If we can't read/save to the config files of the mod or (if recursive is true) any of it's dependents.
|
/// 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,
|
local_db: &LocalDatabase,
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
recursive: bool,
|
recursive: bool,
|
||||||
) -> Result<()> {
|
) -> Result<Vec<String>> {
|
||||||
|
let mut show_warnings_for: Vec<String> = vec![];
|
||||||
|
|
||||||
let local_mod = local_db
|
let local_mod = local_db
|
||||||
.get_mod(unique_name)
|
.get_mod(unique_name)
|
||||||
.ok_or_else(|| anyhow!("Mod {} not found", unique_name))?;
|
.ok_or_else(|| anyhow!("Mod {} not found", unique_name))?;
|
||||||
let config_path = PathBuf::from(&local_mod.mod_path).join("config.json");
|
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() {
|
if config_path.is_file() {
|
||||||
let mut config = read_config(&config_path)?;
|
let mut config = read_config(&config_path)?;
|
||||||
config.enabled = enabled;
|
config.enabled = enabled;
|
||||||
write_config(&config, &config_path)?;
|
write_config(&config, &config_path)?;
|
||||||
} else {
|
} else {
|
||||||
generate_config(&config_path)?;
|
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 recursive {
|
||||||
if let Some(deps) = local_mod.manifest.dependencies.as_ref() {
|
if let Some(deps) = local_mod.manifest.dependencies.as_ref() {
|
||||||
for dep in deps.iter() {
|
for dep in deps.iter() {
|
||||||
@ -98,12 +111,12 @@ pub fn toggle_mod(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if flag {
|
if flag {
|
||||||
toggle_mod(
|
show_warnings_for.extend(toggle_mod(
|
||||||
&dep_mod.manifest.unique_name,
|
&dep_mod.manifest.unique_name,
|
||||||
local_db,
|
local_db,
|
||||||
enabled,
|
enabled,
|
||||||
recursive,
|
recursive,
|
||||||
)?;
|
)?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -112,7 +125,7 @@ pub fn toggle_mod(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(show_warnings_for)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@ -208,24 +208,25 @@ pub async fn toggle_mod(
|
|||||||
unique_name: &str,
|
unique_name: &str,
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
state: tauri::State<'_, State>,
|
state: tauri::State<'_, State>,
|
||||||
) -> Result {
|
) -> Result<Vec<String>> {
|
||||||
let db = state.local_db.read().await;
|
let db = state.local_db.read().await;
|
||||||
owmods_core::toggle::toggle_mod(unique_name, &db, enabled, false)?;
|
let show_warnings_for = owmods_core::toggle::toggle_mod(unique_name, &db, enabled, false)?;
|
||||||
Ok(())
|
Ok(show_warnings_for)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[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<Vec<String>> {
|
||||||
let local_db = state.local_db.read().await;
|
let local_db = state.local_db.read().await;
|
||||||
|
let mut show_warnings_for: Vec<String> = vec![];
|
||||||
for local_mod in local_db.valid() {
|
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_mod.manifest.unique_name,
|
||||||
&local_db,
|
&local_db,
|
||||||
enabled,
|
enabled,
|
||||||
false,
|
false,
|
||||||
)?;
|
)?);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(show_warnings_for)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
|||||||
@ -77,6 +77,8 @@
|
|||||||
"Outdated": "This mod is outdated, consider updating (latest version is v$payload$)",
|
"Outdated": "This mod is outdated, consider updating (latest version is v$payload$)",
|
||||||
"PLATFORM": "Platform: $platform$",
|
"PLATFORM": "Platform: $platform$",
|
||||||
"PRERELEASE_WARNING": "Prereleases are experimental versions of mods that may not work correctly. Are you sure you want to install?",
|
"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",
|
"Pink": "Pink",
|
||||||
"Purple": "Purple",
|
"Purple": "Purple",
|
||||||
"RAINBOW": "Rainbow Mode",
|
"RAINBOW": "Rainbow Mode",
|
||||||
|
|||||||
@ -37,8 +37,8 @@ const commandInfo = {
|
|||||||
getLocalMod: $<ModCommand<UnsafeLocalMod>>("get_local_mod"),
|
getLocalMod: $<ModCommand<UnsafeLocalMod>>("get_local_mod"),
|
||||||
getRemoteMod: $<ModCommand<RemoteMod>>("get_remote_mod"),
|
getRemoteMod: $<ModCommand<RemoteMod>>("get_remote_mod"),
|
||||||
getLogLine: $<CommandInfo<{ port: number; line: number }, GameMessage>>("get_game_message"),
|
getLogLine: $<CommandInfo<{ port: number; line: number }, GameMessage>>("get_game_message"),
|
||||||
toggleMod: $<ActionCommand<{ uniqueName: string; enabled: boolean }>>("toggle_mod"),
|
toggleMod: $<CommandInfo<{ uniqueName: string; enabled: boolean }, string[]>>("toggle_mod"),
|
||||||
toggleAll: $<ActionCommand<{ enabled: boolean }>>("toggle_all"),
|
toggleAll: $<CommandInfo<{ enabled: boolean }, string[]>>("toggle_all"),
|
||||||
openModFolder: $<ModAction>("open_mod_folder"),
|
openModFolder: $<ModAction>("open_mod_folder"),
|
||||||
openModReadme: $<ModAction>("open_mod_readme"),
|
openModReadme: $<ModAction>("open_mod_readme"),
|
||||||
uninstallMod: $<ModAction>("uninstall_mod"),
|
uninstallMod: $<ModAction>("uninstall_mod"),
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import ModValidationModal, {
|
|||||||
import { useGetTranslation } from "@hooks";
|
import { useGetTranslation } from "@hooks";
|
||||||
import { memo, useCallback, useEffect, useRef, useState } from "react";
|
import { memo, useCallback, useEffect, useRef, useState } from "react";
|
||||||
import UnsafeModRow from "./UnsafeModRow";
|
import UnsafeModRow from "./UnsafeModRow";
|
||||||
|
import { dialog } from "@tauri-apps/api";
|
||||||
|
|
||||||
const LocalMods = memo(function LocalMods() {
|
const LocalMods = memo(function LocalMods() {
|
||||||
const validationModalRef = useRef<ModValidationModalHandle>();
|
const validationModalRef = useRef<ModValidationModalHandle>();
|
||||||
@ -20,12 +21,23 @@ const LocalMods = memo(function LocalMods() {
|
|||||||
commands.refreshLocalDb();
|
commands.refreshLocalDb();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onToggleAll = useCallback((enabled: boolean) => {
|
const onToggleAll = useCallback(
|
||||||
|
(enabled: boolean) => {
|
||||||
commands
|
commands
|
||||||
.toggleAll({ enabled })
|
.toggleAll({ enabled })
|
||||||
.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 })
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
.catch(console.warn);
|
.catch(console.warn);
|
||||||
}, []);
|
},
|
||||||
|
[getTranslation]
|
||||||
|
);
|
||||||
|
|
||||||
const onSearch = (newFilter: string) => {
|
const onSearch = (newFilter: string) => {
|
||||||
if (activeTimeout !== null) {
|
if (activeTimeout !== null) {
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import { confirm } from "@tauri-apps/api/dialog";
|
|||||||
import { LocalMod, ModValidationError } from "@types";
|
import { LocalMod, ModValidationError } from "@types";
|
||||||
import { memo, useCallback } from "react";
|
import { memo, useCallback } from "react";
|
||||||
import LocalModRow from "./LocalModRow";
|
import LocalModRow from "./LocalModRow";
|
||||||
|
import { dialog } from "@tauri-apps/api";
|
||||||
|
|
||||||
interface LocalModRowProps {
|
interface LocalModRowProps {
|
||||||
mod: LocalMod;
|
mod: LocalMod;
|
||||||
@ -45,9 +46,17 @@ const ValidModRow = memo(function ValidModRow({ mod, onValidationClick }: LocalM
|
|||||||
uniqueName: mod.manifest.uniqueName,
|
uniqueName: mod.manifest.uniqueName,
|
||||||
enabled: newVal
|
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(() => {
|
const onOpen = useCallback(() => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user