diff --git a/l2jserver2-common/src/main/java/com/l2jserver/service/AbstractService.java b/l2jserver2-common/src/main/java/com/l2jserver/service/AbstractService.java index e176646ff..edf2c5d89 100644 --- a/l2jserver2-common/src/main/java/com/l2jserver/service/AbstractService.java +++ b/l2jserver2-common/src/main/java/com/l2jserver/service/AbstractService.java @@ -21,12 +21,20 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * An abstract service implementing basic life-cycle methods. * * @author Rogiel */ public abstract class AbstractService implements Service { + /** + * The service logger + */ + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + /** * Running state of a service */ diff --git a/l2jserver2-common/src/main/java/com/l2jserver/util/ArrayUtils.java b/l2jserver2-common/src/main/java/com/l2jserver/util/ArrayUtils.java index 430607c0d..d6ac46d0e 100644 --- a/l2jserver2-common/src/main/java/com/l2jserver/util/ArrayUtils.java +++ b/l2jserver2-common/src/main/java/com/l2jserver/util/ArrayUtils.java @@ -30,8 +30,6 @@ public class ArrayUtils { /** * Copy an entire array except objects in except array. * - * @param type - * the array type * @param array * the source array * @param except @@ -39,8 +37,8 @@ public class ArrayUtils { * @return the copied array */ @SafeVarargs - public final static T[] copyArrayExcept(Class type, T[] array, - T... except) { + @SuppressWarnings("unchecked") + public final static T[] copyArrayExcept(T[] array, T... except) { final List values = CollectionFactory.newList(); for (final T item : array) { if (Arrays.binarySearch(except, item, new Comparator() { @@ -52,6 +50,6 @@ public class ArrayUtils { values.add(item); } } - return Arrays.copyOf(values.toArray(), values.size(), type); + return (T[]) Arrays.copyOf(values.toArray(), values.size(), array.getClass()); } } diff --git a/l2jserver2-common/src/main/java/com/l2jserver/util/transformer/TransformerFactory.java b/l2jserver2-common/src/main/java/com/l2jserver/util/transformer/TransformerFactory.java index 6201e34e4..6935c7dae 100644 --- a/l2jserver2-common/src/main/java/com/l2jserver/util/transformer/TransformerFactory.java +++ b/l2jserver2-common/src/main/java/com/l2jserver/util/transformer/TransformerFactory.java @@ -26,6 +26,7 @@ import com.l2jserver.util.transformer.impl.BooleanTransformer; import com.l2jserver.util.transformer.impl.ByteTransformer; import com.l2jserver.util.transformer.impl.ClassTransformer; import com.l2jserver.util.transformer.impl.DoubleTransformer; +import com.l2jserver.util.transformer.impl.EnumTransformer; import com.l2jserver.util.transformer.impl.FileTransformer; import com.l2jserver.util.transformer.impl.FloatTransformer; import com.l2jserver.util.transformer.impl.InetSocketAddressTransformer; @@ -77,6 +78,8 @@ public class TransformerFactory { return URLTransformer.SHARED_INSTANCE; } else if (type == Path.class) { return PathTransformer.SHARED_INSTANCE; + } else if(type.isEnum()) { + return EnumTransformer.SHARED_INSTANCE; } return null; } diff --git a/l2jserver2-common/src/test/java/com/l2jserver/util/ArrayUtilsTest.java b/l2jserver2-common/src/test/java/com/l2jserver/util/ArrayUtilsTest.java index 506b10c06..f7138985d 100644 --- a/l2jserver2-common/src/test/java/com/l2jserver/util/ArrayUtilsTest.java +++ b/l2jserver2-common/src/test/java/com/l2jserver/util/ArrayUtilsTest.java @@ -29,7 +29,7 @@ import org.junit.Test; */ public class ArrayUtilsTest extends ArrayUtils { /** - * Test for {@link ArrayUtils#copyArrayExcept(Class, Object[], Object...)} + * Test for {@link ArrayUtils#copyArrayExcept(Object[], Object...)} */ @Test public void testCopyArrayExcept() { @@ -38,7 +38,7 @@ public class ArrayUtilsTest extends ArrayUtils { final TestClass objC = new TestClass("c"); TestClass[] arr = new TestClass[] { objA, objB, objC }; - TestClass[] selected = copyArrayExcept(TestClass[].class, arr, objB); + TestClass[] selected = copyArrayExcept(arr, objB); System.out.println(Arrays.toString(selected)); Assert.assertTrue(Arrays.equals(new TestClass[] { objA, objC }, diff --git a/l2jserver2-gameserver/distribution/services.xml b/l2jserver2-gameserver/distribution/services.xml index db1a96ffd..a959bff0a 100644 --- a/l2jserver2-gameserver/distribution/services.xml +++ b/l2jserver2-gameserver/distribution/services.xml @@ -96,7 +96,13 @@ + implementation="com.l2jserver.service.game.item.ItemServiceImpl"> + + + + + + - @@ -58,17 +58,22 @@ you normally don't need to change anything here nor in the firewall. --> - + - + - - - + + + @@ -112,7 +117,14 @@ + implementation="com.l2jserver.service.game.item.ItemServiceImpl"> + + + + + + . + * + * 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.service.game.item; + +import com.l2jserver.service.ServiceConfiguration; +import com.l2jserver.service.configuration.XMLConfigurationService.ConfigurationXPath; + +/** + * Defines configurations for {@link ItemService} implementations + * + * @author Rogiel + */ +public interface ItemServiceConfiguration extends ServiceConfiguration { + /** + * Gets the item drop mode + * + * @return the drop mode + */ + @ConfigurationPropertyGetter(defaultValue = "ALL") + @ConfigurationXPath("drop/@persistent") + ItemServiceDropMode getItemDropMode(); + + /** + * Sets the item drop mode + * + * @param mode + * the drop mode + */ + @ConfigurationPropertySetter + @ConfigurationXPath("drop/@persistent") + void setItemDropMode(ItemServiceDropMode mode); + + /** + * The drop modes available + * + * @author Rogiel + */ + public enum ItemServiceDropMode { + /** + * All types of drops are stored into the database. + */ + ALL, + /** + * Only items dropped by characters are stored in the database. + */ + CHARACTER_ONLY, + /** + * None of the dropped items are saved into the database. + */ + NONE; + } +} 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 a51367baf..e17aeaf4d 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 @@ -33,7 +33,7 @@ import com.l2jserver.model.world.L2Character; import com.l2jserver.model.world.character.CharacterInventory.ItemLocation; import com.l2jserver.model.world.item.ItemDropEvent; import com.l2jserver.model.world.item.ItemPickEvent; -import com.l2jserver.service.AbstractService; +import com.l2jserver.service.AbstractConfigurableService; import com.l2jserver.service.AbstractService.Depends; import com.l2jserver.service.ServiceStartException; import com.l2jserver.service.ServiceStopException; @@ -52,7 +52,9 @@ import com.l2jserver.util.geometry.Point3D; * @author Rogiel */ @Depends({ SpawnService.class, DatabaseService.class }) -public class ItemServiceImpl extends AbstractService implements ItemService { +public class ItemServiceImpl extends + AbstractConfigurableService implements + ItemService { /** * The item DAO */ @@ -88,6 +90,7 @@ public class ItemServiceImpl extends AbstractService implements ItemService { @Inject private ItemServiceImpl(ItemDAO itemDao, SpawnService spawnService, WorldEventDispatcher eventDispatcher, ItemIDProvider itemIdProvider) { + super(ItemServiceConfiguration.class); this.itemDao = itemDao; this.spawnService = spawnService; this.eventDispatcher = eventDispatcher; @@ -96,6 +99,7 @@ public class ItemServiceImpl extends AbstractService implements ItemService { @Override protected void doStart() throws ServiceStartException { + logger.info("ItemService drop mode is {}", config.getItemDropMode()); items = itemDao.selectDroppedItems(); try { for (final Item item : items) { @@ -204,8 +208,8 @@ public class ItemServiceImpl extends AbstractService implements ItemService { stackItems[items.length] = item; try { item = stack(stackItems); - Item[] deleteItems = ArrayUtils.copyArrayExcept( - Item[].class, stackItems, item); + Item[] deleteItems = ArrayUtils.copyArrayExcept(stackItems, + item); destroy(deleteItems); character.getInventory().add(item); } catch (NonStackableItemsServiceException e) { @@ -218,6 +222,11 @@ public class ItemServiceImpl extends AbstractService implements ItemService { character.getInventory().add(item); this.items.remove(item); + // removes transient state + if (item.equals(originalItem) + && item.getObjectDesire() == ObjectDesire.TRANSIENT) + item.setObjectDesire(ObjectDesire.UPDATE); + itemDao.saveObjectsAsync(item); if (!item.equals(originalItem)) { itemDao.saveObjectsAsync(originalItem); @@ -254,9 +263,29 @@ public class ItemServiceImpl extends AbstractService implements ItemService { } } - itemDao.saveObjectsAsync(item); - if (!item.equals(sourceItem)) { - itemDao.saveObjectsAsync(sourceItem); + boolean persist = true; + switch (config.getItemDropMode()) { + case ALL: + persist = true; + break; + case CHARACTER_ONLY: + persist = (actor instanceof L2Character); + break; + case NONE: + persist = false; + break; + } + + if (persist) { + itemDao.saveObjectsAsync(item); + if (!item.equals(sourceItem)) { + itemDao.saveObjectsAsync(sourceItem); + } + } else { + if (item.equals(sourceItem)) { + itemDao.delete(item); + item.setObjectDesire(ObjectDesire.TRANSIENT); + } } items.add(item);