From ccbc29d330b79e3424f3200c97322f8f5a72921e Mon Sep 17 00:00:00 2001 From: Rogiel Date: Fri, 16 Dec 2011 14:59:12 -0200 Subject: [PATCH] Implements item destroy --- .../game/net/codec/Lineage2PacketReader.java | 9 +- .../net/packet/client/CM_ITEM_DESTROY.java | 100 ++++++++++++++++++ .../java/com/l2jserver/model/world/Item.java | 7 ++ .../service/game/item/ItemService.java | 23 ++++ .../service/game/item/ItemServiceImpl.java | 31 +++++- 5 files changed, 165 insertions(+), 5 deletions(-) create mode 100644 l2jserver2-gameserver/src/main/java/com/l2jserver/game/net/packet/client/CM_ITEM_DESTROY.java diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketReader.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketReader.java index 65f7257c1..8783b4811 100644 --- a/l2jserver2-gameserver/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketReader.java +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketReader.java @@ -29,25 +29,26 @@ import com.l2jserver.game.net.Lineage2Client; import com.l2jserver.game.net.packet.ClientPacket; import com.l2jserver.game.net.packet.client.CM_ACTION_USE; import com.l2jserver.game.net.packet.client.CM_ADMIN_COMMAND; -import com.l2jserver.game.net.packet.client.CM_CHAR_ATTACK; import com.l2jserver.game.net.packet.client.CM_AUTH_LOGIN; import com.l2jserver.game.net.packet.client.CM_BYPASS; import com.l2jserver.game.net.packet.client.CM_CHAR_ACTION; import com.l2jserver.game.net.packet.client.CM_CHAR_APPEARING; +import com.l2jserver.game.net.packet.client.CM_CHAR_ATTACK; +import com.l2jserver.game.net.packet.client.CM_CHAR_CHAT; import com.l2jserver.game.net.packet.client.CM_CHAR_CREATE; import com.l2jserver.game.net.packet.client.CM_CHAR_MOVE; import com.l2jserver.game.net.packet.client.CM_CHAR_OPEN_MAP; import com.l2jserver.game.net.packet.client.CM_CHAR_POSITION; import com.l2jserver.game.net.packet.client.CM_CHAR_REQ_INVENTORY; import com.l2jserver.game.net.packet.client.CM_CHAR_SELECT; -import com.l2jserver.game.net.packet.client.CM_CHAR_CHAT; -import com.l2jserver.game.net.packet.client.CM_ITEM_DROP; import com.l2jserver.game.net.packet.client.CM_ENTER_WORLD; import com.l2jserver.game.net.packet.client.CM_EXT_REQ_ALL_FORTRESS_INFO; import com.l2jserver.game.net.packet.client.CM_EXT_REQ_KEY_MAPPING; import com.l2jserver.game.net.packet.client.CM_EXT_REQ_MANOR_LIST; import com.l2jserver.game.net.packet.client.CM_GG_KEY; import com.l2jserver.game.net.packet.client.CM_GOTO_LOBBY; +import com.l2jserver.game.net.packet.client.CM_ITEM_DESTROY; +import com.l2jserver.game.net.packet.client.CM_ITEM_DROP; import com.l2jserver.game.net.packet.client.CM_LOGOUT; import com.l2jserver.game.net.packet.client.CM_PROTOCOL_VERSION; import com.l2jserver.game.net.packet.client.CM_REQUEST_CHAR_TEMPLATE; @@ -190,6 +191,8 @@ public class Lineage2PacketReader extends OneToOneDecoder { return CM_CHAR_ATTACK.class; case CM_ITEM_DROP.OPCODE: return CM_ITEM_DROP.class; + case CM_ITEM_DESTROY.OPCODE: + return CM_ITEM_DESTROY.class; default: logger.warn("Unknown packet for 0x{}", Integer.toHexString(opcode)); break; diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/game/net/packet/client/CM_ITEM_DESTROY.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/game/net/packet/client/CM_ITEM_DESTROY.java new file mode 100644 index 000000000..0d0a84eec --- /dev/null +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/game/net/packet/client/CM_ITEM_DESTROY.java @@ -0,0 +1,100 @@ +/* + * This file is part of l2jserver2 . + * + * l2jserver2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * l2jserver2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with l2jserver2. If not, see . + */ +package com.l2jserver.game.net.packet.client; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.google.inject.Inject; +import com.l2jserver.game.net.Lineage2Client; +import com.l2jserver.game.net.SystemMessage; +import com.l2jserver.game.net.packet.AbstractClientPacket; +import com.l2jserver.model.id.object.ItemID; +import com.l2jserver.model.id.object.provider.ItemIDProvider; +import com.l2jserver.model.world.Item; +import com.l2jserver.service.game.item.ItemService; +import com.l2jserver.service.game.item.NotEnoughItemsServiceException; + +/** + * This packet drops items on the ground. + * + * @author Rogiel + */ +public class CM_ITEM_DESTROY extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x60; + + /** + * The {@link ItemService} + */ + private final ItemService itemService; + private final ItemIDProvider itemIdProvider; + + /** + * The item ID + */ + private int objectId; + /** + * The number of items to be dropped + */ + private long count; + + /** + * @param itemService + * the item service + * @param itemIdProvider + * the item id provider + */ + @Inject + public CM_ITEM_DESTROY(ItemService itemService, + ItemIDProvider itemIdProvider) { + this.itemService = itemService; + this.itemIdProvider = itemIdProvider; + } + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + objectId = buffer.readInt(); + count = buffer.readLong(); + } + + @Override + public void process(final Lineage2Client conn) { + final ItemID id = itemIdProvider.resolveID(objectId); + final Item item = id.getObject(); + + if (item == null) { + conn.sendActionFailed(); + return; + } + if (!conn.getCharacterID().equals(item.getOwnerID())) { + conn.sendActionFailed(); + return; + } + + try { + if (itemService.destroy(item, count)) { + conn.removeInventoryItems(item); + } else { + conn.updateInventoryItems(item); + } + } catch (NotEnoughItemsServiceException e) { + conn.sendSystemMessage(SystemMessage.CANNOT_DISCARD_THIS_ITEM); + } + } +} diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/model/world/Item.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/model/world/Item.java index dfc869af8..d245a108c 100644 --- a/l2jserver2-gameserver/src/main/java/com/l2jserver/model/world/Item.java +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/model/world/Item.java @@ -149,6 +149,13 @@ public class Item extends PositionableObject { return ownerID; } + /** + * @return the owner + */ + public L2Character getOwner() { + return ownerID.getObject(); + } + /** * @param ownerID * the ownerID to set diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/item/ItemService.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/item/ItemService.java index 9da30806f..76cd3a305 100644 --- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/item/ItemService.java +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/item/ItemService.java @@ -79,6 +79,29 @@ public interface ItemService extends Service { */ Item stack(Item... items) throws NonStackableItemsServiceException; + /** + * Destroys the given item + * + * @param item + * the item to be destroyed + * @param count + * the amount of items to be destroyed + * @return true if the entire item was destroyed. + * false only if it was partially destroyed. + * @throws NotEnoughItemsServiceException + * if count is bigger than {@link Item#getCount()}. + */ + boolean destroy(Item item, long count) + throws NotEnoughItemsServiceException; + + /** + * Destroys several items + * + * @param items + * the items to be destroyed + */ + void destroy(Item... items); + /** * Picks up an dropped item and places it into another players inventory * diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/item/ItemServiceImpl.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/item/ItemServiceImpl.java index 34725a16e..fa68fa8c9 100644 --- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/item/ItemServiceImpl.java +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/item/ItemServiceImpl.java @@ -37,6 +37,7 @@ import com.l2jserver.service.AbstractService; import com.l2jserver.service.AbstractService.Depends; import com.l2jserver.service.ServiceStartException; import com.l2jserver.service.ServiceStopException; +import com.l2jserver.service.core.threading.AsyncFuture; import com.l2jserver.service.database.DatabaseService; import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException; import com.l2jserver.service.game.spawn.NotSpawnedServiceException; @@ -157,6 +158,33 @@ public class ItemServiceImpl extends AbstractService implements ItemService { return item; } + @Override + public boolean destroy(Item item, long count) + throws NotEnoughItemsServiceException { + synchronized (item) { + Item destroyItem = split(item, count); + itemDao.delete(destroyItem); + if (destroyItem.getOwnerID() != null) + destroyItem.getOwner().getInventory().remove(destroyItem); + if (!destroyItem.equals(item)) + itemDao.save(item); + return destroyItem.equals(item); + } + } + + @Override + public void destroy(Item... items) { + // requests the delete and starts removing items from inventory model + AsyncFuture async = itemDao.deleteObjectsAsync(items); + for (final Item item : items) { + if (item.getOwnerID() != null) { + item.getOwner().getInventory().remove(item); + } + } + // now wait until database operation finishes + async.awaitUninterruptibly(); + } + @Override public Item pickUp(Item item, L2Character character) throws ItemNotOnGroundServiceException, NotSpawnedServiceException { @@ -178,8 +206,7 @@ public class ItemServiceImpl extends AbstractService implements ItemService { item = stack(stackItems); Item[] deleteItems = ArrayUtils.copyArrayExcept( Item[].class, stackItems, item); - character.getInventory().remove(deleteItems); - itemDao.deleteObjects(deleteItems); + destroy(deleteItems); character.getInventory().add(item); } catch (NonStackableItemsServiceException e) { character.getInventory().add(item);