Skip to content

Commit e973812

Browse files
committed
feat: SkyClient Part 2
1 parent f49dc71 commit e973812

File tree

10 files changed

+234
-63
lines changed

10 files changed

+234
-63
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ flate2 = { version = "1.0" }
134134
sha1_smol = { version = "1.0", features = [ "std" ] }
135135
sha2 = { version = "0.10" }
136136
murmur2 = { version = "0.1.0" }
137+
md5 = { version = "0.7.0" }
137138
bytes = { version = "1.7" }
138139

139140
# # ============= UTILITY ============= # #

packages/client/src/bindings.ts

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ dirs = { workspace = true }
5151
sha1_smol = { workspace = true }
5252
sha2 = { workspace = true }
5353
murmur2 = { workspace = true }
54+
md5 = { workspace = true }
5455
async_zip = { workspace = true }
5556
discord-rich-presence = { workspace = true }
5657
regex = { workspace = true }

packages/core/src/api/package/content/curseforge.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ impl Into<ManagedVersion> for ModFile {
352352
is_available: self.is_available && files.len() > 0,
353353
files,
354354
game_versions: game_versions,
355-
published: self.file_date,
355+
published: Some(self.file_date),
356356
version_display: self.display_name,
357357
version_type: self.release_type.into(),
358358
}

packages/core/src/api/package/content/mod.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//! Utilities for searching and downloading content packages to `OneLauncher`.
44
55
use std::collections::HashMap;
6+
use std::path::PathBuf;
67

78
use modrinth::{Facet, FacetOperation};
89
use reqwest::Method;
@@ -11,6 +12,7 @@ use serde::{Deserialize, Serialize};
1112
use crate::data::{Loader, ManagedPackage, ManagedUser, ManagedVersion, PackageType};
1213
use crate::package::content::modrinth::FacetBuilder;
1314
use crate::store::{Author, PackageBody, ProviderSearchResults};
15+
use crate::utils::crypto;
1416
use crate::utils::http::fetch_json;
1517
use crate::utils::pagination::Pagination;
1618
use crate::{Result, State};
@@ -178,7 +180,10 @@ impl Providers {
178180
(data.0.into_iter().map(Into::into).collect(), data.1)
179181
}
180182

181-
Self::SkyClient => todo!(),
183+
Self::SkyClient => {
184+
let data = skyclient::get_all_versions(project_id, game_versions, loaders, page, page_size).await?;
185+
(data.0.into_iter().map(Into::into).collect(), data.1)
186+
},
182187
})
183188
}
184189

@@ -194,7 +199,7 @@ impl Providers {
194199
.into_iter()
195200
.map(Into::into)
196201
.collect(),
197-
Self::SkyClient => todo!(),
202+
Self::SkyClient => skyclient::get_versions(versions).await?,
198203
})
199204
}
200205

@@ -230,9 +235,20 @@ impl Providers {
230235
.into_iter()
231236
.map(|(hash, version)| (hash, version.into()))
232237
.collect(),
233-
Self::SkyClient => todo!(),
238+
Self::SkyClient => skyclient::get_versions_by_hashes(hashes).await?,
234239
})
235240
}
241+
242+
pub fn hash_file(&self, path: &PathBuf) -> Result<String> {
243+
match self {
244+
Providers::Modrinth => crypto::sha1_file(path),
245+
Providers::SkyClient => crypto::md5_file(path),
246+
Providers::Curseforge => {
247+
let hash = crypto::murmur2_file(path)?;
248+
Ok(hash.to_string())
249+
},
250+
}
251+
}
236252
}
237253

238254
#[cfg_attr(feature = "specta", derive(specta::Type))]

packages/core/src/api/package/content/modrinth.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ impl From<ModrinthVersion> for ManagedVersion {
177177
changelog: value.changelog,
178178
changelog_url: value.changelog_url,
179179

180-
published: value.date_published,
180+
published: Some(value.date_published),
181181
downloads: value.downloads,
182182
version_type: ManagedVersionReleaseType::from(value.version_type),
183183

packages/core/src/api/package/content/skyclient.rs

Lines changed: 124 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
use std::sync::Arc;
1+
use std::{collections::HashMap, sync::Arc};
22

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

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

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

146+
fn get_managed_version(m: &SkyClientMod, v: &SkyClientModVersion) -> ManagedVersion {
147+
let mut map = HashMap::new();
148+
map.insert(String::from("md5"), v.hash.clone());
149+
150+
ManagedVersion {
151+
id: v.version.clone(),
152+
package_id: m.id.clone(),
153+
author: m.creator.clone(),
154+
changelog_url: None,
155+
changelog: String::new(),
156+
deps: vec![],
157+
downloads: 0,
158+
featured: false,
159+
files: vec![ManagedVersionFile {
160+
file_name: v.file.clone(),
161+
url: v.url.clone(),
162+
file_type: None,
163+
hashes: map,
164+
primary: true,
165+
size: 0,
166+
}],
167+
game_versions: v.game_versions.clone(),
168+
is_available: true,
169+
loaders: v.loaders.iter().map(|l| Loader::from_string(l.to_owned())).collect(),
170+
name: format!("{} v{}", m.display, v.version),
171+
published: None,
172+
version_display: v.version.clone(),
173+
version_type: crate::store::ManagedVersionReleaseType::Release,
174+
}
175+
}
176+
146177
pub async fn get(id: &str) -> Result<SkyClientMod> {
147178
let store = SkyClientStore::get().await?;
148179

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

184-
// pub async fn get_all_versions(
185-
// project_id: &str,
186-
// game_versions: Option<Vec<String>>,
187-
// loaders: Option<Vec<Loader>>,
188-
// page: Option<u32>,
189-
// page_size: Option<u16>,
190-
// ) -> Result<(Vec<ManagedVersion>, Pagination)> {
191-
// let store = SkyClientStore::get().await?;
192-
193-
// let mods = match &store.mods {
194-
// Some(mods) => mods,
195-
// None => return Ok((vec![], Pagination::default()))
196-
// };
197-
198-
199-
// let mut versions = vec![];
200-
201-
// for m in mods {
202-
// if m.id == project_id {
203-
// for v in m.versions {
204-
// let mut can_add = true;
205-
206-
// if let Some(game_versions) = &game_versions {
207-
// can_add = v.game_versions.iter().any(|gv| game_versions.contains(gv))
208-
// }
209-
210-
// if can_add {
211-
// if let Some(loaders) = &loaders {
212-
// can_add = v.loaders.iter().any(|l| loaders.contains(&Loader::from_string(l)))
213-
// }
214-
// }
215-
216-
// if can_add {
217-
//
218-
// }
219-
// }
220-
// }
221-
// }
222-
// }
215+
pub async fn get_all_versions(
216+
project_id: &str,
217+
game_versions: Option<Vec<String>>,
218+
loaders: Option<Vec<Loader>>,
219+
page: Option<u32>,
220+
page_size: Option<u16>,
221+
) -> Result<(Vec<ManagedVersion>, Pagination)> {
222+
let store = SkyClientStore::get().await?;
223+
224+
let mods = match &store.mods {
225+
Some(mods) => mods,
226+
None => return Ok((vec![], Pagination::default()))
227+
};
228+
229+
let mut pagination = Pagination::default();
230+
let mut versions = vec![];
231+
232+
for m in mods {
233+
if m.id == project_id {
234+
for v in &m.versions {
235+
let mut can_add = true;
236+
237+
if let Some(game_versions) = &game_versions {
238+
if !game_versions.is_empty() {
239+
can_add = v.game_versions.iter().any(|gv| game_versions.contains(gv))
240+
}
241+
}
242+
243+
if can_add {
244+
if let Some(loaders) = &loaders {
245+
if !loaders.is_empty() {
246+
can_add = v.loaders.iter().any(|l| loaders.contains(&Loader::from_string(l.to_owned())))
247+
}
248+
}
249+
}
250+
251+
if can_add {
252+
if page_size.map(|ps| versions.len() < ps as usize).unwrap_or(true) && page.map(|p| p <= pagination.index).unwrap_or(true) {
253+
versions.push(get_managed_version(m, v));
254+
}
255+
256+
pagination.total_count += 1;
257+
}
258+
}
259+
}
260+
}
261+
262+
Ok((versions, pagination))
263+
}
264+
265+
pub async fn get_versions(versions: Vec<String>) -> Result<Vec<ManagedVersion>> {
266+
let store = SkyClientStore::get().await?;
267+
268+
let mods = match &store.mods {
269+
Some(mods) => mods,
270+
None => return Ok(vec![])
271+
};
272+
273+
let mut results = vec![];
274+
275+
for m in mods {
276+
for v in &m.versions {
277+
if versions.contains(&v.version) {
278+
results.push(get_managed_version(m, v));
279+
}
280+
}
281+
}
282+
283+
Ok(results)
284+
}
285+
286+
pub async fn get_versions_by_hashes(hashes: Vec<String>) -> Result<HashMap<String, ManagedVersion>> {
287+
let store = SkyClientStore::get().await?;
288+
289+
let mods = match &store.mods {
290+
Some(mods) => mods,
291+
None => return Ok(HashMap::new())
292+
};
293+
294+
let mut results = HashMap::new();
295+
296+
for m in mods {
297+
for v in &m.versions {
298+
if hashes.contains(&v.hash) {
299+
results.insert(v.hash.clone(), get_managed_version(m, v));
300+
}
301+
}
302+
}
303+
304+
Ok(results)
305+
}
223306

224307
pub async fn search(
225308
query: Option<String>,

0 commit comments

Comments
 (0)