Janky fix of the logout timeout problem

This commit is contained in:
Capucho 2020-03-07 22:14:21 +00:00
parent d5c3034b8f
commit 99e64d06b9
4 changed files with 33 additions and 9 deletions

View File

@ -197,7 +197,7 @@ impl Client {
/// Send disconnect message to the server
pub fn request_logout(&mut self) {
self.postbox.send_message(ClientMsg::Disconnect);
self.client_state = ClientState::Pending;
self.client_state = ClientState::Disconnected;
}
/// Request a state transition to `ClientState::Registered` from an ingame
@ -703,6 +703,7 @@ impl Client {
},
ServerMsg::Disconnect => {
frontend_events.push(Event::Disconnect);
self.client_state = ClientState::Disconnected;
},
}
}

View File

@ -16,6 +16,7 @@ pub enum ClientState {
Registered,
Spectator,
Character,
Disconnected,
}
pub const MAX_BYTES_CHAT_MSG: usize = 256;

View File

@ -111,6 +111,7 @@ impl<'a> System<'a> for Sys {
server_emitter.emit(ServerEvent::ExitIngame { entity });
},
ClientState::Pending => {},
ClientState::Disconnected => unreachable!(),
},
// Request spectator state
ClientMsg::Spectate => match client.client_state {
@ -121,6 +122,7 @@ impl<'a> System<'a> for Sys {
client.allow_state(ClientState::Spectator)
},
ClientState::Pending => {},
ClientState::Disconnected => unreachable!(),
},
// Valid player
ClientMsg::Register { player, password } if player.is_valid() => {
@ -187,6 +189,7 @@ impl<'a> System<'a> for Sys {
},
ClientState::Character => client.error_state(RequestStateError::Already),
ClientState::Pending => {},
ClientState::Disconnected => unreachable!(),
},
ClientMsg::ControllerInputs(inputs) => match client.client_state {
ClientState::Connected
@ -200,6 +203,7 @@ impl<'a> System<'a> for Sys {
}
},
ClientState::Pending => {},
ClientState::Disconnected => unreachable!(),
},
ClientMsg::ControlEvent(event) => match client.client_state {
ClientState::Connected
@ -213,6 +217,7 @@ impl<'a> System<'a> for Sys {
}
},
ClientState::Pending => {},
ClientState::Disconnected => unreachable!(),
},
ClientMsg::ChatMsg { message } => match client.client_state {
ClientState::Connected => client.error_state(RequestStateError::Impossible),
@ -227,6 +232,7 @@ impl<'a> System<'a> for Sys {
),
},
ClientState::Pending => {},
ClientState::Disconnected => unreachable!(),
},
ClientMsg::PlayerPhysics { pos, vel, ori } => match client.client_state {
ClientState::Character => {
@ -267,6 +273,7 @@ impl<'a> System<'a> for Sys {
}
},
ClientState::Pending => {},
ClientState::Disconnected => unreachable!(),
},
// Always possible.
ClientMsg::Ping => client.postbox.send_message(ServerMsg::Pong),

View File

@ -33,6 +33,14 @@ pub struct SessionState {
selected_block: Block,
}
/// The action to perform after a tick
enum TickAction {
// Continue executing
Continue,
// Disconnected (i.e. go to main menu)
Disconnect,
}
/// Represents an active game session (i.e., the one being played).
impl SessionState {
/// Create a new `SessionState`.
@ -65,7 +73,7 @@ impl SessionState {
impl SessionState {
/// Tick the session (and the client attached to it).
fn tick(&mut self, dt: Duration) -> Result<(), Error> {
fn tick(&mut self, dt: Duration) -> Result<TickAction, Error> {
self.inputs.tick(dt);
for event in self.client.borrow_mut().tick(
self.inputs.clone(),
@ -79,7 +87,10 @@ impl SessionState {
} => {
self.hud.new_message(event);
},
client::Event::Disconnect => {}, // TODO
client::Event::Disconnect => {
log::warn!("disconnect");
return Ok(TickAction::Disconnect);
},
client::Event::DisconnectionNotification(time) => {
let message = match time {
0 => String::from("Goodbye!"),
@ -94,7 +105,7 @@ impl SessionState {
}
}
Ok(())
Ok(TickAction::Continue)
}
/// Clean up the session (and the client attached to it) after a tick.
@ -390,12 +401,16 @@ impl PlayState for SessionState {
|| !global_state.singleplayer.as_ref().unwrap().is_paused()
{
// Perform an in-game tick.
if let Err(err) = self.tick(clock.get_avg_delta()) {
global_state.info_message =
Some(localized_strings.get("common.connection_lost").to_owned());
error!("[session] Failed to tick the scene: {:?}", err);
match self.tick(clock.get_avg_delta()) {
Ok(TickAction::Continue) => {}, // Do nothing
Ok(TickAction::Disconnect) => return PlayStateResult::Pop, // Go to main menu
Err(err) => {
global_state.info_message =
Some(localized_strings.get("common.connection_lost").to_owned());
error!("[session] Failed to tick the scene: {:?}", err);
return PlayStateResult::Pop;
return PlayStateResult::Pop;
},
}
}