From 652472524541a586f7190546de00c750bf24c3ba Mon Sep 17 00:00:00 2001 From: gnembon Date: Tue, 15 Oct 2019 09:37:50 -0300 Subject: [PATCH] fixes to scarpet 1.5 --- src/main/java/carpet/CarpetServer.java | 1 + .../java/carpet/commands/ScriptCommand.java | 4 +- .../java/carpet/script/CarpetEventServer.java | 16 +++++-- .../java/carpet/script/CarpetExpression.java | 41 +++++++++++++++-- .../carpet/script/CarpetScriptServer.java | 44 +++++++++++++++---- src/main/java/carpet/script/Expression.java | 21 +++++++-- src/main/java/carpet/script/ScriptHost.java | 15 +++++-- .../java/carpet/script/value/ListValue.java | 5 +-- .../java/carpet/script/value/MapValue.java | 2 +- .../java/carpet/settings/CarpetSettings.java | 4 +- .../java/carpet/settings/SettingsManager.java | 6 +++ 11 files changed, 129 insertions(+), 30 deletions(-) diff --git a/src/main/java/carpet/CarpetServer.java b/src/main/java/carpet/CarpetServer.java index b46928a9..b50b6a86 100644 --- a/src/main/java/carpet/CarpetServer.java +++ b/src/main/java/carpet/CarpetServer.java @@ -112,6 +112,7 @@ public class CarpetServer // static for now - easier to handle all around the co public static void onServerClosed(MinecraftServer server) { scriptServer.onClose(); + settingsManager.detachServer(); LoggerRegistry.stopLoggers(); extensions.forEach(e -> e.onServerClosed(server)); } diff --git a/src/main/java/carpet/commands/ScriptCommand.java b/src/main/java/carpet/commands/ScriptCommand.java index fb4b690f..cc50a66d 100644 --- a/src/main/java/carpet/commands/ScriptCommand.java +++ b/src/main/java/carpet/commands/ScriptCommand.java @@ -208,13 +208,13 @@ public class ScriptCommand suggests( (cc, bb) -> suggestMatching(CarpetServer.scriptServer.listAvailableModules(true),bb)). executes((cc) -> { - boolean success = CarpetServer.scriptServer.addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "package"), true); + boolean success = CarpetServer.scriptServer.addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "package"), true, false); return success?1:0; }). then(literal("shared"). executes((cc) -> { - boolean success = CarpetServer.scriptServer.addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "package"), false); + boolean success = CarpetServer.scriptServer.addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "package"), false, false); return success?1:0; } ) diff --git a/src/main/java/carpet/script/CarpetEventServer.java b/src/main/java/carpet/script/CarpetEventServer.java index 54ab74f1..ff74838e 100644 --- a/src/main/java/carpet/script/CarpetEventServer.java +++ b/src/main/java/carpet/script/CarpetEventServer.java @@ -18,6 +18,7 @@ import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; +import net.minecraft.world.dimension.DimensionType; import java.util.ArrayList; import java.util.Arrays; @@ -148,7 +149,10 @@ public class CarpetEventServer @Override public void onTick() { - handler.call(Collections::emptyList, CarpetServer.minecraft_server::getCommandSource); + handler.call(Collections::emptyList, () -> + CarpetServer.minecraft_server.getCommandSource(). + withWorld(CarpetServer.minecraft_server.getWorld(DimensionType.OVERWORLD)) + ); } }, NETHER_TICK("tick_nether",new CallbackList(0)) @@ -156,7 +160,10 @@ public class CarpetEventServer @Override public void onTick() { - handler.call(Collections::emptyList, CarpetServer.minecraft_server::getCommandSource); + handler.call(Collections::emptyList, () -> + CarpetServer.minecraft_server.getCommandSource(). + withWorld(CarpetServer.minecraft_server.getWorld(DimensionType.THE_NETHER)) + ); } }, ENDER_TICK("tick_ender",new CallbackList(0)) @@ -164,7 +171,10 @@ public class CarpetEventServer @Override public void onTick() { - handler.call(Collections::emptyList, CarpetServer.minecraft_server::getCommandSource); + handler.call(Collections::emptyList, () -> + CarpetServer.minecraft_server.getCommandSource(). + withWorld(CarpetServer.minecraft_server.getWorld(DimensionType.THE_END)) + ); } }, PLAYER_JUMPS("player_jumps", new CallbackList(1)) diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index 3ccea2b3..8dc34cb8 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -67,6 +67,7 @@ import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.math.Direction; import net.minecraft.util.math.EulerAngle; import net.minecraft.util.math.Vec3d; import net.minecraft.util.registry.Registry; @@ -686,6 +687,24 @@ public class CarpetExpression } }); + this.expr.addLazyFunction("pos_offset", -1, (c, t, lv) -> + { + BlockValue.LocatorResult locator = BlockValue.fromParams((CarpetContext)c, lv, 0); + BlockPos pos = locator.block.getPos(); + if (lv.size() <= locator.offset) + throw new InternalExpressionException("block_offset needs at least position, and direction"); + String directionString = lv.get(locator.offset).evalValue(c).getString(); + Direction dir = Direction.byName(directionString); + if (dir == null) + throw new InternalExpressionException("Unknown direction: "+directionString); + int howMuch = 1; + if (lv.size() > locator.offset+1) + howMuch = (int) NumericValue.asNumber(lv.get(locator.offset+1).evalValue(c)).getLong(); + BlockPos retpos = pos.offset(dir, howMuch); + Value ret = ListValue.of(new NumericValue(retpos.getX()), new NumericValue(retpos.getY()), new NumericValue(retpos.getZ())); + return (cc, tt) -> ret; + }); + this.expr.addLazyFunction("solid", -1, (c, t, lv) -> genericStateTest(c, "solid", lv, (s, p, w) -> new NumericValue(s.isSimpleFullBlock(w, p)))); @@ -1146,6 +1165,16 @@ public class CarpetExpression return (_c, _t) -> res; }); + this.expr.addLazyFunction("inventory_has_items", -1, (c, t, lv) -> + { + CarpetContext cc = (CarpetContext) c; + NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0); + if (inventoryLocator == null) + return (_c, _t) -> Value.NULL; + Value res = new NumericValue(!inventoryLocator.inventory.isInvEmpty()); + return (_c, _t) -> res; + }); + //inventory_get(, ) -> item_triple this.expr.addLazyFunction("inventory_get", -1, (c, t, lv) -> { @@ -2737,6 +2766,12 @@ public class CarpetExpression return (_c, _t) -> res; // pass through for variables }); + this.expr.addLazyFunction("logger", 1, (c, t, lv) -> + { + Value res = lv.get(0).evalValue(c); + CarpetSettings.LOG.error(res.getString()); + return (_c, _t) -> res; // pass through for variables + }); this.expr.addLazyFunction("run", 1, (c, t, lv) -> { BlockPos target = ((CarpetContext)c).origin; @@ -2875,7 +2910,7 @@ public class CarpetExpression return (c_, t_) -> Value.TRUE; }); - this.expr.addLazyFunction("get_global_state", -1, (c, t, lv) -> + this.expr.addLazyFunction("load_app_data", -1, (c, t, lv) -> { String file = null; if (lv.size()>0) @@ -2887,10 +2922,10 @@ public class CarpetExpression return (cc, tt) -> retVal; }); - this.expr.addLazyFunction("set_global_state", -1, (c, t, lv) -> + this.expr.addLazyFunction("store_app_data", -1, (c, t, lv) -> { if (lv.size() == 0) - throw new InternalExpressionException("save_state needs nbt tag and optional file"); + throw new InternalExpressionException("store_app_data needs nbt tag and optional file"); Value val = lv.get(0).evalValue(c); String file = null; if (lv.size()>1) diff --git a/src/main/java/carpet/script/CarpetScriptServer.java b/src/main/java/carpet/script/CarpetScriptServer.java index c19f8fa8..3c92548f 100644 --- a/src/main/java/carpet/script/CarpetScriptServer.java +++ b/src/main/java/carpet/script/CarpetScriptServer.java @@ -1,6 +1,8 @@ package carpet.script; import carpet.script.bundled.BundledModule; +import carpet.script.value.MapValue; +import carpet.script.value.StringValue; import carpet.settings.CarpetSettings; import carpet.CarpetServer; import carpet.script.bundled.FileModule; @@ -19,6 +21,7 @@ import net.minecraft.util.math.BlockPos; import java.io.File; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -59,9 +62,10 @@ public class CarpetScriptServer { if (CarpetSettings.scriptsAutoload) { + Messenger.m(CarpetServer.minecraft_server.getCommandSource(), "Autoloading world scarpet apps"); for (String moduleName: listAvailableModules(false)) { - addScriptHost(CarpetServer.minecraft_server.getCommandSource(), moduleName, true); + addScriptHost(CarpetServer.minecraft_server.getCommandSource(), moduleName, true, true); } } @@ -156,7 +160,7 @@ public class CarpetScriptServer return host; } - public boolean addScriptHost(ServerCommandSource source, String name, boolean perPlayer) + public boolean addScriptHost(ServerCommandSource source, String name, boolean perPlayer, boolean autoload) { //TODO add per player modules to support player actions better on a server name = name.toLowerCase(Locale.ROOT); @@ -164,32 +168,56 @@ public class CarpetScriptServer ScriptHost newHost = createMinecraftScriptHost(name, module, perPlayer, source); if (newHost == null) { - Messenger.m(source, "r Failed to add a module"); + Messenger.m(source, "r Failed to add "+name+" app"); return false; } if (module == null) { - Messenger.m(source, "r Unable to locate the package, but created empty host "+name+" instead"); + Messenger.m(source, "r Unable to locate the app, but created empty "+name+" app instead"); modules.put(name, newHost); return true; } String code = module.getCode(); if (module.getCode() == null) { - Messenger.m(source, "r Unable to load the package - not found"); + Messenger.m(source, "r Unable to load "+name+" app - not found"); return false; } modules.put(name, newHost); + if (!addConfig(source, name) && autoload) + { + removeScriptHost(source, name); + return false; + } addEvents(source, name); - addCommand(source, name); return true; } - public void addEvents(ServerCommandSource source, String hostName) + private boolean addConfig(ServerCommandSource source, String hostName) + { + ScriptHost host = modules.get(hostName); + if (host == null || !host.globalFunctions.containsKey("__config")) + { + return false; + } + try + { + Value ret = host.callUDF(BlockPos.ORIGIN, source, host.globalFunctions.get("__config"), Collections.emptyList()); + if (!(ret instanceof MapValue)) return false; + Map config = ((MapValue) ret).getMap(); + host.setPerPlayer(config.getOrDefault(new StringValue("scope"), new StringValue("player")).getString().equalsIgnoreCase("player")); + return config.getOrDefault(new StringValue("stay_loaded"), Value.FALSE).getBoolean(); + } + catch (NullPointerException | InvalidCallbackException ignored) + { + } + return false; + } + private void addEvents(ServerCommandSource source, String hostName) { ScriptHost host = modules.get(hostName); if (host == null) @@ -208,7 +236,7 @@ public class CarpetScriptServer } - public void addCommand(ServerCommandSource source, String hostName) + private void addCommand(ServerCommandSource source, String hostName) { ScriptHost host = modules.get(hostName); if (host == null) diff --git a/src/main/java/carpet/script/Expression.java b/src/main/java/carpet/script/Expression.java index 1ba0bc63..de69545f 100644 --- a/src/main/java/carpet/script/Expression.java +++ b/src/main/java/carpet/script/Expression.java @@ -1323,7 +1323,7 @@ public class Expression implements Cloneable addLazyBinaryOperator("+=", precedence.get("assign=<>"), false, (c, t, lv1, lv2) -> { - Value v1 = lv1.evalValue(c); + Value v1 = lv1.evalValue(c, Context.LVALUE); Value v2 = lv2.evalValue(c); if (v1 instanceof ListValue.ListConstructorValue && v2 instanceof ListValue) { @@ -1343,6 +1343,18 @@ public class Expression implements Cloneable } return (cc, tt) -> Value.TRUE; } + if (v1 instanceof LContainerValue) + { + ContainerValueInterface cvi = ((LContainerValue) v1).getContainer(); + if (cvi == null) + { + throw new InternalExpressionException("Failed to resolve left hand side of the += operation"); + } + Value key = ((LContainerValue) v1).getAddress(); + Value res = cvi.get(key).add(v2); + cvi.put(key, res); + return (cc, tt) -> res; + } v1.assertAssignable(); String varname = v1.getVariable(); LazyValue boundedLHS; @@ -2360,7 +2372,10 @@ public class Expression implements Cloneable return (cc, tt) -> innerLValue; } if (!(container instanceof ContainerValueInterface)) - return (cc, tt) -> Value.NULL; + if (t == Context.LVALUE) + return (cc, tt) -> new LContainerValue(null, null); + else + return (cc, tt) -> Value.NULL; Value address = key_lv.evalValue(c); if (t != Context.LVALUE) { @@ -2456,7 +2471,7 @@ public class Expression implements Cloneable Value address = ((LContainerValue) container).getAddress(); Value what = lv.get(1).evalValue(c); Value retVal = new NumericValue( (lv.size() > 2) - ? internalContainer.put(address, what, lv.get(3).evalValue(c)) + ? internalContainer.put(address, what, lv.get(2).evalValue(c)) : internalContainer.put(address, what)); return (cc, tt) -> retVal; diff --git a/src/main/java/carpet/script/ScriptHost.java b/src/main/java/carpet/script/ScriptHost.java index f0901383..7b362bf3 100644 --- a/src/main/java/carpet/script/ScriptHost.java +++ b/src/main/java/carpet/script/ScriptHost.java @@ -39,7 +39,7 @@ public class ScriptHost public String getName() {return name;} private final ModuleInterface myCode; - private final boolean perUser; + private boolean perUser; ScriptHost(String name, ModuleInterface code, boolean perUser, ScriptHost parent) { @@ -207,10 +207,10 @@ public class ScriptHost } } - public void callUDF(BlockPos pos, ServerCommandSource source, UserDefinedFunction acf, List argv) throws InvalidCallbackException + public Value callUDF(BlockPos pos, ServerCommandSource source, UserDefinedFunction acf, List argv) throws InvalidCallbackException { if (CarpetServer.scriptServer.stopAll) - return; + return Value.NULL; List args = acf.getArguments(); if (argv.size() != args.size()) @@ -221,7 +221,7 @@ public class ScriptHost { // TODO: this is just for now - invoke would be able to invoke other hosts scripts Context context = new CarpetContext(this, source, pos); - Expression.evalValue( + return Expression.evalValue( () -> acf.lazyEval(context, Context.VOID, acf.expression, acf.token, argv), context, Context.VOID); @@ -230,6 +230,7 @@ public class ScriptHost { CarpetSettings.LOG.error("Callback failed: "+e.getMessage()); } + return Value.NULL; } private void dumpState() @@ -288,4 +289,10 @@ public class ScriptHost if (this.saveTimeout > 0) dumpState(); } + + public void setPerPlayer(boolean isPerUser) + { + CarpetSettings.LOG.error("Setting per player for "+name+" of "+isPerUser); + perUser = isPerUser; + } } diff --git a/src/main/java/carpet/script/value/ListValue.java b/src/main/java/carpet/script/value/ListValue.java index c7e77bf6..3b404d21 100644 --- a/src/main/java/carpet/script/value/ListValue.java +++ b/src/main/java/carpet/script/value/ListValue.java @@ -227,10 +227,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf return items; } - public Iterator iterator() - { - return items.iterator(); - } + public Iterator iterator() { return new ArrayList<>(items).iterator(); } public void extend(List subList) { diff --git a/src/main/java/carpet/script/value/MapValue.java b/src/main/java/carpet/script/value/MapValue.java index f924256b..c7237db9 100644 --- a/src/main/java/carpet/script/value/MapValue.java +++ b/src/main/java/carpet/script/value/MapValue.java @@ -30,7 +30,7 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa @Override public Iterator iterator() { - return map.keySet().iterator(); + return new ArrayList<>(map.keySet()).iterator(); } @Override diff --git a/src/main/java/carpet/settings/CarpetSettings.java b/src/main/java/carpet/settings/CarpetSettings.java index f707a39d..28e8d736 100644 --- a/src/main/java/carpet/settings/CarpetSettings.java +++ b/src/main/java/carpet/settings/CarpetSettings.java @@ -174,8 +174,8 @@ public class CarpetSettings @Rule( desc = "Enables /log command to monitor events in the game via chat and overlays", - category = COMMAND, - validate = Validator.WIP.class + category = COMMAND//, + //validate = Validator.WIP.class ) public static boolean commandLog = true; diff --git a/src/main/java/carpet/settings/SettingsManager.java b/src/main/java/carpet/settings/SettingsManager.java index f57e131a..349850d4 100644 --- a/src/main/java/carpet/settings/SettingsManager.java +++ b/src/main/java/carpet/settings/SettingsManager.java @@ -74,6 +74,12 @@ public class SettingsManager notifyPlayersCommandsChanged(); } + public void detachServer() + { + for (ParsedRule rule : rules.values()) rule.resetToDefault(server.getCommandSource()); + server = null; + } + public void parseSettingsClass(Class settingsClass) { for (Field f : settingsClass.getDeclaredFields())