use std::{collections::HashMap, convert::Infallible, fmt::Display, str::FromStr};
use crate::io::java::install::JavaInstallationKind;
use nitro_shared::java_args::MemoryNum;
#[derive(Debug, Clone)]
pub struct LaunchConfiguration {
pub java: JavaInstallationKind,
pub jvm_args: Vec<String>,
pub game_args: Vec<String>,
pub min_mem: Option<MemoryNum>,
pub max_mem: Option<MemoryNum>,
pub env: HashMap<String, String>,
pub wrappers: Vec<WrapperCommand>,
pub quick_play: QuickPlayType,
pub exclude_default_args: bool,
pub use_log4j_config: bool,
}
impl LaunchConfiguration {
pub fn new() -> Self {
Self {
java: JavaInstallationKind::Auto,
jvm_args: Vec::new(),
game_args: Vec::new(),
min_mem: None,
max_mem: None,
env: HashMap::new(),
wrappers: Vec::new(),
quick_play: QuickPlayType::None,
exclude_default_args: false,
use_log4j_config: false,
}
}
pub fn builder() -> LaunchConfigBuilder {
LaunchConfigBuilder::new()
}
}
impl Default for LaunchConfiguration {
fn default() -> Self {
Self::new()
}
}
pub struct LaunchConfigBuilder {
config: LaunchConfiguration,
}
impl LaunchConfigBuilder {
pub fn new() -> Self {
Self {
config: LaunchConfiguration::new(),
}
}
pub fn build(self) -> LaunchConfiguration {
self.config
}
pub fn java(mut self, java: JavaInstallationKind) -> Self {
self.config.java = java;
self
}
pub fn jvm_args(mut self, jvm_args: Vec<String>) -> Self {
self.config.jvm_args = jvm_args;
self
}
pub fn game_args(mut self, game_args: Vec<String>) -> Self {
self.config.game_args = game_args;
self
}
pub fn min_mem(mut self, min_mem: MemoryNum) -> Self {
self.config.min_mem = Some(min_mem);
self
}
pub fn max_mem(mut self, max_mem: MemoryNum) -> Self {
self.config.max_mem = Some(max_mem);
self
}
pub fn env(mut self, env: HashMap<String, String>) -> Self {
self.config.env = env;
self
}
pub fn wrapper(mut self, wrapper: WrapperCommand) -> Self {
self.config.wrappers.push(wrapper);
self
}
pub fn quick_play(mut self, quick_play: QuickPlayType) -> Self {
self.config.quick_play = quick_play;
self
}
pub fn exclude_default_args(mut self, exclude_default_args: bool) -> Self {
self.config.exclude_default_args = exclude_default_args;
self
}
pub fn use_log4j_config(mut self, use_log4j_config: bool) -> Self {
self.config.use_log4j_config = use_log4j_config;
self
}
}
impl Default for LaunchConfigBuilder {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
pub struct WrapperCommand {
pub cmd: String,
pub args: Vec<String>,
}
#[derive(Debug, PartialEq, Eq, Default, Clone, Hash)]
pub enum QuickPlayType {
World {
world: String,
},
Server {
server: String,
port: Option<u16>,
},
Realm {
realm: String,
},
#[default]
None,
}
impl FromStr for QuickPlayType {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if let Some(s) = s.strip_prefix("world:") {
Ok(Self::World {
world: s.to_string(),
})
} else if let Some(s) = s.strip_prefix("server:") {
let mut split = s.split(":");
let server = split.next().unwrap();
let port = split.next();
Ok(Self::Server {
server: server.to_string(),
port: port.and_then(|x| x.parse().ok()),
})
} else if let Some(s) = s.strip_prefix("realm:") {
Ok(Self::Realm {
realm: s.to_string(),
})
} else {
Ok(Self::World {
world: s.to_string(),
})
}
}
}
impl Display for QuickPlayType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::None => write!(f, "none"),
Self::World { world } => write!(f, "world:{world}"),
Self::Server { server, port } => match port {
Some(port) => write!(f, "server:{server}:{port}"),
None => write!(f, "server:{server}"),
},
Self::Realm { realm } => write!(f, "realm:{realm}"),
}
}
}