From 83a96c24ec446404e08c6c3534049cbd654fd9f6 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Thu, 25 Jun 2020 13:07:01 +0100 Subject: [PATCH] Added MOTD on login, MOTD editing --- common/src/cmd.rs | 4 +++ server/src/cmd.rs | 30 ++++++++++++++++++- server/src/lib.rs | 3 +- server/src/sys/message.rs | 61 ++++++++++++++++++++++++++++----------- 4 files changed, 78 insertions(+), 20 deletions(-) diff --git a/common/src/cmd.rs b/common/src/cmd.rs index 4a803c7c5d..97284b4237 100644 --- a/common/src/cmd.rs +++ b/common/src/cmd.rs @@ -43,6 +43,7 @@ pub enum ChatCommand { KillNpcs, Lantern, Light, + Motd, Object, Players, RemoveLights, @@ -74,6 +75,7 @@ pub static CHAT_COMMANDS: &[ChatCommand] = &[ ChatCommand::KillNpcs, ChatCommand::Lantern, ChatCommand::Light, + ChatCommand::Motd, ChatCommand::Object, ChatCommand::Players, ChatCommand::RemoveLights, @@ -224,6 +226,7 @@ impl ChatCommand { "Spawn entity with light", true, ), + ChatCommand::Motd => cmd(vec![Message], "Set the server description", true), ChatCommand::Object => cmd( vec![Enum("object", OBJECTS.clone(), Required)], "Spawn an object", @@ -295,6 +298,7 @@ impl ChatCommand { ChatCommand::KillNpcs => "kill_npcs", ChatCommand::Lantern => "lantern", ChatCommand::Light => "light", + ChatCommand::Motd => "motd", ChatCommand::Object => "object", ChatCommand::Players => "players", ChatCommand::RemoveLights => "remove_lights", diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 8e1d17197d..ced1a459ab 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -2,7 +2,7 @@ //! To implement a new command, add an instance of `ChatCommand` to //! `CHAT_COMMANDS` and provide a handler function. -use crate::{Server, StateExt}; +use crate::{Server, ServerSettings, StateExt}; use chrono::{NaiveTime, Timelike}; use common::{ assets, @@ -78,6 +78,7 @@ fn get_handler(cmd: &ChatCommand) -> CommandHandler { ChatCommand::KillNpcs => handle_kill_npcs, ChatCommand::Lantern => handle_lantern, ChatCommand::Light => handle_light, + ChatCommand::Motd => handle_motd, ChatCommand::Object => handle_object, ChatCommand::Players => handle_players, ChatCommand::RemoveLights => handle_remove_lights, @@ -168,6 +169,33 @@ fn handle_give_item( } } +fn handle_motd( + server: &mut Server, + client: EcsEntity, + _target: EcsEntity, + args: String, + action: &ChatCommand, +) { + match scan_fmt!(&args, &action.arg_fmt(), String) { + Ok(msg) => { + server + .state_mut() + .ecs_mut() + .fetch_mut::() + .server_description = msg.clone(); + server.server_info.description = msg.clone(); + server.notify_client( + client, + ServerMsg::private(format!("Server description set to \"{}\"", msg)), + ); + }, + Err(_) => server.notify_client( + client, + ServerMsg::broadcast(format!("{}", server.server_info.description)), + ), + } +} + fn handle_jump( server: &mut Server, client: EcsEntity, diff --git a/server/src/lib.rs b/server/src/lib.rs index 5e357bc547..eb302c4a44 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -251,8 +251,7 @@ impl Server { // Run pending DB migrations (if any) debug!("Running DB migrations..."); - if let Some(e) = persistence::run_migrations(&settings.persistence_db_dir).err() - { + if let Some(e) = persistence::run_migrations(&settings.persistence_db_dir).err() { info!(?e, "Migration error"); } diff --git a/server/src/sys/message.rs b/server/src/sys/message.rs index e836878cfc..7194e0d851 100644 --- a/server/src/sys/message.rs +++ b/server/src/sys/message.rs @@ -16,8 +16,8 @@ use common::{ }, state::{BlockChange, Time}, sync::Uid, - terrain::{Block, TerrainGrid, TerrainChunkSize}, - vol::{Vox, RectVolSize}, + terrain::{Block, TerrainChunkSize, TerrainGrid}, + vol::{RectVolSize, Vox}, }; use hashbrown::HashMap; use specs::{ @@ -159,7 +159,8 @@ impl<'a> System<'a> for Sys { Ok((username, uuid)) => (username, uuid), }; - let vd = view_distance.map(|vd| vd.min(settings.max_view_distance.unwrap_or(vd))); + let vd = view_distance + .map(|vd| vd.min(settings.max_view_distance.unwrap_or(vd))); let player = Player::new(username, None, vd, uuid); if !player.is_valid() { @@ -191,22 +192,36 @@ impl<'a> System<'a> for Sys { // Limit view distance if it's too high // This comes after state registration so that the client actually hears it - if settings.max_view_distance.zip(view_distance).map(|(vd, max)| vd > max).unwrap_or(false) { - client.notify(ServerMsg::SetViewDistance(settings.max_view_distance.unwrap_or(0))); + if settings + .max_view_distance + .zip(view_distance) + .map(|(vd, max)| vd > max) + .unwrap_or(false) + { + client.notify(ServerMsg::SetViewDistance( + settings.max_view_distance.unwrap_or(0), + )); }; }, ClientMsg::SetViewDistance(view_distance) => match client.client_state { ClientState::Character { .. } => { - if settings.max_view_distance.map(|max| view_distance <= max).unwrap_or(true) { - players - .get_mut(entity) - .map(|player| player.view_distance = Some( - settings.max_view_distance + if settings + .max_view_distance + .map(|max| view_distance <= max) + .unwrap_or(true) + { + players.get_mut(entity).map(|player| { + player.view_distance = Some( + settings + .max_view_distance .map(|max| view_distance.min(max)) - .unwrap_or(view_distance) - )); + .unwrap_or(view_distance), + ) + }); } else { - client.notify(ServerMsg::SetViewDistance(settings.max_view_distance.unwrap_or(0))); + client.notify(ServerMsg::SetViewDistance( + settings.max_view_distance.unwrap_or(0), + )); } }, _ => {}, @@ -232,6 +247,14 @@ impl<'a> System<'a> for Sys { character_id, }); + // Give the player a welcome message + if settings.server_description.len() > 0 { + client.notify(ServerMsg::broadcast(format!( + "{}", + settings.server_description + ))); + } + // Only send login message if it wasn't already // sent previously if !client.login_msg_sent { @@ -345,7 +368,11 @@ impl<'a> System<'a> for Sys { players.get(entity).and_then(|p| p.view_distance), positions.get(entity), ) { - pos.0.xy().map(|e| e as f64).distance(key.map(|e| e as f64 + 0.5) * TerrainChunkSize::RECT_SIZE.map(|e| e as f64)) < (view_distance as f64 + 1.0) * TerrainChunkSize::RECT_SIZE.x as f64 + pos.0.xy().map(|e| e as f64).distance( + key.map(|e| e as f64 + 0.5) + * TerrainChunkSize::RECT_SIZE.map(|e| e as f64), + ) < (view_distance as f64 + 1.5) + * TerrainChunkSize::RECT_SIZE.x as f64 } else { true }; @@ -357,10 +384,10 @@ impl<'a> System<'a> for Sys { chunk: Ok(Box::new(chunk.clone())), }) }, - None => server_emitter.emit(ServerEvent::ChunkRequest(entity, key)), + None => { + server_emitter.emit(ServerEvent::ChunkRequest(entity, key)) + }, } - } else { - warn!("Not in VD!"); } }, ClientState::Pending => {},