From 62e5a966f63d48cdf8b75e27156afa4352023629 Mon Sep 17 00:00:00 2001 From: andy Date: Fri, 2 Oct 2020 21:24:32 -0300 Subject: [PATCH 1/4] options saved to character! --- src/entity/character.rs | 3 +++ src/entity/gateway/inmemory.rs | 1 + src/ship/character.rs | 11 +++++++++++ src/ship/packet/handler/lobby.rs | 1 + src/ship/packet/handler/settings.rs | 12 ++++++++++++ src/ship/ship.rs | 5 +++++ 6 files changed, 33 insertions(+) diff --git a/src/entity/character.rs b/src/entity/character.rs index 4fc6383..3c4d87a 100644 --- a/src/entity/character.rs +++ b/src/entity/character.rs @@ -260,6 +260,7 @@ pub struct NewCharacterEntity { pub tech_menu: CharacterTechMenu, pub meseta: u32, pub bank_meseta: u32, + pub option_flags: u32, } impl NewCharacterEntity { @@ -280,6 +281,7 @@ impl NewCharacterEntity { tech_menu: CharacterTechMenu::new(), meseta: 0, bank_meseta: 0, + option_flags: 0, } } } @@ -307,4 +309,5 @@ pub struct CharacterEntity { pub meseta: u32, // TODO: this should not be tied to the character pub bank_meseta: u32, + pub option_flags: u32, } diff --git a/src/entity/gateway/inmemory.rs b/src/entity/gateway/inmemory.rs index 5620cb6..56da621 100644 --- a/src/entity/gateway/inmemory.rs +++ b/src/entity/gateway/inmemory.rs @@ -127,6 +127,7 @@ impl EntityGateway for InMemoryGateway { tech_menu: character.tech_menu, meseta: character.meseta, bank_meseta: character.bank_meseta, + option_flags: character.option_flags, }; characters.insert(new_character.id, new_character.clone()); Some(new_character) diff --git a/src/ship/character.rs b/src/ship/character.rs index c22af29..efbe494 100644 --- a/src/ship/character.rs +++ b/src/ship/character.rs @@ -86,6 +86,7 @@ pub struct FullCharacterBytesBuilder<'a> { joystick_config: Option<&'a [u8; 0x38]>, symbol_chat: Option<&'a [u8; 1248]>, tech_menu: Option<&'a [u8; 40]>, + option_flags: Option, } @@ -101,6 +102,7 @@ impl<'a> FullCharacterBytesBuilder<'a> { joystick_config: None, symbol_chat: None, tech_menu: None, + option_flags: None, } } @@ -167,6 +169,13 @@ impl<'a> FullCharacterBytesBuilder<'a> { } } + pub fn option_flags(self, option_flags: u32) -> FullCharacterBytesBuilder<'a> { + FullCharacterBytesBuilder { + option_flags: Some(option_flags), + ..self + } + } + pub fn build(self) -> character::FullCharacter { let character = self.character.unwrap(); let stats = self.stats.unwrap(); @@ -177,6 +186,7 @@ impl<'a> FullCharacterBytesBuilder<'a> { let joystick_config = self.joystick_config.unwrap(); let symbol_chat = self.symbol_chat.unwrap(); let tech_menu = self.tech_menu.unwrap(); + let option_flags = self.option_flags.unwrap(); let mut inventory_items = inventory.as_client_inventory_items(); inventory_items[7].material_count = character.materials.power as u8; @@ -207,6 +217,7 @@ impl<'a> FullCharacterBytesBuilder<'a> { symbol_chats: *symbol_chat, tech_menu: *tech_menu, bank: bank.as_client_bank_items(), + option_flags: option_flags, ..character::FullCharacter::default() } } diff --git a/src/ship/packet/handler/lobby.rs b/src/ship/packet/handler/lobby.rs index 2112133..55ecc3f 100644 --- a/src/ship/packet/handler/lobby.rs +++ b/src/ship/packet/handler/lobby.rs @@ -34,6 +34,7 @@ pub fn block_selected(id: ClientId, .joystick_config(&client.settings.settings.joystick_config) .symbol_chat(&client.settings.settings.symbol_chats) .tech_menu(&client.character.tech_menu.as_bytes()) + .option_flags(client.character.option_flags) .build(); Ok(vec![ diff --git a/src/ship/packet/handler/settings.rs b/src/ship/packet/handler/settings.rs index 109c26b..26b632d 100644 --- a/src/ship/packet/handler/settings.rs +++ b/src/ship/packet/handler/settings.rs @@ -13,3 +13,15 @@ pub async fn update_config(id: ClientId, entity_gateway.save_character(&client.character).await; Box::new(None.into_iter()) } + +pub async fn save_options(id: ClientId, + save_options: &SaveOptions, + clients: &mut Clients, + entity_gateway: &mut EG) + -> Box + Send> { + // // TODO: don't unwrap? + let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap(); + client.character.option_flags = save_options.options; + entity_gateway.save_character(&client.character).await; + Box::new(None.into_iter()) +} \ No newline at end of file diff --git a/src/ship/ship.rs b/src/ship/ship.rs index e654bc3..0055d2e 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -91,6 +91,7 @@ pub enum RecvShipPacket { QuestFileRequest(QuestFileRequest), QuestChunkAck(QuestChunkAck), DoneLoadingQuest(DoneLoadingQuest), + SaveOptions(SaveOptions), } impl RecvServerPacket for RecvShipPacket { @@ -126,6 +127,7 @@ impl RecvServerPacket for RecvShipPacket { 0x84 => Ok(RecvShipPacket::LobbySelect(LobbySelect::from_bytes(data)?)), 0xA2 => Ok(RecvShipPacket::RequestQuestList(RequestQuestList::from_bytes(data)?)), 0xAC => Ok(RecvShipPacket::DoneLoadingQuest(DoneLoadingQuest::from_bytes(data)?)), + 0x1ED => Ok(RecvShipPacket::SaveOptions(SaveOptions::from_bytes(data)?)), _ => Err(PacketParseError::WrongPacketForServerType(u16::from_le_bytes([data[2], data[3]]), data.to_vec())) } } @@ -556,6 +558,9 @@ impl ServerState for ShipServerState { RecvShipPacket::DoneLoadingQuest(_) => { handler::quest::done_loading_quest(id, &mut self.clients, &self.client_location)? }, + RecvShipPacket::SaveOptions(save_options) => { + handler::settings::save_options(id, save_options, &mut self.clients, &mut self.entity_gateway).await + }, }) } From db23a9794eb6c47ecec1df3b44c9b0c160c39210 Mon Sep 17 00:00:00 2001 From: andy Date: Fri, 2 Oct 2020 21:24:32 -0300 Subject: [PATCH 2/4] options saved to character! --- src/entity/character.rs | 3 +++ src/entity/gateway/inmemory.rs | 1 + src/ship/character.rs | 11 +++++++++++ src/ship/packet/handler/lobby.rs | 1 + src/ship/packet/handler/settings.rs | 12 ++++++++++++ src/ship/ship.rs | 5 +++++ 6 files changed, 33 insertions(+) diff --git a/src/entity/character.rs b/src/entity/character.rs index 4fc6383..3c4d87a 100644 --- a/src/entity/character.rs +++ b/src/entity/character.rs @@ -260,6 +260,7 @@ pub struct NewCharacterEntity { pub tech_menu: CharacterTechMenu, pub meseta: u32, pub bank_meseta: u32, + pub option_flags: u32, } impl NewCharacterEntity { @@ -280,6 +281,7 @@ impl NewCharacterEntity { tech_menu: CharacterTechMenu::new(), meseta: 0, bank_meseta: 0, + option_flags: 0, } } } @@ -307,4 +309,5 @@ pub struct CharacterEntity { pub meseta: u32, // TODO: this should not be tied to the character pub bank_meseta: u32, + pub option_flags: u32, } diff --git a/src/entity/gateway/inmemory.rs b/src/entity/gateway/inmemory.rs index 5620cb6..56da621 100644 --- a/src/entity/gateway/inmemory.rs +++ b/src/entity/gateway/inmemory.rs @@ -127,6 +127,7 @@ impl EntityGateway for InMemoryGateway { tech_menu: character.tech_menu, meseta: character.meseta, bank_meseta: character.bank_meseta, + option_flags: character.option_flags, }; characters.insert(new_character.id, new_character.clone()); Some(new_character) diff --git a/src/ship/character.rs b/src/ship/character.rs index c22af29..efbe494 100644 --- a/src/ship/character.rs +++ b/src/ship/character.rs @@ -86,6 +86,7 @@ pub struct FullCharacterBytesBuilder<'a> { joystick_config: Option<&'a [u8; 0x38]>, symbol_chat: Option<&'a [u8; 1248]>, tech_menu: Option<&'a [u8; 40]>, + option_flags: Option, } @@ -101,6 +102,7 @@ impl<'a> FullCharacterBytesBuilder<'a> { joystick_config: None, symbol_chat: None, tech_menu: None, + option_flags: None, } } @@ -167,6 +169,13 @@ impl<'a> FullCharacterBytesBuilder<'a> { } } + pub fn option_flags(self, option_flags: u32) -> FullCharacterBytesBuilder<'a> { + FullCharacterBytesBuilder { + option_flags: Some(option_flags), + ..self + } + } + pub fn build(self) -> character::FullCharacter { let character = self.character.unwrap(); let stats = self.stats.unwrap(); @@ -177,6 +186,7 @@ impl<'a> FullCharacterBytesBuilder<'a> { let joystick_config = self.joystick_config.unwrap(); let symbol_chat = self.symbol_chat.unwrap(); let tech_menu = self.tech_menu.unwrap(); + let option_flags = self.option_flags.unwrap(); let mut inventory_items = inventory.as_client_inventory_items(); inventory_items[7].material_count = character.materials.power as u8; @@ -207,6 +217,7 @@ impl<'a> FullCharacterBytesBuilder<'a> { symbol_chats: *symbol_chat, tech_menu: *tech_menu, bank: bank.as_client_bank_items(), + option_flags: option_flags, ..character::FullCharacter::default() } } diff --git a/src/ship/packet/handler/lobby.rs b/src/ship/packet/handler/lobby.rs index 2112133..55ecc3f 100644 --- a/src/ship/packet/handler/lobby.rs +++ b/src/ship/packet/handler/lobby.rs @@ -34,6 +34,7 @@ pub fn block_selected(id: ClientId, .joystick_config(&client.settings.settings.joystick_config) .symbol_chat(&client.settings.settings.symbol_chats) .tech_menu(&client.character.tech_menu.as_bytes()) + .option_flags(client.character.option_flags) .build(); Ok(vec![ diff --git a/src/ship/packet/handler/settings.rs b/src/ship/packet/handler/settings.rs index 109c26b..26b632d 100644 --- a/src/ship/packet/handler/settings.rs +++ b/src/ship/packet/handler/settings.rs @@ -13,3 +13,15 @@ pub async fn update_config(id: ClientId, entity_gateway.save_character(&client.character).await; Box::new(None.into_iter()) } + +pub async fn save_options(id: ClientId, + save_options: &SaveOptions, + clients: &mut Clients, + entity_gateway: &mut EG) + -> Box + Send> { + // // TODO: don't unwrap? + let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap(); + client.character.option_flags = save_options.options; + entity_gateway.save_character(&client.character).await; + Box::new(None.into_iter()) +} \ No newline at end of file diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 7fb960a..5d314d5 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -92,6 +92,7 @@ pub enum RecvShipPacket { QuestChunkAck(QuestChunkAck), DoneLoadingQuest(DoneLoadingQuest), FullCharacterData(Box), + SaveOptions(SaveOptions), } impl RecvServerPacket for RecvShipPacket { @@ -128,6 +129,7 @@ impl RecvServerPacket for RecvShipPacket { 0xA2 => Ok(RecvShipPacket::RequestQuestList(RequestQuestList::from_bytes(data)?)), 0xAC => Ok(RecvShipPacket::DoneLoadingQuest(DoneLoadingQuest::from_bytes(data)?)), 0xE7 => Ok(RecvShipPacket::FullCharacterData(Box::new(FullCharacterData::from_bytes(data)?))), + 0x1ED => Ok(RecvShipPacket::SaveOptions(SaveOptions::from_bytes(data)?)), _ => Err(PacketParseError::WrongPacketForServerType(u16::from_le_bytes([data[2], data[3]]), data.to_vec())) } } @@ -561,6 +563,9 @@ impl ServerState for ShipServerState { RecvShipPacket::FullCharacterData(full_character_data) => { Box::new(None.into_iter()) }, + RecvShipPacket::SaveOptions(save_options) => { + handler::settings::save_options(id, save_options, &mut self.clients, &mut self.entity_gateway).await + }, }) } From 114ed07adc54fa5baac19c1a60e5b3113936e275 Mon Sep 17 00:00:00 2001 From: andy Date: Fri, 2 Oct 2020 22:17:00 -0300 Subject: [PATCH 3/4] tests! --- tests/test_character.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 tests/test_character.rs diff --git a/tests/test_character.rs b/tests/test_character.rs new file mode 100644 index 0000000..c6196b8 --- /dev/null +++ b/tests/test_character.rs @@ -0,0 +1,31 @@ +use elseware::common::serverstate::{ClientId, ServerState}; +use elseware::entity::gateway::{EntityGateway, InMemoryGateway}; +use elseware::ship::ship::{ShipServerState, RecvShipPacket}; + +use libpso::packet::ship::*; + +#[path = "common.rs"] +mod common; +use common::*; + +#[async_std::test] +pub async fn test_save_options(ship: &mut ShipServerState, id: ClientId, options: u32) { + let mut entity_gateway = InMemoryGateway::new(); + + let (user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + + let mut ship = ShipServerState::builder() + .gateway(entity_gateway.clone()) + .build(); + log_in_char(&mut ship, ClientId(1), "a1", "a").await; + join_lobby(&mut ship, ClientId(1)).await; + + ship.handle(ClientId(1), &RecvShipPacket::SaveOptions(SaveOptions{ + options: 12345, + })).await.unwrap().for_each(drop); + + let characters = entity_gateway.get_characters_by_user(&user1).await; + let char = characters[0].as_ref().unwrap(); + + assert!(char.option_flags == 12345); +} From 046ca492a8de8a82604e85935050c2b5616df8bf Mon Sep 17 00:00:00 2001 From: andy Date: Sat, 3 Oct 2020 00:10:36 -0300 Subject: [PATCH 4/4] add a test --- tests/test_character.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_character.rs b/tests/test_character.rs index c6196b8..979f123 100644 --- a/tests/test_character.rs +++ b/tests/test_character.rs @@ -9,7 +9,7 @@ mod common; use common::*; #[async_std::test] -pub async fn test_save_options(ship: &mut ShipServerState, id: ClientId, options: u32) { +async fn test_save_options(ship: &mut ShipServerState, id: ClientId, options: u32) { let mut entity_gateway = InMemoryGateway::new(); let (user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; @@ -28,4 +28,4 @@ pub async fn test_save_options(ship: &mut ShipServerState let char = characters[0].as_ref().unwrap(); assert!(char.option_flags == 12345); -} +} \ No newline at end of file