implemented the playerlist and player count

This commit is contained in:
Luuk van Oijen committed 2023-11-09 10:57:34 +01:00
1 parent 5011ae280c
commit efad9ec03e
2 files changed
+34

No files matched your search

+2
View File
@@ -322,6 +322,7 @@ impl Client {
self.disconnect(); self.disconnect();
} }
// Panics when userdata is not set!
pub fn get_name(&self) -> &str { pub fn get_name(&self) -> &str {
&self.info.as_ref().unwrap().username &self.info.as_ref().unwrap().username
} }
@@ -330,6 +331,7 @@ impl Client {
self.id self.id
} }
// Panics when userdata is not set!
pub fn get_roles(&self) -> &str { pub fn get_roles(&self) -> &str {
&self.info.as_ref().unwrap().roles &self.info.as_ref().unwrap().roles
} }
+32
View File
@@ -47,6 +47,8 @@ pub struct Server {
connect_runtime_handle: JoinHandle<()>, connect_runtime_handle: JoinHandle<()>,
config: Arc<Config>, config: Arc<Config>,
last_plist_update: Instant,
} }
impl Server { impl Server {
@@ -107,6 +109,8 @@ impl Server {
} }
if set.is_empty() == false { if set.is_empty() == false {
// Because join_next() is cancel safe, we can simply cancel it after N duration
// so at worst this client acceptance loop blocks for N duration
tokio::select!( tokio::select!(
_ = set.join_next() => {}, _ = set.join_next() => {},
_ = tokio::time::sleep(tokio::time::Duration::from_secs(1)) => {}, _ = tokio::time::sleep(tokio::time::Duration::from_secs(1)) => {},
@@ -127,6 +131,8 @@ impl Server {
connect_runtime_handle: connect_runtime_handle, connect_runtime_handle: connect_runtime_handle,
config: config, config: config,
last_plist_update: Instant::now(),
}) })
} }
@@ -216,9 +222,32 @@ impl Server {
} }
} }
// Update the player list
if self.last_plist_update.elapsed().as_secs() >= 1 {
self.last_plist_update = Instant::now();
let mut players = String::new();
for client in &self.clients {
players.push_str(&format!("{},", client.get_name()));
}
if players.ends_with(",") {
players.remove(players.len() - 1);
}
let player_count = self.clients.len();
let max_players = self.config.general.max_players;
let data = format!("Ss{player_count}/{max_players}:{players}");
self.broadcast(Packet::Raw(RawPacket::from_str(&data)), None).await;
}
Ok(()) Ok(())
} }
// NOTE: Skips all clients that are currently connecting!
async fn broadcast(&self, packet: Packet, owner: Option<u8>) { async fn broadcast(&self, packet: Packet, owner: Option<u8>) {
for client in &self.clients { for client in &self.clients {
if let Some(id) = owner { if let Some(id) = owner {
@@ -226,6 +255,9 @@ impl Server {
continue; continue;
} }
} }
if client.state == ClientState::Connecting {
continue;
}
client.queue_packet(packet.clone()).await; client.queue_packet(packet.clone()).await;
} }
} }