package moe.ymc.acron.cmd; import com.mojang.brigadier.ResultConsumer; import com.mojang.brigadier.context.CommandContext; import io.netty.channel.Channel; import moe.ymc.acron.s2c.response.EventCmdRes; import moe.ymc.acron.serialization.Serializer; import net.minecraft.server.command.ServerCommandSource; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; public class CmdResConsumer implements ResultConsumer { private static final Logger LOGGER = LogManager.getLogger(); private final @NotNull Channel channel; private final int id; private boolean hasResult; public CmdResConsumer(@NotNull Channel channel, int id) { this.channel = channel; this.id = id; } @Override public void onCommandComplete(CommandContext context, boolean success, int result) { LOGGER.debug("onCommandComplete[{}]: {} {}", id, success, result); // Ignore any failed results because CommandDispatcher#execute does not reliably send error // results to the consumer. // For example, fail results are either not sent at all (pre-processing errors), or // sent before writing the result, which both violates the spec. // We will send the failed results in a custom mixin. if (success) { hasResult = true; channel.writeAndFlush(Serializer.serialize(new EventCmdRes(id, success, result))); } } public void sendResultIfNot() { if (!hasResult) { channel.writeAndFlush(Serializer.serialize(new EventCmdRes(id, false, -1))); } } }