Initial changes.
This commit is contained in:
parent
24a2cc615e
commit
e70ad4bdb2
@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-12">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="lib" path="dist/libs/HikariCP-3.2.0.jar"/>
|
||||
<classpathentry kind="lib" path="dist/libs/ecj-4.4.2.jar"/>
|
||||
<classpathentry kind="lib" path="dist/libs/java-engine-1.8.jar"/>
|
||||
<classpathentry kind="lib" path="dist/libs/jython-engine.jar"/>
|
||||
<classpathentry kind="lib" path="dist/libs/jython.jar"/>
|
||||
<classpathentry kind="lib" path="dist/libs/mariadb-java-client-2.3.0.jar"/>
|
||||
<classpathentry kind="lib" path="dist/libs/slf4j-api-1.7.25.jar"/>
|
||||
<classpathentry kind="lib" path="dist/libs/slf4j-simple-1.7.25.jar"/>
|
||||
|
@ -17,9 +17,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul
|
||||
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=12
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=12
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
@ -34,6 +34,7 @@ org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
|
||||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
|
||||
@ -90,6 +91,7 @@ org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warn
|
||||
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
|
||||
org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
||||
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
|
||||
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
|
||||
@ -122,7 +124,8 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
org.eclipse.jdt.core.compiler.release=disabled
|
||||
org.eclipse.jdt.core.compiler.source=12
|
||||
org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
|
||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=0
|
||||
|
@ -51,8 +51,8 @@
|
||||
</not>
|
||||
</condition>
|
||||
</fail>
|
||||
<available classname="java.util.stream.Stream" property="JDK8.present" />
|
||||
<fail unless="JDK8.present" message="Java 1.8 is required. But your version is Java ${ant.java.version} and probably JDK is not installed." />
|
||||
<available classname="java.util.stream.Stream" property="JDK12.present" />
|
||||
<fail unless="JDK12.present" message="Java 12 is required. But your version is Java ${ant.java.version} and probably JDK is not installed." />
|
||||
</target>
|
||||
|
||||
<target name="init" depends="checkRequirements" description="Create the output directories.">
|
||||
@ -61,7 +61,7 @@
|
||||
</target>
|
||||
|
||||
<target name="compile" depends="init" description="Compile the source.">
|
||||
<javac srcdir="${src}" classpathref="classpath" destdir="${build.bin}" compiler="modern" debug="true" debuglevel="lines,vars,source" includeantruntime="false" source="1.8" target="1.8" encoding="UTF-8" />
|
||||
<javac srcdir="${src}" classpathref="classpath" destdir="${build.bin}" compiler="modern" debug="true" debuglevel="lines,vars,source" includeantruntime="false" source="12" target="12" encoding="UTF-8" />
|
||||
</target>
|
||||
|
||||
<target name="jar" depends="compile" description="Create the jar files.">
|
||||
|
@ -1,6 +1,6 @@
|
||||
@echo off
|
||||
title L2D geodata converter
|
||||
|
||||
java -version:1.8 -Xmx512m -cp ./../libs/* org.l2jmobius.tools.geodataconverter.GeoDataConverter
|
||||
java -Xmx512m -cp ./../libs/* org.l2jmobius.tools.geodataconverter.GeoDataConverter
|
||||
|
||||
pause
|
||||
|
@ -80,4 +80,7 @@ RemotePrivStoreFactor = 12
|
||||
# To exacute the server under debugger with eclipse use:
|
||||
# DatapackRoot = ../L2jMobius_DataPack
|
||||
# or point the folder directly to your server.
|
||||
DatapackRoot = .
|
||||
DatapackRoot = .
|
||||
|
||||
# Scripts root directory.
|
||||
ScriptRoot = ./data/scripts
|
||||
|
@ -1,11 +0,0 @@
|
||||
# Enable / disable display information about the load on each object
|
||||
EnableScriptDebug = False
|
||||
|
||||
# Enable / disable the mandatory compilation of all the objects
|
||||
AllowCompilation = True
|
||||
|
||||
# Enable / disable hash loaded objects
|
||||
UseCache = False
|
||||
|
||||
# Enable / disable error output
|
||||
EnableScriptErrorLog = True
|
17
L2J_Mobius_C6_Interlude_OpenJDK12/dist/game/config/protected/ScriptEngine.ini
vendored
Normal file
17
L2J_Mobius_C6_Interlude_OpenJDK12/dist/game/config/protected/ScriptEngine.ini
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
# ---------------------------------------------------------------------------
|
||||
# Script Engine Settings
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# The parent class loader for isolated script class loaders.
|
||||
# When this property is not specified, has an invalid value or is a class name which could not be found, the System classloader is used.
|
||||
# Values: System, ThreadContext or a fully qualified java class name.
|
||||
classloader=System
|
||||
|
||||
# Source compatibility.
|
||||
source=1.8
|
||||
|
||||
# The java sourcepath, when you have a different datapack root, you must change this too.
|
||||
sourcepath=data/scripts
|
||||
|
||||
# The debug informations to generate for compiled class files.
|
||||
g=source,lines,vars
|
25
L2J_Mobius_C6_Interlude_OpenJDK12/dist/game/config/protected/Scripts.xml
vendored
Normal file
25
L2J_Mobius_C6_Interlude_OpenJDK12/dist/game/config/protected/Scripts.xml
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../data/xsd/Scripts.xsd">
|
||||
<!-- Skip these filenames from script loading, because they are already loaded using a different way. -->
|
||||
<exclude file="package-info.java" />
|
||||
|
||||
<!--
|
||||
With this file you can exclude/include specific folders/files from within the scripts directory.
|
||||
|
||||
In order to exclude a folder/file simply add the following line:
|
||||
<exclude file="{FOLDER/FILE NAME HERE}" />
|
||||
For example to exclude the quests directory, use:
|
||||
<exclude file="quests" />
|
||||
|
||||
If you want to exclude all files within a directory except certain file(s), you can do it like so:
|
||||
<exclude file="{FOLDER NAME HERE}">
|
||||
<include file="{FOLDER/FILE NAME HERE}" />
|
||||
<include file="{FOLDER/FILE NAME HERE}" />
|
||||
...
|
||||
</exclude>
|
||||
For example to exclude ForgeOfTheGods folder except Valakas script, use:
|
||||
<exclude file="ForgeOfTheGods">
|
||||
<include file="Valakas.java" />
|
||||
</exclude>
|
||||
-->
|
||||
</list>
|
@ -1,129 +0,0 @@
|
||||
# Boss AI
|
||||
ai/bosses/Antharas.java
|
||||
ai/bosses/Baium.java
|
||||
ai/bosses/Barakiel.java
|
||||
ai/bosses/benom.py
|
||||
ai/bosses/Core.java
|
||||
ai/bosses/drchaos.py
|
||||
ai/bosses/Frintezza.java
|
||||
ai/bosses/Golkonda.java
|
||||
ai/bosses/Gordon.java
|
||||
ai/bosses/gustav.py
|
||||
ai/bosses/Hallate.java
|
||||
ai/bosses/IceFairySirra.java
|
||||
ai/bosses/Kernon.java
|
||||
ai/bosses/nurka.py
|
||||
ai/bosses/Orfen.java
|
||||
ai/bosses/QueenAnt.java
|
||||
ai/bosses/Tyrannosaurus.java
|
||||
ai/bosses/sailren.py
|
||||
ai/bosses/Valakas.java
|
||||
ai/bosses/VanHalter.java
|
||||
ai/bosses/Zaken.java
|
||||
|
||||
# Other AI
|
||||
ai/others/AncientEgg.java
|
||||
ai/others/cats_eye_bandit.py
|
||||
ai/others/chests.py
|
||||
ai/others/delu_lizardman_special_agent.py
|
||||
ai/others/delu_lizardman_special_commander.py
|
||||
ai/others/evabox.py
|
||||
ai/others/feedable_beasts.py
|
||||
ai/others/karul_bugbear.py
|
||||
ai/others/Monastery.java
|
||||
ai/others/ol_mahum_general.py
|
||||
ai/others/retreat_onattack.py
|
||||
ai/others/scarlet_stokate_noble.py
|
||||
ai/others/splendor.py
|
||||
#ai/others/squash.py
|
||||
ai/others/SummonMinions.java
|
||||
ai/others/timak_orc_overlord.py
|
||||
ai/others/timak_orc_troop_leader.py
|
||||
ai/others/Transform.java
|
||||
ai/others/turek_orc_footman.py
|
||||
ai/others/turek_orc_supplier.py
|
||||
ai/others/turek_orc_warlord.py
|
||||
ai/others/ZombieGatekeepers.java
|
||||
|
||||
# Custom
|
||||
custom/EchoCrystals/EchoCrystals.java
|
||||
custom/HeroCirclet/HeroCirclet.java
|
||||
custom/HeroWeapon/HeroWeapon.java
|
||||
custom/KetraOrcSupport/KetraOrcSupport.java
|
||||
custom/MissQueen/MissQueen.java
|
||||
custom/NpcLocationInfo/NpcLocationInfo.java
|
||||
custom/RaidbossInfo/RaidbossInfo.java
|
||||
custom/VarkaSilenosSupport/VarkaSilenosSupport.java
|
||||
custom/ShadowWeapon/ShadowWeapon.java
|
||||
custom/8003_MeetBaium/__init__.py
|
||||
custom/8009_HotSpringsBuffs/__init__.py
|
||||
#custom/6666_NoblessTrader/__init__.py
|
||||
#custom/6667_ClanManager/__init__.py
|
||||
|
||||
# Quests - Python
|
||||
quests/24_InhabitantsOfTheForrestOfTheDead/__init__.py
|
||||
quests/25_HidingBehindTheTruth/__init__.py
|
||||
quests/115_TheOtherSideOfTruth/__init__.py
|
||||
quests/120_PavelsResearch/__init__.py
|
||||
quests/137_TempleChampionPart1/__init__.py
|
||||
quests/138_TempleChampionPart2/__init__.py
|
||||
quests/139_ShadowFoxPart1/__init__.py
|
||||
quests/140_ShadowFoxPart2/__init__.py
|
||||
quests/141_ShadowFoxPart3/__init__.py
|
||||
quests/142_FallenAngelRequestOfDawn/__init__.py
|
||||
quests/143_FallenAngelRequestOfDusk/__init__.py
|
||||
quests/178_IconicTrinity/__init__.py
|
||||
quests/183_Relic_Exploration/__init__.py
|
||||
quests/186_Contract_Execution/__init__.py
|
||||
quests/187_Nikolas_Heart/__init__.py
|
||||
quests/188_Seal_Removal/__init__.py
|
||||
quests/189_Contract_Completion/__init__.py
|
||||
quests/191_Vain_Conclusion/__init__.py
|
||||
quests/236_SeedsOfChaos/__init__.py
|
||||
quests/255_Tutorial/__init__.py
|
||||
quests/269_InventionAmbition/__init__.py
|
||||
quests/280_TheFoodChain/__init__.py
|
||||
quests/281_HeadForTheHills/__init__.py
|
||||
quests/283_TheFewTheProudTheBrave/__init__.py
|
||||
quests/284_MuertosFeather/__init__.py
|
||||
quests/286_FabulousFeathers/__init__.py
|
||||
quests/334_TheWishingPotion/__init__.py
|
||||
quests/335_TheSongOfTheHunter/__init__.py
|
||||
quests/336_CoinOfMagic/__init__.py
|
||||
quests/343_UnderTheShadowOfTheIvoryTower/__init__.py
|
||||
quests/350_EnhanceYourWeapon/__init__.py
|
||||
quests/386_StolenDignity/__init__.py
|
||||
quests/501_ProofOfClanAlliance/__init__.py
|
||||
quests/503_PursuitClanAmbition/__init__.py
|
||||
quests/504_CompetitionfortheBanditStronghold/__init__.py
|
||||
quests/505_BloodOffering/__init__.py
|
||||
quests/508_TheClansReputation/__init__.py
|
||||
quests/509_TheClansPrestige/__init__.py
|
||||
quests/510_AClansReputation/__init__.py
|
||||
quests/635_InTheDimensionalRift/__init__.py
|
||||
quests/636_TruthBeyond/__init__.py
|
||||
quests/648_AnIceMerchantsDream/__init__.py
|
||||
quests/655_AGrandPlanforTamingWildBeasts/__init__.py
|
||||
quests/999_C3Tutorial/__init__.py
|
||||
|
||||
# Quests - Java
|
||||
quests/QuestMasterHandler.java
|
||||
|
||||
# Teleports
|
||||
teleports/ElrokiTeleporters/ElrokiTeleporters.java
|
||||
teleports/HuntingGroundsTeleport/HuntingGroundsTeleport.java
|
||||
teleports/NewbieTravelToken/NewbieTravelToken.java
|
||||
teleports/NoblesseTeleport/NoblesseTeleport.java
|
||||
teleports/OracleTeleport/OracleTeleport.java
|
||||
teleports/PaganTeleporters/PaganTeleporters.java
|
||||
teleports/RaceTrack/RaceTrack.java
|
||||
teleports/TeleportWithCharm/TeleportWithCharm.java
|
||||
teleports/ToIVortex/ToIVortex.java
|
||||
teleports/2400_toivortex_exit/__init__.py
|
||||
teleports/6000_GrandBossTeleporters/__init__.py
|
||||
|
||||
# Village Master
|
||||
village_master/ClanMaster/ClanMaster.java
|
||||
village_master/AllianceMaster/AllianceMaster.java
|
||||
village_master/FirstClassChange/FirstClassChange.java
|
||||
village_master/SecondClassChange/SecondClassChange.java
|
@ -1,202 +0,0 @@
|
||||
import sys
|
||||
from org.l2jmobius.gameserver.ai import CtrlIntention
|
||||
from org.l2jmobius.gameserver.model.quest import State
|
||||
from org.l2jmobius.gameserver.model.quest import QuestState
|
||||
from org.l2jmobius.gameserver.model.quest.jython import QuestJython as JQuest
|
||||
from org.l2jmobius.gameserver.network.serverpackets import CreatureSay
|
||||
from org.l2jmobius.commons.util import Rnd
|
||||
|
||||
POLLEN = 6391
|
||||
SKILL_NECTAR = 9998
|
||||
|
||||
# Поливаемые
|
||||
WATERED_SQUASH = [12774,12775,12776,12777,12778,12779]
|
||||
|
||||
class squash(JQuest) :
|
||||
|
||||
def __init__(self,id,name,descr):
|
||||
JQuest.__init__(self,id,name,descr)
|
||||
# Выросшие
|
||||
self.adultSmallSquash = [12775,12776]
|
||||
self.adultLargeSquash = [12778,12779]
|
||||
|
||||
def onAdvEvent(self,event,npc,player) :
|
||||
objId = npc.getObjectId()
|
||||
if event == "Good By" and npc and player :
|
||||
npc.broadcastPacket(CreatureSay(objId,0,npc.getName(),"Good By!! LOL."))
|
||||
npc.onDecay()
|
||||
elif event == "Good By1" and npc and player :
|
||||
npc.broadcastPacket(CreatureSay(objId,0,npc.getName(),"Всем, до свидания... Большая тыква сказала до свидания ..."))
|
||||
npc.onDecay()
|
||||
elif event == "Good By2" and npc and player :
|
||||
npc.broadcastPacket(CreatureSay(objId,0,npc.getName(),"Вы можете быстрее? Через 30 секунд я сбегу ..."))
|
||||
elif event == "Good By3" and npc and player :
|
||||
npc.broadcastPacket(CreatureSay(objId,0,npc.getName(),"Я прерву отношения с Вами через 20 секунд!"))
|
||||
elif event == "Good By4" and npc and player :
|
||||
npc.broadcastPacket(CreatureSay(objId,0,npc.getName(),"У меня осталось всего 10 секунд! 9. 8. 7 ..!"))
|
||||
elif event == "Good By5" and npc and player :
|
||||
npc.broadcastPacket(CreatureSay(objId,0,npc.getName(),"Эй! Счастливо оставаться! Идиот, забудь обо мне!"))
|
||||
return
|
||||
|
||||
def onSkillUse(self,npc,player,skill):
|
||||
npcId = npc.getNpcId()
|
||||
skillId = skill.getId()
|
||||
if skillId != SKILL_NECTAR : return
|
||||
if npcId not in WATERED_SQUASH : return
|
||||
objectId = npc.getObjectId()
|
||||
if skillId == SKILL_NECTAR :
|
||||
# Первый полив
|
||||
if npc.getNectar() == 0 :
|
||||
if Rnd.get(2) == 1 :
|
||||
mytext = ["Чтобы быть способной расти, я должна пить только нектар ... причем чаще",
|
||||
"Если ты будеш быстрее выливать мне нектар - я быстрее выросту!",
|
||||
"Ну, верьте мне, прыскайте нектар! Я могу конечно превратиться в большую тыкву!!!",
|
||||
"Принеси нектар, чтобы вырастить тыкву!",
|
||||
"Плод прекрасной молодой тыквы начинает блестеть, когда семя предано земле! С этого времени будет способен стать здоровым и сильным!",
|
||||
"О, давно не виделись?",
|
||||
"Неожидал увидеть мое красивое появление?",
|
||||
"Отлично! Это - нечто! Нектар?",
|
||||
"Дозаправка! Заправь 5 бутылок, чтобы я смогла превратиться в большую тыкву! О!"]
|
||||
npc.broadcastPacket(CreatureSay(objectId,0,npc.getName(),mytext[Rnd.get(len(mytext))]))
|
||||
npc.addNectar()
|
||||
npc.addGood()
|
||||
else :
|
||||
mytext = ["Не спеши! Слишком часто, я не успеваю!",
|
||||
"Я же не автомат, меня скорострельностью не напоиш",
|
||||
"Да куда же ты торопишься! Слишком часто, я не успеваю!",
|
||||
"Упс, опять слишком быстро",
|
||||
"Давай чуток помедленней, не спеши, медленно достань бутылку и медленно ее вылей!",
|
||||
"У тебя нет чувства скорости? Медленнее давай"]
|
||||
npc.broadcastPacket(CreatureSay(objectId,0,npc.getName(),mytext[Rnd.get(len(mytext))]))
|
||||
npc.addNectar()
|
||||
# Второй полив
|
||||
elif npc.getNectar() == 1 :
|
||||
if Rnd.get(2) == 1 :
|
||||
mytext = ["Желаю стать большой тыквой!",
|
||||
"Ням, ням, ням! Вышло! Заботится - хорошо!",
|
||||
"Как думаеш, я зрелая или гнилая?",
|
||||
"Нектар - только лучшее! Ха! Ха! Ха!"]
|
||||
npc.broadcastPacket(CreatureSay(objectId,0,npc.getName(),mytext[Rnd.get(len(mytext))]))
|
||||
npc.addNectar()
|
||||
npc.addGood()
|
||||
else :
|
||||
mytext = ["О! Опять мимо! Может слишком быстро расходуеш нектар?",
|
||||
"Если я умру такой как сейчас, Вы получите только молодую тыкву ...",
|
||||
"Выращивают немного быстрее! Неплохо было бы стать большой тыквой, молодая тыква не хороша!",
|
||||
"Tакую маленькую тыкву вы все должны есть? Принесите нектар, я могу быть больше!"]
|
||||
npc.broadcastPacket(CreatureSay(objectId,0,npc.getName(),mytext[Rnd.get(len(mytext))]))
|
||||
npc.addNectar()
|
||||
# Третий полив
|
||||
elif npc.getNectar() == 2 :
|
||||
if Rnd.get(2) == 1 :
|
||||
mytext = ["Tыква, изголодалась! Просит утолить жажду!",
|
||||
"Ну наконец-то ..., это действительно вкусно! Есть еще?",
|
||||
"Ухаживаешь за мной только для того, чтобы есть? Отлично, является случайным ваш ..., чтобы не дать манну на самоубийство"]
|
||||
npc.broadcastPacket(CreatureSay(objectId,0,npc.getName(),mytext[Rnd.get(len(mytext))]))
|
||||
npc.addNectar()
|
||||
npc.addGood()
|
||||
else :
|
||||
mytext = ["Не воду ли Вы добавляете? Какой вкус?",
|
||||
"Хозяин, спасите меня... Я не имею аромата нектара, я должна умереть ..."]
|
||||
npc.broadcastPacket(CreatureSay(objectId,0,npc.getName(),mytext[Rnd.get(len(mytext))]))
|
||||
npc.addNectar()
|
||||
# Четвертый полив
|
||||
elif npc.getNectar() == 3 :
|
||||
if Rnd.get(2) == 1 :
|
||||
mytext = ["Очень хорошо, делаешь чрезвычайно хорошо! Знаешь что следующим шагом должен делать?",
|
||||
"Если Вы поймаете меня, я даю Вам 10 миллионов adena!!! Согласны?"]
|
||||
npc.broadcastPacket(CreatureSay(objectId,0,npc.getName(),mytext[Rnd.get(len(mytext))]))
|
||||
npc.addNectar()
|
||||
npc.addGood()
|
||||
else :
|
||||
mytext = ["Я голодна, Tы хочеш чтоб я засохла?",
|
||||
"Tребую нектар, чтобы расти немного быстрее."]
|
||||
npc.broadcastPacket(CreatureSay(objectId,0,npc.getName(),mytext[Rnd.get(len(mytext))]))
|
||||
npc.addNectar()
|
||||
# Пятый полив
|
||||
elif npc.getNectar() == 4 :
|
||||
if Rnd.get(2) == 1 :
|
||||
npc.addGood()
|
||||
if npc.getGood() >= 3 :
|
||||
if npcId == 12774 :
|
||||
newGourd = self.addSpawn(12775,npc)
|
||||
newGourd.setOwner(player.getName())
|
||||
self.startQuestTimer("Good By", 120000, newGourd, player) # Через 2 минуты исчезновение
|
||||
self.startQuestTimer("Good By2", 90000, newGourd, player) # 30 секунд до исчезновения
|
||||
self.startQuestTimer("Good By3", 100000, newGourd, player) # 20 секунд до исчезновения
|
||||
self.startQuestTimer("Good By4", 110000, newGourd, player) # 10 секунд до исчезновения
|
||||
mytext = ["Молодая тыква, жаждящая! Как, уже выросла?",
|
||||
"Я убегу через 2 минуты"]
|
||||
npc.broadcastPacket(CreatureSay(objectId,0,npc.getName(),mytext[Rnd.get(len(mytext))]))
|
||||
npc.onDecay()
|
||||
else :
|
||||
newGourd = self.addSpawn(12778,npc)
|
||||
newGourd.setOwner(player.getName())
|
||||
self.startQuestTimer("Good By1", 120000, newGourd, player) # Через 2 минуты исчезновение
|
||||
self.startQuestTimer("Good By2", 90000, newGourd, player) # 30 секунд до исчезновения
|
||||
self.startQuestTimer("Good By3", 100000, newGourd, player) # 20 секунд до исчезновения
|
||||
self.startQuestTimer("Good By4", 110000, newGourd, player) # 10 секунд до исчезновения
|
||||
mytext = ["Милосердность является очень хорошей чертой. Tеперь посмотрите, я чувствую себя все более хорошо",
|
||||
"Я убегу через 2 минуты"]
|
||||
npc.broadcastPacket(CreatureSay(objectId,0,npc.getName(),mytext[Rnd.get(len(mytext))]))
|
||||
npc.onDecay()
|
||||
else :
|
||||
if npcId == 12774 :
|
||||
newGourd = self.addSpawn(12776,npc)
|
||||
newGourd.setOwner(player.getName())
|
||||
mytext = ["Эй! Была - не была! Есть! Сейчас же! Tы не можешь должным образом заботиться? Я же так сгнию!",
|
||||
"Ничего себе, остановки? За что тебя благодарить",
|
||||
"Жажду нектара о ...",
|
||||
"Вы хотите большую тыкву? Но я хочу остаться маленькой тыковкой ..."]
|
||||
npc.broadcastPacket(CreatureSay(objectId,0,npc.getName(),mytext[Rnd.get(len(mytext))]))
|
||||
npc.onDecay()
|
||||
if npcId == 12777 :
|
||||
newGourd = self.addSpawn(12779,npc)
|
||||
newGourd.setOwner(player.getName())
|
||||
mytext = ["Эй! Была - не была! Есть! Сейчас же! Tы не можешь должным образом заботиться? Я так сгнию!",
|
||||
"Ничего себе, остановки? За что тебя благодарить",
|
||||
"Жажду нектара о ...",
|
||||
"Вы хотите большую тыкву? Но я хочу остаться маленькой тыковкой ..."]
|
||||
npc.broadcastPacket(CreatureSay(objectId,0,npc.getName(),mytext[Rnd.get(len(mytext))]))
|
||||
npc.onDecay()
|
||||
return
|
||||
|
||||
def onAttack(self,npc,player,damage,isPet) :
|
||||
npcId = npc.getNpcId()
|
||||
objId = npc.getObjectId()
|
||||
if npcId not in WATERED_SQUASH : return
|
||||
if npcId in self.adultLargeSquash :
|
||||
if Rnd.get(30) < 2 :
|
||||
mytext = ["Укусы плетут кружево крысой ..., чтобы заменить ... тело ...!",
|
||||
"Ха ха, росла! Полностью на всех!",
|
||||
"Не можете чтоли все прицелиться? Смотрите все, чтобы не сбежала ...",
|
||||
"Я считаю ваши удары! О, напоминает удар снова!",
|
||||
"Не тратьте впустую ваше время!",
|
||||
"Ха, этот звук действительно приятно слышать?",
|
||||
"Я потребляю ваши атаки, чтобы расти!",
|
||||
"Время, чтобы ударить снова! Ударь еще разок!",
|
||||
"Tолько полезная музыка может открыть большую тыкву... Меня нельзя открыть с оружием!"]
|
||||
npc.broadcastPacket(CreatureSay(objId,0,npc.getName(),mytext[Rnd.get(len(mytext))]))
|
||||
return
|
||||
|
||||
def onKill(self,npc,player,isPet) :
|
||||
npcId = npc.getNpcId()
|
||||
objId = npc.getObjectId()
|
||||
if npcId not in WATERED_SQUASH : return
|
||||
if npcId in self.adultSmallSquash :
|
||||
npc.broadcastPacket(CreatureSay(objId,0,npc.getName(),"Tыква открывается!!"))
|
||||
npc.broadcastPacket(CreatureSay(objId,0,npc.getName(),"Ееее! Открывается! Много хороших вещей ..."))
|
||||
elif npcId in self.adultLargeSquash :
|
||||
npc.broadcastPacket(CreatureSay(objId,0,npc.getName(),"Tыква открывается!!"))
|
||||
npc.broadcastPacket(CreatureSay(objId,0,npc.getName(),"Ееее! Открывается! Много хороших вещей ..."))
|
||||
else :
|
||||
npc.broadcastPacket(CreatureSay(objId,0,npc.getName(),"За что, хозяин?!"))
|
||||
npc.broadcastPacket(CreatureSay(objId,0,npc.getName(),"Ой, кишки вывалились!!"))
|
||||
return
|
||||
|
||||
QUEST = squash(-1,"group_template","ai")
|
||||
|
||||
for i in WATERED_SQUASH:
|
||||
QUEST.addSkillUseId(i)
|
||||
QUEST.addAttackId(i)
|
||||
QUEST.addKillId(i)
|
@ -1,18 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
NoblessTrader:<br>
|
||||
Do you know the story of the seventeen heroes who challenged the Land
|
||||
Dragon Antharas? It's fascinating! Such a heroic sacrifice! It could be
|
||||
an epic poem! In fact, it's one of my all-time favorite stories! It's
|
||||
what motivated me to become a bohemian poet! It's always been my dream
|
||||
to write a great epic poem tying all the pieces of this story together.<br>
|
||||
Well forget all that because we have made the quest simple !!<br>
|
||||
I will make you Noblesse if you have a second Subclass at Level
|
||||
70+ and if you have 2 gold bars in your inventory.<br>
|
||||
<a action="bypass -h Quest 6666_NoblessTrader 31739-3.htm">"Make
|
||||
me Noblesse."</a>
|
||||
</body>
|
||||
</html>
|
@ -1,10 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
NoblessTrader:<br>
|
||||
Sorry but I will make you Noblesse only if you have a second Subclass at Level
|
||||
70+ and if you have not 2 gold bars in your inventory.<br>
|
||||
</body>
|
||||
</html>
|
@ -1,10 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
Talien:<br>
|
||||
Awesome! Thank you! For comming to see me, we have saved you a lot of
|
||||
time you are now Noblesse.! Only at Titan energy:}
|
||||
</body>
|
||||
</html>
|
@ -1,67 +0,0 @@
|
||||
import sys
|
||||
from org.l2jmobius.gameserver.model.actor.instance import L2PcInstance
|
||||
from org.l2jmobius.gameserver.model.actor.instance import L2NpcInstance
|
||||
from java.util import Iterator
|
||||
from org.l2jmobius.gameserver.model.quest import State
|
||||
from org.l2jmobius.gameserver.model.quest import QuestState
|
||||
from org.l2jmobius.gameserver.model.quest.jython import QuestJython as JQuest
|
||||
|
||||
qn = "6666_NoblessTrader"
|
||||
|
||||
NPC=[66666]
|
||||
NOBLESS_TIARA=7694
|
||||
GOLD_BAR=3470
|
||||
QuestId = 6666
|
||||
QuestName = "NoblessTrade"
|
||||
QuestDesc = "custom"
|
||||
InitialHtml = "31739-1.htm"
|
||||
|
||||
print "INFO Nobless Trader (66666) Enabled..."
|
||||
|
||||
class Quest (JQuest) :
|
||||
|
||||
def __init__(self,id,name,descr): JQuest.__init__(self,id,name,descr)
|
||||
|
||||
def onEvent(self,event,st):
|
||||
htmltext = "<html><head><body>I have nothing to say you</body></html>"
|
||||
cond = st.getInt("cond")
|
||||
count=st.getQuestItemsCount(GOLD_BAR)
|
||||
if event == "31739-3.htm" :
|
||||
if cond == 0 and st.getPlayer().isSubClassActive() :
|
||||
if st.getPlayer().getLevel() >= 70 and count > 1:
|
||||
htmltext=event
|
||||
st.set("cond","0")
|
||||
st.getPlayer().setNoble(True)
|
||||
st.giveItems(NOBLESS_TIARA,1)
|
||||
st.playSound("ItemSound.quest_finish")
|
||||
st.exitQuest(1)
|
||||
st.takeItems(GOLD_BAR,2)
|
||||
else :
|
||||
htmltext="31739-2.htm"
|
||||
st.exitQuest(1)
|
||||
else :
|
||||
htmltext="31739-2.htm"
|
||||
st.exitQuest(1)
|
||||
return htmltext
|
||||
|
||||
def onTalk (self,npc,player):
|
||||
htmltext = "<html><head><body>I have nothing to say you</body></html>"
|
||||
st = player.getQuestState(qn)
|
||||
if not st : return htmltext
|
||||
npcId = npc.getNpcId()
|
||||
id = st.getState()
|
||||
if id == State.CREATED :
|
||||
st.set("cond","0")
|
||||
htmltext="31739-1.htm"
|
||||
elif id == State.COMPLETED :
|
||||
htmltext = "<html><head><body>This quest have already been completed.</body></html>"
|
||||
else :
|
||||
st.exitQuest(1)
|
||||
return htmltext
|
||||
|
||||
|
||||
QUEST = Quest(6666,qn,"custom")
|
||||
|
||||
for npcId in NPC:
|
||||
QUEST.addStartNpc(npcId)
|
||||
QUEST.addTalkId(npcId)
|
@ -1,23 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
Clan Manager:<br>
|
||||
Do you know the story of the seventeen heroes who challenged the Land
|
||||
Dragon Antharas? It's fascinating! Such a heroic sacrifice! It could be
|
||||
an epic poem! In fact, it's one of my all-time favorite stories! It's
|
||||
what motivated me to become a bohemian poet! It's always been my dream
|
||||
to write a great epic poem tying all the pieces of this story together.<br>
|
||||
Well forget all that because we have made the quest simple !!<br>
|
||||
I will make your clan Level 8 if you are Noble and have 13 Gold Bar... <br>
|
||||
|
||||
<a action="bypass -h Quest 6667_ClanManager 66667-clanOk.htm">"Make Clan Lvl 8"</a><br>
|
||||
|
||||
I will give to your clan 3kk Reputation Points if you are Noble and 13 Gold Bar<br>
|
||||
have ...
|
||||
|
||||
<a action="bypass -h Quest 6667_ClanManager 66667-repOk.htm">"Give me 3kk Rep. Points"</a><br>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,10 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
Clan Manager:<br>
|
||||
Awesome! Thank you! For comming to see me, we have saved you a lot of
|
||||
time! Your clan has now lvl 8!!!
|
||||
</body>
|
||||
</html>
|
@ -1,10 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
Clan Manager:<br>
|
||||
Sorry but I can't give you lvl 8 Clan: check requirements!<br>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,9 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
Clan Manager:<br>
|
||||
Sorry but I can't give you 3kk Reputation Points: check requirements!<br>
|
||||
</body>
|
||||
</html>
|
@ -1,10 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
Clan Manager:<br>
|
||||
Awesome! Thank you! For comming to see me, we have saved you a lot of
|
||||
time! Your clan has now 3kk Reputation Points!!!
|
||||
</body>
|
||||
</html>
|
@ -1,76 +0,0 @@
|
||||
import sys
|
||||
from org.l2jmobius.gameserver.model.actor.instance import L2PcInstance
|
||||
from org.l2jmobius.gameserver.model.actor.instance import L2NpcInstance
|
||||
from java.util import Iterator
|
||||
from org.l2jmobius.gameserver.model.quest import State
|
||||
from org.l2jmobius.gameserver.model.quest import QuestState
|
||||
from org.l2jmobius.gameserver.model.quest.jython import QuestJython as JQuest
|
||||
|
||||
qn = "6667_ClanManager"
|
||||
|
||||
NPC=[66667]
|
||||
REQUESTED_ITEM=3470
|
||||
REQUESTED_AMOUNT=2
|
||||
NEW_REP_SCORE=3000000
|
||||
QuestId = 6667
|
||||
QuestName = "ClanManager"
|
||||
QuestDesc = "custom"
|
||||
InitialHtml = "66667-1.htm"
|
||||
|
||||
print "INFO Clan Manager (66667) Enabled..."
|
||||
|
||||
class Quest (JQuest) :
|
||||
|
||||
def __init__(self,id,name,descr): JQuest.__init__(self,id,name,descr)
|
||||
|
||||
def onEvent(self,event,st):
|
||||
htmltext = "<html><head><body>I have nothing to say you</body></html>"
|
||||
count=st.getQuestItemsCount(REQUESTED_ITEM)
|
||||
if event == "66667-clanOk.htm" :
|
||||
if st.getPlayer().isClanLeader() and st.getPlayer().getClan().getLevel()<8:
|
||||
if st.getPlayer().isNoble() and count >= REQUESTED_AMOUNT:
|
||||
htmltext=event
|
||||
st.getPlayer().getClan().changeLevel(8)
|
||||
st.playSound("ItemSound.quest_finish")
|
||||
st.takeItems(REQUESTED_ITEM,REQUESTED_AMOUNT)
|
||||
else :
|
||||
htmltext="66667-no_clan.htm"
|
||||
st.exitQuest(1)
|
||||
else :
|
||||
htmltext="66667-no_clan.htm"
|
||||
st.exitQuest(1)
|
||||
elif event == "66667-repOk.htm" :
|
||||
if st.getPlayer().isClanLeader() and st.getPlayer().getClan().getLevel() >= 5 and st.getPlayer().getClan().getReputationScore() < NEW_REP_SCORE :
|
||||
if st.getPlayer().isNoble() and count > REQUESTED_AMOUNT:
|
||||
htmltext=event
|
||||
st.getPlayer().getClan().setReputationScore(NEW_REP_SCORE, 1);
|
||||
st.playSound("ItemSound.quest_finish")
|
||||
st.takeItems(REQUESTED_ITEM,REQUESTED_AMOUNT)
|
||||
else :
|
||||
htmltext="66667-no_points.htm"
|
||||
st.exitQuest(1)
|
||||
else :
|
||||
htmltext="66667-no_points.htm"
|
||||
st.exitQuest(1)
|
||||
return htmltext
|
||||
|
||||
def onTalk (self,npc,player):
|
||||
htmltext = "<html><head><body>I have nothing to say you</body></html>"
|
||||
st = player.getQuestState(qn)
|
||||
if not st : return htmltext
|
||||
npcId = npc.getNpcId()
|
||||
id = st.getState()
|
||||
if id == State.CREATED :
|
||||
htmltext="66667-1.htm"
|
||||
elif id == State.COMPLETED :
|
||||
htmltext = "<html><head><body>This quest have already been completed.</body></html>"
|
||||
else :
|
||||
st.exitQuest(1)
|
||||
return htmltext
|
||||
|
||||
|
||||
QUEST = Quest(6667,qn,"custom")
|
||||
|
||||
for npcId in NPC:
|
||||
QUEST.addStartNpc(npcId)
|
||||
QUEST.addTalkId(npcId)
|
@ -679,7 +679,7 @@ public class QuestMasterHandler
|
||||
{
|
||||
try
|
||||
{
|
||||
quest.newInstance();
|
||||
quest.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
21
L2J_Mobius_C6_Interlude_OpenJDK12/dist/game/data/xsd/Scripts.xsd
vendored
Normal file
21
L2J_Mobius_C6_Interlude_OpenJDK12/dist/game/data/xsd/Scripts.xsd
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<xs:element name="list">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="exclude" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="include" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="file" type="xs:string" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="file" type="xs:string" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
@ -1 +1 @@
|
||||
-server -Dfile.encoding=UTF-8 -Djava.util.logging.manager=org.l2jmobius.log.ServerLogManager -Dorg.slf4j.simpleLogger.log.com.zaxxer.hikari=error -XX:+AggressiveOpts -Xnoclassgc -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseParNewGC -XX:SurvivorRatio=8 -Xmx4g -Xms2g -Xmn1g
|
||||
-server -Dfile.encoding=UTF-8 -Djava.util.logging.manager=org.l2jmobius.log.ServerLogManager -Dorg.slf4j.simpleLogger.log.com.zaxxer.hikari=error -Xnoclassgc -XX:+CMSParallelRemarkEnabled -XX:SurvivorRatio=8 -Xmx4g -Xms2g -Xmn1g
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,5 +1,5 @@
|
||||
@echo off
|
||||
title Register Game Server
|
||||
color 17
|
||||
java -version:1.8 -Djava.util.logging.config.file=console.cfg -cp ./../libs/* org.l2jmobius.tools.gsregistering.BaseGameServerRegister -c
|
||||
java -Djava.util.logging.config.file=console.cfg -cp ./../libs/* org.l2jmobius.tools.gsregistering.BaseGameServerRegister -c
|
||||
pause
|
@ -1,7 +1,7 @@
|
||||
@echo off
|
||||
title SQL Account Manager
|
||||
color 17
|
||||
java -version:1.8 -Djava.util.logging.config.file=console.cfg -cp ./../libs/* org.l2jmobius.tools.accountmanager.SQLAccountManager
|
||||
java -Djava.util.logging.config.file=console.cfg -cp ./../libs/* org.l2jmobius.tools.accountmanager.SQLAccountManager
|
||||
if %errorlevel% == 0 (
|
||||
echo.
|
||||
echo Execution successful
|
||||
|
@ -81,7 +81,6 @@ public final class Config
|
||||
private static final String PROTECT_FLOOD_CONFIG_FILE = "./config/protected/Flood.ini";
|
||||
private static final String ID_CONFIG_FILE = "./config/protected/IdFactory.ini";
|
||||
private static final String PROTECT_OTHER_CONFIG_FILE = "./config/protected/Other.ini";
|
||||
private static final String SCRIPT_CONFIG_FILE = "./config/protected/Script.ini";
|
||||
public static final String TELNET_CONFIG_FILE = "./config/protected/Telnet.ini";
|
||||
// events
|
||||
private static final String EVENT_CTF_CONFIG_FILE = "./config/events/CtF.ini";
|
||||
@ -1143,10 +1142,7 @@ public final class Config
|
||||
public static String RAID_INFO_IDS;
|
||||
public static List<Integer> RAID_INFO_IDS_LIST = new ArrayList<>();
|
||||
|
||||
public static boolean SCRIPT_DEBUG;
|
||||
public static boolean SCRIPT_ALLOW_COMPILATION;
|
||||
public static boolean SCRIPT_CACHE;
|
||||
public static boolean SCRIPT_ERROR_LOG;
|
||||
public static File SCRIPT_ROOT;
|
||||
|
||||
public static Map<String, List<String>> EXTENDERS;
|
||||
|
||||
@ -1364,6 +1360,7 @@ public final class Config
|
||||
BACKUP_DAYS = Integer.parseInt(serverSettings.getProperty("BackupDays", "30"));
|
||||
|
||||
DATAPACK_ROOT = new File(serverSettings.getProperty("DatapackRoot", ".")).getCanonicalFile();
|
||||
SCRIPT_ROOT = new File(serverSettings.getProperty("ScriptRoot", "./data/scripts").replaceAll("\\\\", "/")).getCanonicalFile();
|
||||
|
||||
final Random ppc = new Random();
|
||||
int z = ppc.nextInt(6);
|
||||
@ -3581,27 +3578,6 @@ public final class Config
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadScriptConfig()
|
||||
{
|
||||
try
|
||||
{
|
||||
final Properties scriptSetting = new Properties();
|
||||
final InputStream is = new FileInputStream(new File(SCRIPT_CONFIG_FILE));
|
||||
scriptSetting.load(is);
|
||||
is.close();
|
||||
|
||||
SCRIPT_DEBUG = Boolean.valueOf(scriptSetting.getProperty("EnableScriptDebug", "false"));
|
||||
SCRIPT_ALLOW_COMPILATION = Boolean.valueOf(scriptSetting.getProperty("AllowCompilation", "true"));
|
||||
SCRIPT_CACHE = Boolean.valueOf(scriptSetting.getProperty("UseCache", "true"));
|
||||
SCRIPT_ERROR_LOG = Boolean.valueOf(scriptSetting.getProperty("EnableScriptErrorLog", "true"));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
throw new Error("Failed to Load " + SCRIPT_CONFIG_FILE + " File.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadExtendersConfig()
|
||||
{
|
||||
EXTENDERS = new HashMap<>();
|
||||
|
@ -0,0 +1,739 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.l2jmobius.commons.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
import org.l2jmobius.Config;
|
||||
import org.l2jmobius.commons.util.file.filter.XMLFilter;
|
||||
import org.l2jmobius.gameserver.model.actor.position.Location;
|
||||
|
||||
/**
|
||||
* Interface for XML parsers.
|
||||
* @author Zoey76
|
||||
*/
|
||||
public interface IXmlReader
|
||||
{
|
||||
Logger LOGGER = Logger.getLogger(IXmlReader.class.getName());
|
||||
|
||||
String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
|
||||
String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
|
||||
/** The default file filter, ".xml" files only. */
|
||||
XMLFilter XML_FILTER = new XMLFilter();
|
||||
|
||||
/**
|
||||
* This method can be used to load/reload the data.<br>
|
||||
* It's highly recommended to clear the data storage, either the list or map.
|
||||
*/
|
||||
void load();
|
||||
|
||||
/**
|
||||
* Wrapper for {@link #parseFile(File)} method.
|
||||
* @param path the relative path to the datapack root of the XML file to parse.
|
||||
*/
|
||||
default void parseDatapackFile(String path)
|
||||
{
|
||||
parseFile(new File(Config.DATAPACK_ROOT, path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a single XML file.<br>
|
||||
* If the file was successfully parsed, call {@link #parseDocument(Document, File)} for the parsed document.<br>
|
||||
* <b>Validation is enforced.</b>
|
||||
* @param f the XML file to parse.
|
||||
*/
|
||||
default void parseFile(File f)
|
||||
{
|
||||
if (!getCurrentFileFilter().accept(f))
|
||||
{
|
||||
LOGGER.warning("Could not parse " + f.getName() + " is not a file or it doesn't exist!");
|
||||
return;
|
||||
}
|
||||
|
||||
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
dbf.setNamespaceAware(true);
|
||||
dbf.setValidating(isValidating());
|
||||
dbf.setIgnoringComments(isIgnoringComments());
|
||||
try
|
||||
{
|
||||
dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
|
||||
final DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
db.setErrorHandler(new XMLErrorHandler());
|
||||
parseDocument(db.parse(f), f);
|
||||
}
|
||||
catch (SAXParseException e)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Could not parse file: " + f.getName() + " at line: " + e.getLineNumber() + ", column: " + e.getColumnNumber() + " :", e);
|
||||
return;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Could not parse file: " + f.getName(), e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if XML validation is enabled.
|
||||
* @return {@code true} if its enabled, {@code false} otherwise
|
||||
*/
|
||||
default boolean isValidating()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if XML comments are ignored.
|
||||
* @return {@code true} if its comments are ignored, {@code false} otherwise
|
||||
*/
|
||||
default boolean isIgnoringComments()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for {@link #parseDirectory(File, boolean)}.
|
||||
* @param file the path to the directory where the XML files are.
|
||||
* @return {@code false} if it fails to find the directory, {@code true} otherwise.
|
||||
*/
|
||||
default boolean parseDirectory(File file)
|
||||
{
|
||||
return parseDirectory(file, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for {@link #parseDirectory(File, boolean)}.
|
||||
* @param path the path to the directory where the XML files are
|
||||
* @param recursive parses all sub folders if there is
|
||||
* @return {@code false} if it fails to find the directory, {@code true} otherwise
|
||||
*/
|
||||
default boolean parseDatapackDirectory(String path, boolean recursive)
|
||||
{
|
||||
return parseDirectory(new File(Config.DATAPACK_ROOT, path), recursive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all XML files from {@code path} and calls {@link #parseFile(File)} for each one of them.
|
||||
* @param dir the directory object to scan.
|
||||
* @param recursive parses all sub folders if there is.
|
||||
* @return {@code false} if it fails to find the directory, {@code true} otherwise.
|
||||
*/
|
||||
default boolean parseDirectory(File dir, boolean recursive)
|
||||
{
|
||||
if (!dir.exists())
|
||||
{
|
||||
LOGGER.warning("Folder " + dir.getAbsolutePath() + " doesn't exist!");
|
||||
return false;
|
||||
}
|
||||
|
||||
final File[] listOfFiles = dir.listFiles();
|
||||
for (File file : listOfFiles)
|
||||
{
|
||||
if (recursive && file.isDirectory())
|
||||
{
|
||||
parseDirectory(file, recursive);
|
||||
}
|
||||
else if (getCurrentFileFilter().accept(file))
|
||||
{
|
||||
parseFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method that when implemented will parse the current document.<br>
|
||||
* Is expected to be call from {@link #parseFile(File)}.
|
||||
* @param doc the current document to parse
|
||||
* @param f the current file
|
||||
*/
|
||||
void parseDocument(Document doc, File f);
|
||||
|
||||
/**
|
||||
* Parses a boolean value.
|
||||
* @param node the node to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Boolean parseBoolean(Node node, Boolean defaultValue)
|
||||
{
|
||||
return node != null ? Boolean.valueOf(node.getNodeValue()) : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a boolean value.
|
||||
* @param node the node to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Boolean parseBoolean(Node node)
|
||||
{
|
||||
return parseBoolean(node, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a boolean value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Boolean parseBoolean(NamedNodeMap attrs, String name)
|
||||
{
|
||||
return parseBoolean(attrs.getNamedItem(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a boolean value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Boolean parseBoolean(NamedNodeMap attrs, String name, Boolean defaultValue)
|
||||
{
|
||||
return parseBoolean(attrs.getNamedItem(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a byte value.
|
||||
* @param node the node to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Byte parseByte(Node node, Byte defaultValue)
|
||||
{
|
||||
return node != null ? Byte.decode(node.getNodeValue()) : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a byte value.
|
||||
* @param node the node to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Byte parseByte(Node node)
|
||||
{
|
||||
return parseByte(node, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a byte value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Byte parseByte(NamedNodeMap attrs, String name)
|
||||
{
|
||||
return parseByte(attrs.getNamedItem(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a byte value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Byte parseByte(NamedNodeMap attrs, String name, Byte defaultValue)
|
||||
{
|
||||
return parseByte(attrs.getNamedItem(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a short value.
|
||||
* @param node the node to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Short parseShort(Node node, Short defaultValue)
|
||||
{
|
||||
return node != null ? Short.decode(node.getNodeValue()) : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a short value.
|
||||
* @param node the node to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Short parseShort(Node node)
|
||||
{
|
||||
return parseShort(node, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a short value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Short parseShort(NamedNodeMap attrs, String name)
|
||||
{
|
||||
return parseShort(attrs.getNamedItem(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a short value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Short parseShort(NamedNodeMap attrs, String name, Short defaultValue)
|
||||
{
|
||||
return parseShort(attrs.getNamedItem(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an int value.
|
||||
* @param node the node to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default int parseInt(Node node, Integer defaultValue)
|
||||
{
|
||||
return node != null ? Integer.decode(node.getNodeValue()) : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an int value.
|
||||
* @param node the node to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default int parseInt(Node node)
|
||||
{
|
||||
return parseInt(node, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an integer value.
|
||||
* @param node the node to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Integer parseInteger(Node node, Integer defaultValue)
|
||||
{
|
||||
return node != null ? Integer.decode(node.getNodeValue()) : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an integer value.
|
||||
* @param node the node to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Integer parseInteger(Node node)
|
||||
{
|
||||
return parseInteger(node, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an integer value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Integer parseInteger(NamedNodeMap attrs, String name)
|
||||
{
|
||||
return parseInteger(attrs.getNamedItem(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an integer value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Integer parseInteger(NamedNodeMap attrs, String name, Integer defaultValue)
|
||||
{
|
||||
return parseInteger(attrs.getNamedItem(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a long value.
|
||||
* @param node the node to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Long parseLong(Node node, Long defaultValue)
|
||||
{
|
||||
return node != null ? Long.decode(node.getNodeValue()) : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a long value.
|
||||
* @param node the node to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Long parseLong(Node node)
|
||||
{
|
||||
return parseLong(node, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a long value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Long parseLong(NamedNodeMap attrs, String name)
|
||||
{
|
||||
return parseLong(attrs.getNamedItem(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a long value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Long parseLong(NamedNodeMap attrs, String name, Long defaultValue)
|
||||
{
|
||||
return parseLong(attrs.getNamedItem(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a float value.
|
||||
* @param node the node to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Float parseFloat(Node node, Float defaultValue)
|
||||
{
|
||||
return node != null ? Float.valueOf(node.getNodeValue()) : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a float value.
|
||||
* @param node the node to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Float parseFloat(Node node)
|
||||
{
|
||||
return parseFloat(node, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a float value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Float parseFloat(NamedNodeMap attrs, String name)
|
||||
{
|
||||
return parseFloat(attrs.getNamedItem(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a float value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Float parseFloat(NamedNodeMap attrs, String name, Float defaultValue)
|
||||
{
|
||||
return parseFloat(attrs.getNamedItem(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a double value.
|
||||
* @param node the node to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Double parseDouble(Node node, Double defaultValue)
|
||||
{
|
||||
return node != null ? Double.valueOf(node.getNodeValue()) : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a double value.
|
||||
* @param node the node to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Double parseDouble(Node node)
|
||||
{
|
||||
return parseDouble(node, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a double value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Double parseDouble(NamedNodeMap attrs, String name)
|
||||
{
|
||||
return parseDouble(attrs.getNamedItem(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a double value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Double parseDouble(NamedNodeMap attrs, String name, Double defaultValue)
|
||||
{
|
||||
return parseDouble(attrs.getNamedItem(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string value.
|
||||
* @param node the node to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default String parseString(Node node, String defaultValue)
|
||||
{
|
||||
return node != null ? node.getNodeValue() : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string value.
|
||||
* @param node the node to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default String parseString(Node node)
|
||||
{
|
||||
return parseString(node, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default String parseString(NamedNodeMap attrs, String name)
|
||||
{
|
||||
return parseString(attrs.getNamedItem(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default String parseString(NamedNodeMap attrs, String name, String defaultValue)
|
||||
{
|
||||
return parseString(attrs.getNamedItem(name), defaultValue);
|
||||
}
|
||||
|
||||
default Location parseLocation(Node n)
|
||||
{
|
||||
final NamedNodeMap attrs = n.getAttributes();
|
||||
final int x = parseInteger(attrs, "x");
|
||||
final int y = parseInteger(attrs, "y");
|
||||
final int z = parseInteger(attrs, "z");
|
||||
final int heading = parseInteger(attrs, "heading", 0);
|
||||
return new Location(x, y, z, heading);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an enumerated value.
|
||||
* @param <T> the enumerated type
|
||||
* @param node the node to parse
|
||||
* @param clazz the class of the enumerated
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null and the node value is valid the parsed value, otherwise the default value
|
||||
*/
|
||||
default <T extends Enum<T>> T parseEnum(Node node, Class<T> clazz, T defaultValue)
|
||||
{
|
||||
if (node == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return Enum.valueOf(clazz, node.getNodeValue());
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
LOGGER.warning("Invalid value specified for node: " + node.getNodeName() + " specified value: " + node.getNodeValue() + " should be enum value of \"" + clazz.getSimpleName() + "\" using default value: " + defaultValue);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an enumerated value.
|
||||
* @param <T> the enumerated type
|
||||
* @param node the node to parse
|
||||
* @param clazz the class of the enumerated
|
||||
* @return if the node is not null and the node value is valid the parsed value, otherwise null
|
||||
*/
|
||||
default <T extends Enum<T>> T parseEnum(Node node, Class<T> clazz)
|
||||
{
|
||||
return parseEnum(node, clazz, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an enumerated value.
|
||||
* @param <T> the enumerated type
|
||||
* @param attrs the attributes
|
||||
* @param clazz the class of the enumerated
|
||||
* @param name the name of the attribute to parse
|
||||
* @return if the node is not null and the node value is valid the parsed value, otherwise null
|
||||
*/
|
||||
default <T extends Enum<T>> T parseEnum(NamedNodeMap attrs, Class<T> clazz, String name)
|
||||
{
|
||||
return parseEnum(attrs.getNamedItem(name), clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an enumerated value.
|
||||
* @param <T> the enumerated type
|
||||
* @param attrs the attributes
|
||||
* @param clazz the class of the enumerated
|
||||
* @param name the name of the attribute to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null and the node value is valid the parsed value, otherwise the default value
|
||||
*/
|
||||
default <T extends Enum<T>> T parseEnum(NamedNodeMap attrs, Class<T> clazz, String name, T defaultValue)
|
||||
{
|
||||
return parseEnum(attrs.getNamedItem(name), clazz, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @return parses all attributes to a Map
|
||||
*/
|
||||
default Map<String, Object> parseAttributes(Node node)
|
||||
{
|
||||
final NamedNodeMap attrs = node.getAttributes();
|
||||
final Map<String, Object> map = new LinkedHashMap<>();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
final Node att = attrs.item(i);
|
||||
map.put(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes action for each child of node
|
||||
* @param node
|
||||
* @param action
|
||||
*/
|
||||
default void forEach(Node node, Consumer<Node> action)
|
||||
{
|
||||
forEach(node, a -> true, action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes action for each child that matches nodeName
|
||||
* @param node
|
||||
* @param nodeName
|
||||
* @param action
|
||||
*/
|
||||
default void forEach(Node node, String nodeName, Consumer<Node> action)
|
||||
{
|
||||
forEach(node, innerNode -> nodeName.equalsIgnoreCase(innerNode.getNodeName()), action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes action for each child of node if matches the filter specified
|
||||
* @param node
|
||||
* @param filter
|
||||
* @param action
|
||||
*/
|
||||
default void forEach(Node node, Predicate<Node> filter, Consumer<Node> action)
|
||||
{
|
||||
final NodeList list = node.getChildNodes();
|
||||
for (int i = 0; i < list.getLength(); i++)
|
||||
{
|
||||
final Node targetNode = list.item(i);
|
||||
if (filter.test(targetNode))
|
||||
{
|
||||
action.accept(targetNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @return {@code true} if the node is an element type, {@code false} otherwise
|
||||
*/
|
||||
static boolean isNode(Node node)
|
||||
{
|
||||
return node.getNodeType() == Node.ELEMENT_NODE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @return {@code true} if the node is an element type, {@code false} otherwise
|
||||
*/
|
||||
static boolean isText(Node node)
|
||||
{
|
||||
return node.getNodeType() == Node.TEXT_NODE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current file filter.
|
||||
* @return the current file filter
|
||||
*/
|
||||
default FileFilter getCurrentFileFilter()
|
||||
{
|
||||
return XML_FILTER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple XML error handler.
|
||||
* @author Zoey76
|
||||
*/
|
||||
class XMLErrorHandler implements ErrorHandler
|
||||
{
|
||||
@Override
|
||||
public void warning(SAXParseException e) throws SAXParseException
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(SAXParseException e) throws SAXParseException
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fatalError(SAXParseException e) throws SAXParseException
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@ public final class Rnd
|
||||
* Thread-specific random number generator.<br>
|
||||
* Each is seeded with the thread ID, so the sequence of random numbers are unique between threads.
|
||||
*/
|
||||
private static ThreadLocal<Random> RANDOM = new ThreadLocal<Random>()
|
||||
private static ThreadLocal<Random> RANDOM = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
protected Random initialValue()
|
||||
|
@ -133,8 +133,7 @@ import org.l2jmobius.gameserver.network.GameClient;
|
||||
import org.l2jmobius.gameserver.network.GamePacketHandler;
|
||||
import org.l2jmobius.gameserver.script.EventDroplist;
|
||||
import org.l2jmobius.gameserver.script.faenor.FaenorScriptEngine;
|
||||
import org.l2jmobius.gameserver.scripting.CompiledScriptCache;
|
||||
import org.l2jmobius.gameserver.scripting.L2ScriptEngineManager;
|
||||
import org.l2jmobius.gameserver.scripting.ScriptEngineManager;
|
||||
import org.l2jmobius.gameserver.taskmanager.TaskManager;
|
||||
import org.l2jmobius.gameserver.thread.LoginServerThread;
|
||||
import org.l2jmobius.gameserver.thread.daemons.DeadlockDetector;
|
||||
@ -204,7 +203,7 @@ public class GameServer
|
||||
|
||||
HtmCache.getInstance();
|
||||
CrestCache.getInstance();
|
||||
L2ScriptEngineManager.getInstance();
|
||||
ScriptEngineManager.getInstance();
|
||||
|
||||
nProtect.getInstance();
|
||||
if (nProtect.isEnabled())
|
||||
@ -438,27 +437,8 @@ public class GameServer
|
||||
Util.printSection("Scripts");
|
||||
if (!Config.ALT_DEV_NO_SCRIPT)
|
||||
{
|
||||
final File scripts = new File(Config.DATAPACK_ROOT, "data/scripts.cfg");
|
||||
L2ScriptEngineManager.getInstance().executeScriptsList(scripts);
|
||||
|
||||
final CompiledScriptCache compiledScriptCache = L2ScriptEngineManager.getInstance().getCompiledScriptCache();
|
||||
if (compiledScriptCache == null)
|
||||
{
|
||||
LOGGER.info("Compiled Scripts Cache is disabled.");
|
||||
}
|
||||
else
|
||||
{
|
||||
compiledScriptCache.purge();
|
||||
if (compiledScriptCache.isModified())
|
||||
{
|
||||
compiledScriptCache.save();
|
||||
LOGGER.info("Compiled Scripts Cache was saved.");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.info("Compiled Scripts Cache is up-to-date.");
|
||||
}
|
||||
}
|
||||
LOGGER.info("ScriptEngineManager: Loading server scripts:");
|
||||
ScriptEngineManager.getInstance().executeScriptList();
|
||||
FaenorScriptEngine.getInstance();
|
||||
}
|
||||
else
|
||||
|
@ -117,7 +117,6 @@ public class ExperienceData
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final ExperienceData INSTANCE = new ExperienceData();
|
||||
|
@ -365,7 +365,6 @@ public class ItemTable
|
||||
return _allTemplates.length;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final ItemTable INSTANCE = new ItemTable();
|
||||
|
@ -121,7 +121,6 @@ public class DocumentEngine
|
||||
return list;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final DocumentEngine INSTANCE = new DocumentEngine();
|
||||
|
@ -16,7 +16,6 @@
|
||||
*/
|
||||
package org.l2jmobius.gameserver.handler.admincommandhandlers;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.l2jmobius.Config;
|
||||
@ -33,7 +32,6 @@ import org.l2jmobius.gameserver.instancemanager.Manager;
|
||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||
import org.l2jmobius.gameserver.model.multisell.Multisell;
|
||||
import org.l2jmobius.gameserver.scripting.L2ScriptEngineManager;
|
||||
import org.l2jmobius.gameserver.util.BuilderUtil;
|
||||
|
||||
/**
|
||||
@ -153,16 +151,16 @@ public class AdminReload implements IAdminCommandHandler
|
||||
}
|
||||
else if (type.startsWith("scripts_custom"))
|
||||
{
|
||||
try
|
||||
{
|
||||
final File custom_scripts_dir = new File(Config.DATAPACK_ROOT + "/data/scripts/custom");
|
||||
L2ScriptEngineManager.getInstance().executeAllScriptsInDirectory(custom_scripts_dir, true, 3);
|
||||
}
|
||||
catch (Exception ioe)
|
||||
{
|
||||
BuilderUtil.sendSysMessage(activeChar, "Failed loading " + Config.DATAPACK_ROOT + "/data/scripts/custom scripts, no script going to be loaded");
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
// try
|
||||
// {
|
||||
// final File custom_scripts_dir = new File(Config.DATAPACK_ROOT + "/data/scripts/custom");
|
||||
// L2ScriptEngineManager.getInstance().executeAllScriptsInDirectory(custom_scripts_dir, true, 3);
|
||||
// }
|
||||
// catch (Exception ioe)
|
||||
// {
|
||||
// BuilderUtil.sendSysMessage(activeChar, "Failed loading " + Config.DATAPACK_ROOT + "/data/scripts/custom scripts, no script going to be loaded");
|
||||
// ioe.printStackTrace();
|
||||
// }
|
||||
}
|
||||
BuilderUtil.sendSysMessage(activeChar, "WARNING: There are several known issues regarding this feature. Reloading server data during runtime is STRONGLY NOT RECOMMENDED for live servers, just for developing environments.");
|
||||
}
|
||||
|
@ -20,12 +20,9 @@ import java.io.File;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.script.ScriptException;
|
||||
|
||||
import org.l2jmobius.Config;
|
||||
import org.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||
import org.l2jmobius.gameserver.scripting.L2ScriptEngineManager;
|
||||
|
||||
/**
|
||||
* @author KidZor
|
||||
@ -57,14 +54,14 @@ public class AdminScript implements IAdminCommandHandler
|
||||
|
||||
if (file.isFile())
|
||||
{
|
||||
try
|
||||
{
|
||||
L2ScriptEngineManager.getInstance().executeScript(file);
|
||||
}
|
||||
catch (ScriptException e)
|
||||
{
|
||||
L2ScriptEngineManager.getInstance().reportScriptFileError(file, e);
|
||||
}
|
||||
// try
|
||||
// {
|
||||
// L2ScriptEngineManager.getInstance().executeScript(file);
|
||||
// }
|
||||
// catch (ScriptException e)
|
||||
// {
|
||||
// ScriptEngineManager.getInstance().reportScriptFileError(file, e);
|
||||
// }
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -290,7 +290,6 @@ public class ItemsOnGroundManager
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final ItemsOnGroundManager INSTANCE = new ItemsOnGroundManager();
|
||||
|
@ -16,17 +16,13 @@
|
||||
*/
|
||||
package org.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.l2jmobius.Config;
|
||||
import org.l2jmobius.gameserver.model.quest.Quest;
|
||||
import org.l2jmobius.gameserver.scripting.L2ScriptEngineManager;
|
||||
import org.l2jmobius.gameserver.scripting.ScriptManager;
|
||||
|
||||
public class QuestManager extends ScriptManager<Quest>
|
||||
public final class QuestManager
|
||||
{
|
||||
protected static final Logger LOGGER = Logger.getLogger(QuestManager.class.getName());
|
||||
private Map<String, Quest> _quests = new HashMap<>();
|
||||
@ -76,19 +72,19 @@ public class QuestManager extends ScriptManager<Quest>
|
||||
|
||||
public final void reloadAllQuests()
|
||||
{
|
||||
LOGGER.info("Reloading Server Scripts");
|
||||
// unload all scripts
|
||||
for (Quest quest : _quests.values())
|
||||
{
|
||||
if (quest != null)
|
||||
{
|
||||
quest.unload();
|
||||
}
|
||||
}
|
||||
// now load all scripts
|
||||
final File scripts = new File(Config.DATAPACK_ROOT + "/data/scripts.cfg");
|
||||
L2ScriptEngineManager.getInstance().executeScriptsList(scripts);
|
||||
getInstance().report();
|
||||
// LOGGER.info("Reloading Server Scripts");
|
||||
//// unload all scripts
|
||||
// for (Quest quest : _quests.values())
|
||||
// {
|
||||
// if (quest != null)
|
||||
// {
|
||||
// quest.unload();
|
||||
// }
|
||||
// }
|
||||
//// now load all scripts
|
||||
// final File scripts = new File(Config.DATAPACK_ROOT + "/data/scripts.cfg");
|
||||
// ScriptEngineManager.getInstance().executeScriptsList(scripts);
|
||||
// getInstance().report();
|
||||
}
|
||||
|
||||
public final void report()
|
||||
@ -154,20 +150,17 @@ public class QuestManager extends ScriptManager<Quest>
|
||||
_instance = new QuestManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Quest> getAllManagedScripts()
|
||||
{
|
||||
return _quests.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unload(Quest ms)
|
||||
{
|
||||
ms.saveGlobalData();
|
||||
return removeQuest(ms);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getScriptManagerName()
|
||||
{
|
||||
return "QuestManager";
|
||||
|
@ -455,7 +455,6 @@ public class SiegeManager
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final SiegeManager INSTANCE = new SiegeManager();
|
||||
|
@ -117,7 +117,6 @@ public class PartyMatchRoomList
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final PartyMatchRoomList INSTANCE = new PartyMatchRoomList();
|
||||
|
@ -59,7 +59,6 @@ public class PartyMatchWaitingList
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final PartyMatchWaitingList INSTANCE = new PartyMatchWaitingList();
|
||||
|
@ -424,7 +424,6 @@ class OlympiadManager implements Runnable
|
||||
return titles;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final OlympiadManager INSTANCE = new OlympiadManager();
|
||||
|
@ -16,8 +16,7 @@
|
||||
*/
|
||||
package org.l2jmobius.gameserver.model.quest;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.file.Path;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
@ -28,6 +27,7 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -35,7 +35,6 @@ import org.l2jmobius.Config;
|
||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||
import org.l2jmobius.commons.util.Rnd;
|
||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||
import org.l2jmobius.gameserver.datatables.GmListTable;
|
||||
import org.l2jmobius.gameserver.datatables.sql.NpcTable;
|
||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||
import org.l2jmobius.gameserver.model.Party;
|
||||
@ -52,7 +51,7 @@ import org.l2jmobius.gameserver.network.serverpackets.ConfirmDlg;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import org.l2jmobius.gameserver.scripting.ManagedScript;
|
||||
import org.l2jmobius.gameserver.scripting.ScriptManager;
|
||||
import org.l2jmobius.gameserver.scripting.ScriptEngineManager;
|
||||
import org.l2jmobius.gameserver.templates.creatures.NpcTemplate;
|
||||
|
||||
/**
|
||||
@ -81,7 +80,7 @@ public class Quest extends ManagedScript
|
||||
public int[] questItemIds = null;
|
||||
|
||||
// Dimensional Diamond Rewards by Class for 2nd class transfer quest (35)
|
||||
protected static final Map<Integer, Integer> DF_REWARD_35 = new HashMap<>();
|
||||
protected static final Map<Integer, Integer> DF_REWARD_35 = new HashMap<>();
|
||||
static
|
||||
{
|
||||
DF_REWARD_35.put(1, 61);
|
||||
@ -105,7 +104,7 @@ public class Quest extends ManagedScript
|
||||
}
|
||||
|
||||
// Dimensional Diamond Rewards by Race for 2nd class transfer quest (37)
|
||||
protected static final Map<Integer, Integer> DF_REWARD_37 = new HashMap<>();
|
||||
protected static final Map<Integer, Integer> DF_REWARD_37 = new HashMap<>();
|
||||
static
|
||||
{
|
||||
DF_REWARD_37.put(0, 96);
|
||||
@ -116,7 +115,7 @@ public class Quest extends ManagedScript
|
||||
}
|
||||
|
||||
// Dimensional Diamond Rewards by Class for 2nd class transfer quest (39)
|
||||
protected static final Map<Integer, Integer> DF_REWARD_39 = new HashMap<>();
|
||||
protected static final Map<Integer, Integer> DF_REWARD_39 = new HashMap<>();
|
||||
static
|
||||
{
|
||||
DF_REWARD_39.put(1, 72);
|
||||
@ -818,43 +817,14 @@ public class Quest extends ManagedScript
|
||||
*/
|
||||
public boolean showError(Creature object, Throwable t)
|
||||
{
|
||||
if (getScriptFile() != null)
|
||||
LOGGER.log(Level.WARNING, getScriptFile().toAbsolutePath().toString(), t);
|
||||
if (t.getMessage() == null)
|
||||
{
|
||||
LOGGER.warning(getScriptFile().getAbsolutePath() + " " + t);
|
||||
LOGGER.warning(getClass().getSimpleName() + ": " + t.getMessage());
|
||||
}
|
||||
|
||||
if (object == null)
|
||||
if ((object != null) && object.isPlayer() && object.getActingPlayer().getAccessLevel().isGm())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (object instanceof PlayerInstance)
|
||||
{
|
||||
PlayerInstance player = (PlayerInstance) object;
|
||||
if (player.getAccessLevel().isGm())
|
||||
{
|
||||
final StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
|
||||
t.printStackTrace(pw);
|
||||
pw.close();
|
||||
|
||||
final String res = "<html><body><title>Script error</title>" + sw + "</body></html>";
|
||||
|
||||
return showResult(player, res);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
final StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
|
||||
t.printStackTrace(pw);
|
||||
pw.close();
|
||||
|
||||
final String res = "Script error: " + sw;
|
||||
GmListTable.broadcastMessageToGMs(res);
|
||||
|
||||
final String res = "<html><body><title>Script error</title>" + t.getMessage() + "</body></html>";
|
||||
return showResult(object, res);
|
||||
}
|
||||
return false;
|
||||
@ -1879,12 +1849,6 @@ public class Quest extends ManagedScript
|
||||
questItemIds = items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptManager<?> getScriptManager()
|
||||
{
|
||||
return QuestManager.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unload()
|
||||
{
|
||||
@ -1965,4 +1929,10 @@ public class Quest extends ManagedScript
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getScriptPath()
|
||||
{
|
||||
return ScriptEngineManager.getInstance().getCurrentLoadingScript();
|
||||
}
|
||||
}
|
||||
|
@ -1,94 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.l2jmobius.gameserver.script;
|
||||
|
||||
import javax.script.ScriptContext;
|
||||
|
||||
import org.l2jmobius.gameserver.scripting.L2ScriptEngineManager;
|
||||
|
||||
public class Expression
|
||||
{
|
||||
private final ScriptContext _context;
|
||||
|
||||
public static Object eval(String lang, String code)
|
||||
{
|
||||
try
|
||||
{
|
||||
return L2ScriptEngineManager.getInstance().eval(lang, code);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Object eval(ScriptContext context, String lang, String code)
|
||||
{
|
||||
try
|
||||
{
|
||||
return L2ScriptEngineManager.getInstance().eval(lang, code, context);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Expression create(ScriptContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new Expression(context);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Expression(ScriptContext pContext)
|
||||
{
|
||||
_context = pContext;
|
||||
}
|
||||
|
||||
public <T> void addDynamicVariable(String name, T value)
|
||||
{
|
||||
try
|
||||
{
|
||||
_context.setAttribute(name, value, ScriptContext.ENGINE_SCOPE);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeDynamicVariable(String name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_context.removeAttribute(name, ScriptContext.ENGINE_SCOPE);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,196 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.l2jmobius.gameserver.scripting;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.script.Compilable;
|
||||
import javax.script.CompiledScript;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptException;
|
||||
|
||||
/**
|
||||
* Cache of Compiled Scripts
|
||||
* @author KenM
|
||||
*/
|
||||
public class CompiledScriptCache implements Serializable
|
||||
{
|
||||
private final Map<String, CompiledScriptHolder> _compiledScriptCache = new HashMap<>();
|
||||
private transient boolean _modified = false;
|
||||
|
||||
public CompiledScript loadCompiledScript(ScriptEngine engine, File file) throws ScriptException
|
||||
{
|
||||
final int len = L2ScriptEngineManager.SCRIPT_FOLDER.getPath().length() + 1;
|
||||
final String relativeName = file.getPath().substring(len);
|
||||
|
||||
final CompiledScriptHolder csh = _compiledScriptCache.get(relativeName);
|
||||
if ((csh != null) && csh.matches(file))
|
||||
{
|
||||
return csh.getCompiledScript();
|
||||
}
|
||||
|
||||
final Compilable eng = (Compilable) engine;
|
||||
FileInputStream fis = null;
|
||||
|
||||
BufferedReader buff = null;
|
||||
InputStreamReader isr = null;
|
||||
CompiledScript cs = null;
|
||||
|
||||
try
|
||||
{
|
||||
fis = new FileInputStream(file);
|
||||
isr = new InputStreamReader(fis);
|
||||
buff = new BufferedReader(isr);
|
||||
|
||||
cs = eng.compile(buff);
|
||||
if (cs instanceof Serializable)
|
||||
{
|
||||
synchronized (_compiledScriptCache)
|
||||
{
|
||||
_compiledScriptCache.put(relativeName, new CompiledScriptHolder(cs, file));
|
||||
_modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (buff != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
buff.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (isr != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
isr.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (fis != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
fis.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cs;
|
||||
}
|
||||
|
||||
public boolean isModified()
|
||||
{
|
||||
return _modified;
|
||||
}
|
||||
|
||||
public void purge()
|
||||
{
|
||||
synchronized (_compiledScriptCache)
|
||||
{
|
||||
for (String path : _compiledScriptCache.keySet())
|
||||
{
|
||||
final File file = new File(L2ScriptEngineManager.SCRIPT_FOLDER, path);
|
||||
if (!file.isFile())
|
||||
{
|
||||
_compiledScriptCache.remove(path);
|
||||
_modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void save()
|
||||
{
|
||||
synchronized (_compiledScriptCache)
|
||||
{
|
||||
File file = null;
|
||||
FileOutputStream out = null;
|
||||
ObjectOutputStream oos = null;
|
||||
|
||||
try
|
||||
{
|
||||
file = new File(L2ScriptEngineManager.SCRIPT_FOLDER, "CompiledScripts.cache");
|
||||
out = new FileOutputStream(file);
|
||||
oos = new ObjectOutputStream(out);
|
||||
oos.writeObject(this);
|
||||
_modified = false;
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (oos != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
oos.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (out != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
out.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.l2jmobius.gameserver.scripting;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.script.CompiledScript;
|
||||
|
||||
/**
|
||||
* @author KenM
|
||||
*/
|
||||
public class CompiledScriptHolder implements Serializable
|
||||
{
|
||||
private long _lastModified;
|
||||
private long _size;
|
||||
private CompiledScript _compiledScript;
|
||||
|
||||
/**
|
||||
* @param compiledScript
|
||||
* @param lastModified
|
||||
* @param size
|
||||
*/
|
||||
public CompiledScriptHolder(CompiledScript compiledScript, long lastModified, long size)
|
||||
{
|
||||
_compiledScript = compiledScript;
|
||||
_lastModified = lastModified;
|
||||
_size = size;
|
||||
}
|
||||
|
||||
public CompiledScriptHolder(CompiledScript compiledScript, File scriptFile)
|
||||
{
|
||||
this(compiledScript, scriptFile.lastModified(), scriptFile.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the lastModified.
|
||||
*/
|
||||
public long getLastModified()
|
||||
{
|
||||
return _lastModified;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param lastModified The lastModified to set.
|
||||
*/
|
||||
public void setLastModified(long lastModified)
|
||||
{
|
||||
_lastModified = lastModified;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the size.
|
||||
*/
|
||||
public long getSize()
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param size The size to set.
|
||||
*/
|
||||
public void setSize(long size)
|
||||
{
|
||||
_size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the compiledScript.
|
||||
*/
|
||||
public CompiledScript getCompiledScript()
|
||||
{
|
||||
return _compiledScript;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param compiledScript The compiledScript to set.
|
||||
*/
|
||||
public void setCompiledScript(CompiledScript compiledScript)
|
||||
{
|
||||
_compiledScript = compiledScript;
|
||||
}
|
||||
|
||||
public boolean matches(File f)
|
||||
{
|
||||
return (f.lastModified() == _lastModified) && (f.length() == _size);
|
||||
}
|
||||
}
|
@ -1,700 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.l2jmobius.gameserver.scripting;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.InvalidClassException;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.script.Compilable;
|
||||
import javax.script.CompiledScript;
|
||||
import javax.script.ScriptContext;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineFactory;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.ScriptException;
|
||||
import javax.script.SimpleScriptContext;
|
||||
|
||||
import com.l2jserver.script.jython.JythonScriptEngine;
|
||||
|
||||
import org.l2jmobius.Config;
|
||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
||||
|
||||
/**
|
||||
* Caches script engines and provides functionality for executing and managing scripts.<BR>
|
||||
* @author KenM
|
||||
*/
|
||||
public final class L2ScriptEngineManager
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(L2ScriptEngineManager.class.getName());
|
||||
|
||||
public static final File SCRIPT_FOLDER = new File(Config.DATAPACK_ROOT.getAbsolutePath(), "data/scripts");
|
||||
|
||||
public static L2ScriptEngineManager getInstance()
|
||||
{
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
private final Map<String, ScriptEngine> _nameEngines = new HashMap<>();
|
||||
private final Map<String, ScriptEngine> _extEngines = new HashMap<>();
|
||||
private final List<ScriptManager<?>> _scriptManagers = new LinkedList<>();
|
||||
|
||||
private final CompiledScriptCache _cache;
|
||||
|
||||
private File _currentLoadingScript;
|
||||
|
||||
private L2ScriptEngineManager()
|
||||
{
|
||||
final ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
|
||||
final List<ScriptEngineFactory> factories = scriptEngineManager.getEngineFactories();
|
||||
if (Config.SCRIPT_CACHE)
|
||||
{
|
||||
_cache = loadCompiledScriptCache();
|
||||
}
|
||||
else
|
||||
{
|
||||
_cache = null;
|
||||
}
|
||||
ThreadPool.scheduleAtFixedRate(new CleaneCache(), 43200000, 43200000);
|
||||
LOGGER.info("Initializing Script Engine Manager");
|
||||
|
||||
for (ScriptEngineFactory factory : factories)
|
||||
{
|
||||
try
|
||||
{
|
||||
final ScriptEngine engine = factory.getScriptEngine();
|
||||
boolean reg = false;
|
||||
for (String name : factory.getNames())
|
||||
{
|
||||
final ScriptEngine existentEngine = _nameEngines.get(name);
|
||||
|
||||
if (existentEngine != null)
|
||||
{
|
||||
final double engineVer = Double.parseDouble(factory.getEngineVersion());
|
||||
final double existentEngVer = Double.parseDouble(existentEngine.getFactory().getEngineVersion());
|
||||
|
||||
if (engineVer <= existentEngVer)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
reg = true;
|
||||
_nameEngines.put(name, engine);
|
||||
}
|
||||
|
||||
if (reg)
|
||||
{
|
||||
LOGGER.info("Script Engine: " + factory.getEngineName() + " " + factory.getEngineVersion() + " - Language: " + factory.getLanguageName() + " - Language Version: " + factory.getLanguageVersion());
|
||||
}
|
||||
|
||||
for (String ext : factory.getExtensions())
|
||||
{
|
||||
if (!ext.equals("java") || factory.getLanguageName().equals("java"))
|
||||
{
|
||||
_extEngines.put(ext, engine);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warning("Failed initializing factory. ");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
preConfigure();
|
||||
}
|
||||
|
||||
private void preConfigure()
|
||||
{
|
||||
// Jython sys.path
|
||||
final String dataPackDirForwardSlashes = SCRIPT_FOLDER.getPath().replaceAll("\\\\", "/");
|
||||
final String configScript = "import sys;sys.path.insert(0,'" + dataPackDirForwardSlashes + "');";
|
||||
try
|
||||
{
|
||||
eval("jython", configScript);
|
||||
}
|
||||
catch (ScriptException e)
|
||||
{
|
||||
LOGGER.warning("Failed preconfiguring jython " + e);
|
||||
}
|
||||
}
|
||||
|
||||
private ScriptEngine getEngineByName(String name)
|
||||
{
|
||||
return _nameEngines.get(name);
|
||||
}
|
||||
|
||||
private ScriptEngine getEngineByExtension(String ext)
|
||||
{
|
||||
return _extEngines.get(ext);
|
||||
}
|
||||
|
||||
public void executeScriptsList(File list) throws IllegalArgumentException
|
||||
{
|
||||
if (list.isFile())
|
||||
{
|
||||
FileInputStream reader = null;
|
||||
InputStreamReader buff = null;
|
||||
LineNumberReader lnr = null;
|
||||
|
||||
try
|
||||
{
|
||||
reader = new FileInputStream(list);
|
||||
buff = new InputStreamReader(reader);
|
||||
lnr = new LineNumberReader(buff);
|
||||
|
||||
String line;
|
||||
File file;
|
||||
|
||||
while ((line = lnr.readLine()) != null)
|
||||
{
|
||||
final String[] parts = line.trim().split("#");
|
||||
|
||||
if ((parts.length > 0) && !parts[0].startsWith("#") && (parts[0].length() > 0))
|
||||
{
|
||||
line = parts[0];
|
||||
|
||||
if (line.endsWith("/**"))
|
||||
{
|
||||
line = line.substring(0, line.length() - 3);
|
||||
}
|
||||
else if (line.endsWith("/*"))
|
||||
{
|
||||
line = line.substring(0, line.length() - 2);
|
||||
}
|
||||
|
||||
file = new File(SCRIPT_FOLDER, line);
|
||||
|
||||
if (file.isDirectory() && parts[0].endsWith("/**"))
|
||||
{
|
||||
executeAllScriptsInDirectory(file, true, 32);
|
||||
}
|
||||
else if (file.isDirectory() && parts[0].endsWith("/*"))
|
||||
{
|
||||
executeAllScriptsInDirectory(file);
|
||||
}
|
||||
else if (file.isFile())
|
||||
{
|
||||
try
|
||||
{
|
||||
executeScript(file);
|
||||
}
|
||||
catch (ScriptException e)
|
||||
{
|
||||
reportScriptFileError(file, e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.warning("Failed loading: (" + file.getCanonicalPath() + ") @ " + list.getName() + ":" + lnr.getLineNumber() + " - Reason: doesnt exists or is not a file.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lnr != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
lnr.close();
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (buff != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
buff.close();
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (reader != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
reader.close();
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException("Argument must be an file containing a list of scripts to be loaded");
|
||||
}
|
||||
}
|
||||
|
||||
public void executeAllScriptsInDirectory(File dir)
|
||||
{
|
||||
executeAllScriptsInDirectory(dir, false, 0);
|
||||
}
|
||||
|
||||
public void executeAllScriptsInDirectory(File dir, boolean recurseDown, int maxDepth)
|
||||
{
|
||||
executeAllScriptsInDirectory(dir, recurseDown, maxDepth, 0);
|
||||
}
|
||||
|
||||
private void executeAllScriptsInDirectory(File dir, boolean recurseDown, int maxDepth, int currentDepth)
|
||||
{
|
||||
if (dir.isDirectory())
|
||||
{
|
||||
for (File file : dir.listFiles())
|
||||
{
|
||||
if (file.isDirectory() && recurseDown && (maxDepth > currentDepth))
|
||||
{
|
||||
if (Config.SCRIPT_DEBUG)
|
||||
{
|
||||
LOGGER.info("Entering folder: " + file.getName());
|
||||
}
|
||||
executeAllScriptsInDirectory(file, recurseDown, maxDepth, currentDepth + 1);
|
||||
}
|
||||
else if (file.isFile())
|
||||
{
|
||||
try
|
||||
{
|
||||
final String name = file.getName();
|
||||
final int lastIndex = name.lastIndexOf('.');
|
||||
String extension;
|
||||
if (lastIndex != -1)
|
||||
{
|
||||
extension = name.substring(lastIndex + 1);
|
||||
final ScriptEngine engine = getEngineByExtension(extension);
|
||||
if (engine != null)
|
||||
{
|
||||
executeScript(engine, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ScriptException e)
|
||||
{
|
||||
reportScriptFileError(file, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException("The argument directory either doesnt exists or is not an directory.");
|
||||
}
|
||||
}
|
||||
|
||||
public CompiledScriptCache getCompiledScriptCache()
|
||||
{
|
||||
return _cache;
|
||||
}
|
||||
|
||||
public CompiledScriptCache loadCompiledScriptCache()
|
||||
{
|
||||
CompiledScriptCache cache = null;
|
||||
|
||||
if (Config.SCRIPT_CACHE)
|
||||
{
|
||||
final File file = new File(SCRIPT_FOLDER, "CompiledScripts.cache");
|
||||
if (file.isFile())
|
||||
{
|
||||
FileInputStream fis = null;
|
||||
ObjectInputStream ois = null;
|
||||
try
|
||||
{
|
||||
fis = new FileInputStream(file);
|
||||
ois = new ObjectInputStream(fis);
|
||||
cache = (CompiledScriptCache) ois.readObject();
|
||||
}
|
||||
catch (InvalidClassException e)
|
||||
{
|
||||
LOGGER.warning("Failed loading Compiled Scripts Cache, invalid class (Possibly outdated). " + e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOGGER.warning("Failed loading Compiled Scripts Cache from file. " + e);
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
LOGGER.warning("Failed loading Compiled Scripts Cache, class not found. " + e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (ois != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
ois.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (fis != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
fis.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cache == null)
|
||||
{
|
||||
cache = new CompiledScriptCache();
|
||||
}
|
||||
}
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
protected class CleaneCache implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public void executeScript(File file) throws ScriptException
|
||||
{
|
||||
final String name = file.getName();
|
||||
final int lastIndex = name.lastIndexOf('.');
|
||||
String extension;
|
||||
if (lastIndex != -1)
|
||||
{
|
||||
extension = name.substring(lastIndex + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ScriptException("Script file (" + name + ") doesnt has an extension that identifies the ScriptEngine to be used.");
|
||||
}
|
||||
|
||||
final ScriptEngine engine = getEngineByExtension(extension);
|
||||
if (engine == null)
|
||||
{
|
||||
throw new ScriptException("No engine registered for extension (" + extension + ")");
|
||||
}
|
||||
executeScript(engine, file);
|
||||
}
|
||||
|
||||
public void executeScript(String engineName, File file) throws ScriptException
|
||||
{
|
||||
final ScriptEngine engine = getEngineByName(engineName);
|
||||
if (engine == null)
|
||||
{
|
||||
throw new ScriptException("No engine registered with name (" + engineName + ")");
|
||||
}
|
||||
executeScript(engine, file);
|
||||
}
|
||||
|
||||
public void executeScript(ScriptEngine engine, File file) throws ScriptException
|
||||
{
|
||||
FileInputStream reader = null;
|
||||
InputStreamReader buff = null;
|
||||
BufferedReader lnr = null;
|
||||
|
||||
try
|
||||
{
|
||||
reader = new FileInputStream(file);
|
||||
buff = new InputStreamReader(reader);
|
||||
lnr = new BufferedReader(buff);
|
||||
|
||||
if (Config.SCRIPT_DEBUG)
|
||||
{
|
||||
LOGGER.info("Loading Script: " + file.getAbsolutePath());
|
||||
}
|
||||
|
||||
if (Config.SCRIPT_ERROR_LOG)
|
||||
{
|
||||
final String name = file.getAbsolutePath() + ".error.LOGGER";
|
||||
final File errorLogger = new File(name);
|
||||
if (errorLogger.isFile())
|
||||
{
|
||||
errorLogger.delete();
|
||||
}
|
||||
}
|
||||
|
||||
if ((engine instanceof Compilable) && Config.SCRIPT_ALLOW_COMPILATION)
|
||||
{
|
||||
final ScriptContext context = new SimpleScriptContext();
|
||||
context.setAttribute("mainClass", getClassForFile(file).replace('/', '.').replace('\\', '.'), ScriptContext.ENGINE_SCOPE);
|
||||
context.setAttribute(ScriptEngine.FILENAME, file.getName(), ScriptContext.ENGINE_SCOPE);
|
||||
context.setAttribute("classpath", SCRIPT_FOLDER.getAbsolutePath(), ScriptContext.ENGINE_SCOPE);
|
||||
context.setAttribute("sourcepath", SCRIPT_FOLDER.getAbsolutePath(), ScriptContext.ENGINE_SCOPE);
|
||||
context.setAttribute(JythonScriptEngine.JYTHON_ENGINE_INSTANCE, engine, ScriptContext.ENGINE_SCOPE);
|
||||
|
||||
setCurrentLoadingScript(file);
|
||||
final ScriptContext ctx = engine.getContext();
|
||||
try
|
||||
{
|
||||
engine.setContext(context);
|
||||
if (Config.SCRIPT_CACHE)
|
||||
{
|
||||
final CompiledScript cs = _cache.loadCompiledScript(engine, file);
|
||||
cs.eval(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
final Compilable eng = (Compilable) engine;
|
||||
final CompiledScript cs = eng.compile(lnr);
|
||||
cs.eval(context);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
engine.setContext(ctx);
|
||||
setCurrentLoadingScript(null);
|
||||
context.removeAttribute(ScriptEngine.FILENAME, ScriptContext.ENGINE_SCOPE);
|
||||
context.removeAttribute("mainClass", ScriptContext.ENGINE_SCOPE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
final ScriptContext context = new SimpleScriptContext();
|
||||
context.setAttribute("mainClass", getClassForFile(file).replace('/', '.').replace('\\', '.'), ScriptContext.ENGINE_SCOPE);
|
||||
context.setAttribute(ScriptEngine.FILENAME, file.getName(), ScriptContext.ENGINE_SCOPE);
|
||||
context.setAttribute("classpath", SCRIPT_FOLDER.getAbsolutePath(), ScriptContext.ENGINE_SCOPE);
|
||||
context.setAttribute("sourcepath", SCRIPT_FOLDER.getAbsolutePath(), ScriptContext.ENGINE_SCOPE);
|
||||
setCurrentLoadingScript(file);
|
||||
try
|
||||
{
|
||||
engine.eval(lnr, context);
|
||||
}
|
||||
finally
|
||||
{
|
||||
setCurrentLoadingScript(null);
|
||||
engine.getContext().removeAttribute(ScriptEngine.FILENAME, ScriptContext.ENGINE_SCOPE);
|
||||
engine.getContext().removeAttribute("mainClass", ScriptContext.ENGINE_SCOPE);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lnr != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
lnr.close();
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (buff != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
buff.close();
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (reader != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
reader.close();
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String getClassForFile(File script)
|
||||
{
|
||||
final String path = script.getAbsolutePath();
|
||||
final String scpPath = SCRIPT_FOLDER.getAbsolutePath();
|
||||
if (path.startsWith(scpPath))
|
||||
{
|
||||
final int idx = path.lastIndexOf('.');
|
||||
return path.substring(scpPath.length() + 1, idx);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ScriptContext getScriptContext(ScriptEngine engine)
|
||||
{
|
||||
return engine.getContext();
|
||||
}
|
||||
|
||||
public ScriptContext getScriptContext(String engineName)
|
||||
{
|
||||
final ScriptEngine engine = getEngineByName(engineName);
|
||||
if (engine == null)
|
||||
{
|
||||
throw new IllegalStateException("No engine registered with name (" + engineName + ")");
|
||||
}
|
||||
return getScriptContext(engine);
|
||||
}
|
||||
|
||||
public Object eval(ScriptEngine engine, String script, ScriptContext context) throws ScriptException
|
||||
{
|
||||
if ((engine instanceof Compilable) && Config.SCRIPT_ALLOW_COMPILATION)
|
||||
{
|
||||
final Compilable eng = (Compilable) engine;
|
||||
final CompiledScript cs = eng.compile(script);
|
||||
return context != null ? cs.eval(context) : cs.eval();
|
||||
}
|
||||
return context != null ? engine.eval(script, context) : engine.eval(script);
|
||||
}
|
||||
|
||||
public Object eval(String engineName, String script) throws ScriptException
|
||||
{
|
||||
return eval(engineName, script, null);
|
||||
}
|
||||
|
||||
public Object eval(String engineName, String script, ScriptContext context) throws ScriptException
|
||||
{
|
||||
final ScriptEngine engine = getEngineByName(engineName);
|
||||
if (engine == null)
|
||||
{
|
||||
throw new ScriptException("No engine registered with name (" + engineName + ")");
|
||||
}
|
||||
return eval(engine, script, context);
|
||||
}
|
||||
|
||||
public Object eval(ScriptEngine engine, String script) throws ScriptException
|
||||
{
|
||||
return eval(engine, script, null);
|
||||
}
|
||||
|
||||
public void reportScriptFileError(File script, ScriptException e)
|
||||
{
|
||||
final String dir = script.getParent();
|
||||
final String name = script.getName() + ".error.LOGGER";
|
||||
if (dir != null)
|
||||
{
|
||||
final File file = new File(dir + "/" + name);
|
||||
FileOutputStream fos = null;
|
||||
try
|
||||
{
|
||||
if (!file.exists())
|
||||
{
|
||||
file.createNewFile();
|
||||
}
|
||||
|
||||
fos = new FileOutputStream(file);
|
||||
final String errorHeader = "Error on: " + file.getCanonicalPath() + "\r\nLine: " + e.getLineNumber() + " - Column: " + e.getColumnNumber() + "\r\n\r\n";
|
||||
fos.write(errorHeader.getBytes());
|
||||
fos.write(e.getMessage().getBytes());
|
||||
LOGGER.warning("Failed executing script: " + script.getAbsolutePath() + ". See " + file.getName() + " for details.");
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
LOGGER.warning("Failed executing script: " + script.getAbsolutePath() + "\r\n" + e.getMessage() + "Additionally failed when trying to write an error report on script directory. Reason: " + ioe.getMessage());
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (fos != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
fos.close();
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.warning("Failed executing script: " + script.getAbsolutePath() + "\r\n" + e.getMessage() + "Additionally failed when trying to write an error report on script directory.");
|
||||
}
|
||||
}
|
||||
|
||||
public void registerScriptManager(ScriptManager<?> manager)
|
||||
{
|
||||
_scriptManagers.add(manager);
|
||||
}
|
||||
|
||||
public void removeScriptManager(ScriptManager<?> manager)
|
||||
{
|
||||
_scriptManagers.remove(manager);
|
||||
}
|
||||
|
||||
public List<ScriptManager<?>> getScriptManagers()
|
||||
{
|
||||
return _scriptManagers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param currentLoadingScript The currentLoadingScript to set.
|
||||
*/
|
||||
protected void setCurrentLoadingScript(File currentLoadingScript)
|
||||
{
|
||||
_currentLoadingScript = currentLoadingScript;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the currentLoadingScript.
|
||||
*/
|
||||
protected File getCurrentLoadScript()
|
||||
{
|
||||
return _currentLoadingScript;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final L2ScriptEngineManager INSTANCE = new L2ScriptEngineManager();
|
||||
}
|
||||
}
|
@ -16,26 +16,30 @@
|
||||
*/
|
||||
package org.l2jmobius.gameserver.scripting;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.script.ScriptException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Abstract class for classes that are meant to be implemented by scripts.
|
||||
* Abstract class for classes that are meant to be implemented by scripts.<BR>
|
||||
* @author KenM
|
||||
*/
|
||||
public abstract class ManagedScript
|
||||
{
|
||||
private final File _scriptFile;
|
||||
private static final Logger LOGGER = Logger.getLogger(ManagedScript.class.getName());
|
||||
|
||||
private final Path _scriptFile;
|
||||
private long _lastLoadTime;
|
||||
private boolean _isActive;
|
||||
|
||||
public ManagedScript()
|
||||
{
|
||||
_scriptFile = L2ScriptEngineManager.getInstance().getCurrentLoadScript();
|
||||
_scriptFile = getScriptPath();
|
||||
setLastLoadTime(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public abstract Path getScriptPath();
|
||||
|
||||
/**
|
||||
* Attempts to reload this script and to refresh the necessary bindings with it ScriptControler.<BR>
|
||||
* Subclasses of this class should override this method to properly refresh their bindings when necessary.
|
||||
@ -45,11 +49,12 @@ public abstract class ManagedScript
|
||||
{
|
||||
try
|
||||
{
|
||||
L2ScriptEngineManager.getInstance().executeScript(getScriptFile());
|
||||
ScriptEngineManager.getInstance().executeScript(getScriptFile());
|
||||
return true;
|
||||
}
|
||||
catch (ScriptException e)
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Failed to reload script!", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -69,7 +74,7 @@ public abstract class ManagedScript
|
||||
/**
|
||||
* @return Returns the scriptFile.
|
||||
*/
|
||||
public File getScriptFile()
|
||||
public Path getScriptFile()
|
||||
{
|
||||
return _scriptFile;
|
||||
}
|
||||
@ -91,6 +96,4 @@ public abstract class ManagedScript
|
||||
}
|
||||
|
||||
public abstract String getScriptName();
|
||||
|
||||
public abstract ScriptManager<?> getScriptManager();
|
||||
}
|
||||
|
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.l2jmobius.gameserver.scripting;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import org.l2jmobius.Config;
|
||||
import org.l2jmobius.commons.util.IXmlReader;
|
||||
import org.l2jmobius.gameserver.scripting.java.JavaExecutionContext;
|
||||
import org.l2jmobius.gameserver.scripting.java.JavaScriptingEngine;
|
||||
|
||||
/**
|
||||
* @author Mobius
|
||||
*/
|
||||
public final class ScriptEngineManager implements IXmlReader
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(ScriptEngineManager.class.getName());
|
||||
|
||||
public static final Path SCRIPT_FOLDER = Config.SCRIPT_ROOT.toPath();
|
||||
|
||||
private static final JavaExecutionContext _javaExecutionContext = new JavaScriptingEngine().createExecutionContext();
|
||||
protected static final List<String> _exclusions = new ArrayList<>();
|
||||
|
||||
protected ScriptEngineManager()
|
||||
{
|
||||
// Load Scripts.xml
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_exclusions.clear();
|
||||
parseDatapackFile("config/protected/Scripts.xml");
|
||||
LOGGER.info("Loaded " + _exclusions.size() + " files to exclude.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc, File f)
|
||||
{
|
||||
try
|
||||
{
|
||||
final Map<String, List<String>> excludePaths = new HashMap<>();
|
||||
forEach(doc, "list", listNode -> forEach(listNode, "exclude", excludeNode ->
|
||||
{
|
||||
final String excludeFile = parseString(excludeNode.getAttributes(), "file");
|
||||
excludePaths.putIfAbsent(excludeFile, new ArrayList<>());
|
||||
|
||||
forEach(excludeNode, "include", includeNode -> excludePaths.get(excludeFile).add(parseString(includeNode.getAttributes(), "file")));
|
||||
}));
|
||||
|
||||
final int nameCount = SCRIPT_FOLDER.getNameCount();
|
||||
Files.walkFileTree(SCRIPT_FOLDER, new SimpleFileVisitor<Path>()
|
||||
{
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException
|
||||
{
|
||||
final String fileName = file.getFileName().toString();
|
||||
if (fileName.endsWith(".java"))
|
||||
{
|
||||
final Iterator<Path> relativePath = file.subpath(nameCount, file.getNameCount()).iterator();
|
||||
while (relativePath.hasNext())
|
||||
{
|
||||
final String nextPart = relativePath.next().toString();
|
||||
if (excludePaths.containsKey(nextPart))
|
||||
{
|
||||
boolean excludeScript = true;
|
||||
|
||||
final List<String> includePath = excludePaths.get(nextPart);
|
||||
if (includePath != null)
|
||||
{
|
||||
while (relativePath.hasNext())
|
||||
{
|
||||
if (includePath.contains(relativePath.next().toString()))
|
||||
{
|
||||
excludeScript = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (excludeScript)
|
||||
{
|
||||
_exclusions.add(file.toUri().getPath());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return super.visitFile(file, attrs);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (final IOException e)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Couldn't load script exclusions.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void processDirectory(File dir, List<Path> files)
|
||||
{
|
||||
for (File file : dir.listFiles())
|
||||
{
|
||||
if (file.isFile())
|
||||
{
|
||||
final String filePath = file.toURI().getPath();
|
||||
if (filePath.endsWith(".java") && !_exclusions.contains(filePath))
|
||||
{
|
||||
files.add(file.toPath().toAbsolutePath());
|
||||
}
|
||||
}
|
||||
else if (file.isDirectory())
|
||||
{
|
||||
processDirectory(file, files);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void executeScript(Path sourceFile) throws Exception
|
||||
{
|
||||
if (!sourceFile.isAbsolute())
|
||||
{
|
||||
sourceFile = SCRIPT_FOLDER.resolve(sourceFile);
|
||||
}
|
||||
|
||||
sourceFile = sourceFile.toAbsolutePath();
|
||||
|
||||
final Entry<Path, Throwable> error = _javaExecutionContext.executeScript(sourceFile);
|
||||
if (error != null)
|
||||
{
|
||||
throw new Exception("ScriptEngine: " + error.getKey() + " failed execution!", error.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public void executeScriptList() throws Exception
|
||||
{
|
||||
if (Config.ALT_DEV_NO_QUESTS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<Path> files = new ArrayList<>();
|
||||
processDirectory(SCRIPT_FOLDER.toFile(), files);
|
||||
|
||||
final Map<Path, Throwable> invokationErrors = _javaExecutionContext.executeScripts(files);
|
||||
for (Entry<Path, Throwable> entry : invokationErrors.entrySet())
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "ScriptEngine: " + entry.getKey() + " failed execution!", entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public Path getCurrentLoadingScript()
|
||||
{
|
||||
return _javaExecutionContext.getCurrentExecutingScript();
|
||||
}
|
||||
|
||||
public static ScriptEngineManager getInstance()
|
||||
{
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final ScriptEngineManager INSTANCE = new ScriptEngineManager();
|
||||
}
|
||||
}
|
@ -14,30 +14,19 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.l2jmobius.gameserver.scripting;
|
||||
package org.l2jmobius.gameserver.scripting.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author KenM
|
||||
* @param <S>
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public abstract class ScriptManager<S extends ManagedScript>
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface Disabled
|
||||
{
|
||||
public abstract Iterable<S> getAllManagedScripts();
|
||||
|
||||
public boolean reload(S ms)
|
||||
{
|
||||
return ms.reload();
|
||||
}
|
||||
|
||||
public boolean unload(S ms)
|
||||
{
|
||||
return ms.unload();
|
||||
}
|
||||
|
||||
public void setActive(S ms, boolean status)
|
||||
{
|
||||
ms.setActive(status);
|
||||
}
|
||||
|
||||
public abstract String getScriptManagerName();
|
||||
}
|
@ -0,0 +1,254 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.l2jmobius.gameserver.scripting.java;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.DiagnosticCollector;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import org.l2jmobius.gameserver.scripting.annotations.Disabled;
|
||||
|
||||
/**
|
||||
* @author HorridoJoho
|
||||
*/
|
||||
public final class JavaExecutionContext extends JavaScriptingEngine
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(JavaExecutionContext.class.getName());
|
||||
|
||||
private static final List<String> _options = new ArrayList<>();
|
||||
private static Path _currentExecutingScript;
|
||||
|
||||
JavaExecutionContext(JavaScriptingEngine engine)
|
||||
{
|
||||
// Set options.
|
||||
addOptionIfNotNull(_options, getProperty("source"), "-source");
|
||||
addOptionIfNotNull(_options, getProperty("sourcepath"), "-sourcepath");
|
||||
addOptionIfNotNull(_options, getProperty("g"), "-g:");
|
||||
|
||||
// We always set the target JVM to the current running version.
|
||||
final String targetVersion = System.getProperty("java.specification.version");
|
||||
if (!targetVersion.contains("."))
|
||||
{
|
||||
_options.add("-target");
|
||||
_options.add(targetVersion);
|
||||
}
|
||||
else
|
||||
{
|
||||
final String[] versionSplit = targetVersion.split("\\.");
|
||||
if (versionSplit.length > 1)
|
||||
{
|
||||
_options.add("-target");
|
||||
_options.add(versionSplit[0] + '.' + versionSplit[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException("Could not determine target version!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean addOptionIfNotNull(List<String> list, String nullChecked, String before)
|
||||
{
|
||||
if (nullChecked == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (before.endsWith(":"))
|
||||
{
|
||||
list.add(before + nullChecked);
|
||||
}
|
||||
else
|
||||
{
|
||||
list.add(before);
|
||||
list.add(nullChecked);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private ClassLoader determineScriptParentClassloader()
|
||||
{
|
||||
final String classloader = getProperty("classloader");
|
||||
if (classloader == null)
|
||||
{
|
||||
return ClassLoader.getSystemClassLoader();
|
||||
}
|
||||
|
||||
switch (classloader)
|
||||
{
|
||||
case "ThreadContext":
|
||||
{
|
||||
return Thread.currentThread().getContextClassLoader();
|
||||
}
|
||||
case "System":
|
||||
{
|
||||
return ClassLoader.getSystemClassLoader();
|
||||
}
|
||||
default:
|
||||
{
|
||||
try
|
||||
{
|
||||
return Class.forName(classloader).getClassLoader();
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
return ClassLoader.getSystemClassLoader();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Path, Throwable> executeScripts(Iterable<Path> sourcePaths) throws Exception
|
||||
{
|
||||
final DiagnosticCollector<JavaFileObject> fileManagerDiagnostics = new DiagnosticCollector<>();
|
||||
final DiagnosticCollector<JavaFileObject> compilationDiagnostics = new DiagnosticCollector<>();
|
||||
|
||||
try (ScriptingFileManager fileManager = new ScriptingFileManager(getCompiler().getStandardFileManager(fileManagerDiagnostics, null, StandardCharsets.UTF_8)))
|
||||
{
|
||||
// We really need an iterable of files or strings.
|
||||
final List<String> sourcePathStrings = new ArrayList<>();
|
||||
for (Path sourcePath : sourcePaths)
|
||||
{
|
||||
sourcePathStrings.add(sourcePath.toString());
|
||||
}
|
||||
|
||||
final StringWriter strOut = new StringWriter();
|
||||
final PrintWriter out = new PrintWriter(strOut);
|
||||
final boolean compilationSuccess = getCompiler().getTask(out, fileManager, compilationDiagnostics, _options, null, fileManager.getJavaFileObjectsFromStrings(sourcePathStrings)).call();
|
||||
if (!compilationSuccess)
|
||||
{
|
||||
out.println();
|
||||
out.println("----------------");
|
||||
out.println("File diagnostics");
|
||||
out.println("----------------");
|
||||
for (Diagnostic<? extends JavaFileObject> diagnostic : fileManagerDiagnostics.getDiagnostics())
|
||||
{
|
||||
out.println("\t" + diagnostic.getKind() + ": " + diagnostic.getSource().getName() + ", Line " + diagnostic.getLineNumber() + ", Column " + diagnostic.getColumnNumber());
|
||||
out.println("\t\tcode: " + diagnostic.getCode());
|
||||
out.println("\t\tmessage: " + diagnostic.getMessage(null));
|
||||
}
|
||||
|
||||
out.println();
|
||||
out.println("-----------------------");
|
||||
out.println("Compilation diagnostics");
|
||||
out.println("-----------------------");
|
||||
for (Diagnostic<? extends JavaFileObject> diagnostic : compilationDiagnostics.getDiagnostics())
|
||||
{
|
||||
out.println("\t" + diagnostic.getKind() + ": " + diagnostic.getSource().getName() + ", Line " + diagnostic.getLineNumber() + ", Column " + diagnostic.getColumnNumber());
|
||||
out.println("\t\tcode: " + diagnostic.getCode());
|
||||
out.println("\t\tmessage: " + diagnostic.getMessage(null));
|
||||
}
|
||||
|
||||
throw new RuntimeException(strOut.toString());
|
||||
}
|
||||
|
||||
final ClassLoader parentClassLoader = determineScriptParentClassloader();
|
||||
|
||||
final Map<Path, Throwable> executionFailures = new HashMap<>();
|
||||
final Iterable<ScriptingOutputFileObject> compiledClasses = fileManager.getCompiledClasses();
|
||||
for (Path sourcePath : sourcePaths)
|
||||
{
|
||||
boolean found = false;
|
||||
|
||||
for (ScriptingOutputFileObject compiledClass : compiledClasses)
|
||||
{
|
||||
final Path compiledSourcePath = compiledClass.getSourcePath();
|
||||
// sourePath can be relative, so we have to use endsWith
|
||||
if ((compiledSourcePath != null) && (compiledSourcePath.equals(sourcePath) || compiledSourcePath.endsWith(sourcePath)))
|
||||
{
|
||||
final String javaName = compiledClass.getJavaName();
|
||||
if (javaName.indexOf('$') != -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
found = true;
|
||||
_currentExecutingScript = compiledSourcePath;
|
||||
try
|
||||
{
|
||||
final ScriptingClassLoader loader = new ScriptingClassLoader(parentClassLoader, compiledClasses);
|
||||
final Class<?> javaClass = loader.loadClass(javaName);
|
||||
Method mainMethod = null;
|
||||
for (Method m : javaClass.getMethods())
|
||||
{
|
||||
if (m.getName().equals("main") && Modifier.isStatic(m.getModifiers()) && (m.getParameterCount() == 1) && (m.getParameterTypes()[0] == String[].class))
|
||||
{
|
||||
mainMethod = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((mainMethod != null) && !javaClass.isAnnotationPresent(Disabled.class))
|
||||
{
|
||||
mainMethod.invoke(null, (Object) new String[]
|
||||
{
|
||||
compiledSourcePath.toString()
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
executionFailures.put(compiledSourcePath, e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_currentExecutingScript = null;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
LOGGER.severe("Compilation successfull, but class coresponding to " + sourcePath.toString() + " not found!");
|
||||
}
|
||||
}
|
||||
|
||||
return executionFailures;
|
||||
}
|
||||
}
|
||||
|
||||
public Entry<Path, Throwable> executeScript(Path sourcePath) throws Exception
|
||||
{
|
||||
final Map<Path, Throwable> executionFailures = executeScripts(Arrays.asList(sourcePath));
|
||||
if (!executionFailures.isEmpty())
|
||||
{
|
||||
return executionFailures.entrySet().iterator().next();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final Path getCurrentExecutingScript()
|
||||
{
|
||||
return _currentExecutingScript;
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.l2jmobius.gameserver.scripting.java;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.ToolProvider;
|
||||
|
||||
/**
|
||||
* @author Mobius
|
||||
*/
|
||||
public class JavaScriptingEngine
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(JavaScriptingEngine.class.getName());
|
||||
|
||||
private final static Map<String, String> _properties = new HashMap<>();
|
||||
private final static JavaCompiler _compiler = ToolProvider.getSystemJavaCompiler();
|
||||
|
||||
public JavaScriptingEngine()
|
||||
{
|
||||
// Load config.
|
||||
Properties props = new Properties();
|
||||
try (FileInputStream fis = new FileInputStream("config/protected/ScriptEngine.ini"))
|
||||
{
|
||||
props.load(fis);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warning("Could not load ScriptEngine.ini: " + e.getMessage());
|
||||
}
|
||||
|
||||
// Set properties.
|
||||
for (Entry<Object, Object> prop : props.entrySet())
|
||||
{
|
||||
_properties.put((String) prop.getKey(), (String) prop.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public JavaExecutionContext createExecutionContext()
|
||||
{
|
||||
return new JavaExecutionContext(this);
|
||||
}
|
||||
|
||||
public final String getProperty(String key)
|
||||
{
|
||||
return _properties.get(key);
|
||||
}
|
||||
|
||||
public JavaCompiler getCompiler()
|
||||
{
|
||||
return _compiler;
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.l2jmobius.gameserver.scripting.java;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* @author HorridoJoho
|
||||
*/
|
||||
public final class ScriptingClassLoader extends ClassLoader
|
||||
{
|
||||
public static final Logger LOGGER = Logger.getLogger(ScriptingClassLoader.class.getName());
|
||||
|
||||
private Iterable<ScriptingOutputFileObject> _compiledClasses;
|
||||
|
||||
ScriptingClassLoader(ClassLoader parent, Iterable<ScriptingOutputFileObject> compiledClasses)
|
||||
{
|
||||
super(parent);
|
||||
_compiledClasses = compiledClasses;
|
||||
}
|
||||
|
||||
void removeCompiledClasses()
|
||||
{
|
||||
_compiledClasses = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException
|
||||
{
|
||||
for (ScriptingOutputFileObject compiledClass : _compiledClasses)
|
||||
{
|
||||
if (compiledClass.getJavaName().equals(name))
|
||||
{
|
||||
final byte[] classBytes = compiledClass.getJavaData();
|
||||
return defineClass(name, classBytes, 0, classBytes.length);
|
||||
}
|
||||
}
|
||||
|
||||
return super.findClass(name);
|
||||
}
|
||||
}
|
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.l2jmobius.gameserver.scripting.java;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.JavaFileObject.Kind;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
|
||||
/**
|
||||
* @author HorridoJoho
|
||||
*/
|
||||
final class ScriptingFileManager implements StandardJavaFileManager
|
||||
{
|
||||
private final StandardJavaFileManager _wrapped;
|
||||
private final LinkedList<ScriptingOutputFileObject> _classOutputs = new LinkedList<>();
|
||||
|
||||
public ScriptingFileManager(StandardJavaFileManager wrapped)
|
||||
{
|
||||
_wrapped = wrapped;
|
||||
}
|
||||
|
||||
Iterable<ScriptingOutputFileObject> getCompiledClasses()
|
||||
{
|
||||
return Collections.unmodifiableCollection(_classOutputs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int isSupportedOption(String option)
|
||||
{
|
||||
return _wrapped.isSupportedOption(option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader getClassLoader(Location location)
|
||||
{
|
||||
return _wrapped.getClassLoader(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse) throws IOException
|
||||
{
|
||||
return _wrapped.list(location, packageName, kinds, recurse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String inferBinaryName(Location location, JavaFileObject file)
|
||||
{
|
||||
return _wrapped.inferBinaryName(location, file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameFile(FileObject a, FileObject b)
|
||||
{
|
||||
return _wrapped.isSameFile(a, b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleOption(String current, Iterator<String> remaining)
|
||||
{
|
||||
return _wrapped.handleOption(current, remaining);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLocation(Location location)
|
||||
{
|
||||
return _wrapped.hasLocation(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException
|
||||
{
|
||||
return _wrapped.getJavaFileForInput(location, className, kind);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException
|
||||
{
|
||||
if (kind != Kind.CLASS)
|
||||
{
|
||||
return _wrapped.getJavaFileForOutput(location, className, kind, sibling);
|
||||
}
|
||||
|
||||
if (className.contains("/"))
|
||||
{
|
||||
className = className.replace('/', '.');
|
||||
}
|
||||
|
||||
ScriptingOutputFileObject fileObject;
|
||||
if (sibling != null)
|
||||
{
|
||||
fileObject = new ScriptingOutputFileObject(Paths.get(sibling.getName()), className, className.substring(className.lastIndexOf('.') + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
fileObject = new ScriptingOutputFileObject(null, className, className.substring(className.lastIndexOf('.') + 1));
|
||||
}
|
||||
|
||||
_classOutputs.add(fileObject);
|
||||
return fileObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException
|
||||
{
|
||||
return _wrapped.getFileForInput(location, packageName, relativeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling) throws IOException
|
||||
{
|
||||
return _wrapped.getFileForOutput(location, packageName, relativeName, sibling);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException
|
||||
{
|
||||
_wrapped.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
_wrapped.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(Iterable<? extends File> files)
|
||||
{
|
||||
return _wrapped.getJavaFileObjectsFromFiles(files);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files)
|
||||
{
|
||||
return _wrapped.getJavaFileObjects(files);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names)
|
||||
{
|
||||
return _wrapped.getJavaFileObjectsFromStrings(names);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends JavaFileObject> getJavaFileObjects(String... names)
|
||||
{
|
||||
return _wrapped.getJavaFileObjects(names);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLocation(Location location, Iterable<? extends File> path) throws IOException
|
||||
{
|
||||
_wrapped.setLocation(location, path);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends File> getLocation(Location location)
|
||||
{
|
||||
return _wrapped.getLocation(location);
|
||||
}
|
||||
}
|
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.l2jmobius.gameserver.scripting.java;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.NestingKind;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
/**
|
||||
* @author HorridoJoho
|
||||
*/
|
||||
final class ScriptingOutputFileObject implements JavaFileObject
|
||||
{
|
||||
private final Path _sourcePath;
|
||||
private final String _javaName;
|
||||
private final String _javaSimpleName;
|
||||
private final ByteArrayOutputStream _out;
|
||||
|
||||
public ScriptingOutputFileObject(Path sourcePath, String javaName, String javaSimpleName)
|
||||
{
|
||||
_sourcePath = sourcePath;
|
||||
_javaName = javaName;
|
||||
_javaSimpleName = javaSimpleName;
|
||||
_out = new ByteArrayOutputStream();
|
||||
}
|
||||
|
||||
public Path getSourcePath()
|
||||
{
|
||||
return _sourcePath;
|
||||
}
|
||||
|
||||
public String getJavaName()
|
||||
{
|
||||
return _javaName;
|
||||
}
|
||||
|
||||
public String getJavaSimpleName()
|
||||
{
|
||||
return _javaSimpleName;
|
||||
}
|
||||
|
||||
public byte[] getJavaData()
|
||||
{
|
||||
return _out.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI toUri()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream openInputStream()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream openOutputStream()
|
||||
{
|
||||
return _out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reader openReader(boolean ignoreEncodingErrors)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getCharContent(boolean ignoreEncodingErrors)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Writer openWriter()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastModified()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Kind getKind()
|
||||
{
|
||||
return Kind.CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNameCompatible(String simpleName, Kind kind)
|
||||
{
|
||||
return (kind == Kind.CLASS) && (_javaSimpleName == simpleName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NestingKind getNestingKind()
|
||||
{
|
||||
return NestingKind.TOP_LEVEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Modifier getAccessLevel()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
@ -128,7 +128,6 @@ public class AttackStanceTaskManager
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final AttackStanceTaskManager INSTANCE = new AttackStanceTaskManager();
|
||||
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.l2jmobius.gameserver.taskmanager.tasks;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.python.util.PythonInterpreter;
|
||||
|
||||
import org.l2jmobius.gameserver.taskmanager.Task;
|
||||
import org.l2jmobius.gameserver.taskmanager.TaskManager.ExecutedTask;
|
||||
|
||||
/**
|
||||
* @author Layane
|
||||
*/
|
||||
public class TaskJython extends Task
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(TaskJython.class.getName());
|
||||
public static final String NAME = "jython";
|
||||
|
||||
private final PythonInterpreter _python = new PythonInterpreter();
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeElapsed(ExecutedTask task)
|
||||
{
|
||||
_python.cleanup();
|
||||
_python.exec("import sys");
|
||||
_python.execfile("data/scripts/cron/" + task.getParams()[2]);
|
||||
LOGGER.info("[GlobalTask] Python Cleanup launched.");
|
||||
}
|
||||
}
|
@ -156,7 +156,7 @@ public class DynamicExtension
|
||||
try
|
||||
{
|
||||
final Class<?> extension = Class.forName(className, true, _classLoader);
|
||||
final Object obj = extension.newInstance();
|
||||
final Object obj = extension.getDeclaredConstructor().newInstance();
|
||||
extension.getMethod("init", new Class[0]).invoke(obj, new Object[0]);
|
||||
LOGGER.info("Extension " + className + " loaded.");
|
||||
_loadedExtensions.put(className, obj);
|
||||
|
@ -29,7 +29,7 @@ import org.l2jmobius.tools.dbinstaller.gui.DBConfigGUI;
|
||||
*/
|
||||
public class LauncherGS extends AbstractDBLauncher
|
||||
{
|
||||
public static void main(String[] args)
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
final String defDatabase = "l2jmobiusc6";
|
||||
final String dir = "sql/game/";
|
||||
|
@ -29,7 +29,7 @@ import org.l2jmobius.tools.dbinstaller.gui.DBConfigGUI;
|
||||
*/
|
||||
public class LauncherLS extends AbstractDBLauncher
|
||||
{
|
||||
public static void main(String[] args)
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
final String defDatabase = "l2jmobiusc6";
|
||||
final String dir = "sql/login/";
|
||||
|
@ -32,9 +32,9 @@ public class DBInstallerConsole implements DBOutputInterface
|
||||
{
|
||||
Connection _con;
|
||||
|
||||
public DBInstallerConsole(String db, String dir)
|
||||
public DBInstallerConsole(String db, String dir) throws Exception
|
||||
{
|
||||
System.out.println("Welcome to L2J DataBase installer");
|
||||
System.out.println("Welcome to DataBase installer");
|
||||
final Preferences prop = Preferences.userRoot();
|
||||
RunTasks rt = null;
|
||||
try (Scanner scn = new Scanner(new CloseShieldedInputStream(System.in)))
|
||||
@ -98,8 +98,9 @@ public class DBInstallerConsole implements DBOutputInterface
|
||||
* @param pass the password
|
||||
* @param database the database name
|
||||
* @param mode the mode, c: Clean, u:update
|
||||
* @throws Exception
|
||||
*/
|
||||
public DBInstallerConsole(String defDatabase, String dir, String host, String port, String user, String pass, String database, String mode)
|
||||
public DBInstallerConsole(String defDatabase, String dir, String host, String port, String user, String pass, String database, String mode) throws Exception
|
||||
{
|
||||
if ((database == null) || database.isEmpty())
|
||||
{
|
||||
|
@ -138,9 +138,17 @@ public class DBConfigGUI extends JFrame
|
||||
|
||||
final ActionListener connectListener = e ->
|
||||
{
|
||||
final MySqlConnect connector = new MySqlConnect(_dbHost.getText(), _dbPort.getText(), _dbUser.getText(), new String(_dbPass.getPassword()), _dbDbse.getText(), false);
|
||||
MySqlConnect connector = null;
|
||||
try
|
||||
{
|
||||
connector = new MySqlConnect(_dbHost.getText(), _dbPort.getText(), _dbUser.getText(), new String(_dbPass.getPassword()), _dbDbse.getText(), false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
if (connector.getConnection() != null)
|
||||
if ((connector != null) && (connector.getConnection() != null))
|
||||
{
|
||||
_prop.put("dbHost_" + _db, _dbHost.getText());
|
||||
_prop.put("dbPort_" + _db, _dbPort.getText());
|
||||
@ -193,6 +201,8 @@ public class DBConfigGUI extends JFrame
|
||||
add(btnConnect);
|
||||
|
||||
SpringUtilities.makeCompactGrid(getContentPane(), 6, 2, 5, 5, 5, 5);
|
||||
|
||||
pack();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,6 +78,9 @@ public class DBInstallerGUI extends JFrame implements DBOutputInterface
|
||||
appendToProgressArea("Connected");
|
||||
|
||||
add(scrollPane, BorderLayout.CENTER);
|
||||
|
||||
getContentPane().setPreferredSize(new Dimension(width, height));
|
||||
pack();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -31,11 +31,11 @@ public class MySqlConnect
|
||||
{
|
||||
Connection con = null;
|
||||
|
||||
public MySqlConnect(String host, String port, String user, String password, String db, boolean console)
|
||||
public MySqlConnect(String host, String port, String user, String password, String db, boolean console) throws Exception
|
||||
{
|
||||
try (Formatter form = new Formatter())
|
||||
{
|
||||
Class.forName("org.mariadb.jdbc.Driver").newInstance();
|
||||
Class.forName("org.mariadb.jdbc.Driver").getDeclaredConstructor().newInstance();
|
||||
final String formattedText = form.format("jdbc:mariadb://%1$s:%2$s", host, port).toString();
|
||||
con = DriverManager.getConnection(formattedText, user, password);
|
||||
|
||||
|
@ -1,18 +1,32 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle or the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package org.l2jmobius.tools.dbinstaller.util.swing;
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
L2J-Mobius Interlude
|
||||
L2J-Mobius Interlude (OpenJDK 12)
|
||||
[All existing python scripts do not work.]
|
||||
|
||||
Client: https://drive.google.com/uc?id=1LcKCQTbRXJvteJcuvc_rnX8i2gT1fcHB&export=download
|
||||
Geodata: http://www.mediafire.com/file/xdpoj68vrx8hp5u/L2J_Mobius_C6_Interlude_Geodata.zip
|
||||
JDK: http://www.mediafire.com/file/ffc3trl5axsl2kt/jdk-8u181-windows-x64.exe
|
||||
JDK: https://www.mediafire.com/file/k25pt0umuf16uoh/openjdk-12.0.2_windows-x64_bin.zip
|
||||
|
||||
|
||||
Prelude: http://legacy.lineage2.com/news/career.html
|
||||
@ -84,8 +85,6 @@ Dueling system.
|
||||
|
||||
|
||||
TODO:
|
||||
Rewrite Python scripts to Java.
|
||||
Use Java 10.
|
||||
Convert CSV files to XML.
|
||||
Drop knownlists -> Use L2World.
|
||||
Drop MmoCore -> Use Netty.
|
||||
|
Loading…
Reference in New Issue
Block a user