Skip to content

Commit

Permalink
put VarInt and VarLong Serialize and Deserialize together
Browse files Browse the repository at this point in the history
  • Loading branch information
Snowiiii committed Dec 12, 2024
1 parent f587cb6 commit dde83d0
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 137 deletions.
6 changes: 2 additions & 4 deletions pumpkin-protocol/src/bytebuf/deserializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,16 +127,14 @@ impl<'de> de::Deserializer<'de> for Deserializer<'_> {
where
V: de::Visitor<'de>,
{
let string = self.inner.get_string()?;
visitor.visit_str(&string)
visitor.visit_str(&self.inner.get_string()?)
}

fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
let string = self.inner.get_string()?;
visitor.visit_str(&string)
visitor.visit_str(&self.inner.get_string()?)
}

fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
Expand Down
130 changes: 2 additions & 128 deletions pumpkin-protocol/src/bytebuf/packet_id.rs
Original file line number Diff line number Diff line change
@@ -1,135 +1,9 @@
use bytes::BufMut;
use serde::{
de::{self, DeserializeOwned, SeqAccess, Visitor},
Deserialize, Deserializer, Serialize, Serializer,
};
use serde::{de::DeserializeOwned, Serialize};

use crate::{BitSet, ClientPacket, ServerPacket, VarInt, VarIntType, VarLong};
use crate::{ClientPacket, ServerPacket, VarIntType};

use super::{deserializer, serializer, ByteBuffer, DeserializerError};

impl Serialize for BitSet<'_> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// TODO: make this right
(&self.0, self.1).serialize(serializer)
}
}

impl Serialize for VarInt {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut value = self.0 as u32;
let mut buf = Vec::new();

while value > 0x7F {
buf.put_u8(value as u8 | 0x80);
value >>= 7;
}

buf.put_u8(value as u8);

serializer.serialize_bytes(&buf)
}
}

impl<'de> Deserialize<'de> for VarInt {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct VarIntVisitor;

impl<'de> Visitor<'de> for VarIntVisitor {
type Value = VarInt;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a valid VarInt encoded in a byte sequence")
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut val = 0;
for i in 0..VarInt::MAX_SIZE {
if let Some(byte) = seq.next_element::<u8>()? {
val |= (i32::from(byte) & 0b01111111) << (i * 7);
if byte & 0b10000000 == 0 {
return Ok(VarInt(val));
}
} else {
break;
}
}
Err(de::Error::custom("VarInt was too large"))
}
}

deserializer.deserialize_seq(VarIntVisitor)
}
}

impl Serialize for VarLong {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut value = self.0 as u64;
let mut buf = Vec::new();

while value > 0x7F {
buf.put_u8(value as u8 | 0x80);
value >>= 7;
}

buf.put_u8(value as u8);

serializer.serialize_bytes(&buf)
}
}

impl<'de> Deserialize<'de> for VarLong {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct VarLongVisitor;

impl<'de> Visitor<'de> for VarLongVisitor {
type Value = VarLong;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a valid VarInt encoded in a byte sequence")
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut val = 0;
for i in 0..VarLong::MAX_SIZE {
if let Some(byte) = seq.next_element::<u8>()? {
val |= (i64::from(byte) & 0b01111111) << (i * 7);
if byte & 0b10000000 == 0 {
return Ok(VarLong(val));
}
} else {
break;
}
}
Err(de::Error::custom("VarInt was too large"))
}
}

deserializer.deserialize_seq(VarLongVisitor)
}
}

pub trait Packet {
const PACKET_ID: VarIntType;
}
Expand Down
14 changes: 11 additions & 3 deletions pumpkin-protocol/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bytebuf::{packet_id::Packet, ByteBuffer, DeserializerError};
use pumpkin_core::text::{style::Style, TextComponent};
use serde::{Deserialize, Serialize};
use serde::{Deserialize, Serialize, Serializer};

pub mod bytebuf;
pub mod client;
Expand All @@ -24,12 +24,20 @@ pub const MAX_PACKET_SIZE: i32 = 2097152;

/// usually uses a namespace like "minecraft:thing"
pub type Identifier = String;
pub type VarIntType = i32;
pub type VarLongType = i64;
pub type FixedBitSet = bytes::Bytes;

pub struct BitSet<'a>(pub VarInt, pub &'a [i64]);

impl Serialize for BitSet<'_> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// TODO: make this right
(&self.0, self.1).serialize(serializer)
}
}

#[derive(Debug, PartialEq, Clone, Copy)]
pub enum ConnectionState {
HandShake,
Expand Down
65 changes: 64 additions & 1 deletion pumpkin-protocol/src/var_int.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
use bytes::{Buf, BufMut};
use serde::{
de::{SeqAccess, Visitor},
Deserialize, Deserializer, Serialize, Serializer,
};
use thiserror::Error;

use crate::VarIntType;
pub type VarIntType = i32;

/**
* A variable-length integer type used by the Minecraft network protocol.
*/
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VarInt(pub VarIntType);

Expand Down Expand Up @@ -84,3 +91,59 @@ pub enum VarIntDecodeError {
#[error("VarInt is too large")]
TooLarge,
}

impl Serialize for VarInt {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut value = self.0 as u32;
let mut buf = Vec::new();

while value > 0x7F {
buf.put_u8(value as u8 | 0x80);
value >>= 7;
}

buf.put_u8(value as u8);

serializer.serialize_bytes(&buf)
}
}

impl<'de> Deserialize<'de> for VarInt {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct VarIntVisitor;

impl<'de> Visitor<'de> for VarIntVisitor {
type Value = VarInt;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a valid VarInt encoded in a byte sequence")
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut val = 0;
for i in 0..VarInt::MAX_SIZE {
if let Some(byte) = seq.next_element::<u8>()? {
val |= (i32::from(byte) & 0b01111111) << (i * 7);
if byte & 0b10000000 == 0 {
return Ok(VarInt(val));
}
} else {
break;
}
}
Err(serde::de::Error::custom("VarInt was too large"))
}
}

deserializer.deserialize_seq(VarIntVisitor)
}
}
65 changes: 64 additions & 1 deletion pumpkin-protocol/src/var_long.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
use bytes::{Buf, BufMut};
use serde::{
de::{self, SeqAccess, Visitor},
Deserialize, Deserializer, Serialize, Serializer,
};
use thiserror::Error;

use crate::VarLongType;
pub type VarLongType = i64;

/**
* A variable-length long type used by the Minecraft network protocol.
*/
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VarLong(pub VarLongType);

Expand Down Expand Up @@ -85,3 +92,59 @@ pub enum VarLongDecodeError {
#[error("VarLong is too large")]
TooLarge,
}

impl Serialize for VarLong {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut value = self.0 as u64;
let mut buf = Vec::new();

while value > 0x7F {
buf.put_u8(value as u8 | 0x80);
value >>= 7;
}

buf.put_u8(value as u8);

serializer.serialize_bytes(&buf)
}
}

impl<'de> Deserialize<'de> for VarLong {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct VarLongVisitor;

impl<'de> Visitor<'de> for VarLongVisitor {
type Value = VarLong;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a valid VarInt encoded in a byte sequence")
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut val = 0;
for i in 0..VarLong::MAX_SIZE {
if let Some(byte) = seq.next_element::<u8>()? {
val |= (i64::from(byte) & 0b01111111) << (i * 7);
if byte & 0b10000000 == 0 {
return Ok(VarLong(val));
}
} else {
break;
}
}
Err(de::Error::custom("VarInt was too large"))
}
}

deserializer.deserialize_seq(VarLongVisitor)
}
}

0 comments on commit dde83d0

Please sign in to comment.