Add game chat messages
This commit is contained in:
parent
bc9e6a921f
commit
06eec06800
@ -16,3 +16,5 @@ serde = { version = "1.0", features = ["derive"] }
|
|||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
uuid = { version = "0.7", features = ["v4", "serde"] }
|
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-derive = "0.2"
|
||||||
|
129
src/game.rs
Normal file
129
src/game.rs
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
|
use byteorder::{ReadBytesExt, WriteBytesExt};
|
||||||
|
use num_derive::{FromPrimitive, ToPrimitive};
|
||||||
|
use num_traits::FromPrimitive;
|
||||||
|
use num_traits::ToPrimitive;
|
||||||
|
|
||||||
|
use crate::chat::Message;
|
||||||
|
use crate::{DecodeError, EncodeError, Packet, PacketRead, PacketWrite};
|
||||||
|
|
||||||
|
const SERVER_BOUND_CHAT_MESSAGE_MAX_LENGTH: u32 = 256;
|
||||||
|
|
||||||
|
pub enum GameServerBoundPacket {
|
||||||
|
ServerBoundChatMessage(ServerBoundChatMessage),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum GameClientBoundPacket {
|
||||||
|
ClientBoundChatMessage(ClientBoundChatMessage),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GameServerBoundPacket {
|
||||||
|
pub fn get_type_id(&self) -> u8 {
|
||||||
|
match self {
|
||||||
|
GameServerBoundPacket::ServerBoundChatMessage(_) => 0x03,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decode<R: Read>(type_id: u8, reader: &mut R) -> Result<Self, DecodeError> {
|
||||||
|
match type_id {
|
||||||
|
0x03 => {
|
||||||
|
let chat_message = ServerBoundChatMessage::decode(reader)?;
|
||||||
|
|
||||||
|
Ok(GameServerBoundPacket::ServerBoundChatMessage(chat_message))
|
||||||
|
}
|
||||||
|
_ => Err(DecodeError::UnknownPacketType { type_id }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GameClientBoundPacket {
|
||||||
|
pub fn get_type_id(&self) -> u8 {
|
||||||
|
match self {
|
||||||
|
GameClientBoundPacket::ClientBoundChatMessage(_) => 0x0E,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decode<R: Read>(type_id: u8, reader: &mut R) -> Result<Self, DecodeError> {
|
||||||
|
match type_id {
|
||||||
|
0x0E => {
|
||||||
|
let chat_message = ClientBoundChatMessage::decode(reader)?;
|
||||||
|
|
||||||
|
Ok(GameClientBoundPacket::ClientBoundChatMessage(chat_message))
|
||||||
|
}
|
||||||
|
_ => Err(DecodeError::UnknownPacketType { type_id }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ServerBoundChatMessage {
|
||||||
|
pub message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ServerBoundChatMessage {
|
||||||
|
pub fn new(message: String) -> GameServerBoundPacket {
|
||||||
|
let chat_message = ServerBoundChatMessage { message };
|
||||||
|
|
||||||
|
GameServerBoundPacket::ServerBoundChatMessage(chat_message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Packet for ServerBoundChatMessage {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn encode<W: Write>(&self, writer: &mut W) -> Result<(), EncodeError> {
|
||||||
|
writer.write_string(&self.message, SERVER_BOUND_CHAT_MESSAGE_MAX_LENGTH)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decode<R: Read>(reader: &mut R) -> Result<Self::Output, DecodeError> {
|
||||||
|
let message = reader.read_string(SERVER_BOUND_CHAT_MESSAGE_MAX_LENGTH)?;
|
||||||
|
|
||||||
|
Ok(ServerBoundChatMessage { message })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ClientBoundChatMessage {
|
||||||
|
pub message: Message,
|
||||||
|
pub position: MessagePosition,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, FromPrimitive, ToPrimitive)]
|
||||||
|
pub enum MessagePosition {
|
||||||
|
Chat,
|
||||||
|
System,
|
||||||
|
HotBar,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ClientBoundChatMessage {
|
||||||
|
pub fn new(message: Message, position: MessagePosition) -> GameClientBoundPacket {
|
||||||
|
let chat_message = ClientBoundChatMessage { message, position };
|
||||||
|
|
||||||
|
GameClientBoundPacket::ClientBoundChatMessage(chat_message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Packet for ClientBoundChatMessage {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn encode<W: Write>(&self, writer: &mut W) -> Result<(), EncodeError> {
|
||||||
|
writer.write_chat_message(&self.message)?;
|
||||||
|
writer.write_u8(ToPrimitive::to_u8(&self.position).unwrap())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decode<R: Read>(reader: &mut R) -> Result<Self::Output, DecodeError> {
|
||||||
|
let message = reader.read_chat_message()?;
|
||||||
|
let position_type_id = reader.read_u8()?;
|
||||||
|
|
||||||
|
let position = FromPrimitive::from_u8(position_type_id).ok_or_else(|| {
|
||||||
|
DecodeError::UnknownEnumType {
|
||||||
|
type_id: position_type_id,
|
||||||
|
}
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let chat_message = ClientBoundChatMessage { message, position };
|
||||||
|
|
||||||
|
Ok(chat_message)
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,7 @@ use uuid::parser::ParseError as UuidParseError;
|
|||||||
use crate::chat::Message;
|
use crate::chat::Message;
|
||||||
|
|
||||||
pub mod chat;
|
pub mod chat;
|
||||||
|
pub mod game;
|
||||||
pub mod login;
|
pub mod login;
|
||||||
pub mod status;
|
pub mod status;
|
||||||
|
|
||||||
@ -80,6 +81,10 @@ pub enum DecodeError {
|
|||||||
UuidParseError {
|
UuidParseError {
|
||||||
uuid_parse_error: UuidParseError,
|
uuid_parse_error: UuidParseError,
|
||||||
},
|
},
|
||||||
|
// Type id was not parsed as valid enum value.
|
||||||
|
UnknownEnumType {
|
||||||
|
type_id: u8,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<IoError> for DecodeError {
|
impl From<IoError> for DecodeError {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user