feat: Java checker and DB helpers

This commit is contained in:
LynithDev 2025-03-30 15:38:55 +02:00
parent 33ac7b4397
commit 249898b3d2
15 changed files with 201 additions and 55 deletions

63
Cargo.lock generated
View file

@ -1214,12 +1214,12 @@ dependencies = [
[[package]]
name = "errno"
version = "0.3.9"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
dependencies = [
"libc",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@ -1616,6 +1616,18 @@ dependencies = [
"wasi 0.11.0+wasi-snapshot-preview1",
]
[[package]]
name = "getrandom"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasi 0.14.2+wasi-0.2.4",
]
[[package]]
name = "gimli"
version = "0.31.0"
@ -2297,9 +2309,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.159"
version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
[[package]]
name = "libloading"
@ -2340,9 +2352,9 @@ dependencies = [
[[package]]
name = "linux-raw-sys"
version = "0.4.14"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413"
[[package]]
name = "lock_api"
@ -2957,6 +2969,7 @@ dependencies = [
"sysinfo",
"tauri",
"tauri-specta",
"tempfile",
"thiserror 1.0.64",
"tokio",
"tokio-stream",
@ -3573,6 +3586,12 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
[[package]]
name = "radium"
version = "0.7.0"
@ -3918,15 +3937,15 @@ dependencies = [
[[package]]
name = "rustix"
version = "0.38.37"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96"
dependencies = [
"bitflags 2.6.0",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@ -5287,12 +5306,12 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.12.0"
version = "3.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
dependencies = [
"cfg-if",
"fastrand",
"getrandom 0.3.2",
"once_cell",
"rustix",
"windows-sys 0.59.0",
@ -5896,6 +5915,15 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasi"
version = "0.14.2+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
dependencies = [
"wit-bindgen-rt",
]
[[package]]
name = "wasite"
version = "0.1.0"
@ -6516,6 +6544,15 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags 2.6.0",
]
[[package]]
name = "wry"
version = "0.46.2"

View file

@ -109,7 +109,7 @@ tokio = { version = "1.40", features = [ "full" ] }
tokio-stream = { version = "0.1.16", features = [ "fs" ] }
notify = { version = "6.1", default-features = false }
notify-debouncer-mini = { version = "0.4", default-features = false }
tempfile = { version = "3.12" }
tempfile = { version = "3.19" }
dunce = { version = "1.0.5" }
zip = { version = "2.2.0" }
dirs = { version = "5.0" }

View file

@ -21,7 +21,7 @@ tauri = [
"specta",
"gui"
]
specta = [ "dep:specta" ]
specta = [ "dep:specta", "onelauncher_entity/specta" ]
cli = [ "dep:indicatif" ]
gui = []
@ -82,6 +82,7 @@ bytes = { workspace = true }
base64 = { workspace = true }
async-compression = { workspace = true }
dunce = { workspace = true }
tempfile = { workspace = true }
# features[tauri]
tauri = { workspace = true, optional = true }

Binary file not shown.

View file

@ -0,0 +1,19 @@
public final class JavaInfo {
private static final String[] CHECKED_PROPERTIES = new String[] {"os.arch", "java.version", "java.vendor"};
public static void main(String[] args) {
int returnCode = 0;
for (String key : CHECKED_PROPERTIES) {
String property = System.getProperty(key);
if (property != null) {
System.out.println(key + "=" + property);
} else {
returnCode = 1;
}
}
System.exit(returnCode);
}
}

View file

@ -0,0 +1,6 @@
[`JavaInfo`](./JavaInfo.java) compiled by [`LynithDev`](https://github.com/LynithDev) using
```
os.arch=amd64
java.version=1.8.0_382
java.vendor=Azul Systems, Inc.
```

View file

View file

@ -1,2 +1,3 @@
pub mod ingress;
pub mod proxy;
pub mod proxy;
pub mod java;

View file

@ -108,7 +108,8 @@ pub struct IngressPayload {
pub enum IngressType {
Download {
file_name: String,
}
},
JavaCheck
}
impl Drop for IngressId {

View file

@ -1,14 +1,108 @@
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, path::PathBuf};
use crate::LauncherResult;
use onelauncher_entity::java_versions;
use sea_orm::{ActiveValue::Set, ActiveModelTrait, ColumnTrait, EntityTrait, Order, QueryFilter, QueryOrder};
use serde::Serialize;
// pub async fn get_java_versions() -> LauncherResult<Vec<JavaVersion>> {
// // let java_versions = sqlx::query_as!(
// // JavaVersion,
// // r#"
// // SELECT id, major_version, display_name, absolute_path, full_version FROM java_versions
// // "#
// // );
use crate::{api::ingress::{init_ingress, send_ingress}, store::{ingress::IngressType, State}, utils::io::{self, IOError}, LauncherResult};
pub async fn get_java_all() -> LauncherResult<Vec<java_versions::Model>> {
let db = &State::get().await?.db;
Ok(java_versions::Entity::find()
.order_by(java_versions::Column::MajorVersion, Order::Desc)
.all(db)
.await?)
}
pub async fn get_java_by_id(id: i32) -> LauncherResult<Option<java_versions::Model>> {
let db = &State::get().await?.db;
Ok(java_versions::Entity::find()
.filter(java_versions::Column::Id.eq(id))
.one(db)
.await?)
}
pub async fn get_java_by_major(major: i32) -> LauncherResult<Vec<java_versions::Model>> {
let db = &State::get().await?.db;
Ok(java_versions::Entity::find()
.filter(java_versions::Column::MajorVersion.eq(major))
.order_by(java_versions::Column::FullVersion, Order::Desc)
.all(db)
.await?)
}
pub async fn insert_java(absolute_path: PathBuf) -> LauncherResult<java_versions::Model> {
let db = &State::get().await?.db;
let java_info = check_java_runtime(&absolute_path).await?;
let major_version = if java_info.java_version[0..2].eq("1.") {
java_info.java_version[2..3].parse::<i32>().unwrap_or(0)
} else {
let split = java_info.java_version.split_once('.').unwrap_or_default();
split.0.parse::<i32>().unwrap_or(0)
};
let model = java_versions::ActiveModel {
absolute_path: Set(absolute_path.to_string_lossy().to_string()),
major_version: Set(major_version),
full_version: Set(java_info.java_version.clone()),
vendor_name: Set(java_info.java_vendor.clone()),
..Default::default()
};
Ok(model.insert(db).await?)
}
#[onelauncher_macro::specta]
#[derive(Debug, Clone, Serialize)]
pub struct JavaInfo {
pub os_arch: String,
pub java_version: String,
pub java_vendor: String,
}
const JAVA_INFO_CLASS: &[u8] = include_bytes!("../../assets/java/JavaInfo.class");
pub async fn check_java_runtime(absolute_path: &PathBuf) -> LauncherResult<JavaInfo> {
let id = init_ingress(IngressType::JavaCheck, "Checking JRE information", 100.0).await?;
let dir = io::tempdir()?;
let file = dir.path().join("JavaInfo.class");
send_ingress(&id, 25.0).await?;
io::write(&file, JAVA_INFO_CLASS).await?;
send_ingress(&id, 25.0).await?;
let java_info = tokio::process::Command::new(absolute_path)
.arg("-cp")
.arg(dir.path())
.arg("JavaInfo")
.env_remove("_JAVA_OPTIONS")
.output()
.await
.map_err(IOError::from)?;
let java_info = String::from_utf8_lossy(&java_info.stdout);
send_ingress(&id, 50.0).await?;
let info = java_info.lines()
.map(|line| {
let mut parts = line.splitn(2, '=');
let key = parts.next().unwrap_or("unknown");
let value = parts.next().unwrap_or("unknown");
(key.to_string(), value.to_string())
})
.collect::<HashMap<_, _>>();
Ok(JavaInfo {
os_arch: info.get("os.arch").cloned().unwrap_or_else(|| String::from("unknown")),
java_version: info.get("java.version").cloned().unwrap_or_else(|| String::from("unknown")),
java_vendor: info.get("java.vendor").cloned().unwrap_or_else(|| String::from("unknown")),
})
}
// Ok(vec![])
// }

View file

@ -1,4 +1,5 @@
use async_compression::tokio::bufread::GzipDecoder;
use tempfile::TempDir;
use tokio::io::AsyncReadExt;
/// A wrapper around generic and unhelpful [`std::io::Error`] messages.
@ -182,4 +183,14 @@ pub async fn remove_file(path: impl AsRef<std::path::Path>) -> Result<(), IOErro
source: e,
path: path.to_string_lossy().to_string(),
})
}
}
/// Creates a temporary directory.
pub fn tempdir() -> Result<TempDir, IOError> {
Ok(tempfile::tempdir()?)
}
/// Creates a temporary file.
pub fn tempfile() -> Result<std::fs::File, IOError> {
Ok(tempfile::tempfile()?)
}

View file

@ -1,24 +0,0 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <https://unlicense.org>

View file

@ -11,7 +11,7 @@ pub struct Model {
pub id: i32,
pub major_version: i32,
#[sea_orm(column_type = "Text")]
pub display_name: String,
pub vendor_name: String,
#[sea_orm(column_type = "Text")]
pub absolute_path: String,
#[sea_orm(column_type = "Text")]

View file

@ -7,7 +7,7 @@ create table cluster_groups (
create table java_versions (
id integer not null,
major_version integer not null,
display_name text not null,
vendor_name text not null,
absolute_path text not null,
full_version text not null,
constraint java_versions_pk primary key (id autoincrement)