1.15.1 protocol support (575) (#252)
* Add v1_15_1 for protocol 575 * Update for shifted packet IDs https://wiki.vg/index.php?title=Pre-release_protocol&oldid=15213#Packets https://wiki.vg/Pre-release_protocol * Add SpawnMob packet variant, no metadata * Add SpawnPlayer packet variant, no metadata * Add block update actions comments, including beehive * Add particle packet variant with 64-bit floats * Add and handle join game and respawn packet variants, with hashed seeds * Add chunk data packet variant with 3D biomes https://wiki.vg/index.php?title=Pre-release_protocol&oldid=15213#Chunk_Data "1024 biome IDs, ordered by x then z then d, in 4×4×4 blocks. Not present if full chunk is false." This is a fixed-size array of integers, but Rust doesn't yet support generics over integers, so the 1024-element array doesn't support fmt::Debug, hence we wrap it and implement fmt::Debug ourselves. * Add load_chunk115 to not read chunk data structure biomes https://wiki.vg/index.php?title=Pre-release_protocol&oldid=15213#Data_structure
This commit is contained in:
parent
3da354def4
commit
2daca512b0
|
@ -23,6 +23,7 @@ Join with your favorite IRC client or [Matrix](https://matrix.to/#/#_espernet_#s
|
||||||
|
|
||||||
| Game version | Protocol version | Supported? |
|
| Game version | Protocol version | Supported? |
|
||||||
| ------ | --- | --- |
|
| ------ | --- | --- |
|
||||||
|
| 1.15.1 | 575 | ✓ |
|
||||||
| 1.14.4 | 498 | ✓ |
|
| 1.14.4 | 498 | ✓ |
|
||||||
| 1.14.3 | 490 | ✓ |
|
| 1.14.3 | 490 | ✓ |
|
||||||
| 1.14.2 | 485 | ✓ |
|
| 1.14.2 | 485 | ✓ |
|
||||||
|
|
|
@ -42,7 +42,7 @@ use std::time::{Instant, Duration};
|
||||||
use crate::shared::Position;
|
use crate::shared::Position;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
|
||||||
pub const SUPPORTED_PROTOCOLS: [i32; 17] = [498, 490, 485, 480, 477, 452, 451, 404, 340, 316, 315, 210, 109, 107, 74, 47, 5];
|
pub const SUPPORTED_PROTOCOLS: [i32; 18] = [575, 498, 490, 485, 480, 477, 452, 451, 404, 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
|
// 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];
|
pub static mut CURRENT_PROTOCOL_VERSION: i32 = SUPPORTED_PROTOCOLS[0];
|
||||||
|
@ -447,6 +447,43 @@ impl Serializable for UUID {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Biomes3D {
|
||||||
|
pub data: [i32; 1024],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for Biomes3D {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "Biomes3D(")?;
|
||||||
|
for i in 0..1024 {
|
||||||
|
write!(f, "{}, ", self.data[i])?;
|
||||||
|
}
|
||||||
|
write!(f, ")")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Biomes3D {
|
||||||
|
fn default() -> Self {
|
||||||
|
Biomes3D { data: [0; 1024] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serializable for Biomes3D {
|
||||||
|
fn read_from<R: io::Read>(buf: &mut R) -> Result<Biomes3D, Error> {
|
||||||
|
let mut data: [i32; 1024] = [0; 1024];
|
||||||
|
|
||||||
|
// Non-length-prefixed three-dimensional biome data
|
||||||
|
for i in 0..1024 {
|
||||||
|
let b: i32 = Serializable::read_from(buf)?;
|
||||||
|
data[i] = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result::Ok(Biomes3D { data })
|
||||||
|
}
|
||||||
|
fn write_to<W: io::Write>(&self, _buf: &mut W) -> Result<(), Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub trait Lengthable : Serializable + Copy + Default {
|
pub trait Lengthable : Serializable + Copy + Default {
|
||||||
fn into_len(self) -> usize;
|
fn into_len(self) -> usize;
|
||||||
|
|
|
@ -558,7 +558,21 @@ state_packets!(
|
||||||
}
|
}
|
||||||
/// SpawnMob is used to spawn a living entity into the world when it is in
|
/// SpawnMob is used to spawn a living entity into the world when it is in
|
||||||
/// range of the client.
|
/// range of the client.
|
||||||
packet SpawnMob {
|
packet SpawnMob_NoMeta {
|
||||||
|
field entity_id: VarInt =,
|
||||||
|
field uuid: UUID =,
|
||||||
|
field ty: VarInt =,
|
||||||
|
field x: f64 =,
|
||||||
|
field y: f64 =,
|
||||||
|
field z: f64 =,
|
||||||
|
field yaw: i8 =,
|
||||||
|
field pitch: i8 =,
|
||||||
|
field head_pitch: i8 =,
|
||||||
|
field velocity_x: i16 =,
|
||||||
|
field velocity_y: i16 =,
|
||||||
|
field velocity_z: i16 =,
|
||||||
|
}
|
||||||
|
packet SpawnMob_WithMeta {
|
||||||
field entity_id: VarInt =,
|
field entity_id: VarInt =,
|
||||||
field uuid: UUID =,
|
field uuid: UUID =,
|
||||||
field ty: VarInt =,
|
field ty: VarInt =,
|
||||||
|
@ -650,6 +664,15 @@ state_packets!(
|
||||||
/// SpawnPlayer is used to spawn a player when they are in range of the client.
|
/// 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
|
/// This packet alone isn't enough to display the player as the skin and username
|
||||||
/// information is in the player information packet.
|
/// information is in the player information packet.
|
||||||
|
packet SpawnPlayer_f64_NoMeta {
|
||||||
|
field entity_id: VarInt =,
|
||||||
|
field uuid: UUID =,
|
||||||
|
field x: f64 =,
|
||||||
|
field y: f64 =,
|
||||||
|
field z: f64 =,
|
||||||
|
field yaw: i8 =,
|
||||||
|
field pitch: i8 =,
|
||||||
|
}
|
||||||
packet SpawnPlayer_f64 {
|
packet SpawnPlayer_f64 {
|
||||||
field entity_id: VarInt =,
|
field entity_id: VarInt =,
|
||||||
field uuid: UUID =,
|
field uuid: UUID =,
|
||||||
|
@ -969,6 +992,16 @@ state_packets!(
|
||||||
}
|
}
|
||||||
/// ChunkData sends or updates a single chunk on the client. If New is set
|
/// ChunkData sends or updates a single chunk on the client. If New is set
|
||||||
/// then biome data should be sent too.
|
/// then biome data should be sent too.
|
||||||
|
packet ChunkData_Biomes3D {
|
||||||
|
field chunk_x: i32 =,
|
||||||
|
field chunk_z: i32 =,
|
||||||
|
field new: bool =,
|
||||||
|
field bitmask: VarInt =,
|
||||||
|
field heightmaps: Option<nbt::NamedTag> =,
|
||||||
|
field biomes: Biomes3D = when(|p: &ChunkData_Biomes3D| p.new),
|
||||||
|
field data: LenPrefixedBytes<VarInt> =,
|
||||||
|
field block_entities: LenPrefixed<VarInt, Option<nbt::NamedTag>> =,
|
||||||
|
}
|
||||||
packet ChunkData_HeightMap {
|
packet ChunkData_HeightMap {
|
||||||
field chunk_x: i32 =,
|
field chunk_x: i32 =,
|
||||||
field chunk_z: i32 =,
|
field chunk_z: i32 =,
|
||||||
|
@ -1038,6 +1071,24 @@ state_packets!(
|
||||||
}
|
}
|
||||||
/// Particle spawns particles at the target location with the various
|
/// Particle spawns particles at the target location with the various
|
||||||
/// modifiers.
|
/// modifiers.
|
||||||
|
packet Particle_f64 {
|
||||||
|
field particle_id: i32 =,
|
||||||
|
field long_distance: bool =,
|
||||||
|
field x: f64 =,
|
||||||
|
field y: f64=,
|
||||||
|
field z: f64 =,
|
||||||
|
field offset_x: f32 =,
|
||||||
|
field offset_y: f32 =,
|
||||||
|
field offset_z: f32 =,
|
||||||
|
field speed: f32 =,
|
||||||
|
field count: i32 =,
|
||||||
|
field block_state: VarInt = when(|p: &Particle_f64| p.particle_id == 3 || p.particle_id == 20),
|
||||||
|
field red: f32 = when(|p: &Particle_f64| p.particle_id == 11),
|
||||||
|
field green: f32 = when(|p: &Particle_f64| p.particle_id == 11),
|
||||||
|
field blue: f32 = when(|p: &Particle_f64| p.particle_id == 11),
|
||||||
|
field scale: f32 = when(|p: &Particle_f64| p.particle_id == 11),
|
||||||
|
field item: Option<nbt::NamedTag> = when(|p: &Particle_f64| p.particle_id == 27),
|
||||||
|
}
|
||||||
packet Particle_Data {
|
packet Particle_Data {
|
||||||
field particle_id: i32 =,
|
field particle_id: i32 =,
|
||||||
field long_distance: bool =,
|
field long_distance: bool =,
|
||||||
|
@ -1083,6 +1134,27 @@ state_packets!(
|
||||||
}
|
}
|
||||||
/// JoinGame is sent after completing the login process. This
|
/// JoinGame is sent after completing the login process. This
|
||||||
/// sets the initial state for the client.
|
/// sets the initial state for the client.
|
||||||
|
packet JoinGame_HashedSeed_Respawn {
|
||||||
|
/// The entity id the client will be referenced by
|
||||||
|
field entity_id: i32 =,
|
||||||
|
/// The starting gamemode of the client
|
||||||
|
field gamemode: u8 =,
|
||||||
|
/// The dimension the client is starting in
|
||||||
|
field dimension: i32 =,
|
||||||
|
/// Truncated SHA-256 hash of world's seed
|
||||||
|
field hashed_seed: i64 =,
|
||||||
|
/// The max number of players on the server
|
||||||
|
field max_players: u8 =,
|
||||||
|
/// The level type of the server
|
||||||
|
field level_type: String =,
|
||||||
|
/// The render distance (2-32)
|
||||||
|
field view_distance: VarInt =,
|
||||||
|
/// Whether the client should reduce the amount of debug
|
||||||
|
/// information it displays in F3 mode
|
||||||
|
field reduced_debug_info: bool =,
|
||||||
|
/// Whether to prompt or immediately respawn
|
||||||
|
field enable_respawn_screen: bool =,
|
||||||
|
}
|
||||||
packet JoinGame_i32_ViewDistance {
|
packet JoinGame_i32_ViewDistance {
|
||||||
/// The entity id the client will be referenced by
|
/// The entity id the client will be referenced by
|
||||||
field entity_id: i32 =,
|
field entity_id: i32 =,
|
||||||
|
@ -1387,6 +1459,13 @@ state_packets!(
|
||||||
field gamemode: u8 =,
|
field gamemode: u8 =,
|
||||||
field level_type: String =,
|
field level_type: String =,
|
||||||
}
|
}
|
||||||
|
packet Respawn_HashedSeed {
|
||||||
|
field dimension: i32 =,
|
||||||
|
field hashed_seed: i64 =,
|
||||||
|
field difficulty: u8 =,
|
||||||
|
field gamemode: u8 =,
|
||||||
|
field level_type: String =,
|
||||||
|
}
|
||||||
/// EntityHeadLook rotates an entity's head to the new angle.
|
/// EntityHeadLook rotates an entity's head to the new angle.
|
||||||
packet EntityHeadLook {
|
packet EntityHeadLook {
|
||||||
field entity_id: VarInt =,
|
field entity_id: VarInt =,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
mod v1_15_1;
|
||||||
mod v1_14_4;
|
mod v1_14_4;
|
||||||
mod v1_14_3;
|
mod v1_14_3;
|
||||||
mod v1_14_2;
|
mod v1_14_2;
|
||||||
|
@ -23,6 +24,7 @@ mod v1_7_10;
|
||||||
pub fn protocol_name_to_protocol_version(s: String) -> i32 {
|
pub fn protocol_name_to_protocol_version(s: String) -> i32 {
|
||||||
match s.as_ref() {
|
match s.as_ref() {
|
||||||
"" => SUPPORTED_PROTOCOLS[0],
|
"" => SUPPORTED_PROTOCOLS[0],
|
||||||
|
"1.15.1" => 575,
|
||||||
"1.14.4" => 498,
|
"1.14.4" => 498,
|
||||||
"1.14.3" => 490,
|
"1.14.3" => 490,
|
||||||
"1.14.2" => 485,
|
"1.14.2" => 485,
|
||||||
|
@ -52,6 +54,7 @@ pub fn protocol_name_to_protocol_version(s: String) -> i32 {
|
||||||
|
|
||||||
pub fn translate_internal_packet_id_for_version(version: i32, state: State, dir: Direction, id: i32, to_internal: bool) -> i32 {
|
pub fn translate_internal_packet_id_for_version(version: i32, state: State, dir: Direction, id: i32, to_internal: bool) -> i32 {
|
||||||
match version {
|
match version {
|
||||||
|
575 => v1_15_1::translate_internal_packet_id(state, dir, id, to_internal),
|
||||||
498 => v1_14_4::translate_internal_packet_id(state, dir, id, to_internal),
|
498 => v1_14_4::translate_internal_packet_id(state, dir, id, to_internal),
|
||||||
490 => v1_14_3::translate_internal_packet_id(state, dir, id, to_internal),
|
490 => v1_14_3::translate_internal_packet_id(state, dir, id, to_internal),
|
||||||
485 => v1_14_2::translate_internal_packet_id(state, dir, id, to_internal),
|
485 => v1_14_2::translate_internal_packet_id(state, dir, id, to_internal),
|
||||||
|
|
|
@ -56,7 +56,7 @@ protocol_packet_ids!(
|
||||||
0x00 => SpawnObject
|
0x00 => SpawnObject
|
||||||
0x01 => SpawnExperienceOrb
|
0x01 => SpawnExperienceOrb
|
||||||
0x02 => SpawnGlobalEntity
|
0x02 => SpawnGlobalEntity
|
||||||
0x03 => SpawnMob
|
0x03 => SpawnMob_WithMeta
|
||||||
0x04 => SpawnPainting_String
|
0x04 => SpawnPainting_String
|
||||||
0x05 => SpawnPlayer_f64
|
0x05 => SpawnPlayer_f64
|
||||||
0x06 => Animation
|
0x06 => Animation
|
||||||
|
|
|
@ -56,7 +56,7 @@ protocol_packet_ids!(
|
||||||
0x00 => SpawnObject
|
0x00 => SpawnObject
|
||||||
0x01 => SpawnExperienceOrb
|
0x01 => SpawnExperienceOrb
|
||||||
0x02 => SpawnGlobalEntity
|
0x02 => SpawnGlobalEntity
|
||||||
0x03 => SpawnMob
|
0x03 => SpawnMob_WithMeta
|
||||||
0x04 => SpawnPainting_String
|
0x04 => SpawnPainting_String
|
||||||
0x05 => SpawnPlayer_f64
|
0x05 => SpawnPlayer_f64
|
||||||
0x06 => Animation
|
0x06 => Animation
|
||||||
|
|
|
@ -43,7 +43,7 @@ protocol_packet_ids!(
|
||||||
0x00 => SpawnObject
|
0x00 => SpawnObject
|
||||||
0x01 => SpawnExperienceOrb
|
0x01 => SpawnExperienceOrb
|
||||||
0x02 => SpawnGlobalEntity
|
0x02 => SpawnGlobalEntity
|
||||||
0x03 => SpawnMob
|
0x03 => SpawnMob_WithMeta
|
||||||
0x04 => SpawnPainting_String
|
0x04 => SpawnPainting_String
|
||||||
0x05 => SpawnPlayer_f64
|
0x05 => SpawnPlayer_f64
|
||||||
0x06 => Animation
|
0x06 => Animation
|
||||||
|
|
|
@ -46,7 +46,7 @@ protocol_packet_ids!(
|
||||||
0x00 => SpawnObject
|
0x00 => SpawnObject
|
||||||
0x01 => SpawnExperienceOrb
|
0x01 => SpawnExperienceOrb
|
||||||
0x02 => SpawnGlobalEntity
|
0x02 => SpawnGlobalEntity
|
||||||
0x03 => SpawnMob
|
0x03 => SpawnMob_WithMeta
|
||||||
0x04 => SpawnPainting_VarInt
|
0x04 => SpawnPainting_VarInt
|
||||||
0x05 => SpawnPlayer_f64
|
0x05 => SpawnPlayer_f64
|
||||||
0x06 => Animation
|
0x06 => Animation
|
||||||
|
|
|
@ -56,7 +56,7 @@ protocol_packet_ids!(
|
||||||
0x00 => SpawnObject
|
0x00 => SpawnObject
|
||||||
0x01 => SpawnExperienceOrb
|
0x01 => SpawnExperienceOrb
|
||||||
0x02 => SpawnGlobalEntity
|
0x02 => SpawnGlobalEntity
|
||||||
0x03 => SpawnMob
|
0x03 => SpawnMob_WithMeta
|
||||||
0x04 => SpawnPainting_VarInt
|
0x04 => SpawnPainting_VarInt
|
||||||
0x05 => SpawnPlayer_f64
|
0x05 => SpawnPlayer_f64
|
||||||
0x06 => Animation
|
0x06 => Animation
|
||||||
|
|
|
@ -59,7 +59,7 @@ protocol_packet_ids!(
|
||||||
0x00 => SpawnObject
|
0x00 => SpawnObject
|
||||||
0x01 => SpawnExperienceOrb
|
0x01 => SpawnExperienceOrb
|
||||||
0x02 => SpawnGlobalEntity
|
0x02 => SpawnGlobalEntity
|
||||||
0x03 => SpawnMob
|
0x03 => SpawnMob_WithMeta
|
||||||
0x04 => SpawnPainting_VarInt
|
0x04 => SpawnPainting_VarInt
|
||||||
0x05 => SpawnPlayer_f64
|
0x05 => SpawnPlayer_f64
|
||||||
0x06 => Animation
|
0x06 => Animation
|
||||||
|
|
|
@ -59,7 +59,7 @@ protocol_packet_ids!(
|
||||||
0x00 => SpawnObject
|
0x00 => SpawnObject
|
||||||
0x01 => SpawnExperienceOrb
|
0x01 => SpawnExperienceOrb
|
||||||
0x02 => SpawnGlobalEntity
|
0x02 => SpawnGlobalEntity
|
||||||
0x03 => SpawnMob
|
0x03 => SpawnMob_WithMeta
|
||||||
0x04 => SpawnPainting_VarInt
|
0x04 => SpawnPainting_VarInt
|
||||||
0x05 => SpawnPlayer_f64
|
0x05 => SpawnPlayer_f64
|
||||||
0x06 => Animation
|
0x06 => Animation
|
||||||
|
|
|
@ -59,7 +59,7 @@ protocol_packet_ids!(
|
||||||
0x00 => SpawnObject
|
0x00 => SpawnObject
|
||||||
0x01 => SpawnExperienceOrb
|
0x01 => SpawnExperienceOrb
|
||||||
0x02 => SpawnGlobalEntity
|
0x02 => SpawnGlobalEntity
|
||||||
0x03 => SpawnMob
|
0x03 => SpawnMob_WithMeta
|
||||||
0x04 => SpawnPainting_VarInt
|
0x04 => SpawnPainting_VarInt
|
||||||
0x05 => SpawnPlayer_f64
|
0x05 => SpawnPlayer_f64
|
||||||
0x06 => Animation
|
0x06 => Animation
|
||||||
|
|
|
@ -59,7 +59,7 @@ protocol_packet_ids!(
|
||||||
0x00 => SpawnObject
|
0x00 => SpawnObject
|
||||||
0x01 => SpawnExperienceOrb
|
0x01 => SpawnExperienceOrb
|
||||||
0x02 => SpawnGlobalEntity
|
0x02 => SpawnGlobalEntity
|
||||||
0x03 => SpawnMob
|
0x03 => SpawnMob_WithMeta
|
||||||
0x04 => SpawnPainting_VarInt
|
0x04 => SpawnPainting_VarInt
|
||||||
0x05 => SpawnPlayer_f64
|
0x05 => SpawnPlayer_f64
|
||||||
0x06 => Animation
|
0x06 => Animation
|
||||||
|
|
|
@ -59,7 +59,7 @@ protocol_packet_ids!(
|
||||||
0x00 => SpawnObject
|
0x00 => SpawnObject
|
||||||
0x01 => SpawnExperienceOrb
|
0x01 => SpawnExperienceOrb
|
||||||
0x02 => SpawnGlobalEntity
|
0x02 => SpawnGlobalEntity
|
||||||
0x03 => SpawnMob
|
0x03 => SpawnMob_WithMeta
|
||||||
0x04 => SpawnPainting_VarInt
|
0x04 => SpawnPainting_VarInt
|
||||||
0x05 => SpawnPlayer_f64
|
0x05 => SpawnPlayer_f64
|
||||||
0x06 => Animation
|
0x06 => Animation
|
||||||
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
protocol_packet_ids!(
|
||||||
|
handshake Handshaking {
|
||||||
|
serverbound Serverbound {
|
||||||
|
0x00 => Handshake
|
||||||
|
}
|
||||||
|
clientbound Clientbound {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
play Play {
|
||||||
|
serverbound Serverbound {
|
||||||
|
0x00 => TeleportConfirm
|
||||||
|
0x01 => QueryBlockNBT
|
||||||
|
0x02 => SetDifficulty
|
||||||
|
0x03 => ChatMessage
|
||||||
|
0x04 => ClientStatus
|
||||||
|
0x05 => ClientSettings
|
||||||
|
0x06 => TabComplete
|
||||||
|
0x07 => ConfirmTransactionServerbound
|
||||||
|
0x08 => ClickWindowButton
|
||||||
|
0x09 => ClickWindow
|
||||||
|
0x0a => CloseWindow
|
||||||
|
0x0b => PluginMessageServerbound
|
||||||
|
0x0c => EditBook
|
||||||
|
0x0d => QueryEntityNBT
|
||||||
|
0x0e => UseEntity
|
||||||
|
0x0f => KeepAliveServerbound_i64
|
||||||
|
0x10 => LockDifficulty
|
||||||
|
0x11 => PlayerPosition
|
||||||
|
0x12 => PlayerPositionLook
|
||||||
|
0x13 => PlayerLook
|
||||||
|
0x14 => Player
|
||||||
|
0x15 => VehicleMove
|
||||||
|
0x16 => SteerBoat
|
||||||
|
0x17 => PickItem
|
||||||
|
0x18 => CraftRecipeRequest
|
||||||
|
0x19 => ClientAbilities
|
||||||
|
0x1a => PlayerDigging
|
||||||
|
0x1b => PlayerAction
|
||||||
|
0x1c => SteerVehicle
|
||||||
|
0x1d => CraftingBookData
|
||||||
|
0x1e => NameItem
|
||||||
|
0x1f => ResourcePackStatus
|
||||||
|
0x20 => AdvancementTab
|
||||||
|
0x21 => SelectTrade
|
||||||
|
0x22 => SetBeaconEffect
|
||||||
|
0x23 => HeldItemChange
|
||||||
|
0x24 => UpdateCommandBlock
|
||||||
|
0x25 => UpdateCommandBlockMinecart
|
||||||
|
0x26 => CreativeInventoryAction
|
||||||
|
0x27 => UpdateJigsawBlock
|
||||||
|
0x28 => UpdateStructureBlock
|
||||||
|
0x29 => SetSign
|
||||||
|
0x2a => ArmSwing
|
||||||
|
0x2b => SpectateTeleport
|
||||||
|
0x2c => PlayerBlockPlacement_f32
|
||||||
|
0x2d => UseItem
|
||||||
|
}
|
||||||
|
clientbound Clientbound {
|
||||||
|
0x00 => SpawnObject
|
||||||
|
0x01 => SpawnExperienceOrb
|
||||||
|
0x02 => SpawnGlobalEntity
|
||||||
|
0x03 => SpawnMob_NoMeta
|
||||||
|
0x04 => SpawnPainting_VarInt
|
||||||
|
0x05 => SpawnPlayer_f64_NoMeta
|
||||||
|
0x06 => Animation
|
||||||
|
0x07 => Statistics
|
||||||
|
0x08 => AcknowledgePlayerDigging
|
||||||
|
0x09 => BlockBreakAnimation
|
||||||
|
0x0a => UpdateBlockEntity
|
||||||
|
0x0b => BlockAction
|
||||||
|
0x0c => BlockChange_VarInt
|
||||||
|
0x0d => BossBar
|
||||||
|
0x0e => ServerDifficulty_Locked
|
||||||
|
0x0f => ServerMessage
|
||||||
|
0x10 => MultiBlockChange_VarInt
|
||||||
|
0x11 => TabCompleteReply
|
||||||
|
0x12 => DeclareCommands
|
||||||
|
0x13 => ConfirmTransaction
|
||||||
|
0x14 => WindowClose
|
||||||
|
0x15 => WindowItems
|
||||||
|
0x16 => WindowProperty
|
||||||
|
0x17 => WindowSetSlot
|
||||||
|
0x18 => SetCooldown
|
||||||
|
0x19 => PluginMessageClientbound
|
||||||
|
0x1a => NamedSoundEffect
|
||||||
|
0x1b => Disconnect
|
||||||
|
0x1c => EntityAction
|
||||||
|
0x1d => Explosion
|
||||||
|
0x1e => ChunkUnload
|
||||||
|
0x1f => ChangeGameState
|
||||||
|
0x20 => WindowOpenHorse
|
||||||
|
0x21 => KeepAliveClientbound_i64
|
||||||
|
0x22 => ChunkData_Biomes3D
|
||||||
|
0x23 => Effect
|
||||||
|
0x24 => Particle_f64
|
||||||
|
0x25 => UpdateLight
|
||||||
|
0x26 => JoinGame_HashedSeed_Respawn
|
||||||
|
0x27 => Maps
|
||||||
|
0x28 => TradeList_WithRestock
|
||||||
|
0x29 => EntityMove_i16
|
||||||
|
0x2a => EntityLookAndMove_i16
|
||||||
|
0x2b => EntityLook_VarInt
|
||||||
|
0x2c => Entity
|
||||||
|
0x2d => VehicleTeleport
|
||||||
|
0x2e => OpenBook
|
||||||
|
0x2f => WindowOpen_VarInt
|
||||||
|
0x30 => SignEditorOpen
|
||||||
|
0x31 => CraftRecipeResponse
|
||||||
|
0x32 => PlayerAbilities
|
||||||
|
0x33 => CombatEvent
|
||||||
|
0x34 => PlayerInfo
|
||||||
|
0x35 => FacePlayer
|
||||||
|
0x36 => TeleportPlayer_WithConfirm
|
||||||
|
0x37 => UnlockRecipes_WithSmelting
|
||||||
|
0x38 => EntityDestroy
|
||||||
|
0x39 => EntityRemoveEffect
|
||||||
|
0x3a => ResourcePackSend
|
||||||
|
0x3b => Respawn_HashedSeed
|
||||||
|
0x3c => EntityHeadLook
|
||||||
|
0x3d => SelectAdvancementTab
|
||||||
|
0x3e => WorldBorder
|
||||||
|
0x3f => Camera
|
||||||
|
0x40 => SetCurrentHotbarSlot
|
||||||
|
0x41 => UpdateViewPosition
|
||||||
|
0x42 => UpdateViewDistance
|
||||||
|
0x43 => ScoreboardDisplay
|
||||||
|
0x44 => EntityMetadata
|
||||||
|
0x45 => EntityAttach
|
||||||
|
0x46 => EntityVelocity
|
||||||
|
0x47 => EntityEquipment
|
||||||
|
0x48 => SetExperience
|
||||||
|
0x49 => UpdateHealth
|
||||||
|
0x4a => ScoreboardObjective
|
||||||
|
0x4b => SetPassengers
|
||||||
|
0x4c => Teams_VarInt
|
||||||
|
0x4d => UpdateScore
|
||||||
|
0x4e => SpawnPosition
|
||||||
|
0x4f => TimeUpdate
|
||||||
|
0x50 => Title
|
||||||
|
0x51 => EntitySoundEffect
|
||||||
|
0x52 => SoundEffect
|
||||||
|
0x53 => StopSound
|
||||||
|
0x54 => PlayerListHeaderFooter
|
||||||
|
0x55 => NBTQueryResponse
|
||||||
|
0x56 => CollectItem
|
||||||
|
0x57 => EntityTeleport_f64
|
||||||
|
0x58 => Advancements
|
||||||
|
0x59 => EntityProperties
|
||||||
|
0x5a => EntityEffect
|
||||||
|
0x5b => DeclareRecipes
|
||||||
|
0x5c => TagsWithEntities
|
||||||
|
}
|
||||||
|
}
|
||||||
|
login Login {
|
||||||
|
serverbound Serverbound {
|
||||||
|
0x00 => LoginStart
|
||||||
|
0x01 => EncryptionResponse
|
||||||
|
0x02 => LoginPluginResponse
|
||||||
|
}
|
||||||
|
clientbound Clientbound {
|
||||||
|
0x00 => LoginDisconnect
|
||||||
|
0x01 => EncryptionRequest
|
||||||
|
0x02 => LoginSuccess
|
||||||
|
0x03 => SetInitialCompression
|
||||||
|
0x04 => LoginPluginRequest
|
||||||
|
}
|
||||||
|
}
|
||||||
|
status Status {
|
||||||
|
serverbound Serverbound {
|
||||||
|
0x00 => StatusRequest
|
||||||
|
0x01 => StatusPing
|
||||||
|
}
|
||||||
|
clientbound Clientbound {
|
||||||
|
0x00 => StatusResponse
|
||||||
|
0x01 => StatusPong
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
|
@ -396,15 +396,18 @@ impl Server {
|
||||||
self pck {
|
self pck {
|
||||||
PluginMessageClientbound_i16 => on_plugin_message_clientbound_i16,
|
PluginMessageClientbound_i16 => on_plugin_message_clientbound_i16,
|
||||||
PluginMessageClientbound => on_plugin_message_clientbound_1,
|
PluginMessageClientbound => on_plugin_message_clientbound_1,
|
||||||
|
JoinGame_HashedSeed_Respawn => on_game_join_hashedseed_respawn,
|
||||||
JoinGame_i32_ViewDistance => on_game_join_i32_viewdistance,
|
JoinGame_i32_ViewDistance => on_game_join_i32_viewdistance,
|
||||||
JoinGame_i32 => on_game_join_i32,
|
JoinGame_i32 => on_game_join_i32,
|
||||||
JoinGame_i8 => on_game_join_i8,
|
JoinGame_i8 => on_game_join_i8,
|
||||||
JoinGame_i8_NoDebug => on_game_join_i8_nodebug,
|
JoinGame_i8_NoDebug => on_game_join_i8_nodebug,
|
||||||
Respawn => on_respawn,
|
Respawn => on_respawn,
|
||||||
|
Respawn_HashedSeed => on_respawn_hashedseed,
|
||||||
KeepAliveClientbound_i64 => on_keep_alive_i64,
|
KeepAliveClientbound_i64 => on_keep_alive_i64,
|
||||||
KeepAliveClientbound_VarInt => on_keep_alive_varint,
|
KeepAliveClientbound_VarInt => on_keep_alive_varint,
|
||||||
KeepAliveClientbound_i32 => on_keep_alive_i32,
|
KeepAliveClientbound_i32 => on_keep_alive_i32,
|
||||||
ChunkData => on_chunk_data,
|
ChunkData => on_chunk_data,
|
||||||
|
ChunkData_Biomes3D => on_chunk_data_biomes3d,
|
||||||
ChunkData_HeightMap => on_chunk_data_heightmap,
|
ChunkData_HeightMap => on_chunk_data_heightmap,
|
||||||
ChunkData_NoEntities => on_chunk_data_no_entities,
|
ChunkData_NoEntities => on_chunk_data_no_entities,
|
||||||
ChunkData_NoEntities_u16 => on_chunk_data_no_entities_u16,
|
ChunkData_NoEntities_u16 => on_chunk_data_no_entities_u16,
|
||||||
|
@ -778,6 +781,10 @@ impl Server {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_game_join_hashedseed_respawn(&mut self, join: packet::play::clientbound::JoinGame_HashedSeed_Respawn) {
|
||||||
|
self.on_game_join(join.gamemode, join.entity_id)
|
||||||
|
}
|
||||||
|
|
||||||
fn on_game_join_i32_viewdistance(&mut self, join: packet::play::clientbound::JoinGame_i32_ViewDistance) {
|
fn on_game_join_i32_viewdistance(&mut self, join: packet::play::clientbound::JoinGame_i32_ViewDistance) {
|
||||||
self.on_game_join(join.gamemode, join.entity_id)
|
self.on_game_join(join.gamemode, join.entity_id)
|
||||||
}
|
}
|
||||||
|
@ -821,9 +828,17 @@ impl Server {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_respawn_hashedseed(&mut self, respawn: packet::play::clientbound::Respawn_HashedSeed) {
|
||||||
|
self.respawn(respawn.gamemode)
|
||||||
|
}
|
||||||
|
|
||||||
fn on_respawn(&mut self, respawn: packet::play::clientbound::Respawn) {
|
fn on_respawn(&mut self, respawn: packet::play::clientbound::Respawn) {
|
||||||
|
self.respawn(respawn.gamemode)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn respawn(&mut self, gamemode_u8: u8) {
|
||||||
self.world = world::World::new(self.protocol_version);
|
self.world = world::World::new(self.protocol_version);
|
||||||
let gamemode = Gamemode::from_int((respawn.gamemode & 0x7) as i32);
|
let gamemode = Gamemode::from_int((gamemode_u8 & 0x7) as i32);
|
||||||
|
|
||||||
if let Some(player) = self.player {
|
if let Some(player) = self.player {
|
||||||
*self.entities.get_component_mut(player, self.gamemode).unwrap() = gamemode;
|
*self.entities.get_component_mut(player, self.gamemode).unwrap() = gamemode;
|
||||||
|
@ -1073,7 +1088,17 @@ impl Server {
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
Some(nbt) => {
|
Some(nbt) => {
|
||||||
if block_update.action == 9 {
|
match block_update.action {
|
||||||
|
// TODO: support more block update actions
|
||||||
|
//1 => // Mob spawner
|
||||||
|
//2 => // Command block text
|
||||||
|
//3 => // Beacon
|
||||||
|
//4 => // Mob head
|
||||||
|
//5 => // Conduit
|
||||||
|
//6 => // Banner
|
||||||
|
//7 => // Structure
|
||||||
|
//8 => // Gateway
|
||||||
|
9 => { // Sign
|
||||||
let line1 = format::Component::from_string(nbt.1.get("Text1").unwrap().as_str().unwrap());
|
let line1 = format::Component::from_string(nbt.1.get("Text1").unwrap().as_str().unwrap());
|
||||||
let line2 = format::Component::from_string(nbt.1.get("Text2").unwrap().as_str().unwrap());
|
let line2 = format::Component::from_string(nbt.1.get("Text2").unwrap().as_str().unwrap());
|
||||||
let line3 = format::Component::from_string(nbt.1.get("Text3").unwrap().as_str().unwrap());
|
let line3 = format::Component::from_string(nbt.1.get("Text3").unwrap().as_str().unwrap());
|
||||||
|
@ -1085,6 +1110,14 @@ impl Server {
|
||||||
line3,
|
line3,
|
||||||
line4,
|
line4,
|
||||||
));
|
));
|
||||||
|
},
|
||||||
|
//10 => // Unused
|
||||||
|
//11 => // Jigsaw
|
||||||
|
//12 => // Campfire
|
||||||
|
//14 => // Beehive
|
||||||
|
_ => {
|
||||||
|
debug!("Unsupported block entity action: {}", block_update.action);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1231,6 +1264,18 @@ impl Server {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_chunk_data_biomes3d(&mut self, chunk_data: packet::play::clientbound::ChunkData_Biomes3D) {
|
||||||
|
self.world.load_chunk115(
|
||||||
|
chunk_data.chunk_x,
|
||||||
|
chunk_data.chunk_z,
|
||||||
|
chunk_data.new,
|
||||||
|
chunk_data.bitmask.0 as u16,
|
||||||
|
chunk_data.data.data
|
||||||
|
).unwrap();
|
||||||
|
self.load_block_entities(chunk_data.block_entities.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn on_chunk_data(&mut self, chunk_data: packet::play::clientbound::ChunkData) {
|
fn on_chunk_data(&mut self, chunk_data: packet::play::clientbound::ChunkData) {
|
||||||
self.world.load_chunk19(
|
self.world.load_chunk19(
|
||||||
chunk_data.chunk_x,
|
chunk_data.chunk_x,
|
||||||
|
|
|
@ -830,6 +830,14 @@ impl World {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_chunk19(&mut self, x: i32, z: i32, new: bool, mask: u16, data: Vec<u8>) -> Result<(), protocol::Error> {
|
pub fn load_chunk19(&mut self, x: i32, z: i32, new: bool, mask: u16, data: Vec<u8>) -> Result<(), protocol::Error> {
|
||||||
|
self.load_chunk19_or_115(true, x, z, new, mask, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_chunk115(&mut self, x: i32, z: i32, new: bool, mask: u16, data: Vec<u8>) -> Result<(), protocol::Error> {
|
||||||
|
self.load_chunk19_or_115(false, x, z, new, mask, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_chunk19_or_115(&mut self, read_biomes: bool, x: i32, z: i32, new: bool, mask: u16, data: Vec<u8>) -> Result<(), protocol::Error> {
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use byteorder::ReadBytesExt;
|
use byteorder::ReadBytesExt;
|
||||||
use crate::protocol::{VarInt, Serializable, LenPrefixed};
|
use crate::protocol::{VarInt, Serializable, LenPrefixed};
|
||||||
|
@ -911,7 +919,7 @@ impl World {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if new {
|
if read_biomes && new {
|
||||||
data.read_exact(&mut chunk.biomes)?;
|
data.read_exact(&mut chunk.biomes)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue