Add chunk data packet
This commit is contained in:
parent
8675361bef
commit
5c4721a2bc
@ -18,3 +18,4 @@ uuid = { version = "0.7", features = ["v4", "serde"] }
|
|||||||
mc-varint = { git = "https://github.com/luojia65/mc-varint" }
|
mc-varint = { git = "https://github.com/luojia65/mc-varint" }
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
num-derive = "0.2"
|
num-derive = "0.2"
|
||||||
|
named-binary-tag = "0.2"
|
||||||
|
89
src/game.rs
89
src/game.rs
@ -6,6 +6,7 @@ use num_derive::{FromPrimitive, ToPrimitive};
|
|||||||
use crate::chat::Message;
|
use crate::chat::Message;
|
||||||
use crate::{DecodeError, EncodeError, Packet, PacketRead, PacketWrite};
|
use crate::{DecodeError, EncodeError, Packet, PacketRead, PacketWrite};
|
||||||
use mc_varint::{VarIntRead, VarIntWrite};
|
use mc_varint::{VarIntRead, VarIntWrite};
|
||||||
|
use nbt::CompoundTag;
|
||||||
|
|
||||||
const SERVER_BOUND_CHAT_MESSAGE_MAX_LENGTH: u32 = 256;
|
const SERVER_BOUND_CHAT_MESSAGE_MAX_LENGTH: u32 = 256;
|
||||||
const LEVEL_TYPE_MAX_LENGTH: u32 = 16;
|
const LEVEL_TYPE_MAX_LENGTH: u32 = 16;
|
||||||
@ -19,6 +20,7 @@ pub enum GameClientBoundPacket {
|
|||||||
ClientBoundChatMessage(ClientBoundChatMessage),
|
ClientBoundChatMessage(ClientBoundChatMessage),
|
||||||
JoinGame(JoinGame),
|
JoinGame(JoinGame),
|
||||||
ClientBoundKeepAlive(ClientBoundKeepAlive),
|
ClientBoundKeepAlive(ClientBoundKeepAlive),
|
||||||
|
ChunkData(ChunkData),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameServerBoundPacket {
|
impl GameServerBoundPacket {
|
||||||
@ -51,6 +53,7 @@ impl GameClientBoundPacket {
|
|||||||
match self {
|
match self {
|
||||||
GameClientBoundPacket::ClientBoundChatMessage(_) => 0x0E,
|
GameClientBoundPacket::ClientBoundChatMessage(_) => 0x0E,
|
||||||
GameClientBoundPacket::ClientBoundKeepAlive(_) => 0x20,
|
GameClientBoundPacket::ClientBoundKeepAlive(_) => 0x20,
|
||||||
|
GameClientBoundPacket::ChunkData(_) => 0x21,
|
||||||
GameClientBoundPacket::JoinGame(_) => 0x25,
|
GameClientBoundPacket::JoinGame(_) => 0x25,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,6 +70,11 @@ impl GameClientBoundPacket {
|
|||||||
|
|
||||||
Ok(GameClientBoundPacket::ClientBoundKeepAlive(keep_alive))
|
Ok(GameClientBoundPacket::ClientBoundKeepAlive(keep_alive))
|
||||||
}
|
}
|
||||||
|
0x21 => {
|
||||||
|
let chunk_data = ChunkData::decode(reader)?;
|
||||||
|
|
||||||
|
Ok(GameClientBoundPacket::ChunkData(chunk_data))
|
||||||
|
}
|
||||||
0x25 => {
|
0x25 => {
|
||||||
let join_game = JoinGame::decode(reader)?;
|
let join_game = JoinGame::decode(reader)?;
|
||||||
|
|
||||||
@ -278,3 +286,84 @@ impl Packet for ClientBoundKeepAlive {
|
|||||||
Ok(ClientBoundKeepAlive { id })
|
Ok(ClientBoundKeepAlive { id })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ChunkData {
|
||||||
|
pub x: i32,
|
||||||
|
pub z: i32,
|
||||||
|
pub full: bool,
|
||||||
|
pub primary_mask: u32,
|
||||||
|
pub heights: CompoundTag,
|
||||||
|
pub data: Vec<u8>,
|
||||||
|
pub tiles: Vec<CompoundTag>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChunkData {
|
||||||
|
pub fn new(
|
||||||
|
x: i32,
|
||||||
|
z: i32,
|
||||||
|
full: bool,
|
||||||
|
primary_mask: u32,
|
||||||
|
heights: CompoundTag,
|
||||||
|
data: Vec<u8>,
|
||||||
|
tiles: Vec<CompoundTag>,
|
||||||
|
) -> GameClientBoundPacket {
|
||||||
|
let chunk_data = ChunkData {
|
||||||
|
x,
|
||||||
|
z,
|
||||||
|
full,
|
||||||
|
primary_mask,
|
||||||
|
heights,
|
||||||
|
data,
|
||||||
|
tiles,
|
||||||
|
};
|
||||||
|
|
||||||
|
GameClientBoundPacket::ChunkData(chunk_data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Packet for ChunkData {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn encode<W: Write>(&self, writer: &mut W) -> Result<(), EncodeError> {
|
||||||
|
writer.write_i32::<BigEndian>(self.x)?;
|
||||||
|
writer.write_i32::<BigEndian>(self.z)?;
|
||||||
|
writer.write_bool(self.full)?;
|
||||||
|
writer.write_var_u32(self.primary_mask)?;
|
||||||
|
writer.write_compound_tag(&self.heights)?;
|
||||||
|
writer.write_byte_array(&self.data)?;
|
||||||
|
writer.write_var_u32(self.tiles.len() as u32)?;
|
||||||
|
|
||||||
|
for tile_compound_tag in self.tiles.iter() {
|
||||||
|
writer.write_compound_tag(&tile_compound_tag)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decode<R: Read>(reader: &mut R) -> Result<Self::Output, DecodeError> {
|
||||||
|
let x = reader.read_i32::<BigEndian>()?;
|
||||||
|
let z = reader.read_i32::<BigEndian>()?;
|
||||||
|
let full = reader.read_bool()?;
|
||||||
|
let primary_mask = reader.read_var_u32()?;
|
||||||
|
let heights = reader.read_compound_tag()?;
|
||||||
|
let data = reader.read_byte_array()?;
|
||||||
|
|
||||||
|
let tiles_length = reader.read_var_u32()?;
|
||||||
|
let mut tiles = Vec::new();
|
||||||
|
|
||||||
|
for _ in 0..tiles_length {
|
||||||
|
let tile_compound_tag = reader.read_compound_tag()?;
|
||||||
|
tiles.push(tile_compound_tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(ChunkData {
|
||||||
|
x,
|
||||||
|
z,
|
||||||
|
full,
|
||||||
|
primary_mask,
|
||||||
|
heights,
|
||||||
|
data,
|
||||||
|
tiles,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
25
src/lib.rs
25
src/lib.rs
@ -13,6 +13,8 @@ use serde_json::error::Error as JsonError;
|
|||||||
use uuid::parser::ParseError as UuidParseError;
|
use uuid::parser::ParseError as UuidParseError;
|
||||||
|
|
||||||
use crate::chat::Message;
|
use crate::chat::Message;
|
||||||
|
use nbt::decode::TagDecodeError;
|
||||||
|
use nbt::CompoundTag;
|
||||||
use num_traits::{FromPrimitive, ToPrimitive};
|
use num_traits::{FromPrimitive, ToPrimitive};
|
||||||
|
|
||||||
pub mod chat;
|
pub mod chat;
|
||||||
@ -86,6 +88,9 @@ pub enum DecodeError {
|
|||||||
UnknownEnumType {
|
UnknownEnumType {
|
||||||
type_id: u8,
|
type_id: u8,
|
||||||
},
|
},
|
||||||
|
TagDecodeError {
|
||||||
|
tag_decode_error: TagDecodeError,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<IoError> for DecodeError {
|
impl From<IoError> for DecodeError {
|
||||||
@ -112,6 +117,12 @@ impl From<UuidParseError> for DecodeError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<TagDecodeError> for DecodeError {
|
||||||
|
fn from(tag_decode_error: TagDecodeError) -> Self {
|
||||||
|
DecodeError::TagDecodeError { tag_decode_error }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
trait Packet {
|
trait Packet {
|
||||||
type Output;
|
type Output;
|
||||||
|
|
||||||
@ -131,6 +142,8 @@ trait PacketRead {
|
|||||||
fn read_chat_message(&mut self) -> Result<Message, DecodeError>;
|
fn read_chat_message(&mut self) -> Result<Message, DecodeError>;
|
||||||
|
|
||||||
fn read_enum<T: FromPrimitive>(&mut self) -> Result<T, DecodeError>;
|
fn read_enum<T: FromPrimitive>(&mut self) -> Result<T, DecodeError>;
|
||||||
|
|
||||||
|
fn read_compound_tag(&mut self) -> Result<CompoundTag, DecodeError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait adds additional helper methods for `Write` to write protocol data.
|
/// Trait adds additional helper methods for `Write` to write protocol data.
|
||||||
@ -144,6 +157,8 @@ trait PacketWrite {
|
|||||||
fn write_chat_message(&mut self, value: &Message) -> Result<(), EncodeError>;
|
fn write_chat_message(&mut self, value: &Message) -> Result<(), EncodeError>;
|
||||||
|
|
||||||
fn write_enum<T: ToPrimitive>(&mut self, value: &T) -> Result<(), EncodeError>;
|
fn write_enum<T: ToPrimitive>(&mut self, value: &T) -> Result<(), EncodeError>;
|
||||||
|
|
||||||
|
fn write_compound_tag(&mut self, value: &CompoundTag) -> Result<(), EncodeError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read> PacketRead for R {
|
impl<R: Read> PacketRead for R {
|
||||||
@ -190,6 +205,10 @@ impl<R: Read> PacketRead for R {
|
|||||||
|
|
||||||
result.ok_or_else(|| DecodeError::UnknownEnumType { type_id })
|
result.ok_or_else(|| DecodeError::UnknownEnumType { type_id })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_compound_tag(&mut self) -> Result<CompoundTag, DecodeError> {
|
||||||
|
Ok(nbt::decode::read_compound_tag(self)?)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W: Write> PacketWrite for W {
|
impl<W: Write> PacketWrite for W {
|
||||||
@ -233,4 +252,10 @@ impl<W: Write> PacketWrite for W {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn write_compound_tag(&mut self, value: &CompoundTag) -> Result<(), EncodeError> {
|
||||||
|
nbt::encode::write_compound_tag(self, value.clone())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user