fix voxygen state system. before we had a timing error that we did the next voxygen step before client set in_game which lead us to a disconnect.

now assume in_game is correct in client unless told by server in its answer
This commit is contained in:
Marcel Märtens 2020-10-05 01:11:02 +02:00
parent b1db5ef488
commit d7a74c0cf1
3 changed files with 27 additions and 16 deletions

View File

@ -116,8 +116,8 @@ pub struct Client {
singleton_stream: Stream,
ping_stream: Stream,
register_stream: Stream,
not_in_game_stream: Stream,
in_game_stream: Stream,
not_in_game_stream: Stream,
client_timeout: Duration,
last_server_ping: f64,
@ -161,8 +161,8 @@ impl Client {
let stream = block_on(participant.opened())?;
let mut ping_stream = block_on(participant.opened())?;
let mut register_stream = block_on(participant.opened())?;
let not_in_game_stream = block_on(participant.opened())?;
let in_game_stream = block_on(participant.opened())?;
let not_in_game_stream = block_on(participant.opened())?;
register_stream.send(ClientType::Game)?;
let server_info: ServerInfo = block_on(register_stream.recv())?;
@ -456,7 +456,10 @@ impl Client {
Err(RegisterError::InvalidCharacter) => Err(Error::InvalidCharacter),
Err(RegisterError::NotOnWhitelist) => Err(Error::NotOnWhitelist),
Err(RegisterError::Banned(reason)) => Err(Error::Banned(reason)),
Ok(()) => Ok(()),
Ok(()) => {
self.registered = true;
Ok(())
},
}
}
@ -466,6 +469,9 @@ impl Client {
.send(ClientNotInGameMsg::Character(character_id))
.unwrap();
//Assume we are in_game unless server tells us otherwise
self.client_ingame = Some(ClientIngame::Character);
self.active_character_id = Some(character_id);
}
@ -1351,6 +1357,7 @@ impl Client {
},
// Cleanup for when the client goes back to the `in_game = None`
ServerInGameMsg::ExitInGameSuccess => {
self.client_ingame = None;
self.clean_state();
},
ServerInGameMsg::InventoryUpdate(mut inventory, event) => {
@ -1409,11 +1416,13 @@ impl Client {
self.character_list.error = Some(error);
},
ServerNotInGameMsg::CharacterDataLoadError(error) => {
trace!("Handling join error by server");
self.client_ingame = None;
self.clean_state();
self.character_list.error = Some(error);
},
ServerNotInGameMsg::CharacterSuccess => {
warn!("WOOP88u8yeah");
debug!("client is now in ingame state on server");
},
}
Ok(())
@ -1447,23 +1456,23 @@ impl Client {
) -> Result<(), Error> {
loop {
let (m1, m2, m3, m4) = select!(
msg = self.singleton_stream.recv().fuse() => (Some(msg?), None, None, None),
msg = self.ping_stream.recv().fuse() => (None, Some(msg?), None, None),
msg = self.not_in_game_stream.recv().fuse() => (None, None, Some(msg?), None),
msg = self.in_game_stream.recv().fuse() => (None, None, None, Some(msg?)),
msg = self.singleton_stream.recv().fuse() => (Some(msg), None, None, None),
msg = self.ping_stream.recv().fuse() => (None, Some(msg), None, None),
msg = self.not_in_game_stream.recv().fuse() => (None, None, Some(msg), None),
msg = self.in_game_stream.recv().fuse() => (None, None, None, Some(msg)),
);
*cnt += 1;
if let Some(msg) = m1 {
self.handle_server_msg(frontend_events, msg)?;
self.handle_server_msg(frontend_events, msg?)?;
}
if let Some(msg) = m2 {
self.handle_ping_msg(msg)?;
self.handle_ping_msg(msg?)?;
}
if let Some(msg) = m3 {
self.handle_server_not_in_game_msg(msg)?;
self.handle_server_not_in_game_msg(msg?)?;
}
if let Some(msg) = m4 {
self.handle_server_in_game_msg(frontend_events, msg)?;
self.handle_server_in_game_msg(frontend_events, msg?)?;
}
}
}

View File

@ -61,8 +61,11 @@ impl PlayState for CharSelectionState {
fn tick(&mut self, global_state: &mut GlobalState, events: Vec<WinEvent>) -> PlayStateResult {
span!(_guard, "tick", "<CharSelectionState as PlayState>::tick");
let client_in_game = self.client.borrow().get_in_game();
if client_in_game.is_none() {
let (client_in_game, client_registered) = {
let client = self.client.borrow();
(client.get_in_game(), client.get_registered())
};
if client_in_game.is_none() && client_registered {
// Handle window events
for event in events {
if self.char_selection_ui.handle_event(event.clone()) {

View File

@ -211,12 +211,11 @@ impl PlayState for SessionState {
));
// TODO: can this be a method on the session or are there borrowcheck issues?
let (client_in_game, client_registered) = {
let client = self.client.borrow();
(client.get_in_game(), client.get_registered())
};
if client_in_game.is_none() {
if client_in_game.is_some() {
// Update MyEntity
// Note: Alternatively, the client could emit an event when the entity changes
// which may or may not be more elegant