diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 9e188e152a..0af600c39c 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -26,6 +26,7 @@ use world::util::Sampler; use scan_fmt::{scan_fmt, scan_fmt_some}; use tracing::error; +use crate::login_provider::LoginProvider; pub trait ChatCommandExt { fn execute(&self, server: &mut Server, entity: EcsEntity, args: String); @@ -1870,34 +1871,42 @@ fn handle_ban( scan_fmt_some!(&args, &action.arg_fmt(), String, String) { let reason = reason_opt.unwrap_or_default(); + let uuid_result = server.state.ecs().read_resource::().username_to_uuid(&target_alias); - if server.settings().banlist.contains_key(&target_alias) { - server.notify_client( - client, - ChatType::CommandError - .server_msg(format!("{} is already on the banlist", target_alias)), - ) - } else { - server.settings_mut().edit(|s| { - s.banlist.insert(target_alias.clone(), reason.clone()); - }); - server.notify_client( - client, - ChatType::CommandInfo.server_msg(format!( - "Added {} to the banlist with reason: {}", - target_alias, reason - )), - ); + if let Ok(uuid) = uuid_result { + if server.settings().banlist.contains_key(&uuid) { + server.notify_client( + client, + ChatType::CommandError + .server_msg(format!("{} is already on the banlist", target_alias)), + ) + } else { + server.settings_mut().edit(|s| { + s.banlist.insert(uuid, (target_alias.clone(), reason.clone())); + }); + server.notify_client( + client, + ChatType::CommandInfo.server_msg(format!( + "Added {} to the banlist with reason: {}", + target_alias, reason + )), + ); - // If the player is online kick them - let ecs = server.state.ecs(); - let target_player_opt = (&ecs.entities(), &ecs.read_storage::()) - .join() - .find(|(_, player)| player.alias == target_alias) - .map(|(entity, _)| entity); - if let Some(target_player) = target_player_opt { - kick_player(server, target_player, &reason); + // If the player is online kick them + let ecs = server.state.ecs(); + let target_player_opt = (&ecs.entities(), &ecs.read_storage::()) + .join() + .find(|(_, player)| player.alias == target_alias) + .map(|(entity, _)| entity); + if let Some(target_player) = target_player_opt { + kick_player(server, target_player, &reason); + } } + } else { + server.notify_client( + client, + ChatType::CommandError.server_msg(format!("Unable to determine UUID for username \"{}\"", target_alias)) + ) } } else { server.notify_client( @@ -1915,13 +1924,23 @@ fn handle_unban( action: &ChatCommand, ) { if let Ok(username) = scan_fmt!(&args, &action.arg_fmt(), String) { - server.settings_mut().edit(|s| { - s.banlist.remove(&username); - }); - server.notify_client( - client, - ChatType::CommandInfo.server_msg(format!("{} was successfully unbanned", username)), - ); + let uuid_result = server.state.ecs().read_resource::().username_to_uuid(&username); + + if let Ok(uuid) = uuid_result { + server.settings_mut().edit(|s| { + s.banlist.remove(&uuid); + }); + server.notify_client( + client, + ChatType::CommandInfo.server_msg(format!("{} was successfully unbanned", username)), + ); + } else { + server.notify_client( + client, + ChatType::CommandError.server_msg(format!("Unable to determine UUID for username \"{}\"", username)) + ) + } + } else { server.notify_client( client, diff --git a/server/src/login_provider.rs b/server/src/login_provider.rs index 3111f6fa47..bf2087c024 100644 --- a/server/src/login_provider.rs +++ b/server/src/login_provider.rs @@ -53,7 +53,7 @@ impl LoginProvider { &mut self, username_or_token: &str, whitelist: &[String], - banlist: &HashMap, + banlist: &HashMap, ) -> Result<(String, Uuid), RegisterError> { self // resolve user information @@ -61,9 +61,9 @@ impl LoginProvider { // if found, check name against whitelist or if user is admin .and_then(|(username, uuid)| { // user cannot join if they are listed on the banlist - if let Some(ban_record) = banlist.get(&username) { + if let Some(ban_record) = banlist.get(&uuid) { // Pull reason string out of ban record and send a copy of it - return Err(RegisterError::Banned(ban_record.clone())); + return Err(RegisterError::Banned(ban_record.1.clone())); } // user can only join if he is admin, the whitelist is empty (everyone can join) @@ -105,6 +105,6 @@ impl LoginProvider { } pub fn username_to_uuid(&self, username: &str) -> Result { - self.auth_server.map_or_else(|| Ok(derive_uuid(username)), |username| auth.username_to_uuid(username)) + self.auth_server.as_ref().map_or_else(|| Ok(derive_uuid(username)), |auth| auth.username_to_uuid(&username)) } } diff --git a/server/src/settings.rs b/server/src/settings.rs index 5bd08c6140..0dee4d8c86 100644 --- a/server/src/settings.rs +++ b/server/src/settings.rs @@ -4,6 +4,7 @@ use serde::{Deserialize, Serialize}; use std::{fs, io::prelude::*, net::SocketAddr, path::PathBuf, time::Duration}; use tracing::{error, warn}; use world::sim::FileOpts; +use authc::Uuid; const DEFAULT_WORLD_SEED: u32 = 59686; @@ -21,7 +22,7 @@ pub struct ServerSettings { pub start_time: f64, pub admins: Vec, pub whitelist: Vec, - pub banlist: HashMap, + pub banlist: HashMap, /// When set to None, loads the default map file (if available); otherwise, /// uses the value of the file options to decide how to proceed. pub map_file: Option,