Start with entity support

This commit is contained in:
Lol3rrr
2024-09-20 23:46:38 +02:00
parent c5237af33b
commit 1bf68e78e4
11 changed files with 2849 additions and 8 deletions

370
src/parser/decoder.rs Normal file
View File

@@ -0,0 +1,370 @@
mod quantizedfloat;
pub use quantizedfloat::{QfMapper, QuantalizedFloat};
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Decoder {
QuantalizedFloatDecoder(u8),
VectorNormalDecoder,
VectorNoscaleDecoder,
VectorFloatCoordDecoder,
Unsigned64Decoder,
CentityHandleDecoder,
NoscaleDecoder,
BooleanDecoder,
StringDecoder,
SignedDecoder,
UnsignedDecoder,
ComponentDecoder,
FloatCoordDecoder,
FloatSimulationTimeDecoder,
Fixed64Decoder,
QanglePitchYawDecoder,
Qangle3Decoder,
QangleVarDecoder,
BaseDecoder,
AmmoDecoder,
QanglePresDecoder,
GameModeRulesDecoder,
}
use Decoder::*;
pub static BASETYPE_DECODERS: phf::Map<&'static str, Decoder> = phf::phf_map! {
"bool" => BooleanDecoder,
"char" => StringDecoder,
"int16" => SignedDecoder,
"int32" => SignedDecoder,
"int64" => SignedDecoder,
"int8" => SignedDecoder,
"uint16" => UnsignedDecoder,
"uint32" => UnsignedDecoder,
"uint8" => UnsignedDecoder,
"color32" => UnsignedDecoder,
"GameTime_t" => NoscaleDecoder,
"CBodyComponent" => ComponentDecoder,
"CGameSceneNodeHandle" => UnsignedDecoder,
"Color" => UnsignedDecoder,
"CPhysicsComponent" => ComponentDecoder,
"CRenderComponent" => ComponentDecoder,
"CUtlString" => StringDecoder,
"CUtlStringToken" => UnsignedDecoder,
"CUtlSymbolLarge" => StringDecoder,
"Quaternion" => NoscaleDecoder,
"CTransform" => NoscaleDecoder,
"HSequence" => Unsigned64Decoder,
"AttachmentHandle_t"=> Unsigned64Decoder,
"CEntityIndex"=> Unsigned64Decoder,
"MoveCollide_t"=> Unsigned64Decoder,
"MoveType_t"=> Unsigned64Decoder,
"RenderMode_t"=> Unsigned64Decoder,
"RenderFx_t"=> Unsigned64Decoder,
"SolidType_t"=> Unsigned64Decoder,
"SurroundingBoundsType_t"=> Unsigned64Decoder,
"ModelConfigHandle_t"=> Unsigned64Decoder,
"NPC_STATE"=> Unsigned64Decoder,
"StanceType_t"=> Unsigned64Decoder,
"AbilityPathType_t"=> Unsigned64Decoder,
"WeaponState_t"=> Unsigned64Decoder,
"DoorState_t"=> Unsigned64Decoder,
"RagdollBlendDirection"=> Unsigned64Decoder,
"BeamType_t"=> Unsigned64Decoder,
"BeamClipStyle_t"=> Unsigned64Decoder,
"EntityDisolveType_t"=> Unsigned64Decoder,
"tablet_skin_state_t" => Unsigned64Decoder,
"CStrongHandle" => Unsigned64Decoder,
"CSWeaponMode" => Unsigned64Decoder,
"ESurvivalSpawnTileState"=> Unsigned64Decoder,
"SpawnStage_t"=> Unsigned64Decoder,
"ESurvivalGameRuleDecision_t"=> Unsigned64Decoder,
"RelativeDamagedDirection_t"=> Unsigned64Decoder,
"CSPlayerState"=> Unsigned64Decoder,
"MedalRank_t"=> Unsigned64Decoder,
"CSPlayerBlockingUseAction_t"=> Unsigned64Decoder,
"MoveMountingAmount_t"=> Unsigned64Decoder,
"QuestProgress::Reason"=> Unsigned64Decoder,
};
pub fn find_decoder(field: &super::sendtables::ConstructorField, qf_map: &mut QfMapper) -> Decoder {
if field.var_name.as_str() == "m_iClip1" {
return Decoder::AmmoDecoder;
}
match BASETYPE_DECODERS.get(field.field_type.base_type.as_str()) {
Some(d) => d.clone(),
None => match field.field_type.base_type.as_str() {
"float32" => float_decoder(field, qf_map),
"Vector" => find_vector_type(3, field, qf_map),
"Vector2D" => find_vector_type(2, field, qf_map),
"Vector4D" => find_vector_type(4, field, qf_map),
"uint64" => find_uint_decoder(field),
"QAngle" => find_qangle_decoder(field),
"CHandle" => Decoder::UnsignedDecoder,
"CNetworkedQuantizedFloat" => float_decoder(field, qf_map),
"CStrongHandle" => find_uint_decoder(field),
"CEntityHandle" => find_uint_decoder(field),
_ => Decoder::UnsignedDecoder,
},
}
}
fn find_qangle_decoder(field: &super::sendtables::ConstructorField) -> Decoder {
match field.var_name.as_str() {
"m_angEyeAngles" => Decoder::QanglePitchYawDecoder,
_ => {
if field.bitcount != 0 {
Decoder::Qangle3Decoder
} else {
Decoder::QangleVarDecoder
}
}
}
}
fn find_uint_decoder(field: &super::sendtables::ConstructorField) -> Decoder {
match field.encoder.as_str() {
"fixed64" => Decoder::Fixed64Decoder,
_ => Decoder::Unsigned64Decoder,
}
}
fn float_decoder(field: &super::sendtables::ConstructorField, qf_map: &mut QfMapper) -> Decoder {
match field.var_name.as_str() {
"m_flSimulationTime" => return Decoder::FloatSimulationTimeDecoder,
"m_flAnimTime" => return Decoder::FloatSimulationTimeDecoder,
_ => {}
};
match field.encoder.as_str() {
"coord" => Decoder::FloatCoordDecoder,
"m_flSimulationTime" => Decoder::FloatSimulationTimeDecoder,
_ => {
if field.bitcount <= 0 || field.bitcount >= 32 {
return Decoder::NoscaleDecoder;
} else {
let qf = QuantalizedFloat::new(
field.bitcount as u32,
Some(field.encode_flags),
Some(field.low_value),
Some(field.high_value),
);
let idx = qf_map.idx;
qf_map.map.insert(idx, qf);
qf_map.idx += 1;
Decoder::QuantalizedFloatDecoder(idx as u8)
}
}
}
}
fn find_vector_type(
dimensions: usize,
field: &super::sendtables::ConstructorField,
qf_map: &mut QfMapper,
) -> Decoder {
if dimensions == 3 && field.encoder.as_str() == "normal" {
return Decoder::VectorNormalDecoder;
}
let float_type = float_decoder(field, qf_map);
match float_type {
Decoder::NoscaleDecoder => Decoder::VectorNoscaleDecoder,
Decoder::FloatCoordDecoder => Decoder::VectorFloatCoordDecoder,
_ => Decoder::VectorNormalDecoder,
}
}
impl Decoder {
pub fn decode(
&self,
bitreader: &mut crate::bitreader::Bitreader,
qf_map: &mut QfMapper,
) -> Result<super::variant::Variant, super::FirstPassError> {
use super::variant::Variant;
match self {
Self::NoscaleDecoder => Ok(Variant::F32(f32::from_bits(bitreader.read_nbits(32)?))),
Self::FloatSimulationTimeDecoder => Ok(Variant::F32(bitreader.decode_simul_time()?)),
Self::UnsignedDecoder => Ok(Variant::U32(bitreader.read_varint()?)),
Self::QuantalizedFloatDecoder(qf_idx) => Ok(bitreader.decode_qfloat(*qf_idx, qf_map)?),
Self::Qangle3Decoder => Ok(Variant::VecXYZ(bitreader.decode_qangle_all_3()?)),
Self::SignedDecoder => Ok(Variant::I32(bitreader.read_varint32()?)),
Self::VectorNoscaleDecoder => Ok(Variant::VecXYZ(bitreader.decode_vector_noscale()?)),
Self::BooleanDecoder => Ok(Variant::Bool(bitreader.read_boolean()?)),
Self::BaseDecoder => Ok(Variant::U32(bitreader.read_varint()?)),
Self::CentityHandleDecoder => Ok(Variant::U32(bitreader.read_varint()?)),
Self::ComponentDecoder => Ok(Variant::Bool(bitreader.read_boolean()?)),
Self::FloatCoordDecoder => Ok(Variant::F32(bitreader.read_bit_coord()?)),
Self::StringDecoder => Ok(Variant::String(bitreader.read_string()?)),
Self::QanglePitchYawDecoder => {
Ok(Variant::VecXYZ(bitreader.decode_qangle_pitch_yaw()?))
}
Self::QangleVarDecoder => Ok(Variant::VecXYZ(bitreader.decode_qangle_variant()?)),
Self::VectorNormalDecoder => Ok(Variant::VecXYZ(bitreader.decode_normal_vec()?)),
Self::Unsigned64Decoder => Ok(Variant::U64(bitreader.read_varint_u_64()?)),
Self::Fixed64Decoder => Ok(Variant::U64(bitreader.decode_uint64()?)),
Self::VectorFloatCoordDecoder => {
Ok(Variant::VecXYZ(bitreader.decode_vector_float_coord()?))
}
Self::AmmoDecoder => Ok(Variant::U32(bitreader.decode_ammo()?)),
Self::QanglePresDecoder => Ok(Variant::VecXYZ(bitreader.decode_qangle_variant_pres()?)),
Self::GameModeRulesDecoder => Ok(Variant::U32(bitreader.read_nbits(7)?)),
}
}
}
impl<'b> crate::bitreader::Bitreader<'b> {
pub fn read_bit_coord_pres(&mut self) -> Result<f32, super::FirstPassError> {
return Ok(self.read_nbits(20)? as f32 * 360.0 / (1 << 20) as f32 - 180.0);
}
pub fn decode_qfloat(
&mut self,
qf_idx: u8,
qf_map: &QfMapper,
) -> Result<super::variant::Variant, super::FirstPassError> {
match qf_map.map.get(&(qf_idx as u32)) {
Some(qf) => Ok(super::variant::Variant::F32(qf.decode(self)?)),
None => panic!(),
}
}
pub fn decode_ammo(&mut self) -> Result<u32, super::FirstPassError> {
let ammo = self.read_varint()?;
if ammo > 0 {
return Ok(ammo - 1);
}
return Ok(ammo);
}
pub fn decode_uint64(&mut self) -> Result<u64, super::FirstPassError> {
let bytes = self.read_n_bytes(8)?;
match bytes.try_into() {
Err(_) => panic!(),
Ok(arr) => Ok(u64::from_ne_bytes(arr)),
}
}
pub fn decode_noscale(&mut self) -> Result<f32, super::FirstPassError> {
Ok(f32::from_le_bytes(self.read_nbits(32)?.to_le_bytes()))
}
pub fn read_string(&mut self) -> Result<String, super::FirstPassError> {
let mut s: Vec<u8> = vec![];
loop {
let c = self.read_nbits(8)? as u8;
if c == 0 {
break;
}
s.push(c);
}
Ok(String::from_utf8_lossy(&s).to_string())
}
pub fn decode_float_coord(&mut self) -> Result<f32, super::FirstPassError> {
Ok(self.read_bit_coord()?)
}
fn decode_simul_time(&mut self) -> Result<f32, super::FirstPassError> {
Ok(self.read_varint()? as f32 * (1.0 / 30.0))
}
pub fn decode_vector_noscale(&mut self) -> Result<[f32; 3], super::FirstPassError> {
let mut v = [0.0; 3];
for idx in 0..3 {
v[idx] = self.decode_noscale()?;
}
Ok(v)
}
pub fn decode_qangle_pitch_yaw(&mut self) -> Result<[f32; 3], super::FirstPassError> {
let mut v = [0.0; 3];
v[0] = self.read_angle(32)?;
v[1] = self.read_angle(32)?;
v[2] = self.read_angle(32)?;
Ok(v)
}
pub fn decode_qangle_all_3(&mut self) -> Result<[f32; 3], super::FirstPassError> {
// Used by aimpunch props (not exposed atm) maybe wrong format? correct number of bits anyhow.
let mut v = [0.0; 3];
v[0] = self.decode_noscale()?;
v[1] = self.decode_noscale()?;
v[2] = self.decode_noscale()?;
Ok(v)
}
pub fn decode_qangle_variant(&mut self) -> Result<[f32; 3], super::FirstPassError> {
let mut v = [0.0; 3];
let has_x = self.read_boolean()?;
let has_y = self.read_boolean()?;
let has_z = self.read_boolean()?;
if has_x {
v[0] = self.read_bit_coord()?;
}
if has_y {
v[1] = self.read_bit_coord()?;
}
if has_z {
v[2] = self.read_bit_coord()?;
}
Ok(v)
}
pub fn read_angle(&mut self, n: usize) -> Result<f32, super::FirstPassError> {
return Ok(self.decode_noscale()? / ((1 << n) as f32));
}
pub fn decode_normal(&mut self) -> Result<f32, super::FirstPassError> {
let is_neg = self.read_boolean()?;
let len = self.read_nbits(11)?;
let result = (len as f64 * (1.0 / ((1 << 11) as f64) - 1.0)) as f32;
match is_neg {
true => Ok(-result),
false => Ok(result),
}
}
pub fn decode_normal_vec(&mut self) -> Result<[f32; 3], super::FirstPassError> {
let mut v = [0.0; 3];
let has_x = self.read_boolean()?;
let has_y = self.read_boolean()?;
if has_x {
v[0] = self.decode_normal()?;
}
if has_y {
v[1] = self.decode_normal()?;
}
let neg_z = self.read_boolean()?;
let prod_sum = v[0] * v[0] + v[1] * v[1];
if prod_sum < 1.0 {
v[2] = (1.0 - prod_sum).sqrt() as f32;
} else {
v[2] = 0.0;
}
if neg_z {
v[2] = -v[2];
}
Ok(v)
}
pub fn decode_vector_float_coord(&mut self) -> Result<[f32; 3], super::FirstPassError> {
let mut v = [0.0; 3];
for idx in 0..3 {
v[idx] = self.decode_float_coord()?;
}
Ok(v)
}
pub fn decode_qangle_variant_pres(&mut self) -> Result<[f32; 3], super::FirstPassError> {
let mut v = [0.0; 3];
let has_x = self.read_boolean()?;
let has_y = self.read_boolean()?;
let has_z = self.read_boolean()?;
if has_x {
v[0] = self.read_bit_coord_pres()?;
}
if has_y {
v[1] = self.read_bit_coord_pres()?;
}
if has_z {
v[2] = self.read_bit_coord_pres()?;
}
Ok(v)
}
}

View File

@@ -0,0 +1,208 @@
use crate::{bitreader::Bitreader, parser::FirstPassError};
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct QuantalizedFloat {
low: f32,
high: f32,
high_low_mul: f32,
dec_mul: f32,
offset: f32,
bit_count: u32,
flags: u32,
no_scale: bool,
}
#[derive(Debug, Clone)]
pub struct QfMapper {
pub idx: u32,
pub map: std::collections::HashMap<u32, QuantalizedFloat>,
}
const QFF_ROUNDDOWN: u32 = 1 << 0;
const QFF_ROUNDUP: u32 = 1 << 1;
const QFF_ENCODE_ZERO: u32 = 1 << 2;
const QFF_ENCODE_INTEGERS: u32 = 1 << 3;
impl QuantalizedFloat {
// More or less directly translated from here:
// https://github.com/dotabuff/manta/blob/09a1d60ef77f68eef84b79e9ca519caf76a1f291/quantizedfloat.go
fn validate_flags(&mut self) {
if self.flags == 0 {
return;
}
if (self.low == 0.0 && (self.flags & QFF_ROUNDDOWN) != 0)
|| (self.high == 0.0 && (self.flags & QFF_ROUNDUP) != 0)
{
self.flags &= !QFF_ENCODE_ZERO;
}
if self.low == 0.0 && (self.flags & QFF_ENCODE_ZERO) != 0 {
self.flags |= QFF_ROUNDDOWN;
self.flags &= !QFF_ENCODE_ZERO;
}
if self.high == 0.0 && (self.flags & QFF_ENCODE_ZERO) != 0 {
self.flags |= QFF_ROUNDUP;
self.flags &= !QFF_ENCODE_ZERO;
}
if self.low > 0.0 || self.high < 0.0 {
self.flags &= !QFF_ENCODE_ZERO;
}
if (self.flags & QFF_ENCODE_INTEGERS) != 0 {
self.flags &= !(QFF_ROUNDUP | QFF_ROUNDDOWN | QFF_ENCODE_ZERO);
}
}
fn assign_multipliers(&mut self, steps: u32) {
self.high_low_mul = 0.0;
let range = self.high - self.low;
let high: u32;
if self.bit_count == 32 {
high = 0xFFFFFFFE;
} else {
high = (1 << self.bit_count) - 1;
}
let mut high_mul: f32;
// Xd?
if range.abs() <= 0.0 {
high_mul = high as f32;
} else {
high_mul = (high as f32) / range;
}
if (high_mul * range > (high as f32))
|| (((high_mul * range) as f64) > ((high as f32) as f64))
{
let multipliers = vec![0.9999, 0.99, 0.9, 0.8, 0.7];
for multiplier in multipliers {
high_mul = (high as f32) / range * multiplier;
if (high_mul * range > (high as f32))
|| (((high_mul * range) as f64) > (high as f32) as f64)
{
continue;
}
break;
}
}
self.high_low_mul = high_mul;
self.dec_mul = 1.0 / (steps - 1) as f32;
}
pub fn quantize(&mut self, val: f32) -> f32 {
if val < self.low {
return self.low;
} else if val > self.high {
return self.high;
}
let i = ((val - self.low) * self.high_low_mul) as u32;
self.low + (self.high - self.low) * ((i as f32) * self.dec_mul)
}
pub fn decode(&self, bitreader: &mut Bitreader) -> Result<f32, FirstPassError> {
if self.flags & QFF_ROUNDDOWN != 0 && bitreader.read_boolean()? {
return Ok(self.low);
}
if self.flags & QFF_ROUNDUP != 0 && bitreader.read_boolean()? {
return Ok(self.high);
}
if self.flags & QFF_ENCODE_ZERO != 0 && bitreader.read_boolean()? {
return Ok(0.0);
}
let bits = bitreader.read_nbits(self.bit_count)?;
Ok(self.low + (self.high - self.low) * bits as f32 * self.dec_mul)
}
pub fn new(
bitcount: u32,
flags: Option<i32>,
low_value: Option<f32>,
high_value: Option<f32>,
) -> Self {
let mut qf = QuantalizedFloat {
no_scale: false,
bit_count: 0,
dec_mul: 0.0,
low: 0.0,
high: 0.0,
high_low_mul: 0.0,
offset: 0.0,
flags: 0,
};
if bitcount == 0 || bitcount >= 32 {
qf.no_scale = true;
qf.bit_count = 32;
return qf;
} else {
qf.no_scale = false;
qf.bit_count = bitcount;
qf.offset = 0.0;
if low_value.is_some() {
qf.low = low_value.unwrap_or(0.0);
} else {
qf.low = 0.0;
}
if high_value.is_some() {
qf.high = high_value.unwrap_or(0.0);
} else {
qf.high = 1.0;
}
}
if flags.is_some() {
qf.flags = flags.unwrap_or(0) as u32;
} else {
qf.flags = 0;
}
qf.validate_flags();
let mut steps = 1 << qf.bit_count;
if (qf.flags & QFF_ROUNDDOWN) != 0 {
let range = qf.high - qf.low;
qf.offset = range / (steps as f32);
qf.high -= qf.offset;
} else if (qf.flags & QFF_ROUNDUP) != 0 {
let range = qf.high - qf.low;
qf.offset = range / (steps as f32);
qf.low += qf.offset;
}
if (qf.flags & QFF_ENCODE_INTEGERS) != 0 {
let mut delta = qf.high - qf.low;
if delta < 1.0 {
delta = 1.0;
}
let delta_log2 = delta.log2().ceil();
let range_2: u32 = 1 << delta_log2 as u32;
let mut bit_count = qf.bit_count;
loop {
if (1 << bit_count) > range_2 {
break;
} else {
bit_count += 1;
}
}
if bit_count > qf.bit_count {
qf.bit_count = bit_count;
steps = 1 << qf.bit_count;
}
qf.offset = range_2 as f32 / steps as f32;
qf.high = qf.low + ((range_2 as f32 - qf.offset) as f32);
}
qf.assign_multipliers(steps);
if (qf.flags & QFF_ROUNDDOWN) != 0 {
if qf.quantize(qf.low) == qf.low {
qf.flags &= !QFF_ROUNDDOWN;
}
}
if (qf.flags & QFF_ROUNDUP) != 0 {
if qf.quantize(qf.high) == qf.high {
qf.flags &= !QFF_ROUNDUP
}
}
if (qf.flags & QFF_ENCODE_ZERO) != 0 {
if qf.quantize(0.0) == 0.0 {
qf.flags &= !QFF_ENCODE_ZERO;
}
}
qf
}
}

411
src/parser/fieldpath.rs Normal file
View File

@@ -0,0 +1,411 @@
#[derive(Debug)]
pub struct Paths(Vec<FieldPath>);
#[derive(Debug, Clone, Copy)]
pub struct FieldPath {
pub path: [i32; 7],
pub last: usize,
}
impl Paths {
pub fn new() -> Self {
Self(Vec::new())
}
pub fn new_path() -> FieldPath {
FieldPath {
path: [-1, 0, 0, 0, 0, 0, 0],
last: 0,
}
}
pub fn write(&mut self, fp: &FieldPath, idx: usize) {
match self.0.get_mut(idx) {
Some(entry) => {
*entry = *fp;
}
None => {
self.0.resize(idx + 1, Self::new_path());
let entry = self.0.get_mut(idx).expect("We just resized the Vec");
*entry = *fp;
}
};
}
pub fn paths(&self) -> impl Iterator<Item = &FieldPath> {
self.0.iter()
}
}
pub fn parse_paths(
bitreader: &mut crate::bitreader::Bitreader,
paths: &mut Paths,
) -> Result<usize, super::FirstPassError> {
let mut path = Paths::new_path();
let mut idx = 0;
loop {
if bitreader.bits_left < 17 {
bitreader.refill();
}
let peeked_bits = bitreader.peek(17);
let (symbol, code_len) = super::HUFFMAN_LOOKUP_TABLE[peeked_bits as usize];
bitreader.consume(code_len as u32);
if symbol == 39 {
break;
}
super::do_op(symbol, bitreader, &mut path)?;
paths.write(&path, idx);
idx += 1;
}
Ok(idx)
}
impl FieldPath {
pub fn pop_special(&mut self, n: usize) -> Result<(), super::FirstPassError> {
for _ in 0..n {
*self.get_entry_mut(self.last)? = 0;
self.last -= 1;
}
Ok(())
}
pub fn get_entry_mut(&mut self, idx: usize) -> Result<&mut i32, super::FirstPassError> {
match self.path.get_mut(idx) {
Some(e) => Ok(e),
None => panic!(),
}
}
pub fn find<'ser>(
&self,
ser: &'ser super::sendtables::Serializer,
) -> Result<&'ser super::sendtables::Field, super::FirstPassError> {
let f = match ser.fields.get(self.path[0] as usize) {
Some(entry) => entry,
None => panic!("Field-Len: {:?} - Path: {:?}", ser.fields.len(), self.path),
};
match self.last {
0 => Ok(f),
1 => Ok(f.get_inner(self.path[1] as usize)?),
2 => Ok(f.get_inner(self.path[1] as usize)?.get_inner(self.path[2] as usize)?),
3 => Ok(f.get_inner(self.path[1] as usize)?.get_inner(self.path[2] as usize)?.get_inner(self.path[3] as usize)?),
other => panic!("{:?}", other),
}
}
}
pub mod ops {
use super::FieldPath;
use crate::{bitreader::Bitreader, parser::FirstPassError};
pub fn plus_one(_bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 1;
Ok(())
}
pub fn plus_two(_bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 2;
Ok(())
}
pub fn plus_three(_bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 3;
Ok(())
}
pub fn plus_four(_bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 4;
Ok(())
}
pub fn plus_n(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32 + 5;
Ok(())
}
pub fn push_one_left_delta_zero_right_zero(_bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = 0;
Ok(())
}
pub fn push_one_left_delta_zero_right_non_zero(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
Ok(())
}
pub fn push_one_left_delta_one_right_zero(_bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 1;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = 0;
Ok(())
}
pub fn push_one_left_delta_one_right_non_zero(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 1;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = bitreader.read_ubit_var_fp()? as i32;
Ok(())
}
pub fn push_one_left_delta_n_right_zero(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = 0;
Ok(())
}
pub fn push_one_left_delta_n_right_non_zero(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32 + 2;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = bitreader.read_ubit_var_fp()? as i32 + 1;
Ok(())
}
pub fn push_one_left_delta_n_right_non_zero_pack6_bits(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += (bitreader.read_nbits(3)? + 2) as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = (bitreader.read_nbits(3)? + 1) as i32;
Ok(())
}
pub fn push_one_left_delta_n_right_non_zero_pack8_bits(
bitreader: &mut Bitreader,
field_path: &mut FieldPath,
) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += (bitreader.read_nbits(4)? + 2) as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = (bitreader.read_nbits(4)? + 1) as i32;
Ok(())
}
pub fn push_two_left_delta_zero(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
Ok(())
}
pub fn push_two_pack5_left_delta_zero(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = bitreader.read_nbits(5)? as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = bitreader.read_nbits(5)? as i32;
Ok(())
}
pub fn push_three_left_delta_zero(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
Ok(())
}
pub fn push_three_pack5_left_delta_zero(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = bitreader.read_nbits(5)? as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = bitreader.read_nbits(5)? as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = bitreader.read_nbits(5)? as i32;
Ok(())
}
pub fn push_two_left_delta_one(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 1;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
Ok(())
}
pub fn push_two_pack5_left_delta_one(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 1;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32;
Ok(())
}
pub fn push_three_left_delta_one(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 1;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
Ok(())
}
pub fn push_three_pack5_left_delta_one(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += 1;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32;
Ok(())
}
pub fn push_two_left_delta_n(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += (bitreader.read_u_bit_var()? + 2) as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
Ok(())
}
pub fn push_two_pack5_left_delta_n(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += (bitreader.read_u_bit_var()? + 2) as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32;
Ok(())
}
pub fn push_three_left_delta_n(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += (bitreader.read_u_bit_var()? + 2) as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
Ok(())
}
pub fn push_three_pack5_left_delta_n(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last)? += (bitreader.read_u_bit_var()? + 2) as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32;
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_nbits(5)? as i32;
Ok(())
}
pub fn push_n(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
let n = bitreader.read_u_bit_var()? as i32;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_u_bit_var()? as i32;
for _ in 0..n {
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32;
}
Ok(())
}
pub fn push_n_and_non_topological(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
for i in 0..field_path.last + 1 {
if bitreader.read_boolean()? {
*field_path.get_entry_mut(i)? += bitreader.read_varint32()? + 1;
}
}
let count = bitreader.read_u_bit_var()?;
for _ in 0..count {
field_path.last += 1;
*field_path.get_entry_mut(field_path.last)? = bitreader.read_ubit_var_fp()? as i32;
}
Ok(())
}
pub fn pop_one_plus_one(_bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
field_path.pop_special(1)?;
*field_path.get_entry_mut(field_path.last)? += 1;
Ok(())
}
pub fn pop_one_plus_n(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
field_path.pop_special(1)?;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_ubit_var_fp()? as i32 + 1;
Ok(())
}
pub fn pop_all_but_one_plus_one(_bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
field_path.pop_special(field_path.last)?;
*field_path.get_entry_mut(0)? += 1;
Ok(())
}
pub fn pop_all_but_one_plus_n(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
field_path.pop_special(field_path.last)?;
*field_path.get_entry_mut(0)? += bitreader.read_ubit_var_fp()? as i32 + 1;
Ok(())
}
pub fn pop_all_but_one_plus_n_pack3_bits(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
field_path.pop_special(field_path.last)?;
*field_path.get_entry_mut(0)? += bitreader.read_nbits(3)? as i32 + 1;
Ok(())
}
pub fn pop_all_but_one_plus_n_pack6_bits(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
field_path.pop_special(field_path.last)?;
*field_path.get_entry_mut(0)? += bitreader.read_nbits(6)? as i32 + 1;
Ok(())
}
pub fn pop_n_plus_one(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
field_path.pop_special(bitreader.read_ubit_var_fp()? as usize)?;
*field_path.get_entry_mut(field_path.last)? += 1;
Ok(())
}
pub fn pop_n_plus_n(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
field_path.pop_special(bitreader.read_ubit_var_fp()? as usize)?;
*field_path.get_entry_mut(field_path.last)? += bitreader.read_varint32()?;
Ok(())
}
pub fn pop_n_and_non_topographical(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
field_path.pop_special(bitreader.read_ubit_var_fp()? as usize)?;
for i in 0..field_path.last + 1 {
if bitreader.read_boolean()? {
*field_path.get_entry_mut(i)? += bitreader.read_varint32()?;
}
}
Ok(())
}
pub fn non_topo_complex(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
for i in 0..field_path.last + 1 {
if bitreader.read_boolean()? {
*field_path.get_entry_mut(i)? += bitreader.read_varint32()?;
}
}
Ok(())
}
pub fn non_topo_penultimate_plus_one(_bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
*field_path.get_entry_mut(field_path.last - 1)? += 1;
Ok(())
}
pub fn non_topo_complex_pack4_bits(bitreader: &mut Bitreader, field_path: &mut FieldPath) -> Result<(), FirstPassError> {
for i in 0..field_path.last + 1 {
if bitreader.read_boolean()? {
*field_path.get_entry_mut(i)? += bitreader.read_nbits(4)? as i32 - 7;
}
}
Ok(())
}
}

1449
src/parser/sendtables.rs Normal file

File diff suppressed because it is too large Load Diff

26
src/parser/variant.rs Normal file
View File

@@ -0,0 +1,26 @@
#[derive(Debug, Clone, PartialEq)]
pub enum Variant {
Bool(bool),
U32(u32),
I32(i32),
I16(i16),
F32(f32),
U64(u64),
U8(u8),
String(String),
VecXY([f32; 2]),
VecXYZ([f32; 3]),
// Todo change to Vec<T>
StringVec(Vec<String>),
U32Vec(Vec<u32>),
U64Vec(Vec<u64>),
Stickers(Vec<Sticker>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct Sticker {
pub name: String,
pub wear: f32,
pub id: u32,
pub x: f32,
pub y: f32,
}