111 lines
3.1 KiB
Rust
111 lines
3.1 KiB
Rust
mod server;
|
|
mod signals;
|
|
mod stdin;
|
|
|
|
use clap::Parser;
|
|
use server::ServerType;
|
|
use std::io;
|
|
use std::path::PathBuf;
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
#[derive(Parser)]
|
|
#[command(author, version, about, long_about = None)]
|
|
struct Cli {
|
|
/// Type of server
|
|
type_: ServerType,
|
|
/// Version string for the server, e.g. 1.19.4-545
|
|
#[arg(env = "ALEX_SERVER_VERSION")]
|
|
server_version: String,
|
|
|
|
/// Server jar to execute
|
|
#[arg(
|
|
long,
|
|
value_name = "JAR_PATH",
|
|
default_value = "server.jar",
|
|
env = "ALEX_JAR"
|
|
)]
|
|
jar: PathBuf,
|
|
/// Directory where configs are stored, and where the server will run
|
|
#[arg(
|
|
long,
|
|
value_name = "CONFIG_DIR",
|
|
default_value = ".",
|
|
env = "ALEX_CONFIG_DIR"
|
|
)]
|
|
config: PathBuf,
|
|
/// Directory where world files will be saved
|
|
#[arg(
|
|
long,
|
|
value_name = "WORLD_DIR",
|
|
default_value = "../worlds",
|
|
env = "ALEX_WORLD_DIR"
|
|
)]
|
|
world: PathBuf,
|
|
/// Directory where backups will be stored
|
|
#[arg(
|
|
long,
|
|
value_name = "BACKUP_DIR",
|
|
default_value = "../backups",
|
|
env = "ALEX_WORLD_DIR"
|
|
)]
|
|
backup: PathBuf,
|
|
/// Java command to run the server jar with
|
|
#[arg(long, value_name = "JAVA_CMD", default_value_t = String::from("java"), env = "ALEX_JAVA")]
|
|
java: String,
|
|
|
|
/// XMS value in megabytes for the server instance
|
|
#[arg(long, default_value_t = 1024, env = "ALEX_XMS")]
|
|
xms: u64,
|
|
/// XMX value in megabytes for the server instance
|
|
#[arg(long, default_value_t = 2048, env = "ALEX_XMX")]
|
|
xmx: u64,
|
|
|
|
/// How many backups to keep
|
|
#[arg(short = 'n', long, default_value_t = 7, env = "ALEX_MAX_BACKUPS")]
|
|
max_backups: u64,
|
|
/// How frequently to perform a backup, in minutes; 0 to disable.
|
|
#[arg(short = 't', long, default_value_t = 0, env = "ALEX_FREQUENCY")]
|
|
frequency: u64,
|
|
}
|
|
|
|
fn backups_thread(counter: Arc<Mutex<server::ServerProcess>>, frequency: u64) {
|
|
loop {
|
|
std::thread::sleep(std::time::Duration::from_secs(frequency * 60));
|
|
|
|
{
|
|
let mut server = counter.lock().unwrap();
|
|
|
|
// We explicitely ignore the error here, as we don't want the thread to fail
|
|
let _ = server.backup();
|
|
}
|
|
}
|
|
}
|
|
|
|
fn main() -> io::Result<()> {
|
|
let (_, mut signals) = signals::install_signal_handlers()?;
|
|
let cli = Cli::parse();
|
|
|
|
let cmd = server::ServerCommand::new(cli.type_, &cli.server_version)
|
|
.java(&cli.java)
|
|
.jar(cli.jar)
|
|
.config(cli.config)
|
|
.world(cli.world)
|
|
.backup(cli.backup)
|
|
.xms(cli.xms)
|
|
.xmx(cli.xmx)
|
|
.max_backups(cli.max_backups);
|
|
let counter = Arc::new(Mutex::new(cmd.spawn()?));
|
|
|
|
if cli.frequency > 0 {
|
|
let clone = Arc::clone(&counter);
|
|
std::thread::spawn(move || backups_thread(clone, cli.frequency));
|
|
}
|
|
|
|
// Spawn thread that handles the main stdin loop
|
|
let clone = Arc::clone(&counter);
|
|
std::thread::spawn(move || stdin::handle_stdin(clone));
|
|
|
|
// Signal handler loop exits the process when necessary
|
|
signals::handle_signals(&mut signals, counter)
|
|
}
|