mirror of
https://github.com/tribufu/rust-gamedig
synced 2026-05-06 07:17:27 +00:00
[Protocol] Standardize fields (#84)
* [Protocol] Standardize The Ship fields * [Protocol] Standardize FFOW fields * [Protocol] Rename Valve's protocol field to protocol_version * [Protocol] Rename Minecraft's version_protocol field to protocol_version * [Protocol] Rename Valve's version field to game_version * [Protocol] Rename Minecraft java version_name to game_version * [Crate] Reformat RESPONSES.md * [Protocol] Renamed Minecraft Java players_sample to players * [Protocol] Rename Quake (1,2,3) version field to game_version * [Protocol] Rename quake (1 and 2) game_type field to game_mode * [Protocol] Rename Valve, FFOW, TS game field to game_mode * [Generics] Rename game field/function to game_mode * [Protocol] Change players_minimum, _maximum and _bots from those who werent u8 or u32 to u32 * [Protocol] Change instances of player score field type from u32 to i32 * [Crate] Nicer gramar in CHANGELOG * [Protocol] Apply clippy fixes
This commit is contained in:
parent
65c56dc196
commit
9d8fb1ba94
25 changed files with 249 additions and 200 deletions
52
CHANGELOG.md
52
CHANGELOG.md
|
|
@ -18,6 +18,58 @@ Crate:
|
|||
- The enum used for errors, `GDError` has been renamed to `GDErrorKind`.
|
||||
- `GDError` is now a struct that holds its kind, the source and a backtrace.
|
||||
|
||||
Generics:
|
||||
- Renamed `CommonResponseJson`'s `game` field (and the function) to `game_mode`.
|
||||
- Changed `players_maximum` and `players_online` (and their functions) types from `u64` to `u32`.
|
||||
- Changed `score` type (and the function) of player from `u32` to `i32`.
|
||||
|
||||
Protocol:
|
||||
- Valve:
|
||||
1. Renamed `protocol` to `protocol_version`.
|
||||
2. Renamed `version` to `game_version`.
|
||||
3. Renamed `game` to `game_mode`.
|
||||
4. Changed `score` type of player from `u32` to `i32`.
|
||||
|
||||
- GameSpy (1, 2, 3):
|
||||
1. Renamed `version` to `game_version`.
|
||||
2. Changed `players_maximum` and `players_online` (and their functions) types from `usize` to `u32`.
|
||||
|
||||
- GameSpy 1:
|
||||
1. Changed `score` type of player from `u32` to `i32`.
|
||||
|
||||
- Quake (1, 2):
|
||||
1. Renamed `game_type` to `game_mode`.
|
||||
|
||||
- Minecraft Java
|
||||
1. Renamed `version_protocol` to `protocol_version`.
|
||||
2. Renamed `version_name` to `game_version`.
|
||||
3. Renamed `players_sample` to `players`.
|
||||
|
||||
- Minecraft Bedrock
|
||||
1. Renamed `version_protocol` to `protocol_version`.
|
||||
|
||||
- The Ship:
|
||||
1. Renamed `protocol` to `protocol_version`.
|
||||
2. Renamed `max_players` to `players_maximum` and changed its type from `u64` to `u32`.
|
||||
3. Renamed `bots` to `players_bots`. and changed its type from `u64` to `u32`.
|
||||
4. Renamed `players` to `players_online`.
|
||||
5. Renamed `players_details` to `players`.
|
||||
6. Renamed `game` to `game_mode`.
|
||||
7. Added field `game_version`.
|
||||
8. Changed `players_bots` type from `Option<u64>` to `Option<u32>`.
|
||||
9. Changed `score` type of player from `u32` to `i32`.
|
||||
|
||||
- Frontlines: Fuel of War:
|
||||
1. Renamed `game_mode` to `game`.
|
||||
2. Renamed `version` to `game_version`.
|
||||
3. Renamed `protocol` to `protocol_version`.
|
||||
4. Renamed `game` to `game_mode`.
|
||||
5. Changed `players_maximum` and `players_minimum` types from `usize` to `u32`.
|
||||
|
||||
- Just Cause 2: Multiplayer:
|
||||
1. Renamed `version` to `game_version`.
|
||||
2. Changed `players_maximum` and `players_minimum` types from `usize` to `u32`.
|
||||
|
||||
# 0.3.0 - 18/07/2023
|
||||
### Changes:
|
||||
Protocols:
|
||||
|
|
|
|||
94
RESPONSES.md
94
RESPONSES.md
|
|
@ -5,50 +5,50 @@ In the case that a field that performs the same function exists in the current c
|
|||
|
||||
# Response table
|
||||
|
||||
| Field | Generic | GameSpy(1) | GameSpy(2) | GameSpy(3) | Minecraft(Java) | Minecraft(Bedrock) | Valve | Quake | Proprietary: FFOW | Proprietary: TheShip |
|
||||
| :--------------- | ---------------- | ------------ | ------------ | ------------ | ----------------- | -------------------- | -------- | -------- | -------- | --------- |
|
||||
| name | `Option<String>` | `String` | `String` | `String` | | `String` | `String` | `String` | `String` | `String` |
|
||||
| description | `Option<String>` | | | | `String` | | | | `String` | |
|
||||
| game | `Option<String>` | `String` (game_type) | | `String` (game_type) | | `Option<GameMode>` (game_mode) | `String` | | `String` (game_mode) | `String` |
|
||||
| game_version | `Option<String>` | `String` | | `String` | `String` (version_name) | | `String` (version) | `String` (version) | `String` (version) | `String` (version) |
|
||||
| map | `Option<String>` | `String` | `String` | `String` | | `Option<String>` | `String` | `String` | `String` | `String` |
|
||||
| players_maxmimum | `u64` | `usize` | `usize` | `usize` | `u32` | `u32` | `u8` | `u8` | `u8` | `u8` (max_players) |
|
||||
| players_online | `u64` | `usize` | `usize` | `usize` | `u32` | `u32` | `u8` | `u8` | `u8` | `u8` (players) |
|
||||
| players_bots | `Option<u64>` | | | | | | `u8` | | | `u8` (bots) |
|
||||
| has_password | `Option<bool>` | `bool` | `bool` | `bool` | | | `bool` | | `bool` | `bool` |
|
||||
| map_title | | `Option<String>` | | | | | | | | |
|
||||
| admin_contact | | `Option<String>` | | | | | | | | |
|
||||
| admin_name | | `Option<String>` | | | | | | | | |
|
||||
| players_minimum | | `Option<u8>` | `Option<u8>` | `Option<u8>` | | | | | | |
|
||||
| players | | `Vec<Player>` | `Vec<Player>` | `Vec<Player>` | | | `Option<Vec<ServerPlayer>>` | `Vec<P>` | | `Vec<TheShipPlayer>` (player_details) |
|
||||
| tournament | | `bool` | |`bool` | | | | | | |
|
||||
| unused_entries | | `Hashmap<String, String>` | | `HashMap<String, String>` | | | `Option<ExtraData>` (extra_data) | `HashMap<String, String>` | | |
|
||||
| teams | | | `Vec<Team>` | `Vec<Team>` | | | | | | |
|
||||
| version_protocol | | | | | `i32` | `String` | `u8` (protocol) | | `u8` (protocol) | `u8` (protocol) |
|
||||
| players_sample | | | | | `Option<Vec<Player>>` | | | | | |
|
||||
| favicon | | | | | `Option<String>` | | | | | |
|
||||
| previews_chat | | | | | `Option<bool>` | | | | | |
|
||||
| enforces_secure_chat | | | | | `Option<bool>` | | | | | |
|
||||
| server_type | | | | | `Server` | `Server` | `Server` | | | `Server` |
|
||||
| edition | | | | | | `String` | | | | |
|
||||
| id | | | | | | `String` | | | | |
|
||||
| rules | | | | | | | `Option<HashMap<String,String>>` | | | `HashMap<String,String>` |
|
||||
| folder | | | | | | | `String` | | | |
|
||||
| appid | | | | | | | `u32` | | | |
|
||||
| environment_type | | | | | | | `Environment` | | `Environment` | |
|
||||
| vac_secured | | | | | | | `bool` | | `bool` | `bool` |
|
||||
| the_ship | | | | | | | `Option<TheShip>` | | | |
|
||||
| is_mod | | | | | | | `bool` | | | |
|
||||
| mod_data | | | | | | | `Option<ModData>` | | | |
|
||||
| active_mod | | | | | | | | | `String` | |
|
||||
| round | | | | | | | | | `u8` | |
|
||||
| rounds_maximum | | | | | | | | | `u8` | |
|
||||
| time_left | | | | | | | | | `u16` | |
|
||||
| port | | | | | | | | | | `Option<u16>` |
|
||||
| steam_id | | | | | | | | | | `Option<u64>` |
|
||||
| tv_port | | | | | | | | | | `Option<u16>` |
|
||||
| tv_name | | | | | | | | | | `Option<String>` |
|
||||
| keywords | | | | | | | | | | `Option<string>` |
|
||||
| mode | | | | | | | | | | `u8` |
|
||||
| witnesses | | | | | | | | | | `u8` |
|
||||
| duration | | | | | | | | | | `u8` |
|
||||
| Field | Generic | GameSpy(1) | GameSpy(2) | GameSpy(3) | Minecraft(Java) | Minecraft(Bedrock) | Valve | Quake | Proprietary: FFOW | Proprietary: TheShip | Proprietary: JC2MP |
|
||||
|:---------------------|------------------|---------------------------|---------------|---------------------------|-----------------------|----------------------|----------------------------------|---------------------------|-------------------|--------------------------|--------------------|
|
||||
| name | `Option<String>` | `String` | `String` | `String` | | `String` | `String` | `String` | `String` | `String` | `String` |
|
||||
| description | `Option<String>` | | | | `String` | | | | `String` | | `String` |
|
||||
| game_mode | `Option<String>` | `String` | | `String` | | `Option<GameMode>` | `String` | | `String` | `String` | |
|
||||
| game_version | `Option<String>` | `String` | | `String` | `String` | | `String` | `String` | `String` | `String` | `String` |
|
||||
| map | `Option<String>` | `String` | `String` | `String` | | `Option<String>` | `String` | `String` | `String` | `String` | |
|
||||
| players_maxmimum | `u32` | `u32` | `u32` | `u32` | `u32` | `u32` | `u8` | `u8` | `u8` | `u8` | `u32` |
|
||||
| players_online | `u32` | `u32` | `u32` | `u32` | `u32` | `u32` | `u8` | `u8` | `u8` | `u8` | `u32` |
|
||||
| players_bots | `Option<u32>` | | | | | | `u8` | | | `u8` | |
|
||||
| has_password | `Option<bool>` | `bool` | `bool` | `bool` | | | `bool` | | `bool` | `bool` | `bool` |
|
||||
| players_minimum | | `Option<u8>` | `Option<u8>` | `Option<u8>` | | | | | | | |
|
||||
| players | | `Vec<Player>` | `Vec<Player>` | `Vec<Player>` | `Option<Vec<Player>>` | | `Option<Vec<ServerPlayer>>` | `Vec<P>` | | `Vec<TheShipPlayer>` | `Vec<Player>` |
|
||||
| tournament | | `bool` | | `bool` | | | | | | | |
|
||||
| unused_entries | | `Hashmap<String, String>` | | `HashMap<String, String>` | | | | `HashMap<String, String>` | | | |
|
||||
| teams | | | `Vec<Team>` | `Vec<Team>` | | | | | | | |
|
||||
| protocol_version | | | | | `i32` | `String` | `u8` | | `u8` | `u8` | |
|
||||
| server_type | | | | | `Server` | `Server` | `Server` | | | `Server` | |
|
||||
| rules | | | | | | | `Option<HashMap<String,String>>` | | | `HashMap<String,String>` | |
|
||||
| environment_type | | | | | | | `Environment` | | `Environment` | | |
|
||||
| vac_secured | | | | | | | `bool` | | `bool` | `bool` | |
|
||||
| map_title | | `Option<String>` | | | | | | | | | |
|
||||
| admin_contact | | `Option<String>` | | | | | | | | | |
|
||||
| admin_name | | `Option<String>` | | | | | | | | | |
|
||||
| favicon | | | | | `Option<String>` | | | | | | |
|
||||
| previews_chat | | | | | `Option<bool>` | | | | | | |
|
||||
| enforces_secure_chat | | | | | `Option<bool>` | | | | | | |
|
||||
| edition | | | | | | `String` | | | | | |
|
||||
| id | | | | | | `String` | | | | | |
|
||||
| the_ship | | | | | | | `Option<TheShip>` | | | | |
|
||||
| is_mod | | | | | | | `bool` | | | | |
|
||||
| extra_data | | | | | | | `Option<ExtraData>` | | | | |
|
||||
| mod_data | | | | | | | `Option<ModData>` | | | | |
|
||||
| folder | | | | | | | `String` | | | | |
|
||||
| appid | | | | | | | `u32` | | | | |
|
||||
| active_mod | | | | | | | | | `String` | | |
|
||||
| round | | | | | | | | | `u8` | | |
|
||||
| rounds_maximum | | | | | | | | | `u8` | | |
|
||||
| time_left | | | | | | | | | `u16` | | |
|
||||
| port | | | | | | | | | | `Option<u16>` | |
|
||||
| steam_id | | | | | | | | | | `Option<u64>` | |
|
||||
| tv_port | | | | | | | | | | `Option<u16>` | |
|
||||
| tv_name | | | | | | | | | | `Option<String>` | |
|
||||
| keywords | | | | | | | | | | `Option<string>` | |
|
||||
| mode | | | | | | | | | | `u8` | |
|
||||
| witnesses | | | | | | | | | | `u8` | |
|
||||
| duration | | | | | | | | | | `u8` | |
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ pub fn query(address: &IpAddr, port: Option<u16>) -> GDResult<game::Response> {
|
|||
}
|
||||
|
||||
if let Some(bat_gamemode) = rules.get("bat_gamemode_s") {
|
||||
valve_response.info.game = bat_gamemode.clone();
|
||||
valve_response.info.game_mode = bat_gamemode.clone();
|
||||
rules.remove("bat_gamemode_s");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,17 +13,17 @@ use std::net::{IpAddr, SocketAddr};
|
|||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct Response {
|
||||
/// Protocol used by the server.
|
||||
pub protocol: u8,
|
||||
pub protocol_version: u8,
|
||||
/// Name of the server.
|
||||
pub name: String,
|
||||
/// Map name.
|
||||
pub active_mod: String,
|
||||
/// Running game mode.
|
||||
pub game_mode: String,
|
||||
/// The version that the server is running on.
|
||||
pub game_version: String,
|
||||
/// Description of the server.
|
||||
pub description: String,
|
||||
/// The version that the server is running on.
|
||||
pub version: String,
|
||||
/// Current map.
|
||||
pub map: String,
|
||||
/// Number of players on the server.
|
||||
|
|
@ -50,13 +50,13 @@ impl CommonResponse for Response {
|
|||
fn as_original(&self) -> GenericResponse { GenericResponse::FFOW(self) }
|
||||
|
||||
fn name(&self) -> Option<&str> { Some(&self.name) }
|
||||
fn game(&self) -> Option<&str> { Some(&self.game_mode) }
|
||||
fn game_mode(&self) -> Option<&str> { Some(&self.game_mode) }
|
||||
fn description(&self) -> Option<&str> { Some(&self.description) }
|
||||
fn game_version(&self) -> Option<&str> { Some(&self.version) }
|
||||
fn game_version(&self) -> Option<&str> { Some(&self.game_version) }
|
||||
fn map(&self) -> Option<&str> { Some(&self.map) }
|
||||
fn has_password(&self) -> Option<bool> { Some(self.has_password) }
|
||||
fn players_maximum(&self) -> u64 { self.players_maximum.into() }
|
||||
fn players_online(&self) -> u64 { self.players_online.into() }
|
||||
fn players_maximum(&self) -> u32 { self.players_maximum.into() }
|
||||
fn players_online(&self) -> u32 { self.players_online.into() }
|
||||
}
|
||||
|
||||
pub fn query(address: &IpAddr, port: Option<u16>) -> GDResult<Response> { query_with_timeout(address, port, None) }
|
||||
|
|
@ -79,13 +79,13 @@ pub fn query_with_timeout(
|
|||
|
||||
let mut buffer = Buffer::<LittleEndian>::new(&data);
|
||||
|
||||
let protocol = buffer.read::<u8>()?;
|
||||
let protocol_version = buffer.read::<u8>()?;
|
||||
let name = buffer.read_string::<Utf8Decoder>(None)?;
|
||||
let map = buffer.read_string::<Utf8Decoder>(None)?;
|
||||
let active_mod = buffer.read_string::<Utf8Decoder>(None)?;
|
||||
let game_mode = buffer.read_string::<Utf8Decoder>(None)?;
|
||||
let description = buffer.read_string::<Utf8Decoder>(None)?;
|
||||
let version = buffer.read_string::<Utf8Decoder>(None)?;
|
||||
let game_version = buffer.read_string::<Utf8Decoder>(None)?;
|
||||
buffer.move_cursor(2)?;
|
||||
let players_online = buffer.read::<u8>()?;
|
||||
let players_maximum = buffer.read::<u8>()?;
|
||||
|
|
@ -99,12 +99,12 @@ pub fn query_with_timeout(
|
|||
let time_left = buffer.read::<u16>()?;
|
||||
|
||||
Ok(Response {
|
||||
protocol,
|
||||
protocol_version,
|
||||
name,
|
||||
active_mod,
|
||||
game_mode,
|
||||
game_version,
|
||||
description,
|
||||
version,
|
||||
map,
|
||||
players_online,
|
||||
players_maximum,
|
||||
|
|
|
|||
|
|
@ -27,28 +27,24 @@ impl CommonPlayer for Player {
|
|||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct Response {
|
||||
version: String,
|
||||
game_version: String,
|
||||
description: String,
|
||||
name: String,
|
||||
has_password: bool,
|
||||
players: Vec<Player>,
|
||||
players_maximum: usize,
|
||||
players_online: usize,
|
||||
players_maximum: u32,
|
||||
players_online: u32,
|
||||
}
|
||||
|
||||
impl CommonResponse for Response {
|
||||
fn as_original(&self) -> GenericResponse { GenericResponse::JC2MP(self) }
|
||||
|
||||
fn game_version(&self) -> Option<&str> { Some(&self.version) }
|
||||
fn game_version(&self) -> Option<&str> { Some(&self.game_version) }
|
||||
fn description(&self) -> Option<&str> { Some(&self.description) }
|
||||
fn name(&self) -> Option<&str> { Some(&self.name) }
|
||||
fn has_password(&self) -> Option<bool> { Some(self.has_password) }
|
||||
fn players_maximum(&self) -> u64 {
|
||||
// If usize doesn't fit in u64 silently return 0 as this is extremely unlikely
|
||||
// for a player count
|
||||
self.players_maximum.try_into().unwrap_or(0)
|
||||
}
|
||||
fn players_online(&self) -> u64 { self.players_online.try_into().unwrap_or(0) }
|
||||
fn players_maximum(&self) -> u32 { self.players_maximum }
|
||||
fn players_online(&self) -> u32 { self.players_online }
|
||||
|
||||
fn players(&self) -> Option<Vec<&dyn crate::protocols::types::CommonPlayer>> {
|
||||
Some(
|
||||
|
|
@ -113,10 +109,10 @@ pub fn query_with_timeout(
|
|||
false => reported_players,
|
||||
}
|
||||
}
|
||||
};
|
||||
} as u32;
|
||||
|
||||
Ok(Response {
|
||||
version: server_vars
|
||||
game_version: server_vars
|
||||
.remove("version")
|
||||
.ok_or(GDErrorKind::PacketBad)?,
|
||||
description: server_vars
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use serde::{Deserialize, Serialize};
|
|||
#[derive(Debug, Clone, PartialEq, PartialOrd)]
|
||||
pub struct TheShipPlayer {
|
||||
pub name: String,
|
||||
pub score: u32,
|
||||
pub score: i32,
|
||||
pub duration: f32,
|
||||
pub deaths: u32,
|
||||
pub money: u32,
|
||||
|
|
@ -39,24 +39,24 @@ impl CommonPlayer for TheShipPlayer {
|
|||
fn as_original(&self) -> GenericPlayer { GenericPlayer::TheShip(self) }
|
||||
|
||||
fn name(&self) -> &str { &self.name }
|
||||
fn score(&self) -> Option<u32> { Some(self.score) }
|
||||
fn score(&self) -> Option<i32> { Some(self.score) }
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Response {
|
||||
pub protocol: u8,
|
||||
pub protocol_version: u8,
|
||||
pub name: String,
|
||||
pub map: String,
|
||||
pub game: String,
|
||||
pub players: u8,
|
||||
pub players_details: Vec<TheShipPlayer>,
|
||||
pub max_players: u8,
|
||||
pub bots: u8,
|
||||
pub game_mode: String,
|
||||
pub game_version: String,
|
||||
pub players: Vec<TheShipPlayer>,
|
||||
pub players_online: u8,
|
||||
pub players_maximum: u8,
|
||||
pub players_bots: u8,
|
||||
pub server_type: Server,
|
||||
pub has_password: bool,
|
||||
pub vac_secured: bool,
|
||||
pub version: String,
|
||||
pub port: Option<u16>,
|
||||
pub steam_id: Option<u64>,
|
||||
pub tv_port: Option<u16>,
|
||||
|
|
@ -73,15 +73,15 @@ impl CommonResponse for Response {
|
|||
|
||||
fn name(&self) -> Option<&str> { Some(&self.name) }
|
||||
fn map(&self) -> Option<&str> { Some(&self.map) }
|
||||
fn game(&self) -> Option<&str> { Some(&self.game) }
|
||||
fn players_maximum(&self) -> u64 { self.max_players.into() }
|
||||
fn players_online(&self) -> u64 { self.players.into() }
|
||||
fn players_bots(&self) -> Option<u64> { Some(self.bots.into()) }
|
||||
fn game_mode(&self) -> Option<&str> { Some(&self.game_mode) }
|
||||
fn players_maximum(&self) -> u32 { self.players_maximum.into() }
|
||||
fn players_online(&self) -> u32 { self.players_online.into() }
|
||||
fn players_bots(&self) -> Option<u32> { Some(self.players_bots.into()) }
|
||||
fn has_password(&self) -> Option<bool> { Some(self.has_password) }
|
||||
|
||||
fn players(&self) -> Option<Vec<&dyn CommonPlayer>> {
|
||||
Some(
|
||||
self.players_details
|
||||
self.players
|
||||
.iter()
|
||||
.map(|p| p as &dyn CommonPlayer)
|
||||
.collect(),
|
||||
|
|
@ -96,23 +96,23 @@ impl Response {
|
|||
let the_unwrapped_ship = response.info.the_ship.unwrap();
|
||||
|
||||
Self {
|
||||
protocol: response.info.protocol,
|
||||
protocol_version: response.info.protocol_version,
|
||||
name: response.info.name,
|
||||
map: response.info.map,
|
||||
game: response.info.game,
|
||||
players: response.info.players_online,
|
||||
players_details: response
|
||||
game_mode: response.info.game_mode,
|
||||
game_version: response.info.game_version,
|
||||
players_online: response.info.players_online,
|
||||
players: response
|
||||
.players
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(TheShipPlayer::new_from_valve_player)
|
||||
.collect(),
|
||||
max_players: response.info.players_maximum,
|
||||
bots: response.info.players_bots,
|
||||
players_maximum: response.info.players_maximum,
|
||||
players_bots: response.info.players_bots,
|
||||
server_type: response.info.server_type,
|
||||
has_password: response.info.has_password,
|
||||
vac_secured: response.info.vac_secured,
|
||||
version: response.info.version,
|
||||
port,
|
||||
steam_id,
|
||||
tv_port,
|
||||
|
|
|
|||
|
|
@ -87,8 +87,8 @@ fn get_server_values(
|
|||
Ok(server_values)
|
||||
}
|
||||
|
||||
fn extract_players(server_vars: &mut HashMap<String, String>, players_maximum: usize) -> GDResult<Vec<Player>> {
|
||||
let mut players_data: Vec<HashMap<String, String>> = Vec::with_capacity(players_maximum);
|
||||
fn extract_players(server_vars: &mut HashMap<String, String>, players_maximum: u32) -> GDResult<Vec<Player>> {
|
||||
let mut players_data: Vec<HashMap<String, String>> = Vec::with_capacity(players_maximum as usize);
|
||||
|
||||
server_vars.retain(|key, value| {
|
||||
let split: Vec<&str> = key.split('_').collect();
|
||||
|
|
@ -201,7 +201,7 @@ pub fn query_vars(
|
|||
pub fn query(address: &SocketAddr, timeout_settings: Option<TimeoutSettings>) -> GDResult<Response> {
|
||||
let mut server_vars = query_vars(address, timeout_settings)?;
|
||||
|
||||
let players_maximum = server_vars
|
||||
let players_maximum: u32 = server_vars
|
||||
.remove("maxplayers")
|
||||
.ok_or(GDErrorKind::PacketBad)?
|
||||
.parse()
|
||||
|
|
@ -226,14 +226,14 @@ pub fn query(address: &SocketAddr, timeout_settings: Option<TimeoutSettings>) ->
|
|||
.remove("AdminName")
|
||||
.or_else(|| server_vars.remove("admin")),
|
||||
has_password: has_password(&mut server_vars)?,
|
||||
game_type: server_vars
|
||||
game_mode: server_vars
|
||||
.remove("gametype")
|
||||
.ok_or(GDErrorKind::PacketBad)?,
|
||||
game_version: server_vars
|
||||
.remove("gamever")
|
||||
.ok_or(GDErrorKind::PacketBad)?,
|
||||
players_maximum,
|
||||
players_online: players.len(),
|
||||
players_online: players.len() as u32,
|
||||
players_minimum,
|
||||
players,
|
||||
tournament: server_vars
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ pub struct Player {
|
|||
pub face: String,
|
||||
pub skin: String,
|
||||
pub mesh: String,
|
||||
pub score: u32,
|
||||
pub score: i32,
|
||||
pub deaths: Option<u32>,
|
||||
pub health: Option<u32>,
|
||||
pub secret: bool,
|
||||
|
|
@ -28,7 +28,7 @@ impl CommonPlayer for Player {
|
|||
fn as_original(&self) -> GenericPlayer { GenericPlayer::Gamespy(VersionedPlayer::One(self)) }
|
||||
|
||||
fn name(&self) -> &str { &self.name }
|
||||
fn score(&self) -> Option<u32> { Some(self.score) }
|
||||
fn score(&self) -> Option<i32> { Some(self.score) }
|
||||
}
|
||||
|
||||
/// A query response.
|
||||
|
|
@ -41,10 +41,10 @@ pub struct Response {
|
|||
pub admin_contact: Option<String>,
|
||||
pub admin_name: Option<String>,
|
||||
pub has_password: bool,
|
||||
pub game_type: String,
|
||||
pub game_mode: String,
|
||||
pub game_version: String,
|
||||
pub players_maximum: usize,
|
||||
pub players_online: usize,
|
||||
pub players_maximum: u32,
|
||||
pub players_online: u32,
|
||||
pub players_minimum: Option<u8>,
|
||||
pub players: Vec<Player>,
|
||||
pub tournament: bool,
|
||||
|
|
@ -57,10 +57,10 @@ impl CommonResponse for Response {
|
|||
fn name(&self) -> Option<&str> { Some(&self.name) }
|
||||
fn map(&self) -> Option<&str> { Some(&self.map) }
|
||||
fn has_password(&self) -> Option<bool> { Some(self.has_password) }
|
||||
fn game(&self) -> Option<&str> { Some(&self.game_type) }
|
||||
fn game_mode(&self) -> Option<&str> { Some(&self.game_mode) }
|
||||
fn game_version(&self) -> Option<&str> { Some(&self.game_version) }
|
||||
fn players_maximum(&self) -> u64 { self.players_maximum.try_into().unwrap_or(0) }
|
||||
fn players_online(&self) -> u64 { self.players_online.try_into().unwrap_or(0) }
|
||||
fn players_maximum(&self) -> u32 { self.players_maximum }
|
||||
fn players_online(&self) -> u32 { self.players_online }
|
||||
|
||||
fn players(&self) -> Option<Vec<&dyn CommonPlayer>> {
|
||||
Some(
|
||||
|
|
|
|||
|
|
@ -358,7 +358,7 @@ pub fn query(address: &SocketAddr, timeout_settings: Option<TimeoutSettings>) ->
|
|||
None => None,
|
||||
Some(v) => Some(v.parse::<u8>().map_err(|e| TypeParse.context(e))?),
|
||||
};
|
||||
let players_online = match server_vars.remove("numplayers") {
|
||||
let players_online: u32 = match server_vars.remove("numplayers") {
|
||||
None => players.len(),
|
||||
Some(v) => {
|
||||
let reported_players = v.parse().map_err(|e| TypeParse.context(e))?;
|
||||
|
|
@ -367,7 +367,7 @@ pub fn query(address: &SocketAddr, timeout_settings: Option<TimeoutSettings>) ->
|
|||
false => reported_players,
|
||||
}
|
||||
}
|
||||
};
|
||||
} as u32;
|
||||
|
||||
Ok(Response {
|
||||
name: server_vars
|
||||
|
|
@ -377,7 +377,7 @@ pub fn query(address: &SocketAddr, timeout_settings: Option<TimeoutSettings>) ->
|
|||
.remove("mapname")
|
||||
.ok_or(GDErrorKind::PacketBad)?,
|
||||
has_password: has_password(&mut server_vars)?,
|
||||
game_type: server_vars
|
||||
game_mode: server_vars
|
||||
.remove("gametype")
|
||||
.ok_or(GDErrorKind::PacketBad)?,
|
||||
game_version: server_vars
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ impl CommonPlayer for Player {
|
|||
}
|
||||
|
||||
fn name(&self) -> &str { &self.name }
|
||||
fn score(&self) -> Option<u32> { Some(self.score.try_into().unwrap_or(0)) }
|
||||
fn score(&self) -> Option<i32> { Some(self.score) }
|
||||
}
|
||||
|
||||
/// A team's details
|
||||
|
|
@ -42,10 +42,10 @@ pub struct Response {
|
|||
pub name: String,
|
||||
pub map: String,
|
||||
pub has_password: bool,
|
||||
pub game_type: String,
|
||||
pub game_mode: String,
|
||||
pub game_version: String,
|
||||
pub players_maximum: usize,
|
||||
pub players_online: usize,
|
||||
pub players_maximum: u32,
|
||||
pub players_online: u32,
|
||||
pub players_minimum: Option<u8>,
|
||||
pub players: Vec<Player>,
|
||||
pub teams: Vec<Team>,
|
||||
|
|
@ -59,10 +59,10 @@ impl CommonResponse for Response {
|
|||
fn name(&self) -> Option<&str> { Some(&self.name) }
|
||||
fn map(&self) -> Option<&str> { Some(&self.map) }
|
||||
fn has_password(&self) -> Option<bool> { Some(self.has_password) }
|
||||
fn game(&self) -> Option<&str> { Some(&self.game_type) }
|
||||
fn game_mode(&self) -> Option<&str> { Some(&self.game_mode) }
|
||||
fn game_version(&self) -> Option<&str> { Some(&self.game_version) }
|
||||
fn players_maximum(&self) -> u64 { self.players_maximum.try_into().unwrap_or(0) }
|
||||
fn players_online(&self) -> u64 { self.players_online.try_into().unwrap_or(0) }
|
||||
fn players_maximum(&self) -> u32 { self.players_maximum }
|
||||
fn players_online(&self) -> u32 { self.players_online }
|
||||
|
||||
fn players(&self) -> Option<Vec<&dyn CommonPlayer>> {
|
||||
Some(
|
||||
|
|
|
|||
|
|
@ -173,10 +173,10 @@ pub fn query(address: &SocketAddr, timeout_settings: Option<TimeoutSettings>) ->
|
|||
false => reported_players,
|
||||
}
|
||||
}
|
||||
};
|
||||
} as u32;
|
||||
let players_minimum = match server_vars.remove("minplayers") {
|
||||
None => None,
|
||||
Some(v) => Some(v.parse::<u8>().map_err(|e| TypeParse.context(e))?),
|
||||
Some(v) => Some(v.parse::<u32>().map_err(|e| TypeParse.context(e))?),
|
||||
};
|
||||
|
||||
Ok(Response {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ impl CommonPlayer for Player {
|
|||
fn as_original(&self) -> GenericPlayer { GenericPlayer::Gamespy(VersionedPlayer::Two(self)) }
|
||||
|
||||
fn name(&self) -> &str { &self.name }
|
||||
fn score(&self) -> Option<u32> { Some(self.score.into()) }
|
||||
fn score(&self) -> Option<i32> { Some(self.score.into()) }
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
|
|
@ -37,9 +37,9 @@ pub struct Response {
|
|||
pub map: String,
|
||||
pub has_password: bool,
|
||||
pub teams: Vec<Team>,
|
||||
pub players_maximum: usize,
|
||||
pub players_online: usize,
|
||||
pub players_minimum: Option<u8>,
|
||||
pub players_maximum: u32,
|
||||
pub players_online: u32,
|
||||
pub players_minimum: Option<u32>,
|
||||
pub players: Vec<Player>,
|
||||
pub unused_entries: HashMap<String, String>,
|
||||
}
|
||||
|
|
@ -50,8 +50,8 @@ impl CommonResponse for Response {
|
|||
fn name(&self) -> Option<&str> { Some(&self.name) }
|
||||
fn map(&self) -> Option<&str> { Some(&self.map) }
|
||||
fn has_password(&self) -> Option<bool> { Some(self.has_password) }
|
||||
fn players_maximum(&self) -> u64 { self.players_maximum.try_into().unwrap_or(0) }
|
||||
fn players_online(&self) -> u64 { self.players_online.try_into().unwrap_or(0) }
|
||||
fn players_maximum(&self) -> u32 { self.players_maximum }
|
||||
fn players_online(&self) -> u32 { self.players_online }
|
||||
|
||||
fn players(&self) -> Option<Vec<&dyn CommonPlayer>> {
|
||||
Some(
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ impl Bedrock {
|
|||
edition: status[0].to_string(),
|
||||
name: status[1].to_string(),
|
||||
version_name: status[3].to_string(),
|
||||
version_protocol: status[2].to_string(),
|
||||
protocol_version: status[2].to_string(),
|
||||
players_maximum: status[5].parse().map_err(|e| TypeParse.context(e))?,
|
||||
players_online: status[4].parse().map_err(|e| TypeParse.context(e))?,
|
||||
id: status.get(6).map(|v| v.to_string()),
|
||||
|
|
|
|||
|
|
@ -96,11 +96,11 @@ impl Java {
|
|||
let json_response = get_string(&mut buffer)?;
|
||||
let value_response: Value = serde_json::from_str(&json_response).map_err(|e| JsonParse.context(e))?;
|
||||
|
||||
let version_name = value_response["version"]["name"]
|
||||
let game_version = value_response["version"]["name"]
|
||||
.as_str()
|
||||
.ok_or(PacketBad)?
|
||||
.to_string();
|
||||
let version_protocol = value_response["version"]["protocol"]
|
||||
let protocol_version = value_response["version"]["protocol"]
|
||||
.as_i64()
|
||||
.ok_or(PacketBad)? as i32;
|
||||
|
||||
|
|
@ -108,7 +108,7 @@ impl Java {
|
|||
let online_players = value_response["players"]["online"]
|
||||
.as_u64()
|
||||
.ok_or(PacketBad)? as u32;
|
||||
let sample_players: Option<Vec<Player>> = match value_response["players"]["sample"].is_null() {
|
||||
let players: Option<Vec<Player>> = match value_response["players"]["sample"].is_null() {
|
||||
true => None,
|
||||
false => {
|
||||
Some({
|
||||
|
|
@ -130,11 +130,11 @@ impl Java {
|
|||
};
|
||||
|
||||
Ok(JavaResponse {
|
||||
version_name,
|
||||
version_protocol,
|
||||
game_version,
|
||||
protocol_version,
|
||||
players_maximum: max_players,
|
||||
players_online: online_players,
|
||||
players_sample: sample_players,
|
||||
players,
|
||||
description: value_response["description"].to_string(),
|
||||
favicon: value_response["favicon"].as_str().map(str::to_string),
|
||||
previews_chat: value_response["previewsChat"].as_bool(),
|
||||
|
|
|
|||
|
|
@ -51,11 +51,11 @@ impl LegacyBV1_8 {
|
|||
let max_players = split[2].parse().map_err(|e| PacketBad.context(e))?;
|
||||
|
||||
Ok(JavaResponse {
|
||||
version_name: "Beta 1.8+".to_string(),
|
||||
version_protocol: -1,
|
||||
game_version: "Beta 1.8+".to_string(),
|
||||
protocol_version: -1,
|
||||
players_maximum: max_players,
|
||||
players_online: online_players,
|
||||
players_sample: None,
|
||||
players: None,
|
||||
description,
|
||||
favicon: None,
|
||||
previews_chat: None,
|
||||
|
|
|
|||
|
|
@ -54,11 +54,11 @@ impl LegacyV1_4 {
|
|||
let max_players = split[2].parse().map_err(|e| PacketBad.context(e))?;
|
||||
|
||||
Ok(JavaResponse {
|
||||
version_name: "1.4+".to_string(),
|
||||
version_protocol: -1,
|
||||
game_version: "1.4+".to_string(),
|
||||
protocol_version: -1,
|
||||
players_maximum: max_players,
|
||||
players_online: online_players,
|
||||
players_sample: None,
|
||||
players: None,
|
||||
description,
|
||||
favicon: None,
|
||||
previews_chat: None,
|
||||
|
|
|
|||
|
|
@ -52,11 +52,11 @@ impl LegacyV1_6 {
|
|||
|
||||
pub(crate) fn get_response(buffer: &mut Buffer<BigEndian>) -> GDResult<JavaResponse> {
|
||||
// This is a specific order!
|
||||
let version_protocol = buffer
|
||||
let protocol_version = buffer
|
||||
.read_string::<Utf16Decoder<BigEndian>>(None)?
|
||||
.parse()
|
||||
.map_err(|e| PacketBad.context(e))?;
|
||||
let version_name = buffer.read_string::<Utf16Decoder<BigEndian>>(None)?;
|
||||
let game_version = buffer.read_string::<Utf16Decoder<BigEndian>>(None)?;
|
||||
let description = buffer.read_string::<Utf16Decoder<BigEndian>>(None)?;
|
||||
let online_players = buffer
|
||||
.read_string::<Utf16Decoder<BigEndian>>(None)?
|
||||
|
|
@ -68,11 +68,11 @@ impl LegacyV1_6 {
|
|||
.map_err(|e| PacketBad.context(e))?;
|
||||
|
||||
Ok(JavaResponse {
|
||||
version_name,
|
||||
version_protocol,
|
||||
game_version,
|
||||
protocol_version,
|
||||
players_maximum: max_players,
|
||||
players_online: online_players,
|
||||
players_sample: None,
|
||||
players: None,
|
||||
description,
|
||||
favicon: None,
|
||||
previews_chat: None,
|
||||
|
|
|
|||
|
|
@ -66,16 +66,16 @@ pub enum VersionedResponse<'a> {
|
|||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct JavaResponse {
|
||||
/// Version name, example: "1.19.2".
|
||||
pub version_name: String,
|
||||
/// Version protocol, example: 760 (for 1.19.2). Note that for versions
|
||||
/// below 1.6 this field is always -1.
|
||||
pub version_protocol: i32,
|
||||
pub game_version: String,
|
||||
/// Protocol version, example: 760 (for 1.19.1 or 1.19.2).
|
||||
/// Note that for versions below 1.6 this field is always -1.
|
||||
pub protocol_version: i32,
|
||||
/// Number of server capacity.
|
||||
pub players_maximum: u32,
|
||||
/// Number of online players.
|
||||
pub players_online: u32,
|
||||
/// Some online players (can be missing).
|
||||
pub players_sample: Option<Vec<Player>>,
|
||||
pub players: Option<Vec<Player>>,
|
||||
/// Server's description or MOTD.
|
||||
pub description: String,
|
||||
/// The favicon (can be missing).
|
||||
|
|
@ -92,12 +92,12 @@ impl CommonResponse for JavaResponse {
|
|||
fn as_original(&self) -> GenericResponse { GenericResponse::Minecraft(VersionedResponse::Java(self)) }
|
||||
|
||||
fn description(&self) -> Option<&str> { Some(&self.description) }
|
||||
fn players_maximum(&self) -> u64 { self.players_maximum.into() }
|
||||
fn players_online(&self) -> u64 { self.players_online.into() }
|
||||
fn game_version(&self) -> Option<&str> { Some(&self.version_name) }
|
||||
fn players_maximum(&self) -> u32 { self.players_maximum }
|
||||
fn players_online(&self) -> u32 { self.players_online }
|
||||
fn game_version(&self) -> Option<&str> { Some(&self.game_version) }
|
||||
|
||||
fn players(&self) -> Option<Vec<&dyn CommonPlayer>> {
|
||||
self.players_sample
|
||||
self.players
|
||||
.as_ref()
|
||||
.map(|players| players.iter().map(|p| p as &dyn CommonPlayer).collect())
|
||||
}
|
||||
|
|
@ -113,8 +113,8 @@ pub struct BedrockResponse {
|
|||
pub name: String,
|
||||
/// Version name, example: "1.19.40".
|
||||
pub version_name: String,
|
||||
/// Version protocol, example: 760 (for 1.19.2).
|
||||
pub version_protocol: String,
|
||||
/// Protocol version, example: 760 (for 1.19.2).
|
||||
pub protocol_version: String,
|
||||
/// Maximum number of players the server reports it can hold.
|
||||
pub players_maximum: u32,
|
||||
/// Number of players on the server.
|
||||
|
|
@ -135,18 +135,18 @@ impl CommonResponse for BedrockResponse {
|
|||
fn name(&self) -> Option<&str> { Some(&self.name) }
|
||||
fn map(&self) -> Option<&str> { self.map.as_deref() }
|
||||
fn game_version(&self) -> Option<&str> { Some(&self.version_name) }
|
||||
fn players_maximum(&self) -> u64 { self.players_maximum.into() }
|
||||
fn players_online(&self) -> u64 { self.players_online.into() }
|
||||
fn players_maximum(&self) -> u32 { self.players_maximum }
|
||||
fn players_online(&self) -> u32 { self.players_online }
|
||||
}
|
||||
|
||||
impl JavaResponse {
|
||||
pub fn from_bedrock_response(response: BedrockResponse) -> Self {
|
||||
Self {
|
||||
version_name: response.version_name,
|
||||
version_protocol: 0,
|
||||
game_version: response.version_name,
|
||||
protocol_version: 0,
|
||||
players_maximum: response.players_maximum,
|
||||
players_online: response.players_online,
|
||||
players_sample: None,
|
||||
players: None,
|
||||
description: response.name,
|
||||
favicon: None,
|
||||
previews_chat: None,
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ pub(crate) fn client_query<Client: QuakeClient>(
|
|||
.parse()
|
||||
.map_err(|e| TypeParse.context(e))?,
|
||||
players,
|
||||
version: server_vars
|
||||
game_version: server_vars
|
||||
.remove("version")
|
||||
.or(server_vars.remove("*version")),
|
||||
unused_entries: server_vars,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ impl CommonPlayer for Player {
|
|||
fn as_original(&self) -> GenericPlayer { GenericPlayer::QuakeOne(self) }
|
||||
|
||||
fn name(&self) -> &str { &self.name }
|
||||
fn score(&self) -> Option<u32> { Some(self.score.into()) }
|
||||
fn score(&self) -> Option<i32> { Some(self.score.into()) }
|
||||
}
|
||||
|
||||
pub(crate) struct QuakeOne;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ impl CommonPlayer for Player {
|
|||
|
||||
fn name(&self) -> &str { &self.name }
|
||||
|
||||
fn score(&self) -> Option<u32> { Some(self.score.try_into().unwrap_or(0)) }
|
||||
fn score(&self) -> Option<i32> { Some(self.score) }
|
||||
}
|
||||
|
||||
pub(crate) struct QuakeTwo;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ pub struct Response<P> {
|
|||
/// Maximum number of players the server reports it can hold.
|
||||
pub players_maximum: u8,
|
||||
/// The server version.
|
||||
pub version: Option<String>,
|
||||
pub game_version: Option<String>,
|
||||
/// Other server entries that weren't used.
|
||||
pub unused_entries: HashMap<String, String>,
|
||||
}
|
||||
|
|
@ -35,10 +35,10 @@ impl<P: QuakePlayerType> CommonResponse for Response<P> {
|
|||
fn as_original(&self) -> GenericResponse { GenericResponse::Quake(P::version(self)) }
|
||||
|
||||
fn name(&self) -> Option<&str> { Some(&self.name) }
|
||||
fn game_version(&self) -> Option<&str> { self.version.as_deref() }
|
||||
fn game_version(&self) -> Option<&str> { self.game_version.as_deref() }
|
||||
fn map(&self) -> Option<&str> { Some(&self.map) }
|
||||
fn players_maximum(&self) -> u64 { self.players_maximum.into() }
|
||||
fn players_online(&self) -> u64 { self.players_online.into() }
|
||||
fn players_maximum(&self) -> u32 { self.players_maximum.into() }
|
||||
fn players_online(&self) -> u32 { self.players_online.into() }
|
||||
|
||||
fn players(&self) -> Option<Vec<&dyn CommonPlayer>> {
|
||||
Some(
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ pub trait CommonResponse {
|
|||
CommonResponseJson {
|
||||
name: self.name(),
|
||||
description: self.description(),
|
||||
game: self.game(),
|
||||
game_mode: self.game_mode(),
|
||||
game_version: self.game_version(),
|
||||
has_password: self.has_password(),
|
||||
map: self.map(),
|
||||
|
|
@ -84,17 +84,17 @@ pub trait CommonResponse {
|
|||
/// Description of the server
|
||||
fn description(&self) -> Option<&str> { None }
|
||||
/// Name of the current game or game mode
|
||||
fn game(&self) -> Option<&str> { None }
|
||||
fn game_mode(&self) -> Option<&str> { None }
|
||||
/// Version of the game being run on the server
|
||||
fn game_version(&self) -> Option<&str> { None }
|
||||
/// The current map name
|
||||
fn map(&self) -> Option<&str> { None }
|
||||
/// Maximum number of players allowed to connect
|
||||
fn players_maximum(&self) -> u64;
|
||||
fn players_maximum(&self) -> u32;
|
||||
/// Number of players currently connected
|
||||
fn players_online(&self) -> u64;
|
||||
fn players_online(&self) -> u32;
|
||||
/// Number of bots currently connected
|
||||
fn players_bots(&self) -> Option<u64> { None }
|
||||
fn players_bots(&self) -> Option<u32> { None }
|
||||
/// Whether the server requires a password to join
|
||||
fn has_password(&self) -> Option<bool> { None }
|
||||
/// Currently connected players
|
||||
|
|
@ -106,12 +106,12 @@ pub trait CommonResponse {
|
|||
pub struct CommonResponseJson<'a> {
|
||||
pub name: Option<&'a str>,
|
||||
pub description: Option<&'a str>,
|
||||
pub game: Option<&'a str>,
|
||||
pub game_mode: Option<&'a str>,
|
||||
pub game_version: Option<&'a str>,
|
||||
pub map: Option<&'a str>,
|
||||
pub players_maximum: u64,
|
||||
pub players_online: u64,
|
||||
pub players_bots: Option<u64>,
|
||||
pub players_maximum: u32,
|
||||
pub players_online: u32,
|
||||
pub players_bots: Option<u32>,
|
||||
pub has_password: Option<bool>,
|
||||
pub players: Option<Vec<CommonPlayerJson<'a>>>,
|
||||
}
|
||||
|
|
@ -131,14 +131,14 @@ pub trait CommonPlayer {
|
|||
/// Player name
|
||||
fn name(&self) -> &str;
|
||||
/// Player score
|
||||
fn score(&self) -> Option<u32> { None }
|
||||
fn score(&self) -> Option<i32> { None }
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct CommonPlayerJson<'a> {
|
||||
pub name: &'a str,
|
||||
pub score: Option<u32>,
|
||||
pub score: Option<i32>,
|
||||
}
|
||||
|
||||
/// Timeout settings for socket operations
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ impl ValveProtocol {
|
|||
let name = buffer.read_string::<Utf8Decoder>(None)?;
|
||||
let map = buffer.read_string::<Utf8Decoder>(None)?;
|
||||
let folder = buffer.read_string::<Utf8Decoder>(None)?;
|
||||
let game = buffer.read_string::<Utf8Decoder>(None)?;
|
||||
let game_mode = buffer.read_string::<Utf8Decoder>(None)?;
|
||||
let players = buffer.read()?;
|
||||
let max_players = buffer.read()?;
|
||||
let protocol = buffer.read()?;
|
||||
|
|
@ -245,11 +245,11 @@ impl ValveProtocol {
|
|||
let bots = buffer.read::<u8>()?;
|
||||
|
||||
Ok(ServerInfo {
|
||||
protocol,
|
||||
protocol_version: protocol,
|
||||
name,
|
||||
map,
|
||||
folder,
|
||||
game,
|
||||
game_mode,
|
||||
appid: 0, // not present in the obsolete response
|
||||
players_online: players,
|
||||
players_maximum: max_players,
|
||||
|
|
@ -259,7 +259,7 @@ impl ValveProtocol {
|
|||
has_password,
|
||||
vac_secured,
|
||||
the_ship: None,
|
||||
version: "".to_string(), // a version field only for the mod
|
||||
game_version: "".to_string(), // a version field only for the mod
|
||||
extra_data: None,
|
||||
is_mod,
|
||||
mod_data,
|
||||
|
|
@ -281,7 +281,7 @@ impl ValveProtocol {
|
|||
let name = buffer.read_string::<Utf8Decoder>(None)?;
|
||||
let map = buffer.read_string::<Utf8Decoder>(None)?;
|
||||
let folder = buffer.read_string::<Utf8Decoder>(None)?;
|
||||
let game = buffer.read_string::<Utf8Decoder>(None)?;
|
||||
let game_mode = buffer.read_string::<Utf8Decoder>(None)?;
|
||||
let mut appid = buffer.read::<u16>()? as u32;
|
||||
let players = buffer.read()?;
|
||||
let max_players = buffer.read()?;
|
||||
|
|
@ -300,7 +300,7 @@ impl ValveProtocol {
|
|||
})
|
||||
}
|
||||
};
|
||||
let version = buffer.read_string::<Utf8Decoder>(None)?;
|
||||
let game_version = buffer.read_string::<Utf8Decoder>(None)?;
|
||||
let extra_data = match buffer.read::<u8>() {
|
||||
Err(_) => None,
|
||||
Ok(value) => {
|
||||
|
|
@ -339,11 +339,11 @@ impl ValveProtocol {
|
|||
};
|
||||
|
||||
Ok(ServerInfo {
|
||||
protocol,
|
||||
protocol_version: protocol,
|
||||
name,
|
||||
map,
|
||||
folder,
|
||||
game,
|
||||
game_mode,
|
||||
appid,
|
||||
players_online: players,
|
||||
players_maximum: max_players,
|
||||
|
|
@ -353,7 +353,7 @@ impl ValveProtocol {
|
|||
has_password,
|
||||
vac_secured,
|
||||
the_ship,
|
||||
version,
|
||||
game_version,
|
||||
extra_data,
|
||||
is_mod: false,
|
||||
mod_data: None,
|
||||
|
|
@ -436,7 +436,6 @@ fn get_response(
|
|||
let mut client = ValveProtocol::new(address, timeout_settings)?;
|
||||
|
||||
let info = client.get_server_info(&engine)?;
|
||||
let protocol = info.protocol;
|
||||
|
||||
if let Engine::Source(Some(appids)) = &engine {
|
||||
let mut is_specified_id = false;
|
||||
|
|
@ -454,6 +453,8 @@ fn get_response(
|
|||
}
|
||||
}
|
||||
|
||||
let protocol = info.protocol_version;
|
||||
|
||||
Ok(Response {
|
||||
info,
|
||||
players: match gather_settings.players {
|
||||
|
|
|
|||
|
|
@ -61,12 +61,12 @@ impl CommonResponse for Response {
|
|||
fn as_original(&self) -> GenericResponse { GenericResponse::Valve(self) }
|
||||
|
||||
fn name(&self) -> Option<&str> { Some(&self.info.name) }
|
||||
fn game(&self) -> Option<&str> { Some(&self.info.game) }
|
||||
fn game_version(&self) -> Option<&str> { Some(&self.info.version) }
|
||||
fn game_mode(&self) -> Option<&str> { Some(&self.info.game_mode) }
|
||||
fn game_version(&self) -> Option<&str> { Some(&self.info.game_version) }
|
||||
fn map(&self) -> Option<&str> { Some(&self.info.map) }
|
||||
fn players_maximum(&self) -> u64 { self.info.players_maximum.into() }
|
||||
fn players_online(&self) -> u64 { self.info.players_online.into() }
|
||||
fn players_bots(&self) -> Option<u64> { Some(self.info.players_bots.into()) }
|
||||
fn players_maximum(&self) -> u32 { self.info.players_maximum.into() }
|
||||
fn players_online(&self) -> u32 { self.info.players_online.into() }
|
||||
fn players_bots(&self) -> Option<u32> { Some(self.info.players_bots.into()) }
|
||||
fn has_password(&self) -> Option<bool> { Some(self.info.has_password) }
|
||||
|
||||
fn players(&self) -> Option<Vec<&dyn CommonPlayer>> {
|
||||
|
|
@ -81,15 +81,15 @@ impl CommonResponse for Response {
|
|||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct ServerInfo {
|
||||
/// Protocol used by the server.
|
||||
pub protocol: u8,
|
||||
pub protocol_version: u8,
|
||||
/// Name of the server.
|
||||
pub name: String,
|
||||
/// Map name.
|
||||
pub map: String,
|
||||
/// Name of the folder containing the game files.
|
||||
pub folder: String,
|
||||
/// The name of the game.
|
||||
pub game: String,
|
||||
/// The server-declared name of the game/game mode.
|
||||
pub game_mode: String,
|
||||
/// [Steam Application ID](https://developer.valvesoftware.com/wiki/Steam_Application_ID) of game.
|
||||
pub appid: u32,
|
||||
/// Number of players on the server.
|
||||
|
|
@ -109,7 +109,7 @@ pub struct ServerInfo {
|
|||
/// [The ship](https://developer.valvesoftware.com/wiki/The_Ship) extra data
|
||||
pub the_ship: Option<TheShip>,
|
||||
/// Version of the game installed on the server.
|
||||
pub version: String,
|
||||
pub game_version: String,
|
||||
/// Some extra data that the server might provide or not.
|
||||
pub extra_data: Option<ExtraData>,
|
||||
/// GoldSrc only: Indicates whether the hosted game is a mod.
|
||||
|
|
@ -125,7 +125,7 @@ pub struct ServerPlayer {
|
|||
/// Player's name.
|
||||
pub name: String,
|
||||
/// General score.
|
||||
pub score: u32,
|
||||
pub score: i32,
|
||||
/// How long a player has been in the server (seconds).
|
||||
pub duration: f32,
|
||||
/// Only for [the ship](https://developer.valvesoftware.com/wiki/The_Ship): deaths count
|
||||
|
|
@ -137,7 +137,7 @@ pub struct ServerPlayer {
|
|||
impl CommonPlayer for ServerPlayer {
|
||||
fn as_original(&self) -> GenericPlayer { GenericPlayer::Valve(self) }
|
||||
fn name(&self) -> &str { &self.name }
|
||||
fn score(&self) -> Option<u32> { Some(self.score) }
|
||||
fn score(&self) -> Option<i32> { Some(self.score) }
|
||||
}
|
||||
|
||||
/// Only present for [the ship](https://developer.valvesoftware.com/wiki/The_Ship).
|
||||
|
|
@ -447,7 +447,7 @@ pub mod game {
|
|||
/// Player's name.
|
||||
pub name: String,
|
||||
/// Player's score.
|
||||
pub score: u32,
|
||||
pub score: i32,
|
||||
/// How long a player has been in the server (seconds).
|
||||
pub duration: f32,
|
||||
}
|
||||
|
|
@ -511,10 +511,10 @@ pub mod game {
|
|||
let (port, steam_id, tv_port, tv_name, keywords) = get_optional_extracted_data(response.info.extra_data);
|
||||
|
||||
Self {
|
||||
protocol: response.info.protocol,
|
||||
protocol: response.info.protocol_version,
|
||||
name: response.info.name,
|
||||
map: response.info.map,
|
||||
game: response.info.game,
|
||||
game: response.info.game_mode,
|
||||
appid: response.info.appid,
|
||||
players_online: response.info.players_online,
|
||||
players_details: response
|
||||
|
|
@ -528,7 +528,7 @@ pub mod game {
|
|||
server_type: response.info.server_type,
|
||||
has_password: response.info.has_password,
|
||||
vac_secured: response.info.vac_secured,
|
||||
version: response.info.version,
|
||||
version: response.info.game_version,
|
||||
port,
|
||||
steam_id,
|
||||
tv_port,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue