Skip to content

Commit 4960ada

Browse files
committed
feat: add online player count to status response
1 parent a2bd2be commit 4960ada

File tree

4 files changed

+31
-5
lines changed

4 files changed

+31
-5
lines changed

binaries/pico_limbo/src/handlers/status.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub async fn on_status_request(
1717
version.humanize(),
1818
version.version_number(),
1919
state.description_text(),
20+
state.online_players(),
2021
state.max_players(),
2122
false,
2223
);

binaries/pico_limbo/src/server_state.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use minecraft_packets::play::Dimension;
22
use minecraft_server::server::GetDataDirectory;
33
use std::path::PathBuf;
4+
use std::sync::Arc;
5+
use std::sync::atomic::{AtomicU32, Ordering};
46
use thiserror::Error;
57

68
#[derive(Clone, Debug)]
@@ -12,6 +14,7 @@ pub struct ServerState {
1214
description_text: String,
1315
max_players: u32,
1416
welcome_message: String,
17+
connected_clients: Arc<AtomicU32>,
1518
}
1619

1720
impl ServerState {
@@ -43,6 +46,11 @@ impl ServerState {
4346
Some(self.welcome_message.clone())
4447
}
4548
}
49+
50+
/// Returns the current number of connected clients.
51+
pub fn online_players(&self) -> u32 {
52+
self.connected_clients.load(Ordering::SeqCst)
53+
}
4654
}
4755

4856
impl GetDataDirectory for ServerState {
@@ -53,6 +61,10 @@ impl GetDataDirectory for ServerState {
5361
fn spawn_dimension(&self) -> &Dimension {
5462
&self.spawn_dimension
5563
}
64+
65+
fn connected_clients(&self) -> &Arc<AtomicU32> {
66+
&self.connected_clients
67+
}
5668
}
5769

5870
#[derive(Error, Debug)]
@@ -136,6 +148,7 @@ impl ServerStateBuilder {
136148
description_text: self.description_text,
137149
max_players: self.max_players,
138150
welcome_message: self.welcome_message,
151+
connected_clients: Arc::new(AtomicU32::new(0)),
139152
})
140153
}
141154
}

crates/minecraft_packets/src/status/data/status_response.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ impl StatusResponse {
4444
version_name: &str,
4545
version_protocol: u32,
4646
description_text: &str,
47+
online_players: u32,
4748
max_players: u32,
4849
enforces_secure_chat: bool,
4950
) -> Self {
@@ -60,7 +61,7 @@ impl StatusResponse {
6061
},
6162
players: Players {
6263
max: max_players,
63-
online: 0,
64+
online: online_players,
6465
sample: None,
6566
},
6667
description,

crates/minecraft_server/src/server.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,24 @@ use crate::event_handler::{Handler, ListenerHandler};
33
use minecraft_packets::play::Dimension;
44
use minecraft_protocol::data::packets_report::packet_map::PacketMap;
55
use minecraft_protocol::prelude::{DecodePacket, PacketId};
6+
use minecraft_protocol::state::State;
67
use std::collections::HashMap;
78
use std::future::Future;
89
use std::path::PathBuf;
910
use std::sync::Arc;
10-
use std::time::Duration;
11+
use std::sync::atomic::{AtomicU32, Ordering};
1112
use tokio::net::{TcpListener, TcpStream};
1213
use tokio::signal;
1314
use tokio::sync::Mutex;
14-
use tokio::time::interval;
15+
use tokio::time::{Duration, interval};
1516
use tracing::{debug, error, info};
1617

1718
pub trait GetDataDirectory {
1819
fn data_directory(&self) -> &PathBuf;
1920

2021
fn spawn_dimension(&self) -> &Dimension;
22+
23+
fn connected_clients(&self) -> &Arc<AtomicU32>;
2124
}
2225

2326
pub struct Server<S>
@@ -76,7 +79,7 @@ where
7679
let packet_map = packet_map.clone();
7780
let state = self.state.clone();
7881
tokio::spawn(async move {
79-
if let Err(e) = handle_client(socket, handlers, packet_map, state).await {
82+
if let Err(e) = handle_client(socket, handlers, packet_map, state.clone()).await {
8083
error!("Error handling client {}: {:?}", addr, e);
8184
}
8285
});
@@ -96,7 +99,7 @@ where
9699
}
97100
}
98101

99-
async fn handle_client<S: Clone>(
102+
async fn handle_client<S: Clone + GetDataDirectory>(
100103
socket: TcpStream,
101104
handlers: Arc<HashMap<String, Box<dyn Handler<S>>>>,
102105
packet_map: PacketMap,
@@ -114,6 +117,10 @@ async fn handle_client<S: Clone>(
114117
Ok(named_packet) => {
115118
if let Some(handler) = handlers.get(&named_packet.name) {
116119
handler.handle(state.clone(), client.clone(), named_packet).await;
120+
121+
if client.lock().await.state() == &State::Play {
122+
state.connected_clients().fetch_add(1, Ordering::SeqCst);
123+
}
117124
}
118125
// Silently ignore no handler
119126
}
@@ -138,5 +145,9 @@ async fn handle_client<S: Clone>(
138145
}
139146
}
140147

148+
if client.lock().await.state() == &State::Play {
149+
state.connected_clients().fetch_sub(1, Ordering::SeqCst);
150+
}
151+
141152
Ok(())
142153
}

0 commit comments

Comments
 (0)