You've already forked AstralRinth
forked from didirus/AstralRinth
Migrate to SQLite for Internal Launcher Data (#1300)
* initial migration * barebones profiles * Finish profiles * Add back file watcher * UI support progress * Finish most of cache * Fix options page * Fix forge, finish modrinth auth * Accounts, process cache * Run SQLX prepare * Finish * Run lint + actions * Fix version to be compat with windows * fix lint * actually fix lint * actually fix lint again
This commit is contained in:
@@ -1,16 +1,10 @@
|
||||
use crate::config::MODRINTH_API_URL;
|
||||
use crate::data::ModLoader;
|
||||
use crate::event::emit::{emit_loading, init_loading};
|
||||
use crate::event::{LoadingBarId, LoadingBarType};
|
||||
use crate::prelude::ProfilePathId;
|
||||
use crate::state::{
|
||||
LinkedData, ModrinthProject, ModrinthVersion, ProfileInstallStage, SideType,
|
||||
};
|
||||
use crate::util::fetch::{
|
||||
fetch, fetch_advanced, fetch_json, write_cached_icon,
|
||||
};
|
||||
use crate::state::{CachedEntry, LinkedData, ProfileInstallStage, SideType};
|
||||
use crate::util::fetch::{fetch, fetch_advanced, write_cached_icon};
|
||||
use crate::util::io;
|
||||
use crate::{InnerProjectPathUnix, State};
|
||||
use crate::State;
|
||||
|
||||
use reqwest::Method;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -33,7 +27,7 @@ pub struct PackFormat {
|
||||
#[derive(Serialize, Deserialize, Eq, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PackFile {
|
||||
pub path: InnerProjectPathUnix,
|
||||
pub path: String,
|
||||
pub hashes: HashMap<PackFileHash, String>,
|
||||
pub env: Option<HashMap<EnvType, SideType>>,
|
||||
pub downloads: Vec<String>,
|
||||
@@ -84,7 +78,7 @@ pub enum PackDependency {
|
||||
Minecraft,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
#[serde(rename_all = "camelCase", tag = "type")]
|
||||
pub enum CreatePackLocation {
|
||||
// Create a pack from a modrinth version ID (such as a modpack)
|
||||
@@ -144,7 +138,7 @@ pub struct CreatePackDescription {
|
||||
pub project_id: Option<String>,
|
||||
pub version_id: Option<String>,
|
||||
pub existing_loading_bar: Option<LoadingBarId>,
|
||||
pub profile_path: ProfilePathId,
|
||||
pub profile_path: String,
|
||||
}
|
||||
|
||||
pub fn get_profile_from_pack(
|
||||
@@ -160,9 +154,9 @@ pub fn get_profile_from_pack(
|
||||
name: title,
|
||||
icon_url,
|
||||
linked_data: Some(LinkedData {
|
||||
project_id: Some(project_id),
|
||||
version_id: Some(version_id),
|
||||
locked: Some(true),
|
||||
project_id,
|
||||
version_id,
|
||||
locked: true,
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
@@ -182,13 +176,13 @@ pub fn get_profile_from_pack(
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
#[theseus_macros::debug_pin]
|
||||
|
||||
pub async fn generate_pack_from_version_id(
|
||||
project_id: String,
|
||||
version_id: String,
|
||||
title: String,
|
||||
icon_url: Option<String>,
|
||||
profile_path: ProfilePathId,
|
||||
profile_path: String,
|
||||
|
||||
// Existing loading bar. Unlike when existing_loading_bar is used, this one is pre-initialized with PackFileDownload
|
||||
// For example, you might use this if multiple packs are being downloaded at once and you want to use the same loading bar
|
||||
@@ -202,7 +196,7 @@ pub async fn generate_pack_from_version_id(
|
||||
} else {
|
||||
init_loading(
|
||||
LoadingBarType::PackFileDownload {
|
||||
profile_path: profile_path.get_full_path().await?,
|
||||
profile_path: profile_path.clone(),
|
||||
pack_name: title,
|
||||
icon: icon_url,
|
||||
pack_version: version_id.clone(),
|
||||
@@ -214,16 +208,18 @@ pub async fn generate_pack_from_version_id(
|
||||
};
|
||||
|
||||
emit_loading(&loading_bar, 0.0, Some("Fetching version")).await?;
|
||||
let creds = state.credentials.read().await;
|
||||
let version: ModrinthVersion = fetch_json(
|
||||
Method::GET,
|
||||
&format!("{}version/{}", MODRINTH_API_URL, version_id),
|
||||
let version = CachedEntry::get_version(
|
||||
&version_id,
|
||||
None,
|
||||
None,
|
||||
&state.fetch_semaphore,
|
||||
&creds,
|
||||
&state.pool,
|
||||
&state.api_semaphore,
|
||||
)
|
||||
.await?;
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
crate::ErrorKind::InputError(
|
||||
"Invalid version ID specified!".to_string(),
|
||||
)
|
||||
})?;
|
||||
emit_loading(&loading_bar, 10.0, None).await?;
|
||||
|
||||
let (url, hash) =
|
||||
@@ -249,27 +245,29 @@ pub async fn generate_pack_from_version_id(
|
||||
None,
|
||||
Some((&loading_bar, 70.0)),
|
||||
&state.fetch_semaphore,
|
||||
&creds,
|
||||
&state.pool,
|
||||
)
|
||||
.await?;
|
||||
emit_loading(&loading_bar, 0.0, Some("Fetching project metadata")).await?;
|
||||
|
||||
let project: ModrinthProject = fetch_json(
|
||||
Method::GET,
|
||||
&format!("{}project/{}", MODRINTH_API_URL, version.project_id),
|
||||
let project = CachedEntry::get_project(
|
||||
&version.project_id,
|
||||
None,
|
||||
None,
|
||||
&state.fetch_semaphore,
|
||||
&creds,
|
||||
&state.pool,
|
||||
&state.api_semaphore,
|
||||
)
|
||||
.await?;
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
crate::ErrorKind::InputError(
|
||||
"Invalid project ID specified!".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
emit_loading(&loading_bar, 10.0, Some("Retrieving icon")).await?;
|
||||
let icon = if let Some(icon_url) = project.icon_url {
|
||||
let state = State::get().await?;
|
||||
let icon_bytes =
|
||||
fetch(&icon_url, None, &state.fetch_semaphore, &creds).await?;
|
||||
drop(creds);
|
||||
fetch(&icon_url, None, &state.fetch_semaphore, &state.pool).await?;
|
||||
|
||||
let filename = icon_url.rsplit('/').next();
|
||||
|
||||
@@ -305,10 +303,10 @@ pub async fn generate_pack_from_version_id(
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
#[theseus_macros::debug_pin]
|
||||
|
||||
pub async fn generate_pack_from_file(
|
||||
path: PathBuf,
|
||||
profile_path: ProfilePathId,
|
||||
profile_path: String,
|
||||
) -> crate::Result<CreatePack> {
|
||||
let file = io::read(&path).await?;
|
||||
Ok(CreatePack {
|
||||
@@ -326,9 +324,9 @@ pub async fn generate_pack_from_file(
|
||||
|
||||
/// Sets generated profile attributes to the pack ones (using profile::edit)
|
||||
/// This includes the pack name, icon, game version, loader version, and loader
|
||||
#[theseus_macros::debug_pin]
|
||||
|
||||
pub async fn set_profile_information(
|
||||
profile_path: ProfilePathId,
|
||||
profile_path: String,
|
||||
description: &CreatePackDescription,
|
||||
backup_name: &str,
|
||||
dependencies: &HashMap<PackDependency, String>,
|
||||
@@ -371,10 +369,10 @@ pub async fn set_profile_information(
|
||||
|
||||
let mod_loader = mod_loader.unwrap_or(ModLoader::Vanilla);
|
||||
let loader_version = if mod_loader != ModLoader::Vanilla {
|
||||
crate::profile::create::get_loader_version_from_loader(
|
||||
game_version.clone(),
|
||||
crate::launcher::get_loader_version_from_profile(
|
||||
game_version,
|
||||
mod_loader,
|
||||
loader_version.cloned(),
|
||||
loader_version.cloned().as_deref(),
|
||||
)
|
||||
.await?
|
||||
} else {
|
||||
@@ -382,35 +380,36 @@ pub async fn set_profile_information(
|
||||
};
|
||||
// Sets values in profile
|
||||
crate::api::profile::edit(&profile_path, |prof| {
|
||||
prof.metadata.name = description
|
||||
prof.name = description
|
||||
.override_title
|
||||
.clone()
|
||||
.unwrap_or_else(|| backup_name.to_string());
|
||||
prof.install_stage = ProfileInstallStage::PackInstalling;
|
||||
|
||||
let project_id = description.project_id.clone();
|
||||
let version_id = description.version_id.clone();
|
||||
if let Some(ref project_id) = description.project_id {
|
||||
if let Some(ref version_id) = description.version_id {
|
||||
prof.linked_data = Some(LinkedData {
|
||||
project_id: project_id.clone(),
|
||||
version_id: version_id.clone(),
|
||||
locked: if !ignore_lock {
|
||||
true
|
||||
} else {
|
||||
prof.linked_data
|
||||
.as_ref()
|
||||
.map(|x| x.locked)
|
||||
.unwrap_or(true)
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
prof.metadata.linked_data = if project_id.is_some()
|
||||
&& version_id.is_some()
|
||||
{
|
||||
Some(LinkedData {
|
||||
project_id,
|
||||
version_id,
|
||||
locked: if !ignore_lock {
|
||||
Some(true)
|
||||
} else {
|
||||
prof.metadata.linked_data.as_ref().and_then(|x| x.locked)
|
||||
},
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
prof.metadata.icon.clone_from(&description.icon);
|
||||
prof.metadata.game_version.clone_from(game_version);
|
||||
prof.metadata.loader_version.clone_from(&loader_version);
|
||||
prof.metadata.loader = mod_loader;
|
||||
prof.icon_path = description
|
||||
.icon
|
||||
.clone()
|
||||
.map(|x| x.to_string_lossy().to_string());
|
||||
prof.game_version.clone_from(game_version);
|
||||
prof.loader_version = loader_version.clone().map(|x| x.id);
|
||||
prof.loader = mod_loader;
|
||||
|
||||
async { Ok(()) }
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user