From bf595f969327b77ef38fb279f55ef582246c6d0b Mon Sep 17 00:00:00 2001 From: jake Date: Sun, 29 Mar 2020 12:43:20 -0700 Subject: [PATCH 1/6] Character -> CharacterEntity --- src/entity/character.rs | 8 ++++---- src/entity/gateway/entitygateway.rs | 12 ++++++------ src/entity/gateway/inmemory.rs | 16 ++++++++-------- src/login/character.rs | 10 +++++----- src/ship/character.rs | 10 +++++----- src/ship/items.rs | 4 ++-- src/ship/ship.rs | 6 +++--- 7 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/entity/character.rs b/src/entity/character.rs index 98da20b..1480016 100644 --- a/src/entity/character.rs +++ b/src/entity/character.rs @@ -225,7 +225,7 @@ impl CharacterInfoboard { #[derive(Clone)] -pub struct Character { +pub struct CharacterEntity { pub id: u32, pub user_id: u32, pub slot: u32, @@ -242,9 +242,9 @@ pub struct Character { pub info_board: CharacterInfoboard, } -impl std::default::Default for Character { - fn default() -> Character { - Character { +impl std::default::Default for CharacterEntity { + fn default() -> CharacterEntity { + CharacterEntity { id: 0, user_id: 0, slot: 0, diff --git a/src/entity/gateway/entitygateway.rs b/src/entity/gateway/entitygateway.rs index edcc45c..564d9b2 100644 --- a/src/entity/gateway/entitygateway.rs +++ b/src/entity/gateway/entitygateway.rs @@ -25,15 +25,15 @@ pub trait EntityGateway { unimplemented!(); } - fn get_characters_by_user(&self, _user: &UserAccount) -> [Option; 4] { + fn get_characters_by_user(&self, _user: &UserAccount) -> [Option; 4] { unimplemented!(); } - fn set_character(&mut self, _char: &Character) { + fn set_character(&mut self, _char: &CharacterEntity) { unimplemented!(); } - fn new_character_by_user(&mut self, _user: &UserAccount) -> Character { + fn new_character_by_user(&mut self, _user: &UserAccount) -> CharacterEntity { unimplemented!(); } @@ -49,15 +49,15 @@ pub trait EntityGateway { unimplemented!(); } - fn get_items_by_character(&self, _char: &Character) -> Vec { + fn get_items_by_character(&self, _char: &CharacterEntity) -> Vec { unimplemented!(); } - fn create_guild_card_by_character(&self, _character: &Character) -> GuildCard { + fn create_guild_card_by_character(&self, _character: &CharacterEntity) -> GuildCard { unimplemented!(); } - fn get_guild_card_by_character(&self, _character: &Character) -> Option { + fn get_guild_card_by_character(&self, _character: &CharacterEntity) -> Option { unimplemented!(); } } diff --git a/src/entity/gateway/inmemory.rs b/src/entity/gateway/inmemory.rs index a616ce4..708b6b4 100644 --- a/src/entity/gateway/inmemory.rs +++ b/src/entity/gateway/inmemory.rs @@ -16,7 +16,7 @@ pub struct InMemoryGateway { users: Arc>>, user_settings: Arc>>, guildcards: Arc>>, - characters: Arc>>, + characters: Arc>>, items: Arc>>, } @@ -74,7 +74,7 @@ impl EntityGateway for InMemoryGateway { new_settings } - fn get_characters_by_user(&self, user: &UserAccount) -> [Option; 4] { + fn get_characters_by_user(&self, user: &UserAccount) -> [Option; 4] { let characters = self.characters.lock().unwrap(); let mut chars = [None; 4]; characters @@ -84,21 +84,21 @@ impl EntityGateway for InMemoryGateway { chars } - fn new_character_by_user(&mut self, user: &UserAccount) -> Character { + fn new_character_by_user(&mut self, user: &UserAccount) -> CharacterEntity { let mut characters = self.characters.lock().unwrap(); let id = characters .iter() .fold(0, |sum, (i, _)| std::cmp::max(sum, *i)) + 1; - let mut c = Character::default(); + let mut c = CharacterEntity::default(); c.id = id; c.user_id = user.id; characters.insert(id, c.clone()); c } - fn set_character(&mut self, char: &Character) { + fn set_character(&mut self, char: &CharacterEntity) { let mut characters = self.characters.lock().unwrap(); characters.insert(char.id, char.clone()); } @@ -127,7 +127,7 @@ impl EntityGateway for InMemoryGateway { items.insert(item.id, item.clone()); } - fn get_items_by_character(&self, character: &Character) -> Vec { + fn get_items_by_character(&self, character: &CharacterEntity) -> Vec { let items = self.items.lock().unwrap(); items .iter() @@ -144,7 +144,7 @@ impl EntityGateway for InMemoryGateway { .collect() } - fn create_guild_card_by_character(&self, character: &Character) -> GuildCard { + fn create_guild_card_by_character(&self, character: &CharacterEntity) -> GuildCard { let mut guildcards = self.guildcards.lock().unwrap(); let user = self.get_user_by_id(character.user_id).unwrap(); let settings = self.get_user_settings_by_user(&user).unwrap(); @@ -172,7 +172,7 @@ impl EntityGateway for InMemoryGateway { new_guildcard } - fn get_guild_card_by_character(&self, character: &Character) -> Option { + fn get_guild_card_by_character(&self, character: &CharacterEntity) -> Option { let guildcards = self.guildcards.lock().unwrap(); guildcards .iter() diff --git a/src/login/character.rs b/src/login/character.rs index 818aeb1..4b9cf24 100644 --- a/src/login/character.rs +++ b/src/login/character.rs @@ -23,7 +23,7 @@ use crate::entity::item::armor::Armor; use crate::entity::item::tech::Technique; use crate::entity::item::tool::Tool; use crate::entity::item::mag::{Mag, MagType}; -use crate::entity::character::{Character, CharacterClass, TechLevel}; +use crate::entity::character::{CharacterEntity, CharacterClass, TechLevel}; use crate::login::login::get_login_status; @@ -143,7 +143,7 @@ fn generate_param_data(path: &str) -> (ParamDataHeader, Vec) { struct ClientState { param_index: usize, user: Option, - characters: Option<[Option; 4]>, + characters: Option<[Option; 4]>, guildcard_data_buffer: Option>, session: Session, } @@ -552,7 +552,7 @@ impl ServerState for CharacterServerState { } -fn new_character_from_preview(character: &mut Character, preview: &CharacterPreview) { +fn new_character_from_preview(character: &mut CharacterEntity, preview: &CharacterPreview) { character.slot = preview.slot; character.name = String::from_utf16_lossy(&preview.character.name).trim_matches(char::from(0)).into(); character.section_id = preview.character.section_id.into(); @@ -571,7 +571,7 @@ fn new_character_from_preview(character: &mut Character, preview: &CharacterPrev struct SelectScreenCharacterBuilder<'a> { - character: Option<&'a Character>, + character: Option<&'a CharacterEntity>, level: Option, } @@ -583,7 +583,7 @@ impl<'a> SelectScreenCharacterBuilder<'a> { } } - fn character(self, character: &'a Character) -> SelectScreenCharacterBuilder<'a> { + fn character(self, character: &'a CharacterEntity) -> SelectScreenCharacterBuilder<'a> { SelectScreenCharacterBuilder { character: Some(character), ..self diff --git a/src/ship/character.rs b/src/ship/character.rs index df38c37..8be687c 100644 --- a/src/ship/character.rs +++ b/src/ship/character.rs @@ -1,11 +1,11 @@ use libpso::character::character; use crate::common::leveltable::CharacterStats; -use crate::entity::character::Character; +use crate::entity::character::CharacterEntity; use crate::ship::items::ActiveInventory; // TODO: exp pub struct CharacterBytesBuilder<'a> { - character: Option<&'a Character>, + character: Option<&'a CharacterEntity>, stats: Option<&'a CharacterStats>, level: Option, } @@ -20,7 +20,7 @@ impl<'a> CharacterBytesBuilder<'a> { } } - pub fn character(self, character: &'a Character) -> CharacterBytesBuilder<'a> { + pub fn character(self, character: &'a CharacterEntity) -> CharacterBytesBuilder<'a> { CharacterBytesBuilder { character: Some(character), ..self @@ -76,7 +76,7 @@ impl<'a> CharacterBytesBuilder<'a> { pub struct FullCharacterBytesBuilder<'a> { - character: Option<&'a Character>, + character: Option<&'a CharacterEntity>, stats: Option<&'a CharacterStats>, level: Option, inventory: Option<&'a ActiveInventory>, @@ -97,7 +97,7 @@ impl<'a> FullCharacterBytesBuilder<'a> { } } - pub fn character(self, character: &'a Character) -> FullCharacterBytesBuilder<'a> { + pub fn character(self, character: &'a CharacterEntity) -> FullCharacterBytesBuilder<'a> { FullCharacterBytesBuilder { character: Some(character), ..self diff --git a/src/ship/items.rs b/src/ship/items.rs index 838ae66..6875d6d 100644 --- a/src/ship/items.rs +++ b/src/ship/items.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use libpso::character::character::InventoryItem; use crate::entity::gateway::EntityGateway; -use crate::entity::character::Character; +use crate::entity::character::CharacterEntity; use crate::entity::item::{Item, ItemId, ItemDetail, ItemLocation}; use crate::entity::item::weapon::Weapon; use crate::entity::item::armor::Armor; @@ -151,7 +151,7 @@ impl ActiveItemDatabase { // deactivate item - pub fn get_character_inventory(&mut self, entity_gateway: &mut EG, character: &Character) -> ActiveInventory { + pub fn get_character_inventory(&mut self, entity_gateway: &mut EG, character: &CharacterEntity) -> ActiveInventory { let items = entity_gateway.get_items_by_character(&character); let inventory_items = items.into_iter() .filter(|item| { diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 6b44b19..80f0ccf 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -17,7 +17,7 @@ use crate::common::leveltable::CharacterLevelTable; use crate::entity::gateway::EntityGateway; use crate::entity::account::{UserAccount, UserSettings, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM, GuildCard}; -use crate::entity::character::Character; +use crate::entity::character::CharacterEntity; use crate::entity::item::{ItemLocation, Item}; use crate::login::login::get_login_status; use crate::ship::location::{ClientLocation, LobbyId, RoomId, AreaType, MAX_ROOMS}; @@ -120,7 +120,7 @@ impl SendServerPacket for SendShipPacket { struct ClientState { user: UserAccount, settings: UserSettings, - character: Character, + character: CharacterEntity, session: Session, guildcard: GuildCard, inventory: items::ActiveInventory, @@ -129,7 +129,7 @@ struct ClientState { } impl ClientState { - fn new(user: UserAccount, settings: UserSettings, character: Character, inventory: items::ActiveInventory, /*bank: Bank,*/ session: Session, guildcard: GuildCard) -> ClientState { + fn new(user: UserAccount, settings: UserSettings, character: CharacterEntity, inventory: items::ActiveInventory, /*bank: Bank,*/ session: Session, guildcard: GuildCard) -> ClientState { ClientState { user: user, settings: settings, From de8f44f269181616ccbb66c50a16bdd4e1dc70dd Mon Sep 17 00:00:00 2001 From: jake Date: Sun, 29 Mar 2020 13:27:23 -0700 Subject: [PATCH 2/6] andy what were you doing make guild card sending much more sane --- src/entity/account.rs | 7 ------ src/entity/character.rs | 7 +++++- src/entity/gateway/entitygateway.rs | 8 ------ src/entity/gateway/inmemory.rs | 38 ----------------------------- src/main.rs | 8 ------ src/ship/ship.rs | 33 ++++++++++++------------- 6 files changed, 21 insertions(+), 80 deletions(-) diff --git a/src/entity/account.rs b/src/entity/account.rs index e0e5667..cc77d92 100644 --- a/src/entity/account.rs +++ b/src/entity/account.rs @@ -32,10 +32,3 @@ pub struct GuildCardData { pub user_id: u32, pub guildcard: guildcard::GuildCardData, } - -#[derive(Clone, Default)] -pub struct GuildCard { - pub id: u32, - pub character_id: u32, - pub guildcard: guildcard::GuildCard, -} \ No newline at end of file diff --git a/src/entity/character.rs b/src/entity/character.rs index 1480016..d10fc44 100644 --- a/src/entity/character.rs +++ b/src/entity/character.rs @@ -1,7 +1,6 @@ use std::convert::{From, Into, TryFrom, TryInto}; use std::collections::HashMap; -use libpso::character::character; use libpso::packet::ship::{UpdateConfig, WriteInfoboard}; use crate::entity::item::tech::Technique; @@ -223,6 +222,10 @@ impl CharacterInfoboard { } } +#[derive(Clone, Default)] +pub struct CharacterGuildCard { + pub description: String, +} #[derive(Clone)] pub struct CharacterEntity { @@ -240,6 +243,7 @@ pub struct CharacterEntity { pub techs: CharacterTechniques, pub config: CharacterConfig, pub info_board: CharacterInfoboard, + pub guildcard: CharacterGuildCard, } impl std::default::Default for CharacterEntity { @@ -256,6 +260,7 @@ impl std::default::Default for CharacterEntity { techs: CharacterTechniques::new(), config: CharacterConfig::new(), info_board: CharacterInfoboard::new(), + guildcard: CharacterGuildCard::default(), } } } diff --git a/src/entity/gateway/entitygateway.rs b/src/entity/gateway/entitygateway.rs index 564d9b2..c478dcb 100644 --- a/src/entity/gateway/entitygateway.rs +++ b/src/entity/gateway/entitygateway.rs @@ -52,12 +52,4 @@ pub trait EntityGateway { fn get_items_by_character(&self, _char: &CharacterEntity) -> Vec { unimplemented!(); } - - fn create_guild_card_by_character(&self, _character: &CharacterEntity) -> GuildCard { - unimplemented!(); - } - - fn get_guild_card_by_character(&self, _character: &CharacterEntity) -> Option { - unimplemented!(); - } } diff --git a/src/entity/gateway/inmemory.rs b/src/entity/gateway/inmemory.rs index 708b6b4..15c90b5 100644 --- a/src/entity/gateway/inmemory.rs +++ b/src/entity/gateway/inmemory.rs @@ -15,7 +15,6 @@ use std::sync::{Arc, Mutex}; pub struct InMemoryGateway { users: Arc>>, user_settings: Arc>>, - guildcards: Arc>>, characters: Arc>>, items: Arc>>, } @@ -25,7 +24,6 @@ impl InMemoryGateway { InMemoryGateway { users: Arc::new(Mutex::new(HashMap::new())), user_settings: Arc::new(Mutex::new(HashMap::new())), - guildcards: Arc::new(Mutex::new(HashMap::new())), characters: Arc::new(Mutex::new(HashMap::new())), items: Arc::new(Mutex::new(HashMap::new())), } @@ -143,40 +141,4 @@ impl EntityGateway for InMemoryGateway { }) .collect() } - - fn create_guild_card_by_character(&self, character: &CharacterEntity) -> GuildCard { - let mut guildcards = self.guildcards.lock().unwrap(); - let user = self.get_user_by_id(character.user_id).unwrap(); - let settings = self.get_user_settings_by_user(&user).unwrap(); - let id = guildcards - .iter() - .fold(0, |sum, (i, _)| std::cmp::max(sum, *i)) - + 1; - let new_guildcard = GuildCard { - id: id, - character_id: character.id, - guildcard: libpso::character::guildcard::GuildCard { - guildcard: user.guildcard, - name: libpso::utf8_to_utf16_array!(character.name, 24), - team: settings.settings.team_name, - desc: [0; 88], // TODO? - reserved1: 1, - language: 0, - section_id: character.section_id.into(), - class: character.char_class.into(), - padding: 0, - comment: [0; 88], // TODO? - }, - }; - guildcards.insert(id, new_guildcard.clone()); - new_guildcard - } - - fn get_guild_card_by_character(&self, character: &CharacterEntity) -> Option { - let guildcards = self.guildcards.lock().unwrap(); - guildcards - .iter() - .find(|(_, k)| k.character_id == character.id) - .map(|(_, k)| k.clone()) - } } diff --git a/src/main.rs b/src/main.rs index 3d506e1..e1dabfd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -73,13 +73,11 @@ fn main() { entity_gateway.create_user_settings_by_user(&fake_user); let mut character = entity_gateway.new_character_by_user(&fake_user); character.name = "Test Char 1".into(); - entity_gateway.create_guild_card_by_character(&character); entity_gateway.set_character(&character); let mut character = entity_gateway.new_character_by_user(&fake_user); character.slot = 2; character.name = "\tE12345678".into(); character.exp = 80000000; - entity_gateway.create_guild_card_by_character(&character); entity_gateway.set_character(&character); entity_gateway.new_item( @@ -115,12 +113,10 @@ fn main() { entity_gateway.create_user_settings_by_user(&fake_user2); let mut character = entity_gateway.new_character_by_user(&fake_user2); character.name = "Test Char 3".into(); - entity_gateway.create_guild_card_by_character(&character); entity_gateway.set_character(&character); let mut character = entity_gateway.new_character_by_user(&fake_user2); character.slot = 2; character.name = "Test Char 4".into(); - entity_gateway.create_guild_card_by_character(&character); entity_gateway.set_character(&character); let fake_user3 = UserAccount { @@ -138,12 +134,10 @@ fn main() { entity_gateway.create_user_settings_by_user(&fake_user3); let mut character = entity_gateway.new_character_by_user(&fake_user3); character.name = "Test Char 5".into(); - entity_gateway.create_guild_card_by_character(&character); entity_gateway.set_character(&character); let mut character = entity_gateway.new_character_by_user(&fake_user3); character.slot = 2; character.name = "Test Char 6".into(); - entity_gateway.create_guild_card_by_character(&character); entity_gateway.set_character(&character); let fake_user4 = UserAccount { @@ -161,12 +155,10 @@ fn main() { entity_gateway.create_user_settings_by_user(&fake_user4); let mut character = entity_gateway.new_character_by_user(&fake_user4); character.name = "Test Char 7".into(); - entity_gateway.create_guild_card_by_character(&character); entity_gateway.set_character(&character); let mut character = entity_gateway.new_character_by_user(&fake_user4); character.slot = 2; character.name = "Test Char 8".into(); - entity_gateway.create_guild_card_by_character(&character); entity_gateway.set_character(&character); async_std::task::block_on(async move { diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 80f0ccf..518d874 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -10,13 +10,14 @@ use libpso::{PacketParseError, PSOPacket}; use libpso::crypto::bb::PSOBBCipher; use libpso::character::character; use libpso::packet::ship::{ROOM_MENU_ID}; +use libpso::{utf8_to_array, utf8_to_utf16_array}; use crate::common::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY}; use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId}; use crate::common::leveltable::CharacterLevelTable; use crate::entity::gateway::EntityGateway; -use crate::entity::account::{UserAccount, UserSettings, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM, GuildCard}; +use crate::entity::account::{UserAccount, UserSettings, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM}; use crate::entity::character::CharacterEntity; use crate::entity::item::{ItemLocation, Item}; use crate::login::login::get_login_status; @@ -122,21 +123,20 @@ struct ClientState { settings: UserSettings, character: CharacterEntity, session: Session, - guildcard: GuildCard, + //guildcard: GuildCard, inventory: items::ActiveInventory, //bank: Bank, block: u32, } impl ClientState { - fn new(user: UserAccount, settings: UserSettings, character: CharacterEntity, inventory: items::ActiveInventory, /*bank: Bank,*/ session: Session, guildcard: GuildCard) -> ClientState { + fn new(user: UserAccount, settings: UserSettings, character: CharacterEntity, inventory: items::ActiveInventory, /*bank: Bank,*/ session: Session) -> ClientState { ClientState { user: user, settings: settings, character: character, session: session, inventory: inventory, - guildcard: guildcard, //bank: bank, block: 1, } @@ -181,11 +181,9 @@ impl ShipServerState { .clone(); let settings = self.entity_gateway.get_user_settings_by_user(&user) .ok_or(ShipError::ClientNotFound(id))?; - let guildcard = self.entity_gateway.get_guild_card_by_character(&character) - .ok_or(ShipError::ClientNotFound(id))?; let inventory = self.item_database.get_character_inventory(&mut self.entity_gateway, &character); - self.clients.insert(id, ClientState::new(user, settings, character, inventory, pkt.session, guildcard)); + self.clients.insert(id, ClientState::new(user, settings, character, inventory, pkt.session)); vec![SendShipPacket::LoginResponse(response), SendShipPacket::ShipBlockList(ShipBlockList::new(&self.name, 3))] }, Err(err) => { @@ -331,22 +329,21 @@ impl ShipServerState { fn direct_message(&mut self, id: ClientId, msg: &DirectMessage) -> Box + Send> { let cmsg = msg.clone(); let client = self.clients.get_mut(&id).unwrap(); - let gc = self.entity_gateway.get_guild_card_by_character(&client.character).unwrap(); match &cmsg.msg { - GameMessage::GuildcardSend(GuildcardSend) => { + GameMessage::GuildcardSend(guildcard_send) => { let out_msg = DirectMessage{ flag: cmsg.flag, msg: GameMessage::GuildcardRecv(GuildcardRecv { - client: 141, - target: 8, - guildcard: gc.guildcard.guildcard, - name: gc.guildcard.name, - team: gc.guildcard.team, - desc: gc.guildcard.desc, + client: guildcard_send.client, + target: guildcard_send.target, + guildcard: client.user.id, + name: utf8_to_utf16_array!(client.character.name, 0x18), + team: [0; 0x10], // TODO: teams not yet implemented + desc: utf8_to_utf16_array!(client.character.guildcard.description, 0x58), one: 1, - language: gc.guildcard.language, - section_id: gc.guildcard.section_id, - class: gc.guildcard.class, + language: 0, // TODO: add language flag to character + section_id: client.character.section_id.into(), + class: client.character.char_class.into(), }), }; Box::new(self.client_location.get_area_by_user(id).clients().iter() From 0954d85e5a4a405e75b539583de50fa0fa265935 Mon Sep 17 00:00:00 2001 From: jake Date: Sun, 29 Mar 2020 14:40:24 -0700 Subject: [PATCH 3/6] CharacterEntityId --- src/entity/character.rs | 8 ++++++-- src/entity/gateway/inmemory.rs | 8 ++++---- src/entity/item/mod.rs | 11 +++++++---- src/ship/items.rs | 19 ++++++++++--------- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/entity/character.rs b/src/entity/character.rs index d10fc44..fe856e7 100644 --- a/src/entity/character.rs +++ b/src/entity/character.rs @@ -227,9 +227,13 @@ pub struct CharacterGuildCard { pub description: String, } + +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct CharacterEntityId(pub u32); + #[derive(Clone)] pub struct CharacterEntity { - pub id: u32, + pub id: CharacterEntityId, pub user_id: u32, pub slot: u32, @@ -249,7 +253,7 @@ pub struct CharacterEntity { impl std::default::Default for CharacterEntity { fn default() -> CharacterEntity { CharacterEntity { - id: 0, + id: CharacterEntityId(0), user_id: 0, slot: 0, name: "".into(), diff --git a/src/entity/gateway/inmemory.rs b/src/entity/gateway/inmemory.rs index 15c90b5..292024a 100644 --- a/src/entity/gateway/inmemory.rs +++ b/src/entity/gateway/inmemory.rs @@ -15,7 +15,7 @@ use std::sync::{Arc, Mutex}; pub struct InMemoryGateway { users: Arc>>, user_settings: Arc>>, - characters: Arc>>, + characters: Arc>>, items: Arc>>, } @@ -86,13 +86,13 @@ impl EntityGateway for InMemoryGateway { let mut characters = self.characters.lock().unwrap(); let id = characters .iter() - .fold(0, |sum, (i, _)| std::cmp::max(sum, *i)) + .fold(0, |sum, (i, _)| std::cmp::max(sum, i.0)) + 1; let mut c = CharacterEntity::default(); - c.id = id; + c.id = CharacterEntityId(id); c.user_id = user.id; - characters.insert(id, c.clone()); + characters.insert(CharacterEntityId(id), c.clone()); c } diff --git a/src/entity/item/mod.rs b/src/entity/item/mod.rs index 3c0cb13..9895bfb 100644 --- a/src/entity/item/mod.rs +++ b/src/entity/item/mod.rs @@ -6,22 +6,25 @@ pub mod tech; pub mod unit; pub mod mag; +use crate::entity::character::CharacterEntityId; + #[derive(PartialEq, Copy, Clone, Debug, Hash, Eq)] pub struct ItemEntityId(pub u32); #[derive(Hash, PartialEq, Eq, Debug, Clone)] pub struct ItemId(u32); - +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct BankName(String); #[derive(Clone, Debug, PartialEq)] pub enum ItemLocation { Inventory { - character_id: u32, + character_id: CharacterEntityId, index: usize, equipped: bool, }, Bank { - character_id: u32, - slot: usize, + character_id: CharacterEntityId, + slot: BankName, }, Floor { // floor: eventually diff --git a/src/ship/items.rs b/src/ship/items.rs index 6875d6d..7a11221 100644 --- a/src/ship/items.rs +++ b/src/ship/items.rs @@ -172,6 +172,7 @@ impl ActiveItemDatabase { #[cfg(test)] mod test { use super::*; + use crate::entity::character::CharacterEntityId; use crate::entity::item; use crate::entity::item::{Item, ItemDetail, ItemEntityId, ItemLocation}; #[test] @@ -179,7 +180,7 @@ mod test { let item1 = Item { id: ItemEntityId(1), location: ItemLocation::Inventory { - character_id: 0, + character_id: CharacterEntityId(0), index: 0, equipped: false, }, @@ -194,7 +195,7 @@ mod test { let item2 = Item { id: ItemEntityId(2), location: ItemLocation::Inventory { - character_id: 0, + character_id: CharacterEntityId(0), index: 1, equipped: false, }, @@ -205,7 +206,7 @@ mod test { let item3 = Item { id: ItemEntityId(3), location: ItemLocation::Inventory { - character_id: 0, + character_id: CharacterEntityId(0), index: 2, equipped: false, }, @@ -220,7 +221,7 @@ mod test { let item4 = Item { id: ItemEntityId(4), location: ItemLocation::Inventory { - character_id: 0, + character_id: CharacterEntityId(0), index: 1, equipped: false, }, @@ -231,7 +232,7 @@ mod test { let item5 = Item { id: ItemEntityId(5), location: ItemLocation::Inventory { - character_id: 0, + character_id: CharacterEntityId(0), index: 1, equipped: false, }, @@ -242,7 +243,7 @@ mod test { let item6 = Item { id: ItemEntityId(6), location: ItemLocation::Inventory { - character_id: 0, + character_id: CharacterEntityId(0), index: 3, equipped: false, }, @@ -257,7 +258,7 @@ mod test { let item7 = Item { id: ItemEntityId(7), location: ItemLocation::Inventory { - character_id: 0, + character_id: CharacterEntityId(0), index: 4, equipped: false, }, @@ -268,7 +269,7 @@ mod test { let item8 = Item { id: ItemEntityId(8), location: ItemLocation::Inventory { - character_id: 0, + character_id: CharacterEntityId(0), index: 4, equipped: false, }, @@ -279,7 +280,7 @@ mod test { let item9 = Item { id: ItemEntityId(9), location: ItemLocation::Inventory { - character_id: 0, + character_id: CharacterEntityId(0), index: 4, equipped: false, }, From 44c35f350dd8d56817502b63e16ba4c9d8befb8a Mon Sep 17 00:00:00 2001 From: jake Date: Sun, 29 Mar 2020 14:53:51 -0700 Subject: [PATCH 4/6] Item -> ItemEntity --- src/entity/gateway/entitygateway.rs | 6 +++--- src/entity/gateway/inmemory.rs | 10 ++++----- src/entity/item/mod.rs | 2 +- src/ship/items.rs | 32 ++++++++++++++--------------- src/ship/ship.rs | 2 +- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/entity/gateway/entitygateway.rs b/src/entity/gateway/entitygateway.rs index c478dcb..ebbe509 100644 --- a/src/entity/gateway/entitygateway.rs +++ b/src/entity/gateway/entitygateway.rs @@ -41,15 +41,15 @@ pub trait EntityGateway { unimplemented!(); } - fn new_item(&mut self, _item: ItemDetail, _location: ItemLocation) -> Item { + fn new_item(&mut self, _item: ItemDetail, _location: ItemLocation) -> ItemEntity { unimplemented!(); } - fn set_item(&self, _item: &Item) { + fn set_item(&self, _item: &ItemEntity) { unimplemented!(); } - fn get_items_by_character(&self, _char: &CharacterEntity) -> Vec { + fn get_items_by_character(&self, _char: &CharacterEntity) -> Vec { unimplemented!(); } } diff --git a/src/entity/gateway/inmemory.rs b/src/entity/gateway/inmemory.rs index 292024a..1c93af8 100644 --- a/src/entity/gateway/inmemory.rs +++ b/src/entity/gateway/inmemory.rs @@ -16,7 +16,7 @@ pub struct InMemoryGateway { users: Arc>>, user_settings: Arc>>, characters: Arc>>, - items: Arc>>, + items: Arc>>, } impl InMemoryGateway { @@ -105,13 +105,13 @@ impl EntityGateway for InMemoryGateway { GuildCardData::default() } - fn new_item(&mut self, item: ItemDetail, location: ItemLocation) -> Item { + fn new_item(&mut self, item: ItemDetail, location: ItemLocation) -> ItemEntity { let mut items = self.items.lock().unwrap(); let id = items .iter() .fold(0, |sum, (i, _)| std::cmp::max(sum, i.0)) + 1; - let new_item = Item { + let new_item = ItemEntity { id: ItemEntityId(id), location: location, item: item, @@ -120,12 +120,12 @@ impl EntityGateway for InMemoryGateway { new_item } - fn set_item(&self, item: &Item) { + fn set_item(&self, item: &ItemEntity) { let mut items = self.items.lock().unwrap(); items.insert(item.id, item.clone()); } - fn get_items_by_character(&self, character: &CharacterEntity) -> Vec { + fn get_items_by_character(&self, character: &CharacterEntity) -> Vec { let items = self.items.lock().unwrap(); items .iter() diff --git a/src/entity/item/mod.rs b/src/entity/item/mod.rs index 9895bfb..1cdb96b 100644 --- a/src/entity/item/mod.rs +++ b/src/entity/item/mod.rs @@ -87,7 +87,7 @@ impl ItemDetail { #[derive(Clone, Debug, PartialEq)] -pub struct Item { +pub struct ItemEntity { pub id: ItemEntityId, pub location: ItemLocation, pub item: ItemDetail, diff --git a/src/ship/items.rs b/src/ship/items.rs index 7a11221..77fd88f 100644 --- a/src/ship/items.rs +++ b/src/ship/items.rs @@ -4,7 +4,7 @@ use libpso::character::character::InventoryItem; use crate::entity::gateway::EntityGateway; use crate::entity::character::CharacterEntity; -use crate::entity::item::{Item, ItemId, ItemDetail, ItemLocation}; +use crate::entity::item::{ItemEntity, ItemId, ItemDetail, ItemLocation}; use crate::entity::item::weapon::Weapon; use crate::entity::item::armor::Armor; use crate::entity::item::shield::Shield; @@ -15,8 +15,8 @@ use crate::entity::item::mag::Mag; #[derive(Debug, PartialEq)] pub enum StackedItem { - Individual(Item), - Stacked(Vec), + Individual(ItemEntity), + Stacked(Vec), } #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] @@ -68,12 +68,12 @@ impl ActiveInventory { // does this do anything? inventory[index].equipped = match item.item { - StackedItem::Individual(Item {location: ItemLocation::Inventory{ equipped: true, ..}, ..}) => 1, + StackedItem::Individual(ItemEntity {location: ItemLocation::Inventory{ equipped: true, ..}, ..}) => 1, _ => 0, }; // because this actually equips the item inventory[index].flags |= match item.item { - StackedItem::Individual(Item {location: ItemLocation::Inventory{ equipped: true, ..}, ..}) => 8, + StackedItem::Individual(ItemEntity {location: ItemLocation::Inventory{ equipped: true, ..}, ..}) => 8, _ => 0, }; inventory @@ -102,7 +102,7 @@ fn inventory_item_index(item: &StackedItem) -> usize { } } -fn stack_items(items: Vec) -> Vec { +fn stack_items(items: Vec) -> Vec { let mut stacks = HashMap::new(); for item in items { @@ -174,10 +174,10 @@ mod test { use super::*; use crate::entity::character::CharacterEntityId; use crate::entity::item; - use crate::entity::item::{Item, ItemDetail, ItemEntityId, ItemLocation}; + use crate::entity::item::{ItemEntity, ItemDetail, ItemEntityId, ItemLocation}; #[test] fn test_stack_items() { - let item1 = Item { + let item1 = ItemEntity { id: ItemEntityId(1), location: ItemLocation::Inventory { character_id: CharacterEntityId(0), @@ -192,7 +192,7 @@ mod test { tekked: true, }) }; - let item2 = Item { + let item2 = ItemEntity { id: ItemEntityId(2), location: ItemLocation::Inventory { character_id: CharacterEntityId(0), @@ -203,7 +203,7 @@ mod test { tool: item::tool::ToolType::Monofluid, }) }; - let item3 = Item { + let item3 = ItemEntity { id: ItemEntityId(3), location: ItemLocation::Inventory { character_id: CharacterEntityId(0), @@ -218,7 +218,7 @@ mod test { tekked: true, }) }; - let item4 = Item { + let item4 = ItemEntity { id: ItemEntityId(4), location: ItemLocation::Inventory { character_id: CharacterEntityId(0), @@ -229,7 +229,7 @@ mod test { tool: item::tool::ToolType::Monofluid, }) }; - let item5 = Item { + let item5 = ItemEntity { id: ItemEntityId(5), location: ItemLocation::Inventory { character_id: CharacterEntityId(0), @@ -240,7 +240,7 @@ mod test { tool: item::tool::ToolType::Monofluid, }) }; - let item6 = Item { + let item6 = ItemEntity { id: ItemEntityId(6), location: ItemLocation::Inventory { character_id: CharacterEntityId(0), @@ -255,7 +255,7 @@ mod test { tekked: true, }) }; - let item7 = Item { + let item7 = ItemEntity { id: ItemEntityId(7), location: ItemLocation::Inventory { character_id: CharacterEntityId(0), @@ -266,7 +266,7 @@ mod test { tool: item::tool::ToolType::Monomate, }) }; - let item8 = Item { + let item8 = ItemEntity { id: ItemEntityId(8), location: ItemLocation::Inventory { character_id: CharacterEntityId(0), @@ -277,7 +277,7 @@ mod test { tool: item::tool::ToolType::Monomate, }) }; - let item9 = Item { + let item9 = ItemEntity { id: ItemEntityId(9), location: ItemLocation::Inventory { character_id: CharacterEntityId(0), diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 518d874..5dbb472 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -19,7 +19,7 @@ use crate::common::leveltable::CharacterLevelTable; use crate::entity::gateway::EntityGateway; use crate::entity::account::{UserAccount, UserSettings, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM}; use crate::entity::character::CharacterEntity; -use crate::entity::item::{ItemLocation, Item}; +use crate::entity::item::{ItemLocation, ItemEntity}; use crate::login::login::get_login_status; use crate::ship::location::{ClientLocation, LobbyId, RoomId, AreaType, MAX_ROOMS}; use crate::ship::character::{CharacterBytesBuilder, FullCharacterBytesBuilder}; From 6b1ef41bd093059cd68acee1ebfb845f75b34c8a Mon Sep 17 00:00:00 2001 From: jake Date: Sun, 29 Mar 2020 16:11:14 -0700 Subject: [PATCH 5/6] UserAccount/UserSettings/GuildCardData -> *Entities --- src/entity/account.rs | 24 ++++++++++++++-------- src/entity/character.rs | 5 +++-- src/entity/gateway/entitygateway.rs | 16 +++++++-------- src/entity/gateway/inmemory.rs | 32 ++++++++++++++--------------- src/login/character.rs | 12 +++++------ src/login/login.rs | 18 ++++++++-------- src/main.rs | 18 ++++++++-------- src/ship/ship.rs | 20 +++++++++--------- 8 files changed, 77 insertions(+), 68 deletions(-) diff --git a/src/entity/account.rs b/src/entity/account.rs index cc77d92..032d80b 100644 --- a/src/entity/account.rs +++ b/src/entity/account.rs @@ -6,9 +6,17 @@ use libpso::character::guildcard; pub const USERFLAG_NEWCHAR: u32 = 0x00000001; pub const USERFLAG_DRESSINGROOM: u32 = 0x00000002; +// TOOD: these should not derive default +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Default)] +pub struct UserAccountId(pub u32); +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Default)] +pub struct UserSettingsId(pub u32); +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Default)] +pub struct GuildCardDataId(pub u32); + #[derive(Clone, Debug)] -pub struct UserAccount { - pub id: u32, +pub struct UserAccountEntity { + pub id: UserAccountId, pub username: String, pub password: String, pub guildcard: u32, @@ -20,15 +28,15 @@ pub struct UserAccount { } #[derive(Clone, Debug, Default)] -pub struct UserSettings { - pub id: u32, - pub user_id: u32, +pub struct UserSettingsEntity { + pub id: UserSettingsId, + pub user_id: UserAccountId, pub settings: settings::UserSettings, } #[derive(Clone, Default)] -pub struct GuildCardData { - pub id: u32, - pub user_id: u32, +pub struct GuildCardDataEntity { + pub id: GuildCardDataId, + pub user_id: UserAccountId, pub guildcard: guildcard::GuildCardData, } diff --git a/src/entity/character.rs b/src/entity/character.rs index fe856e7..3e49631 100644 --- a/src/entity/character.rs +++ b/src/entity/character.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use libpso::packet::ship::{UpdateConfig, WriteInfoboard}; use crate::entity::item::tech::Technique; +use crate::entity::account::UserAccountId; #[derive(Copy, Clone, Hash, PartialEq, Eq)] pub enum CharacterClass { @@ -234,7 +235,7 @@ pub struct CharacterEntityId(pub u32); #[derive(Clone)] pub struct CharacterEntity { pub id: CharacterEntityId, - pub user_id: u32, + pub user_id: UserAccountId, pub slot: u32, pub name: String, @@ -254,7 +255,7 @@ impl std::default::Default for CharacterEntity { fn default() -> CharacterEntity { CharacterEntity { id: CharacterEntityId(0), - user_id: 0, + user_id: UserAccountId(0), slot: 0, name: "".into(), exp: 0, diff --git a/src/entity/gateway/entitygateway.rs b/src/entity/gateway/entitygateway.rs index ebbe509..eb15535 100644 --- a/src/entity/gateway/entitygateway.rs +++ b/src/entity/gateway/entitygateway.rs @@ -5,27 +5,27 @@ use crate::entity::item::*; use libpso::item; pub trait EntityGateway { - fn get_user_by_id(&self, _id: u32) -> Option { + fn get_user_by_id(&self, _id: UserAccountId) -> Option { unimplemented!(); } - fn get_user_by_name(&self, _username: String) -> Option { + fn get_user_by_name(&self, _username: String) -> Option { unimplemented!(); } - fn set_user(&mut self, _user: &UserAccount) { + fn set_user(&mut self, _user: &UserAccountEntity) { unimplemented!(); } - fn get_user_settings_by_user(&self, _user: &UserAccount) -> Option { + fn get_user_settings_by_user(&self, _user: &UserAccountEntity) -> Option { unimplemented!(); } - fn create_user_settings_by_user(&self, _user: &UserAccount) -> UserSettings { + fn create_user_settings_by_user(&self, _user: &UserAccountEntity) -> UserSettingsEntity { unimplemented!(); } - fn get_characters_by_user(&self, _user: &UserAccount) -> [Option; 4] { + fn get_characters_by_user(&self, _user: &UserAccountEntity) -> [Option; 4] { unimplemented!(); } @@ -33,11 +33,11 @@ pub trait EntityGateway { unimplemented!(); } - fn new_character_by_user(&mut self, _user: &UserAccount) -> CharacterEntity { + fn new_character_by_user(&mut self, _user: &UserAccountEntity) -> CharacterEntity { unimplemented!(); } - fn get_guild_card_data_by_user(&self, _user: &UserAccount) -> GuildCardData { + fn get_guild_card_data_by_user(&self, _user: &UserAccountEntity) -> GuildCardDataEntity { unimplemented!(); } diff --git a/src/entity/gateway/inmemory.rs b/src/entity/gateway/inmemory.rs index 1c93af8..5e04f99 100644 --- a/src/entity/gateway/inmemory.rs +++ b/src/entity/gateway/inmemory.rs @@ -13,8 +13,8 @@ use std::sync::{Arc, Mutex}; #[derive(Clone)] pub struct InMemoryGateway { - users: Arc>>, - user_settings: Arc>>, + users: Arc>>, + user_settings: Arc>>, characters: Arc>>, items: Arc>>, } @@ -31,12 +31,12 @@ impl InMemoryGateway { } impl EntityGateway for InMemoryGateway { - fn get_user_by_id(&self, id: u32) -> Option { + fn get_user_by_id(&self, id: UserAccountId) -> Option { let users = self.users.lock().unwrap(); users.get(&id).map(|k| k.clone()) } - fn get_user_by_name(&self, username: String) -> Option { + fn get_user_by_name(&self, username: String) -> Option { let users = self.users.lock().unwrap(); users .iter() @@ -44,35 +44,35 @@ impl EntityGateway for InMemoryGateway { .map(|(_, k)| k.clone()) } - fn set_user(&mut self, user: &UserAccount) { + fn set_user(&mut self, user: &UserAccountEntity) { let mut users = self.users.lock().unwrap(); users.insert(user.id, user.clone()); } - fn get_user_settings_by_user(&self, user: &UserAccount) -> Option { + fn get_user_settings_by_user(&self, user: &UserAccountEntity) -> Option { let user_settings = self.user_settings.lock().unwrap(); user_settings .iter() - .find(|(_, k)| k.id == user.id) + .find(|(_, k)| k.user_id == user.id) .map(|(_, k)| k.clone()) } - fn create_user_settings_by_user(&self, user: &UserAccount) -> UserSettings { + fn create_user_settings_by_user(&self, user: &UserAccountEntity) -> UserSettingsEntity { let mut user_settings = self.user_settings.lock().unwrap(); let id = user_settings .iter() - .fold(0, |sum, (i, _)| std::cmp::max(sum, *i)) + .fold(0, |sum, (i, _)| std::cmp::max(sum, i.0)) + 1; - let new_settings = UserSettings { - id: id, + let new_settings = UserSettingsEntity { + id: UserSettingsId(id), user_id: user.id, settings: settings::UserSettings::default(), }; - user_settings.insert(id, new_settings.clone()); + user_settings.insert(new_settings.id, new_settings.clone()); new_settings } - fn get_characters_by_user(&self, user: &UserAccount) -> [Option; 4] { + fn get_characters_by_user(&self, user: &UserAccountEntity) -> [Option; 4] { let characters = self.characters.lock().unwrap(); let mut chars = [None; 4]; characters @@ -82,7 +82,7 @@ impl EntityGateway for InMemoryGateway { chars } - fn new_character_by_user(&mut self, user: &UserAccount) -> CharacterEntity { + fn new_character_by_user(&mut self, user: &UserAccountEntity) -> CharacterEntity { let mut characters = self.characters.lock().unwrap(); let id = characters .iter() @@ -101,8 +101,8 @@ impl EntityGateway for InMemoryGateway { characters.insert(char.id, char.clone()); } - fn get_guild_card_data_by_user(&self, _user: &UserAccount) -> GuildCardData { - GuildCardData::default() + fn get_guild_card_data_by_user(&self, _user: &UserAccountEntity) -> GuildCardDataEntity { + GuildCardDataEntity::default() } fn new_item(&mut self, item: ItemDetail, location: ItemLocation) -> ItemEntity { diff --git a/src/login/character.rs b/src/login/character.rs index 4b9cf24..71934f8 100644 --- a/src/login/character.rs +++ b/src/login/character.rs @@ -16,7 +16,7 @@ use crate::common::leveltable::CharacterLevelTable; use libpso::{utf8_to_array, utf8_to_utf16_array}; use crate::entity::gateway::EntityGateway; -use crate::entity::account::{UserAccount, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM}; +use crate::entity::account::{UserAccountEntity, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM}; use crate::entity::item::{ItemDetail, ItemLocation}; use crate::entity::item::weapon::Weapon; use crate::entity::item::armor::Armor; @@ -142,7 +142,7 @@ fn generate_param_data(path: &str) -> (ParamDataHeader, Vec) { #[derive(Clone)] struct ClientState { param_index: usize, - user: Option, + user: Option, characters: Option<[Option; 4]>, guildcard_data_buffer: Option>, session: Session, @@ -189,7 +189,7 @@ pub struct CharacterServerState { } -fn new_character(entity_gateway: &mut EG, user: &UserAccount, preview: &CharacterPreview) { +fn new_character(entity_gateway: &mut EG, user: &UserAccountEntity, preview: &CharacterPreview) { let mut char = entity_gateway.new_character_by_user(&user); new_character_from_preview(&mut char, preview); match char.char_class { @@ -647,7 +647,7 @@ mod test { } impl EntityGateway for TestData { - fn get_user_settings_by_user(&self, _user: &UserAccount) -> Option { + fn get_user_settings_by_user(&self, _user: &UserAccountEntity) -> Option { Some(UserSettings { id: 0, user_id: 0, @@ -658,7 +658,7 @@ mod test { let mut server = CharacterServerState::new(TestData {}); let mut clientstate = ClientState::new(); - clientstate.user = Some(UserAccount { + clientstate.user = Some(UserAccountEntity { id: 1, username: "testuser".to_owned(), password: bcrypt::hash("mypassword", 5).unwrap(), @@ -700,7 +700,7 @@ mod test { fn test_character_create() { let TestData = InMemoryGateway::new(); let mut fake_user = ClientState::new(); - fake_user.user = Some(UserAccount { + fake_user.user = Some(UserAccountEntity { id: 3, username: "hi3".to_string(), password: bcrypt::hash("qwer", 5).unwrap(), diff --git a/src/login/login.rs b/src/login/login.rs index e0feec7..6237dfe 100644 --- a/src/login/login.rs +++ b/src/login/login.rs @@ -14,7 +14,7 @@ use crate::common::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY}; use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId}; use crate::entity::gateway::EntityGateway; -use crate::entity::account::UserAccount; +use crate::entity::account::UserAccountEntity; pub const LOGIN_PORT: u16 = 12000; @@ -56,7 +56,7 @@ impl SendServerPacket for SendLoginPacket { } -pub fn get_login_status(entity_gateway: &impl EntityGateway, pkt: &Login) -> Result { +pub fn get_login_status(entity_gateway: &impl EntityGateway, pkt: &Login) -> Result { let username = array_to_utf8(pkt.username).map_err(|_err| AccountStatus::Error)?; let password = array_to_utf8(pkt.password).map_err(|_err| AccountStatus::Error)?; let user = entity_gateway.get_user_by_name(username).ok_or(AccountStatus::InvalidUser)?; @@ -172,9 +172,9 @@ mod test { } impl EntityGateway for TestData { - fn get_user_by_name(&self, name: String) -> Option { + fn get_user_by_name(&self, name: String) -> Option { assert!(name == "testuser"); - Some(UserAccount { + Some(UserAccountEntity { id: 1, username: "testuser".to_owned(), password: bcrypt::hash("mypassword", 5).unwrap(), @@ -220,7 +220,7 @@ mod test { } impl EntityGateway for TestData { - fn get_user_by_name(&self, _name: String) -> Option { + fn get_user_by_name(&self, _name: String) -> Option { None } } @@ -252,9 +252,9 @@ mod test { } impl EntityGateway for TestData { - fn get_user_by_name(&self, name: String) -> Option { + fn get_user_by_name(&self, name: String) -> Option { assert!(name == "testuser"); - Some(UserAccount { + Some(UserAccountEntity { id: 1, username: "testuser".to_owned(), password: bcrypt::hash("notpassword", 5).unwrap(), @@ -295,9 +295,9 @@ mod test { } impl EntityGateway for TestData { - fn get_user_by_name(&self, name: String) -> Option { + fn get_user_by_name(&self, name: String) -> Option { assert!(name == "testuser"); - Some(UserAccount { + Some(UserAccountEntity { id: 1, username: "testuser".to_owned(), password: bcrypt::hash("mypassword", 5).unwrap(), diff --git a/src/main.rs b/src/main.rs index e1dabfd..4035914 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,7 @@ use patch::patch::{PatchServerState, generate_patch_tree, load_config, load_motd use login::login::LoginServerState; use login::character::CharacterServerState; use ship::ship::ShipServerState; -use entity::account::UserAccount; +use entity::account::{UserAccountEntity, UserAccountId}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item::ItemLocation; @@ -58,8 +58,8 @@ fn main() { setup_logger(); let mut entity_gateway = InMemoryGateway::new(); - let fake_user = UserAccount { - id: 1, + let fake_user = UserAccountEntity { + id: UserAccountId(1), username: "hi".to_string(), password: bcrypt::hash("qwer", 5).unwrap(), guildcard: 1u32, @@ -98,8 +98,8 @@ fn main() { ); - let fake_user2 = UserAccount { - id: 2, + let fake_user2 = UserAccountEntity { + id: UserAccountId(2), username: "hi2".to_string(), password: bcrypt::hash("qwer", 5).unwrap(), guildcard: 2u32, @@ -119,8 +119,8 @@ fn main() { character.name = "Test Char 4".into(); entity_gateway.set_character(&character); - let fake_user3 = UserAccount { - id: 3, + let fake_user3 = UserAccountEntity { + id: UserAccountId(3), username: "hi3".to_string(), password: bcrypt::hash("qwer", 5).unwrap(), guildcard: 3u32, @@ -140,8 +140,8 @@ fn main() { character.name = "Test Char 6".into(); entity_gateway.set_character(&character); - let fake_user4 = UserAccount { - id: 4, + let fake_user4 = UserAccountEntity { + id: UserAccountId(4), username: "hi4".to_string(), password: bcrypt::hash("qwer", 5).unwrap(), guildcard: 4u32, diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 5dbb472..3ce13f8 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -17,7 +17,7 @@ use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState use crate::common::leveltable::CharacterLevelTable; use crate::entity::gateway::EntityGateway; -use crate::entity::account::{UserAccount, UserSettings, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM}; +use crate::entity::account::{UserAccountEntity, UserSettingsEntity, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM}; use crate::entity::character::CharacterEntity; use crate::entity::item::{ItemLocation, ItemEntity}; use crate::login::login::get_login_status; @@ -119,8 +119,8 @@ impl SendServerPacket for SendShipPacket { } struct ClientState { - user: UserAccount, - settings: UserSettings, + user: UserAccountEntity, + settings: UserSettingsEntity, character: CharacterEntity, session: Session, //guildcard: GuildCard, @@ -130,7 +130,7 @@ struct ClientState { } impl ClientState { - fn new(user: UserAccount, settings: UserSettings, character: CharacterEntity, inventory: items::ActiveInventory, /*bank: Bank,*/ session: Session) -> ClientState { + fn new(user: UserAccountEntity, settings: UserSettingsEntity, character: CharacterEntity, inventory: items::ActiveInventory, /*bank: Bank,*/ session: Session) -> ClientState { ClientState { user: user, settings: settings, @@ -171,7 +171,7 @@ impl ShipServerState { Ok(match get_login_status(&self.entity_gateway, pkt) { Ok(user) => { let mut response = LoginResponse::by_status(AccountStatus::Ok, Session::new()); - response.guildcard = user.id as u32; + response.guildcard = user.id.0 as u32; response.team_id = user.team_id.map_or(31, |ti| ti) as u32; let characters = self.entity_gateway.get_characters_by_user(&user); let character = characters @@ -233,7 +233,7 @@ impl ShipServerState { PlayerInfo { header: PlayerHeader { tag: 0x100, - guildcard: client.user.id, + guildcard: client.user.id.0, _unknown1: [0; 5], client_id: room_client.index as u32, name: c.name, @@ -289,7 +289,7 @@ impl ShipServerState { playerinfo: PlayerInfo { header: PlayerHeader { tag: 0x100, - guildcard: client.user.id, + guildcard: client.user.id.0, _unknown1: [0; 5], client_id: client_id as u32, name: c.name, @@ -336,7 +336,7 @@ impl ShipServerState { msg: GameMessage::GuildcardRecv(GuildcardRecv { client: guildcard_send.client, target: guildcard_send.target, - guildcard: client.user.id, + guildcard: client.user.id.0, name: utf8_to_utf16_array!(client.character.name, 0x18), team: [0; 0x10], // TODO: teams not yet implemented desc: utf8_to_utf16_array!(client.character.guildcard.description, 0x58), @@ -365,7 +365,7 @@ impl ShipServerState { fn player_chat(&mut self, id: ClientId, msg: &PlayerChat) -> Result + Send>, ShipError> { let client = self.clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?; - let cmsg = PlayerChat::new(client.user.id, msg.message.clone()); + let cmsg = PlayerChat::new(client.user.id.0, msg.message.clone()); Ok(Box::new(self.client_location.get_area_by_user(id).clients().iter() .map(move |client| { @@ -392,7 +392,7 @@ impl ShipServerState { let client = self.clients.get_mut(&id).unwrap();//.ok_or(ShipError::ClientNotFound(id)).unwrap(); let players = [PlayerHeader { tag: 0x00010000, - guildcard: client.user.id, + guildcard: client.user.id.0, _unknown1: [0; 5], client_id: 0, name: libpso::utf8_to_utf16_array!(client.character.name, 16), From b39ee6c0f378384914439118739793f5ebafdcf0 Mon Sep 17 00:00:00 2001 From: jake Date: Sun, 29 Mar 2020 22:00:07 -0700 Subject: [PATCH 6/6] use Option for entity primary keys --- src/entity/account.rs | 38 ++++-- src/entity/character.rs | 10 +- src/entity/gateway/entitygateway.rs | 16 +-- src/entity/gateway/inmemory.rs | 96 +++++++-------- src/entity/item/mod.rs | 2 +- src/login/character.rs | 180 +++++++++++++++------------- src/login/login.rs | 8 +- src/main.rs | 149 +++++++---------------- src/ship/items.rs | 20 ++-- src/ship/ship.rs | 16 +-- 10 files changed, 248 insertions(+), 287 deletions(-) diff --git a/src/entity/account.rs b/src/entity/account.rs index 032d80b..1c3afbc 100644 --- a/src/entity/account.rs +++ b/src/entity/account.rs @@ -6,17 +6,16 @@ use libpso::character::guildcard; pub const USERFLAG_NEWCHAR: u32 = 0x00000001; pub const USERFLAG_DRESSINGROOM: u32 = 0x00000002; -// TOOD: these should not derive default -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Default)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct UserAccountId(pub u32); -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Default)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct UserSettingsId(pub u32); -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Default)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct GuildCardDataId(pub u32); #[derive(Clone, Debug)] pub struct UserAccountEntity { - pub id: UserAccountId, + pub id: Option, pub username: String, pub password: String, pub guildcard: u32, @@ -27,16 +26,37 @@ pub struct UserAccountEntity { pub flags: u32, // TODO: is this used for anything other than character creation? } -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct UserSettingsEntity { - pub id: UserSettingsId, + pub id: Option, pub user_id: UserAccountId, pub settings: settings::UserSettings, } -#[derive(Clone, Default)] +impl UserSettingsEntity { + pub fn new(user_id: UserAccountId) -> UserSettingsEntity { + UserSettingsEntity { + id: None, + user_id: user_id, + settings: settings::UserSettings::default(), + } + } +} + + +#[derive(Clone)] pub struct GuildCardDataEntity { - pub id: GuildCardDataId, + pub id: Option, pub user_id: UserAccountId, pub guildcard: guildcard::GuildCardData, } + +impl GuildCardDataEntity { + pub fn new(user_id: UserAccountId) -> GuildCardDataEntity { + GuildCardDataEntity { + id: None, + user_id: user_id, + guildcard: guildcard::GuildCardData::default(), + } + } +} diff --git a/src/entity/character.rs b/src/entity/character.rs index 3e49631..11f431a 100644 --- a/src/entity/character.rs +++ b/src/entity/character.rs @@ -234,7 +234,7 @@ pub struct CharacterEntityId(pub u32); #[derive(Clone)] pub struct CharacterEntity { - pub id: CharacterEntityId, + pub id: Option, pub user_id: UserAccountId, pub slot: u32, @@ -251,11 +251,11 @@ pub struct CharacterEntity { pub guildcard: CharacterGuildCard, } -impl std::default::Default for CharacterEntity { - fn default() -> CharacterEntity { +impl CharacterEntity { + pub fn new(user: UserAccountId) -> CharacterEntity { CharacterEntity { - id: CharacterEntityId(0), - user_id: UserAccountId(0), + id: None, + user_id: user, slot: 0, name: "".into(), exp: 0, diff --git a/src/entity/gateway/entitygateway.rs b/src/entity/gateway/entitygateway.rs index eb15535..3b90e08 100644 --- a/src/entity/gateway/entitygateway.rs +++ b/src/entity/gateway/entitygateway.rs @@ -13,7 +13,7 @@ pub trait EntityGateway { unimplemented!(); } - fn set_user(&mut self, _user: &UserAccountEntity) { + fn set_user(&mut self, _user: &mut UserAccountEntity) { unimplemented!(); } @@ -21,7 +21,7 @@ pub trait EntityGateway { unimplemented!(); } - fn create_user_settings_by_user(&self, _user: &UserAccountEntity) -> UserSettingsEntity { + fn set_user_settings(&mut self, _settings: &mut UserSettingsEntity) { unimplemented!(); } @@ -29,11 +29,7 @@ pub trait EntityGateway { unimplemented!(); } - fn set_character(&mut self, _char: &CharacterEntity) { - unimplemented!(); - } - - fn new_character_by_user(&mut self, _user: &UserAccountEntity) -> CharacterEntity { + fn set_character(&mut self, _char: &mut CharacterEntity) { unimplemented!(); } @@ -41,11 +37,7 @@ pub trait EntityGateway { unimplemented!(); } - fn new_item(&mut self, _item: ItemDetail, _location: ItemLocation) -> ItemEntity { - unimplemented!(); - } - - fn set_item(&self, _item: &ItemEntity) { + fn set_item(&mut self, _item: &mut ItemEntity) { unimplemented!(); } diff --git a/src/entity/gateway/inmemory.rs b/src/entity/gateway/inmemory.rs index 5e04f99..5f85b49 100644 --- a/src/entity/gateway/inmemory.rs +++ b/src/entity/gateway/inmemory.rs @@ -44,32 +44,37 @@ impl EntityGateway for InMemoryGateway { .map(|(_, k)| k.clone()) } - fn set_user(&mut self, user: &UserAccountEntity) { + fn set_user(&mut self, user: &mut UserAccountEntity) { let mut users = self.users.lock().unwrap(); - users.insert(user.id, user.clone()); + if let None = user.id { + let id = users + .iter() + .fold(0, |sum, (i, _)| std::cmp::max(sum, i.0)) + + 1; + user.id = Some(UserAccountId(id)); + } + users.insert(user.id.unwrap(), user.clone()); } fn get_user_settings_by_user(&self, user: &UserAccountEntity) -> Option { let user_settings = self.user_settings.lock().unwrap(); user_settings .iter() - .find(|(_, k)| k.user_id == user.id) + .find(|(_, k)| k.user_id == user.id.unwrap()) .map(|(_, k)| k.clone()) } - fn create_user_settings_by_user(&self, user: &UserAccountEntity) -> UserSettingsEntity { + + fn set_user_settings(&mut self, user_setting: &mut UserSettingsEntity) { let mut user_settings = self.user_settings.lock().unwrap(); - let id = user_settings - .iter() - .fold(0, |sum, (i, _)| std::cmp::max(sum, i.0)) - + 1; - let new_settings = UserSettingsEntity { - id: UserSettingsId(id), - user_id: user.id, - settings: settings::UserSettings::default(), - }; - user_settings.insert(new_settings.id, new_settings.clone()); - new_settings + if let None = user_setting.id { + let id = user_settings + .iter() + .fold(0, |sum, (i, _)| std::cmp::max(sum, i.0)) + + 1; + user_setting.id = Some(UserSettingsId(id)); + } + user_settings.insert(user_setting.id.unwrap(), user_setting.clone()); } fn get_characters_by_user(&self, user: &UserAccountEntity) -> [Option; 4] { @@ -77,52 +82,37 @@ impl EntityGateway for InMemoryGateway { let mut chars = [None; 4]; characters .iter() - .filter(|(_, c)| c.user_id == user.id) + .filter(|(_, c)| c.user_id == user.id.unwrap()) .for_each(|(_, c)| chars[c.slot as usize] = Some(c.clone())); chars } - fn new_character_by_user(&mut self, user: &UserAccountEntity) -> CharacterEntity { - let mut characters = self.characters.lock().unwrap(); - let id = characters - .iter() - .fold(0, |sum, (i, _)| std::cmp::max(sum, i.0)) - + 1; - - let mut c = CharacterEntity::default(); - c.id = CharacterEntityId(id); - c.user_id = user.id; - characters.insert(CharacterEntityId(id), c.clone()); - c - } - - fn set_character(&mut self, char: &CharacterEntity) { + fn set_character(&mut self, char: &mut CharacterEntity) { let mut characters = self.characters.lock().unwrap(); - characters.insert(char.id, char.clone()); + if let None = char.id { + let id = characters + .iter() + .fold(0, |sum, (i, _)| std::cmp::max(sum, i.0)) + + 1; + char.id = Some(CharacterEntityId(id)); + } + characters.insert(char.id.unwrap(), char.clone()); } - fn get_guild_card_data_by_user(&self, _user: &UserAccountEntity) -> GuildCardDataEntity { - GuildCardDataEntity::default() + fn get_guild_card_data_by_user(&self, user: &UserAccountEntity) -> GuildCardDataEntity { + GuildCardDataEntity::new(user.id.unwrap()) } - fn new_item(&mut self, item: ItemDetail, location: ItemLocation) -> ItemEntity { + fn set_item(&mut self, item: &mut ItemEntity) { let mut items = self.items.lock().unwrap(); - let id = items - .iter() - .fold(0, |sum, (i, _)| std::cmp::max(sum, i.0)) - + 1; - let new_item = ItemEntity { - id: ItemEntityId(id), - location: location, - item: item, - }; - items.insert(ItemEntityId(id), new_item.clone()); - new_item - } - - fn set_item(&self, item: &ItemEntity) { - let mut items = self.items.lock().unwrap(); - items.insert(item.id, item.clone()); + if let None = item.id { + let id = items + .iter() + .fold(0, |sum, (i, _)| std::cmp::max(sum, i.0)) + + 1; + item.id = Some(ItemEntityId(id)); + } + items.insert(item.id.unwrap(), item.clone()); } fn get_items_by_character(&self, character: &CharacterEntity) -> Vec { @@ -131,8 +121,8 @@ impl EntityGateway for InMemoryGateway { .iter() .filter(|(_, k)| { match k.location { - ItemLocation::Inventory{character_id, ..} => character_id == character.id, - ItemLocation::Bank{character_id, ..} => character_id == character.id, + ItemLocation::Inventory{character_id, ..} => character_id == character.id.unwrap(), + ItemLocation::Bank{character_id, ..} => character_id == character.id.unwrap(), _ => false } }) diff --git a/src/entity/item/mod.rs b/src/entity/item/mod.rs index 1cdb96b..aeb4a5c 100644 --- a/src/entity/item/mod.rs +++ b/src/entity/item/mod.rs @@ -88,7 +88,7 @@ impl ItemDetail { #[derive(Clone, Debug, PartialEq)] pub struct ItemEntity { - pub id: ItemEntityId, + pub id: Option, pub location: ItemLocation, pub item: ItemDetail, } diff --git a/src/login/character.rs b/src/login/character.rs index 71934f8..4a5cff5 100644 --- a/src/login/character.rs +++ b/src/login/character.rs @@ -16,8 +16,8 @@ use crate::common::leveltable::CharacterLevelTable; use libpso::{utf8_to_array, utf8_to_utf16_array}; use crate::entity::gateway::EntityGateway; -use crate::entity::account::{UserAccountEntity, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM}; -use crate::entity::item::{ItemDetail, ItemLocation}; +use crate::entity::account::{UserAccountEntity, UserSettingsEntity, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM}; +use crate::entity::item::{ItemEntity, ItemDetail, ItemLocation}; use crate::entity::item::weapon::Weapon; use crate::entity::item::armor::Armor; use crate::entity::item::tech::Technique; @@ -190,89 +190,101 @@ pub struct CharacterServerState { fn new_character(entity_gateway: &mut EG, user: &UserAccountEntity, preview: &CharacterPreview) { - let mut char = entity_gateway.new_character_by_user(&user); - new_character_from_preview(&mut char, preview); - match char.char_class { - CharacterClass::FOmar | CharacterClass::FOmarl| CharacterClass::FOnewm | CharacterClass::FOnewearl => char.techs.set_tech(Technique::Foie, TechLevel(1)), + //let mut character = entity_gateway.new_character_by_user(&user); + //new_character_from_preview(&mut char, preview); + let mut character = new_character_from_preview(user, preview); + match character.char_class { + CharacterClass::FOmar | CharacterClass::FOmarl| CharacterClass::FOnewm | CharacterClass::FOnewearl => character.techs.set_tech(Technique::Foie, TechLevel(1)), _ => {} } - entity_gateway.set_character(&char); + entity_gateway.set_character(&mut character); - let new_weapon = match char.char_class { + let new_weapon = match character.char_class { CharacterClass::HUmar | CharacterClass::HUnewearl | CharacterClass::HUcast | CharacterClass::HUcaseal => item::weapon::WeaponType::Saber, CharacterClass::RAmar | CharacterClass::RAmarl | CharacterClass::RAcast | CharacterClass::RAcaseal => item::weapon::WeaponType::Handgun, CharacterClass::FOmar | CharacterClass::FOmarl | CharacterClass::FOnewm | CharacterClass::FOnewearl => item::weapon::WeaponType::Cane, }; - entity_gateway.new_item( - ItemDetail::Weapon( - Weapon { - weapon: new_weapon, - grind: 0, - special: None, - attrs: [None; 3], - tekked: true, - }), - ItemLocation::Inventory { - character_id: char.id, - index: 0, - equipped: true, - }); - entity_gateway.new_item( - ItemDetail::Armor ( - Armor { - armor: item::armor::ArmorType::Frame, - dfp: 0, - evp: 0, - slots: 0, + entity_gateway.set_item( + &mut ItemEntity { + id: None, + item : ItemDetail::Weapon( + Weapon { + weapon: new_weapon, + grind: 0, + special: None, + attrs: [None; 3], + tekked: true, }), - ItemLocation::Inventory { - character_id: char.id, - index: 1, + location: ItemLocation::Inventory { + character_id: character.id.unwrap(), + index: 0, + equipped: true, + }}); + + entity_gateway.set_item( + &mut ItemEntity { + id: None, + item: ItemDetail::Armor ( + Armor { + armor: item::armor::ArmorType::Frame, + dfp: 0, + evp: 0, + slots: 0, + }), + location: ItemLocation::Inventory { + character_id: character.id.unwrap(), + index: 1, equipped: true, - }); - - entity_gateway.new_item( - ItemDetail::Mag( - Mag { - mag: MagType::Mag, - def: 500, - pow: 0, - dex: 0, - mnd: 0, - synchro: 20, - iq: 0, - photon_blast: [None; 3], - }), - ItemLocation::Inventory { - character_id: char.id, + }}); + + entity_gateway.set_item( + &mut ItemEntity { + id: None, + item: ItemDetail::Mag( + Mag { + mag: MagType::Mag, + def: 500, + pow: 0, + dex: 0, + mnd: 0, + synchro: 20, + iq: 0, + photon_blast: [None; 3], + }), + location: ItemLocation::Inventory { + character_id: character.id.unwrap(), index: 2, equipped: true, - }); + }}); for _ in 0..4 { - entity_gateway.new_item( - ItemDetail::Tool ( - Tool { - tool: item::tool::ToolType::Monomate, - }), - ItemLocation::Inventory { - character_id: char.id, - index: 3, - equipped: false, - }); - entity_gateway.new_item( - ItemDetail::Tool ( - Tool { - tool: item::tool::ToolType::Monofluid, - }), - ItemLocation::Inventory { - character_id: char.id, - index: 4, - equipped: false, - }); + entity_gateway.set_item( + &mut ItemEntity { + id: None, + item: ItemDetail::Tool ( + Tool { + tool: item::tool::ToolType::Monomate, + }), + location: ItemLocation::Inventory { + character_id: character.id.unwrap(), + index: 3, + equipped: false, + }}); + entity_gateway.set_item( + &mut ItemEntity { + id: None, + item: ItemDetail::Tool ( + Tool { + tool: item::tool::ToolType::Monofluid, + }), + location: ItemLocation::Inventory { + character_id: character.id.unwrap(), + index: 4, + equipped: false, + }}); } } @@ -333,7 +345,11 @@ impl CharacterServerState { // TODO: this should error (data should be added on account creation, why did I copy this silly sylv logic?) let settings = match self.entity_gateway.get_user_settings_by_user(&user) { Some(settings) => settings, - None => self.entity_gateway.create_user_settings_by_user(&user), + None => { + let mut user_settings = UserSettingsEntity::new(user.id.unwrap()); + self.entity_gateway.set_user_settings(&mut user_settings); + user_settings + } }; let pkt = SendKeyAndTeamSettings::new(settings.settings.key_config, @@ -421,7 +437,7 @@ impl CharacterServerState { let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; let mut user = client.user.as_mut().unwrap(); user.flags = setflag.flags; - self.entity_gateway.set_user(&user); + self.entity_gateway.set_user(&mut user); Ok(None.into_iter()) } @@ -459,7 +475,7 @@ impl CharacterServerState { client.session.action = SessionAction::SelectCharacter; client.session.character_slot = preview.slot as u8; user.flags = 0; - self.entity_gateway.set_user(&user); + self.entity_gateway.set_user(&mut user); Ok(vec![SendCharacterPacket::LoginResponse(LoginResponse::by_char_select(user.guildcard, user.team_id.unwrap_or(1), client.session)), @@ -552,7 +568,8 @@ impl ServerState for CharacterServerState { } -fn new_character_from_preview(character: &mut CharacterEntity, preview: &CharacterPreview) { +fn new_character_from_preview(user: &UserAccountEntity, preview: &CharacterPreview) -> CharacterEntity { + let mut character = CharacterEntity::new(user.id.unwrap()); character.slot = preview.slot; character.name = String::from_utf16_lossy(&preview.character.name).trim_matches(char::from(0)).into(); character.section_id = preview.character.section_id.into(); @@ -567,6 +584,7 @@ fn new_character_from_preview(character: &mut CharacterEntity, preview: &Charact character.appearance.hair_b = preview.character.hair_b; character.appearance.prop_x = preview.character.prop_x; character.appearance.prop_y = preview.character.prop_y; + character } @@ -636,7 +654,7 @@ impl<'a> SelectScreenCharacterBuilder<'a> { #[cfg(test)] mod test { use super::*; - use crate::entity::account::UserSettings; + use crate::entity::account::*; use libpso::character::{settings, character}; use std::time::SystemTime; use crate::entity::gateway::{InMemoryGateway}; @@ -647,10 +665,10 @@ mod test { } impl EntityGateway for TestData { - fn get_user_settings_by_user(&self, _user: &UserAccountEntity) -> Option { - Some(UserSettings { - id: 0, - user_id: 0, + fn get_user_settings_by_user(&self, user: &UserAccountEntity) -> Option { + Some(UserSettingsEntity { + id: Some(UserSettingsId(0)), + user_id: user.id.unwrap(), settings: settings::UserSettings::default() }) } @@ -659,7 +677,7 @@ mod test { let mut server = CharacterServerState::new(TestData {}); let mut clientstate = ClientState::new(); clientstate.user = Some(UserAccountEntity { - id: 1, + id: Some(UserAccountId(1)), username: "testuser".to_owned(), password: bcrypt::hash("mypassword", 5).unwrap(), guildcard: 0, @@ -701,7 +719,7 @@ mod test { let TestData = InMemoryGateway::new(); let mut fake_user = ClientState::new(); fake_user.user = Some(UserAccountEntity { - id: 3, + id: Some(UserAccountId(3)), username: "hi3".to_string(), password: bcrypt::hash("qwer", 5).unwrap(), guildcard: 3, @@ -715,7 +733,7 @@ mod test { let mut server = CharacterServerState::new(TestData.clone()); server.clients.insert(ClientId(1), fake_user.clone()); let mut send = server.handle(ClientId(1), &RecvCharacterPacket::SetFlag(SetFlag {flags: 1})).unwrap().collect::>(); - assert!(TestData.get_user_by_id(3).unwrap().flags == 1); + assert!(TestData.get_user_by_id(UserAccountId(3)).unwrap().flags == 1); send = server.handle(ClientId(1), &RecvCharacterPacket::CharacterPreview(CharacterPreview {slot: 1, character: character::SelectScreenCharacter { exp: 0, level: 0, diff --git a/src/login/login.rs b/src/login/login.rs index 6237dfe..349b745 100644 --- a/src/login/login.rs +++ b/src/login/login.rs @@ -14,7 +14,7 @@ use crate::common::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY}; use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId}; use crate::entity::gateway::EntityGateway; -use crate::entity::account::UserAccountEntity; +use crate::entity::account::{UserAccountId, UserAccountEntity}; pub const LOGIN_PORT: u16 = 12000; @@ -175,7 +175,7 @@ mod test { fn get_user_by_name(&self, name: String) -> Option { assert!(name == "testuser"); Some(UserAccountEntity { - id: 1, + id: Some(UserAccountId(1)), username: "testuser".to_owned(), password: bcrypt::hash("mypassword", 5).unwrap(), guildcard: 0, @@ -255,7 +255,7 @@ mod test { fn get_user_by_name(&self, name: String) -> Option { assert!(name == "testuser"); Some(UserAccountEntity { - id: 1, + id: Some(UserAccountId(1)), username: "testuser".to_owned(), password: bcrypt::hash("notpassword", 5).unwrap(), guildcard: 0, @@ -298,7 +298,7 @@ mod test { fn get_user_by_name(&self, name: String) -> Option { assert!(name == "testuser"); Some(UserAccountEntity { - id: 1, + id: Some(UserAccountId(1)), username: "testuser".to_owned(), password: bcrypt::hash("mypassword", 5).unwrap(), guildcard: 0, diff --git a/src/main.rs b/src/main.rs index 4035914..a6a41f0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,9 +18,10 @@ use patch::patch::{PatchServerState, generate_patch_tree, load_config, load_motd use login::login::LoginServerState; use login::character::CharacterServerState; use ship::ship::ShipServerState; -use entity::account::{UserAccountEntity, UserAccountId}; +use entity::account::{UserAccountEntity, UserSettingsEntity}; use entity::gateway::{EntityGateway, InMemoryGateway}; -use entity::item::ItemLocation; +use entity::character::CharacterEntity; +use entity::item::{ItemEntity, ItemDetail, ItemLocation}; use crate::entity::item; @@ -58,108 +59,48 @@ fn main() { setup_logger(); let mut entity_gateway = InMemoryGateway::new(); - let fake_user = UserAccountEntity { - id: UserAccountId(1), - username: "hi".to_string(), - password: bcrypt::hash("qwer", 5).unwrap(), - guildcard: 1u32, - team_id: None, - banned: false, - muted_until: SystemTime::now(), - created_at: SystemTime::now(), - flags: 0, - }; - entity_gateway.set_user(&fake_user); - entity_gateway.create_user_settings_by_user(&fake_user); - let mut character = entity_gateway.new_character_by_user(&fake_user); - character.name = "Test Char 1".into(); - entity_gateway.set_character(&character); - let mut character = entity_gateway.new_character_by_user(&fake_user); - character.slot = 2; - character.name = "\tE12345678".into(); - character.exp = 80000000; - entity_gateway.set_character(&character); - - entity_gateway.new_item( - item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 5, - special: None, - attrs: [None; 3], - tekked: true, - } - ), - ItemLocation::Inventory { - character_id: character.id, - index: 0, - equipped: true, - } - ); - - - let fake_user2 = UserAccountEntity { - id: UserAccountId(2), - username: "hi2".to_string(), - password: bcrypt::hash("qwer", 5).unwrap(), - guildcard: 2u32, - team_id: None, - banned: false, - muted_until: SystemTime::now(), - created_at: SystemTime::now(), - flags: 0, - }; - entity_gateway.set_user(&fake_user2); - entity_gateway.create_user_settings_by_user(&fake_user2); - let mut character = entity_gateway.new_character_by_user(&fake_user2); - character.name = "Test Char 3".into(); - entity_gateway.set_character(&character); - let mut character = entity_gateway.new_character_by_user(&fake_user2); - character.slot = 2; - character.name = "Test Char 4".into(); - entity_gateway.set_character(&character); - - let fake_user3 = UserAccountEntity { - id: UserAccountId(3), - username: "hi3".to_string(), - password: bcrypt::hash("qwer", 5).unwrap(), - guildcard: 3u32, - team_id: None, - banned: false, - muted_until: SystemTime::now(), - created_at: SystemTime::now(), - flags: 0, - }; - entity_gateway.set_user(&fake_user3); - entity_gateway.create_user_settings_by_user(&fake_user3); - let mut character = entity_gateway.new_character_by_user(&fake_user3); - character.name = "Test Char 5".into(); - entity_gateway.set_character(&character); - let mut character = entity_gateway.new_character_by_user(&fake_user3); - character.slot = 2; - character.name = "Test Char 6".into(); - entity_gateway.set_character(&character); - - let fake_user4 = UserAccountEntity { - id: UserAccountId(4), - username: "hi4".to_string(), - password: bcrypt::hash("qwer", 5).unwrap(), - guildcard: 4u32, - team_id: None, - banned: false, - muted_until: SystemTime::now(), - created_at: SystemTime::now(), - flags: 0, - }; - entity_gateway.set_user(&fake_user4); - entity_gateway.create_user_settings_by_user(&fake_user4); - let mut character = entity_gateway.new_character_by_user(&fake_user4); - character.name = "Test Char 7".into(); - entity_gateway.set_character(&character); - let mut character = entity_gateway.new_character_by_user(&fake_user4); - character.slot = 2; - character.name = "Test Char 8".into(); - entity_gateway.set_character(&character); + for i in 0..5 { + let mut fake_user = UserAccountEntity { + id: None, + username: if i == 0 { "hi".to_string() } else { format!("hi{}", i+1) }, + password: bcrypt::hash("qwer", 5).unwrap(), + guildcard: i + 1, + team_id: None, + banned: false, + muted_until: SystemTime::now(), + created_at: SystemTime::now(), + flags: 0, + }; + entity_gateway.set_user(&mut fake_user); + entity_gateway.set_user_settings(&mut UserSettingsEntity::new(fake_user.id.unwrap())); + let mut character = CharacterEntity::new(fake_user.id.unwrap()); + character.name = format!("Test Char {}", i*2); + entity_gateway.set_character(&mut character); + let mut character = CharacterEntity::new(fake_user.id.unwrap()); + character.slot = 2; + character.name = "\tE12345678".into(); + character.exp = 80000000; + entity_gateway.set_character(&mut character); + + entity_gateway.set_item( + &mut ItemEntity { + id: None, + item: ItemDetail::Weapon( + item::weapon::Weapon { + weapon: item::weapon::WeaponType::Handgun, + grind: 5, + special: None, + attrs: [None; 3], + tekked: true, + } + ), + location: ItemLocation::Inventory { + character_id: character.id.unwrap(), + index: 0, + equipped: true, + } + }); + } async_std::task::block_on(async move { let thread_entity_gateway = entity_gateway.clone(); diff --git a/src/ship/items.rs b/src/ship/items.rs index 77fd88f..617a699 100644 --- a/src/ship/items.rs +++ b/src/ship/items.rs @@ -178,7 +178,7 @@ mod test { #[test] fn test_stack_items() { let item1 = ItemEntity { - id: ItemEntityId(1), + id: Some(ItemEntityId(1)), location: ItemLocation::Inventory { character_id: CharacterEntityId(0), index: 0, @@ -193,7 +193,7 @@ mod test { }) }; let item2 = ItemEntity { - id: ItemEntityId(2), + id: Some(ItemEntityId(2)), location: ItemLocation::Inventory { character_id: CharacterEntityId(0), index: 1, @@ -204,7 +204,7 @@ mod test { }) }; let item3 = ItemEntity { - id: ItemEntityId(3), + id: Some(ItemEntityId(3)), location: ItemLocation::Inventory { character_id: CharacterEntityId(0), index: 2, @@ -218,8 +218,8 @@ mod test { tekked: true, }) }; - let item4 = ItemEntity { - id: ItemEntityId(4), + let item4 = ItemEntity { + id: Some(ItemEntityId(4)), location: ItemLocation::Inventory { character_id: CharacterEntityId(0), index: 1, @@ -230,7 +230,7 @@ mod test { }) }; let item5 = ItemEntity { - id: ItemEntityId(5), + id: Some(ItemEntityId(5)), location: ItemLocation::Inventory { character_id: CharacterEntityId(0), index: 1, @@ -241,7 +241,7 @@ mod test { }) }; let item6 = ItemEntity { - id: ItemEntityId(6), + id: Some(ItemEntityId(6)), location: ItemLocation::Inventory { character_id: CharacterEntityId(0), index: 3, @@ -256,7 +256,7 @@ mod test { }) }; let item7 = ItemEntity { - id: ItemEntityId(7), + id: Some(ItemEntityId(7)), location: ItemLocation::Inventory { character_id: CharacterEntityId(0), index: 4, @@ -267,7 +267,7 @@ mod test { }) }; let item8 = ItemEntity { - id: ItemEntityId(8), + id: Some(ItemEntityId(8)), location: ItemLocation::Inventory { character_id: CharacterEntityId(0), index: 4, @@ -278,7 +278,7 @@ mod test { }) }; let item9 = ItemEntity { - id: ItemEntityId(9), + id: Some(ItemEntityId(9)), location: ItemLocation::Inventory { character_id: CharacterEntityId(0), index: 4, diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 3ce13f8..fe1fcb4 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -171,7 +171,7 @@ impl ShipServerState { Ok(match get_login_status(&self.entity_gateway, pkt) { Ok(user) => { let mut response = LoginResponse::by_status(AccountStatus::Ok, Session::new()); - response.guildcard = user.id.0 as u32; + response.guildcard = user.id.unwrap().0 as u32; response.team_id = user.team_id.map_or(31, |ti| ti) as u32; let characters = self.entity_gateway.get_characters_by_user(&user); let character = characters @@ -233,7 +233,7 @@ impl ShipServerState { PlayerInfo { header: PlayerHeader { tag: 0x100, - guildcard: client.user.id.0, + guildcard: client.user.id.unwrap().0, _unknown1: [0; 5], client_id: room_client.index as u32, name: c.name, @@ -289,7 +289,7 @@ impl ShipServerState { playerinfo: PlayerInfo { header: PlayerHeader { tag: 0x100, - guildcard: client.user.id.0, + guildcard: client.user.id.unwrap().0, _unknown1: [0; 5], client_id: client_id as u32, name: c.name, @@ -336,7 +336,7 @@ impl ShipServerState { msg: GameMessage::GuildcardRecv(GuildcardRecv { client: guildcard_send.client, target: guildcard_send.target, - guildcard: client.user.id.0, + guildcard: client.user.id.unwrap().0, name: utf8_to_utf16_array!(client.character.name, 0x18), team: [0; 0x10], // TODO: teams not yet implemented desc: utf8_to_utf16_array!(client.character.guildcard.description, 0x58), @@ -365,7 +365,7 @@ impl ShipServerState { fn player_chat(&mut self, id: ClientId, msg: &PlayerChat) -> Result + Send>, ShipError> { let client = self.clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?; - let cmsg = PlayerChat::new(client.user.id.0, msg.message.clone()); + let cmsg = PlayerChat::new(client.user.id.unwrap().0, msg.message.clone()); Ok(Box::new(self.client_location.get_area_by_user(id).clients().iter() .map(move |client| { @@ -392,7 +392,7 @@ impl ShipServerState { let client = self.clients.get_mut(&id).unwrap();//.ok_or(ShipError::ClientNotFound(id)).unwrap(); let players = [PlayerHeader { tag: 0x00010000, - guildcard: client.user.id.0, + guildcard: client.user.id.unwrap().0, _unknown1: [0; 5], client_id: 0, name: libpso::utf8_to_utf16_array!(client.character.name, 16), @@ -434,7 +434,7 @@ impl ShipServerState { fn update_config(&mut self, id: ClientId, update_config: &UpdateConfig) -> Box + Send> { let client = self.clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap(); client.character.config.update(update_config); - self.entity_gateway.set_character(&client.character); + self.entity_gateway.set_character(&mut client.character); Box::new(None.into_iter()) } @@ -460,7 +460,7 @@ impl ShipServerState { 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); + self.entity_gateway.set_character(&mut client.character); Box::new(None.into_iter()) }