You've already forked AstralRinth
forked from didirus/AstralRinth
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:
@@ -1,12 +1,11 @@
|
||||
//! Authentication flow based on Hydra
|
||||
use crate::util::fetch::{fetch_advanced, fetch_json};
|
||||
use crate::util::fetch::{fetch_advanced, fetch_json, FetchSemaphore};
|
||||
use async_tungstenite as ws;
|
||||
use chrono::{prelude::*, Duration};
|
||||
use futures::prelude::*;
|
||||
use lazy_static::lazy_static;
|
||||
use reqwest::Method;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::sync::{RwLock, Semaphore};
|
||||
use url::Url;
|
||||
|
||||
lazy_static! {
|
||||
@@ -95,7 +94,7 @@ impl HydraAuthFlow<ws::tokio::ConnectStream> {
|
||||
|
||||
pub async fn extract_credentials(
|
||||
&mut self,
|
||||
semaphore: &RwLock<Semaphore>,
|
||||
semaphore: &FetchSemaphore,
|
||||
) -> crate::Result<Credentials> {
|
||||
// Minecraft bearer token
|
||||
let token_resp = self
|
||||
@@ -130,7 +129,7 @@ impl HydraAuthFlow<ws::tokio::ConnectStream> {
|
||||
|
||||
pub async fn refresh_credentials(
|
||||
credentials: &mut Credentials,
|
||||
semaphore: &RwLock<Semaphore>,
|
||||
semaphore: &FetchSemaphore,
|
||||
) -> crate::Result<()> {
|
||||
let resp = fetch_json::<TokenJSON>(
|
||||
Method::POST,
|
||||
@@ -152,7 +151,7 @@ pub async fn refresh_credentials(
|
||||
// Helpers
|
||||
async fn fetch_info(
|
||||
token: &str,
|
||||
semaphore: &RwLock<Semaphore>,
|
||||
semaphore: &FetchSemaphore,
|
||||
) -> crate::Result<ProfileInfoJSON> {
|
||||
let result = fetch_advanced(
|
||||
Method::GET,
|
||||
@@ -160,6 +159,7 @@ async fn fetch_info(
|
||||
None,
|
||||
None,
|
||||
Some(("Authorization", &format!("Bearer {token}"))),
|
||||
None,
|
||||
semaphore,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
//! Downloader for Minecraft data
|
||||
|
||||
use crate::{
|
||||
event::emit::{emit_loading, loading_try_for_each_concurrent},
|
||||
event::{
|
||||
emit::{emit_loading, loading_try_for_each_concurrent},
|
||||
LoadingBarId,
|
||||
},
|
||||
state::State,
|
||||
util::{fetch::*, platform::OsExt},
|
||||
};
|
||||
@@ -15,24 +18,26 @@ use daedalus::{
|
||||
};
|
||||
use futures::prelude::*;
|
||||
use tokio::{fs, sync::OnceCell};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub async fn download_minecraft(
|
||||
st: &State,
|
||||
version: &GameVersionInfo,
|
||||
loading_bar: Uuid,
|
||||
loading_bar: &LoadingBarId,
|
||||
) -> crate::Result<()> {
|
||||
log::info!("Downloading Minecraft version {}", version.id);
|
||||
let assets_index = download_assets_index(st, version).await?;
|
||||
tracing::info!("Downloading Minecraft version {}", version.id);
|
||||
// 5
|
||||
let assets_index =
|
||||
download_assets_index(st, version, Some(loading_bar)).await?;
|
||||
|
||||
tokio::try_join! {
|
||||
download_client(st, version, Some(&loading_bar)),
|
||||
download_assets(st, version.assets == "legacy", &assets_index, Some(&loading_bar)),
|
||||
download_libraries(st, version.libraries.as_slice(), &version.id, Some(&loading_bar))
|
||||
// Total loading sums to 80
|
||||
download_client(st, version, Some(loading_bar)), // 10
|
||||
download_assets(st, version.assets == "legacy", &assets_index, Some(loading_bar)), // 35
|
||||
download_libraries(st, version.libraries.as_slice(), &version.id, Some(loading_bar)) // 35
|
||||
}?;
|
||||
|
||||
log::info!("Done downloading Minecraft!");
|
||||
tracing::info!("Done downloading Minecraft!");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -42,10 +47,11 @@ pub async fn download_version_info(
|
||||
version: &GameVersion,
|
||||
loader: Option<&LoaderVersion>,
|
||||
force: Option<bool>,
|
||||
loading_bar: Option<&LoadingBarId>,
|
||||
) -> crate::Result<GameVersionInfo> {
|
||||
let version_id = loader
|
||||
.map_or(version.id.clone(), |it| format!("{}-{}", version.id, it.id));
|
||||
log::debug!("Loading version info for Minecraft {version_id}");
|
||||
tracing::debug!("Loading version info for Minecraft {version_id}");
|
||||
let path = st
|
||||
.directories
|
||||
.version_dir(&version_id)
|
||||
@@ -57,7 +63,7 @@ pub async fn download_version_info(
|
||||
.await
|
||||
.and_then(|ref it| Ok(serde_json::from_slice(it)?))
|
||||
} else {
|
||||
log::info!("Downloading version info for version {}", &version.id);
|
||||
tracing::info!("Downloading version info for version {}", &version.id);
|
||||
let mut info = d::minecraft::fetch_version_info(version).await?;
|
||||
|
||||
if let Some(loader) = loader {
|
||||
@@ -70,7 +76,25 @@ pub async fn download_version_info(
|
||||
Ok(info)
|
||||
}?;
|
||||
|
||||
log::debug!("Loaded version info for Minecraft {version_id}");
|
||||
if let Some(loading_bar) = loading_bar {
|
||||
emit_loading(
|
||||
loading_bar,
|
||||
if res
|
||||
.processors
|
||||
.as_ref()
|
||||
.map(|x| !x.is_empty())
|
||||
.unwrap_or(false)
|
||||
{
|
||||
5.0
|
||||
} else {
|
||||
15.0
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
tracing::debug!("Loaded version info for Minecraft {version_id}");
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
@@ -78,10 +102,10 @@ pub async fn download_version_info(
|
||||
pub async fn download_client(
|
||||
st: &State,
|
||||
version_info: &GameVersionInfo,
|
||||
loading_bar: Option<&Uuid>,
|
||||
loading_bar: Option<&LoadingBarId>,
|
||||
) -> crate::Result<()> {
|
||||
let version = &version_info.id;
|
||||
log::debug!("Locating client for version {version}");
|
||||
tracing::debug!("Locating client for version {version}");
|
||||
let client_download = version_info
|
||||
.downloads
|
||||
.get(&d::minecraft::DownloadType::Client)
|
||||
@@ -100,17 +124,17 @@ pub async fn download_client(
|
||||
let bytes = fetch(
|
||||
&client_download.url,
|
||||
Some(&client_download.sha1),
|
||||
&st.io_semaphore,
|
||||
&st.fetch_semaphore,
|
||||
)
|
||||
.await?;
|
||||
write(&path, &bytes, &st.io_semaphore).await?;
|
||||
log::info!("Fetched client version {version}");
|
||||
tracing::trace!("Fetched client version {version}");
|
||||
}
|
||||
if let Some(loading_bar) = loading_bar {
|
||||
emit_loading(loading_bar, 20.0, None).await?;
|
||||
emit_loading(loading_bar, 10.0, None).await?;
|
||||
}
|
||||
|
||||
log::debug!("Client loaded for version {version}!");
|
||||
tracing::debug!("Client loaded for version {version}!");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -118,8 +142,9 @@ pub async fn download_client(
|
||||
pub async fn download_assets_index(
|
||||
st: &State,
|
||||
version: &GameVersionInfo,
|
||||
loading_bar: Option<&LoadingBarId>,
|
||||
) -> crate::Result<AssetsIndex> {
|
||||
log::debug!("Loading assets index");
|
||||
tracing::debug!("Loading assets index");
|
||||
let path = st
|
||||
.directories
|
||||
.assets_index_dir()
|
||||
@@ -133,11 +158,14 @@ pub async fn download_assets_index(
|
||||
} else {
|
||||
let index = d::minecraft::fetch_assets_index(version).await?;
|
||||
write(&path, &serde_json::to_vec(&index)?, &st.io_semaphore).await?;
|
||||
log::info!("Fetched assets index");
|
||||
tracing::info!("Fetched assets index");
|
||||
Ok(index)
|
||||
}?;
|
||||
|
||||
log::debug!("Assets index successfully loaded!");
|
||||
if let Some(loading_bar) = loading_bar {
|
||||
emit_loading(loading_bar, 5.0, None).await?;
|
||||
}
|
||||
tracing::debug!("Assets index successfully loaded!");
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
@@ -146,9 +174,9 @@ pub async fn download_assets(
|
||||
st: &State,
|
||||
with_legacy: bool,
|
||||
index: &AssetsIndex,
|
||||
loading_bar: Option<&Uuid>,
|
||||
loading_bar: Option<&LoadingBarId>,
|
||||
) -> crate::Result<()> {
|
||||
log::debug!("Loading assets");
|
||||
tracing::debug!("Loading assets");
|
||||
let num_futs = index.objects.len();
|
||||
let assets = stream::iter(index.objects.iter())
|
||||
.map(Ok::<(&String, &Asset), crate::Error>);
|
||||
@@ -156,7 +184,7 @@ pub async fn download_assets(
|
||||
loading_try_for_each_concurrent(assets,
|
||||
None,
|
||||
loading_bar,
|
||||
50.0,
|
||||
35.0,
|
||||
num_futs,
|
||||
None,
|
||||
|(name, asset)| async move {
|
||||
@@ -172,33 +200,33 @@ pub async fn download_assets(
|
||||
async {
|
||||
if !resource_path.exists() {
|
||||
let resource = fetch_cell
|
||||
.get_or_try_init(|| fetch(&url, Some(hash), &st.io_semaphore))
|
||||
.get_or_try_init(|| fetch(&url, Some(hash), &st.fetch_semaphore))
|
||||
.await?;
|
||||
write(&resource_path, resource, &st.io_semaphore).await?;
|
||||
log::info!("Fetched asset with hash {hash}");
|
||||
tracing::trace!("Fetched asset with hash {hash}");
|
||||
}
|
||||
Ok::<_, crate::Error>(())
|
||||
},
|
||||
async {
|
||||
if with_legacy {
|
||||
let resource = fetch_cell
|
||||
.get_or_try_init(|| fetch(&url, Some(hash), &st.io_semaphore))
|
||||
.get_or_try_init(|| fetch(&url, Some(hash), &st.fetch_semaphore))
|
||||
.await?;
|
||||
let resource_path = st.directories.legacy_assets_dir().join(
|
||||
name.replace('/', &String::from(std::path::MAIN_SEPARATOR))
|
||||
);
|
||||
write(&resource_path, resource, &st.io_semaphore).await?;
|
||||
log::info!("Fetched legacy asset with hash {hash}");
|
||||
tracing::trace!("Fetched legacy asset with hash {hash}");
|
||||
}
|
||||
Ok::<_, crate::Error>(())
|
||||
},
|
||||
}?;
|
||||
|
||||
log::debug!("Loaded asset with hash {hash}");
|
||||
tracing::trace!("Loaded asset with hash {hash}");
|
||||
Ok(())
|
||||
}).await?;
|
||||
|
||||
log::debug!("Done loading assets!");
|
||||
tracing::debug!("Done loading assets!");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -207,9 +235,9 @@ pub async fn download_libraries(
|
||||
st: &State,
|
||||
libraries: &[Library],
|
||||
version: &str,
|
||||
loading_bar: Option<&Uuid>,
|
||||
loading_bar: Option<&LoadingBarId>,
|
||||
) -> crate::Result<()> {
|
||||
log::debug!("Loading libraries");
|
||||
tracing::debug!("Loading libraries");
|
||||
|
||||
tokio::try_join! {
|
||||
fs::create_dir_all(st.directories.libraries_dir()),
|
||||
@@ -218,7 +246,7 @@ pub async fn download_libraries(
|
||||
let num_files = libraries.len();
|
||||
loading_try_for_each_concurrent(
|
||||
stream::iter(libraries.iter())
|
||||
.map(Ok::<&Library, crate::Error>), None, loading_bar,50.0,num_files, None,|library| async move {
|
||||
.map(Ok::<&Library, crate::Error>), None, loading_bar,35.0,num_files, None,|library| async move {
|
||||
if let Some(rules) = &library.rules {
|
||||
if !rules.iter().all(super::parse_rule) {
|
||||
return Ok(());
|
||||
@@ -235,10 +263,10 @@ pub async fn download_libraries(
|
||||
artifact: Some(ref artifact),
|
||||
..
|
||||
}) => {
|
||||
let bytes = fetch(&artifact.url, Some(&artifact.sha1), &st.io_semaphore)
|
||||
let bytes = fetch(&artifact.url, Some(&artifact.sha1), &st.fetch_semaphore)
|
||||
.await?;
|
||||
write(&path, &bytes, &st.io_semaphore).await?;
|
||||
log::info!("Fetched library {}", &library.name);
|
||||
tracing::trace!("Fetched library {}", &library.name);
|
||||
Ok::<_, crate::Error>(())
|
||||
}
|
||||
None => {
|
||||
@@ -250,9 +278,9 @@ pub async fn download_libraries(
|
||||
&artifact_path
|
||||
].concat();
|
||||
|
||||
let bytes = fetch(&url, None, &st.io_semaphore).await?;
|
||||
let bytes = fetch(&url, None, &st.fetch_semaphore).await?;
|
||||
write(&path, &bytes, &st.io_semaphore).await?;
|
||||
log::info!("Fetched library {}", &library.name);
|
||||
tracing::trace!("Fetched library {}", &library.name);
|
||||
Ok::<_, crate::Error>(())
|
||||
}
|
||||
_ => Ok(())
|
||||
@@ -277,15 +305,15 @@ pub async fn download_libraries(
|
||||
);
|
||||
|
||||
if let Some(native) = classifiers.get(&parsed_key) {
|
||||
let data = fetch(&native.url, Some(&native.sha1), &st.io_semaphore).await?;
|
||||
let data = fetch(&native.url, Some(&native.sha1), &st.fetch_semaphore).await?;
|
||||
let reader = std::io::Cursor::new(&data);
|
||||
if let Ok(mut archive) = zip::ZipArchive::new(reader) {
|
||||
match archive.extract(&st.directories.version_natives_dir(version)) {
|
||||
Ok(_) => log::info!("Fetched native {}", &library.name),
|
||||
Err(err) => log::error!("Failed extracting native {}. err: {}", &library.name, err)
|
||||
Ok(_) => tracing::info!("Fetched native {}", &library.name),
|
||||
Err(err) => tracing::error!("Failed extracting native {}. err: {}", &library.name, err)
|
||||
}
|
||||
} else {
|
||||
log::error!("Failed extracting native {}", &library.name)
|
||||
tracing::error!("Failed extracting native {}", &library.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -294,11 +322,11 @@ pub async fn download_libraries(
|
||||
}
|
||||
}?;
|
||||
|
||||
log::debug!("Loaded library {}", library.name);
|
||||
tracing::debug!("Loaded library {}", library.name);
|
||||
Ok(())
|
||||
}
|
||||
).await?;
|
||||
|
||||
log::debug!("Done loading libraries!");
|
||||
tracing::debug!("Done loading libraries!");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Logic for launching Minecraft
|
||||
use crate::event::emit::{emit_loading, init_or_edit_loading};
|
||||
use crate::event::LoadingBarType;
|
||||
use crate::event::{LoadingBarId, LoadingBarType};
|
||||
use crate::{
|
||||
process,
|
||||
state::{self as st, MinecraftChild},
|
||||
@@ -53,9 +53,10 @@ macro_rules! processor_rules {
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(profile))]
|
||||
pub async fn install_minecraft(
|
||||
profile: &Profile,
|
||||
existing_loading_bar: Option<Uuid>,
|
||||
existing_loading_bar: Option<LoadingBarId>,
|
||||
) -> crate::Result<()> {
|
||||
let state = State::get().await?;
|
||||
let instance_path = &canonicalize(&profile.path)?;
|
||||
@@ -79,14 +80,6 @@ pub async fn install_minecraft(
|
||||
format!("{}-{}", version.id.clone(), it.id.clone())
|
||||
});
|
||||
|
||||
let mut version_info = download::download_version_info(
|
||||
&state,
|
||||
version,
|
||||
profile.metadata.loader_version.as_ref(),
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let loading_bar = init_or_edit_loading(
|
||||
existing_loading_bar,
|
||||
LoadingBarType::MinecraftDownload {
|
||||
@@ -95,11 +88,22 @@ pub async fn install_minecraft(
|
||||
profile_uuid: profile.uuid,
|
||||
},
|
||||
100.0,
|
||||
"Downloading Minecraft...",
|
||||
"Downloading Minecraft",
|
||||
)
|
||||
.await?;
|
||||
|
||||
download::download_minecraft(&state, &version_info, loading_bar).await?;
|
||||
// Download version info
|
||||
let mut version_info = download::download_version_info(
|
||||
&state,
|
||||
version,
|
||||
profile.metadata.loader_version.as_ref(),
|
||||
None,
|
||||
Some(&loading_bar),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Download minecraft (5-90)
|
||||
download::download_minecraft(&state, &version_info, &loading_bar).await?;
|
||||
|
||||
let client_path = state
|
||||
.directories
|
||||
@@ -131,10 +135,11 @@ pub async fn install_minecraft(
|
||||
.await?;
|
||||
let total_length = processors.len();
|
||||
|
||||
// Forge processors (90-100)
|
||||
for (index, processor) in processors.iter().enumerate() {
|
||||
emit_loading(
|
||||
&loading_bar,
|
||||
index as f64 / total_length as f64,
|
||||
10.0 / total_length as f64,
|
||||
Some(&format!(
|
||||
"Running forge processor {}/{}",
|
||||
index, total_length
|
||||
@@ -223,7 +228,7 @@ pub async fn launch_minecraft(
|
||||
install_minecraft(profile, None).await?;
|
||||
}
|
||||
|
||||
let state = st::State::get().await?;
|
||||
let state = State::get().await?;
|
||||
let metadata = state.metadata.read().await;
|
||||
let instance_path = &canonicalize(&profile.path)?;
|
||||
|
||||
@@ -250,6 +255,7 @@ pub async fn launch_minecraft(
|
||||
version,
|
||||
profile.metadata.loader_version.as_ref(),
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -320,8 +326,12 @@ pub async fn launch_minecraft(
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped());
|
||||
|
||||
// Clear cargo-added env varaibles for debugging, and add settings env vars
|
||||
clear_cargo_env_vals(&mut command).envs(env_args);
|
||||
// CARGO-set DYLD_LIBRARY_PATH breaks Minecraft on macOS during testing on playground
|
||||
#[cfg(target_os = "macos")]
|
||||
if std::env::var("CARGO").is_ok() {
|
||||
command.env_remove("DYLD_FALLBACK_LIBRARY_PATH");
|
||||
}
|
||||
command.envs(env_args);
|
||||
|
||||
// Get Modrinth logs directories
|
||||
let datetime_string =
|
||||
@@ -351,14 +361,3 @@ pub async fn launch_minecraft(
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
fn clear_cargo_env_vals(command: &mut Command) -> &mut Command {
|
||||
for (key, _) in std::env::vars() {
|
||||
command.env_remove(key);
|
||||
|
||||
// if key.starts_with("CARGO") {
|
||||
// command.env_remove(key);
|
||||
// }
|
||||
}
|
||||
command
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user