Skip to content

Commit

Permalink
Add much more logging, safer mmc + metadata handling, "fix" instance …
Browse files Browse the repository at this point in the history
…page
  • Loading branch information
DerCommander323 committed Jan 10, 2024
1 parent e9932cb commit eebb812
Show file tree
Hide file tree
Showing 16 changed files with 211 additions and 135 deletions.
45 changes: 30 additions & 15 deletions src-tauri/src/configuration/settings.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::fs;

use log::warn;
use serde::{Deserialize, Serialize};

use crate::{minecraft::java::JavaDetails, get_config_dir};
Expand Down Expand Up @@ -28,31 +29,45 @@ pub fn update_settings(new_settings: AppSettings) {

impl AppSettings {
pub fn get() -> Self {
let defaults = AppSettings {
instance_size: 16,
instance_path: None,
icon_path: None,
java_settings: Vec::new(),
};

let path = get_config_dir().join(SETTINGS_FILE_NAME);

if !path.is_file() {
if let Some(parent) = path.parent() {
if !parent.exists() {
fs::create_dir_all(parent).expect("Failed to create config directory!");
}
}
fs::write(path, serde_json::to_string_pretty(&defaults).unwrap()).expect("Failed to write to settings file!");
return defaults
Self::generate();
}

let file = fs::read_to_string(path).expect("Failed to read settings file!");
serde_json::from_str(&file).expect("Failed to parse settings!")
match serde_json::from_str(&file) {
Ok(settings) => settings,
Err(err) => {
warn!("Failed to parse settings: {err}, resetting them!");
Self::generate()
},
}
}

pub fn set(self) {
let path = get_config_dir().join(SETTINGS_FILE_NAME);

fs::write(path, serde_json::to_string_pretty(&self).unwrap()).expect("Failed to write to settings file!");
}

fn generate() -> Self {
let path = get_config_dir().join(SETTINGS_FILE_NAME);

let defaults = AppSettings {
instance_size: 16,
instance_path: None,
icon_path: None,
java_settings: Vec::new(),
};

if let Some(parent) = path.parent() {
if !parent.exists() {
fs::create_dir_all(parent).expect("Failed to create config directory!");
}
}

fs::write(path, serde_json::to_string_pretty(&defaults).unwrap()).expect("Failed to write to settings file!");
defaults
}
}
66 changes: 46 additions & 20 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use std::{fs::{self, create_dir_all}, path::{Path, PathBuf}, io::Cursor};
use log::debug;
use reqwest::Client;
use serde::Serialize;
use sha1_smol::Sha1;
use simple_logger::SimpleLogger;
use tauri::{AppHandle, Manager, api::path::{data_dir, config_dir}};
Expand Down Expand Up @@ -44,23 +45,10 @@ pub mod configuration {



#[derive(serde::Serialize, Clone)]
struct Notification {
status: NotificationState,
text: String
}
#[derive(serde::Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub enum NotificationState {
Running,
Error,
Success
}


fn main() {
SimpleLogger::new()
.with_level(log::LevelFilter::Debug)
.env()
.init()
.expect("Failed to initialize logger!");

Expand Down Expand Up @@ -93,12 +81,6 @@ fn file_exists(path: String) -> bool {
Path::new(&path).exists()
}

pub fn notify(app_handle: &AppHandle, name: &str, text: &str, status: NotificationState) {
app_handle.emit_all(
&format!("notification_{name}"),
Notification { text: text.to_string(), status }
).unwrap()
}

/// Checks if the checksum of the file at `path` matches `checksum` and downloads it from `url` if not.
pub async fn download_file_checked(client: &Client, checksum: Option<&String>, path: &PathBuf, url: &String) {
Expand Down Expand Up @@ -146,8 +128,52 @@ pub fn maven_identifier_to_path(identifier: &str) -> String {
format!("{path}/{raw_name}/{version_path}/{raw_name}-{version}.{extension}")
}

#[derive(Debug, Clone)]
pub struct Notifier {
notif_id: String,
app_handle: AppHandle
}

#[derive(Debug, Clone, Serialize)]
pub struct Notif {
pub text: String,
pub progress: u32,
pub max_progress: u32,
pub status: NotificationState
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum NotificationState {
Running,
Error,
Success
}

impl Notifier {
pub fn notify_status(&self, contents: Notif) {
self.app_handle.emit_all(&self.notif_id, contents).expect("Failed to emit notification!?")
}

pub fn notify(&self, text: &str, status: NotificationState) {
self.app_handle.emit_all(&self.notif_id, Notif::new(text, 0, 0, status) ).expect("Failed to emit notification!?")
}

pub fn new(notif_id: &str, app_handle: AppHandle) -> Self {
Self { notif_id: notif_id.to_string(), app_handle }
}
}

impl Notif {
pub fn new(text: &str, progress: u32, max_progress: u32, status: NotificationState) -> Self {
Self { text: text.to_string(), progress, max_progress, status}
}
}


pub fn get_classpath_separator() -> String { String::from(if cfg!(windows) { ";" } else { ":" }) }


pub fn get_config_dir() -> PathBuf { config_dir().unwrap().join("yamcl") }
pub fn get_data_dir() -> PathBuf { data_dir().unwrap().join("yamcl") }

Expand Down
44 changes: 22 additions & 22 deletions src-tauri/src/minecraft/authentication/auth.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use afire::{Server, Method, Response, Status};
use chrono::{Utc, Duration};
use log::{info, debug, error};
use log::*;
use reqwest::Client;
use serde_json::json;
use tauri::{AppHandle, async_runtime::block_on};
use crate::{minecraft::authentication::auth_structs::*, notify, NotificationState, configuration::accounts::{save_new_account, update_account}};
use crate::{minecraft::authentication::auth_structs::*, NotificationState, configuration::accounts::{save_new_account, update_account}, Notifier};


const MS_CLIENT_ID: &str = "5431ff2d-20f8-415b-aa2f-5218eba055ea"; // The Yet Another MC Launcher client_id. If you fork this project, please make sure to use your own!
Expand Down Expand Up @@ -57,31 +57,31 @@ pub async fn add_account(app_handle: AppHandle) {
.center()
.focused(true)
.build()
.unwrap();
.expect("Failed to create login window!");

notify(&app_handle, "login_status", "Awaiting login", NotificationState::Running);
let notifier = Notifier::new("login_status", app_handle);

std::thread::spawn(move || {
let app_handle_clone = app_handle.clone();
notifier.notify("Awaiting login", NotificationState::Running);
tokio::task::spawn_blocking(move || {
let notifier_clone = notifier.clone();
login_window.on_window_event(move |event| {
if let tauri::WindowEvent::Destroyed = event {
notify(&app_handle_clone, "login_status", "Login aborted!", NotificationState::Error);
notifier_clone.notify("Login aborted!", NotificationState::Error);
}
});

let app_handle_clone = app_handle.clone();
redirect_server.route(Method::GET, "/", move |req| {
if let Some(code) = req.query.get("code") {
info!("Code obtained!");
notify(&app_handle, "login_status", "Beginning login process...", NotificationState::Running);
notifier.notify("Beginning login process...", NotificationState::Running);
login_window.close().unwrap();
block_on(add_account_code(code, &app_handle_clone));
block_on(add_account_code(code, &notifier));
Response::new()
.text("You may close this window now.")
.status(Status::Ok)
} else {
error!("Getting Code failed!");
notify(&app_handle_clone, "login_status", "Failed getting code from response!", NotificationState::Error);
notifier.notify("Failed getting code from response!", NotificationState::Error);
Response::new()
.text("Failed to get the authentication code!")
.status(Status::NotFound)
Expand All @@ -92,42 +92,42 @@ pub async fn add_account(app_handle: AppHandle) {
if let Err(e) = redirect_server.start() {
error!("Starting redirect server failed: {e}")
};
});
}).await.unwrap();
}

async fn add_account_code(code: &str, app_handle: &AppHandle) {
async fn add_account_code(code: &str, notifier: &Notifier) {
info!("Started adding new Minecraft account!");
let client = Client::new();

info!("Getting Microsoft Auth response...");
notify(app_handle, "login_status", "Getting Microsoft Auth reponse...", NotificationState::Running);
notifier.notify("Getting Microsoft Auth reponse...", NotificationState::Running);
let msa_response = MSAResponse2::from_code(code, &client).await;
// trace!("{:#?}", msa_response);

info!("Getting Xbox Live Auth response...");
notify(app_handle, "login_status", "Getting Xbox Live Auth reponse...", NotificationState::Running);
notifier.notify("Getting Xbox Live Auth reponse...", NotificationState::Running);
let xbl_response = msa_response.get_xbl_reponse(&client).await;
// trace!("{:#?}", xbl_response);

info!("Getting Xsts Auth response...");
notify(app_handle, "login_status", "Getting Xsts Auth reponse...", NotificationState::Running);
notifier.notify("Getting Xsts Auth reponse...", NotificationState::Running);
let xsts_response = xbl_response.xbl_to_xsts_response(&client).await;
// trace!("{:#?}", xsts_response);

info!("Getting Minecraft Auth response...");
notify(app_handle, "login_status", "Getting Minecraft Auth reponse...", NotificationState::Running);
notifier.notify("Getting Minecraft Auth reponse...", NotificationState::Running);
let mc_response = xsts_response.xsts_to_mc_response(&client).await;
// trace!("{:#?}", mc_response);

info!("Checking Minecraft ownership...");
notify(app_handle, "login_status", "Checking Minecraft ownership...", NotificationState::Running);
notifier.notify("Checking Minecraft ownership...", NotificationState::Running);
if !mc_response.has_mc_ownership(&client).await {
notify(&app_handle, "login_status", "Account does not own Minecraft!", NotificationState::Error);
notifier.notify("Account does not own Minecraft!", NotificationState::Error);
return;
}

info!("Getting Minecraft account...");
notify(app_handle, "login_status", "Getting Minecraft account...", NotificationState::Running);
notifier.notify("Getting Minecraft account...", NotificationState::Running);
let mc_profile = mc_response.get_mc_profile(&client).await;
// trace!("{:#?}", mc_profile);

Expand All @@ -142,12 +142,12 @@ async fn add_account_code(code: &str, app_handle: &AppHandle) {

// trace!("{:#?}", mc_account);
info!("Saving new Minecraft account...");
notify(app_handle, "login_status", "Saving new account...", NotificationState::Running);
notifier.notify("Saving new account...", NotificationState::Running);
if let Err(e) = save_new_account(mc_account) {
error!("Error occured while saving new account: {e}")
}

notify(app_handle, "login_status", &String::from_iter(["Successfully added account \"", &username, "\"!"]), NotificationState::Success);
notifier.notify(&String::from_iter(["Successfully added account \"", &username, "\"!"]), NotificationState::Success);
info!("Successfully added new account.");
}

Expand Down
Loading

0 comments on commit eebb812

Please sign in to comment.