1.7.10 (5) multiprotocol support (#64)

Adds 1.7.10 protocol version 5 support, a major update with significant changes.
Expands https://github.com/iceiix/steven/issues/18 Enhance protocol support

* Add v1_7_10 protocol packet structures and IDs

* EncryptionRequest/Response i16 variant in login protocol

* 1.7.10 slot NBT data parsing

* Support both 1.7/1.8+ item::Stack in read_from, using if protocol_verson

* 1.7.10 chunk format support, ChunkDataBulk_17 and ChunkData_17

* Extract dirty_chunks_by_bitmask from load_chunks17/18/19

* Implement keepalive i32 handler

* Send PlayerPositionLook_HeadY

* Send PlayerBlockPlacement_u8_Item_u8y

* Handle JoinGame_i8_NoDebug

* Handle SpawnPlayer_i32_HeldItem_String

* BlockChange_u8, MultiBlockChange_i16, UpdateBlockEntity_Data, EntityMove_i8_i32_NoGround, EntityLook_i32_NoGround, EntityLookAndMove_i8_i32_NoGround

* UpdateSign_u16, PlayerInfo_String, EntityDestroy_u8, EntityTeleport_i32_i32_NoGround

* Send feet_y = head_y - 1.62, fixes Illegal stance

https://wiki.vg/index.php?title=Protocol&oldid=6003#Player_Position

> Updates the players XYZ position on the server. If HeadY - FeetY is less than 0.1 or greater than 1.65, the stance is illegal and the client will be kicked with the message “Illegal Stance”.

> Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc…

* Set on_ground = true in entity teleport, fixes bouncing

* Implement block change, fix metadata/id packing, bounce _u8 through on_block_change

* Implement on_multi_block_change_u16, used with explosions
This commit is contained in:
iceiix 2018-12-15 19:56:54 -08:00 committed by ice_iix
parent a6ea434421
commit 4d127c55fe
11 changed files with 556 additions and 25 deletions

View File

@ -37,7 +37,7 @@ use flate2::Compression;
use std::time::{Instant, Duration};
use crate::shared::Position;
pub const SUPPORTED_PROTOCOLS: [i32; 8] = [340, 316, 315, 210, 109, 107, 74, 47];
pub const SUPPORTED_PROTOCOLS: [i32; 9] = [340, 316, 315, 210, 109, 107, 74, 47, 5];
// TODO: switch to using thread_local storage?, see https://doc.rust-lang.org/std/macro.thread_local.html
pub static mut CURRENT_PROTOCOL_VERSION: i32 = SUPPORTED_PROTOCOLS[0];
@ -553,6 +553,16 @@ impl <L: Lengthable> fmt::Debug for LenPrefixedBytes<L> {
}
}
impl Lengthable for u8 {
fn into(self) -> usize {
self as usize
}
fn from(u: usize) -> u8 {
u as u8
}
}
impl Lengthable for i16 {
fn into(self) -> usize {
self as usize

View File

@ -66,6 +66,9 @@ state_packets!(
field has_target: bool =,
field target: Option<Position> = when(|p: &TabComplete_NoAssume| p.has_target),
}
packet TabComplete_NoAssume_NoTarget {
field text: String =,
}
/// ChatMessage is sent by the client when it sends a chat message or
/// executes a command (prefixed by '/').
packet ChatMessage {
@ -75,6 +78,9 @@ state_packets!(
packet ClientStatus {
field action_id: VarInt =,
}
packet ClientStatus_u8 {
field action_id: u8=,
}
/// ClientSettings is sent by the client to update its current settings.
packet ClientSettings {
field locale: String =,
@ -99,6 +105,14 @@ state_packets!(
field chat_colors: bool =,
field displayed_skin_parts: u8 =,
}
packet ClientSettings_u8_Handsfree_Difficulty {
field locale: String =,
field view_distance: u8 =,
field chat_mode: u8 =,
field chat_colors: bool =,
field difficulty: u8 =,
field displayed_skin_parts: u8 =,
}
/// ConfirmTransactionServerbound is a reply to ConfirmTransaction.
packet ConfirmTransactionServerbound {
field id: u8 =,
@ -138,6 +152,10 @@ state_packets!(
field channel: String =,
field data: Vec<u8> =,
}
packet PluginMessageServerbound_i16 {
field channel: String =,
field data: LenPrefixedBytes<i16> =,
}
/// UseEntity is sent when the user interacts (right clicks) or attacks
/// (left clicks) an entity.
packet UseEntity {
@ -155,6 +173,10 @@ state_packets!(
field target_y: f32 = when(|p: &UseEntity_Handsfree| p.ty.0 == 2),
field target_z: f32 = when(|p: &UseEntity_Handsfree| p.ty.0 == 2),
}
packet UseEntity_Handsfree_i32 {
field target_id: i32 =,
field ty: u8 =,
}
/// KeepAliveServerbound is sent by a client as a response to a
/// KeepAliveClientbound. If the client doesn't reply the server
/// may disconnect the client.
@ -164,6 +186,9 @@ state_packets!(
packet KeepAliveServerbound_VarInt {
field id: VarInt =,
}
packet KeepAliveServerbound_i32 {
field id: i32 =,
}
/// PlayerPosition is used to update the player's position.
packet PlayerPosition {
field x: f64 =,
@ -171,6 +196,13 @@ state_packets!(
field z: f64 =,
field on_ground: bool =,
}
packet PlayerPosition_HeadY {
field x: f64 =,
field feet_y: f64 =,
field head_y: f64 =,
field z: f64 =,
field on_ground: bool =,
}
/// PlayerPositionLook is a combination of PlayerPosition and
/// PlayerLook.
packet PlayerPositionLook {
@ -181,6 +213,15 @@ state_packets!(
field pitch: f32 =,
field on_ground: bool =,
}
packet PlayerPositionLook_HeadY {
field x: f64 =,
field feet_y: f64 =,
field head_y: f64 =,
field z: f64 =,
field yaw: f32 =,
field pitch: f32 =,
field on_ground: bool =,
}
/// PlayerLook is used to update the player's rotation.
packet PlayerLook {
field yaw: f32 =,
@ -229,12 +270,24 @@ state_packets!(
field location: Position =,
field face: u8 =,
}
packet PlayerDigging_u8_u8y {
field status: u8 =,
field x: i32 =,
field y: u8 =,
field z: i32 =,
field face: u8 =,
}
/// PlayerAction is sent when a player preforms various actions.
packet PlayerAction {
field entity_id: VarInt =,
field action_id: VarInt =,
field jump_boost: VarInt =,
}
packet PlayerAction_i32 {
field entity_id: i32 =,
field action_id: i8 =,
field jump_boost: i32 =,
}
/// SteerVehicle is sent by the client when steers or preforms an action
/// on a vehicle.
packet SteerVehicle {
@ -242,6 +295,12 @@ state_packets!(
field forward: f32 =,
field flags: u8 =,
}
packet SteerVehicle_jump_unmount {
field sideways: f32 =,
field forward: f32 =,
field jump: bool =,
field unmount: bool =,
}
/// CraftingBookData is sent when the player interacts with the crafting book.
packet CraftingBookData {
field action: VarInt =,
@ -282,6 +341,15 @@ state_packets!(
field line3: String =,
field line4: String =,
}
packet SetSign_i16y {
field x: i32 =,
field y: i16 =,
field z: i32 =,
field line1: String =,
field line2: String =,
field line3: String =,
field line4: String =,
}
/// ArmSwing is sent by the client when the player left clicks (to swing their
/// arm).
packet ArmSwing {
@ -290,6 +358,10 @@ state_packets!(
packet ArmSwing_Handsfree {
field empty: () =,
}
packet ArmSwing_Handsfree_ID {
field entity_id: i32 =,
field animation: u8 =,
}
/// SpectateTeleport is sent by clients in spectator mode to teleport to a player.
packet SpectateTeleport {
field target: UUID =,
@ -319,6 +391,16 @@ state_packets!(
field cursor_y: u8 =,
field cursor_z: u8 =,
}
packet PlayerBlockPlacement_u8_Item_u8y {
field x: i32 =,
field y: u8 =,
field z: i32 =,
field face: u8 =,
field hand: Option<item::Stack> =,
field cursor_x: u8 =,
field cursor_y: u8 =,
field cursor_z: u8 =,
}
/// UseItem is sent when the client tries to use an item.
packet UseItem {
@ -478,6 +560,14 @@ state_packets!(
field location: Position =,
field direction: u8 =,
}
packet SpawnPainting_NoUUID_i32 {
field entity_id: VarInt =,
field title: String =,
field x: i32 =,
field y: i32 =,
field z: i32 =,
field direction: i32 =,
}
/// SpawnPlayer is used to spawn a player when they are in range of the client.
/// This packet alone isn't enough to display the player as the skin and username
/// information is in the player information packet.
@ -512,6 +602,20 @@ state_packets!(
field current_item: u16 =,
field metadata: types::Metadata =,
}
packet SpawnPlayer_i32_HeldItem_String {
field entity_id: VarInt =,
field uuid: String =,
field name: String =,
field properties: LenPrefixed<VarInt, packet::SpawnProperty> =,
field x: i32 =,
field y: i32 =,
field z: i32 =,
field yaw: i8 =,
field pitch: i8 =,
field current_item: u16 =,
field metadata: types::Metadata =,
}
/// Animation is sent by the server to play an animation on a specific entity.
packet Animation {
field entity_id: VarInt =,
@ -528,6 +632,13 @@ state_packets!(
field location: Position =,
field stage: i8 =,
}
packet BlockBreakAnimation_i32 {
field entity_id: VarInt =,
field x: i32 =,
field y: i32 =,
field z: i32 =,
field stage: i8 =,
}
/// UpdateBlockEntity updates the nbt tag of a block entity in the
/// world.
packet UpdateBlockEntity {
@ -535,6 +646,14 @@ state_packets!(
field action: u8 =,
field nbt: Option<nbt::NamedTag> =,
}
packet UpdateBlockEntity_Data {
field x: i32 =,
field y: i16 =,
field z: i32 =,
field action: u8 =,
field data_length: i16 =,
field gzipped_nbt: Vec<u8> =,
}
/// BlockAction triggers different actions depending on the target block.
packet BlockAction {
field location: Position =,
@ -542,11 +661,26 @@ state_packets!(
field byte2: u8 =,
field block_type: VarInt =,
}
packet BlockAction_u16 {
field x: i32 =,
field y: u16 =,
field z: i32 =,
field byte1: u8 =,
field byte2: u8 =,
field block_type: VarInt =,
}
/// BlockChange is used to update a single block on the client.
packet BlockChange {
packet BlockChange_VarInt {
field location: Position =,
field block_id: VarInt =,
}
packet BlockChange_u8 {
field x: i32 =,
field y: u8 =,
field z: i32 =,
field block_id: VarInt =,
field block_metadata: u8 =,
}
/// BossBar displays and/or changes a boss bar that is displayed on the
/// top of the client's screen. This is normally used for bosses such as
/// the ender dragon or the wither.
@ -578,12 +712,22 @@ state_packets!(
/// 0 - Chat message, 1 - System message, 2 - Action bar message
field position: u8 =,
}
packet ServerMessage_NoPosition {
field message: format::Component =,
}
/// MultiBlockChange is used to update a batch of blocks in a single packet.
packet MultiBlockChange {
packet MultiBlockChange_VarInt {
field chunk_x: i32 =,
field chunk_z: i32 =,
field records: LenPrefixed<VarInt, packet::BlockChangeRecord> =,
}
packet MultiBlockChange_u16 {
field chunk_x: i32 =,
field chunk_z: i32 =,
field record_count: u16 =,
field data_size: i32 =,
field data: Vec<u8> =,
}
/// ConfirmTransaction notifies the client whether a transaction was successful
/// or failed (e.g. due to lag).
packet ConfirmTransaction {
@ -606,6 +750,14 @@ state_packets!(
field slot_count: u8 =,
field entity_id: i32 = when(|p: &WindowOpen| p.ty == "EntityHorse"),
}
packet WindowOpen_u8 {
field id: u8 =,
field ty: u8 =,
field title: format::Component =,
field slot_count: u8 =,
field use_provided_window_title: bool =,
field entity_id: i32 = when(|p: &WindowOpen_u8| p.ty == 11),
}
/// WindowItems sets every item in a window.
packet WindowItems {
field id: u8 =,
@ -636,6 +788,10 @@ state_packets!(
field channel: String =,
field data: Vec<u8> =,
}
packet PluginMessageClientbound_i16 {
field channel: String =,
field data: LenPrefixedBytes<i16> =,
}
/// Plays a sound by name on the client
packet NamedSoundEffect {
field name: String =,
@ -711,6 +867,9 @@ state_packets!(
packet KeepAliveClientbound_VarInt {
field id: VarInt =,
}
packet KeepAliveClientbound_i32 {
field id: i32 =,
}
/// ChunkData sends or updates a single chunk on the client. If New is set
/// then biome data should be sent too.
packet ChunkData {
@ -735,11 +894,25 @@ state_packets!(
field bitmask: u16 =,
field data: LenPrefixedBytes<VarInt> =,
}
packet ChunkData_17 {
field chunk_x: i32 =,
field chunk_z: i32 =,
field new: bool =,
field bitmask: u16 =,
field add_bitmask: u16 =,
field compressed_data: LenPrefixedBytes<i32> =,
}
packet ChunkDataBulk {
field skylight: bool =,
field chunk_meta: LenPrefixed<VarInt, packet::ChunkMeta> =,
field chunk_data: Vec<u8> =,
}
packet ChunkDataBulk_17 {
field chunk_column_count: u16 =,
field data_length: i32 =,
field skylight: bool =,
field chunk_data_and_meta: Vec<u8> =,
}
/// Effect plays a sound effect or particle at the target location with the
/// volume (of sounds) being relative to the player's position unless
/// DisableRelative is set to true.
@ -749,6 +922,14 @@ state_packets!(
field data: i32 =,
field disable_relative: bool =,
}
packet Effect_u8y {
field effect_id: i32 =,
field x: i32 =,
field y: u8 =,
field z: i32 =,
field data: i32 =,
field disable_relative: bool =,
}
/// Particle spawns particles at the target location with the various
/// modifiers.
packet Particle {
@ -765,6 +946,17 @@ state_packets!(
field data1: VarInt = when(|p: &Particle| p.particle_id == 36 || p.particle_id == 37 || p.particle_id == 38 || p.particle_id == 46),
field data2: VarInt = when(|p: &Particle| p.particle_id == 36),
}
packet Particle_Named {
field particle_id: String =,
field x: f32 =,
field y: f32 =,
field z: f32 =,
field offset_x: f32 =,
field offset_y: f32 =,
field offset_z: f32 =,
field speed: f32 =,
field count: i32 =,
}
/// JoinGame is sent after completing the login process. This
/// sets the initial state for the client.
packet JoinGame_i32 {
@ -801,6 +993,14 @@ state_packets!(
/// information it displays in F3 mode
field reduced_debug_info: bool =,
}
packet JoinGame_i8_NoDebug {
field entity_id: i32 =,
field gamemode: u8 =,
field dimension: i8 =,
field difficulty: u8 =,
field max_players: u8 =,
field level_type: String =,
}
/// Maps updates a single map's contents
packet Maps {
field item_damage: VarInt =,
@ -823,6 +1023,10 @@ state_packets!(
field z: Option<u8> = when(|p: &Maps_NoTracking| p.columns > 0),
field data: Option<LenPrefixedBytes<VarInt>> = when(|p: &Maps_NoTracking| p.columns > 0),
}
packet Maps_NoTracking_Data {
field item_damage: VarInt =,
field data: LenPrefixedBytes<i16> =,
}
/// EntityMove moves the entity with the id by the offsets provided.
packet EntityMove_i16 {
field entity_id: VarInt =,
@ -838,6 +1042,12 @@ state_packets!(
field delta_z: i8 =,
field on_ground: bool =,
}
packet EntityMove_i8_i32_NoGround {
field entity_id: i32 =,
field delta_x: i8 =,
field delta_y: i8 =,
field delta_z: i8 =,
}
/// EntityLookAndMove is a combination of EntityMove and EntityLook.
packet EntityLookAndMove_i16 {
field entity_id: VarInt =,
@ -857,17 +1067,33 @@ state_packets!(
field pitch: i8 =,
field on_ground: bool =,
}
packet EntityLookAndMove_i8_i32_NoGround {
field entity_id: i32 =,
field delta_x: i8 =,
field delta_y: i8 =,
field delta_z: i8 =,
field yaw: i8 =,
field pitch: i8 =,
}
/// EntityLook rotates the entity to the new angles provided.
packet EntityLook {
packet EntityLook_VarInt {
field entity_id: VarInt =,
field yaw: i8 =,
field pitch: i8 =,
field on_ground: bool =,
}
packet EntityLook_i32_NoGround {
field entity_id: i32 =,
field yaw: i8 =,
field pitch: i8 =,
}
/// Entity does nothing. It is a result of subclassing used in Minecraft.
packet Entity {
field entity_id: VarInt =,
}
packet Entity_i32 {
field entity_id: i32 =,
}
/// EntityUpdateNBT updates the entity named binary tag.
packet EntityUpdateNBT {
field entity_id: VarInt =,
@ -886,6 +1112,11 @@ state_packets!(
packet SignEditorOpen {
field location: Position =,
}
packet SignEditorOpen_i32 {
field x: i32 =,
field y: i32 =,
field z: i32 =,
}
/// CraftRecipeResponse is a response to CraftRecipeRequest, notifies the UI.
packet CraftRecipeResponse {
field window_id: u8 =,
@ -912,6 +1143,11 @@ state_packets!(
packet PlayerInfo {
field inner: packet::PlayerInfoData =,
}
packet PlayerInfo_String {
field name: String =,
field online: bool =,
field ping: u16 =,
}
/// TeleportPlayer is sent to change the player's position. The client is expected
/// to reply to the server with the same positions as contained in this packet
/// otherwise will reject future packets.
@ -937,6 +1173,12 @@ state_packets!(
field entity_id: VarInt =,
field location: Position =,
}
packet EntityUsedBed_i32 {
field entity_id: i32 =,
field x: i32 =,
field y: u8 =,
field z: i32 =,
}
packet UnlockRecipes {
field action: VarInt =,
field crafting_book_open: bool =,
@ -948,11 +1190,18 @@ state_packets!(
packet EntityDestroy {
field entity_ids: LenPrefixed<VarInt, VarInt> =,
}
packet EntityDestroy_u8 {
field entity_ids: LenPrefixed<u8, i32> =,
}
/// EntityRemoveEffect removes an effect from an entity.
packet EntityRemoveEffect {
field entity_id: VarInt =,
field effect_id: i8 =,
}
packet EntityRemoveEffect_i32 {
field entity_id: i32 =,
field effect_id: i8 =,
}
/// ResourcePackSend causes the client to check its cache for the requested
/// resource packet and download it if its missing. Once the resource pack
/// is obtained the client will use it.
@ -972,6 +1221,10 @@ state_packets!(
field entity_id: VarInt =,
field head_yaw: i8 =,
}
packet EntityHeadLook_i32 {
field entity_id: i32 =,
field head_yaw: i8 =,
}
packet EntityStatus {
field entity_id: i32 =,
field entity_status: i8 =,
@ -1012,6 +1265,10 @@ state_packets!(
field entity_id: VarInt =,
field metadata: types::Metadata =,
}
packet EntityMetadata_i32 {
field entity_id: i32 =,
field metadata: types::Metadata =,
}
/// EntityAttach attaches to entities together, either by mounting or leashing.
/// -1 can be used at the EntityID to deattach.
packet EntityAttach {
@ -1031,6 +1288,12 @@ state_packets!(
field velocity_y: i16 =,
field velocity_z: i16 =,
}
packet EntityVelocity_i32 {
field entity_id: i32 =,
field velocity_x: i16 =,
field velocity_y: i16 =,
field velocity_z: i16 =,
}
/// EntityEquipment is sent to display an item on an entity, like a sword
/// or armor. Slot 0 is the held item and slots 1 to 4 are boots, leggings
/// chestplate and helmet respectively.
@ -1044,18 +1307,33 @@ state_packets!(
field slot: u16 =,
field item: Option<item::Stack> =,
}
packet EntityEquipment_u16_i32 {
field entity_id: i32 =,
field slot: u16 =,
field item: Option<item::Stack> =,
}
/// SetExperience updates the experience bar on the client.
packet SetExperience {
field experience_bar: f32 =,
field level: VarInt =,
field total_experience: VarInt =,
}
packet SetExperience_i16 {
field experience_bar: f32 =,
field level: i16 =,
field total_experience: i16 =,
}
/// UpdateHealth is sent by the server to update the player's health and food.
packet UpdateHealth {
field health: f32 =,
field food: VarInt =,
field food_saturation: f32 =,
}
packet UpdateHealth_u16 {
field health: f32 =,
field food: u16 =,
field food_saturation: f32 =,
}
/// ScoreboardObjective creates/updates a scoreboard objective.
packet ScoreboardObjective {
field name: String =,
@ -1063,6 +1341,11 @@ state_packets!(
field value: String = when(|p: &ScoreboardObjective| p.mode == 0 || p.mode == 2),
field ty: String = when(|p: &ScoreboardObjective| p.mode == 0 || p.mode == 2),
}
packet ScoreboardObjective_NoMode {
field name: String =,
field value: String =,
field ty: u8 =,
}
/// SetPassengers mounts entities to an entity
packet SetPassengers {
field entity_id: VarInt =,
@ -1081,6 +1364,15 @@ state_packets!(
field color: Option<i8> = when(|p: &Teams| p.mode == 0 || p.mode == 2),
field players: Option<LenPrefixed<VarInt, String>> = when(|p: &Teams| p.mode == 0 || p.mode == 3 || p.mode == 4),
}
packet Teams_NoVisColor {
field name: String =,
field mode: u8 =,
field display_name: Option<String> = when(|p: &Teams_NoVisColor| p.mode == 0 || p.mode == 2),
field prefix: Option<String> = when(|p: &Teams_NoVisColor| p.mode == 0 || p.mode == 2),
field suffix: Option<String> = when(|p: &Teams_NoVisColor| p.mode == 0 || p.mode == 2),
field flags: Option<u8> = when(|p: &Teams_NoVisColor| p.mode == 0 || p.mode == 2),
field players: Option<LenPrefixed<VarInt, String>> = when(|p: &Teams_NoVisColor| p.mode == 0 || p.mode == 3 || p.mode == 4),
}
/// UpdateScore is used to update or remove an item from a scoreboard
/// objective.
packet UpdateScore {
@ -1089,11 +1381,22 @@ state_packets!(
field object_name: String =,
field value: Option<VarInt> = when(|p: &UpdateScore| p.action != 1),
}
packet UpdateScore_i32 {
field name: String =,
field action: u8 =,
field object_name: String =,
field value: Option<i32 > = when(|p: &UpdateScore_i32| p.action != 1),
}
/// SpawnPosition is sent to change the player's current spawn point. Currently
/// only used by the client for the compass.
packet SpawnPosition {
field location: Position =,
}
packet SpawnPosition_i32 {
field x: i32 =,
field y: i32 =,
field z: i32 =,
}
/// TimeUpdate is sent to sync the world's time to the client, the client
/// will manually tick the time itself so this doesn't need to sent repeatedly
/// but if the server or client has issues keeping up this can fall out of sync
@ -1136,6 +1439,15 @@ state_packets!(
field line3: format::Component =,
field line4: format::Component =,
}
packet UpdateSign_u16 {
field x: i32 =,
field y: u16 =,
field z: i32 =,
field line1: format::Component =,
field line2: format::Component =,
field line3: format::Component =,
field line4: format::Component =,
}
/// SoundEffect plays the named sound at the target location.
packet SoundEffect {
field name: VarInt =,
@ -1171,6 +1483,10 @@ state_packets!(
field collected_entity_id: VarInt =,
field collector_entity_id: VarInt =,
}
packet CollectItem_nocount_i32 {
field collected_entity_id: i32 =,
field collector_entity_id: i32 =,
}
/// EntityTeleport teleports the entity to the target location. This is
/// sent if the entity moves further than EntityMove allows.
packet EntityTeleport_f64 {
@ -1191,6 +1507,14 @@ state_packets!(
field pitch: i8 =,
field on_ground: bool =,
}
packet EntityTeleport_i32_i32_NoGround {
field entity_id: i32 =,
field x: i32 =,
field y: i32 =,
field z: i32 =,
field yaw: i8 =,
field pitch: i8 =,
}
packet Advancements {
field reset_clear: bool =,
field mapping: LenPrefixed<VarInt, packet::Advancement> =,
@ -1202,6 +1526,10 @@ state_packets!(
field entity_id: VarInt =,
field properties: LenPrefixed<i32, packet::EntityProperty> =,
}
packet EntityProperties_i32 {
field entity_id: i32 =,
field properties: LenPrefixed<i32, packet::EntityProperty_i16> =,
}
/// EntityEffect applies a status effect to an entity for a given duration.
packet EntityEffect {
field entity_id: VarInt =,
@ -1210,6 +1538,12 @@ state_packets!(
field duration: VarInt =,
field hide_particles: bool =,
}
packet EntityEffect_i32 {
field entity_id: i32 =,
field effect_id: i8 =,
field amplifier: i8 =,
field duration: i16 =,
}
}
}
login Login {
@ -1231,6 +1565,10 @@ state_packets!(
/// public key
field verify_token: LenPrefixedBytes<VarInt> =,
}
packet EncryptionResponse_i16 {
field shared_secret: LenPrefixedBytes<i16> =,
field verify_token: LenPrefixedBytes<i16> =,
}
}
clientbound Clientbound {
/// LoginDisconnect is sent by the server if there was any issues
@ -1252,6 +1590,11 @@ state_packets!(
/// correctly
field verify_token: LenPrefixedBytes<VarInt> =,
}
packet EncryptionRequest_i16 {
field server_id: String =,
field public_key: LenPrefixedBytes<i16> =,
field verify_token: LenPrefixedBytes<i16> =,
}
/// LoginSuccess is sent by the server if the player successfully
/// authenicates with the session servers (online mode) or straight
/// after LoginStart (offline mode).
@ -1323,6 +1666,29 @@ state_packets!(
}
);
#[derive(Debug, Default)]
pub struct SpawnProperty {
pub name: String,
pub value: String,
pub signature: String,
}
impl Serializable for SpawnProperty {
fn read_from<R: io::Read>(buf: &mut R) -> Result<Self, Error> {
Ok(SpawnProperty {
name: Serializable::read_from(buf)?,
value: Serializable::read_from(buf)?,
signature: Serializable::read_from(buf)?,
})
}
fn write_to<W: io::Write>(&self, buf: &mut W) -> Result<(), Error> {
self.name.write_to(buf)?;
self.value.write_to(buf)?;
self.signature.write_to(buf)
}
}
#[derive(Debug, Default)]
pub struct Statistic {
pub name: String,
@ -1625,6 +1991,30 @@ impl Serializable for EntityProperty {
}
}
#[derive(Debug, Default)]
pub struct EntityProperty_i16 {
pub key: String,
pub value: f64,
pub modifiers: LenPrefixed<i16, PropertyModifier>,
}
impl Serializable for EntityProperty_i16 {
fn read_from<R: io::Read>(buf: &mut R) -> Result<Self, Error> {
Ok(EntityProperty_i16 {
key: Serializable::read_from(buf)?,
value: Serializable::read_from(buf)?,
modifiers: Serializable::read_from(buf)?,
})
}
fn write_to<W: io::Write>(&self, buf: &mut W) -> Result<(), Error> {
self.key.write_to(buf)?;
self.value.write_to(buf)?;
self.modifiers.write_to(buf)
}
}
#[derive(Debug, Default)]
pub struct PropertyModifier {
pub uuid: UUID,

View File

@ -7,6 +7,7 @@ mod v1_9_2;
mod v1_9;
mod v15w39c;
mod v1_8_9;
mod v1_7_10;
pub fn translate_internal_packet_id_for_version(version: i32, state: State, dir: Direction, id: i32, to_internal: bool) -> i32 {
match version {
@ -36,6 +37,9 @@ pub fn translate_internal_packet_id_for_version(version: i32, state: State, dir:
// 1.8.9 - 1.8
47 => v1_8_9::translate_internal_packet_id(state, dir, id, to_internal),
// 1.7.10 - 1.7.6
5 => v1_7_10::translate_internal_packet_id(state, dir, id, to_internal),
_ => panic!("unsupported protocol version"),
}
}

View File

@ -48,12 +48,12 @@ protocol_packet_ids!(
0x08 => BlockBreakAnimation
0x09 => UpdateBlockEntity
0x0a => BlockAction
0x0b => BlockChange
0x0b => BlockChange_VarInt
0x0c => BossBar
0x0d => ServerDifficulty
0x0e => TabCompleteReply
0x0f => ServerMessage
0x10 => MultiBlockChange
0x10 => MultiBlockChange_VarInt
0x11 => ConfirmTransaction
0x12 => WindowClose
0x13 => WindowOpen
@ -77,7 +77,7 @@ protocol_packet_ids!(
0x25 => Maps
0x26 => EntityMove_i8
0x27 => EntityLookAndMove_i8
0x28 => EntityLook
0x28 => EntityLook_VarInt
0x29 => Entity
0x2a => SignEditorOpen
0x2b => PlayerAbilities

View File

@ -51,12 +51,12 @@ protocol_packet_ids!(
0x08 => BlockBreakAnimation
0x09 => UpdateBlockEntity
0x0a => BlockAction
0x0b => BlockChange
0x0b => BlockChange_VarInt
0x0c => BossBar
0x0d => ServerDifficulty
0x0e => TabCompleteReply
0x0f => ServerMessage
0x10 => MultiBlockChange
0x10 => MultiBlockChange_VarInt
0x11 => ConfirmTransaction
0x12 => WindowClose
0x13 => WindowOpen
@ -79,7 +79,7 @@ protocol_packet_ids!(
0x24 => Maps
0x25 => EntityMove_i16
0x26 => EntityLookAndMove_i16
0x27 => EntityLook
0x27 => EntityLook_VarInt
0x28 => Entity
0x29 => VehicleTeleport
0x2a => SignEditorOpen

View File

@ -51,12 +51,12 @@ protocol_packet_ids!(
0x08 => BlockBreakAnimation
0x09 => UpdateBlockEntity
0x0a => BlockAction
0x0b => BlockChange
0x0b => BlockChange_VarInt
0x0c => BossBar
0x0d => ServerDifficulty
0x0e => TabCompleteReply
0x0f => ServerMessage
0x10 => MultiBlockChange
0x10 => MultiBlockChange_VarInt
0x11 => ConfirmTransaction
0x12 => WindowClose
0x13 => WindowOpen
@ -79,7 +79,7 @@ protocol_packet_ids!(
0x24 => Maps
0x25 => EntityMove_i16
0x26 => EntityLookAndMove_i16
0x27 => EntityLook
0x27 => EntityLook_VarInt
0x28 => Entity
0x29 => VehicleTeleport
0x2a => SignEditorOpen

View File

@ -54,12 +54,12 @@ protocol_packet_ids!(
0x08 => BlockBreakAnimation
0x09 => UpdateBlockEntity
0x0a => BlockAction
0x0b => BlockChange
0x0b => BlockChange_VarInt
0x0c => BossBar
0x0d => ServerDifficulty
0x0e => TabCompleteReply
0x0f => ServerMessage
0x10 => MultiBlockChange
0x10 => MultiBlockChange_VarInt
0x11 => ConfirmTransaction
0x12 => WindowClose
0x13 => WindowOpen
@ -83,7 +83,7 @@ protocol_packet_ids!(
0x25 => Entity
0x26 => EntityMove_i16
0x27 => EntityLookAndMove_i16
0x28 => EntityLook
0x28 => EntityLook_VarInt
0x29 => VehicleTeleport
0x2a => SignEditorOpen
0x2b => CraftRecipeResponse

View File

@ -0,0 +1,127 @@
protocol_packet_ids!(
handshake Handshaking {
serverbound Serverbound {
0x00 => Handshake
}
clientbound Clientbound {
}
}
play Play {
serverbound Serverbound {
0x00 => KeepAliveServerbound_i32
0x01 => ChatMessage
0x02 => UseEntity_Handsfree_i32
0x03 => Player
0x04 => PlayerPosition_HeadY
0x05 => PlayerLook
0x06 => PlayerPositionLook_HeadY
0x07 => PlayerDigging_u8_u8y
0x08 => PlayerBlockPlacement_u8_Item_u8y
0x09 => HeldItemChange
0x0a => ArmSwing_Handsfree_ID
0x0b => PlayerAction_i32
0x0c => SteerVehicle_jump_unmount
0x0d => CloseWindow
0x0e => ClickWindow_u8
0x0f => ConfirmTransactionServerbound
0x10 => CreativeInventoryAction
0x11 => EnchantItem
0x12 => SetSign_i16y
0x13 => ClientAbilities
0x14 => TabComplete_NoAssume_NoTarget
0x15 => ClientSettings_u8_Handsfree_Difficulty
0x16 => ClientStatus_u8
0x17 => PluginMessageServerbound_i16
}
clientbound Clientbound {
0x00 => KeepAliveClientbound_i32
0x01 => JoinGame_i8_NoDebug
0x02 => ServerMessage_NoPosition
0x03 => TimeUpdate
0x04 => EntityEquipment_u16_i32
0x05 => SpawnPosition_i32
0x06 => UpdateHealth_u16
0x07 => Respawn
0x08 => TeleportPlayer_NoConfirm
0x09 => SetCurrentHotbarSlot
0x0a => EntityUsedBed_i32
0x0b => Animation
0x0c => SpawnPlayer_i32_HeldItem_String
0x0d => CollectItem_nocount_i32
0x0e => SpawnObject_i32_NoUUID
0x0f => SpawnMob_u8_i32_NoUUID
0x10 => SpawnPainting_NoUUID_i32
0x11 => SpawnExperienceOrb_i32
0x12 => EntityVelocity_i32
0x13 => EntityDestroy_u8
0x14 => Entity_i32
0x15 => EntityMove_i8_i32_NoGround
0x16 => EntityLook_i32_NoGround
0x17 => EntityLookAndMove_i8_i32_NoGround
0x18 => EntityTeleport_i32_i32_NoGround
0x19 => EntityHeadLook_i32
0x1a => EntityStatus
0x1b => EntityAttach_leashed
0x1c => EntityMetadata_i32
0x1d => EntityEffect_i32
0x1e => EntityRemoveEffect_i32
0x1f => SetExperience_i16
0x20 => EntityProperties_i32
0x21 => ChunkData_17
0x22 => MultiBlockChange_u16
0x23 => BlockChange_u8
0x24 => BlockAction_u16
0x25 => BlockBreakAnimation_i32
0x26 => ChunkDataBulk_17
0x27 => Explosion
0x28 => Effect_u8y
0x29 => NamedSoundEffect_u8_NoCategory
0x2a => Particle_Named
0x2b => ChangeGameState
0x2c => SpawnGlobalEntity_i32
0x2d => WindowOpen_u8
0x2e => WindowClose
0x2f => WindowSetSlot
0x30 => WindowItems
0x31 => WindowProperty
0x32 => ConfirmTransaction
0x33 => UpdateSign_u16
0x34 => Maps_NoTracking_Data
0x35 => UpdateBlockEntity_Data
0x36 => SignEditorOpen_i32
0x37 => Statistics
0x38 => PlayerInfo_String
0x39 => PlayerAbilities
0x3a => TabCompleteReply
0x3b => ScoreboardObjective_NoMode
0x3c => UpdateScore_i32
0x3d => ScoreboardDisplay
0x3e => Teams_NoVisColor
0x3f => PluginMessageClientbound_i16
0x40 => Disconnect
}
}
login Login {
serverbound Serverbound {
0x00 => LoginStart
0x01 => EncryptionResponse_i16
}
clientbound Clientbound {
0x00 => LoginDisconnect
0x01 => EncryptionRequest_i16
0x02 => LoginSuccess
}
}
status Status {
serverbound Serverbound {
0x00 => StatusRequest
0x01 => StatusPing
}
clientbound Clientbound {
0x00 => StatusResponse
0x01 => StatusPong
}
}
);

View File

@ -58,7 +58,7 @@ protocol_packet_ids!(
0x13 => EntityDestroy
0x14 => Entity
0x15 => EntityMove_i8
0x16 => EntityLook
0x16 => EntityLook_VarInt
0x17 => EntityLookAndMove_i8
0x18 => EntityTeleport_i32
0x19 => EntityHeadLook
@ -70,8 +70,8 @@ protocol_packet_ids!(
0x1f => SetExperience
0x20 => EntityProperties
0x21 => ChunkData_NoEntities_u16
0x22 => MultiBlockChange
0x23 => BlockChange
0x22 => MultiBlockChange_VarInt
0x23 => BlockChange_VarInt
0x24 => BlockAction
0x25 => BlockBreakAnimation
0x26 => ChunkDataBulk

View File

@ -51,12 +51,12 @@ protocol_packet_ids!(
0x08 => BlockBreakAnimation
0x09 => UpdateBlockEntity
0x0a => BlockAction
0x0b => BlockChange
0x0b => BlockChange_VarInt
0x0c => BossBar
0x0d => ServerDifficulty
0x0e => TabCompleteReply
0x0f => ServerMessage
0x10 => MultiBlockChange
0x10 => MultiBlockChange_VarInt
0x11 => ConfirmTransaction
0x12 => WindowClose
0x13 => WindowOpen
@ -79,7 +79,7 @@ protocol_packet_ids!(
0x24 => Maps
0x25 => EntityMove_i16
0x26 => EntityLookAndMove_i16
0x27 => EntityLook
0x27 => EntityLook_VarInt
0x28 => Entity
0x29 => VehicleTeleport
0x2a => SignEditorOpen

View File

@ -51,12 +51,12 @@ protocol_packet_ids!(
0x08 => BlockBreakAnimation
0x09 => UpdateBlockEntity
0x0a => BlockAction
0x0b => BlockChange
0x0b => BlockChange_VarInt
0x0c => BossBar
0x0d => ServerDifficulty
0x0e => TabCompleteReply
0x0f => ServerMessage
0x10 => MultiBlockChange
0x10 => MultiBlockChange_VarInt
0x11 => ConfirmTransaction
0x12 => WindowClose
0x13 => WindowOpen
@ -79,7 +79,7 @@ protocol_packet_ids!(
0x24 => Maps
0x25 => EntityMove_i16
0x26 => EntityLookAndMove_i16
0x27 => EntityLook
0x27 => EntityLook_VarInt
0x28 => Entity
0x29 => VehicleTeleport
0x2a => SignEditorOpen