Add game chat messages

This commit is contained in:
vagola 2019-12-26 23:35:19 +03:00
parent bc9e6a921f
commit 06eec06800
3 changed files with 136 additions and 0 deletions

View File

@ -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
View 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)
}
}

View File

@ -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 {