Split connecting from registering

Former-commit-id: 56c21f72bc5b53635d6fdf00c99eb34df3b448c9
This commit is contained in:
timokoesters 2019-04-21 20:12:29 +02:00
parent 9a48e2fd42
commit e9027c6433
5 changed files with 34 additions and 33 deletions

View File

@ -53,21 +53,16 @@ impl Client {
#[allow(dead_code)]
pub fn new<A: Into<SocketAddr>>(
addr: A,
player: comp::Player,
view_distance: u64,
) -> Result<Self, Error> {
let mut client_state = ClientState::Connected;
let mut postbox = PostBox::to(addr)?;
// Send connection request
postbox.send_message(ClientMsg::Connect { player });
// Wait for initial sync
let (state, player_entity) = match postbox.next_message() {
Some(ServerMsg::InitialSync { ecs_state, player_entity_uid }) => {
Some(ServerMsg::InitialSync { ecs_state, entity_uid }) => {
let mut state = State::from_state_package(ecs_state);
let player_entity = state.ecs().entity_from_uid(player_entity_uid).ok_or(Error::ServerWentMad)?;
let player_entity = state.ecs().entity_from_uid(entity_uid).ok_or(Error::ServerWentMad)?;
(state, player_entity)
},
_ => return Err(Error::ServerWentMad),
@ -91,6 +86,10 @@ impl Client {
})
}
pub fn register(&mut self, player: comp::Player) {
self.postbox.send_message(ClientMsg::Register { player });
}
/// Get a reference to the client's worker thread pool. This pool should be used for any
/// computationally expensive operations that run outside of the main thread (i.e: threads that
/// block on I/O operations are exempt).

View File

@ -4,7 +4,7 @@ use crate::comp;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ClientMsg {
Connect { player: comp::Player },
Register { player: comp::Player },
Character(comp::Character),
RequestState(ClientState),
Ping,

View File

@ -14,12 +14,12 @@ pub enum RequestStateError {
#[derive(Clone, Serialize, Deserialize)]
pub enum ServerMsg {
StateAnswer(Result<ClientState, (RequestStateError, ClientState)>),
ForceState(ClientState),
InitialSync {
ecs_state: sphynx::StatePackage<EcsPacket>,
player_entity_uid: u64,
entity_uid: u64,
},
StateAnswer(Result<ClientState, (RequestStateError, ClientState)>),
ForceState(ClientState),
Ping,
Pong,
Chat(String),

View File

@ -213,14 +213,26 @@ impl Server {
for mut postbox in self.postoffice.new_postboxes() {
let entity = self.state.ecs_mut().create_entity_synced().build();
self.clients.add(
entity,
Client {
let mut client = Client {
client_state: ClientState::Connected,
postbox,
last_ping: self.state.get_time(),
},
};
// Return the state of the current world
// (All components 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(),
});
self.clients.add(
entity,
client,
);
frontend_events.push(Event::ClientConnected { entity });
@ -250,7 +262,7 @@ impl Server {
for msg in new_msgs {
match msg {
ClientMsg::RequestState(requested_state) => match requested_state {
ClientState::Connected => disconnect = true,
ClientState::Connected => disconnect = true, // Default state
ClientState::Registered => match client.client_state {
ClientState::Connected => {}, // Use ClientMsg::Connect instead
ClientState::Registered => client.error_state(RequestStateError::Already),
@ -265,8 +277,8 @@ impl Server {
},
ClientState::Character => disconnect = true, // Use ClientMsg::Character instead
},
ClientMsg::Connect { player } => match client.client_state {
ClientState::Connected => Self::initialize_client(state, entity, client, player),
ClientMsg::Register { player } => match client.client_state {
ClientState::Connected => Self::initialize_player(state, entity, client, player),
_ => disconnect = true,
},
ClientMsg::Character(character) => match client.client_state {
@ -370,7 +382,7 @@ impl Server {
}
/// Initialize a new client states with important information
fn initialize_client(
fn initialize_player(
state: &mut State,
entity: specs::Entity,
client: &mut Client,
@ -379,17 +391,6 @@ impl Server {
// Save player metadata (for example the username)
state.write_component(entity, player);
// Return the state of the current world
// (All components Sphynx tracks)
client.notify(ServerMsg::InitialSync {
ecs_state: state.ecs().gen_state_package(),
player_entity_uid: state
.ecs()
.uid_from_entity(entity)
.unwrap()
.into(),
});
// Sync logical information other players have authority over, not the server
for (other_entity, &uid, &animation_history) in (
&state.ecs().entities(),

View File

@ -44,8 +44,9 @@ impl ClientInit {
let mut last_err = None;
for socket_addr in first_addrs.into_iter().chain(second_addrs) {
match Client::new(socket_addr, player.clone(), view_distance) {
Ok(client) => {
match Client::new(socket_addr, view_distance) {
Ok(mut client) => {
client.register(player);
let _ = tx.send(Ok(client));
return;
}