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
Show file tree
Hide file tree
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
Expand Up @@ -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 = ();
Expand All @@ -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"));
})
}
}

Expand Down
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};
Expand Down Expand Up @@ -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>((
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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>(),
]
Expand Down
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,
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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(
"
Expand All @@ -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(&())));
Expand Down Expand Up @@ -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| {
Expand Down
3 changes: 3 additions & 0 deletions crates/nomi-core/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
3 changes: 2 additions & 1 deletion crates/nomi-core/src/repository/java_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
Expand Down
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;
Expand Down Expand Up @@ -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()),
}
Expand Down
Loading