Addition of item related task managers.
This commit is contained in:
@@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
|
|||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
||||||
|
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author NosBit
|
* @author NosBit
|
||||||
@@ -45,7 +43,6 @@ public class Product
|
|||||||
private final long _maxCount;
|
private final long _maxCount;
|
||||||
private final double _baseTax;
|
private final double _baseTax;
|
||||||
private AtomicLong _count = null;
|
private AtomicLong _count = null;
|
||||||
private ScheduledFuture<?> _restockTask = null;
|
|
||||||
|
|
||||||
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
||||||
{
|
{
|
||||||
@@ -122,10 +119,9 @@ public class Product
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((_restockTask == null) || _restockTask.isDone())
|
|
||||||
{
|
BuyListTaskManager.getInstance().add(this, _restockDelay);
|
||||||
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
|
|
||||||
}
|
|
||||||
final boolean result = _count.addAndGet(-value) >= 0;
|
final boolean result = _count.addAndGet(-value) >= 0;
|
||||||
save();
|
save();
|
||||||
return result;
|
return result;
|
||||||
@@ -141,7 +137,7 @@ public class Product
|
|||||||
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
||||||
if (remainTime > 0)
|
if (remainTime > 0)
|
||||||
{
|
{
|
||||||
_restockTask = ThreadPool.schedule(this::restock, remainTime);
|
BuyListTaskManager.getInstance().update(this, remainTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -164,9 +160,10 @@ public class Product
|
|||||||
statement.setInt(2, _item.getId());
|
statement.setInt(2, _item.getId());
|
||||||
statement.setLong(3, getCount());
|
statement.setLong(3, getCount());
|
||||||
statement.setLong(5, 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(4, nextRestockTime);
|
||||||
statement.setLong(6, nextRestockTime);
|
statement.setLong(6, nextRestockTime);
|
||||||
}
|
}
|
||||||
@@ -175,6 +172,7 @@ public class Product
|
|||||||
statement.setLong(4, 0);
|
statement.setLong(4, 0);
|
||||||
statement.setLong(6, 0);
|
statement.setLong(6, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
|
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.InventoryUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
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;
|
import org.l2jmobius.gameserver.util.GMAudit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -137,7 +139,6 @@ public class ItemInstance extends WorldObject
|
|||||||
/** Shadow item */
|
/** Shadow item */
|
||||||
private int _mana = -1;
|
private int _mana = -1;
|
||||||
private boolean _consumingMana = false;
|
private boolean _consumingMana = false;
|
||||||
private static final int MANA_CONSUMPTION_RATE = 60000;
|
|
||||||
|
|
||||||
/** Custom item types (used loto, race tickets) */
|
/** Custom item types (used loto, race tickets) */
|
||||||
private int _type1;
|
private int _type1;
|
||||||
@@ -167,8 +168,6 @@ public class ItemInstance extends WorldObject
|
|||||||
private Map<AttributeType, AttributeHolder> _elementals = null;
|
private Map<AttributeType, AttributeHolder> _elementals = null;
|
||||||
|
|
||||||
private ScheduledFuture<?> _itemLootShedule = null;
|
private ScheduledFuture<?> _itemLootShedule = null;
|
||||||
private ScheduledFuture<?> _lifeTimeTask;
|
|
||||||
private ScheduledFuture<?> _appearanceLifeTimeTask;
|
|
||||||
|
|
||||||
private final DropProtection _dropProtection = new DropProtection();
|
private final DropProtection _dropProtection = new DropProtection();
|
||||||
|
|
||||||
@@ -831,15 +830,11 @@ public class ItemInstance extends WorldObject
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!isPrivateWareHouse)
|
// augmented not tradeable
|
||||||
|
if (!isPrivateWareHouse && (!isTradeable() || isShadowItem()))
|
||||||
{
|
{
|
||||||
// augmented not tradeable
|
return false;
|
||||||
if (!isTradeable() || isShadowItem())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
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
|
* Returns true if this item is a shadow item Shadow items have a limited life-time
|
||||||
* @return
|
* @return
|
||||||
@@ -1454,7 +1418,7 @@ public class ItemInstance extends WorldObject
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_consumingMana = true;
|
_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>
|
* <b><u>Example of use</u>:</b><br>
|
||||||
* <li>Drop item</li>
|
* <li>Drop item</li>
|
||||||
* <li>Call Pet</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;
|
int x = locX;
|
||||||
private int _y;
|
int y = locY;
|
||||||
private int _z;
|
int z = locZ;
|
||||||
private final Creature _dropper;
|
|
||||||
private final ItemInstance _itеm;
|
|
||||||
|
|
||||||
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
|
if (dropper != null)
|
||||||
{
|
{
|
||||||
_x = x;
|
final Instance instance = dropper.getInstanceWorld();
|
||||||
_y = y;
|
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
|
||||||
_z = z;
|
x = dropDest.getX();
|
||||||
_dropper = dropper;
|
y = dropDest.getY();
|
||||||
_itеm = item;
|
z = dropDest.getZ();
|
||||||
|
setInstance(instance); // Inherit instancezone when dropped in visible world
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setInstance(null); // No dropper? Make it a global item...
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Set the x,y,z position of the ItemInstance dropped and update its world region
|
||||||
public void run()
|
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)
|
ItemsOnGroundManager.getInstance().save(this);
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
|
||||||
|
|
||||||
public void dropMe(Creature dropper, int x, int y, int z)
|
|
||||||
{
|
|
||||||
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
|
|
||||||
if ((dropper != null) && dropper.isPlayer())
|
if ((dropper != null) && dropper.isPlayer())
|
||||||
{
|
{
|
||||||
|
_owner = null;
|
||||||
|
|
||||||
// Notify to scripts
|
// Notify to scripts
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerItemDrop(dropper.getActingPlayer(), this, new Location(x, y, z)), getItem());
|
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerItemDrop(dropper.getActingPlayer(), this, new Location(x, y, z)), getItem());
|
||||||
}
|
}
|
||||||
@@ -1890,38 +1838,7 @@ public class ItemInstance extends WorldObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_lifeTimeTask != null)
|
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
|
||||||
{
|
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2185,16 +2102,8 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void stopAllTasks()
|
public void stopAllTasks()
|
||||||
{
|
{
|
||||||
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
|
ItemLifeTimeTaskManager.getInstance().remove(this);
|
||||||
{
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_lifeTimeTask.cancel(false);
|
|
||||||
_lifeTimeTask = null;
|
|
||||||
}
|
|
||||||
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
|
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemVariables getVariables()
|
public ItemVariables getVariables()
|
||||||
@@ -2237,10 +2146,9 @@ public class ItemInstance extends WorldObject
|
|||||||
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
||||||
|
|
||||||
// When removed, cancel existing lifetime task.
|
// When removed, cancel existing lifetime task.
|
||||||
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
|
if (visualId == 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask.cancel(true);
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
onVisualLifeTimeEnd();
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2252,25 +2160,22 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void scheduleVisualLifeTime()
|
public void scheduleVisualLifeTime()
|
||||||
{
|
{
|
||||||
if (_appearanceLifeTimeTask != null)
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
}
|
|
||||||
if (getVisualLifeTime() > 0)
|
if (getVisualLifeTime() > 0)
|
||||||
{
|
{
|
||||||
final long time = getVisualLifeTime() - System.currentTimeMillis();
|
final long endTime = getVisualLifeTime();
|
||||||
if (time > 0)
|
if ((endTime - System.currentTimeMillis()) > 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
|
ItemAppearanceTaskManager.getInstance().add(this, endTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadPool.execute(this::onVisualLifeTimeEnd);
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onVisualLifeTimeEnd()
|
public void onVisualLifeTimeEnd()
|
||||||
{
|
{
|
||||||
final ItemVariables vars = getVariables();
|
final ItemVariables vars = getVariables();
|
||||||
vars.remove(ItemVariables.VISUAL_ID);
|
vars.remove(ItemVariables.VISUAL_ID);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
|
|||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
||||||
|
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author NosBit
|
* @author NosBit
|
||||||
@@ -45,7 +43,6 @@ public class Product
|
|||||||
private final long _maxCount;
|
private final long _maxCount;
|
||||||
private final double _baseTax;
|
private final double _baseTax;
|
||||||
private AtomicLong _count = null;
|
private AtomicLong _count = null;
|
||||||
private ScheduledFuture<?> _restockTask = null;
|
|
||||||
|
|
||||||
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
||||||
{
|
{
|
||||||
@@ -122,10 +119,9 @@ public class Product
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((_restockTask == null) || _restockTask.isDone())
|
|
||||||
{
|
BuyListTaskManager.getInstance().add(this, _restockDelay);
|
||||||
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
|
|
||||||
}
|
|
||||||
final boolean result = _count.addAndGet(-value) >= 0;
|
final boolean result = _count.addAndGet(-value) >= 0;
|
||||||
save();
|
save();
|
||||||
return result;
|
return result;
|
||||||
@@ -141,7 +137,7 @@ public class Product
|
|||||||
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
||||||
if (remainTime > 0)
|
if (remainTime > 0)
|
||||||
{
|
{
|
||||||
_restockTask = ThreadPool.schedule(this::restock, remainTime);
|
BuyListTaskManager.getInstance().update(this, remainTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -164,9 +160,10 @@ public class Product
|
|||||||
statement.setInt(2, _item.getId());
|
statement.setInt(2, _item.getId());
|
||||||
statement.setLong(3, getCount());
|
statement.setLong(3, getCount());
|
||||||
statement.setLong(5, 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(4, nextRestockTime);
|
||||||
statement.setLong(6, nextRestockTime);
|
statement.setLong(6, nextRestockTime);
|
||||||
}
|
}
|
||||||
@@ -175,6 +172,7 @@ public class Product
|
|||||||
statement.setLong(4, 0);
|
statement.setLong(4, 0);
|
||||||
statement.setLong(6, 0);
|
statement.setLong(6, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
|
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.InventoryUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
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;
|
import org.l2jmobius.gameserver.util.GMAudit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -139,7 +141,6 @@ public class ItemInstance extends WorldObject
|
|||||||
/** Shadow item */
|
/** Shadow item */
|
||||||
private int _mana = -1;
|
private int _mana = -1;
|
||||||
private boolean _consumingMana = false;
|
private boolean _consumingMana = false;
|
||||||
private static final int MANA_CONSUMPTION_RATE = 60000;
|
|
||||||
|
|
||||||
/** Custom item types (used loto, race tickets) */
|
/** Custom item types (used loto, race tickets) */
|
||||||
private int _type1;
|
private int _type1;
|
||||||
@@ -169,8 +170,6 @@ public class ItemInstance extends WorldObject
|
|||||||
private Map<AttributeType, AttributeHolder> _elementals = null;
|
private Map<AttributeType, AttributeHolder> _elementals = null;
|
||||||
|
|
||||||
private ScheduledFuture<?> _itemLootShedule = null;
|
private ScheduledFuture<?> _itemLootShedule = null;
|
||||||
private ScheduledFuture<?> _lifeTimeTask;
|
|
||||||
private ScheduledFuture<?> _appearanceLifeTimeTask;
|
|
||||||
|
|
||||||
private final DropProtection _dropProtection = new DropProtection();
|
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
|
* Returns true if this item is a shadow item Shadow items have a limited life-time
|
||||||
* @return
|
* @return
|
||||||
@@ -1455,7 +1423,7 @@ public class ItemInstance extends WorldObject
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_consumingMana = true;
|
_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>
|
* <b><u>Example of use</u>:</b><br>
|
||||||
* <li>Drop item</li>
|
* <li>Drop item</li>
|
||||||
* <li>Call Pet</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;
|
int x = locX;
|
||||||
private int _y;
|
int y = locY;
|
||||||
private int _z;
|
int z = locZ;
|
||||||
private final Creature _dropper;
|
|
||||||
private final ItemInstance _itеm;
|
|
||||||
|
|
||||||
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
|
if (dropper != null)
|
||||||
{
|
{
|
||||||
_x = x;
|
final Instance instance = dropper.getInstanceWorld();
|
||||||
_y = y;
|
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
|
||||||
_z = z;
|
x = dropDest.getX();
|
||||||
_dropper = dropper;
|
y = dropDest.getY();
|
||||||
_itеm = item;
|
z = dropDest.getZ();
|
||||||
|
setInstance(instance); // Inherit instancezone when dropped in visible world
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setInstance(null); // No dropper? Make it a global item...
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Set the x,y,z position of the ItemInstance dropped and update its world region
|
||||||
public void run()
|
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)
|
ItemsOnGroundManager.getInstance().save(this);
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
|
||||||
|
|
||||||
public void dropMe(Creature dropper, int x, int y, int z)
|
|
||||||
{
|
|
||||||
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
|
|
||||||
if ((dropper != null) && dropper.isPlayer())
|
if ((dropper != null) && dropper.isPlayer())
|
||||||
{
|
{
|
||||||
_owner = null;
|
_owner = null;
|
||||||
@@ -1899,38 +1849,7 @@ public class ItemInstance extends WorldObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_lifeTimeTask != null)
|
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
|
||||||
{
|
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2440,16 +2359,8 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void stopAllTasks()
|
public void stopAllTasks()
|
||||||
{
|
{
|
||||||
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
|
ItemLifeTimeTaskManager.getInstance().remove(this);
|
||||||
{
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_lifeTimeTask.cancel(false);
|
|
||||||
_lifeTimeTask = null;
|
|
||||||
}
|
|
||||||
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
|
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemVariables getVariables()
|
public ItemVariables getVariables()
|
||||||
@@ -2492,10 +2403,9 @@ public class ItemInstance extends WorldObject
|
|||||||
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
||||||
|
|
||||||
// When removed, cancel existing lifetime task.
|
// When removed, cancel existing lifetime task.
|
||||||
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
|
if (visualId == 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask.cancel(true);
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
onVisualLifeTimeEnd();
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2507,25 +2417,22 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void scheduleVisualLifeTime()
|
public void scheduleVisualLifeTime()
|
||||||
{
|
{
|
||||||
if (_appearanceLifeTimeTask != null)
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
}
|
|
||||||
if (getVisualLifeTime() > 0)
|
if (getVisualLifeTime() > 0)
|
||||||
{
|
{
|
||||||
final long time = getVisualLifeTime() - System.currentTimeMillis();
|
final long endTime = getVisualLifeTime();
|
||||||
if (time > 0)
|
if ((endTime - System.currentTimeMillis()) > 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
|
ItemAppearanceTaskManager.getInstance().add(this, endTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadPool.execute(this::onVisualLifeTimeEnd);
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onVisualLifeTimeEnd()
|
public void onVisualLifeTimeEnd()
|
||||||
{
|
{
|
||||||
final ItemVariables vars = getVariables();
|
final ItemVariables vars = getVariables();
|
||||||
vars.remove(ItemVariables.VISUAL_ID);
|
vars.remove(ItemVariables.VISUAL_ID);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
|
|||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
||||||
|
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author NosBit
|
* @author NosBit
|
||||||
@@ -45,7 +43,6 @@ public class Product
|
|||||||
private final long _maxCount;
|
private final long _maxCount;
|
||||||
private final double _baseTax;
|
private final double _baseTax;
|
||||||
private AtomicLong _count = null;
|
private AtomicLong _count = null;
|
||||||
private ScheduledFuture<?> _restockTask = null;
|
|
||||||
|
|
||||||
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
||||||
{
|
{
|
||||||
@@ -122,10 +119,9 @@ public class Product
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((_restockTask == null) || _restockTask.isDone())
|
|
||||||
{
|
BuyListTaskManager.getInstance().add(this, _restockDelay);
|
||||||
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
|
|
||||||
}
|
|
||||||
final boolean result = _count.addAndGet(-value) >= 0;
|
final boolean result = _count.addAndGet(-value) >= 0;
|
||||||
save();
|
save();
|
||||||
return result;
|
return result;
|
||||||
@@ -141,7 +137,7 @@ public class Product
|
|||||||
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
||||||
if (remainTime > 0)
|
if (remainTime > 0)
|
||||||
{
|
{
|
||||||
_restockTask = ThreadPool.schedule(this::restock, remainTime);
|
BuyListTaskManager.getInstance().update(this, remainTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -164,9 +160,10 @@ public class Product
|
|||||||
statement.setInt(2, _item.getId());
|
statement.setInt(2, _item.getId());
|
||||||
statement.setLong(3, getCount());
|
statement.setLong(3, getCount());
|
||||||
statement.setLong(5, 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(4, nextRestockTime);
|
||||||
statement.setLong(6, nextRestockTime);
|
statement.setLong(6, nextRestockTime);
|
||||||
}
|
}
|
||||||
@@ -175,6 +172,7 @@ public class Product
|
|||||||
statement.setLong(4, 0);
|
statement.setLong(4, 0);
|
||||||
statement.setLong(6, 0);
|
statement.setLong(6, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
|
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.InventoryUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
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;
|
import org.l2jmobius.gameserver.util.GMAudit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -139,7 +141,6 @@ public class ItemInstance extends WorldObject
|
|||||||
/** Shadow item */
|
/** Shadow item */
|
||||||
private int _mana = -1;
|
private int _mana = -1;
|
||||||
private boolean _consumingMana = false;
|
private boolean _consumingMana = false;
|
||||||
private static final int MANA_CONSUMPTION_RATE = 60000;
|
|
||||||
|
|
||||||
/** Custom item types (used loto, race tickets) */
|
/** Custom item types (used loto, race tickets) */
|
||||||
private int _type1;
|
private int _type1;
|
||||||
@@ -169,8 +170,6 @@ public class ItemInstance extends WorldObject
|
|||||||
private Map<AttributeType, AttributeHolder> _elementals = null;
|
private Map<AttributeType, AttributeHolder> _elementals = null;
|
||||||
|
|
||||||
private ScheduledFuture<?> _itemLootShedule = null;
|
private ScheduledFuture<?> _itemLootShedule = null;
|
||||||
private ScheduledFuture<?> _lifeTimeTask;
|
|
||||||
private ScheduledFuture<?> _appearanceLifeTimeTask;
|
|
||||||
|
|
||||||
private final DropProtection _dropProtection = new DropProtection();
|
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
|
* Returns true if this item is a shadow item Shadow items have a limited life-time
|
||||||
* @return
|
* @return
|
||||||
@@ -1455,7 +1423,7 @@ public class ItemInstance extends WorldObject
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_consumingMana = true;
|
_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>
|
* <b><u>Example of use</u>:</b><br>
|
||||||
* <li>Drop item</li>
|
* <li>Drop item</li>
|
||||||
* <li>Call Pet</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;
|
int x = locX;
|
||||||
private int _y;
|
int y = locY;
|
||||||
private int _z;
|
int z = locZ;
|
||||||
private final Creature _dropper;
|
|
||||||
private final ItemInstance _itеm;
|
|
||||||
|
|
||||||
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
|
if (dropper != null)
|
||||||
{
|
{
|
||||||
_x = x;
|
final Instance instance = dropper.getInstanceWorld();
|
||||||
_y = y;
|
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
|
||||||
_z = z;
|
x = dropDest.getX();
|
||||||
_dropper = dropper;
|
y = dropDest.getY();
|
||||||
_itеm = item;
|
z = dropDest.getZ();
|
||||||
|
setInstance(instance); // Inherit instancezone when dropped in visible world
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setInstance(null); // No dropper? Make it a global item...
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Set the x,y,z position of the ItemInstance dropped and update its world region
|
||||||
public void run()
|
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)
|
ItemsOnGroundManager.getInstance().save(this);
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
|
||||||
|
|
||||||
public void dropMe(Creature dropper, int x, int y, int z)
|
|
||||||
{
|
|
||||||
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
|
|
||||||
if ((dropper != null) && dropper.isPlayer())
|
if ((dropper != null) && dropper.isPlayer())
|
||||||
{
|
{
|
||||||
_owner = null;
|
_owner = null;
|
||||||
@@ -1899,38 +1849,7 @@ public class ItemInstance extends WorldObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_lifeTimeTask != null)
|
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
|
||||||
{
|
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2440,16 +2359,8 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void stopAllTasks()
|
public void stopAllTasks()
|
||||||
{
|
{
|
||||||
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
|
ItemLifeTimeTaskManager.getInstance().remove(this);
|
||||||
{
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_lifeTimeTask.cancel(false);
|
|
||||||
_lifeTimeTask = null;
|
|
||||||
}
|
|
||||||
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
|
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemVariables getVariables()
|
public ItemVariables getVariables()
|
||||||
@@ -2492,10 +2403,9 @@ public class ItemInstance extends WorldObject
|
|||||||
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
||||||
|
|
||||||
// When removed, cancel existing lifetime task.
|
// When removed, cancel existing lifetime task.
|
||||||
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
|
if (visualId == 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask.cancel(true);
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
onVisualLifeTimeEnd();
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2507,25 +2417,22 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void scheduleVisualLifeTime()
|
public void scheduleVisualLifeTime()
|
||||||
{
|
{
|
||||||
if (_appearanceLifeTimeTask != null)
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
}
|
|
||||||
if (getVisualLifeTime() > 0)
|
if (getVisualLifeTime() > 0)
|
||||||
{
|
{
|
||||||
final long time = getVisualLifeTime() - System.currentTimeMillis();
|
final long endTime = getVisualLifeTime();
|
||||||
if (time > 0)
|
if ((endTime - System.currentTimeMillis()) > 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
|
ItemAppearanceTaskManager.getInstance().add(this, endTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadPool.execute(this::onVisualLifeTimeEnd);
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onVisualLifeTimeEnd()
|
public void onVisualLifeTimeEnd()
|
||||||
{
|
{
|
||||||
final ItemVariables vars = getVariables();
|
final ItemVariables vars = getVariables();
|
||||||
vars.remove(ItemVariables.VISUAL_ID);
|
vars.remove(ItemVariables.VISUAL_ID);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
|
|||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
||||||
|
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author NosBit
|
* @author NosBit
|
||||||
@@ -45,7 +43,6 @@ public class Product
|
|||||||
private final long _maxCount;
|
private final long _maxCount;
|
||||||
private final double _baseTax;
|
private final double _baseTax;
|
||||||
private AtomicLong _count = null;
|
private AtomicLong _count = null;
|
||||||
private ScheduledFuture<?> _restockTask = null;
|
|
||||||
|
|
||||||
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
||||||
{
|
{
|
||||||
@@ -122,10 +119,9 @@ public class Product
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((_restockTask == null) || _restockTask.isDone())
|
|
||||||
{
|
BuyListTaskManager.getInstance().add(this, _restockDelay);
|
||||||
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
|
|
||||||
}
|
|
||||||
final boolean result = _count.addAndGet(-value) >= 0;
|
final boolean result = _count.addAndGet(-value) >= 0;
|
||||||
save();
|
save();
|
||||||
return result;
|
return result;
|
||||||
@@ -141,7 +137,7 @@ public class Product
|
|||||||
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
||||||
if (remainTime > 0)
|
if (remainTime > 0)
|
||||||
{
|
{
|
||||||
_restockTask = ThreadPool.schedule(this::restock, remainTime);
|
BuyListTaskManager.getInstance().update(this, remainTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -164,9 +160,10 @@ public class Product
|
|||||||
statement.setInt(2, _item.getId());
|
statement.setInt(2, _item.getId());
|
||||||
statement.setLong(3, getCount());
|
statement.setLong(3, getCount());
|
||||||
statement.setLong(5, 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(4, nextRestockTime);
|
||||||
statement.setLong(6, nextRestockTime);
|
statement.setLong(6, nextRestockTime);
|
||||||
}
|
}
|
||||||
@@ -175,6 +172,7 @@ public class Product
|
|||||||
statement.setLong(4, 0);
|
statement.setLong(4, 0);
|
||||||
statement.setLong(6, 0);
|
statement.setLong(6, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
|
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.InventoryUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
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;
|
import org.l2jmobius.gameserver.util.GMAudit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -139,7 +141,6 @@ public class ItemInstance extends WorldObject
|
|||||||
/** Shadow item */
|
/** Shadow item */
|
||||||
private int _mana = -1;
|
private int _mana = -1;
|
||||||
private boolean _consumingMana = false;
|
private boolean _consumingMana = false;
|
||||||
private static final int MANA_CONSUMPTION_RATE = 60000;
|
|
||||||
|
|
||||||
/** Custom item types (used loto, race tickets) */
|
/** Custom item types (used loto, race tickets) */
|
||||||
private int _type1;
|
private int _type1;
|
||||||
@@ -169,8 +170,6 @@ public class ItemInstance extends WorldObject
|
|||||||
private Map<AttributeType, AttributeHolder> _elementals = null;
|
private Map<AttributeType, AttributeHolder> _elementals = null;
|
||||||
|
|
||||||
private ScheduledFuture<?> _itemLootShedule = null;
|
private ScheduledFuture<?> _itemLootShedule = null;
|
||||||
private ScheduledFuture<?> _lifeTimeTask;
|
|
||||||
private ScheduledFuture<?> _appearanceLifeTimeTask;
|
|
||||||
|
|
||||||
private final DropProtection _dropProtection = new DropProtection();
|
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
|
* Returns true if this item is a shadow item Shadow items have a limited life-time
|
||||||
* @return
|
* @return
|
||||||
@@ -1455,7 +1423,7 @@ public class ItemInstance extends WorldObject
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_consumingMana = true;
|
_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>
|
* <b><u>Example of use</u>:</b><br>
|
||||||
* <li>Drop item</li>
|
* <li>Drop item</li>
|
||||||
* <li>Call Pet</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;
|
int x = locX;
|
||||||
private int _y;
|
int y = locY;
|
||||||
private int _z;
|
int z = locZ;
|
||||||
private final Creature _dropper;
|
|
||||||
private final ItemInstance _itеm;
|
|
||||||
|
|
||||||
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
|
if (dropper != null)
|
||||||
{
|
{
|
||||||
_x = x;
|
final Instance instance = dropper.getInstanceWorld();
|
||||||
_y = y;
|
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
|
||||||
_z = z;
|
x = dropDest.getX();
|
||||||
_dropper = dropper;
|
y = dropDest.getY();
|
||||||
_itеm = item;
|
z = dropDest.getZ();
|
||||||
|
setInstance(instance); // Inherit instancezone when dropped in visible world
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setInstance(null); // No dropper? Make it a global item...
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Set the x,y,z position of the ItemInstance dropped and update its world region
|
||||||
public void run()
|
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)
|
ItemsOnGroundManager.getInstance().save(this);
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
|
||||||
|
|
||||||
public void dropMe(Creature dropper, int x, int y, int z)
|
|
||||||
{
|
|
||||||
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
|
|
||||||
if ((dropper != null) && dropper.isPlayer())
|
if ((dropper != null) && dropper.isPlayer())
|
||||||
{
|
{
|
||||||
_owner = null;
|
_owner = null;
|
||||||
@@ -1899,38 +1849,7 @@ public class ItemInstance extends WorldObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_lifeTimeTask != null)
|
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
|
||||||
{
|
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2474,16 +2393,8 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void stopAllTasks()
|
public void stopAllTasks()
|
||||||
{
|
{
|
||||||
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
|
ItemLifeTimeTaskManager.getInstance().remove(this);
|
||||||
{
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_lifeTimeTask.cancel(false);
|
|
||||||
_lifeTimeTask = null;
|
|
||||||
}
|
|
||||||
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
|
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemVariables getVariables()
|
public ItemVariables getVariables()
|
||||||
@@ -2526,10 +2437,9 @@ public class ItemInstance extends WorldObject
|
|||||||
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
||||||
|
|
||||||
// When removed, cancel existing lifetime task.
|
// When removed, cancel existing lifetime task.
|
||||||
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
|
if (visualId == 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask.cancel(true);
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
onVisualLifeTimeEnd();
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2541,25 +2451,22 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void scheduleVisualLifeTime()
|
public void scheduleVisualLifeTime()
|
||||||
{
|
{
|
||||||
if (_appearanceLifeTimeTask != null)
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
}
|
|
||||||
if (getVisualLifeTime() > 0)
|
if (getVisualLifeTime() > 0)
|
||||||
{
|
{
|
||||||
final long time = getVisualLifeTime() - System.currentTimeMillis();
|
final long endTime = getVisualLifeTime();
|
||||||
if (time > 0)
|
if ((endTime - System.currentTimeMillis()) > 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
|
ItemAppearanceTaskManager.getInstance().add(this, endTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadPool.execute(this::onVisualLifeTimeEnd);
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onVisualLifeTimeEnd()
|
public void onVisualLifeTimeEnd()
|
||||||
{
|
{
|
||||||
final ItemVariables vars = getVariables();
|
final ItemVariables vars = getVariables();
|
||||||
vars.remove(ItemVariables.VISUAL_ID);
|
vars.remove(ItemVariables.VISUAL_ID);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
|
|||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
||||||
|
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author NosBit
|
* @author NosBit
|
||||||
@@ -45,7 +43,6 @@ public class Product
|
|||||||
private final long _maxCount;
|
private final long _maxCount;
|
||||||
private final double _baseTax;
|
private final double _baseTax;
|
||||||
private AtomicLong _count = null;
|
private AtomicLong _count = null;
|
||||||
private ScheduledFuture<?> _restockTask = null;
|
|
||||||
|
|
||||||
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
||||||
{
|
{
|
||||||
@@ -122,10 +119,9 @@ public class Product
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((_restockTask == null) || _restockTask.isDone())
|
|
||||||
{
|
BuyListTaskManager.getInstance().add(this, _restockDelay);
|
||||||
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
|
|
||||||
}
|
|
||||||
final boolean result = _count.addAndGet(-value) >= 0;
|
final boolean result = _count.addAndGet(-value) >= 0;
|
||||||
save();
|
save();
|
||||||
return result;
|
return result;
|
||||||
@@ -141,7 +137,7 @@ public class Product
|
|||||||
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
||||||
if (remainTime > 0)
|
if (remainTime > 0)
|
||||||
{
|
{
|
||||||
_restockTask = ThreadPool.schedule(this::restock, remainTime);
|
BuyListTaskManager.getInstance().update(this, remainTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -164,9 +160,10 @@ public class Product
|
|||||||
statement.setInt(2, _item.getId());
|
statement.setInt(2, _item.getId());
|
||||||
statement.setLong(3, getCount());
|
statement.setLong(3, getCount());
|
||||||
statement.setLong(5, 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(4, nextRestockTime);
|
||||||
statement.setLong(6, nextRestockTime);
|
statement.setLong(6, nextRestockTime);
|
||||||
}
|
}
|
||||||
@@ -175,6 +172,7 @@ public class Product
|
|||||||
statement.setLong(4, 0);
|
statement.setLong(4, 0);
|
||||||
statement.setLong(6, 0);
|
statement.setLong(6, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
|
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.InventoryUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
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;
|
import org.l2jmobius.gameserver.util.GMAudit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -142,7 +144,6 @@ public class ItemInstance extends WorldObject
|
|||||||
/** Shadow item */
|
/** Shadow item */
|
||||||
private int _mana = -1;
|
private int _mana = -1;
|
||||||
private boolean _consumingMana = false;
|
private boolean _consumingMana = false;
|
||||||
private static final int MANA_CONSUMPTION_RATE = 60000;
|
|
||||||
|
|
||||||
/** Custom item types (used loto, race tickets) */
|
/** Custom item types (used loto, race tickets) */
|
||||||
private int _type1;
|
private int _type1;
|
||||||
@@ -172,8 +173,6 @@ public class ItemInstance extends WorldObject
|
|||||||
private Map<AttributeType, AttributeHolder> _elementals = null;
|
private Map<AttributeType, AttributeHolder> _elementals = null;
|
||||||
|
|
||||||
private ScheduledFuture<?> _itemLootShedule = null;
|
private ScheduledFuture<?> _itemLootShedule = null;
|
||||||
private ScheduledFuture<?> _lifeTimeTask;
|
|
||||||
private ScheduledFuture<?> _appearanceLifeTimeTask;
|
|
||||||
|
|
||||||
private final DropProtection _dropProtection = new DropProtection();
|
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
|
* Returns true if this item is a shadow item Shadow items have a limited life-time
|
||||||
* @return
|
* @return
|
||||||
@@ -1463,7 +1431,7 @@ public class ItemInstance extends WorldObject
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_consumingMana = true;
|
_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>
|
* <b><u>Example of use</u>:</b><br>
|
||||||
* <li>Drop item</li>
|
* <li>Drop item</li>
|
||||||
* <li>Call Pet</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;
|
int x = locX;
|
||||||
private int _y;
|
int y = locY;
|
||||||
private int _z;
|
int z = locZ;
|
||||||
private final Creature _dropper;
|
|
||||||
private final ItemInstance _itеm;
|
|
||||||
|
|
||||||
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
|
if (dropper != null)
|
||||||
{
|
{
|
||||||
_x = x;
|
final Instance instance = dropper.getInstanceWorld();
|
||||||
_y = y;
|
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
|
||||||
_z = z;
|
x = dropDest.getX();
|
||||||
_dropper = dropper;
|
y = dropDest.getY();
|
||||||
_itеm = item;
|
z = dropDest.getZ();
|
||||||
|
setInstance(instance); // Inherit instancezone when dropped in visible world
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setInstance(null); // No dropper? Make it a global item...
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Set the x,y,z position of the ItemInstance dropped and update its world region
|
||||||
public void run()
|
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)
|
ItemsOnGroundManager.getInstance().save(this);
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
|
||||||
|
|
||||||
public void dropMe(Creature dropper, int x, int y, int z)
|
|
||||||
{
|
|
||||||
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
|
|
||||||
if ((dropper != null) && dropper.isPlayer())
|
if ((dropper != null) && dropper.isPlayer())
|
||||||
{
|
{
|
||||||
_owner = null;
|
_owner = null;
|
||||||
@@ -1907,38 +1857,7 @@ public class ItemInstance extends WorldObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_lifeTimeTask != null)
|
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
|
||||||
{
|
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2485,16 +2404,8 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void stopAllTasks()
|
public void stopAllTasks()
|
||||||
{
|
{
|
||||||
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
|
ItemLifeTimeTaskManager.getInstance().remove(this);
|
||||||
{
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_lifeTimeTask.cancel(false);
|
|
||||||
_lifeTimeTask = null;
|
|
||||||
}
|
|
||||||
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
|
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemVariables getVariables()
|
public ItemVariables getVariables()
|
||||||
@@ -2537,10 +2448,9 @@ public class ItemInstance extends WorldObject
|
|||||||
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
||||||
|
|
||||||
// When removed, cancel existing lifetime task.
|
// When removed, cancel existing lifetime task.
|
||||||
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
|
if (visualId == 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask.cancel(true);
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
onVisualLifeTimeEnd();
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2552,25 +2462,22 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void scheduleVisualLifeTime()
|
public void scheduleVisualLifeTime()
|
||||||
{
|
{
|
||||||
if (_appearanceLifeTimeTask != null)
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
}
|
|
||||||
if (getVisualLifeTime() > 0)
|
if (getVisualLifeTime() > 0)
|
||||||
{
|
{
|
||||||
final long time = getVisualLifeTime() - System.currentTimeMillis();
|
final long endTime = getVisualLifeTime();
|
||||||
if (time > 0)
|
if ((endTime - System.currentTimeMillis()) > 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
|
ItemAppearanceTaskManager.getInstance().add(this, endTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadPool.execute(this::onVisualLifeTimeEnd);
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onVisualLifeTimeEnd()
|
public void onVisualLifeTimeEnd()
|
||||||
{
|
{
|
||||||
final ItemVariables vars = getVariables();
|
final ItemVariables vars = getVariables();
|
||||||
vars.remove(ItemVariables.VISUAL_ID);
|
vars.remove(ItemVariables.VISUAL_ID);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
|
|||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
||||||
|
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author NosBit
|
* @author NosBit
|
||||||
@@ -45,7 +43,6 @@ public class Product
|
|||||||
private final long _maxCount;
|
private final long _maxCount;
|
||||||
private final double _baseTax;
|
private final double _baseTax;
|
||||||
private AtomicLong _count = null;
|
private AtomicLong _count = null;
|
||||||
private ScheduledFuture<?> _restockTask = null;
|
|
||||||
|
|
||||||
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
||||||
{
|
{
|
||||||
@@ -122,10 +119,9 @@ public class Product
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((_restockTask == null) || _restockTask.isDone())
|
|
||||||
{
|
BuyListTaskManager.getInstance().add(this, _restockDelay);
|
||||||
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
|
|
||||||
}
|
|
||||||
final boolean result = _count.addAndGet(-value) >= 0;
|
final boolean result = _count.addAndGet(-value) >= 0;
|
||||||
save();
|
save();
|
||||||
return result;
|
return result;
|
||||||
@@ -141,7 +137,7 @@ public class Product
|
|||||||
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
||||||
if (remainTime > 0)
|
if (remainTime > 0)
|
||||||
{
|
{
|
||||||
_restockTask = ThreadPool.schedule(this::restock, remainTime);
|
BuyListTaskManager.getInstance().update(this, remainTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -164,9 +160,10 @@ public class Product
|
|||||||
statement.setInt(2, _item.getId());
|
statement.setInt(2, _item.getId());
|
||||||
statement.setLong(3, getCount());
|
statement.setLong(3, getCount());
|
||||||
statement.setLong(5, 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(4, nextRestockTime);
|
||||||
statement.setLong(6, nextRestockTime);
|
statement.setLong(6, nextRestockTime);
|
||||||
}
|
}
|
||||||
@@ -175,6 +172,7 @@ public class Product
|
|||||||
statement.setLong(4, 0);
|
statement.setLong(4, 0);
|
||||||
statement.setLong(6, 0);
|
statement.setLong(6, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
|
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.InventoryUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
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;
|
import org.l2jmobius.gameserver.util.GMAudit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -142,7 +144,6 @@ public class ItemInstance extends WorldObject
|
|||||||
/** Shadow item */
|
/** Shadow item */
|
||||||
private int _mana = -1;
|
private int _mana = -1;
|
||||||
private boolean _consumingMana = false;
|
private boolean _consumingMana = false;
|
||||||
private static final int MANA_CONSUMPTION_RATE = 60000;
|
|
||||||
|
|
||||||
/** Custom item types (used loto, race tickets) */
|
/** Custom item types (used loto, race tickets) */
|
||||||
private int _type1;
|
private int _type1;
|
||||||
@@ -172,8 +173,6 @@ public class ItemInstance extends WorldObject
|
|||||||
private Map<AttributeType, AttributeHolder> _elementals = null;
|
private Map<AttributeType, AttributeHolder> _elementals = null;
|
||||||
|
|
||||||
private ScheduledFuture<?> _itemLootShedule = null;
|
private ScheduledFuture<?> _itemLootShedule = null;
|
||||||
private ScheduledFuture<?> _lifeTimeTask;
|
|
||||||
private ScheduledFuture<?> _appearanceLifeTimeTask;
|
|
||||||
|
|
||||||
private final DropProtection _dropProtection = new DropProtection();
|
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
|
* Returns true if this item is a shadow item Shadow items have a limited life-time
|
||||||
* @return
|
* @return
|
||||||
@@ -1463,7 +1431,7 @@ public class ItemInstance extends WorldObject
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_consumingMana = true;
|
_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>
|
* <b><u>Example of use</u>:</b><br>
|
||||||
* <li>Drop item</li>
|
* <li>Drop item</li>
|
||||||
* <li>Call Pet</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;
|
int x = locX;
|
||||||
private int _y;
|
int y = locY;
|
||||||
private int _z;
|
int z = locZ;
|
||||||
private final Creature _dropper;
|
|
||||||
private final ItemInstance _itеm;
|
|
||||||
|
|
||||||
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
|
if (dropper != null)
|
||||||
{
|
{
|
||||||
_x = x;
|
final Instance instance = dropper.getInstanceWorld();
|
||||||
_y = y;
|
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
|
||||||
_z = z;
|
x = dropDest.getX();
|
||||||
_dropper = dropper;
|
y = dropDest.getY();
|
||||||
_itеm = item;
|
z = dropDest.getZ();
|
||||||
|
setInstance(instance); // Inherit instancezone when dropped in visible world
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setInstance(null); // No dropper? Make it a global item...
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Set the x,y,z position of the ItemInstance dropped and update its world region
|
||||||
public void run()
|
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)
|
ItemsOnGroundManager.getInstance().save(this);
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
|
||||||
|
|
||||||
public void dropMe(Creature dropper, int x, int y, int z)
|
|
||||||
{
|
|
||||||
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
|
|
||||||
if ((dropper != null) && dropper.isPlayer())
|
if ((dropper != null) && dropper.isPlayer())
|
||||||
{
|
{
|
||||||
_owner = null;
|
_owner = null;
|
||||||
@@ -1907,38 +1857,7 @@ public class ItemInstance extends WorldObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_lifeTimeTask != null)
|
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
|
||||||
{
|
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2485,16 +2404,8 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void stopAllTasks()
|
public void stopAllTasks()
|
||||||
{
|
{
|
||||||
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
|
ItemLifeTimeTaskManager.getInstance().remove(this);
|
||||||
{
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_lifeTimeTask.cancel(false);
|
|
||||||
_lifeTimeTask = null;
|
|
||||||
}
|
|
||||||
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
|
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemVariables getVariables()
|
public ItemVariables getVariables()
|
||||||
@@ -2537,10 +2448,9 @@ public class ItemInstance extends WorldObject
|
|||||||
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
||||||
|
|
||||||
// When removed, cancel existing lifetime task.
|
// When removed, cancel existing lifetime task.
|
||||||
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
|
if (visualId == 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask.cancel(true);
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
onVisualLifeTimeEnd();
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2552,25 +2462,22 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void scheduleVisualLifeTime()
|
public void scheduleVisualLifeTime()
|
||||||
{
|
{
|
||||||
if (_appearanceLifeTimeTask != null)
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
}
|
|
||||||
if (getVisualLifeTime() > 0)
|
if (getVisualLifeTime() > 0)
|
||||||
{
|
{
|
||||||
final long time = getVisualLifeTime() - System.currentTimeMillis();
|
final long endTime = getVisualLifeTime();
|
||||||
if (time > 0)
|
if ((endTime - System.currentTimeMillis()) > 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
|
ItemAppearanceTaskManager.getInstance().add(this, endTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadPool.execute(this::onVisualLifeTimeEnd);
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onVisualLifeTimeEnd()
|
public void onVisualLifeTimeEnd()
|
||||||
{
|
{
|
||||||
final ItemVariables vars = getVariables();
|
final ItemVariables vars = getVariables();
|
||||||
vars.remove(ItemVariables.VISUAL_ID);
|
vars.remove(ItemVariables.VISUAL_ID);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
|
|||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
||||||
|
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author NosBit
|
* @author NosBit
|
||||||
@@ -45,7 +43,6 @@ public class Product
|
|||||||
private final long _maxCount;
|
private final long _maxCount;
|
||||||
private final double _baseTax;
|
private final double _baseTax;
|
||||||
private AtomicLong _count = null;
|
private AtomicLong _count = null;
|
||||||
private ScheduledFuture<?> _restockTask = null;
|
|
||||||
|
|
||||||
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
||||||
{
|
{
|
||||||
@@ -122,10 +119,9 @@ public class Product
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((_restockTask == null) || _restockTask.isDone())
|
|
||||||
{
|
BuyListTaskManager.getInstance().add(this, _restockDelay);
|
||||||
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
|
|
||||||
}
|
|
||||||
final boolean result = _count.addAndGet(-value) >= 0;
|
final boolean result = _count.addAndGet(-value) >= 0;
|
||||||
save();
|
save();
|
||||||
return result;
|
return result;
|
||||||
@@ -141,7 +137,7 @@ public class Product
|
|||||||
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
||||||
if (remainTime > 0)
|
if (remainTime > 0)
|
||||||
{
|
{
|
||||||
_restockTask = ThreadPool.schedule(this::restock, remainTime);
|
BuyListTaskManager.getInstance().update(this, remainTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -164,9 +160,10 @@ public class Product
|
|||||||
statement.setInt(2, _item.getId());
|
statement.setInt(2, _item.getId());
|
||||||
statement.setLong(3, getCount());
|
statement.setLong(3, getCount());
|
||||||
statement.setLong(5, 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(4, nextRestockTime);
|
||||||
statement.setLong(6, nextRestockTime);
|
statement.setLong(6, nextRestockTime);
|
||||||
}
|
}
|
||||||
@@ -175,6 +172,7 @@ public class Product
|
|||||||
statement.setLong(4, 0);
|
statement.setLong(4, 0);
|
||||||
statement.setLong(6, 0);
|
statement.setLong(6, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
|
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.InventoryUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
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;
|
import org.l2jmobius.gameserver.util.GMAudit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -142,7 +144,6 @@ public class ItemInstance extends WorldObject
|
|||||||
/** Shadow item */
|
/** Shadow item */
|
||||||
private int _mana = -1;
|
private int _mana = -1;
|
||||||
private boolean _consumingMana = false;
|
private boolean _consumingMana = false;
|
||||||
private static final int MANA_CONSUMPTION_RATE = 60000;
|
|
||||||
|
|
||||||
/** Custom item types (used loto, race tickets) */
|
/** Custom item types (used loto, race tickets) */
|
||||||
private int _type1;
|
private int _type1;
|
||||||
@@ -172,8 +173,6 @@ public class ItemInstance extends WorldObject
|
|||||||
private Map<AttributeType, AttributeHolder> _elementals = null;
|
private Map<AttributeType, AttributeHolder> _elementals = null;
|
||||||
|
|
||||||
private ScheduledFuture<?> _itemLootShedule = null;
|
private ScheduledFuture<?> _itemLootShedule = null;
|
||||||
private ScheduledFuture<?> _lifeTimeTask;
|
|
||||||
private ScheduledFuture<?> _appearanceLifeTimeTask;
|
|
||||||
|
|
||||||
private final DropProtection _dropProtection = new DropProtection();
|
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
|
* Returns true if this item is a shadow item Shadow items have a limited life-time
|
||||||
* @return
|
* @return
|
||||||
@@ -1463,7 +1431,7 @@ public class ItemInstance extends WorldObject
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_consumingMana = true;
|
_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>
|
* <b><u>Example of use</u>:</b><br>
|
||||||
* <li>Drop item</li>
|
* <li>Drop item</li>
|
||||||
* <li>Call Pet</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;
|
int x = locX;
|
||||||
private int _y;
|
int y = locY;
|
||||||
private int _z;
|
int z = locZ;
|
||||||
private final Creature _dropper;
|
|
||||||
private final ItemInstance _itеm;
|
|
||||||
|
|
||||||
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
|
if (dropper != null)
|
||||||
{
|
{
|
||||||
_x = x;
|
final Instance instance = dropper.getInstanceWorld();
|
||||||
_y = y;
|
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
|
||||||
_z = z;
|
x = dropDest.getX();
|
||||||
_dropper = dropper;
|
y = dropDest.getY();
|
||||||
_itеm = item;
|
z = dropDest.getZ();
|
||||||
|
setInstance(instance); // Inherit instancezone when dropped in visible world
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setInstance(null); // No dropper? Make it a global item...
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Set the x,y,z position of the ItemInstance dropped and update its world region
|
||||||
public void run()
|
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)
|
ItemsOnGroundManager.getInstance().save(this);
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
|
||||||
|
|
||||||
public void dropMe(Creature dropper, int x, int y, int z)
|
|
||||||
{
|
|
||||||
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
|
|
||||||
if ((dropper != null) && dropper.isPlayer())
|
if ((dropper != null) && dropper.isPlayer())
|
||||||
{
|
{
|
||||||
_owner = null;
|
_owner = null;
|
||||||
@@ -1907,38 +1857,7 @@ public class ItemInstance extends WorldObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_lifeTimeTask != null)
|
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
|
||||||
{
|
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2485,16 +2404,8 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void stopAllTasks()
|
public void stopAllTasks()
|
||||||
{
|
{
|
||||||
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
|
ItemLifeTimeTaskManager.getInstance().remove(this);
|
||||||
{
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_lifeTimeTask.cancel(false);
|
|
||||||
_lifeTimeTask = null;
|
|
||||||
}
|
|
||||||
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
|
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemVariables getVariables()
|
public ItemVariables getVariables()
|
||||||
@@ -2537,10 +2448,9 @@ public class ItemInstance extends WorldObject
|
|||||||
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
||||||
|
|
||||||
// When removed, cancel existing lifetime task.
|
// When removed, cancel existing lifetime task.
|
||||||
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
|
if (visualId == 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask.cancel(true);
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
onVisualLifeTimeEnd();
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2552,25 +2462,22 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void scheduleVisualLifeTime()
|
public void scheduleVisualLifeTime()
|
||||||
{
|
{
|
||||||
if (_appearanceLifeTimeTask != null)
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
}
|
|
||||||
if (getVisualLifeTime() > 0)
|
if (getVisualLifeTime() > 0)
|
||||||
{
|
{
|
||||||
final long time = getVisualLifeTime() - System.currentTimeMillis();
|
final long endTime = getVisualLifeTime();
|
||||||
if (time > 0)
|
if ((endTime - System.currentTimeMillis()) > 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
|
ItemAppearanceTaskManager.getInstance().add(this, endTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadPool.execute(this::onVisualLifeTimeEnd);
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onVisualLifeTimeEnd()
|
public void onVisualLifeTimeEnd()
|
||||||
{
|
{
|
||||||
final ItemVariables vars = getVariables();
|
final ItemVariables vars = getVariables();
|
||||||
vars.remove(ItemVariables.VISUAL_ID);
|
vars.remove(ItemVariables.VISUAL_ID);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
|
|||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
||||||
|
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author NosBit
|
* @author NosBit
|
||||||
@@ -45,7 +43,6 @@ public class Product
|
|||||||
private final long _maxCount;
|
private final long _maxCount;
|
||||||
private final double _baseTax;
|
private final double _baseTax;
|
||||||
private AtomicLong _count = null;
|
private AtomicLong _count = null;
|
||||||
private ScheduledFuture<?> _restockTask = null;
|
|
||||||
|
|
||||||
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
||||||
{
|
{
|
||||||
@@ -122,10 +119,9 @@ public class Product
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((_restockTask == null) || _restockTask.isDone())
|
|
||||||
{
|
BuyListTaskManager.getInstance().add(this, _restockDelay);
|
||||||
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
|
|
||||||
}
|
|
||||||
final boolean result = _count.addAndGet(-value) >= 0;
|
final boolean result = _count.addAndGet(-value) >= 0;
|
||||||
save();
|
save();
|
||||||
return result;
|
return result;
|
||||||
@@ -141,7 +137,7 @@ public class Product
|
|||||||
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
||||||
if (remainTime > 0)
|
if (remainTime > 0)
|
||||||
{
|
{
|
||||||
_restockTask = ThreadPool.schedule(this::restock, remainTime);
|
BuyListTaskManager.getInstance().update(this, remainTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -164,9 +160,10 @@ public class Product
|
|||||||
statement.setInt(2, _item.getId());
|
statement.setInt(2, _item.getId());
|
||||||
statement.setLong(3, getCount());
|
statement.setLong(3, getCount());
|
||||||
statement.setLong(5, 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(4, nextRestockTime);
|
||||||
statement.setLong(6, nextRestockTime);
|
statement.setLong(6, nextRestockTime);
|
||||||
}
|
}
|
||||||
@@ -175,6 +172,7 @@ public class Product
|
|||||||
statement.setLong(4, 0);
|
statement.setLong(4, 0);
|
||||||
statement.setLong(6, 0);
|
statement.setLong(6, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
|
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.InventoryUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
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;
|
import org.l2jmobius.gameserver.util.GMAudit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -142,7 +144,6 @@ public class ItemInstance extends WorldObject
|
|||||||
/** Shadow item */
|
/** Shadow item */
|
||||||
private int _mana = -1;
|
private int _mana = -1;
|
||||||
private boolean _consumingMana = false;
|
private boolean _consumingMana = false;
|
||||||
private static final int MANA_CONSUMPTION_RATE = 60000;
|
|
||||||
|
|
||||||
/** Custom item types (used loto, race tickets) */
|
/** Custom item types (used loto, race tickets) */
|
||||||
private int _type1;
|
private int _type1;
|
||||||
@@ -172,8 +173,6 @@ public class ItemInstance extends WorldObject
|
|||||||
private Map<AttributeType, AttributeHolder> _elementals = null;
|
private Map<AttributeType, AttributeHolder> _elementals = null;
|
||||||
|
|
||||||
private ScheduledFuture<?> _itemLootShedule = null;
|
private ScheduledFuture<?> _itemLootShedule = null;
|
||||||
private ScheduledFuture<?> _lifeTimeTask;
|
|
||||||
private ScheduledFuture<?> _appearanceLifeTimeTask;
|
|
||||||
|
|
||||||
private final DropProtection _dropProtection = new DropProtection();
|
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
|
* Returns true if this item is a shadow item Shadow items have a limited life-time
|
||||||
* @return
|
* @return
|
||||||
@@ -1463,7 +1431,7 @@ public class ItemInstance extends WorldObject
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_consumingMana = true;
|
_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>
|
* <b><u>Example of use</u>:</b><br>
|
||||||
* <li>Drop item</li>
|
* <li>Drop item</li>
|
||||||
* <li>Call Pet</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;
|
int x = locX;
|
||||||
private int _y;
|
int y = locY;
|
||||||
private int _z;
|
int z = locZ;
|
||||||
private final Creature _dropper;
|
|
||||||
private final ItemInstance _itеm;
|
|
||||||
|
|
||||||
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
|
if (dropper != null)
|
||||||
{
|
{
|
||||||
_x = x;
|
final Instance instance = dropper.getInstanceWorld();
|
||||||
_y = y;
|
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
|
||||||
_z = z;
|
x = dropDest.getX();
|
||||||
_dropper = dropper;
|
y = dropDest.getY();
|
||||||
_itеm = item;
|
z = dropDest.getZ();
|
||||||
|
setInstance(instance); // Inherit instancezone when dropped in visible world
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setInstance(null); // No dropper? Make it a global item...
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Set the x,y,z position of the ItemInstance dropped and update its world region
|
||||||
public void run()
|
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)
|
ItemsOnGroundManager.getInstance().save(this);
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
|
||||||
|
|
||||||
public void dropMe(Creature dropper, int x, int y, int z)
|
|
||||||
{
|
|
||||||
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
|
|
||||||
if ((dropper != null) && dropper.isPlayer())
|
if ((dropper != null) && dropper.isPlayer())
|
||||||
{
|
{
|
||||||
_owner = null;
|
_owner = null;
|
||||||
@@ -1907,38 +1857,7 @@ public class ItemInstance extends WorldObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_lifeTimeTask != null)
|
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
|
||||||
{
|
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2485,16 +2404,8 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void stopAllTasks()
|
public void stopAllTasks()
|
||||||
{
|
{
|
||||||
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
|
ItemLifeTimeTaskManager.getInstance().remove(this);
|
||||||
{
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_lifeTimeTask.cancel(false);
|
|
||||||
_lifeTimeTask = null;
|
|
||||||
}
|
|
||||||
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
|
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemVariables getVariables()
|
public ItemVariables getVariables()
|
||||||
@@ -2537,10 +2448,9 @@ public class ItemInstance extends WorldObject
|
|||||||
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
||||||
|
|
||||||
// When removed, cancel existing lifetime task.
|
// When removed, cancel existing lifetime task.
|
||||||
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
|
if (visualId == 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask.cancel(true);
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
onVisualLifeTimeEnd();
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2552,25 +2462,22 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void scheduleVisualLifeTime()
|
public void scheduleVisualLifeTime()
|
||||||
{
|
{
|
||||||
if (_appearanceLifeTimeTask != null)
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
}
|
|
||||||
if (getVisualLifeTime() > 0)
|
if (getVisualLifeTime() > 0)
|
||||||
{
|
{
|
||||||
final long time = getVisualLifeTime() - System.currentTimeMillis();
|
final long endTime = getVisualLifeTime();
|
||||||
if (time > 0)
|
if ((endTime - System.currentTimeMillis()) > 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
|
ItemAppearanceTaskManager.getInstance().add(this, endTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadPool.execute(this::onVisualLifeTimeEnd);
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onVisualLifeTimeEnd()
|
public void onVisualLifeTimeEnd()
|
||||||
{
|
{
|
||||||
final ItemVariables vars = getVariables();
|
final ItemVariables vars = getVariables();
|
||||||
vars.remove(ItemVariables.VISUAL_ID);
|
vars.remove(ItemVariables.VISUAL_ID);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
|
|||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
||||||
|
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author NosBit
|
* @author NosBit
|
||||||
@@ -45,7 +43,6 @@ public class Product
|
|||||||
private final long _maxCount;
|
private final long _maxCount;
|
||||||
private final double _baseTax;
|
private final double _baseTax;
|
||||||
private AtomicLong _count = null;
|
private AtomicLong _count = null;
|
||||||
private ScheduledFuture<?> _restockTask = null;
|
|
||||||
|
|
||||||
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
||||||
{
|
{
|
||||||
@@ -122,10 +119,9 @@ public class Product
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((_restockTask == null) || _restockTask.isDone())
|
|
||||||
{
|
BuyListTaskManager.getInstance().add(this, _restockDelay);
|
||||||
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
|
|
||||||
}
|
|
||||||
final boolean result = _count.addAndGet(-value) >= 0;
|
final boolean result = _count.addAndGet(-value) >= 0;
|
||||||
save();
|
save();
|
||||||
return result;
|
return result;
|
||||||
@@ -141,7 +137,7 @@ public class Product
|
|||||||
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
||||||
if (remainTime > 0)
|
if (remainTime > 0)
|
||||||
{
|
{
|
||||||
_restockTask = ThreadPool.schedule(this::restock, remainTime);
|
BuyListTaskManager.getInstance().update(this, remainTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -164,9 +160,10 @@ public class Product
|
|||||||
statement.setInt(2, _item.getId());
|
statement.setInt(2, _item.getId());
|
||||||
statement.setLong(3, getCount());
|
statement.setLong(3, getCount());
|
||||||
statement.setLong(5, 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(4, nextRestockTime);
|
||||||
statement.setLong(6, nextRestockTime);
|
statement.setLong(6, nextRestockTime);
|
||||||
}
|
}
|
||||||
@@ -175,6 +172,7 @@ public class Product
|
|||||||
statement.setLong(4, 0);
|
statement.setLong(4, 0);
|
||||||
statement.setLong(6, 0);
|
statement.setLong(6, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
|
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.InventoryUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
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;
|
import org.l2jmobius.gameserver.util.GMAudit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -142,7 +144,6 @@ public class ItemInstance extends WorldObject
|
|||||||
/** Shadow item */
|
/** Shadow item */
|
||||||
private int _mana = -1;
|
private int _mana = -1;
|
||||||
private boolean _consumingMana = false;
|
private boolean _consumingMana = false;
|
||||||
private static final int MANA_CONSUMPTION_RATE = 60000;
|
|
||||||
|
|
||||||
/** Custom item types (used loto, race tickets) */
|
/** Custom item types (used loto, race tickets) */
|
||||||
private int _type1;
|
private int _type1;
|
||||||
@@ -172,8 +173,6 @@ public class ItemInstance extends WorldObject
|
|||||||
private Map<AttributeType, AttributeHolder> _elementals = null;
|
private Map<AttributeType, AttributeHolder> _elementals = null;
|
||||||
|
|
||||||
private ScheduledFuture<?> _itemLootShedule = null;
|
private ScheduledFuture<?> _itemLootShedule = null;
|
||||||
private ScheduledFuture<?> _lifeTimeTask;
|
|
||||||
private ScheduledFuture<?> _appearanceLifeTimeTask;
|
|
||||||
|
|
||||||
private final DropProtection _dropProtection = new DropProtection();
|
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
|
* Returns true if this item is a shadow item Shadow items have a limited life-time
|
||||||
* @return
|
* @return
|
||||||
@@ -1463,7 +1431,7 @@ public class ItemInstance extends WorldObject
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_consumingMana = true;
|
_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>
|
* <b><u>Example of use</u>:</b><br>
|
||||||
* <li>Drop item</li>
|
* <li>Drop item</li>
|
||||||
* <li>Call Pet</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;
|
int x = locX;
|
||||||
private int _y;
|
int y = locY;
|
||||||
private int _z;
|
int z = locZ;
|
||||||
private final Creature _dropper;
|
|
||||||
private final ItemInstance _itеm;
|
|
||||||
|
|
||||||
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
|
if (dropper != null)
|
||||||
{
|
{
|
||||||
_x = x;
|
final Instance instance = dropper.getInstanceWorld();
|
||||||
_y = y;
|
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
|
||||||
_z = z;
|
x = dropDest.getX();
|
||||||
_dropper = dropper;
|
y = dropDest.getY();
|
||||||
_itеm = item;
|
z = dropDest.getZ();
|
||||||
|
setInstance(instance); // Inherit instancezone when dropped in visible world
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setInstance(null); // No dropper? Make it a global item...
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Set the x,y,z position of the ItemInstance dropped and update its world region
|
||||||
public void run()
|
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)
|
ItemsOnGroundManager.getInstance().save(this);
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
|
||||||
|
|
||||||
public void dropMe(Creature dropper, int x, int y, int z)
|
|
||||||
{
|
|
||||||
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
|
|
||||||
if ((dropper != null) && dropper.isPlayer())
|
if ((dropper != null) && dropper.isPlayer())
|
||||||
{
|
{
|
||||||
_owner = null;
|
_owner = null;
|
||||||
@@ -1907,38 +1857,7 @@ public class ItemInstance extends WorldObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_lifeTimeTask != null)
|
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
|
||||||
{
|
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2485,16 +2404,8 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void stopAllTasks()
|
public void stopAllTasks()
|
||||||
{
|
{
|
||||||
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
|
ItemLifeTimeTaskManager.getInstance().remove(this);
|
||||||
{
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_lifeTimeTask.cancel(false);
|
|
||||||
_lifeTimeTask = null;
|
|
||||||
}
|
|
||||||
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
|
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemVariables getVariables()
|
public ItemVariables getVariables()
|
||||||
@@ -2537,10 +2448,9 @@ public class ItemInstance extends WorldObject
|
|||||||
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
||||||
|
|
||||||
// When removed, cancel existing lifetime task.
|
// When removed, cancel existing lifetime task.
|
||||||
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
|
if (visualId == 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask.cancel(true);
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
onVisualLifeTimeEnd();
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2552,25 +2462,22 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void scheduleVisualLifeTime()
|
public void scheduleVisualLifeTime()
|
||||||
{
|
{
|
||||||
if (_appearanceLifeTimeTask != null)
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
}
|
|
||||||
if (getVisualLifeTime() > 0)
|
if (getVisualLifeTime() > 0)
|
||||||
{
|
{
|
||||||
final long time = getVisualLifeTime() - System.currentTimeMillis();
|
final long endTime = getVisualLifeTime();
|
||||||
if (time > 0)
|
if ((endTime - System.currentTimeMillis()) > 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
|
ItemAppearanceTaskManager.getInstance().add(this, endTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadPool.execute(this::onVisualLifeTimeEnd);
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onVisualLifeTimeEnd()
|
public void onVisualLifeTimeEnd()
|
||||||
{
|
{
|
||||||
final ItemVariables vars = getVariables();
|
final ItemVariables vars = getVariables();
|
||||||
vars.remove(ItemVariables.VISUAL_ID);
|
vars.remove(ItemVariables.VISUAL_ID);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,7 +25,6 @@ import java.util.logging.LogRecord;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
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.InventoryUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
|
import org.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||||
|
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
|
||||||
import org.l2jmobius.gameserver.util.IllegalPlayerAction;
|
import org.l2jmobius.gameserver.util.IllegalPlayerAction;
|
||||||
import org.l2jmobius.gameserver.util.Util;
|
import org.l2jmobius.gameserver.util.Util;
|
||||||
|
|
||||||
@@ -92,7 +92,6 @@ public class ItemInstance extends WorldObject
|
|||||||
private boolean _wear;
|
private boolean _wear;
|
||||||
private int _mana = -1;
|
private int _mana = -1;
|
||||||
private boolean _consumingMana = false;
|
private boolean _consumingMana = false;
|
||||||
private static final int MANA_CONSUMPTION_RATE = 60000;
|
|
||||||
private int _type1;
|
private int _type1;
|
||||||
private int _type2;
|
private int _type2;
|
||||||
private long _dropTime;
|
private long _dropTime;
|
||||||
@@ -653,39 +652,6 @@ public class ItemInstance extends WorldObject
|
|||||||
return 0;
|
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.
|
* Returns true if this item is a shadow item Shadow items have a limited life-time.
|
||||||
* @return true, if is shadow item
|
* @return true, if is shadow item
|
||||||
@@ -834,7 +800,7 @@ public class ItemInstance extends WorldObject
|
|||||||
private void scheduleConsumeManaTask()
|
private void scheduleConsumeManaTask()
|
||||||
{
|
{
|
||||||
_consumingMana = true;
|
_consumingMana = true;
|
||||||
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
|
ItemManaTaskManager.getInstance().add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,7 +25,6 @@ import java.util.logging.LogRecord;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
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.InventoryUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
|
import org.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||||
|
import org.l2jmobius.gameserver.taskmanager.ItemManaTaskManager;
|
||||||
import org.l2jmobius.gameserver.util.IllegalPlayerAction;
|
import org.l2jmobius.gameserver.util.IllegalPlayerAction;
|
||||||
import org.l2jmobius.gameserver.util.Util;
|
import org.l2jmobius.gameserver.util.Util;
|
||||||
|
|
||||||
@@ -94,7 +94,6 @@ public class ItemInstance extends WorldObject
|
|||||||
private Augmentation _augmentation = null;
|
private Augmentation _augmentation = null;
|
||||||
private int _mana = -1;
|
private int _mana = -1;
|
||||||
private boolean _consumingMana = false;
|
private boolean _consumingMana = false;
|
||||||
private static final int MANA_CONSUMPTION_RATE = 60000;
|
|
||||||
private int _type1;
|
private int _type1;
|
||||||
private int _type2;
|
private int _type2;
|
||||||
private long _dropTime;
|
private long _dropTime;
|
||||||
@@ -702,39 +701,6 @@ public class ItemInstance extends WorldObject
|
|||||||
_augmentation = null;
|
_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.
|
* Returns true if this item is a shadow item Shadow items have a limited life-time.
|
||||||
* @return true, if is shadow item
|
* @return true, if is shadow item
|
||||||
@@ -883,7 +849,7 @@ public class ItemInstance extends WorldObject
|
|||||||
private void scheduleConsumeManaTask()
|
private void scheduleConsumeManaTask()
|
||||||
{
|
{
|
||||||
_consumingMana = true;
|
_consumingMana = true;
|
||||||
ThreadPool.schedule(new ScheduleConsumeManaTask(this), MANA_CONSUMPTION_RATE);
|
ItemManaTaskManager.getInstance().add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,15 +18,13 @@ package org.l2jmobius.gameserver.model.buylist;
|
|||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
|
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author NosBit
|
* @author NosBit
|
||||||
@@ -41,7 +39,6 @@ public class Product
|
|||||||
private final long _restockDelay;
|
private final long _restockDelay;
|
||||||
private final long _maxCount;
|
private final long _maxCount;
|
||||||
private AtomicLong _count = null;
|
private AtomicLong _count = null;
|
||||||
private ScheduledFuture<?> _restockTask = null;
|
|
||||||
|
|
||||||
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount)
|
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount)
|
||||||
{
|
{
|
||||||
@@ -111,10 +108,9 @@ public class Product
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((_restockTask == null) || _restockTask.isDone())
|
|
||||||
{
|
BuyListTaskManager.getInstance().add(this, _restockDelay);
|
||||||
_restockTask = ThreadPool.schedule(new RestockTask(), _restockDelay);
|
|
||||||
}
|
|
||||||
final boolean result = _count.addAndGet(-value) >= 0;
|
final boolean result = _count.addAndGet(-value) >= 0;
|
||||||
save();
|
save();
|
||||||
return result;
|
return result;
|
||||||
@@ -130,7 +126,7 @@ public class Product
|
|||||||
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
||||||
if (remainTime > 0)
|
if (remainTime > 0)
|
||||||
{
|
{
|
||||||
_restockTask = ThreadPool.schedule(new RestockTask(), remainTime);
|
BuyListTaskManager.getInstance().update(this, remainTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -144,36 +140,29 @@ public class Product
|
|||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final class RestockTask implements Runnable
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
restock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void save()
|
private void save()
|
||||||
{
|
{
|
||||||
try (Connection con = DatabaseFactory.getConnection();
|
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);
|
statement.setInt(1, _buyListId);
|
||||||
ps.setInt(2, _item.getId());
|
statement.setInt(2, _item.getId());
|
||||||
ps.setLong(3, getCount());
|
statement.setLong(3, getCount());
|
||||||
ps.setLong(5, 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);
|
||||||
ps.setLong(4, nextRestockTime);
|
statement.setLong(6, nextRestockTime);
|
||||||
ps.setLong(6, nextRestockTime);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ps.setLong(4, 0);
|
statement.setLong(4, 0);
|
||||||
ps.setLong(6, 0);
|
statement.setLong(6, 0);
|
||||||
}
|
}
|
||||||
ps.executeUpdate();
|
|
||||||
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.EnchantItemOptionsData;
|
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.SpawnItem;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
|
import org.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
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;
|
import org.l2jmobius.gameserver.util.GMAudit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -127,7 +128,6 @@ public class ItemInstance extends WorldObject
|
|||||||
/** Shadow item */
|
/** Shadow item */
|
||||||
private int _mana = -1;
|
private int _mana = -1;
|
||||||
private boolean _consumingMana = false;
|
private boolean _consumingMana = false;
|
||||||
private static final int MANA_CONSUMPTION_RATE = 60000;
|
|
||||||
|
|
||||||
/** Custom item types (used loto, race tickets) */
|
/** Custom item types (used loto, race tickets) */
|
||||||
private int _type1;
|
private int _type1;
|
||||||
@@ -157,7 +157,6 @@ public class ItemInstance extends WorldObject
|
|||||||
private Elementals[] _elementals = null;
|
private Elementals[] _elementals = null;
|
||||||
|
|
||||||
private ScheduledFuture<?> _itemLootShedule = null;
|
private ScheduledFuture<?> _itemLootShedule = null;
|
||||||
private ScheduledFuture<?> _lifeTimeTask;
|
|
||||||
|
|
||||||
private final DropProtection _dropProtection = new DropProtection();
|
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
|
* Returns true if this item is a shadow item Shadow items have a limited life-time
|
||||||
* @return
|
* @return
|
||||||
@@ -1393,7 +1361,7 @@ public class ItemInstance extends WorldObject
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_consumingMana = true;
|
_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>
|
* <b><u>Example of use</u>:</b><br>
|
||||||
* <li>Drop item</li>
|
* <li>Drop item</li>
|
||||||
* <li>Call Pet</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;
|
int x = locX;
|
||||||
private int _y;
|
int y = locY;
|
||||||
private int _z;
|
int z = locZ;
|
||||||
private final Creature _dropper;
|
|
||||||
private final ItemInstance _itm;
|
|
||||||
|
|
||||||
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
|
if (dropper != null)
|
||||||
{
|
{
|
||||||
_x = x;
|
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, dropper.getInstanceId());
|
||||||
_y = y;
|
x = dropDest.getX();
|
||||||
_z = z;
|
y = dropDest.getY();
|
||||||
_dropper = dropper;
|
z = dropDest.getZ();
|
||||||
_itm = item;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
if (dropper != null)
|
||||||
public void run()
|
|
||||||
{
|
{
|
||||||
if (_dropper != null)
|
setInstanceId(dropper.getInstanceId()); // Inherit instancezone when dropped in visible world
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
public void dropMe(Creature dropper, int x, int y, int z)
|
setInstanceId(0); // No dropper? Make it a global item...
|
||||||
{
|
}
|
||||||
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
|
|
||||||
|
// 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())
|
if ((dropper != null) && dropper.isPlayer())
|
||||||
{
|
{
|
||||||
|
_owner = null;
|
||||||
|
|
||||||
// Notify to scripts
|
// Notify to scripts
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerItemDrop(dropper.getActingPlayer(), this, new Location(x, y, z)), getItem());
|
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerItemDrop(dropper.getActingPlayer(), this, new Location(x, y, z)), getItem());
|
||||||
}
|
}
|
||||||
@@ -1870,38 +1822,7 @@ public class ItemInstance extends WorldObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_lifeTimeTask != null)
|
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
|
||||||
{
|
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2199,10 +2120,6 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void stopAllTasks()
|
public void stopAllTasks()
|
||||||
{
|
{
|
||||||
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
|
ItemLifeTimeTaskManager.getInstance().remove(this);
|
||||||
{
|
|
||||||
_lifeTimeTask.cancel(false);
|
|
||||||
_lifeTimeTask = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,15 +18,13 @@ package org.l2jmobius.gameserver.model.buylist;
|
|||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
|
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author NosBit
|
* @author NosBit
|
||||||
@@ -41,7 +39,6 @@ public class Product
|
|||||||
private final long _restockDelay;
|
private final long _restockDelay;
|
||||||
private final long _maxCount;
|
private final long _maxCount;
|
||||||
private AtomicLong _count = null;
|
private AtomicLong _count = null;
|
||||||
private ScheduledFuture<?> _restockTask = null;
|
|
||||||
|
|
||||||
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount)
|
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount)
|
||||||
{
|
{
|
||||||
@@ -111,10 +108,9 @@ public class Product
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((_restockTask == null) || _restockTask.isDone())
|
|
||||||
{
|
BuyListTaskManager.getInstance().add(this, _restockDelay);
|
||||||
_restockTask = ThreadPool.schedule(new RestockTask(), _restockDelay);
|
|
||||||
}
|
|
||||||
final boolean result = _count.addAndGet(-value) >= 0;
|
final boolean result = _count.addAndGet(-value) >= 0;
|
||||||
save();
|
save();
|
||||||
return result;
|
return result;
|
||||||
@@ -130,7 +126,7 @@ public class Product
|
|||||||
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
||||||
if (remainTime > 0)
|
if (remainTime > 0)
|
||||||
{
|
{
|
||||||
_restockTask = ThreadPool.schedule(new RestockTask(), remainTime);
|
BuyListTaskManager.getInstance().update(this, remainTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -144,36 +140,29 @@ public class Product
|
|||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final class RestockTask implements Runnable
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
restock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void save()
|
private void save()
|
||||||
{
|
{
|
||||||
try (Connection con = DatabaseFactory.getConnection();
|
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);
|
statement.setInt(1, _buyListId);
|
||||||
ps.setInt(2, _item.getId());
|
statement.setInt(2, _item.getId());
|
||||||
ps.setLong(3, getCount());
|
statement.setLong(3, getCount());
|
||||||
ps.setLong(5, 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);
|
||||||
ps.setLong(4, nextRestockTime);
|
statement.setLong(6, nextRestockTime);
|
||||||
ps.setLong(6, nextRestockTime);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ps.setLong(4, 0);
|
statement.setLong(4, 0);
|
||||||
ps.setLong(6, 0);
|
statement.setLong(6, 0);
|
||||||
}
|
}
|
||||||
ps.executeUpdate();
|
|
||||||
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.EnchantItemOptionsData;
|
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.SpawnItem;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
|
import org.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
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;
|
import org.l2jmobius.gameserver.util.GMAudit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -127,7 +128,6 @@ public class ItemInstance extends WorldObject
|
|||||||
/** Shadow item */
|
/** Shadow item */
|
||||||
private int _mana = -1;
|
private int _mana = -1;
|
||||||
private boolean _consumingMana = false;
|
private boolean _consumingMana = false;
|
||||||
private static final int MANA_CONSUMPTION_RATE = 60000;
|
|
||||||
|
|
||||||
/** Custom item types (used loto, race tickets) */
|
/** Custom item types (used loto, race tickets) */
|
||||||
private int _type1;
|
private int _type1;
|
||||||
@@ -157,7 +157,6 @@ public class ItemInstance extends WorldObject
|
|||||||
private Elementals[] _elementals = null;
|
private Elementals[] _elementals = null;
|
||||||
|
|
||||||
private ScheduledFuture<?> _itemLootShedule = null;
|
private ScheduledFuture<?> _itemLootShedule = null;
|
||||||
private ScheduledFuture<?> _lifeTimeTask;
|
|
||||||
|
|
||||||
private final DropProtection _dropProtection = new DropProtection();
|
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
|
* Returns true if this item is a shadow item Shadow items have a limited life-time
|
||||||
* @return
|
* @return
|
||||||
@@ -1393,7 +1361,7 @@ public class ItemInstance extends WorldObject
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_consumingMana = true;
|
_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>
|
* <b><u>Example of use</u>:</b><br>
|
||||||
* <li>Drop item</li>
|
* <li>Drop item</li>
|
||||||
* <li>Call Pet</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;
|
int x = locX;
|
||||||
private int _y;
|
int y = locY;
|
||||||
private int _z;
|
int z = locZ;
|
||||||
private final Creature _dropper;
|
|
||||||
private final ItemInstance _itm;
|
|
||||||
|
|
||||||
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
|
if (dropper != null)
|
||||||
{
|
{
|
||||||
_x = x;
|
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, dropper.getInstanceId());
|
||||||
_y = y;
|
x = dropDest.getX();
|
||||||
_z = z;
|
y = dropDest.getY();
|
||||||
_dropper = dropper;
|
z = dropDest.getZ();
|
||||||
_itm = item;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
if (dropper != null)
|
||||||
public void run()
|
|
||||||
{
|
{
|
||||||
if (_dropper != null)
|
setInstanceId(dropper.getInstanceId()); // Inherit instancezone when dropped in visible world
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
public void dropMe(Creature dropper, int x, int y, int z)
|
setInstanceId(0); // No dropper? Make it a global item...
|
||||||
{
|
}
|
||||||
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
|
|
||||||
|
// 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())
|
if ((dropper != null) && dropper.isPlayer())
|
||||||
{
|
{
|
||||||
|
_owner = null;
|
||||||
|
|
||||||
// Notify to scripts
|
// Notify to scripts
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerItemDrop(dropper.getActingPlayer(), this, new Location(x, y, z)), getItem());
|
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerItemDrop(dropper.getActingPlayer(), this, new Location(x, y, z)), getItem());
|
||||||
}
|
}
|
||||||
@@ -1870,38 +1822,7 @@ public class ItemInstance extends WorldObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_lifeTimeTask != null)
|
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
|
||||||
{
|
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2199,10 +2120,6 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void stopAllTasks()
|
public void stopAllTasks()
|
||||||
{
|
{
|
||||||
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
|
ItemLifeTimeTaskManager.getInstance().remove(this);
|
||||||
{
|
|
||||||
_lifeTimeTask.cancel(false);
|
|
||||||
_lifeTimeTask = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
|
|||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
||||||
|
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author NosBit
|
* @author NosBit
|
||||||
@@ -45,7 +43,6 @@ public class Product
|
|||||||
private final long _maxCount;
|
private final long _maxCount;
|
||||||
private final double _baseTax;
|
private final double _baseTax;
|
||||||
private AtomicLong _count = null;
|
private AtomicLong _count = null;
|
||||||
private ScheduledFuture<?> _restockTask = null;
|
|
||||||
|
|
||||||
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
||||||
{
|
{
|
||||||
@@ -122,10 +119,9 @@ public class Product
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((_restockTask == null) || _restockTask.isDone())
|
|
||||||
{
|
BuyListTaskManager.getInstance().add(this, _restockDelay);
|
||||||
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
|
|
||||||
}
|
|
||||||
final boolean result = _count.addAndGet(-value) >= 0;
|
final boolean result = _count.addAndGet(-value) >= 0;
|
||||||
save();
|
save();
|
||||||
return result;
|
return result;
|
||||||
@@ -141,7 +137,7 @@ public class Product
|
|||||||
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
||||||
if (remainTime > 0)
|
if (remainTime > 0)
|
||||||
{
|
{
|
||||||
_restockTask = ThreadPool.schedule(this::restock, remainTime);
|
BuyListTaskManager.getInstance().update(this, remainTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -164,9 +160,10 @@ public class Product
|
|||||||
statement.setInt(2, _item.getId());
|
statement.setInt(2, _item.getId());
|
||||||
statement.setLong(3, getCount());
|
statement.setLong(3, getCount());
|
||||||
statement.setLong(5, 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(4, nextRestockTime);
|
||||||
statement.setLong(6, nextRestockTime);
|
statement.setLong(6, nextRestockTime);
|
||||||
}
|
}
|
||||||
@@ -175,6 +172,7 @@ public class Product
|
|||||||
statement.setLong(4, 0);
|
statement.setLong(4, 0);
|
||||||
statement.setLong(6, 0);
|
statement.setLong(6, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
|
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.InventoryUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
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;
|
import org.l2jmobius.gameserver.util.GMAudit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -139,7 +141,6 @@ public class ItemInstance extends WorldObject
|
|||||||
/** Shadow item */
|
/** Shadow item */
|
||||||
private int _mana = -1;
|
private int _mana = -1;
|
||||||
private boolean _consumingMana = false;
|
private boolean _consumingMana = false;
|
||||||
private static final int MANA_CONSUMPTION_RATE = 60000;
|
|
||||||
|
|
||||||
/** Custom item types (used loto, race tickets) */
|
/** Custom item types (used loto, race tickets) */
|
||||||
private int _type1;
|
private int _type1;
|
||||||
@@ -169,8 +170,6 @@ public class ItemInstance extends WorldObject
|
|||||||
private Map<AttributeType, AttributeHolder> _elementals = null;
|
private Map<AttributeType, AttributeHolder> _elementals = null;
|
||||||
|
|
||||||
private ScheduledFuture<?> _itemLootShedule = null;
|
private ScheduledFuture<?> _itemLootShedule = null;
|
||||||
private ScheduledFuture<?> _lifeTimeTask;
|
|
||||||
private ScheduledFuture<?> _appearanceLifeTimeTask;
|
|
||||||
|
|
||||||
private final DropProtection _dropProtection = new DropProtection();
|
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
|
* Returns true if this item is a shadow item Shadow items have a limited life-time
|
||||||
* @return
|
* @return
|
||||||
@@ -1455,7 +1423,7 @@ public class ItemInstance extends WorldObject
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_consumingMana = true;
|
_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>
|
* <b><u>Example of use</u>:</b><br>
|
||||||
* <li>Drop item</li>
|
* <li>Drop item</li>
|
||||||
* <li>Call Pet</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;
|
int x = locX;
|
||||||
private final Creature _dropper;
|
int y = locY;
|
||||||
private final ItemInstance _itеm;
|
int z = locZ;
|
||||||
|
|
||||||
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
|
if (dropper != null)
|
||||||
{
|
{
|
||||||
_x = x;
|
final Instance instance = dropper.getInstanceWorld();
|
||||||
_y = y;
|
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
|
||||||
_z = z;
|
x = dropDest.getX();
|
||||||
_dropper = dropper;
|
y = dropDest.getY();
|
||||||
_itеm = item;
|
z = dropDest.getZ();
|
||||||
|
setInstance(instance); // Inherit instancezone when dropped in visible world
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setInstance(null); // No dropper? Make it a global item...
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Set the x,y,z position of the ItemInstance dropped and update its world region
|
||||||
public void run()
|
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)
|
ItemsOnGroundManager.getInstance().save(this);
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
|
||||||
|
|
||||||
public void dropMe(Creature dropper, int x, int y, int z)
|
|
||||||
{
|
|
||||||
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
|
|
||||||
if ((dropper != null) && dropper.isPlayer())
|
if ((dropper != null) && dropper.isPlayer())
|
||||||
{
|
{
|
||||||
_owner = null;
|
_owner = null;
|
||||||
@@ -1897,38 +1849,7 @@ public class ItemInstance extends WorldObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_lifeTimeTask != null)
|
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
|
||||||
{
|
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2472,16 +2393,8 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void stopAllTasks()
|
public void stopAllTasks()
|
||||||
{
|
{
|
||||||
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
|
ItemLifeTimeTaskManager.getInstance().remove(this);
|
||||||
{
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_lifeTimeTask.cancel(false);
|
|
||||||
_lifeTimeTask = null;
|
|
||||||
}
|
|
||||||
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
|
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemVariables getVariables()
|
public ItemVariables getVariables()
|
||||||
@@ -2524,10 +2437,9 @@ public class ItemInstance extends WorldObject
|
|||||||
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
||||||
|
|
||||||
// When removed, cancel existing lifetime task.
|
// When removed, cancel existing lifetime task.
|
||||||
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
|
if (visualId == 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask.cancel(true);
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
onVisualLifeTimeEnd();
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2539,25 +2451,22 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void scheduleVisualLifeTime()
|
public void scheduleVisualLifeTime()
|
||||||
{
|
{
|
||||||
if (_appearanceLifeTimeTask != null)
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
}
|
|
||||||
if (getVisualLifeTime() > 0)
|
if (getVisualLifeTime() > 0)
|
||||||
{
|
{
|
||||||
final long time = getVisualLifeTime() - System.currentTimeMillis();
|
final long endTime = getVisualLifeTime();
|
||||||
if (time > 0)
|
if ((endTime - System.currentTimeMillis()) > 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
|
ItemAppearanceTaskManager.getInstance().add(this, endTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadPool.execute(this::onVisualLifeTimeEnd);
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onVisualLifeTimeEnd()
|
public void onVisualLifeTimeEnd()
|
||||||
{
|
{
|
||||||
final ItemVariables vars = getVariables();
|
final ItemVariables vars = getVariables();
|
||||||
vars.remove(ItemVariables.VISUAL_ID);
|
vars.remove(ItemVariables.VISUAL_ID);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
|
|||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
||||||
|
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author NosBit
|
* @author NosBit
|
||||||
@@ -45,7 +43,6 @@ public class Product
|
|||||||
private final long _maxCount;
|
private final long _maxCount;
|
||||||
private final double _baseTax;
|
private final double _baseTax;
|
||||||
private AtomicLong _count = null;
|
private AtomicLong _count = null;
|
||||||
private ScheduledFuture<?> _restockTask = null;
|
|
||||||
|
|
||||||
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
||||||
{
|
{
|
||||||
@@ -122,10 +119,9 @@ public class Product
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((_restockTask == null) || _restockTask.isDone())
|
|
||||||
{
|
BuyListTaskManager.getInstance().add(this, _restockDelay);
|
||||||
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
|
|
||||||
}
|
|
||||||
final boolean result = _count.addAndGet(-value) >= 0;
|
final boolean result = _count.addAndGet(-value) >= 0;
|
||||||
save();
|
save();
|
||||||
return result;
|
return result;
|
||||||
@@ -141,7 +137,7 @@ public class Product
|
|||||||
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
||||||
if (remainTime > 0)
|
if (remainTime > 0)
|
||||||
{
|
{
|
||||||
_restockTask = ThreadPool.schedule(this::restock, remainTime);
|
BuyListTaskManager.getInstance().update(this, remainTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -164,9 +160,10 @@ public class Product
|
|||||||
statement.setInt(2, _item.getId());
|
statement.setInt(2, _item.getId());
|
||||||
statement.setLong(3, getCount());
|
statement.setLong(3, getCount());
|
||||||
statement.setLong(5, 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(4, nextRestockTime);
|
||||||
statement.setLong(6, nextRestockTime);
|
statement.setLong(6, nextRestockTime);
|
||||||
}
|
}
|
||||||
@@ -175,6 +172,7 @@ public class Product
|
|||||||
statement.setLong(4, 0);
|
statement.setLong(4, 0);
|
||||||
statement.setLong(6, 0);
|
statement.setLong(6, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
|
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.InventoryUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
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;
|
import org.l2jmobius.gameserver.util.GMAudit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -139,7 +141,6 @@ public class ItemInstance extends WorldObject
|
|||||||
/** Shadow item */
|
/** Shadow item */
|
||||||
private int _mana = -1;
|
private int _mana = -1;
|
||||||
private boolean _consumingMana = false;
|
private boolean _consumingMana = false;
|
||||||
private static final int MANA_CONSUMPTION_RATE = 60000;
|
|
||||||
|
|
||||||
/** Custom item types (used loto, race tickets) */
|
/** Custom item types (used loto, race tickets) */
|
||||||
private int _type1;
|
private int _type1;
|
||||||
@@ -169,8 +170,6 @@ public class ItemInstance extends WorldObject
|
|||||||
private Map<AttributeType, AttributeHolder> _elementals = null;
|
private Map<AttributeType, AttributeHolder> _elementals = null;
|
||||||
|
|
||||||
private ScheduledFuture<?> _itemLootShedule = null;
|
private ScheduledFuture<?> _itemLootShedule = null;
|
||||||
private ScheduledFuture<?> _lifeTimeTask;
|
|
||||||
private ScheduledFuture<?> _appearanceLifeTimeTask;
|
|
||||||
|
|
||||||
private final DropProtection _dropProtection = new DropProtection();
|
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
|
* Returns true if this item is a shadow item Shadow items have a limited life-time
|
||||||
* @return
|
* @return
|
||||||
@@ -1455,7 +1423,7 @@ public class ItemInstance extends WorldObject
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_consumingMana = true;
|
_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>
|
* <b><u>Example of use</u>:</b><br>
|
||||||
* <li>Drop item</li>
|
* <li>Drop item</li>
|
||||||
* <li>Call Pet</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;
|
int x = locX;
|
||||||
private final Creature _dropper;
|
int y = locY;
|
||||||
private final ItemInstance _itеm;
|
int z = locZ;
|
||||||
|
|
||||||
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
|
if (dropper != null)
|
||||||
{
|
{
|
||||||
_x = x;
|
final Instance instance = dropper.getInstanceWorld();
|
||||||
_y = y;
|
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
|
||||||
_z = z;
|
x = dropDest.getX();
|
||||||
_dropper = dropper;
|
y = dropDest.getY();
|
||||||
_itеm = item;
|
z = dropDest.getZ();
|
||||||
|
setInstance(instance); // Inherit instancezone when dropped in visible world
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setInstance(null); // No dropper? Make it a global item...
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Set the x,y,z position of the ItemInstance dropped and update its world region
|
||||||
public void run()
|
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)
|
ItemsOnGroundManager.getInstance().save(this);
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
|
||||||
|
|
||||||
public void dropMe(Creature dropper, int x, int y, int z)
|
|
||||||
{
|
|
||||||
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
|
|
||||||
if ((dropper != null) && dropper.isPlayer())
|
if ((dropper != null) && dropper.isPlayer())
|
||||||
{
|
{
|
||||||
_owner = null;
|
_owner = null;
|
||||||
@@ -1897,38 +1849,7 @@ public class ItemInstance extends WorldObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_lifeTimeTask != null)
|
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
|
||||||
{
|
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2472,16 +2393,8 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void stopAllTasks()
|
public void stopAllTasks()
|
||||||
{
|
{
|
||||||
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
|
ItemLifeTimeTaskManager.getInstance().remove(this);
|
||||||
{
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_lifeTimeTask.cancel(false);
|
|
||||||
_lifeTimeTask = null;
|
|
||||||
}
|
|
||||||
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
|
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemVariables getVariables()
|
public ItemVariables getVariables()
|
||||||
@@ -2524,10 +2437,9 @@ public class ItemInstance extends WorldObject
|
|||||||
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
||||||
|
|
||||||
// When removed, cancel existing lifetime task.
|
// When removed, cancel existing lifetime task.
|
||||||
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
|
if (visualId == 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask.cancel(true);
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
onVisualLifeTimeEnd();
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2539,25 +2451,22 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void scheduleVisualLifeTime()
|
public void scheduleVisualLifeTime()
|
||||||
{
|
{
|
||||||
if (_appearanceLifeTimeTask != null)
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
}
|
|
||||||
if (getVisualLifeTime() > 0)
|
if (getVisualLifeTime() > 0)
|
||||||
{
|
{
|
||||||
final long time = getVisualLifeTime() - System.currentTimeMillis();
|
final long endTime = getVisualLifeTime();
|
||||||
if (time > 0)
|
if ((endTime - System.currentTimeMillis()) > 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
|
ItemAppearanceTaskManager.getInstance().add(this, endTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadPool.execute(this::onVisualLifeTimeEnd);
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onVisualLifeTimeEnd()
|
public void onVisualLifeTimeEnd()
|
||||||
{
|
{
|
||||||
final ItemVariables vars = getVariables();
|
final ItemVariables vars = getVariables();
|
||||||
vars.remove(ItemVariables.VISUAL_ID);
|
vars.remove(ItemVariables.VISUAL_ID);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
|
|||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
||||||
|
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author NosBit
|
* @author NosBit
|
||||||
@@ -45,7 +43,6 @@ public class Product
|
|||||||
private final long _maxCount;
|
private final long _maxCount;
|
||||||
private final double _baseTax;
|
private final double _baseTax;
|
||||||
private AtomicLong _count = null;
|
private AtomicLong _count = null;
|
||||||
private ScheduledFuture<?> _restockTask = null;
|
|
||||||
|
|
||||||
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
||||||
{
|
{
|
||||||
@@ -122,10 +119,9 @@ public class Product
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((_restockTask == null) || _restockTask.isDone())
|
|
||||||
{
|
BuyListTaskManager.getInstance().add(this, _restockDelay);
|
||||||
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
|
|
||||||
}
|
|
||||||
final boolean result = _count.addAndGet(-value) >= 0;
|
final boolean result = _count.addAndGet(-value) >= 0;
|
||||||
save();
|
save();
|
||||||
return result;
|
return result;
|
||||||
@@ -141,7 +137,7 @@ public class Product
|
|||||||
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
||||||
if (remainTime > 0)
|
if (remainTime > 0)
|
||||||
{
|
{
|
||||||
_restockTask = ThreadPool.schedule(this::restock, remainTime);
|
BuyListTaskManager.getInstance().update(this, remainTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -164,9 +160,10 @@ public class Product
|
|||||||
statement.setInt(2, _item.getId());
|
statement.setInt(2, _item.getId());
|
||||||
statement.setLong(3, getCount());
|
statement.setLong(3, getCount());
|
||||||
statement.setLong(5, 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(4, nextRestockTime);
|
||||||
statement.setLong(6, nextRestockTime);
|
statement.setLong(6, nextRestockTime);
|
||||||
}
|
}
|
||||||
@@ -175,6 +172,7 @@ public class Product
|
|||||||
statement.setLong(4, 0);
|
statement.setLong(4, 0);
|
||||||
statement.setLong(6, 0);
|
statement.setLong(6, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
|
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.InventoryUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
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;
|
import org.l2jmobius.gameserver.util.GMAudit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -139,7 +141,6 @@ public class ItemInstance extends WorldObject
|
|||||||
/** Shadow item */
|
/** Shadow item */
|
||||||
private int _mana = -1;
|
private int _mana = -1;
|
||||||
private boolean _consumingMana = false;
|
private boolean _consumingMana = false;
|
||||||
private static final int MANA_CONSUMPTION_RATE = 60000;
|
|
||||||
|
|
||||||
/** Custom item types (used loto, race tickets) */
|
/** Custom item types (used loto, race tickets) */
|
||||||
private int _type1;
|
private int _type1;
|
||||||
@@ -169,8 +170,6 @@ public class ItemInstance extends WorldObject
|
|||||||
private Map<AttributeType, AttributeHolder> _elementals = null;
|
private Map<AttributeType, AttributeHolder> _elementals = null;
|
||||||
|
|
||||||
private ScheduledFuture<?> _itemLootShedule = null;
|
private ScheduledFuture<?> _itemLootShedule = null;
|
||||||
private ScheduledFuture<?> _lifeTimeTask;
|
|
||||||
private ScheduledFuture<?> _appearanceLifeTimeTask;
|
|
||||||
|
|
||||||
private final DropProtection _dropProtection = new DropProtection();
|
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
|
* Returns true if this item is a shadow item Shadow items have a limited life-time
|
||||||
* @return
|
* @return
|
||||||
@@ -1455,7 +1423,7 @@ public class ItemInstance extends WorldObject
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_consumingMana = true;
|
_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>
|
* <b><u>Example of use</u>:</b><br>
|
||||||
* <li>Drop item</li>
|
* <li>Drop item</li>
|
||||||
* <li>Call Pet</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;
|
int x = locX;
|
||||||
private final Creature _dropper;
|
int y = locY;
|
||||||
private final ItemInstance _itеm;
|
int z = locZ;
|
||||||
|
|
||||||
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
|
if (dropper != null)
|
||||||
{
|
{
|
||||||
_x = x;
|
final Instance instance = dropper.getInstanceWorld();
|
||||||
_y = y;
|
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
|
||||||
_z = z;
|
x = dropDest.getX();
|
||||||
_dropper = dropper;
|
y = dropDest.getY();
|
||||||
_itеm = item;
|
z = dropDest.getZ();
|
||||||
|
setInstance(instance); // Inherit instancezone when dropped in visible world
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setInstance(null); // No dropper? Make it a global item...
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Set the x,y,z position of the ItemInstance dropped and update its world region
|
||||||
public void run()
|
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)
|
ItemsOnGroundManager.getInstance().save(this);
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
|
||||||
|
|
||||||
public void dropMe(Creature dropper, int x, int y, int z)
|
|
||||||
{
|
|
||||||
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
|
|
||||||
if ((dropper != null) && dropper.isPlayer())
|
if ((dropper != null) && dropper.isPlayer())
|
||||||
{
|
{
|
||||||
_owner = null;
|
_owner = null;
|
||||||
@@ -1897,38 +1849,7 @@ public class ItemInstance extends WorldObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_lifeTimeTask != null)
|
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
|
||||||
{
|
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2472,16 +2393,8 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void stopAllTasks()
|
public void stopAllTasks()
|
||||||
{
|
{
|
||||||
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
|
ItemLifeTimeTaskManager.getInstance().remove(this);
|
||||||
{
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_lifeTimeTask.cancel(false);
|
|
||||||
_lifeTimeTask = null;
|
|
||||||
}
|
|
||||||
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
|
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemVariables getVariables()
|
public ItemVariables getVariables()
|
||||||
@@ -2524,10 +2437,9 @@ public class ItemInstance extends WorldObject
|
|||||||
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
||||||
|
|
||||||
// When removed, cancel existing lifetime task.
|
// When removed, cancel existing lifetime task.
|
||||||
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
|
if (visualId == 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask.cancel(true);
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
onVisualLifeTimeEnd();
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2539,25 +2451,22 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void scheduleVisualLifeTime()
|
public void scheduleVisualLifeTime()
|
||||||
{
|
{
|
||||||
if (_appearanceLifeTimeTask != null)
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
}
|
|
||||||
if (getVisualLifeTime() > 0)
|
if (getVisualLifeTime() > 0)
|
||||||
{
|
{
|
||||||
final long time = getVisualLifeTime() - System.currentTimeMillis();
|
final long endTime = getVisualLifeTime();
|
||||||
if (time > 0)
|
if ((endTime - System.currentTimeMillis()) > 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
|
ItemAppearanceTaskManager.getInstance().add(this, endTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadPool.execute(this::onVisualLifeTimeEnd);
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onVisualLifeTimeEnd()
|
public void onVisualLifeTimeEnd()
|
||||||
{
|
{
|
||||||
final ItemVariables vars = getVariables();
|
final ItemVariables vars = getVariables();
|
||||||
vars.remove(ItemVariables.VISUAL_ID);
|
vars.remove(ItemVariables.VISUAL_ID);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
|
|||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
||||||
|
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author NosBit
|
* @author NosBit
|
||||||
@@ -45,7 +43,6 @@ public class Product
|
|||||||
private final long _maxCount;
|
private final long _maxCount;
|
||||||
private final double _baseTax;
|
private final double _baseTax;
|
||||||
private AtomicLong _count = null;
|
private AtomicLong _count = null;
|
||||||
private ScheduledFuture<?> _restockTask = null;
|
|
||||||
|
|
||||||
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
||||||
{
|
{
|
||||||
@@ -122,10 +119,9 @@ public class Product
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((_restockTask == null) || _restockTask.isDone())
|
|
||||||
{
|
BuyListTaskManager.getInstance().add(this, _restockDelay);
|
||||||
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
|
|
||||||
}
|
|
||||||
final boolean result = _count.addAndGet(-value) >= 0;
|
final boolean result = _count.addAndGet(-value) >= 0;
|
||||||
save();
|
save();
|
||||||
return result;
|
return result;
|
||||||
@@ -141,7 +137,7 @@ public class Product
|
|||||||
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
||||||
if (remainTime > 0)
|
if (remainTime > 0)
|
||||||
{
|
{
|
||||||
_restockTask = ThreadPool.schedule(this::restock, remainTime);
|
BuyListTaskManager.getInstance().update(this, remainTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -164,9 +160,10 @@ public class Product
|
|||||||
statement.setInt(2, _item.getId());
|
statement.setInt(2, _item.getId());
|
||||||
statement.setLong(3, getCount());
|
statement.setLong(3, getCount());
|
||||||
statement.setLong(5, 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(4, nextRestockTime);
|
||||||
statement.setLong(6, nextRestockTime);
|
statement.setLong(6, nextRestockTime);
|
||||||
}
|
}
|
||||||
@@ -175,6 +172,7 @@ public class Product
|
|||||||
statement.setLong(4, 0);
|
statement.setLong(4, 0);
|
||||||
statement.setLong(6, 0);
|
statement.setLong(6, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
|
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.InventoryUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
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;
|
import org.l2jmobius.gameserver.util.GMAudit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -139,7 +141,6 @@ public class ItemInstance extends WorldObject
|
|||||||
/** Shadow item */
|
/** Shadow item */
|
||||||
private int _mana = -1;
|
private int _mana = -1;
|
||||||
private boolean _consumingMana = false;
|
private boolean _consumingMana = false;
|
||||||
private static final int MANA_CONSUMPTION_RATE = 60000;
|
|
||||||
|
|
||||||
/** Custom item types (used loto, race tickets) */
|
/** Custom item types (used loto, race tickets) */
|
||||||
private int _type1;
|
private int _type1;
|
||||||
@@ -169,8 +170,6 @@ public class ItemInstance extends WorldObject
|
|||||||
private Map<AttributeType, AttributeHolder> _elementals = null;
|
private Map<AttributeType, AttributeHolder> _elementals = null;
|
||||||
|
|
||||||
private ScheduledFuture<?> _itemLootShedule = null;
|
private ScheduledFuture<?> _itemLootShedule = null;
|
||||||
private ScheduledFuture<?> _lifeTimeTask;
|
|
||||||
private ScheduledFuture<?> _appearanceLifeTimeTask;
|
|
||||||
|
|
||||||
private final DropProtection _dropProtection = new DropProtection();
|
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
|
* Returns true if this item is a shadow item Shadow items have a limited life-time
|
||||||
* @return
|
* @return
|
||||||
@@ -1455,7 +1423,7 @@ public class ItemInstance extends WorldObject
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_consumingMana = true;
|
_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>
|
* <b><u>Example of use</u>:</b><br>
|
||||||
* <li>Drop item</li>
|
* <li>Drop item</li>
|
||||||
* <li>Call Pet</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;
|
int x = locX;
|
||||||
private final Creature _dropper;
|
int y = locY;
|
||||||
private final ItemInstance _itеm;
|
int z = locZ;
|
||||||
|
|
||||||
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
|
if (dropper != null)
|
||||||
{
|
{
|
||||||
_x = x;
|
final Instance instance = dropper.getInstanceWorld();
|
||||||
_y = y;
|
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
|
||||||
_z = z;
|
x = dropDest.getX();
|
||||||
_dropper = dropper;
|
y = dropDest.getY();
|
||||||
_itеm = item;
|
z = dropDest.getZ();
|
||||||
|
setInstance(instance); // Inherit instancezone when dropped in visible world
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setInstance(null); // No dropper? Make it a global item...
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Set the x,y,z position of the ItemInstance dropped and update its world region
|
||||||
public void run()
|
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)
|
ItemsOnGroundManager.getInstance().save(this);
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
|
||||||
|
|
||||||
public void dropMe(Creature dropper, int x, int y, int z)
|
|
||||||
{
|
|
||||||
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
|
|
||||||
if ((dropper != null) && dropper.isPlayer())
|
if ((dropper != null) && dropper.isPlayer())
|
||||||
{
|
{
|
||||||
_owner = null;
|
_owner = null;
|
||||||
@@ -1897,38 +1849,7 @@ public class ItemInstance extends WorldObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_lifeTimeTask != null)
|
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
|
||||||
{
|
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2472,16 +2393,8 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void stopAllTasks()
|
public void stopAllTasks()
|
||||||
{
|
{
|
||||||
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
|
ItemLifeTimeTaskManager.getInstance().remove(this);
|
||||||
{
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_lifeTimeTask.cancel(false);
|
|
||||||
_lifeTimeTask = null;
|
|
||||||
}
|
|
||||||
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
|
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemVariables getVariables()
|
public ItemVariables getVariables()
|
||||||
@@ -2524,10 +2437,9 @@ public class ItemInstance extends WorldObject
|
|||||||
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
||||||
|
|
||||||
// When removed, cancel existing lifetime task.
|
// When removed, cancel existing lifetime task.
|
||||||
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
|
if (visualId == 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask.cancel(true);
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
onVisualLifeTimeEnd();
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2539,25 +2451,22 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void scheduleVisualLifeTime()
|
public void scheduleVisualLifeTime()
|
||||||
{
|
{
|
||||||
if (_appearanceLifeTimeTask != null)
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
}
|
|
||||||
if (getVisualLifeTime() > 0)
|
if (getVisualLifeTime() > 0)
|
||||||
{
|
{
|
||||||
final long time = getVisualLifeTime() - System.currentTimeMillis();
|
final long endTime = getVisualLifeTime();
|
||||||
if (time > 0)
|
if ((endTime - System.currentTimeMillis()) > 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
|
ItemAppearanceTaskManager.getInstance().add(this, endTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadPool.execute(this::onVisualLifeTimeEnd);
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onVisualLifeTimeEnd()
|
public void onVisualLifeTimeEnd()
|
||||||
{
|
{
|
||||||
final ItemVariables vars = getVariables();
|
final ItemVariables vars = getVariables();
|
||||||
vars.remove(ItemVariables.VISUAL_ID);
|
vars.remove(ItemVariables.VISUAL_ID);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
|
|||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
||||||
|
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author NosBit
|
* @author NosBit
|
||||||
@@ -45,7 +43,6 @@ public class Product
|
|||||||
private final long _maxCount;
|
private final long _maxCount;
|
||||||
private final double _baseTax;
|
private final double _baseTax;
|
||||||
private AtomicLong _count = null;
|
private AtomicLong _count = null;
|
||||||
private ScheduledFuture<?> _restockTask = null;
|
|
||||||
|
|
||||||
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
||||||
{
|
{
|
||||||
@@ -122,10 +119,9 @@ public class Product
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((_restockTask == null) || _restockTask.isDone())
|
|
||||||
{
|
BuyListTaskManager.getInstance().add(this, _restockDelay);
|
||||||
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
|
|
||||||
}
|
|
||||||
final boolean result = _count.addAndGet(-value) >= 0;
|
final boolean result = _count.addAndGet(-value) >= 0;
|
||||||
save();
|
save();
|
||||||
return result;
|
return result;
|
||||||
@@ -141,7 +137,7 @@ public class Product
|
|||||||
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
||||||
if (remainTime > 0)
|
if (remainTime > 0)
|
||||||
{
|
{
|
||||||
_restockTask = ThreadPool.schedule(this::restock, remainTime);
|
BuyListTaskManager.getInstance().update(this, remainTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -164,9 +160,10 @@ public class Product
|
|||||||
statement.setInt(2, _item.getId());
|
statement.setInt(2, _item.getId());
|
||||||
statement.setLong(3, getCount());
|
statement.setLong(3, getCount());
|
||||||
statement.setLong(5, 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(4, nextRestockTime);
|
||||||
statement.setLong(6, nextRestockTime);
|
statement.setLong(6, nextRestockTime);
|
||||||
}
|
}
|
||||||
@@ -175,6 +172,7 @@ public class Product
|
|||||||
statement.setLong(4, 0);
|
statement.setLong(4, 0);
|
||||||
statement.setLong(6, 0);
|
statement.setLong(6, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
|
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.InventoryUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
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;
|
import org.l2jmobius.gameserver.util.GMAudit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -139,7 +141,6 @@ public class ItemInstance extends WorldObject
|
|||||||
/** Shadow item */
|
/** Shadow item */
|
||||||
private int _mana = -1;
|
private int _mana = -1;
|
||||||
private boolean _consumingMana = false;
|
private boolean _consumingMana = false;
|
||||||
private static final int MANA_CONSUMPTION_RATE = 60000;
|
|
||||||
|
|
||||||
/** Custom item types (used loto, race tickets) */
|
/** Custom item types (used loto, race tickets) */
|
||||||
private int _type1;
|
private int _type1;
|
||||||
@@ -169,8 +170,6 @@ public class ItemInstance extends WorldObject
|
|||||||
private Map<AttributeType, AttributeHolder> _elementals = null;
|
private Map<AttributeType, AttributeHolder> _elementals = null;
|
||||||
|
|
||||||
private ScheduledFuture<?> _itemLootShedule = null;
|
private ScheduledFuture<?> _itemLootShedule = null;
|
||||||
private ScheduledFuture<?> _lifeTimeTask;
|
|
||||||
private ScheduledFuture<?> _appearanceLifeTimeTask;
|
|
||||||
|
|
||||||
private final DropProtection _dropProtection = new DropProtection();
|
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
|
* Returns true if this item is a shadow item Shadow items have a limited life-time
|
||||||
* @return
|
* @return
|
||||||
@@ -1455,7 +1423,7 @@ public class ItemInstance extends WorldObject
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_consumingMana = true;
|
_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>
|
* <b><u>Example of use</u>:</b><br>
|
||||||
* <li>Drop item</li>
|
* <li>Drop item</li>
|
||||||
* <li>Call Pet</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;
|
int x = locX;
|
||||||
private final Creature _dropper;
|
int y = locY;
|
||||||
private final ItemInstance _itеm;
|
int z = locZ;
|
||||||
|
|
||||||
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
|
if (dropper != null)
|
||||||
{
|
{
|
||||||
_x = x;
|
final Instance instance = dropper.getInstanceWorld();
|
||||||
_y = y;
|
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
|
||||||
_z = z;
|
x = dropDest.getX();
|
||||||
_dropper = dropper;
|
y = dropDest.getY();
|
||||||
_itеm = item;
|
z = dropDest.getZ();
|
||||||
|
setInstance(instance); // Inherit instancezone when dropped in visible world
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setInstance(null); // No dropper? Make it a global item...
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Set the x,y,z position of the ItemInstance dropped and update its world region
|
||||||
public void run()
|
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)
|
ItemsOnGroundManager.getInstance().save(this);
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
|
||||||
|
|
||||||
public void dropMe(Creature dropper, int x, int y, int z)
|
|
||||||
{
|
|
||||||
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
|
|
||||||
if ((dropper != null) && dropper.isPlayer())
|
if ((dropper != null) && dropper.isPlayer())
|
||||||
{
|
{
|
||||||
_owner = null;
|
_owner = null;
|
||||||
@@ -1897,38 +1849,7 @@ public class ItemInstance extends WorldObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_lifeTimeTask != null)
|
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
|
||||||
{
|
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2472,16 +2393,8 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void stopAllTasks()
|
public void stopAllTasks()
|
||||||
{
|
{
|
||||||
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
|
ItemLifeTimeTaskManager.getInstance().remove(this);
|
||||||
{
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_lifeTimeTask.cancel(false);
|
|
||||||
_lifeTimeTask = null;
|
|
||||||
}
|
|
||||||
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
|
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemVariables getVariables()
|
public ItemVariables getVariables()
|
||||||
@@ -2524,10 +2437,9 @@ public class ItemInstance extends WorldObject
|
|||||||
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
||||||
|
|
||||||
// When removed, cancel existing lifetime task.
|
// When removed, cancel existing lifetime task.
|
||||||
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
|
if (visualId == 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask.cancel(true);
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
onVisualLifeTimeEnd();
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2539,25 +2451,22 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void scheduleVisualLifeTime()
|
public void scheduleVisualLifeTime()
|
||||||
{
|
{
|
||||||
if (_appearanceLifeTimeTask != null)
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
}
|
|
||||||
if (getVisualLifeTime() > 0)
|
if (getVisualLifeTime() > 0)
|
||||||
{
|
{
|
||||||
final long time = getVisualLifeTime() - System.currentTimeMillis();
|
final long endTime = getVisualLifeTime();
|
||||||
if (time > 0)
|
if ((endTime - System.currentTimeMillis()) > 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
|
ItemAppearanceTaskManager.getInstance().add(this, endTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadPool.execute(this::onVisualLifeTimeEnd);
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onVisualLifeTimeEnd()
|
public void onVisualLifeTimeEnd()
|
||||||
{
|
{
|
||||||
final ItemVariables vars = getVariables();
|
final ItemVariables vars = getVariables();
|
||||||
vars.remove(ItemVariables.VISUAL_ID);
|
vars.remove(ItemVariables.VISUAL_ID);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,17 +19,15 @@ package org.l2jmobius.gameserver.model.buylist;
|
|||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
import org.l2jmobius.gameserver.model.items.type.EtcItemType;
|
||||||
|
import org.l2jmobius.gameserver.taskmanager.BuyListTaskManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author NosBit
|
* @author NosBit
|
||||||
@@ -45,7 +43,6 @@ public class Product
|
|||||||
private final long _maxCount;
|
private final long _maxCount;
|
||||||
private final double _baseTax;
|
private final double _baseTax;
|
||||||
private AtomicLong _count = null;
|
private AtomicLong _count = null;
|
||||||
private ScheduledFuture<?> _restockTask = null;
|
|
||||||
|
|
||||||
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
public Product(int buyListId, Item item, long price, long restockDelay, long maxCount, int baseTax)
|
||||||
{
|
{
|
||||||
@@ -122,10 +119,9 @@ public class Product
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((_restockTask == null) || _restockTask.isDone())
|
|
||||||
{
|
BuyListTaskManager.getInstance().add(this, _restockDelay);
|
||||||
_restockTask = ThreadPool.schedule(this::restock, _restockDelay);
|
|
||||||
}
|
|
||||||
final boolean result = _count.addAndGet(-value) >= 0;
|
final boolean result = _count.addAndGet(-value) >= 0;
|
||||||
save();
|
save();
|
||||||
return result;
|
return result;
|
||||||
@@ -141,7 +137,7 @@ public class Product
|
|||||||
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
final long remainTime = nextRestockTime - System.currentTimeMillis();
|
||||||
if (remainTime > 0)
|
if (remainTime > 0)
|
||||||
{
|
{
|
||||||
_restockTask = ThreadPool.schedule(this::restock, remainTime);
|
BuyListTaskManager.getInstance().update(this, remainTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -164,9 +160,10 @@ public class Product
|
|||||||
statement.setInt(2, _item.getId());
|
statement.setInt(2, _item.getId());
|
||||||
statement.setLong(3, getCount());
|
statement.setLong(3, getCount());
|
||||||
statement.setLong(5, 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(4, nextRestockTime);
|
||||||
statement.setLong(6, nextRestockTime);
|
statement.setLong(6, nextRestockTime);
|
||||||
}
|
}
|
||||||
@@ -175,6 +172,7 @@ public class Product
|
|||||||
statement.setLong(4, 0);
|
statement.setLong(4, 0);
|
||||||
statement.setLong(6, 0);
|
statement.setLong(6, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
|
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.InventoryUpdate;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
||||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
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;
|
import org.l2jmobius.gameserver.util.GMAudit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -139,7 +141,6 @@ public class ItemInstance extends WorldObject
|
|||||||
/** Shadow item */
|
/** Shadow item */
|
||||||
private int _mana = -1;
|
private int _mana = -1;
|
||||||
private boolean _consumingMana = false;
|
private boolean _consumingMana = false;
|
||||||
private static final int MANA_CONSUMPTION_RATE = 60000;
|
|
||||||
|
|
||||||
/** Custom item types (used loto, race tickets) */
|
/** Custom item types (used loto, race tickets) */
|
||||||
private int _type1;
|
private int _type1;
|
||||||
@@ -169,8 +170,6 @@ public class ItemInstance extends WorldObject
|
|||||||
private Map<AttributeType, AttributeHolder> _elementals = null;
|
private Map<AttributeType, AttributeHolder> _elementals = null;
|
||||||
|
|
||||||
private ScheduledFuture<?> _itemLootShedule = null;
|
private ScheduledFuture<?> _itemLootShedule = null;
|
||||||
private ScheduledFuture<?> _lifeTimeTask;
|
|
||||||
private ScheduledFuture<?> _appearanceLifeTimeTask;
|
|
||||||
|
|
||||||
private final DropProtection _dropProtection = new DropProtection();
|
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
|
* Returns true if this item is a shadow item Shadow items have a limited life-time
|
||||||
* @return
|
* @return
|
||||||
@@ -1455,7 +1423,7 @@ public class ItemInstance extends WorldObject
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_consumingMana = true;
|
_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>
|
* <b><u>Example of use</u>:</b><br>
|
||||||
* <li>Drop item</li>
|
* <li>Drop item</li>
|
||||||
* <li>Call Pet</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;
|
int x = locX;
|
||||||
private final Creature _dropper;
|
int y = locY;
|
||||||
private final ItemInstance _itеm;
|
int z = locZ;
|
||||||
|
|
||||||
public ItemDropTask(ItemInstance item, Creature dropper, int x, int y, int z)
|
if (dropper != null)
|
||||||
{
|
{
|
||||||
_x = x;
|
final Instance instance = dropper.getInstanceWorld();
|
||||||
_y = y;
|
final Location dropDest = GeoEngine.getInstance().canMoveToTargetLoc(dropper.getX(), dropper.getY(), dropper.getZ(), x, y, z, instance);
|
||||||
_z = z;
|
x = dropDest.getX();
|
||||||
_dropper = dropper;
|
y = dropDest.getY();
|
||||||
_itеm = item;
|
z = dropDest.getZ();
|
||||||
|
setInstance(instance); // Inherit instancezone when dropped in visible world
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setInstance(null); // No dropper? Make it a global item...
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Set the x,y,z position of the ItemInstance dropped and update its world region
|
||||||
public void run()
|
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)
|
ItemsOnGroundManager.getInstance().save(this);
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
setDropperObjectId(0); // Set the dropper Id back to 0 so it no longer shows the drop packet
|
||||||
|
|
||||||
public void dropMe(Creature dropper, int x, int y, int z)
|
|
||||||
{
|
|
||||||
ThreadPool.execute(new ItemDropTask(this, dropper, x, y, z));
|
|
||||||
if ((dropper != null) && dropper.isPlayer())
|
if ((dropper != null) && dropper.isPlayer())
|
||||||
{
|
{
|
||||||
_owner = null;
|
_owner = null;
|
||||||
@@ -1897,38 +1849,7 @@ public class ItemInstance extends WorldObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_lifeTimeTask != null)
|
ItemLifeTimeTaskManager.getInstance().add(this, getRemainingTime());
|
||||||
{
|
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2472,16 +2393,8 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void stopAllTasks()
|
public void stopAllTasks()
|
||||||
{
|
{
|
||||||
if ((_lifeTimeTask != null) && !_lifeTimeTask.isDone())
|
ItemLifeTimeTaskManager.getInstance().remove(this);
|
||||||
{
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_lifeTimeTask.cancel(false);
|
|
||||||
_lifeTimeTask = null;
|
|
||||||
}
|
|
||||||
if ((_appearanceLifeTimeTask != null) && !_appearanceLifeTimeTask.isDone())
|
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemVariables getVariables()
|
public ItemVariables getVariables()
|
||||||
@@ -2524,10 +2437,9 @@ public class ItemInstance extends WorldObject
|
|||||||
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
getVariables().set(ItemVariables.VISUAL_ID, visualId);
|
||||||
|
|
||||||
// When removed, cancel existing lifetime task.
|
// When removed, cancel existing lifetime task.
|
||||||
if ((visualId == 0) && (_appearanceLifeTimeTask != null))
|
if (visualId == 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask.cancel(true);
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
_appearanceLifeTimeTask = null;
|
|
||||||
onVisualLifeTimeEnd();
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2539,25 +2451,22 @@ public class ItemInstance extends WorldObject
|
|||||||
|
|
||||||
public void scheduleVisualLifeTime()
|
public void scheduleVisualLifeTime()
|
||||||
{
|
{
|
||||||
if (_appearanceLifeTimeTask != null)
|
ItemAppearanceTaskManager.getInstance().remove(this);
|
||||||
{
|
|
||||||
_appearanceLifeTimeTask.cancel(false);
|
|
||||||
}
|
|
||||||
if (getVisualLifeTime() > 0)
|
if (getVisualLifeTime() > 0)
|
||||||
{
|
{
|
||||||
final long time = getVisualLifeTime() - System.currentTimeMillis();
|
final long endTime = getVisualLifeTime();
|
||||||
if (time > 0)
|
if ((endTime - System.currentTimeMillis()) > 0)
|
||||||
{
|
{
|
||||||
_appearanceLifeTimeTask = ThreadPool.schedule(this::onVisualLifeTimeEnd, time);
|
ItemAppearanceTaskManager.getInstance().add(this, endTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadPool.execute(this::onVisualLifeTimeEnd);
|
onVisualLifeTimeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onVisualLifeTimeEnd()
|
public void onVisualLifeTimeEnd()
|
||||||
{
|
{
|
||||||
final ItemVariables vars = getVariables();
|
final ItemVariables vars = getVariables();
|
||||||
vars.remove(ItemVariables.VISUAL_ID);
|
vars.remove(ItemVariables.VISUAL_ID);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user