You've already forked AstralRinth
forked from didirus/AstralRinth
Updating + Profile Repairs + Performance Improvements (#97)
* repairing * Main framework for updating * add jsconfig * more work * Improve performance * Finish updating * run lint
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
//! Authentication flow based on Hydra
|
||||
use crate::util::fetch::{fetch_advanced, fetch_json};
|
||||
use async_tungstenite as ws;
|
||||
use bincode::{Decode, Encode};
|
||||
use chrono::{prelude::*, Duration};
|
||||
use futures::prelude::*;
|
||||
use lazy_static::lazy_static;
|
||||
@@ -50,14 +49,12 @@ struct ProfileInfoJSON {
|
||||
}
|
||||
|
||||
// Login information
|
||||
#[derive(Encode, Decode, Serialize, Deserialize, Clone, Debug)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct Credentials {
|
||||
#[bincode(with_serde)]
|
||||
pub id: uuid::Uuid,
|
||||
pub username: String,
|
||||
pub access_token: String,
|
||||
pub refresh_token: String,
|
||||
#[bincode(with_serde)]
|
||||
pub expires: DateTime<Utc>,
|
||||
_ctor_scope: std::marker::PhantomData<()>,
|
||||
}
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
//! Downloader for Minecraft data
|
||||
|
||||
use crate::{
|
||||
event::{
|
||||
emit::{emit_loading, init_loading, loading_try_for_each_concurrent},
|
||||
LoadingBarId, LoadingBarType,
|
||||
},
|
||||
process::Profile,
|
||||
event::emit::{emit_loading, loading_try_for_each_concurrent},
|
||||
state::State,
|
||||
util::{fetch::*, platform::OsExt},
|
||||
};
|
||||
@@ -19,26 +15,17 @@ 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,
|
||||
profile: &Profile,
|
||||
loading_bar: Uuid,
|
||||
) -> crate::Result<()> {
|
||||
log::info!("Downloading Minecraft version {}", version.id);
|
||||
let assets_index = download_assets_index(st, version).await?;
|
||||
|
||||
let loading_bar = init_loading(
|
||||
LoadingBarType::MinecraftDownload {
|
||||
// If we are downloading minecraft for a profile, provide its name and uuid
|
||||
profile_name: profile.metadata.name.clone(),
|
||||
profile_uuid: profile.uuid,
|
||||
},
|
||||
100.0,
|
||||
"Downloading Minecraft...",
|
||||
)
|
||||
.await?;
|
||||
tokio::try_join! {
|
||||
download_client(st, version, Some(&loading_bar)),
|
||||
download_assets(st, version.assets == "legacy", &assets_index, Some(&loading_bar)),
|
||||
@@ -54,6 +41,7 @@ pub async fn download_version_info(
|
||||
st: &State,
|
||||
version: &GameVersion,
|
||||
loader: Option<&LoaderVersion>,
|
||||
force: Option<bool>,
|
||||
) -> crate::Result<GameVersionInfo> {
|
||||
let version_id = loader
|
||||
.map_or(version.id.clone(), |it| format!("{}-{}", version.id, it.id));
|
||||
@@ -63,7 +51,7 @@ pub async fn download_version_info(
|
||||
.version_dir(&version_id)
|
||||
.join(format!("{version_id}.json"));
|
||||
|
||||
let res = if path.exists() {
|
||||
let res = if path.exists() && !force.unwrap_or(false) {
|
||||
fs::read(path)
|
||||
.err_into::<crate::Error>()
|
||||
.await
|
||||
@@ -90,7 +78,7 @@ pub async fn download_version_info(
|
||||
pub async fn download_client(
|
||||
st: &State,
|
||||
version_info: &GameVersionInfo,
|
||||
loading_bar: Option<&LoadingBarId>,
|
||||
loading_bar: Option<&Uuid>,
|
||||
) -> crate::Result<()> {
|
||||
let version = &version_info.id;
|
||||
log::debug!("Locating client for version {version}");
|
||||
@@ -158,7 +146,7 @@ pub async fn download_assets(
|
||||
st: &State,
|
||||
with_legacy: bool,
|
||||
index: &AssetsIndex,
|
||||
loading_bar: Option<&LoadingBarId>,
|
||||
loading_bar: Option<&Uuid>,
|
||||
) -> crate::Result<()> {
|
||||
log::debug!("Loading assets");
|
||||
let num_futs = index.objects.len();
|
||||
@@ -219,7 +207,7 @@ pub async fn download_libraries(
|
||||
st: &State,
|
||||
libraries: &[Library],
|
||||
version: &str,
|
||||
loading_bar: Option<&LoadingBarId>,
|
||||
loading_bar: Option<&Uuid>,
|
||||
) -> crate::Result<()> {
|
||||
log::debug!("Loading libraries");
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
//! Logic for launching Minecraft
|
||||
use crate::event::emit::{emit_loading, init_or_edit_loading};
|
||||
use crate::event::LoadingBarType;
|
||||
use crate::{
|
||||
process,
|
||||
state::{self as st, MinecraftChild},
|
||||
@@ -8,6 +10,7 @@ use dunce::canonicalize;
|
||||
use st::Profile;
|
||||
use std::{path::Path, process::Stdio, sync::Arc};
|
||||
use tokio::process::Command;
|
||||
use uuid::Uuid;
|
||||
|
||||
mod args;
|
||||
|
||||
@@ -48,55 +51,60 @@ macro_rules! processor_rules {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[tracing::instrument(skip_all, fields(path = ?instance_path))]
|
||||
pub async fn launch_minecraft(
|
||||
game_version: &str,
|
||||
loader_version: &Option<d::modded::LoaderVersion>,
|
||||
instance_path: &Path,
|
||||
java_install: &Path,
|
||||
java_args: &[String],
|
||||
env_args: &[(String, String)],
|
||||
wrapper: &Option<String>,
|
||||
memory: &st::MemorySettings,
|
||||
resolution: &st::WindowSize,
|
||||
credentials: &auth::Credentials,
|
||||
post_exit_hook: Option<Command>,
|
||||
profile: &Profile, // optional ref to Profile for event tracking
|
||||
) -> crate::Result<Arc<tokio::sync::RwLock<MinecraftChild>>> {
|
||||
pub async fn install_minecraft(
|
||||
profile: &Profile,
|
||||
existing_loading_bar: Option<Uuid>,
|
||||
) -> crate::Result<()> {
|
||||
let state = st::State::get().await?;
|
||||
let instance_path = &canonicalize(instance_path)?;
|
||||
let instance_path = &canonicalize(&profile.path)?;
|
||||
let metadata = state.metadata.read().await;
|
||||
|
||||
let version = state
|
||||
.metadata
|
||||
let version = metadata
|
||||
.minecraft
|
||||
.versions
|
||||
.iter()
|
||||
.find(|it| it.id == game_version)
|
||||
.find(|it| it.id == profile.metadata.game_version)
|
||||
.ok_or(crate::ErrorKind::LauncherError(format!(
|
||||
"Invalid game version: {game_version}"
|
||||
"Invalid game version: {}",
|
||||
profile.metadata.game_version
|
||||
)))?;
|
||||
|
||||
let version_jar =
|
||||
loader_version.as_ref().map_or(version.id.clone(), |it| {
|
||||
let version_jar = profile
|
||||
.metadata
|
||||
.loader_version
|
||||
.as_ref()
|
||||
.map_or(version.id.clone(), |it| {
|
||||
format!("{}-{}", version.id.clone(), it.id.clone())
|
||||
});
|
||||
|
||||
let mut version_info = download::download_version_info(
|
||||
&state,
|
||||
version,
|
||||
loader_version.as_ref(),
|
||||
profile.metadata.loader_version.as_ref(),
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let loading_bar = init_or_edit_loading(
|
||||
existing_loading_bar,
|
||||
LoadingBarType::MinecraftDownload {
|
||||
// If we are downloading minecraft for a profile, provide its name and uuid
|
||||
profile_name: profile.metadata.name.clone(),
|
||||
profile_uuid: profile.uuid,
|
||||
},
|
||||
100.0,
|
||||
"Downloading Minecraft...",
|
||||
)
|
||||
.await?;
|
||||
|
||||
download::download_minecraft(&state, &version_info, loading_bar).await?;
|
||||
st::State::sync().await?;
|
||||
|
||||
let client_path = state
|
||||
.directories
|
||||
.version_dir(&version_jar)
|
||||
.join(format!("{version_jar}.jar"));
|
||||
|
||||
download::download_minecraft(&state, &version_info, profile).await?;
|
||||
st::State::sync().await?;
|
||||
|
||||
if let Some(processors) = &version_info.processors {
|
||||
if let Some(ref mut data) = version_info.data {
|
||||
processor_rules! {
|
||||
@@ -108,7 +116,7 @@ pub async fn launch_minecraft(
|
||||
client => client_path.to_string_lossy(),
|
||||
server => "";
|
||||
"MINECRAFT_VERSION":
|
||||
client => game_version,
|
||||
client => profile.metadata.game_version.clone(),
|
||||
server => "";
|
||||
"ROOT":
|
||||
client => instance_path.to_string_lossy(),
|
||||
@@ -118,7 +126,21 @@ pub async fn launch_minecraft(
|
||||
server => "";
|
||||
}
|
||||
|
||||
for processor in processors {
|
||||
emit_loading(&loading_bar, 0.0, Some("Running forge processors"))
|
||||
.await?;
|
||||
let total_length = processors.len();
|
||||
|
||||
for (index, processor) in processors.iter().enumerate() {
|
||||
emit_loading(
|
||||
&loading_bar,
|
||||
index as f64 / total_length as f64,
|
||||
Some(&format!(
|
||||
"Running forge processor {}/{}",
|
||||
index, total_length
|
||||
)),
|
||||
)
|
||||
.await?;
|
||||
|
||||
if let Some(sides) = &processor.sides {
|
||||
if !sides.contains(&String::from("client")) {
|
||||
continue;
|
||||
@@ -173,6 +195,68 @@ pub async fn launch_minecraft(
|
||||
}
|
||||
}
|
||||
|
||||
crate::api::profile::edit(&profile.path, |prof| {
|
||||
prof.installed = true;
|
||||
|
||||
async { Ok(()) }
|
||||
})
|
||||
.await?;
|
||||
crate::api::profile::sync(&profile.path).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn launch_minecraft(
|
||||
java_install: &Path,
|
||||
java_args: &[String],
|
||||
env_args: &[(String, String)],
|
||||
wrapper: &Option<String>,
|
||||
memory: &st::MemorySettings,
|
||||
resolution: &st::WindowSize,
|
||||
credentials: &auth::Credentials,
|
||||
post_exit_hook: Option<Command>,
|
||||
profile: &Profile,
|
||||
) -> crate::Result<Arc<tokio::sync::RwLock<MinecraftChild>>> {
|
||||
if !profile.installed {
|
||||
install_minecraft(profile, None).await?;
|
||||
}
|
||||
|
||||
let state = st::State::get().await?;
|
||||
let metadata = state.metadata.read().await;
|
||||
let instance_path = &canonicalize(&profile.path)?;
|
||||
|
||||
let version = metadata
|
||||
.minecraft
|
||||
.versions
|
||||
.iter()
|
||||
.find(|it| it.id == profile.metadata.game_version)
|
||||
.ok_or(crate::ErrorKind::LauncherError(format!(
|
||||
"Invalid game version: {}",
|
||||
profile.metadata.game_version
|
||||
)))?;
|
||||
|
||||
let version_jar = profile
|
||||
.metadata
|
||||
.loader_version
|
||||
.as_ref()
|
||||
.map_or(version.id.clone(), |it| {
|
||||
format!("{}-{}", version.id.clone(), it.id.clone())
|
||||
});
|
||||
|
||||
let version_info = download::download_version_info(
|
||||
&state,
|
||||
version,
|
||||
profile.metadata.loader_version.as_ref(),
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let client_path = state
|
||||
.directories
|
||||
.version_dir(&version_jar)
|
||||
.join(format!("{version_jar}.jar"));
|
||||
|
||||
let args = version_info.arguments.clone().unwrap_or_default();
|
||||
let mut command = match wrapper {
|
||||
Some(hook) => {
|
||||
|
||||
Reference in New Issue
Block a user