Pumpkin/pumpkin/src/config/mod.rs
2024-08-31 19:27:06 +02:00

237 lines
7.3 KiB
Rust

use std::path::Path;
use auth_config::AuthenticationConfig;
use proxy::ProxyConfig;
use resource_pack::ResourcePackConfig;
use serde::{Deserialize, Serialize};
use crate::{entity::player::GameMode, server::Difficulty};
pub mod auth_config;
pub mod proxy;
pub mod resource_pack;
/// Current Config version of the Base Config
const CURRENT_BASE_VERSION: &str = "1.0.0";
/// The idea is that Pumpkin should very customizable.
/// You can Enable or Disable Features depending on your needs.
///
/// This also allows you get some Performance or Resource boosts.
/// Important: The Configuration should match Vanilla by default
#[derive(Deserialize, Serialize)]
pub struct AdvancedConfiguration {
pub proxy: ProxyConfig,
pub authentication: AuthenticationConfig,
pub packet_compression: CompressionConfig,
pub resource_pack: ResourcePackConfig,
pub commands: CommandsConfig,
pub rcon: RCONConfig,
pub pvp: PVPConfig,
}
#[derive(Deserialize, Serialize, Clone)]
pub struct RCONConfig {
pub enabled: bool,
pub ip: String,
pub port: u16,
pub password: String,
}
impl Default for RCONConfig {
fn default() -> Self {
Self {
enabled: false,
ip: "0.0.0.0".to_string(),
port: 25575,
password: "".to_string(),
}
}
}
#[derive(Deserialize, Serialize)]
pub struct CommandsConfig {
/// Are commands from the Console accepted ?
pub use_console: bool,
// TODO: commands...
}
impl Default for CommandsConfig {
fn default() -> Self {
Self { use_console: true }
}
}
#[derive(Deserialize, Serialize)]
pub struct PVPConfig {
/// Is PVP enabled ?
pub enabled: bool,
/// Do we want to have the Red hurt animation & fov bobbing
pub hurt_animation: bool,
/// Should players in creative be protected against PVP
pub protect_creative: bool,
/// Has PVP Knockback?
pub knockback: bool,
/// Should player swing when attacking?
pub swing: bool,
}
impl Default for PVPConfig {
fn default() -> Self {
Self {
enabled: true,
hurt_animation: true,
protect_creative: true,
knockback: true,
swing: true,
}
}
}
#[derive(Deserialize, Serialize)]
// Packet compression
pub struct CompressionConfig {
/// Is compression enabled ?
pub enabled: bool,
/// The compression threshold used when compression is enabled
pub compression_threshold: u32,
/// A value between 0..9
/// 1 = Optimize for the best speed of encoding.
/// 9 = Optimize for the size of data being encoded.
pub compression_level: u32,
}
impl Default for CompressionConfig {
fn default() -> Self {
Self {
enabled: true,
compression_threshold: 256,
compression_level: 4,
}
}
}
/// Important: The Configuration should match Vanilla by default
impl Default for AdvancedConfiguration {
fn default() -> Self {
Self {
proxy: ProxyConfig::default(),
authentication: AuthenticationConfig::default(),
commands: CommandsConfig::default(),
packet_compression: CompressionConfig::default(),
resource_pack: ResourcePackConfig::default(),
rcon: RCONConfig::default(),
pvp: PVPConfig::default(),
}
}
}
#[derive(Serialize, Deserialize)]
pub struct BasicConfiguration {
/// A version identifier for the configuration format.
pub config_version: String,
/// The address to bind the server to.
pub server_address: String,
/// The port to listen on.
pub server_port: u16,
/// The seed for world generation.
pub seed: String,
/// The maximum number of players allowed on the server.
pub max_players: u32,
/// The maximum view distance for players.
pub view_distance: u8,
/// The maximum simulated view distance.
pub simulation_distance: u8,
/// The default game difficulty.
pub default_difficulty: Difficulty,
/// Whether the Nether dimension is enabled.
pub allow_nether: bool,
/// Whether the server is in hardcore mode.
pub hardcore: bool,
/// Whether online mode is enabled. Requires valid Minecraft accounts.
pub online_mode: bool,
/// Whether packet encryption is enabled. Required when online mode is enabled.
pub encryption: bool,
/// The server's description displayed on the status screen.
pub motd: String,
/// The default game mode for players.
pub default_gamemode: GameMode,
}
impl Default for BasicConfiguration {
fn default() -> Self {
Self {
config_version: CURRENT_BASE_VERSION.to_string(),
server_address: "0.0.0.0".to_string(),
server_port: 25565,
seed: "".to_string(),
max_players: 100000,
view_distance: 10,
simulation_distance: 10,
default_difficulty: Difficulty::Normal,
allow_nether: true,
hardcore: false,
online_mode: true,
encryption: true,
motd: "A Blazing fast Pumpkin Server!".to_string(),
default_gamemode: GameMode::Survival,
}
}
}
impl AdvancedConfiguration {
pub fn load<P: AsRef<Path>>(path: P) -> AdvancedConfiguration {
if path.as_ref().exists() {
let toml = std::fs::read_to_string(path).expect("Couldn't read configuration");
let config: AdvancedConfiguration =
toml::from_str(toml.as_str()).expect("Couldn't parse features.toml, Probably old config, Replacing with a new one or just delete it");
config.validate();
config
} else {
let config = AdvancedConfiguration::default();
let toml = toml::to_string(&config).expect("Couldn't create toml!");
std::fs::write(path, toml).expect("Couldn't save configuration");
config.validate();
config
}
}
pub fn validate(&self) {
self.resource_pack.validate()
}
}
impl BasicConfiguration {
pub fn load<P: AsRef<Path>>(path: P) -> BasicConfiguration {
if path.as_ref().exists() {
let toml = std::fs::read_to_string(path).expect("Couldn't read configuration");
let config: BasicConfiguration = toml::from_str(toml.as_str()).expect("Couldn't parse configuration.toml, Probably old config, Replacing with a new one or just delete it");
config.validate();
config
} else {
let config = BasicConfiguration::default();
let toml = toml::to_string(&config).expect("Couldn't create toml!");
std::fs::write(path, toml).expect("Couldn't save configuration");
config.validate();
config
}
}
pub fn validate(&self) {
assert_eq!(
self.config_version, CURRENT_BASE_VERSION,
"Config version does not match used Config version. Please update your config"
);
assert!(self.view_distance >= 2, "View distance must be at least 2");
assert!(
self.view_distance <= 32,
"View distance must be less than 32"
);
if self.online_mode {
assert!(
self.encryption,
"When Online Mode is enabled, Encryption must be enabled"
)
}
}
}