diff --git a/src/main/java/carpet/script/CarpetScriptServer.java b/src/main/java/carpet/script/CarpetScriptServer.java index 7f0a3f2c..f6f47d2d 100644 --- a/src/main/java/carpet/script/CarpetScriptServer.java +++ b/src/main/java/carpet/script/CarpetScriptServer.java @@ -51,6 +51,7 @@ public class CarpetScriptServer public Set unloadableModules; public long tickStart; public boolean stopAll; + public int tickDepth; private Set holyMoly; public CarpetEventServer events; diff --git a/src/main/java/carpet/script/api/Auxiliary.java b/src/main/java/carpet/script/api/Auxiliary.java index eeefd681..cb8dbee4 100644 --- a/src/main/java/carpet/script/api/Auxiliary.java +++ b/src/main/java/carpet/script/api/Auxiliary.java @@ -634,30 +634,40 @@ public class Auxiliary { expression.addLazyFunction("game_tick", -1, (c, t, lv) -> { - ServerCommandSource s = ((CarpetContext)c).s; + CarpetContext cc = (CarpetContext)c; + ServerCommandSource s = cc.s; if (!s.getMinecraftServer().isOnThread()) throw new InternalExpressionException("Unable to run ticks from threads"); - ((MinecraftServerInterface)s.getMinecraftServer()).forceTick( () -> System.nanoTime()- CarpetServer.scriptServer.tickStart<50000000L); - if (lv.size()>0) + if (CarpetServer.scriptServer.tickDepth > 16) throw new InternalExpressionException("'game_tick' function caused other 'game_tick' functions to run. You should not allow that."); + try { - long ms_total = NumericValue.asNumber(lv.get(0).evalValue(c)).getLong(); - long end_expected = CarpetServer.scriptServer.tickStart+ms_total*1000000L; - long wait = end_expected-System.nanoTime(); - if (wait > 0L) + CarpetServer.scriptServer.tickDepth ++; + ((MinecraftServerInterface) s.getMinecraftServer()).forceTick(() -> System.nanoTime() - CarpetServer.scriptServer.tickStart < 50000000L); + if (lv.size() > 0) { - try - { - Thread.sleep(wait/1000000L); - } - catch (InterruptedException ignored) + long ms_total = NumericValue.asNumber(lv.get(0).evalValue(c)).getLong(); + long end_expected = CarpetServer.scriptServer.tickStart + ms_total * 1000000L; + long wait = end_expected - System.nanoTime(); + if (wait > 0L) { + try + { + Thread.sleep(wait / 1000000L); + } + catch (InterruptedException ignored) + { + } } } + CarpetServer.scriptServer.tickStart = System.nanoTime(); // for the next tick + Thread.yield(); + } + finally + { + CarpetServer.scriptServer.tickDepth --; } - CarpetServer.scriptServer.tickStart = System.nanoTime(); // for the next tick - Thread.yield(); if(CarpetServer.scriptServer.stopAll) throw new ExitStatement(Value.NULL); - return (cc, tt) -> Value.TRUE; + return (_c, _t) -> Value.TRUE; }); expression.addLazyFunction("seed", -1, (c, t, lv) -> {