Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use javaw on Windows and refactor settings #77

Merged
merged 1 commit into from
Aug 21, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions crates/client/src/collections.rs
Original file line number Diff line number Diff line change
@@ -53,9 +53,9 @@ impl<'c> TasksCollection<'c> for AssetsCollection {
}
}

pub struct JavaCollection;
pub struct JavaDownloadingCollection;

impl<'c> TasksCollection<'c> for JavaCollection {
impl<'c> TasksCollection<'c> for JavaDownloadingCollection {
type Context = ();

type Target = ();
@@ -67,7 +67,9 @@ impl<'c> TasksCollection<'c> for JavaCollection {
}

fn handle(_context: Self::Context) -> Handler<'c, Self::Target> {
Handler::new(|()| ())
Handler::new(|()| {
toasts::add(|toasts| toasts.success("Successfully downloaded Java"));
})
}
}

38 changes: 34 additions & 4 deletions crates/client/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
// Remove console window in release builds
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use collections::{AssetsCollection, GameDownloadingCollection, GameRunnerCollection, JavaCollection};
use collections::{AssetsCollection, GameDownloadingCollection, GameRunnerCollection, JavaDownloadingCollection};
use context::MyContext;
use eframe::{
egui::{self, Align, Button, Frame, Id, Layout, RichText, ScrollArea, ViewportBuilder},
epaint::Vec2,
};
use egui_dock::{DockArea, DockState, NodeIndex, Style};
use open_directory::open_directory_native;
use std::path::Path;
use states::download_java_and_update_config;
use std::path::{Path, PathBuf};
use subscriber::EguiLayer;
use ui_ext::UiExt;
use views::{add_tab_menu::AddTab, AddProfileMenu, CreateInstanceMenu, View};
@@ -135,7 +136,7 @@ impl eframe::App for MyTabs {
.add_collection::<collections::GameDeletionCollection>(&self.context.states.instances.instances)
.add_collection::<collections::InstanceDeletionCollection>(&mut self.context.states.instances.instances)
.add_collection::<collections::GameDownloadingCollection>(&self.context.states.instances.instances)
.add_collection::<collections::JavaCollection>(())
.add_collection::<collections::JavaDownloadingCollection>(())
.add_collection::<collections::ProjectCollection>(&mut self.context.states.mod_manager.current_project)
.add_collection::<collections::ProjectVersionsCollection>(&mut self.context.states.mod_manager.current_versions)
.add_collection::<collections::DependenciesCollection>((
@@ -183,6 +184,35 @@ impl eframe::App for MyTabs {
}
});

ui.menu_button("Download", |ui| {
if ui
.add_enabled(
self.context.manager.get_collection::<JavaDownloadingCollection>().tasks().is_empty(),
egui::Button::new("Download Java"),
)
.clicked()
{
download_java_and_update_config(
ui,
&mut self.context.manager,
&mut self.context.states.java,
&mut self.context.states.settings,
);
}
});

ui.menu_button("Utils", |ui| {
let launcher_path = PathBuf::from(DOT_NOMI_LOGS_DIR);

if launcher_path.exists() {
if ui.button("Delete launcher's logs").clicked() {
let _ = std::fs::remove_dir_all(launcher_path);
}
} else {
ui.warn_label("The launcher log's directory is already deleted");
}
});

AddTab {
dock_state: &self.dock_state,
tabs_state: &mut self.context.states.tabs,
@@ -308,7 +338,7 @@ impl eframe::App for MyTabs {

self.context.is_allowed_to_take_action = [
manager.get_collection::<AssetsCollection>(),
manager.get_collection::<JavaCollection>(),
manager.get_collection::<JavaDownloadingCollection>(),
manager.get_collection::<GameDownloadingCollection>(),
manager.get_collection::<GameRunnerCollection>(),
]
13 changes: 10 additions & 3 deletions crates/client/src/states.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
use std::path::PathBuf;

use eframe::egui::Context;
use eframe::egui::{Context, Ui};
use egui_task_manager::{Caller, Task, TaskManager};
use nomi_core::{
downloads::{java::JavaDownloader, progress::MappedSender, traits::Downloader},
fs::read_toml_config_sync,
repository::java_runner::JavaRunner,
DOT_NOMI_JAVA_DIR, DOT_NOMI_JAVA_EXECUTABLE, DOT_NOMI_SETTINGS_CONFIG,
};
use tracing::info;

use crate::{
collections::JavaCollection,
collections::JavaDownloadingCollection,
errors_pool::ErrorPoolExt,
views::{
add_tab_menu::TabsState,
@@ -92,6 +93,12 @@ impl JavaState {
});

let task = Task::new("Java downloading", caller);
manager.push_task::<JavaCollection>(task);
manager.push_task::<JavaDownloadingCollection>(task);
}
}

pub fn download_java_and_update_config(ui: &mut Ui, manager: &mut TaskManager, java_state: &mut JavaState, settings_state: &mut SettingsState) {
java_state.download_java(manager, ui.ctx().clone());
settings_state.java = JavaRunner::path(PathBuf::from(DOT_NOMI_JAVA_EXECUTABLE));
settings_state.update_config();
}
52 changes: 13 additions & 39 deletions crates/client/src/views/settings.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
use std::path::PathBuf;
use std::{path::PathBuf, sync::LazyLock};

use eframe::egui::{self};
use egui_file_dialog::FileDialog;
use egui_form::{garde::field_path, Form, FormField};
use egui_task_manager::TaskManager;
use garde::{Error, Validate};
use nomi_core::{
fs::write_toml_config_sync, regex::Regex, repository::java_runner::JavaRunner, Uuid, DOT_NOMI_JAVA_EXECUTABLE, DOT_NOMI_LOGS_DIR,
DOT_NOMI_SETTINGS_CONFIG,
};
use nomi_core::{fs::write_toml_config_sync, regex::Regex, repository::java_runner::JavaRunner, Uuid, DOT_NOMI_SETTINGS_CONFIG};
use serde::{Deserialize, Serialize};

use crate::{collections::JavaCollection, errors_pool::ErrorPoolExt, states::JavaState, ui_ext::UiExt};
use crate::{
collections::JavaDownloadingCollection,
errors_pool::ErrorPoolExt,
states::{download_java_and_update_config, JavaState},
};

use super::View;

@@ -66,10 +67,9 @@ impl Default for ClientSettingsState {
}

fn check_username(value: &str, _context: &()) -> garde::Result {
let regex =
Regex::new(r"^[a-zA-Z0-9_]{3,16}$").map_err(|_| Error::new("Cannot create regex (this is a bug, please create an issue on the github)"))?;
static REGEX: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"^[a-zA-Z0-9_]{3,16}$").unwrap());

regex.captures(value).map_or_else(
REGEX.captures(value).map_or_else(
|| {
Err(Error::new(
"
@@ -85,36 +85,12 @@ A-Z characters, a-z characters, 0-9 numbers, `_` (underscore) symbol
}

fn check_uuid(value: &str, _context: &()) -> garde::Result {
let regex = Regex::new(r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$")
.map_err(|_| Error::new("Cannot create regex (this is a bug, please create an issue on the github)"))?;

regex.captures(value).map_or_else(|| Err(Error::new("Invalid UUID")), |_| Ok(()))
static REGEX: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$").unwrap());
REGEX.captures(value).map_or_else(|| Err(Error::new("Invalid UUID")), |_| Ok(()))
}

impl View for SettingsPage<'_> {
fn ui(self, ui: &mut eframe::egui::Ui) {
ui.heading("Utils");

let launcher_path = PathBuf::from(DOT_NOMI_LOGS_DIR);

if launcher_path.exists() {
if ui.button("Delete launcher's logs").clicked() {
let _ = std::fs::remove_dir_all(launcher_path);
}
} else {
ui.warn_label("The launcher log's directory is already deleted");
}

let game_path = PathBuf::from("./logs");

if game_path.exists() {
if ui.button("Delete game's logs").clicked() {
let _ = std::fs::remove_dir_all(game_path);
}
} else {
ui.warn_label("The games log's directory is already deleted");
}

let settings_data = self.settings_state.clone();

let mut form = Form::new().add_report(egui_form::garde::GardeReport::new(settings_data.validate(&())));
@@ -142,15 +118,13 @@ impl View for SettingsPage<'_> {

if ui
.add_enabled(
self.manager.get_collection::<JavaCollection>().tasks().is_empty(),
self.manager.get_collection::<JavaDownloadingCollection>().tasks().is_empty(),
egui::Button::new("Download Java"),
)
.on_hover_text("Pressing this button will start the Java downloading process and add the downloaded binary as the selected one")
.clicked()
{
self.java_state.download_java(self.manager, ui.ctx().clone());
self.settings_state.java = JavaRunner::path(PathBuf::from(DOT_NOMI_JAVA_EXECUTABLE));
self.settings_state.update_config();
download_java_and_update_config(ui, self.manager, self.java_state, self.settings_state);
}

FormField::new(&mut form, field_path!("java")).label("Java").ui(ui, |ui: &mut egui::Ui| {
3 changes: 3 additions & 0 deletions crates/nomi-core/src/consts.rs
Original file line number Diff line number Diff line change
@@ -4,7 +4,10 @@ pub const DOT_NOMI_CONFIGS_DIR: &str = "./.nomi/configs";
pub const DOT_NOMI_SETTINGS_CONFIG: &str = "./.nomi/configs/Settings.toml";
pub const DOT_NOMI_LOGS_DIR: &str = "./.nomi/logs";
pub const DOT_NOMI_JAVA_DIR: &str = "./.nomi/java";
#[cfg(not(windows))]
pub const DOT_NOMI_JAVA_EXECUTABLE: &str = "./.nomi/java/jdk-22.0.1/bin/java";
#[cfg(windows)]
pub const DOT_NOMI_JAVA_EXECUTABLE: &str = "./.nomi/java/jdk-22.0.1/bin/javaw.exe";
pub const DOT_NOMI_DATA_PACKS_DIR: &str = "./.nomi/datapacks";

pub const LIBRARIES_DIR: &str = "./libraries";
3 changes: 2 additions & 1 deletion crates/nomi-core/src/repository/java_runner.rs
Original file line number Diff line number Diff line change
@@ -14,7 +14,8 @@ pub enum JavaRunner {
impl JavaRunner {
pub fn from_environment() -> Self {
if std::env::var("PATH").is_ok_and(|path| path.contains("java")) {
Self::command("java")
let command = if cfg!(windows) { "javaw" } else { "java" };
Self::command(command)
} else {
Self::path(DOT_NOMI_JAVA_EXECUTABLE.into())
}
7 changes: 5 additions & 2 deletions crates/nomi-core/src/repository/username.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::sync::LazyLock;

use regex::Regex;
use serde::{de::Visitor, Deserialize, Serialize};
use thiserror::Error;
@@ -62,9 +64,10 @@ pub enum ValidationError {

impl Username {
pub fn new(s: impl Into<String>) -> anyhow::Result<Self> {
static REGEX: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"^[a-zA-Z0-9_]{3,16}$").unwrap());

let s = s.into();
let re = Regex::new(r"^[a-zA-Z0-9_]{3,16}$")?;
match re.captures(&s) {
match REGEX.captures(&s) {
Some(_) => Ok(Username(s)),
None => Err(ValidationError::InvalidUsername.into()),
}