use psopacket::pso_packet; use crate::{PSOPacket, PacketParseError, PSOPacketData}; use crate::utf8_to_utf16_array; use std::io::Read; const BLOCK_MENU_ID: u32 = 1; #[pso_packet(0x03)] pub struct ShipWelcome { #[utf8] copyright: [u8; 0x60], server_key: [u8; 48], client_key: [u8; 48], } impl ShipWelcome { pub fn new(server_key: [u8; 48], client_key: [u8; 48]) -> ShipWelcome { let mut copyright = [0u8; 0x60]; copyright[..0x4B].clone_from_slice(b"Phantasy Star Online Blue Burst Game Server. Copyright 1999-2004 SONICTEAM."); ShipWelcome { copyright: copyright, server_key: server_key, client_key: client_key, } } } #[derive(Debug, PartialEq, Clone)] pub struct BlockEntry { menu: u32, item: u32, flags: u16, name: [u16; 0x11], } impl PSOPacketData for BlockEntry { fn from_bytes<R: Read>(_cursor: &mut R) -> Result<Self, PacketParseError> { unimplemented!(); } fn as_bytes(&self) -> Vec<u8> { let mut bytes = Vec::new(); bytes.extend_from_slice(&u32::to_le_bytes(self.menu)); bytes.extend_from_slice(&u32::to_le_bytes(self.item)); bytes.extend_from_slice(&u16::to_le_bytes(self.flags)); bytes.extend_from_slice(&unsafe { std::mem::transmute::<[u16; 0x11], [u8; 0x11*2]>(self.name) }); bytes } } #[pso_packet(0xA1)] pub struct ShipBlockList { shipblock: BlockEntry, blocks: Vec<BlockEntry> } impl ShipBlockList { pub fn new(num_blocks: usize) -> ShipBlockList { ShipBlockList { shipblock: BlockEntry { menu: BLOCK_MENU_ID, item: 0, flags: 0, name: utf8_to_utf16_array!("Shipname", 0x11) }, blocks: (0..num_blocks).map(|i| BlockEntry { menu: BLOCK_MENU_ID, item: i as u32 + 1, flags: 0, name: utf8_to_utf16_array!(format!("Block {}", i+1), 0x11) }).collect() } } }