impromptu db transaction refactor
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
e6e080004f
commit
e0e68b9ad7
@ -19,15 +19,12 @@ pub enum GatewayError {
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait EntityGateway: Send + Sync {
|
||||
async fn transaction<'a>(&'a mut self) -> Result<Box<dyn EntityGatewayTransaction + 'a>, GatewayError>
|
||||
{
|
||||
unimplemented!();
|
||||
}
|
||||
type Transaction: EntityGatewayTransaction + Clone;
|
||||
|
||||
async fn with_transaction<'a, F, Fut, R, E>(&'a mut self, _func: F) -> Result<R, E>
|
||||
where
|
||||
Fut: Future<Output = Result<(Box<dyn EntityGatewayTransaction + 'a>, R), E>> + Send + 'a,
|
||||
F: FnOnce(Box<dyn EntityGatewayTransaction + 'a>) -> Fut + Send,
|
||||
Fut: Future<Output = Result<(Self::Transaction, R), E>> + Send + 'a,
|
||||
F: FnOnce(Self::Transaction) -> Fut + Send,
|
||||
R: Send,
|
||||
E: From<GatewayError>,
|
||||
Self: Sized
|
||||
@ -155,12 +152,14 @@ pub trait EntityGateway: Send + Sync {
|
||||
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait EntityGatewayTransaction: Send + Sync {
|
||||
fn gateway(&mut self) -> &mut dyn EntityGateway {
|
||||
pub trait EntityGatewayTransaction: Send + Sync + Sized {
|
||||
type ParentGateway: EntityGateway + Clone;
|
||||
|
||||
fn gateway(&mut self) -> &mut Self::ParentGateway {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
async fn commit(self: Box<Self>) -> Result<(), GatewayError> {
|
||||
async fn commit(self) -> Result<(), GatewayError> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
@ -9,10 +9,10 @@ use crate::entity::item::*;
|
||||
|
||||
use async_std::sync::{Arc, Mutex};
|
||||
|
||||
// TODO: implement multiple banks
|
||||
pub struct InMemoryGatewayTransaction<'a> {
|
||||
#[derive(Clone)]
|
||||
pub struct InMemoryGatewayTransaction {
|
||||
working_gateway: InMemoryGateway,
|
||||
original_gateway: &'a mut InMemoryGateway,
|
||||
original_gateway: InMemoryGateway,
|
||||
}
|
||||
|
||||
|
||||
@ -30,7 +30,9 @@ where
|
||||
|
||||
// functions here have been skipped as they are not used in transactions, add as needed
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> EntityGateway for InMemoryGatewayTransaction<'a> {
|
||||
impl EntityGateway for InMemoryGatewayTransaction {
|
||||
type Transaction = InMemoryGatewayTransaction;
|
||||
|
||||
async fn create_user(&mut self, user: NewUserAccountEntity) -> Result<UserAccountEntity, GatewayError> {
|
||||
self.working_gateway.create_user(user).await
|
||||
}
|
||||
@ -182,12 +184,14 @@ impl<'a> EntityGateway for InMemoryGatewayTransaction<'a> {
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> EntityGatewayTransaction for InMemoryGatewayTransaction<'a> {
|
||||
fn gateway(&mut self) -> &mut dyn EntityGateway {
|
||||
impl EntityGatewayTransaction for InMemoryGatewayTransaction {
|
||||
type ParentGateway = InMemoryGatewayTransaction;
|
||||
|
||||
fn gateway(&mut self) -> &mut Self::ParentGateway {
|
||||
self
|
||||
}
|
||||
|
||||
async fn commit(mut self: Box<Self>) -> Result<(), GatewayError> {
|
||||
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());
|
||||
@ -298,49 +302,12 @@ fn apply_modifiers(items: &BTreeMap<ItemEntityId, ItemEntity>,
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl EntityGateway for InMemoryGateway {
|
||||
async fn transaction<'a>(&'a mut self) -> Result<Box<dyn EntityGatewayTransaction + 'a>, GatewayError>
|
||||
{
|
||||
let working_gateway = {
|
||||
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 items = self.items.lock().await.clone();
|
||||
let inventories = self.inventories.lock().await.clone();
|
||||
let banks = self.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();
|
||||
|
||||
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)),
|
||||
items: Arc::new(Mutex::new(items)),
|
||||
inventories: Arc::new(Mutex::new(inventories)),
|
||||
banks: Arc::new(Mutex::new(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)),
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Box::new(InMemoryGatewayTransaction {
|
||||
working_gateway,
|
||||
original_gateway: self,
|
||||
}))
|
||||
}
|
||||
|
||||
type Transaction = InMemoryGatewayTransaction;
|
||||
|
||||
async fn with_transaction<'a, F, Fut, R, E>(&'a mut self, func: F) -> Result<R, E>
|
||||
where
|
||||
Fut: Future<Output = Result<(Box<dyn EntityGatewayTransaction + 'a>, R), E>> + Send + 'a,
|
||||
F: FnOnce(Box<dyn EntityGatewayTransaction + 'a>) -> Fut + Send,
|
||||
Fut: Future<Output = Result<(Self::Transaction, R), E>> + Send + 'a,
|
||||
F: FnOnce(Self::Transaction) -> Fut + Send,
|
||||
R: Send,
|
||||
E: From<GatewayError>,
|
||||
{
|
||||
@ -372,10 +339,10 @@ impl EntityGateway for InMemoryGateway {
|
||||
trades: Arc::new(Mutex::new(trades)),
|
||||
};
|
||||
|
||||
let transaction = Box::new(InMemoryGatewayTransaction {
|
||||
let transaction = InMemoryGatewayTransaction {
|
||||
working_gateway,
|
||||
original_gateway: self,
|
||||
});
|
||||
original_gateway: self.clone(),
|
||||
};
|
||||
|
||||
let (transaction, result) = func(transaction).await?;
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
use std::convert::{From, TryFrom, Into};
|
||||
use futures::{Future, TryStreamExt};
|
||||
use async_std::stream::StreamExt;
|
||||
use async_std::sync::{Arc, Mutex};
|
||||
use libpso::character::guildcard;
|
||||
use crate::entity::account::*;
|
||||
use crate::entity::character::*;
|
||||
@ -21,31 +22,41 @@ mod embedded {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PostgresTransaction<'t> {
|
||||
pgtransaction: sqlx::Transaction<'t, sqlx::Postgres>,
|
||||
pgtransaction: Arc<Mutex<sqlx::Transaction<'t, sqlx::Postgres>>>,
|
||||
}
|
||||
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<'t> EntityGatewayTransaction for PostgresTransaction<'t> {
|
||||
fn gateway(&mut self) -> &mut dyn EntityGateway {
|
||||
type ParentGateway = PostgresTransaction<'t>;
|
||||
|
||||
fn gateway(&mut self) -> &mut Self::ParentGateway {
|
||||
self
|
||||
}
|
||||
|
||||
async fn commit(self: Box<Self>) -> Result<(), GatewayError> {
|
||||
self.pgtransaction.commit().await?;
|
||||
//async fn commit(self: Box<Self>) -> Result<(), GatewayError> {
|
||||
async fn commit(self) -> Result<(), GatewayError> {
|
||||
//self.pgtransaction.lock().await.commit().await?;
|
||||
Arc::try_unwrap(self.pgtransaction)
|
||||
.unwrap()
|
||||
.into_inner()
|
||||
.commit()
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PostgresGateway {
|
||||
pub struct PostgresGateway<'t> {
|
||||
pool: sqlx::Pool<sqlx::Postgres>,
|
||||
_t: std::marker::PhantomData<&'t ()>,
|
||||
}
|
||||
|
||||
impl PostgresGateway {
|
||||
pub fn new(host: &str, dbname: &str, username: &str, password: &str) -> PostgresGateway {
|
||||
impl<'t> PostgresGateway<'t> {
|
||||
pub fn new(host: &str, dbname: &str, username: &str, password: &str) -> PostgresGateway<'t> {
|
||||
let mut conn = refinery::config::Config::new(refinery::config::ConfigDbType::Postgres)
|
||||
.set_db_host(host)
|
||||
.set_db_user(username)
|
||||
@ -61,6 +72,7 @@ impl PostgresGateway {
|
||||
|
||||
PostgresGateway {
|
||||
pool,
|
||||
_t: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -581,24 +593,19 @@ async fn set_character_playtime(conn: &mut sqlx::PgConnection, char_id: &Charact
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl EntityGateway for PostgresGateway {
|
||||
async fn transaction<'a>(&'a mut self) -> Result<Box<dyn EntityGatewayTransaction + 'a>, GatewayError>
|
||||
{
|
||||
Ok(Box::new(PostgresTransaction {
|
||||
pgtransaction: self.pool.begin().await?,
|
||||
}))
|
||||
}
|
||||
impl<'t> EntityGateway for PostgresGateway<'t> {
|
||||
type Transaction = PostgresTransaction<'t>;
|
||||
|
||||
async fn with_transaction<'a, F, Fut, R, E>(&'a mut self, func: F) -> Result<R, E>
|
||||
where
|
||||
Fut: Future<Output = Result<(Box<dyn EntityGatewayTransaction + 'a>, R), E>> + Send + 'a,
|
||||
F: FnOnce(Box<dyn EntityGatewayTransaction + 'a>) -> Fut + Send,
|
||||
Fut: Future<Output = Result<(Self::Transaction, R), E>> + Send + 'a,
|
||||
F: FnOnce(Self::Transaction) -> Fut + Send,
|
||||
R: Send,
|
||||
E: From<GatewayError>,
|
||||
{
|
||||
let transaction = Box::new(PostgresTransaction {
|
||||
pgtransaction: self.pool.begin().await.map_err(|_| ()).unwrap()
|
||||
});
|
||||
let transaction = PostgresTransaction {
|
||||
pgtransaction: Arc::new(Mutex::new(self.pool.begin().await.map_err(|_| ()).unwrap()))
|
||||
};
|
||||
let (transaction, result) = func(transaction).await.map_err(|_| ()).unwrap();
|
||||
transaction.commit().await.map_err(|_| ()).unwrap();
|
||||
Ok(result)
|
||||
@ -728,44 +735,46 @@ impl EntityGateway for PostgresGateway {
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<'c> EntityGateway for PostgresTransaction<'c> {
|
||||
type Transaction = PostgresTransaction<'c>;
|
||||
|
||||
async fn create_user(&mut self, user: NewUserAccountEntity) -> Result<UserAccountEntity, GatewayError> {
|
||||
create_user(&mut *self.pgtransaction, user).await
|
||||
create_user(&mut *self.pgtransaction.lock().await, user).await
|
||||
}
|
||||
|
||||
async fn get_user_by_id(&mut self, id: UserAccountId) -> Result<UserAccountEntity, GatewayError> {
|
||||
get_user_by_id(&mut *self.pgtransaction, id).await
|
||||
get_user_by_id(&mut *self.pgtransaction.lock().await, id).await
|
||||
}
|
||||
|
||||
async fn get_user_by_name(&mut self, username: String) -> Result<UserAccountEntity, GatewayError> {
|
||||
get_user_by_name(&mut *self.pgtransaction, username).await
|
||||
get_user_by_name(&mut *self.pgtransaction.lock().await, username).await
|
||||
}
|
||||
|
||||
async fn save_user(&mut self, user: &UserAccountEntity) -> Result<(), GatewayError> {
|
||||
save_user(&mut *self.pgtransaction, user).await
|
||||
save_user(&mut *self.pgtransaction.lock().await, user).await
|
||||
}
|
||||
|
||||
async fn create_user_settings(&mut self, settings: NewUserSettingsEntity) -> Result<UserSettingsEntity, GatewayError> {
|
||||
create_user_settings(&mut *self.pgtransaction, settings).await
|
||||
create_user_settings(&mut *self.pgtransaction.lock().await, settings).await
|
||||
}
|
||||
|
||||
async fn get_user_settings_by_user(&mut self, user: &UserAccountEntity) -> Result<UserSettingsEntity, GatewayError> {
|
||||
get_user_settings_by_user(&mut *self.pgtransaction, user).await
|
||||
get_user_settings_by_user(&mut *self.pgtransaction.lock().await, user).await
|
||||
}
|
||||
|
||||
async fn save_user_settings(&mut self, settings: &UserSettingsEntity) -> Result<(), GatewayError> {
|
||||
save_user_settings(&mut *self.pgtransaction, settings).await
|
||||
save_user_settings(&mut *self.pgtransaction.lock().await, settings).await
|
||||
}
|
||||
|
||||
async fn create_character(&mut self, char: NewCharacterEntity) -> Result<CharacterEntity, GatewayError> {
|
||||
create_character(&mut *self.pgtransaction, char).await
|
||||
create_character(&mut *self.pgtransaction.lock().await, char).await
|
||||
}
|
||||
|
||||
async fn get_characters_by_user(&mut self, user: &UserAccountEntity) -> Result<[Option<CharacterEntity>; 4], GatewayError> {
|
||||
get_characters_by_user(&mut *self.pgtransaction, user).await
|
||||
get_characters_by_user(&mut *self.pgtransaction.lock().await, user).await
|
||||
}
|
||||
|
||||
async fn save_character(&mut self, char: &CharacterEntity) -> Result<(), GatewayError> {
|
||||
save_character(&mut *self.pgtransaction, char).await
|
||||
save_character(&mut *self.pgtransaction.lock().await, char).await
|
||||
}
|
||||
|
||||
async fn get_guild_card_data_by_user(&mut self, user: &UserAccountEntity) -> Result<GuildCardDataEntity, GatewayError> {
|
||||
@ -777,75 +786,75 @@ impl<'c> EntityGateway for PostgresTransaction<'c> {
|
||||
}
|
||||
|
||||
async fn create_item(&mut self, item: NewItemEntity) -> Result<ItemEntity, GatewayError> {
|
||||
create_item(&mut *self.pgtransaction, item).await
|
||||
create_item(&mut *self.pgtransaction.lock().await, item).await
|
||||
}
|
||||
|
||||
async fn add_item_note(&mut self, item_id: &ItemEntityId, item_note: ItemNote) -> Result<(), GatewayError> {
|
||||
add_item_note(&mut *self.pgtransaction, item_id, item_note).await
|
||||
add_item_note(&mut *self.pgtransaction.lock().await, item_id, item_note).await
|
||||
}
|
||||
|
||||
async fn feed_mag(&mut self, mag_item_id: &ItemEntityId, tool_item_id: &ItemEntityId) -> Result<(), GatewayError> {
|
||||
feed_mag(&mut *self.pgtransaction, mag_item_id, tool_item_id).await
|
||||
feed_mag(&mut *self.pgtransaction.lock().await, mag_item_id, tool_item_id).await
|
||||
}
|
||||
|
||||
async fn change_mag_owner(&mut self, mag_item_id: &ItemEntityId, character: &CharacterEntity) -> Result<(), GatewayError> {
|
||||
change_mag_owner(&mut *self.pgtransaction, mag_item_id, character).await
|
||||
change_mag_owner(&mut *self.pgtransaction.lock().await, mag_item_id, character).await
|
||||
}
|
||||
|
||||
async fn use_mag_cell(&mut self, mag_item_id: &ItemEntityId, mag_cell_id: &ItemEntityId) -> Result<(), GatewayError> {
|
||||
use_mag_cell(&mut *self.pgtransaction, mag_item_id, mag_cell_id).await
|
||||
use_mag_cell(&mut *self.pgtransaction.lock().await, mag_item_id, mag_cell_id).await
|
||||
}
|
||||
|
||||
async fn add_weapon_modifier(&mut self, item_id: &ItemEntityId, modifier: weapon::WeaponModifier) -> Result<(), GatewayError> {
|
||||
add_weapon_modifier(&mut *self.pgtransaction, item_id, modifier).await
|
||||
add_weapon_modifier(&mut *self.pgtransaction.lock().await, item_id, modifier).await
|
||||
}
|
||||
|
||||
async fn get_character_inventory(&mut self, char_id: &CharacterEntityId) -> Result<InventoryEntity, GatewayError> {
|
||||
get_character_inventory(&mut *self.pgtransaction, char_id).await
|
||||
get_character_inventory(&mut *self.pgtransaction.lock().await, char_id).await
|
||||
}
|
||||
|
||||
async fn get_character_bank(&mut self, char_id: &CharacterEntityId, bank_name: &BankName) -> Result<BankEntity, GatewayError> {
|
||||
get_character_bank(&mut *self.pgtransaction, char_id, bank_name).await
|
||||
get_character_bank(&mut *self.pgtransaction.lock().await, char_id, bank_name).await
|
||||
}
|
||||
|
||||
async fn set_character_inventory(&mut self, char_id: &CharacterEntityId, inventory: &InventoryEntity) -> Result<(), GatewayError> {
|
||||
set_character_inventory(&mut *self.pgtransaction, char_id, inventory).await
|
||||
set_character_inventory(&mut *self.pgtransaction.lock().await, char_id, inventory).await
|
||||
}
|
||||
|
||||
async fn set_character_bank(&mut self, char_id: &CharacterEntityId, bank: &BankEntity, bank_name: &BankName) -> Result<(), GatewayError> {
|
||||
set_character_bank(&mut *self.pgtransaction, char_id, bank, bank_name).await
|
||||
set_character_bank(&mut *self.pgtransaction.lock().await, char_id, bank, bank_name).await
|
||||
}
|
||||
|
||||
async fn get_character_equips(&mut self, char_id: &CharacterEntityId) -> Result<EquippedEntity, GatewayError> {
|
||||
get_character_equips(&mut *self.pgtransaction, char_id).await
|
||||
get_character_equips(&mut *self.pgtransaction.lock().await, char_id).await
|
||||
}
|
||||
|
||||
async fn set_character_equips(&mut self, char_id: &CharacterEntityId, equips: &EquippedEntity) -> Result<(), GatewayError> {
|
||||
set_character_equips(&mut *self.pgtransaction, char_id, equips).await
|
||||
set_character_equips(&mut *self.pgtransaction.lock().await, char_id, equips).await
|
||||
}
|
||||
|
||||
async fn set_character_meseta(&mut self, char_id: &CharacterEntityId, meseta: Meseta) -> Result<(), GatewayError> {
|
||||
set_character_meseta(&mut *self.pgtransaction, char_id, meseta).await
|
||||
set_character_meseta(&mut *self.pgtransaction.lock().await, char_id, meseta).await
|
||||
}
|
||||
|
||||
async fn get_character_meseta(&mut self, char_id: &CharacterEntityId) -> Result<Meseta, GatewayError> {
|
||||
get_character_meseta(&mut *self.pgtransaction, char_id).await
|
||||
get_character_meseta(&mut *self.pgtransaction.lock().await, char_id).await
|
||||
}
|
||||
|
||||
async fn set_bank_meseta(&mut self, char_id: &CharacterEntityId, bank: &BankName, meseta: Meseta) -> Result<(), GatewayError> {
|
||||
set_bank_meseta(&mut *self.pgtransaction, char_id, bank, meseta).await
|
||||
set_bank_meseta(&mut *self.pgtransaction.lock().await, char_id, bank, meseta).await
|
||||
}
|
||||
|
||||
async fn get_bank_meseta(&mut self, char_id: &CharacterEntityId, bank: &BankName) -> Result<Meseta, GatewayError> {
|
||||
get_bank_meseta(&mut *self.pgtransaction, char_id, bank).await
|
||||
get_bank_meseta(&mut *self.pgtransaction.lock().await, char_id, bank).await
|
||||
}
|
||||
|
||||
async fn create_trade(&mut self, char_id1: &CharacterEntityId, char_id2: &CharacterEntityId) -> Result<TradeEntity, GatewayError> {
|
||||
create_trade(&mut *self.pgtransaction, char_id1, char_id2).await
|
||||
create_trade(&mut *self.pgtransaction.lock().await, char_id1, char_id2).await
|
||||
}
|
||||
|
||||
async fn set_character_playtime(&mut self, char_id: &CharacterEntityId, playtime: u32) -> Result<(), GatewayError> {
|
||||
set_character_playtime(&mut *self.pgtransaction, char_id, playtime).await
|
||||
set_character_playtime(&mut *self.pgtransaction.lock().await, char_id, playtime).await
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ use crate::common::interserver::{ServerId, InterserverActor, LoginMessage, ShipM
|
||||
use crate::common::leveltable::LEVEL_TABLE;
|
||||
use libpso::{utf8_to_array, utf8_to_utf16_array};
|
||||
|
||||
use crate::entity::gateway::{EntityGateway, GatewayError};
|
||||
use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction, GatewayError};
|
||||
use crate::entity::account::{UserAccountId, UserAccountEntity, NewUserSettingsEntity, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM};
|
||||
use crate::entity::item::{NewItemEntity, ItemDetail, ItemNote, InventoryItemEntity, InventoryEntity, BankEntity, BankName, EquippedEntity, Meseta};
|
||||
use crate::entity::item::weapon::Weapon;
|
||||
@ -830,6 +830,14 @@ mod test {
|
||||
use libpso::character::{settings, character};
|
||||
use crate::entity::gateway::{InMemoryGateway, GatewayError};
|
||||
|
||||
impl EntityGateway for () {
|
||||
type Transaction = ();
|
||||
}
|
||||
|
||||
impl EntityGatewayTransaction for () {
|
||||
type ParentGateway = ();
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_option_send() {
|
||||
#[derive(Clone)]
|
||||
@ -838,6 +846,7 @@ mod test {
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl EntityGateway for TestData {
|
||||
type Transaction = ();
|
||||
async fn get_user_settings_by_user(&mut self, user: &UserAccountEntity) -> Result<UserSettingsEntity, GatewayError> {
|
||||
Ok(UserSettingsEntity {
|
||||
id: UserSettingsId(0),
|
||||
@ -879,7 +888,9 @@ mod test {
|
||||
async fn test_user_checksum() {
|
||||
#[derive(Clone)]
|
||||
struct TestData;
|
||||
impl EntityGateway for TestData {}
|
||||
impl EntityGateway for TestData {
|
||||
type Transaction = ();
|
||||
}
|
||||
let mut server = CharacterServerState::new(TestData {}, AuthToken("".into()));
|
||||
let send = server.handle(ClientId(1), RecvCharacterPacket::Checksum(Checksum {checksum: 1234,
|
||||
padding: 0,
|
||||
|
@ -14,7 +14,7 @@ use libpso::util::array_to_utf8;
|
||||
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::gateway::{EntityGateway, EntityGatewayTransaction};
|
||||
use crate::entity::account::{UserAccountEntity};
|
||||
|
||||
pub const LOGIN_PORT: u16 = 12000;
|
||||
@ -205,6 +205,14 @@ mod test {
|
||||
}
|
||||
});
|
||||
|
||||
impl EntityGateway for () {
|
||||
type Transaction = ();
|
||||
}
|
||||
|
||||
impl EntityGatewayTransaction for () {
|
||||
type ParentGateway = ();
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_correct_login() {
|
||||
#[derive(Clone)]
|
||||
@ -213,6 +221,7 @@ mod test {
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl EntityGateway for TestData {
|
||||
type Transaction = ();
|
||||
async fn get_user_by_name(&mut self, name: String) -> Result<UserAccountEntity, GatewayError> {
|
||||
assert!(name == "testuser");
|
||||
Ok(UserAccountEntity {
|
||||
@ -271,6 +280,7 @@ mod test {
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl EntityGateway for TestData {
|
||||
type Transaction = ();
|
||||
async fn get_user_by_name(&mut self, _name: String) -> Result<UserAccountEntity, GatewayError> {
|
||||
Err(GatewayError::Error)
|
||||
}
|
||||
@ -305,6 +315,7 @@ mod test {
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl EntityGateway for TestData {
|
||||
type Transaction = ();
|
||||
async fn get_user_by_name(&mut self, name: String) -> Result<UserAccountEntity, GatewayError> {
|
||||
assert!(name == "testuser");
|
||||
Ok(UserAccountEntity {
|
||||
@ -354,6 +365,7 @@ mod test {
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl EntityGateway for TestData {
|
||||
type Transaction = ();
|
||||
async fn get_user_by_name(&mut self, name: String) -> Result<UserAccountEntity, GatewayError> {
|
||||
assert!(name == "testuser");
|
||||
Ok(UserAccountEntity {
|
||||
|
@ -6,12 +6,12 @@ use std::pin::Pin;
|
||||
|
||||
use crate::ship::map::MapArea;
|
||||
use crate::entity::character::{CharacterEntity, CharacterEntityId};
|
||||
use crate::entity::gateway::EntityGatewayTransaction;
|
||||
use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction};
|
||||
use crate::ship::items::state::{ItemStateProxy, ItemStateError, AddItemResult, StackedItemDetail, IndividualItemDetail};
|
||||
use crate::ship::items::bank::{BankItem, BankItemDetail};
|
||||
use crate::ship::items::inventory::{InventoryItem, InventoryItemDetail};
|
||||
use crate::ship::items::floor::{FloorItem, FloorItemDetail};
|
||||
use crate::ship::items::apply_item::apply_item;
|
||||
use crate::ship::items::apply_item::{apply_item, ApplyItemAction};
|
||||
use crate::entity::item::{ItemDetail, NewItemEntity, TradeId};
|
||||
use crate::entity::item::tool::Tool;
|
||||
use crate::entity::item::ItemModifier;
|
||||
@ -23,11 +23,16 @@ pub enum TriggerCreateItem {
|
||||
No
|
||||
}
|
||||
|
||||
pub(super) fn take_item_from_floor(character_id: CharacterEntityId, item_id: ClientItemId)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn take_item_from_floor<EG, TR>(
|
||||
character_id: CharacterEntityId,
|
||||
item_id: ClientItemId
|
||||
) -> impl Fn((ItemStateProxy, TR), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), FloorItem), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway + Send,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, transaction): (ItemStateProxy<'_>, Box<dyn EntityGatewayTransaction + '_>) , _| {
|
||||
move |(mut item_state, transaction): (ItemStateProxy, TR) , _| {
|
||||
Box::pin(async move {
|
||||
let mut floor = item_state.floor(&character_id).await?;
|
||||
let item = floor.take_item(&item_id).ok_or_else(|| ItemStateError::NoFloorItem(item_id))?;
|
||||
@ -38,13 +43,18 @@ pub(super) fn take_item_from_floor(character_id: CharacterEntityId, item_id: Cli
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn add_floor_item_to_inventory(character: &CharacterEntity)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), TriggerCreateItem), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn add_floor_item_to_inventory<EG, TR>(
|
||||
character: &CharacterEntity
|
||||
) -> impl Fn((ItemStateProxy, TR), FloorItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), TriggerCreateItem), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + Clone + 'static,
|
||||
{
|
||||
let character = character.clone();
|
||||
move |(mut item_state, transaction), floor_item| {
|
||||
let character = character.clone();
|
||||
let transaction = transaction.clone();
|
||||
Box::pin(async move {
|
||||
let mut inventory = item_state.inventory(&character.id).await?;
|
||||
|
||||
@ -67,7 +77,7 @@ pub(super) fn add_floor_item_to_inventory(character: &CharacterEntity)
|
||||
let add_result = inventory.add_floor_item(floor_item)?;
|
||||
transaction.gateway().set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?;
|
||||
transaction.gateway().set_character_meseta(&character_id, inventory.meseta).await?;
|
||||
item_state.set_inventory(inventory);
|
||||
item_state.set_inventory(inventory).await;
|
||||
|
||||
Ok(((item_state, transaction),
|
||||
match add_result {
|
||||
@ -81,9 +91,15 @@ pub(super) fn add_floor_item_to_inventory(character: &CharacterEntity)
|
||||
|
||||
|
||||
|
||||
pub(super) fn take_item_from_inventory(character_id: CharacterEntityId, item_id: ClientItemId, amount: u32)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn take_item_from_inventory<EG, TR>(
|
||||
character_id: CharacterEntityId,
|
||||
item_id: ClientItemId,
|
||||
amount: u32,
|
||||
) -> impl Fn((ItemStateProxy, TR), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), InventoryItem), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, mut transaction), _| {
|
||||
Box::pin(async move {
|
||||
@ -91,7 +107,7 @@ pub(super) fn take_item_from_inventory(character_id: CharacterEntityId, item_id:
|
||||
let item = inventory.take_item(&item_id, amount).ok_or_else(|| ItemStateError::NoFloorItem(item_id))?;
|
||||
|
||||
transaction.gateway().set_character_inventory(&character_id, &inventory.as_inventory_entity(&character_id)).await?;
|
||||
item_state.set_inventory(inventory);
|
||||
item_state.set_inventory(inventory).await;
|
||||
|
||||
Ok(((item_state, transaction), item))
|
||||
})
|
||||
@ -99,9 +115,15 @@ pub(super) fn take_item_from_inventory(character_id: CharacterEntityId, item_id:
|
||||
}
|
||||
|
||||
|
||||
pub(super) fn add_inventory_item_to_shared_floor(character_id: CharacterEntityId, map_area: MapArea, drop_position: (f32, f32, f32))
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn add_inventory_item_to_shared_floor<EG, TR>(
|
||||
character_id: CharacterEntityId,
|
||||
map_area: MapArea,
|
||||
drop_position: (f32, f32, f32),
|
||||
) -> impl Fn((ItemStateProxy, TR), InventoryItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), FloorItem), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, transaction), inventory_item| {
|
||||
Box::pin(async move {
|
||||
@ -127,43 +149,59 @@ pub(super) fn add_inventory_item_to_shared_floor(character_id: CharacterEntityId
|
||||
}
|
||||
|
||||
|
||||
pub(super) fn take_meseta_from_inventory(character_id: CharacterEntityId, amount: u32)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn take_meseta_from_inventory<EG, TR>(
|
||||
character_id: CharacterEntityId,
|
||||
amount: u32,
|
||||
) -> impl Fn((ItemStateProxy, TR), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), ()), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, mut transaction), _| {
|
||||
Box::pin(async move {
|
||||
let mut inventory = item_state.inventory(&character_id).await?;
|
||||
inventory.remove_meseta(amount)?;
|
||||
transaction.gateway().set_character_meseta(&character_id, inventory.meseta).await?;
|
||||
item_state.set_inventory(inventory);
|
||||
item_state.set_inventory(inventory).await;
|
||||
|
||||
Ok(((item_state, transaction), ()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn add_meseta_to_inventory(character_id: CharacterEntityId, amount: u32)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn add_meseta_to_inventory<EG, TR>(
|
||||
character_id: CharacterEntityId,
|
||||
amount: u32
|
||||
) -> impl Fn((ItemStateProxy, TR), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), ()), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, mut transaction), _| {
|
||||
Box::pin(async move {
|
||||
let mut inventory = item_state.inventory(&character_id).await?;
|
||||
inventory.add_meseta(amount)?;
|
||||
transaction.gateway().set_character_meseta(&character_id, inventory.meseta).await?;
|
||||
item_state.set_inventory(inventory);
|
||||
item_state.set_inventory(inventory).await;
|
||||
|
||||
Ok(((item_state, transaction), ()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn add_meseta_to_shared_floor(character_id: CharacterEntityId, amount: u32, map_area: MapArea, drop_position: (f32, f32))
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn add_meseta_to_shared_floor<EG, TR>(
|
||||
character_id: CharacterEntityId,
|
||||
amount: u32,
|
||||
map_area: MapArea,
|
||||
drop_position: (f32, f32)
|
||||
) -> impl Fn((ItemStateProxy, TR), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), FloorItem), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
|
||||
move |(mut item_state, transaction), _| {
|
||||
Box::pin(async move {
|
||||
let floor_item = FloorItem {
|
||||
@ -184,9 +222,14 @@ pub(super) fn add_meseta_to_shared_floor(character_id: CharacterEntityId, amount
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn take_meseta_from_bank(character_id: CharacterEntityId, amount: u32)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn take_meseta_from_bank<EG, TR>(
|
||||
character_id: CharacterEntityId,
|
||||
amount: u32,
|
||||
) -> impl Fn((ItemStateProxy, TR), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), ()), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, mut transaction), _| {
|
||||
Box::pin(async move {
|
||||
@ -199,9 +242,14 @@ pub(super) fn take_meseta_from_bank(character_id: CharacterEntityId, amount: u32
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn add_meseta_from_bank_to_inventory(character_id: CharacterEntityId, amount: u32)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn add_meseta_from_bank_to_inventory<EG, TR>(
|
||||
character_id: CharacterEntityId,
|
||||
amount: u32,
|
||||
) -> impl Fn((ItemStateProxy, TR), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), ()), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, mut transaction), _| {
|
||||
Box::pin(async move {
|
||||
@ -215,9 +263,14 @@ pub(super) fn add_meseta_from_bank_to_inventory(character_id: CharacterEntityId,
|
||||
}
|
||||
|
||||
|
||||
pub(super) fn add_meseta_to_bank(character_id: CharacterEntityId, amount: u32)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn add_meseta_to_bank<EG, TR>(
|
||||
character_id: CharacterEntityId,
|
||||
amount: u32,
|
||||
) -> impl Fn((ItemStateProxy, TR), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), ()), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, mut transaction), _| {
|
||||
Box::pin(async move {
|
||||
@ -231,25 +284,35 @@ pub(super) fn add_meseta_to_bank(character_id: CharacterEntityId, amount: u32)
|
||||
}
|
||||
|
||||
|
||||
pub(super) fn take_item_from_bank(character_id: CharacterEntityId, item_id: ClientItemId, amount: u32)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), BankItem), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn take_item_from_bank<EG, TR>(
|
||||
character_id: CharacterEntityId,
|
||||
item_id: ClientItemId,
|
||||
amount: u32,
|
||||
) -> impl Fn((ItemStateProxy, TR), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), BankItem), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, mut transaction), _| {
|
||||
Box::pin(async move {
|
||||
let mut bank = item_state.bank(&character_id).await?;
|
||||
let item = bank.take_item(&item_id, amount).ok_or_else(|| ItemStateError::NoBankItem(item_id))?;
|
||||
transaction.gateway().set_character_bank(&character_id, &bank.as_bank_entity(), &bank.name).await?;
|
||||
item_state.set_bank(bank);
|
||||
item_state.set_bank(bank).await;
|
||||
|
||||
Ok(((item_state, transaction), item))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn add_bank_item_to_inventory(character: &CharacterEntity)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), BankItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn add_bank_item_to_inventory<EG, TR>(
|
||||
character: &CharacterEntity,
|
||||
) -> impl Fn((ItemStateProxy, TR), BankItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), InventoryItem), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
let character = character.clone();
|
||||
move |(mut item_state, transaction), bank_item| {
|
||||
@ -286,7 +349,7 @@ pub(super) fn add_bank_item_to_inventory(character: &CharacterEntity)
|
||||
|
||||
inventory.add_item(inventory_item.clone())?;
|
||||
transaction.gateway().set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?;
|
||||
item_state.set_inventory(inventory);
|
||||
item_state.set_inventory(inventory).await;
|
||||
|
||||
Ok(((item_state, transaction), inventory_item))
|
||||
})
|
||||
@ -294,9 +357,13 @@ pub(super) fn add_bank_item_to_inventory(character: &CharacterEntity)
|
||||
}
|
||||
|
||||
|
||||
pub(super) fn add_inventory_item_to_bank(character_id: CharacterEntityId)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn add_inventory_item_to_bank<EG, TR>(
|
||||
character_id: CharacterEntityId,
|
||||
) -> impl Fn((ItemStateProxy, TR), InventoryItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), ()), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, transaction), inventory_item| {
|
||||
Box::pin(async move {
|
||||
@ -315,7 +382,7 @@ pub(super) fn add_inventory_item_to_bank(character_id: CharacterEntityId)
|
||||
bank.add_inventory_item(inventory_item)?;
|
||||
|
||||
transaction.gateway().set_character_bank(&character_id, &bank.as_bank_entity(), &bank.name).await?;
|
||||
item_state.set_bank(bank);
|
||||
item_state.set_bank(bank).await;
|
||||
|
||||
|
||||
Ok(((item_state, transaction), ()))
|
||||
@ -324,16 +391,22 @@ pub(super) fn add_inventory_item_to_bank(character_id: CharacterEntityId)
|
||||
}
|
||||
|
||||
|
||||
pub(super) fn equip_inventory_item(character_id: CharacterEntityId, item_id: ClientItemId, equip_slot: u8)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn equip_inventory_item<EG, TR>(
|
||||
character_id: CharacterEntityId,
|
||||
item_id: ClientItemId,
|
||||
equip_slot: u8,
|
||||
) -> impl Fn((ItemStateProxy, TR), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), ()), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, mut transaction), _| {
|
||||
Box::pin(async move {
|
||||
let mut inventory = item_state.inventory(&character_id).await?;
|
||||
inventory.equip(&item_id, equip_slot);
|
||||
transaction.gateway().set_character_equips(&character_id, &inventory.as_equipped_entity()).await?;
|
||||
item_state.set_inventory(inventory);
|
||||
item_state.set_inventory(inventory).await;
|
||||
|
||||
Ok(((item_state, transaction), ()))
|
||||
})
|
||||
@ -341,16 +414,21 @@ pub(super) fn equip_inventory_item(character_id: CharacterEntityId, item_id: Cli
|
||||
}
|
||||
|
||||
|
||||
pub(super) fn unequip_inventory_item(character_id: CharacterEntityId, item_id: ClientItemId)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn unequip_inventory_item<EG, TR>(
|
||||
character_id: CharacterEntityId,
|
||||
item_id: ClientItemId,
|
||||
) -> impl Fn((ItemStateProxy, TR), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), ()), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, mut transaction), _| {
|
||||
Box::pin(async move {
|
||||
let mut inventory = item_state.inventory(&character_id).await?;
|
||||
inventory.unequip(&item_id);
|
||||
transaction.gateway().set_character_equips(&character_id, &inventory.as_equipped_entity()).await?;
|
||||
item_state.set_inventory(inventory);
|
||||
item_state.set_inventory(inventory).await;
|
||||
|
||||
Ok(((item_state, transaction), ()))
|
||||
})
|
||||
@ -359,9 +437,14 @@ pub(super) fn unequip_inventory_item(character_id: CharacterEntityId, item_id: C
|
||||
|
||||
|
||||
|
||||
pub(super) fn sort_inventory_items(character_id: CharacterEntityId, item_ids: Vec<ClientItemId>)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn sort_inventory_items<EG, TR>(
|
||||
character_id: CharacterEntityId,
|
||||
item_ids: Vec<ClientItemId>,
|
||||
) -> impl Fn((ItemStateProxy, TR), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), ()), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, mut transaction), _| {
|
||||
let item_ids = item_ids.clone();
|
||||
@ -369,7 +452,7 @@ pub(super) fn sort_inventory_items(character_id: CharacterEntityId, item_ids: Ve
|
||||
let mut inventory = item_state.inventory(&character_id).await?;
|
||||
inventory.sort(&item_ids);
|
||||
transaction.gateway().set_character_inventory(&character_id, &inventory.as_inventory_entity(&character_id)).await?;
|
||||
item_state.set_inventory(inventory);
|
||||
item_state.set_inventory(inventory).await;
|
||||
|
||||
Ok(((item_state, transaction), ()))
|
||||
})
|
||||
@ -377,9 +460,13 @@ pub(super) fn sort_inventory_items(character_id: CharacterEntityId, item_ids: Ve
|
||||
}
|
||||
|
||||
|
||||
pub(super) fn use_consumed_item(character: CharacterEntity)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), CharacterEntity), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn use_consumed_item<EG, TR>(
|
||||
character: CharacterEntity,
|
||||
) -> impl Fn((ItemStateProxy, TR), InventoryItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), Vec<ApplyItemAction>), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway + Clone + 'static,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, transaction), inventory_item| {
|
||||
let mut character = character.clone();
|
||||
@ -390,17 +477,22 @@ pub(super) fn use_consumed_item(character: CharacterEntity)
|
||||
Ok(transaction)
|
||||
}}).await?;
|
||||
|
||||
apply_item(&mut item_state, transaction.gateway(), &mut character, inventory_item).await?;
|
||||
let apply_item_actions = apply_item(&mut item_state, transaction.gateway(), &mut character, inventory_item).await?;
|
||||
|
||||
Ok(((item_state, transaction), character))
|
||||
Ok(((item_state, transaction), apply_item_actions))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub(super) fn feed_mag_item(character: CharacterEntity, mag_item_id: ClientItemId)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), CharacterEntity), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn feed_mag_item<EG, TR>(
|
||||
character: CharacterEntity,
|
||||
mag_item_id: ClientItemId,
|
||||
) -> impl Fn((ItemStateProxy, TR), InventoryItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), CharacterEntity), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, transaction), tool| {
|
||||
let character = character.clone();
|
||||
@ -437,7 +529,7 @@ pub(super) fn feed_mag_item(character: CharacterEntity, mag_item_id: ClientItemI
|
||||
mag_entity.feed(food_tool);
|
||||
|
||||
transaction.gateway().set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?;
|
||||
item_state.set_inventory(inventory);
|
||||
item_state.set_inventory(inventory).await;
|
||||
|
||||
Ok(((item_state, transaction), character))
|
||||
})
|
||||
@ -445,12 +537,16 @@ pub(super) fn feed_mag_item(character: CharacterEntity, mag_item_id: ClientItemI
|
||||
}
|
||||
|
||||
|
||||
pub(super) fn add_bought_item_to_inventory<'a>(character_id: CharacterEntityId,
|
||||
shop_item: &'a (dyn ShopItem + Send + Sync),
|
||||
item_id: ClientItemId,
|
||||
amount: u32)
|
||||
-> impl Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn add_bought_item_to_inventory<'a, EG, TR>(
|
||||
character_id: CharacterEntityId,
|
||||
shop_item: &'a (dyn ShopItem + Send + Sync),
|
||||
item_id: ClientItemId,
|
||||
amount: u32,
|
||||
) -> impl Fn((ItemStateProxy, TR), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), InventoryItem), ItemStateError>> + Send + 'a>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, mut transaction), _| {
|
||||
Box::pin(async move {
|
||||
@ -499,16 +595,20 @@ pub(super) fn add_bought_item_to_inventory<'a>(character_id: CharacterEntityId,
|
||||
};
|
||||
|
||||
transaction.gateway().set_character_inventory(&character_id, &inventory.as_inventory_entity(&character_id)).await?;
|
||||
item_state.set_inventory(inventory);
|
||||
item_state.set_inventory(inventory).await;
|
||||
Ok(((item_state, transaction), inventory_item))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub(super) fn sell_inventory_item<'a>(character_id: CharacterEntityId)
|
||||
-> impl Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn sell_inventory_item<EG, TR>(
|
||||
character_id: CharacterEntityId,
|
||||
) -> impl Fn((ItemStateProxy, TR), InventoryItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), InventoryItem), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, transaction), inventory_item| {
|
||||
Box::pin(async move {
|
||||
@ -522,7 +622,7 @@ pub(super) fn sell_inventory_item<'a>(character_id: CharacterEntityId)
|
||||
Ok(transaction)
|
||||
}}).await?;
|
||||
transaction.gateway().set_character_meseta(&character_id, inventory.meseta).await?;
|
||||
item_state.set_inventory(inventory);
|
||||
item_state.set_inventory(inventory).await;
|
||||
Ok(((item_state, transaction), inventory_item))
|
||||
})
|
||||
}
|
||||
@ -530,19 +630,22 @@ pub(super) fn sell_inventory_item<'a>(character_id: CharacterEntityId)
|
||||
|
||||
|
||||
#[async_recursion::async_recursion]
|
||||
async fn iterate_inner<'a, I, O, T, F, FR>(state: (ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>),
|
||||
mut input: Vec<I>,
|
||||
func: F,
|
||||
arg: T)
|
||||
-> Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), Vec<O>), ItemStateError>
|
||||
async fn iterate_inner<'a, EG, TR, I, O, T, F, FR>(
|
||||
state: (ItemStateProxy, TR),
|
||||
mut input: Vec<I>,
|
||||
func: F,
|
||||
arg: T,
|
||||
) -> Result<((ItemStateProxy, TR), Vec<O>), ItemStateError>
|
||||
where
|
||||
'a: 'async_recursion,
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG>,
|
||||
I: Send,
|
||||
O: Send,
|
||||
T: Clone + Send + Sync,
|
||||
F: Fn(I) -> FR + Send + Sync + Clone + 'static,
|
||||
FR: Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), T)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), O), ItemStateError>> + Send + 'a>> + Send + Sync,
|
||||
FR: Fn((ItemStateProxy, TR), T)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), O), ItemStateError>> + Send>> + Send + Sync,
|
||||
{
|
||||
let item = match input.pop() {
|
||||
Some(item) => item,
|
||||
@ -558,18 +661,20 @@ where
|
||||
Ok((state, output))
|
||||
}
|
||||
|
||||
pub(super) fn iterate<'k, I, O, T, F, FR>(
|
||||
pub(super) fn iterate<'k, EG, TR, I, O, T, F, FR>(
|
||||
input: Vec<I>,
|
||||
func: F)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), T)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), Vec<O>), ItemStateError>> + Send + 'a>>
|
||||
func: F,
|
||||
) -> impl Fn((ItemStateProxy, TR), T)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), Vec<O>), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
O: Send,
|
||||
I: Send + Clone + 'static + std::fmt::Debug,
|
||||
T: Send + Clone + 'static + std::fmt::Debug,
|
||||
F: Fn(I) -> FR + Send + Sync + Clone + 'static,
|
||||
FR: for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), T)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), O), ItemStateError>> + Send + 'a>> + Send + Sync,
|
||||
FR: Fn((ItemStateProxy, TR), T)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), O), ItemStateError>> + Send>> + Send + Sync,
|
||||
T: Clone + Send + Sync,
|
||||
{
|
||||
move |(item_state, transaction), arg| {
|
||||
@ -584,16 +689,19 @@ where
|
||||
|
||||
|
||||
#[async_recursion::async_recursion]
|
||||
async fn foreach_inner<'a, O, T, F>(state: (ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>),
|
||||
mut input: Vec<T>,
|
||||
func: F)
|
||||
-> Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), Vec<O>), ItemStateError>
|
||||
async fn foreach_inner<'a, EG, TR, O, T, F>(
|
||||
state: (ItemStateProxy, TR),
|
||||
mut input: Vec<T>,
|
||||
func: F,
|
||||
) -> Result<((ItemStateProxy, TR), Vec<O>), ItemStateError>
|
||||
where
|
||||
'a: 'async_recursion,
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
O: Send,
|
||||
T: Clone + Send,
|
||||
F: Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), T)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), O), ItemStateError>> + Send + 'a>> + Send + Sync,
|
||||
F: Fn((ItemStateProxy, TR), T)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), O), ItemStateError>> + Send>> + Send + Sync,
|
||||
F: Clone,
|
||||
{
|
||||
let item = match input.pop() {
|
||||
@ -609,14 +717,17 @@ where
|
||||
Ok((state, output))
|
||||
}
|
||||
|
||||
pub(super) fn foreach<'k, O, T, F>(func: F)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), Vec<T>)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), Vec<O>), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn foreach<'k, EG, TR, O, T, F>(
|
||||
func: F
|
||||
) -> impl Fn((ItemStateProxy, TR), Vec<T>)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), Vec<O>), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
O: Send,
|
||||
T: Send + Clone + 'static + std::fmt::Debug,
|
||||
F: for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), T)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), O), ItemStateError>> + Send + 'a>> + Send + Sync + 'static,
|
||||
F: Fn((ItemStateProxy, TR), T)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), O), ItemStateError>> + Send>> + Send + Sync + 'static,
|
||||
F: Clone,
|
||||
T: Clone + Send + Sync,
|
||||
{
|
||||
@ -629,9 +740,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn insert<'a, T: Send + Clone + 'a>(element: T)
|
||||
-> impl Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), T), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn insert<'a, EG, TR, T>(
|
||||
element: T
|
||||
) -> impl Fn((ItemStateProxy, TR), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), T), ItemStateError>> + Send + 'a>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
T: Send + Clone + 'a,
|
||||
{
|
||||
move |state, _| {
|
||||
let element = element.clone();
|
||||
@ -641,9 +757,13 @@ pub(super) fn insert<'a, T: Send + Clone + 'a>(element: T)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn add_item_to_inventory(character: CharacterEntity)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>> + Clone
|
||||
pub(super) fn add_item_to_inventory<EG, TR>(
|
||||
character: CharacterEntity,
|
||||
) -> impl Fn((ItemStateProxy, TR), InventoryItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), InventoryItem), ItemStateError>> + Send>> + Clone
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, transaction), inventory_item| {
|
||||
let character = character.clone();
|
||||
@ -658,16 +778,22 @@ pub(super) fn add_item_to_inventory(character: CharacterEntity)
|
||||
|
||||
inventory.add_item(inventory_item.clone())?;
|
||||
transaction.gateway().set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?;
|
||||
item_state.set_inventory(inventory);
|
||||
item_state.set_inventory(inventory).await;
|
||||
|
||||
Ok(((item_state, transaction), inventory_item))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn record_trade(trade_id: TradeId, character_to: CharacterEntityId, character_from: CharacterEntityId)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), Vec<InventoryItem>)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), Vec<InventoryItem>), ItemStateError>> + Send + 'a>> + Clone
|
||||
pub(super) fn record_trade<EG, TR>(
|
||||
trade_id: TradeId,
|
||||
character_to: CharacterEntityId,
|
||||
character_from: CharacterEntityId,
|
||||
) -> impl Fn((ItemStateProxy, TR), Vec<InventoryItem>)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), Vec<InventoryItem>), ItemStateError>> + Send>> + Clone
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(item_state, mut transaction), traded_items| {
|
||||
Box::pin(async move {
|
||||
@ -688,9 +814,12 @@ pub(super) fn record_trade(trade_id: TradeId, character_to: CharacterEntityId, c
|
||||
}
|
||||
|
||||
|
||||
pub(super) fn assign_new_item_id()
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>> + Clone
|
||||
pub(super) fn assign_new_item_id<EG, TR>(
|
||||
) -> impl Fn((ItemStateProxy, TR), InventoryItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), InventoryItem), ItemStateError>> + Send>> + Clone
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, transaction), mut inventory_item| {
|
||||
Box::pin(async move {
|
||||
@ -701,9 +830,14 @@ pub(super) fn assign_new_item_id()
|
||||
}
|
||||
|
||||
|
||||
pub(super) fn convert_item_drop_to_floor_item(character_id: CharacterEntityId, item_drop: ItemDrop)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem), ItemStateError>> + Send + 'a>> + Clone
|
||||
pub(super) fn convert_item_drop_to_floor_item<EG, TR>(
|
||||
character_id: CharacterEntityId,
|
||||
item_drop: ItemDrop,
|
||||
) -> impl Fn((ItemStateProxy, TR), ())
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), FloorItem), ItemStateError>> + Send>> + Clone
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, mut transaction), _| {
|
||||
let item_drop = item_drop.clone();
|
||||
@ -798,9 +932,13 @@ pub(super) fn convert_item_drop_to_floor_item(character_id: CharacterEntityId, i
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn add_item_to_local_floor(character_id: CharacterEntityId)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn add_item_to_local_floor<EG, TR>(
|
||||
character_id: CharacterEntityId,
|
||||
) -> impl Fn((ItemStateProxy, TR), FloorItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), FloorItem), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(mut item_state, transaction) , floor_item| {
|
||||
Box::pin(async move {
|
||||
@ -813,9 +951,13 @@ pub(super) fn add_item_to_local_floor(character_id: CharacterEntityId)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn apply_modifier_to_inventory_item(modifier: ItemModifier)
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn apply_modifier_to_inventory_item<EG, TR>(
|
||||
modifier: ItemModifier,
|
||||
) -> impl Fn((ItemStateProxy, TR), InventoryItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), InventoryItem), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(item_state, mut transaction), mut inventory_item| {
|
||||
let modifier = modifier.clone();
|
||||
@ -833,9 +975,12 @@ pub(super) fn apply_modifier_to_inventory_item(modifier: ItemModifier)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn as_individual_item()
|
||||
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), IndividualItemDetail), ItemStateError>> + Send + 'a>>
|
||||
pub(super) fn as_individual_item<EG, TR>(
|
||||
) -> impl Fn((ItemStateProxy, TR), InventoryItem)
|
||||
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), IndividualItemDetail), ItemStateError>> + Send>>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
|
||||
{
|
||||
move |(item_state, transaction), inventory_item| {
|
||||
Box::pin(async move {
|
||||
|
@ -1,5 +1,7 @@
|
||||
use thiserror::Error;
|
||||
use std::convert::TryInto;
|
||||
use futures::future::{join_all, BoxFuture, LocalBoxFuture};
|
||||
use futures::stream::{FuturesOrdered, StreamExt};
|
||||
use thiserror::Error;
|
||||
use crate::entity::gateway::{EntityGateway, GatewayError};
|
||||
use crate::entity::character::CharacterEntity;
|
||||
use crate::entity::item::mag::{MagCell, MagCellError};
|
||||
@ -27,53 +29,57 @@ pub enum ApplyItemError {
|
||||
MagCellError(#[from] MagCellError),
|
||||
}
|
||||
|
||||
pub enum ApplyItemAction {
|
||||
UpdateCharacter(CharacterEntity),
|
||||
CreateItem(()),
|
||||
}
|
||||
|
||||
impl From<ItemStateError> for ApplyItemError {
|
||||
fn from(other: ItemStateError) -> ApplyItemError {
|
||||
ApplyItemError::ItemStateError(Box::new(other))
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: make all these functions not-pub
|
||||
pub async fn power_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
|
||||
async fn power_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, ApplyItemError> {
|
||||
character.materials.power += 1;
|
||||
entity_gateway.save_character(character).await?;
|
||||
Ok(())
|
||||
Ok(vec![ApplyItemAction::UpdateCharacter(character.clone())])
|
||||
}
|
||||
|
||||
pub async fn mind_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
|
||||
async fn mind_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, ApplyItemError> {
|
||||
character.materials.mind += 1;
|
||||
entity_gateway.save_character(character).await.unwrap();
|
||||
Ok(())
|
||||
Ok(vec![ApplyItemAction::UpdateCharacter(character.clone())])
|
||||
}
|
||||
|
||||
pub async fn evade_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
|
||||
async fn evade_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, ApplyItemError> {
|
||||
character.materials.evade += 1;
|
||||
entity_gateway.save_character(character).await.unwrap();
|
||||
Ok(())
|
||||
Ok(vec![ApplyItemAction::UpdateCharacter(character.clone())])
|
||||
}
|
||||
|
||||
pub async fn def_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
|
||||
async fn def_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, ApplyItemError> {
|
||||
character.materials.def += 1;
|
||||
entity_gateway.save_character(character).await.unwrap();
|
||||
Ok(())
|
||||
Ok(vec![ApplyItemAction::UpdateCharacter(character.clone())])
|
||||
}
|
||||
|
||||
pub async fn luck_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
|
||||
async fn luck_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, ApplyItemError> {
|
||||
character.materials.luck += 1;
|
||||
entity_gateway.save_character(character).await.unwrap();
|
||||
Ok(())
|
||||
Ok(vec![ApplyItemAction::UpdateCharacter(character.clone())])
|
||||
}
|
||||
|
||||
pub async fn hp_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
|
||||
async fn hp_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, ApplyItemError> {
|
||||
character.materials.hp += 1;
|
||||
entity_gateway.save_character(character).await.unwrap();
|
||||
Ok(())
|
||||
Ok(vec![ApplyItemAction::UpdateCharacter(character.clone())])
|
||||
}
|
||||
|
||||
pub async fn tp_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
|
||||
async fn tp_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, ApplyItemError> {
|
||||
character.materials.tp += 1;
|
||||
entity_gateway.save_character(character).await.unwrap();
|
||||
Ok(())
|
||||
Ok(vec![ApplyItemAction::UpdateCharacter(character.clone())])
|
||||
}
|
||||
|
||||
/*
|
||||
@ -98,12 +104,12 @@ async fn mag_cell<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &Consum
|
||||
*/
|
||||
|
||||
|
||||
async fn mag_cell<'a, EG>(item_state: &mut ItemStateProxy<'a>,
|
||||
async fn mag_cell<'a, EG>(item_state: &mut ItemStateProxy,
|
||||
entity_gateway: &mut EG,
|
||||
character: &CharacterEntity,
|
||||
cell_entity_id: ItemEntityId,
|
||||
mag_cell_type: MagCell)
|
||||
-> Result<(), ApplyItemError>
|
||||
-> Result<Vec<ApplyItemAction>, ApplyItemError>
|
||||
where
|
||||
EG: EntityGateway + ?Sized,
|
||||
{
|
||||
@ -117,7 +123,7 @@ where
|
||||
entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?;
|
||||
item_state.set_inventory(inventory);
|
||||
|
||||
Ok(())
|
||||
Ok(Vec::new())
|
||||
}
|
||||
|
||||
/*
|
||||
@ -218,12 +224,21 @@ pub async fn liberta_kit<EG: EntityGateway>(entity_gateway: &mut EG, used_cell:
|
||||
}
|
||||
*/
|
||||
|
||||
async fn apply_tool<'a, EG>(item_state: &mut ItemStateProxy<'a>,
|
||||
async fn jack_o_lantern<'a, EG>(item_state: &mut ItemStateProxy,
|
||||
entity_gateway: &mut EG
|
||||
) -> Result<Vec<ApplyItemAction>, ApplyItemError>
|
||||
where
|
||||
EG: EntityGateway + ?Sized,
|
||||
{
|
||||
Ok(Vec::new())
|
||||
}
|
||||
|
||||
async fn apply_tool<'a, EG>(item_state: &mut ItemStateProxy,
|
||||
entity_gateway: &mut EG,
|
||||
character: &mut CharacterEntity,
|
||||
entity_id: ItemEntityId,
|
||||
tool: ToolType)
|
||||
-> Result<(), ApplyItemError>
|
||||
-> Result<Vec<ApplyItemAction>, ApplyItemError>
|
||||
where
|
||||
EG: EntityGateway + ?Sized,
|
||||
{
|
||||
@ -235,13 +250,13 @@ where
|
||||
ToolType::LuckMaterial => luck_material(entity_gateway, character).await,
|
||||
ToolType::HpMaterial => hp_material(entity_gateway, character).await,
|
||||
ToolType::TpMaterial => tp_material(entity_gateway, character).await,
|
||||
ToolType::Monomate => Ok(()),
|
||||
ToolType::Dimate => Ok(()),
|
||||
ToolType::Trimate => Ok(()),
|
||||
ToolType::Monofluid => Ok(()),
|
||||
ToolType::Difluid => Ok(()),
|
||||
ToolType::Trifluid => Ok(()),
|
||||
ToolType::HuntersReport => Ok(()),
|
||||
ToolType::Monomate => Ok(Vec::new()),
|
||||
ToolType::Dimate => Ok(Vec::new()),
|
||||
ToolType::Trimate => Ok(Vec::new()),
|
||||
ToolType::Monofluid => Ok(Vec::new()),
|
||||
ToolType::Difluid => Ok(Vec::new()),
|
||||
ToolType::Trifluid => Ok(Vec::new()),
|
||||
ToolType::HuntersReport => Ok(Vec::new()),
|
||||
ToolType::CellOfMag502
|
||||
| ToolType::CellOfMag213
|
||||
| ToolType::PartsOfRobochao
|
||||
@ -268,6 +283,7 @@ where
|
||||
| ToolType::LibertaKit => {
|
||||
mag_cell(item_state, entity_gateway, character, entity_id, tool.try_into()?).await
|
||||
}
|
||||
ToolType::JackOLantern => jack_o_lantern(item_state, entity_gateway).await,
|
||||
// TODO: rest of these
|
||||
_ => Err(ApplyItemError::InvalidItem)
|
||||
}
|
||||
@ -275,7 +291,14 @@ where
|
||||
}
|
||||
|
||||
|
||||
pub async fn apply_item<'a, EG: EntityGateway + ?Sized>(item_state: &mut ItemStateProxy<'a>, entity_gateway: &mut EG, character: &mut CharacterEntity, item: InventoryItem) -> Result<(), ApplyItemError> {
|
||||
pub async fn apply_item<'a, EG>(item_state: &mut ItemStateProxy,
|
||||
entity_gateway: &mut EG,
|
||||
character: &mut CharacterEntity,
|
||||
item: InventoryItem
|
||||
) -> Result<Vec<ApplyItemAction>, ApplyItemError>
|
||||
where
|
||||
EG: EntityGateway + ?Sized + Clone + 'static
|
||||
{
|
||||
match item.item {
|
||||
InventoryItemDetail::Individual(individual_item) => {
|
||||
match individual_item.item {
|
||||
@ -284,10 +307,22 @@ pub async fn apply_item<'a, EG: EntityGateway + ?Sized>(item_state: &mut ItemSta
|
||||
}
|
||||
},
|
||||
InventoryItemDetail::Stacked(stacked_item) => {
|
||||
for entity_id in stacked_item.entity_ids {
|
||||
apply_tool(item_state, entity_gateway, character, entity_id, stacked_item.tool.tool).await?
|
||||
}
|
||||
Ok(())
|
||||
Ok(join_all(stacked_item.entity_ids.iter()
|
||||
.map(|entity_id| {
|
||||
let mut entity_gateway = entity_gateway.clone();
|
||||
let mut character = character.clone();
|
||||
let mut item_state = item_state.clone();
|
||||
async move {
|
||||
apply_tool(&mut item_state, &mut entity_gateway, &mut character, *entity_id, stacked_item.tool.tool).await
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>())
|
||||
.await
|
||||
.into_iter()
|
||||
.collect::<Result<Vec<Vec<_>>, _>>()?
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.collect())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use std::collections::HashMap;
|
||||
use async_std::sync::{Arc, RwLock};
|
||||
use async_std::sync::{Arc, RwLock, Mutex};
|
||||
use futures::future::join_all;
|
||||
|
||||
use crate::entity::gateway::{EntityGateway, GatewayError};
|
||||
@ -373,36 +373,38 @@ impl ItemState {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Default)]
|
||||
#[derive(Default, Clone)]
|
||||
struct ProxiedItemState {
|
||||
character_inventory: HashMap<CharacterEntityId, InventoryState>,
|
||||
character_bank: HashMap<CharacterEntityId, BankState>,
|
||||
character_inventory: Arc<Mutex<HashMap<CharacterEntityId, InventoryState>>>,
|
||||
character_bank: Arc<Mutex<HashMap<CharacterEntityId, BankState>>>,
|
||||
|
||||
//character_room: HashMap<CharacterEntityId, RoomId>,
|
||||
character_floor: HashMap<CharacterEntityId, LocalFloor>,
|
||||
room_floor: HashMap<RoomId, SharedFloor>,
|
||||
character_floor: Arc<Mutex<HashMap<CharacterEntityId, LocalFloor>>>,
|
||||
room_floor: Arc<Mutex<HashMap<RoomId, SharedFloor>>>,
|
||||
}
|
||||
|
||||
pub struct ItemStateProxy<'a> {
|
||||
item_state: &'a mut ItemState,
|
||||
#[derive(Clone)]
|
||||
pub struct ItemStateProxy {
|
||||
item_state: ItemState,
|
||||
proxied_state: ProxiedItemState,
|
||||
}
|
||||
|
||||
impl<'a> ItemStateProxy<'a> {
|
||||
impl ItemStateProxy {
|
||||
pub async fn commit(self) {
|
||||
async fn copy_back<K, V>(master: &Arc<RwLock<HashMap<K, RwLock<V>>>>,
|
||||
proxy: HashMap<K, V>)
|
||||
proxy: Arc<Mutex<HashMap<K, V>>>)
|
||||
where
|
||||
K: Eq + std::hash::Hash,
|
||||
V: Clone,
|
||||
{
|
||||
for (key, value) in proxy {
|
||||
for (key, value) in proxy.lock().await.iter() {
|
||||
if let Some(element) = master
|
||||
.read()
|
||||
.await
|
||||
.get(&key) {
|
||||
*element
|
||||
.write()
|
||||
.await = value;
|
||||
.await = value.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -417,7 +419,7 @@ impl<'a> ItemStateProxy<'a> {
|
||||
|
||||
|
||||
async fn get_or_clone<K, V>(master: &Arc<RwLock<HashMap<K, RwLock<V>>>>,
|
||||
proxy: &mut HashMap<K, V>,
|
||||
proxy: &Arc<Mutex<HashMap<K, V>>>,
|
||||
key: K,
|
||||
err: fn(K) -> ItemStateError) -> Result<V, ItemStateError>
|
||||
where
|
||||
@ -432,14 +434,17 @@ where
|
||||
.read()
|
||||
.await
|
||||
.clone();
|
||||
Ok(proxy.entry(key)
|
||||
Ok(proxy
|
||||
.lock()
|
||||
.await
|
||||
.entry(key)
|
||||
.or_insert_with(|| existing_element)
|
||||
.clone())
|
||||
|
||||
}
|
||||
|
||||
impl<'a> ItemStateProxy<'a> {
|
||||
pub fn new(item_state: &'a mut ItemState) -> Self {
|
||||
impl ItemStateProxy {
|
||||
pub fn new(item_state: ItemState) -> Self {
|
||||
ItemStateProxy {
|
||||
item_state,
|
||||
proxied_state: Default::default(),
|
||||
@ -453,8 +458,8 @@ impl<'a> ItemStateProxy<'a> {
|
||||
ItemStateError::NoCharacter).await
|
||||
}
|
||||
|
||||
pub fn set_inventory(&mut self, inventory: InventoryState) {
|
||||
self.proxied_state.character_inventory.insert(inventory.character_id, inventory);
|
||||
pub async fn set_inventory(&mut self, inventory: InventoryState) {
|
||||
self.proxied_state.character_inventory.lock().await.insert(inventory.character_id, inventory);
|
||||
}
|
||||
|
||||
pub async fn bank(&mut self, character_id: &CharacterEntityId) -> Result<BankState, ItemStateError> {
|
||||
@ -464,8 +469,8 @@ impl<'a> ItemStateProxy<'a> {
|
||||
ItemStateError::NoCharacter).await
|
||||
}
|
||||
|
||||
pub fn set_bank(&mut self, bank: BankState) {
|
||||
self.proxied_state.character_bank.insert(bank.character_id, bank);
|
||||
pub async fn set_bank(&mut self, bank: BankState) {
|
||||
self.proxied_state.character_bank.lock().await.insert(bank.character_id, bank);
|
||||
}
|
||||
|
||||
pub async fn floor(&mut self, character_id: &CharacterEntityId) -> Result<FloorState, ItemStateError> {
|
||||
@ -479,8 +484,8 @@ impl<'a> ItemStateProxy<'a> {
|
||||
|
||||
pub async fn set_floor(&mut self, floor: FloorState) {
|
||||
let room_id = *self.item_state.character_room.read().await.get(&floor.character_id).unwrap();
|
||||
self.proxied_state.character_floor.insert(floor.character_id, floor.local);
|
||||
self.proxied_state.room_floor.insert(room_id, floor.shared);
|
||||
self.proxied_state.character_floor.lock().await.insert(floor.character_id, floor.local);
|
||||
self.proxied_state.room_floor.lock().await.insert(room_id, floor.shared);
|
||||
}
|
||||
|
||||
pub async fn new_item_id(&mut self) -> Result<ClientItemId, ItemStateError> {
|
||||
|
@ -1,13 +1,15 @@
|
||||
use crate::ship::items::ClientItemId;
|
||||
use crate::entity::item::Meseta;
|
||||
|
||||
use crate::ship::ship::SendShipPacket;
|
||||
use crate::ship::map::MapArea;
|
||||
use crate::entity::character::{CharacterEntity, CharacterEntityId};
|
||||
use crate::entity::gateway::EntityGateway;
|
||||
use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction};
|
||||
use crate::ship::items::state::{ItemState, ItemStateProxy, ItemStateError, IndividualItemDetail};
|
||||
use crate::ship::items::itemstateaction::{ItemStateAction, ItemAction};
|
||||
use crate::ship::items::inventory::InventoryItem;
|
||||
use crate::ship::items::floor::FloorItem;
|
||||
use crate::ship::items::apply_item::ApplyItemAction;
|
||||
use crate::entity::item::ItemModifier;
|
||||
use crate::ship::shops::ShopItem;
|
||||
use crate::ship::trade::TradeItem;
|
||||
@ -23,10 +25,11 @@ pub async fn pick_up_item<EG>(
|
||||
item_id: &ClientItemId)
|
||||
-> Result<actions::TriggerCreateItem, ItemStateError>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
EG: EntityGateway + 'static,
|
||||
EG::Transaction: Clone,
|
||||
{
|
||||
entity_gateway.with_transaction(|transaction| async move {
|
||||
let item_state_proxy = ItemStateProxy::new(item_state);
|
||||
let item_state_proxy = ItemStateProxy::new(item_state.clone());
|
||||
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
|
||||
.act(actions::take_item_from_floor(character.id, *item_id))
|
||||
.act(actions::add_floor_item_to_inventory(character))
|
||||
@ -46,10 +49,10 @@ pub async fn drop_item<EG>(
|
||||
drop_position: (f32, f32, f32))
|
||||
-> Result<FloorItem, ItemStateError>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
EG: EntityGateway + 'static,
|
||||
{
|
||||
entity_gateway.with_transaction(|transaction| async move {
|
||||
let item_state_proxy = ItemStateProxy::new(item_state);
|
||||
let item_state_proxy = ItemStateProxy::new(item_state.clone());
|
||||
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
|
||||
.act(actions::take_item_from_inventory(character.id, *item_id, 0))
|
||||
.act(actions::add_inventory_item_to_shared_floor(character.id, map_area, drop_position))
|
||||
@ -70,10 +73,10 @@ pub async fn drop_partial_item<'a, EG>(
|
||||
amount: u32)
|
||||
-> Result<FloorItem, ItemStateError>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
EG: EntityGateway + 'static,
|
||||
{
|
||||
entity_gateway.with_transaction(|transaction| async move {
|
||||
let item_state_proxy = ItemStateProxy::new(item_state);
|
||||
let item_state_proxy = ItemStateProxy::new(item_state.clone());
|
||||
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
|
||||
.act(actions::take_item_from_inventory(character.id, *item_id, amount))
|
||||
.act(actions::add_inventory_item_to_shared_floor(character.id, map_area, (drop_position.0, 0.0, drop_position.1)))
|
||||
@ -95,10 +98,10 @@ pub async fn drop_meseta<'a, EG>(
|
||||
amount: u32)
|
||||
-> Result<FloorItem, ItemStateError>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
EG: EntityGateway + 'static,
|
||||
{
|
||||
entity_gateway.with_transaction(|transaction| async move {
|
||||
let item_state_proxy = ItemStateProxy::new(item_state);
|
||||
let item_state_proxy = ItemStateProxy::new(item_state.clone());
|
||||
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
|
||||
.act(actions::take_meseta_from_inventory(character.id, amount))
|
||||
.act(actions::add_meseta_to_shared_floor(character.id, amount, map_area, drop_position))
|
||||
@ -117,10 +120,10 @@ pub async fn withdraw_meseta<'a, EG>(
|
||||
amount: u32)
|
||||
-> Result<(), ItemStateError>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
EG: EntityGateway + 'static,
|
||||
{
|
||||
entity_gateway.with_transaction(|transaction| async move {
|
||||
let item_state_proxy = ItemStateProxy::new(item_state);
|
||||
let item_state_proxy = ItemStateProxy::new(item_state.clone());
|
||||
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
|
||||
.act(actions::take_meseta_from_bank(character.id, amount))
|
||||
.act(actions::add_meseta_from_bank_to_inventory(character.id, amount))
|
||||
@ -139,10 +142,10 @@ pub async fn deposit_meseta<'a, EG>(
|
||||
amount: u32)
|
||||
-> Result<(), ItemStateError>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
EG: EntityGateway + 'static,
|
||||
{
|
||||
entity_gateway.with_transaction(|transaction| async move {
|
||||
let item_state_proxy = ItemStateProxy::new(item_state);
|
||||
let item_state_proxy = ItemStateProxy::new(item_state.clone());
|
||||
let ((item_state_proxy, transaction), _) = ItemStateAction::default()
|
||||
.act(actions::take_meseta_from_inventory(character.id, amount))
|
||||
.act(actions::add_meseta_to_bank(character.id, amount))
|
||||
@ -162,10 +165,10 @@ pub async fn withdraw_item<'a, EG>(
|
||||
amount: u32)
|
||||
-> Result<InventoryItem, ItemStateError>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
EG: EntityGateway + 'static,
|
||||
{
|
||||
entity_gateway.with_transaction(|transaction| async move {
|
||||
let item_state_proxy = ItemStateProxy::new(item_state);
|
||||
let item_state_proxy = ItemStateProxy::new(item_state.clone());
|
||||
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
|
||||
.act(actions::take_item_from_bank(character.id, *item_id, amount))
|
||||
//.act(bank_item_to_inventory_item)
|
||||
@ -187,10 +190,10 @@ pub async fn deposit_item<'a, EG> (
|
||||
amount: u32)
|
||||
-> Result<(), ItemStateError>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
EG: EntityGateway + 'static,
|
||||
{
|
||||
entity_gateway.with_transaction(|transaction| async move {
|
||||
let item_state_proxy = ItemStateProxy::new(item_state);
|
||||
let item_state_proxy = ItemStateProxy::new(item_state.clone());
|
||||
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
|
||||
.act(actions::take_item_from_inventory(character.id, *item_id, amount))
|
||||
.act(actions::add_inventory_item_to_bank(character.id))
|
||||
@ -209,10 +212,10 @@ pub async fn equip_item<'a, EG> (
|
||||
equip_slot: u8,
|
||||
) -> Result<(), ItemStateError>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
EG: EntityGateway + 'static,
|
||||
{
|
||||
entity_gateway.with_transaction(|transaction| async move {
|
||||
let item_state_proxy = ItemStateProxy::new(item_state);
|
||||
let item_state_proxy = ItemStateProxy::new(item_state.clone());
|
||||
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
|
||||
.act(actions::equip_inventory_item(character.id, *item_id, equip_slot))
|
||||
.commit((item_state_proxy, transaction))
|
||||
@ -230,10 +233,10 @@ pub async fn unequip_item<'a, EG> (
|
||||
item_id: &ClientItemId,
|
||||
) -> Result<(), ItemStateError>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
EG: EntityGateway + 'static,
|
||||
{
|
||||
entity_gateway.with_transaction(|transaction| async move {
|
||||
let item_state_proxy = ItemStateProxy::new(item_state);
|
||||
let item_state_proxy = ItemStateProxy::new(item_state.clone());
|
||||
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
|
||||
.act(actions::unequip_inventory_item(character.id, *item_id))
|
||||
.commit((item_state_proxy, transaction))
|
||||
@ -251,10 +254,10 @@ pub async fn sort_inventory<'a, EG> (
|
||||
item_ids: Vec<ClientItemId>,
|
||||
) -> Result<(), ItemStateError>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
EG: EntityGateway + 'static,
|
||||
{
|
||||
entity_gateway.with_transaction(|transaction| async move {
|
||||
let item_state_proxy = ItemStateProxy::new(item_state);
|
||||
let item_state_proxy = ItemStateProxy::new(item_state.clone());
|
||||
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
|
||||
.act(actions::sort_inventory_items(character.id, item_ids))
|
||||
.commit((item_state_proxy, transaction))
|
||||
@ -273,11 +276,11 @@ pub async fn use_item<'a, EG> (
|
||||
amount: u32,
|
||||
) -> Result<(), ItemStateError>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
EG: EntityGateway + 'static,
|
||||
{
|
||||
entity_gateway.with_transaction(|transaction| async move {
|
||||
let item_state_proxy = ItemStateProxy::new(item_state);
|
||||
let ((item_state_proxy, transaction), new_character) = ItemStateAction::default()
|
||||
let item_state_proxy = ItemStateProxy::new(item_state.clone());
|
||||
let ((item_state_proxy, transaction), apply_item_actions) = ItemStateAction::default()
|
||||
.act(actions::take_item_from_inventory(character.id, *item_id, amount))
|
||||
.act(actions::use_consumed_item(character.clone()))
|
||||
.commit((item_state_proxy, transaction))
|
||||
@ -297,10 +300,10 @@ pub async fn feed_mag<'a, EG> (
|
||||
tool_item_id: &ClientItemId,
|
||||
) -> Result<(), ItemStateError>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
EG: EntityGateway + 'static,
|
||||
{
|
||||
entity_gateway.with_transaction(|transaction| async move {
|
||||
let item_state_proxy = ItemStateProxy::new(item_state);
|
||||
let item_state_proxy = ItemStateProxy::new(item_state.clone());
|
||||
let ((item_state_proxy, transaction), _) = ItemStateAction::default()
|
||||
.act(actions::take_item_from_inventory(character.id, *tool_item_id, 1))
|
||||
.act(actions::feed_mag_item(character.clone(), *mag_item_id))
|
||||
@ -321,11 +324,11 @@ pub async fn buy_shop_item<'a, EG> (
|
||||
amount: u32,
|
||||
) -> Result<InventoryItem, ItemStateError>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
EG: EntityGateway + 'static,
|
||||
{
|
||||
let item_price = shop_item.price() as u32 * amount;
|
||||
entity_gateway.with_transaction(|transaction| async move {
|
||||
let item_state_proxy = ItemStateProxy::new(item_state);
|
||||
let item_state_proxy = ItemStateProxy::new(item_state.clone());
|
||||
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
|
||||
.act(actions::take_meseta_from_inventory(character.id, item_price))
|
||||
//.act(bought_item_to_inventory_item)
|
||||
@ -347,10 +350,10 @@ pub async fn sell_item<'a, EG> (
|
||||
amount: u32,
|
||||
) -> Result<InventoryItem, ItemStateError>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
EG: EntityGateway + 'static,
|
||||
{
|
||||
entity_gateway.with_transaction(|transaction| async move {
|
||||
let item_state_proxy = ItemStateProxy::new(item_state);
|
||||
let item_state_proxy = ItemStateProxy::new(item_state.clone());
|
||||
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
|
||||
.act(actions::take_item_from_inventory(character.id, item_id, amount))
|
||||
.act(actions::sell_inventory_item(character.id))
|
||||
@ -367,7 +370,7 @@ pub async fn trade_items<'a, EG> (
|
||||
p2: (&AreaClient, &CharacterEntity, &Vec<TradeItem>, Meseta))
|
||||
-> Result<(Vec<InventoryItem>, Vec<InventoryItem>), ItemStateError>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
EG: EntityGateway + 'static,
|
||||
{
|
||||
let p1_trade_items = p1.2
|
||||
.iter()
|
||||
@ -391,7 +394,7 @@ where
|
||||
let p1_id = p1.1.id;
|
||||
let p2_id = p2.1.id;
|
||||
let trade = transaction.gateway().create_trade(&p1_id, &p2_id).await?;
|
||||
let item_state_proxy = ItemStateProxy::new(item_state);
|
||||
let item_state_proxy = ItemStateProxy::new(item_state.clone());
|
||||
let ((item_state_proxy, transaction), p1_removed_items) = ItemStateAction::default()
|
||||
.act(actions::iterate(p1_trade_items, move |p1_trade_item| actions::take_item_from_inventory(p1_id, p1_trade_item.0, p1_trade_item.1) ))
|
||||
.act(actions::foreach(actions::assign_new_item_id()))
|
||||
@ -437,10 +440,10 @@ pub async fn take_meseta<'a, EG> (
|
||||
meseta: Meseta)
|
||||
-> Result<(), ItemStateError>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
EG: EntityGateway + 'static,
|
||||
{
|
||||
entity_gateway.with_transaction(|transaction| async move {
|
||||
let item_state_proxy = ItemStateProxy::new(item_state);
|
||||
let item_state_proxy = ItemStateProxy::new(item_state.clone());
|
||||
let ((item_state_proxy, transaction), _) = ItemStateAction::default()
|
||||
.act(actions::take_meseta_from_inventory(*character_id, meseta.0))
|
||||
.commit((item_state_proxy, transaction))
|
||||
@ -458,10 +461,10 @@ pub async fn enemy_drops_item<'a, EG> (
|
||||
item_drop: ItemDrop)
|
||||
-> Result<FloorItem, ItemStateError>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
EG: EntityGateway + 'static,
|
||||
{
|
||||
entity_gateway.with_transaction(|transaction| async move {
|
||||
let item_state_proxy = ItemStateProxy::new(item_state);
|
||||
let item_state_proxy = ItemStateProxy::new(item_state.clone());
|
||||
let ((item_state_proxy, transaction), floor_item) = ItemStateAction::default()
|
||||
.act(actions::convert_item_drop_to_floor_item(character_id, item_drop))
|
||||
.act(actions::add_item_to_local_floor(character_id))
|
||||
@ -482,10 +485,10 @@ pub async fn apply_modifier<'a, EG> (
|
||||
modifier: ItemModifier)
|
||||
-> Result<IndividualItemDetail, ItemStateError>
|
||||
where
|
||||
EG: EntityGateway,
|
||||
EG: EntityGateway + 'static,
|
||||
{
|
||||
entity_gateway.with_transaction(|transaction| async move {
|
||||
let item_state_proxy = ItemStateProxy::new(item_state);
|
||||
let item_state_proxy = ItemStateProxy::new(item_state.clone());
|
||||
let ((item_state_proxy, transaction), item) = ItemStateAction::default()
|
||||
.act(actions::take_item_from_inventory(character.id, item_id, 1))
|
||||
.act(actions::apply_modifier_to_inventory_item(modifier))
|
||||
|
@ -84,7 +84,7 @@ pub async fn request_item<EG>(id: ClientId,
|
||||
item_state: &mut ItemState)
|
||||
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
|
||||
where
|
||||
EG: EntityGateway
|
||||
EG: EntityGateway + 'static,
|
||||
{
|
||||
let room_id = client_location.get_room(id).await?;
|
||||
let monster = rooms.with(room_id, |room| Box::pin(async move {
|
||||
|
Loading…
x
Reference in New Issue
Block a user