feat: 1.21.7-1.21.11 support
Its works, but block state ids are currently not mapped, meaning that when using the current default world gen the client mostly will disconnect due to a not found block state id, vanilla version compatible worlds should work
This commit is contained in:
parent
232bf29d07
commit
186ad2edea
1
assets/packet/1_21_7_packets.json
Normal file
1
assets/packet/1_21_7_packets.json
Normal file
File diff suppressed because one or more lines are too long
96
assets/tracked_data/1_21_7_tracked_data.json
Normal file
96
assets/tracked_data/1_21_7_tracked_data.json
Normal file
@ -0,0 +1,96 @@
|
||||
{
|
||||
"FLAGS": 0,
|
||||
"AIR": 1,
|
||||
"CUSTOM_NAME": 2,
|
||||
"NAME_VISIBLE": 3,
|
||||
"SILENT": 4,
|
||||
"NO_GRAVITY": 5,
|
||||
"POSE": 6,
|
||||
"FROZEN_TICKS": 7,
|
||||
"LIVING_FLAGS": 8,
|
||||
"HEALTH": 9,
|
||||
"POTION_SWIRLS": 10,
|
||||
"POTION_SWIRLS_AMBIENT": 11,
|
||||
"STUCK_ARROW_COUNT": 12,
|
||||
"STINGER_COUNT": 13,
|
||||
"SLEEPING_POSITION": 14,
|
||||
"MOB_FLAGS": 15,
|
||||
"ITEM_STACK": 8,
|
||||
"ROTATION": 9,
|
||||
"FUSE": 8,
|
||||
"EXPLOSION_RADIUS": 9,
|
||||
"FUSE_SPEED": 16,
|
||||
"IGNITED": 18,
|
||||
"CHARGED": 19,
|
||||
"ARMOR_STAND_FLAGS": 15,
|
||||
"TRACKER_HEAD_ROTATION": 16,
|
||||
"TRACKER_BODY_ROTATION": 17,
|
||||
"TRACKER_LEFT_ARM_ROTATION": 18,
|
||||
"TRACKER_RIGHT_ARM_ROTATION": 19,
|
||||
"TRACKER_LEFT_LEG_ROTATION": 20,
|
||||
"TRACKER_RIGHT_LEG_ROTATION": 21,
|
||||
"BLOCK_STATE": 8,
|
||||
"START_INTERPOLATION": 8,
|
||||
"INTERPOLATION_DURATION": 9,
|
||||
"TELEPORT_DURATION": 10,
|
||||
"TRANSLATION": 11,
|
||||
"SCALE": 12,
|
||||
"LEFT_ROTATION": 13,
|
||||
"RIGHT_ROTATION": 14,
|
||||
"BILLBOARD": 15,
|
||||
"BRIGHTNESS": 16,
|
||||
"VIEW_RANGE": 17,
|
||||
"SHADOW_RADIUS": 18,
|
||||
"SHADOW_STRENGTH": 19,
|
||||
"WIDTH": 20,
|
||||
"HEIGHT": 21,
|
||||
"GLOW_COLOR_OVERRIDE": 22,
|
||||
"TEXT": 23,
|
||||
"LINE_WIDTH": 24,
|
||||
"BACKGROUND": 25,
|
||||
"TEXT_OPACITY": 26,
|
||||
"TEXT_DISPLAY_FLAGS": 27,
|
||||
"ITEM_DISPLAY": 24,
|
||||
"PLAYER_MODE_CUSTOMIZATION_ID": 17,
|
||||
"MAIN_ARM_ID": 18,
|
||||
"LEFT_PADDLE_MOVING": 11,
|
||||
"RIGHT_PADDLE_MOVING": 12,
|
||||
"BUBBLE_WOBBLE_TICKS": 13,
|
||||
"VILLAGER_DATA": 18,
|
||||
"ANGER_END_TIME": 21,
|
||||
"VARIANT": 20,
|
||||
"BABY": 16,
|
||||
"ZOMBIE_TYPE": 17,
|
||||
"CONVERTING_IN_WATER": 18,
|
||||
"VEX_FLAGS": 16,
|
||||
"SHEARED": 16,
|
||||
"PUFF_STATE": 17,
|
||||
"FOX_FLAGS": 18,
|
||||
"CAT_VARIANT": 19,
|
||||
"COLLAR_COLOR": 20,
|
||||
"TAMEABLE_FLAGS": 17,
|
||||
"OWNER_UUID": 18,
|
||||
"BEE_FLAGS": 17,
|
||||
"ANGER": 16,
|
||||
"ATTACHED_FACE": 16,
|
||||
"PEEK_AMOUNT": 17,
|
||||
"CONVERTING": 19,
|
||||
"SNOW_GOLEM_FLAGS": 16,
|
||||
"IRON_GOLEM_FLAGS": 16,
|
||||
"SLIME_SIZE": 16,
|
||||
"PANDA_FLAGS": 22,
|
||||
"MAIN_GENE": 20,
|
||||
"HIDDEN_GENE": 21,
|
||||
"EATING_TICKS": 19,
|
||||
"SNEEZE_PROGRESS": 18,
|
||||
"STRENGTH": 19,
|
||||
"HORSE_FLAGS": 17,
|
||||
"CARRIED_BLOCK": 16,
|
||||
"ANGRY": 17,
|
||||
"PROVOKED": 18,
|
||||
"SPIKES_RETRACTED": 16,
|
||||
"BEAM_TARGET_ID": 17,
|
||||
"PHASE_TYPE": 16,
|
||||
"BEAM_TARGET": 8,
|
||||
"SHOW_BOTTOM": 9
|
||||
}
|
||||
@ -1,8 +1,7 @@
|
||||
use std::{collections::BTreeMap, fs};
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote};
|
||||
use serde::Deserialize;
|
||||
use std::{collections::BTreeMap, fs};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Packets {
|
||||
@ -12,20 +11,62 @@ pub struct Packets {
|
||||
}
|
||||
|
||||
pub(crate) fn build() -> TokenStream {
|
||||
// 1. Track the JSON assets for rebuilds
|
||||
println!("cargo:rerun-if-changed=../assets/packet/1_21_7_packets.json");
|
||||
println!("cargo:rerun-if-changed=../assets/packet/1_21_11_packets.json");
|
||||
|
||||
let packets: Packets =
|
||||
serde_json::from_str(&fs::read_to_string("../assets/packet/1_21_11_packets.json").unwrap())
|
||||
.expect("Failed to parse packets.json");
|
||||
// 2. Parse the protocol files
|
||||
let packets_7: Packets = serde_json::from_str(
|
||||
&fs::read_to_string("../assets/packet/1_21_7_packets.json").expect("1.21.7 file missing"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let version = packets.version;
|
||||
let serverbound_consts = parse_packets(packets.serverbound);
|
||||
let clientbound_consts = parse_packets(packets.clientbound);
|
||||
let packets_11: Packets = serde_json::from_str(
|
||||
&fs::read_to_string("../assets/packet/1_21_11_packets.json").expect("1.21.11 file missing"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let latest_version = packets_11.version;
|
||||
// 3. Generate mapped constants for both directions
|
||||
let serverbound_consts = generate_mapped_consts(&packets_11, &packets_7, true);
|
||||
let clientbound_consts = generate_mapped_consts(&packets_11, &packets_7, false);
|
||||
|
||||
quote!(
|
||||
/// The current Minecraft protocol version.
|
||||
pub const CURRENT_MC_PROTOCOL: u32 = #version;
|
||||
use pumpkin_util::version::MinecraftVersion;
|
||||
|
||||
pub const CURRENT_MC_PROTOCOL: u32 = #latest_version;
|
||||
|
||||
pub struct PacketId {
|
||||
pub latest_id: i32,
|
||||
pub v1_21_7_id: i32,
|
||||
}
|
||||
|
||||
impl PacketId {
|
||||
/// Converts the latest packet ID to the ID used in the requested version.
|
||||
/// Returns -1 if the packet does not exist in that version.
|
||||
pub fn to_id(&self, version: MinecraftVersion) -> i32 {
|
||||
match version {
|
||||
MinecraftVersion::V_1_21_11 => self.latest_id,
|
||||
MinecraftVersion::V_1_21_7 => self.v1_21_7_id,
|
||||
// Default to latest for unrecognized/unmapped versions
|
||||
_ => self.latest_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<i32> for PacketId {
|
||||
fn eq(&self, other: &i32) -> bool {
|
||||
self.latest_id == *other
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<PacketId> for i32 {
|
||||
fn eq(&self, other: &PacketId) -> bool {
|
||||
*self == other.latest_id
|
||||
}
|
||||
}
|
||||
|
||||
// We place the constants directly into these modules
|
||||
pub mod serverbound {
|
||||
#serverbound_consts
|
||||
}
|
||||
@ -36,22 +77,39 @@ pub(crate) fn build() -> TokenStream {
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn parse_packets(phases: BTreeMap<String, BTreeMap<String, i32>>) -> TokenStream {
|
||||
let mut consts = TokenStream::new();
|
||||
fn generate_mapped_consts(latest: &Packets, v7: &Packets, is_serverbound: bool) -> TokenStream {
|
||||
let mut output = TokenStream::new();
|
||||
let latest_phases = if is_serverbound {
|
||||
&latest.serverbound
|
||||
} else {
|
||||
&latest.clientbound
|
||||
};
|
||||
let v7_phases = if is_serverbound {
|
||||
&v7.serverbound
|
||||
} else {
|
||||
&v7.clientbound
|
||||
};
|
||||
|
||||
for (phase_name, packets) in phases {
|
||||
for (packet_name, packet_id) in packets {
|
||||
let sanitized_name = packet_name
|
||||
.replace("/", "_")
|
||||
.replace("-", "_")
|
||||
.to_uppercase();
|
||||
for (phase, packets) in latest_phases {
|
||||
for (name, id_11) in packets {
|
||||
let sanitized = name.replace("/", "_").replace("-", "_").to_uppercase();
|
||||
let const_name = format_ident!("{}_{}", phase.to_uppercase(), sanitized);
|
||||
|
||||
let const_name = format_ident!("{}_{}", phase_name.to_uppercase(), sanitized_name);
|
||||
// Check if the packet exists in 1.21.7 to get the alternate ID
|
||||
let id_7 = v7_phases
|
||||
.get(phase)
|
||||
.and_then(|p| p.get(name))
|
||||
.cloned()
|
||||
.unwrap_or(-1);
|
||||
|
||||
consts.extend(quote! {
|
||||
pub const #const_name: i32 = #packet_id;
|
||||
// Since serverbound/clientbound are modules, we reference the PacketId in the parent scope
|
||||
output.extend(quote! {
|
||||
pub const #const_name: super::PacketId = super::PacketId {
|
||||
latest_id: #id_11,
|
||||
v1_21_7_id: #id_7,
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
consts
|
||||
output
|
||||
}
|
||||
|
||||
@ -86,6 +86,7 @@ pub(crate) fn build() -> TokenStream {
|
||||
impl Registry {
|
||||
pub fn get_synced(version: MinecraftVersion) -> Vec<Self> {
|
||||
let static_regs = match version {
|
||||
MinecraftVersion::V_1_21_7 => REGISTRIES_1_21_9,
|
||||
MinecraftVersion::V_1_21_9 => REGISTRIES_1_21_9,
|
||||
_ => REGISTRIES_1_21_11,
|
||||
};
|
||||
|
||||
@ -205,6 +205,8 @@ pub(crate) fn build() -> TokenStream {
|
||||
});
|
||||
match_get_map
|
||||
.push(quote! { MinecraftVersion::V_1_21_9 => tags_1_21_9::get_map(tag_category) });
|
||||
match_get_map
|
||||
.push(quote! { MinecraftVersion::V_1_21_7 => tags_1_21_9::get_map(tag_category) });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,33 +1,67 @@
|
||||
use std::fs;
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote};
|
||||
use std::{collections::BTreeMap, fs};
|
||||
|
||||
pub(crate) fn build() -> TokenStream {
|
||||
println!("cargo:rerun-if-changed=../assets/tracked_data.json");
|
||||
// 1. Track files
|
||||
println!("cargo:rerun-if-changed=../assets/tracked_data/1_21_7_tracked_data.json");
|
||||
println!("cargo:rerun-if-changed=../assets/tracked_data/1_21_11_tracked_data.json");
|
||||
|
||||
let mut handlers: Vec<(String, u8)> =
|
||||
serde_json::from_str::<std::collections::BTreeMap<String, u8>>(
|
||||
&fs::read_to_string("../assets/tracked_data.json").unwrap(),
|
||||
)
|
||||
.expect("Failed to parse tracked_data.json")
|
||||
.into_iter()
|
||||
.collect();
|
||||
let data_7: BTreeMap<String, u8> = serde_json::from_str(
|
||||
&fs::read_to_string("../assets/tracked_data/1_21_7_tracked_data.json")
|
||||
.expect("1.21.7 data missing"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
handlers.sort_by_key(|&(_, id)| id);
|
||||
let data_11: BTreeMap<String, u8> = serde_json::from_str(
|
||||
&fs::read_to_string("../assets/tracked_data/1_21_11_tracked_data.json")
|
||||
.expect("1.21.11 data missing"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let constants = handlers.iter().map(|(name, id)| {
|
||||
let mut constants = TokenStream::new();
|
||||
|
||||
for (name, id_11) in &data_11 {
|
||||
let ident = format_ident!("DATA_{}", name.to_uppercase());
|
||||
quote! {
|
||||
pub const #ident: u8 = #id;
|
||||
}
|
||||
});
|
||||
|
||||
let id_7 = data_7.get(name).cloned().unwrap_or(255); // 255 as an 'Invalid' marker
|
||||
|
||||
constants.extend(quote! {
|
||||
pub const #ident: TrackedId = TrackedId {
|
||||
latest: #id_11,
|
||||
v1_21_7: #id_7,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
quote! {
|
||||
use pumpkin_util::version::MinecraftVersion;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct TrackedId {
|
||||
pub latest: u8,
|
||||
pub v1_21_7: u8,
|
||||
}
|
||||
|
||||
impl TrackedId {
|
||||
pub fn get(&self, version: &MinecraftVersion) -> u8 {
|
||||
match version {
|
||||
MinecraftVersion::V_1_21_7 => self.v1_21_7,
|
||||
_ => self.latest,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TrackedId> for u8 {
|
||||
fn from(id: TrackedId) -> u8 {
|
||||
id.latest
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TrackedData;
|
||||
|
||||
impl TrackedData {
|
||||
#(#constants)*
|
||||
#constants
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -167,6 +167,23 @@ pub fn packet(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn java_packet(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let packet_id_expr = parse_macro_input!(args as Expr);
|
||||
let ast = parse_macro_input!(item as DeriveInput);
|
||||
|
||||
let name = &ast.ident;
|
||||
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
|
||||
|
||||
quote! {
|
||||
#ast
|
||||
impl #impl_generics crate::packet::MultiVersionJavaPacket for #name #ty_generics #where_clause {
|
||||
const PACKET_ID: pumpkin_data::packet::PacketId = #packet_id_expr;
|
||||
}
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn pumpkin_block(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let input_item = item.clone();
|
||||
|
||||
@ -1,11 +1,56 @@
|
||||
use pumpkin_util::math::vector3::Vector3;
|
||||
|
||||
use crate::VarInt;
|
||||
use crate::{
|
||||
VarInt,
|
||||
ser::{NetworkWriteExt, WritingError},
|
||||
};
|
||||
use serde::{Serialize, ser::Serializer};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Velocity(pub Vector3<f64>);
|
||||
|
||||
impl Velocity {
|
||||
pub fn write<W: std::io::Write>(&self, writer: &mut W) -> Result<(), WritingError> {
|
||||
let velocity = self.0;
|
||||
let d = clamp_value(velocity.x);
|
||||
let e = clamp_value(velocity.y);
|
||||
let f = clamp_value(velocity.z);
|
||||
let g = abs_max(d, abs_max(e, f));
|
||||
|
||||
if g < MIN_VELOCITY_MAGNITUDE {
|
||||
return writer.write_slice(&[0u8]);
|
||||
}
|
||||
|
||||
let l = g.ceil() as i64;
|
||||
let bl = l > 3;
|
||||
|
||||
// The header byte: bits 0-1 are scale, bit 2 is the extension flag
|
||||
let m = if bl { (l & 3) | 4 } else { l };
|
||||
|
||||
// Pack the 15-bit quantized components into a 64-bit long
|
||||
// n (x): bits 3-17 | o (y): bits 18-32 | p (z): bits 33-47
|
||||
let n = to_long(d / l as f64) << 3;
|
||||
let o = to_long(e / l as f64) << 18;
|
||||
let p = to_long(f / l as f64) << 33;
|
||||
|
||||
let packed_data: i64 = m | n | o | p;
|
||||
|
||||
writer
|
||||
.write_all(&(packed_data as u16).to_le_bytes())
|
||||
.unwrap(); // Write low 16 bits
|
||||
writer
|
||||
.write_all(&((packed_data >> 16) as i32).to_be_bytes())
|
||||
.unwrap(); // Write next 32 bits
|
||||
|
||||
if bl {
|
||||
let scale_tail = VarInt((l >> 2) as i32);
|
||||
writer.write_var_int(&scale_tail)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
const MAX_VELOCITY_CLAMP: f64 = 1.7179869183E10;
|
||||
const MIN_VELOCITY_MAGNITUDE: f64 = 3.051944088384301E-5;
|
||||
const MAX_15_BIT_VALUE: f64 = 32766.0;
|
||||
@ -28,47 +73,7 @@ fn to_long(value: f64) -> i64 {
|
||||
impl Serialize for Velocity {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
let mut buf = Vec::new();
|
||||
let velocity = self.0;
|
||||
let d = clamp_value(velocity.x);
|
||||
let e = clamp_value(velocity.y);
|
||||
let f = clamp_value(velocity.z);
|
||||
let g = abs_max(d, abs_max(e, f));
|
||||
|
||||
if g < MIN_VELOCITY_MAGNITUDE {
|
||||
buf.push(0u8);
|
||||
return serializer.serialize_bytes(&buf);
|
||||
}
|
||||
|
||||
// l is the scale factor
|
||||
let l = g.ceil() as i64;
|
||||
// bl is true if the scale factor is > 3 and needs VarInt extension
|
||||
let bl = l > 3;
|
||||
|
||||
// m is the first byte of the packed data (low 3 bits of l + 4 if bl is true)
|
||||
let m = if bl { l & 3 | 4 } else { l };
|
||||
|
||||
// Quantize and shift the velocity components (15 bits each)
|
||||
let n: i64 = to_long(d / l as f64) << 3; // X shifted 3
|
||||
let o: i64 = to_long(e / l as f64) << 18; // Y shifted 18
|
||||
let p: i64 = to_long(f / l as f64) << 33; // Z shifted 33
|
||||
|
||||
// q is the packed 48-bit value (m + X + Y + Z)
|
||||
let q: i64 = m | n | o | p;
|
||||
|
||||
// 1. Write first byte (low 8 bits)
|
||||
buf.push(q as u8);
|
||||
|
||||
// 2. Write second byte (bits 8-15)
|
||||
buf.push((q >> 8) as u8);
|
||||
|
||||
// 3. Write remaining 4 bytes (bits 16-47) as a Big Endian i32 (Java's writeInt)
|
||||
buf.extend_from_slice(&((q >> 16) as i32).to_be_bytes());
|
||||
|
||||
// 4. Write VarInt for scale factor tail if needed
|
||||
if bl {
|
||||
VarInt::encode(&VarInt((l >> 2) as i32), &mut buf).unwrap();
|
||||
}
|
||||
|
||||
self.write(&mut buf).unwrap();
|
||||
serializer.serialize_bytes(&buf)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
use pumpkin_util::text::TextComponent;
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use pumpkin_data::packet::clientbound::CONFIG_RESOURCE_PACK_PUSH;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(CONFIG_RESOURCE_PACK_PUSH)]
|
||||
#[java_packet(CONFIG_RESOURCE_PACK_PUSH)]
|
||||
pub struct CConfigAddResourcePack<'a> {
|
||||
#[serde(with = "uuid::serde::compact")]
|
||||
pub uuid: &'a uuid::Uuid,
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
use pumpkin_data::packet::clientbound::CONFIG_DISCONNECT;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(serde::Serialize, Deserialize)]
|
||||
#[packet(CONFIG_DISCONNECT)]
|
||||
#[java_packet(CONFIG_DISCONNECT)]
|
||||
pub struct CConfigDisconnect<'a> {
|
||||
pub reason: &'a str,
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
use pumpkin_data::packet::clientbound::CONFIG_COOKIE_REQUEST;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
#[packet(CONFIG_COOKIE_REQUEST)]
|
||||
#[java_packet(CONFIG_COOKIE_REQUEST)]
|
||||
/// Requests a cookie that was previously stored.
|
||||
pub struct CCookieRequest<'a> {
|
||||
pub key: &'a ResourceLocation,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use pumpkin_data::packet::clientbound::CONFIG_FINISH_CONFIGURATION;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(CONFIG_FINISH_CONFIGURATION)]
|
||||
#[java_packet(CONFIG_FINISH_CONFIGURATION)]
|
||||
pub struct CFinishConfig;
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use pumpkin_data::packet::clientbound::CONFIG_SELECT_KNOWN_PACKS;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::KnownPack;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(CONFIG_SELECT_KNOWN_PACKS)]
|
||||
#[java_packet(CONFIG_SELECT_KNOWN_PACKS)]
|
||||
pub struct CKnownPacks<'a> {
|
||||
pub known_packs: &'a [KnownPack<'a>],
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use pumpkin_data::packet::clientbound::CONFIG_CUSTOM_PAYLOAD;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::ser::network_serialize_no_prefix;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(CONFIG_CUSTOM_PAYLOAD)]
|
||||
#[java_packet(CONFIG_CUSTOM_PAYLOAD)]
|
||||
pub struct CPluginMessage<'a> {
|
||||
pub channel: &'a str,
|
||||
#[serde(serialize_with = "network_serialize_no_prefix")]
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use crate::ser::network_serialize_no_prefix;
|
||||
use pumpkin_data::packet::clientbound::CONFIG_REGISTRY_DATA;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(CONFIG_REGISTRY_DATA)]
|
||||
#[java_packet(CONFIG_REGISTRY_DATA)]
|
||||
pub struct CRegistryData<'a> {
|
||||
pub registry_id: &'a ResourceLocation,
|
||||
pub entries: &'a [RegistryEntry],
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
use crate::Link;
|
||||
use pumpkin_data::packet::clientbound::CONFIG_SERVER_LINKS;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(CONFIG_SERVER_LINKS)]
|
||||
#[java_packet(CONFIG_SERVER_LINKS)]
|
||||
pub struct CConfigServerLinks<'a> {
|
||||
pub links: &'a [Link<'a>],
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
use pumpkin_data::packet::clientbound::CONFIG_STORE_COOKIE;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
#[packet(CONFIG_STORE_COOKIE)]
|
||||
#[java_packet(CONFIG_STORE_COOKIE)]
|
||||
/// Stores some arbitrary data on the client, which persists between server transfers.
|
||||
/// The Notchian (vanilla) client only accepts cookies of up to 5 KiB in size.
|
||||
pub struct CStoreCookie<'a> {
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
use crate::VarInt;
|
||||
use pumpkin_data::packet::clientbound::CONFIG_TRANSFER;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(CONFIG_TRANSFER)]
|
||||
#[java_packet(CONFIG_TRANSFER)]
|
||||
pub struct CTransfer<'a> {
|
||||
pub host: &'a str,
|
||||
pub port: &'a VarInt,
|
||||
|
||||
@ -7,11 +7,11 @@ use pumpkin_data::{
|
||||
packet::clientbound::CONFIG_UPDATE_TAGS,
|
||||
tag::{RegistryKey, get_registry_key_tags},
|
||||
};
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
use pumpkin_util::version::MinecraftVersion;
|
||||
|
||||
#[packet(CONFIG_UPDATE_TAGS)]
|
||||
#[java_packet(CONFIG_UPDATE_TAGS)]
|
||||
pub struct CUpdateTags<'a> {
|
||||
pub tags: &'a [pumpkin_data::tag::RegistryKey],
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::LOGIN_COOKIE_REQUEST;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
use serde::Serialize;
|
||||
|
||||
@ -8,7 +8,7 @@ use serde::Serialize;
|
||||
/// This occurs during the login phase, allowing the server to identify
|
||||
/// returning players or retrieve session data stored during a previous visit.
|
||||
#[derive(Serialize)]
|
||||
#[packet(LOGIN_COOKIE_REQUEST)]
|
||||
#[java_packet(LOGIN_COOKIE_REQUEST)]
|
||||
pub struct CLoginCookieRequest<'a> {
|
||||
/// The unique identifier of the cookie being requested.
|
||||
pub key: &'a ResourceLocation,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::LOGIN_HELLO;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Sent by the server to initiate the encryption handshake.
|
||||
@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
|
||||
/// verification token, allowing the client to generate a shared secret
|
||||
/// for secure communication.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[packet(LOGIN_HELLO)]
|
||||
#[java_packet(LOGIN_HELLO)]
|
||||
pub struct CEncryptionRequest<'a> {
|
||||
/// The server's ID string. In modern Minecraft, this is usually
|
||||
/// an empty string unless the server is using legacy authentication.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::LOGIN_LOGIN_DISCONNECT;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Sent by the server to reject a login attempt or kick a player during the login phase
|
||||
@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
|
||||
/// This is used for reasons such as the server being full, the player being banned,
|
||||
/// or version mismatches. After this packet is sent, the connection is closed.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[packet(LOGIN_LOGIN_DISCONNECT)]
|
||||
#[java_packet(LOGIN_LOGIN_DISCONNECT)]
|
||||
pub struct CLoginDisconnect {
|
||||
/// A JSON-encoded chat component explaining why the player was disconnected.
|
||||
pub json_reason: String,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::LOGIN_LOGIN_FINISHED;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::Property;
|
||||
@ -9,7 +9,7 @@ use crate::Property;
|
||||
/// This packet provides the client with its official UUID and username as
|
||||
/// recognized by the server, along with any associated skin or cape properties.
|
||||
#[derive(Serialize)]
|
||||
#[packet(LOGIN_LOGIN_FINISHED)]
|
||||
#[java_packet(LOGIN_LOGIN_FINISHED)]
|
||||
pub struct CLoginSuccess<'a> {
|
||||
/// The unique identifier assigned to the player.
|
||||
pub uuid: &'a uuid::Uuid,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::LOGIN_CUSTOM_QUERY;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{VarInt, ser::network_serialize_no_prefix};
|
||||
@ -9,7 +9,7 @@ use crate::{VarInt, ser::network_serialize_no_prefix};
|
||||
/// This is used by server software (like proxies or anti-cheats) to request
|
||||
/// information from a client-side mod before the player officially joins.
|
||||
#[derive(Serialize)]
|
||||
#[packet(LOGIN_CUSTOM_QUERY)]
|
||||
#[java_packet(LOGIN_CUSTOM_QUERY)]
|
||||
pub struct CLoginPluginRequest<'a> {
|
||||
/// A unique ID for this request. The client must include this same ID
|
||||
/// in its response so the server can match them up.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::LOGIN_LOGIN_COMPRESSION;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::VarInt;
|
||||
@ -9,7 +9,7 @@ use crate::VarInt;
|
||||
/// Once this packet is sent, both the server and the client must compress any
|
||||
/// packet with a size equal to or greater than the specified threshold.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[packet(LOGIN_LOGIN_COMPRESSION)]
|
||||
#[java_packet(LOGIN_LOGIN_COMPRESSION)]
|
||||
pub struct CSetCompression {
|
||||
/// The packet size threshold (in bytes) at which compression is applied.
|
||||
///
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_BLOCK_CHANGED_ACK;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::VarInt;
|
||||
@ -9,7 +9,7 @@ use crate::VarInt;
|
||||
/// This packet is critical for preventing "ghost blocks" and synchronization issues.
|
||||
/// It tells the client that the server has processed all actions up to a specific point.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[packet(PLAY_BLOCK_CHANGED_ACK)]
|
||||
#[java_packet(PLAY_BLOCK_CHANGED_ACK)]
|
||||
pub struct CAcknowledgeBlockChange {
|
||||
/// The ID of the last sequence processed by the server.
|
||||
///
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_SET_ACTION_BAR_TEXT;
|
||||
use pumpkin_util::text::TextComponent;
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
/// Updates the text displayed above the player's hotbar (the Action Bar).
|
||||
@ -10,7 +10,7 @@ use serde::Serialize;
|
||||
/// non-critical status information like "Now entering: Wilderness" or
|
||||
/// mana/stamina counters.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_ACTION_BAR_TEXT)]
|
||||
#[java_packet(PLAY_SET_ACTION_BAR_TEXT)]
|
||||
pub struct CActionBar<'a> {
|
||||
/// The text component to be displayed.
|
||||
pub action_bar: &'a TextComponent,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_BLOCK_DESTRUCTION;
|
||||
use pumpkin_util::math::position::BlockPos;
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
@ -11,7 +11,7 @@ use crate::VarInt;
|
||||
/// This packet controls the overlay of cracks that appear on a block when
|
||||
/// it is being mined. It is often used to show other players' mining progress.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_BLOCK_DESTRUCTION)]
|
||||
#[java_packet(PLAY_BLOCK_DESTRUCTION)]
|
||||
pub struct CSetBlockDestroyStage {
|
||||
/// A unique ID for this destruction instance. Usually the miner's Entity ID.
|
||||
/// If multiple entities mine the same block, they must use different IDs.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_BLOCK_ENTITY_DATA;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::math::position::BlockPos;
|
||||
use serde::Serialize;
|
||||
|
||||
@ -10,7 +10,7 @@ use crate::{VarInt, ser::network_serialize_no_prefix};
|
||||
/// This packet is sent by the server when a block entity's state changes
|
||||
/// (like text on a sign) or when the block entity is loaded into the client's view.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_BLOCK_ENTITY_DATA)]
|
||||
#[java_packet(PLAY_BLOCK_ENTITY_DATA)]
|
||||
pub struct CBlockEntityData {
|
||||
/// The world coordinates of the block entity.
|
||||
pub location: BlockPos,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_BLOCK_EVENT;
|
||||
use pumpkin_util::math::position::BlockPos;
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
@ -11,7 +11,7 @@ use crate::VarInt;
|
||||
/// This is used for simple block interactions that don't necessarily change
|
||||
/// NBT data, such as chests opening/closing, pistons extending, or note blocks playing.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_BLOCK_EVENT)]
|
||||
#[java_packet(PLAY_BLOCK_EVENT)]
|
||||
pub struct CBlockEvent {
|
||||
/// The coordinates where the event occurs.
|
||||
pub location: BlockPos,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_BLOCK_UPDATE;
|
||||
use pumpkin_util::math::position::BlockPos;
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
@ -11,7 +11,7 @@ use crate::VarInt;
|
||||
/// This is the most common way to sync world changes to the client, such as
|
||||
/// when a player places a block, a fluid flows, or a redstone component toggles.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_BLOCK_UPDATE)]
|
||||
#[java_packet(PLAY_BLOCK_UPDATE)]
|
||||
pub struct CBlockUpdate {
|
||||
/// The world coordinates of the block being updated.
|
||||
pub location: BlockPos,
|
||||
|
||||
@ -4,14 +4,14 @@ use crate::java::client::play::BosseventAction;
|
||||
use crate::ser::NetworkWriteExt;
|
||||
use crate::{ClientPacket, WritingError};
|
||||
use pumpkin_data::packet::clientbound::PLAY_BOSS_EVENT;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::version::MinecraftVersion;
|
||||
|
||||
/// Updates the "Boss Bar" displayed at the top of the player's screen.
|
||||
///
|
||||
/// This packet is used to manage health bars for entities like the Ender Dragon
|
||||
/// or Wither, as well as custom progress bars for server events or raids.
|
||||
#[packet(PLAY_BOSS_EVENT)]
|
||||
#[java_packet(PLAY_BOSS_EVENT)]
|
||||
pub struct CBossEvent<'a> {
|
||||
/// A unique identifier for this specific boss bar instance.
|
||||
pub uuid: &'a uuid::Uuid,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_SET_CHUNK_CACHE_CENTER;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
@ -10,7 +10,7 @@ use crate::VarInt;
|
||||
/// focal point for loading and unloading chunks. It is typically sent when
|
||||
/// a player moves across a chunk boundary.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_CHUNK_CACHE_CENTER)]
|
||||
#[java_packet(PLAY_SET_CHUNK_CACHE_CENTER)]
|
||||
pub struct CCenterChunk {
|
||||
/// The X coordinate of the center chunk.
|
||||
pub chunk_x: VarInt,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_CHANGE_DIFFICULTY;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
/// Notifies the client of a change in the world's difficulty level or lock status.
|
||||
@ -8,7 +8,7 @@ use serde::Serialize;
|
||||
/// and client-side behavior (though actual game logic like mob damage is
|
||||
/// primarily handled by the server).
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_CHANGE_DIFFICULTY)]
|
||||
#[java_packet(PLAY_CHANGE_DIFFICULTY)]
|
||||
pub struct CChangeDifficulty {
|
||||
/// The current difficulty level of the world.
|
||||
///
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_CHUNK_BATCH_FINISHED;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::codec::var_int::VarInt;
|
||||
@ -10,7 +10,7 @@ use crate::codec::var_int::VarInt;
|
||||
/// allows the client to acknowledge the receipt of a group of chunks, helping
|
||||
/// the server regulate the flow of data and prevent network congestion.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_CHUNK_BATCH_FINISHED)]
|
||||
#[java_packet(PLAY_CHUNK_BATCH_FINISHED)]
|
||||
pub struct CChunkBatchEnd {
|
||||
/// The number of chunks sent in the batch that just finished.
|
||||
pub batch_size: VarInt,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_CHUNK_BATCH_START;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
/// Signals the beginning of a new batch of chunk data packets.
|
||||
@ -9,5 +9,5 @@ use serde::Serialize;
|
||||
/// a `Start` and `End` packet to manage client-side backpressure and
|
||||
/// network throughput.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_CHUNK_BATCH_START)]
|
||||
#[java_packet(PLAY_CHUNK_BATCH_START)]
|
||||
pub struct CChunkBatchStart;
|
||||
|
||||
@ -2,7 +2,7 @@ use crate::WritingError;
|
||||
use crate::codec::bit_set::BitSet;
|
||||
use crate::{ClientPacket, VarInt, ser::NetworkWriteExt};
|
||||
use pumpkin_data::packet::clientbound::PLAY_LEVEL_CHUNK_WITH_LIGHT;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_nbt::END_ID;
|
||||
use pumpkin_util::math::position::get_local_cord;
|
||||
use pumpkin_util::version::MinecraftVersion;
|
||||
@ -15,7 +15,7 @@ use std::io::Write;
|
||||
/// This includes heightmaps, the actual block and biome data (organized into sections),
|
||||
/// block entities (like signs or chests), and the light level information for both
|
||||
/// sky and block light.
|
||||
#[packet(PLAY_LEVEL_CHUNK_WITH_LIGHT)]
|
||||
#[java_packet(PLAY_LEVEL_CHUNK_WITH_LIGHT)]
|
||||
pub struct CChunkData<'a>(pub &'a ChunkData);
|
||||
|
||||
impl ClientPacket for CChunkData<'_> {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_CLEAR_TITLES;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
/// Removes any currently displayed Title or Subtitle from the player's screen.
|
||||
@ -7,7 +7,7 @@ use serde::Serialize;
|
||||
/// This packet is used to immediately hide titles that are currently in their
|
||||
/// "stay" or "fade-out" phases.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_CLEAR_TITLES)]
|
||||
#[java_packet(PLAY_CLEAR_TITLES)]
|
||||
pub struct CClearTitle {
|
||||
/// If true, the client also resets the title timings (fade-in, stay, fade-out)
|
||||
/// to their default values (10, 70, 20 ticks).
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_CONTAINER_CLOSE;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
@ -10,7 +10,7 @@ use crate::VarInt;
|
||||
/// if the player moves too far away from a chest or if an NPC's trade window
|
||||
/// is invalidated.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_CONTAINER_CLOSE)]
|
||||
#[java_packet(PLAY_CONTAINER_CLOSE)]
|
||||
pub struct CCloseContainer {
|
||||
/// The ID of the container window to close.
|
||||
///
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_PLAYER_COMBAT_KILL;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::text::TextComponent;
|
||||
use serde::Serialize;
|
||||
|
||||
@ -10,7 +10,7 @@ use crate::VarInt;
|
||||
/// This packet is responsible for triggering the death screen on the client
|
||||
/// and displaying the death message in the chat for the deceased player.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_PLAYER_COMBAT_KILL)]
|
||||
#[java_packet(PLAY_PLAYER_COMBAT_KILL)]
|
||||
pub struct CCombatDeath<'a> {
|
||||
/// The Entity ID of the player who died.
|
||||
pub player_id: VarInt,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_COMMAND_SUGGESTIONS;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::text::TextComponent;
|
||||
use serde::Serialize;
|
||||
|
||||
@ -11,7 +11,7 @@ use crate::VarInt;
|
||||
/// appearing as a scrollable list of options while the player is typing
|
||||
/// in the chat bar.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_COMMAND_SUGGESTIONS)]
|
||||
#[java_packet(PLAY_COMMAND_SUGGESTIONS)]
|
||||
pub struct CCommandSuggestions {
|
||||
/// The unique ID of the request this response is for.
|
||||
/// This must match the ID sent by the client in the request packet.
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use std::io::Write;
|
||||
|
||||
use pumpkin_data::packet::clientbound::PLAY_COMMANDS;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::version::MinecraftVersion;
|
||||
|
||||
use crate::{ClientPacket, VarInt, WritingError, ser::NetworkWriteExt};
|
||||
@ -11,7 +11,7 @@ use crate::{ClientPacket, VarInt, WritingError, ser::NetworkWriteExt};
|
||||
/// Minecraft uses the "Brigadier" command system. This packet informs the client
|
||||
/// which commands exist, their arguments, and how they branch, allowing the
|
||||
/// client to highlight syntax errors in red before the command is even sent.
|
||||
#[packet(PLAY_COMMANDS)]
|
||||
#[java_packet(PLAY_COMMANDS)]
|
||||
pub struct CCommands<'a> {
|
||||
/// A flat list of all nodes in the command graph.
|
||||
/// Nodes reference each other by their index in this array.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_COOKIE_REQUEST;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
use serde::Serialize;
|
||||
|
||||
@ -9,7 +9,7 @@ use serde::Serialize;
|
||||
/// small amounts of persistent data on the client side that can be retrieved
|
||||
/// even across different server instances or sub-servers in a network.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_COOKIE_REQUEST)]
|
||||
#[java_packet(PLAY_COOKIE_REQUEST)]
|
||||
pub struct CPlayCookieRequest<'a> {
|
||||
/// The unique identifier (namespace:path) of the cookie to retrieve.
|
||||
pub key: &'a ResourceLocation,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_DAMAGE_EVENT;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::math::vector3::Vector3;
|
||||
use serde::Serialize;
|
||||
|
||||
@ -12,7 +12,7 @@ use crate::VarInt;
|
||||
/// with specific details about the damage source to ensure the visual feedback
|
||||
/// matches the cause.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_DAMAGE_EVENT)]
|
||||
#[java_packet(PLAY_DAMAGE_EVENT)]
|
||||
pub struct CDamageEvent {
|
||||
/// The Entity ID of the entity taking damage.
|
||||
pub entity_id: VarInt,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_DISCONNECT;
|
||||
use pumpkin_util::text::TextComponent;
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
/// Forces the client to disconnect from the server while in the "Play" state.
|
||||
@ -10,7 +10,7 @@ use serde::Serialize;
|
||||
/// disconnection screen. It is used for kicks, server shutdowns, or when
|
||||
/// a player is banned.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_DISCONNECT)]
|
||||
#[java_packet(PLAY_DISCONNECT)]
|
||||
pub struct CPlayDisconnect<'a> {
|
||||
/// The message shown to the player explaining why they were disconnected.
|
||||
/// This supports full JSON formatting (colors, bold, links, etc.).
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_DISGUISED_CHAT;
|
||||
use pumpkin_util::text::TextComponent;
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
@ -12,7 +12,7 @@ use crate::VarInt;
|
||||
/// this packet bypasses the player-to-player chat signing requirements while
|
||||
/// still allowing the client to format the message using the standard chat registry.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_DISGUISED_CHAT)]
|
||||
#[java_packet(PLAY_DISGUISED_CHAT)]
|
||||
pub struct CDisguisedChatMessage<'a> {
|
||||
/// The raw content of the message.
|
||||
pub message: &'a TextComponent,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use pumpkin_data::{
|
||||
packet::clientbound::PLAY_SET_DISPLAY_OBJECTIVE, scoreboard::ScoreboardDisplaySlot,
|
||||
};
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
@ -12,7 +12,7 @@ use crate::VarInt;
|
||||
/// an objective is created and populated with scores, this packet "maps"
|
||||
/// that objective to a visual location like the sidebar or the player list.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_DISPLAY_OBJECTIVE)]
|
||||
#[java_packet(PLAY_SET_DISPLAY_OBJECTIVE)]
|
||||
pub struct CDisplayObjective {
|
||||
/// The display slot/position for the objective.
|
||||
pub position: VarInt,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_ANIMATE;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
@ -9,7 +9,7 @@ use crate::VarInt;
|
||||
/// This is primarily used for player-driven animations like swinging an arm
|
||||
/// or showing damage, but it can apply to other entities as well.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_ANIMATE)]
|
||||
#[java_packet(PLAY_ANIMATE)]
|
||||
pub struct CEntityAnimation {
|
||||
/// The Entity ID of the entity performing the animation.
|
||||
pub entity_id: VarInt,
|
||||
|
||||
@ -1,8 +1,14 @@
|
||||
use pumpkin_data::{meta_data_type::MetaDataType, packet::clientbound::PLAY_SET_ENTITY_DATA};
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_data::{
|
||||
meta_data_type::MetaDataType, packet::clientbound::PLAY_SET_ENTITY_DATA,
|
||||
tracked_data::TrackedId,
|
||||
};
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{VarInt, ser::network_serialize_no_prefix};
|
||||
use crate::{
|
||||
VarInt,
|
||||
ser::{NetworkWriteExt, WritingError, network_serialize_no_prefix, serializer},
|
||||
};
|
||||
|
||||
/// Updates the "Data Tracker" values for an entity.
|
||||
///
|
||||
@ -10,7 +16,7 @@ use crate::{VarInt, ser::network_serialize_no_prefix};
|
||||
/// don't require a full packet to update, such as whether an entity is on fire,
|
||||
/// crouching, glowing, or the custom name displayed above its head.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_ENTITY_DATA)]
|
||||
#[java_packet(PLAY_SET_ENTITY_DATA)]
|
||||
pub struct CSetEntityMetadata {
|
||||
/// The Entity ID of the entity whose metadata is being updated.
|
||||
pub entity_id: VarInt,
|
||||
@ -29,19 +35,43 @@ impl CSetEntityMetadata {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone)]
|
||||
pub struct Metadata<T> {
|
||||
index: u8,
|
||||
index: TrackedId,
|
||||
r#type: VarInt,
|
||||
value: T,
|
||||
}
|
||||
|
||||
impl<T> Metadata<T> {
|
||||
pub fn new(index: u8, r#type: MetaDataType, value: T) -> Self {
|
||||
pub fn new(index: TrackedId, r#type: MetaDataType, value: T) -> Self {
|
||||
Self {
|
||||
index,
|
||||
r#type: VarInt(r#type as i32),
|
||||
value,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write<W: std::io::Write>(
|
||||
&self,
|
||||
mut writer: W,
|
||||
version: &pumpkin_util::version::MinecraftVersion,
|
||||
) -> Result<(), WritingError>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
let resolved_index = self.index.get(version);
|
||||
|
||||
if resolved_index == 255 {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
writer.write_u8(resolved_index)?;
|
||||
self.r#type.encode(&mut writer)?;
|
||||
|
||||
let mut serializer = serializer::Serializer::new(&mut writer);
|
||||
self.value
|
||||
.serialize(&mut serializer)
|
||||
.map_err(|e| WritingError::Serde(e.to_string()))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_ENTITY_POSITION_SYNC;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::math::vector3::Vector3;
|
||||
use serde::Serialize;
|
||||
|
||||
@ -13,7 +13,7 @@ use crate::VarInt;
|
||||
///
|
||||
/// Note: This packet must NOT be used for the player receiving the packet or
|
||||
/// any entity the player is currently riding.
|
||||
#[packet(PLAY_ENTITY_POSITION_SYNC)]
|
||||
#[java_packet(PLAY_ENTITY_POSITION_SYNC)]
|
||||
#[derive(Serialize)]
|
||||
pub struct CEntityPositionSync {
|
||||
/// The Entity ID of the entity being moved.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::{packet::clientbound::PLAY_SOUND_ENTITY, sound::SoundCategory};
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{IdOr, SoundEvent, VarInt};
|
||||
@ -10,7 +10,7 @@ use crate::{IdOr, SoundEvent, VarInt};
|
||||
/// through the world. The client handles the panning and attenuation
|
||||
/// (volume drop-off) based on the distance between the player and the entity.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SOUND_ENTITY)]
|
||||
#[java_packet(PLAY_SOUND_ENTITY)]
|
||||
pub struct CEntitySoundEffect {
|
||||
/// The sound to play. Can be a hardcoded ID or a custom SoundEvent
|
||||
/// (Resource Location).
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_ENTITY_EVENT;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Sends a status update for a specific entity.
|
||||
@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
|
||||
/// and logical state triggers, such as tool breaking, totem usage,
|
||||
/// or sheep shearing.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[packet(PLAY_ENTITY_EVENT)]
|
||||
#[java_packet(PLAY_ENTITY_EVENT)]
|
||||
pub struct CEntityStatus {
|
||||
/// The Entity ID of the entity affected by the status change.
|
||||
pub entity_id: i32,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_SET_ENTITY_MOTION;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::math::vector3::Vector3;
|
||||
use serde::Serialize;
|
||||
|
||||
@ -10,7 +10,7 @@ use crate::{VarInt, codec::velocity::Velocity};
|
||||
/// This packet informs the client of a sudden change in an entity's movement,
|
||||
/// such as knockback from an attack, explosions, or being launched by a piston.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_ENTITY_MOTION)]
|
||||
#[java_packet(PLAY_SET_ENTITY_MOTION)]
|
||||
pub struct CEntityVelocity {
|
||||
/// The Entity ID of the entity whose velocity is being set
|
||||
pub entity_id: VarInt,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_EXPLODE;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::math::vector3::Vector3;
|
||||
use serde::Serialize;
|
||||
|
||||
@ -11,7 +11,7 @@ use crate::{IdOr, SoundEvent, codec::var_int::VarInt};
|
||||
/// effects of an explosion in a single call. It triggers the explosion particles,
|
||||
/// plays the sound at the source, and applies knockback to the player.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_EXPLODE)]
|
||||
#[java_packet(PLAY_EXPLODE)]
|
||||
pub struct CExplosion {
|
||||
/// The center coordinates of the explosion.
|
||||
pub center: Vector3<f64>,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_GAME_EVENT;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Updates the game state or triggers specific environmental changes.
|
||||
@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
|
||||
/// context-specific transitions, such as changing the weather,
|
||||
/// altering the player's gamemode, or displaying the credits.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[packet(PLAY_GAME_EVENT)]
|
||||
#[java_packet(PLAY_GAME_EVENT)]
|
||||
pub struct CGameEvent {
|
||||
/// The ID of the event type.
|
||||
pub event: u8,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_ROTATE_HEAD;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::VarInt;
|
||||
@ -11,7 +11,7 @@ use crate::VarInt;
|
||||
/// required to make an entity (like a player or a mob) look in a
|
||||
/// specific direction without necessarily turning its entire body.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[packet(PLAY_ROTATE_HEAD)]
|
||||
#[java_packet(PLAY_ROTATE_HEAD)]
|
||||
pub struct CHeadRot {
|
||||
/// The Entity ID of the entity whose head is rotating.
|
||||
pub entity_id: VarInt,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_HURT_ANIMATION;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::VarInt;
|
||||
@ -10,7 +10,7 @@ use crate::VarInt;
|
||||
/// camera shake or model tilt. It is typically sent immediately after
|
||||
/// an entity's health is reduced.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[packet(PLAY_HURT_ANIMATION)]
|
||||
#[java_packet(PLAY_HURT_ANIMATION)]
|
||||
pub struct CHurtAnimation {
|
||||
/// The Entity ID of the entity that was hurt.
|
||||
pub entity_id: VarInt,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_INITIALIZE_BORDER;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{VarInt, codec::var_long::VarLong};
|
||||
@ -10,7 +10,7 @@ use crate::{VarInt, codec::var_long::VarLong};
|
||||
/// It synchronizes the current position, size, and all warning parameters
|
||||
/// to ensure the client-side visual barrier matches the server's authority.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_INITIALIZE_BORDER)]
|
||||
#[java_packet(PLAY_INITIALIZE_BORDER)]
|
||||
pub struct CInitializeWorldBorder {
|
||||
/// The X coordinate of the center of the world border.
|
||||
pub x: f64,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_KEEP_ALIVE;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Maintains the connection and measures latency (ping) between client and server.
|
||||
@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
|
||||
/// a response within a timeout period (usually 30 seconds), it will disconnect
|
||||
/// the player with a "Timed Out" message.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[packet(PLAY_KEEP_ALIVE)]
|
||||
#[java_packet(PLAY_KEEP_ALIVE)]
|
||||
pub struct CKeepAlive {
|
||||
/// A unique random identifier for this specific keep-alive request.
|
||||
/// Used to match the server's request with the client's response.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_LEVEL_EVENT;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::math::position::BlockPos;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
|
||||
/// block breaking particles, firework explosions, or ambient sounds
|
||||
/// like doors opening and portals humming.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[packet(PLAY_LEVEL_EVENT)]
|
||||
#[java_packet(PLAY_LEVEL_EVENT)]
|
||||
pub struct CLevelEvent {
|
||||
/// The ID of the event to trigger.
|
||||
/// Event IDs are generally divided into Sound Events (1000s) and
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_LOGIN;
|
||||
use pumpkin_util::{math::position::BlockPos, resource_location::ResourceLocation};
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
@ -13,7 +13,7 @@ use crate::VarInt;
|
||||
/// initializes the player's world view, dimension settings, and local game
|
||||
/// rules. Once received, the client begins rendering the world.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_LOGIN)]
|
||||
#[java_packet(PLAY_LOGIN)]
|
||||
pub struct CLogin<'a> {
|
||||
/// The unique ID assigned to the player for the current session.
|
||||
pub entity_id: i32,
|
||||
|
||||
@ -4,7 +4,7 @@ use pumpkin_util::math::{
|
||||
vector3::{self, Vector3},
|
||||
};
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::{Serialize, ser::SerializeTuple};
|
||||
|
||||
use crate::codec::{var_int::VarInt, var_long::VarLong};
|
||||
@ -14,7 +14,7 @@ use crate::codec::{var_int::VarInt, var_long::VarLong};
|
||||
/// This packet is much more efficient than sending multiple individual
|
||||
/// `CBlockUpdate` packets when many changes occur in the same area
|
||||
/// (e.g., explosions, structure generation, or large-scale terraforming).
|
||||
#[packet(PLAY_SECTION_BLOCKS_UPDATE)]
|
||||
#[java_packet(PLAY_SECTION_BLOCKS_UPDATE)]
|
||||
pub struct CMultiBlockUpdate {
|
||||
/// The coordinates of the chunk section being updated.
|
||||
/// Calculated as (block_coord >> 4).
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_OPEN_SCREEN;
|
||||
use pumpkin_util::text::TextComponent;
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
@ -13,7 +13,7 @@ use crate::VarInt;
|
||||
/// `sync_id` which must be used in all subsequent "Set Slot" or "Click Slot"
|
||||
/// packets to ensure the server and client are talking about the same window.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_OPEN_SCREEN)]
|
||||
#[java_packet(PLAY_OPEN_SCREEN)]
|
||||
pub struct COpenScreen<'a> {
|
||||
/// A unique identifier for the current window session.
|
||||
/// Typically increments by 1 for every new window opened.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_OPEN_SIGN_EDITOR;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::math::position::BlockPos;
|
||||
use serde::Serialize;
|
||||
|
||||
@ -9,7 +9,7 @@ use serde::Serialize;
|
||||
/// sign editing interface. This usually happens immediately after a
|
||||
/// player places a sign or interacts with an existing one (if allowed).
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_OPEN_SIGN_EDITOR)]
|
||||
#[java_packet(PLAY_OPEN_SIGN_EDITOR)]
|
||||
pub struct COpenSignEditor {
|
||||
/// The world coordinates of the sign block to be edited.
|
||||
pub location: BlockPos,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_LEVEL_PARTICLES;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::math::vector3::Vector3;
|
||||
use serde::Serialize;
|
||||
|
||||
@ -12,7 +12,7 @@ use crate::{VarInt, ser::network_serialize_no_prefix};
|
||||
/// carry extra data for complex particles like redstone dust (color) or
|
||||
/// block/item breaking (textures).
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_LEVEL_PARTICLES)]
|
||||
#[java_packet(PLAY_LEVEL_PARTICLES)]
|
||||
pub struct CParticle<'a> {
|
||||
/// If true, the particle renders even if the client's "Particles"
|
||||
/// setting is set to "Minimal".
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_PONG_RESPONSE;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Responds to a client-initiated ping request to synchronize game state.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[packet(PLAY_PONG_RESPONSE)]
|
||||
#[java_packet(PLAY_PONG_RESPONSE)]
|
||||
pub struct CPingResponse {
|
||||
/// The unique identifier sent by the client in the initial Ping packet.
|
||||
/// The server must return this exact value.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_PLAYER_ABILITIES;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
/// Updates the player's movement and interaction abilities.
|
||||
@ -8,7 +8,7 @@ use serde::Serialize;
|
||||
/// and sets the movement speeds. While the client applies these visuals,
|
||||
/// the server must still validate these states to prevent cheating.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_PLAYER_ABILITIES)]
|
||||
#[java_packet(PLAY_PLAYER_ABILITIES)]
|
||||
pub struct CPlayerAbilities {
|
||||
/// A bitmask of player states.
|
||||
/// Bit 0 (0x01): Invulnerable (Creative mode)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use std::io::Write;
|
||||
|
||||
use pumpkin_data::packet::clientbound::PLAY_PLAYER_CHAT;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::{text::TextComponent, version::MinecraftVersion};
|
||||
|
||||
use crate::{
|
||||
@ -14,7 +14,7 @@ use crate::{
|
||||
///
|
||||
/// This packet is the backbone of the modern secure chat system. It includes
|
||||
/// tracking indices, digital signatures, and context for reporting.
|
||||
#[packet(PLAY_PLAYER_CHAT)]
|
||||
#[java_packet(PLAY_PLAYER_CHAT)]
|
||||
pub struct CPlayerChatMessage {
|
||||
/// Incremental index for messages sent TO this specific client.
|
||||
/// Starts at 0 on login; client disconnects if the sequence is broken.
|
||||
|
||||
@ -2,7 +2,7 @@ use std::io::Write;
|
||||
|
||||
use bitflags::bitflags;
|
||||
use pumpkin_data::packet::clientbound::PLAY_PLAYER_INFO_UPDATE;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::version::MinecraftVersion;
|
||||
|
||||
use crate::{ClientPacket, Property, WritingError, ser::NetworkWriteExt};
|
||||
@ -40,7 +40,7 @@ bitflags! {
|
||||
/// This packet replaces the legacy "Player Info" packet with a more efficient
|
||||
/// bitmask-driven approach. Instead of sending full data every time, the
|
||||
/// server only sends the fields specified in the `actions` bitmask.
|
||||
#[packet(PLAY_PLAYER_INFO_UPDATE)]
|
||||
#[java_packet(PLAY_PLAYER_INFO_UPDATE)]
|
||||
pub struct CPlayerInfoUpdate<'a> {
|
||||
/// The bitmask (PlayerInfoFlags) determining which data follows.
|
||||
pub actions: u8,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use std::io::Write;
|
||||
|
||||
use pumpkin_data::packet::clientbound::PLAY_PLAYER_POSITION;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::{math::vector3::Vector3, version::MinecraftVersion};
|
||||
|
||||
use crate::{
|
||||
@ -14,7 +14,7 @@ use crate::{
|
||||
/// Commonly known as the "Teleport Packet," this is sent by the server to
|
||||
/// force a change in the player's location. The client must respond with a
|
||||
/// `Teleport Confirm` packet matching the `teleport_id`.
|
||||
#[packet(PLAY_PLAYER_POSITION)]
|
||||
#[java_packet(PLAY_PLAYER_POSITION)]
|
||||
pub struct CPlayerPosition {
|
||||
/// A unique ID for this teleport. The client must echo this back
|
||||
/// to confirm the teleport was processed.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_PLAYER_INFO_REMOVE;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::{Serialize, ser::SerializeSeq};
|
||||
|
||||
/// Sent by the server to remove one or more players from the client's player list (tab list).
|
||||
@ -7,7 +7,7 @@ use serde::{Serialize, ser::SerializeSeq};
|
||||
/// This packet is typically used when a player leaves the server or becomes invisible
|
||||
/// to the recipient (e.g., moving out of tracking range).
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_PLAYER_INFO_REMOVE)]
|
||||
#[java_packet(PLAY_PLAYER_INFO_REMOVE)]
|
||||
pub struct CRemovePlayerInfo<'a> {
|
||||
/// A list of UUIDs corresponding to the players that should be removed.
|
||||
///
|
||||
|
||||
@ -1,15 +1,19 @@
|
||||
use serde::Serialize;
|
||||
use std::io::Write;
|
||||
|
||||
use pumpkin_data::packet::clientbound::PLAY_SET_DEFAULT_SPAWN_POSITION;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_util::math::position::BlockPos;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::{math::position::BlockPos, version::MinecraftVersion};
|
||||
|
||||
use crate::{
|
||||
ClientPacket,
|
||||
ser::{NetworkWriteExt, WritingError},
|
||||
};
|
||||
|
||||
/// Sent by the server to set the client's default spawn point and compass target.
|
||||
///
|
||||
/// This packet updates where the player will respawn upon death (if no bed or anchor is set)
|
||||
/// and dictates the coordinates that a compass will point toward.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_DEFAULT_SPAWN_POSITION)]
|
||||
#[java_packet(PLAY_SET_DEFAULT_SPAWN_POSITION)]
|
||||
pub struct CPlayerSpawnPosition {
|
||||
/// The namespaced ID of the dimension (e.g., "minecraft:overworld").
|
||||
/// Required for the client to determine if the spawn point is in their current world.
|
||||
@ -32,3 +36,25 @@ impl CPlayerSpawnPosition {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ClientPacket for CPlayerSpawnPosition {
|
||||
fn write_packet_data(
|
||||
&self,
|
||||
write: impl Write,
|
||||
version: &MinecraftVersion,
|
||||
) -> Result<(), WritingError> {
|
||||
let mut write = write;
|
||||
|
||||
if *version >= MinecraftVersion::V_1_21_9 {
|
||||
write.write_string(&self.dimension_name)?;
|
||||
}
|
||||
write.write_block_pos(&self.location)?;
|
||||
write.write_f32_be(self.yaw)?;
|
||||
|
||||
if *version >= MinecraftVersion::V_1_21_9 {
|
||||
write.write_f32_be(self.pitch)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_REMOVE_ENTITIES;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
@ -9,7 +9,7 @@ use crate::VarInt;
|
||||
/// This is typically sent when an entity leaves the player's tracking range,
|
||||
/// is killed, or is otherwise removed from the world.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_REMOVE_ENTITIES)]
|
||||
#[java_packet(PLAY_REMOVE_ENTITIES)]
|
||||
pub struct CRemoveEntities<'a> {
|
||||
/// A list of entity IDs to be removed.
|
||||
pub entity_ids: &'a [VarInt],
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
use crate::codec::var_int::VarInt;
|
||||
use pumpkin_data::packet::clientbound::PLAY_REMOVE_MOB_EFFECT;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_REMOVE_MOB_EFFECT)]
|
||||
#[java_packet(PLAY_REMOVE_MOB_EFFECT)]
|
||||
pub struct CRemoveMobEffect {
|
||||
pub entity_id: VarInt,
|
||||
pub effect_id: VarInt,
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_RESET_SCORE;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_RESET_SCORE)]
|
||||
#[java_packet(PLAY_RESET_SCORE)]
|
||||
pub struct CResetScore {
|
||||
pub entity_name: String,
|
||||
pub objective_name: Option<String>,
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_RESPAWN;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::{math::position::BlockPos, resource_location::ResourceLocation};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::VarInt;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[packet(PLAY_RESPAWN)]
|
||||
#[java_packet(PLAY_RESPAWN)]
|
||||
pub struct CRespawn {
|
||||
pub dimension_type: VarInt,
|
||||
pub dimension_name: ResourceLocation,
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
use crate::Link;
|
||||
use pumpkin_data::packet::clientbound::PLAY_SERVER_LINKS;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SERVER_LINKS)]
|
||||
#[java_packet(PLAY_SERVER_LINKS)]
|
||||
pub struct CPlayServerLinks<'a> {
|
||||
pub links: &'a [Link<'a>],
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_SET_BORDER_CENTER;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_BORDER_CENTER)]
|
||||
#[java_packet(PLAY_SET_BORDER_CENTER)]
|
||||
pub struct CSetBorderCenter {
|
||||
pub x: f64,
|
||||
pub z: f64,
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_SET_BORDER_LERP_SIZE;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::codec::var_long::VarLong;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_BORDER_LERP_SIZE)]
|
||||
#[java_packet(PLAY_SET_BORDER_LERP_SIZE)]
|
||||
pub struct CSetBorderLerpSize {
|
||||
pub old_diameter: f64,
|
||||
pub new_diameter: f64,
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_SET_BORDER_SIZE;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_BORDER_SIZE)]
|
||||
#[java_packet(PLAY_SET_BORDER_SIZE)]
|
||||
pub struct CSetBorderSize {
|
||||
pub diameter: f64,
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_SET_BORDER_WARNING_DELAY;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_BORDER_WARNING_DELAY)]
|
||||
#[java_packet(PLAY_SET_BORDER_WARNING_DELAY)]
|
||||
pub struct CSetBorderWarningDelay {
|
||||
pub warning_time: VarInt,
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_SET_BORDER_WARNING_DISTANCE;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_BORDER_WARNING_DISTANCE)]
|
||||
#[java_packet(PLAY_SET_BORDER_WARNING_DISTANCE)]
|
||||
pub struct CSetBorderWarningDistance {
|
||||
pub warning_blocks: VarInt,
|
||||
}
|
||||
|
||||
@ -2,11 +2,11 @@ use crate::VarInt;
|
||||
use crate::codec::item_stack_seralizer::ItemStackSerializer;
|
||||
|
||||
use pumpkin_data::packet::clientbound::PLAY_CONTAINER_SET_CONTENT;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_CONTAINER_SET_CONTENT)]
|
||||
#[java_packet(PLAY_CONTAINER_SET_CONTENT)]
|
||||
pub struct CSetContainerContent<'a> {
|
||||
pub window_id: VarInt,
|
||||
pub state_id: VarInt,
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_CONTAINER_SET_DATA;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_CONTAINER_SET_DATA)]
|
||||
#[java_packet(PLAY_CONTAINER_SET_DATA)]
|
||||
pub struct CSetContainerProperty {
|
||||
pub window_id: VarInt,
|
||||
pub property: i16,
|
||||
|
||||
@ -2,11 +2,11 @@ use crate::VarInt;
|
||||
use crate::codec::item_stack_seralizer::ItemStackSerializer;
|
||||
|
||||
use pumpkin_data::packet::clientbound::PLAY_CONTAINER_SET_SLOT;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_CONTAINER_SET_SLOT)]
|
||||
#[java_packet(PLAY_CONTAINER_SET_SLOT)]
|
||||
pub struct CSetContainerSlot<'a> {
|
||||
pub window_id: i8,
|
||||
pub state_id: VarInt,
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use crate::codec::item_stack_seralizer::ItemStackSerializer;
|
||||
|
||||
use pumpkin_data::packet::clientbound::PLAY_SET_CURSOR_ITEM;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_CURSOR_ITEM)]
|
||||
#[java_packet(PLAY_SET_CURSOR_ITEM)]
|
||||
pub struct CSetCursorItem<'a> {
|
||||
pub stack: &'a ItemStackSerializer<'a>,
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ use crate::{
|
||||
ser::{NetworkWriteExt, serializer::Serializer},
|
||||
};
|
||||
use pumpkin_data::packet::clientbound::PLAY_SET_EQUIPMENT;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::version::MinecraftVersion;
|
||||
use serde::Serialize;
|
||||
|
||||
@ -14,7 +14,7 @@ use crate::{
|
||||
codec::{item_stack_seralizer::ItemStackSerializer, var_int::VarInt},
|
||||
};
|
||||
|
||||
#[packet(PLAY_SET_EQUIPMENT)]
|
||||
#[java_packet(PLAY_SET_EQUIPMENT)]
|
||||
pub struct CSetEquipment {
|
||||
pub entity_id: VarInt,
|
||||
pub equipment: Vec<(i8, ItemStackSerializer<'static>)>,
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_SET_EXPERIENCE;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_EXPERIENCE)]
|
||||
#[java_packet(PLAY_SET_EXPERIENCE)]
|
||||
pub struct CSetExperience {
|
||||
pub progress: f32,
|
||||
pub total_experience: VarInt,
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_SET_HEALTH;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_HEALTH)]
|
||||
#[java_packet(PLAY_SET_HEALTH)]
|
||||
pub struct CSetHealth {
|
||||
pub health: f32,
|
||||
pub food: VarInt,
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_SET_HELD_SLOT;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_HELD_SLOT)]
|
||||
#[java_packet(PLAY_SET_HELD_SLOT)]
|
||||
pub struct CSetSelectedSlot {
|
||||
pub slot: i8,
|
||||
}
|
||||
|
||||
@ -2,11 +2,11 @@ use crate::VarInt;
|
||||
use crate::codec::item_stack_seralizer::ItemStackSerializer;
|
||||
|
||||
use pumpkin_data::packet::clientbound::PLAY_SET_PLAYER_INVENTORY;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_PLAYER_INVENTORY)]
|
||||
#[java_packet(PLAY_SET_PLAYER_INVENTORY)]
|
||||
pub struct CSetPlayerInventory<'a> {
|
||||
pub slot: VarInt,
|
||||
pub item: &'a ItemStackSerializer<'a>,
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_SET_TIME;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_TIME)]
|
||||
#[java_packet(PLAY_SET_TIME)]
|
||||
pub struct CUpdateTime {
|
||||
pub world_age: i64,
|
||||
pub time_of_day: i64,
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_SET_TITLE_TEXT;
|
||||
use pumpkin_util::text::TextComponent;
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_TITLE_TEXT)]
|
||||
#[java_packet(PLAY_SET_TITLE_TEXT)]
|
||||
pub struct CTitleText<'a> {
|
||||
pub title: &'a TextComponent,
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_SET_TITLES_ANIMATION;
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_TITLES_ANIMATION)]
|
||||
#[java_packet(PLAY_SET_TITLES_ANIMATION)]
|
||||
pub struct CTitleAnimation {
|
||||
pub fade_in_ticks: i32,
|
||||
pub stay_ticks: i32,
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
use pumpkin_data::{packet::clientbound::PLAY_SOUND, sound::SoundCategory};
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::math::vector3::Vector3;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{IdOr, SoundEvent, VarInt};
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SOUND)]
|
||||
#[java_packet(PLAY_SOUND)]
|
||||
pub struct CSoundEffect {
|
||||
pub sound_event: IdOr<SoundEvent>,
|
||||
pub sound_category: VarInt,
|
||||
|
||||
@ -1,15 +1,18 @@
|
||||
use std::io::Write;
|
||||
|
||||
use pumpkin_data::packet::clientbound::PLAY_ADD_ENTITY;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_util::math::vector3::Vector3;
|
||||
use serde::Serialize;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::{math::vector3::Vector3, version::MinecraftVersion};
|
||||
|
||||
use crate::{VarInt, codec::velocity::Velocity};
|
||||
use crate::{
|
||||
ClientPacket, VarInt,
|
||||
codec::velocity::Velocity,
|
||||
ser::{NetworkWriteExt, WritingError},
|
||||
};
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_ADD_ENTITY)]
|
||||
#[java_packet(PLAY_ADD_ENTITY)]
|
||||
pub struct CSpawnEntity {
|
||||
pub entity_id: VarInt,
|
||||
#[serde(with = "uuid::serde::compact")]
|
||||
pub entity_uuid: uuid::Uuid,
|
||||
pub r#type: VarInt,
|
||||
pub position: Vector3<f64>,
|
||||
@ -46,3 +49,39 @@ impl CSpawnEntity {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ClientPacket for CSpawnEntity {
|
||||
fn write_packet_data(
|
||||
&self,
|
||||
write: impl Write,
|
||||
version: &MinecraftVersion,
|
||||
) -> Result<(), WritingError> {
|
||||
let mut write = write;
|
||||
|
||||
write.write_var_int(&self.entity_id)?;
|
||||
write.write_uuid(&self.entity_uuid)?;
|
||||
write.write_var_int(&self.r#type)?;
|
||||
|
||||
write.write_f64_be(self.position.x)?;
|
||||
write.write_f64_be(self.position.y)?;
|
||||
write.write_f64_be(self.position.z)?;
|
||||
|
||||
// Angles
|
||||
if version >= &MinecraftVersion::V_1_21_9 {
|
||||
self.velocity.write(&mut write)?;
|
||||
}
|
||||
write.write_u8(self.pitch)?;
|
||||
write.write_u8(self.yaw)?;
|
||||
write.write_u8(self.head_yaw)?;
|
||||
|
||||
write.write_var_int(&self.data)?;
|
||||
|
||||
if version <= &MinecraftVersion::V_1_21_7 {
|
||||
write.write_i16_be(self.velocity.0.x as i16)?;
|
||||
write.write_i16_be(self.velocity.0.y as i16)?;
|
||||
write.write_i16_be(self.velocity.0.z as i16)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,11 +4,11 @@ use crate::codec::var_int::VarInt;
|
||||
use crate::ser::NetworkWriteExt;
|
||||
use crate::{ClientPacket, WritingError};
|
||||
use pumpkin_data::{packet::clientbound::PLAY_STOP_SOUND, sound::SoundCategory};
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
use pumpkin_util::version::MinecraftVersion;
|
||||
|
||||
#[packet(PLAY_STOP_SOUND)]
|
||||
#[java_packet(PLAY_STOP_SOUND)]
|
||||
pub struct CStopSound {
|
||||
pub sound_id: Option<ResourceLocation>,
|
||||
pub category: Option<SoundCategory>,
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_STORE_COOKIE;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use pumpkin_util::resource_location::ResourceLocation;
|
||||
use serde::Serialize;
|
||||
|
||||
/// Stores some arbitrary data on the client, which persists between server transfers.
|
||||
/// The Notchian client only accepts cookies of up to 5 kiB in size.
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_STORE_COOKIE)]
|
||||
#[java_packet(PLAY_STORE_COOKIE)]
|
||||
pub struct CStoreCookie<'a> {
|
||||
pub key: &'a ResourceLocation,
|
||||
pub payload: &'a [u8], // 5120,
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use pumpkin_data::packet::clientbound::PLAY_SET_SUBTITLE_TEXT;
|
||||
use pumpkin_util::text::TextComponent;
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_macros::java_packet;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(PLAY_SET_SUBTITLE_TEXT)]
|
||||
#[java_packet(PLAY_SET_SUBTITLE_TEXT)]
|
||||
pub struct CSubtitle<'a> {
|
||||
pub subtitle: &'a TextComponent,
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user