* feat: added microsoft sdk provider * feat: changed the default provider to microsoft everywhere * feat: added checking for microsoft jdks and prompting user to install them (ui for discussion) * feat: added toast popup when user tries to remove runtime that is pinned to some cluster * feat: added 'migrating' user to the microsoft jdks * feat: changed reading mods from cluster folders on launch to having cluster folders symlinks in the shared .minecraft folder where mods stay per given cluster; changed resource packs and shader packs from working per cluster to global, every resource pack and shader pack is now being shared between clusters; added mods disabling whenever a mod is manually removed from the mods folder * fix/feat: fixed hardlinks counting as a duplicate of files it was pointing to (windows); added a progress bar to the disk storage view in settings * chore: connected microsoft jdk branch and package folder management one --------- Co-authored-by: LynithDev <61880709+LynithDev@users.noreply.github.com>
109 lines
3.1 KiB
Rust
109 lines
3.1 KiB
Rust
use std::path::Path;
|
|
|
|
use oneclient_common::domain::GameLoader;
|
|
|
|
const MODS_FOLDER_PROPERTY: &str = "fabric.modsFolder";
|
|
|
|
// version 0.15.0 is required for fabric.modsFolder to work
|
|
const MIN_LOADER_VERSION: Version = Version(0, 15, 0);
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
|
struct Version(u32, u32, u32);
|
|
|
|
fn parse_version(raw: &str) -> Option<Version> {
|
|
let core = raw.trim().split(['+', '-']).next()?;
|
|
let mut parts = core.split('.');
|
|
|
|
let major = parts.next()?.parse().ok()?;
|
|
let minor = parts.next().and_then(|p| p.parse().ok()).unwrap_or(0);
|
|
let patch = parts.next().and_then(|p| p.parse().ok()).unwrap_or(0);
|
|
|
|
Some(Version(major, minor, patch))
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn uses_cluster_mods_folder(
|
|
loader: GameLoader,
|
|
loader_version: Option<&str>,
|
|
custom_args: &str,
|
|
) -> bool {
|
|
if loader != GameLoader::Fabric {
|
|
return false;
|
|
}
|
|
|
|
if custom_args.contains(MODS_FOLDER_PROPERTY) {
|
|
tracing::info!("launch args already set {MODS_FOLDER_PROPERTY}; leaving the layout alone");
|
|
return false;
|
|
}
|
|
|
|
parse_version(loader_version.unwrap_or_default()).is_some_and(|v| v >= MIN_LOADER_VERSION)
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn mods_folder_argument(
|
|
loader: GameLoader,
|
|
loader_version: Option<&str>,
|
|
custom_args: &str,
|
|
mods_dir: &Path,
|
|
) -> Option<String> {
|
|
if !uses_cluster_mods_folder(loader, loader_version, custom_args) {
|
|
return None;
|
|
}
|
|
|
|
Some(format!("-D{MODS_FOLDER_PROPERTY}={}", mods_dir.display()))
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn versions_compare_by_component_not_by_string() {
|
|
assert!(parse_version("0.9.0") < parse_version("0.15.0"));
|
|
assert!(parse_version("0.16.5") > parse_version("0.15.0"));
|
|
assert_eq!(parse_version("0.15"), Some(Version(0, 15, 0)));
|
|
}
|
|
|
|
#[test]
|
|
fn build_metadata_is_ignored() {
|
|
assert_eq!(parse_version("0.16.0+build.1"), Some(Version(0, 16, 0)));
|
|
assert_eq!(parse_version("0.16.0-rc.1"), Some(Version(0, 16, 0)));
|
|
}
|
|
|
|
#[test]
|
|
fn only_fabric_and_only_new_enough() {
|
|
assert!(uses_cluster_mods_folder(
|
|
GameLoader::Fabric,
|
|
Some("0.16.5"),
|
|
""
|
|
));
|
|
assert!(!uses_cluster_mods_folder(
|
|
GameLoader::Fabric,
|
|
Some("0.11.0"),
|
|
""
|
|
));
|
|
|
|
assert!(!uses_cluster_mods_folder(GameLoader::Fabric, None, ""));
|
|
|
|
for loader in [
|
|
GameLoader::Vanilla,
|
|
GameLoader::Forge,
|
|
GameLoader::NeoForge,
|
|
GameLoader::Quilt,
|
|
GameLoader::LegacyFabric,
|
|
] {
|
|
assert!(!uses_cluster_mods_folder(loader, Some("0.16.5"), ""));
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn a_user_set_property_takes_the_whole_layout_with_it() {
|
|
let dir = Path::new("/clusters/one/mods");
|
|
let mine = "-Dfabric.modsFolder=/elsewhere";
|
|
|
|
assert!(mods_folder_argument(GameLoader::Fabric, Some("0.16.5"), "-Xmx4G", dir).is_some());
|
|
|
|
assert!(!uses_cluster_mods_folder(GameLoader::Fabric, Some("0.16.5"), mine));
|
|
assert!(mods_folder_argument(GameLoader::Fabric, Some("0.16.5"), mine, dir).is_none());
|
|
}
|
|
}
|