aboutsummaryrefslogtreecommitdiff
path: root/azalea-protocol/src/mc_buf
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2022-06-23 15:12:17 -0500
committermat <github@matdoes.dev>2022-06-23 15:12:17 -0500
commit5ca49e680ed8519456dc9a9af84321d4b69dcbb3 (patch)
tree0f727c3e862f60eb227db69c87946a0f629a397d /azalea-protocol/src/mc_buf
parentc7b0c51274b5d8548c8a2f829b75dfbec4038be2 (diff)
downloadazalea-drasl-5ca49e680ed8519456dc9a9af84321d4b69dcbb3.tar.xz
azalea-buf
Diffstat (limited to 'azalea-protocol/src/mc_buf')
-rw-r--r--azalea-protocol/src/mc_buf/definitions.rs442
-rw-r--r--azalea-protocol/src/mc_buf/mod.rs233
-rw-r--r--azalea-protocol/src/mc_buf/read.rs525
-rw-r--r--azalea-protocol/src/mc_buf/write.rs430
4 files changed, 0 insertions, 1630 deletions
diff --git a/azalea-protocol/src/mc_buf/definitions.rs b/azalea-protocol/src/mc_buf/definitions.rs
deleted file mode 100644
index 3867b3fc..00000000
--- a/azalea-protocol/src/mc_buf/definitions.rs
+++ /dev/null
@@ -1,442 +0,0 @@
-use crate::mc_buf::read::{McBufReadable, Readable};
-use crate::mc_buf::write::{McBufWritable, Writable};
-use crate::mc_buf::McBufVarReadable;
-use azalea_chat::component::Component;
-use azalea_core::{BlockPos, Direction, Slot};
-use packet_macros::McBuf;
-use std::io::{Read, Write};
-use std::ops::Deref;
-use uuid::Uuid;
-
-/// A Vec<u8> that isn't prefixed by a VarInt with the size.
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct UnsizedByteArray(Vec<u8>);
-
-impl Deref for UnsizedByteArray {
- type Target = Vec<u8>;
-
- fn deref(&self) -> &Self::Target {
- &self.0
- }
-}
-
-impl From<Vec<u8>> for UnsizedByteArray {
- fn from(vec: Vec<u8>) -> Self {
- Self(vec)
- }
-}
-
-impl From<&str> for UnsizedByteArray {
- fn from(s: &str) -> Self {
- Self(s.as_bytes().to_vec())
- }
-}
-
-/// Represents Java's BitSet, a list of bits.
-#[derive(Debug, Clone, PartialEq, Eq, Hash, McBuf)]
-pub struct BitSet {
- data: Vec<u64>,
-}
-
-// the Index trait requires us to return a reference, but we can't do that
-impl BitSet {
- pub fn index(&self, index: usize) -> bool {
- (self.data[index / 64] & (1u64 << (index % 64))) != 0
- }
-}
-
-pub type EntityMetadata = Vec<EntityDataItem>;
-
-#[derive(Clone, Debug)]
-pub struct EntityDataItem {
- // we can't identify what the index is for here because we don't know the
- // entity type
- pub index: u8,
- pub value: EntityDataValue,
-}
-
-impl McBufReadable for Vec<EntityDataItem> {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- let mut metadata = Vec::new();
- loop {
- let index = buf.read_byte()?;
- if index == 0xff {
- break;
- }
- let value = EntityDataValue::read_into(buf)?;
- metadata.push(EntityDataItem { index, value });
- }
- Ok(metadata)
- }
-}
-
-impl McBufWritable for Vec<EntityDataItem> {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- for item in self {
- buf.write_byte(item.index)?;
- item.value.write_into(buf)?;
- }
- buf.write_byte(0xff)?;
- Ok(())
- }
-}
-
-#[derive(Clone, Debug)]
-pub enum EntityDataValue {
- Byte(u8),
- // varint
- Int(i32),
- Float(f32),
- String(String),
- Component(Component),
- OptionalComponent(Option<Component>),
- ItemStack(Slot),
- Boolean(bool),
- Rotations { x: f32, y: f32, z: f32 },
- BlockPos(BlockPos),
- OptionalBlockPos(Option<BlockPos>),
- Direction(Direction),
- OptionalUuid(Option<Uuid>),
- // 0 for absent (implies air); otherwise, a block state ID as per the global palette
- // this is a varint
- OptionalBlockState(Option<i32>),
- CompoundTag(azalea_nbt::Tag),
- Particle(Particle),
- VillagerData(VillagerData),
- // 0 for absent; 1 + actual value otherwise. Used for entity IDs.
- OptionalUnsignedInt(Option<u32>),
- Pose(Pose),
-}
-
-impl McBufReadable for EntityDataValue {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- let type_ = buf.read_varint()?;
- Ok(match type_ {
- 0 => EntityDataValue::Byte(buf.read_byte()?),
- 1 => EntityDataValue::Int(buf.read_varint()?),
- 2 => EntityDataValue::Float(buf.read_float()?),
- 3 => EntityDataValue::String(buf.read_utf()?),
- 4 => EntityDataValue::Component(Component::read_into(buf)?),
- 5 => EntityDataValue::OptionalComponent(Option::<Component>::read_into(buf)?),
- 6 => EntityDataValue::ItemStack(Slot::read_into(buf)?),
- 7 => EntityDataValue::Boolean(buf.read_boolean()?),
- 8 => EntityDataValue::Rotations {
- x: buf.read_float()?,
- y: buf.read_float()?,
- z: buf.read_float()?,
- },
- 9 => EntityDataValue::BlockPos(BlockPos::read_into(buf)?),
- 10 => EntityDataValue::OptionalBlockPos(Option::<BlockPos>::read_into(buf)?),
- 11 => EntityDataValue::Direction(Direction::read_into(buf)?),
- 12 => EntityDataValue::OptionalUuid(Option::<Uuid>::read_into(buf)?),
- 13 => EntityDataValue::OptionalBlockState({
- let val = i32::read_into(buf)?;
- if val == 0 {
- None
- } else {
- Some(val)
- }
- }),
- 14 => EntityDataValue::CompoundTag(azalea_nbt::Tag::read_into(buf)?),
- 15 => EntityDataValue::Particle(Particle::read_into(buf)?),
- 16 => EntityDataValue::VillagerData(VillagerData::read_into(buf)?),
- 17 => EntityDataValue::OptionalUnsignedInt({
- let val = buf.read_varint()?;
- if val == 0 {
- None
- } else {
- Some((val - 1) as u32)
- }
- }),
- 18 => EntityDataValue::Pose(Pose::read_into(buf)?),
- _ => return Err(format!("Unknown entity data type: {}", type_)),
- })
- }
-}
-
-impl McBufWritable for EntityDataValue {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- todo!();
- }
-}
-
-#[derive(Clone, Debug, Copy, McBuf)]
-pub enum Pose {
- Standing = 0,
- FallFlying = 1,
- Sleeping = 2,
- Swimming = 3,
- SpinAttack = 4,
- Sneaking = 5,
- LongJumping = 6,
- Dying = 7,
-}
-
-#[derive(Debug, Clone, McBuf)]
-pub struct VillagerData {
- #[var]
- type_: u32,
- #[var]
- profession: u32,
- #[var]
- level: u32,
-}
-
-#[derive(Debug, Clone, McBuf)]
-pub struct Particle {
- #[var]
- pub id: i32,
- pub data: ParticleData,
-}
-
-#[derive(Clone, Debug)]
-pub enum ParticleData {
- AmbientEntityEffect,
- AngryVillager,
- Block(BlockParticle),
- BlockMarker(BlockParticle),
- Bubble,
- Cloud,
- Crit,
- DamageIndicator,
- DragonBreath,
- DrippingLava,
- FallingLava,
- LandingLava,
- DrippingWater,
- FallingWater,
- Dust(DustParticle),
- DustColorTransition(DustColorTransitionParticle),
- Effect,
- ElderGuardian,
- EnchantedHit,
- Enchant,
- EndRod,
- EntityEffect,
- ExplosionEmitter,
- Explosion,
- FallingDust(BlockParticle),
- Firework,
- Fishing,
- Flame,
- SoulFireFlame,
- Soul,
- Flash,
- HappyVillager,
- Composter,
- Heart,
- InstantEffect,
- Item(ItemParticle),
- Vibration(VibrationParticle),
- ItemSlime,
- ItemSnowball,
- LargeSmoke,
- Lava,
- Mycelium,
- Note,
- Poof,
- Portal,
- Rain,
- Smoke,
- Sneeze,
- Spit,
- SquidInk,
- SweepAttack,
- TotemOfUndying,
- Underwater,
- Splash,
- Witch,
- BubblePop,
- CurrentDown,
- BubbleColumnUp,
- Nautilus,
- Dolphin,
- CampfireCozySmoke,
- CampfireSignalSmoke,
- DrippingHoney,
- FallingHoney,
- LandingHoney,
- FallingNectar,
- FallingSporeBlossom,
- Ash,
- CrimsonSpore,
- WarpedSpore,
- SporeBlossomAir,
- DrippingObsidianTear,
- FallingObsidianTear,
- LandingObsidianTear,
- ReversePortal,
- WhiteAsh,
- SmallFlame,
- Snowflake,
- DrippingDripstoneLava,
- FallingDripstoneLava,
- DrippingDripstoneWater,
- FallingDripstoneWater,
- GlowSquidInk,
- Glow,
- WaxOn,
- WaxOff,
- ElectricSpark,
- Scrape,
-}
-
-#[derive(Debug, Clone, McBuf)]
-pub struct BlockParticle {
- #[var]
- pub block_state: i32,
-}
-#[derive(Debug, Clone, McBuf)]
-pub struct DustParticle {
- /// Red value, 0-1
- pub red: f32,
- /// Green value, 0-1
- pub green: f32,
- /// Blue value, 0-1
- pub blue: f32,
- /// The scale, will be clamped between 0.01 and 4.
- pub scale: f32,
-}
-
-#[derive(Debug, Clone, McBuf)]
-pub struct DustColorTransitionParticle {
- /// Red value, 0-1
- pub from_red: f32,
- /// Green value, 0-1
- pub from_green: f32,
- /// Blue value, 0-1
- pub from_blue: f32,
- /// The scale, will be clamped between 0.01 and 4.
- pub scale: f32,
- /// Red value, 0-1
- pub to_red: f32,
- /// Green value, 0-1
- pub to_green: f32,
- /// Blue value, 0-1
- pub to_blue: f32,
-}
-
-#[derive(Debug, Clone, McBuf)]
-pub struct ItemParticle {
- pub item: Slot,
-}
-
-#[derive(Debug, Clone, McBuf)]
-pub struct VibrationParticle {
- pub origin: BlockPos,
- pub position_type: String,
- pub block_position: BlockPos,
- #[var]
- pub entity_id: u32,
- #[var]
- pub ticks: u32,
-}
-
-impl ParticleData {
- pub fn read_from_particle_id(buf: &mut impl Read, id: u32) -> Result<Self, String> {
- Ok(match id {
- 0 => ParticleData::AmbientEntityEffect,
- 1 => ParticleData::AngryVillager,
- 2 => ParticleData::Block(BlockParticle::read_into(buf)?),
- 3 => ParticleData::BlockMarker(BlockParticle::read_into(buf)?),
- 4 => ParticleData::Bubble,
- 5 => ParticleData::Cloud,
- 6 => ParticleData::Crit,
- 7 => ParticleData::DamageIndicator,
- 8 => ParticleData::DragonBreath,
- 9 => ParticleData::DrippingLava,
- 10 => ParticleData::FallingLava,
- 11 => ParticleData::LandingLava,
- 12 => ParticleData::DrippingWater,
- 13 => ParticleData::FallingWater,
- 14 => ParticleData::Dust(DustParticle::read_into(buf)?),
- 15 => ParticleData::DustColorTransition(DustColorTransitionParticle::read_into(buf)?),
- 16 => ParticleData::Effect,
- 17 => ParticleData::ElderGuardian,
- 18 => ParticleData::EnchantedHit,
- 19 => ParticleData::Enchant,
- 20 => ParticleData::EndRod,
- 21 => ParticleData::EntityEffect,
- 22 => ParticleData::ExplosionEmitter,
- 23 => ParticleData::Explosion,
- 24 => ParticleData::FallingDust(BlockParticle::read_into(buf)?),
- 25 => ParticleData::Firework,
- 26 => ParticleData::Fishing,
- 27 => ParticleData::Flame,
- 28 => ParticleData::SoulFireFlame,
- 29 => ParticleData::Soul,
- 30 => ParticleData::Flash,
- 31 => ParticleData::HappyVillager,
- 32 => ParticleData::Composter,
- 33 => ParticleData::Heart,
- 34 => ParticleData::InstantEffect,
- 35 => ParticleData::Item(ItemParticle::read_into(buf)?),
- 36 => ParticleData::Vibration(VibrationParticle::read_into(buf)?),
- 37 => ParticleData::ItemSlime,
- 38 => ParticleData::ItemSnowball,
- 39 => ParticleData::LargeSmoke,
- 40 => ParticleData::Lava,
- 41 => ParticleData::Mycelium,
- 42 => ParticleData::Note,
- 43 => ParticleData::Poof,
- 44 => ParticleData::Portal,
- 45 => ParticleData::Rain,
- 46 => ParticleData::Smoke,
- 47 => ParticleData::Sneeze,
- 48 => ParticleData::Spit,
- 49 => ParticleData::SquidInk,
- 50 => ParticleData::SweepAttack,
- 51 => ParticleData::TotemOfUndying,
- 52 => ParticleData::Underwater,
- 53 => ParticleData::Splash,
- 54 => ParticleData::Witch,
- 55 => ParticleData::BubblePop,
- 56 => ParticleData::CurrentDown,
- 57 => ParticleData::BubbleColumnUp,
- 58 => ParticleData::Nautilus,
- 59 => ParticleData::Dolphin,
- 60 => ParticleData::CampfireCozySmoke,
- 61 => ParticleData::CampfireSignalSmoke,
- 62 => ParticleData::DrippingHoney,
- 63 => ParticleData::FallingHoney,
- 64 => ParticleData::LandingHoney,
- 65 => ParticleData::FallingNectar,
- 66 => ParticleData::FallingSporeBlossom,
- 67 => ParticleData::Ash,
- 68 => ParticleData::CrimsonSpore,
- 69 => ParticleData::WarpedSpore,
- 70 => ParticleData::SporeBlossomAir,
- 71 => ParticleData::DrippingObsidianTear,
- 72 => ParticleData::FallingObsidianTear,
- 73 => ParticleData::LandingObsidianTear,
- 74 => ParticleData::ReversePortal,
- 75 => ParticleData::WhiteAsh,
- 76 => ParticleData::SmallFlame,
- 77 => ParticleData::Snowflake,
- 78 => ParticleData::DrippingDripstoneLava,
- 79 => ParticleData::FallingDripstoneLava,
- 80 => ParticleData::DrippingDripstoneWater,
- 81 => ParticleData::FallingDripstoneWater,
- 82 => ParticleData::GlowSquidInk,
- 83 => ParticleData::Glow,
- 84 => ParticleData::WaxOn,
- 85 => ParticleData::WaxOff,
- 86 => ParticleData::ElectricSpark,
- 87 => ParticleData::Scrape,
- _ => return Err(format!("Unknown particle id: {}", id)),
- })
- }
-}
-
-impl McBufReadable for ParticleData {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- let id = u32::var_read_into(buf)?;
- ParticleData::read_from_particle_id(buf, id)
- }
-}
-
-impl McBufWritable for ParticleData {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- todo!()
- }
-}
diff --git a/azalea-protocol/src/mc_buf/mod.rs b/azalea-protocol/src/mc_buf/mod.rs
deleted file mode 100644
index 548ba7c2..00000000
--- a/azalea-protocol/src/mc_buf/mod.rs
+++ /dev/null
@@ -1,233 +0,0 @@
-//! Utilities for reading and writing for the Minecraft protocol
-
-mod definitions;
-mod read;
-mod write;
-
-pub use definitions::{BitSet, EntityMetadata, ParticleData, UnsizedByteArray};
-pub use read::{read_varint_async, McBufReadable, McBufVarReadable, Readable};
-pub use write::{McBufVarWritable, McBufWritable, Writable};
-
-// const DEFAULT_NBT_QUOTA: u32 = 2097152;
-const MAX_STRING_LENGTH: u16 = 32767;
-// const MAX_COMPONENT_STRING_LENGTH: u32 = 262144;
-
-// TODO: maybe get rid of the readable/writable traits so there's not two ways to do the same thing and improve McBufReadable/McBufWritable
-
-// TODO: have a definitions.rs in mc_buf that contains UnsizedByteArray and BitSet
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use azalea_core::resource_location::ResourceLocation;
- use std::{collections::HashMap, io::Cursor};
-
- #[test]
- fn test_write_varint() {
- let mut buf = Vec::new();
- buf.write_varint(0).unwrap();
- assert_eq!(buf, vec![0]);
-
- let mut buf = Vec::new();
- buf.write_varint(1).unwrap();
- assert_eq!(buf, vec![1]);
-
- let mut buf = Vec::new();
- buf.write_varint(2).unwrap();
- assert_eq!(buf, vec![2]);
-
- let mut buf = Vec::new();
- buf.write_varint(127).unwrap();
- assert_eq!(buf, vec![127]);
-
- let mut buf = Vec::new();
- buf.write_varint(128).unwrap();
- assert_eq!(buf, vec![128, 1]);
-
- let mut buf = Vec::new();
- buf.write_varint(255).unwrap();
- assert_eq!(buf, vec![255, 1]);
-
- let mut buf = Vec::new();
- buf.write_varint(25565).unwrap();
- assert_eq!(buf, vec![221, 199, 1]);
-
- let mut buf = Vec::new();
- buf.write_varint(2097151).unwrap();
- assert_eq!(buf, vec![255, 255, 127]);
-
- let mut buf = Vec::new();
- buf.write_varint(2147483647).unwrap();
- assert_eq!(buf, vec![255, 255, 255, 255, 7]);
-
- let mut buf = Vec::new();
- buf.write_varint(-1).unwrap();
- assert_eq!(buf, vec![255, 255, 255, 255, 15]);
-
- let mut buf = Vec::new();
- buf.write_varint(-2147483648).unwrap();
- assert_eq!(buf, vec![128, 128, 128, 128, 8]);
- }
-
- #[test]
- fn test_read_varint() {
- let mut buf = Cursor::new(vec![0]);
- assert_eq!(buf.read_varint().unwrap(), 0);
- assert_eq!(buf.get_varint_size(0), 1);
-
- let mut buf = Cursor::new(vec![1]);
- assert_eq!(buf.read_varint().unwrap(), 1);
- assert_eq!(buf.get_varint_size(1), 1);
-
- let mut buf = Cursor::new(vec![2]);
- assert_eq!(buf.read_varint().unwrap(), 2);
- assert_eq!(buf.get_varint_size(2), 1);
-
- let mut buf = Cursor::new(vec![127]);
- assert_eq!(buf.read_varint().unwrap(), 127);
- assert_eq!(buf.get_varint_size(127), 1);
-
- let mut buf = Cursor::new(vec![128, 1]);
- assert_eq!(buf.read_varint().unwrap(), 128);
- assert_eq!(buf.get_varint_size(128), 2);
-
- let mut buf = Cursor::new(vec![255, 1]);
- assert_eq!(buf.read_varint().unwrap(), 255);
- assert_eq!(buf.get_varint_size(255), 2);
-
- let mut buf = Cursor::new(vec![221, 199, 1]);
- assert_eq!(buf.read_varint().unwrap(), 25565);
- assert_eq!(buf.get_varint_size(25565), 3);
-
- let mut buf = Cursor::new(vec![255, 255, 127]);
- assert_eq!(buf.read_varint().unwrap(), 2097151);
- assert_eq!(buf.get_varint_size(2097151), 3);
-
- let mut buf = Cursor::new(vec![255, 255, 255, 255, 7]);
- assert_eq!(buf.read_varint().unwrap(), 2147483647);
- assert_eq!(buf.get_varint_size(2147483647), 5);
-
- let mut buf = Cursor::new(vec![255, 255, 255, 255, 15]);
- assert_eq!(buf.read_varint().unwrap(), -1);
- assert_eq!(buf.get_varint_size(-1), 5);
-
- let mut buf = Cursor::new(vec![128, 128, 128, 128, 8]);
- assert_eq!(buf.read_varint().unwrap(), -2147483648);
- assert_eq!(buf.get_varint_size(-2147483648), 5);
- }
-
- #[test]
- fn test_read_varint_longer() {
- let mut buf = Cursor::new(vec![138, 56, 0, 135, 56, 123]);
- assert_eq!(buf.read_varint().unwrap(), 7178);
- }
-
- #[test]
- fn test_list() {
- let mut buf = Vec::new();
- buf.write_list(&vec!["a", "bc", "def"], |buf, s| buf.write_utf(s))
- .unwrap();
-
- // there's no read_list because idk how to do it in rust
- let mut buf = Cursor::new(buf);
-
- let mut result = Vec::new();
- let length = buf.read_varint().unwrap();
- for _ in 0..length {
- result.push(buf.read_utf().unwrap());
- }
-
- assert_eq!(result, vec!["a", "bc", "def"]);
- }
-
- #[test]
- fn test_int_id_list() {
- let mut buf = Vec::new();
- buf.write_list(&vec![1, 2, 3], |buf, i| buf.write_varint(*i))
- .unwrap();
-
- let mut buf = Cursor::new(buf);
-
- let result = buf.read_int_id_list().unwrap();
- assert_eq!(result, vec![1, 2, 3]);
- }
-
- #[test]
- fn test_map() {
- let mut buf = Vec::new();
- buf.write_map(
- vec![("a", 1), ("bc", 23), ("def", 456)],
- Vec::write_utf,
- Vec::write_varint,
- )
- .unwrap();
-
- let mut buf = Cursor::new(buf);
-
- let mut result = Vec::new();
- let length = buf.read_varint().unwrap();
- for _ in 0..length {
- result.push((buf.read_utf().unwrap(), buf.read_varint().unwrap()));
- }
-
- assert_eq!(
- result,
- vec![
- ("a".to_string(), 1),
- ("bc".to_string(), 23),
- ("def".to_string(), 456)
- ]
- );
- }
-
- #[test]
- fn test_nbt() {
- let mut buf = Vec::new();
- buf.write_nbt(&azalea_nbt::Tag::Compound(HashMap::from_iter(vec![(
- "hello world".to_string(),
- azalea_nbt::Tag::Compound(HashMap::from_iter(vec![(
- "name".to_string(),
- azalea_nbt::Tag::String("Bananrama".to_string()),
- )])),
- )])))
- .unwrap();
-
- let mut buf = Cursor::new(buf);
-
- let result = buf.read_nbt().unwrap();
- assert_eq!(
- result,
- azalea_nbt::Tag::Compound(HashMap::from_iter(vec![(
- "hello world".to_string(),
- azalea_nbt::Tag::Compound(HashMap::from_iter(vec![(
- "name".to_string(),
- azalea_nbt::Tag::String("Bananrama".to_string()),
- )])),
- )]))
- );
- }
-
- #[test]
- fn test_long() {
- let mut buf = Vec::new();
- buf.write_long(123456).unwrap();
-
- let mut buf = Cursor::new(buf);
-
- assert_eq!(buf.read_long().unwrap(), 123456);
- }
-
- #[test]
- fn test_resource_location() {
- let mut buf = Vec::new();
- buf.write_resource_location(&ResourceLocation::new("minecraft:dirt").unwrap())
- .unwrap();
-
- let mut buf = Cursor::new(buf);
-
- assert_eq!(
- buf.read_resource_location().unwrap(),
- ResourceLocation::new("minecraft:dirt").unwrap()
- );
- }
-}
diff --git a/azalea-protocol/src/mc_buf/read.rs b/azalea-protocol/src/mc_buf/read.rs
deleted file mode 100644
index ac8d5ccb..00000000
--- a/azalea-protocol/src/mc_buf/read.rs
+++ /dev/null
@@ -1,525 +0,0 @@
-use super::{UnsizedByteArray, MAX_STRING_LENGTH};
-use azalea_chat::component::Component;
-use azalea_core::{
- difficulty::Difficulty, game_type::GameType, resource_location::ResourceLocation,
- serializable_uuid::SerializableUuid, BlockPos, ChunkSectionPos, Direction, GlobalPos, Slot,
- SlotData,
-};
-use azalea_crypto::SaltSignaturePair;
-use byteorder::{ReadBytesExt, BE};
-use serde::Deserialize;
-use std::{collections::HashMap, hash::Hash, io::Read};
-use tokio::io::{AsyncRead, AsyncReadExt};
-use uuid::Uuid;
-
-pub trait Readable {
- fn read_int_id_list(&mut self) -> Result<Vec<i32>, String>;
- fn read_varint(&mut self) -> Result<i32, String>;
- fn get_varint_size(&mut self, value: i32) -> u8;
- fn get_varlong_size(&mut self, value: i32) -> u8;
- fn read_byte_array(&mut self) -> Result<Vec<u8>, String>;
- fn read_bytes_with_len(&mut self, n: usize) -> Result<Vec<u8>, String>;
- fn read_bytes(&mut self) -> Result<Vec<u8>, String>;
- fn read_utf(&mut self) -> Result<String, String>;
- fn read_utf_with_len(&mut self, max_length: u32) -> Result<String, String>;
- fn read_byte(&mut self) -> Result<u8, String>;
- fn read_int(&mut self) -> Result<i32, String>;
- fn read_boolean(&mut self) -> Result<bool, String>;
- fn read_nbt(&mut self) -> Result<azalea_nbt::Tag, String>;
- fn read_long(&mut self) -> Result<i64, String>;
- fn read_resource_location(&mut self) -> Result<ResourceLocation, String>;
- fn read_short(&mut self) -> Result<i16, String>;
- fn read_float(&mut self) -> Result<f32, String>;
- fn read_double(&mut self) -> Result<f64, String>;
- fn read_uuid(&mut self) -> Result<Uuid, String>;
-}
-
-impl<R> Readable for R
-where
- R: Read,
-{
- fn read_int_id_list(&mut self) -> Result<Vec<i32>, String> {
- let len = self.read_varint()?;
- let mut list = Vec::with_capacity(len as usize);
- for _ in 0..len {
- list.push(self.read_varint()?);
- }
- Ok(list)
- }
-
- // fast varints modified from https://github.com/luojia65/mc-varint/blob/master/src/lib.rs#L67
- /// Read a single varint from the reader and return the value, along with the number of bytes read
- fn read_varint(&mut self) -> Result<i32, String> {
- let mut buffer = [0];
- let mut ans = 0;
- for i in 0..5 {
- self.read_exact(&mut buffer)
- .map_err(|_| "Invalid VarInt".to_string())?;
- ans |= ((buffer[0] & 0b0111_1111) as i32) << (7 * i);
- if buffer[0] & 0b1000_0000 == 0 {
- return Ok(ans);
- }
- }
- Ok(ans)
- }
-
- fn get_varint_size(&mut self, value: i32) -> u8 {
- for i in 1..5 {
- if (value & -1 << (i * 7)) != 0 {
- continue;
- }
- return i;
- }
- 5
- }
-
- fn get_varlong_size(&mut self, value: i32) -> u8 {
- for i in 1..10 {
- if (value & -1 << (i * 7)) != 0 {
- continue;
- }
- return i;
- }
- 10
- }
-
- fn read_byte_array(&mut self) -> Result<Vec<u8>, String> {
- let length = self.read_varint()? as usize;
- self.read_bytes_with_len(length)
- }
-
- fn read_bytes_with_len(&mut self, n: usize) -> Result<Vec<u8>, String> {
- let mut buffer = vec![0; n];
- self.read_exact(&mut buffer)
- .map_err(|_| "Error reading bytes".to_string())?;
- Ok(buffer)
- }
-
- fn read_bytes(&mut self) -> Result<Vec<u8>, String> {
- // read to end of the buffer
- let mut bytes = vec![];
- self.read_to_end(&mut bytes)
- .map_err(|_| "Error reading bytes".to_string())?;
- Ok(bytes)
- }
-
- fn read_utf(&mut self) -> Result<String, String> {
- self.read_utf_with_len(MAX_STRING_LENGTH.into())
- }
-
- fn read_utf_with_len(&mut self, max_length: u32) -> Result<String, String> {
- let length = self.read_varint()?;
- // i don't know why it's multiplied by 4 but it's like that in mojang's code so
- if length < 0 {
- return Err(
- "The received encoded string buffer length is less than zero! Weird string!"
- .to_string(),
- );
- }
- if length as u32 > max_length * 4 {
- return Err(format!(
- "The received encoded string buffer length is longer than maximum allowed ({} > {})",
- length,
- max_length * 4
- ));
- }
-
- // this is probably quite inefficient, idk how to do it better
- let mut string = String::new();
- let mut buffer = vec![0; length as usize];
- self.read_exact(&mut buffer)
- .map_err(|_| "Invalid UTF-8".to_string())?;
- string.push_str(std::str::from_utf8(&buffer).unwrap());
- if string.len() > length as usize {
- return Err(format!(
- "The received string length is longer than maximum allowed ({} > {})",
- length, max_length
- ));
- }
-
- Ok(string)
- }
-
- /// Read a single byte from the reader
- fn read_byte(&mut self) -> Result<u8, String> {
- self.read_u8().map_err(|_| "Error reading byte".to_string())
- }
-
- fn read_int(&mut self) -> Result<i32, String> {
- match self.read_i32::<BE>() {
- Ok(r) => Ok(r),
- Err(_) => Err("Error reading int".to_string()),
- }
- }
-
- fn read_boolean(&mut self) -> Result<bool, String> {
- match self.read_byte()? {
- 0 => Ok(false),
- 1 => Ok(true),
- _ => Err("Error reading boolean".to_string()),
- }
- }
-
- fn read_nbt(&mut self) -> Result<azalea_nbt::Tag, String> {
- match azalea_nbt::Tag::read(self) {
- Ok(r) => Ok(r),
- // Err(e) => Err(e.to_string()),
- Err(e) => Err(e.to_string()).unwrap(),
- }
- }
-
- fn read_long(&mut self) -> Result<i64, String> {
- match self.read_i64::<BE>() {
- Ok(r) => Ok(r),
- Err(_) => Err("Error reading long".to_string()),
- }
- }
-
- fn read_resource_location(&mut self) -> Result<ResourceLocation, String> {
- // get the resource location from the string
- let location_string = self.read_utf()?;
- let location = ResourceLocation::new(&location_string)?;
- Ok(location)
- }
-
- fn read_short(&mut self) -> Result<i16, String> {
- match self.read_i16::<BE>() {
- Ok(r) => Ok(r),
- Err(_) => Err("Error reading short".to_string()),
- }
- }
-
- fn read_float(&mut self) -> Result<f32, String> {
- match self.read_f32::<BE>() {
- Ok(r) => Ok(r),
- Err(_) => Err("Error reading float".to_string()),
- }
- }
-
- fn read_double(&mut self) -> Result<f64, String> {
- match self.read_f64::<BE>() {
- Ok(r) => Ok(r),
- Err(_) => Err("Error reading double".to_string()),
- }
- }
-
- fn read_uuid(&mut self) -> Result<Uuid, String> {
- Ok(Uuid::from_int_array([
- Readable::read_int(self)? as u32,
- Readable::read_int(self)? as u32,
- Readable::read_int(self)? as u32,
- Readable::read_int(self)? as u32,
- ]))
- }
-}
-
-// fast varints modified from https://github.com/luojia65/mc-varint/blob/master/src/lib.rs#L67
-/// Read a single varint from the reader and return the value, along with the number of bytes read
-pub async fn read_varint_async(reader: &mut (dyn AsyncRead + Unpin + Send)) -> Result<i32, String> {
- let mut buffer = [0];
- let mut ans = 0;
- for i in 0..5 {
- reader
- .read_exact(&mut buffer)
- .await
- .map_err(|_| "Invalid VarInt".to_string())?;
- ans |= ((buffer[0] & 0b0111_1111) as i32) << (7 * i);
- if buffer[0] & 0b1000_0000 == 0 {
- return Ok(ans);
- }
- }
- Ok(ans)
-}
-
-pub trait McBufReadable
-where
- Self: Sized,
-{
- fn read_into(buf: &mut impl Read) -> Result<Self, String>;
-}
-
-pub trait McBufVarReadable
-where
- Self: Sized,
-{
- fn var_read_into(buf: &mut impl Read) -> Result<Self, String>;
-}
-
-impl McBufReadable for i32 {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- Readable::read_int(buf)
- }
-}
-
-impl McBufVarReadable for i32 {
- fn var_read_into(buf: &mut impl Read) -> Result<Self, String> {
- buf.read_varint()
- }
-}
-
-impl McBufVarReadable for i64 {
- // fast varints modified from https://github.com/luojia65/mc-varint/blob/master/src/lib.rs#L54
- fn var_read_into(buf: &mut impl Read) -> Result<Self, String> {
- let mut buffer = [0];
- let mut ans = 0;
- for i in 0..8 {
- buf.read_exact(&mut buffer)
- .map_err(|_| "Invalid VarLong".to_string())?;
- ans |= ((buffer[0] & 0b0111_1111) as i64) << 7 * i;
- if buffer[0] & 0b1000_0000 == 0 {
- break;
- }
- }
- Ok(ans)
- }
-}
-impl McBufVarReadable for u64 {
- fn var_read_into(buf: &mut impl Read) -> Result<Self, String> {
- i64::var_read_into(buf).map(|i| i as u64)
- }
-}
-
-impl McBufReadable for UnsizedByteArray {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- Ok(buf.read_bytes()?.into())
- }
-}
-
-impl<T: McBufReadable + Send> McBufReadable for Vec<T> {
- default fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- let length = buf.read_varint()? as usize;
- let mut contents = Vec::with_capacity(length);
- for _ in 0..length {
- contents.push(T::read_into(buf)?);
- }
- Ok(contents)
- }
-}
-
-impl<K: McBufReadable + Send + Eq + Hash, V: McBufReadable + Send> McBufReadable for HashMap<K, V> {
- default fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- let length = buf.read_varint()? as usize;
- let mut contents = HashMap::with_capacity(length);
- for _ in 0..length {
- contents.insert(K::read_into(buf)?, V::read_into(buf)?);
- }
- Ok(contents)
- }
-}
-
-impl McBufReadable for Vec<u8> {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- buf.read_byte_array()
- }
-}
-
-impl McBufReadable for String {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- buf.read_utf()
- }
-}
-
-impl McBufReadable for ResourceLocation {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- buf.read_resource_location()
- }
-}
-
-impl McBufReadable for u32 {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- Readable::read_int(buf).map(|i| i as u32)
- }
-}
-
-impl McBufVarReadable for u32 {
- fn var_read_into(buf: &mut impl Read) -> Result<Self, String> {
- buf.read_varint().map(|i| i as u32)
- }
-}
-
-impl McBufReadable for u16 {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- buf.read_short().map(|i| i as u16)
- }
-}
-
-impl McBufReadable for i16 {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- buf.read_short()
- }
-}
-
-impl McBufVarReadable for u16 {
- fn var_read_into(buf: &mut impl Read) -> Result<Self, String> {
- buf.read_varint().map(|i| i as u16)
- }
-}
-
-impl<T: McBufVarReadable> McBufVarReadable for Vec<T> {
- fn var_read_into(buf: &mut impl Read) -> Result<Self, String> {
- let length = buf.read_varint()? as usize;
- let mut contents = Vec::with_capacity(length);
- for _ in 0..length {
- contents.push(T::var_read_into(buf)?);
- }
- Ok(contents)
- }
-}
-
-impl McBufReadable for i64 {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- buf.read_long()
- }
-}
-
-impl McBufReadable for u64 {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- i64::read_into(buf).map(|i| i as u64)
- }
-}
-
-impl McBufReadable for bool {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- buf.read_boolean()
- }
-}
-
-impl McBufReadable for u8 {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- buf.read_byte()
- }
-}
-
-impl McBufReadable for i8 {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- buf.read_byte().map(|i| i as i8)
- }
-}
-
-impl McBufReadable for f32 {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- buf.read_float()
- }
-}
-
-impl McBufReadable for f64 {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- buf.read_double()
- }
-}
-
-impl McBufReadable for GameType {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- GameType::from_id(buf.read_byte()?)
- }
-}
-
-impl McBufReadable for Option<GameType> {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- GameType::from_optional_id(buf.read_byte()? as i8)
- }
-}
-
-impl<T: McBufReadable> McBufReadable for Option<T> {
- default fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- let present = buf.read_boolean()?;
- Ok(if present {
- Some(T::read_into(buf)?)
- } else {
- None
- })
- }
-}
-
-impl McBufReadable for azalea_nbt::Tag {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- buf.read_nbt()
- }
-}
-
-impl McBufReadable for Difficulty {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- Ok(Difficulty::by_id(u8::read_into(buf)?))
- }
-}
-
-impl McBufReadable for Component {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- let string = buf.read_utf()?;
- let json: serde_json::Value = serde_json::from_str(string.as_str())
- .map_err(|_| "Component isn't valid JSON".to_string())?;
- let component = Component::deserialize(json).map_err(|e| e.to_string())?;
- Ok(component)
- }
-}
-
-impl McBufReadable for Slot {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- let present = buf.read_boolean()?;
- if !present {
- return Ok(Slot::Empty);
- }
- let id = buf.read_varint()?;
- let count = buf.read_byte()?;
- let nbt = buf.read_nbt()?;
- Ok(Slot::Present(SlotData { id, count, nbt }))
- }
-}
-
-impl McBufReadable for Uuid {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- buf.read_uuid()
- }
-}
-
-impl McBufReadable for BlockPos {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- let val = u64::read_into(buf)?;
- let x = (val >> 38) as i32;
- let y = (val & 0xFFF) as i32;
- let z = ((val >> 12) & 0x3FFFFFF) as i32;
- Ok(BlockPos { x, y, z })
- }
-}
-
-impl McBufReadable for GlobalPos {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- Ok(GlobalPos {
- dimension: ResourceLocation::read_into(buf)?,
- pos: BlockPos::read_into(buf)?,
- })
- }
-}
-
-impl McBufReadable for Direction {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- match buf.read_varint()? {
- 0 => Ok(Self::Down),
- 1 => Ok(Self::Up),
- 2 => Ok(Self::North),
- 3 => Ok(Self::South),
- 4 => Ok(Self::West),
- 5 => Ok(Self::East),
- _ => Err("Invalid direction".to_string()),
- }
- }
-}
-
-impl McBufReadable for ChunkSectionPos {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- let long = i64::read_into(buf)?;
- Ok(ChunkSectionPos {
- x: (long >> 42) as i32,
- y: (long << 44 >> 44) as i32,
- z: (long << 22 >> 42) as i32,
- })
- }
-}
-
-impl McBufReadable for SaltSignaturePair {
- fn read_into(buf: &mut impl Read) -> Result<Self, String> {
- let salt = u64::read_into(buf)?;
- let signature = Vec::<u8>::read_into(buf)?;
- Ok(SaltSignaturePair { salt, signature })
- }
-}
diff --git a/azalea-protocol/src/mc_buf/write.rs b/azalea-protocol/src/mc_buf/write.rs
deleted file mode 100644
index 945477d0..00000000
--- a/azalea-protocol/src/mc_buf/write.rs
+++ /dev/null
@@ -1,430 +0,0 @@
-use super::{UnsizedByteArray, MAX_STRING_LENGTH};
-use azalea_chat::component::Component;
-use azalea_core::{
- difficulty::Difficulty, game_type::GameType, resource_location::ResourceLocation,
- serializable_uuid::SerializableUuid, BlockPos, ChunkSectionPos, Direction, GlobalPos, Slot,
-};
-use azalea_crypto::SaltSignaturePair;
-use byteorder::{BigEndian, WriteBytesExt};
-use std::{collections::HashMap, io::Write};
-use uuid::Uuid;
-
-pub trait Writable: Write {
- fn write_list<F, T>(&mut self, list: &[T], writer: F) -> Result<(), std::io::Error>
- where
- F: FnOnce(&mut Self, &T) -> Result<(), std::io::Error> + Copy,
- {
- self.write_varint(list.len() as i32)?;
- for item in list {
- writer(self, item)?;
- }
- Ok(())
- }
-
- fn write_int_id_list(&mut self, list: &[i32]) -> Result<(), std::io::Error> {
- self.write_list(list, |buf, n| buf.write_varint(*n))
- }
-
- fn write_map<KF, VF, KT, VT>(
- &mut self,
- map: Vec<(KT, VT)>,
- key_writer: KF,
- value_writer: VF,
- ) -> Result<(), std::io::Error>
- where
- KF: Fn(&mut Self, KT) -> Result<(), std::io::Error> + Copy,
- VF: Fn(&mut Self, VT) -> Result<(), std::io::Error> + Copy,
- {
- self.write_varint(map.len() as i32)?;
- for (key, value) in map {
- key_writer(self, key)?;
- value_writer(self, value)?;
- }
- Ok(())
- }
-
- fn write_byte(&mut self, n: u8) -> Result<(), std::io::Error> {
- WriteBytesExt::write_u8(self, n)
- }
-
- fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), std::io::Error> {
- self.write_all(bytes)?;
- Ok(())
- }
-
- fn write_varint(&mut self, mut value: i32) -> Result<(), std::io::Error> {
- let mut buffer = [0];
- if value == 0 {
- self.write_all(&buffer).unwrap();
- }
- while value != 0 {
- buffer[0] = (value & 0b0111_1111) as u8;
- value = (value >> 7) & (i32::max_value() >> 6);
- if value != 0 {
- buffer[0] |= 0b1000_0000;
- }
- self.write_all(&buffer)?;
- }
- Ok(())
- }
-
- fn write_utf_with_len(&mut self, string: &str, len: usize) -> Result<(), std::io::Error> {
- if string.len() > len {
- panic!(
- "String too big (was {} bytes encoded, max {})",
- string.len(),
- len
- );
- }
- self.write_varint(string.len() as i32)?;
- self.write_bytes(string.as_bytes())
- }
-
- fn write_utf(&mut self, string: &str) -> Result<(), std::io::Error> {
- self.write_utf_with_len(string, MAX_STRING_LENGTH.into())
- }
-
- fn write_short(&mut self, n: i16) -> Result<(), std::io::Error> {
- WriteBytesExt::write_i16::<BigEndian>(self, n)
- }
-
- fn write_byte_array(&mut self, bytes: &[u8]) -> Result<(), std::io::Error> {
- self.write_varint(bytes.len() as i32)?;
- self.write_bytes(bytes)
- }
-
- fn write_int(&mut self, n: i32) -> Result<(), std::io::Error> {
- WriteBytesExt::write_i32::<BigEndian>(self, n)
- }
-
- fn write_boolean(&mut self, b: bool) -> Result<(), std::io::Error> {
- self.write_byte(if b { 1 } else { 0 })
- }
-
- fn write_nbt(&mut self, nbt: &azalea_nbt::Tag) -> Result<(), std::io::Error>
- where
- Self: Sized,
- {
- nbt.write(self)
- .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))
- }
-
- fn write_long(&mut self, n: i64) -> Result<(), std::io::Error> {
- WriteBytesExt::write_i64::<BigEndian>(self, n)
- }
-
- fn write_float(&mut self, n: f32) -> Result<(), std::io::Error> {
- WriteBytesExt::write_f32::<BigEndian>(self, n)
- }
-
- fn write_double(&mut self, n: f64) -> Result<(), std::io::Error> {
- WriteBytesExt::write_f64::<BigEndian>(self, n)
- }
-
- fn write_resource_location(
- &mut self,
- location: &ResourceLocation,
- ) -> Result<(), std::io::Error> {
- self.write_utf(&location.to_string())
- }
-
- fn write_uuid(&mut self, uuid: &Uuid) -> Result<(), std::io::Error>
- where
- Self: Sized,
- {
- let [a, b, c, d] = uuid.to_int_array();
- a.write_into(self)?;
- b.write_into(self)?;
- c.write_into(self)?;
- d.write_into(self)?;
- Ok(())
- }
-}
-
-impl<W: Write + ?Sized> Writable for W {}
-
-pub trait McBufWritable {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error>;
-}
-
-pub trait McBufVarWritable {
- fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error>;
-}
-
-impl McBufWritable for i32 {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- Writable::write_int(buf, *self)
- }
-}
-
-impl McBufVarWritable for i32 {
- fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- buf.write_varint(*self)
- }
-}
-
-impl McBufWritable for UnsizedByteArray {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- buf.write_bytes(self)
- }
-}
-
-impl<T: McBufWritable> McBufWritable for Vec<T> {
- default fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- buf.write_list(self, |buf, i| T::write_into(i, buf))
- }
-}
-
-impl<K: McBufWritable, V: McBufWritable> McBufWritable for HashMap<K, V> {
- default fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- u32::var_write_into(&(self.len() as u32), buf)?;
- for (key, value) in self {
- key.write_into(buf)?;
- value.write_into(buf)?;
- }
-
- Ok(())
- }
-}
-
-impl McBufWritable for Vec<u8> {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- buf.write_byte_array(self)
- }
-}
-
-impl McBufWritable for String {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- buf.write_utf(self)
- }
-}
-
-impl McBufWritable for ResourceLocation {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- buf.write_resource_location(self)
- }
-}
-
-impl McBufWritable for u32 {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- i16::write_into(&(*self as i16), buf)
- }
-}
-
-impl McBufVarWritable for u32 {
- fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- i32::var_write_into(&(*self as i32), buf)
- }
-}
-
-impl McBufVarWritable for i64 {
- fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- let mut buffer = [0];
- let mut cnt = 0;
- let mut value = *self;
- while value != 0 {
- buffer[0] = (value & 0b0111_1111) as u8;
- value = (value >> 7) & (i64::max_value() >> 6);
- if value != 0 {
- buffer[0] |= 0b1000_0000;
- }
- cnt += buf.write(&mut buffer)?;
- }
- Ok(())
- }
-}
-
-impl McBufVarWritable for u64 {
- fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- i64::var_write_into(&(*self as i64), buf)
- }
-}
-
-impl McBufWritable for u16 {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- i16::write_into(&(*self as i16), buf)
- }
-}
-
-impl McBufVarWritable for u16 {
- fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- i32::var_write_into(&(*self as i32), buf)
- }
-}
-
-impl<T: McBufVarWritable> McBufVarWritable for Vec<T> {
- fn var_write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- u32::var_write_into(&(self.len() as u32), buf)?;
- for i in self {
- i.var_write_into(buf)?;
- }
- Ok(())
- }
-}
-
-impl McBufWritable for u8 {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- buf.write_byte(*self)
- }
-}
-
-impl McBufWritable for i16 {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- Writable::write_short(buf, *self)
- }
-}
-
-impl McBufWritable for i64 {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- Writable::write_long(buf, *self)
- }
-}
-
-impl McBufWritable for u64 {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- i64::write_into(&(*self as i64), buf)
- }
-}
-
-impl McBufWritable for bool {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- buf.write_boolean(*self)
- }
-}
-
-impl McBufWritable for i8 {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- buf.write_byte(*self as u8)
- }
-}
-
-impl McBufWritable for f32 {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- buf.write_float(*self)
- }
-}
-
-impl McBufWritable for f64 {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- buf.write_double(*self)
- }
-}
-
-impl McBufWritable for GameType {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- u8::write_into(&self.to_id(), buf)
- }
-}
-
-impl McBufWritable for Option<GameType> {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- buf.write_byte(GameType::to_optional_id(self) as u8)
- }
-}
-
-impl<T: McBufWritable> McBufWritable for Option<T> {
- default fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- if let Some(s) = self {
- buf.write_boolean(true)?;
- s.write_into(buf)?;
- } else {
- buf.write_boolean(false)?;
- };
- Ok(())
- }
-}
-
-impl McBufWritable for azalea_nbt::Tag {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- buf.write_nbt(self)
- }
-}
-
-impl McBufWritable for Difficulty {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- u8::write_into(&self.id(), buf)
- }
-}
-
-impl McBufWritable for Component {
- // async fn read_into(buf: &mut impl Read) -> Result<Self, String>
- // where
- // R: AsyncRead + std::marker::Unpin + std::marker::Send,
- // {
- // let string = buf.read_utf().await?;
- // let json: serde_json::Value = serde_json::from_str(string.as_str())
- // .map_err(|e| "Component isn't valid JSON".to_string())?;
- // let component = Component::deserialize(json).map_err(|e| e.to_string())?;
- // Ok(component)
- // }
- fn write_into(&self, _buf: &mut impl Write) -> Result<(), std::io::Error> {
- // component doesn't have serialize implemented yet
- todo!()
- }
-}
-
-impl McBufWritable for Slot {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- match self {
- Slot::Empty => buf.write_byte(0)?,
- Slot::Present(i) => {
- buf.write_varint(i.id)?;
- buf.write_byte(i.count)?;
- buf.write_nbt(&i.nbt)?;
- }
- }
-
- Ok(())
- }
-}
-
-impl McBufWritable for Uuid {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- buf.write_uuid(self)?;
-
- Ok(())
- }
-}
-
-impl McBufWritable for BlockPos {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- buf.write_long(
- (((self.x & 0x3FFFFFF) as i64) << 38)
- | (((self.z & 0x3FFFFFF) as i64) << 12)
- | ((self.y & 0xFFF) as i64),
- )
- }
-}
-
-impl McBufWritable for GlobalPos {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- ResourceLocation::write_into(&self.dimension, buf)?;
- BlockPos::write_into(&self.pos, buf)?;
-
- Ok(())
- }
-}
-
-impl McBufWritable for Direction {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- buf.write_varint(*self as i32)
- }
-}
-
-impl McBufWritable for ChunkSectionPos {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- let long = (((self.x & 0x3FFFFF) as i64) << 42)
- | (self.y & 0xFFFFF) as i64
- | (((self.z & 0x3FFFFF) as i64) << 20);
- long.write_into(buf)?;
- Ok(())
- }
-}
-
-impl McBufWritable for SaltSignaturePair {
- fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- self.salt.write_into(buf)?;
- self.signature.write_into(buf)?;
- Ok(())
- }
-}