Merge branch 'tylerlowrey/add-ban-unban-kick-cmds' into 'master'

Tylerlowrey/add ban unban kick cmds

See merge request veloren/veloren!1382
This commit is contained in:
Joshua Yanovski 2020-09-14 07:18:33 +00:00
commit 8d829f9c69
14 changed files with 273 additions and 28 deletions

View File

@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Beehives and bees - Beehives and bees
- Fireflies - Fireflies
- Fullscreen modes now show two options (exclusive and borderless) - Fullscreen modes now show two options (exclusive and borderless)
- Added banlist and `/ban`, `/unban`, and `/kick` commands for admins
### Changed ### Changed

View File

@ -141,6 +141,8 @@ https://account.veloren.net."#,
"main.login.invalid_character": "The selected character is invalid", "main.login.invalid_character": "The selected character is invalid",
"main.login.client_crashed": "Client crashed", "main.login.client_crashed": "Client crashed",
"main.login.not_on_whitelist": "You need a Whitelist entry by an Admin to join", "main.login.not_on_whitelist": "You need a Whitelist entry by an Admin to join",
"main.login.banned": "You have been banned with the following reason",
"main.login.kicked": "You have been kicked with the following reason",
/// End Main screen section /// End Main screen section

View File

@ -16,6 +16,7 @@ pub enum Error {
AuthErr(String), AuthErr(String),
AuthClientError(AuthClientError), AuthClientError(AuthClientError),
AuthServerNotTrusted, AuthServerNotTrusted,
Banned(String),
/// Persisted character data is invalid or missing /// Persisted character data is invalid or missing
InvalidCharacter, InvalidCharacter,
//TODO: InvalidAlias, //TODO: InvalidAlias,

View File

@ -23,9 +23,9 @@ use common::{
InventoryManip, InventoryUpdateEvent, InventoryManip, InventoryUpdateEvent,
}, },
msg::{ msg::{
validate_chat_msg, ChatMsgValidationError, ClientMsg, ClientState, InviteAnswer, validate_chat_msg, ChatMsgValidationError, ClientMsg, ClientState, DisconnectReason,
Notification, PlayerInfo, PlayerListUpdate, RegisterError, RequestStateError, ServerInfo, InviteAnswer, Notification, PlayerInfo, PlayerListUpdate, RegisterError, RequestStateError,
ServerMsg, MAX_BYTES_CHAT_MSG, ServerInfo, ServerMsg, MAX_BYTES_CHAT_MSG,
}, },
outcome::Outcome, outcome::Outcome,
recipe::RecipeBook, recipe::RecipeBook,
@ -59,6 +59,7 @@ pub enum Event {
Disconnect, Disconnect,
DisconnectionNotification(u64), DisconnectionNotification(u64),
InventoryUpdated(InventoryUpdateEvent), InventoryUpdated(InventoryUpdateEvent),
Kicked(String),
Notification(Notification), Notification(Notification),
SetViewDistance(u32), SetViewDistance(u32),
Outcome(Outcome), Outcome(Outcome),
@ -455,6 +456,7 @@ impl Client {
RegisterError::AuthError(err) => Error::AuthErr(err), RegisterError::AuthError(err) => Error::AuthErr(err),
RegisterError::InvalidCharacter => Error::InvalidCharacter, RegisterError::InvalidCharacter => Error::InvalidCharacter,
RegisterError::NotOnWhitelist => Error::NotOnWhitelist, RegisterError::NotOnWhitelist => Error::NotOnWhitelist,
RegisterError::Banned(reason) => Error::Banned(reason),
}); });
}, },
ServerMsg::StateAnswer(Ok(ClientState::Registered)) => break Ok(()), ServerMsg::StateAnswer(Ok(ClientState::Registered)) => break Ok(()),
@ -1108,7 +1110,20 @@ impl Client {
ServerMsg::TooManyPlayers => { ServerMsg::TooManyPlayers => {
return Err(Error::ServerWentMad); return Err(Error::ServerWentMad);
}, },
ServerMsg::Shutdown => return Err(Error::ServerShutdown), ServerMsg::Disconnect(reason) => match reason {
DisconnectReason::Shutdown => return Err(Error::ServerShutdown),
DisconnectReason::Requested => {
debug!("finally sending ClientMsg::Terminate");
frontend_events.push(Event::Disconnect);
self.singleton_stream.send(ClientMsg::Terminate)?;
break Ok(());
},
DisconnectReason::Kicked(reason) => {
debug!("sending ClientMsg::Terminate because we got kicked");
frontend_events.push(Event::Kicked(reason.clone()));
self.singleton_stream.send(ClientMsg::Terminate)?;
},
},
ServerMsg::InitialSync { .. } => return Err(Error::ServerWentMad), ServerMsg::InitialSync { .. } => return Err(Error::ServerWentMad),
ServerMsg::PlayerListUpdate(PlayerListUpdate::Init(list)) => { ServerMsg::PlayerListUpdate(PlayerListUpdate::Init(list)) => {
self.player_list = list self.player_list = list
@ -1388,12 +1403,6 @@ impl Client {
error, state error, state
); );
}, },
ServerMsg::Disconnect => {
debug!("finally sending ClientMsg::Terminate");
frontend_events.push(Event::Disconnect);
self.singleton_stream.send(ClientMsg::Terminate)?;
break Ok(());
},
ServerMsg::CharacterListUpdate(character_list) => { ServerMsg::CharacterListUpdate(character_list) => {
self.character_list.characters = character_list; self.character_list.characters = character_list;
self.character_list.loading = false; self.character_list.loading = false;

View File

@ -37,6 +37,7 @@ impl ChatCommandData {
pub enum ChatCommand { pub enum ChatCommand {
Adminify, Adminify,
Alias, Alias,
Ban,
Build, Build,
Campfire, Campfire,
Debug, Debug,
@ -52,6 +53,7 @@ pub enum ChatCommand {
Help, Help,
JoinFaction, JoinFaction,
Jump, Jump,
Kick,
Kill, Kill,
KillNpcs, KillNpcs,
Lantern, Lantern,
@ -70,6 +72,7 @@ pub enum ChatCommand {
Tell, Tell,
Time, Time,
Tp, Tp,
Unban,
Version, Version,
Waypoint, Waypoint,
Whitelist, Whitelist,
@ -80,6 +83,7 @@ pub enum ChatCommand {
pub static CHAT_COMMANDS: &[ChatCommand] = &[ pub static CHAT_COMMANDS: &[ChatCommand] = &[
ChatCommand::Adminify, ChatCommand::Adminify,
ChatCommand::Alias, ChatCommand::Alias,
ChatCommand::Ban,
ChatCommand::Build, ChatCommand::Build,
ChatCommand::Campfire, ChatCommand::Campfire,
ChatCommand::Debug, ChatCommand::Debug,
@ -95,6 +99,7 @@ pub static CHAT_COMMANDS: &[ChatCommand] = &[
ChatCommand::Help, ChatCommand::Help,
ChatCommand::JoinFaction, ChatCommand::JoinFaction,
ChatCommand::Jump, ChatCommand::Jump,
ChatCommand::Kick,
ChatCommand::Kill, ChatCommand::Kill,
ChatCommand::KillNpcs, ChatCommand::KillNpcs,
ChatCommand::Lantern, ChatCommand::Lantern,
@ -113,6 +118,7 @@ pub static CHAT_COMMANDS: &[ChatCommand] = &[
ChatCommand::Tell, ChatCommand::Tell,
ChatCommand::Time, ChatCommand::Time,
ChatCommand::Tp, ChatCommand::Tp,
ChatCommand::Unban,
ChatCommand::Version, ChatCommand::Version,
ChatCommand::Waypoint, ChatCommand::Waypoint,
ChatCommand::Whitelist, ChatCommand::Whitelist,
@ -193,6 +199,11 @@ impl ChatCommand {
Admin, Admin,
), ),
ChatCommand::Alias => cmd(vec![Any("name", Required)], "Change your alias", NoAdmin), ChatCommand::Alias => cmd(vec![Any("name", Required)], "Change your alias", NoAdmin),
ChatCommand::Ban => cmd(
vec![Any("username", Required), Message(Optional)],
"Ban a player with a given username",
Admin,
),
ChatCommand::Build => cmd(vec![], "Toggles build mode on and off", Admin), ChatCommand::Build => cmd(vec![], "Toggles build mode on and off", Admin),
ChatCommand::Campfire => cmd(vec![], "Spawns a campfire", Admin), ChatCommand::Campfire => cmd(vec![], "Spawns a campfire", Admin),
ChatCommand::Debug => cmd(vec![], "Place all debug items into your pack.", Admin), ChatCommand::Debug => cmd(vec![], "Place all debug items into your pack.", Admin),
@ -263,6 +274,11 @@ impl ChatCommand {
"Offset your current position", "Offset your current position",
Admin, Admin,
), ),
ChatCommand::Kick => cmd(
vec![Any("username", Required), Message(Optional)],
"Kick a player with a given username",
Admin,
),
ChatCommand::Kill => cmd(vec![], "Kill yourself", NoAdmin), ChatCommand::Kill => cmd(vec![], "Kill yourself", NoAdmin),
ChatCommand::KillNpcs => cmd(vec![], "Kill the NPCs", Admin), ChatCommand::KillNpcs => cmd(vec![], "Kill the NPCs", Admin),
ChatCommand::Lantern => cmd( ChatCommand::Lantern => cmd(
@ -357,6 +373,11 @@ impl ChatCommand {
"Teleport to another player", "Teleport to another player",
Admin, Admin,
), ),
ChatCommand::Unban => cmd(
vec![Any("username", Required)],
"Remove the ban for the given username",
Admin,
),
ChatCommand::Version => cmd(vec![], "Prints server version", NoAdmin), ChatCommand::Version => cmd(vec![], "Prints server version", NoAdmin),
ChatCommand::Waypoint => { ChatCommand::Waypoint => {
cmd(vec![], "Set your waypoint to your current position", Admin) cmd(vec![], "Set your waypoint to your current position", Admin)
@ -379,6 +400,7 @@ impl ChatCommand {
match self { match self {
ChatCommand::Adminify => "adminify", ChatCommand::Adminify => "adminify",
ChatCommand::Alias => "alias", ChatCommand::Alias => "alias",
ChatCommand::Ban => "ban",
ChatCommand::Build => "build", ChatCommand::Build => "build",
ChatCommand::Campfire => "campfire", ChatCommand::Campfire => "campfire",
ChatCommand::Debug => "debug", ChatCommand::Debug => "debug",
@ -394,6 +416,7 @@ impl ChatCommand {
ChatCommand::JoinFaction => "join_faction", ChatCommand::JoinFaction => "join_faction",
ChatCommand::Help => "help", ChatCommand::Help => "help",
ChatCommand::Jump => "jump", ChatCommand::Jump => "jump",
ChatCommand::Kick => "kick",
ChatCommand::Kill => "kill", ChatCommand::Kill => "kill",
ChatCommand::KillNpcs => "kill_npcs", ChatCommand::KillNpcs => "kill_npcs",
ChatCommand::Lantern => "lantern", ChatCommand::Lantern => "lantern",
@ -412,6 +435,7 @@ impl ChatCommand {
ChatCommand::Tell => "tell", ChatCommand::Tell => "tell",
ChatCommand::Time => "time", ChatCommand::Time => "time",
ChatCommand::Tp => "tp", ChatCommand::Tp => "tp",
ChatCommand::Unban => "unban",
ChatCommand::Version => "version", ChatCommand::Version => "version",
ChatCommand::Waypoint => "waypoint", ChatCommand::Waypoint => "waypoint",
ChatCommand::Whitelist => "whitelist", ChatCommand::Whitelist => "whitelist",

View File

@ -7,8 +7,8 @@ pub use self::{
client::ClientMsg, client::ClientMsg,
ecs_packet::EcsCompPacket, ecs_packet::EcsCompPacket,
server::{ server::{
CharacterInfo, InviteAnswer, Notification, PlayerInfo, PlayerListUpdate, RegisterError, CharacterInfo, DisconnectReason, InviteAnswer, Notification, PlayerInfo, PlayerListUpdate,
RequestStateError, ServerInfo, ServerMsg, RegisterError, RequestStateError, ServerInfo, ServerMsg,
}, },
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -182,6 +182,16 @@ pub enum Notification {
WaypointSaved, WaypointSaved,
} }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum DisconnectReason {
/// Server shut down
Shutdown,
/// Client sent disconnect message
Requested,
/// Client was kicked
Kicked(String),
}
/// Messages sent from the server to the client /// Messages sent from the server to the client
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ServerMsg { pub enum ServerMsg {
@ -238,8 +248,7 @@ pub enum ServerMsg {
chunk: Result<Box<TerrainChunk>, ()>, chunk: Result<Box<TerrainChunk>, ()>,
}, },
TerrainBlockUpdates(HashMap<Vec3<i32>, Block>), TerrainBlockUpdates(HashMap<Vec3<i32>, Block>),
Disconnect, Disconnect(DisconnectReason),
Shutdown,
TooManyPlayers, TooManyPlayers,
/// Send a popup notification such as "Waypoint Saved" /// Send a popup notification such as "Waypoint Saved"
Notification(Notification), Notification(Notification),
@ -260,6 +269,7 @@ pub enum RequestStateError {
pub enum RegisterError { pub enum RegisterError {
AlreadyLoggedIn, AlreadyLoggedIn,
AuthError(String), AuthError(String),
Banned(String),
InvalidCharacter, InvalidCharacter,
NotOnWhitelist, NotOnWhitelist,
//TODO: InvalidAlias, //TODO: InvalidAlias,

View File

@ -9,7 +9,7 @@ use common::{
cmd::{ChatCommand, CHAT_COMMANDS, CHAT_SHORTCUTS}, cmd::{ChatCommand, CHAT_COMMANDS, CHAT_SHORTCUTS},
comp::{self, item::ItemAsset, ChatType, Item, LightEmitter, WaypointArea}, comp::{self, item::ItemAsset, ChatType, Item, LightEmitter, WaypointArea},
event::{EventBus, ServerEvent}, event::{EventBus, ServerEvent},
msg::{Notification, PlayerListUpdate, ServerMsg}, msg::{DisconnectReason, Notification, PlayerListUpdate, ServerMsg},
npc::{self, get_npc_name}, npc::{self, get_npc_name},
state::TimeOfDay, state::TimeOfDay,
sync::{Uid, WorldSyncExt}, sync::{Uid, WorldSyncExt},
@ -24,6 +24,7 @@ use std::convert::TryFrom;
use vek::*; use vek::*;
use world::util::Sampler; use world::util::Sampler;
use crate::login_provider::LoginProvider;
use scan_fmt::{scan_fmt, scan_fmt_some}; use scan_fmt::{scan_fmt, scan_fmt_some};
use tracing::error; use tracing::error;
@ -65,6 +66,7 @@ fn get_handler(cmd: &ChatCommand) -> CommandHandler {
match cmd { match cmd {
ChatCommand::Adminify => handle_adminify, ChatCommand::Adminify => handle_adminify,
ChatCommand::Alias => handle_alias, ChatCommand::Alias => handle_alias,
ChatCommand::Ban => handle_ban,
ChatCommand::Build => handle_build, ChatCommand::Build => handle_build,
ChatCommand::Campfire => handle_spawn_campfire, ChatCommand::Campfire => handle_spawn_campfire,
ChatCommand::Debug => handle_debug, ChatCommand::Debug => handle_debug,
@ -80,6 +82,7 @@ fn get_handler(cmd: &ChatCommand) -> CommandHandler {
ChatCommand::Help => handle_help, ChatCommand::Help => handle_help,
ChatCommand::JoinFaction => handle_join_faction, ChatCommand::JoinFaction => handle_join_faction,
ChatCommand::Jump => handle_jump, ChatCommand::Jump => handle_jump,
ChatCommand::Kick => handle_kick,
ChatCommand::Kill => handle_kill, ChatCommand::Kill => handle_kill,
ChatCommand::KillNpcs => handle_kill_npcs, ChatCommand::KillNpcs => handle_kill_npcs,
ChatCommand::Lantern => handle_lantern, ChatCommand::Lantern => handle_lantern,
@ -98,6 +101,7 @@ fn get_handler(cmd: &ChatCommand) -> CommandHandler {
ChatCommand::Tell => handle_tell, ChatCommand::Tell => handle_tell,
ChatCommand::Time => handle_time, ChatCommand::Time => handle_time,
ChatCommand::Tp => handle_tp, ChatCommand::Tp => handle_tp,
ChatCommand::Unban => handle_unban,
ChatCommand::Version => handle_version, ChatCommand::Version => handle_version,
ChatCommand::Waypoint => handle_waypoint, ChatCommand::Waypoint => handle_waypoint,
ChatCommand::Whitelist => handle_whitelist, ChatCommand::Whitelist => handle_whitelist,
@ -1810,3 +1814,159 @@ fn handle_whitelist(
); );
} }
} }
fn kick_player(server: &mut Server, target_player: EcsEntity, reason: &str) {
server
.state
.ecs()
.read_resource::<EventBus<ServerEvent>>()
.emit_now(ServerEvent::ClientDisconnect(target_player));
server.notify_client(
target_player,
ServerMsg::Disconnect(DisconnectReason::Kicked(reason.to_string())),
);
}
fn handle_kick(
server: &mut Server,
client: EcsEntity,
_target: EcsEntity,
args: String,
action: &ChatCommand,
) {
if let (Some(target_alias), reason_opt) =
scan_fmt_some!(&args, &action.arg_fmt(), String, String)
{
let reason = reason_opt.unwrap_or_default();
let ecs = server.state.ecs();
let target_player_opt = (&ecs.entities(), &ecs.read_storage::<comp::Player>())
.join()
.find(|(_, player)| player.alias == target_alias)
.map(|(entity, _)| entity);
if let Some(target_player) = target_player_opt {
kick_player(server, target_player, &reason);
server.notify_client(
client,
ChatType::CommandInfo.server_msg(format!(
"Kicked {} from the server with reason: {}",
target_alias, reason
)),
);
} else {
server.notify_client(
client,
ChatType::CommandError
.server_msg(format!("Player with alias {} not found", target_alias)),
)
}
} else {
server.notify_client(
client,
ChatType::CommandError.server_msg(action.help_string()),
);
}
}
fn handle_ban(
server: &mut Server,
client: EcsEntity,
_target: EcsEntity,
args: String,
action: &ChatCommand,
) {
if let (Some(target_alias), reason_opt) =
scan_fmt_some!(&args, &action.arg_fmt(), String, String)
{
let reason = reason_opt.unwrap_or_default();
let uuid_result = server
.state
.ecs()
.read_resource::<LoginProvider>()
.username_to_uuid(&target_alias);
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::<comp::Player>())
.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(
client,
ChatType::CommandError.server_msg(action.help_string()),
);
}
}
fn handle_unban(
server: &mut Server,
client: EcsEntity,
_target: EcsEntity,
args: String,
action: &ChatCommand,
) {
if let Ok(username) = scan_fmt!(&args, &action.arg_fmt(), String) {
let uuid_result = server
.state
.ecs()
.read_resource::<LoginProvider>()
.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,
ChatType::CommandError.server_msg(action.help_string()),
);
}
}

View File

@ -34,7 +34,7 @@ use common::{
cmd::ChatCommand, cmd::ChatCommand,
comp::{self, ChatType}, comp::{self, ChatType},
event::{EventBus, ServerEvent}, event::{EventBus, ServerEvent},
msg::{server::WorldMapMsg, ClientState, ServerInfo, ServerMsg}, msg::{server::WorldMapMsg, ClientState, DisconnectReason, ServerInfo, ServerMsg},
outcome::Outcome, outcome::Outcome,
recipe::default_recipe_book, recipe::default_recipe_book,
state::{State, TimeOfDay}, state::{State, TimeOfDay},
@ -817,5 +817,8 @@ impl Server {
} }
impl Drop for Server { impl Drop for Server {
fn drop(&mut self) { self.state.notify_registered_clients(ServerMsg::Shutdown); } fn drop(&mut self) {
self.state
.notify_registered_clients(ServerMsg::Disconnect(DisconnectReason::Shutdown));
}
} }

View File

@ -1,4 +1,4 @@
use authc::{AuthClient, AuthToken, Uuid}; use authc::{AuthClient, AuthClientError, AuthToken, Uuid};
use common::msg::RegisterError; use common::msg::RegisterError;
use hashbrown::HashMap; use hashbrown::HashMap;
use std::str::FromStr; use std::str::FromStr;
@ -53,12 +53,19 @@ impl LoginProvider {
&mut self, &mut self,
username_or_token: &str, username_or_token: &str,
whitelist: &[String], whitelist: &[String],
banlist: &HashMap<Uuid, (String, String)>,
) -> Result<(String, Uuid), RegisterError> { ) -> Result<(String, Uuid), RegisterError> {
self self
// resolve user information // resolve user information
.query(username_or_token) .query(username_or_token)
// if found, check name against whitelist or if user is admin // if found, check name against whitelist or if user is admin
.and_then(|(username, uuid)| { .and_then(|(username, uuid)| {
// user cannot join if they are listed on the banlist
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.1.clone()));
}
// user can only join if he is admin, the whitelist is empty (everyone can join) // user can only join if he is admin, the whitelist is empty (everyone can join)
// or his name is in the whitelist // or his name is in the whitelist
if !whitelist.is_empty() && !whitelist.contains(&username) { if !whitelist.is_empty() && !whitelist.contains(&username) {
@ -96,4 +103,11 @@ impl LoginProvider {
}, },
} }
} }
pub fn username_to_uuid(&self, username: &str) -> Result<Uuid, AuthClientError> {
self.auth_server.as_ref().map_or_else(
|| Ok(derive_uuid(username)),
|auth| auth.username_to_uuid(&username),
)
}
} }

View File

@ -1,3 +1,5 @@
use authc::Uuid;
use hashbrown::HashMap;
use portpicker::pick_unused_port; use portpicker::pick_unused_port;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{fs, io::prelude::*, net::SocketAddr, path::PathBuf, time::Duration}; use std::{fs, io::prelude::*, net::SocketAddr, path::PathBuf, time::Duration};
@ -20,6 +22,7 @@ pub struct ServerSettings {
pub start_time: f64, pub start_time: f64,
pub admins: Vec<String>, pub admins: Vec<String>,
pub whitelist: Vec<String>, pub whitelist: Vec<String>,
pub banlist: HashMap<Uuid, (String, String)>,
/// When set to None, loads the default map file (if available); otherwise, /// When set to None, loads the default map file (if available); otherwise,
/// uses the value of the file options to decide how to proceed. /// uses the value of the file options to decide how to proceed.
pub map_file: Option<FileOpts>, pub map_file: Option<FileOpts>,
@ -44,6 +47,7 @@ impl Default for ServerSettings {
map_file: None, map_file: None,
admins: Vec::new(), admins: Vec::new(),
whitelist: Vec::new(), whitelist: Vec::new(),
banlist: HashMap::new(),
persistence_db_dir: "saves".to_owned(), persistence_db_dir: "saves".to_owned(),
max_view_distance: Some(30), max_view_distance: Some(30),
banned_words_files: Vec::new(), banned_words_files: Vec::new(),

View File

@ -11,7 +11,8 @@ use common::{
event::{EventBus, ServerEvent}, event::{EventBus, ServerEvent},
msg::{ msg::{
validate_chat_msg, CharacterInfo, ChatMsgValidationError, ClientMsg, ClientState, validate_chat_msg, CharacterInfo, ChatMsgValidationError, ClientMsg, ClientState,
PlayerInfo, PlayerListUpdate, RequestStateError, ServerMsg, MAX_BYTES_CHAT_MSG, DisconnectReason, PlayerInfo, PlayerListUpdate, RequestStateError, ServerMsg,
MAX_BYTES_CHAT_MSG,
}, },
span, span,
state::{BlockChange, Time}, state::{BlockChange, Time},
@ -88,14 +89,17 @@ impl Sys {
view_distance, view_distance,
token_or_username, token_or_username,
} => { } => {
let (username, uuid) = let (username, uuid) = match login_provider.try_login(
match login_provider.try_login(&token_or_username, &settings.whitelist) { &token_or_username,
Err(err) => { &settings.whitelist,
client.error_state(RequestStateError::RegisterDenied(err)); &settings.banlist,
break Ok(()); ) {
}, Err(err) => {
Ok((username, uuid)) => (username, uuid), client.error_state(RequestStateError::RegisterDenied(err));
}; break Ok(());
},
Ok((username, uuid)) => (username, uuid),
};
let vd = let vd =
view_distance.map(|vd| vd.min(settings.max_view_distance.unwrap_or(vd))); view_distance.map(|vd| vd.min(settings.max_view_distance.unwrap_or(vd)));
@ -339,7 +343,7 @@ impl Sys {
ClientMsg::Ping => client.notify(ServerMsg::Pong), ClientMsg::Ping => client.notify(ServerMsg::Pong),
ClientMsg::Pong => {}, ClientMsg::Pong => {},
ClientMsg::Disconnect => { ClientMsg::Disconnect => {
client.notify(ServerMsg::Disconnect); client.notify(ServerMsg::Disconnect(DisconnectReason::Requested));
}, },
ClientMsg::Terminate => { ClientMsg::Terminate => {
debug!(?entity, "Client send message to termitate session"); debug!(?entity, "Client send message to termitate session");

View File

@ -125,6 +125,11 @@ impl PlayState for MainMenuState {
client::Error::NotOnWhitelist => { client::Error::NotOnWhitelist => {
localized_strings.get("main.login.not_on_whitelist").into() localized_strings.get("main.login.not_on_whitelist").into()
}, },
client::Error::Banned(reason) => format!(
"{}: {}",
localized_strings.get("main.login.banned"),
reason
),
client::Error::InvalidCharacter => { client::Error::InvalidCharacter => {
localized_strings.get("main.login.invalid_character").into() localized_strings.get("main.login.invalid_character").into()
}, },

View File

@ -163,6 +163,14 @@ impl SessionState {
message, message,
}); });
}, },
client::Event::Kicked(reason) => {
global_state.info_message = Some(format!(
"{}: {}",
self.voxygen_i18n.get("main.login.kicked").to_string(),
reason
));
return Ok(TickAction::Disconnect);
},
client::Event::Notification(n) => { client::Event::Notification(n) => {
self.hud.new_notification(n); self.hud.new_notification(n);
}, },