Synced ScriptEngineManager changes from Test to HighFive.
This commit is contained in:
39
L2J_Mobius_HighFive/dist/game/config/ScriptEngines.ini
vendored
Normal file
39
L2J_Mobius_HighFive/dist/game/config/ScriptEngines.ini
vendored
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
###############################################################################
|
||||||
|
# Properties retrived with System.getProperty(String) can be used as values
|
||||||
|
# by enclosing the property name with %. Eg.: %java.class.path%
|
||||||
|
#
|
||||||
|
# You can set a property for a scripting engine by language name.
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
# language.Java.source=1.8
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# L2J_JavaEngine #####################
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
# The prefered java compiler api to use.
|
||||||
|
# The value is a fully qualified name of a class which implements the javax.toold.JavaCompiler and has a zero argument constructor.
|
||||||
|
# When the prefered compiler is not set, the first found compiler is used.
|
||||||
|
# When the prefered compiler is not found, the last found compiler is used.
|
||||||
|
language.Java.preferedCompiler=com.sun.tools.javac.api.JavacTool
|
||||||
|
language.Java.preferedCompiler=org.eclipse.jdt.internal.compiler.tool.EclipseCompiler
|
||||||
|
|
||||||
|
# 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
|
||||||
|
language.Java.classloader=System
|
||||||
|
#language.Java.classloader=ThreadContext
|
||||||
|
|
||||||
|
# Source compatibility
|
||||||
|
language.Java.source=1.8
|
||||||
|
|
||||||
|
# The java sourcepath, when you have a different datapack root, you must change this too.
|
||||||
|
language.Java.sourcepath=data/scripts
|
||||||
|
|
||||||
|
# The java classpath
|
||||||
|
language.Java.cp=%java.class.path%
|
||||||
|
|
||||||
|
# The debug informations to generate for compiled class files
|
||||||
|
language.Java.g=source,lines,vars
|
@@ -31,7 +31,7 @@ import com.l2jmobius.gameserver.network.serverpackets.ExCubeGameTeamList;
|
|||||||
* Handys Block Checker Event AI.
|
* Handys Block Checker Event AI.
|
||||||
* @authors BiggBoss, Gigiikun
|
* @authors BiggBoss, Gigiikun
|
||||||
*/
|
*/
|
||||||
final class HandysBlockCheckerEvent extends Quest
|
public final class HandysBlockCheckerEvent extends Quest
|
||||||
{
|
{
|
||||||
// Arena Managers
|
// Arena Managers
|
||||||
private static final int A_MANAGER_1 = 32521;
|
private static final int A_MANAGER_1 = 32521;
|
||||||
|
@@ -32,7 +32,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Fantasy Isle Parade
|
* Fantasy Isle Parade
|
||||||
* @author JOJO, Pandragon
|
* @author JOJO, Pandragon
|
||||||
*/
|
*/
|
||||||
final class Parade extends AbstractNpcAI
|
public final class Parade extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
final int[] ACTORS =
|
final int[] ACTORS =
|
||||||
|
@@ -36,7 +36,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Talent Show AI.
|
* Talent Show AI.
|
||||||
* @author Kerberos
|
* @author Kerberos
|
||||||
*/
|
*/
|
||||||
final class TalentShow extends AbstractNpcAI
|
public final class TalentShow extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
private static int MC = 32433;
|
private static int MC = 32433;
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
|
@@ -32,7 +32,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Anais AI.
|
* Anais AI.
|
||||||
* @author nonom
|
* @author nonom
|
||||||
*/
|
*/
|
||||||
final class Anais extends AbstractNpcAI
|
public final class Anais extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// NPCs
|
// NPCs
|
||||||
private static final int ANAIS = 25701;
|
private static final int ANAIS = 25701;
|
||||||
|
@@ -30,7 +30,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Ballista AI.
|
* Ballista AI.
|
||||||
* @author St3eT
|
* @author St3eT
|
||||||
*/
|
*/
|
||||||
final class Ballista extends AbstractNpcAI
|
public final class Ballista extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// NPCs
|
// NPCs
|
||||||
private static final int[] BALLISTA =
|
private static final int[] BALLISTA =
|
||||||
|
@@ -54,7 +54,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Beleth's AI.
|
* Beleth's AI.
|
||||||
* @author Treat, Sahar
|
* @author Treat, Sahar
|
||||||
*/
|
*/
|
||||||
final class Beleth extends AbstractNpcAI
|
public final class Beleth extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// Status
|
// Status
|
||||||
private static final int ALIVE = 0;
|
private static final int ALIVE = 0;
|
||||||
|
@@ -37,7 +37,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Core AI.
|
* Core AI.
|
||||||
* @author DrLecter, Emperorc
|
* @author DrLecter, Emperorc
|
||||||
*/
|
*/
|
||||||
final class Core extends AbstractNpcAI
|
public final class Core extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
private static final int CORE = 29006;
|
private static final int CORE = 29006;
|
||||||
private static final int DEATH_KNIGHT = 29007;
|
private static final int DEATH_KNIGHT = 29007;
|
||||||
|
@@ -28,7 +28,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* AI for Kamaloka (33) - Crimson Hatu Otis
|
* AI for Kamaloka (33) - Crimson Hatu Otis
|
||||||
* @author Gladicek
|
* @author Gladicek
|
||||||
*/
|
*/
|
||||||
final class CrimsonHatuOtis extends AbstractNpcAI
|
public final class CrimsonHatuOtis extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// Npc
|
// Npc
|
||||||
private static final int CRIMSON_HATU_OTIS = 18558;
|
private static final int CRIMSON_HATU_OTIS = 18558;
|
||||||
|
@@ -32,7 +32,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
/**
|
/**
|
||||||
* Dark Water Dragon's AI.
|
* Dark Water Dragon's AI.
|
||||||
*/
|
*/
|
||||||
final class DarkWaterDragon extends AbstractNpcAI
|
public final class DarkWaterDragon extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
private static final int DRAGON = 22267;
|
private static final int DRAGON = 22267;
|
||||||
private static final int SHADE1 = 22268;
|
private static final int SHADE1 = 22268;
|
||||||
|
@@ -26,7 +26,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Simple AI that manages special conditions for Divine Beast summon.
|
* Simple AI that manages special conditions for Divine Beast summon.
|
||||||
* @author UnAfraid
|
* @author UnAfraid
|
||||||
*/
|
*/
|
||||||
final class DivineBeast extends AbstractNpcAI
|
public final class DivineBeast extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
private static final int DIVINE_BEAST = 14870;
|
private static final int DIVINE_BEAST = 14870;
|
||||||
private static final int TRANSFORMATION_ID = 258;
|
private static final int TRANSFORMATION_ID = 258;
|
||||||
|
@@ -32,7 +32,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Manages minion's spawn, idle despawn and Teleportation Cube spawn.
|
* Manages minion's spawn, idle despawn and Teleportation Cube spawn.
|
||||||
* @author GKR
|
* @author GKR
|
||||||
*/
|
*/
|
||||||
final class Epidos extends AbstractNpcAI
|
public final class Epidos extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
private static final int[] EPIDOSES =
|
private static final int[] EPIDOSES =
|
||||||
{
|
{
|
||||||
|
@@ -27,7 +27,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Eva's Gift Box AI.
|
* Eva's Gift Box AI.
|
||||||
* @author St3eT
|
* @author St3eT
|
||||||
*/
|
*/
|
||||||
final class EvasGiftBox extends AbstractNpcAI
|
public final class EvasGiftBox extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// NPC
|
// NPC
|
||||||
private static final int BOX = 32342; // Eva's Gift Box
|
private static final int BOX = 32342; // Eva's Gift Box
|
||||||
|
@@ -32,7 +32,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Frightened Ragna Orc AI.
|
* Frightened Ragna Orc AI.
|
||||||
* @author Gladicek, malyelfik
|
* @author Gladicek, malyelfik
|
||||||
*/
|
*/
|
||||||
final class FrightenedRagnaOrc extends AbstractNpcAI
|
public final class FrightenedRagnaOrc extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// NPC ID
|
// NPC ID
|
||||||
private static final int MOB_ID = 18807;
|
private static final int MOB_ID = 18807;
|
||||||
|
@@ -27,7 +27,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Gordon AI
|
* Gordon AI
|
||||||
* @author TOFIZ, malyelfik
|
* @author TOFIZ, malyelfik
|
||||||
*/
|
*/
|
||||||
final class Gordon extends AbstractNpcAI
|
public final class Gordon extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
private static final int GORDON = 29095;
|
private static final int GORDON = 29095;
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* </ul>
|
* </ul>
|
||||||
* @author Zealar
|
* @author Zealar
|
||||||
*/
|
*/
|
||||||
final class GraveRobbers extends AbstractNpcAI
|
public final class GraveRobbers extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
private static final int GRAVE_ROBBER_SUMMONER = 22678;
|
private static final int GRAVE_ROBBER_SUMMONER = 22678;
|
||||||
private static final int GRAVE_ROBBER_MEGICIAN = 22679;
|
private static final int GRAVE_ROBBER_MEGICIAN = 22679;
|
||||||
|
@@ -45,7 +45,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Orfen's AI
|
* Orfen's AI
|
||||||
* @author Emperorc
|
* @author Emperorc
|
||||||
*/
|
*/
|
||||||
final class Orfen extends AbstractNpcAI
|
public final class Orfen extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
private static final Location[] POS =
|
private static final Location[] POS =
|
||||||
{
|
{
|
||||||
|
@@ -45,7 +45,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Queen Ant's AI
|
* Queen Ant's AI
|
||||||
* @author Emperorc
|
* @author Emperorc
|
||||||
*/
|
*/
|
||||||
final class QueenAnt extends AbstractNpcAI
|
public final class QueenAnt extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
private static final int QUEEN = 29001;
|
private static final int QUEEN = 29001;
|
||||||
private static final int LARVA = 29002;
|
private static final int LARVA = 29002;
|
||||||
|
@@ -30,7 +30,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Queen Shyeed AI
|
* Queen Shyeed AI
|
||||||
* @author malyelfik
|
* @author malyelfik
|
||||||
*/
|
*/
|
||||||
final class QueenShyeed extends AbstractNpcAI
|
public final class QueenShyeed extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// NPC
|
// NPC
|
||||||
private static final int SHYEED = 25671;
|
private static final int SHYEED = 25671;
|
||||||
|
@@ -24,7 +24,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Ragna Orc Commander AI.
|
* Ragna Orc Commander AI.
|
||||||
* @author Zealar
|
* @author Zealar
|
||||||
*/
|
*/
|
||||||
final class RagnaOrcCommander extends AbstractNpcAI
|
public final class RagnaOrcCommander extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
private static final int RAGNA_ORC_COMMANDER = 22694;
|
private static final int RAGNA_ORC_COMMANDER = 22694;
|
||||||
|
|
||||||
|
@@ -24,7 +24,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Ragna Orc Hero AI.
|
* Ragna Orc Hero AI.
|
||||||
* @author Zealar
|
* @author Zealar
|
||||||
*/
|
*/
|
||||||
final class RagnaOrcHero extends AbstractNpcAI
|
public final class RagnaOrcHero extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
private static final int RAGNA_ORC_HERO = 22693;
|
private static final int RAGNA_ORC_HERO = 22693;
|
||||||
|
|
||||||
|
@@ -24,7 +24,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Ragna Orc Seer AI.
|
* Ragna Orc Seer AI.
|
||||||
* @author Zealar
|
* @author Zealar
|
||||||
*/
|
*/
|
||||||
final class RagnaOrcSeer extends AbstractNpcAI
|
public final class RagnaOrcSeer extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
private static final int RAGNA_ORC_SEER = 22697;
|
private static final int RAGNA_ORC_SEER = 22697;
|
||||||
|
|
||||||
|
@@ -39,7 +39,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
/**
|
/**
|
||||||
* @author Micr0, Zerox
|
* @author Micr0, Zerox
|
||||||
*/
|
*/
|
||||||
final class ScarletVanHalisha extends AbstractNpcAI
|
public final class ScarletVanHalisha extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
private L2Character _target;
|
private L2Character _target;
|
||||||
private Skill _skill;
|
private Skill _skill;
|
||||||
|
@@ -36,7 +36,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Sin Eater AI.
|
* Sin Eater AI.
|
||||||
* @author St3eT.
|
* @author St3eT.
|
||||||
*/
|
*/
|
||||||
final class SinEater extends AbstractNpcAI
|
public final class SinEater extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// NPCs
|
// NPCs
|
||||||
private static final int SIN_EATER = 12564;
|
private static final int SIN_EATER = 12564;
|
||||||
|
@@ -32,7 +32,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Manages Sin Wardens disappearing and chat.
|
* Manages Sin Wardens disappearing and chat.
|
||||||
* @author GKR
|
* @author GKR
|
||||||
*/
|
*/
|
||||||
final class SinWardens extends AbstractNpcAI
|
public final class SinWardens extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
private static final int[] SIN_WARDEN_MINIONS =
|
private static final int[] SIN_WARDEN_MINIONS =
|
||||||
{
|
{
|
||||||
|
@@ -41,7 +41,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Venom AI on Rune Castle.
|
* Venom AI on Rune Castle.
|
||||||
* @author nonom, MELERIX
|
* @author nonom, MELERIX
|
||||||
*/
|
*/
|
||||||
final class Venom extends AbstractNpcAI
|
public final class Venom extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
private static final int CASTLE = 8; // Rune
|
private static final int CASTLE = 8; // Rune
|
||||||
|
|
||||||
|
@@ -31,7 +31,7 @@ import quests.Q00185_NikolasCooperation.Q00185_NikolasCooperation;
|
|||||||
* Alarm AI for quests Art of Persuasion (184) and Nikola's Cooperation (185).
|
* Alarm AI for quests Art of Persuasion (184) and Nikola's Cooperation (185).
|
||||||
* @author Zoey76
|
* @author Zoey76
|
||||||
*/
|
*/
|
||||||
final class Alarm extends AbstractNpcAI
|
public final class Alarm extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// NPC
|
// NPC
|
||||||
private static final int ALARM = 32367;
|
private static final int ALARM = 32367;
|
||||||
|
@@ -32,7 +32,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Alexandria (Armor Merchant) AI.
|
* Alexandria (Armor Merchant) AI.
|
||||||
* @author xban1x
|
* @author xban1x
|
||||||
*/
|
*/
|
||||||
final class Alexandria extends AbstractNpcAI
|
public final class Alexandria extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// NPC
|
// NPC
|
||||||
private static final int ALEXANDRIA = 30098;
|
private static final int ALEXANDRIA = 30098;
|
||||||
|
@@ -29,7 +29,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Arena Manager AI.
|
* Arena Manager AI.
|
||||||
* @author St3eT
|
* @author St3eT
|
||||||
*/
|
*/
|
||||||
final class ArenaManager extends AbstractNpcAI
|
public final class ArenaManager extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// NPCs
|
// NPCs
|
||||||
private static final int[] ARENA_MANAGER =
|
private static final int[] ARENA_MANAGER =
|
||||||
|
@@ -29,7 +29,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Castle Ambassador AI.
|
* Castle Ambassador AI.
|
||||||
* @author St3eT
|
* @author St3eT
|
||||||
*/
|
*/
|
||||||
final class CastleAmbassador extends AbstractNpcAI
|
public final class CastleAmbassador extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// NPCs
|
// NPCs
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
|
@@ -27,7 +27,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Castle Blacksmith AI.
|
* Castle Blacksmith AI.
|
||||||
* @author malyelfik
|
* @author malyelfik
|
||||||
*/
|
*/
|
||||||
final class CastleBlacksmith extends AbstractNpcAI
|
public final class CastleBlacksmith extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// Blacksmith IDs
|
// Blacksmith IDs
|
||||||
private static final int[] NPCS =
|
private static final int[] NPCS =
|
||||||
|
@@ -25,7 +25,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Castle Siege Manager AI.
|
* Castle Siege Manager AI.
|
||||||
* @author St3eT
|
* @author St3eT
|
||||||
*/
|
*/
|
||||||
final class CastleSiegeManager extends AbstractNpcAI
|
public final class CastleSiegeManager extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// NPCs
|
// NPCs
|
||||||
private static final int[] SIEGE_MANAGER =
|
private static final int[] SIEGE_MANAGER =
|
||||||
|
@@ -31,7 +31,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Castle Teleporter AI.
|
* Castle Teleporter AI.
|
||||||
* @author malyelfik
|
* @author malyelfik
|
||||||
*/
|
*/
|
||||||
final class CastleTeleporter extends AbstractNpcAI
|
public final class CastleTeleporter extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// Teleporter IDs
|
// Teleporter IDs
|
||||||
private static final int[] NPCS =
|
private static final int[] NPCS =
|
||||||
|
@@ -25,7 +25,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Castle Warehouse Keeper AI.
|
* Castle Warehouse Keeper AI.
|
||||||
* @author malyelfik
|
* @author malyelfik
|
||||||
*/
|
*/
|
||||||
final class CastleWarehouse extends AbstractNpcAI
|
public final class CastleWarehouse extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// NPCs
|
// NPCs
|
||||||
private static final int[] NPCS =
|
private static final int[] NPCS =
|
||||||
|
@@ -29,7 +29,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Clan Trader AI.
|
* Clan Trader AI.
|
||||||
* @author St3eT
|
* @author St3eT
|
||||||
*/
|
*/
|
||||||
final class ClanTrader extends AbstractNpcAI
|
public final class ClanTrader extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// Npc
|
// Npc
|
||||||
private static final int[] CLAN_TRADER =
|
private static final int[] CLAN_TRADER =
|
||||||
|
@@ -27,7 +27,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Fame Manager AI.
|
* Fame Manager AI.
|
||||||
* @author St3eT
|
* @author St3eT
|
||||||
*/
|
*/
|
||||||
final class FameManager extends AbstractNpcAI
|
public final class FameManager extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// Npc
|
// Npc
|
||||||
private static final int[] FAME_MANAGER =
|
private static final int[] FAME_MANAGER =
|
||||||
|
@@ -27,7 +27,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Forge of the Gods AI
|
* Forge of the Gods AI
|
||||||
* @author nonom, malyelfik
|
* @author nonom, malyelfik
|
||||||
*/
|
*/
|
||||||
final class ForgeOfTheGods extends AbstractNpcAI
|
public final class ForgeOfTheGods extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// NPCs
|
// NPCs
|
||||||
private static final int[] FOG_MOBS =
|
private static final int[] FOG_MOBS =
|
||||||
|
@@ -29,7 +29,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Rooney AI
|
* Rooney AI
|
||||||
* @author malyelfik
|
* @author malyelfik
|
||||||
*/
|
*/
|
||||||
final class Rooney extends AbstractNpcAI
|
public final class Rooney extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// NPC
|
// NPC
|
||||||
private static final int ROONEY = 32049;
|
private static final int ROONEY = 32049;
|
||||||
|
@@ -25,7 +25,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Fortress Archer Captain AI.
|
* Fortress Archer Captain AI.
|
||||||
* @author St3eT
|
* @author St3eT
|
||||||
*/
|
*/
|
||||||
final class FortressArcherCaptain extends AbstractNpcAI
|
public final class FortressArcherCaptain extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// NPCs
|
// NPCs
|
||||||
private static final int[] ARCHER_CAPTAIN =
|
private static final int[] ARCHER_CAPTAIN =
|
||||||
|
@@ -33,7 +33,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Fortress Siege Manager AI.
|
* Fortress Siege Manager AI.
|
||||||
* @author St3eT
|
* @author St3eT
|
||||||
*/
|
*/
|
||||||
final class FortressSiegeManager extends AbstractNpcAI
|
public final class FortressSiegeManager extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// NPCs
|
// NPCs
|
||||||
private static final int[] MANAGERS =
|
private static final int[] MANAGERS =
|
||||||
|
@@ -26,7 +26,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Freya's Steward AI.
|
* Freya's Steward AI.
|
||||||
* @author Adry_85
|
* @author Adry_85
|
||||||
*/
|
*/
|
||||||
final class FreyasSteward extends AbstractNpcAI
|
public final class FreyasSteward extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// NPC
|
// NPC
|
||||||
private static final int FREYAS_STEWARD = 32029;
|
private static final int FREYAS_STEWARD = 32029;
|
||||||
|
@@ -27,7 +27,7 @@ import quests.Q10286_ReunionWithSirra.Q10286_ReunionWithSirra;
|
|||||||
* Jinia AI.
|
* Jinia AI.
|
||||||
* @author Adry_85
|
* @author Adry_85
|
||||||
*/
|
*/
|
||||||
final class Jinia extends AbstractNpcAI
|
public final class Jinia extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
// NPC
|
// NPC
|
||||||
private static final int JINIA = 32781;
|
private static final int JINIA = 32781;
|
||||||
|
@@ -32,7 +32,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Original Jython script by Emperorc and Kerberos_20.
|
* Original Jython script by Emperorc and Kerberos_20.
|
||||||
* @authors Nyaran
|
* @authors Nyaran
|
||||||
*/
|
*/
|
||||||
final class KetraOrcSupport extends AbstractNpcAI
|
public final class KetraOrcSupport extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
private static class BuffsData
|
private static class BuffsData
|
||||||
{
|
{
|
||||||
|
@@ -39,7 +39,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Monastery Minigame AI.
|
* Monastery Minigame AI.
|
||||||
* @author nonom
|
* @author nonom
|
||||||
*/
|
*/
|
||||||
final class Minigame extends AbstractNpcAI
|
public final class Minigame extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
private static final int SUMIEL = 32758;
|
private static final int SUMIEL = 32758;
|
||||||
private static final int BURNER = 18913;
|
private static final int BURNER = 18913;
|
||||||
|
@@ -32,7 +32,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* Original Jython script by Emperorc and Kerberos_20.
|
* Original Jython script by Emperorc and Kerberos_20.
|
||||||
* @author Nyaran
|
* @author Nyaran
|
||||||
*/
|
*/
|
||||||
final class VarkaSilenosSupport extends AbstractNpcAI
|
public final class VarkaSilenosSupport extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
private static class BuffsData
|
private static class BuffsData
|
||||||
{
|
{
|
||||||
|
@@ -32,7 +32,7 @@ import ai.npc.AbstractNpcAI;
|
|||||||
* None of them provide actual class transfers, they only talk about it.
|
* None of them provide actual class transfers, they only talk about it.
|
||||||
* @author jurchiks, xban1x
|
* @author jurchiks, xban1x
|
||||||
*/
|
*/
|
||||||
final class FirstClassTransferTalk extends AbstractNpcAI
|
public final class FirstClassTransferTalk extends AbstractNpcAI
|
||||||
{
|
{
|
||||||
private static final Map<Integer, Race> MASTERS = new HashMap<>();
|
private static final Map<Integer, Race> MASTERS = new HashMap<>();
|
||||||
static
|
static
|
||||||
|
@@ -40,6 +40,7 @@ import com.l2jmobius.gameserver.model.Location;
|
|||||||
import com.l2jmobius.gameserver.model.TeleportWhereType;
|
import com.l2jmobius.gameserver.model.TeleportWhereType;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||||
|
import com.l2jmobius.gameserver.model.entity.Siegable;
|
||||||
import com.l2jmobius.gameserver.model.entity.clanhall.ClanHallSiegeEngine;
|
import com.l2jmobius.gameserver.model.entity.clanhall.ClanHallSiegeEngine;
|
||||||
import com.l2jmobius.gameserver.model.entity.clanhall.SiegeStatus;
|
import com.l2jmobius.gameserver.model.entity.clanhall.SiegeStatus;
|
||||||
import com.l2jmobius.gameserver.model.zone.type.L2ResidenceHallTeleportZone;
|
import com.l2jmobius.gameserver.model.zone.type.L2ResidenceHallTeleportZone;
|
||||||
@@ -498,17 +499,20 @@ public abstract class FlagWar extends ClanHallSiegeEngine
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Schedule open doors closement and siege start in 2 minutes
|
// Schedule open doors closement and siege start in 2 minutes
|
||||||
ThreadPoolManager.getInstance().scheduleGeneral(new CloseOutterDoorsTask(), 300000);
|
ThreadPoolManager.getInstance().scheduleGeneral(new CloseOutterDoorsTask(this), 300000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runnable class to schedule doors closing and siege start.
|
* Runnable class to schedule doors closing and siege start.
|
||||||
* @author Zoey76
|
* @author Zoey76
|
||||||
*/
|
*/
|
||||||
private class CloseOutterDoorsTask implements Runnable
|
protected class CloseOutterDoorsTask implements Runnable
|
||||||
{
|
{
|
||||||
public CloseOutterDoorsTask()
|
private final Siegable _siegable;
|
||||||
|
|
||||||
|
protected CloseOutterDoorsTask(Siegable clanHallSiege)
|
||||||
{
|
{
|
||||||
|
_siegable = clanHallSiege;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -520,7 +524,8 @@ public abstract class FlagWar extends ClanHallSiegeEngine
|
|||||||
}
|
}
|
||||||
|
|
||||||
_hall.getZone().banishNonSiegeParticipants();
|
_hall.getZone().banishNonSiegeParticipants();
|
||||||
_hall.getSiege().startSiege();
|
|
||||||
|
_siegable.startSiege();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -16,12 +16,13 @@
|
|||||||
*/
|
*/
|
||||||
package handlers.admincommandhandlers;
|
package handlers.admincommandhandlers;
|
||||||
|
|
||||||
import java.io.File;
|
import java.nio.file.Paths;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
import java.util.logging.Level;
|
||||||
import javax.script.ScriptException;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||||
import com.l2jmobius.gameserver.instancemanager.QuestManager;
|
import com.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
@@ -33,11 +34,12 @@ import com.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
|||||||
import com.l2jmobius.gameserver.model.quest.Quest;
|
import com.l2jmobius.gameserver.model.quest.Quest;
|
||||||
import com.l2jmobius.gameserver.model.quest.QuestTimer;
|
import com.l2jmobius.gameserver.model.quest.QuestTimer;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||||
import com.l2jmobius.gameserver.scripting.L2ScriptEngineManager;
|
import com.l2jmobius.gameserver.scripting.ScriptEngineManager;
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
import com.l2jmobius.gameserver.util.Util;
|
||||||
|
|
||||||
public class AdminQuest implements IAdminCommandHandler
|
public class AdminQuest implements IAdminCommandHandler
|
||||||
{
|
{
|
||||||
|
public static final Logger LOGGER = Logger.getLogger(AdminQuest.class.getName());
|
||||||
private static final String[] ADMIN_COMMANDS =
|
private static final String[] ADMIN_COMMANDS =
|
||||||
{
|
{
|
||||||
"admin_quest_reload",
|
"admin_quest_reload",
|
||||||
@@ -47,139 +49,89 @@ public class AdminQuest implements IAdminCommandHandler
|
|||||||
"admin_quest_info"
|
"admin_quest_info"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private Quest findScript(String script)
|
||||||
|
{
|
||||||
|
if (Util.isDigit(script))
|
||||||
|
{
|
||||||
|
return QuestManager.getInstance().getQuest(Integer.parseInt(script));
|
||||||
|
}
|
||||||
|
return QuestManager.getInstance().getQuest(script);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean useAdminCommand(String command, L2PcInstance activeChar)
|
public boolean useAdminCommand(String command, L2PcInstance activeChar)
|
||||||
{
|
{
|
||||||
if (activeChar == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// syntax will either be:
|
|
||||||
// //quest_reload <id>
|
|
||||||
// //quest_reload <questName>
|
|
||||||
// The questName MUST start with a non-numeric character for this to work,
|
|
||||||
// regardless which of the two formats is used.
|
|
||||||
// Example: //quest_reload orc_occupation_change_1
|
|
||||||
// Example: //quest_reload chests
|
|
||||||
// Example: //quest_reload SagasSuperclass
|
|
||||||
// Example: //quest_reload 12
|
|
||||||
if (command.startsWith("admin_quest_reload"))
|
if (command.startsWith("admin_quest_reload"))
|
||||||
{
|
{
|
||||||
final String[] parts = command.split(" ");
|
StringTokenizer st = new StringTokenizer(command);
|
||||||
if (parts.length < 2)
|
st.nextToken(); // skip command token
|
||||||
|
|
||||||
|
if (!st.hasMoreTokens())
|
||||||
{
|
{
|
||||||
activeChar.sendMessage("Usage: //quest_reload <questFolder>.<questSubFolders...>.questName> or //quest_reload <id>");
|
activeChar.sendMessage("Usage: //quest_reload <questName> or <questId>");
|
||||||
}
|
return false;
|
||||||
else
|
|
||||||
{
|
|
||||||
// try the first param as id
|
|
||||||
try
|
|
||||||
{
|
|
||||||
final int questId = Integer.parseInt(parts[1]);
|
|
||||||
if (QuestManager.getInstance().reload(questId))
|
|
||||||
{
|
|
||||||
activeChar.sendMessage("Quest Reloaded Successfully.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
activeChar.sendMessage("Quest Reloaded Failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e)
|
|
||||||
{
|
|
||||||
if (QuestManager.getInstance().reload(parts[1]))
|
|
||||||
{
|
|
||||||
activeChar.sendMessage("Quest Reloaded Successfully.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
activeChar.sendMessage("Quest Reloaded Failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// script load should NOT be used in place of reload. If a script is already loaded
|
|
||||||
// successfully, quest_reload ought to be used. The script_load command should only
|
|
||||||
// be used for scripts that failed to load altogether (eg. due to errors) or that
|
|
||||||
// did not at all exist during server boot. Using script_load to re-load a previously
|
|
||||||
// loaded script may cause unpredictable script flow, minor loss of data, and more.
|
|
||||||
// This provides a way to load new scripts without having to reboot the server.
|
|
||||||
else if (command.startsWith("admin_script_load"))
|
|
||||||
{
|
|
||||||
final String[] parts = command.split(" ");
|
|
||||||
if (parts.length < 2)
|
|
||||||
{
|
|
||||||
// activeChar.sendMessage("Example: //script_load <questFolder>/<questSubFolders...>/<filename>.<ext> ");
|
|
||||||
activeChar.sendMessage("Example: //script_load quests/SagasSuperclass/__init__.py");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
File file = new File(L2ScriptEngineManager.SCRIPT_FOLDER, parts[1]);
|
|
||||||
// Trying to reload by script name.
|
|
||||||
if (!file.exists())
|
|
||||||
{
|
|
||||||
final Quest quest = QuestManager.getInstance().getQuest(parts[1]);
|
|
||||||
if (quest != null)
|
|
||||||
{
|
|
||||||
file = new File(L2ScriptEngineManager.SCRIPT_FOLDER, quest.getClass().getName().replaceAll("\\.", "/") + ".java");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reloading by full path
|
|
||||||
if (file.isFile())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
L2ScriptEngineManager.getInstance().executeScript(file);
|
|
||||||
|
|
||||||
// This part should be called only when the script is successfully loaded.
|
|
||||||
activeChar.sendMessage("Script Successfully Loaded.");
|
|
||||||
}
|
|
||||||
catch (ScriptException e)
|
|
||||||
{
|
|
||||||
activeChar.sendMessage("Failed loading: " + parts[1]);
|
|
||||||
L2ScriptEngineManager.getInstance().reportScriptFileError(file, e);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
activeChar.sendMessage("Failed loading: " + parts[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
activeChar.sendMessage("File Not Found: " + parts[1]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String script = st.nextToken();
|
||||||
|
Quest quest = findScript(script);
|
||||||
|
if (quest == null)
|
||||||
|
{
|
||||||
|
activeChar.sendMessage("The script " + script + " couldn't be found!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!quest.reload())
|
||||||
|
{
|
||||||
|
activeChar.sendMessage("Failed to reload " + script + "!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
activeChar.sendMessage("Script successful reloaded.");
|
||||||
|
}
|
||||||
|
else if (command.startsWith("admin_script_load"))
|
||||||
|
{
|
||||||
|
StringTokenizer st = new StringTokenizer(command);
|
||||||
|
st.nextToken(); // skip command token
|
||||||
|
|
||||||
|
if (!st.hasMoreTokens())
|
||||||
|
{
|
||||||
|
activeChar.sendMessage("Usage: //script_load path/to/script.java");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String script = st.nextToken();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ScriptEngineManager.getInstance().executeScript(Paths.get(script));
|
||||||
|
activeChar.sendMessage("Script loaded seccessful!");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
activeChar.sendMessage("Failed to load script!");
|
||||||
|
LOGGER.log(Level.WARNING, "Failed to load script " + script + "!", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (command.startsWith("admin_script_unload"))
|
else if (command.startsWith("admin_script_unload"))
|
||||||
{
|
{
|
||||||
final String[] parts = command.split(" ");
|
StringTokenizer st = new StringTokenizer(command);
|
||||||
if (parts.length < 2)
|
st.nextToken(); // skip command token
|
||||||
|
|
||||||
|
if (!st.hasMoreTokens())
|
||||||
{
|
{
|
||||||
activeChar.sendMessage("Example: //script_unload questName/questId");
|
activeChar.sendMessage("Usage: //script_load path/to/script.java");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
String script = st.nextToken();
|
||||||
|
Quest quest = findScript(script);
|
||||||
|
if (quest == null)
|
||||||
{
|
{
|
||||||
final Quest q = Util.isDigit(parts[1]) ? QuestManager.getInstance().getQuest(Integer.parseInt(parts[1])) : QuestManager.getInstance().getQuest(parts[1]);
|
activeChar.sendMessage("The script " + script + " couldn't be found!");
|
||||||
|
return false;
|
||||||
if (q != null)
|
|
||||||
{
|
|
||||||
if (q.unload())
|
|
||||||
{
|
|
||||||
activeChar.sendMessage("Script Successfully Unloaded [" + q.getName() + "/" + q.getId() + "]");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
activeChar.sendMessage("Failed unloading [" + q.getName() + "/" + q.getId() + "].");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
activeChar.sendMessage("The quest [" + parts[1] + "] was not found!.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
quest.unload();
|
||||||
|
activeChar.sendMessage("Script successful unloaded!");
|
||||||
}
|
}
|
||||||
else if (command.startsWith("admin_show_quests"))
|
else if (command.startsWith("admin_show_quests"))
|
||||||
{
|
{
|
||||||
|
@@ -18,8 +18,8 @@ package handlers.admincommandhandlers;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
import java.util.logging.Level;
|
||||||
import javax.script.ScriptException;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.gameserver.cache.HtmCache;
|
import com.l2jmobius.gameserver.cache.HtmCache;
|
||||||
@@ -41,7 +41,7 @@ import com.l2jmobius.gameserver.instancemanager.QuestManager;
|
|||||||
import com.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import com.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.scripting.L2ScriptEngineManager;
|
import com.l2jmobius.gameserver.scripting.ScriptEngineManager;
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
import com.l2jmobius.gameserver.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -49,6 +49,8 @@ import com.l2jmobius.gameserver.util.Util;
|
|||||||
*/
|
*/
|
||||||
public class AdminReload implements IAdminCommandHandler
|
public class AdminReload implements IAdminCommandHandler
|
||||||
{
|
{
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(AdminReload.class.getName());
|
||||||
|
|
||||||
private static final String[] ADMIN_COMMANDS =
|
private static final String[] ADMIN_COMMANDS =
|
||||||
{
|
{
|
||||||
"admin_reload"
|
"admin_reload"
|
||||||
@@ -204,31 +206,29 @@ public class AdminReload implements IAdminCommandHandler
|
|||||||
}
|
}
|
||||||
case "effect":
|
case "effect":
|
||||||
{
|
{
|
||||||
final File file = new File(L2ScriptEngineManager.SCRIPT_FOLDER, "handlers/EffectMasterHandler.java");
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
L2ScriptEngineManager.getInstance().executeScript(file);
|
ScriptEngineManager.getInstance().executeEffectMasterHandler();
|
||||||
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Effects.");
|
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded effect master handler.");
|
||||||
}
|
}
|
||||||
catch (ScriptException e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
L2ScriptEngineManager.getInstance().reportScriptFileError(file, e);
|
LOGGER.log(Level.WARNING, "Failed executing effect master handler!", e);
|
||||||
activeChar.sendMessage("There was an error while loading handlers.");
|
activeChar.sendMessage("Error reloading effect master handler!");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "handler":
|
case "handler":
|
||||||
{
|
{
|
||||||
final File file = new File(L2ScriptEngineManager.SCRIPT_FOLDER, "handlers/MasterHandler.java");
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
L2ScriptEngineManager.getInstance().executeScript(file);
|
ScriptEngineManager.getInstance().executeMasterHandler();
|
||||||
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Handlers.");
|
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded master handler.");
|
||||||
}
|
}
|
||||||
catch (ScriptException e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
L2ScriptEngineManager.getInstance().reportScriptFileError(file, e);
|
LOGGER.log(Level.WARNING, "Failed executing master handler!", e);
|
||||||
activeChar.sendMessage("There was an error while loading handlers.");
|
activeChar.sendMessage("Error reloading master handler!");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -261,5 +261,4 @@ public class AdminReload implements IAdminCommandHandler
|
|||||||
{
|
{
|
||||||
return ADMIN_COMMANDS;
|
return ADMIN_COMMANDS;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -16,12 +16,11 @@
|
|||||||
*/
|
*/
|
||||||
package handlers.telnethandlers;
|
package handlers.telnethandlers;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.nio.file.Paths;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
import java.util.logging.Level;
|
||||||
import javax.script.ScriptException;
|
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.cache.HtmCache;
|
import com.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import com.l2jmobius.gameserver.data.sql.impl.TeleportLocationTable;
|
import com.l2jmobius.gameserver.data.sql.impl.TeleportLocationTable;
|
||||||
@@ -36,7 +35,7 @@ import com.l2jmobius.gameserver.instancemanager.QuestManager;
|
|||||||
import com.l2jmobius.gameserver.instancemanager.RaidBossSpawnManager;
|
import com.l2jmobius.gameserver.instancemanager.RaidBossSpawnManager;
|
||||||
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.scripting.L2ScriptEngineManager;
|
import com.l2jmobius.gameserver.scripting.ScriptEngineManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author UnAfraid
|
* @author UnAfraid
|
||||||
@@ -116,29 +115,16 @@ public class ReloadHandler implements ITelnetHandler
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
final String questPath = st.hasMoreTokens() ? st.nextToken() : "";
|
String questPath = st.hasMoreTokens() ? st.nextToken() : "";
|
||||||
|
|
||||||
final File file = new File(L2ScriptEngineManager.SCRIPT_FOLDER, questPath);
|
try
|
||||||
if (file.isFile())
|
|
||||||
{
|
{
|
||||||
try
|
ScriptEngineManager.getInstance().executeScript(Paths.get(questPath));
|
||||||
{
|
_print.println(questPath + " was successfully loaded!\n");
|
||||||
L2ScriptEngineManager.getInstance().executeScript(file);
|
|
||||||
_print.println(file.getName() + " was successfully loaded!\n");
|
|
||||||
}
|
|
||||||
catch (ScriptException e)
|
|
||||||
{
|
|
||||||
_print.println("Failed loading: " + questPath);
|
|
||||||
L2ScriptEngineManager.getInstance().reportScriptFileError(file, e);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_print.println("Failed loading: " + questPath);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_print.println(file.getName() + " is not a file in: " + questPath);
|
_log.log(Level.WARNING, "Failed to execute script!", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (StringIndexOutOfBoundsException e)
|
catch (StringIndexOutOfBoundsException e)
|
||||||
|
@@ -134,7 +134,7 @@ import com.l2jmobius.gameserver.model.olympiad.Olympiad;
|
|||||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||||
import com.l2jmobius.gameserver.network.L2GamePacketHandler;
|
import com.l2jmobius.gameserver.network.L2GamePacketHandler;
|
||||||
import com.l2jmobius.gameserver.pathfinding.PathFinding;
|
import com.l2jmobius.gameserver.pathfinding.PathFinding;
|
||||||
import com.l2jmobius.gameserver.scripting.L2ScriptEngineManager;
|
import com.l2jmobius.gameserver.scripting.ScriptEngineManager;
|
||||||
import com.l2jmobius.gameserver.taskmanager.KnownListUpdateTaskManager;
|
import com.l2jmobius.gameserver.taskmanager.KnownListUpdateTaskManager;
|
||||||
import com.l2jmobius.gameserver.taskmanager.TaskManager;
|
import com.l2jmobius.gameserver.taskmanager.TaskManager;
|
||||||
import com.l2jmobius.status.Status;
|
import com.l2jmobius.status.Status;
|
||||||
@@ -171,8 +171,8 @@ public final class GameServer
|
|||||||
new File("log/game").mkdirs();
|
new File("log/game").mkdirs();
|
||||||
|
|
||||||
// load script engines
|
// load script engines
|
||||||
printSection("Engines");
|
printSection("Scripting Engines");
|
||||||
L2ScriptEngineManager.getInstance();
|
ScriptEngineManager.getInstance();
|
||||||
|
|
||||||
printSection("World");
|
printSection("World");
|
||||||
// start game time control early
|
// start game time control early
|
||||||
@@ -294,15 +294,12 @@ public final class GameServer
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_log.info(getClass().getSimpleName() + ": Loading server scripts:");
|
_log.info("Loading server scripts...");
|
||||||
if (!Config.ALT_DEV_NO_HANDLERS || !Config.ALT_DEV_NO_QUESTS)
|
ScriptEngineManager.getInstance().executeScriptList();
|
||||||
{
|
|
||||||
L2ScriptEngineManager.getInstance().executeScriptList(new File(Config.DATAPACK_ROOT, "data/scripts.cfg"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (IOException ioe)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_log.severe(getClass().getSimpleName() + ": Failed loading scripts.cfg, scripts are not going to be loaded!");
|
_log.log(Level.WARNING, "Failed to execute script list!", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpawnTable.getInstance().load();
|
SpawnTable.getInstance().load();
|
||||||
|
@@ -16,12 +16,11 @@
|
|||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.handler;
|
package com.l2jmobius.gameserver.handler;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import com.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import com.l2jmobius.gameserver.scripting.L2ScriptEngineManager;
|
import com.l2jmobius.gameserver.scripting.ScriptEngineManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author BiggBoss, UnAfraid
|
* @author BiggBoss, UnAfraid
|
||||||
@@ -63,7 +62,7 @@ public final class EffectHandler implements IHandler<Class<? extends AbstractEff
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
L2ScriptEngineManager.getInstance().executeScript(new File(L2ScriptEngineManager.SCRIPT_FOLDER, "handlers/EffectMasterHandler.java"));
|
ScriptEngineManager.getInstance().executeEffectMasterHandler();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@@ -16,8 +16,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.instancemanager;
|
package com.l2jmobius.gameserver.instancemanager;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@@ -25,15 +23,14 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.gameserver.model.quest.Quest;
|
import com.l2jmobius.gameserver.model.quest.Quest;
|
||||||
import com.l2jmobius.gameserver.scripting.L2ScriptEngineManager;
|
import com.l2jmobius.gameserver.scripting.ScriptEngineManager;
|
||||||
import com.l2jmobius.gameserver.scripting.ScriptManager;
|
|
||||||
import com.l2jmobius.util.Util;
|
import com.l2jmobius.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Quests and scripts manager.
|
* Quests and scripts manager.
|
||||||
* @author Zoey76
|
* @author Zoey76
|
||||||
*/
|
*/
|
||||||
public final class QuestManager extends ScriptManager<Quest>
|
public final class QuestManager
|
||||||
{
|
{
|
||||||
protected static final Logger _log = Logger.getLogger(QuestManager.class.getName());
|
protected static final Logger _log = Logger.getLogger(QuestManager.class.getName());
|
||||||
|
|
||||||
@@ -93,9 +90,9 @@ public final class QuestManager extends ScriptManager<Quest>
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
L2ScriptEngineManager.getInstance().executeScriptList(new File(Config.DATAPACK_ROOT, "data/scripts.cfg"));
|
ScriptEngineManager.getInstance().executeScriptList();
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_log.log(Level.SEVERE, getClass().getSimpleName() + ": Failed loading scripts.cfg, no script going to be loaded!", e);
|
_log.log(Level.SEVERE, getClass().getSimpleName() + ": Failed loading scripts.cfg, no script going to be loaded!", e);
|
||||||
}
|
}
|
||||||
@@ -216,24 +213,16 @@ public final class QuestManager extends ScriptManager<Quest>
|
|||||||
return _quests;
|
return _quests;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean unload(Quest ms)
|
public boolean unload(Quest ms)
|
||||||
{
|
{
|
||||||
ms.saveGlobalData();
|
ms.saveGlobalData();
|
||||||
return removeScript(ms);
|
return removeScript(ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getScriptManagerName()
|
|
||||||
{
|
|
||||||
return getClass().getSimpleName();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all the registered scripts.
|
* Gets all the registered scripts.
|
||||||
* @return all the scripts
|
* @return all the scripts
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public Map<String, Quest> getScripts()
|
public Map<String, Quest> getScripts()
|
||||||
{
|
{
|
||||||
return _scripts;
|
return _scripts;
|
||||||
|
@@ -16,7 +16,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.model.events;
|
package com.l2jmobius.gameserver.model.events;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -33,8 +32,6 @@ import java.util.function.Function;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.script.ScriptException;
|
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.gameserver.GameTimeController;
|
import com.l2jmobius.gameserver.GameTimeController;
|
||||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
@@ -112,7 +109,6 @@ import com.l2jmobius.gameserver.model.events.returns.AbstractEventReturn;
|
|||||||
import com.l2jmobius.gameserver.model.events.returns.TerminateReturn;
|
import com.l2jmobius.gameserver.model.events.returns.TerminateReturn;
|
||||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import com.l2jmobius.gameserver.model.interfaces.INamable;
|
|
||||||
import com.l2jmobius.gameserver.model.interfaces.IPositionable;
|
import com.l2jmobius.gameserver.model.interfaces.IPositionable;
|
||||||
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
import com.l2jmobius.gameserver.model.itemcontainer.PcInventory;
|
import com.l2jmobius.gameserver.model.itemcontainer.PcInventory;
|
||||||
@@ -130,26 +126,21 @@ import com.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
|
|||||||
import com.l2jmobius.gameserver.network.serverpackets.SpecialCamera;
|
import com.l2jmobius.gameserver.network.serverpackets.SpecialCamera;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
|
import com.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||||
import com.l2jmobius.gameserver.scripting.L2ScriptEngineManager;
|
import com.l2jmobius.gameserver.scripting.ManagedScript;
|
||||||
import com.l2jmobius.gameserver.scripting.ScriptManager;
|
|
||||||
import com.l2jmobius.gameserver.util.MinionList;
|
import com.l2jmobius.gameserver.util.MinionList;
|
||||||
import com.l2jmobius.util.Rnd;
|
import com.l2jmobius.util.Rnd;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract script.
|
* @author UnAfraid
|
||||||
* @author KenM, UnAfraid, Zoey76
|
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractScript implements INamable
|
public abstract class AbstractScript extends ManagedScript
|
||||||
{
|
{
|
||||||
public static final Logger _log = Logger.getLogger(AbstractScript.class.getName());
|
public static final Logger _log = Logger.getLogger(AbstractScript.class.getName());
|
||||||
private final Map<ListenerRegisterType, Set<Integer>> _registeredIds = new ConcurrentHashMap<>();
|
private final Map<ListenerRegisterType, Set<Integer>> _registeredIds = new ConcurrentHashMap<>();
|
||||||
private final List<AbstractEventListener> _listeners = new CopyOnWriteArrayList<>();
|
private final List<AbstractEventListener> _listeners = new CopyOnWriteArrayList<>();
|
||||||
private final File _scriptFile;
|
|
||||||
private boolean _isActive;
|
|
||||||
|
|
||||||
public AbstractScript()
|
public AbstractScript()
|
||||||
{
|
{
|
||||||
_scriptFile = L2ScriptEngineManager.getInstance().getCurrentLoadingScript();
|
|
||||||
initializeAnnotationListeners();
|
initializeAnnotationListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,38 +286,11 @@ public abstract class AbstractScript implements INamable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setActive(boolean status)
|
|
||||||
{
|
|
||||||
_isActive = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isActive()
|
|
||||||
{
|
|
||||||
return _isActive;
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getScriptFile()
|
|
||||||
{
|
|
||||||
return _scriptFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean reload()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
L2ScriptEngineManager.getInstance().executeScript(getScriptFile());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (ScriptException e)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unloads all listeners registered by this class.
|
* Unloads all listeners registered by this class.
|
||||||
* @return {@code true}
|
* @return {@code true}
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean unload()
|
public boolean unload()
|
||||||
{
|
{
|
||||||
_listeners.forEach(AbstractEventListener::unregisterMe);
|
_listeners.forEach(AbstractEventListener::unregisterMe);
|
||||||
@@ -334,8 +298,6 @@ public abstract class AbstractScript implements INamable
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract ScriptManager<?> getManager();
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -63,7 +63,6 @@ import com.l2jmobius.gameserver.model.zone.L2ZoneType;
|
|||||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.NpcQuestHtmlMessage;
|
import com.l2jmobius.gameserver.network.serverpackets.NpcQuestHtmlMessage;
|
||||||
import com.l2jmobius.gameserver.scripting.ScriptManager;
|
|
||||||
import com.l2jmobius.util.Rnd;
|
import com.l2jmobius.util.Rnd;
|
||||||
import com.l2jmobius.util.Util;
|
import com.l2jmobius.util.Util;
|
||||||
|
|
||||||
@@ -203,7 +202,6 @@ public class Quest extends AbstractScript implements IIdentifiable
|
|||||||
return _initialState;
|
return _initialState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName()
|
public String getName()
|
||||||
{
|
{
|
||||||
return _name;
|
return _name;
|
||||||
@@ -1385,7 +1383,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
|||||||
*/
|
*/
|
||||||
public boolean showError(L2PcInstance player, Throwable t)
|
public boolean showError(L2PcInstance player, Throwable t)
|
||||||
{
|
{
|
||||||
_log.log(Level.WARNING, getScriptFile().getAbsolutePath(), t);
|
_log.log(Level.WARNING, getScriptFile().toAbsolutePath().toString(), t);
|
||||||
if (t.getMessage() == null)
|
if (t.getMessage() == null)
|
||||||
{
|
{
|
||||||
_log.warning(getClass().getSimpleName() + ": " + t.getMessage());
|
_log.warning(getClass().getSimpleName() + ": " + t.getMessage());
|
||||||
@@ -2595,6 +2593,12 @@ public class Quest extends AbstractScript implements IIdentifiable
|
|||||||
takeItems(player, -1, questItemIds);
|
takeItems(player, -1, questItemIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getScriptName()
|
||||||
|
{
|
||||||
|
return getName();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setActive(boolean status)
|
public void setActive(boolean status)
|
||||||
{
|
{
|
||||||
@@ -2652,12 +2656,6 @@ public class Quest extends AbstractScript implements IIdentifiable
|
|||||||
return super.unload();
|
return super.unload();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ScriptManager<?> getManager()
|
|
||||||
{
|
|
||||||
return QuestManager.getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnEnterWorld(boolean state)
|
public void setOnEnterWorld(boolean state)
|
||||||
{
|
{
|
||||||
if (state)
|
if (state)
|
||||||
|
@@ -1,76 +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 com.l2jmobius.gameserver.script;
|
|
||||||
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import javax.script.ScriptContext;
|
|
||||||
|
|
||||||
public class Expression
|
|
||||||
{
|
|
||||||
protected static final Logger _log = Logger.getLogger(Expression.class.getName());
|
|
||||||
private final ScriptContext _context;
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final String _lang;
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final String _code;
|
|
||||||
|
|
||||||
public static Expression create(ScriptContext context, String lang, String code)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return new Expression(context, lang, code);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_log.log(Level.WARNING, "", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Expression(ScriptContext pContext, String pLang, String pCode)
|
|
||||||
{
|
|
||||||
_context = pContext;
|
|
||||||
_lang = pLang;
|
|
||||||
_code = pCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> void addDynamicVariable(String name, T value)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_context.setAttribute(name, value, ScriptContext.ENGINE_SCOPE);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_log.log(Level.WARNING, "", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeDynamicVariable(String name)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_context.removeAttribute(name, ScriptContext.ENGINE_SCOPE);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_log.log(Level.WARNING, "", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.l2jmobius.gameserver.scripting;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author HorridoJoho
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
|
public abstract class AbstractExecutionContext<T extends IScriptingEngine> implements IExecutionContext
|
||||||
|
{
|
||||||
|
private final T _engine;
|
||||||
|
private final Map<String, String> _properties;
|
||||||
|
private volatile Path _currentExecutingScipt;
|
||||||
|
|
||||||
|
protected AbstractExecutionContext(final T engine)
|
||||||
|
{
|
||||||
|
if (engine == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
_engine = engine;
|
||||||
|
_properties = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void setCurrentExecutingScript(final Path currentExecutingScript)
|
||||||
|
{
|
||||||
|
_currentExecutingScipt = currentExecutingScript;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final String setProperty(final String key, final String value)
|
||||||
|
{
|
||||||
|
return _properties.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final String getProperty(final String key)
|
||||||
|
{
|
||||||
|
if (!_properties.containsKey(key))
|
||||||
|
{
|
||||||
|
return _engine.getProperty(key);
|
||||||
|
}
|
||||||
|
return _properties.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final Path getCurrentExecutingScript()
|
||||||
|
{
|
||||||
|
return _currentExecutingScipt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final T getScriptingEngine()
|
||||||
|
{
|
||||||
|
return _engine;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.l2jmobius.gameserver.scripting;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author HorridoJoho
|
||||||
|
*/
|
||||||
|
public abstract class AbstractScriptingEngine implements IScriptingEngine
|
||||||
|
{
|
||||||
|
private final String _engineName;
|
||||||
|
private final String _engineVersion;
|
||||||
|
private final String[] _commonFileExtensions;
|
||||||
|
private final Map<String, String> _properties;
|
||||||
|
|
||||||
|
protected AbstractScriptingEngine(final String engineName, final String engineVersion, final String... commonFileExtensions)
|
||||||
|
{
|
||||||
|
if ((engineName == null) || engineName.isEmpty() || (engineVersion == null) || engineVersion.isEmpty() || (commonFileExtensions == null) || (commonFileExtensions.length == 0))
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
_engineName = engineName;
|
||||||
|
_engineVersion = engineVersion;
|
||||||
|
_commonFileExtensions = commonFileExtensions;
|
||||||
|
_properties = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final String setProperty(final String key, final String value)
|
||||||
|
{
|
||||||
|
return _properties.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final String getProperty(final String key)
|
||||||
|
{
|
||||||
|
return _properties.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final String getEngineName()
|
||||||
|
{
|
||||||
|
return _engineName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final String getEngineVersion()
|
||||||
|
{
|
||||||
|
return _engineVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final String[] getCommonFileExtensions()
|
||||||
|
{
|
||||||
|
return Arrays.copyOf(_commonFileExtensions, _commonFileExtensions.length);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.l2jmobius.gameserver.scripting;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author HorridoJoho
|
||||||
|
*/
|
||||||
|
public interface IExecutionContext
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Properties set here override the settings from the IScriptEngine<br>
|
||||||
|
* this class was created from.
|
||||||
|
* @param key the key
|
||||||
|
* @param value the value
|
||||||
|
* @return the previous value, or null when this key was not present before
|
||||||
|
*/
|
||||||
|
String setProperty(String key, String value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes all script in the iterable.
|
||||||
|
* @param sourcePaths the scripts to execute
|
||||||
|
* @return map of failed executions, Path=source file Throwable=thrown exception
|
||||||
|
* @throws Exception preparation for script execution failed
|
||||||
|
*/
|
||||||
|
Map<Path, Throwable> executeScripts(Iterable<Path> sourcePaths) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes a single file.
|
||||||
|
* @param sourcePath the script to execute
|
||||||
|
* @return entry of failed execution, Path=source file Throwable=thrown exception
|
||||||
|
* @throws Exception preparation for script execution failed
|
||||||
|
*/
|
||||||
|
Entry<Path, Throwable> executeScript(Path sourcePath) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get the specified property value.
|
||||||
|
* @param key the key
|
||||||
|
* @return the value, or null if the key is not present
|
||||||
|
*/
|
||||||
|
String getProperty(String key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get the current executing script file.
|
||||||
|
* @return the currently executing script file, null if non
|
||||||
|
*/
|
||||||
|
Path getCurrentExecutingScript();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get the script engine this execution context belongs to.
|
||||||
|
* @return the script engine this execution context belongs to
|
||||||
|
*/
|
||||||
|
IScriptingEngine getScriptingEngine();
|
||||||
|
}
|
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.l2jmobius.gameserver.scripting;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author HorridoJoho
|
||||||
|
*/
|
||||||
|
public interface IScriptingEngine
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Sets script engine properties. The script values will be available<br>
|
||||||
|
* to the the insatnces created {@link IExecutionContext} implementation.
|
||||||
|
* @param key the key
|
||||||
|
* @param value the value
|
||||||
|
* @return the previous value, or null when this key was not present before
|
||||||
|
*/
|
||||||
|
String setProperty(String key, String value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an execution context.
|
||||||
|
* @return the created execution context.
|
||||||
|
*/
|
||||||
|
IExecutionContext createExecutionContext();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get the specified property value.
|
||||||
|
* @param key the key
|
||||||
|
* @return the value,or null if the key is not present
|
||||||
|
*/
|
||||||
|
String getProperty(String key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get the engine name.
|
||||||
|
* @return the engine name
|
||||||
|
*/
|
||||||
|
String getEngineName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get the engine version.
|
||||||
|
* @return the engine version
|
||||||
|
*/
|
||||||
|
String getEngineVersion();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get the scripting language name.
|
||||||
|
* @return the scripting engine name
|
||||||
|
*/
|
||||||
|
String getLanguageName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get the the language version.
|
||||||
|
* @return the language version
|
||||||
|
*/
|
||||||
|
String getLanguageVersion();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to retrive the commonly used file extensions for the language.
|
||||||
|
* @return the commonly used file extensions for the language
|
||||||
|
*/
|
||||||
|
String[] getCommonFileExtensions();
|
||||||
|
}
|
@@ -1,363 +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 com.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.LineNumberReader;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
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.l2jmobius.Config;
|
|
||||||
import com.l2jmobius.commons.javaengine.JavaScriptEngineFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Caches script engines and provides functionality for executing and managing scripts.
|
|
||||||
* @author KenM
|
|
||||||
*/
|
|
||||||
public final class L2ScriptEngineManager
|
|
||||||
{
|
|
||||||
private static final Logger _log = 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> _extEngines = new HashMap<>();
|
|
||||||
private final List<ScriptManager<?>> _scriptManagers = new LinkedList<>();
|
|
||||||
|
|
||||||
private File _currentLoadingScript;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the script engine supports compilation the script is compiled before execution.<BR>
|
|
||||||
*/
|
|
||||||
private static final boolean ATTEMPT_COMPILATION = true;
|
|
||||||
|
|
||||||
protected L2ScriptEngineManager()
|
|
||||||
{
|
|
||||||
final ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
|
|
||||||
final ScriptEngineFactory factory = new JavaScriptEngineFactory();
|
|
||||||
scriptEngineManager.registerEngineExtension("java", factory);
|
|
||||||
_extEngines.put("java", factory.getScriptEngine());
|
|
||||||
_log.info("Script Engine: " + factory.getEngineName() + " " + factory.getEngineVersion() + " - Language: " + factory.getLanguageName() + " - Language Version: " + factory.getLanguageVersion());
|
|
||||||
}
|
|
||||||
|
|
||||||
private ScriptEngine getEngineByExtension(String ext)
|
|
||||||
{
|
|
||||||
return _extEngines.get(ext);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void executeScriptList(File list) throws IOException
|
|
||||||
{
|
|
||||||
if (Config.ALT_DEV_NO_QUESTS)
|
|
||||||
{
|
|
||||||
if (!Config.ALT_DEV_NO_HANDLERS)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
executeScript(new File(SCRIPT_FOLDER, "handlers/MasterHandler.java"));
|
|
||||||
_log.info("Handlers loaded, all other scripts skipped");
|
|
||||||
}
|
|
||||||
catch (ScriptException se)
|
|
||||||
{
|
|
||||||
_log.log(Level.WARNING, "", se);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!list.isFile())
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("Argument must be an file containing a list of scripts to be loaded");
|
|
||||||
}
|
|
||||||
|
|
||||||
try (FileInputStream fis = new FileInputStream(list);
|
|
||||||
InputStreamReader isr = new InputStreamReader(fis);
|
|
||||||
LineNumberReader lnr = new LineNumberReader(isr))
|
|
||||||
{
|
|
||||||
String line;
|
|
||||||
while ((line = lnr.readLine()) != null)
|
|
||||||
{
|
|
||||||
if (Config.ALT_DEV_NO_HANDLERS && line.contains("MasterHandler.java"))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String[] parts = line.trim().split("#");
|
|
||||||
|
|
||||||
if ((parts.length > 0) && !parts[0].isEmpty() && (parts[0].charAt(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
final File 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
|
|
||||||
{
|
|
||||||
_log.warning("Failed loading: (" + file.getCanonicalPath() + ") @ " + list.getName() + ":" + lnr.getLineNumber() + " - Reason: doesnt exists or is not a file.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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())
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("The argument directory either doesnt exists or is not an directory.");
|
|
||||||
}
|
|
||||||
|
|
||||||
final File[] files = dir.listFiles();
|
|
||||||
if (files == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (File file : files)
|
|
||||||
{
|
|
||||||
if (file.isDirectory() && recurseDown && (maxDepth > currentDepth))
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void executeScript(File file) throws ScriptException
|
|
||||||
{
|
|
||||||
final String name = file.getName();
|
|
||||||
final int lastIndex = name.lastIndexOf('.');
|
|
||||||
String extension;
|
|
||||||
if (lastIndex == -1)
|
|
||||||
{
|
|
||||||
throw new ScriptException("Script file (" + name + ") doesnt has an extension that identifies the ScriptEngine to be used.");
|
|
||||||
}
|
|
||||||
extension = name.substring(lastIndex + 1);
|
|
||||||
final ScriptEngine engine = getEngineByExtension(extension);
|
|
||||||
if (engine == null)
|
|
||||||
{
|
|
||||||
throw new ScriptException("No engine registered for extension (" + extension + ")");
|
|
||||||
}
|
|
||||||
executeScript(engine, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void executeScript(ScriptEngine engine, File file) throws ScriptException
|
|
||||||
{
|
|
||||||
{
|
|
||||||
final String name = file.getAbsolutePath() + ".error.log";
|
|
||||||
final File errorLog = new File(name);
|
|
||||||
if (errorLog.isFile())
|
|
||||||
{
|
|
||||||
errorLog.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final String relativeName = file.getAbsolutePath().substring(SCRIPT_FOLDER.getAbsolutePath().length() + 1).replace('\\', '/');
|
|
||||||
try (FileInputStream fis = new FileInputStream(file);
|
|
||||||
InputStreamReader isr = new InputStreamReader(fis);
|
|
||||||
BufferedReader reader = new BufferedReader(isr))
|
|
||||||
{
|
|
||||||
final ScriptContext context = new SimpleScriptContext();
|
|
||||||
context.setAttribute("mainClass", getClassForFile(file).replace('/', '.').replace('\\', '.'), ScriptContext.ENGINE_SCOPE);
|
|
||||||
context.setAttribute(ScriptEngine.FILENAME, relativeName, 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(reader, context);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
setCurrentLoadingScript(null);
|
|
||||||
engine.getContext().removeAttribute(ScriptEngine.FILENAME, ScriptContext.ENGINE_SCOPE);
|
|
||||||
engine.getContext().removeAttribute("mainClass", ScriptContext.ENGINE_SCOPE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
_log.log(Level.WARNING, "Error executing script!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getClassForFile(File script)
|
|
||||||
{
|
|
||||||
final String path = script.getAbsolutePath();
|
|
||||||
final String scpPath = SCRIPT_FOLDER.getAbsolutePath();
|
|
||||||
return path.startsWith(scpPath) ? path.substring(scpPath.length() + 1, path.lastIndexOf('.')) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScriptContext getScriptContext(ScriptEngine engine)
|
|
||||||
{
|
|
||||||
return engine.getContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object eval(ScriptEngine engine, String script, ScriptContext context) throws ScriptException
|
|
||||||
{
|
|
||||||
if (!(engine instanceof Compilable) || !ATTEMPT_COMPILATION)
|
|
||||||
{
|
|
||||||
return context != null ? engine.eval(script, context) : engine.eval(script);
|
|
||||||
}
|
|
||||||
final Compilable eng = (Compilable) engine;
|
|
||||||
final CompiledScript cs = eng.compile(script);
|
|
||||||
return context != null ? cs.eval(context) : cs.eval();
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
if (dir != null)
|
|
||||||
{
|
|
||||||
final File file = new File(dir + "/" + script.getName() + ".error.log");
|
|
||||||
try (FileOutputStream fos = new FileOutputStream(file))
|
|
||||||
{
|
|
||||||
final String errorHeader = "Error on: " + file.getCanonicalPath() + Config.EOL + "Line: " + e.getLineNumber() + " - Column: " + e.getColumnNumber() + Config.EOL + Config.EOL;
|
|
||||||
fos.write(errorHeader.getBytes());
|
|
||||||
fos.write(e.getMessage().getBytes());
|
|
||||||
_log.warning("Failed executing script: " + script.getAbsolutePath() + ". See " + file.getName() + " for details.");
|
|
||||||
}
|
|
||||||
catch (IOException ioe)
|
|
||||||
{
|
|
||||||
_log.log(Level.WARNING, "Failed executing script: " + script.getAbsolutePath() + Config.EOL + e.getMessage() + "Additionally failed when trying to write an error report on script directory. Reason: " + ioe.getMessage(), ioe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_log.log(Level.WARNING, "Failed executing script: " + script.getAbsolutePath() + Config.EOL + e.getMessage() + "Additionally failed when trying to write an error report on script directory.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
public File getCurrentLoadingScript()
|
|
||||||
{
|
|
||||||
return _currentLoadingScript;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class SingletonHolder
|
|
||||||
{
|
|
||||||
protected static final L2ScriptEngineManager _instance = new L2ScriptEngineManager();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.l2jmobius.gameserver.scripting;
|
||||||
|
|
||||||
|
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.<BR>
|
||||||
|
* @author KenM
|
||||||
|
*/
|
||||||
|
public abstract class ManagedScript
|
||||||
|
{
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(ManagedScript.class.getName());
|
||||||
|
|
||||||
|
private final Path _scriptFile;
|
||||||
|
private long _lastLoadTime;
|
||||||
|
private boolean _isActive;
|
||||||
|
|
||||||
|
public ManagedScript()
|
||||||
|
{
|
||||||
|
_scriptFile = ScriptEngineManager.getInstance().getCurrentLoadingScript();
|
||||||
|
setLastLoadTime(System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
* @return true if and only if the script was reloaded, false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean reload()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ScriptEngineManager.getInstance().executeScript(getScriptFile());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
LOGGER.log(Level.WARNING, "Failed to reload script!", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract boolean unload();
|
||||||
|
|
||||||
|
public void setActive(boolean status)
|
||||||
|
{
|
||||||
|
_isActive = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isActive()
|
||||||
|
{
|
||||||
|
return _isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the scriptFile.
|
||||||
|
*/
|
||||||
|
public Path getScriptFile()
|
||||||
|
{
|
||||||
|
return _scriptFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param lastLoadTime The lastLoadTime to set.
|
||||||
|
*/
|
||||||
|
protected void setLastLoadTime(long lastLoadTime)
|
||||||
|
{
|
||||||
|
_lastLoadTime = lastLoadTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the lastLoadTime.
|
||||||
|
*/
|
||||||
|
protected long getLastLoadTime()
|
||||||
|
{
|
||||||
|
return _lastLoadTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract String getScriptName();
|
||||||
|
}
|
@@ -0,0 +1,287 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.l2jmobius.gameserver.scripting;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.ServiceLoader;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import com.l2jmobius.Config;
|
||||||
|
import com.l2jmobius.gameserver.scripting.java.JavaScriptingEngine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caches script engines and provides functionality for executing and managing scripts.
|
||||||
|
* @author KenM, HorridoJoho
|
||||||
|
*/
|
||||||
|
public final class ScriptEngineManager
|
||||||
|
{
|
||||||
|
private static final Logger _log = Logger.getLogger(ScriptEngineManager.class.getName());
|
||||||
|
public static final Path SCRIPT_LIST_FILE = Paths.get(Config.DATAPACK_ROOT.getAbsolutePath(), "data", "scripts.cfg");
|
||||||
|
public static final Path SCRIPT_FOLDER = Paths.get(Config.DATAPACK_ROOT.getAbsolutePath(), "data", "scripts");
|
||||||
|
public static final Path MASTER_HANDLER_FILE = Paths.get(SCRIPT_FOLDER.toString(), "handlers", "MasterHandler.java");
|
||||||
|
public static final Path EFFECT_MASTER_HANDLER_FILE = Paths.get(SCRIPT_FOLDER.toString(), "handlers", "EffectMasterHandler.java");
|
||||||
|
|
||||||
|
private final Map<String, IExecutionContext> _extEngines = new HashMap<>();
|
||||||
|
private IExecutionContext _currentExecutionContext = null;
|
||||||
|
|
||||||
|
protected ScriptEngineManager()
|
||||||
|
{
|
||||||
|
final Properties props = loadProperties();
|
||||||
|
|
||||||
|
// Default java engine implementation
|
||||||
|
registerEngine(new JavaScriptingEngine(), props);
|
||||||
|
|
||||||
|
// Load external script engines
|
||||||
|
ServiceLoader.load(IScriptingEngine.class).forEach(engine -> registerEngine(engine, props));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Properties loadProperties()
|
||||||
|
{
|
||||||
|
Properties props = null;
|
||||||
|
try (FileInputStream fis = new FileInputStream("config/ScriptEngines.ini"))
|
||||||
|
{
|
||||||
|
props = new Properties();
|
||||||
|
props.load(fis);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
props = null;
|
||||||
|
_log.warning("Couldn't load ScriptEngines.ini: " + e.getMessage());
|
||||||
|
}
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerEngine(IScriptingEngine engine, Properties props)
|
||||||
|
{
|
||||||
|
maybeSetProperties("language." + engine.getLanguageName() + ".", props, engine);
|
||||||
|
final IExecutionContext context = engine.createExecutionContext();
|
||||||
|
for (String commonExtension : engine.getCommonFileExtensions())
|
||||||
|
{
|
||||||
|
_extEngines.put(commonExtension, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
_log.info("ScriptEngine: " + engine.getEngineName() + " " + engine.getEngineVersion() + " (" + engine.getLanguageName() + " " + engine.getLanguageVersion() + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void maybeSetProperties(String propPrefix, Properties props, IScriptingEngine engine)
|
||||||
|
{
|
||||||
|
if (props == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final Entry<Object, Object> prop : props.entrySet())
|
||||||
|
{
|
||||||
|
String key = (String) prop.getKey();
|
||||||
|
String value = (String) prop.getValue();
|
||||||
|
|
||||||
|
if (key.startsWith(propPrefix))
|
||||||
|
{
|
||||||
|
key = key.substring(propPrefix.length());
|
||||||
|
if (value.startsWith("%") && value.endsWith("%"))
|
||||||
|
{
|
||||||
|
value = System.getProperty(value.substring(1, value.length() - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
engine.setProperty(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IExecutionContext getEngineByExtension(String ext)
|
||||||
|
{
|
||||||
|
return _extEngines.get(ext);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFileExtension(Path p)
|
||||||
|
{
|
||||||
|
final String name = p.getFileName().toString();
|
||||||
|
final int lastDotIdx = name.lastIndexOf('.');
|
||||||
|
if (lastDotIdx == -1)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String extension = name.substring(lastDotIdx + 1);
|
||||||
|
if (extension.isEmpty())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkExistingFile(String messagePre, Path filePath) throws Exception
|
||||||
|
{
|
||||||
|
if (!Files.exists(filePath))
|
||||||
|
{
|
||||||
|
throw new Exception(messagePre + ": " + filePath + " does not exists!");
|
||||||
|
}
|
||||||
|
else if (!Files.isRegularFile(filePath))
|
||||||
|
{
|
||||||
|
throw new Exception(messagePre + ": " + filePath + " is not a file!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void executeMasterHandler() throws Exception
|
||||||
|
{
|
||||||
|
executeScript(MASTER_HANDLER_FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void executeEffectMasterHandler() throws Exception
|
||||||
|
{
|
||||||
|
executeScript(EFFECT_MASTER_HANDLER_FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void executeScriptList() throws Exception
|
||||||
|
{
|
||||||
|
if (Config.ALT_DEV_NO_QUESTS)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// throws exception if not exists or not file
|
||||||
|
checkExistingFile("ScriptList", SCRIPT_LIST_FILE);
|
||||||
|
|
||||||
|
final LinkedHashMap<IExecutionContext, LinkedList<Path>> files = new LinkedHashMap<>();
|
||||||
|
final LinkedList<String> extWithoutEngine = new LinkedList<>();
|
||||||
|
|
||||||
|
Files.lines(SCRIPT_LIST_FILE).forEach(line ->
|
||||||
|
{
|
||||||
|
line = line.trim();
|
||||||
|
if (line.isEmpty() || (line.charAt(0) == '#'))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Path sourceFile = SCRIPT_FOLDER.resolve(line);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
checkExistingFile("ScriptFile", sourceFile);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_log.warning(e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceFile = sourceFile.toAbsolutePath();
|
||||||
|
final String ext = getFileExtension(sourceFile);
|
||||||
|
if (ext == null)
|
||||||
|
{
|
||||||
|
_log.warning("ScriptFile: " + sourceFile + " does not have an extension to determine the script engine!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final IExecutionContext engine = getEngineByExtension(ext);
|
||||||
|
if (engine == null)
|
||||||
|
{
|
||||||
|
if (!extWithoutEngine.contains(ext))
|
||||||
|
{
|
||||||
|
extWithoutEngine.add(ext);
|
||||||
|
_log.warning("ScriptEngine: No engine registered for extension " + ext + "!");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkedList<Path> ll = files.get(engine);
|
||||||
|
if (ll == null)
|
||||||
|
{
|
||||||
|
ll = new LinkedList<>();
|
||||||
|
files.put(engine, ll);
|
||||||
|
}
|
||||||
|
ll.add(sourceFile);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (Entry<IExecutionContext, LinkedList<Path>> entry : files.entrySet())
|
||||||
|
{
|
||||||
|
_currentExecutionContext = entry.getKey();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Map<Path, Throwable> invokationErrors = entry.getKey().executeScripts(entry.getValue());
|
||||||
|
for (Entry<Path, Throwable> entry2 : invokationErrors.entrySet())
|
||||||
|
{
|
||||||
|
_log.log(Level.WARNING, "ScriptEngine: " + entry2.getKey() + " failed execution!", entry2.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_currentExecutionContext = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void executeScript(Path sourceFile) throws Exception
|
||||||
|
{
|
||||||
|
Objects.requireNonNull(sourceFile);
|
||||||
|
|
||||||
|
if (!sourceFile.isAbsolute())
|
||||||
|
{
|
||||||
|
sourceFile = SCRIPT_FOLDER.resolve(sourceFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
// throws exception if not exists or not file
|
||||||
|
checkExistingFile("ScriptFile", sourceFile);
|
||||||
|
|
||||||
|
sourceFile = sourceFile.toAbsolutePath();
|
||||||
|
String ext = getFileExtension(sourceFile);
|
||||||
|
Objects.requireNonNull(sourceFile, "ScriptFile: " + sourceFile + " does not have an extension to determine the script engine!");
|
||||||
|
|
||||||
|
IExecutionContext engine = getEngineByExtension(ext);
|
||||||
|
Objects.requireNonNull(engine, "ScriptEngine: No engine registered for extension " + ext + "!");
|
||||||
|
|
||||||
|
_currentExecutionContext = engine;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Entry<Path, Throwable> error = engine.executeScript(sourceFile);
|
||||||
|
if (error != null)
|
||||||
|
{
|
||||||
|
throw new Exception("ScriptEngine: " + error.getKey() + " failed execution!", error.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_currentExecutionContext = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Path getCurrentLoadingScript()
|
||||||
|
{
|
||||||
|
return _currentExecutionContext.getCurrentExecutingScript();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ScriptEngineManager getInstance()
|
||||||
|
{
|
||||||
|
return SingletonHolder._instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SingletonHolder
|
||||||
|
{
|
||||||
|
protected static final ScriptEngineManager _instance = new ScriptEngineManager();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.l2jmobius.gameserver.scripting.java;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author HorridoJoho
|
||||||
|
*/
|
||||||
|
public final class JavaCompilerException extends RuntimeException
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = -8330513514176036095L;
|
||||||
|
|
||||||
|
public JavaCompilerException(String diagnostics)
|
||||||
|
{
|
||||||
|
super(diagnostics);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,239 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.l2jmobius.gameserver.scripting.java;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
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 com.l2jmobius.gameserver.scripting.AbstractExecutionContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author HorridoJoho
|
||||||
|
*/
|
||||||
|
public final class JavaExecutionContext extends AbstractExecutionContext<JavaScriptingEngine>
|
||||||
|
{
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(JavaExecutionContext.class.getName());
|
||||||
|
|
||||||
|
JavaExecutionContext(final JavaScriptingEngine engine)
|
||||||
|
{
|
||||||
|
super(engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean addOptionIfNotNull(final LinkedList<String> list, final String nullChecked, final 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()
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Path, Throwable> executeScripts(final Iterable<Path> sourcePaths) throws Exception
|
||||||
|
{
|
||||||
|
final DiagnosticCollector<JavaFileObject> fileManagerDiagnostics = new DiagnosticCollector<>();
|
||||||
|
final DiagnosticCollector<JavaFileObject> compilationDiagnostics = new DiagnosticCollector<>();
|
||||||
|
|
||||||
|
try (final ScriptingFileManager fileManager = new ScriptingFileManager(getScriptingEngine().getCompiler().getStandardFileManager(fileManagerDiagnostics, null, StandardCharsets.UTF_8)))
|
||||||
|
{
|
||||||
|
final StringWriter strOut = new StringWriter();
|
||||||
|
final PrintWriter out = new PrintWriter(strOut);
|
||||||
|
final LinkedList<String> options = new LinkedList<>();
|
||||||
|
|
||||||
|
addOptionIfNotNull(options, getProperty("source"), "-source");
|
||||||
|
addOptionIfNotNull(options, getProperty("sourcepath"), "-sourcepath");
|
||||||
|
if (!addOptionIfNotNull(options, getProperty("cp"), "-cp") && !addOptionIfNotNull(options, getProperty("classpath"), "-classpath"))
|
||||||
|
{
|
||||||
|
addOptionIfNotNull(options, System.getProperty("java.class.path"), "-cp");
|
||||||
|
}
|
||||||
|
addOptionIfNotNull(options, getProperty("g"), "-g:");
|
||||||
|
|
||||||
|
// we always add 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
|
||||||
|
{
|
||||||
|
String[] versionSplit = targetVersion.split("\\.");
|
||||||
|
if (versionSplit.length > 1)
|
||||||
|
{
|
||||||
|
options.add("-target");
|
||||||
|
options.add(versionSplit[0] + '.' + versionSplit[1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new JavaCompilerException("Could not determine target version!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we really need an iterable of files or strings
|
||||||
|
final LinkedList<String> sourcePathStrings = new LinkedList<>();
|
||||||
|
for (Path sourcePath : sourcePaths)
|
||||||
|
{
|
||||||
|
sourcePathStrings.add(sourcePath.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean compilationSuccess = getScriptingEngine().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().toString() + ": " + 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().toString() + ": " + diagnostic.getSource().getName() + ", Line " + diagnostic.getLineNumber() + ", Column " + diagnostic.getColumnNumber());
|
||||||
|
out.println("\t\tcode: " + diagnostic.getCode());
|
||||||
|
out.println("\t\tmessage: " + diagnostic.getMessage(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new JavaCompilerException(strOut.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
final ClassLoader parentClassLoader = determineScriptParentClassloader();
|
||||||
|
|
||||||
|
LinkedHashMap<Path, Throwable> executionFailures = new LinkedHashMap<>();
|
||||||
|
Iterable<ScriptingOutputFileObject> compiledClasses = fileManager.getCompiledClasses();
|
||||||
|
for (final Path sourcePath : sourcePaths)
|
||||||
|
{
|
||||||
|
boolean found = false;
|
||||||
|
|
||||||
|
for (final ScriptingOutputFileObject compiledClass : compiledClasses)
|
||||||
|
{
|
||||||
|
Path compiledSourcePath = compiledClass.getSourcePath();
|
||||||
|
// sourePath can be relative, so we have to use endsWith
|
||||||
|
if ((compiledSourcePath != null) && (compiledSourcePath.equals(sourcePath) || compiledSourcePath.endsWith(sourcePath)))
|
||||||
|
{
|
||||||
|
String javaName = compiledClass.getJavaName();
|
||||||
|
if (javaName.indexOf('$') != -1)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
setCurrentExecutingScript(compiledSourcePath);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ScriptingClassLoader loader = new ScriptingClassLoader(parentClassLoader, compiledClasses);
|
||||||
|
Class<?> javaCls = loader.loadClass(javaName);
|
||||||
|
javaCls.getMethod("main", String[].class).invoke(null, (Object) new String[]
|
||||||
|
{
|
||||||
|
compiledSourcePath.toString()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
executionFailures.put(compiledSourcePath, e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
setCurrentExecutingScript(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
LOGGER.severe("Compilation successfull, but class coresponding to " + sourcePath.toString() + " not found!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return executionFailures;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entry<Path, Throwable> executeScript(final Path sourcePath) throws Exception
|
||||||
|
{
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
Map<Path, Throwable> executionFailures = executeScripts(new LinkedList<Path>()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
add(sourcePath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!executionFailures.isEmpty())
|
||||||
|
{
|
||||||
|
return executionFailures.entrySet().iterator().next();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.l2jmobius.gameserver.scripting.java;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.ServiceLoader;
|
||||||
|
|
||||||
|
import javax.lang.model.SourceVersion;
|
||||||
|
import javax.tools.JavaCompiler;
|
||||||
|
import javax.tools.ToolProvider;
|
||||||
|
|
||||||
|
import com.l2jmobius.gameserver.scripting.AbstractScriptingEngine;
|
||||||
|
import com.l2jmobius.gameserver.scripting.IExecutionContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author HorridoJoho
|
||||||
|
*/
|
||||||
|
public final class JavaScriptingEngine extends AbstractScriptingEngine
|
||||||
|
{
|
||||||
|
private volatile JavaCompiler _compiler;
|
||||||
|
|
||||||
|
public JavaScriptingEngine()
|
||||||
|
{
|
||||||
|
super("L2J Java Engine", "1.0", "java");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void determineCompilerOrThrow()
|
||||||
|
{
|
||||||
|
final String preferedCompiler = getProperty("preferedCompiler");
|
||||||
|
LinkedList<JavaCompiler> allCompilers = null;
|
||||||
|
|
||||||
|
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||||
|
if (compiler != null)
|
||||||
|
{
|
||||||
|
if ((preferedCompiler == null) || compiler.getClass().getName().equals(preferedCompiler))
|
||||||
|
{
|
||||||
|
_compiler = compiler;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
allCompilers = new LinkedList<>();
|
||||||
|
allCompilers.add(compiler);
|
||||||
|
}
|
||||||
|
|
||||||
|
final ServiceLoader<JavaCompiler> thirdPartyCompilers = ServiceLoader.load(JavaCompiler.class);
|
||||||
|
Iterator<JavaCompiler> compilersIterator = thirdPartyCompilers.iterator();
|
||||||
|
while (compilersIterator.hasNext())
|
||||||
|
{
|
||||||
|
compiler = compilersIterator.next();
|
||||||
|
if ((preferedCompiler == null) || compiler.getClass().getName().equals(preferedCompiler))
|
||||||
|
{
|
||||||
|
_compiler = compiler;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allCompilers == null)
|
||||||
|
{
|
||||||
|
allCompilers = new LinkedList<>();
|
||||||
|
}
|
||||||
|
allCompilers.add(compilersIterator.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allCompilers != null)
|
||||||
|
{
|
||||||
|
compilersIterator = allCompilers.iterator();
|
||||||
|
while (compilersIterator.hasNext())
|
||||||
|
{
|
||||||
|
compiler = compilersIterator.next();
|
||||||
|
if ((preferedCompiler == null) || compiler.getClass().getName().equals(preferedCompiler))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compiler == null)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("No javax.tools.JavaCompiler service installed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
_compiler = compiler;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureCompilerOrThrow()
|
||||||
|
{
|
||||||
|
if (_compiler == null)
|
||||||
|
{
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
if (_compiler == null)
|
||||||
|
{
|
||||||
|
determineCompilerOrThrow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JavaCompiler getCompiler()
|
||||||
|
{
|
||||||
|
return _compiler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IExecutionContext createExecutionContext()
|
||||||
|
{
|
||||||
|
ensureCompilerOrThrow();
|
||||||
|
return new JavaExecutionContext(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLanguageName()
|
||||||
|
{
|
||||||
|
return "Java";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLanguageVersion()
|
||||||
|
{
|
||||||
|
ensureCompilerOrThrow();
|
||||||
|
return Arrays.deepToString(_compiler.getSourceVersions().toArray(new SourceVersion[0])).replace("RELEASE_", "");
|
||||||
|
}
|
||||||
|
}
|
@@ -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 com.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(final ClassLoader parent, final Iterable<ScriptingOutputFileObject> compiledClasses)
|
||||||
|
{
|
||||||
|
super(parent);
|
||||||
|
_compiledClasses = compiledClasses;
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeCompiledClasses()
|
||||||
|
{
|
||||||
|
_compiledClasses = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?> findClass(final String name) throws ClassNotFoundException
|
||||||
|
{
|
||||||
|
for (final 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 com.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,147 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -16,11 +16,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.taskmanager.tasks;
|
package com.l2jmobius.gameserver.taskmanager.tasks;
|
||||||
|
|
||||||
import java.io.File;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import javax.script.ScriptException;
|
import com.l2jmobius.gameserver.scripting.ScriptEngineManager;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.scripting.L2ScriptEngineManager;
|
|
||||||
import com.l2jmobius.gameserver.taskmanager.Task;
|
import com.l2jmobius.gameserver.taskmanager.Task;
|
||||||
import com.l2jmobius.gameserver.taskmanager.TaskManager.ExecutedTask;
|
import com.l2jmobius.gameserver.taskmanager.TaskManager.ExecutedTask;
|
||||||
|
|
||||||
@@ -40,26 +39,13 @@ public class TaskScript extends Task
|
|||||||
@Override
|
@Override
|
||||||
public void onTimeElapsed(ExecutedTask task)
|
public void onTimeElapsed(ExecutedTask task)
|
||||||
{
|
{
|
||||||
final File file = new File(L2ScriptEngineManager.SCRIPT_FOLDER, "cron/" + task.getParams()[2]);
|
try
|
||||||
if (file.isFile())
|
|
||||||
{
|
{
|
||||||
try
|
ScriptEngineManager.getInstance().executeScript(Paths.get("cron", task.getParams()[2]));
|
||||||
{
|
|
||||||
L2ScriptEngineManager.getInstance().executeScript(file);
|
|
||||||
}
|
|
||||||
catch (ScriptException e)
|
|
||||||
{
|
|
||||||
_log.warning("Failed loading: " + task.getParams()[2]);
|
|
||||||
L2ScriptEngineManager.getInstance().reportScriptFileError(file, e);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_log.warning("Failed loading: " + task.getParams()[2]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_log.warning("File Not Found: " + task.getParams()[2]);
|
_log.log(Level.WARNING, "Script execution failed!", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user