mirror of
https://github.com/ow-mods/ow-mod-man.git
synced 2025-12-11 20:15:50 +01:00
[CORE] More doc comments
This commit is contained in:
parent
a5420a6948
commit
e8748676a2
@ -18,10 +18,15 @@ use crate::{
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Config {
|
||||
/// The path to the OWML install, defaults to `~/.local/share/OuterWildsModManager/OWML`
|
||||
pub owml_path: String,
|
||||
/// The URL to the database
|
||||
pub database_url: String,
|
||||
/// The URL to fetch alerts from
|
||||
pub alert_url: String,
|
||||
/// The mod warnings that have been shown to the user
|
||||
pub viewed_alerts: Vec<String>,
|
||||
/// Where the config is saved, this is not serialized
|
||||
#[serde(skip)]
|
||||
pub path: PathBuf,
|
||||
}
|
||||
|
||||
@ -1,14 +1,37 @@
|
||||
/// OWML is considered a mod in the remote database, this is its unique name
|
||||
pub const OWML_UNIQUE_NAME: &str = "Alek.OWML";
|
||||
|
||||
/// The default URL to the database
|
||||
pub const DEFAULT_DB_URL: &str = "https://ow-mods.github.io/ow-mod-db/database.json";
|
||||
|
||||
/// The URL used by the old manager to fetch alerts, this is here so we can migrate users to the new alert system
|
||||
pub const OLD_ALERT_URL: &str =
|
||||
"https://raw.githubusercontent.com/ow-mods/ow-mod-db/source/alert.json";
|
||||
|
||||
/// The default URL to fetch alerts from
|
||||
pub const DEFAULT_ALERT_URL: &str =
|
||||
"https://raw.githubusercontent.com/ow-mods/ow-mod-db/source/alert-v2.json";
|
||||
|
||||
/// The name of the config file
|
||||
pub const CONFIG_FILE_NAME: &str = "settings.json";
|
||||
|
||||
/// The URL to the repository for the mod database
|
||||
pub const DB_REPO_URL: &str = "https://github.com/ow-mods/ow-mod-db";
|
||||
|
||||
/// The URL to the documentation for OWML
|
||||
pub const OWML_DOCS_URL: &str = "https://owml.outerwildsmods.com";
|
||||
|
||||
/// The name of OWML's manifest file
|
||||
pub const OWML_MANIFEST_NAME: &str = "OWML.Manifest.json";
|
||||
|
||||
/// The name of OWML's default config file
|
||||
pub const OWML_DEFAULT_CONFIG_NAME: &str = "OWML.DefaultConfig.json";
|
||||
|
||||
/// The name of OWML's launcher exe
|
||||
pub const OWML_EXE_NAME: &str = "OWML.Launcher.exe";
|
||||
|
||||
/// The URL to the website
|
||||
pub const WEBSITE_URL: &str = "https://outerwildsmods.com";
|
||||
|
||||
/// The name of the old manager folder, the new manager uses the OWML installation here to make migration easier
|
||||
pub const OLD_MANAGER_FOLDER_NAME: &str = "OuterWildsModManager";
|
||||
|
||||
@ -20,6 +20,7 @@ use super::{fix_version, RemoteDatabase};
|
||||
/// Represents the local (on the local PC) database of mods.
|
||||
#[derive(Default, Clone)]
|
||||
pub struct LocalDatabase {
|
||||
/// A hashmap of unique names to mods
|
||||
pub mods: HashMap<String, UnsafeLocalMod>,
|
||||
}
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@ struct RawRemoteDatabase {
|
||||
/// Represents the remote (on the website) database of mods.
|
||||
#[derive(Default, Clone)]
|
||||
pub struct RemoteDatabase {
|
||||
/// A hashmap of unique names to mods
|
||||
pub mods: HashMap<String, RemoteMod>,
|
||||
}
|
||||
|
||||
@ -149,6 +150,7 @@ impl RemoteDatabase {
|
||||
tag_counts.into_iter().map(|i| i.0).rev().collect()
|
||||
}
|
||||
|
||||
/// Filter a list of mods by a list of tags
|
||||
pub fn filter_by_tags<'a>(
|
||||
mods: impl Iterator<Item = &'a RemoteMod>,
|
||||
tags: Vec<String>,
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#![doc(
|
||||
html_logo_url = "https://github.com/ow-mods/ow-mod-man/blob/main/.github/assets/logo-core.png?raw=true"
|
||||
)]
|
||||
#![deny(missing_docs)]
|
||||
|
||||
/// Fetch database alerts and get mod warnings.
|
||||
pub mod alerts;
|
||||
|
||||
@ -11,13 +11,18 @@ use crate::{search::Searchable, validate::ModValidationError};
|
||||
#[derive(Clone, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct LocalMod {
|
||||
/// Whether the mod is enabled
|
||||
pub enabled: bool,
|
||||
/// Any non-critical errors that occurred when loading the mod
|
||||
pub errors: Vec<ModValidationError>,
|
||||
/// The path to the mod
|
||||
pub mod_path: String,
|
||||
/// The manifest for the mod
|
||||
pub manifest: ModManifest,
|
||||
}
|
||||
|
||||
impl LocalMod {
|
||||
/// Determines if a mod uses a prepatcher
|
||||
pub fn uses_pre_patcher(&self) -> bool {
|
||||
self.manifest.patcher.is_some()
|
||||
}
|
||||
@ -28,8 +33,11 @@ impl LocalMod {
|
||||
#[derive(Serialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct FailedMod {
|
||||
/// The error that caused the mod to fail to load
|
||||
pub error: ModValidationError,
|
||||
/// The path to the mod
|
||||
pub mod_path: String,
|
||||
/// The path to the mod relative to the mods folder, this usually will match the unique name so it's good for display
|
||||
pub display_path: String,
|
||||
}
|
||||
|
||||
@ -39,7 +47,9 @@ pub struct FailedMod {
|
||||
#[serde(tag = "loadState", content = "mod", rename_all = "camelCase")]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
pub enum UnsafeLocalMod {
|
||||
/// A mod was loaded successfully
|
||||
Valid(LocalMod),
|
||||
/// A mod failed to load
|
||||
Invalid(FailedMod),
|
||||
}
|
||||
|
||||
@ -154,16 +164,27 @@ pub fn get_paths_to_preserve(local_mod: Option<&LocalMod>) -> Vec<PathBuf> {
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ModManifest {
|
||||
/// The unique name of the mod
|
||||
pub unique_name: String,
|
||||
/// The name of the mod
|
||||
pub name: String,
|
||||
/// The author of the mod
|
||||
pub author: String,
|
||||
/// The version of the mod, usually in the format `major.minor.patch`
|
||||
pub version: String,
|
||||
/// The name of the DLL file to load when starting the mod
|
||||
pub filename: Option<String>,
|
||||
/// The version of OWML this mod was built for
|
||||
pub owml_version: Option<String>,
|
||||
/// The dependencies of the mod
|
||||
pub dependencies: Option<Vec<String>>,
|
||||
/// The mods this mod will conflict with
|
||||
pub conflicts: Option<Vec<String>>,
|
||||
/// The paths to preserve when updating the mod
|
||||
pub paths_to_preserve: Option<Vec<String>>,
|
||||
/// A warning the mod wants to show to the user on start
|
||||
pub warning: Option<ModWarning>,
|
||||
/// An exe that runs before the game starts, a prepatcher. This is used for mods that need to patch the game before it starts
|
||||
pub patcher: Option<String>,
|
||||
}
|
||||
|
||||
@ -172,14 +193,18 @@ pub struct ModManifest {
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ModWarning {
|
||||
/// The title of the warning
|
||||
pub title: String,
|
||||
/// The body of the warning
|
||||
pub body: String,
|
||||
}
|
||||
|
||||
/// Represents a configuration file for a mod
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct ModStubConfig {
|
||||
/// Whether the mod is enabled
|
||||
pub enabled: bool,
|
||||
/// The settings for the mod, this is kept in a Map because the manager doesn't touch it
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub settings: Option<Map<String, Value>>,
|
||||
}
|
||||
|
||||
@ -8,21 +8,37 @@ use crate::search::Searchable;
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RemoteMod {
|
||||
/// The URL to download the mod from, always GitHub
|
||||
pub download_url: String,
|
||||
/// The number of times the mod has been downloaded, this uses GitHub releases
|
||||
pub download_count: u32,
|
||||
/// The version of the mod, usually in the format `major.minor.patch`
|
||||
pub version: String,
|
||||
/// The name of the mod
|
||||
pub name: String,
|
||||
/// The unique name of the mod
|
||||
pub unique_name: String,
|
||||
/// The description of the mod
|
||||
pub description: String,
|
||||
/// The mod's README file, if it has one
|
||||
pub readme: Option<ModReadMe>,
|
||||
/// The slug of the mod, this is used for the URL on the website
|
||||
pub slug: String,
|
||||
/// Whether the mod is "required" this is an artifact of old manager as it treated OWML (and the manager itself) as a mod and required it to be installed
|
||||
required: Option<bool>,
|
||||
/// A link to the mod's repository on GitHub
|
||||
pub repo: String,
|
||||
/// The author of the mod, based on GitHub author name
|
||||
pub author: String,
|
||||
/// The display name of the author of the mod, manually set in the database
|
||||
pub author_display: Option<String>,
|
||||
/// The parent of the mod if this mod is an addon, e.g. NH
|
||||
pub parent: Option<String>,
|
||||
/// The prerelease for the mod, if it has one
|
||||
pub prerelease: Option<ModPrerelease>,
|
||||
/// Whether the mod is for the alpha version of the game, currently alpha support is not implemented
|
||||
alpha: Option<bool>,
|
||||
/// The tags for the mod, these are manually set in the database
|
||||
pub tags: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
@ -58,7 +74,9 @@ impl Searchable for RemoteMod {
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ModPrerelease {
|
||||
/// The URL to download the prerelease from, always GitHub
|
||||
pub download_url: String,
|
||||
/// The version of the prerelease, usually in the format `major.minor.patch`
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
@ -67,6 +85,8 @@ pub struct ModPrerelease {
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ModReadMe {
|
||||
/// The URL to the README in HTML format
|
||||
pub html_url: String,
|
||||
/// The URL to the README for download
|
||||
pub download_url: String,
|
||||
}
|
||||
|
||||
@ -25,15 +25,19 @@ const fn _default_false() -> bool {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[allow(non_snake_case)] // Have to allow non_snake_case here because OWML's config uses "incrementalGC", which isn't proper camelCase
|
||||
pub struct OWMLConfig {
|
||||
/// The path to the game
|
||||
pub game_path: String,
|
||||
#[serde(default = "_default_false")]
|
||||
debug_mode: bool,
|
||||
/// Whether to launch the game directly
|
||||
#[serde(default = "_default_false")]
|
||||
pub force_exe: bool,
|
||||
#[serde(default = "_default_true")]
|
||||
incremental_GC: bool,
|
||||
/// The path to OWML
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
owml_path: Option<String>,
|
||||
/// The port to use for sending logs to
|
||||
pub socket_port: u16,
|
||||
#[typeshare(skip)]
|
||||
#[serde(flatten)]
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use log::info;
|
||||
use serde::Serialize;
|
||||
|
||||
/// Represents a value in a progress bar
|
||||
pub type ProgressValue = u32;
|
||||
|
||||
/// Type of progress bar
|
||||
@ -31,6 +32,7 @@ pub enum ProgressAction {
|
||||
}
|
||||
|
||||
impl ProgressAction {
|
||||
/// Parse a progress action from a string
|
||||
pub fn parse(input: &str) -> Self {
|
||||
match input {
|
||||
"Download" => ProgressAction::Download,
|
||||
@ -40,33 +42,56 @@ impl ProgressAction {
|
||||
}
|
||||
}
|
||||
|
||||
/// Payload sent when a progress bar is started
|
||||
/// Contains all the information needed to create a progress bar
|
||||
#[derive(Clone, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ProgressStartPayload {
|
||||
/// The ID of the progress bar
|
||||
pub id: String,
|
||||
/// The unique name of the mod this progress bar is for, sometimes this will be None if the progress bar doesn't know what mod it's for
|
||||
pub unique_name: Option<String>,
|
||||
/// The length of the progress bar
|
||||
pub len: ProgressValue,
|
||||
/// The message of the progress bar
|
||||
pub msg: String,
|
||||
/// The type of progress bar
|
||||
pub progress_type: ProgressType,
|
||||
/// The action this progress bar is reporting
|
||||
pub progress_action: ProgressAction,
|
||||
}
|
||||
|
||||
/// Payload sent when a progress bar is incremented
|
||||
/// Note progress bars internally throttle the amount of times they can be incremented and may not report every increment
|
||||
/// This is done to prevent spamming small increments
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct ProgressIncrementPayload {
|
||||
/// The ID of the progress bar
|
||||
pub id: String,
|
||||
/// The amount to increment the progress bar by
|
||||
pub progress: ProgressValue,
|
||||
}
|
||||
|
||||
/// Payload sent when a progress bar's message is updated
|
||||
/// This is usually used to show the current file being extracted
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct ProgressMessagePayload {
|
||||
/// The ID of the progress bar
|
||||
pub id: String,
|
||||
/// The message of the progress bar
|
||||
pub msg: String,
|
||||
}
|
||||
|
||||
/// Payload sent when a progress bar has finished its task
|
||||
/// This is usually used to show the final message of the progress bar
|
||||
/// If the progress bar failed, the message will be the failure message
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct ProgressFinishPayload {
|
||||
/// The ID of the progress bar
|
||||
pub id: String,
|
||||
/// Whether the progress bar succeeded or failed
|
||||
pub success: bool,
|
||||
/// The message of the progress bar
|
||||
pub msg: String,
|
||||
}
|
||||
|
||||
@ -81,6 +106,7 @@ pub enum ProgressPayload {
|
||||
Msg(ProgressMessagePayload),
|
||||
/// Payload sent when a progress bar has finished its task
|
||||
Finish(ProgressFinishPayload),
|
||||
/// An invalid payload
|
||||
Unknown,
|
||||
}
|
||||
|
||||
@ -150,6 +176,23 @@ pub struct ProgressBar {
|
||||
}
|
||||
|
||||
impl ProgressBar {
|
||||
/// Create a new progress bar
|
||||
/// This will begin reporting the progress bar to the log
|
||||
///
|
||||
/// ## Arguments
|
||||
///
|
||||
/// - `id` - The ID of the progress bar
|
||||
/// - `unique_name` - The unique name of the mod this progress bar is for, pass None if the progress bar doesn't know what mod it's for
|
||||
/// - `len` - The length of the progress bar
|
||||
/// - `msg` - The message of the progress bar
|
||||
/// - `failure_message` - The message to show if the progress bar fails
|
||||
/// - `progress_type` - The type of progress bar
|
||||
/// - `progress_action` - The action this progress bar is reporting
|
||||
///
|
||||
/// ## Returns
|
||||
///
|
||||
/// The new progress bar
|
||||
/// Note that if this is dropped without calling finish, it will be considered a failure, so make sure to call finish!
|
||||
pub fn new(
|
||||
id: &str,
|
||||
unique_name: Option<&str>,
|
||||
@ -171,6 +214,9 @@ impl ProgressBar {
|
||||
new
|
||||
}
|
||||
|
||||
/// Increment the progress bar
|
||||
/// This will throttle the amount of times the progress bar can be incremented, so an increment may not emit a log line
|
||||
/// This is done to prevent spamming small increments
|
||||
pub fn inc(&mut self, amount: ProgressValue) {
|
||||
const THROTTLING_AMOUNT: ProgressValue = 30;
|
||||
|
||||
@ -186,10 +232,21 @@ impl ProgressBar {
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the message of the progress bar
|
||||
pub fn set_msg(&self, msg: &str) {
|
||||
info!(target: "progress", "Msg|{}|{}", self.id, msg);
|
||||
}
|
||||
|
||||
/// Finish the progress bar
|
||||
///
|
||||
/// This will emit a log line with the final message of the progress bar
|
||||
/// This function should always be called when the progress bar is done, as a drop will result in a failure
|
||||
///
|
||||
/// ## Arguments
|
||||
///
|
||||
/// - `success` - Whether the progress bar succeeded or failed
|
||||
/// - `msg` - The message of the progress bar, **this will be ignored if the progress bar failed,
|
||||
/// and will instead use the failure message passed initially**
|
||||
pub fn finish(&mut self, success: bool, msg: &str) {
|
||||
self.complete = true;
|
||||
let msg = if success { msg } else { &self.failure_message };
|
||||
|
||||
@ -53,7 +53,7 @@ where
|
||||
/// These scores are then summed and the list is sorted by the total score of each item.
|
||||
///
|
||||
/// It's not recommended to use this function when working with the mod databases
|
||||
/// Use [LocalDatabase::search] or [RemoteDatabase::search] instead
|
||||
/// Use [LocalDatabase::search](crate::db::LocalDatabase::search) or [RemoteDatabase::search](crate::db::RemoteDatabase::search) instead
|
||||
pub fn search_list<'a, T>(source_list: Vec<&'a T>, filter: &str) -> Vec<&'a T>
|
||||
where
|
||||
T: Searchable,
|
||||
|
||||
@ -11,13 +11,17 @@ use typeshare::typeshare;
|
||||
|
||||
use crate::search::Searchable;
|
||||
|
||||
/// A channel to send logs to the server
|
||||
pub type LogServerSender = mpsc::Sender<SocketMessage>;
|
||||
|
||||
/// Represents the type of message sent from the game
|
||||
///
|
||||
/// See [the OWML docs](https://owml.outerwildsmods.com/mod_helper/console.html#WriteLine) for what the types mean.
|
||||
#[typeshare]
|
||||
#[derive(Eq, PartialEq, Clone, Debug, Serialize_repr, Deserialize_repr)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[repr(u8)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum SocketMessageType {
|
||||
Message = 0,
|
||||
Error = 1,
|
||||
@ -52,9 +56,14 @@ impl SocketMessageType {
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SocketMessage {
|
||||
/// The name of the sender, usually the name of the mod
|
||||
pub sender_name: Option<String>,
|
||||
/// The type of the sender, usually ModHelper
|
||||
pub sender_type: Option<String>,
|
||||
/// The message sent from the game
|
||||
pub message: String,
|
||||
/// The type of message sent from the game
|
||||
/// Note that the message sent calls this `type` so we have to alias it because type is a reserved keyword
|
||||
#[serde(alias = "type")]
|
||||
pub message_type: SocketMessageType,
|
||||
}
|
||||
@ -88,6 +97,7 @@ impl Searchable for SocketMessage {
|
||||
|
||||
/// A server used to listen to logs from the game
|
||||
pub struct LogServer {
|
||||
/// The port the server is bound to
|
||||
pub port: u16,
|
||||
listener: TcpListener,
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user