Index: C:/workspace/L2_GameServer/java/config/altsettings.properties
===================================================================
--- C:/workspace/L2_GameServer/java/config/altsettings.properties (revision 2151)
+++ C:/workspace/L2_GameServer/java/config/altsettings.properties (working copy)
@@ -20,6 +20,11 @@
# - players get EXP/SP for crafting
AltGameCreation = False
+# Alt game creation XP/SP based on mana
+# new XP/SP reward system, calculation based on
+# mana used to craft item
+AltGameCreationByMana = False
+
# Alternative skill learn rules:
# - all classes can learn all skills
# - skills of another class costs x2 SP
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/Config.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/Config.java (revision 2151)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/Config.java (working copy)
@@ -72,8 +72,11 @@
/** Thread pools size */
public static int THREAD_P_HIGH;
+ public static int THREAD_P_MEDHIGH;
public static int THREAD_P_MED;
public static int THREAD_P_LOW;
+ public static int THREAD_P_AI;
+ public static int THREAD_P_CRAFT;
/** Auto-loot? */
public static boolean AUTO_LOOT;
@@ -83,10 +86,16 @@
/** Global chat state */
public static String DEFAULT_GLOBAL_CHAT;
+
/** For test servers - evrybody has admin rights */
public static boolean EVERYBODY_HAS_ADMIN_RIGHTS;
+
/** Alternative game crafting */
public static boolean ALT_GAME_CREATION;
+
+ /** Reward XP/SP to crafter based on mana **/
+ public static boolean ALT_GAME_CREATION_BY_MANA;
+
/** Alternative game skill learning */
public static boolean ALT_GAME_SKILL_LEARN;
/** Cancel ATTACK/cast by hit */
@@ -388,8 +397,10 @@
public static int EXECUTOR_PRI_LOW;
public static int EXECUTOR_PRI_MED;
+ public static int EXECUTOR_PRI_MEDHIGH;
public static int EXECUTOR_PRI_HIGH;
-
+ public static int EXECUTOR_PRI_AI;
+ public static int EXECUTOR_PRI_CRAFT;
public static enum IdFactoryType
{
@@ -583,8 +594,11 @@
AUTODELETE_INVALID_QUEST_DATA = Boolean.valueOf(serverSettings.getProperty("AutoDeleteInvalidQuestData", "False"));
THREAD_P_HIGH = Integer.parseInt(serverSettings.getProperty("ThreadPoolSizeHigh", "4"));
- THREAD_P_MED = Integer.parseInt(serverSettings.getProperty("ThreadPoolSizeMed", "10"));
- THREAD_P_LOW = Integer.parseInt(serverSettings.getProperty("ThreadPoolSizeLow", "4"));
+ THREAD_P_MEDHIGH = Integer.parseInt(serverSettings.getProperty("ThreadPoolSizeMedHigh","4"));
+ THREAD_P_MED = Integer.parseInt(serverSettings.getProperty("ThreadPoolSizeMed", "4"));
+ THREAD_P_LOW = Integer.parseInt(serverSettings.getProperty("ThreadPoolSizeLow", "4"));
+ THREAD_P_AI = Integer.parseInt(serverSettings.getProperty("ThreadPoolSizeAi", "4"));
+ THREAD_P_CRAFT = Integer.parseInt(serverSettings.getProperty("ThreadPoolSizeCraft", "4"));
MAXIMUM_ONLINE_USERS = Integer.parseInt(serverSettings.getProperty("MaximumOnlineUsers", "100"));
@@ -617,7 +631,10 @@
EXECUTOR_PRI_LOW = Integer.parseInt(serverSettings.getProperty("ExecutorPriLow", "-1"));
EXECUTOR_PRI_MED = Integer.parseInt(serverSettings.getProperty("ExecutorPriMed", "0"));
- EXECUTOR_PRI_HIGH = Integer.parseInt(serverSettings.getProperty("ExecutorPriHigh", "1"));
+ EXECUTOR_PRI_MEDHIGH = Integer.parseInt(serverSettings.getProperty("ExecutorPriMedHigh", "1"));
+ EXECUTOR_PRI_HIGH = Integer.parseInt(serverSettings.getProperty("ExecutorPriHigh", "2"));
+ EXECUTOR_PRI_AI = Integer.parseInt(serverSettings.getProperty("ExecutorPriAi", "0"));
+ EXECUTOR_PRI_CRAFT = Integer.parseInt(serverSettings.getProperty("ExecutorPriCraft", "0"));
}
catch (Exception e)
{
@@ -718,7 +735,7 @@
STARTING_ADENA = Integer.parseInt(otherSettings.getProperty("StartingAdena", "100"));
UNSTUCK_INTERVAL = Integer.parseInt(otherSettings.getProperty("UnstuckInterval", "300"));
-
+
/* Player protection after teleport or login */
PLAYER_SPAWN_PROTECTION = Integer.parseInt(otherSettings.getProperty("PlayerSpawnProtection", "0"));
@@ -787,25 +804,26 @@
altSettings.load(is);
is.close();
- ALT_GAME_TIREDNESS = Boolean.parseBoolean(altSettings.getProperty("AltGameTiredness", "false"));
- ALT_GAME_CREATION = Boolean.parseBoolean(altSettings.getProperty("AltGameCreation", "false"));
- ALT_GAME_SKILL_LEARN = Boolean.parseBoolean(altSettings.getProperty("AltGameSkillLearn", "false"));
- ALT_GAME_CANCEL_BOW = altSettings.getProperty("AltGameCancelByHit", "Cast").equalsIgnoreCase("bow") || altSettings.getProperty("AltGameCancelByHit", "Cast").equalsIgnoreCase("all");
- ALT_GAME_CANCEL_CAST = altSettings.getProperty("AltGameCancelByHit", "Cast").equalsIgnoreCase("cast") || altSettings.getProperty("AltGameCancelByHit", "Cast").equalsIgnoreCase("all");
- ALT_GAME_SHIELD_BLOCKS = Boolean.parseBoolean(altSettings.getProperty("AltShieldBlocks", "false"));
- ALT_GAME_DELEVEL = Boolean.parseBoolean(altSettings.getProperty("Delevel", "true"));
- ALT_GAME_MOB_ATTACK_AI = Boolean.parseBoolean(altSettings.getProperty("AltGameMobAttackAI", "false"));
- ALT_GAME_SKILL_FORMULAS = altSettings.getProperty("AltGameSkillFormulas", "none");
- ALT_GAME_EXPONENT_XP = Float.parseFloat(altSettings.getProperty("AltGameExponentXp", "0."));
- ALT_GAME_EXPONENT_SP = Float.parseFloat(altSettings.getProperty("AltGameExponentSp", "0."));
- ALLOW_CLASS_MASTERS = Boolean.valueOf(altSettings.getProperty("AllowClassMasters", "False"));
- ALT_GAME_FREIGHTS = Boolean.parseBoolean(altSettings.getProperty("AltGameFreights", "false"));
- ALT_GAME_FREIGHT_PRICE = Integer.parseInt(altSettings.getProperty("AltGameFreightPrice", "1000"));
- ALT_GAME_SKILL_HIT_RATE = Float.parseFloat(altSettings.getProperty("AltGameSkillHitRate", "1."));
- ENABLE_RATE_HP = Boolean.parseBoolean(altSettings.getProperty("EnableRateHp", "false"));
- IS_CRAFTING_ENABLED = Boolean.parseBoolean(altSettings.getProperty("CraftingEnabled", "true"));
- SP_BOOK_NEEDED = Boolean.parseBoolean(altSettings.getProperty("SpBookNeeded", "true"));
- AUTO_LOOT = altSettings.getProperty("AutoLoot").equalsIgnoreCase("True");
+ ALT_GAME_TIREDNESS = Boolean.parseBoolean(altSettings.getProperty("AltGameTiredness", "false"));
+ ALT_GAME_CREATION = Boolean.parseBoolean(altSettings.getProperty("AltGameCreation", "false"));
+ ALT_GAME_CREATION_BY_MANA = Boolean.parseBoolean(altSettings.getProperty("AltGameCreationByMana", "false"));
+ ALT_GAME_SKILL_LEARN = Boolean.parseBoolean(altSettings.getProperty("AltGameSkillLearn", "false"));
+ ALT_GAME_CANCEL_BOW = altSettings.getProperty("AltGameCancelByHit", "Cast").equalsIgnoreCase("bow") || altSettings.getProperty("AltGameCancelByHit", "Cast").equalsIgnoreCase("all");
+ ALT_GAME_CANCEL_CAST = altSettings.getProperty("AltGameCancelByHit", "Cast").equalsIgnoreCase("cast") || altSettings.getProperty("AltGameCancelByHit", "Cast").equalsIgnoreCase("all");
+ ALT_GAME_SHIELD_BLOCKS = Boolean.parseBoolean(altSettings.getProperty("AltShieldBlocks", "false"));
+ ALT_GAME_DELEVEL = Boolean.parseBoolean(altSettings.getProperty("Delevel", "true"));
+ ALT_GAME_MOB_ATTACK_AI = Boolean.parseBoolean(altSettings.getProperty("AltGameMobAttackAI", "false"));
+ ALT_GAME_SKILL_FORMULAS = altSettings.getProperty("AltGameSkillFormulas", "none");
+ ALT_GAME_EXPONENT_XP = Float.parseFloat(altSettings.getProperty("AltGameExponentXp", "0."));
+ ALT_GAME_EXPONENT_SP = Float.parseFloat(altSettings.getProperty("AltGameExponentSp", "0."));
+ ALLOW_CLASS_MASTERS = Boolean.valueOf(altSettings.getProperty("AllowClassMasters", "False"));
+ ALT_GAME_FREIGHTS = Boolean.parseBoolean(altSettings.getProperty("AltGameFreights", "false"));
+ ALT_GAME_FREIGHT_PRICE = Integer.parseInt(altSettings.getProperty("AltGameFreightPrice", "1000"));
+ ALT_GAME_SKILL_HIT_RATE = Float.parseFloat(altSettings.getProperty("AltGameSkillHitRate", "1."));
+ ENABLE_RATE_HP = Boolean.parseBoolean(altSettings.getProperty("EnableRateHp", "false"));
+ IS_CRAFTING_ENABLED = Boolean.parseBoolean(altSettings.getProperty("CraftingEnabled", "true"));
+ SP_BOOK_NEEDED = Boolean.parseBoolean(altSettings.getProperty("SpBookNeeded", "true"));
+ AUTO_LOOT = altSettings.getProperty("AutoLoot").equalsIgnoreCase("True");
ALT_GAME_KARMA_PLAYER_CAN_BE_KILLED_IN_PEACEZONE = Boolean.valueOf(altSettings.getProperty("AltKarmaPlayerCanBeKilledInPeaceZone", "false"));
ALT_GAME_KARMA_PLAYER_CAN_SHOP = Boolean.valueOf(altSettings.getProperty("AltKarmaPlayerCanShop", "true"));
ALT_GAME_KARMA_PLAYER_CAN_TELEPORT = Boolean.valueOf(altSettings.getProperty("AltKarmaPlayerCanTeleport", "true"));
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/SpawnTable.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/SpawnTable.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/SpawnTable.java (working copy)
@@ -53,7 +53,6 @@
private SpawnTable()
{
-
fillSpawnTable();
}
@@ -90,6 +89,7 @@
}
else
{
+ try {
spawnDat = new L2Spawn(template1);
spawnDat.setId(rset.getInt("id"));
spawnDat.setAmount(rset.getInt("count"));
@@ -106,10 +106,15 @@
if (spawnDat.getId() > _highestId)
_highestId = spawnDat.getId();
- }
+ } catch (Exception e)
+ {
+ _log.warning("_npcSpawnCount: "+_npcSpawnCount + " _spawntable.size(): " + _spawntable.size()+ " spawnDat id: "+rset.getInt("id"));
+ _log.warning("SpawnTable: Data missing in NPC table for ID: " + rset.getInt("npc_templateid") + ".");
+ };
+ }
}
else {
- _log.warning("SpawnTable: Data missing in NPC table for ID: " + rset.getInt("npc_templateid") + ".");
+ _log.warning("@@@@SpawnTable: Data missing in NPC table for ID: " + rset.getInt("npc_templateid") + ".");
}
}
@@ -119,7 +124,9 @@
catch (Exception e)
{
// problem with initializing spawn, go to next one
- _log.warning("SpawnTable: Spawn could not be initialized: " + e);
+ _log.warning("####SpawnTable: Spawn could not be initialized: " + e);
+ _log.warning("Spawntable problem details: ");
+ _log.warning("_npcSpawnCount: "+_npcSpawnCount + " _spawntable.size(): " + _spawntable.size());
}
finally
{
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/SelectorThread.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/SelectorThread.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/SelectorThread.java (working copy)
@@ -146,7 +146,7 @@
this._hostname = hostname;
this._port = port;
this.setDaemon(true);
- this.setPriority(Thread.NORM_PRIORITY+1);
+ this.setPriority(Thread.NORM_PRIORITY+2);
// write buffers (HeapByteBuffer is much faster for our perposes)
writeBuffers = new ByteBuffer[WRITE_BUF_HASH_SIZE];
for (int i=0; i < WRITE_BUF_HASH_SIZE; i++) {
@@ -723,7 +723,7 @@
packetHistory.clear();
byteHistory.clear();
- packetMonitor = ClientScheduler.getInstance().scheduleLowAtFixedRate(
+ packetMonitor = ClientScheduler.getInstance().scheduleMedAtFixedRate(
new Runnable()
{
public void run()
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/RequestRestartPoint.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/RequestRestartPoint.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/RequestRestartPoint.java (working copy)
@@ -67,16 +67,16 @@
{
try
{
- Location loc;
- if (requestedPointType == 2) // to castle
- loc = MapRegionTable.getInstance().getTeleToLocation(activeChar, MapRegionTable.TeleportWhereType.Castle);
- else if (requestedPointType == 3) // to siege HQ
- loc = MapRegionTable.getInstance().getTeleToLocation(activeChar, MapRegionTable.TeleportWhereType.SiegeFlag);
- else if (requestedPointType == 4 || // Fixed or
- activeChar.isFestivalParticipant()) // Player is a festival participant
- loc = new Location(activeChar.getX(), activeChar.getY(), activeChar.getZ()); // spawn them where they died
- else
- loc = MapRegionTable.getInstance().getTeleToLocation(activeChar, MapRegionTable.TeleportWhereType.ClosestTown);
+ Location loc;
+ if (requestedPointType == 2) // to castle
+ loc = MapRegionTable.getInstance().getTeleToLocation(activeChar, MapRegionTable.TeleportWhereType.Castle);
+ else if (requestedPointType == 3) // to siege HQ
+ loc = MapRegionTable.getInstance().getTeleToLocation(activeChar, MapRegionTable.TeleportWhereType.SiegeFlag);
+ else if (requestedPointType == 4 || // Fixed or
+ activeChar.isFestivalParticipant()) // Player is a festival participant
+ loc = new Location(activeChar.getX(), activeChar.getY(), activeChar.getZ()); // spawn them where they died
+ else
+ loc = MapRegionTable.getInstance().getTeleToLocation(activeChar, MapRegionTable.TeleportWhereType.ClosestTown);
//Teleport and revive
MapRegionTable.getInstance().teleToLocation(activeChar, loc);
@@ -94,8 +94,8 @@
if (activeChar == null)
return;
//SystemMessage sm2 = new SystemMessage(614);
- //sm2.addString("type:"+requestedPointType);
- //activeChar.sendPacket(sm2);
+ //sm2.addString("type:"+requestedPointType);
+ //activeChar.sendPacket(sm2);
if (activeChar.isFakeDeath())
{
@@ -113,21 +113,21 @@
&& castle.getSiege().checkIsAttacker(activeChar.getClan()))
{
// Schedule respawn delay for attacker
- ClientScheduler.getInstance().scheduleLow(new DeathTask(activeChar), castle.getSiege().getAttackerRespawnDelay());
+ ClientScheduler.getInstance().scheduleMed(new DeathTask(activeChar), castle.getSiege().getAttackerRespawnDelay());
sm.addString("You will be re-spawned in " + castle.getSiege().getAttackerRespawnDelay()/1000 + " seconds");
activeChar.sendPacket(sm);
}
else
{
// Schedule respawn delay for defender with penalty for CT lose
- ClientScheduler.getInstance().scheduleLow(new DeathTask(activeChar), castle.getSiege().getDefenderRespawnDelay());
+ ClientScheduler.getInstance().scheduleMed(new DeathTask(activeChar), castle.getSiege().getDefenderRespawnDelay());
sm.addString("You will be re-spawned in " + castle.getSiege().getDefenderRespawnDelay()/1000 + " seconds");
activeChar.sendPacket(sm);
}
return;
}
- ClientScheduler.getInstance().scheduleLow(new DeathTask(activeChar), 1);
+ ClientScheduler.getInstance().scheduleMed(new DeathTask(activeChar), 1);
}
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/EnterWorld.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/EnterWorld.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/EnterWorld.java (working copy)
@@ -75,7 +75,7 @@
if(activeChar.isGM())
{
- activeChar.setInvisible();
+ //activeChar.setInvisible();
}
if (Config.PLAYER_SPAWN_PROTECTION > 0)
@@ -187,9 +187,9 @@
if(activeChar.isGM())
{
- activeChar.sendMessage("Hide is default for builder");
- activeChar.setMessageRefusal(true);
- activeChar.sendMessage("Message refusal mode");
+ activeChar.sendMessage("Admins are not cowards!");
+ activeChar.sendMessage("We don't hide and we don't refuse questions from players!");
+ activeChar.setMessageRefusal(false);
}
}
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/RequestRecipeItemMakeSelf.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/RequestRecipeItemMakeSelf.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/RequestRecipeItemMakeSelf.java (working copy)
@@ -19,8 +19,10 @@
package net.sf.l2j.gameserver.clientpackets;
import java.nio.ByteBuffer;
+import java.util.logging.Logger;
import net.sf.l2j.gameserver.ClientThread;
+import net.sf.l2j.gameserver.GameServer;
import net.sf.l2j.gameserver.RecipeController;
import net.sf.l2j.gameserver.model.L2PcInstance;
@@ -33,7 +35,7 @@
public class RequestRecipeItemMakeSelf extends ClientBasePacket
{
private static final String _C__AF_REQUESTRECIPEITEMMAKESELF = "[C] AF RequestRecipeItemMakeSelf";
- //private static Logger _log = Logger.getLogger(RequestSellItem.class.getName());
+ private static final Logger _log = Logger.getLogger(RequestRecipeItemMakeSelf.class.getName());
private final int _id;
/**
@@ -60,6 +62,7 @@
if (activeChar.isInCraftMode())
{
activeChar.sendMessage("Currently in Craft Mode");
+ _log.warning("Currently in Craft Mode");
return;
}
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2SiegeGuardInstance.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2SiegeGuardInstance.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2SiegeGuardInstance.java (working copy)
@@ -133,8 +133,8 @@
*/
public void onAction(L2PcInstance player)
{
- // if (player == null)
- // return;
+ if (player == null)
+ return;
if (this != player.getTarget())
{
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Potion.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Potion.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Potion.java (working copy)
@@ -24,7 +24,6 @@
import net.sf.l2j.Config;
import net.sf.l2j.gameserver.ClientScheduler;
-
/**
*
* This class ...
@@ -65,15 +64,13 @@
{
double nowHp = _instance.getCurrentHp();
if(_duration == 0)
- {
stopPotionHpRegeneration();
- }
- if (_duration != 0)
+ else
{
nowHp += _effect;
_instance.setCurrentHp(nowHp);
- _duration = _duration - (_milliseconds / 1000);
- setCurrentHpPotion2();
+ _duration -= (_milliseconds / 1000);
+ if(_duration==0) stopPotionHpRegeneration();
}
}
}
@@ -100,13 +97,6 @@
if (Config.DEBUG) _log.fine("Potion HP regen stop");
}
- public void setCurrentHpPotion2()
- {
- if (_duration == 0)
- {
- stopPotionHpRegeneration();
- }
- }
public void setCurrentHpPotion1(L2Character activeChar, int item)
{
_potion = item;
@@ -114,23 +104,8 @@
switch (_potion)
{
- case (1540):
- double nowHp = activeChar.getCurrentHp();
- nowHp+=435;
- if (nowHp>= activeChar.getMaxHp())
- {
- nowHp = activeChar.getMaxHp();
- }
- activeChar.setCurrentHp(nowHp);
- case (728):
- double nowMp = activeChar.getMaxMp();
- nowMp+=435;
- if (nowMp>= activeChar.getMaxMp())
- {
- nowMp = activeChar.getMaxMp();
- }
- activeChar.setCurrentMp(nowMp);
- break;
+ case (1540): activeChar.setCurrentHp(java.lang.Math.min(activeChar.getCurrentHp()+435,(double)activeChar.getMaxHp()));break;
+ case (728) : activeChar.setCurrentMp(java.lang.Math.min(activeChar.getCurrentMp()+435,(double)activeChar.getMaxMp()));break;
case (726):
_milliseconds = 500;
_duration = 15;
@@ -157,16 +132,13 @@
{
double nowMp = _instance.getCurrentMp();
if(_duration == 0)
+ stopPotionMpRegeneration();
+ else
{
- stopPotionMpRegeneration();
- }
- if (_duration != 0)
- {
nowMp+=_effect;
_instance.setCurrentMp(nowMp);
_duration=(_duration-(_milliseconds/1000));
- setCurrentMpPotion2();
-
+ if(_duration == 0) stopPotionMpRegeneration();
}
}
}
@@ -179,7 +151,7 @@
private void startPotionMpRegeneration(L2Character activeChar)
{
- _potionmpRegTask = ClientScheduler.getInstance().scheduleMedAtFixedRate(
+ _potionmpRegTask = ClientScheduler.getInstance().scheduleMedHighAtFixedRate(
new PotionMpHealing(activeChar), 1000, _milliseconds);
if (Config.DEBUG) _log.fine("Potion MP regen Started");
}
@@ -195,14 +167,6 @@
if (Config.DEBUG) _log.fine("Potion MP regen stop");
}
- public void setCurrentMpPotion2()
- {
- if (_duration == 0)
- {
- stopPotionMpRegeneration();
- }
- }
-
public void setCurrentMpPotion1(L2Character activeChar, int item)
{
_potion = item;
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/actor/character/CharStatus.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/actor/character/CharStatus.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/actor/character/CharStatus.java (working copy)
@@ -197,7 +197,7 @@
int period = Formulas.getInstance().getRegeneratePeriod(getActiveChar());
// Create the HP/MP/CP Regeneration task
- _RegTask = ClientScheduler.getInstance().scheduleMedAtFixedRate(new RegenTask(), period, period);
+ _RegTask = ClientScheduler.getInstance().scheduleMedHighAtFixedRate(new RegenTask(), period, period);
}
}
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2MonsterInstance.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2MonsterInstance.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2MonsterInstance.java (working copy)
@@ -28,7 +28,7 @@
import net.sf.l2j.gameserver.model.actor.monster.MonsterKnownList;
import net.sf.l2j.gameserver.templates.L2NpcTemplate;
import net.sf.l2j.gameserver.util.MinionList;
-
+import net.sf.l2j.gameserver.ai.CtrlIntention;
/**
* This class manages all Monsters.
*
@@ -108,18 +108,27 @@
{
minionList.maintainMinions();
//must be fixed. class exception.
- //for(L2MinionInstance minion : minionList.getSpawnedMinions())
- // minion.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, this);
+ for(L2MinionInstance minion : minionList.getSpawnedMinions())
+ {
+ if(minion==null) {
+ _log.warning("minion=null, spawnedMinions: "+minionList.countSpawnedMinions());
+ continue;
+ }
+
+ //minion.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, this);
+ };
}
- catch (Throwable e)
+ catch (Exception e)
{
- _log.log(Level.SEVERE, "", e);
+ _log.log(Level.SEVERE, "%%%%%", e);
+ e.printStackTrace();
}
}
}, getMaintenanceInterval());
}
catch ( NullPointerException e )
{
+ _log.log(Level.SEVERE, "", e);
}
}
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Clan.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Clan.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Clan.java (working copy)
@@ -83,7 +83,11 @@
public L2Clan(int clanId)
{
_clanId = clanId;
- restore();
+ try
+ {restore();} catch (Exception e)
+ {
+ _log.warning("Exception in L2Clan constructor, restore() failed: "+e);
+ }
}
/**
@@ -96,6 +100,11 @@
{
_clanId = clanId;
_name = clanName;
+ if(leader==null)
+ {
+ _log.warning("Clan '"+clanName + "' id "+clanId+" has no leader (null), attempting to setNewLeader()");
+ _log.warning("New leader now: "+getLeaderName());
+ };
setLeader(leader);
}
@@ -118,6 +127,7 @@
*/
public int getLeaderId()
{
+ if (_leader==null) setNewLeader();
return _leader.getObjectId();
}
/**
@@ -125,6 +135,7 @@
*/
public L2ClanMember getLeader()
{
+ if (_leader==null) setNewLeader();
return _leader;
}
/**
@@ -135,6 +146,7 @@
_leader = leader;
_members.put(leader.getName(), leader);
}
+
public void setNewLeader()
{
int maxLevel = 0;
@@ -160,7 +172,8 @@
*/
public String getLeaderName()
{
- return _leader.getName();
+ if (_leader==null) setNewLeader();
+ return _leader.getName();
}
/**
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Skill.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Skill.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Skill.java (working copy)
@@ -159,7 +159,8 @@
DRAIN_SOUL,
// unimplemented
- NOTDONE;
+ NOTDONE,
+ MDAM_ELEMENTAL;
private final Class extends L2Skill> clazz;
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Character.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Character.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Character.java (working copy)
@@ -210,7 +210,7 @@
{
decayMe();
}
-
+
public void onTeleported()
{
setIsTeleporting(false);
@@ -218,7 +218,7 @@
spawnMe(getPosition().getX(), getPosition().getY(), getPosition().getZ());
if (_IsPendingRevive) doRevive();
-
+
// Modify the position of the pet if necessary
if(getPet() != null) getPet().teleToLocation(getPosition().getX() + Rnd.get(-100,100), getPosition().getY() + Rnd.get(-100,100), getPosition().getZ());
}
@@ -253,6 +253,7 @@
for (L2PcInstance player : knownPlayers)
{
if (player == null || player == this) continue;
+ if(getDistance(player.getX(),player.getY()) > 2000) continue;
player.sendPacket(mov);
if(Config.DEVELOPER && getDistance(player.getX(),player.getY()) > 1500) _log.warning("broadcastPacket: Too far player see event!");
}
@@ -290,6 +291,7 @@
temp.sendPacket(su);
}
+
/**
* Not Implemented.
*
@@ -321,12 +323,12 @@
setIsAttacked(false);
setIsTeleporting(true);
setTarget(null);
-
- x += Rnd.get(-70, 70);
- y += Rnd.get(-70, 70);
+
+ x += Rnd.get(-70,70);
+ y += Rnd.get(-70,70);
z += 5;
- if (Config.DEBUG) _log.fine("Teleporting to: " + x + ", " + y + ", " + z);
+ if (Config.DEBUG) _log.fine("Teleporting to: "+x+", "+y+", "+z);
// Send a Server->Client packet TeleportToLocationt to the L2Character AND to all L2PcInstance in the _KnownPlayers of the L2Character
broadcastPacket(new TeleportToLocation(this, x, y, z));
@@ -396,7 +398,7 @@
{
// If L2PcInstance doesn't have enough MP, stop the attack
- ClientScheduler.getInstance().scheduleMed(new NotifyAITask(CtrlEvent.EVT_READY_TO_ACT), 1000);
+ ClientScheduler.getInstance().scheduleAi(new NotifyAITask(CtrlEvent.EVT_READY_TO_ACT), 1000);
sendPacket(new SystemMessage(SystemMessage.NOT_ENOUGH_MP));
@@ -416,7 +418,7 @@
else
{
// Cancel the action because the bow can't be re-use at this moment
- ClientScheduler.getInstance().scheduleMed(new NotifyAITask(CtrlEvent.EVT_READY_TO_ACT), 1000);
+ ClientScheduler.getInstance().scheduleAi(new NotifyAITask(CtrlEvent.EVT_READY_TO_ACT), 1000);
ActionFailed af = new ActionFailed();
sendPacket(af);
@@ -502,7 +504,7 @@
int reuse = weaponItem==null ? 0 : weaponItem.getAttackReuseDelay();
// Notify AI with EVT_READY_TO_ACT
- ClientScheduler.getInstance().scheduleMed(new NotifyAITask(CtrlEvent.EVT_READY_TO_ACT), sAtk+reuse);
+ ClientScheduler.getInstance().scheduleAi(new NotifyAITask(CtrlEvent.EVT_READY_TO_ACT), sAtk+reuse);
}
/**
@@ -578,7 +580,7 @@
}
// Create a new hit task with Medium priority
- ClientScheduler.getInstance().scheduleMed(new HitTask(target, damage1, crit1, miss1, attack._soulshot, shld1), sAtk);
+ ClientScheduler.getInstance().scheduleMedHigh(new HitTask(target, damage1, crit1, miss1, attack._soulshot, shld1), sAtk);
// Calculate and set the disable delay of the bow in function of the Attack Speed
_disableBowAttackEndTime = (sAtk+reuse)/GameTimeController.MILLIS_IN_TICK + GameTimeController.getGameTicks();
@@ -648,10 +650,10 @@
}
// Create a new hit task with Medium priority for hit 1
- ClientScheduler.getInstance().scheduleMed(new HitTask(target, damage1, crit1, miss1, attack._soulshot, shld1), 650);
+ ClientScheduler.getInstance().scheduleMedHigh(new HitTask(target, damage1, crit1, miss1, attack._soulshot, shld1), 650);
// Create a new hit task with Medium priority for hit 2 with a higher delay
- ClientScheduler.getInstance().scheduleMed(new HitTask(target, damage2, crit2, miss2, attack._soulshot, shld2), 1250);
+ ClientScheduler.getInstance().scheduleMedHigh(new HitTask(target, damage2, crit2, miss2, attack._soulshot, shld2), 1250);
// Add those hits to the Server-Client packet Attack
attack.addHit(target, damage1, miss1, crit1, shld1);
@@ -795,7 +797,7 @@
}
// Create a new hit task with Medium priority
- ClientScheduler.getInstance().scheduleMed(new HitTask(target, damage1, crit1, miss1, attack._soulshot, shld1), 980);
+ ClientScheduler.getInstance().scheduleMedHigh(new HitTask(target, damage1, crit1, miss1, attack._soulshot, shld1), 980);
// Add this hit to the Server-Client packet Attack
attack.addHit(target, damage1, miss1, crit1, shld1);
@@ -974,7 +976,7 @@
if (reuseDelay > 10)
{
disableSkill(skill.getId());
- ClientScheduler.getInstance().scheduleMed(new EnableSkill(skill.getId()), reuseDelay);
+ ClientScheduler.getInstance().scheduleMedHigh(new EnableSkill(skill.getId()), reuseDelay);
}
// launch the magic in skillTime milliseconds
@@ -989,7 +991,7 @@
// Disable all skills during the casting time and create a task EnableAllSkills with Medium priority to enable all skills at the end of the cating time
disableAllSkills();
- ClientScheduler.getInstance().scheduleMed(new EnableAllSkills(skill), skillTime);
+ ClientScheduler.getInstance().scheduleMedHigh(new EnableAllSkills(skill), skillTime);
if (_skillCast != null)
{
@@ -998,7 +1000,7 @@
}
// Create a task MagicUseTask with Medium priority to launch the MagicSkill at the end of the casting time
- _skillCast = ClientScheduler.getInstance().scheduleMed(new MagicUseTask(targets, skill), skillTime);
+ _skillCast = ClientScheduler.getInstance().scheduleMedHigh(new MagicUseTask(targets, skill), skillTime);
}
else
{
@@ -1056,26 +1058,26 @@
_NotifyQuestOfDeathList.clear();
getAttackByList().clear();
}
-
+
/** Sets HP, MP and CP and revives the L2Character. */
public void doRevive()
{
if (!isTeleporting())
{
setIsPendingRevive(false);
-
+
_Status.setCurrentCp(getMaxCp() * Config.RESPAWN_RESTORE_CP);
- _Status.setCurrentHp(getMaxHp() * Config.RESPAWN_RESTORE_HP);
- _Status.setCurrentMp(getMaxMp() * Config.RESPAWN_RESTORE_MP);
-
- // Start broadcast status
- broadcastPacket(new SocialAction(getObjectId(), 15));
- broadcastPacket(new Revive(this));
- }
+ _Status.setCurrentHp(getMaxHp() * Config.RESPAWN_RESTORE_HP);
+ _Status.setCurrentMp(getMaxMp() * Config.RESPAWN_RESTORE_MP);
+
+ // Start broadcast status
+ broadcastPacket(new SocialAction(getObjectId(), 15));
+ broadcastPacket(new Revive(this));
+ }
else
setIsPendingRevive(true);
}
-
+
/** Revives the L2Character using skill. */
public void doRevive(L2Skill skill) { doRevive(); }
@@ -3261,7 +3263,7 @@
// Create a task to notify the AI that L2Character arrives at a check point of the movement
if (tm > 3000)
- ClientScheduler.getInstance().scheduleMed( new NotifyAITask(CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
+ ClientScheduler.getInstance().scheduleAi( new NotifyAITask(CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
// the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
// to destination by GameTimeController
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/GameServer.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/GameServer.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/GameServer.java (working copy)
@@ -134,12 +134,27 @@
import net.sf.l2j.gameserver.script.faenor.FaenorScriptEngine;
import net.sf.l2j.status.Status;
import net.sf.l2j.gameserver.taskmanager.TaskManager;
+import net.sf.l2j.gameserver.ClientScheduler;
+
+class Finalizator implements Runnable
+{
+ public void run()
+ {
+ System.runFinalization();
+ //Runtime.getRuntime().gc();
+ Runtime.getRuntime().runFinalization();
+ };
+};
+
+
+
/**
* This class ...
*
* @version $Revision: 1.29.2.15.2.19 $ $Date: 2005/04/05 19:41:23 $
*/
+
public class GameServer
{
private static final Logger _log = Logger.getLogger(GameServer.class.getName());
@@ -176,8 +191,7 @@
return _selectorThread;
}
-
- public GameServer() throws Exception
+ public GameServer() throws Exception
{
gameServer = this;
_log.finest("used mem:" + getUsedMemoryMB()+"MB" );
@@ -428,7 +442,14 @@
_log.config("IdFactory: Free ObjectID's remaining: " + IdFactory.getInstance().size());
- System.gc();
+ System.runFinalization();
+ System.gc();
+ System.runFinalization();
+ System.gc();
+ Runtime.getRuntime().gc();
+ Runtime.getRuntime().runFinalization();
+ ClientScheduler.getInstance().scheduleLowAtFixedRate(new Finalizator(),60,60);
+
// maxMemory is the upper limit the jvm can use, totalMemory the size of the current allocation pool, freeMemory the unused memory in the allocation pool
long freeMem = (Runtime.getRuntime().maxMemory()-Runtime.getRuntime().totalMemory()+Runtime.getRuntime().freeMemory()) / 1024 / 1024;
long totalMem = Runtime.getRuntime().maxMemory() / 1024 / 1024;
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ItemTable.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ItemTable.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ItemTable.java (working copy)
@@ -31,7 +31,11 @@
import net.sf.l2j.L2DatabaseFactory;
import net.sf.l2j.gameserver.idfactory.IdFactory;
import net.sf.l2j.gameserver.model.L2ItemInstance;
+import net.sf.l2j.gameserver.model.L2PcInstance;
+import net.sf.l2j.gameserver.model.L2Skill;
import net.sf.l2j.gameserver.model.L2World;
+import net.sf.l2j.gameserver.serverpackets.ActionFailed;
+import net.sf.l2j.gameserver.serverpackets.SystemMessage;
import net.sf.l2j.gameserver.skills.SkillsEngine;
import net.sf.l2j.gameserver.templates.L2Armor;
import net.sf.l2j.gameserver.templates.L2ArmorType;
@@ -603,7 +607,8 @@
return temp;
}
-
+
+
/**
* Returns a dummy (fr = factice) item.
* Concept :
@@ -634,5 +639,36 @@
return temp;
}
-
+
+ public L2ItemInstance createItemByCrafting(int itemId,L2PcInstance crafter,L2PcInstance customer,int price)
+ {
+ int skillLevel = crafter.getSkillLevel(L2Skill.SKILL_CRAFTING);
+ if (skillLevel <= 0)
+ {
+ crafter.sendPacket(new ActionFailed());
+ return null;
+ }
+
+ if (customer==null) customer=crafter;
+
+ // here we decided that crafting is possible so we can proceed
+ crafter.isInCraftMode(true);
+
+ if (customer.getAdena() < price)
+ {
+ customer.sendPacket(new SystemMessage(SystemMessage.YOU_NOT_ENOUGH_ADENA));
+ return null;
+ }
+
+
+ // Create and Init the L2ItemInstance corresponding to the Item Identifier
+ L2ItemInstance temp = new L2ItemInstance(IdFactory.getInstance().getNextId(), itemId);
+ if (Config.DEBUG) _log.fine("ItemTable: Item created oid:" + temp.getObjectId()+ " itemid:" + itemId);
+
+ // Add the L2ItemInstance object to _allObjects of L2world
+ L2World.getInstance().storeObject(temp);
+
+ return temp;
+ }
+
}
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2AttackableAI.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2AttackableAI.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2AttackableAI.java (working copy)
@@ -244,7 +244,7 @@
// If not idle - create an AI task (schedule onEvtThink repeatedly)
if (aiTask == null)
{
- aiTask = ClientScheduler.getInstance().scheduleLowAtFixedRate(this, 1000, 1000);
+ aiTask = ClientScheduler.getInstance().scheduleAiAtFixedRate(this, 1000, 1000);
}
}
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2SummonAI.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2SummonAI.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2SummonAI.java (working copy)
@@ -16,7 +16,7 @@
*
* http://www.gnu.org/copyleft/gpl.html
*/
-package net.sf.l2j.gameserver.ai;
+package net.sf.l2j.gameserver.ai;
import static net.sf.l2j.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK;
import static net.sf.l2j.gameserver.ai.CtrlIntention.AI_INTENTION_CAST;
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2SiegeGuardAI.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2SiegeGuardAI.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2SiegeGuardAI.java (working copy)
@@ -21,6 +21,7 @@
import static net.sf.l2j.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE;
import static net.sf.l2j.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK;
import static net.sf.l2j.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE;
+import static net.sf.l2j.gameserver.ai.CtrlIntention.AI_INTENTION_FOLLOW;
import java.util.Random;
import java.util.concurrent.Future;
@@ -40,8 +41,7 @@
import net.sf.l2j.gameserver.model.L2PcInstance;
import net.sf.l2j.gameserver.model.L2SiegeGuardInstance;
import net.sf.l2j.gameserver.model.L2Skill;
-
-
+import java.lang.Math;
/**
* This class manages AI of L2Attackable.
*
@@ -80,18 +80,16 @@
{
super(accessor);
- _attack_timeout = Integer.MAX_VALUE;
+ _attack_timeout = java.lang.Math.min(Integer.MAX_VALUE,MAX_ATTACK_TIMEOUT);
_globalAggro = -10; // 10 seconds timeout of ATTACK after respawn
attackRange = ((L2Attackable)_actor).getPhysicalAttackRange();
}
-
public void run()
{
// Launch actions corresponding to the Event Think
onEvtThink();
-
}
/**
@@ -163,11 +161,17 @@
// Check if actor is not dead
if(!_actor.isAlikeDead())
{
- L2Attackable npc = (L2Attackable)_actor;
-
+ // remove from knownlist all dead or alikedead players
+ for(L2PcInstance in:((L2Attackable)_actor).getKnownList().getKnownPlayers())
+ {
+ if(in.isAlikeDead()) ((L2Attackable)_actor).getKnownList().removeKnownObject(in);
+ }
+
// If its _knownPlayer isn't empty set the Intention to AI_INTENTION_ACTIVE
- if(npc.getKnownList().getKnownPlayers().size() > 0)
+ if(((L2Attackable)_actor).getKnownList().getKnownPlayers().size() > 0)
+ {
intention = AI_INTENTION_ACTIVE;
+ }
else
intention = AI_INTENTION_IDLE;
}
@@ -197,7 +201,7 @@
// If not idle - create an AI task (schedule onEvtThink repeatedly)
if (aiTask == null)
{
- aiTask = ClientScheduler.getInstance().scheduleLowAtFixedRate(this, 1000, 1000);
+ aiTask = ClientScheduler.getInstance().scheduleAiAtFixedRate(this, 1000, 1000);
}
}
@@ -562,11 +566,22 @@
{
// if(getIntention() != AI_INTENTION_IDLE && (!_actor.isVisible() || !_actor.hasAI() || !_actor.isKnownPlayers()))
// setIntention(AI_INTENTION_IDLE);
+
+ // Check if the actor can't use skills and if a thinking action isn't already in progress
+ if (thinking || _actor.isAllSkillsDisabled())
+ return;
+
+ if((!_actor.isVisible()) || (!_actor.hasAI()))
+ setIntention(AI_INTENTION_IDLE);
+ if((getIntention() == AI_INTENTION_FOLLOW) && (_actor.getKnownList().getKnownPlayers().isEmpty()))
+ setIntention(AI_INTENTION_IDLE);
+
+ if(getIntention() == AI_INTENTION_IDLE)
+ return;
+
// Check if the actor can't use skills and if a thinking action isn't already in progress
- if (thinking || _actor.isAllSkillsDisabled())
- return;
-
+
// Start thinking action
thinking = true;
@@ -599,6 +614,12 @@
*/
protected void onEvtAttacked(L2Character attacker)
{
+ if(attacker==null)
+ {
+ _log.warning("L2SiegeGuardAI.java: onEvtAttacked(L2Character attacker) -> attacker=null, RETURNING with setting attacktimeout");
+ _attack_timeout = GameTimeController.getGameTicks();
+ return;
+ }
// Calculate the attack timeout
_attack_timeout = MAX_ATTACK_TIMEOUT + GameTimeController.getGameTicks();
@@ -655,9 +676,8 @@
if (!_actor.isRunning())
_actor.setRunning();
- L2SiegeGuardInstance sGuard = (L2SiegeGuardInstance)_actor;
- double homeX = target.getX() - sGuard.getHomeX();
- double homeY = target.getY() - sGuard.getHomeY();
+ double homeX = target.getX() - ((L2SiegeGuardInstance)_actor).getHomeX();
+ double homeY = target.getY() - ((L2SiegeGuardInstance)_actor).getHomeY();
// Check if the L2SiegeGuardInstance is not too far from its home location
if (homeX*homeX+homeY*homeY < 1200*1200)
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/AbstractAI.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/AbstractAI.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/AbstractAI.java (working copy)
@@ -714,7 +714,7 @@
// Create and Launch an AI Follow Task to execute every 1s
_follow_target = target;
- _follow_task = ClientScheduler.getInstance().scheduleMedAtFixedRate(new FollowTask(), 5, FOLLOW_INTERVAL);
+ _follow_task = ClientScheduler.getInstance().scheduleAiAtFixedRate(new FollowTask(), 5, FOLLOW_INTERVAL);
}
/**
@@ -732,7 +732,7 @@
}
_follow_target = target;
- _follow_task = ClientScheduler.getInstance().scheduleMedAtFixedRate(new FollowTask(range), 5, ATTACK_FOLLOW_INTERVAL);
+ _follow_task = ClientScheduler.getInstance().scheduleAiAtFixedRate(new FollowTask(range), 5, ATTACK_FOLLOW_INTERVAL);
}
/**
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/RecipeController.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/RecipeController.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/RecipeController.java (working copy)
@@ -16,8 +16,20 @@
*
* http://www.gnu.org/copyleft/gpl.html
*/
+
+
+
+
+
package net.sf.l2j.gameserver;
-
+/////
+////
+///
+// This file is now overcomented to explain all the changes
+// in detail. Feel free to remove them if it makes you happy
+///
+////
+/////
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
@@ -55,524 +67,690 @@
public class RecipeController
{
- protected static Logger _log = Logger.getLogger(RecipeController.class.getName());
- private static RecipeController _instance;
+ protected static Logger _log = Logger.getLogger(RecipeController.class.getName());
+ private static RecipeController _instance;
+
+ private Map _lists;
+
+ protected static Map activeMakers = Collections.synchronizedMap(new WeakHashMap());
- private Map _lists;
-
- protected static Map activeMakers = Collections.synchronizedMap(new WeakHashMap());
-
protected static final Random _rnd = new Random();
-
- public static RecipeController getInstance()
- {
- if (_instance == null)
- {
- _instance = new RecipeController();
- }
- return _instance;
- }
-
- public RecipeController()
- {
- _lists = new FastMap();
- String line = null;
- LineNumberReader lnr = null;
-
- try
- {
- File recipesData = new File(Config.DATAPACK_ROOT, "data/recipes.csv");
- lnr = new LineNumberReader(new BufferedReader( new FileReader(recipesData)));
-
- while ((line=lnr.readLine()) != null)
- {
- if (line.trim().length() == 0 || line.startsWith("#"))
- {
- continue;
- }
-
- parseList(line);
-
- }
- _log.config("RecipeController: Loaded "+_lists.size()+" Recipes.");
- }
- catch (Exception e)
- {
- if (lnr != null)
- {
- _log.log(Level.WARNING, "error while creating recipe controller in linenr: "+lnr.getLineNumber(), e);
- }
- else
- {
- _log.warning("No recipes were found in data folder");
- }
- }
+
+ public static RecipeController getInstance()
+ {
+ if (_instance == null)
+ {
+ _instance = new RecipeController();
+ }
+ return _instance;
+ }
+
+ public RecipeController()
+ {
+ _lists = new FastMap();
+ String line = null;
+ LineNumberReader lnr = null;
+
+ try
+ {
+ File recipesData = new File(Config.DATAPACK_ROOT, "data/recipes.csv");
+ lnr = new LineNumberReader(new BufferedReader( new FileReader(recipesData)));
+
+ while ((line=lnr.readLine()) != null)
+ {
+ if (line.trim().length() == 0 || line.startsWith("#"))
+ {
+ continue;
+ }
+
+ parseList(line);
+
+ }
+ _log.config("RecipeController: Loaded "+_lists.size()+" Recipes.");
+ }
+ catch (Exception e)
+ {
+ if (lnr != null)
+ {
+ _log.log(Level.WARNING, "error while creating recipe controller in linenr: "+lnr.getLineNumber(), e);
+ }
+ else
+ {
+ _log.warning("No recipes were found in data folder");
+ }
+ }
finally
{
try { lnr.close(); } catch (Exception e) { }
}
- }
-
- public int getRecipesCount()
- {
- return _lists.size();
- }
-
- public L2RecipeList getRecipeList(int listId)
- {
- return _lists.get(listId);
- }
-
- public L2RecipeList getRecipeByItemId(int itemId)
- {
- for (int i = 0; i < _lists.size(); i++)
- {
- L2RecipeList find = _lists.get(new Integer(i));
- if (find.getRecipeId() == itemId)
- {
- return find;
- }
- }
- return null;
- }
-
- public synchronized void requestBookOpen(L2PcInstance player)
- {
- if (!Config.ALT_GAME_CREATION){
- RecipeBookItemList response = new RecipeBookItemList();
- response.addRecipes(player.getRecipeBook());
- player.sendPacket(response);
- return;
- }
- ReceipeItemMaker maker = activeMakers.get(player);
+ }
+
+ public int getRecipesCount()
+ {
+ return _lists.size();
+ }
+ public L2RecipeList getRecipeList(int listId)
+ {
+ return _lists.get(listId);
+ }
+ public L2RecipeList getRecipeByItemId(int itemId)
+ {
+ for (int i = 0; i < _lists.size(); i++)
+ {
+ L2RecipeList find = _lists.get(new Integer(i));
+ if (find.getRecipeId() == itemId)
+ {
+ return find;
+ }
+ }
+ return null;
+ }
+
+ public synchronized void requestBookOpen(L2PcInstance player)
+ {
+ RecipeItemMaker maker=null;
+
+ // @@todo: this must be removed, but also made sure it will happen only if realy crafting
+ if (Config.ALT_GAME_CREATION)
+ {
+ maker = activeMakers.get(player);
+ if(!player.isInCraftMode() && maker!=null)
+ {
+ activeMakers.remove(player);
+ if (Config.DEBUG)
+ _log.fine("removed "+player.getName()+" from activeMakers by force, trust only isInCraftMode for acurate state");
+ }
+ }
+
if (maker == null) {
- RecipeBookItemList response = new RecipeBookItemList();
- response.addRecipes(player.getRecipeBook());
- player.sendPacket(response);
- return;
+ RecipeBookItemList response = new RecipeBookItemList();
+ response.addRecipes(player.getRecipeBook());
+ player.sendPacket(response);
+ return;
}
- if (maker.timeReady <= GameTimeController.getGameTicks()) {
- maker.run();
- return;
- }
+
+ if (Config.DEBUG) _log.fine("requestBookOpen: Busy creating");
SystemMessage sm = new SystemMessage(614);
sm.addString("You are busy creating ");
sm.addItemName(maker.recipeList.getItemId());
player.sendPacket(sm);
return;
- }
-
- public synchronized void requestManufactureItem(L2PcInstance manufacturer, int recipeListId, L2PcInstance player)
- {
- L2RecipeList recipeList = getRecipeList(recipeListId-1);
-
- SystemMessage sm = new SystemMessage(614);
+ }
+
+ public synchronized void requestManufactureItem(L2PcInstance manufacturer, int recipeListId, L2PcInstance customer)
+ {
+ L2RecipeList recipeList = getRecipeList(recipeListId-1);
+ SystemMessage sm = new SystemMessage(614);
- manufacturer.isInCraftMode(true);
- if ((recipeList == null) || (recipeList.getRecipes().length == 0))
- {
- sm = new SystemMessage(614);
- sm.addString("No recipe for: " + recipeListId);
- player.sendPacket(sm);
- manufacturer.isInCraftMode(false);
- return;
- }
- if (!Config.ALT_GAME_CREATION) {
- new ReceipeItemMaker(manufacturer, recipeList, player);
- } else {
- ReceipeItemMaker maker = activeMakers.get(manufacturer);
- if (maker != null)
- {
- sm = new SystemMessage(614);
- sm.addString("Manufacturer are busy creating.");
- sm.addItemName(recipeList.getItemId());
- player.sendPacket(sm);
- manufacturer.isInCraftMode(false);
- return;
- }
- maker = new ReceipeItemMaker(manufacturer, recipeList, player);
- if (maker.isValid)
- activeMakers.put(manufacturer, maker);
- }
- }
- public synchronized void requestMakeItem(L2PcInstance player, int recipeListId)
- {
- L2RecipeList recipeList = getRecipeList(recipeListId-1);
-
- SystemMessage sm = new SystemMessage(614);
+ if(manufacturer.isInCraftMode())
+ {
+ if(Config.DEBUG) _log.fine("requestManufactureItem called but manufacturer is in craft mode");
+ sm = new SystemMessage(614);
+ sm.addString("Manufacturer is busy.");
+ sm.addItemName(recipeList.getItemId());
+ customer.sendPacket(sm);
+ return;
+ }
- player.isInCraftMode(true);
- if ((recipeList == null) || (recipeList.getRecipes().length == 0))
- {
- sm = new SystemMessage(614);
- sm.addString("No recipe for: " + recipeListId);
- player.sendPacket(sm);
- player.isInCraftMode(false);
- return;
- }
- if (!Config.ALT_GAME_CREATION) {
- new ReceipeItemMaker(player, recipeList, null);
- } else {
- ReceipeItemMaker maker = activeMakers.get(player);
- if (maker != null)
- {
- sm = new SystemMessage(614);
- sm.addString("You are busy creating ");
- sm.addItemName(recipeList.getItemId());
- player.sendPacket(sm);
- player.isInCraftMode(false);
- return;
- }
- maker = new ReceipeItemMaker(player, recipeList, null);
- if (maker.isValid)
- activeMakers.put(player, maker);
- }
- }
-
- public synchronized void requestMakeItemAbort(L2PcInstance player)
- {
- activeMakers.remove(player);
- }
-
- private void parseList(String line)
- {
- StringTokenizer st = new StringTokenizer(line,";");
- List recipePartList = new FastList();
-
- String recipeName = st.nextToken();
- int id = Integer.parseInt(st.nextToken());
- int recipeId = Integer.parseInt(st.nextToken());
- int level = Integer.parseInt(st.nextToken());
-
- //material
- StringTokenizer st2 = new StringTokenizer(st.nextToken(), "[],");
- while (st2.hasMoreTokens())
- {
- StringTokenizer st3 = new StringTokenizer(st2.nextToken(), "()");
- int rpItemId = Integer.parseInt(st3.nextToken());
- int quantity = Integer.parseInt(st3.nextToken());
- L2RecipeInstance rp = new L2RecipeInstance(rpItemId, quantity);
- recipePartList.add(rp);
- //recipe.addRecipe(rp);
- }
-
- int itemId = Integer.parseInt(st.nextToken());
- int count = Integer.parseInt(st.nextToken());
-
- //npc fee
- /*String notdoneyet = */ st.nextToken();
-
- int mpCost = Integer.parseInt(st.nextToken());
- int successRate = Integer.parseInt(st.nextToken());
-
- L2RecipeList recipeList = new L2RecipeList(id,level,recipeId,recipeName,successRate,mpCost,itemId,count);
- for (L2RecipeInstance recipePart : recipePartList)
- {
- recipeList.addRecipe(recipePart);
- }
- _lists.put(new Integer(_lists.size()), recipeList);
- }
-
-
-
-
- class ReceipeItemMaker implements Runnable
- {
- int timeReady;
- final L2PcInstance player;
- final L2PcInstance target;
- final L2RecipeList recipeList;
- final List items;
- int materialsRefPrice;
- int totalItems;
- int usedItems;
- int price;
- boolean isValid;
-
- ReceipeItemMaker(L2PcInstance player, L2RecipeList recipeList, L2PcInstance target )
- {
- this.player = player;
- this.target = target;
- this.recipeList = recipeList;
- this.items = new FastList();
-
- int skillLevel = player.getSkillLevel(L2Skill.SKILL_CRAFTING);
- if (skillLevel <= 0)
- {
- player.sendPacket(new ActionFailed());
- player.isInCraftMode(false);
- return;
- }
-
- if ((recipeList == null) || (recipeList.getRecipes().length == 0))
- {
- SystemMessage sm = new SystemMessage(614);
- sm.addString("No such recipe");
- player.sendPacket(sm);
- player.isInCraftMode(false);
- return;
- }
-
- if (target != null)
- {
- for (L2ManufactureItem temp : player.getCreateList().getList())
- {
- if (temp.getRecipeId() == recipeList.getId())
- {
- price = temp.getCost();
- if (target.getAdena() < price)
- {
- target.sendPacket(new SystemMessage(SystemMessage.YOU_NOT_ENOUGH_ADENA));
- player.isInCraftMode(false);
- return;
- }
- break;
- }
- }
- }
- if (recipeList.getLevel()>skillLevel)
- {
- SystemMessage sm = new SystemMessage(614);
- sm.addString("Need skill level "+recipeList.getLevel());
- player.sendPacket(sm);
- player.isInCraftMode(false);
- return;
- }
- /*
- if (recipeList.getAdenaCost()>activeChar.getAdena())
- {
- SystemMessage sm = new SystemMessage(614);
- sm.addString("Need "+recipeList.getAdenaCost()+" Adena");
- activeChar.sendPacket(sm);
- return;
- }*/
-
- L2RecipeInstance[] recipes = recipeList.getRecipes();
-
- Inventory inv = null;
- if (target == null)
- inv = player.getInventory();
- else
- inv = target.getInventory();
-
- for (L2RecipeInstance recipe : recipes)
- {
- if (recipe.getQuantity() != 0)
- {
- L2ItemInstance invItem = inv.getItemByItemId(recipe.getItemId());
- if ((invItem == null) || (recipe.getQuantity()>invItem.getCount()))
- {
- SystemMessage sm = new SystemMessage(614);
- sm.addString("You dont have the right elements for making this item");
- if (target == null)
- player.sendPacket(sm);
- else
- target.sendPacket(sm);
- player.isInCraftMode(false);
- return;
- }
- }
- }
-
- if (!Config.ALT_GAME_CREATION)
- {
- if (player.getCurrentMp() < recipeList.getMpCost())
- {
- if (Config.DEBUG) _log.fine("not enough mana");
- SystemMessage sm = new SystemMessage(SystemMessage.NOT_ENOUGH_MP);
- if (target == null)
- player.sendPacket(sm);
- else
- target.sendPacket(sm);
- timeReady = GameTimeController.getGameTicks();
- player.isInCraftMode(false);
- return;
- }
- }
-
- for (L2RecipeInstance recipe : recipes)
- {
- if (recipe.getQuantity() != 0)
- {
- L2ItemInstance invItem = inv.getItemByItemId(recipe.getItemId());
- invItem = inv.dropItem(invItem, recipe.getQuantity());
- items.add(invItem);
- materialsRefPrice += invItem.getReferencePrice()*invItem.getCount();
- totalItems += invItem.getCount();
- }
- }
-
- isValid = true;
-
- timeReady = GameTimeController.TICKS_PER_SECOND + GameTimeController.getGameTicks();
- ClientScheduler.getInstance().scheduleLow(this, 1100);
- }
-
- public void run()
- {
- player.isInCraftMode(true);
+ // now we can allow crafting
+ manufacturer.isInCraftMode(true);
+
+ if ((recipeList == null) || (recipeList.getRecipes().length == 0))
+ {
+ _log.warning("I bet this can never happen normally, "+
+ "cause customer can order only listed recipes, which are 100% in manufacturer's recipe book");
- if ( Config.IS_CRAFTING_ENABLED ) {
- double currentPlayerMp = player.getCurrentMp();
- if (currentPlayerMp < recipeList.getMpCost()) {
- if (Config.DEBUG) _log.fine("not enough mana");
- SystemMessage sm = new SystemMessage(SystemMessage.NOT_ENOUGH_MP);
- if (target == null)
- player.sendPacket(sm);
- else
- target.sendPacket(sm);
- timeReady = GameTimeController.getGameTicks();
- player.isInCraftMode(false);
- return;
- }
-
- int gameTicks = GameTimeController.getGameTicks();
- if (timeReady > gameTicks)
+ sm = new SystemMessage(614);
+ sm.addString("No recipe for: " + recipeListId);
+ customer.sendPacket(sm);
+ manufacturer.isInCraftMode(false);
+ return;
+ }
+
+ if (Config.ALT_GAME_CREATION)
+ {
+ RecipeItemMaker maker = activeMakers.get(manufacturer);
+ if (maker != null)
+ {
+ if(!manufacturer.isInCraftMode())
{
- player.isInCraftMode(false);
- return;
+ if(Config.DEBUG)
+ {
+ _log.fine(maker.manufacturer.getName() + " is in activeMakers but not IsInCraftmode");
+ _log.fine("decision: isincraftmode() is right, activeMakers wrong, removing from activeMakers");
+ }
+ activeMakers.remove(manufacturer);
+ } else
+ {
+ sm = new SystemMessage(614);
+ sm.addString("Manufacturer is busy.");
+ sm.addItemName(recipeList.getItemId());
+ customer.sendPacket(sm);
+ manufacturer.isInCraftMode(false);
+ return;
}
-
- timeReady = gameTicks + (int)(15 * player.getMReuseRate(player.getKnownSkill(172)) * GameTimeController.TICKS_PER_SECOND);
-
- if (!Config.ALT_GAME_CREATION || items.isEmpty()) {
- player.reduceCurrentMp(recipeList.getMpCost());
-
- StatusUpdate su = new StatusUpdate(player.getObjectId());
-
- L2ItemInstance createdItem = ItemTable.getInstance().createItem(recipeList.getItemId());
- createdItem.setCount(recipeList.getCount());
-
- int randCheck = _rnd.nextInt(100);
- if(recipeList.getSuccessRate() <= randCheck ) {
- SystemMessage sm = new SystemMessage(614);
- sm.addString("Item(s) failed to create");
- player.sendPacket(sm);
- player.isInCraftMode(false);
- }
- else {
- int createdItemCount = createdItem.getCount();
- SystemMessage sm = new SystemMessage(SystemMessage.EARNED_ITEM);
- sm.addItemName(createdItem.getItemId());
- sm.addNumber(createdItemCount);
- //sm.addString("Item(s) created");
- if (target == null)
- {
- player.getInventory().addItem(createdItem);
- player.sendPacket(sm);
- su.addAttribute(StatusUpdate.CUR_LOAD, player.getCurrentLoad());
- } else
- {
- if (price > 0) {
- target.reduceAdena(price);
- player.addAdena(price);
- L2ItemInstance adenaupdate = player.getInventory().findItemByItemId(57);
- InventoryUpdate iu = new InventoryUpdate();
- iu.addModifiedItem(adenaupdate);
- player.sendPacket(iu);
- SystemMessage sm2 = new SystemMessage(SystemMessage.DISSAPEARED_ADENA);
- sm2.addNumber(price);
- target.sendPacket(sm2);
- sm2 = new SystemMessage(SystemMessage.EARNED_ADENA);
- sm2.addNumber(price);
- player.sendPacket(sm2);
- }
- target.getInventory().addItem(createdItem);
- target.sendPacket(sm);
- StatusUpdate su2 = new StatusUpdate(target.getObjectId());
- su2.addAttribute(StatusUpdate.CUR_LOAD, target.getCurrentLoad());
- target.sendPacket(su2);
- }
-
-
- if (Config.ALT_GAME_CREATION) {
- int skillLevel = player.getSkillLevel(L2Skill.SKILL_CRAFTING);
- int receipeLevel = recipeList.getLevel();
- int exp = createdItem.getReferencePrice()*createdItemCount;
- // one variation
- exp -= materialsRefPrice;
- if (exp < 0) exp = 0;
- // another variation
- // exp /= receipeLevel
- for (int i=skillLevel; i > receipeLevel; i--)
- exp /= 4;
- int sp = exp / 10;
- player.addExpAndSp((int)player.calcStat(Stats.EXPSP_RATE, exp * Config.RATE_XP, null, null),
- (int)player.calcStat(Stats.EXPSP_RATE, sp * Config.RATE_SP, null, null));
- }
- }
- activeMakers.remove(player);
- player.isInCraftMode(false);
-
- su.addAttribute(StatusUpdate.CUR_MP, (int) player.getCurrentMp());
- player.sendPacket(su);
- if (target == null){
- player.sendPacket(new ItemList(player, false));
- player.sendPacket(new RecipeItemMakeInfo(recipeList.getId(),player));
- } else
- {
- target.sendPacket(new ItemList(target, false));
- target.sendPacket(new RecipeShopItemInfo(player.getObjectId(),recipeList.getId()));
- }
- }
- else {
- double currentMp = player.getCurrentMp();
- if (currentMp < recipeList.getMpCost()) {
- if (Config.DEBUG) _log.fine("not enough mana");
- SystemMessage sm = new SystemMessage(SystemMessage.NOT_ENOUGH_MP);
- if (target == null)
- player.sendPacket(sm);
- else
- target.sendPacket(sm);
- timeReady = GameTimeController.getGameTicks();
- player.isInCraftMode(false);
- return;
- }
- player.setCurrentMp(currentMp - recipeList.getMpCost());
-
- int numItems = player.getSkillLevel(172);
- while (numItems > 0 && !items.isEmpty()) {
- L2ItemInstance item = items.get(0);
-
- int count = item.getCount();
- if (count >= numItems) count = numItems;
-
- item.setCount(item.getCount() - count);
- if (item.getCount() <= 0) items.remove(0);
-
- numItems -= count;
- usedItems += count;
-
- SystemMessage sm = new SystemMessage(368);
- sm.addNumber(count);
- sm.addItemName(item.getItemId());
- if (target == null)
- player.sendPacket(sm);
- else
- target.sendPacket(sm);
-
- player.isInCraftMode(false);
- }
-
- int delay = (timeReady-gameTicks) * GameTimeController.MILLIS_IN_TICK;
- MagicSkillUser msk = new MagicSkillUser(player, 1050, 1, delay, 0);
- player.broadcastPacket(msk);
- SetupGauge sg = new SetupGauge(0, delay);
- player.sendPacket(sg);
-
- ClientScheduler.getInstance().scheduleLow(this, 100+delay);
- }
- }
- else {
- // crafting is disabled...
- SystemMessage sm = new SystemMessage(614);
- sm.addString("Crafting is currently disabled.");
- if (target == null)
- player.sendPacket(sm);
- else
- target.sendPacket(sm);
- player.isInCraftMode(false);
- }
- }
- }
+ }
+
+ maker = new RecipeItemMaker(manufacturer, recipeList, customer);
+
+ if (maker!=null && manufacturer!=null && maker.isValid)
+ activeMakers.put(manufacturer, maker);
+ } else // for regular crafting we don't use activeMakers
+ new RecipeItemMaker(manufacturer, recipeList, customer);
+ }
+ public synchronized void requestMakeItem(L2PcInstance manufacturer, int recipeListId)
+ {
+ L2RecipeList recipeList = getRecipeList(recipeListId-1);
+
+ SystemMessage sm = new SystemMessage(614);
+
+ if ((recipeList == null) || (recipeList.getRecipes().length == 0))
+ {
+ sm = new SystemMessage(614);
+ sm.addString("No recipe for: " + recipeListId);
+ manufacturer.sendPacket(sm);
+ return;
+ }
+
+ if(manufacturer.isInCraftMode())
+ {
+ sm = new SystemMessage(614);
+ sm.addString("You are busy creating ");
+ sm.addItemName(recipeList.getItemId());
+ manufacturer.sendPacket(sm);
+ return;
+ }
+
+ if (Config.ALT_GAME_CREATION)
+ {
+ RecipeItemMaker maker = activeMakers.get(manufacturer);
+ if (maker != null)
+ activeMakers.remove(manufacturer);
+
+ maker = new RecipeItemMaker(manufacturer, recipeList, null);
+
+ if (manufacturer!=null && maker!=null && maker.isValid)
+ activeMakers.put(manufacturer, maker);
+ } else
+ {
+ new RecipeItemMaker(manufacturer, recipeList, null);
+ }
+ }
+ public synchronized void requestMakeItemAbort(L2PcInstance manufacturer)
+ {
+ manufacturer.isInCraftMode(false);
+ if (Config.DEBUG) _log.fine(manufacturer.getName()+" IsInCraftMode(false)");
+
+ if(Config.ALT_GAME_CREATION && activeMakers!=null)
+ {
+ if(activeMakers.get(manufacturer)!=null) activeMakers.remove(manufacturer);
+ if (Config.DEBUG)
+ _log.fine("requestMakeItemAbort called - removing " +manufacturer.getName() +" from activeMakers ");
+ }
+ }
+
+ private void parseList(String line)
+ {
+ StringTokenizer st = new StringTokenizer(line,";");
+ List recipePartList = new FastList();
+
+ String recipeName = st.nextToken();
+ int id = Integer.parseInt(st.nextToken());
+ int recipeId = Integer.parseInt(st.nextToken());
+ int level = Integer.parseInt(st.nextToken());
+
+ //material
+ StringTokenizer st2 = new StringTokenizer(st.nextToken(), "[],");
+ while (st2.hasMoreTokens())
+ {
+ StringTokenizer st3 = new StringTokenizer(st2.nextToken(), "()");
+ int rpItemId = Integer.parseInt(st3.nextToken());
+ int quantity = Integer.parseInt(st3.nextToken());
+ L2RecipeInstance rp = new L2RecipeInstance(rpItemId, quantity);
+ recipePartList.add(rp);
+ //recipe.addRecipe(rp);
+ }
+
+ int itemId = Integer.parseInt(st.nextToken());
+ int count = Integer.parseInt(st.nextToken());
+
+ //npc fee
+ /*String notdoneyet = */ st.nextToken();
+
+ int mpCost = Integer.parseInt(st.nextToken());
+ int successRate = Integer.parseInt(st.nextToken());
+
+ L2RecipeList recipeList = new L2RecipeList(id,level,recipeId,recipeName,successRate,mpCost,itemId,count);
+ for (L2RecipeInstance recipePart : recipePartList)
+ {
+ recipeList.addRecipe(recipePart);
+ }
+ _lists.put(new Integer(_lists.size()), recipeList);
+ }
+
+ class RecipeItemMaker implements Runnable
+ {
+ int timeReady;
+ final L2PcInstance manufacturer;
+ final L2PcInstance customer;
+ final L2RecipeList recipeList;
+ final List items;
+ final int skillLevel;
+ int creationPasses;
+ int materialsRefPrice;
+ int totalItems;
+ int usedItems;
+ int price;
+ boolean isValid;
+
+
+ RecipeItemMaker(L2PcInstance manufacturer, L2RecipeList recipeList, L2PcInstance customer )
+ {
+ this.manufacturer = manufacturer;
+ this.customer = customer;
+ this.recipeList = recipeList;
+ this.items = new FastList();
+ this.skillLevel = manufacturer.getSkillLevel(L2Skill.SKILL_CRAFTING);
+
+ // crafting is disabled...
+ if (!Config.IS_CRAFTING_ENABLED)
+ {
+ SystemMessage sm = new SystemMessage(614);
+ sm.addString("Crafting is currently disabled.");
+ if (customer == null)
+ manufacturer.sendPacket(sm);
+ else
+ customer.sendPacket(sm);
+ manufacturer.isInCraftMode(false);
+ return;
+ }
+
+ if (manufacturer.isInCraftMode())
+ {
+ if(Config.DEBUG) _log.fine("manufacturer.isInCraftMode()==true, in RecipeItemMaker constructor");
+ SystemMessage sm = new SystemMessage(614);
+
+ if (customer == null)
+ {
+ sm.addString("You are busy crafting");
+ manufacturer.sendPacket(sm);
+ }
+ else
+ {
+ sm.addString("Manufacturer is busy crafting");
+ customer.sendPacket(sm);
+ };
+ return;
+ }
+
+ if (skillLevel <= 0)
+ {
+ manufacturer.sendPacket(new ActionFailed());
+ manufacturer.isInCraftMode(false);
+
+ if(customer!=null)
+ {
+ customer.sendPacket(new ActionFailed());
+ if(Config.DEBUG)
+ _log.warning("skillLevel <= 0 and customer!=null, so why can manufacturer open manufacture shop if he has no skill?");
+ }
+ return;
+ }
+
+ if ((recipeList == null) || (recipeList.getRecipes().length == 0))
+ {
+ SystemMessage sm = new SystemMessage(614);
+ sm.addString("No such recipe");
+ manufacturer.sendPacket(sm);
+
+ if(customer!=null)
+ {
+ customer.sendPacket(sm);
+ if(Config.DEBUG)
+ _log.warning("customer!=null, so why can manufacturer offer manufacture for item if he has no recipe ?");
+ }
+
+ return;
+ }
+
+ if (customer != null)
+ {
+ for (L2ManufactureItem temp : manufacturer.getCreateList().getList())
+ if (temp.getRecipeId() == recipeList.getId())
+ {
+ price = temp.getCost();
+ if (customer.getAdena() < price)
+ {
+ customer.sendPacket(new SystemMessage(SystemMessage.YOU_NOT_ENOUGH_ADENA));
+ return;
+ }
+ break;
+ }
+ }
+
+ if (recipeList.getLevel()>skillLevel)
+ {
+ SystemMessage sm = new SystemMessage(614);
+ sm.addString("Need skill level "+recipeList.getLevel());
+ manufacturer.sendPacket(sm);
+ return;
+ }
+
+ L2RecipeInstance[] recipes = recipeList.getRecipes();
+
+ Inventory inv = null;
+
+ if (customer == null)
+ inv = manufacturer.getInventory();
+ else
+ inv = customer.getInventory();
+
+ for (L2RecipeInstance recipe : recipes)
+ {
+ if (recipe.getQuantity() != 0)
+ {
+ L2ItemInstance invItem = inv.getItemByItemId(recipe.getItemId());
+ if ((invItem == null) || (recipe.getQuantity()>invItem.getCount()))
+ {
+ SystemMessage sm = new SystemMessage(614);
+ sm.addString("You dont have the right elements for making this item");
+
+ if (customer == null) manufacturer.sendPacket(sm);
+ else customer.sendPacket(sm);
+
+ return;
+ }
+ }
+ }
+
+ if (manufacturer.getCurrentMp() < recipeList.getMpCost())
+ {
+ if (Config.DEBUG) _log.fine("not enough mana in RecipeItemMaker constructor");
+ SystemMessage sm = new SystemMessage(SystemMessage.NOT_ENOUGH_MP);
+ if (customer == null)
+ manufacturer.sendPacket(sm);
+ else
+ customer.sendPacket(sm);
+
+ return;
+ }
+
+ creationPasses=0;
+ for (L2RecipeInstance recipe : recipes)
+ {
+ if (recipe.getQuantity() != 0)
+ {
+ L2ItemInstance invItem = inv.getItemByItemId(recipe.getItemId());
+ invItem = inv.dropItem(invItem, recipe.getQuantity());
+ items.add(invItem);
+ materialsRefPrice += invItem.getReferencePrice()*invItem.getCount();
+ totalItems += invItem.getCount();
+ creationPasses+=invItem.getCount()/skillLevel;
+ if((invItem.getCount()%skillLevel)>0) creationPasses++;
+ }
+ }
+
+ if(Config.DEBUG)
+ {
+ _log.warning("calculated creation passes: "+creationPasses);
+
+ if(creationPasses==0)
+ {
+ creationPasses++;
+ _log.warning("creationPasses was ZERO so creationPasses++ and it is now " + creationPasses);
+ }
+ }
+ isValid = true;
+
+ manufacturer.isInCraftMode(true); // here we say craf mode started, no reason to do it sooner, just makes problems
+
+ //ClientScheduler.scheduleCraftAction(this, 100);
+ run(); // for not-alternative crafting -> no reason why not craft immediately, cause it uses really little cpu
+ // and will never make lag ... scheduled things tend to make lag, things that are immediately done don't if you
+ // have sufficient cpu anyway ... how long can craft take ? few nanoseconds ?
+ // and for ALT_CRAFTING=true, first run is innitial, and takes no time also, and on end, if needed, another run
+ // is scheduled
+
+ }
+ public void run()
+ {
+ if (!Config.ALT_GAME_CREATION || items.isEmpty()) // this method does the actual creation of item,
+ { // it is called immediately for normal crafting,
+ completeCreation(); // cause normal crafting does not take time, bug gives no XP/SP
+ manufacturer.isInCraftMode(false); // for ALT_CRAFTING it is called only when all items are "equiped"
+ // thru multiple scheduled runs using
+ // ClientScheduler.ScheduleCraftAction() - separate thread pool
+ // there should be no thread launching at all
+
+ if(Config.DEBUG)
+ {
+ _log.warning("MP_Cost: "+recipeList.getMpCost()+" ");
+ _log.warning("passes: "+creationPasses+" ");
+ _log.warning("mana/pass:"+recipeList.getMpCost()/creationPasses+" ");
+ _log.warning("error: "+(recipeList.getMpCost()-((recipeList.getMpCost()/creationPasses)*creationPasses)));
+ }
+
+ return;
+ }
+
+
+ // all this code is for ALT_GAME_CREATION only
+ // previous code was very confusing, which led
+ // to "craft lag" due to misunderstanding of
+ // "crafting" in normal mode.
+ // normal mode takes no time but gives no XP/SP
+ // ALT_MODE takes time but gives XP/SP as reward
+ // ---------------------------------------------
+ // run() is scheduled multiple times,
+ // (equiping) skillLevel items on every run, until
+ // all items are "equiped", and then on next run,
+ // completeCreation() will produce the result
+ // and remove equiped materials from inventory
+ //
+ // on every run() part of mana is deducted from
+ // manufacturer, amount is calculated as sum of
+ // all item counts from recipe.
+
+ double currentManufacturerMp = manufacturer.getCurrentMp(); // we need player to have only mana needed
+ if (currentManufacturerMp < ((double)recipeList.getMpCost()/(double)creationPasses))
+ { // for this pass, next pass is in 1 second
+ if (Config.DEBUG) _log.warning("not enough mana in run()"); // so we can allow mp regen to help manufacturer
+ SystemMessage sm = new SystemMessage(SystemMessage.NOT_ENOUGH_MP);
+ if (customer == null)
+ manufacturer.sendPacket(sm);
+ else
+ customer.sendPacket(sm);
+
+ manufacturer.isInCraftMode(false);
+ activeMakers.remove(manufacturer);
+ return;
+ }
+
+
+ manufacturer.reduceCurrentMp((double)recipeList.getMpCost()/(double)creationPasses);
+
+ int numItems = skillLevel;
+
+ while (numItems > 0 && !items.isEmpty()) // equip # of items we can in one run()
+ { // if players complain they lose items during craft on server crashes, try
+ L2ItemInstance item = items.get(0); // not to item.remove(), but instead copy it somehow and return if crafting
+ int count = item.getCount(); // did not finish for some reason ?? umh don't know how it works really
+ // when is sql db updated ? all the time ? sometimes ?
+
+ if (count >= numItems) count = numItems;
+ item.setCount(item.getCount() - count);
+ if (item.getCount() <= 0) items.remove(0);
+ numItems -= count;
+ usedItems += count;
+
+ SystemMessage sm = new SystemMessage(368);
+ sm.addNumber(count);
+ sm.addItemName(item.getItemId());
+
+ if (customer == null) manufacturer.sendPacket(sm);
+ else customer.sendPacket(sm);
+ }
+
+ int delay = ((int)(manufacturer.getMReuseRate(manufacturer.getKnownSkill(L2Skill.SKILL_CRAFTING)) * GameTimeController.TICKS_PER_SECOND)) * GameTimeController.MILLIS_IN_TICK;
+
+ MagicSkillUser msk = new MagicSkillUser(manufacturer, 1050, 1, delay, 0);
+ manufacturer.broadcastPacket(msk);
+
+ SetupGauge sg = new SetupGauge(0, delay);
+ manufacturer.sendPacket(sg);
+
+ StatusUpdate su = new StatusUpdate(manufacturer.getObjectId());
+ su.addAttribute(StatusUpdate.CUR_MP, (int) manufacturer.getCurrentMp());
+ manufacturer.sendPacket(su);
+// // this works but it makes craft of level1 items very fast for alt mode ... uhm
+// // I'd allow that, cause crafting "braided hemp" is not very fun and you need to do it
+// // in huge quantities, even if you are high level, so you get no XP/SP
+// // but it's not my call
+// if (items.isEmpty())
+// {
+// if(Config.DEBUG) _log.fine("saved "+delay+" miliseconds");
+// completeCreation();
+// manufacturer.isInCraftMode(false);
+// activeMakers.remove(manufacturer);
+// } else
+ ClientScheduler.scheduleCraftAction(this, 1+delay); // Craft thread pool has nothing to do with other pools, so
+ // only way this can make any kind of lag is when CPU usage is 100%
+ // when nobody is "in craft mode" scheduled tasks for
+ // craft thread pool must be 0 or we have a bug again :/
+ }
+
+ private void completeCreation() // this is where real item production is done
+ {
+ int createdItemCount=0;
+ if(Config.DEBUG)
+ _log.fine(manufacturer.getName()+" : completeCreation() ");
+
+ if(!Config.ALT_GAME_CREATION) // we reduce Mp in run() for ALT_GAME_CREATION
+ manufacturer.reduceCurrentMp(recipeList.getMpCost());
+
+ StatusUpdate su = new StatusUpdate(manufacturer.getObjectId());
+
+ L2ItemInstance createdItem = ItemTable.getInstance().createItem(recipeList.getItemId());
+ createdItem.setCount(recipeList.getCount());
+
+ int randCheck = _rnd.nextInt(100);
+
+ if(recipeList.getSuccessRate() <= randCheck )
+ {
+ SystemMessage sm = new SystemMessage(614);
+ sm.addString("Item(s) failed to create");
+ manufacturer.sendPacket(sm);
+ manufacturer.isInCraftMode(false);
+ if(Config.ALT_GAME_CREATION && activeMakers.get(manufacturer)!=null) activeMakers.remove(manufacturer);
+ } else
+ { // item succesfully created
+ createdItemCount = createdItem.getCount();
+ SystemMessage sm = new SystemMessage(SystemMessage.EARNED_ITEM);
+ sm.addItemName(createdItem.getItemId());
+ sm.addNumber(createdItemCount);
+
+ if (customer == null)
+ {
+ manufacturer.getInventory().addItem(createdItem);
+ manufacturer.sendPacket(sm);
+ su.addAttribute(StatusUpdate.CUR_LOAD, manufacturer.getCurrentLoad());
+ } else
+ {
+ if (price > 0)
+ {
+ customer.reduceAdena(price);
+ manufacturer.addAdena(price);
+ L2ItemInstance adenaupdate = manufacturer.getInventory().findItemByItemId(57);
+ InventoryUpdate iu = new InventoryUpdate();
+ iu.addModifiedItem(adenaupdate);
+ manufacturer.sendPacket(iu);
+ SystemMessage sm2 = new SystemMessage(SystemMessage.DISSAPEARED_ADENA);
+ sm2.addNumber(price);
+ customer.sendPacket(sm2);
+ sm2 = new SystemMessage(SystemMessage.EARNED_ADENA);
+ sm2.addNumber(price);
+ manufacturer.sendPacket(sm2);
+ }
+
+ customer.getInventory().addItem(createdItem);
+ customer.sendPacket(sm);
+ StatusUpdate su2 = new StatusUpdate(customer.getObjectId());
+ su2.addAttribute(StatusUpdate.CUR_LOAD, customer.getCurrentLoad());
+ customer.sendPacket(su2);
+ }
+ }
+
+ if (Config.ALT_GAME_CREATION)
+ {
+ int RecipeLevel = recipeList.getLevel();
+ int exp;
+ int sp;
+
+ // if sitting, default formula, standing my new formula based on MP used to craft item(s)
+ if(!Config.ALT_GAME_CREATION_BY_MANA) // standard formula, tried to fix but no luck
+ {
+ exp = createdItem.getReferencePrice()*createdItemCount;
+ // ensure at least some profit
+ materialsRefPrice=(int)((double)materialsRefPrice*(double)0.96);
+
+ // one variation
+ if(Config.DEBUG)
+ {
+ _log.fine("BASED ON ITEM PRICE - MATERIALS PRICE");
+ _log.fine("createdItemCount: "+createdItemCount);
+ _log.fine("exp: "+exp);
+ _log.fine("referent price: "+createdItem.getReferencePrice());
+ _log.fine("referent total: "+createdItem.getReferencePrice()*createdItemCount);
+ _log.fine("materials price: "+materialsRefPrice);
+ _log.fine("exp: "+(exp-materialsRefPrice));
+ }
+
+ exp -= materialsRefPrice;
+
+ if (exp < 0) exp = 0;
+
+ exp/=RecipeLevel;
+
+ for (int i=skillLevel; i > RecipeLevel; i--) exp /= 4;
+
+ sp = exp / 10;
+
+ if(Config.DEBUG) _log.fine("exp with mods: "+exp);
+
+ } else
+ {
+ exp=2*(recipeList.getLevel() * recipeList.getMpCost())
+ /skillLevel;
+
+ sp = exp / 10;
+
+ // one variation
+ if(Config.DEBUG)
+ {
+ _log.fine("NEW METHOD - BASED ON MANA");
+ _log.fine("createdItemCount: "+createdItemCount);
+ _log.fine("exp: "+exp);
+ }
+
+ }
+ manufacturer.addExpAndSp((int)manufacturer.calcStat(Stats.EXPSP_RATE, exp * Config.RATE_XP, null, null),
+ (int)manufacturer.calcStat(Stats.EXPSP_RATE, sp * Config.RATE_SP, null, null));
+
+ if(activeMakers.get(manufacturer)!=null) activeMakers.remove(manufacturer);
+ }
+
+ manufacturer.isInCraftMode(false);
+
+ su.addAttribute(StatusUpdate.CUR_MP, (int) manufacturer.getCurrentMp());
+ manufacturer.sendPacket(su);
+ if (customer == null){
+ manufacturer.sendPacket(new ItemList(manufacturer, false));
+ manufacturer.sendPacket(new RecipeItemMakeInfo(recipeList.getId(),manufacturer));
+ } else
+ {
+ customer.sendPacket(new ItemList(customer, false));
+ customer.sendPacket(new RecipeShopItemInfo(manufacturer.getObjectId(),recipeList.getId()));
+ }
+ }
+ }
}
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ClientScheduler.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ClientScheduler.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ClientScheduler.java (working copy)
@@ -31,16 +31,6 @@
import net.sf.l2j.Config;
import net.sf.l2j.gameserver.clientpackets.ClientBasePacket;
-/**
- * This class permit to create 3 Threads pools and to add to it tasks to execute in function of their priority (HIGH, MEDIUM,LOW).
- *
- * Threads pools :
- * A pool containing 4 Hight Threads
- * A pool containing 10 Medium Threads
- * A pool containing 4 Low priority Threads
- *
- */
-
public final class ClientScheduler
{
static Logger _log = Logger.getLogger(ClientScheduler.class.getName());
@@ -53,8 +43,11 @@
private static final ClientScheduler _instance = new ClientScheduler();
private final ScheduledThreadPoolExecutor _executorHighPriority;
+ private final ScheduledThreadPoolExecutor _executorMedHighPriority;
private final ScheduledThreadPoolExecutor _executorMedPriority;
private final ScheduledThreadPoolExecutor _executorLowPriority;
+ private final ScheduledThreadPoolExecutor _executorAi;
+ private final ScheduledThreadPoolExecutor _executorCraft;
/**
@@ -67,15 +60,18 @@
/**
- * Create a pool of 4 Hight Threads, a pool of 10 Medium Threads, and a pool of 4 Low priority Threads to execute Task.
+ * Create a pool of 4 Hight Threads, a pool of 4 Medium Threads, and a pool of 4 Low priority Threads to execute Task.
*/
private ClientScheduler()
{
if (Config.ASSERT) assert _instance == null;
_executorHighPriority = new ScheduledThreadPoolExecutor(Config.THREAD_P_HIGH, new ThrFactory(Config.EXECUTOR_PRI_HIGH, "PoolHIGH"));
- _executorMedPriority = new ScheduledThreadPoolExecutor(Config.THREAD_P_MED, new ThrFactory(Config.EXECUTOR_PRI_MED, "PoolMED"));
+ _executorMedHighPriority = new ScheduledThreadPoolExecutor(Config.THREAD_P_HIGH, new ThrFactory(Config.EXECUTOR_PRI_HIGH-1, "PoolHIGH"));
+ _executorMedPriority = new ScheduledThreadPoolExecutor(Config.THREAD_P_MED, new ThrFactory(Config.EXECUTOR_PRI_MED, "PoolMED"));
_executorLowPriority = new ScheduledThreadPoolExecutor(Config.THREAD_P_LOW, new ThrFactory(Config.EXECUTOR_PRI_LOW, "PoolLOW"));
+ _executorAi = new ScheduledThreadPoolExecutor(Config.THREAD_P_MED, new ThrFactory((Config.EXECUTOR_PRI_HIGH-1), "PoolMED"));
+ _executorCraft = new ScheduledThreadPoolExecutor(Config.THREAD_P_MED, new ThrFactory((Config.EXECUTOR_PRI_MED-1), "PoolLOW"));
}
/**
@@ -83,17 +79,26 @@
*/
public void closeAll()
{
- try { _executorHighPriority.shutdown(); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
+ try { _executorHighPriority.shutdown(); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
+ try { _executorMedHighPriority.shutdown(); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
try { _executorMedPriority.shutdown(); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
try { _executorLowPriority.shutdown(); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
+ try { _executorAi.shutdown(); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
+ try { _executorCraft.shutdown(); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
- try { _executorHighPriority.awaitTermination(1000, TimeUnit.MILLISECONDS); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
+ try { _executorHighPriority.awaitTermination(1000, TimeUnit.MILLISECONDS); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
+ try { _executorMedHighPriority.awaitTermination(1000, TimeUnit.MILLISECONDS); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
try { _executorMedPriority.awaitTermination(1000, TimeUnit.MILLISECONDS); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
try { _executorLowPriority.awaitTermination(1000, TimeUnit.MILLISECONDS); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
+ try { _executorAi.awaitTermination(1000, TimeUnit.MILLISECONDS); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
+ try { _executorCraft.awaitTermination(1000, TimeUnit.MILLISECONDS); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
_executorHighPriority.shutdownNow();
- _executorHighPriority.shutdownNow();
- _executorHighPriority.shutdownNow();
+ _executorMedHighPriority.shutdownNow();
+ _executorMedPriority.shutdownNow();
+ _executorLowPriority.shutdownNow();
+ _executorAi.shutdownNow();
+ _executorCraft.shutdownNow();
}
@@ -105,7 +110,10 @@
TaskPriority pr = pkt.getPriority();
if (pr == null)
- pr = PR_LOW;
+ {
+ _log.warning("Packet without priority defaulted to PR_LOW: "+pkt.getType());
+ pr = PR_LOW;
+ }
// Add a task to one of the pool of thread in function of its priority (HIGH, MEDIUM,LOW)
// This has effect equivalent to schedule(command, 0, anyUnit)
@@ -121,9 +129,9 @@
_instance._executorMedPriority.execute(pkt);
return;
case PR_LOW:
- default:
- _instance._executorLowPriority.execute(pkt);
- return;
+ default:
+ _instance._executorLowPriority.execute(pkt);
+ return;
}
}
@@ -146,8 +154,9 @@
{
case PR_HIGH: return scheduleHighAtFixedRate(r, initial, delay);
case PR_MEDIUM: return scheduleMedAtFixedRate(r, initial, delay);
- default:
- case PR_LOW: return scheduleLowAtFixedRate(r, initial, delay);
+ case PR_LOW: return scheduleLowAtFixedRate(r, initial, delay);
+ default:
+ return scheduleLowAtFixedRate(r, initial, delay);
}
}
@@ -169,7 +178,42 @@
} catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ }
}
-
+ /**
+ * Create a MedHigh priority task that is executed after an initial time (in ms) and each delay ms.
+ *
+ * @param r The task to launch
+ * @param initial The initial delay (in ms) after what the task is executed for the first time
+ * @param delay The delay (in ms) between 2 consecutive executions of the task
+ *
+ */
+ public ScheduledFuture scheduleMedHighAtFixedRate(Runnable r, long initial, long delay)
+ {
+ try
+ {
+ if (delay < 0) delay = 0;
+ return _executorMedHighPriority.scheduleAtFixedRate(r, initial, delay, TimeUnit.MILLISECONDS);
+ } catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ }
+ }
+
+ public ScheduledFuture scheduleAiAtFixedRate(Runnable r, long initial, long delay)
+ {
+ try
+ {
+ if (delay < 0) delay = 0;
+ return _executorAi.scheduleAtFixedRate(r, initial, delay, TimeUnit.MILLISECONDS);
+ } catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ }
+ }
+
+ public ScheduledFuture scheduleCraftAtFixedRate(Runnable r, long initial, long delay)
+ {
+ try
+ {
+ if (delay < 0) delay = 0;
+ return _executorCraft.scheduleAtFixedRate(r, initial, delay, TimeUnit.MILLISECONDS);
+ } catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ }
+ }
+
+
/**
* Create a Medium priority task that is executed after an initial time (in ms) and each delay ms.
*
@@ -231,8 +275,9 @@
{
case PR_HIGH: return scheduleHigh(r, delay);
case PR_MEDIUM: return scheduleMed(r, delay);
+ case PR_LOW: return scheduleLow(r, delay);
default:
- case PR_LOW: return scheduleLow(r, delay);
+ return scheduleLow(r,delay);
}
}
@@ -254,7 +299,22 @@
} catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ }
}
-
+ /**
+ * Create a Medium priority task that is executed after an initial time (in ms).
+ *
+ * @param r The task to launch
+ * @param initial The initial delay (in ms) after what the task is executed for the first time
+ * @param delay The delay (in ms) between 2 consecutive executions of the task
+ *
+ */
+ public ScheduledFuture scheduleMedHigh(Runnable r, long delay)
+ {
+ try
+ {
+ if (delay < 0) delay = 0;
+ return _executorMedHighPriority.schedule(r, delay, TimeUnit.MILLISECONDS);
+ } catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ }
+ }
/**
* Create a Medium priority task that is executed after an initial time (in ms).
*
@@ -263,6 +323,7 @@
* @param delay The delay (in ms) between 2 consecutive executions of the task
*
*/
+
public ScheduledFuture scheduleMed(Runnable r, long delay)
{
try
@@ -289,7 +350,24 @@
} catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ }
}
-
+ public ScheduledFuture scheduleAi(Runnable r, long delay)
+ {
+ try
+ {
+ if (delay < 0) delay = 0;
+ return _executorAi.schedule(r, delay, TimeUnit.MILLISECONDS);
+ } catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ }
+ }
+
+ public ScheduledFuture scheduleCraft(Runnable r, long delay)
+ {
+ try
+ {
+ if (delay < 0) delay = 0;
+ return _executorCraft.schedule(r, delay, TimeUnit.MILLISECONDS);
+ } catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ }
+ }
+
class ThrFactory implements ThreadFactory
{
private final String _prefix;
@@ -316,30 +394,49 @@
{
return new String[] {
"HIGH ("+Config.EXECUTOR_PRI_HIGH+")",
- "ActiveThreads: "+_executorHighPriority.getActiveCount(),
- "CompletedTasks: "+_executorHighPriority.getCompletedTaskCount(),
- "getCorePoolSize: "+_executorHighPriority.getCorePoolSize(),
- "MaximumPoolSize: "+_executorHighPriority.getMaximumPoolSize(),
- "LargestPoolSize: "+_executorHighPriority.getLargestPoolSize(),
- "PoolSize: "+_executorHighPriority.getPoolSize(),
- "ScheduledTasks: "+(_executorHighPriority.getTaskCount() - _executorHighPriority.getCompletedTaskCount()),
- "MEDIUM ("+Config.EXECUTOR_PRI_MED+")",
- "ActiveThreads: "+_executorMedPriority.getActiveCount(),
- "CompletedTasks: "+_executorMedPriority.getCompletedTaskCount(),
- "getCorePoolSize: "+_executorMedPriority.getCorePoolSize(),
- "MaximumPoolSize: "+_executorMedPriority.getMaximumPoolSize(),
- "LargestPoolSize: "+_executorMedPriority.getLargestPoolSize(),
- "PoolSize: "+_executorMedPriority.getPoolSize(),
- "ScheduledTasks: "+(_executorMedPriority.getTaskCount() - _executorMedPriority.getCompletedTaskCount()),
+ "ActiveThreads: "+_executorHighPriority.getActiveCount(),
+ "CompletedTasks: "+_executorHighPriority.getCompletedTaskCount(),
+ "ScheduledTasks: "+(_executorHighPriority.getTaskCount() - _executorHighPriority.getCompletedTaskCount()),
+ "TaskCount(total): "+_executorHighPriority.getTaskCount(),
+ "PoolSize: "+_executorHighPriority.getPoolSize(),
+ "",
+ "MedHigh ("+Config.EXECUTOR_PRI_MEDHIGH+")",
+ "ActiveThreads: "+_executorMedHighPriority.getActiveCount(),
+ "CompletedTasks: "+_executorMedHighPriority.getCompletedTaskCount(),
+ "ScheduledTasks: "+(_executorMedHighPriority.getTaskCount() - _executorMedHighPriority.getCompletedTaskCount()),
+ "TaskCount(total): "+_executorMedHighPriority.getTaskCount(),
+ "PoolSize: "+_executorMedHighPriority.getPoolSize(),
+ "",
+ "MEDIUM ("+(Config.EXECUTOR_PRI_MED)+")",
+ "ActiveThreads: "+_executorMedPriority.getActiveCount(),
+ "CompletedTasks: "+_executorMedPriority.getCompletedTaskCount(),
+ "ScheduledTasks: "+(_executorMedPriority.getTaskCount() - _executorMedPriority.getCompletedTaskCount()),
+ "TaskCount(total): "+_executorMedPriority.getTaskCount(),
+ "PoolSize: "+_executorMedPriority.getPoolSize(),
+ "",
"LOW ("+Config.EXECUTOR_PRI_LOW+")",
- "ActiveThreads: "+_executorLowPriority.getActiveCount(),
- "CompletedTasks: "+_executorLowPriority.getCompletedTaskCount(),
- "getCorePoolSize: "+_executorLowPriority.getCorePoolSize(),
- "MaximumPoolSize: "+_executorLowPriority.getMaximumPoolSize(),
- "LargestPoolSize: "+_executorLowPriority.getLargestPoolSize(),
- "PoolSize: "+_executorLowPriority.getPoolSize(),
- "ScheduledTasks: "+(_executorLowPriority.getTaskCount() - _executorLowPriority.getCompletedTaskCount())
+ "ActiveThreads: "+_executorLowPriority.getActiveCount(),
+ "CompletedTasks: "+_executorLowPriority.getCompletedTaskCount(),
+ "ScheduledTasks: "+(_executorLowPriority.getTaskCount() - _executorLowPriority.getCompletedTaskCount()),
+ "TaskCount(total): "+_executorLowPriority.getTaskCount(),
+ "PoolSize: "+_executorLowPriority.getPoolSize(),
+ "",
+ "AI ("+Config.EXECUTOR_PRI_AI+")",
+ "ActiveThreads: "+_executorAi.getActiveCount(),
+ "CompletedTasks: "+_executorAi.getCompletedTaskCount(),
+ "ScheduledTasks: "+(_executorAi.getTaskCount() - _executorAi.getCompletedTaskCount()),
+ "TaskCount(total): "+_executorAi.getTaskCount(),
+ "PoolSize: "+_executorAi.getPoolSize(),
+ "",
+ "CRAFT ("+Config.EXECUTOR_PRI_CRAFT+")",
+ "ActiveThreads: "+_executorCraft.getActiveCount(),
+ "CompletedTasks: "+_executorCraft.getCompletedTaskCount(),
+ "ScheduledTasks: "+(_executorCraft.getTaskCount() - _executorCraft.getCompletedTaskCount()),
+ "TaskCount(total): "+_executorCraft.getTaskCount(),
+ "PoolSize: "+_executorCraft.getPoolSize(),
+ ""
};
+
}
@@ -348,4 +445,14 @@
return getInstance().scheduleLow(event, delay);
}
+ public static ScheduledFuture scheduleAiAction(Runnable event, long delay)
+ {
+ return getInstance().scheduleAi(event, delay);
+ }
+
+ public static ScheduledFuture scheduleCraftAction(Runnable event, long delay)
+ {
+ return getInstance().scheduleCraft(event, delay);
+ }
+
}
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/taskmanager/tasks/TaskCleanUp.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/taskmanager/tasks/TaskCleanUp.java (revision 2151)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/taskmanager/tasks/TaskCleanUp.java (working copy)
@@ -1,35 +0,0 @@
-/**
- *
- */
-package net.sf.l2j.gameserver.taskmanager.tasks;
-
-import net.sf.l2j.gameserver.taskmanager.Task;
-import net.sf.l2j.gameserver.taskmanager.TaskManager;
-import net.sf.l2j.gameserver.taskmanager.TaskTypes;
-import net.sf.l2j.gameserver.taskmanager.TaskManager.ExecutedTask;
-
-/**
- * @author Tempy
- *
- */
-public final class TaskCleanUp extends Task
-{
- public static String NAME = "CleanUp";
-
- public String getName()
- {
- return NAME;
- }
-
- public void onTimeElapsed(ExecutedTask task)
- {
- System.runFinalization();
- System.gc();
- }
-
- public void initializate()
- {
- super.initializate();
- TaskManager.addUniqueTask(NAME, TaskTypes.TYPE_FIXED_SHEDULED, "0", "1800000", "");
- }
-}
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/taskmanager/TaskManager.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/taskmanager/TaskManager.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/taskmanager/TaskManager.java (working copy)
@@ -24,7 +24,6 @@
import javolution.util.FastMap;
import net.sf.l2j.L2DatabaseFactory;
import net.sf.l2j.gameserver.ClientScheduler;
-import net.sf.l2j.gameserver.taskmanager.tasks.TaskCleanUp;
import net.sf.l2j.gameserver.taskmanager.tasks.TaskJython;
import net.sf.l2j.gameserver.taskmanager.tasks.TaskRecom;
import net.sf.l2j.gameserver.taskmanager.tasks.TaskRestart;
@@ -163,7 +162,6 @@
private void initializate()
{
- registerTask(new TaskCleanUp());
registerTask(new TaskJython());
registerTask(new TaskRecom());
registerTask(new TaskRestart());
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/script/EngineInterface.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/script/EngineInterface.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/script/EngineInterface.java (working copy)
@@ -44,6 +44,9 @@
public interface EngineInterface
{
//* keep the references of Singletons to prevent garbage collection
+ // garbage collector will never 'collect' what is still "alive" in ram so why "preventing" ?
+ // if you don't use it, let it be collected, if you use it, don't fear -> it will not be collected.
+
public CharNameTable _charNametable = CharNameTable.getInstance();
public IdFactory _idFactory = IdFactory.getInstance();
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/GameTimeController.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/GameTimeController.java (revision 2156)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/GameTimeController.java (working copy)
@@ -72,7 +72,7 @@
_timer = new TimerThread();
_timer.start();
- ClientScheduler.getInstance().scheduleLowAtFixedRate(
+ ClientScheduler.getInstance().scheduleMedHighAtFixedRate(
new TimerWatcher(), 0, 1000);
ClientScheduler.getInstance().scheduleLowAtFixedRate(
new BroadcastSunState(), 0, 60*60*1000
@@ -151,7 +151,7 @@
// Create a task to update the _knownObject and _knowPlayers of each L2Character that finished its movement and of their already known L2Object
// then notify AI with EVT_ARRIVED
if (ended != null)
- ClientScheduler.getInstance().scheduleLow(new MovingObjectArrived(ended), 10);
+ ClientScheduler.getInstance().scheduleMed(new MovingObjectArrived(ended), 10);
}
@@ -169,7 +169,7 @@
{
super("TimerThread");
setDaemon(true);
- setPriority(MAX_PRIORITY);
+ setPriority(MAX_PRIORITY-1);
_stop = false;
_error = null;
}