mirror of
https://codeberg.org/demostf/parser.git
synced 2026-06-03 10:14:06 +02:00
write TempEntitiesMessage
This commit is contained in:
parent
7fe9fd0fce
commit
34533a9608
3 changed files with 60 additions and 13 deletions
|
|
@ -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),
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue