From 1bec0f88f4076388f919a433007a416910a621e7 Mon Sep 17 00:00:00 2001 From: gnembon Date: Thu, 10 Sep 2020 01:48:32 -0300 Subject: [PATCH] `run` now returns success count, intercepted output and an error message. Good for parsing. Fixes #428 --- docs/scarpet/Full.md | 10 ++++-- docs/scarpet/api/Auxiliary.md | 10 ++++-- .../java/carpet/script/api/Auxiliary.java | 35 ++++++++++++++++--- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/docs/scarpet/Full.md b/docs/scarpet/Full.md index 05eb2756..5c0a4f76 100644 --- a/docs/scarpet/Full.md +++ b/docs/scarpet/Full.md @@ -3776,11 +3776,15 @@ read_file('foo', 'shared_text') => ['one', 'two', 'three', '', 'four', '', ' ### `run(expr)` -Runs a vanilla command from the string result of the `expr` and returns its success count +Runs a vanilla command from the string result of the `expr` and returns a triple of success count, +intercepted list of output messages, and error message if the command resulted in a failure. +Successful commands return `null` as their error.
-run('fill 1 1 1 10 10 10 air') -> 123 // 123 block were filled, this operation was successful 123 times out of a possible 1000 block volume
-run('give @s stone 4') -> 1 // this operation was successful once
+run('fill 1 1 1 10 10 10 air') -> [123, ["Successfully filled 123 blocks"], null] // 123 block were filled, this operation was successful 123 times out of a possible 1000 block volume
+run('give @s stone 4') -> [1, ["Gave 4 [Stone] to gnembon"], null] // this operation was successful once
+run('seed') -> [-170661413, ["Seed: [4031384495743822299]"], null]
+run('sed') -> [0, [], "sed<--[HERE]"] // wrong command
 
### `save()` diff --git a/docs/scarpet/api/Auxiliary.md b/docs/scarpet/api/Auxiliary.md index 76bc349d..4b27a290 100644 --- a/docs/scarpet/api/Auxiliary.md +++ b/docs/scarpet/api/Auxiliary.md @@ -313,11 +313,15 @@ read_file('foo', 'shared_text') => ['one', 'two', 'three', '', 'four', '', ' ### `run(expr)` -Runs a vanilla command from the string result of the `expr` and returns its success count +Runs a vanilla command from the string result of the `expr` and returns a triple of success count, +intercepted list of output messages, and error message if the command resulted in a failure. +Successful commands return `null` as their error.
-run('fill 1 1 1 10 10 10 air') -> 123 // 123 block were filled, this operation was successful 123 times out of a possible 1000 block volume
-run('give @s stone 4') -> 1 // this operation was successful once
+run('fill 1 1 1 10 10 10 air') -> [123, ["Successfully filled 123 blocks"], null] // 123 block were filled, this operation was successful 123 times out of a possible 1000 block volume
+run('give @s stone 4') -> [1, ["Gave 4 [Stone] to gnembon"], null] // this operation was successful once
+run('seed') -> [-170661413, ["Seed: [4031384495743822299]"], null]
+run('sed') -> [0, [], "sed<--[HERE]"] // wrong command
 
### `save()` diff --git a/src/main/java/carpet/script/api/Auxiliary.java b/src/main/java/carpet/script/api/Auxiliary.java index 48925ca0..accb93a7 100644 --- a/src/main/java/carpet/script/api/Auxiliary.java +++ b/src/main/java/carpet/script/api/Auxiliary.java @@ -30,6 +30,7 @@ import carpet.script.value.Value; import carpet.script.value.ValueConversions; import carpet.utils.Messenger; import net.minecraft.block.BlockState; +import net.minecraft.command.argument.EntityAnchorArgumentType; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.EquipmentSlot; @@ -41,6 +42,7 @@ import net.minecraft.nbt.Tag; import net.minecraft.network.packet.s2c.play.PlaySoundIdS2CPacket; import net.minecraft.particle.ParticleEffect; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.command.CommandOutput; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; @@ -48,11 +50,13 @@ import net.minecraft.sound.SoundCategory; import net.minecraft.stat.Stat; import net.minecraft.stat.StatType; import net.minecraft.text.LiteralText; +import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.minecraft.util.InvalidIdentifierException; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.EulerAngle; +import net.minecraft.util.math.Vec2f; import net.minecraft.util.math.Vec3d; import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.RegistryKey; @@ -463,12 +467,35 @@ public class Auxiliary { ServerCommandSource s = ((CarpetContext)c).s; try { + Value[] error = {Value.NULL}; + List output = new ArrayList<>(); Value retval = new NumericValue(s.getMinecraftServer().getCommandManager().execute( - s.withPosition(posf).withSilent().withLevel(CarpetSettings.runPermissionLevel), lv.get(0).evalValue(c).getString())); - return (c_, t_) -> retval; + new ServerCommandSource( + CommandOutput.DUMMY, posf, Vec2f.ZERO, s.getWorld(), CarpetSettings.runPermissionLevel, + s.getName(), s.getDisplayName(), s.getMinecraftServer(), s.getPlayer(), true, + (ctx, succ, res) -> { }, EntityAnchorArgumentType.EntityAnchor.FEET) + { + @Override + public void sendError(Text message) + { + error[0] = new FormattedTextValue(message); + } + @Override + public void sendFeedback(Text message, boolean broadcastToOps) + { + output.add(new FormattedTextValue(message)); + } + }, + lv.get(0).evalValue(c).getString()) + ); + Value ret = ListValue.of(retval, ListValue.wrap(output), error[0]); + return (c_, t_) -> ret; + } + catch (Exception exc) + { + Value ret = ListValue.of(Value.NULL, ListValue.of(), new FormattedTextValue(new LiteralText(exc.getMessage()))); + return (c_, t_) -> ret; } - catch (Exception ignored) {} - return LazyValue.NULL; }); expression.addLazyFunction("save", 0, (c, t, lv) -> {