You've already forked AstralRinth
forked from didirus/AstralRinth
Jre api (#66)
* basic push * actual push * JRE detection, and autosetting * removed a println, retrying CI/CD * new game version compare; preset java 7 and 8 using our jre * 1.8 mislabeled * working JRE changes * fixed bugs with JRE setup * fixed bugs with JRE setup * manual merge * prettier * fixes + jre 17 * clippy, prettier * typo * forgot to hook up a function * pr fix + comment fix * added loader_version * take 2
This commit is contained in:
137
theseus/src/api/jre.rs
Normal file
137
theseus/src/api/jre.rs
Normal file
@@ -0,0 +1,137 @@
|
||||
//! Authentication flow interface
|
||||
use crate::{
|
||||
launcher::download,
|
||||
prelude::Profile,
|
||||
state::JavaGlobals,
|
||||
util::jre::{self, extract_java_majorminor_version, JavaVersion},
|
||||
State,
|
||||
};
|
||||
|
||||
pub const JAVA_8_KEY: &str = "JAVA_8";
|
||||
pub const JAVA_17_KEY: &str = "JAVA_17";
|
||||
pub const JAVA_18PLUS_KEY: &str = "JAVA_18PLUS";
|
||||
|
||||
// Autodetect JavaSettings default
|
||||
// Make a guess for what the default Java global settings should be
|
||||
pub fn autodetect_java_globals() -> crate::Result<JavaGlobals> {
|
||||
let mut java_8 = find_java8_jres()?;
|
||||
let mut java_17 = find_java17_jres()?;
|
||||
let mut java_18plus = find_java18plus_jres()?;
|
||||
|
||||
// Simply select last one found for initial guess
|
||||
let mut java_globals = JavaGlobals::new();
|
||||
if let Some(jre) = java_8.pop() {
|
||||
java_globals.insert(JAVA_8_KEY.to_string(), jre);
|
||||
}
|
||||
if let Some(jre) = java_17.pop() {
|
||||
java_globals.insert(JAVA_17_KEY.to_string(), jre);
|
||||
}
|
||||
if let Some(jre) = java_18plus.pop() {
|
||||
java_globals.insert(JAVA_18PLUS_KEY.to_string(), jre);
|
||||
}
|
||||
|
||||
Ok(java_globals)
|
||||
}
|
||||
|
||||
// Gets the optimal JRE key for the given profile, using Daedalus
|
||||
// Generally this would be used for profile_create, to get the optimal JRE key
|
||||
// this can be overwritten by the user a profile-by-profile basis
|
||||
pub async fn get_optimal_jre_key(profile: &Profile) -> crate::Result<String> {
|
||||
let state = State::get().await?;
|
||||
|
||||
// Fetch version info from stored profile game_version
|
||||
let version = state
|
||||
.metadata
|
||||
.minecraft
|
||||
.versions
|
||||
.iter()
|
||||
.find(|it| it.id == profile.metadata.game_version.as_ref())
|
||||
.ok_or_else(|| {
|
||||
crate::ErrorKind::LauncherError(format!(
|
||||
"Invalid or unknown Minecraft version: {}",
|
||||
profile.metadata.game_version
|
||||
))
|
||||
})?;
|
||||
|
||||
// Get detailed manifest info from Daedalus
|
||||
let version_info =
|
||||
download::download_version_info(&state, version, profile.metadata.loader_version.as_ref()).await?;
|
||||
let optimal_key = match version_info
|
||||
.java_version
|
||||
.as_ref()
|
||||
.map(|it| it.major_version)
|
||||
.unwrap_or(0)
|
||||
{
|
||||
0..=16 => JAVA_8_KEY.to_string(),
|
||||
17 => JAVA_17_KEY.to_string(),
|
||||
_ => JAVA_18PLUS_KEY.to_string(),
|
||||
};
|
||||
Ok(optimal_key)
|
||||
}
|
||||
|
||||
// Searches for jres on the system that are 1.18 or higher
|
||||
pub fn find_java18plus_jres() -> crate::Result<Vec<JavaVersion>> {
|
||||
let version = extract_java_majorminor_version("1.18")?;
|
||||
let jres = jre::get_all_jre()?;
|
||||
// Filter out JREs that are not 1.17 or higher
|
||||
Ok(jres
|
||||
.into_iter()
|
||||
.filter(|jre| {
|
||||
let jre_version = extract_java_majorminor_version(&jre.version);
|
||||
if let Ok(jre_version) = jre_version {
|
||||
jre_version >= version
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
||||
// Searches for jres on the system that are 1.8 exactly
|
||||
pub fn find_java8_jres() -> crate::Result<Vec<JavaVersion>> {
|
||||
let version = extract_java_majorminor_version("1.8")?;
|
||||
let jres = jre::get_all_jre()?;
|
||||
|
||||
// Filter out JREs that are not 1.8
|
||||
Ok(jres
|
||||
.into_iter()
|
||||
.filter(|jre| {
|
||||
let jre_version = extract_java_majorminor_version(&jre.version);
|
||||
if let Ok(jre_version) = jre_version {
|
||||
jre_version == version
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
||||
// Searches for jres on the system that are 1.17 exactly
|
||||
pub fn find_java17_jres() -> crate::Result<Vec<JavaVersion>> {
|
||||
let version = extract_java_majorminor_version("1.17")?;
|
||||
let jres = jre::get_all_jre()?;
|
||||
|
||||
// Filter out JREs that are not 1.8
|
||||
Ok(jres
|
||||
.into_iter()
|
||||
.filter(|jre| {
|
||||
let jre_version = extract_java_majorminor_version(&jre.version);
|
||||
if let Ok(jre_version) = jre_version {
|
||||
jre_version == version
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
||||
// Get all JREs that exist on the system
|
||||
pub fn get_all_jre() -> crate::Result<Vec<JavaVersion>> {
|
||||
Ok(jre::get_all_jre()?)
|
||||
}
|
||||
|
||||
pub async fn validate_globals() -> crate::Result<bool> {
|
||||
let state = State::get().await?;
|
||||
let settings = state.settings.read().await;
|
||||
Ok(settings.java_globals.is_all_valid())
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
//! API for interacting with Theseus
|
||||
pub mod auth;
|
||||
pub mod jre;
|
||||
pub mod pack;
|
||||
pub mod process;
|
||||
pub mod profile;
|
||||
@@ -18,8 +19,11 @@ pub mod prelude {
|
||||
pub use crate::{
|
||||
auth::{self, Credentials},
|
||||
data::*,
|
||||
pack, process,
|
||||
jre, pack, process,
|
||||
profile::{self, Profile},
|
||||
profile_create, settings, State,
|
||||
profile_create, settings,
|
||||
state::JavaGlobals,
|
||||
util::jre::JavaVersion,
|
||||
State,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
//! Theseus profile management interface
|
||||
use crate::state::MinecraftChild;
|
||||
use crate::{launcher::download, state::MinecraftChild};
|
||||
pub use crate::{
|
||||
state::{JavaSettings, Profile},
|
||||
State,
|
||||
};
|
||||
use daedalus as d;
|
||||
use std::{
|
||||
future::Future,
|
||||
path::{Path, PathBuf},
|
||||
@@ -120,8 +119,8 @@ pub async fn run(
|
||||
profile.metadata.game_version
|
||||
))
|
||||
})?;
|
||||
let version_info = d::minecraft::fetch_version_info(version).await?;
|
||||
|
||||
let version_info =
|
||||
download::download_version_info(&state, version, profile.metadata.loader_version.as_ref()).await?;
|
||||
let pre_launch_hooks =
|
||||
&profile.hooks.as_ref().unwrap_or(&settings.hooks).pre_launch;
|
||||
for hook in pre_launch_hooks.iter() {
|
||||
@@ -145,29 +144,42 @@ pub async fn run(
|
||||
}
|
||||
}
|
||||
|
||||
let java_install = match profile.java {
|
||||
let java_version = match profile.java {
|
||||
// Load profile-specific Java implementation choice
|
||||
// (This defaults to Daedalus-decided key on init, but can be changed by the user)
|
||||
Some(JavaSettings {
|
||||
install: Some(ref install),
|
||||
jre_key: Some(ref jre_key),
|
||||
..
|
||||
}) => install,
|
||||
_ => if version_info
|
||||
.java_version
|
||||
.as_ref()
|
||||
.filter(|it| it.major_version >= 16)
|
||||
.is_some()
|
||||
{
|
||||
settings.java_17_path.as_ref()
|
||||
} else {
|
||||
settings.java_8_path.as_ref()
|
||||
}) => settings.java_globals.get(jre_key),
|
||||
// Fall back to Daedalus-decided key if no profile-specific key is set
|
||||
_ => {
|
||||
match version_info
|
||||
.java_version
|
||||
.as_ref()
|
||||
.map(|it| it.major_version)
|
||||
.unwrap_or(0)
|
||||
{
|
||||
0..=16 => settings
|
||||
.java_globals
|
||||
.get(&crate::jre::JAVA_8_KEY.to_string()),
|
||||
17 => settings
|
||||
.java_globals
|
||||
.get(&crate::jre::JAVA_17_KEY.to_string()),
|
||||
_ => settings
|
||||
.java_globals
|
||||
.get(&crate::jre::JAVA_18PLUS_KEY.to_string()),
|
||||
}
|
||||
}
|
||||
.ok_or_else(|| {
|
||||
crate::ErrorKind::LauncherError(format!(
|
||||
"No Java installed for version {}",
|
||||
version_info.java_version.map_or(8, |it| it.major_version),
|
||||
))
|
||||
})?,
|
||||
};
|
||||
let java_version = java_version.as_ref().ok_or_else(|| {
|
||||
crate::ErrorKind::LauncherError(format!(
|
||||
"No Java stored for version {}",
|
||||
version_info.java_version.map_or(8, |it| it.major_version),
|
||||
))
|
||||
})?;
|
||||
|
||||
// Get the path to the Java executable from the chosen Java implementation key
|
||||
let java_install: &Path = &PathBuf::from(&java_version.path);
|
||||
if !java_install.exists() {
|
||||
return Err(crate::ErrorKind::LauncherError(format!(
|
||||
"Could not find Java install: {}",
|
||||
@@ -175,7 +187,6 @@ pub async fn run(
|
||||
))
|
||||
.as_error());
|
||||
}
|
||||
|
||||
let java_args = profile
|
||||
.java
|
||||
.as_ref()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! Theseus profile management interface
|
||||
use crate::prelude::ModLoader;
|
||||
use crate::{jre, prelude::ModLoader};
|
||||
pub use crate::{
|
||||
state::{JavaSettings, Profile},
|
||||
State,
|
||||
@@ -145,6 +145,20 @@ pub async fn profile_create(
|
||||
}
|
||||
|
||||
profile.metadata.linked_project_id = linked_project_id;
|
||||
|
||||
// Attempts to find optimal JRE for the profile from the JavaGlobals
|
||||
// Finds optimal key, and see if key has been set in JavaGlobals
|
||||
let settings = state.settings.read().await;
|
||||
let optimal_version_key = jre::get_optimal_jre_key(&profile).await?;
|
||||
if settings.java_globals.get(&optimal_version_key).is_some() {
|
||||
profile.set_java_settings(Some(JavaSettings {
|
||||
jre_key: Some(optimal_version_key),
|
||||
extra_arguments: None,
|
||||
}))?;
|
||||
} else {
|
||||
println!("Could not detect optimal JRE: {optimal_version_key}, falling back to system default.");
|
||||
}
|
||||
|
||||
{
|
||||
let mut profiles = state.profiles.write().await;
|
||||
profiles.insert(profile)?;
|
||||
|
||||
Reference in New Issue
Block a user