From 56d86cc300ef7d8edc32e5408a63d0b92568884c Mon Sep 17 00:00:00 2001 From: RedstoneWizard08 Date: Mon, 20 Mar 2023 17:38:44 -0700 Subject: [PATCH] Bump versions --- .eslintignore | 62 ++--- .gitignore | 60 ++-- .stylelintignore | 62 ++--- Cargo.lock | 6 +- Cargo.toml | 12 +- SECURITY.md | 26 +- bump.py | 2 + cli/Cargo.toml | 4 +- cli/src/commands/mod.rs | 2 +- cli/src/commands/mods/mod.rs | 2 +- common/Cargo.toml | 2 +- common/src/boot/integrity.rs | 198 ++++++------- common/src/boot/mod.rs | 4 +- common/src/finder/mod.rs | 106 +++---- common/src/finder/pdlauncher.rs | 88 +++--- common/src/finder/resolver/linux.rs | 26 +- common/src/finder/resolver/macos.rs | 34 +-- common/src/finder/resolver/mod.rs | 6 +- common/src/finder/resolver/windows.rs | 24 +- common/src/finder/steam.rs | 292 ++++++++++---------- common/src/models/latest.rs | 24 +- common/src/mods/mod.rs | 4 +- common/src/mods/schema/browse.rs | 382 +++++++++++++------------- common/src/mods/schema/mod.rs | 2 +- common/src/mods/spacedock/mod.rs | 162 +++++------ gui/Cargo.toml | 4 +- gui/build.rs | 6 +- 27 files changed, 802 insertions(+), 800 deletions(-) diff --git a/.eslintignore b/.eslintignore index 3908fda..ef4463c 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,31 +1,31 @@ -# Build outputs -target -build -dist -out - -# Dependencies -node_modules - -# Why would I lint these? -*.md -LICENSE - -# Image files -*.png -*.svg -*.gif -*.jpg -*.jpeg -*.jfif - -# Lock files -*.lock -pnpm-lock.yaml -package-lock.json - -# Git -.git - -# Rust -*.rs +# Build outputs +target +build +dist +out + +# Dependencies +node_modules + +# Why would I lint these? +*.md +LICENSE + +# Image files +*.png +*.svg +*.gif +*.jpg +*.jpeg +*.jfif + +# Lock files +*.lock +pnpm-lock.yaml +package-lock.json + +# Git +.git + +# Rust +*.rs diff --git a/.gitignore b/.gitignore index 4f060d5..d0f20c6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,30 +1,30 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -node_modules -dist -dist-ssr -*.local - -testing - -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? - -# Tauri generated files -target -wormhole.AppDir +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +testing + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +# Tauri generated files +target +wormhole.AppDir diff --git a/.stylelintignore b/.stylelintignore index 3908fda..ef4463c 100644 --- a/.stylelintignore +++ b/.stylelintignore @@ -1,31 +1,31 @@ -# Build outputs -target -build -dist -out - -# Dependencies -node_modules - -# Why would I lint these? -*.md -LICENSE - -# Image files -*.png -*.svg -*.gif -*.jpg -*.jpeg -*.jfif - -# Lock files -*.lock -pnpm-lock.yaml -package-lock.json - -# Git -.git - -# Rust -*.rs +# Build outputs +target +build +dist +out + +# Dependencies +node_modules + +# Why would I lint these? +*.md +LICENSE + +# Image files +*.png +*.svg +*.gif +*.jpg +*.jpeg +*.jfif + +# Lock files +*.lock +pnpm-lock.yaml +package-lock.json + +# Git +.git + +# Rust +*.rs diff --git a/Cargo.lock b/Cargo.lock index ee57800..72f6635 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4813,7 +4813,7 @@ dependencies = [ [[package]] name = "wormhole-cli" -version = "0.3.1" +version = "0.4.0" dependencies = [ "clap", "tokio 1.26.0", @@ -4822,7 +4822,7 @@ dependencies = [ [[package]] name = "wormhole-common" -version = "0.3.1" +version = "0.4.0" dependencies = [ "ckandex", "keyvalues-parser", @@ -4838,7 +4838,7 @@ dependencies = [ [[package]] name = "wormhole-gui" -version = "0.3.1" +version = "0.4.0" dependencies = [ "ckandex", "keyvalues-parser", diff --git a/Cargo.toml b/Cargo.toml index 6407a9a..1543175 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ -[workspace] -members = [ - "cli", - "common", - "gui" -] +[workspace] +members = [ + "cli", + "common", + "gui" +] diff --git a/SECURITY.md b/SECURITY.md index ae09d48..56b69ba 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,13 +1,13 @@ -# Security Policy - -## Supported Versions - -| Version | Supported | -|---------|--------------------| -| < 1.0 | :white_check_mark: | - -## Reporting a Vulnerability - -To report a vulnerability, please head to the issues section -and create one describing the issue. We will try to fix it -as soon as possible. Thanks! +# Security Policy + +## Supported Versions + +| Version | Supported | +|---------|--------------------| +| < 1.0 | :white_check_mark: | + +## Reporting a Vulnerability + +To report a vulnerability, please head to the issues section +and create one describing the issue. We will try to fix it +as soon as possible. Thanks! diff --git a/bump.py b/bump.py index 89e4c25..d891a95 100644 --- a/bump.py +++ b/bump.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + import re import argparse diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 098c47f..fca3b79 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wormhole-cli" -version = "0.3.1" +version = "0.4.0" edition = "2021" description = "The Wormhole CLI." license = "MIT" @@ -12,4 +12,4 @@ authors = ["RedstoneWizard08", "Rexicon226", "cheese3660", "Wormhole Contributor [dependencies] clap = { version = "4.1.8", features = ["derive", "env", "string", "debug"] } tokio = { version = "1.26.0", features = ["full"] } -wormhole-common = { path = "../common", version = "0.3.1" } +wormhole-common = { path = "../common", version = "0.4.0" } diff --git a/cli/src/commands/mod.rs b/cli/src/commands/mod.rs index d4d53da..b862462 100644 --- a/cli/src/commands/mod.rs +++ b/cli/src/commands/mod.rs @@ -1 +1 @@ -pub mod mods; +pub mod mods; diff --git a/cli/src/commands/mods/mod.rs b/cli/src/commands/mods/mod.rs index e5b1d65..e03495a 100644 --- a/cli/src/commands/mods/mod.rs +++ b/cli/src/commands/mods/mod.rs @@ -1 +1 @@ -pub mod install; +pub mod install; diff --git a/common/Cargo.toml b/common/Cargo.toml index c3d85af..b326e43 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wormhole-common" -version = "0.3.1" +version = "0.4.0" edition = "2021" description = "Common code for the Wormhole mod manager project." license = "MIT" diff --git a/common/src/boot/integrity.rs b/common/src/boot/integrity.rs index 5d6e74b..46e58a1 100644 --- a/common/src/boot/integrity.rs +++ b/common/src/boot/integrity.rs @@ -1,99 +1,99 @@ -use serde::{Deserialize, Serialize}; -use std::fs; -use std::path::PathBuf; - -#[derive(Debug, Deserialize, Serialize)] -pub struct Mods { - mods: Vec, -} - -#[derive(Debug, Deserialize, Serialize)] -struct Mod { - name: String, - date_installed: String, - size: u64, - install_path: String, -} - -pub fn check_directories() { - let mut dir_path = PathBuf::from(std::env::var("APPDATA").unwrap()); - dir_path.push("Wormhole"); - - if !dir_path.exists() { - let _ = fs::create_dir_all(&dir_path); - } - - if !&dir_path.join("instances").exists() { - let _ = fs::create_dir_all(dir_path.join("instances")); - } - - if !&dir_path.join("mods").exists() { - let _ = fs::create_dir_all(dir_path.join("mods")); - } - - if !&dir_path.join("cache").exists() { - let _ = fs::create_dir_all(dir_path.join("cache")); - } -} - -pub fn check_files() { - let mut dir_path = PathBuf::from(std::env::var("APPDATA").unwrap()); - dir_path.push("Wormhole"); - - if !&dir_path.join("instances").join("instances.json").exists() { - let _ = fs::write(dir_path.join("instances").join("instances.json"), "[]"); - } - - const MODS_TEMPLATE: &str = r#" - { - "mods": [ - { - "name": "Mod 1", - "date_installed": "2022-03-10T10:30:00Z", - "size": 1000000, - "install_path": "C:\\Users\\username\\AppData\\Roaming\\Wormhole\\mods\\mod1" - }, - { - "name": "Mod 2", - "date_installed": "2022-03-09T15:20:00Z", - "size": 500000, - "install_path": "C:\\Users\\username\\AppData\\Roaming\\Wormhole\\mods\\mod2" - }, - { - "name": "Mod 3", - "date_installed": "2022-03-08T11:45:00Z", - "size": 2000000, - "install_path": "C:\\Users\\username\\AppData\\Roaming\\Wormhole\\mods\\mod3" - } - ] - } - "#; - - if !&dir_path.join("mods").join("mods.json").exists() { - let _ = fs::write(dir_path.join("mods").join("mods.json"), MODS_TEMPLATE); - } -} - -pub fn directory_integrity_check() { - check_directories(); - check_files(); -} - -pub fn read_mods_file() -> Mods { - let mut dir_path = PathBuf::from(std::env::var("APPDATA").unwrap()); - dir_path.push("Wormhole"); - dir_path.push("mods"); - dir_path.push("mods.json"); - let mods_file_contents = fs::read_to_string(dir_path); - let mods: Mods = serde_json::from_str(&mods_file_contents.unwrap()).unwrap(); - return mods; -} - -// write to mods file -pub fn write_mods_file(mods: Mods) { - let mut dir_path = PathBuf::from(std::env::var("APPDATA").unwrap()); - dir_path.push("Wormhole"); - dir_path.push("mods"); - dir_path.push("mods.json"); - let _mods_file_contents = fs::write(dir_path, serde_json::to_string(&mods).unwrap()); -} +use serde::{Deserialize, Serialize}; +use std::fs; +use std::path::PathBuf; + +#[derive(Debug, Deserialize, Serialize)] +pub struct Mods { + mods: Vec, +} + +#[derive(Debug, Deserialize, Serialize)] +struct Mod { + name: String, + date_installed: String, + size: u64, + install_path: String, +} + +pub fn check_directories() { + let mut dir_path = PathBuf::from(std::env::var("APPDATA").unwrap()); + dir_path.push("Wormhole"); + + if !dir_path.exists() { + let _ = fs::create_dir_all(&dir_path); + } + + if !&dir_path.join("instances").exists() { + let _ = fs::create_dir_all(dir_path.join("instances")); + } + + if !&dir_path.join("mods").exists() { + let _ = fs::create_dir_all(dir_path.join("mods")); + } + + if !&dir_path.join("cache").exists() { + let _ = fs::create_dir_all(dir_path.join("cache")); + } +} + +pub fn check_files() { + let mut dir_path = PathBuf::from(std::env::var("APPDATA").unwrap()); + dir_path.push("Wormhole"); + + if !&dir_path.join("instances").join("instances.json").exists() { + let _ = fs::write(dir_path.join("instances").join("instances.json"), "[]"); + } + + const MODS_TEMPLATE: &str = r#" + { + "mods": [ + { + "name": "Mod 1", + "date_installed": "2022-03-10T10:30:00Z", + "size": 1000000, + "install_path": "C:\\Users\\username\\AppData\\Roaming\\Wormhole\\mods\\mod1" + }, + { + "name": "Mod 2", + "date_installed": "2022-03-09T15:20:00Z", + "size": 500000, + "install_path": "C:\\Users\\username\\AppData\\Roaming\\Wormhole\\mods\\mod2" + }, + { + "name": "Mod 3", + "date_installed": "2022-03-08T11:45:00Z", + "size": 2000000, + "install_path": "C:\\Users\\username\\AppData\\Roaming\\Wormhole\\mods\\mod3" + } + ] + } + "#; + + if !&dir_path.join("mods").join("mods.json").exists() { + let _ = fs::write(dir_path.join("mods").join("mods.json"), MODS_TEMPLATE); + } +} + +pub fn directory_integrity_check() { + check_directories(); + check_files(); +} + +pub fn read_mods_file() -> Mods { + let mut dir_path = PathBuf::from(std::env::var("APPDATA").unwrap()); + dir_path.push("Wormhole"); + dir_path.push("mods"); + dir_path.push("mods.json"); + let mods_file_contents = fs::read_to_string(dir_path); + let mods: Mods = serde_json::from_str(&mods_file_contents.unwrap()).unwrap(); + return mods; +} + +// write to mods file +pub fn write_mods_file(mods: Mods) { + let mut dir_path = PathBuf::from(std::env::var("APPDATA").unwrap()); + dir_path.push("Wormhole"); + dir_path.push("mods"); + dir_path.push("mods.json"); + let _mods_file_contents = fs::write(dir_path, serde_json::to_string(&mods).unwrap()); +} diff --git a/common/src/boot/mod.rs b/common/src/boot/mod.rs index e992ded..4586299 100644 --- a/common/src/boot/mod.rs +++ b/common/src/boot/mod.rs @@ -1,2 +1,2 @@ -pub mod cache; -pub mod integrity; +pub mod cache; +pub mod integrity; diff --git a/common/src/finder/mod.rs b/common/src/finder/mod.rs index 0e04a77..51b4177 100644 --- a/common/src/finder/mod.rs +++ b/common/src/finder/mod.rs @@ -1,53 +1,53 @@ -use std::path::PathBuf; - -use pdlauncher::PDLauncherInstallFinder; -use steam::SteamInstallFinder; - -use crate::instances::KSPGame; - -pub mod pdlauncher; -pub mod resolver; -pub mod steam; - -pub fn find_ksp2_install_dir() -> PathBuf { - let mut steam_install_finder = SteamInstallFinder::default(); - let pdlauncher_install_finder = PDLauncherInstallFinder::default(); - - let steam_install_dir = steam_install_finder.find_ksp2_dir(); - let pdlauncher_install_dir = pdlauncher_install_finder.find_ksp2_dir(); - - if let Some(dir) = steam_install_dir { - return dir; - } - - if let Some(dir) = pdlauncher_install_dir { - return dir; - } - - return None.expect("No KSP2 install found!"); -} - -pub fn find_ksp1_install_dir() -> PathBuf { - let mut steam_install_finder = SteamInstallFinder::default(); - let pdlauncher_install_finder = PDLauncherInstallFinder::default(); - - let steam_install_dir = steam_install_finder.find_ksp1_dir(); - let pdlauncher_install_dir = pdlauncher_install_finder.find_ksp1_dir(); - - if let Some(dir) = steam_install_dir { - return dir; - } - - if let Some(dir) = pdlauncher_install_dir { - return dir; - } - - return None.expect("No KSP1 install found!"); -} - -pub fn find_install_dir(game: KSPGame) -> PathBuf { - return match game { - KSPGame::KSP1 => find_ksp1_install_dir(), - KSPGame::KSP2 => find_ksp2_install_dir(), - }; -} +use std::path::PathBuf; + +use pdlauncher::PDLauncherInstallFinder; +use steam::SteamInstallFinder; + +use crate::instances::KSPGame; + +pub mod pdlauncher; +pub mod resolver; +pub mod steam; + +pub fn find_ksp2_install_dir() -> PathBuf { + let mut steam_install_finder = SteamInstallFinder::default(); + let pdlauncher_install_finder = PDLauncherInstallFinder::default(); + + let steam_install_dir = steam_install_finder.find_ksp2_dir(); + let pdlauncher_install_dir = pdlauncher_install_finder.find_ksp2_dir(); + + if let Some(dir) = steam_install_dir { + return dir; + } + + if let Some(dir) = pdlauncher_install_dir { + return dir; + } + + return None.expect("No KSP2 install found!"); +} + +pub fn find_ksp1_install_dir() -> PathBuf { + let mut steam_install_finder = SteamInstallFinder::default(); + let pdlauncher_install_finder = PDLauncherInstallFinder::default(); + + let steam_install_dir = steam_install_finder.find_ksp1_dir(); + let pdlauncher_install_dir = pdlauncher_install_finder.find_ksp1_dir(); + + if let Some(dir) = steam_install_dir { + return dir; + } + + if let Some(dir) = pdlauncher_install_dir { + return dir; + } + + return None.expect("No KSP1 install found!"); +} + +pub fn find_install_dir(game: KSPGame) -> PathBuf { + return match game { + KSPGame::KSP1 => find_ksp1_install_dir(), + KSPGame::KSP2 => find_ksp2_install_dir(), + }; +} diff --git a/common/src/finder/pdlauncher.rs b/common/src/finder/pdlauncher.rs index f5c80a1..933bc61 100644 --- a/common/src/finder/pdlauncher.rs +++ b/common/src/finder/pdlauncher.rs @@ -1,44 +1,44 @@ -use std::path::PathBuf; -#[cfg(target_os = "windows")] -use std::{env, path::Path}; - -#[derive(Default)] -pub struct PDLauncherInstallFinder {} - -impl PDLauncherInstallFinder { - #[cfg(target_os = "windows")] - pub fn find_ksp2_dir(&self) -> Option { - let default_install_folder = Path::new(env::var("PROGRAMFILES").unwrap().as_str()) - .join("Private Division") - .join("Kerbal Space Program 2"); - - if default_install_folder.exists() { - return Some(default_install_folder); - } - - return None; - } - - #[cfg(not(target_os = "windows"))] - pub fn find_ksp2_dir(&self) -> Option { - return None; - } - - #[cfg(target_os = "windows")] - pub fn find_ksp1_dir(&self) -> Option { - let default_install_folder = Path::new(env::var("PROGRAMFILES").unwrap().as_str()) - .join("Private Division") - .join("Kerbal Space Program"); - - if default_install_folder.exists() { - return Some(default_install_folder); - } - - return None; - } - - #[cfg(not(target_os = "windows"))] - pub fn find_ksp1_dir(&self) -> Option { - return None; - } -} +use std::path::PathBuf; +#[cfg(target_os = "windows")] +use std::{env, path::Path}; + +#[derive(Default)] +pub struct PDLauncherInstallFinder {} + +impl PDLauncherInstallFinder { + #[cfg(target_os = "windows")] + pub fn find_ksp2_dir(&self) -> Option { + let default_install_folder = Path::new(env::var("PROGRAMFILES").unwrap().as_str()) + .join("Private Division") + .join("Kerbal Space Program 2"); + + if default_install_folder.exists() { + return Some(default_install_folder); + } + + return None; + } + + #[cfg(not(target_os = "windows"))] + pub fn find_ksp2_dir(&self) -> Option { + return None; + } + + #[cfg(target_os = "windows")] + pub fn find_ksp1_dir(&self) -> Option { + let default_install_folder = Path::new(env::var("PROGRAMFILES").unwrap().as_str()) + .join("Private Division") + .join("Kerbal Space Program"); + + if default_install_folder.exists() { + return Some(default_install_folder); + } + + return None; + } + + #[cfg(not(target_os = "windows"))] + pub fn find_ksp1_dir(&self) -> Option { + return None; + } +} diff --git a/common/src/finder/resolver/linux.rs b/common/src/finder/resolver/linux.rs index 85d0c3b..f84fab0 100644 --- a/common/src/finder/resolver/linux.rs +++ b/common/src/finder/resolver/linux.rs @@ -1,13 +1,13 @@ -use std::{ - env, - path::{Path, PathBuf}, -}; - -pub fn get_steam_library_folders_file() -> PathBuf { - let binding = env::var("HOME").unwrap(); - let home_dir = Path::new(binding.as_str()); - - let config_dir = home_dir.join(".steam").join("root").join("config"); - - return config_dir.join("libraryfolders.vdf"); -} +use std::{ + env, + path::{Path, PathBuf}, +}; + +pub fn get_steam_library_folders_file() -> PathBuf { + let binding = env::var("HOME").unwrap(); + let home_dir = Path::new(binding.as_str()); + + let config_dir = home_dir.join(".steam").join("root").join("config"); + + return config_dir.join("libraryfolders.vdf"); +} diff --git a/common/src/finder/resolver/macos.rs b/common/src/finder/resolver/macos.rs index ab2d756..238125c 100644 --- a/common/src/finder/resolver/macos.rs +++ b/common/src/finder/resolver/macos.rs @@ -1,17 +1,17 @@ -use std::{ - env, - path::{Path, PathBuf}, -}; - -pub fn get_steam_library_folders_file() -> PathBuf { - let binding = env::var("HOME").unwrap(); - let home_dir = Path::new(binding.as_str()); - - let config_dir = home_dir - .join("Library") - .join("Application Support") - .join("Steam") - .join("config"); - - return config_dir.join("libraryfolders.vdf"); -} +use std::{ + env, + path::{Path, PathBuf}, +}; + +pub fn get_steam_library_folders_file() -> PathBuf { + let binding = env::var("HOME").unwrap(); + let home_dir = Path::new(binding.as_str()); + + let config_dir = home_dir + .join("Library") + .join("Application Support") + .join("Steam") + .join("config"); + + return config_dir.join("libraryfolders.vdf"); +} diff --git a/common/src/finder/resolver/mod.rs b/common/src/finder/resolver/mod.rs index 8183326..645a5db 100644 --- a/common/src/finder/resolver/mod.rs +++ b/common/src/finder/resolver/mod.rs @@ -1,3 +1,3 @@ -pub mod linux; -pub mod macos; -pub mod windows; +pub mod linux; +pub mod macos; +pub mod windows; diff --git a/common/src/finder/resolver/windows.rs b/common/src/finder/resolver/windows.rs index 50006f1..fda842c 100644 --- a/common/src/finder/resolver/windows.rs +++ b/common/src/finder/resolver/windows.rs @@ -1,12 +1,12 @@ -use std::{ - env, - path::{Path, PathBuf}, -}; - -pub fn get_steam_library_folders_file() -> PathBuf { - let binding = env::var("PROGRAMFILES(X86)").unwrap(); - let program_files = Path::new(binding.as_str()); - let config_dir = program_files.join("Steam").join("config"); - - return config_dir.join("libraryfolders.vdf"); -} +use std::{ + env, + path::{Path, PathBuf}, +}; + +pub fn get_steam_library_folders_file() -> PathBuf { + let binding = env::var("PROGRAMFILES(X86)").unwrap(); + let program_files = Path::new(binding.as_str()); + let config_dir = program_files.join("Steam").join("config"); + + return config_dir.join("libraryfolders.vdf"); +} diff --git a/common/src/finder/steam.rs b/common/src/finder/steam.rs index 9a62e71..894dc96 100644 --- a/common/src/finder/steam.rs +++ b/common/src/finder/steam.rs @@ -1,146 +1,146 @@ -use std::{fs, path::PathBuf}; - -use keyvalues_parser::Vdf; - -#[cfg(target_os = "linux")] -use super::resolver::linux; -#[cfg(target_os = "macos")] -use super::resolver::macos; -#[cfg(target_os = "windows")] -use super::resolver::windows; - -#[derive(Default, Clone, Debug)] -pub struct LibraryFolders { - pub paths: Vec, - pub discovered: bool, -} - -impl LibraryFolders { - pub fn new() -> Self { - return Self { - paths: vec![], - discovered: false, - }; - } - - #[cfg(target_os = "macos")] - pub fn get_library_folders_file(&self) -> PathBuf { - return macos::get_steam_library_folders_file(); - } - - #[cfg(target_os = "linux")] - pub fn get_library_folders_file(&self) -> PathBuf { - return linux::get_steam_library_folders_file(); - } - - #[cfg(target_os = "windows")] - pub fn get_library_folders_file(&self) -> PathBuf { - return windows::get_steam_library_folders_file(); - } - - pub fn discover(&mut self) -> Option<&mut Self> { - let libraryfolders_vdf_path = self.get_library_folders_file(); - - if libraryfolders_vdf_path.is_file() { - let vdf_text = fs::read_to_string(&libraryfolders_vdf_path).ok()?; - let value = Vdf::parse(&vdf_text).ok()?.value; - let obj = value.get_obj()?; - - let library_folders: Vec<_> = obj - .iter() - .filter(|(key, values)| key.parse::().is_ok() && values.len() == 1) - .filter_map(|(_, values)| { - let library_folder_string = values - .get(0)? - .get_obj()? - .get("path")? - .get(0)? - .get_str()? - .to_string(); - - let library_folder = PathBuf::from(library_folder_string).join("steamapps"); - - return Some(library_folder); - }) - .collect(); - - self.paths = library_folders; - } - - self.discovered = true; - - return Some(self); - } -} - -pub struct SteamInstallFinder { - pub library_folders: LibraryFolders, -} - -impl Default for SteamInstallFinder { - fn default() -> Self { - let mut me = Self { - library_folders: LibraryFolders::new(), - }; - - me.library_folders - .discover() - .expect("Failed to discover Steam library folders!"); - - return me; - } -} - -impl SteamInstallFinder { - pub fn find_ksp2_dir(&mut self) -> Option { - for library_folder in self.library_folders.clone().paths { - let ksp2_dir = library_folder.join("common").join("Kerbal Space Program 2"); - - if ksp2_dir.is_dir() { - let dir_contents = fs::read_dir(&ksp2_dir).unwrap().flatten(); - - for file in dir_contents { - let file_path = file.path(); - - if file_path.is_file() - && file_path - .as_os_str() - .to_str() - .unwrap() - .contains("KSP2_x64.exe") - { - return Some(ksp2_dir); - } - } - } - } - - return None; - } - - pub fn find_ksp1_dir(&mut self) -> Option { - for library_folder in self.library_folders.clone().paths { - let ksp2_dir = library_folder.join("common").join("Kerbal Space Program"); - - if ksp2_dir.is_dir() { - let dir_contents = fs::read_dir(&ksp2_dir).unwrap().flatten(); - - for file in dir_contents { - let file_path = file.path(); - - if file_path.is_file() - && file_path - .as_os_str() - .to_str() - .unwrap() - .contains("KSP_x64.exe") - { - return Some(ksp2_dir); - } - } - } - } - - return None; - } -} +use std::{fs, path::PathBuf}; + +use keyvalues_parser::Vdf; + +#[cfg(target_os = "linux")] +use super::resolver::linux; +#[cfg(target_os = "macos")] +use super::resolver::macos; +#[cfg(target_os = "windows")] +use super::resolver::windows; + +#[derive(Default, Clone, Debug)] +pub struct LibraryFolders { + pub paths: Vec, + pub discovered: bool, +} + +impl LibraryFolders { + pub fn new() -> Self { + return Self { + paths: vec![], + discovered: false, + }; + } + + #[cfg(target_os = "macos")] + pub fn get_library_folders_file(&self) -> PathBuf { + return macos::get_steam_library_folders_file(); + } + + #[cfg(target_os = "linux")] + pub fn get_library_folders_file(&self) -> PathBuf { + return linux::get_steam_library_folders_file(); + } + + #[cfg(target_os = "windows")] + pub fn get_library_folders_file(&self) -> PathBuf { + return windows::get_steam_library_folders_file(); + } + + pub fn discover(&mut self) -> Option<&mut Self> { + let libraryfolders_vdf_path = self.get_library_folders_file(); + + if libraryfolders_vdf_path.is_file() { + let vdf_text = fs::read_to_string(&libraryfolders_vdf_path).ok()?; + let value = Vdf::parse(&vdf_text).ok()?.value; + let obj = value.get_obj()?; + + let library_folders: Vec<_> = obj + .iter() + .filter(|(key, values)| key.parse::().is_ok() && values.len() == 1) + .filter_map(|(_, values)| { + let library_folder_string = values + .get(0)? + .get_obj()? + .get("path")? + .get(0)? + .get_str()? + .to_string(); + + let library_folder = PathBuf::from(library_folder_string).join("steamapps"); + + return Some(library_folder); + }) + .collect(); + + self.paths = library_folders; + } + + self.discovered = true; + + return Some(self); + } +} + +pub struct SteamInstallFinder { + pub library_folders: LibraryFolders, +} + +impl Default for SteamInstallFinder { + fn default() -> Self { + let mut me = Self { + library_folders: LibraryFolders::new(), + }; + + me.library_folders + .discover() + .expect("Failed to discover Steam library folders!"); + + return me; + } +} + +impl SteamInstallFinder { + pub fn find_ksp2_dir(&mut self) -> Option { + for library_folder in self.library_folders.clone().paths { + let ksp2_dir = library_folder.join("common").join("Kerbal Space Program 2"); + + if ksp2_dir.is_dir() { + let dir_contents = fs::read_dir(&ksp2_dir).unwrap().flatten(); + + for file in dir_contents { + let file_path = file.path(); + + if file_path.is_file() + && file_path + .as_os_str() + .to_str() + .unwrap() + .contains("KSP2_x64.exe") + { + return Some(ksp2_dir); + } + } + } + } + + return None; + } + + pub fn find_ksp1_dir(&mut self) -> Option { + for library_folder in self.library_folders.clone().paths { + let ksp2_dir = library_folder.join("common").join("Kerbal Space Program"); + + if ksp2_dir.is_dir() { + let dir_contents = fs::read_dir(&ksp2_dir).unwrap().flatten(); + + for file in dir_contents { + let file_path = file.path(); + + if file_path.is_file() + && file_path + .as_os_str() + .to_str() + .unwrap() + .contains("KSP_x64.exe") + { + return Some(ksp2_dir); + } + } + } + } + + return None; + } +} diff --git a/common/src/models/latest.rs b/common/src/models/latest.rs index d67fd9b..8ae70fc 100644 --- a/common/src/models/latest.rs +++ b/common/src/models/latest.rs @@ -1,12 +1,12 @@ -use serde::{Deserialize, Serialize}; - -#[derive(Serialize, Deserialize, Debug)] -pub struct LatestSchema { - pub friendly_version: String, - pub game_version: String, - pub id: i32, - pub created: String, - pub download_path: String, - pub changelog: Option, - pub downloads: i32, -} +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug)] +pub struct LatestSchema { + pub friendly_version: String, + pub game_version: String, + pub id: i32, + pub created: String, + pub download_path: String, + pub changelog: Option, + pub downloads: i32, +} diff --git a/common/src/mods/mod.rs b/common/src/mods/mod.rs index 9a3c6dd..ece6803 100644 --- a/common/src/mods/mod.rs +++ b/common/src/mods/mod.rs @@ -1,2 +1,2 @@ -pub mod schema; -pub mod spacedock; +pub mod schema; +pub mod spacedock; diff --git a/common/src/mods/schema/browse.rs b/common/src/mods/schema/browse.rs index cc064e1..8a5915f 100644 --- a/common/src/mods/schema/browse.rs +++ b/common/src/mods/schema/browse.rs @@ -1,191 +1,191 @@ -use serde::{Deserialize, Serialize}; -use serde_json::Value; - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct ModVersion { - pub friendly_version: Option, - pub game_version: Option, - pub id: Option, - pub created: Option, - pub download_path: Option, - pub changelog: Option, - pub downloads: Option, -} - -impl Default for ModVersion { - fn default() -> Self { - return Self { - friendly_version: None, - game_version: None, - id: None, - created: None, - download_path: None, - changelog: None, - downloads: None, - }; - } -} - -impl ModVersion { - pub fn finish(&self) -> Self { - let out = ModVersion { - friendly_version: Some(self.friendly_version.clone().unwrap_or("".to_string())), - game_version: Some(self.friendly_version.clone().unwrap_or("".to_string())), - id: Some(self.id.unwrap_or(0)), - created: Some(self.created.clone().unwrap_or("".to_string())), - download_path: Some(self.download_path.clone().unwrap_or("".to_string())), - changelog: Some(self.changelog.clone().unwrap_or("".to_string())), - downloads: Some(self.downloads.unwrap_or(0)), - }; - - return out; - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct ModInfo { - pub name: Option, - pub id: Option, - pub game: Option, - pub game_id: Option, - pub short_description: Option, - pub downloads: Option, - pub followers: Option, - pub author: Option, - pub default_version_id: Option, - pub shared_authors: Option>, - pub background: Option, - pub bg_offset_y: Option, - pub license: Option, - pub website: Option, - pub donations: Option, - pub source_code: Option, - pub url: Option, - pub versions: Option>, - pub description: Option, -} - -impl Default for ModInfo { - fn default() -> Self { - return Self { - name: None, - id: None, - game: None, - game_id: None, - short_description: None, - downloads: None, - followers: None, - author: None, - default_version_id: None, - shared_authors: None, - background: None, - bg_offset_y: None, - license: None, - website: None, - donations: None, - source_code: None, - url: None, - versions: None, - description: None, - }; - } -} - -impl ModInfo { - pub fn finish(&self, browse: bool) -> Self { - let mut out = ModInfo::default(); - let mut _versions = Vec::new(); - let mut bg_img = "https://spacedock.info/static/background.png".to_string(); - - if browse { - bg_img = "https://spacedock.info/static/background-s.png".to_string(); - } - - if let Some(versions) = self.versions.clone() { - _versions = versions.iter().map(|v| v.finish()).collect(); - } - - out.name = Some(self.name.clone().unwrap_or("".to_string())); - out.id = Some(self.id.unwrap_or(0)); - out.game = Some(self.game.clone().unwrap_or("".to_string())); - out.game_id = Some(self.game_id.unwrap_or(0)); - out.short_description = Some(self.short_description.clone().unwrap_or("".to_string())); - out.downloads = Some(self.downloads.unwrap_or(0)); - out.followers = Some(self.followers.unwrap_or(0)); - out.author = Some(self.author.clone().unwrap_or("".to_string())); - out.default_version_id = Some(self.default_version_id.unwrap_or(0)); - out.shared_authors = Some(self.shared_authors.clone().unwrap_or(Vec::new())); - - out.background = Some(self.background.clone().unwrap_or(bg_img)); - - out.bg_offset_y = Some(self.bg_offset_y.unwrap_or(0)); - out.license = Some(self.license.clone().unwrap_or("".to_string())); - out.website = Some(self.website.clone().unwrap_or("".to_string())); - out.donations = Some(self.donations.clone().unwrap_or("".to_string())); - out.source_code = Some(self.source_code.clone().unwrap_or("".to_string())); - out.url = Some(self.url.clone().unwrap_or("".to_string())); - out.versions = Some(_versions); - out.description = Some(self.description.clone().unwrap_or("".to_string())); - - return out; - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BrowseResult { - pub result: Option>, - pub count: Option, - pub pages: Option, - pub page: Option, -} - -impl Default for BrowseResult { - fn default() -> Self { - return Self { - result: None, - count: None, - pages: None, - page: None, - }; - } -} - -impl BrowseResult { - pub fn finish(&self) -> Self { - let mut out = BrowseResult::default(); - let mut _res = Vec::new(); - - if let Some(result) = self.result.clone() { - _res = result.iter().map(|v| v.finish(true)).collect(); - } - - out.result = Some(_res); - out.count = Some(self.count.unwrap_or(0)); - out.pages = Some(self.pages.unwrap_or(0)); - out.page = Some(self.page.unwrap_or(0)); - - return out; - } -} - -#[derive(Debug, Deserialize)] -pub struct BrowseModInfo { - pub name: String, - pub id: i32, - pub game: String, - pub game_id: i32, - pub short_description: String, - pub downloads: i32, - pub followers: i32, - pub author: String, - pub default_version_id: i32, - pub shared_authors: Vec, - pub background: String, - pub bg_offset_y: String, - pub license: String, - pub website: String, - pub donations: String, - pub source_code: String, - pub url: String, - pub versions: Vec, -} +use serde::{Deserialize, Serialize}; +use serde_json::Value; + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct ModVersion { + pub friendly_version: Option, + pub game_version: Option, + pub id: Option, + pub created: Option, + pub download_path: Option, + pub changelog: Option, + pub downloads: Option, +} + +impl Default for ModVersion { + fn default() -> Self { + return Self { + friendly_version: None, + game_version: None, + id: None, + created: None, + download_path: None, + changelog: None, + downloads: None, + }; + } +} + +impl ModVersion { + pub fn finish(&self) -> Self { + let out = ModVersion { + friendly_version: Some(self.friendly_version.clone().unwrap_or("".to_string())), + game_version: Some(self.friendly_version.clone().unwrap_or("".to_string())), + id: Some(self.id.unwrap_or(0)), + created: Some(self.created.clone().unwrap_or("".to_string())), + download_path: Some(self.download_path.clone().unwrap_or("".to_string())), + changelog: Some(self.changelog.clone().unwrap_or("".to_string())), + downloads: Some(self.downloads.unwrap_or(0)), + }; + + return out; + } +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct ModInfo { + pub name: Option, + pub id: Option, + pub game: Option, + pub game_id: Option, + pub short_description: Option, + pub downloads: Option, + pub followers: Option, + pub author: Option, + pub default_version_id: Option, + pub shared_authors: Option>, + pub background: Option, + pub bg_offset_y: Option, + pub license: Option, + pub website: Option, + pub donations: Option, + pub source_code: Option, + pub url: Option, + pub versions: Option>, + pub description: Option, +} + +impl Default for ModInfo { + fn default() -> Self { + return Self { + name: None, + id: None, + game: None, + game_id: None, + short_description: None, + downloads: None, + followers: None, + author: None, + default_version_id: None, + shared_authors: None, + background: None, + bg_offset_y: None, + license: None, + website: None, + donations: None, + source_code: None, + url: None, + versions: None, + description: None, + }; + } +} + +impl ModInfo { + pub fn finish(&self, browse: bool) -> Self { + let mut out = ModInfo::default(); + let mut _versions = Vec::new(); + let mut bg_img = "https://spacedock.info/static/background.png".to_string(); + + if browse { + bg_img = "https://spacedock.info/static/background-s.png".to_string(); + } + + if let Some(versions) = self.versions.clone() { + _versions = versions.iter().map(|v| v.finish()).collect(); + } + + out.name = Some(self.name.clone().unwrap_or("".to_string())); + out.id = Some(self.id.unwrap_or(0)); + out.game = Some(self.game.clone().unwrap_or("".to_string())); + out.game_id = Some(self.game_id.unwrap_or(0)); + out.short_description = Some(self.short_description.clone().unwrap_or("".to_string())); + out.downloads = Some(self.downloads.unwrap_or(0)); + out.followers = Some(self.followers.unwrap_or(0)); + out.author = Some(self.author.clone().unwrap_or("".to_string())); + out.default_version_id = Some(self.default_version_id.unwrap_or(0)); + out.shared_authors = Some(self.shared_authors.clone().unwrap_or(Vec::new())); + + out.background = Some(self.background.clone().unwrap_or(bg_img)); + + out.bg_offset_y = Some(self.bg_offset_y.unwrap_or(0)); + out.license = Some(self.license.clone().unwrap_or("".to_string())); + out.website = Some(self.website.clone().unwrap_or("".to_string())); + out.donations = Some(self.donations.clone().unwrap_or("".to_string())); + out.source_code = Some(self.source_code.clone().unwrap_or("".to_string())); + out.url = Some(self.url.clone().unwrap_or("".to_string())); + out.versions = Some(_versions); + out.description = Some(self.description.clone().unwrap_or("".to_string())); + + return out; + } +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct BrowseResult { + pub result: Option>, + pub count: Option, + pub pages: Option, + pub page: Option, +} + +impl Default for BrowseResult { + fn default() -> Self { + return Self { + result: None, + count: None, + pages: None, + page: None, + }; + } +} + +impl BrowseResult { + pub fn finish(&self) -> Self { + let mut out = BrowseResult::default(); + let mut _res = Vec::new(); + + if let Some(result) = self.result.clone() { + _res = result.iter().map(|v| v.finish(true)).collect(); + } + + out.result = Some(_res); + out.count = Some(self.count.unwrap_or(0)); + out.pages = Some(self.pages.unwrap_or(0)); + out.page = Some(self.page.unwrap_or(0)); + + return out; + } +} + +#[derive(Debug, Deserialize)] +pub struct BrowseModInfo { + pub name: String, + pub id: i32, + pub game: String, + pub game_id: i32, + pub short_description: String, + pub downloads: i32, + pub followers: i32, + pub author: String, + pub default_version_id: i32, + pub shared_authors: Vec, + pub background: String, + pub bg_offset_y: String, + pub license: String, + pub website: String, + pub donations: String, + pub source_code: String, + pub url: String, + pub versions: Vec, +} diff --git a/common/src/mods/schema/mod.rs b/common/src/mods/schema/mod.rs index c5d6a61..f35bd75 100644 --- a/common/src/mods/schema/mod.rs +++ b/common/src/mods/schema/mod.rs @@ -1 +1 @@ -pub mod browse; +pub mod browse; diff --git a/common/src/mods/spacedock/mod.rs b/common/src/mods/spacedock/mod.rs index 7654235..44c399a 100644 --- a/common/src/mods/spacedock/mod.rs +++ b/common/src/mods/spacedock/mod.rs @@ -1,81 +1,81 @@ -use serde::{Deserialize, Serialize}; -use std::time::Instant; - -use crate::models::latest::LatestSchema; - -use super::schema::browse::{BrowseResult, ModInfo}; - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct SpaceDockAPI { - pub base: String, - pub api_base: String, -} - -impl Default for SpaceDockAPI { - fn default() -> Self { - return Self::new(); - } -} - -impl SpaceDockAPI { - pub fn new() -> Self { - return Self { - base: SpaceDockAPI::get_default_url(), - api_base: SpaceDockAPI::get_default_api_url(), - }; - } - - pub fn get_default_api_url() -> String { - return "https://spacedock.info/api".to_string(); - } - - pub fn get_default_url() -> String { - return "https://spacedock.info".to_string(); - } - - pub async fn get_mod(&self, id: i32) -> ModInfo { - let uri = format!("{}/mod/{}", self.api_base, id); - let resp = reqwest::get(uri).await.unwrap(); - let data = resp.json::().await.unwrap(); - - return data.finish(false); - } - - pub async fn get_mods(&self, page: i32, count: i32) -> BrowseResult { - let uri = format!("{}/browse?page={}&count={}", self.api_base, page, count); - let resp = reqwest::get(uri).await.unwrap(); - let data = resp.json::().await.unwrap(); - - return data.finish(); - } - - pub async fn get_mods_for_game(&self, game: i32, page: i32, count: i32) -> BrowseResult { - let start_time = Instant::now(); - - let uri = format!( - "{}/browse?page={}&count={}&game_id={}", - self.api_base, page, count, game - ); - let resp = reqwest::get(uri).await.unwrap(); - let text = resp.text().await.unwrap(); - let data = serde_json::from_str::(&text); - - let elapsed = start_time.elapsed(); - println!("API call took {:?}", elapsed); - - if let Ok(data) = data { - return data.finish(); - } - - panic!("Found: {}", text); - } - - pub async fn get_mod_download(&self, id: i32) -> String { - let uri = format!("{}/mod/{}/latest", self.api_base, id); - let resp = reqwest::get(uri).await.unwrap(); - let text = resp.text().await.unwrap(); - let data = serde_json::from_str::(&text).unwrap(); - - return format!("{}{}", self.base, data.download_path); - } -} +use serde::{Deserialize, Serialize}; +use std::time::Instant; + +use crate::models::latest::LatestSchema; + +use super::schema::browse::{BrowseResult, ModInfo}; + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct SpaceDockAPI { + pub base: String, + pub api_base: String, +} + +impl Default for SpaceDockAPI { + fn default() -> Self { + return Self::new(); + } +} + +impl SpaceDockAPI { + pub fn new() -> Self { + return Self { + base: SpaceDockAPI::get_default_url(), + api_base: SpaceDockAPI::get_default_api_url(), + }; + } + + pub fn get_default_api_url() -> String { + return "https://spacedock.info/api".to_string(); + } + + pub fn get_default_url() -> String { + return "https://spacedock.info".to_string(); + } + + pub async fn get_mod(&self, id: i32) -> ModInfo { + let uri = format!("{}/mod/{}", self.api_base, id); + let resp = reqwest::get(uri).await.unwrap(); + let data = resp.json::().await.unwrap(); + + return data.finish(false); + } + + pub async fn get_mods(&self, page: i32, count: i32) -> BrowseResult { + let uri = format!("{}/browse?page={}&count={}", self.api_base, page, count); + let resp = reqwest::get(uri).await.unwrap(); + let data = resp.json::().await.unwrap(); + + return data.finish(); + } + + pub async fn get_mods_for_game(&self, game: i32, page: i32, count: i32) -> BrowseResult { + let start_time = Instant::now(); + + let uri = format!( + "{}/browse?page={}&count={}&game_id={}", + self.api_base, page, count, game + ); + let resp = reqwest::get(uri).await.unwrap(); + let text = resp.text().await.unwrap(); + let data = serde_json::from_str::(&text); + + let elapsed = start_time.elapsed(); + println!("API call took {:?}", elapsed); + + if let Ok(data) = data { + return data.finish(); + } + + panic!("Found: {}", text); + } + + pub async fn get_mod_download(&self, id: i32) -> String { + let uri = format!("{}/mod/{}/latest", self.api_base, id); + let resp = reqwest::get(uri).await.unwrap(); + let text = resp.text().await.unwrap(); + let data = serde_json::from_str::(&text).unwrap(); + + return format!("{}{}", self.base, data.download_path); + } +} diff --git a/gui/Cargo.toml b/gui/Cargo.toml index efe1876..c492db1 100644 --- a/gui/Cargo.toml +++ b/gui/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wormhole-gui" -version = "0.3.1" +version = "0.4.0" edition = "2021" description = "An installer for the SpaceWarp mod Lloader." license = "MIT" @@ -23,7 +23,7 @@ tokio = { version = "1.26.0", features = ["full"] } reqwest = { version = "0.11.14", features = ["stream", "gzip"] } tokio-util = { version = "0.7.7", features = ["full"] } tokio-stream = { version = "0.1.12", features = ["tokio-util", "fs", "net", "sync"] } -wormhole-common = { path = "../common", version = "0.3.1" } +wormhole-common = { path = "../common", version = "0.4.0" } [features] default = ["custom-protocol"] diff --git a/gui/build.rs b/gui/build.rs index d860e1e..2ba80a8 100644 --- a/gui/build.rs +++ b/gui/build.rs @@ -1,3 +1,3 @@ -fn main() { - tauri_build::build() -} +fn main() { + tauri_build::build() +}