Tweak packet macros

This commit is contained in:
Ryan 2022-08-14 14:58:32 -07:00
parent 02fe0bae3b
commit 7fac522a8e
3 changed files with 253 additions and 273 deletions

View file

@ -54,7 +54,7 @@ pub trait DecodePacket: Sized + fmt::Debug {
macro_rules! def_struct { macro_rules! def_struct {
( (
$(#[$struct_attrs:meta])* $(#[$struct_attrs:meta])*
$name:ident $($id:literal)? { $name:ident {
$( $(
$(#[$field_attrs:meta])* $(#[$field_attrs:meta])*
$field:ident: $typ:ty $field:ident: $typ:ty
@ -95,36 +95,6 @@ macro_rules! def_struct {
} }
} }
$(
impl EncodePacket for $name {
fn encode_packet(&self, w: &mut impl Write) -> anyhow::Result<()> {
VarInt($id)
.encode(w)
.context(concat!("failed to write packet ID for `", stringify!($name), "`"))?;
self.encode(w)
}
}
impl DecodePacket for $name {
fn decode_packet(r: &mut impl Read) -> anyhow::Result<Self> {
let VarInt(packet_id) = VarInt::decode(r)
.context(concat!("failed to read packet ID for `", stringify!($name), "`"))?;
ensure!(
$id == packet_id,
concat!("bad packet ID for `", stringify!($name), "` (expected {:#04x}, got {:#04x})"),
$id,
packet_id
);
Self::decode(r)
}
}
impl $name {
pub const PACKET_ID: i32 = $id;
}
)*
// TODO: https://github.com/rust-lang/rust/issues/48214 // TODO: https://github.com/rust-lang/rust/issues/48214
//impl Copy for $name //impl Copy for $name
//where //where
@ -145,7 +115,7 @@ macro_rules! def_struct {
macro_rules! def_enum { macro_rules! def_enum {
( (
$(#[$enum_attrs:meta])* $(#[$enum_attrs:meta])*
$name:ident $($id:literal)?: $tag_ty:ty { $name:ident: $tag_ty:ty {
$( $(
$(#[$variant_attrs:meta])* $(#[$variant_attrs:meta])*
$variant:ident$(: $typ:ty)? = $lit:literal $variant:ident$(: $typ:ty)? = $lit:literal
@ -203,36 +173,6 @@ macro_rules! def_enum {
} }
} }
} }
$(
impl EncodePacket for $name {
fn encode_packet(&self, w: &mut impl Write) -> anyhow::Result<()> {
VarInt($id)
.encode(w)
.context(concat!("failed to write packet ID for `", stringify!($name), "`"))?;
self.encode(w)
}
}
impl DecodePacket for $name {
fn decode_packet(r: &mut impl Read) -> anyhow::Result<Self> {
let VarInt(packet_id) = VarInt::decode(r)
.context(concat!("failed to read packet ID for `", stringify!($name), "`"))?;
ensure!(
$id == packet_id,
concat!("bad packet ID for `", stringify!($name), "` (expected {:#04X}, got {:#04X})"),
$id,
packet_id
);
Self::decode(r)
}
}
impl $name {
pub const PACKET_ID: i32 = $id;
}
)*
} }
} }
@ -336,7 +276,7 @@ macro_rules! def_packet_group {
( (
$(#[$attrs:meta])* $(#[$attrs:meta])*
$group_name:ident { $group_name:ident {
$($packet:ident),* $(,)? $($packet:ident = $id:literal),* $(,)?
} }
) => { ) => {
#[derive(Clone)] #[derive(Clone)]
@ -351,6 +291,26 @@ macro_rules! def_packet_group {
Self::$packet(p) Self::$packet(p)
} }
} }
impl EncodePacket for $packet {
fn encode_packet(&self, w: &mut impl Write) -> anyhow::Result<()> {
VarInt($id).encode(w).context("failed to write packet ID")?;
self.encode(w)
}
}
impl DecodePacket for $packet {
fn decode_packet(r: &mut impl Read) -> anyhow::Result<Self> {
let packet_id = VarInt::decode(r).context("failed to read packet ID")?.0;
ensure!(
$id == packet_id,
"bad packet ID (expected {}, got {packet_id}",
$id
);
Self::decode(r)
}
}
)* )*
impl DecodePacket for $group_name { impl DecodePacket for $group_name {
@ -360,12 +320,12 @@ macro_rules! def_packet_group {
match packet_id { match packet_id {
$( $(
$packet::PACKET_ID => { $id => {
let pkt = $packet::decode(r)?; let pkt = $packet::decode(r)?;
Ok(Self::$packet(pkt)) Ok(Self::$packet(pkt))
} }
)* )*
id => bail!(concat!("unknown ", stringify!($group_name), " packet ID {:#04x}"), id), id => bail!(concat!("unknown ", stringify!($group_name), " packet ID {}"), id),
} }
} }
} }
@ -375,7 +335,7 @@ macro_rules! def_packet_group {
match self { match self {
$( $(
Self::$packet(pkt) => { Self::$packet(pkt) => {
VarInt($packet::PACKET_ID) VarInt($id)
.encode(w) .encode(w)
.context(concat!( .context(concat!(
"failed to write ", "failed to write ",

View file

@ -6,7 +6,7 @@ pub mod handshake {
use super::*; use super::*;
def_struct! { def_struct! {
Handshake 0x00 { Handshake {
protocol_version: VarInt, protocol_version: VarInt,
server_adddress: BoundedString<0, 255>, server_adddress: BoundedString<0, 255>,
server_port: u16, server_port: u16,
@ -20,34 +20,47 @@ pub mod handshake {
Login = 2, Login = 2,
} }
} }
def_packet_group! {
C2sHandshakePacket {
Handshake = 0,
}
}
} }
pub mod status { pub mod status {
use super::*; use super::*;
def_struct! { def_struct! {
QueryRequest 0x00 {} QueryRequest {}
} }
def_struct! { def_struct! {
QueryPing 0x01 { QueryPing {
payload: u64 payload: u64
} }
} }
def_packet_group! {
C2sStatusPacket {
QueryRequest = 0,
QueryPing = 1,
}
}
} }
pub mod login { pub mod login {
use super::*; use super::*;
def_struct! { def_struct! {
LoginStart 0x00 { LoginStart {
username: BoundedString<3, 16>, username: BoundedString<3, 16>,
sig_data: Option<SignatureData>, sig_data: Option<SignatureData>,
} }
} }
def_struct! { def_struct! {
EncryptionResponse 0x01 { EncryptionResponse {
shared_secret: BoundedArray<u8, 16, 128>, shared_secret: BoundedArray<u8, 16, 128>,
token_or_sig: VerifyTokenOrMsgSig, token_or_sig: VerifyTokenOrMsgSig,
} }
@ -68,7 +81,7 @@ pub mod login {
} }
def_struct! { def_struct! {
LoginPluginResponse 0x02 { LoginPluginResponse {
message_id: VarInt, message_id: VarInt,
data: Option<RawBytes>, data: Option<RawBytes>,
} }
@ -76,9 +89,9 @@ pub mod login {
def_packet_group! { def_packet_group! {
C2sLoginPacket { C2sLoginPacket {
LoginStart, LoginStart = 0,
EncryptionResponse, EncryptionResponse = 1,
LoginPluginResponse, LoginPluginResponse = 2,
} }
} }
} }
@ -87,20 +100,20 @@ pub mod play {
use super::super::*; use super::super::*;
def_struct! { def_struct! {
TeleportConfirm 0x00 { TeleportConfirm {
teleport_id: VarInt teleport_id: VarInt
} }
} }
def_struct! { def_struct! {
QueryBlockNbt 0x01 { QueryBlockNbt {
transaction_id: VarInt, transaction_id: VarInt,
location: BlockPos, location: BlockPos,
} }
} }
def_enum! { def_enum! {
UpdateDifficulty 0x02: i8 { UpdateDifficulty: i8 {
Peaceful = 0, Peaceful = 0,
Easy = 1, Easy = 1,
Normal = 2, Normal = 2,
@ -109,7 +122,7 @@ pub mod play {
} }
def_struct! { def_struct! {
CommandExecution 0x03 { CommandExecution {
command: String, // TODO: bounded? command: String, // TODO: bounded?
// TODO: timestamp, arg signatures // TODO: timestamp, arg signatures
signed_preview: bool, signed_preview: bool,
@ -117,7 +130,7 @@ pub mod play {
} }
def_struct! { def_struct! {
ChatMessage 0x04 { ChatMessage {
message: BoundedString<0, 256>, message: BoundedString<0, 256>,
timestamp: u64, timestamp: u64,
salt: u64, salt: u64,
@ -127,14 +140,14 @@ pub mod play {
} }
def_struct! { def_struct! {
RequestChatPreview 0x05 { RequestChatPreview {
query: i32, // TODO: is this an i32 or a varint? query: i32, // TODO: is this an i32 or a varint?
message: BoundedString<0, 256>, message: BoundedString<0, 256>,
} }
} }
def_enum! { def_enum! {
ClientStatus 0x06: VarInt { ClientStatus: VarInt {
/// Sent when ready to complete login and ready to respawn after death. /// Sent when ready to complete login and ready to respawn after death.
PerformRespawn = 0, PerformRespawn = 0,
/// Sent when the statistics menu is opened. /// Sent when the statistics menu is opened.
@ -143,7 +156,7 @@ pub mod play {
} }
def_struct! { def_struct! {
ClientSettings 0x07 { ClientSettings {
/// e.g. en_US /// e.g. en_US
locale: BoundedString<0, 16>, locale: BoundedString<0, 16>,
/// Client-side render distance in chunks. /// Client-side render distance in chunks.
@ -189,7 +202,7 @@ pub mod play {
} }
def_struct! { def_struct! {
RequestCommandCompletion 0x08 { RequestCommandCompletion {
transaction_id: VarInt, transaction_id: VarInt,
/// Text behind the cursor without the '/'. /// Text behind the cursor without the '/'.
text: BoundedString<0, 32500> text: BoundedString<0, 32500>
@ -197,33 +210,33 @@ pub mod play {
} }
def_struct! { def_struct! {
ButtonClick 0x09 { ButtonClick {
window_id: i8, window_id: i8,
button_id: i8, button_id: i8,
} }
} }
def_struct! { def_struct! {
ClickSlot 0x0a { ClickSlot {
// TODO // TODO
} }
} }
def_struct! { def_struct! {
CloseHandledScreen 0x0b { CloseHandledScreen {
window_id: u8, window_id: u8,
} }
} }
def_struct! { def_struct! {
CustomPayload 0x0c { CustomPayload {
channel: Ident, channel: Ident,
data: RawBytes, data: RawBytes,
} }
} }
def_struct! { def_struct! {
BookUpdate 0x0d { BookUpdate {
slot: VarInt, slot: VarInt,
entries: Vec<String>, entries: Vec<String>,
title: Option<String>, title: Option<String>,
@ -231,14 +244,14 @@ pub mod play {
} }
def_struct! { def_struct! {
QueryEntityNbt 0x0e { QueryEntityNbt {
transaction_id: VarInt, transaction_id: VarInt,
entity_id: VarInt, entity_id: VarInt,
} }
} }
def_struct! { def_struct! {
PlayerInteractEntity 0x0f { PlayerInteractEntity {
entity_id: VarInt, entity_id: VarInt,
kind: InteractKind, kind: InteractKind,
sneaking: bool, sneaking: bool,
@ -262,7 +275,7 @@ pub mod play {
} }
def_struct! { def_struct! {
JigsawGenerate 0x10 { JigsawGenerate {
location: BlockPos, location: BlockPos,
levels: VarInt, levels: VarInt,
keep_jigsaws: bool, keep_jigsaws: bool,
@ -270,26 +283,26 @@ pub mod play {
} }
def_struct! { def_struct! {
KeepAlive 0x11 { KeepAlive {
id: i64, id: i64,
} }
} }
def_struct! { def_struct! {
UpdateDifficultyLock 0x12 { UpdateDifficultyLock {
locked: bool locked: bool
} }
} }
def_struct! { def_struct! {
MovePlayerPosition 0x13 { MovePlayerPosition {
position: Vec3<f64>, position: Vec3<f64>,
on_ground: bool, on_ground: bool,
} }
} }
def_struct! { def_struct! {
MovePlayerPositionAndRotation 0x14 { MovePlayerPositionAndRotation {
// Absolute position // Absolute position
position: Vec3<f64>, position: Vec3<f64>,
/// Absolute rotation on X axis in degrees. /// Absolute rotation on X axis in degrees.
@ -301,7 +314,7 @@ pub mod play {
} }
def_struct! { def_struct! {
MovePlayerRotation 0x15 { MovePlayerRotation {
/// Absolute rotation on X axis in degrees. /// Absolute rotation on X axis in degrees.
yaw: f32, yaw: f32,
/// Absolute rotation on Y axis in degrees. /// Absolute rotation on Y axis in degrees.
@ -311,13 +324,13 @@ pub mod play {
} }
def_struct! { def_struct! {
MovePlayerOnGround 0x16 { MovePlayerOnGround {
on_ground: bool on_ground: bool
} }
} }
def_struct! { def_struct! {
MoveVehicle 0x17 { MoveVehicle {
/// Absolute position /// Absolute position
position: Vec3<f64>, position: Vec3<f64>,
/// Degrees /// Degrees
@ -328,20 +341,20 @@ pub mod play {
} }
def_struct! { def_struct! {
BoatPaddleState 0x18 { BoatPaddleState {
left_paddle_turning: bool, left_paddle_turning: bool,
right_paddle_turning: bool, right_paddle_turning: bool,
} }
} }
def_struct! { def_struct! {
PickFromInventory 0x19 { PickFromInventory {
slot_to_use: VarInt, slot_to_use: VarInt,
} }
} }
def_struct! { def_struct! {
CraftRequest 0x1a { CraftRequest {
window_id: i8, window_id: i8,
recipe: Ident, recipe: Ident,
make_all: bool, make_all: bool,
@ -349,14 +362,14 @@ pub mod play {
} }
def_enum! { def_enum! {
UpdatePlayerAbilities 0x1b: i8 { UpdatePlayerAbilities: i8 {
NotFlying = 0, NotFlying = 0,
Flying = 0b10, Flying = 0b10,
} }
} }
def_struct! { def_struct! {
PlayerAction 0x1c { PlayerAction {
status: DiggingStatus, status: DiggingStatus,
location: BlockPos, location: BlockPos,
face: BlockFace, face: BlockFace,
@ -395,7 +408,7 @@ pub mod play {
} }
def_struct! { def_struct! {
PlayerCommand 0x1d { PlayerCommand {
entity_id: VarInt, entity_id: VarInt,
action_id: PlayerCommandId, action_id: PlayerCommandId,
jump_boost: BoundedInt<VarInt, 0, 100>, jump_boost: BoundedInt<VarInt, 0, 100>,
@ -417,7 +430,7 @@ pub mod play {
} }
def_struct! { def_struct! {
PlayerInput 0x1e { PlayerInput {
sideways: f32, sideways: f32,
forward: f32, forward: f32,
flags: PlayerInputFlags, flags: PlayerInputFlags,
@ -432,13 +445,13 @@ pub mod play {
} }
def_struct! { def_struct! {
PlayPong 0x1f { PlayPong {
id: i32, id: i32,
} }
} }
def_struct! { def_struct! {
RecipeBookChangeSettings 0x20 { RecipeBookChangeSettings {
book_id: RecipeBookId, book_id: RecipeBookId,
book_open: bool, book_open: bool,
filter_active: bool, filter_active: bool,
@ -455,19 +468,19 @@ pub mod play {
} }
def_struct! { def_struct! {
RecipeBookSeenRecipe 0x21 { RecipeBookSeenRecipe {
recipe_id: Ident, recipe_id: Ident,
} }
} }
def_struct! { def_struct! {
RenameItem 0x22 { RenameItem {
item_name: BoundedString<0, 50>, item_name: BoundedString<0, 50>,
} }
} }
def_enum! { def_enum! {
ResourcePackStatus 0x23: VarInt { ResourcePackStatus: VarInt {
SuccessfullyLoaded = 0, SuccessfullyLoaded = 0,
Declined = 1, Declined = 1,
FailedDownload = 2, FailedDownload = 2,
@ -476,20 +489,20 @@ pub mod play {
} }
def_enum! { def_enum! {
AdvancementTab 0x24: VarInt { AdvancementTab: VarInt {
OpenedTab: Ident = 0, OpenedTab: Ident = 0,
ClosedScreen = 1, ClosedScreen = 1,
} }
} }
def_struct! { def_struct! {
SelectMerchantTrade 0x25 { SelectMerchantTrade {
selected_slot: VarInt, selected_slot: VarInt,
} }
} }
def_struct! { def_struct! {
UpdateBeacon 0x26 { UpdateBeacon {
// TODO: potion ids // TODO: potion ids
primary_effect: Option<VarInt>, primary_effect: Option<VarInt>,
secondary_effect: Option<VarInt>, secondary_effect: Option<VarInt>,
@ -497,13 +510,13 @@ pub mod play {
} }
def_struct! { def_struct! {
UpdateSelectedSlot 0x27 { UpdateSelectedSlot {
slot: BoundedInt<i16, 0, 8>, slot: BoundedInt<i16, 0, 8>,
} }
} }
def_struct! { def_struct! {
UpdateCommandBlock 0x28 { UpdateCommandBlock {
location: BlockPos, location: BlockPos,
command: String, command: String,
mode: CommandBlockMode, mode: CommandBlockMode,
@ -528,7 +541,7 @@ pub mod play {
} }
def_struct! { def_struct! {
UpdateCommandBlockMinecart 0x29 { UpdateCommandBlockMinecart {
entity_id: VarInt, entity_id: VarInt,
command: String, command: String,
track_output: bool, track_output: bool,
@ -536,14 +549,14 @@ pub mod play {
} }
def_struct! { def_struct! {
UpdateCreativeModeSlot 0x2a { UpdateCreativeModeSlot {
slot: i16, slot: i16,
// TODO: clicked_item: Slot, // TODO: clicked_item: Slot,
} }
} }
def_struct! { def_struct! {
UpdateJigsaw 0x2b { UpdateJigsaw {
location: BlockPos, location: BlockPos,
name: Ident, name: Ident,
target: Ident, target: Ident,
@ -554,7 +567,7 @@ pub mod play {
} }
def_struct! { def_struct! {
UpdateStructureBlock 0x2c { UpdateStructureBlock {
location: BlockPos, location: BlockPos,
action: StructureBlockAction, action: StructureBlockAction,
mode: StructureBlockMode, mode: StructureBlockMode,
@ -614,26 +627,26 @@ pub mod play {
} }
def_struct! { def_struct! {
UpdateSign 0x2d { UpdateSign {
location: BlockPos, location: BlockPos,
lines: [BoundedString<0, 384>; 4], lines: [BoundedString<0, 384>; 4],
} }
} }
def_struct! { def_struct! {
HandSwing 0x2e { HandSwing {
hand: Hand, hand: Hand,
} }
} }
def_struct! { def_struct! {
SpectatorTeleport 0x2f { SpectatorTeleport {
target: Uuid, target: Uuid,
} }
} }
def_struct! { def_struct! {
PlayerInteractBlock 0x30 { PlayerInteractBlock {
hand: Hand, hand: Hand,
location: BlockPos, location: BlockPos,
face: BlockFace, face: BlockFace,
@ -644,7 +657,7 @@ pub mod play {
} }
def_struct! { def_struct! {
PlayerInteractItem 0x31 { PlayerInteractItem {
hand: Hand, hand: Hand,
sequence: VarInt, sequence: VarInt,
} }
@ -652,56 +665,56 @@ pub mod play {
def_packet_group! { def_packet_group! {
C2sPlayPacket { C2sPlayPacket {
TeleportConfirm, TeleportConfirm = 0,
QueryBlockNbt, QueryBlockNbt = 1,
UpdateDifficulty, UpdateDifficulty = 2,
CommandExecution, CommandExecution = 3,
ChatMessage, ChatMessage = 4,
RequestChatPreview, RequestChatPreview = 5,
ClientStatus, ClientStatus = 6,
ClientSettings, ClientSettings = 7,
RequestCommandCompletion, RequestCommandCompletion = 8,
ButtonClick, ButtonClick = 9,
ClickSlot, ClickSlot = 10,
CloseHandledScreen, CloseHandledScreen = 11,
CustomPayload, CustomPayload = 12,
BookUpdate, BookUpdate = 13,
QueryEntityNbt, QueryEntityNbt = 14,
PlayerInteractEntity, PlayerInteractEntity = 15,
JigsawGenerate, JigsawGenerate = 16,
KeepAlive, KeepAlive = 17,
UpdateDifficultyLock, UpdateDifficultyLock = 18,
MovePlayerPosition, MovePlayerPosition = 19,
MovePlayerPositionAndRotation, MovePlayerPositionAndRotation = 20,
MovePlayerRotation, MovePlayerRotation = 21,
MovePlayerOnGround, MovePlayerOnGround = 22,
MoveVehicle, MoveVehicle = 23,
BoatPaddleState, BoatPaddleState = 24,
PickFromInventory, PickFromInventory = 25,
CraftRequest, CraftRequest = 26,
UpdatePlayerAbilities, UpdatePlayerAbilities = 27,
PlayerAction, PlayerAction = 28,
PlayerCommand, PlayerCommand = 29,
PlayerInput, PlayerInput = 30,
PlayPong, PlayPong = 31,
RecipeBookChangeSettings, RecipeBookChangeSettings = 32,
RecipeBookSeenRecipe, RecipeBookSeenRecipe = 33,
RenameItem, RenameItem = 34,
ResourcePackStatus, ResourcePackStatus = 35,
AdvancementTab, AdvancementTab = 36,
SelectMerchantTrade, SelectMerchantTrade = 37,
UpdateBeacon, UpdateBeacon = 38,
UpdateSelectedSlot, UpdateSelectedSlot = 39,
UpdateCommandBlock, UpdateCommandBlock = 40,
UpdateCommandBlockMinecart, UpdateCommandBlockMinecart = 41,
UpdateCreativeModeSlot, UpdateCreativeModeSlot = 42,
UpdateJigsaw, UpdateJigsaw = 43,
UpdateStructureBlock, UpdateStructureBlock = 44,
UpdateSign, UpdateSign = 45,
HandSwing, HandSwing = 46,
SpectatorTeleport, SpectatorTeleport = 47,
PlayerInteractBlock, PlayerInteractBlock = 48,
PlayerInteractItem, PlayerInteractItem = 49,
} }
} }
} }

View file

@ -6,30 +6,37 @@ pub mod status {
use super::*; use super::*;
def_struct! { def_struct! {
QueryResponse 0x00 { QueryResponse {
json_response: String json_response: String
} }
} }
def_struct! { def_struct! {
QueryPong 0x01 { QueryPong {
/// Should be the same as the payload from ping. /// Should be the same as the payload from ping.
payload: u64 payload: u64
} }
} }
def_packet_group! {
S2cStatusPacket {
QueryResponse = 0,
QueryPong = 1,
}
}
} }
pub mod login { pub mod login {
use super::*; use super::*;
def_struct! { def_struct! {
LoginDisconnect 0x00 { LoginDisconnect {
reason: Text, reason: Text,
} }
} }
def_struct! { def_struct! {
EncryptionRequest 0x01 { EncryptionRequest {
/// Currently unused /// Currently unused
server_id: BoundedString<0, 20>, server_id: BoundedString<0, 20>,
/// The RSA public key /// The RSA public key
@ -39,7 +46,7 @@ pub mod login {
} }
def_struct! { def_struct! {
LoginSuccess 0x02 { LoginSuccess {
uuid: Uuid, uuid: Uuid,
username: BoundedString<3, 16>, username: BoundedString<3, 16>,
properties: Vec<Property>, properties: Vec<Property>,
@ -47,13 +54,13 @@ pub mod login {
} }
def_struct! { def_struct! {
LoginCompression 0x03 { LoginCompression {
threshold: VarInt threshold: VarInt
} }
} }
def_struct! { def_struct! {
LoginPluginRequest 0x04 { LoginPluginRequest {
message_id: VarInt, message_id: VarInt,
channel: Ident, channel: Ident,
data: RawBytes, data: RawBytes,
@ -62,11 +69,11 @@ pub mod login {
def_packet_group! { def_packet_group! {
S2cLoginPacket { S2cLoginPacket {
LoginDisconnect, LoginDisconnect = 0,
EncryptionRequest, EncryptionRequest = 1,
LoginSuccess, LoginSuccess = 2,
LoginCompression, LoginCompression = 3,
LoginPluginRequest, LoginPluginRequest = 4,
} }
} }
} }
@ -75,7 +82,7 @@ pub mod play {
use super::*; use super::*;
def_struct! { def_struct! {
EntitySpawn 0x00 { EntitySpawn {
entity_id: VarInt, entity_id: VarInt,
object_uuid: Uuid, object_uuid: Uuid,
kind: VarInt, kind: VarInt,
@ -89,7 +96,7 @@ pub mod play {
} }
def_struct! { def_struct! {
ExperienceOrbSpawn 0x01 { ExperienceOrbSpawn {
entity_id: VarInt, entity_id: VarInt,
position: Vec3<f64>, position: Vec3<f64>,
count: i16, count: i16,
@ -97,7 +104,7 @@ pub mod play {
} }
def_struct! { def_struct! {
PlayerSpawn 0x02 { PlayerSpawn {
entity_id: VarInt, entity_id: VarInt,
player_uuid: Uuid, player_uuid: Uuid,
position: Vec3<f64>, position: Vec3<f64>,
@ -107,20 +114,20 @@ pub mod play {
} }
def_struct! { def_struct! {
EntityAnimation 0x03 { EntityAnimation {
entity_id: VarInt, entity_id: VarInt,
animation: u8, animation: u8,
} }
} }
def_struct! { def_struct! {
PlayerActionResponse 0x05 { PlayerActionResponse {
sequence: VarInt, sequence: VarInt,
} }
} }
def_struct! { def_struct! {
BlockBreakingProgress 0x06 { BlockBreakingProgress {
entity_id: VarInt, entity_id: VarInt,
location: BlockPos, location: BlockPos,
destroy_stage: BoundedInt<u8, 0, 10>, destroy_stage: BoundedInt<u8, 0, 10>,
@ -128,7 +135,7 @@ pub mod play {
} }
def_struct! { def_struct! {
BlockEntityUpdate 0x07 { BlockEntityUpdate {
location: BlockPos, location: BlockPos,
kind: VarInt, // TODO: use enum here kind: VarInt, // TODO: use enum here
data: nbt::Blob, data: nbt::Blob,
@ -136,7 +143,7 @@ pub mod play {
} }
def_struct! { def_struct! {
BlockEvent 0x08 { BlockEvent {
location: BlockPos, location: BlockPos,
action_id: u8, action_id: u8,
action_param: u8, action_param: u8,
@ -145,14 +152,14 @@ pub mod play {
} }
def_struct! { def_struct! {
BlockUpdate 0x09 { BlockUpdate {
location: BlockPos, location: BlockPos,
block_id: VarInt, block_id: VarInt,
} }
} }
def_struct! { def_struct! {
BossBar 0x0a { BossBar {
uuid: Uuid, uuid: Uuid,
action: BossBarAction, action: BossBarAction,
} }
@ -199,7 +206,7 @@ pub mod play {
} }
def_struct! { def_struct! {
SetDifficulty 0x0b { SetDifficulty {
difficulty: Difficulty, difficulty: Difficulty,
locked: bool, locked: bool,
} }
@ -215,33 +222,33 @@ pub mod play {
} }
def_struct! { def_struct! {
ClearTitles 0x0d { ClearTitles {
reset: bool, reset: bool,
} }
} }
def_struct! { def_struct! {
Disconnect 0x17 { Disconnect {
reason: Text, reason: Text,
} }
} }
def_struct! { def_struct! {
EntityStatus 0x18 { EntityStatus {
entity_id: i32, entity_id: i32,
entity_status: u8, entity_status: u8,
} }
} }
def_struct! { def_struct! {
UnloadChunk 0x1a { UnloadChunk {
chunk_x: i32, chunk_x: i32,
chunk_z: i32 chunk_z: i32
} }
} }
def_struct! { def_struct! {
GameStateChange 0x1b { GameStateChange {
reason: GameStateChangeReason, reason: GameStateChangeReason,
value: f32, value: f32,
} }
@ -265,7 +272,7 @@ pub mod play {
} }
def_struct! { def_struct! {
WorldBorderInitialize 0x1d { WorldBorderInitialize {
x: f64, x: f64,
z: f64, z: f64,
old_diameter: f64, old_diameter: f64,
@ -278,13 +285,13 @@ pub mod play {
} }
def_struct! { def_struct! {
KeepAlive 0x1e { KeepAlive {
id: i64, id: i64,
} }
} }
def_struct! { def_struct! {
ChunkData 0x1f { ChunkData {
chunk_x: i32, chunk_x: i32,
chunk_z: i32, chunk_z: i32,
heightmaps: Nbt<ChunkDataHeightmaps>, heightmaps: Nbt<ChunkDataHeightmaps>,
@ -316,7 +323,7 @@ pub mod play {
} }
def_struct! { def_struct! {
GameJoin 0x23 { GameJoin {
/// Entity ID of the joining player /// Entity ID of the joining player
entity_id: i32, entity_id: i32,
is_hardcore: bool, is_hardcore: bool,
@ -508,7 +515,7 @@ pub mod play {
} }
def_struct! { def_struct! {
MoveRelative 0x26 { MoveRelative {
entity_id: VarInt, entity_id: VarInt,
delta: Vec3<i16>, delta: Vec3<i16>,
on_ground: bool, on_ground: bool,
@ -516,7 +523,7 @@ pub mod play {
} }
def_struct! { def_struct! {
RotateAndMoveRelative 0x27 { RotateAndMoveRelative {
entity_id: VarInt, entity_id: VarInt,
delta: Vec3<i16>, delta: Vec3<i16>,
yaw: ByteAngle, yaw: ByteAngle,
@ -526,7 +533,7 @@ pub mod play {
} }
def_struct! { def_struct! {
Rotate 0x28 { Rotate {
entity_id: VarInt, entity_id: VarInt,
yaw: ByteAngle, yaw: ByteAngle,
pitch: ByteAngle, pitch: ByteAngle,
@ -535,7 +542,7 @@ pub mod play {
} }
def_struct! { def_struct! {
ChatMessage 0x30 { ChatMessage {
message: Text, message: Text,
/// Index into the chat type registry /// Index into the chat type registry
kind: VarInt, kind: VarInt,
@ -545,7 +552,7 @@ pub mod play {
} }
def_enum! { def_enum! {
UpdatePlayerList 0x34: VarInt { UpdatePlayerList: VarInt {
AddPlayer: Vec<PlayerListAddPlayer> = 0, AddPlayer: Vec<PlayerListAddPlayer> = 0,
UpdateGameMode: Vec<(Uuid, GameMode)> = 1, UpdateGameMode: Vec<(Uuid, GameMode)> = 1,
UpdateLatency: Vec<(Uuid, VarInt)> = 2, UpdateLatency: Vec<(Uuid, VarInt)> = 2,
@ -567,7 +574,7 @@ pub mod play {
} }
def_struct! { def_struct! {
PlayerPositionLook 0x36 { PlayerPositionLook {
position: Vec3<f64>, position: Vec3<f64>,
yaw: f32, yaw: f32,
pitch: f32, pitch: f32,
@ -588,13 +595,13 @@ pub mod play {
} }
def_struct! { def_struct! {
EntitiesDestroy 0x38 { EntitiesDestroy {
entities: Vec<VarInt>, entities: Vec<VarInt>,
} }
} }
def_struct! { def_struct! {
PlayerRespawn 0x3b { PlayerRespawn {
dimension_type_name: Ident, dimension_type_name: Ident,
dimension_name: Ident, dimension_name: Ident,
hashed_seed: u64, hashed_seed: u64,
@ -608,14 +615,14 @@ pub mod play {
} }
def_struct! { def_struct! {
EntitySetHeadYaw 0x3c { EntitySetHeadYaw {
entity_id: VarInt, entity_id: VarInt,
head_yaw: ByteAngle, head_yaw: ByteAngle,
} }
} }
def_struct! { def_struct! {
ChunkSectionUpdate 0x3d { ChunkSectionUpdate {
chunk_section_position: i64, chunk_section_position: i64,
invert_trust_edges: bool, invert_trust_edges: bool,
blocks: Vec<VarLong>, blocks: Vec<VarLong>,
@ -623,53 +630,53 @@ pub mod play {
} }
def_struct! { def_struct! {
UpdateSelectedSlot 0x47 { UpdateSelectedSlot {
slot: BoundedInt<u8, 0, 9>, slot: BoundedInt<u8, 0, 9>,
} }
} }
def_struct! { def_struct! {
ChunkRenderDistanceCenter 0x48 { ChunkRenderDistanceCenter {
chunk_x: VarInt, chunk_x: VarInt,
chunk_z: VarInt, chunk_z: VarInt,
} }
} }
def_struct! { def_struct! {
ChunkLoadDistance 0x49 { ChunkLoadDistance {
view_distance: BoundedInt<VarInt, 2, 32>, view_distance: BoundedInt<VarInt, 2, 32>,
} }
} }
def_struct! { def_struct! {
PlayerSpawnPosition 0x4a { PlayerSpawnPosition {
location: BlockPos, location: BlockPos,
angle: f32, angle: f32,
} }
} }
def_struct! { def_struct! {
EntityTrackerUpdate 0x4d { EntityTrackerUpdate {
entity_id: VarInt, entity_id: VarInt,
metadata: RawBytes, metadata: RawBytes,
} }
} }
def_struct! { def_struct! {
EntityVelocityUpdate 0x4f { EntityVelocityUpdate {
entity_id: VarInt, entity_id: VarInt,
velocity: Vec3<i16>, velocity: Vec3<i16>,
} }
} }
def_struct! { def_struct! {
UpdateSubtitle 0x58 { UpdateSubtitle {
subtitle_text: Text, subtitle_text: Text,
} }
} }
def_struct! { def_struct! {
WorldTimeUpdate 0x59 { WorldTimeUpdate {
/// The age of the world in 1/20ths of a second. /// The age of the world in 1/20ths of a second.
world_age: i64, world_age: i64,
/// The current time of day in 1/20ths of a second. /// The current time of day in 1/20ths of a second.
@ -680,14 +687,14 @@ pub mod play {
} }
def_struct! { def_struct! {
UpdateTitle 0x5a { UpdateTitle {
text: Text, text: Text,
} }
} }
def_struct! { def_struct! {
#[derive(Copy, PartialEq, Eq)] #[derive(Copy, PartialEq, Eq)]
TitleAnimationTimes 0x5b { TitleAnimationTimes {
/// Ticks to spend fading in. /// Ticks to spend fading in.
fade_in: u32, fade_in: u32,
/// Ticks to keep the title displayed. /// Ticks to keep the title displayed.
@ -698,7 +705,7 @@ pub mod play {
} }
def_struct! { def_struct! {
GameMessage 0x5f { GameMessage {
chat: Text, chat: Text,
/// Index into the chat type registry. /// Index into the chat type registry.
kind: VarInt, kind: VarInt,
@ -706,14 +713,14 @@ pub mod play {
} }
def_struct! { def_struct! {
PlayerListHeaderFooter 0x60 { PlayerListHeaderFooter {
header: Text, header: Text,
footer: Text, footer: Text,
} }
} }
def_struct! { def_struct! {
EntityPosition 0x63 { EntityPosition {
entity_id: VarInt, entity_id: VarInt,
position: Vec3<f64>, position: Vec3<f64>,
yaw: ByteAngle, yaw: ByteAngle,
@ -723,7 +730,7 @@ pub mod play {
} }
def_struct! { def_struct! {
EntityAttributes 0x65 { EntityAttributes {
entity_id: VarInt, entity_id: VarInt,
properties: Vec<EntityAttributesProperty>, properties: Vec<EntityAttributesProperty>,
} }
@ -747,48 +754,48 @@ pub mod play {
def_packet_group! { def_packet_group! {
S2cPlayPacket { S2cPlayPacket {
EntitySpawn, EntitySpawn = 0,
ExperienceOrbSpawn, ExperienceOrbSpawn = 1,
PlayerSpawn, PlayerSpawn = 2,
EntityAnimation, EntityAnimation = 3,
PlayerActionResponse, PlayerActionResponse = 5,
BlockBreakingProgress, BlockBreakingProgress = 6,
BlockEntityUpdate, BlockEntityUpdate = 7,
BlockEvent, BlockEvent = 8,
BlockUpdate, BlockUpdate = 9,
BossBar, BossBar = 10,
ClearTitles, ClearTitles = 13,
Disconnect, Disconnect = 23,
EntityStatus, EntityStatus = 24,
UnloadChunk, UnloadChunk = 26,
GameStateChange, GameStateChange = 27,
KeepAlive, KeepAlive = 30,
ChunkData, ChunkData = 31,
GameJoin, GameJoin = 35,
MoveRelative, MoveRelative = 38,
RotateAndMoveRelative, RotateAndMoveRelative = 39,
Rotate, Rotate = 40,
ChatMessage, ChatMessage = 48,
UpdatePlayerList, UpdatePlayerList = 52,
PlayerPositionLook, PlayerPositionLook = 54,
EntitiesDestroy, EntitiesDestroy = 56,
PlayerRespawn, PlayerRespawn = 59,
EntitySetHeadYaw, EntitySetHeadYaw = 60,
ChunkSectionUpdate, ChunkSectionUpdate = 61,
UpdateSelectedSlot, UpdateSelectedSlot = 71,
ChunkRenderDistanceCenter, ChunkRenderDistanceCenter = 72,
ChunkLoadDistance, ChunkLoadDistance = 73,
PlayerSpawnPosition, PlayerSpawnPosition = 74,
EntityTrackerUpdate, EntityTrackerUpdate = 77,
EntityVelocityUpdate, EntityVelocityUpdate = 79,
UpdateSubtitle, UpdateSubtitle = 88,
WorldTimeUpdate, WorldTimeUpdate = 89,
UpdateTitle, UpdateTitle = 90,
TitleAnimationTimes, TitleAnimationTimes = 91,
GameMessage, GameMessage = 95,
PlayerListHeaderFooter, PlayerListHeaderFooter = 96,
EntityPosition, EntityPosition = 99,
EntityAttributes, EntityAttributes = 101,
} }
} }
} }