diff --git a/common/net/src/msg/server.rs b/common/net/src/msg/server.rs index d626017eaf..9bc05e3206 100644 --- a/common/net/src/msg/server.rs +++ b/common/net/src/msg/server.rs @@ -51,6 +51,7 @@ pub struct ServerInfo { pub git_hash: String, pub git_date: String, pub auth_provider: Option, + pub rules: Option, } /// Reponse To ClientType diff --git a/server/src/cmd.rs b/server/src/cmd.rs index a478ca4108..d4eca8ae8d 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -779,7 +779,7 @@ fn handle_motd( client, ServerGeneral::server_msg( ChatType::CommandInfo, - (*server.editable_settings().server_description).clone(), + server.editable_settings().server_description.motd.clone(), ), ); Ok(()) @@ -804,8 +804,8 @@ fn handle_set_motd( .editable_settings_mut() .server_description .edit(data_dir.as_ref(), |d| { - let info = format!("Server description set to {:?}", msg); - **d = msg; + let info = format!("Server message of the day set to {:?}", msg); + d.motd = msg; Some(info) }); drop(data_dir); @@ -819,8 +819,8 @@ fn handle_set_motd( .editable_settings_mut() .server_description .edit(data_dir.as_ref(), |d| { - d.clear(); - Some("Removed server description".to_string()) + d.motd.clear(); + Some("Removed server message of the day".to_string()) }); drop(data_dir); edit_setting_feedback(server, client, edit, || { diff --git a/server/src/lib.rs b/server/src/lib.rs index 071db2b428..5f17aec6e1 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -627,10 +627,11 @@ impl Server { let editable_settings = self.state.ecs().fetch::(); ServerInfo { name: settings.server_name.clone(), - description: (*editable_settings.server_description).clone(), + description: editable_settings.server_description.motd.clone(), git_hash: common::util::GIT_HASH.to_string(), git_date: common::util::GIT_DATE.to_string(), auth_provider: settings.auth_server_address.clone(), + rules: editable_settings.server_description.rules.clone(), } } diff --git a/server/src/settings.rs b/server/src/settings.rs index 011f4e32f3..3fe2f1653b 100644 --- a/server/src/settings.rs +++ b/server/src/settings.rs @@ -380,7 +380,7 @@ impl EditableSettings { let load = Self::load(data_dir); let mut server_description = ServerDescription::default(); - *server_description = "Who needs friends anyway?".into(); + server_description.motd = "Who needs friends anyway?".into(); let mut admins = Admins::default(); // TODO: Let the player choose if they want to use admin commands or not diff --git a/server/src/settings/server_description.rs b/server/src/settings/server_description.rs index cb4294df0a..fba5e9735f 100644 --- a/server/src/settings/server_description.rs +++ b/server/src/settings/server_description.rs @@ -12,20 +12,21 @@ use serde::{Deserialize, Serialize}; /// ServerDescription, the previously most recent module, and add a new module /// for the latest version! Please respect the migration upgrade guarantee /// found in the parent module with any upgrade. -pub use self::v1::*; +pub use self::v2::*; /// Versioned settings files, one per version (v0 is only here as an example; we /// do not expect to see any actual v0 settings files). #[derive(Deserialize, Serialize)] pub enum ServerDescriptionRaw { V0(v0::ServerDescription), - V1(ServerDescription), + V1(v1::ServerDescription), + V2(ServerDescription), } impl From for ServerDescriptionRaw { fn from(value: ServerDescription) -> Self { // Replace variant with that of current latest version. - Self::V1(value) + Self::V2(value) } } @@ -39,9 +40,10 @@ impl TryFrom for (Version, ServerDescription) { Ok(match value { // Old versions V0(value) => (Version::Old, value.try_into()?), + V1(value) => (Version::Old, value.try_into()?), // Latest version (move to old section using the pattern of other old version when it // is no longer latest). - V1(mut value) => (value.validate()?, value), + V2(mut value) => (value.validate()?, value), }) } } @@ -131,7 +133,6 @@ mod v1 { use crate::settings::editable::{EditableSetting, Version}; use core::ops::{Deref, DerefMut}; use serde::{Deserialize, Serialize}; - /* use super::v2 as next; */ #[derive(Clone, Deserialize, Serialize)] #[serde(transparent)] @@ -168,10 +169,67 @@ mod v1 { } } + use super::{v2 as next, MIGRATION_UPGRADE_GUARANTEE}; + impl TryFrom for Final { + type Error = ::Error; + + fn try_from(mut value: ServerDescription) -> Result { + value.validate()?; + Ok(next::ServerDescription::migrate(value) + .try_into() + .expect(MIGRATION_UPGRADE_GUARANTEE)) + } + } +} + +mod v2 { + use super::{v1 as prev, Final}; + use crate::settings::editable::{EditableSetting, Version}; + use serde::{Deserialize, Serialize}; + + #[derive(Clone, Deserialize, Serialize)] + pub struct ServerDescription { + pub motd: String, + pub rules: Option, + } + + impl Default for ServerDescription { + fn default() -> Self { + Self { + motd: "This is the best Veloren server".into(), + rules: None, + } + } + } + + impl ServerDescription { + /// One-off migration from the previous version. This must be + /// guaranteed to produce a valid settings file as long as it is + /// called with a valid settings file from the previous version. + pub(super) fn migrate(prev: prev::ServerDescription) -> Self { + Self { + motd: prev.0, + rules: None, + } + } + + /// Perform any needed validation on this server description that can't + /// be done using parsing. + /// + /// The returned version being "Old" indicates the loaded setting has + /// been modified during validation (this is why validate takes + /// `&mut self`). + pub(super) fn validate(&mut self) -> Result::Error> { + Ok(Version::Latest) + } + } + // NOTE: Whenever there is a version upgrade, copy this note as well as the // commented-out code below to the next version, then uncomment the code // for this version. - /* impl TryFrom for Final { + /* + use super::{v3 as next, MIGRATION_UPGRADE_GUARANTEE}; + impl TryFrom for Final { type Error = ::Error; fn try_from(mut value: ServerDescription) -> Result { diff --git a/server/src/sys/msg/character_screen.rs b/server/src/sys/msg/character_screen.rs index c6d68a434d..ccbed7802e 100644 --- a/server/src/sys/msg/character_screen.rs +++ b/server/src/sys/msg/character_screen.rs @@ -45,10 +45,10 @@ impl Sys { ) -> Result<(), crate::error::Error> { let mut send_join_messages = || -> Result<(), crate::error::Error> { // Give the player a welcome message - if !editable_settings.server_description.is_empty() { + if !editable_settings.server_description.motd.is_empty() { client.send(ServerGeneral::server_msg( ChatType::CommandInfo, - editable_settings.server_description.as_str(), + editable_settings.server_description.motd.as_str(), ))?; }