Merge branch 'main' of github.com:Grasscutters/Cultivation

This commit is contained in:
SpikeHD
2022-07-11 19:45:29 -07:00
13 changed files with 615 additions and 823 deletions

View File

@@ -8,9 +8,9 @@ Consider Cultivation to be the bleeding-edge version of GrassClipper.
During this open-beta testing period, **helpful issues are appreciated**, while unhelpful ones will be closed.
## Fair Warning
Cultivation is **VERY MUCH IN BETA** and a majority of features do not work.\
There are **no official releases of Cultivation**. You are **required** to build the application from **scratch**.\
Please do **NOT install, download, or use pre-compiled versions of Cultivation**. Only use releases from this GitHub repository.
Cultivation is **VERY MUCH IN BETA**.
There are **no official releases of Cultivation**. You are **required** to build the application from **scratch** unless you want to deal with the alpha state of the current builds.
Please do **NOT install, download, or use pre-compiled versions of Cultivation found elsewhere**. Only use releases from this GitHub repository.
# Cultivation
A game launcher designed to easily proxy traffic from anime game to private servers.

View File

@@ -1,6 +1,6 @@
{
"name": "cultivation",
"version": "1.0.1",
"version": "1.0.2",
"private": true,
"dependencies": {
"@tauri-apps/api": "^1.0.0-rc.5",

1255
src-tauri/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -26,14 +26,14 @@ serde = { version = "1.0", features = ["derive"] }
tauri = { version = "1.0.0-rc.9", features = ["api-all"] }
# Access system process info.
sysinfo = "0.23.12"
sysinfo = "0.24.6"
# ZIP-archive library.
zip-extract = "0.1.1"
zip = "0.6.2"
# For creating a "global" downloads list.
lazy_static = "1.4.0"
once_cell = "1.13.0"
# Program opener.
open = "2.1.2"
@@ -42,9 +42,6 @@ duct = "0.13.5"
# Serialization.
serde_json = "1"
# System process elevation.
runas = "0.2.1"
# Dependencies for the HTTP(S) proxy.
http = "0.2"
hudsucker = "0.17.2"

View File

@@ -1,4 +1,4 @@
use lazy_static::lazy_static;
use once_cell::sync::Lazy;
use std::sync::Mutex;
use std::cmp::min;
@@ -8,12 +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! {
static ref DOWNLOADS: Mutex<Vec<String>> = {
let m = Vec::new();
Mutex::new(m)
};
}
static DOWNLOADS: Lazy<Mutex<Vec<String>>> = Lazy::new(|| Mutex::new(Vec::new()));
// Lots of help from: https://gist.github.com/giuliano-oliveira/4d11d6b3bb003dba3a1b53f43d81b30d
// and docs ofc
@@ -59,17 +54,17 @@ pub async fn download_file(window: tauri::Window, url: &str, path: &str) -> Resu
let chunk = match item {
Ok(itm) => itm,
Err(e) => {
emit_download_err(window, format!("Error while downloading file"), path);
emit_download_err(window, "Error while downloading file".to_string(), path);
return Err(format!("Error while downloading file: {}", e));
}
};
let vect = &chunk.to_vec()[..];
// Write bytes
match file.write_all(&vect) {
match file.write_all(vect) {
Ok(x) => x,
Err(e) => {
emit_download_err(window, format!("Error while writing file"), path);
emit_download_err(window, "Error while writing file".to_string(), path);
return Err(format!("Error while writing file: {}", e));
}
}
@@ -78,7 +73,7 @@ pub async fn download_file(window: tauri::Window, url: &str, path: &str) -> Resu
let new = min(downloaded + (chunk.len() as u64), total_size);
downloaded = new;
total_downloaded = total_downloaded + chunk.len() as u64;
total_downloaded += chunk.len() as u64;
let mut res_hash = std::collections::HashMap::new();
@@ -110,15 +105,15 @@ pub async fn download_file(window: tauri::Window, url: &str, path: &str) -> Resu
window.emit("download_finished", &path).unwrap();
// We are done
return Ok(());
Ok(())
}
pub fn emit_download_err(window: tauri::Window, msg: std::string::String, path: &str) {
pub fn emit_download_err(window: tauri::Window, msg: String, path: &str) {
let mut res_hash = std::collections::HashMap::new();
res_hash.insert(
"error".to_string(),
msg.to_string(),
msg,
);
res_hash.insert(

View File

@@ -5,31 +5,51 @@ pub fn rename(path: String, new_name: String) {
let mut new_path = path.clone();
// Check if file/folder to replace exists
if !fs::metadata(&path).is_ok() {
if fs::metadata(&path).is_err() {
return;
}
// Check if path uses forward or back slashes
if new_path.contains("\\") {
new_path = path.replace("\\", "/");
if new_path.contains('\\') {
new_path = path.replace('\\', "/");
}
let path_replaced = &path.replace(&new_path.split("/").last().unwrap(), &new_name);
let path_replaced = &path.replace(&new_path.split('/').last().unwrap(), &new_name);
fs::rename(path, &path_replaced).unwrap();
}
#[tauri::command]
pub fn dir_exists(path: &str) -> bool {
return fs::metadata(&path).is_ok();
fs::metadata(&path).is_ok()
}
#[tauri::command]
pub fn dir_is_empty(path: &str) -> bool {
return fs::read_dir(&path).unwrap().count() == 0;
fs::read_dir(&path).unwrap().count() == 0
}
#[tauri::command]
pub fn dir_delete(path: &str) {
fs::remove_dir_all(path).unwrap();
}
}
#[tauri::command]
pub fn copy_file(path: String, new_path: String) -> bool {
let filename = &path.split("/").last().unwrap();
let mut new_path_buf = std::path::PathBuf::from(&new_path);
// If the new path doesn't exist, create it.
if !dir_exists(new_path_buf.pop().to_string().as_str()) {
std::fs::create_dir_all(&new_path).unwrap();
}
// Copy old to new
match std::fs::copy(&path, format!("{}/{}", new_path, filename)) {
Ok(_) => true,
Err(e) => {
println!("Failed to copy file: {}", e);
false
}
}
}

View File

@@ -7,15 +7,13 @@ pub async fn get_lang(window: tauri::Window, lang: String) -> String {
// Send contents of language file back
let lang_path: PathBuf = [&install_location(), "lang", &format!("{}.json", lang)].iter().collect();
let contents = match std::fs::read_to_string(&lang_path) {
match std::fs::read_to_string(&lang_path) {
Ok(x) => x,
Err(e) => {
emit_lang_err(window, format!("Failed to read language file: {}", e));
return "".to_string();
"".to_string()
}
};
return contents;
}
}
#[tauri::command]
@@ -23,9 +21,9 @@ pub async fn get_languages() -> std::collections::HashMap<String, String> {
// for each lang file, set the key as the filename and the value as the lang_name contained in the file
let mut languages = std::collections::HashMap::new();
let mut lang_files = std::fs::read_dir(Path::new(&install_location()).join("lang")).unwrap();
let lang_files = std::fs::read_dir(Path::new(&install_location()).join("lang")).unwrap();
while let Some(entry) = lang_files.next() {
for entry in lang_files {
let entry = entry.unwrap();
let path = entry.path();
let filename = path.file_name().unwrap().to_str().unwrap();
@@ -41,15 +39,15 @@ pub async fn get_languages() -> std::collections::HashMap<String, String> {
languages.insert(filename.to_string(), content);
}
return languages;
languages
}
pub fn emit_lang_err(window: tauri::Window, msg: std::string::String) {
pub fn emit_lang_err(window: tauri::Window, msg: String) {
let mut res_hash = std::collections::HashMap::new();
res_hash.insert(
"error".to_string(),
msg.to_string(),
msg,
);
window.emit("lang_error", &res_hash).unwrap();

View File

@@ -3,7 +3,7 @@ all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
use lazy_static::lazy_static;
use once_cell::sync::Lazy;
use std::{sync::Mutex, collections::HashMap};
use std::path::PathBuf;
@@ -20,21 +20,12 @@ mod lang;
mod proxy;
mod web;
lazy_static! {
static ref WATCH_GAME_PROCESS: Mutex<String> = {
let m = "".to_string();
Mutex::new(m)
};
}
static WATCH_GAME_PROCESS: Lazy<Mutex<String>> = Lazy::new(|| Mutex::new(String::new()));
fn main() {
// Start the game process watcher.
process_watcher();
// Make BG folder if it doesn't exist.
let bg_folder: PathBuf = [&system_helpers::install_location(), "bg"].iter().collect();
std::fs::create_dir_all(&bg_folder).unwrap();
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![
enable_process_watcher,
@@ -48,7 +39,6 @@ fn main() {
system_helpers::run_program,
system_helpers::run_jar,
system_helpers::open_in_browser,
system_helpers::copy_file,
system_helpers::install_location,
system_helpers::is_elevated,
proxy::set_proxy_addr,
@@ -58,6 +48,7 @@ fn main() {
file_helpers::dir_exists,
file_helpers::dir_is_empty,
file_helpers::dir_delete,
file_helpers::copy_file,
downloader::download_file,
downloader::stop_download,
lang::get_lang,
@@ -84,14 +75,9 @@ fn process_watcher() {
// Grab the game process name
let proc = WATCH_GAME_PROCESS.lock().unwrap().to_string();
if !&proc.is_empty() {
let proc_with_name = system.processes_by_exact_name(&proc);
let mut exists = false;
for _p in proc_with_name {
exists = true;
break;
}
if !proc.is_empty() {
let mut proc_with_name = system.processes_by_exact_name(&proc);
let exists = proc_with_name.next().is_some();
// If the game process closes, disable the proxy.
if !exists {
@@ -109,7 +95,7 @@ fn is_game_running() -> bool {
// Grab the game process name
let proc = WATCH_GAME_PROCESS.lock().unwrap().to_string();
return !proc.is_empty();
!proc.is_empty()
}
#[tauri::command]
@@ -140,11 +126,8 @@ fn disconnect() {
#[tauri::command]
async fn req_get(url: String) -> String {
// Send a GET request to the specified URL.
let response = web::query(&url.to_string()).await;
// Send the response body back to the client.
return response;
// Send a GET request to the specified URL and send the response body back to the client.
web::query(&url.to_string()).await
}
#[tauri::command]
@@ -180,7 +163,7 @@ async fn get_theme_list(data_dir: String) -> Vec<HashMap<String, String>> {
}
}
return themes;
themes
}
#[tauri::command]
@@ -204,7 +187,7 @@ async fn get_bg_file(bg_path: String, appdata: String) -> String {
}
// 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());
let bg_img_path = format!("{}\\{}", &bg_path, &file_name);
// If it doesn't, then we do not have backgrounds to grab.
if !file_helpers::dir_exists(&bg_path) {
@@ -220,15 +203,15 @@ async fn get_bg_file(bg_path: String, appdata: String) -> String {
// The image exists, lets copy it to our local '\bg' folder.
let bg_img_path_local = format!("{}\\bg\\{}", copy_loc, file_name.as_str());
return match std::fs::copy(bg_img_path, bg_img_path_local) {
match std::fs::copy(bg_img_path, bg_img_path_local) {
Ok(_) => {
// Copy was successful, lets return true.
format!("{}\\{}", copy_loc, response_data.bg_file.as_str())
format!("{}\\{}", copy_loc, response_data.bg_file)
}
Err(e) => {
// Copy failed, lets return false
println!("Failed to copy background image: {}", e);
"".to_string()
}
};
}
}

View File

@@ -3,7 +3,7 @@
* https://github.com/omjadas/hudsucker/blob/main/examples/log.rs
*/
use lazy_static::lazy_static;
use once_cell::sync::Lazy;
use std::{sync::Mutex, str::FromStr};
use rcgen::*;
@@ -30,12 +30,7 @@ async fn shutdown_signal() {
}
// Global ver for getting server address.
lazy_static! {
static ref SERVER: Mutex<String> = {
let m = "http://localhost:443".to_string();
Mutex::new(m)
};
}
static SERVER: Lazy<Mutex<String>> = Lazy::new(|| Mutex::new("http://localhost:443".to_string()));
#[derive(Clone)]
struct ProxyHandler;

View File

@@ -1,7 +1,3 @@
use std::thread;
use tauri;
use open;
use duct::cmd;
use crate::file_helpers;
@@ -9,11 +5,7 @@ use crate::file_helpers;
#[tauri::command]
pub fn run_program(path: String) {
// Open the program from the specified path.
// Open in new thread to prevent blocking.
thread::spawn(move || {
open::that(&path).unwrap();
});
open::that(&path).unwrap();
}
#[tauri::command]
@@ -31,7 +23,7 @@ pub fn run_jar(path: String, execute_in: String, java_path: String) {
};
// Open the program from the specified path.
match open::with(format!("/k cd /D \"{}\" & {}", &execute_in, &command).to_string(), "C:\\Windows\\System32\\cmd.exe") {
match open::with(format!("/k cd /D \"{}\" & {}", &execute_in, &command), "C:\\Windows\\System32\\cmd.exe") {
Ok(_) => (),
Err(e) => println!("Failed to open jar ({} from {}): {}", &path, &execute_in, e),
};
@@ -46,25 +38,6 @@ pub fn open_in_browser(url: String) {
};
}
#[tauri::command]
pub fn copy_file(path: String, new_path: String) -> bool {
let filename = &path.split("/").last().unwrap();
let mut new_path_buf = std::path::PathBuf::from(&new_path);
// If the new path doesn't exist, create it.
if !file_helpers::dir_exists(new_path_buf.pop().to_string().as_str()) {
std::fs::create_dir_all(&new_path).unwrap();
}
// Copy old to new
match std::fs::copy(&path, format!("{}/{}", new_path, filename)) {
Ok(_) => true,
Err(e) => {
println!("Failed to copy file: {}", e);
false
}
}
}
#[tauri::command]
pub fn install_location() -> String {

View File

@@ -1,5 +1,3 @@
use zip_extract;
use zip;
use std::fs::File;
use std::path;
use std::thread;

View File

@@ -4,7 +4,7 @@ pub(crate) async fn query(site: &str) -> String {
let client = reqwest::Client::new();
let response = client.get(site).header(USER_AGENT, "cultivation").send().await.unwrap();
return response.text().await.unwrap();
response.text().await.unwrap()
}
#[tauri::command]
@@ -14,5 +14,5 @@ pub(crate) async fn valid_url(url: String) -> bool {
let response = client.get(url).header(USER_AGENT, "cultivation").send().await.unwrap();
return response.status().as_str() == "200";
response.status().as_str() == "200"
}

View File

@@ -7,7 +7,7 @@
},
"package": {
"productName": "Cultivation",
"version": "1.0.1"
"version": "1.0.2"
},
"tauri": {
"allowlist": {