pumpkin-protocol: added codecs
This commit is contained in:
parent
55e8cd696e
commit
0633197b62
@ -1,11 +1,11 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use super::{ByteBuf, ReadingError};
|
||||
use bytes::Bytes;
|
||||
use bytes::Buf;
|
||||
use serde::de::{self, DeserializeSeed, SeqAccess};
|
||||
|
||||
pub struct Deserializer<'a> {
|
||||
inner: &'a mut Bytes,
|
||||
pub struct Deserializer<'a, B: Buf> {
|
||||
inner: &'a mut B,
|
||||
}
|
||||
|
||||
impl de::Error for ReadingError {
|
||||
@ -14,13 +14,13 @@ impl de::Error for ReadingError {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Deserializer<'a> {
|
||||
pub fn new(buf: &'a mut Bytes) -> Self {
|
||||
impl<'a, B: Buf> Deserializer<'a, B> {
|
||||
pub fn new(buf: &'a mut B) -> Self {
|
||||
Self { inner: buf }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> de::Deserializer<'de> for Deserializer<'_> {
|
||||
impl<'de, B: Buf> de::Deserializer<'de> for Deserializer<'_, B> {
|
||||
type Error = ReadingError;
|
||||
|
||||
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
@ -184,11 +184,11 @@ impl<'de> de::Deserializer<'de> for Deserializer<'_> {
|
||||
where
|
||||
V: de::Visitor<'de>,
|
||||
{
|
||||
struct Access<'a, 'b> {
|
||||
deserializer: &'a mut Deserializer<'b>,
|
||||
struct Access<'a, 'b, B: Buf> {
|
||||
deserializer: &'a mut Deserializer<'b, B>,
|
||||
}
|
||||
|
||||
impl<'de, 'a, 'b: 'a> SeqAccess<'de> for Access<'a, 'b> {
|
||||
impl<'de, 'a, 'b: 'a, B: Buf> SeqAccess<'de> for Access<'a, 'b, B> {
|
||||
type Error = ReadingError;
|
||||
|
||||
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
|
||||
@ -216,12 +216,12 @@ impl<'de> de::Deserializer<'de> for Deserializer<'_> {
|
||||
where
|
||||
V: de::Visitor<'de>,
|
||||
{
|
||||
struct Access<'a, 'b> {
|
||||
deserializer: &'a mut Deserializer<'b>,
|
||||
struct Access<'a, 'b, B: Buf> {
|
||||
deserializer: &'a mut Deserializer<'b, B>,
|
||||
len: usize,
|
||||
}
|
||||
|
||||
impl<'de, 'a, 'b: 'a> SeqAccess<'de> for Access<'a, 'b> {
|
||||
impl<'de, 'a, 'b: 'a, B: Buf> SeqAccess<'de> for Access<'a, 'b, B> {
|
||||
type Error = ReadingError;
|
||||
|
||||
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
use core::str;
|
||||
|
||||
use crate::{BitSet, FixedBitSet, VarInt, VarLong};
|
||||
use crate::{
|
||||
codec::{
|
||||
bit_set::BitSet, identifier::Identifier, var_int::VarInt, var_long::VarLong, Codec,
|
||||
DecodeError,
|
||||
},
|
||||
FixedBitSet,
|
||||
};
|
||||
use bytes::{Buf, BufMut};
|
||||
|
||||
mod deserializer;
|
||||
@ -54,9 +60,11 @@ pub trait ByteBuf: Buf {
|
||||
|
||||
fn try_get_var_long(&mut self) -> Result<VarLong, ReadingError>;
|
||||
|
||||
fn try_get_identifer(&mut self) -> Result<Identifier, ReadingError>;
|
||||
|
||||
fn try_get_string(&mut self) -> Result<String, ReadingError>;
|
||||
|
||||
fn try_get_string_len(&mut self, max_size: u32) -> Result<String, ReadingError>;
|
||||
fn try_get_string_len(&mut self, max_size: usize) -> Result<String, ReadingError>;
|
||||
|
||||
/// Reads a boolean. If true, the closure is called, and the returned value is
|
||||
/// wrapped in Some. Otherwise, this returns None.
|
||||
@ -181,12 +189,8 @@ impl<T: Buf> ByteBuf for T {
|
||||
match VarInt::decode(self) {
|
||||
Ok(var_int) => Ok(var_int),
|
||||
Err(error) => match error {
|
||||
crate::VarIntDecodeError::Incomplete => {
|
||||
Err(ReadingError::Incomplete("varint".to_string()))
|
||||
}
|
||||
crate::VarIntDecodeError::TooLarge => {
|
||||
Err(ReadingError::TooLarge("varint".to_string()))
|
||||
}
|
||||
DecodeError::Incomplete => Err(ReadingError::Incomplete("varint".to_string())),
|
||||
DecodeError::TooLarge => Err(ReadingError::TooLarge("varint".to_string())),
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -194,28 +198,24 @@ impl<T: Buf> ByteBuf for T {
|
||||
match VarLong::decode(self) {
|
||||
Ok(var_long) => Ok(var_long),
|
||||
Err(error) => match error {
|
||||
crate::VarLongDecodeError::Incomplete => {
|
||||
Err(ReadingError::Incomplete("varint".to_string()))
|
||||
}
|
||||
crate::VarLongDecodeError::TooLarge => {
|
||||
Err(ReadingError::TooLarge("varlong".to_string()))
|
||||
}
|
||||
DecodeError::Incomplete => Err(ReadingError::Incomplete("varint".to_string())),
|
||||
DecodeError::TooLarge => Err(ReadingError::TooLarge("varlong".to_string())),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn try_get_string(&mut self) -> Result<String, ReadingError> {
|
||||
self.try_get_string_len(i16::MAX as u32)
|
||||
self.try_get_string_len(i16::MAX as usize)
|
||||
}
|
||||
|
||||
fn try_get_string_len(&mut self, max_size: u32) -> Result<String, ReadingError> {
|
||||
fn try_get_string_len(&mut self, max_size: usize) -> Result<String, ReadingError> {
|
||||
let size = self.try_get_var_int()?.0;
|
||||
if size as u32 > max_size {
|
||||
if size as usize > max_size {
|
||||
return Err(ReadingError::TooLarge("string".to_string()));
|
||||
}
|
||||
|
||||
let data = self.try_copy_to_bytes(size as usize)?;
|
||||
if data.len() as u32 > max_size {
|
||||
if data.len() > max_size {
|
||||
return Err(ReadingError::TooLarge("string".to_string()));
|
||||
}
|
||||
match str::from_utf8(&data) {
|
||||
@ -256,6 +256,16 @@ impl<T: Buf> ByteBuf for T {
|
||||
fn try_get_fixed_bitset(&mut self, bits: usize) -> Result<FixedBitSet, ReadingError> {
|
||||
self.try_copy_to_bytes(bits.div_ceil(8))
|
||||
}
|
||||
|
||||
fn try_get_identifer(&mut self) -> Result<Identifier, ReadingError> {
|
||||
match Identifier::decode(self) {
|
||||
Ok(identifer) => Ok(identifer),
|
||||
Err(error) => match error {
|
||||
DecodeError::Incomplete => Err(ReadingError::Incomplete("identifer".to_string())),
|
||||
DecodeError::TooLarge => Err(ReadingError::TooLarge("identifer".to_string())),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ByteBufMut {
|
||||
@ -265,7 +275,7 @@ pub trait ByteBufMut {
|
||||
|
||||
fn put_string(&mut self, val: &str);
|
||||
|
||||
fn put_string_len(&mut self, val: &str, max_size: u32);
|
||||
fn put_string_len(&mut self, val: &str, max_size: usize);
|
||||
|
||||
fn put_string_array(&mut self, array: &[String]);
|
||||
|
||||
@ -277,6 +287,8 @@ pub trait ByteBufMut {
|
||||
|
||||
fn put_list<G>(&mut self, list: &[G], write: impl Fn(&mut Self, &G));
|
||||
|
||||
fn put_identifier(&mut self, val: &Identifier);
|
||||
|
||||
fn put_var_int(&mut self, value: &VarInt);
|
||||
|
||||
fn put_varint_arr(&mut self, v: &[i32]);
|
||||
@ -299,11 +311,11 @@ impl<T: BufMut> ByteBufMut for T {
|
||||
}
|
||||
|
||||
fn put_string(&mut self, val: &str) {
|
||||
self.put_string_len(val, i16::MAX as u32);
|
||||
self.put_string_len(val, i16::MAX as usize);
|
||||
}
|
||||
|
||||
fn put_string_len(&mut self, val: &str, max_size: u32) {
|
||||
if val.len() as u32 > max_size {
|
||||
fn put_string_len(&mut self, val: &str, max_size: usize) {
|
||||
if val.len() > max_size {
|
||||
// Should be panic?, I mean its our fault
|
||||
panic!("String is too big");
|
||||
}
|
||||
@ -317,15 +329,12 @@ impl<T: BufMut> ByteBufMut for T {
|
||||
}
|
||||
}
|
||||
|
||||
fn put_var_int(&mut self, value: &VarInt) {
|
||||
value.encode(self);
|
||||
fn put_var_int(&mut self, var_int: &VarInt) {
|
||||
var_int.encode(self);
|
||||
}
|
||||
|
||||
fn put_bit_set(&mut self, set: &BitSet) {
|
||||
self.put_var_int(&set.0);
|
||||
for b in set.1 {
|
||||
self.put_i64(*b);
|
||||
}
|
||||
fn put_bit_set(&mut self, bit_set: &BitSet) {
|
||||
bit_set.encode(self);
|
||||
}
|
||||
|
||||
fn put_option<G>(&mut self, val: &Option<G>, write: impl FnOnce(&mut Self, &G)) {
|
||||
@ -345,6 +354,10 @@ impl<T: BufMut> ByteBufMut for T {
|
||||
fn put_varint_arr(&mut self, v: &[i32]) {
|
||||
self.put_list(v, |p, &v| p.put_var_int(&v.into()))
|
||||
}
|
||||
|
||||
fn put_identifier(&mut self, val: &Identifier) {
|
||||
val.encode(self);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -364,14 +377,12 @@ mod test {
|
||||
bar: i32,
|
||||
}
|
||||
let foo = Foo { bar: 69 };
|
||||
let mut serializer = serializer::Serializer::new(BytesMut::new());
|
||||
let mut bytes = BytesMut::new();
|
||||
let mut serializer = serializer::Serializer::new(&mut bytes);
|
||||
foo.serialize(&mut serializer).unwrap();
|
||||
|
||||
let serialized: BytesMut = serializer.into();
|
||||
let deserialized: Foo = Foo::deserialize(deserializer::Deserializer::new(
|
||||
&mut Bytes::from(serialized),
|
||||
))
|
||||
.unwrap();
|
||||
let deserialized: Foo =
|
||||
Foo::deserialize(deserializer::Deserializer::new(&mut Bytes::from(bytes))).unwrap();
|
||||
|
||||
assert_eq!(foo, deserialized);
|
||||
}
|
||||
@ -383,14 +394,12 @@ mod test {
|
||||
bar: VarInt,
|
||||
}
|
||||
let foo = Foo { bar: 69.into() };
|
||||
let mut serializer = serializer::Serializer::new(BytesMut::new());
|
||||
let mut bytes = BytesMut::new();
|
||||
let mut serializer = serializer::Serializer::new(&mut bytes);
|
||||
foo.serialize(&mut serializer).unwrap();
|
||||
|
||||
let serialized: BytesMut = serializer.into();
|
||||
let deserialized: Foo = Foo::deserialize(deserializer::Deserializer::new(
|
||||
&mut Bytes::from(serialized),
|
||||
))
|
||||
.unwrap();
|
||||
let deserialized: Foo =
|
||||
Foo::deserialize(deserializer::Deserializer::new(&mut Bytes::from(bytes))).unwrap();
|
||||
|
||||
assert_eq!(foo, deserialized);
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use bytes::{BufMut, Bytes, BytesMut};
|
||||
use bytes::{Buf, BufMut};
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
|
||||
use crate::{ClientPacket, ServerPacket, VarIntType};
|
||||
use crate::{codec::var_int::VarIntType, ClientPacket, ServerPacket};
|
||||
|
||||
use super::{deserializer, serializer, ReadingError};
|
||||
|
||||
@ -13,14 +13,10 @@ impl<P> ClientPacket for P
|
||||
where
|
||||
P: Packet + Serialize,
|
||||
{
|
||||
fn write(&self, bytebuf: &mut BytesMut) {
|
||||
let mut serializer = serializer::Serializer::new(BytesMut::new());
|
||||
fn write(&self, bytebuf: &mut impl BufMut) {
|
||||
let mut serializer = serializer::Serializer::new(bytebuf);
|
||||
self.serialize(&mut serializer)
|
||||
.expect("Could not serialize packet");
|
||||
// We write the packet in an empty bytebuffer and then put it into our current one.
|
||||
// In the future we may do packet batching thats the reason i don't let every packet create a new bytebuffer and use
|
||||
// an existing instead
|
||||
bytebuf.put(serializer.output);
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,7 +24,7 @@ impl<P> ServerPacket for P
|
||||
where
|
||||
P: Packet + DeserializeOwned,
|
||||
{
|
||||
fn read(bytebuf: &mut Bytes) -> Result<P, ReadingError> {
|
||||
fn read(bytebuf: &mut impl Buf) -> Result<P, ReadingError> {
|
||||
let deserializer = deserializer::Deserializer::new(bytebuf);
|
||||
P::deserialize(deserializer)
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use bytes::BufMut;
|
||||
use serde::{
|
||||
ser::{self},
|
||||
Serialize,
|
||||
@ -9,34 +9,16 @@ use thiserror::Error;
|
||||
|
||||
use super::ByteBufMut;
|
||||
|
||||
pub struct Serializer {
|
||||
pub output: BytesMut,
|
||||
pub struct Serializer<B: BufMut> {
|
||||
pub output: B,
|
||||
}
|
||||
|
||||
impl Serializer {
|
||||
pub fn new(buf: BytesMut) -> Self {
|
||||
impl<B: BufMut> Serializer<B> {
|
||||
pub fn new(buf: B) -> Self {
|
||||
Self { output: buf }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Serializer> for BytesMut {
|
||||
fn from(val: Serializer) -> Self {
|
||||
val.output
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<BytesMut> for Serializer {
|
||||
fn as_ref(&self) -> &BytesMut {
|
||||
&self.output
|
||||
}
|
||||
}
|
||||
|
||||
impl AsMut<BytesMut> for Serializer {
|
||||
fn as_mut(&mut self) -> &mut BytesMut {
|
||||
&mut self.output
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SerializerError {
|
||||
#[error("serializer error {0}")]
|
||||
@ -57,7 +39,7 @@ impl ser::Error for SerializerError {
|
||||
// Structs are ignored
|
||||
// Iterables' values are written in order, but NO information (e.g. size) about the
|
||||
// iterable itself is written (list sizes should be a separate field)
|
||||
impl ser::Serializer for &mut Serializer {
|
||||
impl<B: BufMut> ser::Serializer for &mut Serializer<B> {
|
||||
type Ok = ();
|
||||
type Error = SerializerError;
|
||||
|
||||
@ -227,7 +209,7 @@ impl ser::Serializer for &mut Serializer {
|
||||
}
|
||||
}
|
||||
|
||||
impl ser::SerializeSeq for &mut Serializer {
|
||||
impl<B: BufMut> ser::SerializeSeq for &mut Serializer<B> {
|
||||
// Must match the `Ok` type of the serializer.
|
||||
type Ok = ();
|
||||
// Must match the `Error` type of the serializer.
|
||||
@ -247,7 +229,7 @@ impl ser::SerializeSeq for &mut Serializer {
|
||||
}
|
||||
}
|
||||
|
||||
impl ser::SerializeTuple for &mut Serializer {
|
||||
impl<B: BufMut> ser::SerializeTuple for &mut Serializer<B> {
|
||||
type Ok = ();
|
||||
type Error = SerializerError;
|
||||
|
||||
@ -264,7 +246,7 @@ impl ser::SerializeTuple for &mut Serializer {
|
||||
}
|
||||
|
||||
// Same thing but for tuple structs.
|
||||
impl ser::SerializeTupleStruct for &mut Serializer {
|
||||
impl<B: BufMut> ser::SerializeTupleStruct for &mut Serializer<B> {
|
||||
type Ok = ();
|
||||
type Error = SerializerError;
|
||||
|
||||
@ -289,7 +271,7 @@ impl ser::SerializeTupleStruct for &mut Serializer {
|
||||
//
|
||||
// So the `end` method in this impl is responsible for closing both the `]` and
|
||||
// the `}`.
|
||||
impl ser::SerializeTupleVariant for &mut Serializer {
|
||||
impl<B: BufMut> ser::SerializeTupleVariant for &mut Serializer<B> {
|
||||
type Ok = ();
|
||||
type Error = SerializerError;
|
||||
|
||||
@ -313,7 +295,7 @@ impl ser::SerializeTupleVariant for &mut Serializer {
|
||||
// `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 ser::SerializeMap for &mut Serializer {
|
||||
impl<B: BufMut> ser::SerializeMap for &mut Serializer<B> {
|
||||
type Ok = ();
|
||||
type Error = SerializerError;
|
||||
|
||||
@ -349,7 +331,7 @@ impl ser::SerializeMap for &mut Serializer {
|
||||
|
||||
// Structs are like maps in which the keys are constrained to be compile-time
|
||||
// constant strings.
|
||||
impl ser::SerializeStruct for &mut Serializer {
|
||||
impl<B: BufMut> ser::SerializeStruct for &mut Serializer<B> {
|
||||
type Ok = ();
|
||||
type Error = SerializerError;
|
||||
|
||||
@ -372,7 +354,7 @@ impl ser::SerializeStruct for &mut Serializer {
|
||||
|
||||
// Similar to `SerializeTupleVariant`, here the `end` method is responsible for
|
||||
// closing both of the curly braces opened by `serialize_struct_variant`.
|
||||
impl ser::SerializeStructVariant for &mut Serializer {
|
||||
impl<B: BufMut> ser::SerializeStructVariant for &mut Serializer<B> {
|
||||
type Ok = ();
|
||||
type Error = SerializerError;
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use pumpkin_macros::client_packet;
|
||||
|
||||
use crate::Identifier;
|
||||
use crate::codec::identifier::Identifier;
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
#[client_packet("config:cookie_request")]
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use bytes::BytesMut;
|
||||
use bytes::BufMut;
|
||||
use pumpkin_macros::client_packet;
|
||||
|
||||
use crate::{bytebuf::ByteBufMut, ClientPacket, KnownPack};
|
||||
@ -15,7 +15,7 @@ impl<'a> CKnownPacks<'a> {
|
||||
}
|
||||
|
||||
impl ClientPacket for CKnownPacks<'_> {
|
||||
fn write(&self, bytebuf: &mut BytesMut) {
|
||||
fn write(&self, bytebuf: &mut impl BufMut) {
|
||||
bytebuf.put_list::<KnownPack>(self.known_packs, |p, v| {
|
||||
p.put_string(v.namespace);
|
||||
p.put_string(v.id);
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use pumpkin_macros::client_packet;
|
||||
|
||||
use crate::{bytebuf::ByteBufMut, ClientPacket};
|
||||
use crate::{bytebuf::ByteBufMut, codec::identifier::Identifier, ClientPacket};
|
||||
|
||||
#[client_packet("config:registry_data")]
|
||||
pub struct CRegistryData<'a> {
|
||||
registry_id: &'a str,
|
||||
entries: &'a [RegistryEntry<'a>],
|
||||
registry_id: &'a Identifier,
|
||||
entries: &'a [RegistryEntry],
|
||||
}
|
||||
|
||||
impl<'a> CRegistryData<'a> {
|
||||
pub fn new(registry_id: &'a str, entries: &'a [RegistryEntry]) -> Self {
|
||||
pub fn new(registry_id: &'a Identifier, entries: &'a [RegistryEntry]) -> Self {
|
||||
Self {
|
||||
registry_id,
|
||||
entries,
|
||||
@ -18,18 +18,17 @@ impl<'a> CRegistryData<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RegistryEntry<'a> {
|
||||
pub entry_id: &'a str,
|
||||
pub data: BytesMut,
|
||||
pub struct RegistryEntry {
|
||||
pub entry_id: Identifier,
|
||||
pub data: Option<BytesMut>,
|
||||
}
|
||||
|
||||
impl ClientPacket for CRegistryData<'_> {
|
||||
fn write(&self, bytebuf: &mut BytesMut) {
|
||||
bytebuf.put_string(self.registry_id);
|
||||
fn write(&self, bytebuf: &mut impl BufMut) {
|
||||
bytebuf.put_identifier(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);
|
||||
p.put_identifier(&v.entry_id);
|
||||
p.put_option(&v.data, |p, v| p.put_slice(v));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::{Identifier, VarInt};
|
||||
use crate::{codec::identifier::Identifier, VarInt};
|
||||
use pumpkin_macros::client_packet;
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
use crate::Identifier;
|
||||
use pumpkin_macros::client_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::codec::identifier::Identifier;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[client_packet("login:cookie_request")]
|
||||
/// Requests a cookie that was previously stored.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use bytes::BytesMut;
|
||||
use bytes::BufMut;
|
||||
use pumpkin_macros::client_packet;
|
||||
|
||||
use crate::{bytebuf::ByteBufMut, ClientPacket, Property};
|
||||
@ -21,7 +21,7 @@ impl<'a> CLoginSuccess<'a> {
|
||||
}
|
||||
|
||||
impl ClientPacket for CLoginSuccess<'_> {
|
||||
fn write(&self, bytebuf: &mut BytesMut) {
|
||||
fn write(&self, bytebuf: &mut impl BufMut) {
|
||||
bytebuf.put_uuid(self.uuid);
|
||||
bytebuf.put_string(self.username);
|
||||
bytebuf.put_list::<Property>(self.properties, |p, v| {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::bytebuf::ByteBufMut;
|
||||
use crate::client::play::bossevent_action::BosseventAction;
|
||||
use crate::{ClientPacket, VarInt};
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use bytes::BufMut;
|
||||
use pumpkin_macros::client_packet;
|
||||
|
||||
#[client_packet("play:boss_event")]
|
||||
@ -17,7 +17,7 @@ impl<'a> CBossEvent<'a> {
|
||||
}
|
||||
|
||||
impl ClientPacket for CBossEvent<'_> {
|
||||
fn write(&self, bytebuf: &mut BytesMut) {
|
||||
fn write(&self, bytebuf: &mut impl BufMut) {
|
||||
bytebuf.put_uuid(&self.uuid);
|
||||
let action = &self.action;
|
||||
match action {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::{bytebuf::ByteBufMut, BitSet, ClientPacket, VarInt};
|
||||
use crate::{bytebuf::ByteBufMut, codec::bit_set::BitSet, ClientPacket, VarInt};
|
||||
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use pumpkin_macros::client_packet;
|
||||
@ -8,7 +8,7 @@ use pumpkin_world::{chunk::ChunkData, DIRECT_PALETTE_BITS};
|
||||
pub struct CChunkData<'a>(pub &'a ChunkData);
|
||||
|
||||
impl ClientPacket for CChunkData<'_> {
|
||||
fn write(&self, buf: &mut BytesMut) {
|
||||
fn write(&self, buf: &mut impl BufMut) {
|
||||
// Chunk X
|
||||
buf.put_i32(self.0.position.x);
|
||||
// Chunk Z
|
||||
@ -113,13 +113,13 @@ impl ClientPacket for CChunkData<'_> {
|
||||
// Sky Light Mask
|
||||
// All of the chunks, this is not optimal and uses way more data than needed but will be
|
||||
// overhauled with full lighting system.
|
||||
buf.put_bit_set(&BitSet(VarInt(1), &[0b01111111111111111111111110]));
|
||||
buf.put_bit_set(&BitSet(VarInt(1), vec![0b01111111111111111111111110]));
|
||||
// Block Light Mask
|
||||
buf.put_bit_set(&BitSet(VarInt(1), &[0]));
|
||||
buf.put_bit_set(&BitSet(VarInt(1), vec![0]));
|
||||
// Empty Sky Light Mask
|
||||
buf.put_bit_set(&BitSet(VarInt(1), &[0b0]));
|
||||
buf.put_bit_set(&BitSet(VarInt(1), vec![0b0]));
|
||||
// Empty Block Light Mask
|
||||
buf.put_bit_set(&BitSet(VarInt(1), &[0]));
|
||||
buf.put_bit_set(&BitSet(VarInt(1), vec![0]));
|
||||
|
||||
buf.put_var_int(&VarInt(self.0.blocks.subchunks_len() as i32));
|
||||
self.0.blocks.iter_subchunks().for_each(|chunk| {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use bytes::BufMut;
|
||||
use pumpkin_core::text::TextComponent;
|
||||
use pumpkin_macros::client_packet;
|
||||
|
||||
@ -29,7 +29,7 @@ impl<'a> CCommandSuggestions<'a> {
|
||||
}
|
||||
|
||||
impl ClientPacket for CCommandSuggestions<'_> {
|
||||
fn write(&self, bytebuf: &mut BytesMut) {
|
||||
fn write(&self, bytebuf: &mut impl BufMut) {
|
||||
bytebuf.put_var_int(&self.id);
|
||||
bytebuf.put_var_int(&self.start);
|
||||
bytebuf.put_var_int(&self.length);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use bytes::BufMut;
|
||||
use pumpkin_macros::client_packet;
|
||||
|
||||
use crate::{bytebuf::ByteBufMut, ClientPacket, VarInt};
|
||||
@ -19,7 +19,7 @@ impl<'a> CCommands<'a> {
|
||||
}
|
||||
|
||||
impl ClientPacket for CCommands<'_> {
|
||||
fn write(&self, bytebuf: &mut BytesMut) {
|
||||
fn write(&self, bytebuf: &mut impl BufMut) {
|
||||
bytebuf.put_list(&self.nodes, |bytebuf, node: &ProtoNode| {
|
||||
node.write_to(bytebuf)
|
||||
});
|
||||
@ -52,7 +52,7 @@ impl ProtoNode<'_> {
|
||||
const FLAG_HAS_REDIRECT: u8 = 8;
|
||||
const FLAG_HAS_SUGGESTION_TYPE: u8 = 16;
|
||||
|
||||
pub fn write_to(&self, bytebuf: &mut BytesMut) {
|
||||
pub fn write_to(&self, bytebuf: &mut impl BufMut) {
|
||||
// flags
|
||||
let flags = match self.node_type {
|
||||
ProtoNodeType::Root => 0,
|
||||
@ -188,7 +188,7 @@ impl ProtoCmdArgParser<'_> {
|
||||
|
||||
pub const SCORE_HOLDER_FLAG_ALLOW_MULTIPLE: u8 = 1;
|
||||
|
||||
pub fn write_to_buffer(&self, bytebuf: &mut BytesMut) {
|
||||
pub fn write_to_buffer(&self, bytebuf: &mut impl BufMut) {
|
||||
match self {
|
||||
Self::Bool => bytebuf.put_var_int(&0.into()),
|
||||
Self::Float { min, max } => Self::write_number_arg(&1.into(), *min, *max, bytebuf),
|
||||
@ -270,7 +270,7 @@ impl ProtoCmdArgParser<'_> {
|
||||
id: &VarInt,
|
||||
min: Option<T>,
|
||||
max: Option<T>,
|
||||
bytebuf: &mut BytesMut,
|
||||
bytebuf: &mut impl BufMut,
|
||||
) {
|
||||
let mut flags: u8 = 0;
|
||||
if min.is_some() {
|
||||
@ -291,13 +291,13 @@ impl ProtoCmdArgParser<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
fn write_with_flags(id: &VarInt, flags: u8, bytebuf: &mut BytesMut) {
|
||||
fn write_with_flags(id: &VarInt, flags: u8, bytebuf: &mut impl BufMut) {
|
||||
bytebuf.put_var_int(id);
|
||||
|
||||
bytebuf.put_u8(flags);
|
||||
}
|
||||
|
||||
fn write_with_identifier(id: &VarInt, extra_identifier: &str, bytebuf: &mut BytesMut) {
|
||||
fn write_with_identifier(id: &VarInt, extra_identifier: &str, bytebuf: &mut impl BufMut) {
|
||||
bytebuf.put_var_int(id);
|
||||
|
||||
bytebuf.put_string(extra_identifier);
|
||||
@ -313,29 +313,29 @@ pub enum StringProtoArgBehavior {
|
||||
}
|
||||
|
||||
trait NumberCmdArg {
|
||||
fn write(self, bytebuf: &mut BytesMut);
|
||||
fn write(self, bytebuf: &mut impl BufMut);
|
||||
}
|
||||
|
||||
impl NumberCmdArg for f32 {
|
||||
fn write(self, bytebuf: &mut BytesMut) {
|
||||
fn write(self, bytebuf: &mut impl BufMut) {
|
||||
bytebuf.put_f32(self);
|
||||
}
|
||||
}
|
||||
|
||||
impl NumberCmdArg for f64 {
|
||||
fn write(self, bytebuf: &mut BytesMut) {
|
||||
fn write(self, bytebuf: &mut impl BufMut) {
|
||||
bytebuf.put_f64(self);
|
||||
}
|
||||
}
|
||||
|
||||
impl NumberCmdArg for i32 {
|
||||
fn write(self, bytebuf: &mut BytesMut) {
|
||||
fn write(self, bytebuf: &mut impl BufMut) {
|
||||
bytebuf.put_i32(self);
|
||||
}
|
||||
}
|
||||
|
||||
impl NumberCmdArg for i64 {
|
||||
fn write(self, bytebuf: &mut BytesMut) {
|
||||
fn write(self, bytebuf: &mut impl BufMut) {
|
||||
bytebuf.put_i64(self);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
use crate::Identifier;
|
||||
use pumpkin_macros::client_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::codec::identifier::Identifier;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[client_packet("play:cookie_request")]
|
||||
/// Requests a cookie that was previously stored.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use bytes::BufMut;
|
||||
use pumpkin_macros::client_packet;
|
||||
|
||||
use crate::{bytebuf::ByteBufMut, ClientPacket, IDOrSoundEvent, SoundCategory, SoundEvent, VarInt};
|
||||
@ -39,11 +39,11 @@ impl CEntitySoundEffect {
|
||||
}
|
||||
|
||||
impl ClientPacket for CEntitySoundEffect {
|
||||
fn write(&self, bytebuf: &mut BytesMut) {
|
||||
fn write(&self, bytebuf: &mut impl BufMut) {
|
||||
bytebuf.put_var_int(&self.sound_event.id);
|
||||
if self.sound_event.id.0 == 0 {
|
||||
if let Some(test) = &self.sound_event.sound_event {
|
||||
bytebuf.put_string(&test.sound_name);
|
||||
bytebuf.put_identifier(&test.sound_name);
|
||||
|
||||
bytebuf.put_option(&test.range, |p, v| {
|
||||
p.put_f32(*v);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use pumpkin_macros::client_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{VarInt, VarLong};
|
||||
use crate::{codec::var_long::VarLong, VarInt};
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[client_packet("play:initialize_border")]
|
||||
|
||||
@ -3,7 +3,7 @@ use pumpkin_core::math::position::WorldPosition;
|
||||
use pumpkin_macros::client_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
use crate::{codec::identifier::Identifier, VarInt};
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[client_packet("play:login")]
|
||||
@ -11,7 +11,7 @@ pub struct CLogin<'a> {
|
||||
entity_id: i32,
|
||||
is_hardcore: bool,
|
||||
dimension_count: VarInt,
|
||||
dimension_names: &'a [&'a str],
|
||||
dimension_names: &'a [Identifier],
|
||||
max_players: VarInt,
|
||||
view_distance: VarInt,
|
||||
simulated_distance: VarInt,
|
||||
@ -20,13 +20,13 @@ pub struct CLogin<'a> {
|
||||
limited_crafting: bool,
|
||||
// Spawn Info
|
||||
dimension_type: VarInt,
|
||||
dimension_name: &'a str,
|
||||
dimension_name: Identifier,
|
||||
hashed_seed: i64,
|
||||
game_mode: u8,
|
||||
previous_gamemode: i8,
|
||||
debug: bool,
|
||||
is_flat: bool,
|
||||
death_dimension_name: Option<(&'a str, WorldPosition)>,
|
||||
death_dimension_name: Option<(Identifier, WorldPosition)>,
|
||||
portal_cooldown: VarInt,
|
||||
sealevel: VarInt,
|
||||
enforce_secure_chat: bool,
|
||||
@ -37,7 +37,7 @@ impl<'a> CLogin<'a> {
|
||||
pub fn new(
|
||||
entity_id: i32,
|
||||
is_hardcore: bool,
|
||||
dimension_names: &'a [&'a str],
|
||||
dimension_names: &'a [Identifier],
|
||||
max_players: VarInt,
|
||||
view_distance: VarInt,
|
||||
simulated_distance: VarInt,
|
||||
@ -45,13 +45,13 @@ impl<'a> CLogin<'a> {
|
||||
enabled_respawn_screen: bool,
|
||||
limited_crafting: bool,
|
||||
dimension_type: VarInt,
|
||||
dimension_name: &'a str,
|
||||
dimension_name: Identifier,
|
||||
hashed_seed: i64,
|
||||
game_mode: u8,
|
||||
previous_gamemode: i8,
|
||||
debug: bool,
|
||||
is_flat: bool,
|
||||
death_dimension_name: Option<(&'a str, WorldPosition)>,
|
||||
death_dimension_name: Option<(Identifier, WorldPosition)>,
|
||||
portal_cooldown: VarInt,
|
||||
sealevel: VarInt,
|
||||
enforce_secure_chat: bool,
|
||||
|
||||
@ -3,7 +3,7 @@ use pumpkin_core::text::TextComponent;
|
||||
use pumpkin_macros::client_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{BitSet, VarInt};
|
||||
use crate::{codec::bit_set::BitSet, VarInt};
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[client_packet("play:player_chat")]
|
||||
@ -18,7 +18,7 @@ pub struct CPlayerChatMessage<'a> {
|
||||
previous_messages_count: VarInt,
|
||||
previous_messages: &'a [PreviousMessage<'a>], // max 20
|
||||
unsigned_content: Option<TextComponent<'a>>,
|
||||
filter_type: FilterType<'a>,
|
||||
filter_type: FilterType,
|
||||
chat_type: VarInt,
|
||||
sender_name: TextComponent<'a>,
|
||||
target_name: Option<TextComponent<'a>>,
|
||||
@ -35,7 +35,7 @@ impl<'a> CPlayerChatMessage<'a> {
|
||||
salt: i64,
|
||||
previous_messages: &'a [PreviousMessage<'a>],
|
||||
unsigned_content: Option<TextComponent<'a>>,
|
||||
filter_type: FilterType<'a>,
|
||||
filter_type: FilterType,
|
||||
chat_type: VarInt,
|
||||
sender_name: TextComponent<'a>,
|
||||
target_name: Option<TextComponent<'a>>,
|
||||
@ -66,11 +66,11 @@ pub struct PreviousMessage<'a> {
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[repr(i32)]
|
||||
pub enum FilterType<'a> {
|
||||
pub enum FilterType {
|
||||
/// Message is not filtered at all
|
||||
PassThrough = 0,
|
||||
/// Message is fully filtered
|
||||
FullyFiltered = 1,
|
||||
/// Only some characters in the message are filtered
|
||||
PartiallyFiltered(BitSet<'a>) = 2,
|
||||
PartiallyFiltered(BitSet) = 2,
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use bytes::BufMut;
|
||||
use pumpkin_macros::client_packet;
|
||||
|
||||
use crate::{bytebuf::ByteBufMut, ClientPacket, Property};
|
||||
@ -23,7 +23,7 @@ impl<'a> CPlayerInfoUpdate<'a> {
|
||||
}
|
||||
|
||||
impl ClientPacket for CPlayerInfoUpdate<'_> {
|
||||
fn write(&self, bytebuf: &mut BytesMut) {
|
||||
fn write(&self, bytebuf: &mut impl BufMut) {
|
||||
bytebuf.put_i8(self.actions);
|
||||
bytebuf.put_list::<Player>(self.players, |p, v| {
|
||||
p.put_uuid(&v.uuid);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use bytes::BufMut;
|
||||
use pumpkin_core::math::vector3::Vector3;
|
||||
use pumpkin_macros::client_packet;
|
||||
|
||||
@ -35,7 +35,7 @@ impl<'a> CPlayerPosition<'a> {
|
||||
}
|
||||
|
||||
impl ClientPacket for CPlayerPosition<'_> {
|
||||
fn write(&self, bytebuf: &mut BytesMut) {
|
||||
fn write(&self, bytebuf: &mut impl BufMut) {
|
||||
bytebuf.put_var_int(&self.teleport_id);
|
||||
bytebuf.put_f64(self.position.x);
|
||||
bytebuf.put_f64(self.position.y);
|
||||
|
||||
@ -2,35 +2,35 @@ use pumpkin_core::math::position::WorldPosition;
|
||||
use pumpkin_macros::client_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
use crate::{codec::identifier::Identifier, VarInt};
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[client_packet("play:respawn")]
|
||||
pub struct CRespawn<'a> {
|
||||
pub struct CRespawn {
|
||||
dimension_type: VarInt,
|
||||
dimension_name: &'a str,
|
||||
dimension_name: Identifier,
|
||||
hashed_seed: i64,
|
||||
game_mode: u8,
|
||||
previous_gamemode: i8,
|
||||
debug: bool,
|
||||
is_flat: bool,
|
||||
death_dimension_name: Option<(&'a str, WorldPosition)>,
|
||||
death_dimension_name: Option<(Identifier, WorldPosition)>,
|
||||
portal_cooldown: VarInt,
|
||||
sealevel: VarInt,
|
||||
data_kept: u8,
|
||||
}
|
||||
|
||||
impl<'a> CRespawn<'a> {
|
||||
impl CRespawn {
|
||||
#[expect(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
dimension_type: VarInt,
|
||||
dimension_name: &'a str,
|
||||
dimension_name: Identifier,
|
||||
hashed_seed: i64,
|
||||
game_mode: u8,
|
||||
previous_gamemode: i8,
|
||||
debug: bool,
|
||||
is_flat: bool,
|
||||
death_dimension_name: Option<(&'a str, WorldPosition)>,
|
||||
death_dimension_name: Option<(Identifier, WorldPosition)>,
|
||||
portal_cooldown: VarInt,
|
||||
sealevel: VarInt,
|
||||
data_kept: u8,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use pumpkin_macros::client_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarLong;
|
||||
use crate::codec::var_long::VarLong;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[client_packet("play:set_border_lerp_size")]
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use bytes::BufMut;
|
||||
use pumpkin_macros::client_packet;
|
||||
|
||||
use crate::{bytebuf::ByteBufMut, ClientPacket, IDOrSoundEvent, SoundCategory, SoundEvent, VarInt};
|
||||
@ -45,11 +45,11 @@ impl CSoundEffect {
|
||||
}
|
||||
|
||||
impl ClientPacket for CSoundEffect {
|
||||
fn write(&self, bytebuf: &mut BytesMut) {
|
||||
fn write(&self, bytebuf: &mut impl BufMut) {
|
||||
bytebuf.put_var_int(&self.sound_event.id);
|
||||
if self.sound_event.id.0 == 0 {
|
||||
if let Some(test) = &self.sound_event.sound_event {
|
||||
bytebuf.put_string(&test.sound_name);
|
||||
bytebuf.put_identifier(&test.sound_name);
|
||||
|
||||
bytebuf.put_option(&test.range, |p, v| {
|
||||
p.put_f32(*v);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::{Identifier, VarInt};
|
||||
use crate::{codec::identifier::Identifier, VarInt};
|
||||
use pumpkin_macros::client_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use bytes::BufMut;
|
||||
use pumpkin_core::math::vector3::Vector3;
|
||||
use pumpkin_macros::client_packet;
|
||||
|
||||
@ -38,7 +38,7 @@ impl<'a> CTeleportEntity<'a> {
|
||||
}
|
||||
|
||||
impl ClientPacket for CTeleportEntity<'_> {
|
||||
fn write(&self, bytebuf: &mut BytesMut) {
|
||||
fn write(&self, bytebuf: &mut impl BufMut) {
|
||||
bytebuf.put_var_int(&self.entity_id);
|
||||
bytebuf.put_f64(self.position.x);
|
||||
bytebuf.put_f64(self.position.y);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use bytes::BufMut;
|
||||
use pumpkin_core::text::TextComponent;
|
||||
use pumpkin_macros::client_packet;
|
||||
|
||||
@ -32,7 +32,7 @@ impl<'a> CUpdateObjectives<'a> {
|
||||
}
|
||||
|
||||
impl ClientPacket for CUpdateObjectives<'_> {
|
||||
fn write(&self, bytebuf: &mut BytesMut) {
|
||||
fn write(&self, bytebuf: &mut impl BufMut) {
|
||||
bytebuf.put_string(self.objective_name);
|
||||
bytebuf.put_u8(self.mode);
|
||||
if self.mode == 0 || self.mode == 2 {
|
||||
|
||||
@ -1,48 +1,28 @@
|
||||
use std::num::NonZeroU16;
|
||||
|
||||
use bytebuf::{packet_id::Packet, ReadingError};
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use bytes::{Buf, BufMut, Bytes};
|
||||
use codec::{identifier::Identifier, var_int::VarInt};
|
||||
use pumpkin_core::text::{style::Style, TextComponent};
|
||||
use serde::{Deserialize, Serialize, Serializer};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub mod bytebuf;
|
||||
pub mod client;
|
||||
pub mod codec;
|
||||
pub mod packet_decoder;
|
||||
pub mod packet_encoder;
|
||||
pub mod query;
|
||||
pub mod server;
|
||||
pub mod slot;
|
||||
|
||||
mod var_int;
|
||||
pub use var_int::*;
|
||||
|
||||
mod var_long;
|
||||
pub use var_long::*;
|
||||
|
||||
/// To current Minecraft protocol
|
||||
/// Don't forget to change this when porting
|
||||
pub const CURRENT_MC_PROTOCOL: NonZeroU16 = unsafe { NonZeroU16::new_unchecked(769) };
|
||||
|
||||
pub const MAX_PACKET_SIZE: i32 = 2097152;
|
||||
|
||||
/// usally 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,
|
||||
@ -89,7 +69,7 @@ pub struct IDOrSoundEvent {
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct SoundEvent {
|
||||
pub sound_name: String,
|
||||
pub sound_name: Identifier,
|
||||
pub range: Option<f32>,
|
||||
}
|
||||
|
||||
@ -99,11 +79,11 @@ pub struct RawPacket {
|
||||
}
|
||||
|
||||
pub trait ClientPacket: Packet {
|
||||
fn write(&self, bytebuf: &mut BytesMut);
|
||||
fn write(&self, bytebuf: &mut impl BufMut);
|
||||
}
|
||||
|
||||
pub trait ServerPacket: Packet + Sized {
|
||||
fn read(bytebuf: &mut Bytes) -> Result<Self, ReadingError>;
|
||||
fn read(bytebuf: &mut impl Buf) -> Result<Self, ReadingError>;
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
|
||||
@ -3,7 +3,10 @@ use bytes::{Buf, Bytes, BytesMut};
|
||||
use libdeflater::{DecompressionError, Decompressor};
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::{RawPacket, VarInt, VarIntDecodeError, MAX_PACKET_SIZE};
|
||||
use crate::{
|
||||
codec::{Codec, DecodeError},
|
||||
RawPacket, VarInt, MAX_PACKET_SIZE,
|
||||
};
|
||||
|
||||
type Cipher = cfb8::Decryptor<aes::Aes128>;
|
||||
|
||||
@ -38,8 +41,8 @@ impl PacketDecoder {
|
||||
|
||||
let packet_len = match VarInt::decode(&mut r) {
|
||||
Ok(len) => len,
|
||||
Err(VarIntDecodeError::Incomplete) => return Ok(None),
|
||||
Err(VarIntDecodeError::TooLarge) => Err(PacketDecodeError::MalformedLength)?,
|
||||
Err(DecodeError::Incomplete) => return Ok(None),
|
||||
Err(DecodeError::TooLarge) => Err(PacketDecodeError::MalformedLength)?,
|
||||
};
|
||||
let packet_len = packet_len.0;
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ use thiserror::Error;
|
||||
|
||||
use libdeflater::{CompressionLvl, Compressor};
|
||||
|
||||
use crate::{ClientPacket, VarInt, MAX_PACKET_SIZE};
|
||||
use crate::{codec::Codec, ClientPacket, VarInt, MAX_PACKET_SIZE};
|
||||
|
||||
type Cipher = cfb8::Encryptor<aes::Aes128>;
|
||||
|
||||
@ -221,9 +221,8 @@ pub enum PacketEncodeError {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::bytebuf::packet_id::Packet;
|
||||
use crate::client::status::CStatusResponse;
|
||||
use crate::VarIntDecodeError;
|
||||
use crate::{bytebuf::packet_id::Packet, codec::DecodeError};
|
||||
use aes::Aes128;
|
||||
use cfb8::cipher::AsyncStreamCipher;
|
||||
use cfb8::Decryptor as Cfb8Decryptor;
|
||||
@ -247,7 +246,7 @@ mod tests {
|
||||
}
|
||||
|
||||
/// Helper function to decode a VarInt from bytes
|
||||
fn decode_varint(buffer: &mut &[u8]) -> Result<i32, VarIntDecodeError> {
|
||||
fn decode_varint(buffer: &mut &[u8]) -> Result<i32, DecodeError> {
|
||||
VarInt::decode(buffer).map(|varint| varint.0)
|
||||
}
|
||||
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
use bytes::Bytes;
|
||||
use bytes::Buf;
|
||||
use pumpkin_macros::server_packet;
|
||||
use serde::de;
|
||||
|
||||
use crate::{
|
||||
bytebuf::{ByteBuf, ReadingError},
|
||||
Identifier, ServerPacket, VarInt,
|
||||
codec::identifier::Identifier,
|
||||
ServerPacket, VarInt,
|
||||
};
|
||||
|
||||
#[server_packet("config:cookie_response")]
|
||||
@ -20,8 +21,8 @@ pub struct SCookieResponse {
|
||||
const MAX_PAYLOAD_SIZE: i32 = 5120;
|
||||
|
||||
impl ServerPacket for SCookieResponse {
|
||||
fn read(bytebuf: &mut Bytes) -> Result<Self, ReadingError> {
|
||||
let key = bytebuf.try_get_string()?;
|
||||
fn read(bytebuf: &mut impl Buf) -> Result<Self, ReadingError> {
|
||||
let key = bytebuf.try_get_identifer()?;
|
||||
let has_payload = bytebuf.try_get_bool()?;
|
||||
|
||||
if !has_payload {
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
use bytes::Bytes;
|
||||
use bytes::Buf;
|
||||
use pumpkin_macros::server_packet;
|
||||
|
||||
use crate::{
|
||||
bytebuf::{ByteBuf, ReadingError},
|
||||
Identifier, ServerPacket,
|
||||
codec::identifier::Identifier,
|
||||
ServerPacket,
|
||||
};
|
||||
|
||||
#[server_packet("config:custom_payload")]
|
||||
@ -13,10 +14,10 @@ pub struct SPluginMessage {
|
||||
}
|
||||
|
||||
impl ServerPacket for SPluginMessage {
|
||||
fn read(bytebuf: &mut Bytes) -> Result<Self, ReadingError> {
|
||||
fn read(bytebuf: &mut impl Buf) -> Result<Self, ReadingError> {
|
||||
Ok(Self {
|
||||
channel: bytebuf.try_get_string()?,
|
||||
data: bytebuf.split_to(bytebuf.len()),
|
||||
channel: bytebuf.try_get_identifer()?,
|
||||
data: bytebuf.try_copy_to_bytes(bytebuf.remaining())?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use bytes::Bytes;
|
||||
use bytes::Buf;
|
||||
use pumpkin_macros::server_packet;
|
||||
|
||||
use crate::{
|
||||
@ -15,7 +15,7 @@ pub struct SHandShake {
|
||||
}
|
||||
|
||||
impl ServerPacket for SHandShake {
|
||||
fn read(bytebuf: &mut Bytes) -> Result<Self, ReadingError> {
|
||||
fn read(bytebuf: &mut impl Buf) -> Result<Self, ReadingError> {
|
||||
Ok(Self {
|
||||
protocol_version: bytebuf.try_get_var_int()?,
|
||||
server_address: bytebuf.try_get_string_len(255)?,
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
use crate::{
|
||||
bytebuf::{ByteBuf, ReadingError},
|
||||
Identifier, ServerPacket, VarInt,
|
||||
codec::identifier::Identifier,
|
||||
ServerPacket, VarInt,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use bytes::Buf;
|
||||
use pumpkin_macros::server_packet;
|
||||
use serde::de;
|
||||
|
||||
@ -19,8 +20,8 @@ pub struct SCookieResponse {
|
||||
const MAX_PAYLOAD_SIZE: i32 = 5120;
|
||||
|
||||
impl ServerPacket for SCookieResponse {
|
||||
fn read(bytebuf: &mut Bytes) -> Result<Self, ReadingError> {
|
||||
let key = bytebuf.try_get_string()?;
|
||||
fn read(bytebuf: &mut impl Buf) -> Result<Self, ReadingError> {
|
||||
let key = bytebuf.try_get_identifer()?;
|
||||
let has_payload = bytebuf.try_get_bool()?;
|
||||
|
||||
if !has_payload {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use bytes::Bytes;
|
||||
use bytes::Buf;
|
||||
use pumpkin_macros::server_packet;
|
||||
|
||||
use crate::{
|
||||
@ -15,7 +15,7 @@ pub struct SEncryptionResponse {
|
||||
}
|
||||
|
||||
impl ServerPacket for SEncryptionResponse {
|
||||
fn read(bytebuf: &mut Bytes) -> Result<Self, ReadingError> {
|
||||
fn read(bytebuf: &mut impl Buf) -> Result<Self, ReadingError> {
|
||||
let shared_secret_length = bytebuf.try_get_var_int()?;
|
||||
let shared_secret = bytebuf.try_copy_to_bytes(shared_secret_length.0 as usize)?;
|
||||
let verify_token_length = bytebuf.try_get_var_int()?;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use bytes::Bytes;
|
||||
use bytes::Buf;
|
||||
use pumpkin_macros::server_packet;
|
||||
|
||||
use crate::{
|
||||
@ -13,7 +13,7 @@ pub struct SLoginStart {
|
||||
}
|
||||
|
||||
impl ServerPacket for SLoginStart {
|
||||
fn read(bytebuf: &mut Bytes) -> Result<Self, ReadingError> {
|
||||
fn read(bytebuf: &mut impl Buf) -> Result<Self, ReadingError> {
|
||||
Ok(Self {
|
||||
name: bytebuf.try_get_string_len(16)?,
|
||||
uuid: bytebuf.try_get_uuid()?,
|
||||
|
||||
@ -2,7 +2,7 @@ use crate::{
|
||||
bytebuf::{ByteBuf, ReadingError},
|
||||
ServerPacket, VarInt,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use bytes::{Buf, Bytes};
|
||||
use pumpkin_macros::server_packet;
|
||||
|
||||
#[server_packet("login:custom_query_answer")]
|
||||
@ -12,10 +12,10 @@ pub struct SLoginPluginResponse {
|
||||
}
|
||||
|
||||
impl ServerPacket for SLoginPluginResponse {
|
||||
fn read(bytebuf: &mut Bytes) -> Result<Self, ReadingError> {
|
||||
fn read(bytebuf: &mut impl Buf) -> Result<Self, ReadingError> {
|
||||
Ok(Self {
|
||||
message_id: bytebuf.try_get_var_int()?,
|
||||
data: bytebuf.try_get_option(|v| Ok(v.split_to(v.len())))?,
|
||||
data: bytebuf.try_get_option(|v| v.try_copy_to_bytes(v.remaining()))?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use bytes::Bytes;
|
||||
use bytes::{Buf, Bytes};
|
||||
use pumpkin_macros::server_packet;
|
||||
|
||||
use crate::{
|
||||
@ -19,7 +19,7 @@ pub struct SChatMessage {
|
||||
|
||||
// TODO
|
||||
impl ServerPacket for SChatMessage {
|
||||
fn read(bytebuf: &mut Bytes) -> Result<Self, ReadingError> {
|
||||
fn read(bytebuf: &mut impl Buf) -> Result<Self, ReadingError> {
|
||||
Ok(Self {
|
||||
message: bytebuf.try_get_string()?,
|
||||
timestamp: bytebuf.try_get_i64()?,
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
use crate::{
|
||||
bytebuf::{ByteBuf, ReadingError},
|
||||
Identifier, ServerPacket, VarInt,
|
||||
codec::identifier::Identifier,
|
||||
ServerPacket, VarInt,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use bytes::Buf;
|
||||
use pumpkin_macros::server_packet;
|
||||
use serde::de;
|
||||
|
||||
@ -19,8 +20,8 @@ pub struct SCookieResponse {
|
||||
const MAX_PAYLOAD_SIZE: i32 = 5120;
|
||||
|
||||
impl ServerPacket for SCookieResponse {
|
||||
fn read(bytebuf: &mut Bytes) -> Result<Self, ReadingError> {
|
||||
let key = bytebuf.try_get_string()?;
|
||||
fn read(bytebuf: &mut impl Buf) -> Result<Self, ReadingError> {
|
||||
let key = bytebuf.try_get_identifer()?;
|
||||
let has_payload = bytebuf.try_get_bool()?;
|
||||
|
||||
if !has_payload {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use bytes::Bytes;
|
||||
use bytes::Buf;
|
||||
use num_derive::FromPrimitive;
|
||||
use num_traits::FromPrimitive;
|
||||
use pumpkin_core::math::vector3::Vector3;
|
||||
@ -20,7 +20,7 @@ pub struct SInteract {
|
||||
|
||||
// Great job Mojang ;D
|
||||
impl ServerPacket for SInteract {
|
||||
fn read(bytebuf: &mut Bytes) -> Result<Self, ReadingError> {
|
||||
fn read(bytebuf: &mut impl Buf) -> Result<Self, ReadingError> {
|
||||
let entity_id = bytebuf.try_get_var_int()?;
|
||||
let typ = bytebuf.try_get_var_int()?;
|
||||
let action = ActionType::from_i32(typ.0)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use bytes::Bytes;
|
||||
use bytes::Buf;
|
||||
use num_derive::FromPrimitive;
|
||||
use pumpkin_macros::server_packet;
|
||||
|
||||
@ -27,7 +27,7 @@ pub enum Action {
|
||||
}
|
||||
|
||||
impl ServerPacket for SPlayerCommand {
|
||||
fn read(bytebuf: &mut Bytes) -> Result<Self, ReadingError> {
|
||||
fn read(bytebuf: &mut impl Buf) -> Result<Self, ReadingError> {
|
||||
Ok(Self {
|
||||
entity_id: bytebuf.try_get_var_int()?,
|
||||
action: bytebuf.try_get_var_int()?,
|
||||
|
||||
@ -1,151 +0,0 @@
|
||||
use std::num::NonZeroUsize;
|
||||
|
||||
use bytes::{Buf, BufMut};
|
||||
use serde::{
|
||||
de::{SeqAccess, Visitor},
|
||||
Deserialize, Deserializer, Serialize, Serializer,
|
||||
};
|
||||
use thiserror::Error;
|
||||
|
||||
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);
|
||||
|
||||
impl VarInt {
|
||||
/// The maximum number of bytes a `VarInt` can occupy.
|
||||
pub const MAX_SIZE: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(5) };
|
||||
|
||||
/// Returns the exact number of bytes this varint will write when
|
||||
/// [`Encode::encode`] is called, assuming no error occurs.
|
||||
pub const fn written_size(self) -> usize {
|
||||
match self.0 {
|
||||
0 => 1,
|
||||
n => (31 - n.leading_zeros() as usize) / 7 + 1,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encode(&self, w: &mut impl BufMut) {
|
||||
let mut val = self.0;
|
||||
for _ in 0..Self::MAX_SIZE.get() {
|
||||
let b: u8 = val as u8 & 0b01111111;
|
||||
val >>= 7;
|
||||
w.put_u8(if val == 0 { b } else { b | 0b10000000 });
|
||||
if val == 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decode(r: &mut impl Buf) -> Result<Self, VarIntDecodeError> {
|
||||
let mut val = 0;
|
||||
for i in 0..Self::MAX_SIZE.get() {
|
||||
if !r.has_remaining() {
|
||||
return Err(VarIntDecodeError::Incomplete);
|
||||
}
|
||||
let byte = r.get_u8();
|
||||
val |= (i32::from(byte) & 0x7F) << (i * 7);
|
||||
if byte & 0x80 == 0 {
|
||||
return Ok(VarInt(val));
|
||||
}
|
||||
}
|
||||
Err(VarIntDecodeError::TooLarge)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i32> for VarInt {
|
||||
fn from(value: i32) -> Self {
|
||||
VarInt(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for VarInt {
|
||||
fn from(value: u32) -> Self {
|
||||
VarInt(value as i32)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u8> for VarInt {
|
||||
fn from(value: u8) -> Self {
|
||||
VarInt(value as i32)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for VarInt {
|
||||
fn from(value: usize) -> Self {
|
||||
VarInt(value as i32)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VarInt> for i32 {
|
||||
fn from(value: VarInt) -> Self {
|
||||
value.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Error)]
|
||||
pub enum VarIntDecodeError {
|
||||
#[error("Incomplete VarInt decode")]
|
||||
Incomplete,
|
||||
#[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.get() {
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -1,152 +0,0 @@
|
||||
use std::num::NonZeroUsize;
|
||||
|
||||
use bytes::{Buf, BufMut};
|
||||
use serde::{
|
||||
de::{self, SeqAccess, Visitor},
|
||||
Deserialize, Deserializer, Serialize, Serializer,
|
||||
};
|
||||
use thiserror::Error;
|
||||
|
||||
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);
|
||||
|
||||
impl VarLong {
|
||||
/// The maximum number of bytes a `VarLong`
|
||||
pub const MAX_SIZE: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(10) };
|
||||
|
||||
/// Returns the exact number of bytes this varlong will write when
|
||||
/// [`Encode::encode`] is called, assuming no error occurs.
|
||||
pub const fn written_size(self) -> usize {
|
||||
match self.0 {
|
||||
0 => 1,
|
||||
n => (31 - n.leading_zeros() as usize) / 7 + 1,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encode(&self, w: &mut impl BufMut) {
|
||||
let mut x = self.0;
|
||||
for _ in 0..Self::MAX_SIZE.get() {
|
||||
let byte = (x & 0x7F) as u8;
|
||||
x >>= 7;
|
||||
if x == 0 {
|
||||
w.put_slice(&[byte]);
|
||||
break;
|
||||
}
|
||||
w.put_slice(&[byte | 0x80]);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decode(r: &mut impl Buf) -> Result<Self, VarLongDecodeError> {
|
||||
let mut val = 0;
|
||||
for i in 0..Self::MAX_SIZE.get() {
|
||||
if !r.has_remaining() {
|
||||
return Err(VarLongDecodeError::Incomplete);
|
||||
}
|
||||
let byte = r.get_u8();
|
||||
val |= (i64::from(byte) & 0b01111111) << (i * 7);
|
||||
if byte & 0b10000000 == 0 {
|
||||
return Ok(VarLong(val));
|
||||
}
|
||||
}
|
||||
Err(VarLongDecodeError::TooLarge)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i64> for VarLong {
|
||||
fn from(value: i64) -> Self {
|
||||
VarLong(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for VarLong {
|
||||
fn from(value: u32) -> Self {
|
||||
VarLong(value as i64)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u8> for VarLong {
|
||||
fn from(value: u8) -> Self {
|
||||
VarLong(value as i64)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for VarLong {
|
||||
fn from(value: usize) -> Self {
|
||||
VarLong(value as i64)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VarLong> for i64 {
|
||||
fn from(value: VarLong) -> Self {
|
||||
value.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Error)]
|
||||
pub enum VarLongDecodeError {
|
||||
#[error("incomplete VarLong decode")]
|
||||
Incomplete,
|
||||
#[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.get() {
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,8 @@
|
||||
use pumpkin_protocol::codec::identifier::Identifier;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct BannerPattern {
|
||||
asset_id: String,
|
||||
asset_id: Identifier,
|
||||
translation_key: String,
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use pumpkin_protocol::VarInt;
|
||||
use pumpkin_protocol::codec::var_int::VarInt;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
|
||||
@ -10,7 +10,7 @@ use indexmap::IndexMap;
|
||||
use instrument::Instrument;
|
||||
use jukebox_song::JukeboxSong;
|
||||
use paint::Painting;
|
||||
use pumpkin_protocol::client::config::RegistryEntry;
|
||||
use pumpkin_protocol::{client::config::RegistryEntry, codec::identifier::Identifier};
|
||||
pub use recipe::{
|
||||
flatten_3x3, IngredientSlot, IngredientType, Recipe, RecipeResult, RecipeType, RECIPES,
|
||||
};
|
||||
@ -41,8 +41,8 @@ pub static SYNCED_REGISTRIES: LazyLock<SyncedRegistry> = LazyLock::new(|| {
|
||||
});
|
||||
|
||||
pub struct Registry {
|
||||
pub registry_id: String,
|
||||
pub registry_entries: Vec<RegistryEntry<'static>>,
|
||||
pub registry_id: Identifier,
|
||||
pub registry_entries: Vec<RegistryEntry>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
@ -78,12 +78,12 @@ struct DataPool<T> {
|
||||
}
|
||||
|
||||
impl DimensionType {
|
||||
pub fn name(&self) -> &str {
|
||||
pub fn name(&self) -> Identifier {
|
||||
match self {
|
||||
Self::Overworld => "minecraft:overworld",
|
||||
Self::OverworldCaves => "minecraft:overworld_caves",
|
||||
Self::TheEnd => "minecraft:the_end",
|
||||
Self::TheNether => "minecraft:the_nether",
|
||||
Self::Overworld => Identifier::vanilla("overworld"),
|
||||
Self::OverworldCaves => Identifier::vanilla("overworld_caves"),
|
||||
Self::TheEnd => Identifier::vanilla("the_end"),
|
||||
Self::TheNether => Identifier::vanilla("the_nether"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -94,12 +94,12 @@ impl Registry {
|
||||
.biome
|
||||
.iter()
|
||||
.map(|s| RegistryEntry {
|
||||
entry_id: s.0,
|
||||
data: pumpkin_nbt::serializer::to_bytes_unnamed(&s.1).unwrap(),
|
||||
entry_id: Identifier::vanilla(s.0),
|
||||
data: Some(pumpkin_nbt::serializer::to_bytes_unnamed(&s.1).unwrap()),
|
||||
})
|
||||
.collect();
|
||||
let biome = Registry {
|
||||
registry_id: "minecraft:worldgen/biome".to_string(),
|
||||
registry_id: Identifier::vanilla("worldgen/biome"),
|
||||
registry_entries,
|
||||
};
|
||||
|
||||
@ -107,12 +107,12 @@ impl Registry {
|
||||
.chat_type
|
||||
.iter()
|
||||
.map(|s| RegistryEntry {
|
||||
entry_id: s.0,
|
||||
data: pumpkin_nbt::serializer::to_bytes_unnamed(&s.1).unwrap(),
|
||||
entry_id: Identifier::vanilla(s.0),
|
||||
data: Some(pumpkin_nbt::serializer::to_bytes_unnamed(&s.1).unwrap()),
|
||||
})
|
||||
.collect();
|
||||
let chat_type = Registry {
|
||||
registry_id: "minecraft:chat_type".to_string(),
|
||||
registry_id: Identifier::vanilla("chat_type"),
|
||||
registry_entries,
|
||||
};
|
||||
|
||||
@ -120,7 +120,7 @@ impl Registry {
|
||||
// .trim_pattern
|
||||
// .iter()
|
||||
// .map(|s| RegistryEntry {
|
||||
// entry_id: s.0,
|
||||
// entry_id: Identifier::vanilla(s.0),
|
||||
// data: pumpkin_nbt::serializer::to_bytes_unnamed(&s.1).unwrap(),
|
||||
// })
|
||||
// .collect();
|
||||
@ -133,7 +133,7 @@ impl Registry {
|
||||
// .trim_material
|
||||
// .iter()
|
||||
// .map(|s| RegistryEntry {
|
||||
// entry_id: s.0,
|
||||
// entry_id: Identifier::vanilla(s.0),
|
||||
// data: pumpkin_nbt::serializer::to_bytes_unnamed(&s.1).unwrap(),
|
||||
// })
|
||||
// .collect();
|
||||
@ -148,13 +148,13 @@ impl Registry {
|
||||
.map(|s| {
|
||||
let variant = s.1.clone();
|
||||
RegistryEntry {
|
||||
entry_id: s.0,
|
||||
data: pumpkin_nbt::serializer::to_bytes_unnamed(&variant).unwrap(),
|
||||
entry_id: Identifier::vanilla(s.0),
|
||||
data: Some(pumpkin_nbt::serializer::to_bytes_unnamed(&variant).unwrap()),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let wolf_variant = Registry {
|
||||
registry_id: "minecraft:wolf_variant".to_string(),
|
||||
registry_id: Identifier::vanilla("wolf_variant"),
|
||||
registry_entries,
|
||||
};
|
||||
|
||||
@ -162,12 +162,12 @@ impl Registry {
|
||||
.painting_variant
|
||||
.iter()
|
||||
.map(|s| RegistryEntry {
|
||||
entry_id: s.0,
|
||||
data: pumpkin_nbt::serializer::to_bytes_unnamed(&s.1).unwrap(),
|
||||
entry_id: Identifier::vanilla(s.0),
|
||||
data: Some(pumpkin_nbt::serializer::to_bytes_unnamed(&s.1).unwrap()),
|
||||
})
|
||||
.collect();
|
||||
let painting_variant = Registry {
|
||||
registry_id: "minecraft:painting_variant".to_string(),
|
||||
registry_id: Identifier::vanilla("painting_variant"),
|
||||
registry_entries,
|
||||
};
|
||||
|
||||
@ -175,12 +175,12 @@ impl Registry {
|
||||
.dimension_type
|
||||
.iter()
|
||||
.map(|s| RegistryEntry {
|
||||
entry_id: s.0,
|
||||
data: pumpkin_nbt::serializer::to_bytes_unnamed(&s.1).unwrap(),
|
||||
entry_id: Identifier::vanilla(s.0),
|
||||
data: Some(pumpkin_nbt::serializer::to_bytes_unnamed(&s.1).unwrap()),
|
||||
})
|
||||
.collect();
|
||||
let dimension_type = Registry {
|
||||
registry_id: "minecraft:dimension_type".to_string(),
|
||||
registry_id: Identifier::vanilla("dimension_type"),
|
||||
registry_entries,
|
||||
};
|
||||
|
||||
@ -188,12 +188,12 @@ impl Registry {
|
||||
.damage_type
|
||||
.iter()
|
||||
.map(|s| RegistryEntry {
|
||||
entry_id: s.0,
|
||||
data: pumpkin_nbt::serializer::to_bytes_unnamed(&s.1).unwrap(),
|
||||
entry_id: Identifier::vanilla(s.0),
|
||||
data: Some(pumpkin_nbt::serializer::to_bytes_unnamed(&s.1).unwrap()),
|
||||
})
|
||||
.collect();
|
||||
let damage_type = Registry {
|
||||
registry_id: "minecraft:damage_type".to_string(),
|
||||
registry_id: Identifier::vanilla("damage_type"),
|
||||
registry_entries,
|
||||
};
|
||||
|
||||
@ -201,12 +201,12 @@ impl Registry {
|
||||
.banner_pattern
|
||||
.iter()
|
||||
.map(|s| RegistryEntry {
|
||||
entry_id: s.0,
|
||||
data: pumpkin_nbt::serializer::to_bytes_unnamed(&s.1).unwrap(),
|
||||
entry_id: Identifier::vanilla(s.0),
|
||||
data: Some(pumpkin_nbt::serializer::to_bytes_unnamed(&s.1).unwrap()),
|
||||
})
|
||||
.collect();
|
||||
let banner_pattern = Registry {
|
||||
registry_id: "minecraft:banner_pattern".to_string(),
|
||||
registry_id: Identifier::vanilla("banner_pattern"),
|
||||
registry_entries,
|
||||
};
|
||||
|
||||
@ -215,7 +215,7 @@ impl Registry {
|
||||
// .enchantment
|
||||
// .iter()
|
||||
// .map(|s| RegistryEntry {
|
||||
// entry_id: s.0,
|
||||
// entry_id: Identifier::vanilla(s.0),
|
||||
// data: pumpkin_nbt::serializer::to_bytes_unnamed(&s.1).unwrap(),
|
||||
// })
|
||||
// .collect();
|
||||
@ -228,12 +228,12 @@ impl Registry {
|
||||
.jukebox_song
|
||||
.iter()
|
||||
.map(|s| RegistryEntry {
|
||||
entry_id: s.0,
|
||||
data: pumpkin_nbt::serializer::to_bytes_unnamed(&s.1).unwrap(),
|
||||
entry_id: Identifier::vanilla(s.0),
|
||||
data: Some(pumpkin_nbt::serializer::to_bytes_unnamed(&s.1).unwrap()),
|
||||
})
|
||||
.collect();
|
||||
let jukebox_song = Registry {
|
||||
registry_id: "minecraft:jukebox_song".to_string(),
|
||||
registry_id: Identifier::vanilla("jukebox_song"),
|
||||
registry_entries,
|
||||
};
|
||||
|
||||
@ -241,7 +241,7 @@ impl Registry {
|
||||
// .instrument
|
||||
// .iter()
|
||||
// .map(|s| RegistryEntry {
|
||||
// entry_id: s.0,
|
||||
// entry_id: Identifier::vanilla(s.0),
|
||||
// data: pumpkin_nbt::serializer::to_bytes_unnamed(&s.1).unwrap(),
|
||||
// })
|
||||
// .collect();
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
use pumpkin_protocol::codec::identifier::Identifier;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Painting {
|
||||
asset_id: String,
|
||||
asset_id: Identifier,
|
||||
// #[serde(skip_serializing_if = "Option::is_none")]
|
||||
// title: Option<TextComponent<'static>>,
|
||||
// #[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
use pumpkin_protocol::codec::identifier::Identifier;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct TrimPattern {
|
||||
asset_id: String,
|
||||
asset_id: Identifier,
|
||||
template_item: String,
|
||||
// description: TextComponent<'static>,
|
||||
decal: bool,
|
||||
|
||||
@ -57,6 +57,15 @@ pub struct Modifier {
|
||||
pub type_val: String,
|
||||
pub id: String,
|
||||
pub amount: f64,
|
||||
pub operation: String,
|
||||
pub operation: Operation,
|
||||
// TODO: Make this an enum
|
||||
pub slot: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Debug, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Operation {
|
||||
AddValue,
|
||||
AddMultipliedBase,
|
||||
AddMultipliedTotal,
|
||||
}
|
||||
|
||||
@ -12,9 +12,12 @@ use core::str;
|
||||
use num_traits::FromPrimitive;
|
||||
use pumpkin_config::{ADVANCED_CONFIG, BASIC_CONFIG};
|
||||
use pumpkin_core::text::TextComponent;
|
||||
use pumpkin_protocol::client::config::{CServerLinks, Label, Link, LinkType};
|
||||
use pumpkin_protocol::server::config::SCookieResponse as SCCookieResponse;
|
||||
use pumpkin_protocol::server::login::SCookieResponse as SLCookieResponse;
|
||||
use pumpkin_protocol::{
|
||||
client::config::{CServerLinks, Label, Link, LinkType},
|
||||
codec::var_int::VarInt,
|
||||
};
|
||||
use pumpkin_protocol::{
|
||||
client::{
|
||||
config::{CConfigAddResourcePack, CFinishConfig, CKnownPacks, CRegistryData},
|
||||
@ -27,7 +30,7 @@ use pumpkin_protocol::{
|
||||
login::{SEncryptionResponse, SLoginPluginResponse, SLoginStart},
|
||||
status::SStatusPingRequest,
|
||||
},
|
||||
ConnectionState, KnownPack, VarInt, CURRENT_MC_PROTOCOL,
|
||||
ConnectionState, KnownPack, CURRENT_MC_PROTOCOL,
|
||||
};
|
||||
use std::{
|
||||
num::{NonZeroI32, NonZeroU8},
|
||||
@ -318,7 +321,7 @@ impl Client {
|
||||
// TODO: allow plugins to access this
|
||||
log::debug!(
|
||||
"Received cookie_response[login]: key: \"{}\", has_payload: \"{}\", payload_length: \"{}\"",
|
||||
packet.key,
|
||||
packet.key.to_string(),
|
||||
packet.has_payload,
|
||||
packet.payload_length.unwrap_or(VarInt::from(0)).0
|
||||
);
|
||||
@ -417,8 +420,10 @@ impl Client {
|
||||
|
||||
pub async fn handle_plugin_message(&self, plugin_message: SPluginMessage) {
|
||||
log::debug!("Handling plugin message");
|
||||
if plugin_message.channel.starts_with("minecraft:brand")
|
||||
|| plugin_message.channel.starts_with("MC|Brand")
|
||||
if plugin_message
|
||||
.channel
|
||||
.to_string()
|
||||
.starts_with("minecraft:brand")
|
||||
{
|
||||
log::debug!("got a client brand");
|
||||
match str::from_utf8(&plugin_message.data) {
|
||||
@ -432,7 +437,7 @@ impl Client {
|
||||
// TODO: allow plugins to access this
|
||||
log::debug!(
|
||||
"Received cookie_response[config]: key: \"{}\", has_payload: \"{}\", payload_length: \"{}\"",
|
||||
packet.key,
|
||||
packet.key.to_string(),
|
||||
packet.has_payload,
|
||||
packet.payload_length.unwrap_or(VarInt::from(0)).0
|
||||
);
|
||||
|
||||
@ -4,7 +4,8 @@ use pumpkin_core::math::vector3::Vector3;
|
||||
use pumpkin_macros::{particle, sound};
|
||||
use pumpkin_protocol::{
|
||||
client::play::{CEntityVelocity, CParticle},
|
||||
SoundCategory, VarInt,
|
||||
codec::var_int::VarInt,
|
||||
SoundCategory,
|
||||
};
|
||||
use pumpkin_world::item::ItemStack;
|
||||
|
||||
|
||||
@ -12,9 +12,9 @@ use pumpkin_inventory::{Container, WindowType};
|
||||
use pumpkin_protocol::client::play::{
|
||||
CCloseContainer, COpenScreen, CSetContainerContent, CSetContainerProperty, CSetContainerSlot,
|
||||
};
|
||||
use pumpkin_protocol::codec::var_int::VarInt;
|
||||
use pumpkin_protocol::server::play::SClickContainer;
|
||||
use pumpkin_protocol::slot::Slot;
|
||||
use pumpkin_protocol::VarInt;
|
||||
use pumpkin_world::item::item_registry::Item;
|
||||
use pumpkin_world::item::ItemStack;
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -296,8 +296,8 @@ impl Client {
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `server`: A reference to the `Arc<Server>` instance.
|
||||
pub async fn process_packets(&self, server: &Arc<Server>) {
|
||||
/// * `server`: A reference to the `Server` instance.
|
||||
pub async fn process_packets(&self, server: &Server) {
|
||||
let mut packet_queue = self.client_packets_queue.lock().await;
|
||||
while let Some(mut packet) = packet_queue.pop_front() {
|
||||
if self.closed.load(std::sync::atomic::Ordering::Relaxed) {
|
||||
@ -330,7 +330,7 @@ impl Client {
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `server`: A reference to the `Arc<Server>` instance.
|
||||
/// * `server`: A reference to the `Server` instance.
|
||||
/// * `packet`: A mutable reference to the `RawPacket` to be processed.
|
||||
///
|
||||
/// # Returns
|
||||
@ -342,7 +342,7 @@ impl Client {
|
||||
/// Returns a `DeserializerError` if an error occurs during packet deserialization.
|
||||
pub async fn handle_packet(
|
||||
&self,
|
||||
server: &Arc<Server>,
|
||||
server: &Server,
|
||||
packet: &mut RawPacket,
|
||||
) -> Result<(), ReadingError> {
|
||||
match self.connection_state.load() {
|
||||
@ -386,7 +386,7 @@ impl Client {
|
||||
|
||||
async fn handle_status_packet(
|
||||
&self,
|
||||
server: &Arc<Server>,
|
||||
server: &Server,
|
||||
packet: &mut RawPacket,
|
||||
) -> Result<(), ReadingError> {
|
||||
log::debug!("Handling status group");
|
||||
@ -412,7 +412,7 @@ impl Client {
|
||||
|
||||
async fn handle_login_packet(
|
||||
&self,
|
||||
server: &Arc<Server>,
|
||||
server: &Server,
|
||||
packet: &mut RawPacket,
|
||||
) -> Result<(), ReadingError> {
|
||||
log::debug!("Handling login group for id");
|
||||
@ -448,7 +448,7 @@ impl Client {
|
||||
|
||||
async fn handle_config_packet(
|
||||
&self,
|
||||
server: &Arc<Server>,
|
||||
server: &Server,
|
||||
packet: &mut RawPacket,
|
||||
) -> Result<(), ReadingError> {
|
||||
log::debug!("Handling config group");
|
||||
|
||||
@ -19,11 +19,11 @@ use pumpkin_core::{
|
||||
GameMode,
|
||||
};
|
||||
use pumpkin_inventory::{InventoryError, WindowType};
|
||||
use pumpkin_protocol::codec::var_int::VarInt;
|
||||
use pumpkin_protocol::server::play::SCookieResponse as SPCookieResponse;
|
||||
use pumpkin_protocol::{
|
||||
client::play::CCommandSuggestions,
|
||||
server::play::{SCloseContainer, SCommandSuggestion, SKeepAlive, SSetPlayerGround, SUseItem},
|
||||
VarInt,
|
||||
};
|
||||
use pumpkin_protocol::{
|
||||
client::play::{
|
||||
@ -896,7 +896,7 @@ impl Player {
|
||||
// TODO: allow plugins to access this
|
||||
log::debug!(
|
||||
"Received cookie_response[play]: key: \"{}\", has_payload: \"{}\", payload_length: \"{}\"",
|
||||
packet.key,
|
||||
packet.key.to_string(),
|
||||
packet.has_payload,
|
||||
packet.payload_length.unwrap_or(VarInt::from(0)).0
|
||||
);
|
||||
|
||||
@ -2,7 +2,7 @@ use async_trait::async_trait;
|
||||
use pumpkin_core::text::color::{Color, NamedColor};
|
||||
use pumpkin_core::text::TextComponent;
|
||||
use pumpkin_protocol::client::play::CTransfer;
|
||||
use pumpkin_protocol::VarInt;
|
||||
use pumpkin_protocol::codec::var_int::VarInt;
|
||||
|
||||
use crate::command::args::arg_bounded_num::BoundedNumArgumentConsumer;
|
||||
use crate::command::args::arg_players::PlayersArgumentConsumer;
|
||||
|
||||
@ -12,7 +12,7 @@ use pumpkin_core::math::{
|
||||
use pumpkin_entity::{entity_type::EntityType, pose::EntityPose, EntityId};
|
||||
use pumpkin_protocol::{
|
||||
client::play::{CSetEntityMetadata, CTeleportEntity, Metadata},
|
||||
VarInt,
|
||||
codec::var_int::VarInt,
|
||||
};
|
||||
|
||||
use crate::world::World;
|
||||
|
||||
@ -24,7 +24,6 @@ use pumpkin_core::{
|
||||
use pumpkin_entity::{entity_type::EntityType, EntityId};
|
||||
use pumpkin_inventory::player::PlayerInventory;
|
||||
use pumpkin_macros::sound;
|
||||
use pumpkin_protocol::client::play::CUpdateTime;
|
||||
use pumpkin_protocol::server::play::{
|
||||
SCloseContainer, SCookieResponse as SPCookieResponse, SPlayPingRequest,
|
||||
};
|
||||
@ -41,15 +40,19 @@ use pumpkin_protocol::{
|
||||
SPlayerCommand, SPlayerInput, SPlayerPosition, SPlayerPositionRotation, SPlayerRotation,
|
||||
SSetCreativeSlot, SSetHeldItem, SSetPlayerGround, SSwingArm, SUseItem, SUseItemOn,
|
||||
},
|
||||
RawPacket, ServerPacket, SoundCategory, VarInt,
|
||||
RawPacket, ServerPacket, SoundCategory,
|
||||
};
|
||||
use pumpkin_protocol::{client::play::CUpdateTime, codec::var_int::VarInt};
|
||||
use pumpkin_protocol::{
|
||||
client::play::{CSetEntityMetadata, Metadata},
|
||||
server::play::{SClickContainer, SKeepAlive},
|
||||
};
|
||||
use pumpkin_world::{
|
||||
cylindrical_chunk_iterator::Cylindrical,
|
||||
item::{item_registry::get_item_by_id, ItemStack},
|
||||
item::{
|
||||
item_registry::{get_item_by_id, Operation},
|
||||
ItemStack,
|
||||
},
|
||||
};
|
||||
use tokio::sync::{Mutex, Notify};
|
||||
|
||||
@ -257,7 +260,7 @@ impl Player {
|
||||
// TODO: this should be cached in memory
|
||||
if let Some(modifiers) = &item.components.attribute_modifiers {
|
||||
for item_mod in &modifiers.modifiers {
|
||||
if item_mod.operation == "add_value" {
|
||||
if item_mod.operation == Operation::AddValue {
|
||||
if item_mod.id == "minecraft:base_attack_damage" {
|
||||
add_damage = item_mod.amount;
|
||||
}
|
||||
|
||||
@ -10,7 +10,8 @@ use base64::{engine::general_purpose, Engine as _};
|
||||
use pumpkin_config::{BasicConfiguration, BASIC_CONFIG};
|
||||
use pumpkin_protocol::{
|
||||
client::{config::CPluginMessage, status::CStatusResponse},
|
||||
Players, StatusResponse, VarInt, Version, CURRENT_MC_PROTOCOL,
|
||||
codec::{var_int::VarInt, Codec},
|
||||
Players, StatusResponse, Version, CURRENT_MC_PROTOCOL,
|
||||
};
|
||||
|
||||
use super::CURRENT_MC_VERSION;
|
||||
|
||||
@ -71,8 +71,6 @@ impl Server {
|
||||
#[allow(clippy::new_without_default)]
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
// TODO: only create when needed
|
||||
|
||||
let auth_client = BASIC_CONFIG.online_mode.then(|| {
|
||||
reqwest::Client::builder()
|
||||
.timeout(Duration::from_millis(5000))
|
||||
|
||||
@ -15,7 +15,10 @@ use pumpkin_core::math::vector2::Vector2;
|
||||
use pumpkin_core::math::{position::WorldPosition, vector3::Vector3};
|
||||
use pumpkin_core::text::{color::NamedColor, TextComponent};
|
||||
use pumpkin_entity::{entity_type::EntityType, EntityId};
|
||||
use pumpkin_protocol::client::play::CLevelEvent;
|
||||
use pumpkin_protocol::{
|
||||
client::play::CLevelEvent,
|
||||
codec::{identifier::Identifier, var_int::VarInt},
|
||||
};
|
||||
use pumpkin_protocol::{
|
||||
client::play::{CBlockUpdate, CRespawn, CSoundEffect, CWorldEvent},
|
||||
SoundCategory,
|
||||
@ -25,7 +28,7 @@ use pumpkin_protocol::{
|
||||
CChunkData, CGameEvent, CLogin, CPlayerInfoUpdate, CRemoveEntities, CRemovePlayerInfo,
|
||||
CSetEntityMetadata, CSpawnEntity, GameEvent, Metadata, PlayerAction,
|
||||
},
|
||||
ClientPacket, VarInt,
|
||||
ClientPacket,
|
||||
};
|
||||
use pumpkin_registry::DimensionType;
|
||||
use pumpkin_world::chunk::ChunkData;
|
||||
@ -223,7 +226,8 @@ impl World {
|
||||
server: &Server,
|
||||
) {
|
||||
let command_dispatcher = &server.command_dispatcher;
|
||||
let dimensions: Vec<&str> = server.dimensions.iter().map(DimensionType::name).collect();
|
||||
let dimensions: Vec<Identifier> =
|
||||
server.dimensions.iter().map(DimensionType::name).collect();
|
||||
|
||||
// This code follows the vanilla packet order
|
||||
let entity_id = player.entity_id();
|
||||
|
||||
@ -3,7 +3,8 @@ use std::collections::HashMap;
|
||||
use pumpkin_core::text::TextComponent;
|
||||
use pumpkin_protocol::{
|
||||
client::play::{CDisplayObjective, CUpdateObjectives, CUpdateScore, RenderType},
|
||||
NumberFormat, VarInt,
|
||||
codec::var_int::VarInt,
|
||||
NumberFormat,
|
||||
};
|
||||
|
||||
use super::World;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user