Script engine refactor preparation (#492)

* Fix Invocable casting, remove useless script engine cache

* Remove useless script retry

* Remove null reference in EventManager
This commit is contained in:
kolakcc
2019-08-15 01:47:00 +02:00
committed by Ronan Lana
parent 993398180e
commit 2295317a84
6 changed files with 63 additions and 65 deletions

View File

@@ -44,6 +44,7 @@ import java.util.Set;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import jdk.nashorn.api.scripting.NashornScriptEngine;
import tools.*; import tools.*;
import javax.script.ScriptEngine; import javax.script.ScriptEngine;
@@ -106,7 +107,7 @@ public class MapleClient {
private long lastPong; private long lastPong;
private int gmlevel; private int gmlevel;
private Set<String> macs = new HashSet<>(); private Set<String> macs = new HashSet<>();
private Map<String, ScriptEngine> engines = new HashMap<>(); private Map<String, NashornScriptEngine> engines = new HashMap<>();
private byte characterSlots = 3; private byte characterSlots = 3;
private byte loginattempt = 0; private byte loginattempt = 0;
private String pin = ""; private String pin = "";
@@ -1174,11 +1175,11 @@ public class MapleClient {
gmlevel = level; gmlevel = level;
} }
public void setScriptEngine(String name, ScriptEngine e) { public void setScriptEngine(String name, NashornScriptEngine e) {
engines.put(name, e); engines.put(name, e);
} }
public ScriptEngine getScriptEngine(String name) { public NashornScriptEngine getScriptEngine(String name) {
return engines.get(name); return engines.get(name);
} }

View File

@@ -27,12 +27,11 @@ import java.io.File;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import javax.script.Invocable; import javax.script.*;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import constants.ServerConstants; import constants.ServerConstants;
import jdk.nashorn.api.scripting.NashornScriptEngine;
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
import tools.FilePrinter; import tools.FilePrinter;
/** /**
@@ -40,45 +39,42 @@ import tools.FilePrinter;
* @author Matze * @author Matze
*/ */
public abstract class AbstractScriptManager { public abstract class AbstractScriptManager {
private ScriptEngineFactory sef;
protected ScriptEngine engine;
private ScriptEngineManager sem;
protected AbstractScriptManager() { protected AbstractScriptManager() {
sem = new ScriptEngineManager(); sef = new ScriptEngineManager().getEngineByName("javascript").getFactory();
} }
protected Invocable getInvocable(String path, MapleClient c) { protected NashornScriptEngine getScriptEngine(String path) {
path = "scripts/" + path; path = "scripts/" + path;
engine = null; File scriptFile = new File(path);
if (c != null) { if (!scriptFile.exists()) {
try { return null;
engine = c.getScriptEngine(path);
} catch (NullPointerException npe) {
c = null; // player disconnected
}
} }
if (engine == null) { NashornScriptEngine engine = (NashornScriptEngine) sef.getScriptEngine();
File scriptFile = new File(path); try (FileReader fr = new FileReader(scriptFile)) {
if (!scriptFile.exists()) { if (ServerConstants.JAVA_8){
return null; engine.eval("load('nashorn:mozilla_compat.js');" + System.lineSeparator());
}
engine = sem.getEngineByName("javascript");
if (c != null) {
c.setScriptEngine(path, engine);
}
try (FileReader fr = new FileReader(scriptFile)) {
if (ServerConstants.JAVA_8){
engine.eval("load('nashorn:mozilla_compat.js');" + System.lineSeparator());
}
engine.eval(fr);
} catch (final ScriptException | IOException t) {
FilePrinter.printError(FilePrinter.INVOCABLE + path.substring(12, path.length()), t, path);
return null;
} }
engine.eval(fr);
} catch (final ScriptException | IOException t) {
FilePrinter.printError(FilePrinter.INVOCABLE + path.substring(12), t, path);
return null;
} }
return (Invocable) engine; return engine;
}
protected NashornScriptEngine getScriptEngine(String path, MapleClient c) {
String cachePath = "scripts/" + path;
NashornScriptEngine engine = c.getScriptEngine(cachePath);
if (engine == null) {
engine = getScriptEngine(cachePath);
c.setScriptEngine(path, engine);
}
return engine;
} }
protected void resetContext(String path, MapleClient c) { protected void resetContext(String path, MapleClient c) {

View File

@@ -54,7 +54,7 @@ public class EventScriptManager extends AbstractScriptManager {
super(); super();
for (String script : scripts) { for (String script : scripts) {
if (!script.equals("")) { if (!script.equals("")) {
Invocable iv = getInvocable("event/" + script + ".js", null); Invocable iv = getScriptEngine("event/" + script + ".js");
events.put(script, new EventEntry(iv, new EventManager(cserv, iv, script))); events.put(script, new EventEntry(iv, new EventManager(cserv, iv, script)));
} }
} }
@@ -88,7 +88,7 @@ public class EventScriptManager extends AbstractScriptManager {
Channel cserv = events.values().iterator().next().em.getChannelServer(); Channel cserv = events.values().iterator().next().em.getChannelServer();
for (Entry<String, EventEntry> entry : events.entrySet()) { for (Entry<String, EventEntry> entry : events.entrySet()) {
String script = entry.getKey(); String script = entry.getKey();
Invocable iv = getInvocable("event/" + script + ".js", null); Invocable iv = getScriptEngine("event/" + script + ".js");
events.put(script, new EventEntry(iv, new EventManager(cserv, iv, script))); events.put(script, new EventEntry(iv, new EventManager(cserv, iv, script)));
} }
} }

View File

@@ -30,7 +30,10 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import javax.script.Invocable; import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptException; import javax.script.ScriptException;
import jdk.nashorn.api.scripting.NashornScriptEngine;
import net.server.world.MaplePartyCharacter; import net.server.world.MaplePartyCharacter;
import scripting.AbstractScriptManager; import scripting.AbstractScriptManager;
@@ -56,7 +59,7 @@ public class NPCScriptManager extends AbstractScriptManager {
public boolean isNpcScriptAvailable(MapleClient c, String fileName) { public boolean isNpcScriptAvailable(MapleClient c, String fileName) {
Invocable iv = null; Invocable iv = null;
if (fileName != null) { if (fileName != null) {
iv = getInvocable("npc/" + fileName + ".js", c); iv = getScriptEngine("npc/" + fileName + ".js", c);
} }
return iv != null; return iv != null;
@@ -90,24 +93,19 @@ public class NPCScriptManager extends AbstractScriptManager {
return; return;
} }
cms.put(c, cm); cms.put(c, cm);
Invocable iv = null; NashornScriptEngine iv = getScriptEngine("npc/" + filename + ".js", c);
iv = getInvocable("npc/" + filename + ".js", c);
if (iv == null) { if (iv == null) {
c.getPlayer().dropMessage(1, npc + ""); c.getPlayer().dropMessage(1, npc + "");
cm.dispose(); cm.dispose();
return; return;
} }
engine.put("cm", cm); iv.put("cm", cm);
scripts.put(c, iv); scripts.put(c, iv);
try { try {
iv.invokeFunction("start", chrs); iv.invokeFunction("start", chrs);
} catch (final NoSuchMethodException nsme) { } catch (final NoSuchMethodException nsme) {
try { nsme.printStackTrace();
iv.invokeFunction("start", chrs);
} catch (final NoSuchMethodException nsma) {
nsma.printStackTrace();
}
} }
} catch (final UndeclaredThrowableException ute) { } catch (final UndeclaredThrowableException ute) {
@@ -127,25 +125,25 @@ public class NPCScriptManager extends AbstractScriptManager {
} }
if (c.canClickNPC()) { if (c.canClickNPC()) {
cms.put(c, cm); cms.put(c, cm);
Invocable iv = null; NashornScriptEngine iv = null;
if (!itemScript) { if (!itemScript) {
if (fileName != null) { if (fileName != null) {
iv = getInvocable("npc/" + fileName + ".js", c); iv = getScriptEngine("npc/" + fileName + ".js", c);
} }
} else { } else {
if (fileName != null) { // thanks MiLin for drafting NPC-based item scripts if (fileName != null) { // thanks MiLin for drafting NPC-based item scripts
iv = getInvocable("item/" + fileName + ".js", c); iv = getScriptEngine("item/" + fileName + ".js", c);
} }
} }
if (iv == null) { if (iv == null) {
iv = getInvocable("npc/" + npc + ".js", c); iv = getScriptEngine("npc/" + npc + ".js", c);
cm.resetItemScript(); cm.resetItemScript();
} }
if (iv == null) { if (iv == null) {
dispose(c); dispose(c);
return false; return false;
} }
engine.put(engineName, cm); iv.put(engineName, cm);
scripts.put(c, iv); scripts.put(c, iv);
c.setClickedNPC(); c.setClickedNPC();
try { try {

View File

@@ -27,6 +27,7 @@ import java.util.Map;
import javax.script.Invocable; import javax.script.Invocable;
import jdk.nashorn.api.scripting.NashornScriptEngine;
import scripting.AbstractScriptManager; import scripting.AbstractScriptManager;
import server.quest.MapleQuest; import server.quest.MapleQuest;
import tools.FilePrinter; import tools.FilePrinter;
@@ -62,10 +63,10 @@ public class QuestScriptManager extends AbstractScriptManager {
} }
if(c.canClickNPC()) { if(c.canClickNPC()) {
qms.put(c, qm); qms.put(c, qm);
Invocable iv = getInvocable("quest/" + questid + ".js", c); NashornScriptEngine iv = getScriptEngine("quest/" + questid + ".js", c);
if (iv == null) { if (iv == null) {
if(GameConstants.isMedalQuest(questid)) { // start generic medal quest if(GameConstants.isMedalQuest(questid)) { // start generic medal quest
iv = getInvocable("quest/medalQuest.js", c); iv = getScriptEngine("quest/medalQuest.js", c);
} else { } else {
FilePrinter.printError(FilePrinter.QUEST_UNCODED, "START Quest " + questid + " is uncoded."); FilePrinter.printError(FilePrinter.QUEST_UNCODED, "START Quest " + questid + " is uncoded.");
} }
@@ -74,7 +75,7 @@ public class QuestScriptManager extends AbstractScriptManager {
qm.dispose(); qm.dispose();
return; return;
} }
engine.put("qm", qm); iv.put("qm", qm);
scripts.put(c, iv); scripts.put(c, iv);
c.setClickedNPC(); c.setClickedNPC();
iv.invokeFunction("start", (byte) 1, (byte) 0, 0); iv.invokeFunction("start", (byte) 1, (byte) 0, 0);
@@ -117,17 +118,17 @@ public class QuestScriptManager extends AbstractScriptManager {
} }
if(c.canClickNPC()){ if(c.canClickNPC()){
qms.put(c, qm); qms.put(c, qm);
Invocable iv = getInvocable("quest/" + questid + ".js", c); NashornScriptEngine iv = getScriptEngine("quest/" + questid + ".js", c);
if (iv == null) { if (iv == null) {
if(GameConstants.isMedalQuest(questid)) { // start generic medal quest if(GameConstants.isMedalQuest(questid)) { // start generic medal quest
iv = getInvocable("quest/medalQuest.js", c); iv = getScriptEngine("quest/medalQuest.js", c);
} else { } else {
FilePrinter.printError(FilePrinter.QUEST_UNCODED, "END Quest " + questid + " is uncoded."); FilePrinter.printError(FilePrinter.QUEST_UNCODED, "END Quest " + questid + " is uncoded.");
qm.dispose(); qm.dispose();
return; return;
} }
} }
engine.put("qm", qm); iv.put("qm", qm);
scripts.put(c, iv); scripts.put(c, iv);
c.setClickedNPC(); c.setClickedNPC();
iv.invokeFunction("end", (byte) 1, (byte) 0, 0); iv.invokeFunction("end", (byte) 1, (byte) 0, 0);

View File

@@ -31,6 +31,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import javax.script.Invocable; import javax.script.Invocable;
import javax.script.ScriptException; import javax.script.ScriptException;
import jdk.nashorn.api.scripting.NashornScriptEngine;
import scripting.AbstractScriptManager; import scripting.AbstractScriptManager;
import server.maps.MapleReactor; import server.maps.MapleReactor;
import server.maps.ReactorDropEntry; import server.maps.ReactorDropEntry;
@@ -52,11 +54,11 @@ public class ReactorScriptManager extends AbstractScriptManager {
public void onHit(MapleClient c, MapleReactor reactor) { public void onHit(MapleClient c, MapleReactor reactor) {
try { try {
Invocable iv = getInvocable("reactor/" + reactor.getId() + ".js", c); NashornScriptEngine iv = getScriptEngine("reactor/" + reactor.getId() + ".js", c);
if (iv == null) return; if (iv == null) return;
ReactorActionManager rm = new ReactorActionManager(c, reactor, iv); ReactorActionManager rm = new ReactorActionManager(c, reactor, iv);
engine.put("rm", rm); iv.put("rm", rm);
iv.invokeFunction("hit"); iv.invokeFunction("hit");
} catch (final NoSuchMethodException e) {} //do nothing, hit is OPTIONAL } catch (final NoSuchMethodException e) {} //do nothing, hit is OPTIONAL
@@ -67,11 +69,11 @@ public class ReactorScriptManager extends AbstractScriptManager {
public void act(MapleClient c, MapleReactor reactor) { public void act(MapleClient c, MapleReactor reactor) {
try { try {
Invocable iv = getInvocable("reactor/" + reactor.getId() + ".js", c); NashornScriptEngine iv = getScriptEngine("reactor/" + reactor.getId() + ".js", c);
if (iv == null) return; if (iv == null) return;
ReactorActionManager rm = new ReactorActionManager(c, reactor, iv); ReactorActionManager rm = new ReactorActionManager(c, reactor, iv);
engine.put("rm", rm); iv.put("rm", rm);
iv.invokeFunction("act"); iv.invokeFunction("act");
} catch (final ScriptException | NoSuchMethodException | NullPointerException e) { } catch (final ScriptException | NoSuchMethodException | NullPointerException e) {
FilePrinter.printError(FilePrinter.REACTOR + reactor.getId() + ".txt", e); FilePrinter.printError(FilePrinter.REACTOR + reactor.getId() + ".txt", e);
@@ -116,11 +118,11 @@ public class ReactorScriptManager extends AbstractScriptManager {
private void touching(MapleClient c, MapleReactor reactor, boolean touching) { private void touching(MapleClient c, MapleReactor reactor, boolean touching) {
try { try {
Invocable iv = getInvocable("reactor/" + reactor.getId() + ".js", c); NashornScriptEngine iv = getScriptEngine("reactor/" + reactor.getId() + ".js", c);
if (iv == null) return; if (iv == null) return;
ReactorActionManager rm = new ReactorActionManager(c, reactor, iv); ReactorActionManager rm = new ReactorActionManager(c, reactor, iv);
engine.put("rm", rm); iv.put("rm", rm);
if (touching) { if (touching) {
iv.invokeFunction("touch"); iv.invokeFunction("touch");
} else { } else {