Browse Source

Merge pull request 'fix mags and picking up invalid items' (#260) from misc_stuff into master

pbs
jake 4 years ago
parent
commit
cf7be2e5d0
  1. 24
      src/entity/gateway/postgres/postgres.rs
  2. 65
      src/ship/items/manager.rs
  3. 2
      src/ship/packet/handler/auth.rs
  4. 49
      src/ship/packet/handler/direct_message.rs
  5. 6
      src/ship/packet/handler/lobby.rs
  6. 30
      src/ship/packet/handler/message.rs
  7. 8
      tests/test_item_pickup.rs

24
src/entity/gateway/postgres/postgres.rs

@ -450,16 +450,20 @@ impl EntityGateway for PostgresGateway {
let entity = sqlx::query_as::<_, PgItemWithLocation>("select item.id, item.item, item_location.location from item join item_location on item.id = item_location.item where id = $1")
.bind(item)
.fetch_one(&self.pool).await
.map(|item| item.into())?;
.map(|item| item.into())
.map(|item| self.apply_item_modifications(item))?
.await;
real_inventory.push(InventoryItemEntity::Individual(entity));
},
PgInventoryItemEntity::Stacked(items) => {
let mut stacked_item = Vec::new();
for s_item in items {
stacked_item.push(sqlx::query_as::<_, PgItemWithLocation>("select item.id, item.item, item_location.location from item join item_location on item.id = item_location.item where id = $1")
.bind(s_item)
.fetch_one(&self.pool).await
.map(|item| item.into())?)
.bind(s_item)
.fetch_one(&self.pool).await
.map(|item| item.into())
.map(|item| self.apply_item_modifications(item))?
.await)
}
real_inventory.push(InventoryItemEntity::Stacked(stacked_item));
}
@ -482,16 +486,20 @@ impl EntityGateway for PostgresGateway {
let entity = sqlx::query_as::<_, PgItemWithLocation>("select item.id, item.item, item_location.location from item join item_location on item.id = item_location.item where id = $1")
.bind(item)
.fetch_one(&self.pool).await
.map(|item| item.into())?;
.map(|item| item.into())
.map(|item| self.apply_item_modifications(item))?
.await;
real_bank.push(BankItemEntity::Individual(entity));
},
PgInventoryItemEntity::Stacked(items) => {
let mut stacked_item = Vec::new();
for s_item in items {
stacked_item.push(sqlx::query_as::<_, PgItemWithLocation>("select item.id, item.item, item_location.location from item join item_location on item.id = item_location.item where id = $1")
.bind(s_item)
.fetch_one(&self.pool).await
.map(|item| item.into())?)
.bind(s_item)
.fetch_one(&self.pool).await
.map(|item| item.into())
.map(|item| self.apply_item_modifications(item))?
.await)
}
real_bank.push(BankItemEntity::Stacked(stacked_item));
}

65
src/ship/items/manager.rs

@ -18,6 +18,11 @@ use crate::ship::items::floor::*;
use crate::ship::items::inventory::*;
use crate::ship::items::use_tool;
#[derive(PartialEq, Eq)]
pub enum FloorType {
Local,
Shared,
}
pub enum TriggerCreateItem {
Yes,
@ -84,7 +89,7 @@ impl ItemManager {
}
// TODO: Result
pub async fn load_character<EG: EntityGateway>(&mut self, entity_gateway: &mut EG, character: &CharacterEntity) -> Result<(), ItemManagerError> {
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?;
@ -164,19 +169,19 @@ impl ItemManager {
self.character_floor.insert(character.id, RoomFloorItems::new());
self.room_floor.entry(room_id).or_insert(RoomFloorItems::new());
let mut inc = 0xF0000000;
let mut inc = 0x00810000;
self.room_item_id_counter.entry(room_id).or_insert(Box::new(move || {
inc += 1;
ClientItemId(inc)
}));
}
pub fn get_character_inventory(&self, character: &CharacterEntity) -> Result<&CharacterInventory, ItemManagerError> {
pub fn get_character_inventory(&self, character: &CharacterEntity) -> Result<&CharacterInventory, anyhow::Error> {
Ok(self.character_inventory.get(&character.id)
.ok_or(ItemManagerError::NoCharacter(character.id))?)
}
pub fn get_character_bank(&self, character: &CharacterEntity) -> Result<&CharacterBank, ItemManagerError> {
pub fn get_character_bank(&self, character: &CharacterEntity) -> Result<&CharacterBank, anyhow::Error> {
Ok(self.character_bank
.get(&character.id)
.ok_or(ItemManagerError::NoCharacter(character.id))?)
@ -205,20 +210,20 @@ impl ItemManager {
});
}
pub fn get_floor_item_by_id(&self, character: &CharacterEntity, item_id: ClientItemId) -> Result<&FloorItem, ItemManagerError> {
pub fn get_floor_item_by_id(&self, character: &CharacterEntity, item_id: ClientItemId) -> Result<(&FloorItem, FloorType), anyhow::Error> {
let local_floor = self.character_floor.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
let room = self.character_room.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
let shared_floor = self.room_floor.get(room).ok_or(ItemManagerError::NoCharacter(character.id))?;
local_floor.get_item_by_id(item_id)
local_floor.get_item_by_id(item_id).map(|item| (item, FloorType::Local))
.or_else(|| {
shared_floor.get_item_by_id(item_id)
shared_floor.get_item_by_id(item_id).map(|item| (item, FloorType::Shared))
})
.ok_or(ItemManagerError::NoSuchItemId(item_id))
.ok_or(ItemManagerError::NoSuchItemId(item_id).into())
}
pub async fn character_picks_up_item<EG: EntityGateway>(&mut self, entity_gateway: &mut EG, character: &mut CharacterEntity, item_id: ClientItemId)
-> Result<TriggerCreateItem, ItemManagerError> {
-> Result<TriggerCreateItem, anyhow::Error> {
let local_floor = self.character_floor.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
let room_id = self.character_room.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
@ -246,7 +251,7 @@ impl ItemManager {
}
},
None => {
return Err(ItemManagerError::CouldNotAddToInventory(item_id));
return Err(ItemManagerError::CouldNotAddToInventory(item_id).into());
},
}
TriggerCreateItem::Yes
@ -273,20 +278,20 @@ impl ItemManager {
}
},
None => {
return Err(ItemManagerError::CouldNotAddToInventory(item_id));
return Err(ItemManagerError::CouldNotAddToInventory(item_id).into());
}
}
},
Some(FloorItem::Meseta(meseta_floor_item)) => {
if character.meseta >= 999999 {
return Err(ItemManagerError::CouldNotAddToInventory(item_id));
return Err(ItemManagerError::CouldNotAddToInventory(item_id).into());
}
character.meseta = std::cmp::min(character.meseta + meseta_floor_item.meseta.0, 999999);
entity_gateway.save_character(&character).await?;
TriggerCreateItem::No
},
None => {
return Err(ItemManagerError::CouldNotAddToInventory(item_id));
return Err(ItemManagerError::CouldNotAddToInventory(item_id).into());
}
};
@ -295,7 +300,7 @@ impl ItemManager {
Ok(trigger_create_item)
}
pub async fn enemy_drop_item_on_local_floor<EG: EntityGateway>(&mut self, entity_gateway: &mut EG, character: &CharacterEntity, item_drop: ItemDrop) -> Result<&FloorItem, ItemManagerError> {
pub async fn enemy_drop_item_on_local_floor<EG: EntityGateway>(&mut self, entity_gateway: &mut EG, character: &CharacterEntity, item_drop: ItemDrop) -> Result<&FloorItem, anyhow::Error> {
let room_id = self.character_room.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
enum ItemOrMeseta {
@ -377,7 +382,7 @@ impl ItemManager {
self.character_floor.entry(character.id).or_insert(RoomFloorItems::new()).add_item(floor_item);
// TODO: make these real errors
self.character_floor.get(&character.id).ok_or(ItemManagerError::Idunnoman)?.get_item_by_id(item_id).ok_or(ItemManagerError::Idunnoman)
self.character_floor.get(&character.id).ok_or(ItemManagerError::Idunnoman)?.get_item_by_id(item_id).ok_or(ItemManagerError::Idunnoman.into())
}
pub async fn player_drop_item_on_shared_floor<EG: EntityGateway>(&mut self,
@ -386,7 +391,7 @@ impl ItemManager {
//inventory_item: InventoryItem,
item_id: ClientItemId,
item_drop_location: (MapArea, f32, f32, f32))
-> Result<(), ItemManagerError> {
-> Result<(), anyhow::Error> {
let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
let room_id = self.character_room.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
let shared_floor = self.room_floor.get_mut(&room_id).ok_or(ItemManagerError::NoCharacter(character.id))?;
@ -431,11 +436,11 @@ impl ItemManager {
character: &mut CharacterEntity,
drop_location: ItemDropLocation,
amount: u32)
-> Result<FloorItem, ItemManagerError> {
-> Result<FloorItem, anyhow::Error> {
let room_id = self.character_room.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
let shared_floor = self.room_floor.get_mut(&room_id).ok_or(ItemManagerError::NoCharacter(character.id))?;
if character.meseta < amount {
return Err(ItemManagerError::CouldNotDropMeseta)
return Err(ItemManagerError::CouldNotDropMeseta.into())
}
character.meseta -= amount;
entity_gateway.save_character(&character).await?;
@ -461,7 +466,7 @@ impl ItemManager {
item_id: ClientItemId,
drop_location: ItemDropLocation,
amount: usize)
-> Result<&StackedFloorItem, ItemManagerError> {
-> Result<&StackedFloorItem, anyhow::Error> {
let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
let room_id = self.character_room.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
let shared_floor = self.room_floor.get_mut(&room_id).ok_or(ItemManagerError::NoCharacter(character.id))?;
@ -493,7 +498,7 @@ impl ItemManager {
character: &mut CharacterEntity,
item_id: ClientItemId,
amount: usize)
-> Result<ConsumedItem, ItemManagerError> {
-> Result<ConsumedItem, anyhow::Error> {
let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
let used_item = inventory.get_item_handle_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?;
let consumed_item = used_item.consume(amount)?;
@ -518,7 +523,7 @@ impl ItemManager {
character: &CharacterEntity,
item_id: ClientItemId,
amount: usize)
-> Result<(), ItemManagerError> {
-> Result<(), anyhow::Error> {
let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
let bank = self.character_bank
.get_mut(&character.id)
@ -556,7 +561,7 @@ impl ItemManager {
character: &CharacterEntity,
item_id: ClientItemId,
amount: usize)
-> Result<&InventoryItem, ItemManagerError> {
-> Result<&InventoryItem, anyhow::Error> {
let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
let bank = self.character_bank
@ -588,7 +593,7 @@ impl ItemManager {
entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?;
entity_gateway.set_character_bank(&character.id, &bank.as_bank_entity(&character.id, &BankName("".into())), BankName("".into())).await?;
inventory.slot(inventory_item_slot).ok_or(ItemManagerError::Idunnoman)
inventory.slot(inventory_item_slot).ok_or(ItemManagerError::Idunnoman.into())
}
pub async fn player_feeds_mag_item<EG: EntityGateway>(&mut self,
@ -596,7 +601,7 @@ impl ItemManager {
character: &CharacterEntity,
mag_id: ClientItemId,
tool_id: ClientItemId)
-> Result<(), ItemManagerError> {
-> Result<(), anyhow::Error> {
let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
let consumed_tool = {
let item_to_feed = inventory.get_item_handle_by_id(tool_id).ok_or(ItemManagerError::NoSuchItemId(tool_id))?;
@ -614,7 +619,7 @@ impl ItemManager {
let consumed_tool_type = match &consumed_tool {
ConsumedItem::Stacked(stacked_consumed_item) => stacked_consumed_item.tool.tool,
_ => return Err(ItemManagerError::WrongItemType(tool_id))
_ => return Err(ItemManagerError::WrongItemType(tool_id).into())
};
mag.feed(consumed_tool_type);
@ -632,7 +637,7 @@ impl ItemManager {
pub async fn use_item<EG: EntityGateway>(&mut self,
used_item: ConsumedItem,
entity_gateway: &mut EG,
character: &mut CharacterEntity) -> Result<(), ItemManagerError> {
character: &mut CharacterEntity) -> Result<(), anyhow::Error> {
let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
match &used_item.item() {
ItemDetail::Weapon(_w) => {
@ -749,7 +754,7 @@ impl ItemManager {
shop_item: &(dyn ShopItem + Send + Sync),
item_id: ClientItemId,
amount: usize)
-> Result<&InventoryItem, ItemManagerError> {
-> Result<&InventoryItem, anyhow::Error> {
let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
let item_detail = shop_item.as_item();
@ -848,7 +853,7 @@ impl ItemManager {
character: &CharacterEntity,
item_id: ClientItemId,
equip_slot: u8)
-> Result<(), ItemManagerError> {
-> Result<(), anyhow::Error> {
let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
inventory.equip(&item_id, equip_slot);
entity_gateway.set_character_equips(&character.id, &inventory.as_equipped_entity()).await?;
@ -859,7 +864,7 @@ impl ItemManager {
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: ClientItemId)
-> Result<(), ItemManagerError> {
-> Result<(), anyhow::Error> {
let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
inventory.unequip(&item_id);
entity_gateway.set_character_equips(&character.id, &inventory.as_equipped_entity()).await?;
@ -870,7 +875,7 @@ impl ItemManager {
entity_gateway: &mut EG,
character: &CharacterEntity,
item_ids: [u32; 30])
-> Result<(), ItemManagerError> {
-> Result<(), anyhow::Error> {
let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
let sorted_inventory_items: Vec<InventoryItem> = item_ids.iter()
.filter(|&client_item_id| *client_item_id < 0xFFFFFFFF)

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

@ -12,7 +12,7 @@ pub async fn validate_login<EG: EntityGateway>(id: ClientId,
clients: &mut Clients,
item_manager: &mut ItemManager,
ship_name: &String)
-> Result<Vec<SendShipPacket>, ShipError> {
-> Result<Vec<SendShipPacket>, anyhow::Error> {
Ok(match get_login_status(entity_gateway, pkt).await.and_then(check_if_already_online) {
Ok(mut user) => {
user.at_ship= true;

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

@ -6,7 +6,7 @@ use crate::common::serverstate::ClientId;
use crate::ship::ship::{SendShipPacket, ShipError, Clients, Rooms, ItemShops};
use crate::ship::location::{ClientLocation, ClientLocationError};
use crate::ship::drops::ItemDrop;
use crate::ship::items::{ItemManager, ClientItemId, TriggerCreateItem, FloorItem};
use crate::ship::items::{ItemManager, ClientItemId, TriggerCreateItem, FloorItem, FloorType};
use crate::entity::gateway::EntityGateway;
use libpso::utf8_to_utf16_array;
use crate::ship::packet::builder;
@ -65,7 +65,7 @@ pub async fn request_item<EG>(id: ClientId,
clients: &mut Clients,
rooms: &mut Rooms,
item_manager: &mut ItemManager)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError>
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
where
EG: EntityGateway
{
@ -77,7 +77,7 @@ where
let monster = room.maps.enemy_by_id(request_item.enemy_id as usize)?;
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).map_err(|err| -> ClientLocationError { err.into() })?;
@ -114,7 +114,7 @@ pub async fn pickup_item<EG>(id: ClientId,
client_location: &ClientLocation,
clients: &mut Clients,
item_manager: &mut ItemManager)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError>
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
where
EG: EntityGateway
{
@ -124,7 +124,7 @@ where
let clients_in_area = client_location.get_clients_in_room(room_id).map_err(|err| -> ClientLocationError { err.into() })?;
// TODO: should not need to fetch the item here to construct this packet
let item = item_manager.get_floor_item_by_id(&client.character, ClientItemId(pickup_item.item_id))?;
let (item, floor_type) = item_manager.get_floor_item_by_id(&client.character, ClientItemId(pickup_item.item_id))?;
let remove_item = builder::message::remove_item_from_floor(area_client, &item)?;
let create_item = match item {
FloorItem::Meseta(_) => None,
@ -133,11 +133,19 @@ where
match item_manager.character_picks_up_item(entity_gateway, &mut client.character, ClientItemId(pickup_item.item_id)).await {
Ok(trigger_create_item) => {
Ok(Box::new(Vec::new().into_iter()
.chain(clients_in_area.clone().into_iter()
.map(move |c| {
(c.client, SendShipPacket::Message(Message::new(GameMessage::RemoveItemFromFloor(remove_item.clone()))))
}))
let remove_packets: Box<dyn Iterator<Item=(ClientId, SendShipPacket)> + Send> = match floor_type {
FloorType::Local => {
Box::new(vec![(id, SendShipPacket::Message(Message::new(GameMessage::RemoveItemFromFloor(remove_item.clone()))))].into_iter())
},
FloorType::Shared => {
Box::new(clients_in_area.clone().into_iter()
.map(move |c| {
(c.client, SendShipPacket::Message(Message::new(GameMessage::RemoveItemFromFloor(remove_item.clone()))))
}))
},
};
Ok(Box::new(remove_packets
.chain(clients_in_area.into_iter().
filter_map(move |c| {
match trigger_create_item {
@ -145,8 +153,7 @@ where
_ => None
}
}
)))
)
))))
},
Err(err) => {
warn!("character {:?} could not pick up item: {:?}", client.character.id, err);
@ -162,7 +169,7 @@ pub async fn request_box_item<EG>(id: ClientId,
clients: &mut Clients,
rooms: &mut Rooms,
item_manager: &mut ItemManager)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError>
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
where
EG: EntityGateway
{
@ -174,7 +181,7 @@ EG: EntityGateway
let box_object = room.maps.object_by_id(box_drop_request.object_id as usize)?;
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).map_err(|err| -> ClientLocationError { err.into() })?;
@ -209,7 +216,7 @@ EG: EntityGateway
pub async fn send_bank_list(id: ClientId,
clients: &Clients,
item_manager: &mut ItemManager)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError>
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
{
let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?;
let bank_items = item_manager.get_character_bank(&client.character)?;
@ -224,7 +231,7 @@ pub async fn bank_interaction<EG>(id: ClientId,
client_location: &ClientLocation,
clients: &mut Clients,
item_manager: &mut ItemManager)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError>
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
where
EG: EntityGateway
{
@ -285,7 +292,7 @@ pub async fn shop_request(id: ClientId,
rooms: &Rooms,
level_table: &CharacterLevelTable,
shops: &mut ItemShops)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError>
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
{
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
let room_id = client_location.get_room(id).map_err(|err| -> ClientLocationError { err.into() })?;
@ -310,7 +317,7 @@ pub async fn shop_request(id: ClientId,
builder::message::shop_list(shop_request.shop_type, &client.armor_shop)
},
_ => {
return Err(ShipError::ShopError)
return Err(ShipError::ShopError.into())
}
};
@ -324,7 +331,7 @@ pub async fn buy_item<EG>(id: ClientId,
client_location: &ClientLocation,
clients: &mut Clients,
item_manager: &mut ItemManager)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError>
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
where
EG: EntityGateway
{
@ -353,12 +360,12 @@ where
(item, remove)
},
_ => {
return Err(ShipError::ShopError)
return Err(ShipError::ShopError.into())
}
};
if client.character.meseta < item.price() as u32 {
return Err(ShipError::ShopError)
return Err(ShipError::ShopError.into())
}
client.character.meseta -= item.price() as u32;

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

@ -15,7 +15,7 @@ pub fn block_selected(id: ClientId,
clients: &mut Clients,
item_manager: &ItemManager,
level_table: &CharacterLevelTable)
-> Result<Vec<SendShipPacket>, ShipError> {
-> Result<Vec<SendShipPacket>, anyhow::Error> {
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
client.block = pkt.item as u32;
@ -52,7 +52,7 @@ pub fn send_player_to_lobby(id: ClientId,
clients: &Clients,
item_manager: &ItemManager,
level_table: &CharacterLevelTable)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
let lobby = client_location.add_client_to_next_available_lobby(id, LobbyId(0)).map_err(|_| ShipError::TooManyClients)?;
let join_lobby = packet::builder::lobby::join_lobby(id, lobby, client_location, clients, item_manager, level_table)?;
let addto = packet::builder::lobby::add_to_lobby(id, lobby, client_location, clients, item_manager, level_table)?;
@ -71,7 +71,7 @@ pub async fn change_lobby<EG: EntityGateway>(id: ClientId,
level_table: &CharacterLevelTable,
ship_rooms: &mut Rooms,
entity_gateway: &mut EG)
-> Result<Vec<(ClientId, SendShipPacket)>, ShipError> {
-> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?;
let prev_area = client_location.get_area(id).map_err(|err| -> ClientLocationError {err.into()})?;
match prev_area {

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

@ -16,7 +16,7 @@ pub async fn request_exp<EG: EntityGateway>(id: ClientId,
clients: &mut Clients,
rooms: &mut Rooms,
level_table: &CharacterLevelTable)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError> {
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error> {
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
let area_client = client_location.get_local_client(id).map_err(|err| -> ClientLocationError { err.into() })?;
let room_id = client_location.get_room(id).map_err(|err| -> ClientLocationError { err.into() })?;
@ -70,7 +70,7 @@ pub async fn player_drop_item<EG>(id: ClientId,
clients: &mut Clients,
rooms: &mut Rooms,
item_manager: &mut ItemManager)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError>
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
where
EG: EntityGateway
{
@ -95,7 +95,7 @@ pub fn drop_coordinates(id: ClientId,
client_location: &ClientLocation,
clients: &mut Clients,
rooms: &Rooms)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError>
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
{
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
let room_id = client_location.get_room(id).map_err(|err| -> ClientLocationError { err.into() })?;
@ -120,7 +120,7 @@ pub async fn split_item_stack<EG>(id: ClientId,
client_location: &ClientLocation,
clients: &mut Clients,
item_manager: &mut ItemManager)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError>
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
where
EG: EntityGateway
{
@ -130,7 +130,7 @@ where
let drop_location = client.item_drop_location.ok_or(ShipError::ItemDropLocationNotSet)?;
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 {
@ -164,7 +164,7 @@ pub fn update_player_position(id: ClientId,
clients: &mut Clients,
client_location: &ClientLocation,
rooms: &Rooms)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError> {
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error> {
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
if let Ok(room_id) = client_location.get_room(id).map_err(|err| -> ClientLocationError { err.into() }) {
let room = rooms.get(room_id.0)
@ -236,7 +236,7 @@ pub async fn charge_attack<EG>(id: ClientId,
charge: &ChargeAttack,
clients: &mut Clients,
entity_gateway: &mut EG)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError>
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
where
EG: EntityGateway
{
@ -246,7 +246,7 @@ where
entity_gateway.save_character(&client.character).await?;
Ok(Box::new(None.into_iter()))
} else {
Err(ShipError::NotEnoughMeseta(id, client.character.meseta))
Err(ShipError::NotEnoughMeseta(id, client.character.meseta).into())
}
}
@ -256,7 +256,7 @@ pub async fn use_item<EG>(id: ClientId,
_client_location: &ClientLocation,
clients: &mut Clients,
item_manager: &mut ItemManager)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError>
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
where
EG: EntityGateway
{
@ -271,7 +271,7 @@ pub async fn player_used_medical_center<EG>(id: ClientId,
_pumc: &PlayerUsedMedicalCenter, // not needed?
entity_gateway: &mut EG,
clients: &mut Clients)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError>
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
where
EG: EntityGateway
{
@ -281,7 +281,7 @@ where
entity_gateway.save_character(&client.character).await?;
Ok(Box::new(None.into_iter()))
} else {
Err(ShipError::NotEnoughMeseta(id, client.character.meseta))
Err(ShipError::NotEnoughMeseta(id, client.character.meseta).into())
}
}
@ -292,7 +292,7 @@ pub async fn player_feed_mag<EG>(id: ClientId,
client_location: &ClientLocation,
clients: &Clients,
item_manager: &mut ItemManager)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError>
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
where
EG: EntityGateway
{
@ -311,7 +311,7 @@ pub async fn player_equips_item<EG>(id: ClientId,
entity_gateway: &mut EG,
clients: &Clients,
item_manager: &mut ItemManager)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError>
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
where
EG: EntityGateway
{
@ -331,7 +331,7 @@ pub async fn player_unequips_item<EG>(id: ClientId,
entity_gateway: &mut EG,
clients: &Clients,
item_manager: &mut ItemManager)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError>
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
where
EG: EntityGateway
{
@ -345,7 +345,7 @@ pub async fn player_sorts_items<EG>(id: ClientId,
entity_gateway: &mut EG,
clients: &Clients,
item_manager: &mut ItemManager)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError>
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
where
EG: EntityGateway
{

8
tests/test_item_pickup.rs

@ -218,7 +218,7 @@ async fn test_pick_up_meseta_when_inventory_full() {
ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
client: 0,
target: 0,
item_id: 0xF0000001,
item_id: 0x00810001,
map_area: 0,
unknown: [0; 3]
})))).await.unwrap().for_each(drop);
@ -590,7 +590,7 @@ async fn test_can_not_pick_up_meseta_when_full() {
let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
client: 0,
target: 0,
item_id: 0xF0000001,
item_id: 0x00810001,
map_area: 0,
unknown: [0; 3]
})))).await.unwrap().collect::<Vec<_>>();
@ -648,7 +648,7 @@ async fn test_meseta_caps_at_999999_when_trying_to_pick_up_more() {
ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
client: 0,
target: 0,
item_id: 0xF0000001,
item_id: 0x00810001,
map_area: 0,
unknown: [0; 3]
})))).await.unwrap().for_each(drop);
@ -717,7 +717,7 @@ async fn test_player_drops_partial_stack_and_other_player_picks_it_up() {
ship.handle(ClientId(2), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
client: 0,
target: 0,
item_id: 0xF0000001,
item_id: 0x00810001,
map_area: 0,
unknown: [0; 3]
})))).await.unwrap().for_each(drop);

Loading…
Cancel
Save