diff --git a/pumpkin-protocol/src/bytebuf/mod.rs b/pumpkin-protocol/src/bytebuf/mod.rs index d7046496..8f4a5fdb 100644 --- a/pumpkin-protocol/src/bytebuf/mod.rs +++ b/pumpkin-protocol/src/bytebuf/mod.rs @@ -297,7 +297,7 @@ impl ByteBuffer { self.buffer.put_slice(src) } - pub fn put(&mut self, mut src: T) + pub fn put(&mut self, src: T) where Self: Sized, { diff --git a/pumpkin-protocol/src/bytebuf/serializer.rs b/pumpkin-protocol/src/bytebuf/serializer.rs index 8685fb7b..f3c81f5d 100644 --- a/pumpkin-protocol/src/bytebuf/serializer.rs +++ b/pumpkin-protocol/src/bytebuf/serializer.rs @@ -1,6 +1,5 @@ use std::fmt::Display; -use bytes::Buf; use serde::{ser, Serialize}; use thiserror::Error; @@ -124,20 +123,22 @@ impl<'a> ser::Serializer for &'a mut Serializer { unimplemented!() } fn serialize_none(self) -> Result { - unimplemented!() + self.output.put_bool(false); + Ok(()) } fn serialize_seq(self, len: Option) -> Result { if let Some(len) = len { - self.output.reserve(len); self.output.put_var_int(&VarInt(len as i32)); } Ok(self) } - fn serialize_some(self, _value: &T) -> Result + fn serialize_some(self, value: &T) -> Result where T: ?Sized + Serialize, { - unimplemented!() + self.output.put_bool(true); + dbg!("aa"); + value.serialize(self) } fn serialize_str(self, v: &str) -> Result { self.output.put_string(v); diff --git a/pumpkin-protocol/src/client/login/c_encryption_request.rs b/pumpkin-protocol/src/client/login/c_encryption_request.rs index 7636ca37..312b5cd2 100644 --- a/pumpkin-protocol/src/client/login/c_encryption_request.rs +++ b/pumpkin-protocol/src/client/login/c_encryption_request.rs @@ -1,11 +1,13 @@ use pumpkin_macros::packet; -use crate::{bytebuf::ByteBuffer, ClientPacket, VarIntType}; +use crate::{bytebuf::ByteBuffer, ClientPacket, VarInt}; #[packet(0x01)] pub struct CEncryptionRequest<'a> { server_id: &'a str, // 20 + public_key_length: VarInt, public_key: &'a [u8], + verify_token_length: VarInt, verify_token: &'a [u8], should_authenticate: bool, } @@ -19,7 +21,9 @@ impl<'a> CEncryptionRequest<'a> { ) -> Self { Self { server_id, + public_key_length: public_key.len().into(), public_key, + verify_token_length: verify_token.len().into(), verify_token, should_authenticate, } @@ -29,9 +33,9 @@ impl<'a> CEncryptionRequest<'a> { impl<'a> ClientPacket for CEncryptionRequest<'a> { fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_string(self.server_id); - bytebuf.put_var_int(&(self.public_key.len() as VarIntType).into()); + bytebuf.put_var_int(&self.public_key_length); bytebuf.put_slice(self.public_key); - bytebuf.put_var_int(&(self.verify_token.len() as VarIntType).into()); + bytebuf.put_var_int(&self.verify_token_length); bytebuf.put_slice(self.verify_token); bytebuf.put_bool(self.should_authenticate); } diff --git a/pumpkin-protocol/src/client/play/c_login.rs b/pumpkin-protocol/src/client/play/c_login.rs index 0cb8fe79..ad18d6e7 100644 --- a/pumpkin-protocol/src/client/play/c_login.rs +++ b/pumpkin-protocol/src/client/play/c_login.rs @@ -1,7 +1,9 @@ use pumpkin_macros::packet; +use serde::Serialize; -use crate::{bytebuf::ByteBuffer, ClientPacket, VarInt}; +use crate::VarInt; +#[derive(Serialize)] #[packet(0x2B)] pub struct CLogin { entity_id: i32, @@ -20,9 +22,7 @@ pub struct CLogin { previous_gamemode: i8, debug: bool, is_flat: bool, - has_death_loc: bool, - death_dimension_name: Option, - death_loc: Option, // POSITION NOT STRING + death_dimension_name: Option<(String, i64)>, // POSITION NOT STRING portal_cooldown: VarInt, enforce_secure_chat: bool, } @@ -46,9 +46,7 @@ impl CLogin { previous_gamemode: i8, debug: bool, is_flat: bool, - has_death_loc: bool, - death_dimension_name: Option, - death_loc: Option, // todo add block pos + death_dimension_name: Option<(String, i64)>, portal_cooldown: VarInt, enforce_secure_chat: bool, ) -> Self { @@ -69,39 +67,9 @@ impl CLogin { previous_gamemode, debug, is_flat, - has_death_loc, death_dimension_name, - death_loc, portal_cooldown, enforce_secure_chat, } } } - -impl ClientPacket for CLogin { - fn write(&self, bytebuf: &mut ByteBuffer) { - bytebuf.put_i32(self.entity_id); - bytebuf.put_bool(self.is_hardcore); - bytebuf.put_list(&self.dimension_names, |buf, v| buf.put_string(v)); - bytebuf.put_var_int(&self.max_players); - bytebuf.put_var_int(&self.view_distance); - bytebuf.put_var_int(&self.simulated_distance); - bytebuf.put_bool(self.reduced_debug_info); - bytebuf.put_bool(self.enabled_respawn_screen); - bytebuf.put_bool(self.limited_crafting); - 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); - bytebuf.put_i8(self.previous_gamemode); - bytebuf.put_bool(self.debug); - bytebuf.put_bool(self.is_flat); - bytebuf.put_bool(self.has_death_loc); - if self.has_death_loc { - bytebuf.put_string(self.death_dimension_name.as_ref().unwrap()); - bytebuf.put_i64(self.death_loc.unwrap()); - } - bytebuf.put_var_int(&self.portal_cooldown); - bytebuf.put_bool(self.enforce_secure_chat); - } -} diff --git a/pumpkin-protocol/src/client/play/c_player_abilities.rs b/pumpkin-protocol/src/client/play/c_player_abilities.rs index 65c4cbd0..c7f50cb3 100644 --- a/pumpkin-protocol/src/client/play/c_player_abilities.rs +++ b/pumpkin-protocol/src/client/play/c_player_abilities.rs @@ -1,7 +1,8 @@ use pumpkin_macros::packet; +use serde::Serialize; -use crate::{bytebuf::ByteBuffer, ClientPacket}; +#[derive(Serialize)] #[packet(0x38)] pub struct CPlayerAbilities { flags: i8, @@ -18,11 +19,3 @@ impl CPlayerAbilities { } } } - -impl ClientPacket for CPlayerAbilities { - fn write(&self, bytebuf: &mut ByteBuffer) { - bytebuf.put_i8(self.flags); - bytebuf.put_f32(self.flying_speed); - bytebuf.put_f32(self.field_of_view); - } -} diff --git a/pumpkin-protocol/src/client/play/mod.rs b/pumpkin-protocol/src/client/play/mod.rs index 0399b656..4d0f2231 100644 --- a/pumpkin-protocol/src/client/play/mod.rs +++ b/pumpkin-protocol/src/client/play/mod.rs @@ -1,5 +1,6 @@ mod c_change_difficulty; mod c_chunk_data_update_light; +mod c_entity_metadata; mod c_game_event; mod c_head_rot; mod c_login; @@ -18,6 +19,7 @@ mod player_action; pub use c_change_difficulty::*; pub use c_chunk_data_update_light::*; +pub use c_entity_metadata::*; pub use c_game_event::*; pub use c_head_rot::*; pub use c_login::*; diff --git a/pumpkin-protocol/src/client/status/c_ping_response.rs b/pumpkin-protocol/src/client/status/c_ping_response.rs index 333339a9..a75f8616 100644 --- a/pumpkin-protocol/src/client/status/c_ping_response.rs +++ b/pumpkin-protocol/src/client/status/c_ping_response.rs @@ -1,6 +1,7 @@ use pumpkin_macros::packet; +use serde::Serialize; -#[derive(serde::Serialize)] +#[derive(Serialize)] #[packet(0x01)] pub struct CPingResponse { payload: i64, // must responde with the same as in `SPingRequest` diff --git a/pumpkin-protocol/src/client/status/c_status_response.rs b/pumpkin-protocol/src/client/status/c_status_response.rs index 5f82c33e..4589877f 100644 --- a/pumpkin-protocol/src/client/status/c_status_response.rs +++ b/pumpkin-protocol/src/client/status/c_status_response.rs @@ -1,6 +1,7 @@ use pumpkin_macros::packet; +use serde::Serialize; -#[derive(serde::Serialize)] +#[derive(Serialize)] #[packet(0x00)] pub struct CStatusResponse<'a> { json_response: &'a str, // 32767 diff --git a/pumpkin-protocol/src/lib.rs b/pumpkin-protocol/src/lib.rs index 2cbbe3ce..733c1c23 100644 --- a/pumpkin-protocol/src/lib.rs +++ b/pumpkin-protocol/src/lib.rs @@ -215,7 +215,7 @@ pub struct Sample { } // basicly game profile -#[derive(Deserialize, Clone, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug)] pub struct Property { pub name: String, // base 64 diff --git a/pumpkin/src/server.rs b/pumpkin/src/server.rs index bc73ee60..0fc80f42 100644 --- a/pumpkin/src/server.rs +++ b/pumpkin/src/server.rs @@ -14,8 +14,7 @@ use pumpkin_protocol::{ client::{ config::CPluginMessage, play::{ - CChunkDataUpdateLight, CGameEvent, CLogin, CPlayerAbilities, CPlayerInfoUpdate, - CSpawnEntity, PlayerAction, + CChunkDataUpdateLight, CGameEvent, CLogin, CPlayerAbilities, CPlayerInfoUpdate, CSpawnEntity, PlayerAction, }, }, BitSet, ClientPacket, Players, Sample, StatusResponse, VarInt, Version, CURRENT_MC_PROTOCOL, @@ -144,8 +143,6 @@ impl Server { self.base_config.default_gamemode.to_i8().unwrap(), false, false, - false, // deth loc - None, None, 0.into(), false, @@ -160,19 +157,7 @@ impl Server { client.teleport(x, y, z, 10.0, 10.0); let gameprofile = client.gameprofile.as_ref().unwrap(); // first send info update to our new player, So he can see his Skin - // TODO: send more actions, (chat. list, ping) - client.send_packet(CPlayerInfoUpdate::new( - 0x01, - &[pumpkin_protocol::client::play::Player { - uuid: gameprofile.id, - actions: vec![PlayerAction::AddPlayer { - name: gameprofile.name.clone(), - properties: gameprofile.properties.clone(), - }], - }], - )); - let gameprofile = client.gameprofile.as_ref().unwrap(); - // send his info to everyone else + // also send his info to everyone else self.broadcast_packet( client, CPlayerInfoUpdate::new( @@ -210,7 +195,7 @@ impl Server { let gameprofile = client.gameprofile.as_ref().unwrap(); // spawn player for every client - self.broadcast_packet( + self.broadcast_packet_expect( client, CSpawnEntity::new( entity_id.into(), @@ -252,12 +237,37 @@ impl Server { )) } } + // entity meta data + /* if let Some(config) = &client.config { + self.broadcast_packet( + client, + CSetEntityMetadata::new(entity_id.into(), vec![Metadata::new(18, VarInt(0), 0)]), + ) + } + */ // Server::spawn_test_chunk(client); } /// Sends a Packet to all Players - pub fn broadcast_packet

(&mut self, from: &Client, packet: P) + pub fn broadcast_packet

(&mut self, from: &mut Client, packet: P) + where + P: ClientPacket, + P: Clone, + { + // we can't borrow twice at same time + from.send_packet(packet.clone()); + for (_, client) in self.current_clients.iter().filter(|c| c.0 != &from.token) { + // Check if client is a player + let mut client = client.borrow_mut(); + if client.is_player() { + // we need to clone, Because we send a new packet to every client + client.send_packet(packet.clone()); + } + } + } + + pub fn broadcast_packet_expect

(&mut self, from: &mut Client, packet: P) where P: ClientPacket, P: Clone,