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

write TempEntitiesMessage

This commit is contained in:
Robin Appelman 2021-07-18 21:38:07 +02:00
commit 34533a9608
3 changed files with 60 additions and 13 deletions

View file

@ -92,7 +92,7 @@ pub enum Message<'a> {
EntityMessage(EntityMessage<'a>), EntityMessage(EntityMessage<'a>),
GameEvent(GameEventMessage), GameEvent(GameEventMessage),
PacketEntities(PacketEntitiesMessage), PacketEntities(PacketEntitiesMessage),
TempEntities(TempEntitiesMessage), TempEntities(TempEntitiesMessage<'a>),
PreFetch(PreFetchMessage), PreFetch(PreFetchMessage),
Menu(MenuMessage<'a>), Menu(MenuMessage<'a>),
GameEventList(GameEventListMessage), GameEventList(GameEventListMessage),

View file

@ -1,4 +1,6 @@
use bitbuffer::{BitReadBuffer, BitReadStream, LittleEndian}; use bitbuffer::{
BitReadBuffer, BitReadStream, BitWrite, BitWriteSized, BitWriteStream, LittleEndian,
};
use num_traits::{PrimInt, Unsigned}; use num_traits::{PrimInt, Unsigned};
use snap::raw::{decompress_len, Decoder}; use snap::raw::{decompress_len, Decoder};
@ -303,6 +305,40 @@ pub fn read_var_int(stream: &mut Stream) -> ReadResult<u32> {
Ok(result) Ok(result)
} }
pub fn write_var_int(mut int: u32, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
loop {
let byte: u8 = int as u8 & 0x7F;
byte.write_sized(stream, 7)?;
int >>= 7;
(int > 0).write(stream)?;
if int == 0 {
return Ok(());
}
}
}
#[test]
fn test_var_int_roundtrip() {
fn var_int_roundtrip(int: u32) {
let mut data = Vec::new();
let pos = {
let mut write = BitWriteStream::new(&mut data, LittleEndian);
write_var_int(int, &mut write).unwrap();
write.bit_len()
};
let mut read = BitReadStream::new(BitReadBuffer::new(&data, LittleEndian));
assert_eq!(int, read_var_int(&mut read).unwrap());
assert_eq!(pos, read.pos());
}
var_int_roundtrip(0);
var_int_roundtrip(1);
var_int_roundtrip(10);
var_int_roundtrip(55);
var_int_roundtrip(355);
var_int_roundtrip(12354);
var_int_roundtrip(123125412);
}
pub fn log_base2<T: PrimInt + Unsigned>(num: T) -> u32 { pub fn log_base2<T: PrimInt + Unsigned>(num: T) -> u32 {
// log(0) = inf, but that's a useless result // log(0) = inf, but that's a useless result
// since this would only happen in malformed demos, we just return 0 // since this would only happen in malformed demos, we just return 0

View file

@ -1,30 +1,41 @@
use crate::{Parse, ParseError, ParserState, Result, Stream}; use crate::{ReadResult, Stream};
use super::packetentities::PacketEntity; use super::packetentities::PacketEntity;
use super::stringtable::read_var_int; use super::stringtable::read_var_int;
use crate::demo::parser::ParseBitSkip; use crate::demo::message::stringtable::write_var_int;
use bitbuffer::{BitRead, BitWrite, BitWriteStream, LittleEndian};
#[derive(Debug)] #[derive(Debug)]
pub struct TempEntitiesMessage { pub struct TempEntitiesMessage<'a> {
pub count: u8,
pub data: Stream<'a>,
pub entities: Vec<PacketEntity>, pub entities: Vec<PacketEntity>,
} }
impl Parse<'_> for TempEntitiesMessage { impl<'a> BitRead<'a, LittleEndian> for TempEntitiesMessage<'a> {
fn parse(stream: &mut Stream, _state: &ParserState) -> Result<Self> { fn read(stream: &mut Stream<'a>) -> ReadResult<Self> {
let _count: u8 = stream.read()?; let count: u8 = stream.read()?;
let length = read_var_int(stream)?; let length = read_var_int(stream)?;
let _data = stream.read_bits(length as usize)?; let data = stream.read_bits(length as usize)?;
Ok(TempEntitiesMessage { Ok(TempEntitiesMessage {
count,
data,
entities: Vec::new(), entities: Vec::new(),
}) })
} }
}
impl ParseBitSkip<'_> for TempEntitiesMessage { fn skip(stream: &mut Stream) -> ReadResult<()> {
fn parse_skip(stream: &mut Stream) -> Result<()> {
let _: u8 = stream.read()?; let _: u8 = stream.read()?;
let length = read_var_int(stream)?; let length = read_var_int(stream)?;
stream.skip_bits(length as usize).map_err(ParseError::from) stream.skip_bits(length as usize)
}
}
impl BitWrite<LittleEndian> for TempEntitiesMessage<'_> {
fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
self.count.write(stream)?;
write_var_int(self.data.bit_len() as u32, stream)?;
self.data.write(stream)
} }
} }