From 07de4fb4a58bf8c676f97ff6bb35d0fde85ad22a Mon Sep 17 00:00:00 2001 From: gnembon <41132274+gnembon@users.noreply.github.com> Date: Fri, 14 Feb 2025 13:17:49 +0100 Subject: [PATCH] commands output reliable return values and new result for `run` if not run directly --- docs/scarpet/api/Auxiliary.md | 18 ++++++++++++++---- .../carpet/network/ServerNetworkHandler.java | 4 +++- src/main/java/carpet/script/api/Auxiliary.java | 10 ++++++++-- .../script/utils/SnoopyCommandSource.java | 12 ++++++------ 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/docs/scarpet/api/Auxiliary.md b/docs/scarpet/api/Auxiliary.md index 8427523e..5a3915fb 100644 --- a/docs/scarpet/api/Auxiliary.md +++ b/docs/scarpet/api/Auxiliary.md @@ -410,11 +410,21 @@ Runs a vanilla command from the string result of the `expr` and returns a triple intercepted list of output messages, and error message if the command resulted in a failure. Successful commands return `null` as their error. +The command return `null` if the command was not run immediately, but was scheduled for later execution +due to being requested while command was executed. This happens most commonly +when running `run` from a `/script run/invoke` command since that always results in piling up command to run while `script` is being executed. + +The mitigation for this is to use `run` in a separate scheduled function, or use `run` in a `tick` event, or literally in +any other way than directly from a `/script` command, which will ensure that the command runs immediately. +
-run('fill 1 1 1 10 10 10 air') -> [0, ["Successfully filled 123 blocks"], null]
-run('give @s stone 4') -> [0, ["Gave 4 [Stone] to gnembon"], null]
-run('seed') -> [0, ["Seed: [4031384495743822299]"], null]
-run('sed') -> [0, [], "sed<--[HERE]"] // wrong command
+run('fill 1 1 1 10 10 10 air') -> [123, ["Successfully filled 123 blocks"], null]
+run('give @s stone 4') -> [1, ["Gave 4 [Stone] to gnembon"], null]
+run('seed') -> [-170661413, [Seed: [4031384495743822299]], null]
+run('sed') -> [-1, [], "sed<--[HERE]"] // wrong command
+
+/script run run('setblock 0 0 0 stone') -> null
+/script run schedule(0, _() -> print(run('setblock 0 0 0 stone'))) -> [1, [Changed the block at 0, 0, 0], null]
 
### `save()` diff --git a/src/main/java/carpet/network/ServerNetworkHandler.java b/src/main/java/carpet/network/ServerNetworkHandler.java index 771bbaaa..2770e005 100644 --- a/src/main/java/carpet/network/ServerNetworkHandler.java +++ b/src/main/java/carpet/network/ServerNetworkHandler.java @@ -83,6 +83,7 @@ public class ServerNetworkHandler String id = commandData.getString("id"); List output = new ArrayList<>(); Component[] error = {null}; + int[] returnValue = {0}; if (player.getServer() == null) { error[0] = Component.literal("No Server"); @@ -90,7 +91,7 @@ public class ServerNetworkHandler else { player.getServer().getCommands().performPrefixedCommand( - new SnoopyCommandSource(player, error, output), command + new SnoopyCommandSource(player, error, output, returnValue), command ); } CompoundTag result = new CompoundTag(); @@ -99,6 +100,7 @@ public class ServerNetworkHandler { result.putString("error", error[0].getContents().toString()); } + result.putInt("return", returnValue[0]); ListTag outputResult = new ListTag(); for (Component line : output) { diff --git a/src/main/java/carpet/script/api/Auxiliary.java b/src/main/java/carpet/script/api/Auxiliary.java index 960d44b7..4770a03f 100644 --- a/src/main/java/carpet/script/api/Auxiliary.java +++ b/src/main/java/carpet/script/api/Auxiliary.java @@ -97,6 +97,7 @@ import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.OptionalLong; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; @@ -684,12 +685,17 @@ public class Auxiliary try { Component[] error = {null}; + OptionalLong[] returnValue = {OptionalLong.empty()}; List output = new ArrayList<>(); s.getServer().getCommands().performPrefixedCommand( - new SnoopyCommandSource(s, error, output), + new SnoopyCommandSource(s, error, output, returnValue), lv.get(0).getString()); + if (returnValue[0].isEmpty()) + { + return Value.NULL; + } return ListValue.of( - NumericValue.ZERO, + NumericValue.of(returnValue[0].getAsLong()), ListValue.wrap(output.stream().map(FormattedTextValue::new)), FormattedTextValue.of(error[0]) ); diff --git a/src/main/java/carpet/script/utils/SnoopyCommandSource.java b/src/main/java/carpet/script/utils/SnoopyCommandSource.java index fc2315db..74955665 100644 --- a/src/main/java/carpet/script/utils/SnoopyCommandSource.java +++ b/src/main/java/carpet/script/utils/SnoopyCommandSource.java @@ -19,6 +19,7 @@ import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.OptionalLong; import java.util.function.BinaryOperator; import java.util.function.Supplier; @@ -43,11 +44,11 @@ public class SnoopyCommandSource extends CommandSourceStack private final TaskChainer taskChainer; - public SnoopyCommandSource(CommandSourceStack original, Component[] error, List chatOutput) + public SnoopyCommandSource(CommandSourceStack original, Component[] error, List chatOutput, OptionalLong[] returnValue) { super(CommandSource.NULL, original.getPosition(), original.getRotation(), original.getLevel(), Vanilla.MinecraftServer_getRunPermissionLevel(original.getServer()), original.getTextName(), original.getDisplayName(), original.getServer(), original.getEntity(), false, - CommandResultCallback.EMPTY, EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(original.getServer())); + (b, i) -> returnValue[0] = OptionalLong.of(i), EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(original.getServer())); this.output = CommandSource.NULL; this.position = original.getPosition(); this.world = original.getLevel(); @@ -56,7 +57,7 @@ public class SnoopyCommandSource extends CommandSourceStack this.name = original.getDisplayName(); this.server = original.getServer(); this.entity = original.getEntity(); - this.resultConsumer = CommandResultCallback.EMPTY; + this.resultConsumer = (b, i) -> returnValue[0] = OptionalLong.of(i); this.entityAnchor = original.getAnchor(); this.rotation = original.getRotation(); this.error = error; @@ -65,7 +66,7 @@ public class SnoopyCommandSource extends CommandSourceStack this.taskChainer = TaskChainer.immediate(original.getServer()); } - public SnoopyCommandSource(ServerPlayer player, Component[] error, List output) + public SnoopyCommandSource(ServerPlayer player, Component[] error, List output, int [] result) { super(player.commandSource(), player.position(), player.getRotationVector(), player.level() instanceof final ServerLevel serverLevel ? serverLevel : null, @@ -79,7 +80,7 @@ public class SnoopyCommandSource extends CommandSourceStack this.name = player.getDisplayName(); this.server = player.level().getServer(); this.entity = player; - this.resultConsumer = CommandResultCallback.EMPTY; + this.resultConsumer = (b, i) -> result[0] = i; this.entityAnchor = EntityAnchorArgument.Anchor.FEET; this.rotation = player.getRotationVector(); // not a client call really this.error = error; @@ -203,5 +204,4 @@ public class SnoopyCommandSource extends CommandSourceStack { chatOutput.add(message.get()); } - }