Make all reactor script invocations thread safe

Might be a bit overkill to force synchronization
for every single method invocation when the only
scheduling done in reactor scripts are:
- 5511000 (summon Targa)
- 5511001 (summon Scarlion)
This commit is contained in:
P0nk
2021-05-20 21:30:46 +02:00
parent 2ce6041ef8
commit cdfb7074ec
2 changed files with 25 additions and 16 deletions

View File

@@ -13,10 +13,14 @@ import javax.script.ScriptException;
public class SynchronizedInvocable implements Invocable {
private final Invocable invocable;
public SynchronizedInvocable(Invocable invocable) {
private SynchronizedInvocable(Invocable invocable) {
this.invocable = invocable;
}
public static Invocable of(Invocable invocable) {
return new SynchronizedInvocable(invocable);
}
@Override
public synchronized Object invokeMethod(Object thiz, String name, Object... args) throws ScriptException, NoSuchMethodException {
return invocable.invokeMethod(thiz, name, args);

View File

@@ -23,6 +23,7 @@ package scripting.reactor;
import client.MapleClient;
import scripting.AbstractScriptManager;
import scripting.SynchronizedInvocable;
import server.maps.MapleReactor;
import server.maps.ReactorDropEntry;
import tools.DatabaseConnection;
@@ -53,14 +54,11 @@ public class ReactorScriptManager extends AbstractScriptManager {
public void onHit(MapleClient c, MapleReactor reactor) {
try {
ScriptEngine engine = getInvocableScriptEngine("reactor/" + reactor.getId() + ".js", c);
if (engine == null) {
Invocable iv = initializeInvocable(c, reactor);
if (iv == null) {
return;
}
Invocable iv = (Invocable) engine;
ReactorActionManager rm = new ReactorActionManager(c, reactor, iv);
engine.put("rm", rm);
iv.invokeFunction("hit");
} catch (final NoSuchMethodException e) {} //do nothing, hit is OPTIONAL
@@ -71,14 +69,11 @@ public class ReactorScriptManager extends AbstractScriptManager {
public void act(MapleClient c, MapleReactor reactor) {
try {
ScriptEngine engine = getInvocableScriptEngine("reactor/" + reactor.getId() + ".js", c);
if (engine == null) {
Invocable iv = initializeInvocable(c, reactor);
if (iv == null) {
return;
}
Invocable iv = (Invocable) engine;
ReactorActionManager rm = new ReactorActionManager(c, reactor, iv);
engine.put("rm", rm);
iv.invokeFunction("act");
} catch (final ScriptException | NoSuchMethodException | NullPointerException e) {
FilePrinter.printError(FilePrinter.REACTOR + reactor.getId() + ".txt", e);
@@ -120,14 +115,11 @@ public class ReactorScriptManager extends AbstractScriptManager {
private void touching(MapleClient c, MapleReactor reactor, boolean touching) {
try {
ScriptEngine engine = getInvocableScriptEngine("reactor/" + reactor.getId() + ".js", c);
if (engine == null) {
Invocable iv = initializeInvocable(c, reactor);
if (iv == null) {
return;
}
Invocable iv = (Invocable) engine;
ReactorActionManager rm = new ReactorActionManager(c, reactor, iv);
engine.put("rm", rm);
if (touching) {
iv.invokeFunction("touch");
} else {
@@ -137,4 +129,17 @@ public class ReactorScriptManager extends AbstractScriptManager {
FilePrinter.printError(FilePrinter.REACTOR + reactor.getId() + ".txt", ute);
}
}
private Invocable initializeInvocable(MapleClient c, MapleReactor reactor) {
ScriptEngine engine = getInvocableScriptEngine("reactor/" + reactor.getId() + ".js", c);
if (engine == null) {
return null;
}
Invocable iv = SynchronizedInvocable.of((Invocable) engine);
ReactorActionManager rm = new ReactorActionManager(c, reactor, iv);
engine.put("rm", rm);
return iv;
}
}