Serde serialize for automatic packet serialization

This commit is contained in:
lukas0008 2024-08-05 00:55:19 +02:00
parent c54ab006ae
commit 284db803f9
11 changed files with 508 additions and 51 deletions

7
Cargo.lock generated
View File

@ -1178,6 +1178,7 @@ dependencies = [
"log", "log",
"serde", "serde",
"serde_json", "serde_json",
"take_mut",
"thiserror", "thiserror",
"uuid", "uuid",
] ]
@ -1644,6 +1645,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "take_mut"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60"
[[package]] [[package]]
name = "tar" name = "tar"
version = "0.4.41" version = "0.4.41"

View File

@ -20,4 +20,5 @@ fastnbt = { git = "https://github.com/owengage/fastnbt.git" }
# encryption # encryption
aes = "0.8.4" aes = "0.8.4"
cfb8 = "0.8.1" cfb8 = "0.8.1"
take_mut = "0.2.2"

View File

@ -1,13 +1,15 @@
use core::str; use core::str;
use std::io::{self, Error, ErrorKind}; use std::io::{self, Error, ErrorKind};
use bytes::{Buf, BufMut, BytesMut}; use bytes::{Buf, BufMut, BytesMut};
use crate::{BitSet, VarInt, VarLong}; use crate::{BitSet, VarInt, VarLong};
mod serializer;
pub mod packet_id;
const SEGMENT_BITS: u8 = 0x7F; const SEGMENT_BITS: u8 = 0x7F;
const CONTINUE_BIT: u8 = 0x80; const CONTINUE_BIT: u8 = 0x80;
#[derive(Debug)]
pub struct ByteBuffer { pub struct ByteBuffer {
buffer: BytesMut, buffer: BytesMut,
} }
@ -130,7 +132,7 @@ impl ByteBuffer {
} }
pub fn put_var_int(&mut self, value: VarInt) { pub fn put_var_int(&mut self, value: VarInt) {
let mut val = value as u32; let mut val = value;
for _ in 0..5 { for _ in 0..5 {
let mut b: u8 = val as u8 & 0b01111111; let mut b: u8 = val as u8 & 0b01111111;
val >>= 7; val >>= 7;

View File

@ -0,0 +1,46 @@
use serde::{Serialize, Serializer};
use crate::{ClientPacket, VarInt, VarInt32};
use super::{serializer, ByteBuffer};
impl Serialize for VarInt32 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut val = self.0;
let mut buf: Vec<u8> = Vec::new();
for _ in 0..5 {
let mut b: u8 = val as u8 & 0b01111111;
val >>= 7;
if val != 0 {
b |= 0b10000000;
}
buf.push(b);
if val == 0 {
break;
}
}
serializer.serialize_bytes(&buf)
}
}
pub trait Packet {
const PACKET_ID: VarInt;
}
impl<P> ClientPacket for P
where
P: Packet + Serialize,
{
fn write(&self, bytebuf: &mut ByteBuffer) {
dbg!(P::PACKET_ID);
take_mut::take(bytebuf, |bytebuf| {
let mut serializer = serializer::Serializer::new(bytebuf);
self.serialize(&mut serializer)
.expect("Could not serialize packet");
serializer.into()
});
}
}

View File

@ -0,0 +1,359 @@
use std::fmt::Display;
use serde::{ser, Serialize};
use thiserror::Error;
use super::ByteBuffer;
pub struct Serializer {
output: ByteBuffer,
}
impl Serializer {
pub fn new(buf: ByteBuffer) -> Self {
Self { output: buf }
}
}
impl Into<ByteBuffer> for Serializer {
fn into(self) -> ByteBuffer {
self.output
}
}
impl AsRef<ByteBuffer> for Serializer {
fn as_ref(&self) -> &ByteBuffer {
&self.output
}
}
impl AsMut<ByteBuffer> for Serializer {
fn as_mut(&mut self) -> &mut ByteBuffer {
&mut self.output
}
}
#[derive(Debug, Error)]
pub enum SerializerError {
#[error("serializer error {0}")]
Message(String),
}
impl ser::Error for SerializerError {
fn custom<T: Display>(msg: T) -> Self {
Self::Message(msg.to_string())
}
}
impl<'a> ser::Serializer for &'a mut Serializer {
type Ok = ();
type Error = SerializerError;
type SerializeSeq = Self;
type SerializeTuple = Self;
type SerializeTupleStruct = Self;
type SerializeTupleVariant = Self;
type SerializeMap = Self;
type SerializeStruct = Self;
type SerializeStructVariant = Self;
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
self.output.put_bool(v);
Ok(())
}
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
self.output.put_slice(v);
Ok(())
}
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
todo!()
}
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
todo!()
}
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
todo!()
}
fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
todo!()
}
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
todo!()
}
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
todo!()
}
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
self.output.put_i64(v);
Ok(())
}
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
todo!()
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
todo!()
}
fn serialize_newtype_struct<T>(
self,
name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
todo!()
}
fn serialize_newtype_variant<T>(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
todo!()
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
todo!()
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
todo!()
}
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
todo!()
}
fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
self.output.put_string(v);
Ok(())
}
fn serialize_struct(
self,
name: &'static str,
len: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
Ok(self)
}
fn serialize_struct_variant(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
todo!()
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
todo!()
}
fn serialize_tuple_struct(
self,
name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
todo!()
}
fn serialize_tuple_variant(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
todo!()
}
fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
todo!()
}
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
todo!()
}
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
todo!()
}
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
todo!()
}
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
todo!()
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
todo!()
}
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
todo!()
}
fn serialize_unit_variant(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok, Self::Error> {
todo!()
}
}
impl<'a> ser::SerializeSeq for &'a mut Serializer {
// Must match the `Ok` type of the serializer.
type Ok = ();
// Must match the `Error` type of the serializer.
type Error = SerializerError;
// Serialize a single element of the sequence.
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: ?Sized + Serialize,
{
todo!()
}
// Close the sequence.
fn end(self) -> Result<(), Self::Error> {
todo!()
}
}
impl<'a> ser::SerializeTuple for &'a mut Serializer {
type Ok = ();
type Error = SerializerError;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: ?Sized + Serialize,
{
todo!()
}
fn end(self) -> Result<(), Self::Error> {
todo!()
}
}
// Same thing but for tuple structs.
impl<'a> ser::SerializeTupleStruct for &'a mut Serializer {
type Ok = ();
type Error = SerializerError;
fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: ?Sized + Serialize,
{
todo!()
}
fn end(self) -> Result<(), Self::Error> {
todo!()
}
}
// Tuple variants are a little different. Refer back to the
// `serialize_tuple_variant` method above:
//
// self.output += "{";
// variant.serialize(&mut *self)?;
// self.output += ":[";
//
// So the `end` method in this impl is responsible for closing both the `]` and
// the `}`.
impl<'a> ser::SerializeTupleVariant for &'a mut Serializer {
type Ok = ();
type Error = SerializerError;
fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: ?Sized + Serialize,
{
todo!()
}
fn end(self) -> Result<(), Self::Error> {
todo!()
}
}
// Some `Serialize` types are not able to hold a key and value in memory at the
// same time so `SerializeMap` implementations are required to support
// `serialize_key` and `serialize_value` individually.
//
// There is a third optional method on the `SerializeMap` trait. The
// `serialize_entry` method allows serializers to optimize for the case where
// key and value are both available simultaneously. In JSON it doesn't make a
// difference so the default behavior for `serialize_entry` is fine.
impl<'a> ser::SerializeMap for &'a mut Serializer {
type Ok = ();
type Error = SerializerError;
// The Serde data model allows map keys to be any serializable type. JSON
// only allows string keys so the implementation below will produce invalid
// JSON if the key serializes as something other than a string.
//
// A real JSON serializer would need to validate that map keys are strings.
// This can be done by using a different Serializer to serialize the key
// (instead of `&mut **self`) and having that other serializer only
// implement `serialize_str` and return an error on any other data type.
fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
where
T: ?Sized + Serialize,
{
todo!()
}
// It doesn't make a difference whether the colon is printed at the end of
// `serialize_key` or at the beginning of `serialize_value`. In this case
// the code is a bit simpler having it here.
fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: ?Sized + Serialize,
{
todo!()
}
fn end(self) -> Result<(), Self::Error> {
todo!()
}
}
// Structs are like maps in which the keys are constrained to be compile-time
// constant strings.
impl<'a> ser::SerializeStruct for &'a mut Serializer {
type Ok = ();
type Error = SerializerError;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<(), Self::Error> {
Ok(())
}
fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> {
let _ = key;
Ok(())
}
}
// Similar to `SerializeTupleVariant`, here the `end` method is responsible for
// closing both of the curly braces opened by `serialize_struct_variant`.
impl<'a> ser::SerializeStructVariant for &'a mut Serializer {
type Ok = ();
type Error = SerializerError;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
where
T: ?Sized + Serialize,
{
todo!()
}
fn end(self) -> Result<(), Self::Error> {
todo!()
}
}

View File

@ -1,12 +1,17 @@
use crate::{bytebuf::ByteBuffer, ClientPacket, Identifier, KnownPack, VarInt}; use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, Identifier, KnownPack, VarInt,
};
pub struct CCookieRequest { pub struct CCookieRequest {
key: Identifier, key: Identifier,
} }
impl ClientPacket for CCookieRequest { impl Packet for CCookieRequest {
const PACKET_ID: VarInt = 0x00; const PACKET_ID: VarInt = 0x00;
}
impl ClientPacket for CCookieRequest {
fn write(&self, bytebuf: &mut ByteBuffer) { fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_string(&self.key); bytebuf.put_string(&self.key);
} }
@ -23,33 +28,33 @@ impl<'a> CPluginMessage<'a> {
} }
} }
impl<'a> ClientPacket for CPluginMessage<'a> { impl<'a> Packet for CPluginMessage<'a> {
const PACKET_ID: VarInt = 0x01; const PACKET_ID: VarInt = 0x01;
}
impl<'a> ClientPacket for CPluginMessage<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) { fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_string(self.channel); bytebuf.put_string(self.channel);
bytebuf.put_slice(self.data); bytebuf.put_slice(self.data);
} }
} }
#[derive(serde::Serialize)]
pub struct CConfigDisconnect<'a> { pub struct CConfigDisconnect<'a> {
reason: &'a str, reason: &'a str,
} }
impl<'a> Packet for CConfigDisconnect<'a> {
const PACKET_ID: i32 = 0x02;
}
impl<'a> CConfigDisconnect<'a> { impl<'a> CConfigDisconnect<'a> {
pub fn new(reason: &'a str) -> Self { pub fn new(reason: &'a str) -> Self {
Self { reason } Self { reason }
} }
} }
impl<'a> ClientPacket for CConfigDisconnect<'a> { #[derive(serde::Serialize)]
const PACKET_ID: VarInt = 0x02;
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_string(self.reason);
}
}
pub struct CFinishConfig {} pub struct CFinishConfig {}
impl Default for CFinishConfig { impl Default for CFinishConfig {
@ -64,10 +69,8 @@ impl CFinishConfig {
} }
} }
impl ClientPacket for CFinishConfig { impl Packet for CFinishConfig {
const PACKET_ID: VarInt = 0x03; const PACKET_ID: VarInt = 0x03;
fn write(&self, _bytebuf: &mut ByteBuffer) {}
} }
pub struct CKnownPacks<'a> { pub struct CKnownPacks<'a> {
@ -80,9 +83,11 @@ impl<'a> CKnownPacks<'a> {
} }
} }
impl<'a> ClientPacket for CKnownPacks<'a> { impl<'a> Packet for CKnownPacks<'a> {
const PACKET_ID: VarInt = 0x0E; const PACKET_ID: VarInt = 0x0E;
}
impl<'a> ClientPacket for CKnownPacks<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) { fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_list::<KnownPack>(self.known_packs, |p, v| { bytebuf.put_list::<KnownPack>(self.known_packs, |p, v| {
p.put_string(v.namespace); p.put_string(v.namespace);
@ -111,9 +116,11 @@ pub struct RegistryEntry<'a> {
pub data: Vec<u8>, pub data: Vec<u8>,
} }
impl<'a> ClientPacket for CRegistryData<'a> { impl<'a> Packet for CRegistryData<'a> {
const PACKET_ID: VarInt = 0x07; const PACKET_ID: VarInt = 0x07;
}
impl<'a> ClientPacket for CRegistryData<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) { fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_string(self.registry_id); bytebuf.put_string(self.registry_id);
bytebuf.put_list::<RegistryEntry>(self.entries, |p, v| { bytebuf.put_list::<RegistryEntry>(self.entries, |p, v| {

View File

@ -1,4 +1,7 @@
use crate::{bytebuf::ByteBuffer, ClientPacket, Property, VarInt}; use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, Property, VarInt,
};
pub struct CLoginDisconnect<'a> { pub struct CLoginDisconnect<'a> {
reason: &'a str, reason: &'a str,
@ -10,9 +13,11 @@ impl<'a> CLoginDisconnect<'a> {
} }
} }
impl<'a> ClientPacket for CLoginDisconnect<'a> { impl<'a> Packet for CLoginDisconnect<'a> {
const PACKET_ID: VarInt = 0x00; const PACKET_ID: VarInt = 0x00;
}
impl<'a> ClientPacket for CLoginDisconnect<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) { fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_string(&serde_json::to_string_pretty(&self.reason).unwrap()); bytebuf.put_string(&serde_json::to_string_pretty(&self.reason).unwrap());
} }
@ -41,9 +46,11 @@ impl<'a> CEncryptionRequest<'a> {
} }
} }
impl<'a> ClientPacket for CEncryptionRequest<'a> { impl<'a> Packet for CEncryptionRequest<'a> {
const PACKET_ID: VarInt = 0x01; const PACKET_ID: VarInt = 0x01;
}
impl<'a> ClientPacket for CEncryptionRequest<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) { fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_string(self.server_id); bytebuf.put_string(self.server_id);
bytebuf.put_var_int(self.public_key.len() as VarInt); bytebuf.put_var_int(self.public_key.len() as VarInt);
@ -81,9 +88,11 @@ impl<'a> CLoginSuccess<'a> {
} }
} }
impl<'a> ClientPacket for CLoginSuccess<'a> { impl<'a> Packet for CLoginSuccess<'a> {
const PACKET_ID: VarInt = 0x02; const PACKET_ID: VarInt = 0x02;
}
impl<'a> ClientPacket for CLoginSuccess<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) { fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_uuid(self.uuid); bytebuf.put_uuid(self.uuid);
bytebuf.put_string(&self.username); bytebuf.put_string(&self.username);
@ -105,9 +114,11 @@ impl CSetCompression {
} }
} }
impl ClientPacket for CSetCompression { impl Packet for CSetCompression {
const PACKET_ID: VarInt = 0x03; const PACKET_ID: VarInt = 0x03;
}
impl ClientPacket for CSetCompression {
fn write(&self, bytebuf: &mut ByteBuffer) { fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_var_int(self.threshold); bytebuf.put_var_int(self.threshold);
} }

View File

@ -1,4 +1,8 @@
use crate::{bytebuf::ByteBuffer, text::TextComponent, BitSet, ClientPacket, Property, VarInt}; use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
text::Text,
BitSet, ClientPacket, Property, VarInt,
};
pub struct SetHeldItem { pub struct SetHeldItem {
slot: i8, slot: i8,
@ -10,9 +14,11 @@ impl SetHeldItem {
} }
} }
impl ClientPacket for SetHeldItem { impl Packet for SetHeldItem {
const PACKET_ID: VarInt = 0x53; const PACKET_ID: VarInt = 0x53;
}
impl ClientPacket for SetHeldItem {
fn write(&self, bytebuf: &mut ByteBuffer) { fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i8(self.slot); bytebuf.put_i8(self.slot);
} }
@ -48,9 +54,11 @@ impl<'a> CPlayerInfoUpdate<'a> {
} }
} }
impl<'a> ClientPacket for CPlayerInfoUpdate<'a> { impl<'a> Packet for CPlayerInfoUpdate<'a> {
const PACKET_ID: VarInt = 0x3E; const PACKET_ID: VarInt = 0x3E;
}
impl<'a> ClientPacket for CPlayerInfoUpdate<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) { fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i8(self.actions); bytebuf.put_i8(self.actions);
bytebuf.put_list::<Player>(self.players, |p, v| { bytebuf.put_list::<Player>(self.players, |p, v| {
@ -95,9 +103,11 @@ impl CPlayerAbilities {
} }
} }
impl ClientPacket for CPlayerAbilities { impl Packet for CPlayerAbilities {
const PACKET_ID: VarInt = 0x38; const PACKET_ID: VarInt = 0x38;
}
impl ClientPacket for CPlayerAbilities {
fn write(&self, bytebuf: &mut ByteBuffer) { fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i8(self.flags); bytebuf.put_i8(self.flags);
bytebuf.put_f32(self.flying_speed); bytebuf.put_f32(self.flying_speed);
@ -115,9 +125,11 @@ impl CPlayDisconnect {
} }
} }
impl ClientPacket for CPlayDisconnect { impl Packet for CPlayDisconnect {
const PACKET_ID: VarInt = 0x1D; const PACKET_ID: VarInt = 0x1D;
}
impl ClientPacket for CPlayDisconnect {
fn write(&self, bytebuf: &mut ByteBuffer) { fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_slice(&self.reason.encode()); bytebuf.put_slice(&self.reason.encode());
} }
@ -154,9 +166,11 @@ impl CChangeDifficulty {
} }
} }
impl ClientPacket for CChangeDifficulty { impl Packet for CChangeDifficulty {
const PACKET_ID: VarInt = 0x0B; const PACKET_ID: VarInt = 0x0B;
}
impl ClientPacket for CChangeDifficulty {
fn write(&self, bytebuf: &mut ByteBuffer) { fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_u8(self.difficulty); bytebuf.put_u8(self.difficulty);
bytebuf.put_bool(self.locked); bytebuf.put_bool(self.locked);
@ -237,9 +251,11 @@ impl CLogin {
} }
} }
impl ClientPacket for CLogin { impl Packet for CLogin {
const PACKET_ID: VarInt = 0x2B; const PACKET_ID: VarInt = 0x2B;
}
impl ClientPacket for CLogin {
fn write(&self, bytebuf: &mut ByteBuffer) { fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i32(self.entity_id); bytebuf.put_i32(self.entity_id);
bytebuf.put_bool(self.is_hardcore); bytebuf.put_bool(self.is_hardcore);
@ -278,9 +294,11 @@ impl CGameEvent {
} }
} }
impl ClientPacket for CGameEvent { impl Packet for CGameEvent {
const PACKET_ID: VarInt = 0x22; const PACKET_ID: VarInt = 0x22;
}
impl ClientPacket for CGameEvent {
fn write(&self, bytebuf: &mut ByteBuffer) { fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_u8(self.event); bytebuf.put_u8(self.event);
bytebuf.put_f32(self.value); bytebuf.put_f32(self.value);
@ -319,9 +337,11 @@ impl CSyncPlayerPostion {
} }
} }
impl ClientPacket for CSyncPlayerPostion { impl Packet for CSyncPlayerPostion {
const PACKET_ID: VarInt = 0x40; const PACKET_ID: VarInt = 0x40;
}
impl ClientPacket for CSyncPlayerPostion {
fn write(&self, bytebuf: &mut ByteBuffer) { fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_f64(self.x); bytebuf.put_f64(self.x);
bytebuf.put_f64(self.y); bytebuf.put_f64(self.y);
@ -375,9 +395,11 @@ impl CChunkDataUpdateLight {
} }
} }
impl ClientPacket for CChunkDataUpdateLight { impl Packet for CChunkDataUpdateLight {
const PACKET_ID: VarInt = 0x27; const PACKET_ID: VarInt = 0x27;
}
impl ClientPacket for CChunkDataUpdateLight {
fn write(&self, bytebuf: &mut ByteBuffer) { fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i32(self.chunk_x); bytebuf.put_i32(self.chunk_x);
bytebuf.put_i32(self.chunk_y); bytebuf.put_i32(self.chunk_y);

View File

@ -1,23 +1,23 @@
use crate::{bytebuf::ByteBuffer, ClientPacket, VarInt}; use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, VarInt,
};
#[derive(serde::Serialize)]
pub struct CPingResponse { pub struct CPingResponse {
payload: i64, // must responde with the same as in `SPingRequest` payload: i64, // must responde with the same as in `SPingRequest`
} }
impl Packet for CPingResponse {
const PACKET_ID: VarInt = 0x01;
}
impl CPingResponse { impl CPingResponse {
pub fn new(payload: i64) -> Self { pub fn new(payload: i64) -> Self {
Self { payload } Self { payload }
} }
} }
impl ClientPacket for CPingResponse {
const PACKET_ID: VarInt = 0x01;
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i64(self.payload);
}
}
pub struct CStatusResponse<'a> { pub struct CStatusResponse<'a> {
json_response: &'a str, // 32767 json_response: &'a str, // 32767
} }
@ -27,10 +27,11 @@ impl<'a> CStatusResponse<'a> {
Self { json_response } Self { json_response }
} }
} }
impl<'a> Packet for CStatusResponse<'a> {
const PACKET_ID: VarInt = 0x00;
}
impl<'a> ClientPacket for CStatusResponse<'a> { impl<'a> ClientPacket for CStatusResponse<'a> {
const PACKET_ID: VarInt = 0x00;
fn write(&self, bytebuf: &mut ByteBuffer) { fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_string(self.json_response); bytebuf.put_string(self.json_response);
} }

View File

@ -1,6 +1,6 @@
use std::io::{self, Write}; use std::io::{self, Write};
use bytebuf::ByteBuffer; use bytebuf::{packet_id::Packet, ByteBuffer};
use bytes::Buf; use bytes::Buf;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use thiserror::Error; use thiserror::Error;
@ -146,9 +146,7 @@ pub struct RawPacket {
pub bytebuf: ByteBuffer, pub bytebuf: ByteBuffer,
} }
pub trait ClientPacket { pub trait ClientPacket: Packet {
const PACKET_ID: VarInt;
fn write(&self, bytebuf: &mut ByteBuffer); fn write(&self, bytebuf: &mut ByteBuffer);
} }

View File

@ -3,7 +3,10 @@ use std::io::Write;
use aes::cipher::{generic_array::GenericArray, BlockEncryptMut, BlockSizeUser, KeyIvInit}; use aes::cipher::{generic_array::GenericArray, BlockEncryptMut, BlockSizeUser, KeyIvInit};
use bytes::{BufMut, BytesMut}; use bytes::{BufMut, BytesMut};
use crate::{bytebuf::ByteBuffer, ClientPacket, PacketError, VarInt32, MAX_PACKET_SIZE}; use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, PacketError, VarInt32, MAX_PACKET_SIZE,
};
type Cipher = cfb8::Encryptor<aes::Aes128>; type Cipher = cfb8::Encryptor<aes::Aes128>;