Begin Refactoring Clientbound Packets to new structure

See https://github.com/Snowiiii/Pumpkin/issues/19 for details
This commit is contained in:
Snowiiii 2024-08-05 23:12:26 +02:00
parent 1e114c008e
commit 9e634295ca
14 changed files with 76 additions and 151 deletions

View File

@ -1,20 +1,15 @@
use pumpkin_macros::packet; use pumpkin_macros::packet;
use serde::Serialize;
use crate::{bytebuf::ByteBuffer, ClientPacket}; #[derive(Serialize)]
#[packet(0x00)] #[packet(0x00)]
pub struct CLoginDisconnect<'a> { pub struct CLoginDisconnect<'a> {
reason: &'a str, json_reason: &'a str,
} }
impl<'a> CLoginDisconnect<'a> { impl<'a> CLoginDisconnect<'a> {
pub fn new(reason: &'a str) -> Self { // input json!
Self { reason } pub fn new(json_reason: &'a str) -> Self {
} Self { json_reason }
}
impl<'a> ClientPacket for CLoginDisconnect<'a> {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_string(&serde_json::to_string_pretty(&self.reason).unwrap());
} }
} }

View File

@ -1,20 +1,16 @@
use pumpkin_macros::packet; use pumpkin_macros::packet;
use serde::Serialize;
use crate::{bytebuf::ByteBuffer, ClientPacket, VarInt}; use crate::VarInt32;
#[derive(Serialize)]
#[packet(0x03)] #[packet(0x03)]
pub struct CSetCompression { pub struct CSetCompression {
threshold: VarInt, threshold: VarInt32,
} }
impl CSetCompression { impl CSetCompression {
pub fn new(threshold: VarInt) -> Self { pub fn new(threshold: VarInt32) -> Self {
Self { threshold } Self { threshold }
} }
} }
impl ClientPacket for CSetCompression {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_var_int(self.threshold);
}
}

View File

@ -1,7 +1,7 @@
use pumpkin_macros::packet; use pumpkin_macros::packet;
use serde::Serialize;
use crate::{bytebuf::ByteBuffer, ClientPacket}; #[derive(Serialize)]
#[packet(0x0B)] #[packet(0x0B)]
pub struct CChangeDifficulty { pub struct CChangeDifficulty {
difficulty: u8, difficulty: u8,
@ -13,10 +13,3 @@ impl CChangeDifficulty {
Self { difficulty, locked } Self { difficulty, locked }
} }
} }
impl ClientPacket for CChangeDifficulty {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_u8(self.difficulty);
bytebuf.put_bool(self.locked);
}
}

View File

@ -1,7 +1,7 @@
use pumpkin_macros::packet; use pumpkin_macros::packet;
use serde::Serialize;
use crate::{bytebuf::ByteBuffer, ClientPacket}; #[derive(Serialize)]
#[packet(0x22)] #[packet(0x22)]
pub struct CGameEvent { pub struct CGameEvent {
event: u8, event: u8,
@ -13,10 +13,3 @@ impl CGameEvent {
Self { event, value } Self { event, value }
} }
} }
impl ClientPacket for CGameEvent {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_u8(self.event);
bytebuf.put_f32(self.value);
}
}

View File

@ -1,7 +1,9 @@
use pumpkin_macros::packet; use pumpkin_macros::packet;
use serde::Serialize;
use crate::{bytebuf::ByteBuffer, text::TextComponent, ClientPacket}; use crate::text::TextComponent;
#[derive(Serialize)]
#[packet(0x1D)] #[packet(0x1D)]
pub struct CPlayDisconnect { pub struct CPlayDisconnect {
reason: TextComponent, reason: TextComponent,
@ -12,9 +14,3 @@ impl CPlayDisconnect {
Self { reason } Self { reason }
} }
} }
impl ClientPacket for CPlayDisconnect {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_slice(&self.reason.encode());
}
}

View File

@ -1,7 +1,7 @@
use pumpkin_macros::packet; use pumpkin_macros::packet;
use serde::Serialize;
use crate::{bytebuf::ByteBuffer, ClientPacket}; #[derive(Serialize)]
#[packet(0x53)] #[packet(0x53)]
pub struct CSetHeldItem { pub struct CSetHeldItem {
slot: i8, slot: i8,
@ -12,9 +12,3 @@ impl CSetHeldItem {
Self { slot } Self { slot }
} }
} }
impl ClientPacket for CSetHeldItem {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i8(self.slot);
}
}

View File

@ -1,7 +1,9 @@
use pumpkin_macros::packet; use pumpkin_macros::packet;
use serde::Serialize;
use crate::{bytebuf::ByteBuffer, ClientPacket, VarInt}; use crate::VarInt32;
#[derive(Serialize)]
#[packet(0x40)] #[packet(0x40)]
pub struct CSyncPlayerPostion { pub struct CSyncPlayerPostion {
x: f64, x: f64,
@ -10,7 +12,7 @@ pub struct CSyncPlayerPostion {
yaw: f32, yaw: f32,
pitch: f32, pitch: f32,
flags: i8, flags: i8,
teleport_id: VarInt, teleport_id: VarInt32,
} }
impl CSyncPlayerPostion { impl CSyncPlayerPostion {
@ -21,7 +23,7 @@ impl CSyncPlayerPostion {
yaw: f32, yaw: f32,
pitch: f32, pitch: f32,
flags: i8, flags: i8,
teleport_id: VarInt, teleport_id: VarInt32,
) -> Self { ) -> Self {
Self { Self {
x, x,
@ -34,15 +36,3 @@ impl CSyncPlayerPostion {
} }
} }
} }
impl ClientPacket for CSyncPlayerPostion {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_f64(self.x);
bytebuf.put_f64(self.y);
bytebuf.put_f64(self.z);
bytebuf.put_f32(self.yaw.to_degrees());
bytebuf.put_f32(self.pitch.to_degrees());
bytebuf.put_i8(self.flags);
bytebuf.put_var_int(self.teleport_id);
}
}

View File

@ -1,7 +1,9 @@
use pumpkin_macros::packet; use pumpkin_macros::packet;
use serde::Serialize;
use crate::{bytebuf::ByteBuffer, text::TextComponent, ClientPacket}; use crate::text::TextComponent;
#[derive(Serialize)]
#[packet(0x6C)] #[packet(0x6C)]
pub struct CSystemChatMessge { pub struct CSystemChatMessge {
content: TextComponent, content: TextComponent,
@ -13,10 +15,3 @@ impl CSystemChatMessge {
Self { content, overlay } Self { content, overlay }
} }
} }
impl ClientPacket for CSystemChatMessge {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_slice(&self.content.encode());
bytebuf.put_bool(self.overlay);
}
}

View File

@ -90,6 +90,12 @@ impl VarInt32 {
} }
} }
impl From<i32> for VarInt32 {
fn from(value: i32) -> Self {
VarInt32(value)
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Error)] #[derive(Copy, Clone, PartialEq, Eq, Debug, Error)]
pub enum VarIntDecodeError { pub enum VarIntDecodeError {
#[error("incomplete VarInt decode")] #[error("incomplete VarInt decode")]

View File

@ -25,65 +25,27 @@ use crate::{
use super::{authentication::auth_digest, Client, EncryptionError, PlayerConfig}; use super::{authentication::auth_digest, Client, EncryptionError, PlayerConfig};
/// Processes incoming Packets from the Client to the Server /// Processes incoming Packets from the Client to the Server
/// Implements the `Client` Packets, So everything before the Play state, then will use the `PlayerPacketProcessor` /// Implements the `Client` Packets
pub trait ClientPacketProcessor { impl Client {
// Handshake pub fn handle_handshake(&mut self, _server: &mut Server, handshake: SHandShake) {
fn handle_handshake(&mut self, server: &mut Server, handshake: SHandShake);
// Status
fn handle_status_request(&mut self, server: &mut Server, status_request: SStatusRequest);
fn handle_ping_request(&mut self, server: &mut Server, ping_request: SPingRequest);
// Login
fn handle_login_start(&mut self, server: &mut Server, login_start: SLoginStart);
fn handle_encryption_response(
&mut self,
server: &mut Server,
encryption_response: SEncryptionResponse,
);
fn handle_plugin_response(
&mut self,
server: &mut Server,
plugin_response: SLoginPluginResponse,
);
fn handle_login_acknowledged(
&mut self,
server: &mut Server,
login_acknowledged: SLoginAcknowledged,
);
// Config
fn handle_client_information(
&mut self,
server: &mut Server,
client_information: SClientInformation,
);
fn handle_plugin_message(&mut self, server: &mut Server, plugin_message: SPluginMessage);
fn handle_known_packs(&mut self, server: &mut Server, config_acknowledged: SKnownPacks);
fn handle_config_acknowledged(
&mut self,
server: &mut Server,
config_acknowledged: SAcknowledgeFinishConfig,
);
}
impl ClientPacketProcessor for Client {
fn handle_handshake(&mut self, _server: &mut Server, handshake: SHandShake) {
// TODO set protocol version and check protocol version // TODO set protocol version and check protocol version
self.connection_state = handshake.next_state; self.connection_state = handshake.next_state;
dbg!("handshake"); dbg!("handshake");
} }
fn handle_status_request(&mut self, server: &mut Server, _status_request: SStatusRequest) { pub fn handle_status_request(&mut self, server: &mut Server, _status_request: SStatusRequest) {
self.send_packet(CStatusResponse::new(&server.status_response_json)) self.send_packet(CStatusResponse::new(&server.status_response_json))
.unwrap_or_else(|e| self.kick(&e.to_string())); .unwrap_or_else(|e| self.kick(&e.to_string()));
} }
fn handle_ping_request(&mut self, _server: &mut Server, ping_request: SPingRequest) { pub fn handle_ping_request(&mut self, _server: &mut Server, ping_request: SPingRequest) {
dbg!("ping"); dbg!("ping");
self.send_packet(CPingResponse::new(ping_request.payload)) self.send_packet(CPingResponse::new(ping_request.payload))
.unwrap_or_else(|e| self.kick(&e.to_string())); .unwrap_or_else(|e| self.kick(&e.to_string()));
self.close(); self.close();
} }
fn handle_login_start(&mut self, server: &mut Server, login_start: SLoginStart) { pub fn handle_login_start(&mut self, server: &mut Server, login_start: SLoginStart) {
dbg!("login start"); dbg!("login start");
// default game profile, when no online mode // default game profile, when no online mode
self.gameprofile = Some(GameProfile { self.gameprofile = Some(GameProfile {
@ -105,7 +67,7 @@ impl ClientPacketProcessor for Client {
.unwrap_or_else(|e| self.kick(&e.to_string())); .unwrap_or_else(|e| self.kick(&e.to_string()));
} }
fn handle_encryption_response( pub fn handle_encryption_response(
&mut self, &mut self,
server: &mut Server, server: &mut Server,
encryption_response: SEncryptionResponse, encryption_response: SEncryptionResponse,
@ -145,14 +107,14 @@ impl ClientPacketProcessor for Client {
} }
} }
fn handle_plugin_response( pub fn handle_plugin_response(
&mut self, &mut self,
_server: &mut Server, _server: &mut Server,
_plugin_response: SLoginPluginResponse, _plugin_response: SLoginPluginResponse,
) { ) {
} }
fn handle_login_acknowledged( pub fn handle_login_acknowledged(
&mut self, &mut self,
server: &mut Server, server: &mut Server,
_login_acknowledged: SLoginAcknowledged, _login_acknowledged: SLoginAcknowledged,
@ -170,7 +132,7 @@ impl ClientPacketProcessor for Client {
.unwrap_or_else(|e| self.kick(&e.to_string())); .unwrap_or_else(|e| self.kick(&e.to_string()));
dbg!("login achnowlaged"); dbg!("login achnowlaged");
} }
fn handle_client_information( pub fn handle_client_information(
&mut self, &mut self,
_server: &mut Server, _server: &mut Server,
client_information: SClientInformation, client_information: SClientInformation,
@ -178,16 +140,16 @@ impl ClientPacketProcessor for Client {
self.config = Some(PlayerConfig { self.config = Some(PlayerConfig {
locale: client_information.locale, locale: client_information.locale,
view_distance: client_information.view_distance, view_distance: client_information.view_distance,
chat_mode: ChatMode::from_varint(client_information.chat_mode), chat_mode: ChatMode::from(client_information.chat_mode),
chat_colors: client_information.chat_colors, chat_colors: client_information.chat_colors,
skin_parts: client_information.skin_parts, skin_parts: client_information.skin_parts,
main_hand: Hand::from_varint(client_information.main_hand), main_hand: Hand::from(client_information.main_hand),
text_filtering: client_information.text_filtering, text_filtering: client_information.text_filtering,
server_listing: client_information.server_listing, server_listing: client_information.server_listing,
}); });
} }
fn handle_plugin_message(&mut self, _server: &mut Server, plugin_message: SPluginMessage) { pub fn handle_plugin_message(&mut self, _server: &mut Server, plugin_message: SPluginMessage) {
if plugin_message.channel.starts_with("minecraft:brand") if plugin_message.channel.starts_with("minecraft:brand")
|| plugin_message.channel.starts_with("MC|Brand") || plugin_message.channel.starts_with("MC|Brand")
{ {
@ -199,7 +161,7 @@ impl ClientPacketProcessor for Client {
} }
} }
fn handle_known_packs(&mut self, _server: &mut Server, _config_acknowledged: SKnownPacks) { pub fn handle_known_packs(&mut self, _server: &mut Server, _config_acknowledged: SKnownPacks) {
for registry in Registry::get_static() { for registry in Registry::get_static() {
self.send_packet(CRegistryData::new( self.send_packet(CRegistryData::new(
&registry.registry_id, &registry.registry_id,
@ -214,7 +176,7 @@ impl ClientPacketProcessor for Client {
.unwrap_or_else(|e| self.kick(&e.to_string())); .unwrap_or_else(|e| self.kick(&e.to_string()));
} }
fn handle_config_acknowledged( pub fn handle_config_acknowledged(
&mut self, &mut self,
server: &mut Server, server: &mut Server,
_config_acknowledged: SAcknowledgeFinishConfig, _config_acknowledged: SAcknowledgeFinishConfig,

View File

@ -6,7 +6,7 @@ use std::{
}; };
use crate::{ use crate::{
entity::player::{ChatMode, Hand, Player}, entity::player::{ChatMode, GameMode, Hand, Player},
server::Server, server::Server,
}; };
@ -16,7 +16,7 @@ use pumpkin_protocol::{
client::{ client::{
config::CConfigDisconnect, config::CConfigDisconnect,
login::CLoginDisconnect, login::CLoginDisconnect,
play::{CPlayDisconnect, CSyncPlayerPostion, CSystemChatMessge}, play::{CGameEvent, CPlayDisconnect, CSyncPlayerPostion, CSystemChatMessge},
}, },
packet_decoder::PacketDecoder, packet_decoder::PacketDecoder,
packet_encoder::PacketEncoder, packet_encoder::PacketEncoder,
@ -41,8 +41,6 @@ mod authentication;
mod client_packet; mod client_packet;
pub mod player_packet; pub mod player_packet;
use client_packet::ClientPacketProcessor;
pub struct PlayerConfig { pub struct PlayerConfig {
pub locale: String, // 16 pub locale: String, // 16
pub view_distance: i8, pub view_distance: i8,
@ -136,7 +134,12 @@ impl Client {
player.yaw = yaw; player.yaw = yaw;
player.pitch = pitch; player.pitch = pitch;
player.awaiting_teleport = Some(id); player.awaiting_teleport = Some(id);
self.send_packet(CSyncPlayerPostion::new(x, y, z, yaw, pitch, 0, id)) self.send_packet(CSyncPlayerPostion::new(x, y, z, yaw, pitch, 0, id.into()))
.unwrap_or_else(|e| self.kick(&e.to_string()));
}
pub fn set_gamemode(&mut self, gamemode: GameMode) {
self.send_packet(CGameEvent::new(3, gamemode.to_byte() as f32))
.unwrap_or_else(|e| self.kick(&e.to_string())); .unwrap_or_else(|e| self.kick(&e.to_string()));
} }
@ -299,8 +302,10 @@ impl Client {
dbg!(reason); dbg!(reason);
match self.connection_state { match self.connection_state {
ConnectionState::Login => { ConnectionState::Login => {
self.send_packet(CLoginDisconnect::new(reason)) self.send_packet(CLoginDisconnect::new(
.unwrap_or_else(|_| self.close()); &serde_json::to_string_pretty(&reason).unwrap(),
))
.unwrap_or_else(|_| self.close());
} }
ConnectionState::Config => { ConnectionState::Config => {
self.send_packet(CConfigDisconnect::new(reason)) self.send_packet(CConfigDisconnect::new(reason))

View File

@ -9,7 +9,7 @@ use crate::{
use super::Client; use super::Client;
/// Handles all Play Packets send by a real Player
impl Client { impl Client {
pub fn handle_confirm_teleport( pub fn handle_confirm_teleport(
&mut self, &mut self,

View File

@ -2,6 +2,17 @@ use mio::net::TcpListener;
use mio::{Events, Interest, Poll, Token}; use mio::{Events, Interest, Poll, Token};
use std::io::{self}; use std::io::{self};
use client::Client;
use commands::handle_command;
use configuration::AdvancedConfiguration;
use std::{
collections::HashMap,
rc::Rc,
sync::{Arc, Mutex},
thread,
};
use client::interrupted; use client::interrupted;
use configuration::BasicConfiguration; use configuration::BasicConfiguration;
use server::Server; use server::Server;
@ -18,17 +29,6 @@ pub mod util;
#[cfg(not(target_os = "wasi"))] #[cfg(not(target_os = "wasi"))]
fn main() -> io::Result<()> { fn main() -> io::Result<()> {
use std::{
collections::HashMap,
rc::Rc,
sync::{Arc, Mutex},
thread,
};
use client::Client;
use commands::handle_command;
use configuration::AdvancedConfiguration;
let basic_config = BasicConfiguration::load("configuration.toml"); let basic_config = BasicConfiguration::load("configuration.toml");
let advanced_configuration = AdvancedConfiguration::load("features.toml"); let advanced_configuration = AdvancedConfiguration::load("features.toml");

View File

@ -103,11 +103,11 @@ impl Server {
client.poll(self, event) client.poll(self, event)
} }
pub fn add_client(&mut self, token: Rc<Token>, client: Rc<RefCell<Client>>) { pub fn add_client(&mut self, _token: Rc<Token>, _client: Rc<RefCell<Client>>) {
// self.current_clients.insert(token, client); // self.current_clients.insert(token, client);
} }
pub fn remove_client(&mut self, token: &Token) { pub fn remove_client(&mut self, _token: &Token) {
// self.current_clients.remove(token); // self.current_clients.remove(token);
} }
@ -176,7 +176,7 @@ impl Server {
} }
/// Sends a Packet to all Players /// Sends a Packet to all Players
fn _broadcast_packet<P>(&mut self, packet: P) -> Result<(), PacketError> fn _broadcast_packet<P>(&mut self, _packet: P) -> Result<(), PacketError>
where where
P: ClientPacket, P: ClientPacket,
P: Clone, P: Clone,