diff --git a/common/src/comp/player.rs b/common/src/comp/player.rs index 68818560e4..c713394f72 100644 --- a/common/src/comp/player.rs +++ b/common/src/comp/player.rs @@ -1,5 +1,7 @@ use specs::{Component, FlaggedStorage, NullStorage, VecStorage}; +const MAX_ALIAS_LEN: usize = 32; + #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Player { pub alias: String, @@ -13,6 +15,11 @@ impl Player { view_distance, } } + + pub fn is_valid(&self) -> bool { + self.alias.chars().all(|c| c.is_alphanumeric() || c == '_') && self.alias.len() <= MAX_ALIAS_LEN + // TODO: Check view distance here based on server config too + } } impl Component for Player { diff --git a/server/src/lib.rs b/server/src/lib.rs index aa331e103b..62813a91bb 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(drain_filter)] +#![feature(drain_filter, bind_by_move_pattern_guards)] pub mod client; pub mod cmd; @@ -454,7 +454,8 @@ impl Server { ClientState::Dead => client.error_state(RequestStateError::Impossible), ClientState::Pending => {} }, - ClientMsg::Register { player } => match client.client_state { + // Valid player + ClientMsg::Register { player } if player.is_valid() => match client.client_state { ClientState::Connected => { Self::initialize_player(state, entity, client, player); if let Some(player) = @@ -467,6 +468,8 @@ impl Server { // Use RequestState instead (No need to send `player` again). _ => client.error_state(RequestStateError::Impossible), }, + // Invalid player + ClientMsg::Register { player } => client.error_state(RequestStateError::Impossible), ClientMsg::SetViewDistance(view_distance) => match client.client_state { ClientState::Character { .. } => { state diff --git a/voxygen/src/menu/main/mod.rs b/voxygen/src/menu/main/mod.rs index f2b2ccf505..ecadaa589d 100644 --- a/voxygen/src/menu/main/mod.rs +++ b/voxygen/src/menu/main/mod.rs @@ -100,15 +100,22 @@ impl PlayState for MainMenuState { if let Err(err) = global_state.settings.save_to_file() { warn!("Failed to save settings: {:?}", err); } - // Don't try to connect if there is already a connection in progress. - client_init = client_init.or(Some(ClientInit::new( - (server_address, DEFAULT_PORT, false), - comp::Player::new( - username.clone(), - Some(global_state.settings.graphics.view_distance), - ), - false, - ))); + + let player = comp::Player::new( + username.clone(), + Some(global_state.settings.graphics.view_distance), + ); + + if player.is_valid() { + // Don't try to connect if there is already a connection in progress. + client_init = client_init.or(Some(ClientInit::new( + (server_address, DEFAULT_PORT, false), + player, + false, + ))); + } else { + self.main_menu_ui.login_error("Invalid username".to_string()); + } } MainMenuEvent::StartSingleplayer => { return PlayStateResult::Push(Box::new(StartSingleplayerState::new()));