#![allow(dead_code, unused_imports, clippy::all)]
use delta_pack::IndexMap;
use delta_pack::{Decoder, Encoder};
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Team {
RED,
BLUE,
GREEN,
YELLOW,
}
impl Team {
pub const NUM_BITS: u8 = 2;
pub fn from_u32(val: u32) -> Self {
match val {
0 => Team::RED,
1 => Team::BLUE,
2 => Team::GREEN,
3 => Team::YELLOW,
_ => panic!("Invalid Team value: {}", val),
}
}
pub fn to_u32(self) -> u32 {
match self {
Team::RED => 0,
Team::BLUE => 1,
Team::GREEN => 2,
Team::YELLOW => 3,
}
}
}
impl Default for Team {
fn default() -> Self {
Team::RED
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum PlayerStatus {
ALIVE,
DEAD,
SPECTATING,
DISCONNECTED,
}
impl PlayerStatus {
pub const NUM_BITS: u8 = 2;
pub fn from_u32(val: u32) -> Self {
match val {
0 => PlayerStatus::ALIVE,
1 => PlayerStatus::DEAD,
2 => PlayerStatus::SPECTATING,
3 => PlayerStatus::DISCONNECTED,
_ => panic!("Invalid PlayerStatus value: {}", val),
}
}
pub fn to_u32(self) -> u32 {
match self {
PlayerStatus::ALIVE => 0,
PlayerStatus::DEAD => 1,
PlayerStatus::SPECTATING => 2,
PlayerStatus::DISCONNECTED => 3,
}
}
}
impl Default for PlayerStatus {
fn default() -> Self {
PlayerStatus::ALIVE
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum WeaponType {
SWORD,
BOW,
STAFF,
DAGGER,
AXE,
}
impl WeaponType {
pub const NUM_BITS: u8 = 3;
pub fn from_u32(val: u32) -> Self {
match val {
0 => WeaponType::SWORD,
1 => WeaponType::BOW,
2 => WeaponType::STAFF,
3 => WeaponType::DAGGER,
4 => WeaponType::AXE,
_ => panic!("Invalid WeaponType value: {}", val),
}
}
pub fn to_u32(self) -> u32 {
match self {
WeaponType::SWORD => 0,
WeaponType::BOW => 1,
WeaponType::STAFF => 2,
WeaponType::DAGGER => 3,
WeaponType::AXE => 4,
}
}
}
impl Default for WeaponType {
fn default() -> Self {
WeaponType::SWORD
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum ItemRarity {
COMMON,
UNCOMMON,
RARE,
EPIC,
LEGENDARY,
}
impl ItemRarity {
pub const NUM_BITS: u8 = 3;
pub fn from_u32(val: u32) -> Self {
match val {
0 => ItemRarity::COMMON,
1 => ItemRarity::UNCOMMON,
2 => ItemRarity::RARE,
3 => ItemRarity::EPIC,
4 => ItemRarity::LEGENDARY,
_ => panic!("Invalid ItemRarity value: {}", val),
}
}
pub fn to_u32(self) -> u32 {
match self {
ItemRarity::COMMON => 0,
ItemRarity::UNCOMMON => 1,
ItemRarity::RARE => 2,
ItemRarity::EPIC => 3,
ItemRarity::LEGENDARY => 4,
}
}
}
impl Default for ItemRarity {
fn default() -> Self {
ItemRarity::COMMON
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum AbilityType {
HEAL,
DAMAGE,
SHIELD,
BUFF,
DEBUFF,
TELEPORT,
}
impl AbilityType {
pub const NUM_BITS: u8 = 3;
pub fn from_u32(val: u32) -> Self {
match val {
0 => AbilityType::HEAL,
1 => AbilityType::DAMAGE,
2 => AbilityType::SHIELD,
3 => AbilityType::BUFF,
4 => AbilityType::DEBUFF,
5 => AbilityType::TELEPORT,
_ => panic!("Invalid AbilityType value: {}", val),
}
}
pub fn to_u32(self) -> u32 {
match self {
AbilityType::HEAL => 0,
AbilityType::DAMAGE => 1,
AbilityType::SHIELD => 2,
AbilityType::BUFF => 3,
AbilityType::DEBUFF => 4,
AbilityType::TELEPORT => 5,
}
}
}
impl Default for AbilityType {
fn default() -> Self {
AbilityType::HEAL
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum EffectType {
POISON,
BURN,
FREEZE,
STUN,
REGEN,
HASTE,
}
impl EffectType {
pub const NUM_BITS: u8 = 3;
pub fn from_u32(val: u32) -> Self {
match val {
0 => EffectType::POISON,
1 => EffectType::BURN,
2 => EffectType::FREEZE,
3 => EffectType::STUN,
4 => EffectType::REGEN,
5 => EffectType::HASTE,
_ => panic!("Invalid EffectType value: {}", val),
}
}
pub fn to_u32(self) -> u32 {
match self {
EffectType::POISON => 0,
EffectType::BURN => 1,
EffectType::FREEZE => 2,
EffectType::STUN => 3,
EffectType::REGEN => 4,
EffectType::HASTE => 5,
}
}
}
impl Default for EffectType {
fn default() -> Self {
EffectType::POISON
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Position {
pub x: f32,
pub y: f32,
}
impl Default for Position {
fn default() -> Self {
Self { x: 0.0, y: 0.0 }
}
}
impl Position {
pub fn equals(&self, other: &Self) -> bool {
delta_pack::equals_float_quantized(self.x, other.x, 0.1_f32)
&& delta_pack::equals_float_quantized(self.y, other.y, 0.1_f32)
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_float_quantized(self.x, 0.1_f32);
encoder.push_float_quantized(self.y, 0.1_f32);
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.x,
&b.x,
|x, y| delta_pack::equals_float_quantized(*x, *y, 0.1_f32),
|enc, &a, &b| enc.push_float_quantized_diff(a, b, 0.1_f32),
);
encoder.push_field_diff(
&a.y,
&b.y,
|x, y| delta_pack::equals_float_quantized(*x, *y, 0.1_f32),
|enc, &a, &b| enc.push_float_quantized_diff(a, b, 0.1_f32),
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
x: decoder.next_float_quantized(0.1_f32),
y: decoder.next_float_quantized(0.1_f32),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
x: decoder.next_field_diff(&obj.x, |dec, &a| dec.next_float_quantized_diff(a, 0.1_f32)),
y: decoder.next_field_diff(&obj.y, |dec, &a| dec.next_float_quantized_diff(a, 0.1_f32)),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Velocity {
pub vx: f32,
pub vy: f32,
}
impl Default for Velocity {
fn default() -> Self {
Self { vx: 0.0, vy: 0.0 }
}
}
impl Velocity {
pub fn equals(&self, other: &Self) -> bool {
delta_pack::equals_float(self.vx, other.vx) && delta_pack::equals_float(self.vy, other.vy)
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_float(self.vx);
encoder.push_float(self.vy);
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.vx,
&b.vx,
|x, y| delta_pack::equals_float(*x, *y),
|enc, &a, &b| enc.push_float_diff(a, b),
);
encoder.push_field_diff(
&a.vy,
&b.vy,
|x, y| delta_pack::equals_float(*x, *y),
|enc, &a, &b| enc.push_float_diff(a, b),
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
vx: decoder.next_float(),
vy: decoder.next_float(),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
vx: decoder.next_field_diff(&obj.vx, |dec, &a| dec.next_float_diff(a)),
vy: decoder.next_field_diff(&obj.vy, |dec, &a| dec.next_float_diff(a)),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct InventoryItem {
#[serde(rename = "itemId")]
pub item_id: String,
pub name: String,
pub quantity: u64,
pub rarity: ItemRarity,
pub durability: Option<u64>,
#[serde(rename = "enchantmentLevel")]
pub enchantment_level: Option<u64>,
}
impl Default for InventoryItem {
fn default() -> Self {
Self {
item_id: String::new(),
name: String::new(),
quantity: 0,
rarity: ItemRarity::default(),
durability: None,
enchantment_level: None,
}
}
}
impl InventoryItem {
pub fn equals(&self, other: &Self) -> bool {
self.item_id == other.item_id
&& self.name == other.name
&& self.quantity == other.quantity
&& self.rarity == other.rarity
&& self.durability == other.durability
&& self.enchantment_level == other.enchantment_level
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_string(&self.item_id);
encoder.push_string(&self.name);
encoder.push_uint(self.quantity);
encoder.push_enum(self.rarity.to_u32(), 3);
encoder.push_optional(&self.durability, |enc, &item| enc.push_uint(item));
encoder.push_optional(&self.enchantment_level, |enc, &item| enc.push_uint(item));
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.item_id,
&b.item_id,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.name,
&b.name,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.quantity,
&b.quantity,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.rarity,
&b.rarity,
|x, y| x == y,
|enc, &a, &b| enc.push_enum_diff(a.to_u32(), b.to_u32(), 3),
);
encoder.push_field_diff(
&a.durability,
&b.durability,
|x, y| x == y,
|enc, a, b| {
enc.push_optional_diff(
a,
b,
|enc, &item| enc.push_uint(item),
|enc, &a, &b| enc.push_uint_diff(a, b),
)
},
);
encoder.push_field_diff(
&a.enchantment_level,
&b.enchantment_level,
|x, y| x == y,
|enc, a, b| {
enc.push_optional_diff(
a,
b,
|enc, &item| enc.push_uint(item),
|enc, &a, &b| enc.push_uint_diff(a, b),
)
},
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
item_id: decoder.next_string(),
name: decoder.next_string(),
quantity: decoder.next_uint(),
rarity: ItemRarity::from_u32(decoder.next_enum(3)),
durability: decoder.next_optional(|dec| dec.next_uint()),
enchantment_level: decoder.next_optional(|dec| dec.next_uint()),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
item_id: decoder.next_field_diff(&obj.item_id, |dec, a| dec.next_string_diff(a)),
name: decoder.next_field_diff(&obj.name, |dec, a| dec.next_string_diff(a)),
quantity: decoder.next_field_diff(&obj.quantity, |dec, &a| dec.next_uint_diff(a)),
rarity: decoder.next_field_diff(&obj.rarity, |dec, &a| {
ItemRarity::from_u32(dec.next_enum_diff(a.to_u32(), 3))
}),
durability: decoder.next_field_diff(&obj.durability, |dec, a| {
dec.next_optional_diff(a, |dec| dec.next_uint(), |dec, &a| dec.next_uint_diff(a))
}),
enchantment_level: decoder.next_field_diff(&obj.enchantment_level, |dec, a| {
dec.next_optional_diff(a, |dec| dec.next_uint(), |dec, &a| dec.next_uint_diff(a))
}),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Equipment {
pub weapon: Option<WeaponType>,
pub armor: Option<String>,
pub accessory1: Option<String>,
pub accessory2: Option<String>,
}
impl Default for Equipment {
fn default() -> Self {
Self {
weapon: None,
armor: None,
accessory1: None,
accessory2: None,
}
}
}
impl Equipment {
pub fn equals(&self, other: &Self) -> bool {
self.weapon == other.weapon
&& self.armor == other.armor
&& self.accessory1 == other.accessory1
&& self.accessory2 == other.accessory2
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_optional(&self.weapon, |enc, &item| enc.push_enum(item.to_u32(), 3));
encoder.push_optional(&self.armor, |enc, item| enc.push_string(item));
encoder.push_optional(&self.accessory1, |enc, item| enc.push_string(item));
encoder.push_optional(&self.accessory2, |enc, item| enc.push_string(item));
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.weapon,
&b.weapon,
|x, y| x == y,
|enc, a, b| {
enc.push_optional_diff(
a,
b,
|enc, &item| enc.push_enum(item.to_u32(), 3),
|enc, &a, &b| enc.push_enum_diff(a.to_u32(), b.to_u32(), 3),
)
},
);
encoder.push_field_diff(
&a.armor,
&b.armor,
|x, y| x == y,
|enc, a, b| {
enc.push_optional_diff(
a,
b,
|enc, item| enc.push_string(item),
|enc, a, b| enc.push_string_diff(a, b),
)
},
);
encoder.push_field_diff(
&a.accessory1,
&b.accessory1,
|x, y| x == y,
|enc, a, b| {
enc.push_optional_diff(
a,
b,
|enc, item| enc.push_string(item),
|enc, a, b| enc.push_string_diff(a, b),
)
},
);
encoder.push_field_diff(
&a.accessory2,
&b.accessory2,
|x, y| x == y,
|enc, a, b| {
enc.push_optional_diff(
a,
b,
|enc, item| enc.push_string(item),
|enc, a, b| enc.push_string_diff(a, b),
)
},
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
weapon: decoder.next_optional(|dec| WeaponType::from_u32(dec.next_enum(3))),
armor: decoder.next_optional(|dec| dec.next_string()),
accessory1: decoder.next_optional(|dec| dec.next_string()),
accessory2: decoder.next_optional(|dec| dec.next_string()),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
weapon: decoder.next_field_diff(&obj.weapon, |dec, a| {
dec.next_optional_diff(
a,
|dec| WeaponType::from_u32(dec.next_enum(3)),
|dec, &a| WeaponType::from_u32(dec.next_enum_diff(a.to_u32(), 3)),
)
}),
armor: decoder.next_field_diff(&obj.armor, |dec, a| {
dec.next_optional_diff(a, |dec| dec.next_string(), |dec, a| dec.next_string_diff(a))
}),
accessory1: decoder.next_field_diff(&obj.accessory1, |dec, a| {
dec.next_optional_diff(a, |dec| dec.next_string(), |dec, a| dec.next_string_diff(a))
}),
accessory2: decoder.next_field_diff(&obj.accessory2, |dec, a| {
dec.next_optional_diff(a, |dec| dec.next_string(), |dec, a| dec.next_string_diff(a))
}),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PlayerStats {
pub health: u64,
#[serde(rename = "maxHealth")]
pub max_health: u64,
pub mana: u64,
#[serde(rename = "maxMana")]
pub max_mana: u64,
pub stamina: u64,
#[serde(rename = "maxStamina")]
pub max_stamina: u64,
pub level: u64,
pub experience: u64,
pub strength: u64,
pub agility: u64,
pub intelligence: u64,
pub defense: u64,
}
impl Default for PlayerStats {
fn default() -> Self {
Self {
health: 0,
max_health: 0,
mana: 0,
max_mana: 0,
stamina: 0,
max_stamina: 0,
level: 0,
experience: 0,
strength: 0,
agility: 0,
intelligence: 0,
defense: 0,
}
}
}
impl PlayerStats {
pub fn equals(&self, other: &Self) -> bool {
self.health == other.health
&& self.max_health == other.max_health
&& self.mana == other.mana
&& self.max_mana == other.max_mana
&& self.stamina == other.stamina
&& self.max_stamina == other.max_stamina
&& self.level == other.level
&& self.experience == other.experience
&& self.strength == other.strength
&& self.agility == other.agility
&& self.intelligence == other.intelligence
&& self.defense == other.defense
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_uint(self.health);
encoder.push_uint(self.max_health);
encoder.push_uint(self.mana);
encoder.push_uint(self.max_mana);
encoder.push_uint(self.stamina);
encoder.push_uint(self.max_stamina);
encoder.push_uint(self.level);
encoder.push_uint(self.experience);
encoder.push_uint(self.strength);
encoder.push_uint(self.agility);
encoder.push_uint(self.intelligence);
encoder.push_uint(self.defense);
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.health,
&b.health,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.max_health,
&b.max_health,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.mana,
&b.mana,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.max_mana,
&b.max_mana,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.stamina,
&b.stamina,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.max_stamina,
&b.max_stamina,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.level,
&b.level,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.experience,
&b.experience,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.strength,
&b.strength,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.agility,
&b.agility,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.intelligence,
&b.intelligence,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.defense,
&b.defense,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
health: decoder.next_uint(),
max_health: decoder.next_uint(),
mana: decoder.next_uint(),
max_mana: decoder.next_uint(),
stamina: decoder.next_uint(),
max_stamina: decoder.next_uint(),
level: decoder.next_uint(),
experience: decoder.next_uint(),
strength: decoder.next_uint(),
agility: decoder.next_uint(),
intelligence: decoder.next_uint(),
defense: decoder.next_uint(),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
health: decoder.next_field_diff(&obj.health, |dec, &a| dec.next_uint_diff(a)),
max_health: decoder.next_field_diff(&obj.max_health, |dec, &a| dec.next_uint_diff(a)),
mana: decoder.next_field_diff(&obj.mana, |dec, &a| dec.next_uint_diff(a)),
max_mana: decoder.next_field_diff(&obj.max_mana, |dec, &a| dec.next_uint_diff(a)),
stamina: decoder.next_field_diff(&obj.stamina, |dec, &a| dec.next_uint_diff(a)),
max_stamina: decoder.next_field_diff(&obj.max_stamina, |dec, &a| dec.next_uint_diff(a)),
level: decoder.next_field_diff(&obj.level, |dec, &a| dec.next_uint_diff(a)),
experience: decoder.next_field_diff(&obj.experience, |dec, &a| dec.next_uint_diff(a)),
strength: decoder.next_field_diff(&obj.strength, |dec, &a| dec.next_uint_diff(a)),
agility: decoder.next_field_diff(&obj.agility, |dec, &a| dec.next_uint_diff(a)),
intelligence: decoder
.next_field_diff(&obj.intelligence, |dec, &a| dec.next_uint_diff(a)),
defense: decoder.next_field_diff(&obj.defense, |dec, &a| dec.next_uint_diff(a)),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ActiveEffect {
#[serde(rename = "effectType")]
pub effect_type: EffectType,
pub duration: f32,
pub strength: u64,
#[serde(rename = "stackCount")]
pub stack_count: u64,
}
impl Default for ActiveEffect {
fn default() -> Self {
Self {
effect_type: EffectType::default(),
duration: 0.0,
strength: 0,
stack_count: 0,
}
}
}
impl ActiveEffect {
pub fn equals(&self, other: &Self) -> bool {
self.effect_type == other.effect_type
&& delta_pack::equals_float(self.duration, other.duration)
&& self.strength == other.strength
&& self.stack_count == other.stack_count
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_enum(self.effect_type.to_u32(), 3);
encoder.push_float(self.duration);
encoder.push_uint(self.strength);
encoder.push_uint(self.stack_count);
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.effect_type,
&b.effect_type,
|x, y| x == y,
|enc, &a, &b| enc.push_enum_diff(a.to_u32(), b.to_u32(), 3),
);
encoder.push_field_diff(
&a.duration,
&b.duration,
|x, y| delta_pack::equals_float(*x, *y),
|enc, &a, &b| enc.push_float_diff(a, b),
);
encoder.push_field_diff(
&a.strength,
&b.strength,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.stack_count,
&b.stack_count,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
effect_type: EffectType::from_u32(decoder.next_enum(3)),
duration: decoder.next_float(),
strength: decoder.next_uint(),
stack_count: decoder.next_uint(),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
effect_type: decoder.next_field_diff(&obj.effect_type, |dec, &a| {
EffectType::from_u32(dec.next_enum_diff(a.to_u32(), 3))
}),
duration: decoder.next_field_diff(&obj.duration, |dec, &a| dec.next_float_diff(a)),
strength: decoder.next_field_diff(&obj.strength, |dec, &a| dec.next_uint_diff(a)),
stack_count: decoder.next_field_diff(&obj.stack_count, |dec, &a| dec.next_uint_diff(a)),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AbilityCooldown {
#[serde(rename = "abilityId")]
pub ability_id: String,
#[serde(rename = "abilityType")]
pub ability_type: AbilityType,
#[serde(rename = "remainingCooldown")]
pub remaining_cooldown: f32,
}
impl Default for AbilityCooldown {
fn default() -> Self {
Self {
ability_id: String::new(),
ability_type: AbilityType::default(),
remaining_cooldown: 0.0,
}
}
}
impl AbilityCooldown {
pub fn equals(&self, other: &Self) -> bool {
self.ability_id == other.ability_id
&& self.ability_type == other.ability_type
&& delta_pack::equals_float(self.remaining_cooldown, other.remaining_cooldown)
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_string(&self.ability_id);
encoder.push_enum(self.ability_type.to_u32(), 3);
encoder.push_float(self.remaining_cooldown);
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.ability_id,
&b.ability_id,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.ability_type,
&b.ability_type,
|x, y| x == y,
|enc, &a, &b| enc.push_enum_diff(a.to_u32(), b.to_u32(), 3),
);
encoder.push_field_diff(
&a.remaining_cooldown,
&b.remaining_cooldown,
|x, y| delta_pack::equals_float(*x, *y),
|enc, &a, &b| enc.push_float_diff(a, b),
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
ability_id: decoder.next_string(),
ability_type: AbilityType::from_u32(decoder.next_enum(3)),
remaining_cooldown: decoder.next_float(),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
ability_id: decoder.next_field_diff(&obj.ability_id, |dec, a| dec.next_string_diff(a)),
ability_type: decoder.next_field_diff(&obj.ability_type, |dec, &a| {
AbilityType::from_u32(dec.next_enum_diff(a.to_u32(), 3))
}),
remaining_cooldown: decoder
.next_field_diff(&obj.remaining_cooldown, |dec, &a| dec.next_float_diff(a)),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Player {
#[serde(rename = "playerId")]
pub player_id: String,
pub username: String,
pub team: Option<Team>,
pub status: PlayerStatus,
pub position: Position,
pub velocity: Velocity,
pub rotation: f32,
pub stats: PlayerStats,
pub inventory: Vec<InventoryItem>,
pub equipment: Equipment,
#[serde(rename = "activeEffects")]
pub active_effects: Vec<ActiveEffect>,
#[serde(rename = "abilityCooldowns")]
pub ability_cooldowns: Vec<AbilityCooldown>,
pub kills: u64,
pub deaths: u64,
pub assists: u64,
pub gold: u64,
pub score: i64,
pub ping: u64,
#[serde(rename = "isJumping")]
pub is_jumping: bool,
#[serde(rename = "isCrouching")]
pub is_crouching: bool,
#[serde(rename = "isAiming")]
pub is_aiming: bool,
#[serde(rename = "lastDamageTime")]
pub last_damage_time: Option<f32>,
#[serde(rename = "respawnTime")]
pub respawn_time: Option<f32>,
}
impl Default for Player {
fn default() -> Self {
Self {
player_id: String::new(),
username: String::new(),
team: None,
status: PlayerStatus::default(),
position: Position::default(),
velocity: Velocity::default(),
rotation: 0.0,
stats: PlayerStats::default(),
inventory: Vec::new(),
equipment: Equipment::default(),
active_effects: Vec::new(),
ability_cooldowns: Vec::new(),
kills: 0,
deaths: 0,
assists: 0,
gold: 0,
score: 0,
ping: 0,
is_jumping: false,
is_crouching: false,
is_aiming: false,
last_damage_time: None,
respawn_time: None,
}
}
}
impl Player {
pub fn equals(&self, other: &Self) -> bool {
self.player_id == other.player_id
&& self.username == other.username
&& self.team == other.team
&& self.status == other.status
&& self.position.equals(&other.position)
&& self.velocity.equals(&other.velocity)
&& delta_pack::equals_float(self.rotation, other.rotation)
&& self.stats.equals(&other.stats)
&& delta_pack::equals_array(&self.inventory, &other.inventory, |x, y| x.equals(y))
&& self.equipment.equals(&other.equipment)
&& delta_pack::equals_array(&self.active_effects, &other.active_effects, |x, y| {
x.equals(y)
})
&& delta_pack::equals_array(
&self.ability_cooldowns,
&other.ability_cooldowns,
|x, y| x.equals(y),
)
&& self.kills == other.kills
&& self.deaths == other.deaths
&& self.assists == other.assists
&& self.gold == other.gold
&& self.score == other.score
&& self.ping == other.ping
&& self.is_jumping == other.is_jumping
&& self.is_crouching == other.is_crouching
&& self.is_aiming == other.is_aiming
&& self.last_damage_time == other.last_damage_time
&& self.respawn_time == other.respawn_time
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_string(&self.player_id);
encoder.push_string(&self.username);
encoder.push_optional(&self.team, |enc, &item| enc.push_enum(item.to_u32(), 2));
encoder.push_enum(self.status.to_u32(), 2);
self.position.encode_into(encoder);
self.velocity.encode_into(encoder);
encoder.push_float(self.rotation);
self.stats.encode_into(encoder);
encoder.push_array(&self.inventory, |enc, item| item.encode_into(enc));
self.equipment.encode_into(encoder);
encoder.push_array(&self.active_effects, |enc, item| item.encode_into(enc));
encoder.push_array(&self.ability_cooldowns, |enc, item| item.encode_into(enc));
encoder.push_uint(self.kills);
encoder.push_uint(self.deaths);
encoder.push_uint(self.assists);
encoder.push_uint(self.gold);
encoder.push_int(self.score);
encoder.push_uint(self.ping);
encoder.push_boolean(self.is_jumping);
encoder.push_boolean(self.is_crouching);
encoder.push_boolean(self.is_aiming);
encoder.push_optional(&self.last_damage_time, |enc, &item| enc.push_float(item));
encoder.push_optional(&self.respawn_time, |enc, &item| enc.push_float(item));
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.player_id,
&b.player_id,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.username,
&b.username,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.team,
&b.team,
|x, y| x == y,
|enc, a, b| {
enc.push_optional_diff(
a,
b,
|enc, &item| enc.push_enum(item.to_u32(), 2),
|enc, &a, &b| enc.push_enum_diff(a.to_u32(), b.to_u32(), 2),
)
},
);
encoder.push_field_diff(
&a.status,
&b.status,
|x, y| x == y,
|enc, &a, &b| enc.push_enum_diff(a.to_u32(), b.to_u32(), 2),
);
encoder.push_field_diff(
&a.position,
&b.position,
|x, y| x.equals(y),
|enc, a, b| Position::encode_diff_into(a, b, enc),
);
encoder.push_field_diff(
&a.velocity,
&b.velocity,
|x, y| x.equals(y),
|enc, a, b| Velocity::encode_diff_into(a, b, enc),
);
encoder.push_field_diff(
&a.rotation,
&b.rotation,
|x, y| delta_pack::equals_float(*x, *y),
|enc, &a, &b| enc.push_float_diff(a, b),
);
encoder.push_field_diff(
&a.stats,
&b.stats,
|x, y| x.equals(y),
|enc, a, b| PlayerStats::encode_diff_into(a, b, enc),
);
encoder.push_field_diff(
&a.inventory,
&b.inventory,
|x, y| delta_pack::equals_array(&x, &y, |x, y| x.equals(y)),
|enc, a, b| {
enc.push_array_diff(
a,
b,
|x, y| x.equals(y),
|enc, item| item.encode_into(enc),
|enc, a, b| InventoryItem::encode_diff_into(a, b, enc),
)
},
);
encoder.push_field_diff(
&a.equipment,
&b.equipment,
|x, y| x.equals(y),
|enc, a, b| Equipment::encode_diff_into(a, b, enc),
);
encoder.push_field_diff(
&a.active_effects,
&b.active_effects,
|x, y| delta_pack::equals_array(&x, &y, |x, y| x.equals(y)),
|enc, a, b| {
enc.push_array_diff(
a,
b,
|x, y| x.equals(y),
|enc, item| item.encode_into(enc),
|enc, a, b| ActiveEffect::encode_diff_into(a, b, enc),
)
},
);
encoder.push_field_diff(
&a.ability_cooldowns,
&b.ability_cooldowns,
|x, y| delta_pack::equals_array(&x, &y, |x, y| x.equals(y)),
|enc, a, b| {
enc.push_array_diff(
a,
b,
|x, y| x.equals(y),
|enc, item| item.encode_into(enc),
|enc, a, b| AbilityCooldown::encode_diff_into(a, b, enc),
)
},
);
encoder.push_field_diff(
&a.kills,
&b.kills,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.deaths,
&b.deaths,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.assists,
&b.assists,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.gold,
&b.gold,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.score,
&b.score,
|x, y| x == y,
|enc, &a, &b| enc.push_int_diff(a, b),
);
encoder.push_field_diff(
&a.ping,
&b.ping,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_boolean_diff(a.is_jumping, b.is_jumping);
encoder.push_boolean_diff(a.is_crouching, b.is_crouching);
encoder.push_boolean_diff(a.is_aiming, b.is_aiming);
encoder.push_field_diff(
&a.last_damage_time,
&b.last_damage_time,
|x, y| x == y,
|enc, a, b| {
enc.push_optional_diff(
a,
b,
|enc, &item| enc.push_float(item),
|enc, &a, &b| enc.push_float_diff(a, b),
)
},
);
encoder.push_field_diff(
&a.respawn_time,
&b.respawn_time,
|x, y| x == y,
|enc, a, b| {
enc.push_optional_diff(
a,
b,
|enc, &item| enc.push_float(item),
|enc, &a, &b| enc.push_float_diff(a, b),
)
},
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
player_id: decoder.next_string(),
username: decoder.next_string(),
team: decoder.next_optional(|dec| Team::from_u32(dec.next_enum(2))),
status: PlayerStatus::from_u32(decoder.next_enum(2)),
position: Position::decode_from(decoder),
velocity: Velocity::decode_from(decoder),
rotation: decoder.next_float(),
stats: PlayerStats::decode_from(decoder),
inventory: decoder.next_array(|dec| InventoryItem::decode_from(dec)),
equipment: Equipment::decode_from(decoder),
active_effects: decoder.next_array(|dec| ActiveEffect::decode_from(dec)),
ability_cooldowns: decoder.next_array(|dec| AbilityCooldown::decode_from(dec)),
kills: decoder.next_uint(),
deaths: decoder.next_uint(),
assists: decoder.next_uint(),
gold: decoder.next_uint(),
score: decoder.next_int(),
ping: decoder.next_uint(),
is_jumping: decoder.next_boolean(),
is_crouching: decoder.next_boolean(),
is_aiming: decoder.next_boolean(),
last_damage_time: decoder.next_optional(|dec| dec.next_float()),
respawn_time: decoder.next_optional(|dec| dec.next_float()),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
player_id: decoder.next_field_diff(&obj.player_id, |dec, a| dec.next_string_diff(a)),
username: decoder.next_field_diff(&obj.username, |dec, a| dec.next_string_diff(a)),
team: decoder.next_field_diff(&obj.team, |dec, a| {
dec.next_optional_diff(
a,
|dec| Team::from_u32(dec.next_enum(2)),
|dec, &a| Team::from_u32(dec.next_enum_diff(a.to_u32(), 2)),
)
}),
status: decoder.next_field_diff(&obj.status, |dec, &a| {
PlayerStatus::from_u32(dec.next_enum_diff(a.to_u32(), 2))
}),
position: decoder
.next_field_diff(&obj.position, |dec, a| Position::decode_diff_from(a, dec)),
velocity: decoder
.next_field_diff(&obj.velocity, |dec, a| Velocity::decode_diff_from(a, dec)),
rotation: decoder.next_field_diff(&obj.rotation, |dec, &a| dec.next_float_diff(a)),
stats: decoder
.next_field_diff(&obj.stats, |dec, a| PlayerStats::decode_diff_from(a, dec)),
inventory: decoder.next_field_diff(&obj.inventory, |dec, a| {
dec.next_array_diff(
a,
|dec| InventoryItem::decode_from(dec),
|dec, a| InventoryItem::decode_diff_from(a, dec),
)
}),
equipment: decoder
.next_field_diff(&obj.equipment, |dec, a| Equipment::decode_diff_from(a, dec)),
active_effects: decoder.next_field_diff(&obj.active_effects, |dec, a| {
dec.next_array_diff(
a,
|dec| ActiveEffect::decode_from(dec),
|dec, a| ActiveEffect::decode_diff_from(a, dec),
)
}),
ability_cooldowns: decoder.next_field_diff(&obj.ability_cooldowns, |dec, a| {
dec.next_array_diff(
a,
|dec| AbilityCooldown::decode_from(dec),
|dec, a| AbilityCooldown::decode_diff_from(a, dec),
)
}),
kills: decoder.next_field_diff(&obj.kills, |dec, &a| dec.next_uint_diff(a)),
deaths: decoder.next_field_diff(&obj.deaths, |dec, &a| dec.next_uint_diff(a)),
assists: decoder.next_field_diff(&obj.assists, |dec, &a| dec.next_uint_diff(a)),
gold: decoder.next_field_diff(&obj.gold, |dec, &a| dec.next_uint_diff(a)),
score: decoder.next_field_diff(&obj.score, |dec, &a| dec.next_int_diff(a)),
ping: decoder.next_field_diff(&obj.ping, |dec, &a| dec.next_uint_diff(a)),
is_jumping: decoder.next_boolean_diff(obj.is_jumping),
is_crouching: decoder.next_boolean_diff(obj.is_crouching),
is_aiming: decoder.next_boolean_diff(obj.is_aiming),
last_damage_time: decoder.next_field_diff(&obj.last_damage_time, |dec, a| {
dec.next_optional_diff(a, |dec| dec.next_float(), |dec, &a| dec.next_float_diff(a))
}),
respawn_time: decoder.next_field_diff(&obj.respawn_time, |dec, a| {
dec.next_optional_diff(a, |dec| dec.next_float(), |dec, &a| dec.next_float_diff(a))
}),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Enemy {
#[serde(rename = "enemyId")]
pub enemy_id: String,
pub name: String,
pub position: Position,
pub velocity: Velocity,
pub health: u64,
#[serde(rename = "maxHealth")]
pub max_health: u64,
pub level: u64,
#[serde(rename = "isAggro")]
pub is_aggro: bool,
#[serde(rename = "targetPlayerId")]
pub target_player_id: Option<String>,
#[serde(rename = "lastAttackTime")]
pub last_attack_time: f32,
#[serde(rename = "lootTableId")]
pub loot_table_id: Option<String>,
}
impl Default for Enemy {
fn default() -> Self {
Self {
enemy_id: String::new(),
name: String::new(),
position: Position::default(),
velocity: Velocity::default(),
health: 0,
max_health: 0,
level: 0,
is_aggro: false,
target_player_id: None,
last_attack_time: 0.0,
loot_table_id: None,
}
}
}
impl Enemy {
pub fn equals(&self, other: &Self) -> bool {
self.enemy_id == other.enemy_id
&& self.name == other.name
&& self.position.equals(&other.position)
&& self.velocity.equals(&other.velocity)
&& self.health == other.health
&& self.max_health == other.max_health
&& self.level == other.level
&& self.is_aggro == other.is_aggro
&& self.target_player_id == other.target_player_id
&& delta_pack::equals_float(self.last_attack_time, other.last_attack_time)
&& self.loot_table_id == other.loot_table_id
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_string(&self.enemy_id);
encoder.push_string(&self.name);
self.position.encode_into(encoder);
self.velocity.encode_into(encoder);
encoder.push_uint(self.health);
encoder.push_uint(self.max_health);
encoder.push_uint(self.level);
encoder.push_boolean(self.is_aggro);
encoder.push_optional(&self.target_player_id, |enc, item| enc.push_string(item));
encoder.push_float(self.last_attack_time);
encoder.push_optional(&self.loot_table_id, |enc, item| enc.push_string(item));
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.enemy_id,
&b.enemy_id,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.name,
&b.name,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.position,
&b.position,
|x, y| x.equals(y),
|enc, a, b| Position::encode_diff_into(a, b, enc),
);
encoder.push_field_diff(
&a.velocity,
&b.velocity,
|x, y| x.equals(y),
|enc, a, b| Velocity::encode_diff_into(a, b, enc),
);
encoder.push_field_diff(
&a.health,
&b.health,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.max_health,
&b.max_health,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.level,
&b.level,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_boolean_diff(a.is_aggro, b.is_aggro);
encoder.push_field_diff(
&a.target_player_id,
&b.target_player_id,
|x, y| x == y,
|enc, a, b| {
enc.push_optional_diff(
a,
b,
|enc, item| enc.push_string(item),
|enc, a, b| enc.push_string_diff(a, b),
)
},
);
encoder.push_field_diff(
&a.last_attack_time,
&b.last_attack_time,
|x, y| delta_pack::equals_float(*x, *y),
|enc, &a, &b| enc.push_float_diff(a, b),
);
encoder.push_field_diff(
&a.loot_table_id,
&b.loot_table_id,
|x, y| x == y,
|enc, a, b| {
enc.push_optional_diff(
a,
b,
|enc, item| enc.push_string(item),
|enc, a, b| enc.push_string_diff(a, b),
)
},
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
enemy_id: decoder.next_string(),
name: decoder.next_string(),
position: Position::decode_from(decoder),
velocity: Velocity::decode_from(decoder),
health: decoder.next_uint(),
max_health: decoder.next_uint(),
level: decoder.next_uint(),
is_aggro: decoder.next_boolean(),
target_player_id: decoder.next_optional(|dec| dec.next_string()),
last_attack_time: decoder.next_float(),
loot_table_id: decoder.next_optional(|dec| dec.next_string()),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
enemy_id: decoder.next_field_diff(&obj.enemy_id, |dec, a| dec.next_string_diff(a)),
name: decoder.next_field_diff(&obj.name, |dec, a| dec.next_string_diff(a)),
position: decoder
.next_field_diff(&obj.position, |dec, a| Position::decode_diff_from(a, dec)),
velocity: decoder
.next_field_diff(&obj.velocity, |dec, a| Velocity::decode_diff_from(a, dec)),
health: decoder.next_field_diff(&obj.health, |dec, &a| dec.next_uint_diff(a)),
max_health: decoder.next_field_diff(&obj.max_health, |dec, &a| dec.next_uint_diff(a)),
level: decoder.next_field_diff(&obj.level, |dec, &a| dec.next_uint_diff(a)),
is_aggro: decoder.next_boolean_diff(obj.is_aggro),
target_player_id: decoder.next_field_diff(&obj.target_player_id, |dec, a| {
dec.next_optional_diff(a, |dec| dec.next_string(), |dec, a| dec.next_string_diff(a))
}),
last_attack_time: decoder
.next_field_diff(&obj.last_attack_time, |dec, &a| dec.next_float_diff(a)),
loot_table_id: decoder.next_field_diff(&obj.loot_table_id, |dec, a| {
dec.next_optional_diff(a, |dec| dec.next_string(), |dec, a| dec.next_string_diff(a))
}),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Projectile {
#[serde(rename = "projectileId")]
pub projectile_id: String,
#[serde(rename = "ownerId")]
pub owner_id: String,
pub position: Position,
pub velocity: Velocity,
pub damage: u64,
pub penetration: u64,
#[serde(rename = "timeToLive")]
pub time_to_live: f32,
#[serde(rename = "hitPlayers")]
pub hit_players: Vec<String>,
}
impl Default for Projectile {
fn default() -> Self {
Self {
projectile_id: String::new(),
owner_id: String::new(),
position: Position::default(),
velocity: Velocity::default(),
damage: 0,
penetration: 0,
time_to_live: 0.0,
hit_players: Vec::new(),
}
}
}
impl Projectile {
pub fn equals(&self, other: &Self) -> bool {
self.projectile_id == other.projectile_id
&& self.owner_id == other.owner_id
&& self.position.equals(&other.position)
&& self.velocity.equals(&other.velocity)
&& self.damage == other.damage
&& self.penetration == other.penetration
&& delta_pack::equals_float(self.time_to_live, other.time_to_live)
&& self.hit_players == other.hit_players
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_string(&self.projectile_id);
encoder.push_string(&self.owner_id);
self.position.encode_into(encoder);
self.velocity.encode_into(encoder);
encoder.push_uint(self.damage);
encoder.push_uint(self.penetration);
encoder.push_float(self.time_to_live);
encoder.push_array(&self.hit_players, |enc, item| enc.push_string(item));
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.projectile_id,
&b.projectile_id,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.owner_id,
&b.owner_id,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.position,
&b.position,
|x, y| x.equals(y),
|enc, a, b| Position::encode_diff_into(a, b, enc),
);
encoder.push_field_diff(
&a.velocity,
&b.velocity,
|x, y| x.equals(y),
|enc, a, b| Velocity::encode_diff_into(a, b, enc),
);
encoder.push_field_diff(
&a.damage,
&b.damage,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.penetration,
&b.penetration,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.time_to_live,
&b.time_to_live,
|x, y| delta_pack::equals_float(*x, *y),
|enc, &a, &b| enc.push_float_diff(a, b),
);
encoder.push_field_diff(
&a.hit_players,
&b.hit_players,
|x, y| x == y,
|enc, a, b| {
enc.push_array_diff(
a,
b,
|x, y| x == y,
|enc, item| enc.push_string(item),
|enc, a, b| enc.push_string_diff(a, b),
)
},
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
projectile_id: decoder.next_string(),
owner_id: decoder.next_string(),
position: Position::decode_from(decoder),
velocity: Velocity::decode_from(decoder),
damage: decoder.next_uint(),
penetration: decoder.next_uint(),
time_to_live: decoder.next_float(),
hit_players: decoder.next_array(|dec| dec.next_string()),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
projectile_id: decoder
.next_field_diff(&obj.projectile_id, |dec, a| dec.next_string_diff(a)),
owner_id: decoder.next_field_diff(&obj.owner_id, |dec, a| dec.next_string_diff(a)),
position: decoder
.next_field_diff(&obj.position, |dec, a| Position::decode_diff_from(a, dec)),
velocity: decoder
.next_field_diff(&obj.velocity, |dec, a| Velocity::decode_diff_from(a, dec)),
damage: decoder.next_field_diff(&obj.damage, |dec, &a| dec.next_uint_diff(a)),
penetration: decoder.next_field_diff(&obj.penetration, |dec, &a| dec.next_uint_diff(a)),
time_to_live: decoder
.next_field_diff(&obj.time_to_live, |dec, &a| dec.next_float_diff(a)),
hit_players: decoder.next_field_diff(&obj.hit_players, |dec, a| {
dec.next_array_diff(a, |dec| dec.next_string(), |dec, a| dec.next_string_diff(a))
}),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DroppedLoot {
#[serde(rename = "lootId")]
pub loot_id: String,
pub position: Position,
pub item: InventoryItem,
#[serde(rename = "despawnTime")]
pub despawn_time: f32,
}
impl Default for DroppedLoot {
fn default() -> Self {
Self {
loot_id: String::new(),
position: Position::default(),
item: InventoryItem::default(),
despawn_time: 0.0,
}
}
}
impl DroppedLoot {
pub fn equals(&self, other: &Self) -> bool {
self.loot_id == other.loot_id
&& self.position.equals(&other.position)
&& self.item.equals(&other.item)
&& delta_pack::equals_float(self.despawn_time, other.despawn_time)
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_string(&self.loot_id);
self.position.encode_into(encoder);
self.item.encode_into(encoder);
encoder.push_float(self.despawn_time);
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.loot_id,
&b.loot_id,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.position,
&b.position,
|x, y| x.equals(y),
|enc, a, b| Position::encode_diff_into(a, b, enc),
);
encoder.push_field_diff(
&a.item,
&b.item,
|x, y| x.equals(y),
|enc, a, b| InventoryItem::encode_diff_into(a, b, enc),
);
encoder.push_field_diff(
&a.despawn_time,
&b.despawn_time,
|x, y| delta_pack::equals_float(*x, *y),
|enc, &a, &b| enc.push_float_diff(a, b),
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
loot_id: decoder.next_string(),
position: Position::decode_from(decoder),
item: InventoryItem::decode_from(decoder),
despawn_time: decoder.next_float(),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
loot_id: decoder.next_field_diff(&obj.loot_id, |dec, a| dec.next_string_diff(a)),
position: decoder
.next_field_diff(&obj.position, |dec, a| Position::decode_diff_from(a, dec)),
item: decoder
.next_field_diff(&obj.item, |dec, a| InventoryItem::decode_diff_from(a, dec)),
despawn_time: decoder
.next_field_diff(&obj.despawn_time, |dec, &a| dec.next_float_diff(a)),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct WorldObject {
#[serde(rename = "objectId")]
pub object_id: String,
#[serde(rename = "objectType")]
pub object_type: String,
pub position: Position,
pub health: Option<u64>,
#[serde(rename = "isDestroyed")]
pub is_destroyed: bool,
#[serde(rename = "isInteractable")]
pub is_interactable: bool,
#[serde(rename = "interactedBy")]
pub interacted_by: Option<String>,
}
impl Default for WorldObject {
fn default() -> Self {
Self {
object_id: String::new(),
object_type: String::new(),
position: Position::default(),
health: None,
is_destroyed: false,
is_interactable: false,
interacted_by: None,
}
}
}
impl WorldObject {
pub fn equals(&self, other: &Self) -> bool {
self.object_id == other.object_id
&& self.object_type == other.object_type
&& self.position.equals(&other.position)
&& self.health == other.health
&& self.is_destroyed == other.is_destroyed
&& self.is_interactable == other.is_interactable
&& self.interacted_by == other.interacted_by
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_string(&self.object_id);
encoder.push_string(&self.object_type);
self.position.encode_into(encoder);
encoder.push_optional(&self.health, |enc, &item| enc.push_uint(item));
encoder.push_boolean(self.is_destroyed);
encoder.push_boolean(self.is_interactable);
encoder.push_optional(&self.interacted_by, |enc, item| enc.push_string(item));
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.object_id,
&b.object_id,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.object_type,
&b.object_type,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.position,
&b.position,
|x, y| x.equals(y),
|enc, a, b| Position::encode_diff_into(a, b, enc),
);
encoder.push_field_diff(
&a.health,
&b.health,
|x, y| x == y,
|enc, a, b| {
enc.push_optional_diff(
a,
b,
|enc, &item| enc.push_uint(item),
|enc, &a, &b| enc.push_uint_diff(a, b),
)
},
);
encoder.push_boolean_diff(a.is_destroyed, b.is_destroyed);
encoder.push_boolean_diff(a.is_interactable, b.is_interactable);
encoder.push_field_diff(
&a.interacted_by,
&b.interacted_by,
|x, y| x == y,
|enc, a, b| {
enc.push_optional_diff(
a,
b,
|enc, item| enc.push_string(item),
|enc, a, b| enc.push_string_diff(a, b),
)
},
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
object_id: decoder.next_string(),
object_type: decoder.next_string(),
position: Position::decode_from(decoder),
health: decoder.next_optional(|dec| dec.next_uint()),
is_destroyed: decoder.next_boolean(),
is_interactable: decoder.next_boolean(),
interacted_by: decoder.next_optional(|dec| dec.next_string()),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
object_id: decoder.next_field_diff(&obj.object_id, |dec, a| dec.next_string_diff(a)),
object_type: decoder
.next_field_diff(&obj.object_type, |dec, a| dec.next_string_diff(a)),
position: decoder
.next_field_diff(&obj.position, |dec, a| Position::decode_diff_from(a, dec)),
health: decoder.next_field_diff(&obj.health, |dec, a| {
dec.next_optional_diff(a, |dec| dec.next_uint(), |dec, &a| dec.next_uint_diff(a))
}),
is_destroyed: decoder.next_boolean_diff(obj.is_destroyed),
is_interactable: decoder.next_boolean_diff(obj.is_interactable),
interacted_by: decoder.next_field_diff(&obj.interacted_by, |dec, a| {
dec.next_optional_diff(a, |dec| dec.next_string(), |dec, a| dec.next_string_diff(a))
}),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct MatchStats {
#[serde(rename = "totalKills")]
pub total_kills: u64,
#[serde(rename = "totalDeaths")]
pub total_deaths: u64,
#[serde(rename = "totalDamageDealt")]
pub total_damage_dealt: u64,
#[serde(rename = "totalHealingDone")]
pub total_healing_done: u64,
#[serde(rename = "longestKillStreak")]
pub longest_kill_streak: u64,
#[serde(rename = "matchDuration")]
pub match_duration: f32,
}
impl Default for MatchStats {
fn default() -> Self {
Self {
total_kills: 0,
total_deaths: 0,
total_damage_dealt: 0,
total_healing_done: 0,
longest_kill_streak: 0,
match_duration: 0.0,
}
}
}
impl MatchStats {
pub fn equals(&self, other: &Self) -> bool {
self.total_kills == other.total_kills
&& self.total_deaths == other.total_deaths
&& self.total_damage_dealt == other.total_damage_dealt
&& self.total_healing_done == other.total_healing_done
&& self.longest_kill_streak == other.longest_kill_streak
&& delta_pack::equals_float(self.match_duration, other.match_duration)
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_uint(self.total_kills);
encoder.push_uint(self.total_deaths);
encoder.push_uint(self.total_damage_dealt);
encoder.push_uint(self.total_healing_done);
encoder.push_uint(self.longest_kill_streak);
encoder.push_float(self.match_duration);
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.total_kills,
&b.total_kills,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.total_deaths,
&b.total_deaths,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.total_damage_dealt,
&b.total_damage_dealt,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.total_healing_done,
&b.total_healing_done,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.longest_kill_streak,
&b.longest_kill_streak,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.match_duration,
&b.match_duration,
|x, y| delta_pack::equals_float(*x, *y),
|enc, &a, &b| enc.push_float_diff(a, b),
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
total_kills: decoder.next_uint(),
total_deaths: decoder.next_uint(),
total_damage_dealt: decoder.next_uint(),
total_healing_done: decoder.next_uint(),
longest_kill_streak: decoder.next_uint(),
match_duration: decoder.next_float(),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
total_kills: decoder.next_field_diff(&obj.total_kills, |dec, &a| dec.next_uint_diff(a)),
total_deaths: decoder
.next_field_diff(&obj.total_deaths, |dec, &a| dec.next_uint_diff(a)),
total_damage_dealt: decoder
.next_field_diff(&obj.total_damage_dealt, |dec, &a| dec.next_uint_diff(a)),
total_healing_done: decoder
.next_field_diff(&obj.total_healing_done, |dec, &a| dec.next_uint_diff(a)),
longest_kill_streak: decoder
.next_field_diff(&obj.longest_kill_streak, |dec, &a| dec.next_uint_diff(a)),
match_duration: decoder
.next_field_diff(&obj.match_duration, |dec, &a| dec.next_float_diff(a)),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct TeamScore {
pub team: Team,
pub score: u64,
pub kills: u64,
#[serde(rename = "objectivesCaptured")]
pub objectives_captured: u64,
}
impl Default for TeamScore {
fn default() -> Self {
Self {
team: Team::default(),
score: 0,
kills: 0,
objectives_captured: 0,
}
}
}
impl TeamScore {
pub fn equals(&self, other: &Self) -> bool {
self.team == other.team
&& self.score == other.score
&& self.kills == other.kills
&& self.objectives_captured == other.objectives_captured
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_enum(self.team.to_u32(), 2);
encoder.push_uint(self.score);
encoder.push_uint(self.kills);
encoder.push_uint(self.objectives_captured);
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.team,
&b.team,
|x, y| x == y,
|enc, &a, &b| enc.push_enum_diff(a.to_u32(), b.to_u32(), 2),
);
encoder.push_field_diff(
&a.score,
&b.score,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.kills,
&b.kills,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.objectives_captured,
&b.objectives_captured,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
team: Team::from_u32(decoder.next_enum(2)),
score: decoder.next_uint(),
kills: decoder.next_uint(),
objectives_captured: decoder.next_uint(),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
team: decoder.next_field_diff(&obj.team, |dec, &a| {
Team::from_u32(dec.next_enum_diff(a.to_u32(), 2))
}),
score: decoder.next_field_diff(&obj.score, |dec, &a| dec.next_uint_diff(a)),
kills: decoder.next_field_diff(&obj.kills, |dec, &a| dec.next_uint_diff(a)),
objectives_captured: decoder
.next_field_diff(&obj.objectives_captured, |dec, &a| dec.next_uint_diff(a)),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GameSettings {
#[serde(rename = "maxPlayers")]
pub max_players: u64,
#[serde(rename = "friendlyFire")]
pub friendly_fire: bool,
#[serde(rename = "respawnDelay")]
pub respawn_delay: f32,
#[serde(rename = "roundTimeLimit")]
pub round_time_limit: u64,
#[serde(rename = "startingGold")]
pub starting_gold: u64,
#[serde(rename = "gravityMultiplier")]
pub gravity_multiplier: f32,
}
impl Default for GameSettings {
fn default() -> Self {
Self {
max_players: 0,
friendly_fire: false,
respawn_delay: 0.0,
round_time_limit: 0,
starting_gold: 0,
gravity_multiplier: 0.0,
}
}
}
impl GameSettings {
pub fn equals(&self, other: &Self) -> bool {
self.max_players == other.max_players
&& self.friendly_fire == other.friendly_fire
&& delta_pack::equals_float(self.respawn_delay, other.respawn_delay)
&& self.round_time_limit == other.round_time_limit
&& self.starting_gold == other.starting_gold
&& delta_pack::equals_float(self.gravity_multiplier, other.gravity_multiplier)
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_uint(self.max_players);
encoder.push_boolean(self.friendly_fire);
encoder.push_float(self.respawn_delay);
encoder.push_uint(self.round_time_limit);
encoder.push_uint(self.starting_gold);
encoder.push_float(self.gravity_multiplier);
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.max_players,
&b.max_players,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_boolean_diff(a.friendly_fire, b.friendly_fire);
encoder.push_field_diff(
&a.respawn_delay,
&b.respawn_delay,
|x, y| delta_pack::equals_float(*x, *y),
|enc, &a, &b| enc.push_float_diff(a, b),
);
encoder.push_field_diff(
&a.round_time_limit,
&b.round_time_limit,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.starting_gold,
&b.starting_gold,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.gravity_multiplier,
&b.gravity_multiplier,
|x, y| delta_pack::equals_float(*x, *y),
|enc, &a, &b| enc.push_float_diff(a, b),
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
max_players: decoder.next_uint(),
friendly_fire: decoder.next_boolean(),
respawn_delay: decoder.next_float(),
round_time_limit: decoder.next_uint(),
starting_gold: decoder.next_uint(),
gravity_multiplier: decoder.next_float(),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
max_players: decoder.next_field_diff(&obj.max_players, |dec, &a| dec.next_uint_diff(a)),
friendly_fire: decoder.next_boolean_diff(obj.friendly_fire),
respawn_delay: decoder
.next_field_diff(&obj.respawn_delay, |dec, &a| dec.next_float_diff(a)),
round_time_limit: decoder
.next_field_diff(&obj.round_time_limit, |dec, &a| dec.next_uint_diff(a)),
starting_gold: decoder
.next_field_diff(&obj.starting_gold, |dec, &a| dec.next_uint_diff(a)),
gravity_multiplier: decoder
.next_field_diff(&obj.gravity_multiplier, |dec, &a| dec.next_float_diff(a)),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GameState {
#[serde(rename = "gameId")]
pub game_id: String,
#[serde(rename = "serverTime")]
pub server_time: f32,
#[serde(rename = "tickNumber")]
pub tick_number: u64,
pub round: u64,
pub phase: String,
#[serde(rename = "timeRemaining")]
pub time_remaining: f32,
pub players: IndexMap<String, Player>,
pub enemies: IndexMap<String, Enemy>,
pub projectiles: IndexMap<String, Projectile>,
#[serde(rename = "droppedLoot")]
pub dropped_loot: IndexMap<String, DroppedLoot>,
#[serde(rename = "worldObjects")]
pub world_objects: IndexMap<String, WorldObject>,
#[serde(rename = "teamScores")]
pub team_scores: Vec<TeamScore>,
#[serde(rename = "matchStats")]
pub match_stats: MatchStats,
pub settings: GameSettings,
#[serde(rename = "winningTeam")]
pub winning_team: Option<Team>,
#[serde(rename = "mapName")]
pub map_name: String,
#[serde(rename = "weatherIntensity")]
pub weather_intensity: f32,
}
impl Default for GameState {
fn default() -> Self {
Self {
game_id: String::new(),
server_time: 0.0,
tick_number: 0,
round: 0,
phase: String::new(),
time_remaining: 0.0,
players: IndexMap::new(),
enemies: IndexMap::new(),
projectiles: IndexMap::new(),
dropped_loot: IndexMap::new(),
world_objects: IndexMap::new(),
team_scores: Vec::new(),
match_stats: MatchStats::default(),
settings: GameSettings::default(),
winning_team: None,
map_name: String::new(),
weather_intensity: 0.0,
}
}
}
impl GameState {
pub fn equals(&self, other: &Self) -> bool {
self.game_id == other.game_id
&& delta_pack::equals_float(self.server_time, other.server_time)
&& self.tick_number == other.tick_number
&& self.round == other.round
&& self.phase == other.phase
&& delta_pack::equals_float(self.time_remaining, other.time_remaining)
&& delta_pack::equals_record(&self.players, &other.players, |x, y| x.equals(y))
&& delta_pack::equals_record(&self.enemies, &other.enemies, |x, y| x.equals(y))
&& delta_pack::equals_record(&self.projectiles, &other.projectiles, |x, y| x.equals(y))
&& delta_pack::equals_record(&self.dropped_loot, &other.dropped_loot, |x, y| {
x.equals(y)
})
&& delta_pack::equals_record(&self.world_objects, &other.world_objects, |x, y| {
x.equals(y)
})
&& delta_pack::equals_array(&self.team_scores, &other.team_scores, |x, y| x.equals(y))
&& self.match_stats.equals(&other.match_stats)
&& self.settings.equals(&other.settings)
&& self.winning_team == other.winning_team
&& self.map_name == other.map_name
&& delta_pack::equals_float(self.weather_intensity, other.weather_intensity)
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_string(&self.game_id);
encoder.push_float(self.server_time);
encoder.push_uint(self.tick_number);
encoder.push_uint(self.round);
encoder.push_string(&self.phase);
encoder.push_float(self.time_remaining);
encoder.push_record(
&self.players,
|enc, item| enc.push_string(item),
|enc, item| item.encode_into(enc),
);
encoder.push_record(
&self.enemies,
|enc, item| enc.push_string(item),
|enc, item| item.encode_into(enc),
);
encoder.push_record(
&self.projectiles,
|enc, item| enc.push_string(item),
|enc, item| item.encode_into(enc),
);
encoder.push_record(
&self.dropped_loot,
|enc, item| enc.push_string(item),
|enc, item| item.encode_into(enc),
);
encoder.push_record(
&self.world_objects,
|enc, item| enc.push_string(item),
|enc, item| item.encode_into(enc),
);
encoder.push_array(&self.team_scores, |enc, item| item.encode_into(enc));
self.match_stats.encode_into(encoder);
self.settings.encode_into(encoder);
encoder.push_optional(&self.winning_team, |enc, &item| {
enc.push_enum(item.to_u32(), 2)
});
encoder.push_string(&self.map_name);
encoder.push_float(self.weather_intensity);
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.game_id,
&b.game_id,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.server_time,
&b.server_time,
|x, y| delta_pack::equals_float(*x, *y),
|enc, &a, &b| enc.push_float_diff(a, b),
);
encoder.push_field_diff(
&a.tick_number,
&b.tick_number,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.round,
&b.round,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.phase,
&b.phase,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.time_remaining,
&b.time_remaining,
|x, y| delta_pack::equals_float(*x, *y),
|enc, &a, &b| enc.push_float_diff(a, b),
);
encoder.push_field_diff(
&a.players,
&b.players,
|x, y| delta_pack::equals_record(&x, &y, |x, y| x.equals(y)),
|enc, a, b| {
enc.push_record_diff(
a,
b,
|x, y| x.equals(y),
|enc, item| enc.push_string(item),
|enc, item| item.encode_into(enc),
|enc, a, b| Player::encode_diff_into(a, b, enc),
)
},
);
encoder.push_field_diff(
&a.enemies,
&b.enemies,
|x, y| delta_pack::equals_record(&x, &y, |x, y| x.equals(y)),
|enc, a, b| {
enc.push_record_diff(
a,
b,
|x, y| x.equals(y),
|enc, item| enc.push_string(item),
|enc, item| item.encode_into(enc),
|enc, a, b| Enemy::encode_diff_into(a, b, enc),
)
},
);
encoder.push_field_diff(
&a.projectiles,
&b.projectiles,
|x, y| delta_pack::equals_record(&x, &y, |x, y| x.equals(y)),
|enc, a, b| {
enc.push_record_diff(
a,
b,
|x, y| x.equals(y),
|enc, item| enc.push_string(item),
|enc, item| item.encode_into(enc),
|enc, a, b| Projectile::encode_diff_into(a, b, enc),
)
},
);
encoder.push_field_diff(
&a.dropped_loot,
&b.dropped_loot,
|x, y| delta_pack::equals_record(&x, &y, |x, y| x.equals(y)),
|enc, a, b| {
enc.push_record_diff(
a,
b,
|x, y| x.equals(y),
|enc, item| enc.push_string(item),
|enc, item| item.encode_into(enc),
|enc, a, b| DroppedLoot::encode_diff_into(a, b, enc),
)
},
);
encoder.push_field_diff(
&a.world_objects,
&b.world_objects,
|x, y| delta_pack::equals_record(&x, &y, |x, y| x.equals(y)),
|enc, a, b| {
enc.push_record_diff(
a,
b,
|x, y| x.equals(y),
|enc, item| enc.push_string(item),
|enc, item| item.encode_into(enc),
|enc, a, b| WorldObject::encode_diff_into(a, b, enc),
)
},
);
encoder.push_field_diff(
&a.team_scores,
&b.team_scores,
|x, y| delta_pack::equals_array(&x, &y, |x, y| x.equals(y)),
|enc, a, b| {
enc.push_array_diff(
a,
b,
|x, y| x.equals(y),
|enc, item| item.encode_into(enc),
|enc, a, b| TeamScore::encode_diff_into(a, b, enc),
)
},
);
encoder.push_field_diff(
&a.match_stats,
&b.match_stats,
|x, y| x.equals(y),
|enc, a, b| MatchStats::encode_diff_into(a, b, enc),
);
encoder.push_field_diff(
&a.settings,
&b.settings,
|x, y| x.equals(y),
|enc, a, b| GameSettings::encode_diff_into(a, b, enc),
);
encoder.push_field_diff(
&a.winning_team,
&b.winning_team,
|x, y| x == y,
|enc, a, b| {
enc.push_optional_diff(
a,
b,
|enc, &item| enc.push_enum(item.to_u32(), 2),
|enc, &a, &b| enc.push_enum_diff(a.to_u32(), b.to_u32(), 2),
)
},
);
encoder.push_field_diff(
&a.map_name,
&b.map_name,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.weather_intensity,
&b.weather_intensity,
|x, y| delta_pack::equals_float(*x, *y),
|enc, &a, &b| enc.push_float_diff(a, b),
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
game_id: decoder.next_string(),
server_time: decoder.next_float(),
tick_number: decoder.next_uint(),
round: decoder.next_uint(),
phase: decoder.next_string(),
time_remaining: decoder.next_float(),
players: decoder.next_record(|dec| dec.next_string(), |dec| Player::decode_from(dec)),
enemies: decoder.next_record(|dec| dec.next_string(), |dec| Enemy::decode_from(dec)),
projectiles: decoder
.next_record(|dec| dec.next_string(), |dec| Projectile::decode_from(dec)),
dropped_loot: decoder
.next_record(|dec| dec.next_string(), |dec| DroppedLoot::decode_from(dec)),
world_objects: decoder
.next_record(|dec| dec.next_string(), |dec| WorldObject::decode_from(dec)),
team_scores: decoder.next_array(|dec| TeamScore::decode_from(dec)),
match_stats: MatchStats::decode_from(decoder),
settings: GameSettings::decode_from(decoder),
winning_team: decoder.next_optional(|dec| Team::from_u32(dec.next_enum(2))),
map_name: decoder.next_string(),
weather_intensity: decoder.next_float(),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
game_id: decoder.next_field_diff(&obj.game_id, |dec, a| dec.next_string_diff(a)),
server_time: decoder
.next_field_diff(&obj.server_time, |dec, &a| dec.next_float_diff(a)),
tick_number: decoder.next_field_diff(&obj.tick_number, |dec, &a| dec.next_uint_diff(a)),
round: decoder.next_field_diff(&obj.round, |dec, &a| dec.next_uint_diff(a)),
phase: decoder.next_field_diff(&obj.phase, |dec, a| dec.next_string_diff(a)),
time_remaining: decoder
.next_field_diff(&obj.time_remaining, |dec, &a| dec.next_float_diff(a)),
players: decoder.next_field_diff(&obj.players, |dec, a| {
dec.next_record_diff(
a,
|dec| dec.next_string(),
|dec| Player::decode_from(dec),
|dec, a| Player::decode_diff_from(a, dec),
)
}),
enemies: decoder.next_field_diff(&obj.enemies, |dec, a| {
dec.next_record_diff(
a,
|dec| dec.next_string(),
|dec| Enemy::decode_from(dec),
|dec, a| Enemy::decode_diff_from(a, dec),
)
}),
projectiles: decoder.next_field_diff(&obj.projectiles, |dec, a| {
dec.next_record_diff(
a,
|dec| dec.next_string(),
|dec| Projectile::decode_from(dec),
|dec, a| Projectile::decode_diff_from(a, dec),
)
}),
dropped_loot: decoder.next_field_diff(&obj.dropped_loot, |dec, a| {
dec.next_record_diff(
a,
|dec| dec.next_string(),
|dec| DroppedLoot::decode_from(dec),
|dec, a| DroppedLoot::decode_diff_from(a, dec),
)
}),
world_objects: decoder.next_field_diff(&obj.world_objects, |dec, a| {
dec.next_record_diff(
a,
|dec| dec.next_string(),
|dec| WorldObject::decode_from(dec),
|dec, a| WorldObject::decode_diff_from(a, dec),
)
}),
team_scores: decoder.next_field_diff(&obj.team_scores, |dec, a| {
dec.next_array_diff(
a,
|dec| TeamScore::decode_from(dec),
|dec, a| TeamScore::decode_diff_from(a, dec),
)
}),
match_stats: decoder.next_field_diff(&obj.match_stats, |dec, a| {
MatchStats::decode_diff_from(a, dec)
}),
settings: decoder.next_field_diff(&obj.settings, |dec, a| {
GameSettings::decode_diff_from(a, dec)
}),
winning_team: decoder.next_field_diff(&obj.winning_team, |dec, a| {
dec.next_optional_diff(
a,
|dec| Team::from_u32(dec.next_enum(2)),
|dec, &a| Team::from_u32(dec.next_enum_diff(a.to_u32(), 2)),
)
}),
map_name: decoder.next_field_diff(&obj.map_name, |dec, a| dec.next_string_diff(a)),
weather_intensity: decoder
.next_field_diff(&obj.weather_intensity, |dec, &a| dec.next_float_diff(a)),
}
}
}