- Much better / faster crafting without any "craft lag" - Admin/Admin2 menus fully working (enchant armor + lot other things) - ALT_COMMAND_PRIVILEGES fully working (tested) - Separate thread pools for AI and Crafting - lot of minor fixes - new command-privileges.properties at end of patch ----- BEGIN PATCH SVN DIFF ----- Index: C:/workspace/L2_GameServer/java/config/altsettings.properties =================================================================== --- C:/workspace/L2_GameServer/java/config/altsettings.properties (revision 2183) +++ 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/config/other.properties =================================================================== --- C:/workspace/L2_GameServer/java/config/other.properties (revision 2183) +++ C:/workspace/L2_GameServer/java/config/other.properties (working copy) @@ -90,7 +90,20 @@ AltPrivilegesSecureCheck = True AltPrivilegesDefaultLevel = 100 -#Change Colour Of GM's Name (True / False) -GMNameColourEnabled = False -#Colour Of GM's Name (Must Be RGB I.E 00FF00 = Green) (Default = Green) -GMNameColour = 00FF00 \ No newline at end of file +#Change Color Of GM's Name (True / False) +GmNameColorEnabled = False +#Color Of GM's Name (Must Be RGB I.E 00FF00 = Green) (Default = Green) +GmNameColor = 00FF00 + +# show colored name on comunity for >= level +GmColorComunityLevel = 100 + +# makes char invisible if access level >= # (default 100) +LoginHideLevel = 100 +LoginMessageRefusalLevel = 100 + +# if char IsInvis(), don't show on comunity board (defaults to false) +InvisHidesFromComunity = False + +# set to false on linux +NewLineCrLf = True Index: C:/workspace/L2_GameServer/java/net/sf/l2j/status/Status.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/status/Status.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/status/Status.java (working copy) @@ -43,6 +43,7 @@ if(lst.isAlive()) { _loginStatus.add(lst); + lst.setPriority(lst.getPriority()+1); // raise priority a bit } } if (this.isInterrupted()) Index: C:/workspace/L2_GameServer/java/net/sf/l2j/status/LoginStatusThread.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/status/LoginStatusThread.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/status/LoginStatusThread.java (working copy) @@ -322,8 +322,10 @@ { synchronized(_print) { - _print.println(msg); - _print.flush(); + // server running on linux outputed only \n + // which windows telnet did not understand - this fixes it + _print.println(msg + (Config.NEWLINE_CRLF ?"" : "\r") ); + _print.flush(); } } Index: C:/workspace/L2_GameServer/java/net/sf/l2j/status/GameStatusThread.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/status/GameStatusThread.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/status/GameStatusThread.java (working copy) @@ -75,7 +75,8 @@ String HostList = telnetSettings.getProperty("ListOfHosts", "127.0.0.1,localhost"); - if ( Config.DEVELOPER ) telnetOutput(3, "Comparing ip to list..."); + if ( Config.DEVELOPER ) + telnetOutput(3, "Comparing ip to list..."); // compare String ipToCompare = null; @@ -245,6 +246,12 @@ { _print.println(line); } + _print.println(); + // 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; + _print.println("Free memory "+freeMem+" Mb of "+totalMem+" Mb total"); + _print.println(); _print.flush(); } else if (_usrCommand.startsWith("announce")) Index: C:/workspace/L2_GameServer/java/net/sf/l2j/ChatLogFormatter.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/ChatLogFormatter.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/ChatLogFormatter.java (working copy) @@ -31,7 +31,7 @@ public class ChatLogFormatter extends Formatter { - private static final String CRLF = "\r\n"; + private static final String CRLF = Config.NEWLINE_CRLF ? "\r\n" : "\n"; private SimpleDateFormat dateFmt = new SimpleDateFormat("dd MMM H:mm:ss"); Index: C:/workspace/L2_GameServer/java/net/sf/l2j/Config.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/Config.java (revision 2183) +++ 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 */ @@ -203,6 +212,9 @@ public static int GM_TRANSACTION_MIN; public static int GM_TRANSACTION_MAX; + /** General GM AccessLevel with Enchant rights */ + public static int GM_ENCHANT; + /** Rate control */ public static float RATE_XP; @@ -254,9 +266,9 @@ public static boolean ALLOW_DISCARDITEM; public static boolean ALLOW_FREIGHT; public static boolean ALLOW_WAREHOUSE; - public static boolean ALLOW_WEAR; - public static boolean ALLOW_WATER; - public static boolean ALLOW_RENTPET; + public static boolean ALLOW_WEAR; + public static boolean ALLOW_WATER; + public static boolean ALLOW_RENTPET; // Pets public static int WYVERN_SPEED; @@ -298,14 +310,14 @@ public static boolean CHECK_KNOWN; public static int GAME_SERVER_LOGIN_PORT; - public static String GAME_SERVER_LOGIN_HOST; + public static String GAME_SERVER_LOGIN_HOST; public static String INTERNAL_HOSTNAME; public static String EXTERNAL_HOSTNAME; public static int PATH_NODE_RADIUS; - public static int NEW_NODE_ID; - public static int SELECTED_NODE_ID; - public static int LINKED_NODE_ID; - public static String NEW_NODE_TYPE; + public static int NEW_NODE_ID; + public static int SELECTED_NODE_ID; + public static int LINKED_NODE_ID; + public static String NEW_NODE_TYPE; public static boolean SERVER_SIDE_NPC_NAME; public static boolean SERVER_SIDE_NPC_NAME_WITH_LVL; public static boolean ALLOW_GUARDS; @@ -388,9 +400,11 @@ 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 { Compaction, @@ -479,10 +493,16 @@ public static boolean ANNOUNCE_MAMMON_SPAWN; public static boolean LAZY_CACHE; + + public static boolean GM_NAME_COLOR_ENABLED; + public static int GM_NAME_COLOR; - public static boolean GM_NAME_COLOUR_ENABLED; - public static int GM_NAME_COLOUR; - + public static int LOGIN_HIDE_LEVEL; // invis on login for builders, defaults to 100 + public static int LOGIN_MESSAGE_REFUSAL_LEVEL; // activate message refusal for level >= + public static int GM_COLOR_COMMUNITY_LEVEL; // chars >= level have GM color on community default=100 + public static boolean INVIS_HIDES_FROM_COMMUNITY; // defaults to false + public static boolean NEWLINE_CRLF; // defaults to true, set to false on linux + public static void load() { if(Server.SERVER_MODE == Server.MODE_GAMESERVER) @@ -586,8 +606,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")); @@ -620,7 +643,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) { @@ -721,7 +747,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")); @@ -743,6 +769,7 @@ PET_RENT_NPC = otherSettings.getProperty("ListPetRentNpc", "7827"); LIST_PET_RENT_NPC = new FastList(); + for (String id : PET_RENT_NPC.split(",")) { LIST_PET_RENT_NPC.add(Integer.parseInt(id)); } @@ -753,8 +780,14 @@ ALT_PRIVILEGES_SECURE_CHECK = Boolean.parseBoolean(otherSettings.getProperty("AltPrivilegesSecureCheck", "True")); ALT_PRIVILEGES_DEFAULT_LEVEL = Integer.parseInt(otherSettings.getProperty("AltPrivilegesDefaultLevel", "100")); - GM_NAME_COLOUR_ENABLED = Boolean.parseBoolean(otherSettings.getProperty("GMNameColourEnabled", "False")); - GM_NAME_COLOUR = Integer.decode("0x" + otherSettings.getProperty("GMNameColour", "00FF00")); + GM_NAME_COLOR_ENABLED = Boolean.parseBoolean(otherSettings.getProperty("GMNameColorEnabled", "False")); + GM_NAME_COLOR = Integer.decode("0x" + otherSettings.getProperty("GMNameColor", "00FF00")); + + GM_COLOR_COMMUNITY_LEVEL = Integer.parseInt(otherSettings.getProperty("GMColorCommunityLevel","100")); + LOGIN_HIDE_LEVEL = Integer.parseInt(otherSettings.getProperty("LoginHideLevel","100")); + LOGIN_MESSAGE_REFUSAL_LEVEL = Integer.parseInt(otherSettings.getProperty("LoginMessageRefusalLevel","100")); + INVIS_HIDES_FROM_COMMUNITY = Boolean.parseBoolean(otherSettings.getProperty("InvisHidesFromCommunity","False")); + NEWLINE_CRLF = Boolean.parseBoolean(otherSettings.getProperty("NewLineCrLf","True")); } catch (Exception e) @@ -793,25 +826,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")); @@ -914,6 +948,7 @@ GM_UNBLOCK = Integer.parseInt(gmSettings.getProperty("GMUnblock", "100")); GM_CACHE = Integer.parseInt(gmSettings.getProperty("GMCache", "100")); GM_TEST = Integer.parseInt(gmSettings.getProperty("GMTest", "100")); + GM_ENCHANT = Integer.parseInt(gmSettings.getProperty("GMEnchant", "100")); String gmTrans = gmSettings.getProperty("GMDisableTransaction", "False"); Index: C:/workspace/L2_GameServer/java/net/sf/l2j/FileLogFormatter.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/FileLogFormatter.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/FileLogFormatter.java (working copy) @@ -33,11 +33,14 @@ /* (non-Javadoc) * @see java.util.logging.Formatter#format(java.util.logging.LogRecord) */ - private static final String CRLF = "\r\n"; + + private static final String CRLF = Config.NEWLINE_CRLF ? "\r\n" : "\n"; private static final String _ = "\t"; + public String format(LogRecord record) { - StringBuffer output = new StringBuffer(); + + StringBuffer output = new StringBuffer(); output.append(record.getMillis()); output.append(_); output.append(record.getLevel().getName()); Index: C:/workspace/L2_GameServer/java/net/sf/l2j/Server.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/Server.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/Server.java (working copy) @@ -79,6 +79,7 @@ if ( Config.IS_TELNET_ENABLED ) { statusServer = new Status(0); statusServer.start(); + statusServer.setPriority(statusServer.getPriority()+2); // telnet is very important } else { System.out.println("Telnet server is currently disabled."); Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/SpawnTable.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/SpawnTable.java (revision 2183) +++ 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 2183) +++ 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/RequestBypassToServer.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/RequestBypassToServer.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/RequestBypassToServer.java (working copy) @@ -64,14 +64,21 @@ return; try { - if (_command.startsWith("admin_") && activeChar.getAccessLevel() >= Config.GM_ACCESSLEVEL) + _log.warning("command as inputed: \""+_command+"\""); + + if (_command.startsWith("admin_") && activeChar.getAccessLevel() >= Config.GM_ACCESSLEVEL) { + if(Config.ALT_PRIVILEGES_ADMIN) _log.warning("ALT_PRIVILEGES_ADMIN==True"); + _log.warning("AdminCommandHandler.getInstance().checkPrivileges(activeChar,_command) == "+AdminCommandHandler.getInstance().checkPrivileges(activeChar,_command)); + if (Config.ALT_PRIVILEGES_ADMIN && !AdminCommandHandler.getInstance().checkPrivileges(activeChar,_command)) return; + _log.warning("passed privileges check"); IAdminCommandHandler ach = AdminCommandHandler.getInstance().getAdminCommandHandler(_command); if (ach != null) { + _log.warning("useAdminCommand("+_command+","+activeChar.getName()+")"); ach.useAdminCommand(_command, activeChar); } else { _log.warning("No handler registered for bypass '"+_command+"'"); 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 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/RequestRestartPoint.java (working copy) @@ -67,15 +67,15 @@ { 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 + 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.Town); //Teleport and revive @@ -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/SendBypassBuildCmd.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/SendBypassBuildCmd.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/SendBypassBuildCmd.java (working copy) @@ -19,9 +19,11 @@ package net.sf.l2j.gameserver.clientpackets; import java.nio.ByteBuffer; +import java.util.logging.Logger; import net.sf.l2j.Config; import net.sf.l2j.gameserver.ClientThread; +import net.sf.l2j.gameserver.PacketHandler; import net.sf.l2j.gameserver.handler.AdminCommandHandler; import net.sf.l2j.gameserver.handler.IAdminCommandHandler; import net.sf.l2j.gameserver.model.L2PcInstance; @@ -34,7 +36,9 @@ public class SendBypassBuildCmd extends ClientBasePacket { private static final String _C__5B_SENDBYPASSBUILDCMD = "[C] 5b SendBypassBuildCmd"; - public final static int GM_MESSAGE = 9; + private static Logger _log = Logger.getLogger(SendBypassBuildCmd.class.getName()); + + public final static int GM_MESSAGE = 9; public final static int ANNOUNCEMENT = 10; private final String _command; @@ -43,22 +47,50 @@ { super(buf, client); _command = readS(); + if(Config.DEBUG) + _log.info("SendBypassBuildCmd: \""+_command+"\""); } void runImpl() { L2PcInstance activeChar = getClient().getActiveChar(); + if(activeChar == null) return; - - if (Config.ALT_PRIVILEGES_ADMIN && !AdminCommandHandler.getInstance().checkPrivileges(activeChar,_command)) + + if (Config.ALT_PRIVILEGES_ADMIN) + _log.info("using ALT_PRIVILEGES for player "+activeChar.getName()+" command "+_command); + else + _log.info("using default PRIVILEGES for player "+activeChar.getName()+" command "+_command); + + if (Config.ALT_PRIVILEGES_ADMIN && (! + (AdminCommandHandler.getInstance().checkPrivileges(activeChar,"admin_"+_command) || + AdminCommandHandler.getInstance().checkPrivileges(activeChar,"admin_"+_command)) + )) + { + if(Config.DEBUG) + _log.info("checkPrivileges failed for "+activeChar+" command "+_command); return; + } - IAdminCommandHandler ach = AdminCommandHandler.getInstance().getAdminCommandHandler("admin_"+_command); - if (ach != null) + if(Config.DEBUG) + _log.info("calling getAdminCommandHandler for command=admin_"+_command); + IAdminCommandHandler ach = AdminCommandHandler.getInstance().getAdminCommandHandler("admin_"+_command); + + if(ach==null) + { + ach = AdminCommandHandler.getInstance().getAdminCommandHandler(_command); + if(ach==null) + _log.warning("failed to obtain commandHandler for command: "+_command); + } + + if (ach != null) { - ach.useAdminCommand("admin_"+_command, activeChar); + if(!ach.useAdminCommand("admin_"+_command, activeChar)) + { + ach.useAdminCommand(_command, activeChar); + } } } 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 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/EnterWorld.java (working copy) @@ -57,233 +57,255 @@ */ public class EnterWorld extends ClientBasePacket { - private static final String _C__03_ENTERWORLD = "[C] 03 EnterWorld"; - private static Logger _log = Logger.getLogger(EnterWorld.class.getName()); + private static final String _C__03_ENTERWORLD = "[C] 03 EnterWorld"; + private static final Logger _log = Logger.getLogger(EnterWorld.class.getName()); - /** - * @param decrypt - */ - public EnterWorld(ByteBuffer buf, ClientThread client) - { - super(buf, client); - // this is just a trigger packet. it has no content - } - - void runImpl() - { - L2PcInstance activeChar = getClient().getActiveChar(); + /** + * @param decrypt + */ + public EnterWorld(ByteBuffer buf, ClientThread client) + { + super(buf, client); + // this is just a trigger packet. it has no content + } + + void runImpl() + { + L2PcInstance activeChar = getClient().getActiveChar(); - if(activeChar.isGM()) + try { - activeChar.setInvisible(); - } - - if (Config.PLAYER_SPAWN_PROTECTION > 0) - activeChar.setProtection(true); - - activeChar.spawnMe(activeChar.getX(), activeChar.getY(), activeChar.getZ()); - - if (SevenSigns.getInstance().isSealValidationPeriod()) - { - SignsSky ss = new SignsSky(); - activeChar.sendPacket(ss); - } - - if (Config.STORE_SKILL_COOLTIME) - activeChar.restoreEffects(); - - if (activeChar.getAllEffects() != null) - { - for (L2Effect e : activeChar.getAllEffects()) + if (Config.PLAYER_SPAWN_PROTECTION > 0) + activeChar.setProtection(true); + + activeChar.spawnMe(activeChar.getX(), activeChar.getY(), activeChar.getZ()); + + if (SevenSigns.getInstance().isSealValidationPeriod()) { - if (e.getEffectType() == L2Effect.EffectType.HEAL_OVER_TIME) + SignsSky ss = new SignsSky(); + activeChar.sendPacket(ss); + } + + if (Config.STORE_SKILL_COOLTIME) + activeChar.restoreEffects(); + + if (activeChar.getAllEffects() != null) + { + for (L2Effect e : activeChar.getAllEffects()) { - activeChar.stopEffects(L2Effect.EffectType.HEAL_OVER_TIME); - activeChar.removeEffect(e); + if (e.getEffectType() == L2Effect.EffectType.HEAL_OVER_TIME) + { + activeChar.stopEffects(L2Effect.EffectType.HEAL_OVER_TIME); + activeChar.removeEffect(e); + } + if (e.getEffectType() == L2Effect.EffectType.COMBAT_POINT_HEAL_OVER_TIME) + { + activeChar.stopEffects(L2Effect.EffectType.COMBAT_POINT_HEAL_OVER_TIME); + activeChar.removeEffect(e); + } } - if (e.getEffectType() == L2Effect.EffectType.COMBAT_POINT_HEAL_OVER_TIME) - { - activeChar.stopEffects(L2Effect.EffectType.COMBAT_POINT_HEAL_OVER_TIME); - activeChar.removeEffect(e); - } - } - } - - ItemList il = new ItemList(activeChar, false); - activeChar.sendPacket(il); - - UserInfo ui = new UserInfo(activeChar); - sendPacket(ui); - - activeChar.getMacroses().sendUpdate(); - - ShortCutInit sci = new ShortCutInit(); - sendPacket(sci); - - SystemMessage sm = new SystemMessage(34); - sendPacket(sm); - - HennaInfo hii = new HennaInfo(activeChar); - sendPacket(hii); - - sm = new SystemMessage(614); - sm.addString(getText("VGhpcyBTZXJ2ZXIgaXMgcnVubmluZyBMMko=")); - sm.addString(getText("IHZlcnNpb24gMyBkZXYvdW5zdGFibGU=")); - sendPacket(sm); - sm = new SystemMessage(614); - sm.addString(getText("Y3JlYXRlZCBieSBMMkNoZWYgYW5kIHRoZQ==")); - sm.addString(getText("IEwySiB0ZWFtLg==")); - sendPacket(sm); - sm = new SystemMessage(614); - sm.addString(getText("dmlzaXQgIGwyai5zb3VyY2Vmb3JnZS5uZXQ=")); - sm.addString(getText("ICBmb3Igc3VwcG9ydC4=")); - sendPacket(sm); - sm = new SystemMessage(614); - sm.addString(getText("V2VsY29tZSB0byA=")); - sm.addString(LoginServerThread.getInstance().getServerName()); - sendPacket(sm); - - if (Config.SERVER_VERSION != null) - { + } + + ItemList il = new ItemList(activeChar, false); + activeChar.sendPacket(il); + + UserInfo ui = new UserInfo(activeChar); + sendPacket(ui); + + activeChar.getMacroses().sendUpdate(); + + ShortCutInit sci = new ShortCutInit(); + sendPacket(sci); + + SystemMessage sm = new SystemMessage(34); + sendPacket(sm); + + HennaInfo hii = new HennaInfo(activeChar); + sendPacket(hii); + sm = new SystemMessage(614); - sm.addString(getText("TDJKIFNlcnZlciBWZXJzaW9uOg==")+" "+Config.SERVER_VERSION); + sm.addString(getText("VGhpcyBTZXJ2ZXIgaXMgcnVubmluZyBMMko=")); + sm.addString(getText("IHZlcnNpb24gMyBkZXYvdW5zdGFibGU=")); sendPacket(sm); sm = new SystemMessage(614); - sm.addString(getText("TDJKIFNlcnZlciBCdWlsZCBEYXRlOg==")+" "+Config.SERVER_BUILD_DATE); + sm.addString(getText("Y3JlYXRlZCBieSBMMkNoZWYgYW5kIHRoZQ==")); + sm.addString(getText("IEwySiB0ZWFtLg==")); sendPacket(sm); - } - - Announcements.getInstance().showAnnouncements(activeChar); - SevenSigns.getInstance().sendCurrentPeriodMsg(activeChar); + sm = new SystemMessage(614); + sm.addString(getText("dmlzaXQgIGwyai5zb3VyY2Vmb3JnZS5uZXQ=")); + sm.addString(getText("ICBmb3Igc3VwcG9ydC4=")); + sendPacket(sm); + sm = new SystemMessage(614); + sm.addString(getText("V2VsY29tZSB0byA=")); + sm.addString(LoginServerThread.getInstance().getServerName()); + sendPacket(sm); + + if (Config.SERVER_VERSION != null) + { + sm = new SystemMessage(614); + sm.addString(getText("TDJKIFNlcnZlciBWZXJzaW9uOg==")+" "+Config.SERVER_VERSION); + sendPacket(sm); + sm = new SystemMessage(614); + sm.addString(getText("TDJKIFNlcnZlciBCdWlsZCBEYXRlOg==")+" "+Config.SERVER_BUILD_DATE); + sendPacket(sm); + } + + Announcements.getInstance().showAnnouncements(activeChar); + SevenSigns.getInstance().sendCurrentPeriodMsg(activeChar); + + Quest.playerEnter(activeChar); + + // send user info again .. just like the real client + sendPacket(ui); + + if (activeChar.getClanId() != 0 && activeChar.getClan() != null) + { + sendPacket( new PledgeShowMemberListAll(activeChar.getClan(), activeChar) ); + sendPacket( new PledgeStatusChanged(activeChar.getClan())); + } + + if (activeChar.isAlikeDead()) + { + // no broadcast needed since the player will already spawn dead to others + activeChar.sendPacket(new Die(activeChar)); + } + + if (Config.ALLOW_WATER) + activeChar.checkWaterState(); + + //add char to online characters + activeChar.setOnlineStatus(true); + + if (activeChar.getAccessLevel() > 0 || Config.EVERYBODY_HAS_ADMIN_RIGHTS) + { + activeChar.setIsGM(true); + activeChar.sendMessage("GM status activated."); + _log.warning("GM status activated."); + } + + //_log.warning("GM_NAME_COLOR_ENABLED: "+Config.GM_NAME_COLOR_ENABLED); + if(Config.GM_NAME_COLOR_ENABLED && activeChar.isGM()) + activeChar.setNameColor(Config.GM_NAME_COLOR); + + if(activeChar.getAccessLevel() >= Config.LOGIN_HIDE_LEVEL) + { + activeChar.setInvisible(); + activeChar.sendMessage("Invisible mode."); + _log.warning("Invisible mode."); + }; + - Quest.playerEnter(activeChar); - - // send user info again .. just like the real client - sendPacket(ui); - - if (activeChar.getClanId() != 0 && activeChar.getClan() != null) + if(activeChar.getAccessLevel() >= Config.LOGIN_MESSAGE_REFUSAL_LEVEL) + { + activeChar.setMessageRefusal(true); + activeChar.sendMessage("Message refusal mode."); + _log.warning("Message refusal mode."); + } + + notifyFriends(activeChar); + notifyClanMembers(activeChar); + + // send user info again .. just like the real client + sendPacket(ui); + activeChar.onPlayerEnter(); + } catch (Throwable t) { - sendPacket( new PledgeShowMemberListAll(activeChar.getClan(), activeChar) ); - sendPacket( new PledgeStatusChanged(activeChar.getClan())); + _log.warning("exception in enterworld: "); + t.printStackTrace(); } - - if (activeChar.isAlikeDead()) - { - // no broadcast needed since the player will already spawn dead to others - activeChar.sendPacket(new Die(activeChar)); - } - - if (Config.ALLOW_WATER) - activeChar.checkWaterState(); - - - //add char to online characters - activeChar.setOnlineStatus(true); - - notifyFriends(activeChar); - notifyClanMembers(activeChar); - - activeChar.onPlayerEnter(); - - if(activeChar.isGM()) + finally { - activeChar.sendMessage("Hide is default for builder"); - activeChar.setMessageRefusal(true); - activeChar.sendMessage("Message refusal mode"); - if(Config.GM_NAME_COLOUR_ENABLED) - { - activeChar.setNameColor(Config.GM_NAME_COLOUR); - } - } - } + + }; + } - /** - * @param activeChar - */ - private void notifyFriends(L2PcInstance cha) - { - java.sql.Connection con = null; - try { - con = L2DatabaseFactory.getInstance().getConnection(); - PreparedStatement statement; - statement = con.prepareStatement("SELECT char_id,friend_name from character_friends where char_id=? or friend_name=?"); - statement.setInt(1, cha.getObjectId()); - statement.setString(2, cha.getName()); - ResultSet rset = statement.executeQuery(); - + /** + * @param activeChar + */ + private void notifyFriends(L2PcInstance cha) + { + java.sql.Connection con = null; + try { + con = L2DatabaseFactory.getInstance().getConnection(); + PreparedStatement statement; + statement = con.prepareStatement("SELECT char_id,friend_name from character_friends where char_id=? or friend_name=?"); + statement.setInt(1, cha.getObjectId()); + statement.setString(2, cha.getName()); + ResultSet rset = statement.executeQuery(); + L2PcInstance friend; int objectId; String name; SystemMessage sm = new SystemMessage(503); sm.addString(cha.getName()); - + while (rset.next()){ objectId = rset.getInt("char_id"); name = rset.getString("friend_name"); - + if (cha.getObjectId() != objectId) friend = (L2PcInstance)L2World.getInstance().findObject(objectId); else friend = L2World.getInstance().getPlayer(name); - + if (friend != null) //friend logged in. friend.sendPacket(sm); - } + } } catch (Exception e) { _log.warning("could not restore friend data:"+e); } finally { try {con.close();} catch (Exception e){} } cha.updateEffectIcons(); - } + } - /** - * @param activeChar - */ - private void notifyClanMembers(L2PcInstance activeChar) - { - L2Clan clan = activeChar.getClan(); - if (clan != null) - { - clan.getClanMember(activeChar.getName()).setPlayerInstance(activeChar); - SystemMessage msg = new SystemMessage(SystemMessage.CLAN_MEMBER_S1_LOGGED_IN); - msg.addString(activeChar.getName()); - + /** + * @param activeChar + */ + private void notifyClanMembers(L2PcInstance activeChar) + { + L2Clan clan = activeChar.getClan(); + if (clan != null) + { + clan.getClanMember(activeChar.getName()).setPlayerInstance(activeChar); + SystemMessage msg = new SystemMessage(SystemMessage.CLAN_MEMBER_S1_LOGGED_IN); + msg.addString(activeChar.getName()); + if(activeChar.isClanLeader()) activeChar.setClanPrivileges(L2Clan.CP_ALL); - - L2PcInstance[] clanMembers = clan.getOnlineMembers(activeChar.getName()); + + L2PcInstance[] clanMembers = clan.getOnlineMembers(activeChar.getName()); PledgeShowMemberListAdd ps = new PledgeShowMemberListAdd(activeChar); - for (int i = 0; i < clanMembers.length; i++) - { - clanMembers[i].sendPacket(ps); - clanMembers[i].sendPacket(msg); - } - } - } - - /** - * @param string - * @return - * @throws UnsupportedEncodingException - */ - private String getText(String string) - { - try { - String result = new String(Base64.decode(string), "UTF-8"); - return result; - } catch (UnsupportedEncodingException e) { - // huh, UTF-8 is not supported? :) - return null; - } - } + for (int i = 0; i < clanMembers.length; i++) + { + clanMembers[i].sendPacket(ps); + clanMembers[i].sendPacket(msg); + } + } + } + /** + * @param string + * @return + * @throws UnsupportedEncodingException + */ + private String getText(String string) + { + try { + String result = new String(Base64.decode(string), "UTF-8"); + return result; + } catch (UnsupportedEncodingException e) { + // huh, UTF-8 is not supported? :) + return null; + } + } + /* (non-Javadoc) - * @see net.sf.l2j.gameserver.clientpackets.ClientBasePacket#getType() - */ - public String getType() - { - return _C__03_ENTERWORLD; - } + * @see net.sf.l2j.gameserver.clientpackets.ClientBasePacket#getType() + */ + public String getType() + { + return _C__03_ENTERWORLD; + } } 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 2183) +++ 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/clientpackets/Say2.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/Say2.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/Say2.java (working copy) @@ -19,6 +19,7 @@ package net.sf.l2j.gameserver.clientpackets; import java.nio.ByteBuffer; +import java.util.ArrayList; import java.util.StringTokenizer; import java.util.logging.Level; import java.util.logging.LogRecord; @@ -113,6 +114,22 @@ _logChat.log(record); } + + // 'snoop' implementation + ArrayList snoopers; + snoopers = activeChar.getSnoop(); + if(!snoopers.isEmpty()) + { + SystemMessage sm = new SystemMessage(614); + sm.addString("snoop("+activeChar.getName()+") "+_text); + + for (L2PcInstance _snoop : snoopers) + { + _snoop.sendPacket(sm); + } + } + + CreatureSay cs = new CreatureSay(activeChar.getObjectId(), _type, activeChar.getName(), _text); if (_type == TELL) Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/Shutdown.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/Shutdown.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/Shutdown.java (working copy) @@ -354,11 +354,11 @@ // Seven Signs data is now saved along with Festival data. if (!SevenSigns.getInstance().isSealValidationPeriod()) - SevenSignsFestival.getInstance().saveFestivalData(false); - } - catch (Exception e) { + SevenSignsFestival.getInstance().saveFestivalData(false); + } + catch (Exception e) { System.err.println("Failed to save Seven Signs configuration: " + e); - } + } } System.err.println("Data saved. All players disconnected, shutting down."); Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/Announcements.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/Announcements.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/Announcements.java (working copy) @@ -212,7 +212,7 @@ for (int i = 0; i < _announcements.size(); i++) { save.write(_announcements.get(i).toString()); - save.write("\r\n"); + save.write(Config.NEWLINE_CRLF ? "\r\n":"\n"); } } catch (IOException e) 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 2183) +++ 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 2183) +++ 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/playable/PlayableStat.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/actor/playable/PlayableStat.java (revision 2187) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/actor/playable/PlayableStat.java (working copy) @@ -57,7 +57,7 @@ if (getExp() >= getExpForLevel(getLevel() + 1) || getExpForLevel(getLevel()) > getExp()) setExp(getExpForLevel(getLevel())); if (!levelIncreased) return false; - + getActiveChar().getStatus().setCurrentHp(getActiveChar().getStat().getMaxHp()); getActiveChar().getStatus().setCurrentMp(getActiveChar().getStat().getMaxMp()); 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 2186) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/actor/character/CharStatus.java (working copy) @@ -207,7 +207,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); } } @@ -317,8 +317,8 @@ getActiveChar().updateStats(); } } - } - + } + // Send the Server->Client packet StatusUpdate with current HP and MP to all other L2PcInstance to inform getActiveChar().broadcastStatusUpdate(); } 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 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2MonsterInstance.java (working copy) @@ -109,9 +109,7 @@ try { minionList.maintainMinions(); - //must be fixed. class exception. - //for(L2MinionInstance minion : minionList.getSpawnedMinions()) - // minion.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, this); + callMinions(); } catch (Throwable e) { @@ -129,7 +127,7 @@ public void callMinions() { - if (minionList.hasMinions()) + if (getTemplate().getMinionData() != null) { for (L2MinionInstance minion : minionList.getSpawnedMinions()) { @@ -145,7 +143,8 @@ Random rnd = getRnd(); int minionX = masterX + (rnd.nextInt(401) - 200); int minionY = masterY + (rnd.nextInt(401) - 200); - int minionZ = masterZ; + int minionZ = masterZ+100; // just in case master is on high ground, shouldn't hurt ? + while (((minionX != (masterX + 30)) && (minionX != (masterX - 30))) || ((minionY != (masterY + 30)) && (minionY != (masterY - 30)))) { minionX = masterX + (rnd.nextInt(401) - 200); @@ -154,9 +153,7 @@ // Move the minion to the new coords if (!minion.isInCombat() && !minion.isDead() && !minion.isMovementDisabled()) - { minion.moveToLocation(minionX, minionY, minionZ, 0); - } } } } @@ -186,7 +183,7 @@ { if (minionMaintainTask != null) minionMaintainTask.cancel(true); - + minionMaintainTask=null; super.doDie(killer); } Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2PcInstance.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2PcInstance.java (revision 2191) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2PcInstance.java (working copy) @@ -24,6 +24,7 @@ import java.io.ObjectOutputStream; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.List; @@ -318,7 +319,7 @@ private boolean _dietMode = false; // ignore weight penalty private boolean _tradeRefusal = false; // Trade refusal private boolean _exchangeRefusal = false; // Exchange refusal - + private ArrayList _snoopers; // who 'snoop' this player FIXME: we need 2 use Syncronized Hash Set, coze many gms can add/romove snoops same time public boolean _exploring = false; // this is needed to find the inviting player for Party response @@ -527,6 +528,9 @@ // Create an AI _ai = new L2PlayerAI(new L2PcInstance.AIAccessor()); + // Create snoopers + _snoopers = new ArrayList(); + // Create a L2Radar object radar = new L2Radar(this); @@ -6217,8 +6221,44 @@ super.onTeleported(); if (Config.PLAYER_SPAWN_PROTECTION > 0) setProtection(true); - if (Config.ALLOW_WATER && this instanceof L2PcInstance) ((L2PcInstance)this).checkWaterState(); + if (Config.ALLOW_WATER && this instanceof L2PcInstance) ((L2PcInstance)this).checkWaterState(); } public void addExpAndSp(int addToExp, int addToSp) { getStat().addExpAndSp(addToExp, addToSp); } + + public void removeSnoop(L2PcInstance target) + { + if(target != null && !_snoopers.isEmpty()) + { + _snoopers.remove(target); + } + } + + public void addSnoop(L2PcInstance target) + { + if(target != null) + { + _snoopers.add(target); + } + } + + public boolean isSnoopedBy(L2PcInstance target) + { + if(_snoopers != null) + { + for(L2PcInstance candidate : _snoopers) + { + if(target == candidate) + { + return true; + } + } + } + return false; + } + + public ArrayList getSnoop() + { + return _snoopers; + } } 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 2183) +++ 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 2183) +++ 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 clazz; @@ -1086,14 +1087,14 @@ if(!partyMember.isDead()) { if (!Util.checkIfInRange(radius, activeChar, partyMember, true)) - continue; - - targetList.add(partyMember); + continue; + + targetList.add(partyMember); // break; + } + } } } - } - } return targetList.toArray(new L2Character[targetList.size()]); } case TARGET_CORPSE_ALLY: @@ -1115,7 +1116,7 @@ if (newTarget == null || !(newTarget instanceof L2PcInstance)) continue; if ((((L2PcInstance)newTarget).getAllyId() == 0 || ((L2PcInstance)newTarget).getAllyId() != player.getAllyId()) - && (((L2PcInstance)newTarget).getClan() == null || ((L2PcInstance)newTarget).getClanId() != player.getClanId())) + && (((L2PcInstance)newTarget).getClan() == null || ((L2PcInstance)newTarget).getClanId() != player.getClanId())) continue; if (targetType == SkillTargetType.TARGET_CORPSE_ALLY && !((L2PcInstance)newTarget).isDead()) continue; @@ -1125,7 +1126,7 @@ // Don't add this target if this is a Pc->Pc pvp casting and pvp condition not met if (!player.checkPvpSkill(newTarget, this)) continue; - + targetList.add((L2Character)newTarget); } } Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Attackable.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Attackable.java (revision 2190) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Attackable.java (working copy) @@ -339,7 +339,7 @@ if (this instanceof L2MinionInstance) { master = ((L2MinionInstance)this).getLeader(); - if (!master.isInCombat()) + if (!master.isInCombat()&&!master.isDead()) master.addDamage(attacker, 1); } if (master.hasMinions()) @@ -401,13 +401,11 @@ } } catch (Exception e) { _log.log(Level.SEVERE, "", e); } - + // Clear all aggro char from list getAggroList().clear(); - // Kill the L2NpcInstance (the corpse disappeared after 7 seconds) super.doDie(killer); - } /** @@ -442,20 +440,20 @@ RewardInfo reward; // Go through the _aggroList of the L2Attackable - List toRemove = new FastList(); + List toRemove = new FastList(); for (AggroInfo info : getAggroList().values()) - { + { if (info == null) continue; - // Get the L2Character corresponding to this attacker + // Get the L2Character corresponding to this attacker attacker = info.attacker; - - // Get damages done by this attacker + + // Get damages done by this attacker damage = info.damage; - - // Prevent unwanted behavior + + // Prevent unwanted behavior if (npcID > 0 && damage > 1) - { + { if (attacker instanceof L2SummonInstance) ddealer = ((L2SummonInstance)attacker).getOwner(); else @@ -475,16 +473,16 @@ } rewards.put(ddealer, reward); + } + + toRemove.add(attacker); } - - toRemove.add(attacker); - } - + for (L2Character atker : toRemove) - { + { if (atker != null) getAggroList().remove(atker); + } } - } if (!rewards.isEmpty()) { @@ -522,8 +520,8 @@ attackerParty = ((L2PetInstance)attacker).getParty(); else if (attacker instanceof L2PcInstance) attackerParty = ((L2PcInstance)attacker).getParty(); - else - return; + else + return; // If this attacker is a L2PcInstance with a summoned L2SummonInstance, get Exp Penalty applied for the current summoned L2SummonInstance if (attacker instanceof L2PcInstance && ((L2PcInstance)attacker).getPet() instanceof L2SummonInstance) @@ -540,22 +538,22 @@ // Calculate Exp and SP rewards if (attacker.getKnownList().knowsObject(this)) { - // Calculate the difference of level between this attacker (L2PcInstance or L2SummonInstance owner) and the L2Attackable - // mob = 24, atk = 10, diff = -14 (full xp) - // mob = 24, atk = 28, diff = 4 (some xp) - // mob = 24, atk = 50, diff = 26 (no xp) + // Calculate the difference of level between this attacker (L2PcInstance or L2SummonInstance owner) and the L2Attackable + // mob = 24, atk = 10, diff = -14 (full xp) + // mob = 24, atk = 28, diff = 4 (some xp) + // mob = 24, atk = 50, diff = 26 (no xp) levelDiff = attacker.getLevel() - getLevel(); - + tmp = calculateExpAndSp(levelDiff, damage); exp = tmp[0]; exp *= 1 - penalty; sp = tmp[1]; - - // Distribute the Exp and SP between the L2PcInstance and its L2Summon + + // Distribute the Exp and SP between the L2PcInstance and its L2Summon attacker.addExpAndSp((int)attacker.calcStat(Stats.EXPSP_RATE, exp, null, null), - (int)attacker.calcStat(Stats.EXPSP_RATE, sp, null, null)); - } + (int)attacker.calcStat(Stats.EXPSP_RATE, sp, null, null)); } + } else { //share with party members @@ -589,7 +587,7 @@ // If the party didn't killed this L2Attackable alone if (partyDmg < getMaxHp()) partyMul = ((float)partyDmg / (float)getMaxHp()); - + // Avoid "over damage" if (partyDmg > getMaxHp()) partyDmg = getMaxHp(); @@ -645,24 +643,24 @@ { if (attacker == null) return; - // Get the AggroInfo of the attacker L2Character from the _aggroList of the L2Attackable + // Get the AggroInfo of the attacker L2Character from the _aggroList of the L2Attackable AggroInfo ai = getAggroList().get(attacker); - if (ai != null) - { - // Add new damage and aggro (=damage) to the AggroInfo object - ai.damage += damage; - ai.hate += aggro; - } - else - { - // Create a AggroInfo object and Init it - ai = new AggroInfo(attacker); - ai.damage = damage; - ai.hate = aggro; - - // Add the attaker L2Character and the AggroInfo object in the _aggroList of the L2Attackable + if (ai != null) + { + // Add new damage and aggro (=damage) to the AggroInfo object + ai.damage += damage; + ai.hate += aggro; + } + else + { + // Create a AggroInfo object and Init it + ai = new AggroInfo(attacker); + ai.damage = damage; + ai.hate = aggro; + + // Add the attaker L2Character and the AggroInfo object in the _aggroList of the L2Attackable getAggroList().put(attacker, ai); - } + } // Set the intention to the L2Attackable to AI_INTENTION_ACTIVE if (aggro > 0 && getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE) getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE); @@ -676,14 +674,17 @@ L2PcInstance player = attacker instanceof L2PcInstance?(L2PcInstance)attacker:((L2SummonInstance)attacker).getOwner(); QuestState[] quests = player.getQuestsForAttacks(this); + if (quests != null) { for (QuestState qs : quests) qs.getQuest().notifyAttack(this, qs); } + } } catch (Exception e) { _log.log(Level.SEVERE, "", e); } + } /** @@ -741,6 +742,7 @@ getAggroList().remove(target); return 0; } + if (ai.attacker.isAlikeDead()) { ai.hate = 0; @@ -850,7 +852,7 @@ { L2ItemInstance dropit; _rand = new Random(); - + int dropConstant; int randDropLim = 70; int randPlusMin = 1; 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 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Character.java (working copy) @@ -212,7 +212,7 @@ { decayMe(); } - + public void onTeleported() { setIsTeleporting(false); @@ -220,7 +220,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()); } @@ -254,7 +254,7 @@ if (getKnownList().getKnownPlayers() == null) return; Collection knownPlayers = getKnownList().getKnownPlayers(); - + if (Config.DEBUG) _log.fine("players to notify:" + knownPlayers.size() + " packet:"+mov.getType()); for (L2PcInstance player : knownPlayers) @@ -297,6 +297,7 @@ temp.sendPacket(su); } + /** * Not Implemented.

* @@ -328,12 +329,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)); @@ -407,7 +408,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)); @@ -427,7 +428,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); @@ -513,7 +514,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); } /** @@ -589,7 +590,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(); @@ -659,10 +660,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); @@ -807,7 +808,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); @@ -986,7 +987,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 @@ -1001,7 +1002,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) { @@ -1010,7 +1011,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 { @@ -1068,26 +1069,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(); } @@ -3273,7 +3274,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 @@ -3770,7 +3771,7 @@ break; default: atkSpd = getStat().getPAtkSpd(); - } + } } return Formulas.getInstance().calcPAtkSpd(this, target, atkSpd); } Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/SevenSignsFestival.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/SevenSignsFestival.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/SevenSignsFestival.java (working copy) @@ -1,6 +1,7 @@ package net.sf.l2j.gameserver; import java.io.InputStream; +import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.List; @@ -1017,7 +1018,27 @@ statement.close(); con.close(); - Properties festivalData = new Properties(); + String query = "SELECT festival_cycle, "; + for(int i = 0; i < FESTIVAL_COUNT-1; i++) + query += "accumulated_bonus" + String.valueOf(i) + ", "; + query += "accumulated_bonus" + String.valueOf(FESTIVAL_COUNT -1) + " "; + query += "FROM seven_signs_status WHERE id=1"; + Connection con2 = L2DatabaseFactory.getInstance().getConnection(); + PreparedStatement statement2 = con2.prepareStatement(query); + ResultSet rset2 = statement2.executeQuery(); + + while(rset2.next()) + { + _festivalCycle = rset2.getInt("festival_cycle"); + for(int i = 0; i < FESTIVAL_COUNT; i++) + _accumulatedBonuses.add(i, rset2.getInt("accumulated_bonus" + String.valueOf(i))); + + } + + if (Config.DEBUG) + _log.info("SevenSignsFestival: Loaded data from SQL."); + + /*Properties festivalData = new Properties(); InputStream is = SevenSignsFestival.class.getResourceAsStream("/" + FESTIVAL_DATA_FILE); festivalData.load(is); is.close(); @@ -1028,7 +1049,7 @@ _accumulatedBonuses.add(i, Integer.parseInt(festivalData.getProperty("AccumulatedBonus_" + i, "0"))); if (Config.DEBUG) - _log.info("SevenSignsFestival: Loaded data from signs.properties."); + _log.info("SevenSignsFestival: Loaded data from signs.properties."); */ } /** Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/CommunityBoard.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/CommunityBoard.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/CommunityBoard.java (working copy) @@ -1097,11 +1097,7 @@ if (player != null) { - String sex = "Male"; - if (player.getSex() == 1) - { - sex = "Female"; - } + String sex = player.getSex()==1 ? "Female" : "Male"; String levelApprox = "low"; if (player.getLevel() >= 60) levelApprox = "very high"; @@ -1197,6 +1193,19 @@ if (activeChar != null) { Collection players = L2World.getInstance().getAllPlayers(); + int invisible_admins=0; + int admins=0; + + for(L2PcInstance player : players) + { + if(player.isGM()) + { + admins++; + if(player.getInvisible()>0) + invisible_admins++; + } + } + String tdClose = ""; String tdOpen = ""; String trClose = ""; @@ -1254,15 +1263,15 @@ { htmlCode.append(trOpen); htmlCode.append(tdOpen + L2World.getInstance().getAllVisibleObjects().size() - + " Object count"); + + " Object count "+admins +" GMs online"); htmlCode.append(trClose); } htmlCode.append(trOpen); - htmlCode.append(tdOpen + players.size() + " Player(s) Online:"); + htmlCode.append(tdOpen + (players.size()-invisible_admins) + " Player(s) Online:"); htmlCode.append(trClose); htmlCode.append(""); - + int i; htmlCode.append(""); htmlCode.append(""); + public void showMainPage2(L2PcInstance activeChar) + { + NpcHtmlMessage adminReply = new NpcHtmlMessage(5); + StringBuffer replyMSG = new StringBuffer(""); + replyMSG.append("
"); @@ -1275,12 +1284,17 @@ L2PcInstance player = iterator.next(); // Get the current record if (i < startIndex) continue; // If not at start index - if (player == null) // If object is null + if (player == null) { i--; // Don't count the current loop continue; // Go to next } + if(Config.INVIS_HIDES_FROM_COMMUNITY && player.getInvisible()>0) // if player is invisible, don't show + { + i--; // Don't count the current loop + continue; // Go to next + } cell++; if (cell == 1) htmlCode.append(trOpen); @@ -1288,7 +1302,7 @@ htmlCode.append("
"); - if (player.isGM()) htmlCode.append("" + player.getName() + if (player.isGM() && player.getAccessLevel()>=Config.GM_COLOR_COMMUNITY_LEVEL) htmlCode.append("" + player.getName() + ""); else htmlCode.append(player.getName()); Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/handler/AdminCommandHandler.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/handler/AdminCommandHandler.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/handler/AdminCommandHandler.java (working copy) @@ -20,7 +20,6 @@ import java.io.FileInputStream; import java.io.InputStream; -import java.math.BigInteger; import java.util.Map; import java.util.Properties; import java.util.logging.Logger; @@ -78,7 +77,7 @@ command = adminCommand.substring(0, adminCommand.indexOf(" ")); } if (Config.DEBUG) - _log.fine("getting handler for command: "+command+ + _log.warning("getting handler for command: "+command+ " -> "+(_datatable.get(new String(command)) != null)); return _datatable.get(command); } @@ -93,29 +92,36 @@ public final boolean checkPrivileges(L2PcInstance player, String adminCommand) { - //Only a GM can execute a admin command - if (!player.isGM()) - return false; - //Skip special privileges handler? if (!Config.ALT_PRIVILEGES_ADMIN || Config.EVERYBODY_HAS_ADMIN_RIGHTS) return true; + + //Only a GM can execute a admin command + if (player.getAccessLevel()<1) + return false; if (_privileges == null) _privileges = new FastMap(); String command = adminCommand; + if (adminCommand.indexOf(" ") != -1) { command = adminCommand.substring(0, adminCommand.indexOf(" ")); } + if(Config.DEBUG) + _log.warning("searching _datatable for \""+command+"\""); + //The command not exists if (!_datatable.containsKey(command)) + { + _log.warning("Handler for command \""+command+"\" not found, so no chance to execute that command"); return false; + } int requireLevel = 0; - if (!_privileges.containsKey(command)) + if (!_privileges.containsKey("_admin"+command)) { //Try to loaded the command config boolean isLoaded = false; @@ -123,12 +129,25 @@ try { Properties Settings = new Properties(); + // uhm must find better Properties() class to use .. this one is bugged to the bone + InputStream is = new FileInputStream(Config.COMMAND_PRIVILEGES_FILE); Settings.load(is); is.close(); - String stringLevel = Settings.getProperty(command); - + if(Config.DEBUG) + { + _log.finest(""); + _log.finest(""); + _log.finest("Settings loaded: "+Settings.toString()); + _log.finest(""); + _log.finest(""); + if(Settings.containsKey(command)) _log.info("contains "+command); + if(Settings.containsKey("admin_"+command)) _log.info("contains admin_"+command); + }; + + String stringLevel = Settings.getProperty("admin_"+command); + if (stringLevel == null) stringLevel = Settings.getProperty(command); if (stringLevel != null) { isLoaded = true; @@ -142,7 +161,7 @@ { if (Config.ALT_PRIVILEGES_SECURE_CHECK) { - _priviLog.info("The command '" + command + "' haven't got a entry in the configuration file. The command cannot be executed!!"); + _priviLog.info("The command '" + command + "' haven't got a entry in the configuration file. The command cannot be executed!!!"); return false; } @@ -161,7 +180,6 @@ _priviLog.warning("" + player.getName() + ": have not access level to execute the command '" + command +"'"); return false; } - return true; } } Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminAdmin.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminAdmin.java (revision 2186) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminAdmin.java (working copy) @@ -6,7 +6,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -14,7 +14,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * - * [URL]http://www.gnu.org/copyleft/gpl.html[/URL] + * http://www.gnu.org/copyleft/gpl.html */ package net.sf.l2j.gameserver.handler.admincommandhandlers; @@ -42,141 +42,166 @@ * * @version $Revision: 1.3.2.1.2.4 $ $Date: 2005/04/11 10:06:06 $ */ -public class AdminAdmin implements IAdminCommandHandler { +public class AdminAdmin implements IAdminCommandHandler +{ - private static String[] _adminCommands = {"admin_admin","admin_play_sounds","admin_play_sound", - "admin_gmliston","admin_gmlistoff","admin_silence", - "admin_atmosphere","admin_diet","admin_tradeoff", - "admin_reload"}; - private static final int REQUIRED_LEVEL = Config.GM_MENU; + private static String[] _adminCommands = {"admin_admin", "admin_admin2", "admin_play_sounds", + "admin_play_sound", "admin_gmliston", "admin_gmlistoff", + "admin_silence", "admin_tradeoff", "admin_atmosphere", + "admin_diet", "admin_tradeoff", "admin_snoop", + "admin_reload"}; + private static final int REQUIRED_LEVEL = Config.GM_MENU; - public boolean useAdminCommand(String command, L2PcInstance activeChar) { - + public boolean useAdminCommand(String command, L2PcInstance activeChar) + { + if (!Config.ALT_PRIVILEGES_ADMIN) if (!(checkLevel(activeChar.getAccessLevel()) && activeChar.isGM())) return false; - - if (command.equals("admin_admin")) showMainPage(activeChar); - if (command.equals("admin_play_sounds")) - { - AdminHelpPage.showHelpPage(activeChar, "songs/songs.htm"); - } + if (command.equals("admin_admin")) showMainPage(activeChar); + if (command.equals("admin_admin2")) showMainPage2(activeChar); - else if (command.startsWith("admin_play_sounds")) - { + if (command.equals("admin_play_sounds")) + { + AdminHelpPage.showHelpPage(activeChar, "songs/songs.htm"); + } + + else if (command.startsWith("admin_play_sounds")) + { try { - AdminHelpPage.showHelpPage(activeChar, "songs/songs"+command.substring(17)+".htm"); + AdminHelpPage.showHelpPage(activeChar, "songs/songs" + command.substring(17) + ".htm"); } catch (StringIndexOutOfBoundsException e) - { } - } + { + } + } - else if (command.startsWith("admin_play_sound")) - { + else if (command.startsWith("admin_play_sound")) + { try { - playAdminSound(activeChar,command.substring(17)); + playAdminSound(activeChar, command.substring(17)); } catch (StringIndexOutOfBoundsException e) - { } - } - - else if(command.startsWith("admin_gmliston")) - { - GmListTable.getInstance().addGm(activeChar); + { + } + } + + else if (command.startsWith("admin_gmliston")) + { + GmListTable.getInstance().addGm(activeChar); activeChar.sendMessage("Registerd into gm list"); - } - - else if(command.startsWith("admin_gmlistoff")) - { - GmListTable.getInstance().deleteGm(activeChar); + } + + else if (command.startsWith("admin_gmlistoff")) + { + GmListTable.getInstance().deleteGm(activeChar); activeChar.sendMessage("Removed from gm list"); - } - - else if(command.startsWith("admin_silence")) - { - if(activeChar.getMessageRefusal()) // already in message refusal mode - { - activeChar.setMessageRefusal(false); - SystemMessage _sm = new SystemMessage(SystemMessage.MESSAGE_ACCEPTANCE_MODE); - activeChar.sendPacket(_sm); - } - else - { - activeChar.setMessageRefusal(true); - SystemMessage _sm = new SystemMessage(SystemMessage.MESSAGE_REFUSAL_MODE); - activeChar.sendPacket(_sm); - } - - } - - else if(command.startsWith("admin_atmosphere")) + } + + else if (command.startsWith("admin_silence")) { + if (activeChar.getMessageRefusal()) // already in message refusal mode + { + activeChar.setMessageRefusal(false); + SystemMessage _sm = new SystemMessage(SystemMessage.MESSAGE_ACCEPTANCE_MODE); + activeChar.sendPacket(_sm); + } + else + { + activeChar.setMessageRefusal(true); + SystemMessage _sm = new SystemMessage(SystemMessage.MESSAGE_REFUSAL_MODE); + activeChar.sendPacket(_sm); + } + + } + else if (command.startsWith("admin_snoop")) + { + StringTokenizer st = new StringTokenizer(command); + if (st.countTokens() > 1) + { + st.nextToken(); + String player = st.nextToken(); + L2PcInstance plyr = L2World.getInstance().getPlayer(player); + if (plyr != null) + { + if (!plyr.isSnoopedBy(activeChar)) + { + plyr.addSnoop(activeChar); + activeChar.sendMessage("You are snooping on " + plyr.getName()); + } + else + { + plyr.removeSnoop(activeChar); + activeChar.sendMessage("You are no more snooping on " + plyr.getName()); + } + } + } + } + else if (command.startsWith("admin_atmosphere")) + { try { StringTokenizer st = new StringTokenizer(command); st.nextToken(); String type = st.nextToken(); + String state = st.nextToken(); - adminAtmosphere(type,state,activeChar); + adminAtmosphere(type, state, activeChar); } - catch(Exception ex) + catch (Exception ex) { } } - else if(command.startsWith("admin_diet")) + else if (command.startsWith("admin_diet")) { try { StringTokenizer st = new StringTokenizer(command); st.nextToken(); - if(st.nextToken().equalsIgnoreCase("on")) + if (st.nextToken().equalsIgnoreCase("on")) { activeChar.setDietMode(true); activeChar.refreshOverloaded(); activeChar.sendMessage("Diet mode on"); } - else if(st.nextToken().equalsIgnoreCase("off")) + else if (st.nextToken().equalsIgnoreCase("off")) { activeChar.setDietMode(false); activeChar.sendMessage("Diet mode off"); } } - catch(Exception ex) + catch (Exception ex) { - if(activeChar.getDietMode()) - activeChar.sendMessage("Diet mode currently on"); - else - activeChar.sendMessage("Diet mode currently off"); - } + if (activeChar.getDietMode()) activeChar.sendMessage("Diet mode currently on"); + else activeChar.sendMessage("Diet mode currently off"); + } } - else if(command.startsWith("admin_tradeoff")) + else if (command.startsWith("admin_tradeoff")) { try { StringTokenizer st = new StringTokenizer(command); st.nextToken(); - if(st.nextToken().equalsIgnoreCase("on")) + if (st.nextToken().equalsIgnoreCase("on")) { activeChar.setTradeRefusal(true); activeChar.sendMessage("tradeoff enabled"); } - else if(st.nextToken().equalsIgnoreCase("off")) + else if (st.nextToken().equalsIgnoreCase("off")) { activeChar.setTradeRefusal(false); activeChar.sendMessage("tradeoff disabled"); } } - catch(Exception ex) + catch (Exception ex) { - if(activeChar.getTradeRefusal()) - activeChar.sendMessage("tradeoff currently enabled"); - else - activeChar.sendMessage("tradeoff currently disabled"); - } + if (activeChar.getTradeRefusal()) activeChar.sendMessage("tradeoff currently enabled"); + else activeChar.sendMessage("tradeoff currently disabled"); + } } - else if(command.startsWith("admin_reload")) + else if (command.startsWith("admin_reload")) { StringTokenizer st = new StringTokenizer(command); st.nextToken(); @@ -185,41 +210,41 @@ { String type = st.nextToken(); - if(type.equals("multisell")) + if (type.equals("multisell")) { L2Multisell.getInstance().reload(); activeChar.sendMessage("multisell reloaded"); } - else if(type.contains("skill")) + else if (type.contains("skill")) { SkillTable.getInstance().reload(); activeChar.sendMessage("skills reloaded"); } - else if(type.contains("npc")) + else if (type.contains("npc")) { NpcTable.getInstance().reloadAllNpc(); activeChar.sendMessage("npcs reloaded"); } } - catch(Exception e) + catch (Exception e) { - activeChar.sendMessage("Usage: //reload "); + activeChar.sendMessage("Usage: //reload "); } } - return true; - } + return true; + } - public String[] getAdminCommandList() - { - return _adminCommands; - } + public String[] getAdminCommandList() + { + return _adminCommands; + } - private boolean checkLevel(int level) - { - return (level >= REQUIRED_LEVEL); - } - + private boolean checkLevel(int level) + { + return (level >= REQUIRED_LEVEL); + } + /** * * @param type - atmosphere type (signssky,sky) @@ -228,28 +253,28 @@ public void adminAtmosphere(String type, String state, L2PcInstance activeChar) { ServerBasePacket packet = null; - - if(type.equals("signsky")) + + if (type.equals("signsky")) { - if(state.equals("dawn")) + if (state.equals("dawn")) { packet = new SignsSky(2); } - else if(state.equals("dusk")) + else if (state.equals("dusk")) { packet = new SignsSky(1); } } - else if(type.equals("sky")) + else if (type.equals("sky")) { - if(state.equals("night")) - { - packet = new SunSet(); - } - else if(state.equals("day")) - { - packet = new SunRise(); - } + if (state.equals("night")) + { + packet = new SunSet(); + } + else if (state.equals("day")) + { + packet = new SunRise(); + } } else { @@ -258,7 +283,7 @@ activeChar.sendPacket(sm); } - if(packet != null) + if (packet != null) { for (L2PcInstance player : L2World.getInstance().getAllPlayers()) { @@ -266,54 +291,53 @@ } } } - - public void playAdminSound(L2PcInstance activeChar, String sound) - { - PlaySound _snd = new PlaySound(1,sound,0,0,0,0,0); - activeChar.sendPacket(_snd); - activeChar.broadcastPacket(_snd); - showMainPage(activeChar); - SystemMessage _sm = new SystemMessage(614); - _sm.addString("Playing "+sound+"."); - activeChar.sendPacket(_sm); - } - public void showMainPage(L2PcInstance activeChar) - { - NpcHtmlMessage adminReply = new NpcHtmlMessage(5); + public void playAdminSound(L2PcInstance activeChar, String sound) + { + PlaySound _snd = new PlaySound(1, sound, 0, 0, 0, 0, 0); + activeChar.sendPacket(_snd); + activeChar.broadcastPacket(_snd); + showMainPage(activeChar); + SystemMessage _sm = new SystemMessage(614); + _sm.addString("Playing " + sound + "."); + activeChar.sendPacket(_sm); + } - StringBuffer replyMSG = new StringBuffer(""); - - replyMSG.append("
L2J Admin Panel

"); - replyMSG.append("
"); - replyMSG.append(""); - replyMSG.append("

"); + public void showMainPage(L2PcInstance activeChar) + { + NpcHtmlMessage adminReply = new NpcHtmlMessage(5); + + StringBuffer replyMSG = new StringBuffer(""); + replyMSG.append("
L2J Admin Support Panel

"); + replyMSG.append("
"); + replyMSG.append(""); + replyMSG.append("

"); replyMSG.append("
Name / Karma / Ench 0-65535:
"); replyMSG.append("

"); replyMSG.append("
"); replyMSG.append(""); replyMSG.append(""); - replyMSG.append("
"); @@ -335,12 +359,59 @@ replyMSG.append("



"); + replyMSG.append("
"); + replyMSG.append(""); + adminReply.setHtml(replyMSG.toString()); + activeChar.sendPacket(adminReply); + } - replyMSG.append("
Server Software: Server software running L2J version 3.0.1 nightly created by L2Chef and the L2J team.
L2J Admin Support Panel

"); + replyMSG.append("
"); + replyMSG.append(""); + replyMSG.append("

"); + replyMSG.append("
Name / Karma / Ench 0-65535
"); + replyMSG.append("

"); + replyMSG.append("
"); + replyMSG.append(""); + replyMSG.append("

"); + replyMSG.append("
Server Create: L2J
"); replyMSG.append(""); + adminReply.setHtml(replyMSG.toString()); + activeChar.sendPacket(adminReply); - adminReply.setHtml(replyMSG.toString()); - activeChar.sendPacket(adminReply); - } + } } Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/GameServer.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/GameServer.java (revision 2186) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/GameServer.java (working copy) @@ -78,6 +78,8 @@ import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminTest; import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminUnblockIp; import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminZone; +import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminEvent; +import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminEncArmor; import net.sf.l2j.gameserver.handler.itemhandlers.AdvQuestItems; import net.sf.l2j.gameserver.handler.itemhandlers.BlessedSpiritShot; import net.sf.l2j.gameserver.handler.itemhandlers.CharChangePotions; @@ -142,6 +144,7 @@ * * @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()); @@ -178,8 +181,7 @@ return _selectorThread; } - - public GameServer() throws Exception + public GameServer() throws Exception { gameServer = this; _log.finest("used mem:" + getUsedMemoryMB()+"MB" ); @@ -199,7 +201,7 @@ ClientScheduler.getInstance(); _selectorThread = new SelectorThread(Config.GAMESERVER_HOSTNAME, Config.PORT_GAME); - _selectorThread.start(); + _log.config("Maximum Numbers of Connected Players: " + Config.MAXIMUM_ONLINE_USERS); @@ -349,6 +351,7 @@ _adminCommandHandler.registerAdminCommandHandler(new AdminShutdown()); _adminCommandHandler.registerAdminCommandHandler(new AdminSpawn()); _adminCommandHandler.registerAdminCommandHandler(new AdminSkill()); + _adminCommandHandler.registerAdminCommandHandler(new AdminEvent()); _adminCommandHandler.registerAdminCommandHandler(new AdminExpSp()); _adminCommandHandler.registerAdminCommandHandler(new AdminGmChat()); _adminCommandHandler.registerAdminCommandHandler(new AdminEditChar()); @@ -369,6 +372,7 @@ _adminCommandHandler.registerAdminCommandHandler(new AdminEffects()); _adminCommandHandler.registerAdminCommandHandler(new AdminDoorControl()); _adminCommandHandler.registerAdminCommandHandler(new AdminTest()); + _adminCommandHandler.registerAdminCommandHandler(new AdminEncArmor()); _adminCommandHandler.registerAdminCommandHandler(new AdminMobGroup()); _adminCommandHandler.registerAdminCommandHandler(new AdminRes()); _adminCommandHandler.registerAdminCommandHandler(new AdminMammon()); @@ -432,7 +436,7 @@ _log.config("IdFactory: Free ObjectID's remaining: " + IdFactory.getInstance().size()); - System.gc(); + System.gc(); // 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; @@ -441,6 +445,7 @@ _loginThread = LoginServerThread.getInstance(); _loginThread.setMaxPlayer(Config.MAXIMUM_ONLINE_USERS); _loginThread.start(); + _selectorThread.start(); } public static void main(String[] args) throws Exception Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/transaction/TransactionLogFormatter.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/transaction/TransactionLogFormatter.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/transaction/TransactionLogFormatter.java (working copy) @@ -33,6 +33,8 @@ import java.util.logging.Formatter; import java.util.logging.LogRecord; +import net.sf.l2j.Config; + /** * This class ... * @@ -42,7 +44,7 @@ public class TransactionLogFormatter extends Formatter { //private static final String _ = ": "; - private static final String CRLF = "\r\n"; + private static final String CRLF = Config.NEWLINE_CRLF ? "\r\n" : "\n"; private SimpleDateFormat dateFmt = new SimpleDateFormat("dd MMM H:mm:ss"); Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ItemTable.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ItemTable.java (revision 2183) +++ 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 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2AttackableAI.java (working copy) @@ -206,45 +206,53 @@ */ synchronized void changeIntention(CtrlIntention intention, Object arg0, Object arg1) { - if (intention == AI_INTENTION_IDLE || intention == AI_INTENTION_ACTIVE) + if (intention == AI_INTENTION_ACTIVE) + { + intention = AI_INTENTION_IDLE; // suppose we don't need AI anymore + + // Check if actor is not dead + if(!_actor.isAlikeDead()) + { + // find at least one L2PcInstance worth keeping AI active (in knownlist but also not dead) + for(L2PcInstance in:((L2Attackable)_actor).getKnownList().getKnownPlayers()) + { + if(in!=null && !in.isAlikeDead()) + { + intention=AI_INTENTION_ACTIVE; // found one, worth activating + break; + } + } + } + } + + // ================================================================== + + if (intention == AI_INTENTION_IDLE) { - // Check if actor is not dead - if (!_actor.isAlikeDead()) + // Set the Intention of this L2AttackableAI to AI_INTENTION_IDLE + super.changeIntention(AI_INTENTION_IDLE, null, null); + + // Stop AI task and detach AI from NPC + if (aiTask != null) { - L2Attackable npc = (L2Attackable)_actor; - - // If its _knownPlayer isn't empty set the Intention to AI_INTENTION_ACTIVE - Collection knownPlayers = npc.getKnownList().getKnownPlayers(); - if (knownPlayers != null && knownPlayers.size() > 0) - intention = AI_INTENTION_ACTIVE; + aiTask.cancel(true); + aiTask = null; } - - if (intention == AI_INTENTION_IDLE) - { - // Set the Intention of this L2AttackableAI to AI_INTENTION_IDLE - super.changeIntention(AI_INTENTION_IDLE, null, null); - - // Stop AI task and detach AI from NPC - if (aiTask != null) - { - aiTask.cancel(true); - aiTask = null; - } - // Cancel the AI - _accessor.detachAI(); + // Cancel the AI + _accessor.detachAI(); - return; - } + return; } + // Set the Intention of this L2AttackableAI to intention super.changeIntention(intention, arg0, arg1); // 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); } } @@ -351,7 +359,7 @@ // Order to the L2Attackable to attack the target - if (hated != null) + if (hated != null && !hated.isAlikeDead()) { // Get the hate level of the L2Attackable against this L2Character target contained in _aggroList int aggro = npc.getHating(hated); Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2CharacterAI.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2CharacterAI.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2CharacterAI.java (working copy) @@ -193,6 +193,12 @@ return; } + if(target.isAlikeDead()) + { + notifyEvent(CtrlEvent.EVT_CANCEL, target); + _log.warning("added evt_cancel for "+target); + } + if (getIntention() == AI_INTENTION_REST) { // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2PlayerAI.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2PlayerAI.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2PlayerAI.java (working copy) @@ -255,6 +255,8 @@ private void thinkPickUp() { if (_actor.isAllSkillsDisabled()) return; + if (_actor.isAlikeDead()) + return; if (checkTargetLost(getTarget())) return; if (maybeMoveToPawn(getTarget(), 36)) 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 2183) +++ 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 2183) +++ 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(); - } /** @@ -155,40 +153,41 @@ */ synchronized void changeIntention(CtrlIntention intention, Object arg0, Object arg1) { - if (Config.DEBUG) - _log.info("L2SiegeAI.changeIntention(" + intention + ", " + arg0 + ", " + arg1+")"); + if (intention == AI_INTENTION_ACTIVE) + { + intention = AI_INTENTION_IDLE; - if (intention == AI_INTENTION_IDLE || intention == AI_INTENTION_ACTIVE) - { // Check if actor is not dead if(!_actor.isAlikeDead()) { - L2Attackable npc = (L2Attackable)_actor; - - // If its _knownPlayer isn't empty set the Intention to AI_INTENTION_ACTIVE - if(npc.getKnownList().getKnownPlayers().size() > 0) - intention = AI_INTENTION_ACTIVE; - else - intention = AI_INTENTION_IDLE; + // find at least one L2PcInstance worth keeping AI active (in knownlist but also not dead) + for(L2PcInstance in:((L2Attackable)_actor).getKnownList().getKnownPlayers()) + { + if(in!=null && !in.isAlikeDead()) + { + intention=AI_INTENTION_ACTIVE; // found one, worth activating + break; + } + } } + } - if (intention == AI_INTENTION_IDLE) + if (intention == AI_INTENTION_IDLE) + { + // Set the Intention of this L2AttackableAI to AI_INTENTION_IDLE + super.changeIntention(AI_INTENTION_IDLE, null, null); + + // Stop AI task and detach AI from NPC + if (aiTask != null) { - // Set the Intention of this L2AttackableAI to AI_INTENTION_IDLE - super.changeIntention(AI_INTENTION_IDLE, null, null); - - // Stop AI task and detach AI from NPC - if (aiTask != null) - { - aiTask.cancel(true); - aiTask = null; - } + aiTask.cancel(true); + aiTask = null; + } - // Cancel the AI - _accessor.detachAI(); + // Cancel the AI + _accessor.detachAI(); - return; - } + return; } // Set the Intention of this L2AttackableAI to intention @@ -197,7 +196,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 +561,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 +609,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 +671,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 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/AbstractAI.java (working copy) @@ -29,6 +29,7 @@ import net.sf.l2j.gameserver.ClientScheduler; import net.sf.l2j.gameserver.GameTimeController; import net.sf.l2j.gameserver.model.L2CharPosition; +import net.sf.l2j.gameserver.model.L2Attackable; import net.sf.l2j.gameserver.model.L2Character; import net.sf.l2j.gameserver.model.L2Object; import net.sf.l2j.gameserver.model.L2PcInstance; @@ -245,10 +246,10 @@ if (!_actor.isVisible() || !_actor.hasAI()) return; - /* - if (Config.DEBUG) + + /* _log.warning("AbstractAI: setIntention -> " + intention + " " + arg0 + " " + arg1); - */ + */ // Stop the follow mode if necessary if (intention != AI_INTENTION_FOLLOW && intention != AI_INTENTION_ATTACK) @@ -714,7 +715,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 +733,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 2183) +++ 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,687 @@ 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); + 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.95); + + // 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 2183) +++ 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 2183) +++ 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 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/taskmanager/TaskManager.java (working copy) @@ -24,12 +24,12 @@ 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; import net.sf.l2j.gameserver.taskmanager.tasks.TaskSevenSignsUpdate; import net.sf.l2j.gameserver.taskmanager.tasks.TaskShutdown; +import net.sf.l2j.gameserver.taskmanager.tasks.TaskSevenSignsStatus; /** * @author Layane @@ -163,12 +163,12 @@ private void initializate() { - registerTask(new TaskCleanUp()); registerTask(new TaskJython()); registerTask(new TaskRecom()); registerTask(new TaskRestart()); registerTask(new TaskSevenSignsUpdate()); registerTask(new TaskShutdown()); + registerTask(new TaskSevenSignsStatus()); } public void registerTask(Task task) Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/SevenSigns.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/SevenSigns.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/SevenSigns.java (working copy) @@ -1,14 +1,11 @@ package net.sf.l2j.gameserver; -import java.io.File; -import java.io.FileOutputStream; -import java.io.InputStream; +import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Calendar; import java.util.List; import java.util.Map; -import java.util.Properties; import java.util.logging.Logger; import javolution.util.FastList; @@ -42,250 +39,236 @@ * * @author Tempy */ -public class SevenSigns { +public class SevenSigns +{ protected static Logger _log = Logger.getLogger(SevenSigns.class.getName()); - private static SevenSigns _instance; + private static SevenSigns _instance; - // Basic Seven Signs Constants \\ - public static final String SEVEN_SIGNS_DATA_FILE = "config/signs.properties"; - public static final String SEVEN_SIGNS_HTML_PATH = "data/html/seven_signs/"; - - public static final int CABAL_NULL = 0; - public static final int CABAL_DUSK = 1; - public static final int CABAL_DAWN = 2; - - public static final int SEAL_NULL = 0; - public static final int SEAL_AVARICE = 1; - public static final int SEAL_GNOSIS = 2; - public static final int SEAL_STRIFE = 3; + // Basic Seven Signs Constants \\ + public static final String SEVEN_SIGNS_DATA_FILE = "config/signs.properties"; + public static final String SEVEN_SIGNS_HTML_PATH = "data/html/seven_signs/"; - public static final int PERIOD_COMP_RECRUITING = 0; - public static final int PERIOD_COMPETITION = 1; - public static final int PERIOD_COMP_RESULTS = 2; - public static final int PERIOD_SEAL_VALIDATION = 3; - - public static final int PERIOD_START_HOUR = 1; - public static final int PERIOD_START_MINS = 20; + public static final int CABAL_NULL = 0; + public static final int CABAL_DUSK = 1; + public static final int CABAL_DAWN = 2; + + public static final int SEAL_NULL = 0; + public static final int SEAL_AVARICE = 1; + public static final int SEAL_GNOSIS = 2; + public static final int SEAL_STRIFE = 3; + + public static final int PERIOD_COMP_RECRUITING = 0; + public static final int PERIOD_COMPETITION = 1; + public static final int PERIOD_COMP_RESULTS = 2; + public static final int PERIOD_SEAL_VALIDATION = 3; + + public static final int PERIOD_START_HOUR = 1; + public static final int PERIOD_START_MINS = 20; public static final int PERIOD_START_DAY = Calendar.MONDAY; // The quest event and seal validation periods last for approximately one week // with a 1 hour "interval" period sandwiched between them. public static final int PERIOD_MINOR_LENGTH = 3600000; public static final int PERIOD_MAJOR_LENGTH = 604800000 - PERIOD_MINOR_LENGTH; - - public static final int ANCIENT_ADENA_ID = 5575; - public static final int RECORD_SEVEN_SIGNS_ID = 5707; + + public static final int ANCIENT_ADENA_ID = 5575; + public static final int RECORD_SEVEN_SIGNS_ID = 5707; public static final int CERTIFICATE_OF_APPROVAL_ID = 6388; - public static final int RECORD_SEVEN_SIGNS_COST = 500; + public static final int RECORD_SEVEN_SIGNS_COST = 500; public static final int ADENA_JOIN_DAWN_COST = 50000; // NPC Related Constants \\ - public static final int ORATOR_NPC_ID = 8094; - public static final int PREACHER_NPC_ID = 8093; + public static final int ORATOR_NPC_ID = 8094; + public static final int PREACHER_NPC_ID = 8093; public static final int MAMMON_MERCHANT_ID = 8113; public static final int MAMMON_BLACKSMITH_ID = 8126; public static final int LILITH_NPC_ID = 10283; public static final int ANAKIM_NPC_ID = 10286; - // Seal Stone Related Constants \\ - public static final int SEAL_STONE_BLUE_ID = 6360; - public static final int SEAL_STONE_GREEN_ID = 6361; - public static final int SEAL_STONE_RED_ID = 6362; - - public static final int SEAL_STONE_BLUE_VALUE = 3; - public static final int SEAL_STONE_GREEN_VALUE = 5; - public static final int SEAL_STONE_RED_VALUE = 10; + // Seal Stone Related Constants \\ + public static final int SEAL_STONE_BLUE_ID = 6360; + public static final int SEAL_STONE_GREEN_ID = 6361; + public static final int SEAL_STONE_RED_ID = 6362; - private static final int BLUE_CONTRIB_POINTS = 1; - private static final int GREEN_CONTRIB_POINTS = 5; - private static final int RED_CONTRIB_POINTS = 10; + public static final int SEAL_STONE_BLUE_VALUE = 3; + public static final int SEAL_STONE_GREEN_VALUE = 5; + public static final int SEAL_STONE_RED_VALUE = 10; - // There is a max on official, but not sure what! - private static final int MAXIMUM_PLAYER_CONTRIB = 300000; - - // NPC Related Constants \\ - private static final int [][] merchantSpawns = { - {172373, -17833, -4901}, // Disciples - {83175, 208998, -5439}, // Saints - {118343, 132578, -4831}, // Martyrs - {-52172, 78884, -4741}, // Ascetics - {-21657, 77164, -5173}, // Patriots - {111337, 173804, -5439}, // Worshippers - {45029, 123802, -5413}, // Pilgrims - {-41350, 209876, -5087}, // Sacrifice - }; + private static final int BLUE_CONTRIB_POINTS = 1; + private static final int GREEN_CONTRIB_POINTS = 5; + private static final int RED_CONTRIB_POINTS = 10; - private static final int [][] blacksmithSpawns = { - {114013, 84326, -6541}, // Forbidden Path - {-19360, 13278, -4901}, // Dark Omens - {140519, 79464, -5429}, // Witch - {77787, 78176, -5125}, // Apostate - {46303, 170091, -4981}, // Branded - {43093, 143706, -5381}, // Heretics - }; - - private static final int[][] oratorSpawns = { - //Dion - {16901, 144748, -3027}, - {17557, 147084, -3150}, - {20826, 145769, -3171}, - {19038, 142923, -3078}, - //Oren - {81002, 53495, -1586}, - {80039, 54291, -1586}, - {81527, 56009, -1551}, - //Aden - {143926, 26468, -2338}, - {150417, 25182, -2141}, - {147460, 20537, -2101}, - //Giran - {85328, 147352, -3431}, - {83872, 143882, -3431}, - {81540, 144204, -3559}, - {77830, 148627, -3623}, - {81556, 152183, -3559}, - //Hunters Village - {114907, 77916, -2662}, - {115509, 74857, -2625}, - {118273, 74592, -2529}, - //Gludio - {-12344, 123605, -3132}, - {-14199, 126128, -3171}, - {-16168, 124129, -3143}, - {-14563, 121461, -3015}, - //Gludin - {-83157, 149846, -3155}, - {-84356, 152742, -3204}, - {-79563, 152726, -3204}, - {-79123, 155098, -3204}, - //Heine - {115482, 219266, -3689}, - {107251, 218166, -3701} - }; + // There is a max on official, but not sure what! + private static final int MAXIMUM_PLAYER_CONTRIB = 300000; - private static final int[][] preacherSpawns = { - //Giran - {83319, 148054, -3431}, - {83894, 147495, -3431}, - {81547, 150347, -3559}, - {79825, 148619, -3559}, - {81535, 146866, -3559}, - //Dion - {15722, 142877, -2732}, - {18172, 145740, -3140}, - {19096, 143980, -3096}, - {19823, 145863, -3142}, - //Gludin - {-80690, 149996, -3070}, - {-83107, 150270, -3155}, - {-83070, 152740, -3204}, - {-80037, 154344, -3204}, - {-80752, 152738, -3204}, - //Gludio - {-12591, 122673, -3142}, - {-13252, 123689, -3143}, - {-14268, 124941, -3156}, - {-15549, 124170, -3143}, - {-14480, 122330, -3126}, - //Heine - {111389, 219257, -3572}, - {113479, 217795, -3731}, - {114086, 220214, -3568}, - {110189, 221393, -3569}, - {107256, 218615, -3701}, - {109660, 217339, -3775}, - //Hunters Village - {117098, 77066, -2720}, - {115893, 77551, -2729}, - {115936, 75382, -2625}, - {118049, 75783, -2715}, - //Oren - {82863, 53290, -1522}, - {80617, 54116, -1586}, - {80416, 55959, -1586}, - {82048, 55417, -1551}, - //Aden - {147440, 30047, -2487}, - {145394, 27629, -2295}, - {149515, 27641, -2295}, - {149899, 24719, -2167}, - {147459, 21148, -2167}, - {145015, 25269, -2167}, - {146616, 25816, -2039}, - {148013, 27029, -2231} - }; + // NPC Related Constants \\ + private static final int[][] merchantSpawns = { {172373, -17833, -4901}, // Disciples + {83175, 208998, -5439}, // Saints + {118343, 132578, -4831}, // Martyrs + {-52172, 78884, -4741}, // Ascetics + {-21657, 77164, -5173}, // Patriots + {111337, 173804, -5439}, // Worshippers + {45029, 123802, -5413}, // Pilgrims + {-41350, 209876, -5087}, // Sacrifice + }; - public static final String[] chatDoomPreacher = { - "The prophecy of doom has awoken!", - "All is lost! Prepare to meet the goddess of death!", - "All is lost! The prophecy of destruction has been fulfilled!", - "This world will soon be annihilated!", - "%player_cabal_loser%! You might as well give up!", - "%player_cabal_loser%! You bring an ill wind!", - "A curse upon you!", - "%player_cabal_loser%! All is lost! Prepare to meet the goddess of death!" - }; - - public static final String[] chatOratorRevelations = { - "%player_cabal_winner%, the time for glory is at hand!", - "The prophecy of darkness has been fulfilled!", - "The prophecy of darkness has come to pass!", - "As foretold in the prophecy of darkness, the era of chaos has begun!", - "The day of judgment is near!", - "%player_cabal_winner%, Darkness shall be banished forever!", - "All hail the eternal twilight!", - "%player_cabal_winner%! I bestow on you the authority of the abyss!" - }; - - // Current max of 30 items sellable right now. + private static final int[][] blacksmithSpawns = { {114013, 84326, -6541}, // Forbidden Path + {-19360, 13278, -4901}, // Dark Omens + {140519, 79464, -5429}, // Witch + {77787, 78176, -5125}, // Apostate + {46303, 170091, -4981}, // Branded + {43093, 143706, -5381}, // Heretics + }; + + private static final int[][] oratorSpawns = { + //Dion + {16901, 144748, -3027}, {17557, 147084, -3150}, + {20826, 145769, -3171}, {19038, 142923, -3078}, + //Oren + {81002, 53495, -1586}, {80039, 54291, -1586}, + {81527, 56009, -1551}, + //Aden + {143926, 26468, -2338}, {150417, 25182, -2141}, + {147460, 20537, -2101}, + //Giran + {85328, 147352, -3431}, {83872, 143882, -3431}, + {81540, 144204, -3559}, {77830, 148627, -3623}, + {81556, 152183, -3559}, + //Hunters Village + {114907, 77916, -2662}, {115509, 74857, -2625}, + {118273, 74592, -2529}, + //Gludio + {-12344, 123605, -3132}, {-14199, 126128, -3171}, + {-16168, 124129, -3143}, {-14563, 121461, -3015}, + //Gludin + {-83157, 149846, -3155}, {-84356, 152742, -3204}, + {-79563, 152726, -3204}, {-79123, 155098, -3204}, + //Heine + {115482, 219266, -3689}, {107251, 218166, -3701}}; + + private static final int[][] preacherSpawns = { + //Giran + {83319, 148054, -3431}, {83894, 147495, -3431}, + {81547, 150347, -3559}, {79825, 148619, -3559}, + {81535, 146866, -3559}, + //Dion + {15722, 142877, -2732}, {18172, 145740, -3140}, + {19096, 143980, -3096}, {19823, 145863, -3142}, + //Gludin + {-80690, 149996, -3070}, {-83107, 150270, -3155}, + {-83070, 152740, -3204}, {-80037, 154344, -3204}, + {-80752, 152738, -3204}, + //Gludio + {-12591, 122673, -3142}, {-13252, 123689, -3143}, + {-14268, 124941, -3156}, {-15549, 124170, -3143}, + {-14480, 122330, -3126}, + //Heine + {111389, 219257, -3572}, {113479, 217795, -3731}, + {114086, 220214, -3568}, {110189, 221393, -3569}, + {107256, 218615, -3701}, {109660, 217339, -3775}, + //Hunters Village + {117098, 77066, -2720}, {115893, 77551, -2729}, + {115936, 75382, -2625}, {118049, 75783, -2715}, + //Oren + {82863, 53290, -1522}, {80617, 54116, -1586}, + {80416, 55959, -1586}, {82048, 55417, -1551}, + //Aden + {147440, 30047, -2487}, {145394, 27629, -2295}, + {149515, 27641, -2295}, {149899, 24719, -2167}, + {147459, 21148, -2167}, {145015, 25269, -2167}, + {146616, 25816, -2039}, {148013, 27029, -2231}}; + + public static final String[] chatDoomPreacher = { + "The prophecy of doom has awoken!", + "All is lost! Prepare to meet the goddess of death!", + "All is lost! The prophecy of destruction has been fulfilled!", + "This world will soon be annihilated!", + "%player_cabal_loser%! You might as well give up!", + "%player_cabal_loser%! You bring an ill wind!", + "A curse upon you!", + "%player_cabal_loser%! All is lost! Prepare to meet the goddess of death!"}; + + public static final String[] chatOratorRevelations = { + "%player_cabal_winner%, the time for glory is at hand!", + "The prophecy of darkness has been fulfilled!", + "The prophecy of darkness has come to pass!", + "As foretold in the prophecy of darkness, the era of chaos has begun!", + "The day of judgment is near!", + "%player_cabal_winner%, Darkness shall be banished forever!", + "All hail the eternal twilight!", + "%player_cabal_winner%! I bestow on you the authority of the abyss!"}; + + // Current max of 30 items sellable right now. // Updated to include official prices as well as "modern" adena price. - public static final String[][] priestItems = { - // Greater Healing Potion - {"1539","1080","90","icon.etc_reagent_white_i00"}, - // Blessed Rez Scroll for Pet - {"6387","6000","500","etc_scroll_of_resurrection_pet_i01"}, - // Greater Haste Potion - {"1374","3600","360","etc_lesser_potion_green_i00"}, - // Greater Swift Attack Potion - {"1375","7200","600","etc_lesser_potion_purple_i00"}, - // Greater Magic Haste Potion - {"6036","7200","600","etc_potion_of_acumen3_i00"}, - // CP Potion - {"5591","240","20","etc_cp_potion_i00"}, - // Greater CP Potion - {"5592","600","50","etc_cp_potion_i01"}, - // SP Scroll - Low Grade - {"5593","2400","200","etc_sp_scroll1_i00"}, - // SP Scroll - Medium Grade - {"5594","24000","2000","etc_sp_scroll2_i00"}, - // SP Scroll - High Grade - {"5595","480000","40000","etc_sp_scroll3_i00"}, - // Mystery Potion - {"5234","12000","1000","etc_lesser_potion_clear_i00"}, - // Facelifting Potions A-C - {"5235","24000","2000","etc_lesser_potion_purple_i00"}, {"5236","24000","2000","etc_lesser_potion_purple_i00"}, - {"5237","24000","2000","etc_lesser_potion_purple_i00"}, - // Hair Dye Potions A-D - {"5238","24000","2000","etc_lesser_potion_scarlet_i00"}, {"5239","24000","2000","etc_lesser_potion_scarlet_i00"}, - {"5240","24000","2000","etc_lesser_potion_scarlet_i00"}, {"5241","24000","2000","etc_lesser_potion_scarlet_i00"}, - // Hair Style Change Potion A-G - {"5242","24000","2000","etc_lesser_potion_green_i00"}, {"5243","24000","2000","etc_lesser_potion_green_i00"}, - {"5244","24000","2000","etc_lesser_potion_green_i00"}, {"5245","24000","2000","etc_lesser_potion_green_i00"}, - {"5246","24000","2000","etc_lesser_potion_green_i00"}, {"5247","24000","2000","etc_lesser_potion_green_i00"}, - // Party Masks - {"5808","600000","50000","etc_party_mask_i00"}, {"6394","600000","50000","etc_party_mask_i01"}, - // Squeaking Shoes - {"5590","420000","35000","armor_cloth_shoes_i00"}, - // Record of the Seven Signs - {"5707","600","50","etc_ssq_scroll_i00"} - // Luck Charms - //{"5703","5000","etc_charm_of_luck_i00"},{"5803","7500","etc_charm_of_luck_i00"}, - //{"5804","11000","etc_charm_of_luck_i00"},{"5805","15000","etc_charm_of_luck_i00"},{"5806","21000","etc_charm_of_luck_i00"}, - //{"5807","28500","etc_charm_of_luck_i00"}, - }; // Total: 28 Items + public static final String[][] priestItems = { + // Greater Healing Potion + {"1539", "1080", "90", "icon.etc_reagent_white_i00"}, + // Blessed Rez Scroll for Pet + {"6387", "6000", "500", + "etc_scroll_of_resurrection_pet_i01"}, + // Greater Haste Potion + {"1374", "3600", "360", "etc_lesser_potion_green_i00"}, + // Greater Swift Attack Potion + {"1375", "7200", "600", "etc_lesser_potion_purple_i00"}, + // Greater Magic Haste Potion + {"6036", "7200", "600", "etc_potion_of_acumen3_i00"}, + // CP Potion + {"5591", "240", "20", "etc_cp_potion_i00"}, + // Greater CP Potion + {"5592", "600", "50", "etc_cp_potion_i01"}, + // SP Scroll - Low Grade + {"5593", "2400", "200", "etc_sp_scroll1_i00"}, + // SP Scroll - Medium Grade + {"5594", "24000", "2000", "etc_sp_scroll2_i00"}, + // SP Scroll - High Grade + {"5595", "480000", "40000", "etc_sp_scroll3_i00"}, + // Mystery Potion + {"5234", "12000", "1000", + "etc_lesser_potion_clear_i00"}, + // Facelifting Potions A-C + {"5235", "24000", "2000", + "etc_lesser_potion_purple_i00"}, + {"5236", "24000", "2000", + "etc_lesser_potion_purple_i00"}, + {"5237", "24000", "2000", + "etc_lesser_potion_purple_i00"}, + // Hair Dye Potions A-D + {"5238", "24000", "2000", + "etc_lesser_potion_scarlet_i00"}, + {"5239", "24000", "2000", + "etc_lesser_potion_scarlet_i00"}, + {"5240", "24000", "2000", + "etc_lesser_potion_scarlet_i00"}, + {"5241", "24000", "2000", + "etc_lesser_potion_scarlet_i00"}, + // Hair Style Change Potion A-G + {"5242", "24000", "2000", + "etc_lesser_potion_green_i00"}, + {"5243", "24000", "2000", + "etc_lesser_potion_green_i00"}, + {"5244", "24000", "2000", + "etc_lesser_potion_green_i00"}, + {"5245", "24000", "2000", + "etc_lesser_potion_green_i00"}, + {"5246", "24000", "2000", + "etc_lesser_potion_green_i00"}, + {"5247", "24000", "2000", + "etc_lesser_potion_green_i00"}, + // Party Masks + {"5808", "600000", "50000", "etc_party_mask_i00"}, + {"6394", "600000", "50000", "etc_party_mask_i01"}, + // Squeaking Shoes + {"5590", "420000", "35000", "armor_cloth_shoes_i00"}, + // Record of the Seven Signs + {"5707", "600", "50", "etc_ssq_scroll_i00"} + // Luck Charms + //{"5703","5000","etc_charm_of_luck_i00"},{"5803","7500","etc_charm_of_luck_i00"}, + //{"5804","11000","etc_charm_of_luck_i00"},{"5805","15000","etc_charm_of_luck_i00"},{"5806","21000","etc_charm_of_luck_i00"}, + //{"5807","28500","etc_charm_of_luck_i00"}, + }; // Total: 28 Items - private final Calendar _calendar = Calendar.getInstance(); - + private final Calendar _calendar = Calendar.getInstance(); + protected int _activePeriod; protected int _currentCycle; protected int _dawnStoneScore; @@ -294,168 +277,181 @@ protected int _duskFestivalScore; protected int _compWinner; protected int _previousWinner; - - private boolean _initializedSpawns; - private Map _signsPlayerData; - private List _signsNPCInsts; - - private Map _signsSealOwners; - private Map _signsDuskSealTotals; - private Map _signsDawnSealTotals; - + private boolean _initializedSpawns; + + private Map _signsPlayerData; + private List _signsNPCInsts; + + private Map _signsSealOwners; + private Map _signsDuskSealTotals; + private Map _signsDawnSealTotals; + private static AutoSpawnInstance _merchantSpawn; private static AutoSpawnInstance _blacksmithSpawn; private static AutoChatInstance _preacherChat; private static AutoChatInstance _oratorChat; - - public SevenSigns() - { - _signsPlayerData = new FastMap(); - _signsNPCInsts = new FastList(); - _signsSealOwners = new FastMap(); - _signsDuskSealTotals = new FastMap(); - _signsDawnSealTotals = new FastMap(); - - try { - restoreSevenSignsData(); - } - catch (Exception e) { - _log.severe("SevenSigns: Failed to load configuration: " + e); - } - - _log.info("SevenSigns: Currently in the " + getCurrentPeriodName() + " period!"); - initializeSeals(); - - if (isSealValidationPeriod()) - _log.info("SevenSigns: The " + getCabalName(getCabalHighestScore()) + " were victorious last week."); - else - _log.info("SevenSigns: The " + getCabalName(getCabalHighestScore()) + " are in the lead this week."); - - synchronized (this) - { + + public SevenSigns() + { + _signsPlayerData = new FastMap(); + _signsNPCInsts = new FastList(); + _signsSealOwners = new FastMap(); + _signsDuskSealTotals = new FastMap(); + _signsDawnSealTotals = new FastMap(); + + try + { + restoreSevenSignsData(); + } + catch (Exception e) + { + _log.severe("SevenSigns: Failed to load configuration: " + e); + } + + _log.info("SevenSigns: Currently in the " + getCurrentPeriodName() + " period!"); + initializeSeals(); + + if (isSealValidationPeriod()) _log.info("SevenSigns: The " + + getCabalName(getCabalHighestScore()) + " were victorious last week."); + else _log.info("SevenSigns: The " + getCabalName(getCabalHighestScore()) + + " are in the lead this week."); + + synchronized (this) + { setCalendarForNextPeriodChange(); - long milliToChange = getMilliToPeriodChange(); - - // Schedule a time for the next period change. - SevenSignsPeriodChange sspc = new SevenSignsPeriodChange(); - ClientScheduler.getInstance().scheduleMed(sspc, milliToChange); - - // Thanks to http://rainbow.arch.scriptmania.com/scripts/timezone_countdown.html for help with this. - double numSecs = (milliToChange / 1000) % 60; - double countDown = ((milliToChange / 1000) - numSecs) / 60; - int numMins = (int)Math.floor(countDown % 60); - countDown = (countDown - numMins) / 60; - int numHours = (int)Math.floor(countDown % 24); - int numDays = (int)Math.floor((countDown - numHours) / 24); + long milliToChange = getMilliToPeriodChange(); - _log.info("SevenSigns: Next period begins in " + numDays + " days, " + numHours + " hours and " + numMins + " mins."); - } - } - - public static SevenSigns getInstance() { - if (_instance == null) { - _instance = new SevenSigns(); - } - return _instance; - } - - public static int calcContributionScore(int blueCount, int greenCount, int redCount) - { - int contrib = blueCount * BLUE_CONTRIB_POINTS; - contrib += greenCount * GREEN_CONTRIB_POINTS; - contrib += redCount * RED_CONTRIB_POINTS; - - return contrib; - } - - public static int calcAncientAdenaReward(int blueCount, int greenCount, int redCount) - { - int reward = blueCount * SEAL_STONE_BLUE_VALUE; - reward += greenCount * SEAL_STONE_GREEN_VALUE; - reward += redCount * SEAL_STONE_RED_VALUE; - - return reward; - } - - public static final String getCabalShortName(int cabal) { - return (cabal == CABAL_DUSK) ? "dusk" : "dawn"; - } - - public static final String getCabalName(int cabal) { - return (cabal == CABAL_DUSK) ? "Revolutionaries of Dusk" : "Lords of Dawn"; - } - - public static final String getSealName(int seal, boolean shortName) - { - String sealName = (!shortName) ? "Seal of " : ""; - - switch (seal) { - case SEAL_AVARICE: - sealName += "Avarice"; - break; - case SEAL_GNOSIS: - sealName += "Gnosis"; - break; - case SEAL_STRIFE: - sealName += "Strife"; - break; - } - - return sealName; - } - - /** - * Used to capitalize the first letter of every "word" in a string.
    - * (Ported from the idea in Perl and PHP) - * - * @param String str - * @return String containing the modified string. - */ - public static String capitalizeWords(String str) - { - char[] charArray = str.toCharArray(); - String result = ""; - - // Capitalize the first letter in the given string! - charArray[0] = Character.toUpperCase(charArray[0]); - - for (int i = 0; i < charArray.length; i++) { - if (Character.isWhitespace(charArray[i])) - charArray[i + 1] = Character.toUpperCase(charArray[i + 1]); + // Schedule a time for the next period change. + SevenSignsPeriodChange sspc = new SevenSignsPeriodChange(); + SevenSignsUpdateSystem ssus = new SevenSignsUpdateSystem(); + ClientScheduler.getInstance().scheduleMed(sspc, milliToChange); + ClientScheduler.getInstance().scheduleMedAtFixedRate(ssus, 1000 * 60 * 60, 1000 * 60 * 60); - result += Character.toString(charArray[i]); - } - - return result; - } - - public final int getCurrentCycle() { - return _currentCycle; - } - - public final int getCurrentPeriod() { - return _activePeriod; - } - - private final int getDaysToPeriodChange() { - int numDays = _calendar.get(Calendar.DAY_OF_WEEK) - PERIOD_START_DAY; + // Thanks to http://rainbow.arch.scriptmania.com/scripts/timezone_countdown.html for help with this. + double numSecs = (milliToChange / 1000) % 60; + double countDown = ((milliToChange / 1000) - numSecs) / 60; + int numMins = (int) Math.floor(countDown % 60); + countDown = (countDown - numMins) / 60; + int numHours = (int) Math.floor(countDown % 24); + int numDays = (int) Math.floor((countDown - numHours) / 24); - if (numDays < 0) - return 0 - numDays; - + _log.info("SevenSigns: Next period begins in " + numDays + " days, " + numHours + + " hours and " + numMins + " mins."); + } + } + + public static SevenSigns getInstance() + { + if (_instance == null) + { + _instance = new SevenSigns(); + } + return _instance; + } + + public static int calcContributionScore(int blueCount, int greenCount, int redCount) + { + int contrib = blueCount * BLUE_CONTRIB_POINTS; + contrib += greenCount * GREEN_CONTRIB_POINTS; + contrib += redCount * RED_CONTRIB_POINTS; + + return contrib; + } + + public static int calcAncientAdenaReward(int blueCount, int greenCount, int redCount) + { + int reward = blueCount * SEAL_STONE_BLUE_VALUE; + reward += greenCount * SEAL_STONE_GREEN_VALUE; + reward += redCount * SEAL_STONE_RED_VALUE; + + return reward; + } + + public static final String getCabalShortName(int cabal) + { + return (cabal == CABAL_DUSK) ? "dusk" : "dawn"; + } + + public static final String getCabalName(int cabal) + { + return (cabal == CABAL_DUSK) ? "Revolutionaries of Dusk" : "Lords of Dawn"; + } + + public static final String getSealName(int seal, boolean shortName) + { + String sealName = (!shortName) ? "Seal of " : ""; + + switch (seal) + { + case SEAL_AVARICE: + sealName += "Avarice"; + break; + case SEAL_GNOSIS: + sealName += "Gnosis"; + break; + case SEAL_STRIFE: + sealName += "Strife"; + break; + } + + return sealName; + } + + /** + * Used to capitalize the first letter of every "word" in a string.
    + * (Ported from the idea in Perl and PHP) + * + * @param String str + * @return String containing the modified string. + */ + public static String capitalizeWords(String str) + { + char[] charArray = str.toCharArray(); + String result = ""; + + // Capitalize the first letter in the given string! + charArray[0] = Character.toUpperCase(charArray[0]); + + for (int i = 0; i < charArray.length; i++) + { + if (Character.isWhitespace(charArray[i])) + charArray[i + 1] = Character.toUpperCase(charArray[i + 1]); + + result += Character.toString(charArray[i]); + } + + return result; + } + + public final int getCurrentCycle() + { + return _currentCycle; + } + + public final int getCurrentPeriod() + { + return _activePeriod; + } + + private final int getDaysToPeriodChange() + { + int numDays = _calendar.get(Calendar.DAY_OF_WEEK) - PERIOD_START_DAY; + + if (numDays < 0) return 0 - numDays; + return 7 - numDays; - } - - public final long getMilliToPeriodChange() + } + + public final long getMilliToPeriodChange() { long currTimeMillis = System.currentTimeMillis(); long changeTimeMillis = _calendar.getTimeInMillis(); - - return (changeTimeMillis - currTimeMillis); + + return (changeTimeMillis - currTimeMillis); } - - private void setCalendarForNextPeriodChange() + + private void setCalendarForNextPeriodChange() { // Calculate the number of days until the next period // A period starts at 1:20 am (local time), like on official servers. @@ -464,17 +460,16 @@ case PERIOD_SEAL_VALIDATION: case PERIOD_COMPETITION: int daysToChange = getDaysToPeriodChange(); - - if (daysToChange == 7) + + if (daysToChange == 7) if (_calendar.get(Calendar.MINUTE) < PERIOD_START_MINS) if (_calendar.get(Calendar.HOUR_OF_DAY) <= PERIOD_START_HOUR) - // If next period is due to start today, don't add any days to the calendar. - daysToChange = 0; - + // If next period is due to start today, don't add any days to the calendar. + daysToChange = 0; + // Otherwise... - if (daysToChange > 0) - _calendar.add(Calendar.DATE, daysToChange); - + if (daysToChange > 0) _calendar.add(Calendar.DATE, daysToChange); + _calendar.set(Calendar.HOUR_OF_DAY, PERIOD_START_HOUR); _calendar.set(Calendar.MINUTE, PERIOD_START_MINS); break; @@ -484,146 +479,138 @@ break; } } - - public final String getCurrentPeriodName() { - String periodName = null; - - switch (_activePeriod) { - case PERIOD_COMP_RECRUITING: - periodName = "Quest Event Initialization"; - break; - case PERIOD_COMPETITION: - periodName = "Competition (Quest Event)"; - break; - case PERIOD_COMP_RESULTS: - periodName = "Quest Event Results"; - break; - case PERIOD_SEAL_VALIDATION: - periodName = "Seal Validation"; - break; - } - - return periodName; - } - - public final boolean isSealValidationPeriod() { - return (_activePeriod == PERIOD_SEAL_VALIDATION); - } - - public final int getCurrentScore(int cabal) { - if (cabal == CABAL_DUSK) - return _duskStoneScore + _duskFestivalScore; - else if (cabal == CABAL_DAWN) - return _dawnStoneScore + _dawnFestivalScore; - else - return 1; // to prevent any divide by zero errors - } - - public final int getCurrentStoneScore(int cabal) { - if (cabal == CABAL_DUSK) - return _duskStoneScore; - else if (cabal == CABAL_DAWN) - return _dawnStoneScore; - else - return 1; // to prevent any divide by zero errors - } - - public final int getCurrentFestivalScore(int cabal) { - if (cabal == CABAL_DUSK) - return _duskFestivalScore; - else if (cabal == CABAL_DAWN) - return _dawnFestivalScore; - else - return 1; // to prevent any divide by zero errors - } - - public final int getCabalHighestScore() { - if (getCurrentScore(CABAL_DUSK) > getCurrentScore(CABAL_DAWN)) - return CABAL_DUSK; - + + public final String getCurrentPeriodName() + { + String periodName = null; + + switch (_activePeriod) + { + case PERIOD_COMP_RECRUITING: + periodName = "Quest Event Initialization"; + break; + case PERIOD_COMPETITION: + periodName = "Competition (Quest Event)"; + break; + case PERIOD_COMP_RESULTS: + periodName = "Quest Event Results"; + break; + case PERIOD_SEAL_VALIDATION: + periodName = "Seal Validation"; + break; + } + + return periodName; + } + + public final boolean isSealValidationPeriod() + { + return (_activePeriod == PERIOD_SEAL_VALIDATION); + } + + public final int getCurrentScore(int cabal) + { + if (cabal == CABAL_DUSK) return _duskStoneScore + _duskFestivalScore; + else if (cabal == CABAL_DAWN) return _dawnStoneScore + _dawnFestivalScore; + else return 1; // to prevent any divide by zero errors + } + + public final int getCurrentStoneScore(int cabal) + { + if (cabal == CABAL_DUSK) return _duskStoneScore; + else if (cabal == CABAL_DAWN) return _dawnStoneScore; + else return 1; // to prevent any divide by zero errors + } + + public final int getCurrentFestivalScore(int cabal) + { + if (cabal == CABAL_DUSK) return _duskFestivalScore; + else if (cabal == CABAL_DAWN) return _dawnFestivalScore; + else return 1; // to prevent any divide by zero errors + } + + public final int getCabalHighestScore() + { + if (getCurrentScore(CABAL_DUSK) > getCurrentScore(CABAL_DAWN)) return CABAL_DUSK; + return CABAL_DAWN; - } - - public final int getSealOwner(int seal) { - return _signsSealOwners.get(seal); - } + } - public final int getSealProportion(int seal, int cabal) { - if (cabal == CABAL_NULL) - return -1; - else if (cabal == CABAL_DUSK) - return _signsDuskSealTotals.get(seal); - else - return _signsDawnSealTotals.get(seal); - } - - public int getTotalMembers(int cabal) - { - int cabalMembers = 0; - String cabalName = getCabalShortName(cabal); - - for (StatsSet sevenDat : _signsPlayerData.values()) - if (sevenDat.getString("cabal").equals(cabalName)) - cabalMembers++; - - return cabalMembers; - } - + public final int getSealOwner(int seal) + { + return _signsSealOwners.get(seal); + } + + public final int getSealProportion(int seal, int cabal) + { + if (cabal == CABAL_NULL) return -1; + else if (cabal == CABAL_DUSK) return _signsDuskSealTotals.get(seal); + else return _signsDawnSealTotals.get(seal); + } + + public int getTotalMembers(int cabal) + { + int cabalMembers = 0; + String cabalName = getCabalShortName(cabal); + + for (StatsSet sevenDat : _signsPlayerData.values()) + if (sevenDat.getString("cabal").equals(cabalName)) cabalMembers++; + + return cabalMembers; + } + public final StatsSet getPlayerStatsSet(L2PcInstance player) { - if (!hasRegisteredBefore(player)) - return null; - + if (!hasRegisteredBefore(player)) return null; + return _signsPlayerData.get(player.getObjectId()); } - - public int getPlayerStoneContrib(L2PcInstance player) { - if (!hasRegisteredBefore(player)) - return 0; - - int stoneCount = 0; - - StatsSet currPlayer = _signsPlayerData.get(player.getObjectId()); - - stoneCount += currPlayer.getInteger("red_stones"); - stoneCount += currPlayer.getInteger("green_stones"); - stoneCount += currPlayer.getInteger("blue_stones"); - - return stoneCount; - } - - public int getPlayerAdenaCollect(L2PcInstance player) { - if (!hasRegisteredBefore(player)) - return 0; - - return _signsPlayerData.get(player.getObjectId()).getInteger("ancient_adena_amount"); - } - - public int getPlayerSeal(L2PcInstance player) { - if (!hasRegisteredBefore(player)) - return SEAL_NULL; - - return _signsPlayerData.get(player.getObjectId()).getInteger("seal"); - } - public int getPlayerCabal(L2PcInstance player) { - if (!hasRegisteredBefore(player)) - return CABAL_NULL; - - String playerCabal = getPlayerCabalStr(player); + public int getPlayerStoneContrib(L2PcInstance player) + { + if (!hasRegisteredBefore(player)) return 0; - if (playerCabal.equals("")) - return CABAL_NULL; - else if (playerCabal.equals("dawn")) - return CABAL_DAWN; - else - return CABAL_DUSK; - } - - public String getPlayerCabalStr(L2PcInstance player) { - return _signsPlayerData.get(player.getObjectId()).getString("cabal"); - } - + int stoneCount = 0; + + StatsSet currPlayer = _signsPlayerData.get(player.getObjectId()); + + stoneCount += currPlayer.getInteger("red_stones"); + stoneCount += currPlayer.getInteger("green_stones"); + stoneCount += currPlayer.getInteger("blue_stones"); + + return stoneCount; + } + + public int getPlayerAdenaCollect(L2PcInstance player) + { + if (!hasRegisteredBefore(player)) return 0; + + return _signsPlayerData.get(player.getObjectId()).getInteger("ancient_adena_amount"); + } + + public int getPlayerSeal(L2PcInstance player) + { + if (!hasRegisteredBefore(player)) return SEAL_NULL; + + return _signsPlayerData.get(player.getObjectId()).getInteger("seal"); + } + + public int getPlayerCabal(L2PcInstance player) + { + if (!hasRegisteredBefore(player)) return CABAL_NULL; + + String playerCabal = getPlayerCabalStr(player); + + if (playerCabal.equals("")) return CABAL_NULL; + else if (playerCabal.equals("dawn")) return CABAL_DAWN; + else return CABAL_DUSK; + } + + public String getPlayerCabalStr(L2PcInstance player) + { + return _signsPlayerData.get(player.getObjectId()).getString("cabal"); + } + /** * Registers all random spawns and auto-chats for Seven Signs NPCs, * along with spawns for the Preachers of Doom and Orators of Revelations @@ -632,615 +619,713 @@ public void spawnSevenSignsNPCs() { L2NpcTemplate npcTemplate = null; - + // Register the random auto spawns of the Mammon NPCs _merchantSpawn = AutoSpawnHandler.getInstance().registerSpawn(8113, merchantSpawns, -1, -1, -1); _merchantSpawn.setRandomSpawn(true); - - _blacksmithSpawn = AutoSpawnHandler.getInstance().registerSpawn(8126, blacksmithSpawns, -1, -1, -1); + + _blacksmithSpawn = AutoSpawnHandler.getInstance().registerSpawn(8126, blacksmithSpawns, -1, -1, + -1); _blacksmithSpawn.setRandomSpawn(true); - - if (Config.ANNOUNCE_MAMMON_SPAWN) { + + if (Config.ANNOUNCE_MAMMON_SPAWN) + { _merchantSpawn.setBroadcast(true); _blacksmithSpawn.setBroadcast(true); } - + /* Set up the spawning and required auto chats. */ // First, do this for the Preachers of Doom - _preacherChat = AutoChatHandler.getInstance().registerGlobalChat(PREACHER_NPC_ID, SevenSigns.chatDoomPreacher, -1); + _preacherChat = AutoChatHandler.getInstance().registerGlobalChat(PREACHER_NPC_ID, + SevenSigns.chatDoomPreacher, -1); _preacherChat.setDefaultRandom(true); - - _oratorChat = AutoChatHandler.getInstance().registerGlobalChat(ORATOR_NPC_ID, SevenSigns.chatOratorRevelations, -1); + + _oratorChat = AutoChatHandler.getInstance().registerGlobalChat(ORATOR_NPC_ID, + SevenSigns.chatOratorRevelations, + -1); _oratorChat.setDefaultRandom(true); - + /* * If the spawns have been initialized before don't try to do it again. * Otherwise, create the spawns for the required monsters and minions. */ - if (_initializedSpawns) - return; - - try { + if (_initializedSpawns) return; + + try + { // First, do this for the Preachers of Doom \\ npcTemplate = NpcTable.getInstance().getTemplate(PREACHER_NPC_ID); - - for (int i = 0; i < preacherSpawns.length; i++) - { + + for (int i = 0; i < preacherSpawns.length; i++) + { L2Spawn npcSpawn = new L2Spawn(npcTemplate); - + npcSpawn.setLocx(preacherSpawns[i][0]); npcSpawn.setLocy(preacherSpawns[i][1]); npcSpawn.setLocz(preacherSpawns[i][2]); npcSpawn.setAmount(1); SpawnTable.getInstance().addNewSpawn(npcSpawn, false); _signsNPCInsts.add(npcSpawn.doSpawn()); - + if (Config.DEBUG) - _log.info("SevenSigns: Spawned a Preacher at " - + preacherSpawns[i][0] + " " + preacherSpawns[i][1] + " " + preacherSpawns[i][2]); + _log.info("SevenSigns: Spawned a Preacher at " + preacherSpawns[i][0] + " " + + preacherSpawns[i][1] + " " + preacherSpawns[i][2]); } - + // Now do the same again for the Orators of Revelations \\ npcTemplate = NpcTable.getInstance().getTemplate(ORATOR_NPC_ID); - - for (int i = 0; i < oratorSpawns.length; i++) - { + + for (int i = 0; i < oratorSpawns.length; i++) + { L2Spawn npcSpawn = new L2Spawn(npcTemplate); - + npcSpawn.setLocx(oratorSpawns[i][0]); npcSpawn.setLocy(oratorSpawns[i][1]); npcSpawn.setLocz(oratorSpawns[i][2]); npcSpawn.setAmount(1); SpawnTable.getInstance().addNewSpawn(npcSpawn, false); _signsNPCInsts.add(npcSpawn.doSpawn()); - + if (Config.DEBUG) - _log.info("SevenSigns: Spawned an Orator at " - + oratorSpawns[i][0] + " " + oratorSpawns[i][1] + " " + oratorSpawns[i][2]); + _log.info("SevenSigns: Spawned an Orator at " + oratorSpawns[i][0] + " " + + oratorSpawns[i][1] + " " + oratorSpawns[i][2]); } - + /* Similarly, spawn either of the two major boss monsters and their minions. * * If Dawn wins, spawn Lilith with 2 Lilith's Agent and 2 Lilith's Escort. * If Dusk wins, spawn Anakim with 2 Anakim's Guardian and 2 Anakim's Royal Guard. * - */ + */ final String bossName; L2MinionData minionDat; - - if (getCabalHighestScore() == CABAL_DAWN) { + + if (getCabalHighestScore() == CABAL_DAWN) + { bossName = "Lilith"; npcTemplate = NpcTable.getInstance().getTemplate(LILITH_NPC_ID); - - minionDat = new L2MinionData(); + + minionDat = new L2MinionData(); minionDat.setMinionId(10284); minionDat.setAmount(2); npcTemplate.addRaidData(minionDat); - - minionDat = new L2MinionData(); + + minionDat = new L2MinionData(); minionDat.setMinionId(10285); minionDat.setAmount(2); npcTemplate.addRaidData(minionDat); } - else { + else + { bossName = "Anakim"; npcTemplate = NpcTable.getInstance().getTemplate(ANAKIM_NPC_ID); - - minionDat = new L2MinionData(); + + minionDat = new L2MinionData(); minionDat.setMinionId(10287); minionDat.setAmount(2); - npcTemplate.addRaidData(minionDat); - - minionDat = new L2MinionData(); + npcTemplate.addRaidData(minionDat); + + minionDat = new L2MinionData(); minionDat.setMinionId(10288); minionDat.setAmount(2); - npcTemplate.addRaidData(minionDat); + npcTemplate.addRaidData(minionDat); } - + L2Spawn npcSpawn = new L2Spawn(npcTemplate); npcSpawn.setLocx(-42900); npcSpawn.setLocy(211044); npcSpawn.setLocz(-5088); npcSpawn.setRespawnDelay(86400); // Respawns every 24 hours. npcSpawn.setAmount(1); - + SpawnTable.getInstance().addNewSpawn(npcSpawn, false); _signsNPCInsts.add(npcSpawn.doSpawn()); - - if (Config.DEBUG) - _log.info("SevenSigns: Spawned " + bossName + " with her minions."); + + if (Config.DEBUG) _log.info("SevenSigns: Spawned " + bossName + " with her minions."); } - catch (Exception e) { + catch (Exception e) + { _log.warning("SevenSigns: Error while spawning period NPCs: " + e); } - + _initializedSpawns = true; - } - - /** - * Used to remove random spawns and auto-chats at the beginning of a new Quest Event period. + } + + /** + * Used to remove random spawns and auto-chats at the beginning of a new Quest Event period. *
    * Also hides all Preachers of Doom and Orators of Revelations. - */ - protected void removeSevenSignsNPCs() - { - // Remove the random auto spawns of Mammon NPCs - AutoSpawnHandler.getInstance().removeSpawn(_merchantSpawn); - AutoSpawnHandler.getInstance().removeSpawn(_blacksmithSpawn); - - // Remove the auto chats of Seven Signs NPCs and hide them - AutoChatHandler.getInstance().removeChat(_preacherChat); - AutoChatHandler.getInstance().removeChat(_oratorChat); + */ + protected void removeSevenSignsNPCs() + { + // Remove the random auto spawns of Mammon NPCs + AutoSpawnHandler.getInstance().removeSpawn(_merchantSpawn); + AutoSpawnHandler.getInstance().removeSpawn(_blacksmithSpawn); + // Remove the auto chats of Seven Signs NPCs and hide them + AutoChatHandler.getInstance().removeChat(_preacherChat); + AutoChatHandler.getInstance().removeChat(_oratorChat); + // Remove all spawned NPCs and clean up the boss' minions. - for (L2NpcInstance npcInst : _signsNPCInsts) + for (L2NpcInstance npcInst : _signsNPCInsts) { - if (npcInst.getNpcId() == LILITH_NPC_ID || npcInst.getNpcId() == ANAKIM_NPC_ID) + if (npcInst.getNpcId() == LILITH_NPC_ID || npcInst.getNpcId() == ANAKIM_NPC_ID) { - L2MonsterInstance monsterInst = (L2MonsterInstance)npcInst; - + L2MonsterInstance monsterInst = (L2MonsterInstance) npcInst; + for (L2MinionInstance minion : monsterInst.getSpawnedMinions()) minion.deleteMe(); } - - npcInst.deleteMe(); + + npcInst.deleteMe(); } - } - + } + /** * Restores all Seven Signs data and settings, usually called at server startup. * * @throws Exception */ protected void restoreSevenSignsData() throws Exception - { - java.sql.Connection con = L2DatabaseFactory.getInstance().getConnection(); - - PreparedStatement statement = con.prepareStatement("SELECT char_obj_id, cabal, seal, red_stones, green_stones, blue_stones, " + - "ancient_adena_amount, contribution_score FROM seven_signs"); - ResultSet rset = statement.executeQuery(); - - while (rset.next()) - { - int charObjId = rset.getInt("char_obj_id"); - - StatsSet sevenDat = new StatsSet(); - sevenDat.set("char_obj_id", charObjId); - sevenDat.set("cabal", rset.getString("cabal")); - sevenDat.set("seal", rset.getInt("seal")); - sevenDat.set("red_stones", rset.getInt("red_stones")); - sevenDat.set("green_stones", rset.getInt("green_stones")); - sevenDat.set("blue_stones", rset.getInt("blue_stones")); - sevenDat.set("ancient_adena_amount", rset.getInt("ancient_adena_amount")); - sevenDat.set("contribution_score", rset.getInt("contribution_score")); + { + java.sql.Connection con = L2DatabaseFactory.getInstance().getConnection(); - if (Config.DEBUG) - _log.info("SevenSigns: Loaded data from DB for char ID " + charObjId + " (" + sevenDat.getString("cabal") + ")"); - - _signsPlayerData.put(charObjId, sevenDat); - } - - rset.close(); - statement.close(); - con.close(); - - Properties SevenSignsProp = new Properties(); - InputStream is = SevenSigns.class.getResourceAsStream("/" + SEVEN_SIGNS_DATA_FILE); - SevenSignsProp.load(is); - is.close(); + PreparedStatement statement = con.prepareStatement("SELECT char_obj_id, cabal, seal, red_stones, green_stones, blue_stones, " + + "ancient_adena_amount, contribution_score FROM seven_signs"); + ResultSet rset = statement.executeQuery(); - _currentCycle = Integer.parseInt(SevenSignsProp.getProperty("CurrentCycle", "1")); - _activePeriod = Integer.parseInt(SevenSignsProp.getProperty("Period", String.valueOf(PERIOD_COMPETITION))); - _previousWinner = Integer.parseInt(SevenSignsProp.getProperty("PreviousWinner", String.valueOf(CABAL_NULL))); - - _dawnStoneScore = Integer.parseInt(SevenSignsProp.getProperty("DawnStoneScore", "0")); - _dawnFestivalScore = Integer.parseInt(SevenSignsProp.getProperty("DawnFestivalScore", "0")); - _duskStoneScore = Integer.parseInt(SevenSignsProp.getProperty("DuskStoneScore", "0")); - _duskFestivalScore = Integer.parseInt(SevenSignsProp.getProperty("DuskFestivalScore", "0")); - - _signsSealOwners.put(SEAL_AVARICE, Integer.parseInt(SevenSignsProp.getProperty("AvariceOwner", String.valueOf(CABAL_NULL)))); - _signsSealOwners.put(SEAL_GNOSIS, Integer.parseInt(SevenSignsProp.getProperty("GnosisOwner", String.valueOf(CABAL_NULL)))); - _signsSealOwners.put(SEAL_STRIFE, Integer.parseInt(SevenSignsProp.getProperty("StrifeOwner", String.valueOf(CABAL_NULL)))); - - _signsDawnSealTotals.put(SEAL_AVARICE, Integer.parseInt(SevenSignsProp.getProperty("AvariceDawnScore", "0"))); - _signsDawnSealTotals.put(SEAL_GNOSIS, Integer.parseInt(SevenSignsProp.getProperty("GnosisDawnScore", "0"))); - _signsDawnSealTotals.put(SEAL_STRIFE, Integer.parseInt(SevenSignsProp.getProperty("StrifeDawnScore", "0"))); - _signsDuskSealTotals.put(SEAL_AVARICE, Integer.parseInt(SevenSignsProp.getProperty("AvariceDuskScore", "0"))); - _signsDuskSealTotals.put(SEAL_GNOSIS, Integer.parseInt(SevenSignsProp.getProperty("GnosisDuskScore", "0"))); - _signsDuskSealTotals.put(SEAL_STRIFE, Integer.parseInt(SevenSignsProp.getProperty("StrifeDuskScore", "0"))); - - // Festival data is loaded now after the Seven Signs engine data. - } - - /** + while (rset.next()) + { + int charObjId = rset.getInt("char_obj_id"); + + StatsSet sevenDat = new StatsSet(); + sevenDat.set("char_obj_id", charObjId); + sevenDat.set("cabal", rset.getString("cabal")); + sevenDat.set("seal", rset.getInt("seal")); + sevenDat.set("red_stones", rset.getInt("red_stones")); + sevenDat.set("green_stones", rset.getInt("green_stones")); + sevenDat.set("blue_stones", rset.getInt("blue_stones")); + sevenDat.set("ancient_adena_amount", rset.getInt("ancient_adena_amount")); + sevenDat.set("contribution_score", rset.getInt("contribution_score")); + + if (Config.DEBUG) + _log.info("SevenSigns: Loaded data from DB for char ID " + charObjId + " (" + + sevenDat.getString("cabal") + ")"); + + _signsPlayerData.put(charObjId, sevenDat); + } + + rset.close(); + statement.close(); + con.close(); + + Connection con2 = L2DatabaseFactory.getInstance().getConnection(); + PreparedStatement statement2 = con2.prepareStatement("SELECT * FROM seven_signs_status WHERE id=1"); + ResultSet rset2 = statement2.executeQuery(); + + while (rset2.next()) + { + _currentCycle = rset2.getInt("current_cycle"); + _activePeriod = rset2.getInt("active_period"); + _previousWinner = rset2.getInt("previous_winner"); + + _dawnStoneScore = rset2.getInt("dawn_stone_score"); + _dawnFestivalScore = rset2.getInt("dawn_festival_score"); + _duskStoneScore = rset2.getInt("dusk_stone_score"); + _duskFestivalScore = rset2.getInt("dusk_festival_score"); + + _signsSealOwners.put(SEAL_AVARICE, rset2.getInt("avarice_owner")); + _signsSealOwners.put(SEAL_GNOSIS, rset2.getInt("gnosis_owner")); + _signsSealOwners.put(SEAL_STRIFE, rset2.getInt("strife_owner")); + + _signsDawnSealTotals.put(SEAL_AVARICE, rset2.getInt("avarice_dawn_score")); + _signsDawnSealTotals.put(SEAL_GNOSIS, rset2.getInt("gnosis_dawn_score")); + _signsDawnSealTotals.put(SEAL_STRIFE, rset2.getInt("strife_dawn_score")); + _signsDuskSealTotals.put(SEAL_AVARICE, rset2.getInt("avarice_dusk_score")); + _signsDuskSealTotals.put(SEAL_GNOSIS, rset2.getInt("gnosis_dusk_score")); + _signsDuskSealTotals.put(SEAL_STRIFE, rset2.getInt("strife_dusk_score")); + } + + rset2.close(); + statement2.close(); + con2.close(); + + Connection con3 = L2DatabaseFactory.getInstance().getConnection(); + PreparedStatement statement3 = con3.prepareStatement("UPDATE seven_signs_status SET date=? WHERE id=1"); + statement3.setInt(1, Calendar.getInstance().get(Calendar.DAY_OF_WEEK)); + statement3.execute(); + statement3.close(); + con3.close(); + + /*Properties SevenSignsProp = new Properties(); + InputStream is = SevenSigns.class.getResourceAsStream("/" + SEVEN_SIGNS_DATA_FILE); + SevenSignsProp.load(is); + is.close(); + + _currentCycle = Integer.parseInt(SevenSignsProp.getProperty("CurrentCycle", "1")); + _activePeriod = Integer.parseInt(SevenSignsProp.getProperty("Period", String.valueOf(PERIOD_COMPETITION))); + _previousWinner = Integer.parseInt(SevenSignsProp.getProperty("PreviousWinner", String.valueOf(CABAL_NULL))); + + _dawnStoneScore = Integer.parseInt(SevenSignsProp.getProperty("DawnStoneScore", "0")); + _dawnFestivalScore = Integer.parseInt(SevenSignsProp.getProperty("DawnFestivalScore", "0")); + _duskStoneScore = Integer.parseInt(SevenSignsProp.getProperty("DuskStoneScore", "0")); + _duskFestivalScore = Integer.parseInt(SevenSignsProp.getProperty("DuskFestivalScore", "0")); + + _signsSealOwners.put(SEAL_AVARICE, Integer.parseInt(SevenSignsProp.getProperty("AvariceOwner", String.valueOf(CABAL_NULL)))); + _signsSealOwners.put(SEAL_GNOSIS, Integer.parseInt(SevenSignsProp.getProperty("GnosisOwner", String.valueOf(CABAL_NULL)))); + _signsSealOwners.put(SEAL_STRIFE, Integer.parseInt(SevenSignsProp.getProperty("StrifeOwner", String.valueOf(CABAL_NULL)))); + + _signsDawnSealTotals.put(SEAL_AVARICE, Integer.parseInt(SevenSignsProp.getProperty("AvariceDawnScore", "0"))); + _signsDawnSealTotals.put(SEAL_GNOSIS, Integer.parseInt(SevenSignsProp.getProperty("GnosisDawnScore", "0"))); + _signsDawnSealTotals.put(SEAL_STRIFE, Integer.parseInt(SevenSignsProp.getProperty("StrifeDawnScore", "0"))); + _signsDuskSealTotals.put(SEAL_AVARICE, Integer.parseInt(SevenSignsProp.getProperty("AvariceDuskScore", "0"))); + _signsDuskSealTotals.put(SEAL_GNOSIS, Integer.parseInt(SevenSignsProp.getProperty("GnosisDuskScore", "0"))); + _signsDuskSealTotals.put(SEAL_STRIFE, Integer.parseInt(SevenSignsProp.getProperty("StrifeDuskScore", "0")));*/ + + // Festival data is loaded now after the Seven Signs engine data. + } + + /** * Saves all Seven Signs data, both to the database and properties file (if updateSettings = True). * Often called to preserve data integrity and synchronization with DB, in case of errors. *
    * If player != null, just that player's data is updated in the database, otherwise all player's data is * sequentially updated. * - * @param player - * @param updateSettings - * @throws Exception - */ - public synchronized void saveSevenSignsData(L2PcInstance player, boolean updateSettings) throws Exception - { - if (Config.DEBUG) - System.out.println("SevenSigns: Saving data to disk."); - - java.sql.Connection con = L2DatabaseFactory.getInstance().getConnection(); - - for (StatsSet sevenDat : _signsPlayerData.values()) - { - if (player != null) - if (sevenDat.getInteger("char_obj_id") != player.getObjectId()) - continue; - - PreparedStatement statement = con.prepareStatement( - "UPDATE seven_signs SET cabal=?, seal=?, red_stones=?, " + - "green_stones=?, blue_stones=?, ancient_adena_amount=?, contribution_score=? WHERE char_obj_id=?"); - statement.setString(1, sevenDat.getString("cabal")); - statement.setInt(2, sevenDat.getInteger("seal")); - statement.setInt(3, sevenDat.getInteger("red_stones")); - statement.setInt(4, sevenDat.getInteger("green_stones")); - statement.setInt(5, sevenDat.getInteger("blue_stones")); - statement.setInt(6, sevenDat.getInteger("ancient_adena_amount")); - statement.setInt(7, sevenDat.getInteger("contribution_score")); - statement.setInt(8, sevenDat.getInteger("char_obj_id")); - statement.execute(); - statement.close(); - - if (Config.DEBUG) - _log.info("SevenSigns: Updated data in DB for char ID " + sevenDat.getInteger("char_obj_id") + " (" + sevenDat.getString("cabal") + ")"); - } - - con.close(); - - if (updateSettings) { - Properties SevenSignsProp = new Properties(); - FileOutputStream fos = new FileOutputStream(new File(Config.DATAPACK_ROOT, SEVEN_SIGNS_DATA_FILE)); - - SevenSignsProp.setProperty("CurrentCycle", String.valueOf(_currentCycle)); - SevenSignsProp.setProperty("Period", String.valueOf(_activePeriod)); - SevenSignsProp.setProperty("PreviousWinner", String.valueOf(_previousWinner)); - - SevenSignsProp.setProperty("DawnStoneScore", String.valueOf(_dawnStoneScore)); - SevenSignsProp.setProperty("DuskStoneScore", String.valueOf(_duskStoneScore)); - SevenSignsProp.setProperty("DawnFestivalScore", String.valueOf(_dawnFestivalScore)); - SevenSignsProp.setProperty("DuskFestivalScore", String.valueOf(_duskFestivalScore)); - - SevenSignsProp.setProperty("AvariceOwner", String.valueOf(_signsSealOwners.get(SEAL_AVARICE))); - SevenSignsProp.setProperty("GnosisOwner", String.valueOf(_signsSealOwners.get(SEAL_GNOSIS))); - SevenSignsProp.setProperty("StrifeOwner", String.valueOf(_signsSealOwners.get(SEAL_STRIFE))); - - SevenSignsProp.setProperty("AvariceDawnScore", String.valueOf(_signsDawnSealTotals.get(SEAL_AVARICE))); - SevenSignsProp.setProperty("GnosisDawnScore", String.valueOf(_signsDawnSealTotals.get(SEAL_GNOSIS))); - SevenSignsProp.setProperty("StrifeDawnScore", String.valueOf(_signsDawnSealTotals.get(SEAL_STRIFE))); - SevenSignsProp.setProperty("AvariceDuskScore", String.valueOf(_signsDuskSealTotals.get(SEAL_AVARICE))); - SevenSignsProp.setProperty("GnosisDuskScore", String.valueOf(_signsDuskSealTotals.get(SEAL_GNOSIS))); - SevenSignsProp.setProperty("StrifeDuskScore", String.valueOf(_signsDuskSealTotals.get(SEAL_STRIFE))); - - // Festival data is now saved along with the rest of the Seven Signs settings. - SevenSignsProp.setProperty("FestivalCycle", String.valueOf(SevenSignsFestival.getInstance().getCurrentFestivalCycle())); - - for (int i = 0; i < SevenSignsFestival.FESTIVAL_COUNT; i++) - SevenSignsProp.setProperty("AccumulatedBonus_" + i, String.valueOf(SevenSignsFestival.getInstance().getAccumulatedBonus(i))); - - SevenSignsProp.store(fos, "Seven Signs Properties"); - fos.close(); - + * @param player + * @param updateSettings + * @throws Exception + */ + public synchronized void saveSevenSignsData(L2PcInstance player, boolean updateSettings) + throws Exception + { + if (Config.DEBUG) System.out.println("SevenSigns: Saving data to disk."); + + java.sql.Connection con = L2DatabaseFactory.getInstance().getConnection(); + + for (StatsSet sevenDat : _signsPlayerData.values()) + { + if (player != null) + if (sevenDat.getInteger("char_obj_id") != player.getObjectId()) continue; + + PreparedStatement statement = con.prepareStatement("UPDATE seven_signs SET cabal=?, seal=?, red_stones=?, " + + "green_stones=?, blue_stones=?, ancient_adena_amount=?, contribution_score=? WHERE char_obj_id=?"); + statement.setString(1, sevenDat.getString("cabal")); + statement.setInt(2, sevenDat.getInteger("seal")); + statement.setInt(3, sevenDat.getInteger("red_stones")); + statement.setInt(4, sevenDat.getInteger("green_stones")); + statement.setInt(5, sevenDat.getInteger("blue_stones")); + statement.setInt(6, sevenDat.getInteger("ancient_adena_amount")); + statement.setInt(7, sevenDat.getInteger("contribution_score")); + statement.setInt(8, sevenDat.getInteger("char_obj_id")); + statement.execute(); + statement.close(); + if (Config.DEBUG) - _log.info("SevenSigns: Updated data in signs.properties file."); - } - } - + _log.info("SevenSigns: Updated data in DB for char ID " + + sevenDat.getInteger("char_obj_id") + " (" + sevenDat.getString("cabal") + ")"); + } + + con.close(); + + Connection con2 = L2DatabaseFactory.getInstance().getConnection(); + + if (updateSettings) + { + + String query = "UPDATE seven_signs_status SET current_cycle=?, active_period=?, previous_winner=?, " + + "dawn_stone_score=?, dawn_festival_score=?, dusk_stone_score=?, dusk_festival_score=?, " + + "avarice_owner=?, gnosis_owner=?, strife_owner=?, avarice_dawn_score=?, gnosis_dawn_score=?, " + + "strife_dawn_score=?, avarice_dusk_score=?, gnosis_dusk_score=?, strife_dusk_score=?, " + + "festival_cycle=?, "; + for (int i = 0; i < (SevenSignsFestival.FESTIVAL_COUNT); i++) + query += "accumulated_bonus" + String.valueOf(i) + "=?, "; + query += "date=? WHERE id=1"; + + PreparedStatement statement2 = con2.prepareStatement(query); + + statement2.setInt(1, _currentCycle); + statement2.setInt(2, _activePeriod); + statement2.setInt(3, _previousWinner); + statement2.setInt(4, _dawnStoneScore); + statement2.setInt(5, _dawnFestivalScore); + statement2.setInt(6, _duskStoneScore); + statement2.setInt(7, _duskFestivalScore); + statement2.setInt(8, _signsSealOwners.get(SEAL_AVARICE)); + statement2.setInt(9, _signsSealOwners.get(SEAL_GNOSIS)); + statement2.setInt(10, _signsSealOwners.get(SEAL_STRIFE)); + statement2.setInt(11, _signsDawnSealTotals.get(SEAL_AVARICE)); + statement2.setInt(12, _signsDawnSealTotals.get(SEAL_GNOSIS)); + statement2.setInt(13, _signsDawnSealTotals.get(SEAL_STRIFE)); + statement2.setInt(14, _signsDuskSealTotals.get(SEAL_AVARICE)); + statement2.setInt(15, _signsDuskSealTotals.get(SEAL_GNOSIS)); + statement2.setInt(16, _signsDuskSealTotals.get(SEAL_STRIFE)); + + statement2.setInt(17, SevenSignsFestival.getInstance().getCurrentFestivalCycle()); + for (int i = 0; i < SevenSignsFestival.FESTIVAL_COUNT; i++) + statement2.setInt(18 + i, SevenSignsFestival.getInstance().getAccumulatedBonus(i)); + statement2.setInt(18 + SevenSignsFestival.FESTIVAL_COUNT, + Calendar.getInstance().get(Calendar.DAY_OF_WEEK)); + + statement2.execute(); + statement2.close(); + + if (Config.DEBUG) _log.info("SevenSigns: Updated data in SQL database."); + + } + con2.close(); + /*if (updateSettings) { + Properties SevenSignsProp = new Properties(); + FileOutputStream fos = new FileOutputStream(new File(Config.DATAPACK_ROOT, SEVEN_SIGNS_DATA_FILE)); + + SevenSignsProp.setProperty("CurrentCycle", String.valueOf(_currentCycle)); + SevenSignsProp.setProperty("Period", String.valueOf(_activePeriod)); + SevenSignsProp.setProperty("PreviousWinner", String.valueOf(_previousWinner)); + + SevenSignsProp.setProperty("DawnStoneScore", String.valueOf(_dawnStoneScore)); + SevenSignsProp.setProperty("DuskStoneScore", String.valueOf(_duskStoneScore)); + SevenSignsProp.setProperty("DawnFestivalScore", String.valueOf(_dawnFestivalScore)); + SevenSignsProp.setProperty("DuskFestivalScore", String.valueOf(_duskFestivalScore)); + + SevenSignsProp.setProperty("AvariceOwner", String.valueOf(_signsSealOwners.get(SEAL_AVARICE))); + SevenSignsProp.setProperty("GnosisOwner", String.valueOf(_signsSealOwners.get(SEAL_GNOSIS))); + SevenSignsProp.setProperty("StrifeOwner", String.valueOf(_signsSealOwners.get(SEAL_STRIFE))); + + SevenSignsProp.setProperty("AvariceDawnScore", String.valueOf(_signsDawnSealTotals.get(SEAL_AVARICE))); + SevenSignsProp.setProperty("GnosisDawnScore", String.valueOf(_signsDawnSealTotals.get(SEAL_GNOSIS))); + SevenSignsProp.setProperty("StrifeDawnScore", String.valueOf(_signsDawnSealTotals.get(SEAL_STRIFE))); + SevenSignsProp.setProperty("AvariceDuskScore", String.valueOf(_signsDuskSealTotals.get(SEAL_AVARICE))); + SevenSignsProp.setProperty("GnosisDuskScore", String.valueOf(_signsDuskSealTotals.get(SEAL_GNOSIS))); + SevenSignsProp.setProperty("StrifeDuskScore", String.valueOf(_signsDuskSealTotals.get(SEAL_STRIFE))); + + // Festival data is now saved along with the rest of the Seven Signs settings. + SevenSignsProp.setProperty("FestivalCycle", String.valueOf(SevenSignsFestival.getInstance().getCurrentFestivalCycle())); + + for (int i = 0; i < SevenSignsFestival.FESTIVAL_COUNT; i++) + SevenSignsProp.setProperty("AccumulatedBonus_" + i, String.valueOf(SevenSignsFestival.getInstance().getAccumulatedBonus(i))); + + SevenSignsProp.store(fos, "Seven Signs Properties"); + fos.close(); + + if (Config.DEBUG) + _log.info("SevenSigns: Updated data in signs.properties file."); + } */ + } + /** * Used to reset the cabal details of all players, and update the database.
    * Primarily used when beginning a new cycle, and should otherwise never be called. */ protected void resetPlayerData() - { - String compWinner = "dawn"; - - if (getCabalHighestScore() == CABAL_DUSK) - compWinner = "dusk"; - - if (Config.DEBUG) - _log.info("SevenSigns: Resetting player data for new event period."); - - for (StatsSet sevenDat : _signsPlayerData.values()) - { - int charObjId = sevenDat.getInteger("char_obj_id"); - - // Reset seal stones for the winning cabal - if (sevenDat.getString("cabal").equals(compWinner)) - { - sevenDat.set("red_stones", 0); - sevenDat.set("green_stones", 0); - sevenDat.set("blue_stones", 0); - sevenDat.set("contribution_score", 0); - } - - // Reset the player's cabal and seal information - sevenDat.set("cabal", ""); - sevenDat.set("seal", SEAL_NULL); - _signsPlayerData.put(charObjId, sevenDat); - } - + { + String compWinner = "dawn"; + + if (getCabalHighestScore() == CABAL_DUSK) compWinner = "dusk"; + + if (Config.DEBUG) _log.info("SevenSigns: Resetting player data for new event period."); + + for (StatsSet sevenDat : _signsPlayerData.values()) + { + int charObjId = sevenDat.getInteger("char_obj_id"); + + // Reset seal stones for the winning cabal + if (sevenDat.getString("cabal").equals(compWinner)) + { + sevenDat.set("red_stones", 0); + sevenDat.set("green_stones", 0); + sevenDat.set("blue_stones", 0); + sevenDat.set("contribution_score", 0); + } + + // Reset the player's cabal and seal information + sevenDat.set("cabal", ""); + sevenDat.set("seal", SEAL_NULL); + _signsPlayerData.put(charObjId, sevenDat); + } + // A database update should soon follow this! - } - - /** + } + + /** * Tests whether the specified player has joined a cabal in the past. * - * @param player - * @return boolean hasRegistered - */ - private boolean hasRegisteredBefore(L2PcInstance player) { - return _signsPlayerData.containsKey(player.getObjectId()); - } - - - /** + * @param player + * @return boolean hasRegistered + */ + private boolean hasRegisteredBefore(L2PcInstance player) + { + return _signsPlayerData.containsKey(player.getObjectId()); + } + + /** * Used to specify cabal-related details for the specified player. This method * checks to see if the player has registered before and will update the database * if necessary. *
    * Returns the cabal ID the player has joined. * - * @param player - * @param chosenCabal - * @param chosenSeal - * @return int cabal - */ - public int setPlayerInfo(L2PcInstance player, int chosenCabal, int chosenSeal) - { - final int charObjId = player.getObjectId(); - - if (hasRegisteredBefore(player)) { - final int oldCabal = getPlayerCabal(player); - - if (oldCabal == chosenCabal) - return oldCabal; + * @param player + * @param chosenCabal + * @param chosenSeal + * @return int cabal + */ + public int setPlayerInfo(L2PcInstance player, int chosenCabal, int chosenSeal) + { + final int charObjId = player.getObjectId(); - // If the seal validation period has passed, - // cabal information was removed and so "re-register" player - StatsSet currPlayer = _signsPlayerData.get(charObjId); - currPlayer.set("cabal", getCabalShortName(chosenCabal)); - currPlayer.set("seal", chosenSeal); - - _signsPlayerData.put(charObjId, currPlayer); - - try { + if (hasRegisteredBefore(player)) + { + final int oldCabal = getPlayerCabal(player); + + if (oldCabal == chosenCabal) return oldCabal; + + // If the seal validation period has passed, + // cabal information was removed and so "re-register" player + StatsSet currPlayer = _signsPlayerData.get(charObjId); + currPlayer.set("cabal", getCabalShortName(chosenCabal)); + currPlayer.set("seal", chosenSeal); + + _signsPlayerData.put(charObjId, currPlayer); + + try + { saveSevenSignsData(player, false); } - catch (Exception e) { + catch (Exception e) + { _log.severe("SevenSigns: Failed to save configuration: " + e); } - } - else { - StatsSet sevenDat = new StatsSet(); - sevenDat.set("char_obj_id", charObjId); - sevenDat.set("cabal", getCabalShortName(chosenCabal)); - sevenDat.set("seal", chosenSeal); - sevenDat.set("red_stones", 0); - sevenDat.set("green_stones", 0); - sevenDat.set("blue_stones", 0); - sevenDat.set("ancient_adena_amount", 0); - sevenDat.set("contribution_score", 0); + } + else + { + StatsSet sevenDat = new StatsSet(); + sevenDat.set("char_obj_id", charObjId); + sevenDat.set("cabal", getCabalShortName(chosenCabal)); + sevenDat.set("seal", chosenSeal); + sevenDat.set("red_stones", 0); + sevenDat.set("green_stones", 0); + sevenDat.set("blue_stones", 0); + sevenDat.set("ancient_adena_amount", 0); + sevenDat.set("contribution_score", 0); - _signsPlayerData.put(charObjId, sevenDat); - - // Update data in database, as we have a new player signing up. - java.sql.Connection con = null; - - try { - con = L2DatabaseFactory.getInstance().getConnection(); - - PreparedStatement statement = con.prepareStatement( - "INSERT INTO seven_signs (char_obj_id, cabal, seal, red_stones, green_stones, blue_stones, " + - "ancient_adena_amount, contribution_score) VALUES (?,?,?,0,0,0,0,0)"); - statement.setInt(1, charObjId); - statement.setString(2, getCabalShortName(chosenCabal)); - statement.setInt(3, chosenSeal); - statement.execute(); - statement.close(); - - con.close(); - } - catch (Exception e) { - _log.severe("SevenSigns: Failed to save data: " + e); - } - - if (Config.DEBUG) - _log.info("SevenSigns: Inserted data in DB for char ID " + sevenDat.getInteger("char_obj_id") + " (" + sevenDat.getString("cabal") + ")"); - } - - if (Config.DEBUG) - _log.info("SevenSigns: " + player.getName() + " has joined the " + getCabalName(chosenCabal) + " for the " + getSealName(chosenSeal, false) + "!"); - - return chosenCabal; - } - - /** + _signsPlayerData.put(charObjId, sevenDat); + + // Update data in database, as we have a new player signing up. + java.sql.Connection con = null; + + try + { + con = L2DatabaseFactory.getInstance().getConnection(); + + PreparedStatement statement = con.prepareStatement("INSERT INTO seven_signs (char_obj_id, cabal, seal, red_stones, green_stones, blue_stones, " + + "ancient_adena_amount, contribution_score) VALUES (?,?,?,0,0,0,0,0)"); + statement.setInt(1, charObjId); + statement.setString(2, getCabalShortName(chosenCabal)); + statement.setInt(3, chosenSeal); + statement.execute(); + statement.close(); + + con.close(); + } + catch (Exception e) + { + _log.severe("SevenSigns: Failed to save data: " + e); + } + + if (Config.DEBUG) + _log.info("SevenSigns: Inserted data in DB for char ID " + + sevenDat.getInteger("char_obj_id") + " (" + sevenDat.getString("cabal") + ")"); + } + + if (Config.DEBUG) + _log.info("SevenSigns: " + player.getName() + " has joined the " + getCabalName(chosenCabal) + + " for the " + getSealName(chosenSeal, false) + "!"); + + return chosenCabal; + } + + /** * Returns the amount of ancient adena the specified player can claim, if any.
    * If removeReward = True, all the ancient adena owed to them is removed, then * DB is updated. * - * @param player - * @param removeReward - * @return int rewardAmount - */ - public int getAncientAdenaReward(L2PcInstance player, boolean removeReward) + * @param player + * @param removeReward + * @return int rewardAmount + */ + public int getAncientAdenaReward(L2PcInstance player, boolean removeReward) { - int charObjId = player.getObjectId(); - StatsSet currPlayer = _signsPlayerData.get(charObjId); - - int rewardAmount = currPlayer.getInteger("ancient_adena_amount"); - - if (removeReward) { - currPlayer.set("ancient_adena_amount", 0); - _signsPlayerData.put(charObjId, currPlayer); - - try { + int charObjId = player.getObjectId(); + StatsSet currPlayer = _signsPlayerData.get(charObjId); + + int rewardAmount = currPlayer.getInteger("ancient_adena_amount"); + + if (removeReward) + { + currPlayer.set("ancient_adena_amount", 0); + _signsPlayerData.put(charObjId, currPlayer); + + try + { saveSevenSignsData(player, false); } - catch (Exception e) { + catch (Exception e) + { _log.severe("Failed to save Seven Signs configuration: " + e); } - } - - return rewardAmount; - } - - /** + } + + return rewardAmount; + } + + /** * Used to add the specified player's seal stone contribution points * to the current total for their cabal. Returns the point score the * contribution was worth. * * Each stone count must be broken down and specified by the stone's color. * - * @param player - * @param blueCount - * @param greenCount - * @param redCount - * @return int contribScore - */ - public int addPlayerStoneContrib(L2PcInstance player, int blueCount, int greenCount, int redCount) - { - int charObjId = player.getObjectId(); - StatsSet currPlayer = _signsPlayerData.get(charObjId); - - int contribScore = calcContributionScore(blueCount, greenCount, redCount); - int totalAncientAdena = currPlayer.getInteger("ancient_adena_amount") + calcAncientAdenaReward(blueCount, greenCount, redCount); - int totalContribScore = currPlayer.getInteger("contribution_score") + contribScore; - - if (totalContribScore > MAXIMUM_PLAYER_CONTRIB) - return -1; - - currPlayer.set("red_stones", currPlayer.getInteger("red_stones") + redCount); - currPlayer.set("green_stones", currPlayer.getInteger("green_stones") + greenCount); - currPlayer.set("blue_stones", currPlayer.getInteger("blue_stones") + blueCount); - currPlayer.set("ancient_adena_amount", totalAncientAdena); - currPlayer.set("contribution_score", totalContribScore); - _signsPlayerData.put(charObjId, currPlayer); - - if (currPlayer.getString("cabal").equals("dawn")) - _dawnStoneScore += contribScore; - else - _duskStoneScore += contribScore; - - try { - saveSevenSignsData(player, true); - } - catch (Exception e) { - _log.severe("Failed to save Seven Signs configuration: " + e); - } - - if (Config.DEBUG) - _log.info("SevenSigns: " + player.getName() + " contributed " + contribScore + " seal stone points to their cabal."); - - return contribScore; - } - - /** + * @param player + * @param blueCount + * @param greenCount + * @param redCount + * @return int contribScore + */ + public int addPlayerStoneContrib(L2PcInstance player, int blueCount, int greenCount, int redCount) + { + int charObjId = player.getObjectId(); + StatsSet currPlayer = _signsPlayerData.get(charObjId); + + int contribScore = calcContributionScore(blueCount, greenCount, redCount); + int totalAncientAdena = currPlayer.getInteger("ancient_adena_amount") + + calcAncientAdenaReward(blueCount, greenCount, redCount); + int totalContribScore = currPlayer.getInteger("contribution_score") + contribScore; + + if (totalContribScore > MAXIMUM_PLAYER_CONTRIB) return -1; + + currPlayer.set("red_stones", currPlayer.getInteger("red_stones") + redCount); + currPlayer.set("green_stones", currPlayer.getInteger("green_stones") + greenCount); + currPlayer.set("blue_stones", currPlayer.getInteger("blue_stones") + blueCount); + currPlayer.set("ancient_adena_amount", totalAncientAdena); + currPlayer.set("contribution_score", totalContribScore); + _signsPlayerData.put(charObjId, currPlayer); + + if (currPlayer.getString("cabal").equals("dawn")) _dawnStoneScore += contribScore; + else _duskStoneScore += contribScore; + + try + { + saveSevenSignsData(player, true); + } + catch (Exception e) + { + _log.severe("Failed to save Seven Signs configuration: " + e); + } + + if (Config.DEBUG) + _log.info("SevenSigns: " + player.getName() + " contributed " + contribScore + + " seal stone points to their cabal."); + + return contribScore; + } + + /** * Adds the specified number of festival points to the specified cabal. * Remember, the same number of points are deducted from the rival cabal * to maintain proportionality. * - * @param cabal - * @param amount - */ - public void addFestivalScore(int cabal, int amount) + * @param cabal + * @param amount + */ + public void addFestivalScore(int cabal, int amount) { - if (cabal == CABAL_DUSK) { - _duskFestivalScore += amount; - + if (cabal == CABAL_DUSK) + { + _duskFestivalScore += amount; + // To prevent negative scores! - if (_dawnFestivalScore >= amount) - _dawnFestivalScore -= amount; + if (_dawnFestivalScore >= amount) _dawnFestivalScore -= amount; } - else { - _dawnFestivalScore += amount; - - if (_duskFestivalScore >= amount) - _duskFestivalScore -= amount; + else + { + _dawnFestivalScore += amount; + + if (_duskFestivalScore >= amount) _duskFestivalScore -= amount; } - } - - /** + } + + /** * Send info on the current Seven Signs period to the specified player. * - * @param player - */ - public void sendCurrentPeriodMsg(L2PcInstance player) - { + * @param player + */ + public void sendCurrentPeriodMsg(L2PcInstance player) + { SystemMessage sm = null; - - switch (_activePeriod) { - case PERIOD_COMP_RECRUITING: - sm = new SystemMessage(1260); - break; - case PERIOD_COMPETITION: - sm = new SystemMessage(1261); - break; - case PERIOD_COMP_RESULTS: - sm = new SystemMessage(1262); - break; - case PERIOD_SEAL_VALIDATION: - sm = new SystemMessage(1263); - break; - } - - player.sendPacket(sm); - } - - /** + + switch (_activePeriod) + { + case PERIOD_COMP_RECRUITING: + sm = new SystemMessage(1260); + break; + case PERIOD_COMPETITION: + sm = new SystemMessage(1261); + break; + case PERIOD_COMP_RESULTS: + sm = new SystemMessage(1262); + break; + case PERIOD_SEAL_VALIDATION: + sm = new SystemMessage(1263); + break; + } + + player.sendPacket(sm); + } + + /** * Sends the built-in system message specified by sysMsgId to all online players. * - * @param sysMsgId - */ - public void sendMessageToAll(int sysMsgId) - { + * @param sysMsgId + */ + public void sendMessageToAll(int sysMsgId) + { SystemMessage sm = new SystemMessage(sysMsgId); - - for (L2PcInstance player : L2World.getInstance().getAllPlayers()) - player.sendPacket(sm); - } - + + for (L2PcInstance player : L2World.getInstance().getAllPlayers()) + player.sendPacket(sm); + } + /** * Used to initialize the seals for each cabal. (Used at startup or at beginning of a new cycle). * This method should be called after resetSeals() and calcNewSealOwners() on a new cycle. */ protected void initializeSeals() - { - for (Integer currSeal : _signsSealOwners.keySet()) - { - int sealOwner = _signsSealOwners.get(currSeal); - - if (sealOwner != CABAL_NULL) - if (isSealValidationPeriod()) - _log.info("SevenSigns: The " + getCabalName(sealOwner) + " have won the " + getSealName(currSeal, false) + "."); - else - _log.info("SevenSigns: The " + getSealName(currSeal, false) + " is currently owned by " + getCabalName(sealOwner) + "."); - else - _log.info("SevenSigns: The " + getSealName(currSeal, false) + " remains unclaimed."); - } - } - + { + for (Integer currSeal : _signsSealOwners.keySet()) + { + int sealOwner = _signsSealOwners.get(currSeal); + + if (sealOwner != CABAL_NULL) if (isSealValidationPeriod()) _log.info("SevenSigns: The " + + getCabalName(sealOwner) + " have won the " + getSealName(currSeal, false) + "."); + else _log.info("SevenSigns: The " + getSealName(currSeal, false) + " is currently owned by " + + getCabalName(sealOwner) + "."); + else _log.info("SevenSigns: The " + getSealName(currSeal, false) + " remains unclaimed."); + } + } + /** * Only really used at the beginning of a new cycle, this method resets all seal-related data. */ protected void resetSeals() - { - _signsDawnSealTotals.put(SEAL_AVARICE, CABAL_NULL); - _signsDawnSealTotals.put(SEAL_GNOSIS, CABAL_NULL); - _signsDawnSealTotals.put(SEAL_STRIFE, CABAL_NULL); - _signsDuskSealTotals.put(SEAL_AVARICE, CABAL_NULL); - _signsDuskSealTotals.put(SEAL_GNOSIS, CABAL_NULL); - _signsDuskSealTotals.put(SEAL_STRIFE, CABAL_NULL); - } - + { + _signsDawnSealTotals.put(SEAL_AVARICE, CABAL_NULL); + _signsDawnSealTotals.put(SEAL_GNOSIS, CABAL_NULL); + _signsDawnSealTotals.put(SEAL_STRIFE, CABAL_NULL); + _signsDuskSealTotals.put(SEAL_AVARICE, CABAL_NULL); + _signsDuskSealTotals.put(SEAL_GNOSIS, CABAL_NULL); + _signsDuskSealTotals.put(SEAL_STRIFE, CABAL_NULL); + } + /** * Calculates the ownership of the three Seals of the Seven Signs, * based on various criterion. @@ -1248,100 +1333,91 @@ * Should only ever called at the beginning of a new cycle. */ protected void calcNewSealOwners() - { - for (StatsSet sevenDat : _signsPlayerData.values()) - { - int playerSeal = sevenDat.getInteger("seal"); - - if (playerSeal == SEAL_NULL) - continue; - - if (sevenDat.getString("cabal").equals("dawn")) - _signsDawnSealTotals.put(playerSeal, _signsDawnSealTotals.get(playerSeal) + 1); - else if (sevenDat.getString("cabal").equals("dusk")) - _signsDuskSealTotals.put(playerSeal, _signsDuskSealTotals.get(playerSeal) + 1); - else - continue; - } - - if (Config.DEBUG) { - _log.info("SevenSigns: (Avarice) Dawn = " + _signsDawnSealTotals.get(SEAL_AVARICE) + ", Dusk = " + _signsDuskSealTotals.get(SEAL_AVARICE)); - _log.info("SevenSigns: (Gnosis) Dawn = " + _signsDawnSealTotals.get(SEAL_GNOSIS) + ", Dusk = " + _signsDuskSealTotals.get(SEAL_GNOSIS)); - _log.info("SevenSigns: (Strife) Dawn = " + _signsDawnSealTotals.get(SEAL_STRIFE) + ", Dusk = " + _signsDuskSealTotals.get(SEAL_STRIFE)); - } - - for (Integer currSeal : _signsDawnSealTotals.keySet()) - { - int prevSealOwner = _signsSealOwners.get(currSeal); - int newSealOwner; - - int winningCabalSealScore = 0; - int totalWinningCabalMembers = 0; - - /* - * - If a Seal was already closed or owned by the opponent and the new winner wants - * to assume ownership of the Seal, 35% or more of the members of the Cabal must - * have chosen the Seal. If they chose less than 35%, they cannot own the Seal. - * - * - If the Seal was owned by the winner in the previous Seven Signs, they can retain - * that seal if 10% or more members have chosen it. If they want to possess a new Seal, - * at least 35% of the members of the Cabal must have chosen the new Seal. - */ - if (prevSealOwner != getCabalHighestScore()) - { - totalWinningCabalMembers = getTotalMembers(getCabalHighestScore()); - - if (getCabalHighestScore() == CABAL_DAWN) - winningCabalSealScore = _signsDawnSealTotals.get(currSeal); - else - winningCabalSealScore = _signsDuskSealTotals.get(currSeal); - - if (winningCabalSealScore > Math.round((float)0.35 * totalWinningCabalMembers)) - newSealOwner = getCabalHighestScore(); - else - newSealOwner = prevSealOwner; - } - else - { - totalWinningCabalMembers = getTotalMembers(prevSealOwner); - - if (prevSealOwner == CABAL_DAWN) - winningCabalSealScore = _signsDawnSealTotals.get(currSeal); - else - winningCabalSealScore = _signsDuskSealTotals.get(currSeal); + { + for (StatsSet sevenDat : _signsPlayerData.values()) + { + int playerSeal = sevenDat.getInteger("seal"); - if (winningCabalSealScore > Math.round((float)0.10 * totalWinningCabalMembers)) - newSealOwner = prevSealOwner; - else - newSealOwner = CABAL_NULL; - } - - _signsSealOwners.put(currSeal, newSealOwner); - - // Alert all online players to new seal status. - switch (currSeal) { - case SEAL_AVARICE: - if (newSealOwner == CABAL_DAWN) - sendMessageToAll(1212); - if (newSealOwner == CABAL_DUSK) - sendMessageToAll(1215); - break; - case SEAL_GNOSIS: - if (newSealOwner == CABAL_DAWN) - sendMessageToAll(1213); - if (newSealOwner == CABAL_DUSK) - sendMessageToAll(1216); - break; - case SEAL_STRIFE: - if (newSealOwner == CABAL_DAWN) - sendMessageToAll(1214); - if (newSealOwner == CABAL_DUSK) - sendMessageToAll(1217); - break; - } - } - } - + if (playerSeal == SEAL_NULL) continue; + + if (sevenDat.getString("cabal").equals("dawn")) _signsDawnSealTotals.put( + playerSeal, + _signsDawnSealTotals.get(playerSeal) + 1); + else if (sevenDat.getString("cabal").equals("dusk")) _signsDuskSealTotals.put( + playerSeal, + _signsDuskSealTotals.get(playerSeal) + 1); + else continue; + } + + if (Config.DEBUG) + { + _log.info("SevenSigns: (Avarice) Dawn = " + _signsDawnSealTotals.get(SEAL_AVARICE) + + ", Dusk = " + _signsDuskSealTotals.get(SEAL_AVARICE)); + _log.info("SevenSigns: (Gnosis) Dawn = " + _signsDawnSealTotals.get(SEAL_GNOSIS) + + ", Dusk = " + _signsDuskSealTotals.get(SEAL_GNOSIS)); + _log.info("SevenSigns: (Strife) Dawn = " + _signsDawnSealTotals.get(SEAL_STRIFE) + + ", Dusk = " + _signsDuskSealTotals.get(SEAL_STRIFE)); + } + + for (Integer currSeal : _signsDawnSealTotals.keySet()) + { + int prevSealOwner = _signsSealOwners.get(currSeal); + int newSealOwner; + + int winningCabalSealScore = 0; + int totalWinningCabalMembers = 0; + + /* + * - If a Seal was already closed or owned by the opponent and the new winner wants + * to assume ownership of the Seal, 35% or more of the members of the Cabal must + * have chosen the Seal. If they chose less than 35%, they cannot own the Seal. + * + * - If the Seal was owned by the winner in the previous Seven Signs, they can retain + * that seal if 10% or more members have chosen it. If they want to possess a new Seal, + * at least 35% of the members of the Cabal must have chosen the new Seal. + */ + if (prevSealOwner != getCabalHighestScore()) + { + totalWinningCabalMembers = getTotalMembers(getCabalHighestScore()); + + if (getCabalHighestScore() == CABAL_DAWN) winningCabalSealScore = _signsDawnSealTotals.get(currSeal); + else winningCabalSealScore = _signsDuskSealTotals.get(currSeal); + + if (winningCabalSealScore > Math.round((float) 0.35 * totalWinningCabalMembers)) newSealOwner = getCabalHighestScore(); + else newSealOwner = prevSealOwner; + } + else + { + totalWinningCabalMembers = getTotalMembers(prevSealOwner); + + if (prevSealOwner == CABAL_DAWN) winningCabalSealScore = _signsDawnSealTotals.get(currSeal); + else winningCabalSealScore = _signsDuskSealTotals.get(currSeal); + + if (winningCabalSealScore > Math.round((float) 0.10 * totalWinningCabalMembers)) newSealOwner = prevSealOwner; + else newSealOwner = CABAL_NULL; + } + + _signsSealOwners.put(currSeal, newSealOwner); + + // Alert all online players to new seal status. + switch (currSeal) + { + case SEAL_AVARICE: + if (newSealOwner == CABAL_DAWN) sendMessageToAll(1212); + if (newSealOwner == CABAL_DUSK) sendMessageToAll(1215); + break; + case SEAL_GNOSIS: + if (newSealOwner == CABAL_DAWN) sendMessageToAll(1213); + if (newSealOwner == CABAL_DUSK) sendMessageToAll(1216); + break; + case SEAL_STRIFE: + if (newSealOwner == CABAL_DAWN) sendMessageToAll(1214); + if (newSealOwner == CABAL_DUSK) sendMessageToAll(1217); + break; + } + } + } + /** * This method is called to remove all players from catacombs and * necropolises, who belong to the losing cabal. @@ -1351,115 +1427,133 @@ private void teleLosingCabalFromDungeons() { for (L2PcInstance onlinePlayer : L2World.getInstance().getAllPlayers()) - if (onlinePlayer.getZ() < -4700) + if (onlinePlayer.getZ() < -4700) { onlinePlayer.teleToLocation(MapRegionTable.TeleportWhereType.Town); onlinePlayer.sendMessage("You have been teleported to the nearest town due to the beginning of the Seal Validation period."); } } - - /** + + /** * The primary controller of period change of the Seven Signs system. * This runs all related tasks depending on the period that is about to begin. * - * @author Tempy - */ - private class SevenSignsPeriodChange implements Runnable - { - public void run() + * @author Tempy + */ + private class SevenSignsPeriodChange implements Runnable + { + public void run() { /* * Remember the period check here refers to the period just ENDED! */ final int periodEnded = _activePeriod; _activePeriod++; - - switch (periodEnded) { - case PERIOD_COMP_RECRUITING: // Initialization - + + switch (periodEnded) + { + case PERIOD_COMP_RECRUITING: // Initialization + // Start the Festival of Darkness cycle. - SevenSignsFestival.getInstance().startFestivalManager(); - + SevenSignsFestival.getInstance().startFestivalManager(); + // Send message that Competition has begun. sendMessageToAll(1210); - break; - case PERIOD_COMPETITION: // Results Calculation - - // Send message that Competition has ended. - sendMessageToAll(1211); - - int compWinner = getCabalHighestScore(); - - // Schedule a stop of the festival engine. - SevenSignsFestival.getInstance().getFestivalManagerSchedule().cancel(false); - - resetSeals(); + break; + case PERIOD_COMPETITION: // Results Calculation + + // Send message that Competition has ended. + sendMessageToAll(1211); + + int compWinner = getCabalHighestScore(); + + // Schedule a stop of the festival engine. + SevenSignsFestival.getInstance().getFestivalManagerSchedule().cancel(false); + + resetSeals(); calcNewSealOwners(); - - if (compWinner == CABAL_DUSK) - sendMessageToAll(1240); // Send message that Dusk are victorious. - else - sendMessageToAll(1241); // Send message that Dawn are victorious. - + + if (compWinner == CABAL_DUSK) sendMessageToAll(1240); // Send message that Dusk are victorious. + else sendMessageToAll(1241); // Send message that Dawn are victorious. + _previousWinner = compWinner; - break; - case PERIOD_COMP_RESULTS: // Seal Validation - + break; + case PERIOD_COMP_RESULTS: // Seal Validation + // Perform initial Seal Validation set up. initializeSeals(); spawnSevenSignsNPCs(); teleLosingCabalFromDungeons(); - + // Send message that Seal Validation has begun. sendMessageToAll(1218); - - _log.info("SevenSigns: The " + getCabalName(_previousWinner) + " have won the competition with " + getCurrentScore(_previousWinner) + " points!"); - break; - case PERIOD_SEAL_VALIDATION: // Reset for New Cycle - - // Ensure a cycle restart when this period ends. + + _log.info("SevenSigns: The " + getCabalName(_previousWinner) + + " have won the competition with " + getCurrentScore(_previousWinner) + + " points!"); + break; + case PERIOD_SEAL_VALIDATION: // Reset for New Cycle + + // Ensure a cycle restart when this period ends. _activePeriod = PERIOD_COMP_RECRUITING; - // Send message that Seal Validation has ended. - sendMessageToAll(1219); - - // Reset all data - resetPlayerData(); + // Send message that Seal Validation has ended. + sendMessageToAll(1219); + // Reset all data + resetPlayerData(); + // Reset all Festival-related data and remove any unused blood offerings. // NOTE: A full update of Festival data in the database is also performed. SevenSignsFestival.getInstance().resetFestivalData(false); - - _dawnStoneScore = 0; - _duskStoneScore = 0; - - _dawnFestivalScore = 0; - _duskFestivalScore = 0; - - removeSevenSignsNPCs(); - _currentCycle++; - break; - } - - // Make sure all Seven Signs data is saved for future use. - try { - saveSevenSignsData(null, true); - } - catch (Exception e) { - _log.severe("SevenSigns: Failed to save configuration: " + e); - } - - SignsSky ss = new SignsSky(); - - for (L2PcInstance player : L2World.getInstance().getAllPlayers()) - player.sendPacket(ss); - - _log.info("SevenSigns: The " + getCurrentPeriodName() + " period has begun!"); - + + _dawnStoneScore = 0; + _duskStoneScore = 0; + + _dawnFestivalScore = 0; + _duskFestivalScore = 0; + + removeSevenSignsNPCs(); + _currentCycle++; + break; + } + + // Make sure all Seven Signs data is saved for future use. + try + { + saveSevenSignsData(null, true); + } + catch (Exception e) + { + _log.severe("SevenSigns: Failed to save configuration: " + e); + } + + SignsSky ss = new SignsSky(); + + for (L2PcInstance player : L2World.getInstance().getAllPlayers()) + player.sendPacket(ss); + + _log.info("SevenSigns: The " + getCurrentPeriodName() + " period has begun!"); + setCalendarForNextPeriodChange(); - - SevenSignsPeriodChange sspc = new SevenSignsPeriodChange(); - ClientScheduler.getInstance().scheduleMed(sspc, getMilliToPeriodChange()); - } - } + + SevenSignsPeriodChange sspc = new SevenSignsPeriodChange(); + ClientScheduler.getInstance().scheduleMed(sspc, getMilliToPeriodChange()); + } + } + + private class SevenSignsUpdateSystem implements Runnable + { + public void run() + { + try + { + saveSevenSignsData(null, true); + } + catch (Exception e) + { + _log.severe("SevenSigns: Failed to save configuration: " + e); + } + } + } } \ No newline at end of file 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 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/script/EngineInterface.java (working copy) @@ -18,6 +18,7 @@ */ package net.sf.l2j.gameserver.script; +/* import net.sf.l2j.gameserver.Announcements; import net.sf.l2j.gameserver.CharNameTable; import net.sf.l2j.gameserver.CharTemplateTable; @@ -34,6 +35,7 @@ import net.sf.l2j.gameserver.TeleportLocationTable; import net.sf.l2j.gameserver.idfactory.IdFactory; import net.sf.l2j.gameserver.model.L2World; +*/ /** * @author Luis Arias @@ -44,6 +46,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(); @@ -67,8 +72,8 @@ public Announcements _announcements = Announcements.getInstance(); public MapRegionTable _mapRegions = MapRegionTable.getInstance(); + */ - //public ArrayList getAllPlayers(); //public Player getPlayer(String characterName); public void addQuestDrop(int npcID, int itemID, int min, int max, int chance, String questID, String[] states); Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/script/faenor/FaenorInterface.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/script/faenor/FaenorInterface.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/script/faenor/FaenorInterface.java (working copy) @@ -33,6 +33,7 @@ import net.sf.l2j.gameserver.script.EngineInterface; import net.sf.l2j.gameserver.script.Expression; import net.sf.l2j.gameserver.templates.L2NpcTemplate; +import net.sf.l2j.gameserver.NpcTable; import org.apache.bsf.BSFException; import org.apache.bsf.BSFManager; @@ -77,7 +78,7 @@ */ public void addQuestDrop(int npcID, int itemID, int min, int max, int chance, String questID, String[] states) { - L2NpcTemplate npc = _npcTable.getTemplate(npcID); + L2NpcTemplate npc = NpcTable.getInstance().getTemplate(npcID); if (npc == null) { throw new NullPointerException(); @@ -100,7 +101,7 @@ */ public void addDrop(int npcID, int itemID, int min, int max, boolean sweep, int chance) throws NullPointerException { - L2NpcTemplate npc = _npcTable.getTemplate(npcID); + L2NpcTemplate npc = NpcTable.getInstance().getTemplate(npcID); if (npc == null) { if (Config.DEBUG) System.out.print("Npc doesnt Exist"); @@ -120,7 +121,7 @@ */ public List getQuestDrops(int npcID) { - L2NpcTemplate npc = _npcTable.getTemplate(npcID); + L2NpcTemplate npc = NpcTable.getInstance().getTemplate(npcID); if (npc == null) { return null; Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/GameTimeController.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/GameTimeController.java (revision 2183) +++ 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; } Index: C:/workspace/L2_GameServer/java/net/sf/l2j/ConsoleLogFormatter.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/ConsoleLogFormatter.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/ConsoleLogFormatter.java (working copy) @@ -36,7 +36,7 @@ * @see java.util.logging.Formatter#format(java.util.logging.LogRecord) */ // private static final String _ = " "; - private static final String CRLF = "\r\n"; + private static final String CRLF = Config.NEWLINE_CRLF ? "\r\n" : "\n"; public String format(LogRecord record) { StringBuffer output = new StringBuffer(); Index: C:/workspace/L2_GameServer/java/net/sf/l2j/L2DatabaseFactory.java =================================================================== --- C:/workspace/L2_GameServer/java/net/sf/l2j/L2DatabaseFactory.java (revision 2183) +++ C:/workspace/L2_GameServer/java/net/sf/l2j/L2DatabaseFactory.java (working copy) @@ -63,9 +63,9 @@ config.setMinPoolSize(1); config.setMaxPoolSize(Config.DATABASE_MAX_CONNECTIONS); config.setMaxStatements(100); - config.setIdleConnectionTestPeriod(0); // test idle connection every 1 minute - config.setMaxIdleTime(0); // remove unused connection after 10 minutes - + config.setIdleConnectionTestPeriod(60); // test idle connection every 1 minute + config.setMaxIdleTime(600); // remove unused connection after 10 minutes + config.setNumHelperThreads(5); Class.forName(Config.DATABASE_DRIVER).newInstance(); if (Config.DEBUG) _log.fine("Database Connection Working"); Index: C:/workspace/L2_GameServer/dist/LoginServer_loop.sh =================================================================== --- C:/workspace/L2_GameServer/dist/LoginServer_loop.sh (revision 2183) +++ C:/workspace/L2_GameServer/dist/LoginServer_loop.sh (working copy) @@ -5,7 +5,7 @@ do mv log/java0.log.0 "log/`date +%Y-%m-%d_%H-%M-%S`_java.log" mv log/stdout.log "log/`date +%Y-%m-%d_%H-%M-%S`_stdout.log" - nice -n -2 java -Xms512m -Xmx512m -cp javolution.jar:c3p0-0.9.0.jar:mysql-connector-java-3.1.10-bin.jar:sqljdbc.jar:l2jserver.jar net.sf.l2j.loginserver.LoginServer > log/stdout.log 2>&1 + nice -n -2 java -Xss256k -Xincgc -Xms96m -Xmx128m -cp javolution.jar:c3p0-0.9.0.jar:mysql-connector-java-3.1.10-bin.jar:sqljdbc.jar:l2jserver.jar net.sf.l2j.loginserver.LoginServer > log/stdout.log 2>&1 err=$? # /etc/init.d/mysql restart sleep 10; Index: C:/workspace/L2_GameServer/dist/GameServer_loop.sh =================================================================== --- C:/workspace/L2_GameServer/dist/GameServer_loop.sh (revision 2183) +++ C:/workspace/L2_GameServer/dist/GameServer_loop.sh (working copy) @@ -5,7 +5,7 @@ do mv log/java0.log.0 "log/`date +%Y-%m-%d_%H-%M-%S`_java.log" mv log/stdout.log "log/`date +%Y-%m-%d_%H-%M-%S`_stdout.log" - nice -n -2 java -Xms512m -Xmx512m -cp bsf.jar:javolution.jar:bsh-2.0.jar:jython.jar:c3p0-0.9.0.jar:mysql-connector-java-3.1.10-bin.jar:sqljdbc.jar:l2jserver.jar net.sf.l2j.gameserver.GameServer > log/stdout.log 2>&1 + nice -n -2 java -Xincgc -Xss256k -Xms512m -Xmx512m -cp bsf.jar:javolution.jar:bsh-2.0.jar:jython.jar:c3p0-0.9.0.jar:mysql-connector-java-3.1.10-bin.jar:sqljdbc.jar:l2jserver.jar net.sf.l2j.gameserver.GameServer > log/stdout.log 2>&1 err=$? # /etc/init.d/mysql restart sleep 10; ----- END SVN DIFF ----- ----- BEGIN command-privileges.properties ----- # Alternative Configure GM commands access level # # This file only read if "AltPrivilegesAdmin = True"!!! # # Information: # 1) If AltPrivilegesSecureCheck = True # Every commands need a entry in this file, else the command cannot be executed. # else if a command haven't got a entry in this file the minimun access level is # AltPrivilegesDefaultLevel (default = 100) # 2) Some commands need a correct access level on GM Access table too, like: # the commands contained into AdminEditChar.java,AdminEditNpc.java,AdminSpawn.java files admin_admin = 100 admin_admin2 = 100 admin_list_announcements = 100 admin_reload_announcements = 100 admin_announce_announcements = 100 admin_add_announcement = 100 admin_del_announcement = 100 admin_announce = 100 admin_announce_menu = 100 admin_gm = 100 admin_kill = 100 admin_edit_npc = 100 admin_save_npc = 100 admin_show_droplist = 100 admin_edit_drop = 100 admin_add_drop = 100 admin_del_drop = 100 admin_showShop = 100 admin_showShopList = 100 admin_addShopItem = 100 admin_delShopItem = 100 admin_box_access = 100 admin_editShopItem = 100 admin_character_disconnect = 100 admin_server_gm_only = 100 admin_server_all = 100 admin_server_max_player = 100 admin_server_list_clock = 100 admin_server_login = 100 admin_pledge = 100 admin_kick = 100 admin_kick_non_gm = 100 admin_itemcreate = 100 admin_create_item = 100 admin_open = 100 admin_close = 100 admin_openall = 100 admin_closeall = 100 admin_mobmenu = 100 admin_mobgroup_create = 100 admin_mobgroup_spawn = 100 admin_mobgroup_unspawn = 100 admin_mobgroup_kill = 100 admin_mobgroup_idle = 100 admin_mobgroup_attack = 100 admin_mobgroup_rnd = 100 admin_mobgroup_return = 100 admin_mobgroup_follow = 100 admin_mobgroup_casting = 100 admin_mobgroup_nomove = 100 admin_mobgroup_attackgrp = 100 admin_mobgroup_invul = 100 admin_mobinst = 100 admin_heal = 100 admin_res = 100 admin_show_moves = 100 admin_show_moves_other = 100 admin_show_teleport = 100 admin_teleport_to_character = 100 admin_teleportto = 100 admin_move_to = 100 admin_teleport_character = 100 admin_recall = 100 admin_walk = 100 admin_explore = 100 admin_recall_npc = 100 admin_gonorth = 100 admin_gosouth = 100 admin_goeast = 100 admin_gowest = 100 admin_goup = 100 admin_godown = 100 admin_tele = 100 admin_teleto = 100 admin_failed = 100 admin_add_exp_sp_to_character = 100 admin_add_exp_sp = 100 admin_invis = 100 admin_invisible = 100 admin_vis = 100 admin_visible = 100 admin_earthquake = 201 admin_bighead = 100 admin_shrinkhead = 100 admin_unpara_all = 100 admin_para_all = 100 admin_unpara = 100 admin_para = 100 admin_polyself = 100 admin_unpolyself = 100 admin_changename = 100 admin_zone_get = 100 admin_ban = 100 admin_unban = 100 admin_changelvl = 100 admin_test = 100 admin_stats = 100 admin_skill_test = 100 admin_st = 100 admin_mp = 100 admin_known = 100 admin_restore = 100 admin_repair = 100 admin_help = 100 admin_fight_calculator = 100 admin_fight_calculator_show = 100 admin_fcs = 100 admin_server_shutdown = 100 admin_server_restart = 100 admin_server_abort = 100 admin_show_spawns = 100 admin_spawn = 100 admin_spawn_monster = 100 admin_spawn_index = 100 admin_unspawnall = 100 admin_respawnall = 100 admin_target = 100 admin_cache_htm_rebuild = 100 admin_cache_htm_reload = 100 admin_cache_crest_rebuild = 100 admin_cache_crest_fix = 100 admin_play_sounds = 100 admin_play_sound = 100 admin_gmliston = 100 admin_gmlistoff = 100 admin_silence = 100 admin_atmosphere = 100 admin_diet = 100 admin_tradeoff = 100 admin_reload = 100 admin_ride_wyvern = 100 admin_ride_strider = 100 admin_unride_wyvern = 100 admin_unride_strider = 100 admin_unride = 100 admin_buy = 100 admin_gmshop = 100 admin_unblockip = 100 admin_invul = 100 admin_setinvul = 100 admin_polymorph = 100 admin_show_skills = 100 admin_remove_skills = 100 admin_skill_list = 100 admin_skill_index = 100 admin_add_skill = 100 admin_remove_skill = 100 admin_get_skills = 100 admin_reset_skills = 100 admin_give_all_skills = 100 admin_delete = 100 admin_edit_character = 100 admin_current_player = 100 admin_nokarma = 100 admin_setkarma = 100 admin_character_list = 100 admin_show_characters = 100 admin_find_character = 100 admin_save_modifications = 100 admin_rec = 100 admin_settitle = 100 admin_setname = 100 admin_setsex = 100 admin_setcolor = 100 admin_banchatadmin_unbanchat = 100 admin_mammon_find = 100 admin_mammon_respawn = 100 admin_list_spawns = 100 admin_msg = 100 admin_mons = 100 admin_siege = 100 admin_add_attacker = 100 admin_add_defender = 100 admin_add_guard = 100 admin_list_siege_clans = 100 admin_clear_siege_list = 100 admin_move_defenders = 100 admin_spawn_doors = 100 admin_endsiege = 100 admin_startsiege = 100 admin_setcastle = 100 admin_char_manage = 100 admin_teleport_character_to_menu = 100 admin_recall_char_menu = 100 admin_goto_char_menu = 100 admin_kick_menu = 100 admin_kill_menu = 100 admin_ban_menu = 100 admin_unban_menu = 100 admin_gmchat = 100 admin_setew = 100 admin_seteh = 100 admin_setec = 100 admin_seteg = 100 admin_setel = 100 admin_seteb = 100 admin_setes = 100 admin_setle = 100 admin_setre = 100 admin_setlf = 100 admin_setrf = 100 admin_seten = 100 admin_setun = 100 admin_setba = 100 admin_enchant = 100 ----- END altsettings.properties ----