From 45d9b82598e4ca0c99807cc44609892ba5efde73 Mon Sep 17 00:00:00 2001 From: andy Date: Sat, 31 Oct 2020 01:25:18 -0300 Subject: [PATCH 1/7] sort items packets and dont equip multiple items in main it's confusing --- src/bin/main.rs | 4 ++-- src/ship/items/manager.rs | 34 ++++++++++++++++++++++++++++++ src/ship/packet/handler/message.rs | 20 +++++++++++++++++- src/ship/ship.rs | 4 +++- 4 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/bin/main.rs b/src/bin/main.rs index fcd99af..529fdc2 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -185,7 +185,7 @@ fn main() { location: ItemLocation::Inventory { character_id: character.id, slot: 3, - equipped: true, + equipped: false, } }).await.unwrap(); entity_gateway.create_item( @@ -205,7 +205,7 @@ fn main() { location: ItemLocation::Inventory { character_id: character.id, slot: 4, - equipped: true, + equipped: false, } }).await.unwrap(); diff --git a/src/ship/items/manager.rs b/src/ship/items/manager.rs index b037f59..5e5bd0c 100644 --- a/src/ship/items/manager.rs +++ b/src/ship/items/manager.rs @@ -979,4 +979,38 @@ impl ItemManager { }).await; Ok(()) } + + pub async fn player_sorts_items(&mut self, + entity_gateway: &mut EG, + character: &CharacterEntity, + item_ids: [u32; 30]) + -> Result<(), ItemManagerError> { + let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; + let sorted_inventory_items: Vec<(usize, Option<&InventoryItem>)> = item_ids.iter() + .enumerate() + .filter(|(slot, &client_item_id)| client_item_id < 0xFFFFFFFF) + .map(|(slot, &client_item_id)| (slot, inventory.get_item_by_id(ClientItemId(client_item_id)))) + .collect(); + for (slot, item) in sorted_inventory_items { + match item.unwrap() { + InventoryItem::Individual(i) => { + entity_gateway.change_item_location(&i.entity_id, ItemLocation::Inventory { + character_id: character.id, + slot: slot, + equipped: i.equipped, + }).await + }, + InventoryItem::Stacked(s) => { + for entity_id in s.entity_ids.iter() { + entity_gateway.change_item_location(&entity_id, ItemLocation::Inventory { + character_id: character.id, + slot: slot, + equipped: false, + }).await + } + }, + }; + } + Ok(()) + } } diff --git a/src/ship/packet/handler/message.rs b/src/ship/packet/handler/message.rs index 8934b19..489c3a5 100644 --- a/src/ship/packet/handler/message.rs +++ b/src/ship/packet/handler/message.rs @@ -6,7 +6,7 @@ use crate::common::serverstate::ClientId; use crate::common::leveltable::CharacterLevelTable; use crate::ship::ship::{SendShipPacket, ShipError, Rooms, Clients, ItemDropLocation}; use crate::ship::location::{ClientLocation, ClientLocationError}; -use crate::ship::items::{ItemManager, ClientItemId}; +use crate::ship::items::{ItemManager, ClientItemId, InventoryItem}; use crate::ship::packet::builder; pub async fn request_exp(id: ClientId, @@ -356,3 +356,21 @@ where Ok(Box::new(None.into_iter())) } + +pub async fn player_sorts_items(id: ClientId, + pkt: &SortItems, + entity_gateway: &mut EG, + client_location: &ClientLocation, + clients: &Clients, + item_manager: &mut ItemManager) + -> Result + Send>, ShipError> +where + EG: EntityGateway +{ + let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?; + let room_id = client_location.get_room(id).map_err(|err| -> ClientLocationError { err.into() })?; + let clients_in_area = client_location.get_clients_in_room(room_id).map_err(|err| -> ClientLocationError { err.into() })?; + item_manager.player_sorts_items(entity_gateway, &client.character, pkt.item_ids).await?; + let sort_packet = pkt.clone(); + Ok(Box::new(None.into_iter())) // Do clients care about the order of other clients items? +} diff --git a/src/ship/ship.rs b/src/ship/ship.rs index d27c10f..53357a1 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -400,7 +400,9 @@ impl ShipServerState { GameMessage::PlayerUnequipItem(player_unequip_item) => { handler::message::player_unequips_item(id, &player_unequip_item, &mut self.entity_gateway, &mut self.clients, &mut self.item_manager).await }, - + GameMessage::SortItems(sort_items) => { + handler::message::player_sorts_items(id, sort_items, &mut self.entity_gateway, &mut self.client_location, &mut self.clients, &mut self.item_manager).await + }, _ => { let cmsg = msg.clone(); Ok(Box::new(self.client_location.get_client_neighbors(id).unwrap().into_iter() From fd1e3697fc2611b5bcd81176623100f6cc7ba472 Mon Sep 17 00:00:00 2001 From: andy Date: Sat, 31 Oct 2020 14:32:44 -0300 Subject: [PATCH 2/7] sorting test. need to rename the test file --- tests/test_item_equip.rs | 72 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/tests/test_item_equip.rs b/tests/test_item_equip.rs index 484c161..b948684 100644 --- a/tests/test_item_equip.rs +++ b/tests/test_item_equip.rs @@ -216,3 +216,75 @@ async fn test_unequip_armor_with_units() { assert!(unit1_equipped == false); assert!(unit2_equipped == false); } + +#[async_std::test] +async fn test_sort_items() { + let mut entity_gateway = InMemoryGateway::new(); + + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + + entity_gateway.create_item( + item::NewItemEntity { + item: item::ItemDetail::Armor( + item::armor::Armor{ + armor: item::armor::ArmorType::Frame, + dfp: 0, + evp: 0, + slots: 4, + modifiers: Vec::new(), + }), + location: item::ItemLocation::Inventory { + character_id: char1.id, + slot: 0, + equipped: true, + } + }).await; + + entity_gateway.create_item( + item::NewItemEntity { + item: item::ItemDetail::Unit( + item::unit::Unit{ + unit: item::unit::UnitType::KnightPower, + modifier: None, + armor_slot: 0, + }), + location: item::ItemLocation::Inventory { + character_id: char1.id, + slot: 1, + equipped: false, + } + }).await; + + entity_gateway.create_item( + item::NewItemEntity { + item: item::ItemDetail::Unit( + item::unit::Unit{ + unit: item::unit::UnitType::KnightPower, + modifier: Some(item::unit::UnitModifier::Plus), + armor_slot: 0, + }), + location: item::ItemLocation::Inventory { + character_id: char1.id, + slot: 2, + equipped: false, + } + }).await; + + let mut ship = 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; + + ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::SortItems(SortItems { + client: 255, + target: 255, + item_ids: [0x10001u32, 0x10002, 0x10000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF], + })))).await.unwrap().for_each(drop); + + let items = entity_gateway.get_items_by_character(&char1).await; + assert!(items[2].item.item_type() == item::ItemType::Armor(item::armor::ArmorType::Frame)); +} \ No newline at end of file From 6d4f5ae8f6bc22b79676309fea1795c824e8f2f6 Mon Sep 17 00:00:00 2001 From: andy Date: Sat, 31 Oct 2020 22:26:12 -0300 Subject: [PATCH 3/7] enumerate after filtering and add test --- src/ship/items/manager.rs | 26 ++++++++++++++++++++------ src/ship/packet/handler/message.rs | 6 +----- src/ship/ship.rs | 2 +- tests/common.rs | 7 +++++++ tests/test_item_equip.rs | 14 +++++++++++++- 5 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/ship/items/manager.rs b/src/ship/items/manager.rs index 5e5bd0c..084dd19 100644 --- a/src/ship/items/manager.rs +++ b/src/ship/items/manager.rs @@ -986,13 +986,17 @@ impl ItemManager { item_ids: [u32; 30]) -> Result<(), ItemManagerError> { let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - let sorted_inventory_items: Vec<(usize, Option<&InventoryItem>)> = item_ids.iter() - .enumerate() - .filter(|(slot, &client_item_id)| client_item_id < 0xFFFFFFFF) - .map(|(slot, &client_item_id)| (slot, inventory.get_item_by_id(ClientItemId(client_item_id)))) - .collect(); + + let sorted_inventory_items: Vec<(usize, &InventoryItem)> = item_ids.iter() + .filter(|&client_item_id| *client_item_id < 0xFFFFFFFF) + .enumerate() + .map(|(slot, &client_item_id)| (slot, inventory.get_item_by_id(ClientItemId(client_item_id)).unwrap())) + .collect(); + println!("sorted_inventory_items: {:?}", sorted_inventory_items); + + // wait how is this different than update_inventory_slots() ??? for (slot, item) in sorted_inventory_items { - match item.unwrap() { + match item { InventoryItem::Individual(i) => { entity_gateway.change_item_location(&i.entity_id, ItemLocation::Inventory { character_id: character.id, @@ -1011,6 +1015,16 @@ impl ItemManager { }, }; } + + /* + let sorted_inventory_items: Vec = item_ids.iter() + .filter(|&client_item_id| *client_item_id < 0xFFFFFFFF) + .map(|&client_item_id| inventory.get_item_by_id(ClientItemId(client_item_id)).cloned().unwrap()) + .collect(); + + let sorted_inventory = CharacterInventory::new(sorted_inventory_items); + update_inventory_slots(entity_gateway, character, &sorted_inventory).await; + */ Ok(()) } } diff --git a/src/ship/packet/handler/message.rs b/src/ship/packet/handler/message.rs index 489c3a5..c1efe6b 100644 --- a/src/ship/packet/handler/message.rs +++ b/src/ship/packet/handler/message.rs @@ -360,7 +360,6 @@ where pub async fn player_sorts_items(id: ClientId, pkt: &SortItems, entity_gateway: &mut EG, - client_location: &ClientLocation, clients: &Clients, item_manager: &mut ItemManager) -> Result + Send>, ShipError> @@ -368,9 +367,6 @@ where EG: EntityGateway { let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?; - let room_id = client_location.get_room(id).map_err(|err| -> ClientLocationError { err.into() })?; - let clients_in_area = client_location.get_clients_in_room(room_id).map_err(|err| -> ClientLocationError { err.into() })?; item_manager.player_sorts_items(entity_gateway, &client.character, pkt.item_ids).await?; - let sort_packet = pkt.clone(); Ok(Box::new(None.into_iter())) // Do clients care about the order of other clients items? -} +} \ No newline at end of file diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 53357a1..610b1be 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -401,7 +401,7 @@ impl ShipServerState { handler::message::player_unequips_item(id, &player_unequip_item, &mut self.entity_gateway, &mut self.clients, &mut self.item_manager).await }, GameMessage::SortItems(sort_items) => { - handler::message::player_sorts_items(id, sort_items, &mut self.entity_gateway, &mut self.client_location, &mut self.clients, &mut self.item_manager).await + handler::message::player_sorts_items(id, sort_items, &mut self.entity_gateway, &mut self.clients, &mut self.item_manager).await }, _ => { let cmsg = msg.clone(); diff --git a/tests/common.rs b/tests/common.rs index 7e7c925..6c8d24b 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -80,3 +80,10 @@ pub async fn join_room(ship: &mut ShipServerState, id: Cl item: room_id, })).await.unwrap().for_each(drop); } + +pub async fn change_lobby(ship: &mut ShipServerState, id: ClientId, lobby: u32) { + ship.handle(id, &RecvShipPacket::LobbySelect(LobbySelect{ + menu: LOBBY_MENU_ID, + lobby: lobby, + })).await.unwrap().for_each(drop); +} \ No newline at end of file diff --git a/tests/test_item_equip.rs b/tests/test_item_equip.rs index b948684..1e22d2d 100644 --- a/tests/test_item_equip.rs +++ b/tests/test_item_equip.rs @@ -277,6 +277,13 @@ async fn test_sort_items() { join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; + let old_items = entity_gateway.get_items_by_character(&char1).await; + assert!(old_items[0].location == item::ItemLocation::Inventory{ + character_id: char1.id, + slot: 0, + equipped: true, + }); + ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::SortItems(SortItems { client: 255, target: 255, @@ -286,5 +293,10 @@ async fn test_sort_items() { })))).await.unwrap().for_each(drop); let items = entity_gateway.get_items_by_character(&char1).await; - assert!(items[2].item.item_type() == item::ItemType::Armor(item::armor::ArmorType::Frame)); + assert!(items[0].item.item_type() == item::ItemType::Armor(item::armor::ArmorType::Frame)); + assert!(items[0].location == item::ItemLocation::Inventory{ + character_id: char1.id, + slot: 2, + equipped: true, + }); } \ No newline at end of file From 51240a31e327bb612c3175e61a21e26dab08e844 Mon Sep 17 00:00:00 2001 From: andy Date: Sat, 31 Oct 2020 23:02:41 -0300 Subject: [PATCH 4/7] rename test file --- src/ship/items/manager.rs | 32 ------------------- ...est_item_equip.rs => test_item_actions.rs} | 1 + 2 files changed, 1 insertion(+), 32 deletions(-) rename tests/{test_item_equip.rs => test_item_actions.rs} (98%) diff --git a/src/ship/items/manager.rs b/src/ship/items/manager.rs index 084dd19..dcf9c86 100644 --- a/src/ship/items/manager.rs +++ b/src/ship/items/manager.rs @@ -986,37 +986,6 @@ impl ItemManager { item_ids: [u32; 30]) -> Result<(), ItemManagerError> { let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; - - let sorted_inventory_items: Vec<(usize, &InventoryItem)> = item_ids.iter() - .filter(|&client_item_id| *client_item_id < 0xFFFFFFFF) - .enumerate() - .map(|(slot, &client_item_id)| (slot, inventory.get_item_by_id(ClientItemId(client_item_id)).unwrap())) - .collect(); - println!("sorted_inventory_items: {:?}", sorted_inventory_items); - - // wait how is this different than update_inventory_slots() ??? - for (slot, item) in sorted_inventory_items { - match item { - InventoryItem::Individual(i) => { - entity_gateway.change_item_location(&i.entity_id, ItemLocation::Inventory { - character_id: character.id, - slot: slot, - equipped: i.equipped, - }).await - }, - InventoryItem::Stacked(s) => { - for entity_id in s.entity_ids.iter() { - entity_gateway.change_item_location(&entity_id, ItemLocation::Inventory { - character_id: character.id, - slot: slot, - equipped: false, - }).await - } - }, - }; - } - - /* let sorted_inventory_items: Vec = item_ids.iter() .filter(|&client_item_id| *client_item_id < 0xFFFFFFFF) .map(|&client_item_id| inventory.get_item_by_id(ClientItemId(client_item_id)).cloned().unwrap()) @@ -1024,7 +993,6 @@ impl ItemManager { let sorted_inventory = CharacterInventory::new(sorted_inventory_items); update_inventory_slots(entity_gateway, character, &sorted_inventory).await; - */ Ok(()) } } diff --git a/tests/test_item_equip.rs b/tests/test_item_actions.rs similarity index 98% rename from tests/test_item_equip.rs rename to tests/test_item_actions.rs index 1e22d2d..ae57d52 100644 --- a/tests/test_item_equip.rs +++ b/tests/test_item_actions.rs @@ -278,6 +278,7 @@ async fn test_sort_items() { create_room(&mut ship, ClientId(1), "room", "").await; let old_items = entity_gateway.get_items_by_character(&char1).await; + assert!(old_items[0].item.item_type() == item::ItemType::Armor(item::armor::ArmorType::Frame)); assert!(old_items[0].location == item::ItemLocation::Inventory{ character_id: char1.id, slot: 0, From ead1752978e332faeddda6b2c1abdbe7e9a1c369 Mon Sep 17 00:00:00 2001 From: andy Date: Sat, 31 Oct 2020 23:14:15 -0300 Subject: [PATCH 5/7] rebase and remove unneeded function --- tests/common.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/common.rs b/tests/common.rs index 6c8d24b..7e7c925 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -80,10 +80,3 @@ pub async fn join_room(ship: &mut ShipServerState, id: Cl item: room_id, })).await.unwrap().for_each(drop); } - -pub async fn change_lobby(ship: &mut ShipServerState, id: ClientId, lobby: u32) { - ship.handle(id, &RecvShipPacket::LobbySelect(LobbySelect{ - menu: LOBBY_MENU_ID, - lobby: lobby, - })).await.unwrap().for_each(drop); -} \ No newline at end of file From e08c582f17bdb7cf2a80073f5611d0ef23fac628 Mon Sep 17 00:00:00 2001 From: andy Date: Sat, 31 Oct 2020 23:53:06 -0300 Subject: [PATCH 6/7] fix test after rebase --- tests/test_item_actions.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_item_actions.rs b/tests/test_item_actions.rs index ae57d52..201f9fa 100644 --- a/tests/test_item_actions.rs +++ b/tests/test_item_actions.rs @@ -277,7 +277,7 @@ async fn test_sort_items() { join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").await; - let old_items = entity_gateway.get_items_by_character(&char1).await; + let old_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); assert!(old_items[0].item.item_type() == item::ItemType::Armor(item::armor::ArmorType::Frame)); assert!(old_items[0].location == item::ItemLocation::Inventory{ character_id: char1.id, @@ -293,7 +293,7 @@ async fn test_sort_items() { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF], })))).await.unwrap().for_each(drop); - let items = entity_gateway.get_items_by_character(&char1).await; + let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); assert!(items[0].item.item_type() == item::ItemType::Armor(item::armor::ArmorType::Frame)); assert!(items[0].location == item::ItemLocation::Inventory{ character_id: char1.id, From 34cf660cbdd850d72e11358910094036b2a80ca6 Mon Sep 17 00:00:00 2001 From: andy Date: Sun, 1 Nov 2020 19:54:50 -0400 Subject: [PATCH 7/7] dont make new inventory --- src/ship/items/inventory.rs | 4 ++++ src/ship/items/manager.rs | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ship/items/inventory.rs b/src/ship/items/inventory.rs index b4dcc58..6360037 100644 --- a/src/ship/items/inventory.rs +++ b/src/ship/items/inventory.rs @@ -631,5 +631,9 @@ impl CharacterInventory { pub fn items(&self) -> &Vec { &self.items } + + pub fn set_items(&mut self, sorted_items: Vec) { + self.items = sorted_items; + } } diff --git a/src/ship/items/manager.rs b/src/ship/items/manager.rs index dcf9c86..642ec51 100644 --- a/src/ship/items/manager.rs +++ b/src/ship/items/manager.rs @@ -988,11 +988,13 @@ impl ItemManager { let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; let sorted_inventory_items: Vec = item_ids.iter() .filter(|&client_item_id| *client_item_id < 0xFFFFFFFF) - .map(|&client_item_id| inventory.get_item_by_id(ClientItemId(client_item_id)).cloned().unwrap()) + .map(|&client_item_id| inventory.get_item_by_id(ClientItemId(client_item_id))) + .filter(|&x| x.is_some() == true) + .map(|x| x.cloned().unwrap()) .collect(); - let sorted_inventory = CharacterInventory::new(sorted_inventory_items); - update_inventory_slots(entity_gateway, character, &sorted_inventory).await; + inventory.set_items(sorted_inventory_items); + update_inventory_slots(entity_gateway, character, &inventory).await; Ok(()) } }