1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use std::io::Cursor;
use std::net::ToSocketAddrs;
use byteorder::{LittleEndian, ReadBytesExt};
use crate::{A2SClient, ReadCString};
use crate::errors::{Error, Result};
const PLAYER_REQUEST: [u8; 5] = [0xff, 0xff, 0xff, 0xff, 0x55];
#[derive(Debug)]
pub struct Players {
pub count: u8,
pub players: Vec<Player>,
}
#[derive(Debug)]
pub struct Player {
pub index: u8,
pub name: String,
pub score: u32,
pub duration: f32,
pub the_ship: Option<TheShipPlayer>,
}
#[derive(Debug)]
pub struct TheShipPlayer {
pub deaths: u32,
pub money: u32,
}
impl A2SClient {
pub fn players<A: ToSocketAddrs>(&self, addr: A) -> Result<Players> {
let data = self.do_challenge_request(addr, &PLAYER_REQUEST)?;
let mut data = Cursor::new(data);
if data.read_u8()? != 0x44 {
return Err(Error::InvalidResponse);
}
let player_count = data.read_u8()?;
let mut players: Vec<Player> = Vec::with_capacity(player_count as usize);
for _ in 0..player_count {
players.push(Player{
index: data.read_u8()?,
name: data.read_cstring()?,
score: data.read_u32::<LittleEndian>()?,
duration: data.read_f32::<LittleEndian>()?,
the_ship: {
if self.app_id == 2400 {
Some(TheShipPlayer{
deaths: data.read_u32::<LittleEndian>()?,
money: data.read_u32::<LittleEndian>()?,
})
} else {
None
}
}
})
}
Ok(Players{
count: player_count,
players: players,
})
}
}