mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'capucho/voxygen-logout-timeout' into 'master'
FIX #513 logout timeout See merge request veloren/veloren!837
This commit is contained in:
commit
406767ae31
@ -220,10 +220,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;
|
||||
}
|
||||
pub fn request_logout(&mut self) { self.postbox.send_message(ClientMsg::Disconnect); }
|
||||
|
||||
/// Request a state transition to `ClientState::Registered` from an ingame
|
||||
/// state.
|
||||
@ -722,6 +719,7 @@ impl Client {
|
||||
},
|
||||
ServerMsg::Disconnect => {
|
||||
frontend_events.push(Event::Disconnect);
|
||||
self.postbox.send_message(ClientMsg::Terminate);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -35,4 +35,5 @@ pub enum ClientMsg {
|
||||
key: Vec2<i32>,
|
||||
},
|
||||
Disconnect,
|
||||
Terminate,
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use common::{
|
||||
sync::{Uid, UidAllocator},
|
||||
};
|
||||
use log::error;
|
||||
use specs::{saveload::MarkerAllocator, Builder, Entity as EcsEntity, WorldExt};
|
||||
use specs::{saveload::MarkerAllocator, Builder, Entity as EcsEntity, Join, WorldExt};
|
||||
|
||||
pub fn handle_exit_ingame(server: &mut Server, entity: EcsEntity) {
|
||||
let state = server.state_mut();
|
||||
@ -53,12 +53,19 @@ pub fn handle_client_disconnect(server: &mut Server, entity: EcsEntity) -> Event
|
||||
}
|
||||
|
||||
// Make sure to remove the player from the logged in list. (See AuthProvider)
|
||||
// And send a disconnected message
|
||||
{
|
||||
let players = state.ecs().read_storage::<Player>();
|
||||
let mut accounts = state.ecs().write_resource::<AuthProvider>();
|
||||
let mut clients = state.ecs().write_storage::<Client>();
|
||||
|
||||
if let Some(player) = players.get(entity) {
|
||||
accounts.logout(player.uuid());
|
||||
|
||||
let msg = ServerMsg::broadcast(format!("{} went offline.", &player.alias));
|
||||
for client in (&mut clients).join().filter(|c| c.is_registered()) {
|
||||
client.notify(msg.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
// Delete client entity
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::SysTimer;
|
||||
use crate::{auth_provider::AuthProvider, client::Client, CLIENT_TIMEOUT};
|
||||
use common::{
|
||||
comp::{Admin, Body, CanBuild, Controller, ForceUpdate, Ori, Player, Pos, Stats, Vel},
|
||||
comp::{Admin, CanBuild, Controller, ForceUpdate, Ori, Player, Pos, Stats, Vel},
|
||||
event::{EventBus, ServerEvent},
|
||||
msg::{
|
||||
validate_chat_msg, ChatMsgValidationError, ClientMsg, ClientState, PlayerListUpdate,
|
||||
@ -27,7 +27,6 @@ impl<'a> System<'a> for Sys {
|
||||
ReadExpect<'a, TerrainGrid>,
|
||||
Write<'a, SysTimer<Self>>,
|
||||
ReadStorage<'a, Uid>,
|
||||
ReadStorage<'a, Body>,
|
||||
ReadStorage<'a, CanBuild>,
|
||||
ReadStorage<'a, Admin>,
|
||||
ReadStorage<'a, ForceUpdate>,
|
||||
@ -51,7 +50,6 @@ impl<'a> System<'a> for Sys {
|
||||
terrain,
|
||||
mut timer,
|
||||
uids,
|
||||
bodies,
|
||||
can_build,
|
||||
admins,
|
||||
force_updates,
|
||||
@ -81,7 +79,6 @@ impl<'a> System<'a> for Sys {
|
||||
let mut new_players = Vec::new();
|
||||
|
||||
for (entity, client) in (&entities, &mut clients).join() {
|
||||
let mut disconnect = false;
|
||||
let new_msgs = client.postbox.new_messages();
|
||||
|
||||
// Update client ping.
|
||||
@ -91,7 +88,7 @@ impl<'a> System<'a> for Sys {
|
||||
|| client.postbox.error().is_some()
|
||||
// Postbox error
|
||||
{
|
||||
disconnect = true;
|
||||
server_emitter.emit(ServerEvent::ClientDisconnect(entity));
|
||||
} else if time - client.last_ping > CLIENT_TIMEOUT * 0.5 {
|
||||
// Try pinging the client if the timeout is nearing.
|
||||
client.postbox.send_message(ServerMsg::Ping);
|
||||
@ -285,25 +282,13 @@ impl<'a> System<'a> for Sys {
|
||||
ClientMsg::Ping => client.postbox.send_message(ServerMsg::Pong),
|
||||
ClientMsg::Pong => {},
|
||||
ClientMsg::Disconnect => {
|
||||
disconnect = true;
|
||||
client.postbox.send_message(ServerMsg::Disconnect);
|
||||
},
|
||||
ClientMsg::Terminate => {
|
||||
server_emitter.emit(ServerEvent::ClientDisconnect(entity));
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if disconnect {
|
||||
if let (Some(player), Some(_)) = (
|
||||
players.get(entity),
|
||||
// It only shows a message if you had a body (not in char selection)
|
||||
bodies.get(entity),
|
||||
) {
|
||||
new_chat_msgs.push((
|
||||
None,
|
||||
ServerMsg::broadcast(format!("{} went offline.", &player.alias)),
|
||||
));
|
||||
}
|
||||
server_emitter.emit(ServerEvent::ClientDisconnect(entity));
|
||||
client.postbox.send_message(ServerMsg::Disconnect);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle new players.
|
||||
|
@ -78,7 +78,7 @@ impl PlayState for CharSelectionState {
|
||||
char_data.body,
|
||||
char_data.tool,
|
||||
);
|
||||
return PlayStateResult::Push(Box::new(SessionState::new(
|
||||
return PlayStateResult::Switch(Box::new(SessionState::new(
|
||||
global_state,
|
||||
self.client.clone(),
|
||||
)));
|
||||
@ -141,7 +141,7 @@ impl PlayState for CharSelectionState {
|
||||
) {
|
||||
global_state.info_message =
|
||||
Some(localized_strings.get("common.connection_lost").to_owned());
|
||||
error!("[session] Failed to tick the scene: {:?}", err);
|
||||
error!("[char_selection] Failed to tick the scene: {:?}", err);
|
||||
|
||||
return PlayStateResult::Pop;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ use crate::{
|
||||
hud::{DebugInfo, Event as HudEvent, Hud},
|
||||
i18n::{i18n_asset_key, VoxygenLocalization},
|
||||
key_state::KeyState,
|
||||
menu::char_selection::CharSelectionState,
|
||||
render::Renderer,
|
||||
scene::{camera, Scene, SceneData},
|
||||
window::{AnalogGameInput, Event, GameInput},
|
||||
@ -24,6 +25,14 @@ use specs::{Join, WorldExt};
|
||||
use std::{cell::RefCell, rc::Rc, time::Duration};
|
||||
use vek::*;
|
||||
|
||||
/// The action to perform after a tick
|
||||
enum TickAction {
|
||||
// Continue executing
|
||||
Continue,
|
||||
// Disconnected (i.e. go to main menu)
|
||||
Disconnect,
|
||||
}
|
||||
|
||||
pub struct SessionState {
|
||||
scene: Scene,
|
||||
client: Rc<RefCell<Client>>,
|
||||
@ -65,7 +74,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 +88,7 @@ impl SessionState {
|
||||
} => {
|
||||
self.hud.new_message(event);
|
||||
},
|
||||
client::Event::Disconnect => {}, // TODO
|
||||
client::Event::Disconnect => return Ok(TickAction::Disconnect),
|
||||
client::Event::DisconnectionNotification(time) => {
|
||||
let message = match time {
|
||||
0 => String::from("Goodbye!"),
|
||||
@ -94,7 +103,7 @@ impl SessionState {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(TickAction::Continue)
|
||||
}
|
||||
|
||||
/// Clean up the session (and the client attached to it) after a tick.
|
||||
@ -426,12 +435,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;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -704,6 +717,13 @@ impl PlayState for SessionState {
|
||||
current_client_state = self.client.borrow().get_client_state();
|
||||
}
|
||||
|
||||
if let ClientState::Registered = current_client_state {
|
||||
return PlayStateResult::Switch(Box::new(CharSelectionState::new(
|
||||
global_state,
|
||||
self.client.clone(),
|
||||
)));
|
||||
}
|
||||
|
||||
PlayStateResult::Pop
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user