Skip to content

Commit

Permalink
feat: SkyClient Part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
LynithDev committed Dec 8, 2024
1 parent f49dc71 commit e973812
Show file tree
Hide file tree
Showing 10 changed files with 234 additions and 63 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ flate2 = { version = "1.0" }
sha1_smol = { version = "1.0", features = [ "std" ] }
sha2 = { version = "0.10" }
murmur2 = { version = "0.1.0" }
md5 = { version = "0.7.0" }
bytes = { version = "1.7" }

# # ============= UTILITY ============= # #
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/bindings.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ dirs = { workspace = true }
sha1_smol = { workspace = true }
sha2 = { workspace = true }
murmur2 = { workspace = true }
md5 = { workspace = true }
async_zip = { workspace = true }
discord-rich-presence = { workspace = true }
regex = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/api/package/content/curseforge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ impl Into<ManagedVersion> for ModFile {
is_available: self.is_available && files.len() > 0,
files,
game_versions: game_versions,
published: self.file_date,
published: Some(self.file_date),
version_display: self.display_name,
version_type: self.release_type.into(),
}
Expand Down
22 changes: 19 additions & 3 deletions packages/core/src/api/package/content/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! Utilities for searching and downloading content packages to `OneLauncher`.
use std::collections::HashMap;
use std::path::PathBuf;

use modrinth::{Facet, FacetOperation};
use reqwest::Method;
Expand All @@ -11,6 +12,7 @@ use serde::{Deserialize, Serialize};
use crate::data::{Loader, ManagedPackage, ManagedUser, ManagedVersion, PackageType};
use crate::package::content::modrinth::FacetBuilder;
use crate::store::{Author, PackageBody, ProviderSearchResults};
use crate::utils::crypto;
use crate::utils::http::fetch_json;
use crate::utils::pagination::Pagination;
use crate::{Result, State};
Expand Down Expand Up @@ -178,7 +180,10 @@ impl Providers {
(data.0.into_iter().map(Into::into).collect(), data.1)
}

Self::SkyClient => todo!(),
Self::SkyClient => {
let data = skyclient::get_all_versions(project_id, game_versions, loaders, page, page_size).await?;
(data.0.into_iter().map(Into::into).collect(), data.1)
},
})
}

Expand All @@ -194,7 +199,7 @@ impl Providers {
.into_iter()
.map(Into::into)
.collect(),
Self::SkyClient => todo!(),
Self::SkyClient => skyclient::get_versions(versions).await?,
})
}

Expand Down Expand Up @@ -230,9 +235,20 @@ impl Providers {
.into_iter()
.map(|(hash, version)| (hash, version.into()))
.collect(),
Self::SkyClient => todo!(),
Self::SkyClient => skyclient::get_versions_by_hashes(hashes).await?,
})
}

pub fn hash_file(&self, path: &PathBuf) -> Result<String> {
match self {
Providers::Modrinth => crypto::sha1_file(path),
Providers::SkyClient => crypto::md5_file(path),
Providers::Curseforge => {
let hash = crypto::murmur2_file(path)?;
Ok(hash.to_string())
},
}
}
}

#[cfg_attr(feature = "specta", derive(specta::Type))]
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/api/package/content/modrinth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ impl From<ModrinthVersion> for ManagedVersion {
changelog: value.changelog,
changelog_url: value.changelog_url,

published: value.date_published,
published: Some(value.date_published),
downloads: value.downloads,
version_type: ManagedVersionReleaseType::from(value.version_type),

Expand Down
165 changes: 124 additions & 41 deletions packages/core/src/api/package/content/skyclient.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::sync::Arc;
use std::{collections::HashMap, sync::Arc};

use serde::{de::DeserializeOwned, Deserialize, Serialize};
use tokio::sync::{OnceCell, RwLock};

use crate::{data::{Loader, ManagedPackage, ManagedUser, ManagedVersion}, store::{ProviderSearchResults, SearchResult}, utils::{http, pagination::Pagination}, Result, State};
use crate::{data::{Loader, ManagedPackage, ManagedUser, ManagedVersion}, store::{ManagedVersionFile, ProviderSearchResults, SearchResult}, utils::{http, pagination::Pagination}, Result, State};

async fn fetch<T: DeserializeOwned>(url: &str) -> Result<T> {
let state = State::get().await?;
Expand Down Expand Up @@ -143,6 +143,37 @@ pub struct SkyClientModVersion {
pub mod_id: Option<String>,
}

fn get_managed_version(m: &SkyClientMod, v: &SkyClientModVersion) -> ManagedVersion {
let mut map = HashMap::new();
map.insert(String::from("md5"), v.hash.clone());

ManagedVersion {
id: v.version.clone(),
package_id: m.id.clone(),
author: m.creator.clone(),
changelog_url: None,
changelog: String::new(),
deps: vec![],
downloads: 0,
featured: false,
files: vec![ManagedVersionFile {
file_name: v.file.clone(),
url: v.url.clone(),
file_type: None,
hashes: map,
primary: true,
size: 0,
}],
game_versions: v.game_versions.clone(),
is_available: true,
loaders: v.loaders.iter().map(|l| Loader::from_string(l.to_owned())).collect(),
name: format!("{} v{}", m.display, v.version),
published: None,
version_display: v.version.clone(),
version_type: crate::store::ManagedVersionReleaseType::Release,
}
}

pub async fn get(id: &str) -> Result<SkyClientMod> {
let store = SkyClientStore::get().await?;

Expand Down Expand Up @@ -181,45 +212,97 @@ pub async fn get_multiple(slug_or_ids: &[String]) -> Result<Vec<SkyClientMod>> {
Ok(results)
}

// pub async fn get_all_versions(
// project_id: &str,
// game_versions: Option<Vec<String>>,
// loaders: Option<Vec<Loader>>,
// page: Option<u32>,
// page_size: Option<u16>,
// ) -> Result<(Vec<ManagedVersion>, Pagination)> {
// let store = SkyClientStore::get().await?;

// let mods = match &store.mods {
// Some(mods) => mods,
// None => return Ok((vec![], Pagination::default()))
// };


// let mut versions = vec![];

// for m in mods {
// if m.id == project_id {
// for v in m.versions {
// let mut can_add = true;

// if let Some(game_versions) = &game_versions {
// can_add = v.game_versions.iter().any(|gv| game_versions.contains(gv))
// }

// if can_add {
// if let Some(loaders) = &loaders {
// can_add = v.loaders.iter().any(|l| loaders.contains(&Loader::from_string(l)))
// }
// }

// if can_add {
//
// }
// }
// }
// }
// }
pub async fn get_all_versions(
project_id: &str,
game_versions: Option<Vec<String>>,
loaders: Option<Vec<Loader>>,
page: Option<u32>,
page_size: Option<u16>,
) -> Result<(Vec<ManagedVersion>, Pagination)> {
let store = SkyClientStore::get().await?;

let mods = match &store.mods {
Some(mods) => mods,
None => return Ok((vec![], Pagination::default()))
};

let mut pagination = Pagination::default();
let mut versions = vec![];

for m in mods {
if m.id == project_id {
for v in &m.versions {
let mut can_add = true;

if let Some(game_versions) = &game_versions {
if !game_versions.is_empty() {
can_add = v.game_versions.iter().any(|gv| game_versions.contains(gv))
}
}

if can_add {
if let Some(loaders) = &loaders {
if !loaders.is_empty() {
can_add = v.loaders.iter().any(|l| loaders.contains(&Loader::from_string(l.to_owned())))
}
}
}

if can_add {
if page_size.map(|ps| versions.len() < ps as usize).unwrap_or(true) && page.map(|p| p <= pagination.index).unwrap_or(true) {
versions.push(get_managed_version(m, v));
}

pagination.total_count += 1;
}
}
}
}

Ok((versions, pagination))
}

pub async fn get_versions(versions: Vec<String>) -> Result<Vec<ManagedVersion>> {
let store = SkyClientStore::get().await?;

let mods = match &store.mods {
Some(mods) => mods,
None => return Ok(vec![])
};

let mut results = vec![];

for m in mods {
for v in &m.versions {
if versions.contains(&v.version) {
results.push(get_managed_version(m, v));
}
}
}

Ok(results)
}

pub async fn get_versions_by_hashes(hashes: Vec<String>) -> Result<HashMap<String, ManagedVersion>> {
let store = SkyClientStore::get().await?;

let mods = match &store.mods {
Some(mods) => mods,
None => return Ok(HashMap::new())
};

let mut results = HashMap::new();

for m in mods {
for v in &m.versions {
if hashes.contains(&v.hash) {
results.insert(v.hash.clone(), get_managed_version(m, v));
}
}
}

Ok(results)
}

pub async fn search(
query: Option<String>,
Expand Down
Loading

0 comments on commit e973812

Please sign in to comment.