fix: Remove liftimes from CStatusResponse and CPlayerPosition (#1128)

* fix: Remove liftimes from CStatusResponse and CPlayerPosition

* fix: Add lifetimes to CachedBranding and fix tests

* fix: Remove lifetimes from CLoginDisconnect packet, data is dropped immediately after the packet is constructed

* fix: Apply formatting to packet_encoder.rs

---------

Co-authored-by: Alexander Medvedev <lilalexmed@proton.me>
This commit is contained in:
Connor
2025-08-22 07:57:55 +00:00
committed by GitHub
parent 23b3517ae5
commit 736f073b3c
8 changed files with 36 additions and 32 deletions

View File

@@ -4,13 +4,13 @@ use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
#[packet(LOGIN_LOGIN_DISCONNECT)]
pub struct CLoginDisconnect<'a> {
pub json_reason: &'a str,
pub struct CLoginDisconnect {
pub json_reason: String,
}
impl<'a> CLoginDisconnect<'a> {
impl CLoginDisconnect {
// input json!
pub fn new(json_reason: &'a str) -> Self {
pub fn new(json_reason: String) -> Self {
Self { json_reason }
}
}

View File

@@ -10,23 +10,23 @@ use crate::{
};
#[packet(PLAY_PLAYER_POSITION)]
pub struct CPlayerPosition<'a> {
pub struct CPlayerPosition {
pub teleport_id: VarInt,
pub position: Vector3<f64>,
pub delta: Vector3<f64>,
pub yaw: f32,
pub pitch: f32,
pub releatives: &'a [PositionFlag],
pub releatives: Vec<PositionFlag>,
}
impl<'a> CPlayerPosition<'a> {
impl CPlayerPosition {
pub fn new(
teleport_id: VarInt,
position: Vector3<f64>,
delta: Vector3<f64>,
yaw: f32,
pitch: f32,
releatives: &'a [PositionFlag],
releatives: Vec<PositionFlag>,
) -> Self {
Self {
teleport_id,
@@ -40,7 +40,7 @@ impl<'a> CPlayerPosition<'a> {
}
// TODO: Do we need a custom impl?
impl ClientPacket for CPlayerPosition<'_> {
impl ClientPacket for CPlayerPosition {
fn write_packet_data(&self, write: impl Write) -> Result<(), WritingError> {
let mut write = write;
@@ -54,11 +54,11 @@ impl ClientPacket for CPlayerPosition<'_> {
write.write_f32_be(self.yaw)?;
write.write_f32_be(self.pitch)?;
// not sure about that
write.write_i32_be(PositionFlag::get_bitfield(self.releatives))
write.write_i32_be(PositionFlag::get_bitfield(self.releatives.as_slice()))
}
}
impl ServerPacket for CPlayerPosition<'_> {
impl ServerPacket for CPlayerPosition {
fn read(mut read: impl std::io::Read) -> Result<Self, crate::ser::ReadingError> {
Ok(Self {
teleport_id: read.get_var_int()?,
@@ -67,7 +67,7 @@ impl ServerPacket for CPlayerPosition<'_> {
delta: Vector3::new(0.0, 0.0, 0.0),
yaw: 0.0,
pitch: 0.0,
releatives: &[],
releatives: Vec::new(),
})
}
}

View File

@@ -4,11 +4,11 @@ use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
#[packet(STATUS_STATUS_RESPONSE)]
pub struct CStatusResponse<'a> {
pub json_response: &'a str, // 32767
pub struct CStatusResponse {
pub json_response: String, // 32767
}
impl<'a> CStatusResponse<'a> {
pub fn new(json_response: &'a str) -> Self {
impl CStatusResponse {
pub fn new(json_response: String) -> Self {
Self { json_response }
}
}

View File

@@ -350,7 +350,8 @@ mod tests {
#[tokio::test]
async fn test_encode_without_compression_and_encryption() {
// Create a CStatusResponse packet
let packet = CStatusResponse::new("{\"description\": \"A Minecraft Server\"}");
let packet =
CStatusResponse::new(String::from("{\"description\": \"A Minecraft Server\"}"));
// Build the packet without compression and encryption
let packet_bytes = build_packet_with_encoder(&packet, None, None).await;
@@ -382,7 +383,8 @@ mod tests {
#[tokio::test]
async fn test_encode_with_compression() {
// Create a CStatusResponse packet
let packet = CStatusResponse::new("{\"description\": \"A Minecraft Server\"}");
let packet =
CStatusResponse::new("{\"description\": \"A Minecraft Server\"}".parse().unwrap());
// Build the packet with compression enabled
let packet_bytes = build_packet_with_encoder(&packet, Some((0, 6)), None).await;
@@ -429,7 +431,8 @@ mod tests {
#[tokio::test]
async fn test_encode_with_encryption() {
// Create a CStatusResponse packet
let packet = CStatusResponse::new("{\"description\": \"A Minecraft Server\"}");
let packet =
CStatusResponse::new("{\"description\": \"A Minecraft Server\"}".parse().unwrap());
// Encryption key and IV (IV is the same as key in this case)
let key = [0x00u8; 16]; // Example key
@@ -465,7 +468,8 @@ mod tests {
#[tokio::test]
async fn test_encode_with_compression_and_encryption() {
// Create a CStatusResponse packet
let packet = CStatusResponse::new("{\"description\": \"A Minecraft Server\"}");
let packet =
CStatusResponse::new("{\"description\": \"A Minecraft Server\"}".parse().unwrap());
// Encryption key and IV (IV is the same as key in this case)
let key = [0x01u8; 16]; // Example key
@@ -519,7 +523,7 @@ mod tests {
#[tokio::test]
async fn test_encode_with_zero_length_payload() {
// Create a CStatusResponse packet with empty payload
let packet = CStatusResponse::new("");
let packet = CStatusResponse::new(String::from(""));
// Build the packet without compression and encryption
let packet_bytes = build_packet_with_encoder(&packet, None, None).await;
@@ -557,7 +561,7 @@ mod tests {
// Maximum allowed string length is 32767 bytes
let max_string_length = 32767;
let payload_str = "A".repeat(max_string_length);
let packet = CStatusResponse::new(&payload_str);
let packet = CStatusResponse::new(payload_str);
// Build the packet without compression and encryption
let packet_bytes = build_packet_with_encoder(&packet, None, None).await;
@@ -608,7 +612,7 @@ mod tests {
#[tokio::test]
async fn test_encode_small_payload_no_compression() {
// Create a CStatusResponse packet with small payload
let packet = CStatusResponse::new("Hi");
let packet = CStatusResponse::new(String::from("Hi"));
// Build the packet with compression enabled
// Compression threshold is set to a value higher than payload length

View File

@@ -1177,7 +1177,7 @@ impl Player {
yaw,
pitch,
// TODO
&[],
Vec::new(),
)).await;
}
}}

View File

@@ -255,7 +255,7 @@ impl JavaClient {
ConnectionState::Login => {
// TextComponent implements Serialize and writes in bytes instead of String, that's the reasib we only use content
self.send_packet_now(&CLoginDisconnect::new(
&serde_json::to_string(&reason.0).unwrap_or_else(|_| String::new()),
serde_json::to_string(&reason.0).unwrap_or_else(|_| String::new()),
))
.await;
}

View File

@@ -350,7 +350,7 @@ impl JavaClient {
Vector3::new(0.0, 0.0, 0.0),
player.living_entity.entity.yaw.load(),
player.living_entity.entity.pitch.load(),
&[],
Vec::new(),
)).await;
}
}}
@@ -483,7 +483,7 @@ impl JavaClient {
Vector3::new(0.0, 0.0, 0.0),
player.living_entity.entity.yaw.load(),
player.living_entity.entity.pitch.load(),
&[],
Vec::new(),
))
.await;
}

View File

@@ -39,7 +39,7 @@ pub struct CachedBranding {
cached_server_brand: Box<[u8]>,
}
impl CachedBranding {
impl<'a> CachedBranding {
pub fn new() -> Self {
let cached_server_brand = Self::build_brand();
Self {
@@ -49,8 +49,8 @@ impl CachedBranding {
pub fn get_branding(&self) -> CPluginMessage<'_> {
CPluginMessage::new("minecraft:brand", &self.cached_server_brand)
}
const BRAND: &str = "Pumpkin";
const BRAND_BYTES: &[u8] = Self::BRAND.as_bytes();
const BRAND: &'a str = "Pumpkin";
const BRAND_BYTES: &'a [u8] = Self::BRAND.as_bytes();
fn build_brand() -> Box<[u8]> {
let mut buf = Vec::new();
@@ -73,8 +73,8 @@ impl CachedStatus {
}
}
pub fn get_status(&self) -> CStatusResponse<'_> {
CStatusResponse::new(&self.status_response_json)
pub fn get_status(&self) -> CStatusResponse {
CStatusResponse::new(self.status_response_json.clone())
}
// TODO: Player samples