mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Implement the Player Timeout as config
This commit is contained in:
parent
198c12babc
commit
961b8a4d7c
@ -52,14 +52,6 @@ use tracing::{debug, error, trace, warn};
|
|||||||
use uvth::{ThreadPool, ThreadPoolBuilder};
|
use uvth::{ThreadPool, ThreadPoolBuilder};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
// The duration of network inactivity until the player is kicked
|
|
||||||
// @TODO: in the future, this should be configurable on the server
|
|
||||||
// and be provided to the client
|
|
||||||
const SERVER_TIMEOUT: f64 = 40.0;
|
|
||||||
|
|
||||||
// After this duration has elapsed, the user will begin getting kick warnings in
|
|
||||||
// their chat window
|
|
||||||
const SERVER_TIMEOUT_GRACE_PERIOD: f64 = 14.0;
|
|
||||||
const PING_ROLLING_AVERAGE_SECS: usize = 10;
|
const PING_ROLLING_AVERAGE_SECS: usize = 10;
|
||||||
|
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
@ -117,6 +109,7 @@ pub struct Client {
|
|||||||
participant: Option<Participant>,
|
participant: Option<Participant>,
|
||||||
singleton_stream: Stream,
|
singleton_stream: Stream,
|
||||||
|
|
||||||
|
client_timeout: Duration,
|
||||||
last_server_ping: f64,
|
last_server_ping: f64,
|
||||||
last_server_pong: f64,
|
last_server_pong: f64,
|
||||||
last_ping_delta: f64,
|
last_ping_delta: f64,
|
||||||
@ -173,6 +166,7 @@ impl Client {
|
|||||||
world_map,
|
world_map,
|
||||||
recipe_book,
|
recipe_book,
|
||||||
max_group_size,
|
max_group_size,
|
||||||
|
client_timeout,
|
||||||
) = block_on(async {
|
) = block_on(async {
|
||||||
loop {
|
loop {
|
||||||
match stream.recv().await? {
|
match stream.recv().await? {
|
||||||
@ -181,6 +175,7 @@ impl Client {
|
|||||||
server_info,
|
server_info,
|
||||||
time_of_day,
|
time_of_day,
|
||||||
max_group_size,
|
max_group_size,
|
||||||
|
client_timeout,
|
||||||
world_map,
|
world_map,
|
||||||
recipe_book,
|
recipe_book,
|
||||||
} => {
|
} => {
|
||||||
@ -358,6 +353,7 @@ impl Client {
|
|||||||
(world_map, map_size, map_bounds),
|
(world_map, map_size, map_bounds),
|
||||||
recipe_book,
|
recipe_book,
|
||||||
max_group_size,
|
max_group_size,
|
||||||
|
client_timeout,
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
ServerMsg::TooManyPlayers => break Err(Error::TooManyPlayers),
|
ServerMsg::TooManyPlayers => break Err(Error::TooManyPlayers),
|
||||||
@ -399,6 +395,7 @@ impl Client {
|
|||||||
_network: network,
|
_network: network,
|
||||||
participant: Some(participant),
|
participant: Some(participant),
|
||||||
singleton_stream: stream,
|
singleton_stream: stream,
|
||||||
|
client_timeout,
|
||||||
|
|
||||||
last_server_ping: 0.0,
|
last_server_ping: 0.0,
|
||||||
last_server_pong: 0.0,
|
last_server_pong: 0.0,
|
||||||
@ -1434,7 +1431,10 @@ impl Client {
|
|||||||
let duration_since_last_pong = self.state.get_time() - self.last_server_pong;
|
let duration_since_last_pong = self.state.get_time() - self.last_server_pong;
|
||||||
|
|
||||||
// Dispatch a notification to the HUD warning they will be kicked in {n} seconds
|
// Dispatch a notification to the HUD warning they will be kicked in {n} seconds
|
||||||
if duration_since_last_pong >= SERVER_TIMEOUT_GRACE_PERIOD
|
const KICK_WARNING_AFTER_REL_TO_TIMEOUT_FRACTION: f64 = 0.75;
|
||||||
|
if duration_since_last_pong
|
||||||
|
>= (self.client_timeout.as_secs() as f64
|
||||||
|
* KICK_WARNING_AFTER_REL_TO_TIMEOUT_FRACTION)
|
||||||
&& self.state.get_time() - duration_since_last_pong > 0.
|
&& self.state.get_time() - duration_since_last_pong > 0.
|
||||||
{
|
{
|
||||||
frontend_events.push(Event::DisconnectionNotification(
|
frontend_events.push(Event::DisconnectionNotification(
|
||||||
@ -1453,7 +1453,9 @@ impl Client {
|
|||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if handles_msg == 0 && self.state.get_time() - self.last_server_pong > SERVER_TIMEOUT {
|
if handles_msg == 0
|
||||||
|
&& self.state.get_time() - self.last_server_pong > self.client_timeout.as_secs() as f64
|
||||||
|
{
|
||||||
return Err(Error::ServerTimeout);
|
return Err(Error::ServerTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ use crate::{
|
|||||||
use authc::AuthClientError;
|
use authc::AuthClientError;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::time::Duration;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
@ -189,6 +190,7 @@ pub enum ServerMsg {
|
|||||||
server_info: ServerInfo,
|
server_info: ServerInfo,
|
||||||
time_of_day: state::TimeOfDay,
|
time_of_day: state::TimeOfDay,
|
||||||
max_group_size: u32,
|
max_group_size: u32,
|
||||||
|
client_timeout: Duration,
|
||||||
world_map: WorldMapMsg,
|
world_map: WorldMapMsg,
|
||||||
recipe_book: RecipeBook,
|
recipe_book: RecipeBook,
|
||||||
},
|
},
|
||||||
|
@ -70,8 +70,6 @@ use world::{
|
|||||||
#[macro_use] extern crate diesel;
|
#[macro_use] extern crate diesel;
|
||||||
#[macro_use] extern crate diesel_migrations;
|
#[macro_use] extern crate diesel_migrations;
|
||||||
|
|
||||||
const CLIENT_TIMEOUT: f64 = 40.0; // Seconds
|
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
struct SpawnPoint(Vec3<f32>);
|
struct SpawnPoint(Vec3<f32>);
|
||||||
|
|
||||||
@ -753,6 +751,7 @@ impl Server {
|
|||||||
server_info: self.get_server_info(),
|
server_info: self.get_server_info(),
|
||||||
time_of_day: *self.state.ecs().read_resource(),
|
time_of_day: *self.state.ecs().read_resource(),
|
||||||
max_group_size: self.settings().max_player_group_size,
|
max_group_size: self.settings().max_player_group_size,
|
||||||
|
client_timeout: self.settings().client_timeout,
|
||||||
world_map: self.map.clone(),
|
world_map: self.map.clone(),
|
||||||
recipe_book: (&*default_recipe_book()).clone(),
|
recipe_book: (&*default_recipe_book()).clone(),
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use portpicker::pick_unused_port;
|
use portpicker::pick_unused_port;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{fs, io::prelude::*, net::SocketAddr, path::PathBuf};
|
use std::{fs, io::prelude::*, net::SocketAddr, path::PathBuf, time::Duration};
|
||||||
use tracing::{error, warn};
|
use tracing::{error, warn};
|
||||||
use world::sim::FileOpts;
|
use world::sim::FileOpts;
|
||||||
|
|
||||||
@ -27,6 +27,7 @@ pub struct ServerSettings {
|
|||||||
pub max_view_distance: Option<u32>,
|
pub max_view_distance: Option<u32>,
|
||||||
pub banned_words_files: Vec<PathBuf>,
|
pub banned_words_files: Vec<PathBuf>,
|
||||||
pub max_player_group_size: u32,
|
pub max_player_group_size: u32,
|
||||||
|
pub client_timeout: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ServerSettings {
|
impl Default for ServerSettings {
|
||||||
@ -47,6 +48,7 @@ impl Default for ServerSettings {
|
|||||||
max_view_distance: Some(30),
|
max_view_distance: Some(30),
|
||||||
banned_words_files: Vec::new(),
|
banned_words_files: Vec::new(),
|
||||||
max_player_group_size: 6,
|
max_player_group_size: 6,
|
||||||
|
client_timeout: Duration::from_secs(40),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,6 +115,7 @@ impl ServerSettings {
|
|||||||
* to use admin commands or not */
|
* to use admin commands or not */
|
||||||
persistence_db_dir,
|
persistence_db_dir,
|
||||||
max_view_distance: None,
|
max_view_distance: None,
|
||||||
|
client_timeout: Duration::from_secs(180),
|
||||||
..load // Fill in remaining fields from server_settings.ron.
|
..load // Fill in remaining fields from server_settings.ron.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::SysTimer;
|
use super::SysTimer;
|
||||||
use crate::{
|
use crate::{
|
||||||
alias_validator::AliasValidator, client::Client, login_provider::LoginProvider,
|
alias_validator::AliasValidator, client::Client, login_provider::LoginProvider,
|
||||||
persistence::character::CharacterLoader, ServerSettings, CLIENT_TIMEOUT,
|
persistence::character::CharacterLoader, ServerSettings,
|
||||||
};
|
};
|
||||||
use common::{
|
use common::{
|
||||||
comp::{
|
comp::{
|
||||||
@ -519,7 +519,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
// Update client ping.
|
// Update client ping.
|
||||||
if cnt > 0 {
|
if cnt > 0 {
|
||||||
client.last_ping = time.0
|
client.last_ping = time.0
|
||||||
} else if time.0 - client.last_ping > CLIENT_TIMEOUT
|
} else if time.0 - client.last_ping > settings.client_timeout.as_secs() as f64
|
||||||
// Timeout
|
// Timeout
|
||||||
{
|
{
|
||||||
info!(?entity, "timeout error with client, disconnecting");
|
info!(?entity, "timeout error with client, disconnecting");
|
||||||
@ -529,7 +529,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
{
|
{
|
||||||
debug!(?entity, "postbox error with client, disconnecting");
|
debug!(?entity, "postbox error with client, disconnecting");
|
||||||
server_emitter.emit(ServerEvent::ClientDisconnect(entity));
|
server_emitter.emit(ServerEvent::ClientDisconnect(entity));
|
||||||
} else if time.0 - client.last_ping > CLIENT_TIMEOUT * 0.5 {
|
} else if time.0 - client.last_ping > settings.client_timeout.as_secs() as f64 * 0.5 {
|
||||||
// Try pinging the client if the timeout is nearing.
|
// Try pinging the client if the timeout is nearing.
|
||||||
client.notify(ServerMsg::Ping);
|
client.notify(ServerMsg::Ping);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user