Skip to content

Commit

Permalink
Fixed disabled inventory items
Browse files Browse the repository at this point in the history
Items could get locked when trying to move multiple into an almost full storage.
  • Loading branch information
neon-dev committed Sep 22, 2024
1 parent 82f91b0 commit 0b80c4d
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import static com.aionemu.gameserver.services.item.ItemPacketService.*;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -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;
Expand All @@ -60,23 +58,23 @@ public static void moveItem(Player player, int itemObjId, byte sourceStorageType
}
if (slot == -1) {
if (item.getItemTemplate().isStackable()) {
List<Item> 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) {
Expand All @@ -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;
Expand All @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
};
}
}

Expand All @@ -112,7 +102,7 @@ public static enum ItemAddType {

private final int mask;

private ItemAddType(int mask) {
ItemAddType(int mask) {
this.mask = mask;
}

Expand All @@ -121,7 +111,7 @@ public int getMask() {
}
}

public static enum ItemDeleteType {
public enum ItemDeleteType {
QUEST_REWARD(0),
SPLIT(0x04),
MOVE(0x14),
Expand All @@ -136,54 +126,45 @@ public static enum ItemDeleteType {

private final int mask;

private ItemDeleteType(int mask) {
ItemDeleteType(int mask) {
this.mask = mask;
}

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 {
Expand All @@ -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));
}
Expand All @@ -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));
Expand All @@ -224,15 +203,15 @@ 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);
}

/**
* 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));
Expand All @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand All @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 0b80c4d

Please sign in to comment.