Browse Source

anyhow

pull/127/head
jake 2 years ago
parent
commit
a2686e2be8
  1. 4
      Cargo.lock
  2. 2
      Cargo.toml
  3. 10
      src/common/mainloop/client.rs
  4. 5
      src/entity/gateway/entitygateway.rs
  5. 5
      src/entity/gateway/inmemory.rs
  6. 13
      src/entity/gateway/postgres/postgres.rs
  7. 2
      src/lib.rs
  8. 6
      src/ship/client.rs
  9. 87
      src/ship/items/actions.rs
  10. 33
      src/ship/items/apply_item.rs
  11. 30
      src/ship/items/state.rs
  12. 40
      src/ship/items/tasks.rs
  13. 26
      src/ship/location.rs
  14. 11
      src/ship/packet/builder/lobby.rs
  15. 7
      src/ship/packet/builder/room.rs
  16. 2
      src/ship/packet/handler/auth.rs
  17. 10
      src/ship/packet/handler/communication.rs
  18. 50
      src/ship/packet/handler/direct_message.rs
  19. 12
      src/ship/packet/handler/lobby.rs
  20. 34
      src/ship/packet/handler/message.rs
  21. 36
      src/ship/packet/handler/quest.rs
  22. 14
      src/ship/packet/handler/room.rs
  23. 8
      src/ship/packet/handler/settings.rs
  24. 26
      src/ship/packet/handler/trade.rs
  25. 10
      src/ship/room.rs
  26. 8
      src/ship/ship.rs

4
Cargo.lock

@ -48,9 +48,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.57"
version = "1.0.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61"
dependencies = [
"backtrace",
]

2
Cargo.toml

@ -32,4 +32,4 @@ refinery = { version = "0.5.0", features = ["postgres"] }
sqlx = { version = "0.5.10", features = ["runtime-async-std-native-tls", "postgres", "json", "chrono"] }
strum = "0.19.5"
strum_macros = "0.19"
anyhow = { version = "1.0.47", features = ["backtrace"] }
anyhow = { version = "1.0.68", features = ["backtrace"] }

10
src/common/mainloop/client.rs

@ -4,7 +4,7 @@ use async_std::channel;
use async_std::io::prelude::{ReadExt, WriteExt};
use async_std::sync::{Arc, RwLock};
use futures::future::Future;
use log::{trace, info, warn};
use log::{trace, info, warn, error};
use libpso::crypto::{PSOCipher, NullCipher, CipherError};
use libpso::PacketParseError;
@ -132,7 +132,7 @@ where
match pkt_receiver.recv_pkts::<R>().await {
Ok(pkts) => {
for pkt in pkts {
info!("[recv from {:?}] {:#?}", client_id, pkt);
trace!("[recv from {:?}] {:#?}", client_id, pkt);
match state.handle(client_id, pkt).await {
Ok(response) => {
for resp in response {
@ -147,7 +147,7 @@ where
}
},
Err(err) => {
warn!("[client recv {:?}] error {:?} ", client_id, err);
error!("[client recv {:?}] error {:?} ", client_id, err);
}
}
}
@ -173,7 +173,7 @@ where
break;
}
_ => {
warn!("[client {:?} recv error] {:?}", client_id, err);
error!("[client {:?} recv error] {:?}", client_id, err);
}
}
}
@ -206,7 +206,7 @@ where
Ok(pkt) => {
info!("[send to {:?}] {:#?}", client_id, pkt);
if let Err(err) = send_pkt(&mut socket, &mut cipher, &pkt).await {
warn!("error sending pkt {:#?} to {:?} {:?}", pkt, client_id, err);
error!("error sending pkt {:#?} to {:?} {:?}", pkt, client_id, err);
}
},
Err(err) => {

5
src/entity/gateway/entitygateway.rs

@ -22,12 +22,11 @@ pub enum GatewayError {
pub trait EntityGateway: Send + Sync {
type Transaction: EntityGatewayTransaction + Clone;
async fn with_transaction<'a, F, Fut, R, E>(&'a mut self, _func: F) -> Result<R, E>
async fn with_transaction<'a, F, Fut, R>(&'a mut self, _func: F) -> Result<R, anyhow::Error>
where
Fut: Future<Output = Result<(Self::Transaction, R), E>> + Send + 'a,
Fut: Future<Output = Result<(Self::Transaction, R), anyhow::Error>> + Send + 'a,
F: FnOnce(Self::Transaction) -> Fut + Send,
R: Send,
E: From<GatewayError>,
Self: Sized
{
unimplemented!();

5
src/entity/gateway/inmemory.rs

@ -304,12 +304,11 @@ fn apply_modifiers(items: &BTreeMap<ItemEntityId, ItemEntity>,
impl EntityGateway for InMemoryGateway {
type Transaction = InMemoryGatewayTransaction;
async fn with_transaction<'a, F, Fut, R, E>(&'a mut self, func: F) -> Result<R, E>
async fn with_transaction<'a, F, Fut, R>(&'a mut self, func: F) -> Result<R, anyhow::Error>
where
Fut: Future<Output = Result<(Self::Transaction, R), E>> + Send + 'a,
Fut: Future<Output = Result<(Self::Transaction, R), anyhow::Error>> + Send + 'a,
F: FnOnce(Self::Transaction) -> Fut + Send,
R: Send,
E: From<GatewayError>,
{
let users = self.users.lock().await.clone();
let user_settings = self.user_settings.lock().await.clone();

13
src/entity/gateway/postgres/postgres.rs

@ -298,7 +298,7 @@ async fn save_character(conn: &mut sqlx::PgConnection, char: &CharacterEntity) -
let q = r#"update player_character set
user_account=$1, slot=$2, name=$3, exp=$4, class=$5, section_id=$6, costume=$7, skin=$8, face=$9, head=$10, hair=$11, hair_r=$12,
hair_g=$13, hair_b=$14, prop_x=$15, prop_y=$16, techs=$17, config=$18, infoboard=$19, guildcard=$20, power=$21, mind=$22, def=$23,
evade=$24, luck=$25, hp=$26, tp=$27, tech_menu=$28, option_flags=$29, keyboard_config=$30, gamepad_config=$31, playtime=$32,
evade=$24, luck=$25, hp=$26, tp=$27, tech_menu=$28, option_flags=$29, keyboard_config=$30, gamepad_config=$31, playtime=$32
where id=$33;"#;
sqlx::query(q)
.bind(char.user_id.0) // $1
@ -612,18 +612,17 @@ async fn set_character_playtime(conn: &mut sqlx::PgConnection, char_id: &Charact
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>
async fn with_transaction<'a, F, Fut, R>(&'a mut self, func: F) -> Result<R, anyhow::Error>
where
Fut: Future<Output = Result<(Self::Transaction, R), E>> + Send + 'a,
Fut: Future<Output = Result<(Self::Transaction, R), anyhow::Error>> + Send + 'a,
F: FnOnce(Self::Transaction) -> Fut + Send,
R: Send,
E: From<GatewayError>,
{
let transaction = PostgresTransaction {
pgtransaction: Arc::new(Mutex::new(self.pool.begin().await.map_err(|_| ()).unwrap()))
pgtransaction: Arc::new(Mutex::new(self.pool.begin().await?))
};
let (transaction, result) = func(transaction).await.map_err(|_| ()).unwrap();
transaction.commit().await.map_err(|_| ()).unwrap();
let (transaction, result) = func(transaction).await?;
transaction.commit().await?;
Ok(result)
}

2
src/lib.rs

@ -4,6 +4,8 @@
#![feature(try_blocks)]
#![feature(once_cell)]
#![feature(test)]
#![feature(error_generic_member_access)]
#![feature(provide_any)]
extern crate test;

6
src/ship/client.rs

@ -36,7 +36,7 @@ impl Clients {
.into_inner())
}
pub async fn with<'a, T, F>(&'a self, client_id: ClientId, func: F) -> Result<T, ShipError>
pub async fn with<'a, T, F>(&'a self, client_id: ClientId, func: F) -> Result<T, anyhow::Error>
where
T: Send,
F: for<'b> FnOnce(&'b ClientState) -> BoxFuture<'b, T> + Send + 'a,
@ -53,7 +53,7 @@ impl Clients {
Ok(func(&client).await)
}
pub async fn with_many<'a, T, F, const N: usize>(&'a self, client_ids: [ClientId; N], func: F) -> Result<T, ShipError>
pub async fn with_many<'a, T, F, const N: usize>(&'a self, client_ids: [ClientId; N], func: F) -> Result<T, anyhow::Error>
where
T: Send,
F: for<'b> FnOnce([RwLockReadGuard<'b, ClientState>; N]) -> BoxFuture<'b, T> + Send + 'a,
@ -85,7 +85,7 @@ impl Clients {
Ok(func(client_states).await)
}
pub async fn with_mut<'a, T, F>(&'a self, client_id: ClientId, func: F) -> Result<T, ShipError>
pub async fn with_mut<'a, T, F>(&'a self, client_id: ClientId, func: F) -> Result<T, anyhow::Error>
where
T: Send,
F: for<'b> FnOnce(&'b mut ClientState) -> BoxFuture<'b, T> + Send + 'a,

87
src/ship/items/actions.rs

@ -6,6 +6,8 @@ use std::future::Future;
use std::pin::Pin;
use std::iter::IntoIterator;
use log::warn;
use libpso::packet::{ship::Message, messages::GameMessage};
use crate::ship::map::MapArea;
use crate::ship::ship::SendShipPacket;
@ -35,7 +37,7 @@ pub(super) fn take_item_from_floor<EG, TR>(
character_id: CharacterEntityId,
item_id: ClientItemId
) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), FloorItem), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>>
where
EG: EntityGateway + Send,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -54,7 +56,7 @@ where
pub(super) fn add_floor_item_to_inventory<EG, TR>(
character: &CharacterEntity
) -> impl Fn((ItemStateProxy, TR), FloorItem)
-> BoxFuture<Result<((ItemStateProxy, TR), TriggerCreateItem), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), TriggerCreateItem), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + Clone + 'static,
@ -103,7 +105,7 @@ pub(super) fn take_item_from_inventory<EG, TR>(
item_id: ClientItemId,
amount: u32,
) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), InventoryItem), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -127,7 +129,7 @@ pub(super) fn add_inventory_item_to_shared_floor<EG, TR>(
map_area: MapArea,
drop_position: (f32, f32, f32),
) -> impl Fn((ItemStateProxy, TR), InventoryItem)
-> BoxFuture<Result<((ItemStateProxy, TR), FloorItem), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -160,7 +162,7 @@ pub(super) fn take_meseta_from_inventory<EG, TR>(
character_id: CharacterEntityId,
amount: u32,
) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), ()), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), ()), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -181,7 +183,7 @@ pub(super) fn add_meseta_to_inventory<EG, TR>(
character_id: CharacterEntityId,
amount: u32
) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), ()), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), ()), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -204,7 +206,7 @@ pub(super) fn add_meseta_to_shared_floor<EG, TR>(
map_area: MapArea,
drop_position: (f32, f32)
) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), FloorItem), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -233,7 +235,7 @@ pub(super) fn take_meseta_from_bank<EG, TR>(
character_id: CharacterEntityId,
amount: u32,
) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), ()), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), ()), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -253,7 +255,7 @@ pub(super) fn add_meseta_from_bank_to_inventory<EG, TR>(
character_id: CharacterEntityId,
amount: u32,
) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), ()), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), ()), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -274,7 +276,7 @@ pub(super) fn add_meseta_to_bank<EG, TR>(
character_id: CharacterEntityId,
amount: u32,
) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), ()), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), ()), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -296,7 +298,7 @@ pub(super) fn take_item_from_bank<EG, TR>(
item_id: ClientItemId,
amount: u32,
) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), BankItem), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), BankItem), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -316,7 +318,7 @@ where
pub(super) fn add_bank_item_to_inventory<EG, TR>(
character: &CharacterEntity,
) -> impl Fn((ItemStateProxy, TR), BankItem)
-> BoxFuture<Result<((ItemStateProxy, TR), InventoryItem), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -367,7 +369,7 @@ where
pub(super) fn add_inventory_item_to_bank<EG, TR>(
character_id: CharacterEntityId,
) -> impl Fn((ItemStateProxy, TR), InventoryItem)
-> BoxFuture<Result<((ItemStateProxy, TR), ()), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), ()), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -403,7 +405,7 @@ pub(super) fn equip_inventory_item<EG, TR>(
item_id: ClientItemId,
equip_slot: u8,
) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), ()), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), ()), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -425,7 +427,7 @@ pub(super) fn unequip_inventory_item<EG, TR>(
character_id: CharacterEntityId,
item_id: ClientItemId,
) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), ()), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), ()), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -448,7 +450,7 @@ pub(super) fn sort_inventory_items<EG, TR>(
character_id: CharacterEntityId,
item_ids: Vec<ClientItemId>,
) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), ()), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), ()), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -470,7 +472,7 @@ where
pub(super) fn use_consumed_item<EG, TR>(
character: &CharacterEntity,
) -> impl Fn((ItemStateProxy, TR), InventoryItem)
-> BoxFuture<Result<((ItemStateProxy, TR), Vec<ApplyItemAction>), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), Vec<ApplyItemAction>), anyhow::Error>>
where
EG: EntityGateway + Clone + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -497,7 +499,7 @@ pub(super) fn feed_mag_item<EG, TR>(
character: CharacterEntity,
mag_item_id: ClientItemId,
) -> impl Fn((ItemStateProxy, TR), InventoryItem)
-> BoxFuture<Result<((ItemStateProxy, TR), CharacterEntity), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), CharacterEntity), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -551,7 +553,7 @@ pub(super) fn add_bought_item_to_inventory<'a, EG, TR>(
item_id: ClientItemId,
amount: u32,
) -> impl Fn((ItemStateProxy, TR), ())
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), InventoryItem), ItemStateError>> + Send + 'a>>
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>> + Send + 'a>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -613,7 +615,7 @@ where
pub(super) fn sell_inventory_item<EG, TR>(
character_id: CharacterEntityId,
) -> impl Fn((ItemStateProxy, TR), InventoryItem)
-> BoxFuture<Result<((ItemStateProxy, TR), InventoryItem), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -643,7 +645,7 @@ async fn iterate_inner<'a, EG, TR, I, O, T, F, FR>(
mut input: Vec<I>,
func: F,
arg: T,
) -> Result<((ItemStateProxy, TR), Vec<O>), ItemStateError>
) -> Result<((ItemStateProxy, TR), Vec<O>), anyhow::Error>
where
'a: 'async_recursion,
EG: EntityGateway,
@ -653,7 +655,7 @@ where
T: Clone + Send + Sync,
F: Fn(I) -> FR + Send + Sync + Clone + 'static,
FR: Fn((ItemStateProxy, TR), T)
-> BoxFuture<Result<((ItemStateProxy, TR), O), ItemStateError>> + Send + Sync,
-> BoxFuture<Result<((ItemStateProxy, TR), O), anyhow::Error>> + Send + Sync,
{
let item = match input.pop() {
Some(item) => item,
@ -673,7 +675,7 @@ pub(super) fn iterate<EG, TR, I, O, T, F, FR>(
input: Vec<I>,
func: F,
) -> impl Fn((ItemStateProxy, TR), T)
-> BoxFuture<Result<((ItemStateProxy, TR), Vec<O>), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), Vec<O>), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -682,7 +684,7 @@ where
T: Send + Clone + 'static + std::fmt::Debug,
F: Fn(I) -> FR + Send + Sync + Clone + 'static,
FR: Fn((ItemStateProxy, TR), T)
-> BoxFuture<Result<((ItemStateProxy, TR), O), ItemStateError>> + Send + Sync,
-> BoxFuture<Result<((ItemStateProxy, TR), O), anyhow::Error>> + Send + Sync,
T: Clone + Send + Sync,
{
move |(item_state, transaction), arg| {
@ -701,7 +703,7 @@ async fn foreach_inner<'a, EG, TR, O, T, F, I>(
state: (ItemStateProxy, TR),
mut input: I,
func: Arc<F>,
) -> Result<((ItemStateProxy, TR), Vec<O>), ItemStateError>
) -> Result<((ItemStateProxy, TR), Vec<O>), anyhow::Error>
where
'a: 'async_recursion,
EG: EntityGateway,
@ -709,7 +711,7 @@ where
O: Send,
T: Send,
F: Fn((ItemStateProxy, TR), T)
-> BoxFuture<Result<((ItemStateProxy, TR), O), ItemStateError>> + Send + Sync,
-> BoxFuture<Result<((ItemStateProxy, TR), O), anyhow::Error>> + Send + Sync,
I: Iterator<Item = T> + Send + Sync + 'static,
{
let item = match input.next() {
@ -728,14 +730,14 @@ where
pub(super) fn foreach<EG, TR, O, T, F, I>(
func: F
) -> impl Fn((ItemStateProxy, TR), I)
-> BoxFuture<Result<((ItemStateProxy, TR), Vec<O>), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), Vec<O>), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
O: Send,
T: Send + Clone + 'static + std::fmt::Debug,
F: Fn((ItemStateProxy, TR), T)
-> BoxFuture<Result<((ItemStateProxy, TR), O), ItemStateError>> + Send + Sync + 'static,
-> BoxFuture<Result<((ItemStateProxy, TR), O), anyhow::Error>> + Send + Sync + 'static,
T: Send + Sync,
I: IntoIterator<Item = T> + Send + Sync + 'static,
I::IntoIter: Send + Sync,
@ -754,7 +756,7 @@ where
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>>
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), T), anyhow::Error>> + Send + 'a>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -772,12 +774,12 @@ pub(super) fn fork<EG, TR, F1, F2, T, O1, O2>(
func1: F1,
func2: F2,
) -> impl Fn((ItemStateProxy, TR), T)
-> BoxFuture<Result<((ItemStateProxy, TR), (O1, O2)), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), (O1, O2)), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
F1: Fn((ItemStateProxy, TR), T) -> BoxFuture<Result<((ItemStateProxy, TR), O1), ItemStateError>> + Send + Sync + 'static,
F2: Fn((ItemStateProxy, TR), T) -> BoxFuture<Result<((ItemStateProxy, TR), O2), ItemStateError>> + Send + Sync + 'static,
F1: Fn((ItemStateProxy, TR), T) -> BoxFuture<Result<((ItemStateProxy, TR), O1), anyhow::Error>> + Send + Sync + 'static,
F2: Fn((ItemStateProxy, TR), T) -> BoxFuture<Result<((ItemStateProxy, TR), O2), anyhow::Error>> + Send + Sync + 'static,
T: Send + Sync + Clone + 'static,
O1: Send,
O2: Send,
@ -799,7 +801,7 @@ where
pub(super) fn add_item_to_inventory<EG, TR>(
character: CharacterEntity,
) -> impl Fn((ItemStateProxy, TR), InventoryItem)
-> BoxFuture<Result<((ItemStateProxy, TR), InventoryItem), ItemStateError>> + Clone
-> BoxFuture<Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>> + Clone
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -829,7 +831,7 @@ pub(super) fn record_trade<EG, TR>(
character_to: CharacterEntityId,
character_from: CharacterEntityId,
) -> impl Fn((ItemStateProxy, TR), Vec<InventoryItem>)
-> BoxFuture<Result<((ItemStateProxy, TR), Vec<InventoryItem>), ItemStateError>> + Clone
-> BoxFuture<Result<((ItemStateProxy, TR), Vec<InventoryItem>), anyhow::Error>> + Clone
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -855,7 +857,7 @@ where
pub(super) fn assign_new_item_id<EG, TR>(
) -> impl Fn((ItemStateProxy, TR), InventoryItem)
-> BoxFuture<Result<((ItemStateProxy, TR), InventoryItem), ItemStateError>> + Clone
-> BoxFuture<Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>> + Clone
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -873,7 +875,7 @@ pub(super) fn convert_item_drop_to_floor_item<EG, TR>(
character_id: CharacterEntityId,
item_drop: ItemDrop,
) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), FloorItem), ItemStateError>> + Clone
-> BoxFuture<Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>> + Clone
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -881,6 +883,7 @@ where
move |(mut item_state, mut transaction), _| {
let item_drop = item_drop.clone();
Box::pin(async move {
warn!("converting item drop to floor item");
enum ItemOrMeseta {
Individual(ItemDetail),
Stacked(Tool),
@ -993,7 +996,7 @@ where
pub(super) fn apply_modifier_to_inventory_item<EG, TR>(
modifier: ItemModifier,
) -> impl Fn((ItemStateProxy, TR), InventoryItem)
-> BoxFuture<Result<((ItemStateProxy, TR), InventoryItem), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -1006,7 +1009,7 @@ where
weapon.apply_modifier(&modifier);
transaction.gateway().add_weapon_modifier(entity_id, modifier).await?;
},
_ => return Err(ItemStateError::InvalidModifier)
_ => return Err(ItemStateError::InvalidModifier.into())
}
Ok(((item_state, transaction), inventory_item))
@ -1016,7 +1019,7 @@ where
pub(super) fn as_individual_item<EG, TR>(
) -> impl Fn((ItemStateProxy, TR), InventoryItem)
-> BoxFuture<Result<((ItemStateProxy, TR), IndividualItemDetail), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), IndividualItemDetail), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -1025,7 +1028,7 @@ where
Box::pin(async move {
let item = match inventory_item.item {
InventoryItemDetail::Individual(individual_item) => individual_item,
_ => return Err(ItemStateError::WrongItemType(inventory_item.item_id))
_ => return Err(ItemStateError::WrongItemType(inventory_item.item_id).into())
};
Ok(((item_state, transaction), item))
@ -1038,7 +1041,7 @@ pub(super) fn apply_item_action_packets<EG, TR>(
character_id: CharacterEntityId,
area_client: AreaClient,
) -> impl Fn((ItemStateProxy, TR), ApplyItemAction)
-> BoxFuture<Result<((ItemStateProxy, TR), Vec<SendShipPacket>), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), Vec<SendShipPacket>), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
@ -1095,7 +1098,7 @@ where
pub(super) fn apply_item_action_character<EG, TR>(
character: &CharacterEntity
) -> impl Fn((ItemStateProxy, TR), Vec<ApplyItemAction>)
-> BoxFuture<Result<((ItemStateProxy, TR), CharacterEntity), ItemStateError>>
-> BoxFuture<Result<((ItemStateProxy, TR), CharacterEntity), anyhow::Error>>
where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,

33
src/ship/items/apply_item.rs

@ -23,8 +23,8 @@ pub enum ApplyItemError {
#[error("gateway error {0}")]
GatewayError(#[from] GatewayError),
#[error("itemstate error {0}")]
ItemStateError(Box<ItemStateError>),
//#[error("itemstate error {0}")]
//ItemStateError(Box<ItemStateError>),
#[error("magcell error {0}")]
MagCellError(#[from] MagCellError),
@ -38,49 +38,52 @@ pub enum ApplyItemAction {
//RemoveItem,
}
/*
impl From<ItemStateError> for ApplyItemError {
fn from(other: ItemStateError) -> ApplyItemError {
ApplyItemError::ItemStateError(Box::new(other))
}
}
*/
async fn power_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, ApplyItemError> {
async fn power_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, anyhow::Error> {
character.materials.power += 1;
entity_gateway.save_character(character).await?;
Ok(vec![ApplyItemAction::UpdateCharacter(Box::new(character.clone()))])
}
async fn mind_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, ApplyItemError> {
async fn mind_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, anyhow::Error> {
character.materials.mind += 1;
entity_gateway.save_character(character).await.unwrap();
Ok(vec![ApplyItemAction::UpdateCharacter(Box::new(character.clone()))])
}
async fn evade_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, ApplyItemError> {
async fn evade_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, anyhow::Error> {
character.materials.evade += 1;
entity_gateway.save_character(character).await.unwrap();
Ok(vec![ApplyItemAction::UpdateCharacter(Box::new(character.clone()))])
}
async fn def_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, ApplyItemError> {
async fn def_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, anyhow::Error> {
character.materials.def += 1;
entity_gateway.save_character(character).await.unwrap();
Ok(vec![ApplyItemAction::UpdateCharacter(Box::new(character.clone()))])
}
async fn luck_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, ApplyItemError> {
async fn luck_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, anyhow::Error> {
character.materials.luck += 1;
entity_gateway.save_character(character).await.unwrap();
Ok(vec![ApplyItemAction::UpdateCharacter(Box::new(character.clone()))])
}
async fn hp_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, ApplyItemError> {
async fn hp_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, anyhow::Error> {
character.materials.hp += 1;
entity_gateway.save_character(character).await.unwrap();
Ok(vec![ApplyItemAction::UpdateCharacter(Box::new(character.clone()))])
}
async fn tp_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, ApplyItemError> {
async fn tp_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<Vec<ApplyItemAction>, anyhow::Error> {
character.materials.tp += 1;
entity_gateway.save_character(character).await.unwrap();
Ok(vec![ApplyItemAction::UpdateCharacter(Box::new(character.clone()))])
@ -113,7 +116,7 @@ async fn mag_cell<'a, EG>(item_state: &mut ItemStateProxy,
character: &CharacterEntity,
cell_entity_id: ItemEntityId,
mag_cell_type: MagCell)
-> Result<Vec<ApplyItemAction>, ApplyItemError>
-> Result<Vec<ApplyItemAction>, anyhow::Error>
where
EG: EntityGateway + ?Sized,
{
@ -229,7 +232,7 @@ pub async fn liberta_kit<EG: EntityGateway>(entity_gateway: &mut EG, used_cell:
*/
fn jack_o_lantern() -> Result<Vec<ApplyItemAction>, ApplyItemError>
fn jack_o_lantern() -> Result<Vec<ApplyItemAction>, anyhow::Error>
{
let mag_rate = WeightedIndex::new(&[13, 13, 13, 13, 12, 12, 12, 12]).unwrap();
let mag_type = match mag_rate.sample(&mut rand_chacha::ChaChaRng::from_entropy()) {
@ -252,7 +255,7 @@ async fn apply_tool<'a, EG>(item_state: &mut ItemStateProxy,
character: &mut CharacterEntity,
entity_id: ItemEntityId,
tool: ToolType)
-> Result<Vec<ApplyItemAction>, ApplyItemError>
-> Result<Vec<ApplyItemAction>, anyhow::Error>
where
EG: EntityGateway + ?Sized,
{
@ -299,7 +302,7 @@ where
}
ToolType::JackOLantern => jack_o_lantern(),
// TODO: rest of these
_ => Err(ApplyItemError::InvalidItem)
_ => Err(ApplyItemError::InvalidItem.into())
}
}
@ -309,7 +312,7 @@ pub async fn apply_item<'a, EG>(item_state: &mut ItemStateProxy,
entity_gateway: &mut EG,
character: &mut CharacterEntity,
item: InventoryItem
) -> Result<Vec<ApplyItemAction>, ApplyItemError>
) -> Result<Vec<ApplyItemAction>, anyhow::Error>
where
EG: EntityGateway + ?Sized + Clone + 'static
{
@ -317,7 +320,7 @@ where
InventoryItemDetail::Individual(individual_item) => {
match individual_item.item {
ItemDetail::Tool(tool) => apply_tool(item_state, entity_gateway, character, individual_item.entity_id, tool.tool).await,
_ => Err(ApplyItemError::InvalidItem)
_ => Err(ApplyItemError::InvalidItem.into())
}
},
InventoryItemDetail::Stacked(stacked_item) => {

30
src/ship/items/state.rs

@ -1,6 +1,7 @@
use std::collections::HashMap;
use async_std::sync::{Arc, RwLock, Mutex};
use futures::future::join_all;
use anyhow::Context;
use crate::entity::gateway::{EntityGateway, GatewayError};
use crate::entity::character::{CharacterEntity, CharacterEntityId};
@ -55,7 +56,7 @@ pub enum ItemStateError {
ItemNotSellable,
#[error("could not modify item")]
InvalidModifier,
#[error("wrong item type ")]
#[error("wrong item type {0}")]
WrongItemType(ClientItemId),
}
@ -150,7 +151,7 @@ impl Default for ItemState {
}
impl ItemState {
pub async fn get_character_inventory(&self, character: &CharacterEntity) -> Result<InventoryState, ItemStateError> {
pub async fn get_character_inventory(&self, character: &CharacterEntity) -> Result<InventoryState, anyhow::Error> {
Ok(self.character_inventory
.read()
.await
@ -161,7 +162,7 @@ impl ItemState {
.clone())
}
pub async fn get_character_bank(&self, character: &CharacterEntity) -> Result<BankState, ItemStateError> {
pub async fn get_character_bank(&self, character: &CharacterEntity) -> Result<BankState, anyhow::Error> {
Ok(self.character_bank
.read()
.await
@ -174,20 +175,20 @@ impl ItemState {
}
impl ItemState {
async fn new_item_id(&mut self) -> Result<ClientItemId, ItemStateError> {
async fn new_item_id(&mut self) -> Result<ClientItemId, anyhow::Error> {
*self.room_item_id_counter
.write()
.await += 1;
Ok(ClientItemId(*self.room_item_id_counter.read().await))
}
pub async fn load_character<EG: EntityGateway>(&mut self, entity_gateway: &mut EG, character: &CharacterEntity) -> Result<(), ItemStateError> {
pub async fn load_character<EG: EntityGateway>(&mut self, entity_gateway: &mut EG, character: &CharacterEntity) -> Result<(), anyhow::Error> {
let inventory = entity_gateway.get_character_inventory(&character.id).await?;
let bank = entity_gateway.get_character_bank(&character.id, &BankName("".into())).await?;
let equipped = entity_gateway.get_character_equips(&character.id).await?;
let inventory_items = inventory.items.into_iter()
.map(|item| -> Result<InventoryItem, ItemStateError> {
.map(|item| -> Result<InventoryItem, anyhow::Error> {
Ok(match item {
InventoryItemEntity::Individual(item) => {
InventoryItem {
@ -214,7 +215,7 @@ impl ItemState {
},
})
})
.collect::<Result<Vec<_>, ItemStateError>>()?;
.collect::<Result<Vec<_>, anyhow::Error>>()?;
let character_meseta = entity_gateway.get_character_meseta(&character.id).await?;
let inventory_state = InventoryState {
@ -259,7 +260,7 @@ impl ItemState {
.collect::<Vec<_>>())
.await
.into_iter()
.collect::<Result<Vec<_>, ItemStateError>>()?;
.collect::<Result<Vec<_>, anyhow::Error>>()?;
let bank_meseta = entity_gateway.get_bank_meseta(&character.id, &BankName("".into())).await?;
let bank_state = BankState::new(character.id, BankName("".into()), Bank::new(bank_items), bank_meseta);
@ -334,7 +335,7 @@ impl ItemState {
}
}
pub async fn get_floor_item(&self, character_id: &CharacterEntityId, item_id: &ClientItemId) -> Result<(FloorItem, FloorType), ItemStateError> {
pub async fn get_floor_item(&self, character_id: &CharacterEntityId, item_id: &ClientItemId) -> Result<(FloorItem, FloorType), anyhow::Error> {
let local_floors = self.character_floor
.read()
.await;
@ -369,6 +370,7 @@ impl ItemState {
.map(|item| (item.clone(), FloorType::Shared))
})
.ok_or_else(|| ItemStateError::NoFloorItem(*item_id))
.with_context(|| format!("character {}\nlocal floors: {:#?}\nshared floors: {:#?}", character_id, local_floors, shared_floors))
}
}
@ -421,7 +423,7 @@ impl ItemStateProxy {
async fn get_or_clone<K, V>(master: &Arc<RwLock<HashMap<K, RwLock<V>>>>,
proxy: &Arc<Mutex<HashMap<K, V>>>,
key: K,
err: fn(K) -> ItemStateError) -> Result<V, ItemStateError>
err: fn(K) -> ItemStateError) -> Result<V, anyhow::Error>
where
K: Eq + std::hash::Hash + Copy,
V: Clone
@ -451,7 +453,7 @@ impl ItemStateProxy {
}
}
pub async fn inventory(&mut self, character_id: &CharacterEntityId) -> Result<InventoryState, ItemStateError> {
pub async fn inventory(&mut self, character_id: &CharacterEntityId) -> Result<InventoryState, anyhow::Error> {
get_or_clone(&self.item_state.character_inventory,
&self.proxied_state.character_inventory,
*character_id,
@ -462,7 +464,7 @@ impl ItemStateProxy {
self.proxied_state.character_inventory.lock().await.insert(inventory.character_id, inventory);
}
pub async fn bank(&mut self, character_id: &CharacterEntityId) -> Result<BankState, ItemStateError> {
pub async fn bank(&mut self, character_id: &CharacterEntityId) -> Result<BankState, anyhow::Error> {
get_or_clone(&self.item_state.character_bank,
&self.proxied_state.character_bank,
*character_id,
@ -473,7 +475,7 @@ impl ItemStateProxy {
self.proxied_state.character_bank.lock().await.insert(bank.character_id, bank);
}
pub async fn floor(&mut self, character_id: &CharacterEntityId) -> Result<FloorState, ItemStateError> {
pub async fn floor(&mut self, character_id: &CharacterEntityId) -> Result<FloorState, anyhow::Error> {
let room_id = *self.item_state.character_room.read().await.get(character_id).unwrap();
Ok(FloorState {
character_id: *character_id,
@ -488,7 +490,7 @@ impl ItemStateProxy {
self.proxied_state.room_floor.lock().await.insert(room_id, floor.shared);
}
pub async fn new_item_id(&mut self) -> Result<ClientItemId, ItemStateError> {
pub async fn new_item_id(&mut self) -> Result<ClientItemId, anyhow::Error> {
self.item_state.new_item_id().await
}
}

40
src/ship/items/tasks.rs

@ -5,7 +5,7 @@ use crate::ship::ship::SendShipPacket;
use crate::ship::map::MapArea;
use crate::entity::character::{CharacterEntity, CharacterEntityId};
use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction};
use crate::ship::items::state::{ItemState, ItemStateProxy, ItemStateError, IndividualItemDetail};
use crate::ship::items::state::{ItemState, ItemStateProxy, IndividualItemDetail};
use crate::ship::items::itemstateaction::{ItemStateAction, ItemAction};
use crate::ship::items::inventory::InventoryItem;
use crate::ship::items::floor::FloorItem;
@ -17,12 +17,14 @@ use crate::ship::drops::ItemDrop;
use crate::ship::items::actions;
use log::warn;
pub async fn pick_up_item<EG>(
item_state: &mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: &ClientItemId)
-> Result<actions::TriggerCreateItem, ItemStateError>
-> Result<actions::TriggerCreateItem, anyhow::Error>
where
EG: EntityGateway + 'static,
EG::Transaction: Clone,
@ -46,7 +48,7 @@ pub async fn drop_item<EG>(
item_id: &ClientItemId,
map_area: MapArea,
drop_position: (f32, f32, f32))
-> Result<FloorItem, ItemStateError>
-> Result<FloorItem, anyhow::Error>
where
EG: EntityGateway + 'static,
{
@ -70,7 +72,7 @@ pub async fn drop_partial_item<'a, EG>(
map_area: MapArea,
drop_position: (f32, f32),
amount: u32)
-> Result<FloorItem, ItemStateError>
-> Result<FloorItem, anyhow::Error>
where
EG: EntityGateway + 'static,
{
@ -95,7 +97,7 @@ pub async fn drop_meseta<'a, EG>(
map_area: MapArea,
drop_position: (f32, f32),
amount: u32)
-> Result<FloorItem, ItemStateError>
-> Result<FloorItem, anyhow::Error>
where
EG: EntityGateway + 'static,
{
@ -117,7 +119,7 @@ pub async fn withdraw_meseta<'a, EG>(
entity_gateway: &mut EG,
character: &CharacterEntity,
amount: u32)
-> Result<(), ItemStateError>
-> Result<(), anyhow::Error>
where
EG: EntityGateway + 'static,
{
@ -139,7 +141,7 @@ pub async fn deposit_meseta<'a, EG>(
entity_gateway: &mut EG,
character: &CharacterEntity,
amount: u32)
-> Result<(), ItemStateError>
-> Result<(), anyhow::Error>
where
EG: EntityGateway + 'static,
{
@ -162,7 +164,7 @@ pub async fn withdraw_item<'a, EG>(
character: &CharacterEntity,
item_id: &ClientItemId,
amount: u32)
-> Result<InventoryItem, ItemStateError>
-> Result<InventoryItem, anyhow::Error>
where
EG: EntityGateway + 'static,
{
@ -187,7 +189,7 @@ pub async fn deposit_item<'a, EG> (
character: &CharacterEntity,
item_id: &ClientItemId,
amount: u32)
-> Result<(), ItemStateError>
-> Result<(), anyhow::Error>
where
EG: EntityGateway + 'static,
{
@ -209,7 +211,7 @@ pub async fn equip_item<'a, EG> (
character: &CharacterEntity,
item_id: &ClientItemId,
equip_slot: u8,
) -> Result<(), ItemStateError>
) -> Result<(), anyhow::Error>
where
EG: EntityGateway + 'static,
{
@ -230,7 +232,7 @@ pub async fn unequip_item<'a, EG> (
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: &ClientItemId,
) -> Result<(), ItemStateError>
) -> Result<(), anyhow::Error>
where
EG: EntityGateway + 'static,
{
@ -251,7 +253,7 @@ pub async fn sort_inventory<'a, EG> (
entity_gateway: &mut EG,
character: &CharacterEntity,
item_ids: Vec<ClientItemId>,
) -> Result<(), ItemStateError>
) -> Result<(), anyhow::Error>
where
EG: EntityGateway + 'static,
{
@ -274,7 +276,7 @@ pub async fn use_item<'a, EG> (
area_client: AreaClient,
item_id: &ClientItemId,
amount: u32,
) -> Result<Vec<SendShipPacket>, ItemStateError>
) -> Result<Vec<SendShipPacket>, anyhow::Error>
where
EG: EntityGateway + 'static,
{
@ -303,7 +305,7 @@ pub async fn feed_mag<'a, EG> (
character: &CharacterEntity,
mag_item_id: &ClientItemId,
tool_item_id: &ClientItemId,
) -> Result<(), ItemStateError>
) -> Result<(), anyhow::Error>
where
EG: EntityGateway + 'static,
{
@ -327,7 +329,7 @@ pub async fn buy_shop_item<'a, EG> (
shop_item: &'a (dyn ShopItem + Send + Sync),
item_id: ClientItemId,
amount: u32,
) -> Result<InventoryItem, ItemStateError>
) -> Result<InventoryItem, anyhow::Error>
where
EG: EntityGateway + 'static,
{
@ -353,7 +355,7 @@ pub async fn sell_item<'a, EG> (
character: &CharacterEntity,
item_id: ClientItemId,
amount: u32,
) -> Result<InventoryItem, ItemStateError>
) -> Result<InventoryItem, anyhow::Error>
where
EG: EntityGateway + 'static,
{
@ -373,7 +375,7 @@ pub async fn trade_items<'a, EG> (
entity_gateway: &mut EG,
p1: (&AreaClient, &CharacterEntity, &Vec<TradeItem>, Meseta),
p2: (&AreaClient, &CharacterEntity, &Vec<TradeItem>, Meseta))
-> Result<(Vec<InventoryItem>, Vec<InventoryItem>), ItemStateError>
-> Result<(Vec<InventoryItem>, Vec<InventoryItem>), anyhow::Error>
where
EG: EntityGateway + 'static,
{
@ -443,7 +445,7 @@ pub async fn take_meseta<'a, EG> (
entity_gateway: &mut EG,
character_id: &CharacterEntityId,
meseta: Meseta)
-> Result<(), ItemStateError>
-> Result<(), anyhow::Error>
where
EG: EntityGateway + 'static,
{
@ -488,7 +490,7 @@ pub async fn apply_modifier<'a, EG> (
character: &CharacterEntity,
item_id: ClientItemId,
modifier: ItemModifier)
-> Result<IndividualItemDetail, ItemStateError>
-> Result<IndividualItemDetail, anyhow::Error>
where
EG: EntityGateway + 'static,
{

26
src/ship/location.rs

@ -30,41 +30,50 @@ impl LobbyId {
#[derive(Error, Debug, PartialEq, Eq)]
#[error("create room")]
pub enum CreateRoomError {
#[error("no open slots")]
NoOpenSlots,
#[error("client already in area")]
ClientInAreaAlready,
#[error("join error")]
JoinError,
}
#[derive(Error, Debug, PartialEq, Eq)]
#[error("join room")]
pub enum JoinRoomError {
#[error("room does not exist")]
RoomDoesNotExist,
#[error("room is full")]
RoomFull,
#[error("client already in area")]
ClientInAreaAlready,
}
#[derive(Error, Debug, PartialEq, Eq)]
#[error("join lobby")]
pub enum JoinLobbyError {
#[error("lobby does not exist")]
LobbyDoesNotExist,
#[error("lobby is full")]
LobbyFull,
#[error("client already in area")]
ClientInAreaAlready,
}
#[derive(Error, Debug, PartialEq, Eq)]
#[error("get area")]
pub enum GetAreaError {
#[error("not in a room")]
NotInRoom,
#[error("not in a lobby")]
NotInLobby,
#[error("get area: invalid client")]
InvalidClient,
}
#[derive(Error, Debug, PartialEq, Eq)]
#[error("client removal")]
pub enum ClientRemovalError {
#[error("client removal: client not in area")]
ClientNotInArea,
#[error("client removal: invalid area")]
InvalidArea,
}
@ -77,17 +86,20 @@ pub enum GetClientsError {
}
#[derive(Error, Debug, PartialEq, Eq)]
#[error("get neighbor")]
pub enum GetNeighborError {
#[error("get neighbor: invalid client")]
InvalidClient,
#[error("get neighbor: invalid area")]
InvalidArea,
}
#[derive(Error, Debug, PartialEq, Eq)]
#[error("get leader")]
pub enum GetLeaderError {
#[error("get leader: invalid client")]
InvalidClient,
#[error("get leader: invalid area")]
InvalidArea,
#[error("get leader: client not in area")]
NoClientInArea,
}

11
src/ship/packet/builder/lobby.rs

@ -1,6 +1,6 @@
use libpso::packet::ship::*;
use crate::common::serverstate::ClientId;
use crate::ship::ship::{ShipError, Clients, ShipEvent};
use crate::ship::ship::{Clients, ShipEvent};
use crate::ship::location::{ClientLocation, LobbyId, ClientLocationError};
use crate::ship::packet::builder::{player_info};
use crate::ship::items::state::ItemState;
@ -13,7 +13,7 @@ pub async fn join_lobby(id: ClientId,
clients: &Clients,
item_state: &ItemState,
event: ShipEvent)
-> Result<JoinLobby, ShipError> {
-> Result<JoinLobby, anyhow::Error> {
let lobby_clients = client_location.get_clients_in_lobby(lobby).await.map_err(|err| -> ClientLocationError { err.into() })?;
let playerinfo = join_all(
@ -28,9 +28,8 @@ pub async fn join_lobby(id: ClientId,
}}))
.await
.into_iter()
.collect::<Result<Vec<_>, ShipError>>()?;
.collect::<Result<Vec<_>, anyhow::Error>>()?;
//let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id)).unwrap();
let client_block = clients.with(id, |client| Box::pin(async move {
client.block as u16
})).await?;
@ -54,7 +53,7 @@ pub async fn add_to_lobby(id: ClientId,
clients: &Clients,
item_state: &ItemState,
event: ShipEvent)
-> Result<AddToLobby, ShipError> {
-> Result<AddToLobby, anyhow::Error> {
let area_client = client_location.get_local_client(id).await.map_err(|err| -> ClientLocationError { err.into() })?;
let leader = client_location.get_lobby_leader(lobby).await.map_err(|err| -> ClientLocationError { err.into() })?;
clients.with(id, |client| {
@ -77,7 +76,7 @@ pub async fn add_to_lobby(id: ClientId,
pub async fn remove_from_lobby(id: ClientId,
client_location: &ClientLocation)
-> Result<LeaveLobby, ShipError> {
-> Result<LeaveLobby, anyhow::Error> {
let prev_area_index = client_location.get_local_client(id).await.map_err(|err| -> ClientLocationError { err.into() })?.local_client.id();
let prev_area_leader_index = client_location
.get_area_leader(client_location

7
src/ship/packet/builder/room.rs

@ -15,12 +15,11 @@ pub async fn join_room(id: ClientId,
room_id: RoomId,
room: &RoomState,
event: ShipEvent)
-> Result<JoinRoom, ShipError> {
-> Result<JoinRoom, anyhow::Error> {
let all_clients = client_location.get_clients_in_room(room_id).await.map_err(|err| -> ClientLocationError { err.into() })?;
let players = futures::stream::iter(all_clients.iter())
.enumerate()
.fold::<Result<_, ShipError>, _, _>(Ok([PlayerHeader::default(); 4]), |acc, (i, c)| async move {
//let header_client = clients.get(&c.client).ok_or(ShipError::ClientNotFound(id))?;
.fold::<Result<_, anyhow::Error>, _, _>(Ok([PlayerHeader::default(); 4]), |acc, (i, c)| async move {
let header_area_client = client_location.get_local_client(id).await.map_err(|err| ShipError::ClientLocationError(err.into()))?;
clients.with(c.client, |client| Box::pin(async move {
acc.map(|mut a| {
@ -59,7 +58,7 @@ pub async fn add_to_room(_id: ClientId,
leader: &AreaClient,
item_state: &ItemState,
event: ShipEvent)
-> Result<AddToRoom, ShipError> {
-> Result<AddToRoom, anyhow::Error> {
let inventory = item_state.get_character_inventory(&client.character).await?;
Ok(AddToRoom {
flag: 1,

2
src/ship/packet/handler/auth.rs

@ -16,7 +16,7 @@ pub async fn validate_login<EG>(id: ClientId,
shipgate_sender: &Option<async_std::channel::Sender<ShipMessage>>,
ship_name: &str,
num_blocks: usize)
-> Result<Vec<SendShipPacket>, ShipError>
-> Result<Vec<SendShipPacket>, anyhow::Error>
where
EG: EntityGateway,
{

10
src/ship/packet/handler/communication.rs

@ -1,6 +1,6 @@
use libpso::packet::ship::*;
use crate::common::serverstate::ClientId;
use crate::ship::ship::{SendShipPacket, ShipError, Clients};
use crate::ship::ship::{SendShipPacket, Clients};
use crate::ship::location::{ClientLocation};
use crate::entity::gateway::EntityGateway;
@ -10,7 +10,7 @@ pub async fn player_chat(id: ClientId,
msg: PlayerChat,
client_location: &ClientLocation,
clients: &Clients)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
let cmsg = clients.with(id, |client| Box::pin(async move {
PlayerChat::new(client.user.id.0, msg.message)
})).await?;
@ -25,7 +25,7 @@ pub async fn player_chat(id: ClientId,
pub async fn request_infoboard(id: ClientId,
client_location: &ClientLocation,
clients: &Clients)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
let area_clients = client_location.get_client_neighbors(id).await.unwrap();
let infoboards = join_all(
area_clients.iter()
@ -39,7 +39,7 @@ pub async fn request_infoboard(id: ClientId,
}))
.await
.into_iter()
.collect::<Result<Vec<_>, ShipError>>()?;
.collect::<Result<Vec<_>, anyhow::Error>>()?;
Ok(vec![(id, SendShipPacket::ViewInfoboardResponse(ViewInfoboardResponse {response: infoboards}))])
}
@ -47,7 +47,7 @@ pub async fn write_infoboard<EG>(id: ClientId,
new_infoboard: WriteInfoboard,
clients: &Clients,
entity_gateway: &mut EG)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{

50
src/ship/packet/handler/direct_message.rs

@ -39,13 +39,15 @@ async fn send_to_client(id: ClientId,
target: u8,
msg: DirectMessage,
client_location: &ClientLocation)
-> Vec<(ClientId, SendShipPacket)> {
client_location.get_all_clients_by_client(id).await.unwrap().into_iter()
.filter(move |client| client.local_client.id() == target)
.map(move |client| {
(client.client, SendShipPacket::DirectMessage(msg.clone()))
})
.collect()
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
Ok(client_location.get_all_clients_by_client(id)
.await?
.into_iter()
.filter(move |client| client.local_client.id() == target)
.map(move |client| {
(client.client, SendShipPacket::DirectMessage(msg.clone()))
})
.collect())
}
pub async fn guildcard_send(id: ClientId,
@ -53,7 +55,7 @@ pub async fn guildcard_send(id: ClientId,
target: u32,
client_location: &ClientLocation,
clients: &Clients)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
let msg = clients.with(id, |client| Box::pin(async move {
DirectMessage{
flag: target,
@ -72,7 +74,7 @@ pub async fn guildcard_send(id: ClientId,
}
})).await?;
Ok(send_to_client(id, target as u8, msg, client_location).await)
send_to_client(id, target as u8, msg, client_location).await
}
pub async fn request_item<EG>(id: ClientId,
@ -82,7 +84,7 @@ pub async fn request_item<EG>(id: ClientId,
clients: &Clients,
rooms: &Rooms,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + 'static,
{
@ -92,7 +94,7 @@ where
})).await??;
if monster.dropped_item {
return Err(ShipError::MonsterAlreadyDroppedItem(id, request_item.enemy_id))
return Err(ShipError::MonsterAlreadyDroppedItem(id, request_item.enemy_id).into())
}
let clients_in_area = client_location.get_clients_in_room(room_id).await?;
@ -134,7 +136,7 @@ pub async fn pickup_item<EG>(id: ClientId,
client_location: &ClientLocation,
clients: &Clients,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{
@ -193,7 +195,7 @@ pub async fn request_box_item<EG>(id: ClientId,
clients: &Clients,
rooms: &Rooms,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static
{
@ -203,7 +205,7 @@ where
})).await??;
if box_object.dropped_item {
return Err(ShipError::BoxAlreadyDroppedItem(id, box_drop_request.object_id))
return Err(ShipError::BoxAlreadyDroppedItem(id, box_drop_request.object_id).into())
}
let clients_in_area = client_location.get_clients_in_room(room_id).await?;
@ -244,7 +246,7 @@ where
pub async fn send_bank_list(id: ClientId,
clients: &Clients,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
{
let bank = clients.with(id, |client| {
let item_state = item_state.clone();
@ -262,7 +264,7 @@ pub async fn bank_interaction<EG>(id: ClientId,
client_location: &ClientLocation,
clients: &Clients,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{
@ -273,7 +275,7 @@ where
let mut entity_gateway = entity_gateway.clone();
let mut item_state = item_state.clone();
Box::pin(async move {
Ok::<_, ShipError>(match bank_interaction.action {
Ok::<_, anyhow::Error>(match bank_interaction.action {
BANK_ACTION_DEPOSIT => {
if bank_interaction.item_id == 0xFFFFFFFF {
deposit_meseta(&mut item_state, &mut entity_gateway, &client.character, bank_interaction.meseta_amount).await?;
@ -320,7 +322,7 @@ pub async fn shop_request(id: ClientId,
clients: &Clients,
rooms: &Rooms,
shops: &ItemShops)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
{
//let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
let room_id = client_location.get_room(id).await?;
@ -397,7 +399,7 @@ pub async fn buy_item<EG>(id: ClientId,
client_location: &ClientLocation,
clients: &Clients,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{
@ -422,7 +424,7 @@ where
(item, remove)
},
_ => {
return Err(ShipError::ShopError)
return Err(ShipError::ShopError.into())
}
};
@ -439,7 +441,7 @@ where
_ => {}
}
}
builder::message::create_withdrawn_inventory_item(area_client, &inventory_item)
Ok::<_, anyhow::Error>(builder::message::create_withdrawn_inventory_item(area_client, &inventory_item)?)
})}).await??;
let other_clients_in_area = client_location.get_client_neighbors(id).await?;
@ -465,7 +467,7 @@ pub async fn request_tek_item<EG>(id: ClientId,
entity_gateway: &mut EG,
clients: &Clients,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{
@ -502,7 +504,7 @@ where
});
take_meseta(&mut item_state, &mut entity_gateway, &client.character.id, item::Meseta(100)).await?;
builder::message::tek_preview(ClientItemId(tek_request.item_id), &weapon)
Ok::<_, anyhow::Error>(builder::message::tek_preview(ClientItemId(tek_request.item_id), &weapon)?)
})}).await??;
@ -515,7 +517,7 @@ pub async fn accept_tek_item<EG>(id: ClientId,
client_location: &ClientLocation,
clients: &Clients,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{

12
src/ship/packet/handler/lobby.rs

@ -16,7 +16,7 @@ pub async fn block_selected(id: ClientId,
pkt: MenuSelect,
clients: &Clients,
item_state: &ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
clients.with_mut(id, |client| {
let item_state = item_state.clone();
Box::pin(async move {
@ -57,7 +57,7 @@ pub async fn send_player_to_lobby(id: ClientId,
clients: &Clients,
item_state: &ItemState,
event: ShipEvent)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
let lobby = client_location.add_client_to_next_available_lobby(id, LobbyId(0)).await.map_err(|_| ShipError::TooManyClients)?;
let join_lobby = packet::builder::lobby::join_lobby(id, lobby, client_location, clients, item_state, event).await?;
let addto = packet::builder::lobby::add_to_lobby(id, lobby, client_location, clients, item_state, event).await?;
@ -77,7 +77,7 @@ pub async fn change_lobby<EG>(id: ClientId,
rooms: &Rooms,
entity_gateway: &mut EG,
event: ShipEvent)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{
@ -134,7 +134,7 @@ where
pub async fn remove_from_lobby(id: ClientId,
client_location: &mut ClientLocation)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
let area_client = client_location.get_local_client(id).await?;
let neighbors = client_location.get_client_neighbors(id).await?;
let leader = client_location.get_leader_by_client(id).await.map_err(|err| -> ClientLocationError { err.into() })?;
@ -150,7 +150,7 @@ pub async fn get_room_tab_info(id: ClientId,
pkt: MenuDetail,
client_location: &mut ClientLocation,
clients: &Clients)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
let room_id = RoomId(pkt.item as usize);
let clients_in_room = client_location.get_clients_in_room(room_id).await.map_err(|err| -> ClientLocationError { err.into() })?;
let room_info = if clients_in_room.is_empty() {
@ -169,7 +169,7 @@ pub async fn get_room_tab_info(id: ClientId,
})).await
})).await
.into_iter()
.collect::<Result<Vec<_>, ShipError>>()?
.collect::<Result<Vec<_>, anyhow::Error>>()?
.join("\n")
};
Ok(vec![(id, SendShipPacket::SmallLeftDialog(SmallLeftDialog::new(room_info)))])

34
src/ship/packet/handler/message.rs

@ -18,7 +18,7 @@ pub async fn request_exp<EG>(id: ClientId,
client_location: &ClientLocation,
clients: &Clients,
rooms: &Rooms)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{
@ -29,7 +29,7 @@ where
let enemy_exp = rooms.with(room_id, |room| Box::pin(async move {
let monster = room.maps.enemy_by_id(enemy_id)?;
let monster_stats = room.monster_stats.get(&monster.monster).ok_or_else(|| ShipError::UnknownMonster(monster.monster))?;
Ok::<_, ShipError>(monster_stats.exp)
Ok::<_, anyhow::Error>(monster_stats.exp)
})).await??;
let exp_gain = if request_exp.last_hitter == 1 {
@ -83,7 +83,7 @@ pub async fn player_drop_item<EG>(id: ClientId,
clients: &Clients,
rooms: &Rooms,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{
@ -112,7 +112,7 @@ pub async fn drop_coordinates(id: ClientId,
client_location: &ClientLocation,
clients: &Clients,
rooms: &Rooms)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
{
let room_id = client_location.get_room(id).await.map_err(|err| -> ClientLocationError { err.into() })?;
let map_area = rooms.with(room_id, |room| Box::pin(async move {
@ -137,7 +137,7 @@ pub async fn no_longer_has_item<EG>(id: ClientId,
client_location: &ClientLocation,
clients: &Clients,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{
@ -150,7 +150,7 @@ where
})).await?;
if let Some(drop_location) = drop_location {
if drop_location.item_id.0 != no_longer_has_item.item_id {
return Err(ShipError::DropInvalidItemId(no_longer_has_item.item_id));
return Err(ShipError::DropInvalidItemId(no_longer_has_item.item_id).into());
}
if no_longer_has_item.item_id == 0xFFFFFFFF {
@ -218,7 +218,7 @@ where
.collect())
}
else {
Err(ShipError::InvalidItem(ClientItemId(no_longer_has_item.item_id)))
Err(ShipError::InvalidItem(ClientItemId(no_longer_has_item.item_id)).into())
}
}
@ -227,7 +227,7 @@ pub async fn update_player_position(id: ClientId,
clients: &Clients,
client_location: &ClientLocation,
rooms: &Rooms)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
if let Ok(room_id) = client_location.get_room(id).await.map_err(|err| -> ClientLocationError { err.into() }) {
let msg = message.msg.clone();
clients.with_mut(id, |client| {
@ -291,7 +291,7 @@ pub async fn update_player_position(id: ClientId,
}
_ => {},
}
Ok::<_, ShipError>(())
Ok::<_, anyhow::Error>(())
})}).await??;
}
Ok(client_location.get_client_neighbors(id).await?.into_iter()
@ -307,7 +307,7 @@ pub async fn charge_attack<EG>(id: ClientId,
client_location: &ClientLocation,
clients: &Clients,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{
@ -333,7 +333,7 @@ pub async fn player_uses_item<EG>(id: ClientId,
client_location: &ClientLocation,
clients: &Clients,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{
@ -364,7 +364,7 @@ pub async fn player_used_medical_center<EG>(id: ClientId,
client_location: &ClientLocation,
clients: &Clients,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{
@ -390,7 +390,7 @@ pub async fn player_feed_mag<EG>(id: ClientId,
client_location: &ClientLocation,
clients: &Clients,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{
@ -415,7 +415,7 @@ pub async fn player_equips_item<EG>(id: ClientId,
entity_gateway: &mut EG,
clients: &Clients,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{
@ -440,7 +440,7 @@ pub async fn player_unequips_item<EG>(id: ClientId,
entity_gateway: &mut EG,
clients: &Clients,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{
@ -458,7 +458,7 @@ pub async fn player_sorts_items<EG>(id: ClientId,
entity_gateway: &mut EG,
clients: &Clients,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{
@ -488,7 +488,7 @@ pub async fn player_sells_item<EG> (id: ClientId,
entity_gateway: &mut EG,
clients: &Clients,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{

36
src/ship/packet/handler/quest.rs

@ -4,7 +4,7 @@ use libpso::packet::ship::*;
use crate::common::serverstate::ClientId;
use crate::ship::ship::{SendShipPacket, ShipError, Clients, ShipEvent};
use crate::ship::room::Rooms;
use crate::ship::location::{ClientLocation, ClientLocationError};
use crate::ship::location::{ClientLocation};
use crate::ship::packet::builder::quest;
use libpso::util::array_to_utf8;
@ -13,7 +13,7 @@ enum QuestFileType {
Dat
}
fn parse_filename(filename_bytes: &[u8; 16]) -> Result<(u16, u16, QuestFileType), ShipError> {
fn parse_filename(filename_bytes: &[u8; 16]) -> Result<(u16, u16, QuestFileType), anyhow::Error> {
let filename = array_to_utf8(*filename_bytes).map_err(|_| ShipError::InvalidQuestFilename("NOT UTF8".to_string()))?;
let (filename, suffix) = {
let mut s = filename.splitn(2, '.');
@ -24,7 +24,7 @@ fn parse_filename(filename_bytes: &[u8; 16]) -> Result<(u16, u16, QuestFileType)
let datatype = match suffix {
"bin" => QuestFileType::Bin,
"dat" => QuestFileType::Dat,
_ => return Err(ShipError::InvalidQuestFilename(filename.to_owned()))
_ => Err(ShipError::InvalidQuestFilename(filename.to_owned()))?
};
let (category, quest) = {
@ -41,8 +41,8 @@ pub async fn send_quest_category_list(id: ClientId,
rql: RequestQuestList,
client_location: &ClientLocation,
rooms: &Rooms)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
let room_id = client_location.get_room(id).await.map_err(|err| -> ClientLocationError { err.into() })?;
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
let room_id = client_location.get_room(id).await?;
let rql = rql.clone();
rooms.with_mut(room_id, |room| Box::pin(async move {
let qcl = quest::quest_category_list(&room.quests[rql.flag.clamp(0, (room.quests.len() - 1) as u32) as usize]);
@ -55,8 +55,8 @@ pub async fn select_quest_category(id: ClientId,
menuselect: MenuSelect,
client_location: &ClientLocation,
rooms: &Rooms)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
let room_id = client_location.get_room(id).await.map_err(|err| -> ClientLocationError { err.into() })?;
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
let room_id = client_location.get_room(id).await?;
rooms.with(room_id, |room| Box::pin(async move {
let (_, category_quests) = room.quests[room.quest_group.value()].iter()
.nth(menuselect.item as usize)
@ -72,8 +72,8 @@ pub async fn quest_detail(id: ClientId,
questdetailrequest: QuestDetailRequest,
client_location: &ClientLocation,
rooms: &Rooms)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
let room_id = client_location.get_room(id).await.map_err(|err| -> ClientLocationError { err.into() })?;
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
let room_id = client_location.get_room(id).await?;
rooms.with(room_id, |room| Box::pin(async move {
let (_, category_quests) = room.quests[room.quest_group.value()].iter()
.nth(questdetailrequest.category as usize)
@ -96,8 +96,8 @@ pub async fn player_chose_quest(id: ClientId,
client_location: &ClientLocation,
rooms: &Rooms,
event: ShipEvent)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
let room_id = client_location.get_room(id).await.map_err(|err| -> ClientLocationError { err.into() })?;
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
let room_id = client_location.get_room(id).await?;
let client_location = client_location.clone();
let questmenuselect = questmenuselect.clone();
@ -122,7 +122,7 @@ pub async fn player_chose_quest(id: ClientId,
let bin = quest::quest_header(&questmenuselect, &quest.bin_blob, "bin");
let dat = quest::quest_header(&questmenuselect, &quest.dat_blob, "dat");
let area_clients = client_location.get_all_clients_by_client(id).await.map_err(|err| -> ClientLocationError { err.into() })?;
let area_clients = client_location.get_all_clients_by_client(id).await?;
for client in &area_clients {
clients.with_mut(client.client, |client| Box::pin(async move {
client.done_loading_quest = false;
@ -141,9 +141,9 @@ pub async fn quest_file_request(id: ClientId,
quest_file_request: QuestFileRequest,
client_location: &ClientLocation,
rooms: &mut Rooms)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
{
let room_id = client_location.get_room(id).await.map_err(|err| -> ClientLocationError { err.into() })?;
let room_id = client_location.get_room(id).await?;
let quest_file_request = quest_file_request.clone();
rooms.with(room_id, |room| Box::pin(async move {
@ -175,8 +175,8 @@ pub async fn quest_chunk_ack(id: ClientId,
quest_chunk_ack: QuestChunkAck,
client_location: &ClientLocation,
rooms: &Rooms)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
let room_id = client_location.get_room(id).await.map_err(|err| -> ClientLocationError { err.into() })?;
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
let room_id = client_location.get_room(id).await?;
let quest_chunk_ack = quest_chunk_ack.clone();
rooms.with(room_id, |room| Box::pin(async move {
@ -211,11 +211,11 @@ pub async fn quest_chunk_ack(id: ClientId,
pub async fn done_loading_quest(id: ClientId,
clients: &Clients,
client_location: &ClientLocation)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
clients.with_mut(id, |client| Box::pin(async move {
client.done_loading_quest = true;
})).await?;
let area_clients = client_location.get_all_clients_by_client(id).await.map_err(|err| -> ClientLocationError { err.into() })?;
let area_clients = client_location.get_all_clients_by_client(id).await?;
let all_loaded = area_clients.iter()
.map(|client|

14
src/ship/packet/handler/room.rs

@ -5,7 +5,7 @@ use libpso::packet::ship::*;
use libpso::packet::messages::*;
use crate::common::serverstate::ClientId;
use crate::common::leveltable::LEVEL_TABLE;
use crate::ship::ship::{SendShipPacket, ShipError, Clients, ShipEvent};
use crate::ship::ship::{SendShipPacket, Clients, ShipEvent};
use crate::ship::room::Rooms;
use crate::ship::location::{ClientLocation, RoomId, RoomLobby, GetAreaError};
use crate::ship::packet::builder;
@ -19,7 +19,7 @@ pub async fn create_room(id: ClientId,
item_state: &mut ItemState,
rooms: &Rooms,
event: ShipEvent)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
let level = clients.with(id, |client| Box::pin(async move {
LEVEL_TABLE.get_level_from_exp(client.character.char_class, client.character.exp)
})).await?;
@ -47,7 +47,7 @@ pub async fn create_room(id: ClientId,
item_state.add_character_to_room(room_id, &client.character, area_client).await;
let mut room = room::RoomState::from_create_room(&create_room, client.character.section_id, event)?;
room.bursting = true;
Ok::<_, ShipError>(room)
Ok::<_, anyhow::Error>(room)
})}).await??;
let join_room = builder::room::join_room(id, clients, client_location, room_id, &room, event).await?;
@ -69,7 +69,7 @@ pub async fn create_room(id: ClientId,
pub async fn room_name_request(id: ClientId,
client_location: &ClientLocation,
rooms: &Rooms)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
let area = client_location.get_area(id).await?;
match area {
RoomLobby::Room(room) => {
@ -90,7 +90,7 @@ pub async fn join_room(id: ClientId,
item_state: &mut ItemState,
rooms: &Rooms,
event: ShipEvent)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
let room_id = RoomId(pkt.item as usize);
if !rooms.exists(room_id).await {
return Ok(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("This room no longer exists!".into())))])
@ -171,7 +171,7 @@ pub async fn join_room(id: ClientId,
pub async fn done_bursting(id: ClientId,
client_location: &ClientLocation,
rooms: &Rooms)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
let room_id = client_location.get_room(id).await?;
let rare_monster_list = rooms.with_mut(room_id, |room| Box::pin(async move {
room.bursting = false;
@ -235,7 +235,7 @@ pub async fn request_room_list(id: ClientId,
pub async fn cool_62(id: ClientId,
cool_62: Like62ButCooler,
client_location: &ClientLocation)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
let target = cool_62.flag as u8;
let cool_62 = cool_62.clone();
Ok(client_location

8
src/ship/packet/handler/settings.rs

@ -7,7 +7,7 @@ pub async fn update_config<EG>(id: ClientId,
update_config: UpdateConfig,
clients: &Clients,
entity_gateway: &mut EG)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{
@ -24,7 +24,7 @@ pub async fn save_options<EG>(id: ClientId,
save_options: SaveOptions,
clients: &Clients,
entity_gateway: &mut EG)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{
@ -41,7 +41,7 @@ pub async fn keyboard_config<EG>(id: ClientId,
keyboard_config: KeyboardConfig,
clients: &Clients,
entity_gateway: &mut EG)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{
@ -58,7 +58,7 @@ pub async fn gamepad_config<EG>(id: ClientId,
gamepad_config: GamepadConfig,
clients: &Clients,
entity_gateway: &mut EG)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{

26
src/ship/packet/handler/trade.rs

@ -3,7 +3,7 @@ use libpso::packet::ship::*;
use libpso::packet::messages::*;
use crate::common::serverstate::ClientId;
use crate::ship::ship::{SendShipPacket, ShipError, Clients};
use crate::ship::location::{ClientLocation, ClientLocationError};
use crate::ship::location::{ClientLocation};
use crate::ship::items::ClientItemId;
use crate::ship::items::state::{ItemState, ItemStateError};
use crate::ship::items::inventory::InventoryItemDetail;
@ -57,9 +57,9 @@ async fn do_trade_action<F>(id: ClientId,
this: &mut ClientTradeState,
other: &mut ClientTradeState,
action: F)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
F: Fn(&mut ClientTradeState, &mut ClientTradeState) -> Result<(), ShipError>,
F: Fn(&mut ClientTradeState, &mut ClientTradeState) -> Result<(), anyhow::Error>,
{
Ok(match action(this, other) {
Ok(_) => {
@ -92,7 +92,7 @@ pub async fn trade_request(id: ClientId,
clients: &Clients,
item_state: &mut ItemState,
trades: &mut TradeState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
{
let trade_request = trade_request.clone(); // TODO: make this function take ownership of packet
match trade_request.trade {
@ -293,12 +293,12 @@ async fn inner_items_to_trade(id: ClientId,
clients: &Clients,
item_state: &mut ItemState,
trades: &mut TradeState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
{
let pkts = trades
.with(&id, |mut this, other| async move {
if status_is_not(&this.status, &[TradeStatus::FinalConfirm]) || status_is_not(&other.status, &[TradeStatus::FinalConfirm, TradeStatus::ItemsChecked]) {
return Err(ShipError::from(TradeError::MismatchedStatus))
return Err(anyhow::Error::from(ShipError::from(TradeError::MismatchedStatus)))
}
let other_client = other.client();
let (this_inventory, other_inventory) = clients.with(this.client(), |client| {
@ -311,7 +311,7 @@ async fn inner_items_to_trade(id: ClientId,
Box::pin(async move {
item_state.get_character_inventory(&client.character).await
})}).await??;
Ok::<_, ShipError>((this, other_inventory))
Ok::<_, anyhow::Error>((this, other_inventory))
})}).await??;
if items_to_trade.count as usize != (this.items.len() + usize::from(this.meseta != 0)) {
@ -383,7 +383,7 @@ async fn inner_items_to_trade(id: ClientId,
}
}
})
.collect::<Result<Vec<_>, ShipError>>()?;
.collect::<Result<Vec<_>, anyhow::Error>>()?;
this.status = TradeStatus::ItemsChecked;
if this.status == TradeStatus::ItemsChecked && other.status == TradeStatus::ItemsChecked {
@ -418,7 +418,7 @@ pub async fn items_to_trade(id: ClientId,
clients: &Clients,
item_state: &mut ItemState,
trades: &mut TradeState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
{
let t = inner_items_to_trade(id, items_to_trade_pkt, client_location, clients, item_state, trades).await;
match t {
@ -443,7 +443,7 @@ async fn trade_confirmed_inner<EG>(id: ClientId,
clients: &Clients,
item_state: &mut ItemState,
trades: &mut TradeState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{
@ -460,14 +460,14 @@ where
.with(&id, |mut this, other| {
async move {
if status_is_not(&this.status, &[TradeStatus::ItemsChecked]) || status_is_not(&other.status, &[TradeStatus::ItemsChecked, TradeStatus::TradeComplete]) {
return Err(ShipError::TradeError(TradeError::MismatchedStatus))
return Err(anyhow::Error::from(ShipError::TradeError(TradeError::MismatchedStatus)))
}
this.status = TradeStatus::TradeComplete;
if this.status == TradeStatus::TradeComplete && other.status == TradeStatus::TradeComplete {
let this_local_client = client_location.get_local_client(this.client()).await?;
let other_local_client = client_location.get_local_client(other.client()).await?;
let room_id = client_location.get_room(id).await.map_err(|err| -> ClientLocationError { err.into() })?;
let room_id = client_location.get_room(id).await?;
Ok(TradeReady::BothPlayers(room_id,
(this_local_client, /*this_client, */this.clone()),
@ -584,7 +584,7 @@ pub async fn trade_confirmed<EG>(id: ClientId,
clients: &Clients,
item_state: &mut ItemState,
trades: &mut TradeState)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError>
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error>
where
EG: EntityGateway + Clone + 'static,
{

10
src/ship/room.rs

@ -29,7 +29,7 @@ impl Default for Rooms {
}
impl Rooms {
pub async fn add(&self, room_id: RoomId, room: RoomState) -> Result<(), ShipError> {
pub async fn add(&self, room_id: RoomId, room: RoomState) -> Result<(), anyhow::Error> {
*self.0
.get(room_id.0)
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?
@ -58,7 +58,7 @@ impl Rooms {
}
}
pub async fn with<'a, T, F>(&'a self, room_id: RoomId, func: F) -> Result<T, ShipError>
pub async fn with<'a, T, F>(&'a self, room_id: RoomId, func: F) -> Result<T, anyhow::Error>
where
T: Send,
F: for<'b> FnOnce(&'b RoomState) -> BoxFuture<'b, T> + Send + 'a
@ -72,11 +72,11 @@ impl Rooms {
Ok(func(room).await)
}
else {
Err(ShipError::InvalidRoom(room_id.0 as u32))
Err(ShipError::InvalidRoom(room_id.0 as u32).into())
}
}
pub async fn with_mut<'a, T, F>(&'a self, room_id: RoomId, func: F) -> Result<T, ShipError>
pub async fn with_mut<'a, T, F>(&'a self, room_id: RoomId, func: F) -> Result<T, anyhow::Error>
where
T: Send,
F: for<'b> FnOnce(&'b mut RoomState) -> BoxFuture<'b, T> + Send + 'a
@ -91,7 +91,7 @@ impl Rooms {
Ok(func(room).await)
}
else {
Err(ShipError::InvalidRoom(room_id.0 as u32))
Err(ShipError::InvalidRoom(room_id.0 as u32).into())
}
}

8
src/ship/ship.rs

@ -2,6 +2,8 @@
use std::net::Ipv4Addr;
use std::collections::HashMap;
use std::backtrace::Backtrace;
use async_std::channel;
use async_std::sync::{Arc, Mutex, RwLock};
@ -162,11 +164,13 @@ pub enum ShipError {
SendError(#[from] async_std::channel::SendError<ShipMessage>),
}
/*
impl<I: Into<ClientLocationError>> From<I> for ShipError {
fn from(other: I) -> ShipError {
ShipError::ClientLocationError(other.into())
}
}
*/
#[derive(Debug)]
@ -467,13 +471,13 @@ pub struct Block {
pub struct Blocks(pub Vec<Block>);
impl Blocks {
async fn get_from_client(&mut self, id: ClientId, clients: &Clients) -> Result<&mut Block, ShipError> {
async fn get_from_client(&mut self, id: ClientId, clients: &Clients) -> Result<&mut Block, anyhow::Error> {
let block = clients.with(id, |client| Box::pin(async move {
client.block
})).await?;
self.0
.get_mut(block)
.ok_or_else(|| ShipError::InvalidBlock(block))
.ok_or_else(|| ShipError::InvalidBlock(block).into())
}
}

Loading…
Cancel
Save