mcvm_options/server/
mod.rs

1/// Writing to the server.properties file
2mod 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
17// I do not want to document all of these
18pub 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}