use crate::mc_buf::{McBufReadable, McBufWritable, Readable, Writable}; use azalea_chat::component::Component; use packet_macros::{GamePacket, McBuf}; use std::io::{Read, Write}; use uuid::Uuid; #[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundPlayerInfoPacket { pub action: Action, } #[derive(Clone, Debug)] pub enum Action { AddPlayer(Vec), UpdateGameMode(Vec), UpdateLatency(Vec), UpdateDisplayName(Vec), RemovePlayer(Vec), } #[derive(Clone, Debug, McBuf)] pub struct PlayerProperty { name: String, value: String, signature: Option, } #[derive(Clone, Debug, McBuf)] pub struct AddPlayer { uuid: Uuid, name: String, properties: Vec, #[var] gamemode: u32, #[var] ping: i32, display_name: Option, } #[derive(Clone, Debug, McBuf)] pub struct UpdateGameMode { uuid: Uuid, #[var] gamemode: u32, } #[derive(Clone, Debug, McBuf)] pub struct UpdateLatency { uuid: Uuid, #[var] ping: i32, } #[derive(Clone, Debug, McBuf)] pub struct UpdateDisplayName { uuid: Uuid, display_name: Option, } #[derive(Clone, Debug, McBuf)] pub struct RemovePlayer { uuid: Uuid, } impl McBufReadable for Action { fn read_into(buf: &mut impl Read) -> Result { let id = buf.read_byte()?; Ok(match id { 0 => Action::AddPlayer(Vec::::read_into(buf)?), 1 => Action::UpdateGameMode(Vec::::read_into(buf)?), 2 => Action::UpdateLatency(Vec::::read_into(buf)?), 3 => Action::UpdateDisplayName(Vec::::read_into(buf)?), 4 => Action::RemovePlayer(Vec::::read_into(buf)?), _ => panic!("Unknown player info action id: {}", id), }) } } impl McBufWritable for Action { fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_byte(match self { Action::AddPlayer(_) => 0, Action::UpdateGameMode(_) => 1, Action::UpdateLatency(_) => 2, Action::UpdateDisplayName(_) => 3, Action::RemovePlayer(_) => 4, })?; match self { Action::AddPlayer(players) => players.write_into(buf)?, Action::UpdateGameMode(players) => players.write_into(buf)?, Action::UpdateLatency(players) => players.write_into(buf)?, Action::UpdateDisplayName(players) => players.write_into(buf)?, Action::RemovePlayer(players) => players.write_into(buf)?, } Ok(()) } }