From a55d3694d92f0ba9b65d4a99bcc14b4a548d7be9 Mon Sep 17 00:00:00 2001 From: Andy Newjack Date: Thu, 27 Feb 2020 23:58:00 -0400 Subject: [PATCH] players can write and save their own infoboards --- src/entity/character.rs | 25 ++++++++++++++++++++++++- src/ship/character.rs | 11 +++++++++++ src/ship/ship.rs | 16 +++++++++++++++- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/entity/character.rs b/src/entity/character.rs index a1cf2b3..ab84014 100644 --- a/src/entity/character.rs +++ b/src/entity/character.rs @@ -2,7 +2,7 @@ use std::convert::{From, Into, TryFrom, TryInto}; use std::collections::HashMap; use libpso::character::character; -use libpso::packet::ship::{UpdateConfig}; +use libpso::packet::ship::{UpdateConfig, WriteInfoboard}; #[derive(Copy, Clone, Hash, PartialEq, Eq)] pub enum CharacterClass { @@ -224,6 +224,27 @@ impl CharacterConfig { } } +#[derive(Clone)] +pub struct CharacterInfoboard { + board: [u16; 172], +} + +impl CharacterInfoboard { + fn new() -> CharacterInfoboard { + CharacterInfoboard { + board: [0; 172] + } + } + + pub fn as_bytes(&mut self) -> [u16; 172] { + self.board + } + + pub fn update_infoboard(&mut self, new_board: &WriteInfoboard) { + self.board = libpso::utf8_to_utf16_array!(new_board.message, 172); + } +} + #[derive(Clone)] pub struct Character { @@ -240,6 +261,7 @@ pub struct Character { pub appearance: CharacterAppearance, pub techs: CharacterTechniques, pub config: CharacterConfig, + pub info_board: CharacterInfoboard, } impl std::default::Default for Character { @@ -255,6 +277,7 @@ impl std::default::Default for Character { appearance: CharacterAppearance::default(), techs: CharacterTechniques::new(), config: CharacterConfig::new(), + info_board: CharacterInfoboard::new(), } } } diff --git a/src/ship/character.rs b/src/ship/character.rs index b85bc71..7aa71ad 100644 --- a/src/ship/character.rs +++ b/src/ship/character.rs @@ -82,6 +82,7 @@ pub struct FullCharacterBytesBuilder<'a> { inventory: Option<&'a Inventory>, key_config: Option<&'a [u8; 0x16C]>, joystick_config: Option<&'a [u8; 0x38]>, + info_board: Option<&'a [u16; 172]>, } @@ -94,6 +95,7 @@ impl<'a> FullCharacterBytesBuilder<'a> { inventory: None, key_config: None, joystick_config: None, + info_board: None, } } @@ -139,6 +141,13 @@ impl<'a> FullCharacterBytesBuilder<'a> { } } + pub fn info_board(self, info_board: &'a [u16; 172]) -> FullCharacterBytesBuilder<'a> { + FullCharacterBytesBuilder { + info_board: Some(info_board), + ..self + } + } + pub fn build(self) -> character::FullCharacter { let character = self.character.unwrap(); let stats = self.stats.unwrap(); @@ -146,6 +155,7 @@ impl<'a> FullCharacterBytesBuilder<'a> { let inventory = self.inventory.unwrap(); let key_config = self.key_config.unwrap(); let joystick_config = self.joystick_config.unwrap(); + let info_board = self.info_board.unwrap(); character::FullCharacter { character: CharacterBytesBuilder::new() @@ -163,6 +173,7 @@ impl<'a> FullCharacterBytesBuilder<'a> { joystick_config: *joystick_config, ..character::KeyTeamConfig::default() }, + info_board: *info_board, ..character::FullCharacter::default() } } diff --git a/src/ship/ship.rs b/src/ship/ship.rs index b0c6668..dbed40a 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -44,6 +44,7 @@ pub enum RecvShipPacket { CreateRoom(CreateRoom), RoomNameRequest(RoomNameRequest), UpdateConfig(UpdateConfig), + WriteInfoboard(WriteInfoboard), } impl RecvServerPacket for RecvShipPacket { @@ -58,6 +59,7 @@ impl RecvServerPacket for RecvShipPacket { 0xC1 => Ok(RecvShipPacket::CreateRoom(CreateRoom::from_bytes(data)?)), 0x8A => Ok(RecvShipPacket::RoomNameRequest(RoomNameRequest::from_bytes(data)?)), 0x7ED => Ok(RecvShipPacket::UpdateConfig(UpdateConfig::from_bytes(data)?)), + 0xD9 => Ok(RecvShipPacket::WriteInfoboard(WriteInfoboard::from_bytes(data)?)), _ => Err(PacketParseError::WrongPacketForServerType(u16::from_le_bytes([data[2], data[3]]), data.to_vec())) } } @@ -197,12 +199,13 @@ impl ShipServerState { let (level, stats) = self.level_table.get_stats_from_exp(client.character.char_class, client.character.exp); let fc = FullCharacterBytesBuilder::new() - .character(&client.character) + .character(&client.character.clone()) .stats(&stats) .level(level) .inventory(&client.inventory) .key_config(&client.settings.settings.key_config) .joystick_config(&client.settings.settings.joystick_config) + .info_board(&client.character.info_board.as_bytes()) .build(); Ok(vec![ @@ -407,6 +410,13 @@ impl ShipServerState { self.entity_gateway.set_character(&client.character); Box::new(None.into_iter()) } + + fn write_infoboard(&mut self, id: ClientId, new_infoboard: &WriteInfoboard) -> Box + Send> { + let client = self.clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap(); + client.character.info_board.update_infoboard(new_infoboard); + self.entity_gateway.set_character(&client.character); + Box::new(None.into_iter()) + } } @@ -463,6 +473,10 @@ impl ServerState for ShipServerState { RecvShipPacket::UpdateConfig(pkt) => { self.update_config(id, pkt) }, + + RecvShipPacket::WriteInfoboard(pkt) => { + self.write_infoboard(id, pkt) + }, }) }