1
0
Fork 0
mirror of https://codeberg.org/demostf/parser.git synced 2026-10-01 08:44:05 +02:00

Add StaticBaseline::reencode

A baseline is packed entity data, only meaningful against the table it
was written with. Anything that edits a send table has to rewrite the
baselines of every class using the changed props.
This commit is contained in:
Peter 2026-09-07 10:09:11 +01:00
commit 03ae55e0f8

View file

@ -70,6 +70,26 @@ impl StaticBaseline {
)?; )?;
Ok(props) Ok(props)
} }
/// Re-encode the baseline from one send table to another.
///
/// Baselines are packed against a specific table, so any edit that changes
/// how a prop encodes leaves them readable at the wrong offsets.
#[cfg(feature = "write")]
pub fn reencode(&self, from: &SendTable, to: &SendTable) -> Result<Stream<'static>> {
use bitbuffer::{BitReadBuffer, BitReadStream, BitWriteStream, LittleEndian};
let props = self.parse(from)?;
let mut bytes = Vec::new();
{
let mut out = BitWriteStream::new(&mut bytes, LittleEndian);
PacketEntitiesMessage::write_update(&props, &mut out, to, 0u32.into())?;
}
Ok(BitReadStream::new(BitReadBuffer::new_owned(
bytes,
LittleEndian,
)))
}
} }
impl ParserState { impl ParserState {
@ -424,3 +444,72 @@ impl From<BaselineEntity> for PacketEntity {
} }
} }
} }
#[test]
#[cfg(feature = "write")]
fn test_static_baseline_reencode() {
use crate::demo::packet::datatable::SendTable;
use crate::demo::sendprop::{SendPropDefinition, SendPropParseDefinition, SendPropValue};
use bitbuffer::{BitReadBuffer, BitReadStream, BitWriteStream, LittleEndian};
fn table(first_prop_bits: u8) -> SendTable {
SendTable {
name: SendTableName::from("table"),
needs_decoder: false,
flattened_props: vec![
SendPropDefinition {
identifier: SendPropIdentifier::new("table", "first"),
parse_definition: SendPropParseDefinition::UnsignedInt {
changes_often: false,
bit_count: first_prop_bits,
},
},
SendPropDefinition {
identifier: SendPropIdentifier::new("table", "second"),
parse_definition: SendPropParseDefinition::UnsignedInt {
changes_often: false,
bit_count: 8,
},
},
],
}
}
let from = table(8);
let to = table(16);
let props = vec![
SendProp {
index: 0,
identifier: SendPropIdentifier::new("table", "first"),
value: SendPropValue::Integer(200),
},
SendProp {
index: 1,
identifier: SendPropIdentifier::new("table", "second"),
value: SendPropValue::Integer(37),
},
];
let mut bytes = Vec::new();
{
let mut out = BitWriteStream::new(&mut bytes, LittleEndian);
PacketEntitiesMessage::write_update(&props, &mut out, &from, 0u32.into()).unwrap();
}
let baseline = StaticBaseline::new(
ClassId::from(0u16),
BitReadStream::new(BitReadBuffer::new_owned(bytes, LittleEndian)),
);
assert_eq!(baseline.parse(&from).unwrap(), props);
// the old blob no longer decodes to the same values
if let Ok(misread) = baseline.parse(&to) {
assert_ne!(misread, props);
}
let fixed = StaticBaseline::new(
ClassId::from(0u16),
baseline.reencode(&from, &to).unwrap(),
);
assert_eq!(fixed.parse(&to).unwrap(), props);
}