Merge pull request 'changes to entities' (#97) from entity_renaming into master
This commit is contained in:
commit
eb2cefa868
@ -6,9 +6,16 @@ use libpso::character::guildcard;
|
||||
pub const USERFLAG_NEWCHAR: u32 = 0x00000001;
|
||||
pub const USERFLAG_DRESSINGROOM: u32 = 0x00000002;
|
||||
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub struct UserAccountId(pub u32);
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub struct UserSettingsId(pub u32);
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub struct GuildCardDataId(pub u32);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct UserAccount {
|
||||
pub id: u32,
|
||||
pub struct UserAccountEntity {
|
||||
pub id: Option<UserAccountId>,
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
pub guildcard: u32,
|
||||
@ -19,23 +26,37 @@ pub struct UserAccount {
|
||||
pub flags: u32, // TODO: is this used for anything other than character creation?
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct UserSettings {
|
||||
pub id: u32,
|
||||
pub user_id: u32,
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct UserSettingsEntity {
|
||||
pub id: Option<UserSettingsId>,
|
||||
pub user_id: UserAccountId,
|
||||
pub settings: settings::UserSettings,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct GuildCardData {
|
||||
pub id: u32,
|
||||
pub user_id: u32,
|
||||
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: Option<GuildCardDataId>,
|
||||
pub user_id: UserAccountId,
|
||||
pub guildcard: guildcard::GuildCardData,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct GuildCard {
|
||||
pub id: u32,
|
||||
pub character_id: u32,
|
||||
pub guildcard: guildcard::GuildCard,
|
||||
}
|
||||
impl GuildCardDataEntity {
|
||||
pub fn new(user_id: UserAccountId) -> GuildCardDataEntity {
|
||||
GuildCardDataEntity {
|
||||
id: None,
|
||||
user_id: user_id,
|
||||
guildcard: guildcard::GuildCardData::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
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;
|
||||
use crate::entity::account::UserAccountId;
|
||||
|
||||
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub enum CharacterClass {
|
||||
@ -223,11 +223,19 @@ impl CharacterInfoboard {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct CharacterGuildCard {
|
||||
pub description: String,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct CharacterEntityId(pub u32);
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Character {
|
||||
pub id: u32,
|
||||
pub user_id: u32,
|
||||
pub struct CharacterEntity {
|
||||
pub id: Option<CharacterEntityId>,
|
||||
pub user_id: UserAccountId,
|
||||
pub slot: u32,
|
||||
|
||||
pub name: String,
|
||||
@ -240,13 +248,14 @@ pub struct Character {
|
||||
pub techs: CharacterTechniques,
|
||||
pub config: CharacterConfig,
|
||||
pub info_board: CharacterInfoboard,
|
||||
pub guildcard: CharacterGuildCard,
|
||||
}
|
||||
|
||||
impl std::default::Default for Character {
|
||||
fn default() -> Character {
|
||||
Character {
|
||||
id: 0,
|
||||
user_id: 0,
|
||||
impl CharacterEntity {
|
||||
pub fn new(user: UserAccountId) -> CharacterEntity {
|
||||
CharacterEntity {
|
||||
id: None,
|
||||
user_id: user,
|
||||
slot: 0,
|
||||
name: "".into(),
|
||||
exp: 0,
|
||||
@ -256,6 +265,7 @@ impl std::default::Default for Character {
|
||||
techs: CharacterTechniques::new(),
|
||||
config: CharacterConfig::new(),
|
||||
info_board: CharacterInfoboard::new(),
|
||||
guildcard: CharacterGuildCard::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,59 +5,43 @@ use crate::entity::item::*;
|
||||
use libpso::item;
|
||||
|
||||
pub trait EntityGateway {
|
||||
fn get_user_by_id(&self, _id: u32) -> Option<UserAccount> {
|
||||
fn get_user_by_id(&self, _id: UserAccountId) -> Option<UserAccountEntity> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn get_user_by_name(&self, _username: String) -> Option<UserAccount> {
|
||||
fn get_user_by_name(&self, _username: String) -> Option<UserAccountEntity> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn set_user(&mut self, _user: &UserAccount) {
|
||||
fn set_user(&mut self, _user: &mut UserAccountEntity) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn get_user_settings_by_user(&self, _user: &UserAccount) -> Option<UserSettings> {
|
||||
fn get_user_settings_by_user(&self, _user: &UserAccountEntity) -> Option<UserSettingsEntity> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn create_user_settings_by_user(&self, _user: &UserAccount) -> UserSettings {
|
||||
fn set_user_settings(&mut self, _settings: &mut UserSettingsEntity) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn get_characters_by_user(&self, _user: &UserAccount) -> [Option<Character>; 4] {
|
||||
fn get_characters_by_user(&self, _user: &UserAccountEntity) -> [Option<CharacterEntity>; 4] {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn set_character(&mut self, _char: &Character) {
|
||||
fn set_character(&mut self, _char: &mut CharacterEntity) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn new_character_by_user(&mut self, _user: &UserAccount) -> Character {
|
||||
fn get_guild_card_data_by_user(&self, _user: &UserAccountEntity) -> GuildCardDataEntity {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn get_guild_card_data_by_user(&self, _user: &UserAccount) -> GuildCardData {
|
||||
fn set_item(&mut self, _item: &mut ItemEntity) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn new_item(&mut self, _item: ItemDetail, _location: ItemLocation) -> Item {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn set_item(&self, _item: &Item) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn get_items_by_character(&self, _char: &Character) -> Vec<Item> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn create_guild_card_by_character(&self, _character: &Character) -> GuildCard {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn get_guild_card_by_character(&self, _character: &Character) -> Option<GuildCard> {
|
||||
fn get_items_by_character(&self, _char: &CharacterEntity) -> Vec<ItemEntity> {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
@ -13,11 +13,10 @@ use std::sync::{Arc, Mutex};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct InMemoryGateway {
|
||||
users: Arc<Mutex<HashMap<u32, UserAccount>>>,
|
||||
user_settings: Arc<Mutex<HashMap<u32, UserSettings>>>,
|
||||
guildcards: Arc<Mutex<HashMap<u32, GuildCard>>>,
|
||||
characters: Arc<Mutex<HashMap<u32, Character>>>,
|
||||
items: Arc<Mutex<HashMap<ItemEntityId, Item>>>,
|
||||
users: Arc<Mutex<HashMap<UserAccountId, UserAccountEntity>>>,
|
||||
user_settings: Arc<Mutex<HashMap<UserSettingsId, UserSettingsEntity>>>,
|
||||
characters: Arc<Mutex<HashMap<CharacterEntityId, CharacterEntity>>>,
|
||||
items: Arc<Mutex<HashMap<ItemEntityId, ItemEntity>>>,
|
||||
}
|
||||
|
||||
impl InMemoryGateway {
|
||||
@ -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())),
|
||||
}
|
||||
@ -33,12 +31,12 @@ impl InMemoryGateway {
|
||||
}
|
||||
|
||||
impl EntityGateway for InMemoryGateway {
|
||||
fn get_user_by_id(&self, id: u32) -> Option<UserAccount> {
|
||||
fn get_user_by_id(&self, id: UserAccountId) -> Option<UserAccountEntity> {
|
||||
let users = self.users.lock().unwrap();
|
||||
users.get(&id).map(|k| k.clone())
|
||||
}
|
||||
|
||||
fn get_user_by_name(&self, username: String) -> Option<UserAccount> {
|
||||
fn get_user_by_name(&self, username: String) -> Option<UserAccountEntity> {
|
||||
let users = self.users.lock().unwrap();
|
||||
users
|
||||
.iter()
|
||||
@ -46,95 +44,85 @@ impl EntityGateway for InMemoryGateway {
|
||||
.map(|(_, k)| k.clone())
|
||||
}
|
||||
|
||||
fn set_user(&mut self, user: &UserAccount) {
|
||||
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: &UserAccount) -> Option<UserSettings> {
|
||||
fn get_user_settings_by_user(&self, user: &UserAccountEntity) -> Option<UserSettingsEntity> {
|
||||
let user_settings = self.user_settings.lock().unwrap();
|
||||
user_settings
|
||||
.iter()
|
||||
.find(|(_, k)| k.id == user.id)
|
||||
.find(|(_, k)| k.user_id == user.id.unwrap())
|
||||
.map(|(_, k)| k.clone())
|
||||
}
|
||||
|
||||
fn create_user_settings_by_user(&self, user: &UserAccount) -> UserSettings {
|
||||
|
||||
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))
|
||||
+ 1;
|
||||
let new_settings = UserSettings {
|
||||
id: id,
|
||||
user_id: user.id,
|
||||
settings: settings::UserSettings::default(),
|
||||
};
|
||||
user_settings.insert(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: &UserAccount) -> [Option<Character>; 4] {
|
||||
fn get_characters_by_user(&self, user: &UserAccountEntity) -> [Option<CharacterEntity>; 4] {
|
||||
let characters = self.characters.lock().unwrap();
|
||||
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: &UserAccount) -> Character {
|
||||
fn set_character(&mut self, char: &mut 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();
|
||||
c.id = id;
|
||||
c.user_id = user.id;
|
||||
characters.insert(id, c.clone());
|
||||
c
|
||||
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 set_character(&mut self, char: &Character) {
|
||||
let mut characters = self.characters.lock().unwrap();
|
||||
characters.insert(char.id, char.clone());
|
||||
fn get_guild_card_data_by_user(&self, user: &UserAccountEntity) -> GuildCardDataEntity {
|
||||
GuildCardDataEntity::new(user.id.unwrap())
|
||||
}
|
||||
|
||||
fn get_guild_card_data_by_user(&self, _user: &UserAccount) -> GuildCardData {
|
||||
GuildCardData::default()
|
||||
}
|
||||
|
||||
fn new_item(&mut self, item: ItemDetail, location: ItemLocation) -> Item {
|
||||
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 = Item {
|
||||
id: ItemEntityId(id),
|
||||
location: location,
|
||||
item: item,
|
||||
};
|
||||
items.insert(ItemEntityId(id), new_item.clone());
|
||||
new_item
|
||||
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 set_item(&self, item: &Item) {
|
||||
let mut items = self.items.lock().unwrap();
|
||||
items.insert(item.id, item.clone());
|
||||
}
|
||||
|
||||
fn get_items_by_character(&self, character: &Character) -> Vec<Item> {
|
||||
fn get_items_by_character(&self, character: &CharacterEntity) -> Vec<ItemEntity> {
|
||||
let items = self.items.lock().unwrap();
|
||||
items
|
||||
.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
|
||||
}
|
||||
})
|
||||
@ -143,40 +131,4 @@ 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<GuildCard> {
|
||||
let guildcards = self.guildcards.lock().unwrap();
|
||||
guildcards
|
||||
.iter()
|
||||
.find(|(_, k)| k.character_id == character.id)
|
||||
.map(|(_, k)| k.clone())
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
@ -84,8 +87,8 @@ impl ItemDetail {
|
||||
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Item {
|
||||
pub id: ItemEntityId,
|
||||
pub struct ItemEntity {
|
||||
pub id: Option<ItemEntityId>,
|
||||
pub location: ItemLocation,
|
||||
pub item: ItemDetail,
|
||||
}
|
||||
|
@ -16,14 +16,14 @@ 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::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;
|
||||
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;
|
||||
|
||||
@ -142,8 +142,8 @@ fn generate_param_data(path: &str) -> (ParamDataHeader, Vec<u8>) {
|
||||
#[derive(Clone)]
|
||||
struct ClientState {
|
||||
param_index: usize,
|
||||
user: Option<UserAccount>,
|
||||
characters: Option<[Option<Character>; 4]>,
|
||||
user: Option<UserAccountEntity>,
|
||||
characters: Option<[Option<CharacterEntity>; 4]>,
|
||||
guildcard_data_buffer: Option<Vec<u8>>,
|
||||
session: Session,
|
||||
}
|
||||
@ -189,90 +189,102 @@ pub struct CharacterServerState<EG: EntityGateway> {
|
||||
}
|
||||
|
||||
|
||||
fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccount, 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)),
|
||||
fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountEntity, preview: &CharacterPreview) {
|
||||
//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,
|
||||
entity_gateway.set_item(
|
||||
&mut ItemEntity {
|
||||
id: None,
|
||||
item : ItemDetail::Weapon(
|
||||
Weapon {
|
||||
weapon: new_weapon,
|
||||
grind: 0,
|
||||
special: None,
|
||||
attrs: [None; 3],
|
||||
tekked: true,
|
||||
}),
|
||||
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,
|
||||
}),
|
||||
ItemLocation::Inventory {
|
||||
character_id: char.id,
|
||||
index: 1,
|
||||
}),
|
||||
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<EG: EntityGateway> CharacterServerState<EG> {
|
||||
// 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<EG: EntityGateway> CharacterServerState<EG> {
|
||||
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<EG: EntityGateway> CharacterServerState<EG> {
|
||||
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<EG: EntityGateway> ServerState for CharacterServerState<EG> {
|
||||
}
|
||||
|
||||
|
||||
fn new_character_from_preview(character: &mut Character, 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,11 +584,12 @@ fn new_character_from_preview(character: &mut Character, preview: &CharacterPrev
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
struct SelectScreenCharacterBuilder<'a> {
|
||||
character: Option<&'a Character>,
|
||||
character: Option<&'a CharacterEntity>,
|
||||
level: Option<u32>,
|
||||
}
|
||||
|
||||
@ -583,7 +601,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
|
||||
@ -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: &UserAccount) -> Option<UserSettings> {
|
||||
Some(UserSettings {
|
||||
id: 0,
|
||||
user_id: 0,
|
||||
fn get_user_settings_by_user(&self, user: &UserAccountEntity) -> Option<UserSettingsEntity> {
|
||||
Some(UserSettingsEntity {
|
||||
id: Some(UserSettingsId(0)),
|
||||
user_id: user.id.unwrap(),
|
||||
settings: settings::UserSettings::default()
|
||||
})
|
||||
}
|
||||
@ -658,8 +676,8 @@ mod test {
|
||||
|
||||
let mut server = CharacterServerState::new(TestData {});
|
||||
let mut clientstate = ClientState::new();
|
||||
clientstate.user = Some(UserAccount {
|
||||
id: 1,
|
||||
clientstate.user = Some(UserAccountEntity {
|
||||
id: Some(UserAccountId(1)),
|
||||
username: "testuser".to_owned(),
|
||||
password: bcrypt::hash("mypassword", 5).unwrap(),
|
||||
guildcard: 0,
|
||||
@ -700,8 +718,8 @@ mod test {
|
||||
fn test_character_create() {
|
||||
let TestData = InMemoryGateway::new();
|
||||
let mut fake_user = ClientState::new();
|
||||
fake_user.user = Some(UserAccount {
|
||||
id: 3,
|
||||
fake_user.user = Some(UserAccountEntity {
|
||||
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::<Vec<_>>();
|
||||
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,
|
||||
|
@ -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::{UserAccountId, 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<UserAccount, AccountStatus> {
|
||||
pub fn get_login_status(entity_gateway: &impl EntityGateway, pkt: &Login) -> Result<UserAccountEntity, AccountStatus> {
|
||||
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,10 +172,10 @@ mod test {
|
||||
}
|
||||
|
||||
impl EntityGateway for TestData {
|
||||
fn get_user_by_name(&self, name: String) -> Option<UserAccount> {
|
||||
fn get_user_by_name(&self, name: String) -> Option<UserAccountEntity> {
|
||||
assert!(name == "testuser");
|
||||
Some(UserAccount {
|
||||
id: 1,
|
||||
Some(UserAccountEntity {
|
||||
id: Some(UserAccountId(1)),
|
||||
username: "testuser".to_owned(),
|
||||
password: bcrypt::hash("mypassword", 5).unwrap(),
|
||||
guildcard: 0,
|
||||
@ -220,7 +220,7 @@ mod test {
|
||||
}
|
||||
|
||||
impl EntityGateway for TestData {
|
||||
fn get_user_by_name(&self, _name: String) -> Option<UserAccount> {
|
||||
fn get_user_by_name(&self, _name: String) -> Option<UserAccountEntity> {
|
||||
None
|
||||
}
|
||||
}
|
||||
@ -252,10 +252,10 @@ mod test {
|
||||
}
|
||||
|
||||
impl EntityGateway for TestData {
|
||||
fn get_user_by_name(&self, name: String) -> Option<UserAccount> {
|
||||
fn get_user_by_name(&self, name: String) -> Option<UserAccountEntity> {
|
||||
assert!(name == "testuser");
|
||||
Some(UserAccount {
|
||||
id: 1,
|
||||
Some(UserAccountEntity {
|
||||
id: Some(UserAccountId(1)),
|
||||
username: "testuser".to_owned(),
|
||||
password: bcrypt::hash("notpassword", 5).unwrap(),
|
||||
guildcard: 0,
|
||||
@ -295,10 +295,10 @@ mod test {
|
||||
}
|
||||
|
||||
impl EntityGateway for TestData {
|
||||
fn get_user_by_name(&self, name: String) -> Option<UserAccount> {
|
||||
fn get_user_by_name(&self, name: String) -> Option<UserAccountEntity> {
|
||||
assert!(name == "testuser");
|
||||
Some(UserAccount {
|
||||
id: 1,
|
||||
Some(UserAccountEntity {
|
||||
id: Some(UserAccountId(1)),
|
||||
username: "testuser".to_owned(),
|
||||
password: bcrypt::hash("mypassword", 5).unwrap(),
|
||||
guildcard: 0,
|
||||
|
155
src/main.rs
155
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::UserAccount;
|
||||
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,116 +59,48 @@ fn main() {
|
||||
setup_logger();
|
||||
let mut entity_gateway = InMemoryGateway::new();
|
||||
|
||||
let fake_user = UserAccount {
|
||||
id: 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.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);
|
||||
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.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 = UserAccount {
|
||||
id: 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.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: 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.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: 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.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);
|
||||
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();
|
||||
|
@ -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<u32>,
|
||||
}
|
||||
@ -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<u32>,
|
||||
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
|
||||
|
@ -3,8 +3,8 @@ use std::collections::HashMap;
|
||||
use libpso::character::character::InventoryItem;
|
||||
|
||||
use crate::entity::gateway::EntityGateway;
|
||||
use crate::entity::character::Character;
|
||||
use crate::entity::item::{Item, ItemId, ItemDetail, ItemLocation};
|
||||
use crate::entity::character::CharacterEntity;
|
||||
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<Item>),
|
||||
Individual(ItemEntity),
|
||||
Stacked(Vec<ItemEntity>),
|
||||
}
|
||||
|
||||
#[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<Item>) -> Vec<StackedItem> {
|
||||
fn stack_items(items: Vec<ItemEntity>) -> Vec<StackedItem> {
|
||||
let mut stacks = HashMap::new();
|
||||
|
||||
for item in items {
|
||||
@ -151,7 +151,7 @@ impl ActiveItemDatabase {
|
||||
|
||||
// deactivate item
|
||||
|
||||
pub fn get_character_inventory<EG: EntityGateway>(&mut self, entity_gateway: &mut EG, character: &Character) -> ActiveInventory {
|
||||
pub fn get_character_inventory<EG: EntityGateway>(&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| {
|
||||
@ -172,14 +172,15 @@ 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};
|
||||
use crate::entity::item::{ItemEntity, ItemDetail, ItemEntityId, ItemLocation};
|
||||
#[test]
|
||||
fn test_stack_items() {
|
||||
let item1 = Item {
|
||||
id: ItemEntityId(1),
|
||||
let item1 = ItemEntity {
|
||||
id: Some(ItemEntityId(1)),
|
||||
location: ItemLocation::Inventory {
|
||||
character_id: 0,
|
||||
character_id: CharacterEntityId(0),
|
||||
index: 0,
|
||||
equipped: false,
|
||||
},
|
||||
@ -191,10 +192,10 @@ mod test {
|
||||
tekked: true,
|
||||
})
|
||||
};
|
||||
let item2 = Item {
|
||||
id: ItemEntityId(2),
|
||||
let item2 = ItemEntity {
|
||||
id: Some(ItemEntityId(2)),
|
||||
location: ItemLocation::Inventory {
|
||||
character_id: 0,
|
||||
character_id: CharacterEntityId(0),
|
||||
index: 1,
|
||||
equipped: false,
|
||||
},
|
||||
@ -202,10 +203,10 @@ mod test {
|
||||
tool: item::tool::ToolType::Monofluid,
|
||||
})
|
||||
};
|
||||
let item3 = Item {
|
||||
id: ItemEntityId(3),
|
||||
let item3 = ItemEntity {
|
||||
id: Some(ItemEntityId(3)),
|
||||
location: ItemLocation::Inventory {
|
||||
character_id: 0,
|
||||
character_id: CharacterEntityId(0),
|
||||
index: 2,
|
||||
equipped: false,
|
||||
},
|
||||
@ -217,10 +218,10 @@ mod test {
|
||||
tekked: true,
|
||||
})
|
||||
};
|
||||
let item4 = Item {
|
||||
id: ItemEntityId(4),
|
||||
let item4 = ItemEntity {
|
||||
id: Some(ItemEntityId(4)),
|
||||
location: ItemLocation::Inventory {
|
||||
character_id: 0,
|
||||
character_id: CharacterEntityId(0),
|
||||
index: 1,
|
||||
equipped: false,
|
||||
},
|
||||
@ -228,10 +229,10 @@ mod test {
|
||||
tool: item::tool::ToolType::Monofluid,
|
||||
})
|
||||
};
|
||||
let item5 = Item {
|
||||
id: ItemEntityId(5),
|
||||
let item5 = ItemEntity {
|
||||
id: Some(ItemEntityId(5)),
|
||||
location: ItemLocation::Inventory {
|
||||
character_id: 0,
|
||||
character_id: CharacterEntityId(0),
|
||||
index: 1,
|
||||
equipped: false,
|
||||
},
|
||||
@ -239,10 +240,10 @@ mod test {
|
||||
tool: item::tool::ToolType::Monofluid,
|
||||
})
|
||||
};
|
||||
let item6 = Item {
|
||||
id: ItemEntityId(6),
|
||||
let item6 = ItemEntity {
|
||||
id: Some(ItemEntityId(6)),
|
||||
location: ItemLocation::Inventory {
|
||||
character_id: 0,
|
||||
character_id: CharacterEntityId(0),
|
||||
index: 3,
|
||||
equipped: false,
|
||||
},
|
||||
@ -254,10 +255,10 @@ mod test {
|
||||
tekked: true,
|
||||
})
|
||||
};
|
||||
let item7 = Item {
|
||||
id: ItemEntityId(7),
|
||||
let item7 = ItemEntity {
|
||||
id: Some(ItemEntityId(7)),
|
||||
location: ItemLocation::Inventory {
|
||||
character_id: 0,
|
||||
character_id: CharacterEntityId(0),
|
||||
index: 4,
|
||||
equipped: false,
|
||||
},
|
||||
@ -265,10 +266,10 @@ mod test {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
})
|
||||
};
|
||||
let item8 = Item {
|
||||
id: ItemEntityId(8),
|
||||
let item8 = ItemEntity {
|
||||
id: Some(ItemEntityId(8)),
|
||||
location: ItemLocation::Inventory {
|
||||
character_id: 0,
|
||||
character_id: CharacterEntityId(0),
|
||||
index: 4,
|
||||
equipped: false,
|
||||
},
|
||||
@ -276,10 +277,10 @@ mod test {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
})
|
||||
};
|
||||
let item9 = Item {
|
||||
id: ItemEntityId(9),
|
||||
let item9 = ItemEntity {
|
||||
id: Some(ItemEntityId(9)),
|
||||
location: ItemLocation::Inventory {
|
||||
character_id: 0,
|
||||
character_id: CharacterEntityId(0),
|
||||
index: 4,
|
||||
equipped: false,
|
||||
},
|
||||
|
@ -10,15 +10,16 @@ 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::character::Character;
|
||||
use crate::entity::item::{ItemLocation, Item};
|
||||
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;
|
||||
use crate::ship::location::{ClientLocation, LobbyId, RoomId, AreaType, MAX_ROOMS};
|
||||
use crate::ship::character::{CharacterBytesBuilder, FullCharacterBytesBuilder};
|
||||
@ -118,25 +119,24 @@ impl SendServerPacket for SendShipPacket {
|
||||
}
|
||||
|
||||
struct ClientState {
|
||||
user: UserAccount,
|
||||
settings: UserSettings,
|
||||
character: Character,
|
||||
user: UserAccountEntity,
|
||||
settings: UserSettingsEntity,
|
||||
character: CharacterEntity,
|
||||
session: Session,
|
||||
guildcard: GuildCard,
|
||||
//guildcard: GuildCard,
|
||||
inventory: items::ActiveInventory,
|
||||
//bank: Bank,
|
||||
block: u32,
|
||||
}
|
||||
|
||||
impl ClientState {
|
||||
fn new(user: UserAccount, settings: UserSettings, character: Character, inventory: items::ActiveInventory, /*bank: Bank,*/ session: Session, guildcard: GuildCard) -> ClientState {
|
||||
fn new(user: UserAccountEntity, settings: UserSettingsEntity, 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,
|
||||
}
|
||||
@ -171,7 +171,7 @@ impl<EG: EntityGateway> ShipServerState<EG> {
|
||||
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.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
|
||||
@ -181,11 +181,9 @@ impl<EG: EntityGateway> ShipServerState<EG> {
|
||||
.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) => {
|
||||
@ -235,7 +233,7 @@ impl<EG: EntityGateway> ShipServerState<EG> {
|
||||
PlayerInfo {
|
||||
header: PlayerHeader {
|
||||
tag: 0x100,
|
||||
guildcard: client.user.id,
|
||||
guildcard: client.user.id.unwrap().0,
|
||||
_unknown1: [0; 5],
|
||||
client_id: room_client.index as u32,
|
||||
name: c.name,
|
||||
@ -291,7 +289,7 @@ impl<EG: EntityGateway> ShipServerState<EG> {
|
||||
playerinfo: PlayerInfo {
|
||||
header: PlayerHeader {
|
||||
tag: 0x100,
|
||||
guildcard: client.user.id,
|
||||
guildcard: client.user.id.unwrap().0,
|
||||
_unknown1: [0; 5],
|
||||
client_id: client_id as u32,
|
||||
name: c.name,
|
||||
@ -331,22 +329,21 @@ impl<EG: EntityGateway> ShipServerState<EG> {
|
||||
fn direct_message(&mut self, id: ClientId, msg: &DirectMessage) -> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + 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.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),
|
||||
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()
|
||||
@ -368,7 +365,7 @@ impl<EG: EntityGateway> ShipServerState<EG> {
|
||||
|
||||
fn player_chat(&mut self, id: ClientId, msg: &PlayerChat) -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + 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.unwrap().0, msg.message.clone());
|
||||
|
||||
Ok(Box::new(self.client_location.get_area_by_user(id).clients().iter()
|
||||
.map(move |client| {
|
||||
@ -395,7 +392,7 @@ impl<EG: EntityGateway> ShipServerState<EG> {
|
||||
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.unwrap().0,
|
||||
_unknown1: [0; 5],
|
||||
client_id: 0,
|
||||
name: libpso::utf8_to_utf16_array!(client.character.name, 16),
|
||||
@ -437,7 +434,7 @@ impl<EG: EntityGateway> ShipServerState<EG> {
|
||||
fn update_config(&mut self, id: ClientId, update_config: &UpdateConfig) -> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + 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())
|
||||
}
|
||||
|
||||
@ -463,7 +460,7 @@ impl<EG: EntityGateway> ShipServerState<EG> {
|
||||
fn write_infoboard(&mut self, id: ClientId, new_infoboard: &WriteInfoboard) -> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + 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())
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user