mirror of
https://github.com/italicsjenga/valence.git
synced 2024-12-23 22:41:30 +11:00
Restructure packet module
This commit is contained in:
parent
959e2b2deb
commit
e21fd70160
|
@ -253,7 +253,11 @@ impl Config for Game {
|
||||||
let mut vel = (victim.position() - e.state.attacker_pos).normalized();
|
let mut vel = (victim.position() - e.state.attacker_pos).normalized();
|
||||||
|
|
||||||
let knockback_xz = if e.state.extra_knockback { 18.0 } else { 8.0 };
|
let knockback_xz = if e.state.extra_knockback { 18.0 } else { 8.0 };
|
||||||
let knockback_y = if e.state.extra_knockback { 8.432 } else { 6.432 };
|
let knockback_y = if e.state.extra_knockback {
|
||||||
|
8.432
|
||||||
|
} else {
|
||||||
|
6.432
|
||||||
|
};
|
||||||
|
|
||||||
vel.x *= knockback_xz;
|
vel.x *= knockback_xz;
|
||||||
vel.y = knockback_y;
|
vel.y = knockback_y;
|
||||||
|
|
|
@ -175,8 +175,8 @@ impl Config for Game {
|
||||||
&& (0..SIZE_Z as i32).contains(&position.z)
|
&& (0..SIZE_Z as i32).contains(&position.z)
|
||||||
&& position.y == BOARD_Y
|
&& position.y == BOARD_Y
|
||||||
{
|
{
|
||||||
server.state.board[position.x as usize + position.z as usize * SIZE_X] =
|
server.state.board
|
||||||
true;
|
[position.x as usize + position.z as usize * SIZE_X] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::ArmSwing(hand) => match hand {
|
Event::ArmSwing(hand) => match hand {
|
||||||
|
|
|
@ -16,8 +16,8 @@ use valence::protocol::codec::Decoder;
|
||||||
use valence::protocol::packets::handshake::{Handshake, HandshakeNextState};
|
use valence::protocol::packets::handshake::{Handshake, HandshakeNextState};
|
||||||
use valence::protocol::packets::login::c2s::{EncryptionResponse, LoginStart};
|
use valence::protocol::packets::login::c2s::{EncryptionResponse, LoginStart};
|
||||||
use valence::protocol::packets::login::s2c::{LoginSuccess, S2cLoginPacket};
|
use valence::protocol::packets::login::s2c::{LoginSuccess, S2cLoginPacket};
|
||||||
use valence::protocol::packets::play::c2s::C2sPlayPacket;
|
use valence::protocol::packets::c2s::play::C2sPlayPacket;
|
||||||
use valence::protocol::packets::play::s2c::S2cPlayPacket;
|
use valence::protocol::packets::s2c::play::S2cPlayPacket;
|
||||||
use valence::protocol::packets::status::c2s::{QueryPing, QueryRequest};
|
use valence::protocol::packets::status::c2s::{QueryPing, QueryRequest};
|
||||||
use valence::protocol::packets::status::s2c::{QueryPong, QueryResponse};
|
use valence::protocol::packets::status::s2c::{QueryPong, QueryResponse};
|
||||||
use valence::protocol::packets::{DecodePacket, EncodePacket};
|
use valence::protocol::packets::{DecodePacket, EncodePacket};
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use crate::ident;
|
use crate::ident;
|
||||||
use crate::ident::Ident;
|
use crate::ident::Ident;
|
||||||
use crate::protocol_inner::packets::play::s2c::Biome as BiomeRegistryBiome;
|
use crate::protocol_inner::packets::s2c::play::Biome as BiomeRegistryBiome;
|
||||||
|
|
||||||
/// Identifies a particular [`Biome`] on the server.
|
/// Identifies a particular [`Biome`] on the server.
|
||||||
///
|
///
|
||||||
|
@ -48,7 +48,7 @@ pub struct Biome {
|
||||||
|
|
||||||
impl Biome {
|
impl Biome {
|
||||||
pub(crate) fn to_biome_registry_item(&self, id: i32) -> BiomeRegistryBiome {
|
pub(crate) fn to_biome_registry_item(&self, id: i32) -> BiomeRegistryBiome {
|
||||||
use crate::protocol_inner::packets::play::s2c::{
|
use crate::protocol_inner::packets::s2c::play::{
|
||||||
BiomeAdditionsSound, BiomeEffects, BiomeMoodSound, BiomeMusic, BiomeParticle,
|
BiomeAdditionsSound, BiomeEffects, BiomeMoodSound, BiomeMusic, BiomeParticle,
|
||||||
BiomeParticleOptions, BiomeProperty,
|
BiomeParticleOptions, BiomeProperty,
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,8 +17,8 @@ use crate::block_pos::BlockPos;
|
||||||
pub use crate::chunk_pos::ChunkPos;
|
pub use crate::chunk_pos::ChunkPos;
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::dimension::DimensionId;
|
use crate::dimension::DimensionId;
|
||||||
use crate::protocol_inner::packets::play::s2c::{
|
use crate::protocol_inner::packets::s2c::play::{
|
||||||
BlockUpdate, ChunkDataHeightmaps, ChunkData, S2cPlayPacket, ChunkSectionUpdate,
|
BlockUpdate, ChunkData, ChunkDataHeightmaps, ChunkSectionUpdate, S2cPlayPacket,
|
||||||
};
|
};
|
||||||
use crate::protocol_inner::{Encode, Nbt, VarInt, VarLong};
|
use crate::protocol_inner::{Encode, Nbt, VarInt, VarLong};
|
||||||
use crate::server::SharedServer;
|
use crate::server::SharedServer;
|
||||||
|
|
|
@ -22,19 +22,19 @@ use crate::entity::{
|
||||||
StatusOrAnimation,
|
StatusOrAnimation,
|
||||||
};
|
};
|
||||||
use crate::player_textures::SignedPlayerTextures;
|
use crate::player_textures::SignedPlayerTextures;
|
||||||
use crate::protocol_inner::packets::play::c2s::{
|
use crate::protocol_inner::packets::c2s::play::{
|
||||||
C2sPlayPacket, DiggingStatus, InteractKind, PlayerCommandId,
|
C2sPlayPacket, DiggingStatus, InteractKind, PlayerCommandId,
|
||||||
};
|
};
|
||||||
pub use crate::protocol_inner::packets::play::s2c::TitleAnimationTimes as TitleAnimationTimes;
|
pub use crate::protocol_inner::packets::s2c::play::TitleAnimationTimes;
|
||||||
use crate::protocol_inner::packets::play::s2c::{
|
use crate::protocol_inner::packets::s2c::play::{
|
||||||
EntityAnimation, BiomeRegistry, PlayerActionResponse, ChatType, ChatTypeChat, ChatTypeNarration,
|
BiomeRegistry, ChatType, ChatTypeChat, ChatTypeNarration, ChatTypeRegistry,
|
||||||
ChatTypeRegistry, ChatTypeRegistryEntry, ClearTitles, DimensionTypeRegistry,
|
ChatTypeRegistryEntry, ChunkLoadDistance, ChunkRenderDistanceCenter, ClearTitles,
|
||||||
DimensionTypeRegistryEntry, Disconnect, EntityStatus, UnloadChunk, GameStateChange,
|
DimensionTypeRegistry, DimensionTypeRegistryEntry, Disconnect, EntitiesDestroy,
|
||||||
GameStateChangeReason, KeepAlive, GameJoin, MoveRelative, RotateAndMoveRelative,
|
EntityAnimation, EntityAttributes, EntityAttributesProperty, EntityPosition, EntitySetHeadYaw,
|
||||||
Rotate, PlayerPositionLook, PlayerPositionLookFlags, RegistryCodec, EntitiesDestroy,
|
EntityStatus, EntityTrackerUpdate, EntityVelocityUpdate, GameJoin, GameMessage,
|
||||||
PlayerRespawn, EntitySetHeadYaw, S2cPlayPacket, ChunkRenderDistanceCenter, ChunkLoadDistance,
|
GameStateChange, GameStateChangeReason, KeepAlive, MoveRelative, PlayerActionResponse,
|
||||||
EntityTrackerUpdate, EntityVelocityUpdate, UpdateSubtitle, UpdateTitle, PlayerSpawnPosition, GameMessage,
|
PlayerPositionLook, PlayerPositionLookFlags, PlayerRespawn, PlayerSpawnPosition, RegistryCodec,
|
||||||
EntityPosition, EntityAttributes, EntityAttributesProperty,
|
Rotate, RotateAndMoveRelative, S2cPlayPacket, UnloadChunk, UpdateSubtitle, UpdateTitle,
|
||||||
};
|
};
|
||||||
use crate::protocol_inner::{BoundedInt, ByteAngle, Nbt, RawBytes, VarInt};
|
use crate::protocol_inner::{BoundedInt, ByteAngle, Nbt, RawBytes, VarInt};
|
||||||
use crate::server::{C2sPacketChannels, NewClientData, SharedServer};
|
use crate::server::{C2sPacketChannels, NewClientData, SharedServer};
|
||||||
|
|
|
@ -4,9 +4,9 @@ use vek::Vec3;
|
||||||
|
|
||||||
use crate::block_pos::BlockPos;
|
use crate::block_pos::BlockPos;
|
||||||
use crate::entity::EntityId;
|
use crate::entity::EntityId;
|
||||||
use crate::protocol_inner::packets::play::c2s::BlockFace;
|
use crate::protocol_inner::packets::c2s::play::BlockFace;
|
||||||
pub use crate::protocol_inner::packets::play::c2s::{ChatMode, DisplayedSkinParts, Hand, MainHand};
|
pub use crate::protocol_inner::packets::c2s::play::{ChatMode, DisplayedSkinParts, Hand, MainHand};
|
||||||
pub use crate::protocol_inner::packets::play::s2c::GameMode;
|
pub use crate::protocol_inner::packets::s2c::play::GameMode;
|
||||||
|
|
||||||
/// Represents an action performed by a client.
|
/// Represents an action performed by a client.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Dimension configuration and identification.
|
//! Dimension configuration and identification.
|
||||||
|
|
||||||
use crate::ident;
|
use crate::ident;
|
||||||
use crate::protocol_inner::packets::play::s2c::DimensionType;
|
use crate::protocol_inner::packets::s2c::play::DimensionType;
|
||||||
|
|
||||||
/// Identifies a particular [`Dimension`] on the server.
|
/// Identifies a particular [`Dimension`] on the server.
|
||||||
///
|
///
|
||||||
|
|
|
@ -12,8 +12,8 @@ use uuid::Uuid;
|
||||||
use vek::{Aabb, Vec3};
|
use vek::{Aabb, Vec3};
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::protocol_inner::packets::play::s2c::{
|
use crate::protocol_inner::packets::s2c::play::{
|
||||||
EntitySpawn, ExperienceOrbSpawn, PlayerSpawn, S2cPlayPacket, EntityTrackerUpdate,
|
EntitySpawn, EntityTrackerUpdate, ExperienceOrbSpawn, PlayerSpawn, S2cPlayPacket,
|
||||||
};
|
};
|
||||||
use crate::protocol_inner::{ByteAngle, RawBytes, VarInt};
|
use crate::protocol_inner::{ByteAngle, RawBytes, VarInt};
|
||||||
use crate::slotmap::{Key, SlotMap};
|
use crate::slotmap::{Key, SlotMap};
|
||||||
|
|
|
@ -8,7 +8,7 @@ use uuid::Uuid;
|
||||||
|
|
||||||
use crate::client::GameMode;
|
use crate::client::GameMode;
|
||||||
use crate::player_textures::SignedPlayerTextures;
|
use crate::player_textures::SignedPlayerTextures;
|
||||||
use crate::protocol_inner::packets::play::s2c::{
|
use crate::protocol_inner::packets::s2c::play::{
|
||||||
PlayerListAddPlayer, PlayerListHeaderFooter, S2cPlayPacket, UpdatePlayerList,
|
PlayerListAddPlayer, PlayerListHeaderFooter, S2cPlayPacket, UpdatePlayerList,
|
||||||
};
|
};
|
||||||
use crate::protocol_inner::packets::Property;
|
use crate::protocol_inner::packets::Property;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
707
src/protocol_inner/packets/c2s.rs
Normal file
707
src/protocol_inner/packets/c2s.rs
Normal file
|
@ -0,0 +1,707 @@
|
||||||
|
//! Client to server packets.
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub mod handshake {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
Handshake 0x00 {
|
||||||
|
protocol_version: VarInt,
|
||||||
|
server_adddress: BoundedString<0, 255>,
|
||||||
|
server_port: u16,
|
||||||
|
next_state: HandshakeNextState,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
HandshakeNextState: VarInt {
|
||||||
|
Status = 1,
|
||||||
|
Login = 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod status {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
QueryRequest 0x00 {}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
QueryPing 0x01 {
|
||||||
|
payload: u64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod login {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
LoginStart 0x00 {
|
||||||
|
username: BoundedString<3, 16>,
|
||||||
|
sig_data: Option<SignatureData>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
EncryptionResponse 0x01 {
|
||||||
|
shared_secret: BoundedArray<u8, 16, 128>,
|
||||||
|
token_or_sig: VerifyTokenOrMsgSig,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
VerifyTokenOrMsgSig: u8 {
|
||||||
|
VerifyToken: BoundedArray<u8, 16, 128> = 1,
|
||||||
|
MsgSig: MessageSignature = 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
MessageSignature {
|
||||||
|
salt: u64,
|
||||||
|
sig: Vec<u8>, // TODO: bounds?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
LoginPluginResponse 0x02 {
|
||||||
|
message_id: VarInt,
|
||||||
|
data: Option<RawBytes>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_packet_group! {
|
||||||
|
C2sLoginPacket {
|
||||||
|
LoginStart,
|
||||||
|
EncryptionResponse,
|
||||||
|
LoginPluginResponse,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod play {
|
||||||
|
use super::super::*;
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
TeleportConfirm 0x00 {
|
||||||
|
teleport_id: VarInt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
QueryBlockNbt 0x01 {
|
||||||
|
transaction_id: VarInt,
|
||||||
|
location: BlockPos,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
UpdateDifficulty 0x02: i8 {
|
||||||
|
Peaceful = 0,
|
||||||
|
Easy = 1,
|
||||||
|
Normal = 2,
|
||||||
|
Hard = 3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
CommandExecution 0x03 {
|
||||||
|
command: String, // TODO: bounded?
|
||||||
|
// TODO: timestamp, arg signatures
|
||||||
|
signed_preview: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
ChatMessage 0x04 {
|
||||||
|
message: BoundedString<0, 256>,
|
||||||
|
timestamp: u64,
|
||||||
|
salt: u64,
|
||||||
|
signature: Vec<u8>,
|
||||||
|
signed_preview: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
RequestChatPreview 0x05 {
|
||||||
|
query: i32, // TODO: is this an i32 or a varint?
|
||||||
|
message: BoundedString<0, 256>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
ClientStatus 0x06: VarInt {
|
||||||
|
/// Sent when ready to complete login and ready to respawn after death.
|
||||||
|
PerformRespawn = 0,
|
||||||
|
/// Sent when the statistics menu is opened.
|
||||||
|
RequestStatus = 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
ClientSettings 0x07 {
|
||||||
|
/// e.g. en_US
|
||||||
|
locale: BoundedString<0, 16>,
|
||||||
|
/// Client-side render distance in chunks.
|
||||||
|
view_distance: BoundedInt<u8, 2, 32>,
|
||||||
|
chat_mode: ChatMode,
|
||||||
|
chat_colors: bool,
|
||||||
|
displayed_skin_parts: DisplayedSkinParts,
|
||||||
|
main_hand: MainHand,
|
||||||
|
/// Currently always false
|
||||||
|
enable_text_filtering: bool,
|
||||||
|
/// False if the client should not show up in the hover preview.
|
||||||
|
allow_server_listings: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
#[derive(Copy, PartialEq, Eq)]
|
||||||
|
ChatMode: VarInt {
|
||||||
|
Enabled = 0,
|
||||||
|
CommandsOnly = 1,
|
||||||
|
Hidden = 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_bitfield! {
|
||||||
|
DisplayedSkinParts: u8 {
|
||||||
|
cape = 0,
|
||||||
|
jacket = 1,
|
||||||
|
left_sleeve = 2,
|
||||||
|
right_sleeve = 3,
|
||||||
|
left_pants_leg = 4,
|
||||||
|
right_pants_leg = 5,
|
||||||
|
hat = 6,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
#[derive(Copy, PartialEq, Eq)]
|
||||||
|
MainHand: VarInt {
|
||||||
|
Left = 0,
|
||||||
|
Right = 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
RequestCommandCompletion 0x08 {
|
||||||
|
transaction_id: VarInt,
|
||||||
|
/// Text behind the cursor without the '/'.
|
||||||
|
text: BoundedString<0, 32500>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
ButtonClick 0x09 {
|
||||||
|
window_id: i8,
|
||||||
|
button_id: i8,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
ClickSlot 0x0a {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
CloseHandledScreen 0x0b {
|
||||||
|
window_id: u8,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
CustomPayload 0x0c {
|
||||||
|
channel: Ident,
|
||||||
|
data: RawBytes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
BookUpdate 0x0d {
|
||||||
|
slot: VarInt,
|
||||||
|
entries: Vec<String>,
|
||||||
|
title: Option<String>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
QueryEntityNbt 0x0e {
|
||||||
|
transaction_id: VarInt,
|
||||||
|
entity_id: VarInt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
PlayerInteractEntity 0x0f {
|
||||||
|
entity_id: VarInt,
|
||||||
|
kind: InteractKind,
|
||||||
|
sneaking: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
InteractKind: VarInt {
|
||||||
|
Interact: Hand = 0,
|
||||||
|
Attack = 1,
|
||||||
|
InteractAt: (Vec3<f32>, Hand) = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
#[derive(Copy, PartialEq, Eq)]
|
||||||
|
Hand: VarInt {
|
||||||
|
Main = 0,
|
||||||
|
Off = 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
JigsawGenerate 0x10 {
|
||||||
|
location: BlockPos,
|
||||||
|
levels: VarInt,
|
||||||
|
keep_jigsaws: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
KeepAlive 0x11 {
|
||||||
|
id: i64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
UpdateDifficultyLock 0x12 {
|
||||||
|
locked: bool
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
MovePlayerPosition 0x13 {
|
||||||
|
position: Vec3<f64>,
|
||||||
|
on_ground: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
MovePlayerPositionAndRotation 0x14 {
|
||||||
|
// Absolute position
|
||||||
|
position: Vec3<f64>,
|
||||||
|
/// Absolute rotation on X axis in degrees.
|
||||||
|
yaw: f32,
|
||||||
|
/// Absolute rotation on Y axis in degrees.
|
||||||
|
pitch: f32,
|
||||||
|
on_ground: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
MovePlayerRotation 0x15 {
|
||||||
|
/// Absolute rotation on X axis in degrees.
|
||||||
|
yaw: f32,
|
||||||
|
/// Absolute rotation on Y axis in degrees.
|
||||||
|
pitch: f32,
|
||||||
|
on_ground: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
MovePlayerOnGround 0x16 {
|
||||||
|
on_ground: bool
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
MoveVehicle 0x17 {
|
||||||
|
/// Absolute position
|
||||||
|
position: Vec3<f64>,
|
||||||
|
/// Degrees
|
||||||
|
yaw: f32,
|
||||||
|
/// Degrees
|
||||||
|
pitch: f32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
BoatPaddleState 0x18 {
|
||||||
|
left_paddle_turning: bool,
|
||||||
|
right_paddle_turning: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
PickFromInventory 0x19 {
|
||||||
|
slot_to_use: VarInt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
CraftRequest 0x1a {
|
||||||
|
window_id: i8,
|
||||||
|
recipe: Ident,
|
||||||
|
make_all: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
UpdatePlayerAbilities 0x1b: i8 {
|
||||||
|
NotFlying = 0,
|
||||||
|
Flying = 0b10,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
PlayerAction 0x1c {
|
||||||
|
status: DiggingStatus,
|
||||||
|
location: BlockPos,
|
||||||
|
face: BlockFace,
|
||||||
|
sequence: VarInt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
DiggingStatus: VarInt {
|
||||||
|
StartedDigging = 0,
|
||||||
|
CancelledDigging = 1,
|
||||||
|
FinishedDigging = 2,
|
||||||
|
DropItemStack = 3,
|
||||||
|
DropItem = 4,
|
||||||
|
ShootArrowOrFinishEating = 5,
|
||||||
|
SwapItemInHand = 6,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
#[derive(Copy, PartialEq, Eq)]
|
||||||
|
BlockFace: i8 {
|
||||||
|
/// -Y
|
||||||
|
Bottom = 0,
|
||||||
|
/// +Y
|
||||||
|
Top = 1,
|
||||||
|
/// -Z
|
||||||
|
North = 2,
|
||||||
|
/// +Z
|
||||||
|
South = 3,
|
||||||
|
/// -X
|
||||||
|
West = 4,
|
||||||
|
/// +X
|
||||||
|
East = 5,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
PlayerCommand 0x1d {
|
||||||
|
entity_id: VarInt,
|
||||||
|
action_id: PlayerCommandId,
|
||||||
|
jump_boost: BoundedInt<VarInt, 0, 100>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
PlayerCommandId: VarInt {
|
||||||
|
StartSneaking = 0,
|
||||||
|
StopSneaking = 1,
|
||||||
|
LeaveBed = 2,
|
||||||
|
StartSprinting = 3,
|
||||||
|
StopSprinting = 4,
|
||||||
|
StartJumpWithHorse = 5,
|
||||||
|
StopJumpWithHorse = 6,
|
||||||
|
OpenHorseInventory = 7,
|
||||||
|
StartFlyingWithElytra = 8,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
PlayerInput 0x1e {
|
||||||
|
sideways: f32,
|
||||||
|
forward: f32,
|
||||||
|
flags: PlayerInputFlags,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_bitfield! {
|
||||||
|
PlayerInputFlags: u8 {
|
||||||
|
jump = 0,
|
||||||
|
unmount = 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
PlayPong 0x1f {
|
||||||
|
id: i32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
RecipeBookChangeSettings 0x20 {
|
||||||
|
book_id: RecipeBookId,
|
||||||
|
book_open: bool,
|
||||||
|
filter_active: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
RecipeBookId: VarInt {
|
||||||
|
Crafting = 0,
|
||||||
|
Furnace = 1,
|
||||||
|
BlastFurnace = 2,
|
||||||
|
Smoker = 3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
RecipeBookSeenRecipe 0x21 {
|
||||||
|
recipe_id: Ident,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
RenameItem 0x22 {
|
||||||
|
item_name: BoundedString<0, 50>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
ResourcePackStatus 0x23: VarInt {
|
||||||
|
SuccessfullyLoaded = 0,
|
||||||
|
Declined = 1,
|
||||||
|
FailedDownload = 2,
|
||||||
|
Accepted = 3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
AdvancementTab 0x24: VarInt {
|
||||||
|
OpenedTab: Ident = 0,
|
||||||
|
ClosedScreen = 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
SelectMerchantTrade 0x25 {
|
||||||
|
selected_slot: VarInt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
UpdateBeacon 0x26 {
|
||||||
|
// TODO: potion ids
|
||||||
|
primary_effect: Option<VarInt>,
|
||||||
|
secondary_effect: Option<VarInt>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
UpdateSelectedSlot 0x27 {
|
||||||
|
slot: BoundedInt<i16, 0, 8>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
UpdateCommandBlock 0x28 {
|
||||||
|
location: BlockPos,
|
||||||
|
command: String,
|
||||||
|
mode: CommandBlockMode,
|
||||||
|
flags: CommandBlockFlags,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
CommandBlockMode: VarInt {
|
||||||
|
Sequence = 0,
|
||||||
|
Auto = 1,
|
||||||
|
Redstone = 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_bitfield! {
|
||||||
|
CommandBlockFlags: i8 {
|
||||||
|
track_output = 0,
|
||||||
|
is_conditional = 1,
|
||||||
|
automatic = 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
UpdateCommandBlockMinecart 0x29 {
|
||||||
|
entity_id: VarInt,
|
||||||
|
command: String,
|
||||||
|
track_output: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
UpdateCreativeModeSlot 0x2a {
|
||||||
|
slot: i16,
|
||||||
|
// TODO: clicked_item: Slot,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
UpdateJigsaw 0x2b {
|
||||||
|
location: BlockPos,
|
||||||
|
name: Ident,
|
||||||
|
target: Ident,
|
||||||
|
pool: Ident,
|
||||||
|
final_state: String,
|
||||||
|
joint_type: String,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
UpdateStructureBlock 0x2c {
|
||||||
|
location: BlockPos,
|
||||||
|
action: StructureBlockAction,
|
||||||
|
mode: StructureBlockMode,
|
||||||
|
name: String,
|
||||||
|
offset_xyz: [BoundedInt<i8, -32, 32>; 3],
|
||||||
|
size_xyz: [BoundedInt<i8, 0, 32>; 3],
|
||||||
|
mirror: StructureBlockMirror,
|
||||||
|
rotation: StructureBlockRotation,
|
||||||
|
metadata: String,
|
||||||
|
integrity: f32, // TODO: bounded float between 0 and 1.
|
||||||
|
seed: VarLong,
|
||||||
|
flags: StructureBlockFlags,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
StructureBlockAction: VarInt {
|
||||||
|
UpdateData = 0,
|
||||||
|
SaveStructure = 1,
|
||||||
|
LoadStructure = 2,
|
||||||
|
DetectSize = 3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
StructureBlockMode: VarInt {
|
||||||
|
Save = 0,
|
||||||
|
Load = 1,
|
||||||
|
Corner = 2,
|
||||||
|
Data = 3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
StructureBlockMirror: VarInt {
|
||||||
|
None = 0,
|
||||||
|
LeftRight = 1,
|
||||||
|
FrontBack = 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
StructureBlockRotation: VarInt {
|
||||||
|
None = 0,
|
||||||
|
Clockwise90 = 1,
|
||||||
|
Clockwise180 = 2,
|
||||||
|
Counterclockwise90 = 3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_bitfield! {
|
||||||
|
StructureBlockFlags: i8 {
|
||||||
|
ignore_entities = 0,
|
||||||
|
show_air = 1,
|
||||||
|
show_bounding_box = 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
UpdateSign 0x2d {
|
||||||
|
location: BlockPos,
|
||||||
|
lines: [BoundedString<0, 384>; 4],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
HandSwing 0x2e {
|
||||||
|
hand: Hand,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
SpectatorTeleport 0x2f {
|
||||||
|
target: Uuid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
PlayerInteractBlock 0x30 {
|
||||||
|
hand: Hand,
|
||||||
|
location: BlockPos,
|
||||||
|
face: BlockFace,
|
||||||
|
cursor_pos: Vec3<f32>,
|
||||||
|
head_inside_block: bool,
|
||||||
|
sequence: VarInt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
PlayerInteractItem 0x31 {
|
||||||
|
hand: Hand,
|
||||||
|
sequence: VarInt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_packet_group! {
|
||||||
|
C2sPlayPacket {
|
||||||
|
TeleportConfirm,
|
||||||
|
QueryBlockNbt,
|
||||||
|
UpdateDifficulty,
|
||||||
|
CommandExecution,
|
||||||
|
ChatMessage,
|
||||||
|
RequestChatPreview,
|
||||||
|
ClientStatus,
|
||||||
|
ClientSettings,
|
||||||
|
RequestCommandCompletion,
|
||||||
|
ButtonClick,
|
||||||
|
ClickSlot,
|
||||||
|
CloseHandledScreen,
|
||||||
|
CustomPayload,
|
||||||
|
BookUpdate,
|
||||||
|
QueryEntityNbt,
|
||||||
|
PlayerInteractEntity,
|
||||||
|
JigsawGenerate,
|
||||||
|
KeepAlive,
|
||||||
|
UpdateDifficultyLock,
|
||||||
|
MovePlayerPosition,
|
||||||
|
MovePlayerPositionAndRotation,
|
||||||
|
MovePlayerRotation,
|
||||||
|
MovePlayerOnGround,
|
||||||
|
MoveVehicle,
|
||||||
|
BoatPaddleState,
|
||||||
|
PickFromInventory,
|
||||||
|
CraftRequest,
|
||||||
|
UpdatePlayerAbilities,
|
||||||
|
PlayerAction,
|
||||||
|
PlayerCommand,
|
||||||
|
PlayerInput,
|
||||||
|
PlayPong,
|
||||||
|
RecipeBookChangeSettings,
|
||||||
|
RecipeBookSeenRecipe,
|
||||||
|
RenameItem,
|
||||||
|
ResourcePackStatus,
|
||||||
|
AdvancementTab,
|
||||||
|
SelectMerchantTrade,
|
||||||
|
UpdateBeacon,
|
||||||
|
UpdateSelectedSlot,
|
||||||
|
UpdateCommandBlock,
|
||||||
|
UpdateCommandBlockMinecart,
|
||||||
|
UpdateCreativeModeSlot,
|
||||||
|
UpdateJigsaw,
|
||||||
|
UpdateStructureBlock,
|
||||||
|
UpdateSign,
|
||||||
|
HandSwing,
|
||||||
|
SpectatorTeleport,
|
||||||
|
PlayerInteractBlock,
|
||||||
|
PlayerInteractItem,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
794
src/protocol_inner/packets/s2c.rs
Normal file
794
src/protocol_inner/packets/s2c.rs
Normal file
|
@ -0,0 +1,794 @@
|
||||||
|
//! Server to client packets.
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub mod status {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
QueryResponse 0x00 {
|
||||||
|
json_response: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
QueryPong 0x01 {
|
||||||
|
/// Should be the same as the payload from ping.
|
||||||
|
payload: u64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod login {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
LoginDisconnect 0x00 {
|
||||||
|
reason: Text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
EncryptionRequest 0x01 {
|
||||||
|
/// Currently unused
|
||||||
|
server_id: BoundedString<0, 20>,
|
||||||
|
/// The RSA public key
|
||||||
|
public_key: Vec<u8>,
|
||||||
|
verify_token: BoundedArray<u8, 16, 16>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
LoginSuccess 0x02 {
|
||||||
|
uuid: Uuid,
|
||||||
|
username: BoundedString<3, 16>,
|
||||||
|
properties: Vec<Property>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
LoginCompression 0x03 {
|
||||||
|
threshold: VarInt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
LoginPluginRequest 0x04 {
|
||||||
|
message_id: VarInt,
|
||||||
|
channel: Ident,
|
||||||
|
data: RawBytes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_packet_group! {
|
||||||
|
S2cLoginPacket {
|
||||||
|
LoginDisconnect,
|
||||||
|
EncryptionRequest,
|
||||||
|
LoginSuccess,
|
||||||
|
LoginCompression,
|
||||||
|
LoginPluginRequest,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod play {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
EntitySpawn 0x00 {
|
||||||
|
entity_id: VarInt,
|
||||||
|
object_uuid: Uuid,
|
||||||
|
kind: VarInt,
|
||||||
|
position: Vec3<f64>,
|
||||||
|
pitch: ByteAngle,
|
||||||
|
yaw: ByteAngle,
|
||||||
|
head_yaw: ByteAngle,
|
||||||
|
data: VarInt,
|
||||||
|
velocity: Vec3<i16>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
ExperienceOrbSpawn 0x01 {
|
||||||
|
entity_id: VarInt,
|
||||||
|
position: Vec3<f64>,
|
||||||
|
count: i16,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
PlayerSpawn 0x02 {
|
||||||
|
entity_id: VarInt,
|
||||||
|
player_uuid: Uuid,
|
||||||
|
position: Vec3<f64>,
|
||||||
|
yaw: ByteAngle,
|
||||||
|
pitch: ByteAngle,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
EntityAnimation 0x03 {
|
||||||
|
entity_id: VarInt,
|
||||||
|
animation: u8,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
PlayerActionResponse 0x05 {
|
||||||
|
sequence: VarInt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
BlockBreakingProgress 0x06 {
|
||||||
|
entity_id: VarInt,
|
||||||
|
location: BlockPos,
|
||||||
|
destroy_stage: BoundedInt<u8, 0, 10>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
BlockEntityUpdate 0x07 {
|
||||||
|
location: BlockPos,
|
||||||
|
kind: VarInt, // TODO: use enum here
|
||||||
|
data: nbt::Blob,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
BlockEvent 0x08 {
|
||||||
|
location: BlockPos,
|
||||||
|
action_id: u8,
|
||||||
|
action_param: u8,
|
||||||
|
block_type: VarInt, // TODO: use BlockType type.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
BlockUpdate 0x09 {
|
||||||
|
location: BlockPos,
|
||||||
|
block_id: VarInt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
BossBar 0x0a {
|
||||||
|
uuid: Uuid,
|
||||||
|
action: BossBarAction,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
BossBarAction: VarInt {
|
||||||
|
Add: BossBarActionAdd = 0,
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
BossBarActionAdd {
|
||||||
|
title: Text,
|
||||||
|
health: f32,
|
||||||
|
color: BossBarColor,
|
||||||
|
division: BossBarDivision,
|
||||||
|
/// TODO: bitmask
|
||||||
|
flags: u8,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
BossBarColor: VarInt {
|
||||||
|
Pink = 0,
|
||||||
|
Blue = 1,
|
||||||
|
Red = 2,
|
||||||
|
Green = 3,
|
||||||
|
Yellow = 4,
|
||||||
|
Purple = 5,
|
||||||
|
White = 6,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
BossBarDivision: VarInt {
|
||||||
|
NoDivision = 0,
|
||||||
|
SixNotches = 1,
|
||||||
|
TenNotches = 2,
|
||||||
|
TwelveNotches = 3,
|
||||||
|
TwentyNotches = 4,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
SetDifficulty 0x0b {
|
||||||
|
difficulty: Difficulty,
|
||||||
|
locked: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
Difficulty: u8 {
|
||||||
|
Peaceful = 0,
|
||||||
|
Easy = 1,
|
||||||
|
Normal = 2,
|
||||||
|
Hard = 3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
ClearTitles 0x0d {
|
||||||
|
reset: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
Disconnect 0x17 {
|
||||||
|
reason: Text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
EntityStatus 0x18 {
|
||||||
|
entity_id: i32,
|
||||||
|
entity_status: u8,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
UnloadChunk 0x1a {
|
||||||
|
chunk_x: i32,
|
||||||
|
chunk_z: i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
GameStateChange 0x1b {
|
||||||
|
reason: GameStateChangeReason,
|
||||||
|
value: f32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
GameStateChangeReason: u8 {
|
||||||
|
NoRespawnBlockAvailable = 0,
|
||||||
|
EndRaining = 1,
|
||||||
|
BeginRaining = 2,
|
||||||
|
ChangeGameMode = 3,
|
||||||
|
WinGame = 4,
|
||||||
|
DemoEvent = 5,
|
||||||
|
ArrowHitPlayer = 6,
|
||||||
|
RainLevelChange = 7,
|
||||||
|
ThunderLevelChange = 8,
|
||||||
|
PlayPufferfishStingSound = 9,
|
||||||
|
PlayElderGuardianMobAppearance = 10,
|
||||||
|
EnableRespawnScreen = 11,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
WorldBorderInitialize 0x1d {
|
||||||
|
x: f64,
|
||||||
|
z: f64,
|
||||||
|
old_diameter: f64,
|
||||||
|
new_diameter: f64,
|
||||||
|
speed: VarLong,
|
||||||
|
portal_teleport_boundary: VarInt,
|
||||||
|
warning_blocks: VarInt,
|
||||||
|
warning_time: VarInt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
KeepAlive 0x1e {
|
||||||
|
id: i64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
ChunkData 0x1f {
|
||||||
|
chunk_x: i32,
|
||||||
|
chunk_z: i32,
|
||||||
|
heightmaps: Nbt<ChunkDataHeightmaps>,
|
||||||
|
blocks_and_biomes: Vec<u8>,
|
||||||
|
block_entities: Vec<ChunkDataBlockEntity>,
|
||||||
|
trust_edges: bool,
|
||||||
|
sky_light_mask: BitVec<u64>,
|
||||||
|
block_light_mask: BitVec<u64>,
|
||||||
|
empty_sky_light_mask: BitVec<u64>,
|
||||||
|
empty_block_light_mask: BitVec<u64>,
|
||||||
|
sky_light_arrays: Vec<[u8; 2048]>,
|
||||||
|
block_light_arrays: Vec<[u8; 2048]>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct ChunkDataHeightmaps {
|
||||||
|
#[serde(rename = "MOTION_BLOCKING", serialize_with = "nbt::i64_array")]
|
||||||
|
pub motion_blocking: Vec<i64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
ChunkDataBlockEntity {
|
||||||
|
packed_xz: i8,
|
||||||
|
y: i16,
|
||||||
|
kind: VarInt,
|
||||||
|
data: nbt::Blob,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
GameJoin 0x23 {
|
||||||
|
/// Entity ID of the joining player
|
||||||
|
entity_id: i32,
|
||||||
|
is_hardcore: bool,
|
||||||
|
gamemode: GameMode,
|
||||||
|
previous_gamemode: GameMode,
|
||||||
|
dimension_names: Vec<Ident>,
|
||||||
|
registry_codec: Nbt<RegistryCodec>,
|
||||||
|
/// The name of the dimension type being spawned into.
|
||||||
|
dimension_type_name: Ident,
|
||||||
|
/// The name of the dimension being spawned into.
|
||||||
|
dimension_name: Ident,
|
||||||
|
/// Hash of the world's seed used for client biome noise.
|
||||||
|
hashed_seed: i64,
|
||||||
|
/// No longer used by the client.
|
||||||
|
max_players: VarInt,
|
||||||
|
view_distance: BoundedInt<VarInt, 2, 32>,
|
||||||
|
simulation_distance: VarInt,
|
||||||
|
/// If reduced debug info should be shown on the F3 screen.
|
||||||
|
reduced_debug_info: bool,
|
||||||
|
/// If player respawns should be instant or not.
|
||||||
|
enable_respawn_screen: bool,
|
||||||
|
is_debug: bool,
|
||||||
|
/// If this is a superflat world.
|
||||||
|
/// Superflat worlds have different void fog and horizon levels.
|
||||||
|
is_flat: bool,
|
||||||
|
last_death_location: Option<(Ident, BlockPos)>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct RegistryCodec {
|
||||||
|
#[serde(rename = "minecraft:dimension_type")]
|
||||||
|
pub dimension_type_registry: DimensionTypeRegistry,
|
||||||
|
#[serde(rename = "minecraft:worldgen/biome")]
|
||||||
|
pub biome_registry: BiomeRegistry,
|
||||||
|
#[serde(rename = "minecraft:chat_type")]
|
||||||
|
pub chat_type_registry: ChatTypeRegistry,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct DimensionTypeRegistry {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub kind: Ident,
|
||||||
|
pub value: Vec<DimensionTypeRegistryEntry>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct DimensionTypeRegistryEntry {
|
||||||
|
pub name: Ident,
|
||||||
|
pub id: i32,
|
||||||
|
pub element: DimensionType,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct DimensionType {
|
||||||
|
pub piglin_safe: bool,
|
||||||
|
pub has_raids: bool,
|
||||||
|
pub monster_spawn_light_level: i32,
|
||||||
|
pub monster_spawn_block_light_limit: i32,
|
||||||
|
pub natural: bool,
|
||||||
|
pub ambient_light: f32,
|
||||||
|
pub fixed_time: Option<i64>,
|
||||||
|
pub infiniburn: String, // TODO: tag type?
|
||||||
|
pub respawn_anchor_works: bool,
|
||||||
|
pub has_skylight: bool,
|
||||||
|
pub bed_works: bool,
|
||||||
|
pub effects: Ident,
|
||||||
|
pub min_y: i32,
|
||||||
|
pub height: i32,
|
||||||
|
pub logical_height: i32,
|
||||||
|
pub coordinate_scale: f64,
|
||||||
|
pub ultrawarm: bool,
|
||||||
|
pub has_ceiling: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct BiomeRegistry {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub kind: Ident,
|
||||||
|
pub value: Vec<Biome>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Biome {
|
||||||
|
pub name: Ident,
|
||||||
|
pub id: i32,
|
||||||
|
pub element: BiomeProperty,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct BiomeProperty {
|
||||||
|
pub precipitation: String,
|
||||||
|
pub depth: f32,
|
||||||
|
pub temperature: f32,
|
||||||
|
pub scale: f32,
|
||||||
|
pub downfall: f32,
|
||||||
|
pub category: String,
|
||||||
|
pub temperature_modifier: Option<String>,
|
||||||
|
pub effects: BiomeEffects,
|
||||||
|
pub particle: Option<BiomeParticle>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct BiomeEffects {
|
||||||
|
pub sky_color: i32,
|
||||||
|
pub water_fog_color: i32,
|
||||||
|
pub fog_color: i32,
|
||||||
|
pub water_color: i32,
|
||||||
|
pub foliage_color: Option<i32>,
|
||||||
|
pub grass_color: Option<i32>,
|
||||||
|
pub grass_color_modifier: Option<String>,
|
||||||
|
pub music: Option<BiomeMusic>,
|
||||||
|
pub ambient_sound: Option<Ident>,
|
||||||
|
pub additions_sound: Option<BiomeAdditionsSound>,
|
||||||
|
pub mood_sound: Option<BiomeMoodSound>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct BiomeMusic {
|
||||||
|
pub replace_current_music: bool,
|
||||||
|
pub sound: Ident,
|
||||||
|
pub max_delay: i32,
|
||||||
|
pub min_delay: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct BiomeAdditionsSound {
|
||||||
|
pub sound: Ident,
|
||||||
|
pub tick_chance: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct BiomeMoodSound {
|
||||||
|
pub sound: Ident,
|
||||||
|
pub tick_delay: i32,
|
||||||
|
pub offset: f64,
|
||||||
|
pub block_search_extent: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct BiomeParticle {
|
||||||
|
pub probability: f32,
|
||||||
|
pub options: BiomeParticleOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct BiomeParticleOptions {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub kind: Ident,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct ChatTypeRegistry {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub kind: Ident,
|
||||||
|
pub value: Vec<ChatTypeRegistryEntry>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct ChatTypeRegistryEntry {
|
||||||
|
pub name: Ident,
|
||||||
|
pub id: i32,
|
||||||
|
pub element: ChatType,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct ChatType {
|
||||||
|
pub chat: ChatTypeChat,
|
||||||
|
pub narration: ChatTypeNarration,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct ChatTypeChat {}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct ChatTypeNarration {
|
||||||
|
pub priority: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
|
||||||
|
GameMode: u8 {
|
||||||
|
#[default]
|
||||||
|
Survival = 0,
|
||||||
|
Creative = 1,
|
||||||
|
Adventure = 2,
|
||||||
|
Spectator = 3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
MoveRelative 0x26 {
|
||||||
|
entity_id: VarInt,
|
||||||
|
delta: Vec3<i16>,
|
||||||
|
on_ground: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
RotateAndMoveRelative 0x27 {
|
||||||
|
entity_id: VarInt,
|
||||||
|
delta: Vec3<i16>,
|
||||||
|
yaw: ByteAngle,
|
||||||
|
pitch: ByteAngle,
|
||||||
|
on_ground: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
Rotate 0x28 {
|
||||||
|
entity_id: VarInt,
|
||||||
|
yaw: ByteAngle,
|
||||||
|
pitch: ByteAngle,
|
||||||
|
on_ground: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
ChatMessage 0x30 {
|
||||||
|
message: Text,
|
||||||
|
/// Index into the chat type registry
|
||||||
|
kind: VarInt,
|
||||||
|
sender: Uuid,
|
||||||
|
// TODO more fields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_enum! {
|
||||||
|
UpdatePlayerList 0x34: VarInt {
|
||||||
|
AddPlayer: Vec<PlayerListAddPlayer> = 0,
|
||||||
|
UpdateGameMode: Vec<(Uuid, GameMode)> = 1,
|
||||||
|
UpdateLatency: Vec<(Uuid, VarInt)> = 2,
|
||||||
|
UpdateDisplayName: Vec<(Uuid, Option<Text>)> = 3,
|
||||||
|
RemovePlayer: Vec<Uuid> = 4,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
PlayerListAddPlayer {
|
||||||
|
uuid: Uuid,
|
||||||
|
username: BoundedString<3, 16>,
|
||||||
|
properties: Vec<Property>,
|
||||||
|
game_mode: GameMode,
|
||||||
|
ping: VarInt,
|
||||||
|
display_name: Option<Text>,
|
||||||
|
sig_data: Option<SignatureData>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
PlayerPositionLook 0x36 {
|
||||||
|
position: Vec3<f64>,
|
||||||
|
yaw: f32,
|
||||||
|
pitch: f32,
|
||||||
|
flags: PlayerPositionLookFlags,
|
||||||
|
teleport_id: VarInt,
|
||||||
|
dismount_vehicle: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_bitfield! {
|
||||||
|
PlayerPositionLookFlags: u8 {
|
||||||
|
x = 0,
|
||||||
|
y = 1,
|
||||||
|
z = 2,
|
||||||
|
y_rot = 3,
|
||||||
|
x_rot = 4,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
EntitiesDestroy 0x38 {
|
||||||
|
entities: Vec<VarInt>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
PlayerRespawn 0x3b {
|
||||||
|
dimension_type_name: Ident,
|
||||||
|
dimension_name: Ident,
|
||||||
|
hashed_seed: u64,
|
||||||
|
game_mode: GameMode,
|
||||||
|
previous_game_mode: GameMode,
|
||||||
|
is_debug: bool,
|
||||||
|
is_flat: bool,
|
||||||
|
copy_metadata: bool,
|
||||||
|
last_death_location: Option<(Ident, BlockPos)>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
EntitySetHeadYaw 0x3c {
|
||||||
|
entity_id: VarInt,
|
||||||
|
head_yaw: ByteAngle,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
ChunkSectionUpdate 0x3d {
|
||||||
|
chunk_section_position: i64,
|
||||||
|
invert_trust_edges: bool,
|
||||||
|
blocks: Vec<VarLong>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
UpdateSelectedSlot 0x47 {
|
||||||
|
slot: BoundedInt<u8, 0, 9>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
ChunkRenderDistanceCenter 0x48 {
|
||||||
|
chunk_x: VarInt,
|
||||||
|
chunk_z: VarInt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
ChunkLoadDistance 0x49 {
|
||||||
|
view_distance: BoundedInt<VarInt, 2, 32>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
PlayerSpawnPosition 0x4a {
|
||||||
|
location: BlockPos,
|
||||||
|
angle: f32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
EntityTrackerUpdate 0x4d {
|
||||||
|
entity_id: VarInt,
|
||||||
|
metadata: RawBytes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
EntityVelocityUpdate 0x4f {
|
||||||
|
entity_id: VarInt,
|
||||||
|
velocity: Vec3<i16>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
UpdateSubtitle 0x58 {
|
||||||
|
subtitle_text: Text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
WorldTimeUpdate 0x59 {
|
||||||
|
/// The age of the world in 1/20ths of a second.
|
||||||
|
world_age: i64,
|
||||||
|
/// The current time of day in 1/20ths of a second.
|
||||||
|
/// The value should be in the range \[0, 24000].
|
||||||
|
/// 6000 is noon, 12000 is sunset, and 18000 is midnight.
|
||||||
|
time_of_day: i64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
UpdateTitle 0x5a {
|
||||||
|
text: Text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
#[derive(Copy, PartialEq, Eq)]
|
||||||
|
TitleAnimationTimes 0x5b {
|
||||||
|
/// Ticks to spend fading in.
|
||||||
|
fade_in: u32,
|
||||||
|
/// Ticks to keep the title displayed.
|
||||||
|
stay: u32,
|
||||||
|
/// Ticks to spend fading out.
|
||||||
|
fade_out: u32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
GameMessage 0x5f {
|
||||||
|
chat: Text,
|
||||||
|
/// Index into the chat type registry.
|
||||||
|
kind: VarInt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
PlayerListHeaderFooter 0x60 {
|
||||||
|
header: Text,
|
||||||
|
footer: Text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
EntityPosition 0x63 {
|
||||||
|
entity_id: VarInt,
|
||||||
|
position: Vec3<f64>,
|
||||||
|
yaw: ByteAngle,
|
||||||
|
pitch: ByteAngle,
|
||||||
|
on_ground: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
EntityAttributes 0x65 {
|
||||||
|
entity_id: VarInt,
|
||||||
|
properties: Vec<EntityAttributesProperty>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
EntityAttributesProperty {
|
||||||
|
key: Ident,
|
||||||
|
value: f64,
|
||||||
|
modifiers: Vec<EntityAttributesModifiers>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
EntityAttributesModifiers {
|
||||||
|
uuid: Uuid,
|
||||||
|
amount: f64,
|
||||||
|
operation: u8,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_packet_group! {
|
||||||
|
S2cPlayPacket {
|
||||||
|
EntitySpawn,
|
||||||
|
ExperienceOrbSpawn,
|
||||||
|
PlayerSpawn,
|
||||||
|
EntityAnimation,
|
||||||
|
PlayerActionResponse,
|
||||||
|
BlockBreakingProgress,
|
||||||
|
BlockEntityUpdate,
|
||||||
|
BlockEvent,
|
||||||
|
BlockUpdate,
|
||||||
|
BossBar,
|
||||||
|
ClearTitles,
|
||||||
|
Disconnect,
|
||||||
|
EntityStatus,
|
||||||
|
UnloadChunk,
|
||||||
|
GameStateChange,
|
||||||
|
KeepAlive,
|
||||||
|
ChunkData,
|
||||||
|
GameJoin,
|
||||||
|
MoveRelative,
|
||||||
|
RotateAndMoveRelative,
|
||||||
|
Rotate,
|
||||||
|
ChatMessage,
|
||||||
|
UpdatePlayerList,
|
||||||
|
PlayerPositionLook,
|
||||||
|
EntitiesDestroy,
|
||||||
|
PlayerRespawn,
|
||||||
|
EntitySetHeadYaw,
|
||||||
|
ChunkSectionUpdate,
|
||||||
|
UpdateSelectedSlot,
|
||||||
|
ChunkRenderDistanceCenter,
|
||||||
|
ChunkLoadDistance,
|
||||||
|
PlayerSpawnPosition,
|
||||||
|
EntityTrackerUpdate,
|
||||||
|
EntityVelocityUpdate,
|
||||||
|
UpdateSubtitle,
|
||||||
|
WorldTimeUpdate,
|
||||||
|
UpdateTitle,
|
||||||
|
TitleAnimationTimes,
|
||||||
|
GameMessage,
|
||||||
|
PlayerListHeaderFooter,
|
||||||
|
EntityPosition,
|
||||||
|
EntityAttributes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,16 +34,16 @@ use crate::dimension::{Dimension, DimensionId};
|
||||||
use crate::entity::Entities;
|
use crate::entity::Entities;
|
||||||
use crate::player_textures::SignedPlayerTextures;
|
use crate::player_textures::SignedPlayerTextures;
|
||||||
use crate::protocol_inner::codec::{Decoder, Encoder};
|
use crate::protocol_inner::codec::{Decoder, Encoder};
|
||||||
use crate::protocol_inner::packets::handshake::{Handshake, HandshakeNextState};
|
use crate::protocol_inner::packets::c2s::handshake::{Handshake, HandshakeNextState};
|
||||||
use crate::protocol_inner::packets::login::c2s::{
|
use crate::protocol_inner::packets::c2s::login::{
|
||||||
EncryptionResponse, LoginStart, VerifyTokenOrMsgSig,
|
EncryptionResponse, LoginStart, VerifyTokenOrMsgSig,
|
||||||
};
|
};
|
||||||
use crate::protocol_inner::packets::login::s2c::{EncryptionRequest, LoginSuccess, LoginCompression};
|
use crate::protocol_inner::packets::c2s::play::C2sPlayPacket;
|
||||||
use crate::protocol_inner::packets::play::c2s::C2sPlayPacket;
|
use crate::protocol_inner::packets::c2s::status::{QueryPing, QueryRequest};
|
||||||
use crate::protocol_inner::packets::play::s2c::S2cPlayPacket;
|
use crate::protocol_inner::packets::s2c::login::{EncryptionRequest, LoginCompression, LoginDisconnect, LoginSuccess};
|
||||||
use crate::protocol_inner::packets::status::c2s::{QueryPing, QueryRequest};
|
use crate::protocol_inner::packets::s2c::play::S2cPlayPacket;
|
||||||
use crate::protocol_inner::packets::status::s2c::{QueryPong, QueryResponse};
|
use crate::protocol_inner::packets::s2c::status::{QueryPong, QueryResponse};
|
||||||
use crate::protocol_inner::packets::{login, Property};
|
use crate::protocol_inner::packets::Property;
|
||||||
use crate::protocol_inner::{BoundedArray, BoundedString, VarInt};
|
use crate::protocol_inner::{BoundedArray, BoundedString, VarInt};
|
||||||
use crate::util::valid_username;
|
use crate::util::valid_username;
|
||||||
use crate::world::Worlds;
|
use crate::world::Worlds;
|
||||||
|
@ -723,7 +723,7 @@ async fn handle_login<C: Config>(
|
||||||
if let Err(reason) = server.0.cfg.login(server, &npd).await {
|
if let Err(reason) = server.0.cfg.login(server, &npd).await {
|
||||||
log::info!("Disconnect at login: \"{reason}\"");
|
log::info!("Disconnect at login: \"{reason}\"");
|
||||||
c.enc
|
c.enc
|
||||||
.write_packet(&login::s2c::LoginDisconnect { reason })
|
.write_packet(&LoginDisconnect { reason })
|
||||||
.await?;
|
.await?;
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue