Skip to content

Commit

Permalink
Fix java installs (#1123)
Browse files Browse the repository at this point in the history
* Fix java installs

* Finish java installs
  • Loading branch information
Geometrically committed Apr 19, 2024
1 parent 2877919 commit 49cecf8
Show file tree
Hide file tree
Showing 12 changed files with 104 additions and 305 deletions.
78 changes: 17 additions & 61 deletions theseus/src/api/jre.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,64 +10,32 @@ use crate::util::fetch::{fetch_advanced, fetch_json};
use crate::util::io;
use crate::util::jre::extract_java_majorminor_version;
use crate::{
state::JavaGlobals,
util::jre::{self, JavaVersion},
LoadingBarType, 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
// Using the supplied JavaVersions, autodetects the default JavaSettings
// Make a guess for what the default Java global settings should be
// Since the JRE paths are passed in as args, this handles the logic for selection. Currently this just pops the last one found
// TODO: When tauri compiler issue is fixed, this can be be improved (ie: getting JREs in-function)
pub async fn autodetect_java_globals(
mut java_8: Vec<JavaVersion>,
mut java_17: Vec<JavaVersion>,
mut java_18plus: Vec<JavaVersion>,
) -> crate::Result<JavaGlobals> {
// 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)
}

// Searches for jres on the system given a java version (ex: 1.8, 1.17, 1.18)
// Allow higher allows for versions higher than the given version to be returned ('at least')
pub async fn find_filtered_jres(
version: &str,
jres: Vec<JavaVersion>,
allow_higher: bool,
java_version: Option<u32>,
) -> crate::Result<Vec<JavaVersion>> {
let version = extract_java_majorminor_version(version)?;
let jres = jre::get_all_jre().await?;

// 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 {
if allow_higher {
jre_version >= version
Ok(if let Some(java_version) = java_version {
jres.into_iter()
.filter(|jre| {
let jre_version = extract_java_majorminor_version(&jre.version);
if let Ok(jre_version) = jre_version {
jre_version.1 == java_version
} else {
jre_version == version
false
}
} else {
false
}
})
.collect())
})
.collect()
} else {
jres
})
}

#[theseus_macros::debug_pin]
Expand Down Expand Up @@ -176,17 +144,6 @@ pub async fn auto_install_java(java_version: u32) -> crate::Result<PathBuf> {
}
}

// Get all JREs that exist on the system
pub async fn get_all_jre() -> crate::Result<Vec<JavaVersion>> {
Ok(jre::get_all_jre().await?)
}

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().await)
}

// Validates JRE at a given at a given path
pub async fn check_jre(path: PathBuf) -> crate::Result<Option<JavaVersion>> {
Ok(jre::check_java_at_filepath(&path).await)
Expand All @@ -196,14 +153,13 @@ pub async fn check_jre(path: PathBuf) -> crate::Result<Option<JavaVersion>> {
pub async fn test_jre(
path: PathBuf,
major_version: u32,
minor_version: u32,
) -> crate::Result<bool> {
let jre = match jre::check_java_at_filepath(&path).await {
Some(jre) => jre,
None => return Ok(false),
};
let (major, minor) = extract_java_majorminor_version(&jre.version)?;
Ok(major == major_version && minor == minor_version)
let (major, _) = extract_java_majorminor_version(&jre.version)?;
Ok(major == major_version)
}

// Gets maximum memory in KiB.
Expand Down
72 changes: 42 additions & 30 deletions theseus/src/launcher/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Logic for launching Minecraft
use crate::event::emit::{emit_loading, init_or_edit_loading};
use crate::event::{LoadingBarId, LoadingBarType};
use crate::jre::{self, JAVA_17_KEY, JAVA_18PLUS_KEY, JAVA_8_KEY};
use crate::launcher::io::IOError;
use crate::prelude::JavaVersion;
use crate::state::{Credentials, ProfileInstallStage};
Expand Down Expand Up @@ -118,24 +117,17 @@ pub async fn get_java_version_from_profile(
if let Some(java) = profile.java.clone().and_then(|x| x.override_version) {
Ok(Some(java))
} else {
let optimal_keys = match version_info
let key = version_info
.java_version
.as_ref()
.map(|it| it.major_version)
.unwrap_or(8)
{
0..=15 => vec![JAVA_8_KEY, JAVA_17_KEY, JAVA_18PLUS_KEY],
16..=17 => vec![JAVA_17_KEY, JAVA_18PLUS_KEY],
_ => vec![JAVA_18PLUS_KEY],
};
.unwrap_or(8);

let state = State::get().await?;
let settings = state.settings.read().await;

for key in optimal_keys {
if let Some(java) = settings.java_globals.get(&key.to_string()) {
return Ok(Some(java.clone()));
}
if let Some(java) = settings.java_globals.get(&format!("JAVA_{key}")) {
return Ok(Some(java.clone()));
}

Ok(None)
Expand Down Expand Up @@ -215,24 +207,43 @@ pub async fn install_minecraft(
)
.await?;

let java_version = get_java_version_from_profile(profile, &version_info)
.await?
.ok_or_else(|| {
crate::ErrorKind::OtherError(
"Missing correct java installation".to_string(),
)
})?;
// TODO: check if java exists, if not install it add to install step

let key = version_info
.java_version
.as_ref()
.map(|it| it.major_version)
.unwrap_or(8);
let (java_version, set_java) = if let Some(java_version) =
get_java_version_from_profile(profile, &version_info).await?
{
(std::path::PathBuf::from(java_version.path), false)
} else {
let path = crate::api::jre::auto_install_java(key).await?;

(path, true)
};

// Test jre version
let java_version = jre::check_jre(java_version.path.clone().into())
let java_version = crate::api::jre::check_jre(java_version.clone())
.await?
.ok_or_else(|| {
crate::ErrorKind::LauncherError(format!(
"Java path invalid or non-functional: {}",
java_version.path
"Java path invalid or non-functional: {:?}",
java_version
))
})?;

if set_java {
{
let mut settings = state.settings.write().await;
settings
.java_globals
.insert(format!("JAVA_{key}"), java_version.clone());
}
State::sync().await?;
}

// Download minecraft (5-90)
download::download_minecraft(
&state,
Expand Down Expand Up @@ -434,14 +445,15 @@ pub async fn launch_minecraft(
})?;

// Test jre version
let java_version = jre::check_jre(java_version.path.clone().into())
.await?
.ok_or_else(|| {
crate::ErrorKind::LauncherError(format!(
"Java path invalid or non-functional: {}",
java_version.path
))
})?;
let java_version =
crate::api::jre::check_jre(java_version.path.clone().into())
.await?
.ok_or_else(|| {
crate::ErrorKind::LauncherError(format!(
"Java path invalid or non-functional: {}",
java_version.path
))
})?;

let client_path = state
.directories
Expand Down
3 changes: 1 addition & 2 deletions theseus/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,9 @@ impl State {
let res2 = Tags::update();
let res3 = Metadata::update();
let res4 = Profiles::update_projects();
let res5 = Settings::update_java();
let res6 = CredentialsStore::update_creds();

let _ = join!(res1, res2, res3, res4, res5, res6);
let _ = join!(res1, res2, res3, res4, res6);
}
}
});
Expand Down
38 changes: 0 additions & 38 deletions theseus/src/state/settings.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
//! Theseus settings file
use crate::{
jre::{self, autodetect_java_globals, find_filtered_jres},
State,
};
use serde::{Deserialize, Serialize};
use std::path::{Path, PathBuf};
use tokio::fs;
Expand Down Expand Up @@ -116,40 +112,6 @@ impl Settings {
}
}

#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn update_java() {
let res = async {
let state = State::get().await?;
let settings_read = state.settings.write().await;

if settings_read.java_globals.count() == 0 {
drop(settings_read);
let jres = jre::get_all_jre().await?;
let java_8 =
find_filtered_jres("1.8", jres.clone(), false).await?;
let java_17 =
find_filtered_jres("1.17", jres.clone(), false).await?;
let java_18plus =
find_filtered_jres("1.18", jres.clone(), true).await?;
let java_globals =
autodetect_java_globals(java_8, java_17, java_18plus)
.await?;
state.settings.write().await.java_globals = java_globals;
}

Ok::<(), crate::Error>(())
}
.await;

match res {
Ok(()) => {}
Err(err) => {
tracing::warn!("Unable to update launcher java: {err}")
}
};
}

#[tracing::instrument(skip(self))]
pub async fn sync(&self, to: &Path) -> crate::Result<()> {
fs::write(to, serde_json::to_vec(self)?)
Expand Down
42 changes: 4 additions & 38 deletions theseus_gui/src-tauri/src/api/jre.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ use theseus::prelude::*;
pub fn init<R: tauri::Runtime>() -> TauriPlugin<R> {
tauri::plugin::Builder::new("jre")
.invoke_handler(tauri::generate_handler![
jre_get_all_jre,
jre_find_filtered_jres,
jre_autodetect_java_globals,
jre_validate_globals,
jre_get_jre,
jre_test_jre,
jre_auto_install_java,
Expand All @@ -20,39 +17,12 @@ pub fn init<R: tauri::Runtime>() -> TauriPlugin<R> {
.build()
}

/// Get all JREs that exist on the system
#[tauri::command]
pub async fn jre_get_all_jre() -> Result<Vec<JavaVersion>> {
Ok(jre::get_all_jre().await?)
}

// Finds the installation of Java 8, if it exists
#[tauri::command]
pub async fn jre_find_filtered_jres(
jres: Vec<JavaVersion>,
version: String,
allow_higher: bool,
version: Option<u32>,
) -> Result<Vec<JavaVersion>> {
Ok(jre::find_filtered_jres(&version, jres, allow_higher).await?)
}

// Autodetect Java globals, by searching the users computer.
// Selects from the given JREs, and returns a new JavaGlobals
// Returns a *NEW* JavaGlobals that can be put into Settings
#[tauri::command]
pub async fn jre_autodetect_java_globals(
java_8: Vec<JavaVersion>,
java_17: Vec<JavaVersion>,
java_18plus: Vec<JavaVersion>,
) -> Result<JavaGlobals> {
Ok(jre::autodetect_java_globals(java_8, java_17, java_18plus).await?)
}

// Validates java globals, by checking if the paths exist
// If false, recommend to direct them to reassign, or to re-guess
#[tauri::command]
pub async fn jre_validate_globals() -> Result<bool> {
Ok(jre::validate_globals().await?)
Ok(jre::find_filtered_jres(version).await?)
}

// Validates JRE at a given path
Expand All @@ -64,12 +34,8 @@ pub async fn jre_get_jre(path: PathBuf) -> Result<Option<JavaVersion>> {

// Tests JRE of a certain version
#[tauri::command]
pub async fn jre_test_jre(
path: PathBuf,
major_version: u32,
minor_version: u32,
) -> Result<bool> {
Ok(jre::test_jre(path, major_version, minor_version).await?)
pub async fn jre_test_jre(path: PathBuf, major_version: u32) -> Result<bool> {
Ok(jre::test_jre(path, major_version).await?)
}

// Auto installs java for the given java version
Expand Down
20 changes: 5 additions & 15 deletions theseus_gui/src/components/ui/JavaDetectionModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,7 @@
<script setup>
import { Modal, PlusIcon, CheckIcon, Button, XIcon } from 'omorphia'
import { ref } from 'vue'
import {
find_jre_17_jres,
find_jre_18plus_jres,
find_jre_8_jres,
get_all_jre,
} from '@/helpers/jre.js'
import { find_filtered_jres } from '@/helpers/jre.js'
import { handleError } from '@/store/notifications.js'
import { mixpanel_track } from '@/helpers/mixpanel'
import { useTheming } from '@/store/theme.js'
Expand All @@ -55,15 +50,10 @@ const currentSelected = ref({})
defineExpose({
show: async (version, currentSelectedJava) => {
if (version <= 8 && !!version) {
chosenInstallOptions.value = await find_jre_8_jres().catch(handleError)
} else if (version >= 18) {
chosenInstallOptions.value = await find_jre_18plus_jres().catch(handleError)
} else if (version) {
chosenInstallOptions.value = await find_jre_17_jres().catch(handleError)
} else {
chosenInstallOptions.value = await get_all_jre().catch(handleError)
}
chosenInstallOptions.value = await find_filtered_jres(version).catch(handleError)
console.log(chosenInstallOptions.value)
console.log(version)
currentSelected.value = currentSelectedJava
if (!currentSelected.value) {
Expand Down
Loading

0 comments on commit 49cecf8

Please sign in to comment.