use chrono::Utc; use clap::{ArgMatches, Command, arg}; use crate::cli::env_settings; use crate::status::ServerStatus; use crate::utils::{ validate_name, extract_archive, move_all_elements}; use diesel::prelude::*; use crate::{DbPool, models}; use crate::schema; use tokio::{fs::{File, create_dir}, io::AsyncWriteExt}; use std::path::Path; pub fn create_subcommand() -> Command { let mut arguments = vec![ arg!( "Name of the server"), arg!([SERVER_ARCHIVE] "initial server archive (supported : prism zip)"), ]; arguments.extend(env_settings::get_args()); Command::new("add") .about("Add a server") .args(arguments.as_slice()) } pub async fn subcommand(arg: &ArgMatches, pool: DbPool) -> Result<(), String>{ use schema::servers::dsl::*; let config = crate::Config::load(); let server_name = arg.get_one::("NAME").unwrap(); if !validate_name(server_name) { return Err("Invalid name provided".to_string()); } let conn = &mut pool.get().unwrap(); if let Ok(_) = schema::servers::table.filter(schema::servers::name.eq(server_name)).select(models::Servers::as_select()).first(conn) { return Err("Server with this name already exists".to_string()) } let path = config.config_path + "/" + server_name + "/"; create_dir(&path).await.map_err(|e| format!("failed to create the config folder, reason : {}", e))?; let mut file = File::create(path.to_string() + "env").await.map_err(|e| format!("failed to create .env file, reason {}", e))?; file.write_all(env_settings::args_to_env(arg, true).as_bytes()).await.map_err(|e| format!("Failed to write to env file, reason : {}", e))?; create_dir(path.to_string() + "server").await.map_err(|e| format!("failed to create server subfolder, reason: {}", e))?; if let Some(archive) = arg.get_one::("SERVER_ARCHIVE") { extract_archive(archive.to_owned(), path.to_string() + "tmp").await?; move_all_elements(Path::new(&(path.to_string() + "tmp/minecraft")), Path::new(&(path.to_string() + "server"))).map_err(|e| format!("failed to move the elements, reason: {}", e))?; std::fs::remove_dir_all(path.to_string() + "tmp").map_err(|e| format!("failed to remove the tmp dir, reason : {}", e))?; } let new_server = models::CreateServer { name: server_name, last_login: Some(Utc::now().naive_utc()), status: ServerStatus::Stopped, redirect_ip: None }; diesel::insert_into(servers).values(&new_server).execute(conn).map_err(|e| format!("Failed to insert in db, error : {:?}", e))?; Ok(()) }