Browse Source

dataaccess -> entity gateway, move stuff around

pbs
jake 5 years ago
parent
commit
187fc18119
  1. 8
      src/entity/account.rs
  2. 8
      src/entity/character.rs
  3. 36
      src/entity/gateway/entitygateway.rs
  4. 3
      src/entity/gateway/mod.rs
  5. 0
      src/entity/item.rs
  6. 4
      src/entity/mod.rs
  7. 1
      src/lib.rs
  8. 38
      src/login/character.rs
  9. 83
      src/login/dataaccess.rs
  10. 30
      src/login/login.rs
  11. 9
      src/login/main.rs

8
src/login/entities.rs → src/entity/account.rs

@ -1,7 +1,6 @@
use std::time::SystemTime; use std::time::SystemTime;
use libpso::character::settings; use libpso::character::settings;
use libpso::character::character;
use libpso::character::guildcard; use libpso::character::guildcard;
pub const USERFLAG_NEWCHAR: u32 = 0x00000001; pub const USERFLAG_NEWCHAR: u32 = 0x00000001;
@ -26,13 +25,6 @@ pub struct UserSettings {
pub settings: settings::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 struct GuildCardData {
pub id: u32, pub id: u32,
pub user_id: u32, pub user_id: u32,

8
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,
}

36
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<UserAccount> {
unimplemented!();
}
fn get_user_by_name(&self, _username: String) -> Option<UserAccount> {
unimplemented!();
}
fn set_user(&mut self, _user: &UserAccount) {
unimplemented!();
}
fn get_user_settings_by_user(&self, _user: &UserAccount) -> Option<UserSettings> {
unimplemented!();
}
fn create_user_settings_by_user(&self, _user: &UserAccount) -> UserSettings {
unimplemented!();
}
fn get_characters_by_user(&self, _user: &UserAccount) -> [Option<Character>; 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!();
}
}

3
src/entity/gateway/mod.rs

@ -0,0 +1,3 @@
pub mod entitygateway;
pub use entitygateway::EntityGateway;

0
src/entity/item.rs

4
src/entity/mod.rs

@ -0,0 +1,4 @@
pub mod gateway;
pub mod account;
pub mod character;
pub mod item;

1
src/lib.rs

@ -1,3 +1,4 @@
#![feature(const_generics)] #![feature(const_generics)]
pub mod common; pub mod common;
pub mod entity;

38
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::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId};
use elseware::{utf8_to_array, utf8_to_utf16_array}; 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::login::get_login_status;
use crate::entities::{UserAccount, Character, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM};
pub const CHARACTER_PORT: u16 = 12001; pub const CHARACTER_PORT: u16 = 12001;
@ -143,20 +145,20 @@ impl ClientState {
} }
} }
pub struct CharacterServerState<DA: DataAccess> {
data_access: DA,
pub struct CharacterServerState<EG: EntityGateway> {
entity_gateway: EG,
param_header: ParamDataHeader, param_header: ParamDataHeader,
param_data: Vec<u8>, param_data: Vec<u8>,
clients: HashMap<ClientId, ClientState>, clients: HashMap<ClientId, ClientState>,
} }
impl<DA: DataAccess> CharacterServerState<DA> {
pub fn new(data_access: DA) -> CharacterServerState<DA> {
impl<EG: EntityGateway> CharacterServerState<EG> {
pub fn new(entity_gateway: EG) -> CharacterServerState<EG> {
let (param_header, param_data) = generate_param_data("param/"); let (param_header, param_data) = generate_param_data("param/");
CharacterServerState { CharacterServerState {
//shared_state: shared_state, //shared_state: shared_state,
data_access: data_access,
entity_gateway: entity_gateway,
param_header: param_header, param_header: param_header,
param_data: param_data, param_data: param_data,
clients: HashMap::new(), clients: HashMap::new(),
@ -165,7 +167,7 @@ impl<DA: DataAccess> CharacterServerState<DA> {
fn validate_login(&mut self, id: ClientId, pkt: &Login) -> Result<Vec<SendCharacterPacket>, CharacterError> { fn validate_login(&mut self, id: ClientId, pkt: &Login) -> Result<Vec<SendCharacterPacket>, CharacterError> {
let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; 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) => { Ok(user) => {
let mut response = LoginResponse::by_status(AccountStatus::Ok, [0; 40]); let mut response = LoginResponse::by_status(AccountStatus::Ok, [0; 40]);
response.guildcard = user.guildcard.map_or(0, |gc| gc) as u32; response.guildcard = user.guildcard.map_or(0, |gc| gc) as u32;
@ -212,9 +214,9 @@ impl<DA: DataAccess> CharacterServerState<DA> {
let user = client.user.as_ref().unwrap(); 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?) // 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, 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, let pkt = SendKeyAndTeamSettings::new(settings.settings.key_config,
@ -227,7 +229,7 @@ impl<DA: DataAccess> CharacterServerState<DA> {
fn char_select(&mut self, id: ClientId, select: &CharSelect) -> Result<Vec<SendCharacterPacket>, CharacterError> { fn char_select(&mut self, id: ClientId, select: &CharSelect) -> Result<Vec<SendCharacterPacket>, CharacterError> {
let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?;
if client.characters.is_none() { 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 { if select.reason == 0 {
@ -273,7 +275,7 @@ impl<DA: DataAccess> CharacterServerState<DA> {
fn guildcard_data_header(&mut self, id: ClientId) -> Result<Vec<SendCharacterPacket>, CharacterError> { fn guildcard_data_header(&mut self, id: ClientId) -> Result<Vec<SendCharacterPacket>, CharacterError> {
let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; 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 bytes = guildcard_data.guildcard.as_bytes();
let mut crc = crc32::Digest::new(crc32::IEEE); let mut crc = crc32::Digest::new(crc32::IEEE);
@ -301,7 +303,7 @@ impl<DA: DataAccess> CharacterServerState<DA> {
} }
impl<DA: DataAccess> ServerState for CharacterServerState<DA> {
impl<EG: EntityGateway> ServerState for CharacterServerState<EG> {
type SendPacket = SendCharacterPacket; type SendPacket = SendCharacterPacket;
type RecvPacket = RecvCharacterPacket; type RecvPacket = RecvCharacterPacket;
type PacketError = CharacterError; type PacketError = CharacterError;
@ -355,7 +357,7 @@ impl<DA: DataAccess> ServerState for CharacterServerState<DA> {
let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?;
let mut user = client.user.as_mut().unwrap(); let mut user = client.user.as_mut().unwrap();
user.flags = flags.flags; user.flags = flags.flags;
self.data_access.set_user(&user);
self.entity_gateway.set_user(&user);
Box::new(None.into_iter()) Box::new(None.into_iter())
}, },
RecvCharacterPacket::ParamDataChunkRequest(_request) => { RecvCharacterPacket::ParamDataChunkRequest(_request) => {
@ -386,7 +388,7 @@ impl<DA: DataAccess> ServerState for CharacterServerState<DA> {
user_id: user.id, user_id: user.id,
character: preview.character.as_character() 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 { if user.flags == USERFLAG_DRESSINGROOM {
// TODO: dressing room stuff // TODO: dressing room stuff
@ -396,7 +398,7 @@ impl<DA: DataAccess> ServerState for CharacterServerState<DA> {
client.security_data[4] = preview.slot as u8; client.security_data[4] = preview.slot as u8;
client.security_data[5] = 1; client.security_data[5] = 1;
user.flags = 0; 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), Box::new(vec![SendCharacterPacket::LoginResponse(LoginResponse::by_char_select(user.guildcard.unwrap_or(0),
user.team_id.unwrap_or(0), user.team_id.unwrap_or(0),
client.security_data)), client.security_data)),
@ -423,7 +425,7 @@ mod test {
struct TestData { struct TestData {
} }
impl DataAccess for TestData {
impl EntityGateway for TestData {
fn get_user_settings_by_user(&self, _user: &UserAccount) -> Option<UserSettings> { fn get_user_settings_by_user(&self, _user: &UserAccount) -> Option<UserSettings> {
Some(UserSettings { Some(UserSettings {
id: 0, id: 0,
@ -462,7 +464,7 @@ mod test {
#[test] #[test]
fn test_user_checksum() { fn test_user_checksum() {
struct TestData; struct TestData;
impl DataAccess for TestData {}
impl EntityGateway for TestData {}
let mut server = CharacterServerState::new(TestData {}); let mut server = CharacterServerState::new(TestData {});
let send = server.handle(ClientId(1), &RecvCharacterPacket::Checksum(Checksum {flag: 0, let send = server.handle(ClientId(1), &RecvCharacterPacket::Checksum(Checksum {flag: 0,
checksum: 1234, checksum: 1234,

83
src/login/dataaccess.rs

@ -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<UserAccount> {
unimplemented!();
}
fn get_user_by_name(&self, _username: String) -> Option<UserAccount> {
unimplemented!();
}
fn set_user(&mut self, _user: &UserAccount) {
unimplemented!();
}
fn get_user_settings_by_user(&self, _user: &UserAccount) -> Option<UserSettings> {
unimplemented!();
}
fn create_user_settings_by_user(&self, _user: &UserAccount) -> UserSettings {
unimplemented!();
}
fn get_characters_by_user(&self, _user: &UserAccount) -> [Option<Character>; 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<UserAccount> {
use elseware::schema::user_accounts::dsl::{user_accounts, username};
self.connection_pool.get()
.map(|conn| {
user_accounts.filter(username.eq(name)).load::<UserAccount>(&conn)
.map(|mut user| user.pop()).unwrap_or(None)
})
.unwrap_or(None)
}
fn get_user_settings_by_user(&self, user: &UserAccount) -> Option<UserSettings> {
self.connection_pool.get()
.ok()
.and_then(|conn| {
UserSettings::belonging_to(user).first::<UserSettings>(&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()
}
}
*/

30
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::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId};
use elseware::common::util::array_to_utf8; 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; 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<UserAccount, AccountStatus> {
pub fn get_login_status(entity_gateway: &dyn EntityGateway, pkt: &Login) -> Result<UserAccount, AccountStatus> {
let username = array_to_utf8(pkt.username).map_err(|_err| AccountStatus::Error)?; 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 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)?; let verified = bcrypt::verify(password, user.password.as_str()).map_err(|_err| AccountStatus::Error)?;
match verified { match verified {
true => Ok(user), true => Ok(user),
@ -68,19 +70,19 @@ pub fn get_login_status(data_access: &dyn DataAccess, pkt: &Login) -> Result<Use
} }
pub struct LoginServerState<DA: DataAccess> {
data_access: DA,
pub struct LoginServerState<EG: EntityGateway> {
entity_gateway: EG,
} }
impl<DA: DataAccess> LoginServerState<DA> {
pub fn new(data_access: DA) -> LoginServerState<DA> {
impl<EG: EntityGateway> LoginServerState<EG> {
pub fn new(entity_gateway: EG) -> LoginServerState<EG> {
LoginServerState { LoginServerState {
data_access: data_access,
entity_gateway: entity_gateway,
} }
} }
fn validate_login(&mut self, pkt: &Login) -> Vec<SendLoginPacket> { fn validate_login(&mut self, pkt: &Login) -> Vec<SendLoginPacket> {
match get_login_status(&self.data_access, pkt) {
match get_login_status(&self.entity_gateway, pkt) {
Ok(_user) => { Ok(_user) => {
let response = SendLoginPacket::LoginResponse(LoginResponse::by_status(AccountStatus::Ok, pkt.security_data)); let response = SendLoginPacket::LoginResponse(LoginResponse::by_status(AccountStatus::Ok, pkt.security_data));
let ip = net::Ipv4Addr::new(127,0,0,1); let ip = net::Ipv4Addr::new(127,0,0,1);
@ -95,7 +97,7 @@ impl<DA: DataAccess> LoginServerState<DA> {
} }
} }
impl<DA: DataAccess> ServerState for LoginServerState<DA> {
impl<EG: EntityGateway> ServerState for LoginServerState<EG> {
type SendPacket = SendLoginPacket; type SendPacket = SendLoginPacket;
type RecvPacket = RecvLoginPacket; type RecvPacket = RecvLoginPacket;
type PacketError = LoginError; type PacketError = LoginError;
@ -157,7 +159,7 @@ mod test {
struct TestData { struct TestData {
} }
impl DataAccess for TestData {
impl EntityGateway for TestData {
fn get_user_by_name(&self, name: String) -> Option<UserAccount> { fn get_user_by_name(&self, name: String) -> Option<UserAccount> {
assert!(name == "testuser"); assert!(name == "testuser");
Some(UserAccount { Some(UserAccount {
@ -201,7 +203,7 @@ mod test {
struct TestData { struct TestData {
} }
impl DataAccess for TestData {
impl EntityGateway for TestData {
fn get_user_by_name(&self, _name: String) -> Option<UserAccount> { fn get_user_by_name(&self, _name: String) -> Option<UserAccount> {
None None
} }
@ -228,7 +230,7 @@ mod test {
struct TestData { struct TestData {
} }
impl DataAccess for TestData {
impl EntityGateway for TestData {
fn get_user_by_name(&self, name: String) -> Option<UserAccount> { fn get_user_by_name(&self, name: String) -> Option<UserAccount> {
assert!(name == "testuser"); assert!(name == "testuser");
Some(UserAccount { Some(UserAccount {

9
src/login/main.rs

@ -1,7 +1,5 @@
mod login; mod login;
mod character; mod character;
mod dataaccess;
mod entities;
use std::thread; use std::thread;
use std::collections::HashMap; use std::collections::HashMap;
@ -12,8 +10,9 @@ use libpso::character::settings;
use libpso::character::character as pso_character; use libpso::character::character as pso_character;
use libpso::character::guildcard; 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 elseware::utf8_to_utf16_array;
use login::LoginServerState; 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<UserAccount> { fn get_user_by_name(&self, username: String) -> Option<UserAccount> {
self.users.get(&username).map(|user| user.clone()) self.users.get(&username).map(|user| user.clone())
} }

Loading…
Cancel
Save