1mod file;
3
4use mcvm_shared::util::{DefaultExt, ToInt};
5
6pub use file::create_keys;
7pub use file::get_world_name;
8pub use file::write_server_properties;
9
10use std::collections::HashMap;
11use std::fmt::Display;
12
13use serde::{Deserialize, Serialize};
14
15use super::read::{EnumOrNumber, EnumOrString};
16
17pub use deser::*;
19#[allow(missing_docs)]
20pub mod deser {
21 #[cfg(feature = "schema")]
22 use schemars::JsonSchema;
23
24 use super::*;
25
26 #[derive(Deserialize, Serialize, Debug, Clone, Default)]
27 #[cfg_attr(feature = "schema", derive(JsonSchema))]
28 #[serde(default)]
29 pub struct ServerOptions {
30 #[serde(skip_serializing_if = "DefaultExt::is_default")]
31 pub rcon: RconOptions,
32 #[serde(skip_serializing_if = "DefaultExt::is_default")]
33 pub query: QueryOptions,
34 #[serde(skip_serializing_if = "DefaultExt::is_default")]
35 pub whitelist: WhitelistOptions,
36 #[serde(skip_serializing_if = "DefaultExt::is_default")]
37 pub gamemode: GamemodeOptions,
38 #[serde(skip_serializing_if = "DefaultExt::is_default")]
39 pub datapacks: DatapacksOptions,
40 #[serde(skip_serializing_if = "DefaultExt::is_default")]
41 pub world: WorldOptions,
42 #[serde(skip_serializing_if = "DefaultExt::is_default")]
43 pub resource_pack: ResourcePackOptions,
44 #[serde(skip_serializing_if = "HashMap::is_empty")]
45 pub custom: HashMap<String, String>,
46 #[serde(skip_serializing_if = "Option::is_none")]
47 pub allow_flight: Option<bool>,
48 #[serde(skip_serializing_if = "Option::is_none")]
49 pub broadcast_console_to_ops: Option<bool>,
50 #[serde(skip_serializing_if = "Option::is_none")]
51 pub broadcast_rcon_to_ops: Option<bool>,
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub difficulty: Option<EnumOrNumber<Difficulty>>,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub allow_command_blocks: Option<bool>,
56 #[serde(skip_serializing_if = "Option::is_none")]
57 pub jmx_monitoring: Option<bool>,
58 #[serde(skip_serializing_if = "Option::is_none")]
59 pub enable_status: Option<bool>,
60 #[serde(skip_serializing_if = "Option::is_none")]
61 pub enforce_secure_profile: Option<bool>,
62 #[serde(skip_serializing_if = "Option::is_none")]
63 pub entity_broadcast_range: Option<u16>,
64 #[serde(skip_serializing_if = "Option::is_none")]
65 pub hardcore: Option<bool>,
66 #[serde(skip_serializing_if = "Option::is_none")]
67 pub hide_online_players: Option<bool>,
68 #[serde(skip_serializing_if = "Option::is_none")]
69 pub max_chained_neighbor_updates: Option<i32>,
70 #[serde(skip_serializing_if = "Option::is_none")]
71 pub max_players: Option<u32>,
72 #[serde(skip_serializing_if = "Option::is_none")]
73 pub max_tick_time: Option<u64>,
74 #[serde(skip_serializing_if = "Option::is_none")]
75 pub motd: Option<String>,
76 #[serde(skip_serializing_if = "Option::is_none")]
77 pub network_compression_threshold: Option<EnumOrNumber<NetworkCompression>>,
78 #[serde(skip_serializing_if = "Option::is_none")]
79 pub offline_mode: Option<bool>,
80 #[serde(skip_serializing_if = "Option::is_none")]
81 pub op_permission_level: Option<u8>,
82 #[serde(skip_serializing_if = "Option::is_none")]
83 pub player_idle_timeout: Option<u32>,
84 #[serde(skip_serializing_if = "Option::is_none")]
85 pub prevent_proxy_connections: Option<bool>,
86 #[serde(skip_serializing_if = "Option::is_none")]
87 pub enable_chat_preview: Option<bool>,
88 #[serde(skip_serializing_if = "Option::is_none")]
89 pub enable_pvp: Option<bool>,
90 #[serde(skip_serializing_if = "Option::is_none")]
91 pub rate_limit: Option<i16>,
92 #[serde(skip_serializing_if = "Option::is_none")]
93 pub ip: Option<String>,
94 #[serde(skip_serializing_if = "Option::is_none")]
95 pub port: Option<u16>,
96 #[serde(skip_serializing_if = "Option::is_none")]
97 pub simulation_distance: Option<u8>,
98 #[serde(skip_serializing_if = "Option::is_none")]
99 pub enable_snooper: Option<bool>,
100 #[serde(skip_serializing_if = "Option::is_none")]
101 pub spawn_animals: Option<bool>,
102 #[serde(skip_serializing_if = "Option::is_none")]
103 pub spawn_monsters: Option<bool>,
104 #[serde(skip_serializing_if = "Option::is_none")]
105 pub spawn_npcs: Option<bool>,
106 #[serde(skip_serializing_if = "Option::is_none")]
107 pub spawn_protection: Option<u32>,
108 #[serde(skip_serializing_if = "Option::is_none")]
109 pub sync_chunk_writes: Option<bool>,
110 #[serde(skip_serializing_if = "Option::is_none")]
111 pub use_native_transport: Option<bool>,
112 #[serde(skip_serializing_if = "Option::is_none")]
113 pub view_distance: Option<u8>,
114 }
115
116 #[derive(Deserialize, Serialize, Debug, Clone, Default, PartialEq)]
117 #[cfg_attr(feature = "schema", derive(JsonSchema))]
118 #[serde(default)]
119 pub struct RconOptions {
120 #[serde(skip_serializing_if = "Option::is_none")]
121 pub enable: Option<bool>,
122 #[serde(skip_serializing_if = "Option::is_none")]
123 pub port: Option<u16>,
124 #[serde(skip_serializing_if = "Option::is_none")]
125 pub password: Option<String>,
126 }
127
128 #[derive(Deserialize, Serialize, Debug, Clone, Default, PartialEq)]
129 #[cfg_attr(feature = "schema", derive(JsonSchema))]
130 #[serde(default)]
131 pub struct QueryOptions {
132 #[serde(skip_serializing_if = "Option::is_none")]
133 pub enable: Option<bool>,
134 #[serde(skip_serializing_if = "Option::is_none")]
135 pub port: Option<u16>,
136 }
137
138 #[derive(Deserialize, Serialize, Debug, Clone, Default, PartialEq)]
139 #[cfg_attr(feature = "schema", derive(JsonSchema))]
140 #[serde(default)]
141 pub struct WhitelistOptions {
142 #[serde(skip_serializing_if = "Option::is_none")]
143 pub enable: Option<bool>,
144 #[serde(skip_serializing_if = "Option::is_none")]
145 pub enforce: Option<bool>,
146 }
147
148 #[derive(Deserialize, Serialize, Debug, Clone, Default, PartialEq)]
149 #[cfg_attr(feature = "schema", derive(JsonSchema))]
150 #[serde(default)]
151 pub struct GamemodeOptions {
152 #[serde(skip_serializing_if = "Option::is_none")]
153 pub default: Option<EnumOrNumber<GameMode>>,
154 #[serde(skip_serializing_if = "Option::is_none")]
155 pub force: Option<bool>,
156 }
157
158 #[derive(Deserialize, Serialize, Debug, Clone, Default, PartialEq)]
159 #[cfg_attr(feature = "schema", derive(JsonSchema))]
160 #[serde(default)]
161 pub struct DatapacksOptions {
162 #[serde(skip_serializing_if = "Option::is_none")]
163 pub function_permission_level: Option<u8>,
164 #[serde(skip_serializing_if = "Option::is_none")]
165 pub initial_enabled: Option<Vec<String>>,
166 #[serde(skip_serializing_if = "Option::is_none")]
167 pub initial_disabled: Option<Vec<String>>,
168 }
169
170 #[derive(Deserialize, Serialize, Debug, Clone, Default, PartialEq)]
171 #[cfg_attr(feature = "schema", derive(JsonSchema))]
172 #[serde(default)]
173 pub struct WorldOptions {
174 #[serde(skip_serializing_if = "Option::is_none")]
175 pub name: Option<String>,
176 #[serde(skip_serializing_if = "Option::is_none")]
177 pub seed: Option<String>,
178 #[serde(skip_serializing_if = "Option::is_none")]
179 pub r#type: Option<EnumOrString<WorldType>>,
180 #[serde(skip_serializing_if = "Option::is_none")]
181 pub structures: Option<bool>,
182 #[serde(skip_serializing_if = "Option::is_none")]
183 pub generator_settings: Option<serde_json::Map<String, serde_json::Value>>,
184 #[serde(skip_serializing_if = "Option::is_none")]
185 pub max_size: Option<u32>,
186 #[serde(skip_serializing_if = "Option::is_none")]
187 pub max_build_height: Option<u32>,
188 #[serde(skip_serializing_if = "Option::is_none")]
189 pub allow_nether: Option<bool>,
190 }
191
192 #[derive(Deserialize, Serialize, Debug, Clone, Default, PartialEq)]
193 #[cfg_attr(feature = "schema", derive(JsonSchema))]
194 #[serde(default)]
195 pub struct ResourcePackOptions {
196 #[serde(skip_serializing_if = "Option::is_none")]
197 pub uri: Option<String>,
198 #[serde(skip_serializing_if = "Option::is_none")]
199 pub prompt: Option<String>,
200 #[serde(skip_serializing_if = "Option::is_none")]
201 pub sha1: Option<String>,
202 #[serde(skip_serializing_if = "Option::is_none")]
203 pub required: Option<bool>,
204 }
205
206 #[derive(Deserialize, Serialize, Debug, Clone)]
207 #[cfg_attr(feature = "schema", derive(JsonSchema))]
208 #[serde(rename_all = "snake_case")]
209 pub enum Difficulty {
210 Peaceful,
211 Easy,
212 Normal,
213 Hard,
214 }
215
216 impl Display for Difficulty {
217 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
218 write!(
219 f,
220 "{}",
221 match self {
222 Self::Peaceful => "peaceful",
223 Self::Easy => "easy",
224 Self::Normal => "normal",
225 Self::Hard => "hard",
226 }
227 )
228 }
229 }
230
231 impl ToInt for Difficulty {
232 fn to_int(&self) -> i32 {
233 self.clone() as i32
234 }
235 }
236
237 #[derive(Deserialize, Serialize, Debug, Clone, PartialEq)]
238 #[cfg_attr(feature = "schema", derive(JsonSchema))]
239 #[serde(rename_all = "snake_case")]
240 pub enum GameMode {
241 Survival,
242 Creative,
243 Adventure,
244 Spectator,
245 }
246
247 impl Display for GameMode {
248 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
249 write!(
250 f,
251 "{}",
252 match self {
253 Self::Survival => "survival",
254 Self::Creative => "creative",
255 Self::Adventure => "adventure",
256 Self::Spectator => "spectator",
257 }
258 )
259 }
260 }
261
262 impl ToInt for GameMode {
263 fn to_int(&self) -> i32 {
264 self.clone() as i32
265 }
266 }
267
268 #[derive(Deserialize, Serialize, Debug, Clone, PartialEq)]
269 #[cfg_attr(feature = "schema", derive(JsonSchema))]
270 #[serde(rename_all = "snake_case")]
271 pub enum WorldType {
272 Normal,
273 Flat,
274 LargeBiomes,
275 Amplified,
276 SingleBiome,
277 Buffet,
278 Custom,
279 }
280
281 impl Display for WorldType {
282 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
283 write!(
284 f,
285 "{}",
286 match self {
287 WorldType::Normal => "minecraft:normal",
288 WorldType::Flat => "minecraft:flat",
289 WorldType::LargeBiomes => "miecraft:large_biomes",
290 WorldType::Amplified => "minecraft:amplified",
291 WorldType::SingleBiome => "minecraft:single_biome_surface",
292 WorldType::Buffet => "buffet",
293 WorldType::Custom => "customized",
294 }
295 )
296 }
297 }
298
299 #[derive(Deserialize, Serialize, Debug, Clone)]
300 #[cfg_attr(feature = "schema", derive(JsonSchema))]
301 #[serde(rename_all = "snake_case")]
302 pub enum NetworkCompression {
303 Disabled,
304 All,
305 }
306
307 impl ToInt for NetworkCompression {
308 fn to_int(&self) -> i32 {
309 self.clone() as i32
310 }
311 }
312}