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