Skip to main content

mc_minder/config/
mod.rs

1use serde::Deserialize;
2use std::path::PathBuf;
3use anyhow::{Result, Context};
4
5#[derive(Debug, Deserialize, Clone)]
6pub struct Config {
7    pub rcon: RconConfig,
8    pub ai: Option<AiConfig>,
9    pub ollama: Option<OllamaConfig>,
10    #[serde(default)]
11    pub server: ServerConfig,
12    #[serde(default)]
13    pub backup: BackupConfig,
14    #[serde(default)]
15    pub notification: NotificationConfig,
16}
17
18#[derive(Debug, Deserialize, Clone)]
19pub struct RconConfig {
20    #[serde(default = "default_rcon_host")]
21    pub host: String,
22    #[serde(default = "default_rcon_port")]
23    pub port: u16,
24    pub password: String,
25}
26
27fn default_rcon_host() -> String { "127.0.0.1".to_string() }
28fn default_rcon_port() -> u16 { 25575 }
29
30#[derive(Debug, Deserialize, Clone)]
31pub struct ServerConfig {
32    #[serde(default = "default_jar")]
33    pub jar: String,
34    #[serde(default = "default_min_mem")]
35    pub min_mem: String,
36    #[serde(default = "default_max_mem")]
37    pub max_mem: String,
38    #[serde(default = "default_session_name")]
39    pub session_name: String,
40    #[serde(default = "default_log_file")]
41    pub log_file: String,
42}
43
44fn default_jar() -> String { "fabric-server.jar".to_string() }
45fn default_min_mem() -> String { "512M".to_string() }
46fn default_max_mem() -> String { "1G".to_string() }
47fn default_session_name() -> String { "mc_server".to_string() }
48fn default_log_file() -> String { "logs/latest.log".to_string() }
49
50impl Default for ServerConfig {
51    fn default() -> Self {
52        Self {
53            jar: default_jar(),
54            min_mem: default_min_mem(),
55            max_mem: default_max_mem(),
56            session_name: default_session_name(),
57            log_file: default_log_file(),
58        }
59    }
60}
61
62#[derive(Debug, Deserialize, Clone)]
63pub struct AiConfig {
64    pub api_url: String,
65    pub api_key: String,
66    #[serde(default = "default_model")]
67    pub model: String,
68    #[serde(default = "default_trigger")]
69    pub trigger: String,
70    #[serde(default = "default_max_tokens")]
71    pub max_tokens: u32,
72    #[serde(default = "default_temperature")]
73    pub temperature: f32,
74}
75
76fn default_model() -> String { "gpt-3.5-turbo".to_string() }
77fn default_trigger() -> String { "!".to_string() }
78fn default_max_tokens() -> u32 { 150 }
79fn default_temperature() -> f32 { 0.7 }
80
81#[derive(Debug, Deserialize, Clone)]
82pub struct OllamaConfig {
83    #[serde(default = "default_ollama_enabled")]
84    pub enabled: bool,
85    #[serde(default = "default_ollama_url")]
86    pub url: String,
87    #[serde(default = "default_ollama_model")]
88    pub model: String,
89}
90
91fn default_ollama_enabled() -> bool { false }
92fn default_ollama_url() -> String { "http://localhost:11434/api/generate".to_string() }
93fn default_ollama_model() -> String { "qwen:0.5b".to_string() }
94
95#[derive(Debug, Deserialize, Clone)]
96pub struct BackupConfig {
97    #[serde(default = "default_world_dir")]
98    pub world_dir: String,
99    #[serde(default = "default_backup_dest")]
100    pub backup_dest: String,
101    #[serde(default = "default_retain_days")]
102    pub retain_days: u32,
103}
104
105fn default_world_dir() -> String { "world".to_string() }
106fn default_backup_dest() -> String { "../backups".to_string() }
107fn default_retain_days() -> u32 { 7 }
108
109impl Default for BackupConfig {
110    fn default() -> Self {
111        Self {
112            world_dir: default_world_dir(),
113            backup_dest: default_backup_dest(),
114            retain_days: default_retain_days(),
115        }
116    }
117}
118
119#[derive(Debug, Deserialize, Clone)]
120pub struct NotificationConfig {
121    #[serde(default)]
122    pub telegram_bot_token: String,
123    #[serde(default)]
124    pub telegram_chat_id: String,
125    #[serde(default = "default_termux_notify")]
126    pub termux_notify: bool,
127}
128
129fn default_termux_notify() -> bool { true }
130
131impl Default for NotificationConfig {
132    fn default() -> Self {
133        Self {
134            telegram_bot_token: String::new(),
135            telegram_chat_id: String::new(),
136            termux_notify: default_termux_notify(),
137        }
138    }
139}
140
141impl Config {
142    pub fn load(path: &PathBuf) -> Result<Self> {
143        let content = std::fs::read_to_string(path)
144            .with_context(|| format!("Failed to read config file: {:?}", path))?;
145        
146        Self::load_from_str(&content)
147    }
148
149    pub fn load_from_str(content: &str) -> Result<Self> {
150        let mut config: Config = toml::from_str(content)
151            .with_context(|| "Failed to parse config file")?;
152        
153        if let Some(ref ai) = config.ai {
154            if ai.api_key.is_empty() || ai.api_url.is_empty() {
155                config.ai = None;
156            }
157        }
158        
159        Ok(config)
160    }
161
162    pub fn generate_template() -> String {
163        r#"# MC-Minder Configuration File
164# MC-Minder 配置文件
165
166# Server Configuration
167# 服务器配置
168[server]
169jar = "fabric-server.jar"
170min_mem = "512M"
171max_mem = "1G"
172session_name = "mc_server"
173log_file = "logs/latest.log"
174
175# RCON Configuration - Required for MC-Minder to communicate with Minecraft server
176# RCON 配置 - MC-Minder 与 Minecraft 服务器通信必需
177[rcon]
178host = "127.0.0.1"
179port = 25575
180password = "your_rcon_password"
181
182# AI Configuration - Leave empty or remove this section to disable AI features
183# AI 配置 - 留空或删除此部分可禁用 AI 功能
184[ai]
185api_url = ""
186api_key = ""
187model = "gpt-3.5-turbo"
188trigger = "!"
189max_tokens = 150
190temperature = 0.7
191
192# Ollama Configuration - Set enabled = true to use local AI
193# Ollama 配置 - 设置 enabled = true 使用本地 AI
194[ollama]
195enabled = false
196url = "http://localhost:11434/api/generate"
197model = "qwen:0.5b"
198
199# Backup Configuration
200# 备份配置
201[backup]
202world_dir = "world"
203backup_dest = "../backups"
204retain_days = 7
205
206# Notification Configuration - Leave empty to disable notifications
207# 通知配置 - 留空禁用通知功能
208[notification]
209telegram_bot_token = ""
210telegram_chat_id = ""
211termux_notify = true
212"#.to_string()
213    }
214}