Add trait to obtain protocol packet ID from packet data

This commit is contained in:
timvisee 2021-11-16 17:56:31 +01:00
parent d26a525c7b
commit 4e6a1f9380
No known key found for this signature in database
GPG Key ID: B8DB720BC383E172
6 changed files with 98 additions and 12 deletions

View File

@ -1,2 +1,19 @@
pub mod v1_14_4; pub mod v1_14_4;
pub mod v1_17_1; pub mod v1_17_1;
/// Trait to obtain packet ID from packet data.
pub trait PacketId {
/// Get protcol packet ID.
fn packet_id(&self) -> u8;
}
#[macro_export]
macro_rules! trait_packet_id (
($type: ident, $id: expr) => (
impl PacketId for $type {
fn packet_id(&self) -> u8 {
$id
}
}
)
);

View File

@ -3,6 +3,7 @@ use crate::decoder::Decoder;
use crate::decoder::DecoderReadExt; use crate::decoder::DecoderReadExt;
use crate::encoder::EncoderWriteExt; use crate::encoder::EncoderWriteExt;
use crate::error::DecodeError; use crate::error::DecodeError;
use crate::{trait_packet_id, version::PacketId};
use byteorder::{ReadBytesExt, WriteBytesExt}; use byteorder::{ReadBytesExt, WriteBytesExt};
use minecraft_protocol_derive::{Decoder, Encoder}; use minecraft_protocol_derive::{Decoder, Encoder};
use nbt::CompoundTag; use nbt::CompoundTag;
@ -732,3 +733,15 @@ mod tests {
assert!(abilities.creative_mode); assert!(abilities.creative_mode);
} }
} }
trait_packet_id!(ServerBoundChatMessage, 0x03);
trait_packet_id!(ServerBoundKeepAlive, 0x0F);
trait_packet_id!(ServerBoundAbilities, 0x19);
trait_packet_id!(ClientBoundChatMessage, 0x0E);
trait_packet_id!(GameDisconnect, 0x1A);
trait_packet_id!(ClientBoundKeepAlive, 0x20);
trait_packet_id!(ChunkData, 0x21);
trait_packet_id!(JoinGame, 0x25);
trait_packet_id!(BossBar, 0x0D);
trait_packet_id!(EntityAction, 0x1B);

View File

@ -1,5 +1,6 @@
use crate::decoder::Decoder; use crate::decoder::Decoder;
use crate::error::DecodeError; use crate::error::DecodeError;
use crate::{trait_packet_id, version::PacketId};
use minecraft_protocol_derive::{Decoder, Encoder}; use minecraft_protocol_derive::{Decoder, Encoder};
use std::io::Read; use std::io::Read;
@ -53,3 +54,5 @@ impl Handshake {
HandshakeServerBoundPacket::Handshake(handshake) HandshakeServerBoundPacket::Handshake(handshake)
} }
} }
trait_packet_id!(Handshake, 0x00);

View File

@ -4,6 +4,7 @@ use uuid::Uuid;
use crate::data::chat::Message; use crate::data::chat::Message;
use crate::decoder::Decoder; use crate::decoder::Decoder;
use crate::error::DecodeError; use crate::error::DecodeError;
use crate::{trait_packet_id, version::PacketId};
use minecraft_protocol_derive::{Decoder, Encoder}; use minecraft_protocol_derive::{Decoder, Encoder};
pub enum LoginServerBoundPacket { pub enum LoginServerBoundPacket {
@ -480,3 +481,13 @@ mod tests {
); );
} }
} }
trait_packet_id!(LoginStart, 0x00);
trait_packet_id!(EncryptionResponse, 0x01);
trait_packet_id!(LoginPluginResponse, 0x02);
trait_packet_id!(LoginDisconnect, 0x00);
trait_packet_id!(EncryptionRequest, 0x01);
trait_packet_id!(LoginSuccess, 0x02);
trait_packet_id!(SetCompression, 0x03);
trait_packet_id!(LoginPluginRequest, 0x04);

View File

@ -1,11 +1,12 @@
use crate::data::server_status::*; use crate::data::server_status::*;
use crate::decoder::Decoder; use crate::decoder::Decoder;
use crate::error::DecodeError; use crate::error::DecodeError;
use crate::{trait_packet_id, version::PacketId};
use minecraft_protocol_derive::{Decoder, Encoder}; use minecraft_protocol_derive::{Decoder, Encoder};
use std::io::Read; use std::io::Read;
pub enum StatusServerBoundPacket { pub enum StatusServerBoundPacket {
StatusRequest, StatusRequest(StatusRequest),
PingRequest(PingRequest), PingRequest(PingRequest),
} }
@ -17,14 +18,14 @@ pub enum StatusClientBoundPacket {
impl StatusServerBoundPacket { impl StatusServerBoundPacket {
pub fn get_type_id(&self) -> u8 { pub fn get_type_id(&self) -> u8 {
match self { match self {
StatusServerBoundPacket::StatusRequest => 0x00, StatusServerBoundPacket::StatusRequest(_) => 0x00,
StatusServerBoundPacket::PingRequest(_) => 0x01, StatusServerBoundPacket::PingRequest(_) => 0x01,
} }
} }
pub fn decode<R: Read>(type_id: u8, reader: &mut R) -> Result<Self, DecodeError> { pub fn decode<R: Read>(type_id: u8, reader: &mut R) -> Result<Self, DecodeError> {
match type_id { match type_id {
0x00 => Ok(StatusServerBoundPacket::StatusRequest), 0x00 => Ok(StatusServerBoundPacket::StatusRequest(StatusRequest {})),
0x01 => { 0x01 => {
let ping_request = PingRequest::decode(reader)?; let ping_request = PingRequest::decode(reader)?;
@ -70,6 +71,15 @@ impl PingResponse {
} }
} }
#[derive(Encoder, Decoder, Debug)]
pub struct StatusRequest {}
impl StatusRequest {
pub fn new() -> StatusServerBoundPacket {
StatusServerBoundPacket::StatusRequest(StatusRequest {})
}
}
#[derive(Encoder, Decoder, Debug)] #[derive(Encoder, Decoder, Debug)]
pub struct StatusResponse { pub struct StatusResponse {
pub server_status: ServerStatus, pub server_status: ServerStatus,
@ -198,3 +208,9 @@ mod tests {
); );
} }
} }
trait_packet_id!(StatusRequest, 0x00);
trait_packet_id!(PingRequest, 0x01);
trait_packet_id!(StatusResponse, 0x00);
trait_packet_id!(PingResponse, 0x01);

View File

@ -1,6 +1,7 @@
use crate::data::chat::Message; use crate::data::chat::Message;
use crate::decoder::Decoder; use crate::decoder::Decoder;
use crate::error::DecodeError; use crate::error::DecodeError;
use crate::{trait_packet_id, version::PacketId};
use minecraft_protocol_derive::Decoder; use minecraft_protocol_derive::Decoder;
use minecraft_protocol_derive::Encoder; use minecraft_protocol_derive::Encoder;
use nbt::CompoundTag; use nbt::CompoundTag;
@ -14,7 +15,7 @@ pub use super::super::v1_14_4::game::{
pub enum GameServerBoundPacket { pub enum GameServerBoundPacket {
ServerBoundChatMessage(ServerBoundChatMessage), ServerBoundChatMessage(ServerBoundChatMessage),
PluginMessage(PluginMessage), ServerBoundPluginMessage(ServerBoundPluginMessage),
ServerBoundKeepAlive(ServerBoundKeepAlive), ServerBoundKeepAlive(ServerBoundKeepAlive),
ServerBoundAbilities(ServerBoundAbilities), ServerBoundAbilities(ServerBoundAbilities),
} }
@ -28,7 +29,7 @@ pub enum GameClientBoundPacket {
BossBar(BossBar), BossBar(BossBar),
EntityAction(EntityAction), EntityAction(EntityAction),
PluginMessage(PluginMessage), ClientBoundPluginMessage(ClientBoundPluginMessage),
NamedSoundEffect(NamedSoundEffect), NamedSoundEffect(NamedSoundEffect),
Respawn(Respawn), Respawn(Respawn),
PlayerPositionAndLook(PlayerPositionAndLook), PlayerPositionAndLook(PlayerPositionAndLook),
@ -43,7 +44,7 @@ impl GameServerBoundPacket {
pub fn get_type_id(&self) -> u8 { pub fn get_type_id(&self) -> u8 {
match self { match self {
GameServerBoundPacket::ServerBoundChatMessage(_) => 0x03, GameServerBoundPacket::ServerBoundChatMessage(_) => 0x03,
GameServerBoundPacket::PluginMessage(_) => 0x0A, GameServerBoundPacket::ServerBoundPluginMessage(_) => 0x0A,
GameServerBoundPacket::ServerBoundKeepAlive(_) => 0x0F, GameServerBoundPacket::ServerBoundKeepAlive(_) => 0x0F,
GameServerBoundPacket::ServerBoundAbilities(_) => 0x19, GameServerBoundPacket::ServerBoundAbilities(_) => 0x19,
} }
@ -57,9 +58,11 @@ impl GameServerBoundPacket {
Ok(GameServerBoundPacket::ServerBoundChatMessage(chat_message)) Ok(GameServerBoundPacket::ServerBoundChatMessage(chat_message))
} }
0x0A => { 0x0A => {
let plugin_message = PluginMessage::decode(reader)?; let plugin_message = ServerBoundPluginMessage::decode(reader)?;
Ok(GameServerBoundPacket::PluginMessage(plugin_message)) Ok(GameServerBoundPacket::ServerBoundPluginMessage(
plugin_message,
))
} }
0x0F => { 0x0F => {
let keep_alive = ServerBoundKeepAlive::decode(reader)?; let keep_alive = ServerBoundKeepAlive::decode(reader)?;
@ -80,7 +83,7 @@ impl GameClientBoundPacket {
pub fn get_type_id(&self) -> u8 { pub fn get_type_id(&self) -> u8 {
match self { match self {
GameClientBoundPacket::ClientBoundChatMessage(_) => 0x0E, GameClientBoundPacket::ClientBoundChatMessage(_) => 0x0E,
GameClientBoundPacket::PluginMessage(_) => 0x18, GameClientBoundPacket::ClientBoundPluginMessage(_) => 0x18,
GameClientBoundPacket::NamedSoundEffect(_) => 0x19, GameClientBoundPacket::NamedSoundEffect(_) => 0x19,
GameClientBoundPacket::GameDisconnect(_) => 0x1A, GameClientBoundPacket::GameDisconnect(_) => 0x1A,
GameClientBoundPacket::ClientBoundKeepAlive(_) => 0x20, GameClientBoundPacket::ClientBoundKeepAlive(_) => 0x20,
@ -106,9 +109,11 @@ impl GameClientBoundPacket {
Ok(GameClientBoundPacket::ClientBoundChatMessage(chat_message)) Ok(GameClientBoundPacket::ClientBoundChatMessage(chat_message))
} }
0x18 => { 0x18 => {
let plugin_message = PluginMessage::decode(reader)?; let plugin_message = ClientBoundPluginMessage::decode(reader)?;
Ok(GameClientBoundPacket::PluginMessage(plugin_message)) Ok(GameClientBoundPacket::ClientBoundPluginMessage(
plugin_message,
))
} }
0x19 => { 0x19 => {
let named_sound_effect = NamedSoundEffect::decode(reader)?; let named_sound_effect = NamedSoundEffect::decode(reader)?;
@ -179,7 +184,15 @@ impl GameClientBoundPacket {
// TODO(timvisee): implement new() // TODO(timvisee): implement new()
#[derive(Encoder, Decoder, Debug)] #[derive(Encoder, Decoder, Debug)]
pub struct PluginMessage { pub struct ServerBoundPluginMessage {
#[data_type(max_length = 32767)]
pub channel: String,
pub data: Vec<u8>,
}
// TODO(timvisee): implement new()
#[derive(Encoder, Decoder, Debug)]
pub struct ClientBoundPluginMessage {
#[data_type(max_length = 32767)] #[data_type(max_length = 32767)]
pub channel: String, pub channel: String,
pub data: Vec<u8>, pub data: Vec<u8>,
@ -285,3 +298,16 @@ pub struct SpawnPosition {
pub position: u64, pub position: u64,
pub angle: f32, pub angle: f32,
} }
trait_packet_id!(ServerBoundPluginMessage, 0x0A);
trait_packet_id!(ClientBoundPluginMessage, 0x18);
trait_packet_id!(NamedSoundEffect, 0x19);
trait_packet_id!(JoinGame, 0x25);
trait_packet_id!(PlayerPositionAndLook, 0x38);
trait_packet_id!(Respawn, 0x3D);
trait_packet_id!(SpawnPosition, 0x4B);
trait_packet_id!(SetTitleSubtitle, 0x57);
trait_packet_id!(TimeUpdate, 0x58);
trait_packet_id!(SetTitleText, 0x59);
trait_packet_id!(SetTitleTimes, 0x5A);