mirror of
https://github.com/Grasscutters/Cultivation.git
synced 2025-12-12 23:24:35 +01:00
Implement MongoDB autostart and GC watching
Windows's implementation of enable_grasscutter_watcher works just fine. systemd is pretty much standart for handling services. No "sudo" or "pkexec" is needed, systemd does that automatically, but since the user needs to authenticate, we can’t await service_status.
This commit is contained in:
1
src-tauri/Cargo.lock
generated
1
src-tauri/Cargo.lock
generated
@@ -909,6 +909,7 @@ name = "cultivation"
|
|||||||
version = "1.1.1"
|
version = "1.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anime-launcher-sdk",
|
"anime-launcher-sdk",
|
||||||
|
"anyhow",
|
||||||
"args",
|
"args",
|
||||||
"cc",
|
"cc",
|
||||||
"ctrlc",
|
"ctrlc",
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ registry = "1.2.1"
|
|||||||
sudo = "0.6.0"
|
sudo = "0.6.0"
|
||||||
|
|
||||||
[target.'cfg(target_os = "linux")'.dependencies]
|
[target.'cfg(target_os = "linux")'.dependencies]
|
||||||
|
anyhow = "1.0.58"
|
||||||
term-detect = "0.1.7"
|
term-detect = "0.1.7"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@@ -411,7 +411,6 @@ fn restart_grasscutter(_window: tauri::Window) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
fn enable_grasscutter_watcher(window: tauri::Window, process: String) {
|
fn enable_grasscutter_watcher(window: tauri::Window, process: String) {
|
||||||
let grasscutter_name = process.clone();
|
let grasscutter_name = process.clone();
|
||||||
@@ -472,13 +471,6 @@ fn enable_grasscutter_watcher(window: tauri::Window, process: String) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
#[tauri::command]
|
|
||||||
fn enable_grasscutter_watcher(_window: tauri::Window, _process: String) {
|
|
||||||
let gc_pid = Pid::from(696969);
|
|
||||||
*GC_PID.lock().unwrap() = gc_pid.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn connect(port: u16, certificate_path: String) {
|
async fn connect(port: u16, certificate_path: String) {
|
||||||
// Log message to console.
|
// Log message to console.
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
use ini::Ini;
|
use ini::Ini;
|
||||||
use std::ffi::OsStr;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
use std::ffi::OsStr;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use {
|
use {
|
||||||
registry::{Data, Hive, Security},
|
registry::{Data, Hive, Security},
|
||||||
@@ -15,7 +16,7 @@ use crate::AAGL_THREAD;
|
|||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
use anime_launcher_sdk::genshin::game;
|
use anime_launcher_sdk::genshin::game;
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
use std::thread;
|
use std::{process::Stdio, thread};
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
use term_detect::get_terminal;
|
use term_detect::get_terminal;
|
||||||
|
|
||||||
@@ -29,6 +30,29 @@ fn guess_user_terminal() -> String {
|
|||||||
"xterm".to_string()
|
"xterm".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub trait SpawnItsFineReally {
|
||||||
|
fn spawn_its_fine_really(&mut self, msg: &str) -> anyhow::Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
impl SpawnItsFineReally for Command {
|
||||||
|
fn spawn_its_fine_really(&mut self, msg: &str) -> anyhow::Result<()> {
|
||||||
|
let res = self.status();
|
||||||
|
let Ok(status) = res else {
|
||||||
|
let error = res.unwrap_err();
|
||||||
|
println!("{}: {}", msg, &error);
|
||||||
|
return Err(error.into());
|
||||||
|
};
|
||||||
|
if !status.success() {
|
||||||
|
println!("{}: {}", msg, status);
|
||||||
|
Err(anyhow::anyhow!("{}: {}", msg, status))
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn run_program(path: String, args: Option<String>) {
|
pub fn run_program(path: String, args: Option<String>) {
|
||||||
// Without unwrap_or, this can crash when UAC prompt is denied
|
// Without unwrap_or, this can crash when UAC prompt is denied
|
||||||
@@ -326,9 +350,41 @@ pub fn service_status(service: String) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(target_os = "linux")]
|
||||||
|
fn to_linux_service_name(service: &str) -> Option<String> {
|
||||||
|
Some(format!(
|
||||||
|
"{}.service",
|
||||||
|
match service {
|
||||||
|
"MongoDB" => "mongod",
|
||||||
|
_ => return None,
|
||||||
|
}
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn service_status(_service: String) {}
|
pub fn service_status(service: String) -> bool {
|
||||||
|
// Change Windows service name into Linux service name
|
||||||
|
let service_lnx = to_linux_service_name(&service);
|
||||||
|
if service_lnx.is_none() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let service_lnx = service_lnx.unwrap();
|
||||||
|
let status = Command::new("systemctl")
|
||||||
|
.arg("is-active")
|
||||||
|
.arg(service_lnx)
|
||||||
|
.stdout(Stdio::null())
|
||||||
|
.status();
|
||||||
|
if status.is_err() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let status = status.unwrap().success();
|
||||||
|
if status {
|
||||||
|
status
|
||||||
|
} else {
|
||||||
|
start_service(service)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -349,10 +405,20 @@ pub fn start_service(service: String) -> bool {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(target_os = "linux")]
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn start_service(_service: String) {
|
pub fn start_service(service: String) -> bool {
|
||||||
let _started = OsStr::new("Started service!");
|
println!("Starting service: {}", service);
|
||||||
|
let service_lnx = to_linux_service_name(&service);
|
||||||
|
if service_lnx.is_none() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let service_lnx = service_lnx.unwrap();
|
||||||
|
Command::new("systemctl")
|
||||||
|
.arg("start")
|
||||||
|
.arg(service_lnx)
|
||||||
|
.spawn_its_fine_really(&format!("Failed to stop service {}", service))
|
||||||
|
.is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@@ -374,9 +440,21 @@ pub fn stop_service(service: String) -> bool {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(target_os = "linux")]
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn stop_service(_service: String) {}
|
pub fn stop_service(service: String) -> bool {
|
||||||
|
println!("Stopping service: {}", service);
|
||||||
|
let service_lnx = to_linux_service_name(&service);
|
||||||
|
if service_lnx.is_none() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let service_lnx = service_lnx.unwrap();
|
||||||
|
Command::new("systemctl")
|
||||||
|
.arg("stop")
|
||||||
|
.arg(service_lnx)
|
||||||
|
.spawn_its_fine_really(&format!("Failed to start service {}", service))
|
||||||
|
.is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
|
|||||||
process: proc_name || grasscutter_jar,
|
process: proc_name || grasscutter_jar,
|
||||||
})
|
})
|
||||||
// Check if MongoDB is running and start it if not
|
// Check if MongoDB is running and start it if not
|
||||||
await invoke('service_status', { service: 'MongoDB' })
|
invoke('service_status', { service: 'MongoDB' })
|
||||||
}
|
}
|
||||||
|
|
||||||
let jarFolder = config.grasscutter_path
|
let jarFolder = config.grasscutter_path
|
||||||
|
|||||||
Reference in New Issue
Block a user