tf_demo_parser/demo/message/
tempentities.rs1use super::stringtable::read_var_int;
2use crate::demo::message::packetentities::PacketEntitiesMessage;
3use crate::demo::message::stringtable::{encode_var_int_fixed, log_base2};
4use crate::demo::packet::datatable::ClassId;
5use crate::demo::parser::{Encode, ParseBitSkip};
6use crate::demo::sendprop::SendProp;
7use crate::Result;
8use crate::{Parse, ParseError, ParserState, Stream};
9use bitbuffer::{BitWrite, BitWriteSized, BitWriteStream, LittleEndian};
10use serde::{Deserialize, Serialize};
11
12#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
13#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
14pub struct TempEntitiesMessage {
15 pub events: Vec<EventInfo>,
16}
17
18#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
19#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
20pub struct EventInfo {
21 pub class_id: ClassId,
22 pub fire_delay: f32,
23 pub reliable: bool,
24 pub props: Vec<SendProp>,
25}
26
27impl Parse<'_> for TempEntitiesMessage {
28 fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self> {
29 let count: u8 = stream.read()?;
30 let length = if state.protocol_version > 23 {
31 read_var_int(stream)?
32 } else {
33 stream.read_sized(17)?
34 };
35 let data = stream.read_bits(length as usize)?;
36 let mut stream = data.clone();
37 let stream = &mut stream;
38
39 let (count, reliable) = if count == 0 {
40 (1, true)
41 } else {
42 (count, false)
43 };
44
45 let mut events: Vec<EventInfo> = Vec::with_capacity(count as usize);
46
47 for _ in 0..count {
48 let delay = if stream.read()? {
49 let raw: u8 = stream.read()?;
50 raw as f32 / 100.0
51 } else {
52 0.0
53 };
54
55 let class_id = if stream.read()? {
56 let bits = log_base2(state.server_classes.len()) + 1;
57 (stream.read_sized::<u16>(bits as usize)?.saturating_sub(1)).into()
58 } else {
59 let last = events.last().ok_or(ParseError::InvalidDemo(
60 "temp entity update without previous",
61 ))?;
62
63 last.class_id
64 };
65 let send_table = state
66 .send_tables
67 .get(usize::from(class_id))
68 .ok_or(ParseError::UnknownServerClass(class_id))?;
69
70 let mut props = Vec::new();
71 PacketEntitiesMessage::read_update(stream, send_table, &mut props, 0u32.into())?;
72
73 events.push(EventInfo {
74 class_id,
75 fire_delay: delay,
76 reliable,
77 props,
78 });
79 }
80
81 Ok(TempEntitiesMessage { events })
82 }
83}
84
85impl ParseBitSkip<'_> for TempEntitiesMessage {
86 fn parse_skip(stream: &mut Stream, state: &ParserState) -> Result<()> {
87 let _: u8 = stream.read()?;
88 let length = if state.protocol_version > 23 {
89 read_var_int(stream)?
90 } else {
91 stream.read_sized(17)?
92 };
93 stream.skip_bits(length as usize)?;
94 Ok(())
95 }
96}
97
98impl Encode for TempEntitiesMessage {
99 fn encode(&self, stream: &mut BitWriteStream<LittleEndian>, state: &ParserState) -> Result<()> {
100 let count = match (self.events.len(), self.events.first()) {
101 (1, Some(event)) if event.reliable => 0,
102 (1, _) => 1,
103 (len, _) => len as u8,
104 };
105 count.write(stream)?;
106
107 stream.reserve_int::<ParseError, _>(40, |stream| {
108 let start = stream.bit_len();
109 let mut last_class_id = u16::MAX.into();
110
111 for event in self.events.iter() {
112 if event.fire_delay > 0.0 {
113 true.write(stream)?;
114 ((event.fire_delay * 100.0) as u8).write(stream)?;
115 } else {
116 false.write(stream)?;
117 }
118
119 if event.class_id != last_class_id {
120 true.write(stream)?;
121 let bits = log_base2(state.server_classes.len()) + 1;
122 let id: u16 = event.class_id.into();
123 (id + 1).write_sized(stream, bits as usize)?;
124 } else {
125 false.write(stream)?;
126 }
127 last_class_id = event.class_id;
128
129 let send_table = state
130 .send_tables
131 .get(usize::from(event.class_id))
132 .ok_or(ParseError::UnknownServerClass(event.class_id))?;
133 PacketEntitiesMessage::write_update(&event.props, stream, send_table, 0u32.into())?;
134 }
135 let end = stream.bit_len();
136 Ok(encode_var_int_fixed((end - start) as u32))
137 })?;
138 Ok(())
139 }
140}