1
0
Fork 0
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:
Robin Appelman 2022-09-17 15:31:32 +02:00
commit 28de17a67c
34 changed files with 14232 additions and 1033 deletions

View file

@ -7,6 +7,7 @@ use pretty_assertions::assert_eq;
use std::fs;
use std::collections::{HashMap, HashSet};
use tf_demo_parser::demo::data::DemoTick;
use tf_demo_parser::demo::message::Message;
use tf_demo_parser::demo::packet::datatable::{ParseSendTable, SendTableName};
use tf_demo_parser::demo::packet::stringtable::StringTableEntry;
@ -23,7 +24,7 @@ impl MessageHandler for AllMessages {
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) {
black_box(message);
}

View file

@ -1,4 +1,5 @@
use iai::black_box;
use tf_demo_parser::demo::data::DemoTick;
use tf_demo_parser::demo::message::Message;
use tf_demo_parser::demo::parser::MessageHandler;
use tf_demo_parser::{Demo, DemoParser, MessageType, ParserState};
@ -12,7 +13,7 @@ impl MessageHandler for AllMessages {
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) {
black_box(message);
}

View file

@ -2,6 +2,7 @@ use fnv::{FnvHashMap, FnvHashSet};
use main_error::MainError;
use std::env;
use std::fs;
use tf_demo_parser::demo::data::DemoTick;
use tf_demo_parser::demo::message::Message;
use tf_demo_parser::demo::packet::datatable::{ParseSendTable, SendTableName, ServerClass};
use tf_demo_parser::demo::parser::MessageHandler;
@ -42,7 +43,7 @@ impl MessageHandler for PropAnalyzer {
matches!(message_type, MessageType::PacketEntities)
}
fn handle_message(&mut self, message: &Message, _tick: u32, _parser_state: &ParserState) {
fn handle_message(&mut self, message: &Message, _tick: DemoTick, _parser_state: &ParserState) {
if let Message::PacketEntities(message) = message {
for entity in &message.entities {
for prop in &entity.props {

View file

@ -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 {

View file

@ -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
}
}

View file

@ -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,
}

View file

@ -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()?;

View file

@ -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 {

View file

@ -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,
}

View file

@ -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,

View file

@ -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)
}
}

View file

@ -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(),

View file

@ -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,
}

View file

@ -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,
}

View file

@ -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,
}

View file

@ -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,
) {

View file

@ -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 {

View file

@ -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())
}

View file

@ -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,
}

View file

@ -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;

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +1,16 @@
{"chat":[],"users":{"2":{"classes":{},"name":"Icewind | demos.tf","userId":2,"steamId":"[U:1:64229260]","team":"other"}},"deaths":[],"rounds":[],"startTick":4854,"intervalPerTick":0.015}
{
"chat": [],
"users": {
"2": {
"classes": {},
"name": "Icewind | demos.tf",
"userId": 2,
"steamId": "[U:1:64229260]",
"team": "other"
}
},
"deaths": [],
"rounds": [],
"startTick": 68,
"intervalPerTick": 0.015
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -6,6 +6,7 @@ use test_case::test_case;
use fnv::FnvHashMap;
use std::collections::HashMap;
use std::io::{BufRead, BufReader};
use tf_demo_parser::demo::data::DemoTick;
use tf_demo_parser::demo::message::packetentities::{EntityId, PacketEntity, UpdateType};
use tf_demo_parser::demo::message::Message;
use tf_demo_parser::demo::packet::datatable::{
@ -39,7 +40,7 @@ impl From<UpdateType> for PVSCompat {
#[derive(PartialEq, Clone, Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct EntityDump {
tick: u32,
tick: DemoTick,
server_class: ServerClassName,
id: EntityId,
props: HashMap<String, SendPropValue>,
@ -49,7 +50,7 @@ struct EntityDump {
impl EntityDump {
pub fn from_entity(
entity: PacketEntity,
tick: u32,
tick: DemoTick,
classes: &[ServerClass],
prop_names: &FnvHashMap<SendPropIdentifier, (SendTableName, SendPropName)>,
state: &ParserState,
@ -71,7 +72,7 @@ impl EntityDump {
}
struct EntityDumper {
entities: Vec<(u32, PacketEntity)>,
entities: Vec<(DemoTick, PacketEntity)>,
prop_names: FnvHashMap<SendPropIdentifier, (SendTableName, SendPropName)>,
}
@ -94,7 +95,7 @@ impl MessageHandler for EntityDumper {
}
}
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(entity_message) => self.entities.extend(
entity_message

View file

@ -73,5 +73,5 @@ fn setup_message(handler: &mut DemoHandler<NullHandler>, input: &str) {
&handler.state_handler,
)
.unwrap();
handler.handle_message(message);
handler.handle_message(message, 0.into());
}

View file

@ -18,6 +18,12 @@ fn snapshot_test(input_file: &str, snapshot_file: &str) {
let file = fs::read(format!("test_data/{}", input_file)).expect("Unable to read file");
let demo = Demo::new(&file);
let (_, state) = DemoParser::new(demo.get_stream()).parse().unwrap();
//
// fs::write(
// format!("test_data/{}", snapshot_file),
// serde_json::to_string_pretty(&state).unwrap(),
// )
// .unwrap();
let expected: MatchState = serde_json::from_slice(
fs::read(format!("test_data/{}", snapshot_file))