use crate::{ util::pack::{ pack_u64, unpack_u64, }, protocol::*, }; use super::Packet; #[derive(Clone, Copy)] pub enum GameMessageData { Error, PlayMove(u16, u8, u8), PlayDrop(u16, u8, u8), PlayAlt(u16, u8, u8), Online(u8, u32), Undo(u16, u8), Resign, Reaction(u16), } #[derive(Clone)] pub struct PacketGameMessage { pub data:GameMessageData, } impl PacketGameMessage { pub fn new() -> Self { Self { data:GameMessageData::Error, } } } impl Packet for PacketGameMessage { type Data = Self; fn decode(data:&Vec, index:&mut usize) -> Result { let mut result = Self::new(); if data.len() - *index >= 8 { let data = unpack_u64(data, index); result.data = match (data & 0xFF) as u8 { GMSG_PLAY_MOVE => GameMessageData::PlayMove( ((data >> 8) & 0xFFFF) as u16, ((data >> 24) & 0x3F) as u8, ((data >> 30) & 0x3F) as u8, ), GMSG_PLAY_DROP => GameMessageData::PlayDrop( ((data >> 8) & 0xFFFF) as u16, ((data >> 24) & 0x3F) as u8, ((data >> 30) & 0x3F) as u8, ), GMSG_PLAY_ALT => GameMessageData::PlayAlt( ((data >> 8) & 0xFFFF) as u16, ((data >> 24) & 0x3F) as u8, ((data >> 30) & 0x3F) as u8, ), GMSG_UNDO => GameMessageData::Undo( ((data >> 8) & 0xFFFF) as u16, ((data >> 24) & 0x1) as u8, ), GMSG_RETIRE => GameMessageData::Resign, GMSG_REACTION => GameMessageData::Reaction( ((data >> 8) & 0xFFFF) as u16, ), _ => GameMessageData::Error, } } Ok(result) } fn encode(&self) -> Vec { pack_u64(match self.data { GameMessageData::PlayMove(turn, from, to) => { GMSG_PLAY_MOVE as u64 | ((turn as u64) << 8) | ((from as u64) << 24) | ((to as u64) << 30) } GameMessageData::PlayDrop(turn, piece, to) => { GMSG_PLAY_DROP as u64 | ((turn as u64) << 8) | ((piece as u64) << 24) | ((to as u64) << 30) } GameMessageData::PlayAlt(turn, from, to) => { GMSG_PLAY_ALT as u64 | ((turn as u64) << 8) | ((from as u64) << 24) | ((to as u64) << 30) } GameMessageData::Online(client, state) => { GMSG_ONLINE as u64 | ((client as u64) << 8) | ((state as u64) << 10) } GameMessageData::Undo(turn, state) => { GMSG_UNDO as u64 | ((turn as u64) << 8) | ((state as u64) << 24) } GameMessageData::Resign => { GMSG_RETIRE as u64 } GameMessageData::Reaction(index) => { GMSG_REACTION as u64 | ((index as u64) << 8) } _ => { 0 } }) } }