Avoid Packet cloning

This commit is contained in:
Snowiiii 2024-08-12 17:31:43 +02:00
parent d47fb18465
commit 2909cad081
19 changed files with 46 additions and 48 deletions

View File

@ -1,7 +1,7 @@
use pumpkin_macros::packet; use pumpkin_macros::packet;
use serde::Serialize; use serde::Serialize;
use crate::{VarInt}; use crate::VarInt;
#[derive(Serialize)] #[derive(Serialize)]
#[packet(0x01)] #[packet(0x01)]

View File

@ -4,7 +4,7 @@ use serde::Serialize;
use crate::VarInt; use crate::VarInt;
#[derive(Serialize, Clone)] #[derive(Serialize)]
#[packet(0x03)] #[packet(0x03)]
pub struct CEntityAnimation { pub struct CEntityAnimation {
entity_id: VarInt, entity_id: VarInt,

View File

@ -3,7 +3,7 @@ use serde::Serialize;
use crate::VarInt; use crate::VarInt;
#[derive(Serialize, Clone)] #[derive(Serialize)]
#[packet(0x58)] #[packet(0x58)]
pub struct CSetEntityMetadata { pub struct CSetEntityMetadata {
entity_id: VarInt, entity_id: VarInt,
@ -19,7 +19,7 @@ impl CSetEntityMetadata {
} }
} }
#[derive(Serialize, Clone)] #[derive(Serialize)]
pub struct Metadata { pub struct Metadata {
index: u8, index: u8,
typ: VarInt, typ: VarInt,

View File

@ -3,7 +3,7 @@ use serde::Serialize;
use crate::VarInt; use crate::VarInt;
#[derive(Serialize, Clone)] #[derive(Serialize)]
#[packet(0x48)] #[packet(0x48)]
pub struct CHeadRot { pub struct CHeadRot {
entity_id: VarInt, entity_id: VarInt,

View File

@ -4,7 +4,7 @@ use serde::Serialize;
use crate::VarInt; use crate::VarInt;
#[derive(Serialize, Clone)] #[derive(Serialize)]
#[packet(0x33)] #[packet(0x33)]
pub struct COpenScreen { pub struct COpenScreen {
window_id: VarInt, window_id: VarInt,

View File

@ -5,7 +5,7 @@ use serde::Serialize;
use crate::{uuid::UUID, BitSet, VarInt}; use crate::{uuid::UUID, BitSet, VarInt};
#[derive(Serialize, Clone)] #[derive(Serialize)]
#[packet(0x39)] #[packet(0x39)]
pub struct CPlayerChatMessage<'a> { pub struct CPlayerChatMessage<'a> {
sender: UUID, sender: UUID,

View File

@ -3,7 +3,7 @@ use serde::Serialize;
use crate::{uuid::UUID, VarInt}; use crate::{uuid::UUID, VarInt};
#[derive(Serialize, Clone)] #[derive(Serialize)]
#[packet(0x3D)] #[packet(0x3D)]
pub struct CRemovePlayerInfo<'a> { pub struct CRemovePlayerInfo<'a> {
players_count: VarInt, players_count: VarInt,

View File

@ -3,7 +3,7 @@ use serde::Serialize;
use crate::VarInt; use crate::VarInt;
#[derive(Serialize, Clone)] #[derive(Serialize)]
#[packet(0x42)] #[packet(0x42)]
pub struct CRemoveEntities<'a> { pub struct CRemoveEntities<'a> {
count: VarInt, count: VarInt,

View File

@ -3,7 +3,7 @@ use serde::Serialize;
use crate::{uuid::UUID, VarInt}; use crate::{uuid::UUID, VarInt};
#[derive(Serialize, Clone)] #[derive(Serialize)]
#[packet(0x01)] #[packet(0x01)]
pub struct CSpawnEntity { pub struct CSpawnEntity {
entity_id: VarInt, entity_id: VarInt,

View File

@ -2,7 +2,7 @@ use pumpkin_macros::packet;
use pumpkin_text::TextComponent; use pumpkin_text::TextComponent;
use serde::Serialize; use serde::Serialize;
#[derive(Serialize, Clone)] #[derive(Serialize)]
#[packet(0x6C)] #[packet(0x6C)]
pub struct CSystemChatMessge { pub struct CSystemChatMessge {
content: TextComponent, content: TextComponent,

View File

@ -3,7 +3,7 @@ use serde::Serialize;
use crate::VarInt; use crate::VarInt;
#[derive(Serialize, Clone)] #[derive(Serialize)]
#[packet(0x2F)] #[packet(0x2F)]
pub struct CUpdateEntityPosRot { pub struct CUpdateEntityPosRot {
entity_id: VarInt, entity_id: VarInt,

View File

@ -3,7 +3,7 @@ use serde::Serialize;
use crate::VarInt; use crate::VarInt;
#[derive(Serialize, Clone)] #[derive(Serialize)]
#[packet(0x2E)] #[packet(0x2E)]
pub struct CUpdateEntityPos { pub struct CUpdateEntityPos {
entity_id: VarInt, entity_id: VarInt,

View File

@ -3,7 +3,7 @@ use serde::Serialize;
use crate::VarInt; use crate::VarInt;
#[derive(Serialize, Clone)] #[derive(Serialize)]
#[packet(0x30)] #[packet(0x30)]
pub struct CUpdateEntityRot { pub struct CUpdateEntityRot {
entity_id: VarInt, entity_id: VarInt,

View File

@ -22,7 +22,7 @@ pub struct PacketEncoder {
} }
impl PacketEncoder { impl PacketEncoder {
pub fn append_packet<P: ClientPacket>(&mut self, packet: P) -> Result<(), PacketError> { pub fn append_packet<P: ClientPacket>(&mut self, packet: &P) -> Result<(), PacketError> {
let start_len = self.buf.len(); let start_len = self.buf.len();
let mut writer = (&mut self.buf).writer(); let mut writer = (&mut self.buf).writer();

View File

@ -40,12 +40,12 @@ impl Client {
} }
pub 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));
} }
pub 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));
self.close(); self.close();
} }
@ -70,7 +70,7 @@ impl Client {
&verify_token, &verify_token,
server.base_config.online_mode, // TODO server.base_config.online_mode, // TODO
); );
self.send_packet(packet); self.send_packet(&packet);
} }
pub async fn handle_encryption_response( pub async fn handle_encryption_response(
@ -144,13 +144,13 @@ impl Client {
.packet_compression .packet_compression
.compression_threshold; .compression_threshold;
let level = server.advanced_config.packet_compression.compression_level; let level = server.advanced_config.packet_compression.compression_level;
self.send_packet(CSetCompression::new(threshold.into())); self.send_packet(&CSetCompression::new(threshold.into()));
self.set_compression(Some((threshold, level))); self.set_compression(Some((threshold, level)));
} }
if let Some(profile) = self.gameprofile.as_ref().cloned() { if let Some(profile) = self.gameprofile.as_ref().cloned() {
let packet = CLoginSuccess::new(profile.id, &profile.name, &profile.properties, false); let packet = CLoginSuccess::new(profile.id, &profile.name, &profile.properties, false);
self.send_packet(packet); self.send_packet(&packet);
} else { } else {
self.kick("game profile is none"); self.kick("game profile is none");
} }
@ -178,7 +178,7 @@ impl Client {
} else { } else {
Some(TextComponent::from(resource_config.prompt_message.clone())) Some(TextComponent::from(resource_config.prompt_message.clone()))
}; };
self.send_packet(CConfigAddResourcePack::new( self.send_packet(&CConfigAddResourcePack::new(
uuid::Uuid::from_str(&resource_config.resource_pack_url).unwrap(), uuid::Uuid::from_str(&resource_config.resource_pack_url).unwrap(),
resource_config.resource_pack_url.clone(), resource_config.resource_pack_url.clone(),
resource_config.resource_pack_sha1.clone(), resource_config.resource_pack_sha1.clone(),
@ -188,7 +188,7 @@ impl Client {
} }
// known data packs // known data packs
self.send_packet(CKnownPacks::new(&[KnownPack { self.send_packet(&CKnownPacks::new(&[KnownPack {
namespace: "minecraft", namespace: "minecraft",
id: "core", id: "core",
version: "1.21", version: "1.21",
@ -226,7 +226,7 @@ impl Client {
pub 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 &server.cached_registry { for registry in &server.cached_registry {
self.send_packet(CRegistryData::new( self.send_packet(&CRegistryData::new(
&registry.registry_id, &registry.registry_id,
&registry.registry_entries, &registry.registry_entries,
)); ));
@ -234,7 +234,7 @@ impl Client {
// We are done with configuring // We are done with configuring
dbg!("finish config"); dbg!("finish config");
self.send_packet(CFinishConfig::new()); self.send_packet(&CFinishConfig::new());
} }
pub fn handle_config_acknowledged( pub fn handle_config_acknowledged(

View File

@ -122,7 +122,7 @@ impl Client {
} }
/// Send a Clientbound Packet to the Client /// Send a Clientbound Packet to the Client
pub fn send_packet<P: ClientPacket>(&mut self, packet: P) { pub fn send_packet<P: ClientPacket>(&mut self, packet: &P) {
self.enc self.enc
.append_packet(packet) .append_packet(packet)
.unwrap_or_else(|e| self.kick(&e.to_string())); .unwrap_or_else(|e| self.kick(&e.to_string()));
@ -132,7 +132,7 @@ impl Client {
.unwrap_or_else(|e| self.kick(&e.to_string())); .unwrap_or_else(|e| self.kick(&e.to_string()));
} }
pub fn try_send_packet<P: ClientPacket>(&mut self, packet: P) -> Result<(), PacketError> { pub fn try_send_packet<P: ClientPacket>(&mut self, packet: &P) -> Result<(), PacketError> {
self.enc.append_packet(packet)?; self.enc.append_packet(packet)?;
self.connection self.connection
.write_all(&self.enc.take()) .write_all(&self.enc.take())
@ -155,11 +155,11 @@ impl Client {
entity.yaw = yaw; entity.yaw = yaw;
entity.pitch = pitch; entity.pitch = pitch;
player.awaiting_teleport = Some(id.into()); player.awaiting_teleport = Some(id.into());
self.send_packet(CSyncPlayerPostion::new(x, y, z, yaw, pitch, 0, id.into())); self.send_packet(&CSyncPlayerPostion::new(x, y, z, yaw, pitch, 0, id.into()));
} }
pub fn set_gamemode(&mut self, gamemode: GameMode) { pub fn set_gamemode(&mut self, gamemode: GameMode) {
self.send_packet(CGameEvent::new(3, gamemode.to_f32().unwrap())); self.send_packet(&CGameEvent::new(3, gamemode.to_f32().unwrap()));
} }
pub async fn process_packets(&mut self, server: &mut Server) { pub async fn process_packets(&mut self, server: &mut Server) {
@ -323,7 +323,7 @@ impl Client {
} }
pub fn send_system_message(&mut self, text: TextComponent) { pub fn send_system_message(&mut self, text: TextComponent) {
self.send_packet(CSystemChatMessge::new(text, false)); self.send_packet(&CSystemChatMessge::new(text, false));
} }
/// Kicks the Client with a reason depending on the connection state /// Kicks the Client with a reason depending on the connection state
@ -331,17 +331,17 @@ impl Client {
dbg!(reason); dbg!(reason);
match self.connection_state { match self.connection_state {
ConnectionState::Login => { ConnectionState::Login => {
self.try_send_packet(CLoginDisconnect::new( self.try_send_packet(&CLoginDisconnect::new(
&serde_json::to_string_pretty(&reason).unwrap(), &serde_json::to_string_pretty(&reason).unwrap(),
)) ))
.unwrap_or_else(|_| self.close()); .unwrap_or_else(|_| self.close());
} }
ConnectionState::Config => { ConnectionState::Config => {
self.try_send_packet(CConfigDisconnect::new(reason)) self.try_send_packet(&CConfigDisconnect::new(reason))
.unwrap_or_else(|_| self.close()); .unwrap_or_else(|_| self.close());
} }
ConnectionState::Play => { ConnectionState::Play => {
self.try_send_packet(CPlayDisconnect::new(TextComponent::from(reason))) self.try_send_packet(&CPlayDisconnect::new(TextComponent::from(reason)))
.unwrap_or_else(|_| self.close()); .unwrap_or_else(|_| self.close());
} }
_ => { _ => {

View File

@ -186,7 +186,7 @@ impl Client {
}; };
let player = self.player.as_mut().unwrap(); let player = self.player.as_mut().unwrap();
let id = player.entity_id(); let id = player.entity_id();
server.broadcast_packet_expect(self, CEntityAnimation::new(id.into(), animation as u8)) server.broadcast_packet_expect(self, &CEntityAnimation::new(id.into(), animation as u8))
} }
pub fn handle_chat_message(&mut self, server: &mut Server, chat_message: SChatMessage) { pub fn handle_chat_message(&mut self, server: &mut Server, chat_message: SChatMessage) {

View File

@ -3,7 +3,7 @@ use std::io::{self, BufRead, Cursor, Write};
use bytes::{BufMut, BytesMut}; use bytes::{BufMut, BytesMut};
use mio::net::TcpStream; use mio::net::TcpStream;
use thiserror::Error; use thiserror::Error;
use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::io::AsyncReadExt;
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum PacketType { pub enum PacketType {

View File

@ -145,7 +145,7 @@ impl Server {
client.player = Some(player); client.player = Some(player);
// login packet for our new player // login packet for our new player
client.send_packet(CLogin::new( client.send_packet(&CLogin::new(
entity_id, entity_id,
self.base_config.hardcore, self.base_config.hardcore,
&["minecraft:overworld"], &["minecraft:overworld"],
@ -173,7 +173,7 @@ impl Server {
)); ));
dbg!("sending abilities"); dbg!("sending abilities");
// player abilities // player abilities
client.send_packet(CPlayerAbilities::new(0x02, 00.2, 0.1)); client.send_packet(&CPlayerAbilities::new(0x02, 00.2, 0.1));
// teleport // teleport
let x = 10.0; let x = 10.0;
@ -220,10 +220,10 @@ impl Server {
}) })
} }
} }
client.send_packet(CPlayerInfoUpdate::new(0x01 | 0x08, &entries)); client.send_packet(&CPlayerInfoUpdate::new(0x01 | 0x08, &entries));
// Start waiting for level chunks // Start waiting for level chunks
client.send_packet(CGameEvent::new(13, 0.0)); client.send_packet(&CGameEvent::new(13, 0.0));
let gameprofile = client.gameprofile.as_ref().unwrap(); let gameprofile = client.gameprofile.as_ref().unwrap();
@ -231,7 +231,7 @@ impl Server {
self.broadcast_packet_expect( self.broadcast_packet_expect(
client, client,
// TODO: add velo // TODO: add velo
CSpawnEntity::new( &CSpawnEntity::new(
entity_id.into(), entity_id.into(),
UUID(gameprofile.id), UUID(gameprofile.id),
EntityType::Player.to_i32().unwrap().into(), EntityType::Player.to_i32().unwrap().into(),
@ -254,7 +254,7 @@ impl Server {
if let Some(player) = &existing_client.player { if let Some(player) = &existing_client.player {
let entity = &player.entity; let entity = &player.entity;
let gameprofile = existing_client.gameprofile.as_ref().unwrap(); let gameprofile = existing_client.gameprofile.as_ref().unwrap();
client.send_packet(CSpawnEntity::new( client.send_packet(&CSpawnEntity::new(
player.entity_id().into(), player.entity_id().into(),
UUID(gameprofile.id), UUID(gameprofile.id),
EntityType::Player.to_i32().unwrap().into(), EntityType::Player.to_i32().unwrap().into(),
@ -287,31 +287,29 @@ impl Server {
pub fn broadcast_packet<P>(&mut self, from: &mut Client, packet: P) pub fn broadcast_packet<P>(&mut self, from: &mut Client, packet: P)
where where
P: ClientPacket, P: ClientPacket,
P: Clone,
{ {
// we can't borrow twice at same time // we can't borrow twice at same time
from.send_packet(packet.clone()); from.send_packet(&packet);
for (_, client) in self.current_clients.iter().filter(|c| c.0 != &from.token) { for (_, client) in self.current_clients.iter().filter(|c| c.0 != &from.token) {
// Check if client is a player // Check if client is a player
let mut client = client.borrow_mut(); let mut client = client.borrow_mut();
if client.is_player() { if client.is_player() {
// we need to clone, Because we send a new packet to every client // we need to clone, Because we send a new packet to every client
client.send_packet(packet.clone()); client.send_packet(&packet);
} }
} }
} }
pub fn broadcast_packet_expect<P>(&mut self, from: &mut Client, packet: P) pub fn broadcast_packet_expect<P>(&mut self, from: &mut Client, packet: &P)
where where
P: ClientPacket, P: ClientPacket,
P: Clone,
{ {
for (_, client) in self.current_clients.iter().filter(|c| c.0 != &from.token) { for (_, client) in self.current_clients.iter().filter(|c| c.0 != &from.token) {
// Check if client is a player // Check if client is a player
let mut client = client.borrow_mut(); let mut client = client.borrow_mut();
if client.is_player() { if client.is_player() {
// we need to clone, Because we send a new packet to every client // we need to clone, Because we send a new packet to every client
client.send_packet(packet.clone()); client.send_packet(packet);
} }
} }
} }
@ -319,7 +317,7 @@ impl Server {
// TODO: do this in a world // TODO: do this in a world
fn _spawn_test_chunk(client: &mut Client) { fn _spawn_test_chunk(client: &mut Client) {
let test_chunk = TestChunk::new(); let test_chunk = TestChunk::new();
client.send_packet(CChunkDataUpdateLight::new( client.send_packet(&CChunkDataUpdateLight::new(
10, 10,
10, 10,
test_chunk.heightmap, test_chunk.heightmap,
@ -348,7 +346,7 @@ impl Server {
pub fn send_brand(&self, client: &mut Client) { pub fn send_brand(&self, client: &mut Client) {
// send server brand // send server brand
client.send_packet(CPluginMessage::new( client.send_packet(&CPluginMessage::new(
"minecraft:brand", "minecraft:brand",
&self.cached_server_brand, &self.cached_server_brand,
)); ));