mirror of
https://github.com/Grasscutters/Cultivation.git
synced 2025-12-12 15:14:35 +01:00
Refactor spacing
This commit is contained in:
@@ -8,7 +8,7 @@ use std::io::Write;
|
||||
use futures_util::StreamExt;
|
||||
|
||||
// This will create a downloads list that will be used to check if we should continue downloading the file
|
||||
lazy_static!{
|
||||
lazy_static! {
|
||||
static ref DOWNLOADS: Mutex<Vec<String>> = {
|
||||
let m = Vec::new();
|
||||
Mutex::new(m)
|
||||
@@ -19,121 +19,121 @@ lazy_static!{
|
||||
// and docs ofc
|
||||
#[tauri::command]
|
||||
pub async fn download_file(window: tauri::Window, url: &str, path: &str) -> Result<(), String> {
|
||||
// Reqwest setup
|
||||
let res = match reqwest::get(url)
|
||||
.await {
|
||||
Ok(r) => r,
|
||||
Err(_e) => {
|
||||
emit_download_err(window, format!("Failed to request {}", url), path);
|
||||
return Err(format!("Failed to request {}", url));
|
||||
},
|
||||
};
|
||||
let total_size = res
|
||||
.content_length()
|
||||
.unwrap_or(0);
|
||||
// Reqwest setup
|
||||
let res = match reqwest::get(url)
|
||||
.await {
|
||||
Ok(r) => r,
|
||||
Err(_e) => {
|
||||
emit_download_err(window, format!("Failed to request {}", url), path);
|
||||
return Err(format!("Failed to request {}", url));
|
||||
}
|
||||
};
|
||||
let total_size = res
|
||||
.content_length()
|
||||
.unwrap_or(0);
|
||||
|
||||
// Create file path
|
||||
let mut file = match File::create(path) {
|
||||
Ok(f) => f,
|
||||
Err(_e) => {
|
||||
emit_download_err(window, format!("Failed to create file '{}'", path), path);
|
||||
return Err(format!("Failed to create file '{}'", path));
|
||||
},
|
||||
};
|
||||
let mut downloaded: u64 = 0;
|
||||
// Create file path
|
||||
let mut file = match File::create(path) {
|
||||
Ok(f) => f,
|
||||
Err(_e) => {
|
||||
emit_download_err(window, format!("Failed to create file '{}'", path), path);
|
||||
return Err(format!("Failed to create file '{}'", path));
|
||||
}
|
||||
};
|
||||
let mut downloaded: u64 = 0;
|
||||
|
||||
// File stream
|
||||
let mut stream = res.bytes_stream();
|
||||
// File stream
|
||||
let mut stream = res.bytes_stream();
|
||||
|
||||
// Assuming all goes well, add to the downloads list
|
||||
DOWNLOADS.lock().unwrap().push(path.to_string());
|
||||
// Assuming all goes well, add to the downloads list
|
||||
DOWNLOADS.lock().unwrap().push(path.to_string());
|
||||
|
||||
// Await chunks
|
||||
while let Some(item) = stream.next().await {
|
||||
// Stop the loop if the download is removed from the list
|
||||
if !DOWNLOADS.lock().unwrap().contains(&path.to_string()) {
|
||||
break;
|
||||
}
|
||||
|
||||
let chunk = match item {
|
||||
Ok(itm) => itm,
|
||||
Err(e) => {
|
||||
emit_download_err(window, format!("Error while downloading file"), path);
|
||||
return Err(format!("Error while downloading file: {}", e));
|
||||
},
|
||||
};
|
||||
let vect = &chunk.to_vec()[..];
|
||||
|
||||
// Write bytes
|
||||
match file.write_all(&vect) {
|
||||
Ok(x) => x,
|
||||
Err(e) => {
|
||||
emit_download_err(window, format!("Error while writing file"), path);
|
||||
return Err(format!("Error while writing file: {}", e));
|
||||
},
|
||||
}
|
||||
|
||||
// New progress
|
||||
let new = min(downloaded + (chunk.len() as u64), total_size);
|
||||
downloaded = new;
|
||||
|
||||
let mut res_hash = std::collections::HashMap::new();
|
||||
|
||||
res_hash.insert(
|
||||
"downloaded".to_string(),
|
||||
downloaded.to_string()
|
||||
);
|
||||
|
||||
res_hash.insert(
|
||||
"total".to_string(),
|
||||
total_size.to_string()
|
||||
);
|
||||
|
||||
res_hash.insert(
|
||||
"path".to_string(),
|
||||
path.to_string()
|
||||
);
|
||||
|
||||
// Create event to send to frontend
|
||||
window.emit("download_progress", &res_hash).unwrap();
|
||||
// Await chunks
|
||||
while let Some(item) = stream.next().await {
|
||||
// Stop the loop if the download is removed from the list
|
||||
if !DOWNLOADS.lock().unwrap().contains(&path.to_string()) {
|
||||
break;
|
||||
}
|
||||
|
||||
// One more "finish" event
|
||||
window.emit("download_finished", &path).unwrap();
|
||||
let chunk = match item {
|
||||
Ok(itm) => itm,
|
||||
Err(e) => {
|
||||
emit_download_err(window, format!("Error while downloading file"), path);
|
||||
return Err(format!("Error while downloading file: {}", e));
|
||||
}
|
||||
};
|
||||
let vect = &chunk.to_vec()[..];
|
||||
|
||||
// We are done
|
||||
return Ok(());
|
||||
}
|
||||
// Write bytes
|
||||
match file.write_all(&vect) {
|
||||
Ok(x) => x,
|
||||
Err(e) => {
|
||||
emit_download_err(window, format!("Error while writing file"), path);
|
||||
return Err(format!("Error while writing file: {}", e));
|
||||
}
|
||||
}
|
||||
|
||||
// New progress
|
||||
let new = min(downloaded + (chunk.len() as u64), total_size);
|
||||
downloaded = new;
|
||||
|
||||
pub fn emit_download_err(window: tauri::Window, msg: std::string::String, path: &str) {
|
||||
let mut res_hash = std::collections::HashMap::new();
|
||||
|
||||
res_hash.insert(
|
||||
"error".to_string(),
|
||||
msg.to_string()
|
||||
"downloaded".to_string(),
|
||||
downloaded.to_string(),
|
||||
);
|
||||
|
||||
res_hash.insert(
|
||||
"path".to_string(),
|
||||
path.to_string()
|
||||
"total".to_string(),
|
||||
total_size.to_string(),
|
||||
);
|
||||
|
||||
window.emit("download_error", &res_hash).unwrap();
|
||||
res_hash.insert(
|
||||
"path".to_string(),
|
||||
path.to_string(),
|
||||
);
|
||||
|
||||
// Create event to send to frontend
|
||||
window.emit("download_progress", &res_hash).unwrap();
|
||||
}
|
||||
|
||||
// One more "finish" event
|
||||
window.emit("download_finished", &path).unwrap();
|
||||
|
||||
// We are done
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
pub fn emit_download_err(window: tauri::Window, msg: std::string::String, path: &str) {
|
||||
let mut res_hash = std::collections::HashMap::new();
|
||||
|
||||
res_hash.insert(
|
||||
"error".to_string(),
|
||||
msg.to_string(),
|
||||
);
|
||||
|
||||
res_hash.insert(
|
||||
"path".to_string(),
|
||||
path.to_string(),
|
||||
);
|
||||
|
||||
window.emit("download_error", &res_hash).unwrap();
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn stop_download(path: String) {
|
||||
// Check if the path is in the downloads list
|
||||
let mut downloads = DOWNLOADS.lock().unwrap();
|
||||
let index = downloads.iter().position(|x| x == &path);
|
||||
// Check if the path is in the downloads list
|
||||
let mut downloads = DOWNLOADS.lock().unwrap();
|
||||
let index = downloads.iter().position(|x| x == &path);
|
||||
|
||||
// Remove from list
|
||||
if let Some(i) = index {
|
||||
downloads.remove(i);
|
||||
}
|
||||
// Remove from list
|
||||
if let Some(i) = index {
|
||||
downloads.remove(i);
|
||||
}
|
||||
|
||||
// Delete the file from disk
|
||||
if let Err(_e) = std::fs::remove_file(&path) {
|
||||
// Do nothing
|
||||
}
|
||||
// Delete the file from disk
|
||||
if let Err(_e) = std::fs::remove_file(&path) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@@ -44,8 +44,8 @@ pub fn emit_lang_err(window: tauri::Window, msg: std::string::String) {
|
||||
let mut res_hash = std::collections::HashMap::new();
|
||||
|
||||
res_hash.insert(
|
||||
"error".to_string(),
|
||||
msg.to_string()
|
||||
"error".to_string(),
|
||||
msg.to_string(),
|
||||
);
|
||||
|
||||
window.emit("lang_error", &res_hash).unwrap();
|
||||
|
||||
@@ -19,7 +19,7 @@ mod lang;
|
||||
mod proxy;
|
||||
mod web;
|
||||
|
||||
lazy_static!{
|
||||
lazy_static! {
|
||||
static ref WATCH_GAME_PROCESS: Mutex<String> = {
|
||||
let m = "".to_string();
|
||||
Mutex::new(m)
|
||||
@@ -48,7 +48,7 @@ fn main() {
|
||||
lang::get_lang,
|
||||
lang::get_languages
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
|
||||
@@ -60,14 +60,14 @@ fn process_watcher() {
|
||||
// Start in thread so as to not block the main thread.
|
||||
thread::spawn(|| {
|
||||
let mut s = System::new_all();
|
||||
|
||||
|
||||
loop {
|
||||
// Refresh system info
|
||||
s.refresh_all();
|
||||
|
||||
|
||||
// Grab the game process name
|
||||
let proc = WATCH_GAME_PROCESS.lock().unwrap().to_string();
|
||||
|
||||
|
||||
if !&proc.is_empty() {
|
||||
let proc_with_name = s.processes_by_exact_name(&proc);
|
||||
let mut exists = false;
|
||||
@@ -133,7 +133,7 @@ async fn get_bg_file(bg_path: String) -> String {
|
||||
return "".to_string();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
let file_name = response_data.backgroundFile.to_string() + ".png";
|
||||
|
||||
// First we see if the file already exists in our local bg folder
|
||||
@@ -141,7 +141,7 @@ async fn get_bg_file(bg_path: String) -> String {
|
||||
let cwd = std::env::current_dir().unwrap();
|
||||
return format!("{}\\{}", cwd.display(), response_data.backgroundFile.as_str());
|
||||
}
|
||||
|
||||
|
||||
// Now we check if the bg folder, which is one directory above the game_path, exists.
|
||||
let bg_img_path = format!("{}\\{}", bg_path.clone().to_string(), file_name.as_str());
|
||||
|
||||
@@ -164,7 +164,7 @@ async fn get_bg_file(bg_path: String) -> String {
|
||||
// Copy was successful, lets return true
|
||||
let cwd = std::env::current_dir().unwrap();
|
||||
return format!("{}\\{}", cwd.display(), response_data.backgroundFile.as_str());
|
||||
},
|
||||
}
|
||||
Err(e) => {
|
||||
// Copy failed, lets return false
|
||||
println!("Failed to copy background image: {}", e);
|
||||
|
||||
@@ -7,10 +7,10 @@ use lazy_static::lazy_static;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use hudsucker::{
|
||||
async_trait::async_trait,
|
||||
certificate_authority::RcgenAuthority,
|
||||
hyper::{Body, Request, Response},
|
||||
*
|
||||
async_trait::async_trait,
|
||||
certificate_authority::RcgenAuthority,
|
||||
hyper::{Body, Request, Response},
|
||||
*,
|
||||
};
|
||||
|
||||
use std::net::SocketAddr;
|
||||
@@ -20,12 +20,12 @@ use rustls_pemfile as pemfile;
|
||||
use tauri::http::Uri;
|
||||
|
||||
async unsafe fn shutdown_signal() {
|
||||
tokio::signal::ctrl_c().await
|
||||
.expect("Failed to install CTRL+C signal handler");
|
||||
tokio::signal::ctrl_c().await
|
||||
.expect("Failed to install CTRL+C signal handler");
|
||||
}
|
||||
|
||||
// Global ver for getting server address
|
||||
lazy_static!{
|
||||
lazy_static! {
|
||||
static ref SERVER: Mutex<String> = {
|
||||
let m = "localhost:443".to_string();
|
||||
Mutex::new(m)
|
||||
@@ -36,110 +36,106 @@ lazy_static!{
|
||||
struct ProxyHandler;
|
||||
|
||||
#[tauri::command]
|
||||
pub fn set_proxy_addr(addr: String){
|
||||
*SERVER.lock().unwrap() = addr;
|
||||
pub fn set_proxy_addr(addr: String) {
|
||||
*SERVER.lock().unwrap() = addr;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl HttpHandler for ProxyHandler {
|
||||
async fn handle_request(&mut self,
|
||||
_context: &HttpContext,
|
||||
mut request: Request<Body>
|
||||
) -> RequestOrResponse {
|
||||
println!("Request: {}", &request.uri());
|
||||
async fn handle_request(&mut self,
|
||||
_context: &HttpContext,
|
||||
mut request: Request<Body>,
|
||||
) -> RequestOrResponse {
|
||||
// Get request URI.
|
||||
let uri = request.uri().to_string();
|
||||
let uri_path = request.uri().path();
|
||||
|
||||
// Get request URI
|
||||
let uri = request.uri().to_string();
|
||||
let uri_path = request.uri().path();
|
||||
|
||||
// Only switch up if request is to the game servers
|
||||
if uri.contains("hoyoverse.com") || uri.contains("mihoyo.com") || uri.contains("yuanshen.com") {
|
||||
// Copy the request and just change the URI
|
||||
let uri = format!("https://{}{}", SERVER.lock().unwrap(), uri_path).parse::<Uri>().unwrap();
|
||||
|
||||
*request.uri_mut() = uri;
|
||||
}
|
||||
|
||||
println!("New request: {}", &request.uri());
|
||||
|
||||
RequestOrResponse::Request(request)
|
||||
// Only switch up if request is to the game servers.
|
||||
if uri.contains("hoyoverse.com") || uri.contains("mihoyo.com") || uri.contains("yuanshen.com") {
|
||||
// Create new URI.
|
||||
let uri = format!("https://{}{}", SERVER.lock().unwrap(), uri_path).parse::<Uri>().unwrap();
|
||||
// Set request URI to the new one.
|
||||
*request.uri_mut() = uri;
|
||||
}
|
||||
|
||||
async fn handle_response(&mut self,
|
||||
_context: &HttpContext,
|
||||
response: Response<Body>
|
||||
) -> Response<Body> { response }
|
||||
|
||||
RequestOrResponse::Request(request)
|
||||
}
|
||||
|
||||
async fn handle_response(&mut self,
|
||||
_context: &HttpContext,
|
||||
response: Response<Body>,
|
||||
) -> Response<Body> { response }
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts an HTTP(S) proxy server.
|
||||
*/
|
||||
pub(crate) async fn create_proxy(proxy_port: u16) {
|
||||
// Get the certificate and private key.
|
||||
let mut private_key_bytes: &[u8] = include_bytes!("../resources/private-key.pem");
|
||||
let mut ca_cert_bytes: &[u8] = include_bytes!("../resources/ca-certificate.pem");
|
||||
|
||||
// Parse the private key and certificate.
|
||||
let private_key = rustls::PrivateKey(
|
||||
pemfile::pkcs8_private_keys(&mut private_key_bytes)
|
||||
.expect("Failed to parse private key")
|
||||
.remove(0),
|
||||
);
|
||||
// Get the certificate and private key.
|
||||
let mut private_key_bytes: &[u8] = include_bytes!("../resources/private-key.pem");
|
||||
let mut ca_cert_bytes: &[u8] = include_bytes!("../resources/ca-certificate.pem");
|
||||
|
||||
let ca_cert = rustls::Certificate(
|
||||
pemfile::certs(&mut ca_cert_bytes)
|
||||
.expect("Failed to parse CA certificate")
|
||||
.remove(0),
|
||||
);
|
||||
|
||||
// Create the certificate authority.
|
||||
let authority = RcgenAuthority::new(private_key, ca_cert, 1_000)
|
||||
.expect("Failed to create Certificate Authority");
|
||||
|
||||
// Create an instance of the proxy.
|
||||
let proxy = ProxyBuilder::new()
|
||||
.with_addr(SocketAddr::from(([0, 0, 0, 0], proxy_port)))
|
||||
.with_rustls_client()
|
||||
.with_ca(authority)
|
||||
.with_http_handler(ProxyHandler)
|
||||
.build();
|
||||
// Parse the private key and certificate.
|
||||
let private_key = rustls::PrivateKey(
|
||||
pemfile::pkcs8_private_keys(&mut private_key_bytes)
|
||||
.expect("Failed to parse private key")
|
||||
.remove(0),
|
||||
);
|
||||
|
||||
// Start the proxy.
|
||||
unsafe {
|
||||
tokio::spawn(proxy.start(shutdown_signal()));
|
||||
}
|
||||
let ca_cert = rustls::Certificate(
|
||||
pemfile::certs(&mut ca_cert_bytes)
|
||||
.expect("Failed to parse CA certificate")
|
||||
.remove(0),
|
||||
);
|
||||
|
||||
// Create the certificate authority.
|
||||
let authority = RcgenAuthority::new(private_key, ca_cert, 1_000)
|
||||
.expect("Failed to create Certificate Authority");
|
||||
|
||||
// Create an instance of the proxy.
|
||||
let proxy = ProxyBuilder::new()
|
||||
.with_addr(SocketAddr::from(([0, 0, 0, 0], proxy_port)))
|
||||
.with_rustls_client()
|
||||
.with_ca(authority)
|
||||
.with_http_handler(ProxyHandler)
|
||||
.build();
|
||||
|
||||
// Start the proxy.
|
||||
unsafe {
|
||||
tokio::spawn(proxy.start(shutdown_signal()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the local HTTP(S) proxy server.
|
||||
*/
|
||||
pub(crate) fn connect_to_proxy(proxy_port: u16) {
|
||||
if cfg!(target_os = "windows") {
|
||||
// Create 'ProxyServer' string.
|
||||
let server_string: String = format!("http=127.0.0.1:{};https=127.0.0.1:{};ftp=127.0.0.1:{}", proxy_port, proxy_port, proxy_port);
|
||||
if cfg!(target_os = "windows") {
|
||||
// Create 'ProxyServer' string.
|
||||
let server_string: String = format!("http=127.0.0.1:{};https=127.0.0.1:{};ftp=127.0.0.1:{}", proxy_port, proxy_port, proxy_port);
|
||||
|
||||
// Fetch the 'Internet Settings' registry key.
|
||||
let settings = Hive::CurrentUser.open(r"Software\Microsoft\Windows\CurrentVersion\Internet Settings", Security::Write).unwrap();
|
||||
|
||||
// Set registry values.
|
||||
settings.set_value("ProxyServer", &Data::String(server_string.parse().unwrap())).unwrap();
|
||||
settings.set_value("ProxyEnable", &Data::U32(1)).unwrap();
|
||||
}
|
||||
// Fetch the 'Internet Settings' registry key.
|
||||
let settings = Hive::CurrentUser.open(r"Software\Microsoft\Windows\CurrentVersion\Internet Settings", Security::Write).unwrap();
|
||||
|
||||
println!("Connected to the proxy.");
|
||||
// Set registry values.
|
||||
settings.set_value("ProxyServer", &Data::String(server_string.parse().unwrap())).unwrap();
|
||||
settings.set_value("ProxyEnable", &Data::U32(1)).unwrap();
|
||||
}
|
||||
|
||||
println!("Connected to the proxy.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects from the local HTTP(S) proxy server.
|
||||
*/
|
||||
pub(crate) fn disconnect_from_proxy() {
|
||||
if cfg!(target_os = "windows") {
|
||||
// Fetch the 'Internet Settings' registry key.
|
||||
let settings = Hive::CurrentUser.open(r"Software\Microsoft\Windows\CurrentVersion\Internet Settings", Security::Write).unwrap();
|
||||
if cfg!(target_os = "windows") {
|
||||
// Fetch the 'Internet Settings' registry key.
|
||||
let settings = Hive::CurrentUser.open(r"Software\Microsoft\Windows\CurrentVersion\Internet Settings", Security::Write).unwrap();
|
||||
|
||||
// Set registry values.
|
||||
settings.set_value("ProxyEnable", &Data::U32(0)).unwrap();
|
||||
}
|
||||
// Set registry values.
|
||||
settings.set_value("ProxyEnable", &Data::U32(0)).unwrap();
|
||||
}
|
||||
|
||||
println!("Disconnected from proxy.");
|
||||
println!("Disconnected from proxy.");
|
||||
}
|
||||
@@ -4,5 +4,5 @@ use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub(crate) struct APIQuery {
|
||||
pub backgroundFile: String,
|
||||
pub backgroundFile: String,
|
||||
}
|
||||
@@ -26,21 +26,21 @@ pub fn unzip(window: tauri::Window, zipfile: String, destpath: String) {
|
||||
match zip_extract::extract(&f, &full_path, true) {
|
||||
Ok(_) => {
|
||||
println!("Extracted zip file to: {}", full_path.to_str().unwrap_or("Error"));
|
||||
},
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to extract zip file: {}", e);
|
||||
let mut res_hash = std::collections::HashMap::new();
|
||||
|
||||
res_hash.insert(
|
||||
"error".to_string(),
|
||||
e.to_string()
|
||||
"error".to_string(),
|
||||
e.to_string(),
|
||||
);
|
||||
|
||||
|
||||
res_hash.insert(
|
||||
"path".to_string(),
|
||||
zipfile.to_string()
|
||||
"path".to_string(),
|
||||
zipfile.to_string(),
|
||||
);
|
||||
|
||||
|
||||
window.emit("download_error", &res_hash).unwrap();
|
||||
}
|
||||
};
|
||||
@@ -59,7 +59,7 @@ pub fn unzip(window: tauri::Window, zipfile: String, destpath: String) {
|
||||
match std::fs::remove_file(&zipfile) {
|
||||
Ok(_) => {
|
||||
println!("Deleted zip file: {}", zipfile);
|
||||
},
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to delete zip file: {}", e);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use reqwest::header::USER_AGENT;
|
||||
|
||||
pub(crate) async fn query(site: &str) -> String {
|
||||
let client = reqwest::Client::new();
|
||||
let client = reqwest::Client::new();
|
||||
|
||||
let response = client.get(site).header(USER_AGENT, "cultivation").send().await.unwrap();
|
||||
return response.text().await.unwrap();
|
||||
let response = client.get(site).header(USER_AGENT, "cultivation").send().await.unwrap();
|
||||
return response.text().await.unwrap();
|
||||
}
|
||||
Reference in New Issue
Block a user