You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

787 lines
33 KiB

use std::collections::BTreeMap;
use std::convert::TryInto;
use futures::future::{Future, BoxFuture};
use crate::entity::account::*;
use crate::entity::character::*;
use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction, GatewayError};
use crate::entity::item::*;
use crate::entity::room::*;
use async_std::sync::{Arc, Mutex};
#[derive(Clone)]
pub struct InMemoryGatewayTransaction {
working_gateway: InMemoryGateway,
original_gateway: InMemoryGateway,
}
fn copy_if_needed<K, V>(working_table: &mut BTreeMap<K, V>, original_table: &BTreeMap<K, V>, key: K) -> Option<()>
where
K: Ord + Copy,
V: Clone,
{
if let std::collections::btree_map::Entry::Vacant(e) = working_table.entry(key) {
e.insert(original_table.get(&key)?.clone());
}
Some(())
}
// functions here have been skipped as they are not used in transactions, add as needed
#[async_trait::async_trait]
impl EntityGateway for InMemoryGatewayTransaction {
type Transaction<'t> = InMemoryGatewayTransaction where Self: 't;
async fn create_user(&mut self, user: NewUserAccountEntity) -> Result<UserAccountEntity, GatewayError> {
self.working_gateway.create_user(user).await
}
async fn get_user_by_id(&mut self, id: UserAccountId) -> Result<UserAccountEntity, GatewayError> {
match self.working_gateway.get_user_by_id(id).await {
Ok(user) => Ok(user),
Err(_) => {
self.original_gateway.get_user_by_id(id).await
}
}
}
async fn get_user_by_name(&mut self, username: String) -> Result<UserAccountEntity, GatewayError> {
match self.working_gateway.get_user_by_name(username.clone()).await {
Ok(user) => Ok(user),
Err(_) => {
self.original_gateway.get_user_by_name(username).await
}
}
}
async fn save_user(&mut self, user: &UserAccountEntity) -> Result<(), GatewayError> {
self.working_gateway.save_user(user).await
}
async fn create_user_settings(&mut self, settings: NewUserSettingsEntity) -> Result<UserSettingsEntity, GatewayError> {
self.working_gateway.create_user_settings(settings).await
}
async fn get_user_settings_by_user(&mut self, user: &UserAccountEntity) -> Result<UserSettingsEntity, GatewayError> {
match self.working_gateway.get_user_settings_by_user(user).await {
Ok(user) => Ok(user),
Err(_) => {
self.original_gateway.get_user_settings_by_user(user).await
}
}
}
async fn save_user_settings(&mut self, settings: &UserSettingsEntity) -> Result<(), GatewayError> {
self.original_gateway.save_user_settings(settings).await
}
async fn save_character(&mut self, char: &CharacterEntity) -> Result<(), GatewayError> {
copy_if_needed(&mut *self.working_gateway.characters.lock().await,
&*self.original_gateway.characters.lock().await,
char.id
);
self.working_gateway.save_character(char).await
}
async fn create_item(&mut self, item: NewItemEntity) -> Result<ItemEntity, GatewayError> {
self.working_gateway.create_item(item).await
}
async fn add_item_note(&mut self, item_id: &ItemEntityId, item_note: ItemNote) -> Result<(), GatewayError> {
self.working_gateway.add_item_note(item_id, item_note).await
}
async fn feed_mag(&mut self, mag_item_id: &ItemEntityId, tool_item_id: &ItemEntityId) -> Result<(), GatewayError> {
self.working_gateway.feed_mag(mag_item_id, tool_item_id).await
}
async fn change_mag_owner(&mut self, mag_item_id: &ItemEntityId, character: &CharacterEntity) -> Result<(), GatewayError> {
self.working_gateway.change_mag_owner(mag_item_id, character).await
}
async fn use_mag_cell(&mut self, mag_item_id: &ItemEntityId, mag_cell_id: &ItemEntityId) -> Result<(), GatewayError> {
self.working_gateway.use_mag_cell(mag_item_id, mag_cell_id).await
}
async fn add_weapon_modifier(&mut self, item_id: &ItemEntityId, modifier: &weapon::WeaponModifier) -> Result<(), GatewayError> {
self.working_gateway.add_weapon_modifier(item_id, modifier).await
}
async fn get_character_inventory(&mut self, char_id: &CharacterEntityId) -> Result<InventoryEntity, GatewayError> {
match self.working_gateway.get_character_inventory(char_id).await {
Ok(inventory) => Ok(inventory),
Err(_) => {
self.original_gateway.get_character_inventory(char_id).await
}
}
}
async fn get_character_bank(&mut self, char_id: &CharacterEntityId, bank_identifier: &BankIdentifier) -> Result<BankEntity, GatewayError> {
match self.working_gateway.get_character_bank(char_id, bank_identifier).await {
Ok(bank) => Ok(bank),
Err(_) => {
self.original_gateway.get_character_bank(char_id, bank_identifier).await
}
}
}
async fn set_character_inventory(&mut self, char_id: &CharacterEntityId, inventory: &InventoryEntity) -> Result<(), GatewayError> {
self.working_gateway.set_character_inventory(char_id, inventory).await
}
async fn set_character_bank(&mut self, char_id: &CharacterEntityId, bank: &BankEntity, bank_identifier: &BankIdentifier) -> Result<(), GatewayError> {
self.working_gateway.set_character_bank(char_id, bank, bank_identifier).await
}
async fn get_character_equips(&mut self, char_id: &CharacterEntityId) -> Result<EquippedEntity, GatewayError> {
match self.working_gateway.get_character_equips(char_id).await {
Ok(equips) => Ok(equips),
Err(_) => {
self.original_gateway.get_character_equips(char_id).await
}
}
}
async fn set_character_equips(&mut self, char_id: &CharacterEntityId, equipped: &EquippedEntity) -> Result<(), GatewayError> {
self.working_gateway.set_character_equips(char_id, equipped).await
}
async fn set_character_meseta(&mut self, char_id: &CharacterEntityId, meseta: Meseta) -> Result<(), GatewayError> {
self.working_gateway.set_character_meseta(char_id, meseta).await
}
async fn get_character_meseta(&mut self, char_id: &CharacterEntityId) -> Result<Meseta, GatewayError> {
match self.working_gateway.get_character_meseta(char_id).await {
Ok(meseta) => Ok(meseta),
Err(_) => {
self.original_gateway.get_character_meseta(char_id).await
}
}
}
async fn set_bank_meseta(&mut self, char_id: &CharacterEntityId, bank_identifier: &BankIdentifier, meseta: Meseta) -> Result<(), GatewayError> {
self.working_gateway.set_bank_meseta(char_id, bank_identifier, meseta).await
}
async fn get_bank_meseta(&mut self, char_id: &CharacterEntityId, bank_identifier: &BankIdentifier) -> Result<Meseta, GatewayError> {
match self.working_gateway.get_bank_meseta(char_id, bank_identifier).await {
Ok(meseta) => Ok(meseta),
Err(_) => {
self.original_gateway.get_bank_meseta(char_id, bank_identifier).await
}
}
}
async fn create_trade(&mut self, char_id1: &CharacterEntityId, char_id2: &CharacterEntityId) -> Result<TradeEntity, GatewayError> {
self.working_gateway.create_trade(char_id1, char_id2).await
}
async fn set_character_playtime(&mut self, char_id: &CharacterEntityId, playtime: u32) -> Result<(), GatewayError> {
copy_if_needed(&mut *self.working_gateway.characters.lock().await,
&*self.original_gateway.characters.lock().await,
*char_id
);
self.working_gateway.set_character_playtime(char_id, playtime).await
}
}
#[async_trait::async_trait]
impl EntityGatewayTransaction for InMemoryGatewayTransaction {
type ParentGateway = InMemoryGatewayTransaction;
fn gateway(&mut self) -> &mut Self::ParentGateway {
self
}
async fn commit(mut self) -> Result<(), GatewayError> {
self.original_gateway.users.lock().await.extend(self.working_gateway.users.lock().await.clone());
self.original_gateway.user_settings.lock().await.extend(self.working_gateway.user_settings.lock().await.clone());
self.original_gateway.characters.lock().await.extend(self.working_gateway.characters.lock().await.clone());
self.original_gateway.character_meseta.lock().await.extend(self.working_gateway.character_meseta.lock().await.clone());
self.original_gateway.bank_meseta.lock().await.extend(self.working_gateway.bank_meseta.lock().await.clone());
self.original_gateway.shared_bank_meseta.lock().await.extend(self.working_gateway.shared_bank_meseta.lock().await.clone());
self.original_gateway.items.lock().await.extend(self.working_gateway.items.lock().await.clone());
self.original_gateway.inventories.lock().await.extend(self.working_gateway.inventories.lock().await.clone());
self.original_gateway.character_banks.lock().await.extend(self.working_gateway.character_banks.lock().await.clone());
self.original_gateway.shared_banks.lock().await.extend(self.working_gateway.shared_banks.lock().await.clone());
self.original_gateway.equips.lock().await.extend(self.working_gateway.equips.lock().await.clone());
self.original_gateway.mag_modifiers.lock().await.extend(self.working_gateway.mag_modifiers.lock().await.clone());
self.original_gateway.weapon_modifiers.lock().await.extend(self.working_gateway.weapon_modifiers.lock().await.clone());
self.original_gateway.trades.lock().await.extend(self.working_gateway.trades.lock().await.clone());
Ok(())
}
}
#[derive(Clone)]
enum InventoryItemElement {
Individual(ItemEntityId),
Stacked(Vec<ItemEntityId>),
}
#[derive(Clone)]
pub struct InMemoryGateway {
users: Arc<Mutex<BTreeMap<UserAccountId, UserAccountEntity>>>,
user_settings: Arc<Mutex<BTreeMap<UserSettingsId, UserSettingsEntity>>>,
characters: Arc<Mutex<BTreeMap<CharacterEntityId, CharacterEntity>>>,
character_meseta: Arc<Mutex<BTreeMap<CharacterEntityId, Meseta>>>,
bank_meseta: Arc<Mutex<BTreeMap<CharacterEntityId, Meseta>>>,
shared_bank_meseta: Arc<Mutex<BTreeMap<(UserAccountId, BankName), Meseta>>>,
items: Arc<Mutex<BTreeMap<ItemEntityId, ItemEntity>>>,
inventories: Arc<Mutex<BTreeMap<CharacterEntityId, Vec<InventoryItemElement>>>>,
character_banks: Arc<Mutex<BTreeMap<CharacterEntityId, BankEntity>>>,
shared_banks: Arc<Mutex<BTreeMap<(UserAccountId, BankName), BankEntity>>>,
equips: Arc<Mutex<BTreeMap<CharacterEntityId, EquippedEntity>>>,
mag_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<mag::MagModifier>>>>,
weapon_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<weapon::WeaponModifier>>>>,
trades: Arc<Mutex<Vec<TradeEntity>>>,
}
impl Default for InMemoryGateway {
fn default() -> InMemoryGateway {
InMemoryGateway {
users: Arc::new(Mutex::new(BTreeMap::new())),
user_settings: Arc::new(Mutex::new(BTreeMap::new())),
characters: Arc::new(Mutex::new(BTreeMap::new())),
character_meseta: Arc::new(Mutex::new(BTreeMap::new())),
bank_meseta: Arc::new(Mutex::new(BTreeMap::new())),
shared_bank_meseta: Arc::new(Mutex::new(BTreeMap::new())),
items: Arc::new(Mutex::new(BTreeMap::new())),
inventories: Arc::new(Mutex::new(BTreeMap::new())),
character_banks: Arc::new(Mutex::new(BTreeMap::new())),
shared_banks: Arc::new(Mutex::new(BTreeMap::new())),
equips: Arc::new(Mutex::new(BTreeMap::new())),
mag_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
weapon_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
trades: Arc::new(Mutex::new(Vec::new())),
}
}
}
fn apply_modifiers(items: &BTreeMap<ItemEntityId, ItemEntity>,
weapon_modifiers: &BTreeMap<ItemEntityId, Vec<weapon::WeaponModifier>>,
mag_modifiers: &BTreeMap<ItemEntityId, Vec<mag::MagModifier>>,
inventory: InventoryEntity ) -> InventoryEntity {
let inventory_items = inventory.items.into_iter()
.map(|item| {
item.map_individual(|mut item| {
item.item = match item.item {
ItemDetail::Weapon(mut weapon) => {
if let Some(weapon_modifiers) = weapon_modifiers.get(&item.id) {
for weapon_modifier in weapon_modifiers.iter() {
weapon.apply_modifier(weapon_modifier);
}
}
ItemDetail::Weapon(weapon)
},
ItemDetail::Mag(mag) => {
let mut mag = mag::Mag::baby_mag(mag.color as u16);
if let Some(mag_modifiers) = mag_modifiers.get(&item.id) {
for mag_modifier in mag_modifiers.iter() {
match mag_modifier {
mag::MagModifier::FeedMag {food} => {
if let Some(mag_feed) = items.get(food) {
if let ItemDetail::Tool(mag_feed) = mag_feed.item {
mag.feed(mag_feed.tool)
}
}
},
mag::MagModifier::OwnerChange(class, section_id) => {
mag.change_owner(*class, *section_id)
},
mag::MagModifier::MagCell(mag_cell_id) => {
if let Some(mag_cell) = items.get(mag_cell_id) {
if let ItemDetail::Tool(mag_cell) = mag_cell.item {
mag.apply_mag_cell(mag_cell.tool.try_into().unwrap()).unwrap()
}
}
},
_ => {}
}
}
}
ItemDetail::Mag(mag)
}
_ => {
item.item
}
};
item
})
})
.collect();
InventoryEntity::new(inventory_items)
}
#[async_trait::async_trait]
impl EntityGateway for InMemoryGateway {
type Transaction<'t> = InMemoryGatewayTransaction where Self: 't;
fn with_transaction<'a, F, Fut, R>(&'a mut self, func: F) -> BoxFuture<'a, Result<R, anyhow::Error>>
where
Fut: Future<Output = Result<(Self::Transaction<'a>, R), anyhow::Error>> + Send + 'a,
F: FnOnce(Self::Transaction<'a>) -> Fut + Send + 'a,
R: Send,
{
Box::pin(async move {
let users = self.users.lock().await.clone();
let user_settings = self.user_settings.lock().await.clone();
let characters = self.characters.lock().await.clone();
let character_meseta = self.character_meseta.lock().await.clone();
let bank_meseta = self.bank_meseta.lock().await.clone();
let shared_bank_meseta = self.shared_bank_meseta.lock().await.clone();
let items = self.items.lock().await.clone();
let inventories = self.inventories.lock().await.clone();
let character_banks = self.character_banks.lock().await.clone();
let shared_banks = self.shared_banks.lock().await.clone();
let equips = self.equips.lock().await.clone();
let mag_modifiers = self.mag_modifiers.lock().await.clone();
let weapon_modifiers = self.weapon_modifiers.lock().await.clone();
let trades = self.trades.lock().await.clone();
let working_gateway = InMemoryGateway {
users: Arc::new(Mutex::new(users)),
user_settings: Arc::new(Mutex::new(user_settings)),
characters: Arc::new(Mutex::new(characters)),
character_meseta: Arc::new(Mutex::new(character_meseta)),
bank_meseta: Arc::new(Mutex::new(bank_meseta)),
shared_bank_meseta: Arc::new(Mutex::new(shared_bank_meseta)),
items: Arc::new(Mutex::new(items)),
inventories: Arc::new(Mutex::new(inventories)),
character_banks: Arc::new(Mutex::new(character_banks)),
shared_banks: Arc::new(Mutex::new(shared_banks)),
equips: Arc::new(Mutex::new(equips)),
mag_modifiers: Arc::new(Mutex::new(mag_modifiers)),
weapon_modifiers: Arc::new(Mutex::new(weapon_modifiers)),
trades: Arc::new(Mutex::new(trades)),
};
let transaction = InMemoryGatewayTransaction {
working_gateway,
original_gateway: self.clone(),
};
let (transaction, result) = func(transaction).await?;
transaction.commit().await?;
Ok(result)
})
}
async fn create_user(&mut self, user: NewUserAccountEntity) -> Result<UserAccountEntity, GatewayError> {
let mut users = self.users.lock().await;
let id = users
.iter()
.fold(0, |sum, (i, _)| std::cmp::max(sum, i.0))
+ 1;
let user = UserAccountEntity {
id: UserAccountId(id),
username: user.username,
password: user.password,
guildcard: user.guildcard,
team_id: user.team_id,
banned_until: user.banned_until,
muted_until: user.muted_until,
created_at: chrono::Utc::now(),
flags: user.flags,
activated: user.activated,
at_login: false,
at_character: false,
at_ship: false,
};
users.insert(user.id, user.clone());
Ok(user)
}
async fn get_user_by_id(&mut self, id: UserAccountId) -> Result<UserAccountEntity, GatewayError> {
let users = self.users.lock().await;
users.get(&id).cloned().ok_or(GatewayError::Error)
}
async fn get_user_by_name(&mut self, username: String) -> Result<UserAccountEntity, GatewayError> {
let users = self.users.lock().await;
users
.iter()
.find(|(_, k)| k.username == username)
.map(|(_, k)| k.clone())
.ok_or(GatewayError::Error)
}
async fn save_user(&mut self, user: &UserAccountEntity) -> Result<(), GatewayError> {
let mut users = self.users.lock().await;
users.insert(user.id, user.clone());
Ok(())
}
async fn create_user_settings(&mut self, settings: NewUserSettingsEntity) -> Result<UserSettingsEntity, GatewayError> {
let mut user_settings = self.user_settings.lock().await;
let id = user_settings
.iter()
.fold(0, |sum, (i, _)| std::cmp::max(sum, i.0))
+ 1;
let new_settings = UserSettingsEntity {
id: UserSettingsId(id),
user_id: settings.user_id,
settings: settings.settings,
};
user_settings.insert(new_settings.id, new_settings.clone());
Ok(new_settings)
}
async fn get_user_settings_by_user(&mut self, user: &UserAccountEntity) -> Result<UserSettingsEntity, GatewayError> {
let user_settings = self.user_settings.lock().await;
user_settings
.iter()
.find(|(_, k)| k.user_id == user.id)
.map(|(_, k)| k.clone())
.ok_or(GatewayError::Error)
}
async fn save_user_settings(&mut self, settings: &UserSettingsEntity) -> Result<(), GatewayError> {
let mut user_settings = self.user_settings.lock().await;
user_settings.insert(settings.id, settings.clone());
Ok(())
}
async fn get_characters_by_user(&mut self, user: &UserAccountEntity) -> Result<[Option<CharacterEntity>; 4], GatewayError> {
let characters = self.characters.lock().await;
const NONE: Option<CharacterEntity> = None;
let mut chars = [NONE; 4];
characters
.iter()
.filter(|(_, c)| c.user_id == user.id)
.for_each(|(_, c)| chars[c.slot as usize] = Some(c.clone()));
Ok(chars)
}
async fn create_character(&mut self, character: NewCharacterEntity) -> Result<CharacterEntity, GatewayError> {
let mut characters = self.characters.lock().await;
let id = characters
.iter()
.fold(0, |sum, (i, _)| std::cmp::max(sum, i.0))
+ 1;
let new_character = CharacterEntity {
id: CharacterEntityId(id),
user_id: character.user_id,
slot: character.slot,
name: character.name,
exp: character.exp,
char_class: character.char_class,
section_id: character.section_id,
appearance: character.appearance,
techs: character.techs,
config: character.config,
info_board: character.info_board,
guildcard: character.guildcard,
materials: character.materials,
tech_menu: character.tech_menu,
option_flags: character.option_flags,
playtime: 0,
};
characters.insert(new_character.id, new_character.clone());
Ok(new_character)
}
async fn save_character(&mut self, char: &CharacterEntity) -> Result<(), GatewayError> {
let mut characters = self.characters.lock().await;
characters.insert(char.id, char.clone());
Ok(())
}
async fn get_guild_card_data_by_user(&mut self, user: &UserAccountEntity) -> Result<GuildCardDataEntity, GatewayError> {
Ok(GuildCardDataEntity::new(user.id))
}
async fn create_item(&mut self, item: NewItemEntity) -> Result<ItemEntity, GatewayError> {
let mut items = self.items.lock().await;
let id = items
.iter()
.fold(0, |sum, (i, _)| std::cmp::max(sum, i.0))
+ 1;
let new_item = ItemEntity {
id: ItemEntityId(id),
item: item.item,
};
items.insert(ItemEntityId(id), new_item.clone());
Ok(new_item)
}
async fn add_item_note(&mut self, _item_id: &ItemEntityId, _item_note: ItemNote) -> Result<(), GatewayError> {
Ok(())
}
async fn feed_mag(&mut self, mag_item_id: &ItemEntityId, tool_item_id: &ItemEntityId) -> Result<(), GatewayError> {
self.mag_modifiers.lock().await
.entry(*mag_item_id)
.or_insert_with(Vec::new)
.push(mag::MagModifier::FeedMag {
food: *tool_item_id
});
Ok(())
}
async fn change_mag_owner(&mut self, mag_item_id: &ItemEntityId, character: &CharacterEntity) -> Result<(), GatewayError> {
self.mag_modifiers.lock().await
.entry(*mag_item_id)
.or_insert_with(Vec::new)
.push(mag::MagModifier::OwnerChange(character.char_class, character.section_id));
Ok(())
}
async fn use_mag_cell(&mut self, mag_item_id: &ItemEntityId, mag_cell_id: &ItemEntityId) -> Result<(), GatewayError> {
self.mag_modifiers.lock().await
.entry(*mag_item_id)
.or_insert_with(Vec::new)
.push(mag::MagModifier::MagCell(*mag_cell_id));
Ok(())
}
async fn add_weapon_modifier(&mut self, item_id: &ItemEntityId, modifier: &weapon::WeaponModifier) -> Result<(), GatewayError> {
self.weapon_modifiers.lock().await
.entry(*item_id)
.or_insert_with(Vec::new)
.push(modifier.clone());
Ok(())
}
async fn get_character_inventory(&mut self, char_id: &CharacterEntityId) -> Result<InventoryEntity, GatewayError> {
let inventories = self.inventories.lock().await;
let items = self.items.lock().await;
let weapon_modifiers = self.weapon_modifiers.lock().await;
let mag_modifiers = self.mag_modifiers.lock().await;
Ok(inventories
.iter()
.find(|(id, _)| **id == *char_id)
.map(|(_, inv)| {
InventoryEntity {
items: inv
.iter()
.map(|inv_item_id| {
match inv_item_id {
InventoryItemElement::Individual(individual_id) => {
InventoryItemEntity::Individual(items.get(individual_id).unwrap().clone())
},
InventoryItemElement::Stacked(stacked_ids) => {
InventoryItemEntity::Stacked(
stacked_ids.iter()
.map(|stacked_id| {
items.get(stacked_id).unwrap().clone()
})
.collect()
)
}
}
})
.collect()
}
})
.map(|inv| apply_modifiers(&items, &weapon_modifiers, &mag_modifiers, inv))
.unwrap_or_default())
}
async fn get_character_bank(&mut self, char_id: &CharacterEntityId, bank_identifier: &BankIdentifier) -> Result<BankEntity, GatewayError> {
match bank_identifier {
BankIdentifier::Character => {
let character_banks = self.character_banks.lock().await;
Ok(character_banks
.iter()
.find(|(id, _)| **id == *char_id)
.map(|(_, b)| b.clone())
.unwrap_or_default())
},
BankIdentifier::Shared(bank_name) => {
let user_id = self.characters
.lock()
.await
.iter()
.find(|(id, _)| **id == *char_id)
.unwrap()
.1
.user_id;
let shared_banks = self.shared_banks.lock().await;
Ok(shared_banks
.iter()
.find(|((id, name), _)| *id == user_id && *name == *bank_name)
.map(|(_, b)| b.clone())
.unwrap_or_default())
}
}
}
async fn set_character_inventory(&mut self, char_id: &CharacterEntityId, inventory: &InventoryEntity) -> Result<(), GatewayError> {
let mut inventories = self.inventories.lock().await;
inventories.insert(*char_id, inventory.items
.iter()
.map(|inventory_item| {
match inventory_item {
InventoryItemEntity::Individual(individual) => {
InventoryItemElement::Individual(individual.id)
},
InventoryItemEntity::Stacked(stacked) => {
InventoryItemElement::Stacked(
stacked.iter()
.map(|stacked| {
stacked.id
})
.collect()
)
}
}
})
.collect());
Ok(())
}
async fn set_character_bank(&mut self, char_id: &CharacterEntityId, bank: &BankEntity, bank_identifier: &BankIdentifier) -> Result<(), GatewayError> {
match bank_identifier {
BankIdentifier::Character => {
let mut character_banks = self.character_banks.lock().await;
character_banks.insert(*char_id, bank.clone());
},
BankIdentifier::Shared(bank_name) => {
let user_id = self.characters
.lock()
.await
.iter()
.find(|(id, _)| **id == *char_id)
.unwrap()
.1
.user_id;
let mut shared_banks = self.shared_banks.lock().await;
shared_banks.insert((user_id, bank_name.clone()), bank.clone());
}
}
Ok(())
}
async fn get_character_equips(&mut self, char_id: &CharacterEntityId) -> Result<EquippedEntity, GatewayError> {
let equips = self.equips.lock().await;
Ok(equips
.iter()
.find(|(id, _)| **id == *char_id)
.map(|(_, inv)| inv.clone())
.unwrap_or_default())
}
async fn set_character_equips(&mut self, char_id: &CharacterEntityId, equipped: &EquippedEntity) -> Result<(), GatewayError> {
let mut equips = self.equips.lock().await;
equips.insert(*char_id, equipped.clone());
Ok(())
}
async fn set_character_meseta(&mut self, char_id: &CharacterEntityId, meseta: Meseta) -> Result<(), GatewayError> {
let mut character_meseta = self.character_meseta.lock().await;
character_meseta.insert(*char_id, meseta);
Ok(())
}
async fn get_character_meseta(&mut self, char_id: &CharacterEntityId) -> Result<Meseta, GatewayError> {
let mut character_meseta = self.character_meseta.lock().await;
if let Some(meseta) = character_meseta.get_mut(char_id) {
Ok(*meseta)
}
else {
Err(GatewayError::Error)
}
}
async fn set_bank_meseta(&mut self, char_id: &CharacterEntityId, bank_identifier: &BankIdentifier, meseta: Meseta) -> Result<(), GatewayError> {
match bank_identifier {
BankIdentifier::Character => {
let mut bank_meseta = self.bank_meseta.lock().await;
bank_meseta.insert(*char_id, meseta);
}
BankIdentifier::Shared(bank_name) => {
let user_id = self.characters
.lock()
.await
.iter()
.find(|(id, _)| **id == *char_id)
.unwrap()
.1
.user_id;
self.shared_bank_meseta
.lock()
.await
.insert((user_id, bank_name.clone()), meseta);
}
}
Ok(())
}
async fn get_bank_meseta(&mut self, char_id: &CharacterEntityId, bank_identifier: &BankIdentifier) -> Result<Meseta, GatewayError> {
match bank_identifier {
BankIdentifier::Character => {
let mut bank_meseta = self.bank_meseta.lock().await;
if let Some(meseta) = bank_meseta.get_mut(char_id) {
Ok(*meseta)
}
else {
Err(GatewayError::Error)
}
},
BankIdentifier::Shared(bank_name) => {
let mut shared_bank_meseta = self.shared_bank_meseta.lock().await;
let user_id = self.characters
.lock()
.await
.iter()
.find(|(id, _)| **id == *char_id)
.unwrap()
.1
.user_id;
if let Some(meseta) = shared_bank_meseta.get_mut(&(user_id, bank_name.clone())) {
Ok(*meseta)
}
else {
Ok(Meseta(0))
}
}
}
}
async fn create_trade(&mut self, char_id1: &CharacterEntityId, char_id2: &CharacterEntityId) -> Result<TradeEntity, GatewayError> {
let mut trades = self.trades.lock().await;
let id = trades.len() as u32;
let new_trade = TradeEntity {
id: TradeId(id),
character1: *char_id1,
character2: *char_id2,
};
trades.push(new_trade.clone());
Ok(new_trade)
}
async fn set_character_playtime(&mut self, char_id: &CharacterEntityId, playtime: u32) -> Result<(), GatewayError> {
let mut characters = self.characters.lock().await;
if let Some(character) = characters.get_mut(char_id) {
character.playtime = playtime;
Ok(())
}
else {
Err(GatewayError::Error)
}
}
// I do not care to replicate this in testing
async fn create_room(&mut self, room: NewRoomEntity) -> Result<RoomEntity, GatewayError> {
Ok(RoomEntity {
id: RoomEntityId(0),
name: room.name,
section_id: room.section_id,
episode: room.episode,
difficulty: room.difficulty,
mode: room.mode,
})
}
// I do not care to replicate this in testing
async fn add_room_note(&mut self, _room_id: RoomEntityId, _note: RoomNote) -> Result<(), GatewayError> {
Ok(())
}
}