Misc improvements and fixes (#109)

* now utilizing tracing better

* better tracing

* fix mac vs pc oppositional env var issue

* modified loading package

* added droppable loadingbarid that sends completion message

* loading bar

* regressed bug on mac

* fixed non-updated loading bar on playground

* Loading bar improvements

---------

Co-authored-by: Jai A <jaiagr+gpg@pm.me>
This commit is contained in:
Wyatt Verchere
2023-05-08 12:14:08 -07:00
committed by GitHub
parent c79d5c32a6
commit 65c1942037
33 changed files with 726 additions and 294 deletions

View File

@@ -46,7 +46,7 @@ pub async fn authenticate(
))
})?;
let credentials = flow.extract_credentials(&state.io_semaphore).await?;
let credentials = flow.extract_credentials(&state.fetch_semaphore).await?;
users.insert(&credentials).await?;
if state.settings.read().await.default_user.is_none() {
@@ -64,7 +64,7 @@ pub async fn refresh(user: uuid::Uuid) -> crate::Result<Credentials> {
let state = State::get().await?;
let mut users = state.users.write().await;
let io_sempahore = &state.io_semaphore;
let fetch_semaphore = &state.fetch_semaphore;
futures::future::ready(users.get(user).ok_or_else(|| {
crate::ErrorKind::OtherError(format!(
"Tried to refresh nonexistent user with ID {user}"
@@ -73,7 +73,8 @@ pub async fn refresh(user: uuid::Uuid) -> crate::Result<Credentials> {
}))
.and_then(|mut credentials| async move {
if chrono::offset::Utc::now() > credentials.expires {
inner::refresh_credentials(&mut credentials, io_sempahore).await?;
inner::refresh_credentials(&mut credentials, fetch_semaphore)
.await?;
}
users.insert(&credentials).await?;
Ok(credentials)

View File

@@ -61,6 +61,7 @@ pub async fn get_optimal_jre_key(profile: &Profile) -> crate::Result<String> {
version,
profile.metadata.loader_version.as_ref(),
None,
None,
)
.await?;
let optimal_key = match version_info

View File

@@ -1,12 +1,13 @@
use crate::config::MODRINTH_API_URL;
use crate::data::ModLoader;
use crate::event::emit::{
emit_loading, init_loading, loading_try_for_each_concurrent,
emit_loading, init_loading, init_or_edit_loading,
loading_try_for_each_concurrent,
};
use crate::event::LoadingBarType;
use crate::event::{LoadingBarId, LoadingBarType};
use crate::state::{LinkedData, ModrinthProject, ModrinthVersion, SideType};
use crate::util::fetch::{
fetch, fetch_json, fetch_mirrors, write, write_cached_icon,
fetch, fetch_advanced, fetch_json, fetch_mirrors, write, write_cached_icon,
};
use crate::State;
use async_zip::tokio::read::seek::ZipFileReader;
@@ -75,17 +76,30 @@ enum PackDependency {
pub async fn install_pack_from_version_id(
version_id: String,
title: Option<String>,
) -> crate::Result<PathBuf> {
let state = State::get().await?;
let loading_bar = init_loading(
LoadingBarType::PackFileDownload {
pack_name: title,
pack_version: version_id.clone(),
},
100.0,
"Downloading pack file",
)
.await?;
emit_loading(&loading_bar, 0.0, Some("Fetching version")).await?;
let version: ModrinthVersion = fetch_json(
Method::GET,
&format!("{}version/{}", MODRINTH_API_URL, version_id),
None,
None,
&state.io_semaphore,
&state.fetch_semaphore,
)
.await?;
emit_loading(&loading_bar, 10.0, None).await?;
let (url, hash) =
if let Some(file) = version.files.iter().find(|x| x.primary) {
@@ -102,20 +116,31 @@ pub async fn install_pack_from_version_id(
)
})?;
let file = fetch(&url, hash.map(|x| &**x), &state.io_semaphore).await?;
let file = fetch_advanced(
Method::GET,
&url,
hash.map(|x| &**x),
None,
None,
Some((&loading_bar, 70.0)),
&state.fetch_semaphore,
)
.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),
None,
None,
&state.io_semaphore,
&state.fetch_semaphore,
)
.await?;
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.io_semaphore).await?;
let icon_bytes = fetch(&icon_url, None, &state.fetch_semaphore).await?;
let filename = icon_url.rsplit('/').next();
@@ -135,6 +160,7 @@ pub async fn install_pack_from_version_id(
} else {
None
};
emit_loading(&loading_bar, 10.0, None).await?;
install_pack(
file,
@@ -142,6 +168,7 @@ pub async fn install_pack_from_version_id(
Some(project.title),
Some(version.project_id),
Some(version.id),
Some(loading_bar),
)
.await
}
@@ -149,7 +176,7 @@ pub async fn install_pack_from_version_id(
pub async fn install_pack_from_file(path: PathBuf) -> crate::Result<PathBuf> {
let file = fs::read(path).await?;
install_pack(bytes::Bytes::from(file), None, None, None, None).await
install_pack(bytes::Bytes::from(file), None, None, None, None, None).await
}
async fn install_pack(
@@ -158,6 +185,7 @@ async fn install_pack(
override_title: Option<String>,
project_id: Option<String>,
version_id: Option<String>,
existing_loading_bar: Option<LoadingBarId>,
) -> crate::Result<PathBuf> {
let state = &State::get().await?;
@@ -242,14 +270,15 @@ async fn install_pack(
.await?;
let profile = profile_raw.clone();
let result = async {
let loading_bar = init_loading(
let loading_bar = init_or_edit_loading(
existing_loading_bar,
LoadingBarType::PackDownload {
pack_name: pack.name.clone(),
pack_id: project_id,
pack_version: version_id,
},
100.0,
"Downloading modpack...",
"Downloading modpack",
)
.await?;
@@ -260,7 +289,7 @@ async fn install_pack(
.map(Ok::<PackFile, crate::Error>),
None,
Some(&loading_bar),
80.0,
70.0,
num_files,
None,
|project| {
@@ -287,7 +316,7 @@ async fn install_pack(
.hashes
.get(&PackFileHash::Sha1)
.map(|x| &**x),
&state.io_semaphore,
&state.fetch_semaphore,
)
.await?;
@@ -365,11 +394,11 @@ async fn install_pack(
.await
};
emit_loading(&loading_bar, 0.05, Some("Extracting overrides"))
emit_loading(&loading_bar, 0.0, Some("Extracting overrides"))
.await?;
extract_overrides("overrides".to_string()).await?;
extract_overrides("client_overrides".to_string()).await?;
emit_loading(&loading_bar, 0.1, Some("Done extacting overrides"))
emit_loading(&loading_bar, 29.9, Some("Done extacting overrides"))
.await?;
if let Some(profile) = crate::api::profile::get(&profile).await? {
@@ -380,13 +409,6 @@ async fn install_pack(
Some(loading_bar)
),
)?;
} else {
emit_loading(
&loading_bar,
0.1,
Some("Done extacting overrides"),
)
.await?;
}
Ok::<PathBuf, crate::Error>(profile)

View File

@@ -148,7 +148,7 @@ pub async fn update_all(profile_path: &Path) -> crate::Result<()> {
profile_name: profile.metadata.name.clone(),
},
100.0,
"Updating profile...",
"Updating profile",
)
.await?;
@@ -159,7 +159,7 @@ pub async fn update_all(profile_path: &Path) -> crate::Result<()> {
None,
Some(&loading_bar),
100.0,
profile.projects.len(),
profile.projects.keys().len(),
None,
|project| update_project(profile_path, project, Some(true)),
)
@@ -344,7 +344,7 @@ pub async fn remove_project(
}
/// Run Minecraft using a profile and the default credentials, logged in credentials,
/// failing with an error if no credentials are available
#[tracing::instrument(skip_all)]
#[tracing::instrument]
pub async fn run(path: &Path) -> crate::Result<Arc<RwLock<MinecraftChild>>> {
let state = State::get().await?;
@@ -367,7 +367,7 @@ pub async fn run(path: &Path) -> crate::Result<Arc<RwLock<MinecraftChild>>> {
/// Run Minecraft using a profile, and credentials for authentication
/// Returns Arc pointer to RwLock to Child
#[tracing::instrument(skip_all)]
#[tracing::instrument]
pub async fn run_credentials(
path: &Path,
credentials: &auth::Credentials,
@@ -398,6 +398,7 @@ pub async fn run_credentials(
version,
profile.metadata.loader_version.as_ref(),
None,
None,
)
.await?;
let pre_launch_hooks =

View File

@@ -1,4 +1,5 @@
//! Theseus profile management interface
use crate::event::emit::emit_warning;
use crate::state::LinkedData;
use crate::{
event::{emit::emit_profile, ProfilePayloadType},
@@ -15,6 +16,7 @@ use futures::prelude::*;
use std::path::PathBuf;
use tokio::fs;
use tokio_stream::wrappers::ReadDirStream;
use tracing::{info, trace};
use uuid::Uuid;
const DEFAULT_NAME: &str = "Untitled Instance";
@@ -47,6 +49,7 @@ pub async fn profile_create(
linked_data: Option<LinkedData>, // the linked project ID (mainly for modpacks)- used for updating
skip_install_profile: Option<bool>,
) -> crate::Result<PathBuf> {
trace!("Creating new profile. {}", name);
let state = State::get().await?;
let metadata = state.metadata.read().await;
@@ -74,7 +77,7 @@ pub async fn profile_create(
fs::create_dir_all(&path).await?;
}
println!(
info!(
"Creating profile at path {}",
&canonicalize(&path)?.display()
);
@@ -173,7 +176,7 @@ pub async fn profile_create(
extra_arguments: None,
});
} else {
println!("Could not detect optimal JRE: {optimal_version_key}, falling back to system default.");
emit_warning(&format!("Could not detect optimal JRE: {optimal_version_key}, falling back to system default.")).await?;
}
emit_profile(

View File

@@ -19,8 +19,22 @@ pub async fn get() -> crate::Result<Settings> {
pub async fn set(settings: Settings) -> crate::Result<()> {
let state = State::get().await?;
// Replaces the settings struct in the RwLock with the passed argument
let (reset_io, reset_fetch) = async {
let read = state.settings.read().await;
(
settings.max_concurrent_writes != read.max_concurrent_writes,
settings.max_concurrent_downloads != read.max_concurrent_downloads,
)
}
.await;
*state.settings.write().await = settings;
state.reset_semaphore().await; // reset semaphore to new max
if reset_io {
state.reset_io_semaphore().await;
}
if reset_fetch {
state.reset_fetch_semaphore().await;
}
State::sync().await?;
Ok(())
}