mirror of
https://codeberg.org/demostf/parser.git
synced 2026-06-03 18:24:05 +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
|
|
@ -7,6 +7,7 @@ use pretty_assertions::assert_eq;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
use tf_demo_parser::demo::data::DemoTick;
|
||||||
use tf_demo_parser::demo::message::Message;
|
use tf_demo_parser::demo::message::Message;
|
||||||
use tf_demo_parser::demo::packet::datatable::{ParseSendTable, SendTableName};
|
use tf_demo_parser::demo::packet::datatable::{ParseSendTable, SendTableName};
|
||||||
use tf_demo_parser::demo::packet::stringtable::StringTableEntry;
|
use tf_demo_parser::demo::packet::stringtable::StringTableEntry;
|
||||||
|
|
@ -23,7 +24,7 @@ impl MessageHandler for AllMessages {
|
||||||
true
|
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);
|
black_box(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use iai::black_box;
|
use iai::black_box;
|
||||||
|
use tf_demo_parser::demo::data::DemoTick;
|
||||||
use tf_demo_parser::demo::message::Message;
|
use tf_demo_parser::demo::message::Message;
|
||||||
use tf_demo_parser::demo::parser::MessageHandler;
|
use tf_demo_parser::demo::parser::MessageHandler;
|
||||||
use tf_demo_parser::{Demo, DemoParser, MessageType, ParserState};
|
use tf_demo_parser::{Demo, DemoParser, MessageType, ParserState};
|
||||||
|
|
@ -12,7 +13,7 @@ impl MessageHandler for AllMessages {
|
||||||
true
|
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);
|
black_box(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ use fnv::{FnvHashMap, FnvHashSet};
|
||||||
use main_error::MainError;
|
use main_error::MainError;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use tf_demo_parser::demo::data::DemoTick;
|
||||||
use tf_demo_parser::demo::message::Message;
|
use tf_demo_parser::demo::message::Message;
|
||||||
use tf_demo_parser::demo::packet::datatable::{ParseSendTable, SendTableName, ServerClass};
|
use tf_demo_parser::demo::packet::datatable::{ParseSendTable, SendTableName, ServerClass};
|
||||||
use tf_demo_parser::demo::parser::MessageHandler;
|
use tf_demo_parser::demo::parser::MessageHandler;
|
||||||
|
|
@ -42,7 +43,7 @@ impl MessageHandler for PropAnalyzer {
|
||||||
matches!(message_type, MessageType::PacketEntities)
|
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 {
|
if let Message::PacketEntities(message) = message {
|
||||||
for entity in &message.entities {
|
for entity in &message.entities {
|
||||||
for prop in &entity.props {
|
for prop in &entity.props {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ use std::fs;
|
||||||
|
|
||||||
use bitbuffer::{BitError, BitRead, BitWrite, BitWriteStream, LittleEndian};
|
use bitbuffer::{BitError, BitRead, BitWrite, BitWriteStream, LittleEndian};
|
||||||
use main_error::MainError;
|
use main_error::MainError;
|
||||||
|
use tf_demo_parser::demo::data::DemoTick;
|
||||||
use tf_demo_parser::demo::header::Header;
|
use tf_demo_parser::demo::header::Header;
|
||||||
use tf_demo_parser::demo::message::{setconvar::SetConVarMessage, Message, NetTickMessage};
|
use tf_demo_parser::demo::message::{setconvar::SetConVarMessage, Message, NetTickMessage};
|
||||||
use tf_demo_parser::demo::packet::stop::StopPacket;
|
use tf_demo_parser::demo::packet::stop::StopPacket;
|
||||||
|
|
@ -58,7 +59,7 @@ fn main() -> Result<(), MainError> {
|
||||||
|
|
||||||
let mut packet_start = packets.pos();
|
let mut packet_start = packets.pos();
|
||||||
let mut has_stop = false;
|
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)? {
|
while let Some(mut packet) = packets.next(&handler.state_handler)? {
|
||||||
let packet_end = packets.pos();
|
let packet_end = packets.pos();
|
||||||
|
|
@ -116,7 +117,7 @@ fn header_fixup(header: &mut Header, mut packets: RawPacketStream) -> Result<(),
|
||||||
let mut tickrate = 66;
|
let mut tickrate = 66;
|
||||||
|
|
||||||
while let Some(packet) = packets.next(&handler.state_handler)? {
|
while let Some(packet) = packets.next(&handler.state_handler)? {
|
||||||
ticks = packet.tick();
|
ticks = packet.tick().into();
|
||||||
|
|
||||||
if let Packet::Signon(message_packet) = &packet {
|
if let Packet::Signon(message_packet) = &packet {
|
||||||
for message in &message_packet.messages {
|
for message in &message_packet.messages {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ pub mod userinfo;
|
||||||
|
|
||||||
use bitbuffer::{BitRead, BitReadStream, BitWrite, BitWriteStream, Endianness};
|
use bitbuffer::{BitRead, BitReadStream, BitWrite, BitWriteStream, Endianness};
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
use std::cmp::Ordering;
|
||||||
use std::fmt::{Debug, Display, Formatter};
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
|
|
||||||
pub use userinfo::UserInfo;
|
pub use userinfo::UserInfo;
|
||||||
|
|
@ -127,3 +128,87 @@ impl schemars::JsonSchema for MaybeUtf8String {
|
||||||
String::json_schema(gen)
|
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
|
/// 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 crate::Stream;
|
||||||
use bitbuffer::{BitRead, BitWrite, LittleEndian};
|
use bitbuffer::{BitRead, BitWrite, LittleEndian};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
@ -15,7 +15,7 @@ pub struct FileMessage {
|
||||||
#[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 NetTickMessage {
|
pub struct NetTickMessage {
|
||||||
pub tick: u32,
|
pub tick: ServerTick,
|
||||||
pub frame_time: u16,
|
pub frame_time: u16,
|
||||||
pub std_dev: u16,
|
pub std_dev: u16,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::demo::data::DemoTick;
|
||||||
use crate::{ReadResult, Stream};
|
use crate::{ReadResult, Stream};
|
||||||
use bitbuffer::{BitRead, BitWrite, LittleEndian};
|
use bitbuffer::{BitRead, BitWrite, LittleEndian};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
@ -5,13 +6,13 @@ use serde::{Deserialize, Serialize};
|
||||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||||
pub struct ConsoleCmdPacket {
|
pub struct ConsoleCmdPacket {
|
||||||
pub tick: u32,
|
pub tick: DemoTick,
|
||||||
pub command: String,
|
pub command: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitRead<'_, LittleEndian> for ConsoleCmdPacket {
|
impl BitRead<'_, LittleEndian> for ConsoleCmdPacket {
|
||||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
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 len = stream.read_int::<usize>(32)?;
|
||||||
let mut packet_data = stream.read_bits(len * 8)?;
|
let mut packet_data = stream.read_bits(len * 8)?;
|
||||||
let command: String = packet_data.read()?;
|
let command: String = packet_data.read()?;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::demo::data::DemoTick;
|
||||||
use crate::demo::parser::MalformedSendPropDefinitionError;
|
use crate::demo::parser::MalformedSendPropDefinitionError;
|
||||||
use crate::demo::sendprop::{
|
use crate::demo::sendprop::{
|
||||||
RawSendPropDefinition, SendPropDefinition, SendPropFlag, SendPropIdentifier, SendPropType,
|
RawSendPropDefinition, SendPropDefinition, SendPropFlag, SendPropIdentifier, SendPropType,
|
||||||
|
|
@ -403,7 +404,7 @@ pub struct SendTable {
|
||||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||||
pub struct DataTablePacket {
|
pub struct DataTablePacket {
|
||||||
pub tick: u32,
|
pub tick: DemoTick,
|
||||||
pub tables: Vec<ParseSendTable>,
|
pub tables: Vec<ParseSendTable>,
|
||||||
pub server_classes: Vec<ServerClass>,
|
pub server_classes: Vec<ServerClass>,
|
||||||
}
|
}
|
||||||
|
|
@ -460,7 +461,7 @@ fn test_data_table_packet_roundtrip() {
|
||||||
let state = ParserState::new(24, |_| false, false);
|
let state = ParserState::new(24, |_| false, false);
|
||||||
crate::test_roundtrip_encode(
|
crate::test_roundtrip_encode(
|
||||||
DataTablePacket {
|
DataTablePacket {
|
||||||
tick: 123,
|
tick: 123.into(),
|
||||||
tables: vec![],
|
tables: vec![],
|
||||||
server_classes: vec![],
|
server_classes: vec![],
|
||||||
},
|
},
|
||||||
|
|
@ -545,7 +546,7 @@ fn test_data_table_packet_roundtrip() {
|
||||||
};
|
};
|
||||||
crate::test_roundtrip_encode(
|
crate::test_roundtrip_encode(
|
||||||
DataTablePacket {
|
DataTablePacket {
|
||||||
tick: 1,
|
tick: 1.into(),
|
||||||
tables: vec![table1, table2],
|
tables: vec![table1, table2],
|
||||||
server_classes: vec![
|
server_classes: vec![
|
||||||
ServerClass {
|
ServerClass {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use bitbuffer::{BitRead, BitWrite, BitWriteStream, LittleEndian};
|
use bitbuffer::{BitRead, BitWrite, BitWriteStream, LittleEndian};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::demo::data::DemoTick;
|
||||||
use crate::demo::message::{Message, MessageType};
|
use crate::demo::message::{Message, MessageType};
|
||||||
use crate::demo::parser::Encode;
|
use crate::demo::parser::Encode;
|
||||||
use crate::demo::vector::Vector;
|
use crate::demo::vector::Vector;
|
||||||
|
|
@ -21,7 +22,7 @@ pub struct MessagePacketMeta {
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone, Default)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone, Default)]
|
||||||
#[serde(bound(deserialize = "'a: 'static"))]
|
#[serde(bound(deserialize = "'a: 'static"))]
|
||||||
pub struct MessagePacket<'a> {
|
pub struct MessagePacket<'a> {
|
||||||
pub tick: u32,
|
pub tick: DemoTick,
|
||||||
pub messages: Vec<Message<'a>>,
|
pub messages: Vec<Message<'a>>,
|
||||||
pub meta: MessagePacketMeta,
|
pub meta: MessagePacketMeta,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ use self::stop::StopPacket;
|
||||||
use self::stringtable::StringTablePacket;
|
use self::stringtable::StringTablePacket;
|
||||||
use self::synctick::SyncTickPacket;
|
use self::synctick::SyncTickPacket;
|
||||||
use self::usercmd::UserCmdPacket;
|
use self::usercmd::UserCmdPacket;
|
||||||
|
use crate::demo::data::DemoTick;
|
||||||
use crate::demo::parser::Encode;
|
use crate::demo::parser::Encode;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "trace")]
|
||||||
|
|
@ -38,7 +39,7 @@ pub enum Packet<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Packet<'_> {
|
impl Packet<'_> {
|
||||||
pub fn tick(&self) -> u32 {
|
pub fn tick(&self) -> DemoTick {
|
||||||
match self {
|
match self {
|
||||||
Packet::Signon(msg) => msg.tick,
|
Packet::Signon(msg) => msg.tick,
|
||||||
Packet::Message(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 {
|
match self {
|
||||||
Packet::Signon(msg) => msg.tick = tick,
|
Packet::Signon(msg) => msg.tick = tick,
|
||||||
Packet::Message(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};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||||
#[derive(Debug, BitRead, BitWrite, PartialEq, Serialize, Deserialize, Clone)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||||
pub struct StopPacket {
|
pub struct StopPacket {
|
||||||
#[size = 24]
|
pub tick: DemoTick,
|
||||||
pub tick: u32,
|
}
|
||||||
|
|
||||||
|
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 serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use crate::demo::data::DemoTick;
|
||||||
use crate::demo::message::stringtable::StringTableMeta;
|
use crate::demo::message::stringtable::StringTableMeta;
|
||||||
use crate::demo::parser::Encode;
|
use crate::demo::parser::Encode;
|
||||||
use crate::{Parse, ParseError, ParserState, ReadResult, Result, Stream};
|
use crate::{Parse, ParseError, ParserState, ReadResult, Result, Stream};
|
||||||
|
|
@ -233,13 +234,13 @@ impl fmt::Debug for StringTableEntry<'_> {
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||||
#[serde(bound(deserialize = "'a: 'static"))]
|
#[serde(bound(deserialize = "'a: 'static"))]
|
||||||
pub struct StringTablePacket<'a> {
|
pub struct StringTablePacket<'a> {
|
||||||
pub tick: u32,
|
pub tick: DemoTick,
|
||||||
pub tables: Vec<StringTable<'a>>,
|
pub tables: Vec<StringTable<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Parse<'a> for StringTablePacket<'a> {
|
impl<'a> Parse<'a> for StringTablePacket<'a> {
|
||||||
fn parse(stream: &mut Stream<'a>, _state: &ParserState) -> Result<Self> {
|
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 length: usize = stream.read_int(32)?;
|
||||||
let mut packet_data = stream.read_bits(length.saturating_mul(8))?;
|
let mut packet_data = stream.read_bits(length.saturating_mul(8))?;
|
||||||
let count: usize = packet_data.read_int(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);
|
let state = ParserState::new(24, |_| false, false);
|
||||||
crate::test_roundtrip_encode(
|
crate::test_roundtrip_encode(
|
||||||
StringTablePacket {
|
StringTablePacket {
|
||||||
tick: 1,
|
tick: 1.into(),
|
||||||
tables: vec![],
|
tables: vec![],
|
||||||
},
|
},
|
||||||
&state,
|
&state,
|
||||||
);
|
);
|
||||||
crate::test_roundtrip_encode(
|
crate::test_roundtrip_encode(
|
||||||
StringTablePacket {
|
StringTablePacket {
|
||||||
tick: 1,
|
tick: 1.into(),
|
||||||
tables: vec![StringTable {
|
tables: vec![StringTable {
|
||||||
name: "table1".into(),
|
name: "table1".into(),
|
||||||
entries: vec![],
|
entries: vec![],
|
||||||
|
|
@ -295,7 +296,7 @@ fn test_string_table_packet_roundtrip() {
|
||||||
);
|
);
|
||||||
crate::test_roundtrip_encode(
|
crate::test_roundtrip_encode(
|
||||||
StringTablePacket {
|
StringTablePacket {
|
||||||
tick: 1,
|
tick: 1.into(),
|
||||||
tables: vec![
|
tables: vec![
|
||||||
StringTable {
|
StringTable {
|
||||||
name: "table1".into(),
|
name: "table1".into(),
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
|
use crate::demo::data::DemoTick;
|
||||||
use bitbuffer::{BitRead, BitWrite};
|
use bitbuffer::{BitRead, BitWrite};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[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 SyncTickPacket {
|
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 bitbuffer::{BitRead, BitReadStream, BitWrite, BitWriteStream, LittleEndian};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||||
pub struct UserCmdPacket {
|
pub struct UserCmdPacket {
|
||||||
pub tick: u32,
|
pub tick: DemoTick,
|
||||||
pub sequence_out: u32,
|
pub sequence_out: u32,
|
||||||
pub cmd: UserCmd,
|
pub cmd: UserCmd,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::demo::data::{DemoTick, ServerTick};
|
||||||
use crate::demo::gameevent_gen::{
|
use crate::demo::gameevent_gen::{
|
||||||
GameEvent, PlayerDeathEvent, PlayerSpawnEvent, TeamPlayRoundWinEvent,
|
GameEvent, PlayerDeathEvent, PlayerSpawnEvent, TeamPlayRoundWinEvent,
|
||||||
};
|
};
|
||||||
|
|
@ -22,11 +23,11 @@ pub struct ChatMessage {
|
||||||
pub kind: ChatMessageKind,
|
pub kind: ChatMessageKind,
|
||||||
pub from: String,
|
pub from: String,
|
||||||
pub text: String,
|
pub text: String,
|
||||||
pub tick: u32,
|
pub tick: DemoTick,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChatMessage {
|
impl ChatMessage {
|
||||||
pub fn from_message(message: &SayText2Message, tick: u32) -> Self {
|
pub fn from_message(message: &SayText2Message, tick: DemoTick) -> Self {
|
||||||
ChatMessage {
|
ChatMessage {
|
||||||
kind: message.kind,
|
kind: message.kind,
|
||||||
from: message
|
from: message
|
||||||
|
|
@ -264,11 +265,11 @@ pub struct Spawn {
|
||||||
pub user: UserId,
|
pub user: UserId,
|
||||||
pub class: Class,
|
pub class: Class,
|
||||||
pub team: Team,
|
pub team: Team,
|
||||||
pub tick: u32,
|
pub tick: DemoTick,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Spawn {
|
impl Spawn {
|
||||||
pub fn from_event(event: &PlayerSpawnEvent, tick: u32) -> Self {
|
pub fn from_event(event: &PlayerSpawnEvent, tick: DemoTick) -> Self {
|
||||||
Spawn {
|
Spawn {
|
||||||
user: UserId::from(event.user_id),
|
user: UserId::from(event.user_id),
|
||||||
class: Class::new(event.class),
|
class: Class::new(event.class),
|
||||||
|
|
@ -319,11 +320,11 @@ pub struct Death {
|
||||||
pub victim: UserId,
|
pub victim: UserId,
|
||||||
pub assister: Option<UserId>,
|
pub assister: Option<UserId>,
|
||||||
pub killer: UserId,
|
pub killer: UserId,
|
||||||
pub tick: u32,
|
pub tick: DemoTick,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Death {
|
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) {
|
let assister = if event.assister < (16 * 1024) {
|
||||||
Some(UserId::from(event.assister))
|
Some(UserId::from(event.assister))
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -343,11 +344,11 @@ impl Death {
|
||||||
pub struct Round {
|
pub struct Round {
|
||||||
pub winner: Team,
|
pub winner: Team,
|
||||||
pub length: f32,
|
pub length: f32,
|
||||||
pub end_tick: u32,
|
pub end_tick: DemoTick,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Round {
|
impl Round {
|
||||||
pub fn from_event(event: &TeamPlayRoundWinEvent, tick: u32) -> Self {
|
pub fn from_event(event: &TeamPlayRoundWinEvent, tick: DemoTick) -> Self {
|
||||||
Round {
|
Round {
|
||||||
winner: Team::new(event.team),
|
winner: Team::new(event.team),
|
||||||
length: event.round_time,
|
length: event.round_time,
|
||||||
|
|
@ -374,15 +375,20 @@ impl MessageHandler for Analyser {
|
||||||
fn does_handle(message_type: MessageType) -> bool {
|
fn does_handle(message_type: MessageType) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
message_type,
|
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) {
|
fn handle_message(&mut self, message: &Message, tick: DemoTick, _parser_state: &ParserState) {
|
||||||
if self.state.start_tick == 0 {
|
|
||||||
self.state.start_tick = tick;
|
|
||||||
}
|
|
||||||
match message {
|
match message {
|
||||||
|
Message::NetTick(msg) => {
|
||||||
|
if self.state.start_tick == 0 {
|
||||||
|
self.state.start_tick = msg.tick;
|
||||||
|
}
|
||||||
|
}
|
||||||
Message::ServerInfo(message) => {
|
Message::ServerInfo(message) => {
|
||||||
self.state.interval_per_tick = message.interval_per_tick
|
self.state.interval_per_tick = message.interval_per_tick
|
||||||
}
|
}
|
||||||
|
|
@ -424,7 +430,7 @@ impl Analyser {
|
||||||
Self::default()
|
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 let UserMessage::SayText2(text_message) = message {
|
||||||
if text_message.kind == ChatMessageKind::NameChange {
|
if text_message.kind == ChatMessageKind::NameChange {
|
||||||
if let Some(from) = text_message.from.clone() {
|
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;
|
const WIN_REASON_TIME_LIMIT: u8 = 6;
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
|
|
@ -494,6 +500,6 @@ pub struct MatchState {
|
||||||
pub users: BTreeMap<UserId, UserInfo>,
|
pub users: BTreeMap<UserId, UserInfo>,
|
||||||
pub deaths: Vec<Death>,
|
pub deaths: Vec<Death>,
|
||||||
pub rounds: Vec<Round>,
|
pub rounds: Vec<Round>,
|
||||||
pub start_tick: u32,
|
pub start_tick: ServerTick,
|
||||||
pub interval_per_tick: f32,
|
pub interval_per_tick: f32,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::demo::data::DemoTick;
|
||||||
use crate::demo::gameevent_gen::{ObjectDestroyedEvent, PlayerDeathEvent};
|
use crate::demo::gameevent_gen::{ObjectDestroyedEvent, PlayerDeathEvent};
|
||||||
use crate::demo::gamevent::GameEvent;
|
use crate::demo::gamevent::GameEvent;
|
||||||
use crate::demo::message::gameevent::GameEventMessage;
|
use crate::demo::message::gameevent::GameEventMessage;
|
||||||
|
|
@ -239,11 +240,11 @@ pub struct Kill {
|
||||||
pub assister_id: u16,
|
pub assister_id: u16,
|
||||||
pub victim_id: u16,
|
pub victim_id: u16,
|
||||||
pub weapon: String,
|
pub weapon: String,
|
||||||
pub tick: u32,
|
pub tick: DemoTick,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Kill {
|
impl Kill {
|
||||||
fn new(tick: u32, death: &PlayerDeathEvent) -> Self {
|
fn new(tick: DemoTick, death: &PlayerDeathEvent) -> Self {
|
||||||
Kill {
|
Kill {
|
||||||
attacker_id: death.attacker,
|
attacker_id: death.attacker,
|
||||||
assister_id: death.assister,
|
assister_id: death.assister,
|
||||||
|
|
@ -260,7 +261,7 @@ pub struct GameState {
|
||||||
pub buildings: BTreeMap<EntityId, Building>,
|
pub buildings: BTreeMap<EntityId, Building>,
|
||||||
pub world: Option<World>,
|
pub world: Option<World>,
|
||||||
pub kills: Vec<Kill>,
|
pub kills: Vec<Kill>,
|
||||||
pub tick: u32,
|
pub tick: DemoTick,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameState {
|
impl GameState {
|
||||||
|
|
@ -303,7 +304,7 @@ impl GameState {
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct GameStateAnalyser {
|
pub struct GameStateAnalyser {
|
||||||
pub state: GameState,
|
pub state: GameState,
|
||||||
tick: u32,
|
tick: DemoTick,
|
||||||
class_names: Vec<ServerClassName>, // indexed by ClassId
|
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 {
|
match message {
|
||||||
Message::PacketEntities(message) => {
|
Message::PacketEntities(message) => {
|
||||||
for entity in &message.entities {
|
for entity in &message.entities {
|
||||||
|
|
@ -374,7 +375,7 @@ impl MessageHandler for GameStateAnalyser {
|
||||||
|
|
||||||
fn handle_packet_meta(
|
fn handle_packet_meta(
|
||||||
&mut self,
|
&mut self,
|
||||||
tick: u32,
|
tick: DemoTick,
|
||||||
_meta: &MessagePacketMeta,
|
_meta: &MessagePacketMeta,
|
||||||
_parser_state: &ParserState,
|
_parser_state: &ParserState,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ use crate::demo::packet::stringtable::{StringTable, StringTableEntry};
|
||||||
use crate::demo::packet::Packet;
|
use crate::demo::packet::Packet;
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
|
use crate::demo::data::{DemoTick, ServerTick};
|
||||||
use crate::demo::header::Header;
|
use crate::demo::header::Header;
|
||||||
use crate::demo::packet::message::MessagePacketMeta;
|
use crate::demo::packet::message::MessagePacketMeta;
|
||||||
use crate::ParserState;
|
use crate::ParserState;
|
||||||
|
|
@ -16,7 +17,8 @@ pub trait MessageHandler {
|
||||||
|
|
||||||
fn handle_header(&mut self, _header: &Header) {}
|
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(
|
fn handle_string_entry(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
@ -37,7 +39,7 @@ pub trait MessageHandler {
|
||||||
|
|
||||||
fn handle_packet_meta(
|
fn handle_packet_meta(
|
||||||
&mut self,
|
&mut self,
|
||||||
_tick: u32,
|
_tick: DemoTick,
|
||||||
_meta: &MessagePacketMeta,
|
_meta: &MessagePacketMeta,
|
||||||
_parser_state: &ParserState,
|
_parser_state: &ParserState,
|
||||||
) {
|
) {
|
||||||
|
|
@ -64,7 +66,8 @@ impl MessageHandler for NullHandler {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct DemoHandler<'a, T: MessageHandler> {
|
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>>,
|
pub string_table_names: Vec<Cow<'a, str>>,
|
||||||
analyser: T,
|
analyser: T,
|
||||||
pub state_handler: ParserState,
|
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);
|
let state_handler = ParserState::new(24, T::does_handle, false);
|
||||||
|
|
||||||
DemoHandler {
|
DemoHandler {
|
||||||
tick: 0,
|
server_tick: ServerTick::default(),
|
||||||
|
demo_tick: DemoTick::default(),
|
||||||
string_table_names: Vec::new(),
|
string_table_names: Vec::new(),
|
||||||
analyser,
|
analyser,
|
||||||
state_handler,
|
state_handler,
|
||||||
|
|
@ -97,7 +101,8 @@ impl<'a, T: MessageHandler> DemoHandler<'a, T> {
|
||||||
let state_handler = ParserState::new(24, T::does_handle, true);
|
let state_handler = ParserState::new(24, T::does_handle, true);
|
||||||
|
|
||||||
DemoHandler {
|
DemoHandler {
|
||||||
tick: 0,
|
server_tick: ServerTick::default(),
|
||||||
|
demo_tick: DemoTick::default(),
|
||||||
string_table_names: Vec::new(),
|
string_table_names: Vec::new(),
|
||||||
analyser,
|
analyser,
|
||||||
state_handler,
|
state_handler,
|
||||||
|
|
@ -124,7 +129,10 @@ impl<'a, T: MessageHandler> DemoHandler<'a, T> {
|
||||||
.handle_packet_meta(packet.tick, &packet.meta, &self.state_handler);
|
.handle_packet_meta(packet.tick, &packet.meta, &self.state_handler);
|
||||||
for message in packet.messages {
|
for message in packet.messages {
|
||||||
match message {
|
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) => {
|
Message::CreateStringTable(message) => {
|
||||||
self.handle_string_table(message.table)
|
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)
|
self.handle_table_update(message.table_id, message.entries)
|
||||||
}
|
}
|
||||||
Message::PacketEntities(msg) => {
|
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)
|
.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();
|
let message_type = message.get_message_type();
|
||||||
if T::does_handle(message_type) {
|
if T::does_handle(message_type) {
|
||||||
self.analyser
|
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 {
|
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::message::{Message, MessageType};
|
||||||
|
|
||||||
use crate::demo::parser::handler::MessageHandler;
|
use crate::demo::parser::handler::MessageHandler;
|
||||||
|
|
@ -16,7 +17,7 @@ impl MessageHandler for MessageTypeAnalyser {
|
||||||
true
|
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())
|
self.packet_types.push(message.get_message_type())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::demo::data::DemoTick;
|
||||||
use bitbuffer::{BitError, BitRead, BitWrite, BitWriteStream, LittleEndian};
|
use bitbuffer::{BitError, BitRead, BitWrite, BitWriteStream, LittleEndian};
|
||||||
|
|
||||||
pub use self::messagetypeanalyser::MessageTypeAnalyser;
|
pub use self::messagetypeanalyser::MessageTypeAnalyser;
|
||||||
|
|
@ -208,5 +209,5 @@ impl<'a, A: MessageHandler + BorrowMessageHandler> DemoTicker<'a, A> {
|
||||||
pub struct Tick<'a, State> {
|
pub struct Tick<'a, State> {
|
||||||
pub state: &'a State,
|
pub state: &'a State,
|
||||||
pub parser_state: &'a ParserState,
|
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::packet::stringtable::StringTableEntry;
|
||||||
|
|
||||||
|
use crate::demo::data::DemoTick;
|
||||||
use crate::demo::sendprop::{SendProp, SendPropIdentifier};
|
use crate::demo::sendprop::{SendProp, SendPropIdentifier};
|
||||||
use crate::nullhasher::NullHasherBuilder;
|
use crate::nullhasher::NullHasherBuilder;
|
||||||
use crate::{Result, Stream};
|
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 {
|
match message {
|
||||||
Message::ServerInfo(message) => {
|
Message::ServerInfo(message) => {
|
||||||
self.demo_meta.version = message.version;
|
self.demo_meta.version = message.version;
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
1902
test_data/decal.json
1902
test_data/decal.json
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
|
|
@ -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
|
|
@ -6,6 +6,7 @@ use test_case::test_case;
|
||||||
use fnv::FnvHashMap;
|
use fnv::FnvHashMap;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::{BufRead, BufReader};
|
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::packetentities::{EntityId, PacketEntity, UpdateType};
|
||||||
use tf_demo_parser::demo::message::Message;
|
use tf_demo_parser::demo::message::Message;
|
||||||
use tf_demo_parser::demo::packet::datatable::{
|
use tf_demo_parser::demo::packet::datatable::{
|
||||||
|
|
@ -39,7 +40,7 @@ impl From<UpdateType> for PVSCompat {
|
||||||
#[derive(PartialEq, Clone, Serialize, Deserialize, Debug)]
|
#[derive(PartialEq, Clone, Serialize, Deserialize, Debug)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
struct EntityDump {
|
struct EntityDump {
|
||||||
tick: u32,
|
tick: DemoTick,
|
||||||
server_class: ServerClassName,
|
server_class: ServerClassName,
|
||||||
id: EntityId,
|
id: EntityId,
|
||||||
props: HashMap<String, SendPropValue>,
|
props: HashMap<String, SendPropValue>,
|
||||||
|
|
@ -49,7 +50,7 @@ struct EntityDump {
|
||||||
impl EntityDump {
|
impl EntityDump {
|
||||||
pub fn from_entity(
|
pub fn from_entity(
|
||||||
entity: PacketEntity,
|
entity: PacketEntity,
|
||||||
tick: u32,
|
tick: DemoTick,
|
||||||
classes: &[ServerClass],
|
classes: &[ServerClass],
|
||||||
prop_names: &FnvHashMap<SendPropIdentifier, (SendTableName, SendPropName)>,
|
prop_names: &FnvHashMap<SendPropIdentifier, (SendTableName, SendPropName)>,
|
||||||
state: &ParserState,
|
state: &ParserState,
|
||||||
|
|
@ -71,7 +72,7 @@ impl EntityDump {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EntityDumper {
|
struct EntityDumper {
|
||||||
entities: Vec<(u32, PacketEntity)>,
|
entities: Vec<(DemoTick, PacketEntity)>,
|
||||||
prop_names: FnvHashMap<SendPropIdentifier, (SendTableName, SendPropName)>,
|
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 {
|
match message {
|
||||||
Message::PacketEntities(entity_message) => self.entities.extend(
|
Message::PacketEntities(entity_message) => self.entities.extend(
|
||||||
entity_message
|
entity_message
|
||||||
|
|
|
||||||
|
|
@ -73,5 +73,5 @@ fn setup_message(handler: &mut DemoHandler<NullHandler>, input: &str) {
|
||||||
&handler.state_handler,
|
&handler.state_handler,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
handler.handle_message(message);
|
handler.handle_message(message, 0.into());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 file = fs::read(format!("test_data/{}", input_file)).expect("Unable to read file");
|
||||||
let demo = Demo::new(&file);
|
let demo = Demo::new(&file);
|
||||||
let (_, state) = DemoParser::new(demo.get_stream()).parse().unwrap();
|
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(
|
let expected: MatchState = serde_json::from_slice(
|
||||||
fs::read(format!("test_data/{}", snapshot_file))
|
fs::read(format!("test_data/{}", snapshot_file))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue