diff --git a/src/login/entities.rs b/src/entity/account.rs similarity index 82% rename from src/login/entities.rs rename to src/entity/account.rs index dc12aa6..3406f52 100644 --- a/src/login/entities.rs +++ b/src/entity/account.rs @@ -1,7 +1,6 @@ use std::time::SystemTime; use libpso::character::settings; -use libpso::character::character; use libpso::character::guildcard; pub const USERFLAG_NEWCHAR: u32 = 0x00000001; @@ -26,13 +25,6 @@ pub struct UserSettings { pub settings: settings::UserSettings, } -#[derive(Copy, Clone, Debug)] -pub struct Character { - pub id: u32, - pub user_id: u32, - pub character: character::Character, -} - pub struct GuildCardData { pub id: u32, pub user_id: u32, diff --git a/src/entity/character.rs b/src/entity/character.rs new file mode 100644 index 0000000..d682eba --- /dev/null +++ b/src/entity/character.rs @@ -0,0 +1,8 @@ +use libpso::character::character; + +#[derive(Copy, Clone, Debug)] +pub struct Character { + pub id: u32, + pub user_id: u32, + pub character: character::Character, +} diff --git a/src/entity/gateway/entitygateway.rs b/src/entity/gateway/entitygateway.rs new file mode 100644 index 0000000..9299cb4 --- /dev/null +++ b/src/entity/gateway/entitygateway.rs @@ -0,0 +1,36 @@ +use crate::entity::account::*; +use crate::entity::character::*; + +pub trait EntityGateway { + fn get_user_by_id(&self, _id: u32) -> Option { + unimplemented!(); + } + + fn get_user_by_name(&self, _username: String) -> Option { + unimplemented!(); + } + + fn set_user(&mut self, _user: &UserAccount) { + unimplemented!(); + } + + fn get_user_settings_by_user(&self, _user: &UserAccount) -> Option { + unimplemented!(); + } + + fn create_user_settings_by_user(&self, _user: &UserAccount) -> UserSettings { + unimplemented!(); + } + + fn get_characters_by_user(&self, _user: &UserAccount) -> [Option; 4] { + unimplemented!(); + } + + fn set_character_by_user(&mut self, _user: &UserAccount, _slot: u32, _char: Character) { + unimplemented!(); + } + + fn get_guild_card_data_by_user(&self, _user: &UserAccount) -> GuildCardData { + unimplemented!(); + } +} diff --git a/src/entity/gateway/mod.rs b/src/entity/gateway/mod.rs new file mode 100644 index 0000000..480cac3 --- /dev/null +++ b/src/entity/gateway/mod.rs @@ -0,0 +1,3 @@ +pub mod entitygateway; + +pub use entitygateway::EntityGateway; diff --git a/src/entity/item.rs b/src/entity/item.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/entity/mod.rs b/src/entity/mod.rs new file mode 100644 index 0000000..ba0b6e4 --- /dev/null +++ b/src/entity/mod.rs @@ -0,0 +1,4 @@ +pub mod gateway; +pub mod account; +pub mod character; +pub mod item; diff --git a/src/lib.rs b/src/lib.rs index 7871731..a1630e8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ #![feature(const_generics)] pub mod common; +pub mod entity; diff --git a/src/login/character.rs b/src/login/character.rs index 76df05c..01c247d 100644 --- a/src/login/character.rs +++ b/src/login/character.rs @@ -12,9 +12,11 @@ use elseware::common::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY}; use elseware::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId}; use elseware::{utf8_to_array, utf8_to_utf16_array}; -use crate::dataaccess::DataAccess; +use elseware::entity::gateway::EntityGateway; +use elseware::entity::account::{UserAccount, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM}; +use elseware::entity::character::Character; + use crate::login::get_login_status; -use crate::entities::{UserAccount, Character, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM}; pub const CHARACTER_PORT: u16 = 12001; @@ -143,20 +145,20 @@ impl ClientState { } } -pub struct CharacterServerState { - data_access: DA, +pub struct CharacterServerState { + entity_gateway: EG, param_header: ParamDataHeader, param_data: Vec, clients: HashMap, } -impl CharacterServerState { - pub fn new(data_access: DA) -> CharacterServerState { +impl CharacterServerState { + pub fn new(entity_gateway: EG) -> CharacterServerState { let (param_header, param_data) = generate_param_data("param/"); CharacterServerState { //shared_state: shared_state, - data_access: data_access, + entity_gateway: entity_gateway, param_header: param_header, param_data: param_data, clients: HashMap::new(), @@ -165,7 +167,7 @@ impl CharacterServerState { fn validate_login(&mut self, id: ClientId, pkt: &Login) -> Result, CharacterError> { let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; - Ok(match get_login_status(&self.data_access, pkt) { + Ok(match get_login_status(&self.entity_gateway, pkt) { Ok(user) => { let mut response = LoginResponse::by_status(AccountStatus::Ok, [0; 40]); response.guildcard = user.guildcard.map_or(0, |gc| gc) as u32; @@ -212,9 +214,9 @@ impl CharacterServerState { let user = client.user.as_ref().unwrap(); // TODO: this should error (data should be added on account creation, why did I copy this silly sylv logic?) - let settings = match self.data_access.get_user_settings_by_user(&user) { + let settings = match self.entity_gateway.get_user_settings_by_user(&user) { Some(settings) => settings, - None => self.data_access.create_user_settings_by_user(&user), + None => self.entity_gateway.create_user_settings_by_user(&user), }; let pkt = SendKeyAndTeamSettings::new(settings.settings.key_config, @@ -227,7 +229,7 @@ impl CharacterServerState { fn char_select(&mut self, id: ClientId, select: &CharSelect) -> Result, CharacterError> { let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; if client.characters.is_none() { - client.characters = Some(self.data_access.get_characters_by_user(client.user.as_ref().unwrap())); + client.characters = Some(self.entity_gateway.get_characters_by_user(client.user.as_ref().unwrap())); } if select.reason == 0 { @@ -273,7 +275,7 @@ impl CharacterServerState { fn guildcard_data_header(&mut self, id: ClientId) -> Result, CharacterError> { let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; - let guildcard_data = self.data_access.get_guild_card_data_by_user(client.user.as_ref().unwrap()); + let guildcard_data = self.entity_gateway.get_guild_card_data_by_user(client.user.as_ref().unwrap()); let bytes = guildcard_data.guildcard.as_bytes(); let mut crc = crc32::Digest::new(crc32::IEEE); @@ -301,7 +303,7 @@ impl CharacterServerState { } -impl ServerState for CharacterServerState { +impl ServerState for CharacterServerState { type SendPacket = SendCharacterPacket; type RecvPacket = RecvCharacterPacket; type PacketError = CharacterError; @@ -355,7 +357,7 @@ impl ServerState for CharacterServerState { let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; let mut user = client.user.as_mut().unwrap(); user.flags = flags.flags; - self.data_access.set_user(&user); + self.entity_gateway.set_user(&user); Box::new(None.into_iter()) }, RecvCharacterPacket::ParamDataChunkRequest(_request) => { @@ -386,7 +388,7 @@ impl ServerState for CharacterServerState { user_id: user.id, character: preview.character.as_character() }; - self.data_access.set_character_by_user(&user, preview.slot, char); + self.entity_gateway.set_character_by_user(&user, preview.slot, char); } if user.flags == USERFLAG_DRESSINGROOM { // TODO: dressing room stuff @@ -396,7 +398,7 @@ impl ServerState for CharacterServerState { client.security_data[4] = preview.slot as u8; client.security_data[5] = 1; user.flags = 0; - self.data_access.set_user(&user); + self.entity_gateway.set_user(&user); Box::new(vec![SendCharacterPacket::LoginResponse(LoginResponse::by_char_select(user.guildcard.unwrap_or(0), user.team_id.unwrap_or(0), client.security_data)), @@ -423,7 +425,7 @@ mod test { struct TestData { } - impl DataAccess for TestData { + impl EntityGateway for TestData { fn get_user_settings_by_user(&self, _user: &UserAccount) -> Option { Some(UserSettings { id: 0, @@ -462,7 +464,7 @@ mod test { #[test] fn test_user_checksum() { struct TestData; - impl DataAccess for TestData {} + impl EntityGateway for TestData {} let mut server = CharacterServerState::new(TestData {}); let send = server.handle(ClientId(1), &RecvCharacterPacket::Checksum(Checksum {flag: 0, checksum: 1234, diff --git a/src/login/dataaccess.rs b/src/login/dataaccess.rs deleted file mode 100644 index 43f1437..0000000 --- a/src/login/dataaccess.rs +++ /dev/null @@ -1,83 +0,0 @@ -use crate::entities::*; - -// TODO: should any of these be options? as in, what does failure look like -// TODO: determine best way to design this, current path will lead to 8493024039280x functions (probably?) -pub trait DataAccess { - fn get_user_by_id(&self, _id: u32) -> Option { - unimplemented!(); - } - - fn get_user_by_name(&self, _username: String) -> Option { - unimplemented!(); - } - - fn set_user(&mut self, _user: &UserAccount) { - unimplemented!(); - } - - fn get_user_settings_by_user(&self, _user: &UserAccount) -> Option { - unimplemented!(); - } - - fn create_user_settings_by_user(&self, _user: &UserAccount) -> UserSettings { - unimplemented!(); - } - - fn get_characters_by_user(&self, _user: &UserAccount) -> [Option; 4] { - unimplemented!(); - } - - fn set_character_by_user(&mut self, _user: &UserAccount, slot: u32, char: Character) { - unimplemented!(); - } - - fn get_guild_card_data_by_user(&self, _user: &UserAccount) -> GuildCardData { - unimplemented!(); - } -} - -/*#[derive(Clone)] -pub struct DBAccess { - connection_pool: ConnectionPool, -} - -impl DBAccess { - pub fn new(pool: ConnectionPool) -> DBAccess { - DBAccess { - connection_pool: pool, - } - } -} - -impl DataAccess for DBAccess { - fn get_user_by_name(&self, name: String) -> Option { - use elseware::schema::user_accounts::dsl::{user_accounts, username}; - self.connection_pool.get() - .map(|conn| { - user_accounts.filter(username.eq(name)).load::(&conn) - .map(|mut user| user.pop()).unwrap_or(None) - }) - .unwrap_or(None) - } - - fn get_user_settings_by_user(&self, user: &UserAccount) -> Option { - self.connection_pool.get() - .ok() - .and_then(|conn| { - UserSettings::belonging_to(user).first::(&conn).ok() - }) - } - - fn create_user_settings_by_user(&self, user: &UserAccount) -> UserSettings { - use elseware::schema::user_settings::dsl::user_settings; - self.connection_pool.get() - .map(|conn| { - let new_settings = NewUserSettings { - user_id: user.id, - settings: EUserSettings(settings::UserSettings::default()) - }; - diesel::insert_into(user_settings).values(&new_settings).get_result(&conn).unwrap() - }).unwrap() - } -} -*/ diff --git a/src/login/login.rs b/src/login/login.rs index 34e2a50..2936987 100644 --- a/src/login/login.rs +++ b/src/login/login.rs @@ -13,8 +13,10 @@ use elseware::common::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY}; use elseware::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId}; use elseware::common::util::array_to_utf8; -use crate::dataaccess::DataAccess; -use crate::entities::UserAccount; +//use crate::dataaccess::EntityGateway; +//use crate::entities::UserAccount; +use elseware::entity::gateway::EntityGateway; +use elseware::entity::account::UserAccount; pub const LOGIN_PORT: u16 = 12000; @@ -56,10 +58,10 @@ impl SendServerPacket for SendLoginPacket { } -pub fn get_login_status(data_access: &dyn DataAccess, pkt: &Login) -> Result { +pub fn get_login_status(entity_gateway: &dyn 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 = data_access.get_user_by_name(username).ok_or(AccountStatus::InvalidUser)?; + let user = entity_gateway.get_user_by_name(username).ok_or(AccountStatus::InvalidUser)?; let verified = bcrypt::verify(password, user.password.as_str()).map_err(|_err| AccountStatus::Error)?; match verified { true => Ok(user), @@ -68,19 +70,19 @@ pub fn get_login_status(data_access: &dyn DataAccess, pkt: &Login) -> Result { - data_access: DA, +pub struct LoginServerState { + entity_gateway: EG, } -impl LoginServerState { - pub fn new(data_access: DA) -> LoginServerState { +impl LoginServerState { + pub fn new(entity_gateway: EG) -> LoginServerState { LoginServerState { - data_access: data_access, + entity_gateway: entity_gateway, } } fn validate_login(&mut self, pkt: &Login) -> Vec { - match get_login_status(&self.data_access, pkt) { + match get_login_status(&self.entity_gateway, pkt) { Ok(_user) => { let response = SendLoginPacket::LoginResponse(LoginResponse::by_status(AccountStatus::Ok, pkt.security_data)); let ip = net::Ipv4Addr::new(127,0,0,1); @@ -95,7 +97,7 @@ impl LoginServerState { } } -impl ServerState for LoginServerState { +impl ServerState for LoginServerState { type SendPacket = SendLoginPacket; type RecvPacket = RecvLoginPacket; type PacketError = LoginError; @@ -157,7 +159,7 @@ mod test { struct TestData { } - impl DataAccess for TestData { + impl EntityGateway for TestData { fn get_user_by_name(&self, name: String) -> Option { assert!(name == "testuser"); Some(UserAccount { @@ -201,7 +203,7 @@ mod test { struct TestData { } - impl DataAccess for TestData { + impl EntityGateway for TestData { fn get_user_by_name(&self, _name: String) -> Option { None } @@ -228,7 +230,7 @@ mod test { struct TestData { } - impl DataAccess for TestData { + impl EntityGateway for TestData { fn get_user_by_name(&self, name: String) -> Option { assert!(name == "testuser"); Some(UserAccount { diff --git a/src/login/main.rs b/src/login/main.rs index 6df293a..47708c6 100644 --- a/src/login/main.rs +++ b/src/login/main.rs @@ -1,7 +1,5 @@ mod login; mod character; -mod dataaccess; -mod entities; use std::thread; use std::collections::HashMap; @@ -12,8 +10,9 @@ use libpso::character::settings; use libpso::character::character as pso_character; use libpso::character::guildcard; -use entities::{UserAccount, UserSettings, Character, GuildCardData}; -use dataaccess::DataAccess; +use elseware::entity::gateway::EntityGateway; +use elseware::entity::account::{UserAccount, UserSettings, GuildCardData}; +use elseware::entity::character::Character; use elseware::utf8_to_utf16_array; use login::LoginServerState; @@ -58,7 +57,7 @@ impl LoginStubData { } } -impl DataAccess for LoginStubData { +impl EntityGateway for LoginStubData { fn get_user_by_name(&self, username: String) -> Option { self.users.get(&username).map(|user| user.clone()) }