From fd9344a512db8a9b9c27c8f73d867f6bb6eb8df0 Mon Sep 17 00:00:00 2001 From: Snowiiii Date: Fri, 2 Aug 2024 10:57:38 +0200 Subject: [PATCH] reorganize into different crates Should help to get a more clear view and simplify things --- Cargo.lock | 32 +++++++++-- Cargo.toml | 3 +- pumpkin-protocol/Cargo.toml | 20 +++++++ pumpkin-protocol/README.md | 32 +++++++++++ .../src}/bytebuf/mod.rs | 2 +- .../src}/client/config/mod.rs | 8 +-- .../src}/client/login/mod.rs | 2 +- .../src}/client/mod.rs | 0 .../src}/client/play/mod.rs | 17 +++--- .../src}/client/status/mod.rs | 2 +- .../mod.rs => pumpkin-protocol/src/lib.rs | 32 ++++++++++- .../src}/packet_decoder.rs | 3 +- .../src}/packet_encoder.rs | 6 +- .../src}/server/config/mod.rs | 31 +++++----- .../src}/server/handshake/mod.rs | 8 +-- .../src}/server/login/mod.rs | 26 ++++----- .../src}/server/mod.rs | 0 .../src}/server/play/mod.rs | 0 pumpkin-protocol/src/server/status/mod.rs | 27 +++++++++ pumpkin-registry/Cargo.toml | 13 +++++ pumpkin-registry/README.md | 5 ++ .../src}/biomes.rs | 3 +- .../src}/chat_type.rs | 0 .../src}/damage_type.rs | 0 .../src}/dimensions.rs | 0 .../mod.rs => pumpkin-registry/src/lib.rs | 3 +- .../registry => pumpkin-registry/src}/wolf.rs | 0 pumpkin/Cargo.toml | 16 ++++-- pumpkin/src/client/client_packet.rs | 36 ++++++------ pumpkin/src/client/mod.rs | 57 ++++++------------- pumpkin/src/entity/player.rs | 2 +- pumpkin/src/main.rs | 1 - pumpkin/src/protocol/server/status/mod.rs | 27 --------- pumpkin/src/server.rs | 14 ++--- 34 files changed, 258 insertions(+), 170 deletions(-) create mode 100644 pumpkin-protocol/Cargo.toml create mode 100644 pumpkin-protocol/README.md rename {pumpkin/src/protocol => pumpkin-protocol/src}/bytebuf/mod.rs (99%) rename {pumpkin/src/protocol => pumpkin-protocol/src}/client/config/mod.rs (91%) rename {pumpkin/src/protocol => pumpkin-protocol/src}/client/login/mod.rs (97%) rename {pumpkin/src/protocol => pumpkin-protocol/src}/client/mod.rs (100%) rename {pumpkin/src/protocol => pumpkin-protocol/src}/client/play/mod.rs (92%) rename {pumpkin/src/protocol => pumpkin-protocol/src}/client/status/mod.rs (91%) rename pumpkin/src/protocol/mod.rs => pumpkin-protocol/src/lib.rs (84%) rename {pumpkin/src/client => pumpkin-protocol/src}/packet_decoder.rs (95%) rename {pumpkin/src/client => pumpkin-protocol/src}/packet_encoder.rs (94%) rename {pumpkin/src/protocol => pumpkin-protocol/src}/server/config/mod.rs (54%) rename {pumpkin/src/protocol => pumpkin-protocol/src}/server/handshake/mod.rs (69%) rename {pumpkin/src/protocol => pumpkin-protocol/src}/server/login/mod.rs (69%) rename {pumpkin/src/protocol => pumpkin-protocol/src}/server/mod.rs (100%) rename {pumpkin/src/protocol => pumpkin-protocol/src}/server/play/mod.rs (100%) create mode 100644 pumpkin-protocol/src/server/status/mod.rs create mode 100644 pumpkin-registry/Cargo.toml create mode 100644 pumpkin-registry/README.md rename {pumpkin/src/protocol/registry => pumpkin-registry/src}/biomes.rs (98%) rename {pumpkin/src/protocol/registry => pumpkin-registry/src}/chat_type.rs (100%) rename {pumpkin/src/protocol/registry => pumpkin-registry/src}/damage_type.rs (100%) rename {pumpkin/src/protocol/registry => pumpkin-registry/src}/dimensions.rs (100%) rename pumpkin/src/protocol/registry/mod.rs => pumpkin-registry/src/lib.rs (98%) rename {pumpkin/src/protocol/registry => pumpkin-registry/src}/wolf.rs (100%) delete mode 100644 pumpkin/src/protocol/server/status/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 7b2c8b357..51c859f81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -521,17 +521,14 @@ dependencies = [ name = "pumpkin" version = "0.1.0" dependencies = [ - "aes", "base64", - "bytes", - "cfb8", "crossbeam-channel", - "fastnbt", - "fastsnbt", "flate2", "image", "log", "mio", + "pumpkin-protocol", + "pumpkin-registry", "rand", "rsa", "rsa-der", @@ -543,6 +540,31 @@ dependencies = [ "uuid", ] +[[package]] +name = "pumpkin-protocol" +version = "0.1.0" +dependencies = [ + "aes", + "bytes", + "cfb8", + "log", + "serde", + "serde_json", + "thiserror", + "uuid", +] + +[[package]] +name = "pumpkin-registry" +version = "0.1.0" +dependencies = [ + "fastnbt", + "fastsnbt", + "pumpkin-protocol", + "serde", + "serde_json", +] + [[package]] name = "quote" version = "1.0.36" diff --git a/Cargo.toml b/Cargo.toml index 0897a4616..3dc4b921f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,6 @@ [workspace] resolver = "2" -members = [ - "pumpkin/"] +members = [ "pumpkin-protocol/", "pumpkin-registry/", "pumpkin/"] [workspace.package] version = "0.1.0" diff --git a/pumpkin-protocol/Cargo.toml b/pumpkin-protocol/Cargo.toml new file mode 100644 index 000000000..c58e78d53 --- /dev/null +++ b/pumpkin-protocol/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "pumpkin-protocol" +version.workspace = true +edition.workspace = true + +[dependencies] +bytes = "1.7" + +uuid = "1.10" + +serde = { version = "1.0", features = ["derive"] } +# to parse strings to json responses +serde_json = "1.0" + +thiserror = "1.0.63" +log = "0.4" + +# encryption +aes = "0.8.4" +cfb8 = "0.8.1" \ No newline at end of file diff --git a/pumpkin-protocol/README.md b/pumpkin-protocol/README.md new file mode 100644 index 000000000..aa57731b4 --- /dev/null +++ b/pumpkin-protocol/README.md @@ -0,0 +1,32 @@ +### Pumpkin Protocol +Contains all Serverbound(Client->Server) and Clientbound(Server->Client) Packets. +The packets are sorted by their folder architecture you find: + +Serverbound Packets under: + `server` +Clientbound Packets under: + `client` +Than they both have folders for packets for all their diffrent states: + +### States: +**Handshake**: Always the first packet being send from the Client. This begins also determins the next state, usally to indicate if the player thans perform a Status Request, Join the Server or wants to be transfered. + +**Status**: Indicates the Client wants to see a Status response (MOTD). + +**Login**: The Login sequence. Indicates the Client wants to join to the Server + +**Config**: A sequence of Configuration packets beining mostly send from the Server to the Client. (Features, Resource Pack, Server Links...) + +**Play**: The final state which indicate the Player is now ready to Join in also used to handle all other Gameplay packets. + +### How to add a Packet ? +You can find all Minecraft Java packets at https://wiki.vg/Protocol. There you also can see in which [State](State) they are. +You also can see all the information the Packets has which we can either Write or Read depending if its Serverbound or Clientbound +#### Adding a Serverbound Packet +Serverbound Packets do use the trait `ServerPacket` which has an packet id (use hex) and can read incoming Client packets. +https://wiki.vg/Protocol gives you the Packet structure which you can than read. Feel free to orientate on already existing Packets. +Please use a name structure like `SPacketName` for the struct, The 'S' representing its Serverbound +#### Adding a Clientbound Packet +Clientbound Packets do use the trait `ClientPacket` which has an packet id (use hex) and can write outgoining Server packets. +https://wiki.vg/Protocol gives you the Packet structure which you can than write. Feel free to orientate on already existing Packets. +Please use a name structure like `CPacketName` for the struct, The 'C' representing its Clientbound \ No newline at end of file diff --git a/pumpkin/src/protocol/bytebuf/mod.rs b/pumpkin-protocol/src/bytebuf/mod.rs similarity index 99% rename from pumpkin/src/protocol/bytebuf/mod.rs rename to pumpkin-protocol/src/bytebuf/mod.rs index 0bbb3a1dc..faeed3e91 100644 --- a/pumpkin/src/protocol/bytebuf/mod.rs +++ b/pumpkin-protocol/src/bytebuf/mod.rs @@ -3,7 +3,7 @@ use std::io::{self, Error, ErrorKind}; use bytes::{Buf, BufMut, BytesMut}; -use crate::protocol::{VarInt, VarLong}; +use crate::{VarInt, VarLong}; const SEGMENT_BITS: u8 = 0x7F; const CONTINUE_BIT: u8 = 0x80; diff --git a/pumpkin/src/protocol/client/config/mod.rs b/pumpkin-protocol/src/client/config/mod.rs similarity index 91% rename from pumpkin/src/protocol/client/config/mod.rs rename to pumpkin-protocol/src/client/config/mod.rs index da1335b90..8af787258 100644 --- a/pumpkin/src/protocol/client/config/mod.rs +++ b/pumpkin-protocol/src/client/config/mod.rs @@ -1,11 +1,11 @@ -use crate::protocol::{bytebuf::ByteBuffer, ClientPacket, KnownPack, VarInt}; +use crate::{bytebuf::ByteBuffer, ClientPacket, KnownPack, VarInt}; pub struct CCookieRequest { // TODO } impl ClientPacket for CCookieRequest { - const PACKET_ID: crate::protocol::VarInt = 0x00; + const PACKET_ID: VarInt = 0x00; fn write(&self, bytebuf: &mut ByteBuffer) {} } @@ -41,7 +41,7 @@ impl<'a> CConfigDisconnect<'a> { } impl<'a> ClientPacket for CConfigDisconnect<'a> { - const PACKET_ID: crate::protocol::VarInt = 0x02; + const PACKET_ID: VarInt = 0x02; fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_string(self.reason); @@ -63,7 +63,7 @@ impl CFinishConfig { } impl ClientPacket for CFinishConfig { - const PACKET_ID: crate::protocol::VarInt = 0x03; + const PACKET_ID: VarInt = 0x03; fn write(&self, _bytebuf: &mut ByteBuffer) {} } diff --git a/pumpkin/src/protocol/client/login/mod.rs b/pumpkin-protocol/src/client/login/mod.rs similarity index 97% rename from pumpkin/src/protocol/client/login/mod.rs rename to pumpkin-protocol/src/client/login/mod.rs index cbccab05a..2562d4479 100644 --- a/pumpkin/src/protocol/client/login/mod.rs +++ b/pumpkin-protocol/src/client/login/mod.rs @@ -1,4 +1,4 @@ -use crate::protocol::{bytebuf::ByteBuffer, ClientPacket, VarInt}; +use crate::{bytebuf::ByteBuffer, ClientPacket, VarInt}; pub struct CLoginDisconnect<'a> { reason: &'a str, diff --git a/pumpkin/src/protocol/client/mod.rs b/pumpkin-protocol/src/client/mod.rs similarity index 100% rename from pumpkin/src/protocol/client/mod.rs rename to pumpkin-protocol/src/client/mod.rs diff --git a/pumpkin/src/protocol/client/play/mod.rs b/pumpkin-protocol/src/client/play/mod.rs similarity index 92% rename from pumpkin/src/protocol/client/play/mod.rs rename to pumpkin-protocol/src/client/play/mod.rs index 49f11101e..8f40220cd 100644 --- a/pumpkin/src/protocol/client/play/mod.rs +++ b/pumpkin-protocol/src/client/play/mod.rs @@ -1,7 +1,4 @@ -use crate::{ - entity::player::GameMode, - protocol::{bytebuf::ByteBuffer, ClientPacket, VarInt}, -}; +use crate::{bytebuf::ByteBuffer, ClientPacket, VarInt}; pub struct SetHeldItem { slot: i8, @@ -80,8 +77,8 @@ pub struct CLogin { dimension_type: VarInt, dimension_name: String, hashed_seed: i64, - game_mode: GameMode, - previous_gamemode: GameMode, + game_mode: u8, + previous_gamemode: i8, debug: bool, is_flat: bool, has_death_loc: bool, @@ -107,8 +104,8 @@ impl CLogin { dimension_type: VarInt, dimension_name: String, hashed_seed: i64, - game_mode: GameMode, - previous_gamemode: GameMode, + game_mode: u8, + previous_gamemode: i8, debug: bool, is_flat: bool, has_death_loc: bool, @@ -161,8 +158,8 @@ impl ClientPacket for CLogin { bytebuf.put_var_int(self.dimension_type); bytebuf.put_string(&self.dimension_name); bytebuf.put_i64(self.hashed_seed); - bytebuf.put_u8(self.game_mode.to_byte() as u8); - bytebuf.put_i8(self.previous_gamemode.to_byte()); + bytebuf.put_u8(self.game_mode); + bytebuf.put_i8(self.previous_gamemode); bytebuf.put_bool(self.debug); bytebuf.put_bool(self.is_flat); bytebuf.put_bool(self.has_death_loc); diff --git a/pumpkin/src/protocol/client/status/mod.rs b/pumpkin-protocol/src/client/status/mod.rs similarity index 91% rename from pumpkin/src/protocol/client/status/mod.rs rename to pumpkin-protocol/src/client/status/mod.rs index 414210371..d358e4967 100644 --- a/pumpkin/src/protocol/client/status/mod.rs +++ b/pumpkin-protocol/src/client/status/mod.rs @@ -1,4 +1,4 @@ -use crate::protocol::{bytebuf::ByteBuffer, ClientPacket, VarInt}; +use crate::{bytebuf::ByteBuffer, ClientPacket, VarInt}; pub struct CPingResponse { payload: i64, // must responde with the same as in `SPingRequest` diff --git a/pumpkin/src/protocol/mod.rs b/pumpkin-protocol/src/lib.rs similarity index 84% rename from pumpkin/src/protocol/mod.rs rename to pumpkin-protocol/src/lib.rs index d38597ae3..b87521bb3 100644 --- a/pumpkin/src/protocol/mod.rs +++ b/pumpkin-protocol/src/lib.rs @@ -6,12 +6,16 @@ use serde::Serialize; use thiserror::Error; pub mod bytebuf; -pub mod registry; - pub mod client; pub mod server; +pub mod packet_decoder; +pub mod packet_encoder; + +pub const MAX_PACKET_SIZE: i32 = 2097152; + pub type VarInt = i32; +pub type VarLong = i64; pub struct VarInt32(pub i32); @@ -87,7 +91,23 @@ pub enum VarIntDecodeError { TooLarge, } -pub type VarLong = i64; +#[derive(Error, Debug)] +pub enum PacketError { + #[error("failed to decode packet ID")] + DecodeID, + #[error("failed to encode packet ID")] + EncodeID, + #[error("failed to write encoded packet")] + EncodeFailedWrite, + #[error("failed to write encoded packet to connection")] + ConnectionWrite, + #[error("packet exceeds maximum length")] + TooLong, + #[error("packet length is out of bounds")] + OutOfBounds, + #[error("malformed packet length VarInt")] + MailformedLength, +} #[derive(Debug, PartialEq)] pub enum ConnectionState { @@ -125,6 +145,12 @@ pub trait ClientPacket { fn write(&self, bytebuf: &mut ByteBuffer); } +pub trait ServerPacket { + const PACKET_ID: VarInt; + + fn read(bytebuf: &mut ByteBuffer) -> Self; +} + #[derive(Serialize)] pub struct StatusResponse { pub version: Version, diff --git a/pumpkin/src/client/packet_decoder.rs b/pumpkin-protocol/src/packet_decoder.rs similarity index 95% rename from pumpkin/src/client/packet_decoder.rs rename to pumpkin-protocol/src/packet_decoder.rs index 419665727..17afaab3f 100644 --- a/pumpkin/src/client/packet_decoder.rs +++ b/pumpkin-protocol/src/packet_decoder.rs @@ -2,8 +2,7 @@ use aes::cipher::{generic_array::GenericArray, BlockDecryptMut, BlockSizeUser, K use bytes::{Buf, BytesMut}; use crate::{ - client::{PacketError, MAX_PACKET_SIZE}, - protocol::{bytebuf::ByteBuffer, RawPacket, VarInt32, VarIntDecodeError}, + bytebuf::ByteBuffer, PacketError, RawPacket, VarInt32, VarIntDecodeError, MAX_PACKET_SIZE, }; type Cipher = cfb8::Decryptor; diff --git a/pumpkin/src/client/packet_encoder.rs b/pumpkin-protocol/src/packet_encoder.rs similarity index 94% rename from pumpkin/src/client/packet_encoder.rs rename to pumpkin-protocol/src/packet_encoder.rs index bcda7e755..ac9af376a 100644 --- a/pumpkin/src/client/packet_encoder.rs +++ b/pumpkin-protocol/src/packet_encoder.rs @@ -4,12 +4,10 @@ use aes::cipher::{generic_array::GenericArray, BlockEncryptMut, BlockSizeUser, K use bytes::{BufMut, BytesMut}; use crate::{ - client::MAX_PACKET_SIZE, - protocol::{bytebuf::ByteBuffer, ClientPacket, VarInt32}, + bytebuf::ByteBuffer, ClientPacket, PacketError, VarInt32, + MAX_PACKET_SIZE, }; -use super::PacketError; - type Cipher = cfb8::Encryptor; // Encoder: Server -> Client diff --git a/pumpkin/src/protocol/server/config/mod.rs b/pumpkin-protocol/src/server/config/mod.rs similarity index 54% rename from pumpkin/src/protocol/server/config/mod.rs rename to pumpkin-protocol/src/server/config/mod.rs index a42986825..d137bdf73 100644 --- a/pumpkin/src/protocol/server/config/mod.rs +++ b/pumpkin-protocol/src/server/config/mod.rs @@ -1,30 +1,27 @@ -use crate::{ - entity::player::{ChatMode, Hand}, - protocol::{bytebuf::ByteBuffer, VarInt}, -}; +use crate::{bytebuf::ByteBuffer, ServerPacket, VarInt}; pub struct SClientInformation { pub locale: String, // 16 pub view_distance: i8, - pub chat_mode: ChatMode, // Varint + pub chat_mode: VarInt, // Varint pub chat_colors: bool, pub skin_parts: u8, - pub main_hand: Hand, + pub main_hand: VarInt, pub text_filtering: bool, pub server_listing: bool, } -impl SClientInformation { - pub const PACKET_ID: VarInt = 0x00; +impl ServerPacket for SClientInformation { + const PACKET_ID: VarInt = 0x00; - pub fn read(bytebuf: &mut ByteBuffer) -> Self { + fn read(bytebuf: &mut ByteBuffer) -> Self { Self { locale: bytebuf.get_string_len(16).unwrap(), view_distance: bytebuf.get_i8(), - chat_mode: ChatMode::from_varint(bytebuf.get_var_int()), + chat_mode: bytebuf.get_var_int(), chat_colors: bytebuf.get_bool(), skin_parts: bytebuf.get_u8(), - main_hand: Hand::from_varint(bytebuf.get_var_int()), + main_hand: bytebuf.get_var_int(), text_filtering: bytebuf.get_bool(), server_listing: bytebuf.get_bool(), } @@ -33,10 +30,10 @@ impl SClientInformation { pub struct SAcknowledgeFinishConfig {} -impl SAcknowledgeFinishConfig { - pub const PACKET_ID: VarInt = 0x03; +impl ServerPacket for SAcknowledgeFinishConfig { + const PACKET_ID: VarInt = 0x03; - pub fn read(_bytebuf: &mut ByteBuffer) -> Self { + fn read(_bytebuf: &mut ByteBuffer) -> Self { Self {} } } @@ -46,10 +43,10 @@ pub struct SKnownPacks { // known_packs: &'a [KnownPack] } -impl SKnownPacks { - pub const PACKET_ID: VarInt = 0x07; +impl ServerPacket for SKnownPacks { + const PACKET_ID: VarInt = 0x07; - pub fn read(bytebuf: &mut ByteBuffer) -> Self { + fn read(bytebuf: &mut ByteBuffer) -> Self { Self { known_pack_count: bytebuf.get_var_int(), } diff --git a/pumpkin/src/protocol/server/handshake/mod.rs b/pumpkin-protocol/src/server/handshake/mod.rs similarity index 69% rename from pumpkin/src/protocol/server/handshake/mod.rs rename to pumpkin-protocol/src/server/handshake/mod.rs index b5e0049bc..04c27256b 100644 --- a/pumpkin/src/protocol/server/handshake/mod.rs +++ b/pumpkin-protocol/src/server/handshake/mod.rs @@ -1,4 +1,4 @@ -use crate::protocol::{bytebuf::ByteBuffer, ConnectionState, VarInt}; +use crate::{bytebuf::ByteBuffer, ConnectionState, ServerPacket, VarInt}; pub struct SHandShake { pub protocol_version: VarInt, @@ -7,10 +7,10 @@ pub struct SHandShake { pub next_state: ConnectionState, } -impl SHandShake { - pub const PACKET_ID: VarInt = 0x00; +impl ServerPacket for SHandShake { + const PACKET_ID: VarInt = 0x00; - pub fn read(bytebuf: &mut ByteBuffer) -> Self { + fn read(bytebuf: &mut ByteBuffer) -> Self { Self { protocol_version: bytebuf.get_var_int(), server_address: bytebuf.get_string_len(255).unwrap(), diff --git a/pumpkin/src/protocol/server/login/mod.rs b/pumpkin-protocol/src/server/login/mod.rs similarity index 69% rename from pumpkin/src/protocol/server/login/mod.rs rename to pumpkin-protocol/src/server/login/mod.rs index 561420327..ad6a29e4f 100644 --- a/pumpkin/src/protocol/server/login/mod.rs +++ b/pumpkin-protocol/src/server/login/mod.rs @@ -1,14 +1,14 @@ -use crate::protocol::{bytebuf::ByteBuffer, VarInt}; +use crate::{bytebuf::ByteBuffer, ServerPacket, VarInt}; pub struct SLoginStart { pub name: String, // 16 pub uuid: uuid::Uuid, } -impl SLoginStart { - pub const PACKET_ID: VarInt = 0x00; +impl ServerPacket for SLoginStart { + const PACKET_ID: VarInt = 0x00; - pub fn read(bytebuf: &mut ByteBuffer) -> Self { + fn read(bytebuf: &mut ByteBuffer) -> Self { Self { name: bytebuf.get_string_len(16).unwrap(), uuid: bytebuf.get_uuid(), @@ -23,10 +23,10 @@ pub struct SEncryptionResponse { pub verify_token: Vec, } -impl SEncryptionResponse { - pub const PACKET_ID: VarInt = 0x01; +impl ServerPacket for SEncryptionResponse { + const PACKET_ID: VarInt = 0x01; - pub fn read(bytebuf: &mut ByteBuffer) -> Self { + fn read(bytebuf: &mut ByteBuffer) -> Self { let shared_secret_length = bytebuf.get_var_int(); let shared_secret = bytebuf.copy_to_bytes(shared_secret_length as usize); let verify_token_length = bytebuf.get_var_int(); @@ -46,10 +46,10 @@ pub struct SLoginPluginResponse<'a> { data: Option<&'a [u8]>, } -impl<'a> SLoginPluginResponse<'a> { - pub const PACKET_ID: VarInt = 0x02; +impl<'a> ServerPacket for SLoginPluginResponse<'a> { + const PACKET_ID: VarInt = 0x02; - pub fn read(bytebuf: &mut ByteBuffer) -> Self { + fn read(bytebuf: &mut ByteBuffer) -> Self { Self { message_id: bytebuf.get_var_int(), successful: bytebuf.get_bool(), @@ -63,10 +63,10 @@ pub struct SLoginAcknowledged { // empty } -impl SLoginAcknowledged { - pub const PACKET_ID: VarInt = 0x03; +impl ServerPacket for SLoginAcknowledged { + const PACKET_ID: VarInt = 0x03; - pub fn read(_bytebuf: &mut ByteBuffer) -> Self { + fn read(_bytebuf: &mut ByteBuffer) -> Self { Self {} } } diff --git a/pumpkin/src/protocol/server/mod.rs b/pumpkin-protocol/src/server/mod.rs similarity index 100% rename from pumpkin/src/protocol/server/mod.rs rename to pumpkin-protocol/src/server/mod.rs diff --git a/pumpkin/src/protocol/server/play/mod.rs b/pumpkin-protocol/src/server/play/mod.rs similarity index 100% rename from pumpkin/src/protocol/server/play/mod.rs rename to pumpkin-protocol/src/server/play/mod.rs diff --git a/pumpkin-protocol/src/server/status/mod.rs b/pumpkin-protocol/src/server/status/mod.rs new file mode 100644 index 000000000..da6548ca7 --- /dev/null +++ b/pumpkin-protocol/src/server/status/mod.rs @@ -0,0 +1,27 @@ +use crate::{bytebuf::ByteBuffer, ServerPacket, VarInt}; + +pub struct SStatusRequest { + // empty +} + +impl ServerPacket for SStatusRequest { + const PACKET_ID: VarInt = 0x00; + + fn read(_bytebuf: &mut ByteBuffer) -> Self { + Self {} + } +} + +pub struct SPingRequest { + pub payload: i64, +} + +impl ServerPacket for SPingRequest { + const PACKET_ID: VarInt = 0x01; + + fn read(bytebuf: &mut ByteBuffer) -> Self { + Self { + payload: bytebuf.get_i64(), + } + } +} diff --git a/pumpkin-registry/Cargo.toml b/pumpkin-registry/Cargo.toml new file mode 100644 index 000000000..b86aaf9cd --- /dev/null +++ b/pumpkin-registry/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "pumpkin-registry" +version.workspace = true +edition.workspace = true + +[dependencies] +pumpkin-protocol = { path = "../pumpkin-protocol"} +# nbt +fastnbt = { git = "https://github.com/owengage/fastnbt.git" } +fastsnbt = "0.2" + +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" \ No newline at end of file diff --git a/pumpkin-registry/README.md b/pumpkin-registry/README.md new file mode 100644 index 000000000..2202a5d1f --- /dev/null +++ b/pumpkin-registry/README.md @@ -0,0 +1,5 @@ +### Pumpkin Registry +Here you find all the registry data we have. +Registries are repositories of data that contain entries pertaining to certain aspects of the game, such as the world, the player, among others. +Registery data usally send by the Clientbound Registery data Packet. +A list of Registry entries can be found at https://wiki.vg/Registry_Data \ No newline at end of file diff --git a/pumpkin/src/protocol/registry/biomes.rs b/pumpkin-registry/src/biomes.rs similarity index 98% rename from pumpkin/src/protocol/registry/biomes.rs rename to pumpkin-registry/src/biomes.rs index 351da43e0..f9fb6b030 100644 --- a/pumpkin/src/protocol/registry/biomes.rs +++ b/pumpkin-registry/src/biomes.rs @@ -1,6 +1,5 @@ -use crate::protocol::VarInt; - use super::RegistryValue; +use pumpkin_protocol::VarInt; use serde::Serialize; #[derive(Debug, Clone, Serialize)] diff --git a/pumpkin/src/protocol/registry/chat_type.rs b/pumpkin-registry/src/chat_type.rs similarity index 100% rename from pumpkin/src/protocol/registry/chat_type.rs rename to pumpkin-registry/src/chat_type.rs diff --git a/pumpkin/src/protocol/registry/damage_type.rs b/pumpkin-registry/src/damage_type.rs similarity index 100% rename from pumpkin/src/protocol/registry/damage_type.rs rename to pumpkin-registry/src/damage_type.rs diff --git a/pumpkin/src/protocol/registry/dimensions.rs b/pumpkin-registry/src/dimensions.rs similarity index 100% rename from pumpkin/src/protocol/registry/dimensions.rs rename to pumpkin-registry/src/dimensions.rs diff --git a/pumpkin/src/protocol/registry/mod.rs b/pumpkin-registry/src/lib.rs similarity index 98% rename from pumpkin/src/protocol/registry/mod.rs rename to pumpkin-registry/src/lib.rs index aa5da1251..535b2d475 100644 --- a/pumpkin/src/protocol/registry/mod.rs +++ b/pumpkin-registry/src/lib.rs @@ -1,10 +1,9 @@ use dimensions::Dimension; use fastnbt::SerOpts; +use pumpkin_protocol::bytebuf::ByteBuffer; use serde::Serialize; use wolf::WolfVariant; -use super::bytebuf::ByteBuffer; - mod biomes; mod chat_type; mod damage_type; diff --git a/pumpkin/src/protocol/registry/wolf.rs b/pumpkin-registry/src/wolf.rs similarity index 100% rename from pumpkin/src/protocol/registry/wolf.rs rename to pumpkin-registry/src/wolf.rs diff --git a/pumpkin/Cargo.toml b/pumpkin/Cargo.toml index 1e0d87025..303317867 100644 --- a/pumpkin/Cargo.toml +++ b/pumpkin/Cargo.toml @@ -4,32 +4,36 @@ version = "0.1.0" edition = "2021" [dependencies] +pumpkin-protocol = { path = "../pumpkin-protocol"} +pumpkin-registry = { path = "../pumpkin-registry"} +# config serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" rand = "0.8.5" +# encryption rsa = "0.9.6" rsa-der = "0.3.0" -aes = "0.8.4" -cfb8 = "0.8.1" flate2 = "1.0.30" -bytes = "1.7" thiserror = "1.0.63" +# icon loading base64 = "0.22.1" image = { version = "0.25", default-features = false, features = ["png"]} simple_logger = "5.0.0" log = "0.4" + +# networking mio = { version = "1.0.1", features = ["os-poll", "net"]} crossbeam-channel = "0.5.13" + uuid = "1.10" -toml = "0.8.17" -fastnbt = { git = "https://github.com/owengage/fastnbt.git" } -fastsnbt = "0.2" +toml = "0.8.19" + diff --git a/pumpkin/src/client/client_packet.rs b/pumpkin/src/client/client_packet.rs index 8f347ee98..a7e84a210 100644 --- a/pumpkin/src/client/client_packet.rs +++ b/pumpkin/src/client/client_packet.rs @@ -1,19 +1,21 @@ -use crate::{ - protocol::{ - client::{ - config::{CFinishConfig, CKnownPacks, CRegistryData, Entry}, - login::{CEncryptionRequest, CLoginSuccess}, - status::{CPingResponse, CStatusResponse}, - }, - registry::{DimensionCodec, WolfCodec}, - server::{ - config::{SAcknowledgeFinishConfig, SClientInformation, SKnownPacks}, - handshake::SHandShake, - login::{SEncryptionResponse, SLoginAcknowledged, SLoginPluginResponse, SLoginStart}, - status::{SPingRequest, SStatusRequest}, - }, - ConnectionState, KnownPack, +use pumpkin_protocol::{ + client::{ + config::{CFinishConfig, CKnownPacks, CRegistryData, Entry}, + login::{CEncryptionRequest, CLoginSuccess}, + status::{CPingResponse, CStatusResponse}, }, + server::{ + config::{SAcknowledgeFinishConfig, SClientInformation, SKnownPacks}, + handshake::SHandShake, + login::{SEncryptionResponse, SLoginAcknowledged, SLoginPluginResponse, SLoginStart}, + status::{SPingRequest, SStatusRequest}, + }, + ConnectionState, KnownPack, +}; +use pumpkin_registry::{DimensionCodec, WolfCodec}; + +use crate::{ + entity::player::{ChatMode, Hand}, server::Server, }; @@ -150,10 +152,10 @@ impl ClientPacketProcessor for Client { self.config = Some(PlayerConfig { locale: client_information.locale, view_distance: client_information.view_distance, - chat_mode: client_information.chat_mode, + chat_mode: ChatMode::from_varint(client_information.chat_mode), chat_colors: client_information.chat_colors, skin_parts: client_information.skin_parts, - main_hand: client_information.main_hand, + main_hand: Hand::from_varint(client_information.main_hand), text_filtering: client_information.text_filtering, server_listing: client_information.server_listing, }); diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index 8cad8eb63..7a2bb4e69 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -6,23 +6,23 @@ use std::{ use crate::{ entity::player::{ChatMode, Hand, Player}, - protocol::{ - client::{config::CConfigDisconnect, login::CLoginDisconnect}, - server::{ - config::{SAcknowledgeFinishConfig, SClientInformation, SKnownPacks}, - handshake::SHandShake, - login::{SEncryptionResponse, SLoginAcknowledged, SLoginPluginResponse, SLoginStart}, - status::{SPingRequest, SStatusRequest}, - }, - ClientPacket, RawPacket, - }, server::Server, }; -use crate::protocol::ConnectionState; use mio::{event::Event, net::TcpStream, Token}; -use packet_decoder::PacketDecoder; -use packet_encoder::PacketEncoder; +use pumpkin_protocol::{ + client::{config::CConfigDisconnect, login::CLoginDisconnect}, + packet_decoder::PacketDecoder, + packet_encoder::PacketEncoder, + server::{ + config::{SAcknowledgeFinishConfig, SClientInformation, SKnownPacks}, + handshake::SHandShake, + login::{SEncryptionResponse, SLoginAcknowledged, SLoginPluginResponse, SLoginStart}, + status::{SPingRequest, SStatusRequest}, + }, + ClientPacket, ConnectionState, PacketError, RawPacket, ServerPacket, +}; + use rsa::Pkcs1v15Encrypt; use std::io::Read; use thiserror::Error; @@ -30,13 +30,8 @@ use thiserror::Error; mod client_packet; mod player_packet; -mod packet_decoder; -mod packet_encoder; - use client_packet::ClientPacketProcessor; -pub const MAX_PACKET_SIZE: i32 = 2097152; - pub struct PlayerConfig { locale: String, // 16 view_distance: i8, @@ -133,14 +128,14 @@ impl Client { dbg!("Handling packet"); let bytebuf = &mut packet.bytebuf; match self.connection_state { - crate::protocol::ConnectionState::HandShake => match packet.id { + pumpkin_protocol::ConnectionState::HandShake => match packet.id { SHandShake::PACKET_ID => self.handle_handshake(server, SHandShake::read(bytebuf)), _ => log::error!( "Failed to handle packet id {} while in Handshake state", packet.id ), }, - crate::protocol::ConnectionState::Status => match packet.id { + pumpkin_protocol::ConnectionState::Status => match packet.id { SStatusRequest::PACKET_ID => { self.handle_status_request(server, SStatusRequest::read(bytebuf)) } @@ -152,7 +147,7 @@ impl Client { packet.id ), }, - crate::protocol::ConnectionState::Login => match packet.id { + pumpkin_protocol::ConnectionState::Login => match packet.id { SLoginStart::PACKET_ID => { self.handle_login_start(server, SLoginStart::read(bytebuf)) } @@ -170,7 +165,7 @@ impl Client { packet.id ), }, - crate::protocol::ConnectionState::Config => match packet.id { + pumpkin_protocol::ConnectionState::Config => match packet.id { SClientInformation::PACKET_ID => { self.handle_client_information(server, SClientInformation::read(bytebuf)) } @@ -270,24 +265,6 @@ pub enum EncryptionError { SharedWrongLength, } -#[derive(Error, Debug)] -pub enum PacketError { - #[error("failed to decode packet ID")] - DecodeID, - #[error("failed to encode packet ID")] - EncodeID, - #[error("failed to write encoded packet")] - EncodeFailedWrite, - #[error("failed to write encoded packet to connection")] - ConnectionWrite, - #[error("packet exceeds maximum length")] - TooLong, - #[error("packet length is out of bounds")] - OutOfBounds, - #[error("malformed packet length VarInt")] - MailformedLength, -} - fn would_block(err: &io::Error) -> bool { err.kind() == io::ErrorKind::WouldBlock } diff --git a/pumpkin/src/entity/player.rs b/pumpkin/src/entity/player.rs index 2c3486df3..28ac1f474 100644 --- a/pumpkin/src/entity/player.rs +++ b/pumpkin/src/entity/player.rs @@ -1,4 +1,4 @@ -use crate::protocol::VarInt; +use pumpkin_protocol::VarInt; use super::{Entity, EntityId}; diff --git a/pumpkin/src/main.rs b/pumpkin/src/main.rs index 03f1e02fb..b6c226271 100644 --- a/pumpkin/src/main.rs +++ b/pumpkin/src/main.rs @@ -12,7 +12,6 @@ const SERVER: Token = Token(0); pub mod client; pub mod configuration; pub mod entity; -pub mod protocol; pub mod server; pub mod util; pub mod world; diff --git a/pumpkin/src/protocol/server/status/mod.rs b/pumpkin/src/protocol/server/status/mod.rs deleted file mode 100644 index fa10dcad3..000000000 --- a/pumpkin/src/protocol/server/status/mod.rs +++ /dev/null @@ -1,27 +0,0 @@ -use crate::protocol::{bytebuf::ByteBuffer, VarInt}; - -pub struct SStatusRequest { - // empty -} - -impl SStatusRequest { - pub const PACKET_ID: VarInt = 0x00; - - pub fn read(_bytebuf: &mut ByteBuffer) -> Self { - Self {} - } -} - -pub struct SPingRequest { - pub payload: i64, -} - -impl SPingRequest { - pub const PACKET_ID: VarInt = 0x01; - - pub fn read(bytebuf: &mut ByteBuffer) -> Self { - Self { - payload: bytebuf.get_i64(), - } - } -} diff --git a/pumpkin/src/server.rs b/pumpkin/src/server.rs index cb7235dff..04d855af9 100644 --- a/pumpkin/src/server.rs +++ b/pumpkin/src/server.rs @@ -5,20 +5,20 @@ use std::{ use base64::{engine::general_purpose, Engine}; use mio::{event::Event, Poll}; +use pumpkin_protocol::{ + client::{config::CPluginMessage, play::CLogin}, + PacketError, Players, Sample, StatusResponse, VarInt, VarInt32, Version, +}; use rsa::{rand_core::OsRng, traits::PublicKeyParts, RsaPrivateKey, RsaPublicKey}; use serde::{Deserialize, Serialize}; use crate::{ - client::{Client, PacketError}, + client::Client, configuration::{AdvancedConfiguration, BasicConfiguration}, entity::{ player::{GameMode, Player}, Entity, EntityId, }, - protocol::{ - client::{config::CPluginMessage, play::CLogin}, - Players, Sample, StatusResponse, VarInt, VarInt32, Version, - }, world::World, }; @@ -117,8 +117,8 @@ impl Server { 1, "minecraft:overworld".into(), 0, // seed - GameMode::Survival, - GameMode::Undefined, + GameMode::Survival.to_byte() as u8, + GameMode::Undefined.to_byte(), false, false, false, // deth loc