diff --git a/src/ship/items/inventory.rs b/src/ship/items/inventory.rs index 5bb5c19..4aa5467 100644 --- a/src/ship/items/inventory.rs +++ b/src/ship/items/inventory.rs @@ -654,6 +654,19 @@ impl CharacterInventory { } } + pub fn add_item_with_new_item_id(&mut self, item: InventoryItem, item_id: ClientItemId) { + match item { + InventoryItem::Individual(mut individual_inventory_item) => { + individual_inventory_item.item_id = item_id; + self.add_item(InventoryItem::Individual(individual_inventory_item)); + }, + InventoryItem::Stacked(mut stacked_inventory_item) => { + stacked_inventory_item.item_id = item_id; + self.add_stacked_item(stacked_inventory_item) + } + } + } + pub fn add_individual_floor_item(&mut self, floor_item: &IndividualFloorItem) -> &InventoryItem { self.items.push(InventoryItem::Individual(IndividualInventoryItem { entity_id: floor_item.entity_id, diff --git a/src/ship/items/manager.rs b/src/ship/items/manager.rs index 3031511..ba6b562 100644 --- a/src/ship/items/manager.rs +++ b/src/ship/items/manager.rs @@ -1277,7 +1277,7 @@ impl ItemAction for TradeIndividualItem { entity_gateway.set_character_inventory(&self.src_character_id, &src_inventory.as_inventory_entity(&self.src_character_id)).await?; let dest_inventory = item_manager.character_inventory.get_mut(&self.dest_character_id).ok_or(ItemManagerError::NoCharacter(self.dest_character_id))?; - dest_inventory.add_item(inventory_item); + dest_inventory.add_item_with_new_item_id(inventory_item, self.new_item_id); entity_gateway.set_character_inventory(&self.dest_character_id, &dest_inventory.as_inventory_entity(&self.dest_character_id)).await?; Ok(()) @@ -1301,7 +1301,7 @@ impl ItemAction for TradeStackedItem { entity_gateway.set_character_inventory(&self.src_character_id, &src_inventory.as_inventory_entity(&self.src_character_id)).await?; let dest_inventory = item_manager.character_inventory.get_mut(&self.dest_character_id).ok_or(ItemManagerError::NoCharacter(self.dest_character_id))?; - dest_inventory.add_stacked_item(inventory_item); + dest_inventory.add_item_with_new_item_id(InventoryItem::Stacked(inventory_item), self.new_item_id); entity_gateway.set_character_inventory(&self.dest_character_id, &dest_inventory.as_inventory_entity(&self.dest_character_id)).await?; Ok(()) diff --git a/tests/test_trade.rs b/tests/test_trade.rs index 25d4a52..2a1d5d8 100644 --- a/tests/test_trade.rs +++ b/tests/test_trade.rs @@ -152,13 +152,13 @@ async fn test_trade_one_individual_item() { assert_eq!(p2_items.items.len(), 0); initialize_trade(&mut ship, ClientId(1), ClientId(2)).await; - + ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { client: 1, target: 0, trade: TradeRequestCommand::AddItem(0x10000, 1) })))).await.unwrap().for_each(drop); - + confirm_trade(&mut ship, ClientId(1), ClientId(2)).await; finalconfirm_trade(&mut ship, ClientId(1), ClientId(2)).await; @@ -186,7 +186,7 @@ async fn test_trade_one_individual_item() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 5); @@ -253,16 +253,16 @@ async fn test_trade_player2_to_player1() { assert_eq!(p2_items.items.len(), 1); initialize_trade(&mut ship, ClientId(1), ClientId(2)).await; - + ship.handle(ClientId(2), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { client: 1, target: 0, trade: TradeRequestCommand::AddItem(0x210000, 1) })))).await.unwrap().for_each(drop); - + confirm_trade(&mut ship, ClientId(1), ClientId(2)).await; finalconfirm_trade(&mut ship, ClientId(1), ClientId(2)).await; - + let ack = ship.handle(ClientId(1), &RecvShipPacket::ItemsToTrade(ItemsToTrade { trade_target: 1, unknown2: 0, @@ -287,7 +287,7 @@ async fn test_trade_player2_to_player1() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 5); @@ -363,7 +363,7 @@ async fn test_reverse_trade_ack_order() { confirm_trade(&mut ship, ClientId(2), ClientId(1)).await; finalconfirm_trade(&mut ship, ClientId(2), ClientId(1)).await; - + let ack = ship.handle(ClientId(2), &RecvShipPacket::ItemsToTrade(ItemsToTrade { trade_target: 0, unknown2: 0, @@ -388,7 +388,7 @@ async fn test_reverse_trade_ack_order() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 5); @@ -436,7 +436,7 @@ async fn test_trade_one_stacked_item() { .into_iter() .collect::,_>>() .unwrap(); - + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_stack])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); @@ -492,7 +492,7 @@ async fn test_trade_one_stacked_item() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 5); @@ -540,7 +540,7 @@ async fn test_trade_partial_stacked_item() { .into_iter() .collect::,_>>() .unwrap(); - + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_stack])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); @@ -597,7 +597,7 @@ async fn test_trade_partial_stacked_item() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 5); @@ -679,7 +679,7 @@ async fn test_trade_individual_both() { assert_eq!(p2_items.items.len(), 1); initialize_trade(&mut ship, ClientId(1), ClientId(2)).await; - + ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { client: 1, target: 0, @@ -691,7 +691,7 @@ async fn test_trade_individual_both() { target: 0, trade: TradeRequestCommand::AddItem(0x210000, 1) })))).await.unwrap().for_each(drop); - + confirm_trade(&mut ship, ClientId(1), ClientId(2)).await; finalconfirm_trade(&mut ship, ClientId(1), ClientId(2)).await; @@ -722,7 +722,7 @@ async fn test_trade_individual_both() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 8); @@ -894,7 +894,7 @@ async fn test_trade_stacked_both() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 8); @@ -1064,7 +1064,7 @@ async fn test_trade_partial_stack_both() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 8); @@ -1134,7 +1134,7 @@ async fn test_trade_partial_stack_both() { assert!(matches!(p2_items.items[0].with_stacked(|i| i.clone()).unwrap()[0], item::ItemEntity{item: item::ItemDetail::Tool(item::tool::Tool {tool: item::tool::ToolType::Monofluid, ..}), ..})); assert!(matches!(p2_items.items[1].with_stacked(|i| i.clone()).unwrap()[0], item::ItemEntity{item: item::ItemDetail::Tool(item::tool::Tool {tool: item::tool::ToolType::Monomate, ..}), ..})); } - + #[async_std::test] async fn test_trade_same_stacked_item_to_eachother() { let mut entity_gateway = InMemoryGateway::default(); @@ -1240,7 +1240,7 @@ async fn test_trade_same_stacked_item_to_eachother() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 8); @@ -1403,7 +1403,7 @@ async fn test_trade_stacked_when_already_have_partial_stack() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 5); @@ -1549,7 +1549,7 @@ async fn test_trade_individual_for_stacked() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 8); @@ -1753,7 +1753,7 @@ async fn test_trade_multiple_individual() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 14); @@ -2025,7 +2025,7 @@ async fn test_trade_multiple_stacked() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 14); @@ -2214,13 +2214,13 @@ async fn test_trade_not_enough_inventory_space_individual() { assert_eq!(p2_items.items.len(), 30); initialize_trade(&mut ship, ClientId(1), ClientId(2)).await; - + ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { client: 1, target: 0, trade: TradeRequestCommand::AddItem(0x10000, 1) })))).await.unwrap().for_each(drop); - + confirm_trade(&mut ship, ClientId(1), ClientId(2)).await; finalconfirm_trade(&mut ship, ClientId(1), ClientId(2)).await; @@ -2248,7 +2248,7 @@ async fn test_trade_not_enough_inventory_space_individual() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.err().unwrap(); match ack.downcast::>().unwrap() { @@ -2331,13 +2331,13 @@ async fn test_trade_not_enough_inventory_space_stacked() { assert_eq!(p2_items.items.len(), 30); initialize_trade(&mut ship, ClientId(1), ClientId(2)).await; - + ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { client: 1, target: 0, trade: TradeRequestCommand::AddItem(0x10000, 2) })))).await.unwrap().for_each(drop); - + confirm_trade(&mut ship, ClientId(1), ClientId(2)).await; finalconfirm_trade(&mut ship, ClientId(1), ClientId(2)).await; @@ -2365,7 +2365,7 @@ async fn test_trade_not_enough_inventory_space_stacked() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.err().unwrap(); match ack.downcast::>().unwrap() { @@ -2445,13 +2445,13 @@ async fn test_trade_stack_too_big() { assert_eq!(p2_items.items[0].with_stacked(|i| i.len()).unwrap(), 7); initialize_trade(&mut ship, ClientId(1), ClientId(2)).await; - + ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { client: 1, target: 0, trade: TradeRequestCommand::AddItem(0x10000, 4) })))).await.unwrap().for_each(drop); - + confirm_trade(&mut ship, ClientId(1), ClientId(2)).await; finalconfirm_trade(&mut ship, ClientId(1), ClientId(2)).await; @@ -2479,7 +2479,7 @@ async fn test_trade_stack_too_big() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.err().unwrap(); match ack.downcast::>().unwrap() { @@ -2519,13 +2519,13 @@ async fn test_trade_meseta() { join_room(&mut ship, ClientId(2), 0).await; initialize_trade(&mut ship, ClientId(1), ClientId(2)).await; - + ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { client: 1, target: 0, trade: TradeRequestCommand::AddItem(0xFFFFFF01, 23) })))).await.unwrap().for_each(drop); - + confirm_trade(&mut ship, ClientId(1), ClientId(2)).await; finalconfirm_trade(&mut ship, ClientId(1), ClientId(2)).await; @@ -2553,7 +2553,7 @@ async fn test_trade_meseta() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 5); @@ -2601,13 +2601,13 @@ async fn test_trade_too_much_meseta() { join_room(&mut ship, ClientId(2), 0).await; initialize_trade(&mut ship, ClientId(1), ClientId(2)).await; - + ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { client: 1, target: 0, trade: TradeRequestCommand::AddItem(0xFFFFFF01, 2000) })))).await.unwrap().for_each(drop); - + confirm_trade(&mut ship, ClientId(1), ClientId(2)).await; finalconfirm_trade(&mut ship, ClientId(1), ClientId(2)).await; @@ -2653,13 +2653,13 @@ async fn test_trade_invalid_amount_of_meseta() { join_room(&mut ship, ClientId(2), 0).await; initialize_trade(&mut ship, ClientId(1), ClientId(2)).await; - + ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { client: 1, target: 0, trade: TradeRequestCommand::AddItem(0xFFFFFF01, 5000) })))).await.unwrap().for_each(drop); - + confirm_trade(&mut ship, ClientId(1), ClientId(2)).await; finalconfirm_trade(&mut ship, ClientId(1), ClientId(2)).await; @@ -2705,13 +2705,13 @@ async fn test_trade_meseta_request_and_items_dont_match() { join_room(&mut ship, ClientId(2), 0).await; initialize_trade(&mut ship, ClientId(1), ClientId(2)).await; - + ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { client: 1, target: 0, trade: TradeRequestCommand::AddItem(0xFFFFFF01, 50) })))).await.unwrap().for_each(drop); - + confirm_trade(&mut ship, ClientId(1), ClientId(2)).await; finalconfirm_trade(&mut ship, ClientId(1), ClientId(2)).await; @@ -2754,7 +2754,7 @@ async fn test_player_declined_trade() { join_room(&mut ship, ClientId(2), 0).await; initialize_trade(&mut ship, ClientId(1), ClientId(2)).await; - + let ack = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { client: 1, target: 0, @@ -2807,13 +2807,13 @@ async fn test_back_out_of_trade_last_minute() { assert_eq!(p2_items.items.len(), 0); initialize_trade(&mut ship, ClientId(1), ClientId(2)).await; - + ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { client: 1, target: 0, trade: TradeRequestCommand::AddItem(0x10000, 1) })))).await.unwrap().for_each(drop); - + confirm_trade(&mut ship, ClientId(1), ClientId(2)).await; let ack = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { @@ -2824,7 +2824,7 @@ async fn test_back_out_of_trade_last_minute() { assert_eq!(ack.len(), 2); assert!(matches!(ack[0], (ClientId(2), SendShipPacket::CancelTrade(..)))); assert!(matches!(ack[1], (ClientId(1), SendShipPacket::CancelTrade(..)))); - + let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); assert_eq!(p1_items.items.len(), 1); let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap(); @@ -2903,7 +2903,7 @@ async fn test_valid_trade_when_both_inventories_are_full() { assert_eq!(p2_items.items.len(), 30); initialize_trade(&mut ship, ClientId(1), ClientId(2)).await; - + ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { client: 1, target: 0, @@ -2925,7 +2925,7 @@ async fn test_valid_trade_when_both_inventories_are_full() { target: 0, trade: TradeRequestCommand::AddItem(0x210001, 1) })))).await.unwrap().for_each(drop); - + confirm_trade(&mut ship, ClientId(1), ClientId(2)).await; finalconfirm_trade(&mut ship, ClientId(1), ClientId(2)).await; @@ -2958,7 +2958,7 @@ async fn test_valid_trade_when_both_inventories_are_full() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 14); @@ -3045,7 +3045,7 @@ async fn test_invalid_trade_when_both_inventories_are_full() { assert_eq!(p2_items.items.len(), 30); initialize_trade(&mut ship, ClientId(1), ClientId(2)).await; - + ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { client: 1, target: 0, @@ -3072,7 +3072,7 @@ async fn test_invalid_trade_when_both_inventories_are_full() { target: 0, trade: TradeRequestCommand::AddItem(0x210001, 1) })))).await.unwrap().for_each(drop); - + confirm_trade(&mut ship, ClientId(1), ClientId(2)).await; finalconfirm_trade(&mut ship, ClientId(1), ClientId(2)).await; @@ -3106,7 +3106,7 @@ async fn test_invalid_trade_when_both_inventories_are_full() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.err().unwrap(); match ack.downcast::>().unwrap() { @@ -3239,7 +3239,7 @@ async fn test_add_then_remove_individual_item() { assert_eq!(p2_items.items.len(), 0); initialize_trade(&mut ship, ClientId(1), ClientId(2)).await; - + ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { client: 1, target: 0, @@ -3255,7 +3255,7 @@ async fn test_add_then_remove_individual_item() { target: 0, trade: TradeRequestCommand::RemoveItem(0x10000, 1) })))).await.unwrap().for_each(drop); - + confirm_trade(&mut ship, ClientId(1), ClientId(2)).await; finalconfirm_trade(&mut ship, ClientId(1), ClientId(2)).await; @@ -3283,7 +3283,7 @@ async fn test_add_then_remove_individual_item() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 5); @@ -3348,7 +3348,7 @@ async fn test_add_then_remove_stacked_item() { .into_iter() .collect::,_>>() .unwrap(); - + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_stack1, p1_stack2])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); @@ -3414,7 +3414,7 @@ async fn test_add_then_remove_stacked_item() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 5); @@ -3483,7 +3483,7 @@ async fn test_add_then_remove_partial_stack() { .into_iter() .collect::,_>>() .unwrap(); - + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_stack1, p1_stack2])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); @@ -3550,7 +3550,7 @@ async fn test_add_then_remove_partial_stack() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 8); @@ -3589,7 +3589,7 @@ async fn test_add_then_remove_meseta() { join_room(&mut ship, ClientId(2), 0).await; initialize_trade(&mut ship, ClientId(1), ClientId(2)).await; - + ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { client: 1, target: 0, @@ -3600,7 +3600,7 @@ async fn test_add_then_remove_meseta() { target: 0, trade: TradeRequestCommand::RemoveItem(0xFFFFFF01, 5) })))).await.unwrap().for_each(drop); - + confirm_trade(&mut ship, ClientId(1), ClientId(2)).await; finalconfirm_trade(&mut ship, ClientId(1), ClientId(2)).await; @@ -3628,7 +3628,7 @@ async fn test_add_then_remove_meseta() { let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 0); - + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { })).await.unwrap().collect::>(); assert_eq!(ack.len(), 5); @@ -3695,13 +3695,13 @@ async fn test_items_to_trade_data_does_not_match() { assert_eq!(p2_items.items.len(), 0); initialize_trade(&mut ship, ClientId(1), ClientId(2)).await; - + ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { client: 1, target: 0, trade: TradeRequestCommand::AddItem(0x10000, 1) })))).await.unwrap().for_each(drop); - + confirm_trade(&mut ship, ClientId(1), ClientId(2)).await; finalconfirm_trade(&mut ship, ClientId(1), ClientId(2)).await; @@ -3726,7 +3726,6 @@ async fn test_items_to_trade_data_does_not_match() { count: 1, items: titems, })).await.unwrap().collect::>(); - dbg!(&ack); assert_eq!(ack.len(), 2); assert!(matches!(ack[0], (ClientId(2), SendShipPacket::CancelTrade(..)))); assert!(matches!(ack[1], (ClientId(1), SendShipPacket::CancelTrade(..)))); @@ -3779,13 +3778,13 @@ async fn test_items_to_trade_id_does_not_match() { assert_eq!(p2_items.items.len(), 0); initialize_trade(&mut ship, ClientId(1), ClientId(2)).await; - + ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { client: 1, target: 0, trade: TradeRequestCommand::AddItem(0x10000, 1) })))).await.unwrap().for_each(drop); - + confirm_trade(&mut ship, ClientId(1), ClientId(2)).await; finalconfirm_trade(&mut ship, ClientId(1), ClientId(2)).await; @@ -3831,7 +3830,7 @@ async fn test_stack_is_same_amount_in_request_and_items_to_trade() { .into_iter() .collect::,_>>() .unwrap(); - + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_stack])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); @@ -3905,7 +3904,7 @@ async fn test_stack_is_same_amount_in_request_and_items_to_trade2() { .into_iter() .collect::,_>>() .unwrap(); - + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_stack])).await.unwrap(); entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); @@ -4269,3 +4268,115 @@ async fn test_items_to_trade_count_mismatch_with_meseta() { let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap(); assert_eq!(p2_items.items.len(), 0); } + +#[async_std::test] +async fn test_dropping_item_after_trade() { + let mut entity_gateway = InMemoryGateway::default(); + + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; + + let mut p1_inv = Vec::new(); + p1_inv.push(entity_gateway.create_item( + item::NewItemEntity { + item: item::ItemDetail::Weapon( + item::weapon::Weapon { + weapon: item::weapon::WeaponType::Handgun, + grind: 0, + special: None, + attrs: [None, None, None], + tekked: true, + } + ), + }).await.unwrap()); + + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); + entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(Vec::::new())).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() + .gateway(entity_gateway.clone()) + .build()); + log_in_char(&mut ship, ClientId(1), "a1", "a").await; + log_in_char(&mut ship, ClientId(2), "a2", "a").await; + + join_lobby(&mut ship, ClientId(1)).await; + join_lobby(&mut ship, ClientId(2)).await; + + create_room(&mut ship, ClientId(1), "room", "").await; + join_room(&mut ship, ClientId(2), 0).await; + + let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(p1_items.items.len(), 1); + let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap(); + assert_eq!(p2_items.items.len(), 0); + + initialize_trade(&mut ship, ClientId(1), ClientId(2)).await; + + ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(1, GameMessage::TradeRequest(TradeRequest { + client: 1, + target: 0, + trade: TradeRequestCommand::AddItem(0x10000, 1) + })))).await.unwrap().for_each(drop); + + confirm_trade(&mut ship, ClientId(1), ClientId(2)).await; + finalconfirm_trade(&mut ship, ClientId(1), ClientId(2)).await; + + let titems = TradeItemBuilder::default() + .individual(&p1_items.items[0], 0x10000) + .build(); + let ack = ship.handle(ClientId(1), &RecvShipPacket::ItemsToTrade(ItemsToTrade { + trade_target: 1, + unknown2: 0, + count: 1, + items: titems, + })).await.unwrap().collect::>(); + assert_eq!(ack.len(), 0); + + let ack = ship.handle(ClientId(2), &RecvShipPacket::ItemsToTrade(ItemsToTrade { + trade_target: 0, + unknown2: 0, + count: 0, + items: Default::default(), + })).await.unwrap().collect::>(); + assert_eq!(ack.len(), 2); + assert!(matches!(ack[0], (ClientId(2), SendShipPacket::AcknowledgeTrade(AcknowledgeTrade {})))); + assert!(matches!(ack[1], (ClientId(1), SendShipPacket::AcknowledgeTrade(AcknowledgeTrade {})))); + + let ack = ship.handle(ClientId(1), &RecvShipPacket::TradeConfirmed(TradeConfirmed { + })).await.unwrap().collect::>(); + assert_eq!(ack.len(), 0); + + let ack = ship.handle(ClientId(2), &RecvShipPacket::TradeConfirmed(TradeConfirmed { + })).await.unwrap().collect::>(); + assert_eq!(ack.len(), 5); + assert!(matches!(ack[0], (ClientId(1), SendShipPacket::Message(Message { + msg: GameMessage::CreateItem(CreateItem {..}), + .. + })))); + assert!(matches!(ack[1], (ClientId(2), SendShipPacket::Message(Message { + msg: GameMessage::CreateItem(CreateItem {..}), + .. + })))); + assert!(matches!(ack[2], (ClientId(2), SendShipPacket::Message(Message { + msg: GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem {..}), + .. + })))); + assert!(matches!(ack[3], (ClientId(2), SendShipPacket::TradeSuccessful {..}))); + assert!(matches!(ack[4], (ClientId(1), SendShipPacket::TradeSuccessful {..}))); + + let ack = ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem { + client: 0, + target: 0, + unknown1: 0, + map_area: 0, + item_id: 0x810001, + x: 0.0, + y: 0.0, + z: 0.0, + })))).await.unwrap().for_each(drop); + + let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(p1_items.items.len(), 0); + let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap(); + assert_eq!(p2_items.items.len(), 0); +}