1use serde::Deserialize;
2use std::path::PathBuf;
3use anyhow::{Result, Context};
4#[derive(Debug, Deserialize, Clone)]
7pub struct Config {
8 pub rcon: RconConfig,
9 #[serde(default)]
10 pub server: ServerConfig,
11 #[serde(default)]
12 pub backup: BackupConfig,
13 #[serde(default)]
14 pub notification: NotificationConfig,
15 #[serde(default)]
16 #[allow(dead_code)]
17 pub jvm: JvmConfig,
18}
19
20#[derive(Debug, Deserialize, Clone)]
21pub struct RconConfig {
22 #[serde(default = "default_rcon_host")]
23 pub host: String,
24 #[serde(default = "default_rcon_port")]
25 pub port: u16,
26 pub password: String,
27}
28
29fn default_rcon_host() -> String { "127.0.0.1".to_string() }
30fn default_rcon_port() -> u16 { 25575 }
31
32#[derive(Debug, Deserialize, Clone)]
33pub struct ServerConfig {
34 #[serde(default = "default_jar")]
35 pub jar: String,
36 #[serde(default = "default_min_mem")]
37 pub min_mem: String,
38 #[serde(default = "default_max_mem")]
39 pub max_mem: String,
40 #[serde(default = "default_session_name")]
41 pub session_name: String,
42 #[serde(default = "default_log_file")]
43 pub log_file: String,
44 #[serde(default = "default_server_type")]
46 #[allow(dead_code)]
47 pub server_type: String,
48}
49
50fn default_jar() -> String { "fabric-server.jar".to_string() }
51fn default_min_mem() -> String { "512M".to_string() }
52fn default_max_mem() -> String { "1G".to_string() }
53fn default_session_name() -> String { "mc_server".to_string() }
54fn default_log_file() -> String { "logs/latest.log".to_string() }
55fn default_server_type() -> String { "fabric".to_string() }
56
57impl Default for ServerConfig {
58 fn default() -> Self {
59 Self {
60 jar: default_jar(),
61 min_mem: default_min_mem(),
62 max_mem: default_max_mem(),
63 session_name: default_session_name(),
64 log_file: default_log_file(),
65 server_type: default_server_type(),
66 }
67 }
68}
69
70#[derive(Debug, Deserialize, Clone)]
71pub struct BackupConfig {
72 #[serde(default = "default_world_dir")]
73 pub world_dir: String,
74 #[serde(default = "default_backup_dest")]
75 pub backup_dest: String,
76 #[serde(default = "default_retain_days")]
77 pub retain_days: u32,
78}
79
80fn default_world_dir() -> String { "world".to_string() }
81fn default_backup_dest() -> String { "../backups".to_string() }
82fn default_retain_days() -> u32 { 7 }
83
84impl Default for BackupConfig {
85 fn default() -> Self {
86 Self {
87 world_dir: default_world_dir(),
88 backup_dest: default_backup_dest(),
89 retain_days: default_retain_days(),
90 }
91 }
92}
93
94#[derive(Debug, Deserialize, Clone)]
95#[allow(dead_code)]
96pub struct NotificationConfig {
97 #[serde(default)]
98 pub telegram_bot_token: String,
99 #[serde(default)]
100 pub telegram_chat_id: String,
101 #[serde(default = "default_termux_notify")]
102 pub termux_notify: bool,
103}
104
105fn default_termux_notify() -> bool { true }
106
107impl Default for NotificationConfig {
108 fn default() -> Self {
109 Self {
110 telegram_bot_token: String::new(),
111 telegram_chat_id: String::new(),
112 termux_notify: default_termux_notify(),
113 }
114 }
115}
116
117#[derive(Debug, Deserialize, Clone)]
118#[allow(dead_code)]
119pub struct JvmConfig {
120 #[serde(default = "default_gc")]
121 pub gc: String,
122 #[serde(default)]
123 pub extra_flags: String,
124 #[serde(default)]
125 pub xmx: Option<String>,
126 #[serde(default)]
127 pub xms: Option<String>,
128 #[serde(default)]
129 pub jdk_path: Option<String>,
130}
131
132fn default_gc() -> String { "G1GC".to_string() }
133
134impl Default for JvmConfig {
135 fn default() -> Self {
136 Self {
137 gc: default_gc(),
138 extra_flags: String::new(),
139 xmx: None,
140 xms: None,
141 jdk_path: None,
142 }
143 }
144}
145
146impl Config {
147 pub fn load(path: &PathBuf) -> Result<Self> {
148 let content = std::fs::read_to_string(path)
149 .with_context(|| format!("Failed to read config file: {:?}", path))?;
150
151 Self::load_from_str(&content)
152 }
153
154 pub fn load_from_str(content: &str) -> Result<Self> {
155 let config: Config = toml::from_str(content)
156 .with_context(|| "Failed to parse config file")?;
157
158 Ok(config)
159 }
160
161 pub fn generate_template() -> String {
162 let s = r#"# MC-Minder Configuration File
163
164[server]
165jar = "fabric-server.jar"
166min_mem = "512M"
167max_mem = "1G"
168session_name = "mc_server"
169log_file = "logs/latest.log"
170
171[rcon]
172host = "127.0.0.1"
173port = 25575
174password = ""
175
176[backup]
177world_dir = "world"
178backup_dest = "../backups"
179retain_days = 7
180
181[notification]
182telegram_bot_token = ""
183telegram_chat_id = ""
184termux_notify = true
185
186[jvm]
187gc = "G1GC"
188extra_flags = ""
189# jdk_path = "/usr/lib/jvm/java-17-openjdk/bin/java"
190"#;
191 s.to_string()
192 }
193}