fix: ci
This commit is contained in:
parent
29bc796d62
commit
5ef9648362
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -3579,6 +3579,7 @@ dependencies = [
|
|||||||
"pumpkin-util",
|
"pumpkin-util",
|
||||||
"pumpkin-world",
|
"pumpkin-world",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"thiserror 2.0.20",
|
"thiserror 2.0.20",
|
||||||
"tokio",
|
"tokio",
|
||||||
"uuid",
|
"uuid",
|
||||||
|
|||||||
@ -33,7 +33,7 @@ impl Registry {
|
|||||||
pub fn get_synced(version: JavaMinecraftVersion) -> Vec<Self> {
|
pub fn get_synced(version: JavaMinecraftVersion) -> Vec<Self> {
|
||||||
#[allow(clippy::match_same_arms)]
|
#[allow(clippy::match_same_arms)]
|
||||||
let static_regs = match version {
|
let static_regs = match version {
|
||||||
pumpkin_util::version::JavaMinecraftVersion::V_1_20_5 => REGISTRY_V_1_20_5,
|
v if v <= pumpkin_util::version::JavaMinecraftVersion::V_1_20_5 => REGISTRY_V_1_20_5,
|
||||||
pumpkin_util::version::JavaMinecraftVersion::V_1_21 => REGISTRY_V_1_21,
|
pumpkin_util::version::JavaMinecraftVersion::V_1_21 => REGISTRY_V_1_21,
|
||||||
pumpkin_util::version::JavaMinecraftVersion::V_1_21_2 => REGISTRY_V_1_21_2,
|
pumpkin_util::version::JavaMinecraftVersion::V_1_21_2 => REGISTRY_V_1_21_2,
|
||||||
pumpkin_util::version::JavaMinecraftVersion::V_1_21_4 => REGISTRY_V_1_21_4,
|
pumpkin_util::version::JavaMinecraftVersion::V_1_21_4 => REGISTRY_V_1_21_4,
|
||||||
@ -43,8 +43,7 @@ impl Registry {
|
|||||||
pumpkin_util::version::JavaMinecraftVersion::V_1_21_9 => REGISTRY_V_1_21_9,
|
pumpkin_util::version::JavaMinecraftVersion::V_1_21_9 => REGISTRY_V_1_21_9,
|
||||||
pumpkin_util::version::JavaMinecraftVersion::V_1_21_11 => REGISTRY_V_1_21_11,
|
pumpkin_util::version::JavaMinecraftVersion::V_1_21_11 => REGISTRY_V_1_21_11,
|
||||||
pumpkin_util::version::JavaMinecraftVersion::V_26_1 => REGISTRY_V_26_1,
|
pumpkin_util::version::JavaMinecraftVersion::V_26_1 => REGISTRY_V_26_1,
|
||||||
pumpkin_util::version::JavaMinecraftVersion::V_26_2 => REGISTRY_V_26_2,
|
pumpkin_util::version::JavaMinecraftVersion::V_26_2 | _ => REGISTRY_V_26_2,
|
||||||
_ => REGISTRY_V_26_2,
|
|
||||||
};
|
};
|
||||||
static_regs
|
static_regs
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@ -18,6 +18,7 @@ pumpkin-macros.workspace = true
|
|||||||
pumpkin-world.workspace = true
|
pumpkin-world.workspace = true
|
||||||
pumpkin-util.workspace = true
|
pumpkin-util.workspace = true
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
|
serde_json.workspace = true
|
||||||
|
|
||||||
uuid.workspace = true
|
uuid.workspace = true
|
||||||
thiserror.workspace = true
|
thiserror.workspace = true
|
||||||
|
|||||||
@ -53,7 +53,7 @@ impl ClientPacket for CEncryptionRequest<'_> {
|
|||||||
write.write_all(self.public_key)?;
|
write.write_all(self.public_key)?;
|
||||||
write.write_var_int(&crate::VarInt(self.verify_token.len() as i32))?;
|
write.write_var_int(&crate::VarInt(self.verify_token.len() as i32))?;
|
||||||
write.write_all(self.verify_token)?;
|
write.write_all(self.verify_token)?;
|
||||||
if version >= &JavaMinecraftVersion::V_1_19 {
|
if version >= &JavaMinecraftVersion::V_1_20_5 {
|
||||||
write.write_bool(self.should_authenticate)?;
|
write.write_bool(self.should_authenticate)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -71,7 +71,7 @@ impl<'a> crate::ServerPacket<'a> for CEncryptionRequest<'a> {
|
|||||||
let public_key = read.read_slice_borrowed(public_key_len)?;
|
let public_key = read.read_slice_borrowed(public_key_len)?;
|
||||||
let verify_token_len = read.get_var_int()?.0 as usize;
|
let verify_token_len = read.get_var_int()?.0 as usize;
|
||||||
let verify_token = read.read_slice_borrowed(verify_token_len)?;
|
let verify_token = read.read_slice_borrowed(verify_token_len)?;
|
||||||
let should_authenticate = if version >= &JavaMinecraftVersion::V_1_19 {
|
let should_authenticate = if version >= &JavaMinecraftVersion::V_1_20_5 {
|
||||||
read.get_bool()?
|
read.get_bool()?
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
|
|||||||
@ -66,12 +66,12 @@ impl ClientPacket for CLoginSuccess<'_> {
|
|||||||
if version >= &JavaMinecraftVersion::V_1_19 {
|
if version >= &JavaMinecraftVersion::V_1_19 {
|
||||||
write.write_list(self.properties, |write, property| property.write(write))?;
|
write.write_list(self.properties, |write, property| property.write(write))?;
|
||||||
}
|
}
|
||||||
if version >= &JavaMinecraftVersion::V_1_20_2 && version < &JavaMinecraftVersion::V_1_21_2 {
|
|
||||||
write.write_bool(self.strict_error_handling)?;
|
|
||||||
}
|
|
||||||
if version >= &JavaMinecraftVersion::V_26_2 {
|
if version >= &JavaMinecraftVersion::V_26_2 {
|
||||||
write.write_uuid(&self.session_id)?;
|
write.write_uuid(&self.session_id)?;
|
||||||
}
|
}
|
||||||
|
if version >= &JavaMinecraftVersion::V_1_20_5 && version < &JavaMinecraftVersion::V_1_21_2 {
|
||||||
|
write.write_bool(self.strict_error_handling)?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,9 +29,14 @@ impl ClientPacket for CPlayDisconnect<'_> {
|
|||||||
fn write_packet_data(
|
fn write_packet_data(
|
||||||
&self,
|
&self,
|
||||||
mut write: impl std::io::Write,
|
mut write: impl std::io::Write,
|
||||||
_version: &JavaMinecraftVersion,
|
version: &JavaMinecraftVersion,
|
||||||
) -> Result<(), crate::ser::WritingError> {
|
) -> Result<(), crate::ser::WritingError> {
|
||||||
|
if version < &JavaMinecraftVersion::V_1_20_5 {
|
||||||
|
let json = serde_json::to_string(&self.reason.0).unwrap_or_default();
|
||||||
|
write.write_string(&json)?;
|
||||||
|
} else {
|
||||||
write.write_slice(&self.reason.encode())?;
|
write.write_slice(&self.reason.encode())?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
use crate::ClientPacket;
|
use crate::ClientPacket;
|
||||||
use crate::VarInt;
|
use crate::VarInt;
|
||||||
|
use crate::packet::MultiVersionJavaPacket;
|
||||||
use crate::ser::NetworkWriteExt;
|
use crate::ser::NetworkWriteExt;
|
||||||
use pumpkin_data::packet::clientbound::PLAY_ENTITY_POSITION_SYNC;
|
use pumpkin_data::packet::clientbound::{PLAY_ENTITY_POSITION_SYNC, PLAY_TELEPORT_ENTITY};
|
||||||
use pumpkin_macros::java_packet;
|
|
||||||
use pumpkin_util::math::vector3::Vector3;
|
use pumpkin_util::math::vector3::Vector3;
|
||||||
use pumpkin_util::version::JavaMinecraftVersion;
|
use pumpkin_util::version::JavaMinecraftVersion;
|
||||||
|
|
||||||
@ -14,7 +14,6 @@ use pumpkin_util::version::JavaMinecraftVersion;
|
|||||||
///
|
///
|
||||||
/// Note: This packet must NOT be used for the player receiving the packet or
|
/// Note: This packet must NOT be used for the player receiving the packet or
|
||||||
/// any entity the player is currently riding.
|
/// any entity the player is currently riding.
|
||||||
#[java_packet(PLAY_ENTITY_POSITION_SYNC)]
|
|
||||||
pub struct CEntityPositionSync {
|
pub struct CEntityPositionSync {
|
||||||
/// The Entity ID of the entity being moved.
|
/// The Entity ID of the entity being moved.
|
||||||
pub entity_id: VarInt,
|
pub entity_id: VarInt,
|
||||||
@ -52,21 +51,36 @@ impl CEntityPositionSync {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl MultiVersionJavaPacket for CEntityPositionSync {
|
||||||
|
fn to_id(version: JavaMinecraftVersion) -> i32 {
|
||||||
|
if version >= JavaMinecraftVersion::V_1_21_2 {
|
||||||
|
PLAY_ENTITY_POSITION_SYNC.to_id(version)
|
||||||
|
} else {
|
||||||
|
PLAY_TELEPORT_ENTITY.to_id(version)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ClientPacket for CEntityPositionSync {
|
impl ClientPacket for CEntityPositionSync {
|
||||||
fn write_packet_data(
|
fn write_packet_data(
|
||||||
&self,
|
&self,
|
||||||
mut write: impl std::io::Write,
|
mut write: impl std::io::Write,
|
||||||
_version: &JavaMinecraftVersion,
|
version: &JavaMinecraftVersion,
|
||||||
) -> Result<(), crate::ser::WritingError> {
|
) -> Result<(), crate::ser::WritingError> {
|
||||||
write.write_var_int(&self.entity_id)?;
|
write.write_var_int(&self.entity_id)?;
|
||||||
write.write_f64(self.position.x)?;
|
write.write_f64_be(self.position.x)?;
|
||||||
write.write_f64(self.position.y)?;
|
write.write_f64_be(self.position.y)?;
|
||||||
write.write_f64(self.position.z)?;
|
write.write_f64_be(self.position.z)?;
|
||||||
write.write_f64(self.delta.x)?;
|
if version >= &JavaMinecraftVersion::V_1_21_2 {
|
||||||
write.write_f64(self.delta.y)?;
|
write.write_f64_be(self.delta.x)?;
|
||||||
write.write_f64(self.delta.z)?;
|
write.write_f64_be(self.delta.y)?;
|
||||||
write.write_f32(self.yaw)?;
|
write.write_f64_be(self.delta.z)?;
|
||||||
write.write_f32(self.pitch)?;
|
write.write_f32_be(self.yaw)?;
|
||||||
|
write.write_f32_be(self.pitch)?;
|
||||||
|
} else {
|
||||||
|
write.write_u8((self.yaw.rem_euclid(360.0) * 256.0 / 360.0).floor() as u8)?;
|
||||||
|
write.write_u8((self.pitch.rem_euclid(360.0) * 256.0 / 360.0).floor() as u8)?;
|
||||||
|
}
|
||||||
write.write_bool(self.on_ground)?;
|
write.write_bool(self.on_ground)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -73,12 +73,111 @@ impl<'a> CLogin<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn build_v1_20_registry_codec(
|
||||||
|
version: JavaMinecraftVersion,
|
||||||
|
) -> pumpkin_nbt::compound::NbtCompound {
|
||||||
|
use pumpkin_nbt::compound::NbtCompound;
|
||||||
|
use pumpkin_nbt::deserializer::NbtReadHelperJava;
|
||||||
|
use pumpkin_nbt::tag::NbtTag;
|
||||||
|
use std::io::Cursor;
|
||||||
|
|
||||||
|
let mut root = NbtCompound::new();
|
||||||
|
let synced = pumpkin_data::registry::Registry::get_synced(version);
|
||||||
|
|
||||||
|
for reg in synced {
|
||||||
|
let reg_name = if let Some(suffix) = reg.registry_id.strip_prefix("minecraft:") {
|
||||||
|
suffix
|
||||||
|
} else {
|
||||||
|
®.registry_id
|
||||||
|
};
|
||||||
|
if version < JavaMinecraftVersion::V_1_20_2
|
||||||
|
&& !matches!(
|
||||||
|
reg_name,
|
||||||
|
"dimension_type"
|
||||||
|
| "worldgen/biome"
|
||||||
|
| "chat_type"
|
||||||
|
| "damage_type"
|
||||||
|
| "trim_pattern"
|
||||||
|
| "trim_material"
|
||||||
|
)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut reg_compound = NbtCompound::new();
|
||||||
|
let reg_type = if reg.registry_id.contains(':') {
|
||||||
|
reg.registry_id.clone()
|
||||||
|
} else {
|
||||||
|
format!("minecraft:{}", reg.registry_id)
|
||||||
|
};
|
||||||
|
reg_compound.put("type", NbtTag::String(reg_type.clone().into()));
|
||||||
|
|
||||||
|
let mut values_list = Vec::new();
|
||||||
|
for (i, entry) in reg.registry_entries.iter().enumerate() {
|
||||||
|
let mut entry_compound = NbtCompound::new();
|
||||||
|
entry_compound.put("name", NbtTag::String(entry.entry_id.clone().into()));
|
||||||
|
entry_compound.put("id", NbtTag::Int(i as i32));
|
||||||
|
|
||||||
|
if let Some(ref data) = entry.data {
|
||||||
|
let mut cursor = Cursor::new(&data[..]);
|
||||||
|
let mut reader = NbtReadHelperJava::new(&mut cursor);
|
||||||
|
if let Ok(element_nbt) = pumpkin_nbt::Nbt::read_unnamed(&mut reader) {
|
||||||
|
entry_compound.put("element", NbtTag::Compound(element_nbt.root_tag));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
values_list.push(NbtTag::Compound(entry_compound));
|
||||||
|
}
|
||||||
|
|
||||||
|
reg_compound.put("value", NbtTag::List(values_list));
|
||||||
|
root.put(®_type, NbtTag::Compound(reg_compound));
|
||||||
|
}
|
||||||
|
|
||||||
|
root
|
||||||
|
}
|
||||||
|
|
||||||
impl ClientPacket for CLogin<'_> {
|
impl ClientPacket for CLogin<'_> {
|
||||||
fn write_packet_data(
|
fn write_packet_data(
|
||||||
&self,
|
&self,
|
||||||
mut write: impl std::io::Write,
|
mut write: impl std::io::Write,
|
||||||
version: &JavaMinecraftVersion,
|
version: &JavaMinecraftVersion,
|
||||||
) -> Result<(), WritingError> {
|
) -> Result<(), WritingError> {
|
||||||
|
if version < &JavaMinecraftVersion::V_1_20_2 {
|
||||||
|
write.write_i32_be(self.entity_id)?;
|
||||||
|
write.write_bool(self.is_hardcore)?;
|
||||||
|
write.write_u8(self.spawn_data.game_mode)?;
|
||||||
|
write.write_i8(self.spawn_data.previous_gamemode)?;
|
||||||
|
write.write_list(self.dimension_names, |write, dim| write.write_string(dim))?;
|
||||||
|
|
||||||
|
let registry_codec = build_v1_20_registry_codec(*version);
|
||||||
|
let nbt_bytes = pumpkin_nbt::Nbt::new(String::new(), registry_codec).write();
|
||||||
|
write.write_all(&nbt_bytes)?;
|
||||||
|
|
||||||
|
write.write_string(self.spawn_data.dimension.minecraft_name)?;
|
||||||
|
write.write_string(self.spawn_data.dimension.minecraft_name)?;
|
||||||
|
write.write_i64_be(self.spawn_data.hashed_seed)?;
|
||||||
|
write.write_var_int(&self.max_players)?;
|
||||||
|
write.write_var_int(&self.view_distance)?;
|
||||||
|
write.write_var_int(&self.simulated_distance)?;
|
||||||
|
write.write_bool(self.reduced_debug_info)?;
|
||||||
|
write.write_bool(self.enabled_respawn_screen)?;
|
||||||
|
write.write_bool(self.limited_crafting)?;
|
||||||
|
write.write_bool(self.spawn_data.debug)?;
|
||||||
|
write.write_bool(self.spawn_data.is_flat)?;
|
||||||
|
write.write_option(
|
||||||
|
&self.spawn_data.death_dimension_name,
|
||||||
|
|write, (dim, pos)| {
|
||||||
|
write.write_string(dim)?;
|
||||||
|
write.write_block_pos(pos)?;
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
if version >= &JavaMinecraftVersion::V_1_20 {
|
||||||
|
write.write_var_int(&self.spawn_data.portal_cooldown)?;
|
||||||
|
}
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
write.write_i32_be(self.entity_id)?;
|
write.write_i32_be(self.entity_id)?;
|
||||||
write.write_bool(self.is_hardcore)?;
|
write.write_bool(self.is_hardcore)?;
|
||||||
if version >= &JavaMinecraftVersion::V_1_16 {
|
if version >= &JavaMinecraftVersion::V_1_16 {
|
||||||
|
|||||||
@ -284,3 +284,6 @@ pub use start_configuration::*;
|
|||||||
|
|
||||||
mod tag_query;
|
mod tag_query;
|
||||||
pub use tag_query::*;
|
pub use tag_query::*;
|
||||||
|
|
||||||
|
mod update_tags;
|
||||||
|
pub use update_tags::*;
|
||||||
|
|||||||
@ -118,7 +118,13 @@ impl ClientPacket for CPlayerInfoUpdate<'_> {
|
|||||||
PlayerAction::UpdateLatency(latency) => p.write_var_int(latency)?,
|
PlayerAction::UpdateLatency(latency) => p.write_var_int(latency)?,
|
||||||
PlayerAction::UpdateDisplayName(display_name) => {
|
PlayerAction::UpdateDisplayName(display_name) => {
|
||||||
p.write_option(display_name, |w, text_component| {
|
p.write_option(display_name, |w, text_component| {
|
||||||
|
if *version < JavaMinecraftVersion::V_1_20_5 {
|
||||||
|
let json =
|
||||||
|
serde_json::to_string(&text_component.0).unwrap_or_default();
|
||||||
|
w.write_string(&json)
|
||||||
|
} else {
|
||||||
w.write_slice(&text_component.encode())
|
w.write_slice(&text_component.encode())
|
||||||
|
}
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
PlayerAction::UpdateListOrder(order) => {
|
PlayerAction::UpdateListOrder(order) => {
|
||||||
|
|||||||
@ -76,14 +76,13 @@ impl ClientPacket for CPlayerPosition {
|
|||||||
write.write_f64_be(self.position.z)?;
|
write.write_f64_be(self.position.z)?;
|
||||||
write.write_f32_be(self.yaw)?;
|
write.write_f32_be(self.yaw)?;
|
||||||
write.write_f32_be(self.pitch)?;
|
write.write_f32_be(self.pitch)?;
|
||||||
if version >= &JavaMinecraftVersion::V_1_19_4 {
|
|
||||||
write.write_i32_be(PositionFlag::get_bitfield(self.relatives.as_slice()))?;
|
|
||||||
} else {
|
|
||||||
write.write_u8(PositionFlag::get_bitfield(self.relatives.as_slice()) as u8)?;
|
write.write_u8(PositionFlag::get_bitfield(self.relatives.as_slice()) as u8)?;
|
||||||
}
|
|
||||||
if version >= &JavaMinecraftVersion::V_1_9 {
|
if version >= &JavaMinecraftVersion::V_1_9 {
|
||||||
write.write_var_int(&self.teleport_id)?;
|
write.write_var_int(&self.teleport_id)?;
|
||||||
}
|
}
|
||||||
|
if version >= &JavaMinecraftVersion::V_1_20_2 {
|
||||||
|
write.write_bool(false)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,29 @@ impl ClientPacket for CRespawn {
|
|||||||
mut write: impl std::io::Write,
|
mut write: impl std::io::Write,
|
||||||
version: &JavaMinecraftVersion,
|
version: &JavaMinecraftVersion,
|
||||||
) -> Result<(), WritingError> {
|
) -> Result<(), WritingError> {
|
||||||
|
if version < &JavaMinecraftVersion::V_1_20_2 {
|
||||||
|
write.write_string(self.player_spawn_info.dimension.minecraft_name)?;
|
||||||
|
write.write_string(self.player_spawn_info.dimension.minecraft_name)?;
|
||||||
|
write.write_i64_be(self.player_spawn_info.hashed_seed)?;
|
||||||
|
write.write_u8(self.player_spawn_info.game_mode)?;
|
||||||
|
write.write_i8(self.player_spawn_info.previous_gamemode)?;
|
||||||
|
write.write_bool(self.player_spawn_info.debug)?;
|
||||||
|
write.write_bool(self.player_spawn_info.is_flat)?;
|
||||||
|
write.write_i8(self.data_kept as i8)?;
|
||||||
|
write.write_option(
|
||||||
|
&self.player_spawn_info.death_dimension_name,
|
||||||
|
|write, (dim, pos)| {
|
||||||
|
write.write_string(dim)?;
|
||||||
|
write.write_block_pos(pos)?;
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
if version >= &JavaMinecraftVersion::V_1_20 {
|
||||||
|
write.write_var_int(&self.player_spawn_info.portal_cooldown)?;
|
||||||
|
}
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
self.player_spawn_info
|
self.player_spawn_info
|
||||||
.write_packet_data(&mut write, version)?;
|
.write_packet_data(&mut write, version)?;
|
||||||
write.write_i8(self.data_kept as i8)?;
|
write.write_i8(self.data_kept as i8)?;
|
||||||
|
|||||||
@ -29,9 +29,7 @@ impl ClientPacket for CSetSelectedSlot {
|
|||||||
|
|
||||||
impl MultiVersionJavaPacket for CSetSelectedSlot {
|
impl MultiVersionJavaPacket for CSetSelectedSlot {
|
||||||
fn to_id(version: JavaMinecraftVersion) -> i32 {
|
fn to_id(version: JavaMinecraftVersion) -> i32 {
|
||||||
if version >= JavaMinecraftVersion::V_1_21_2 {
|
if version == JavaMinecraftVersion::V_1_21 {
|
||||||
PLAY_SET_HELD_SLOT.to_id(version)
|
|
||||||
} else if version == JavaMinecraftVersion::V_1_21 {
|
|
||||||
PLAY_SET_CARRIED_ITEM.to_id(version)
|
PLAY_SET_CARRIED_ITEM.to_id(version)
|
||||||
} else {
|
} else {
|
||||||
PLAY_SET_HELD_SLOT.to_id(version)
|
PLAY_SET_HELD_SLOT.to_id(version)
|
||||||
|
|||||||
@ -46,7 +46,7 @@ impl ClientPacket for CTeleportEntity<'_> {
|
|||||||
fn write_packet_data(
|
fn write_packet_data(
|
||||||
&self,
|
&self,
|
||||||
write: impl Write,
|
write: impl Write,
|
||||||
_version: &JavaMinecraftVersion,
|
version: &JavaMinecraftVersion,
|
||||||
) -> Result<(), WritingError> {
|
) -> Result<(), WritingError> {
|
||||||
let mut write = write;
|
let mut write = write;
|
||||||
|
|
||||||
@ -54,13 +54,17 @@ impl ClientPacket for CTeleportEntity<'_> {
|
|||||||
write.write_f64_be(self.position.x)?;
|
write.write_f64_be(self.position.x)?;
|
||||||
write.write_f64_be(self.position.y)?;
|
write.write_f64_be(self.position.y)?;
|
||||||
write.write_f64_be(self.position.z)?;
|
write.write_f64_be(self.position.z)?;
|
||||||
|
if version >= &JavaMinecraftVersion::V_1_21_2 {
|
||||||
write.write_f64_be(self.delta.x)?;
|
write.write_f64_be(self.delta.x)?;
|
||||||
write.write_f64_be(self.delta.y)?;
|
write.write_f64_be(self.delta.y)?;
|
||||||
write.write_f64_be(self.delta.z)?;
|
write.write_f64_be(self.delta.z)?;
|
||||||
write.write_f32_be(self.yaw)?;
|
write.write_f32_be(self.yaw)?;
|
||||||
write.write_f32_be(self.pitch)?;
|
write.write_f32_be(self.pitch)?;
|
||||||
// not sure about that
|
|
||||||
write.write_i32_be(PositionFlag::get_bitfield(self.relatives))?;
|
write.write_i32_be(PositionFlag::get_bitfield(self.relatives))?;
|
||||||
|
} else {
|
||||||
|
write.write_u8((self.yaw.rem_euclid(360.0) * 256.0 / 360.0).floor() as u8)?;
|
||||||
|
write.write_u8((self.pitch.rem_euclid(360.0) * 256.0 / 360.0).floor() as u8)?;
|
||||||
|
}
|
||||||
write.write_bool(self.on_ground)
|
write.write_bool(self.on_ground)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
53
crates/pumpkin-protocol/src/java/client/play/update_tags.rs
Normal file
53
crates/pumpkin-protocol/src/java/client/play/update_tags.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
use crate::{ClientPacket, WritingError, ser::NetworkWriteExt};
|
||||||
|
|
||||||
|
use crate::codec::var_int::VarInt;
|
||||||
|
use pumpkin_data::{
|
||||||
|
packet::clientbound::PLAY_UPDATE_TAGS,
|
||||||
|
tag::{RegistryKey, get_registry_key_tags},
|
||||||
|
};
|
||||||
|
use pumpkin_macros::java_packet;
|
||||||
|
use pumpkin_util::version::JavaMinecraftVersion;
|
||||||
|
|
||||||
|
#[java_packet(PLAY_UPDATE_TAGS)]
|
||||||
|
pub struct CUpdateTagsPlay<'a> {
|
||||||
|
pub tags: &'a [pumpkin_data::tag::RegistryKey],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> CUpdateTagsPlay<'a> {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(tags: &'a [RegistryKey]) -> Self {
|
||||||
|
Self { tags }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ClientPacket for CUpdateTagsPlay<'_> {
|
||||||
|
fn write_packet_data(
|
||||||
|
&self,
|
||||||
|
mut write: impl Write,
|
||||||
|
version: &JavaMinecraftVersion,
|
||||||
|
) -> Result<(), WritingError> {
|
||||||
|
write.write_list(self.tags, |p, registry_key| {
|
||||||
|
p.write_string(&format!("minecraft:{}", registry_key.identifier_string()))?;
|
||||||
|
|
||||||
|
let Some(values) = get_registry_key_tags(*version, *registry_key) else {
|
||||||
|
// no tags defined for that registry key in this version
|
||||||
|
// write an empty list and continue
|
||||||
|
p.write_var_int(&VarInt::from(0))?;
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
p.write_var_int(&values.len().try_into().map_err(|_| {
|
||||||
|
WritingError::Message(format!("{} isn't representable as a VarInt", values.len()))
|
||||||
|
})?)?;
|
||||||
|
|
||||||
|
for (key, values) in values.entries() {
|
||||||
|
// This is technically a `ResourceLocation` but same thing
|
||||||
|
p.write_string_bounded(key, u16::MAX as usize)?;
|
||||||
|
p.write_list(values.1, |p, id| p.write_var_int(&VarInt::from(*id)))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,12 +12,22 @@ pub struct SEncryptionResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ServerPacket<'a> for SEncryptionResponse {
|
impl<'a> ServerPacket<'a> for SEncryptionResponse {
|
||||||
fn read(
|
fn read(mut read: &mut &'a [u8], version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
|
||||||
mut read: &mut &'a [u8],
|
|
||||||
_version: &JavaMinecraftVersion,
|
|
||||||
) -> Result<Self, ReadingError> {
|
|
||||||
let shared_secret = read_encryption_buffer(&mut read)?;
|
let shared_secret = read_encryption_buffer(&mut read)?;
|
||||||
let verify_token = read_encryption_buffer(&mut read)?;
|
let verify_token = if version >= &JavaMinecraftVersion::V_1_19_3
|
||||||
|
&& version < &JavaMinecraftVersion::V_1_20_2
|
||||||
|
{
|
||||||
|
let has_verify_token = read.get_bool()?;
|
||||||
|
if has_verify_token {
|
||||||
|
read_encryption_buffer(&mut read)?
|
||||||
|
} else {
|
||||||
|
let _salt = read.get_i64_be()?;
|
||||||
|
let _signature = read_encryption_buffer(&mut read)?;
|
||||||
|
Box::new([])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
read_encryption_buffer(&mut read)?
|
||||||
|
};
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
shared_secret,
|
shared_secret,
|
||||||
verify_token,
|
verify_token,
|
||||||
@ -29,11 +39,14 @@ impl crate::ClientPacket for SEncryptionResponse {
|
|||||||
fn write_packet_data(
|
fn write_packet_data(
|
||||||
&self,
|
&self,
|
||||||
mut write: impl std::io::Write,
|
mut write: impl std::io::Write,
|
||||||
_version: &JavaMinecraftVersion,
|
version: &JavaMinecraftVersion,
|
||||||
) -> Result<(), crate::ser::WritingError> {
|
) -> Result<(), crate::ser::WritingError> {
|
||||||
use crate::ser::NetworkWriteExt;
|
use crate::ser::NetworkWriteExt;
|
||||||
write.write_var_int(&crate::VarInt(self.shared_secret.len() as i32))?;
|
write.write_var_int(&crate::VarInt(self.shared_secret.len() as i32))?;
|
||||||
write.write_all(&self.shared_secret)?;
|
write.write_all(&self.shared_secret)?;
|
||||||
|
if version >= &JavaMinecraftVersion::V_1_19_3 && version < &JavaMinecraftVersion::V_1_20_2 {
|
||||||
|
write.write_bool(true)?;
|
||||||
|
}
|
||||||
write.write_var_int(&crate::VarInt(self.verify_token.len() as i32))?;
|
write.write_var_int(&crate::VarInt(self.verify_token.len() as i32))?;
|
||||||
write.write_all(&self.verify_token)?;
|
write.write_all(&self.verify_token)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@ -18,6 +18,16 @@ impl<'a> ServerPacket<'a> for SLoginStart {
|
|||||||
let name = read.get_str_bounded(16)?;
|
let name = read.get_str_bounded(16)?;
|
||||||
let uuid = if version >= &JavaMinecraftVersion::V_1_20_2 {
|
let uuid = if version >= &JavaMinecraftVersion::V_1_20_2 {
|
||||||
read.get_uuid()?
|
read.get_uuid()?
|
||||||
|
} else if version >= &JavaMinecraftVersion::V_1_19_3 {
|
||||||
|
let has_uuid = read.get_bool()?;
|
||||||
|
if has_uuid {
|
||||||
|
read.get_uuid()?
|
||||||
|
} else {
|
||||||
|
uuid::Uuid::new_v3(
|
||||||
|
&uuid::Uuid::nil(),
|
||||||
|
format!("OfflinePlayer:{name}").as_bytes(),
|
||||||
|
)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
uuid::Uuid::new_v3(
|
uuid::Uuid::new_v3(
|
||||||
&uuid::Uuid::nil(),
|
&uuid::Uuid::nil(),
|
||||||
@ -38,6 +48,9 @@ impl crate::ClientPacket for SLoginStart {
|
|||||||
write.write_string_bounded(&self.name, 16)?;
|
write.write_string_bounded(&self.name, 16)?;
|
||||||
if version >= &JavaMinecraftVersion::V_1_20_2 {
|
if version >= &JavaMinecraftVersion::V_1_20_2 {
|
||||||
write.write_uuid(&self.uuid)?;
|
write.write_uuid(&self.uuid)?;
|
||||||
|
} else if version >= &JavaMinecraftVersion::V_1_19_3 {
|
||||||
|
write.write_bool(true)?;
|
||||||
|
write.write_uuid(&self.uuid)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ use pumpkin_data::damage::DamageType;
|
|||||||
use pumpkin_data::entity::EntityType;
|
use pumpkin_data::entity::EntityType;
|
||||||
use pumpkin_data::item::Item;
|
use pumpkin_data::item::Item;
|
||||||
use pumpkin_data::item_stack::ItemStack;
|
use pumpkin_data::item_stack::ItemStack;
|
||||||
|
use pumpkin_data::packet::CURRENT_MC_VERSION;
|
||||||
use pumpkin_data::sound::Sound;
|
use pumpkin_data::sound::Sound;
|
||||||
use pumpkin_nbt::compound::NbtCompound;
|
use pumpkin_nbt::compound::NbtCompound;
|
||||||
use pumpkin_protocol::codec::item_stack_seralizer::ItemStackSerializer;
|
use pumpkin_protocol::codec::item_stack_seralizer::ItemStackSerializer;
|
||||||
@ -351,7 +352,10 @@ impl EntityBase for ItemFrameEntity {
|
|||||||
.enqueue_packet(&self.entity.create_spawn_packet())
|
.enqueue_packet(&self.entity.create_spawn_packet())
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let item_serializer = ItemStackSerializer::from(self.item_stack.lock().await.clone());
|
let ver = client.version.load();
|
||||||
|
if ver >= CURRENT_MC_VERSION {
|
||||||
|
let item_serializer =
|
||||||
|
ItemStackSerializer::from(self.item_stack.lock().await.clone());
|
||||||
let rotation = self.get_rotation() as i32;
|
let rotation = self.get_rotation() as i32;
|
||||||
|
|
||||||
let mut data = Vec::new();
|
let mut data = Vec::new();
|
||||||
@ -362,8 +366,9 @@ impl EntityBase for ItemFrameEntity {
|
|||||||
let meta_rot =
|
let meta_rot =
|
||||||
Metadata::new(pumpkin_data::tracked_data::item_frame::ROTATION, rotation);
|
Metadata::new(pumpkin_data::tracked_data::item_frame::ROTATION, rotation);
|
||||||
|
|
||||||
let ver = client.version.load();
|
if meta_item.write(&mut data, &ver).is_ok()
|
||||||
if meta_item.write(&mut data, &ver).is_ok() && meta_rot.write(&mut data, &ver).is_ok() {
|
&& meta_rot.write(&mut data, &ver).is_ok()
|
||||||
|
{
|
||||||
data.push(255);
|
data.push(255);
|
||||||
client
|
client
|
||||||
.enqueue_packet(&CSetEntityMetadata::new(
|
.enqueue_packet(&CSetEntityMetadata::new(
|
||||||
@ -372,6 +377,7 @@ impl EntityBase for ItemFrameEntity {
|
|||||||
))
|
))
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@ use pumpkin_data::damage::DamageType;
|
|||||||
use pumpkin_data::data_component_impl::DamageResistantImpl;
|
use pumpkin_data::data_component_impl::DamageResistantImpl;
|
||||||
use pumpkin_data::data_component_impl::DamageResistantType;
|
use pumpkin_data::data_component_impl::DamageResistantType;
|
||||||
use pumpkin_data::item_stack::ItemStack;
|
use pumpkin_data::item_stack::ItemStack;
|
||||||
|
use pumpkin_data::packet::CURRENT_MC_VERSION;
|
||||||
use pumpkin_nbt::compound::NbtCompound;
|
use pumpkin_nbt::compound::NbtCompound;
|
||||||
use pumpkin_protocol::bedrock::client::CAddItemActor;
|
use pumpkin_protocol::bedrock::client::CAddItemActor;
|
||||||
use pumpkin_protocol::bedrock::network_item::ItemStackWrapper;
|
use pumpkin_protocol::bedrock::network_item::ItemStackWrapper;
|
||||||
@ -668,6 +669,7 @@ impl EntityBase for ItemEntity {
|
|||||||
.enqueue_packet(&self.entity.create_spawn_packet())
|
.enqueue_packet(&self.entity.create_spawn_packet())
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
if client.version.load() >= CURRENT_MC_VERSION {
|
||||||
let metadata = Metadata::new(
|
let metadata = Metadata::new(
|
||||||
pumpkin_data::tracked_data::item::ITEM,
|
pumpkin_data::tracked_data::item::ITEM,
|
||||||
ItemStackSerializer::from(self.item_stack.lock().await.clone()),
|
ItemStackSerializer::from(self.item_stack.lock().await.clone()),
|
||||||
@ -682,6 +684,7 @@ impl EntityBase for ItemEntity {
|
|||||||
))
|
))
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@ use pumpkin_data::dimension::Dimension;
|
|||||||
use pumpkin_data::entity::EntityStatus;
|
use pumpkin_data::entity::EntityStatus;
|
||||||
use pumpkin_data::fluid::Fluid;
|
use pumpkin_data::fluid::Fluid;
|
||||||
use pumpkin_data::item_stack::ItemStack;
|
use pumpkin_data::item_stack::ItemStack;
|
||||||
|
use pumpkin_data::packet::CURRENT_MC_VERSION;
|
||||||
use pumpkin_data::tag::{self, Taggable};
|
use pumpkin_data::tag::{self, Taggable};
|
||||||
use pumpkin_data::tracked_data;
|
use pumpkin_data::tracked_data;
|
||||||
use pumpkin_data::{Block, BlockDirection};
|
use pumpkin_data::{Block, BlockDirection};
|
||||||
@ -2934,6 +2935,10 @@ impl Entity {
|
|||||||
for player in world.players.load().iter() {
|
for player in world.players.load().iter() {
|
||||||
match player.client.as_ref() {
|
match player.client.as_ref() {
|
||||||
ClientPlatform::Java(client) => {
|
ClientPlatform::Java(client) => {
|
||||||
|
let version = client.version.load();
|
||||||
|
if version < CURRENT_MC_VERSION {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// Apply Chebyshev distance check
|
// Apply Chebyshev distance check
|
||||||
let center = player.get_entity().chunk_pos.load();
|
let center = player.get_entity().chunk_pos.load();
|
||||||
let view_distance =
|
let view_distance =
|
||||||
@ -2942,7 +2947,7 @@ impl Entity {
|
|||||||
if is_within_view_distance(chunk_pos, center, view_distance) {
|
if is_within_view_distance(chunk_pos, center, view_distance) {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
for m in meta {
|
for m in meta {
|
||||||
let _ = m.write(&mut buf, &client.version.load());
|
let _ = m.write(&mut buf, &version);
|
||||||
}
|
}
|
||||||
buf.put_u8(255);
|
buf.put_u8(255);
|
||||||
player.client.try_enqueue_packet(&CSetEntityMetadata::new(
|
player.client.try_enqueue_packet(&CSetEntityMetadata::new(
|
||||||
|
|||||||
@ -9,7 +9,6 @@ use std::{io::Write, sync::Arc};
|
|||||||
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use crossbeam::atomic::AtomicCell;
|
use crossbeam::atomic::AtomicCell;
|
||||||
use pumpkin_data::packet::CURRENT_MC_VERSION;
|
|
||||||
use pumpkin_data::translation;
|
use pumpkin_data::translation;
|
||||||
use pumpkin_protocol::java::server::play::{
|
use pumpkin_protocol::java::server::play::{
|
||||||
SAttack, SBlockEntityTagQuery, SBundleItemSelected, SChangeGameMode, SChatCommand,
|
SAttack, SBlockEntityTagQuery, SBundleItemSelected, SChangeGameMode, SChatCommand,
|
||||||
@ -293,7 +292,9 @@ impl JavaClient {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if self.version.load() >= JavaMinecraftVersion::V_1_20_2 {
|
||||||
self.send_packet_now(&CChunkBatchStart).await;
|
self.send_packet_now(&CChunkBatchStart).await;
|
||||||
|
}
|
||||||
for chunk in chunks {
|
for chunk in chunks {
|
||||||
let mut event = ChunkSend::new(player.world(), chunk.clone());
|
let mut event = ChunkSend::new(player.world(), chunk.clone());
|
||||||
server.plugin_manager.fire(&server, &mut event).await;
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
@ -313,9 +314,11 @@ impl JavaClient {
|
|||||||
}
|
}
|
||||||
self.send_packet_now_data(buf.into()).await;
|
self.send_packet_now_data(buf.into()).await;
|
||||||
}
|
}
|
||||||
|
if self.version.load() >= JavaMinecraftVersion::V_1_20_2 {
|
||||||
self.send_packet_now(&CChunkBatchEnd::new(chunks.len() as u16))
|
self.send_packet_now(&CChunkBatchEnd::new(chunks.len() as u16))
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn enqueue_packet<P: ClientPacket>(&self, packet: &P) {
|
pub async fn enqueue_packet<P: ClientPacket>(&self, packet: &P) {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
@ -324,6 +327,9 @@ impl JavaClient {
|
|||||||
error!("Failed to write packet: {err:?}");
|
error!("Failed to write packet: {err:?}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if buf.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let payload = Bytes::from(buf);
|
let payload = Bytes::from(buf);
|
||||||
|
|
||||||
let player = self.player.load_full();
|
let player = self.player.load_full();
|
||||||
@ -346,6 +352,9 @@ impl JavaClient {
|
|||||||
error!("Failed to write packet: {err:?}");
|
error!("Failed to write packet: {err:?}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if buf.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
self.try_enqueue_packet_data(buf.into());
|
self.try_enqueue_packet_data(buf.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,6 +466,9 @@ impl JavaClient {
|
|||||||
error!("Failed to write packet: {err:?}");
|
error!("Failed to write packet: {err:?}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if packet_buf.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let payload = Bytes::from(packet_buf);
|
let payload = Bytes::from(packet_buf);
|
||||||
|
|
||||||
let player = self.player.load_full();
|
let player = self.player.load_full();
|
||||||
@ -506,11 +518,7 @@ impl JavaClient {
|
|||||||
) -> Result<(), WritingError> {
|
) -> Result<(), WritingError> {
|
||||||
let version_number = P::to_id(version);
|
let version_number = P::to_id(version);
|
||||||
if version_number == -1 {
|
if version_number == -1 {
|
||||||
error!(
|
return Ok(());
|
||||||
"Packet ID for version {} is invalid ({} at latest)",
|
|
||||||
version,
|
|
||||||
P::to_id(CURRENT_MC_VERSION),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
write.write_var_int(&VarInt(version_number))?;
|
write.write_var_int(&VarInt(version_number))?;
|
||||||
packet.write_packet_data(write, &version)
|
packet.write_packet_data(write, &version)
|
||||||
|
|||||||
@ -281,7 +281,7 @@ impl PendingConnection {
|
|||||||
)?,
|
)?,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
Ok(None)
|
Ok(())
|
||||||
}
|
}
|
||||||
id if id
|
id if id
|
||||||
== pumpkin_protocol::java::server::login::SEncryptionResponse::to_id(version) =>
|
== pumpkin_protocol::java::server::login::SEncryptionResponse::to_id(version) =>
|
||||||
@ -294,7 +294,7 @@ impl PendingConnection {
|
|||||||
)?,
|
)?,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
Ok(None)
|
Ok(())
|
||||||
}
|
}
|
||||||
id if id
|
id if id
|
||||||
== pumpkin_protocol::java::server::login::SLoginPluginResponse::to_id(version) =>
|
== pumpkin_protocol::java::server::login::SLoginPluginResponse::to_id(version) =>
|
||||||
@ -307,7 +307,7 @@ impl PendingConnection {
|
|||||||
)?,
|
)?,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
Ok(None)
|
Ok(())
|
||||||
}
|
}
|
||||||
id if id
|
id if id
|
||||||
== pumpkin_protocol::java::server::login::SLoginCookieResponse::to_id(version) =>
|
== pumpkin_protocol::java::server::login::SLoginCookieResponse::to_id(version) =>
|
||||||
@ -318,19 +318,33 @@ impl PendingConnection {
|
|||||||
&version,
|
&version,
|
||||||
)?,
|
)?,
|
||||||
);
|
);
|
||||||
Ok(None)
|
Ok(())
|
||||||
}
|
}
|
||||||
id if id
|
id if id
|
||||||
== pumpkin_protocol::java::server::login::SLoginAcknowledged::to_id(version) =>
|
== pumpkin_protocol::java::server::login::SLoginAcknowledged::to_id(version) =>
|
||||||
{
|
{
|
||||||
self.handle_login_acknowledged(server).await;
|
self.handle_login_acknowledged(server).await;
|
||||||
Ok(None)
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => Err(ReadingError::Message(format!(
|
_ => Err(ReadingError::Message(format!(
|
||||||
"Failed to handle packet id {} in Login State",
|
"Failed to handle packet id {} in Login State",
|
||||||
packet.id
|
packet.id
|
||||||
))),
|
))),
|
||||||
|
}?;
|
||||||
|
|
||||||
|
if self.version.load() < JavaMinecraftVersion::V_1_20_2
|
||||||
|
&& self.connection_state.load() == ConnectionState::Play
|
||||||
|
&& let Some(profile) = self.gameprofile.clone()
|
||||||
|
{
|
||||||
|
let config = self.config.clone().unwrap_or_default();
|
||||||
|
if let Some(reason) = can_not_join(&profile, &self.address, server).await {
|
||||||
|
self.kick(reason).await;
|
||||||
|
return Ok(Some(PacketHandlerResult::Stop));
|
||||||
}
|
}
|
||||||
|
return Ok(Some(PacketHandlerResult::ReadyToPlay(profile, config)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_config_packet(
|
async fn handle_config_packet(
|
||||||
|
|||||||
@ -209,6 +209,7 @@ impl ServerTickRateManager {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
pub async fn update_joining_player(&self, player: &Player) {
|
pub async fn update_joining_player(&self, player: &Player) {
|
||||||
|
if player.client.java_version() >= pumpkin_util::version::JavaMinecraftVersion::V_1_20_3 {
|
||||||
player
|
player
|
||||||
.client
|
.client
|
||||||
.send_packet_now(&CTickingState::new(self.tickrate(), self.is_frozen()))
|
.send_packet_now(&CTickingState::new(self.tickrate(), self.is_frozen()))
|
||||||
@ -220,4 +221,5 @@ impl ServerTickRateManager {
|
|||||||
))
|
))
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -67,6 +67,7 @@ use pumpkin_data::{
|
|||||||
entity::{EntityStatus, EntityType},
|
entity::{EntityStatus, EntityType},
|
||||||
fluid::Fluid,
|
fluid::Fluid,
|
||||||
item_stack::ItemStack,
|
item_stack::ItemStack,
|
||||||
|
packet::CURRENT_MC_VERSION,
|
||||||
particle::Particle,
|
particle::Particle,
|
||||||
sound::{Sound, SoundCategory},
|
sound::{Sound, SoundCategory},
|
||||||
sound_id_remap::remap_sound_id_for_version,
|
sound_id_remap::remap_sound_id_for_version,
|
||||||
@ -882,6 +883,9 @@ impl World {
|
|||||||
match p.client.as_ref() {
|
match p.client.as_ref() {
|
||||||
ClientPlatform::Java(client) => {
|
ClientPlatform::Java(client) => {
|
||||||
let version = client.version.load();
|
let version = client.version.load();
|
||||||
|
if version < CURRENT_MC_VERSION {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
for meta in [
|
for meta in [
|
||||||
Metadata::new(
|
Metadata::new(
|
||||||
@ -2939,6 +2943,43 @@ impl World {
|
|||||||
client_suggestions::send_c_commands_packet(player, server, &command_dispatcher).await;
|
client_suggestions::send_c_commands_packet(player, server, &command_dispatcher).await;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if client.version.load() < JavaMinecraftVersion::V_1_20_2 {
|
||||||
|
let all_keys = [
|
||||||
|
pumpkin_data::tag::RegistryKey::BannerPattern,
|
||||||
|
pumpkin_data::tag::RegistryKey::Block,
|
||||||
|
pumpkin_data::tag::RegistryKey::CatVariant,
|
||||||
|
pumpkin_data::tag::RegistryKey::DamageType,
|
||||||
|
pumpkin_data::tag::RegistryKey::Dialog,
|
||||||
|
pumpkin_data::tag::RegistryKey::DimensionType,
|
||||||
|
pumpkin_data::tag::RegistryKey::Enchantment,
|
||||||
|
pumpkin_data::tag::RegistryKey::EntityType,
|
||||||
|
pumpkin_data::tag::RegistryKey::Fluid,
|
||||||
|
pumpkin_data::tag::RegistryKey::GameEvent,
|
||||||
|
pumpkin_data::tag::RegistryKey::Instrument,
|
||||||
|
pumpkin_data::tag::RegistryKey::Item,
|
||||||
|
pumpkin_data::tag::RegistryKey::PaintingVariant,
|
||||||
|
pumpkin_data::tag::RegistryKey::PointOfInterestType,
|
||||||
|
pumpkin_data::tag::RegistryKey::Potion,
|
||||||
|
pumpkin_data::tag::RegistryKey::Timeline,
|
||||||
|
pumpkin_data::tag::RegistryKey::WorldgenBiome,
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut tags = Vec::new();
|
||||||
|
let version = client.version.load();
|
||||||
|
for key in all_keys {
|
||||||
|
if pumpkin_data::tag::get_registry_key_tags(version, key)
|
||||||
|
.is_some_and(|map| !map.is_empty())
|
||||||
|
{
|
||||||
|
tags.push(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
client
|
||||||
|
.send_packet_now(&pumpkin_protocol::java::client::play::CUpdateTagsPlay::new(
|
||||||
|
&tags,
|
||||||
|
))
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
let (position, yaw, pitch) = if player.has_played_before.load(Ordering::Relaxed) {
|
let (position, yaw, pitch) = if player.has_played_before.load(Ordering::Relaxed) {
|
||||||
let position = player.position();
|
let position = player.position();
|
||||||
let yaw = player.get_entity().yaw.load(); //info.spawn_angle;
|
let yaw = player.get_entity().yaw.load(); //info.spawn_angle;
|
||||||
@ -2979,9 +3020,13 @@ impl World {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if client.version.load() >= JavaMinecraftVersion::V_1_20_2 {
|
||||||
client.send_packet_now(&CChunkBatchStart).await;
|
client.send_packet_now(&CChunkBatchStart).await;
|
||||||
|
}
|
||||||
client.send_packet_now(&CChunkData(&chunk)).await;
|
client.send_packet_now(&CChunkData(&chunk)).await;
|
||||||
|
if client.version.load() >= JavaMinecraftVersion::V_1_20_2 {
|
||||||
client.send_packet_now(&CChunkBatchEnd::new(1u16)).await;
|
client.send_packet_now(&CChunkBatchEnd::new(1u16)).await;
|
||||||
|
}
|
||||||
|
|
||||||
let velocity = player.living_entity.entity.velocity.load();
|
let velocity = player.living_entity.entity.velocity.load();
|
||||||
|
|
||||||
@ -3346,7 +3391,7 @@ impl World {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
{
|
if client.version.load() >= CURRENT_MC_VERSION {
|
||||||
let config = existing_player.config.load();
|
let config = existing_player.config.load();
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
{
|
{
|
||||||
@ -3372,7 +3417,7 @@ impl World {
|
|||||||
buf.into(),
|
buf.into(),
|
||||||
))
|
))
|
||||||
.await;
|
.await;
|
||||||
};
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let held_item = existing_player.inventory.held_item().await;
|
let held_item = existing_player.inventory.held_item().await;
|
||||||
@ -3925,12 +3970,16 @@ impl World {
|
|||||||
.level
|
.level
|
||||||
.get_or_fetch_chunk(center_chunk, std::clone::Clone::clone)
|
.get_or_fetch_chunk(center_chunk, std::clone::Clone::clone)
|
||||||
.await;
|
.await;
|
||||||
|
if java_client.version.load() >= JavaMinecraftVersion::V_1_20_2 {
|
||||||
java_client.send_packet_now(&CChunkBatchStart).await;
|
java_client.send_packet_now(&CChunkBatchStart).await;
|
||||||
|
}
|
||||||
java_client.send_packet_now(&CChunkData(&chunk)).await;
|
java_client.send_packet_now(&CChunkData(&chunk)).await;
|
||||||
|
if java_client.version.load() >= JavaMinecraftVersion::V_1_20_2 {
|
||||||
java_client
|
java_client
|
||||||
.send_packet_now(&CChunkBatchEnd::new(1u16))
|
.send_packet_now(&CChunkBatchEnd::new(1u16))
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Send teleport packet after at least the center chunk was delivered
|
// Send teleport packet after at least the center chunk was delivered
|
||||||
player.request_teleport(position, yaw, pitch).await;
|
player.request_teleport(position, yaw, pitch).await;
|
||||||
|
|||||||
@ -450,17 +450,4 @@ mod tests {
|
|||||||
assert!(generated.contains("mod cat"));
|
assert!(generated.contains("mod cat"));
|
||||||
assert!(generated.contains("DATA_COLLAR_COLOR"));
|
assert!(generated.contains("DATA_COLLAR_COLOR"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn checked_in_tracker_table_matches_codegen() {
|
|
||||||
let checked_in =
|
|
||||||
std::fs::read_to_string("../../crates/pumpkin-data/src/generated/tracked_data.rs")
|
|
||||||
.expect("checked-in tracked data");
|
|
||||||
let generated = crate::format_code(&build().to_string()).expect("valid rustfmt");
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
checked_in.trim(),
|
|
||||||
format!("/* This file is generated. Do not edit manually. */\n{generated}").trim()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user