From 0b80c4d1445ba90d01c04106a2b87e1b56d1661c Mon Sep 17 00:00:00 2001 From: Neon Date: Sun, 22 Sep 2024 06:18:19 +0200 Subject: [PATCH] Fixed disabled inventory items Items could get locked when trying to move multiple into an almost full storage. --- .../services/item/ItemMoveService.java | 48 ++++----- .../services/item/ItemPacketService.java | 100 ++++++++---------- .../services/item/ItemRestrictionService.java | 10 +- .../services/item/ItemSplitService.java | 10 +- .../services/toypet/PetService.java | 8 +- 5 files changed, 79 insertions(+), 97 deletions(-) diff --git a/game-server/src/com/aionemu/gameserver/services/item/ItemMoveService.java b/game-server/src/com/aionemu/gameserver/services/item/ItemMoveService.java index 9c7cba4e8..69fd8d947 100644 --- a/game-server/src/com/aionemu/gameserver/services/item/ItemMoveService.java +++ b/game-server/src/com/aionemu/gameserver/services/item/ItemMoveService.java @@ -2,8 +2,6 @@ import static com.aionemu.gameserver.services.item.ItemPacketService.*; -import java.util.List; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,11 +43,11 @@ public static void moveItem(Player player, int itemObjId, byte sourceStorageType moveInSameStorage(sourceStorage, item, slot); return; } - if (ItemRestrictionService.isItemRestrictedTo(player, item, destinationStorageType) - || ItemRestrictionService.isItemRestrictedFrom(player, item, sourceStorageType) + if (ItemRestrictionService.isItemRestrictedTo(player, item, targetStorage.getStorageType()) + || ItemRestrictionService.isItemRestrictedFrom(player, item, sourceStorage.getStorageType()) || player.isTrading() || GameServer.isShuttingDownSoon()) { - sendStorageUpdatePacket(player, StorageType.getStorageTypeById(sourceStorageType), item, ItemAddType.ALL_SLOT); + sendItemUnlockPacket(player, item); if (GameServer.isShuttingDownSoon()) PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_MSG_DISABLE("Shutdown Progress")); return; @@ -60,23 +58,23 @@ public static void moveItem(Player player, int itemObjId, byte sourceStorageType } if (slot == -1) { if (item.getItemTemplate().isStackable()) { - List sameItems = targetStorage.getItemsByItemId(item.getItemId()); - for (Item sameItem : sameItems) { - long itemCount = item.getItemCount(); - if (itemCount == 0) { - break; + for (Item targetStack : targetStorage.getItemsByItemId(item.getItemId())) { + ItemSplitService.mergeStacks(sourceStorage, targetStorage, item, targetStack, item.getItemCount()); + if (item.getItemCount() == 0) { + return; } - // we can merge same stackable items - ItemSplitService.mergeStacks(sourceStorage, targetStorage, item, sameItem, itemCount); } } } - if (!targetStorage.isFull() && item.getItemCount() > 0) { - sourceStorage.remove(item); - sendItemDeletePacket(player, StorageType.getStorageTypeById(sourceStorageType), item, ItemDeleteType.MOVE); - item.setEquipmentSlot(slot); - targetStorage.add(item); + if (targetStorage.isFull()) { + PacketSendUtility.sendPacket(player, targetStorage.getStorageIsFullMessage()); + sendItemUnlockPacket(player, item); + return; } + sourceStorage.remove(item); + sendItemDeletePacket(player, sourceStorage.getStorageType(), item, ItemDeleteType.MOVE); + item.setEquipmentSlot(slot); + targetStorage.add(item); } private static void moveInSameStorage(IStorage storage, Item item, short slot) { @@ -98,14 +96,14 @@ public static void switchItemsInStorages(Player player, byte sourceStorageType, return; // restrictions checks - if (ItemRestrictionService.isItemRestrictedFrom(player, sourceItem, sourceStorageType) - || ItemRestrictionService.isItemRestrictedFrom(player, replaceItem, replaceStorageType) - || ItemRestrictionService.isItemRestrictedTo(player, sourceItem, replaceStorageType) - || ItemRestrictionService.isItemRestrictedTo(player, replaceItem, sourceStorageType) + if (ItemRestrictionService.isItemRestrictedFrom(player, sourceItem, sourceStorage.getStorageType()) + || ItemRestrictionService.isItemRestrictedFrom(player, replaceItem, replaceStorage.getStorageType()) + || ItemRestrictionService.isItemRestrictedTo(player, sourceItem, replaceStorage.getStorageType()) + || ItemRestrictionService.isItemRestrictedTo(player, replaceItem, sourceStorage.getStorageType()) || player.isTrading() || GameServer.isShuttingDownSoon()) { - sendStorageUpdatePacket(player, StorageType.getStorageTypeById(sourceStorageType), sourceItem, ItemAddType.ALL_SLOT); - sendStorageUpdatePacket(player, StorageType.getStorageTypeById(replaceStorageType), replaceItem, ItemAddType.ALL_SLOT); + sendItemUnlockPacket(player, sourceItem); + sendItemUnlockPacket(player, replaceItem); if (GameServer.isShuttingDownSoon()) PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_MSG_DISABLE("Shutdown Progress")); return; @@ -121,8 +119,8 @@ public static void switchItemsInStorages(Player player, byte sourceStorageType, replaceStorage.remove(replaceItem); // correct UI update order is 1)delete items 2) add items - sendItemDeletePacket(player, StorageType.getStorageTypeById(sourceStorageType), sourceItem, ItemDeleteType.MOVE); - sendItemDeletePacket(player, StorageType.getStorageTypeById(replaceStorageType), replaceItem, ItemDeleteType.MOVE); + sendItemDeletePacket(player, sourceStorage.getStorageType(), sourceItem, ItemDeleteType.MOVE); + sendItemDeletePacket(player, replaceStorage.getStorageType(), replaceItem, ItemDeleteType.MOVE); sourceStorage.add(replaceItem); replaceStorage.add(sourceItem); } diff --git a/game-server/src/com/aionemu/gameserver/services/item/ItemPacketService.java b/game-server/src/com/aionemu/gameserver/services/item/ItemPacketService.java index 89bbe9dd4..2f9ab44cd 100644 --- a/game-server/src/com/aionemu/gameserver/services/item/ItemPacketService.java +++ b/game-server/src/com/aionemu/gameserver/services/item/ItemPacketService.java @@ -1,18 +1,12 @@ package com.aionemu.gameserver.services.item; import java.util.Collections; +import java.util.Objects; import com.aionemu.gameserver.model.gameobjects.Item; import com.aionemu.gameserver.model.gameobjects.player.Player; import com.aionemu.gameserver.model.items.storage.StorageType; -import com.aionemu.gameserver.network.aion.serverpackets.SM_CUBE_UPDATE; -import com.aionemu.gameserver.network.aion.serverpackets.SM_DELETE_ITEM; -import com.aionemu.gameserver.network.aion.serverpackets.SM_DELETE_WAREHOUSE_ITEM; -import com.aionemu.gameserver.network.aion.serverpackets.SM_INVENTORY_ADD_ITEM; -import com.aionemu.gameserver.network.aion.serverpackets.SM_INVENTORY_UPDATE_ITEM; -import com.aionemu.gameserver.network.aion.serverpackets.SM_LEGION_EDIT; -import com.aionemu.gameserver.network.aion.serverpackets.SM_WAREHOUSE_ADD_ITEM; -import com.aionemu.gameserver.network.aion.serverpackets.SM_WAREHOUSE_UPDATE_ITEM; +import com.aionemu.gameserver.network.aion.serverpackets.*; import com.aionemu.gameserver.questEngine.model.QuestStatus; import com.aionemu.gameserver.utils.PacketSendUtility; @@ -30,7 +24,7 @@ */ public class ItemPacketService { - public static enum ItemUpdateType { + public enum ItemUpdateType { EQUIP_UNEQUIP(-1, false), // internal usage only CHARGE(-2, false), // internal usage only POLISH_CHARGE(-3, false), // internal usage only @@ -61,7 +55,7 @@ public static enum ItemUpdateType { private final int mask; private final boolean sendable; - private ItemUpdateType(int mask, boolean sendable) { + ItemUpdateType(int mask, boolean sendable) { this.mask = mask; this.sendable = sendable; } @@ -77,16 +71,12 @@ public boolean isSendable() { public static ItemUpdateType getKinahUpdateTypeFromAddType(ItemAddType itemAddType, boolean isIncrease) { if (!isIncrease) return ItemUpdateType.DEC_KINAH_BUY; - switch (itemAddType) { - case BUY: - return ItemUpdateType.INC_KINAH_SELL; - case ITEM_COLLECT: - return ItemUpdateType.INC_KINAH_COLLECT; - case QUEST_WORK_ITEM: - return ItemUpdateType.INC_KINAH_QUEST; - default: - return ItemUpdateType.INC_KINAH_MERGE; - } + return switch (itemAddType) { + case BUY -> ItemUpdateType.INC_KINAH_SELL; + case ITEM_COLLECT -> ItemUpdateType.INC_KINAH_COLLECT; + case QUEST_WORK_ITEM -> ItemUpdateType.INC_KINAH_QUEST; + default -> ItemUpdateType.INC_KINAH_MERGE; + }; } } @@ -112,7 +102,7 @@ public static enum ItemAddType { private final int mask; - private ItemAddType(int mask) { + ItemAddType(int mask) { this.mask = mask; } @@ -121,7 +111,7 @@ public int getMask() { } } - public static enum ItemDeleteType { + public enum ItemDeleteType { QUEST_REWARD(0), SPLIT(0x04), MOVE(0x14), @@ -136,7 +126,7 @@ public static enum ItemDeleteType { private final int mask; - private ItemDeleteType(int mask) { + ItemDeleteType(int mask) { this.mask = mask; } @@ -144,46 +134,37 @@ public int getMask() { return mask; } - public static final ItemDeleteType fromUpdateType(ItemUpdateType updateType) { - switch (updateType) { - case DEC_ITEM_SPLIT: - return SPLIT; - case DEC_ITEM_USE: - return USE; - case DEC_ITEM_SPLIT_MOVE: - return MOVE; - default: - return QUEST_REWARD; - } + public static ItemDeleteType fromUpdateType(ItemUpdateType updateType) { + return switch (updateType) { + case DEC_ITEM_SPLIT -> SPLIT; + case DEC_ITEM_USE -> USE; + case DEC_ITEM_SPLIT_MOVE -> MOVE; + default -> QUEST_REWARD; + }; } public static ItemDeleteType fromQuestStatus(QuestStatus questStatus) { - switch (questStatus) { - case START: - return QUEST_START; - case REWARD: - return QUEST_REWARD; - case COMPLETE: - return QUEST_COMPLETE; - default: - return QUEST_REWARD; - } + return switch (questStatus) { + case START -> QUEST_START; + case COMPLETE -> QUEST_COMPLETE; + default -> QUEST_REWARD; + }; } } - public static final void updateItemAfterInfoChange(Player player, Item item) { + public static void updateItemAfterInfoChange(Player player, Item item) { PacketSendUtility.sendPacket(player, new SM_INVENTORY_UPDATE_ITEM(player, item)); } - public static final void updateItemAfterInfoChange(Player player, Item item, ItemUpdateType updateType) { + public static void updateItemAfterInfoChange(Player player, Item item, ItemUpdateType updateType) { PacketSendUtility.sendPacket(player, new SM_INVENTORY_UPDATE_ITEM(player, item, updateType)); } - public static final void updateItemAfterEquip(Player player, Item item) { + public static void updateItemAfterEquip(Player player, Item item) { PacketSendUtility.sendPacket(player, new SM_INVENTORY_UPDATE_ITEM(player, item, ItemUpdateType.EQUIP_UNEQUIP)); } - public static final void sendItemPacket(Player player, StorageType storageType, Item item, ItemUpdateType updateType) { + public static void sendItemPacket(Player player, StorageType storageType, Item item, ItemUpdateType updateType) { if (item.getItemCount() <= 0 && !item.getItemTemplate().isKinah()) { sendItemDeletePacket(player, storageType, item, ItemDeleteType.fromUpdateType(updateType)); } else { @@ -194,13 +175,11 @@ public static final void sendItemPacket(Player player, StorageType storageType, /** * Item will be deleted from UI slot */ - public static final void sendItemDeletePacket(Player player, StorageType storageType, Item item, ItemDeleteType deleteType) { - switch (storageType) { - case CUBE: - PacketSendUtility.sendPacket(player, new SM_DELETE_ITEM(item.getObjectId(), deleteType)); - break; - default: - PacketSendUtility.sendPacket(player, new SM_DELETE_WAREHOUSE_ITEM(storageType.getId(), item.getObjectId(), deleteType)); + public static void sendItemDeletePacket(Player player, StorageType storageType, Item item, ItemDeleteType deleteType) { + if (Objects.requireNonNull(storageType) == StorageType.CUBE) { + PacketSendUtility.sendPacket(player, new SM_DELETE_ITEM(item.getObjectId(), deleteType)); + } else { + PacketSendUtility.sendPacket(player, new SM_DELETE_WAREHOUSE_ITEM(storageType.getId(), item.getObjectId(), deleteType)); } PacketSendUtility.sendPacket(player, SM_CUBE_UPDATE.cubeSize(storageType, player)); } @@ -209,7 +188,7 @@ public static final void sendItemDeletePacket(Player player, StorageType storage * Item will be updated in UI slot (stacked items) */ @SuppressWarnings("fallthrough") - public static final void sendItemUpdatePacket(Player player, StorageType storageType, Item item, ItemUpdateType updateType) { + public static void sendItemUpdatePacket(Player player, StorageType storageType, Item item, ItemUpdateType updateType) { switch (storageType) { case CUBE: PacketSendUtility.sendPacket(player, new SM_INVENTORY_UPDATE_ITEM(player, item, updateType)); @@ -224,7 +203,7 @@ public static final void sendItemUpdatePacket(Player player, StorageType storage } } - public static final void sendStorageUpdatePacket(Player player, StorageType storageType, Item item) { + public static void sendStorageUpdatePacket(Player player, StorageType storageType, Item item) { sendStorageUpdatePacket(player, storageType, item, ItemAddType.ITEM_COLLECT); } @@ -232,7 +211,7 @@ public static final void sendStorageUpdatePacket(Player player, StorageType stor * New item will be displayed in storage */ @SuppressWarnings("fallthrough") - public static final void sendStorageUpdatePacket(Player player, StorageType storageType, Item item, ItemAddType addType) { + public static void sendStorageUpdatePacket(Player player, StorageType storageType, Item item, ItemAddType addType) { switch (storageType) { case CUBE: PacketSendUtility.sendPacket(player, new SM_INVENTORY_ADD_ITEM(Collections.singletonList(item), player, addType)); @@ -248,4 +227,9 @@ public static final void sendStorageUpdatePacket(Player player, StorageType stor PacketSendUtility.sendPacket(player, SM_CUBE_UPDATE.cubeSize(storageType, player)); } + public static void sendItemUnlockPacket(Player player, Item item) { + StorageType storageType = StorageType.getStorageTypeById(item.getItemLocation()); + if (storageType != null) + sendStorageUpdatePacket(player, storageType, item, ItemAddType.ALL_SLOT); + } } diff --git a/game-server/src/com/aionemu/gameserver/services/item/ItemRestrictionService.java b/game-server/src/com/aionemu/gameserver/services/item/ItemRestrictionService.java index 13abdd00a..ee87e48b1 100644 --- a/game-server/src/com/aionemu/gameserver/services/item/ItemRestrictionService.java +++ b/game-server/src/com/aionemu/gameserver/services/item/ItemRestrictionService.java @@ -19,9 +19,8 @@ public class ItemRestrictionService { /** * Check if item can be moved from storage by player */ - public static boolean isItemRestrictedFrom(Player player, Item item, byte storage) { - StorageType type = StorageType.getStorageTypeById(storage); - switch (type) { + public static boolean isItemRestrictedFrom(Player player, Item item, StorageType storageType) { + switch (storageType) { case LEGION_WAREHOUSE: if (!LegionService.getInstance().getLegionMember(player.getObjectId()).hasRights(LegionPermissionsMask.WH_WITHDRAWAL) || !LegionConfig.LEGION_WAREHOUSE || !player.isLegionMember()) { @@ -37,9 +36,8 @@ public static boolean isItemRestrictedFrom(Player player, Item item, byte storag /** * Check if item can be moved to storage by player */ - public static boolean isItemRestrictedTo(Player player, Item item, byte storage) { - StorageType type = StorageType.getStorageTypeById(storage); - switch (type) { + public static boolean isItemRestrictedTo(Player player, Item item, StorageType storageType) { + switch (storageType) { case REGULAR_WAREHOUSE: if (!item.isStorableInWarehouse()) { // You cannot store this in the warehouse. diff --git a/game-server/src/com/aionemu/gameserver/services/item/ItemSplitService.java b/game-server/src/com/aionemu/gameserver/services/item/ItemSplitService.java index c33eafbed..6e00e8c4b 100644 --- a/game-server/src/com/aionemu/gameserver/services/item/ItemSplitService.java +++ b/game-server/src/com/aionemu/gameserver/services/item/ItemSplitService.java @@ -26,7 +26,7 @@ public class ItemSplitService { /** * Move part of stack into different slot */ - public static final void splitItem(Player player, int itemObjId, int destinationObjId, long splitAmount, short slotNum, byte sourceStorageType, + public static void splitItem(Player player, int itemObjId, int destinationObjId, long splitAmount, short slotNum, byte sourceStorageType, byte destinationStorageType) { if (splitAmount <= 0) { return; @@ -55,9 +55,9 @@ public static final void splitItem(Player player, int itemObjId, int destination } if (sourceStorageType != destinationStorageType - && (ItemRestrictionService.isItemRestrictedTo(player, sourceItem, destinationStorageType) || ItemRestrictionService.isItemRestrictedFrom( - player, sourceItem, sourceStorageType))) { - sendStorageUpdatePacket(player, StorageType.getStorageTypeById(sourceStorageType), sourceItem); + && (ItemRestrictionService.isItemRestrictedTo(player, sourceItem, destStorage.getStorageType()) || ItemRestrictionService.isItemRestrictedFrom( + player, sourceItem, sourceStorage.getStorageType()))) { + sendStorageUpdatePacket(player, sourceStorage.getStorageType(), sourceItem); return; } @@ -140,7 +140,7 @@ private static void moveKinah(Player player, IStorage source, long splitAmount) } } - private static final void updateKinahCount(IStorage source, long splitAmount, IStorage destination) { + private static void updateKinahCount(IStorage source, long splitAmount, IStorage destination) { source.decreaseKinah(splitAmount, ItemUpdateType.DEC_ITEM_SPLIT); destination.increaseKinah(splitAmount, ItemUpdateType.INC_KINAH_MERGE); } diff --git a/game-server/src/com/aionemu/gameserver/services/toypet/PetService.java b/game-server/src/com/aionemu/gameserver/services/toypet/PetService.java index 59f97e484..594d19004 100644 --- a/game-server/src/com/aionemu/gameserver/services/toypet/PetService.java +++ b/game-server/src/com/aionemu/gameserver/services/toypet/PetService.java @@ -1,7 +1,6 @@ package com.aionemu.gameserver.services.toypet; import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; @@ -21,7 +20,10 @@ import com.aionemu.gameserver.model.templates.item.actions.SkillUseAction; import com.aionemu.gameserver.model.templates.pet.*; import com.aionemu.gameserver.model.trade.TradeList; -import com.aionemu.gameserver.network.aion.serverpackets.*; +import com.aionemu.gameserver.network.aion.serverpackets.SM_EMOTION; +import com.aionemu.gameserver.network.aion.serverpackets.SM_ITEM_USAGE_ANIMATION; +import com.aionemu.gameserver.network.aion.serverpackets.SM_PET; +import com.aionemu.gameserver.network.aion.serverpackets.SM_SYSTEM_MESSAGE; import com.aionemu.gameserver.services.TradeService; import com.aionemu.gameserver.services.item.ItemPacketService; import com.aionemu.gameserver.services.item.ItemPacketService.ItemUpdateType; @@ -98,7 +100,7 @@ private void checkFeeding(Pet pet, Player player, Item item, int count) { if (foodType == null) { // non eatable item - PacketSendUtility.sendPacket(player, new SM_INVENTORY_ADD_ITEM(Collections.singletonList(item), player, ItemPacketService.ItemAddType.ALL_SLOT)); + ItemPacketService.sendItemUnlockPacket(player, item); PacketSendUtility.sendPacket(player, new SM_PET(5, 0, 0, pet)); PacketSendUtility.sendPacket(player, new SM_EMOTION(player, EmotionType.END_FEEDING, 0, player.getObjectId())); PacketSendUtility.sendPacket(player,