mirror of
https://github.com/tribufu/rust-gamedig
synced 2026-05-06 15:27:28 +00:00
[Crate] Add feature: serde (#21)
* feat(serde): add additional derives * fix: remove attr on internal enum * fix add missing derive
This commit is contained in:
parent
bd2e373d66
commit
84af4230f7
5 changed files with 113 additions and 62 deletions
13
Cargo.toml
13
Cargo.toml
|
|
@ -2,7 +2,10 @@
|
|||
name = "gamedig"
|
||||
version = "0.2.1"
|
||||
edition = "2021"
|
||||
authors = ["CosminPerRam [https://github.com/CosminPerRam]", "node-GameDig contributors [https://github.com/gamedig/node-gamedig/contributors]"]
|
||||
authors = [
|
||||
"CosminPerRam [https://github.com/CosminPerRam]",
|
||||
"node-GameDig contributors [https://github.com/gamedig/node-gamedig/contributors]",
|
||||
]
|
||||
license = "MIT"
|
||||
description = "Check out servers with this."
|
||||
homepage = "https://github.com/gamedig/rust-gamedig"
|
||||
|
|
@ -13,12 +16,14 @@ keywords = ["server", "query", "game", "check", "status"]
|
|||
rust-version = "1.56.1"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
no_games = []
|
||||
serde = ["dep:serde", "serde/derive"]
|
||||
|
||||
[dependencies]
|
||||
byteorder = "1.4.3"
|
||||
|
||||
bzip2-rs = "0.1.2" # for compression
|
||||
bzip2-rs = "0.1.2"
|
||||
crc32fast = "1.3.2"
|
||||
serde_json = "1.0.91"
|
||||
|
||||
serde_json = "1.0.91" # json to structs
|
||||
serde = { version = "1.0.155", optional = true }
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@ use crate::GDResult;
|
|||
use crate::protocols::valve;
|
||||
use crate::protocols::valve::{Server, ServerPlayer, get_optional_extracted_data, SteamApp};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg (feature = "serde")]
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd)]
|
||||
pub struct TheShipPlayer {
|
||||
pub name: String,
|
||||
pub score: u32,
|
||||
|
|
@ -24,7 +28,8 @@ impl TheShipPlayer {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Response {
|
||||
pub protocol: u8,
|
||||
pub name: String,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A player’s details.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct Player {
|
||||
pub name: String,
|
||||
pub team: u8,
|
||||
|
|
@ -13,11 +17,12 @@ pub struct Player {
|
|||
pub frags: u32,
|
||||
pub deaths: Option<u32>,
|
||||
pub health: Option<u32>,
|
||||
pub secret: bool
|
||||
pub secret: bool,
|
||||
}
|
||||
|
||||
/// A query response.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Response {
|
||||
pub name: String,
|
||||
pub map: String,
|
||||
|
|
@ -32,5 +37,5 @@ pub struct Response {
|
|||
pub players_minimum: u8,
|
||||
pub players: Vec<Player>,
|
||||
pub tournament: bool,
|
||||
pub unused_entries: HashMap<String, String>
|
||||
pub unused_entries: HashMap<String, String>,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,45 +1,51 @@
|
|||
|
||||
/*
|
||||
Although its a lightly modified version, this file contains code
|
||||
by Jaiden Bernard (2021-2022 - MIT) from
|
||||
https://github.com/thisjaiden/golden_apple/blob/master/src/lib.rs
|
||||
*/
|
||||
|
||||
use crate::GDResult;
|
||||
use crate::bufferer::Bufferer;
|
||||
use crate::GDError::{PacketBad, UnknownEnumCast};
|
||||
use crate::GDResult;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// The type of Minecraft Server you want to query.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub enum Server {
|
||||
/// Java Edition.
|
||||
Java,
|
||||
/// Legacy Java.
|
||||
Legacy(LegacyGroup),
|
||||
/// Bedrock Edition.
|
||||
Bedrock
|
||||
Bedrock,
|
||||
}
|
||||
|
||||
/// Legacy Java (Versions) Groups.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub enum LegacyGroup {
|
||||
/// 1.6
|
||||
V1_6,
|
||||
/// 1.4 - 1.5
|
||||
V1_4,
|
||||
/// Beta 1.8 - 1.3
|
||||
VB1_8
|
||||
VB1_8,
|
||||
}
|
||||
|
||||
/// Information about a player.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct Player {
|
||||
pub name: String,
|
||||
pub id: String
|
||||
pub id: String,
|
||||
}
|
||||
|
||||
/// A Java query response.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct JavaResponse {
|
||||
/// Version name, example: "1.19.2".
|
||||
pub version_name: String,
|
||||
|
|
@ -60,11 +66,12 @@ pub struct JavaResponse {
|
|||
/// Tells if secure chat is enforced (can be missing).
|
||||
pub enforces_secure_chat: Option<bool>,
|
||||
/// Tell's the server type.
|
||||
pub server_type: Server
|
||||
pub server_type: Server,
|
||||
}
|
||||
|
||||
/// A Bedrock Edition query response.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct BedrockResponse {
|
||||
/// Server's edition.
|
||||
pub edition: String,
|
||||
|
|
@ -85,7 +92,7 @@ pub struct BedrockResponse {
|
|||
/// Current game mode.
|
||||
pub game_mode: Option<GameMode>,
|
||||
/// Tells the server type.
|
||||
pub server_type: Server
|
||||
pub server_type: Server,
|
||||
}
|
||||
|
||||
impl JavaResponse {
|
||||
|
|
@ -100,15 +107,20 @@ impl JavaResponse {
|
|||
favicon: None,
|
||||
previews_chat: None,
|
||||
enforces_secure_chat: None,
|
||||
server_type: Server::Bedrock
|
||||
server_type: Server::Bedrock,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A server's game mode (used only by Bedrock servers).
|
||||
#[derive(Debug)]
|
||||
/// A server's game mode (used only by Bedrock servers.
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub enum GameMode {
|
||||
Survival, Creative, Hardcore, Spectator, Adventure
|
||||
Survival,
|
||||
Creative,
|
||||
Hardcore,
|
||||
Spectator,
|
||||
Adventure,
|
||||
}
|
||||
|
||||
impl GameMode {
|
||||
|
|
@ -119,7 +131,7 @@ impl GameMode {
|
|||
"Hardcore" => Ok(GameMode::Hardcore),
|
||||
"Spectator" => Ok(GameMode::Spectator),
|
||||
"Adventure" => Ok(GameMode::Adventure),
|
||||
_ => Err(UnknownEnumCast)
|
||||
_ => Err(UnknownEnumCast),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -137,7 +149,7 @@ pub(crate) fn get_varint(buffer: &mut Bufferer) -> GDResult<i32> {
|
|||
|
||||
// The 5th byte is only allowed to have the 4 smallest bits set
|
||||
if i == 4 && (current_byte & 0xf0 != 0) {
|
||||
return Err(PacketBad)
|
||||
return Err(PacketBad);
|
||||
}
|
||||
|
||||
if (current_byte & msb) == 0 {
|
||||
|
|
|
|||
|
|
@ -1,31 +1,38 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// The type of the server.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub enum Server {
|
||||
Dedicated,
|
||||
NonDedicated,
|
||||
TV
|
||||
TV,
|
||||
}
|
||||
|
||||
/// The Operating System that the server is on.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub enum Environment {
|
||||
Linux,
|
||||
Windows,
|
||||
Mac
|
||||
Mac,
|
||||
}
|
||||
|
||||
/// A query response.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Response {
|
||||
pub info: ServerInfo,
|
||||
pub players: Option<Vec<ServerPlayer>>,
|
||||
pub rules: Option<HashMap<String, String>>
|
||||
pub rules: Option<HashMap<String, String>>,
|
||||
}
|
||||
|
||||
/// General server information's.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct ServerInfo {
|
||||
/// Protocol used by the server.
|
||||
pub protocol: u8,
|
||||
|
|
@ -62,11 +69,12 @@ pub struct ServerInfo {
|
|||
/// GoldSrc only: Indicates whether the hosted game is a mod.
|
||||
pub is_mod: bool,
|
||||
/// GoldSrc only: If the game is a mod, provide additional data.
|
||||
pub mod_data: Option<ModData>
|
||||
pub mod_data: Option<ModData>,
|
||||
}
|
||||
|
||||
/// A server player.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd)]
|
||||
pub struct ServerPlayer {
|
||||
/// Player's name.
|
||||
pub name: String,
|
||||
|
|
@ -81,15 +89,17 @@ pub struct ServerPlayer {
|
|||
}
|
||||
|
||||
/// Only present for [the ship](https://developer.valvesoftware.com/wiki/The_Ship).
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct TheShip {
|
||||
pub mode: u8,
|
||||
pub witnesses: u8,
|
||||
pub duration: u8
|
||||
pub duration: u8,
|
||||
}
|
||||
|
||||
/// Some extra data that the server might provide or not.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct ExtraData {
|
||||
/// The server's game port number.
|
||||
pub port: Option<u16>,
|
||||
|
|
@ -102,18 +112,19 @@ pub struct ExtraData {
|
|||
/// Keywords that describe the server according to it.
|
||||
pub keywords: Option<String>,
|
||||
/// The server's 64-bit GameID.
|
||||
pub game_id: Option<u64>
|
||||
pub game_id: Option<u64>,
|
||||
}
|
||||
|
||||
/// Data related to GoldSrc Mod response.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct ModData {
|
||||
pub link: String,
|
||||
pub download_link: String,
|
||||
pub version: u32,
|
||||
pub size: u32,
|
||||
pub multiplayer_only: bool,
|
||||
pub has_own_dll: bool
|
||||
pub has_own_dll: bool,
|
||||
}
|
||||
|
||||
pub(crate) type ExtractedData = (
|
||||
|
|
@ -142,11 +153,12 @@ pub(crate) enum Request {
|
|||
/// Known as `A2S_PLAYERS`
|
||||
Players = 0x55,
|
||||
/// Known as `A2S_RULES`
|
||||
Rules = 0x56
|
||||
Rules = 0x56,
|
||||
}
|
||||
|
||||
/// Supported steam apps
|
||||
#[derive(Eq, PartialEq, Clone)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub enum SteamApp {
|
||||
/// Counter-Strike
|
||||
CS,
|
||||
|
|
@ -236,9 +248,9 @@ impl SteamApp {
|
|||
/// Get the specified app as engine.
|
||||
pub fn as_engine(&self) -> Engine {
|
||||
match self {
|
||||
SteamApp::CS => Engine::GoldSrc(false), //10
|
||||
SteamApp::TFC => Engine::GoldSrc(false), //20
|
||||
SteamApp::DOD => Engine::GoldSrc(false), //30
|
||||
SteamApp::CS => Engine::GoldSrc(false), //10
|
||||
SteamApp::TFC => Engine::GoldSrc(false), //20
|
||||
SteamApp::DOD => Engine::GoldSrc(false), //30
|
||||
SteamApp::CSCZ => Engine::GoldSrc(false), //80
|
||||
SteamApp::CSS => Engine::new_source(240),
|
||||
SteamApp::DODS => Engine::new_source(300),
|
||||
|
|
@ -282,7 +294,8 @@ impl SteamApp {
|
|||
}
|
||||
|
||||
/// Engine type.
|
||||
#[derive(Eq, PartialEq, Clone)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub enum Engine {
|
||||
/// A Source game, the argument represents the possible steam app ids, if its **None**, let
|
||||
/// the query find it, if its **Some**, the query fails if the response id is not the first
|
||||
|
|
@ -290,7 +303,7 @@ pub enum Engine {
|
|||
Source(Option<(u32, Option<u32>)>),
|
||||
/// A GoldSrc game, the argument indicates whether to enforce
|
||||
/// requesting the obsolete A2S_INFO response or not.
|
||||
GoldSrc(bool)
|
||||
GoldSrc(bool),
|
||||
}
|
||||
|
||||
impl Engine {
|
||||
|
|
@ -306,7 +319,7 @@ impl Engine {
|
|||
/// What data to gather, purely used only with the query function.
|
||||
pub struct GatheringSettings {
|
||||
pub players: bool,
|
||||
pub rules: bool
|
||||
pub rules: bool,
|
||||
}
|
||||
|
||||
impl Default for GatheringSettings {
|
||||
|
|
@ -314,7 +327,7 @@ impl Default for GatheringSettings {
|
|||
fn default() -> Self {
|
||||
Self {
|
||||
players: true,
|
||||
rules: true
|
||||
rules: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -322,19 +335,23 @@ impl Default for GatheringSettings {
|
|||
/// Generic response types that are used by many games, they are the protocol ones, but without the
|
||||
/// unnecessary bits (example: the **The Ship**-only fields).
|
||||
pub mod game {
|
||||
use std::collections::HashMap;
|
||||
use crate::protocols::valve::types::get_optional_extracted_data;
|
||||
use super::{Server, ServerPlayer};
|
||||
use crate::protocols::valve::types::get_optional_extracted_data;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A player's details.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd)]
|
||||
pub struct Player {
|
||||
/// Player's name.
|
||||
pub name: String,
|
||||
/// Player's score.
|
||||
pub score: u32,
|
||||
/// How long a player has been in the server (seconds).
|
||||
pub duration: f32
|
||||
pub duration: f32,
|
||||
}
|
||||
|
||||
impl Player {
|
||||
|
|
@ -342,13 +359,14 @@ pub mod game {
|
|||
Self {
|
||||
name: player.name.clone(),
|
||||
score: player.score,
|
||||
duration: player.duration
|
||||
duration: player.duration,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The query response.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Response {
|
||||
/// Protocol used by the server.
|
||||
pub protocol: u8,
|
||||
|
|
@ -387,12 +405,13 @@ pub mod game {
|
|||
/// Keywords that describe the server according to it.
|
||||
pub keywords: Option<String>,
|
||||
/// Server's rules.
|
||||
pub rules: HashMap<String, String>
|
||||
pub rules: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl Response {
|
||||
pub fn new_from_valve_response(response: super::Response) -> Self {
|
||||
let (port, steam_id, tv_port, tv_name, keywords) = get_optional_extracted_data(response.info.extra_data);
|
||||
let (port, steam_id, tv_port, tv_name, keywords) =
|
||||
get_optional_extracted_data(response.info.extra_data);
|
||||
|
||||
Self {
|
||||
protocol: response.info.protocol,
|
||||
|
|
@ -401,7 +420,12 @@ pub mod game {
|
|||
game: response.info.game,
|
||||
appid: response.info.appid,
|
||||
players_online: response.info.players_online,
|
||||
players_details: response.players.unwrap_or_default().iter().map(Player::from_valve_response).collect(),
|
||||
players_details: response
|
||||
.players
|
||||
.unwrap_or_default()
|
||||
.iter()
|
||||
.map(Player::from_valve_response)
|
||||
.collect(),
|
||||
players_maximum: response.info.players_maximum,
|
||||
players_bots: response.info.players_bots,
|
||||
server_type: response.info.server_type,
|
||||
|
|
@ -413,7 +437,7 @@ pub mod game {
|
|||
tv_port,
|
||||
tv_name,
|
||||
keywords,
|
||||
rules: response.rules.unwrap_or_default()
|
||||
rules: response.rules.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue