From f397ed40bd8c120ffaa3786fc0bf1f3bd5570644 Mon Sep 17 00:00:00 2001 From: LynithDev <61880709+LynithDev@users.noreply.github.com> Date: Sun, 10 Aug 2025 17:03:55 +0200 Subject: [PATCH] feat: mapped CF categories and added loader field to search results --- packages/core/src/api/packages/data.rs | 1 + .../provider/curseforge/categories.rs | 189 ++++++++++-------- .../api/packages/provider/curseforge/mod.rs | 30 ++- .../src/api/packages/provider/modrinth/mod.rs | 8 + .../core/src/api/packages/provider/tests.rs | 21 ++ packages/entity/src/domain/package.rs | 2 +- 6 files changed, 162 insertions(+), 89 deletions(-) diff --git a/packages/core/src/api/packages/data.rs b/packages/core/src/api/packages/data.rs index 1f8c14cd..4970fe85 100644 --- a/packages/core/src/api/packages/data.rs +++ b/packages/core/src/api/packages/data.rs @@ -64,6 +64,7 @@ pub struct SearchResult { pub title: String, pub description: String, pub categories: PackageCategories, + pub loaders: Vec, pub mc_versions: Vec, pub downloads: usize, pub icon_url: String, diff --git a/packages/core/src/api/packages/provider/curseforge/categories.rs b/packages/core/src/api/packages/provider/curseforge/categories.rs index db66e914..ea36a9bd 100644 --- a/packages/core/src/api/packages/provider/curseforge/categories.rs +++ b/packages/core/src/api/packages/provider/curseforge/categories.rs @@ -7,97 +7,124 @@ use crate::api::packages::provider::CurseForgeProviderImpl; pub struct CurseForgeCategories; define_category_mapping! { - impl ToProviderCategory for CurseForgeCategories { + impl ToProviderCategory for CurseForgeCategories { PackageModCategory as as_mod_out => to_mod { - Adventure => 0, - Library => 0, - Equipment => 0, - Patches => 0, - Cosmetic => 0, - Food => 0, - Magic => 0, - Information => 0, - Misc => 0, - Performance => 0, - Redstone => 0, - ServerUtil => 0, - Storage => 0, - Technology => 0, - Farming => 0, - Automation => 0, - Transport => 0, - Utility => 0, - QoL => 0, - WorldGen => 0, - Mobs => 0, - Economy => 0, - Social => 0, + Adventure => 422, + Library => 421, + Equipment => 434, + Patches => 6821, + Cosmetic => 424, + Food => 436, + Magic => 419, + Information => 423, + Misc => 425, + Performance => 6814, + Redstone => 4558, + ServerUtil => 435, + Storage => 420, + Technology => 412, + Farming => 416, + Automation => 4843, + Transport => 414, + Utility => 5191, + QoL => 5191, + WorldGen => 406, + Mobs => 411, + Economy => -1, + Social => -1, + } + + PackageModCategory as as_data_pack_out => to_data_pack { + Adventure => 6948, + Library => 6950, + Equipment => -1, + Patches => 6946, + Cosmetic => -1, + Food => -1, + Magic => 6952, + Information => -1, + Misc => 6947, + Performance => -1, + Redstone => -1, + ServerUtil => -1, + Storage => -1, + Technology => 6951, + Farming => -1, + Automation => -1, + Transport => -1, + Utility => 6953, + QoL => -1, + WorldGen => -1, + Mobs => -1, + Economy => -1, + Social => -1, } PackageResourcePackCategory as as_resource_pack_out => to_resource_pack { - X8 => 0, - X16 => 0, - X32 => 0, - X48 => 0, - X64 => 0, - X128 => 0, - X256 => 0, - X512 => 0, - VanillaLike => 0, - Utility => 0, - Tweaks => 0, - Themed => 0, - Simplistic => 0, - Realistic => 0, - Modded => 0, - Decoration => 0, - Cursed => 0, - Combat => 0, - Audio => 0, - Blocks => 0, - CoreShaders => 0, - Gui => 0, - Fonts => 0, - Equipment => 0, - Environment => 0, - Entities => 0, - Items => 0, - Locale => 0, - Models => 0, + X8 => -1, + X16 => 393, + X32 => 394, + X48 => -1, + X64 => 395, + X128 => 396, + X256 => 397, + X512 => 398, + VanillaLike => 403, + Utility => 405, + Tweaks => 405, + Themed => 399, + Simplistic => 401, + Realistic => 400, + Modded => 4465, + Decoration => 405, + Cursed => 405, + Combat => 405, + Audio => 405, + Blocks => 405, + CoreShaders => 405, + Gui => 403, + Fonts => 5244, + Equipment => 405, + Environment => 405, + Entities => 405, + Items => 405, + Locale => 405, + Models => 405, } + // Curseforge is very bad with shader categories PackageShaderCategory as as_shader_out => to_shader { - VanillaLike => 0, - SemiRealistic => 0, - Realistic => 0, - Fantasy => 0, - Cursed => 0, - Cartoon => 0, - Bloom => 0, - Atmosphere => 0, - Reflections => 0, - Shadows => 0, - PBR => 0, - PathTracing => 0, - Foliage => 0, - ColoredLightning => 0, - Potato => 0, - Low => 0, - Medium => 0, - High => 0, - Ultra => 0, + VanillaLike => 6555, + SemiRealistic => -1, + Realistic => 6553, + Fantasy => 6554, + Cursed => -1, + Cartoon => -1, + Bloom => -1, + Atmosphere => -1, + Reflections => -1, + Shadows => -1, + PBR => -1, + PathTracing => -1, + Foliage => -1, + ColoredLightning => -1, + Potato => -1, + Low => -1, + Medium => -1, + High => -1, + Ultra => -1, } PackageModPackCategory as as_mod_pack_out => to_mod_pack { - Adventure => 0, - Technology => 0, - Quests => 0, - Optimization => 0, - Multiplayer => 0, - Magic => 0, - LightWeight => 0, - Combat => 0, - Challenging => 0, + Adventure => 4475, + Technology => 4472, + Quests => 4478, + Optimization => 4481, + Multiplayer => 4484, + Magic => 4473, + LightWeight => 4481, + Combat => 4483, + Challenging => 4479, } } } diff --git a/packages/core/src/api/packages/provider/curseforge/mod.rs b/packages/core/src/api/packages/provider/curseforge/mod.rs index 2cbcf227..ac77a80e 100644 --- a/packages/core/src/api/packages/provider/curseforge/mod.rs +++ b/packages/core/src/api/packages/provider/curseforge/mod.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use chrono::{DateTime, Utc}; use onelauncher_entity::loader::GameLoader; @@ -96,7 +96,7 @@ impl ProviderExt for CurseForgeProviderImpl { "[{}]", categories .iter() - .map(u32::to_string) + .map(i32::to_string) .collect::>() .join(",") ); @@ -354,7 +354,7 @@ impl From for CFPackageType { } /// Mapping of Curseforge supported loaders to their respective id -#[derive(Debug, Default, Serialize_repr, Deserialize_repr)] +#[derive(Debug, Default, Clone, Copy, Serialize_repr, Deserialize_repr, Hash, PartialEq)] #[repr(u8)] pub enum CFLoader { #[default] @@ -522,12 +522,24 @@ impl From for SearchResult { fn from(value: CFPackage) -> Self { let mc_versions: Vec = value .latest_files_indexes - .into_iter() - .map(|index| index.game_version) + .iter() + .map(|index| index.game_version.clone()) .collect(); let package_type: PackageType = value.package_type.into(); + let loaders: Vec = value + .latest_files_indexes + .iter() + .filter_map(|index| { + index + .mod_loader + .and_then(|loader| GameLoader::try_from(loader).ok()) + }) + .collect::>() + .into_iter() + .collect(); + Self { title: value.name, slug: value.slug, @@ -546,6 +558,7 @@ impl From for SearchResult { &package_type, &value.categories.into_iter().map(|c| c.id).collect(), ), + loaders, package_type, mc_versions, date_created: value.date_created, @@ -555,7 +568,10 @@ impl From for SearchResult { .into_iter() .map(|asset| asset.url) .collect(), - latest_version: "".to_string(), // TODO: figure out how to get this + latest_version: value + .latest_files_indexes + .first() + .map_or(String::new(), |index| index.file_id.to_string()), license: None, } } @@ -640,7 +656,7 @@ pub struct CFSocialLink { #[derive(Default, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct Category { - pub id: u32, + pub id: i32, // pub game_id: u32, // pub name: String, pub slug: String, diff --git a/packages/core/src/api/packages/provider/modrinth/mod.rs b/packages/core/src/api/packages/provider/modrinth/mod.rs index 3796e2f3..e67c8776 100644 --- a/packages/core/src/api/packages/provider/modrinth/mod.rs +++ b/packages/core/src/api/packages/provider/modrinth/mod.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::str::FromStr; use super::ProviderExt; use crate::api::packages::categories::ToProviderCategory; @@ -358,8 +359,15 @@ struct ModrinthSearchResult { impl From for SearchResult { fn from(value: ModrinthSearchResult) -> Self { + let loaders: Vec = value + .categories + .iter() + .filter_map(|category| GameLoader::from_str(category).ok()) + .collect(); + Self { categories: ModrinthCategories::to_list(&value.project_type, &value.categories), + loaders, package_type: value.project_type, project_id: value.project_id, slug: value.slug, diff --git a/packages/core/src/api/packages/provider/tests.rs b/packages/core/src/api/packages/provider/tests.rs index 15d88b96..09791500 100644 --- a/packages/core/src/api/packages/provider/tests.rs +++ b/packages/core/src/api/packages/provider/tests.rs @@ -3,6 +3,7 @@ use std::sync::LazyLock; use onelauncher_entity::package::{PackageType, Provider}; use crate::api::packages; +use crate::api::packages::data::SearchQuery; use crate::api::packages::provider::ProviderExt; use crate::error::LauncherResult; use crate::utils::DatabaseModelExt; @@ -200,4 +201,24 @@ pub async fn test_download_packages() -> LauncherResult<()> { Ok(()) } +#[tokio::test] +pub async fn test_search_packages() -> LauncherResult<()> { + let cf = init!(); + + for provider in Provider::get_providers().iter() { + if provider == &Provider::CurseForge && !cf { + continue; + } + + let query = SearchQuery::default(); + let res = provider.search(&query).await?; + + dbg!(&res.items); + + assert!(!res.items.is_empty()); + } + + Ok(()) +} + // TODO: Add more tests diff --git a/packages/entity/src/domain/package.rs b/packages/entity/src/domain/package.rs index d680e5d1..e59da9ac 100644 --- a/packages/entity/src/domain/package.rs +++ b/packages/entity/src/domain/package.rs @@ -101,6 +101,6 @@ impl Provider { #[must_use] pub const fn get_providers() -> &'static [Self] { - &[Self::Modrinth, Self::CurseForge, Self::SkyClient] + &[Self::Modrinth, Self::CurseForge] } }