Addition of item related task managers.

This commit is contained in:
MobiusDevelopment 2020-11-04 22:24:20 +00:00
parent d229e3a550
commit 946bcea559
116 changed files with 7250 additions and 2940 deletions

View File

@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.model.items.Item;
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
/**
* @author NosBit
@ -45,7 +43,6 @@ public class Product
private final long _maxCount;
private final double _baseTax;
private AtomicLong _count = null;
private ScheduledFuture<?> _restockTask = null;
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
{
@ -122,10 +119,9 @@ public class Product
{
return false;
}
if ((_restockTask == null) || _restockTask.isDone())
{
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
}
BuyListTaskManager.getInstance().add(this, _restockDelay);
final boolean result = _count.addAndGet(-value) >= 0;
save();
return result;
@ -141,7 +137,7 @@ public class Product
final long remainTime = nextRestockTime - System.currentTimeMillis();
if (remainTime > 0)
{
_restockTask = ThreadPool.schedule(this::restock, remainTime);
BuyListTaskManager.getInstance().update(this, remainTime);
}
else
{
@ -164,9 +160,10 @@ public class Product
statement.setInt(2, _item.getId());
statement.setLong(3, getCount());
statement.setLong(5, getCount());
if ((_restockTask != null) && (_restockTask.getDelay(TimeUnit.MILLISECONDS) > 0))
final long nextRestockTime = BuyListTaskManager.getInstance().getRestockDelay(this);
if (nextRestockTime > 0)
{
final long nextRestockTime = System.currentTimeMillis() + _restockTask.getDelay(TimeUnit.MILLISECONDS);
statement.setLong(4, nextRestockTime);
statement.setLong(6, nextRestockTime);
}
@ -175,6 +172,7 @@ public class Product
statement.setLong(4, 0);
statement.setLong(6, 0);
}
statement.executeUpdate();
}
catch (Exception e)

View File

@ -34,7 +34,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
@ -86,6 +85,9 @@ import org.l2jmobius.gameserver.network.serverpackets.GetItem;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.ItemAppearanceTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemLifeTimeTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
import org.l2jmobius.gameserver.util.GMAudit;
/**
@ -137,7 +139,6 @@ public class ItemInstance extends WorldObject
/** Shadow item */
private int _mana = -1;
private boolean _consumingMana = false;
private static final int MANA_CONSUMPTION_RATE = 60000;
/** Custom item types (used loto, race tickets) */
private int _type1;
@ -167,8 +168,6 @@ public class ItemInstance extends WorldObject
private Map<AttributeType, AttributeHolder> _elementals = null;
private ScheduledFuture<?> _itemLootShedule = null;
private ScheduledFuture<?> _lifeTimeTask;
private ScheduledFuture<?> _appearanceLifeTimeTask;
private final DropProtection _dropProtection = new DropProtection();
@ -831,15 +830,11 @@ public class ItemInstance extends WorldObject
{
return false;
}
if (!isPrivateWareHouse)
// augmented not tradeable
if (!isPrivateWareHouse && (!isTradeable() || isShadowItem()))
{
// augmented not tradeable
if (!isTradeable() || isShadowItem())
{
return false;
}
return false;
}
return true;
}
@ -1279,37 +1274,6 @@ public class ItemInstance extends WorldObject
}
}
/**
* Used to decrease mana (mana means life time for shadow items)
*/
public static class ScheduleConsumeManaTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleConsumeManaTask.class.getName());
private final ItemInstance _shadowItem;
public ScheduleConsumeManaTask(ItemInstance item)
{
_shadowItem = item;
}
@Override
public void run()
{
try
{
// decrease mana
if (_shadowItem != null)
{
_shadowItem.decreaseMana(true);
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
}
}
/**
* Returns true if this item is a shadow item Shadow items have a limited life-time
* @return
@ -1454,7 +1418,7 @@ public class ItemInstance extends WorldObject
return;
}
_consumingMana = true;
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
ItemManaTaskManager.getInstance().add(this);
}
/**
@ -1523,66 +1487,50 @@ public class ItemInstance extends WorldObject
* <b><u>Example of use</u>:</b><br>
* <li>Drop item</li>
* <li>Call Pet</li>
* @param dropper
* @param locX
* @param locY
* @param locZ
*/
public class ItemDropTask implements Runnable
public void dropMe(Creature dropper, int locX, int locY, int locZ)
{
private int _x;
private int _y;
private int _z;
private final Creature _dropper;
private final ItemInstance _itеm;
int x = locX;
int y = locY;
int z = locZ;
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
if (dropper != null)
{
_x = x;
_y = y;
_z = z;
_dropper = dropper;
_itеm = item;
final Instance instance = dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
x = dropDest.getX();
y = dropDest.getY();
z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
@Override
public void run()
// Set the x,y,z position of the ItemInstance dropped and update its world region
setSpawned(true);
setXYZ(x, y, z);
setDropTime(System.currentTimeMillis());
setDropperObjectId(dropper != null ? dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(this, getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
if (_dropper != null)
{
final Instance instance = _dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(_dropper.getX(), _dropper.getY(), _dropper.getZ(), _x, _y, _z, instance);
_x = dropDest.getX();
_y = dropDest.getY();
_z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
synchronized (_itеm)
{
// Set the x,y,z position of the ItemInstance dropped and update its _worldregion
_itеm.setSpawned(true);
_itеm.setXYZ(_x, _y, _z);
}
_itеm.setDropTime(System.currentTimeMillis());
_itеm.setDropperObjectId(_dropper != null ? _dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(_itеm, _itеm.getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().save(_itеm);
}
_itеm.setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
ItemsOnGroundManager.getInstance().save(this);
}
}
public void dropMe(Creature dropper, int x, int y, int z)
{
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
if ((dropper != null) && dropper.isPlayer())
{
_owner = null;
// Notify to scripts
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerItemDrop(dropper.getActingPlayer(), this, new Location(x, y, z)), getItem());
}
@ -1890,38 +1838,7 @@ public class ItemInstance extends WorldObject
}
else
{
if (_lifeTimeTask != null)
{
_lifeTimeTask.cancel(true);
}
_lifeTimeTask = ThreadPool.schedule(new ScheduleLifeTimeTask(this), getRemainingTime());
}
}
static class ScheduleLifeTimeTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleLifeTimeTask.class.getName());
private final ItemInstance _limitedItem;
ScheduleLifeTimeTask(ItemInstance item)
{
_limitedItem = item;
}
@Override
public void run()
{
try
{
if (_limitedItem != null)
{
_limitedItem.endOfLife();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
}
}
@ -2185,16 +2102,8 @@ public class ItemInstance extends WorldObject
public void stopAllTasks()
{
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
{
_lifeTimeTask.cancel(false);
_lifeTimeTask = null;
}
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
{
_appearanceLifeTimeTask.cancel(false);
_appearanceLifeTimeTask = null;
}
ItemLifeTimeTaskManager.getInstance().remove(this);
ItemAppearanceTaskManager.getInstance().remove(this);
}
public ItemVariables getVariables()
@ -2237,10 +2146,9 @@ public class ItemInstance extends WorldObject
getVariables().set(ItemVariables.VISUAL_ID, visualId);
// When removed, cancel existing lifetime task.
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
if (visualId == 0)
{
_appearanceLifeTimeTask.cancel(true);
_appearanceLifeTimeTask = null;
ItemAppearanceTaskManager.getInstance().remove(this);
onVisualLifeTimeEnd();
}
}
@ -2252,25 +2160,22 @@ public class ItemInstance extends WorldObject
public void scheduleVisualLifeTime()
{
if (_appearanceLifeTimeTask != null)
{
_appearanceLifeTimeTask.cancel(false);
}
ItemAppearanceTaskManager.getInstance().remove(this);
if (getVisualLifeTime() > 0)
{
final long time = getVisualLifeTime() - System.currentTimeMillis();
if (time > 0)
final long endTime = getVisualLifeTime();
if ((endTime - System.currentTimeMillis()) > 0)
{
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
ItemAppearanceTaskManager.getInstance().add(this, endTime);
}
else
{
ThreadPool.execute(this::onVisualLifeTimeEnd);
onVisualLifeTimeEnd();
}
}
}
private void onVisualLifeTimeEnd()
public void onVisualLifeTimeEnd()
{
final ItemVariables vars = getVariables();
vars.remove(ItemVariables.VISUAL_ID);

View File

@ -0,0 +1,86 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.buylist.Product;
/**
* @author Mobius
*/
public class BuyListTaskManager
{
private static final Map<Product, Long> PRODUCTS = new ConcurrentHashMap<>();
private static boolean _working = false;
public BuyListTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<Product, Long> entry : PRODUCTS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final Product product = entry.getKey();
PRODUCTS.remove(product);
product.restock();
}
}
_working = false;
}, 1000, 60000);
}
public void add(Product product, long endTime)
{
if (!PRODUCTS.containsKey(product))
{
PRODUCTS.put(product, endTime);
}
}
public void update(Product product, long endTime)
{
PRODUCTS.put(product, endTime);
}
public long getRestockDelay(Product product)
{
return PRODUCTS.getOrDefault(product, 0L);
}
public static BuyListTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final BuyListTaskManager INSTANCE = new BuyListTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemAppearanceTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemAppearanceTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.onVisualLifeTimeEnd();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemAppearanceTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemAppearanceTaskManager INSTANCE = new ItemAppearanceTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemLifeTimeTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemLifeTimeTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.endOfLife();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemLifeTimeTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemLifeTimeTaskManager INSTANCE = new ItemLifeTimeTaskManager();
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemManaTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static final int MANA_CONSUMPTION_RATE = 60000;
private static boolean _working = false;
public ItemManaTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, System.currentTimeMillis() + MANA_CONSUMPTION_RATE);
}
}
public static ItemManaTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemManaTaskManager INSTANCE = new ItemManaTaskManager();
}
}

View File

@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.model.items.Item;
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
/**
* @author NosBit
@ -45,7 +43,6 @@ public class Product
private final long _maxCount;
private final double _baseTax;
private AtomicLong _count = null;
private ScheduledFuture<?> _restockTask = null;
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
{
@ -122,10 +119,9 @@ public class Product
{
return false;
}
if ((_restockTask == null) || _restockTask.isDone())
{
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
}
BuyListTaskManager.getInstance().add(this, _restockDelay);
final boolean result = _count.addAndGet(-value) >= 0;
save();
return result;
@ -141,7 +137,7 @@ public class Product
final long remainTime = nextRestockTime - System.currentTimeMillis();
if (remainTime > 0)
{
_restockTask = ThreadPool.schedule(this::restock, remainTime);
BuyListTaskManager.getInstance().update(this, remainTime);
}
else
{
@ -164,9 +160,10 @@ public class Product
statement.setInt(2, _item.getId());
statement.setLong(3, getCount());
statement.setLong(5, getCount());
if ((_restockTask != null) && (_restockTask.getDelay(TimeUnit.MILLISECONDS) > 0))
final long nextRestockTime = BuyListTaskManager.getInstance().getRestockDelay(this);
if (nextRestockTime > 0)
{
final long nextRestockTime = System.currentTimeMillis() + _restockTask.getDelay(TimeUnit.MILLISECONDS);
statement.setLong(4, nextRestockTime);
statement.setLong(6, nextRestockTime);
}
@ -175,6 +172,7 @@ public class Product
statement.setLong(4, 0);
statement.setLong(6, 0);
}
statement.executeUpdate();
}
catch (Exception e)

View File

@ -34,7 +34,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
@ -88,6 +87,9 @@ import org.l2jmobius.gameserver.network.serverpackets.GetItem;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.ItemAppearanceTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemLifeTimeTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
import org.l2jmobius.gameserver.util.GMAudit;
/**
@ -139,7 +141,6 @@ public class ItemInstance extends WorldObject
/** Shadow item */
private int _mana = -1;
private boolean _consumingMana = false;
private static final int MANA_CONSUMPTION_RATE = 60000;
/** Custom item types (used loto, race tickets) */
private int _type1;
@ -169,8 +170,6 @@ public class ItemInstance extends WorldObject
private Map<AttributeType, AttributeHolder> _elementals = null;
private ScheduledFuture<?> _itemLootShedule = null;
private ScheduledFuture<?> _lifeTimeTask;
private ScheduledFuture<?> _appearanceLifeTimeTask;
private final DropProtection _dropProtection = new DropProtection();
@ -1280,37 +1279,6 @@ public class ItemInstance extends WorldObject
}
}
/**
* Used to decrease mana (mana means life time for shadow items)
*/
public static class ScheduleConsumeManaTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleConsumeManaTask.class.getName());
private final ItemInstance _shadowItem;
public ScheduleConsumeManaTask(ItemInstance item)
{
_shadowItem = item;
}
@Override
public void run()
{
try
{
// decrease mana
if (_shadowItem != null)
{
_shadowItem.decreaseMana(true);
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
}
}
/**
* Returns true if this item is a shadow item Shadow items have a limited life-time
* @return
@ -1455,7 +1423,7 @@ public class ItemInstance extends WorldObject
return;
}
_consumingMana = true;
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
ItemManaTaskManager.getInstance().add(this);
}
/**
@ -1524,64 +1492,46 @@ public class ItemInstance extends WorldObject
* <b><u>Example of use</u>:</b><br>
* <li>Drop item</li>
* <li>Call Pet</li>
* @param dropper
* @param locX
* @param locY
* @param locZ
*/
public class ItemDropTask implements Runnable
public void dropMe(Creature dropper, int locX, int locY, int locZ)
{
private int _x;
private int _y;
private int _z;
private final Creature _dropper;
private final ItemInstance _itеm;
int x = locX;
int y = locY;
int z = locZ;
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
if (dropper != null)
{
_x = x;
_y = y;
_z = z;
_dropper = dropper;
_itеm = item;
final Instance instance = dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
x = dropDest.getX();
y = dropDest.getY();
z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
@Override
public void run()
// Set the x,y,z position of the ItemInstance dropped and update its world region
setSpawned(true);
setXYZ(x, y, z);
setDropTime(System.currentTimeMillis());
setDropperObjectId(dropper != null ? dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(this, getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
if (_dropper != null)
{
final Instance instance = _dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(_dropper.getX(), _dropper.getY(), _dropper.getZ(), _x, _y, _z, instance);
_x = dropDest.getX();
_y = dropDest.getY();
_z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
synchronized (_itеm)
{
// Set the x,y,z position of the ItemInstance dropped and update its _worldregion
_itеm.setSpawned(true);
_itеm.setXYZ(_x, _y, _z);
}
_itеm.setDropTime(System.currentTimeMillis());
_itеm.setDropperObjectId(_dropper != null ? _dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(_itеm, _itеm.getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().save(_itеm);
}
_itеm.setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
ItemsOnGroundManager.getInstance().save(this);
}
}
public void dropMe(Creature dropper, int x, int y, int z)
{
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
if ((dropper != null) && dropper.isPlayer())
{
_owner = null;
@ -1899,38 +1849,7 @@ public class ItemInstance extends WorldObject
}
else
{
if (_lifeTimeTask != null)
{
_lifeTimeTask.cancel(true);
}
_lifeTimeTask = ThreadPool.schedule(new ScheduleLifeTimeTask(this), getRemainingTime());
}
}
static class ScheduleLifeTimeTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleLifeTimeTask.class.getName());
private final ItemInstance _limitedItem;
ScheduleLifeTimeTask(ItemInstance item)
{
_limitedItem = item;
}
@Override
public void run()
{
try
{
if (_limitedItem != null)
{
_limitedItem.endOfLife();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
}
}
@ -2440,16 +2359,8 @@ public class ItemInstance extends WorldObject
public void stopAllTasks()
{
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
{
_lifeTimeTask.cancel(false);
_lifeTimeTask = null;
}
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
{
_appearanceLifeTimeTask.cancel(false);
_appearanceLifeTimeTask = null;
}
ItemLifeTimeTaskManager.getInstance().remove(this);
ItemAppearanceTaskManager.getInstance().remove(this);
}
public ItemVariables getVariables()
@ -2492,10 +2403,9 @@ public class ItemInstance extends WorldObject
getVariables().set(ItemVariables.VISUAL_ID, visualId);
// When removed, cancel existing lifetime task.
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
if (visualId == 0)
{
_appearanceLifeTimeTask.cancel(true);
_appearanceLifeTimeTask = null;
ItemAppearanceTaskManager.getInstance().remove(this);
onVisualLifeTimeEnd();
}
}
@ -2507,25 +2417,22 @@ public class ItemInstance extends WorldObject
public void scheduleVisualLifeTime()
{
if (_appearanceLifeTimeTask != null)
{
_appearanceLifeTimeTask.cancel(false);
}
ItemAppearanceTaskManager.getInstance().remove(this);
if (getVisualLifeTime() > 0)
{
final long time = getVisualLifeTime() - System.currentTimeMillis();
if (time > 0)
final long endTime = getVisualLifeTime();
if ((endTime - System.currentTimeMillis()) > 0)
{
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
ItemAppearanceTaskManager.getInstance().add(this, endTime);
}
else
{
ThreadPool.execute(this::onVisualLifeTimeEnd);
onVisualLifeTimeEnd();
}
}
}
private void onVisualLifeTimeEnd()
public void onVisualLifeTimeEnd()
{
final ItemVariables vars = getVariables();
vars.remove(ItemVariables.VISUAL_ID);

View File

@ -0,0 +1,86 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.buylist.Product;
/**
* @author Mobius
*/
public class BuyListTaskManager
{
private static final Map<Product, Long> PRODUCTS = new ConcurrentHashMap<>();
private static boolean _working = false;
public BuyListTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<Product, Long> entry : PRODUCTS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final Product product = entry.getKey();
PRODUCTS.remove(product);
product.restock();
}
}
_working = false;
}, 1000, 60000);
}
public void add(Product product, long endTime)
{
if (!PRODUCTS.containsKey(product))
{
PRODUCTS.put(product, endTime);
}
}
public void update(Product product, long endTime)
{
PRODUCTS.put(product, endTime);
}
public long getRestockDelay(Product product)
{
return PRODUCTS.getOrDefault(product, 0L);
}
public static BuyListTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final BuyListTaskManager INSTANCE = new BuyListTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemAppearanceTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemAppearanceTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.onVisualLifeTimeEnd();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemAppearanceTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemAppearanceTaskManager INSTANCE = new ItemAppearanceTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemLifeTimeTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemLifeTimeTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.endOfLife();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemLifeTimeTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemLifeTimeTaskManager INSTANCE = new ItemLifeTimeTaskManager();
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemManaTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static final int MANA_CONSUMPTION_RATE = 60000;
private static boolean _working = false;
public ItemManaTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, System.currentTimeMillis() + MANA_CONSUMPTION_RATE);
}
}
public static ItemManaTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemManaTaskManager INSTANCE = new ItemManaTaskManager();
}
}

View File

@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.model.items.Item;
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
/**
* @author NosBit
@ -45,7 +43,6 @@ public class Product
private final long _maxCount;
private final double _baseTax;
private AtomicLong _count = null;
private ScheduledFuture<?> _restockTask = null;
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
{
@ -122,10 +119,9 @@ public class Product
{
return false;
}
if ((_restockTask == null) || _restockTask.isDone())
{
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
}
BuyListTaskManager.getInstance().add(this, _restockDelay);
final boolean result = _count.addAndGet(-value) >= 0;
save();
return result;
@ -141,7 +137,7 @@ public class Product
final long remainTime = nextRestockTime - System.currentTimeMillis();
if (remainTime > 0)
{
_restockTask = ThreadPool.schedule(this::restock, remainTime);
BuyListTaskManager.getInstance().update(this, remainTime);
}
else
{
@ -164,9 +160,10 @@ public class Product
statement.setInt(2, _item.getId());
statement.setLong(3, getCount());
statement.setLong(5, getCount());
if ((_restockTask != null) && (_restockTask.getDelay(TimeUnit.MILLISECONDS) > 0))
final long nextRestockTime = BuyListTaskManager.getInstance().getRestockDelay(this);
if (nextRestockTime > 0)
{
final long nextRestockTime = System.currentTimeMillis() + _restockTask.getDelay(TimeUnit.MILLISECONDS);
statement.setLong(4, nextRestockTime);
statement.setLong(6, nextRestockTime);
}
@ -175,6 +172,7 @@ public class Product
statement.setLong(4, 0);
statement.setLong(6, 0);
}
statement.executeUpdate();
}
catch (Exception e)

View File

@ -34,7 +34,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
@ -88,6 +87,9 @@ import org.l2jmobius.gameserver.network.serverpackets.GetItem;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.ItemAppearanceTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemLifeTimeTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
import org.l2jmobius.gameserver.util.GMAudit;
/**
@ -139,7 +141,6 @@ public class ItemInstance extends WorldObject
/** Shadow item */
private int _mana = -1;
private boolean _consumingMana = false;
private static final int MANA_CONSUMPTION_RATE = 60000;
/** Custom item types (used loto, race tickets) */
private int _type1;
@ -169,8 +170,6 @@ public class ItemInstance extends WorldObject
private Map<AttributeType, AttributeHolder> _elementals = null;
private ScheduledFuture<?> _itemLootShedule = null;
private ScheduledFuture<?> _lifeTimeTask;
private ScheduledFuture<?> _appearanceLifeTimeTask;
private final DropProtection _dropProtection = new DropProtection();
@ -1280,37 +1279,6 @@ public class ItemInstance extends WorldObject
}
}
/**
* Used to decrease mana (mana means life time for shadow items)
*/
public static class ScheduleConsumeManaTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleConsumeManaTask.class.getName());
private final ItemInstance _shadowItem;
public ScheduleConsumeManaTask(ItemInstance item)
{
_shadowItem = item;
}
@Override
public void run()
{
try
{
// decrease mana
if (_shadowItem != null)
{
_shadowItem.decreaseMana(true);
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
}
}
/**
* Returns true if this item is a shadow item Shadow items have a limited life-time
* @return
@ -1455,7 +1423,7 @@ public class ItemInstance extends WorldObject
return;
}
_consumingMana = true;
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
ItemManaTaskManager.getInstance().add(this);
}
/**
@ -1524,64 +1492,46 @@ public class ItemInstance extends WorldObject
* <b><u>Example of use</u>:</b><br>
* <li>Drop item</li>
* <li>Call Pet</li>
* @param dropper
* @param locX
* @param locY
* @param locZ
*/
public class ItemDropTask implements Runnable
public void dropMe(Creature dropper, int locX, int locY, int locZ)
{
private int _x;
private int _y;
private int _z;
private final Creature _dropper;
private final ItemInstance _itеm;
int x = locX;
int y = locY;
int z = locZ;
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
if (dropper != null)
{
_x = x;
_y = y;
_z = z;
_dropper = dropper;
_itеm = item;
final Instance instance = dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
x = dropDest.getX();
y = dropDest.getY();
z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
@Override
public void run()
// Set the x,y,z position of the ItemInstance dropped and update its world region
setSpawned(true);
setXYZ(x, y, z);
setDropTime(System.currentTimeMillis());
setDropperObjectId(dropper != null ? dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(this, getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
if (_dropper != null)
{
final Instance instance = _dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(_dropper.getX(), _dropper.getY(), _dropper.getZ(), _x, _y, _z, instance);
_x = dropDest.getX();
_y = dropDest.getY();
_z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
synchronized (_itеm)
{
// Set the x,y,z position of the ItemInstance dropped and update its _worldregion
_itеm.setSpawned(true);
_itеm.setXYZ(_x, _y, _z);
}
_itеm.setDropTime(System.currentTimeMillis());
_itеm.setDropperObjectId(_dropper != null ? _dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(_itеm, _itеm.getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().save(_itеm);
}
_itеm.setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
ItemsOnGroundManager.getInstance().save(this);
}
}
public void dropMe(Creature dropper, int x, int y, int z)
{
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
if ((dropper != null) && dropper.isPlayer())
{
_owner = null;
@ -1899,38 +1849,7 @@ public class ItemInstance extends WorldObject
}
else
{
if (_lifeTimeTask != null)
{
_lifeTimeTask.cancel(true);
}
_lifeTimeTask = ThreadPool.schedule(new ScheduleLifeTimeTask(this), getRemainingTime());
}
}
static class ScheduleLifeTimeTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleLifeTimeTask.class.getName());
private final ItemInstance _limitedItem;
ScheduleLifeTimeTask(ItemInstance item)
{
_limitedItem = item;
}
@Override
public void run()
{
try
{
if (_limitedItem != null)
{
_limitedItem.endOfLife();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
}
}
@ -2440,16 +2359,8 @@ public class ItemInstance extends WorldObject
public void stopAllTasks()
{
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
{
_lifeTimeTask.cancel(false);
_lifeTimeTask = null;
}
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
{
_appearanceLifeTimeTask.cancel(false);
_appearanceLifeTimeTask = null;
}
ItemLifeTimeTaskManager.getInstance().remove(this);
ItemAppearanceTaskManager.getInstance().remove(this);
}
public ItemVariables getVariables()
@ -2492,10 +2403,9 @@ public class ItemInstance extends WorldObject
getVariables().set(ItemVariables.VISUAL_ID, visualId);
// When removed, cancel existing lifetime task.
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
if (visualId == 0)
{
_appearanceLifeTimeTask.cancel(true);
_appearanceLifeTimeTask = null;
ItemAppearanceTaskManager.getInstance().remove(this);
onVisualLifeTimeEnd();
}
}
@ -2507,25 +2417,22 @@ public class ItemInstance extends WorldObject
public void scheduleVisualLifeTime()
{
if (_appearanceLifeTimeTask != null)
{
_appearanceLifeTimeTask.cancel(false);
}
ItemAppearanceTaskManager.getInstance().remove(this);
if (getVisualLifeTime() > 0)
{
final long time = getVisualLifeTime() - System.currentTimeMillis();
if (time > 0)
final long endTime = getVisualLifeTime();
if ((endTime - System.currentTimeMillis()) > 0)
{
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
ItemAppearanceTaskManager.getInstance().add(this, endTime);
}
else
{
ThreadPool.execute(this::onVisualLifeTimeEnd);
onVisualLifeTimeEnd();
}
}
}
private void onVisualLifeTimeEnd()
public void onVisualLifeTimeEnd()
{
final ItemVariables vars = getVariables();
vars.remove(ItemVariables.VISUAL_ID);

View File

@ -0,0 +1,86 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.buylist.Product;
/**
* @author Mobius
*/
public class BuyListTaskManager
{
private static final Map<Product, Long> PRODUCTS = new ConcurrentHashMap<>();
private static boolean _working = false;
public BuyListTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<Product, Long> entry : PRODUCTS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final Product product = entry.getKey();
PRODUCTS.remove(product);
product.restock();
}
}
_working = false;
}, 1000, 60000);
}
public void add(Product product, long endTime)
{
if (!PRODUCTS.containsKey(product))
{
PRODUCTS.put(product, endTime);
}
}
public void update(Product product, long endTime)
{
PRODUCTS.put(product, endTime);
}
public long getRestockDelay(Product product)
{
return PRODUCTS.getOrDefault(product, 0L);
}
public static BuyListTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final BuyListTaskManager INSTANCE = new BuyListTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemAppearanceTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemAppearanceTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.onVisualLifeTimeEnd();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemAppearanceTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemAppearanceTaskManager INSTANCE = new ItemAppearanceTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemLifeTimeTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemLifeTimeTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.endOfLife();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemLifeTimeTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemLifeTimeTaskManager INSTANCE = new ItemLifeTimeTaskManager();
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemManaTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static final int MANA_CONSUMPTION_RATE = 60000;
private static boolean _working = false;
public ItemManaTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, System.currentTimeMillis() + MANA_CONSUMPTION_RATE);
}
}
public static ItemManaTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemManaTaskManager INSTANCE = new ItemManaTaskManager();
}
}

View File

@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.model.items.Item;
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
/**
* @author NosBit
@ -45,7 +43,6 @@ public class Product
private final long _maxCount;
private final double _baseTax;
private AtomicLong _count = null;
private ScheduledFuture<?> _restockTask = null;
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
{
@ -122,10 +119,9 @@ public class Product
{
return false;
}
if ((_restockTask == null) || _restockTask.isDone())
{
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
}
BuyListTaskManager.getInstance().add(this, _restockDelay);
final boolean result = _count.addAndGet(-value) >= 0;
save();
return result;
@ -141,7 +137,7 @@ public class Product
final long remainTime = nextRestockTime - System.currentTimeMillis();
if (remainTime > 0)
{
_restockTask = ThreadPool.schedule(this::restock, remainTime);
BuyListTaskManager.getInstance().update(this, remainTime);
}
else
{
@ -164,9 +160,10 @@ public class Product
statement.setInt(2, _item.getId());
statement.setLong(3, getCount());
statement.setLong(5, getCount());
if ((_restockTask != null) && (_restockTask.getDelay(TimeUnit.MILLISECONDS) > 0))
final long nextRestockTime = BuyListTaskManager.getInstance().getRestockDelay(this);
if (nextRestockTime > 0)
{
final long nextRestockTime = System.currentTimeMillis() + _restockTask.getDelay(TimeUnit.MILLISECONDS);
statement.setLong(4, nextRestockTime);
statement.setLong(6, nextRestockTime);
}
@ -175,6 +172,7 @@ public class Product
statement.setLong(4, 0);
statement.setLong(6, 0);
}
statement.executeUpdate();
}
catch (Exception e)

View File

@ -34,7 +34,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
@ -88,6 +87,9 @@ import org.l2jmobius.gameserver.network.serverpackets.GetItem;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.ItemAppearanceTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemLifeTimeTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
import org.l2jmobius.gameserver.util.GMAudit;
/**
@ -139,7 +141,6 @@ public class ItemInstance extends WorldObject
/** Shadow item */
private int _mana = -1;
private boolean _consumingMana = false;
private static final int MANA_CONSUMPTION_RATE = 60000;
/** Custom item types (used loto, race tickets) */
private int _type1;
@ -169,8 +170,6 @@ public class ItemInstance extends WorldObject
private Map<AttributeType, AttributeHolder> _elementals = null;
private ScheduledFuture<?> _itemLootShedule = null;
private ScheduledFuture<?> _lifeTimeTask;
private ScheduledFuture<?> _appearanceLifeTimeTask;
private final DropProtection _dropProtection = new DropProtection();
@ -1280,37 +1279,6 @@ public class ItemInstance extends WorldObject
}
}
/**
* Used to decrease mana (mana means life time for shadow items)
*/
public static class ScheduleConsumeManaTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleConsumeManaTask.class.getName());
private final ItemInstance _shadowItem;
public ScheduleConsumeManaTask(ItemInstance item)
{
_shadowItem = item;
}
@Override
public void run()
{
try
{
// decrease mana
if (_shadowItem != null)
{
_shadowItem.decreaseMana(true);
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
}
}
/**
* Returns true if this item is a shadow item Shadow items have a limited life-time
* @return
@ -1455,7 +1423,7 @@ public class ItemInstance extends WorldObject
return;
}
_consumingMana = true;
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
ItemManaTaskManager.getInstance().add(this);
}
/**
@ -1524,64 +1492,46 @@ public class ItemInstance extends WorldObject
* <b><u>Example of use</u>:</b><br>
* <li>Drop item</li>
* <li>Call Pet</li>
* @param dropper
* @param locX
* @param locY
* @param locZ
*/
public class ItemDropTask implements Runnable
public void dropMe(Creature dropper, int locX, int locY, int locZ)
{
private int _x;
private int _y;
private int _z;
private final Creature _dropper;
private final ItemInstance _itеm;
int x = locX;
int y = locY;
int z = locZ;
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
if (dropper != null)
{
_x = x;
_y = y;
_z = z;
_dropper = dropper;
_itеm = item;
final Instance instance = dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
x = dropDest.getX();
y = dropDest.getY();
z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
@Override
public void run()
// Set the x,y,z position of the ItemInstance dropped and update its world region
setSpawned(true);
setXYZ(x, y, z);
setDropTime(System.currentTimeMillis());
setDropperObjectId(dropper != null ? dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(this, getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
if (_dropper != null)
{
final Instance instance = _dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(_dropper.getX(), _dropper.getY(), _dropper.getZ(), _x, _y, _z, instance);
_x = dropDest.getX();
_y = dropDest.getY();
_z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
synchronized (_itеm)
{
// Set the x,y,z position of the ItemInstance dropped and update its _worldregion
_itеm.setSpawned(true);
_itеm.setXYZ(_x, _y, _z);
}
_itеm.setDropTime(System.currentTimeMillis());
_itеm.setDropperObjectId(_dropper != null ? _dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(_itеm, _itеm.getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().save(_itеm);
}
_itеm.setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
ItemsOnGroundManager.getInstance().save(this);
}
}
public void dropMe(Creature dropper, int x, int y, int z)
{
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
if ((dropper != null) && dropper.isPlayer())
{
_owner = null;
@ -1899,38 +1849,7 @@ public class ItemInstance extends WorldObject
}
else
{
if (_lifeTimeTask != null)
{
_lifeTimeTask.cancel(true);
}
_lifeTimeTask = ThreadPool.schedule(new ScheduleLifeTimeTask(this), getRemainingTime());
}
}
static class ScheduleLifeTimeTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleLifeTimeTask.class.getName());
private final ItemInstance _limitedItem;
ScheduleLifeTimeTask(ItemInstance item)
{
_limitedItem = item;
}
@Override
public void run()
{
try
{
if (_limitedItem != null)
{
_limitedItem.endOfLife();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
}
}
@ -2474,16 +2393,8 @@ public class ItemInstance extends WorldObject
public void stopAllTasks()
{
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
{
_lifeTimeTask.cancel(false);
_lifeTimeTask = null;
}
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
{
_appearanceLifeTimeTask.cancel(false);
_appearanceLifeTimeTask = null;
}
ItemLifeTimeTaskManager.getInstance().remove(this);
ItemAppearanceTaskManager.getInstance().remove(this);
}
public ItemVariables getVariables()
@ -2526,10 +2437,9 @@ public class ItemInstance extends WorldObject
getVariables().set(ItemVariables.VISUAL_ID, visualId);
// When removed, cancel existing lifetime task.
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
if (visualId == 0)
{
_appearanceLifeTimeTask.cancel(true);
_appearanceLifeTimeTask = null;
ItemAppearanceTaskManager.getInstance().remove(this);
onVisualLifeTimeEnd();
}
}
@ -2541,25 +2451,22 @@ public class ItemInstance extends WorldObject
public void scheduleVisualLifeTime()
{
if (_appearanceLifeTimeTask != null)
{
_appearanceLifeTimeTask.cancel(false);
}
ItemAppearanceTaskManager.getInstance().remove(this);
if (getVisualLifeTime() > 0)
{
final long time = getVisualLifeTime() - System.currentTimeMillis();
if (time > 0)
final long endTime = getVisualLifeTime();
if ((endTime - System.currentTimeMillis()) > 0)
{
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
ItemAppearanceTaskManager.getInstance().add(this, endTime);
}
else
{
ThreadPool.execute(this::onVisualLifeTimeEnd);
onVisualLifeTimeEnd();
}
}
}
private void onVisualLifeTimeEnd()
public void onVisualLifeTimeEnd()
{
final ItemVariables vars = getVariables();
vars.remove(ItemVariables.VISUAL_ID);

View File

@ -0,0 +1,86 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.buylist.Product;
/**
* @author Mobius
*/
public class BuyListTaskManager
{
private static final Map<Product, Long> PRODUCTS = new ConcurrentHashMap<>();
private static boolean _working = false;
public BuyListTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<Product, Long> entry : PRODUCTS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final Product product = entry.getKey();
PRODUCTS.remove(product);
product.restock();
}
}
_working = false;
}, 1000, 60000);
}
public void add(Product product, long endTime)
{
if (!PRODUCTS.containsKey(product))
{
PRODUCTS.put(product, endTime);
}
}
public void update(Product product, long endTime)
{
PRODUCTS.put(product, endTime);
}
public long getRestockDelay(Product product)
{
return PRODUCTS.getOrDefault(product, 0L);
}
public static BuyListTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final BuyListTaskManager INSTANCE = new BuyListTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemAppearanceTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemAppearanceTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.onVisualLifeTimeEnd();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemAppearanceTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemAppearanceTaskManager INSTANCE = new ItemAppearanceTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemLifeTimeTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemLifeTimeTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.endOfLife();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemLifeTimeTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemLifeTimeTaskManager INSTANCE = new ItemLifeTimeTaskManager();
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemManaTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static final int MANA_CONSUMPTION_RATE = 60000;
private static boolean _working = false;
public ItemManaTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, System.currentTimeMillis() + MANA_CONSUMPTION_RATE);
}
}
public static ItemManaTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemManaTaskManager INSTANCE = new ItemManaTaskManager();
}
}

View File

@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.model.items.Item;
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
/**
* @author NosBit
@ -45,7 +43,6 @@ public class Product
private final long _maxCount;
private final double _baseTax;
private AtomicLong _count = null;
private ScheduledFuture<?> _restockTask = null;
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
{
@ -122,10 +119,9 @@ public class Product
{
return false;
}
if ((_restockTask == null) || _restockTask.isDone())
{
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
}
BuyListTaskManager.getInstance().add(this, _restockDelay);
final boolean result = _count.addAndGet(-value) >= 0;
save();
return result;
@ -141,7 +137,7 @@ public class Product
final long remainTime = nextRestockTime - System.currentTimeMillis();
if (remainTime > 0)
{
_restockTask = ThreadPool.schedule(this::restock, remainTime);
BuyListTaskManager.getInstance().update(this, remainTime);
}
else
{
@ -164,9 +160,10 @@ public class Product
statement.setInt(2, _item.getId());
statement.setLong(3, getCount());
statement.setLong(5, getCount());
if ((_restockTask != null) && (_restockTask.getDelay(TimeUnit.MILLISECONDS) > 0))
final long nextRestockTime = BuyListTaskManager.getInstance().getRestockDelay(this);
if (nextRestockTime > 0)
{
final long nextRestockTime = System.currentTimeMillis() + _restockTask.getDelay(TimeUnit.MILLISECONDS);
statement.setLong(4, nextRestockTime);
statement.setLong(6, nextRestockTime);
}
@ -175,6 +172,7 @@ public class Product
statement.setLong(4, 0);
statement.setLong(6, 0);
}
statement.executeUpdate();
}
catch (Exception e)

View File

@ -34,7 +34,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
@ -91,6 +90,9 @@ import org.l2jmobius.gameserver.network.serverpackets.GetItem;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.ItemAppearanceTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemLifeTimeTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
import org.l2jmobius.gameserver.util.GMAudit;
/**
@ -142,7 +144,6 @@ public class ItemInstance extends WorldObject
/** Shadow item */
private int _mana = -1;
private boolean _consumingMana = false;
private static final int MANA_CONSUMPTION_RATE = 60000;
/** Custom item types (used loto, race tickets) */
private int _type1;
@ -172,8 +173,6 @@ public class ItemInstance extends WorldObject
private Map<AttributeType, AttributeHolder> _elementals = null;
private ScheduledFuture<?> _itemLootShedule = null;
private ScheduledFuture<?> _lifeTimeTask;
private ScheduledFuture<?> _appearanceLifeTimeTask;
private final DropProtection _dropProtection = new DropProtection();
@ -1288,37 +1287,6 @@ public class ItemInstance extends WorldObject
}
}
/**
* Used to decrease mana (mana means life time for shadow items)
*/
public static class ScheduleConsumeManaTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleConsumeManaTask.class.getName());
private final ItemInstance _shadowItem;
public ScheduleConsumeManaTask(ItemInstance item)
{
_shadowItem = item;
}
@Override
public void run()
{
try
{
// decrease mana
if (_shadowItem != null)
{
_shadowItem.decreaseMana(true);
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
}
}
/**
* Returns true if this item is a shadow item Shadow items have a limited life-time
* @return
@ -1463,7 +1431,7 @@ public class ItemInstance extends WorldObject
return;
}
_consumingMana = true;
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
ItemManaTaskManager.getInstance().add(this);
}
/**
@ -1532,64 +1500,46 @@ public class ItemInstance extends WorldObject
* <b><u>Example of use</u>:</b><br>
* <li>Drop item</li>
* <li>Call Pet</li>
* @param dropper
* @param locX
* @param locY
* @param locZ
*/
public class ItemDropTask implements Runnable
public void dropMe(Creature dropper, int locX, int locY, int locZ)
{
private int _x;
private int _y;
private int _z;
private final Creature _dropper;
private final ItemInstance _itеm;
int x = locX;
int y = locY;
int z = locZ;
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
if (dropper != null)
{
_x = x;
_y = y;
_z = z;
_dropper = dropper;
_itеm = item;
final Instance instance = dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
x = dropDest.getX();
y = dropDest.getY();
z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
@Override
public void run()
// Set the x,y,z position of the ItemInstance dropped and update its world region
setSpawned(true);
setXYZ(x, y, z);
setDropTime(System.currentTimeMillis());
setDropperObjectId(dropper != null ? dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(this, getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
if (_dropper != null)
{
final Instance instance = _dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(_dropper.getX(), _dropper.getY(), _dropper.getZ(), _x, _y, _z, instance);
_x = dropDest.getX();
_y = dropDest.getY();
_z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
synchronized (_itеm)
{
// Set the x,y,z position of the ItemInstance dropped and update its _worldregion
_itеm.setSpawned(true);
_itеm.setXYZ(_x, _y, _z);
}
_itеm.setDropTime(System.currentTimeMillis());
_itеm.setDropperObjectId(_dropper != null ? _dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(_itеm, _itеm.getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().save(_itеm);
}
_itеm.setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
ItemsOnGroundManager.getInstance().save(this);
}
}
public void dropMe(Creature dropper, int x, int y, int z)
{
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
if ((dropper != null) && dropper.isPlayer())
{
_owner = null;
@ -1907,38 +1857,7 @@ public class ItemInstance extends WorldObject
}
else
{
if (_lifeTimeTask != null)
{
_lifeTimeTask.cancel(true);
}
_lifeTimeTask = ThreadPool.schedule(new ScheduleLifeTimeTask(this), getRemainingTime());
}
}
static class ScheduleLifeTimeTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleLifeTimeTask.class.getName());
private final ItemInstance _limitedItem;
ScheduleLifeTimeTask(ItemInstance item)
{
_limitedItem = item;
}
@Override
public void run()
{
try
{
if (_limitedItem != null)
{
_limitedItem.endOfLife();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
}
}
@ -2485,16 +2404,8 @@ public class ItemInstance extends WorldObject
public void stopAllTasks()
{
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
{
_lifeTimeTask.cancel(false);
_lifeTimeTask = null;
}
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
{
_appearanceLifeTimeTask.cancel(false);
_appearanceLifeTimeTask = null;
}
ItemLifeTimeTaskManager.getInstance().remove(this);
ItemAppearanceTaskManager.getInstance().remove(this);
}
public ItemVariables getVariables()
@ -2537,10 +2448,9 @@ public class ItemInstance extends WorldObject
getVariables().set(ItemVariables.VISUAL_ID, visualId);
// When removed, cancel existing lifetime task.
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
if (visualId == 0)
{
_appearanceLifeTimeTask.cancel(true);
_appearanceLifeTimeTask = null;
ItemAppearanceTaskManager.getInstance().remove(this);
onVisualLifeTimeEnd();
}
}
@ -2552,25 +2462,22 @@ public class ItemInstance extends WorldObject
public void scheduleVisualLifeTime()
{
if (_appearanceLifeTimeTask != null)
{
_appearanceLifeTimeTask.cancel(false);
}
ItemAppearanceTaskManager.getInstance().remove(this);
if (getVisualLifeTime() > 0)
{
final long time = getVisualLifeTime() - System.currentTimeMillis();
if (time > 0)
final long endTime = getVisualLifeTime();
if ((endTime - System.currentTimeMillis()) > 0)
{
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
ItemAppearanceTaskManager.getInstance().add(this, endTime);
}
else
{
ThreadPool.execute(this::onVisualLifeTimeEnd);
onVisualLifeTimeEnd();
}
}
}
private void onVisualLifeTimeEnd()
public void onVisualLifeTimeEnd()
{
final ItemVariables vars = getVariables();
vars.remove(ItemVariables.VISUAL_ID);

View File

@ -0,0 +1,86 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.buylist.Product;
/**
* @author Mobius
*/
public class BuyListTaskManager
{
private static final Map<Product, Long> PRODUCTS = new ConcurrentHashMap<>();
private static boolean _working = false;
public BuyListTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<Product, Long> entry : PRODUCTS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final Product product = entry.getKey();
PRODUCTS.remove(product);
product.restock();
}
}
_working = false;
}, 1000, 60000);
}
public void add(Product product, long endTime)
{
if (!PRODUCTS.containsKey(product))
{
PRODUCTS.put(product, endTime);
}
}
public void update(Product product, long endTime)
{
PRODUCTS.put(product, endTime);
}
public long getRestockDelay(Product product)
{
return PRODUCTS.getOrDefault(product, 0L);
}
public static BuyListTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final BuyListTaskManager INSTANCE = new BuyListTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemAppearanceTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemAppearanceTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.onVisualLifeTimeEnd();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemAppearanceTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemAppearanceTaskManager INSTANCE = new ItemAppearanceTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemLifeTimeTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemLifeTimeTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.endOfLife();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemLifeTimeTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemLifeTimeTaskManager INSTANCE = new ItemLifeTimeTaskManager();
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemManaTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static final int MANA_CONSUMPTION_RATE = 60000;
private static boolean _working = false;
public ItemManaTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, System.currentTimeMillis() + MANA_CONSUMPTION_RATE);
}
}
public static ItemManaTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemManaTaskManager INSTANCE = new ItemManaTaskManager();
}
}

View File

@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.model.items.Item;
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
/**
* @author NosBit
@ -45,7 +43,6 @@ public class Product
private final long _maxCount;
private final double _baseTax;
private AtomicLong _count = null;
private ScheduledFuture<?> _restockTask = null;
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
{
@ -122,10 +119,9 @@ public class Product
{
return false;
}
if ((_restockTask == null) || _restockTask.isDone())
{
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
}
BuyListTaskManager.getInstance().add(this, _restockDelay);
final boolean result = _count.addAndGet(-value) >= 0;
save();
return result;
@ -141,7 +137,7 @@ public class Product
final long remainTime = nextRestockTime - System.currentTimeMillis();
if (remainTime > 0)
{
_restockTask = ThreadPool.schedule(this::restock, remainTime);
BuyListTaskManager.getInstance().update(this, remainTime);
}
else
{
@ -164,9 +160,10 @@ public class Product
statement.setInt(2, _item.getId());
statement.setLong(3, getCount());
statement.setLong(5, getCount());
if ((_restockTask != null) && (_restockTask.getDelay(TimeUnit.MILLISECONDS) > 0))
final long nextRestockTime = BuyListTaskManager.getInstance().getRestockDelay(this);
if (nextRestockTime > 0)
{
final long nextRestockTime = System.currentTimeMillis() + _restockTask.getDelay(TimeUnit.MILLISECONDS);
statement.setLong(4, nextRestockTime);
statement.setLong(6, nextRestockTime);
}
@ -175,6 +172,7 @@ public class Product
statement.setLong(4, 0);
statement.setLong(6, 0);
}
statement.executeUpdate();
}
catch (Exception e)

View File

@ -34,7 +34,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
@ -91,6 +90,9 @@ import org.l2jmobius.gameserver.network.serverpackets.GetItem;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.ItemAppearanceTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemLifeTimeTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
import org.l2jmobius.gameserver.util.GMAudit;
/**
@ -142,7 +144,6 @@ public class ItemInstance extends WorldObject
/** Shadow item */
private int _mana = -1;
private boolean _consumingMana = false;
private static final int MANA_CONSUMPTION_RATE = 60000;
/** Custom item types (used loto, race tickets) */
private int _type1;
@ -172,8 +173,6 @@ public class ItemInstance extends WorldObject
private Map<AttributeType, AttributeHolder> _elementals = null;
private ScheduledFuture<?> _itemLootShedule = null;
private ScheduledFuture<?> _lifeTimeTask;
private ScheduledFuture<?> _appearanceLifeTimeTask;
private final DropProtection _dropProtection = new DropProtection();
@ -1288,37 +1287,6 @@ public class ItemInstance extends WorldObject
}
}
/**
* Used to decrease mana (mana means life time for shadow items)
*/
public static class ScheduleConsumeManaTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleConsumeManaTask.class.getName());
private final ItemInstance _shadowItem;
public ScheduleConsumeManaTask(ItemInstance item)
{
_shadowItem = item;
}
@Override
public void run()
{
try
{
// decrease mana
if (_shadowItem != null)
{
_shadowItem.decreaseMana(true);
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
}
}
/**
* Returns true if this item is a shadow item Shadow items have a limited life-time
* @return
@ -1463,7 +1431,7 @@ public class ItemInstance extends WorldObject
return;
}
_consumingMana = true;
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
ItemManaTaskManager.getInstance().add(this);
}
/**
@ -1532,64 +1500,46 @@ public class ItemInstance extends WorldObject
* <b><u>Example of use</u>:</b><br>
* <li>Drop item</li>
* <li>Call Pet</li>
* @param dropper
* @param locX
* @param locY
* @param locZ
*/
public class ItemDropTask implements Runnable
public void dropMe(Creature dropper, int locX, int locY, int locZ)
{
private int _x;
private int _y;
private int _z;
private final Creature _dropper;
private final ItemInstance _itеm;
int x = locX;
int y = locY;
int z = locZ;
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
if (dropper != null)
{
_x = x;
_y = y;
_z = z;
_dropper = dropper;
_itеm = item;
final Instance instance = dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
x = dropDest.getX();
y = dropDest.getY();
z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
@Override
public void run()
// Set the x,y,z position of the ItemInstance dropped and update its world region
setSpawned(true);
setXYZ(x, y, z);
setDropTime(System.currentTimeMillis());
setDropperObjectId(dropper != null ? dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(this, getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
if (_dropper != null)
{
final Instance instance = _dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(_dropper.getX(), _dropper.getY(), _dropper.getZ(), _x, _y, _z, instance);
_x = dropDest.getX();
_y = dropDest.getY();
_z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
synchronized (_itеm)
{
// Set the x,y,z position of the ItemInstance dropped and update its _worldregion
_itеm.setSpawned(true);
_itеm.setXYZ(_x, _y, _z);
}
_itеm.setDropTime(System.currentTimeMillis());
_itеm.setDropperObjectId(_dropper != null ? _dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(_itеm, _itеm.getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().save(_itеm);
}
_itеm.setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
ItemsOnGroundManager.getInstance().save(this);
}
}
public void dropMe(Creature dropper, int x, int y, int z)
{
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
if ((dropper != null) && dropper.isPlayer())
{
_owner = null;
@ -1907,38 +1857,7 @@ public class ItemInstance extends WorldObject
}
else
{
if (_lifeTimeTask != null)
{
_lifeTimeTask.cancel(true);
}
_lifeTimeTask = ThreadPool.schedule(new ScheduleLifeTimeTask(this), getRemainingTime());
}
}
static class ScheduleLifeTimeTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleLifeTimeTask.class.getName());
private final ItemInstance _limitedItem;
ScheduleLifeTimeTask(ItemInstance item)
{
_limitedItem = item;
}
@Override
public void run()
{
try
{
if (_limitedItem != null)
{
_limitedItem.endOfLife();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
}
}
@ -2485,16 +2404,8 @@ public class ItemInstance extends WorldObject
public void stopAllTasks()
{
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
{
_lifeTimeTask.cancel(false);
_lifeTimeTask = null;
}
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
{
_appearanceLifeTimeTask.cancel(false);
_appearanceLifeTimeTask = null;
}
ItemLifeTimeTaskManager.getInstance().remove(this);
ItemAppearanceTaskManager.getInstance().remove(this);
}
public ItemVariables getVariables()
@ -2537,10 +2448,9 @@ public class ItemInstance extends WorldObject
getVariables().set(ItemVariables.VISUAL_ID, visualId);
// When removed, cancel existing lifetime task.
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
if (visualId == 0)
{
_appearanceLifeTimeTask.cancel(true);
_appearanceLifeTimeTask = null;
ItemAppearanceTaskManager.getInstance().remove(this);
onVisualLifeTimeEnd();
}
}
@ -2552,25 +2462,22 @@ public class ItemInstance extends WorldObject
public void scheduleVisualLifeTime()
{
if (_appearanceLifeTimeTask != null)
{
_appearanceLifeTimeTask.cancel(false);
}
ItemAppearanceTaskManager.getInstance().remove(this);
if (getVisualLifeTime() > 0)
{
final long time = getVisualLifeTime() - System.currentTimeMillis();
if (time > 0)
final long endTime = getVisualLifeTime();
if ((endTime - System.currentTimeMillis()) > 0)
{
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
ItemAppearanceTaskManager.getInstance().add(this, endTime);
}
else
{
ThreadPool.execute(this::onVisualLifeTimeEnd);
onVisualLifeTimeEnd();
}
}
}
private void onVisualLifeTimeEnd()
public void onVisualLifeTimeEnd()
{
final ItemVariables vars = getVariables();
vars.remove(ItemVariables.VISUAL_ID);

View File

@ -0,0 +1,86 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.buylist.Product;
/**
* @author Mobius
*/
public class BuyListTaskManager
{
private static final Map<Product, Long> PRODUCTS = new ConcurrentHashMap<>();
private static boolean _working = false;
public BuyListTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<Product, Long> entry : PRODUCTS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final Product product = entry.getKey();
PRODUCTS.remove(product);
product.restock();
}
}
_working = false;
}, 1000, 60000);
}
public void add(Product product, long endTime)
{
if (!PRODUCTS.containsKey(product))
{
PRODUCTS.put(product, endTime);
}
}
public void update(Product product, long endTime)
{
PRODUCTS.put(product, endTime);
}
public long getRestockDelay(Product product)
{
return PRODUCTS.getOrDefault(product, 0L);
}
public static BuyListTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final BuyListTaskManager INSTANCE = new BuyListTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemAppearanceTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemAppearanceTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.onVisualLifeTimeEnd();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemAppearanceTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemAppearanceTaskManager INSTANCE = new ItemAppearanceTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemLifeTimeTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemLifeTimeTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.endOfLife();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemLifeTimeTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemLifeTimeTaskManager INSTANCE = new ItemLifeTimeTaskManager();
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemManaTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static final int MANA_CONSUMPTION_RATE = 60000;
private static boolean _working = false;
public ItemManaTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, System.currentTimeMillis() + MANA_CONSUMPTION_RATE);
}
}
public static ItemManaTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemManaTaskManager INSTANCE = new ItemManaTaskManager();
}
}

View File

@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.model.items.Item;
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
/**
* @author NosBit
@ -45,7 +43,6 @@ public class Product
private final long _maxCount;
private final double _baseTax;
private AtomicLong _count = null;
private ScheduledFuture<?> _restockTask = null;
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
{
@ -122,10 +119,9 @@ public class Product
{
return false;
}
if ((_restockTask == null) || _restockTask.isDone())
{
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
}
BuyListTaskManager.getInstance().add(this, _restockDelay);
final boolean result = _count.addAndGet(-value) >= 0;
save();
return result;
@ -141,7 +137,7 @@ public class Product
final long remainTime = nextRestockTime - System.currentTimeMillis();
if (remainTime > 0)
{
_restockTask = ThreadPool.schedule(this::restock, remainTime);
BuyListTaskManager.getInstance().update(this, remainTime);
}
else
{
@ -164,9 +160,10 @@ public class Product
statement.setInt(2, _item.getId());
statement.setLong(3, getCount());
statement.setLong(5, getCount());
if ((_restockTask != null) && (_restockTask.getDelay(TimeUnit.MILLISECONDS) > 0))
final long nextRestockTime = BuyListTaskManager.getInstance().getRestockDelay(this);
if (nextRestockTime > 0)
{
final long nextRestockTime = System.currentTimeMillis() + _restockTask.getDelay(TimeUnit.MILLISECONDS);
statement.setLong(4, nextRestockTime);
statement.setLong(6, nextRestockTime);
}
@ -175,6 +172,7 @@ public class Product
statement.setLong(4, 0);
statement.setLong(6, 0);
}
statement.executeUpdate();
}
catch (Exception e)

View File

@ -34,7 +34,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
@ -91,6 +90,9 @@ import org.l2jmobius.gameserver.network.serverpackets.GetItem;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.ItemAppearanceTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemLifeTimeTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
import org.l2jmobius.gameserver.util.GMAudit;
/**
@ -142,7 +144,6 @@ public class ItemInstance extends WorldObject
/** Shadow item */
private int _mana = -1;
private boolean _consumingMana = false;
private static final int MANA_CONSUMPTION_RATE = 60000;
/** Custom item types (used loto, race tickets) */
private int _type1;
@ -172,8 +173,6 @@ public class ItemInstance extends WorldObject
private Map<AttributeType, AttributeHolder> _elementals = null;
private ScheduledFuture<?> _itemLootShedule = null;
private ScheduledFuture<?> _lifeTimeTask;
private ScheduledFuture<?> _appearanceLifeTimeTask;
private final DropProtection _dropProtection = new DropProtection();
@ -1288,37 +1287,6 @@ public class ItemInstance extends WorldObject
}
}
/**
* Used to decrease mana (mana means life time for shadow items)
*/
public static class ScheduleConsumeManaTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleConsumeManaTask.class.getName());
private final ItemInstance _shadowItem;
public ScheduleConsumeManaTask(ItemInstance item)
{
_shadowItem = item;
}
@Override
public void run()
{
try
{
// decrease mana
if (_shadowItem != null)
{
_shadowItem.decreaseMana(true);
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
}
}
/**
* Returns true if this item is a shadow item Shadow items have a limited life-time
* @return
@ -1463,7 +1431,7 @@ public class ItemInstance extends WorldObject
return;
}
_consumingMana = true;
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
ItemManaTaskManager.getInstance().add(this);
}
/**
@ -1532,64 +1500,46 @@ public class ItemInstance extends WorldObject
* <b><u>Example of use</u>:</b><br>
* <li>Drop item</li>
* <li>Call Pet</li>
* @param dropper
* @param locX
* @param locY
* @param locZ
*/
public class ItemDropTask implements Runnable
public void dropMe(Creature dropper, int locX, int locY, int locZ)
{
private int _x;
private int _y;
private int _z;
private final Creature _dropper;
private final ItemInstance _itеm;
int x = locX;
int y = locY;
int z = locZ;
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
if (dropper != null)
{
_x = x;
_y = y;
_z = z;
_dropper = dropper;
_itеm = item;
final Instance instance = dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
x = dropDest.getX();
y = dropDest.getY();
z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
@Override
public void run()
// Set the x,y,z position of the ItemInstance dropped and update its world region
setSpawned(true);
setXYZ(x, y, z);
setDropTime(System.currentTimeMillis());
setDropperObjectId(dropper != null ? dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(this, getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
if (_dropper != null)
{
final Instance instance = _dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(_dropper.getX(), _dropper.getY(), _dropper.getZ(), _x, _y, _z, instance);
_x = dropDest.getX();
_y = dropDest.getY();
_z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
synchronized (_itеm)
{
// Set the x,y,z position of the ItemInstance dropped and update its _worldregion
_itеm.setSpawned(true);
_itеm.setXYZ(_x, _y, _z);
}
_itеm.setDropTime(System.currentTimeMillis());
_itеm.setDropperObjectId(_dropper != null ? _dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(_itеm, _itеm.getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().save(_itеm);
}
_itеm.setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
ItemsOnGroundManager.getInstance().save(this);
}
}
public void dropMe(Creature dropper, int x, int y, int z)
{
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
if ((dropper != null) && dropper.isPlayer())
{
_owner = null;
@ -1907,38 +1857,7 @@ public class ItemInstance extends WorldObject
}
else
{
if (_lifeTimeTask != null)
{
_lifeTimeTask.cancel(true);
}
_lifeTimeTask = ThreadPool.schedule(new ScheduleLifeTimeTask(this), getRemainingTime());
}
}
static class ScheduleLifeTimeTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleLifeTimeTask.class.getName());
private final ItemInstance _limitedItem;
ScheduleLifeTimeTask(ItemInstance item)
{
_limitedItem = item;
}
@Override
public void run()
{
try
{
if (_limitedItem != null)
{
_limitedItem.endOfLife();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
}
}
@ -2485,16 +2404,8 @@ public class ItemInstance extends WorldObject
public void stopAllTasks()
{
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
{
_lifeTimeTask.cancel(false);
_lifeTimeTask = null;
}
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
{
_appearanceLifeTimeTask.cancel(false);
_appearanceLifeTimeTask = null;
}
ItemLifeTimeTaskManager.getInstance().remove(this);
ItemAppearanceTaskManager.getInstance().remove(this);
}
public ItemVariables getVariables()
@ -2537,10 +2448,9 @@ public class ItemInstance extends WorldObject
getVariables().set(ItemVariables.VISUAL_ID, visualId);
// When removed, cancel existing lifetime task.
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
if (visualId == 0)
{
_appearanceLifeTimeTask.cancel(true);
_appearanceLifeTimeTask = null;
ItemAppearanceTaskManager.getInstance().remove(this);
onVisualLifeTimeEnd();
}
}
@ -2552,25 +2462,22 @@ public class ItemInstance extends WorldObject
public void scheduleVisualLifeTime()
{
if (_appearanceLifeTimeTask != null)
{
_appearanceLifeTimeTask.cancel(false);
}
ItemAppearanceTaskManager.getInstance().remove(this);
if (getVisualLifeTime() > 0)
{
final long time = getVisualLifeTime() - System.currentTimeMillis();
if (time > 0)
final long endTime = getVisualLifeTime();
if ((endTime - System.currentTimeMillis()) > 0)
{
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
ItemAppearanceTaskManager.getInstance().add(this, endTime);
}
else
{
ThreadPool.execute(this::onVisualLifeTimeEnd);
onVisualLifeTimeEnd();
}
}
}
private void onVisualLifeTimeEnd()
public void onVisualLifeTimeEnd()
{
final ItemVariables vars = getVariables();
vars.remove(ItemVariables.VISUAL_ID);

View File

@ -0,0 +1,86 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.buylist.Product;
/**
* @author Mobius
*/
public class BuyListTaskManager
{
private static final Map<Product, Long> PRODUCTS = new ConcurrentHashMap<>();
private static boolean _working = false;
public BuyListTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<Product, Long> entry : PRODUCTS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final Product product = entry.getKey();
PRODUCTS.remove(product);
product.restock();
}
}
_working = false;
}, 1000, 60000);
}
public void add(Product product, long endTime)
{
if (!PRODUCTS.containsKey(product))
{
PRODUCTS.put(product, endTime);
}
}
public void update(Product product, long endTime)
{
PRODUCTS.put(product, endTime);
}
public long getRestockDelay(Product product)
{
return PRODUCTS.getOrDefault(product, 0L);
}
public static BuyListTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final BuyListTaskManager INSTANCE = new BuyListTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemAppearanceTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemAppearanceTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.onVisualLifeTimeEnd();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemAppearanceTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemAppearanceTaskManager INSTANCE = new ItemAppearanceTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemLifeTimeTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemLifeTimeTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.endOfLife();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemLifeTimeTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemLifeTimeTaskManager INSTANCE = new ItemLifeTimeTaskManager();
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemManaTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static final int MANA_CONSUMPTION_RATE = 60000;
private static boolean _working = false;
public ItemManaTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, System.currentTimeMillis() + MANA_CONSUMPTION_RATE);
}
}
public static ItemManaTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemManaTaskManager INSTANCE = new ItemManaTaskManager();
}
}

View File

@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.model.items.Item;
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
/**
* @author NosBit
@ -45,7 +43,6 @@ public class Product
private final long _maxCount;
private final double _baseTax;
private AtomicLong _count = null;
private ScheduledFuture<?> _restockTask = null;
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
{
@ -122,10 +119,9 @@ public class Product
{
return false;
}
if ((_restockTask == null) || _restockTask.isDone())
{
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
}
BuyListTaskManager.getInstance().add(this, _restockDelay);
final boolean result = _count.addAndGet(-value) >= 0;
save();
return result;
@ -141,7 +137,7 @@ public class Product
final long remainTime = nextRestockTime - System.currentTimeMillis();
if (remainTime > 0)
{
_restockTask = ThreadPool.schedule(this::restock, remainTime);
BuyListTaskManager.getInstance().update(this, remainTime);
}
else
{
@ -164,9 +160,10 @@ public class Product
statement.setInt(2, _item.getId());
statement.setLong(3, getCount());
statement.setLong(5, getCount());
if ((_restockTask != null) && (_restockTask.getDelay(TimeUnit.MILLISECONDS) > 0))
final long nextRestockTime = BuyListTaskManager.getInstance().getRestockDelay(this);
if (nextRestockTime > 0)
{
final long nextRestockTime = System.currentTimeMillis() + _restockTask.getDelay(TimeUnit.MILLISECONDS);
statement.setLong(4, nextRestockTime);
statement.setLong(6, nextRestockTime);
}
@ -175,6 +172,7 @@ public class Product
statement.setLong(4, 0);
statement.setLong(6, 0);
}
statement.executeUpdate();
}
catch (Exception e)

View File

@ -34,7 +34,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
@ -91,6 +90,9 @@ import org.l2jmobius.gameserver.network.serverpackets.GetItem;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.ItemAppearanceTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemLifeTimeTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
import org.l2jmobius.gameserver.util.GMAudit;
/**
@ -142,7 +144,6 @@ public class ItemInstance extends WorldObject
/** Shadow item */
private int _mana = -1;
private boolean _consumingMana = false;
private static final int MANA_CONSUMPTION_RATE = 60000;
/** Custom item types (used loto, race tickets) */
private int _type1;
@ -172,8 +173,6 @@ public class ItemInstance extends WorldObject
private Map<AttributeType, AttributeHolder> _elementals = null;
private ScheduledFuture<?> _itemLootShedule = null;
private ScheduledFuture<?> _lifeTimeTask;
private ScheduledFuture<?> _appearanceLifeTimeTask;
private final DropProtection _dropProtection = new DropProtection();
@ -1288,37 +1287,6 @@ public class ItemInstance extends WorldObject
}
}
/**
* Used to decrease mana (mana means life time for shadow items)
*/
public static class ScheduleConsumeManaTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleConsumeManaTask.class.getName());
private final ItemInstance _shadowItem;
public ScheduleConsumeManaTask(ItemInstance item)
{
_shadowItem = item;
}
@Override
public void run()
{
try
{
// decrease mana
if (_shadowItem != null)
{
_shadowItem.decreaseMana(true);
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
}
}
/**
* Returns true if this item is a shadow item Shadow items have a limited life-time
* @return
@ -1463,7 +1431,7 @@ public class ItemInstance extends WorldObject
return;
}
_consumingMana = true;
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
ItemManaTaskManager.getInstance().add(this);
}
/**
@ -1532,64 +1500,46 @@ public class ItemInstance extends WorldObject
* <b><u>Example of use</u>:</b><br>
* <li>Drop item</li>
* <li>Call Pet</li>
* @param dropper
* @param locX
* @param locY
* @param locZ
*/
public class ItemDropTask implements Runnable
public void dropMe(Creature dropper, int locX, int locY, int locZ)
{
private int _x;
private int _y;
private int _z;
private final Creature _dropper;
private final ItemInstance _itеm;
int x = locX;
int y = locY;
int z = locZ;
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
if (dropper != null)
{
_x = x;
_y = y;
_z = z;
_dropper = dropper;
_itеm = item;
final Instance instance = dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
x = dropDest.getX();
y = dropDest.getY();
z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
@Override
public void run()
// Set the x,y,z position of the ItemInstance dropped and update its world region
setSpawned(true);
setXYZ(x, y, z);
setDropTime(System.currentTimeMillis());
setDropperObjectId(dropper != null ? dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(this, getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
if (_dropper != null)
{
final Instance instance = _dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(_dropper.getX(), _dropper.getY(), _dropper.getZ(), _x, _y, _z, instance);
_x = dropDest.getX();
_y = dropDest.getY();
_z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
synchronized (_itеm)
{
// Set the x,y,z position of the ItemInstance dropped and update its _worldregion
_itеm.setSpawned(true);
_itеm.setXYZ(_x, _y, _z);
}
_itеm.setDropTime(System.currentTimeMillis());
_itеm.setDropperObjectId(_dropper != null ? _dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(_itеm, _itеm.getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().save(_itеm);
}
_itеm.setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
ItemsOnGroundManager.getInstance().save(this);
}
}
public void dropMe(Creature dropper, int x, int y, int z)
{
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
if ((dropper != null) && dropper.isPlayer())
{
_owner = null;
@ -1907,38 +1857,7 @@ public class ItemInstance extends WorldObject
}
else
{
if (_lifeTimeTask != null)
{
_lifeTimeTask.cancel(true);
}
_lifeTimeTask = ThreadPool.schedule(new ScheduleLifeTimeTask(this), getRemainingTime());
}
}
static class ScheduleLifeTimeTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleLifeTimeTask.class.getName());
private final ItemInstance _limitedItem;
ScheduleLifeTimeTask(ItemInstance item)
{
_limitedItem = item;
}
@Override
public void run()
{
try
{
if (_limitedItem != null)
{
_limitedItem.endOfLife();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
}
}
@ -2485,16 +2404,8 @@ public class ItemInstance extends WorldObject
public void stopAllTasks()
{
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
{
_lifeTimeTask.cancel(false);
_lifeTimeTask = null;
}
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
{
_appearanceLifeTimeTask.cancel(false);
_appearanceLifeTimeTask = null;
}
ItemLifeTimeTaskManager.getInstance().remove(this);
ItemAppearanceTaskManager.getInstance().remove(this);
}
public ItemVariables getVariables()
@ -2537,10 +2448,9 @@ public class ItemInstance extends WorldObject
getVariables().set(ItemVariables.VISUAL_ID, visualId);
// When removed, cancel existing lifetime task.
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
if (visualId == 0)
{
_appearanceLifeTimeTask.cancel(true);
_appearanceLifeTimeTask = null;
ItemAppearanceTaskManager.getInstance().remove(this);
onVisualLifeTimeEnd();
}
}
@ -2552,25 +2462,22 @@ public class ItemInstance extends WorldObject
public void scheduleVisualLifeTime()
{
if (_appearanceLifeTimeTask != null)
{
_appearanceLifeTimeTask.cancel(false);
}
ItemAppearanceTaskManager.getInstance().remove(this);
if (getVisualLifeTime() > 0)
{
final long time = getVisualLifeTime() - System.currentTimeMillis();
if (time > 0)
final long endTime = getVisualLifeTime();
if ((endTime - System.currentTimeMillis()) > 0)
{
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
ItemAppearanceTaskManager.getInstance().add(this, endTime);
}
else
{
ThreadPool.execute(this::onVisualLifeTimeEnd);
onVisualLifeTimeEnd();
}
}
}
private void onVisualLifeTimeEnd()
public void onVisualLifeTimeEnd()
{
final ItemVariables vars = getVariables();
vars.remove(ItemVariables.VISUAL_ID);

View File

@ -0,0 +1,86 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.buylist.Product;
/**
* @author Mobius
*/
public class BuyListTaskManager
{
private static final Map<Product, Long> PRODUCTS = new ConcurrentHashMap<>();
private static boolean _working = false;
public BuyListTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<Product, Long> entry : PRODUCTS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final Product product = entry.getKey();
PRODUCTS.remove(product);
product.restock();
}
}
_working = false;
}, 1000, 60000);
}
public void add(Product product, long endTime)
{
if (!PRODUCTS.containsKey(product))
{
PRODUCTS.put(product, endTime);
}
}
public void update(Product product, long endTime)
{
PRODUCTS.put(product, endTime);
}
public long getRestockDelay(Product product)
{
return PRODUCTS.getOrDefault(product, 0L);
}
public static BuyListTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final BuyListTaskManager INSTANCE = new BuyListTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemAppearanceTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemAppearanceTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.onVisualLifeTimeEnd();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemAppearanceTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemAppearanceTaskManager INSTANCE = new ItemAppearanceTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemLifeTimeTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemLifeTimeTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.endOfLife();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemLifeTimeTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemLifeTimeTaskManager INSTANCE = new ItemLifeTimeTaskManager();
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemManaTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static final int MANA_CONSUMPTION_RATE = 60000;
private static boolean _working = false;
public ItemManaTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, System.currentTimeMillis() + MANA_CONSUMPTION_RATE);
}
}
public static ItemManaTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemManaTaskManager INSTANCE = new ItemManaTaskManager();
}
}

View File

@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.model.items.Item;
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
/**
* @author NosBit
@ -45,7 +43,6 @@ public class Product
private final long _maxCount;
private final double _baseTax;
private AtomicLong _count = null;
private ScheduledFuture<?> _restockTask = null;
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
{
@ -122,10 +119,9 @@ public class Product
{
return false;
}
if ((_restockTask == null) || _restockTask.isDone())
{
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
}
BuyListTaskManager.getInstance().add(this, _restockDelay);
final boolean result = _count.addAndGet(-value) >= 0;
save();
return result;
@ -141,7 +137,7 @@ public class Product
final long remainTime = nextRestockTime - System.currentTimeMillis();
if (remainTime > 0)
{
_restockTask = ThreadPool.schedule(this::restock, remainTime);
BuyListTaskManager.getInstance().update(this, remainTime);
}
else
{
@ -164,9 +160,10 @@ public class Product
statement.setInt(2, _item.getId());
statement.setLong(3, getCount());
statement.setLong(5, getCount());
if ((_restockTask != null) && (_restockTask.getDelay(TimeUnit.MILLISECONDS) > 0))
final long nextRestockTime = BuyListTaskManager.getInstance().getRestockDelay(this);
if (nextRestockTime > 0)
{
final long nextRestockTime = System.currentTimeMillis() + _restockTask.getDelay(TimeUnit.MILLISECONDS);
statement.setLong(4, nextRestockTime);
statement.setLong(6, nextRestockTime);
}
@ -175,6 +172,7 @@ public class Product
statement.setLong(4, 0);
statement.setLong(6, 0);
}
statement.executeUpdate();
}
catch (Exception e)

View File

@ -34,7 +34,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
@ -91,6 +90,9 @@ import org.l2jmobius.gameserver.network.serverpackets.GetItem;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.ItemAppearanceTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemLifeTimeTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
import org.l2jmobius.gameserver.util.GMAudit;
/**
@ -142,7 +144,6 @@ public class ItemInstance extends WorldObject
/** Shadow item */
private int _mana = -1;
private boolean _consumingMana = false;
private static final int MANA_CONSUMPTION_RATE = 60000;
/** Custom item types (used loto, race tickets) */
private int _type1;
@ -172,8 +173,6 @@ public class ItemInstance extends WorldObject
private Map<AttributeType, AttributeHolder> _elementals = null;
private ScheduledFuture<?> _itemLootShedule = null;
private ScheduledFuture<?> _lifeTimeTask;
private ScheduledFuture<?> _appearanceLifeTimeTask;
private final DropProtection _dropProtection = new DropProtection();
@ -1288,37 +1287,6 @@ public class ItemInstance extends WorldObject
}
}
/**
* Used to decrease mana (mana means life time for shadow items)
*/
public static class ScheduleConsumeManaTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleConsumeManaTask.class.getName());
private final ItemInstance _shadowItem;
public ScheduleConsumeManaTask(ItemInstance item)
{
_shadowItem = item;
}
@Override
public void run()
{
try
{
// decrease mana
if (_shadowItem != null)
{
_shadowItem.decreaseMana(true);
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
}
}
/**
* Returns true if this item is a shadow item Shadow items have a limited life-time
* @return
@ -1463,7 +1431,7 @@ public class ItemInstance extends WorldObject
return;
}
_consumingMana = true;
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
ItemManaTaskManager.getInstance().add(this);
}
/**
@ -1532,64 +1500,46 @@ public class ItemInstance extends WorldObject
* <b><u>Example of use</u>:</b><br>
* <li>Drop item</li>
* <li>Call Pet</li>
* @param dropper
* @param locX
* @param locY
* @param locZ
*/
public class ItemDropTask implements Runnable
public void dropMe(Creature dropper, int locX, int locY, int locZ)
{
private int _x;
private int _y;
private int _z;
private final Creature _dropper;
private final ItemInstance _itеm;
int x = locX;
int y = locY;
int z = locZ;
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
if (dropper != null)
{
_x = x;
_y = y;
_z = z;
_dropper = dropper;
_itеm = item;
final Instance instance = dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
x = dropDest.getX();
y = dropDest.getY();
z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
@Override
public void run()
// Set the x,y,z position of the ItemInstance dropped and update its world region
setSpawned(true);
setXYZ(x, y, z);
setDropTime(System.currentTimeMillis());
setDropperObjectId(dropper != null ? dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(this, getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
if (_dropper != null)
{
final Instance instance = _dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(_dropper.getX(), _dropper.getY(), _dropper.getZ(), _x, _y, _z, instance);
_x = dropDest.getX();
_y = dropDest.getY();
_z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
synchronized (_itеm)
{
// Set the x,y,z position of the ItemInstance dropped and update its _worldregion
_itеm.setSpawned(true);
_itеm.setXYZ(_x, _y, _z);
}
_itеm.setDropTime(System.currentTimeMillis());
_itеm.setDropperObjectId(_dropper != null ? _dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(_itеm, _itеm.getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().save(_itеm);
}
_itеm.setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
ItemsOnGroundManager.getInstance().save(this);
}
}
public void dropMe(Creature dropper, int x, int y, int z)
{
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
if ((dropper != null) && dropper.isPlayer())
{
_owner = null;
@ -1907,38 +1857,7 @@ public class ItemInstance extends WorldObject
}
else
{
if (_lifeTimeTask != null)
{
_lifeTimeTask.cancel(true);
}
_lifeTimeTask = ThreadPool.schedule(new ScheduleLifeTimeTask(this), getRemainingTime());
}
}
static class ScheduleLifeTimeTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleLifeTimeTask.class.getName());
private final ItemInstance _limitedItem;
ScheduleLifeTimeTask(ItemInstance item)
{
_limitedItem = item;
}
@Override
public void run()
{
try
{
if (_limitedItem != null)
{
_limitedItem.endOfLife();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
}
}
@ -2485,16 +2404,8 @@ public class ItemInstance extends WorldObject
public void stopAllTasks()
{
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
{
_lifeTimeTask.cancel(false);
_lifeTimeTask = null;
}
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
{
_appearanceLifeTimeTask.cancel(false);
_appearanceLifeTimeTask = null;
}
ItemLifeTimeTaskManager.getInstance().remove(this);
ItemAppearanceTaskManager.getInstance().remove(this);
}
public ItemVariables getVariables()
@ -2537,10 +2448,9 @@ public class ItemInstance extends WorldObject
getVariables().set(ItemVariables.VISUAL_ID, visualId);
// When removed, cancel existing lifetime task.
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
if (visualId == 0)
{
_appearanceLifeTimeTask.cancel(true);
_appearanceLifeTimeTask = null;
ItemAppearanceTaskManager.getInstance().remove(this);
onVisualLifeTimeEnd();
}
}
@ -2552,25 +2462,22 @@ public class ItemInstance extends WorldObject
public void scheduleVisualLifeTime()
{
if (_appearanceLifeTimeTask != null)
{
_appearanceLifeTimeTask.cancel(false);
}
ItemAppearanceTaskManager.getInstance().remove(this);
if (getVisualLifeTime() > 0)
{
final long time = getVisualLifeTime() - System.currentTimeMillis();
if (time > 0)
final long endTime = getVisualLifeTime();
if ((endTime - System.currentTimeMillis()) > 0)
{
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
ItemAppearanceTaskManager.getInstance().add(this, endTime);
}
else
{
ThreadPool.execute(this::onVisualLifeTimeEnd);
onVisualLifeTimeEnd();
}
}
}
private void onVisualLifeTimeEnd()
public void onVisualLifeTimeEnd()
{
final ItemVariables vars = getVariables();
vars.remove(ItemVariables.VISUAL_ID);

View File

@ -0,0 +1,86 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.buylist.Product;
/**
* @author Mobius
*/
public class BuyListTaskManager
{
private static final Map<Product, Long> PRODUCTS = new ConcurrentHashMap<>();
private static boolean _working = false;
public BuyListTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<Product, Long> entry : PRODUCTS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final Product product = entry.getKey();
PRODUCTS.remove(product);
product.restock();
}
}
_working = false;
}, 1000, 60000);
}
public void add(Product product, long endTime)
{
if (!PRODUCTS.containsKey(product))
{
PRODUCTS.put(product, endTime);
}
}
public void update(Product product, long endTime)
{
PRODUCTS.put(product, endTime);
}
public long getRestockDelay(Product product)
{
return PRODUCTS.getOrDefault(product, 0L);
}
public static BuyListTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final BuyListTaskManager INSTANCE = new BuyListTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemAppearanceTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemAppearanceTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.onVisualLifeTimeEnd();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemAppearanceTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemAppearanceTaskManager INSTANCE = new ItemAppearanceTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemLifeTimeTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemLifeTimeTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.endOfLife();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemLifeTimeTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemLifeTimeTaskManager INSTANCE = new ItemLifeTimeTaskManager();
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemManaTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static final int MANA_CONSUMPTION_RATE = 60000;
private static boolean _working = false;
public ItemManaTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, System.currentTimeMillis() + MANA_CONSUMPTION_RATE);
}
}
public static ItemManaTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemManaTaskManager INSTANCE = new ItemManaTaskManager();
}
}

View File

@ -25,7 +25,6 @@ import java.util.logging.LogRecord;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.data.ItemTable;
@ -48,6 +47,7 @@ import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
import org.l2jmobius.gameserver.util.IllegalPlayerAction;
import org.l2jmobius.gameserver.util.Util;
@ -92,7 +92,6 @@ public class ItemInstance extends WorldObject
private boolean _wear;
private int _mana = -1;
private boolean _consumingMana = false;
private static final int MANA_CONSUMPTION_RATE = 60000;
private int _type1;
private int _type2;
private long _dropTime;
@ -653,39 +652,6 @@ public class ItemInstance extends WorldObject
return 0;
}
/**
* Used to decrease mana (mana means life time for shadow items).
*/
public class ScheduleConsumeManaTask implements Runnable
{
private final ItemInstance _shadowItem;
/**
* Instantiates a new schedule consume mana task.
* @param item the item
*/
public ScheduleConsumeManaTask(ItemInstance item)
{
_shadowItem = item;
}
@Override
public void run()
{
try
{
// decrease mana
if (_shadowItem != null)
{
_shadowItem.decreaseMana(true);
}
}
catch (Throwable t)
{
}
}
}
/**
* Returns true if this item is a shadow item Shadow items have a limited life-time.
* @return true, if is shadow item
@ -834,7 +800,7 @@ public class ItemInstance extends WorldObject
private void scheduleConsumeManaTask()
{
_consumingMana = true;
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
ItemManaTaskManager.getInstance().add(this);
}
/**

View File

@ -0,0 +1,77 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemManaTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static final int MANA_CONSUMPTION_RATE = 60000;
private static boolean _working = false;
public ItemManaTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, System.currentTimeMillis() + MANA_CONSUMPTION_RATE);
}
}
public static ItemManaTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemManaTaskManager INSTANCE = new ItemManaTaskManager();
}
}

View File

@ -25,7 +25,6 @@ import java.util.logging.LogRecord;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.data.ItemTable;
@ -49,6 +48,7 @@ import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
import org.l2jmobius.gameserver.util.IllegalPlayerAction;
import org.l2jmobius.gameserver.util.Util;
@ -94,7 +94,6 @@ public class ItemInstance extends WorldObject
private Augmentation _augmentation = null;
private int _mana = -1;
private boolean _consumingMana = false;
private static final int MANA_CONSUMPTION_RATE = 60000;
private int _type1;
private int _type2;
private long _dropTime;
@ -702,39 +701,6 @@ public class ItemInstance extends WorldObject
_augmentation = null;
}
/**
* Used to decrease mana (mana means life time for shadow items).
*/
public class ScheduleConsumeManaTask implements Runnable
{
private final ItemInstance _shadowItem;
/**
* Instantiates a new schedule consume mana task.
* @param item the item
*/
public ScheduleConsumeManaTask(ItemInstance item)
{
_shadowItem = item;
}
@Override
public void run()
{
try
{
// decrease mana
if (_shadowItem != null)
{
_shadowItem.decreaseMana(true);
}
}
catch (Throwable t)
{
}
}
}
/**
* Returns true if this item is a shadow item Shadow items have a limited life-time.
* @return true, if is shadow item
@ -883,7 +849,7 @@ public class ItemInstance extends WorldObject
private void scheduleConsumeManaTask()
{
_consumingMana = true;
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
ItemManaTaskManager.getInstance().add(this);
}
/**

View File

@ -0,0 +1,77 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemManaTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static final int MANA_CONSUMPTION_RATE = 60000;
private static boolean _working = false;
public ItemManaTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, System.currentTimeMillis() + MANA_CONSUMPTION_RATE);
}
}
public static ItemManaTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemManaTaskManager INSTANCE = new ItemManaTaskManager();
}
}

View File

@ -18,15 +18,13 @@ package org.l2jmobius.gameserver.model.buylist;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.model.items.Item;
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
/**
* @author NosBit
@ -41,7 +39,6 @@ public class Product
private final long _restockDelay;
private final long _maxCount;
private AtomicLong _count = null;
private ScheduledFuture<?> _restockTask = null;
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount)
{
@ -111,10 +108,9 @@ public class Product
{
return false;
}
if ((_restockTask == null) || _restockTask.isDone())
{
_restockTask = ThreadPool.schedule(new RestockTask(), _restockDelay);
}
BuyListTaskManager.getInstance().add(this, _restockDelay);
final boolean result = _count.addAndGet(-value) >= 0;
save();
return result;
@ -130,7 +126,7 @@ public class Product
final long remainTime = nextRestockTime - System.currentTimeMillis();
if (remainTime > 0)
{
_restockTask = ThreadPool.schedule(new RestockTask(), remainTime);
BuyListTaskManager.getInstance().update(this, remainTime);
}
else
{
@ -144,36 +140,29 @@ public class Product
save();
}
protected final class RestockTask implements Runnable
{
@Override
public void run()
{
restock();
}
}
private void save()
{
try (Connection con = DatabaseFactory.getConnection();
PreparedStatement ps = con.prepareStatement("INSERT INTO `buylists`(`buylist_id`, `item_id`, `count`, `next_restock_time`) VALUES(?, ?, ?, ?) ON DUPLICATE KEY UPDATE `count` = ?, `next_restock_time` = ?"))
PreparedStatement statement = con.prepareStatement("INSERT INTO `buylists`(`buylist_id`, `item_id`, `count`, `next_restock_time`) VALUES(?, ?, ?, ?) ON DUPLICATE KEY UPDATE `count` = ?, `next_restock_time` = ?"))
{
ps.setInt(1, _buyListId);
ps.setInt(2, _item.getId());
ps.setLong(3, getCount());
ps.setLong(5, getCount());
if ((_restockTask != null) && (_restockTask.getDelay(TimeUnit.MILLISECONDS) > 0))
statement.setInt(1, _buyListId);
statement.setInt(2, _item.getId());
statement.setLong(3, getCount());
statement.setLong(5, getCount());
final long nextRestockTime = BuyListTaskManager.getInstance().getRestockDelay(this);
if (nextRestockTime > 0)
{
final long nextRestockTime = System.currentTimeMillis() + _restockTask.getDelay(TimeUnit.MILLISECONDS);
ps.setLong(4, nextRestockTime);
ps.setLong(6, nextRestockTime);
statement.setLong(4, nextRestockTime);
statement.setLong(6, nextRestockTime);
}
else
{
ps.setLong(4, 0);
ps.setLong(6, 0);
statement.setLong(4, 0);
statement.setLong(6, 0);
}
ps.executeUpdate();
statement.executeUpdate();
}
catch (Exception e)
{

View File

@ -31,7 +31,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.EnchantItemOptionsData;
@ -76,6 +75,8 @@ import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
import org.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.ItemLifeTimeTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
import org.l2jmobius.gameserver.util.GMAudit;
/**
@ -127,7 +128,6 @@ public class ItemInstance extends WorldObject
/** Shadow item */
private int _mana = -1;
private boolean _consumingMana = false;
private static final int MANA_CONSUMPTION_RATE = 60000;
/** Custom item types (used loto, race tickets) */
private int _type1;
@ -157,7 +157,6 @@ public class ItemInstance extends WorldObject
private Elementals[] _elementals = null;
private ScheduledFuture<?> _itemLootShedule = null;
private ScheduledFuture<?> _lifeTimeTask;
private final DropProtection _dropProtection = new DropProtection();
@ -1207,37 +1206,6 @@ public class ItemInstance extends WorldObject
}
}
/**
* Used to decrease mana (mana means life time for shadow items)
*/
public static class ScheduleConsumeManaTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleConsumeManaTask.class.getName());
private final ItemInstance _shadowItem;
public ScheduleConsumeManaTask(ItemInstance item)
{
_shadowItem = item;
}
@Override
public void run()
{
try
{
// decrease mana
if (_shadowItem != null)
{
_shadowItem.decreaseMana(true);
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
}
}
/**
* Returns true if this item is a shadow item Shadow items have a limited life-time
* @return
@ -1393,7 +1361,7 @@ public class ItemInstance extends WorldObject
return;
}
_consumingMana = true;
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
ItemManaTaskManager.getInstance().add(this);
}
/**
@ -1539,69 +1507,53 @@ public class ItemInstance extends WorldObject
* <b><u>Example of use</u>:</b><br>
* <li>Drop item</li>
* <li>Call Pet</li>
* @param dropper
* @param locX
* @param locY
* @param locZ
*/
public class ItemDropTask implements Runnable
public void dropMe(Creature dropper, int locX, int locY, int locZ)
{
private int _x;
private int _y;
private int _z;
private final Creature _dropper;
private final ItemInstance _itm;
int x = locX;
int y = locY;
int z = locZ;
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
if (dropper != null)
{
_x = x;
_y = y;
_z = z;
_dropper = dropper;
_itm = item;
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, dropper.getInstanceId());
x = dropDest.getX();
y = dropDest.getY();
z = dropDest.getZ();
}
@Override
public void run()
if (dropper != null)
{
if (_dropper != null)
{
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(_dropper.getX(), _dropper.getY(), _dropper.getZ(), _x, _y, _z, _dropper.getInstanceId());
_x = dropDest.getX();
_y = dropDest.getY();
_z = dropDest.getZ();
}
if (_dropper != null)
{
setInstanceId(_dropper.getInstanceId()); // Inherit instancezone when dropped in visible world
}
else
{
setInstanceId(0); // No dropper? Make it a global item...
}
synchronized (_itm)
{
// Set the x,y,z position of the ItemInstance dropped and update its _worldregion
_itm.setSpawned(true);
_itm.setXYZ(_x, _y, _z);
}
_itm.setDropTime(System.currentTimeMillis());
_itm.setDropperObjectId(_dropper != null ? _dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(_itm, _itm.getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().save(_itm);
}
_itm.setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
setInstanceId(dropper.getInstanceId()); // Inherit instancezone when dropped in visible world
}
}
public void dropMe(Creature dropper, int x, int y, int z)
{
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
else
{
setInstanceId(0); // No dropper? Make it a global item...
}
// Set the x,y,z position of the ItemInstance dropped and update its world region
setSpawned(true);
setXYZ(x, y, z);
setDropTime(System.currentTimeMillis());
setDropperObjectId(dropper != null ? dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(this, getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().save(this);
}
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
if ((dropper != null) && dropper.isPlayer())
{
_owner = null;
// Notify to scripts
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerItemDrop(dropper.getActingPlayer(), this, new Location(x, y, z)), getItem());
}
@ -1870,38 +1822,7 @@ public class ItemInstance extends WorldObject
}
else
{
if (_lifeTimeTask != null)
{
_lifeTimeTask.cancel(true);
}
_lifeTimeTask = ThreadPool.schedule(new ScheduleLifeTimeTask(this), getRemainingTime());
}
}
public static class ScheduleLifeTimeTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleLifeTimeTask.class.getName());
private final ItemInstance _limitedItem;
public ScheduleLifeTimeTask(ItemInstance item)
{
_limitedItem = item;
}
@Override
public void run()
{
try
{
if (_limitedItem != null)
{
_limitedItem.endOfLife();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
}
}
@ -2199,10 +2120,6 @@ public class ItemInstance extends WorldObject
public void stopAllTasks()
{
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
{
_lifeTimeTask.cancel(false);
_lifeTimeTask = null;
}
ItemLifeTimeTaskManager.getInstance().remove(this);
}
}

View File

@ -0,0 +1,86 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.buylist.Product;
/**
* @author Mobius
*/
public class BuyListTaskManager
{
private static final Map<Product, Long> PRODUCTS = new ConcurrentHashMap<>();
private static boolean _working = false;
public BuyListTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<Product, Long> entry : PRODUCTS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final Product product = entry.getKey();
PRODUCTS.remove(product);
product.restock();
}
}
_working = false;
}, 1000, 60000);
}
public void add(Product product, long endTime)
{
if (!PRODUCTS.containsKey(product))
{
PRODUCTS.put(product, endTime);
}
}
public void update(Product product, long endTime)
{
PRODUCTS.put(product, endTime);
}
public long getRestockDelay(Product product)
{
return PRODUCTS.getOrDefault(product, 0L);
}
public static BuyListTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final BuyListTaskManager INSTANCE = new BuyListTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemLifeTimeTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemLifeTimeTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.endOfLife();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemLifeTimeTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemLifeTimeTaskManager INSTANCE = new ItemLifeTimeTaskManager();
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemManaTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static final int MANA_CONSUMPTION_RATE = 60000;
private static boolean _working = false;
public ItemManaTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, System.currentTimeMillis() + MANA_CONSUMPTION_RATE);
}
}
public static ItemManaTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemManaTaskManager INSTANCE = new ItemManaTaskManager();
}
}

View File

@ -18,15 +18,13 @@ package org.l2jmobius.gameserver.model.buylist;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.model.items.Item;
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
/**
* @author NosBit
@ -41,7 +39,6 @@ public class Product
private final long _restockDelay;
private final long _maxCount;
private AtomicLong _count = null;
private ScheduledFuture<?> _restockTask = null;
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount)
{
@ -111,10 +108,9 @@ public class Product
{
return false;
}
if ((_restockTask == null) || _restockTask.isDone())
{
_restockTask = ThreadPool.schedule(new RestockTask(), _restockDelay);
}
BuyListTaskManager.getInstance().add(this, _restockDelay);
final boolean result = _count.addAndGet(-value) >= 0;
save();
return result;
@ -130,7 +126,7 @@ public class Product
final long remainTime = nextRestockTime - System.currentTimeMillis();
if (remainTime > 0)
{
_restockTask = ThreadPool.schedule(new RestockTask(), remainTime);
BuyListTaskManager.getInstance().update(this, remainTime);
}
else
{
@ -144,36 +140,29 @@ public class Product
save();
}
protected final class RestockTask implements Runnable
{
@Override
public void run()
{
restock();
}
}
private void save()
{
try (Connection con = DatabaseFactory.getConnection();
PreparedStatement ps = con.prepareStatement("INSERT INTO `buylists`(`buylist_id`, `item_id`, `count`, `next_restock_time`) VALUES(?, ?, ?, ?) ON DUPLICATE KEY UPDATE `count` = ?, `next_restock_time` = ?"))
PreparedStatement statement = con.prepareStatement("INSERT INTO `buylists`(`buylist_id`, `item_id`, `count`, `next_restock_time`) VALUES(?, ?, ?, ?) ON DUPLICATE KEY UPDATE `count` = ?, `next_restock_time` = ?"))
{
ps.setInt(1, _buyListId);
ps.setInt(2, _item.getId());
ps.setLong(3, getCount());
ps.setLong(5, getCount());
if ((_restockTask != null) && (_restockTask.getDelay(TimeUnit.MILLISECONDS) > 0))
statement.setInt(1, _buyListId);
statement.setInt(2, _item.getId());
statement.setLong(3, getCount());
statement.setLong(5, getCount());
final long nextRestockTime = BuyListTaskManager.getInstance().getRestockDelay(this);
if (nextRestockTime > 0)
{
final long nextRestockTime = System.currentTimeMillis() + _restockTask.getDelay(TimeUnit.MILLISECONDS);
ps.setLong(4, nextRestockTime);
ps.setLong(6, nextRestockTime);
statement.setLong(4, nextRestockTime);
statement.setLong(6, nextRestockTime);
}
else
{
ps.setLong(4, 0);
ps.setLong(6, 0);
statement.setLong(4, 0);
statement.setLong(6, 0);
}
ps.executeUpdate();
statement.executeUpdate();
}
catch (Exception e)
{

View File

@ -31,7 +31,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.EnchantItemOptionsData;
@ -76,6 +75,8 @@ import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
import org.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.ItemLifeTimeTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
import org.l2jmobius.gameserver.util.GMAudit;
/**
@ -127,7 +128,6 @@ public class ItemInstance extends WorldObject
/** Shadow item */
private int _mana = -1;
private boolean _consumingMana = false;
private static final int MANA_CONSUMPTION_RATE = 60000;
/** Custom item types (used loto, race tickets) */
private int _type1;
@ -157,7 +157,6 @@ public class ItemInstance extends WorldObject
private Elementals[] _elementals = null;
private ScheduledFuture<?> _itemLootShedule = null;
private ScheduledFuture<?> _lifeTimeTask;
private final DropProtection _dropProtection = new DropProtection();
@ -1207,37 +1206,6 @@ public class ItemInstance extends WorldObject
}
}
/**
* Used to decrease mana (mana means life time for shadow items)
*/
public static class ScheduleConsumeManaTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleConsumeManaTask.class.getName());
private final ItemInstance _shadowItem;
public ScheduleConsumeManaTask(ItemInstance item)
{
_shadowItem = item;
}
@Override
public void run()
{
try
{
// decrease mana
if (_shadowItem != null)
{
_shadowItem.decreaseMana(true);
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
}
}
/**
* Returns true if this item is a shadow item Shadow items have a limited life-time
* @return
@ -1393,7 +1361,7 @@ public class ItemInstance extends WorldObject
return;
}
_consumingMana = true;
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
ItemManaTaskManager.getInstance().add(this);
}
/**
@ -1539,69 +1507,53 @@ public class ItemInstance extends WorldObject
* <b><u>Example of use</u>:</b><br>
* <li>Drop item</li>
* <li>Call Pet</li>
* @param dropper
* @param locX
* @param locY
* @param locZ
*/
public class ItemDropTask implements Runnable
public void dropMe(Creature dropper, int locX, int locY, int locZ)
{
private int _x;
private int _y;
private int _z;
private final Creature _dropper;
private final ItemInstance _itm;
int x = locX;
int y = locY;
int z = locZ;
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
if (dropper != null)
{
_x = x;
_y = y;
_z = z;
_dropper = dropper;
_itm = item;
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, dropper.getInstanceId());
x = dropDest.getX();
y = dropDest.getY();
z = dropDest.getZ();
}
@Override
public void run()
if (dropper != null)
{
if (_dropper != null)
{
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(_dropper.getX(), _dropper.getY(), _dropper.getZ(), _x, _y, _z, _dropper.getInstanceId());
_x = dropDest.getX();
_y = dropDest.getY();
_z = dropDest.getZ();
}
if (_dropper != null)
{
setInstanceId(_dropper.getInstanceId()); // Inherit instancezone when dropped in visible world
}
else
{
setInstanceId(0); // No dropper? Make it a global item...
}
synchronized (_itm)
{
// Set the x,y,z position of the ItemInstance dropped and update its _worldregion
_itm.setSpawned(true);
_itm.setXYZ(_x, _y, _z);
}
_itm.setDropTime(System.currentTimeMillis());
_itm.setDropperObjectId(_dropper != null ? _dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(_itm, _itm.getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().save(_itm);
}
_itm.setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
setInstanceId(dropper.getInstanceId()); // Inherit instancezone when dropped in visible world
}
}
public void dropMe(Creature dropper, int x, int y, int z)
{
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
else
{
setInstanceId(0); // No dropper? Make it a global item...
}
// Set the x,y,z position of the ItemInstance dropped and update its world region
setSpawned(true);
setXYZ(x, y, z);
setDropTime(System.currentTimeMillis());
setDropperObjectId(dropper != null ? dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(this, getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().save(this);
}
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
if ((dropper != null) && dropper.isPlayer())
{
_owner = null;
// Notify to scripts
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerItemDrop(dropper.getActingPlayer(), this, new Location(x, y, z)), getItem());
}
@ -1870,38 +1822,7 @@ public class ItemInstance extends WorldObject
}
else
{
if (_lifeTimeTask != null)
{
_lifeTimeTask.cancel(true);
}
_lifeTimeTask = ThreadPool.schedule(new ScheduleLifeTimeTask(this), getRemainingTime());
}
}
public static class ScheduleLifeTimeTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleLifeTimeTask.class.getName());
private final ItemInstance _limitedItem;
public ScheduleLifeTimeTask(ItemInstance item)
{
_limitedItem = item;
}
@Override
public void run()
{
try
{
if (_limitedItem != null)
{
_limitedItem.endOfLife();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
}
}
@ -2199,10 +2120,6 @@ public class ItemInstance extends WorldObject
public void stopAllTasks()
{
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
{
_lifeTimeTask.cancel(false);
_lifeTimeTask = null;
}
ItemLifeTimeTaskManager.getInstance().remove(this);
}
}

View File

@ -0,0 +1,86 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.buylist.Product;
/**
* @author Mobius
*/
public class BuyListTaskManager
{
private static final Map<Product, Long> PRODUCTS = new ConcurrentHashMap<>();
private static boolean _working = false;
public BuyListTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<Product, Long> entry : PRODUCTS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final Product product = entry.getKey();
PRODUCTS.remove(product);
product.restock();
}
}
_working = false;
}, 1000, 60000);
}
public void add(Product product, long endTime)
{
if (!PRODUCTS.containsKey(product))
{
PRODUCTS.put(product, endTime);
}
}
public void update(Product product, long endTime)
{
PRODUCTS.put(product, endTime);
}
public long getRestockDelay(Product product)
{
return PRODUCTS.getOrDefault(product, 0L);
}
public static BuyListTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final BuyListTaskManager INSTANCE = new BuyListTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemLifeTimeTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemLifeTimeTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.endOfLife();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemLifeTimeTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemLifeTimeTaskManager INSTANCE = new ItemLifeTimeTaskManager();
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemManaTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static final int MANA_CONSUMPTION_RATE = 60000;
private static boolean _working = false;
public ItemManaTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, System.currentTimeMillis() + MANA_CONSUMPTION_RATE);
}
}
public static ItemManaTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemManaTaskManager INSTANCE = new ItemManaTaskManager();
}
}

View File

@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.model.items.Item;
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
/**
* @author NosBit
@ -45,7 +43,6 @@ public class Product
private final long _maxCount;
private final double _baseTax;
private AtomicLong _count = null;
private ScheduledFuture<?> _restockTask = null;
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
{
@ -122,10 +119,9 @@ public class Product
{
return false;
}
if ((_restockTask == null) || _restockTask.isDone())
{
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
}
BuyListTaskManager.getInstance().add(this, _restockDelay);
final boolean result = _count.addAndGet(-value) >= 0;
save();
return result;
@ -141,7 +137,7 @@ public class Product
final long remainTime = nextRestockTime - System.currentTimeMillis();
if (remainTime > 0)
{
_restockTask = ThreadPool.schedule(this::restock, remainTime);
BuyListTaskManager.getInstance().update(this, remainTime);
}
else
{
@ -164,9 +160,10 @@ public class Product
statement.setInt(2, _item.getId());
statement.setLong(3, getCount());
statement.setLong(5, getCount());
if ((_restockTask != null) && (_restockTask.getDelay(TimeUnit.MILLISECONDS) > 0))
final long nextRestockTime = BuyListTaskManager.getInstance().getRestockDelay(this);
if (nextRestockTime > 0)
{
final long nextRestockTime = System.currentTimeMillis() + _restockTask.getDelay(TimeUnit.MILLISECONDS);
statement.setLong(4, nextRestockTime);
statement.setLong(6, nextRestockTime);
}
@ -175,6 +172,7 @@ public class Product
statement.setLong(4, 0);
statement.setLong(6, 0);
}
statement.executeUpdate();
}
catch (Exception e)

View File

@ -34,7 +34,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
@ -88,6 +87,9 @@ import org.l2jmobius.gameserver.network.serverpackets.GetItem;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.ItemAppearanceTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemLifeTimeTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
import org.l2jmobius.gameserver.util.GMAudit;
/**
@ -139,7 +141,6 @@ public class ItemInstance extends WorldObject
/** Shadow item */
private int _mana = -1;
private boolean _consumingMana = false;
private static final int MANA_CONSUMPTION_RATE = 60000;
/** Custom item types (used loto, race tickets) */
private int _type1;
@ -169,8 +170,6 @@ public class ItemInstance extends WorldObject
private Map<AttributeType, AttributeHolder> _elementals = null;
private ScheduledFuture<?> _itemLootShedule = null;
private ScheduledFuture<?> _lifeTimeTask;
private ScheduledFuture<?> _appearanceLifeTimeTask;
private final DropProtection _dropProtection = new DropProtection();
@ -1280,37 +1279,6 @@ public class ItemInstance extends WorldObject
}
}
/**
* Used to decrease mana (mana means life time for shadow items)
*/
public static class ScheduleConsumeManaTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleConsumeManaTask.class.getName());
private final ItemInstance _shadowItem;
public ScheduleConsumeManaTask(ItemInstance item)
{
_shadowItem = item;
}
@Override
public void run()
{
try
{
// decrease mana
if (_shadowItem != null)
{
_shadowItem.decreaseMana(true);
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
}
}
/**
* Returns true if this item is a shadow item Shadow items have a limited life-time
* @return
@ -1455,7 +1423,7 @@ public class ItemInstance extends WorldObject
return;
}
_consumingMana = true;
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
ItemManaTaskManager.getInstance().add(this);
}
/**
@ -1524,62 +1492,46 @@ public class ItemInstance extends WorldObject
* <b><u>Example of use</u>:</b><br>
* <li>Drop item</li>
* <li>Call Pet</li>
* @param dropper
* @param locX
* @param locY
* @param locZ
*/
public class ItemDropTask implements Runnable
public void dropMe(Creature dropper, int locX, int locY, int locZ)
{
private int _x, _y, _z;
private final Creature _dropper;
private final ItemInstance _itеm;
int x = locX;
int y = locY;
int z = locZ;
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
if (dropper != null)
{
_x = x;
_y = y;
_z = z;
_dropper = dropper;
_itеm = item;
final Instance instance = dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
x = dropDest.getX();
y = dropDest.getY();
z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
@Override
public void run()
// Set the x,y,z position of the ItemInstance dropped and update its world region
setSpawned(true);
setXYZ(x, y, z);
setDropTime(System.currentTimeMillis());
setDropperObjectId(dropper != null ? dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(this, getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
if (_dropper != null)
{
final Instance instance = _dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(_dropper.getX(), _dropper.getY(), _dropper.getZ(), _x, _y, _z, instance);
_x = dropDest.getX();
_y = dropDest.getY();
_z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
synchronized (_itеm)
{
// Set the x,y,z position of the ItemInstance dropped and update its _worldregion
_itеm.setSpawned(true);
_itеm.setXYZ(_x, _y, _z);
}
_itеm.setDropTime(System.currentTimeMillis());
_itеm.setDropperObjectId(_dropper != null ? _dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(_itеm, _itеm.getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().save(_itеm);
}
_itеm.setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
ItemsOnGroundManager.getInstance().save(this);
}
}
public void dropMe(Creature dropper, int x, int y, int z)
{
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
if ((dropper != null) && dropper.isPlayer())
{
_owner = null;
@ -1897,38 +1849,7 @@ public class ItemInstance extends WorldObject
}
else
{
if (_lifeTimeTask != null)
{
_lifeTimeTask.cancel(true);
}
_lifeTimeTask = ThreadPool.schedule(new ScheduleLifeTimeTask(this), getRemainingTime());
}
}
static class ScheduleLifeTimeTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleLifeTimeTask.class.getName());
private final ItemInstance _limitedItem;
ScheduleLifeTimeTask(ItemInstance item)
{
_limitedItem = item;
}
@Override
public void run()
{
try
{
if (_limitedItem != null)
{
_limitedItem.endOfLife();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
}
}
@ -2472,16 +2393,8 @@ public class ItemInstance extends WorldObject
public void stopAllTasks()
{
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
{
_lifeTimeTask.cancel(false);
_lifeTimeTask = null;
}
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
{
_appearanceLifeTimeTask.cancel(false);
_appearanceLifeTimeTask = null;
}
ItemLifeTimeTaskManager.getInstance().remove(this);
ItemAppearanceTaskManager.getInstance().remove(this);
}
public ItemVariables getVariables()
@ -2524,10 +2437,9 @@ public class ItemInstance extends WorldObject
getVariables().set(ItemVariables.VISUAL_ID, visualId);
// When removed, cancel existing lifetime task.
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
if (visualId == 0)
{
_appearanceLifeTimeTask.cancel(true);
_appearanceLifeTimeTask = null;
ItemAppearanceTaskManager.getInstance().remove(this);
onVisualLifeTimeEnd();
}
}
@ -2539,25 +2451,22 @@ public class ItemInstance extends WorldObject
public void scheduleVisualLifeTime()
{
if (_appearanceLifeTimeTask != null)
{
_appearanceLifeTimeTask.cancel(false);
}
ItemAppearanceTaskManager.getInstance().remove(this);
if (getVisualLifeTime() > 0)
{
final long time = getVisualLifeTime() - System.currentTimeMillis();
if (time > 0)
final long endTime = getVisualLifeTime();
if ((endTime - System.currentTimeMillis()) > 0)
{
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
ItemAppearanceTaskManager.getInstance().add(this, endTime);
}
else
{
ThreadPool.execute(this::onVisualLifeTimeEnd);
onVisualLifeTimeEnd();
}
}
}
private void onVisualLifeTimeEnd()
public void onVisualLifeTimeEnd()
{
final ItemVariables vars = getVariables();
vars.remove(ItemVariables.VISUAL_ID);

View File

@ -0,0 +1,86 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.buylist.Product;
/**
* @author Mobius
*/
public class BuyListTaskManager
{
private static final Map<Product, Long> PRODUCTS = new ConcurrentHashMap<>();
private static boolean _working = false;
public BuyListTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<Product, Long> entry : PRODUCTS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final Product product = entry.getKey();
PRODUCTS.remove(product);
product.restock();
}
}
_working = false;
}, 1000, 60000);
}
public void add(Product product, long endTime)
{
if (!PRODUCTS.containsKey(product))
{
PRODUCTS.put(product, endTime);
}
}
public void update(Product product, long endTime)
{
PRODUCTS.put(product, endTime);
}
public long getRestockDelay(Product product)
{
return PRODUCTS.getOrDefault(product, 0L);
}
public static BuyListTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final BuyListTaskManager INSTANCE = new BuyListTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemAppearanceTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemAppearanceTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.onVisualLifeTimeEnd();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemAppearanceTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemAppearanceTaskManager INSTANCE = new ItemAppearanceTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemLifeTimeTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemLifeTimeTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.endOfLife();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemLifeTimeTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemLifeTimeTaskManager INSTANCE = new ItemLifeTimeTaskManager();
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemManaTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static final int MANA_CONSUMPTION_RATE = 60000;
private static boolean _working = false;
public ItemManaTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, System.currentTimeMillis() + MANA_CONSUMPTION_RATE);
}
}
public static ItemManaTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemManaTaskManager INSTANCE = new ItemManaTaskManager();
}
}

View File

@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.model.items.Item;
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
/**
* @author NosBit
@ -45,7 +43,6 @@ public class Product
private final long _maxCount;
private final double _baseTax;
private AtomicLong _count = null;
private ScheduledFuture<?> _restockTask = null;
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
{
@ -122,10 +119,9 @@ public class Product
{
return false;
}
if ((_restockTask == null) || _restockTask.isDone())
{
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
}
BuyListTaskManager.getInstance().add(this, _restockDelay);
final boolean result = _count.addAndGet(-value) >= 0;
save();
return result;
@ -141,7 +137,7 @@ public class Product
final long remainTime = nextRestockTime - System.currentTimeMillis();
if (remainTime > 0)
{
_restockTask = ThreadPool.schedule(this::restock, remainTime);
BuyListTaskManager.getInstance().update(this, remainTime);
}
else
{
@ -164,9 +160,10 @@ public class Product
statement.setInt(2, _item.getId());
statement.setLong(3, getCount());
statement.setLong(5, getCount());
if ((_restockTask != null) && (_restockTask.getDelay(TimeUnit.MILLISECONDS) > 0))
final long nextRestockTime = BuyListTaskManager.getInstance().getRestockDelay(this);
if (nextRestockTime > 0)
{
final long nextRestockTime = System.currentTimeMillis() + _restockTask.getDelay(TimeUnit.MILLISECONDS);
statement.setLong(4, nextRestockTime);
statement.setLong(6, nextRestockTime);
}
@ -175,6 +172,7 @@ public class Product
statement.setLong(4, 0);
statement.setLong(6, 0);
}
statement.executeUpdate();
}
catch (Exception e)

View File

@ -34,7 +34,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
@ -88,6 +87,9 @@ import org.l2jmobius.gameserver.network.serverpackets.GetItem;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.ItemAppearanceTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemLifeTimeTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
import org.l2jmobius.gameserver.util.GMAudit;
/**
@ -139,7 +141,6 @@ public class ItemInstance extends WorldObject
/** Shadow item */
private int _mana = -1;
private boolean _consumingMana = false;
private static final int MANA_CONSUMPTION_RATE = 60000;
/** Custom item types (used loto, race tickets) */
private int _type1;
@ -169,8 +170,6 @@ public class ItemInstance extends WorldObject
private Map<AttributeType, AttributeHolder> _elementals = null;
private ScheduledFuture<?> _itemLootShedule = null;
private ScheduledFuture<?> _lifeTimeTask;
private ScheduledFuture<?> _appearanceLifeTimeTask;
private final DropProtection _dropProtection = new DropProtection();
@ -1280,37 +1279,6 @@ public class ItemInstance extends WorldObject
}
}
/**
* Used to decrease mana (mana means life time for shadow items)
*/
public static class ScheduleConsumeManaTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleConsumeManaTask.class.getName());
private final ItemInstance _shadowItem;
public ScheduleConsumeManaTask(ItemInstance item)
{
_shadowItem = item;
}
@Override
public void run()
{
try
{
// decrease mana
if (_shadowItem != null)
{
_shadowItem.decreaseMana(true);
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
}
}
/**
* Returns true if this item is a shadow item Shadow items have a limited life-time
* @return
@ -1455,7 +1423,7 @@ public class ItemInstance extends WorldObject
return;
}
_consumingMana = true;
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
ItemManaTaskManager.getInstance().add(this);
}
/**
@ -1524,62 +1492,46 @@ public class ItemInstance extends WorldObject
* <b><u>Example of use</u>:</b><br>
* <li>Drop item</li>
* <li>Call Pet</li>
* @param dropper
* @param locX
* @param locY
* @param locZ
*/
public class ItemDropTask implements Runnable
public void dropMe(Creature dropper, int locX, int locY, int locZ)
{
private int _x, _y, _z;
private final Creature _dropper;
private final ItemInstance _itеm;
int x = locX;
int y = locY;
int z = locZ;
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
if (dropper != null)
{
_x = x;
_y = y;
_z = z;
_dropper = dropper;
_itеm = item;
final Instance instance = dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
x = dropDest.getX();
y = dropDest.getY();
z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
@Override
public void run()
// Set the x,y,z position of the ItemInstance dropped and update its world region
setSpawned(true);
setXYZ(x, y, z);
setDropTime(System.currentTimeMillis());
setDropperObjectId(dropper != null ? dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(this, getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
if (_dropper != null)
{
final Instance instance = _dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(_dropper.getX(), _dropper.getY(), _dropper.getZ(), _x, _y, _z, instance);
_x = dropDest.getX();
_y = dropDest.getY();
_z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
synchronized (_itеm)
{
// Set the x,y,z position of the ItemInstance dropped and update its _worldregion
_itеm.setSpawned(true);
_itеm.setXYZ(_x, _y, _z);
}
_itеm.setDropTime(System.currentTimeMillis());
_itеm.setDropperObjectId(_dropper != null ? _dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(_itеm, _itеm.getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().save(_itеm);
}
_itеm.setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
ItemsOnGroundManager.getInstance().save(this);
}
}
public void dropMe(Creature dropper, int x, int y, int z)
{
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
if ((dropper != null) && dropper.isPlayer())
{
_owner = null;
@ -1897,38 +1849,7 @@ public class ItemInstance extends WorldObject
}
else
{
if (_lifeTimeTask != null)
{
_lifeTimeTask.cancel(true);
}
_lifeTimeTask = ThreadPool.schedule(new ScheduleLifeTimeTask(this), getRemainingTime());
}
}
static class ScheduleLifeTimeTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleLifeTimeTask.class.getName());
private final ItemInstance _limitedItem;
ScheduleLifeTimeTask(ItemInstance item)
{
_limitedItem = item;
}
@Override
public void run()
{
try
{
if (_limitedItem != null)
{
_limitedItem.endOfLife();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
}
}
@ -2472,16 +2393,8 @@ public class ItemInstance extends WorldObject
public void stopAllTasks()
{
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
{
_lifeTimeTask.cancel(false);
_lifeTimeTask = null;
}
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
{
_appearanceLifeTimeTask.cancel(false);
_appearanceLifeTimeTask = null;
}
ItemLifeTimeTaskManager.getInstance().remove(this);
ItemAppearanceTaskManager.getInstance().remove(this);
}
public ItemVariables getVariables()
@ -2524,10 +2437,9 @@ public class ItemInstance extends WorldObject
getVariables().set(ItemVariables.VISUAL_ID, visualId);
// When removed, cancel existing lifetime task.
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
if (visualId == 0)
{
_appearanceLifeTimeTask.cancel(true);
_appearanceLifeTimeTask = null;
ItemAppearanceTaskManager.getInstance().remove(this);
onVisualLifeTimeEnd();
}
}
@ -2539,25 +2451,22 @@ public class ItemInstance extends WorldObject
public void scheduleVisualLifeTime()
{
if (_appearanceLifeTimeTask != null)
{
_appearanceLifeTimeTask.cancel(false);
}
ItemAppearanceTaskManager.getInstance().remove(this);
if (getVisualLifeTime() > 0)
{
final long time = getVisualLifeTime() - System.currentTimeMillis();
if (time > 0)
final long endTime = getVisualLifeTime();
if ((endTime - System.currentTimeMillis()) > 0)
{
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
ItemAppearanceTaskManager.getInstance().add(this, endTime);
}
else
{
ThreadPool.execute(this::onVisualLifeTimeEnd);
onVisualLifeTimeEnd();
}
}
}
private void onVisualLifeTimeEnd()
public void onVisualLifeTimeEnd()
{
final ItemVariables vars = getVariables();
vars.remove(ItemVariables.VISUAL_ID);

View File

@ -0,0 +1,86 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.buylist.Product;
/**
* @author Mobius
*/
public class BuyListTaskManager
{
private static final Map<Product, Long> PRODUCTS = new ConcurrentHashMap<>();
private static boolean _working = false;
public BuyListTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<Product, Long> entry : PRODUCTS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final Product product = entry.getKey();
PRODUCTS.remove(product);
product.restock();
}
}
_working = false;
}, 1000, 60000);
}
public void add(Product product, long endTime)
{
if (!PRODUCTS.containsKey(product))
{
PRODUCTS.put(product, endTime);
}
}
public void update(Product product, long endTime)
{
PRODUCTS.put(product, endTime);
}
public long getRestockDelay(Product product)
{
return PRODUCTS.getOrDefault(product, 0L);
}
public static BuyListTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final BuyListTaskManager INSTANCE = new BuyListTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemAppearanceTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemAppearanceTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.onVisualLifeTimeEnd();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemAppearanceTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemAppearanceTaskManager INSTANCE = new ItemAppearanceTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemLifeTimeTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemLifeTimeTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.endOfLife();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemLifeTimeTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemLifeTimeTaskManager INSTANCE = new ItemLifeTimeTaskManager();
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemManaTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static final int MANA_CONSUMPTION_RATE = 60000;
private static boolean _working = false;
public ItemManaTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, System.currentTimeMillis() + MANA_CONSUMPTION_RATE);
}
}
public static ItemManaTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemManaTaskManager INSTANCE = new ItemManaTaskManager();
}
}

View File

@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.model.items.Item;
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
/**
* @author NosBit
@ -45,7 +43,6 @@ public class Product
private final long _maxCount;
private final double _baseTax;
private AtomicLong _count = null;
private ScheduledFuture<?> _restockTask = null;
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
{
@ -122,10 +119,9 @@ public class Product
{
return false;
}
if ((_restockTask == null) || _restockTask.isDone())
{
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
}
BuyListTaskManager.getInstance().add(this, _restockDelay);
final boolean result = _count.addAndGet(-value) >= 0;
save();
return result;
@ -141,7 +137,7 @@ public class Product
final long remainTime = nextRestockTime - System.currentTimeMillis();
if (remainTime > 0)
{
_restockTask = ThreadPool.schedule(this::restock, remainTime);
BuyListTaskManager.getInstance().update(this, remainTime);
}
else
{
@ -164,9 +160,10 @@ public class Product
statement.setInt(2, _item.getId());
statement.setLong(3, getCount());
statement.setLong(5, getCount());
if ((_restockTask != null) && (_restockTask.getDelay(TimeUnit.MILLISECONDS) > 0))
final long nextRestockTime = BuyListTaskManager.getInstance().getRestockDelay(this);
if (nextRestockTime > 0)
{
final long nextRestockTime = System.currentTimeMillis() + _restockTask.getDelay(TimeUnit.MILLISECONDS);
statement.setLong(4, nextRestockTime);
statement.setLong(6, nextRestockTime);
}
@ -175,6 +172,7 @@ public class Product
statement.setLong(4, 0);
statement.setLong(6, 0);
}
statement.executeUpdate();
}
catch (Exception e)

View File

@ -34,7 +34,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
@ -88,6 +87,9 @@ import org.l2jmobius.gameserver.network.serverpackets.GetItem;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.ItemAppearanceTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemLifeTimeTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
import org.l2jmobius.gameserver.util.GMAudit;
/**
@ -139,7 +141,6 @@ public class ItemInstance extends WorldObject
/** Shadow item */
private int _mana = -1;
private boolean _consumingMana = false;
private static final int MANA_CONSUMPTION_RATE = 60000;
/** Custom item types (used loto, race tickets) */
private int _type1;
@ -169,8 +170,6 @@ public class ItemInstance extends WorldObject
private Map<AttributeType, AttributeHolder> _elementals = null;
private ScheduledFuture<?> _itemLootShedule = null;
private ScheduledFuture<?> _lifeTimeTask;
private ScheduledFuture<?> _appearanceLifeTimeTask;
private final DropProtection _dropProtection = new DropProtection();
@ -1280,37 +1279,6 @@ public class ItemInstance extends WorldObject
}
}
/**
* Used to decrease mana (mana means life time for shadow items)
*/
public static class ScheduleConsumeManaTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleConsumeManaTask.class.getName());
private final ItemInstance _shadowItem;
public ScheduleConsumeManaTask(ItemInstance item)
{
_shadowItem = item;
}
@Override
public void run()
{
try
{
// decrease mana
if (_shadowItem != null)
{
_shadowItem.decreaseMana(true);
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
}
}
/**
* Returns true if this item is a shadow item Shadow items have a limited life-time
* @return
@ -1455,7 +1423,7 @@ public class ItemInstance extends WorldObject
return;
}
_consumingMana = true;
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
ItemManaTaskManager.getInstance().add(this);
}
/**
@ -1524,62 +1492,46 @@ public class ItemInstance extends WorldObject
* <b><u>Example of use</u>:</b><br>
* <li>Drop item</li>
* <li>Call Pet</li>
* @param dropper
* @param locX
* @param locY
* @param locZ
*/
public class ItemDropTask implements Runnable
public void dropMe(Creature dropper, int locX, int locY, int locZ)
{
private int _x, _y, _z;
private final Creature _dropper;
private final ItemInstance _itеm;
int x = locX;
int y = locY;
int z = locZ;
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
if (dropper != null)
{
_x = x;
_y = y;
_z = z;
_dropper = dropper;
_itеm = item;
final Instance instance = dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
x = dropDest.getX();
y = dropDest.getY();
z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
@Override
public void run()
// Set the x,y,z position of the ItemInstance dropped and update its world region
setSpawned(true);
setXYZ(x, y, z);
setDropTime(System.currentTimeMillis());
setDropperObjectId(dropper != null ? dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(this, getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
if (_dropper != null)
{
final Instance instance = _dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(_dropper.getX(), _dropper.getY(), _dropper.getZ(), _x, _y, _z, instance);
_x = dropDest.getX();
_y = dropDest.getY();
_z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
synchronized (_itеm)
{
// Set the x,y,z position of the ItemInstance dropped and update its _worldregion
_itеm.setSpawned(true);
_itеm.setXYZ(_x, _y, _z);
}
_itеm.setDropTime(System.currentTimeMillis());
_itеm.setDropperObjectId(_dropper != null ? _dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(_itеm, _itеm.getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().save(_itеm);
}
_itеm.setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
ItemsOnGroundManager.getInstance().save(this);
}
}
public void dropMe(Creature dropper, int x, int y, int z)
{
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
if ((dropper != null) && dropper.isPlayer())
{
_owner = null;
@ -1897,38 +1849,7 @@ public class ItemInstance extends WorldObject
}
else
{
if (_lifeTimeTask != null)
{
_lifeTimeTask.cancel(true);
}
_lifeTimeTask = ThreadPool.schedule(new ScheduleLifeTimeTask(this), getRemainingTime());
}
}
static class ScheduleLifeTimeTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleLifeTimeTask.class.getName());
private final ItemInstance _limitedItem;
ScheduleLifeTimeTask(ItemInstance item)
{
_limitedItem = item;
}
@Override
public void run()
{
try
{
if (_limitedItem != null)
{
_limitedItem.endOfLife();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
}
}
@ -2472,16 +2393,8 @@ public class ItemInstance extends WorldObject
public void stopAllTasks()
{
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
{
_lifeTimeTask.cancel(false);
_lifeTimeTask = null;
}
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
{
_appearanceLifeTimeTask.cancel(false);
_appearanceLifeTimeTask = null;
}
ItemLifeTimeTaskManager.getInstance().remove(this);
ItemAppearanceTaskManager.getInstance().remove(this);
}
public ItemVariables getVariables()
@ -2524,10 +2437,9 @@ public class ItemInstance extends WorldObject
getVariables().set(ItemVariables.VISUAL_ID, visualId);
// When removed, cancel existing lifetime task.
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
if (visualId == 0)
{
_appearanceLifeTimeTask.cancel(true);
_appearanceLifeTimeTask = null;
ItemAppearanceTaskManager.getInstance().remove(this);
onVisualLifeTimeEnd();
}
}
@ -2539,25 +2451,22 @@ public class ItemInstance extends WorldObject
public void scheduleVisualLifeTime()
{
if (_appearanceLifeTimeTask != null)
{
_appearanceLifeTimeTask.cancel(false);
}
ItemAppearanceTaskManager.getInstance().remove(this);
if (getVisualLifeTime() > 0)
{
final long time = getVisualLifeTime() - System.currentTimeMillis();
if (time > 0)
final long endTime = getVisualLifeTime();
if ((endTime - System.currentTimeMillis()) > 0)
{
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
ItemAppearanceTaskManager.getInstance().add(this, endTime);
}
else
{
ThreadPool.execute(this::onVisualLifeTimeEnd);
onVisualLifeTimeEnd();
}
}
}
private void onVisualLifeTimeEnd()
public void onVisualLifeTimeEnd()
{
final ItemVariables vars = getVariables();
vars.remove(ItemVariables.VISUAL_ID);

View File

@ -0,0 +1,86 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.buylist.Product;
/**
* @author Mobius
*/
public class BuyListTaskManager
{
private static final Map<Product, Long> PRODUCTS = new ConcurrentHashMap<>();
private static boolean _working = false;
public BuyListTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<Product, Long> entry : PRODUCTS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final Product product = entry.getKey();
PRODUCTS.remove(product);
product.restock();
}
}
_working = false;
}, 1000, 60000);
}
public void add(Product product, long endTime)
{
if (!PRODUCTS.containsKey(product))
{
PRODUCTS.put(product, endTime);
}
}
public void update(Product product, long endTime)
{
PRODUCTS.put(product, endTime);
}
public long getRestockDelay(Product product)
{
return PRODUCTS.getOrDefault(product, 0L);
}
public static BuyListTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final BuyListTaskManager INSTANCE = new BuyListTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemAppearanceTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemAppearanceTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.onVisualLifeTimeEnd();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemAppearanceTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemAppearanceTaskManager INSTANCE = new ItemAppearanceTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemLifeTimeTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemLifeTimeTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.endOfLife();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemLifeTimeTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemLifeTimeTaskManager INSTANCE = new ItemLifeTimeTaskManager();
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemManaTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static final int MANA_CONSUMPTION_RATE = 60000;
private static boolean _working = false;
public ItemManaTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, System.currentTimeMillis() + MANA_CONSUMPTION_RATE);
}
}
public static ItemManaTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemManaTaskManager INSTANCE = new ItemManaTaskManager();
}
}

View File

@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.model.items.Item;
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
/**
* @author NosBit
@ -45,7 +43,6 @@ public class Product
private final long _maxCount;
private final double _baseTax;
private AtomicLong _count = null;
private ScheduledFuture<?> _restockTask = null;
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
{
@ -122,10 +119,9 @@ public class Product
{
return false;
}
if ((_restockTask == null) || _restockTask.isDone())
{
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
}
BuyListTaskManager.getInstance().add(this, _restockDelay);
final boolean result = _count.addAndGet(-value) >= 0;
save();
return result;
@ -141,7 +137,7 @@ public class Product
final long remainTime = nextRestockTime - System.currentTimeMillis();
if (remainTime > 0)
{
_restockTask = ThreadPool.schedule(this::restock, remainTime);
BuyListTaskManager.getInstance().update(this, remainTime);
}
else
{
@ -164,9 +160,10 @@ public class Product
statement.setInt(2, _item.getId());
statement.setLong(3, getCount());
statement.setLong(5, getCount());
if ((_restockTask != null) && (_restockTask.getDelay(TimeUnit.MILLISECONDS) > 0))
final long nextRestockTime = BuyListTaskManager.getInstance().getRestockDelay(this);
if (nextRestockTime > 0)
{
final long nextRestockTime = System.currentTimeMillis() + _restockTask.getDelay(TimeUnit.MILLISECONDS);
statement.setLong(4, nextRestockTime);
statement.setLong(6, nextRestockTime);
}
@ -175,6 +172,7 @@ public class Product
statement.setLong(4, 0);
statement.setLong(6, 0);
}
statement.executeUpdate();
}
catch (Exception e)

View File

@ -34,7 +34,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
@ -88,6 +87,9 @@ import org.l2jmobius.gameserver.network.serverpackets.GetItem;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.ItemAppearanceTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemLifeTimeTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
import org.l2jmobius.gameserver.util.GMAudit;
/**
@ -139,7 +141,6 @@ public class ItemInstance extends WorldObject
/** Shadow item */
private int _mana = -1;
private boolean _consumingMana = false;
private static final int MANA_CONSUMPTION_RATE = 60000;
/** Custom item types (used loto, race tickets) */
private int _type1;
@ -169,8 +170,6 @@ public class ItemInstance extends WorldObject
private Map<AttributeType, AttributeHolder> _elementals = null;
private ScheduledFuture<?> _itemLootShedule = null;
private ScheduledFuture<?> _lifeTimeTask;
private ScheduledFuture<?> _appearanceLifeTimeTask;
private final DropProtection _dropProtection = new DropProtection();
@ -1280,37 +1279,6 @@ public class ItemInstance extends WorldObject
}
}
/**
* Used to decrease mana (mana means life time for shadow items)
*/
public static class ScheduleConsumeManaTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleConsumeManaTask.class.getName());
private final ItemInstance _shadowItem;
public ScheduleConsumeManaTask(ItemInstance item)
{
_shadowItem = item;
}
@Override
public void run()
{
try
{
// decrease mana
if (_shadowItem != null)
{
_shadowItem.decreaseMana(true);
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
}
}
/**
* Returns true if this item is a shadow item Shadow items have a limited life-time
* @return
@ -1455,7 +1423,7 @@ public class ItemInstance extends WorldObject
return;
}
_consumingMana = true;
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
ItemManaTaskManager.getInstance().add(this);
}
/**
@ -1524,62 +1492,46 @@ public class ItemInstance extends WorldObject
* <b><u>Example of use</u>:</b><br>
* <li>Drop item</li>
* <li>Call Pet</li>
* @param dropper
* @param locX
* @param locY
* @param locZ
*/
public class ItemDropTask implements Runnable
public void dropMe(Creature dropper, int locX, int locY, int locZ)
{
private int _x, _y, _z;
private final Creature _dropper;
private final ItemInstance _itеm;
int x = locX;
int y = locY;
int z = locZ;
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
if (dropper != null)
{
_x = x;
_y = y;
_z = z;
_dropper = dropper;
_itеm = item;
final Instance instance = dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
x = dropDest.getX();
y = dropDest.getY();
z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
@Override
public void run()
// Set the x,y,z position of the ItemInstance dropped and update its world region
setSpawned(true);
setXYZ(x, y, z);
setDropTime(System.currentTimeMillis());
setDropperObjectId(dropper != null ? dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(this, getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
if (_dropper != null)
{
final Instance instance = _dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(_dropper.getX(), _dropper.getY(), _dropper.getZ(), _x, _y, _z, instance);
_x = dropDest.getX();
_y = dropDest.getY();
_z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
synchronized (_itеm)
{
// Set the x,y,z position of the ItemInstance dropped and update its _worldregion
_itеm.setSpawned(true);
_itеm.setXYZ(_x, _y, _z);
}
_itеm.setDropTime(System.currentTimeMillis());
_itеm.setDropperObjectId(_dropper != null ? _dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(_itеm, _itеm.getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().save(_itеm);
}
_itеm.setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
ItemsOnGroundManager.getInstance().save(this);
}
}
public void dropMe(Creature dropper, int x, int y, int z)
{
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
if ((dropper != null) && dropper.isPlayer())
{
_owner = null;
@ -1897,38 +1849,7 @@ public class ItemInstance extends WorldObject
}
else
{
if (_lifeTimeTask != null)
{
_lifeTimeTask.cancel(true);
}
_lifeTimeTask = ThreadPool.schedule(new ScheduleLifeTimeTask(this), getRemainingTime());
}
}
static class ScheduleLifeTimeTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleLifeTimeTask.class.getName());
private final ItemInstance _limitedItem;
ScheduleLifeTimeTask(ItemInstance item)
{
_limitedItem = item;
}
@Override
public void run()
{
try
{
if (_limitedItem != null)
{
_limitedItem.endOfLife();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
}
}
@ -2472,16 +2393,8 @@ public class ItemInstance extends WorldObject
public void stopAllTasks()
{
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
{
_lifeTimeTask.cancel(false);
_lifeTimeTask = null;
}
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
{
_appearanceLifeTimeTask.cancel(false);
_appearanceLifeTimeTask = null;
}
ItemLifeTimeTaskManager.getInstance().remove(this);
ItemAppearanceTaskManager.getInstance().remove(this);
}
public ItemVariables getVariables()
@ -2524,10 +2437,9 @@ public class ItemInstance extends WorldObject
getVariables().set(ItemVariables.VISUAL_ID, visualId);
// When removed, cancel existing lifetime task.
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
if (visualId == 0)
{
_appearanceLifeTimeTask.cancel(true);
_appearanceLifeTimeTask = null;
ItemAppearanceTaskManager.getInstance().remove(this);
onVisualLifeTimeEnd();
}
}
@ -2539,25 +2451,22 @@ public class ItemInstance extends WorldObject
public void scheduleVisualLifeTime()
{
if (_appearanceLifeTimeTask != null)
{
_appearanceLifeTimeTask.cancel(false);
}
ItemAppearanceTaskManager.getInstance().remove(this);
if (getVisualLifeTime() > 0)
{
final long time = getVisualLifeTime() - System.currentTimeMillis();
if (time > 0)
final long endTime = getVisualLifeTime();
if ((endTime - System.currentTimeMillis()) > 0)
{
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
ItemAppearanceTaskManager.getInstance().add(this, endTime);
}
else
{
ThreadPool.execute(this::onVisualLifeTimeEnd);
onVisualLifeTimeEnd();
}
}
}
private void onVisualLifeTimeEnd()
public void onVisualLifeTimeEnd()
{
final ItemVariables vars = getVariables();
vars.remove(ItemVariables.VISUAL_ID);

View File

@ -0,0 +1,86 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.buylist.Product;
/**
* @author Mobius
*/
public class BuyListTaskManager
{
private static final Map<Product, Long> PRODUCTS = new ConcurrentHashMap<>();
private static boolean _working = false;
public BuyListTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<Product, Long> entry : PRODUCTS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final Product product = entry.getKey();
PRODUCTS.remove(product);
product.restock();
}
}
_working = false;
}, 1000, 60000);
}
public void add(Product product, long endTime)
{
if (!PRODUCTS.containsKey(product))
{
PRODUCTS.put(product, endTime);
}
}
public void update(Product product, long endTime)
{
PRODUCTS.put(product, endTime);
}
public long getRestockDelay(Product product)
{
return PRODUCTS.getOrDefault(product, 0L);
}
public static BuyListTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final BuyListTaskManager INSTANCE = new BuyListTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemAppearanceTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemAppearanceTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.onVisualLifeTimeEnd();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemAppearanceTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemAppearanceTaskManager INSTANCE = new ItemAppearanceTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemLifeTimeTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemLifeTimeTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.endOfLife();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemLifeTimeTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemLifeTimeTaskManager INSTANCE = new ItemLifeTimeTaskManager();
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemManaTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static final int MANA_CONSUMPTION_RATE = 60000;
private static boolean _working = false;
public ItemManaTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, System.currentTimeMillis() + MANA_CONSUMPTION_RATE);
}
}
public static ItemManaTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemManaTaskManager INSTANCE = new ItemManaTaskManager();
}
}

View File

@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.model.items.Item;
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
/**
* @author NosBit
@ -45,7 +43,6 @@ public class Product
private final long _maxCount;
private final double _baseTax;
private AtomicLong _count = null;
private ScheduledFuture<?> _restockTask = null;
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
{
@ -122,10 +119,9 @@ public class Product
{
return false;
}
if ((_restockTask == null) || _restockTask.isDone())
{
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
}
BuyListTaskManager.getInstance().add(this, _restockDelay);
final boolean result = _count.addAndGet(-value) >= 0;
save();
return result;
@ -141,7 +137,7 @@ public class Product
final long remainTime = nextRestockTime - System.currentTimeMillis();
if (remainTime > 0)
{
_restockTask = ThreadPool.schedule(this::restock, remainTime);
BuyListTaskManager.getInstance().update(this, remainTime);
}
else
{
@ -164,9 +160,10 @@ public class Product
statement.setInt(2, _item.getId());
statement.setLong(3, getCount());
statement.setLong(5, getCount());
if ((_restockTask != null) && (_restockTask.getDelay(TimeUnit.MILLISECONDS) > 0))
final long nextRestockTime = BuyListTaskManager.getInstance().getRestockDelay(this);
if (nextRestockTime > 0)
{
final long nextRestockTime = System.currentTimeMillis() + _restockTask.getDelay(TimeUnit.MILLISECONDS);
statement.setLong(4, nextRestockTime);
statement.setLong(6, nextRestockTime);
}
@ -175,6 +172,7 @@ public class Product
statement.setLong(4, 0);
statement.setLong(6, 0);
}
statement.executeUpdate();
}
catch (Exception e)

View File

@ -34,7 +34,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
@ -88,6 +87,9 @@ import org.l2jmobius.gameserver.network.serverpackets.GetItem;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.ItemAppearanceTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemLifeTimeTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
import org.l2jmobius.gameserver.util.GMAudit;
/**
@ -139,7 +141,6 @@ public class ItemInstance extends WorldObject
/** Shadow item */
private int _mana = -1;
private boolean _consumingMana = false;
private static final int MANA_CONSUMPTION_RATE = 60000;
/** Custom item types (used loto, race tickets) */
private int _type1;
@ -169,8 +170,6 @@ public class ItemInstance extends WorldObject
private Map<AttributeType, AttributeHolder> _elementals = null;
private ScheduledFuture<?> _itemLootShedule = null;
private ScheduledFuture<?> _lifeTimeTask;
private ScheduledFuture<?> _appearanceLifeTimeTask;
private final DropProtection _dropProtection = new DropProtection();
@ -1280,37 +1279,6 @@ public class ItemInstance extends WorldObject
}
}
/**
* Used to decrease mana (mana means life time for shadow items)
*/
public static class ScheduleConsumeManaTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleConsumeManaTask.class.getName());
private final ItemInstance _shadowItem;
public ScheduleConsumeManaTask(ItemInstance item)
{
_shadowItem = item;
}
@Override
public void run()
{
try
{
// decrease mana
if (_shadowItem != null)
{
_shadowItem.decreaseMana(true);
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
}
}
/**
* Returns true if this item is a shadow item Shadow items have a limited life-time
* @return
@ -1455,7 +1423,7 @@ public class ItemInstance extends WorldObject
return;
}
_consumingMana = true;
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
ItemManaTaskManager.getInstance().add(this);
}
/**
@ -1524,62 +1492,46 @@ public class ItemInstance extends WorldObject
* <b><u>Example of use</u>:</b><br>
* <li>Drop item</li>
* <li>Call Pet</li>
* @param dropper
* @param locX
* @param locY
* @param locZ
*/
public class ItemDropTask implements Runnable
public void dropMe(Creature dropper, int locX, int locY, int locZ)
{
private int _x, _y, _z;
private final Creature _dropper;
private final ItemInstance _itеm;
int x = locX;
int y = locY;
int z = locZ;
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
if (dropper != null)
{
_x = x;
_y = y;
_z = z;
_dropper = dropper;
_itеm = item;
final Instance instance = dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
x = dropDest.getX();
y = dropDest.getY();
z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
@Override
public void run()
// Set the x,y,z position of the ItemInstance dropped and update its world region
setSpawned(true);
setXYZ(x, y, z);
setDropTime(System.currentTimeMillis());
setDropperObjectId(dropper != null ? dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(this, getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
if (_dropper != null)
{
final Instance instance = _dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(_dropper.getX(), _dropper.getY(), _dropper.getZ(), _x, _y, _z, instance);
_x = dropDest.getX();
_y = dropDest.getY();
_z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
synchronized (_itеm)
{
// Set the x,y,z position of the ItemInstance dropped and update its _worldregion
_itеm.setSpawned(true);
_itеm.setXYZ(_x, _y, _z);
}
_itеm.setDropTime(System.currentTimeMillis());
_itеm.setDropperObjectId(_dropper != null ? _dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(_itеm, _itеm.getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().save(_itеm);
}
_itеm.setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
ItemsOnGroundManager.getInstance().save(this);
}
}
public void dropMe(Creature dropper, int x, int y, int z)
{
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
if ((dropper != null) && dropper.isPlayer())
{
_owner = null;
@ -1897,38 +1849,7 @@ public class ItemInstance extends WorldObject
}
else
{
if (_lifeTimeTask != null)
{
_lifeTimeTask.cancel(true);
}
_lifeTimeTask = ThreadPool.schedule(new ScheduleLifeTimeTask(this), getRemainingTime());
}
}
static class ScheduleLifeTimeTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleLifeTimeTask.class.getName());
private final ItemInstance _limitedItem;
ScheduleLifeTimeTask(ItemInstance item)
{
_limitedItem = item;
}
@Override
public void run()
{
try
{
if (_limitedItem != null)
{
_limitedItem.endOfLife();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
}
}
@ -2472,16 +2393,8 @@ public class ItemInstance extends WorldObject
public void stopAllTasks()
{
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
{
_lifeTimeTask.cancel(false);
_lifeTimeTask = null;
}
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
{
_appearanceLifeTimeTask.cancel(false);
_appearanceLifeTimeTask = null;
}
ItemLifeTimeTaskManager.getInstance().remove(this);
ItemAppearanceTaskManager.getInstance().remove(this);
}
public ItemVariables getVariables()
@ -2524,10 +2437,9 @@ public class ItemInstance extends WorldObject
getVariables().set(ItemVariables.VISUAL_ID, visualId);
// When removed, cancel existing lifetime task.
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
if (visualId == 0)
{
_appearanceLifeTimeTask.cancel(true);
_appearanceLifeTimeTask = null;
ItemAppearanceTaskManager.getInstance().remove(this);
onVisualLifeTimeEnd();
}
}
@ -2539,25 +2451,22 @@ public class ItemInstance extends WorldObject
public void scheduleVisualLifeTime()
{
if (_appearanceLifeTimeTask != null)
{
_appearanceLifeTimeTask.cancel(false);
}
ItemAppearanceTaskManager.getInstance().remove(this);
if (getVisualLifeTime() > 0)
{
final long time = getVisualLifeTime() - System.currentTimeMillis();
if (time > 0)
final long endTime = getVisualLifeTime();
if ((endTime - System.currentTimeMillis()) > 0)
{
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
ItemAppearanceTaskManager.getInstance().add(this, endTime);
}
else
{
ThreadPool.execute(this::onVisualLifeTimeEnd);
onVisualLifeTimeEnd();
}
}
}
private void onVisualLifeTimeEnd()
public void onVisualLifeTimeEnd()
{
final ItemVariables vars = getVariables();
vars.remove(ItemVariables.VISUAL_ID);

View File

@ -0,0 +1,86 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.buylist.Product;
/**
* @author Mobius
*/
public class BuyListTaskManager
{
private static final Map<Product, Long> PRODUCTS = new ConcurrentHashMap<>();
private static boolean _working = false;
public BuyListTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<Product, Long> entry : PRODUCTS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final Product product = entry.getKey();
PRODUCTS.remove(product);
product.restock();
}
}
_working = false;
}, 1000, 60000);
}
public void add(Product product, long endTime)
{
if (!PRODUCTS.containsKey(product))
{
PRODUCTS.put(product, endTime);
}
}
public void update(Product product, long endTime)
{
PRODUCTS.put(product, endTime);
}
public long getRestockDelay(Product product)
{
return PRODUCTS.getOrDefault(product, 0L);
}
public static BuyListTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final BuyListTaskManager INSTANCE = new BuyListTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemAppearanceTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemAppearanceTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.onVisualLifeTimeEnd();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemAppearanceTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemAppearanceTaskManager INSTANCE = new ItemAppearanceTaskManager();
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemLifeTimeTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static boolean _working = false;
public ItemLifeTimeTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.endOfLife();
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item, long endTime)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, endTime);
}
}
public void remove(ItemInstance item)
{
ITEMS.remove(item);
}
public static ItemLifeTimeTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemLifeTimeTaskManager INSTANCE = new ItemLifeTimeTaskManager();
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.taskmanager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
/**
* @author Mobius
*/
public class ItemManaTaskManager
{
private static final Map<ItemInstance, Long> ITEMS = new ConcurrentHashMap<>();
private static final int MANA_CONSUMPTION_RATE = 60000;
private static boolean _working = false;
public ItemManaTaskManager()
{
ThreadPool.scheduleAtFixedRate(() ->
{
if (_working)
{
return;
}
_working = true;
final long currentTime = System.currentTimeMillis();
for (Entry<ItemInstance, Long> entry : ITEMS.entrySet())
{
if (currentTime > entry.getValue().longValue())
{
final ItemInstance item = entry.getKey();
ITEMS.remove(item);
item.decreaseMana(true);
}
}
_working = false;
}, 1000, 1000);
}
public void add(ItemInstance item)
{
if (!ITEMS.containsKey(item))
{
ITEMS.put(item, System.currentTimeMillis() + MANA_CONSUMPTION_RATE);
}
}
public static ItemManaTaskManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ItemManaTaskManager INSTANCE = new ItemManaTaskManager();
}
}

View File

@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.model.items.Item;
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
/**
* @author NosBit
@ -45,7 +43,6 @@ public class Product
private final long _maxCount;
private final double _baseTax;
private AtomicLong _count = null;
private ScheduledFuture<?> _restockTask = null;
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
{
@ -122,10 +119,9 @@ public class Product
{
return false;
}
if ((_restockTask == null) || _restockTask.isDone())
{
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
}
BuyListTaskManager.getInstance().add(this, _restockDelay);
final boolean result = _count.addAndGet(-value) >= 0;
save();
return result;
@ -141,7 +137,7 @@ public class Product
final long remainTime = nextRestockTime - System.currentTimeMillis();
if (remainTime > 0)
{
_restockTask = ThreadPool.schedule(this::restock, remainTime);
BuyListTaskManager.getInstance().update(this, remainTime);
}
else
{
@ -164,9 +160,10 @@ public class Product
statement.setInt(2, _item.getId());
statement.setLong(3, getCount());
statement.setLong(5, getCount());
if ((_restockTask != null) && (_restockTask.getDelay(TimeUnit.MILLISECONDS) > 0))
final long nextRestockTime = BuyListTaskManager.getInstance().getRestockDelay(this);
if (nextRestockTime > 0)
{
final long nextRestockTime = System.currentTimeMillis() + _restockTask.getDelay(TimeUnit.MILLISECONDS);
statement.setLong(4, nextRestockTime);
statement.setLong(6, nextRestockTime);
}
@ -175,6 +172,7 @@ public class Product
statement.setLong(4, 0);
statement.setLong(6, 0);
}
statement.executeUpdate();
}
catch (Exception e)

View File

@ -34,7 +34,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
@ -88,6 +87,9 @@ import org.l2jmobius.gameserver.network.serverpackets.GetItem;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.ItemAppearanceTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemLifeTimeTaskManager;
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
import org.l2jmobius.gameserver.util.GMAudit;
/**
@ -139,7 +141,6 @@ public class ItemInstance extends WorldObject
/** Shadow item */
private int _mana = -1;
private boolean _consumingMana = false;
private static final int MANA_CONSUMPTION_RATE = 60000;
/** Custom item types (used loto, race tickets) */
private int _type1;
@ -169,8 +170,6 @@ public class ItemInstance extends WorldObject
private Map<AttributeType, AttributeHolder> _elementals = null;
private ScheduledFuture<?> _itemLootShedule = null;
private ScheduledFuture<?> _lifeTimeTask;
private ScheduledFuture<?> _appearanceLifeTimeTask;
private final DropProtection _dropProtection = new DropProtection();
@ -1280,37 +1279,6 @@ public class ItemInstance extends WorldObject
}
}
/**
* Used to decrease mana (mana means life time for shadow items)
*/
public static class ScheduleConsumeManaTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleConsumeManaTask.class.getName());
private final ItemInstance _shadowItem;
public ScheduleConsumeManaTask(ItemInstance item)
{
_shadowItem = item;
}
@Override
public void run()
{
try
{
// decrease mana
if (_shadowItem != null)
{
_shadowItem.decreaseMana(true);
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
}
}
/**
* Returns true if this item is a shadow item Shadow items have a limited life-time
* @return
@ -1455,7 +1423,7 @@ public class ItemInstance extends WorldObject
return;
}
_consumingMana = true;
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
ItemManaTaskManager.getInstance().add(this);
}
/**
@ -1524,62 +1492,46 @@ public class ItemInstance extends WorldObject
* <b><u>Example of use</u>:</b><br>
* <li>Drop item</li>
* <li>Call Pet</li>
* @param dropper
* @param locX
* @param locY
* @param locZ
*/
public class ItemDropTask implements Runnable
public void dropMe(Creature dropper, int locX, int locY, int locZ)
{
private int _x, _y, _z;
private final Creature _dropper;
private final ItemInstance _itеm;
int x = locX;
int y = locY;
int z = locZ;
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
if (dropper != null)
{
_x = x;
_y = y;
_z = z;
_dropper = dropper;
_itеm = item;
final Instance instance = dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
x = dropDest.getX();
y = dropDest.getY();
z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
@Override
public void run()
// Set the x,y,z position of the ItemInstance dropped and update its world region
setSpawned(true);
setXYZ(x, y, z);
setDropTime(System.currentTimeMillis());
setDropperObjectId(dropper != null ? dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(this, getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
if (_dropper != null)
{
final Instance instance = _dropper.getInstanceWorld();
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(_dropper.getX(), _dropper.getY(), _dropper.getZ(), _x, _y, _z, instance);
_x = dropDest.getX();
_y = dropDest.getY();
_z = dropDest.getZ();
setInstance(instance); // Inherit instancezone when dropped in visible world
}
else
{
setInstance(null); // No dropper? Make it a global item...
}
synchronized (_itеm)
{
// Set the x,y,z position of the ItemInstance dropped and update its _worldregion
_itеm.setSpawned(true);
_itеm.setXYZ(_x, _y, _z);
}
_itеm.setDropTime(System.currentTimeMillis());
_itеm.setDropperObjectId(_dropper != null ? _dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
// Add the ItemInstance dropped in the world as a visible object
World.getInstance().addVisibleObject(_itеm, _itеm.getWorldRegion());
if (Config.SAVE_DROPPED_ITEM)
{
ItemsOnGroundManager.getInstance().save(_itеm);
}
_itеm.setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
ItemsOnGroundManager.getInstance().save(this);
}
}
public void dropMe(Creature dropper, int x, int y, int z)
{
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
if ((dropper != null) && dropper.isPlayer())
{
_owner = null;
@ -1897,38 +1849,7 @@ public class ItemInstance extends WorldObject
}
else
{
if (_lifeTimeTask != null)
{
_lifeTimeTask.cancel(true);
}
_lifeTimeTask = ThreadPool.schedule(new ScheduleLifeTimeTask(this), getRemainingTime());
}
}
static class ScheduleLifeTimeTask implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(ScheduleLifeTimeTask.class.getName());
private final ItemInstance _limitedItem;
ScheduleLifeTimeTask(ItemInstance item)
{
_limitedItem = item;
}
@Override
public void run()
{
try
{
if (_limitedItem != null)
{
_limitedItem.endOfLife();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "", e);
}
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
}
}
@ -2472,16 +2393,8 @@ public class ItemInstance extends WorldObject
public void stopAllTasks()
{
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
{
_lifeTimeTask.cancel(false);
_lifeTimeTask = null;
}
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
{
_appearanceLifeTimeTask.cancel(false);
_appearanceLifeTimeTask = null;
}
ItemLifeTimeTaskManager.getInstance().remove(this);
ItemAppearanceTaskManager.getInstance().remove(this);
}
public ItemVariables getVariables()
@ -2524,10 +2437,9 @@ public class ItemInstance extends WorldObject
getVariables().set(ItemVariables.VISUAL_ID, visualId);
// When removed, cancel existing lifetime task.
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
if (visualId == 0)
{
_appearanceLifeTimeTask.cancel(true);
_appearanceLifeTimeTask = null;
ItemAppearanceTaskManager.getInstance().remove(this);
onVisualLifeTimeEnd();
}
}
@ -2539,25 +2451,22 @@ public class ItemInstance extends WorldObject
public void scheduleVisualLifeTime()
{
if (_appearanceLifeTimeTask != null)
{
_appearanceLifeTimeTask.cancel(false);
}
ItemAppearanceTaskManager.getInstance().remove(this);
if (getVisualLifeTime() > 0)
{
final long time = getVisualLifeTime() - System.currentTimeMillis();
if (time > 0)
final long endTime = getVisualLifeTime();
if ((endTime - System.currentTimeMillis()) > 0)
{
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
ItemAppearanceTaskManager.getInstance().add(this, endTime);
}
else
{
ThreadPool.execute(this::onVisualLifeTimeEnd);
onVisualLifeTimeEnd();
}
}
}
private void onVisualLifeTimeEnd()
public void onVisualLifeTimeEnd()
{
final ItemVariables vars = getVariables();
vars.remove(ItemVariables.VISUAL_ID);

Some files were not shown because too many files have changed in this diff Show More