diff options
| author | metamuffin <metamuffin@disroot.org> | 2025-10-30 11:22:38 +0100 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2025-10-30 11:22:38 +0100 |
| commit | a85f6200517405918941cc64ba4b734e246bc411 (patch) | |
| tree | 267f027215e38f5db55181cf3b9706962763cdfa /server | |
| parent | 269da6178e51f727a2b80a784e59981a13704df4 (diff) | |
| download | hurrycurry-a85f6200517405918941cc64ba4b734e246bc411.tar hurrycurry-a85f6200517405918941cc64ba4b734e246bc411.tar.bz2 hurrycurry-a85f6200517405918941cc64ba4b734e246bc411.tar.zst | |
Configurable lobby map and inactivity kick timout (close #492)
Diffstat (limited to 'server')
| -rw-r--r-- | server/src/commands.rs | 2 | ||||
| -rw-r--r-- | server/src/main.rs | 45 | ||||
| -rw-r--r-- | server/src/server.rs | 65 | ||||
| -rw-r--r-- | server/src/state.rs | 4 |
4 files changed, 81 insertions, 35 deletions
diff --git a/server/src/commands.rs b/server/src/commands.rs index a59d93a0..bc4696ae 100644 --- a/server/src/commands.rs +++ b/server/src/commands.rs @@ -194,7 +194,7 @@ impl Server { .ok(); self.load( self.index - .generate_with_book("lobby") + .generate_with_book(&self.config.lobby) .map_err(|e| TrError::Plain(e.to_string()))?, None, ); diff --git a/server/src/main.rs b/server/src/main.rs index 727ad4b1..b1086b39 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -20,7 +20,10 @@ use clap::Parser; use futures_util::{SinkExt, StreamExt}; use hurrycurry_locale::trm; use hurrycurry_protocol::{PacketC, PacketS}; -use hurrycurry_server::{ConnectionID, server::Server}; +use hurrycurry_server::{ + ConnectionID, + server::{Server, ServerConfig}, +}; use log::{LevelFilter, debug, info, trace, warn}; use std::{ env::var, net::SocketAddr, path::PathBuf, process::exit, str::FromStr, sync::Arc, @@ -45,6 +48,12 @@ pub(crate) struct Args { /// Set the address on which the server should listen #[arg(short, long, default_value = "[::]:27032")] listen: SocketAddr, + /// Map name to use as lobby + #[arg(long, default_value = "lobby")] + lobby: String, + /// Inactivity kick timeout in seconds + #[arg(long, default_value_t = 60.)] + inactivity_kick_timeout: f32, /// Enables submissions to the public server registry #[arg(long)] #[cfg(feature = "register")] @@ -115,8 +124,13 @@ async fn run(data_path: PathBuf, args: Args) -> anyhow::Result<()> { let (tx, _) = broadcast::channel::<PacketC>(128 * 1024); - let mut state = Server::new(data_path, tx)?; - state.load(state.index.generate_with_book("lobby")?, None); + let config = ServerConfig { + inactivity_kick_timeout: args.inactivity_kick_timeout, + lobby: args.lobby, + }; + + let mut state = Server::new(data_path, config, tx)?; + state.load(state.index.generate_with_book(&state.config.lobby)?, None); let state = Arc::new(RwLock::new(state)); #[cfg(feature = "register")] @@ -313,7 +327,10 @@ fn find_data_path() -> Result<PathBuf> { #[cfg(test)] mod test { use hurrycurry_protocol::{Character, PacketS, PlayerClass, PlayerID}; - use hurrycurry_server::{ConnectionID, server::Server}; + use hurrycurry_server::{ + ConnectionID, + server::{Server, ServerConfig}, + }; use std::future::Future; use tokio::sync::broadcast; @@ -324,29 +341,39 @@ mod test { .unwrap() .block_on(body); } + fn server() -> Server { + Server::new( + "../data".into(), + ServerConfig::default(), + broadcast::channel(1024).0, + ) + .unwrap() + } #[test] fn run() { - harness(async { Server::new("../data".into(), broadcast::channel(1024).0).unwrap() }); + harness(async { + server(); + }); } #[test] fn map_load() { harness(async { - let mut s = Server::new("../data".into(), broadcast::channel(1024).0).unwrap(); + let mut s = server(); s.load(s.index.generate("5star").unwrap(), None); }); } #[test] fn map_load_book() { harness(async { - let mut s = Server::new("../data".into(), broadcast::channel(1024).0).unwrap(); + let mut s = server(); s.load(s.index.generate_with_book("lobby").unwrap(), None); }); } #[test] fn tick() { harness(async { - let mut s = Server::new("../data".into(), broadcast::channel(1024).0).unwrap(); + let mut s = server(); for _ in 0..100 { s.tick(0.1); } @@ -355,7 +382,7 @@ mod test { #[test] fn packet_sender_verif() { harness(async { - let mut s = Server::new("../data".into(), broadcast::channel(1024).0).unwrap(); + let mut s = server(); for (conn, p) in [ PacketS::Effect { diff --git a/server/src/server.rs b/server/src/server.rs index e3bcd63d..66553640 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -59,7 +59,13 @@ pub enum AnnounceState { Done, } +pub struct ServerConfig { + pub inactivity_kick_timeout: f32, + pub lobby: String, +} + pub struct Server { + pub config: ServerConfig, pub tick_perf: (Duration, usize), pub broadcast: broadcast::Sender<PacketC>, pub connections: HashMap<ConnectionID, ConnectionData>, @@ -79,6 +85,41 @@ pub struct Server { pub editor_address: Option<String>, } +impl Server { + pub fn new( + data_path: PathBuf, + config: ServerConfig, + tx: broadcast::Sender<PacketC>, + ) -> Result<Self> { + Ok(Self { + config, + game: Game::default(), + tick_perf: (Duration::ZERO, 0), + index: DataIndex::new(data_path).context("Failed to load data index")?, + broadcast: tx, + announce_state: AnnounceState::Done, + packet_out: VecDeque::new(), + connections: HashMap::new(), + data: Serverdata::default().into(), + entities: Vec::new(), + score_changed: false, + packet_loopback: VecDeque::new(), + last_movement_update: HashMap::default(), + scoreboard: ScoreboardStore::load().context("Failed to load scoreboards")?, + editor_address: None, + paused: false, + }) + } +} +impl Default for ServerConfig { + fn default() -> Self { + Self { + inactivity_kick_timeout: 60., + lobby: "lobby".to_string(), + } + } +} + pub trait GameServerExt { fn unload(&mut self, packet_out: &mut VecDeque<PacketC>); fn load( @@ -313,28 +354,6 @@ impl GameServerExt for Game { } impl Server { - pub fn new(data_path: PathBuf, tx: broadcast::Sender<PacketC>) -> Result<Self> { - Ok(Self { - game: Game::default(), - tick_perf: (Duration::ZERO, 0), - index: DataIndex::new(data_path).context("Failed to load data index")?, - broadcast: tx, - announce_state: AnnounceState::Done, - packet_out: VecDeque::new(), - connections: HashMap::new(), - data: Serverdata::default().into(), - entities: Vec::new(), - score_changed: false, - packet_loopback: VecDeque::new(), - last_movement_update: HashMap::default(), - scoreboard: ScoreboardStore::load().context("Failed to load scoreboards")?, - editor_address: None, - paused: false, - }) - } -} - -impl Server { pub fn load( &mut self, (gamedata, serverdata): (Gamedata, Serverdata), @@ -778,7 +797,7 @@ impl Server { .collect(), self.game.score.clone(), ); - Some(("lobby".to_string(), None)) + Some((self.config.lobby.to_string(), None)) } else { None } diff --git a/server/src/state.rs b/server/src/state.rs index a42c1663..fc97a7d1 100644 --- a/server/src/state.rs +++ b/server/src/state.rs @@ -34,7 +34,7 @@ impl Server { let mut idle_kick = Vec::new(); for (cid, conn) in &mut self.connections { conn.last_player_input += dt; - if conn.last_player_input > 60. { + if conn.last_player_input > self.config.inactivity_kick_timeout { idle_kick.push(*cid); } } @@ -201,7 +201,7 @@ impl Server { .ok(); self.load( self.index - .generate_with_book("lobby") + .generate_with_book(&self.config.lobby) .map_err(|m| tre!("s.error.map_load", s = format!("{m}")))?, None, ); |