mirror of
https://codeberg.org/demostf/parser.git
synced 2026-06-03 10:14:06 +02:00
strictly distinguish between server and demo ticks
This commit is contained in:
parent
33cc8f6055
commit
28de17a67c
34 changed files with 14232 additions and 1033 deletions
|
|
@ -5,6 +5,7 @@ use std::fs;
|
|||
|
||||
use bitbuffer::{BitError, BitRead, BitWrite, BitWriteStream, LittleEndian};
|
||||
use main_error::MainError;
|
||||
use tf_demo_parser::demo::data::DemoTick;
|
||||
use tf_demo_parser::demo::header::Header;
|
||||
use tf_demo_parser::demo::message::{setconvar::SetConVarMessage, Message, NetTickMessage};
|
||||
use tf_demo_parser::demo::packet::stop::StopPacket;
|
||||
|
|
@ -58,7 +59,7 @@ fn main() -> Result<(), MainError> {
|
|||
|
||||
let mut packet_start = packets.pos();
|
||||
let mut has_stop = false;
|
||||
let mut last_tick = 0;
|
||||
let mut last_tick = DemoTick::default();
|
||||
|
||||
while let Some(mut packet) = packets.next(&handler.state_handler)? {
|
||||
let packet_end = packets.pos();
|
||||
|
|
@ -116,7 +117,7 @@ fn header_fixup(header: &mut Header, mut packets: RawPacketStream) -> Result<(),
|
|||
let mut tickrate = 66;
|
||||
|
||||
while let Some(packet) = packets.next(&handler.state_handler)? {
|
||||
ticks = packet.tick();
|
||||
ticks = packet.tick().into();
|
||||
|
||||
if let Packet::Signon(message_packet) = &packet {
|
||||
for message in &message_packet.messages {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ pub mod userinfo;
|
|||
|
||||
use bitbuffer::{BitRead, BitReadStream, BitWrite, BitWriteStream, Endianness};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
|
||||
pub use userinfo::UserInfo;
|
||||
|
|
@ -127,3 +128,87 @@ impl schemars::JsonSchema for MaybeUtf8String {
|
|||
String::json_schema(gen)
|
||||
}
|
||||
}
|
||||
|
||||
/// Tick relative to the start of the game on the server
|
||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
Ord,
|
||||
PartialOrd,
|
||||
Eq,
|
||||
PartialEq,
|
||||
BitRead,
|
||||
BitWrite,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Default,
|
||||
)]
|
||||
pub struct ServerTick(u32);
|
||||
|
||||
impl PartialEq<u32> for ServerTick {
|
||||
fn eq(&self, other: &u32) -> bool {
|
||||
*other == self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd<u32> for ServerTick {
|
||||
fn partial_cmp(&self, other: &u32) -> Option<Ordering> {
|
||||
other.partial_cmp(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for ServerTick {
|
||||
fn from(tick: u32) -> Self {
|
||||
ServerTick(tick)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ServerTick> for u32 {
|
||||
fn from(tick: ServerTick) -> Self {
|
||||
tick.0
|
||||
}
|
||||
}
|
||||
|
||||
/// Tick relative to the start of the demo
|
||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
Ord,
|
||||
PartialOrd,
|
||||
Eq,
|
||||
PartialEq,
|
||||
BitRead,
|
||||
BitWrite,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Default,
|
||||
)]
|
||||
pub struct DemoTick(u32);
|
||||
|
||||
impl PartialEq<u32> for DemoTick {
|
||||
fn eq(&self, other: &u32) -> bool {
|
||||
*other == self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd<u32> for DemoTick {
|
||||
fn partial_cmp(&self, other: &u32) -> Option<Ordering> {
|
||||
other.partial_cmp(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for DemoTick {
|
||||
fn from(tick: u32) -> Self {
|
||||
DemoTick(tick)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DemoTick> for u32 {
|
||||
fn from(tick: DemoTick) -> Self {
|
||||
tick.0
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/// Messages that consists only of primitives and string and can be derived
|
||||
use crate::demo::data::MaybeUtf8String;
|
||||
use crate::demo::data::{MaybeUtf8String, ServerTick};
|
||||
use crate::Stream;
|
||||
use bitbuffer::{BitRead, BitWrite, LittleEndian};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
|
@ -15,7 +15,7 @@ pub struct FileMessage {
|
|||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||
#[derive(BitRead, BitWrite, Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||
pub struct NetTickMessage {
|
||||
pub tick: u32,
|
||||
pub tick: ServerTick,
|
||||
pub frame_time: u16,
|
||||
pub std_dev: u16,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use crate::demo::data::DemoTick;
|
||||
use crate::{ReadResult, Stream};
|
||||
use bitbuffer::{BitRead, BitWrite, LittleEndian};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
|
@ -5,13 +6,13 @@ use serde::{Deserialize, Serialize};
|
|||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||
pub struct ConsoleCmdPacket {
|
||||
pub tick: u32,
|
||||
pub tick: DemoTick,
|
||||
pub command: String,
|
||||
}
|
||||
|
||||
impl BitRead<'_, LittleEndian> for ConsoleCmdPacket {
|
||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
||||
let tick = stream.read_int(32)?;
|
||||
let tick = stream.read()?;
|
||||
let len = stream.read_int::<usize>(32)?;
|
||||
let mut packet_data = stream.read_bits(len * 8)?;
|
||||
let command: String = packet_data.read()?;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use crate::demo::data::DemoTick;
|
||||
use crate::demo::parser::MalformedSendPropDefinitionError;
|
||||
use crate::demo::sendprop::{
|
||||
RawSendPropDefinition, SendPropDefinition, SendPropFlag, SendPropIdentifier, SendPropType,
|
||||
|
|
@ -403,7 +404,7 @@ pub struct SendTable {
|
|||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||
pub struct DataTablePacket {
|
||||
pub tick: u32,
|
||||
pub tick: DemoTick,
|
||||
pub tables: Vec<ParseSendTable>,
|
||||
pub server_classes: Vec<ServerClass>,
|
||||
}
|
||||
|
|
@ -460,7 +461,7 @@ fn test_data_table_packet_roundtrip() {
|
|||
let state = ParserState::new(24, |_| false, false);
|
||||
crate::test_roundtrip_encode(
|
||||
DataTablePacket {
|
||||
tick: 123,
|
||||
tick: 123.into(),
|
||||
tables: vec![],
|
||||
server_classes: vec![],
|
||||
},
|
||||
|
|
@ -545,7 +546,7 @@ fn test_data_table_packet_roundtrip() {
|
|||
};
|
||||
crate::test_roundtrip_encode(
|
||||
DataTablePacket {
|
||||
tick: 1,
|
||||
tick: 1.into(),
|
||||
tables: vec![table1, table2],
|
||||
server_classes: vec![
|
||||
ServerClass {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use bitbuffer::{BitRead, BitWrite, BitWriteStream, LittleEndian};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::demo::data::DemoTick;
|
||||
use crate::demo::message::{Message, MessageType};
|
||||
use crate::demo::parser::Encode;
|
||||
use crate::demo::vector::Vector;
|
||||
|
|
@ -21,7 +22,7 @@ pub struct MessagePacketMeta {
|
|||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone, Default)]
|
||||
#[serde(bound(deserialize = "'a: 'static"))]
|
||||
pub struct MessagePacket<'a> {
|
||||
pub tick: u32,
|
||||
pub tick: DemoTick,
|
||||
pub messages: Vec<Message<'a>>,
|
||||
pub meta: MessagePacketMeta,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use self::stop::StopPacket;
|
|||
use self::stringtable::StringTablePacket;
|
||||
use self::synctick::SyncTickPacket;
|
||||
use self::usercmd::UserCmdPacket;
|
||||
use crate::demo::data::DemoTick;
|
||||
use crate::demo::parser::Encode;
|
||||
use serde::{Deserialize, Serialize};
|
||||
#[cfg(feature = "trace")]
|
||||
|
|
@ -38,7 +39,7 @@ pub enum Packet<'a> {
|
|||
}
|
||||
|
||||
impl Packet<'_> {
|
||||
pub fn tick(&self) -> u32 {
|
||||
pub fn tick(&self) -> DemoTick {
|
||||
match self {
|
||||
Packet::Signon(msg) => msg.tick,
|
||||
Packet::Message(msg) => msg.tick,
|
||||
|
|
@ -51,7 +52,7 @@ impl Packet<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_tick(&mut self, tick: u32) {
|
||||
pub fn set_tick(&mut self, tick: DemoTick) {
|
||||
match self {
|
||||
Packet::Signon(msg) => msg.tick = tick,
|
||||
Packet::Message(msg) => msg.tick = tick,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,23 @@
|
|||
use bitbuffer::{BitRead, BitWrite};
|
||||
use crate::demo::data::DemoTick;
|
||||
use bitbuffer::{BitRead, BitReadStream, BitWrite, BitWriteStream, Endianness};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||
#[derive(Debug, BitRead, BitWrite, PartialEq, Serialize, Deserialize, Clone)]
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||
pub struct StopPacket {
|
||||
#[size = 24]
|
||||
pub tick: u32,
|
||||
pub tick: DemoTick,
|
||||
}
|
||||
|
||||
impl<'a, E: Endianness> BitRead<'a, E> for StopPacket {
|
||||
fn read(stream: &mut BitReadStream<'a, E>) -> bitbuffer::Result<Self> {
|
||||
Ok(StopPacket {
|
||||
tick: stream.read_int::<u32>(24)?.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Endianness> BitWrite<E> for StopPacket {
|
||||
fn write(&self, stream: &mut BitWriteStream<E>) -> bitbuffer::Result<()> {
|
||||
stream.write_int::<u32>(self.tick.into(), 24)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use bitbuffer::{BitRead, BitWrite, BitWriteStream, LittleEndian};
|
|||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
use crate::demo::data::DemoTick;
|
||||
use crate::demo::message::stringtable::StringTableMeta;
|
||||
use crate::demo::parser::Encode;
|
||||
use crate::{Parse, ParseError, ParserState, ReadResult, Result, Stream};
|
||||
|
|
@ -233,13 +234,13 @@ impl fmt::Debug for StringTableEntry<'_> {
|
|||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||
#[serde(bound(deserialize = "'a: 'static"))]
|
||||
pub struct StringTablePacket<'a> {
|
||||
pub tick: u32,
|
||||
pub tick: DemoTick,
|
||||
pub tables: Vec<StringTable<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for StringTablePacket<'a> {
|
||||
fn parse(stream: &mut Stream<'a>, _state: &ParserState) -> Result<Self> {
|
||||
let tick = stream.read_int(32)?;
|
||||
let tick = stream.read()?;
|
||||
let length: usize = stream.read_int(32)?;
|
||||
let mut packet_data = stream.read_bits(length.saturating_mul(8))?;
|
||||
let count: usize = packet_data.read_int(8)?;
|
||||
|
|
@ -274,14 +275,14 @@ fn test_string_table_packet_roundtrip() {
|
|||
let state = ParserState::new(24, |_| false, false);
|
||||
crate::test_roundtrip_encode(
|
||||
StringTablePacket {
|
||||
tick: 1,
|
||||
tick: 1.into(),
|
||||
tables: vec![],
|
||||
},
|
||||
&state,
|
||||
);
|
||||
crate::test_roundtrip_encode(
|
||||
StringTablePacket {
|
||||
tick: 1,
|
||||
tick: 1.into(),
|
||||
tables: vec![StringTable {
|
||||
name: "table1".into(),
|
||||
entries: vec![],
|
||||
|
|
@ -295,7 +296,7 @@ fn test_string_table_packet_roundtrip() {
|
|||
);
|
||||
crate::test_roundtrip_encode(
|
||||
StringTablePacket {
|
||||
tick: 1,
|
||||
tick: 1.into(),
|
||||
tables: vec![
|
||||
StringTable {
|
||||
name: "table1".into(),
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use crate::demo::data::DemoTick;
|
||||
use bitbuffer::{BitRead, BitWrite};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||
#[derive(BitRead, BitWrite, Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||
pub struct SyncTickPacket {
|
||||
pub tick: u32,
|
||||
pub tick: DemoTick,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
use crate::demo::data::DemoTick;
|
||||
use bitbuffer::{BitRead, BitReadStream, BitWrite, BitWriteStream, LittleEndian};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||
pub struct UserCmdPacket {
|
||||
pub tick: u32,
|
||||
pub tick: DemoTick,
|
||||
pub sequence_out: u32,
|
||||
pub cmd: UserCmd,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use crate::demo::data::{DemoTick, ServerTick};
|
||||
use crate::demo::gameevent_gen::{
|
||||
GameEvent, PlayerDeathEvent, PlayerSpawnEvent, TeamPlayRoundWinEvent,
|
||||
};
|
||||
|
|
@ -22,11 +23,11 @@ pub struct ChatMessage {
|
|||
pub kind: ChatMessageKind,
|
||||
pub from: String,
|
||||
pub text: String,
|
||||
pub tick: u32,
|
||||
pub tick: DemoTick,
|
||||
}
|
||||
|
||||
impl ChatMessage {
|
||||
pub fn from_message(message: &SayText2Message, tick: u32) -> Self {
|
||||
pub fn from_message(message: &SayText2Message, tick: DemoTick) -> Self {
|
||||
ChatMessage {
|
||||
kind: message.kind,
|
||||
from: message
|
||||
|
|
@ -264,11 +265,11 @@ pub struct Spawn {
|
|||
pub user: UserId,
|
||||
pub class: Class,
|
||||
pub team: Team,
|
||||
pub tick: u32,
|
||||
pub tick: DemoTick,
|
||||
}
|
||||
|
||||
impl Spawn {
|
||||
pub fn from_event(event: &PlayerSpawnEvent, tick: u32) -> Self {
|
||||
pub fn from_event(event: &PlayerSpawnEvent, tick: DemoTick) -> Self {
|
||||
Spawn {
|
||||
user: UserId::from(event.user_id),
|
||||
class: Class::new(event.class),
|
||||
|
|
@ -319,11 +320,11 @@ pub struct Death {
|
|||
pub victim: UserId,
|
||||
pub assister: Option<UserId>,
|
||||
pub killer: UserId,
|
||||
pub tick: u32,
|
||||
pub tick: DemoTick,
|
||||
}
|
||||
|
||||
impl Death {
|
||||
pub fn from_event(event: &PlayerDeathEvent, tick: u32) -> Self {
|
||||
pub fn from_event(event: &PlayerDeathEvent, tick: DemoTick) -> Self {
|
||||
let assister = if event.assister < (16 * 1024) {
|
||||
Some(UserId::from(event.assister))
|
||||
} else {
|
||||
|
|
@ -343,11 +344,11 @@ impl Death {
|
|||
pub struct Round {
|
||||
pub winner: Team,
|
||||
pub length: f32,
|
||||
pub end_tick: u32,
|
||||
pub end_tick: DemoTick,
|
||||
}
|
||||
|
||||
impl Round {
|
||||
pub fn from_event(event: &TeamPlayRoundWinEvent, tick: u32) -> Self {
|
||||
pub fn from_event(event: &TeamPlayRoundWinEvent, tick: DemoTick) -> Self {
|
||||
Round {
|
||||
winner: Team::new(event.team),
|
||||
length: event.round_time,
|
||||
|
|
@ -374,15 +375,20 @@ impl MessageHandler for Analyser {
|
|||
fn does_handle(message_type: MessageType) -> bool {
|
||||
matches!(
|
||||
message_type,
|
||||
MessageType::GameEvent | MessageType::UserMessage | MessageType::ServerInfo
|
||||
MessageType::GameEvent
|
||||
| MessageType::UserMessage
|
||||
| MessageType::ServerInfo
|
||||
| MessageType::NetTick
|
||||
)
|
||||
}
|
||||
|
||||
fn handle_message(&mut self, message: &Message, tick: u32, _parser_state: &ParserState) {
|
||||
if self.state.start_tick == 0 {
|
||||
self.state.start_tick = tick;
|
||||
}
|
||||
fn handle_message(&mut self, message: &Message, tick: DemoTick, _parser_state: &ParserState) {
|
||||
match message {
|
||||
Message::NetTick(msg) => {
|
||||
if self.state.start_tick == 0 {
|
||||
self.state.start_tick = msg.tick;
|
||||
}
|
||||
}
|
||||
Message::ServerInfo(message) => {
|
||||
self.state.interval_per_tick = message.interval_per_tick
|
||||
}
|
||||
|
|
@ -424,7 +430,7 @@ impl Analyser {
|
|||
Self::default()
|
||||
}
|
||||
|
||||
fn handle_user_message(&mut self, message: &UserMessage, tick: u32) {
|
||||
fn handle_user_message(&mut self, message: &UserMessage, tick: DemoTick) {
|
||||
if let UserMessage::SayText2(text_message) = message {
|
||||
if text_message.kind == ChatMessageKind::NameChange {
|
||||
if let Some(from) = text_message.from.clone() {
|
||||
|
|
@ -444,7 +450,7 @@ impl Analyser {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_event(&mut self, event: &GameEvent, tick: u32) {
|
||||
fn handle_event(&mut self, event: &GameEvent, tick: DemoTick) {
|
||||
const WIN_REASON_TIME_LIMIT: u8 = 6;
|
||||
|
||||
match event {
|
||||
|
|
@ -494,6 +500,6 @@ pub struct MatchState {
|
|||
pub users: BTreeMap<UserId, UserInfo>,
|
||||
pub deaths: Vec<Death>,
|
||||
pub rounds: Vec<Round>,
|
||||
pub start_tick: u32,
|
||||
pub start_tick: ServerTick,
|
||||
pub interval_per_tick: f32,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use crate::demo::data::DemoTick;
|
||||
use crate::demo::gameevent_gen::{ObjectDestroyedEvent, PlayerDeathEvent};
|
||||
use crate::demo::gamevent::GameEvent;
|
||||
use crate::demo::message::gameevent::GameEventMessage;
|
||||
|
|
@ -239,11 +240,11 @@ pub struct Kill {
|
|||
pub assister_id: u16,
|
||||
pub victim_id: u16,
|
||||
pub weapon: String,
|
||||
pub tick: u32,
|
||||
pub tick: DemoTick,
|
||||
}
|
||||
|
||||
impl Kill {
|
||||
fn new(tick: u32, death: &PlayerDeathEvent) -> Self {
|
||||
fn new(tick: DemoTick, death: &PlayerDeathEvent) -> Self {
|
||||
Kill {
|
||||
attacker_id: death.attacker,
|
||||
assister_id: death.assister,
|
||||
|
|
@ -260,7 +261,7 @@ pub struct GameState {
|
|||
pub buildings: BTreeMap<EntityId, Building>,
|
||||
pub world: Option<World>,
|
||||
pub kills: Vec<Kill>,
|
||||
pub tick: u32,
|
||||
pub tick: DemoTick,
|
||||
}
|
||||
|
||||
impl GameState {
|
||||
|
|
@ -303,7 +304,7 @@ impl GameState {
|
|||
#[derive(Default, Debug)]
|
||||
pub struct GameStateAnalyser {
|
||||
pub state: GameState,
|
||||
tick: u32,
|
||||
tick: DemoTick,
|
||||
class_names: Vec<ServerClassName>, // indexed by ClassId
|
||||
}
|
||||
|
||||
|
|
@ -317,7 +318,7 @@ impl MessageHandler for GameStateAnalyser {
|
|||
)
|
||||
}
|
||||
|
||||
fn handle_message(&mut self, message: &Message, _tick: u32, parser_state: &ParserState) {
|
||||
fn handle_message(&mut self, message: &Message, _tick: DemoTick, parser_state: &ParserState) {
|
||||
match message {
|
||||
Message::PacketEntities(message) => {
|
||||
for entity in &message.entities {
|
||||
|
|
@ -374,7 +375,7 @@ impl MessageHandler for GameStateAnalyser {
|
|||
|
||||
fn handle_packet_meta(
|
||||
&mut self,
|
||||
tick: u32,
|
||||
tick: DemoTick,
|
||||
_meta: &MessagePacketMeta,
|
||||
_parser_state: &ParserState,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use crate::demo::packet::stringtable::{StringTable, StringTableEntry};
|
|||
use crate::demo::packet::Packet;
|
||||
use crate::Result;
|
||||
|
||||
use crate::demo::data::{DemoTick, ServerTick};
|
||||
use crate::demo::header::Header;
|
||||
use crate::demo::packet::message::MessagePacketMeta;
|
||||
use crate::ParserState;
|
||||
|
|
@ -16,7 +17,8 @@ pub trait MessageHandler {
|
|||
|
||||
fn handle_header(&mut self, _header: &Header) {}
|
||||
|
||||
fn handle_message(&mut self, _message: &Message, _tick: u32, _parser_state: &ParserState) {}
|
||||
fn handle_message(&mut self, _message: &Message, _tick: DemoTick, _parser_state: &ParserState) {
|
||||
}
|
||||
|
||||
fn handle_string_entry(
|
||||
&mut self,
|
||||
|
|
@ -37,7 +39,7 @@ pub trait MessageHandler {
|
|||
|
||||
fn handle_packet_meta(
|
||||
&mut self,
|
||||
_tick: u32,
|
||||
_tick: DemoTick,
|
||||
_meta: &MessagePacketMeta,
|
||||
_parser_state: &ParserState,
|
||||
) {
|
||||
|
|
@ -64,7 +66,8 @@ impl MessageHandler for NullHandler {
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct DemoHandler<'a, T: MessageHandler> {
|
||||
pub tick: u32,
|
||||
pub server_tick: ServerTick,
|
||||
pub demo_tick: DemoTick,
|
||||
pub string_table_names: Vec<Cow<'a, str>>,
|
||||
analyser: T,
|
||||
pub state_handler: ParserState,
|
||||
|
|
@ -87,7 +90,8 @@ impl<'a, T: MessageHandler> DemoHandler<'a, T> {
|
|||
let state_handler = ParserState::new(24, T::does_handle, false);
|
||||
|
||||
DemoHandler {
|
||||
tick: 0,
|
||||
server_tick: ServerTick::default(),
|
||||
demo_tick: DemoTick::default(),
|
||||
string_table_names: Vec::new(),
|
||||
analyser,
|
||||
state_handler,
|
||||
|
|
@ -97,7 +101,8 @@ impl<'a, T: MessageHandler> DemoHandler<'a, T> {
|
|||
let state_handler = ParserState::new(24, T::does_handle, true);
|
||||
|
||||
DemoHandler {
|
||||
tick: 0,
|
||||
server_tick: ServerTick::default(),
|
||||
demo_tick: DemoTick::default(),
|
||||
string_table_names: Vec::new(),
|
||||
analyser,
|
||||
state_handler,
|
||||
|
|
@ -124,7 +129,10 @@ impl<'a, T: MessageHandler> DemoHandler<'a, T> {
|
|||
.handle_packet_meta(packet.tick, &packet.meta, &self.state_handler);
|
||||
for message in packet.messages {
|
||||
match message {
|
||||
Message::NetTick(message) => self.tick = message.tick,
|
||||
Message::NetTick(message) => {
|
||||
self.server_tick = message.tick;
|
||||
self.handle_message(Message::NetTick(message), packet.tick)
|
||||
}
|
||||
Message::CreateStringTable(message) => {
|
||||
self.handle_string_table(message.table)
|
||||
}
|
||||
|
|
@ -132,9 +140,9 @@ impl<'a, T: MessageHandler> DemoHandler<'a, T> {
|
|||
self.handle_table_update(message.table_id, message.entries)
|
||||
}
|
||||
Message::PacketEntities(msg) => {
|
||||
self.handle_message(Message::PacketEntities(msg))
|
||||
self.handle_message(Message::PacketEntities(msg), packet.tick)
|
||||
}
|
||||
message => self.handle_message(message),
|
||||
message => self.handle_message(message, packet.tick),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -184,13 +192,13 @@ impl<'a, T: MessageHandler> DemoHandler<'a, T> {
|
|||
.handle_data_table(send_tables, server_classes)
|
||||
}
|
||||
|
||||
pub fn handle_message(&mut self, message: Message<'a>) {
|
||||
pub fn handle_message(&mut self, message: Message<'a>, tick: DemoTick) {
|
||||
let message_type = message.get_message_type();
|
||||
if T::does_handle(message_type) {
|
||||
self.analyser
|
||||
.handle_message(&message, self.tick, &self.state_handler);
|
||||
.handle_message(&message, tick, &self.state_handler);
|
||||
}
|
||||
self.state_handler.handle_message(message, self.tick);
|
||||
self.state_handler.handle_message(message, tick);
|
||||
}
|
||||
|
||||
pub fn into_output(self) -> T::Output {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use crate::demo::data::DemoTick;
|
||||
use crate::demo::message::{Message, MessageType};
|
||||
|
||||
use crate::demo::parser::handler::MessageHandler;
|
||||
|
|
@ -16,7 +17,7 @@ impl MessageHandler for MessageTypeAnalyser {
|
|||
true
|
||||
}
|
||||
|
||||
fn handle_message(&mut self, message: &Message, _tick: u32, _parser_state: &ParserState) {
|
||||
fn handle_message(&mut self, message: &Message, _tick: DemoTick, _parser_state: &ParserState) {
|
||||
self.packet_types.push(message.get_message_type())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use crate::demo::data::DemoTick;
|
||||
use bitbuffer::{BitError, BitRead, BitWrite, BitWriteStream, LittleEndian};
|
||||
|
||||
pub use self::messagetypeanalyser::MessageTypeAnalyser;
|
||||
|
|
@ -208,5 +209,5 @@ impl<'a, A: MessageHandler + BorrowMessageHandler> DemoTicker<'a, A> {
|
|||
pub struct Tick<'a, State> {
|
||||
pub state: &'a State,
|
||||
pub parser_state: &'a ParserState,
|
||||
pub tick: u32,
|
||||
pub tick: DemoTick,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use crate::demo::packet::datatable::{
|
|||
};
|
||||
use crate::demo::packet::stringtable::StringTableEntry;
|
||||
|
||||
use crate::demo::data::DemoTick;
|
||||
use crate::demo::sendprop::{SendProp, SendPropIdentifier};
|
||||
use crate::nullhasher::NullHasherBuilder;
|
||||
use crate::{Result, Stream};
|
||||
|
|
@ -221,7 +222,7 @@ impl<'a> ParserState {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn handle_message(&mut self, message: Message, _tick: u32) {
|
||||
pub fn handle_message(&mut self, message: Message, _tick: DemoTick) {
|
||||
match message {
|
||||
Message::ServerInfo(message) => {
|
||||
self.demo_meta.version = message.version;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue