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:
fnrir
2023-08-18 13:45:07 +02:00
parent b179ccc1f0
commit 2c07cf90bd
5 changed files with 90 additions and 18 deletions

1
src-tauri/Cargo.lock generated
View File

@@ -909,6 +909,7 @@ name = "cultivation"
version = "1.1.1"
dependencies = [
"anime-launcher-sdk",
"anyhow",
"args",
"cc",
"ctrlc",

View File

@@ -23,6 +23,7 @@ registry = "1.2.1"
sudo = "0.6.0"
[target.'cfg(target_os = "linux")'.dependencies]
anyhow = "1.0.58"
term-detect = "0.1.7"
[dependencies]

View File

@@ -411,7 +411,6 @@ fn restart_grasscutter(_window: tauri::Window) {
}
}
#[cfg(windows)]
#[tauri::command]
fn enable_grasscutter_watcher(window: tauri::Window, process: String) {
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]
async fn connect(port: u16, certificate_path: String) {
// Log message to console.

View File

@@ -1,8 +1,9 @@
use ini::Ini;
use std::ffi::OsStr;
use std::path::PathBuf;
use std::process::Command;
#[cfg(windows)]
use std::ffi::OsStr;
#[cfg(windows)]
use {
registry::{Data, Hive, Security},
@@ -15,7 +16,7 @@ use crate::AAGL_THREAD;
#[cfg(target_os = "linux")]
use anime_launcher_sdk::genshin::game;
#[cfg(target_os = "linux")]
use std::thread;
use std::{process::Stdio, thread};
#[cfg(target_os = "linux")]
use term_detect::get_terminal;
@@ -29,6 +30,29 @@ fn guess_user_terminal() -> 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]
pub fn run_program(path: String, args: Option<String>) {
// 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]
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)]
#[tauri::command]
@@ -349,10 +405,20 @@ pub fn start_service(service: String) -> bool {
true
}
#[cfg(unix)]
#[cfg(target_os = "linux")]
#[tauri::command]
pub fn start_service(_service: String) {
let _started = OsStr::new("Started service!");
pub fn start_service(service: String) -> bool {
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)]
@@ -374,9 +440,21 @@ pub fn stop_service(service: String) -> bool {
true
}
#[cfg(unix)]
#[cfg(target_os = "linux")]
#[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)]
#[tauri::command]

View File

@@ -216,7 +216,7 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
process: proc_name || grasscutter_jar,
})
// 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