You've already forked AstralRinth
forked from didirus/AstralRinth
Profile bindings (#55)
* basic framework. still has errors * added functionality for main endpoints + some structuring * formatting * unused code * mimicked CLI function with wait_for process * made PR changes, added playground * cargo fmt * removed missed println * misc tests fixes * cargo fmt * added windows support * cargo fmt * all OS use dunce * restructured profile slightly; fixed mac bug * profile changes, new main.rs * fixed requested pr + canonicaliation bug * fixed regressed bug in ui * fixed regressed bugs * fixed git error * typo * ran prettier * clippy * playground clippy * ported profile loading fix * profile change for real, url println and clippy * PR changes --------- Co-authored-by: Wyatt <wyatt@modrinth.com>
This commit is contained in:
@@ -10,10 +10,14 @@ use daedalus::{
|
||||
minecraft::{Argument, ArgumentValue, Library, VersionType},
|
||||
modded::SidedDataEntry,
|
||||
};
|
||||
use dunce::canonicalize;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::{collections::HashMap, path::Path};
|
||||
use uuid::Uuid;
|
||||
|
||||
// Replaces the space separator with a newline character, as to not split the arguments
|
||||
const TEMPORARY_REPLACE_CHAR: &str = "\n";
|
||||
|
||||
pub fn get_class_paths(
|
||||
libraries_path: &Path,
|
||||
libraries: &[Library],
|
||||
@@ -37,8 +41,7 @@ pub fn get_class_paths(
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
cps.push(
|
||||
client_path
|
||||
.canonicalize()
|
||||
canonicalize(client_path)
|
||||
.map_err(|_| {
|
||||
crate::ErrorKind::LauncherError(format!(
|
||||
"Specified class path {} does not exist",
|
||||
@@ -70,7 +73,7 @@ pub fn get_lib_path(libraries_path: &Path, lib: &str) -> crate::Result<String> {
|
||||
|
||||
path.push(get_path_from_artifact(lib)?);
|
||||
|
||||
let path = &path.canonicalize().map_err(|_| {
|
||||
let path = &canonicalize(&path).map_err(|_| {
|
||||
crate::ErrorKind::LauncherError(format!(
|
||||
"Library file at path {} does not exist",
|
||||
path.to_string_lossy()
|
||||
@@ -104,15 +107,13 @@ pub fn get_jvm_arguments(
|
||||
} else {
|
||||
parsed_arguments.push(format!(
|
||||
"-Djava.library.path={}",
|
||||
&natives_path
|
||||
.canonicalize()
|
||||
canonicalize(natives_path)
|
||||
.map_err(|_| crate::ErrorKind::LauncherError(format!(
|
||||
"Specified natives path {} does not exist",
|
||||
natives_path.to_string_lossy()
|
||||
))
|
||||
.as_error())?
|
||||
.to_string_lossy()
|
||||
.to_string()
|
||||
));
|
||||
parsed_arguments.push("-cp".to_string());
|
||||
parsed_arguments.push(class_paths.to_string());
|
||||
@@ -142,8 +143,7 @@ fn parse_jvm_argument(
|
||||
Ok(argument
|
||||
.replace(
|
||||
"${natives_directory}",
|
||||
&natives_path
|
||||
.canonicalize()
|
||||
&canonicalize(natives_path)
|
||||
.map_err(|_| {
|
||||
crate::ErrorKind::LauncherError(format!(
|
||||
"Specified natives path {} does not exist",
|
||||
@@ -155,8 +155,7 @@ fn parse_jvm_argument(
|
||||
)
|
||||
.replace(
|
||||
"${library_directory}",
|
||||
&libraries_path
|
||||
.canonicalize()
|
||||
&canonicalize(libraries_path)
|
||||
.map_err(|_| {
|
||||
crate::ErrorKind::LauncherError(format!(
|
||||
"Specified libraries path {} does not exist",
|
||||
@@ -206,7 +205,7 @@ pub fn get_minecraft_arguments(
|
||||
Ok(parsed_arguments)
|
||||
} else if let Some(legacy_arguments) = legacy_arguments {
|
||||
Ok(parse_minecraft_argument(
|
||||
legacy_arguments,
|
||||
&legacy_arguments.replace(' ', TEMPORARY_REPLACE_CHAR),
|
||||
&credentials.access_token,
|
||||
&credentials.username,
|
||||
&credentials.id,
|
||||
@@ -249,8 +248,7 @@ fn parse_minecraft_argument(
|
||||
.replace("${assets_index_name}", asset_index_name)
|
||||
.replace(
|
||||
"${game_directory}",
|
||||
&game_directory
|
||||
.canonicalize()
|
||||
&canonicalize(game_directory)
|
||||
.map_err(|_| {
|
||||
crate::ErrorKind::LauncherError(format!(
|
||||
"Specified game directory {} does not exist",
|
||||
@@ -262,8 +260,7 @@ fn parse_minecraft_argument(
|
||||
)
|
||||
.replace(
|
||||
"${assets_root}",
|
||||
&assets_directory
|
||||
.canonicalize()
|
||||
&canonicalize(assets_directory)
|
||||
.map_err(|_| {
|
||||
crate::ErrorKind::LauncherError(format!(
|
||||
"Specified assets directory {} does not exist",
|
||||
@@ -275,8 +272,7 @@ fn parse_minecraft_argument(
|
||||
)
|
||||
.replace(
|
||||
"${game_assets}",
|
||||
&assets_directory
|
||||
.canonicalize()
|
||||
&canonicalize(assets_directory)
|
||||
.map_err(|_| {
|
||||
crate::ErrorKind::LauncherError(format!(
|
||||
"Specified assets directory {} does not exist",
|
||||
@@ -302,9 +298,9 @@ where
|
||||
for argument in arguments {
|
||||
match argument {
|
||||
Argument::Normal(arg) => {
|
||||
let parsed = parse_function(arg)?;
|
||||
|
||||
for arg in parsed.split(' ') {
|
||||
let parsed =
|
||||
parse_function(&arg.replace(' ', TEMPORARY_REPLACE_CHAR))?;
|
||||
for arg in parsed.split(TEMPORARY_REPLACE_CHAR) {
|
||||
parsed_arguments.push(arg.to_string());
|
||||
}
|
||||
}
|
||||
@@ -312,11 +308,15 @@ where
|
||||
if rules.iter().all(parse_rule) {
|
||||
match value {
|
||||
ArgumentValue::Single(arg) => {
|
||||
parsed_arguments.push(parse_function(arg)?);
|
||||
parsed_arguments.push(parse_function(
|
||||
&arg.replace(' ', TEMPORARY_REPLACE_CHAR),
|
||||
)?);
|
||||
}
|
||||
ArgumentValue::Many(args) => {
|
||||
for arg in args {
|
||||
parsed_arguments.push(parse_function(arg)?);
|
||||
parsed_arguments.push(parse_function(
|
||||
&arg.replace(' ', TEMPORARY_REPLACE_CHAR),
|
||||
)?);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use bincode::{Decode, Encode};
|
||||
use chrono::{prelude::*, Duration};
|
||||
use futures::prelude::*;
|
||||
use lazy_static::lazy_static;
|
||||
use serde::Deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
lazy_static! {
|
||||
@@ -47,7 +47,7 @@ struct ProfileInfoJSON {
|
||||
}
|
||||
|
||||
// Login information
|
||||
#[derive(Encode, Decode)]
|
||||
#[derive(Encode, Decode, Serialize, Deserialize)]
|
||||
pub struct Credentials {
|
||||
#[bincode(with_serde)]
|
||||
pub id: uuid::Uuid,
|
||||
|
||||
@@ -139,10 +139,9 @@ pub async fn download_assets(
|
||||
index: &AssetsIndex,
|
||||
) -> crate::Result<()> {
|
||||
log::debug!("Loading assets");
|
||||
|
||||
stream::iter(index.objects.iter())
|
||||
.map(Ok::<(&String, &Asset), crate::Error>)
|
||||
.try_for_each_concurrent(None, |(name, asset)| async move {
|
||||
.try_for_each_concurrent(Some(st.settings.read().await.max_concurrent_downloads), |(name, asset)| async move {
|
||||
let hash = &asset.hash;
|
||||
let resource_path = st.directories.object_dir(hash);
|
||||
let url = format!(
|
||||
@@ -202,7 +201,7 @@ pub async fn download_libraries(
|
||||
|
||||
stream::iter(libraries.iter())
|
||||
.map(Ok::<&Library, crate::Error>)
|
||||
.try_for_each_concurrent(None, |library| async move {
|
||||
.try_for_each_concurrent(Some(st.settings.read().await.max_concurrent_downloads), |library| async move {
|
||||
if let Some(rules) = &library.rules {
|
||||
if !rules.iter().all(super::parse_rule) {
|
||||
return Ok(());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//! Logic for launching Minecraft
|
||||
use crate::state as st;
|
||||
use daedalus as d;
|
||||
use dunce::canonicalize;
|
||||
use std::{path::Path, process::Stdio};
|
||||
use tokio::process::{Child, Command};
|
||||
|
||||
@@ -58,7 +59,7 @@ pub async fn launch_minecraft(
|
||||
credentials: &auth::Credentials,
|
||||
) -> crate::Result<Child> {
|
||||
let state = st::State::get().await?;
|
||||
let instance_path = instance_path.canonicalize()?;
|
||||
let instance_path = &canonicalize(instance_path)?;
|
||||
|
||||
let version = state
|
||||
.metadata
|
||||
@@ -173,34 +174,45 @@ pub async fn launch_minecraft(
|
||||
};
|
||||
|
||||
command
|
||||
.args(args::get_jvm_arguments(
|
||||
args.get(&d::minecraft::ArgumentType::Jvm)
|
||||
.map(|x| x.as_slice()),
|
||||
&state.directories.version_natives_dir(&version.id),
|
||||
&state.directories.libraries_dir(),
|
||||
&args::get_class_paths(
|
||||
.args(
|
||||
args::get_jvm_arguments(
|
||||
args.get(&d::minecraft::ArgumentType::Jvm)
|
||||
.map(|x| x.as_slice()),
|
||||
&state.directories.version_natives_dir(&version.id),
|
||||
&state.directories.libraries_dir(),
|
||||
version_info.libraries.as_slice(),
|
||||
&client_path,
|
||||
)?,
|
||||
&version_jar,
|
||||
*memory,
|
||||
Vec::from(java_args),
|
||||
)?)
|
||||
&args::get_class_paths(
|
||||
&state.directories.libraries_dir(),
|
||||
version_info.libraries.as_slice(),
|
||||
&client_path,
|
||||
)?,
|
||||
&version_jar,
|
||||
*memory,
|
||||
Vec::from(java_args),
|
||||
)?
|
||||
.into_iter()
|
||||
.map(|r| r.replace(' ', r"\ "))
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.arg(version_info.main_class.clone())
|
||||
.args(args::get_minecraft_arguments(
|
||||
args.get(&d::minecraft::ArgumentType::Game)
|
||||
.map(|x| x.as_slice()),
|
||||
version_info.minecraft_arguments.as_deref(),
|
||||
credentials,
|
||||
&version.id,
|
||||
&version_info.asset_index.id,
|
||||
&instance_path,
|
||||
&state.directories.assets_dir(),
|
||||
&version.type_,
|
||||
*resolution,
|
||||
)?)
|
||||
.args(
|
||||
args::get_minecraft_arguments(
|
||||
args.get(&d::minecraft::ArgumentType::Game)
|
||||
.map(|x| x.as_slice()),
|
||||
version_info.minecraft_arguments.as_deref(),
|
||||
credentials,
|
||||
&version.id,
|
||||
&version_info.asset_index.id,
|
||||
instance_path,
|
||||
&state.directories.assets_dir(),
|
||||
&version.type_,
|
||||
*resolution,
|
||||
)?
|
||||
.into_iter()
|
||||
.map(|r| r.replace(' ', r"\ "))
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.current_dir(instance_path.clone())
|
||||
.env_clear()
|
||||
.stdout(Stdio::inherit())
|
||||
.stderr(Stdio::inherit());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user