diff --git a/Cargo.toml b/Cargo.toml index 804a627..279ad89 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,10 @@ edition = "2018" tar = "0.4.37" # Used to compress said tarballs using gzip flate2 = "1.0.21" +# Used for backup filenames +chrono = "0.4.19" + +[profile.release] +lto = "fat" +codegen-units = 1 +panic = "abort" diff --git a/src/main.rs b/src/main.rs index e331182..f5cd3e5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,47 +1,9 @@ use std::io; -use std::io::Write; -use std::process::{Child, Command, Stdio}; -struct Server { - child: Child, -} - -impl Server { - fn spawn() -> Server { - let child = Command::new("/usr/lib/jvm/java-16-openjdk/bin/java") - .arg("-jar") - .arg("paper-1.17.1-259.jar") - .arg("--universe") - .arg("worlds") - .arg("--nogui") - .stdin(Stdio::piped()) - .spawn() - .expect("Couldn't start child process"); - - Server { child } - } - - pub fn send_command(&mut self, cmd: &str) { - match cmd.trim() { - "stop" | "exit" => self.stop(), - s => self.custom(s), - } - } - - fn custom(&mut self, cmd: &str) { - let mut stdin = self.child.stdin.as_ref().unwrap(); - stdin.write_all(cmd.as_bytes()).unwrap(); - stdin.flush().unwrap(); - } - - pub fn stop(&mut self) { - self.custom("stop"); - self.child.wait(); - } -} +mod server; fn main() { - let mut server = Server::spawn(); + let mut server = server::Server::spawn(); let stdin = io::stdin(); let input = &mut String::new(); diff --git a/src/server.rs b/src/server.rs new file mode 100644 index 0000000..1e8db39 --- /dev/null +++ b/src/server.rs @@ -0,0 +1,60 @@ +use std::io; +use std::io::Write; +use std::process::{Child, Command, Stdio}; +use std::fs::File; +use flate2::Compression; +use flate2::write::GzEncoder; + +pub struct Server { + child: Child, +} + +impl Server { + pub fn spawn() -> Server { + let child = Command::new("/usr/lib/jvm/java-16-openjdk/bin/java") + .arg("-jar") + .arg("paper-1.17.1-259.jar") + .arg("--universe") + .arg("worlds") + .arg("--nogui") + .stdin(Stdio::piped()) + .spawn() + .expect("Couldn't start child process"); + + Server { child } + } + + pub fn send_command(&mut self, cmd: &str) { + match cmd.trim() { + "stop" | "exit" => self.stop(), + "backup" => self.backup(), + s => self.custom(s), + } + } + + fn custom(&mut self, cmd: &str) { + let mut stdin = self.child.stdin.as_ref().unwrap(); + stdin.write_all(format!("{}\n", cmd.trim()).as_bytes()).unwrap(); + stdin.flush().unwrap(); + } + + pub fn stop(&mut self) { + self.custom("stop"); + self.child.wait(); + } + + pub fn backup(&mut self) { + // Make sure the server isn't modifying the files during the backup + self.custom("save-off"); + self.custom("save-all"); + + // Create a gzip-compressed tarball of the worlds folder + let filename = format!("{}", chrono::offset::Local::now().format("backups/%Y-%m-%d_%H-%M-%S.tar.gz")); + let tar_gz = std::fs::File::create(filename).unwrap(); + let enc = GzEncoder::new(tar_gz, Compression::default()); + let mut tar = tar::Builder::new(enc); + tar.append_dir_all("worlds", "worlds").unwrap(); + + self.custom("save-on"); + } +}