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);