package server; import client.MapleBuffStat; import client.MapleCharacter; import client.MapleClient; import client.MapleQuestStatus; import client.PlayerStats; import client.SkillEntry; import client.SkillFactory; import client.inventory.Equip; import client.inventory.InventoryException; import client.inventory.Item; import client.inventory.ItemFlag; import client.inventory.MapleEquipOnlyId; import client.inventory.MapleInventoryIdentifier; import client.inventory.MapleInventoryType; import client.inventory.MaplePet; import client.inventory.ModifyInventory; import constants.GameConstants; import constants.ItemConstants; import handling.world.WorldBroadcastService; import java.awt.Point; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import server.cashshop.CashItemFactory; import server.cashshop.CashItemInfo; import server.quest.MapleQuest; import tools.FileoutputUtil; import tools.MaplePacketCreator; import tools.packet.InventoryPacket; import tools.packet.MTSCSPacket; public class MapleInventoryManipulator { private static final Logger log = Logger.getLogger(MapleInventoryManipulator.class); public static void addRing(MapleCharacter chr, int itemId, int ringId, int sn) { CashItemInfo csi = CashItemFactory.getInstance().getItem(sn); if (csi == null) { return; } Item ring = chr.getCashInventory().toItem(csi, ringId); if ((ring == null) || (ring.getUniqueId() != ringId) || (ring.getUniqueId() <= 0) || (ring.getItemId() != itemId)) { return; } chr.getCashInventory().addToInventory(ring); chr.getClient().getSession().write(MTSCSPacket.购买商城道具(ring, sn, chr.getClient().getAccID())); } public static boolean addbyItem(MapleClient c, Item item) { return addbyItem(c, item, false) >= 0; } public static short addbyItem(MapleClient c, Item item, boolean fromcs) { MapleInventoryType type = ItemConstants.getInventoryType(item.getItemId()); short newSlot = c.getPlayer().getInventory(type).addItem(item); if (newSlot == -1) { if (!fromcs) { c.getSession().write(InventoryPacket.getInventoryFull()); c.getSession().write(InventoryPacket.getShowInventoryFull()); } return newSlot; } if (item.hasSetOnlyId()) { item.setEquipOnlyId(MapleEquipOnlyId.getInstance().getNextEquipOnlyId()); } c.getSession().write(InventoryPacket.addItemToInventory(item)); c.getPlayer().havePartyQuest(item.getItemId()); if ((!fromcs) && (type.equals(MapleInventoryType.EQUIP))) { c.getPlayer().checkCopyItems(); } return newSlot; } public static int getUniqueId(int itemId, MaplePet pet) { int uniqueid = -1; if (ItemConstants.isPet(itemId)) { if (pet != null) { uniqueid = pet.getUniqueId(); } else { uniqueid = MapleInventoryIdentifier.getInstance(); } } else if ((ItemConstants.getInventoryType(itemId) == MapleInventoryType.CASH) || (MapleItemInformationProvider.getInstance().isCash(itemId))) { uniqueid = MapleInventoryIdentifier.getInstance(); } return uniqueid; } public static boolean addById(MapleClient c, int itemId, short quantity, String gmLog) { return addById(c, itemId, quantity, null, null, 0L, 0, gmLog); } public static boolean addById(MapleClient c, int itemId, short quantity, int state, String gmLog) { return addById(c, itemId, quantity, null, null, 0L, state, gmLog); } public static boolean addById(MapleClient c, int itemId, short quantity, long period, String gmLog) { return addById(c, itemId, quantity, null, null, period, 0, gmLog); } public static boolean addById(MapleClient c, int itemId, short quantity, long period, int state, String gmLog) { return addById(c, itemId, quantity, null, null, period, state, gmLog); } public static boolean addById(MapleClient c, int itemId, short quantity, String owner, String gmLog) { return addById(c, itemId, quantity, owner, null, 0L, 0, gmLog); } public static byte addId(MapleClient c, int itemId, short quantity, String owner, String gmLog) { return addId(c, itemId, quantity, owner, null, 0L, 0, gmLog); } public static boolean addById(MapleClient c, int itemId, short quantity, String owner, MaplePet pet, String gmLog) { return addById(c, itemId, quantity, owner, pet, 0L, 0, gmLog); } public static boolean addById(MapleClient c, int itemId, short quantity, String owner, MaplePet pet, long period, String gmLog) { return addById(c, itemId, quantity, owner, pet, period, 0, gmLog); } public static boolean addById(MapleClient c, int itemId, short quantity, String owner, MaplePet pet, long period, int state, String gmLog) { return addId(c, itemId, quantity, owner, pet, period, state, gmLog) >= 0; } /** * 通过ID来添加道具 * @param c * @param itemId * @param quantity * @param owner * @param pet * @param period * @param state * @param gmLog * @return */ public static byte addId(MapleClient c, int itemId, short quantity, String owner, MaplePet pet, long period, int state, String gmLog) { MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); if (((ii.isPickupRestricted(itemId)) && (c.getPlayer().haveItem(itemId, 1, true, false))) || (!ii.itemExists(itemId))) { c.getSession().write(InventoryPacket.getInventoryFull()); c.getSession().write(InventoryPacket.showItemUnavailable()); return -1; } MapleInventoryType type = ItemConstants.getInventoryType(itemId); int uniqueid = getUniqueId(itemId, pet); short newSlot = -1; if (!type.equals(MapleInventoryType.EQUIP)) { // 非装备 short slotMax = ii.getSlotMax(itemId); List existing = c.getPlayer().getInventory(type).listById(itemId); if (!ItemConstants.isRechargable(itemId)) { // 非冲值道具 if (existing.size() > 0) { Iterator i = existing.iterator(); while ((quantity > 0) && (i.hasNext())) { Item eItem = (Item) i.next(); short oldQ = eItem.getQuantity(); if ((oldQ < slotMax) && ((eItem.getOwner().equals(owner)) || (owner == null)) && (eItem.getExpiration() == -1L)) { short newQ = (short) Math.min(oldQ + quantity, slotMax); quantity = (short) (quantity - (newQ - oldQ)); eItem.setQuantity(newQ); c.getSession().write(InventoryPacket.updateInventorySlot(type, eItem)); newSlot = eItem.getPosition(); } } } Item nItem; while (quantity > 0) { short newQ = (short) Math.min(quantity, slotMax); if (newQ != 0) { quantity = (short) (quantity - newQ); nItem = new Item(itemId, (byte) 0, newQ, (byte) 0, uniqueid); newSlot = c.getPlayer().getInventory(type).addItem(nItem); if (newSlot == -1) { c.getSession().write(InventoryPacket.getInventoryFull()); c.getSession().write(InventoryPacket.getShowInventoryFull()); return -1; } if (gmLog != null) { nItem.setGMLog(gmLog); } if (owner != null) { nItem.setOwner(owner); } if (period > 0L) { if (period < 1000L) { nItem.setExpiration(System.currentTimeMillis() + period * 24L * 60L * 60L * 1000L); } else { nItem.setExpiration(System.currentTimeMillis() + period); } } if (pet != null) { nItem.setPet(pet); pet.setInventoryPosition(newSlot); } //c.getSession().write(InventoryPacket.modifyInventory(true, Collections.singletonList(new ModifyInventory(0, nItem)))); FileoutputUtil.log("添加新道具到背包:"+nItem.getItemId()); c.getSession().write(InventoryPacket.addItemToInventory(nItem)); if ((ItemConstants.isRechargable(itemId)) && (quantity == 0)) { break; } } else { c.getPlayer().havePartyQuest(itemId); c.getSession().write(MaplePacketCreator.enableActions()); return (byte) newSlot; } } } else { Item nItem = new Item(itemId, (byte) 0, quantity, (byte) 0, uniqueid); newSlot = c.getPlayer().getInventory(type).addItem(nItem); if (newSlot == -1) { c.getSession().write(InventoryPacket.getInventoryFull()); c.getSession().write(InventoryPacket.getShowInventoryFull()); return -1; } if (period > 0L) { if (period < 1000L) { nItem.setExpiration(System.currentTimeMillis() + period * 24L * 60L * 60L * 1000L); } else { nItem.setExpiration(System.currentTimeMillis() + period); } } if (gmLog != null) { nItem.setGMLog(gmLog); } FileoutputUtil.log("添加新道具到背包2:"+nItem.getItemId()); c.getSession().write(InventoryPacket.addItemToInventory(nItem)); c.getSession().write(MaplePacketCreator.enableActions()); } } else if (quantity == 1) { // 装备 Item nEquip = ii.getEquipById(itemId, uniqueid); if (owner != null) { nEquip.setOwner(owner); } if (gmLog != null) { nEquip.setGMLog(gmLog); } if (period > 0L) { if (period < 1000L) { nEquip.setExpiration(System.currentTimeMillis() + period * 24L * 60L * 60L * 1000L); } else { nEquip.setExpiration(System.currentTimeMillis() + period); } } if (nEquip.hasSetOnlyId()) { nEquip.setEquipOnlyId(MapleEquipOnlyId.getInstance().getNextEquipOnlyId()); } newSlot = c.getPlayer().getInventory(type).addItem(nEquip); if (newSlot == -1) { c.getSession().write(InventoryPacket.getInventoryFull()); c.getSession().write(InventoryPacket.getShowInventoryFull()); return -1; } FileoutputUtil.log("添加新装备到背包1:"+nEquip.getItemId()); c.getSession().write(InventoryPacket.addItemToInventory(nEquip)); c.getPlayer().checkCopyItems(); } else { throw new InventoryException("Trying to create equip with non-one quantity"); } c.getPlayer().havePartyQuest(itemId); return (byte) newSlot; } public static Item addbyId_Gachapon(MapleClient c, int itemId, short quantity) { return addbyId_Gachapon(c, itemId, quantity, null, 0L); } public static Item addbyId_Gachapon(MapleClient c, int itemId, short quantity, String gmLog) { return addbyId_Gachapon(c, itemId, quantity, null, 0L); } public static Item addbyId_Gachapon(MapleClient c, int itemId, short quantity, String gmLog, long period) { if ((c.getPlayer().getInventory(MapleInventoryType.EQUIP).getNextFreeSlot() == -1) || (c.getPlayer().getInventory(MapleInventoryType.USE).getNextFreeSlot() == -1) || (c.getPlayer().getInventory(MapleInventoryType.ETC).getNextFreeSlot() == -1) || (c.getPlayer().getInventory(MapleInventoryType.SETUP).getNextFreeSlot() == -1)) { return null; } MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); if ((ii.isPickupRestricted(itemId) && c.getPlayer().haveItem(itemId, 1, true, false)) || !ii.itemExists(itemId)) { c.getSession().write(InventoryPacket.getInventoryFull()); c.getSession().write(InventoryPacket.showItemUnavailable()); return null; } MapleInventoryType type = ItemConstants.getInventoryType(itemId); if (!type.equals(MapleInventoryType.EQUIP)) { short slotMax = ii.getSlotMax(itemId); List existing = c.getPlayer().getInventory(type).listById(itemId); if (!ItemConstants.isRechargable(itemId)) { Item nItem = null; boolean recieved = false; if (existing.size() > 0) { Iterator i = existing.iterator(); while (quantity > 0 && i.hasNext()) { nItem = (Item) i.next(); short oldQ = nItem.getQuantity(); if (oldQ < slotMax) { recieved = true; short newQ = (short) Math.min(oldQ + quantity, slotMax); quantity = (short) (quantity - (newQ - oldQ)); nItem.setQuantity(newQ); c.getSession().write(InventoryPacket.modifyInventory(true, Collections.singletonList(new ModifyInventory(1, nItem)))); } } } while (quantity > 0) { short newQ = (short) Math.min(quantity, slotMax); if (newQ == 0) { break; } quantity = (short) (quantity - newQ); nItem = new Item(itemId, (byte) 0, newQ, (byte) 0); short newSlot = c.getPlayer().getInventory(type).addItem(nItem); if (newSlot == -1 && recieved) { return nItem; } if (newSlot == -1) { return null; } recieved = true; if (gmLog != null) { nItem.setGMLog(gmLog); } if (period > 0L) { if (period < 1000L) { nItem.setExpiration(System.currentTimeMillis() + period * 24L * 60L * 60L * 1000L); } else { nItem.setExpiration(System.currentTimeMillis() + period); } } c.getSession().write(InventoryPacket.addItemToInventory(nItem)); if ((ItemConstants.isRechargable(itemId)) && (quantity == 0)) { break; } } if (recieved) { c.getPlayer().havePartyQuest(nItem.getItemId()); return nItem; } } else { Item nItem = new Item(itemId, (byte) 0, quantity, (byte) 0); short newSlot = c.getPlayer().getInventory(type).addItem(nItem); if (newSlot == -1) { return null; } if (gmLog != null) { nItem.setGMLog(gmLog); } if (period > 0L) { if (period < 1000L) { nItem.setExpiration(System.currentTimeMillis() + period * 24L * 60L * 60L * 1000L); } else { nItem.setExpiration(System.currentTimeMillis() + period); } } c.getSession().write(InventoryPacket.addItemToInventory(nItem)); c.getPlayer().havePartyQuest(nItem.getItemId()); return nItem; } } else { if (quantity == 1) { Item nEquip = ii.randomizeStats((Equip) ii.getEquipById(itemId)); short newSlot = c.getPlayer().getInventory(type).addItem(nEquip); if (newSlot == -1) { return null; } if (gmLog != null) { nEquip.setGMLog(gmLog); } if (period > 0L) { if (period < 1000L) { nEquip.setExpiration(System.currentTimeMillis() + period * 24L * 60L * 60L * 1000L); } else { nEquip.setExpiration(System.currentTimeMillis() + period); } } if (nEquip.hasSetOnlyId()) { nEquip.setEquipOnlyId(MapleEquipOnlyId.getInstance().getNextEquipOnlyId()); } c.getSession().write(InventoryPacket.addItemToInventory(nEquip)); c.getPlayer().havePartyQuest(nEquip.getItemId()); return nEquip; } throw new InventoryException("Trying to create equip with non-one quantity"); } return null; } /** * 拾取道具 * @param c * @param item * @param show * @return */ public static boolean addFromDrop(MapleClient c, Item item, boolean show) { MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); if ((c.getPlayer() == null) || ((ii.isPickupRestricted(item.getItemId())) && (c.getPlayer().haveItem(item.getItemId(), 1, true, false))) || (!ii.itemExists(item.getItemId()))) { c.getSession().write(InventoryPacket.getInventoryFull()); c.getSession().write(InventoryPacket.showItemUnavailable()); return false; } int before = c.getPlayer().itemQuantity(item.getItemId()); short quantity = item.getQuantity(); MapleInventoryType type = ItemConstants.getInventoryType(item.getItemId()); if (!type.equals(MapleInventoryType.EQUIP)) { // 不是装备 short slotMax = ii.getSlotMax(item.getItemId()); List existing = c.getPlayer().getInventory(type).listById(item.getItemId()); if (!ItemConstants.isRechargable(item.getItemId())) { // 不是飞镖类 if (quantity <= 0) { c.getSession().write(InventoryPacket.getInventoryFull()); c.getSession().write(InventoryPacket.showItemUnavailable()); return false; } if (existing.size() > 0) { Iterator i = existing.iterator(); while ((quantity > 0) && (i.hasNext())) { Item eItem = (Item) i.next(); short oldQ = eItem.getQuantity(); if ((oldQ < slotMax) && (item.getOwner().equals(eItem.getOwner())) && (item.getExpiration() == eItem.getExpiration())) { short newQ = (short) Math.min(oldQ + quantity, slotMax); quantity = (short) (quantity - (newQ - oldQ)); eItem.setQuantity(newQ); c.getSession().write(InventoryPacket.addItemToInventory(eItem)); } } } while (quantity > 0) { short newQ = (short) Math.min(quantity, slotMax); quantity = (short) (quantity - newQ); Item nItem = new Item(item.getItemId(), (byte) 0, newQ, item.getFlag()); nItem.setExpiration(item.getExpiration()); nItem.setOwner(item.getOwner()); nItem.setPet(item.getPet()); nItem.setGMLog(item.getGMLog()); short newSlot = c.getPlayer().getInventory(type).addItem(nItem); if (newSlot == -1) { c.getSession().write(InventoryPacket.getInventoryFull()); c.getSession().write(InventoryPacket.getShowInventoryFull()); item.setQuantity((short) (quantity + newQ)); return false; } c.getSession().write(InventoryPacket.addItemToInventory(nItem)); } } else { // 飞镖 Item nItem = new Item(item.getItemId(), (byte) 0, quantity, item.getFlag()); nItem.setExpiration(item.getExpiration()); nItem.setOwner(item.getOwner()); nItem.setPet(item.getPet()); nItem.setGMLog(item.getGMLog()); short newSlot = c.getPlayer().getInventory(type).addItem(nItem); if (newSlot == -1) { c.getSession().write(InventoryPacket.getInventoryFull()); c.getSession().write(InventoryPacket.getShowInventoryFull()); return false; } c.getSession().write(InventoryPacket.addItemToInventory(nItem)); c.getSession().write(MaplePacketCreator.enableActions()); } } else if (quantity == 1) { // 装备 if (item.hasSetOnlyId()) { item.setEquipOnlyId(MapleEquipOnlyId.getInstance().getNextEquipOnlyId()); } short newSlot = c.getPlayer().getInventory(type).addItem(item); if (newSlot == -1) { c.getSession().write(InventoryPacket.getInventoryFull()); c.getSession().write(InventoryPacket.getShowInventoryFull()); return false; } c.getSession().write(InventoryPacket.addItemToInventory(item)); c.getPlayer().checkCopyItems(); } else { throw new RuntimeException(new StringBuilder().append("玩家[").append(c.getPlayer().getName()).append("] 获得装备但装备的数量不为1 装备ID: ").append(item.getItemId()).toString()); } c.getPlayer().havePartyQuest(item.getItemId()); if (show) { c.getSession().write(MaplePacketCreator.getShowItemGain(item.getItemId(), item.getQuantity())); } return true; } public static boolean addItemAndEquip(MapleClient c, int itemId, short slot) { return addItemAndEquip(c, itemId, slot, 0); } public static boolean addItemAndEquip(MapleClient c, int itemId, short slot, boolean removeItem) { return addItemAndEquip(c, itemId, slot, 0, removeItem); } public static boolean addItemAndEquip(MapleClient c, int itemId, short slot, int state) { return addItemAndEquip(c, itemId, slot, state, true); } public static boolean addItemAndEquip(MapleClient c, int itemId, short slot, int state, boolean removeItem) { return addItemAndEquip(c, itemId, slot, null, 0L, state, new StringBuilder().append("系统赠送 时间: ").append(FileoutputUtil.CurrentReadable_Date()).toString(), removeItem); } public static boolean addItemAndEquip(MapleClient c, int itemId, short slot, int state, String gmLog) { return addItemAndEquip(c, itemId, slot, null, 0L, state, gmLog, true); } public static boolean addItemAndEquip(MapleClient c, int itemId, short slot, String owner, long period, int state, String gmLog, boolean removeItem) { MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); MapleInventoryType type = ItemConstants.getInventoryType(itemId); if ((!ii.itemExists(itemId)) || (slot > 0) || (!type.equals(MapleInventoryType.EQUIP))) { c.getSession().write(MaplePacketCreator.enableActions()); return false; } Item toRemove = c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem(slot); if (toRemove != null) { if (removeItem) { removeFromSlot(c, MapleInventoryType.EQUIPPED, toRemove.getPosition(), toRemove.getQuantity(), false); } else { short nextSlot = c.getPlayer().getInventory(MapleInventoryType.EQUIP).getNextFreeSlot(); if (nextSlot > -1) { unequip(c, toRemove.getPosition(), nextSlot); } } } Item nEquip = ii.getEquipById(itemId); if (owner != null) { nEquip.setOwner(owner); } if (gmLog != null) { nEquip.setGMLog(gmLog); } if (period > 0L) { if (period < 1000L) { nEquip.setExpiration(System.currentTimeMillis() + period * 24L * 60L * 60L * 1000L); } else { nEquip.setExpiration(System.currentTimeMillis() + period); } } if (nEquip.hasSetOnlyId()) { nEquip.setEquipOnlyId(MapleEquipOnlyId.getInstance().getNextEquipOnlyId()); } nEquip.setPosition((byte)slot); c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).addFromDB(nEquip); c.getSession().write(InventoryPacket.addItemToInventory(nEquip)); return true; } public static boolean checkSpace(MapleClient c, int itemid, int quantity, String owner) { MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); if ((c.getPlayer() == null) || ((ii.isPickupRestricted(itemid)) && (c.getPlayer().haveItem(itemid, 1, true, false))) || (!ii.itemExists(itemid))) { c.getSession().write(MaplePacketCreator.enableActions()); return false; } if ((quantity <= 0) && (!ItemConstants.isRechargable(itemid))) { return false; } MapleInventoryType type = ItemConstants.getInventoryType(itemid); if ((c.getPlayer() == null) || (c.getPlayer().getInventory(type) == null)) { return false; } if (!type.equals(MapleInventoryType.EQUIP)) { short slotMax = ii.getSlotMax(itemid); List<Item> existing = c.getPlayer().getInventory(type).listById(itemid); if ((!ItemConstants.isRechargable(itemid)) && (existing.size() > 0)) { for (Item eItem : existing) { short oldQ = eItem.getQuantity(); if ((oldQ < slotMax) && (owner != null) && (owner.equals(eItem.getOwner()))) { short newQ = (short) Math.min(oldQ + quantity, slotMax); quantity -= newQ - oldQ; } if (quantity <= 0) { break; } } } int numSlotsNeeded; if ((slotMax > 0) && (!ItemConstants.isRechargable(itemid))) { numSlotsNeeded = (int) Math.ceil((double) quantity / slotMax); } else { numSlotsNeeded = 1; } return !c.getPlayer().getInventory(type).isFull(numSlotsNeeded - 1); } return !c.getPlayer().getInventory(type).isFull(); } public static boolean removeFromSlot(MapleClient c, MapleInventoryType type, short slot, short quantity, boolean fromDrop) { return removeFromSlot(c, type, slot, quantity, fromDrop, false); } public static boolean removeFromSlot(MapleClient c, MapleInventoryType type, short slot, short quantity, boolean fromDrop, boolean consume) { if ((c.getPlayer() == null) || (c.getPlayer().getInventory(type) == null)) { return false; } Item item = c.getPlayer().getInventory(type).getItem(slot); if (item != null) { if (((item.getItemId() == 5370000) || (item.getItemId() == 5370001)) && (c.getPlayer().getChalkboard() != null)) { c.getPlayer().setChalkboard(null); } boolean allowZero = (consume) && (ItemConstants.isRechargable(item.getItemId())); c.getPlayer().getInventory(type).removeItem(slot, quantity, allowZero); if ((item.getQuantity() == 0) && (!allowZero)) { c.getSession().write(InventoryPacket.clearInventoryItem(type,item.getPosition(),fromDrop)); } else { c.getSession().write(InventoryPacket.updateInventorySlot(type,item,fromDrop)); } return true; } return false; } public static boolean removeById(MapleClient c, MapleInventoryType type, int itemId, int quantity, boolean fromDrop, boolean consume) { int remremove = quantity; if ((c.getPlayer() == null) || (c.getPlayer().getInventory(type) == null)) { return false; } for (Item item : c.getPlayer().getInventory(type).listById(itemId)) { int theQ = item.getQuantity(); if ((remremove <= theQ) && (removeFromSlot(c, type, item.getPosition(), (short) remremove, fromDrop, consume))) { remremove = 0; break; } if ((remremove > theQ) && (removeFromSlot(c, type, item.getPosition(), item.getQuantity(), fromDrop, consume))) { remremove -= theQ; } } return remremove <= 0; } public static boolean removeFromSlot_Lock(MapleClient c, MapleInventoryType type, short slot, short quantity, boolean fromDrop, boolean consume) { if ((c.getPlayer() == null) || (c.getPlayer().getInventory(type) == null)) { return false; } Item item = c.getPlayer().getInventory(type).getItem(slot); if (item != null) { if ((ItemFlag.封印.check(item.getFlag())) || (ItemFlag.不可交易.check(item.getFlag()))) { return false; } return removeFromSlot(c, type, slot, quantity, fromDrop, consume); } return false; } public static boolean removeById_Lock(MapleClient c, MapleInventoryType type, int itemId) { for (Item item : c.getPlayer().getInventory(type).listById(itemId)) { if (removeFromSlot_Lock(c, type, item.getPosition(), (short) 1, false, false)) { return true; } } return false; } public static void removeAllById(MapleClient c, int itemId, boolean checkEquipped) { MapleInventoryType type = ItemConstants.getInventoryType(itemId); for (Item item : c.getPlayer().getInventory(type).listById(itemId)) { if (item != null) { removeFromSlot(c, type, item.getPosition(), item.getQuantity(), true, false); } } if (checkEquipped) { Item ii = c.getPlayer().getInventory(type).findById(itemId); if (ii != null) { c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).removeItem(ii.getPosition()); c.getPlayer().equipChanged(); } } } public static void removeAllByEquipOnlyId(MapleClient c, int equipOnlyId) { if (c.getPlayer() == null) { return; } boolean locked = false; MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); List<Item> copyEquipItems = c.getPlayer().getInventory(MapleInventoryType.EQUIP).listByEquipOnlyId(equipOnlyId); for (Item item : copyEquipItems) { if (item != null) { if (!locked) { short flag = item.getFlag(); flag = (short) (flag | ItemFlag.封印.getValue()); flag = (short) (flag | ItemFlag.不可交易.getValue()); item.setFlag(flag); item.setOwner("复制装备"); c.getPlayer().forceUpdateItem(item); c.getPlayer().dropMessage(-11, new StringBuilder().append("在背包中发现复制装备[").append(ii.getName(item.getItemId())).append("]已经将其锁定。").toString()); String msgtext = new StringBuilder().append("玩家 ").append(c.getPlayer().getName()).append(" ID: ").append(c.getPlayer().getId()).append(" (等级 ").append(c.getPlayer().getLevel()).append(") 地图: ").append(c.getPlayer().getMapId()).append(" 在玩家背包中发现复制装备[").append(ii.getName(item.getItemId())).append("]已经将其锁定。").toString(); WorldBroadcastService.getInstance().broadcastGMMessage(MaplePacketCreator.serverMessageNotice(new StringBuilder().append("[GM 信息] ").append(msgtext).toString())); FileoutputUtil.log(FileoutputUtil.复制装备, new StringBuilder().append(msgtext).append(" 道具唯一ID: ").append(item.getEquipOnlyId()).toString()); locked = true; } else { removeFromSlot(c, MapleInventoryType.EQUIP, item.getPosition(), item.getQuantity(), true, false); c.getPlayer().dropMessage(-11, new StringBuilder().append("在背包中发现复制装备[").append(ii.getName(item.getItemId())).append("]已经将其删除。").toString()); } } } List<Item> copyEquipedItems = c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).listByEquipOnlyId(equipOnlyId); for (Item item : copyEquipedItems) { if (item != null) { if (!locked) { short flag = item.getFlag(); flag = (short) (flag | ItemFlag.封印.getValue()); flag = (short) (flag | ItemFlag.不可交易.getValue()); item.setFlag(flag); item.setOwner("复制装备"); c.getPlayer().forceUpdateItem(item); c.getPlayer().dropMessage(-11, new StringBuilder().append("在穿戴中发现复制装备[").append(ii.getName(item.getItemId())).append("]已经将其锁定。").toString()); String msgtext = new StringBuilder().append("玩家 ").append(c.getPlayer().getName()).append(" ID: ").append(c.getPlayer().getId()).append(" (等级 ").append(c.getPlayer().getLevel()).append(") 地图: ").append(c.getPlayer().getMapId()).append(" 在玩家穿戴中发现复制装备[").append(ii.getName(item.getItemId())).append("]已经将其锁定。").toString(); WorldBroadcastService.getInstance().broadcastGMMessage(MaplePacketCreator.serverMessageNotice(new StringBuilder().append("[GM 信息] ").append(msgtext).toString())); FileoutputUtil.log(FileoutputUtil.复制装备, new StringBuilder().append(msgtext).append(" 道具唯一ID: ").append(item.getEquipOnlyId()).toString()); locked = true; } else { removeFromSlot(c, MapleInventoryType.EQUIPPED, item.getPosition(), item.getQuantity(), true, false); c.getPlayer().dropMessage(-11, new StringBuilder().append("在穿戴中发现复制装备[").append(ii.getName(item.getItemId())).append("]已经将其删除。").toString()); c.getPlayer().equipChanged(); } } } } public static void move(MapleClient c, MapleInventoryType type, short src, short dst) { if ((src < 0) || (dst < 0) || (src == dst) || (type == MapleInventoryType.EQUIPPED)) { return; } MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); Item source = c.getPlayer().getInventory(type).getItem(src); Item initialTarget = c.getPlayer().getInventory(type).getItem(dst); if (source == null) { c.getPlayer().dropMessage(1, "移动道具失败,找不到移动道具的信息。"); c.getSession().write(MaplePacketCreator.enableActions()); return; } boolean bag = false; boolean switchSrcDst = false; boolean bothBag = false; short eqIndicator = -1; List mods = new ArrayList(); if ((src > c.getPlayer().getInventory(type).getSlotLimit()) && (type == MapleInventoryType.ETC) && (src > 100) && (src % 100 != 0)) { if (!bag) { switchSrcDst = true; eqIndicator = 0; bag = true; } else { bothBag = true; } } short olddstQ = -1; if (initialTarget != null) { olddstQ = initialTarget.getQuantity(); } short oldsrcQ = source.getQuantity(); short slotMax = ii.getSlotMax(source.getItemId()); c.getPlayer().getInventory(type).move(src, dst, slotMax); if ((!type.equals(MapleInventoryType.EQUIP)) && (initialTarget != null) && (initialTarget.getItemId() == source.getItemId()) && (initialTarget.getOwner().equals(source.getOwner())) && (initialTarget.getExpiration() == source.getExpiration()) && (!ItemConstants.isRechargable(source.getItemId())) && (!type.equals(MapleInventoryType.CASH))) { if (olddstQ + oldsrcQ > slotMax) { mods.add(new ModifyInventory((bag) && ((switchSrcDst) || (bothBag)) ? 6 : 1, source)); mods.add(new ModifyInventory((bag) && ((switchSrcDst) || (bothBag)) ? 6 : 1, initialTarget)); } else { mods.add(new ModifyInventory((bag) && ((switchSrcDst) || (bothBag)) ? 7 : 3, source)); mods.add(new ModifyInventory((bag) && ((!switchSrcDst) || (bothBag)) ? 6 : 1, initialTarget)); } } else { mods.add(new ModifyInventory(bag ? 5 : bothBag ? 8 : 2, source, src, eqIndicator, switchSrcDst)); } c.getSession().write(InventoryPacket.modifyInventory(true, mods)); } /** * 穿装备 * @param c * @param src * @param dst */ public static void equip(MapleClient c, short src, short dst) { MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); MapleCharacter chr = c.getPlayer(); if (chr == null) { return; } PlayerStats statst = chr.getStat(); Equip source = (Equip) chr.getInventory(MapleInventoryType.EQUIP).getItem(src); if ((source == null) || (ItemConstants.isHarvesting(source.getItemId()))) { c.getSession().write(MaplePacketCreator.enableActions()); return; } if (chr.isShowPacket()) { chr.dropMessage(5, new StringBuilder().append("穿戴装备 ").append(source.getItemId()).append(" src: ").append(src).append(" dst: ").append(dst).toString()); } if (((source.getItemId() == 1003142) || (source.getItemId() == 1002140) || (source.getItemId() == 1042003) || (source.getItemId() == 1062007) || (source.getItemId() == 1322013) || (source.getItemId() == 1003824)) && (!chr.isIntern())) { chr.dropMessage(1, "无法佩带此物品"); FileoutputUtil.log(new StringBuilder().append("[作弊] 非管理员玩家: ").append(chr.getName()).append(" 非法穿戴GM装备 ").append(source.getItemId()).toString()); removeById(c, MapleInventoryType.EQUIP, source.getItemId(), 1, true, false); AutobanManager.getInstance().autoban(chr.getClient(), "非法穿戴GM装备。"); c.getSession().write(MaplePacketCreator.enableActions()); return; } if (GameConstants.isOverPoweredEquip(c, source.getItemId(), src) && !c.getPlayer().isStaff()) { c.getPlayer().dropMessage(1, "这件装备的能量看起来太过于强大,如果你觉得是系统错误请报告给管理员。"); //c.getPlayer().removeAll(source.getItemId(), false); //清除作弊装备,可能判断系统有误 c.getSession().write(MaplePacketCreator.enableActions()); return; } Map stats = ii.getEquipStats(source.getItemId()); if (stats == null) { c.getSession().write(MaplePacketCreator.enableActions()); return; } if (((dst < -5003) || ((dst >= -999) && (dst < -99))) && (!stats.containsKey("cash"))) { if (chr.isShowPacket()) { chr.dropMessage(5, new StringBuilder().append("穿戴装备 - 2 ").append(source.getItemId()).append(" dst: ").append(dst).append(" 检测1: ").append(dst <= -1200).append(" 检测2: ").append((dst >= -999) && (dst < -99)).append(" 检测3: ").append(!stats.containsKey("cash")).toString()); } c.getSession().write(MaplePacketCreator.enableActions()); return; } if ((dst <= -1300) && (dst > -1306) ) { if (chr.isShowPacket()) { chr.dropMessage(5, new StringBuilder().append("穿戴装备 - 4 ").append(source.getItemId()).append(" dst: ").append(dst).append(" 检测1: ").append((dst <= -1300) && (dst > -1306)).append(" 检测2: ").toString()); } c.getSession().write(MaplePacketCreator.enableActions()); return; } if (!ii.canEquip(stats, source.getItemId(), chr.getLevel(), chr.getJob(), chr.getFame(), statst.getTotalStr(), statst.getTotalDex(), statst.getTotalLuk(), statst.getTotalInt(), chr.getStat().levelBonus)) { c.getSession().write(MaplePacketCreator.enableActions()); return; } if ((ItemConstants.isWeapon(source.getItemId())) && (dst != -10) && (dst != -11)) { c.getSession().write(MaplePacketCreator.enableActions()); return; } if ((dst == -23) && (!GameConstants.isMountItemAvailable(source.getItemId(), chr.getJob()))) { c.getSession().write(MaplePacketCreator.enableActions()); return; } if ((dst == -118) && (source.getItemId() / 10000 != 190)) { c.getSession().write(MaplePacketCreator.enableActions()); return; } if ((dst == -119) && (source.getItemId() / 10000 != 191)) { c.getSession().write(MaplePacketCreator.enableActions()); return; } StructExclusiveEquip exclusive; List theList; if (ii.isExclusiveEquip(source.getItemId())) { exclusive = ii.getExclusiveEquipInfo(source.getItemId()); if (exclusive != null) { theList = chr.getInventory(MapleInventoryType.EQUIPPED).listIds(); for (Integer i : exclusive.itemIDs) { if (theList.contains(i)) { chr.dropMessage(1, exclusive.msg); c.getSession().write(MaplePacketCreator.enableActions()); return; } } } } short takeOff = 0; switch (dst) { case -6: { // unequip the overall Item top = chr.getInventory(MapleInventoryType.EQUIPPED).getItem((short) -5); if ((top == null) || (!ItemConstants.isOverall(top.getItemId()))) { break; } if (chr.getInventory(MapleInventoryType.EQUIP).isFull(-1)) { c.getSession().write(InventoryPacket.getInventoryFull()); return; } takeOff = dst; dst = -5; break; } case -5: { // unequip the bottom and top final Item top = chr.getInventory(MapleInventoryType.EQUIPPED).getItem((byte) -5); final Item bottom = chr.getInventory(MapleInventoryType.EQUIPPED).getItem((byte) -6); if (bottom != null && ItemConstants.isOverall(source.getItemId())) { if (chr.getInventory(MapleInventoryType.EQUIP).isFull(-2)) { c.getSession().write(InventoryPacket.getInventoryFull()); return; } if (top == null) { takeOff = dst; dst = -6; } else { unequip(c, (byte) -6, chr.getInventory(MapleInventoryType.EQUIP).getNextFreeSlot()); } } break; } case -10: { // check if weapon is two-handed Item shield = chr.getInventory(MapleInventoryType.EQUIPPED).getItem((byte) -10); Item weapon = chr.getInventory(MapleInventoryType.EQUIPPED).getItem((short) -11); if (weapon != null && ItemConstants.isTwoHanded(weapon.getItemId(), chr.getJob()) && !ItemConstants.isSpecialShield(source.getItemId())) { if (chr.getInventory(MapleInventoryType.EQUIP).isFull(-1)) { c.getSession().write(InventoryPacket.getInventoryFull()); c.getSession().write(InventoryPacket.getShowInventoryFull()); return; } if (shield == null) { takeOff = dst; dst = -11; } else { unequip(c, (byte) -11, chr.getInventory(MapleInventoryType.EQUIP).getNextFreeSlot()); } } break; } case -11: { Item weapon = chr.getInventory(MapleInventoryType.EQUIPPED).getItem((byte) -11); Item shield = chr.getInventory(MapleInventoryType.EQUIPPED).getItem((short) -10); if ((shield == null) || (!ItemConstants.isTwoHanded(source.getItemId(), chr.getJob())) || ItemConstants.isSpecialShield(shield.getItemId())) { break; } if (chr.getInventory(MapleInventoryType.EQUIP).isFull()) { c.getSession().write(InventoryPacket.getInventoryFull()); return; } if (weapon == null) { takeOff = dst; dst = -10; } else { unequip(c, (byte) -10, chr.getInventory(MapleInventoryType.EQUIP).getNextFreeSlot()); } break; } case -9: case -8: case -7: } source = (Equip) chr.getInventory(MapleInventoryType.EQUIP).getItem(src); Equip target = (Equip) chr.getInventory(MapleInventoryType.EQUIPPED).getItem(dst); if (source == null) { c.getSession().write(MaplePacketCreator.enableActions()); return; } short flag = source.getFlag(); boolean itemChanged = false; if ((stats.get("equipTradeBlock") != null || source.getItemId() / 10000 == 167) && !ItemFlag.不可交易.check(flag)) { flag = (short) (flag | ItemFlag.不可交易.getValue()); source.setFlag(flag); itemChanged = true; } chr.getInventory(MapleInventoryType.EQUIP).removeSlot(src); if (target != null) { chr.getInventory(MapleInventoryType.EQUIPPED).removeSlot(dst); } List mods = new ArrayList(); if (itemChanged) { mods.add(new ModifyInventory(3, source)); mods.add(new ModifyInventory(0, source)); } source.setPosition(takeOff == 0 ? (byte)dst : (byte)takeOff); chr.getInventory(MapleInventoryType.EQUIPPED).addFromDB(source); if (target != null) { target.setPosition((byte)src); chr.getInventory(MapleInventoryType.EQUIP).addFromDB(target); } if (ItemConstants.isWeapon(source.getItemId())) { // chr.cancelEffectFromBuffStat(MapleBuffStat.攻击加速); // chr.cancelEffectFromBuffStat(MapleBuffStat.暗器伤人); // chr.cancelEffectFromBuffStat(MapleBuffStat.无形箭弩); // chr.cancelEffectFromBuffStat(MapleBuffStat.属性攻击); } if (source.getItemId() == 1122017) { chr.startFairySchedule(true, true); } mods.add(new ModifyInventory(2, source, src)); if (takeOff != 0) { mods.add(new ModifyInventory(2, target, dst)); } //c.getSession().write(InventoryPacket.modifyInventory(true, mods)); c.getSession().write(InventoryPacket.moveInventoryItem(ItemConstants.getInventoryType(source.getItemId()),(byte)src,(byte)dst,(byte)3)); chr.equipChanged(); } /** * 脱下装备 * @param c * @param src * @param dst */ public static void unequip(MapleClient c, short src, short dst) { if (c.getPlayer() == null) { return; } Equip source = (Equip) c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem(src); Equip target = (Equip) c.getPlayer().getInventory(MapleInventoryType.EQUIP).getItem(dst); if ((dst < 0) || (source == null)) { return; } if ((target != null) && (src <= 0)) { c.getSession().write(InventoryPacket.getInventoryFull()); return; } c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).removeSlot(src); if (target != null) { c.getPlayer().getInventory(MapleInventoryType.EQUIP).removeSlot(dst); } source.setPosition((byte)dst); c.getPlayer().getInventory(MapleInventoryType.EQUIP).addFromDB(source); if (target != null) { target.setPosition((byte)src); c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).addFromDB(target); } if (ItemConstants.isWeapon(source.getItemId())) { // c.getPlayer().cancelEffectFromBuffStat(MapleBuffStat.攻击加速); // c.getPlayer().cancelEffectFromBuffStat(MapleBuffStat.暗器伤人); // c.getPlayer().cancelEffectFromBuffStat(MapleBuffStat.无形箭弩); // c.getPlayer().cancelEffectFromBuffStat(MapleBuffStat.属性攻击); }else if (source.getItemId() == 1122017) { // c.getPlayer().cancelFairySchedule(true); } //c.getSession().write(InventoryPacket.modifyInventory(true, Collections.singletonList(new ModifyInventory(2, source, src)))); c.getSession().write(InventoryPacket.moveInventoryItem(ItemConstants.getInventoryType(source.getItemId()),(byte)src,(byte)dst,(byte)4)); c.getPlayer().equipChanged(); } public static boolean drop(MapleClient c, MapleInventoryType type, short src, short quantity) { return drop(c, type, src, quantity, false); } /** * 丢弃东西 * @param c * @param type * @param src * @param quantity * @param npcInduced * @return */ public static boolean drop(MapleClient c, MapleInventoryType type, short src, short quantity, boolean npcInduced) { MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); if (src < 0) { type = MapleInventoryType.EQUIPPED; } if ((c.getPlayer() == null) || (c.getPlayer().getMap() == null)) { return false; } Item source = c.getPlayer().getInventory(type).getItem(src); if ((quantity < 0) || (source == null) || ((!npcInduced) && (ItemConstants.isPet(source.getItemId()))) || ((quantity == 0) && (!ItemConstants.isRechargable(source.getItemId())))) { c.getSession().write(MaplePacketCreator.enableActions()); return false; } if ((!npcInduced) && (source.getItemId() == 4000463)) { c.getPlayer().dropMessage(1, "该道具无法丢弃。"); c.getSession().write(MaplePacketCreator.enableActions()); return false; } short flag = source.getFlag(); if (quantity > source.getQuantity() && !ItemConstants.isRechargable(source.getItemId())) { c.getSession().write(MaplePacketCreator.enableActions()); return false; } if ((ItemFlag.封印.check(flag)) || ((quantity != 1) && (type == MapleInventoryType.EQUIP))) { c.getSession().write(MaplePacketCreator.enableActions()); return false; } Point dropPos = new Point(c.getPlayer().getPosition()); if (quantity < source.getQuantity() && !ItemConstants.isRechargable(source.getItemId())) { Item target = source.copy(); target.setQuantity(quantity); source.setQuantity((short) (source.getQuantity() - quantity)); c.getSession().write(InventoryPacket.modifyInventory(true, Collections.singletonList(new ModifyInventory(1, source,src)))); if (ItemConstants.isPet(source.getItemId()) || ItemFlag.不可交易.check(flag) || ii.isDropRestricted(target.getItemId()) || ii.isAccountShared(target.getItemId())) { if (ItemFlag.KARMA_USE.check(flag)) { target.setFlag((short) (byte) (flag - ItemFlag.KARMA_USE.getValue())); c.getPlayer().getMap().spawnItemDrop(c.getPlayer(), c.getPlayer(), target, dropPos, true, true); } else { c.getPlayer().getMap().disappearingItemDrop(c.getPlayer(), c.getPlayer(), target, dropPos); } } else { c.getPlayer().getMap().spawnItemDrop(c.getPlayer(), c.getPlayer(), target, dropPos, true, true); } } else { c.getPlayer().getInventory(type).removeSlot(src); c.getSession().write(InventoryPacket.modifyInventory(true, Collections.singletonList(new ModifyInventory(3, source,src)))); if (src < 0) { c.getPlayer().equipChanged(); } if (ItemConstants.isPet(source.getItemId()) || ItemFlag.不可交易.check(flag) || ii.isDropRestricted(source.getItemId()) || ii.isAccountShared(source.getItemId())) { if (ItemFlag.KARMA_USE.check(flag)) { source.setFlag((short) (byte) (flag - ItemFlag.KARMA_USE.getValue())); c.getPlayer().getMap().spawnItemDrop(c.getPlayer(), c.getPlayer(), source, dropPos, true, true); } else { c.getPlayer().getMap().disappearingItemDrop(c.getPlayer(), c.getPlayer(), source, dropPos); } } else { c.getPlayer().getMap().spawnItemDrop(c.getPlayer(), c.getPlayer(), source, dropPos, true, true); } } return true; } }