Перейти к содержанию
Авторизация  
hodor

Знающие Java - помогите подкорректировать.

Рекомендуемые сообщения

Добавил LifeTime (удаляет итем по истечению времени даже если шмотка не одета) и появился баг если это шмотка, оружие - удаляется из инвентаря, но остается на персонаже...

 

Вот как это выглядит (только одел шмотку):

1a1a0c7552.jpg

 

А вот тут время шмотки истекает и она удаляется из инвентаря, но почему-то остается как вид на персонаже, но после релога или телепорта в другой город вид шмотки пропадает:

d9c7a33890.jpg

 

Сам код ( /* LifeTime start */ сделал для удобство поиска того, что я добавлял ) :

/*
 * 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 net.sf.l2j.gameserver.model.itemcontainer;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.sql.SQLException;

import net.sf.l2j.commons.config.Config;
import net.sf.l2j.commons.db.DatabaseFactory;
import net.sf.l2j.gameserver.datatables.ItemTable;
import net.sf.l2j.gameserver.instancemanager.PremiumManager;
/* LifeTime start */
import net.sf.l2j.gameserver.instancemanager.LifeTimeManager;
/* LifeTime end */
import net.sf.l2j.gameserver.model.L2Object;
import net.sf.l2j.gameserver.model.TradeList;
import net.sf.l2j.gameserver.model.TradeList.TradeItem;
import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
import net.sf.l2j.gameserver.model.item.instance.ItemInstance;
import net.sf.l2j.gameserver.model.item.instance.ItemInstance.ItemLocation;
import net.sf.l2j.gameserver.model.item.kind.Item;
import net.sf.l2j.gameserver.model.item.type.EtcItemType;
import net.sf.l2j.gameserver.model.itemcontainer.listeners.ArmorSetListener;
import net.sf.l2j.gameserver.model.itemcontainer.listeners.BowRodListener;
import net.sf.l2j.gameserver.model.itemcontainer.listeners.ItemPassiveSkillsListener;
import net.sf.l2j.gameserver.model.itemcontainer.listeners.ShadowWeaponListener;
import net.sf.l2j.gameserver.network.serverpackets.InventoryUpdate;
import net.sf.l2j.gameserver.network.serverpackets.ItemList;
import net.sf.l2j.gameserver.network.serverpackets.StatusUpdate;
import net.sf.l2j.gameserver.util.Util;

public class PcInventory extends Inventory
{
	public static final int ADENA_ID = 57;
	public static final int ANCIENT_ADENA_ID = 5575;
	
	private final L2PcInstance _owner;
	private ItemInstance _adena;
	private ItemInstance _ancientAdena;
	
	private int[] _blockItems = null;
	
	private int _questSlots;
	/**
	 * Block modes:
	 * <UL>
	 * <LI>-1 - no block
	 * <LI>0 - block items from _invItems, allow usage of other items
	 * <LI>1 - allow usage of items from _invItems, block other items
	 * </UL>
	 */
	private int _blockMode = -1;
	
	public PcInventory(L2PcInstance owner)
	{
		super();
		_owner = owner;
		
		addPaperdollListener(ArmorSetListener.getInstance());
		addPaperdollListener(BowRodListener.getInstance());
		addPaperdollListener(ItemPassiveSkillsListener.getInstance());
		addPaperdollListener(ShadowWeaponListener.getInstance());
	}
	
	@Override
	public L2PcInstance getOwner()
	{
		return _owner;
	}
	
	@Override
	protected ItemLocation getBaseLocation()
	{
		return ItemLocation.INVENTORY;
	}
	
	@Override
	protected ItemLocation getEquipLocation()
	{
		return ItemLocation.PAPERDOLL;
	}
	
	public ItemInstance getAdenaInstance()
	{
		return _adena;
	}
	
	@Override
	public int getAdena()
	{
		return _adena != null ? _adena.getCount() : 0;
	}
	
	public ItemInstance getAncientAdenaInstance()
	{
		return _ancientAdena;
	}
	
	public int getAncientAdena()
	{
		return (_ancientAdena != null) ? _ancientAdena.getCount() : 0;
	}
	
	public ItemInstance[] getUniqueItems(boolean allowAdena, boolean allowAncientAdena)
	{
		return getUniqueItems(allowAdena, allowAncientAdena, true);
	}
	
	/**
	 * Returns the list of items in inventory available for transaction
	 * @param allowAdena
	 * @param allowAncientAdena
	 * @param onlyAvailable
	 * @return ItemInstance : items in inventory
	 */
	public ItemInstance[] getUniqueItems(boolean allowAdena, boolean allowAncientAdena, boolean onlyAvailable)
	{
		List<ItemInstance> list = new ArrayList<>();
		for (ItemInstance item : _items)
		{
			if (item == null)
			{
				continue;
			}
			
			if (!allowAdena && item.getItemId() == ADENA_ID)
			{
				continue;
			}
			
			if (!allowAncientAdena && item.getItemId() == ANCIENT_ADENA_ID)
			{
				continue;
			}
			
			boolean isDuplicate = false;
			for (ItemInstance litem : list)
			{
				if (litem.getItemId() == item.getItemId())
				{
					isDuplicate = true;
					break;
				}
			}
			if (!isDuplicate && (!onlyAvailable || (item.isSellable() && item.isAvailable(getOwner(), false, false))))
			{
				list.add(item);
			}
		}
		return list.toArray(new ItemInstance[list.size()]);
	}
	
	/**
	 * Returns the list of items in inventory available for transaction Allows an item to appear twice if and only if there is a difference in enchantment level.
	 * @param allowAdena
	 * @param allowAncientAdena
	 * @return ItemInstance : items in inventory
	 */
	public ItemInstance[] getUniqueItemsByEnchantLevel(boolean allowAdena, boolean allowAncientAdena)
	{
		return getUniqueItemsByEnchantLevel(allowAdena, allowAncientAdena, true);
	}
	
	public ItemInstance[] getUniqueItemsByEnchantLevel(boolean allowAdena, boolean allowAncientAdena, boolean onlyAvailable)
	{
		List<ItemInstance> list = new ArrayList<>();
		for (ItemInstance item : _items)
		{
			if (item == null)
			{
				continue;
			}
			
			if (!allowAdena && item.getItemId() == ADENA_ID)
			{
				continue;
			}
			
			if (!allowAncientAdena && item.getItemId() == ANCIENT_ADENA_ID)
			{
				continue;
			}
			
			boolean isDuplicate = false;
			for (ItemInstance litem : list)
			{
				if ((litem.getItemId() == item.getItemId()) && (litem.getEnchantLevel() == item.getEnchantLevel()))
				{
					isDuplicate = true;
					break;
				}
			}
			if (!isDuplicate && (!onlyAvailable || (item.isSellable() && item.isAvailable(getOwner(), false, false))))
			{
				list.add(item);
			}
		}
		return list.toArray(new ItemInstance[list.size()]);
	}
	
	/**
	 * @param itemId
	 * @return
	 * @see net.sf.l2j.gameserver.model.itemcontainer.PcInventory#getAllItemsByItemId(int, boolean)
	 */
	public ItemInstance[] getAllItemsByItemId(int itemId)
	{
		return getAllItemsByItemId(itemId, true);
	}
	
	/**
	 * Returns the list of all items in inventory that have a given item id.
	 * @param itemId : ID of item
	 * @param includeEquipped : include equipped items
	 * @return ItemInstance[] : matching items from inventory
	 */
	public ItemInstance[] getAllItemsByItemId(int itemId, boolean includeEquipped)
	{
		List<ItemInstance> list = new ArrayList<>();
		for (ItemInstance item : _items)
		{
			if (item == null)
			{
				continue;
			}
			
			if (item.getItemId() == itemId && (includeEquipped || !item.isEquipped()))
			{
				list.add(item);
			}
		}
		return list.toArray(new ItemInstance[list.size()]);
	}
	
	/**
	 * @param itemId
	 * @param enchantment
	 * @return
	 * @see net.sf.l2j.gameserver.model.itemcontainer.PcInventory#getAllItemsByItemId(int, int, boolean)
	 */
	public ItemInstance[] getAllItemsByItemId(int itemId, int enchantment)
	{
		return getAllItemsByItemId(itemId, enchantment, true);
	}
	
	/**
	 * Returns the list of all items in inventory that have a given item id AND a given enchantment level.
	 * @param itemId : ID of item
	 * @param enchantment : enchant level of item
	 * @param includeEquipped : include equipped items
	 * @return ItemInstance[] : matching items from inventory
	 */
	public ItemInstance[] getAllItemsByItemId(int itemId, int enchantment, boolean includeEquipped)
	{
		List<ItemInstance> list = new ArrayList<>();
		for (ItemInstance item : _items)
		{
			if (item == null)
			{
				continue;
			}
			
			if ((item.getItemId() == itemId) && (item.getEnchantLevel() == enchantment) && (includeEquipped || !item.isEquipped()))
			{
				list.add(item);
			}
		}
		return list.toArray(new ItemInstance[list.size()]);
	}
	
	/**
	 * Returns the list of items in inventory available for transaction
	 * @param allowAdena
	 * @param allowNonTradeable
	 * @return ItemInstance : items in inventory
	 */
	public ItemInstance[] getAvailableItems(boolean allowAdena, boolean allowNonTradeable)
	{
		List<ItemInstance> list = new ArrayList<>();
		for (ItemInstance item : _items)
		{
			if (item != null && item.isAvailable(getOwner(), allowAdena, allowNonTradeable) && canManipulateWithItemId(item.getItemId()))
			{
				list.add(item);
			}
		}
		return list.toArray(new ItemInstance[list.size()]);
	}
	
	/**
	 * Get all augmented items
	 * @return
	 */
	public ItemInstance[] getAugmentedItems()
	{
		List<ItemInstance> list = new ArrayList<>();
		for (ItemInstance item : _items)
		{
			if (item != null && item.isAugmented())
			{
				list.add(item);
			}
		}
		return list.toArray(new ItemInstance[list.size()]);
	}
	
	/**
	 * Returns the list of items in inventory available for transaction adjusetd by tradeList
	 * @param tradeList
	 * @return ItemInstance : items in inventory
	 */
	public TradeItem[] getAvailableItems(TradeList tradeList)
	{
		List<TradeItem> list = new ArrayList<>();
		for (ItemInstance item : _items)
		{
			if (item != null && item.isAvailable(getOwner(), false, false))
			{
				TradeItem adjItem = tradeList.adjustAvailableItem(item);
				if (adjItem != null)
				{
					list.add(adjItem);
				}
			}
		}
		return list.toArray(new TradeItem[list.size()]);
	}
	
	/**
	 * Adjust TradeItem according his status in inventory
	 * @param item : ItemInstance to be adjusten
	 */
	public void adjustAvailableItem(TradeItem item)
	{
		boolean notAllEquipped = false;
		for (ItemInstance adjItem : getItemsByItemId(item.getItem().getItemId()))
		{
			if (adjItem.isEquipable())
			{
				if (!adjItem.isEquipped())
				{
					notAllEquipped |= true;
				}
			}
			else
			{
				notAllEquipped |= true;
				break;
			}
		}
		if (notAllEquipped)
		{
			ItemInstance adjItem = getItemByItemId(item.getItem().getItemId());
			item.setObjectId(adjItem.getObjectId());
			item.setEnchant(adjItem.getEnchantLevel());
			
			if (adjItem.getCount() < item.getCount())
			{
				item.setCount(adjItem.getCount());
			}
			
			return;
		}
		
		item.setCount(0);
	}
	
	/**
	 * Adds adena to PCInventory
	 * @param process : String Identifier of process triggering this action
	 * @param count : int Quantity of adena to be added
	 * @param actor : L2PcInstance Player requesting the item add
	 * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
	 */
	public void addAdena(String process, int count, L2PcInstance actor, L2Object reference)
	{
		if (count > 0)
		{
			addItem(process, ADENA_ID, count, actor, reference);
		}
	}
	
	/**
	 * Removes adena to PCInventory
	 * @param process : String Identifier of process triggering this action
	 * @param count : int Quantity of adena to be removed
	 * @param actor : L2PcInstance Player requesting the item add
	 * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
	 * @return true if successful.
	 */
	public boolean reduceAdena(String process, int count, L2PcInstance actor, L2Object reference)
	{
		if (count > 0)
		{
			return destroyItemByItemId(process, ADENA_ID, count, actor, reference) != null;
		}
		
		return false;
	}
	
	/**
	 * Adds specified amount of ancient adena to player inventory.
	 * @param process : String Identifier of process triggering this action
	 * @param count : int Quantity of adena to be added
	 * @param actor : L2PcInstance Player requesting the item add
	 * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
	 */
	public void addAncientAdena(String process, int count, L2PcInstance actor, L2Object reference)
	{
		if (count > 0)
		{
			addItem(process, ANCIENT_ADENA_ID, count, actor, reference);
		}
	}
	
	/**
	 * Removes specified amount of ancient adena from player inventory.
	 * @param process : String Identifier of process triggering this action
	 * @param count : int Quantity of adena to be removed
	 * @param actor : L2PcInstance Player requesting the item add
	 * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
	 * @return true if successful.
	 */
	public boolean reduceAncientAdena(String process, int count, L2PcInstance actor, L2Object reference)
	{
		if (count > 0)
		{
			return destroyItemByItemId(process, ANCIENT_ADENA_ID, count, actor, reference) != null;
		}
		
		return false;
	}
	
	/**
	 * Adds item in inventory and checks _adena and _ancientAdena
	 * @param process : String Identifier of process triggering this action
	 * @param item : ItemInstance to be added
	 * @param actor : L2PcInstance Player requesting the item add
	 * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
	 * @return ItemInstance corresponding to the new item or the updated item in inventory
	 */
	@Override
	public ItemInstance addItem(String process, ItemInstance item, L2PcInstance actor, L2Object reference)
	{
		item = super.addItem(process, item, actor, reference);
		if (item == null)
		{
			return null;
		}
		
		if (item.getItemId() == ADENA_ID && !item.equals(_adena))
		{
			_adena = item;
		}
		else if (item.getItemId() == ANCIENT_ADENA_ID && !item.equals(_ancientAdena))
		{
			_ancientAdena = item;
		}
		
		if (Config.PREMIUM_ITEM_ENABLED)
		{
			for (int i = 0; i < Config.PREMIUM_ITEM_IDS.length; i++)
			{
				if (item.getItemId() == Config.PREMIUM_ITEM_IDS[i])
				{
					PremiumManager.getInstance().addPremiumItem(item, i);
				}
			}
			actor.calculatePremiumAttributes();
		}
		/* LifeTime start */
		if(item.getItem().getLifetime()!=-1)
 	 		LifeTimeManager.getInstance().setTimedItem(item);
		/* LifeTime end */
		
		return item;
	}
	
	/**
	 * Adds item in inventory and checks _adena and _ancientAdena
	 * @param process : String Identifier of process triggering this action
	 * @param itemId : int Item Identifier of the item to be added
	 * @param count : int Quantity of items to be added
	 * @param actor : L2PcInstance Player requesting the item creation
	 * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
	 * @return ItemInstance corresponding to the new item or the updated item in inventory
	 */
	@Override
	public ItemInstance addItem(String process, int itemId, int count, L2PcInstance actor, L2Object reference)
	{
		ItemInstance item = super.addItem(process, itemId, count, actor, reference);
		if (item == null)
		{
			return null;
		}
		
		if (item.getItemId() == ADENA_ID && !item.equals(_adena))
		{
			_adena = item;
		}
		else if (item.getItemId() == ANCIENT_ADENA_ID && !item.equals(_ancientAdena))
		{
			_ancientAdena = item;
		}
		
		if (actor != null)
		{
			if (Config.PREMIUM_ITEM_ENABLED)
			{
				for (int i = 0; i < Config.PREMIUM_ITEM_IDS.length; i++)
				{
					if (item.getItemId() == Config.PREMIUM_ITEM_IDS[i])
					{
						PremiumManager.getInstance().addPremiumItem(item, i);
					}
				}
				actor.calculatePremiumAttributes();
			}
			
			// Send inventory update packet 
			InventoryUpdate playerIU = new InventoryUpdate();
			playerIU.addItem(item);
			actor.sendPacket(playerIU);
			
			// Update current load as well
			StatusUpdate su = new StatusUpdate(actor);
			su.addAttribute(StatusUpdate.CUR_LOAD, actor.getCurrentLoad());
			actor.sendPacket(su);
		}
		/* LifeTime start */
		if(item.getItem().getLifetime()!=-1)
 	 		LifeTimeManager.getInstance().setTimedItem(item);
		/* LifeTime end */
		
		return item;
	}
	
	/**
	 * Transfers item to another inventory and checks _adena and _ancientAdena
	 * @param process : String Identifier of process triggering this action
	 * @param objectId : int Item Identifier of the item to be transfered
	 * @param count : int Quantity of items to be transfered
	 * @param actor : L2PcInstance Player requesting the item transfer
	 * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
	 * @return ItemInstance corresponding to the new item or the updated item in inventory
	 */
	@Override
	public ItemInstance transferItem(String process, int objectId, int count, ItemContainer target, L2PcInstance actor, L2Object reference)
	{
		ItemInstance item = super.transferItem(process, objectId, count, target, actor, reference);
		
		if (_adena != null && (_adena.getCount() <= 0 || _adena.getOwnerId() != getOwnerId()))
		{
			_adena = null;
		}
		
		if (_ancientAdena != null && (_ancientAdena.getCount() <= 0 || _ancientAdena.getOwnerId() != getOwnerId()))
		{
			_ancientAdena = null;
		}
		
		return item;
	}
	
	/**
	 * Destroy item from inventory and checks _adena and _ancientAdena
	 * @param process : String Identifier of process triggering this action
	 * @param item : ItemInstance to be destroyed
	 * @param actor : L2PcInstance Player requesting the item destroy
	 * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
	 * @return ItemInstance corresponding to the destroyed item or the updated item in inventory
	 */
	@Override
	public ItemInstance destroyItem(String process, ItemInstance item, L2PcInstance actor, L2Object reference)
	{
		return this.destroyItem(process, item, item.getCount(), actor, reference);
	}
	
	/**
	 * Destroy item from inventory and checks _adena and _ancientAdena
	 * @param process : String Identifier of process triggering this action
	 * @param item : ItemInstance to be destroyed
	 * @param actor : L2PcInstance Player requesting the item destroy
	 * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
	 * @return ItemInstance corresponding to the destroyed item or the updated item in inventory
	 */
	@Override
	public ItemInstance destroyItem(String process, ItemInstance item, int count, L2PcInstance actor, L2Object reference)
	{
		item = super.destroyItem(process, item, count, actor, reference);
		
		if (_adena != null && _adena.getCount() <= 0)
		{
			_adena = null;
		}
		
		if (_ancientAdena != null && _ancientAdena.getCount() <= 0)
		{
			_ancientAdena = null;
		}
		
		if (Config.PREMIUM_ITEM_ENABLED)
		{
			for (int i = 0; i < Config.PREMIUM_ITEM_IDS.length; i++)
			{
				if (item.getItemId() == Config.PREMIUM_ITEM_IDS[i])
				{
					PremiumManager.getInstance().destroyItem(item);
				}
			}
			actor.calculatePremiumAttributes();
		}
		/* LifeTime start */
		if(item != null && item.getItem().getLifetime()!= -1)
			LifeTimeManager.getInstance().destroyItem(item);
		/* LifeTime end */
		
		return item;
	}
	
	/**
	 * Destroys item from inventory and checks _adena and _ancientAdena
	 * @param process : String Identifier of process triggering this action
	 * @param objectId : int Item Instance identifier of the item to be destroyed
	 * @param count : int Quantity of items to be destroyed
	 * @param actor : L2PcInstance Player requesting the item destroy
	 * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
	 * @return ItemInstance corresponding to the destroyed item or the updated item in inventory
	 */
	@Override
	public ItemInstance destroyItem(String process, int objectId, int count, L2PcInstance actor, L2Object reference)
	{
		ItemInstance item = getItemByObjectId(objectId);
		if (item == null)
		{
			return null;
		}
		
		return this.destroyItem(process, item, count, actor, reference);
	}
	
	/**
	 * Destroy item from inventory by using its <B>itemId</B> and checks _adena and _ancientAdena
	 * @param process : String Identifier of process triggering this action
	 * @param itemId : int Item identifier of the item to be destroyed
	 * @param count : int Quantity of items to be destroyed
	 * @param actor : L2PcInstance Player requesting the item destroy
	 * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
	 * @return ItemInstance corresponding to the destroyed item or the updated item in inventory
	 */
	@Override
	public ItemInstance destroyItemByItemId(String process, int itemId, int count, L2PcInstance actor, L2Object reference)
	{
		ItemInstance item = getItemByItemId(itemId);
		if (item == null)
		{
			return null;
		}
		
		return this.destroyItem(process, item, count, actor, reference);
	}
	
	/**
	 * Drop item from inventory and checks _adena and _ancientAdena
	 * @param process : String Identifier of process triggering this action
	 * @param item : ItemInstance to be dropped
	 * @param actor : L2PcInstance Player requesting the item drop
	 * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
	 * @return ItemInstance corresponding to the destroyed item or the updated item in inventory
	 */
	@Override
	public ItemInstance dropItem(String process, ItemInstance item, L2PcInstance actor, L2Object reference)
	{
		item = super.dropItem(process, item, actor, reference);
		
		if (_adena != null && (_adena.getCount() <= 0 || _adena.getOwnerId() != getOwnerId()))
		{
			_adena = null;
		}
		
		if (_ancientAdena != null && (_ancientAdena.getCount() <= 0 || _ancientAdena.getOwnerId() != getOwnerId()))
		{
			_ancientAdena = null;
		}
		
		return item;
	}
	
	/**
	 * Drop item from inventory by using its <B>objectID</B> and checks _adena and _ancientAdena
	 * @param process : String Identifier of process triggering this action
	 * @param objectId : int Item Instance identifier of the item to be dropped
	 * @param count : int Quantity of items to be dropped
	 * @param actor : L2PcInstance Player requesting the item drop
	 * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
	 * @return ItemInstance corresponding to the destroyed item or the updated item in inventory
	 */
	@Override
	public ItemInstance dropItem(String process, int objectId, int count, L2PcInstance actor, L2Object reference)
	{
		ItemInstance item = super.dropItem(process, objectId, count, actor, reference);
		
		if (_adena != null && (_adena.getCount() <= 0 || _adena.getOwnerId() != getOwnerId()))
		{
			_adena = null;
		}
		
		if (_ancientAdena != null && (_ancientAdena.getCount() <= 0 || _ancientAdena.getOwnerId() != getOwnerId()))
		{
			_ancientAdena = null;
		}
		
		return item;
	}
	
	/**
	 * <b>Overloaded</b>, when removes item from inventory, remove also owner shortcuts.
	 * @param item : ItemInstance to be removed from inventory
	 */
	@Override
	protected boolean removeItem(ItemInstance item)
	{
		// Removes any reference to the item from Shortcut bar
		getOwner().removeItemFromShortCut(item.getObjectId());
		
		// Removes active Enchant Scroll
		if (item.equals(getOwner().getActiveEnchantItem()))
		{
			getOwner().setActiveEnchantItem(null);
		}
		
		if (item.getItemId() == ADENA_ID)
		{
			_adena = null;
		}
		else if (item.getItemId() == ANCIENT_ADENA_ID)
		{
			_ancientAdena = null;
		}
		
		synchronized (_items)
		{
			if (item.isQuestItem())
			{
				_questSlots--;
				if (_questSlots < 0)
				{
					_questSlots = 0;
					_log.warn(this + ": QuestInventory size < 0!");
				}
			}
			return super.removeItem(item);
		}
	}
	
	/**
	 * Refresh the weight of equipment loaded
	 */
	@Override
	public void refreshWeight()
	{
		super.refreshWeight();
		getOwner().refreshOverloaded();
	}
	
	/**
	 * Get back items in inventory from database
	 */
	@Override
	public void restore()
	{
		super.restore();
		_adena = getItemByItemId(ADENA_ID);
		_ancientAdena = getItemByItemId(ANCIENT_ADENA_ID);
	}
	
	/**
	 * Method used only while logout.<br>
	 * For every equipped shadow item, stop associated timer.
	 */
	public void stopShadowTimers()
	{
		for (ItemInstance item : getPaperdollItems())
		{
			if (item.isShadowItem())
			{
				item.stopTimer();
			}
		}
	}
	
	public static int[][] restoreVisibleInventory(int objectId)
	{
		int[][] paperdoll = new int[0x12][3];
		try (Connection con = DatabaseFactory.getInstance().getConnection())
		{
			PreparedStatement statement2 = con.prepareStatement("SELECT object_id,item_id,loc_data,enchant_level FROM items WHERE owner_id=? AND loc='PAPERDOLL'");
			statement2.setInt(1, objectId);
			ResultSet invdata = statement2.executeQuery();
			
			while (invdata.next())
			{
				int slot = invdata.getInt("loc_data");
				paperdoll[slot][0] = invdata.getInt("object_id");
				paperdoll[slot][1] = invdata.getInt("item_id");
				paperdoll[slot][2] = invdata.getInt("enchant_level");
			}
			
			invdata.close();
			statement2.close();
		}
		catch (Exception e)
		{
			_log.warn("Could not restore inventory: " + e.getMessage(), e);
		}
		return paperdoll;
	}
	
	public boolean validateCapacity(ItemInstance item)
	{
		int slots = 0;
		
		if (!(item.isStackable() && getItemByItemId(item.getItemId()) != null) && item.getItemType() != EtcItemType.HERB)
		{
			slots++;
		}
		
		return validateCapacity(slots, item.isQuestItem());
	}
	
	public boolean validateCapacityByItemId(int ItemId)
	{
		int slots = 0;
		Item item = ItemTable.getInstance().getTemplate(ItemId);
		ItemInstance invItem = getItemByItemId(ItemId);
		if (!(invItem != null && invItem.isStackable()))
		{
			slots++;
		}
		
		return validateCapacity(slots, item.isQuestItem());
	}
	
	@Override
	public boolean validateCapacity(int slots)
	{
		return validateCapacity(slots, false);
	}
	
	public boolean validateCapacity(int slots, boolean questItem)
	{
		if (!questItem)
		{
			return (_items.size() - _questSlots + slots <= _owner.getInventoryLimit());
		}
		
		return _questSlots + slots <= L2PcInstance.getQuestInventoryLimit();
	}
	
	@Override
	public boolean validateWeight(int weight)
	{
		return (_totalWeight + weight <= _owner.getMaxLoad());
	}
	
	/**
	 * Set inventory block for specified IDs<br>
	 * array reference is used for {@link PcInventory#_blockItems}
	 * @param items array of Ids to block/allow
	 * @param mode blocking mode {@link PcInventory#_blockMode}
	 */
	public void setInventoryBlock(int[] items, int mode)
	{
		_blockMode = mode;
		_blockItems = items;
		
		_owner.sendPacket(new ItemList(_owner, false));
	}
	
	/**
	 * Unblock blocked itemIds
	 */
	public void unblock()
	{
		_blockMode = -1;
		_blockItems = null;
		
		_owner.sendPacket(new ItemList(_owner, false));
	}
	
	/**
	 * Check if player inventory is in block mode.
	 * @return true if some itemIds blocked
	 */
	public boolean hasInventoryBlock()
	{
		return (_blockMode > -1 && _blockItems != null && _blockItems.length > 0);
	}
	
	/**
	 * Return block mode
	 * @return int {@link PcInventory#_blockMode}
	 */
	public int getBlockMode()
	{
		return _blockMode;
	}
	
	/**
	 * Return TIntArrayList with blocked item ids
	 * @return TIntArrayList
	 */
	public int[] getBlockItems()
	{
		return _blockItems;
	}
	
	/**
	 * Check if player can use item by itemid
	 * @param itemId int
	 * @return true if can use
	 */
	public boolean canManipulateWithItemId(int itemId)
	{
		if ((_blockMode == 0 && Util.contains(_blockItems, itemId)) || (_blockMode == 1 && !Util.contains(_blockItems, itemId)))
		{
			return false;
		}
		return true;
	}
	
	@Override
	protected void addItem(ItemInstance item)
	{
		synchronized (_items)
		{
			if (item.isQuestItem())
			{
				_questSlots++;
			}
			
			super.addItem(item);
		}
	}
	
	public int getSize(boolean quest)
	{
		if (quest)
		{
			return _questSlots;
		}
		
		return getSize() - _questSlots;
	}
	
	@Override
	public String toString()
	{
		return getClass().getSimpleName() + "[" + _owner + "]";
	}
}
 

 

 

/*
 * 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 net.sf.l2j.gameserver.model.item.kind;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import net.sf.l2j.commons.config.Config;
import net.sf.l2j.gameserver.datatables.ItemTable;
import net.sf.l2j.gameserver.model.L2Effect;
import net.sf.l2j.gameserver.model.L2Object;
import net.sf.l2j.gameserver.model.actor.L2Character;
import net.sf.l2j.gameserver.model.actor.L2Summon;
import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
import net.sf.l2j.gameserver.model.holder.SkillHolder;
import net.sf.l2j.gameserver.model.item.instance.ItemInstance;
import net.sf.l2j.gameserver.model.item.type.ActionType;
import net.sf.l2j.gameserver.model.item.type.ArmorType;
import net.sf.l2j.gameserver.model.item.type.CrystalType;
import net.sf.l2j.gameserver.model.item.type.EtcItemType;
import net.sf.l2j.gameserver.model.item.type.ItemType;
import net.sf.l2j.gameserver.model.item.type.MaterialType;
import net.sf.l2j.gameserver.model.item.type.WeaponType;
import net.sf.l2j.gameserver.model.quest.Quest;
import net.sf.l2j.gameserver.network.SystemMessageId;
import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
import net.sf.l2j.gameserver.skills.Env;
import net.sf.l2j.gameserver.skills.basefuncs.Func;
import net.sf.l2j.gameserver.skills.basefuncs.FuncTemplate;
import net.sf.l2j.gameserver.skills.conditions.Condition;
import net.sf.l2j.gameserver.skills.effects.EffectTemplate;
import net.sf.l2j.gameserver.templates.StatsSet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This class contains all informations concerning the item (weapon, armor, etc). Mother class of :
 * <ul>
 * <li>L2Armor</li>
 * <li>L2EtcItem</li>
 * <li>Weapon</li>
 * </ul>
 */
public abstract class Item
{
	public static final int TYPE1_WEAPON_RING_EARRING_NECKLACE = 0;
	public static final int TYPE1_SHIELD_ARMOR = 1;
	public static final int TYPE1_ITEM_QUESTITEM_ADENA = 4;
	
	public static final int TYPE2_WEAPON = 0;
	public static final int TYPE2_SHIELD_ARMOR = 1;
	public static final int TYPE2_ACCESSORY = 2;
	public static final int TYPE2_QUEST = 3;
	public static final int TYPE2_MONEY = 4;
	public static final int TYPE2_OTHER = 5;
	
	public static final int SLOT_NONE = 0x0000;
	public static final int SLOT_UNDERWEAR = 0x0001;
	public static final int SLOT_R_EAR = 0x0002;
	public static final int SLOT_L_EAR = 0x0004;
	public static final int SLOT_LR_EAR = 0x00006;
	public static final int SLOT_NECK = 0x0008;
	public static final int SLOT_R_FINGER = 0x0010;
	public static final int SLOT_L_FINGER = 0x0020;
	public static final int SLOT_LR_FINGER = 0x0030;
	public static final int SLOT_HEAD = 0x0040;
	public static final int SLOT_R_HAND = 0x0080;
	public static final int SLOT_L_HAND = 0x0100;
	public static final int SLOT_GLOVES = 0x0200;
	public static final int SLOT_CHEST = 0x0400;
	public static final int SLOT_LEGS = 0x0800;
	public static final int SLOT_FEET = 0x1000;
	public static final int SLOT_BACK = 0x2000;
	public static final int SLOT_LR_HAND = 0x4000;
	public static final int SLOT_FULL_ARMOR = 0x8000;
	public static final int SLOT_FACE = 0x010000;
	public static final int SLOT_ALLDRESS = 0x020000;
	public static final int SLOT_HAIR = 0x040000;
	public static final int SLOT_HAIRALL = 0x080000;
	
	public static final int SLOT_WOLF = -100;
	public static final int SLOT_HATCHLING = -101;
	public static final int SLOT_STRIDER = -102;
	public static final int SLOT_BABYPET = -103;
	
	public static final int SLOT_ALLWEAPON = SLOT_LR_HAND | SLOT_R_HAND;
	
	private final int _itemId;
	private final String _name;
	protected int _type1; // needed for item list (inventory)
	protected int _type2; // different lists for armor, weapon, etc
	private final int _weight;
	private final boolean _stackable;
	private final MaterialType _materialType;
	private final CrystalType _crystalType;
	private final int _duration;
	/* LifeTime start */
	private final int _lifetime;
	/* LifeTime end */
	private final int _bodyPart;
	private final int _referencePrice;
	private final int _crystalCount;
	
	private final boolean _sellable;
	private final boolean _dropable;
	private final boolean _destroyable;
	private final boolean _tradable;
	private final boolean _depositable;
	
	private final boolean _heroItem;
	private final boolean _isOlyRestricted;
	
	private final ActionType _defaultAction;
	
	protected List<FuncTemplate> _funcTemplates;
	protected List<EffectTemplate> _effectTemplates;
	
	protected List<Condition> _preConditions;
	private SkillHolder[] _skillHolder;
	
	private final List<Quest> _questEvents = new ArrayList<>();
	
	protected static final Logger _log = LoggerFactory.getLogger(Item.class.getName());
	
	/**
	 * Constructor of the L2Item that fill class variables.
	 * @param set : StatsSet corresponding to a set of couples (key,value) for description of the item
	 */
	protected Item(StatsSet set)
	{
		_itemId = set.getInteger("item_id");
		_name = set.getString("name");
		_weight = set.getInteger("weight", 0);
		_materialType = set.getEnum("material", MaterialType.class, MaterialType.STEEL);
		_duration = set.getInteger("duration", -1);
		/* LifeTime start */
		_lifetime = set.getInteger("lifetime", -1);
		/* LifeTime end */
		_bodyPart = ItemTable._slots.get(set.getString("bodypart", "none"));
		_referencePrice = set.getInteger("price", 0);
		_crystalType = set.getEnum("crystal_type", CrystalType.class, CrystalType.NONE);
		_crystalCount = set.getInteger("crystal_count", 0);
		
		_stackable = set.getBool("is_stackable", false);
		_sellable = set.getBool("is_sellable", true);
		_dropable = set.getBool("is_dropable", true);
		_destroyable = set.getBool("is_destroyable", true);
		_tradable = set.getBool("is_tradable", true);
		_depositable = set.getBool("is_depositable", true);
		
		_heroItem = (_itemId >= 6611 && _itemId <= 6621) || _itemId == 6842;
		_isOlyRestricted = set.getBool("is_oly_restricted", false);
		
		_defaultAction = set.getEnum("default_action", ActionType.class, ActionType.none);
		
		String skills = set.getString("item_skill", null);
		if (skills != null)
		{
			String[] skillsSplit = skills.split(";");
			_skillHolder = new SkillHolder[skillsSplit.length];
			int used = 0;
			
			for (String element : skillsSplit)
			{
				try
				{
					String[] skillSplit = element.split("-");
					int id = Integer.parseInt(skillSplit[0]);
					int level = Integer.parseInt(skillSplit[1]);
					
					if (id == 0)
					{
						_log.info("Ignoring item_skill(" + element + ") for item " + toString() + ". Skill id is 0.");
						continue;
					}
					
					if (level == 0)
					{
						_log.info("Ignoring item_skill(" + element + ") for item " + toString() + ". Skill level is 0.");
						continue;
					}
					
					_skillHolder[used] = new SkillHolder(id, level);
					++used;
				}
				catch (Exception e)
				{
					_log.warn("Failed to parse item_skill(" + element + ") for item " + toString() + ". The used format is wrong.");
				}
			}
			
			// this is only loading? just don't leave a null or use a collection?
			if (used != _skillHolder.length)
			{
				SkillHolder[] skillHolder = new SkillHolder[used];
				System.arraycopy(_skillHolder, 0, skillHolder, 0, used);
				_skillHolder = skillHolder;
			}
		}
	}
	
	/**
	 * @return Enum the itemType.
	 */
	public abstract ItemType getItemType();
	
	/**
	 * @return int the duration of the item
	 */
	public final int getDuration()
	{
		return _duration;
	}
	
	/* LifeTime start */
	public final int getLifetime()
	{
		return _lifetime;
	}
	/* LifeTime end */
	
	/**
	 * @return int the ID of the item
	 */
	public final int getItemId()
	{
		return _itemId;
	}
	
	public abstract int getItemMask();
	
	/**
	 * @return int the type of material of the item
	 */
	public final MaterialType getMaterialType()
	{
		return _materialType;
	}
	
	/**
	 * @return int the type 2 of the item
	 */
	public final int getType2()
	{
		return _type2;
	}
	
	/**
	 * @return int the weight of the item
	 */
	public final int getWeight()
	{
		return _weight;
	}
	
	/**
	 * @return boolean if the item is crystallizable
	 */
	public final boolean isCrystallizable()
	{
		return _crystalType != CrystalType.NONE && _crystalCount > 0;
	}
	
	/**
	 * @return CrystalType the type of crystal if item is crystallizable
	 */
	public final CrystalType getCrystalType()
	{
		return _crystalType;
	}
	
	/**
	 * @return int the type of crystal if item is crystallizable
	 */
	public final int getCrystalItemId()
	{
		return _crystalType.getCrystalId();
	}
	
	/**
	 * @return int the quantity of crystals for crystallization
	 */
	public final int getCrystalCount()
	{
		return _crystalCount;
	}
	
	/**
	 * @param enchantLevel
	 * @return int the quantity of crystals for crystallization on specific enchant level
	 */
	public final int getCrystalCount(int enchantLevel)
	{
		if (enchantLevel > 3)
		{
			switch (_type2)
			{
				case TYPE2_SHIELD_ARMOR:
				case TYPE2_ACCESSORY:
					return _crystalCount + getCrystalType().getCrystalEnchantBonusArmor() * (3 * enchantLevel - 6);
					
				case TYPE2_WEAPON:
					return _crystalCount + getCrystalType().getCrystalEnchantBonusWeapon() * (2 * enchantLevel - 3);
					
				default:
					return _crystalCount;
			}
		}
		else if (enchantLevel > 0)
		{
			switch (_type2)
			{
				case TYPE2_SHIELD_ARMOR:
				case TYPE2_ACCESSORY:
					return _crystalCount + getCrystalType().getCrystalEnchantBonusArmor() * enchantLevel;
				case TYPE2_WEAPON:
					return _crystalCount + getCrystalType().getCrystalEnchantBonusWeapon() * enchantLevel;
				default:
					return _crystalCount;
			}
		}
		else
		{
			return _crystalCount;
		}
	}
	
	/**
	 * @return String the name of the item
	 */
	public final String getName()
	{
		return _name;
	}
	
	/**
	 * @return int the part of the body used with the item.
	 */
	public final int getBodyPart()
	{
		return _bodyPart;
	}
	
	/**
	 * @return int the type 1 of the item
	 */
	public final int getType1()
	{
		return _type1;
	}
	
	/**
	 * @return boolean if the item is stackable
	 */
	public final boolean isStackable()
	{
		return _stackable;
	}
	
	/**
	 * @return boolean if the item is consumable
	 */
	public boolean isConsumable()
	{
		return false;
	}
	
	public boolean isEquipable()
	{
		return getBodyPart() != 0 && !(getItemType() instanceof EtcItemType);
	}
	
	/**
	 * @return int the price of reference of the item
	 */
	public final int getReferencePrice()
	{
		return (isConsumable() ? (int) (_referencePrice * Config.RATE_CONSUMABLE_COST) : _referencePrice);
	}
	
	/**
	 * Returns if the item can be sold
	 * @return boolean
	 */
	public final boolean isSellable()
	{
		return _sellable;
	}
	
	/**
	 * Returns if the item can dropped
	 * @return boolean
	 */
	public final boolean isDropable()
	{
		return _dropable;
	}
	
	/**
	 * Returns if the item can destroy
	 * @return boolean
	 */
	public final boolean isDestroyable()
	{
		return _destroyable;
	}
	
	/**
	 * Returns if the item can add to trade
	 * @return boolean
	 */
	public final boolean isTradable()
	{
		return _tradable;
	}
	
	/**
	 * Returns if the item can be put into warehouse
	 * @return boolean
	 */
	public final boolean isDepositable()
	{
		return _depositable;
	}
	
	/**
	 * Get the functions used by this item.
	 * @param item : ItemInstance pointing out the item
	 * @param player : L2Character pointing out the player
	 * @return the list of functions
	 */
	public final List<Func> getStatFuncs(ItemInstance item, L2Character player)
	{
		if (_funcTemplates == null || _funcTemplates.isEmpty())
		{
			return Collections.emptyList();
		}
		
		final List<Func> funcs = new ArrayList<>(_funcTemplates.size());
		
		final Env env = new Env();
		env.setCharacter(player);
		env.setTarget(player);
		env.setItem(item);
		
		for (FuncTemplate t : _funcTemplates)
		{
			final Func f = t.getFunc(env, item);
			if (f != null)
			{
				funcs.add(f);
			}
		}
		return funcs;
	}
	
	/**
	 * Returns the effects associated with the item.
	 * @param instance : ItemInstance pointing out the item
	 * @param player : L2Character pointing out the player
	 * @return L2Effect[] : array of effects generated by the item
	 */
	public final List<L2Effect> getEffects(ItemInstance instance, L2Character player)
	{
		if (_effectTemplates == null || _effectTemplates.isEmpty())
		{
			return Collections.emptyList();
		}
		
		final List<L2Effect> effects = new ArrayList<>(_effectTemplates.size());
		
		final Env env = new Env();
		env.setCharacter(player);
		env.setTarget(player);
		env.setItem(instance);
		
		for (EffectTemplate et : _effectTemplates)
		{
			final L2Effect effect = et.getEffect(env);
			if (effect != null)
			{
				effect.scheduleEffect();
				effects.add(effect);
			}
		}
		return effects;
	}
	
	/**
	 * Add the FuncTemplate f to the list of functions used with the item
	 * @param f : FuncTemplate to add
	 */
	public void attach(FuncTemplate f)
	{
		if (_funcTemplates == null)
		{
			_funcTemplates = new ArrayList<>(1);
		}
		
		_funcTemplates.add(f);
	}
	
	/**
	 * Add the EffectTemplate effect to the list of effects generated by the item
	 * @param effect : EffectTemplate
	 */
	public void attach(EffectTemplate effect)
	{
		if (_effectTemplates == null)
		{
			_effectTemplates = new ArrayList<>(1);
		}
		
		_effectTemplates.add(effect);
	}
	
	public final void attach(Condition c)
	{
		if (_preConditions == null)
		{
			_preConditions = new ArrayList<>();
		}
		
		if (!_preConditions.contains(c))
		{
			_preConditions.add(c);
		}
	}
	
	/**
	 * Method to retrieve skills linked to this item
	 * @return Skills linked to this item as SkillHolder[]
	 */
	public final SkillHolder[] getSkills()
	{
		return _skillHolder;
	}
	
	public boolean checkCondition(L2Character activeChar, L2Object target, boolean sendMessage)
	{
		// Don't allow hero equipment and restricted items during Olympiad
		if ((isOlyRestrictedItem() || isHeroItem()) && ((activeChar instanceof L2PcInstance) && activeChar.getActingPlayer().isInOlympiadMode()))
		{
			if (isEquipable())
			{
				activeChar.getActingPlayer().sendPacket(SystemMessageId.THIS_ITEM_CANT_BE_EQUIPPED_FOR_THE_OLYMPIAD_EVENT);
			}
			else
			{
				activeChar.getActingPlayer().sendPacket(SystemMessageId.THIS_ITEM_IS_NOT_AVAILABLE_FOR_THE_OLYMPIAD_EVENT);
			}
			
			return false;
		}
		
		if (_preConditions == null)
		{
			return true;
		}
		
		final Env env = new Env();
		env.setCharacter(activeChar);
		if (target instanceof L2Character)
		{
			env.setTarget((L2Character) target);
		}
		
		for (Condition preCondition : _preConditions)
		{
			if (preCondition == null)
			{
				continue;
			}
			
			if (!preCondition.test(env))
			{
				if (activeChar instanceof L2Summon)
				{
					activeChar.getActingPlayer().sendPacket(SystemMessageId.PET_CANNOT_USE_ITEM);
					return false;
				}
				
				if (sendMessage)
				{
					String msg = preCondition.getMessage();
					int msgId = preCondition.getMessageId();
					if (msg != null)
					{
						activeChar.sendMessage(msg);
					}
					else if (msgId != 0)
					{
						SystemMessage sm = SystemMessage.getSystemMessage(msgId);
						if (preCondition.isAddName())
						{
							sm.addItemName(_itemId);
						}
						activeChar.sendPacket(sm);
					}
				}
				return false;
			}
		}
		return true;
	}
	
	public boolean isConditionAttached()
	{
		return _preConditions != null && !_preConditions.isEmpty();
	}
	
	public boolean isQuestItem()
	{
		return (getItemType() == EtcItemType.QUEST);
	}
	
	public final boolean isHeroItem()
	{
		return _heroItem;
	}
	
	public boolean isOlyRestrictedItem()
	{
		return _isOlyRestricted;
	}
	
	public boolean isPetItem()
	{
		return (getItemType() == ArmorType.PET || getItemType() == WeaponType.PET);
	}
	
	public boolean isPotion()
	{
		return (getItemType() == EtcItemType.POTION);
	}
	
	public boolean isElixir()
	{
		return (getItemType() == EtcItemType.ELIXIR);
	}
	
	public ActionType getDefaultAction()
	{
		return _defaultAction;
	}
	
	/**
	 * Returns the name of the item
	 * @return String
	 */
	@Override
	public String toString()
	{
		return _name + " (" + _itemId + ")";
	}
	
	public void addQuestEvent(Quest q)
	{
		_questEvents.add(q);
	}
	
	public List<Quest> getQuestEvents()
	{
		return _questEvents;
	}
}
 

 

 

package net.sf.l2j.gameserver.threadmanager;

import java.util.concurrent.Future;

import net.sf.l2j.gameserver.ThreadPoolManager;


/**
 * @author NB4L1
 */
public abstract class ExclusiveTask
{
	private final boolean _returnIfAlreadyRunning;
	
	private Future<?> _future;
	private boolean _isRunning;
	private Thread _currentThread;
	
	protected ExclusiveTask(boolean returnIfAlreadyRunning)
	{
		_returnIfAlreadyRunning = returnIfAlreadyRunning;
	}
	
	protected ExclusiveTask()
	{
		this(false);
	}
	
	public synchronized boolean isScheduled()
	{
		return _future != null;
	}
	
	public synchronized final void cancel()
	{
		if (_future != null)
		{
			_future.cancel(false);
			_future = null;
		}
	}
	
	public synchronized final void schedule(long delay)
	{
		cancel();
		
		_future = ThreadPoolManager.getInstance().schedule(_runnable, delay);
	}
	
	public synchronized final void scheduleAtFixedRate(long delay, long period)
	{
		cancel();
		
		_future = ThreadPoolManager.getInstance().scheduleAtFixedRate(_runnable, delay, period);
	}
	
	private final Runnable _runnable = new Runnable() {
		@Override
		public void run()
		{
			if (tryLock())
			{
				try
				{
					onElapsed();
				}
				finally
				{
					unlock();
				}
			}
		}
	};
	
	protected abstract void onElapsed();
	
	private synchronized boolean tryLock()
	{
		if (_returnIfAlreadyRunning)
			return !_isRunning;
		
		_currentThread = Thread.currentThread();
		
		for (;
		{
			try
			{
				notifyAll();
				
				if (_currentThread != Thread.currentThread())
					return false;
				
				if (!_isRunning)
					return true;
				
				wait();
			}
			catch (InterruptedException e)
			{
			}
		}
	}
	
	private synchronized void unlock()
	{
		_isRunning = false;
	}
}
 

 

 

/*
 * 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 net.sf.l2j.gameserver;

import java.lang.Thread.UncaughtExceptionHandler;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RunnableScheduledFuture;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import net.sf.l2j.commons.config.Config;
import net.sf.l2j.commons.util.StringUtil;
/* LifeTime start */
import net.sf.l2j.gameserver.threadmanager.ScheduledFutureWrapper;
/* LifeTime end */

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <p>
 * This class is made to handle all the ThreadPools used in L2j.
 * </p>
 * <p>
 * Scheduled Tasks can either be sent to a {@link #_generalScheduledThreadPool "general"} or {@link #_effectsScheduledThreadPool "effects"} {@link ScheduledThreadPoolExecutor ScheduledThreadPool}: The "effects" one is used for every effects (skills, hp/mp regen ...) while the "general" one is used
 * for everything else that needs to be scheduled.<br>
 * There also is an {@link #_aiScheduledThreadPool "ai"} {@link ScheduledThreadPoolExecutor ScheduledThreadPool} used for AI Tasks.
 * </p>
 * <p>
 * Tasks can be sent to {@link ScheduledThreadPoolExecutor ScheduledThreadPool} either with:
 * <ul>
 * <li>{@link #scheduleEffect(Runnable, long)} : for effects Tasks that needs to be executed only once.</li>
 * <li>{@link #scheduleGeneral(Runnable, long)} : for scheduled Tasks that needs to be executed once.</li>
 * <li>{@link #scheduleAi(Runnable, long)} : for AI Tasks that needs to be executed once</li>
 * </ul>
 * or
 * <ul>
 * <li>{@link #scheduleEffectAtFixedRate(Runnable, long, long)} : for effects Tasks that needs to be executed periodicaly.</li>
 * <li>{@link #scheduleGeneralAtFixedRate(Runnable, long, long)} : for scheduled Tasks that needs to be executed periodicaly.</li>
 * <li>{@link #scheduleAiAtFixedRate(Runnable, long, long)} : for AI Tasks that needs to be executed periodicaly</li>
 * </ul>
 * </p>
 * <p>
 * For all Tasks that should be executed with no delay asynchronously in a ThreadPool there also are usual {@link ThreadPoolExecutor ThreadPools} that can grow/shrink according to their load.:
 * <ul>
 * <li>{@link #_generalPacketsThreadPool GeneralPackets} where most packets handler are executed.</li>
 * <li>
 * {@link #_ioPacketsThreadPool I/O Packets} where all the i/o packets are executed.</li>
 * <li>There will be an AI ThreadPool where AI events should be executed</li>
 * <li>A general ThreadPool where everything else that needs to run asynchronously with no delay should be executed ( {@link net.sf.l2j.gameserver.model.actor.knownlist KnownList} updates, SQL updates/inserts...)?</li>
 * </ul>
 * </p>
 * @author -Wooden-
 */
public class ThreadPoolManager
{
	protected static final Logger _log = LoggerFactory.getLogger(ThreadPoolManager.class.getName());
	
	private static final class RunnableWrapper implements Runnable
	{
		private final Runnable _r;
		
		public RunnableWrapper(final Runnable r)
		{
			_r = r;
		}
		
		@Override
		public final void run()
		{
			try
			{
				_r.run();
			}
			catch (final Throwable e)
			{
				final Thread t = Thread.currentThread();
				final UncaughtExceptionHandler h = t.getUncaughtExceptionHandler();
				if (h != null)
				{
					h.uncaughtException(t, e);
				}
			}
		}
	}
	
	protected ScheduledThreadPoolExecutor _effectsScheduledThreadPool;
	protected ScheduledThreadPoolExecutor _generalScheduledThreadPool;
	protected ScheduledThreadPoolExecutor _aiScheduledThreadPool;
	private final ThreadPoolExecutor _generalPacketsThreadPool;
	private final ThreadPoolExecutor _ioPacketsThreadPool;
	private final ThreadPoolExecutor _generalThreadPool;
	
	/** temp workaround for VM issue */
	private static final long MAX_DELAY = Long.MAX_VALUE / 1000000 / 2;
	
	private boolean _shutdown;
	
	public static ThreadPoolManager getInstance()
	{
		return SingletonHolder._instance;
	}
	
	protected ThreadPoolManager()
	{
		_effectsScheduledThreadPool = new ScheduledThreadPoolExecutor(Config.THREAD_P_EFFECTS, new PriorityThreadFactory("EffectsSTPool", Thread.NORM_PRIORITY));
		_generalScheduledThreadPool = new ScheduledThreadPoolExecutor(Config.THREAD_P_GENERAL, new PriorityThreadFactory("GeneralSTPool", Thread.NORM_PRIORITY));
		_ioPacketsThreadPool = new ThreadPoolExecutor(Config.IO_PACKET_THREAD_CORE_SIZE, Integer.MAX_VALUE, 5L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new PriorityThreadFactory("I/O Packet Pool", Thread.NORM_PRIORITY + 1));
		_generalPacketsThreadPool = new ThreadPoolExecutor(Config.GENERAL_PACKET_THREAD_CORE_SIZE, Config.GENERAL_PACKET_THREAD_CORE_SIZE + 2, 15L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new PriorityThreadFactory("Normal Packet Pool", Thread.NORM_PRIORITY + 1));
		_generalThreadPool = new ThreadPoolExecutor(Config.GENERAL_THREAD_CORE_SIZE, Config.GENERAL_THREAD_CORE_SIZE + 2, 5L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new PriorityThreadFactory("General Pool", Thread.NORM_PRIORITY));
		_aiScheduledThreadPool = new ScheduledThreadPoolExecutor(Config.AI_MAX_THREAD, new PriorityThreadFactory("AISTPool", Thread.NORM_PRIORITY));
		
		scheduleGeneralAtFixedRate(new PurgeTask(), 10 * 60 * 1000l, 5 * 60 * 1000l);
	}
	
	public static long validateDelay(long delay)
	{
		if (delay < 0)
		{
			delay = 0;
		}
		else if (delay > MAX_DELAY)
		{
			delay = MAX_DELAY;
		}
		return delay;
	}
	/* LifeTime start */
	public ScheduledFuture<?> schedule(Runnable r, long delay)
	{
		return new ScheduledFutureWrapper(_generalScheduledThreadPool.schedule(r, delay, TimeUnit.MILLISECONDS));
	}
	
	public ScheduledFuture<?> scheduleAtFixedRate(Runnable r, long delay, long period)
	{
		return new ScheduledFutureWrapper(_generalScheduledThreadPool.scheduleAtFixedRate(r, delay, period, TimeUnit.MILLISECONDS));
	}
	/* LifeTime end */
	public ScheduledFuture<?> scheduleEffect(Runnable r, long delay)
	{
		try
		{
			delay = ThreadPoolManager.validateDelay(delay);
			return _effectsScheduledThreadPool.schedule(new RunnableWrapper(r), delay, TimeUnit.MILLISECONDS);
		}
		catch (RejectedExecutionException e)
		{
			return null;
		}
	}
	
	public ScheduledFuture<?> scheduleEffectAtFixedRate(Runnable r, long initial, long delay)
	{
		try
		{
			delay = ThreadPoolManager.validateDelay(delay);
			initial = ThreadPoolManager.validateDelay(initial);
			return _effectsScheduledThreadPool.scheduleAtFixedRate(new RunnableWrapper(r), initial, delay, TimeUnit.MILLISECONDS);
		}
		catch (RejectedExecutionException e)
		{
			return null; /* shutdown, ignore */
		}
	}
	
	@Deprecated
	public boolean removeEffect(RunnableScheduledFuture<?> r)
	{
		return _effectsScheduledThreadPool.remove(r);
	}
	
	public ScheduledFuture<?> scheduleGeneral(Runnable r, long delay)
	{
		try
		{
			delay = ThreadPoolManager.validateDelay(delay);
			return _generalScheduledThreadPool.schedule(new RunnableWrapper(r), delay, TimeUnit.MILLISECONDS);
		}
		catch (RejectedExecutionException e)
		{
			return null; /* shutdown, ignore */
		}
	}
	
	public ScheduledFuture<?> scheduleGeneralAtFixedRate(Runnable r, long initial, long delay)
	{
		try
		{
			delay = ThreadPoolManager.validateDelay(delay);
			initial = ThreadPoolManager.validateDelay(initial);
			return _generalScheduledThreadPool.scheduleAtFixedRate(new RunnableWrapper(r), initial, delay, TimeUnit.MILLISECONDS);
		}
		catch (RejectedExecutionException e)
		{
			return null; /* shutdown, ignore */
		}
	}
	
	@Deprecated
	public boolean removeGeneral(RunnableScheduledFuture<?> r)
	{
		return _generalScheduledThreadPool.remove(r);
	}
	
	public ScheduledFuture<?> scheduleAi(Runnable r, long delay)
	{
		try
		{
			delay = ThreadPoolManager.validateDelay(delay);
			return _aiScheduledThreadPool.schedule(new RunnableWrapper(r), delay, TimeUnit.MILLISECONDS);
		}
		catch (RejectedExecutionException e)
		{
			return null; /* shutdown, ignore */
		}
	}
	
	public ScheduledFuture<?> scheduleAiAtFixedRate(Runnable r, long initial, long delay)
	{
		try
		{
			delay = ThreadPoolManager.validateDelay(delay);
			initial = ThreadPoolManager.validateDelay(initial);
			return _aiScheduledThreadPool.scheduleAtFixedRate(new RunnableWrapper(r), initial, delay, TimeUnit.MILLISECONDS);
		}
		catch (RejectedExecutionException e)
		{
			return null; /* shutdown, ignore */
		}
	}
	
	public void executePacket(Runnable pkt)
	{
		_generalPacketsThreadPool.execute(pkt);
	}
	
	public void executeCommunityPacket(Runnable r)
	{
		_generalPacketsThreadPool.execute(r);
	}
	
	public void executeIOPacket(Runnable pkt)
	{
		_ioPacketsThreadPool.execute(pkt);
	}
	
	public void executeTask(Runnable r)
	{
		_generalThreadPool.execute(r);
	}
	
	public void executeAi(Runnable r)
	{
		_aiScheduledThreadPool.execute(new RunnableWrapper(r));
	}
	
	private static class PriorityThreadFactory implements ThreadFactory
	{
		private final int _prio;
		private final String _name;
		private final AtomicInteger _threadNumber = new AtomicInteger(1);
		private final ThreadGroup _group;
		
		public PriorityThreadFactory(String name, int prio)
		{
			_prio = prio;
			_name = name;
			_group = new ThreadGroup(_name);
		}
		
		@Override
		public Thread newThread(Runnable r)
		{
			Thread t = new Thread(_group, r);
			t.setName(_name + "-" + _threadNumber.getAndIncrement());
			t.setPriority(_prio);
			return t;
		}
		
		public ThreadGroup getGroup()
		{
			return _group;
		}
	}
	
	public void shutdown()
	{
		_shutdown = true;
		
		_effectsScheduledThreadPool.shutdown();
		_generalScheduledThreadPool.shutdown();
		_generalPacketsThreadPool.shutdown();
		_ioPacketsThreadPool.shutdown();
		_generalThreadPool.shutdown();
		
		_log.info("All ThreadPools are now stopped.");
	}
	
	public boolean isShutdown()
	{
		return _shutdown;
	}
	
	public void purge()
	{
		_effectsScheduledThreadPool.purge();
		_generalScheduledThreadPool.purge();
		_aiScheduledThreadPool.purge();
		_ioPacketsThreadPool.purge();
		_generalPacketsThreadPool.purge();
		_generalThreadPool.purge();
	}
	
	public String getPacketStats()
	{
		final StringBuilder sb = new StringBuilder(1000);
		ThreadFactory tf = _generalPacketsThreadPool.getThreadFactory();
		if (tf instanceof PriorityThreadFactory)
		{
			PriorityThreadFactory ptf = (PriorityThreadFactory) tf;
			int count = ptf.getGroup().activeCount();
			Thread[] threads = new Thread[count + 2];
			ptf.getGroup().enumerate(threads);
			StringUtil.append(sb, "General Packet Thread Pool:\r\n" + "Tasks in the queue: ", String.valueOf(_generalPacketsThreadPool.getQueue().size()), "\r\n" + "Showing threads stack trace:\r\n" + "There should be ", String.valueOf(count), " Threads\r\n");
			for (Thread t : threads)
			{
				if (t == null)
				{
					continue;
				}
				
				StringUtil.append(sb, t.getName(), "\r\n");
				for (StackTraceElement ste : t.getStackTrace())
				{
					StringUtil.append(sb, ste.toString(), "\r\n");
				}
			}
		}
		
		sb.append("Packet Tp stack traces printed.\r\n");
		
		return sb.toString();
	}
	
	public String getIOPacketStats()
	{
		final StringBuilder sb = new StringBuilder(1000);
		ThreadFactory tf = _ioPacketsThreadPool.getThreadFactory();
		
		if (tf instanceof PriorityThreadFactory)
		{
			PriorityThreadFactory ptf = (PriorityThreadFactory) tf;
			int count = ptf.getGroup().activeCount();
			Thread[] threads = new Thread[count + 2];
			ptf.getGroup().enumerate(threads);
			StringUtil.append(sb, "I/O Packet Thread Pool:\r\n" + "Tasks in the queue: ", String.valueOf(_ioPacketsThreadPool.getQueue().size()), "\r\n" + "Showing threads stack trace:\r\n" + "There should be ", String.valueOf(count), " Threads\r\n");
			
			for (Thread t : threads)
			{
				if (t == null)
				{
					continue;
				}
				
				StringUtil.append(sb, t.getName(), "\r\n");
				
				for (StackTraceElement ste : t.getStackTrace())
				{
					StringUtil.append(sb, ste.toString(), "\r\n");
				}
			}
		}
		
		sb.append("Packet Tp stack traces printed.\r\n");
		
		return sb.toString();
	}
	
	public String getGeneralStats()
	{
		final StringBuilder sb = new StringBuilder(1000);
		ThreadFactory tf = _generalThreadPool.getThreadFactory();
		
		if (tf instanceof PriorityThreadFactory)
		{
			PriorityThreadFactory ptf = (PriorityThreadFactory) tf;
			int count = ptf.getGroup().activeCount();
			Thread[] threads = new Thread[count + 2];
			ptf.getGroup().enumerate(threads);
			StringUtil.append(sb, "General Thread Pool:\r\n" + "Tasks in the queue: ", String.valueOf(_generalThreadPool.getQueue().size()), "\r\n" + "Showing threads stack trace:\r\n" + "There should be ", String.valueOf(count), " Threads\r\n");
			
			for (Thread t : threads)
			{
				if (t == null)
				{
					continue;
				}
				
				StringUtil.append(sb, t.getName(), "\r\n");
				
				for (StackTraceElement ste : t.getStackTrace())
				{
					StringUtil.append(sb, ste.toString(), "\r\n");
				}
			}
		}
		
		sb.append("Packet Tp stack traces printed.\r\n");
		
		return sb.toString();
	}
	
	protected class PurgeTask implements Runnable
	{
		@Override
		public void run()
		{
			_effectsScheduledThreadPool.purge();
			_generalScheduledThreadPool.purge();
			_aiScheduledThreadPool.purge();
		}
	}
	
	private static class SingletonHolder
	{
		protected static final ThreadPoolManager _instance = new ThreadPoolManager();
	}
}
 

 

 

/*
 * 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 net.sf.l2j.gameserver;

import com.lameguard.LameGuard;

import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Calendar;

import net.sf.l2j.commons.config.Config;
import net.sf.l2j.commons.db.DatabaseFactory;
import net.sf.l2j.commons.nio.SelectorConfig;
import net.sf.l2j.commons.nio.SelectorThread;
import net.sf.l2j.commons.type.Server;
import net.sf.l2j.commons.util.DatabaseOptimizer;
import net.sf.l2j.commons.util.DeadLockDetector;
import net.sf.l2j.commons.util.IPv4Filter;
import net.sf.l2j.commons.util.L2TopDeamon;
import net.sf.l2j.commons.util.MMOTopDeamon;
import net.sf.l2j.commons.util.Util;
import net.sf.l2j.commons.util.security.AntiAfk;
import net.sf.l2j.commons.util.security.AntiBot;
import net.sf.l2j.gameserver.ai.L2AttackableAIScript;
import net.sf.l2j.gameserver.cache.CrestCache;
import net.sf.l2j.gameserver.cache.HtmCache;
import net.sf.l2j.gameserver.communitybbs.Manager.ForumsBBSManager;
import net.sf.l2j.gameserver.datatables.AccessLevels;
import net.sf.l2j.gameserver.datatables.AdminCommandAccessRights;
import net.sf.l2j.gameserver.datatables.ArmorSetsTable;
import net.sf.l2j.gameserver.datatables.AugmentationData;
import net.sf.l2j.gameserver.datatables.BookmarkTable;
import net.sf.l2j.gameserver.datatables.BuyListTable;
import net.sf.l2j.gameserver.datatables.CharNameTable;
import net.sf.l2j.gameserver.datatables.CharTemplateTable;
import net.sf.l2j.gameserver.datatables.ClanTable;
import net.sf.l2j.gameserver.datatables.DoorTable;
import net.sf.l2j.gameserver.datatables.FishTable;
import net.sf.l2j.gameserver.datatables.GmListTable;
import net.sf.l2j.gameserver.datatables.HelperBuffTable;
import net.sf.l2j.gameserver.datatables.HennaTable;
import net.sf.l2j.gameserver.datatables.HerbDropTable;
import net.sf.l2j.gameserver.datatables.ItemTable;
import net.sf.l2j.gameserver.datatables.MapRegionTable;
import net.sf.l2j.gameserver.datatables.MultisellData;
import net.sf.l2j.gameserver.datatables.NpcTable;
import net.sf.l2j.gameserver.datatables.NpcWalkerRoutesTable;
import net.sf.l2j.gameserver.datatables.OfflineTradersTable;
import net.sf.l2j.gameserver.datatables.PetDataTable;
import net.sf.l2j.gameserver.datatables.RecipeTable;
import net.sf.l2j.gameserver.datatables.SkillTable;
import net.sf.l2j.gameserver.datatables.SkillTreeTable;
import net.sf.l2j.gameserver.datatables.SoulCrystalsTable;
import net.sf.l2j.gameserver.datatables.SpawnTable;
import net.sf.l2j.gameserver.datatables.SpellbookTable;
import net.sf.l2j.gameserver.datatables.StaticObjects;
import net.sf.l2j.gameserver.datatables.SummonItemsData;
import net.sf.l2j.gameserver.datatables.TeleportLocationTable;
import net.sf.l2j.gameserver.handler.HandlerLoader;
import net.sf.l2j.gameserver.handler.admin.AdminCommandHandler;
import net.sf.l2j.gameserver.handler.auto.AutoAnnouncementHandler;
import net.sf.l2j.gameserver.handler.chat.ChatHandler;
import net.sf.l2j.gameserver.handler.item.ItemHandler;
import net.sf.l2j.gameserver.handler.skill.SkillHandler;
import net.sf.l2j.gameserver.handler.user.UserCommandHandler;
import net.sf.l2j.gameserver.handler.voiced.VoicedCommandHandler;
import net.sf.l2j.gameserver.idfactory.IdFactory;
import net.sf.l2j.gameserver.instancemanager.AuctionManager;
import net.sf.l2j.gameserver.instancemanager.AutoSpawnManager;
import net.sf.l2j.gameserver.instancemanager.BoatManager;
import net.sf.l2j.gameserver.instancemanager.CastleManager;
import net.sf.l2j.gameserver.instancemanager.CastleManorManager;
import net.sf.l2j.gameserver.instancemanager.ClanHallManager;
import net.sf.l2j.gameserver.instancemanager.CoupleManager;
import net.sf.l2j.gameserver.instancemanager.CursedWeaponsManager;
import net.sf.l2j.gameserver.instancemanager.DayNightSpawnManager;
import net.sf.l2j.gameserver.instancemanager.DimensionalRiftManager;
import net.sf.l2j.gameserver.instancemanager.FishingChampionshipManager;
import net.sf.l2j.gameserver.instancemanager.FourSepulchersManager;
import net.sf.l2j.gameserver.instancemanager.GrandBossManager;
import net.sf.l2j.gameserver.instancemanager.ItemsOnGroundManager;
import net.sf.l2j.gameserver.instancemanager.MercTicketManager;
import net.sf.l2j.gameserver.instancemanager.MovieMakerManager;
import net.sf.l2j.gameserver.instancemanager.PetitionManager;
import net.sf.l2j.gameserver.instancemanager.PremiumManager;
/* LifeTime start */
import net.sf.l2j.gameserver.instancemanager.LifeTimeManager;
/* LifeTime end */
import net.sf.l2j.gameserver.instancemanager.QuestManager;
import net.sf.l2j.gameserver.instancemanager.RaidBossPointsManager;
import net.sf.l2j.gameserver.instancemanager.RaidBossSpawnManager;
import net.sf.l2j.gameserver.instancemanager.SevenSigns;
import net.sf.l2j.gameserver.instancemanager.SevenSignsFestival;
import net.sf.l2j.gameserver.instancemanager.SiegeManager;
import net.sf.l2j.gameserver.instancemanager.SiegeReward;
import net.sf.l2j.gameserver.instancemanager.ZoneManager;
import net.sf.l2j.gameserver.instancemanager.games.MonsterRace;
import net.sf.l2j.gameserver.model.L2Manor;
import net.sf.l2j.gameserver.model.L2World;
import net.sf.l2j.gameserver.model.entity.Hero;
import net.sf.l2j.gameserver.model.entity.events.EventManager;
import net.sf.l2j.gameserver.model.entity.medals.EventMedals;
import net.sf.l2j.gameserver.model.entity.pcbang.PcPoint;
import net.sf.l2j.gameserver.model.entity.pcbang.ServerOnline;
import net.sf.l2j.gameserver.model.olympiad.Olympiad;
import net.sf.l2j.gameserver.model.olympiad.OlympiadGameManager;
import net.sf.l2j.gameserver.model.partymatching.PartyMatchRoomList;
import net.sf.l2j.gameserver.model.partymatching.PartyMatchWaitingList;
import net.sf.l2j.gameserver.network.L2GameClient;
import net.sf.l2j.gameserver.network.L2GamePacketHandler;
import net.sf.l2j.gameserver.network.components.Message;
import net.sf.l2j.gameserver.pathfinding.PathFinding;
import net.sf.l2j.gameserver.scripting.L2ScriptEngineManager;
import net.sf.l2j.gameserver.scripting.L2ScriptLoader;
import net.sf.l2j.gameserver.taskmanager.ItemsAutoDestroyTaskManager;
import net.sf.l2j.gameserver.taskmanager.KnownListUpdateTaskManager;
import net.sf.l2j.gameserver.taskmanager.TaskManager;
import net.sf.l2j.gameserver.taskmanager.tasks.TaskPremium;
/* LifeTime start */
import net.sf.l2j.gameserver.threadmanager.ExclusiveTask;
/* LifeTime end */
import net.sf.l2j.gameserver.xmlfactory.XMLDocumentFactory;
import net.sf.l2j.protection.CatsGuard;
import net.sf.l2j.protection.ProtectionProperties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class GameServer
{
	private static final Logger _log = LoggerFactory.getLogger(GameServer.class.getName());
	
	private final SelectorThread<L2GameClient> _selectorThread;
	private final L2GamePacketHandler _gamePacketHandler;
	private final DeadLockDetector _deadDetectThread;
	public static GameServer gameServer;
	private final LoginServerThread _loginThread;
	public static final Calendar dateTimeServerStarted = Calendar.getInstance();
	long serverLoadStart = System.currentTimeMillis();
	
	public long getUsedMemoryMB()
	{
		return (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1048576; // 1024 * 1024 = 1048576;
	}
	
	public SelectorThread<L2GameClient> getSelectorThread()
	{
		return _selectorThread;
	}
	
	public GameServer() throws Throwable
	{
		gameServer = this;
		
		IdFactory.getInstance();
		ThreadPoolManager.getInstance();
		
		new File("./data/crests").mkdirs();
		
		Util.printSection("World");
		GameTimeController.getInstance();
		L2World.getInstance();
		MapRegionTable.getInstance();
		Announcements.getInstance();
		BookmarkTable.getInstance();
		
		Util.printSection("Skills");
		SkillTable.getInstance();
		SkillTreeTable.getInstance();
		
		Util.printSection("Items");
		if (Config.PREMIUM_ITEM_ENABLED)
		{
			PremiumManager.getInstance();
		}
		/* LifeTime start */
		LifeTimeManager.getInstance();
		/* LifeTime end */
		ItemTable.getInstance();
		SummonItemsData.getInstance();
		BuyListTable.getInstance();
		MultisellData.getInstance();
		RecipeTable.getInstance();
		ArmorSetsTable.getInstance();
		FishTable.getInstance();
		SpellbookTable.getInstance();
		SoulCrystalsTable.load();
		
		Util.printSection("Augments");
		AugmentationData.getInstance();
		
		Util.printSection("Characters");
		AccessLevels.getInstance();
		AdminCommandAccessRights.getInstance();
		CharTemplateTable.getInstance();
		CharNameTable.getInstance();
		GmListTable.getInstance();
		RaidBossPointsManager.getInstance();
		
		Util.printSection("Community server");
		if (Config.ENABLE_COMMUNITY_BOARD)
		{
			ForumsBBSManager.getInstance().initRoot();
		}
		else
		{
			_log.info("Community server is disabled.");
		}
		
		Util.printSection("Cache");
		HtmCache.getInstance();
		Message.getInstance();
		CrestCache.load();
		TeleportLocationTable.getInstance();
		PartyMatchWaitingList.getInstance();
		PartyMatchRoomList.getInstance();
		PetitionManager.getInstance();
		HennaTable.getInstance();
		HelperBuffTable.getInstance();
		CursedWeaponsManager.getInstance();
		
		Util.printSection("Clans");
		ClanTable.getInstance();
		AuctionManager.getInstance();
		ClanHallManager.getInstance();
		
		Util.printSection("Geodata");
		GeoData.getInstance();
		if (Config.GEODATA == 2)
		{
			PathFinding.getInstance();
		}
		
		Util.printSection("World Bosses");
		GrandBossManager.getInstance();
		
		Util.printSection("Zones");
		ZoneManager.getInstance();
		GrandBossManager.getInstance().initZones();
		
		Util.printSection("Castles");
		CastleManager.getInstance().load();
		
		Util.printSection("Seven Signs");
		SevenSigns.getInstance().spawnSevenSignsNPC();
		SevenSignsFestival.getInstance();
		
		Util.printSection("Sieges");
		SiegeManager.getInstance();
		SiegeManager.getSieges();
		SiegeReward.getInstance();
		MercTicketManager.getInstance();
		
		Util.printSection("Manor Manager");
		CastleManorManager.getInstance();
		L2Manor.getInstance();
		
		Util.printSection("NPCs");
		HerbDropTable.getInstance();
		PetDataTable.getInstance();
		NpcTable.getInstance();
		NpcWalkerRoutesTable.getInstance();
		DoorTable.getInstance();
		StaticObjects.load();
		SpawnTable.getInstance();
		RaidBossSpawnManager.getInstance();
		DayNightSpawnManager.getInstance().trim().notifyChangeMode();
		DimensionalRiftManager.getInstance();
		
		Util.printSection("Olympiads & Heroes");
		OlympiadGameManager.getInstance();
		Olympiad.getInstance();
		Hero.getInstance();
		
		Util.printSection("Four Sepulchers");
		FourSepulchersManager.getInstance().init();
		
		Util.printSection("Quests & Scripts");
		QuestManager.getInstance();
		BoatManager.getInstance();
		L2AttackableAIScript.init();
		
		if (!Config.ALT_DEV_NO_SCRIPTS)
		{
			L2ScriptLoader.init(); // init compiled scripts loader
			
			try
			{
				File scripts = new File("./data/scripts.cfg");
				L2ScriptEngineManager.getInstance().executeScriptList(scripts);
			}
			catch (IOException ioe)
			{
				_log.error("Failed loading scripts.cfg, no script going to be loaded");
			}
			QuestManager.getInstance().report();
		}
		else
		{
			_log.info("QuestManager: Skipping scripts.");
		}
		
		Util.printSection("Handlers");
		HandlerLoader.init();
		_log.info("AdminCommandHandler: Loaded " + AdminCommandHandler.getInstance().size() + " handlers.");
		_log.info("AutoSpawnHandler: Loaded " + AutoSpawnManager.getInstance().size() + " handlers.");
		_log.info("AutoAnnouncementHandler: Loaded " + AutoAnnouncementHandler.getInstance().size() + " handlers.");
		_log.info("ChatHandler: Loaded " + ChatHandler.getInstance().size() + " handlers.");
		_log.info("ItemHandler: Loaded " + ItemHandler.getInstance().size() + " handlers.");
		_log.info("SkillHandler: Loaded " + SkillHandler.getInstance().size() + " handlers.");
		_log.info("UserCommandHandler: Loaded " + UserCommandHandler.getInstance().size() + " handlers.");
		_log.info("VoicedCommandHandler: Loaded " + VoicedCommandHandler.getInstance().size() + " handlers.");
		
		if (Config.SAVE_DROPPED_ITEM)
		{
			ItemsOnGroundManager.getInstance();
		}
		
		if (Config.ITEM_AUTO_DESTROY_TIME > 0 || Config.HERB_AUTO_DESTROY_TIME > 0)
		{
			ItemsAutoDestroyTaskManager.getInstance();
		}
		
		if (Config.PREMIUM_ITEM_ENABLED)
		{
			TaskPremium.getInstance();
		}
		
		Util.printSection("Monster Derby Track");
		MonsterRace.getInstance();
		
		Util.printSection("Guard System");
		CatsGuard.getInstance();
		if (!CatsGuard.getInstance().isEnabled())
		{
			try
			{
				Class<?> clazz = Class.forName("com.lameguard.LameGuard");
				if (clazz != null)
				{
					File f = new File("./lameguard/lameguard.properties");
					if (f.exists())
					{
						Util.printSection("LameGuard");
						LameGuard.main(new String[]
						{
							"net.sf.l2j.protection.LameStub"
						});
					}
				}
			}
			catch (Exception ignored)
			{
			}
		}
		
		if (Config.ALLOW_SEQURITY_QUE)
		{
			AntiBot.getInstance();
		}
		if (Config.ALLOW_ANTI_AFK)
		{
			AntiAfk.getInstance();
		}
		
		Util.printSection("Events");
		EventManager.getInstance();
		EventMedals.startEvent();
		if (Config.ALLOW_WEDDING)
		{
			CoupleManager.getInstance();
		}
		
		if (Config.ALT_FISH_CHAMPIONSHIP_ENABLED)
		{
			FishingChampionshipManager.getInstance();
		}
		
		if (Config.PCB_ENABLE)
		{
			ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(PcPoint.getInstance(), Config.PCB_INTERVAL * 1000, Config.PCB_INTERVAL * 1000);
		}
		else if (Config.PCB_WINDOW_ONLINE)
		{
			ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(ServerOnline.getInstance(), Config.PCB_LIKE_WINDOW_ONLINE_RATE * 1000, Config.PCB_LIKE_WINDOW_ONLINE_RATE * 1000);
		}
		if ((Config.OFFLINE_TRADE_ENABLE || Config.OFFLINE_CRAFT_ENABLE) && Config.RESTORE_OFFLINERS)
		{
			OfflineTradersTable.restoreOfflineTraders();
		}
		L2TopDeamon.getInstance();
		MMOTopDeamon.getInstance();
		
		Util.printSection("System");
		TaskManager.getInstance();
		
		Runtime.getRuntime().addShutdownHook(Shutdown.getInstance());
		ForumsBBSManager.getInstance();
		_log.info("IdFactory: Free ObjectIDs remaining: " + IdFactory.getInstance().size());
		
		KnownListUpdateTaskManager.getInstance();
		MovieMakerManager.getInstance();
		
		if (Config.DEADLOCK_DETECTOR)
		{
			_log.info("Deadlock detector is enabled. Timer: " + Config.DEADLOCK_CHECK_INTERVAL + "s.");
			_deadDetectThread = new DeadLockDetector();
			_deadDetectThread.setDaemon(true);
			_deadDetectThread.start();
		}
		else
		{
			_log.info("Deadlock detector is disabled.");
			_deadDetectThread = null;
		}
		
		System.gc();
		
		long usedMem = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1048576;
		long totalMem = Runtime.getRuntime().maxMemory() / 1048576;
		_log.info("Gameserver have started, used memory: " + usedMem + " / " + totalMem + " Mo.");
		
		Util.printSection("Info");
		_log.info("Maximum allowed players: " + Config.MAXIMUM_ONLINE_USERS);
		_log.info("Server loaded in " + (System.currentTimeMillis() - serverLoadStart) / 1000 + " seconds");
		
		Util.printSection("Login");
		_loginThread = LoginServerThread.getInstance();
		_loginThread.start();
		
		final SelectorConfig sc = new SelectorConfig();
		sc.MAX_READ_PER_PASS = Config.MMO_MAX_READ_PER_PASS;
		sc.MAX_SEND_PER_PASS = Config.MMO_MAX_SEND_PER_PASS;
		sc.SLEEP_TIME = Config.MMO_SELECTOR_SLEEP_TIME;
		sc.HELPER_BUFFER_COUNT = Config.MMO_HELPER_BUFFER_COUNT;
		
		_gamePacketHandler = new L2GamePacketHandler();
		_selectorThread = new SelectorThread<>(sc, _gamePacketHandler, _gamePacketHandler, _gamePacketHandler, new IPv4Filter());
		
		InetAddress bindAddress = null;
		if (!Config.GAMESERVER_HOSTNAME.equals("*"))
		{
			try
			{
				bindAddress = InetAddress.getByName(Config.GAMESERVER_HOSTNAME);
			}
			catch (UnknownHostException e1)
			{
				_log.warn("WARNING: The GameServer bind address is invalid, using all available IPs. Reason: " + e1.getMessage(), e1);
			}
		}
		
		try
		{
			_selectorThread.openServerSocket(bindAddress, Config.PORT_GAME);
		}
		catch (IOException e)
		{
			_log.warn("FATAL: Failed to open server socket. Reason: " + e.getMessage(), e);
			System.exit(1);
		}
		_selectorThread.start();
	}
	
	public static void main(String[] args) throws Throwable
	{
		Server.serverMode = Server.MODE_GAMESERVER;
		
		final String LOG_FOLDER = "./log"; // Name of folder for log file
		
		// Create log folder
		File logFolder = new File(LOG_FOLDER);
		logFolder.mkdir();
		
		Util.printSection("Fatum");
		// Initialize config
		Config.load();
		ProtectionProperties.init();
		
		// Factories
		XMLDocumentFactory.getInstance();
		DatabaseFactory.getInstance();
		DatabaseOptimizer.getInstance();
		
		gameServer = new GameServer();
	}
}
 

 

 

package net.sf.l2j.gameserver.instancemanager;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import net.sf.l2j.commons.config.Config;
import net.sf.l2j.commons.db.DatabaseFactory;
import net.sf.l2j.gameserver.model.L2Object;
import net.sf.l2j.gameserver.model.L2World;
import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
import net.sf.l2j.gameserver.model.item.instance.ItemInstance;
import net.sf.l2j.gameserver.model.item.kind.Item;
import net.sf.l2j.gameserver.network.SystemMessageId;
import net.sf.l2j.gameserver.network.serverpackets.ItemList;
import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
import net.sf.l2j.gameserver.threadmanager.ExclusiveTask;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LifeTimeManager
{
	protected static final Logger _log = LoggerFactory.getLogger(LifeTimeManager.class.getName());
	private static LifeTimeManager _instance;
	private final Map<Integer,Info> _timedItems = new ConcurrentHashMap<Integer,Info>();
	
	public static final LifeTimeManager getInstance()
	{
		if (_instance == null)
		{
			_instance = new LifeTimeManager();
		}
		return _instance;
	}
	
	private LifeTimeManager()
	{
		restore();
		_startControlTask.schedule(60000);
	}
	
	/**
	 * Вызывается только когда игрок сам удаляет предмет
	 * @param instance 
	 */
	
	public synchronized void destroyItem(ItemInstance item) {
		Info inf = _timedItems.get(item.getObjectId());
		if(inf !=null) {
			_timedItems.remove(inf._itemId);
			Connection con = null;
			try
			{
				con = DatabaseFactory.getInstance().getConnection();
				PreparedStatement statement;
					statement = con.prepareStatement("DELETE FROM character_timed_items WHERE charId=? AND itemId=?");
					statement.setInt(1, inf._charId);
					statement.setInt(2, inf._itemId);
					statement.execute();
					statement.close();
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
			finally {
				try {
					con.close();
				} catch(Exception e) { }
			}
		}
	}
	public synchronized void setTimedItem(ItemInstance item) {
		Info inf = _timedItems.get(item.getObjectId());
		if(inf!=null) {
				inf._charId = item.getOwnerId();
		} else {
			inf = new Info();
			inf._activationTime = System.currentTimeMillis()/1000+item.getItem().getLifetime()*60;
			inf._charId = item.getOwnerId();
			inf._itemId = item.getObjectId();
			_timedItems.put(inf._itemId, inf);
		}
		saveToDb(inf);
	}
	
	public boolean isActiveItem(ItemInstance item)
	{
		for (Info i:_timedItems.values())
		{
			if (i._itemId==item.getObjectId())
				return true;
		}		
		return false;
	}
	
	private void restore()
	{
		Connection con = null;
		try
		{
			con = DatabaseFactory.getInstance().getConnection();
			PreparedStatement statement = con.prepareStatement("SELECT charId,itemId,time FROM character_timed_items");
			ResultSet rs = statement.executeQuery();

			while (rs.next())
			{
				Info inf=new Info();
				inf._activationTime=rs.getLong("time");
				inf._charId=rs.getInt("charId");
				inf._itemId=rs.getInt("itemId");
				_timedItems.put(inf._itemId, inf);
			}
			rs.close();
			statement.close();
			_log.info("TimedItems: loaded "+_timedItems.size()+" items ");
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			try
			{
				if (con != null)
					con.close();
			}
			catch (SQLException e)
			{
				e.printStackTrace();
			}
		}
	}
		
	private void saveToDb(Info temp)
	{
		Connection con = null;
		try
		{
			con = DatabaseFactory.getInstance().getConnection();
			PreparedStatement statement;
			statement = con.prepareStatement("update character_timed_items set charId=? where itemId=?");
			statement.setInt(1, temp._charId);
			statement.setInt(2, temp._itemId);
			if(statement.executeUpdate()==0) {
				statement.close();
				statement = con.prepareStatement("INSERT INTO character_timed_items (charId,itemId,time) VALUES (?,?,?)");
				statement.setInt(1, temp._charId);
				statement.setInt(2, temp._itemId);
				statement.setLong(3, temp._activationTime);
				statement.execute();
			}
			statement.close();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			try
			{
				if (con != null)
					con.close();
			}
			catch (SQLException e)
			{
				e.printStackTrace();
			}
		}
	}
	private void deleteItem(Info temp)
	{
		_timedItems.remove(temp._itemId);
		Connection con = null;
		try
		{
			con = DatabaseFactory.getInstance().getConnection();
			PreparedStatement statement;
				statement = con.prepareStatement("DELETE FROM character_timed_items WHERE charId=? AND itemId=?");
				statement.setInt(1, temp._charId);
				statement.setInt(2, temp._itemId);
				statement.execute();
				statement.close();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			try
			{
				if (con != null)
					con.close();
			}
			catch (SQLException e)
			{
				e.printStackTrace();
			}
		}
		L2PcInstance pl = L2World.getInstance().getPlayer(temp._charId);
		if (pl!=null)
		{
			ItemInstance item = pl.getInventory().getItemByObjectId(temp._itemId);
			if (item!=null)
			{
				if(item.isEquipped())
					pl.getInventory().unEquipItemInSlot(item.getLocationSlot());
				pl.getInventory().destroyItem("timeLost", item, pl, pl);
				pl.sendPacket(new ItemList(pl, false));
			}
			else
			{
				SystemMessage msg = new SystemMessage(SystemMessageId.S1_DISAPPEARED);
				msg.addItemName(item);
				pl.sendPacket(msg);
			}
		}
		else
		{
			con = null;
			try
			{
				con = DatabaseFactory.getInstance().getConnection();
				PreparedStatement statement;
				if(temp._charId!=0) {
					statement = con.prepareStatement("DELETE FROM items WHERE owner_id=? AND object_id=?");
					statement.setInt(1, temp._charId);
					statement.setInt(2, temp._itemId);
					statement.execute();
					statement.close();
				} else  {
					for(L2Object o: L2World.getInstance().getAllVisibleObjects().values())
					{
						if(o.getObjectId()==temp._itemId) 
						{
							o.decayMe();
							break;
						}
					}
				}
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
			finally
			{
				try
				{
					if (con != null)
						con.close();
				}
				catch (SQLException e)
				{
					e.printStackTrace();
				}
			}			
		}
	}
	private final ExclusiveTask _startControlTask = new ExclusiveTask(){
		@Override
		protected void onElapsed()
		{
			for (Info temp : _timedItems.values())
			{
				if(temp._activationTime<(System.currentTimeMillis()/1000))
				{
					
					deleteItem(temp);
				}
			}
			schedule(60000);
		}
	};	
	private class Info
	{
		int _charId;
		int _itemId;
		long _activationTime;
	}
} 

 

 

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `character_timed_items`
-- ----------------------------
DROP TABLE IF EXISTS `character_timed_items`;
CREATE TABLE `character_timed_items` (
  `charId` int(11) NOT NULL,
  `itemId` int(11) NOT NULL,
  `time` decimal(20,0) NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of character_timed_items
-- ----------------------------
 

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

после истечения времени обновите статус персонажа , хотя бы отсылкой Броадкаст пакета

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

после истечения времени обновите статус персонажа , хотя бы отсылкой Броадкаст пакета

Еще бы знать как это сделать :) Если знаешь - скажи как (код напиши) и куда его сунуть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

player.broadcastUserInfo();

после чего вставить, уважаемый? :help:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

после чего вставить, уважаемый? :help:

после книги Обучение Java  - вы  тут не так уж давно но решили ковырять сборку умом других пользователей , думаю у вас не чего не выйдет с таким  успехом

 

 

а после чего включите логику - заканчивается время у предмета что с ним происходит? удаление значит в методе удаления предмета (в моем случае хватило добавить в классе LifeTimeManager ) у вас даже не знаю и нет желания и времени рассматривать ,  вам дали наводку почему и как а далее постарайтесь уже как то сами , раз взялись за исходники

 

(информация для размышления а не попытка обидеть или наговорить)

Изменено пользователем Himka

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

после книги Обучение Java  - вы  тут не так уж давно но решили ковырять сборку умом других пользователей , думаю у вас не чего не выйдет с таким  успехом

 

 

а после чего включите логику - заканчивается время у предмета что с ним происходит? удаление значит в методе удаления предмета (в моем случае хватило добавить в классе LifeTimeManager ) у вас даже не знаю и нет желания и времени рассматривать ,  вам дали наводку почему и как а далее постарайтесь уже как то сами , раз взялись за исходники

 

(информация для размышления а не попытка обидеть или наговорить)

Я сделал большую часть своими руками и логикой не зная явы вообще так, что перестань умничать! Я лишь попросил помощи, чтобы исправить появившийся баг, а не написать мне код в 1000 строк.... Что сложного сказать куда дописать пару строк фикса, я же весь код LifeTimeManagera выложил?! Вы все только умничать умеете, жаль я не знаю как -1 репутации давать - давно бы навыдовал таким "умникам".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я сделал большую часть своими руками и логикой не зная явы вообще так, что перестань умничать! Я лишь попросил помощи, чтобы исправить появившийся баг, а не написать мне код в 1000 строк.... Что сложного сказать куда дописать пару строк фикса, я же весь код LifeTimeManagera выложил?! Вы все только умничать умеете, жаль я не знаю как -1 репутации давать - давно бы навыдовал таким "умникам".

Репутацию изменять могут только "Постояльцы"

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я сделал большую часть своими руками и логикой не зная явы вообще так, что перестань умничать! Я лишь попросил помощи, чтобы исправить появившийся баг, а не написать мне код в 1000 строк.... Что сложного сказать куда дописать пару строк фикса, я же весь код LifeTimeManagera выложил?! Вы все только умничать умеете, жаль я не знаю как -1 репутации давать - давно бы навыдовал таким "умникам".

Делайте дальше своей логикой вам уже достаточно подсказали , делать за вас не кто не будет , и как вы уже сказали вы сделали уже большую часть руками и логикой так ВПЕРЕД ДАЛЕЕ   (PS Тыкать вам не кто не давал права не зная человека и его возраста то что у вас там идут всплески эмоций это чисто ваши проблемы)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я сделал большую часть своими руками и логикой не зная явы вообще так, что перестань умничать! Я лишь попросил помощи, чтобы исправить появившийся баг, а не написать мне код в 1000 строк.... Что сложного сказать куда дописать пару строк фикса, я же весь код LifeTimeManagera выложил?! Вы все только умничать умеете, жаль я не знаю как -1 репутации давать - давно бы навыдовал таким "умникам".

Окей. Возьми свои золотые руки и иди делай дальше.

Где-то написано что тебе должны? Тебе дали подсказку - будь добр додумайся сам. Или если сам не можешь - плати тем кто может. Какие вопросы дядь, я не врубаюсь?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Решил начать исправлять с шадоуитемов. Вообщем теперь шапка падает в инвентарь после окончания маны, её нельзя одеть, при релоге пропадает из инвентаря:

af9a4ecf09.jpg

/*
 * 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 net.sf.l2j.gameserver.model.itemcontainer.listeners;

import net.sf.l2j.gameserver.model.actor.L2Playable;
import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
import net.sf.l2j.gameserver.model.item.instance.ItemInstance;
import net.sf.l2j.gameserver.network.SystemMessageId;
import net.sf.l2j.gameserver.network.serverpackets.InventoryUpdate;
import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;

public class ShadowWeaponListener implements OnEquipListener
{
	private static ShadowWeaponListener instance = new ShadowWeaponListener();
	
	public static ShadowWeaponListener getInstance()
	{
		return instance;
	}
	
	@Override
	public void onEquip(int slot, ItemInstance item, L2Playable playable)
	{
		if (item.isShadowItem())
		{
			item.startTimer(new ShadowLifeTimeTask(item, playable));
		}
	}
	
	@Override
	public void onUnequip(int slot, ItemInstance item, L2Playable playable)
	{
		if (item.isShadowItem())
		{
			item.stopTimer();
		}
	}
	
	protected class ShadowLifeTimeTask implements Runnable
	{
		private final ItemInstance _item;
		private final L2PcInstance _player;
		
		ShadowLifeTimeTask(ItemInstance item, L2Playable actor)
		{
			_item = item;
			_player = (L2PcInstance) actor;
		}
		
		@Override
		public void run()
		{
			if (!_item.isEquipped())
			{
				return;
			}
			
			int mana;
			synchronized (_item)
			{
				_item.setMana(_item.getMana() - 1);
				mana = _item.getMana();
				if (mana <= 0)
				{
					// Remove item first.
				/*_player.getInventory().unEquipItemInSlotAndRecord(_item.getLocationSlot());
				InventoryUpdate iu = new InventoryUpdate();
				iu.addModifiedItem(_item);
				_player.sendPacket(iu);
				_player.broadcastUserInfo();*/
				
					_player.getInventory().destroyItem("ShadowItem", _item, _player, null);
					_player.getInventory().unEquipItemInSlotAndRecord(_item.getLocationSlot());
					InventoryUpdate iu = new InventoryUpdate();
					iu.addModifiedItem(_item);
					_player.sendPacket(iu);
					_player.broadcastUserInfo();
				}
			}
			
			SystemMessage sm = null;
			if (mana == 10)
			{
				sm = SystemMessage.getSystemMessage(SystemMessageId.S1S_REMAINING_MANA_IS_NOW_10);
			}
			else if (mana == 5)
			{
				sm = SystemMessage.getSystemMessage(SystemMessageId.S1S_REMAINING_MANA_IS_NOW_5);
			}
			else if (mana == 1)
			{
				sm = SystemMessage.getSystemMessage(SystemMessageId.S1S_REMAINING_MANA_IS_NOW_1);
			}
			else if (mana <= 0)
			{
				sm = SystemMessage.getSystemMessage(SystemMessageId.S1S_REMAINING_MANA_IS_NOW_0);
			}
			/*else
			{
				_player.getInventory().unEquipItemInSlotAndRecord(_item.getLocationSlot());
				InventoryUpdate iu = new InventoryUpdate();
				iu.addModifiedItem(_item);
				_player.sendPacket(iu);
				_player.broadcastUserInfo();
			}*/
			
			if (sm != null)
			{
				sm.addItemName(_item.getItemId());
				_player.sendPacket(sm);
			}
		}
	}
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Насчёт Life

 

Метод deleteItem

 

if(item.isEquipped())

pl.getInventory().unEquipItemInSlot(item.getLocationSlot());

pl.getInventory().destroyItem("timeLost", item, pl, pl);

pl.sendPacket(new ItemList(pl, false));

pl.broadcastUserInfo();

 

 

Впредь, надо быть сдержаней.

Изменено пользователем Jumper

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зафиксил, можно закрывать тему.

 

player.broadcastUserInfo();

Огромное спасибо тебе  :friends:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Насчёт Life

 

Метод deleteItem

 

if(item.isEquipped())

pl.getInventory().unEquipItemInSlot(item.getLocationSlot());

pl.getInventory().destroyItem("timeLost", item, pl, pl);

pl.sendPacket(new ItemList(pl, false));

pl.broadcastUserInfo();

 

 

Впредь, надо быть сдержаней.

Я сам додумался, но очень удивился помощи, спасибо :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация  

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...