From 0e75a35c837f59ca226fbc2f578827ed94629ff2 Mon Sep 17 00:00:00 2001 From: Luuk van Oijen Date: Mon, 20 Nov 2023 10:55:31 +0100 Subject: [PATCH] wip updating of server status --- src/heartbeat.rs | 15 +++++++++++---- src/main.rs | 14 +++++++++++++- src/server/mod.rs | 29 ++++++++++++++++------------- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/heartbeat.rs b/src/heartbeat.rs index 44d2392..ee3c917 100644 --- a/src/heartbeat.rs +++ b/src/heartbeat.rs @@ -1,4 +1,5 @@ use serde::Serialize; +use tokio::sync::mpsc::Receiver; #[derive(Serialize)] struct HeartbeatInfo { @@ -18,10 +19,10 @@ struct HeartbeatInfo { desc: String, } -pub async fn backend_heartbeat(config: std::sync::Arc) { - let info = HeartbeatInfo { +pub async fn backend_heartbeat(config: std::sync::Arc, mut hb_rx: Receiver) { + let mut info = HeartbeatInfo { uuid: config.general.auth_key.clone().unwrap_or(String::from("Unknown name!")), - players: 0, // TODO: Implement this. Easiest would probably be to have the server send updates every so often + players: 0, maxplayers: config.general.max_players, port: config.general.port.unwrap_or(30814), map: config.general.map.clone(), @@ -32,7 +33,7 @@ pub async fn backend_heartbeat(config: std::sync::Arc) { modlist: String::from("-"), // TODO: Implement this modstotalsize: 0, // TODO: Implement this modstotal: 0, // TODO: Implement this - playerslist: String::from("luuk-bepis;"), // TODO: Implement this + playerslist: String::new(), desc: config.general.description.clone(), }; @@ -41,6 +42,12 @@ pub async fn backend_heartbeat(config: std::sync::Arc) { interval.tick().await; heartbeat_post(&info).await; + + if let Ok(status) = hb_rx.try_recv() { + trace!("status update: {:?}", status); + info.players = status.player_count; + info.playerslist = status.player_list.clone(); + } } } diff --git a/src/main.rs b/src/main.rs index f9a1f41..2785d06 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,8 @@ #[macro_use] extern crate async_trait; #[macro_use] extern crate lazy_static; +use tokio::sync::mpsc; + mod server; mod config; mod heartbeat; @@ -40,16 +42,26 @@ async fn main() { let user_config = std::sync::Arc::new(user_config); - tokio::spawn(heartbeat::backend_heartbeat(user_config.clone())); + let (hb_tx, hb_rx) = mpsc::channel(100); + + tokio::spawn(heartbeat::backend_heartbeat(user_config.clone(), hb_rx)); let mut server = server::Server::new(user_config) .await .map_err(|e| error!("{:?}", e)) .expect("Failed to start server!"); + let mut status = server.get_server_status(); loop { if let Err(e) = server.process().await { error!("{:?}", e); } + + let new_status = server.get_server_status(); + + if status != new_status { + status = new_status; + hb_tx.send(status.clone()); + } } } diff --git a/src/server/mod.rs b/src/server/mod.rs index 0b0c1c9..c16ffa2 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -71,19 +71,11 @@ fn load_plugins() -> Vec { plugins } -#[derive(PartialEq, IntoPrimitive, Copy, Clone, Debug)] -#[repr(u8)] -enum ServerState { - Unknown = 0, - - WaitingForClients, - WaitingForReady, - WaitingForSpawns, - Qualifying, - LiningUp, - Countdown, - Race, - Finish, +#[derive(PartialEq, Clone, Debug)] +pub struct ServerStatus { + pub player_count: usize, + pub player_list: String, + pub max_players: usize, } pub struct Server { @@ -338,6 +330,17 @@ impl Server { Ok(()) } + pub fn get_server_status(&self) -> ServerStatus { + ServerStatus { + player_count: self.clients.len(), + player_list: self.clients.iter().map(|client| { + format!("{};", &client.get_name()) + }).collect(), + // max_players: self.max_players, // TODO: Support this + max_players: self.config.general.max_players, + } + } + async fn process_udp(&mut self) -> anyhow::Result<()> { // Process UDP packets // TODO: Use a UDP addr -> client ID look up table