diff --git a/client/src/error.rs b/client/src/error.rs index 1f74ae62b9..754ed38d0e 100644 --- a/client/src/error.rs +++ b/client/src/error.rs @@ -6,6 +6,7 @@ pub enum Error { ServerWentMad, ServerTimeout, ServerShutdown, + TooManyPlayers, Other(String), } diff --git a/client/src/lib.rs b/client/src/lib.rs index 977829a722..febc4c2de7 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -73,6 +73,7 @@ impl Client { .ok_or(Error::ServerWentMad)?; (state, entity, server_info) } + Some(ServerMsg::TooManyPlayers) => return Err(Error::TooManyPlayers), _ => return Err(Error::ServerWentMad), }; @@ -362,6 +363,7 @@ impl Client { for msg in new_msgs { match msg { ServerMsg::InitialSync { .. } => return Err(Error::ServerWentMad), + ServerMsg::TooManyPlayers => return Err(Error::ServerWentMad), ServerMsg::Shutdown => return Err(Error::ServerShutdown), ServerMsg::Ping => self.postbox.send_message(ClientMsg::Pong), ServerMsg::Pong => { diff --git a/common/src/msg/server.rs b/common/src/msg/server.rs index 0fadce7afa..7f5af07832 100644 --- a/common/src/msg/server.rs +++ b/common/src/msg/server.rs @@ -41,6 +41,7 @@ pub enum ServerMsg { key: Vec2, chunk: Box, }, + TooManyPlayers, Disconnect, Shutdown, } diff --git a/server/src/client.rs b/server/src/client.rs index e22d8d2e95..fb43465ebb 100644 --- a/server/src/client.rs +++ b/server/src/client.rs @@ -41,6 +41,10 @@ impl Clients { } } + pub fn len(&mut self) -> usize { + self.clients.len() + } + pub fn add(&mut self, entity: EcsEntity, client: Client) { self.clients.insert(entity, client); } diff --git a/server/src/lib.rs b/server/src/lib.rs index 7872c887d0..3d7fc69e58 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -357,16 +357,21 @@ impl Server { last_ping: self.state.get_time(), }; - // Return the state of the current world (all of the components that Sphynx tracks). - client.notify(ServerMsg::InitialSync { - ecs_state: self.state.ecs().gen_state_package(), - entity_uid: self.state.ecs().uid_from_entity(entity).unwrap().into(), // Can't fail. - server_info: self.server_info.clone(), - }); + // TODO: Figure out if this if/else if correct + if self.server_settings.max_players <= self.clients.len() { + client.notify(ServerMsg::TooManyPlayers); + } else { + // Return the state of the current world (all of the components that Sphynx tracks). + client.notify(ServerMsg::InitialSync { + ecs_state: self.state.ecs().gen_state_package(), + entity_uid: self.state.ecs().uid_from_entity(entity).unwrap().into(), // Can't fail. + server_info: self.server_info.clone(), + }); + + frontend_events.push(Event::ClientConnected { entity }); + } self.clients.add(entity, client); - - frontend_events.push(Event::ClientConnected { entity }); } Ok(frontend_events) diff --git a/server/src/settings.rs b/server/src/settings.rs index 7dd157611f..3ba8482cc3 100644 --- a/server/src/settings.rs +++ b/server/src/settings.rs @@ -1,12 +1,11 @@ use serde_derive::{Deserialize, Serialize}; use std::{fs, io::prelude::*, net::SocketAddr, path::PathBuf}; -/// `ControlSettings` contains keybindings. #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(default)] pub struct ServerSettings { pub address: SocketAddr, - //pub max_players: u64, + pub max_players: usize, pub world_seed: u32, //pub pvp_enabled: bool, pub server_name: String, @@ -21,6 +20,7 @@ impl Default for ServerSettings { world_seed: 1337, server_name: "Server name".to_owned(), server_description: "This is the best Veloren server.".to_owned(), + max_players: 16, } } } diff --git a/voxygen/src/menu/main/client_init.rs b/voxygen/src/menu/main/client_init.rs index 86ab1af88a..ee07025a55 100644 --- a/voxygen/src/menu/main/client_init.rs +++ b/voxygen/src/menu/main/client_init.rs @@ -20,6 +20,7 @@ pub enum Error { // Parsing/host name resolution successful but could not connect. ConnectionFailed(ClientError), ClientCrashed, + ServerIsFull, } // Used to asynchronously parse the server address, resolve host names, @@ -76,6 +77,10 @@ impl ClientInit { ClientError::Network(_) => { last_err = Some(Error::ConnectionFailed(err)) } + ClientError::TooManyPlayers => { + last_err = Some(Error::ServerIsFull); + break; + } // TODO: Handle errors? _ => panic!( "Unexpected non-network error when creating client: {:?}", diff --git a/voxygen/src/menu/main/mod.rs b/voxygen/src/menu/main/mod.rs index b46b076e69..ed27a97ea6 100644 --- a/voxygen/src/menu/main/mod.rs +++ b/voxygen/src/menu/main/mod.rs @@ -64,6 +64,7 @@ impl PlayState for MainMenuState { self.main_menu_ui.login_error( match err { InitError::BadAddress(_) | InitError::NoAddress => "Server not found", + InitError::ServerIsFull => "Server is Full!", InitError::ConnectionFailed(_) => "Connection failed", InitError::ClientCrashed => "Client crashed", }