From 177b6948706897e91c8cb6c950f56ab94d0df832 Mon Sep 17 00:00:00 2001 From: Andy Newjack Date: Sun, 22 Mar 2020 22:40:40 -0300 Subject: [PATCH] initial guildcard send/recv --- Cargo.toml | 2 ++ src/entity/account.rs | 9 +++++- src/entity/gateway/entitygateway.rs | 8 +++++ src/entity/gateway/inmemory.rs | 39 ++++++++++++++++++++++- src/login/character.rs | 10 +++--- src/login/login.rs | 6 ++-- src/main.rs | 16 +++++++--- src/ship/ship.rs | 49 ++++++++++++++++++++++++----- 8 files changed, 117 insertions(+), 22 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 09bf365..5daaee4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,3 +39,5 @@ byteorder = "1" enum-utils = "0.1.2" derive_more = { version = "0.99.3", features = ["display"]} +[patch."http://git.sharnoth.com/jake/libpso"] +libpso = { path = "../libpso" } \ No newline at end of file diff --git a/src/entity/account.rs b/src/entity/account.rs index 7c0274c..e0e5667 100644 --- a/src/entity/account.rs +++ b/src/entity/account.rs @@ -11,7 +11,7 @@ pub struct UserAccount { pub id: u32, pub username: String, pub password: String, - pub guildcard: Option, + pub guildcard: u32, pub team_id: Option, pub banned: bool, pub muted_until: SystemTime, @@ -32,3 +32,10 @@ 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/gateway/entitygateway.rs b/src/entity/gateway/entitygateway.rs index 359e095..edcc45c 100644 --- a/src/entity/gateway/entitygateway.rs +++ b/src/entity/gateway/entitygateway.rs @@ -52,4 +52,12 @@ pub trait EntityGateway { fn get_items_by_character(&self, _char: &Character) -> Vec { unimplemented!(); } + + fn create_guild_card_by_character(&self, _character: &Character) -> GuildCard { + unimplemented!(); + } + + fn get_guild_card_by_character(&self, _character: &Character) -> Option { + unimplemented!(); + } } diff --git a/src/entity/gateway/inmemory.rs b/src/entity/gateway/inmemory.rs index c302eba..a616ce4 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>>, - //guildcard: Arc>>, + guildcards: Arc>>, characters: Arc>>, items: Arc>>, } @@ -25,6 +25,7 @@ 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())), } @@ -142,4 +143,40 @@ impl EntityGateway for InMemoryGateway { }) .collect() } + + fn create_guild_card_by_character(&self, character: &Character) -> 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: &Character) -> Option { + let guildcards = self.guildcards.lock().unwrap(); + guildcards + .iter() + .find(|(_, k)| k.character_id == character.id) + .map(|(_, k)| k.clone()) + } } diff --git a/src/login/character.rs b/src/login/character.rs index b7efa66..129f306 100644 --- a/src/login/character.rs +++ b/src/login/character.rs @@ -281,7 +281,7 @@ impl CharacterServerState { Ok(match get_login_status(&self.entity_gateway, pkt) { Ok(user) => { let mut response = LoginResponse::by_status(AccountStatus::Ok, Session::new()); - response.guildcard = user.guildcard.map_or(0, |gc| gc) as u32; + response.guildcard = user.guildcard; response.team_id = user.team_id.map_or(0, |ti| ti) as u32; client.user = Some(user); client.session = pkt.session; @@ -352,7 +352,7 @@ impl CharacterServerState { let user = client.user.as_ref().unwrap(); client.session.action = SessionAction::SelectCharacter; client.session.character_slot = select.slot as u8; - Ok(vec![SendCharacterPacket::LoginResponse(LoginResponse::by_char_select(user.guildcard.unwrap_or(0), + Ok(vec![SendCharacterPacket::LoginResponse(LoginResponse::by_char_select(user.guildcard, user.team_id.unwrap_or(1), client.session)), SendCharacterPacket::CharAck(CharAck { @@ -440,7 +440,7 @@ impl CharacterServerState { client.session.character_slot = preview.slot as u8; user.flags = 0; self.entity_gateway.set_user(&user); - Ok(vec![SendCharacterPacket::LoginResponse(LoginResponse::by_char_select(user.guildcard.unwrap_or(0), + Ok(vec![SendCharacterPacket::LoginResponse(LoginResponse::by_char_select(user.guildcard, user.team_id.unwrap_or(1), client.session)), SendCharacterPacket::CharAck(CharAck { @@ -642,7 +642,7 @@ mod test { id: 1, username: "testuser".to_owned(), password: bcrypt::hash("mypassword", 5).unwrap(), - guildcard: None, + guildcard: 0, team_id: None, banned: false, muted_until: SystemTime::now(), @@ -684,7 +684,7 @@ mod test { id: 3, username: "hi3".to_string(), password: bcrypt::hash("qwer", 5).unwrap(), - guildcard: Some(3), + guildcard: 3, team_id: None, banned: false, muted_until: SystemTime::now(), diff --git a/src/login/login.rs b/src/login/login.rs index 07af784..e0feec7 100644 --- a/src/login/login.rs +++ b/src/login/login.rs @@ -178,7 +178,7 @@ mod test { id: 1, username: "testuser".to_owned(), password: bcrypt::hash("mypassword", 5).unwrap(), - guildcard: None, + guildcard: 0, team_id: None, banned: false, muted_until: SystemTime::now(), @@ -258,7 +258,7 @@ mod test { id: 1, username: "testuser".to_owned(), password: bcrypt::hash("notpassword", 5).unwrap(), - guildcard: None, + guildcard: 0, team_id: None, banned: false, muted_until: SystemTime::now(), @@ -301,7 +301,7 @@ mod test { id: 1, username: "testuser".to_owned(), password: bcrypt::hash("mypassword", 5).unwrap(), - guildcard: None, + guildcard: 0, team_id: None, banned: true, muted_until: SystemTime::now(), diff --git a/src/main.rs b/src/main.rs index a3fbfe7..105ad5a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -62,7 +62,7 @@ fn main() { id: 1, username: "hi".to_string(), password: bcrypt::hash("qwer", 5).unwrap(), - guildcard: Some(1), + guildcard: 1u32, team_id: None, banned: false, muted_until: SystemTime::now(), @@ -73,11 +73,13 @@ 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( @@ -102,7 +104,7 @@ fn main() { id: 2, username: "hi2".to_string(), password: bcrypt::hash("qwer", 5).unwrap(), - guildcard: Some(2), + guildcard: 2u32, team_id: None, banned: false, muted_until: SystemTime::now(), @@ -113,17 +115,19 @@ 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 { id: 3, username: "hi3".to_string(), password: bcrypt::hash("qwer", 5).unwrap(), - guildcard: Some(3), + guildcard: 3u32, team_id: None, banned: false, muted_until: SystemTime::now(), @@ -134,17 +138,19 @@ 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 { id: 4, username: "hi4".to_string(), password: bcrypt::hash("qwer", 5).unwrap(), - guildcard: Some(4), + guildcard: 4u32, team_id: None, banned: false, muted_until: SystemTime::now(), @@ -155,10 +161,12 @@ 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 ced4ba0..e64ad38 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -15,7 +15,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::{UserAccount, UserSettings, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM, GuildCard}; use crate::entity::character::Character; use crate::entity::item::{ItemLocation, Item}; use crate::login::login::get_login_status; @@ -119,18 +119,20 @@ struct ClientState { character: Character, session: Session, inventory: items::Inventory, + guildcard: GuildCard, //bank: Bank, block: u32, } impl ClientState { - fn new(user: UserAccount, settings: UserSettings, character: Character, inventory: items::Inventory, /*bank: Bank,*/ session: Session) -> ClientState { + fn new(user: UserAccount, settings: UserSettings, character: Character, inventory: items::Inventory, /*bank: Bank,*/ session: Session, guildcard: GuildCard) -> ClientState { ClientState { user: user, settings: settings, character: character, session: session, inventory: inventory, + guildcard: guildcard, //bank: bank, block: 1, } @@ -186,8 +188,10 @@ impl ShipServerState { let stacked_items = items::stack_items(inventory); let activated_items = stacked_items.into_iter().map(|item| self.item_activator.activate_item(item)).collect(); let inventory = items::Inventory::new(activated_items); + let guildcard = self.entity_gateway.get_guild_card_by_character(&character) + .ok_or(ShipError::ClientNotFound(id))?; - self.clients.insert(id, ClientState::new(user, settings, character, inventory, pkt.session)); + self.clients.insert(id, ClientState::new(user, settings, character, inventory, pkt.session, guildcard)); vec![SendShipPacket::LoginResponse(response), SendShipPacket::ShipBlockList(ShipBlockList::new(&self.name, 3))] }, Err(err) => { @@ -332,11 +336,40 @@ impl ShipServerState { fn direct_message(&mut self, id: ClientId, msg: &DirectMessage) -> Box + Send> { let cmsg = msg.clone(); - Box::new(self.client_location.get_area_by_user(id).clients().iter() - .filter(|client| client.index == cmsg.flag as usize) - .map(|client| { - (client.client_id, SendShipPacket::DirectMessage(cmsg.clone())) - }).collect::>().into_iter()) + 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) => { + 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, + one: 1, + language: gc.guildcard.language, + section_id: gc.guildcard.section_id, + class: gc.guildcard.class, + }), + }; + Box::new(self.client_location.get_area_by_user(id).clients().iter() + .filter(|client| client.index == cmsg.flag as usize) + .map(|client| { + (client.client_id, SendShipPacket::DirectMessage(out_msg.clone())) + }).collect::>().into_iter()) + }, + _ => { + Box::new(self.client_location.get_area_by_user(id).clients().iter() + .filter(|client| client.index == cmsg.flag as usize) + .map(|client| { + (client.client_id, SendShipPacket::DirectMessage(cmsg.clone())) + }).collect::>().into_iter()) + }, + } + } fn player_chat(&mut self, id: ClientId, msg: &PlayerChat) -> Result + Send>, ShipError> {