diff --git a/Cargo.lock b/Cargo.lock index d0e6a9b8e..0f8bfa1c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1295,9 +1295,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", "hashbrown 0.15.4", @@ -1476,9 +1476,9 @@ checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "lru" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f8cc7106155f10bdf99a6f379688f543ad6596a415375b36a59a054ceda1198" +checksum = "0281c2e25e62316a5c9d98f2d2e9e95a37841afdaf4383c177dbb5c1dfab0568" dependencies = [ "hashbrown 0.15.4", ] diff --git a/README.md b/README.md index c5246bacf..b14f2a9fa 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ and customizable experience. It prioritizes performance and player enjoyment whi ## Goals - **Performance**: Leveraging multi-threading for maximum speed and efficiency. -- **Compatibility**: Supports the latest Minecraft server version while adhering to Vanilla game mechanics. +- **Compatibility**: Supports the latest Java & Bedrock/Pocket Minecraft server version while adhering to Vanilla game mechanics. - **Security**: Prioritizes security by preventing known security exploits. - **Flexibility**: Highly configurable, with the ability to disable unnecessary features. - **Extensibility**: Provides a foundation for plugin development. diff --git a/pumpkin-config/src/lib.rs b/pumpkin-config/src/lib.rs index fd4f40a57..57ec9b0e2 100644 --- a/pumpkin-config/src/lib.rs +++ b/pumpkin-config/src/lib.rs @@ -108,8 +108,14 @@ pub struct AdvancedConfiguration { #[derive(Serialize, Deserialize)] #[serde(default)] pub struct BasicConfiguration { - /// The address to bind the server to. - pub server_address: SocketAddr, + // Whether Java Edition Client's are Accepted + pub java_edition: bool, + /// The address and port to which the Java Edition server will bind + pub java_edition_address: SocketAddr, + // Whether Bedrock/Pocket Edition Client's are Accepted + pub bedrock_edition: bool, + /// The address and port to which the Bedrock/Pocket Edition server will bind + pub bedrock_edition_address: SocketAddr, /// The seed for world generation. pub seed: String, /// The maximum number of players allowed on the server. Specifying `0` disables the limit. @@ -157,7 +163,10 @@ pub struct BasicConfiguration { impl Default for BasicConfiguration { fn default() -> Self { Self { - server_address: SocketAddr::new(Ipv4Addr::new(0, 0, 0, 0).into(), 25565), + java_edition: true, + java_edition_address: SocketAddr::new(Ipv4Addr::new(0, 0, 0, 0).into(), 25565), + bedrock_edition: true, + bedrock_edition_address: SocketAddr::new(Ipv4Addr::new(0, 0, 0, 0).into(), 19132), seed: "".to_string(), max_players: 100000, view_distance: NonZeroU8::new(10).unwrap(), diff --git a/pumpkin-config/src/networking/query.rs b/pumpkin-config/src/networking/query.rs index c3545b92c..9ef99f788 100644 --- a/pumpkin-config/src/networking/query.rs +++ b/pumpkin-config/src/networking/query.rs @@ -1,9 +1,19 @@ +use std::net::{Ipv4Addr, SocketAddr}; + use serde::{Deserialize, Serialize}; -#[derive(Deserialize, Serialize, Default)] +#[derive(Deserialize, Serialize)] #[serde(default)] pub struct QueryConfig { pub enabled: bool, - /// Optional; if not specified, the port the server is running on will be used. - pub port: Option, + pub address: SocketAddr, +} + +impl Default for QueryConfig { + fn default() -> Self { + Self { + enabled: true, + address: SocketAddr::new(Ipv4Addr::new(0, 0, 0, 0).into(), 25565), + } + } } diff --git a/pumpkin-inventory/src/container_click.rs b/pumpkin-inventory/src/container_click.rs index 5ab125b6b..2ed3c73dd 100644 --- a/pumpkin-inventory/src/container_click.rs +++ b/pumpkin-inventory/src/container_click.rs @@ -1,5 +1,5 @@ use crate::InventoryError; -use pumpkin_protocol::server::play::SlotActionType; +use pumpkin_protocol::java::server::play::SlotActionType; use pumpkin_world::item::ItemStack; #[derive(Debug)] diff --git a/pumpkin-inventory/src/player/player_inventory.rs b/pumpkin-inventory/src/player/player_inventory.rs index b70ec3cc2..9efdb6570 100644 --- a/pumpkin-inventory/src/player/player_inventory.rs +++ b/pumpkin-inventory/src/player/player_inventory.rs @@ -2,7 +2,7 @@ use crate::entity_equipment::EntityEquipment; use crate::equipment_slot::EquipmentSlot; use crate::screen_handler::InventoryPlayer; use async_trait::async_trait; -use pumpkin_protocol::client::play::CSetPlayerInventory; +use pumpkin_protocol::java::client::play::CSetPlayerInventory; use pumpkin_world::inventory::split_stack; use pumpkin_world::inventory::{Clearable, Inventory}; use pumpkin_world::item::ItemStack; diff --git a/pumpkin-inventory/src/screen_handler.rs b/pumpkin-inventory/src/screen_handler.rs index ab76e704b..b1df52173 100644 --- a/pumpkin-inventory/src/screen_handler.rs +++ b/pumpkin-inventory/src/screen_handler.rs @@ -2,12 +2,14 @@ use async_trait::async_trait; use log::warn; use pumpkin_data::screen::WindowType; use pumpkin_protocol::{ - client::play::{ - CSetContainerContent, CSetContainerProperty, CSetContainerSlot, CSetCursorItem, - CSetPlayerInventory, CSetSelectedSlot, - }, codec::item_stack_seralizer::OptionalItemStackHash, - server::play::SlotActionType, + java::{ + client::play::{ + CSetContainerContent, CSetContainerProperty, CSetContainerSlot, CSetCursorItem, + CSetPlayerInventory, CSetSelectedSlot, + }, + server::play::SlotActionType, + }, }; use pumpkin_util::text::TextComponent; use pumpkin_world::inventory::{ComparableInventory, Inventory}; diff --git a/pumpkin-inventory/src/sync_handler.rs b/pumpkin-inventory/src/sync_handler.rs index c4e4e1416..945aba5c0 100644 --- a/pumpkin-inventory/src/sync_handler.rs +++ b/pumpkin-inventory/src/sync_handler.rs @@ -1,13 +1,13 @@ use std::sync::Arc; use pumpkin_protocol::{ - client::play::{ - CSetContainerContent, CSetContainerProperty, CSetContainerSlot, CSetCursorItem, - }, codec::{ item_stack_seralizer::{ItemStackSerializer, OptionalItemStackHash}, var_int::VarInt, }, + java::client::play::{ + CSetContainerContent, CSetContainerProperty, CSetContainerSlot, CSetCursorItem, + }, }; use pumpkin_world::item::ItemStack; use tokio::sync::Mutex; diff --git a/pumpkin-macros/src/lib.rs b/pumpkin-macros/src/lib.rs index 4ff7af055..3e8c862d9 100644 --- a/pumpkin-macros/src/lib.rs +++ b/pumpkin-macros/src/lib.rs @@ -167,7 +167,7 @@ pub fn packet(input: TokenStream, item: TokenStream) -> TokenStream { let code = quote! { #item - impl #impl_generics crate::ser::packet::Packet for #name #ty_generics { + impl #impl_generics crate::packet::Packet for #name #ty_generics { const PACKET_ID: i32 = #input; } }; diff --git a/pumpkin-protocol/Cargo.toml b/pumpkin-protocol/Cargo.toml index 21b71edad..28029e755 100644 --- a/pumpkin-protocol/Cargo.toml +++ b/pumpkin-protocol/Cargo.toml @@ -4,8 +4,7 @@ version.workspace = true edition.workspace = true [features] -default = ["packets", "query"] -packets = ["serverbound", "clientbound"] +default = ["query"] serverbound = [] clientbound = [] query = [] diff --git a/pumpkin-protocol/src/bedrock/client/connection.rs b/pumpkin-protocol/src/bedrock/client/connection.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/pumpkin-protocol/src/bedrock/client/connection.rs @@ -0,0 +1 @@ + diff --git a/pumpkin-protocol/src/bedrock/client/mod.rs b/pumpkin-protocol/src/bedrock/client/mod.rs new file mode 100644 index 000000000..6db4677e3 --- /dev/null +++ b/pumpkin-protocol/src/bedrock/client/mod.rs @@ -0,0 +1,3 @@ +pub mod connection; +pub mod open_connection; +pub mod unconnected_pong; diff --git a/pumpkin-protocol/src/bedrock/client/open_connection.rs b/pumpkin-protocol/src/bedrock/client/open_connection.rs new file mode 100644 index 000000000..0ca783735 --- /dev/null +++ b/pumpkin-protocol/src/bedrock/client/open_connection.rs @@ -0,0 +1,46 @@ +use pumpkin_macros::packet; +use serde::Serialize; + +use crate::{bedrock::RAKNET_MAGIC, codec::socket_address::SocketAddress}; + +#[derive(Serialize)] +#[packet(0x06)] +pub struct COpenConnectionReply1 { + magic: [u8; 16], + server_guid: u64, + has_server_security: bool, + cookie: u32, + mtu: u16, +} + +impl COpenConnectionReply1 { + pub fn new(server_guid: u64, has_server_security: bool, cookie: u32, mtu: u16) -> Self { + Self { + magic: RAKNET_MAGIC, + server_guid, + has_server_security, + cookie, + mtu, + } + } +} + +#[derive(Serialize)] +#[packet(0x08)] +pub struct COpenConnectionReply2 { + server_guid: u64, + client_address: SocketAddress, + mtu: u16, + security: bool, +} + +impl COpenConnectionReply2 { + pub fn new(server_guid: u64, client_address: SocketAddress, mtu: u16, security: bool) -> Self { + Self { + server_guid, + client_address, + mtu, + security, + } + } +} diff --git a/pumpkin-protocol/src/bedrock/client/unconnected_pong.rs b/pumpkin-protocol/src/bedrock/client/unconnected_pong.rs new file mode 100644 index 000000000..560de814e --- /dev/null +++ b/pumpkin-protocol/src/bedrock/client/unconnected_pong.rs @@ -0,0 +1,63 @@ +use core::fmt; + +use pumpkin_macros::packet; +use serde::Serialize; + +use crate::codec::ascii_string::AsciiString; + +#[derive(Serialize)] +#[packet(0x1c)] +pub struct CUnconnectedPong { + time: i64, + server_guid: u64, + magic: [u8; 16], + server_id: AsciiString, +} + +pub struct ServerInfo { + /// (MCPE or MCEE for Education Edition) + pub edition: &'static str, + pub motd_line_1: &'static str, + pub protocol_version: u32, + pub version_name: &'static str, + pub player_count: i32, + pub max_player_count: u32, + pub server_unique_id: u64, + pub motd_line_2: &'static str, + pub game_mode: &'static str, + pub game_mode_numeric: u32, + pub port_ipv4: u16, + pub port_ipv6: u16, +} + +impl fmt::Display for ServerInfo { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{};{};{};{};{};{};{};{};{};{};{};{}", + self.edition, + self.motd_line_1, + self.protocol_version, + self.version_name, + self.player_count, + self.max_player_count, + self.server_unique_id, + self.motd_line_2, + self.game_mode, + self.game_mode_numeric, + self.port_ipv4, + self.port_ipv6 + ) + } +} + +impl CUnconnectedPong { + pub fn new(time: i64, server_guid: u64, magic: [u8; 16], server_id: AsciiString) -> Self { + Self { + time, + server_guid, + magic, + server_id, + } + } +} diff --git a/pumpkin-protocol/src/bedrock/mod.rs b/pumpkin-protocol/src/bedrock/mod.rs new file mode 100644 index 000000000..44ecc71f9 --- /dev/null +++ b/pumpkin-protocol/src/bedrock/mod.rs @@ -0,0 +1,8 @@ +pub mod client; +pub mod packet_decoder; +pub mod packet_encoder; +pub mod server; + +pub const RAKNET_MAGIC: [u8; 16] = [ + 0x00, 0xff, 0xff, 0x0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfd, 0xfd, 0xfd, 0xfd, 0x12, 0x34, 0x56, 0x78, +]; diff --git a/pumpkin-protocol/src/bedrock/packet_decoder.rs b/pumpkin-protocol/src/bedrock/packet_decoder.rs new file mode 100644 index 000000000..098cef8b0 --- /dev/null +++ b/pumpkin-protocol/src/bedrock/packet_decoder.rs @@ -0,0 +1,122 @@ +use std::io::Cursor; + +use async_compression::tokio::bufread::ZlibDecoder; +use bytes::Buf; +use tokio::io::{AsyncRead, AsyncReadExt, BufReader}; + +use crate::{Aes128Cfb8Dec, CompressionThreshold, PacketDecodeError, RawPacket, StreamDecryptor}; + +// decrypt -> decompress -> raw +pub enum DecompressionReader { + Decompress(ZlibDecoder>), + None(R), +} + +impl AsyncRead for DecompressionReader { + #[inline] + fn poll_read( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + buf: &mut tokio::io::ReadBuf<'_>, + ) -> std::task::Poll> { + match self.get_mut() { + Self::Decompress(reader) => { + let reader = std::pin::Pin::new(reader); + reader.poll_read(cx, buf) + } + Self::None(reader) => { + let reader = std::pin::Pin::new(reader); + reader.poll_read(cx, buf) + } + } + } +} + +pub enum DecryptionReader { + Decrypt(Box>), + None(R), +} + +impl DecryptionReader { + pub fn upgrade(self, cipher: Aes128Cfb8Dec) -> Self { + match self { + Self::None(stream) => Self::Decrypt(Box::new(StreamDecryptor::new(cipher, stream))), + _ => panic!("Cannot upgrade a stream that already has a cipher!"), + } + } +} + +impl AsyncRead for DecryptionReader { + #[inline] + fn poll_read( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + buf: &mut tokio::io::ReadBuf<'_>, + ) -> std::task::Poll> { + match self.get_mut() { + Self::Decrypt(reader) => { + let reader = std::pin::Pin::new(reader); + reader.poll_read(cx, buf) + } + Self::None(reader) => { + let reader = std::pin::Pin::new(reader); + reader.poll_read(cx, buf) + } + } + } +} + +/// Decoder: Client -> Server +/// Supports ZLib decoding/decompression +/// Supports Aes128 Encryption +pub struct UDPNetworkDecoder { + compression: Option, +} + +impl Default for UDPNetworkDecoder { + fn default() -> Self { + Self::new() + } +} + +impl UDPNetworkDecoder { + pub fn new() -> Self { + Self { compression: None } + } + + pub fn set_compression(&mut self, threshold: CompressionThreshold) { + self.compression = Some(threshold); + } + + /// NOTE: Encryption can only be set; a minecraft stream cannot go back to being unencrypted + pub fn set_encryption(&mut self, _key: &[u8; 16]) { + // if matches!(self.reader, DecryptionReader::Decrypt(_)) { + // panic!("Cannot upgrade a stream that already has a cipher!"); + // } + // let cipher = Aes128Cfb8Dec::new_from_slices(key, key).expect("invalid key"); + // take_mut::take(&mut self.reader, |decoder| decoder.upgrade(cipher)); + } + + pub async fn get_raw_packet( + &mut self, + mut reader: Cursor>, + ) -> Result { + // TODO: Serde is sync so we need to write to a buffer here :( + // Is there a way to deserialize in an asynchronous manner? + + let packet_id = reader + .try_get_u8() + .map_err(|_| PacketDecodeError::DecodeID)?; + + let mut payload = Vec::new(); + reader + .read_to_end(&mut payload) + .await + .map_err(|err| PacketDecodeError::FailedDecompression(err.to_string()))?; + + Ok(RawPacket { + id: packet_id as i32, + payload: payload.into(), + }) + } +} diff --git a/pumpkin-protocol/src/bedrock/packet_encoder.rs b/pumpkin-protocol/src/bedrock/packet_encoder.rs new file mode 100644 index 000000000..fcfa61fb4 --- /dev/null +++ b/pumpkin-protocol/src/bedrock/packet_encoder.rs @@ -0,0 +1,124 @@ +use std::net::SocketAddr; + +use bytes::Bytes; +use thiserror::Error; +use tokio::{io::AsyncWrite, net::UdpSocket}; + +use crate::{ + Aes128Cfb8Enc, CompressionLevel, CompressionThreshold, PacketEncodeError, StreamEncryptor, +}; + +// raw -> compress -> encrypt + +pub enum EncryptionWriter { + Encrypt(Box>), + None(W), +} + +impl EncryptionWriter { + pub fn upgrade(self, cipher: Aes128Cfb8Enc) -> Self { + match self { + Self::None(stream) => Self::Encrypt(Box::new(StreamEncryptor::new(cipher, stream))), + _ => panic!("Cannot upgrade a stream that already has a cipher!"), + } + } +} + +impl AsyncWrite for EncryptionWriter { + fn poll_write( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + buf: &[u8], + ) -> std::task::Poll> { + match self.get_mut() { + Self::Encrypt(writer) => { + let writer = std::pin::Pin::new(writer); + writer.poll_write(cx, buf) + } + Self::None(writer) => { + let writer = std::pin::Pin::new(writer); + writer.poll_write(cx, buf) + } + } + } + + fn poll_flush( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + match self.get_mut() { + Self::Encrypt(writer) => { + let writer = std::pin::Pin::new(writer); + writer.poll_flush(cx) + } + Self::None(writer) => { + let writer = std::pin::Pin::new(writer); + writer.poll_flush(cx) + } + } + } + + fn poll_shutdown( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + match self.get_mut() { + Self::Encrypt(writer) => { + let writer = std::pin::Pin::new(writer); + writer.poll_shutdown(cx) + } + Self::None(writer) => { + let writer = std::pin::Pin::new(writer); + writer.poll_shutdown(cx) + } + } + } +} + +/// Encoder: Server -> Client +/// Supports ZLib endecoding/compression +/// Supports Aes128 Encryption +pub struct UDPNetworkEncoder { + // compression and compression threshold + compression: Option<(CompressionThreshold, CompressionLevel)>, +} + +impl Default for UDPNetworkEncoder { + fn default() -> Self { + Self::new() + } +} + +impl UDPNetworkEncoder { + pub fn new() -> Self { + Self { compression: None } + } + + pub fn set_compression(&mut self, compression_info: (CompressionThreshold, CompressionLevel)) { + self.compression = Some(compression_info); + } + + /// NOTE: Encryption can only be set; a minecraft stream cannot go back to being unencrypted + pub fn set_encryption(&mut self, _key: &[u8; 16]) { + // if matches!(self.writer, EncryptionWriter::Encrypt(_)) { + // panic!("Cannot upgrade a stream that already has a cipher!"); + // } + // let cipher = Aes128Cfb8Enc::new_from_slices(key, key).expect("invalid key"); + // take_mut::take(&mut self.writer, |encoder| encoder.upgrade(cipher)); + } + + pub async fn write_packet( + &mut self, + packet_data: Bytes, + addr: SocketAddr, + socket: &UdpSocket, + ) -> Result<(), PacketEncodeError> { + socket.send_to(&packet_data, addr).await.unwrap(); + + Ok(()) + } +} + +#[derive(Error, Debug)] +#[error("Invalid compression Level")] +pub struct CompressionLevelError; diff --git a/pumpkin-protocol/src/bedrock/server/connection.rs b/pumpkin-protocol/src/bedrock/server/connection.rs new file mode 100644 index 000000000..dcc917e21 --- /dev/null +++ b/pumpkin-protocol/src/bedrock/server/connection.rs @@ -0,0 +1,10 @@ +use pumpkin_macros::packet; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize)] +#[packet(0x09)] +pub struct SConnectionRequest { + pub client_guid: u64, + pub time: u64, + pub security: bool, +} diff --git a/pumpkin-protocol/src/bedrock/server/mod.rs b/pumpkin-protocol/src/bedrock/server/mod.rs new file mode 100644 index 000000000..b729d3e9d --- /dev/null +++ b/pumpkin-protocol/src/bedrock/server/mod.rs @@ -0,0 +1,3 @@ +pub mod connection; +pub mod open_connection; +pub mod unconnected_ping; diff --git a/pumpkin-protocol/src/bedrock/server/open_connection.rs b/pumpkin-protocol/src/bedrock/server/open_connection.rs new file mode 100644 index 000000000..a89b8a2f5 --- /dev/null +++ b/pumpkin-protocol/src/bedrock/server/open_connection.rs @@ -0,0 +1,22 @@ +use pumpkin_macros::packet; +use serde::{Deserialize, Serialize}; + +use crate::codec::socket_address::SocketAddress; + +#[derive(Serialize, Deserialize)] +#[packet(0x05)] +/// The client sends this when attempting to join the server +pub struct SOpenConnectionRequest1 { + pub magic: [u8; 16], + pub protocol_version: u8, + pub mtu: u16, +} + +#[derive(Serialize, Deserialize)] +#[packet(0x07)] +pub struct SOpenConnectionRequest2 { + pub magic: [u8; 16], + pub server_address: SocketAddress, + pub mtu: u16, + pub client_guid: u64, +} diff --git a/pumpkin-protocol/src/bedrock/server/unconnected_ping.rs b/pumpkin-protocol/src/bedrock/server/unconnected_ping.rs new file mode 100644 index 000000000..03f76491a --- /dev/null +++ b/pumpkin-protocol/src/bedrock/server/unconnected_ping.rs @@ -0,0 +1,11 @@ +use pumpkin_macros::packet; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize)] +#[packet(0x01)] +/// Used to request Server information like MOTD +pub struct SUnconnectedPing { + pub time: i64, + pub magic: [u8; 16], + pub client_guid: i64, +} diff --git a/pumpkin-protocol/src/codec/ascii_string.rs b/pumpkin-protocol/src/codec/ascii_string.rs new file mode 100644 index 000000000..dfaa929de --- /dev/null +++ b/pumpkin-protocol/src/codec/ascii_string.rs @@ -0,0 +1,21 @@ +use std::io::Write; + +use bytes::BufMut; +use serde::{Serialize, Serializer}; + +pub struct AsciiString(pub String); + +impl Serialize for AsciiString { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut buf = Vec::new(); + + // Prefixed by a short + buf.put_u16(self.0.len() as u16); + buf.write_all(self.0.as_bytes()).unwrap(); + + serializer.serialize_bytes(&buf) + } +} diff --git a/pumpkin-protocol/src/codec/bit_set.rs b/pumpkin-protocol/src/codec/bit_set.rs index 17fa2d260..0ddbf502f 100644 --- a/pumpkin-protocol/src/codec/bit_set.rs +++ b/pumpkin-protocol/src/codec/bit_set.rs @@ -3,10 +3,10 @@ use std::io::Write; use serde::{Serialize, Serializer}; +use crate::ReadingError; +use crate::WritingError; use crate::ser::NetworkReadExt; use crate::ser::NetworkWriteExt; -use crate::ser::ReadingError; -use crate::ser::WritingError; pub struct BitSet(pub Box<[i64]>); diff --git a/pumpkin-protocol/src/codec/mod.rs b/pumpkin-protocol/src/codec/mod.rs index c15916c5a..1e4ba2d82 100644 --- a/pumpkin-protocol/src/codec/mod.rs +++ b/pumpkin-protocol/src/codec/mod.rs @@ -1,4 +1,6 @@ +pub mod ascii_string; pub mod bit_set; pub mod item_stack_seralizer; +pub mod socket_address; pub mod var_int; pub mod var_long; diff --git a/pumpkin-protocol/src/codec/socket_address.rs b/pumpkin-protocol/src/codec/socket_address.rs new file mode 100644 index 000000000..562a9f73a --- /dev/null +++ b/pumpkin-protocol/src/codec/socket_address.rs @@ -0,0 +1,93 @@ +use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; + +use bytes::BufMut; +use serde::{ + Deserialize, Serialize, Serializer, + de::{self, SeqAccess}, +}; + +pub struct SocketAddress(pub SocketAddr); + +impl Serialize for SocketAddress { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut buf = Vec::new(); + + let version = match self.0 { + SocketAddr::V4(_) => 4, + SocketAddr::V6(_) => 6, + }; + let ip = match self.0 { + SocketAddr::V4(addr) => addr.ip().to_bits(), + SocketAddr::V6(addr) => addr.ip().to_bits() as u32, + }; + + buf.put_u8(version); + buf.put_u32(ip); + buf.put_u16(self.0.port()); + + serializer.serialize_bytes(&buf) + } +} + +impl<'de> Deserialize<'de> for SocketAddress { + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + struct Visitor; + impl<'de> de::Visitor<'de> for Visitor { + type Value = SocketAddress; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("a valid socket addr") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + if let Some(version) = seq.next_element::()? { + match version { + 4 => { + let ip = seq.next_element::()?.unwrap(); + let port = seq.next_element::()?.unwrap(); + + return Ok(SocketAddress(SocketAddr::V4(SocketAddrV4::new( + Ipv4Addr::from_bits(ip), + port, + )))); + } + 6 => { + let _family = seq.next_element::()?.unwrap(); + + let port = seq.next_element::()?.unwrap(); + + let flowinfo = seq.next_element::()?.unwrap(); + let ip = seq.next_element::()?.unwrap(); + let scope_id = seq.next_element::()?.unwrap(); + + return Ok(SocketAddress(SocketAddr::V6(SocketAddrV6::new( + Ipv6Addr::from_bits(ip), + port, + flowinfo, + scope_id, + )))); + } + _ => { + return Err(serde::de::Error::custom(format!( + "Wrong Socket Address version {version}" + ))); + } + } + } + + Err(serde::de::Error::custom("Incomplete Socket Address")) + } + } + + deserializer.deserialize_seq(Visitor) + } +} diff --git a/pumpkin-protocol/src/codec/var_int.rs b/pumpkin-protocol/src/codec/var_int.rs index b3cc56954..b893a6bf9 100644 --- a/pumpkin-protocol/src/codec/var_int.rs +++ b/pumpkin-protocol/src/codec/var_int.rs @@ -4,8 +4,6 @@ use std::{ ops::Deref, }; -use crate::ser::{NetworkReadExt, NetworkWriteExt, ReadingError, WritingError}; - use bytes::BufMut; use serde::{ Deserialize, Deserializer, Serialize, Serializer, @@ -13,6 +11,8 @@ use serde::{ }; use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; +use crate::ser::{NetworkReadExt, NetworkWriteExt, ReadingError, WritingError}; + pub type VarIntType = i32; /** diff --git a/pumpkin-protocol/src/codec/var_long.rs b/pumpkin-protocol/src/codec/var_long.rs index 9ed4c418c..e898b90f9 100644 --- a/pumpkin-protocol/src/codec/var_long.rs +++ b/pumpkin-protocol/src/codec/var_long.rs @@ -4,13 +4,16 @@ use std::{ ops::Deref, }; -use crate::ser::{NetworkReadExt, NetworkWriteExt, ReadingError, WritingError}; - use serde::{ Deserialize, Deserializer, Serialize, Serializer, de::{self, SeqAccess, Visitor}, }; +use crate::{ + WritingError, + ser::{NetworkReadExt, NetworkWriteExt, ReadingError}, +}; + pub type VarLongType = i64; /** diff --git a/pumpkin-protocol/src/client/config/add_resource_pack.rs b/pumpkin-protocol/src/java/client/config/add_resource_pack.rs similarity index 100% rename from pumpkin-protocol/src/client/config/add_resource_pack.rs rename to pumpkin-protocol/src/java/client/config/add_resource_pack.rs diff --git a/pumpkin-protocol/src/client/config/config_disconnect.rs b/pumpkin-protocol/src/java/client/config/config_disconnect.rs similarity index 100% rename from pumpkin-protocol/src/client/config/config_disconnect.rs rename to pumpkin-protocol/src/java/client/config/config_disconnect.rs diff --git a/pumpkin-protocol/src/client/config/cookie_request.rs b/pumpkin-protocol/src/java/client/config/cookie_request.rs similarity index 100% rename from pumpkin-protocol/src/client/config/cookie_request.rs rename to pumpkin-protocol/src/java/client/config/cookie_request.rs diff --git a/pumpkin-protocol/src/client/config/finish_config.rs b/pumpkin-protocol/src/java/client/config/finish_config.rs similarity index 100% rename from pumpkin-protocol/src/client/config/finish_config.rs rename to pumpkin-protocol/src/java/client/config/finish_config.rs diff --git a/pumpkin-protocol/src/client/config/known_packs.rs b/pumpkin-protocol/src/java/client/config/known_packs.rs similarity index 100% rename from pumpkin-protocol/src/client/config/known_packs.rs rename to pumpkin-protocol/src/java/client/config/known_packs.rs diff --git a/pumpkin-protocol/src/client/config/mod.rs b/pumpkin-protocol/src/java/client/config/mod.rs similarity index 100% rename from pumpkin-protocol/src/client/config/mod.rs rename to pumpkin-protocol/src/java/client/config/mod.rs diff --git a/pumpkin-protocol/src/client/config/plugin_message.rs b/pumpkin-protocol/src/java/client/config/plugin_message.rs similarity index 100% rename from pumpkin-protocol/src/client/config/plugin_message.rs rename to pumpkin-protocol/src/java/client/config/plugin_message.rs diff --git a/pumpkin-protocol/src/client/config/registry_data.rs b/pumpkin-protocol/src/java/client/config/registry_data.rs similarity index 100% rename from pumpkin-protocol/src/client/config/registry_data.rs rename to pumpkin-protocol/src/java/client/config/registry_data.rs diff --git a/pumpkin-protocol/src/client/config/server_links.rs b/pumpkin-protocol/src/java/client/config/server_links.rs similarity index 100% rename from pumpkin-protocol/src/client/config/server_links.rs rename to pumpkin-protocol/src/java/client/config/server_links.rs diff --git a/pumpkin-protocol/src/client/config/store_cookie.rs b/pumpkin-protocol/src/java/client/config/store_cookie.rs similarity index 100% rename from pumpkin-protocol/src/client/config/store_cookie.rs rename to pumpkin-protocol/src/java/client/config/store_cookie.rs diff --git a/pumpkin-protocol/src/client/config/transfer.rs b/pumpkin-protocol/src/java/client/config/transfer.rs similarity index 100% rename from pumpkin-protocol/src/client/config/transfer.rs rename to pumpkin-protocol/src/java/client/config/transfer.rs diff --git a/pumpkin-protocol/src/client/config/update_tags.rs b/pumpkin-protocol/src/java/client/config/update_tags.rs similarity index 95% rename from pumpkin-protocol/src/client/config/update_tags.rs rename to pumpkin-protocol/src/java/client/config/update_tags.rs index 435cbccae..c4d386932 100644 --- a/pumpkin-protocol/src/client/config/update_tags.rs +++ b/pumpkin-protocol/src/java/client/config/update_tags.rs @@ -1,9 +1,6 @@ use std::io::Write; -use crate::{ - ClientPacket, - ser::{NetworkWriteExt, WritingError}, -}; +use crate::{ClientPacket, WritingError, ser::NetworkWriteExt}; use pumpkin_data::{ block_properties::get_block, diff --git a/pumpkin-protocol/src/client/login/cookie_request.rs b/pumpkin-protocol/src/java/client/login/cookie_request.rs similarity index 100% rename from pumpkin-protocol/src/client/login/cookie_request.rs rename to pumpkin-protocol/src/java/client/login/cookie_request.rs diff --git a/pumpkin-protocol/src/client/login/encryption_request.rs b/pumpkin-protocol/src/java/client/login/encryption_request.rs similarity index 100% rename from pumpkin-protocol/src/client/login/encryption_request.rs rename to pumpkin-protocol/src/java/client/login/encryption_request.rs diff --git a/pumpkin-protocol/src/client/login/login_disconnect.rs b/pumpkin-protocol/src/java/client/login/login_disconnect.rs similarity index 100% rename from pumpkin-protocol/src/client/login/login_disconnect.rs rename to pumpkin-protocol/src/java/client/login/login_disconnect.rs diff --git a/pumpkin-protocol/src/client/login/login_success.rs b/pumpkin-protocol/src/java/client/login/login_success.rs similarity index 100% rename from pumpkin-protocol/src/client/login/login_success.rs rename to pumpkin-protocol/src/java/client/login/login_success.rs diff --git a/pumpkin-protocol/src/client/login/mod.rs b/pumpkin-protocol/src/java/client/login/mod.rs similarity index 100% rename from pumpkin-protocol/src/client/login/mod.rs rename to pumpkin-protocol/src/java/client/login/mod.rs diff --git a/pumpkin-protocol/src/client/login/plugin_request.rs b/pumpkin-protocol/src/java/client/login/plugin_request.rs similarity index 100% rename from pumpkin-protocol/src/client/login/plugin_request.rs rename to pumpkin-protocol/src/java/client/login/plugin_request.rs diff --git a/pumpkin-protocol/src/client/login/set_compression.rs b/pumpkin-protocol/src/java/client/login/set_compression.rs similarity index 100% rename from pumpkin-protocol/src/client/login/set_compression.rs rename to pumpkin-protocol/src/java/client/login/set_compression.rs diff --git a/pumpkin-protocol/src/client/mod.rs b/pumpkin-protocol/src/java/client/mod.rs similarity index 100% rename from pumpkin-protocol/src/client/mod.rs rename to pumpkin-protocol/src/java/client/mod.rs diff --git a/pumpkin-protocol/src/client/play/acknowledge_block.rs b/pumpkin-protocol/src/java/client/play/acknowledge_block.rs similarity index 100% rename from pumpkin-protocol/src/client/play/acknowledge_block.rs rename to pumpkin-protocol/src/java/client/play/acknowledge_block.rs diff --git a/pumpkin-protocol/src/client/play/actionbar.rs b/pumpkin-protocol/src/java/client/play/actionbar.rs similarity index 100% rename from pumpkin-protocol/src/client/play/actionbar.rs rename to pumpkin-protocol/src/java/client/play/actionbar.rs diff --git a/pumpkin-protocol/src/client/play/block_destroy_stage.rs b/pumpkin-protocol/src/java/client/play/block_destroy_stage.rs similarity index 100% rename from pumpkin-protocol/src/client/play/block_destroy_stage.rs rename to pumpkin-protocol/src/java/client/play/block_destroy_stage.rs diff --git a/pumpkin-protocol/src/client/play/block_entity_data.rs b/pumpkin-protocol/src/java/client/play/block_entity_data.rs similarity index 100% rename from pumpkin-protocol/src/client/play/block_entity_data.rs rename to pumpkin-protocol/src/java/client/play/block_entity_data.rs diff --git a/pumpkin-protocol/src/client/play/block_event.rs b/pumpkin-protocol/src/java/client/play/block_event.rs similarity index 100% rename from pumpkin-protocol/src/client/play/block_event.rs rename to pumpkin-protocol/src/java/client/play/block_event.rs diff --git a/pumpkin-protocol/src/client/play/block_update.rs b/pumpkin-protocol/src/java/client/play/block_update.rs similarity index 100% rename from pumpkin-protocol/src/client/play/block_update.rs rename to pumpkin-protocol/src/java/client/play/block_update.rs diff --git a/pumpkin-protocol/src/client/play/boss_event.rs b/pumpkin-protocol/src/java/client/play/boss_event.rs similarity index 93% rename from pumpkin-protocol/src/client/play/boss_event.rs rename to pumpkin-protocol/src/java/client/play/boss_event.rs index a39c90b57..d93a9b310 100644 --- a/pumpkin-protocol/src/client/play/boss_event.rs +++ b/pumpkin-protocol/src/java/client/play/boss_event.rs @@ -1,8 +1,8 @@ use std::io::Write; -use crate::ClientPacket; -use crate::client::play::bossevent_action::BosseventAction; -use crate::ser::{NetworkWriteExt, WritingError}; +use crate::java::client::play::BosseventAction; +use crate::ser::NetworkWriteExt; +use crate::{ClientPacket, WritingError}; use pumpkin_data::packet::clientbound::PLAY_BOSS_EVENT; use pumpkin_macros::packet; diff --git a/pumpkin-protocol/src/client/play/bossevent_action.rs b/pumpkin-protocol/src/java/client/play/bossevent_action.rs similarity index 100% rename from pumpkin-protocol/src/client/play/bossevent_action.rs rename to pumpkin-protocol/src/java/client/play/bossevent_action.rs diff --git a/pumpkin-protocol/src/client/play/center_chunk.rs b/pumpkin-protocol/src/java/client/play/center_chunk.rs similarity index 100% rename from pumpkin-protocol/src/client/play/center_chunk.rs rename to pumpkin-protocol/src/java/client/play/center_chunk.rs diff --git a/pumpkin-protocol/src/client/play/change_difficulty.rs b/pumpkin-protocol/src/java/client/play/change_difficulty.rs similarity index 100% rename from pumpkin-protocol/src/client/play/change_difficulty.rs rename to pumpkin-protocol/src/java/client/play/change_difficulty.rs diff --git a/pumpkin-protocol/src/client/play/chunk_batch_end.rs b/pumpkin-protocol/src/java/client/play/chunk_batch_end.rs similarity index 100% rename from pumpkin-protocol/src/client/play/chunk_batch_end.rs rename to pumpkin-protocol/src/java/client/play/chunk_batch_end.rs diff --git a/pumpkin-protocol/src/client/play/chunk_batch_start.rs b/pumpkin-protocol/src/java/client/play/chunk_batch_start.rs similarity index 100% rename from pumpkin-protocol/src/client/play/chunk_batch_start.rs rename to pumpkin-protocol/src/java/client/play/chunk_batch_start.rs diff --git a/pumpkin-protocol/src/client/play/chunk_data.rs b/pumpkin-protocol/src/java/client/play/chunk_data.rs similarity index 99% rename from pumpkin-protocol/src/client/play/chunk_data.rs rename to pumpkin-protocol/src/java/client/play/chunk_data.rs index 0686d206c..f98fc4f4a 100644 --- a/pumpkin-protocol/src/client/play/chunk_data.rs +++ b/pumpkin-protocol/src/java/client/play/chunk_data.rs @@ -1,8 +1,6 @@ +use crate::WritingError; use crate::codec::bit_set::BitSet; -use crate::{ - ClientPacket, VarInt, - ser::{NetworkWriteExt, WritingError}, -}; +use crate::{ClientPacket, VarInt, ser::NetworkWriteExt}; use pumpkin_data::packet::clientbound::PLAY_LEVEL_CHUNK_WITH_LIGHT; use pumpkin_macros::packet; use pumpkin_nbt::END_ID; diff --git a/pumpkin-protocol/src/client/play/clear_title.rs b/pumpkin-protocol/src/java/client/play/clear_title.rs similarity index 100% rename from pumpkin-protocol/src/client/play/clear_title.rs rename to pumpkin-protocol/src/java/client/play/clear_title.rs diff --git a/pumpkin-protocol/src/client/play/close_container.rs b/pumpkin-protocol/src/java/client/play/close_container.rs similarity index 100% rename from pumpkin-protocol/src/client/play/close_container.rs rename to pumpkin-protocol/src/java/client/play/close_container.rs diff --git a/pumpkin-protocol/src/client/play/combat_death.rs b/pumpkin-protocol/src/java/client/play/combat_death.rs similarity index 100% rename from pumpkin-protocol/src/client/play/combat_death.rs rename to pumpkin-protocol/src/java/client/play/combat_death.rs diff --git a/pumpkin-protocol/src/client/play/command_suggestions.rs b/pumpkin-protocol/src/java/client/play/command_suggestions.rs similarity index 100% rename from pumpkin-protocol/src/client/play/command_suggestions.rs rename to pumpkin-protocol/src/java/client/play/command_suggestions.rs diff --git a/pumpkin-protocol/src/client/play/commands.rs b/pumpkin-protocol/src/java/client/play/commands.rs similarity index 99% rename from pumpkin-protocol/src/client/play/commands.rs rename to pumpkin-protocol/src/java/client/play/commands.rs index a512aeba0..19cc7f3f2 100644 --- a/pumpkin-protocol/src/client/play/commands.rs +++ b/pumpkin-protocol/src/java/client/play/commands.rs @@ -3,10 +3,7 @@ use std::io::Write; use pumpkin_data::packet::clientbound::PLAY_COMMANDS; use pumpkin_macros::packet; -use crate::{ - ClientPacket, VarInt, - ser::{NetworkWriteExt, WritingError}, -}; +use crate::{ClientPacket, VarInt, WritingError, ser::NetworkWriteExt}; #[packet(PLAY_COMMANDS)] pub struct CCommands<'a> { diff --git a/pumpkin-protocol/src/client/play/cookie_request.rs b/pumpkin-protocol/src/java/client/play/cookie_request.rs similarity index 100% rename from pumpkin-protocol/src/client/play/cookie_request.rs rename to pumpkin-protocol/src/java/client/play/cookie_request.rs diff --git a/pumpkin-protocol/src/client/play/damage_event.rs b/pumpkin-protocol/src/java/client/play/damage_event.rs similarity index 100% rename from pumpkin-protocol/src/client/play/damage_event.rs rename to pumpkin-protocol/src/java/client/play/damage_event.rs diff --git a/pumpkin-protocol/src/client/play/disconnect.rs b/pumpkin-protocol/src/java/client/play/disconnect.rs similarity index 100% rename from pumpkin-protocol/src/client/play/disconnect.rs rename to pumpkin-protocol/src/java/client/play/disconnect.rs diff --git a/pumpkin-protocol/src/client/play/disguised_chat_message.rs b/pumpkin-protocol/src/java/client/play/disguised_chat_message.rs similarity index 100% rename from pumpkin-protocol/src/client/play/disguised_chat_message.rs rename to pumpkin-protocol/src/java/client/play/disguised_chat_message.rs diff --git a/pumpkin-protocol/src/client/play/display_objective.rs b/pumpkin-protocol/src/java/client/play/display_objective.rs similarity index 100% rename from pumpkin-protocol/src/client/play/display_objective.rs rename to pumpkin-protocol/src/java/client/play/display_objective.rs diff --git a/pumpkin-protocol/src/client/play/entity_animation.rs b/pumpkin-protocol/src/java/client/play/entity_animation.rs similarity index 100% rename from pumpkin-protocol/src/client/play/entity_animation.rs rename to pumpkin-protocol/src/java/client/play/entity_animation.rs diff --git a/pumpkin-protocol/src/client/play/entity_metadata.rs b/pumpkin-protocol/src/java/client/play/entity_metadata.rs similarity index 100% rename from pumpkin-protocol/src/client/play/entity_metadata.rs rename to pumpkin-protocol/src/java/client/play/entity_metadata.rs diff --git a/pumpkin-protocol/src/client/play/entity_position_sync.rs b/pumpkin-protocol/src/java/client/play/entity_position_sync.rs similarity index 100% rename from pumpkin-protocol/src/client/play/entity_position_sync.rs rename to pumpkin-protocol/src/java/client/play/entity_position_sync.rs diff --git a/pumpkin-protocol/src/client/play/entity_sound_effect.rs b/pumpkin-protocol/src/java/client/play/entity_sound_effect.rs similarity index 100% rename from pumpkin-protocol/src/client/play/entity_sound_effect.rs rename to pumpkin-protocol/src/java/client/play/entity_sound_effect.rs diff --git a/pumpkin-protocol/src/client/play/entity_status.rs b/pumpkin-protocol/src/java/client/play/entity_status.rs similarity index 100% rename from pumpkin-protocol/src/client/play/entity_status.rs rename to pumpkin-protocol/src/java/client/play/entity_status.rs diff --git a/pumpkin-protocol/src/client/play/entity_velocity.rs b/pumpkin-protocol/src/java/client/play/entity_velocity.rs similarity index 100% rename from pumpkin-protocol/src/client/play/entity_velocity.rs rename to pumpkin-protocol/src/java/client/play/entity_velocity.rs diff --git a/pumpkin-protocol/src/client/play/explode.rs b/pumpkin-protocol/src/java/client/play/explode.rs similarity index 100% rename from pumpkin-protocol/src/client/play/explode.rs rename to pumpkin-protocol/src/java/client/play/explode.rs diff --git a/pumpkin-protocol/src/client/play/game_event.rs b/pumpkin-protocol/src/java/client/play/game_event.rs similarity index 100% rename from pumpkin-protocol/src/client/play/game_event.rs rename to pumpkin-protocol/src/java/client/play/game_event.rs diff --git a/pumpkin-protocol/src/client/play/head_rot.rs b/pumpkin-protocol/src/java/client/play/head_rot.rs similarity index 100% rename from pumpkin-protocol/src/client/play/head_rot.rs rename to pumpkin-protocol/src/java/client/play/head_rot.rs diff --git a/pumpkin-protocol/src/client/play/hurt_animation.rs b/pumpkin-protocol/src/java/client/play/hurt_animation.rs similarity index 100% rename from pumpkin-protocol/src/client/play/hurt_animation.rs rename to pumpkin-protocol/src/java/client/play/hurt_animation.rs diff --git a/pumpkin-protocol/src/client/play/initialize_world_border.rs b/pumpkin-protocol/src/java/client/play/initialize_world_border.rs similarity index 100% rename from pumpkin-protocol/src/client/play/initialize_world_border.rs rename to pumpkin-protocol/src/java/client/play/initialize_world_border.rs diff --git a/pumpkin-protocol/src/client/play/keep_alive.rs b/pumpkin-protocol/src/java/client/play/keep_alive.rs similarity index 100% rename from pumpkin-protocol/src/client/play/keep_alive.rs rename to pumpkin-protocol/src/java/client/play/keep_alive.rs diff --git a/pumpkin-protocol/src/client/play/level_event.rs b/pumpkin-protocol/src/java/client/play/level_event.rs similarity index 100% rename from pumpkin-protocol/src/client/play/level_event.rs rename to pumpkin-protocol/src/java/client/play/level_event.rs diff --git a/pumpkin-protocol/src/client/play/login.rs b/pumpkin-protocol/src/java/client/play/login.rs similarity index 100% rename from pumpkin-protocol/src/client/play/login.rs rename to pumpkin-protocol/src/java/client/play/login.rs diff --git a/pumpkin-protocol/src/client/play/mod.rs b/pumpkin-protocol/src/java/client/play/mod.rs similarity index 100% rename from pumpkin-protocol/src/client/play/mod.rs rename to pumpkin-protocol/src/java/client/play/mod.rs diff --git a/pumpkin-protocol/src/client/play/multi_block_update.rs b/pumpkin-protocol/src/java/client/play/multi_block_update.rs similarity index 100% rename from pumpkin-protocol/src/client/play/multi_block_update.rs rename to pumpkin-protocol/src/java/client/play/multi_block_update.rs diff --git a/pumpkin-protocol/src/client/play/open_screen.rs b/pumpkin-protocol/src/java/client/play/open_screen.rs similarity index 100% rename from pumpkin-protocol/src/client/play/open_screen.rs rename to pumpkin-protocol/src/java/client/play/open_screen.rs diff --git a/pumpkin-protocol/src/client/play/open_sign_editor.rs b/pumpkin-protocol/src/java/client/play/open_sign_editor.rs similarity index 100% rename from pumpkin-protocol/src/client/play/open_sign_editor.rs rename to pumpkin-protocol/src/java/client/play/open_sign_editor.rs diff --git a/pumpkin-protocol/src/client/play/particle.rs b/pumpkin-protocol/src/java/client/play/particle.rs similarity index 100% rename from pumpkin-protocol/src/client/play/particle.rs rename to pumpkin-protocol/src/java/client/play/particle.rs diff --git a/pumpkin-protocol/src/client/play/ping_response.rs b/pumpkin-protocol/src/java/client/play/ping_response.rs similarity index 100% rename from pumpkin-protocol/src/client/play/ping_response.rs rename to pumpkin-protocol/src/java/client/play/ping_response.rs diff --git a/pumpkin-protocol/src/client/play/player_abilities.rs b/pumpkin-protocol/src/java/client/play/player_abilities.rs similarity index 100% rename from pumpkin-protocol/src/client/play/player_abilities.rs rename to pumpkin-protocol/src/java/client/play/player_abilities.rs diff --git a/pumpkin-protocol/src/client/play/player_action.rs b/pumpkin-protocol/src/java/client/play/player_action.rs similarity index 100% rename from pumpkin-protocol/src/client/play/player_action.rs rename to pumpkin-protocol/src/java/client/play/player_action.rs diff --git a/pumpkin-protocol/src/client/play/player_chat_message.rs b/pumpkin-protocol/src/java/client/play/player_chat_message.rs similarity index 98% rename from pumpkin-protocol/src/client/play/player_chat_message.rs rename to pumpkin-protocol/src/java/client/play/player_chat_message.rs index 5f0ddce2e..e6ff7f622 100644 --- a/pumpkin-protocol/src/client/play/player_chat_message.rs +++ b/pumpkin-protocol/src/java/client/play/player_chat_message.rs @@ -5,9 +5,9 @@ use pumpkin_macros::packet; use pumpkin_util::text::TextComponent; use crate::{ - ClientPacket, + ClientPacket, WritingError, codec::{bit_set::BitSet, var_int::VarInt}, - ser::{NetworkWriteExt, WritingError}, + ser::NetworkWriteExt, }; #[packet(PLAY_PLAYER_CHAT)] diff --git a/pumpkin-protocol/src/client/play/player_info_update.rs b/pumpkin-protocol/src/java/client/play/player_info_update.rs similarity index 97% rename from pumpkin-protocol/src/client/play/player_info_update.rs rename to pumpkin-protocol/src/java/client/play/player_info_update.rs index 3730f1b34..1c49375da 100644 --- a/pumpkin-protocol/src/client/play/player_info_update.rs +++ b/pumpkin-protocol/src/java/client/play/player_info_update.rs @@ -4,10 +4,7 @@ use bitflags::bitflags; use pumpkin_data::packet::clientbound::PLAY_PLAYER_INFO_UPDATE; use pumpkin_macros::packet; -use crate::{ - ClientPacket, Property, - ser::{NetworkWriteExt, WritingError}, -}; +use crate::{ClientPacket, Property, WritingError, ser::NetworkWriteExt}; use super::PlayerAction; diff --git a/pumpkin-protocol/src/client/play/player_position.rs b/pumpkin-protocol/src/java/client/play/player_position.rs similarity index 93% rename from pumpkin-protocol/src/client/play/player_position.rs rename to pumpkin-protocol/src/java/client/play/player_position.rs index 47654bade..4679b9927 100644 --- a/pumpkin-protocol/src/client/play/player_position.rs +++ b/pumpkin-protocol/src/java/client/play/player_position.rs @@ -4,10 +4,7 @@ use pumpkin_data::packet::clientbound::PLAY_PLAYER_POSITION; use pumpkin_macros::packet; use pumpkin_util::math::vector3::Vector3; -use crate::{ - ClientPacket, PositionFlag, VarInt, - ser::{NetworkWriteExt, WritingError}, -}; +use crate::{ClientPacket, PositionFlag, VarInt, WritingError, ser::NetworkWriteExt}; #[packet(PLAY_PLAYER_POSITION)] pub struct CPlayerPosition<'a> { diff --git a/pumpkin-protocol/src/client/play/player_remove.rs b/pumpkin-protocol/src/java/client/play/player_remove.rs similarity index 100% rename from pumpkin-protocol/src/client/play/player_remove.rs rename to pumpkin-protocol/src/java/client/play/player_remove.rs diff --git a/pumpkin-protocol/src/client/play/player_spawn_position.rs b/pumpkin-protocol/src/java/client/play/player_spawn_position.rs similarity index 100% rename from pumpkin-protocol/src/client/play/player_spawn_position.rs rename to pumpkin-protocol/src/java/client/play/player_spawn_position.rs diff --git a/pumpkin-protocol/src/client/play/remove_entities.rs b/pumpkin-protocol/src/java/client/play/remove_entities.rs similarity index 100% rename from pumpkin-protocol/src/client/play/remove_entities.rs rename to pumpkin-protocol/src/java/client/play/remove_entities.rs diff --git a/pumpkin-protocol/src/client/play/remove_mob_effect.rs b/pumpkin-protocol/src/java/client/play/remove_mob_effect.rs similarity index 100% rename from pumpkin-protocol/src/client/play/remove_mob_effect.rs rename to pumpkin-protocol/src/java/client/play/remove_mob_effect.rs diff --git a/pumpkin-protocol/src/client/play/reset_score.rs b/pumpkin-protocol/src/java/client/play/reset_score.rs similarity index 100% rename from pumpkin-protocol/src/client/play/reset_score.rs rename to pumpkin-protocol/src/java/client/play/reset_score.rs diff --git a/pumpkin-protocol/src/client/play/respawn.rs b/pumpkin-protocol/src/java/client/play/respawn.rs similarity index 100% rename from pumpkin-protocol/src/client/play/respawn.rs rename to pumpkin-protocol/src/java/client/play/respawn.rs diff --git a/pumpkin-protocol/src/client/play/server_links.rs b/pumpkin-protocol/src/java/client/play/server_links.rs similarity index 100% rename from pumpkin-protocol/src/client/play/server_links.rs rename to pumpkin-protocol/src/java/client/play/server_links.rs diff --git a/pumpkin-protocol/src/client/play/set_border_center.rs b/pumpkin-protocol/src/java/client/play/set_border_center.rs similarity index 100% rename from pumpkin-protocol/src/client/play/set_border_center.rs rename to pumpkin-protocol/src/java/client/play/set_border_center.rs diff --git a/pumpkin-protocol/src/client/play/set_border_lerp_size.rs b/pumpkin-protocol/src/java/client/play/set_border_lerp_size.rs similarity index 100% rename from pumpkin-protocol/src/client/play/set_border_lerp_size.rs rename to pumpkin-protocol/src/java/client/play/set_border_lerp_size.rs diff --git a/pumpkin-protocol/src/client/play/set_border_size.rs b/pumpkin-protocol/src/java/client/play/set_border_size.rs similarity index 100% rename from pumpkin-protocol/src/client/play/set_border_size.rs rename to pumpkin-protocol/src/java/client/play/set_border_size.rs diff --git a/pumpkin-protocol/src/client/play/set_border_warning_delay.rs b/pumpkin-protocol/src/java/client/play/set_border_warning_delay.rs similarity index 100% rename from pumpkin-protocol/src/client/play/set_border_warning_delay.rs rename to pumpkin-protocol/src/java/client/play/set_border_warning_delay.rs diff --git a/pumpkin-protocol/src/client/play/set_border_warning_distance.rs b/pumpkin-protocol/src/java/client/play/set_border_warning_distance.rs similarity index 100% rename from pumpkin-protocol/src/client/play/set_border_warning_distance.rs rename to pumpkin-protocol/src/java/client/play/set_border_warning_distance.rs diff --git a/pumpkin-protocol/src/client/play/set_container_content.rs b/pumpkin-protocol/src/java/client/play/set_container_content.rs similarity index 100% rename from pumpkin-protocol/src/client/play/set_container_content.rs rename to pumpkin-protocol/src/java/client/play/set_container_content.rs diff --git a/pumpkin-protocol/src/client/play/set_container_property.rs b/pumpkin-protocol/src/java/client/play/set_container_property.rs similarity index 100% rename from pumpkin-protocol/src/client/play/set_container_property.rs rename to pumpkin-protocol/src/java/client/play/set_container_property.rs diff --git a/pumpkin-protocol/src/client/play/set_container_slot.rs b/pumpkin-protocol/src/java/client/play/set_container_slot.rs similarity index 100% rename from pumpkin-protocol/src/client/play/set_container_slot.rs rename to pumpkin-protocol/src/java/client/play/set_container_slot.rs diff --git a/pumpkin-protocol/src/client/play/set_cursor_slot.rs b/pumpkin-protocol/src/java/client/play/set_cursor_slot.rs similarity index 100% rename from pumpkin-protocol/src/client/play/set_cursor_slot.rs rename to pumpkin-protocol/src/java/client/play/set_cursor_slot.rs diff --git a/pumpkin-protocol/src/client/play/set_equipment.rs b/pumpkin-protocol/src/java/client/play/set_equipment.rs similarity index 93% rename from pumpkin-protocol/src/client/play/set_equipment.rs rename to pumpkin-protocol/src/java/client/play/set_equipment.rs index 861e51565..de3637b1c 100644 --- a/pumpkin-protocol/src/client/play/set_equipment.rs +++ b/pumpkin-protocol/src/java/client/play/set_equipment.rs @@ -1,6 +1,9 @@ use std::io::Write; -use crate::ser::{NetworkWriteExt, WritingError, serializer::Serializer}; +use crate::{ + WritingError, + ser::{NetworkWriteExt, serializer::Serializer}, +}; use pumpkin_data::packet::clientbound::PLAY_SET_EQUIPMENT; use pumpkin_macros::packet; use serde::Serialize; diff --git a/pumpkin-protocol/src/client/play/set_experience.rs b/pumpkin-protocol/src/java/client/play/set_experience.rs similarity index 100% rename from pumpkin-protocol/src/client/play/set_experience.rs rename to pumpkin-protocol/src/java/client/play/set_experience.rs diff --git a/pumpkin-protocol/src/client/play/set_health.rs b/pumpkin-protocol/src/java/client/play/set_health.rs similarity index 100% rename from pumpkin-protocol/src/client/play/set_health.rs rename to pumpkin-protocol/src/java/client/play/set_health.rs diff --git a/pumpkin-protocol/src/client/play/set_held_item.rs b/pumpkin-protocol/src/java/client/play/set_held_item.rs similarity index 100% rename from pumpkin-protocol/src/client/play/set_held_item.rs rename to pumpkin-protocol/src/java/client/play/set_held_item.rs diff --git a/pumpkin-protocol/src/client/play/set_player_inventory.rs b/pumpkin-protocol/src/java/client/play/set_player_inventory.rs similarity index 100% rename from pumpkin-protocol/src/client/play/set_player_inventory.rs rename to pumpkin-protocol/src/java/client/play/set_player_inventory.rs diff --git a/pumpkin-protocol/src/client/play/set_time.rs b/pumpkin-protocol/src/java/client/play/set_time.rs similarity index 100% rename from pumpkin-protocol/src/client/play/set_time.rs rename to pumpkin-protocol/src/java/client/play/set_time.rs diff --git a/pumpkin-protocol/src/client/play/set_title.rs b/pumpkin-protocol/src/java/client/play/set_title.rs similarity index 100% rename from pumpkin-protocol/src/client/play/set_title.rs rename to pumpkin-protocol/src/java/client/play/set_title.rs diff --git a/pumpkin-protocol/src/client/play/sound_effect.rs b/pumpkin-protocol/src/java/client/play/sound_effect.rs similarity index 100% rename from pumpkin-protocol/src/client/play/sound_effect.rs rename to pumpkin-protocol/src/java/client/play/sound_effect.rs diff --git a/pumpkin-protocol/src/client/play/spawn_entity.rs b/pumpkin-protocol/src/java/client/play/spawn_entity.rs similarity index 100% rename from pumpkin-protocol/src/client/play/spawn_entity.rs rename to pumpkin-protocol/src/java/client/play/spawn_entity.rs diff --git a/pumpkin-protocol/src/client/play/stop_sound.rs b/pumpkin-protocol/src/java/client/play/stop_sound.rs similarity index 95% rename from pumpkin-protocol/src/client/play/stop_sound.rs rename to pumpkin-protocol/src/java/client/play/stop_sound.rs index 0824d4b39..bb0b5adad 100644 --- a/pumpkin-protocol/src/client/play/stop_sound.rs +++ b/pumpkin-protocol/src/java/client/play/stop_sound.rs @@ -1,8 +1,8 @@ use std::io::Write; -use crate::ClientPacket; use crate::codec::var_int::VarInt; -use crate::ser::{NetworkWriteExt, WritingError}; +use crate::ser::NetworkWriteExt; +use crate::{ClientPacket, WritingError}; use pumpkin_data::{packet::clientbound::PLAY_STOP_SOUND, sound::SoundCategory}; use pumpkin_macros::packet; use pumpkin_util::resource_location::ResourceLocation; diff --git a/pumpkin-protocol/src/client/play/store_cookie.rs b/pumpkin-protocol/src/java/client/play/store_cookie.rs similarity index 100% rename from pumpkin-protocol/src/client/play/store_cookie.rs rename to pumpkin-protocol/src/java/client/play/store_cookie.rs diff --git a/pumpkin-protocol/src/client/play/subtitle.rs b/pumpkin-protocol/src/java/client/play/subtitle.rs similarity index 100% rename from pumpkin-protocol/src/client/play/subtitle.rs rename to pumpkin-protocol/src/java/client/play/subtitle.rs diff --git a/pumpkin-protocol/src/client/play/system_chat_message.rs b/pumpkin-protocol/src/java/client/play/system_chat_message.rs similarity index 100% rename from pumpkin-protocol/src/client/play/system_chat_message.rs rename to pumpkin-protocol/src/java/client/play/system_chat_message.rs diff --git a/pumpkin-protocol/src/client/play/take_item.rs b/pumpkin-protocol/src/java/client/play/take_item.rs similarity index 100% rename from pumpkin-protocol/src/client/play/take_item.rs rename to pumpkin-protocol/src/java/client/play/take_item.rs diff --git a/pumpkin-protocol/src/client/play/teleport_entity.rs b/pumpkin-protocol/src/java/client/play/teleport_entity.rs similarity index 94% rename from pumpkin-protocol/src/client/play/teleport_entity.rs rename to pumpkin-protocol/src/java/client/play/teleport_entity.rs index 388bbb505..dc8b6ade2 100644 --- a/pumpkin-protocol/src/client/play/teleport_entity.rs +++ b/pumpkin-protocol/src/java/client/play/teleport_entity.rs @@ -4,10 +4,7 @@ use pumpkin_data::packet::clientbound::PLAY_TELEPORT_ENTITY; use pumpkin_macros::packet; use pumpkin_util::math::vector3::Vector3; -use crate::{ - ClientPacket, PositionFlag, VarInt, - ser::{NetworkWriteExt, WritingError}, -}; +use crate::{ClientPacket, PositionFlag, VarInt, WritingError, ser::NetworkWriteExt}; /// Only used when teleporting a player's vehicle, this packet is sent to the player. #[packet(PLAY_TELEPORT_ENTITY)] diff --git a/pumpkin-protocol/src/client/play/ticking_state.rs b/pumpkin-protocol/src/java/client/play/ticking_state.rs similarity index 100% rename from pumpkin-protocol/src/client/play/ticking_state.rs rename to pumpkin-protocol/src/java/client/play/ticking_state.rs diff --git a/pumpkin-protocol/src/client/play/ticking_step.rs b/pumpkin-protocol/src/java/client/play/ticking_step.rs similarity index 100% rename from pumpkin-protocol/src/client/play/ticking_step.rs rename to pumpkin-protocol/src/java/client/play/ticking_step.rs diff --git a/pumpkin-protocol/src/client/play/transfer.rs b/pumpkin-protocol/src/java/client/play/transfer.rs similarity index 100% rename from pumpkin-protocol/src/client/play/transfer.rs rename to pumpkin-protocol/src/java/client/play/transfer.rs diff --git a/pumpkin-protocol/src/client/play/unload_chunk.rs b/pumpkin-protocol/src/java/client/play/unload_chunk.rs similarity index 100% rename from pumpkin-protocol/src/client/play/unload_chunk.rs rename to pumpkin-protocol/src/java/client/play/unload_chunk.rs diff --git a/pumpkin-protocol/src/client/play/update_entity_pos.rs b/pumpkin-protocol/src/java/client/play/update_entity_pos.rs similarity index 100% rename from pumpkin-protocol/src/client/play/update_entity_pos.rs rename to pumpkin-protocol/src/java/client/play/update_entity_pos.rs diff --git a/pumpkin-protocol/src/client/play/update_entity_pos_rot.rs b/pumpkin-protocol/src/java/client/play/update_entity_pos_rot.rs similarity index 100% rename from pumpkin-protocol/src/client/play/update_entity_pos_rot.rs rename to pumpkin-protocol/src/java/client/play/update_entity_pos_rot.rs diff --git a/pumpkin-protocol/src/client/play/update_entity_rot.rs b/pumpkin-protocol/src/java/client/play/update_entity_rot.rs similarity index 100% rename from pumpkin-protocol/src/client/play/update_entity_rot.rs rename to pumpkin-protocol/src/java/client/play/update_entity_rot.rs diff --git a/pumpkin-protocol/src/client/play/update_mob_effect.rs b/pumpkin-protocol/src/java/client/play/update_mob_effect.rs similarity index 100% rename from pumpkin-protocol/src/client/play/update_mob_effect.rs rename to pumpkin-protocol/src/java/client/play/update_mob_effect.rs diff --git a/pumpkin-protocol/src/client/play/update_objectives.rs b/pumpkin-protocol/src/java/client/play/update_objectives.rs similarity index 95% rename from pumpkin-protocol/src/client/play/update_objectives.rs rename to pumpkin-protocol/src/java/client/play/update_objectives.rs index 0746c70f6..64ee46fbf 100644 --- a/pumpkin-protocol/src/client/play/update_objectives.rs +++ b/pumpkin-protocol/src/java/client/play/update_objectives.rs @@ -4,10 +4,7 @@ use pumpkin_data::packet::clientbound::PLAY_SET_OBJECTIVE; use pumpkin_macros::packet; use pumpkin_util::text::TextComponent; -use crate::{ - ClientPacket, NumberFormat, VarInt, - ser::{NetworkWriteExt, WritingError}, -}; +use crate::{ClientPacket, NumberFormat, VarInt, WritingError, ser::NetworkWriteExt}; #[packet(PLAY_SET_OBJECTIVE)] pub struct CUpdateObjectives { diff --git a/pumpkin-protocol/src/client/play/update_score.rs b/pumpkin-protocol/src/java/client/play/update_score.rs similarity index 100% rename from pumpkin-protocol/src/client/play/update_score.rs rename to pumpkin-protocol/src/java/client/play/update_score.rs diff --git a/pumpkin-protocol/src/client/play/worldevent.rs b/pumpkin-protocol/src/java/client/play/worldevent.rs similarity index 100% rename from pumpkin-protocol/src/client/play/worldevent.rs rename to pumpkin-protocol/src/java/client/play/worldevent.rs diff --git a/pumpkin-protocol/src/client/status/mod.rs b/pumpkin-protocol/src/java/client/status/mod.rs similarity index 100% rename from pumpkin-protocol/src/client/status/mod.rs rename to pumpkin-protocol/src/java/client/status/mod.rs diff --git a/pumpkin-protocol/src/client/status/ping_response.rs b/pumpkin-protocol/src/java/client/status/ping_response.rs similarity index 100% rename from pumpkin-protocol/src/client/status/ping_response.rs rename to pumpkin-protocol/src/java/client/status/ping_response.rs diff --git a/pumpkin-protocol/src/client/status/status_response.rs b/pumpkin-protocol/src/java/client/status/status_response.rs similarity index 100% rename from pumpkin-protocol/src/client/status/status_response.rs rename to pumpkin-protocol/src/java/client/status/status_response.rs diff --git a/pumpkin-protocol/src/java/mod.rs b/pumpkin-protocol/src/java/mod.rs new file mode 100644 index 000000000..ca97d4515 --- /dev/null +++ b/pumpkin-protocol/src/java/mod.rs @@ -0,0 +1,4 @@ +pub mod client; +pub mod packet_decoder; +pub mod packet_encoder; +pub mod server; diff --git a/pumpkin-protocol/src/packet_decoder.rs b/pumpkin-protocol/src/java/packet_decoder.rs similarity index 91% rename from pumpkin-protocol/src/packet_decoder.rs rename to pumpkin-protocol/src/java/packet_decoder.rs index 0e15ade63..3aa4a8453 100644 --- a/pumpkin-protocol/src/packet_decoder.rs +++ b/pumpkin-protocol/src/java/packet_decoder.rs @@ -1,11 +1,10 @@ use aes::cipher::KeyIvInit; use async_compression::tokio::bufread::ZlibDecoder; -use thiserror::Error; use tokio::io::{AsyncRead, AsyncReadExt, BufReader}; use crate::{ - Aes128Cfb8Dec, CompressionThreshold, MAX_PACKET_DATA_SIZE, MAX_PACKET_SIZE, RawPacket, - StreamDecryptor, VarInt, ser::ReadingError, + Aes128Cfb8Dec, CompressionThreshold, MAX_PACKET_DATA_SIZE, MAX_PACKET_SIZE, PacketDecodeError, + RawPacket, ReadingError, StreamDecryptor, VarInt, }; // decrypt -> decompress -> raw @@ -71,12 +70,12 @@ impl AsyncRead for DecryptionReader { /// Decoder: Client -> Server /// Supports ZLib decoding/decompression /// Supports Aes128 Encryption -pub struct NetworkDecoder { +pub struct TCPNetworkDecoder { reader: DecryptionReader, compression: Option, } -impl NetworkDecoder { +impl TCPNetworkDecoder { pub fn new(reader: R) -> Self { Self { reader: DecryptionReader::None(reader), @@ -157,30 +156,6 @@ impl NetworkDecoder { } } -#[derive(Error, Debug)] -pub enum PacketDecodeError { - #[error("failed to decode packet ID")] - DecodeID, - #[error("packet exceeds maximum length")] - TooLong, - #[error("packet length is out of bounds")] - OutOfBounds, - #[error("malformed packet length VarInt: {0}")] - MalformedLength(String), - #[error("failed to decompress packet: {0}")] - FailedDecompression(String), // Updated to include error details - #[error("packet is uncompressed but greater than the threshold")] - NotCompressed, - #[error("the connection has closed")] - ConnectionClosed, -} - -impl From for PacketDecodeError { - fn from(value: ReadingError) -> Self { - Self::FailedDecompression(value.to_string()) - } -} - #[cfg(test)] mod tests { @@ -275,7 +250,7 @@ mod tests { let packet = build_packet(packet_id, payload, false, None, None); // Initialize the decoder without compression and encryption - let mut decoder = NetworkDecoder::new(packet.as_slice()); + let mut decoder = TCPNetworkDecoder::new(packet.as_slice()); // Attempt to decode let raw_packet = decoder.get_raw_packet().await.expect("Decoding failed"); @@ -295,7 +270,7 @@ mod tests { let packet = build_packet(packet_id, payload, true, None, None); // Initialize the decoder with compression enabled - let mut decoder = NetworkDecoder::new(packet.as_slice()); + let mut decoder = TCPNetworkDecoder::new(packet.as_slice()); // Larger than payload decoder.set_compression(1000); @@ -320,7 +295,7 @@ mod tests { let packet = build_packet(packet_id, payload, false, Some(&key), Some(&key)); // Initialize the decoder with encryption enabled - let mut decoder = NetworkDecoder::new(packet.as_slice()); + let mut decoder = TCPNetworkDecoder::new(packet.as_slice()); decoder.set_encryption(&key); // Attempt to decode @@ -345,7 +320,7 @@ mod tests { let packet = build_packet(packet_id, payload, true, Some(&key), Some(&iv)); // Initialize the decoder with both compression and encryption enabled - let mut decoder = NetworkDecoder::new(packet.as_slice()); + let mut decoder = TCPNetworkDecoder::new(packet.as_slice()); decoder.set_compression(1000); decoder.set_encryption(&key); @@ -381,7 +356,7 @@ mod tests { let packet_bytes = packet_buffer; // Initialize the decoder with compression enabled - let mut decoder = NetworkDecoder::new(&packet_bytes[..]); + let mut decoder = TCPNetworkDecoder::new(&packet_bytes[..]); decoder.set_compression(1000); // Attempt to decode and expect a decompression error @@ -403,7 +378,7 @@ mod tests { let packet = build_packet(packet_id, payload, false, None, None); // Initialize the decoder without compression and encryption - let mut decoder = NetworkDecoder::new(packet.as_slice()); + let mut decoder = TCPNetworkDecoder::new(packet.as_slice()); // Attempt to decode and expect a read error let raw_packet = decoder.get_raw_packet().await.unwrap(); @@ -424,7 +399,7 @@ mod tests { println!("Built packet (with compression, maximum length): {packet:?}"); // Initialize the decoder with compression enabled - let mut decoder = NetworkDecoder::new(packet.as_slice()); + let mut decoder = TCPNetworkDecoder::new(packet.as_slice()); decoder.set_compression(MAX_PACKET_SIZE as usize + 1); // Attempt to decode diff --git a/pumpkin-protocol/src/packet_encoder.rs b/pumpkin-protocol/src/java/packet_encoder.rs similarity index 97% rename from pumpkin-protocol/src/packet_encoder.rs rename to pumpkin-protocol/src/java/packet_encoder.rs index 6308b6143..c4ec553a9 100644 --- a/pumpkin-protocol/src/packet_encoder.rs +++ b/pumpkin-protocol/src/java/packet_encoder.rs @@ -6,7 +6,7 @@ use tokio::io::{AsyncWrite, AsyncWriteExt}; use crate::{ Aes128Cfb8Enc, CompressionLevel, CompressionThreshold, MAX_PACKET_DATA_SIZE, MAX_PACKET_SIZE, - StreamEncryptor, VarInt, + PacketEncodeError, StreamEncryptor, VarInt, }; // raw -> compress -> encrypt @@ -79,13 +79,13 @@ impl AsyncWrite for EncryptionWriter { /// Encoder: Server -> Client /// Supports ZLib endecoding/compression /// Supports Aes128 Encryption -pub struct NetworkEncoder { +pub struct TCPNetworkEncoder { writer: EncryptionWriter, // compression and compression threshold compression: Option<(CompressionThreshold, CompressionLevel)>, } -impl NetworkEncoder { +impl TCPNetworkEncoder { pub fn new(writer: W) -> Self { Self { writer: EncryptionWriter::None(writer), @@ -268,26 +268,15 @@ impl NetworkEncoder { #[error("Invalid compression Level")] pub struct CompressionLevelError; -/// Errors that can occur during packet encoding. -#[derive(Error, Debug)] -pub enum PacketEncodeError { - #[error("Packet exceeds maximum length: {0}")] - TooLong(usize), - #[error("Compression failed {0}")] - CompressionFailed(String), - #[error("Writing packet failed: {0}")] - Message(String), -} - #[cfg(test)] mod tests { use std::io::Read; use super::*; - use crate::ClientPacket; - use crate::client::status::CStatusResponse; - use crate::ser::packet::Packet; - use crate::ser::{NetworkReadExt, ReadingError}; + use crate::java::client::status::CStatusResponse; + use crate::packet::Packet; + use crate::ser::{NetworkReadExt, NetworkWriteExt}; + use crate::{ClientPacket, ReadingError}; use aes::Aes128; use cfb8::Decryptor as Cfb8Decryptor; use cfb8::cipher::AsyncStreamCipher; @@ -337,7 +326,7 @@ mod tests { key: Option<&[u8; 16]>, ) -> Box<[u8]> { let mut buf = Vec::new(); - let mut encoder = NetworkEncoder::new(&mut buf); + let mut encoder = TCPNetworkEncoder::new(&mut buf); if let Some(compression_info) = compression_info { encoder.set_compression(compression_info); } @@ -347,7 +336,10 @@ mod tests { } let mut packet_buf = Vec::new(); - packet.write(&mut packet_buf).unwrap(); + let writer = &mut packet_buf; + writer.write_var_int(&VarInt(T::PACKET_ID)).unwrap(); + packet.write_packet_data(writer).unwrap(); + encoder.write_packet(packet_buf.into()).await.unwrap(); buf.into_boxed_slice() diff --git a/pumpkin-protocol/src/server/config/acknowledge_finish_config.rs b/pumpkin-protocol/src/java/server/config/acknowledge_finish_config.rs similarity index 100% rename from pumpkin-protocol/src/server/config/acknowledge_finish_config.rs rename to pumpkin-protocol/src/java/server/config/acknowledge_finish_config.rs diff --git a/pumpkin-protocol/src/server/config/client_information.rs b/pumpkin-protocol/src/java/server/config/client_information.rs similarity index 100% rename from pumpkin-protocol/src/server/config/client_information.rs rename to pumpkin-protocol/src/java/server/config/client_information.rs diff --git a/pumpkin-protocol/src/server/config/cookie_response.rs b/pumpkin-protocol/src/java/server/config/cookie_response.rs similarity index 94% rename from pumpkin-protocol/src/server/config/cookie_response.rs rename to pumpkin-protocol/src/java/server/config/cookie_response.rs index 6c251f765..95b7f0241 100644 --- a/pumpkin-protocol/src/server/config/cookie_response.rs +++ b/pumpkin-protocol/src/java/server/config/cookie_response.rs @@ -4,10 +4,7 @@ use pumpkin_data::packet::serverbound::CONFIG_COOKIE_RESPONSE; use pumpkin_macros::packet; use pumpkin_util::resource_location::ResourceLocation; -use crate::{ - ServerPacket, - ser::{NetworkReadExt, ReadingError}, -}; +use crate::{ReadingError, ServerPacket, ser::NetworkReadExt}; #[packet(CONFIG_COOKIE_RESPONSE)] /// Response to a `CCookieRequest` (configuration) from the server. @@ -23,7 +20,6 @@ const MAX_COOKIE_LENGTH: usize = 5120; impl ServerPacket for SConfigCookieResponse { fn read(read: impl Read) -> Result { let mut read = read; - let key = read.get_resource_location()?; let has_payload = read.get_bool()?; diff --git a/pumpkin-protocol/src/server/config/known_packs.rs b/pumpkin-protocol/src/java/server/config/known_packs.rs similarity index 100% rename from pumpkin-protocol/src/server/config/known_packs.rs rename to pumpkin-protocol/src/java/server/config/known_packs.rs diff --git a/pumpkin-protocol/src/server/config/mod.rs b/pumpkin-protocol/src/java/server/config/mod.rs similarity index 100% rename from pumpkin-protocol/src/server/config/mod.rs rename to pumpkin-protocol/src/java/server/config/mod.rs diff --git a/pumpkin-protocol/src/server/config/plugin_message.rs b/pumpkin-protocol/src/java/server/config/plugin_message.rs similarity index 89% rename from pumpkin-protocol/src/server/config/plugin_message.rs rename to pumpkin-protocol/src/java/server/config/plugin_message.rs index f952b2218..0ba44a738 100644 --- a/pumpkin-protocol/src/server/config/plugin_message.rs +++ b/pumpkin-protocol/src/java/server/config/plugin_message.rs @@ -4,10 +4,7 @@ use pumpkin_data::packet::serverbound::CONFIG_CUSTOM_PAYLOAD; use pumpkin_macros::packet; use pumpkin_util::resource_location::ResourceLocation; -use crate::{ - ServerPacket, - ser::{NetworkReadExt, ReadingError}, -}; +use crate::{ReadingError, ServerPacket, ser::NetworkReadExt}; const MAX_PAYLOAD_SIZE: usize = 1048576; #[packet(CONFIG_CUSTOM_PAYLOAD)] @@ -19,7 +16,6 @@ pub struct SPluginMessage { impl ServerPacket for SPluginMessage { fn read(read: impl Read) -> Result { let mut read = read; - Ok(Self { channel: read.get_resource_location()?, data: read.read_remaining_to_boxed_slice(MAX_PAYLOAD_SIZE)?, diff --git a/pumpkin-protocol/src/server/config/resource_pack_response.rs b/pumpkin-protocol/src/java/server/config/resource_pack_response.rs similarity index 100% rename from pumpkin-protocol/src/server/config/resource_pack_response.rs rename to pumpkin-protocol/src/java/server/config/resource_pack_response.rs diff --git a/pumpkin-protocol/src/server/handshake/mod.rs b/pumpkin-protocol/src/java/server/handshake/mod.rs similarity index 88% rename from pumpkin-protocol/src/server/handshake/mod.rs rename to pumpkin-protocol/src/java/server/handshake/mod.rs index 0e73fca81..18618822c 100644 --- a/pumpkin-protocol/src/server/handshake/mod.rs +++ b/pumpkin-protocol/src/java/server/handshake/mod.rs @@ -1,7 +1,6 @@ use std::io::Read; -use crate::ser::NetworkReadExt; -use crate::{ConnectionState, ServerPacket, VarInt, ser::ReadingError}; +use crate::{ConnectionState, ReadingError, ServerPacket, VarInt, ser::NetworkReadExt}; use pumpkin_data::packet::serverbound::HANDSHAKE_INTENTION; use pumpkin_macros::packet; @@ -16,7 +15,6 @@ pub struct SHandShake { impl ServerPacket for SHandShake { fn read(read: impl Read) -> Result { let mut read = read; - Ok(Self { protocol_version: read.get_var_int()?, server_address: read.get_string_bounded(255)?, diff --git a/pumpkin-protocol/src/server/login/cookie_response.rs b/pumpkin-protocol/src/java/server/login/cookie_response.rs similarity index 100% rename from pumpkin-protocol/src/server/login/cookie_response.rs rename to pumpkin-protocol/src/java/server/login/cookie_response.rs index 34c737243..57bdb105e 100644 --- a/pumpkin-protocol/src/server/login/cookie_response.rs +++ b/pumpkin-protocol/src/java/server/login/cookie_response.rs @@ -1,12 +1,12 @@ +use pumpkin_data::packet::serverbound::LOGIN_COOKIE_RESPONSE; +use pumpkin_macros::packet; +use pumpkin_util::resource_location::ResourceLocation; use std::io::Read; use crate::{ ServerPacket, ser::{NetworkReadExt, ReadingError}, }; -use pumpkin_data::packet::serverbound::LOGIN_COOKIE_RESPONSE; -use pumpkin_macros::packet; -use pumpkin_util::resource_location::ResourceLocation; #[packet(LOGIN_COOKIE_RESPONSE)] /// Response to a `CCookieRequest` (login) from the server. diff --git a/pumpkin-protocol/src/server/login/encryption_response.rs b/pumpkin-protocol/src/java/server/login/encryption_response.rs similarity index 90% rename from pumpkin-protocol/src/server/login/encryption_response.rs rename to pumpkin-protocol/src/java/server/login/encryption_response.rs index 502db522e..8a9176962 100644 --- a/pumpkin-protocol/src/server/login/encryption_response.rs +++ b/pumpkin-protocol/src/java/server/login/encryption_response.rs @@ -3,10 +3,7 @@ use std::io::Read; use pumpkin_data::packet::serverbound::LOGIN_KEY; use pumpkin_macros::packet; -use crate::{ - ServerPacket, - ser::{NetworkReadExt, ReadingError}, -}; +use crate::{ReadingError, ServerPacket, ser::NetworkReadExt}; #[packet(LOGIN_KEY)] pub struct SEncryptionResponse { diff --git a/pumpkin-protocol/src/server/login/login_response.rs b/pumpkin-protocol/src/java/server/login/login_response.rs similarity index 100% rename from pumpkin-protocol/src/server/login/login_response.rs rename to pumpkin-protocol/src/java/server/login/login_response.rs diff --git a/pumpkin-protocol/src/server/login/login_start.rs b/pumpkin-protocol/src/java/server/login/login_start.rs similarity index 85% rename from pumpkin-protocol/src/server/login/login_start.rs rename to pumpkin-protocol/src/java/server/login/login_start.rs index b4d54da74..18e503478 100644 --- a/pumpkin-protocol/src/server/login/login_start.rs +++ b/pumpkin-protocol/src/java/server/login/login_start.rs @@ -1,10 +1,12 @@ use std::io::Read; -use crate::ser::NetworkReadExt; use pumpkin_data::packet::serverbound::LOGIN_HELLO; use pumpkin_macros::packet; -use crate::{ServerPacket, ser::ReadingError}; +use crate::{ + ServerPacket, + ser::{NetworkReadExt, ReadingError}, +}; #[packet(LOGIN_HELLO)] pub struct SLoginStart { @@ -15,7 +17,6 @@ pub struct SLoginStart { impl ServerPacket for SLoginStart { fn read(read: impl Read) -> Result { let mut read = read; - Ok(Self { name: read.get_string_bounded(16)?, uuid: read.get_uuid()?, diff --git a/pumpkin-protocol/src/server/login/mod.rs b/pumpkin-protocol/src/java/server/login/mod.rs similarity index 100% rename from pumpkin-protocol/src/server/login/mod.rs rename to pumpkin-protocol/src/java/server/login/mod.rs diff --git a/pumpkin-protocol/src/server/login/plugin_response.rs b/pumpkin-protocol/src/java/server/login/plugin_response.rs similarity index 87% rename from pumpkin-protocol/src/server/login/plugin_response.rs rename to pumpkin-protocol/src/java/server/login/plugin_response.rs index 054664eaf..73ad55fe5 100644 --- a/pumpkin-protocol/src/server/login/plugin_response.rs +++ b/pumpkin-protocol/src/java/server/login/plugin_response.rs @@ -1,9 +1,6 @@ use std::io::Read; -use crate::{ - ServerPacket, VarInt, - ser::{NetworkReadExt, ReadingError}, -}; +use crate::{ReadingError, ServerPacket, VarInt, ser::NetworkReadExt}; use pumpkin_data::packet::serverbound::LOGIN_CUSTOM_QUERY_ANSWER; use pumpkin_macros::packet; @@ -18,7 +15,6 @@ pub struct SLoginPluginResponse { impl ServerPacket for SLoginPluginResponse { fn read(read: impl Read) -> Result { let mut read = read; - Ok(Self { message_id: read.get_var_int()?, data: read.get_option(|v| v.read_remaining_to_boxed_slice(MAX_PAYLOAD_SIZE))?, diff --git a/pumpkin-protocol/src/server/mod.rs b/pumpkin-protocol/src/java/server/mod.rs similarity index 100% rename from pumpkin-protocol/src/server/mod.rs rename to pumpkin-protocol/src/java/server/mod.rs diff --git a/pumpkin-protocol/src/server/play/change_game_mode.rs b/pumpkin-protocol/src/java/server/play/change_game_mode.rs similarity index 100% rename from pumpkin-protocol/src/server/play/change_game_mode.rs rename to pumpkin-protocol/src/java/server/play/change_game_mode.rs diff --git a/pumpkin-protocol/src/server/play/chat_command.rs b/pumpkin-protocol/src/java/server/play/chat_command.rs similarity index 100% rename from pumpkin-protocol/src/server/play/chat_command.rs rename to pumpkin-protocol/src/java/server/play/chat_command.rs diff --git a/pumpkin-protocol/src/server/play/chat_message.rs b/pumpkin-protocol/src/java/server/play/chat_message.rs similarity index 95% rename from pumpkin-protocol/src/server/play/chat_message.rs rename to pumpkin-protocol/src/java/server/play/chat_message.rs index e23235bf0..7fe8e80c8 100644 --- a/pumpkin-protocol/src/server/play/chat_message.rs +++ b/pumpkin-protocol/src/java/server/play/chat_message.rs @@ -5,7 +5,8 @@ use pumpkin_macros::packet; use serde::Serialize; use crate::{ - ServerPacket, VarInt, + ServerPacket, + codec::var_int::VarInt, ser::{NetworkReadExt, ReadingError}, }; @@ -24,7 +25,6 @@ pub struct SChatMessage { impl ServerPacket for SChatMessage { fn read(read: impl Read) -> Result { let mut read = read; - Ok(Self { message: read.get_string_bounded(256)?, timestamp: read.get_i64_be()?, diff --git a/pumpkin-protocol/src/server/play/chunk_batch.rs b/pumpkin-protocol/src/java/server/play/chunk_batch.rs similarity index 100% rename from pumpkin-protocol/src/server/play/chunk_batch.rs rename to pumpkin-protocol/src/java/server/play/chunk_batch.rs diff --git a/pumpkin-protocol/src/server/play/click_container.rs b/pumpkin-protocol/src/java/server/play/click_container.rs similarity index 100% rename from pumpkin-protocol/src/server/play/click_container.rs rename to pumpkin-protocol/src/java/server/play/click_container.rs diff --git a/pumpkin-protocol/src/server/play/client_command.rs b/pumpkin-protocol/src/java/server/play/client_command.rs similarity index 100% rename from pumpkin-protocol/src/server/play/client_command.rs rename to pumpkin-protocol/src/java/server/play/client_command.rs diff --git a/pumpkin-protocol/src/server/play/client_information.rs b/pumpkin-protocol/src/java/server/play/client_information.rs similarity index 100% rename from pumpkin-protocol/src/server/play/client_information.rs rename to pumpkin-protocol/src/java/server/play/client_information.rs diff --git a/pumpkin-protocol/src/server/play/client_tick_end.rs b/pumpkin-protocol/src/java/server/play/client_tick_end.rs similarity index 100% rename from pumpkin-protocol/src/server/play/client_tick_end.rs rename to pumpkin-protocol/src/java/server/play/client_tick_end.rs diff --git a/pumpkin-protocol/src/server/play/close_container.rs b/pumpkin-protocol/src/java/server/play/close_container.rs similarity index 100% rename from pumpkin-protocol/src/server/play/close_container.rs rename to pumpkin-protocol/src/java/server/play/close_container.rs diff --git a/pumpkin-protocol/src/server/play/command_suggestion.rs b/pumpkin-protocol/src/java/server/play/command_suggestion.rs similarity index 100% rename from pumpkin-protocol/src/server/play/command_suggestion.rs rename to pumpkin-protocol/src/java/server/play/command_suggestion.rs diff --git a/pumpkin-protocol/src/server/play/confirm_teleport.rs b/pumpkin-protocol/src/java/server/play/confirm_teleport.rs similarity index 100% rename from pumpkin-protocol/src/server/play/confirm_teleport.rs rename to pumpkin-protocol/src/java/server/play/confirm_teleport.rs diff --git a/pumpkin-protocol/src/server/play/cookie_response.rs b/pumpkin-protocol/src/java/server/play/cookie_response.rs similarity index 99% rename from pumpkin-protocol/src/server/play/cookie_response.rs rename to pumpkin-protocol/src/java/server/play/cookie_response.rs index 5a001b4c1..b230ebf37 100644 --- a/pumpkin-protocol/src/server/play/cookie_response.rs +++ b/pumpkin-protocol/src/java/server/play/cookie_response.rs @@ -1,12 +1,13 @@ use std::io::Read; +use pumpkin_data::packet::serverbound::PLAY_COOKIE_RESPONSE; +use pumpkin_macros::packet; +use pumpkin_util::resource_location::ResourceLocation; + use crate::{ ServerPacket, ser::{NetworkReadExt, ReadingError}, }; -use pumpkin_data::packet::serverbound::PLAY_COOKIE_RESPONSE; -use pumpkin_macros::packet; -use pumpkin_util::resource_location::ResourceLocation; #[packet(PLAY_COOKIE_RESPONSE)] /// Response to a `CCookieRequest` (play) from the server. diff --git a/pumpkin-protocol/src/server/play/interact.rs b/pumpkin-protocol/src/java/server/play/interact.rs similarity index 97% rename from pumpkin-protocol/src/server/play/interact.rs rename to pumpkin-protocol/src/java/server/play/interact.rs index 26a572e9a..aa6c38e47 100644 --- a/pumpkin-protocol/src/server/play/interact.rs +++ b/pumpkin-protocol/src/java/server/play/interact.rs @@ -5,7 +5,8 @@ use pumpkin_macros::packet; use pumpkin_util::math::vector3::Vector3; use crate::{ - ServerPacket, VarInt, + ServerPacket, + codec::var_int::VarInt, ser::{NetworkReadExt, ReadingError}, }; diff --git a/pumpkin-protocol/src/server/play/keep_alive.rs b/pumpkin-protocol/src/java/server/play/keep_alive.rs similarity index 100% rename from pumpkin-protocol/src/server/play/keep_alive.rs rename to pumpkin-protocol/src/java/server/play/keep_alive.rs diff --git a/pumpkin-protocol/src/server/play/mod.rs b/pumpkin-protocol/src/java/server/play/mod.rs similarity index 100% rename from pumpkin-protocol/src/server/play/mod.rs rename to pumpkin-protocol/src/java/server/play/mod.rs diff --git a/pumpkin-protocol/src/server/play/pick_item.rs b/pumpkin-protocol/src/java/server/play/pick_item.rs similarity index 100% rename from pumpkin-protocol/src/server/play/pick_item.rs rename to pumpkin-protocol/src/java/server/play/pick_item.rs diff --git a/pumpkin-protocol/src/server/play/ping_request.rs b/pumpkin-protocol/src/java/server/play/ping_request.rs similarity index 100% rename from pumpkin-protocol/src/server/play/ping_request.rs rename to pumpkin-protocol/src/java/server/play/ping_request.rs diff --git a/pumpkin-protocol/src/server/play/player_abilities.rs b/pumpkin-protocol/src/java/server/play/player_abilities.rs similarity index 100% rename from pumpkin-protocol/src/server/play/player_abilities.rs rename to pumpkin-protocol/src/java/server/play/player_abilities.rs diff --git a/pumpkin-protocol/src/server/play/player_action.rs b/pumpkin-protocol/src/java/server/play/player_action.rs similarity index 100% rename from pumpkin-protocol/src/server/play/player_action.rs rename to pumpkin-protocol/src/java/server/play/player_action.rs diff --git a/pumpkin-protocol/src/server/play/player_command.rs b/pumpkin-protocol/src/java/server/play/player_command.rs similarity index 96% rename from pumpkin-protocol/src/server/play/player_command.rs rename to pumpkin-protocol/src/java/server/play/player_command.rs index e0daa5718..7c6d1a7d6 100644 --- a/pumpkin-protocol/src/server/play/player_command.rs +++ b/pumpkin-protocol/src/java/server/play/player_command.rs @@ -4,7 +4,8 @@ use pumpkin_data::packet::serverbound::PLAY_PLAYER_COMMAND; use pumpkin_macros::packet; use crate::{ - ServerPacket, VarInt, + ServerPacket, + codec::var_int::VarInt, ser::{NetworkReadExt, ReadingError}, }; diff --git a/pumpkin-protocol/src/server/play/player_ground.rs b/pumpkin-protocol/src/java/server/play/player_ground.rs similarity index 100% rename from pumpkin-protocol/src/server/play/player_ground.rs rename to pumpkin-protocol/src/java/server/play/player_ground.rs diff --git a/pumpkin-protocol/src/server/play/player_input.rs b/pumpkin-protocol/src/java/server/play/player_input.rs similarity index 100% rename from pumpkin-protocol/src/server/play/player_input.rs rename to pumpkin-protocol/src/java/server/play/player_input.rs diff --git a/pumpkin-protocol/src/server/play/player_loaded.rs b/pumpkin-protocol/src/java/server/play/player_loaded.rs similarity index 100% rename from pumpkin-protocol/src/server/play/player_loaded.rs rename to pumpkin-protocol/src/java/server/play/player_loaded.rs diff --git a/pumpkin-protocol/src/server/play/player_position.rs b/pumpkin-protocol/src/java/server/play/player_position.rs similarity index 100% rename from pumpkin-protocol/src/server/play/player_position.rs rename to pumpkin-protocol/src/java/server/play/player_position.rs diff --git a/pumpkin-protocol/src/server/play/player_position_rotation.rs b/pumpkin-protocol/src/java/server/play/player_position_rotation.rs similarity index 100% rename from pumpkin-protocol/src/server/play/player_position_rotation.rs rename to pumpkin-protocol/src/java/server/play/player_position_rotation.rs diff --git a/pumpkin-protocol/src/server/play/player_rotation.rs b/pumpkin-protocol/src/java/server/play/player_rotation.rs similarity index 100% rename from pumpkin-protocol/src/server/play/player_rotation.rs rename to pumpkin-protocol/src/java/server/play/player_rotation.rs diff --git a/pumpkin-protocol/src/server/play/player_session.rs b/pumpkin-protocol/src/java/server/play/player_session.rs similarity index 100% rename from pumpkin-protocol/src/server/play/player_session.rs rename to pumpkin-protocol/src/java/server/play/player_session.rs diff --git a/pumpkin-protocol/src/server/play/set_command_block.rs b/pumpkin-protocol/src/java/server/play/set_command_block.rs similarity index 100% rename from pumpkin-protocol/src/server/play/set_command_block.rs rename to pumpkin-protocol/src/java/server/play/set_command_block.rs diff --git a/pumpkin-protocol/src/server/play/set_creative_slot.rs b/pumpkin-protocol/src/java/server/play/set_creative_slot.rs similarity index 100% rename from pumpkin-protocol/src/server/play/set_creative_slot.rs rename to pumpkin-protocol/src/java/server/play/set_creative_slot.rs diff --git a/pumpkin-protocol/src/server/play/set_held_item.rs b/pumpkin-protocol/src/java/server/play/set_held_item.rs similarity index 100% rename from pumpkin-protocol/src/server/play/set_held_item.rs rename to pumpkin-protocol/src/java/server/play/set_held_item.rs diff --git a/pumpkin-protocol/src/server/play/swing_arm.rs b/pumpkin-protocol/src/java/server/play/swing_arm.rs similarity index 100% rename from pumpkin-protocol/src/server/play/swing_arm.rs rename to pumpkin-protocol/src/java/server/play/swing_arm.rs diff --git a/pumpkin-protocol/src/server/play/update_sign.rs b/pumpkin-protocol/src/java/server/play/update_sign.rs similarity index 100% rename from pumpkin-protocol/src/server/play/update_sign.rs rename to pumpkin-protocol/src/java/server/play/update_sign.rs diff --git a/pumpkin-protocol/src/server/play/use_item.rs b/pumpkin-protocol/src/java/server/play/use_item.rs similarity index 100% rename from pumpkin-protocol/src/server/play/use_item.rs rename to pumpkin-protocol/src/java/server/play/use_item.rs diff --git a/pumpkin-protocol/src/server/play/use_item_on.rs b/pumpkin-protocol/src/java/server/play/use_item_on.rs similarity index 100% rename from pumpkin-protocol/src/server/play/use_item_on.rs rename to pumpkin-protocol/src/java/server/play/use_item_on.rs diff --git a/pumpkin-protocol/src/server/status/mod.rs b/pumpkin-protocol/src/java/server/status/mod.rs similarity index 100% rename from pumpkin-protocol/src/server/status/mod.rs rename to pumpkin-protocol/src/java/server/status/mod.rs diff --git a/pumpkin-protocol/src/server/status/ping_request.rs b/pumpkin-protocol/src/java/server/status/ping_request.rs similarity index 100% rename from pumpkin-protocol/src/server/status/ping_request.rs rename to pumpkin-protocol/src/java/server/status/ping_request.rs diff --git a/pumpkin-protocol/src/server/status/status_request.rs b/pumpkin-protocol/src/java/server/status/status_request.rs similarity index 100% rename from pumpkin-protocol/src/server/status/status_request.rs rename to pumpkin-protocol/src/java/server/status/status_request.rs diff --git a/pumpkin-protocol/src/lib.rs b/pumpkin-protocol/src/lib.rs index 342ca300f..1174c206a 100644 --- a/pumpkin-protocol/src/lib.rs +++ b/pumpkin-protocol/src/lib.rs @@ -10,23 +10,23 @@ use pumpkin_util::{ resource_location::ResourceLocation, text::{TextComponent, style::Style}, }; -use ser::{NetworkWriteExt, ReadingError, WritingError, packet::Packet}; +use ser::{ReadingError, WritingError}; use serde::{ Deserialize, Serialize, Serializer, de::{DeserializeSeed, Visitor}, }; +use thiserror::Error; use tokio::io::{AsyncRead, AsyncWrite}; -#[cfg(feature = "clientbound")] -pub mod client; +use crate::packet::Packet; + +pub mod bedrock; pub mod codec; -pub mod packet_decoder; -pub mod packet_encoder; +pub mod java; +pub mod packet; #[cfg(feature = "query")] pub mod query; pub mod ser; -#[cfg(feature = "serverbound")] -pub mod server; pub const MAX_PACKET_SIZE: u64 = 2097152; pub const MAX_PACKET_DATA_SIZE: usize = 8388608; @@ -334,18 +334,47 @@ pub struct RawPacket { pub trait ClientPacket: Packet { fn write_packet_data(&self, write: impl Write) -> Result<(), WritingError>; - - fn write(&self, write: impl Write) -> Result<(), WritingError> { - let mut write = write; - write.write_var_int(&VarInt(Self::PACKET_ID))?; - self.write_packet_data(write) - } } pub trait ServerPacket: Packet + Sized { fn read(read: impl Read) -> Result; } +/// Errors that can occur during packet encoding. +#[derive(Error, Debug)] +pub enum PacketEncodeError { + #[error("Packet exceeds maximum length: {0}")] + TooLong(usize), + #[error("Compression failed {0}")] + CompressionFailed(String), + #[error("Writing packet failed: {0}")] + Message(String), +} + +#[derive(Error, Debug)] +pub enum PacketDecodeError { + #[error("failed to decode packet ID")] + DecodeID, + #[error("packet exceeds maximum length")] + TooLong, + #[error("packet length is out of bounds")] + OutOfBounds, + #[error("malformed packet length VarInt: {0}")] + MalformedLength(String), + #[error("failed to decompress packet: {0}")] + FailedDecompression(String), // Updated to include error details + #[error("packet is uncompressed but greater than the threshold")] + NotCompressed, + #[error("the connection has closed")] + ConnectionClosed, +} + +impl From for PacketDecodeError { + fn from(value: ReadingError) -> Self { + Self::FailedDecompression(value.to_string()) + } +} + #[derive(Serialize)] pub struct StatusResponse { /// The version on which the server is running. (Optional) @@ -519,11 +548,13 @@ impl Serialize for LinkType { #[cfg(test)] mod test { - use crate::ser::{deserializer::Deserializer, serializer::Serializer}; use pumpkin_util::resource_location::ResourceLocation; use serde::{Deserialize, Serialize}; - use crate::{IdOr, SoundEvent}; + use crate::{ + IdOr, SoundEvent, + ser::{deserializer::Deserializer, serializer::Serializer}, + }; #[test] fn test_serde_id_or_id() { diff --git a/pumpkin-protocol/src/ser/packet.rs b/pumpkin-protocol/src/packet.rs similarity index 78% rename from pumpkin-protocol/src/ser/packet.rs rename to pumpkin-protocol/src/packet.rs index 5db408383..d098e6aa5 100644 --- a/pumpkin-protocol/src/ser/packet.rs +++ b/pumpkin-protocol/src/packet.rs @@ -1,10 +1,11 @@ +use std::io::{Read, Write}; + use serde::{Serialize, de::DeserializeOwned}; -use crate::{ClientPacket, ServerPacket, codec::var_int::VarIntType}; - -use super::{ - Read, ReadingError, Write, WritingError, deserializer, - serializer::{self}, +use crate::{ + ClientPacket, ReadingError, ServerPacket, WritingError, + codec::var_int::VarIntType, + ser::{deserializer, serializer}, }; pub trait Packet { diff --git a/pumpkin-protocol/src/ser/mod.rs b/pumpkin-protocol/src/ser/mod.rs index e9654cb58..2e3ae211e 100644 --- a/pumpkin-protocol/src/ser/mod.rs +++ b/pumpkin-protocol/src/ser/mod.rs @@ -10,7 +10,6 @@ pub mod deserializer; use pumpkin_nbt::{serializer::WriteAdaptor, tag::NbtTag}; use pumpkin_util::resource_location::ResourceLocation; use thiserror::Error; -pub mod packet; pub mod serializer; // TODO: This is a bit hacky diff --git a/pumpkin-registry/Cargo.toml b/pumpkin-registry/Cargo.toml index 93b7f9aa7..f82e98f22 100644 --- a/pumpkin-registry/Cargo.toml +++ b/pumpkin-registry/Cargo.toml @@ -9,7 +9,7 @@ pumpkin-protocol = { path = "../pumpkin-protocol" } pumpkin-nbt = { path = "../pumpkin-nbt" } pumpkin-util = { path = "../pumpkin-util" } -indexmap = { version = "2.9", features = ["serde"] } +indexmap = { version = "2.10", features = ["serde"] } serde.workspace = true serde_json.workspace = true diff --git a/pumpkin-registry/src/lib.rs b/pumpkin-registry/src/lib.rs index 3676f2587..0d483de3a 100644 --- a/pumpkin-registry/src/lib.rs +++ b/pumpkin-registry/src/lib.rs @@ -15,7 +15,7 @@ use instrument::Instrument; use jukebox_song::JukeboxSong; use paint::Painting; use pig::PigVariant; -use pumpkin_protocol::client::config::RegistryEntry; +use pumpkin_protocol::java::client::config::RegistryEntry; use pumpkin_util::resource_location::ResourceLocation; use serde::{Deserialize, Serialize}; use trim_material::TrimMaterial; diff --git a/pumpkin-world/Cargo.toml b/pumpkin-world/Cargo.toml index 6a288ae0c..3b5bb604c 100644 --- a/pumpkin-world/Cargo.toml +++ b/pumpkin-world/Cargo.toml @@ -38,12 +38,12 @@ zstd = "0.13.3" itertools = "0.14.0" file-guard = "0.2" -indexmap = "2.9" +indexmap = "2.10" enum_dispatch = "0.3" derive-getters = "0.5.0" thread_local = "1.1.9" -lru = "0.14.0" +lru = "0.15.0" tokio-util = { version = "0.7.15", features = ["rt"] } diff --git a/pumpkin/src/block/blocks/bamboo.rs b/pumpkin/src/block/blocks/bamboo.rs index 3c85ed7df..c7ac18998 100644 --- a/pumpkin/src/block/blocks/bamboo.rs +++ b/pumpkin/src/block/blocks/bamboo.rs @@ -2,7 +2,7 @@ use async_trait::async_trait; use pumpkin_data::tag::Tagable; use pumpkin_data::{Block, BlockDirection}; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::world::BlockAccessor; diff --git a/pumpkin/src/block/blocks/bed.rs b/pumpkin/src/block/blocks/bed.rs index 10c208388..e4990cb47 100644 --- a/pumpkin/src/block/blocks/bed.rs +++ b/pumpkin/src/block/blocks/bed.rs @@ -6,7 +6,7 @@ use pumpkin_data::entity::EntityType; use pumpkin_data::tag::{RegistryKey, get_tag_values}; use pumpkin_data::{Block, BlockDirection}; use pumpkin_data::{BlockState, block_properties::BedPart}; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_registry::VanillaDimensionType; use pumpkin_util::GameMode; use pumpkin_util::math::position::BlockPos; diff --git a/pumpkin/src/block/blocks/cactus.rs b/pumpkin/src/block/blocks/cactus.rs index 17312c964..da405a5c5 100644 --- a/pumpkin/src/block/blocks/cactus.rs +++ b/pumpkin/src/block/blocks/cactus.rs @@ -8,7 +8,7 @@ use pumpkin_data::damage::DamageType; use pumpkin_data::tag::Tagable; use pumpkin_data::{Block, BlockDirection, BlockState}; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::chunk::TickPriority; diff --git a/pumpkin/src/block/blocks/campfire.rs b/pumpkin/src/block/blocks/campfire.rs index 182a0a2ab..1e5c65f7b 100644 --- a/pumpkin/src/block/blocks/campfire.rs +++ b/pumpkin/src/block/blocks/campfire.rs @@ -7,7 +7,7 @@ use pumpkin_data::{ damage::DamageType, fluid::Fluid, }; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; diff --git a/pumpkin/src/block/blocks/carpet.rs b/pumpkin/src/block/blocks/carpet.rs index 733334451..067fa6526 100644 --- a/pumpkin/src/block/blocks/carpet.rs +++ b/pumpkin/src/block/blocks/carpet.rs @@ -6,7 +6,7 @@ use async_trait::async_trait; use pumpkin_data::tag::{RegistryKey, get_tag_values}; use pumpkin_data::{Block, BlockDirection}; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::chunk::TickPriority; diff --git a/pumpkin/src/block/blocks/chest.rs b/pumpkin/src/block/blocks/chest.rs index 0d4b6dbe3..c2b9e90e2 100644 --- a/pumpkin/src/block/blocks/chest.rs +++ b/pumpkin/src/block/blocks/chest.rs @@ -8,7 +8,7 @@ use pumpkin_data::entity::EntityPose; use pumpkin_data::item::Item; use pumpkin_data::{Block, BlockDirection, BlockState}; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::block::entities::chest::ChestBlockEntity; diff --git a/pumpkin/src/block/blocks/command.rs b/pumpkin/src/block/blocks/command.rs index 7a2c9143a..c494087fe 100644 --- a/pumpkin/src/block/blocks/command.rs +++ b/pumpkin/src/block/blocks/command.rs @@ -98,7 +98,7 @@ impl PumpkinBlock for CommandBlock { _block: &Block, _block_pos: &BlockPos, _face: pumpkin_data::BlockDirection, - _use_item_on: Option<&pumpkin_protocol::server::play::SUseItemOn>, + _use_item_on: Option<&pumpkin_protocol::java::server::play::SUseItemOn>, ) -> bool { if let Some(player) = player { if player.gamemode.load() == GameMode::Creative { diff --git a/pumpkin/src/block/blocks/dirt_path.rs b/pumpkin/src/block/blocks/dirt_path.rs index 53e0154c2..e54a125c5 100644 --- a/pumpkin/src/block/blocks/dirt_path.rs +++ b/pumpkin/src/block/blocks/dirt_path.rs @@ -9,7 +9,7 @@ use async_trait::async_trait; use pumpkin_data::Block; use pumpkin_data::BlockDirection; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::chunk::TickPriority; diff --git a/pumpkin/src/block/blocks/doors.rs b/pumpkin/src/block/blocks/doors.rs index 250fdb2ee..5606d112e 100644 --- a/pumpkin/src/block/blocks/doors.rs +++ b/pumpkin/src/block/blocks/doors.rs @@ -24,7 +24,7 @@ use crate::block::pumpkin_block::{BlockMetadata, PumpkinBlock}; use crate::block::registry::BlockActionResult; use crate::entity::player::Player; use pumpkin_data::item::Item; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use crate::server::Server; use crate::world::World; diff --git a/pumpkin/src/block/blocks/end_portal_frame.rs b/pumpkin/src/block/blocks/end_portal_frame.rs index 4940b295b..39d07b000 100644 --- a/pumpkin/src/block/blocks/end_portal_frame.rs +++ b/pumpkin/src/block/blocks/end_portal_frame.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use pumpkin_data::{Block, BlockDirection, block_properties::BlockProperties}; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; diff --git a/pumpkin/src/block/blocks/farmland.rs b/pumpkin/src/block/blocks/farmland.rs index 772d80089..82db48485 100644 --- a/pumpkin/src/block/blocks/farmland.rs +++ b/pumpkin/src/block/blocks/farmland.rs @@ -9,7 +9,7 @@ use async_trait::async_trait; use pumpkin_data::Block; use pumpkin_data::BlockDirection; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::chunk::TickPriority; diff --git a/pumpkin/src/block/blocks/fence_gates.rs b/pumpkin/src/block/blocks/fence_gates.rs index 85796a45e..0572342ca 100644 --- a/pumpkin/src/block/blocks/fence_gates.rs +++ b/pumpkin/src/block/blocks/fence_gates.rs @@ -8,7 +8,7 @@ use pumpkin_data::BlockDirection; use pumpkin_data::block_properties::BlockProperties; use pumpkin_data::tag::RegistryKey; use pumpkin_data::tag::get_tag_values; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::world::BlockFlags; diff --git a/pumpkin/src/block/blocks/fences.rs b/pumpkin/src/block/blocks/fences.rs index 152d64b87..2de9f3a9c 100644 --- a/pumpkin/src/block/blocks/fences.rs +++ b/pumpkin/src/block/blocks/fences.rs @@ -8,7 +8,7 @@ use pumpkin_data::block_properties::BlockProperties; use pumpkin_data::tag::RegistryKey; use pumpkin_data::tag::Tagable; use pumpkin_data::tag::get_tag_values; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; diff --git a/pumpkin/src/block/blocks/fire/fire.rs b/pumpkin/src/block/blocks/fire/fire.rs index 027c079a5..913407dd6 100644 --- a/pumpkin/src/block/blocks/fire/fire.rs +++ b/pumpkin/src/block/blocks/fire/fire.rs @@ -11,7 +11,7 @@ use std::sync::atomic::Ordering; use async_trait::async_trait; use pumpkin_data::{Block, BlockDirection, BlockState}; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::chunk::TickPriority; diff --git a/pumpkin/src/block/blocks/fire/soul_fire.rs b/pumpkin/src/block/blocks/fire/soul_fire.rs index 094f05eb9..d0c908e34 100644 --- a/pumpkin/src/block/blocks/fire/soul_fire.rs +++ b/pumpkin/src/block/blocks/fire/soul_fire.rs @@ -4,7 +4,7 @@ use async_trait::async_trait; use pumpkin_data::tag::Tagable; use pumpkin_data::{Block, BlockDirection, BlockState}; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::world::BlockAccessor; diff --git a/pumpkin/src/block/blocks/glass_panes.rs b/pumpkin/src/block/blocks/glass_panes.rs index c4583bac5..6d2d2bb9a 100644 --- a/pumpkin/src/block/blocks/glass_panes.rs +++ b/pumpkin/src/block/blocks/glass_panes.rs @@ -7,7 +7,7 @@ use pumpkin_data::block_properties::BlockProperties; use pumpkin_data::tag::RegistryKey; use pumpkin_data::tag::Tagable; use pumpkin_data::tag::get_tag_values; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; diff --git a/pumpkin/src/block/blocks/grindstone.rs b/pumpkin/src/block/blocks/grindstone.rs index c0a6073c8..5dcdf2cd7 100644 --- a/pumpkin/src/block/blocks/grindstone.rs +++ b/pumpkin/src/block/blocks/grindstone.rs @@ -4,7 +4,7 @@ use pumpkin_data::{ block_properties::{BlockFace, BlockProperties, GrindstoneLikeProperties}, }; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::{BlockStateId, world::BlockAccessor}; diff --git a/pumpkin/src/block/blocks/iron_bars.rs b/pumpkin/src/block/blocks/iron_bars.rs index 7a3bc6603..961606f4d 100644 --- a/pumpkin/src/block/blocks/iron_bars.rs +++ b/pumpkin/src/block/blocks/iron_bars.rs @@ -6,7 +6,7 @@ use pumpkin_data::BlockDirection; use pumpkin_data::block_properties::BlockProperties; use pumpkin_data::tag::Tagable; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; diff --git a/pumpkin/src/block/blocks/logs.rs b/pumpkin/src/block/blocks/logs.rs index 6b48d1905..27e85bc14 100644 --- a/pumpkin/src/block/blocks/logs.rs +++ b/pumpkin/src/block/blocks/logs.rs @@ -4,7 +4,7 @@ use pumpkin_data::BlockDirection; use pumpkin_data::block_properties::BlockProperties; use pumpkin_data::tag::RegistryKey; use pumpkin_data::tag::get_tag_values; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; diff --git a/pumpkin/src/block/blocks/note.rs b/pumpkin/src/block/blocks/note.rs index 83517d360..e6daa997b 100644 --- a/pumpkin/src/block/blocks/note.rs +++ b/pumpkin/src/block/blocks/note.rs @@ -14,7 +14,7 @@ use pumpkin_data::{ }, }; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::world::BlockFlags; diff --git a/pumpkin/src/block/blocks/piston/piston.rs b/pumpkin/src/block/blocks/piston/piston.rs index 4e49a8d77..8bdc7a778 100644 --- a/pumpkin/src/block/blocks/piston/piston.rs +++ b/pumpkin/src/block/blocks/piston/piston.rs @@ -9,7 +9,7 @@ use pumpkin_data::{ }, block_state::PistonBehavior, }; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::{ BlockStateId, diff --git a/pumpkin/src/block/blocks/plant/bush.rs b/pumpkin/src/block/blocks/plant/bush.rs index ca961a8a8..42f3fa809 100644 --- a/pumpkin/src/block/blocks/plant/bush.rs +++ b/pumpkin/src/block/blocks/plant/bush.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use pumpkin_data::tag::Tagable; use pumpkin_data::{Block, BlockDirection}; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::world::BlockAccessor; diff --git a/pumpkin/src/block/blocks/plant/dry_vegetation.rs b/pumpkin/src/block/blocks/plant/dry_vegetation.rs index 3a768b030..758540a8d 100644 --- a/pumpkin/src/block/blocks/plant/dry_vegetation.rs +++ b/pumpkin/src/block/blocks/plant/dry_vegetation.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use pumpkin_data::tag::Tagable; use pumpkin_data::{Block, BlockDirection}; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::world::BlockAccessor; diff --git a/pumpkin/src/block/blocks/plant/flower.rs b/pumpkin/src/block/blocks/plant/flower.rs index 828208208..33fd572fc 100644 --- a/pumpkin/src/block/blocks/plant/flower.rs +++ b/pumpkin/src/block/blocks/plant/flower.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use pumpkin_data::tag::{RegistryKey, Tagable, get_tag_values}; use pumpkin_data::{Block, BlockDirection}; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::world::BlockAccessor; diff --git a/pumpkin/src/block/blocks/plant/flowerbed.rs b/pumpkin/src/block/blocks/plant/flowerbed.rs index eefa62c7e..ff5db3dd8 100644 --- a/pumpkin/src/block/blocks/plant/flowerbed.rs +++ b/pumpkin/src/block/blocks/plant/flowerbed.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use pumpkin_data::tag::Tagable; use pumpkin_data::{Block, BlockDirection}; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::{BlockStateId, world::BlockAccessor}; diff --git a/pumpkin/src/block/blocks/plant/leaf_litter.rs b/pumpkin/src/block/blocks/plant/leaf_litter.rs index 8cde7cb53..d263056cc 100644 --- a/pumpkin/src/block/blocks/plant/leaf_litter.rs +++ b/pumpkin/src/block/blocks/plant/leaf_litter.rs @@ -1,6 +1,6 @@ use async_trait::async_trait; use pumpkin_data::{Block, BlockDirection}; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::{BlockStateId, world::BlockAccessor}; diff --git a/pumpkin/src/block/blocks/plant/lily_pad.rs b/pumpkin/src/block/blocks/plant/lily_pad.rs index 0f8b6a884..57d30afe1 100644 --- a/pumpkin/src/block/blocks/plant/lily_pad.rs +++ b/pumpkin/src/block/blocks/plant/lily_pad.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use async_trait::async_trait; use pumpkin_data::{Block, BlockDirection, BlockState}; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::world::{BlockAccessor, BlockFlags}; diff --git a/pumpkin/src/block/blocks/plant/mushroom_plant.rs b/pumpkin/src/block/blocks/plant/mushroom_plant.rs index ce23ca4a9..092962a36 100644 --- a/pumpkin/src/block/blocks/plant/mushroom_plant.rs +++ b/pumpkin/src/block/blocks/plant/mushroom_plant.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use pumpkin_data::tag::Tagable; use pumpkin_data::{Block, BlockDirection}; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::world::BlockAccessor; diff --git a/pumpkin/src/block/blocks/plant/roots.rs b/pumpkin/src/block/blocks/plant/roots.rs index ecd544df2..6cef76ca7 100644 --- a/pumpkin/src/block/blocks/plant/roots.rs +++ b/pumpkin/src/block/blocks/plant/roots.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use pumpkin_data::tag::Tagable; use pumpkin_data::{Block, BlockDirection}; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::world::BlockAccessor; diff --git a/pumpkin/src/block/blocks/plant/sapling.rs b/pumpkin/src/block/blocks/plant/sapling.rs index 2debd583c..a8c9e56c2 100644 --- a/pumpkin/src/block/blocks/plant/sapling.rs +++ b/pumpkin/src/block/blocks/plant/sapling.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use pumpkin_data::tag::{RegistryKey, Tagable, get_tag_values}; use pumpkin_data::{Block, BlockDirection}; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::world::BlockAccessor; diff --git a/pumpkin/src/block/blocks/plant/segmented.rs b/pumpkin/src/block/blocks/plant/segmented.rs index cc69e2204..682864b46 100644 --- a/pumpkin/src/block/blocks/plant/segmented.rs +++ b/pumpkin/src/block/blocks/plant/segmented.rs @@ -3,7 +3,7 @@ use pumpkin_data::{ Block, BlockDirection, block_properties::{BlockProperties, HorizontalFacing, Integer1To4}, }; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; diff --git a/pumpkin/src/block/blocks/plant/short_plant.rs b/pumpkin/src/block/blocks/plant/short_plant.rs index c5e329c27..de241f03d 100644 --- a/pumpkin/src/block/blocks/plant/short_plant.rs +++ b/pumpkin/src/block/blocks/plant/short_plant.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use pumpkin_data::tag::Tagable; use pumpkin_data::{Block, BlockDirection}; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::world::BlockAccessor; diff --git a/pumpkin/src/block/blocks/plant/tall_plant.rs b/pumpkin/src/block/blocks/plant/tall_plant.rs index 31818863d..ab7d5d4a1 100644 --- a/pumpkin/src/block/blocks/plant/tall_plant.rs +++ b/pumpkin/src/block/blocks/plant/tall_plant.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use pumpkin_data::tag::Tagable; use pumpkin_data::{Block, BlockDirection}; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::world::BlockAccessor; diff --git a/pumpkin/src/block/blocks/redstone/buttons.rs b/pumpkin/src/block/blocks/redstone/buttons.rs index b40e17b9d..f581122f9 100644 --- a/pumpkin/src/block/blocks/redstone/buttons.rs +++ b/pumpkin/src/block/blocks/redstone/buttons.rs @@ -10,7 +10,7 @@ use pumpkin_data::block_properties::BlockProperties; use pumpkin_data::item::Item; use pumpkin_data::tag::RegistryKey; use pumpkin_data::tag::get_tag_values; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::chunk::TickPriority; diff --git a/pumpkin/src/block/blocks/redstone/comparator.rs b/pumpkin/src/block/blocks/redstone/comparator.rs index 734b4f4c0..3513f29a8 100644 --- a/pumpkin/src/block/blocks/redstone/comparator.rs +++ b/pumpkin/src/block/blocks/redstone/comparator.rs @@ -11,7 +11,7 @@ use pumpkin_data::{ item::Item, }; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::{boundingbox::BoundingBox, position::BlockPos}; use pumpkin_world::{ BlockStateId, diff --git a/pumpkin/src/block/blocks/redstone/copper_bulb.rs b/pumpkin/src/block/blocks/redstone/copper_bulb.rs index 45887225f..be67e3760 100644 --- a/pumpkin/src/block/blocks/redstone/copper_bulb.rs +++ b/pumpkin/src/block/blocks/redstone/copper_bulb.rs @@ -8,7 +8,7 @@ use async_trait::async_trait; use pumpkin_data::block_properties::BlockProperties; use pumpkin_data::sound::{Sound, SoundCategory}; use pumpkin_data::{Block, BlockDirection}; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::world::BlockFlags; diff --git a/pumpkin/src/block/blocks/redstone/lever.rs b/pumpkin/src/block/blocks/redstone/lever.rs index 0c72747d7..f50b18b37 100644 --- a/pumpkin/src/block/blocks/redstone/lever.rs +++ b/pumpkin/src/block/blocks/redstone/lever.rs @@ -11,7 +11,7 @@ use pumpkin_data::{ item::Item, }; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::{ BlockStateId, diff --git a/pumpkin/src/block/blocks/redstone/observer.rs b/pumpkin/src/block/blocks/redstone/observer.rs index fdfbf0185..48a992038 100644 --- a/pumpkin/src/block/blocks/redstone/observer.rs +++ b/pumpkin/src/block/blocks/redstone/observer.rs @@ -7,7 +7,7 @@ use pumpkin_data::{ block_properties::{BlockProperties, ObserverLikeProperties}, }; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::{BlockStateId, chunk::TickPriority, world::BlockFlags}; diff --git a/pumpkin/src/block/blocks/redstone/rails/activator_rail.rs b/pumpkin/src/block/blocks/redstone/rails/activator_rail.rs index ee490f5a3..63ab227c2 100644 --- a/pumpkin/src/block/blocks/redstone/rails/activator_rail.rs +++ b/pumpkin/src/block/blocks/redstone/rails/activator_rail.rs @@ -2,7 +2,7 @@ use async_trait::async_trait; use pumpkin_data::Block; use pumpkin_data::BlockDirection; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::world::BlockAccessor; diff --git a/pumpkin/src/block/blocks/redstone/rails/detector_rail.rs b/pumpkin/src/block/blocks/redstone/rails/detector_rail.rs index 57353c2db..a1ef96dc1 100644 --- a/pumpkin/src/block/blocks/redstone/rails/detector_rail.rs +++ b/pumpkin/src/block/blocks/redstone/rails/detector_rail.rs @@ -2,7 +2,7 @@ use async_trait::async_trait; use pumpkin_data::Block; use pumpkin_data::BlockDirection; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::world::BlockAccessor; diff --git a/pumpkin/src/block/blocks/redstone/rails/powered_rail.rs b/pumpkin/src/block/blocks/redstone/rails/powered_rail.rs index c20267b98..ec443b17f 100644 --- a/pumpkin/src/block/blocks/redstone/rails/powered_rail.rs +++ b/pumpkin/src/block/blocks/redstone/rails/powered_rail.rs @@ -2,7 +2,7 @@ use async_trait::async_trait; use pumpkin_data::Block; use pumpkin_data::BlockDirection; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::world::BlockAccessor; diff --git a/pumpkin/src/block/blocks/redstone/rails/rail.rs b/pumpkin/src/block/blocks/redstone/rails/rail.rs index 033afa4de..7f6ae9000 100644 --- a/pumpkin/src/block/blocks/redstone/rails/rail.rs +++ b/pumpkin/src/block/blocks/redstone/rails/rail.rs @@ -4,7 +4,7 @@ use pumpkin_data::BlockDirection; use pumpkin_data::block_properties::HorizontalFacing; use pumpkin_data::block_properties::RailShape; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::world::BlockAccessor; diff --git a/pumpkin/src/block/blocks/redstone/redstone_lamp.rs b/pumpkin/src/block/blocks/redstone/redstone_lamp.rs index 8f96ff630..cd6aa9a15 100644 --- a/pumpkin/src/block/blocks/redstone/redstone_lamp.rs +++ b/pumpkin/src/block/blocks/redstone/redstone_lamp.rs @@ -4,7 +4,7 @@ use crate::{block::BlockIsReplacing, entity::player::Player}; use async_trait::async_trait; use pumpkin_data::{Block, BlockDirection, block_properties::BlockProperties}; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::{BlockStateId, chunk::TickPriority, world::BlockFlags}; diff --git a/pumpkin/src/block/blocks/redstone/redstone_torch.rs b/pumpkin/src/block/blocks/redstone/redstone_torch.rs index d3fdecbee..14f42aaf5 100644 --- a/pumpkin/src/block/blocks/redstone/redstone_torch.rs +++ b/pumpkin/src/block/blocks/redstone/redstone_torch.rs @@ -11,7 +11,7 @@ use pumpkin_data::FacingExt; use pumpkin_data::HorizontalFacingExt; use pumpkin_data::block_properties::BlockProperties; use pumpkin_data::block_properties::Facing; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::chunk::TickPriority; diff --git a/pumpkin/src/block/blocks/redstone/redstone_wire.rs b/pumpkin/src/block/blocks/redstone/redstone_wire.rs index b2b3a9454..dd79a9133 100644 --- a/pumpkin/src/block/blocks/redstone/redstone_wire.rs +++ b/pumpkin/src/block/blocks/redstone/redstone_wire.rs @@ -9,7 +9,7 @@ use pumpkin_data::block_properties::{ use pumpkin_data::item::Item; use pumpkin_data::{Block, BlockDirection, BlockState, HorizontalFacingExt}; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::world::{BlockAccessor, BlockFlags}; diff --git a/pumpkin/src/block/blocks/redstone/repeater.rs b/pumpkin/src/block/blocks/redstone/repeater.rs index a00bb1203..b71db3564 100644 --- a/pumpkin/src/block/blocks/redstone/repeater.rs +++ b/pumpkin/src/block/blocks/redstone/repeater.rs @@ -9,7 +9,7 @@ use pumpkin_data::{ item::Item, }; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::world::{BlockAccessor, BlockFlags}; use pumpkin_world::{BlockStateId, chunk::TickPriority}; diff --git a/pumpkin/src/block/blocks/redstone/tripwire.rs b/pumpkin/src/block/blocks/redstone/tripwire.rs index 642a63b97..6885e4141 100644 --- a/pumpkin/src/block/blocks/redstone/tripwire.rs +++ b/pumpkin/src/block/blocks/redstone/tripwire.rs @@ -7,7 +7,7 @@ use pumpkin_data::{ item::Item, }; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::{boundingbox::BoundingBox, position::BlockPos}; use pumpkin_world::{BlockStateId, chunk::TickPriority, world::BlockFlags}; diff --git a/pumpkin/src/block/blocks/redstone/tripwire_hook.rs b/pumpkin/src/block/blocks/redstone/tripwire_hook.rs index f1d8ed478..cbceefd03 100644 --- a/pumpkin/src/block/blocks/redstone/tripwire_hook.rs +++ b/pumpkin/src/block/blocks/redstone/tripwire_hook.rs @@ -7,7 +7,7 @@ use pumpkin_data::{ sound::{Sound, SoundCategory}, }; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::{ BlockStateId, diff --git a/pumpkin/src/block/blocks/sea_pickles.rs b/pumpkin/src/block/blocks/sea_pickles.rs index 4d310cc0e..33bf8c9f3 100644 --- a/pumpkin/src/block/blocks/sea_pickles.rs +++ b/pumpkin/src/block/blocks/sea_pickles.rs @@ -12,7 +12,7 @@ use pumpkin_data::item::Item; use pumpkin_data::tag::Tagable; use pumpkin_data::{Block, BlockDirection}; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::world::{BlockAccessor, BlockFlags}; diff --git a/pumpkin/src/block/blocks/signs.rs b/pumpkin/src/block/blocks/signs.rs index c57e0b3bc..88e6d190a 100644 --- a/pumpkin/src/block/blocks/signs.rs +++ b/pumpkin/src/block/blocks/signs.rs @@ -6,7 +6,7 @@ use pumpkin_data::BlockDirection; use pumpkin_data::block_properties::BlockProperties; use pumpkin_data::tag::RegistryKey; use pumpkin_data::tag::get_tag_values; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::block::entities::sign::SignBlockEntity; diff --git a/pumpkin/src/block/blocks/slabs.rs b/pumpkin/src/block/blocks/slabs.rs index e0d64434c..2596066d2 100644 --- a/pumpkin/src/block/blocks/slabs.rs +++ b/pumpkin/src/block/blocks/slabs.rs @@ -5,7 +5,7 @@ use pumpkin_data::block_properties::BlockProperties; use pumpkin_data::block_properties::SlabType; use pumpkin_data::tag::RegistryKey; use pumpkin_data::tag::get_tag_values; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; diff --git a/pumpkin/src/block/blocks/stairs.rs b/pumpkin/src/block/blocks/stairs.rs index 190e9a162..c0bb57861 100644 --- a/pumpkin/src/block/blocks/stairs.rs +++ b/pumpkin/src/block/blocks/stairs.rs @@ -8,7 +8,7 @@ use pumpkin_data::block_properties::StairShape; use pumpkin_data::tag::RegistryKey; use pumpkin_data::tag::Tagable; use pumpkin_data::tag::get_tag_values; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::world::BlockFlags; diff --git a/pumpkin/src/block/blocks/sugar_cane.rs b/pumpkin/src/block/blocks/sugar_cane.rs index 7d0a46363..58d045526 100644 --- a/pumpkin/src/block/blocks/sugar_cane.rs +++ b/pumpkin/src/block/blocks/sugar_cane.rs @@ -8,7 +8,7 @@ use pumpkin_data::{ block_properties::{BlockProperties, CactusLikeProperties, EnumVariants, Integer0To15}, }; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::chunk::TickPriority; diff --git a/pumpkin/src/block/blocks/torches.rs b/pumpkin/src/block/blocks/torches.rs index abb178c06..cfbec0062 100644 --- a/pumpkin/src/block/blocks/torches.rs +++ b/pumpkin/src/block/blocks/torches.rs @@ -5,7 +5,7 @@ use async_trait::async_trait; use pumpkin_data::BlockDirection; use pumpkin_data::block_properties::{BlockProperties, Facing}; use pumpkin_data::{Block, FacingExt, HorizontalFacingExt}; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::world::BlockAccessor; diff --git a/pumpkin/src/block/blocks/trapdoor.rs b/pumpkin/src/block/blocks/trapdoor.rs index dbcc15679..8ac96594f 100644 --- a/pumpkin/src/block/blocks/trapdoor.rs +++ b/pumpkin/src/block/blocks/trapdoor.rs @@ -12,7 +12,7 @@ use pumpkin_data::block_properties::{BlockHalf, BlockProperties}; use pumpkin_data::item::Item; use pumpkin_data::sound::{Sound, SoundCategory}; use pumpkin_data::tag::{RegistryKey, Tagable, get_tag_values}; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::world::BlockFlags; diff --git a/pumpkin/src/block/blocks/vine.rs b/pumpkin/src/block/blocks/vine.rs index 04caaa8ca..8fdbfa826 100644 --- a/pumpkin/src/block/blocks/vine.rs +++ b/pumpkin/src/block/blocks/vine.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use pumpkin_data::{Block, BlockDirection}; use pumpkin_macros::pumpkin_block; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::world::BlockAccessor; diff --git a/pumpkin/src/block/blocks/walls.rs b/pumpkin/src/block/blocks/walls.rs index 606c7c3fb..fe9769baf 100644 --- a/pumpkin/src/block/blocks/walls.rs +++ b/pumpkin/src/block/blocks/walls.rs @@ -12,7 +12,7 @@ use pumpkin_data::block_properties::WestWallShape; use pumpkin_data::tag::RegistryKey; use pumpkin_data::tag::Tagable; use pumpkin_data::tag::get_tag_values; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; diff --git a/pumpkin/src/block/pumpkin_block.rs b/pumpkin/src/block/pumpkin_block.rs index f071ab829..5170fbad1 100644 --- a/pumpkin/src/block/pumpkin_block.rs +++ b/pumpkin/src/block/pumpkin_block.rs @@ -6,7 +6,7 @@ use crate::world::World; use async_trait::async_trait; use pumpkin_data::item::Item; use pumpkin_data::{Block, BlockDirection, BlockState}; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::world::{BlockAccessor, BlockFlags}; diff --git a/pumpkin/src/block/pumpkin_fluid.rs b/pumpkin/src/block/pumpkin_fluid.rs index 526470255..e6cbe32d7 100644 --- a/pumpkin/src/block/pumpkin_fluid.rs +++ b/pumpkin/src/block/pumpkin_fluid.rs @@ -4,7 +4,7 @@ use crate::entity::{EntityBase, player::Player}; use async_trait::async_trait; use pumpkin_data::BlockDirection; use pumpkin_data::{fluid::Fluid, item::Item}; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; diff --git a/pumpkin/src/block/registry.rs b/pumpkin/src/block/registry.rs index 25e72b54c..da093be09 100644 --- a/pumpkin/src/block/registry.rs +++ b/pumpkin/src/block/registry.rs @@ -7,7 +7,7 @@ use async_trait::async_trait; use pumpkin_data::fluid::Fluid; use pumpkin_data::item::Item; use pumpkin_data::{Block, BlockDirection, BlockState}; -use pumpkin_protocol::server::play::SUseItemOn; +use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; use pumpkin_world::BlockStateId; use pumpkin_world::world::{BlockAccessor, BlockFlags, BlockRegistryExt}; diff --git a/pumpkin/src/command/args/block.rs b/pumpkin/src/command/args/block.rs index ddf13a6cf..bec83d66c 100644 --- a/pumpkin/src/command/args/block.rs +++ b/pumpkin/src/command/args/block.rs @@ -1,6 +1,6 @@ use async_trait::async_trait; use pumpkin_data::{Block, block_properties::get_block}; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; use crate::{command::dispatcher::CommandError, server::Server}; diff --git a/pumpkin/src/command/args/bool.rs b/pumpkin/src/command/args/bool.rs index 2916dfa1f..2b5aad36a 100644 --- a/pumpkin/src/command/args/bool.rs +++ b/pumpkin/src/command/args/bool.rs @@ -4,7 +4,7 @@ use crate::command::dispatcher::CommandError; use crate::command::tree::RawArgs; use crate::server::Server; use async_trait::async_trait; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; pub struct BoolArgConsumer; diff --git a/pumpkin/src/command/args/bossbar_color.rs b/pumpkin/src/command/args/bossbar_color.rs index 81914a6e7..031d5a9ad 100644 --- a/pumpkin/src/command/args/bossbar_color.rs +++ b/pumpkin/src/command/args/bossbar_color.rs @@ -7,7 +7,7 @@ use crate::command::tree::RawArgs; use crate::server::Server; use crate::world::bossbar::BossbarColor; use async_trait::async_trait; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; pub struct BossbarColorArgumentConsumer; diff --git a/pumpkin/src/command/args/bossbar_style.rs b/pumpkin/src/command/args/bossbar_style.rs index c911aaaeb..af5f09759 100644 --- a/pumpkin/src/command/args/bossbar_style.rs +++ b/pumpkin/src/command/args/bossbar_style.rs @@ -7,7 +7,7 @@ use crate::command::tree::RawArgs; use crate::server::Server; use crate::world::bossbar::BossbarDivisions; use async_trait::async_trait; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; pub struct BossbarStyleArgumentConsumer; diff --git a/pumpkin/src/command/args/bounded_num.rs b/pumpkin/src/command/args/bounded_num.rs index f143d1816..b7d99d76b 100644 --- a/pumpkin/src/command/args/bounded_num.rs +++ b/pumpkin/src/command/args/bounded_num.rs @@ -3,7 +3,7 @@ use std::fmt::{Display, Formatter}; use std::str::FromStr; use async_trait::async_trait; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion}; use crate::command::CommandSender; use crate::command::dispatcher::CommandError; @@ -202,7 +202,7 @@ impl GetClientSideArgParser for BoundedNumArgumentConsumer { fn get_client_side_suggestion_type_override( &self, - ) -> Option { + ) -> Option { None } } @@ -230,7 +230,7 @@ impl GetClientSideArgParser for BoundedNumArgumentConsumer { fn get_client_side_suggestion_type_override( &self, - ) -> Option { + ) -> Option { None } } @@ -258,7 +258,7 @@ impl GetClientSideArgParser for BoundedNumArgumentConsumer { fn get_client_side_suggestion_type_override( &self, - ) -> Option { + ) -> Option { None } } @@ -286,7 +286,7 @@ impl GetClientSideArgParser for BoundedNumArgumentConsumer { fn get_client_side_suggestion_type_override( &self, - ) -> Option { + ) -> Option { None } } diff --git a/pumpkin/src/command/args/command.rs b/pumpkin/src/command/args/command.rs index 8c54b068d..bd11ba3a3 100644 --- a/pumpkin/src/command/args/command.rs +++ b/pumpkin/src/command/args/command.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use pumpkin_protocol::client::play::{ +use pumpkin_protocol::java::client::play::{ ArgumentType, CommandSuggestion, StringProtoArgBehavior, SuggestionProviders, }; diff --git a/pumpkin/src/command/args/difficulty.rs b/pumpkin/src/command/args/difficulty.rs index 082374ac7..b6e2bae92 100644 --- a/pumpkin/src/command/args/difficulty.rs +++ b/pumpkin/src/command/args/difficulty.rs @@ -1,7 +1,7 @@ use std::str::FromStr; use async_trait::async_trait; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; use pumpkin_util::Difficulty; use crate::{ @@ -15,7 +15,9 @@ pub struct DifficultyArgumentConsumer; impl GetClientSideArgParser for DifficultyArgumentConsumer { fn get_client_side_parser(&self) -> ArgumentType { - ArgumentType::String(pumpkin_protocol::client::play::StringProtoArgBehavior::SingleWord) + ArgumentType::String( + pumpkin_protocol::java::client::play::StringProtoArgBehavior::SingleWord, + ) } fn get_client_side_suggestion_type_override(&self) -> Option { diff --git a/pumpkin/src/command/args/entities.rs b/pumpkin/src/command/args/entities.rs index 49f819230..e18ae1822 100644 --- a/pumpkin/src/command/args/entities.rs +++ b/pumpkin/src/command/args/entities.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use async_trait::async_trait; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; use crate::command::CommandSender; use crate::command::dispatcher::CommandError; diff --git a/pumpkin/src/command/args/entity.rs b/pumpkin/src/command/args/entity.rs index efb22e7fc..9aa628876 100644 --- a/pumpkin/src/command/args/entity.rs +++ b/pumpkin/src/command/args/entity.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use async_trait::async_trait; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; use crate::command::CommandSender; use crate::command::dispatcher::CommandError; diff --git a/pumpkin/src/command/args/gamemode.rs b/pumpkin/src/command/args/gamemode.rs index 218c5ceeb..bb7f6423b 100644 --- a/pumpkin/src/command/args/gamemode.rs +++ b/pumpkin/src/command/args/gamemode.rs @@ -1,7 +1,7 @@ use std::str::FromStr; use async_trait::async_trait; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; use pumpkin_util::GameMode; use crate::{ diff --git a/pumpkin/src/command/args/message.rs b/pumpkin/src/command/args/message.rs index ec0e81e2d..dc57a4afa 100644 --- a/pumpkin/src/command/args/message.rs +++ b/pumpkin/src/command/args/message.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use pumpkin_protocol::client::play::{ +use pumpkin_protocol::java::client::play::{ ArgumentType, CommandSuggestion, StringProtoArgBehavior, SuggestionProviders, }; diff --git a/pumpkin/src/command/args/mod.rs b/pumpkin/src/command/args/mod.rs index 9752c0ef9..8d728372c 100644 --- a/pumpkin/src/command/args/mod.rs +++ b/pumpkin/src/command/args/mod.rs @@ -6,7 +6,7 @@ use pumpkin_data::damage::DamageType; use pumpkin_data::entity::EffectType; use pumpkin_data::particle::Particle; use pumpkin_data::sound::SoundCategory; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; use pumpkin_util::Difficulty; use pumpkin_util::text::TextComponent; use pumpkin_util::{ diff --git a/pumpkin/src/command/args/players.rs b/pumpkin/src/command/args/players.rs index 93181d643..91d624d8f 100644 --- a/pumpkin/src/command/args/players.rs +++ b/pumpkin/src/command/args/players.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use async_trait::async_trait; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; use crate::command::CommandSender; use crate::command::dispatcher::CommandError; diff --git a/pumpkin/src/command/args/position_2d.rs b/pumpkin/src/command/args/position_2d.rs index 7ab4046c4..acb77bc8a 100644 --- a/pumpkin/src/command/args/position_2d.rs +++ b/pumpkin/src/command/args/position_2d.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; use pumpkin_util::math::vector2::Vector2; use pumpkin_util::math::vector3::Vector3; diff --git a/pumpkin/src/command/args/position_3d.rs b/pumpkin/src/command/args/position_3d.rs index c00d4ef90..67129b35d 100644 --- a/pumpkin/src/command/args/position_3d.rs +++ b/pumpkin/src/command/args/position_3d.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; use pumpkin_util::math::vector3::Vector3; use crate::command::CommandSender; diff --git a/pumpkin/src/command/args/position_block.rs b/pumpkin/src/command/args/position_block.rs index d87bb19b5..f633f5816 100644 --- a/pumpkin/src/command/args/position_block.rs +++ b/pumpkin/src/command/args/position_block.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::vector3::Vector3; diff --git a/pumpkin/src/command/args/resource/damage_type.rs b/pumpkin/src/command/args/resource/damage_type.rs index 24f9a8a58..ccd57c935 100644 --- a/pumpkin/src/command/args/resource/damage_type.rs +++ b/pumpkin/src/command/args/resource/damage_type.rs @@ -1,6 +1,6 @@ use async_trait::async_trait; use pumpkin_data::damage::DamageType; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; use crate::command::{ CommandSender, diff --git a/pumpkin/src/command/args/resource/effect.rs b/pumpkin/src/command/args/resource/effect.rs index cf2002c3b..411a36791 100644 --- a/pumpkin/src/command/args/resource/effect.rs +++ b/pumpkin/src/command/args/resource/effect.rs @@ -1,6 +1,6 @@ use async_trait::async_trait; use pumpkin_data::entity::EffectType; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; use crate::command::{ CommandSender, diff --git a/pumpkin/src/command/args/resource/item.rs b/pumpkin/src/command/args/resource/item.rs index fdad1edde..9dd8664ac 100644 --- a/pumpkin/src/command/args/resource/item.rs +++ b/pumpkin/src/command/args/resource/item.rs @@ -1,6 +1,6 @@ use async_trait::async_trait; use pumpkin_data::item::Item; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; use crate::command::{ CommandSender, diff --git a/pumpkin/src/command/args/resource/particle.rs b/pumpkin/src/command/args/resource/particle.rs index edf1cff42..cbee369b7 100644 --- a/pumpkin/src/command/args/resource/particle.rs +++ b/pumpkin/src/command/args/resource/particle.rs @@ -1,6 +1,6 @@ use async_trait::async_trait; use pumpkin_data::particle::Particle; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; use crate::command::{ CommandSender, diff --git a/pumpkin/src/command/args/resource_location.rs b/pumpkin/src/command/args/resource_location.rs index 6e84660f9..03878e6c8 100644 --- a/pumpkin/src/command/args/resource_location.rs +++ b/pumpkin/src/command/args/resource_location.rs @@ -6,7 +6,7 @@ use crate::command::dispatcher::CommandError; use crate::command::tree::RawArgs; use crate::server::Server; use async_trait::async_trait; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; pub struct ResourceLocationArgumentConsumer { autocomplete: bool, diff --git a/pumpkin/src/command/args/rotation.rs b/pumpkin/src/command/args/rotation.rs index c080675c7..edb93f264 100644 --- a/pumpkin/src/command/args/rotation.rs +++ b/pumpkin/src/command/args/rotation.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; use crate::command::CommandSender; use crate::command::dispatcher::CommandError; diff --git a/pumpkin/src/command/args/simple.rs b/pumpkin/src/command/args/simple.rs index 16eef7b85..7b7860358 100644 --- a/pumpkin/src/command/args/simple.rs +++ b/pumpkin/src/command/args/simple.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use pumpkin_protocol::client::play::{ +use pumpkin_protocol::java::client::play::{ ArgumentType, CommandSuggestion, StringProtoArgBehavior, SuggestionProviders, }; diff --git a/pumpkin/src/command/args/sound.rs b/pumpkin/src/command/args/sound.rs index 494e8feab..2a3230156 100644 --- a/pumpkin/src/command/args/sound.rs +++ b/pumpkin/src/command/args/sound.rs @@ -1,6 +1,6 @@ use async_trait::async_trait; use pumpkin_data::sound::Sound; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; use crate::{command::dispatcher::CommandError, server::Server}; diff --git a/pumpkin/src/command/args/sound_category.rs b/pumpkin/src/command/args/sound_category.rs index 582a422b9..66a7cdb11 100644 --- a/pumpkin/src/command/args/sound_category.rs +++ b/pumpkin/src/command/args/sound_category.rs @@ -7,7 +7,7 @@ use crate::command::tree::RawArgs; use crate::server::Server; use async_trait::async_trait; use pumpkin_data::sound::SoundCategory; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; /// `ArgumentConsumer` for Minecraft sound categories (master, music, record, etc.) pub struct SoundCategoryArgumentConsumer; diff --git a/pumpkin/src/command/args/summonable_entities.rs b/pumpkin/src/command/args/summonable_entities.rs index 57b9cbae0..4c98112e5 100644 --- a/pumpkin/src/command/args/summonable_entities.rs +++ b/pumpkin/src/command/args/summonable_entities.rs @@ -1,6 +1,6 @@ use async_trait::async_trait; use pumpkin_data::entity::EntityType; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; use crate::{command::dispatcher::CommandError, server::Server}; diff --git a/pumpkin/src/command/args/textcomponent.rs b/pumpkin/src/command/args/textcomponent.rs index e4c5dc7b5..83b695e8d 100644 --- a/pumpkin/src/command/args/textcomponent.rs +++ b/pumpkin/src/command/args/textcomponent.rs @@ -4,7 +4,7 @@ use crate::command::dispatcher::CommandError; use crate::command::tree::RawArgs; use crate::server::Server; use async_trait::async_trait; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; use pumpkin_util::text::TextComponent; pub struct TextComponentArgConsumer; diff --git a/pumpkin/src/command/args/time.rs b/pumpkin/src/command/args/time.rs index 03a5d0b51..f46ec69a8 100644 --- a/pumpkin/src/command/args/time.rs +++ b/pumpkin/src/command/args/time.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; +use pumpkin_protocol::java::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders}; use crate::command::{ CommandSender, diff --git a/pumpkin/src/command/client_suggestions.rs b/pumpkin/src/command/client_suggestions.rs index 66afcdb82..5b51c9882 100644 --- a/pumpkin/src/command/client_suggestions.rs +++ b/pumpkin/src/command/client_suggestions.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use pumpkin_protocol::client::play::{CCommands, ProtoNode, ProtoNodeType}; +use pumpkin_protocol::java::client::play::{CCommands, ProtoNode, ProtoNodeType}; use crate::entity::player::Player; diff --git a/pumpkin/src/command/commands/title.rs b/pumpkin/src/command/commands/title.rs index 6450a08d6..dfdf10ffa 100644 --- a/pumpkin/src/command/commands/title.rs +++ b/pumpkin/src/command/commands/title.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use pumpkin_protocol::client::play::CClearTitle; +use pumpkin_protocol::java::client::play::CClearTitle; use pumpkin_util::text::TextComponent; use crate::{ diff --git a/pumpkin/src/command/commands/transfer.rs b/pumpkin/src/command/commands/transfer.rs index bc9cfac61..1c2526a82 100644 --- a/pumpkin/src/command/commands/transfer.rs +++ b/pumpkin/src/command/commands/transfer.rs @@ -1,6 +1,6 @@ use async_trait::async_trait; -use pumpkin_protocol::client::play::CTransfer; use pumpkin_protocol::codec::var_int::VarInt; +use pumpkin_protocol::java::client::play::CTransfer; use pumpkin_util::text::TextComponent; use pumpkin_util::text::color::{Color, NamedColor}; diff --git a/pumpkin/src/command/dispatcher.rs b/pumpkin/src/command/dispatcher.rs index d9e2627f5..1f3e0eb0b 100644 --- a/pumpkin/src/command/dispatcher.rs +++ b/pumpkin/src/command/dispatcher.rs @@ -1,4 +1,4 @@ -use pumpkin_protocol::client::play::CommandSuggestion; +use pumpkin_protocol::java::client::play::CommandSuggestion; use pumpkin_util::text::TextComponent; use super::args::ConsumedArgs; diff --git a/pumpkin/src/entity/ai/path/mod.rs b/pumpkin/src/entity/ai/path/mod.rs index 7053bc2c6..ce8b61eee 100644 --- a/pumpkin/src/entity/ai/path/mod.rs +++ b/pumpkin/src/entity/ai/path/mod.rs @@ -1,4 +1,4 @@ -use pumpkin_protocol::client::play::CUpdateEntityPos; +use pumpkin_protocol::java::client::play::CUpdateEntityPos; use pumpkin_util::math::{position::BlockPos, vector3::Vector3}; use crate::entity::living::LivingEntity; diff --git a/pumpkin/src/entity/combat.rs b/pumpkin/src/entity/combat.rs index 2aa72d6d2..92e675d86 100644 --- a/pumpkin/src/entity/combat.rs +++ b/pumpkin/src/entity/combat.rs @@ -2,7 +2,7 @@ use pumpkin_data::{ particle::Particle, sound::{Sound, SoundCategory}, }; -use pumpkin_protocol::{client::play::CEntityVelocity, codec::var_int::VarInt}; +use pumpkin_protocol::{codec::var_int::VarInt, java::client::play::CEntityVelocity}; use pumpkin_util::math::vector3::Vector3; use crate::{ diff --git a/pumpkin/src/entity/item.rs b/pumpkin/src/entity/item.rs index 1af67055e..22e970a67 100644 --- a/pumpkin/src/entity/item.rs +++ b/pumpkin/src/entity/item.rs @@ -6,8 +6,8 @@ use std::sync::{ use async_trait::async_trait; use pumpkin_data::damage::DamageType; use pumpkin_protocol::{ - client::play::{CTakeItemEntity, MetaDataType, Metadata}, codec::item_stack_seralizer::ItemStackSerializer, + java::client::play::{CTakeItemEntity, MetaDataType, Metadata}, }; use pumpkin_util::math::vector3::Vector3; use pumpkin_world::item::ItemStack; diff --git a/pumpkin/src/entity/living.rs b/pumpkin/src/entity/living.rs index 11621708e..fc09846ab 100644 --- a/pumpkin/src/entity/living.rs +++ b/pumpkin/src/entity/living.rs @@ -15,11 +15,11 @@ use pumpkin_data::{damage::DamageType, sound::Sound}; use pumpkin_inventory::entity_equipment::EntityEquipment; use pumpkin_inventory::equipment_slot::EquipmentSlot; use pumpkin_nbt::tag::NbtTag; -use pumpkin_protocol::client::play::{CHurtAnimation, CTakeItemEntity}; use pumpkin_protocol::codec::var_int::VarInt; +use pumpkin_protocol::java::client::play::{CHurtAnimation, CTakeItemEntity}; use pumpkin_protocol::{ - client::play::{CDamageEvent, CSetEquipment, MetaDataType, Metadata}, codec::item_stack_seralizer::ItemStackSerializer, + java::client::play::{CDamageEvent, CSetEquipment, MetaDataType, Metadata}, }; use pumpkin_util::math::vector3::Vector3; use pumpkin_world::item::ItemStack; diff --git a/pumpkin/src/entity/mod.rs b/pumpkin/src/entity/mod.rs index 248ffb530..803bbca59 100644 --- a/pumpkin/src/entity/mod.rs +++ b/pumpkin/src/entity/mod.rs @@ -13,11 +13,11 @@ use pumpkin_data::{ }; use pumpkin_nbt::{compound::NbtCompound, tag::NbtTag}; use pumpkin_protocol::{ - client::play::{ + codec::var_int::VarInt, + java::client::play::{ CEntityPositionSync, CEntityVelocity, CHeadRot, CSetEntityMetadata, CSpawnEntity, CUpdateEntityRot, MetaDataType, Metadata, }, - codec::var_int::VarInt, ser::serializer::Serializer, }; use pumpkin_registry::VanillaDimensionType; diff --git a/pumpkin/src/entity/player.rs b/pumpkin/src/entity/player.rs index 8b784ff30..f63faaa01 100644 --- a/pumpkin/src/entity/player.rs +++ b/pumpkin/src/entity/player.rs @@ -35,7 +35,8 @@ use pumpkin_inventory::sync_handler::SyncHandler; use pumpkin_macros::send_cancellable; use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::tag::NbtTag; -use pumpkin_protocol::client::play::{ +use pumpkin_protocol::codec::var_int::VarInt; +use pumpkin_protocol::java::client::play::{ Animation, CAcknowledgeBlockChange, CActionBar, CChangeDifficulty, CChunkBatchEnd, CChunkBatchStart, CChunkData, CCloseContainer, CCombatDeath, CDisguisedChatMessage, CEntityAnimation, CEntityPositionSync, CGameEvent, CKeepAlive, COpenScreen, CParticle, @@ -45,9 +46,7 @@ use pumpkin_protocol::client::play::{ CSubtitle, CSystemChatMessage, CTitleText, CUnloadChunk, CUpdateMobEffect, CUpdateTime, GameEvent, MetaDataType, Metadata, PlayerAction, PlayerInfoFlags, PreviousMessage, }; -use pumpkin_protocol::codec::var_int::VarInt; -use pumpkin_protocol::ser::packet::Packet; -use pumpkin_protocol::server::play::{ +use pumpkin_protocol::java::server::play::{ SChangeGameMode, SChatCommand, SChatMessage, SChunkBatch, SClickSlot, SClientCommand, SClientInformationPlay, SClientTickEnd, SCloseContainer, SCommandSuggestion, SConfirmTeleport, SCookieResponse as SPCookieResponse, SInteract, SKeepAlive, SPickItemFromBlock, @@ -55,6 +54,7 @@ use pumpkin_protocol::server::play::{ SPlayerPosition, SPlayerPositionRotation, SPlayerRotation, SPlayerSession, SSetCommandBlock, SSetCreativeSlot, SSetHeldItem, SSetPlayerGround, SSwingArm, SUpdateSign, SUseItem, SUseItemOn, }; +use pumpkin_protocol::packet::Packet; use pumpkin_protocol::{IdOr, RawPacket, ServerPacket}; use pumpkin_registry::VanillaDimensionType; use pumpkin_util::GameMode; @@ -1328,7 +1328,7 @@ impl Player { .await .broadcast_packet_all(&CPlayerInfoUpdate::new( PlayerInfoFlags::UPDATE_GAME_MODE.bits(), - &[pumpkin_protocol::client::play::Player { + &[pumpkin_protocol::java::client::play::Player { uuid: self.gameprofile.id, actions: &[PlayerAction::UpdateGameMode((gamemode as i32).into())], }], @@ -1620,10 +1620,12 @@ impl Player { pub async fn remove_effect(&self, effect_type: EffectType) { let effect_id = VarInt(effect_type as i32); self.client - .enqueue_packet(&pumpkin_protocol::client::play::CRemoveMobEffect::new( - self.entity_id().into(), - effect_id, - )) + .enqueue_packet( + &pumpkin_protocol::java::client::play::CRemoveMobEffect::new( + self.entity_id().into(), + effect_id, + ), + ) .await; self.living_entity.remove_effect(effect_type).await; @@ -1637,10 +1639,12 @@ impl Player { effect_list.push(*effect); let effect_id = VarInt(*effect as i32); self.client - .enqueue_packet(&pumpkin_protocol::client::play::CRemoveMobEffect::new( - self.entity_id().into(), - effect_id, - )) + .enqueue_packet( + &pumpkin_protocol::java::client::play::CRemoveMobEffect::new( + self.entity_id().into(), + effect_id, + ), + ) .await; count += 1; } diff --git a/pumpkin/src/entity/tnt.rs b/pumpkin/src/entity/tnt.rs index bbbce39f2..6e5383a71 100644 --- a/pumpkin/src/entity/tnt.rs +++ b/pumpkin/src/entity/tnt.rs @@ -2,8 +2,8 @@ use crate::server::Server; use async_trait::async_trait; use pumpkin_data::{Block, damage::DamageType}; use pumpkin_protocol::{ - client::play::{MetaDataType, Metadata}, codec::var_int::VarInt, + java::client::play::{MetaDataType, Metadata}, }; use pumpkin_util::math::vector3::Vector3; use std::{ diff --git a/pumpkin/src/lib.rs b/pumpkin/src/lib.rs index baf3fae3c..9ba113189 100644 --- a/pumpkin/src/lib.rs +++ b/pumpkin/src/lib.rs @@ -1,8 +1,12 @@ // Not warn event sending macros #![allow(unused_labels)] +use crate::net::ClientPlatform; +use crate::net::bedrock::BedrockClientPlatform; +use crate::net::java::JavaClientPlatform; use crate::net::{Client, lan_broadcast, query, rcon::RCONServer}; use crate::server::{Server, ticker::Ticker}; +use bytes::Bytes; use log::{Level, LevelFilter, Log}; use net::authentication::fetch_mojang_public_keys; use plugin::PluginManager; @@ -12,18 +16,19 @@ use pumpkin_macros::send_cancellable; use pumpkin_util::permission::{PermissionManager, PermissionRegistry}; use pumpkin_util::text::TextComponent; use rustyline_async::{Readline, ReadlineEvent}; -use std::io::{IsTerminal, stdin}; +use std::collections::HashMap; +use std::io::{Cursor, IsTerminal, stdin}; use std::str::FromStr; -use std::sync::atomic::AtomicBool; +use std::sync::atomic::{AtomicBool, Ordering}; use std::{ net::SocketAddr, sync::{Arc, LazyLock}, }; -use tokio::net::TcpListener; +use tokio::net::{TcpListener, UdpSocket}; use tokio::select; #[cfg(feature = "dhat-heap")] use tokio::sync::Mutex; -use tokio::sync::{Notify, RwLock}; +use tokio::sync::{Mutex, Notify, RwLock}; use tokio_util::task::TaskTracker; pub mod block; @@ -196,8 +201,8 @@ pub fn stop_server() { pub struct PumpkinServer { pub server: Arc, - pub listener: TcpListener, - pub server_addr: SocketAddr, + pub tcp_listener: TcpListener, + pub udp_socket: Arc, } impl PumpkinServer { @@ -208,15 +213,6 @@ impl PumpkinServer { world.level.read_spawn_chunks(&Server::spawn_chunks()).await; } - // Setup the TCP server socket. - let listener = tokio::net::TcpListener::bind(BASIC_CONFIG.server_address) - .await - .expect("Failed to start `TcpListener`"); - // In the event the user puts 0 for their port, this will allow us to know what port it is running on - let addr = listener - .local_addr() - .expect("Unable to get the address of the server!"); - let rcon = advanced_config().networking.rcon.clone(); let mut ticker = Ticker::new(); @@ -243,9 +239,21 @@ impl PumpkinServer { }); } + // Setup the TCP server socket. + let listener = tokio::net::TcpListener::bind(BASIC_CONFIG.java_edition_address) + .await + .expect("Failed to start `TcpListener`"); + // In the event the user puts 0 for their port, this will allow us to know what port it is running on + let addr = listener + .local_addr() + .expect("Unable to get the address of the server!"); + if advanced_config().networking.query.enabled { log::info!("Query protocol is enabled. Starting..."); - server.spawn_task(query::start_query_handler(server.clone(), addr)); + server.spawn_task(query::start_query_handler( + server.clone(), + advanced_config().networking.query.address, + )); } if advanced_config().networking.lan_broadcast.enabled { @@ -268,10 +276,14 @@ impl PumpkinServer { }); }; + let udp_socket = UdpSocket::bind(BASIC_CONFIG.bedrock_edition_address) + .await + .expect("Failed to bind UDP Socket"); + Self { server: server.clone(), - listener, - server_addr: addr, + tcp_listener: listener, + udp_socket: Arc::new(udp_socket), } } @@ -293,86 +305,17 @@ impl PumpkinServer { } pub async fn start(&self) { - let mut master_client_id: u64 = 0; - let tasks = TaskTracker::new(); + let tasks = Arc::new(TaskTracker::new()); + let master_client_id: u64 = 0; + let bedrock_clients = Arc::new(Mutex::new(HashMap::new())); while !SHOULD_STOP.load(std::sync::atomic::Ordering::Relaxed) { - let await_new_client = || async { - let t1 = self.listener.accept(); - let t2 = STOP_INTERRUPT.notified(); - - select! { - client = t1 => Some(client.unwrap()), - () = t2 => None, - } - }; - - // Asynchronously wait for an inbound socket. - let Some((connection, client_addr)) = await_new_client().await else { + if !self + .unified_listener_task(master_client_id, &tasks, &bedrock_clients) + .await + { break; - }; - - if let Err(e) = connection.set_nodelay(true) { - log::warn!("Failed to set TCP_NODELAY {e}"); } - - let id = master_client_id; - master_client_id = master_client_id.wrapping_add(1); - - let formatted_address = if BASIC_CONFIG.scrub_ips { - scrub_address(&format!("{client_addr}")) - } else { - format!("{client_addr}") - }; - log::debug!("Accepted connection from: {formatted_address} (id {id})"); - - let mut client = Client::new(connection, client_addr, id); - client.init(); - let server = self.server.clone(); - - tasks.spawn(async move { - // TODO: We need to add a time-out here for un-cooperative clients - client.process_packets(&server).await; - - if client - .make_player - .load(std::sync::atomic::Ordering::Relaxed) - { - // Client is kicked if this fails - if let Some((player, world)) = server.add_player(client).await { - world - .spawn_player(&BASIC_CONFIG, player.clone(), &server) - .await; - - player.process_packets(&server).await; - player.close().await; - - //TODO: Move these somewhere less likely to be forgotten - log::debug!("Cleaning up player for id {id}"); - - // Save player data on disconnect - if let Err(e) = server - .player_data_storage - .handle_player_leave(&player) - .await - { - log::error!("Failed to save player data on disconnect: {e}"); - } - - // Remove the player from its world - player.remove().await; - // Tick down the online count - server.remove_player(&player).await; - } - } else { - // Also handle case of client connects but does not become a player (like a server - // ping) - client.close(); - log::debug!("Awaiting tasks for client {id}"); - client.await_tasks().await; - log::debug!("Finished awaiting tasks for client {id}"); - } - }); } log::info!("Stopped accepting incoming connections"); @@ -411,6 +354,137 @@ impl PumpkinServer { } } } + + #[expect(unused_assignments)] + pub async fn unified_listener_task( + &self, + mut master_client_id_counter: u64, + _tasks: &Arc, + bedrock_clients: &Arc>>>, + ) -> bool { + let mut udp_buf = vec![0; 4096]; // Buffer for UDP receive + + select! { + // Branch for TCP connections (Java Edition) + tcp_result = self.tcp_listener.accept() => { + match tcp_result { + Ok((connection, client_addr)) => { + if let Err(e) = connection.set_nodelay(true) { + log::warn!("Failed to set TCP_NODELAY: {e}"); + } + + let client_id = master_client_id_counter; + master_client_id_counter += 1; + + let formatted_address = if BASIC_CONFIG.scrub_ips { + scrub_address(&format!("{client_addr}")) + } else { + format!("{client_addr}") + }; + log::debug!("Accepted connection from Java Edition: {formatted_address} (id {client_id})"); + + // Create a new JavaClientPlatform instance for this specific connection + let java_client_platform_instance = JavaClientPlatform::new(connection); + + let mut client = Client::new( + ClientPlatform::Java(java_client_platform_instance), + client_addr, + client_id, + ); + client.init(); + + let server_clone = self.server.clone(); + + tokio::spawn(async move { + // Handles the lifecycle of a single Java client + match client.platform.as_ref() { + ClientPlatform::Java(java) => { + java.process_packets(&client, &server_clone).await; + }, + ClientPlatform::Bedrock(_) => unreachable!("Java client handler received a Bedrock platform."), + }; + + if client.make_player.load(Ordering::Relaxed) { + if let Some((player, world)) = server_clone.add_player(client).await { // client needs to be cloned here if moved into add_player + world.spawn_player(&BASIC_CONFIG, player.clone(), &server_clone).await; + + player.process_packets(&server_clone).await; // Player's main packet loop + player.close().await; // Signal player to stop its packet processing loop + + log::debug!("Cleaning up player for id {client_id}"); + + if let Err(e) = server_clone.player_data_storage + .handle_player_leave(&player) + .await + { + log::error!("Failed to save player data on disconnect: {e}"); + } + + player.remove().await; + server_clone.remove_player(&player).await; + } + } else { + client.close(); + log::debug!("Awaiting tasks for client {}", client.id); + client.await_tasks().await; + log::debug!("Finished awaiting tasks for client {}", client.id); + } + }); + } + Err(e) => { + log::error!("Failed to accept Java client connection: {e}"); + tokio::time::sleep(tokio::time::Duration::from_millis(50)).await; + } + } + }, + + // Branch for UDP packets (Bedrock Edition) + udp_result = self.udp_socket.recv_from(&mut udp_buf) => { + match udp_result { + Ok((len, client_addr)) => { + if len == 0 { + log::warn!("Received empty UDP packet from {client_addr}"); + } + let received_data = Bytes::copy_from_slice(&udp_buf[..len]); + + + let mut clients_guard = bedrock_clients.lock().await; + + let client = clients_guard.entry(client_addr).or_insert_with(|| { + let client_id = master_client_id_counter; + master_client_id_counter += 1; + log::info!("New Bedrock client detected from: {client_addr} (ID: {client_id})"); + // Use the prototype to create a new BedrockClientPlatform instance + Arc::new(Client::new(ClientPlatform::Bedrock( + BedrockClientPlatform::new(self.udp_socket.clone(), client_addr) + ), client_addr, client_id)) + }); + + let server_clone = self.server.clone(); + + let reader = Cursor::new(received_data.to_vec()); + let client = client.clone(); + tokio::spawn(async move { + if let ClientPlatform::Bedrock(bedrock_plat) = client.platform.as_ref() { + bedrock_plat.process_packet(&client, &server_clone, reader).await; + } + //tasks_clone.track_task_completion(client_clone_for_task.id); + }); + } + Err(e) => { + log::error!("Failed to receive UDP packet for Bedrock: {e}"); + tokio::time::sleep(tokio::time::Duration::from_millis(50)).await; + } + } + }, + + // Branch for the global stop signal + () = STOP_INTERRUPT.notified() => { + return false; + } + } + true + } } async fn setup_stdin_console(server: Arc) { diff --git a/pumpkin/src/main.rs b/pumpkin/src/main.rs index 9ce1d2035..0ff1bb445 100644 --- a/pumpkin/src/main.rs +++ b/pumpkin/src/main.rs @@ -37,6 +37,7 @@ compile_error!("Compiling for WASI targets is not supported!"); use plugin::PluginManager; +use pumpkin_config::BASIC_CONFIG; use pumpkin_data::packet::CURRENT_MC_PROTOCOL; use std::{ io::{self}, @@ -156,8 +157,25 @@ async fn main() { log::info!("Started server; took {}ms", time.elapsed().as_millis()); log::info!( - "You now can connect to the server; listening on {}", - pumpkin_server.server_addr + "Server is now running. Connect using: {}{}{}", + if BASIC_CONFIG.java_edition { + format!("Java Edition: {}", BASIC_CONFIG.java_edition_address) + } else { + String::new() + }, + if BASIC_CONFIG.java_edition && BASIC_CONFIG.bedrock_edition { + " | " // Separator if both are enabled + } else { + "" + }, + if BASIC_CONFIG.bedrock_edition { + format!( + "Bedrock/Pocket Edition: {}", + BASIC_CONFIG.bedrock_edition_address + ) + } else { + String::new() + } ); pumpkin_server.start().await; diff --git a/pumpkin/src/net/bedrock/mod.rs b/pumpkin/src/net/bedrock/mod.rs new file mode 100644 index 000000000..e316ee111 --- /dev/null +++ b/pumpkin/src/net/bedrock/mod.rs @@ -0,0 +1,150 @@ +use std::{ + io::{Cursor, Write}, + sync::Arc, +}; + +use bytes::Bytes; +use pumpkin_protocol::{ + ClientPacket, PacketDecodeError, PacketEncodeError, RawPacket, ServerPacket, + bedrock::{ + packet_decoder::UDPNetworkDecoder, + packet_encoder::UDPNetworkEncoder, + server::{ + open_connection::{SOpenConnectionRequest1, SOpenConnectionRequest2}, + unconnected_ping::SUnconnectedPing, + }, + }, + packet::Packet, + ser::{NetworkWriteExt, ReadingError, WritingError}, +}; +use std::net::SocketAddr; +use tokio::{net::UdpSocket, sync::Mutex}; + +pub mod open_connection; +pub mod unconnected; + +use crate::{net::Client, server::Server}; + +pub struct BedrockClientPlatform { + socket: Arc, + addr: SocketAddr, + + /// The packet encoder for outgoing packets. + network_writer: Arc>, + /// The packet decoder for incoming packets. + network_reader: Mutex, +} + +impl BedrockClientPlatform { + pub fn new(socket: Arc, addr: SocketAddr) -> Self { + Self { + socket, + addr, + network_writer: Arc::new(Mutex::new(UDPNetworkEncoder::new())), + network_reader: Mutex::new(UDPNetworkDecoder::new()), + } + } + + pub async fn process_packet(&self, client: &Client, server: &Server, packet: Cursor>) { + let packet = self.get_packet(client, packet).await; + if let Some(packet) = packet { + if let Err(error) = Self::handle_packet(client, server, &packet).await { + let _text = format!("Error while reading incoming packet {error}"); + log::error!( + "Failed to read incoming packet with id {}: {}", + packet.id, + error + ); + //self.kick(TextComponent::text(text)).await; + } + } + } + + pub fn write_packet( + packet: &P, + write: impl Write, + ) -> Result<(), WritingError> { + let mut write = write; + write.write_u8_be(P::PACKET_ID as u8)?; + packet.write_packet_data(write) + } + + pub async fn write_packet_data(&self, packet_data: Bytes) -> Result<(), PacketEncodeError> { + self.network_writer + .lock() + .await + .write_packet(packet_data, self.addr, &self.socket) + .await + } + + pub async fn send_packet_now(&self, client: &Client, packet: Vec) { + if let Err(err) = self + .network_writer + .lock() + .await + .write_packet(packet.into(), self.addr, &self.socket) + .await + { + // It is expected that the packet will fail if we are closed + if !client.closed.load(std::sync::atomic::Ordering::Relaxed) { + log::warn!("Failed to send packet to client {}: {}", client.id, err); + // We now need to close the connection to the client since the stream is in an + // unknown state + client.close(); + } + } + } + + pub async fn handle_packet( + client: &Client, + server: &Server, + packet: &RawPacket, + ) -> Result<(), ReadingError> { + let payload = &packet.payload[..]; + match packet.id { + SUnconnectedPing::PACKET_ID => { + client + .handle_unconnected_ping(server, SUnconnectedPing::read(payload)?) + .await; + } + SOpenConnectionRequest1::PACKET_ID => { + client + .handle_open_connection_1(server, SOpenConnectionRequest1::read(payload)?) + .await; + } + SOpenConnectionRequest2::PACKET_ID => { + client + .handle_open_connection_2(server, SOpenConnectionRequest2::read(payload)?) + .await; + } + _ => { + log::error!("Failed to handle bedrock client packet id {}", packet.id); + } + } + Ok(()) + } + + pub async fn get_packet(&self, client: &Client, packet: Cursor>) -> Option { + let mut network_reader = self.network_reader.lock().await; + tokio::select! { + () = client.await_close_interrupt() => { + log::debug!("Canceling player packet processing"); + None + }, + packet_result = network_reader.get_raw_packet(packet) => { + match packet_result { + Ok(packet) => Some(packet), + Err(err) => { + if !matches!(err, PacketDecodeError::ConnectionClosed) { + log::warn!("Failed to decode packet from client {}: {}", client.id, err); + let _text = format!("Error while reading incoming packet {err}"); + client.close(); + //self.kick(client, TextComponent::text(text)).await; + } + None + } + } + } + } + } +} diff --git a/pumpkin/src/net/bedrock/open_connection.rs b/pumpkin/src/net/bedrock/open_connection.rs new file mode 100644 index 000000000..61ea806a7 --- /dev/null +++ b/pumpkin/src/net/bedrock/open_connection.rs @@ -0,0 +1,30 @@ +use pumpkin_protocol::{ + bedrock::{ + client::open_connection::{COpenConnectionReply1, COpenConnectionReply2}, + server::open_connection::{SOpenConnectionRequest1, SOpenConnectionRequest2}, + }, + codec::socket_address::SocketAddress, +}; + +use crate::{net::Client, server::Server}; + +impl Client { + pub async fn handle_open_connection_1(&self, server: &Server, packet: SOpenConnectionRequest1) { + self.send_packet_now(&COpenConnectionReply1::new( + server.server_guid, + false, + 0, + packet.mtu, + )) + .await; + } + pub async fn handle_open_connection_2(&self, server: &Server, packet: SOpenConnectionRequest2) { + self.send_packet_now(&COpenConnectionReply2::new( + server.server_guid, + SocketAddress(*self.address.lock().await), + packet.mtu, + false, + )) + .await; + } +} diff --git a/pumpkin/src/net/bedrock/unconnected.rs b/pumpkin/src/net/bedrock/unconnected.rs new file mode 100644 index 000000000..c949c5921 --- /dev/null +++ b/pumpkin/src/net/bedrock/unconnected.rs @@ -0,0 +1,36 @@ +use pumpkin_config::BASIC_CONFIG; +use pumpkin_protocol::{ + bedrock::{ + client::unconnected_pong::{CUnconnectedPong, ServerInfo}, + server::unconnected_ping::SUnconnectedPing, + }, + codec::ascii_string::AsciiString, +}; + +use crate::{net::Client, server::Server}; + +impl Client { + pub async fn handle_unconnected_ping(&self, server: &Server, packet: SUnconnectedPing) { + let motd_string = ServerInfo { + edition: "MCPE", + motd_line_1: &BASIC_CONFIG.motd, + protocol_version: 527, + version_name: "1.19.1", + player_count: 1, + max_player_count: BASIC_CONFIG.max_players, + server_unique_id: server.server_guid, + motd_line_2: &BASIC_CONFIG.motd, + game_mode: "Survival", + game_mode_numeric: 1, + port_ipv4: 19132, + port_ipv6: 19133, + }; + self.send_packet_now(&CUnconnectedPong::new( + packet.time, + server.server_guid, + packet.magic, + AsciiString(format!("{motd_string}")), + )) + .await; + } +} diff --git a/pumpkin/src/net/packet/config.rs b/pumpkin/src/net/java/config.rs similarity index 98% rename from pumpkin/src/net/packet/config.rs rename to pumpkin/src/net/java/config.rs index 2b809ffa1..249f8bbf6 100644 --- a/pumpkin/src/net/packet/config.rs +++ b/pumpkin/src/net/java/config.rs @@ -9,8 +9,8 @@ use core::str; use pumpkin_config::advanced_config; use pumpkin_protocol::{ ConnectionState, - client::config::{CFinishConfig, CRegistryData}, - server::config::{ + java::client::config::{CFinishConfig, CRegistryData}, + java::server::config::{ ResourcePackResponseResult, SClientInformationConfig, SConfigCookieResponse, SConfigResourcePack, SKnownPacks, SPluginMessage, }, diff --git a/pumpkin/src/net/packet/handshake.rs b/pumpkin/src/net/java/handshake.rs similarity index 94% rename from pumpkin/src/net/packet/handshake.rs rename to pumpkin/src/net/java/handshake.rs index bedf002bb..d1d711c34 100644 --- a/pumpkin/src/net/packet/handshake.rs +++ b/pumpkin/src/net/java/handshake.rs @@ -1,5 +1,5 @@ use pumpkin_data::packet::CURRENT_MC_PROTOCOL; -use pumpkin_protocol::{ConnectionState, server::handshake::SHandShake}; +use pumpkin_protocol::{ConnectionState, java::server::handshake::SHandShake}; use pumpkin_util::text::TextComponent; use crate::{net::Client, server::CURRENT_MC_VERSION}; diff --git a/pumpkin/src/net/packet/login.rs b/pumpkin/src/net/java/login.rs similarity index 98% rename from pumpkin/src/net/packet/login.rs rename to pumpkin/src/net/java/login.rs index 650c0b4fc..8624dd3d3 100644 --- a/pumpkin/src/net/packet/login.rs +++ b/pumpkin/src/net/java/login.rs @@ -3,11 +3,13 @@ use std::sync::LazyLock; use pumpkin_config::{BASIC_CONFIG, advanced_config}; use pumpkin_protocol::{ ConnectionState, KnownPack, Label, Link, LinkType, - client::{ + java::client::{ config::{CConfigAddResourcePack, CConfigServerLinks, CKnownPacks, CUpdateTags}, login::{CLoginSuccess, CSetCompression}, }, - server::login::{SEncryptionResponse, SLoginCookieResponse, SLoginPluginResponse, SLoginStart}, + java::server::login::{ + SEncryptionResponse, SLoginCookieResponse, SLoginPluginResponse, SLoginStart, + }, }; use pumpkin_util::text::TextComponent; use uuid::Uuid; @@ -16,8 +18,7 @@ use crate::{ net::{ Client, GameProfile, authentication::{self, AuthError}, - offline_uuid, - packet::is_valid_player_name, + is_valid_player_name, offline_uuid, proxy::{bungeecord, velocity}, }, server::Server, diff --git a/pumpkin/src/net/java/mod.rs b/pumpkin/src/net/java/mod.rs new file mode 100644 index 000000000..fdfcdeeca --- /dev/null +++ b/pumpkin/src/net/java/mod.rs @@ -0,0 +1,389 @@ +use std::{io::Write, sync::Arc}; + +use bytes::Bytes; +use pumpkin_config::networking::compression::CompressionInfo; +use pumpkin_protocol::{ + ClientPacket, ConnectionState, PacketDecodeError, PacketEncodeError, RawPacket, ServerPacket, + codec::var_int::VarInt, + java::{ + client::{config::CConfigDisconnect, login::CLoginDisconnect, play::CPlayDisconnect}, + packet_decoder::TCPNetworkDecoder, + packet_encoder::TCPNetworkEncoder, + server::{ + config::{ + SAcknowledgeFinishConfig, SClientInformationConfig, SConfigCookieResponse, + SConfigResourcePack, SKnownPacks, SPluginMessage, + }, + handshake::SHandShake, + login::{ + SEncryptionResponse, SLoginAcknowledged, SLoginCookieResponse, + SLoginPluginResponse, SLoginStart, + }, + status::{SStatusPingRequest, SStatusRequest}, + }, + }, + packet::Packet, + ser::{NetworkWriteExt, ReadingError, WritingError}, +}; +use pumpkin_util::text::TextComponent; +use tokio::{ + io::{BufReader, BufWriter}, + net::{ + TcpStream, + tcp::{OwnedReadHalf, OwnedWriteHalf}, + }, + sync::Mutex, +}; + +pub mod config; +pub mod handshake; +pub mod login; +pub mod play; +pub mod status; + +use crate::{ + net::{Client, EncryptionError}, + server::Server, +}; + +pub struct JavaClientPlatform { + /// The packet encoder for outgoing packets. + network_writer: Arc>>>, + /// The packet decoder for incoming packets. + network_reader: Mutex>>, +} + +impl JavaClientPlatform { + pub fn new(tcp_stream: TcpStream) -> Self { + let (read, write) = tcp_stream.into_split(); + Self { + network_writer: Arc::new(Mutex::new(TCPNetworkEncoder::new(BufWriter::new(write)))), + network_reader: Mutex::new(TCPNetworkDecoder::new(BufReader::new(read))), + } + } + pub async fn set_encryption( + &self, + shared_secret: &[u8], // decrypted + ) -> Result<(), EncryptionError> { + let crypt_key: [u8; 16] = shared_secret + .try_into() + .map_err(|_| EncryptionError::SharedWrongLength)?; + self.network_reader.lock().await.set_encryption(&crypt_key); + self.network_writer.lock().await.set_encryption(&crypt_key); + Ok(()) + } + + pub async fn set_compression(&self, compression: CompressionInfo) { + if compression.level > 9 { + log::error!("Invalid compression level! Clients will not be able to read this!"); + } + + self.network_reader + .lock() + .await + .set_compression(compression.threshold as usize); + + self.network_writer + .lock() + .await + .set_compression((compression.threshold as usize, compression.level)); + } + + /// Processes all packets received from the connected client in a loop. + /// + /// This function continuously dequeues packets from the client's packet queue and processes them. + /// Processing involves calling the `handle_packet` function with the server instance and the packet itself. + /// + /// The loop exits when: + /// + /// - The connection is closed (checked before processing each packet). + /// - An error occurs while processing a packet (client is kicked with an error message). + /// + /// # Arguments + /// + /// * `server`: A reference to the `Server` instance. + pub async fn process_packets(&self, client: &Client, server: &Server) { + while !client + .make_player + .load(std::sync::atomic::Ordering::Relaxed) + { + let packet = self.get_packet(client).await; + let Some(packet) = packet else { break }; + + if let Err(error) = Self::handle_packet(client, server, &packet).await { + let text = format!("Error while reading incoming packet {error}"); + log::error!( + "Failed to read incoming packet with id {}: {}", + packet.id, + error + ); + self.kick(client, TextComponent::text(text)).await; + } + } + } + + pub async fn get_packet(&self, client: &Client) -> Option { + let mut network_reader = self.network_reader.lock().await; + tokio::select! { + () = client.await_close_interrupt() => { + log::debug!("Canceling player packet processing"); + None + }, + packet_result = network_reader.get_raw_packet() => { + match packet_result { + Ok(packet) => Some(packet), + Err(err) => { + if !matches!(err, PacketDecodeError::ConnectionClosed) { + log::warn!("Failed to decode packet from client {}: {}", client.id, err); + let text = format!("Error while reading incoming packet {err}"); + self.kick(client, TextComponent::text(text)).await; + } + None + } + } + } + } + } + + pub async fn kick(&self, client: &Client, reason: TextComponent) { + match client.connection_state.load() { + ConnectionState::Login => { + // TextComponent implements Serialize and writes in bytes instead of String, that's the reasib we only use content + client + .send_packet_now(&CLoginDisconnect::new( + &serde_json::to_string(&reason.0).unwrap_or_else(|_| String::new()), + )) + .await; + } + ConnectionState::Config => { + client + .send_packet_now(&CConfigDisconnect::new(&reason.get_text())) + .await; + } + // This way players get kicked when players using client functions (e.g. poll, send_packet) + ConnectionState::Play => client.send_packet_now(&CPlayDisconnect::new(&reason)).await, + _ => { + log::warn!("Can't kick in {:?} State", client.connection_state); + return; + } + } + log::debug!("Closing connection for {}", client.id); + client.close(); + } + + pub async fn send_packet_now(&self, client: &Client, packet: Vec) { + if let Err(err) = self + .network_writer + .lock() + .await + .write_packet(packet.into()) + .await + { + // It is expected that the packet will fail if we are closed + if !client.closed.load(std::sync::atomic::Ordering::Relaxed) { + log::warn!("Failed to send packet to client {}: {}", client.id, err); + // We now need to close the connection to the client since the stream is in an + // unknown state + client.close(); + } + } + } + + pub fn write_packet( + packet: &P, + write: impl Write, + ) -> Result<(), WritingError> { + let mut write = write; + write.write_var_int(&VarInt(P::PACKET_ID))?; + packet.write_packet_data(write) + } + + pub async fn write_packet_data(&self, packet_data: Bytes) -> Result<(), PacketEncodeError> { + self.network_writer + .lock() + .await + .write_packet(packet_data) + .await + } + + /// Handles an incoming packet, routing it to the appropriate handler based on the current connection state. + /// + /// This function takes a `RawPacket` and routes it to the corresponding handler based on the current connection state. + /// It supports the following connection states: + /// + /// - **Handshake:** Handles handshake packets. + /// - **Status:** Handles status request and ping packets. + /// - **Login/Transfer:** Handles login and transfer packets. + /// - **Config:** Handles configuration packets. + /// + /// For the `Play` state, an error is logged as it indicates an invalid state for packet processing. + /// + /// # Arguments + /// + /// * `server`: A reference to the `Server` instance. + /// * `packet`: A mutable reference to the `RawPacket` to be processed. + /// + /// # Returns + /// + /// A `Result` indicating whether the packet was read and handled successfully. + /// + /// # Errors + /// + /// Returns a `DeserializerError` if an error occurs during packet deserialization. + pub async fn handle_packet( + client: &Client, + server: &Server, + packet: &RawPacket, + ) -> Result<(), ReadingError> { + match client.connection_state.load() { + pumpkin_protocol::ConnectionState::HandShake => { + Self::handle_handshake_packet(client, packet).await + } + pumpkin_protocol::ConnectionState::Status => { + Self::handle_status_packet(client, server, packet).await + } + // TODO: Check config if transfer is enabled + pumpkin_protocol::ConnectionState::Login + | pumpkin_protocol::ConnectionState::Transfer => { + Self::handle_login_packet(client, server, packet).await + } + pumpkin_protocol::ConnectionState::Config => { + Self::handle_config_packet(client, server, packet).await + } + pumpkin_protocol::ConnectionState::Play => { + log::error!("Invalid Connection state {:?}", client.connection_state); + Ok(()) + } + } + } + + async fn handle_handshake_packet( + client: &Client, + packet: &RawPacket, + ) -> Result<(), ReadingError> { + log::debug!("Handling handshake group"); + let payload = &packet.payload[..]; + match packet.id { + 0 => { + client.handle_handshake(SHandShake::read(payload)?).await; + } + _ => { + log::error!( + "Failed to handle java packet id {} in Handshake state", + packet.id + ); + } + } + Ok(()) + } + + async fn handle_status_packet( + client: &Client, + server: &Server, + packet: &RawPacket, + ) -> Result<(), ReadingError> { + log::debug!("Handling status group"); + let payload = &packet.payload[..]; + match packet.id { + SStatusRequest::PACKET_ID => { + client.handle_status_request(server).await; + } + SStatusPingRequest::PACKET_ID => { + client + .handle_ping_request(SStatusPingRequest::read(payload)?) + .await; + } + _ => { + log::error!( + "Failed to handle java client packet id {} in Status State", + packet.id + ); + } + } + + Ok(()) + } + + async fn handle_login_packet( + client: &Client, + server: &Server, + packet: &RawPacket, + ) -> Result<(), ReadingError> { + log::debug!("Handling login group for id"); + let payload = &packet.payload[..]; + match packet.id { + SLoginStart::PACKET_ID => { + client + .handle_login_start(server, SLoginStart::read(payload)?) + .await; + } + SEncryptionResponse::PACKET_ID => { + client + .handle_encryption_response(server, SEncryptionResponse::read(payload)?) + .await; + } + SLoginPluginResponse::PACKET_ID => { + client + .handle_plugin_response(SLoginPluginResponse::read(payload)?) + .await; + } + SLoginAcknowledged::PACKET_ID => { + client.handle_login_acknowledged(server).await; + } + SLoginCookieResponse::PACKET_ID => { + client.handle_login_cookie_response(&SLoginCookieResponse::read(payload)?); + } + _ => { + log::error!( + "Failed to handle java client packet id {} in Login State", + packet.id + ); + } + } + Ok(()) + } + + async fn handle_config_packet( + client: &Client, + server: &Server, + packet: &RawPacket, + ) -> Result<(), ReadingError> { + log::debug!("Handling config group"); + let payload = &packet.payload[..]; + match packet.id { + SClientInformationConfig::PACKET_ID => { + client + .handle_client_information_config(SClientInformationConfig::read(payload)?) + .await; + } + SPluginMessage::PACKET_ID => { + client + .handle_plugin_message(SPluginMessage::read(payload)?) + .await; + } + SAcknowledgeFinishConfig::PACKET_ID => { + client.handle_config_acknowledged(server).await; + } + SKnownPacks::PACKET_ID => { + client + .handle_known_packs(server, SKnownPacks::read(payload)?) + .await; + } + SConfigCookieResponse::PACKET_ID => { + client.handle_config_cookie_response(&SConfigCookieResponse::read(payload)?); + } + SConfigResourcePack::PACKET_ID => { + client + .handle_resource_pack_response(SConfigResourcePack::read(payload)?) + .await; + } + _ => { + log::error!( + "Failed to handle java client packet id {} in Config State", + packet.id + ); + } + } + Ok(()) + } +} diff --git a/pumpkin/src/net/packet/play.rs b/pumpkin/src/net/java/play.rs similarity index 98% rename from pumpkin/src/net/packet/play.rs rename to pumpkin/src/net/java/play.rs index 64459c522..554e223c2 100644 --- a/pumpkin/src/net/packet/play.rs +++ b/pumpkin/src/net/java/play.rs @@ -22,14 +22,14 @@ use pumpkin_inventory::equipment_slot::EquipmentSlot; use pumpkin_inventory::player::player_inventory::PlayerInventory; use pumpkin_inventory::screen_handler::ScreenHandler; use pumpkin_macros::send_cancellable; -use pumpkin_protocol::client::play::{ +use pumpkin_protocol::codec::var_int::VarInt; +use pumpkin_protocol::java::client::play::{ Animation, CBlockUpdate, CCommandSuggestions, CEntityAnimation, CEntityPositionSync, CHeadRot, COpenSignEditor, CPingResponse, CPlayerInfoUpdate, CPlayerPosition, CSetSelectedSlot, CSystemChatMessage, CUpdateEntityPos, CUpdateEntityPosRot, CUpdateEntityRot, InitChat, PlayerAction, }; -use pumpkin_protocol::codec::var_int::VarInt; -use pumpkin_protocol::server::play::{ +use pumpkin_protocol::java::server::play::{ Action, ActionType, CommandBlockMode, FLAG_ON_GROUND, SChangeGameMode, SChatCommand, SChatMessage, SChunkBatch, SClientCommand, SClientInformationPlay, SCloseContainer, SCommandSuggestion, SConfirmTeleport, SCookieResponse as SPCookieResponse, SInteract, @@ -641,24 +641,24 @@ impl Player { if let Ok(action) = Action::try_from(command.action.0) { let entity = &self.living_entity.entity; match action { - pumpkin_protocol::server::play::Action::StartSprinting => { + pumpkin_protocol::java::server::play::Action::StartSprinting => { if !entity.sprinting.load(std::sync::atomic::Ordering::Relaxed) { entity.set_sprinting(true).await; } } - pumpkin_protocol::server::play::Action::StopSprinting => { + pumpkin_protocol::java::server::play::Action::StopSprinting => { if entity.sprinting.load(std::sync::atomic::Ordering::Relaxed) { entity.set_sprinting(false).await; } } - pumpkin_protocol::server::play::Action::LeaveBed => self.wake_up().await, + pumpkin_protocol::java::server::play::Action::LeaveBed => self.wake_up().await, - pumpkin_protocol::server::play::Action::StartHorseJump - | pumpkin_protocol::server::play::Action::StopHorseJump - | pumpkin_protocol::server::play::Action::OpenVehicleInventory => { + pumpkin_protocol::java::server::play::Action::StartHorseJump + | pumpkin_protocol::java::server::play::Action::StopHorseJump + | pumpkin_protocol::java::server::play::Action::OpenVehicleInventory => { log::debug!("todo"); } - pumpkin_protocol::server::play::Action::StartFlyingElytra => { + pumpkin_protocol::java::server::play::Action::StartFlyingElytra => { let fall_flying = entity.check_fall_flying(); if entity .fall_flying @@ -902,7 +902,7 @@ impl Player { server .broadcast_packet_all(&CPlayerInfoUpdate::new( 0x02, - &[pumpkin_protocol::client::play::Player { + &[pumpkin_protocol::java::client::play::Player { uuid: self.gameprofile.id, actions: &[PlayerAction::InitializeChat(Some(InitChat { session_id: session.session_id, diff --git a/pumpkin/src/net/packet/status.rs b/pumpkin/src/net/java/status.rs similarity index 83% rename from pumpkin/src/net/packet/status.rs rename to pumpkin/src/net/java/status.rs index 336112fd9..ee30ff416 100644 --- a/pumpkin/src/net/packet/status.rs +++ b/pumpkin/src/net/java/status.rs @@ -1,4 +1,6 @@ -use pumpkin_protocol::{client::status::CPingResponse, server::status::SStatusPingRequest}; +use pumpkin_protocol::{ + java::client::status::CPingResponse, java::server::status::SStatusPingRequest, +}; use crate::{net::Client, server::Server}; diff --git a/pumpkin/src/net/mod.rs b/pumpkin/src/net/mod.rs index 848adbca4..dabb8ee9d 100644 --- a/pumpkin/src/net/mod.rs +++ b/pumpkin/src/net/mod.rs @@ -1,4 +1,5 @@ use std::{ + io::Write, net::SocketAddr, num::NonZeroU8, sync::{ @@ -13,6 +14,7 @@ use crate::{ op_data::OPERATOR_CONFIG, whitelist_data::WHITELIST_CONFIG, }, entity::player::{ChatMode, Hand}, + net::{bedrock::BedrockClientPlatform, java::JavaClientPlatform}, server::Server, }; @@ -20,48 +22,28 @@ use bytes::Bytes; use crossbeam::atomic::AtomicCell; use pumpkin_config::networking::compression::CompressionInfo; use pumpkin_protocol::{ - ClientPacket, ConnectionState, Property, RawPacket, ServerPacket, - client::{config::CConfigDisconnect, login::CLoginDisconnect, play::CPlayDisconnect}, - packet_decoder::{NetworkDecoder, PacketDecodeError}, - packet_encoder::NetworkEncoder, - ser::{ReadingError, packet::Packet}, - server::{ - config::{ - SAcknowledgeFinishConfig, SClientInformationConfig, SConfigCookieResponse, - SConfigResourcePack, SKnownPacks, SPluginMessage, - }, - handshake::SHandShake, - login::{ - SEncryptionResponse, SLoginAcknowledged, SLoginCookieResponse, SLoginPluginResponse, - SLoginStart, - }, - status::{SStatusPingRequest, SStatusRequest}, - }, + ClientPacket, ConnectionState, PacketEncodeError, Property, RawPacket, ser::WritingError, }; use pumpkin_util::{ProfileAction, text::TextComponent}; use serde::Deserialize; use sha1::Digest; use sha2::Sha256; +use tokio::sync::Mutex; use tokio::{ - io::{BufReader, BufWriter}, - net::tcp::OwnedWriteHalf, sync::{ Notify, mpsc::{Receiver, Sender}, }, task::JoinHandle, }; -use tokio::{ - net::{TcpStream, tcp::OwnedReadHalf}, - sync::Mutex, -}; use thiserror::Error; use tokio_util::task::TaskTracker; use uuid::Uuid; pub mod authentication; +pub mod bedrock; +pub mod java; pub mod lan_broadcast; -mod packet; mod proxy; pub mod query; pub mod rcon; @@ -150,12 +132,9 @@ pub struct Client { pub address: Mutex, /// Indicates if the client is added to the server listing. pub added_to_server_listing: AtomicBool, - /// The packet encoder for outgoing packets. - network_writer: Arc>>>, - /// The packet decoder for incoming packets. - network_reader: Mutex>>, /// Indicates whether the client should be converted into a player. pub make_player: AtomicBool, + pub platform: Arc, /// A collection of tasks associated with this client. The tasks await completion when removing the client. tasks: TaskTracker, /// An notifier that is triggered when this client is closed. @@ -166,10 +145,72 @@ pub struct Client { outgoing_packet_queue_recv: Option>, } +pub enum ClientPlatform { + Java(JavaClientPlatform), + Bedrock(BedrockClientPlatform), +} + +impl ClientPlatform { + pub async fn write_packet_data(&self, packet_data: Bytes) -> Result<(), PacketEncodeError> { + match self { + Self::Java(java) => java.write_packet_data(packet_data).await, + Self::Bedrock(bedrock) => bedrock.write_packet_data(packet_data).await, + } + } + + pub fn write_packet( + &self, + packet: &P, + write: impl Write, + ) -> Result<(), WritingError> { + match self { + Self::Java(_) => JavaClientPlatform::write_packet(packet, write), + Self::Bedrock(_) => BedrockClientPlatform::write_packet(packet, write), + } + } + + pub async fn send_packet_now(&self, client: &Client, packet: Vec) { + match self { + Self::Java(java) => java.send_packet_now(client, packet).await, + Self::Bedrock(bedrock) => bedrock.send_packet_now(client, packet).await, + } + } + + pub async fn kick(&self, client: &Client, reason: TextComponent) { + match self { + Self::Java(java) => java.kick(client, reason).await, + Self::Bedrock(_bedrock) => todo!(), + } + } + + pub async fn set_encryption( + &self, + shared_secret: &[u8], // decrypted + ) -> Result<(), EncryptionError> { + match self { + Self::Java(java) => java.set_encryption(shared_secret).await, + Self::Bedrock(_bedrock) => todo!(), + } + } + + pub async fn set_compression(&self, compression: CompressionInfo) { + match self { + Self::Java(java) => java.set_compression(compression).await, + Self::Bedrock(_bedrock_client_platform) => todo!(), + } + } + + pub async fn get_packet(&self, client: &Client) -> Option { + match self { + Self::Java(java) => java.get_packet(client).await, + Self::Bedrock(_bedrock) => todo!(), + } + } +} + impl Client { #[must_use] - pub fn new(tcp_stream: TcpStream, address: SocketAddr, id: u64) -> Self { - let (read, write) = tcp_stream.into_split(); + pub fn new(platform: ClientPlatform, address: SocketAddr, id: u64) -> Self { let (send, recv) = tokio::sync::mpsc::channel(128); Self { id, @@ -179,9 +220,8 @@ impl Client { brand: Mutex::new(None), server_address: Mutex::new(String::new()), address: Mutex::new(address), + platform: Arc::new(platform), connection_state: AtomicCell::new(ConnectionState::HandShake), - network_writer: Arc::new(Mutex::new(NetworkEncoder::new(BufWriter::new(write)))), - network_reader: Mutex::new(NetworkDecoder::new(BufReader::new(read))), closed: Arc::new(AtomicBool::new(false)), make_player: AtomicBool::new(false), close_interrupt: Arc::new(Notify::new()), @@ -201,9 +241,9 @@ impl Client { .outgoing_packet_queue_recv .take() .expect("This was set in the new fn"); - let writer = self.network_writer.clone(); let close_interrupt = self.close_interrupt.clone(); let closed = self.closed.clone(); + let platform = self.platform.clone(); let id = self.id; self.spawn_task(async move { while !closed.load(std::sync::atomic::Ordering::Relaxed) { @@ -220,7 +260,7 @@ impl Client { break; }; - if let Err(err) = writer.lock().await.write_packet(packet_data).await { + if let Err(err) = platform.write_packet_data(packet_data).await { // It is expected that the packet will fail if we are closed if !closed.load(std::sync::atomic::Ordering::Relaxed) { log::warn!("Failed to send packet to client {id}: {err}",); @@ -290,12 +330,7 @@ impl Client { &self, shared_secret: &[u8], // decrypted ) -> Result<(), EncryptionError> { - let crypt_key: [u8; 16] = shared_secret - .try_into() - .map_err(|_| EncryptionError::SharedWrongLength)?; - self.network_reader.lock().await.set_encryption(&crypt_key); - self.network_writer.lock().await.set_encryption(&crypt_key); - Ok(()) + self.platform.set_encryption(shared_secret).await } /// Enables packet compression for the connection. @@ -307,43 +342,12 @@ impl Client { /// /// * `compression`: A `CompressionInfo` struct containing the compression threshold and compression level. pub async fn set_compression(&self, compression: CompressionInfo) { - if compression.level > 9 { - log::error!("Invalid compression level! Clients will not be able to read this!"); - } - - self.network_reader - .lock() - .await - .set_compression(compression.threshold as usize); - - self.network_writer - .lock() - .await - .set_compression((compression.threshold as usize, compression.level)); + self.platform.set_compression(compression).await; } /// Gets the next packet from the network or `None` if the connection has closed pub async fn get_packet(&self) -> Option { - let mut network_reader = self.network_reader.lock().await; - tokio::select! { - () = self.await_close_interrupt() => { - log::debug!("Canceling player packet processing"); - None - }, - packet_result = network_reader.get_raw_packet() => { - match packet_result { - Ok(packet) => Some(packet), - Err(err) => { - if !matches!(err, PacketDecodeError::ConnectionClosed) { - log::warn!("Failed to decode packet from client {}: {}", self.id, err); - let text = format!("Error while reading incoming packet {err}"); - self.kick(TextComponent::text(text)).await; - } - None - } - } - } - } + self.platform.get_packet(self).await } /// Queues a clientbound packet to be sent to the connected client. Queued chunks are sent @@ -356,12 +360,10 @@ impl Client { where P: ClientPacket, { - let mut packet_buf = Vec::new(); - if let Err(err) = packet.write(&mut packet_buf) { - log::error!("Failed to serialize packet {}: {}", P::PACKET_ID, err); - return; - } - self.enqueue_packet_data(packet_buf.into()).await; + let mut buf = Vec::new(); + let writer = &mut buf; + self.platform.write_packet(packet, writer).unwrap(); + self.enqueue_packet_data(buf.into()).await; } pub async fn enqueue_packet_data(&self, packet_data: Bytes) { @@ -394,226 +396,9 @@ impl Client { /// Returns an `PacketError` if the packet could not be Send. pub async fn send_packet_now(&self, packet: &P) { let mut packet_buf = Vec::new(); - if let Err(err) = packet.write(&mut packet_buf) { - log::error!("Failed to serialize packet {}: {}", P::PACKET_ID, err); - return; - } - - if let Err(err) = self - .network_writer - .lock() - .await - .write_packet(packet_buf.into()) - .await - { - // It is expected that the packet will fail if we are closed - if !self.closed.load(std::sync::atomic::Ordering::Relaxed) { - log::warn!("Failed to send packet to client {}: {}", self.id, err); - // We now need to close the connection to the client since the stream is in an - // unknown state - self.close(); - } - } - } - - /// Processes all packets received from the connected client in a loop. - /// - /// This function continuously dequeues packets from the client's packet queue and processes them. - /// Processing involves calling the `handle_packet` function with the server instance and the packet itself. - /// - /// The loop exits when: - /// - /// - The connection is closed (checked before processing each packet). - /// - An error occurs while processing a packet (client is kicked with an error message). - /// - /// # Arguments - /// - /// * `server`: A reference to the `Server` instance. - pub async fn process_packets(&self, server: &Server) { - while !self.make_player.load(std::sync::atomic::Ordering::Relaxed) { - let packet = self.get_packet().await; - let Some(packet) = packet else { break }; - - if let Err(error) = self.handle_packet(server, &packet).await { - let text = format!("Error while reading incoming packet {error}"); - log::error!( - "Failed to read incoming packet with id {}: {}", - packet.id, - error - ); - self.kick(TextComponent::text(text)).await; - } - } - } - - /// Handles an incoming packet, routing it to the appropriate handler based on the current connection state. - /// - /// This function takes a `RawPacket` and routes it to the corresponding handler based on the current connection state. - /// It supports the following connection states: - /// - /// - **Handshake:** Handles handshake packets. - /// - **Status:** Handles status request and ping packets. - /// - **Login/Transfer:** Handles login and transfer packets. - /// - **Config:** Handles configuration packets. - /// - /// For the `Play` state, an error is logged as it indicates an invalid state for packet processing. - /// - /// # Arguments - /// - /// * `server`: A reference to the `Server` instance. - /// * `packet`: A mutable reference to the `RawPacket` to be processed. - /// - /// # Returns - /// - /// A `Result` indicating whether the packet was read and handled successfully. - /// - /// # Errors - /// - /// Returns a `DeserializerError` if an error occurs during packet deserialization. - pub async fn handle_packet( - &self, - server: &Server, - packet: &RawPacket, - ) -> Result<(), ReadingError> { - match self.connection_state.load() { - pumpkin_protocol::ConnectionState::HandShake => { - self.handle_handshake_packet(packet).await - } - pumpkin_protocol::ConnectionState::Status => { - self.handle_status_packet(server, packet).await - } - // TODO: Check config if transfer is enabled - pumpkin_protocol::ConnectionState::Login - | pumpkin_protocol::ConnectionState::Transfer => { - self.handle_login_packet(server, packet).await - } - pumpkin_protocol::ConnectionState::Config => { - self.handle_config_packet(server, packet).await - } - pumpkin_protocol::ConnectionState::Play => { - log::error!("Invalid Connection state {:?}", self.connection_state); - Ok(()) - } - } - } - - async fn handle_handshake_packet(&self, packet: &RawPacket) -> Result<(), ReadingError> { - log::debug!("Handling handshake group"); - let payload = &packet.payload[..]; - match packet.id { - 0 => { - self.handle_handshake(SHandShake::read(payload)?).await; - } - _ => { - log::error!( - "Failed to handle packet id {} in Handshake state", - packet.id - ); - } - } - Ok(()) - } - - async fn handle_status_packet( - &self, - server: &Server, - packet: &RawPacket, - ) -> Result<(), ReadingError> { - log::debug!("Handling status group"); - let payload = &packet.payload[..]; - match packet.id { - SStatusRequest::PACKET_ID => { - self.handle_status_request(server).await; - } - SStatusPingRequest::PACKET_ID => { - self.handle_ping_request(SStatusPingRequest::read(payload)?) - .await; - } - _ => { - log::error!( - "Failed to handle client packet id {} in Status State", - packet.id - ); - } - } - - Ok(()) - } - - async fn handle_login_packet( - &self, - server: &Server, - packet: &RawPacket, - ) -> Result<(), ReadingError> { - log::debug!("Handling login group for id"); - let payload = &packet.payload[..]; - match packet.id { - SLoginStart::PACKET_ID => { - self.handle_login_start(server, SLoginStart::read(payload)?) - .await; - } - SEncryptionResponse::PACKET_ID => { - self.handle_encryption_response(server, SEncryptionResponse::read(payload)?) - .await; - } - SLoginPluginResponse::PACKET_ID => { - self.handle_plugin_response(SLoginPluginResponse::read(payload)?) - .await; - } - SLoginAcknowledged::PACKET_ID => { - self.handle_login_acknowledged(server).await; - } - SLoginCookieResponse::PACKET_ID => { - self.handle_login_cookie_response(&SLoginCookieResponse::read(payload)?); - } - _ => { - log::error!( - "Failed to handle client packet id {} in Login State", - packet.id - ); - } - } - Ok(()) - } - - async fn handle_config_packet( - &self, - server: &Server, - packet: &RawPacket, - ) -> Result<(), ReadingError> { - log::debug!("Handling config group"); - let payload = &packet.payload[..]; - match packet.id { - SClientInformationConfig::PACKET_ID => { - self.handle_client_information_config(SClientInformationConfig::read(payload)?) - .await; - } - SPluginMessage::PACKET_ID => { - self.handle_plugin_message(SPluginMessage::read(payload)?) - .await; - } - SAcknowledgeFinishConfig::PACKET_ID => { - self.handle_config_acknowledged(server).await; - } - SKnownPacks::PACKET_ID => { - self.handle_known_packs(server, SKnownPacks::read(payload)?) - .await; - } - SConfigCookieResponse::PACKET_ID => { - self.handle_config_cookie_response(&SConfigCookieResponse::read(payload)?); - } - SConfigResourcePack::PACKET_ID => { - self.handle_resource_pack_response(SConfigResourcePack::read(payload)?) - .await; - } - _ => { - log::error!( - "Failed to handle client packet id {} in Config State", - packet.id - ); - } - } - Ok(()) + let writer = &mut packet_buf; + self.platform.write_packet(packet, writer).unwrap(); + self.platform.send_packet_now(self, packet_buf).await; } /// Disconnects a client from the server with a specified reason. @@ -624,27 +409,7 @@ impl Client { /// /// * `reason`: A string describing the reason for kicking the client. pub async fn kick(&self, reason: TextComponent) { - match self.connection_state.load() { - ConnectionState::Login => { - // TextComponent implements Serialize and writes in bytes instead of String, that's the reasib we only use content - self.send_packet_now(&CLoginDisconnect::new( - &serde_json::to_string(&reason.0).unwrap_or_else(|_| String::new()), - )) - .await; - } - ConnectionState::Config => { - self.send_packet_now(&CConfigDisconnect::new(&reason.get_text())) - .await; - } - // This way players get kicked when players using client functions (e.g. poll, send_packet) - ConnectionState::Play => self.send_packet_now(&CPlayDisconnect::new(&reason)).await, - _ => { - log::warn!("Can't kick in {:?} State", self.connection_state); - return; - } - } - log::debug!("Closing connection for {}", self.id); - self.close(); + self.platform.kick(self, reason).await; } /// Checks if the client can join the server. @@ -734,3 +499,7 @@ pub enum EncryptionError { #[error("shared secret has the wrong length")] SharedWrongLength, } + +fn is_valid_player_name(name: &str) -> bool { + name.len() <= 16 && name.chars().all(|c| c > 32u8 as char && c < 127u8 as char) +} diff --git a/pumpkin/src/net/packet/mod.rs b/pumpkin/src/net/packet/mod.rs deleted file mode 100644 index 0dbc697d1..000000000 --- a/pumpkin/src/net/packet/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -mod config; -mod handshake; -mod login; -mod play; -mod status; - -fn is_valid_player_name(name: &str) -> bool { - name.len() <= 16 && name.chars().all(|c| c > 32u8 as char && c < 127u8 as char) -} diff --git a/pumpkin/src/net/proxy/velocity.rs b/pumpkin/src/net/proxy/velocity.rs index be2e26a03..69f57982e 100644 --- a/pumpkin/src/net/proxy/velocity.rs +++ b/pumpkin/src/net/proxy/velocity.rs @@ -10,8 +10,8 @@ use bytes::{BufMut, BytesMut}; use hmac::{Hmac, KeyInit, Mac}; use pumpkin_config::networking::proxy::VelocityConfig; use pumpkin_protocol::{ - Property, client::login::CLoginPluginRequest, ser::NetworkReadExt, - server::login::SLoginPluginResponse, + Property, java::client::login::CLoginPluginRequest, java::server::login::SLoginPluginResponse, + ser::NetworkReadExt, }; use rand::Rng; use sha2::Sha256; diff --git a/pumpkin/src/net/query.rs b/pumpkin/src/net/query.rs index 781104c56..283b095cd 100644 --- a/pumpkin/src/net/query.rs +++ b/pumpkin/src/net/query.rs @@ -6,7 +6,7 @@ use std::{ time::Duration, }; -use pumpkin_config::{BASIC_CONFIG, advanced_config}; +use pumpkin_config::BASIC_CONFIG; use pumpkin_protocol::query::{ CBasicStatus, CFullStatus, CHandshake, PacketType, RawQueryPacket, SHandshake, SStatusRequest, }; @@ -18,12 +18,7 @@ use crate::{ server::{CURRENT_MC_VERSION, Server}, }; -pub async fn start_query_handler(server: Arc, bound_addr: SocketAddr) { - let mut query_addr = bound_addr; - if let Some(port) = advanced_config().networking.query.port { - query_addr.set_port(port); - } - +pub async fn start_query_handler(server: Arc, query_addr: SocketAddr) { let socket = Arc::new( UdpSocket::bind(query_addr) .await @@ -64,7 +59,7 @@ pub async fn start_query_handler(server: Arc, bound_addr: SocketAddr) { server, socket, addr, - bound_addr, + query_addr, ) .await { diff --git a/pumpkin/src/server/connection_cache.rs b/pumpkin/src/server/connection_cache.rs index f28e79697..b90d12fa9 100644 --- a/pumpkin/src/server/connection_cache.rs +++ b/pumpkin/src/server/connection_cache.rs @@ -6,8 +6,8 @@ use pumpkin_config::{BASIC_CONFIG, BasicConfiguration}; use pumpkin_data::packet::CURRENT_MC_PROTOCOL; use pumpkin_protocol::{ Players, StatusResponse, Version, - client::{config::CPluginMessage, status::CStatusResponse}, codec::var_int::VarInt, + java::client::{config::CPluginMessage, status::CStatusResponse}, }; use std::sync::atomic::Ordering; use std::{ diff --git a/pumpkin/src/server/key_store.rs b/pumpkin/src/server/key_store.rs index 215b03c65..5fe67446e 100644 --- a/pumpkin/src/server/key_store.rs +++ b/pumpkin/src/server/key_store.rs @@ -1,5 +1,5 @@ use num_bigint::BigInt; -use pumpkin_protocol::client::login::CEncryptionRequest; +use pumpkin_protocol::java::client::login::CEncryptionRequest; use rsa::{Pkcs1v15Encrypt, RsaPrivateKey, traits::PublicKeyParts as _}; use sha1::Sha1; use sha2::Digest; diff --git a/pumpkin/src/server/mod.rs b/pumpkin/src/server/mod.rs index a963f651f..fab8f7781 100644 --- a/pumpkin/src/server/mod.rs +++ b/pumpkin/src/server/mod.rs @@ -12,17 +12,16 @@ use crate::world::custom_bossbar::CustomBossbars; use crate::{ command::dispatcher::CommandDispatcher, entity::player::Player, net::Client, world::World, }; -use bytes::Bytes; use connection_cache::{CachedBranding, CachedStatus}; use key_store::KeyStore; use pumpkin_config::{BASIC_CONFIG, advanced_config}; use pumpkin_inventory::screen_handler::InventoryPlayer; use pumpkin_macros::send_cancellable; -use pumpkin_protocol::client::login::CEncryptionRequest; -use pumpkin_protocol::client::play::CChangeDifficulty; -use pumpkin_protocol::client::play::CSetSelectedSlot; -use pumpkin_protocol::{ClientPacket, client::config::CPluginMessage}; +use pumpkin_protocol::java::client::login::CEncryptionRequest; +use pumpkin_protocol::java::client::play::CChangeDifficulty; +use pumpkin_protocol::java::client::play::CSetSelectedSlot; +use pumpkin_protocol::{ClientPacket, java::client::config::CPluginMessage}; use pumpkin_registry::{Registry, VanillaDimensionType}; use pumpkin_util::Difficulty; use pumpkin_util::math::vector2::Vector2; @@ -99,6 +98,8 @@ pub struct Server { pub aggregated_tick_times_nanos: AtomicI64, /// Total number of ticks processed by the server pub tick_count: AtomicI32, + /// Random unique Server ID used by Bedrock Edition + pub server_guid: u64, tasks: TaskTracker, // world stuff which maybe should be put into a struct @@ -214,6 +215,7 @@ impl Server { aggregated_tick_times_nanos: AtomicI64::new(0), tick_count: AtomicI32::new(0), tasks: TaskTracker::new(), + server_guid: rand::random(), mojang_public_keys: Mutex::new(Vec::new()), world_info_writer: Arc::new(AnvilLevelInfo), level_info: Arc::new(RwLock::new(level_info)), @@ -397,17 +399,10 @@ impl Server { where P: ClientPacket, { - let mut packet_buf = Vec::new(); - if let Err(err) = packet.write(&mut packet_buf) { - log::error!("Failed to serialize packet {}: {}", P::PACKET_ID, err); - return; - } - let packet_data: Bytes = packet_buf.into(); - for world in self.worlds.read().await.iter() { let current_players = world.players.read().await; for player in current_players.values() { - player.client.enqueue_packet_data(packet_data.clone()).await; + player.client.enqueue_packet(packet).await; } } } diff --git a/pumpkin/src/server/tick_rate_manager.rs b/pumpkin/src/server/tick_rate_manager.rs index dd1d1ad7b..40b9d15fd 100644 --- a/pumpkin/src/server/tick_rate_manager.rs +++ b/pumpkin/src/server/tick_rate_manager.rs @@ -3,7 +3,7 @@ use std::time::Instant; use crossbeam::atomic::AtomicCell; use pumpkin_config::BASIC_CONFIG; -use pumpkin_protocol::client::play::{CSystemChatMessage, CTickingState, CTickingStep}; +use pumpkin_protocol::java::client::play::{CSystemChatMessage, CTickingState, CTickingStep}; use pumpkin_util::text::{TextComponent, color::NamedColor}; use crate::entity::player::Player; diff --git a/pumpkin/src/world/border.rs b/pumpkin/src/world/border.rs index cfac41051..39e34143b 100644 --- a/pumpkin/src/world/border.rs +++ b/pumpkin/src/world/border.rs @@ -1,4 +1,4 @@ -use pumpkin_protocol::client::play::{ +use pumpkin_protocol::java::client::play::{ CInitializeWorldBorder, CSetBorderCenter, CSetBorderLerpSize, CSetBorderSize, CSetBorderWarningDelay, CSetBorderWarningDistance, }; diff --git a/pumpkin/src/world/bossbar.rs b/pumpkin/src/world/bossbar.rs index 1c62aec62..154881f6b 100644 --- a/pumpkin/src/world/bossbar.rs +++ b/pumpkin/src/world/bossbar.rs @@ -1,5 +1,5 @@ use crate::entity::player::Player; -use pumpkin_protocol::client::play::{BosseventAction, CBossEvent}; +use pumpkin_protocol::java::client::play::{BosseventAction, CBossEvent}; use pumpkin_util::text::TextComponent; use uuid::Uuid; diff --git a/pumpkin/src/world/chunker.rs b/pumpkin/src/world/chunker.rs index 26d63cbd0..05cbf0f05 100644 --- a/pumpkin/src/world/chunker.rs +++ b/pumpkin/src/world/chunker.rs @@ -1,7 +1,7 @@ use std::{num::NonZeroU8, sync::Arc}; use pumpkin_config::BASIC_CONFIG; -use pumpkin_protocol::client::play::{CCenterChunk, CUnloadChunk}; +use pumpkin_protocol::java::client::play::{CCenterChunk, CUnloadChunk}; use pumpkin_world::cylindrical_chunk_iterator::Cylindrical; use crate::entity::player::Player; diff --git a/pumpkin/src/world/mod.rs b/pumpkin/src/world/mod.rs index 008ba091d..a4012c45a 100644 --- a/pumpkin/src/world/mod.rs +++ b/pumpkin/src/world/mod.rs @@ -27,7 +27,7 @@ use crate::{ }; use async_trait::async_trait; use border::Worldborder; -use bytes::{BufMut, Bytes}; +use bytes::BufMut; use explosion::Explosion; use pumpkin_config::BasicConfiguration; use pumpkin_data::BlockDirection; @@ -50,25 +50,25 @@ use pumpkin_nbt::{compound::NbtCompound, to_bytes_unnamed}; use pumpkin_protocol::ser::serializer::Serializer; use pumpkin_protocol::{ ClientPacket, IdOr, SoundEvent, - client::play::{ + java::client::play::{ CBlockEntityData, CEntityStatus, CGameEvent, CLogin, CMultiBlockUpdate, CPlayerChatMessage, CPlayerInfoUpdate, CRemoveEntities, CRemovePlayerInfo, CSoundEffect, CSpawnEntity, FilterType, GameEvent, InitChat, PlayerAction, PlayerInfoFlags, }, - server::play::SChatMessage, + java::server::play::SChatMessage, }; use pumpkin_protocol::{ - client::play::{ + codec::item_stack_seralizer::ItemStackSerializer, + java::client::play::{ CBlockEvent, CRemoveMobEffect, CSetEntityMetadata, CSetEquipment, MetaDataType, Metadata, }, - codec::item_stack_seralizer::ItemStackSerializer, }; use pumpkin_protocol::{ - client::play::{ + codec::var_int::VarInt, + java::client::play::{ CBlockUpdate, CDisguisedChatMessage, CExplosion, CRespawn, CSetBlockDestroyStage, CWorldEvent, }, - codec::var_int::VarInt, }; use pumpkin_registry::VanillaDimensionType; use pumpkin_util::math::{position::chunk_section_from_pos, vector2::Vector2}; @@ -399,15 +399,8 @@ impl World { return; } - let mut packet_buf = Vec::new(); - if let Err(err) = packet.write(&mut packet_buf) { - log::error!("Failed to serialize packet {}: {}", P::PACKET_ID, err); - return; - } - let packet_data: Bytes = packet_buf.into(); - for (_, player) in players { - player.client.enqueue_packet_data(packet_data.clone()).await; + player.client.enqueue_packet(packet).await; } } @@ -761,7 +754,7 @@ impl World { | PlayerInfoFlags::UPDATE_GAME_MODE | PlayerInfoFlags::UPDATE_LISTED) .bits(), - &[pumpkin_protocol::client::play::Player { + &[pumpkin_protocol::java::client::play::Player { uuid: gameprofile.id, actions: &[ PlayerAction::AddPlayer { @@ -814,10 +807,12 @@ impl World { let entries = current_player_data .iter() - .map(|(id, actions)| pumpkin_protocol::client::play::Player { - uuid: **id, - actions, - }) + .map( + |(id, actions)| pumpkin_protocol::java::client::play::Player { + uuid: **id, + actions, + }, + ) .collect::>(); log::debug!("Sending player info to {}", player.gameprofile.name); diff --git a/pumpkin/src/world/scoreboard.rs b/pumpkin/src/world/scoreboard.rs index bfe3b53c3..bac215e56 100644 --- a/pumpkin/src/world/scoreboard.rs +++ b/pumpkin/src/world/scoreboard.rs @@ -3,8 +3,8 @@ use std::collections::HashMap; use pumpkin_data::scoreboard::ScoreboardDisplaySlot; use pumpkin_protocol::{ NumberFormat, - client::play::{CDisplayObjective, CUpdateObjectives, CUpdateScore, RenderType}, codec::var_int::VarInt, + java::client::play::{CDisplayObjective, CUpdateObjectives, CUpdateScore, RenderType}, }; use pumpkin_util::text::TextComponent; @@ -36,7 +36,7 @@ impl Scoreboard { world .broadcast_packet_all(&CUpdateObjectives::new( objective.name.to_string(), - pumpkin_protocol::client::play::Mode::Add, + pumpkin_protocol::java::client::play::Mode::Add, objective.display_name, objective.render_type, objective.number_format, diff --git a/pumpkin/src/world/time.rs b/pumpkin/src/world/time.rs index deefd0ab4..4f63baa05 100644 --- a/pumpkin/src/world/time.rs +++ b/pumpkin/src/world/time.rs @@ -1,4 +1,4 @@ -use pumpkin_protocol::client::play::CUpdateTime; +use pumpkin_protocol::java::client::play::CUpdateTime; use super::World; diff --git a/pumpkin/src/world/weather.rs b/pumpkin/src/world/weather.rs index a1a8bd6c0..0e450df22 100644 --- a/pumpkin/src/world/weather.rs +++ b/pumpkin/src/world/weather.rs @@ -1,5 +1,5 @@ use super::World; -use pumpkin_protocol::client::play::{CGameEvent, GameEvent}; +use pumpkin_protocol::java::client::play::{CGameEvent, GameEvent}; use rand::Rng; // Weather timing constants