Fancier run command

This commit is contained in:
Chipmunk 2023-01-21 10:27:03 -05:00
parent eb762c3441
commit ec431febec
5 changed files with 99 additions and 2 deletions

View file

@ -15,6 +15,7 @@ import land.chipmunk.chipmunkbot.plugins.*;
public class ChipmunkBot extends Client {
@Getter public final ChatPlugin chat = new ChatPlugin(this);
@Getter public final QueryPlugin query = new QueryPlugin(this);
@Getter public final PlayerListPlugin playerList = new PlayerListPlugin(this);
@Getter public final CommandManager commandManager = new CommandManager(this);
@Getter public final ChatCommandHandler chatCommandHandler = new ChatCommandHandler(this);

View file

@ -8,6 +8,11 @@ import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
import com.mojang.brigadier.context.CommandContext;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import java.util.concurrent.CompletableFuture;
public class RunCommand extends Command {
public RunCommand () {
@ -26,7 +31,16 @@ public class RunCommand extends Command {
final CommandSource source = context.getSource();
final ChipmunkBot client = source.client();
client.core().run(getString(context, "command"));
final CompletableFuture<CompoundTag> future = client.core().runTracked(getString(context, "command"));
future.thenApply(tag -> {
if (!tag.contains("LastOutput") || !(tag.get("LastOutput") instanceof StringTag)) return tag;
final String outputJson = ((StringTag) tag.get("LastOutput")).getValue();
final Component output = GsonComponentSerializer.gson().deserialize(outputJson);
source.sendOutput(output);
return tag;
});
return 1;
}

View file

@ -16,7 +16,7 @@ public class TestCommand extends Command {
}
public int helloWorld (CommandContext<CommandSource> context) {
CommandSource source = context.getSource();
final CommandSource source = context.getSource();
source.sendOutput(Component.text("Hello, world!"));
return 1;

View file

@ -25,6 +25,9 @@ import com.github.steveice10.opennbt.tag.builtin.ByteTag;
import com.google.gson.JsonObject;
import lombok.Getter;
import lombok.Setter;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CompletableFuture;
public class CommandCore extends SessionAdapter {
private ChipmunkBot client;
@ -130,4 +133,28 @@ public class CommandCore extends SessionAdapter {
incrementCurrentBlock();
}
public CompletableFuture<CompoundTag> runTracked (String command) {
final Session session = client.session();
final Vector3i currentBlock = currentBlockAbsolute();
// TODO: Support using repeating command blocks (on kaboom-like servers) (because less packets)
session.send(new ServerboundSetCommandBlockPacket(currentBlock, "", CommandBlockMode.SEQUENCE, false, false, false));
session.send(new ServerboundSetCommandBlockPacket(currentBlock, command, CommandBlockMode.REDSTONE, true, false, true));
incrementCurrentBlock();
CompletableFuture<CompoundTag> future = new CompletableFuture<CompoundTag>();
final TimerTask queryTask = new TimerTask() {
public void run () {
client.query().block(currentBlock)
.thenApply(tag -> { future.complete(tag); return tag; });
}
};
new Timer().schedule(queryTask, 50);
return future;
}
}

View file

@ -0,0 +1,55 @@
package land.chipmunk.chipmunkbot.plugins;
import land.chipmunk.chipmunkbot.Client;
import com.nukkitx.math.vector.Vector3i;
import com.github.steveice10.packetlib.packet.Packet;
import com.github.steveice10.packetlib.Session;
import com.github.steveice10.packetlib.event.session.SessionListener;
import com.github.steveice10.packetlib.event.session.SessionAdapter;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundBlockEntityTagQuery;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundEntityTagQuery;
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundTagQueryPacket;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import java.util.concurrent.CompletableFuture;
import java.util.Map;
import java.util.HashMap;
public class QueryPlugin extends SessionAdapter {
private Client client;
private int nextTransactionId = 0;
private Map<Integer, CompletableFuture<CompoundTag>> transactions = new HashMap<>();
public QueryPlugin (Client client) {
this.client = client;
client.session().addListener((SessionListener) this);
}
public CompletableFuture<CompoundTag> block (Vector3i position) {
final int transactionId = nextTransactionId++;
if (nextTransactionId > Integer.MAX_VALUE) nextTransactionId = 0; // ? Can and should I use negative numbers too?
client.session().send(new ServerboundBlockEntityTagQuery(transactionId, position));
final CompletableFuture<CompoundTag> future = new CompletableFuture<CompoundTag>();
transactions.put(transactionId, future);
return future;
}
public CompletableFuture<CompoundTag> entity (int entityId) {
final int transactionId = nextTransactionId++;
if (nextTransactionId > Integer.MAX_VALUE) nextTransactionId = 0; // ? Can and should I use negative numbers too?
client.session().send(new ServerboundEntityTagQuery(transactionId, entityId));
final CompletableFuture<CompoundTag> future = new CompletableFuture<CompoundTag>();
transactions.put(transactionId, future);
return future;
}
@Override
public void packetReceived (Session session, Packet packet) {
if (packet instanceof ClientboundTagQueryPacket) packetReceived(session, (ClientboundTagQueryPacket) packet);
}
public void packetReceived (Session session, ClientboundTagQueryPacket packet) {
transactions.get(packet.getTransactionId()).complete(packet.getNbt());
}
}