You've already forked AstralRinth
forked from didirus/AstralRinth
Merge commit '74cf3f076eff43755bb4bef62f1c1bb3fc0e6c2a' into feature-clean
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
//! Minecraft CLI argument logic
|
||||
use crate::launcher::parse_rules;
|
||||
use crate::profile::QuickPlayType;
|
||||
use crate::state::Credentials;
|
||||
use crate::{
|
||||
state::{MemorySettings, WindowSize},
|
||||
@@ -31,7 +32,12 @@ pub fn get_class_paths(
|
||||
.iter()
|
||||
.filter_map(|library| {
|
||||
if let Some(rules) = &library.rules {
|
||||
if !parse_rules(rules, java_arch, minecraft_updated) {
|
||||
if !parse_rules(
|
||||
rules,
|
||||
java_arch,
|
||||
&QuickPlayType::None,
|
||||
minecraft_updated,
|
||||
) {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
@@ -111,6 +117,7 @@ pub fn get_jvm_arguments(
|
||||
memory: MemorySettings,
|
||||
custom_args: Vec<String>,
|
||||
java_arch: &str,
|
||||
quick_play_type: &QuickPlayType,
|
||||
log_config: Option<&LoggingConfiguration>,
|
||||
) -> crate::Result<Vec<String>> {
|
||||
let mut parsed_arguments = Vec::new();
|
||||
@@ -130,6 +137,7 @@ pub fn get_jvm_arguments(
|
||||
)
|
||||
},
|
||||
java_arch,
|
||||
quick_play_type,
|
||||
)?;
|
||||
} else {
|
||||
parsed_arguments.push(format!(
|
||||
@@ -214,6 +222,7 @@ pub fn get_minecraft_arguments(
|
||||
version_type: &VersionType,
|
||||
resolution: WindowSize,
|
||||
java_arch: &str,
|
||||
quick_play_type: &QuickPlayType,
|
||||
) -> crate::Result<Vec<String>> {
|
||||
if let Some(arguments) = arguments {
|
||||
let mut parsed_arguments = Vec::new();
|
||||
@@ -233,9 +242,11 @@ pub fn get_minecraft_arguments(
|
||||
assets_directory,
|
||||
version_type,
|
||||
resolution,
|
||||
quick_play_type,
|
||||
)
|
||||
},
|
||||
java_arch,
|
||||
quick_play_type,
|
||||
)?;
|
||||
|
||||
Ok(parsed_arguments)
|
||||
@@ -253,6 +264,7 @@ pub fn get_minecraft_arguments(
|
||||
assets_directory,
|
||||
version_type,
|
||||
resolution,
|
||||
quick_play_type,
|
||||
)?);
|
||||
}
|
||||
Ok(parsed_arguments)
|
||||
@@ -273,6 +285,7 @@ fn parse_minecraft_argument(
|
||||
assets_directory: &Path,
|
||||
version_type: &VersionType,
|
||||
resolution: WindowSize,
|
||||
quick_play_type: &QuickPlayType,
|
||||
) -> crate::Result<String> {
|
||||
Ok(argument
|
||||
.replace("${accessToken}", access_token)
|
||||
@@ -326,7 +339,21 @@ fn parse_minecraft_argument(
|
||||
)
|
||||
.replace("${version_type}", version_type.as_str())
|
||||
.replace("${resolution_width}", &resolution.0.to_string())
|
||||
.replace("${resolution_height}", &resolution.1.to_string()))
|
||||
.replace("${resolution_height}", &resolution.1.to_string())
|
||||
.replace(
|
||||
"${quickPlaySingleplayer}",
|
||||
match quick_play_type {
|
||||
QuickPlayType::Singleplayer(world) => world,
|
||||
_ => "",
|
||||
},
|
||||
)
|
||||
.replace(
|
||||
"${quickPlayMultiplayer}",
|
||||
match quick_play_type {
|
||||
QuickPlayType::Server(address) => address,
|
||||
_ => "",
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
fn parse_arguments<F>(
|
||||
@@ -334,6 +361,7 @@ fn parse_arguments<F>(
|
||||
parsed_arguments: &mut Vec<String>,
|
||||
parse_function: F,
|
||||
java_arch: &str,
|
||||
quick_play_type: &QuickPlayType,
|
||||
) -> crate::Result<()>
|
||||
where
|
||||
F: Fn(&str) -> crate::Result<String>,
|
||||
@@ -348,7 +376,7 @@ where
|
||||
}
|
||||
}
|
||||
Argument::Ruled { rules, value } => {
|
||||
if parse_rules(rules, java_arch, true) {
|
||||
if parse_rules(rules, java_arch, quick_play_type, true) {
|
||||
match value {
|
||||
ArgumentValue::Single(arg) => {
|
||||
parsed_arguments.push(parse_function(
|
||||
@@ -410,16 +438,14 @@ pub async fn get_processor_main_class(
|
||||
.map_err(|e| IOError::with_path(e, &path))?;
|
||||
let mut archive = zip::ZipArchive::new(zipfile).map_err(|_| {
|
||||
crate::ErrorKind::LauncherError(format!(
|
||||
"Cannot read processor at {}",
|
||||
path
|
||||
"Cannot read processor at {path}"
|
||||
))
|
||||
.as_error()
|
||||
})?;
|
||||
|
||||
let file = archive.by_name("META-INF/MANIFEST.MF").map_err(|_| {
|
||||
crate::ErrorKind::LauncherError(format!(
|
||||
"Cannot read processor manifest at {}",
|
||||
path
|
||||
"Cannot read processor manifest at {path}"
|
||||
))
|
||||
.as_error()
|
||||
})?;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
//! Downloader for Minecraft data
|
||||
|
||||
use crate::launcher::parse_rules;
|
||||
use crate::profile::QuickPlayType;
|
||||
use crate::{
|
||||
event::{
|
||||
emit::{emit_loading, loading_try_for_each_concurrent},
|
||||
LoadingBarId,
|
||||
emit::{emit_loading, loading_try_for_each_concurrent},
|
||||
},
|
||||
state::State,
|
||||
util::{fetch::*, io, platform::OsExt},
|
||||
@@ -295,7 +296,7 @@ pub async fn download_libraries(
|
||||
stream::iter(libraries.iter())
|
||||
.map(Ok::<&Library, crate::Error>), None, loading_bar,loading_amount,num_files, None,|library| async move {
|
||||
if let Some(rules) = &library.rules {
|
||||
if !parse_rules(rules, java_arch, minecraft_updated) {
|
||||
if !parse_rules(rules, java_arch, &QuickPlayType::None, minecraft_updated) {
|
||||
tracing::trace!("Skipped library {}", &library.name);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -4,18 +4,21 @@ use crate::event::emit::{emit_loading, init_or_edit_loading};
|
||||
use crate::event::{LoadingBarId, LoadingBarType};
|
||||
use crate::launcher::download::download_log_config;
|
||||
use crate::launcher::io::IOError;
|
||||
use crate::profile::QuickPlayType;
|
||||
use crate::state::{
|
||||
Credentials, JavaVersion, ProcessMetadata, ProfileInstallStage,
|
||||
};
|
||||
use crate::util::io;
|
||||
use crate::{process, state as st, State};
|
||||
use crate::{State, process, state as st};
|
||||
use chrono::Utc;
|
||||
use daedalus as d;
|
||||
use daedalus::minecraft::{LoggingSide, RuleAction, VersionInfo};
|
||||
use daedalus::modded::LoaderVersion;
|
||||
use rand::seq::SliceRandom;
|
||||
use rand::seq::SliceRandom; // AstralRinth
|
||||
use serde::Deserialize;
|
||||
use st::Profile;
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use tokio::process::Command;
|
||||
|
||||
mod args;
|
||||
@@ -31,11 +34,14 @@ use crate::state::ACTIVE_STATE;
|
||||
pub fn parse_rules(
|
||||
rules: &[d::minecraft::Rule],
|
||||
java_version: &str,
|
||||
quick_play_type: &QuickPlayType,
|
||||
minecraft_updated: bool,
|
||||
) -> bool {
|
||||
let mut x = rules
|
||||
.iter()
|
||||
.map(|x| parse_rule(x, java_version, minecraft_updated))
|
||||
.map(|x| {
|
||||
parse_rule(x, java_version, quick_play_type, minecraft_updated)
|
||||
})
|
||||
.collect::<Vec<Option<bool>>>();
|
||||
|
||||
if rules
|
||||
@@ -56,26 +62,30 @@ pub fn parse_rules(
|
||||
pub fn parse_rule(
|
||||
rule: &d::minecraft::Rule,
|
||||
java_version: &str,
|
||||
quick_play_type: &QuickPlayType,
|
||||
minecraft_updated: bool,
|
||||
) -> Option<bool> {
|
||||
use d::minecraft::{Rule, RuleAction};
|
||||
|
||||
let res = match rule {
|
||||
Rule {
|
||||
os: Some(ref os), ..
|
||||
} => {
|
||||
Rule { os: Some(os), .. } => {
|
||||
crate::util::platform::os_rule(os, java_version, minecraft_updated)
|
||||
}
|
||||
Rule {
|
||||
features: Some(ref features),
|
||||
features: Some(features),
|
||||
..
|
||||
} => {
|
||||
!features.is_demo_user.unwrap_or(true)
|
||||
|| features.has_custom_resolution.unwrap_or(false)
|
||||
|| !features.has_quick_plays_support.unwrap_or(true)
|
||||
|| !features.is_quick_play_multiplayer.unwrap_or(true)
|
||||
|| (features.is_quick_play_singleplayer.unwrap_or(false)
|
||||
&& matches!(
|
||||
quick_play_type,
|
||||
QuickPlayType::Singleplayer(_)
|
||||
))
|
||||
|| (features.is_quick_play_multiplayer.unwrap_or(false)
|
||||
&& matches!(quick_play_type, QuickPlayType::Server(..)))
|
||||
|| !features.is_quick_play_realms.unwrap_or(true)
|
||||
|| !features.is_quick_play_singleplayer.unwrap_or(true)
|
||||
}
|
||||
_ => return Some(true),
|
||||
};
|
||||
@@ -288,8 +298,7 @@ pub async fn install_minecraft(
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
crate::ErrorKind::LauncherError(format!(
|
||||
"Java path invalid or non-functional: {:?}",
|
||||
java_version
|
||||
"Java path invalid or non-functional: {java_version:?}"
|
||||
))
|
||||
})?;
|
||||
|
||||
@@ -308,12 +317,11 @@ pub async fn install_minecraft(
|
||||
)
|
||||
.await?;
|
||||
|
||||
let client_path = state
|
||||
.directories
|
||||
.version_dir(&version_jar)
|
||||
.join(format!("{version_jar}.jar"));
|
||||
if let Some(processors) = &version_info.processors {
|
||||
let client_path = state
|
||||
.directories
|
||||
.version_dir(&version_jar)
|
||||
.join(format!("{version_jar}.jar"));
|
||||
|
||||
let libraries_dir = state.directories.libraries_dir();
|
||||
|
||||
if let Some(ref mut data) = version_info.data {
|
||||
@@ -398,16 +406,18 @@ pub async fn install_minecraft(
|
||||
&loading_bar,
|
||||
30.0 / total_length as f64,
|
||||
Some(&format!(
|
||||
"Running forge processor {}/{}",
|
||||
index, total_length
|
||||
"Running forge processor {index}/{total_length}"
|
||||
)),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let protocol_version = read_protocol_version_from_jar(client_path).await?;
|
||||
|
||||
crate::api::profile::edit(&profile.path, |prof| {
|
||||
prof.install_stage = ProfileInstallStage::Installed;
|
||||
prof.protocol_version = protocol_version;
|
||||
|
||||
async { Ok(()) }
|
||||
})
|
||||
@@ -417,6 +427,34 @@ pub async fn install_minecraft(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn read_protocol_version_from_jar(
|
||||
path: PathBuf,
|
||||
) -> crate::Result<Option<i32>> {
|
||||
let zip = async_zip::tokio::read::fs::ZipFileReader::new(path).await?;
|
||||
let Some(entry_index) = zip
|
||||
.file()
|
||||
.entries()
|
||||
.iter()
|
||||
.position(|x| matches!(x.filename().as_str(), Ok("version.json")))
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct VersionData {
|
||||
protocol_version: Option<i32>,
|
||||
}
|
||||
|
||||
let mut data = vec![];
|
||||
zip.reader_with_entry(entry_index)
|
||||
.await?
|
||||
.read_to_end_checked(&mut data)
|
||||
.await?;
|
||||
let data: VersionData = serde_json::from_slice(&data)?;
|
||||
|
||||
Ok(data.protocol_version)
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn launch_minecraft(
|
||||
@@ -429,6 +467,7 @@ pub async fn launch_minecraft(
|
||||
credentials: &Credentials,
|
||||
post_exit_hook: Option<String>,
|
||||
profile: &Profile,
|
||||
quick_play_type: &QuickPlayType,
|
||||
) -> crate::Result<ProcessMetadata> {
|
||||
if profile.install_stage == ProfileInstallStage::PackInstalling
|
||||
|| profile.install_stage == ProfileInstallStage::MinecraftInstalling
|
||||
@@ -584,6 +623,7 @@ pub async fn launch_minecraft(
|
||||
*memory,
|
||||
Vec::from(java_args),
|
||||
&java_version.architecture,
|
||||
quick_play_type,
|
||||
version_info
|
||||
.logging
|
||||
.as_ref()
|
||||
@@ -606,6 +646,7 @@ pub async fn launch_minecraft(
|
||||
&version.type_,
|
||||
*resolution,
|
||||
&java_version.architecture,
|
||||
quick_play_type,
|
||||
)?
|
||||
.into_iter()
|
||||
.collect::<Vec<_>>(),
|
||||
@@ -637,10 +678,10 @@ pub async fn launch_minecraft(
|
||||
// check if the regex exists in the file
|
||||
if !re.is_match(&options_string) {
|
||||
// The key was not found in the file, so append it
|
||||
options_string.push_str(&format!("\n{}:{}", key, value));
|
||||
options_string.push_str(&format!("\n{key}:{value}"));
|
||||
} else {
|
||||
let replaced_string = re
|
||||
.replace_all(&options_string, &format!("{}:{}", key, value))
|
||||
.replace_all(&options_string, &format!("{key}:{value}"))
|
||||
.to_string();
|
||||
options_string = replaced_string;
|
||||
}
|
||||
@@ -658,12 +699,10 @@ pub async fn launch_minecraft(
|
||||
|
||||
let mut censor_strings = HashMap::new();
|
||||
let username = whoami::username();
|
||||
censor_strings
|
||||
.insert(format!("/{username}/"), "/{COMPUTER_USERNAME}/".to_string());
|
||||
censor_strings.insert(
|
||||
format!("/{}/", username),
|
||||
"/{COMPUTER_USERNAME}/".to_string(),
|
||||
);
|
||||
censor_strings.insert(
|
||||
format!("\\{}\\", username),
|
||||
format!("\\{username}\\"),
|
||||
"\\{COMPUTER_USERNAME}\\".to_string(),
|
||||
);
|
||||
censor_strings.insert(
|
||||
@@ -712,6 +751,12 @@ pub async fn launch_minecraft(
|
||||
// This also spawns the process and prepares the subsequent processes
|
||||
state
|
||||
.process_manager
|
||||
.insert_new_process(&profile.path, command, post_exit_hook)
|
||||
.insert_new_process(
|
||||
&profile.path,
|
||||
command,
|
||||
post_exit_hook,
|
||||
state.directories.profile_logs_dir(&profile.path),
|
||||
version_info.logging.is_some(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user