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 serde::Serialize;
use crate::{VarInt};
use crate::VarInt;
#[derive(Serialize)]
#[packet(0x01)]

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -22,7 +22,7 @@ pub struct 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 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) {
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) {
dbg!("ping");
self.send_packet(CPingResponse::new(ping_request.payload));
self.send_packet(&CPingResponse::new(ping_request.payload));
self.close();
}
@ -70,7 +70,7 @@ impl Client {
&verify_token,
server.base_config.online_mode, // TODO
);
self.send_packet(packet);
self.send_packet(&packet);
}
pub async fn handle_encryption_response(
@ -144,13 +144,13 @@ impl Client {
.packet_compression
.compression_threshold;
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)));
}
if let Some(profile) = self.gameprofile.as_ref().cloned() {
let packet = CLoginSuccess::new(profile.id, &profile.name, &profile.properties, false);
self.send_packet(packet);
self.send_packet(&packet);
} else {
self.kick("game profile is none");
}
@ -178,7 +178,7 @@ impl Client {
} else {
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(),
resource_config.resource_pack_url.clone(),
resource_config.resource_pack_sha1.clone(),
@ -188,7 +188,7 @@ impl Client {
}
// known data packs
self.send_packet(CKnownPacks::new(&[KnownPack {
self.send_packet(&CKnownPacks::new(&[KnownPack {
namespace: "minecraft",
id: "core",
version: "1.21",
@ -226,7 +226,7 @@ impl Client {
pub fn handle_known_packs(&mut self, server: &mut Server, _config_acknowledged: SKnownPacks) {
for registry in &server.cached_registry {
self.send_packet(CRegistryData::new(
self.send_packet(&CRegistryData::new(
&registry.registry_id,
&registry.registry_entries,
));
@ -234,7 +234,7 @@ impl Client {
// We are done with configuring
dbg!("finish config");
self.send_packet(CFinishConfig::new());
self.send_packet(&CFinishConfig::new());
}
pub fn handle_config_acknowledged(

View File

@ -122,7 +122,7 @@ impl 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
.append_packet(packet)
.unwrap_or_else(|e| self.kick(&e.to_string()));
@ -132,7 +132,7 @@ impl Client {
.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.connection
.write_all(&self.enc.take())
@ -155,11 +155,11 @@ impl Client {
entity.yaw = yaw;
entity.pitch = pitch;
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) {
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) {
@ -323,7 +323,7 @@ impl Client {
}
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
@ -331,17 +331,17 @@ impl Client {
dbg!(reason);
match self.connection_state {
ConnectionState::Login => {
self.try_send_packet(CLoginDisconnect::new(
self.try_send_packet(&CLoginDisconnect::new(
&serde_json::to_string_pretty(&reason).unwrap(),
))
.unwrap_or_else(|_| self.close());
}
ConnectionState::Config => {
self.try_send_packet(CConfigDisconnect::new(reason))
self.try_send_packet(&CConfigDisconnect::new(reason))
.unwrap_or_else(|_| self.close());
}
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());
}
_ => {

View File

@ -186,7 +186,7 @@ impl Client {
};
let player = self.player.as_mut().unwrap();
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) {

View File

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

View File

@ -145,7 +145,7 @@ impl Server {
client.player = Some(player);
// login packet for our new player
client.send_packet(CLogin::new(
client.send_packet(&CLogin::new(
entity_id,
self.base_config.hardcore,
&["minecraft:overworld"],
@ -173,7 +173,7 @@ impl Server {
));
dbg!("sending abilities");
// player abilities
client.send_packet(CPlayerAbilities::new(0x02, 00.2, 0.1));
client.send_packet(&CPlayerAbilities::new(0x02, 00.2, 0.1));
// teleport
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
client.send_packet(CGameEvent::new(13, 0.0));
client.send_packet(&CGameEvent::new(13, 0.0));
let gameprofile = client.gameprofile.as_ref().unwrap();
@ -231,7 +231,7 @@ impl Server {
self.broadcast_packet_expect(
client,
// TODO: add velo
CSpawnEntity::new(
&CSpawnEntity::new(
entity_id.into(),
UUID(gameprofile.id),
EntityType::Player.to_i32().unwrap().into(),
@ -254,7 +254,7 @@ impl Server {
if let Some(player) = &existing_client.player {
let entity = &player.entity;
let gameprofile = existing_client.gameprofile.as_ref().unwrap();
client.send_packet(CSpawnEntity::new(
client.send_packet(&CSpawnEntity::new(
player.entity_id().into(),
UUID(gameprofile.id),
EntityType::Player.to_i32().unwrap().into(),
@ -287,31 +287,29 @@ impl Server {
pub fn broadcast_packet<P>(&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());
from.send_packet(&packet);
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());
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
P: ClientPacket,
P: 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());
client.send_packet(packet);
}
}
}
@ -319,7 +317,7 @@ impl Server {
// TODO: do this in a world
fn _spawn_test_chunk(client: &mut Client) {
let test_chunk = TestChunk::new();
client.send_packet(CChunkDataUpdateLight::new(
client.send_packet(&CChunkDataUpdateLight::new(
10,
10,
test_chunk.heightmap,
@ -348,7 +346,7 @@ impl Server {
pub fn send_brand(&self, client: &mut Client) {
// send server brand
client.send_packet(CPluginMessage::new(
client.send_packet(&CPluginMessage::new(
"minecraft:brand",
&self.cached_server_brand,
));