added client commands

This commit is contained in:
Unknown
2019-11-26 20:04:45 -05:00
parent 512ade90f1
commit 4e3c825722
6 changed files with 198 additions and 1 deletions
@@ -0,0 +1,81 @@
package kaptainwutax.seedcracker;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import kaptainwutax.seedcracker.command.ClientCommand;
import kaptainwutax.seedcracker.command.RenderCommand;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.command.CommandException;
import net.minecraft.server.command.ServerCommandSource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
public class ClientCommands {
public static final String PREFIX = "seed";
public static final List<ClientCommand> COMMANDS = new ArrayList<>();
public static RenderCommand RENDER;
static {
COMMANDS.add(RENDER = new RenderCommand());
}
public static void registerCommands(CommandDispatcher<ServerCommandSource> dispatcher) {
COMMANDS.forEach(clientCommand -> clientCommand.register(dispatcher));
}
public static boolean isClientSideCommand(String[] params) {
if(params.length < 2)return false;
if(!PREFIX.equals(params[0]))return false;
for(ClientCommand command: COMMANDS) {
if(command.getName().equals(params[1])) {
return true;
}
}
return false;
}
public static int executeCommand(StringReader reader) {
ClientPlayerEntity player = MinecraftClient.getInstance().player;
try {
return player.networkHandler.getCommandDispatcher().execute(reader, new FakeCommandSource(player));
} catch(CommandException e) {
//lazy
e.printStackTrace();
} catch(CommandSyntaxException e) {
//lazy
e.printStackTrace();
} catch(Exception e) {
//lazy
e.printStackTrace();
}
return 1;
}
/**
* Shoutout to Earthcomputer for this awesome class.
* https://github.com/Earthcomputer/clientcommands/blob/fabric/src/main/java/net/earthcomputer/clientcommands/command/FakeCommandSource.java
* */
public static class FakeCommandSource extends ServerCommandSource {
public FakeCommandSource(ClientPlayerEntity player) {
super(player, player.getPosVector(), player.getRotationClient(), null, 0, player.getEntityName(), player.getName(), null, player);
}
@Override
public Collection<String> getPlayerNames() {
return MinecraftClient.getInstance().getNetworkHandler().getPlayerList()
.stream().map(e -> e.getProfile().getName()).collect(Collectors.toList());
}
}
}
@@ -0,0 +1,28 @@
package kaptainwutax.seedcracker.command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import kaptainwutax.seedcracker.ClientCommands;
import net.minecraft.client.MinecraftClient;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.LiteralText;
import static net.minecraft.server.command.CommandManager.literal;
public abstract class ClientCommand {
public abstract String getName();
public abstract void build(LiteralArgumentBuilder<ServerCommandSource> builder);
protected final void sendFeedback(String message, boolean overlay) {
MinecraftClient.getInstance().player.addChatMessage(new LiteralText(message), overlay);
}
public final void register(CommandDispatcher<ServerCommandSource> dispatcher) {
LiteralArgumentBuilder<ServerCommandSource> builder = literal(this.getName());
this.build(builder);
dispatcher.register(literal(ClientCommands.PREFIX).then(builder));
}
}
@@ -0,0 +1,37 @@
package kaptainwutax.seedcracker.command;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import kaptainwutax.seedcracker.FinderQueue;
import net.minecraft.server.command.ServerCommandSource;
import static net.minecraft.server.command.CommandManager.literal;
public class RenderCommand extends ClientCommand {
@Override
public String getName() {
return "render";
}
@Override
public void build(LiteralArgumentBuilder<ServerCommandSource> builder) {
builder.then(literal("outlines")
.executes(context -> this.printRenderMode())
.then(literal("XRAY").executes(context -> this.setRenderMode(FinderQueue.RenderType.XRAY)))
.then(literal("ON").executes(context -> this.setRenderMode(FinderQueue.RenderType.ON)))
.then(literal("OFF").executes(context -> this.setRenderMode(FinderQueue.RenderType.OFF)))
);
}
private int printRenderMode() {
this.sendFeedback("Current render mode is set to [" + FinderQueue.get().renderType + "].", false);
return 0;
}
private int setRenderMode(FinderQueue.RenderType renderType) {
FinderQueue.get().renderType = renderType;
this.sendFeedback("Set render mode to [" + FinderQueue.get().renderType + "].", false);
return 0;
}
}
@@ -1,9 +1,18 @@
package kaptainwutax.seedcracker.mixin;
import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.CommandDispatcher;
import kaptainwutax.seedcracker.ClientCommands;
import kaptainwutax.seedcracker.FinderQueue;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.packet.ChunkDataS2CPacket;
import net.minecraft.client.network.packet.CommandTreeS2CPacket;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.network.ClientConnection;
import net.minecraft.server.command.CommandSource;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.util.math.ChunkPos;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -15,6 +24,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
public abstract class ClientPlayNetworkHandlerMixin {
@Shadow private ClientWorld world;
@Shadow private CommandDispatcher<CommandSource> commandDispatcher;
@Inject(method = "onChunkData", at = @At("RETURN"))
private void onChunkData(ChunkDataS2CPacket packet, CallbackInfo ci) {
@@ -23,4 +33,15 @@ public abstract class ClientPlayNetworkHandlerMixin {
FinderQueue.get().onChunkData(this.world, new ChunkPos(chunkX, chunkZ));
}
@Inject(method = "<init>", at = @At("RETURN"))
public void onInit(MinecraftClient mc, Screen screen, ClientConnection connection, GameProfile profile, CallbackInfo ci) {
ClientCommands.registerCommands((CommandDispatcher<ServerCommandSource>)(Object)this.commandDispatcher);
}
@SuppressWarnings("unchecked")
@Inject(method = "onCommandTree", at = @At("TAIL"))
public void onOnCommandTree(CommandTreeS2CPacket packet, CallbackInfo ci) {
ClientCommands.registerCommands((CommandDispatcher<ServerCommandSource>)(Object)this.commandDispatcher);
}
}
@@ -0,0 +1,29 @@
package kaptainwutax.seedcracker.mixin;
import com.mojang.brigadier.StringReader;
import kaptainwutax.seedcracker.ClientCommands;
import net.minecraft.client.network.ClientPlayerEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientPlayerEntity.class)
public class ClientPlayerEntityMixin {
@Inject(method = "sendChatMessage", at = @At("HEAD"), cancellable = true)
private void onSendChatMessage(String message, CallbackInfo ci) {
if(!message.startsWith("/"))return;
StringReader reader = new StringReader(message);
reader.skip();
int cursor = reader.getCursor();
reader.setCursor(cursor);
if(ClientCommands.isClientSideCommand(message.substring(1).split(" "))) {
ClientCommands.executeCommand(reader);
ci.cancel();
}
}
}
+2 -1
View File
@@ -8,7 +8,8 @@
"DisableableProfilerMixin",
"GameRendererMixin",
"ClientPlayNetworkHandlerMixin",
"ClientWorldMixin"
"ClientWorldMixin",
"ClientPlayerEntityMixin"
],
"injectors": {
"defaultRequire": 1