From eebef351adfda14584c06628bf68adbe651baf5d Mon Sep 17 00:00:00 2001 From: alterwain Date: Sun, 23 Mar 2025 18:16:01 +0300 Subject: [PATCH] modified: src/launcher.rs modified: src/main.rs modified: src/minecraft.rs modified: src/util.rs modified: src/www/portable.html deleted: src/www/profile_customization.html --- src/launcher.rs | 30 ++++ src/main.rs | 38 ++++- src/minecraft.rs | 20 +++ src/util.rs | 10 ++ src/www/portable.html | 241 ++++++++++++++++++----------- src/www/profile_customization.html | 60 ------- 6 files changed, 241 insertions(+), 158 deletions(-) delete mode 100644 src/www/profile_customization.html diff --git a/src/launcher.rs b/src/launcher.rs index 6dd7c1b..9b60373 100644 --- a/src/launcher.rs +++ b/src/launcher.rs @@ -152,6 +152,36 @@ impl Launcher { } } + pub async fn login_user_server(&mut self, server: String, username: String, password: String) -> (bool, &str) { + let mut session_server_port: u16 = 8999; + let mut server_port: u16 = 25565; + let mut domain = server.clone(); + if let Some(index) = server.find("#") { + let (a,b) = server.split_at(index+1); + session_server_port = b.parse().unwrap(); + domain = a[..a.len()-1].to_string(); + } + + if let Some(index) = domain.find(":") { + let dmc = domain.clone(); + let (a,b) = dmc.split_at(index+1); + domain = a[..a.len()-1].to_string(); + server_port = b.parse().unwrap(); + } + + println!("Server information: {}:{} session={}", domain, server_port, session_server_port); + + match minecraft::session::try_login(domain.clone(), session_server_port, username.clone(), password.clone(), self.config.allow_http).await { + Ok(status) => match status { + SignUpResponse::ServerError => (false, "Internal server error"), + SignUpResponse::BadCredentials => (false, "Username or password is not valid"), + SignUpResponse::UserAlreadyExists => (false, "User already exists"), + SignUpResponse::Registered(uuid) => self.save_server_info(uuid, username, password, domain, session_server_port, server_port) + } + Err(_e) => (false, "Internal server error") + } + } + pub async fn get_servers_list(&self) -> Vec<(String, String, Option)> { let mut v = Vec::new(); let servers = self.config.servers(); diff --git a/src/main.rs b/src/main.rs index dd0cf3e..b1105e1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -159,16 +159,41 @@ async fn main() { responder.respond(Response::new(serde_json::to_vec(&UIMessage { params: v }).unwrap())); } + "get_skin" => { + let params = params.unwrap().params; + let nickname = params[0].clone(); + let domain = params[1].clone(); + if let Some(server) = launcher.find_credentials(&nickname, &domain) { + let resp = util::get_image(&["http", if launcher.config.allow_http { "" } else { "s" }, "://", &domain, ":", &server.session_server_port.to_string(), "/api/skin/s", &server.credentials.uuid].concat()).await; + if let Ok(resp) = resp { + responder.respond(Response::new(serde_json::to_vec(&UIMessage { params: vec!["get_skin".to_string(), resp] }).unwrap())); + } + } + } + "get_cape" => { + let params = params.unwrap().params; + let nickname = params[0].clone(); + let domain = params[1].clone(); + if let Some(server) = launcher.find_credentials(&nickname, &domain) { + let resp = util::get_image(&["http", if launcher.config.allow_http { "" } else { "s" }, "://", &domain, ":", &server.session_server_port.to_string(), "/api/cape/a", &server.credentials.uuid].concat()).await; + if let Ok(resp) = resp { + responder.respond(Response::new(serde_json::to_vec(&UIMessage { params: vec!["get_cape".to_string(), resp] }).unwrap())); + } + } + } "upload_skin" => { let params = params.unwrap().params; if let Some(server) = launcher.find_credentials(¶ms[0], ¶ms[1]) { if let Some(skin_path) = FileDialog::new().add_filter("Images", &["png"]).pick_file() { let msg = launcher.upload_skin(skin_path, &server.credentials.uuid, &server.credentials.password, &[if launcher.config.allow_http {"http"} else {"https"}, "://", &server.domain, ":", &server.session_server_port.to_string(), "/api/upload"].concat()).await; - if let Ok(msg) = msg { - responder.respond(Response::new(serde_json::to_vec(&UIMessage { params: vec!["add_server_response".to_string(), String::new(), msg] }).unwrap())); - } else { - responder.respond(Response::new(serde_json::to_vec(&UIMessage { params: vec!["add_server_response".to_string(), String::new(), "Error uploading new skin".to_string()] }).unwrap())); + match msg { + Ok(msg ) => { + responder.respond(Response::new(serde_json::to_vec(&UIMessage { params: vec!["add_server_response".to_string(), String::new(), msg] }).unwrap())); + }, + Err(_e) => { + responder.respond(Response::new(serde_json::to_vec(&UIMessage { params: vec!["add_server_response".to_string(), String::new(), "Error uploading new skin".to_string()] }).unwrap())); + } } } } @@ -258,6 +283,11 @@ async fn main() { // todo: implement error notifications } } + "add_server_login" => { + let params = ¶ms.unwrap().params; + let (status, msg) = launcher.login_user_server(params[0].clone(), params[1].clone(), params[2].clone()).await; + responder.respond(Response::new(serde_json::to_vec(&UIMessage { params: vec!["add_server_response".to_string(), status.to_string(), msg.to_string()] }).unwrap())); + } "add_server" => { let params = ¶ms.unwrap().params; let (status, msg) = launcher.register_user_server(params[0].clone(), params[1].clone(), params[2].clone()).await; diff --git a/src/minecraft.rs b/src/minecraft.rs index f3d71eb..e49c974 100644 --- a/src/minecraft.rs +++ b/src/minecraft.rs @@ -206,6 +206,26 @@ pub mod session { _ => Ok(SignUpResponse::ServerError) } } + + pub async fn try_login(server_domain: String, port: u16, username: String, password: String, allow_http: bool) -> Result> { + let request = SignUpRequest { username: username.clone(), password }; + let mut r = surf::post([if allow_http { "http://".to_string() } else { "https://".to_string() }, server_domain, ":".to_string(), port.to_string(), "/api/login".to_string()].concat()) + .body_json(&request) + .unwrap() + .await?; + + let b= r.body_bytes().await.unwrap(); + + match r.status() { + surf::StatusCode::BadRequest => Ok(SignUpResponse::BadCredentials), + surf::StatusCode::Conflict => Ok(SignUpResponse::UserAlreadyExists), + surf::StatusCode::Ok => { + let response: ResponseUUID = serde_json::from_slice(&b).unwrap(); + Ok(SignUpResponse::Registered(response.uuid)) + }, + _ => Ok(SignUpResponse::ServerError) + } + } } pub mod multimc { diff --git a/src/util.rs b/src/util.rs index 3aeaa57..036bdca 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,3 +1,7 @@ +use std::error::Error; + +use base64::prelude::BASE64_STANDARD; +use base64::Engine; use futures::AsyncReadExt; use rand::{distr::Alphanumeric, Rng}; use tokio::{fs::File, io::AsyncWriteExt}; @@ -11,6 +15,12 @@ pub fn random_string(len: usize) -> String { .collect() } +pub async fn get_image(url: &str) -> Result> { + let bytes = surf::get(url).recv_bytes().await?; + let base64_string = BASE64_STANDARD.encode(&bytes); + Ok(format!("data:image/png;base64,{}", base64_string)) +} + pub async fn download_file(url: &str, file_path: &str, sender: UnboundedSender<(usize, String)>, status: &str, join: bool) -> Result<(), Box> { let url = url.to_string(); let file_path = file_path.to_string(); diff --git a/src/www/portable.html b/src/www/portable.html index a16c1e2..5d0084e 100644 --- a/src/www/portable.html +++ b/src/www/portable.html @@ -3,6 +3,7 @@ + @@ -14,13 +15,13 @@