l2jkain
Members-
Posts
207 -
Credits
0 -
Joined
-
Last visited
-
Feedback
0%
Content Type
Articles
Profiles
Forums
Store
Everything posted by l2jkain
-
Well I would like to know how I put the player to register only once in olly and not be able to register directly. I use acis 350 .. I keep registering once after the other without for how I shot that ??? Put a message saying you have already registered
-
How do I leave an image on the bottom of the htmls ??? https://www.l2jbrasil.com/index.php?/topic/80308-share-c1-interlude-html-com-imagem/
-
Buy engine ctf, tvt and dm and a feanor system for acis 100% no bugs none
-
Help Feanor L2Jacis For Xml
l2jkain replied to l2jkain's question in Request Server Development Help [L2J]
help -
Hello tou trying to create a feanor with the droplist of the game so you do not have to do with a frozen type lib is able to work? I do not know how to create from 0 so I copied the drop list and removed the parts of npcs and left only the part of the drope someone can help me I know not to be right but I do not know what to do right anymore. /* * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.l2j.gameserver.datatables; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; import net.sf.l2j.gameserver.model.actor.template.NpcTemplate; import net.sf.l2j.gameserver.model.item.DropCategory; import net.sf.l2j.gameserver.model.item.DropData; import net.sf.l2j.gameserver.templates.StatsSet; import net.sf.l2j.gameserver.xmlfactory.XMLDocumentFactory; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; /** * @author williams * */ public class FeanorTable { private static final Logger _log = Logger.getLogger(FeanorTable.class.getName()); private final Map<Integer, NpcTemplate> _feanor = new HashMap<>(); protected FeanorTable() { load(); } public void reloadAllNpc() { _feanor.clear(); load(); } private void load() { try { final File dir = new File("./data/xml/feanor.xml"); final StatsSet set = new StatsSet(); for (File file : dir.listFiles()) { final Document doc = XMLDocumentFactory.getInstance().loadDocument(file); Node list = doc.getFirstChild(); for (Node feanor = list.getFirstChild(); feanor != null; feanor = feanor.getNextSibling()) { NamedNodeMap attrs = feanor.getAttributes(); if ("drops".equalsIgnoreCase(feanor.getNodeName())) { final String type = set.getString("type"); final boolean isRaid = type.equalsIgnoreCase("L2RaidBoss") || type.equalsIgnoreCase("L2GrandBoss"); final List<DropCategory> drops = new ArrayList<>(); for (Node dropCat = feanor.getFirstChild(); dropCat != null; dropCat = dropCat.getNextSibling()) { if ("category".equalsIgnoreCase(dropCat.getNodeName())) { attrs = dropCat.getAttributes(); final DropCategory category = new DropCategory(Integer.parseInt(attrs.getNamedItem("id").getNodeValue())); for (Node item = dropCat.getFirstChild(); item != null; item = item.getNextSibling()) { if ("drop".equalsIgnoreCase(item.getNodeName())) { attrs = item.getAttributes(); final DropData data = new DropData(); data.setItemId(Integer.parseInt(attrs.getNamedItem("itemid").getNodeValue())); data.setMinDrop(Integer.parseInt(attrs.getNamedItem("min").getNodeValue())); data.setMaxDrop(Integer.parseInt(attrs.getNamedItem("max").getNodeValue())); data.setChance(Integer.parseInt(attrs.getNamedItem("chance").getNodeValue())); if (ItemTable.getInstance().getTemplate(data.getItemId()) == null) { _log.warning("Droplist data for undefined itemId: " + data.getItemId()); continue; } category.addDropData(data, isRaid); } } drops.add(category); } } set.set("drops", drops); } else if ("teachTo".equalsIgnoreCase(feanor.getNodeName())) set.set("teachTo", feanor.getAttributes().getNamedItem("classes").getNodeValue()); } } } catch (Exception e) { _log.log(Level.SEVERE, "FeanorTable: Error parsing Feanor Table : ", e); } _log.info("FeanorTable: Loaded " + _feanor.size() + " Feanor Table."); } public NpcTemplate getTemplate(int id) { return _feanor.get(id); } /** * @param name to search. * @return the template list of NPCs for a given name. */ public NpcTemplate getTemplateByName(String name) { for (NpcTemplate npcTemplate : _feanor.values()) { if (npcTemplate.getName().equalsIgnoreCase(name)) return npcTemplate; } return null; } /** * Gets all templates matching the filter. * @param filter * @return the template list for the given filter */ public List<NpcTemplate> getTemplates(Predicate<NpcTemplate> filter) { return _feanor.values().stream().filter(filter).collect(Collectors.toList()); } public Collection<NpcTemplate> getAllNpcs() { return _feanor.values(); } public static FeanorTable getInstance() { return SingletonHolder._instance; } private static class SingletonHolder { protected static final FeanorTable _instance = new FeanorTable(); } }
-
Not replacing this does not lock but it is without video - <zone id="110011" type="BossZone" shape="Cuboid" minZ="-9205" maxZ="-8065"><!-- Frintezza Boss TODO --> - <stat name="InvadeTime" val="1800000" /> - <node X="-89840" Y="-139384" /> - <node X="-85732" Y="-155311" /> - </zone> + <zone id="110011" type="BossZone" shape="Cuboid" minZ="-5140" maxZ="-4000"><!-- Frintezza Boss --> + <stat name="InvadeTime" val="1800000" /> + <node X="172176" Y="-74106" /> + <node X="176284" Y="-90033" /> + </zone>
-
Not the error in the console nor the GameServer of the error in anything
-
Hello, I found a Frintezza on the internet, I adapted it, but it's very buggy. Someone help me to fix it. I do not do the minina idea. What else to change my server is already online. I wanted the Frintezza to make an event. This code is a member of the forum but he has the same error !! Code bug: ### Eclipse Workspace Patch 1.0 #P aCis_gameserver Index: config/npcs.properties =================================================================== --- config/npcs.properties (revision 90) +++ config/npcs.properties (working copy) @@ -185,9 +185,13 @@ # Random interval. Value is hour. FrintezzaRandomSpawn = 8 -# Delay of appearance time of Frintezza. Value is minute. -FrintezzaWaitTime = 1 +# Delay of appearance time of Frintezza. Value is minutes. +FrintezzaWaitTime = 10 +# Min and Max Party in Frintezza Default Min = 4 | Max = 5 +FrintezzaMinParties = 4 +FrintezzaMaxParties = 5 + # ------------------------------------------------------------ # Orfen # ------------------------------------------------------------ Index: java/net/sf/l2j/Config.java =================================================================== --- java/net/sf/l2j/Config.java (revision 90) +++ java/net/sf/l2j/Config.java (working copy) @@ -347,6 +347,8 @@ public static int SPAWN_INTERVAL_FRINTEZZA; public static int RANDOM_SPAWN_TIME_FRINTEZZA; public static int WAIT_TIME_FRINTEZZA; + public static int FRINTEZZA_MIN_PARTIES; + public static int FRINTEZZA_MAX_PARTIES; public static int SPAWN_INTERVAL_ORFEN; public static int RANDOM_SPAWN_TIME_ORFEN; @@ -1052,7 +1054,9 @@ SPAWN_INTERVAL_FRINTEZZA = npcs.getProperty("FrintezzaSpawnInterval", 48); RANDOM_SPAWN_TIME_FRINTEZZA = npcs.getProperty("FrintezzaRandomSpawn", 8); - WAIT_TIME_FRINTEZZA = npcs.getProperty("FrintezzaWaitTime", 1) * 60000; + WAIT_TIME_FRINTEZZA = npcs.getProperty("FrintezzaWaitTime", 10) * 60000; + FRINTEZZA_MIN_PARTIES = npcs.getProperty("FrintezzaMinParties", 4); + FRINTEZZA_MAX_PARTIES = npcs.getProperty("FrintezzaMaxParties", 5); SPAWN_INTERVAL_ORFEN = npcs.getProperty("OrfenSpawnInterval", 48); RANDOM_SPAWN_TIME_ORFEN = npcs.getProperty("OrfenRandomSpawn", 20); Index: java/net/sf/l2j/gameserver/scripting/scripts/ai/individual/Frintezza.java =================================================================== --- java/net/sf/l2j/gameserver/scripting/scripts/ai/individual/Frintezza.java (revision 0) +++ java/net/sf/l2j/gameserver/scripting/scripts/ai/individual/Frintezza.java (working copy) @@ -0,0 +1,1503 @@ +/* + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.sf.l2j.gameserver.scripting.scripts.ai.individual; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import net.sf.l2j.commons.random.Rnd; + +import net.sf.l2j.Config; +import net.sf.l2j.gameserver.ai.CtrlIntention; +import net.sf.l2j.gameserver.datatables.DoorTable; +import net.sf.l2j.gameserver.datatables.SkillTable; +import net.sf.l2j.gameserver.instancemanager.GrandBossManager; +import net.sf.l2j.gameserver.instancemanager.ZoneManager; +import net.sf.l2j.gameserver.model.L2CommandChannel; +import net.sf.l2j.gameserver.model.L2Party; +import net.sf.l2j.gameserver.model.L2Skill; +import net.sf.l2j.gameserver.model.actor.L2Attackable; +import net.sf.l2j.gameserver.model.actor.L2Character; +import net.sf.l2j.gameserver.model.actor.L2Npc; +import net.sf.l2j.gameserver.model.actor.instance.L2GrandBossInstance; +import net.sf.l2j.gameserver.model.actor.instance.L2MonsterInstance; +import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance; +import net.sf.l2j.gameserver.model.zone.type.L2BossZone; +import net.sf.l2j.gameserver.network.SystemMessageId; +import net.sf.l2j.gameserver.network.serverpackets.AbstractNpcInfo.NpcInfo; +import net.sf.l2j.gameserver.network.serverpackets.CreatureSay; +import net.sf.l2j.gameserver.network.serverpackets.Earthquake; +import net.sf.l2j.gameserver.network.serverpackets.MagicSkillCanceld; +import net.sf.l2j.gameserver.network.serverpackets.MagicSkillUse; +import net.sf.l2j.gameserver.network.serverpackets.NpcSay; +import net.sf.l2j.gameserver.network.serverpackets.PlaySound; +import net.sf.l2j.gameserver.network.serverpackets.SocialAction; +import net.sf.l2j.gameserver.network.serverpackets.SpecialCamera; +import net.sf.l2j.gameserver.network.serverpackets.SystemMessage; +import net.sf.l2j.gameserver.scripting.scripts.ai.L2AttackableAIScript; +import net.sf.l2j.gameserver.skills.AbnormalEffect; +import net.sf.l2j.gameserver.templates.StatsSet; + +/** + * Frintezza AI + * @author Darki699 + * @author SANDMAN L2J_JP(modified) + * @author JOJO Update by rocknow Updated by L2jOff team + */ +public class Frintezza extends L2AttackableAIScript +{ + private static final int[][] _invadeLoc = + { + { 174102, -76039, -5105 }, + { 173235, -76884, -5105 }, + { 175003, -76933, -5105 }, + { 174196, -76190, -5105 }, + { 174013, -76120, -5105 }, + { 173263, -75161, -5105 } + }; + private static final int[][] _skill = + { + { 5015, 1, 5000 }, + { 5015, 4, 5000 }, + { 5015, 2, 5000 }, + { 5015, 5, 5000 }, + { 5018, 1, 10000 }, + { 5016, 1, 5000 }, + { 5015, 3, 5000 }, + { 5015, 6, 5000 }, + { 5018, 2, 10000 }, + { 5019, 1, 10000 }, + { 5016, 1, 5000 } + }; + private static final int[][] _mobLoc = + { + { 18328,172894,-76019,-5107,243 }, + { 18328,174095,-77279,-5107,16216 }, + { 18328,174111,-74833,-5107,49043 }, + { 18328,175344,-76042,-5107,32847 }, + { 18330,173489,-76227,-5134,63565 }, + { 18330,173498,-75724,-5107,58498 }, + { 18330,174365,-76745,-5107,22424 }, + { 18330,174570,-75584,-5107,31968 }, + { 18330,174613,-76179,-5107,31471 }, + { 18332,173620,-75981,-5107,4588 }, + { 18332,173630,-76340,-5107,62454 }, + { 18332,173755,-75613,-5107,57892 }, + { 18332,173823,-76688,-5107,2411 }, + { 18332,174000,-75411,-5107,54718 }, + { 18332,174487,-75555,-5107,33861 }, + { 18332,174517,-76471,-5107,21893 }, + { 18332,174576,-76122,-5107,31176 }, + { 18332,174600,-75841,-5134,35927 }, + { 18329,173481,-76043,-5107,61312 }, + { 18329,173539,-75678,-5107,59524 }, + { 18329,173584,-76386,-5107,3041 }, + { 18329,173773,-75420,-5107,51115 }, + { 18329,173777,-76650,-5107,12588 }, + { 18329,174585,-76510,-5107,21704 }, + { 18329,174623,-75571,-5107,40141 }, + { 18329,174744,-76240,-5107,29202 }, + { 18329,174769,-75895,-5107,29572 }, + { 18333,173861,-76011,-5107,383 }, + { 18333,173872,-76461,-5107,8041 }, + { 18333,173898,-75668,-5107,51856 }, + { 18333,174422,-75689,-5107,42878 }, + { 18333,174460,-76355,-5107,27311 }, + { 18333,174483,-76041,-5107,30947 }, + { 18331,173515,-76184,-5107,6971 }, + { 18331,173516,-75790,-5134,3142 }, + { 18331,173696,-76675,-5107,6757 }, + { 18331,173766,-75502,-5134,60827 }, + { 18331,174473,-75321,-5107,37147 }, + { 18331,174493,-76505,-5107,34503 }, + { 18331,174568,-75654,-5134,41661 }, + { 18331,174584,-76263,-5107,31729 }, + { 18339,173892,-81592,-5123,50849 }, + { 18339,173958,-81820,-5123,7459 }, + { 18339,174128,-81805,-5150,21495 }, + { 18339,174245,-81566,-5123,41760 }, + { 18334,173264,-81529,-5072,1646 }, + { 18334,173265,-81656,-5072,441 }, + { 18334,173267,-81889,-5072,0 }, + { 18334,173271,-82015,-5072,65382 }, + { 18334,174867,-81655,-5073,32537 }, + { 18334,174868,-81890,-5073,32768 }, + { 18334,174869,-81485,-5073,32315 }, + { 18334,174871,-82017,-5073,33007 }, + { 18335,173074,-80817,-5107,8353 }, + { 18335,173128,-82702,-5107,5345 }, + { 18335,173181,-82544,-5107,65135 }, + { 18335,173191,-80981,-5107,6947 }, + { 18335,174859,-80889,-5134,24103 }, + { 18335,174924,-82666,-5107,38710 }, + { 18335,174947,-80733,-5107,22449 }, + { 18335,175096,-82724,-5107,42205 }, + { 18336,173435,-80512,-5107,65215 }, + { 18336,173440,-82948,-5107,417 }, + { 18336,173443,-83120,-5107,1094 }, + { 18336,173463,-83064,-5107,286 }, + { 18336,173465,-80453,-5107,174 }, + { 18336,173465,-83006,-5107,2604 }, + { 18336,173468,-82889,-5107,316 }, + { 18336,173469,-80570,-5107,65353 }, + { 18336,173469,-80628,-5107,166 }, + { 18336,173492,-83121,-5107,394 }, + { 18336,173493,-80683,-5107,0 }, + { 18336,173497,-80510,-5134,417 }, + { 18336,173499,-82947,-5107,0 }, + { 18336,173521,-83063,-5107,316 }, + { 18336,173523,-82889,-5107,128 }, + { 18336,173524,-80627,-5134,65027 }, + { 18336,173524,-83007,-5107,0 }, + { 18336,173526,-80452,-5107,64735 }, + { 18336,173527,-80569,-5134,65062 }, + { 18336,174602,-83122,-5107,33104 }, + { 18336,174604,-82949,-5107,33184 }, + { 18336,174609,-80514,-5107,33234 }, + { 18336,174609,-80684,-5107,32851 }, + { 18336,174629,-80627,-5107,33346 }, + { 18336,174632,-80570,-5107,32896 }, + { 18336,174632,-83066,-5107,32768 }, + { 18336,174635,-82893,-5107,33594 }, + { 18336,174636,-80456,-5107,32065 }, + { 18336,174639,-83008,-5107,33057 }, + { 18336,174660,-80512,-5107,33057 }, + { 18336,174661,-83121,-5107,32768 }, + { 18336,174663,-82948,-5107,32768 }, + { 18336,174664,-80685,-5107,32676 }, + { 18336,174687,-83008,-5107,32520 }, + { 18336,174691,-83066,-5107,32961 }, + { 18336,174692,-80455,-5107,33202 }, + { 18336,174692,-80571,-5107,32768 }, + { 18336,174693,-80630,-5107,32994 }, + { 18336,174693,-82889,-5107,32622 }, + { 18337,172837,-82382,-5107,58363 }, + { 18337,172867,-81123,-5107,64055 }, + { 18337,172883,-82495,-5107,64764 }, + { 18337,172916,-81033,-5107,7099 }, + { 18337,172940,-82325,-5107,58998 }, + { 18337,172946,-82435,-5107,58038 }, + { 18337,172971,-81198,-5107,14768 }, + { 18337,172992,-81091,-5107,9438 }, + { 18337,173032,-82365,-5107,59041 }, + { 18337,173064,-81125,-5107,5827 }, + { 18337,175014,-81173,-5107,26398 }, + { 18337,175061,-82374,-5107,43290 }, + { 18337,175096,-81080,-5107,24719 }, + { 18337,175169,-82453,-5107,37672 }, + { 18337,175172,-80972,-5107,32315 }, + { 18337,175174,-82328,-5107,41760 }, + { 18337,175197,-81157,-5107,27617 }, + { 18337,175245,-82547,-5107,40275 }, + { 18337,175249,-81075,-5107,28435 }, + { 18337,175292,-82432,-5107,42225 }, + { 18338,173014,-82628,-5107,11874 }, + { 18338,173033,-80920,-5107,10425 }, + { 18338,173095,-82520,-5107,49152 }, + { 18338,173115,-80986,-5107,9611 }, + { 18338,173144,-80894,-5107,5345 }, + { 18338,173147,-82602,-5107,51316 }, + { 18338,174912,-80825,-5107,24270 }, + { 18338,174935,-80899,-5107,18061 }, + { 18338,175016,-82697,-5107,39533 }, + { 18338,175041,-80834,-5107,25420 }, + { 18338,175071,-82549,-5107,39163 }, + { 18338,175154,-82619,-5107,36345 } + }; + + private static final int SCARLET1 = 29046; + private static final int SCARLET2 = 29047; + private static final int FRINTEZZA = 29045; + private static final int GUIDE = 32011; + private static final int CUBE = 29061; + + // Frintezza Status Tracking : + private static final byte DORMANT = 0; // Frintezza is spawned and no one has entered yet. Entry is unlocked + private static final byte WAITING = 1; // Frintezza is spawend and someone has entered, triggering a 30 minute window for additional people to enter before he unleashes his attack. Entry is unlocked + private static final byte FIGHTING = 2; // Frintezza is engaged in battle, annihilating his foes. Entry is locked + private static final byte DEAD = 3; // Frintezza has been killed. Entry is locked + + private static long _LastAction = 0; + private static int _Angle = 0; + private static int _Heading = 0; + private static int _LocCycle = 0; + private static int _Bomber = 0; + private static int _CheckDie = 0; + private static int _OnCheck = 0; + private static int _OnSong = 0; + private static int _Abnormal = 0; + private static int _OnMorph = 0; + private static int _Scarlet_x = 0; + private static int _Scarlet_y = 0; + private static int _Scarlet_z = 0; + private static int _Scarlet_h = 0; + private static int _SecondMorph = 0; + private static int _ThirdMorph = 0; + private static int _KillHallAlarmDevice = 0; + private static int _KillDarkChoirPlayer = 0; + private static int _KillDarkChoirCaptain = 0; + + private static L2BossZone _Zone; + private L2GrandBossInstance frintezza, weakScarlet, strongScarlet, activeScarlet; + private L2MonsterInstance demon1, demon2, demon3, demon4, portrait1, portrait2, portrait3, portrait4; + private L2Npc _frintezzaDummy, _overheadDummy, _portraitDummy1, _portraitDummy3, _scarletDummy; + private static List<L2PcInstance> _PlayersInside = new CopyOnWriteArrayList<>(); + private static List<L2Npc> _Room1Mobs = new CopyOnWriteArrayList<>(); + private static List<L2Npc> _Room2Mobs = new CopyOnWriteArrayList<>(); + private static List<L2Attackable> Minions = new CopyOnWriteArrayList<>(); + + // Boss: Frintezza + public Frintezza() + { + super("ai/individual"); + int[] mob = {SCARLET1, SCARLET2, FRINTEZZA, 18328, 18329, 18330, 18331, 18332, 18333, 18334, 18335, 18336, 18337, 18338, 18339, 29048, 29049, 29050, 29051}; + _Zone = ZoneManager.getInstance().getZoneById(110011, L2BossZone.class); + addAttackId(mob); + addKillId(mob); + addStartNpc(GUIDE); + addTalkId(GUIDE); + addStartNpc(CUBE); + addTalkId(CUBE); + StatsSet info = GrandBossManager.getInstance().getStatsSet(FRINTEZZA); + int status = GrandBossManager.getInstance().getBossStatus(FRINTEZZA); + if (status == DEAD) + { + long temp = (info.getLong("respawn_time") - System.currentTimeMillis()); + if (temp > 0) + startQuestTimer("frintezza_unlock", temp, null, null, false); + else + GrandBossManager.getInstance().setBossStatus(FRINTEZZA, DORMANT); + } + else if (status != DORMANT) + GrandBossManager.getInstance().setBossStatus(FRINTEZZA, DORMANT); + } + + @Override + public String onAdvEvent(String event, L2Npc npc, L2PcInstance player) + { + long temp = 0; + if (event.equalsIgnoreCase("waiting")) + { + startQuestTimer("close", 27000, npc, null, false); + startQuestTimer("camera_1", 30000, npc, null, false); + _Zone.broadcastPacket(new Earthquake(174232, -88020, -5116, 45, 27)); + } + else if (event.equalsIgnoreCase("room1_spawn")) + { + CreatureSay cs = new CreatureSay(0, 1, "Hall Alarm Device", "Intruders! Sound the alarm!"); + _Zone.broadcastPacket(cs); + for (int i = 0; i <= 17; i++) + { + L2Npc mob = addSpawn(_mobLoc[i][0], _mobLoc[i][1], _mobLoc[i][2], _mobLoc[i][3], _mobLoc[i][4], false, 0, false); + _Room1Mobs.add(mob); + } + } + else if (event.equalsIgnoreCase("room1_spawn2")) + { + for (int i = 18; i <= 26; i++) + { + L2Npc mob = addSpawn(_mobLoc[i][0], _mobLoc[i][1], _mobLoc[i][2], _mobLoc[i][3], _mobLoc[i][4], false, 0, false); + _Room1Mobs.add(mob); + } + } + else if (event.equalsIgnoreCase("room1_spawn3")) + { + for (int i = 27; i <= 32; i++) + { + L2Npc mob = addSpawn(_mobLoc[i][0], _mobLoc[i][1], _mobLoc[i][2], _mobLoc[i][3], _mobLoc[i][4], false, 0, false); + _Room1Mobs.add(mob); + } + } + else if (event.equalsIgnoreCase("room1_spawn4")) + { + for (int i = 33; i <= 40; i++) + { + L2Npc mob = addSpawn(_mobLoc[i][0], _mobLoc[i][1], _mobLoc[i][2], _mobLoc[i][3], _mobLoc[i][4], false, 0, false); + _Room1Mobs.add(mob); + } + } + else if (event.equalsIgnoreCase("room2_spawn")) + { + for (int i = 41; i <= 44; i++) + { + L2Npc mob = addSpawn(_mobLoc[i][0], _mobLoc[i][1], _mobLoc[i][2], _mobLoc[i][3], _mobLoc[i][4], false, 0, false); + _Room2Mobs.add(mob); + } + } + else if (event.equalsIgnoreCase("room2_spawn2")) + { + for (int i = 45; i <= 131; i++) + { + L2Npc mob = addSpawn(_mobLoc[i][0], _mobLoc[i][1], _mobLoc[i][2], _mobLoc[i][3], _mobLoc[i][4], false, 0, false); + _Room2Mobs.add(mob); + } + } + else if (event.equalsIgnoreCase("room1_del")) + { + for (L2Npc mob : _Room1Mobs) + { + if (mob != null) + mob.deleteMe(); + } + _Room1Mobs.clear(); + } + else if (event.equalsIgnoreCase("room2_del")) + { + for (L2Npc mob : _Room2Mobs) + { + if (mob != null) + mob.deleteMe(); + } + _Room2Mobs.clear(); + } + else if (event.equalsIgnoreCase("room3_del")) + { + if (demon1 != null) + demon1.deleteMe(); + if (demon2 != null) + demon2.deleteMe(); + if (demon3 != null) + demon3.deleteMe(); + if (demon4 != null) + demon4.deleteMe(); + if (portrait1 != null) + portrait1.deleteMe(); + if (portrait2 != null) + portrait2.deleteMe(); + if (portrait3 != null) + portrait3.deleteMe(); + if (portrait4 != null) + portrait4.deleteMe(); + if (frintezza != null) + frintezza.deleteMe(); + if (weakScarlet != null) + weakScarlet.deleteMe(); + if (strongScarlet != null) + strongScarlet.deleteMe(); + + demon1 = null; + demon2 = null; + demon3 = null; + demon4 = null; + portrait1 = null; + portrait2 = null; + portrait3 = null; + portrait4 = null; + frintezza = null; + weakScarlet = null; + strongScarlet = null; + activeScarlet = null; + } + else if (event.equalsIgnoreCase("clean")) + { + _LastAction = 0; + _LocCycle = 0; + _CheckDie = 0; + _OnCheck = 0; + _Abnormal = 0; + _OnMorph = 0; + _SecondMorph = 0; + _ThirdMorph = 0; + _KillHallAlarmDevice = 0; + _KillDarkChoirPlayer = 0; + _KillDarkChoirCaptain = 0; + _PlayersInside.clear(); + } + else if (event.equalsIgnoreCase("close")) + { + for (int i = 25150051; i <= 25150058; i++) + DoorTable.getInstance().getDoor(i).closeMe(); + for (int i = 25150061; i <= 25150070; i++) + DoorTable.getInstance().getDoor(i).closeMe(); + + DoorTable.getInstance().getDoor(25150042).closeMe(); + DoorTable.getInstance().getDoor(25150043).closeMe(); + DoorTable.getInstance().getDoor(25150045).closeMe(); + DoorTable.getInstance().getDoor(25150046).closeMe(); + } + else if (event.equalsIgnoreCase("loc_check")) + { + if (GrandBossManager.getInstance().getBossStatus(FRINTEZZA) == FIGHTING) + { + if (!_Zone.isInsideZone(npc)) + npc.teleToLocation(174232, -88020, -5116, 0); + if (npc.getX() < 171932 || npc.getX() > 176532 || npc.getY() < -90320 || npc.getY() > -85720 || npc.getZ() < -5130) + npc.teleToLocation(174232, -88020, -5116, 0); + } + } + else if (event.equalsIgnoreCase("camera_1")) + { + GrandBossManager.getInstance().setBossStatus(FRINTEZZA, FIGHTING); + _frintezzaDummy = addSpawn(29052, 174240, -89805, -5022, 16048, false, 0, false); + _frintezzaDummy.setIsInvul(true); + _frintezzaDummy.setIsImmobilized(true); + _overheadDummy = addSpawn(29052, 174232, -88020, -5110, 16384, false, 0, false); + _overheadDummy.setIsInvul(true); + _overheadDummy.setIsImmobilized(true); + _overheadDummy.setCollisionHeight(600); + _Zone.broadcastPacket(new NpcInfo(_overheadDummy, null)); + _portraitDummy1 = addSpawn(29052, 172450, -87890, -5100, 16048, false, 0, false); + _portraitDummy1.setIsImmobilized(true); + _portraitDummy1.setIsInvul(true); + _portraitDummy3 = addSpawn(29052, 176012, -87890, -5100, 16048, false, 0, false); + _portraitDummy3.setIsImmobilized(true); + _portraitDummy3.setIsInvul(true); + _scarletDummy = addSpawn(29053, 174232, -88020, -5110, 16384, false, 0, false); + _scarletDummy.setIsInvul(true); + _scarletDummy.setIsImmobilized(true); + startQuestTimer("stop_pc", 0, npc, null, false); + startQuestTimer("camera_2", 1000, _overheadDummy, null, false); + } + else if (event.equalsIgnoreCase("camera_2")) + { + _Zone.broadcastPacket(new SpecialCamera(_overheadDummy.getObjectId(), 0, 75, -89, 0, 100, 0, 0, 1, 0)); + startQuestTimer("camera_2b", 0, _overheadDummy, null, false); + } + else if (event.equalsIgnoreCase("camera_2b")) + { + _Zone.broadcastPacket(new SpecialCamera(_overheadDummy.getObjectId(), 0, 75, -89, 0, 100, 0, 0, 1, 0)); + startQuestTimer("camera_3", 0, _overheadDummy, null, false); + } + else if (event.equalsIgnoreCase("camera_3")) + { + _Zone.broadcastPacket(new SpecialCamera(_overheadDummy.getObjectId(), 300, 90, -10, 6500, 7000, 0, 0, 1, 0)); + frintezza = (L2GrandBossInstance) addSpawn(FRINTEZZA, 174240, -89805, -5022, 16048, false, 0, false); + GrandBossManager.getInstance().addBoss(frintezza); + frintezza.setIsImmobilized(true); + frintezza.setIsInvul(true); + frintezza.disableAllSkills(); + _Zone.updateKnownList(frintezza); + demon2 = (L2MonsterInstance) addSpawn(29051, 175876, -88713, -5100, 28205, false, 0, false); + demon2.setIsImmobilized(true); + demon2.disableAllSkills(); + _Zone.updateKnownList(demon2); + demon3 = (L2MonsterInstance) addSpawn(29051, 172608, -88702, -5100, 64817, false, 0, false); + demon3.setIsImmobilized(true); + demon3.disableAllSkills(); + _Zone.updateKnownList(demon3); + demon1 = (L2MonsterInstance) addSpawn(29050, 175833, -87165, -5100, 35048, false, 0, false); + demon1.setIsImmobilized(true); + demon1.disableAllSkills(); + _Zone.updateKnownList(demon1); + demon4 = (L2MonsterInstance) addSpawn(29050, 172634, -87165, -5100, 57730, false, 0, false); + demon4.setIsImmobilized(true); + demon4.disableAllSkills(); + _Zone.updateKnownList(demon4); + startQuestTimer("camera_4", 6500, _overheadDummy, null, false); + } + else if (event.equalsIgnoreCase("camera_4")) + { + _Zone.broadcastPacket(new SpecialCamera(_frintezzaDummy.getObjectId(), 1800, 90, 8, 6500, 7000, 0, 0, 1, 0)); + startQuestTimer("camera_5", 900, _frintezzaDummy, null, false); + } + else if (event.equalsIgnoreCase("camera_5")) + { + _Zone.broadcastPacket(new SpecialCamera(_frintezzaDummy.getObjectId(), 140, 90, 10, 2500, 4500, 0, 0, 1, 0)); + startQuestTimer("camera_5b", 4000, _frintezzaDummy, null, false); + } + else if (event.equalsIgnoreCase("camera_5b")) + { + _Zone.broadcastPacket(new SpecialCamera(frintezza.getObjectId(), 40, 75, -10, 0, 1000, 0, 0, 1, 0)); + startQuestTimer("camera_6", 0, frintezza, null, false); + } + else if (event.equalsIgnoreCase("camera_6")) + { + _Zone.broadcastPacket(new SpecialCamera(frintezza.getObjectId(), 40, 75, -10, 0, 12000, 0, 0, 1, 0)); + startQuestTimer("camera_7", 1350, frintezza, null, false); + } + else if (event.equalsIgnoreCase("camera_7")) + { + _Zone.broadcastPacket(new SocialAction(frintezza, 2)); + startQuestTimer("camera_8", 7000, frintezza, null, false); + } + else if (event.equalsIgnoreCase("camera_8")) + { + startQuestTimer("camera_9", 1000, frintezza, null, false); + _frintezzaDummy.deleteMe(); + _frintezzaDummy = null; + } + else if (event.equalsIgnoreCase("camera_9")) + { + _Zone.broadcastPacket(new SocialAction(demon2, 1)); + _Zone.broadcastPacket(new SocialAction(demon3, 1)); + startQuestTimer("camera_9b", 400, frintezza, null, false); + } + else if (event.equalsIgnoreCase("camera_9b")) + { + _Zone.broadcastPacket(new SocialAction(demon1, 1)); + _Zone.broadcastPacket(new SocialAction(demon4, 1)); + for (L2Character pc : _Zone.getCharactersInside()) + { + if (pc instanceof L2PcInstance) + if (pc.getX() < 174232) + pc.broadcastPacket(new SpecialCamera(_portraitDummy1.getObjectId(), 1000, 118, 0, 0, 1000, 0, 0, 1, 0)); + else + pc.broadcastPacket(new SpecialCamera(_portraitDummy3.getObjectId(), 1000, 62, 0, 0, 1000, 0, 0, 1, 0)); + } + startQuestTimer("camera_9c", 0, frintezza, null, false); + } + else if (event.equalsIgnoreCase("camera_9c")) + { + for (L2Character pc : _Zone.getCharactersInside()) + { + if (pc instanceof L2PcInstance) + if (pc.getX() < 174232) + pc.broadcastPacket(new SpecialCamera(_portraitDummy1.getObjectId(), 1000, 118, 0, 0, 10000, 0, 0, 1, 0)); + else + pc.broadcastPacket(new SpecialCamera(_portraitDummy3.getObjectId(), 1000, 62, 0, 0, 10000, 0, 0, 1, 0)); + } + startQuestTimer("camera_10", 2000, frintezza, null, false); + } + else if (event.equalsIgnoreCase("camera_10")) + { + _Zone.broadcastPacket(new SpecialCamera(frintezza.getObjectId(), 240, 90, 0, 0, 1000, 0, 0, 1, 0)); + startQuestTimer("camera_11", 0, frintezza, null, false); + } + else if (event.equalsIgnoreCase("camera_11")) + { + _Zone.broadcastPacket(new SpecialCamera(frintezza.getObjectId(), 240, 90, 25, 5500, 10000, 0, 0, 1, 0)); + _Zone.broadcastPacket(new SocialAction(frintezza, 3)); + _portraitDummy1.deleteMe(); + _portraitDummy3.deleteMe(); + _portraitDummy1 = null; + _portraitDummy3 = null; + startQuestTimer("camera_12", 4500, frintezza, null, false); + } + else if (event.equalsIgnoreCase("camera_12")) + { + _Zone.broadcastPacket(new SpecialCamera(frintezza.getObjectId(), 100, 195, 35, 0, 10000, 0, 0, 1, 0)); + startQuestTimer("camera_13", 700, frintezza, null, false); + } + else if (event.equalsIgnoreCase("camera_13")) + { + _Zone.broadcastPacket(new SpecialCamera(frintezza.getObjectId(), 100, 195, 35, 0, 10000, 0, 0, 1, 0)); + startQuestTimer("camera_14", 1300, frintezza, null, false); + } + else if (event.equalsIgnoreCase("camera_14")) + { + _Zone.broadcastPacket(new SpecialCamera(frintezza.getObjectId(), 120, 180, 45, 1500, 10000, 0, 0, 1, 0)); + _Zone.broadcastPacket(new MagicSkillUse(frintezza, frintezza, 5006, 1, 34000, 0)); + startQuestTimer("camera_16", 1500, frintezza, null, false); + } + else if (event.equalsIgnoreCase("camera_16")) + { + _Zone.broadcastPacket(new SpecialCamera(frintezza.getObjectId(), 520, 135, 45, 8000, 10000, 0, 0, 1, 0)); + startQuestTimer("camera_17", 7500, frintezza, null, false); + } + else if (event.equalsIgnoreCase("camera_17")) + { + _Zone.broadcastPacket(new SpecialCamera(frintezza.getObjectId(), 1500, 110, 25, 10000, 13000, 0, 0, 1, 0)); + startQuestTimer("camera_18", 9500, frintezza, null, false); + } + else if (event.equalsIgnoreCase("camera_18")) + { + _Zone.broadcastPacket(new SpecialCamera(_overheadDummy.getObjectId(), 930, 160, -20, 0, 1000, 0, 0, 1, 0)); + startQuestTimer("camera_18b", 0, _overheadDummy, null, false); + } + else if (event.equalsIgnoreCase("camera_18b")) + { + _Zone.broadcastPacket(new SpecialCamera(_overheadDummy.getObjectId(), 600, 180, -25, 0, 10000, 0, 0, 1, 0)); + _Zone.broadcastPacket(new MagicSkillUse(_scarletDummy, _overheadDummy, 5004, 1, 5800, 0)); + weakScarlet = (L2GrandBossInstance) addSpawn(29046, 174232, -88020, -5110, 16384, false, 0, true); + weakScarlet.setIsInvul(true); + weakScarlet.setIsImmobilized(true); + weakScarlet.disableAllSkills(); + _Zone.updateKnownList(weakScarlet); + activeScarlet = weakScarlet; + startQuestTimer("camera_19", 2400, _scarletDummy, null, false); + startQuestTimer("camera_19b", 5000, _scarletDummy, null, false); + } + else if (event.equalsIgnoreCase("camera_19")) + weakScarlet.teleToLocation(174232, -88020, -5110, 0); + else if (event.equalsIgnoreCase("camera_19b")) + { + _Zone.broadcastPacket(new SpecialCamera(_scarletDummy.getObjectId(), 800, 180, 10, 1000, 10000, 0, 0, 1, 0)); + startQuestTimer("camera_20", 2100, _scarletDummy, null, false); + } + else if (event.equalsIgnoreCase("camera_20")) + { + _Zone.broadcastPacket(new SpecialCamera(weakScarlet.getObjectId(), 300, 60, 8, 0, 10000, 0, 0, 1, 0)); + startQuestTimer("camera_21", 2000, weakScarlet, null, false); + } + else if (event.equalsIgnoreCase("camera_21")) + { + _Zone.broadcastPacket(new SpecialCamera(weakScarlet.getObjectId(), 500, 90, 10, 3000, 5000, 0, 0, 1, 0)); + startQuestTimer("camera_22", 3000, weakScarlet, null, false); + } + else if (event.equalsIgnoreCase("camera_22")) + { + portrait2 = (L2MonsterInstance) addSpawn(29049, 175876, -88713, -5000, 28205, false, 0, false); + portrait2.setIsImmobilized(true); + portrait2.disableAllSkills(); + _Zone.updateKnownList(portrait2); + portrait3 = (L2MonsterInstance) addSpawn(29049, 172608, -88702, -5000, 64817, false, 0, false); + portrait3.setIsImmobilized(true); + portrait3.disableAllSkills(); + _Zone.updateKnownList(portrait3); + portrait1 = (L2MonsterInstance) addSpawn(29048, 175833, -87165, -5000, 35048, false, 0, false); + portrait1.setIsImmobilized(true); + portrait1.disableAllSkills(); + _Zone.updateKnownList(portrait1); + portrait4 = (L2MonsterInstance) addSpawn(29048, 172634, -87165, -5000, 57730, false, 0, false); + portrait4.setIsImmobilized(true); + portrait4.disableAllSkills(); + _Zone.updateKnownList(portrait4); + _overheadDummy.deleteMe(); + _scarletDummy.deleteMe(); + _overheadDummy = null; + _scarletDummy = null; + startQuestTimer("camera_23", 2000, weakScarlet, null, false); + startQuestTimer("start_pc", 2000, weakScarlet, null, false); + startQuestTimer("loc_check", 60000, weakScarlet, null, true); + startQuestTimer("songs_play", 10000 + Rnd.get(10000), frintezza, null, false); + startQuestTimer("skill01", 10000 + Rnd.get(10000), weakScarlet, null, false); + } + else if (event.equalsIgnoreCase("camera_23")) + { + demon1.setIsImmobilized(false); + demon2.setIsImmobilized(false); + demon3.setIsImmobilized(false); + demon4.setIsImmobilized(false); + demon1.enableAllSkills(); + demon2.enableAllSkills(); + demon3.enableAllSkills(); + demon4.enableAllSkills(); + portrait1.setIsImmobilized(false); + portrait2.setIsImmobilized(false); + portrait3.setIsImmobilized(false); + portrait4.setIsImmobilized(false); + portrait1.enableAllSkills(); + portrait2.enableAllSkills(); + portrait3.enableAllSkills(); + portrait4.enableAllSkills(); + weakScarlet.setIsInvul(false); + weakScarlet.setIsImmobilized(false); + weakScarlet.enableAllSkills(); + weakScarlet.setRunning(); + + startQuestTimer("spawn_minion", 20000, portrait1, null, false); + startQuestTimer("spawn_minion", 20000, portrait2, null, false); + startQuestTimer("spawn_minion", 20000, portrait3, null, false); + startQuestTimer("spawn_minion", 20000, portrait4, null, false); + } + else if (event.equalsIgnoreCase("stop_pc")) + { + for (L2Character cha : _Zone.getCharactersInside()) + { + cha.abortAttack(); + cha.abortCast(); + cha.disableAllSkills(); + cha.setTarget(null); + cha.stopMove(null); + cha.setIsImmobilized(true); + cha.getAI().setIntention(CtrlIntention.IDLE); + } + } + else if (event.equalsIgnoreCase("stop_npc")) + { + _Heading = npc.getHeading(); + if (_Heading < 32768) + _Angle = Math.abs(180 - (int) (_Heading / 182.044444444)); + else + _Angle = Math.abs(540 - (int) (_Heading / 182.044444444)); + } + else if (event.equalsIgnoreCase("start_pc")) + { + for (L2Character cha : _Zone.getCharactersInside()) + { + if (cha != frintezza) + { + cha.enableAllSkills(); + cha.setIsImmobilized(false); + } + } + } + else if (event.equalsIgnoreCase("start_npc")) + { + npc.setRunning(); + npc.setIsInvul(false); + } + else if (event.equalsIgnoreCase("morph_end")) + { + _OnMorph = 0; + } + else if (event.equalsIgnoreCase("morph_01")) + { + _Zone.broadcastPacket(new SpecialCamera(weakScarlet.getObjectId(), 250, _Angle, 12, 2000, 15000, 0, 0, 1, 0)); + startQuestTimer("morph_02", 3000, weakScarlet, null, false); + } + else if (event.equalsIgnoreCase("morph_02")) + { + _Zone.broadcastPacket(new SocialAction(weakScarlet, 1)); + weakScarlet.setRHandId(7903); + startQuestTimer("morph_03", 4000, weakScarlet, null, false); + } + else if (event.equalsIgnoreCase("morph_03")) + { + startQuestTimer("morph_04", 1500, weakScarlet, null, false); + } + else if (event.equalsIgnoreCase("morph_04")) + { + _Zone.broadcastPacket(new SocialAction(weakScarlet, 4)); + L2Skill skill = SkillTable.getInstance().getInfo(5017, 1); + if (skill != null) + skill.getEffects(weakScarlet, weakScarlet); + + startQuestTimer("morph_end", 6000, weakScarlet, null, false); + startQuestTimer("start_pc", 3000, weakScarlet, null, false); + startQuestTimer("start_npc", 3000, weakScarlet, null, false); + startQuestTimer("songs_play", 10000 + Rnd.get(10000), frintezza, null, false); + startQuestTimer("skill02", 10000 + Rnd.get(10000), weakScarlet, null, false); + } + else if (event.equalsIgnoreCase("morph_05a")) + { + _Zone.broadcastPacket(new SocialAction(frintezza, 4)); + } + else if (event.equalsIgnoreCase("morph_05")) + { + _Zone.broadcastPacket(new SpecialCamera(frintezza.getObjectId(), 250, 120, 15, 0, 1000, 0, 0, 1, 0)); + startQuestTimer("morph_06", 0, frintezza, null, false); + } + else if (event.equalsIgnoreCase("morph_06")) + { + _Zone.broadcastPacket(new SpecialCamera(frintezza.getObjectId(), 250, 120, 15, 0, 10000, 0, 0, 1, 0)); + + cancelQuestTimers("loc_check"); + + _Scarlet_x = weakScarlet.getX(); + _Scarlet_y = weakScarlet.getY(); + _Scarlet_z = weakScarlet.getZ(); + _Scarlet_h = weakScarlet.getHeading(); + weakScarlet.deleteMe(); + weakScarlet = null; + activeScarlet = null; + weakScarlet = (L2GrandBossInstance) addSpawn(29046, _Scarlet_x, _Scarlet_y, _Scarlet_z, _Scarlet_h, false, 0, false); + weakScarlet.setIsInvul(true); + weakScarlet.setIsImmobilized(true); + weakScarlet.disableAllSkills(); + weakScarlet.setRHandId(7903); + _Zone.updateKnownList(weakScarlet); + + startQuestTimer("morph_07", 7000, frintezza, null, false); + } + else if (event.equalsIgnoreCase("morph_07")) + { + _Zone.broadcastPacket(new MagicSkillUse(frintezza, frintezza, 5006, 1, 34000, 0)); + _Zone.broadcastPacket(new SpecialCamera(frintezza.getObjectId(), 500, 70, 15, 3000, 10000, 0, 0, 1, 0)); + startQuestTimer("morph_08", 3000, frintezza, null, false); + } + else if (event.equalsIgnoreCase("morph_08")) + { + _Zone.broadcastPacket(new SpecialCamera(frintezza.getObjectId(), 2500, 90, 12, 6000, 10000, 0, 0, 1, 0)); + startQuestTimer("morph_09", 3000, frintezza, null, false); + } + else if (event.equalsIgnoreCase("morph_09")) + { + _Zone.broadcastPacket(new SpecialCamera(weakScarlet.getObjectId(), 250, _Angle, 12, 0, 1000, 0, 0, 1, 0)); + startQuestTimer("morph_10", 0, weakScarlet, null, false); + } + else if (event.equalsIgnoreCase("morph_10")) + { + _Zone.broadcastPacket(new SpecialCamera(weakScarlet.getObjectId(), 250, _Angle, 12, 0, 10000, 0, 0, 1, 0)); + startQuestTimer("morph_11", 500, weakScarlet, null, false); + } + else if (event.equalsIgnoreCase("morph_11")) + { + weakScarlet.doDie(weakScarlet); + _Zone.broadcastPacket(new SpecialCamera(weakScarlet.getObjectId(), 450, _Angle, 14, 8000, 8000, 0, 0, 1, 0)); + + startQuestTimer("morph_12", 6250, weakScarlet, null, false); + startQuestTimer("morph_13", 7200, weakScarlet, null, false); + } + else if (event.equalsIgnoreCase("morph_12")) + { + weakScarlet.deleteMe(); + weakScarlet = null; + } + else if (event.equalsIgnoreCase("morph_13")) + { + strongScarlet = (L2GrandBossInstance) addSpawn(SCARLET2, _Scarlet_x, _Scarlet_y, _Scarlet_z, _Scarlet_h, false, 0, false); + strongScarlet.setIsInvul(true); + strongScarlet.setIsImmobilized(true); + strongScarlet.disableAllSkills(); + _Zone.updateKnownList(strongScarlet); + activeScarlet = strongScarlet; + + _Zone.broadcastPacket(new SpecialCamera(strongScarlet.getObjectId(), 450, _Angle, 12, 500, 14000, 0, 0, 1, 0)); + + startQuestTimer("morph_14", 3000, strongScarlet, null, false); + startQuestTimer("loc_check", 60000, strongScarlet, null, true); + } + else if (event.equalsIgnoreCase("morph_14")) + { + startQuestTimer("morph_15", 5100, strongScarlet, null, false); + } + else if (event.equalsIgnoreCase("morph_15")) + { + _Zone.broadcastPacket(new SocialAction(strongScarlet, 2)); + L2Skill skill = SkillTable.getInstance().getInfo(5017, 1); + if (skill != null) + skill.getEffects(strongScarlet, strongScarlet); + + startQuestTimer("morph_end", 9000, strongScarlet, null, false); + startQuestTimer("start_pc", 6000, strongScarlet, null, false); + startQuestTimer("start_npc", 6000, strongScarlet, null, false); + startQuestTimer("songs_play", 10000 + Rnd.get(10000), frintezza, null, false); + startQuestTimer("skill03", 10000 + Rnd.get(10000), strongScarlet, null, false); + } + else if (event.equalsIgnoreCase("morph_16")) + { + _Zone.broadcastPacket(new SpecialCamera(strongScarlet.getObjectId(), 300, _Angle - 180, 5, 0, 7000, 0, 0, 1, 0)); + startQuestTimer("morph_17", 0, strongScarlet, null, false); + } + else if (event.equalsIgnoreCase("morph_17")) + { + _Zone.broadcastPacket(new SpecialCamera(strongScarlet.getObjectId(), 200, _Angle, 85, 4000, 10000, 0, 0, 1, 0)); + startQuestTimer("morph_17b", 7400, frintezza, null, false); + startQuestTimer("morph_18", 7500, frintezza, null, false); + } + else if (event.equalsIgnoreCase("morph_17b")) + { + frintezza.doDie(frintezza); + } + else if (event.equalsIgnoreCase("morph_18")) + { + _Zone.broadcastPacket(new SpecialCamera(frintezza.getObjectId(), 100, 120, 5, 0, 7000, 0, 0, 1, 0)); + startQuestTimer("morph_19", 0, frintezza, null, false); + } + else if (event.equalsIgnoreCase("morph_19")) + { + _Zone.broadcastPacket(new SpecialCamera(frintezza.getObjectId(), 100, 90, 5, 5000, 15000, 0, 0, 1, 0)); + startQuestTimer("morph_20", 7000, frintezza, null, false); + startQuestTimer("spawn_cubes", 7000, frintezza, null, false); + } + else if (event.equalsIgnoreCase("morph_20")) + { + _Zone.broadcastPacket(new SpecialCamera(frintezza.getObjectId(), 900, 90, 25, 7000, 10000, 0, 0, 1, 0)); + startQuestTimer("start_pc", 7000, frintezza, null, false); + } + else if (event.equalsIgnoreCase("songs_play")) + { + if (frintezza != null && !frintezza.isDead() && _OnMorph == 0) + { + _OnSong = Rnd.get(1, 5); + if (_OnSong == 1 && _ThirdMorph == 1 && strongScarlet.getCurrentHp() < strongScarlet.getMaxHp() * 0.6 && Rnd.get(100) < 80) + { + _Zone.broadcastPacket(new MagicSkillUse(frintezza, frintezza, 5007, 1, 32000, 0)); + startQuestTimer("songs_effect", 5000, frintezza, null, false); + startQuestTimer("songs_play", 32000 + Rnd.get(10000), frintezza, null, false); + } + else if (_OnSong == 2 || _OnSong == 3) + { + _Zone.broadcastPacket(new MagicSkillUse(frintezza, frintezza, 5007, _OnSong, 32000, 0)); + startQuestTimer("songs_effect", 5000, frintezza, null, false); + startQuestTimer("songs_play", 32000 + Rnd.get(10000), frintezza, null, false); + } + else if (_OnSong == 4 && _SecondMorph == 1) + { + _Zone.broadcastPacket(new MagicSkillUse(frintezza, frintezza, 5007, 4, 31000, 0)); + startQuestTimer("songs_effect", 5000, frintezza, null, false); + startQuestTimer("songs_play", 31000 + Rnd.get(10000), frintezza, null, false); + } + else if (_OnSong == 5 && _ThirdMorph == 1 && _Abnormal == 0) + { + _Abnormal = 1; + _Zone.broadcastPacket(new MagicSkillUse(frintezza, frintezza, 5007, 5, 35000, 0)); + startQuestTimer("songs_effect", 5000, frintezza, null, false); + startQuestTimer("songs_play", 35000 + Rnd.get(10000), frintezza, null, false); + } + else + startQuestTimer("songs_play", 5000 + Rnd.get(5000), frintezza, null, false); + } + } + else if (event.equalsIgnoreCase("songs_effect")) + { + L2Skill skill = SkillTable.getInstance().getInfo(5008, _OnSong); + if (skill == null) + return null; + + if (_OnSong == 1 || _OnSong == 2 || _OnSong == 3) + { + if (frintezza != null && !frintezza.isDead() && activeScarlet != null && !activeScarlet.isDead()) + skill.getEffects(frintezza, activeScarlet); + } + else if (_OnSong == 4) + { + for (L2Character cha : _Zone.getCharactersInside()) + { + if (cha instanceof L2PcInstance && Rnd.get(100) < 80) + { + skill.getEffects(frintezza, cha); + cha.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_FEEL_S1_EFFECT).addSkillName(5008, 4)); + } + } + } + else if (_OnSong == 5) + { + for (L2Character cha : _Zone.getCharactersInside()) + { + if (cha instanceof L2PcInstance && Rnd.get(100) < 70) + { + cha.abortAttack(); + cha.abortCast(); + cha.disableAllSkills(); + cha.stopMove(null); + cha.setIsParalyzed(true); + cha.setIsImmobilized(true); + cha.getAI().setIntention(CtrlIntention.IDLE); + skill.getEffects(frintezza, cha); + cha.startAbnormalEffect(AbnormalEffect.DANCE_STUNNED); + cha.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_FEEL_S1_EFFECT).addSkillName(5008, 5)); + } + } + startQuestTimer("stop_effect", 25000, frintezza, null, false); + } + } + else if (event.equalsIgnoreCase("stop_effect")) + { + for (L2Character cha : _Zone.getCharactersInside()) + { + if (cha instanceof L2PcInstance) + { + cha.stopAbnormalEffect(AbnormalEffect.DANCE_STUNNED); + cha.stopAbnormalEffect(AbnormalEffect.FLOATING_ROOT); + cha.enableAllSkills(); + cha.setIsImmobilized(false); + cha.setIsParalyzed(false); + } + } + _Abnormal = 0; + } + else if (event.equalsIgnoreCase("attack_stop")) + { + cancelQuestTimers("skill01"); + cancelQuestTimers("skill02"); + cancelQuestTimers("skill03"); + cancelQuestTimers("songs_play"); + cancelQuestTimers("songs_effect"); + + _Zone.broadcastPacket(new MagicSkillCanceld(frintezza.getObjectId())); + } + else if (event.equalsIgnoreCase("check_hp")) + { + if (npc.isDead()) + { + _OnMorph = 1; + _Zone.broadcastPacket(new PlaySound(1, "BS01_D", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ())); + + startQuestTimer("attack_stop", 0, frintezza, null, false); + startQuestTimer("stop_pc", 0, npc, null, false); + startQuestTimer("stop_npc", 0, npc, null, false); + startQuestTimer("morph_16", 0, npc, null, false); + } + else + { + _CheckDie = _CheckDie + 10; + if (_CheckDie < 3000) + startQuestTimer("check_hp", 10, npc, null, false); + else + { + _OnCheck = 0; + _CheckDie = 0; + } + } + } + else if (event.equalsIgnoreCase("skill01")) + { + if (weakScarlet != null && !weakScarlet.isDead() && _SecondMorph == 0 && _ThirdMorph == 0 && _OnMorph == 0) + { + int i = Rnd.get(0, 1); + L2Skill skill = SkillTable.getInstance().getInfo(_skill[i][0], _skill[i][1]); + if (skill != null) + { + weakScarlet.stopMove(null); + weakScarlet.setIsCastingNow(true); + weakScarlet.doCast(skill); + } + startQuestTimer("skill01", _skill[i][2] + 5000 + Rnd.get(10000), npc, null, false); + } + } + else if (event.equalsIgnoreCase("skill02")) + { + if (weakScarlet != null && !weakScarlet.isDead() && _SecondMorph == 1 && _ThirdMorph == 0 && _OnMorph == 0) + { + int i = 0; + if (_Abnormal == 0) + i = Rnd.get(2, 5); + else + i = Rnd.get(2, 4); + + L2Skill skill = SkillTable.getInstance().getInfo(_skill[i][0], _skill[i][1]); + if (skill != null) + { + weakScarlet.stopMove(null); + weakScarlet.setIsCastingNow(true); + weakScarlet.doCast(skill); + } + startQuestTimer("skill02", _skill[i][2] + 5000 + Rnd.get(10000), npc, null, false); + + if (i == 5) + { + _Abnormal = 1; + startQuestTimer("float_effect", 4000, weakScarlet, null, false); + } + } + } + else if (event.equalsIgnoreCase("skill03")) + { + if (strongScarlet != null && !strongScarlet.isDead() && _SecondMorph == 1 && _ThirdMorph == 1 && _OnMorph == 0) + { + int i = 0; + if (_Abnormal == 0) + i = Rnd.get(6, 10); + else + i = Rnd.get(6, 9); + + L2Skill skill = SkillTable.getInstance().getInfo(_skill[i][0], _skill[i][1]); + if (skill != null) + { + strongScarlet.stopMove(null); + strongScarlet.setIsCastingNow(true); + strongScarlet.doCast(skill); + } + startQuestTimer("skill03", _skill[i][2] + 5000 + Rnd.get(10000), npc, null, false); + + if (i == 10) + { + _Abnormal = 1; + startQuestTimer("float_effect", 3000, npc, null, false); + } + } + } + else if (event.equalsIgnoreCase("float_effect")) + { + if (npc.isCastingNow()) + { + startQuestTimer("float_effect", 500, npc, null, false); + } + else + { + for (L2Character cha : _Zone.getCharactersInside()) + { + if (cha instanceof L2PcInstance) + { + if (cha.getFirstEffect(5016) != null) + { + cha.abortAttack(); + cha.abortCast(); + cha.disableAllSkills(); + cha.stopMove(null); + cha.setIsParalyzed(true); + cha.setIsImmobilized(true); + cha.getAI().setIntention(CtrlIntention.IDLE); + cha.startAbnormalEffect(AbnormalEffect.FLOATING_ROOT); + } + } + } + startQuestTimer("stop_effect", 25000, npc, null, false); + } + } + else if (event.equalsIgnoreCase("action")) + { + _Zone.broadcastPacket(new SocialAction(npc, 1)); + } + else if (event.equalsIgnoreCase("bomber")) + { + _Bomber = 0; + } + else if (event.equalsIgnoreCase("room_final")) + { + _Zone.broadcastPacket(new NpcSay(npc.getObjectId(), 1, npc.getNpcId(), "Exceeded his time limit, challenge failed!")); + _Zone.oustAllPlayers(); + + cancelQuestTimers("waiting"); + cancelQuestTimers("frintezza_despawn"); + startQuestTimer("clean", 1000, npc, null, false); + startQuestTimer("close", 1000, npc, null, false); + startQuestTimer("room1_del", 1000, npc, null, false); + startQuestTimer("room2_del", 1000, npc, null, false); + + GrandBossManager.getInstance().setBossStatus(FRINTEZZA, DORMANT); + } + else if (event.equalsIgnoreCase("frintezza_despawn")) + { + temp = (System.currentTimeMillis() - _LastAction); + if (temp > 900000) + { + _Zone.oustAllPlayers(); + + cancelQuestTimers("waiting"); + cancelQuestTimers("loc_check"); + cancelQuestTimers("room_final"); + cancelQuestTimers("spawn_minion"); + startQuestTimer("clean", 1000, npc, null, false); + startQuestTimer("close", 1000, npc, null, false); + startQuestTimer("attack_stop", 1000, npc, null, false); + startQuestTimer("room1_del", 1000, npc, null, false); + startQuestTimer("room2_del", 1000, npc, null, false); + startQuestTimer("room3_del", 1000, npc, null, false); + startQuestTimer("minions_despawn", 1000, npc, null, false); + + GrandBossManager.getInstance().setBossStatus(FRINTEZZA, DORMANT); + + cancelQuestTimers("frintezza_despawn"); + } + } + else if (event.equalsIgnoreCase("minions_despawn")) + { + for (int i = 0; i < Minions.size(); i++) + { + L2Attackable mob = Minions.get(i); + if (mob != null) + mob.decayMe(); + } + Minions.clear(); + } + else if (event.equalsIgnoreCase("spawn_minion")) + { + if (npc != null && !npc.isDead() && frintezza != null && !frintezza.isDead()) + { + L2Npc mob = addSpawn(npc.getNpcId() + 2, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), false, 0, false); + ((L2Attackable) mob).setIsRaidMinion(true); + Minions.add((L2Attackable) mob); + startQuestTimer("action", 200, mob, null, false); + startQuestTimer("spawn_minion", 18000, npc, null, false); + } + } + else if (event.equalsIgnoreCase("spawn_cubes")) + { + addSpawn(CUBE, 174232, -88020, -5114, 16384, false, 900000, false); + } + else if (event.equalsIgnoreCase("frintezza_unlock")) + { + GrandBossManager.getInstance().setBossStatus(FRINTEZZA, DORMANT); + } + else if (event.equalsIgnoreCase("remove_players")) + { + _Zone.oustAllPlayers(); + } + + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onTalk(L2Npc npc, L2PcInstance player) + { + if (npc.getNpcId() == CUBE) + { + int x = 150037 + Rnd.get(500); + int y = -57720 + Rnd.get(500); + player.teleToLocation(x, y, -2976, 0); + return null; + } + + String htmltext = ""; + if (GrandBossManager.getInstance().getBossStatus(FRINTEZZA) == DEAD) + { + htmltext = "<html><body>There is nothing beyond the Magic Force Field. Come back later.<br>(You may not enter because Frintezza is not inside the Imperial Tomb.)</body></html>"; + } + else if (GrandBossManager.getInstance().getBossStatus(FRINTEZZA) == DORMANT) + { + boolean party_check_success = true; + + if (!player.isGM()) // GMs can enter without a party. + { + if ((!player.isInParty() || !player.getParty().isLeader(player)) || (player.getParty().getCommandChannel() == null) || (player.getParty().getCommandChannel().getChannelLeader() != player)) + { + htmltext = "<html><body>No reaction. Contact must be initiated by the Command Channel Leader.</body></html>"; + party_check_success = false; + } + else if (player.getParty().getCommandChannel().getPartys().size() < Config.FRINTEZZA_MIN_PARTIES || player.getParty().getCommandChannel().getPartys().size() > Config.FRINTEZZA_MAX_PARTIES) + { + htmltext = "<html><body>Your command channel needs to have at least " + Config.FRINTEZZA_MIN_PARTIES + " parties and a maximum of " + Config.FRINTEZZA_MAX_PARTIES + ".</body></html>"; + party_check_success = false; + } + } + + if (party_check_success) + { + if (player.getInventory().getItemByItemId(8073) == null) + { + htmltext = "<html><body>You dont have required item.</body></html>"; + } + else + { + player.destroyItemByItemId("Quest", 8073, 1, player, true); + GrandBossManager.getInstance().setBossStatus(FRINTEZZA, WAITING); + + startQuestTimer("close", 0, npc, null, false); + startQuestTimer("room1_spawn", 5000, npc, null, false); + startQuestTimer("room_final", 2100000, null, null, false); + startQuestTimer("frintezza_despawn", 60000, null, null, true); + + _LastAction = System.currentTimeMillis(); + + if (player.isGM()) + { + if (player.getParty() != null) + { + L2CommandChannel CC = player.getParty().getCommandChannel(); + + if (CC != null) + { // teleport all parties into CC reb12 + for (L2Party party : CC.getPartys()) + { + if (party == null) + continue; + + synchronized (_PlayersInside) + { + + for (L2PcInstance member : party.getPartyMembers()) + { + if (member == null || member.getLevel() < 74) + continue; + if (!member.isInsideRadius(npc, 700, false, false)) + continue; + if (_PlayersInside.size() > 45) + { + member.sendMessage("The number of challenges have been full, so can not enter."); + break; + } + _PlayersInside.add(member); + _Zone.allowPlayerEntry(member, 300); + member.teleToLocation(_invadeLoc[_LocCycle][0] + Rnd.get(50), _invadeLoc[_LocCycle][1] + Rnd.get(50), _invadeLoc[_LocCycle][2], 0); + } + if (_PlayersInside.size() > 45) + break; + } + _LocCycle++; + if (_LocCycle >= 6) + _LocCycle = 1; + } + } + else + { // teleport just actual party reb12 + L2Party party = player.getParty(); + + for (L2PcInstance member : party.getPartyMembers()) + { + if (member == null || member.getLevel() < 74) + continue; + if (!member.isInsideRadius(npc, 700, false, false)) + continue; + + synchronized (_PlayersInside) + { + if (_PlayersInside.size() > 45) + { + member.sendMessage("The number of challenges have been full, so can not enter."); + break; + } + _PlayersInside.add(member); + } + + _Zone.allowPlayerEntry(member, 300); + member.teleToLocation(_invadeLoc[_LocCycle][0] + Rnd.get(50), _invadeLoc[_LocCycle][1] + Rnd.get(50), _invadeLoc[_LocCycle][2], 0); + } + _LocCycle++; + if (_LocCycle >= 6) + _LocCycle = 1; + } + } + else + { // teleport just player reb12 + if (player.isInsideRadius(npc, 700, false, false)) + { + synchronized (_PlayersInside) + { + _PlayersInside.add(player); + + } + player.teleToLocation(_invadeLoc[_LocCycle][0] + Rnd.get(50), _invadeLoc[_LocCycle][1] + Rnd.get(50), _invadeLoc[_LocCycle][2], 0); + } + } + } + else + { + L2CommandChannel CC = player.getParty().getCommandChannel(); + + for (L2Party party : CC.getPartys()) + { + if (party == null) + continue; + + synchronized (_PlayersInside) + { + for (L2PcInstance member : party.getPartyMembers()) + { + if (member == null || member.getLevel() < 74) + continue; + if (!member.isInsideRadius(npc, 700, false, false)) + continue; + if (_PlayersInside.size() > 45) + { + member.sendMessage("The number of challenges have been full, so can not enter."); + break; + } + _PlayersInside.add(member); + _Zone.allowPlayerEntry(member, 300); + member.teleToLocation(_invadeLoc[_LocCycle][0] + Rnd.get(50), _invadeLoc[_LocCycle][1] + Rnd.get(50), _invadeLoc[_LocCycle][2], 0); + } + if (_PlayersInside.size() > 45) + break; + } + _LocCycle++; + if (_LocCycle >= 6) + _LocCycle = 1; + } + } + } + } + } + else + htmltext = "<html><body>Someone else is already inside the Magic Force Field. Try again later.</body></html>"; + + return htmltext; + } + + @Override + public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isPet, L2Skill skill) + { + _LastAction = System.currentTimeMillis(); + if (npc.getNpcId() == FRINTEZZA) + { + npc.setCurrentHpMp(npc.getMaxHp(), 0); + return null; + } + if (npc.getNpcId() == SCARLET1 && _SecondMorph == 0 && _ThirdMorph == 0 && _OnMorph == 0 && npc.getCurrentHp() < npc.getMaxHp() * 0.75 && GrandBossManager.getInstance().getBossStatus(FRINTEZZA) == FIGHTING) + { + startQuestTimer("attack_stop", 0, frintezza, null, false); + + _SecondMorph = 1; + _OnMorph = 1; + + startQuestTimer("stop_pc", 1000, npc, null, false); + startQuestTimer("stop_npc", 1000, npc, null, false); + startQuestTimer("morph_01", 1100, npc, null, false); + } + else if (npc.getNpcId() == SCARLET1 && _SecondMorph == 1 && _ThirdMorph == 0 && _OnMorph == 0 && npc.getCurrentHp() < npc.getMaxHp() * 0.5 && GrandBossManager.getInstance().getBossStatus(FRINTEZZA) == FIGHTING) + { + startQuestTimer("attack_stop", 0, frintezza, null, false); + + _ThirdMorph = 1; + _OnMorph = 1; + + startQuestTimer("stop_pc", 2000, npc, null, false); + startQuestTimer("stop_npc", 2000, npc, null, false); + startQuestTimer("morph_05a", 2000, npc, null, false); + startQuestTimer("morph_05", 2100, npc, null, false); + } + else if (npc.getNpcId() == SCARLET2 && _SecondMorph == 1 && _ThirdMorph == 1 && _OnCheck == 0 && damage >= npc.getCurrentHp() && GrandBossManager.getInstance().getBossStatus(FRINTEZZA) == FIGHTING) + { + _OnCheck = 1; + startQuestTimer("check_hp", 0, npc, null, false); + } + else if ((npc.getNpcId() == 29050 || npc.getNpcId() == 29051) && _Bomber == 0) + { + if (npc.getCurrentHp() < npc.getMaxHp() * 0.1) + { + if (Rnd.get(100) < 30) + { + _Bomber = 1; + startQuestTimer("bomber", 3000, npc, null, false); + + L2Skill sk = SkillTable.getInstance().getInfo(5011, 1); + if (sk != null) + { + npc.doCast(sk); + } + } + } + } + + return super.onAttack(npc, attacker, damage, isPet, skill); + } + + @Override + public String onKill(L2Npc npc, L2PcInstance killer, boolean isPet) + { + if (npc.getNpcId() == SCARLET2) + { + _Zone.broadcastPacket(new PlaySound(1, "BS01_D", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ())); + + startQuestTimer("stop_pc", 0, null, null, false); + startQuestTimer("stop_npc", 0, npc, null, false); + startQuestTimer("morph_16", 0, npc, null, false); + + GrandBossManager.getInstance().setBossStatus(FRINTEZZA, DEAD); + long respawnTime = (long) Config.SPAWN_INTERVAL_FRINTEZZA + Rnd.get(-Config.RANDOM_SPAWN_TIME_FRINTEZZA, Config.RANDOM_SPAWN_TIME_FRINTEZZA); + respawnTime *= 3600000; + + cancelQuestTimers("spawn_minion"); + cancelQuestTimers("frintezza_despawn"); + startQuestTimer("close", 0, null, null, false); + startQuestTimer("rooms_del", 0, npc, null, false); + startQuestTimer("minions_despawn", 0, null, null, false); + startQuestTimer("remove_players", 900000, null, null, false); + startQuestTimer("frintezza_unlock", respawnTime, null, null, false); + + StatsSet info = GrandBossManager.getInstance().getStatsSet(FRINTEZZA); + info.set("respawn_time", System.currentTimeMillis() + respawnTime); + GrandBossManager.getInstance().setStatsSet(FRINTEZZA, info); + } + else if (npc.getNpcId() == 18328) + { + _KillHallAlarmDevice++; + if (_KillHallAlarmDevice == 3) // open walls reb12 + { + for (int i = 25150051; i <= 25150058; i++) + DoorTable.getInstance().getDoor(i).openMe(); + } + else if (_KillHallAlarmDevice == 4) + { + startQuestTimer("room1_del", 100, npc, null, false); + startQuestTimer("room2_spawn", 100, npc, null, false); + DoorTable.getInstance().getDoor(25150042).openMe(); + DoorTable.getInstance().getDoor(25150043).openMe(); + } + } + else if (npc.getNpcId() == 18339) + { + _KillDarkChoirPlayer++; + if (_KillDarkChoirPlayer == 2) + { + DoorTable.getInstance().getDoor(25150042).closeMe(); + DoorTable.getInstance().getDoor(25150043).closeMe(); + + for (int i = 25150061; i <= 25150070; i++) + DoorTable.getInstance().getDoor(i).openMe(); + + startQuestTimer("room2_spawn2", 1000, npc, null, false); + } + } + else if (npc.getNpcId() == 18334) + { + _KillDarkChoirCaptain++; + if (_KillDarkChoirCaptain == 8) + { + startQuestTimer("room2_del", 100, npc, null, false); + + DoorTable.getInstance().getDoor(25150045).openMe(); + DoorTable.getInstance().getDoor(25150046).openMe(); + + startQuestTimer("waiting", Config.WAIT_TIME_FRINTEZZA, npc, null, false); + cancelQuestTimers("room_final"); + } + } + + return super.onKill(npc, killer, isPet); + } +} \ No newline at end of file Index: java/net/sf/l2j/gameserver/model/zone/type/L2BossZone.java =================================================================== --- java/net/sf/l2j/gameserver/model/zone/type/L2BossZone.java (revision 90) +++ java/net/sf/l2j/gameserver/model/zone/type/L2BossZone.java (working copy) @@ -3,12 +3,12 @@ * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. - * + * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. - * + * * You should have received a copy of the GNU General Public License along with * this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -27,6 +27,7 @@ import net.sf.l2j.gameserver.datatables.MapRegionTable.TeleportWhereType; import net.sf.l2j.gameserver.model.actor.L2Attackable; import net.sf.l2j.gameserver.model.actor.L2Character; +import net.sf.l2j.gameserver.model.actor.L2Npc; import net.sf.l2j.gameserver.model.actor.L2Playable; import net.sf.l2j.gameserver.model.actor.L2Summon; import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance; @@ -304,6 +305,18 @@ _playerAllowed.clear(); } + public void updateKnownList(L2Npc npc) + { + if (_characterList == null || _characterList.isEmpty()) + return; + + for (L2Character character : _characterList) + { + if (character instanceof L2PcInstance) + npc.getKnownList().addKnownObject(character); + } + } + @Override public void onDieInside(L2Character character) { aCis_DataPack ### Eclipse Workspace Patch 1.0 #P aCis_datapack Index: data/xml/scripts.xml =================================================================== --- data/xml/scripts.xml (revision 90) +++ data/xml/scripts.xml (working copy) @@ -372,7 +372,7 @@ <!-- <script path="scripts.ai.individual.Benom"/> --> <script path="scripts.ai.individual.Core"/> <script path="scripts.ai.individual.DrChaos"/> -<!-- <script path="scripts.ai.individual.Frintezza"/> --> + <script path="scripts.ai.individual.Frintezza"/> <script path="scripts.ai.individual.Gordon"/> <!-- <script path="scripts.ai.individual.IceFairySirra"/> --> <script path="scripts.ai.individual.Orfen"/> Index: data/xml/zones/BossZone.xml =================================================================== --- data/xml/zones/BossZone.xml (revision 90) +++ data/xml/zones/BossZone.xml (working copy) @@ -98,11 +98,11 @@ <node X="229176" Y="-98508" /> <node X="196880" Y="-98498" /> </zone> - <zone id="110011" type="BossZone" shape="Cuboid" minZ="-9205" maxZ="-8065"><!-- Frintezza Boss TODO --> - <stat name="InvadeTime" val="1800000" /> - <node X="-89840" Y="-139384" /> - <node X="-85732" Y="-155311" /> - </zone> + <zone id="110011" type="BossZone" shape="Cuboid" minZ="-5140" maxZ="-4000"><!-- Frintezza Boss --> + <stat name="InvadeTime" val="1800000" /> + <node X="172176" Y="-74106" /> + <node X="176284" Y="-90033" /> + </zone> <zone id="110012" type="BossZone" shape="NPoly" minZ="-5947" maxZ="-5547"><!-- Queen Ant Boss TODO --> <stat name="EnabledByDefault" val="false" /> <node X="-21490" Y="178613" /> Index: data/html/default/32011.htm =================================================================== --- data/html/default/32011.htm (revision 90) +++ data/html/default/32011.htm (working copy) @@ -1,7 +1,7 @@ <html><body> I feel an invisible barrier... Some sort of Magic Force Field has been put in place...<br> ...? The guide of the Imperial mausoleum seems to have something to say.<br><br> -<a action="bypass -h npc_%objectId%_Quest FinalEmperialTomb">Enter the Magic Force Field</a><br> +<a action="bypass -h npc_%objectId%_Quest Frintezza">Enter the Magic Force Field</a><br> <a action="bypass -h npc_%objectId%_Chat 1">Listen to Imperial Tomb Guide</a><br> <a action="bypass -h npc_%objectId%_Quest">Quest</a> </body></html> \ No newline at end of file Index: data/html/teleporter/29061.htm =================================================================== --- data/html/teleporter/29061.htm (revision 0) +++ data/html/teleporter/29061.htm (working copy) @@ -0,0 +1,3 @@ +<html><body>Teleportation Cubic:<br> +<a action="bypass -h npc_%objectId%_Quest Frintezza">Exit the Last Imperial Tomb</a><br> +</body></html> \ No newline at end of file
-
[Acis] Re-Designed Retail Npc's
l2jkain replied to protoftw's topic in Server Development Discussion [L2J]
download ? -
Hello, I'm creating a code for users to change passwords for a .change command, but I'm not able to get an html for the code. I've taken a part of a npc and help me code it down /* * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.l2j.gameserver.handler.voicedcommandhandlers; import java.security.MessageDigest; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Base64; import java.util.StringTokenizer; import java.util.logging.Logger; import net.sf.l2j.commons.concurrent.ThreadPool; import net.sf.l2j.L2DatabaseFactory; import net.sf.l2j.gameserver.handler.IVoicedCommandHandler; import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance; /** * @author williams * */ public class ChangePassword implements IVoicedCommandHandler { private static final Logger _log = Logger.getLogger(ChangePassword.class.getName()); private static final String[] _voicedCommands = { "change" }; @Override public boolean useVoicedCommand(String command, L2PcInstance activeChar, String target) { if(command.equalsIgnoreCase("change") && target != null) { StringTokenizer st = new StringTokenizer(target); st.nextToken(); String curPass = null; String newPass = null; String repPass = null; try { if (st.hasMoreTokens()) { curPass = st.nextToken(); newPass = st.nextToken(); repPass = st.nextToken(); } else { activeChar.sendMessage("Please fill in all the blanks before requesting for a password change."); return false; } changePassword(curPass, newPass, repPass, activeChar); } catch (StringIndexOutOfBoundsException e) { e.printStackTrace(); } } return false; } @SuppressWarnings("null") public static boolean changePassword(String currPass, String newPass, String repeatNewPass, L2PcInstance activeChar) { if (newPass.length() < 3) { activeChar.sendMessage("The new password is too short!"); return false; } if (newPass.length() > 16) { activeChar.sendMessage("The new password is too long!"); return false; } if (!newPass.equals(repeatNewPass)) { activeChar.sendMessage("Repeated password doesn't match the new password."); return false; } Connection con = null; String password = null; try { MessageDigest md = MessageDigest.getInstance("SHA"); byte[] raw = currPass.getBytes("UTF-8"); raw = md.digest(raw); String currPassEncoded = Base64.getEncoder().encodeToString(raw); con = L2DatabaseFactory.getInstance().getConnection(); PreparedStatement statement = con.prepareStatement("SELECT password FROM accounts WHERE login=?"); statement.setString(1, activeChar.getAccountName()); ResultSet rset = statement.executeQuery(); while (rset.next()) { password = rset.getString("password"); } rset.close(); statement.close(); byte[] password2 = null; if (currPassEncoded.equals(password)) { password2 = newPass.getBytes("UTF-8"); password2 = md.digest(password2); PreparedStatement statement2 = con.prepareStatement("UPDATE accounts SET password=? WHERE login=?"); statement2.setString(1, Base64.getEncoder().encodeToString(password2)); statement2.setString(2, activeChar.getAccountName()); statement2.executeUpdate(); statement2.close(); activeChar.sendMessage("Your password has been changed successfully! For security reasons, You will be disconnected in 3 Seconds. Please login again!"); try { ThreadPool.schedule(() -> activeChar.logout(false), 3000); } catch (Exception e) { { e.printStackTrace(); } } activeChar.broadcastUserInfo(); activeChar.decayMe(); activeChar.spawnMe(); } else { activeChar.sendMessage("The current password you've inserted is incorrect! Please try again!"); return password2 != null; } } catch (Exception e) { _log.warning("could not update the password of account: " + activeChar.getAccountName()); e.printStackTrace(); } finally { if (con != null) try { con.close(); con = null; } catch (final Throwable e){} } return true; } @Override public String[] getVoicedCommandList() { return _voicedCommands; } }
-
Help Dropar Custom Item Of All Mobs L2Jacis
l2jkain posted a question in Request Server Development Help [L2J]
Hello, this code is in a quest, but it has a delay for the player to win the item, how do I take this delay and the player to win the item so kill the mob equal adena ??? ,>,>,>,> -
Hello, I'm creating a patch with my codes but I do not know what that means @@ -3.5 +3,5 @@ Someone please explain me right?
-
I was adapting the code of the engine but I have this error and I do not know how to fix somebody know how it is? He used Javolution I changed to imports from here http://imgur.com/a/gZoEQ
-
Help Baium Attack Angel
l2jkain replied to tazerman2's question in Request Server Development Help [L2J]
The Baium of the 12jacis 350 is in the same way, the angels attack the baium and take damage -
Hi, I'm looking for the updates from acis 301 to 340 someone has and can you provide me? I know the verdicts below the 350 are free Does anyone help me?
-
How would this be for l2jacis? activeChar.setSkillCast(ThreadPool.schedule(ef, teleportTimer)); activeChar.setSkillCastEndTime(10+GameTimeTaskManager.getGameTicks()+teleportTimer/GameTimeController.MILLIS_IN_TICK);
-
Help Help In Adapting Status Limiter For Acis 354
l2jkain posted a question in Request Server Development Help [L2J]
Hello, I'm looking for an update on triskell but I found a very important mod a status limiter wanted help to improve the code following what it has in the code works 100% but I lose many lines that have on the acis and I do not know What these lines represent Like this here Return (int) calcStat (Stats.POWER_ATTACK_SPEED, base, null, null); I do not know how to code Int val = super.getPAtkSpd (); If ((val> Config.MAX_PATK_SPEED) && (! GetActiveChar (). IsGM ())) { Return Config.MAX_PATK_SPEED; } Return val; Codigo : ### Eclipse Workspace Patch 1.0 #P aCis_gameserver Index: java/net/sf/l2j/gameserver/model/actor/stat/CharStat.java =================================================================== --- java/net/sf/l2j/gameserver/model/actor/stat/CharStat.java (revision 104) +++ java/net/sf/l2j/gameserver/model/actor/stat/CharStat.java (working copy) @@ -153,10 +153,20 @@ * @param skill * @return the Critical Hit rate (base+modifier) of the L2Character. */ - public int getCriticalHit(L2Character target, L2Skill skill) - { - return Math.min((int) calcStat(Stats.CRITICAL_RATE, _activeChar.getTemplate().getBaseCritRate(), target, skill), 500); - } + public int getCriticalHit(L2Character target, L2Skill skill) + { + if (_activeChar == null) + { + return 1; + } + + int criticalHit = Math.min((int)calcStat(Stats.CRITICAL_RATE, _activeChar.getTemplate().getBaseCritRate(), target, skill), 500); + + if (criticalHit > Config.MAX_PCRIT_RATE) { + criticalHit = Config.MAX_PCRIT_RATE; + } + return criticalHit; + } /** * @param target @@ -163,19 +173,39 @@ * @param skill * @return the Magic Critical Hit rate (base+modifier) of the L2Character. */ - public final int getMCriticalHit(L2Character target, L2Skill skill) - { - return (int) calcStat(Stats.MCRITICAL_RATE, 8, target, skill); - } + public final int getMCriticalHit(L2Character target, L2Skill skill) + { + if (_activeChar == null) + { + return 1; + } + + double mrate = calcStat(Stats.MCRITICAL_RATE, 8.0D, target, skill); + + if (mrate > Config.MAX_MCRIT_RATE) { + mrate = Config.MAX_MCRIT_RATE; + } + return (int)mrate; + } /** * @param target * @return the Attack Evasion rate (base+modifier) of the L2Character. */ - public int getEvasionRate(L2Character target) - { - return (int) calcStat(Stats.EVASION_RATE, 0, target, null); - } + public int getEvasionRate(L2Character target) + { + if (_activeChar == null) + { + return 1; + } + int val = (int)Math.round(calcStat(Stats.EVASION_RATE, 0.0D, target, null)); + + if ((val > Config.MAX_EVASION) && (!_activeChar.isGM())) + { + val = Config.MAX_EVASION; + } + return val; + } /** * @return the Accuracy (base+modifier) of the L2Character in function of the Weapon Expertise Penalty. @@ -182,7 +212,17 @@ */ public int getAccuracy() { - return (int) calcStat(Stats.ACCURACY_COMBAT, 0, null, null); + if (_activeChar == null) + { + return 1; + } + int val = (int)Math.round(calcStat(Stats.ACCURACY_COMBAT, 0.0D, null, null)); + + if ((val > Config.MAX_ACCURACY) && (!_activeChar.isGM())) + { + val = Config.MAX_ACCURACY; + } + return val; } public int getMaxHp() Index: config/aCis.properties =================================================================== --- config/aCis.properties (revision 104) +++ config/aCis.properties (working copy) @@ -82,3 +82,40 @@ # Players can see in the upper chat who dies in pvp and pk # Default : False AnnounceKillPLayers = true + +#============================================================= +# Limits +#============================================================= + +# Run speed modifier. Example: Setting this to 5 will +# give players +5 to their running speed. +# Default: 0 +RunSpeedBoost = 0 + +# Maximum character running speed. +# Default: 250 +MaxRunSpeed = 250 + +# Maximum character Physical Critical Rate. (10 = 1%) +# Default: 500 +MaxPCritRate = 500 + +# Maximum character Magic Critical Rate. (10 = 1%) +# Default: 200 +MaxMCritRate = 200 + +# Maximum character Attack Speed. +# Default: 1500 +MaxPAtkSpeed = 1500 + +# Maximum character Cast Speed. +# Default: 1999 +MaxMAtkSpeed = 1999 + +# Maximum character Evasion. +# Default: 250 +MaxEvasion = 250 + +# Maxmum character Accuracy +# Default: 300 +MaxAccuracy = 300 Index: java/net/sf/l2j/Config.java =================================================================== --- java/net/sf/l2j/Config.java (revision 104) +++ java/net/sf/l2j/Config.java (working copy) @@ -401,6 +401,15 @@ public static boolean ENABLE_MODIFY_SKILL_DURATION; public static Map<Integer, Integer> SKILL_DURATION_LIST; public static boolean ANNOUNCE_KILL; + /** Limits */ + public static int RUN_SPD_BOOST; + public static int MAX_RUN_SPEED; + public static int MAX_PCRIT_RATE; + public static int MAX_MCRIT_RATE; + public static int MAX_PATK_SPEED; + public static int MAX_MATK_SPEED; + public static int MAX_EVASION; + public static int MAX_ACCURACY; // -------------------------------------------------- // Players @@ -947,8 +956,15 @@ } } ANNOUNCE_KILL = aCis.getProperty("AnnounceKillPLayers", false); + RUN_SPD_BOOST = aCis.getProperty("RunSpeedBoost", 0); + MAX_RUN_SPEED = aCis.getProperty("MaxRunSpeed", 250); + MAX_PCRIT_RATE = aCis.getProperty("MaxPCritRate", 500); + MAX_MCRIT_RATE = aCis.getProperty("MaxMCritRate", 200); + MAX_PATK_SPEED = aCis.getProperty("MaxPAtkSpeed", 1500); + MAX_MATK_SPEED = aCis.getProperty("MaxMAtkSpeed", 1999); + MAX_EVASION = aCis.getProperty("MaxEvasion", 250); + MAX_ACCURACY = aCis.getProperty("MaxAccuracy", 300); - // NPCs / Monsters ExProperties npcs = load(NPCS_FILE); CHAMPION_FREQUENCY = npcs.getProperty("ChampionFrequency", 0); Index: java/net/sf/l2j/gameserver/model/actor/stat/PcStat.java =================================================================== --- java/net/sf/l2j/gameserver/model/actor/stat/PcStat.java (revision 104) +++ java/net/sf/l2j/gameserver/model/actor/stat/PcStat.java (working copy) @@ -330,46 +330,61 @@ else val = super.getRunSpeed(); - final int penalty = getActiveChar().getExpertiseArmorPenalty(); - if (penalty > 0) - val *= Math.pow(0.84, penalty); - - return val; + val += Config.RUN_SPD_BOOST; + + if ((val > Config.MAX_RUN_SPEED) && (!getActiveChar().isGM())) + { + return Config.MAX_RUN_SPEED; + } + return val; } @Override - public int getMAtkSpd() - { - int val = super.getMAtkSpd(); - - final int penalty = getActiveChar().getExpertiseArmorPenalty(); - if (penalty > 0) - val *= Math.pow(0.84, penalty); - - return val; - } + public int getMAtkSpd() + { + int val = super.getMAtkSpd(); + + if ((val > Config.MAX_MATK_SPEED) && (!getActiveChar().isGM())) + { + return Config.MAX_MATK_SPEED; + } + return val; + } + @Override + public int getPAtkSpd() + { + int val = super.getPAtkSpd(); + + if ((val > Config.MAX_PATK_SPEED) && (!getActiveChar().isGM())) + { + return Config.MAX_PATK_SPEED; + } + return val; + } + @Override - public int getEvasionRate(L2Character target) - { - int val = super.getEvasionRate(target); - - final int penalty = getActiveChar().getExpertiseArmorPenalty(); - if (penalty > 0) - val -= (2 * penalty); - - return val; - } + public int getEvasionRate(L2Character target) + { + int val = super.getEvasionRate(target); + + if ((val > Config.MAX_EVASION) && (!getActiveChar().isGM())) + { + return Config.MAX_EVASION; + } + return val; + } @Override public int getAccuracy() { - int val = super.getAccuracy(); - - if (getActiveChar().getExpertiseWeaponPenalty()) - val -= 20; - - return val; + int val = super.getAccuracy(); + + if ((val > Config.MAX_ACCURACY) && (!getActiveChar().isGM())) + { + return Config.MAX_ACCURACY; + } + return val; } @Override -
### Eclipse Workspace Patch 1.0 #P L2JaCis350 Index: java/net/sf/l2j/gameserver/network/clientpackets/RequestWithdrawPledge.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestWithdrawPledge.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestWithdrawPledge.java (working copy) @@ -36,7 +38,7 @@ if (activeChar == null) return; + if (activeChar.isSubmitingPin()) + { + activeChar.sendMessage("Digite a senha do personagem."); + return; + } + final L2Clan clan = activeChar.getClan(); if (clan == null) { Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/TradeRequest.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/TradeRequest.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/TradeRequest.java (working copy) @@ -53,6 +53,12 @@ return; } + if (player.isSubmitingPin() || ((L2PcInstance) target).isSubmitingPin()) + { + player.sendMessage("Digite a senha do personagem."); + return; + } + if (target.isInOlympiadMode() || player.isInOlympiadMode()) { player.sendMessage("You or your target can't trade during Olympiad."); Index: aCis_datapack_350/data/html/passkey/setup.htm =================================================================== --- aCis_datapack_350/data/html/passkey/setup.htm (revision 0) +++ aCis_datapack_350/data/html/passkey/setup.htm (working copy) @@ -0,0 +1,27 @@ +<html> +<title>Personal Password Manager</title> +<body> +<center> +<img src="L2Font.mini_logo-k" width=250 height=90><br> +<img src="L2UI_CH3.herotower_deco" width=256 height=32><br> +</center> +<br> +Hello, stranger! What i do?! Protect you from hacking. +I'll help you set a password for the character. +This way if someone theft your account no one can make any action with the character. +It is not recommended to enter as password the same as you use in the account. +The security question is required if you lose or forget your password. +<center> +<table> +<tr><td><font color="732cde">Enter the password: </font></td><td><edit var="pass1" width=70 height=10></td></tr><br> +<tr><td><font color="732cde">Repeat password: </font></td><td><edit var="pass2" width=70 height=10></td></tr><br> +<tr><td><font color="732cde">Enter a security question: </font></td><td><edit var="question" width=70 height=10></td></tr><br> +<tr><td><font color="732cde">Enter the answer: </font></td><td><edit var="answer" width=70 height=10></td></tr><br> +</table> +<br> +<button value="Confirm" action="bypass -h pkset ] $pass1 ] $pass2 ] $question ] $answer" width=75 height=21 back="L2UI_ch3.Btn1_normalOn" fore="L2UI_ch3.Btn1_normal"> +<br> +<img src="L2UI_CH3.herotower_deco" width=256 height=32> +</center> +</body> +</html> \ No newline at end of file Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestPrivateStoreSell.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestPrivateStoreSell.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestPrivateStoreSell.java (working copy) @@ -64,6 +64,12 @@ if (player == null) return; + if (player.isSubmitingPin()) + { + player.sendMessage("Digite a senha do personagem."); + return; + } + if (_items == null) return; Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java (working copy) @@ -14,10 +14,19 @@ */ package net.sf.l2j.gameserver.network.clientpackets; +import java.security.MessageDigest; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.StringTokenizer; import java.util.logging.Level; import net.sf.l2j.Config; +import net.sf.l2j.Base64; +import net.sf.l2j.gameserver.cache.HtmCache; +import net.sf.l2j.L2DatabaseFactory; +import net.sf.l2j.gameserver.model.actor.L2Character; import net.sf.l2j.gameserver.communitybbs.CommunityBoard; import net.sf.l2j.gameserver.datatables.AdminCommandAccessRights; import net.sf.l2j.gameserver.handler.AdminCommandHandler; @@ -181,6 +190,220 @@ final int arenaId = Integer.parseInt(_command.substring(12).trim()); activeChar.enterOlympiadObserverMode(arenaId); } + else if (_command.equalsIgnoreCase("pkrecovery")) + { + String htmContent = HtmCache.getInstance().getHtm("data/html/passkey/recovery.htm"); + NpcHtmlMessage html = new NpcHtmlMessage(1); + html.setHtml(htmContent); + html.replace("%question%", getPassKeyQuestion(activeChar)); + activeChar.sendPacket(html); + html = null; + } + else if (_command.startsWith("pkset")) + { + StringTokenizer st = new StringTokenizer(_command, "]"); + if (st.countTokens() != 5) + { + activeChar.sendMessage("You have not entered all the data!"); + String htmContent = HtmCache.getInstance().getHtm("data/html/passkey/setup.htm"); + NpcHtmlMessage html = new NpcHtmlMessage(1); + html.setHtml(htmContent); + activeChar.sendPacket(html); + html = null; + return; + } + String newCommand = st.nextToken(); + String pass1 = st.nextToken(); + pass1 = pass1.substring(1, pass1.length() - 1); + String pass2 = st.nextToken(); + pass2 = pass2.substring(1, pass2.length() - 1); + String question = st.nextToken(); + question = question.substring(1, question.length() - 1); + String answer = st.nextToken(); + answer = answer.substring(1, answer.length()); + if (pass1 == null || pass2 == null || question == null || answer == null) + { + activeChar.sendMessage("Input error"); + String htmContent = HtmCache.getInstance().getHtm("data/html/passkey/setup.htm"); + NpcHtmlMessage html = new NpcHtmlMessage(1); + html.setHtml(htmContent); + activeChar.sendPacket(html); + html = null; + return; + } + + if (!pass1.equals(pass2)) + { + activeChar.sendMessage("You entered different passwords"); + activeChar.sendMessage("pass1 = " + pass1); + activeChar.sendMessage("pass2 = " + pass2); + activeChar.sendMessage("Question = " + question); + activeChar.sendMessage("answer = " + answer); + String htmContent = HtmCache.getInstance().getHtm("data/html/passkey/setup.htm"); + NpcHtmlMessage html = new NpcHtmlMessage(1); + html.setHtml(htmContent); + activeChar.sendPacket(html); + html = null; + return; + } + insertPassKeyInformation(activeChar, pass1, question, answer); + String htmContent = HtmCache.getInstance().getHtm("data/html/passkey/login.htm"); + NpcHtmlMessage html = new NpcHtmlMessage(1); + html.setHtml(htmContent); + activeChar.sendPacket(html); + html = null; + } + else if (_command.startsWith("pklogin")) + { + StringTokenizer st = new StringTokenizer(_command, " "); + if (st.countTokens() != 2) + { + activeChar.sendMessage("You make a mistake when entering the password!"); + String htmContent = HtmCache.getInstance().getHtm("data/html/passkey/login.htm"); + NpcHtmlMessage html = new NpcHtmlMessage(1); + html.setHtml(htmContent); + activeChar.sendPacket(html); + html = null; + return; + } + String newCommand = st.nextToken(); + String pass = st.nextToken(); + Connection con = null; + String query = "SELECT passkey FROM passkey WHERE obj_Id = ?"; + String pwdindb = "error"; + try + { + con = L2DatabaseFactory.getInstance().getConnection(); + PreparedStatement ps = con.prepareStatement(query); + ps.setInt(1, activeChar.getObjectId()); + ResultSet rs = ps.executeQuery(); + + while (rs.next()) + pwdindb = rs.getString(1); + rs.close(); + ps.close(); + ps = null; + rs = null; + } + catch (Exception e) + { + e.printStackTrace(); + } + finally + { + try + { + con.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + con = null; + } + if (pwdindb.equals(encodePass(pass))) + { + activeChar.setIsParalyzed(false); + activeChar.setIsSubmitingPin(false); + activeChar.setIsInvul(false); + } + else + { + activeChar.sendMessage("You have not entered the correct password"); + String htmContent = HtmCache.getInstance().getHtm("data/html/passkey/login.htm"); + NpcHtmlMessage html = new NpcHtmlMessage(1); + html.setHtml(htmContent); + activeChar.sendPacket(html); + html = null; + return; + } + } + else if (_command.startsWith("pkrec")) + { + StringTokenizer st = new StringTokenizer(_command, " "); + if (st.countTokens() != 4) + { + activeChar.sendMessage("You make a mistake when entering data!"); + String htmContent = HtmCache.getInstance().getHtm("data/html/passkey/recovery.htm"); + NpcHtmlMessage html = new NpcHtmlMessage(1); + html.setHtml(htmContent); + html.replace("%question%", getPassKeyQuestion(activeChar)); + activeChar.sendPacket(html); + html = null; + return; + } + String newCommand = st.nextToken(); + String answer = st.nextToken(); + String pass1 = st.nextToken(); + String pass2 = st.nextToken(); + if (!pass1.equals(pass2)) + { + activeChar.sendMessage("You entered different passwords"); + String htmContent = HtmCache.getInstance().getHtm("data/html/passkey/recovery.htm"); + NpcHtmlMessage html = new NpcHtmlMessage(1); + html.setHtml(htmContent); + html.replace("%question%", getPassKeyQuestion(activeChar)); + activeChar.sendPacket(html); + html = null; + return; + } + Connection con = null; + String query = "SELECT answer FROM passkey WHERE obj_Id = ?"; + String anwindb = "error"; + try + { + con = L2DatabaseFactory.getInstance().getConnection(); + PreparedStatement ps = con.prepareStatement(query); + ps.setInt(1, activeChar.getObjectId()); + ResultSet rs = ps.executeQuery(); + + while (rs.next()) + anwindb = rs.getString(1); + + rs.close(); + ps.close(); + ps = null; + rs = null; + } + catch (Exception e) + { + e.printStackTrace(); + } + finally + { + try + { + con.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + con = null; + } + + if (anwindb.equals(answer)) + { + updPassKey(activeChar, pass1); + activeChar.sendMessage("You have successfully changed your password."); + String htmContent = HtmCache.getInstance().getHtm("data/html/passkey/login.htm"); + NpcHtmlMessage html = new NpcHtmlMessage(1); + html.setHtml(htmContent); + activeChar.sendPacket(html); + html = null; + } + else + { + activeChar.sendMessage("You entered the wrong answer to your question"); + String htmContent = HtmCache.getInstance().getHtm("data/html/passkey/recovery.htm"); + NpcHtmlMessage html = new NpcHtmlMessage(1); + html.setHtml(htmContent); + html.replace("%question%", getPassKeyQuestion(activeChar)); + activeChar.sendPacket(html); + html = null; + return; + } + } } catch (Exception e) { @@ -188,6 +411,173 @@ } } + private void updPassKey(L2PcInstance player, String pass) + { + Connection con = null; + String query = "UPDATE passkey SET passkey = ? WHERE obj_Id = ?"; + try + { + con = L2DatabaseFactory.getInstance().getConnection(); + PreparedStatement st = con.prepareStatement(query); + st.setString(1, encodePass(pass)); + st.setInt(2, player.getObjectId()); + st.executeUpdate(); + st.close(); + st = null; + } + catch (Exception e) + { + e.printStackTrace(); + } + finally + { + try + { + con.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + con = null; + } + } + + private String encodePass(String password) + { + String pass = "error"; + try + { + MessageDigest md = MessageDigest.getInstance("SHA"); + byte[] raw = password.getBytes("UTF-8"); + byte[] hash = md.digest(raw); + pass = Base64.encodeBytes(hash); + } + catch (Exception e) + { + e.printStackTrace(); + } + return pass; + } + + private void insertPassKeyInformation(L2PcInstance player, String pass, String question, String answer) + { + Connection con = null; + String query = "INSERT INTO passkey (obj_Id, passkey, question, answer) VALUES (?,?,?,?)"; + try + { + con = L2DatabaseFactory.getInstance().getConnection(); + PreparedStatement st = con.prepareStatement(query); + st.setInt(1, player.getObjectId()); + st.setString(2, encodePass(pass)); + st.setString(3, question); + st.setString(4, answer); + st.execute(); + st.close(); + st = null; + } + catch (Exception e) + { + e.printStackTrace(); + } + finally + { + try + { + con.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + con = null; + } + } + + private String getPassKeyQuestion(L2PcInstance player) + { + Connection con = null; + String query = "SELECT question FROM passkey WHERE obj_Id = ?"; + String question = "error"; + try + { + con = L2DatabaseFactory.getInstance().getConnection(); + PreparedStatement st = con.prepareStatement(query); + st.setInt(1, player.getObjectId()); + ResultSet rs = st.executeQuery(); + + while (rs.next()) + question = rs.getString(1); + + rs.close(); + st.close(); + st = null; + rs = null; + } + catch (Exception e) + { + e.printStackTrace(); + } + finally + { + try + { + con.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + con = null; + } + + return question; + } + + public static boolean getPassKeyEnable(L2PcInstance player) + { + Connection con = null; + String query = "SELECT COUNT(*) FROM passkey WHERE obj_Id = ?"; + int count = 0; + + try + { + con = L2DatabaseFactory.getInstance().getConnection(); + PreparedStatement st = con.prepareStatement(query); + st.setInt(1, player.getObjectId()); + ResultSet rs = st.executeQuery(); + + while (rs.next()) + count = rs.getInt(1); + + rs.close(); + st.close(); + st = null; + rs = null; + } + catch (Exception e) + { + e.printStackTrace(); + } + finally + { + try + { + con.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + con = null; + } + + if (count == 1) + return true; + else + return false; + } + private static void playerHelp(L2PcInstance activeChar, String path) { if (path.indexOf("..") != -1) Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestJoinAlly.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestJoinAlly.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestJoinAlly.java (working copy) @@ -38,6 +38,12 @@ if (activeChar == null) return; + if (activeChar.isSubmitingPin()) + { + activeChar.sendMessage("Digite a senha do personagem."); + return; + } + final L2Clan clan = activeChar.getClan(); if (clan == null) { Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestCrystallizeItem.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestCrystallizeItem.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestCrystallizeItem.java (working copy) @@ -46,6 +46,12 @@ if (activeChar == null) return; + if (activeChar.isSubmitingPin()) + { + activeChar.sendMessage("Digite a senha do personagem."); + return; + } + if (_count <= 0) { Util.handleIllegalPlayerAction(activeChar, "[RequestCrystallizeItem] " + activeChar.getName() + "tried to crystallize an object but count was inferior to 0", IllegalPlayerAction.PUNISH_KICK); Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestPrivateStoreBuy.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestPrivateStoreBuy.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestPrivateStoreBuy.java (working copy) @@ -66,6 +66,12 @@ if (player == null) return; + if (player.isSubmitingPin()) + { + player.sendMessage("Digite a senha do personagem."); + return; + } + if (_items == null) return; Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestFriendInvite.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestFriendInvite.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestFriendInvite.java (working copy) @@ -38,6 +38,12 @@ if (activeChar == null) return; + if (activeChar.isSubmitingPin()) + { + activeChar.sendMessage("Digite a senha do personagem."); + return; + } + final L2PcInstance friend = L2World.getInstance().getPlayer(_name); // can't use friend invite for locating invisible characters Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestEnchantItem.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestEnchantItem.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestEnchantItem.java (working copy) @@ -52,6 +52,12 @@ if (activeChar == null || _objectId == 0) return; + if (activeChar.isSubmitingPin()) + { + activeChar.sendMessage("Digite a senha do personagem."); + return; + } + if (!activeChar.isOnline() || getClient().isDetached()) { activeChar.setActiveEnchantItem(null); Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestSellItem.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestSellItem.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestSellItem.java (working copy) @@ -72,6 +72,12 @@ if (player == null) return; + if (player.isSubmitingPin()) + { + player.sendMessage("Digite a senha do personagem."); + return; + } + // Alt game - Karma punishment if (!Config.KARMA_PLAYER_CAN_SHOP && player.getKarma() > 0) return; Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/Say2.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/Say2.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/Say2.java (working copy) @@ -132,6 +132,12 @@ if (activeChar == null) return; + if (activeChar.isSubmitingPin()) + { + activeChar.sendMessage("Digite a senha do personagem."); + return; + } + if (_type < 0 || _type >= CHAT_NAMES.length) { _log.warning("Say2: Invalid type: " + _type + " Player : " + activeChar.getName() + " text: " + _text); Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/SendWarehouseWithdrawList.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/SendWarehouseWithdrawList.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/SendWarehouseWithdrawList.java (working copy) @@ -68,6 +68,12 @@ if (player == null) return; + if (player.isSubmitingPin()) + { + player.sendMessage("Digite a senha do personagem."); + return; + } + if (player.isProcessingTransaction()) { player.sendPacket(SystemMessageId.ALREADY_TRADING); Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/UseItem.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/UseItem.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/UseItem.java (working copy) @@ -78,6 +78,12 @@ if (activeChar == null) return; + if (activeChar.isSubmitingPin()) + { + activeChar.sendMessage("Digite a senha do personagem."); + return; + } + if (activeChar.isInStoreMode()) { activeChar.sendPacket(SystemMessageId.ITEMS_UNAVAILABLE_FOR_STORE_MANUFACTURE); Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestStartPledgeWar.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestStartPledgeWar.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestStartPledgeWar.java (working copy) @@ -42,6 +42,12 @@ if (attackerClan == null) return; + if (player.isSubmitingPin()) + { + player.sendMessage("Digite a senha do personagem."); + return; + } + if ((player.getClanPrivileges() & L2Clan.CP_CL_PLEDGE_WAR) != L2Clan.CP_CL_PLEDGE_WAR) { player.sendPacket(SystemMessageId.YOU_ARE_NOT_AUTHORIZED_TO_DO_THAT); Index: aCis_datapack_350/data/html/passkey/login.htm =================================================================== --- aCis_datapack_350/data/html/passkey/login.htm (revision 0) +++ aCis_datapack_350/data/html/passkey/login.htm (working copy) @@ -0,0 +1,21 @@ +<html> +<title>Personal Password Manager</title> +<body> +<center> +<img src="L2Font.mini_logo-k" width=250 height=90><br> +<img src="L2UI_CH3.herotower_deco" width=256 height=32><br> +</center> +<br> +Hello, stranger! To continue playing, you have to provide your password. +<center> +<table> +<tr><td><font color="732cde">Enter password: </font></td><td><edit var="pass" width=70 height=10></td></tr><br> +</table> +<br> +<button value="Confirm" action="bypass -h pklogin $pass" width=75 height=21 back="L2UI_ch3.Btn1_normalOn" fore="L2UI_ch3.Btn1_normal"> +<button value="Forgot password" action="bypass -h pkrecovery" width=75 height=21 back="L2UI_ch3.Btn1_normalOn" fore="L2UI_ch3.Btn1_normal"> +<br> +<img src="L2UI_CH3.herotower_deco" width=256 height=32> +</center> +</body> +</html> \ No newline at end of file Index: aCis_datapack_350/data/html/passkey/recovery.htm =================================================================== --- aCis_datapack_350/data/html/passkey/recovery.htm (revision 0) +++ aCis_datapack_350/data/html/passkey/recovery.htm (working copy) @@ -0,0 +1,26 @@ +<html> +<title>Personal Password Manager</title> +<body> +<center> +<img src="L2Font.mini_logo-k" width=250 height=90><br> +<img src="L2UI_CH3.herotower_deco" width=256 height=32><br> +</center> +<br> +Hello, stranger! You forgot your password? Okay, I'll help you recover it!<br> +But you have to type the answer to the question, that you've set during registration.<br> + +<center><font color="LEVEL">%question%</font></center> +<br> +<center> +<table> +<tr><td><font color="732cde">Enter the answer: </font></td><td><edit var="answer" width=70 height=10></td></tr><br> +<tr><td><font color="732cde">Enter the new password: </font></td><td><edit var="pass1" width=70 height=10></td></tr><br> +<tr><td><font color="732cde">Confirm new password: </font></td><td><edit var="pass2" width=70 height=10></td></tr><br> +</table> +<br> +<button value="Confirm" action="bypass -h pkrec $answer $pass1 $pass2" width=75 height=21 back="L2UI_ch3.Btn1_normalOn" fore="L2UI_ch3.Btn1_normal"> +<br> +<img src="L2UI_CH3.herotower_deco" width=256 height=32> +</center> +</body> +</html> \ No newline at end of file Index: aCis_datapack_350/data/html/passkey/setup.htm =================================================================== --- aCis_datapack_350/data/html/passkey/setup.htm (revision 0) +++ aCis_datapack_350/data/html/passkey/setup.htm (working copy) @@ -0,0 +1,27 @@ +<html> +<title>Personal Password Manager</title> +<body> +<center> +<img src="L2Font.mini_logo-k" width=250 height=90><br> +<img src="L2UI_CH3.herotower_deco" width=256 height=32><br> +</center> +<br> +Hello, stranger! What i do?! Protect you from hacking. +I'll help you set a password for the character. +This way if someone theft your account no one can make any action with the character. +It is not recommended to enter as password the same as you use in the account. +The security question is required if you lose or forget your password. +<center> +<table> +<tr><td><font color="732cde">Enter the password: </font></td><td><edit var="pass1" width=70 height=10></td></tr><br> +<tr><td><font color="732cde">Repeat password: </font></td><td><edit var="pass2" width=70 height=10></td></tr><br> +<tr><td><font color="732cde">Enter a security question: </font></td><td><edit var="question" width=70 height=10></td></tr><br> +<tr><td><font color="732cde">Enter the answer: </font></td><td><edit var="answer" width=70 height=10></td></tr><br> +</table> +<br> +<button value="Confirm" action="bypass -h pkset ] $pass1 ] $pass2 ] $question ] $answer" width=75 height=21 back="L2UI_ch3.Btn1_normalOn" fore="L2UI_ch3.Btn1_normal"> +<br> +<img src="L2UI_CH3.herotower_deco" width=256 height=32> +</center> +</body> +</html> \ No newline at end of file Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestDropItem.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestDropItem.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestDropItem.java (working copy) @@ -54,6 +54,12 @@ if (activeChar == null || activeChar.isDead()) return; + if (activeChar.isSubmitingPin()) + { + activeChar.sendMessage("Digite a senha do personagem."); + return; + } + final ItemInstance item = activeChar.getInventory().getItemByObjectId(_objectId); if (item == null || _count == 0 || !activeChar.validateItemManipulation(_objectId) || (!Config.ALLOW_DISCARDITEM && !activeChar.isGM()) || !item.isDropable()) { Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestExEnchantSkill.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestExEnchantSkill.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestExEnchantSkill.java (working copy) @@ -56,6 +56,12 @@ if (activeChar == null) return; + if (activeChar.isSubmitingPin()) + { + activeChar.sendMessage("Digite a senha do personagem."); + return; + } + if (activeChar.getClassId().level() < 3 || activeChar.getLevel() < 76) return; Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestShowMiniMap.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestShowMiniMap.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestShowMiniMap.java (working copy) @@ -31,6 +31,12 @@ if (activeChar == null) return; + if (activeChar.isSubmitingPin()) + { + activeChar.sendMessage("Digite a senha do personagem."); + return; + } + activeChar.sendPacket(ShowMiniMap.REGULAR_MAP); } } \ No newline at end of file Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/model/actor/L2Character.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/model/actor/L2Character.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/model/actor/L2Character.java (working copy) @@ -5473,6 +5473,17 @@ return _champion; } + public boolean _isSubmitingPin; + + public final void setIsSubmitingPin(boolean value) + { + _isSubmitingPin = value; + } + public boolean isSubmitingPin() + { + return _isSubmitingPin; + } + /** * Send system message about damage.<BR> * <BR> Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java (working copy) @@ -60,6 +60,7 @@ import net.sf.l2j.gameserver.scripting.QuestState; import net.sf.l2j.gameserver.scripting.ScriptManager; import net.sf.l2j.gameserver.taskmanager.GameTimeTaskManager; +import net.sf.l2j.gameserver.cache.HtmCache; public class EnterWorld extends L2GameClientPacket { @@ -80,6 +81,26 @@ return; } + activeChar.setIsParalyzed(true); + activeChar.setIsSubmitingPin(true); + activeChar.setIsInvul(true); + if (RequestBypassToServer.getPassKeyEnable(activeChar)) + { + String htmContent = HtmCache.getInstance().getHtm("data/html/passkey/login.htm"); + NpcHtmlMessage html = new NpcHtmlMessage(1); + html.setHtml(htmContent); + activeChar.sendPacket(html); + html = null; + } + else + { + String htmContent = HtmCache.getInstance().getHtm("data/html/passkey/setup.htm"); + NpcHtmlMessage html = new NpcHtmlMessage(1); + html.setHtml(htmContent); + activeChar.sendPacket(html); + html = null; + } + if (activeChar.isGM()) { if (Config.GM_STARTUP_INVULNERABLE && AdminCommandAccessRights.getInstance().hasAccess("admin_invul", activeChar.getAccessLevel())) Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestUnEquipItem.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestUnEquipItem.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestUnEquipItem.java (working copy) @@ -45,6 +45,12 @@ if (item == null) return; + if (activeChar.isSubmitingPin()) + { + activeChar.sendMessage("Digite a senha do personagem."); + return; + } + // Prevent of unequiping a cursed weapon if (_slot == Item.SLOT_LR_HAND && activeChar.isCursedWeaponEquipped()) return; @@ -60,7 +66,7 @@ return; ItemInstance[] unequipped = activeChar.getInventory().unEquipItemInBodySlotAndRecord(_slot); - + // show the update in the inventory InventoryUpdate iu = new InventoryUpdate(); for (ItemInstance itm : unequipped) Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestMagicSkillUse.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestMagicSkillUse.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestMagicSkillUse.java (working copy) @@ -46,6 +46,12 @@ if (activeChar == null) return; + if (activeChar.isSubmitingPin()) + { + activeChar.sendMessage("Digite a senha do personagem."); + return; + } + // Get the level of the used skill final int level = activeChar.getSkillLevel(_magicId); if (level <= 0) Index: aCis_datapack_350/tools/database_installer.bat =================================================================== --- aCis_datapack_350/tools/database_installer.bat (revision 13) +++ aCis_datapack_350/tools/database_installer.bat (working copy) @@ -112,6 +112,7 @@ %mysqlPath% -h %gshost% -u %gsuser% --password=%gspass% -D %gsdb% < ../sql/seven_signs_status.sql %mysqlPath% -h %gshost% -u %gsuser% --password=%gspass% -D %gsdb% < ../sql/siege_clans.sql %mysqlPath% -h %gshost% -u %gsuser% --password=%gspass% -D %gsdb% < ../sql/topic.sql +%mysqlPath% -h %gshost% -u %gsuser% --password=%gspass% -D %gsdb% < ../sql/passskey.sql echo Done. echo. Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestSendFriendMsg.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestSendFriendMsg.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestSendFriendMsg.java (working copy) @@ -52,6 +52,12 @@ if (activeChar == null) return; + if (activeChar.isSubmitingPin()) + { + activeChar.sendMessage("Digite a senha do personagem."); + return; + } + final L2PcInstance targetPlayer = L2World.getInstance().getPlayer(_reciever); if (targetPlayer == null || !targetPlayer.getFriendList().contains(activeChar.getObjectId())) { Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/TradeDone.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/TradeDone.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/TradeDone.java (working copy) @@ -37,6 +37,12 @@ if (player == null) return; + if (player.isSubmitingPin()) + { + player.sendMessage("Digite a senha do personagem."); + return; + } + final TradeList trade = player.getActiveTradeList(); if (trade == null) return; Index: aCis_datapack_350/data/html/passkey/recovery.htm =================================================================== --- aCis_datapack_350/data/html/passkey/recovery.htm (revision 0) +++ aCis_datapack_350/data/html/passkey/recovery.htm (working copy) @@ -0,0 +1,26 @@ +<html> +<title>Personal Password Manager</title> +<body> +<center> +<img src="L2Font.mini_logo-k" width=250 height=90><br> +<img src="L2UI_CH3.herotower_deco" width=256 height=32><br> +</center> +<br> +Hello, stranger! You forgot your password? Okay, I'll help you recover it!<br> +But you have to type the answer to the question, that you've set during registration.<br> + +<center><font color="LEVEL">%question%</font></center> +<br> +<center> +<table> +<tr><td><font color="732cde">Enter the answer: </font></td><td><edit var="answer" width=70 height=10></td></tr><br> +<tr><td><font color="732cde">Enter the new password: </font></td><td><edit var="pass1" width=70 height=10></td></tr><br> +<tr><td><font color="732cde">Confirm new password: </font></td><td><edit var="pass2" width=70 height=10></td></tr><br> +</table> +<br> +<button value="Confirm" action="bypass -h pkrec $answer $pass1 $pass2" width=75 height=21 back="L2UI_ch3.Btn1_normalOn" fore="L2UI_ch3.Btn1_normal"> +<br> +<img src="L2UI_CH3.herotower_deco" width=256 height=32> +</center> +</body> +</html> \ No newline at end of file Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/SetPrivateStoreListBuy.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/SetPrivateStoreListBuy.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/SetPrivateStoreListBuy.java (working copy) @@ -62,6 +62,12 @@ if (player == null) return; + if (player.isSubmitingPin()) + { + player.sendMessage("Digite a senha do personagem."); + return; + } + if (_items == null) { player.setPrivateStoreType(PrivateStoreType.NONE); Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestFriendDel.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestFriendDel.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestFriendDel.java (working copy) @@ -43,6 +43,12 @@ if (activeChar == null) return; + if (activeChar.isSubmitingPin()) + { + activeChar.sendMessage("Digite a senha do personagem."); + return; + } + int id = CharNameTable.getInstance().getIdByName(_name); if (id == -1 || !activeChar.getFriendList().contains(id)) Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestSetAllyCrest.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestSetAllyCrest.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestSetAllyCrest.java (working copy) @@ -46,6 +46,12 @@ if (activeChar == null) return; + if (activeChar.isSubmitingPin()) + { + activeChar.sendMessage("Digite a senha do personagem."); + return; + } + if (_length < 0) { activeChar.sendMessage("File transfer error."); Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestPetition.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestPetition.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestPetition.java (working copy) @@ -51,6 +51,12 @@ if (activeChar == null) return; + if (activeChar.isSubmitingPin()) + { + activeChar.sendMessage("Digite a senha do personagem."); + return; + } + if (!GmListTable.getInstance().isGmOnline(false)) { activeChar.sendPacket(SystemMessageId.NO_GM_PROVIDING_SERVICE_NOW); Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestStopPledgeWar.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestStopPledgeWar.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestStopPledgeWar.java (working copy) @@ -35,11 +35,17 @@ final L2PcInstance player = getClient().getActiveChar(); if (player == null) return; - + final L2Clan playerClan = player.getClan(); if (playerClan == null) return; + if (player.isSubmitingPin()) + { + player.sendMessage("Digite a senha do personagem."); + return; + } + final L2Clan clan = ClanTable.getInstance().getClanByName(_pledgeName); if (clan == null) return; Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/util/StringUtil.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/util/StringUtil.java (revision 0) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/util/StringUtil.java (working copy) @@ -0,0 +1,297 @@ +/* + * $Header$ + * + * $Author: fordfrog $ $Date$ $Revision$ $Log$ + * + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.sf.l2j.gameserver.util; + +/** + * String utilities optimized for the best performance. + * + * <h1>How to Use It</h1> <h2>concat() or append()</h2> If concatenating strings + * in single call, use StringUtil.concat(), otherwise use StringUtil.append() + * and its variants. <h2>Minimum Calls</h2> Bad: + * + * <pre> + * final StringBuilder sbString = new StringBuilder(); + * StringUtil.append(sbString, "text 1", String.valueOf(npcId)); + * StringUtil.append("text 2"); + * </pre> + * + * Good: + * + * <pre> + * final StringBuilder sbString = new StringBuilder(); + * StringUtil.append(sbString, "text 1", String.valueOf(npcId), "text 2"); + * </pre> + * + * Why?<br/> + * Because the less calls you do, the less memory re-allocations have to be done + * so the whole text fits into the memory and less array copy tasks has to be + * performed. So if using less calls, less memory is used and string + * concatenation is faster. <h2>Size Hints for Loops</h2> Bad: + * + * <pre> + * final StringBuilder sbString = new StringBuilder(); + * StringUtil.append(sbString, "header start", someText, "header end"); + * for (int i = 0; i < 50; i++) + * { + * StringUtil.append(sbString, "text 1", stringArray, "text 2"); + * } + * </pre> + * + * Good: + * + * <pre> + * final StringBuilder sbString = StringUtil.startAppend(1300, "header start", someText, "header end"); + * for (int i = 0; i < 50; i++) + * { + * StringUtil.append(sbString, "text 1", stringArray, "text 2"); + * } + * </pre> + * + * Why?<br/> + * When using StringUtil.append(), memory is only allocated to fit in the + * strings in method argument. So on each loop new memory for the string has to + * be allocated and old string has to be copied to the new string. With size + * hint, even if the size hint is above the needed memory, memory is saved + * because new memory has not to be allocated on each cycle. Also it is much + * faster if no string copy tasks has to be performed. So if concatenating + * strings in a loop, count approximately the size and set it as the hint for + * the string builder size. It's better to make the size hint little bit larger + * rather than smaller.<br/> + * In case there is no text appended before the cycle, just use <code>new + * StringBuilder(1300)</code>. <h2>Concatenation and Constants</h2> Bad: + * + * <pre> + * StringUtil.concat("text 1 ", "text 2", String.valueOf(npcId)); + * </pre> + * + * Good: + * + * <pre> + * StringUtil.concat("text 1 " + "text 2", String.valueOf(npcId)); + * </pre> + * + * or + * + * <pre> + * StringUtil.concat("text 1 text 2", String.valueOf(npcId)); + * </pre> + * + * Why?<br/> + * It saves some cycles when determining size of memory that needs to be + * allocated because less strings are passed to concat() method. But do not use + * + for concatenation of non-constant strings, that degrades performance and + * makes extra memory allocations needed. <h2>Concatenation and Constant + * Variables</h2> Bad: + * + * <pre> + * String glue = "some glue"; + * StringUtil.concat("text 1", glue, "text 2", glue, String.valueOf(npcId)); + * </pre> + * + * Good: + * + * <pre> + * final String glue = "some glue"; + * StringUtil.concat("text 1" + glue + "text2" + glue, String.valueOf(npcId)); + * </pre> + * + * Why? Because when using <code>final</code> keyword, the <code>glue</code> is + * marked as constant string and compiler treats it as a constant string so it + * is able to create string "text1some gluetext2some glue" during the + * compilation. But this only works in case the value is known at compilation + * time, so this cannot be used for cases like + * <code>final String objectIdString = + * String.valueOf(getObjectId)</code>. <h2>StringBuilder Reuse</h2> Bad: + * + * <pre> + * final StringBuilder sbString1 = new StringBuilder(); + * StringUtil.append(sbString1, "text 1", String.valueOf(npcId), "text 2"); + * ... // output of sbString1, it is no more needed + * final StringBuilder sbString2 = new StringBuilder(); + * StringUtil.append(sbString2, "text 3", String.valueOf(npcId), "text 4"); + * </pre> + * + * Good: + * + * <pre> + * final StringBuilder sbString = new StringBuilder(); + * StringUtil.append(sbString, "text 1", String.valueOf(npcId), "text 2"); + * ... // output of sbString, it is no more needed + * sbString.setLength(0); + * StringUtil.append(sbString, "text 3", String.valueOf(npcId), "text 4"); + * </pre> + * + * Why?</br> In first case, new memory has to be allocated for the second + * string. In second case already allocated memory is reused, but only in case + * the new string is not longer than the previously allocated string. Anyway, + * the second way is better because the string either fits in the memory and + * some memory is saved, or it does not fit in the memory, and in that case it + * works as in the first case. <h2>Primitives to Strings</h2> To convert + * primitives to string, use String.valueOf(). <h2>How much faster is it?</h2> + * Here are some results of my tests. Count is number of strings concatenated. + * Don't take the numbers as 100% true as the numbers are affected by other + * programs running on my computer at the same time. Anyway, from the results it + * is obvious that using StringBuilder with predefined size is the fastest (and + * also most memory efficient) solution. It is about 5 times faster when + * concatenating 7 strings, compared to TextBuilder. Also, with more strings + * concatenated, the difference between StringBuilder and TextBuilder gets + * larger. In code, there are many cases, where there are concatenated 50+ + * strings so the time saving is even greater. + * + * <pre> + * Count: 2 + * TextBuilder: 1893 + * TextBuilder with size: 1703 + * String: 1033 + * StringBuilder: 993 + * StringBuilder with size: 1024 + * Count: 3 + * TextBuilder: 1973 + * TextBuilder with size: 1872 + * String: 2583 + * StringBuilder: 1633 + * StringBuilder with size: 1156 + * Count: 4 + * TextBuilder: 2188 + * TextBuilder with size: 2229 + * String: 4207 + * StringBuilder: 1816 + * StringBuilder with size: 1444 + * Count: 5 + * TextBuilder: 9185 + * TextBuilder with size: 9464 + * String: 6937 + * StringBuilder: 2745 + * StringBuilder with size: 1882 + * Count: 6 + * TextBuilder: 9785 + * TextBuilder with size: 10082 + * String: 9471 + * StringBuilder: 2889 + * StringBuilder with size: 1857 + * Count: 7 + * TextBuilder: 10169 + * TextBuilder with size: 10528 + * String: 12746 + * StringBuilder: 3081 + * StringBuilder with size: 2139 + * </pre> + * + * @author fordfrog + */ +public final class StringUtil +{ + + private StringUtil() + { + } + + /** + * Concatenates strings. + * + * @param strings + * strings to be concatenated + * + * @return concatenated string + * + * @see StringUtil + */ + public static String concat(final String... strings) + { + final StringBuilder sbString = new StringBuilder(getLength(strings)); + + for (final String string : strings) + { + sbString.append(string); + } + + return sbString.toString(); + } + + /** + * Creates new string builder with size initializated to + * <code>sizeHint</code>, unless total length of strings is greater than + * <code>sizeHint</code>. + * + * @param sizeHint + * hint for string builder size allocation + * @param strings + * strings to be appended + * + * @return created string builder + * + * @see StringUtil + */ + public static StringBuilder startAppend(final int sizeHint, final String... strings) + { + final int length = getLength(strings); + final StringBuilder sbString = new StringBuilder(sizeHint > length ? sizeHint : length); + + for (final String string : strings) + { + sbString.append(string); + } + + return sbString; + } + + /** + * Appends strings to existing string builder. + * + * @param sbString + * string builder + * @param strings + * strings to be appended + * + * @see StringUtil + */ + public static void append(final StringBuilder sbString, final String... strings) + { + sbString.ensureCapacity(sbString.length() + getLength(strings)); + + for (final String string : strings) + { + sbString.append(string); + } + } + + /** + * Counts total length of all the strings. + * + * @param strings + * array of strings + * + * @return total length of all the strings + */ + private static int getLength(final String[] strings) + { + int length = 0; + + for (final String string : strings) + { + if (string == null) + length += 4; + else + length += string.length(); + } + + return length; + } +} \ No newline at end of file Index: aCis_gameserver_350/java/net/sf/l2j/Base64.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/Base64.java (revision 0) +++ aCis_gameserver_350/java/net/sf/l2j/Base64.java (working copy) @@ -0,0 +1,1382 @@ +/* + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.sf.l2j; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import net.sf.l2j.gameserver.util.StringUtil; + +/** + * Encodes and decodes to and from Base64 notation. + * + * The source is based on the work of Robert Harder + * + * <p> + * I am placing this code in the Public Domain. Do with it as you will. This + * software comes with no guarantees or warranties but with plenty of + * well-wishing instead! Please visit <a + * href="http://iharder.net/xmlizable">http://iharder.net/base64</a> + * periodically to check for updates or to contribute improvements. + * </p> + * + * @author Robert Harder + * @author rob@iharder.net + * @version 2.0 + */ +public class Base64 +{ + + /* P U B L I C F I E L D S */ + + /** No options specified. Value is zero. */ + public final static int NO_OPTIONS = 0; + + /** Specify encoding. */ + public final static int ENCODE = 1; + + /** Specify decoding. */ + public final static int DECODE = 0; + + /** Specify that data should be gzip-compressed. */ + public final static int GZIP = 2; + + /** Don't break lines when encoding (violates strict Base64 specification) */ + public final static int DONT_BREAK_LINES = 8; + + /* P R I V A T E F I E L D S */ + + /** Maximum line length (76) of Base64 output. */ + private final static int MAX_LINE_LENGTH = 76; + + /** The equals sign (=) as a byte. */ + private final static byte EQUALS_SIGN = (byte) '='; + + /** The new line character (\n) as a byte. */ + private final static byte NEW_LINE = (byte) '\n'; + + /** Preferred encoding. */ + private final static String PREFERRED_ENCODING = "UTF-8"; + + /** The 64 valid Base64 values. */ + private final static byte[] ALPHABET; + private final static byte[] _NATIVE_ALPHABET = /* May be something funny like EBCDIC */ + { (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G', + (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N', + (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', + (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', (byte) 'a', (byte) 'b', + (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', + (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p', + (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u', (byte) 'v', (byte) 'w', + (byte) 'x', (byte) 'y', (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3', + (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) '+', + (byte) '/' }; + + public static void main(String[] args) throws IOException + { + BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); + System.out.print("Enter String to encode: "); + System.out.println(Base64.encodeBytes(bf.readLine().getBytes())); + } + + /** Determine which ALPHABET to use. */ + static + { + byte[] __bytes; + try + { + __bytes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".getBytes(PREFERRED_ENCODING); + } // end try + catch (java.io.UnsupportedEncodingException use) + { + __bytes = _NATIVE_ALPHABET; // Fall back to native encoding + } // end catch + ALPHABET = __bytes; + } // end static + + /** + * Translates a Base64 value to either its 6-bit reconstruction value or a + * negative number indicating some other meaning. + **/ + final static byte[] DECODABET = { -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8 + -5, -5, // Whitespace: Tab and Linefeed + -9, -9, // Decimal 11 - 12 + -5, // Whitespace: Carriage Return + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 + -9, -9, -9, -9, -9, // Decimal 27 - 31 + -5, // Whitespace: Space + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42 + 62, // Plus sign at decimal 43 + -9, -9, -9, // Decimal 44 - 46 + 63, // Slash at decimal 47 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine + -9, -9, -9, // Decimal 58 - 60 + -1, // Equals sign at decimal 61 + -9, -9, -9, // Decimal 62 - 64 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N' + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z' + -9, -9, -9, -9, -9, -9, // Decimal 91 - 96 + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm' + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z' + -9, -9, -9, -9 // Decimal 123 - 126 + /* + * ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 127 - 139 + * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 + * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 + * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 + * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 + * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 + * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 + * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 + * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 + * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 + */ + }; + + // private final static byte BAD_ENCODING = -9; // Indicates error in encoding + private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding + private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding + + /** Defeats instantiation. */ + private Base64() + { + } + + /* E N C O D I N G M E T H O D S */ + + // /** + // * Encodes the first three bytes of array <var>threeBytes</var> + // * and returns a four-byte array in Base64 notation. + // * + // * @param threeBytes the array to convert + // * @return four byte array in Base64 notation. + // * @since 1.3 + // */ + // private static byte[] encode3to4( byte[] threeBytes ) + // { + // return encode3to4( threeBytes, 3 ); + // } // end encodeToBytes + // /** + // * Encodes up to the first three bytes of array <var>threeBytes</var> + // * and returns a four-byte array in Base64 notation. + // * The actual number of significant bytes in your array is + // * given by <var>numSigBytes</var>. + // * The array <var>threeBytes</var> needs only be as big as + // * <var>numSigBytes</var>. + // * + // * @param threeBytes the array to convert + // * @param numSigBytes the number of significant bytes in your array + // * @return four byte array in Base64 notation. + // * @since 1.3 + // */ + // private static byte[] encode3to4( byte[] threeBytes, int numSigBytes ) + // { + // byte[] dest = new byte[4]; + // encode3to4( threeBytes, 0, numSigBytes, dest, 0 ); + // return dest; + // } + /** + * Encodes up to the first three bytes of array <var>threeBytes</var> and + * returns a four-byte array in Base64 notation. The actual number of + * significant bytes in your array is given by <var>numSigBytes</var>. The + * array <var>threeBytes</var> needs only be as big as + * <var>numSigBytes</var>. Code can reuse a byte array by passing a + * four-byte array as <var>b4</var>. + * + * @param b4 + * A reusable byte array to reduce array instantiation + * @param threeBytes + * the array to convert + * @param numSigBytes + * the number of significant bytes in your array + * @return four byte array in Base64 notation. + * @since 1.5.1 + */ + static byte[] encode3to4(byte[] b4, byte[] threeBytes, int numSigBytes) + { + encode3to4(threeBytes, 0, numSigBytes, b4, 0); + return b4; + } // end encode3to4 + + /** + * Encodes up to three bytes of the array <var>source</var> and writes the + * resulting four Base64 bytes to <var>destination</var>. The source and + * destination arrays can be manipulated anywhere along their length by + * specifying <var>srcOffset</var> and <var>destOffset</var>. This method + * does not check to make sure your arrays are large enough to accomodate + * <var>srcOffset</var> + 3 for the <var>source</var> array or + * <var>destOffset</var> + 4 for the <var>destination</var> array. The + * actual number of significant bytes in your array is given by + * <var>numSigBytes</var>. + * + * @param source + * the array to convert + * @param srcOffset + * the index where conversion begins + * @param numSigBytes + * the number of significant bytes in your array + * @param destination + * the array to hold the conversion + * @param destOffset + * the index where output will be put + * @return the <var>destination</var> array + * @since 1.3 + */ + static byte[] encode3to4(byte[] source, int srcOffset, int numSigBytes, byte[] destination, + int destOffset) + { + // 1 2 3 + // 01234567890123456789012345678901 Bit position + // --------000000001111111122222222 Array position from threeBytes + // --------| || || || | Six bit groups to index ALPHABET + // >>18 >>12 >> 6 >> 0 Right shift necessary + // 0x3f 0x3f 0x3f Additional AND + + // Create buffer with zero-padding if there are only one or two + // significant bytes passed in the array. + // We have to shift left 24 in order to flush out the 1's that appear + // when Java treats a value as negative that is cast from a byte to an + // int. + int inBuff = (numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0) + | (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0) + | (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0); + + switch (numSigBytes) + { + case 3: + destination[destOffset] = ALPHABET[(inBuff >>> 18)]; + destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f]; + destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f]; + destination[destOffset + 3] = ALPHABET[(inBuff) & 0x3f]; + return destination; + + case 2: + destination[destOffset] = ALPHABET[(inBuff >>> 18)]; + destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f]; + destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f]; + destination[destOffset + 3] = EQUALS_SIGN; + return destination; + + case 1: + destination[destOffset] = ALPHABET[(inBuff >>> 18)]; + destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f]; + destination[destOffset + 2] = EQUALS_SIGN; + destination[destOffset + 3] = EQUALS_SIGN; + return destination; + + default: + return destination; + } // end switch + } // end encode3to4 + + /** + * Serializes an object and returns the Base64-encoded version of that + * serialized object. If the object cannot be serialized or there is another + * error, the method will return <tt>null</tt>. The object is not + * GZip-compressed before being encoded. + * + * @param serializableObject + * The object to encode + * @return The Base64-encoded object + * @since 1.4 + */ + public static String encodeObject(java.io.Serializable serializableObject) + { + return encodeObject(serializableObject, NO_OPTIONS); + } // end encodeObject + + /** + * Serializes an object and returns the Base64-encoded version of that + * serialized object. If the object cannot be serialized or there is another + * error, the method will return <tt>null</tt>. + * <p> + * Valid options: + * + * <pre> + * GZIP: gzip-compresses object before encoding it. + * DONT_BREAK_LINES: don't break lines at 76 characters + * <i>Note: Technically, this makes your encoding non-compliant.</i> + * </pre> + * <p> + * Example: <code>encodeObject( myObj, Base64.GZIP )</code> or + * <p> + * Example: + * <code>encodeObject( myObj, Base64.GZIP | Base64.DONT_BREAK_LINES )</code> + * + * @param serializableObject + * The object to encode + * @options Specified options + * @return The Base64-encoded object + * @see Base64#GZIP + * @see Base64#DONT_BREAK_LINES + * @since 2.0 + */ + public static String encodeObject(java.io.Serializable serializableObject, int options) + { + // Streams + java.io.ByteArrayOutputStream baos = null; + java.io.OutputStream b64os = null; + java.io.ObjectOutputStream oos = null; + java.util.zip.GZIPOutputStream gzos = null; + + // Isolate options + int gzip = (options & GZIP); + int dontBreakLines = (options & DONT_BREAK_LINES); + + try + { + // ObjectOutputStream -> (GZIP) -> Base64 -> ByteArrayOutputStream + baos = new java.io.ByteArrayOutputStream(); + b64os = new Base64.OutputStream(baos, ENCODE | dontBreakLines); + + // GZip? + if (gzip == GZIP) + { + gzos = new java.util.zip.GZIPOutputStream(b64os); + oos = new java.io.ObjectOutputStream(gzos); + } // end if: gzip + else + oos = new java.io.ObjectOutputStream(b64os); + + oos.writeObject(serializableObject); + } // end try + catch (java.io.IOException e) + { + e.printStackTrace(); + return null; + } // end catch + finally + { + try + { + oos.close(); + } + catch (Exception e) + { + } + try + { + gzos.close(); + } + catch (Exception e) + { + } + try + { + b64os.close(); + } + catch (Exception e) + { + } + try + { + baos.close(); + } + catch (Exception e) + { + } + } // end finally + + // Return value according to relevant encoding. + try + { + return new String(baos.toByteArray(), PREFERRED_ENCODING); + } // end try + catch (java.io.UnsupportedEncodingException uue) + { + return new String(baos.toByteArray()); + } // end catch + + } // end encode + + /** + * Encodes a byte array into Base64 notation. Does not GZip-compress data. + * + * @param source + * The data to convert + * @since 1.4 + */ + public static String encodeBytes(byte[] source) + { + return encodeBytes(source, 0, source.length, NO_OPTIONS); + } // end encodeBytes + + /** + * Encodes a byte array into Base64 notation. + * <p> + * Valid options: + * + * <pre> + * GZIP: gzip-compresses object before encoding it. + * DONT_BREAK_LINES: don't break lines at 76 characters + * <i>Note: Technically, this makes your encoding non-compliant.</i> + * </pre> + * <p> + * Example: <code>encodeBytes( myData, Base64.GZIP )</code> or + * <p> + * Example: + * <code>encodeBytes( myData, Base64.GZIP | Base64.DONT_BREAK_LINES )</code> + * + * + * @param source + * The data to convert + * @param options + * Specified options + * @see Base64#GZIP + * @see Base64#DONT_BREAK_LINES + * @since 2.0 + */ + public static String encodeBytes(byte[] source, int options) + { + return encodeBytes(source, 0, source.length, options); + } // end encodeBytes + + /** + * Encodes a byte array into Base64 notation. Does not GZip-compress data. + * + * @param source + * The data to convert + * @param off + * Offset in array where conversion should begin + * @param len + * Length of data to convert + * @since 1.4 + */ + public static String encodeBytes(byte[] source, int off, int len) + { + return encodeBytes(source, off, len, NO_OPTIONS); + } // end encodeBytes + + /** + * Encodes a byte array into Base64 notation. + * <p> + * Valid options: + * + * <pre> + * GZIP: gzip-compresses object before encoding it. + * DONT_BREAK_LINES: don't break lines at 76 characters + * <i>Note: Technically, this makes your encoding non-compliant.</i> + * </pre> + * <p> + * Example: <code>encodeBytes( myData, Base64.GZIP )</code> or + * <p> + * Example: + * <code>encodeBytes( myData, Base64.GZIP | Base64.DONT_BREAK_LINES )</code> + * + * + * @param source + * The data to convert + * @param off + * Offset in array where conversion should begin + * @param len + * Length of data to convert + * @param breakLines + * Break lines at 80 characters or less. + * @param options + * Specified options + * @see Base64#GZIP + * @see Base64#DONT_BREAK_LINES + * @since 2.0 + */ + public static String encodeBytes(byte[] source, int off, int len, int options) + { + // Isolate options + int dontBreakLines = (options & DONT_BREAK_LINES); + int gzip = (options & GZIP); + + // Compress? + if (gzip == GZIP) + { + java.io.ByteArrayOutputStream baos = null; + java.util.zip.GZIPOutputStream gzos = null; + Base64.OutputStream b64os = null; + + try + { + // GZip -> Base64 -> ByteArray + baos = new java.io.ByteArrayOutputStream(); + b64os = new Base64.OutputStream(baos, ENCODE | dontBreakLines); + gzos = new java.util.zip.GZIPOutputStream(b64os); + + gzos.write(source, off, len); + gzos.close(); + } // end try + catch (java.io.IOException e) + { + e.printStackTrace(); + return null; + } // end catch + finally + { + try + { + gzos.close(); + } + catch (Exception e) + { + } + try + { + b64os.close(); + } + catch (Exception e) + { + } + try + { + baos.close(); + } + catch (Exception e) + { + } + } // end finally + + // Return value according to relevant encoding. + try + { + return new String(baos.toByteArray(), PREFERRED_ENCODING); + } // end try + catch (java.io.UnsupportedEncodingException uue) + { + return new String(baos.toByteArray()); + } // end catch + } // end if: compress + + // Convert option to boolean in way that code likes it. + boolean breakLines = dontBreakLines == 0; + + int len43 = len * 4 / 3; + byte[] outBuff = new byte[(len43) // Main 4:3 + + ((len % 3) > 0 ? 4 : 0) // Account for padding + + (breakLines ? (len43 / MAX_LINE_LENGTH) : 0)]; // New lines + int d = 0; + int e = 0; + int len2 = len - 2; + int lineLength = 0; + for (; d < len2; d += 3, e += 4) + { + encode3to4(source, d + off, 3, outBuff, e); + + lineLength += 4; + if (breakLines && lineLength == MAX_LINE_LENGTH) + { + outBuff[e + 4] = NEW_LINE; + e++; + lineLength = 0; + } // end if: end of line + } // en dfor: each piece of array + + if (d < len) + { + encode3to4(source, d + off, len - d, outBuff, e); + e += 4; + } // end if: some padding needed + + // Return value according to relevant encoding. + try + { + return new String(outBuff, 0, e, PREFERRED_ENCODING); + } // end try + catch (java.io.UnsupportedEncodingException uue) + { + return new String(outBuff, 0, e); + } // end catch + // end else: don't compress + + } // end encodeBytes + + /* D E C O D I N G M E T H O D S */ + + // /** + // * Decodes the first four bytes of array <var>fourBytes</var> + // * and returns an array up to three bytes long with the + // * decoded values. + // * + // * @param fourBytes the array with Base64 content + // * @return array with decoded values + // * @since 1.3 + // */ + // private static byte[] decode4to3( byte[] fourBytes ) + // { + // byte[] outBuff1 = new byte[3]; + // int count = decode4to3( fourBytes, 0, outBuff1, 0 ); + // byte[] outBuff2 = new byte[ count ]; + // + // for( int i = 0; i < count; i++ ) + // outBuff2 = outBuff1; + // + // return outBuff2; + // } + /** + * Decodes four bytes from array <var>source</var> and writes the resulting + * bytes (up to three of them) to <var>destination</var>. The source and + * destination arrays can be manipulated anywhere along their length by + * specifying <var>srcOffset</var> and <var>destOffset</var>. This method + * does not check to make sure your arrays are large enough to accomodate + * <var>srcOffset</var> + 4 for the <var>source</var> array or + * <var>destOffset</var> + 3 for the <var>destination</var> array. This + * method returns the actual number of bytes that were converted from the + * Base64 encoding. + * + * + * @param source + * the array to convert + * @param srcOffset + * the index where conversion begins + * @param destination + * the array to hold the conversion + * @param destOffset + * the index where output will be put + * @return the number of decoded bytes converted + * @since 1.3 + */ + static int decode4to3(byte[] source, int srcOffset, byte[] destination, int destOffset) + { + // Example: Dk== + if (source[srcOffset + 2] == EQUALS_SIGN) + { + // Two ways to do the same thing. Don't know which way I like best. + // int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 + // ) + // | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 ); + int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) + | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12); + + destination[destOffset] = (byte) (outBuff >>> 16); + return 1; + } + + // Example: DkL= + else if (source[srcOffset + 3] == EQUALS_SIGN) + { + // Two ways to do the same thing. Don't know which way I like best. + // int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 + // ) + // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) + // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ); + int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) + | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12) + | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6); + + destination[destOffset] = (byte) (outBuff >>> 16); + destination[destOffset + 1] = (byte) (outBuff >>> 8); + return 2; + } + + // Example: DkLE + else + { + try + { + // Two ways to do the same thing. Don't know which way I like + // best. + // int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) + // >>> 6 ) + // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) + // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ) + // | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 ); + int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) + | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12) + | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6) + | ((DECODABET[source[srcOffset + 3]] & 0xFF)); + + destination[destOffset] = (byte) (outBuff >> 16); + destination[destOffset + 1] = (byte) (outBuff >> 8); + destination[destOffset + 2] = (byte) (outBuff); + + return 3; + } + catch (Exception e) + { + System.out.println(StringUtil.concat(String.valueOf(source[srcOffset]), ": ", String.valueOf(DECODABET[source[srcOffset]]))); + System.out.println(StringUtil.concat(String.valueOf(source[srcOffset + 1]), ": ", String.valueOf(DECODABET[source[srcOffset + 1]]))); + System.out.println(StringUtil.concat(String.valueOf(source[srcOffset + 2]), ": ", String.valueOf(DECODABET[source[srcOffset + 2]]))); + System.out.println(StringUtil.concat(String.valueOf(source[srcOffset + 3]), ": ", String.valueOf(DECODABET[source[srcOffset + 3]]))); + return -1; + } // end catch + } + } // end decodeToBytes + + /** + * Very low-level access to decoding ASCII characters in the form of a byte + * array. Does not support automatically gunzipping or any other "fancy" + * features. + * + * @param source + * The Base64 encoded data + * @param off + * The offset of where to begin decoding + * @param len + * The length of characters to decode + * @return decoded data + * @since 1.3 + */ + public static byte[] decode(byte[] source, int off, int len) + { + int len34 = len * 3 / 4; + byte[] outBuff = new byte[len34]; // Upper limit on size of output + int outBuffPosn = 0; + + byte[] b4 = new byte[4]; + int b4Posn = 0; + int i = 0; + byte sbiCrop = 0; + byte sbiDecode = 0; + for (i = off; i < off + len; i++) + { + sbiCrop = (byte) (source & 0x7f); // Only the low seven bits + sbiDecode = DECODABET[sbiCrop]; + + if (sbiDecode >= WHITE_SPACE_ENC) // White space, Equals sign or + // better + { + if (sbiDecode >= EQUALS_SIGN_ENC) + { + b4[b4Posn++] = sbiCrop; + if (b4Posn > 3) + { + outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn); + b4Posn = 0; + + // If that was the equals sign, break out of 'for' loop + if (sbiCrop == EQUALS_SIGN) + break; + } // end if: quartet built + + } // end if: equals sign or better + + } // end if: white space, equals sign or better + else + { + System.err.println(StringUtil.concat("Bad Base64 input character at ", String.valueOf(i), ": ", String.valueOf(source), "(decimal)")); + return null; + } // end else: + } // each input character + + byte[] out = new byte[outBuffPosn]; + System.arraycopy(outBuff, 0, out, 0, outBuffPosn); + return out; + } // end decode + + /** + * Decodes data from Base64 notation, automatically detecting + * gzip-compressed data and decompressing it. + * + * @param s + * the string to decode + * @return the decoded data + * @since 1.4 + */ + public static byte[] decode(String s) + { + byte[] bytes; + try + { + bytes = s.getBytes(PREFERRED_ENCODING); + } // end try + catch (java.io.UnsupportedEncodingException uee) + { + bytes = s.getBytes(); + } // end catch + // </change> + + // Decode + bytes = decode(bytes, 0, bytes.length); + + // Check to see if it's gzip-compressed + // GZIP Magic Two-Byte Number: 0x8b1f (35615) + if (bytes != null && // In case decoding returned null + bytes.length >= 2) + { + + int head = (bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00); + if (bytes.length >= 4 && // Don't want to get ArrayIndexOutOfBounds + // exception + java.util.zip.GZIPInputStream.GZIP_MAGIC == head) + { + java.io.ByteArrayInputStream bais = null; + java.util.zip.GZIPInputStream gzis = null; + java.io.ByteArrayOutputStream baos = null; + byte[] buffer = new byte[2048]; + int length = 0; + + try + { + baos = new java.io.ByteArrayOutputStream(); + bais = new java.io.ByteArrayInputStream(bytes); + gzis = new java.util.zip.GZIPInputStream(bais); + + while ((length = gzis.read(buffer)) >= 0) + { + baos.write(buffer, 0, length); + } // end while: reading input + + // No error? Get new bytes. + bytes = baos.toByteArray(); + + } // end try + catch (java.io.IOException e) + { + // Just return originally-decoded bytes + } // end catch + finally + { + try + { + baos.close(); + } + catch (Exception e) + { + } + try + { + gzis.close(); + } + catch (Exception e) + { + } + try + { + bais.close(); + } + catch (Exception e) + { + } + } // end finally + + } // end if: gzipped + } // end if: bytes.length >= 2 + + return bytes; + } // end decode + + /** + * Attempts to decode Base64 data and deserialize a Java Object within. + * Returns <tt>null</tt> if there was an error. + * + * @param encodedObject + * The Base64 data to decode + * @return The decoded and deserialized object + * @since 1.5 + */ + public static Object decodeToObject(String encodedObject) + { + // Decode and gunzip if necessary + byte[] objBytes = decode(encodedObject); + + java.io.ByteArrayInputStream bais = null; + java.io.ObjectInputStream ois = null; + Object obj = null; + + try + { + bais = new java.io.ByteArrayInputStream(objBytes); + ois = new java.io.ObjectInputStream(bais); + + obj = ois.readObject(); + } // end try + catch (java.io.IOException e) + { + e.printStackTrace(); + obj = null; + } // end catch + catch (java.lang.ClassNotFoundException e) + { + e.printStackTrace(); + obj = null; + } // end catch + finally + { + try + { + bais.close(); + } + catch (Exception e) + { + } + try + { + ois.close(); + } + catch (Exception e) + { + } + } // end finally + + return obj; + } // end decodeObject + + /* I N N E R C L A S S I N P U T S T R E A M */ + + /** + * A {@link Base64#InputStream} will read data from another + * {@link java.io.InputStream}, given in the constructor, and encode/decode + * to/from Base64 notation on the fly. + * + * @see Base64 + * @see java.io.FilterInputStream + * @since 1.3 + */ + public static class InputStream extends java.io.FilterInputStream + { + // private int options; // Options specified + private boolean encode; // Encoding or decoding + private int position; // Current position in the buffer + private byte[] buffer; // Small buffer holding converted data + private int bufferLength; // Length of buffer (3 or 4) + private int numSigBytes; // Number of meaningful bytes in the buffer + private int lineLength; + private boolean breakLines; // Break lines at less than 80 characters + + /** + * Constructs a {@link Base64#InputStream} in DECODE mode. + * + * @param in + * the {@link java.io.InputStream} from which to read data. + * @since 1.3 + */ + public InputStream(java.io.InputStream pIn) + { + this(pIn, DECODE); + } // end constructor + + /** + * Constructs a {@link Base64#InputStream} in either ENCODE or DECODE + * mode. + * <p> + * Valid options: + * + * <pre> + * ENCODE or DECODE: Encode or Decode as data is read. + * DONT_BREAK_LINES: don't break lines at 76 characters + * (only meaningful when encoding) + * <i>Note: Technically, this makes your encoding non-compliant.</i> + * </pre> + * <p> + * Example: <code>new Base64.InputStream( in, Base64.DECODE )</code> + * + * + * @param in + * the {@link java.io.InputStream} from which to read data. + * @param options + * Specified options + * @see Base64#ENCODE + * @see Base64#DECODE + * @see Base64#DONT_BREAK_LINES + * @since 2.0 + */ + public InputStream(java.io.InputStream pIn, int options) + { + super(pIn); + // this.options = options; + breakLines = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES; + encode = (options & ENCODE) == ENCODE; + bufferLength = encode ? 4 : 3; + buffer = new byte[bufferLength]; + position = -1; + lineLength = 0; + } // end constructor + + /** + * Reads enough of the input stream to convert to/from Base64 and + * returns the next byte. + * + * @return next byte + * @since 1.3 + */ + @Override + public int read() throws java.io.IOException + { + // Do we need to get data? + if (position < 0) + { + if (encode) + { + byte[] b3 = new byte[3]; + int numBinaryBytes = 0; + for (int i = 0; i < 3; i++) + { + try + { + int b = in.read(); + + // If end of stream, b is -1. + if (b >= 0) + { + b3 = (byte) b; + numBinaryBytes++; + } // end if: not end of stream + + } // end try: read + catch (java.io.IOException e) + { + // Only a problem if we got no data at all. + if (i == 0) + throw e; + + } // end catch + } // end for: each needed input byte + + if (numBinaryBytes > 0) + { + encode3to4(b3, 0, numBinaryBytes, buffer, 0); + position = 0; + numSigBytes = 4; + } // end if: got data + else + { + return -1; + } // end else + } // end if: encoding + + // Else decoding + else + { + byte[] b4 = new byte[4]; + int i = 0; + for (i = 0; i < 4; i++) + { + // Read four "meaningful" bytes: + int b = 0; + do + { + b = in.read(); + } + while (b >= 0 && DECODABET[b & 0x7f] <= WHITE_SPACE_ENC); + + if (b < 0) + break; // Reads a -1 if end of stream + + b4 = (byte) b; + } // end for: each needed input byte + + if (i == 4) + { + numSigBytes = decode4to3(b4, 0, buffer, 0); + position = 0; + } // end if: got four characters + else if (i == 0) + { + return -1; + } // end else if: also padded correctly + else + { + // Must have broken out from above. + throw new java.io.IOException("Improperly padded Base64 input."); + } // end + + } // end else: decode + } // end else: get data + + // Got data? + if (position >= 0) + { + // End of relevant data? + if ( /* !encode && */position >= numSigBytes) + return -1; + + if (encode && breakLines && lineLength >= MAX_LINE_LENGTH) + { + lineLength = 0; + return '\n'; + } // end if + lineLength++; // This isn't important when decoding + // but throwing an extra "if" seems + // just as wasteful. + + int b = buffer[position++]; + + if (position >= bufferLength) + position = -1; + + return b & 0xFF; // This is how you "cast" a byte that's + // intended to be unsigned. + // end else + } // end if: position >= 0 + + // When JDK1.4 is more accepted, use an assertion here. + throw new java.io.IOException("Error in Base64 code reading stream."); + // end else + } // end read + + /** + * Calls {@link #read} repeatedly until the end of stream is reached or + * <var>len</var> bytes are read. Returns number of bytes read into + * array or -1 if end of stream is encountered. + * + * @param dest + * array to hold values + * @param off + * offset for array + * @param len + * max number of bytes to read into array + * @return bytes read into array or -1 if end of stream is encountered. + * @since 1.3 + */ + @Override + public int read(byte[] dest, int off, int len) throws java.io.IOException + { + int i; + int b; + for (i = 0; i < len; i++) + { + b = read(); + + // if( b < 0 && i == 0 ) + // return -1; + + if (b >= 0) + dest[off + i] = (byte) b; + else if (i == 0) + return -1; + else + break; // Out of 'for' loop + } // end for: each byte read + return i; + } // end read + + } // end inner class InputStream + + /* I N N E R C L A S S O U T P U T S T R E A M */ + + /** + * A {@link Base64#OutputStream} will write data to another + * {@link java.io.OutputStream}, given in the constructor, and encode/decode + * to/from Base64 notation on the fly. + * + * @see Base64 + * @see java.io.FilterOutputStream + * @since 1.3 + */ + public static class OutputStream extends java.io.FilterOutputStream + { + // private int options; + private boolean encode; + private int position; + private byte[] buffer; + private int bufferLength; + private int lineLength; + private boolean breakLines; + private byte[] b4; // Scratch used in a few places + private boolean suspendEncoding; + + /** + * Constructs a {@link Base64#OutputStream} in ENCODE mode. + * + * @param out + * the {@link java.io.OutputStream} to which data will be + * written. + * @since 1.3 + */ + public OutputStream(java.io.OutputStream pOut) + { + this(pOut, ENCODE); + } // end constructor + + /** + * Constructs a {@link Base64#OutputStream} in either ENCODE or DECODE + * mode. + * <p> + * Valid options: + * + * <pre> + * ENCODE or DECODE: Encode or Decode as data is read. + * DONT_BREAK_LINES: don't break lines at 76 characters + * (only meaningful when encoding) + * <i>Note: Technically, this makes your encoding non-compliant.</i> + * </pre> + * <p> + * Example: <code>new Base64.OutputStream( out, Base64.ENCODE )</code> + * + * @param out + * the {@link java.io.OutputStream} to which data will be + * written. + * @param options + * Specified options. + * @see Base64#ENCODE + * @see Base64#DECODE + * @see Base64#DONT_BREAK_LINES + * @since 1.3 + */ + public OutputStream(java.io.OutputStream pOut, int options) + { + super(pOut); + // this.options = options; + breakLines = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES; + encode = (options & ENCODE) == ENCODE; + bufferLength = encode ? 3 : 4; + buffer = new byte[bufferLength]; + position = 0; + lineLength = 0; + suspendEncoding = false; + b4 = new byte[4]; + } // end constructor + + /** + * Writes the byte to the output stream after converting to/from Base64 + * notation. When encoding, bytes are buffered three at a time before + * the output stream actually gets a write() call. When decoding, bytes + * are buffered four at a time. + * + * @param theByte + * the byte to write + * @since 1.3 + */ + @Override + public void write(int theByte) throws java.io.IOException + { + // Encoding suspended? + if (suspendEncoding) + { + super.out.write(theByte); + return; + } // end if: supsended + + // Encode? + if (encode) + { + buffer[position++] = (byte) theByte; + if (position >= bufferLength) // Enough to encode. + { + out.write(encode3to4(b4, buffer, bufferLength)); + + lineLength += 4; + if (breakLines && lineLength >= MAX_LINE_LENGTH) + { + out.write(NEW_LINE); + lineLength = 0; + } // end if: end of line + + position = 0; + } // end if: enough to output + } // end if: encoding + + // Else, Decoding + else + { + // Meaningful Base64 character? + if (DECODABET[theByte & 0x7f] > WHITE_SPACE_ENC) + { + buffer[position++] = (byte) theByte; + if (position >= bufferLength) // Enough to output. + { + int len = Base64.decode4to3(buffer, 0, b4, 0); + out.write(b4, 0, len); + // out.write( Base64.decode4to3( buffer ) ); + position = 0; + } // end if: enough to output + } // end if: meaningful base64 character + else if (DECODABET[theByte & 0x7f] != WHITE_SPACE_ENC) + { + throw new java.io.IOException("Invalid character in Base64 data."); + } // end else: not white space either + } // end else: decoding + } // end write + + /** + * Calls {@link #write} repeatedly until <var>len</var> bytes are + * written. + * + * @param theBytes + * array from which to read bytes + * @param off + * offset for array + * @param len + * max number of bytes to read into array + * @since 1.3 + */ + @Override + public void write(byte[] theBytes, int off, int len) throws java.io.IOException + { + // Encoding suspended? + if (suspendEncoding) + { + super.out.write(theBytes, off, len); + return; + } // end if: supsended + + for (int i = 0; i < len; i++) + { + write(theBytes[off + i]); + } // end for: each byte written + + } // end write + + /** + * Method added by PHIL. [Thanks, PHIL. -Rob] This pads the buffer + * without closing the stream. + */ + public void flushBase64() throws java.io.IOException + { + if (position > 0) + { + if (encode) + { + out.write(encode3to4(b4, buffer, position)); + position = 0; + } // end if: encoding + else + { + throw new java.io.IOException("Base64 input not properly padded."); + } // end else: decoding + } // end if: buffer partially full + + } // end flush + + /** + * Flushes and closes (I think, in the superclass) the stream. + * + * @since 1.3 + */ + @Override + public void close() throws java.io.IOException + { + // 1. Ensure that pending characters are written + flushBase64(); + + // 2. Actually close the stream + // Base class both flushes and closes. + super.close(); + + buffer = null; + out = null; + } // end close + + /** + * Suspends encoding of the stream. May be helpful if you need to embed + * a piece of base640-encoded data in a stream. + * + * @since 1.5.1 + */ + public void suspendEncoding() throws java.io.IOException + { + flushBase64(); + suspendEncoding = true; + } // end suspendEncoding + + /** + * Resumes encoding of the stream. May be helpful if you need to embed a + * piece of base640-encoded data in a stream. + * + * @since 1.5.1 + */ + public void resumeEncoding() + { + suspendEncoding = false; + } // end resumeEncoding + + } // end inner class OutputStream + +} // end class Base64 \ No newline at end of file Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestItemList.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestItemList.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestItemList.java (working copy) @@ -24,6 +24,11 @@ { } + protected void isSubmitingPin() + { + return; + } + @Override protected void runImpl() { Index: aCis_datapack_350/sql/passskey.sql =================================================================== --- aCis_datapack_350/sql/passskey.sql (revision 0) +++ aCis_datapack_350/sql/passskey.sql (working copy) @@ -0,0 +1,7 @@ +CREATE TABLE IF NOT EXISTS passkey ( +`obj_Id` INT UNSIGNED NOT NULL DEFAULT 0, +`passkey` VARCHAR(45), +`question` VARCHAR(55) NOT NULL, +`answer` VARCHAR(35) NOT NULL, +PRIMARY KEY (obj_Id) +); \ No newline at end of file Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestDismissAlly.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestDismissAlly.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestDismissAlly.java (working copy) @@ -31,6 +31,12 @@ if (activeChar == null) return; + if (activeChar.isSubmitingPin()) + { + activeChar.sendMessage("Digite a senha do personagem."); + return; + } + if (!activeChar.isClanLeader()) { activeChar.sendPacket(SystemMessageId.FEATURE_ONLY_FOR_ALLIANCE_LEADER); Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/SendWarehouseDepositList.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/SendWarehouseDepositList.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/SendWarehouseDepositList.java (working copy) @@ -67,6 +67,12 @@ if (player == null) return; + if (player.isSubmitingPin()) + { + player.sendMessage("Digite a senha do personagem."); + return; + } + if (player.isProcessingTransaction()) { player.sendPacket(SystemMessageId.ALREADY_TRADING); Index: aCis_datapack_350/data/html/passkey/login.htm =================================================================== --- aCis_datapack_350/data/html/passkey/login.htm (revision 0) +++ aCis_datapack_350/data/html/passkey/login.htm (working copy) @@ -0,0 +1,21 @@ +<html> +<title>Personal Password Manager</title> +<body> +<center> +<img src="L2Font.mini_logo-k" width=250 height=90><br> +<img src="L2UI_CH3.herotower_deco" width=256 height=32><br> +</center> +<br> +Hello, stranger! To continue playing, you have to provide your password. +<center> +<table> +<tr><td><font color="732cde">Enter password: </font></td><td><edit var="pass" width=70 height=10></td></tr><br> +</table> +<br> +<button value="Confirm" action="bypass -h pklogin $pass" width=75 height=21 back="L2UI_ch3.Btn1_normalOn" fore="L2UI_ch3.Btn1_normal"> +<button value="Forgot password" action="bypass -h pkrecovery" width=75 height=21 back="L2UI_ch3.Btn1_normalOn" fore="L2UI_ch3.Btn1_normal"> +<br> +<img src="L2UI_CH3.herotower_deco" width=256 height=32> +</center> +</body> +</html> \ No newline at end of file Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestDestroyItem.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestDestroyItem.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestDestroyItem.java (working copy) @@ -48,6 +48,12 @@ if (activeChar == null) return; + if (activeChar.isSubmitingPin()) + { + activeChar.sendMessage("Digite a senha do personagem."); + return; + } + if (activeChar.isProcessingTransaction() || activeChar.isInStoreMode()) { activeChar.sendPacket(SystemMessageId.CANNOT_TRADE_DISCARD_DROP_ITEM_WHILE_IN_SHOPMODE); Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/SetPrivateStoreListSell.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/SetPrivateStoreListSell.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/SetPrivateStoreListSell.java (working copy) @@ -62,6 +62,12 @@ if (player == null) return; + if (player.isSubmitingPin()) + { + player.sendMessage("Digite a senha do personagem."); + return; + } + if (_items == null) { player.sendPacket(SystemMessageId.NOT_ENOUGH_ITEMS); Index: aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestJoinParty.java =================================================================== --- aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestJoinParty.java (revision 18) +++ aCis_gameserver_350/java/net/sf/l2j/gameserver/network/clientpackets/RequestJoinParty.java (working copy) @@ -58,6 +58,12 @@ return; } + if (requestor.isSubmitingPin() || target.isSubmitingPin()) + { + requestor.sendMessage("Digite a senha do personagem."); + return; + } + if (target.equals(requestor) || target.isCursedWeaponEquipped() || requestor.isCursedWeaponEquipped() || target.getAppearance().getInvisible()) { requestor.sendPacket(SystemMessageId.YOU_HAVE_INVITED_THE_WRONG_TARGET);
-
I'm just adapting the mod to alcis, it was not me that did it, I believe that this mod was made by you, elfocrazy myth
-
Help Decrease Bs Heal In Players Flag / Pc For Acis 350
l2jkain replied to l2jkain's question in Request Server Development Help [L2J]
I'm not very good at java if you help me I can improve it and make it work -
Help Decrease Bs Heal In Players Flag / Pc For Acis 350
l2jkain replied to l2jkain's question in Request Server Development Help [L2J]
There is no way because I'm pulling the PvpFlag get method and getKarma they come from L2PcInstance -
LF Title - Name Color Changer For Acis
l2jkain replied to Rokit's question in Request Server Development Help [L2J]
#P aCis_gameserver Index: java/net/sf/l2j/gameserver/datatables/AccessLevels.java =================================================================== --- java/net/sf/l2j/gameserver/datatables/AccessLevels.java (revision 190) +++ java/net/sf/l2j/gameserver/datatables/AccessLevels.java (working copy) @@ -39,7 +39,7 @@ public static final int USER_ACCESS_LEVEL_NUMBER = 0; public static L2AccessLevel MASTER_ACCESS_LEVEL = new L2AccessLevel(MASTER_ACCESS_LEVEL_NUMBER, "Master Access", Config.MASTERACCESS_NAME_COLOR, Config.MASTERACCESS_TITLE_COLOR, null, true, true, true, true, true, true, true, true); - public static L2AccessLevel USER_ACCESS_LEVEL = new L2AccessLevel(USER_ACCESS_LEVEL_NUMBER, "User", 0xFFFFFF, 0xFFFF77, null, false, false, false, true, false, true, true, true); + public static L2AccessLevel USER_ACCESS_LEVEL = new L2AccessLevel(USER_ACCESS_LEVEL_NUMBER, "User", Config. NAME_COLOR, Config.NEWCHAR_TITLE_COLOR, null, false, false, false, true, false, true, true, true); private final Map<Integer, L2AccessLevel> _accessLevels = new HashMap<>(); @@ -91,15 +91,15 @@ nameColor = Integer.decode("0xFFFFFF"); } - int titleColor; - try - { - titleColor = Integer.decode("0x" + attrs.getNamedItem("titleColor").getNodeValue()); - } - catch (NumberFormatException nfe) - { - titleColor = Integer.decode("0x77FFFF"); - } + int titleColor; + try + { + titleColor = Integer.decode("0x" + attrs.getNamedItem("titleColor").getNodeValue()); + } + catch (NumberFormatException nfe) + { + titleColor = Integer.decode("0xFFFFFF"); + } String childs = attrs.getNamedItem("childAccess").getNodeValue(); boolean isGm = Boolean.valueOf(attrs.getNamedItem("isGm").getNodeValue()); Index: java/net/sf/l2j/Config.java =================================================================== --- java/net/sf/l2j/Config.java (revision 190) +++ java/net/sf/l2j/Config.java (working copy) @@ -377,6 +377,12 @@ /** Misc */ + public static int NEWCHAR_TITLE_COLOR; + public static int NEWCHAR_NAME_COLOR; @@ -1081,6 +1087,22 @@ { final ExProperties players = initProperties(PLAYERS_FILE); STARTING_ADENA = players.getProperty("StartingAdena", 100); + NEWCHAR_TITLE_COLOR = Integer.decode("0x" + players.getProperty("NewCharTitleColor", "00FF00")); + NEWCHAR_NAME_COLOR = Integer.decode("0x" + players.getProperty("NewCharNameColor", "00FF00")); Index: config/players.properties =================================================================== --- config/players.properties (revision 191) +++ config/players.properties (working copy) @@ -5,6 +5,26 @@ #Amount of adenas that a new character is given, default is 100 StartingAdena = 100 +# ================================= +# Name / Title Color for acis +# ================================= +# Title color for new characters. +# Default: FFFFFF +NewCharTitleColor = FFFFFF +# Name color for new characters. +# Default: FFFFFF +NewCharNameColor = FFFFFF By : Williamss -
Help Delay In Class Messages Exshowscreenmessage
l2jkain replied to l2jkain's question in Request Server Development Help [L2J]
It appears more of the vip no longer appears if (Config.SERVER_TIME_ON_START) ThreadPool.schedule(() -> activeChar.sendPacket(new ExShowScreenMessage("L2 Serve Time is " + fmt.format(new Date(System.currentTimeMillis())), 10000, 0x02, true)), 10000);