use networking::serverstate::{ClientId, ServerState}; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::item; use elseware::ship::ship::{ShipServerState, RecvShipPacket}; use libpso::packet::ship::*; use libpso::packet::messages::*; #[path = "common.rs"] mod common; use common::*; #[async_std::test] async fn test_use_monomate_after_leaving_and_rejoining_room() { let mut entity_gateway = InMemoryGateway::default(); let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; let mut p1_items = Vec::new(); for tool in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter() { let mut item = Vec::new(); for _ in 0..2usize { item.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { tool: tool } ), }).await.unwrap()); } p1_items.push(item::InventoryItemEntity::Stacked(item)); } entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_items)).await.unwrap(); let mut p2_items = Vec::new(); for tool in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter() { let mut item = Vec::new(); for _ in 0..2usize { item.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { tool: tool } ), }).await.unwrap()); } p2_items.push(item::InventoryItemEntity::Stacked(item)); } entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_items)).await.unwrap(); let mut ship = standard_ship(entity_gateway.clone()); 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; leave_room(&mut ship, ClientId(2)).await; join_room(&mut ship, ClientId(2), 0).await; leave_room(&mut ship, ClientId(2)).await; join_room(&mut ship, ClientId(2), 0).await; leave_room(&mut ship, ClientId(2)).await; join_room(&mut ship, ClientId(2), 0).await; leave_room(&mut ship, ClientId(1)).await; join_room(&mut ship, ClientId(1), 0).await; ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerUseItem(PlayerUseItem { client: 0, target: 0, item_id: 0x10003, })))).await.unwrap(); ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::PlayerUseItem(PlayerUseItem { client: 0, target: 0, item_id: 0x210006, })))).await.unwrap(); let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); assert_eq!(inventory_items.items.len(), 2); inventory_items.items[0].with_stacked(|items| { assert_eq!(items.len(), 2) }).unwrap(); inventory_items.items[1].with_stacked(|items| { assert_eq!(items.len(), 1) }).unwrap(); let inventory_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap(); assert_eq!(inventory_items.items.len(), 2); inventory_items.items[0].with_stacked(|items| { assert_eq!(items.len(), 1) }).unwrap(); inventory_items.items[1].with_stacked(|items| { assert_eq!(items.len(), 2) }).unwrap(); } #[async_std::test] async fn test_using_some_monomates_after_a_convoluted_series_of_leaves_and_joins() { let mut entity_gateway = InMemoryGateway::default(); let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; let (_user3, char3) = new_user_character(&mut entity_gateway, "a3", "a", 1).await; let mut p1_items = Vec::new(); for tool in vec![item::tool::ToolType::Monofluid, item::tool::ToolType::Difluid, item::tool::ToolType::Trifluid].into_iter() { let mut item = Vec::new(); for _ in 0..2usize { item.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { tool: tool } ), }).await.unwrap()); } p1_items.push(item::InventoryItemEntity::Stacked(item)); } entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_items)).await.unwrap(); let mut p2_items = Vec::new(); for tool in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter() { let mut item = Vec::new(); for _ in 0..6usize { item.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { tool: tool } ), }).await.unwrap()); } p2_items.push(item::InventoryItemEntity::Stacked(item)); } entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_items)).await.unwrap(); let mut p3_items = Vec::new(); for _ in 0..5usize { p3_items.push( item::InventoryItemEntity::Individual( entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { weapon: item::weapon::WeaponType::Saber, grind: 0, special: None, attrs: [None, None, None], tekked: true, } ), }).await.unwrap() )); } entity_gateway.set_character_inventory(&char3.id, &item::InventoryEntity::new(p3_items)).await.unwrap(); let mut ship = standard_ship(entity_gateway.clone()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; log_in_char(&mut ship, ClientId(3), "a3", "a").await; join_lobby(&mut ship, ClientId(1)).await; join_lobby(&mut ship, ClientId(2)).await; join_lobby(&mut ship, ClientId(3)).await; // so lets trace the item_ids here as it is dumb: create_room(&mut ship, ClientId(1), "room", "").await; // g1/p1: 0x010000 0x010001 0x010002 ; 0x010003 // g2 : ; 0x210000 // g3 : ; 0x410000 join_room(&mut ship, ClientId(2), 0).await; // g1/p1: 0x010000 0x010001 0x010002 ; 0x10003 // g2/p2: 0x210000 0x210001 ; 0x210002 // g3 : ; 0x410000 ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::PlayerUseItem(PlayerUseItem { client: 0, target: 0, item_id: 0x210000, })))).await.unwrap(); join_room(&mut ship, ClientId(3), 0).await; // g1/p1: 0x010000 0x010001 0x010002 ; 0x010003 // g2/p2: 0x210000 0x210001 ; 0x210002 // g3/p3: 0x410000 0x410001 0x410002 0x410003 0x0410004 ; 0x410005 leave_room(&mut ship, ClientId(2)).await; // g1/p1: 0x010000 0x010001 0x010002 ; 0x010003 // g2 : ; 0x210002 // g3/p3: 0x410000 0x410001 0x410002 0x410003 0x410004 ; 0x410005 join_room(&mut ship, ClientId(2), 0).await; // g1/p1: 0x010000 0x010001 0x010002 ; 0x010003 // g2/p2: 0x210002 0x210003 ; 0x210004 // g3/p3: 0x410000 0x410001 0x410002 0x410003 0x410004 ; 0x410005 leave_room(&mut ship, ClientId(2)).await; // g1/p1: 0x010000 0x010001 0x010002 ; 0x010003 // g2 : ; 0x210004 // g3/p3: 0x410000 0x410001 0x410002 0x410003 0x410004 ; 0x410005 leave_room(&mut ship, ClientId(3)).await; // g1/p1: 0x010000 0x010001 0x010002 ; 0x010003 // g2 : ; 0x210004 // g3 : ; 0x410005 join_room(&mut ship, ClientId(3), 0).await; // g1/p1: 0x010000 0x010001 0x010002 ; 0x010003 // g2/p3: 0x210004 0x210005 0x210006 0x210007 0x210008 ; 0x210009 // g3 : ; 0x410007 join_room(&mut ship, ClientId(2), 0).await; // g1/p1: 0x010000 0x010001 0x010002 ; 0x010003 // g2/p3: 0x210004 0x210005 0x210006 0x210007 0x210008 ; 0x210009 // g3/p2: 0x410005 0x410006 ; 0x410007 ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::PlayerUseItem(PlayerUseItem { client: 0, target: 0, item_id: 0x410005, })))).await.unwrap(); leave_room(&mut ship, ClientId(1)).await; leave_room(&mut ship, ClientId(2)).await; // g1 : ; 0x010003 // g2/p3: 0x210004 0x210005 0x210006 0x210007 0x210008 ; 0x210009 // g3 : ; 0x410007 join_room(&mut ship, ClientId(2), 0).await; // g1/p2: 0x010003 0x010004 ; 0x010005 // g2/p3: 0x210004 0x210005 0x210006 0x210007 0x210008 ; 0x210009 // g3 : ; 0x410007 join_room(&mut ship, ClientId(1), 0).await; // g1/p2: 0x010003 0x010004 ; 0x010005 // g2/p3: 0x210004 0x210005 0x210006 0x210007 0x210008 ; 0x210009 // g3/p1: 0x410008 0x410009 0x41000A ; 0x41000B ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::PlayerUseItem(PlayerUseItem { client: 0, target: 0, item_id: 0x010003, })))).await.unwrap(); leave_room(&mut ship, ClientId(2)).await; leave_room(&mut ship, ClientId(3)).await; join_room(&mut ship, ClientId(3), 0).await; join_room(&mut ship, ClientId(2), 0).await; // g1/p3: 0x010005 0x010006 0x010007 0x010008 0x010009 ; 0x010009 // g2/p2: 0x210009 0x21000A ; 0x21000B // g3/p1: 0x410008 0x410009 0x41000A ; 0x41000B ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::PlayerUseItem(PlayerUseItem { client: 0, target: 0, item_id: 0x210009, })))).await.unwrap(); leave_room(&mut ship, ClientId(2)).await; join_room(&mut ship, ClientId(2), 0).await; // g1/p3: 0x010005 0x010006 0x010007 0x010008 0x010009 ; 0x010009 // g2/p2: 0x21000B 0x21000C ; 0x21000D // g3/p1: 0x410008 0x410009 0x401000A ; 0x41000B ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::PlayerUseItem(PlayerUseItem { client: 0, target: 0, item_id: 0x21000B, })))).await.unwrap(); let inventory_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap(); assert_eq!(inventory_items.items.len(), 2); inventory_items.items[0].with_stacked(|items| { assert_eq!(items.len(), 1) }).unwrap(); inventory_items.items[1].with_stacked(|items| { assert_eq!(items.len(), 6) }).unwrap(); } #[async_std::test] async fn test_depositing_a_full_stack_then_withdrawing_part() { let mut entity_gateway = InMemoryGateway::default(); let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; let mut p1_items = Vec::new(); for tool in vec![item::tool::ToolType::Monofluid, item::tool::ToolType::Difluid, item::tool::ToolType::Trifluid].into_iter() { let mut item = Vec::new(); for _ in 0..5usize { item.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { tool: tool } ), }).await.unwrap()); } p1_items.push(item::InventoryItemEntity::Stacked(item)); } entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_items)).await.unwrap(); let mut monomates = Vec::new(); for _ in 0..3usize { monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { tool: item::tool::ToolType::Monomate, } ), }).await.unwrap()); } entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), &item::BankIdentifier::Character).await.unwrap(); let mut ship = standard_ship(entity_gateway.clone()); 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; ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest { client: 0, target: 0, unknown: 0, })))).await.unwrap(); ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction { client: 0, target: 0, item_id: 0x10001, action: 0, item_amount: 5, meseta_amount: 0, unknown: 0, })))).await.unwrap(); ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction { client: 0, target: 0, item_id: 0x10001, action: 1, item_amount: 3, meseta_amount: 0, unknown: 0, })))).await.unwrap(); ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerUseItem(PlayerUseItem { client: 0, target: 0, item_id: 0x20001, })))).await.unwrap(); }