Split all client requests into seperate files

This commit is contained in:
lukas0008 2024-08-05 01:19:52 +02:00
parent 284db803f9
commit 4fa1cced79
30 changed files with 878 additions and 790 deletions

View File

@ -1,10 +1,10 @@
use crate::{BitSet, VarInt, VarLong};
use bytes::{Buf, BufMut, BytesMut};
use core::str; use core::str;
use std::io::{self, Error, ErrorKind}; use std::io::{self, Error, ErrorKind};
use bytes::{Buf, BufMut, BytesMut};
use crate::{BitSet, VarInt, VarLong};
mod serializer;
pub mod packet_id; pub mod packet_id;
mod serializer;
const SEGMENT_BITS: u8 = 0x7F; const SEGMENT_BITS: u8 = 0x7F;
const CONTINUE_BIT: u8 = 0x80; const CONTINUE_BIT: u8 = 0x80;

View File

@ -15,9 +15,9 @@ impl Serializer {
} }
} }
impl Into<ByteBuffer> for Serializer { impl From<Serializer> for ByteBuffer {
fn into(self) -> ByteBuffer { fn from(val: Serializer) -> Self {
self.output val.output
} }
} }
@ -65,38 +65,38 @@ impl<'a> ser::Serializer for &'a mut Serializer {
self.output.put_slice(v); self.output.put_slice(v);
Ok(()) Ok(())
} }
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> { fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
todo!() todo!()
} }
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> { fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
todo!() todo!()
} }
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> { fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
todo!() todo!()
} }
fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> { fn serialize_i128(self, _v: i128) -> Result<Self::Ok, Self::Error> {
todo!() todo!()
} }
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> { fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
todo!() todo!()
} }
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> { fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
todo!() todo!()
} }
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> { fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
self.output.put_i64(v); self.output.put_i64(v);
Ok(()) Ok(())
} }
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> { fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
todo!() todo!()
} }
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
todo!() todo!()
} }
fn serialize_newtype_struct<T>( fn serialize_newtype_struct<T>(
self, self,
name: &'static str, _name: &'static str,
value: &T, _value: &T,
) -> Result<Self::Ok, Self::Error> ) -> Result<Self::Ok, Self::Error>
where where
T: ?Sized + Serialize, T: ?Sized + Serialize,
@ -105,10 +105,10 @@ impl<'a> ser::Serializer for &'a mut Serializer {
} }
fn serialize_newtype_variant<T>( fn serialize_newtype_variant<T>(
self, self,
name: &'static str, _name: &'static str,
variant_index: u32, _variant_index: u32,
variant: &'static str, _variant: &'static str,
value: &T, _value: &T,
) -> Result<Self::Ok, Self::Error> ) -> Result<Self::Ok, Self::Error>
where where
T: ?Sized + Serialize, T: ?Sized + Serialize,
@ -118,10 +118,10 @@ impl<'a> ser::Serializer for &'a mut Serializer {
fn serialize_none(self) -> Result<Self::Ok, Self::Error> { fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
todo!() todo!()
} }
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> { fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
todo!() todo!()
} }
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error> fn serialize_some<T>(self, _value: &T) -> Result<Self::Ok, Self::Error>
where where
T: ?Sized + Serialize, T: ?Sized + Serialize,
{ {
@ -133,65 +133,65 @@ impl<'a> ser::Serializer for &'a mut Serializer {
} }
fn serialize_struct( fn serialize_struct(
self, self,
name: &'static str, _name: &'static str,
len: usize, _len: usize,
) -> Result<Self::SerializeStruct, Self::Error> { ) -> Result<Self::SerializeStruct, Self::Error> {
Ok(self) Ok(self)
} }
fn serialize_struct_variant( fn serialize_struct_variant(
self, self,
name: &'static str, _name: &'static str,
variant_index: u32, _variant_index: u32,
variant: &'static str, _variant: &'static str,
len: usize, _len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> { ) -> Result<Self::SerializeStructVariant, Self::Error> {
todo!() todo!()
} }
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> { fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
todo!() todo!()
} }
fn serialize_tuple_struct( fn serialize_tuple_struct(
self, self,
name: &'static str, _name: &'static str,
len: usize, _len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> { ) -> Result<Self::SerializeTupleStruct, Self::Error> {
todo!() todo!()
} }
fn serialize_tuple_variant( fn serialize_tuple_variant(
self, self,
name: &'static str, _name: &'static str,
variant_index: u32, _variant_index: u32,
variant: &'static str, _variant: &'static str,
len: usize, _len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> { ) -> Result<Self::SerializeTupleVariant, Self::Error> {
todo!() todo!()
} }
fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> { fn serialize_u128(self, _v: u128) -> Result<Self::Ok, Self::Error> {
todo!() todo!()
} }
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> { fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
todo!() todo!()
} }
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> { fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
todo!() todo!()
} }
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> { fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
todo!() todo!()
} }
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> { fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
todo!() todo!()
} }
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> { fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
todo!() todo!()
} }
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> { fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
todo!() todo!()
} }
fn serialize_unit_variant( fn serialize_unit_variant(
self, self,
name: &'static str, _name: &'static str,
variant_index: u32, _variant_index: u32,
variant: &'static str, _variant: &'static str,
) -> Result<Self::Ok, Self::Error> { ) -> Result<Self::Ok, Self::Error> {
todo!() todo!()
} }
@ -204,7 +204,7 @@ impl<'a> ser::SerializeSeq for &'a mut Serializer {
type Error = SerializerError; type Error = SerializerError;
// Serialize a single element of the sequence. // Serialize a single element of the sequence.
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error> fn serialize_element<T>(&mut self, _value: &T) -> Result<(), Self::Error>
where where
T: ?Sized + Serialize, T: ?Sized + Serialize,
{ {
@ -221,7 +221,7 @@ impl<'a> ser::SerializeTuple for &'a mut Serializer {
type Ok = (); type Ok = ();
type Error = SerializerError; type Error = SerializerError;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error> fn serialize_element<T>(&mut self, _value: &T) -> Result<(), Self::Error>
where where
T: ?Sized + Serialize, T: ?Sized + Serialize,
{ {
@ -238,7 +238,7 @@ impl<'a> ser::SerializeTupleStruct for &'a mut Serializer {
type Ok = (); type Ok = ();
type Error = SerializerError; type Error = SerializerError;
fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error> fn serialize_field<T>(&mut self, _value: &T) -> Result<(), Self::Error>
where where
T: ?Sized + Serialize, T: ?Sized + Serialize,
{ {
@ -263,7 +263,7 @@ impl<'a> ser::SerializeTupleVariant for &'a mut Serializer {
type Ok = (); type Ok = ();
type Error = SerializerError; type Error = SerializerError;
fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error> fn serialize_field<T>(&mut self, _value: &T) -> Result<(), Self::Error>
where where
T: ?Sized + Serialize, T: ?Sized + Serialize,
{ {
@ -295,7 +295,7 @@ impl<'a> ser::SerializeMap for &'a mut Serializer {
// This can be done by using a different Serializer to serialize the key // This can be done by using a different Serializer to serialize the key
// (instead of `&mut **self`) and having that other serializer only // (instead of `&mut **self`) and having that other serializer only
// implement `serialize_str` and return an error on any other data type. // implement `serialize_str` and return an error on any other data type.
fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error> fn serialize_key<T>(&mut self, _key: &T) -> Result<(), Self::Error>
where where
T: ?Sized + Serialize, T: ?Sized + Serialize,
{ {
@ -305,7 +305,7 @@ impl<'a> ser::SerializeMap for &'a mut Serializer {
// It doesn't make a difference whether the colon is printed at the end of // 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 // `serialize_key` or at the beginning of `serialize_value`. In this case
// the code is a bit simpler having it here. // the code is a bit simpler having it here.
fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error> fn serialize_value<T>(&mut self, _value: &T) -> Result<(), Self::Error>
where where
T: ?Sized + Serialize, T: ?Sized + Serialize,
{ {
@ -323,7 +323,7 @@ impl<'a> ser::SerializeStruct for &'a mut Serializer {
type Ok = (); type Ok = ();
type Error = SerializerError; type Error = SerializerError;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> Result<(), Self::Error>
where where
T: ?Sized + Serialize, T: ?Sized + Serialize,
{ {
@ -346,7 +346,7 @@ impl<'a> ser::SerializeStructVariant for &'a mut Serializer {
type Ok = (); type Ok = ();
type Error = SerializerError; type Error = SerializerError;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> fn serialize_field<T>(&mut self, _key: &'static str, _value: &T) -> Result<(), Self::Error>
where where
T: ?Sized + Serialize, T: ?Sized + Serialize,
{ {

View File

@ -0,0 +1,16 @@
use crate::bytebuf::packet_id::Packet;
#[derive(serde::Serialize)]
pub struct CConfigDisconnect<'a> {
reason: &'a str,
}
impl<'a> Packet for CConfigDisconnect<'a> {
const PACKET_ID: i32 = 0x02;
}
impl<'a> CConfigDisconnect<'a> {
pub fn new(reason: &'a str) -> Self {
Self { reason }
}
}

View File

@ -0,0 +1,18 @@
use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, Identifier, VarInt,
};
pub struct CCookieRequest {
key: Identifier,
}
impl Packet for CCookieRequest {
const PACKET_ID: VarInt = 0x00;
}
impl ClientPacket for CCookieRequest {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_string(&self.key);
}
}

View File

@ -0,0 +1,20 @@
use crate::{bytebuf::packet_id::Packet, VarInt};
#[derive(serde::Serialize)]
pub struct CFinishConfig {}
impl Default for CFinishConfig {
fn default() -> Self {
Self::new()
}
}
impl CFinishConfig {
pub fn new() -> Self {
Self {}
}
}
impl Packet for CFinishConfig {
const PACKET_ID: VarInt = 0x03;
}

View File

@ -0,0 +1,28 @@
use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, KnownPack, VarInt,
};
pub struct CKnownPacks<'a> {
known_packs: &'a [KnownPack<'a>],
}
impl<'a> CKnownPacks<'a> {
pub fn new(known_packs: &'a [KnownPack]) -> Self {
Self { known_packs }
}
}
impl<'a> Packet for CKnownPacks<'a> {
const PACKET_ID: VarInt = 0x0E;
}
impl<'a> ClientPacket for CKnownPacks<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_list::<KnownPack>(self.known_packs, |p, v| {
p.put_string(v.namespace);
p.put_string(v.id);
p.put_string(v.version);
});
}
}

View File

@ -0,0 +1,26 @@
use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, VarInt,
};
pub struct CPluginMessage<'a> {
channel: &'a str,
data: &'a [u8],
}
impl<'a> CPluginMessage<'a> {
pub fn new(channel: &'a str, data: &'a [u8]) -> Self {
Self { channel, data }
}
}
impl<'a> Packet for CPluginMessage<'a> {
const PACKET_ID: VarInt = 0x01;
}
impl<'a> ClientPacket for CPluginMessage<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_string(self.channel);
bytebuf.put_slice(self.data);
}
}

View File

@ -0,0 +1,38 @@
use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, VarInt,
};
pub struct CRegistryData<'a> {
registry_id: &'a str,
entries: &'a [RegistryEntry<'a>],
}
impl<'a> CRegistryData<'a> {
pub fn new(registry_id: &'a str, entries: &'a [RegistryEntry]) -> Self {
Self {
registry_id,
entries,
}
}
}
pub struct RegistryEntry<'a> {
pub entry_id: &'a str,
pub data: Vec<u8>,
}
impl<'a> Packet for CRegistryData<'a> {
const PACKET_ID: VarInt = 0x07;
}
impl<'a> ClientPacket for CRegistryData<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_string(self.registry_id);
bytebuf.put_list::<RegistryEntry>(self.entries, |p, v| {
p.put_string(v.entry_id);
p.put_bool(!v.data.is_empty());
p.put_slice(&v.data);
});
}
}

View File

@ -1,132 +1,13 @@
use crate::{ mod c_config_disconnect;
bytebuf::{packet_id::Packet, ByteBuffer}, mod c_cookie_request;
ClientPacket, Identifier, KnownPack, VarInt, mod c_finish_config;
}; mod c_known_packs;
mod c_plugin_message;
mod c_registry_data;
pub struct CCookieRequest { pub use c_config_disconnect::*;
key: Identifier, pub use c_cookie_request::*;
} pub use c_finish_config::*;
pub use c_known_packs::*;
impl Packet for CCookieRequest { pub use c_plugin_message::*;
const PACKET_ID: VarInt = 0x00; pub use c_registry_data::*;
}
impl ClientPacket for CCookieRequest {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_string(&self.key);
}
}
pub struct CPluginMessage<'a> {
channel: &'a str,
data: &'a [u8],
}
impl<'a> CPluginMessage<'a> {
pub fn new(channel: &'a str, data: &'a [u8]) -> Self {
Self { channel, data }
}
}
impl<'a> Packet for CPluginMessage<'a> {
const PACKET_ID: VarInt = 0x01;
}
impl<'a> ClientPacket for CPluginMessage<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_string(self.channel);
bytebuf.put_slice(self.data);
}
}
#[derive(serde::Serialize)]
pub struct CConfigDisconnect<'a> {
reason: &'a str,
}
impl<'a> Packet for CConfigDisconnect<'a> {
const PACKET_ID: i32 = 0x02;
}
impl<'a> CConfigDisconnect<'a> {
pub fn new(reason: &'a str) -> Self {
Self { reason }
}
}
#[derive(serde::Serialize)]
pub struct CFinishConfig {}
impl Default for CFinishConfig {
fn default() -> Self {
Self::new()
}
}
impl CFinishConfig {
pub fn new() -> Self {
Self {}
}
}
impl Packet for CFinishConfig {
const PACKET_ID: VarInt = 0x03;
}
pub struct CKnownPacks<'a> {
known_packs: &'a [KnownPack<'a>],
}
impl<'a> CKnownPacks<'a> {
pub fn new(known_packs: &'a [KnownPack]) -> Self {
Self { known_packs }
}
}
impl<'a> Packet for CKnownPacks<'a> {
const PACKET_ID: VarInt = 0x0E;
}
impl<'a> ClientPacket for CKnownPacks<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_list::<KnownPack>(self.known_packs, |p, v| {
p.put_string(v.namespace);
p.put_string(v.id);
p.put_string(v.version);
});
}
}
pub struct CRegistryData<'a> {
registry_id: &'a str,
entries: &'a [RegistryEntry<'a>],
}
impl<'a> CRegistryData<'a> {
pub fn new(registry_id: &'a str, entries: &'a [RegistryEntry]) -> Self {
Self {
registry_id,
entries,
}
}
}
pub struct RegistryEntry<'a> {
pub entry_id: &'a str,
pub data: Vec<u8>,
}
impl<'a> Packet for CRegistryData<'a> {
const PACKET_ID: VarInt = 0x07;
}
impl<'a> ClientPacket for CRegistryData<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_string(self.registry_id);
bytebuf.put_list::<RegistryEntry>(self.entries, |p, v| {
p.put_string(v.entry_id);
p.put_bool(!v.data.is_empty());
p.put_slice(&v.data);
});
}
}

View File

@ -0,0 +1,42 @@
use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, VarInt,
};
pub struct CEncryptionRequest<'a> {
server_id: &'a str, // 20
public_key: &'a [u8],
verify_token: &'a [u8],
should_authenticate: bool,
}
impl<'a> CEncryptionRequest<'a> {
pub fn new(
server_id: &'a str,
public_key: &'a [u8],
verify_token: &'a [u8],
should_authenticate: bool,
) -> Self {
Self {
server_id,
public_key,
verify_token,
should_authenticate,
}
}
}
impl<'a> Packet for CEncryptionRequest<'a> {
const PACKET_ID: VarInt = 0x01;
}
impl<'a> ClientPacket for CEncryptionRequest<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_string(self.server_id);
bytebuf.put_var_int(self.public_key.len() as VarInt);
bytebuf.put_slice(self.public_key);
bytebuf.put_var_int(self.verify_token.len() as VarInt);
bytebuf.put_slice(self.verify_token);
bytebuf.put_bool(self.should_authenticate);
}
}

View File

@ -0,0 +1,24 @@
use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, VarInt,
};
pub struct CLoginDisconnect<'a> {
reason: &'a str,
}
impl<'a> CLoginDisconnect<'a> {
pub fn new(reason: &'a str) -> Self {
Self { reason }
}
}
impl<'a> Packet for CLoginDisconnect<'a> {
const PACKET_ID: VarInt = 0x00;
}
impl<'a> ClientPacket for CLoginDisconnect<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_string(&serde_json::to_string_pretty(&self.reason).unwrap());
}
}

View File

@ -0,0 +1,47 @@
use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, Property, VarInt,
};
pub struct CLoginSuccess<'a> {
pub uuid: uuid::Uuid,
pub username: String, // 16
pub properties: &'a [Property],
pub strict_error_handling: bool,
}
impl<'a> CLoginSuccess<'a> {
pub fn new(
uuid: uuid::Uuid,
username: String,
properties: &'a [Property],
strict_error_handling: bool,
) -> Self {
Self {
uuid,
username,
properties,
strict_error_handling,
}
}
}
impl<'a> Packet for CLoginSuccess<'a> {
const PACKET_ID: VarInt = 0x02;
}
impl<'a> ClientPacket for CLoginSuccess<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_uuid(self.uuid);
bytebuf.put_string(&self.username);
bytebuf.put_list::<Property>(self.properties, |p, v| {
p.put_string(&v.name);
p.put_string(&v.value);
// has signature ?
// todo: for some reason we get "got too many bytes error when using a signature"
p.put_bool(false);
// p.put_option(&v.signature, |p,v| p.put_string(v));
});
bytebuf.put_bool(self.strict_error_handling);
}
}

View File

@ -0,0 +1,24 @@
use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, VarInt,
};
pub struct CSetCompression {
threshold: VarInt,
}
impl CSetCompression {
pub fn new(threshold: VarInt) -> Self {
Self { threshold }
}
}
impl Packet for CSetCompression {
const PACKET_ID: VarInt = 0x03;
}
impl ClientPacket for CSetCompression {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_var_int(self.threshold);
}
}

View File

@ -1,125 +1,9 @@
use crate::{ mod c_encryption_request;
bytebuf::{packet_id::Packet, ByteBuffer}, mod c_login_disconnect;
ClientPacket, Property, VarInt, mod c_login_success;
}; mod c_set_compression;
pub struct CLoginDisconnect<'a> { pub use c_encryption_request::*;
reason: &'a str, pub use c_login_disconnect::*;
} pub use c_login_success::*;
pub use c_set_compression::*;
impl<'a> CLoginDisconnect<'a> {
pub fn new(reason: &'a str) -> Self {
Self { reason }
}
}
impl<'a> Packet for CLoginDisconnect<'a> {
const PACKET_ID: VarInt = 0x00;
}
impl<'a> ClientPacket for CLoginDisconnect<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_string(&serde_json::to_string_pretty(&self.reason).unwrap());
}
}
pub struct CEncryptionRequest<'a> {
server_id: &'a str, // 20
public_key: &'a [u8],
verify_token: &'a [u8],
should_authenticate: bool,
}
impl<'a> CEncryptionRequest<'a> {
pub fn new(
server_id: &'a str,
public_key: &'a [u8],
verify_token: &'a [u8],
should_authenticate: bool,
) -> Self {
Self {
server_id,
public_key,
verify_token,
should_authenticate,
}
}
}
impl<'a> Packet for CEncryptionRequest<'a> {
const PACKET_ID: VarInt = 0x01;
}
impl<'a> ClientPacket for CEncryptionRequest<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_string(self.server_id);
bytebuf.put_var_int(self.public_key.len() as VarInt);
bytebuf.put_slice(self.public_key);
bytebuf.put_var_int(self.verify_token.len() as VarInt);
bytebuf.put_slice(self.verify_token);
bytebuf.put_bool(self.should_authenticate);
}
}
pub struct CSetCompression {
threshold: VarInt,
}
pub struct CLoginSuccess<'a> {
pub uuid: uuid::Uuid,
pub username: String, // 16
pub properties: &'a [Property],
pub strict_error_handling: bool,
}
impl<'a> CLoginSuccess<'a> {
pub fn new(
uuid: uuid::Uuid,
username: String,
properties: &'a [Property],
strict_error_handling: bool,
) -> Self {
Self {
uuid,
username,
properties,
strict_error_handling,
}
}
}
impl<'a> Packet for CLoginSuccess<'a> {
const PACKET_ID: VarInt = 0x02;
}
impl<'a> ClientPacket for CLoginSuccess<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_uuid(self.uuid);
bytebuf.put_string(&self.username);
bytebuf.put_list::<Property>(self.properties, |p, v| {
p.put_string(&v.name);
p.put_string(&v.value);
// has signature ?
// todo: for some reason we get "got too many bytes error when using a signature"
p.put_bool(false);
// p.put_option(&v.signature, |p,v| p.put_string(v));
});
bytebuf.put_bool(self.strict_error_handling);
}
}
impl CSetCompression {
pub fn new(threshold: VarInt) -> Self {
Self { threshold }
}
}
impl Packet for CSetCompression {
const PACKET_ID: VarInt = 0x03;
}
impl ClientPacket for CSetCompression {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_var_int(self.threshold);
}
}

View File

@ -0,0 +1,26 @@
use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, VarInt,
};
pub struct CChangeDifficulty {
difficulty: u8,
locked: bool,
}
impl CChangeDifficulty {
pub fn new(difficulty: u8, locked: bool) -> Self {
Self { difficulty, locked }
}
}
impl Packet for CChangeDifficulty {
const PACKET_ID: VarInt = 0x0B;
}
impl ClientPacket for CChangeDifficulty {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_u8(self.difficulty);
bytebuf.put_bool(self.locked);
}
}

View File

@ -0,0 +1,92 @@
use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
BitSet, ClientPacket, VarInt,
};
pub struct CChunkDataUpdateLight {
chunk_x: i32,
chunk_y: i32,
heightmaps: Vec<u8>,
data: Vec<u8>,
block_entites: Vec<BlockEntity>,
sky_light_mask: BitSet,
block_light_mask: BitSet,
empty_sky_light_mask: BitSet,
sky_lights: Vec<SkyLight>,
block_lights: Vec<BlockLight>,
}
impl CChunkDataUpdateLight {
#[allow(clippy::too_many_arguments)]
pub fn new(
chunk_x: i32,
chunk_y: i32,
heightmaps: Vec<u8>,
data: Vec<u8>,
block_entites: Vec<BlockEntity>,
sky_light_mask: BitSet,
block_light_mask: BitSet,
empty_sky_light_mask: BitSet,
sky_lights: Vec<SkyLight>,
block_lights: Vec<BlockLight>,
) -> Self {
Self {
chunk_x,
chunk_y,
heightmaps,
data,
block_entites,
sky_light_mask,
block_light_mask,
empty_sky_light_mask,
sky_lights,
block_lights,
}
}
}
impl Packet for CChunkDataUpdateLight {
const PACKET_ID: VarInt = 0x27;
}
impl ClientPacket for CChunkDataUpdateLight {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i32(self.chunk_x);
bytebuf.put_i32(self.chunk_y);
bytebuf.put_slice(&self.heightmaps);
bytebuf.put_var_int(self.data.len() as VarInt);
bytebuf.put_slice(&self.data);
bytebuf.put_list::<BlockEntity>(&self.block_entites, |p, v| {
p.put_u8(v.packed_xz);
p.put_i16(v.y);
p.put_var_int(v.typee);
p.put_slice(&v.data);
});
bytebuf.put_bit_set(&self.sky_light_mask);
bytebuf.put_bit_set(&self.block_light_mask);
bytebuf.put_bit_set(&self.empty_sky_light_mask);
bytebuf.put_list::<SkyLight>(&self.sky_lights, |p, v| {
p.put_var_int(v.array.len() as VarInt);
p.put_slice(&v.array);
});
bytebuf.put_list::<BlockLight>(&self.block_lights, |p, v| {
p.put_var_int(v.array.len() as VarInt);
p.put_slice(&v.array);
});
}
}
pub struct BlockEntity {
packed_xz: u8,
y: i16,
typee: VarInt,
data: Vec<u8>,
}
pub struct SkyLight {
pub array: Vec<u8>,
}
pub struct BlockLight {
pub array: Vec<u8>,
}

View File

@ -0,0 +1,26 @@
use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, VarInt,
};
pub struct CGameEvent {
event: u8,
value: f32,
}
impl CGameEvent {
pub fn new(event: u8, value: f32) -> Self {
Self { event, value }
}
}
impl Packet for CGameEvent {
const PACKET_ID: VarInt = 0x22;
}
impl ClientPacket for CGameEvent {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_u8(self.event);
bytebuf.put_f32(self.value);
}
}

View File

@ -0,0 +1,111 @@
use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, VarInt,
};
pub struct CLogin {
entity_id: i32,
is_hardcore: bool,
dimension_names: Vec<String>,
max_players: VarInt,
view_distance: VarInt,
simulated_distance: VarInt,
reduced_debug_info: bool,
enabled_respawn_screen: bool,
limited_crafting: bool,
dimension_type: VarInt,
dimension_name: String,
hashed_seed: i64,
game_mode: u8,
previous_gamemode: i8,
debug: bool,
is_flat: bool,
has_death_loc: bool,
death_dimension_name: Option<String>,
death_loc: Option<i64>, // POSITION NOT STRING
portal_cooldown: VarInt,
enforce_secure_chat: bool,
}
impl CLogin {
#[allow(clippy::too_many_arguments)]
pub fn new(
entity_id: i32,
is_hardcore: bool,
dimension_names: Vec<String>,
max_players: VarInt,
view_distance: VarInt,
simulated_distance: VarInt,
reduced_debug_info: bool,
enabled_respawn_screen: bool,
limited_crafting: bool,
dimension_type: VarInt,
dimension_name: String,
hashed_seed: i64,
game_mode: u8,
previous_gamemode: i8,
debug: bool,
is_flat: bool,
has_death_loc: bool,
death_dimension_name: Option<String>,
death_loc: Option<i64>, // todo add block pos
portal_cooldown: VarInt,
enforce_secure_chat: bool,
) -> Self {
Self {
entity_id,
is_hardcore,
dimension_names,
max_players,
view_distance,
simulated_distance,
reduced_debug_info,
enabled_respawn_screen,
limited_crafting,
dimension_type,
dimension_name,
hashed_seed,
game_mode,
previous_gamemode,
debug,
is_flat,
has_death_loc,
death_dimension_name,
death_loc,
portal_cooldown,
enforce_secure_chat,
}
}
}
impl Packet for CLogin {
const PACKET_ID: VarInt = 0x2B;
}
impl ClientPacket for CLogin {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i32(self.entity_id);
bytebuf.put_bool(self.is_hardcore);
bytebuf.put_list(&self.dimension_names, |buf, v| buf.put_string(v));
bytebuf.put_var_int(self.max_players);
bytebuf.put_var_int(self.view_distance);
bytebuf.put_var_int(self.simulated_distance);
bytebuf.put_bool(self.reduced_debug_info);
bytebuf.put_bool(self.enabled_respawn_screen);
bytebuf.put_bool(self.limited_crafting);
bytebuf.put_var_int(self.dimension_type);
bytebuf.put_string(&self.dimension_name);
bytebuf.put_i64(self.hashed_seed);
bytebuf.put_u8(self.game_mode);
bytebuf.put_i8(self.previous_gamemode);
bytebuf.put_bool(self.debug);
bytebuf.put_bool(self.is_flat);
bytebuf.put_bool(self.has_death_loc);
if self.has_death_loc {
bytebuf.put_string(self.death_dimension_name.as_ref().unwrap());
bytebuf.put_i64(self.death_loc.unwrap());
}
bytebuf.put_var_int(self.portal_cooldown);
bytebuf.put_bool(self.enforce_secure_chat);
}
}

View File

@ -0,0 +1,25 @@
use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
text::Text,
ClientPacket, VarInt,
};
pub struct CPlayDisconnect {
reason: Text,
}
impl CPlayDisconnect {
pub fn new(reason: Text) -> Self {
Self { reason }
}
}
impl Packet for CPlayDisconnect {
const PACKET_ID: VarInt = 0x1D;
}
impl ClientPacket for CPlayDisconnect {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_slice(&self.reason.encode());
}
}

View File

@ -0,0 +1,32 @@
use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, VarInt,
};
pub struct CPlayerAbilities {
flags: i8,
flying_speed: f32,
field_of_view: f32,
}
impl CPlayerAbilities {
pub fn new(flags: i8, flying_speed: f32, field_of_view: f32) -> Self {
Self {
flags,
flying_speed,
field_of_view,
}
}
}
impl Packet for CPlayerAbilities {
const PACKET_ID: VarInt = 0x38;
}
impl ClientPacket for CPlayerAbilities {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i8(self.flags);
bytebuf.put_f32(self.flying_speed);
bytebuf.put_f32(self.field_of_view);
}
}

View File

@ -0,0 +1,55 @@
use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, Property, VarInt,
};
use super::PlayerAction;
pub struct CPlayerInfoUpdate<'a> {
pub actions: i8,
pub players: &'a [Player<'a>],
}
impl<'a> Packet for CPlayerInfoUpdate<'a> {
const PACKET_ID: VarInt = 0x3E;
}
pub struct Player<'a> {
pub uuid: uuid::Uuid,
pub actions: &'a [PlayerAction],
}
impl<'a> CPlayerInfoUpdate<'a> {
pub fn new(actions: i8, players: &'a [Player]) -> Self {
Self { actions, players }
}
}
impl<'a> ClientPacket for CPlayerInfoUpdate<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i8(self.actions);
bytebuf.put_list::<Player>(self.players, |p, v| {
p.put_uuid(v.uuid);
for action in v.actions {
match action {
PlayerAction::AddPlayer { name, properties } => {
p.put_string(name);
p.put_list::<Property>(properties, |p, v| {
p.put_string(&v.name);
p.put_string(&v.value);
// has signature ?
// todo: for some reason we get "got too many bytes error when using a signature"
p.put_bool(false);
// todo signature
});
}
PlayerAction::InitializeChat(_) => todo!(),
PlayerAction::UpdateGameMode(_) => todo!(),
PlayerAction::UpdateListed { listed } => p.put_bool(*listed),
PlayerAction::UpdateLatency(_) => todo!(),
PlayerAction::UpdateDisplayName(_) => todo!(),
}
}
});
}
}

View File

@ -0,0 +1,24 @@
use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, VarInt,
};
pub struct CSetHeldItem {
slot: i8,
}
impl CSetHeldItem {
pub fn new(slot: i8) -> Self {
Self { slot }
}
}
impl Packet for CSetHeldItem {
const PACKET_ID: VarInt = 0x53;
}
impl ClientPacket for CSetHeldItem {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i8(self.slot);
}
}

View File

@ -0,0 +1,52 @@
use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, VarInt,
};
pub struct CSyncPlayerPostion {
x: f64,
y: f64,
z: f64,
yaw: f32,
pitch: f32,
flags: i8,
teleport_id: VarInt,
}
impl CSyncPlayerPostion {
pub fn new(
x: f64,
y: f64,
z: f64,
yaw: f32,
pitch: f32,
flags: i8,
teleport_id: VarInt,
) -> Self {
Self {
x,
y,
z,
yaw,
pitch,
flags,
teleport_id,
}
}
}
impl Packet for CSyncPlayerPostion {
const PACKET_ID: VarInt = 0x40;
}
impl ClientPacket for CSyncPlayerPostion {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_f64(self.x);
bytebuf.put_f64(self.y);
bytebuf.put_f64(self.z);
bytebuf.put_f32(self.yaw.to_degrees());
bytebuf.put_f32(self.pitch.to_degrees());
bytebuf.put_i8(self.flags);
bytebuf.put_var_int(self.teleport_id);
}
}

View File

@ -1,442 +1,21 @@
use crate::{ mod c_change_difficulty;
bytebuf::{packet_id::Packet, ByteBuffer}, mod c_chunk_data_update_light;
text::Text, mod c_game_event;
BitSet, ClientPacket, Property, VarInt, mod c_login;
}; mod c_play_disconnect;
mod c_player_abilities;
mod c_player_info_update;
mod c_set_held_item;
mod c_sync_player_position;
mod player_action;
pub struct SetHeldItem { pub use c_change_difficulty::*;
slot: i8, pub use c_chunk_data_update_light::*;
} pub use c_game_event::*;
pub use c_login::*;
impl SetHeldItem { pub use c_play_disconnect::*;
pub fn new(slot: i8) -> Self { pub use c_player_abilities::*;
Self { slot } pub use c_player_info_update::*;
} pub use c_set_held_item::*;
} pub use c_sync_player_position::*;
pub use player_action::*;
impl Packet for SetHeldItem {
const PACKET_ID: VarInt = 0x53;
}
impl ClientPacket for SetHeldItem {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i8(self.slot);
}
}
pub struct CPlayerInfoUpdate<'a> {
actions: i8,
players: &'a [Player<'a>],
}
pub struct Player<'a> {
pub uuid: uuid::Uuid,
pub actions: &'a [PlayerAction],
}
pub enum PlayerAction {
AddPlayer {
name: String,
properties: Vec<Property>,
},
InitializeChat(u8),
UpdateGameMode(u8),
UpdateListed {
listed: bool,
},
UpdateLatency(u8),
UpdateDisplayName(u8),
}
impl<'a> CPlayerInfoUpdate<'a> {
pub fn new(actions: i8, players: &'a [Player]) -> Self {
Self { actions, players }
}
}
impl<'a> Packet for CPlayerInfoUpdate<'a> {
const PACKET_ID: VarInt = 0x3E;
}
impl<'a> ClientPacket for CPlayerInfoUpdate<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i8(self.actions);
bytebuf.put_list::<Player>(self.players, |p, v| {
p.put_uuid(v.uuid);
for action in v.actions {
match action {
PlayerAction::AddPlayer { name, properties } => {
p.put_string(name);
p.put_list::<Property>(properties, |p, v| {
p.put_string(&v.name);
p.put_string(&v.value);
// has signature ?
// todo: for some reason we get "got too many bytes error when using a signature"
p.put_bool(false);
// todo signature
});
}
PlayerAction::InitializeChat(_) => todo!(),
PlayerAction::UpdateGameMode(_) => todo!(),
PlayerAction::UpdateListed { listed } => p.put_bool(*listed),
PlayerAction::UpdateLatency(_) => todo!(),
PlayerAction::UpdateDisplayName(_) => todo!(),
}
}
});
}
}
pub struct CPlayerAbilities {
flags: i8,
flying_speed: f32,
field_of_view: f32,
}
impl CPlayerAbilities {
pub fn new(flags: i8, flying_speed: f32, field_of_view: f32) -> Self {
Self {
flags,
flying_speed,
field_of_view,
}
}
}
impl Packet for CPlayerAbilities {
const PACKET_ID: VarInt = 0x38;
}
impl ClientPacket for CPlayerAbilities {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i8(self.flags);
bytebuf.put_f32(self.flying_speed);
bytebuf.put_f32(self.field_of_view);
}
}
pub struct CPlayDisconnect {
reason: TextComponent,
}
impl CPlayDisconnect {
pub fn new(reason: TextComponent) -> Self {
Self { reason }
}
}
impl Packet for CPlayDisconnect {
const PACKET_ID: VarInt = 0x1D;
}
impl ClientPacket for CPlayDisconnect {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_slice(&self.reason.encode());
}
}
pub struct CSystemChatMessge {
content: TextComponent,
overlay: bool,
}
impl CSystemChatMessge {
pub fn new(content: TextComponent, overlay: bool) -> Self {
Self { content, overlay }
}
}
impl ClientPacket for CSystemChatMessge {
const PACKET_ID: VarInt = 0x6C;
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_slice(&self.content.encode());
bytebuf.put_bool(self.overlay);
}
}
pub struct CChangeDifficulty {
difficulty: u8,
locked: bool,
}
impl CChangeDifficulty {
pub fn new(difficulty: u8, locked: bool) -> Self {
Self { difficulty, locked }
}
}
impl Packet for CChangeDifficulty {
const PACKET_ID: VarInt = 0x0B;
}
impl ClientPacket for CChangeDifficulty {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_u8(self.difficulty);
bytebuf.put_bool(self.locked);
}
}
pub struct CLogin {
entity_id: i32,
is_hardcore: bool,
dimension_names: Vec<String>,
max_players: VarInt,
view_distance: VarInt,
simulated_distance: VarInt,
reduced_debug_info: bool,
enabled_respawn_screen: bool,
limited_crafting: bool,
dimension_type: VarInt,
dimension_name: String,
hashed_seed: i64,
game_mode: u8,
previous_gamemode: i8,
debug: bool,
is_flat: bool,
has_death_loc: bool,
death_dimension_name: Option<String>,
death_loc: Option<i64>, // POSITION NOT STRING
portal_cooldown: VarInt,
enforce_secure_chat: bool,
}
impl CLogin {
#[allow(clippy::too_many_arguments)]
pub fn new(
entity_id: i32,
is_hardcore: bool,
dimension_names: Vec<String>,
max_players: VarInt,
view_distance: VarInt,
simulated_distance: VarInt,
reduced_debug_info: bool,
enabled_respawn_screen: bool,
limited_crafting: bool,
dimension_type: VarInt,
dimension_name: String,
hashed_seed: i64,
game_mode: u8,
previous_gamemode: i8,
debug: bool,
is_flat: bool,
has_death_loc: bool,
death_dimension_name: Option<String>,
death_loc: Option<i64>, // todo add block pos
portal_cooldown: VarInt,
enforce_secure_chat: bool,
) -> Self {
Self {
entity_id,
is_hardcore,
dimension_names,
max_players,
view_distance,
simulated_distance,
reduced_debug_info,
enabled_respawn_screen,
limited_crafting,
dimension_type,
dimension_name,
hashed_seed,
game_mode,
previous_gamemode,
debug,
is_flat,
has_death_loc,
death_dimension_name,
death_loc,
portal_cooldown,
enforce_secure_chat,
}
}
}
impl Packet for CLogin {
const PACKET_ID: VarInt = 0x2B;
}
impl ClientPacket for CLogin {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i32(self.entity_id);
bytebuf.put_bool(self.is_hardcore);
bytebuf.put_list(&self.dimension_names, |buf, v| buf.put_string(v));
bytebuf.put_var_int(self.max_players);
bytebuf.put_var_int(self.view_distance);
bytebuf.put_var_int(self.simulated_distance);
bytebuf.put_bool(self.reduced_debug_info);
bytebuf.put_bool(self.enabled_respawn_screen);
bytebuf.put_bool(self.limited_crafting);
bytebuf.put_var_int(self.dimension_type);
bytebuf.put_string(&self.dimension_name);
bytebuf.put_i64(self.hashed_seed);
bytebuf.put_u8(self.game_mode);
bytebuf.put_i8(self.previous_gamemode);
bytebuf.put_bool(self.debug);
bytebuf.put_bool(self.is_flat);
bytebuf.put_bool(self.has_death_loc);
if self.has_death_loc {
bytebuf.put_string(self.death_dimension_name.as_ref().unwrap());
bytebuf.put_i64(self.death_loc.unwrap());
}
bytebuf.put_var_int(self.portal_cooldown);
bytebuf.put_bool(self.enforce_secure_chat);
}
}
pub struct CGameEvent {
event: u8,
value: f32,
}
impl CGameEvent {
pub fn new(event: u8, value: f32) -> Self {
Self { event, value }
}
}
impl Packet for CGameEvent {
const PACKET_ID: VarInt = 0x22;
}
impl ClientPacket for CGameEvent {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_u8(self.event);
bytebuf.put_f32(self.value);
}
}
pub struct CSyncPlayerPostion {
x: f64,
y: f64,
z: f64,
yaw: f32,
pitch: f32,
flags: i8,
teleport_id: VarInt,
}
impl CSyncPlayerPostion {
pub fn new(
x: f64,
y: f64,
z: f64,
yaw: f32,
pitch: f32,
flags: i8,
teleport_id: VarInt,
) -> Self {
Self {
x,
y,
z,
yaw,
pitch,
flags,
teleport_id,
}
}
}
impl Packet for CSyncPlayerPostion {
const PACKET_ID: VarInt = 0x40;
}
impl ClientPacket for CSyncPlayerPostion {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_f64(self.x);
bytebuf.put_f64(self.y);
bytebuf.put_f64(self.z);
bytebuf.put_f32(self.yaw.to_degrees());
bytebuf.put_f32(self.pitch.to_degrees());
bytebuf.put_i8(self.flags);
bytebuf.put_var_int(self.teleport_id);
}
}
pub struct CChunkDataUpdateLight {
chunk_x: i32,
chunk_y: i32,
heightmaps: Vec<u8>,
data: Vec<u8>,
block_entites: Vec<BlockEntity>,
sky_light_mask: BitSet,
block_light_mask: BitSet,
empty_sky_light_mask: BitSet,
sky_lights: Vec<SkyLight>,
block_lights: Vec<BlockLight>,
}
impl CChunkDataUpdateLight {
#[allow(clippy::too_many_arguments)]
pub fn new(
chunk_x: i32,
chunk_y: i32,
heightmaps: Vec<u8>,
data: Vec<u8>,
block_entites: Vec<BlockEntity>,
sky_light_mask: BitSet,
block_light_mask: BitSet,
empty_sky_light_mask: BitSet,
sky_lights: Vec<SkyLight>,
block_lights: Vec<BlockLight>,
) -> Self {
Self {
chunk_x,
chunk_y,
heightmaps,
data,
block_entites,
sky_light_mask,
block_light_mask,
empty_sky_light_mask,
sky_lights,
block_lights,
}
}
}
impl Packet for CChunkDataUpdateLight {
const PACKET_ID: VarInt = 0x27;
}
impl ClientPacket for CChunkDataUpdateLight {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i32(self.chunk_x);
bytebuf.put_i32(self.chunk_y);
bytebuf.put_slice(&self.heightmaps);
bytebuf.put_var_int(self.data.len() as VarInt);
bytebuf.put_slice(&self.data);
bytebuf.put_list::<BlockEntity>(&self.block_entites, |p, v| {
p.put_u8(v.packed_xz);
p.put_i16(v.y);
p.put_var_int(v.typee);
p.put_slice(&v.data);
});
bytebuf.put_bit_set(&self.sky_light_mask);
bytebuf.put_bit_set(&self.block_light_mask);
bytebuf.put_bit_set(&self.empty_sky_light_mask);
bytebuf.put_list::<SkyLight>(&self.sky_lights, |p, v| {
p.put_var_int(v.array.len() as VarInt);
p.put_slice(&v.array);
});
bytebuf.put_list::<BlockLight>(&self.block_lights, |p, v| {
p.put_var_int(v.array.len() as VarInt);
p.put_slice(&v.array);
});
}
}
pub struct BlockEntity {
packed_xz: u8,
y: i16,
typee: VarInt,
data: Vec<u8>,
}
pub struct SkyLight {
pub array: Vec<u8>,
}
pub struct BlockLight {
pub array: Vec<u8>,
}

View File

@ -0,0 +1,15 @@
use crate::Property;
pub enum PlayerAction {
AddPlayer {
name: String,
properties: Vec<Property>,
},
InitializeChat(u8),
UpdateGameMode(u8),
UpdateListed {
listed: bool,
},
UpdateLatency(u8),
UpdateDisplayName(u8),
}

View File

@ -0,0 +1,16 @@
use crate::{bytebuf::packet_id::Packet, VarInt};
#[derive(serde::Serialize)]
pub struct CPingResponse {
payload: i64, // must responde with the same as in `SPingRequest`
}
impl Packet for CPingResponse {
const PACKET_ID: VarInt = 0x01;
}
impl CPingResponse {
pub fn new(payload: i64) -> Self {
Self { payload }
}
}

View File

@ -0,0 +1,23 @@
use crate::{
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, VarInt,
};
pub struct CStatusResponse<'a> {
json_response: &'a str, // 32767
}
impl<'a> CStatusResponse<'a> {
pub fn new(json_response: &'a str) -> Self {
Self { json_response }
}
}
impl<'a> Packet for CStatusResponse<'a> {
const PACKET_ID: VarInt = 0x00;
}
impl<'a> ClientPacket for CStatusResponse<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_string(self.json_response);
}
}

View File

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

View File

@ -3,10 +3,7 @@ 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::{ use crate::{bytebuf::ByteBuffer, ClientPacket, PacketError, VarInt32, MAX_PACKET_SIZE};
bytebuf::{packet_id::Packet, ByteBuffer},
ClientPacket, PacketError, VarInt32, MAX_PACKET_SIZE,
};
type Cipher = cfb8::Encryptor<aes::Aes128>; type Cipher = cfb8::Encryptor<aes::Aes128>;