Added MOTD on login, MOTD editing

This commit is contained in:
Joshua Barretto 2020-06-25 13:07:01 +01:00
parent b46e080ade
commit 83a96c24ec
4 changed files with 78 additions and 20 deletions

View File

@ -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",

View File

@ -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::<ServerSettings>()
.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,

View File

@ -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");
}

View File

@ -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 => {},