1use super::packet::datatable::ParseSendTable;
2use super::vector::{Vector, VectorXY};
3use crate::consthash::ConstFnvHash;
4use crate::demo::message::stringtable::log_base2;
5use crate::demo::packet::datatable::SendTableName;
6use crate::demo::parser::MalformedSendPropDefinitionError;
7use crate::demo::sendprop_gen::get_prop_names;
8use crate::{ParseError, ReadResult, Result, Stream};
9use bitbuffer::{BitRead, BitReadStream, Endianness, LittleEndian};
10#[cfg(feature = "write")]
11use bitbuffer::{BitWrite, BitWriteSized, BitWriteStream};
12use enumflags2::{bitflags, BitFlags};
13#[cfg(feature = "write")]
14use num_traits::Signed;
15use parse_display::Display;
16use serde::de::Error;
17use serde::{Deserialize, Deserializer, Serialize, Serializer};
18use std::borrow::Cow;
19use std::cmp::min;
20use std::convert::{TryFrom, TryInto};
21use std::fmt::{self, Debug, Display, Formatter};
22use std::hash::Hash;
23use std::ops::{BitOr, Deref};
24
25#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
26#[derive(PartialEq, Eq, Hash, Debug, Display, Clone, Serialize, Deserialize, Ord, PartialOrd)]
27#[cfg_attr(feature = "write", derive(BitWrite))]
28pub struct SendPropName(Cow<'static, str>);
29
30impl SendPropName {
31 pub fn as_str(&self) -> &str {
32 self.0.as_ref()
33 }
34}
35
36impl<E: Endianness> BitRead<'_, E> for SendPropName {
37 fn read(stream: &mut BitReadStream<'_, E>) -> bitbuffer::Result<Self> {
38 String::read(stream).map(SendPropName::from)
39 }
40}
41
42impl PartialEq<&str> for SendPropName {
43 fn eq(&self, other: &&str) -> bool {
44 self.as_str() == *other
45 }
46}
47
48impl From<String> for SendPropName {
49 fn from(value: String) -> Self {
50 Self(Cow::Owned(value))
51 }
52}
53
54impl From<&'static str> for SendPropName {
55 fn from(value: &'static str) -> Self {
56 SendPropName(Cow::Borrowed(value))
57 }
58}
59
60impl AsRef<str> for SendPropName {
61 fn as_ref(&self) -> &str {
62 self.0.as_ref()
63 }
64}
65
66impl Deref for SendPropName {
67 type Target = str;
68
69 fn deref(&self) -> &Self::Target {
70 self.0.deref()
71 }
72}
73
74#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
75#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct RawSendPropDefinition {
77 pub prop_type: SendPropType,
78 pub name: SendPropName,
79 pub identifier: SendPropIdentifier,
80 pub flags: SendPropFlags,
81 pub table_name: Option<SendTableName>,
82 pub low_value: Option<f32>,
83 pub high_value: Option<f32>,
84 pub bit_count: Option<u32>,
85 pub element_count: Option<u16>,
86 pub array_property: Option<Box<RawSendPropDefinition>>,
87 pub original_bit_count: Option<u32>,
88}
89
90impl PartialEq for RawSendPropDefinition {
91 fn eq(&self, other: &Self) -> bool {
92 self.identifier() == other.identifier()
93 }
94}
95
96impl fmt::Display for RawSendPropDefinition {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 match self.prop_type {
99 SendPropType::Vector | SendPropType::VectorXY => write!(
100 f,
101 "{}({})(flags: {}, low: {}, high: {}, bits: {})",
102 self.name,
103 self.prop_type,
104 self.flags,
105 self.low_value.unwrap_or_default(),
106 self.high_value.unwrap_or_default(),
107 self.bit_count.unwrap_or(96) / 3
108 ),
109 SendPropType::Float => write!(
110 f,
111 "{}({})(flags: {}, low: {}, high: {}, bits: {})",
112 self.name,
113 self.prop_type,
114 self.flags,
115 self.low_value.unwrap_or_default(),
116 self.high_value.unwrap_or_default(),
117 self.bit_count.unwrap_or(32)
118 ),
119 SendPropType::Int => write!(
120 f,
121 "{}({})(flags: {}, bits: {})",
122 self.name,
123 self.prop_type,
124 self.flags,
125 self.bit_count.unwrap_or(32)
126 ),
127 SendPropType::String => {
128 write!(f, "{}({})", self.name, self.prop_type)
129 }
130 SendPropType::Array => match &self.array_property {
131 Some(array_prop) => write!(
132 f,
133 "{}([{}({})] * {})",
134 self.name,
135 array_prop.prop_type,
136 array_prop.flags,
137 self.element_count.unwrap_or_default(),
138 ),
139 None => write!(f, "{}(Malformed array)", self.name),
140 },
141 SendPropType::DataTable => match &self.table_name {
142 Some(sub_table) => write!(f, "{}(DataTable = {})", self.name, sub_table),
143 None => write!(f, "{}(Malformed DataTable)", self.name),
144 },
145 SendPropType::NumSendPropTypes => {
146 write!(f, "{}(NumSendPropTypes)", self.name)
147 }
148 }
149 }
150}
151
152impl RawSendPropDefinition {
153 pub fn identifier(&self) -> SendPropIdentifier {
154 self.identifier
155 }
156
157 pub fn with_array_property(self, array_property: Self) -> Self {
158 RawSendPropDefinition {
159 prop_type: self.prop_type,
160 identifier: self.identifier,
161 name: self.name,
162 flags: self.flags,
163 table_name: self.table_name,
164 low_value: self.low_value,
165 high_value: self.high_value,
166 bit_count: self.bit_count,
167 element_count: self.element_count,
168 array_property: Some(Box::new(array_property)),
169 original_bit_count: self.original_bit_count,
170 }
171 }
172
173 pub fn get_data_table<'a>(&self, tables: &'a [ParseSendTable]) -> Option<&'a ParseSendTable> {
177 if self.prop_type == SendPropType::DataTable {
178 self.table_name
179 .as_ref()
180 .and_then(|name| tables.iter().find(|table| table.name == *name))
181 } else {
182 None
183 }
184 }
185
186 pub fn read(stream: &mut Stream, owner_table: &SendTableName) -> ReadResult<Self> {
187 let prop_type = SendPropType::read(stream)?;
188 let name: SendPropName = stream.read()?;
189 let identifier = SendPropIdentifier::new(owner_table.as_str(), name.as_str());
190 let flags = SendPropFlags::read(stream)?;
191 let mut table_name = None;
192 let mut element_count = None;
193 let mut low_value = None;
194 let mut high_value = None;
195 let mut bit_count = None;
196 if flags.contains(SendPropFlag::Exclude) || prop_type == SendPropType::DataTable {
197 table_name = Some(stream.read()?);
198 } else if prop_type == SendPropType::Array {
199 element_count = Some(stream.read_int(10)?);
200 } else {
201 low_value = Some(stream.read()?);
202 high_value = Some(stream.read()?);
203 bit_count = Some(stream.read_int(7)?);
204 }
205 let original_bit_count = bit_count;
206
207 if flags.contains(SendPropFlag::NoScale) {
208 if prop_type == SendPropType::Float {
209 bit_count = Some(32);
210 } else if prop_type == SendPropType::Vector
211 && !flags.contains(SendPropFlag::NormalVarInt)
212 {
213 bit_count = Some(32 * 3);
214 }
215 }
216
217 Ok(RawSendPropDefinition {
218 prop_type,
219 name,
220 identifier,
221 flags,
222 table_name,
223 low_value,
224 high_value,
225 bit_count,
226 element_count,
227 original_bit_count,
228 array_property: None,
229 })
230 }
231
232 pub fn is_exclude(&self) -> bool {
233 self.flags.contains(SendPropFlag::Exclude)
234 }
235
236 pub fn get_exclude_table(&self) -> Option<&SendTableName> {
237 if self.is_exclude() {
238 self.table_name.as_ref()
239 } else {
240 None
241 }
242 }
243}
244
245#[cfg(feature = "write")]
246impl BitWrite<LittleEndian> for RawSendPropDefinition {
247 fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
248 self.prop_type.write(stream)?;
249 self.name.write(stream)?;
250 self.flags.write(stream)?;
251
252 if let Some(table_name) = self.table_name.as_ref() {
253 table_name.write(stream)?;
254 }
255 if let Some(element_count) = self.element_count {
256 element_count.write_sized(stream, 10)?;
257 }
258 if let (Some(low_value), Some(high_value), Some(bit_count)) =
259 (self.low_value, self.high_value, self.original_bit_count)
260 {
261 low_value.write(stream)?;
262 high_value.write(stream)?;
263 bit_count.write_sized(stream, 7)?;
264 }
265
266 Ok(())
267 }
268}
269
270#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
271#[derive(BitRead, Copy, Clone, PartialEq, Debug, Display, Serialize, Deserialize)]
272#[cfg_attr(feature = "write", derive(BitWrite))]
273#[discriminant_bits = 5]
274pub enum SendPropType {
275 Int = 0,
276 Float = 1,
277 Vector = 2,
278 VectorXY = 3,
279 String = 4,
280 Array = 5,
281 DataTable = 6,
282 NumSendPropTypes = 7,
283}
284
285#[bitflags]
286#[derive(Copy, Clone, PartialEq, Debug)]
287#[repr(u16)]
288pub enum SendPropFlag {
289 Unsigned = 1,
291 Coord = 2,
294 NoScale = 4,
296 RoundDown = 8,
298 RoundUp = 16,
300 Exclude = 64,
302 XYZE = 128,
304 InsideArray = 256,
307 ProxyAlwaysYes = 512,
310 ChangesOften = 1024,
312 IsVectorElement = 2048,
314 Collapsible = 4096,
319 CoordMP = 8192,
321 CoordMPLowPrecision = 16384,
324 CoordMPIntegral = 32768,
327 NormalVarInt = 32,
328}
329
330#[derive(Debug, Copy, Clone, PartialEq, Default, Serialize, Deserialize)]
331pub struct SendPropFlags(BitFlags<SendPropFlag>);
332
333#[cfg(feature = "schemars")]
334impl schemars::JsonSchema for SendPropFlags {
335 fn schema_name() -> std::borrow::Cow<'static, str> {
336 "SendPropFlags".into()
337 }
338
339 fn json_schema(generator: &mut schemars::SchemaGenerator) -> schemars::Schema {
340 u16::json_schema(generator)
341 }
342}
343
344impl BitOr<SendPropFlag> for SendPropFlags {
345 type Output = SendPropFlags;
346
347 fn bitor(self, rhs: SendPropFlag) -> Self::Output {
348 Self(self.0 | rhs)
349 }
350}
351
352impl fmt::Display for SendPropFlags {
353 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
354 let debug = format!("{:?}", self.0);
355 let flags: String = debug
356 .chars()
357 .skip_while(|c| *c != '[')
358 .take_while(|c| *c != ')')
359 .collect();
360 write!(f, "{flags}")
361 }
362}
363
364impl SendPropFlags {
365 pub fn contains(self, other: SendPropFlag) -> bool {
366 self.0.contains(other)
367 }
368}
369
370impl BitRead<'_, LittleEndian> for SendPropFlags {
371 fn read(stream: &mut Stream) -> ReadResult<Self> {
372 Ok(SendPropFlags(BitFlags::from_bits_truncate(stream.read()?)))
374 }
375
376 fn bit_size() -> Option<usize> {
377 Some(16)
378 }
379}
380
381#[cfg(feature = "write")]
382impl BitWrite<LittleEndian> for SendPropFlags {
383 fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
384 self.0.bits().write(stream)
385 }
386}
387
388#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
389#[derive(Debug, Clone, Serialize, Deserialize)]
390pub enum FloatDefinition {
391 Coord,
392 CoordMP,
393 CoordMPLowPrecision,
394 CoordMPIntegral,
395 FloatNoScale,
396 NormalVarFloat,
397 Scaled { bit_count: u8, high: f32, low: f32 },
398}
399
400impl FloatDefinition {
401 pub fn new(
402 flags: SendPropFlags,
403 bit_count: Option<u32>,
404 high: Option<f32>,
405 low: Option<f32>,
406 ) -> std::result::Result<Self, MalformedSendPropDefinitionError> {
407 if flags.contains(SendPropFlag::Coord) {
408 Ok(FloatDefinition::Coord)
409 } else if flags.contains(SendPropFlag::CoordMP) {
410 Ok(FloatDefinition::CoordMP)
411 } else if flags.contains(SendPropFlag::CoordMPLowPrecision) {
412 Ok(FloatDefinition::CoordMPLowPrecision)
413 } else if flags.contains(SendPropFlag::CoordMPIntegral) {
414 Ok(FloatDefinition::CoordMPIntegral)
415 } else if flags.contains(SendPropFlag::NoScale) {
416 Ok(FloatDefinition::FloatNoScale)
417 } else if flags.contains(SendPropFlag::NormalVarInt) {
418 Ok(FloatDefinition::NormalVarFloat)
419 } else if let (Some(bit_count), Some(high), Some(low)) = (bit_count, high, low) {
420 Ok(FloatDefinition::Scaled {
421 bit_count: bit_count as u8,
422 high,
423 low,
424 })
425 } else {
426 Err(MalformedSendPropDefinitionError::UnsizedFloat)
427 }
428 }
429}
430
431#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
432#[derive(Debug, Clone, Serialize, Deserialize)]
433pub struct SendPropDefinition {
434 pub identifier: SendPropIdentifier,
435 pub parse_definition: SendPropParseDefinition,
436}
437
438impl TryFrom<&RawSendPropDefinition> for SendPropDefinition {
439 type Error = MalformedSendPropDefinitionError;
440
441 fn try_from(definition: &RawSendPropDefinition) -> std::result::Result<Self, Self::Error> {
442 let parse_definition = definition.try_into()?;
443 Ok(SendPropDefinition {
444 parse_definition,
445 identifier: definition.identifier(),
446 })
447 }
448}
449
450#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
451#[derive(Debug, Clone, Serialize, Deserialize)]
452pub enum SendPropParseDefinition {
453 NormalVarInt {
454 changes_often: bool,
455 unsigned: bool,
456 },
457 UnsignedInt {
458 changes_often: bool,
459 bit_count: u8,
460 },
461 Int {
462 changes_often: bool,
463 bit_count: u8,
464 },
465 Float {
466 changes_often: bool,
467 definition: FloatDefinition,
468 },
469 String {
470 changes_often: bool,
471 },
472 Vector {
473 changes_often: bool,
474 definition: FloatDefinition,
475 },
476 VectorXY {
477 changes_often: bool,
478 definition: FloatDefinition,
479 },
480 Array {
481 changes_often: bool,
482 inner_definition: Box<SendPropParseDefinition>,
483 count_bit_count: u16,
484 },
485}
486
487impl SendPropParseDefinition {
488 pub fn changes_often(&self) -> bool {
489 match self {
490 SendPropParseDefinition::NormalVarInt { changes_often, .. } => *changes_often,
491 SendPropParseDefinition::UnsignedInt { changes_often, .. } => *changes_often,
492 SendPropParseDefinition::Int { changes_often, .. } => *changes_often,
493 SendPropParseDefinition::Float { changes_often, .. } => *changes_often,
494 SendPropParseDefinition::String { changes_often, .. } => *changes_often,
495 SendPropParseDefinition::Vector { changes_often, .. } => *changes_often,
496 SendPropParseDefinition::VectorXY { changes_often, .. } => *changes_often,
497 SendPropParseDefinition::Array { changes_often, .. } => *changes_often,
498 }
499 }
500}
501
502impl TryFrom<&RawSendPropDefinition> for SendPropParseDefinition {
503 type Error = MalformedSendPropDefinitionError;
504
505 fn try_from(definition: &RawSendPropDefinition) -> std::result::Result<Self, Self::Error> {
506 let changes_often = definition.flags.contains(SendPropFlag::ChangesOften);
507 match definition.prop_type {
508 SendPropType::Int => {
509 if definition.flags.contains(SendPropFlag::NormalVarInt) {
510 Ok(SendPropParseDefinition::NormalVarInt {
511 changes_often,
512 unsigned: definition.flags.contains(SendPropFlag::Unsigned),
513 })
514 } else if definition.flags.contains(SendPropFlag::Unsigned) {
515 Ok(SendPropParseDefinition::UnsignedInt {
516 changes_often,
517 bit_count: definition.bit_count.unwrap_or(32) as u8,
518 })
519 } else {
520 Ok(SendPropParseDefinition::Int {
521 changes_often,
522 bit_count: definition.bit_count.unwrap_or(32) as u8,
523 })
524 }
525 }
526 SendPropType::Float => Ok(SendPropParseDefinition::Float {
527 changes_often,
528 definition: FloatDefinition::new(
529 definition.flags,
530 definition.bit_count,
531 definition.high_value,
532 definition.low_value,
533 )?,
534 }),
535 SendPropType::String => Ok(SendPropParseDefinition::String { changes_often }),
536 SendPropType::Vector => Ok(SendPropParseDefinition::Vector {
537 changes_often,
538 definition: FloatDefinition::new(
539 definition.flags,
540 definition.bit_count,
541 definition.high_value,
542 definition.low_value,
543 )?,
544 }),
545 SendPropType::VectorXY => Ok(SendPropParseDefinition::VectorXY {
546 changes_often,
547 definition: FloatDefinition::new(
548 definition.flags,
549 definition.bit_count,
550 definition.high_value,
551 definition.low_value,
552 )?,
553 }),
554 SendPropType::Array => {
555 let element_count = definition
556 .element_count
557 .ok_or(MalformedSendPropDefinitionError::UnsizedArray)?;
558 let count_bit_count = log_base2(element_count) as u16 + 1;
559 let child_definition = definition
560 .array_property
561 .as_deref()
562 .ok_or(MalformedSendPropDefinitionError::UntypedArray)?;
563 Ok(SendPropParseDefinition::Array {
564 changes_often,
565 inner_definition: Box::new(SendPropParseDefinition::try_from(
566 child_definition,
567 )?),
568 count_bit_count,
569 })
570 }
571 _ => Err(MalformedSendPropDefinitionError::InvalidPropType),
572 }
573 }
574}
575
576#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
577#[derive(Debug, Clone, Serialize, Deserialize)]
578#[serde(untagged)]
579pub enum SendPropValue {
580 Vector(Vector),
581 VectorXY(VectorXY),
582 Integer(i64),
583 Float(f32),
584 String(String),
585 Array(Vec<SendPropValue>),
586}
587
588impl PartialEq for SendPropValue {
589 fn eq(&self, other: &Self) -> bool {
590 match (self, other) {
592 (SendPropValue::Vector(value1), SendPropValue::Vector(value2)) => value1 == value2,
593 (SendPropValue::VectorXY(value1), SendPropValue::VectorXY(value2)) => value1 == value2,
594 (SendPropValue::Integer(value1), SendPropValue::Integer(value2)) => value1 == value2,
595 (SendPropValue::Float(value1), SendPropValue::Float(value2)) => value1 - value2 < 0.001,
596 (SendPropValue::String(value1), SendPropValue::String(value2)) => value1 == value2,
597 (SendPropValue::Array(value1), SendPropValue::Array(value2)) => value1 == value2,
598 (SendPropValue::Integer(value1), SendPropValue::Float(value2)) => {
599 *value1 as f64 == *value2 as f64
600 }
601 (SendPropValue::Float(value1), SendPropValue::Integer(value2)) => {
602 *value1 as f64 == *value2 as f64
603 }
604 (SendPropValue::Vector(value1), SendPropValue::VectorXY(value2)) => {
605 value1.x == value2.x && value1.y == value2.y && value1.z == 0.0
606 }
607 (SendPropValue::VectorXY(value1), SendPropValue::Vector(value2)) => {
608 value1.x == value2.x && value1.y == value2.y && value2.z == 0.0
609 }
610 (SendPropValue::Vector(value1), SendPropValue::Array(value2)) => {
611 value1 == value2.as_slice()
612 }
613 (SendPropValue::Array(value1), SendPropValue::Vector(value2)) => {
614 value2 == value1.as_slice()
615 }
616 (SendPropValue::VectorXY(value1), SendPropValue::Array(value2)) => {
617 value1 == value2.as_slice()
618 }
619 (SendPropValue::Array(value1), SendPropValue::VectorXY(value2)) => {
620 value2 == value1.as_slice()
621 }
622 _ => false,
623 }
624 }
625}
626
627impl fmt::Display for SendPropValue {
628 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
629 match self {
630 SendPropValue::Vector(vector) => Display::fmt(vector, f),
631 SendPropValue::VectorXY(vector) => Display::fmt(vector, f),
632 SendPropValue::Integer(int) => Display::fmt(int, f),
633 SendPropValue::Float(float) => Display::fmt(float, f),
634 SendPropValue::String(string) => Display::fmt(string, f),
635 SendPropValue::Array(array) => {
636 write!(f, "[")?;
637 for child in array {
638 write!(f, "{child}")?;
639 }
640 write!(f, "]")
641 }
642 }
643 }
644}
645
646fn float_scale(bit_count: u8) -> f32 {
647 (1i32.wrapping_shl(bit_count as u32)) as f32 - 1.0
649}
650
651impl SendPropValue {
652 pub fn parse(stream: &mut Stream, definition: &SendPropParseDefinition) -> Result<Self> {
653 match definition {
654 SendPropParseDefinition::NormalVarInt { unsigned, .. } => {
655 read_var_int(stream, !*unsigned)
656 .map_err(ParseError::from)
657 .map(|int| {
658 if *unsigned {
659 int as u32 as i64
660 } else {
661 int as i64
662 }
663 })
664 .map(SendPropValue::from)
665 }
666 SendPropParseDefinition::UnsignedInt { bit_count, .. } => {
667 Ok((stream.read_sized::<u32>(*bit_count as usize)? as i64).into())
668 }
669 SendPropParseDefinition::Int { bit_count, .. } => stream
670 .read_int::<i32>((*bit_count) as usize)
671 .map_err(ParseError::from)
672 .map(SendPropValue::from),
673 SendPropParseDefinition::Float {
674 definition: float_definition,
675 ..
676 } => Self::read_float(stream, float_definition).map(SendPropValue::from),
677 SendPropParseDefinition::String { .. } => {
678 let length = stream.read_int(9)?;
679 stream
680 .read_sized::<String>(length)
681 .map_err(ParseError::from)
682 .map(SendPropValue::from)
683 }
684 SendPropParseDefinition::Vector {
685 definition: float_definition,
686 ..
687 } => {
688 let x = Self::read_float(stream, float_definition)?;
689 let y = Self::read_float(stream, float_definition)?;
690 let z = match float_definition {
691 FloatDefinition::NormalVarFloat => {
692 let is_negative = stream.read()?;
693 let x2y2 = x * x + y * y;
694 let z = if x2y2 < 1.0f32 {
695 f32::sqrt(1.0f32 - x2y2)
696 } else {
697 0.0f32
698 };
699
700 if is_negative {
701 -z
702 } else {
703 z
704 }
705 }
706 _ => Self::read_float(stream, float_definition)?,
707 };
708
709 Ok(Vector { x, y, z }.into())
710 }
711 SendPropParseDefinition::VectorXY {
712 definition: float_definition,
713 ..
714 } => Ok(VectorXY {
715 x: Self::read_float(stream, float_definition)?,
716 y: Self::read_float(stream, float_definition)?,
717 }
718 .into()),
719 SendPropParseDefinition::Array {
720 count_bit_count,
721 inner_definition,
722 ..
723 } => {
724 let count = stream.read_int(*count_bit_count as usize)?;
725 let mut values = Vec::with_capacity(min(count, 128));
726
727 for _ in 0..count {
728 values.push(Self::parse(stream, inner_definition)?);
729 }
730
731 Ok(values.into())
732 }
733 }
734 }
735
736 #[cfg(feature = "write")]
737 pub fn encode(
738 &self,
739 stream: &mut BitWriteStream<LittleEndian>,
740 definition: &SendPropParseDefinition,
741 ) -> Result<()> {
742 match definition {
743 SendPropParseDefinition::NormalVarInt { unsigned, .. } => {
744 let val: i64 = self.try_into()?;
745 write_var_int(val as i32, stream, !*unsigned)?;
746 Ok(())
747 }
748 SendPropParseDefinition::UnsignedInt { bit_count, .. } => {
749 let val: i64 = self.try_into()?;
750 (val as u32).write_sized(stream, *bit_count as usize)?;
751 Ok(())
752 }
753 SendPropParseDefinition::Int { bit_count, .. } => {
754 let val: i64 = self.try_into()?;
755 (val as i32).write_sized(stream, *bit_count as usize)?;
756 Ok(())
757 }
758 SendPropParseDefinition::Float {
759 definition: float_definition,
760 ..
761 } => {
762 let val: f32 = self.try_into()?;
763 Self::write_float(val, stream, float_definition)
764 }
765 SendPropParseDefinition::String { .. } => {
766 let val: &str = self.try_into()?;
767 (val.len() as u16).write_sized(stream, 9)?;
768 val.write_sized(stream, val.len())?;
769 Ok(())
770 }
771 SendPropParseDefinition::Vector {
772 definition: float_definition,
773 ..
774 } => {
775 let val: Vector = self.try_into()?;
776 Self::write_float(val.x, stream, float_definition)?;
777 Self::write_float(val.y, stream, float_definition)?;
778 match float_definition {
779 FloatDefinition::NormalVarFloat => stream.write_bool(val.z.is_negative())?,
780 _ => Self::write_float(val.z, stream, float_definition)?,
781 }
782 Ok(())
783 }
784 SendPropParseDefinition::VectorXY {
785 definition: float_definition,
786 ..
787 } => {
788 let val: VectorXY = self.try_into()?;
789 Self::write_float(val.x, stream, float_definition)?;
790 Self::write_float(val.y, stream, float_definition)?;
791 Ok(())
792 }
793 SendPropParseDefinition::Array {
794 count_bit_count,
795 inner_definition,
796 ..
797 } => {
798 let array: &[SendPropValue] = self.try_into()?;
799 (array.len() as u16).write_sized(stream, *count_bit_count as usize)?;
800
801 for inner in array {
802 inner.encode(stream, inner_definition)?
803 }
804
805 Ok(())
806 }
807 }
808 }
809
810 fn read_float(stream: &mut Stream, definition: &FloatDefinition) -> Result<f32> {
811 match definition {
812 FloatDefinition::Coord => read_bit_coord(stream).map_err(ParseError::from),
813 FloatDefinition::CoordMP => {
814 read_bit_coord_mp(stream, false, false).map_err(ParseError::from)
815 }
816 FloatDefinition::CoordMPLowPrecision => {
817 read_bit_coord_mp(stream, false, true).map_err(ParseError::from)
818 }
819 FloatDefinition::CoordMPIntegral => {
820 read_bit_coord_mp(stream, true, false).map_err(ParseError::from)
821 }
822 FloatDefinition::FloatNoScale => stream.read().map_err(ParseError::from),
823 FloatDefinition::NormalVarFloat => read_bit_normal(stream).map_err(ParseError::from),
824 FloatDefinition::Scaled {
825 bit_count,
826 low,
827 high,
828 } => {
829 let raw: u32 = stream.read_int(*bit_count as usize)?;
830 let scale = float_scale(*bit_count);
831 let percentage = (raw as f32) / scale;
832 Ok(low + ((high - low) * percentage))
833 }
834 }
835 }
836
837 #[cfg(feature = "write")]
838 fn write_float(
839 val: f32,
840 stream: &mut BitWriteStream<LittleEndian>,
841 definition: &FloatDefinition,
842 ) -> Result<()> {
843 match definition {
844 FloatDefinition::Coord => write_bit_coord(val, stream).map_err(ParseError::from),
845 FloatDefinition::CoordMP => {
846 write_bit_coord_mp(val, stream, false, false).map_err(ParseError::from)
847 }
848 FloatDefinition::CoordMPLowPrecision => {
849 write_bit_coord_mp(val, stream, false, true).map_err(ParseError::from)
850 }
851 FloatDefinition::CoordMPIntegral => {
852 write_bit_coord_mp(val, stream, true, false).map_err(ParseError::from)
853 }
854 FloatDefinition::FloatNoScale => val.write(stream).map_err(ParseError::from),
855 FloatDefinition::NormalVarFloat => {
856 write_bit_normal(val, stream).map_err(ParseError::from)
857 }
858 FloatDefinition::Scaled {
859 bit_count,
860 low,
861 high,
862 } => {
863 let percentage = (val - low) / (high - low);
864 let scale = float_scale(*bit_count);
865 let raw = (percentage * scale).round() as u32;
866 raw.write_sized(stream, *bit_count as usize)?;
867
868 Ok(())
869 }
870 }
871 }
872}
873
874#[test]
875#[cfg(feature = "write")]
876fn test_send_prop_value_roundtrip() {
877 use bitbuffer::{BitReadBuffer, BitReadStream};
878
879 fn send_prop_value_roundtrip(val: SendPropValue, def: SendPropParseDefinition) {
880 let mut data = Vec::new();
881 let pos = {
882 let mut write = BitWriteStream::new(&mut data, LittleEndian);
883 val.encode(&mut write, &def).unwrap();
884 write.bit_len()
885 };
886 let mut read = BitReadStream::new(BitReadBuffer::new(&data, LittleEndian));
887 assert_eq!(val, SendPropValue::parse(&mut read, &def).unwrap());
888 assert_eq!(pos, read.pos());
889 }
890 send_prop_value_roundtrip(
891 SendPropValue::Integer(0),
892 SendPropParseDefinition::UnsignedInt {
893 changes_often: false,
894 bit_count: 5,
895 },
896 );
897 send_prop_value_roundtrip(
898 SendPropValue::Integer(12),
899 SendPropParseDefinition::NormalVarInt {
900 changes_often: false,
901 unsigned: false,
902 },
903 );
904 send_prop_value_roundtrip(
905 SendPropValue::Integer(12),
906 SendPropParseDefinition::NormalVarInt {
907 changes_often: false,
908 unsigned: false,
909 },
910 );
911 send_prop_value_roundtrip(
912 SendPropValue::Integer(-12),
913 SendPropParseDefinition::NormalVarInt {
914 changes_often: false,
915 unsigned: false,
916 },
917 );
918 send_prop_value_roundtrip(
919 SendPropValue::String("foobar".into()),
920 SendPropParseDefinition::String {
921 changes_often: false,
922 },
923 );
924 send_prop_value_roundtrip(
925 SendPropValue::Vector(Vector {
926 x: 1.0,
927 y: 0.0,
928 z: 1.125,
929 }),
930 SendPropParseDefinition::Vector {
931 changes_often: false,
932 definition: FloatDefinition::Coord,
933 },
934 );
935 send_prop_value_roundtrip(
936 SendPropValue::Vector(Vector {
937 x: 0.0,
938 y: 0.0,
939 z: -1.0,
940 }),
941 SendPropParseDefinition::Vector {
942 changes_often: false,
943 definition: FloatDefinition::NormalVarFloat,
944 },
945 );
946 send_prop_value_roundtrip(
947 SendPropValue::VectorXY(VectorXY { x: 1.0, y: 0.0 }),
948 SendPropParseDefinition::VectorXY {
949 changes_often: false,
950 definition: FloatDefinition::FloatNoScale,
951 },
952 );
953 send_prop_value_roundtrip(
954 SendPropValue::Float(12.5),
955 SendPropParseDefinition::Float {
956 changes_often: false,
957 definition: FloatDefinition::CoordMP,
958 },
959 );
960 send_prop_value_roundtrip(
961 SendPropValue::Float(12.0),
962 SendPropParseDefinition::Float {
963 changes_often: false,
964 definition: FloatDefinition::CoordMPIntegral,
965 },
966 );
967 send_prop_value_roundtrip(
968 SendPropValue::Float(12.5),
969 SendPropParseDefinition::Float {
970 changes_often: false,
971 definition: FloatDefinition::CoordMPLowPrecision,
972 },
973 );
974 send_prop_value_roundtrip(
975 SendPropValue::Float(12.498169),
976 SendPropParseDefinition::Float {
977 changes_often: false,
978 definition: FloatDefinition::Scaled {
979 bit_count: 12,
980 high: 25.0,
981 low: 10.0,
982 },
983 },
984 );
985 send_prop_value_roundtrip(
986 SendPropValue::Array(vec![
987 SendPropValue::Integer(0),
988 SendPropValue::Integer(1),
989 SendPropValue::Integer(2),
990 ]),
991 SendPropParseDefinition::Array {
992 changes_often: false,
993 inner_definition: Box::new(SendPropParseDefinition::UnsignedInt {
994 changes_often: false,
995 bit_count: 3,
996 }),
997 count_bit_count: 5,
998 },
999 );
1000
1001 send_prop_value_roundtrip(
1002 SendPropValue::Float(76.22549),
1003 SendPropParseDefinition::Float {
1004 changes_often: false,
1005 definition: FloatDefinition::Scaled {
1006 bit_count: 10,
1007 high: 102.3,
1008 low: 0.09990235,
1009 },
1010 },
1011 );
1012 send_prop_value_roundtrip(
1013 SendPropValue::Vector(Vector {
1014 x: 1.0,
1015 y: -25.96875,
1016 z: 0.1875,
1017 }),
1018 SendPropParseDefinition::Vector {
1019 changes_often: false,
1020 definition: FloatDefinition::CoordMP,
1021 },
1022 );
1023 send_prop_value_roundtrip(
1024 SendPropValue::Integer(-1),
1025 SendPropParseDefinition::NormalVarInt {
1026 changes_often: false,
1027 unsigned: false,
1028 },
1029 );
1030}
1031
1032#[test]
1033#[cfg(feature = "write")]
1034fn test_encode_vector_normal_var_float() {
1035 use bitbuffer::BitWriteStream;
1036
1037 let vector = SendPropValue::Vector(Vector {
1038 x: 0.0f32,
1039 y: 0.0f32,
1040 z: -1.0f32,
1041 });
1042 let def = SendPropParseDefinition::Vector {
1043 changes_often: false,
1044 definition: FloatDefinition::NormalVarFloat,
1045 };
1046
1047 let mut data = Vec::new();
1048 let pos = {
1049 let mut write = BitWriteStream::new(&mut data, LittleEndian);
1050 vector.encode(&mut write, &def).unwrap();
1051 write.bit_len()
1052 };
1053
1054 assert_eq!(pos, 25);
1055 assert_eq!(data, vec![0, 0, 0, 1]);
1056}
1057
1058impl From<i32> for SendPropValue {
1059 fn from(value: i32) -> Self {
1060 SendPropValue::Integer(value as i64)
1061 }
1062}
1063
1064impl From<i64> for SendPropValue {
1065 fn from(value: i64) -> Self {
1066 SendPropValue::Integer(value)
1067 }
1068}
1069
1070impl From<Vector> for SendPropValue {
1071 fn from(value: Vector) -> Self {
1072 SendPropValue::Vector(value)
1073 }
1074}
1075
1076impl From<VectorXY> for SendPropValue {
1077 fn from(value: VectorXY) -> Self {
1078 SendPropValue::VectorXY(value)
1079 }
1080}
1081
1082impl From<f32> for SendPropValue {
1083 fn from(value: f32) -> Self {
1084 SendPropValue::Float(value)
1085 }
1086}
1087
1088impl From<String> for SendPropValue {
1089 fn from(value: String) -> Self {
1090 SendPropValue::String(value)
1091 }
1092}
1093
1094impl From<Vec<SendPropValue>> for SendPropValue {
1095 fn from(value: Vec<SendPropValue>) -> Self {
1096 SendPropValue::Array(value)
1097 }
1098}
1099
1100impl TryFrom<&SendPropValue> for i64 {
1101 type Error = MalformedSendPropDefinitionError;
1102 fn try_from(value: &SendPropValue) -> std::result::Result<Self, Self::Error> {
1103 match value {
1104 SendPropValue::Integer(val) => Ok(*val),
1105 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1106 expected: "integer",
1107 value: value.clone(),
1108 }),
1109 }
1110 }
1111}
1112
1113impl TryFrom<&SendPropValue> for bool {
1114 type Error = MalformedSendPropDefinitionError;
1115 fn try_from(value: &SendPropValue) -> std::result::Result<Self, Self::Error> {
1116 match value {
1117 SendPropValue::Integer(val) => Ok(*val > 0),
1118 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1119 expected: "boolean",
1120 value: value.clone(),
1121 }),
1122 }
1123 }
1124}
1125
1126impl TryFrom<&SendPropValue> for Vector {
1127 type Error = MalformedSendPropDefinitionError;
1128 fn try_from(value: &SendPropValue) -> std::result::Result<Self, Self::Error> {
1129 match value {
1130 SendPropValue::Vector(val) => Ok(*val),
1131 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1132 expected: "vector",
1133 value: value.clone(),
1134 }),
1135 }
1136 }
1137}
1138
1139impl TryFrom<&SendPropValue> for VectorXY {
1140 type Error = MalformedSendPropDefinitionError;
1141 fn try_from(value: &SendPropValue) -> std::result::Result<Self, Self::Error> {
1142 match value {
1143 SendPropValue::VectorXY(val) => Ok(*val),
1144 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1145 expected: "vectorxy",
1146 value: value.clone(),
1147 }),
1148 }
1149 }
1150}
1151
1152impl TryFrom<&SendPropValue> for f32 {
1153 type Error = MalformedSendPropDefinitionError;
1154 fn try_from(value: &SendPropValue) -> std::result::Result<Self, Self::Error> {
1155 match value {
1156 SendPropValue::Float(val) => Ok(*val),
1157 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1158 expected: "float",
1159 value: value.clone(),
1160 }),
1161 }
1162 }
1163}
1164
1165impl<'a> TryFrom<&'a SendPropValue> for &'a str {
1166 type Error = MalformedSendPropDefinitionError;
1167 fn try_from(value: &'a SendPropValue) -> std::result::Result<Self, Self::Error> {
1168 match value {
1169 SendPropValue::String(val) => Ok(val.as_str()),
1170 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1171 expected: "string",
1172 value: value.clone(),
1173 }),
1174 }
1175 }
1176}
1177
1178impl<'a> TryFrom<&'a SendPropValue> for &'a [SendPropValue] {
1179 type Error = MalformedSendPropDefinitionError;
1180 fn try_from(value: &'a SendPropValue) -> std::result::Result<Self, Self::Error> {
1181 match value {
1182 SendPropValue::Array(val) => Ok(val.as_slice()),
1183 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1184 expected: "array",
1185 value: value.clone(),
1186 }),
1187 }
1188 }
1189}
1190
1191#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
1192pub struct SendPropIdentifier(u64);
1193
1194impl SendPropIdentifier {
1195 pub const fn new(table: &str, prop: &str) -> Self {
1196 let hasher = ConstFnvHash::new().push_string(table).push_string(prop);
1197 SendPropIdentifier(hasher.finish())
1198 }
1199
1200 pub const fn from_const(raw: u64) -> Self {
1203 SendPropIdentifier(raw)
1204 }
1205
1206 pub fn table_name(&self) -> Option<SendTableName> {
1210 get_prop_names(*self).map(|(table, _)| table.into())
1211 }
1212
1213 pub fn prop_name(&self) -> Option<SendPropName> {
1217 get_prop_names(*self).map(|(_, prop)| prop.into())
1218 }
1219
1220 pub fn names(&self) -> Option<(SendTableName, SendPropName)> {
1224 get_prop_names(*self).map(|(table, prop)| (table.into(), prop.into()))
1225 }
1226}
1227
1228impl From<u64> for SendPropIdentifier {
1229 fn from(raw: u64) -> Self {
1230 SendPropIdentifier(raw)
1231 }
1232}
1233
1234impl From<SendPropIdentifier> for u64 {
1235 fn from(identifier: SendPropIdentifier) -> Self {
1236 identifier.0
1237 }
1238}
1239
1240impl Display for SendPropIdentifier {
1241 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1242 match get_prop_names(*self) {
1243 Some((table, prop)) => write!(f, "{table}.{prop}"),
1244 None => write!(f, "Prop name {} not known", self.0),
1245 }
1246 }
1247}
1248
1249impl<'de> Deserialize<'de> for SendPropIdentifier {
1250 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
1251 where
1252 D: Deserializer<'de>,
1253 {
1254 #[derive(Deserialize)]
1255 #[serde(untagged)]
1256 enum Options<'a> {
1257 Num(u64),
1258 Str(Cow<'a, str>),
1259 }
1260
1261 let raw = Options::deserialize(deserializer)?;
1262 Ok(match raw {
1263 Options::Num(num) => SendPropIdentifier(num),
1264 Options::Str(s) => {
1265 let num: u64 = s.parse().map_err(D::Error::custom)?;
1266 SendPropIdentifier(num)
1267 }
1268 })
1269 }
1270}
1271
1272impl Serialize for SendPropIdentifier {
1273 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
1274 where
1275 S: Serializer,
1276 {
1277 self.0.to_string().serialize(serializer)
1278 }
1279}
1280
1281#[cfg(feature = "schema")]
1282impl schemars::JsonSchema for SendPropIdentifier {
1283 fn schema_name() -> std::borrow::Cow<'static, str> {
1284 "SendPropIdentifier".into()
1285 }
1286
1287 fn json_schema(generator: &mut schemars::SchemaGenerator) -> schemars::Schema {
1288 <String as schemars::JsonSchema>::json_schema(generator)
1289 }
1290}
1291
1292#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
1293#[derive(Clone, Display, PartialEq, Serialize, Deserialize)]
1294#[display("{index} = {value}")]
1295pub struct SendProp {
1296 pub index: u32,
1297 pub identifier: SendPropIdentifier,
1298 pub value: SendPropValue,
1299}
1300
1301impl Debug for SendProp {
1302 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1303 write!(f, "{} = {}", self.identifier, self.value)
1304 }
1305}
1306
1307pub fn read_var_int(stream: &mut Stream, signed: bool) -> ReadResult<i32> {
1308 let abs_int = crate::demo::message::stringtable::read_var_int(stream)? as i32;
1309
1310 if signed {
1311 Ok((abs_int >> 1) ^ -(abs_int & 1))
1312 } else {
1313 Ok(abs_int)
1314 }
1315}
1316
1317#[cfg(feature = "write")]
1318pub fn write_var_int(
1319 int: i32,
1320 stream: &mut BitWriteStream<LittleEndian>,
1321 signed: bool,
1322) -> ReadResult<()> {
1323 let abs = if signed {
1324 let int = (int << 1) ^ (int >> 31);
1325 u32::from_le_bytes(int.to_le_bytes())
1326 } else {
1327 int as u32
1328 };
1329
1330 crate::demo::message::stringtable::write_var_int(abs, stream)
1331}
1332
1333#[test]
1334#[cfg(feature = "write")]
1335fn test_var_int_roundtrip() {
1336 use bitbuffer::{BitReadBuffer, BitReadStream};
1337
1338 fn var_int_roundtrip(int: i32, signed: bool) {
1339 let mut data = Vec::new();
1340 let pos = {
1341 let mut write = BitWriteStream::new(&mut data, LittleEndian);
1342 write_var_int(int, &mut write, signed).unwrap();
1343 write.bit_len()
1344 };
1345 let mut read = BitReadStream::new(BitReadBuffer::new(&data, LittleEndian));
1346 assert_eq!(int, read_var_int(&mut read, signed).unwrap());
1347 assert_eq!(pos, read.pos());
1348 }
1349 var_int_roundtrip(0, false);
1350 var_int_roundtrip(1, false);
1351 var_int_roundtrip(10, false);
1352 var_int_roundtrip(55, false);
1353 var_int_roundtrip(355, false);
1354 var_int_roundtrip(12354, false);
1355 var_int_roundtrip(123125412, false);
1356
1357 var_int_roundtrip(0, true);
1358 var_int_roundtrip(1, true);
1359 var_int_roundtrip(10, true);
1360 var_int_roundtrip(55, true);
1361 var_int_roundtrip(355, true);
1362 var_int_roundtrip(12354, true);
1363 var_int_roundtrip(123125412, true);
1364 var_int_roundtrip(-0, true);
1365 var_int_roundtrip(-1, true);
1366 var_int_roundtrip(-10, true);
1367 var_int_roundtrip(-55, true);
1368 var_int_roundtrip(-355, true);
1369 var_int_roundtrip(-12354, true);
1370 var_int_roundtrip(-123125412, true);
1371}
1372
1373pub fn read_bit_coord(stream: &mut Stream) -> ReadResult<f32> {
1374 let has_int = stream.read()?;
1375 let has_frac = stream.read()?;
1376
1377 Ok(if has_int || has_frac {
1378 let sign = if stream.read()? { -1f32 } else { 1f32 };
1379 let int_val: u16 = if has_int {
1380 stream.read_sized::<u16>(14)? + 1
1381 } else {
1382 0
1383 };
1384 let frac_val: u8 = if has_frac { stream.read_sized(5)? } else { 0 };
1385 let value = int_val as f32 + (frac_val as f32 * get_frac_factor(5));
1386 value * sign
1387 } else {
1388 0f32
1389 })
1390}
1391
1392#[cfg(feature = "write")]
1393pub fn write_bit_coord(val: f32, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
1394 let has_int = val.abs() >= 1.0;
1395 has_int.write(stream)?;
1396 let has_frac = val.fract() != 0.0;
1397 has_frac.write(stream)?;
1398
1399 if has_frac || has_int {
1400 let sign = val.is_negative();
1401 sign.write(stream)?;
1402 }
1403 let abs = val.abs();
1404 if has_int {
1405 (abs as u16 - 1).write_sized(stream, 14)?;
1406 }
1407 if has_frac {
1408 let frac_val = (abs.fract() / get_frac_factor(5)) as u8;
1409 frac_val.write_sized(stream, 5)?;
1410 }
1411 Ok(())
1412}
1413
1414#[test]
1415#[cfg(feature = "write")]
1416fn bit_coord_roundtrip() {
1417 use bitbuffer::BitReadBuffer;
1418
1419 let mut data = Vec::with_capacity(16);
1420 let (pos1, pos2, pos3, pos4) = {
1421 let mut write = BitWriteStream::new(&mut data, LittleEndian);
1422 write_bit_coord(0.0, &mut write).unwrap();
1423 let pos1 = write.bit_len();
1424 write_bit_coord(123.0, &mut write).unwrap();
1425 let pos2 = write.bit_len();
1426 write_bit_coord(123.4375, &mut write).unwrap();
1427 let pos3 = write.bit_len();
1428 write_bit_coord(-0.4375, &mut write).unwrap();
1429 let pos4 = write.bit_len();
1430 (pos1, pos2, pos3, pos4)
1431 };
1432
1433 let mut read = Stream::from(BitReadBuffer::new(&data, LittleEndian));
1434 assert_eq!(0.0, read_bit_coord(&mut read).unwrap());
1435 assert_eq!(pos1, read.pos());
1436 assert_eq!(123.0, read_bit_coord(&mut read).unwrap());
1437 assert_eq!(pos2, read.pos());
1438 assert_eq!(123.4375, read_bit_coord(&mut read).unwrap());
1439 assert_eq!(pos3, read.pos());
1440 assert_eq!(-0.4375, read_bit_coord(&mut read).unwrap());
1441 assert_eq!(pos4, read.pos());
1442}
1443
1444fn get_frac_factor(bits: usize) -> f32 {
1445 1.0 / ((1 << bits) as f32)
1446}
1447
1448pub fn read_bit_coord_mp(
1449 stream: &mut Stream,
1450 is_integral: bool,
1451 low_precision: bool,
1452) -> ReadResult<f32> {
1453 let mut value = 0.0;
1454 let mut is_negative = false;
1455
1456 let in_bounds = stream.read()?;
1457 let has_int_val = stream.read()?;
1458
1459 if is_integral {
1460 if has_int_val {
1461 is_negative = stream.read()?;
1462
1463 let int_val = stream.read_sized::<u32>(if in_bounds { 11 } else { 14 })? + 1;
1464 value = int_val as f32;
1465 }
1466 } else {
1467 is_negative = stream.read()?;
1468 if has_int_val {
1469 let int_val = stream.read_sized::<u32>(if in_bounds { 11 } else { 14 })? + 1;
1470 value = int_val as f32;
1471 }
1472 let frac_bits = if low_precision { 3 } else { 5 };
1473 let frac_val: u32 = stream.read_sized(frac_bits)?;
1474 value += (frac_val as f32) * get_frac_factor(frac_bits);
1475 }
1476
1477 if is_negative {
1478 value = -value;
1479 }
1480
1481 Ok(value)
1482}
1483
1484#[cfg(feature = "write")]
1485pub fn write_bit_coord_mp(
1486 val: f32,
1487 stream: &mut BitWriteStream<LittleEndian>,
1488 is_integral: bool,
1489 low_precision: bool,
1490) -> ReadResult<()> {
1491 let abs = val.abs();
1492 let in_bounds = (abs as u32) < (1 << 11);
1493 let has_int_val = abs >= 1.0;
1494 in_bounds.write(stream)?;
1495 has_int_val.write(stream)?;
1496
1497 if is_integral {
1498 if has_int_val {
1499 val.is_sign_negative().write(stream)?;
1500 ((abs - 1.0) as u32).write_sized(stream, if in_bounds { 11 } else { 14 })?;
1501 }
1502 } else {
1503 val.is_sign_negative().write(stream)?;
1504 if has_int_val {
1505 ((abs - 1.0) as u32).write_sized(stream, if in_bounds { 11 } else { 14 })?;
1506 }
1507 let frac_bits = if low_precision { 3 } else { 5 };
1508 let frac_val = (abs.fract() / get_frac_factor(frac_bits)) as u32;
1509 frac_val.write_sized(stream, frac_bits)?;
1510 }
1511
1512 Ok(())
1513}
1514
1515#[test]
1516#[cfg(feature = "write")]
1517fn test_bit_coord_mp_roundtrip() {
1518 use bitbuffer::{BitReadBuffer, BitReadStream};
1519
1520 fn bit_coord_mp_normal(val: f32, is_integral: bool, low_precision: bool) {
1521 let mut data = Vec::with_capacity(16);
1522 let pos = {
1523 let mut write = BitWriteStream::new(&mut data, LittleEndian);
1524 write_bit_coord_mp(val, &mut write, is_integral, low_precision).unwrap();
1525 write.bit_len()
1526 };
1527 let mut read = BitReadStream::new(BitReadBuffer::new(&data, LittleEndian));
1528 assert_eq!(
1529 val,
1530 read_bit_coord_mp(&mut read, is_integral, low_precision).unwrap()
1531 );
1532 assert_eq!(pos, read.pos());
1533 }
1534
1535 bit_coord_mp_normal(1.0, false, false);
1536
1537 bit_coord_mp_normal(0.0, false, false);
1538 bit_coord_mp_normal(0.5, false, false);
1539 bit_coord_mp_normal(-0.5, false, false);
1540 bit_coord_mp_normal(1234.5, false, false);
1541 bit_coord_mp_normal(-1234.5, false, false);
1542 bit_coord_mp_normal(2.0f32.powf(12.0) + 0.125, false, false);
1543
1544 bit_coord_mp_normal(0.0, false, true);
1545 bit_coord_mp_normal(0.5, false, true);
1546 bit_coord_mp_normal(-0.5, false, true);
1547 bit_coord_mp_normal(1234.5, false, true);
1548 bit_coord_mp_normal(-1234.5, false, true);
1549 bit_coord_mp_normal(2.0f32.powf(12.0) + 0.125, false, true);
1550
1551 bit_coord_mp_normal(0.0, true, false);
1552 bit_coord_mp_normal(1234.0, true, false);
1553 bit_coord_mp_normal(-1234.0, true, false);
1554 bit_coord_mp_normal(2.0f32.powf(12.0), true, false);
1555}
1556
1557pub fn read_bit_normal(stream: &mut Stream) -> ReadResult<f32> {
1558 let is_negative = stream.read()?;
1559 let frac_val: u16 = stream.read_sized(11)?;
1560 let value = (frac_val as f32) * get_frac_factor(11);
1561 if is_negative {
1562 Ok(-value)
1563 } else {
1564 Ok(value)
1565 }
1566}
1567
1568#[cfg(feature = "write")]
1569pub fn write_bit_normal(val: f32, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
1570 val.is_sign_negative().write(stream)?;
1571 let frac_val = (val.abs().fract() / get_frac_factor(11)) as u16;
1572 frac_val.write_sized(stream, 11)
1573}
1574
1575#[test]
1576#[cfg(feature = "write")]
1577fn test_bit_normal_roundtrip() {
1578 use bitbuffer::{BitReadBuffer, BitReadStream};
1579
1580 fn roundtrip_normal(val: f32) {
1581 let mut data = Vec::with_capacity(16);
1582 let pos = {
1583 let mut write = BitWriteStream::new(&mut data, LittleEndian);
1584 write_bit_normal(val, &mut write).unwrap();
1585 write.bit_len()
1586 };
1587 let mut read = BitReadStream::new(BitReadBuffer::new(&data, LittleEndian));
1588 assert_eq!(val, read_bit_normal(&mut read).unwrap());
1589 assert_eq!(pos, read.pos());
1590 }
1591 roundtrip_normal(0.0);
1592 roundtrip_normal(-0.0);
1593 roundtrip_normal(0.5);
1594 roundtrip_normal(-0.5);
1595}
1596
1597#[test]
1598fn test_vector_normal_var_float() {
1599 use bitbuffer::BitReadBuffer;
1600
1601 let data: Vec<u8> = vec![0, 0, 0, 0];
1602 let mut buffer = BitReadBuffer::new(&data, LittleEndian);
1603 buffer.truncate(25).unwrap();
1605 let mut read = BitReadStream::new(buffer);
1606
1607 let vector = SendPropValue::parse(
1608 &mut read,
1609 &SendPropParseDefinition::Vector {
1610 changes_often: false,
1611 definition: FloatDefinition::NormalVarFloat,
1612 },
1613 )
1614 .unwrap();
1615
1616 assert_eq!(
1617 SendPropValue::Vector(Vector {
1618 x: 0.0f32,
1619 y: 0.0f32,
1620 z: 1.0f32
1621 }),
1622 vector
1623 );
1624}