1
0
Fork 0
mirror of https://codeberg.org/demostf/parser.git synced 2026-06-03 10:14:06 +02:00

entity fixes and test

This commit is contained in:
Robin Appelman 2019-08-28 12:44:33 +02:00
commit 0df7d0b394
10 changed files with 626 additions and 46 deletions

View file

@ -1,5 +1,6 @@
use bitstream_reader::{BitRead, BitReadSized, LittleEndian};
use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
use crate::demo::message::stringtable::{log_base2, read_var_int};
use crate::demo::packet::datatable::{SendTable, SendTableName, ServerClass};
@ -31,8 +32,9 @@ impl FromStr for EntityId {
}
}
#[derive(BitRead, Clone, Copy, Debug, PartialEq, Eq)]
#[derive(BitRead, Clone, Copy, Debug, PartialEq, Eq, Serialize_repr, Deserialize_repr)]
#[discriminant_bits = 2]
#[repr(u8)]
pub enum PVS {
Preserve = 0,
Leave = 1,

View file

@ -30,10 +30,19 @@ impl From<u16> for ClassId {
}
}
#[derive(BitRead, PartialEq, Eq, Hash, Debug, Serialize, Deserialize, Clone, Display)]
pub struct ServerClassName(Rc<String>);
impl From<String> for ServerClassName {
fn from(value: String) -> Self {
Self(Rc::new(value))
}
}
#[derive(BitRead, Debug, Clone)]
pub struct ServerClass {
pub id: ClassId,
pub name: String,
pub name: ServerClassName,
pub data_table: SendTableName,
}

View file

@ -54,6 +54,7 @@ impl<T: MessageHandler> DemoHandler<T> {
}
}
Packet::Message(packet) | Packet::Sigon(packet) => {
//self.tick = packet.tick;
for message in packet.messages {
match message {
Message::NetTick(message) => self.tick = message.tick,
@ -108,12 +109,13 @@ impl<T: MessageHandler> DemoHandler<T> {
fn handle_message(&mut self, message: Message) {
let message_type = message.get_message_type();
if ParserState::does_handle(message_type) {
self.state_handler.handle_message(message, self.tick);
return;
}
if Analyser::does_handle(message_type) {
if let Some(message) = self.state_handler.handle_message(message, self.tick) {
if T::does_handle(message_type) {
self.analyser.handle_message(message, self.tick);
}
}
} else if T::does_handle(message_type) {
self.analyser.handle_message(message, self.tick);
return;
}
}

View file

@ -107,14 +107,11 @@ impl ParserState {
Self::does_handle(message_type) || (self.analyser_handles)(message_type)
}
}
}
impl MessageHandler for ParserState {
type Output = Self;
fn does_handle(message_type: MessageType) -> bool {
pub fn does_handle(message_type: MessageType) -> bool {
match message_type {
MessageType::ServerInfo
| MessageType::NetTick
| MessageType::GameEventList
| MessageType::CreateStringTable
| MessageType::PacketEntities
@ -123,46 +120,49 @@ impl MessageHandler for ParserState {
}
}
fn handle_message(&mut self, message: Message, _tick: u32) {
pub fn handle_message(&mut self, message: Message, _tick: u32) -> Option<Message> {
match message {
Message::ServerInfo(message) => {
self.demo_meta.version = message.version;
self.demo_meta.game = message.game;
self.demo_meta.interval_per_tick = message.interval_per_tick
self.demo_meta.interval_per_tick = message.interval_per_tick;
None
}
Message::GameEventList(message) => {
self.event_definitions = message.event_list;
None
}
Message::PacketEntities(message) => {
if message.updated_base_line {
let old_index = message.base_line as usize;
Message::PacketEntities(ent_message) => {
if ent_message.updated_base_line {
let old_index = ent_message.base_line as usize;
let new_index = 1 - old_index;
self.instance_baselines.swap(0, 1);
//self.instance_baselines[new_index] = self.instance_baselines[new_index].clone();
for entity in message.entities.iter() {
for entity in ent_message.entities.iter() {
self.instance_baselines[new_index]
.insert(entity.entity_index, entity.props.clone());
}
}
for removed in message.removed_entities.iter() {
for removed in ent_message.removed_entities.iter() {
self.entity_classes.remove(removed);
}
for entity in message.entities.iter() {
for entity in ent_message.entities.iter() {
if entity.pvs == PVS::Delete {
self.entity_classes.remove(&entity.entity_index);
}
self.entity_classes
.insert(entity.entity_index, Rc::clone(&entity.server_class));
}
Some(Message::PacketEntities(ent_message))
}
_ => {}
_ => Some(message),
}
}
fn handle_string_entry(&mut self, table: &String, _index: usize, entry: &StringTableEntry) {
pub fn handle_string_entry(&mut self, table: &String, _index: usize, entry: &StringTableEntry) {
match table.as_str() {
"instancebaseline" => {
if let (Some(extra), Ok(class_id)) = (&entry.extra_data, entry.text().parse()) {
@ -173,8 +173,4 @@ impl MessageHandler for ParserState {
_ => {}
}
}
fn get_output(self, _state: ParserState) -> Self {
self
}
}

View file

@ -1,6 +1,7 @@
use bitstream_reader::{BitRead, LittleEndian};
use enumflags2::BitFlags;
use enumflags2_derive::EnumFlags;
use serde::{Deserialize, Serialize};
use crate::{MalformedDemoError, Parse, ParseError, ReadResult, Result, Stream};
@ -14,7 +15,9 @@ use std::convert::TryInto;
use std::fmt;
use std::rc::Rc;
#[derive(BitRead, PartialEq, Eq, Hash, Debug, Display, Clone)]
#[derive(
BitRead, PartialEq, Eq, Hash, Debug, Display, Clone, Serialize, Deserialize, Ord, PartialOrd,
)]
pub struct SendPropName(Rc<String>);
impl PartialEq<&str> for SendPropName {
@ -287,16 +290,66 @@ impl BitRead<LittleEndian> for SendPropFlags {
}
}
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum SendPropValue {
Vector(Vector),
VectorXY(VectorXY),
Integer(i32),
Integer(i64),
Float(f32),
String(String),
Array(Vec<SendPropValue>),
}
impl PartialEq for SendPropValue {
fn eq(&self, other: &Self) -> bool {
// allow comparing some "compatible" types
match (self, other) {
(SendPropValue::Vector(value1), SendPropValue::Vector(value2)) => value1 == value2,
(SendPropValue::VectorXY(value1), SendPropValue::VectorXY(value2)) => value1 == value2,
(SendPropValue::Integer(value1), SendPropValue::Integer(value2)) => value1 == value2,
(SendPropValue::Float(value1), SendPropValue::Float(value2)) => value1 - value2 < 0.001,
(SendPropValue::String(value1), SendPropValue::String(value2)) => value1 == value2,
(SendPropValue::Array(value1), SendPropValue::Array(value2)) => value1 == value2,
(SendPropValue::Integer(value1), SendPropValue::Float(value2)) => {
*value1 as f64 == *value2 as f64
}
(SendPropValue::Float(value1), SendPropValue::Integer(value2)) => {
*value1 as f64 == *value2 as f64
}
(SendPropValue::Vector(value1), SendPropValue::VectorXY(value2)) => {
value1.x == value2.x && value1.y == value2.y && value1.z == 0.0
}
(SendPropValue::VectorXY(value1), SendPropValue::Vector(value2)) => {
value1.x == value2.x && value1.y == value2.y && value2.z == 0.0
}
(SendPropValue::Vector(value1), SendPropValue::Array(value2)) if value2.len() == 3 => {
SendPropValue::Float(value1.x) == value2[0]
&& SendPropValue::Float(value1.y) == value2[1]
&& SendPropValue::Float(value1.z) == value2[2]
}
(SendPropValue::Array(value1), SendPropValue::Vector(value2)) if value1.len() == 3 => {
SendPropValue::Float(value2.x) == value1[0]
&& SendPropValue::Float(value2.y) == value1[1]
&& SendPropValue::Float(value2.z) == value1[2]
}
(SendPropValue::VectorXY(value1), SendPropValue::Array(value2))
if value2.len() == 2 =>
{
SendPropValue::Float(value1.x) == value2[0]
&& SendPropValue::Float(value1.y) == value2[1]
}
(SendPropValue::Array(value1), SendPropValue::VectorXY(value2))
if value1.len() == 2 =>
{
SendPropValue::Float(value2.x) == value1[0]
&& SendPropValue::Float(value2.y) == value1[1]
}
_ => false,
}
}
}
impl fmt::Display for SendPropValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
@ -331,16 +384,17 @@ impl SendPropValue {
}
}
fn read_int(stream: &mut Stream, definition: &SendPropDefinition) -> Result<i32> {
fn read_int(stream: &mut Stream, definition: &SendPropDefinition) -> Result<i64> {
if definition.flags.contains(SendPropFlag::NormalVarInt) {
read_var_int(stream, !definition.flags.contains(SendPropFlag::Unsigned))
.map_err(ParseError::from)
.map(|int| int as i64)
} else {
if definition.flags.contains(SendPropFlag::Unsigned) {
let unsigned: u32 =
stream.read_sized(definition.bit_count.unwrap_or(32) as usize)?;
const MAX: u32 = std::i32::MAX as u32;
Ok((unsigned & MAX) as i32)
//const MAX: u32 = std::i32::MAX as u32;
Ok(unsigned as i64)
} else {
stream
.read_int(definition.bit_count.unwrap_or(32) as usize)
@ -418,7 +472,8 @@ impl SendPropValue {
.low_value
.ok_or(MalformedSendPropDefinitionError::UnsizedFloat)?;
let raw: u32 = stream.read_int(bit_count as usize)?;
let percentage = (raw as f32) * get_frac_factor(bit_count as usize);
// is this -1 correct?, it is consistent with the js version but seems weird
let percentage = (raw as f32) / ((1 << bit_count) as f32 - 1.0);
Ok(low + ((high - low) * percentage))
}
}
@ -426,6 +481,12 @@ impl SendPropValue {
impl From<i32> for SendPropValue {
fn from(value: i32) -> Self {
SendPropValue::Integer(value as i64)
}
}
impl From<i64> for SendPropValue {
fn from(value: i64) -> Self {
SendPropValue::Integer(value)
}
}

View file

@ -2,9 +2,7 @@ use bitstream_reader::{BitRead, BitSize};
use parse_display::Display;
use serde::{Deserialize, Serialize};
#[derive(
BitRead, BitSize, Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Display,
)]
#[derive(BitRead, BitSize, Debug, Clone, Copy, Default, Serialize, Deserialize, Display)]
#[display("({x}, {y}, {z})")]
pub struct Vector {
pub x: f32,
@ -12,11 +10,21 @@ pub struct Vector {
pub z: f32,
}
#[derive(
BitRead, BitSize, Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Display,
)]
impl PartialEq for Vector {
fn eq(&self, other: &Self) -> bool {
(self.x - other.x < 0.001) && (self.y - other.y < 0.001) && (self.z - other.z < 0.001)
}
}
#[derive(BitRead, BitSize, Debug, Clone, Copy, Default, Serialize, Deserialize, Display)]
#[display("({x}, {y})")]
pub struct VectorXY {
pub x: f32,
pub y: f32,
}
impl PartialEq for VectorXY {
fn eq(&self, other: &Self) -> bool {
(self.x - other.x < 0.001) && (self.y - other.y < 0.001)
}
}