1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
use std::fmt::Display;

use serde::{Deserialize, Serialize};

/// A loader for Minecraft mods
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq, Default)]
#[serde(rename_all = "lowercase")]
pub enum Modloader {
	/// No loader, just the default game
	#[default]
	Vanilla,
	/// MinecraftForge
	Forge,
	/// NeoForged
	NeoForged,
	/// Fabric Loader
	Fabric,
	/// Quilt Loader
	Quilt,
	/// LiteLoader
	LiteLoader,
	/// Risugami's Modloader
	Risugamis,
	/// Rift
	Rift,
}

impl Display for Modloader {
	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
		match self {
			Self::Vanilla => write!(f, "None"),
			Self::Forge => write!(f, "Forge"),
			Self::NeoForged => write!(f, "NeoForged"),
			Self::Fabric => write!(f, "Fabric"),
			Self::Quilt => write!(f, "Quilt"),
			Self::LiteLoader => write!(f, "LiteLoader"),
			Self::Risugamis => write!(f, "Risugami's"),
			Self::Rift => write!(f, "Rift"),
		}
	}
}

/// Matcher for different types of loader
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ModloaderMatch {
	/// Matches vanilla
	Vanilla,
	/// Matches MinecraftForge
	Forge,
	/// Matches NeoForged
	NeoForged,
	/// Matches any loader that supports loading Forge mods
	ForgeLike,
	/// Matches Fabric Loader
	Fabric,
	/// Matches Quilt Loader
	Quilt,
	/// Matches any loader that supports loading Fabric mods
	FabricLike,
	/// Matches LiteLoader
	LiteLoader,
	/// Matches Risugami's Modloader
	Risugamis,
	/// Matches Rift
	Rift,
}

impl ModloaderMatch {
	/// Parse a ModloaderMatch from a string
	pub fn parse_from_str(string: &str) -> Option<Self> {
		match string {
			"vanilla" => Some(Self::Vanilla),
			"forge" => Some(Self::Forge),
			"neoforged" => Some(Self::NeoForged),
			"forgelike" => Some(Self::ForgeLike),
			"fabric" => Some(Self::Fabric),
			"quilt" => Some(Self::Quilt),
			"fabriclike" => Some(Self::FabricLike),
			"liteloader" => Some(Self::LiteLoader),
			"risugamis" => Some(Self::Risugamis),
			"rift" => Some(Self::Rift),
			_ => None,
		}
	}

	/// Checks if a modloader matches
	pub fn matches(&self, other: &Modloader) -> bool {
		match self {
			Self::Vanilla => matches!(other, Modloader::Vanilla),
			Self::Forge => matches!(other, Modloader::Forge),
			Self::NeoForged => matches!(other, Modloader::NeoForged),
			Self::ForgeLike => matches!(other, Modloader::Forge | Modloader::NeoForged),
			Self::Fabric => matches!(other, Modloader::Fabric),
			Self::Quilt => matches!(other, Modloader::Quilt),
			Self::FabricLike => matches!(other, Modloader::Fabric | Modloader::Quilt),
			Self::LiteLoader => matches!(other, Modloader::LiteLoader),
			Self::Risugamis => matches!(other, Modloader::Risugamis),
			Self::Rift => matches!(other, Modloader::Rift),
		}
	}
}

/// Different types of server changes. These are mostly mutually exclusive.
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Default)]
#[serde(rename_all = "lowercase")]
pub enum ServerType {
	/// Unspecified. Usually inherits from something else
	#[default]
	None,
	/// No modifications, just the default game
	Vanilla,
	/// Paper server
	Paper,
	/// SpongeVanilla
	Sponge,
	/// SpongeForge
	SpongeForge,
	/// CraftBukkit
	CraftBukkit,
	/// Spigot
	Spigot,
	/// Glowstone
	Glowstone,
	/// Pufferfish
	Pufferfish,
	/// Purpur
	Purpur,
	/// Folia
	Folia,
	/// MinecraftForge
	Forge,
	/// NeoForged
	NeoForged,
	/// Fabric Loader
	Fabric,
	/// Quilt Loader
	Quilt,
	/// Risugami's Modloader
	Risugamis,
	/// Rift
	Rift,
}

impl Display for ServerType {
	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
		match self {
			Self::None => write!(f, "Vanilla"),
			Self::Vanilla => write!(f, "Vanilla"),
			Self::Paper => write!(f, "Paper"),
			Self::Sponge => write!(f, "Sponge"),
			Self::SpongeForge => write!(f, "SpongeForge"),
			Self::CraftBukkit => write!(f, "CraftBukkit"),
			Self::Spigot => write!(f, "Spigot"),
			Self::Glowstone => write!(f, "Glowstone"),
			Self::Pufferfish => write!(f, "Pufferfish"),
			Self::Purpur => write!(f, "Purpur"),
			Self::Folia => write!(f, "Folia"),
			Self::Forge => write!(f, "Forge"),
			Self::NeoForged => write!(f, "NeoForged"),
			Self::Fabric => write!(f, "Fabric"),
			Self::Quilt => write!(f, "Quilt"),
			Self::Risugamis => write!(f, "Risugami's"),
			Self::Rift => write!(f, "Rift"),
		}
	}
}

/// Matcher for different types of server plugin loaders
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum PluginLoaderMatch {
	/// The default game with no plugin support
	Vanilla,
	/// Matches any server that can load Bukkit plugins
	Bukkit,
	/// Matches Paper server
	Paper,
	/// Matches Sponge
	Sponge,
	/// Matches CraftBukkit
	CraftBukkit,
	/// Matches Spigot
	Spigot,
	/// Matches Glowstone
	Glowstone,
	/// Matches Pufferfish
	Pufferfish,
	/// Matches Purpur
	Purpur,
	/// Matches Folia
	Folia,
}

impl PluginLoaderMatch {
	/// Parse a PluginLoaderMatch from a string
	pub fn parse_from_str(string: &str) -> Option<Self> {
		match string {
			"vanilla" => Some(Self::Vanilla),
			"bukkit" => Some(Self::Bukkit),
			"paper" => Some(Self::Paper),
			"sponge" => Some(Self::Sponge),
			"craftbukkit" => Some(Self::CraftBukkit),
			"spigot" => Some(Self::Spigot),
			"glowstone" => Some(Self::Glowstone),
			"pufferfish" => Some(Self::Pufferfish),
			"purpur" => Some(Self::Purpur),
			"folia" => Some(Self::Folia),
			_ => None,
		}
	}

	/// Checks if a plugin loader matches
	pub fn matches(&self, other: &ServerType) -> bool {
		match self {
			Self::Vanilla => matches!(other, ServerType::Vanilla),
			Self::Bukkit => matches!(
				other,
				ServerType::Paper
					| ServerType::CraftBukkit
					| ServerType::Spigot | ServerType::Glowstone
					| ServerType::Pufferfish
					| ServerType::Purpur
			),
			Self::Paper => matches!(other, ServerType::Paper),
			Self::Sponge => matches!(other, ServerType::Sponge | ServerType::SpongeForge),
			Self::CraftBukkit => matches!(other, ServerType::CraftBukkit),
			Self::Spigot => matches!(other, ServerType::Spigot),
			Self::Glowstone => matches!(other, ServerType::Glowstone),
			Self::Pufferfish => matches!(other, ServerType::Pufferfish),
			Self::Purpur => matches!(other, ServerType::Purpur),
			Self::Folia => matches!(other, ServerType::Folia),
		}
	}
}

/// Different modifications for the client. Mostly mututally exclusive
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Default)]
#[serde(rename_all = "lowercase")]
pub enum ClientType {
	/// Unspecified. Usually inherits from something else
	#[default]
	None,
	/// No modifications, just the default game
	Vanilla,
	/// MinecraftForge
	Forge,
	/// NeoForged
	NeoForged,
	/// Fabric Loader
	Fabric,
	/// Quilt Loader
	Quilt,
	/// LiteLoader
	LiteLoader,
	/// Risugami's Modloader
	Risugamis,
	/// Rift
	Rift,
}

impl Display for ClientType {
	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
		match self {
			Self::None => write!(f, "Vanilla"),
			Self::Vanilla => write!(f, "Vanilla"),
			Self::Forge => write!(f, "Forge"),
			Self::NeoForged => write!(f, "NeoForged"),
			Self::Fabric => write!(f, "Fabric"),
			Self::Quilt => write!(f, "Quilt"),
			Self::LiteLoader => write!(f, "LiteLoader"),
			Self::Risugamis => write!(f, "Risugami's"),
			Self::Rift => write!(f, "Rift"),
		}
	}
}