diff --git a/src/ship/items/manager.rs b/src/ship/items/manager.rs index 78b2749..ac8420d 100644 --- a/src/ship/items/manager.rs +++ b/src/ship/items/manager.rs @@ -900,29 +900,35 @@ impl ItemManager { item_id: ClientItemId, amount: usize) -> Result<(), anyhow::Error> { + let character_meseta = self.get_character_meseta(&character.id)?.0; let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; let sold_item_handle = inventory.get_item_handle_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?; if let Some(item_sold) = sold_item_handle.item() { let unit_price = item_sold.get_sell_price()?; { let total_sale = unit_price * amount as u32; - match item_sold { - InventoryItem::Individual(i) => { - entity_gateway.add_item_note(&i.entity_id, ItemNote::SoldToShop).await?; - inventory.remove_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?; - }, - InventoryItem::Stacked(s) => { - match amount.cmp(&s.count()) { - Ordering::Less | Ordering::Equal => { - sold_item_handle.consume(amount)?; - }, - Ordering::Greater => return Err(ItemManagerError::InvalidSale.into()), - }; - }, + if character_meseta + total_sale <= 999999 { + match item_sold { + InventoryItem::Individual(i) => { + entity_gateway.add_item_note(&i.entity_id, ItemNote::SoldToShop).await?; + inventory.remove_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?; + }, + InventoryItem::Stacked(s) => { + match amount.cmp(&s.count()) { + Ordering::Less | Ordering::Equal => { + sold_item_handle.consume(amount)?; + }, + Ordering::Greater => return Err(ItemManagerError::InvalidSale.into()), + }; + }, + } + entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; + let character_meseta = self.get_character_meseta_mut(&character.id)?; + character_meseta.0 += total_sale; + entity_gateway.set_character_meseta(&character.id, *character_meseta).await?; + } + else { + return Err(ItemManagerError::WalletFull.into()) } - entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; - let character_meseta = self.get_character_meseta_mut(&character.id)?; - character_meseta.0 += total_sale; - entity_gateway.set_character_meseta(&character.id, *character_meseta).await?; } } else { return Err(ItemManagerError::ItemIdNotInInventory(item_id).into()) diff --git a/src/ship/items/mod.rs b/src/ship/items/mod.rs index 0d76eb3..8a917a8 100644 --- a/src/ship/items/mod.rs +++ b/src/ship/items/mod.rs @@ -1,7 +1,7 @@ mod bank; mod floor; pub mod inventory; -mod manager; +pub mod manager; pub mod transaction; pub mod use_tool; use serde::{Serialize, Deserialize}; diff --git a/tests/test_shops.rs b/tests/test_shops.rs index 987f43c..27d7f06 100644 --- a/tests/test_shops.rs +++ b/tests/test_shops.rs @@ -3,6 +3,7 @@ use elseware::entity::gateway::{EntityGateway, InMemoryGateway}; use elseware::entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket}; use elseware::ship::room::Difficulty; +use elseware::ship::items::manager::ItemManagerError; use libpso::packet::ship::*; use libpso::packet::messages::*; @@ -1105,3 +1106,44 @@ async fn test_player_sells_rare_unit() { let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap(); assert_eq!(c1_meseta.0, 10); } + +#[async_std::test] +async fn test_player_cant_sell_if_meseta_would_go_over_max() { + let mut entity_gateway = InMemoryGateway::default(); + + let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + entity_gateway.set_character_meseta(&char1.id, item::Meseta(999995)).await.unwrap(); + + let mut p1_inv = Vec::new(); + + p1_inv.push(entity_gateway.create_item( + item::NewItemEntity { + item: item::ItemDetail::Unit( + item::unit::Unit { + unit: item::unit::UnitType::V101, + modifier: None, + } + ), + }).await.unwrap()); + + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() + .gateway(entity_gateway.clone()) + .build()); + + log_in_char(&mut ship, ClientId(1), "a1", "a").await; + join_lobby(&mut ship, ClientId(1)).await; + create_room(&mut ship, ClientId(1), "room", "").await; + + let ack = ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSoldItem(PlayerSoldItem { + client: 0, + target: 0, + item_id: 0x10000, + amount: 1, + })))).await.err().unwrap(); + assert!(matches!(ack.downcast::().unwrap(), ItemManagerError::WalletFull)); + + let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap(); + assert_eq!(c1_meseta.0, 999995); +}