From f7c6be48b2d4b1bae4cf49d558b67c8a1611b2e7 Mon Sep 17 00:00:00 2001 From: jake Date: Fri, 13 Nov 2020 19:04:09 -0700 Subject: [PATCH] don't try and say an item was picked up that the client doesn't know about --- src/ship/items/manager.rs | 13 ++++++++---- src/ship/packet/handler/direct_message.rs | 25 +++++++++++++++-------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/ship/items/manager.rs b/src/ship/items/manager.rs index 9bb4970..b0d4a12 100644 --- a/src/ship/items/manager.rs +++ b/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, @@ -164,7 +169,7 @@ 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) @@ -205,14 +210,14 @@ 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), ItemManagerError> { 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)) } diff --git a/src/ship/packet/handler/direct_message.rs b/src/ship/packet/handler/direct_message.rs index 1b53b26..f5ec259 100644 --- a/src/ship/packet/handler/direct_message.rs +++ b/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; @@ -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 + 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);