mirror of
https://codeberg.org/demostf/parser.git
synced 2026-06-03 18:24:05 +02:00
handle older serverinfo messages
This commit is contained in:
parent
442c4963f6
commit
4bd97e4afc
3 changed files with 153 additions and 32 deletions
|
|
@ -53,28 +53,6 @@ pub struct PrintMessage {
|
||||||
pub value: MaybeUtf8String,
|
pub value: MaybeUtf8String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
|
||||||
#[derive(BitRead, BitWrite, Debug, PartialEq, Serialize, Deserialize, Clone)]
|
|
||||||
pub struct ServerInfoMessage {
|
|
||||||
pub version: u16,
|
|
||||||
pub server_count: u32,
|
|
||||||
pub stv: bool,
|
|
||||||
pub dedicated: bool,
|
|
||||||
pub max_crc: u32,
|
|
||||||
pub max_classes: u16,
|
|
||||||
pub map_hash: [u8; 16],
|
|
||||||
pub player_slot: u8,
|
|
||||||
pub max_player_count: u8,
|
|
||||||
pub interval_per_tick: f32,
|
|
||||||
#[size = 1]
|
|
||||||
pub platform: String,
|
|
||||||
pub game: String,
|
|
||||||
pub map: String,
|
|
||||||
pub skybox: String,
|
|
||||||
pub server_name: String,
|
|
||||||
pub replay: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||||
#[derive(BitRead, BitWrite, Debug, PartialEq, Serialize, Deserialize, Clone)]
|
#[derive(BitRead, BitWrite, Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||||
pub struct SetPauseMessage {
|
pub struct SetPauseMessage {
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,16 @@
|
||||||
pub use generated::*;
|
pub use generated::*;
|
||||||
|
|
||||||
use crate::demo::message::bspdecal::*;
|
pub use crate::demo::message::bspdecal::*;
|
||||||
use crate::demo::message::classinfo::*;
|
pub use crate::demo::message::classinfo::*;
|
||||||
use crate::demo::message::gameevent::*;
|
pub use crate::demo::message::gameevent::*;
|
||||||
use crate::demo::message::packetentities::*;
|
pub use crate::demo::message::packetentities::*;
|
||||||
use crate::demo::message::setconvar::*;
|
pub use crate::demo::message::setconvar::*;
|
||||||
use crate::demo::message::stringtable::*;
|
pub use crate::demo::message::stringtable::*;
|
||||||
use crate::demo::message::tempentities::*;
|
pub use crate::demo::message::tempentities::*;
|
||||||
use crate::demo::message::usermessage::*;
|
pub use crate::demo::message::usermessage::*;
|
||||||
use crate::demo::message::voice::*;
|
pub use crate::demo::message::voice::*;
|
||||||
use crate::demo::message::prefetch::*;
|
pub use crate::demo::message::prefetch::*;
|
||||||
|
pub use crate::demo::message::serverinfo::*;
|
||||||
use crate::demo::parser::{Encode, ParseBitSkip};
|
use crate::demo::parser::{Encode, ParseBitSkip};
|
||||||
use crate::{Parse, ParserState, Result, Stream};
|
use crate::{Parse, ParserState, Result, Stream};
|
||||||
use bitbuffer::{BitRead, BitWrite, BitWriteStream, LittleEndian};
|
use bitbuffer::{BitRead, BitWrite, BitWriteStream, LittleEndian};
|
||||||
|
|
@ -27,6 +28,7 @@ pub mod tempentities;
|
||||||
pub mod usermessage;
|
pub mod usermessage;
|
||||||
pub mod voice;
|
pub mod voice;
|
||||||
pub mod prefetch;
|
pub mod prefetch;
|
||||||
|
mod serverinfo;
|
||||||
|
|
||||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema_repr))]
|
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema_repr))]
|
||||||
#[derive(
|
#[derive(
|
||||||
|
|
|
||||||
141
src/demo/message/serverinfo.rs
Normal file
141
src/demo/message/serverinfo.rs
Normal file
|
|
@ -0,0 +1,141 @@
|
||||||
|
use crate::demo::parser::{Encode, ParseBitSkip};
|
||||||
|
use crate::{Parse, ParserState, Result, Stream};
|
||||||
|
use bitbuffer::{BitRead, BitWrite, BitWriteStream, LittleEndian};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct ServerInfoMessage {
|
||||||
|
pub version: u16,
|
||||||
|
pub server_count: u32,
|
||||||
|
pub stv: bool,
|
||||||
|
pub dedicated: bool,
|
||||||
|
pub max_crc: u32,
|
||||||
|
pub max_classes: u16,
|
||||||
|
pub map_hash: [u8; 16],
|
||||||
|
pub player_slot: u8,
|
||||||
|
pub max_player_count: u8,
|
||||||
|
pub interval_per_tick: f32,
|
||||||
|
pub platform: String,
|
||||||
|
pub game: String,
|
||||||
|
pub map: String,
|
||||||
|
pub skybox: String,
|
||||||
|
pub server_name: String,
|
||||||
|
pub replay: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for ServerInfoMessage {
|
||||||
|
fn parse(stream: &mut Stream<'a>, state: &ParserState) -> Result<Self> {
|
||||||
|
let part1 = ServerInfoMessagePart1::read(stream)?;
|
||||||
|
let map_hash = if state.protocol_version > 17 {
|
||||||
|
<[u8; 16]>::read(stream)?
|
||||||
|
} else {
|
||||||
|
let mut hash = [0; 16];
|
||||||
|
let crc = u32::read(stream)?;
|
||||||
|
hash[0..4].copy_from_slice(&crc.to_le_bytes());
|
||||||
|
hash
|
||||||
|
};
|
||||||
|
let part2 = ServerInfoMessagePart2::read(stream)?;
|
||||||
|
let replay = if state.protocol_version > 15 {
|
||||||
|
bool::read(stream)?
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
Ok(ServerInfoMessage {
|
||||||
|
version: part1.version,
|
||||||
|
server_count: part1.server_count,
|
||||||
|
stv: part1.stv,
|
||||||
|
dedicated: part1.dedicated,
|
||||||
|
max_crc: part1.max_crc,
|
||||||
|
max_classes: part1.max_classes,
|
||||||
|
map_hash,
|
||||||
|
player_slot: part2.player_slot,
|
||||||
|
max_player_count: part2.max_player_count,
|
||||||
|
interval_per_tick: part2.interval_per_tick,
|
||||||
|
platform: part2.platform,
|
||||||
|
game: part2.game,
|
||||||
|
map: part2.map,
|
||||||
|
skybox: part2.skybox,
|
||||||
|
server_name: part2.server_name,
|
||||||
|
replay,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ParseBitSkip<'a> for ServerInfoMessage {
|
||||||
|
fn parse_skip(stream: &mut Stream<'a>, state: &ParserState) -> Result<()> {
|
||||||
|
let version_dependent_size = match state.protocol_version {
|
||||||
|
0..=15 => 4 * 8, // only the 4 byte crc
|
||||||
|
16..=17 => 4 * 8 + 1, // adds the 1 bit replay flag
|
||||||
|
18.. => 16 * 8 + 1, // replaces 4 byte crc with an 16 byte hash
|
||||||
|
};
|
||||||
|
let size = <ServerInfoMessagePart1 as BitRead<LittleEndian>>::bit_size().unwrap_or_default()
|
||||||
|
+ <ServerInfoMessagePart2 as BitRead<LittleEndian>>::bit_size().unwrap_or_default()
|
||||||
|
+ version_dependent_size;
|
||||||
|
stream.skip_bits(size)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encode for ServerInfoMessage {
|
||||||
|
fn encode(&self, stream: &mut BitWriteStream<LittleEndian>, state: &ParserState) -> Result<()> {
|
||||||
|
let part1 = ServerInfoMessagePart1 {
|
||||||
|
version: self.version,
|
||||||
|
server_count: self.server_count,
|
||||||
|
stv: self.stv,
|
||||||
|
dedicated: self.dedicated,
|
||||||
|
max_crc: self.max_crc,
|
||||||
|
max_classes: self.max_classes,
|
||||||
|
};
|
||||||
|
part1.write(stream)?;
|
||||||
|
if state.protocol_version > 17 {
|
||||||
|
self.map_hash.write(stream)?;
|
||||||
|
} else {
|
||||||
|
let crc = u32::from_le_bytes([
|
||||||
|
self.map_hash[0],
|
||||||
|
self.map_hash[1],
|
||||||
|
self.map_hash[2],
|
||||||
|
self.map_hash[3],
|
||||||
|
]);
|
||||||
|
crc.write(stream)?;
|
||||||
|
};
|
||||||
|
let part2 = ServerInfoMessagePart2 {
|
||||||
|
player_slot: self.player_slot,
|
||||||
|
max_player_count: self.max_player_count,
|
||||||
|
interval_per_tick: self.interval_per_tick,
|
||||||
|
platform: self.platform.clone(),
|
||||||
|
game: self.game.clone(),
|
||||||
|
map: self.map.clone(),
|
||||||
|
skybox: self.skybox.clone(),
|
||||||
|
server_name: self.server_name.clone(),
|
||||||
|
};
|
||||||
|
part2.write(stream)?;
|
||||||
|
if state.protocol_version > 15 {
|
||||||
|
self.replay.write(stream)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(BitRead, BitWrite)]
|
||||||
|
pub struct ServerInfoMessagePart1 {
|
||||||
|
pub version: u16,
|
||||||
|
pub server_count: u32,
|
||||||
|
pub stv: bool,
|
||||||
|
pub dedicated: bool,
|
||||||
|
pub max_crc: u32,
|
||||||
|
pub max_classes: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(BitRead, BitWrite)]
|
||||||
|
pub struct ServerInfoMessagePart2 {
|
||||||
|
pub player_slot: u8,
|
||||||
|
pub max_player_count: u8,
|
||||||
|
pub interval_per_tick: f32,
|
||||||
|
#[size = 1]
|
||||||
|
pub platform: String,
|
||||||
|
pub game: String,
|
||||||
|
pub map: String,
|
||||||
|
pub skybox: String,
|
||||||
|
pub server_name: String,
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue