🐛 fix: standardize rust constants bcs i was bored
This commit is contained in:
parent
c853a66969
commit
246b5a3d6a
26 changed files with 739 additions and 487 deletions
|
|
@ -110,7 +110,7 @@ pub fn plugin<R: Runtime>() -> TauriPlugin<R> {
|
|||
})
|
||||
.js_init_script(format!(
|
||||
r#"window.__ONELAUNCHER_VERSION__ = "{}";"#,
|
||||
env!("CARGO_PKG_VERSION")
|
||||
onelauncher::constants::VERSION,
|
||||
))
|
||||
.build()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,13 +24,13 @@
|
|||
"@rspc/tauri": "^0.2.0",
|
||||
"@solid-primitives/refs": "^1.0.8",
|
||||
"@solidjs/router": "^0.14.1",
|
||||
"@tanstack/solid-query": "^5.51.9",
|
||||
"@tanstack/solid-query": "^5.51.15",
|
||||
"@tauri-apps/api": "^2.0.0-beta.13",
|
||||
"@tauri-apps/plugin-clipboard-manager": "github:tauri-apps/tauri-plugin-clipboard-manager#v2",
|
||||
"@tauri-apps/plugin-shell": "github:tauri-apps/tauri-plugin-shell#v2",
|
||||
"@thisbeyond/solid-dnd": "^0.7.5",
|
||||
"@thisbeyond/solid-select": "^0.15.0",
|
||||
"@unocss/reset": "^0.61.5",
|
||||
"@unocss/reset": "^0.61.6",
|
||||
"@untitled-theme/icons-solid": "^0.10.5",
|
||||
"overlayscrollbars": "^2.9.2",
|
||||
"overlayscrollbars-solid": "^0.5.5",
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
"@types/uuid": "^10.0.0",
|
||||
"jsdom": "^24.1.1",
|
||||
"sass": "^1.77.8",
|
||||
"unocss": "^0.61.5",
|
||||
"unocss": "^0.61.6",
|
||||
"vite-plugin-solid": "^2.10.2",
|
||||
"vite-plugin-solid-svg": "^0.8.1",
|
||||
"vite-tsconfig-paths": "^4.3.2"
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
"@types/node": "^20.14.12",
|
||||
"@vitest/ui": "^2.0.4",
|
||||
"bumpp": "^9.4.1",
|
||||
"eslint": "^9.7.0",
|
||||
"eslint": "^9.8.0",
|
||||
"eslint-plugin-solid": "^0.14.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsx": "^4.16.2",
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
"@rspc/solid-query": "^0.2.3",
|
||||
"@rspc/tauri": "^0.2.0",
|
||||
"@solid-primitives/deep": "^0.2.9",
|
||||
"@tanstack/solid-query": "^5.51.9",
|
||||
"@tanstack/solid-query": "^5.51.15",
|
||||
"fast-equals": "^5.0.1",
|
||||
"plausible-tracker": "^0.3.9",
|
||||
"solid-js": "^1.8.19",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use crate::data::{ManagedPackage, ManagedVersion, PackageType};
|
||||
use crate::package::from::MODRINTH_API_URL;
|
||||
use crate::store::{ManagedVersionFile, PackageFile, PackageSide};
|
||||
use crate::utils::http::fetch;
|
||||
use crate::{Result, State};
|
||||
|
|
@ -127,7 +126,7 @@ pub struct Gallery {
|
|||
|
||||
macro_rules! format_url {
|
||||
($($arg:tt)*) => {{
|
||||
format!("{}{}", MODRINTH_API_URL, format!($($arg)*))
|
||||
format!("{}{}", crate::constants::MODRINTH_API_URL, format!($($arg)*))
|
||||
}};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,9 +13,6 @@ use serde::{Deserialize, Serialize};
|
|||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub const MODRINTH_API_URL: &str = "https://api.modrinth.com/v2";
|
||||
pub const CURSEFORGE_API_URL: &str = "https://api.cursefor";
|
||||
|
||||
#[derive(Serialize, Deserialize, Eq, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PackFormat {
|
||||
|
|
@ -216,7 +213,11 @@ pub async fn generate_pack_from_version_id(
|
|||
send_ingress(&ingress, 0.0, Some("fetching version")).await?;
|
||||
let version: ManagedVersion = fetch_json(
|
||||
Method::GET,
|
||||
&format!("{}version/{}", MODRINTH_API_URL, version_id),
|
||||
&format!(
|
||||
"{}version/{}",
|
||||
crate::constants::MODRINTH_API_URL,
|
||||
version_id
|
||||
),
|
||||
None,
|
||||
None,
|
||||
&state.fetch_semaphore,
|
||||
|
|
@ -250,7 +251,11 @@ pub async fn generate_pack_from_version_id(
|
|||
|
||||
let pkg: ManagedPackage = fetch_json(
|
||||
Method::GET,
|
||||
&format!("{}project/{}", MODRINTH_API_URL, version.package_id),
|
||||
&format!(
|
||||
"{}project/{}",
|
||||
crate::constants::MODRINTH_API_URL,
|
||||
version.package_id
|
||||
),
|
||||
None,
|
||||
None,
|
||||
&state.fetch_semaphore,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ use std::path::{Component, PathBuf};
|
|||
|
||||
use super::from::{
|
||||
generate_pack_from_file, generate_pack_from_version_id, CreatePack, CreatePackLocation,
|
||||
PackFormat, MODRINTH_API_URL,
|
||||
PackFormat,
|
||||
};
|
||||
|
||||
/// Install a pack
|
||||
|
|
@ -280,7 +280,7 @@ pub async fn remove_all_related_files(
|
|||
.filter_map(|f| Some(f.hashes.get(&PackFileHash::Sha512)?.clone()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let files_url = format!("{}version_files", MODRINTH_API_URL);
|
||||
let files_url = format!("{}version_files", crate::constants::MODRINTH_API_URL);
|
||||
|
||||
let hash_packages = fetch_json::<HashMap<String, ManagedVersion>>(
|
||||
Method::POST,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ use super::IngressId;
|
|||
use crate::api::proxy::{
|
||||
ClusterPayloadType, Ingress, IngressType, InternetPayload, ProcessPayloadType, ProxyError,
|
||||
};
|
||||
#[cfg(feature = "cli")]
|
||||
use crate::constants::CLI_TOTAL_INGRESS;
|
||||
use crate::store::{ClusterPath, IngressProcessType, IngressProcessor};
|
||||
use uuid::Uuid;
|
||||
|
||||
|
|
@ -22,9 +24,6 @@ pub async fn init_ingress(
|
|||
Ok(key)
|
||||
}
|
||||
|
||||
#[cfg(feature = "cli")]
|
||||
const CLI_TOTAL_INGRESS: u64 = 1000;
|
||||
|
||||
#[onelauncher_macros::memory]
|
||||
pub async fn init_ingress_internal(
|
||||
ingress_type: IngressType,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! Settings Management
|
||||
|
||||
use crate::proxy::send::{init_ingress, send_ingress};
|
||||
use crate::store::{self, Clusters, Directories, Settings};
|
||||
use crate::store::{Clusters, Directories, Settings};
|
||||
use crate::State;
|
||||
use std::path::{Path, PathBuf};
|
||||
use tokio::sync::RwLock;
|
||||
|
|
@ -103,7 +103,9 @@ pub async fn set_directory(new: PathBuf) -> crate::Result<()> {
|
|||
{
|
||||
let epath = e.path();
|
||||
if let Some(file_name) = epath.file_name() {
|
||||
if file_name == store::CLUSTERS_FOLDER || file_name == store::METADATA_FOLDER {
|
||||
if file_name == crate::constants::CLUSTERS_FOLDER
|
||||
|| file_name == crate::constants::METADATA_FOLDER
|
||||
{
|
||||
if across_filesystems {
|
||||
entries.extend(crate::package::import::sub(&epath).await?);
|
||||
cleanable.push(epath.clone());
|
||||
|
|
|
|||
|
|
@ -1,18 +1,26 @@
|
|||
//! **OneLauncher Constants**
|
||||
//!
|
||||
//! Public constant variables and strings that are used throughout the launcher.
|
||||
//! Can be shared publically, any encrypted secrets should be stored in [`crate::store::credentials`].
|
||||
//! Can be shared publically, any secrets should be stored in [`crate::store::credentials`].
|
||||
|
||||
// =========== Core Metadata ===========
|
||||
/// The name of the launcher.
|
||||
pub const NAME: &str = "OneLauncher";
|
||||
/// The version of the launcher
|
||||
pub const VERSION: &str = "1.0.0-alpha.1"; // todo: env
|
||||
/// The version of the launcher (from `../Cargo.toml` env).
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
// =========== Default Ingress ===========
|
||||
/// The amount of attempts to fetch a file before a request fails.
|
||||
pub const FETCH_ATTEMPTS: usize = 3;
|
||||
/// The total ingress capacity of the CLI, provided to [`indicatif`].
|
||||
#[cfg(feature = "cli")]
|
||||
pub const CLI_TOTAL_INGRESS: u64 = 1000;
|
||||
/// The newline which we replace in metadata files.
|
||||
pub const DUMMY_REPLACE_NEWLINE: &str = "\n";
|
||||
|
||||
// =========== Authentication ===========
|
||||
/// The Discord RPC client ID.
|
||||
pub const DISCORD_RPC_CLIENT_ID: &str = "1234567890000000";
|
||||
|
||||
/// Our Discord RPC client ID.
|
||||
pub const DISCORD_RPC_CLIENT_ID: &str = "1234567890000000"; // todo
|
||||
/// Our Microsoft client ID.
|
||||
pub const MICROSOFT_CLIENT_ID: &str = "9eac3a4e-8cdd-43ef-863e-49cd601b1f03";
|
||||
/// Mojang/Microsoft client ID.
|
||||
|
|
@ -22,6 +30,47 @@ pub const MINECRAFT_REDIRECT_URL: &str = "https://login.live.com/oauth20_desktop
|
|||
/// Mojang/Microsoft login xboxlive scopes to get tokens.
|
||||
pub const MINECRAFT_SCOPES: &str = "service::user.auth.xboxlive.com::MBI_SSL";
|
||||
|
||||
// =========== API ===========
|
||||
/// The Modrinth API base url.
|
||||
pub const MODRINTH_API_URL: &str = "https://api.modrinth.com/v2";
|
||||
/// The Curseforge API base url.
|
||||
pub const CURSEFORGE_API_URL: &str = "https://api.curseforge";
|
||||
/// Our metadata API base url.
|
||||
pub const METADATA_API_URL: &str = "https://meta.polyfrost.org";
|
||||
|
||||
// =========== Paths ===========
|
||||
/// The public `settings.json` file used to store the global [`Settings`] state.
|
||||
///
|
||||
/// [`Settings`]: crate::store::Settings
|
||||
pub const SETTINGS_FILE: &str = "settings.json";
|
||||
/// The public `cluster.json` file used to store the global [`Clusters`] state.
|
||||
///
|
||||
/// [`Clusters`]: crate::store::Clusters
|
||||
pub const CLUSTER_FILE: &str = "cluster.json";
|
||||
/// The public `authentication.json` file used to store the global [`MinecraftAuth`] state.
|
||||
///
|
||||
/// [`MinecraftAuth`]: crate::store::MinecraftAuth
|
||||
pub const AUTH_FILE: &str = "authentication.json";
|
||||
/// The public `processor.json` file used to store the global [`Processor`] state.
|
||||
///
|
||||
/// [`Processor`]: crate::store::Processor
|
||||
pub const PROCESSOR_FILE: &str = "processor.json";
|
||||
|
||||
/// The current [`Settings`] format version, bumped for breaking changes.
|
||||
/// If updated, a config file migration logic **NEEDS** to be implemented.
|
||||
///
|
||||
/// [`Settings`]: crate::store::Settings
|
||||
pub const CURRENT_SETTINGS_FORMAT_VERSION: u32 = 1;
|
||||
|
||||
/// The constant core caches folder.
|
||||
pub const CACHES_FOLDER: &str = "caches";
|
||||
/// The constant core crash reports folder.
|
||||
pub const CRASH_PATH: &str = "crash-reports";
|
||||
/// The constant core clusters folder.
|
||||
pub const CLUSTERS_FOLDER: &str = "clusters";
|
||||
/// The constant core metadata folder.
|
||||
pub const METADATA_FOLDER: &str = "metadata";
|
||||
|
||||
// =========== Hacky Mojang-spec OS constants ===========
|
||||
#[cfg(target_os = "windows")]
|
||||
pub const TARGET_OS: &str = "windows";
|
||||
|
|
@ -41,4 +90,19 @@ pub const NATIVE_ARCH: &str = "64";
|
|||
#[cfg(all(not(target_arch = "x86_64"), not(target_arch = "x86")))]
|
||||
pub const NATIVE_ARCH: &str = "64";
|
||||
|
||||
// TODO: Add more architectures
|
||||
// =========== Java ===========
|
||||
/// The default java executable on Windows.
|
||||
#[cfg(target_os = "windows")]
|
||||
pub const JAVA_BIN: &str = "javaw.exe";
|
||||
|
||||
/// The default java executable on macOS and Linux.
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub const JAVA_BIN: &str = "java";
|
||||
|
||||
/// The bit width on x64 architectures.
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub const ARCH_WIDTH: &str = "64";
|
||||
|
||||
/// The bit width on x32 architectures.
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub const ARCH_WIDTH: &str = "32";
|
||||
|
|
|
|||
|
|
@ -9,12 +9,11 @@ use interpulse::api::minecraft::{Argument, ArgumentValue, Library, VersionType};
|
|||
use interpulse::api::modded::SidedDataEntry;
|
||||
use interpulse::utils::get_path_from_artifact;
|
||||
|
||||
use crate::constants::DUMMY_REPLACE_NEWLINE;
|
||||
use crate::store::{Memory, MinecraftCredentials, Resolution};
|
||||
use crate::utils::io::IOError;
|
||||
use crate::utils::platform::classpath_separator;
|
||||
|
||||
const DUMMY_REPLACE_NEWLINE: &str = "\n";
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn java_arguments(
|
||||
arguments: Option<&[Argument]>,
|
||||
|
|
@ -285,8 +284,8 @@ fn parse_java_argument(
|
|||
.to_string_lossy(),
|
||||
)
|
||||
.replace("${classpath_seperator}", classpath_separator(java_arch))
|
||||
.replace("${launcher_name}", "onelauncher")
|
||||
.replace("${launcher_version}", env!("CARGO_PKG_VERSION"))
|
||||
.replace("${launcher_name}", crate::constants::NAME)
|
||||
.replace("${launcher_version}", crate::constants::VERSION)
|
||||
.replace("${version_name}", version)
|
||||
.replace("${classpath}", classpaths))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -290,7 +290,7 @@ pub async fn download_libraries(
|
|||
lib.natives.as_ref()?.get(&Os::native_arch(java_arch))?,
|
||||
lib.downloads.as_ref()?.classifiers.as_ref()?
|
||||
))) {
|
||||
let parsed = os_key.replace("${arch}", crate::utils::platform::ARCH_WIDTH);
|
||||
let parsed = os_key.replace("${arch}", crate::constants::ARCH_WIDTH);
|
||||
if let Some(native) = classifiers.get(&parsed) {
|
||||
let data = fetch(&native.url, Some(&native.sha1), &st.fetch_semaphore).await?;
|
||||
let reader = std::io::Cursor::new(&data);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use std::collections::HashMap;
|
|||
use std::path::{Path, PathBuf};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::constants::CLUSTER_FILE;
|
||||
use crate::proxy::send::{send_cluster, send_message};
|
||||
use crate::proxy::ClusterPayloadType;
|
||||
use crate::utils::http::{write_icon, IoSemaphore};
|
||||
|
|
@ -19,9 +20,6 @@ use crate::State;
|
|||
|
||||
use super::{Directories, InitHooks, Memory, Package, PackageType, Resolution};
|
||||
|
||||
/// The public `cluster.json` file used to store the global [`Clusters`] state.
|
||||
const CLUSTER_JSON: &str = "cluster.json";
|
||||
|
||||
/// Core Cluster state manager with a [`HashMap<ClusterPath, Cluster>`].
|
||||
pub(crate) struct Clusters(pub HashMap<ClusterPath, Cluster>);
|
||||
|
||||
|
|
@ -712,7 +710,7 @@ impl Clusters {
|
|||
.map(Ok::<_, crate::Error>)
|
||||
.try_for_each_concurrent(None, |(_, cluster)| async move {
|
||||
let json = serde_json::to_vec(&cluster)?;
|
||||
let json_path = cluster.get_full_path().await?.join(CLUSTER_JSON);
|
||||
let json_path = cluster.get_full_path().await?.join(CLUSTER_FILE);
|
||||
io::write(&json_path, &json).await?;
|
||||
Ok::<_, crate::Error>(())
|
||||
})
|
||||
|
|
@ -723,7 +721,7 @@ impl Clusters {
|
|||
|
||||
/// read a cluster from a directory
|
||||
async fn from_dir(path: &Path, dirs: &Directories) -> crate::Result<Cluster> {
|
||||
let json = io::read(&path.join(CLUSTER_JSON)).await?;
|
||||
let json = io::read(&path.join(CLUSTER_FILE)).await?;
|
||||
let mut cluster = serde_json::from_slice::<Cluster>(&json)?;
|
||||
cluster.path = PathBuf::from(
|
||||
path.strip_prefix(dirs.clusters_dir().await)
|
||||
|
|
|
|||
|
|
@ -5,15 +5,6 @@ use tokio::sync::RwLock;
|
|||
use super::Settings;
|
||||
use crate::constants;
|
||||
|
||||
/// The public `settings.json` file used to store the [`Settings`] state.
|
||||
pub const SETTINGS_FILE: &str = "settings.json";
|
||||
/// The constant core caches folder.
|
||||
pub const CACHES_FOLDER: &str = "caches";
|
||||
/// The constant core clusters folder.
|
||||
pub const CLUSTERS_FOLDER: &str = "clusters";
|
||||
/// The constant core metadata folder.
|
||||
pub const METADATA_FOLDER: &str = "metadata";
|
||||
|
||||
/// Directory management and utilities.
|
||||
#[derive(Debug)]
|
||||
pub struct Directories {
|
||||
|
|
@ -59,7 +50,10 @@ impl Directories {
|
|||
/// Get the `config_dir/metadata` folder within the core config directory.
|
||||
#[inline]
|
||||
pub async fn metadata_dir(&self) -> PathBuf {
|
||||
self.config_dir.read().await.join(METADATA_FOLDER)
|
||||
self.config_dir
|
||||
.read()
|
||||
.await
|
||||
.join(constants::METADATA_FOLDER)
|
||||
}
|
||||
|
||||
/// Get the `config_dir/metadata/libraries` folder for Minecraft libraries.
|
||||
|
|
@ -89,7 +83,7 @@ impl Directories {
|
|||
/// Get the `settings_dir/settings.json` file as a [`PathBuf`].
|
||||
#[inline]
|
||||
pub fn settings_file(&self) -> PathBuf {
|
||||
self.settings_dir.join(SETTINGS_FILE)
|
||||
self.settings_dir.join(constants::SETTINGS_FILE)
|
||||
}
|
||||
|
||||
/// Get a [`PathBuf`] from a provided environment variable.
|
||||
|
|
|
|||
|
|
@ -4,15 +4,13 @@ use interpulse::api::minecraft::VersionManifest as MinecraftManifest;
|
|||
use interpulse::api::modded::Manifest as ModdedManifest;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::constants::METADATA_API_URL;
|
||||
use crate::utils::http::{fetch, read_json, write, FetchSemaphore, IoSemaphore};
|
||||
use crate::utils::io::copy;
|
||||
use crate::State;
|
||||
|
||||
use super::Directories;
|
||||
|
||||
/// The metadata url.
|
||||
const METADATA_URL: &str = "https://meta.polyfrost.org";
|
||||
|
||||
/// A structure of manifests and metadata fetching utilities.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Metadata {
|
||||
|
|
@ -33,7 +31,7 @@ pub struct Metadata {
|
|||
impl Metadata {
|
||||
/// Get the formatted manifest for a specific [`Metadata`] type.
|
||||
fn get_manifest(name: &str, version: usize) -> String {
|
||||
format!("{METADATA_URL}/{name}/v{version}/manifest.json")
|
||||
format!("{METADATA_API_URL}/{name}/v{version}/manifest.json")
|
||||
}
|
||||
|
||||
/// Fetch all available metadata types that are currently [`None`] and get a new [`Metadata`] structure.
|
||||
|
|
|
|||
|
|
@ -13,9 +13,7 @@ use std::collections::HashMap;
|
|||
use std::fmt::Write;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::constants::{MINECRAFT_CLIENT_ID, MINECRAFT_REDIRECT_URL, MINECRAFT_SCOPES};
|
||||
|
||||
const AUTH_STORE: &str = "authentication.json";
|
||||
use crate::constants::{AUTH_FILE, MINECRAFT_CLIENT_ID, MINECRAFT_REDIRECT_URL, MINECRAFT_SCOPES};
|
||||
|
||||
/// The core state of Microsoft authentication for the launcher
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
|
|
@ -35,7 +33,7 @@ impl MinecraftState {
|
|||
dirs: &super::Directories,
|
||||
io_semaphore: &crate::utils::http::IoSemaphore,
|
||||
) -> crate::Result<Self> {
|
||||
let path = dirs.caches_dir().await.join(AUTH_STORE);
|
||||
let path = dirs.caches_dir().await.join(AUTH_FILE);
|
||||
let store = crate::utils::http::read_json(&path, io_semaphore)
|
||||
.await
|
||||
.ok();
|
||||
|
|
@ -55,7 +53,7 @@ impl MinecraftState {
|
|||
#[tracing::instrument(skip(self))]
|
||||
pub async fn save(&self) -> crate::Result<()> {
|
||||
let state = crate::State::get().await?;
|
||||
let path = state.directories.caches_dir().await.join(AUTH_STORE);
|
||||
let path = state.directories.caches_dir().await.join(AUTH_FILE);
|
||||
crate::utils::http::write(&path, &serde_json::to_vec(&self)?, &state.io_semaphore).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use tokio::task::JoinHandle;
|
|||
use uuid::Uuid;
|
||||
|
||||
use crate::api::cluster;
|
||||
use crate::constants::PROCESSOR_FILE;
|
||||
use crate::proxy::send::send_process;
|
||||
use crate::proxy::ProcessPayloadType;
|
||||
use crate::utils::http::read_json;
|
||||
|
|
@ -18,9 +19,6 @@ use crate::State;
|
|||
|
||||
use super::{Cluster, ClusterPath};
|
||||
|
||||
/// Global processor cache file.
|
||||
const PROCESSOR_JSON: &str = "processor.json";
|
||||
|
||||
/// Wrapper over a HashMap of PIDs to ProcessorChildren and unified apis
|
||||
pub struct Processor(HashMap<Uuid, Arc<RwLock<ProcessorChild>>>);
|
||||
|
||||
|
|
@ -168,7 +166,7 @@ impl ChildType {
|
|||
post,
|
||||
};
|
||||
|
||||
let path = state.directories.caches_dir().await.join(PROCESSOR_JSON);
|
||||
let path = state.directories.caches_dir().await.join(PROCESSOR_FILE);
|
||||
let mut caches = if let Ok(proc_json) =
|
||||
read_json::<HashMap<Uuid, ProcessorCache>>(&path, &state.io_semaphore).await
|
||||
{
|
||||
|
|
@ -187,8 +185,7 @@ impl ChildType {
|
|||
/// Remove a child from the global store of processes.
|
||||
pub async fn remove(&self, uuid: Uuid) -> crate::Result<()> {
|
||||
let state = crate::State::get().await?;
|
||||
|
||||
let path = state.directories.caches_dir().await.join(PROCESSOR_JSON);
|
||||
let path = state.directories.caches_dir().await.join(PROCESSOR_FILE);
|
||||
let mut caches = if let Ok(proc_json) =
|
||||
read_json::<HashMap<Uuid, ProcessorCache>>(&path, &state.io_semaphore).await
|
||||
{
|
||||
|
|
@ -378,8 +375,7 @@ impl Processor {
|
|||
/// restore processes from the cache.
|
||||
pub async fn restore(&mut self) -> crate::Result<()> {
|
||||
let state = crate::State::get().await?;
|
||||
let processor_path = state.directories.caches_dir().await.join(PROCESSOR_JSON);
|
||||
|
||||
let processor_path = state.directories.caches_dir().await.join(PROCESSOR_FILE);
|
||||
let mut processor_caches = if let Ok(processes_json) =
|
||||
read_json::<HashMap<uuid::Uuid, ProcessorCache>>(&processor_path, &state.io_semaphore)
|
||||
.await
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
//! Handles user-inputted settings and global values
|
||||
|
||||
use super::{Directories, JavaVersions};
|
||||
use crate::constants::CURRENT_SETTINGS_FORMAT_VERSION;
|
||||
use crate::utils::io;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
/// The current [`Settings`] format version, changed for breaking changes.
|
||||
/// If updated, a config file migration logic **NEEDS** to be implemented.
|
||||
const CURRENT_FORMAT_VERSION: u32 = 1;
|
||||
|
||||
/// A global settings state for the launcher.
|
||||
#[cfg_attr(feature = "tauri", derive(specta::Type))]
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
|
|
@ -106,7 +103,7 @@ impl Settings {
|
|||
custom_java_args: Vec::new(),
|
||||
max_async_fetches: 10,
|
||||
max_async_io_operations: 10,
|
||||
version: CURRENT_FORMAT_VERSION,
|
||||
version: CURRENT_SETTINGS_FORMAT_VERSION,
|
||||
disable_analytics: false,
|
||||
disable_discord: false,
|
||||
debug_mode: false,
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ use tokio::fs::File;
|
|||
use tokio::io::AsyncWriteExt;
|
||||
use tokio::sync::{RwLock, Semaphore};
|
||||
|
||||
use crate::constants::FETCH_ATTEMPTS;
|
||||
use crate::proxy::send::send_ingress;
|
||||
use crate::proxy::IngressId;
|
||||
use crate::utils::io;
|
||||
|
|
@ -31,8 +32,9 @@ lazy_static::lazy_static! {
|
|||
pub static ref REQWEST_CLIENT: reqwest::Client = {
|
||||
let mut headers = reqwest::header::HeaderMap::new();
|
||||
let header = reqwest::header::HeaderValue::from_str(&format!(
|
||||
"onelauncher/{} (polyfrost.org)",
|
||||
env!("CARGO_PKG_VERSION")
|
||||
"{}/{} (https://polyfrost.org)",
|
||||
crate::constants::NAME,
|
||||
crate::constants::VERSION,
|
||||
)).unwrap();
|
||||
headers.insert(reqwest::header::USER_AGENT, header);
|
||||
reqwest::Client::builder()
|
||||
|
|
@ -43,9 +45,6 @@ lazy_static::lazy_static! {
|
|||
};
|
||||
}
|
||||
|
||||
/// The amount of attempts to fetch a file before the request fails.
|
||||
const FETCH_ATTEMPTS: usize = 3;
|
||||
|
||||
/// Basic HTTP fetch interface.
|
||||
#[tracing::instrument(skip(semaphore))]
|
||||
pub async fn fetch(
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
//! **IO Utilities**
|
||||
//!
|
||||
//! Wrapper around [`tokio::io`] for our error system.
|
||||
//! Async wrapper around [`tokio::fs`] and [`std::io::Error`] for our error system.
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use tempfile::NamedTempFile;
|
||||
use tokio::task::spawn_blocking;
|
||||
|
||||
|
|
@ -184,32 +180,3 @@ pub async fn remove_file(path: impl AsRef<std::path::Path>) -> Result<(), IOErro
|
|||
path: path.to_string_lossy().to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Extract an archive based on its file extension, supporting ZIP files and GZ files.
|
||||
pub fn extract_archive(archive: &PathBuf, dest: &PathBuf) -> crate::Result<()> {
|
||||
let ext = match archive.extension() {
|
||||
Some(ext) => ext.to_str().unwrap(),
|
||||
None => return Err(anyhow!("unsupported operating system").into()),
|
||||
};
|
||||
|
||||
match ext {
|
||||
"zip" => Ok(extract_zip(archive, dest)?),
|
||||
"gz" => Ok(extract_tar_gz(archive, dest)?),
|
||||
_ => Err(anyhow!("unsupported file extension {:?}", ext).into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extract_zip(archive: &PathBuf, dest: &PathBuf) -> Result<(), IOError> {
|
||||
let file = File::open(archive).map_err(|err| IOError::with_path(err, archive.as_path()))?;
|
||||
let archive = zip::ZipArchive::new(file).map_err(IOError::from_zip);
|
||||
archive?.extract(dest).map_err(IOError::from_zip)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn extract_tar_gz(archive: &PathBuf, dest: &PathBuf) -> Result<(), IOError> {
|
||||
let file = File::open(archive).map_err(IOError::from)?;
|
||||
let tar_gz = flate2::read::GzDecoder::new(file);
|
||||
let mut archive = tar::Archive::new(tar_gz);
|
||||
archive.unpack(dest).map_err(IOError::from)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
//!
|
||||
//! Async utilities for managing and downloading Java versions.
|
||||
|
||||
use crate::constants::JAVA_BIN;
|
||||
use crate::State;
|
||||
use futures::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
|
@ -19,10 +20,12 @@ use winreg::{
|
|||
|
||||
use super::io;
|
||||
|
||||
/// A struct representing a single version of the Java Runtime Environment
|
||||
/// Use [`locate_java`] to get an array of all located java instances on the machine
|
||||
/// paths from https://github.com/PrismLauncher/PrismLauncher/blob/develop/launcher/java/JavaUtils.cpp under GPL 3.0
|
||||
/// paths and java_check from https://github.com/modrinth/theseus/blob/master/theseus/src/util/jre.rs under MIT
|
||||
/// A struct representing a single version of the Java Runtime Environment.
|
||||
/// Use [`locate_java`] to get an array of all located java instances on the machine.
|
||||
///
|
||||
/// common java paths from https://github.com/PrismLauncher/PrismLauncher/blob/develop/launcher/java/JavaUtils.cpp under GPL 3.0
|
||||
///
|
||||
/// java check functionality from https://github.com/modrinth/theseus/blob/master/theseus/src/util/jre.rs under MIT
|
||||
#[cfg_attr(feature = "tauri", derive(specta::Type))]
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Clone)]
|
||||
pub struct JavaVersion {
|
||||
|
|
@ -31,7 +34,8 @@ pub struct JavaVersion {
|
|||
pub path: String,
|
||||
}
|
||||
|
||||
/// JVM Entrypoint (WINDOWS ONLY)
|
||||
/// Java entrypoint: Returns all possibly existing java paths on a Linux machine and validates them,
|
||||
/// returning a [`Vec<JavaVersion>`] with all valid java installations, their paths, and associated metadata.
|
||||
#[cfg(target_os = "windows")]
|
||||
#[tracing::instrument]
|
||||
pub async fn locate_java() -> Result<Vec<JavaVersion>, JavaError> {
|
||||
|
|
@ -42,7 +46,6 @@ pub async fn locate_java() -> Result<Vec<JavaVersion>, JavaError> {
|
|||
paths.insert(PathBuf::from(java_home));
|
||||
}
|
||||
|
||||
// i hate windows.com
|
||||
let common_java_paths = [
|
||||
r"C:/Program Files/Java",
|
||||
r"C:\Program Files\Eclipse Adoptium",
|
||||
|
|
@ -76,7 +79,7 @@ pub async fn locate_java() -> Result<Vec<JavaVersion>, JavaError> {
|
|||
r"SOFTWARE\\BellSoft\\Liberica",
|
||||
];
|
||||
|
||||
for key in key_paths {
|
||||
for key in common_key_paths {
|
||||
if let Ok(java_key) = RegKey::predef(HKEY_LOCAL_MACHINE)
|
||||
.open_subkey_with_flags(key, KEY_READ | KEY_WOW64_32KEY)
|
||||
{
|
||||
|
|
@ -91,9 +94,10 @@ pub async fn locate_java() -> Result<Vec<JavaVersion>, JavaError> {
|
|||
|
||||
let java = check_java(paths).await.into_iter().collect();
|
||||
|
||||
Ok(java);
|
||||
Ok(java)
|
||||
}
|
||||
|
||||
/// Locates possibly existing java paths on Windows from Registry keys, returning as a [`HashSet<PathBuf>`]
|
||||
#[cfg(target_os = "windows")]
|
||||
#[tracing::instrument]
|
||||
pub fn get_java_paths_from_windows(java_key: RegKey) -> HashSet<PathBuf> {
|
||||
|
|
@ -113,7 +117,8 @@ pub fn get_java_paths_from_windows(java_key: RegKey) -> HashSet<PathBuf> {
|
|||
paths
|
||||
}
|
||||
|
||||
/// JVM Entrypoint (MacOS ONLY)
|
||||
/// Java entrypoint: Returns all possibly existing java paths on a macOS machine and validates them,
|
||||
/// returning a [`Vec<JavaVersion>`] with all valid java installations, their paths, and associated metadata.
|
||||
#[cfg(target_os = "macos")]
|
||||
#[tracing::instrument]
|
||||
pub async fn locate_java() -> Result<Vec<JavaVersion>, JavaError> {
|
||||
|
|
@ -144,7 +149,8 @@ pub async fn locate_java() -> Result<Vec<JavaVersion>, JavaError> {
|
|||
Ok(java)
|
||||
}
|
||||
|
||||
/// JVM Entrypoint (LINUX ONLY)
|
||||
/// Java entrypoint: Returns all possibly existing java paths on a Linux machine and validates them,
|
||||
/// returning a [`Vec<JavaVersion>`] with all valid java installations, their paths, and associated metadata.
|
||||
#[cfg(target_os = "linux")]
|
||||
#[tracing::instrument]
|
||||
pub async fn locate_java() -> Result<Vec<JavaVersion>, JavaError> {
|
||||
|
|
@ -181,7 +187,7 @@ pub async fn locate_java() -> Result<Vec<JavaVersion>, JavaError> {
|
|||
Ok(java)
|
||||
}
|
||||
|
||||
/// Locate JRE's auto-installed by the launcher instance.
|
||||
/// Locate Java paths automatically added by the launcher instance.
|
||||
#[tracing::instrument]
|
||||
#[onelauncher_macros::memory]
|
||||
async fn locate_installed_java() -> Result<HashSet<PathBuf>, JavaError> {
|
||||
|
|
@ -213,20 +219,16 @@ async fn locate_installed_java() -> Result<HashSet<PathBuf>, JavaError> {
|
|||
.await
|
||||
}
|
||||
|
||||
/// Locate all installed Java instances from the PATH env variable cross-device.
|
||||
/// Locates all installed Java instances from the `PATH` env variable, returning a
|
||||
/// [`HashSet<PathBuf>`] containing all paths in the `PATH` variable to be sorted into java versions.
|
||||
#[tracing::instrument]
|
||||
async fn locate_java_path() -> HashSet<PathBuf> {
|
||||
let paths = env::var("PATH").map(|p| env::split_paths(&p).collect::<HashSet<_>>());
|
||||
paths.unwrap_or_else(|_| HashSet::new())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub const JAVA_BIN: &str = "javaw.exe";
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub const JAVA_BIN: &str = "java";
|
||||
|
||||
/// Verifies that each Java instance is valid from a HashSet of PathBufs
|
||||
/// Verifies that each Java instance is valid from a [`HashSet<PathBuf>`], returning a
|
||||
/// [`HashSet<JavaVersion>`] for each validated path containing the installation's metadata.
|
||||
#[tracing::instrument]
|
||||
pub async fn check_java(paths: HashSet<PathBuf>) -> HashSet<JavaVersion> {
|
||||
let java_instances = stream::iter(paths.into_iter())
|
||||
|
|
@ -242,7 +244,8 @@ pub async fn check_java(paths: HashSet<PathBuf>) -> HashSet<JavaVersion> {
|
|||
.collect()
|
||||
}
|
||||
|
||||
/// Verifies that a java instance [`Path`] is valid.
|
||||
/// Verifies that a java instance [`Path`] is valid, returning a [`JavaVersion`] if the java path
|
||||
/// is valid, containing the installation's metadata.
|
||||
/// java_check from https://github.com/modrinth/theseus/blob/master/theseus/library/JavaInfo.class under MIT
|
||||
#[tracing::instrument]
|
||||
#[onelauncher_macros::memory]
|
||||
|
|
@ -311,7 +314,9 @@ pub async fn check_java_instance(path: &Path) -> Option<JavaVersion> {
|
|||
None
|
||||
}
|
||||
|
||||
/// Get a formatted java version.
|
||||
/// Get a formatted java version as `(major: u32, minor: u32)`.
|
||||
///
|
||||
/// This means 1.8 becomes `(1, 8)`, and 21.0.3 becomes `(21, 0)`.
|
||||
pub fn get_java_version(version: &str) -> Result<(u32, u32), JavaError> {
|
||||
let mut split = version.split('.');
|
||||
let major_opt = split.next();
|
||||
|
|
|
|||
|
|
@ -2,12 +2,11 @@
|
|||
pub mod http;
|
||||
pub mod io;
|
||||
pub mod java;
|
||||
pub mod pkg;
|
||||
pub mod platform;
|
||||
pub mod watcher;
|
||||
|
||||
/// mutable reference gets epically owned by free thinking macro!!!! (not clickbait)
|
||||
/// im going insane insane insane insane insane insane
|
||||
/// mutable reference gets epically owned by free thinking macro!!!!! (not clickbait)
|
||||
/// im going insane insane insane insane insane insane insane insane insane
|
||||
macro_rules! ref_owned {
|
||||
($id:ident = $init:expr => $transform:block) => {{
|
||||
let mut it = $init;
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
|
||||
|
|
@ -5,11 +5,13 @@
|
|||
use interpulse::api::minecraft::{Os, OsRule};
|
||||
use regex::Regex;
|
||||
|
||||
// todo: add this to interpulse (maybe, generally we keep it unimplemented but these are pretty basic functions).
|
||||
|
||||
pub trait OsExt {
|
||||
/// Get the OS of the current system
|
||||
/// Get the [`Os`] of the current system
|
||||
fn native() -> Self;
|
||||
|
||||
/// Gets the OS + Arch of the current system
|
||||
/// Get the [`Os`] of the current system along with it's arch from the `java_arch`.
|
||||
fn native_arch(java_arch: &str) -> Self;
|
||||
}
|
||||
|
||||
|
|
@ -50,13 +52,6 @@ impl OsExt for Os {
|
|||
}
|
||||
}
|
||||
|
||||
// Bit width
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub const ARCH_WIDTH: &str = "64";
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub const ARCH_WIDTH: &str = "32";
|
||||
|
||||
// Platform rule handling
|
||||
pub fn os_rule(rule: &OsRule, java_arch: &str, updated: bool) -> bool {
|
||||
let mut rule_match = true;
|
||||
|
|
|
|||
|
|
@ -11,9 +11,6 @@ use futures::{SinkExt, StreamExt};
|
|||
use notify::RecommendedWatcher;
|
||||
use notify_debouncer_mini::{new_debouncer, DebounceEventResult, Debouncer};
|
||||
|
||||
pub const CLUSTERS_PATH: &str = "clusters";
|
||||
pub const CRASH_PATH: &str = "crash-reports";
|
||||
|
||||
pub async fn initialize_watcher() -> crate::Result<Debouncer<RecommendedWatcher>> {
|
||||
let (mut sender, mut rscv) = channel(1);
|
||||
let watcher = new_debouncer(
|
||||
|
|
@ -56,7 +53,9 @@ pub async fn initialize_watcher() -> crate::Result<Debouncer<RecommendedWatcher>
|
|||
formatted.file_name().unwrap_or_default(),
|
||||
));
|
||||
|
||||
if a.path.components().any(|c| c.as_os_str() == CRASH_PATH)
|
||||
if a.path
|
||||
.components()
|
||||
.any(|c| c.as_os_str() == crate::constants::CRASH_PATH)
|
||||
&& a.path.extension().map(|e| e == "txt").unwrap_or(false)
|
||||
{
|
||||
Cluster::handle_crash(cluster_path);
|
||||
|
|
|
|||
920
pnpm-lock.yaml
generated
920
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue