From a55d3694d92f0ba9b65d4a99bcc14b4a548d7be9 Mon Sep 17 00:00:00 2001 From: Andy Newjack Date: Thu, 27 Feb 2020 23:58:00 -0400 Subject: [PATCH 1/3] 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) + }, }) } From 37b892f5dc5f07c5cf74d345abad4d58ddd6c165 Mon Sep 17 00:00:00 2001 From: Andy Newjack Date: Sun, 1 Mar 2020 02:57:18 -0400 Subject: [PATCH 2/3] view info board --- src/entity/character.rs | 2 +- src/ship/character.rs | 11 +---------- src/ship/ship.rs | 34 ++++++++++++++++++++++++++++++++-- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/entity/character.rs b/src/entity/character.rs index ab84014..2436d13 100644 --- a/src/entity/character.rs +++ b/src/entity/character.rs @@ -236,7 +236,7 @@ impl CharacterInfoboard { } } - pub fn as_bytes(&mut self) -> [u16; 172] { + pub fn as_bytes(&self) -> [u16; 172] { self.board } diff --git a/src/ship/character.rs b/src/ship/character.rs index 7aa71ad..f6334bc 100644 --- a/src/ship/character.rs +++ b/src/ship/character.rs @@ -82,7 +82,6 @@ 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]>, } @@ -95,7 +94,6 @@ impl<'a> FullCharacterBytesBuilder<'a> { inventory: None, key_config: None, joystick_config: None, - info_board: None, } } @@ -141,12 +139,6 @@ 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(); @@ -155,7 +147,6 @@ 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() @@ -173,7 +164,7 @@ impl<'a> FullCharacterBytesBuilder<'a> { joystick_config: *joystick_config, ..character::KeyTeamConfig::default() }, - info_board: *info_board, + info_board: character.info_board.as_bytes(), ..character::FullCharacter::default() } } diff --git a/src/ship/ship.rs b/src/ship/ship.rs index dbed40a..29069dc 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -44,6 +44,7 @@ pub enum RecvShipPacket { CreateRoom(CreateRoom), RoomNameRequest(RoomNameRequest), UpdateConfig(UpdateConfig), + ViewInfoboardRequest(ViewInfoboardRequest), WriteInfoboard(WriteInfoboard), } @@ -59,6 +60,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)?)), + 0xD8 => Ok(RecvShipPacket::ViewInfoboardRequest(ViewInfoboardRequest::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())) } @@ -83,6 +85,7 @@ pub enum SendShipPacket { LeaveLobby(LeaveLobby), LeaveRoom(LeaveRoom), RoomNameResponse(RoomNameResponse), + ViewInfoboardResponse(ViewInfoboardResponse), } impl SendServerPacket for SendShipPacket { @@ -104,6 +107,7 @@ impl SendServerPacket for SendShipPacket { SendShipPacket::LeaveLobby(pkt) => pkt.as_bytes(), SendShipPacket::LeaveRoom(pkt) => pkt.as_bytes(), SendShipPacket::RoomNameResponse(pkt) => pkt.as_bytes(), + SendShipPacket::ViewInfoboardResponse(pkt) => pkt.as_bytes(), } } } @@ -199,13 +203,12 @@ 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.clone()) + .character(&client.character) .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![ @@ -411,6 +414,29 @@ impl ShipServerState { Box::new(None.into_iter()) } + fn request_infoboard(&mut self, id: ClientId, request_infoboard: &ViewInfoboardRequest) -> Box + Send> { + let lobby = self.client_location.get_area_by_user(id); + let clients = lobby.clients(); + let r = clients + .iter() + .filter(|c| c.client_id != id) + .filter_map(|c| { + self.clients.get(&c.client_id) + }) + .map(|c| { + InfoboardResponse { + name: libpso::utf8_to_utf16_array!(c.character.name, 16), + message: c.character.info_board.as_bytes(), + } + }) + .collect(); + + // Box::new(vec![(id, ViewInfoboardResponse { + // response: r + // }].into_iter()) + Box::new(vec![(id, SendShipPacket::ViewInfoboardResponse(ViewInfoboardResponse {response: r}))].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); @@ -474,6 +500,10 @@ impl ServerState for ShipServerState { self.update_config(id, pkt) }, + RecvShipPacket::ViewInfoboardRequest(pkt) => { + self.request_infoboard(id, pkt) + }, + RecvShipPacket::WriteInfoboard(pkt) => { self.write_infoboard(id, pkt) }, From ef90220c0c7d033500d3c82bcdee33b4bd0096b7 Mon Sep 17 00:00:00 2001 From: Andy Newjack Date: Sun, 1 Mar 2020 03:00:28 -0400 Subject: [PATCH 3/3] remove comments --- src/ship/ship.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 29069dc..ced4ba0 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -430,10 +430,6 @@ impl ShipServerState { } }) .collect(); - - // Box::new(vec![(id, ViewInfoboardResponse { - // response: r - // }].into_iter()) Box::new(vec![(id, SendShipPacket::ViewInfoboardResponse(ViewInfoboardResponse {response: r}))].into_iter()) }