chore(net): change get_string to get_str
changed return value from `String` to `Box<str>` which is smaller and makes more sense since we don't mutate packet data String — 24 bytes (ptr + len + capacity) Box<str> — 16 bytes (ptr + len)
This commit is contained in:
parent
8e7195c39e
commit
3303bb7b97
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -2149,6 +2149,15 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nu-ansi-term"
|
||||||
|
version = "0.50.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-bigint"
|
name = "num-bigint"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
@ -3848,6 +3857,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319"
|
checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"matchers",
|
"matchers",
|
||||||
|
"nu-ansi-term",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"regex-automata",
|
"regex-automata",
|
||||||
"sharded-slab",
|
"sharded-slab",
|
||||||
|
|||||||
@ -171,6 +171,7 @@ tracing = { version = "0.1.44", default-features = false, features = ["std", "at
|
|||||||
tracing-subscriber = { version = "0.3.23", default-features = false, features = [
|
tracing-subscriber = { version = "0.3.23", default-features = false, features = [
|
||||||
"env-filter",
|
"env-filter",
|
||||||
"fmt",
|
"fmt",
|
||||||
|
"ansi",
|
||||||
"time",
|
"time",
|
||||||
"std",
|
"std",
|
||||||
] }
|
] }
|
||||||
|
|||||||
@ -87,7 +87,7 @@ impl UDPNetworkDecoder {
|
|||||||
|
|
||||||
pub async fn get_packet_payload(
|
pub async fn get_packet_payload(
|
||||||
&mut self,
|
&mut self,
|
||||||
full_packet: Vec<u8>,
|
mut full_packet: Vec<u8>,
|
||||||
) -> Result<Vec<u8>, PacketDecodeError> {
|
) -> Result<Vec<u8>, PacketDecodeError> {
|
||||||
if full_packet.is_empty() {
|
if full_packet.is_empty() {
|
||||||
return Err(PacketDecodeError::MalformedLength("Empty packet".into()));
|
return Err(PacketDecodeError::MalformedLength("Empty packet".into()));
|
||||||
@ -104,7 +104,7 @@ impl UDPNetworkDecoder {
|
|||||||
|
|
||||||
// If compression is NOT enabled yet, the payload starts at index 1.
|
// If compression is NOT enabled yet, the payload starts at index 1.
|
||||||
if self.compression.is_none() {
|
if self.compression.is_none() {
|
||||||
return Ok(full_packet[1..].to_vec());
|
return Ok(full_packet.split_off(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If compression IS enabled, Bedrock expects a compression method byte at index 1.
|
// If compression IS enabled, Bedrock expects a compression method byte at index 1.
|
||||||
@ -125,7 +125,7 @@ impl UDPNetworkDecoder {
|
|||||||
}
|
}
|
||||||
0xff => {
|
0xff => {
|
||||||
// None (Compression enabled but this specific packet is raw)
|
// None (Compression enabled but this specific packet is raw)
|
||||||
Ok(full_packet[data_start..].to_vec())
|
Ok(full_packet.split_off(2))
|
||||||
}
|
}
|
||||||
_ => Err(PacketDecodeError::FailedDecompression(format!(
|
_ => Err(PacketDecodeError::FailedDecompression(format!(
|
||||||
"Unsupported compression method: 0x{compression_method:02x}"
|
"Unsupported compression method: 0x{compression_method:02x}"
|
||||||
|
|||||||
@ -27,7 +27,7 @@ pub struct CPlayerChatMessage {
|
|||||||
/// The RSA signature (256 bytes) verifying the message's authenticity.
|
/// The RSA signature (256 bytes) verifying the message's authenticity.
|
||||||
pub message_signature: Option<Box<[u8]>>,
|
pub message_signature: Option<Box<[u8]>>,
|
||||||
/// The raw plain-text content of the message.
|
/// The raw plain-text content of the message.
|
||||||
pub message: String,
|
pub message: Box<str>,
|
||||||
/// Epoch timestamp (milliseconds) when the message was sent.
|
/// Epoch timestamp (milliseconds) when the message was sent.
|
||||||
pub timestamp: i64,
|
pub timestamp: i64,
|
||||||
/// A random 64-bit value used to ensure signature uniqueness.
|
/// A random 64-bit value used to ensure signature uniqueness.
|
||||||
@ -58,7 +58,7 @@ impl CPlayerChatMessage {
|
|||||||
sender: uuid::Uuid,
|
sender: uuid::Uuid,
|
||||||
index: VarInt,
|
index: VarInt,
|
||||||
message_signature: Option<Box<[u8]>>,
|
message_signature: Option<Box<[u8]>>,
|
||||||
message: String,
|
message: Box<str>,
|
||||||
timestamp: i64,
|
timestamp: i64,
|
||||||
salt: i64,
|
salt: i64,
|
||||||
previous_messages: Box<[PreviousMessage]>,
|
previous_messages: Box<[PreviousMessage]>,
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use std::io::Read;
|
|||||||
|
|
||||||
use pumpkin_data::packet::serverbound::CONFIG_COOKIE_RESPONSE;
|
use pumpkin_data::packet::serverbound::CONFIG_COOKIE_RESPONSE;
|
||||||
use pumpkin_macros::java_packet;
|
use pumpkin_macros::java_packet;
|
||||||
use pumpkin_util::{resource_location::ResourceLocation, version::JavaMinecraftVersion};
|
use pumpkin_util::version::JavaMinecraftVersion;
|
||||||
|
|
||||||
use crate::{ReadingError, ServerPacket, ser::NetworkReadExt};
|
use crate::{ReadingError, ServerPacket, ser::NetworkReadExt};
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ const MAX_COOKIE_LENGTH: usize = 5120;
|
|||||||
#[java_packet(CONFIG_COOKIE_RESPONSE)]
|
#[java_packet(CONFIG_COOKIE_RESPONSE)]
|
||||||
pub struct SConfigCookieResponse {
|
pub struct SConfigCookieResponse {
|
||||||
/// The unique identifier for the cookie being returned
|
/// The unique identifier for the cookie being returned
|
||||||
pub key: ResourceLocation,
|
pub key: Box<str>,
|
||||||
/// Indicates whether a payload is attached to this response
|
/// Indicates whether a payload is attached to this response
|
||||||
pub has_payload: bool,
|
pub has_payload: bool,
|
||||||
/// The actual data stored in the cookie. Limited to 5120 bytes
|
/// The actual data stored in the cookie. Limited to 5120 bytes
|
||||||
@ -26,7 +26,7 @@ pub struct SConfigCookieResponse {
|
|||||||
impl ServerPacket for SConfigCookieResponse {
|
impl ServerPacket for SConfigCookieResponse {
|
||||||
fn read(read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
|
fn read(read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
|
||||||
let mut read = read;
|
let mut read = read;
|
||||||
let key = read.get_string()?;
|
let key = read.get_str()?;
|
||||||
let has_payload = read.get_bool()?;
|
let has_payload = read.get_bool()?;
|
||||||
|
|
||||||
if !has_payload {
|
if !has_payload {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use std::io::Read;
|
|||||||
|
|
||||||
use pumpkin_data::packet::serverbound::CONFIG_CUSTOM_PAYLOAD;
|
use pumpkin_data::packet::serverbound::CONFIG_CUSTOM_PAYLOAD;
|
||||||
use pumpkin_macros::java_packet;
|
use pumpkin_macros::java_packet;
|
||||||
use pumpkin_util::{resource_location::ResourceLocation, version::JavaMinecraftVersion};
|
use pumpkin_util::version::JavaMinecraftVersion;
|
||||||
|
|
||||||
use crate::{ReadingError, ServerPacket, ser::NetworkReadExt};
|
use crate::{ReadingError, ServerPacket, ser::NetworkReadExt};
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ const MAX_PAYLOAD_SIZE: usize = 1_048_576;
|
|||||||
pub struct SPluginMessage {
|
pub struct SPluginMessage {
|
||||||
/// The name of the channel used to distinguish different types of messages.
|
/// The name of the channel used to distinguish different types of messages.
|
||||||
/// Example: `minecraft:brand` or `velocity:main`.
|
/// Example: `minecraft:brand` or `velocity:main`.
|
||||||
pub channel: ResourceLocation,
|
pub channel: Box<str>,
|
||||||
/// The payload sent by the client.
|
/// The payload sent by the client.
|
||||||
pub data: Box<[u8]>,
|
pub data: Box<[u8]>,
|
||||||
}
|
}
|
||||||
@ -25,7 +25,7 @@ pub struct SPluginMessage {
|
|||||||
impl ServerPacket for SPluginMessage {
|
impl ServerPacket for SPluginMessage {
|
||||||
fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
|
fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
channel: read.get_string()?,
|
channel: read.get_str()?,
|
||||||
data: read.read_remaining_to_boxed_slice(MAX_PAYLOAD_SIZE)?,
|
data: read.read_remaining_to_boxed_slice(MAX_PAYLOAD_SIZE)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ pub struct SHandShake {
|
|||||||
/// The protocol version of the client (e.g., 767 for 1.21).
|
/// The protocol version of the client (e.g., 767 for 1.21).
|
||||||
pub protocol_version: VarInt,
|
pub protocol_version: VarInt,
|
||||||
/// The hostname or IP used by the client to connect
|
/// The hostname or IP used by the client to connect
|
||||||
pub server_address: String,
|
pub server_address: Box<str>,
|
||||||
/// The port number used by the client to connect
|
/// The port number used by the client to connect
|
||||||
pub server_port: u16,
|
pub server_port: u16,
|
||||||
/// The state the client wants to transition to (1 for Status, 2 for Login)
|
/// The state the client wants to transition to (1 for Status, 2 for Login)
|
||||||
@ -28,7 +28,7 @@ impl ServerPacket for SHandShake {
|
|||||||
fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
|
fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
protocol_version: read.get_var_int()?,
|
protocol_version: read.get_var_int()?,
|
||||||
server_address: read.get_string_bounded(255)?,
|
server_address: read.get_str_bounded(255)?,
|
||||||
server_port: read.get_u16_be()?,
|
server_port: read.get_u16_be()?,
|
||||||
next_state: read
|
next_state: read
|
||||||
.get_var_int()?
|
.get_var_int()?
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use pumpkin_data::packet::serverbound::LOGIN_COOKIE_RESPONSE;
|
use pumpkin_data::packet::serverbound::LOGIN_COOKIE_RESPONSE;
|
||||||
use pumpkin_macros::java_packet;
|
use pumpkin_macros::java_packet;
|
||||||
use pumpkin_util::{resource_location::ResourceLocation, version::JavaMinecraftVersion};
|
use pumpkin_util::version::JavaMinecraftVersion;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -12,7 +12,7 @@ use crate::{
|
|||||||
/// Response to a `CCookieRequest` (login) from the server.
|
/// Response to a `CCookieRequest` (login) from the server.
|
||||||
/// The Notchian server only accepts responses of up to 5 kiB in size.
|
/// The Notchian server only accepts responses of up to 5 kiB in size.
|
||||||
pub struct SLoginCookieResponse {
|
pub struct SLoginCookieResponse {
|
||||||
pub key: ResourceLocation,
|
pub key: Box<str>,
|
||||||
pub payload: Option<Box<[u8]>>, // 5120,
|
pub payload: Option<Box<[u8]>>, // 5120,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ const MAX_COOKIE_LENGTH: usize = 5120;
|
|||||||
|
|
||||||
impl ServerPacket for SLoginCookieResponse {
|
impl ServerPacket for SLoginCookieResponse {
|
||||||
fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
|
fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
|
||||||
let key = read.get_string()?;
|
let key = read.get_str()?;
|
||||||
let has_payload = read.get_bool()?;
|
let has_payload = read.get_bool()?;
|
||||||
|
|
||||||
if !has_payload {
|
if !has_payload {
|
||||||
|
|||||||
@ -13,14 +13,14 @@ use crate::{
|
|||||||
#[java_packet(LOGIN_HELLO)]
|
#[java_packet(LOGIN_HELLO)]
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct SLoginStart {
|
pub struct SLoginStart {
|
||||||
pub name: String, // 16
|
pub name: Box<str>, // 16
|
||||||
pub uuid: uuid::Uuid,
|
pub uuid: uuid::Uuid,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServerPacket for SLoginStart {
|
impl ServerPacket for SLoginStart {
|
||||||
fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
|
fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
name: read.get_string_bounded(16)?,
|
name: read.get_str_bounded(16)?,
|
||||||
uuid: read.get_uuid()?,
|
uuid: read.get_uuid()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,7 @@ use crate::{
|
|||||||
|
|
||||||
#[java_packet(PLAY_CHAT)]
|
#[java_packet(PLAY_CHAT)]
|
||||||
pub struct SChatMessage {
|
pub struct SChatMessage {
|
||||||
pub message: String,
|
pub message: Box<str>,
|
||||||
pub timestamp: i64,
|
pub timestamp: i64,
|
||||||
pub salt: i64,
|
pub salt: i64,
|
||||||
pub signature: Option<Box<[u8]>>,
|
pub signature: Option<Box<[u8]>>,
|
||||||
@ -25,7 +25,7 @@ pub struct SChatMessage {
|
|||||||
impl ServerPacket for SChatMessage {
|
impl ServerPacket for SChatMessage {
|
||||||
fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
|
fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
message: read.get_string_bounded(256)?,
|
message: read.get_str_bounded(256)?,
|
||||||
timestamp: read.get_i64_be()?,
|
timestamp: read.get_i64_be()?,
|
||||||
salt: read.get_i64_be()?,
|
salt: read.get_i64_be()?,
|
||||||
signature: read.get_option(|v| v.read_boxed_slice(256))?,
|
signature: read.get_option(|v| v.read_boxed_slice(256))?,
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use std::io::Read;
|
|||||||
|
|
||||||
use pumpkin_data::packet::serverbound::PLAY_COOKIE_RESPONSE;
|
use pumpkin_data::packet::serverbound::PLAY_COOKIE_RESPONSE;
|
||||||
use pumpkin_macros::java_packet;
|
use pumpkin_macros::java_packet;
|
||||||
use pumpkin_util::{resource_location::ResourceLocation, version::JavaMinecraftVersion};
|
use pumpkin_util::version::JavaMinecraftVersion;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ServerPacket,
|
ServerPacket,
|
||||||
@ -13,7 +13,7 @@ use crate::{
|
|||||||
/// Response to a `CCookieRequest` (play) from the server.
|
/// Response to a `CCookieRequest` (play) from the server.
|
||||||
/// The Notchian (vanilla) server only accepts responses of up to 5 KiB in size.
|
/// The Notchian (vanilla) server only accepts responses of up to 5 KiB in size.
|
||||||
pub struct SCookieResponse {
|
pub struct SCookieResponse {
|
||||||
pub key: ResourceLocation,
|
pub key: Box<str>,
|
||||||
pub payload: Option<Box<[u8]>>, // 5120,
|
pub payload: Option<Box<[u8]>>, // 5120,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ const MAX_COOKIE_LENGTH: usize = 5120;
|
|||||||
|
|
||||||
impl ServerPacket for SCookieResponse {
|
impl ServerPacket for SCookieResponse {
|
||||||
fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
|
fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
|
||||||
let key = read.get_string()?;
|
let key = read.get_str()?;
|
||||||
let has_payload = read.get_bool()?;
|
let has_payload = read.get_bool()?;
|
||||||
|
|
||||||
if !has_payload {
|
if !has_payload {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use std::io::Read;
|
|||||||
|
|
||||||
use pumpkin_data::packet::serverbound::PLAY_CUSTOM_PAYLOAD;
|
use pumpkin_data::packet::serverbound::PLAY_CUSTOM_PAYLOAD;
|
||||||
use pumpkin_macros::java_packet;
|
use pumpkin_macros::java_packet;
|
||||||
use pumpkin_util::{resource_location::ResourceLocation, version::JavaMinecraftVersion};
|
use pumpkin_util::version::JavaMinecraftVersion;
|
||||||
|
|
||||||
use crate::{ReadingError, ServerPacket, ser::NetworkReadExt};
|
use crate::{ReadingError, ServerPacket, ser::NetworkReadExt};
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ const MAX_PAYLOAD_SIZE: usize = 32_767;
|
|||||||
pub struct SCustomPayload {
|
pub struct SCustomPayload {
|
||||||
/// The name of the channel used to distinguish different types of messages.
|
/// The name of the channel used to distinguish different types of messages.
|
||||||
/// Example: `minecraft:brand` or `voicechat:request_secret`.
|
/// Example: `minecraft:brand` or `voicechat:request_secret`.
|
||||||
pub channel: ResourceLocation,
|
pub channel: Box<str>,
|
||||||
/// The payload sent by the client.
|
/// The payload sent by the client.
|
||||||
pub data: Box<[u8]>,
|
pub data: Box<[u8]>,
|
||||||
}
|
}
|
||||||
@ -25,7 +25,7 @@ pub struct SCustomPayload {
|
|||||||
impl ServerPacket for SCustomPayload {
|
impl ServerPacket for SCustomPayload {
|
||||||
fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
|
fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
channel: read.get_string()?,
|
channel: read.get_str()?,
|
||||||
data: read.read_remaining_to_boxed_slice(MAX_PAYLOAD_SIZE)?,
|
data: read.read_remaining_to_boxed_slice(MAX_PAYLOAD_SIZE)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,10 +13,10 @@ use crate::{
|
|||||||
pub struct SUpdateSign {
|
pub struct SUpdateSign {
|
||||||
pub location: BlockPos,
|
pub location: BlockPos,
|
||||||
pub is_front_text: bool,
|
pub is_front_text: bool,
|
||||||
pub line_1: String,
|
pub line_1: Box<str>,
|
||||||
pub line_2: String,
|
pub line_2: Box<str>,
|
||||||
pub line_3: String,
|
pub line_3: Box<str>,
|
||||||
pub line_4: String,
|
pub line_4: Box<str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_LINE_LENGTH: usize = 386;
|
const MAX_LINE_LENGTH: usize = 386;
|
||||||
@ -26,10 +26,10 @@ impl ServerPacket for SUpdateSign {
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
location: BlockPos::from_i64(read.get_i64_be()?),
|
location: BlockPos::from_i64(read.get_i64_be()?),
|
||||||
is_front_text: read.get_bool()?,
|
is_front_text: read.get_bool()?,
|
||||||
line_1: read.get_string_bounded(MAX_LINE_LENGTH)?,
|
line_1: read.get_str_bounded(MAX_LINE_LENGTH)?,
|
||||||
line_2: read.get_string_bounded(MAX_LINE_LENGTH)?,
|
line_2: read.get_str_bounded(MAX_LINE_LENGTH)?,
|
||||||
line_3: read.get_string_bounded(MAX_LINE_LENGTH)?,
|
line_3: read.get_str_bounded(MAX_LINE_LENGTH)?,
|
||||||
line_4: read.get_string_bounded(MAX_LINE_LENGTH)?,
|
line_4: read.get_str_bounded(MAX_LINE_LENGTH)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -418,11 +418,11 @@ pub struct Sample {
|
|||||||
// basically game profile
|
// basically game profile
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct Property {
|
pub struct Property {
|
||||||
pub name: String,
|
pub name: Box<str>,
|
||||||
// base 64
|
// base 64
|
||||||
pub value: String,
|
pub value: Box<str>,
|
||||||
// base 64
|
// base 64
|
||||||
pub signature: Option<String>,
|
pub signature: Option<Box<str>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
|
|||||||
@ -101,7 +101,7 @@ impl<'de, R: Read> de::Deserializer<'de> for &mut Deserializer<R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_string<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
|
fn deserialize_string<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
|
||||||
visitor.visit_str(&self.inner.get_string()?)
|
visitor.visit_str(&self.inner.get_str()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_bytes<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value, Self::Error> {
|
fn deserialize_bytes<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value, Self::Error> {
|
||||||
|
|||||||
@ -60,8 +60,8 @@ pub trait NetworkReadExt {
|
|||||||
fn get_var_uint(&mut self) -> Result<VarUInt, ReadingError>;
|
fn get_var_uint(&mut self) -> Result<VarUInt, ReadingError>;
|
||||||
fn get_var_long(&mut self) -> Result<VarLong, ReadingError>;
|
fn get_var_long(&mut self) -> Result<VarLong, ReadingError>;
|
||||||
fn get_var_ulong(&mut self) -> Result<VarULong, ReadingError>;
|
fn get_var_ulong(&mut self) -> Result<VarULong, ReadingError>;
|
||||||
fn get_string_bounded(&mut self, bound: usize) -> Result<String, ReadingError>;
|
fn get_str_bounded(&mut self, bound: usize) -> Result<Box<str>, ReadingError>;
|
||||||
fn get_string(&mut self) -> Result<String, ReadingError>;
|
fn get_str(&mut self) -> Result<Box<str>, ReadingError>;
|
||||||
fn get_uuid(&mut self) -> Result<uuid::Uuid, ReadingError>;
|
fn get_uuid(&mut self) -> Result<uuid::Uuid, ReadingError>;
|
||||||
fn get_fixed_bitset(&mut self, bits: usize) -> Result<FixedBitSet, ReadingError>;
|
fn get_fixed_bitset(&mut self, bits: usize) -> Result<FixedBitSet, ReadingError>;
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ impl<R: Read> NetworkReadExt for R {
|
|||||||
VarULong::decode(self)
|
VarULong::decode(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_string_bounded(&mut self, bound: usize) -> Result<String, ReadingError> {
|
fn get_str_bounded(&mut self, bound: usize) -> Result<Box<str>, ReadingError> {
|
||||||
let bytes_len = self.get_var_uint()?.0 as usize;
|
let bytes_len = self.get_var_uint()?.0 as usize;
|
||||||
|
|
||||||
// We treat `bound` as the maximum number of Java `char`s allowed.
|
// We treat `bound` as the maximum number of Java `char`s allowed.
|
||||||
@ -170,7 +170,7 @@ impl<R: Read> NetworkReadExt for R {
|
|||||||
|
|
||||||
let data = self.read_boxed_slice(bytes_len)?;
|
let data = self.read_boxed_slice(bytes_len)?;
|
||||||
let string =
|
let string =
|
||||||
String::from_utf8(data.into()).map_err(|e| ReadingError::Message(e.to_string()))?;
|
std::str::from_utf8(&data).map_err(|e| ReadingError::Message(e.to_string()))?;
|
||||||
|
|
||||||
// Next, if we're able to find the (bound + 1)th UTF-16 character, the string is too big.
|
// Next, if we're able to find the (bound + 1)th UTF-16 character, the string is too big.
|
||||||
if string.encode_utf16().nth(bound).is_some() {
|
if string.encode_utf16().nth(bound).is_some() {
|
||||||
@ -179,11 +179,11 @@ impl<R: Read> NetworkReadExt for R {
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(string)
|
Ok(string.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_string(&mut self) -> Result<String, ReadingError> {
|
fn get_str(&mut self) -> Result<Box<str>, ReadingError> {
|
||||||
self.get_string_bounded(i32::MAX as usize)
|
self.get_str_bounded(i32::MAX as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_uuid(&mut self) -> Result<uuid::Uuid, ReadingError> {
|
fn get_uuid(&mut self) -> Result<uuid::Uuid, ReadingError> {
|
||||||
|
|||||||
@ -15,6 +15,7 @@ use std::{
|
|||||||
use crate::text::{TextComponentBase, TextContent, style::Style};
|
use crate::text::{TextComponentBase, TextContent, style::Style};
|
||||||
|
|
||||||
static VANILLA_EN_US_JSON: &str = include_str!("../../assets/en_us_java.json");
|
static VANILLA_EN_US_JSON: &str = include_str!("../../assets/en_us_java.json");
|
||||||
|
static PUMPKIN_EN_US_JSON: &str = include_str!("../../assets/translations/en_us.json");
|
||||||
static PUMPKIN_BRB_JSON: &str = include_str!("../../assets/translations/brb.json");
|
static PUMPKIN_BRB_JSON: &str = include_str!("../../assets/translations/brb.json");
|
||||||
static PUMPKIN_DE_DE_JSON: &str = include_str!("../../assets/translations/de_de.json");
|
static PUMPKIN_DE_DE_JSON: &str = include_str!("../../assets/translations/de_de.json");
|
||||||
static PUMPKIN_ES_ES_JSON: &str = include_str!("../../assets/translations/es_es.json");
|
static PUMPKIN_ES_ES_JSON: &str = include_str!("../../assets/translations/es_es.json");
|
||||||
@ -272,6 +273,8 @@ pub static TRANSLATIONS: LazyLock<Mutex<[HashMap<String, String>; Locale::COUNT]
|
|||||||
std::array::from_fn(|_| HashMap::new());
|
std::array::from_fn(|_| HashMap::new());
|
||||||
let vanilla_en_us: HashMap<String, String> =
|
let vanilla_en_us: HashMap<String, String> =
|
||||||
serde_json::from_str(VANILLA_EN_US_JSON).expect("Could not parse en_us_java.json.");
|
serde_json::from_str(VANILLA_EN_US_JSON).expect("Could not parse en_us_java.json.");
|
||||||
|
let pumpkin_en_us: HashMap<String, String> =
|
||||||
|
serde_json::from_str(PUMPKIN_EN_US_JSON).expect("Could not parse en_us.json.");
|
||||||
let pumpkin_brb: HashMap<String, String> =
|
let pumpkin_brb: HashMap<String, String> =
|
||||||
serde_json::from_str(PUMPKIN_BRB_JSON).expect("Could not parse brb.json.");
|
serde_json::from_str(PUMPKIN_BRB_JSON).expect("Could not parse brb.json.");
|
||||||
let pumpkin_de_de: HashMap<String, String> =
|
let pumpkin_de_de: HashMap<String, String> =
|
||||||
@ -322,6 +325,9 @@ pub static TRANSLATIONS: LazyLock<Mutex<[HashMap<String, String>; Locale::COUNT]
|
|||||||
for (key, value) in vanilla_en_us {
|
for (key, value) in vanilla_en_us {
|
||||||
array[Locale::EnUs as usize].insert(format!("minecraft:{key}"), value);
|
array[Locale::EnUs as usize].insert(format!("minecraft:{key}"), value);
|
||||||
}
|
}
|
||||||
|
for (key, value) in pumpkin_en_us {
|
||||||
|
array[Locale::EnUs as usize].insert(format!("pumpkin:{key}"), value);
|
||||||
|
}
|
||||||
for (key, value) in pumpkin_brb {
|
for (key, value) in pumpkin_brb {
|
||||||
array[Locale::Brb as usize].insert(format!("pumpkin:{key}"), value);
|
array[Locale::Brb as usize].insert(format!("pumpkin:{key}"), value);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use alter_ground::AlterGroundTreeDecorator;
|
use alter_ground::AlterGroundTreeDecorator;
|
||||||
use attached_to_leaves::AttachedToLeavesTreeDecorator;
|
use attached_to_leaves::AttachedToLeavesTreeDecorator;
|
||||||
@ -63,22 +65,24 @@ impl TreeDecorator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn get_leaf_litter_positions(
|
pub(super) fn get_leaf_litter_positions<'a>(
|
||||||
root_positions: &[BlockPos],
|
root_positions: &'a [BlockPos],
|
||||||
log_positions: &[BlockPos],
|
log_positions: &'a [BlockPos],
|
||||||
) -> Vec<BlockPos> {
|
) -> Cow<'a, [BlockPos]> {
|
||||||
if root_positions.is_empty() {
|
if root_positions.is_empty() {
|
||||||
return log_positions.to_vec();
|
return Cow::Borrowed(log_positions);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let (Some(root), Some(log)) = (root_positions.first(), log_positions.first())
|
if log_positions
|
||||||
&& root.0.y == log.0.y
|
.first()
|
||||||
|
.is_some_and(|log| root_positions[0].0.y == log.0.y)
|
||||||
{
|
{
|
||||||
let mut list = Vec::with_capacity(root_positions.len() + log_positions.len());
|
let mut list = Vec::with_capacity(root_positions.len() + log_positions.len());
|
||||||
list.extend_from_slice(log_positions);
|
list.extend_from_slice(log_positions);
|
||||||
list.extend_from_slice(root_positions);
|
list.extend_from_slice(root_positions);
|
||||||
return list;
|
return Cow::Owned(list);
|
||||||
}
|
}
|
||||||
root_positions.to_vec()
|
|
||||||
|
Cow::Borrowed(root_positions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@ impl PlaceOnGroundTreeDecorator {
|
|||||||
let mut l = pos.0.z;
|
let mut l = pos.0.z;
|
||||||
let mut m = pos.0.z;
|
let mut m = pos.0.z;
|
||||||
|
|
||||||
for block_pos_2 in list {
|
for block_pos_2 in list.iter() {
|
||||||
if block_pos_2.0.y != i {
|
if block_pos_2.0.y != i {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -121,7 +121,7 @@ pub struct SignBlockEntity {
|
|||||||
pub struct Text {
|
pub struct Text {
|
||||||
pub has_glowing_text: AtomicBool,
|
pub has_glowing_text: AtomicBool,
|
||||||
color: AtomicI8,
|
color: AtomicI8,
|
||||||
pub messages: Arc<std::sync::Mutex<[String; 4]>>,
|
pub messages: Arc<std::sync::Mutex<[Box<str>; 4]>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for Text {
|
impl Clone for Text {
|
||||||
@ -160,7 +160,7 @@ impl From<Text> for NbtTag {
|
|||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| Self::String(s.clone().into()))
|
.map(|s| Self::String(s.clone()))
|
||||||
.collect(),
|
.collect(),
|
||||||
);
|
);
|
||||||
Self::Compound(nbt)
|
Self::Compound(nbt)
|
||||||
@ -173,28 +173,30 @@ impl From<NbtTag> for Text {
|
|||||||
let nbt = tag.extract_compound().unwrap();
|
let nbt = tag.extract_compound().unwrap();
|
||||||
let has_glowing_text = nbt.get_bool("has_glowing_text").unwrap_or(false);
|
let has_glowing_text = nbt.get_bool("has_glowing_text").unwrap_or(false);
|
||||||
let color = nbt.get_string("color").unwrap();
|
let color = nbt.get_string("color").unwrap();
|
||||||
let messages: Vec<String> = nbt
|
let messages: Vec<Box<str>> = nbt
|
||||||
.get_list("messages")
|
.get_list("messages")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|tag| tag.extract_string().map(std::string::ToString::to_string))
|
.filter_map(|tag| tag.extract_string().map(Box::from))
|
||||||
.collect();
|
.collect();
|
||||||
|
let get_message =
|
||||||
|
|i: usize| -> Box<str> { messages.get(i).cloned().unwrap_or_else(|| Box::from("")) };
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
has_glowing_text: AtomicBool::new(has_glowing_text),
|
has_glowing_text: AtomicBool::new(has_glowing_text),
|
||||||
color: AtomicI8::new(DyeColor::from(color) as i8),
|
color: AtomicI8::new(DyeColor::from(color) as i8),
|
||||||
messages: Arc::new(std::sync::Mutex::new([
|
messages: Arc::new(std::sync::Mutex::new([
|
||||||
// its important that we use unwrap_or since otherwise we may crash on older versions
|
get_message(0),
|
||||||
messages.first().unwrap_or(&String::new()).clone(),
|
get_message(1),
|
||||||
messages.get(1).unwrap_or(&String::new()).clone(),
|
get_message(2),
|
||||||
messages.get(2).unwrap_or(&String::new()).clone(),
|
get_message(3),
|
||||||
messages.get(3).unwrap_or(&String::new()).clone(),
|
|
||||||
])),
|
])),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Text {
|
impl Text {
|
||||||
fn new(messages: [String; 4]) -> Self {
|
fn new(messages: [Box<str>; 4]) -> Self {
|
||||||
Self {
|
Self {
|
||||||
has_glowing_text: AtomicBool::new(false),
|
has_glowing_text: AtomicBool::new(false),
|
||||||
color: AtomicI8::new(DyeColor::default() as i8),
|
color: AtomicI8::new(DyeColor::default() as i8),
|
||||||
@ -263,7 +265,7 @@ impl BlockEntity for SignBlockEntity {
|
|||||||
impl SignBlockEntity {
|
impl SignBlockEntity {
|
||||||
pub const ID: &'static str = "minecraft:sign";
|
pub const ID: &'static str = "minecraft:sign";
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(position: BlockPos, is_front: bool, messages: [String; 4]) -> Self {
|
pub fn new(position: BlockPos, is_front: bool, messages: [Box<str>; 4]) -> Self {
|
||||||
Self {
|
Self {
|
||||||
position,
|
position,
|
||||||
is_waxed: AtomicBool::new(false),
|
is_waxed: AtomicBool::new(false),
|
||||||
|
|||||||
@ -9,6 +9,7 @@ use crate::net::java::{JavaClient, PacketHandlerResult};
|
|||||||
use crate::net::{ClientPlatform, DisconnectReason};
|
use crate::net::{ClientPlatform, DisconnectReason};
|
||||||
use crate::net::{lan_broadcast::LANBroadcast, query, rcon::RCONServer};
|
use crate::net::{lan_broadcast::LANBroadcast, query, rcon::RCONServer};
|
||||||
use crate::server::{Server, ticker::Ticker};
|
use crate::server::{Server, ticker::Ticker};
|
||||||
|
use bytes::BytesMut;
|
||||||
use plugin::server::server_command::ServerCommandEvent;
|
use plugin::server::server_command::ServerCommandEvent;
|
||||||
use pumpkin_config::{AdvancedConfiguration, BasicConfiguration};
|
use pumpkin_config::{AdvancedConfiguration, BasicConfiguration};
|
||||||
use pumpkin_macros::send_cancellable;
|
use pumpkin_macros::send_cancellable;
|
||||||
@ -18,7 +19,7 @@ use rustyline::Editor;
|
|||||||
use rustyline::history::FileHistory;
|
use rustyline::history::FileHistory;
|
||||||
use rustyline::{Config, error::ReadlineError};
|
use rustyline::{Config, error::ReadlineError};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::{Cursor, ErrorKind, IsTerminal, stdin};
|
use std::io::{ErrorKind, IsTerminal, stdin};
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::atomic::{AtomicBool, AtomicI32, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicI32, Ordering};
|
||||||
@ -418,14 +419,13 @@ impl PumpkinServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[expect(clippy::too_many_lines)]
|
|
||||||
pub async fn unified_listener_task(
|
pub async fn unified_listener_task(
|
||||||
&self,
|
&self,
|
||||||
master_client_id_counter: &mut u64,
|
master_client_id_counter: &mut u64,
|
||||||
tasks: &Arc<TaskTracker>,
|
tasks: &Arc<TaskTracker>,
|
||||||
bedrock_clients: &Arc<Mutex<HashMap<SocketAddr, Arc<BedrockClient>>>>,
|
bedrock_clients: &Arc<Mutex<HashMap<SocketAddr, Arc<BedrockClient>>>>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut udp_buf = [0; 1496]; // Buffer for UDP receive
|
let mut udp_buf = BytesMut::with_capacity(1496);
|
||||||
|
|
||||||
select! {
|
select! {
|
||||||
// Branch for TCP connections (Java Edition)
|
// Branch for TCP connections (Java Edition)
|
||||||
@ -491,7 +491,10 @@ impl PumpkinServer {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Branch for UDP packets (Bedrock Edition)
|
// Branch for UDP packets (Bedrock Edition)
|
||||||
udp_result = resolve_some(self.udp_socket.as_ref(), |sock: &Arc<UdpSocket>| sock.recv_from(&mut udp_buf)) => {
|
udp_result = resolve_some(self.udp_socket.as_ref(), |sock: &Arc<UdpSocket>| {
|
||||||
|
unsafe { udp_buf.set_len(1496) };
|
||||||
|
sock.recv_from(&mut udp_buf[..])
|
||||||
|
}) => {
|
||||||
match udp_result {
|
match udp_result {
|
||||||
Ok((len, client_addr)) => {
|
Ok((len, client_addr)) => {
|
||||||
if len > 0 {
|
if len > 0 {
|
||||||
@ -515,25 +518,20 @@ impl PumpkinServer {
|
|||||||
new_client
|
new_client
|
||||||
}).clone();
|
}).clone();
|
||||||
|
|
||||||
let reader = udp_buf[..len].to_vec();
|
let packet_bytes = udp_buf.split_to(len).freeze();
|
||||||
|
udp_buf.clear();
|
||||||
let server = self.server.clone();
|
let server = self.server.clone();
|
||||||
tasks.spawn(async move {
|
|
||||||
client.process_packet(&server, reader).await;
|
|
||||||
});
|
|
||||||
|
|
||||||
} else if let Some(sock) = self.udp_socket.as_ref() {
|
tasks.spawn(async move {
|
||||||
let _ = BedrockClient::handle_offline_packet(
|
client.process_packet(&server, packet_bytes).await;
|
||||||
&self.server,
|
});
|
||||||
id,
|
|
||||||
&mut Cursor::new(&udp_buf[1..len]),
|
|
||||||
client_addr,
|
|
||||||
sock
|
|
||||||
).await;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => error!("UDP socket error: {e}"),
|
Err(e) => {
|
||||||
}
|
error!("Failed to receive UDP packet: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Branch for the global stop signal
|
// Branch for the global stop signal
|
||||||
|
|||||||
@ -106,7 +106,7 @@ pub fn authenticate(
|
|||||||
|
|
||||||
pub fn validate_textures(property: &Property, config: &TextureConfig) -> Result<(), TextureError> {
|
pub fn validate_textures(property: &Property, config: &TextureConfig) -> Result<(), TextureError> {
|
||||||
let from64 = general_purpose::STANDARD
|
let from64 = general_purpose::STANDARD
|
||||||
.decode(&property.value)
|
.decode(property.value.as_bytes())
|
||||||
.map_err(|e| TextureError::DecodeError(e.to_string()))?;
|
.map_err(|e| TextureError::DecodeError(e.to_string()))?;
|
||||||
let textures: ProfileTextures =
|
let textures: ProfileTextures =
|
||||||
serde_json::from_slice(&from64).map_err(|e| TextureError::JSONError(e.to_string()))?;
|
serde_json::from_slice(&from64).map_err(|e| TextureError::JSONError(e.to_string()))?;
|
||||||
|
|||||||
@ -229,7 +229,7 @@ impl BedrockClient {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn process_packet(self: &Arc<Self>, server: &Arc<Server>, packet: Vec<u8>) {
|
pub async fn process_packet(self: &Arc<Self>, server: &Arc<Server>, packet: Bytes) {
|
||||||
self.last_seen.store(std::time::Instant::now());
|
self.last_seen.store(std::time::Instant::now());
|
||||||
if let Err(error) = self.handle_packet_payload(server, packet).await {
|
if let Err(error) = self.handle_packet_payload(server, packet).await {
|
||||||
error!(
|
error!(
|
||||||
@ -501,7 +501,7 @@ impl BedrockClient {
|
|||||||
pub async fn handle_packet_payload(
|
pub async fn handle_packet_payload(
|
||||||
self: &Arc<Self>,
|
self: &Arc<Self>,
|
||||||
server: &Arc<Server>,
|
server: &Arc<Server>,
|
||||||
packet: Vec<u8>,
|
packet: Bytes,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let reader = &mut Cursor::new(packet);
|
let reader = &mut Cursor::new(packet);
|
||||||
|
|
||||||
|
|||||||
@ -61,7 +61,7 @@ impl JavaClient {
|
|||||||
match bungeecord::bungeecord_login(
|
match bungeecord::bungeecord_login(
|
||||||
&self.address,
|
&self.address,
|
||||||
&self.server_address.lock().await,
|
&self.server_address.lock().await,
|
||||||
login_start.name,
|
login_start.name.into_string(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@ -82,7 +82,7 @@ impl JavaClient {
|
|||||||
|
|
||||||
let profile = GameProfile {
|
let profile = GameProfile {
|
||||||
id,
|
id,
|
||||||
name: login_start.name,
|
name: login_start.name.into_string(),
|
||||||
properties: ArcSwap::new(Arc::new(vec![])),
|
properties: ArcSwap::new(Arc::new(vec![])),
|
||||||
profile_actions: None,
|
profile_actions: None,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -76,7 +76,7 @@ pub struct JavaClient {
|
|||||||
/// The client's configuration settings, Optional
|
/// The client's configuration settings, Optional
|
||||||
pub config: Mutex<Option<PlayerConfig>>,
|
pub config: Mutex<Option<PlayerConfig>>,
|
||||||
/// The Address used to connect to the Server, Send in the Handshake
|
/// The Address used to connect to the Server, Send in the Handshake
|
||||||
pub server_address: Mutex<String>,
|
pub server_address: Mutex<Box<str>>,
|
||||||
/// The current connection state of the client (e.g., Handshaking, Status, Play).
|
/// The current connection state of the client (e.g., Handshaking, Status, Play).
|
||||||
pub connection_state: AtomicCell<ConnectionState>,
|
pub connection_state: AtomicCell<ConnectionState>,
|
||||||
/// The client's IP address.
|
/// The client's IP address.
|
||||||
@ -138,7 +138,7 @@ impl JavaClient {
|
|||||||
id,
|
id,
|
||||||
gameprofile: Mutex::new(None),
|
gameprofile: Mutex::new(None),
|
||||||
config: Mutex::new(None),
|
config: Mutex::new(None),
|
||||||
server_address: Mutex::new(String::new()),
|
server_address: Mutex::new("".into()),
|
||||||
address: Mutex::new(address),
|
address: Mutex::new(address),
|
||||||
connection_state: AtomicCell::new(ConnectionState::HandShake),
|
connection_state: AtomicCell::new(ConnectionState::HandShake),
|
||||||
close_token: CancellationToken::new(),
|
close_token: CancellationToken::new(),
|
||||||
@ -921,7 +921,7 @@ impl JavaClient {
|
|||||||
let payload = SCustomPayload::read(payload, &version)?;
|
let payload = SCustomPayload::read(payload, &version)?;
|
||||||
let event = PlayerCustomPayloadEvent::new(
|
let event = PlayerCustomPayloadEvent::new(
|
||||||
player.clone(),
|
player.clone(),
|
||||||
payload.channel,
|
payload.channel.to_string(),
|
||||||
Bytes::from(payload.data),
|
Bytes::from(payload.data),
|
||||||
);
|
);
|
||||||
server.plugin_manager.fire(event).await;
|
server.plugin_manager.fire(event).await;
|
||||||
|
|||||||
@ -1211,7 +1211,7 @@ impl JavaClient {
|
|||||||
|
|
||||||
send_cancellable! {{
|
send_cancellable! {{
|
||||||
server;
|
server;
|
||||||
PlayerChatEvent::new(player.clone(), chat_message.message.clone(), vec![]);
|
PlayerChatEvent::new(player.clone(), chat_message.message.to_string(), vec![]);
|
||||||
|
|
||||||
'after: {
|
'after: {
|
||||||
info!("<chat> {}: {}", gameprofile.name, event.message);
|
info!("<chat> {}: {}", gameprofile.name, event.message);
|
||||||
|
|||||||
@ -80,14 +80,14 @@ fn read_game_profile(read: impl Read) -> Result<GameProfile, VelocityError> {
|
|||||||
.map_err(|_| VelocityError::FailedReadProfileUUID)?;
|
.map_err(|_| VelocityError::FailedReadProfileUUID)?;
|
||||||
|
|
||||||
let name = read
|
let name = read
|
||||||
.get_string()
|
.get_str()
|
||||||
.map_err(|_| VelocityError::FailedReadProfileName)?;
|
.map_err(|_| VelocityError::FailedReadProfileName)?;
|
||||||
|
|
||||||
let properties = read
|
let properties = read
|
||||||
.get_list(|data| {
|
.get_list(|data| {
|
||||||
let name = data.get_string()?;
|
let name = data.get_str()?;
|
||||||
let value = data.get_string()?;
|
let value = data.get_str()?;
|
||||||
let signature = data.get_option(NetworkReadExt::get_string)?;
|
let signature = data.get_option(NetworkReadExt::get_str)?;
|
||||||
|
|
||||||
Ok(Property {
|
Ok(Property {
|
||||||
name,
|
name,
|
||||||
@ -99,7 +99,7 @@ fn read_game_profile(read: impl Read) -> Result<GameProfile, VelocityError> {
|
|||||||
|
|
||||||
Ok(GameProfile {
|
Ok(GameProfile {
|
||||||
id,
|
id,
|
||||||
name,
|
name: name.into_string(),
|
||||||
properties: ArcSwap::new(Arc::from(properties)),
|
properties: ArcSwap::new(Arc::from(properties)),
|
||||||
profile_actions: None,
|
profile_actions: None,
|
||||||
})
|
})
|
||||||
@ -131,7 +131,7 @@ pub fn receive_velocity_plugin_response(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
let addr = data_without_signature
|
let addr = data_without_signature
|
||||||
.get_string()
|
.get_str()
|
||||||
.map_err(|_| VelocityError::FailedReadAddress)?;
|
.map_err(|_| VelocityError::FailedReadAddress)?;
|
||||||
|
|
||||||
let socket_addr: SocketAddr = SocketAddr::new(
|
let socket_addr: SocketAddr = SocketAddr::new(
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
use std::string::FromUtf8Error;
|
|
||||||
|
|
||||||
use bytes::{BufMut, BytesMut};
|
use bytes::{BufMut, BytesMut};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
@ -60,7 +58,7 @@ pub enum PacketError {
|
|||||||
#[error("Missing packet lull terminator")]
|
#[error("Missing packet lull terminator")]
|
||||||
MissingNullTerminator,
|
MissingNullTerminator,
|
||||||
#[error("Invalid packet string body")]
|
#[error("Invalid packet string body")]
|
||||||
InvalidBody(FromUtf8Error),
|
InvalidBody(std::str::Utf8Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -68,7 +66,7 @@ pub enum PacketError {
|
|||||||
pub struct Packet {
|
pub struct Packet {
|
||||||
id: i32,
|
id: i32,
|
||||||
ptype: ServerboundPacket,
|
ptype: ServerboundPacket,
|
||||||
body: String,
|
body: Box<str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Packet {
|
impl Packet {
|
||||||
@ -110,8 +108,9 @@ impl Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let payload = &incoming[body_start..body_end];
|
let payload = &incoming[body_start..body_end];
|
||||||
let body = String::from_utf8(payload.to_vec()).map_err(PacketError::InvalidBody)?;
|
let body = std::str::from_utf8(payload)
|
||||||
|
.map_err(PacketError::InvalidBody)?
|
||||||
|
.into();
|
||||||
incoming.drain(0..total_packet_len);
|
incoming.drain(0..total_packet_len);
|
||||||
|
|
||||||
Ok(Some(Self {
|
Ok(Some(Self {
|
||||||
|
|||||||
@ -82,7 +82,13 @@ const fn to_wasm_dye_color(color: InternalDyeColor) -> DyeColor {
|
|||||||
|
|
||||||
fn to_wasm_sign_text(text: &InternalText) -> SignText {
|
fn to_wasm_sign_text(text: &InternalText) -> SignText {
|
||||||
SignText {
|
SignText {
|
||||||
messages: text.messages.lock().unwrap().to_vec(),
|
messages: text
|
||||||
|
.messages
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.clone()
|
||||||
|
.map(str::into_string)
|
||||||
|
.to_vec(),
|
||||||
color: to_wasm_dye_color(text.get_color()),
|
color: to_wasm_dye_color(text.get_color()),
|
||||||
has_glowing_text: text
|
has_glowing_text: text
|
||||||
.has_glowing_text
|
.has_glowing_text
|
||||||
|
|||||||
@ -1326,10 +1326,10 @@ impl pumpkin::plugin::player::HostPlayer for PluginHostState {
|
|||||||
.properties
|
.properties
|
||||||
.load()
|
.load()
|
||||||
.iter()
|
.iter()
|
||||||
.find(|p| p.name == "textures")
|
.find(|p| p.name.as_ref() == "textures")
|
||||||
.map(|p| PlayerSkin {
|
.map(|p| PlayerSkin {
|
||||||
value: p.value.clone(),
|
value: p.value.to_string(),
|
||||||
signature: p.signature.clone(),
|
signature: p.signature.as_ref().map(std::string::ToString::to_string),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1341,11 +1341,11 @@ impl pumpkin::plugin::player::HostPlayer for PluginHostState {
|
|||||||
let player = player_from_resource(self, &player)?;
|
let player = player_from_resource(self, &player)?;
|
||||||
let mut properties = (**player.gameprofile.properties.load()).clone();
|
let mut properties = (**player.gameprofile.properties.load()).clone();
|
||||||
|
|
||||||
properties.retain(|p| p.name != "textures");
|
properties.retain(|p| p.name.as_ref() != "textures");
|
||||||
properties.push(Property {
|
properties.push(Property {
|
||||||
name: "textures".into(),
|
name: "textures".into(),
|
||||||
value: skin.value,
|
value: skin.value.into(),
|
||||||
signature: skin.signature,
|
signature: skin.signature.map(std::convert::Into::into),
|
||||||
});
|
});
|
||||||
|
|
||||||
player.gameprofile.properties.store(Arc::new(properties));
|
player.gameprofile.properties.store(Arc::new(properties));
|
||||||
@ -1509,7 +1509,7 @@ impl pumpkin::plugin::player::HostJavaPlayer for PluginHostState {
|
|||||||
.client
|
.client
|
||||||
.java()
|
.java()
|
||||||
.ok_or_else(|| wasmtime::Error::msg("Not a java player"))?;
|
.ok_or_else(|| wasmtime::Error::msg("Not a java player"))?;
|
||||||
Ok(client.server_address.lock().await.clone())
|
Ok(client.server_address.lock().await.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_settings(
|
async fn get_settings(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user