Skip to content

Commit e37709a

Browse files
committed
Sort and dedup servers when querying a single master server.
1 parent 2bd378a commit e37709a

File tree

3 files changed

+26
-19
lines changed

3 files changed

+26
-19
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description = "Get server addresses from QuakeWorld master servers."
44
keywords = ["masters", "quake", "quakeworld", "servers"]
55
repository = "https://github.com/quakeworld/masterstat"
66
authors = ["Viktor Persson <viktor.persson@arcsin.se>"]
7-
version = "0.3.0"
7+
version = "0.4.0"
88
edition = "2021"
99
license = "MIT"
1010
include = [

src/command.rs

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,8 @@ pub async fn server_addresses(
2929
master_address: &str,
3030
timeout: Duration,
3131
) -> Result<Vec<ServerAddress>> {
32-
const STATUS_MSG: [u8; 3] = [99, 10, 0];
33-
let response = tinyudp::send_and_receive(
34-
master_address,
35-
&STATUS_MSG,
36-
tinyudp::Options {
37-
timeout,
38-
buffer_size: 64 * 1024, // 64 kb
39-
},
40-
)
41-
.await?;
42-
parse_servers_response(&response)
32+
let servers = get_server_addresses(master_address, timeout).await?;
33+
Ok(sorted_and_unique(&servers))
4334
}
4435

4536
/// Get server addresses from many master servers (concurrently)
@@ -66,7 +57,7 @@ pub async fn server_addresses_from_many(
6657
for master_address in master_addresses.iter().map(|a| a.as_ref().to_string()) {
6758
let result_mux = result_mux.clone();
6859
let task = tokio::spawn(async move {
69-
if let Ok(servers) = server_addresses(&master_address, timeout).await {
60+
if let Ok(servers) = get_server_addresses(&master_address, timeout).await {
7061
let mut result = result_mux.lock().await;
7162
result.extend(servers);
7263
}
@@ -80,7 +71,24 @@ pub async fn server_addresses_from_many(
8071
sorted_and_unique(&server_addresses)
8172
}
8273

83-
fn parse_servers_response(response: &[u8]) -> Result<Vec<ServerAddress>> {
74+
async fn get_server_addresses(
75+
master_address: &str,
76+
timeout: Duration,
77+
) -> Result<Vec<ServerAddress>> {
78+
const STATUS_MSG: [u8; 3] = [99, 10, 0];
79+
let response = tinyudp::send_and_receive(
80+
master_address,
81+
&STATUS_MSG,
82+
tinyudp::Options {
83+
timeout,
84+
buffer_size: 64 * 1024, // 64 kb
85+
},
86+
)
87+
.await?;
88+
parse_response(&response)
89+
}
90+
91+
fn parse_response(response: &[u8]) -> Result<Vec<ServerAddress>> {
8492
const RESPONSE_HEADER: [u8; 6] = [255, 255, 255, 255, 100, 10];
8593

8694
if !response.starts_with(&RESPONSE_HEADER) {
@@ -133,11 +141,11 @@ mod tests {
133141
}
134142

135143
#[tokio::test]
136-
async fn test_parse_servers_response() -> Result<()> {
144+
async fn test_parse_response() -> Result<()> {
137145
// invalid response header
138146
{
139147
let response = [0xff, 0xff];
140-
let result = parse_servers_response(&response);
148+
let result = parse_response(&response);
141149
assert_eq!(result.unwrap_err().to_string(), "Invalid response");
142150
}
143151

@@ -147,7 +155,7 @@ mod tests {
147155
0xff, 0xff, 0xff, 0xff, 0x64, 0x0a, 192, 168, 1, 1, 0x75, 0x30, 192, 168, 1, 2,
148156
0x75, 0x30,
149157
];
150-
let result = parse_servers_response(&response)?;
158+
let result = parse_response(&response)?;
151159
assert_eq!(result.len(), 2);
152160
assert_eq!(result[0].ip, "192.168.1.1");
153161
assert_eq!(result[0].port, 30000);

src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,5 @@ mod command;
66
mod server_address;
77
mod tinyudp;
88

9-
pub use crate::command::server_addresses;
10-
pub use crate::command::server_addresses_from_many;
9+
pub use crate::command::{server_addresses, server_addresses_from_many};
1110
pub use crate::server_address::ServerAddress;

0 commit comments

Comments
 (0)