added first working command handler

This commit is contained in:
Marcel Marcel 2021-05-21 22:51:30 +02:00
parent de15912066
commit ac28939480
4 changed files with 154 additions and 1 deletions

View file

@ -0,0 +1,9 @@
package net.saltymc.eaa.commands;
import net.fabricmc.fabric.api.client.command.v1.FabricClientCommandSource;
public interface Command {
int run(FabricClientCommandSource cs, String[] args);
}

View file

@ -0,0 +1,118 @@
package net.saltymc.eaa.commands;
import com.mojang.brigadier.exceptions.BuiltInExceptionProvider;
import com.mojang.brigadier.exceptions.CommandExceptionType;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.fabricmc.fabric.api.client.command.v1.FabricClientCommandSource;
import net.minecraft.client.MinecraftClient;
import net.minecraft.command.CommandException;
import net.minecraft.network.MessageType;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import net.minecraft.text.Texts;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Formatting;
import net.minecraft.util.Util;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.HashMap;
import static net.fabricmc.fabric.api.client.command.v1.ClientCommandManager.DISPATCHER;
public class CommandHandler {
private static final char PREFIX = '/';
private static final Logger LOGGER = LogManager.getLogger();
private static HashMap<String, Command> commands;
//above line stolen from net.fabricmc.fabric.impl.command.client.ClientCommandInternals;
static {
if(CommandHandler.commands == null){
CommandHandler.commands = new HashMap<>();
}
CommandHandler.commands.put("p", new EaaCommand());
//TODO implement
}
/**
* Executes a client-sided command from a message.
*
* @param message the command message
* @return true if the message should not be sent to the server, false otherwise
*/
public static boolean executeCommand(String message) {
if (message.isEmpty()) {
return false; // Nothing to process
}
if (message.charAt(0) != PREFIX) {
return false; // Incorrect prefix, won't execute anything.
}
FabricClientCommandSource commandSource = (FabricClientCommandSource) MinecraftClient.getInstance().getNetworkHandler().getCommandSource();
//commandSource.getClient().getProfiler().push(message);
try {
//DISPATCHER.execute(message.substring(1), commandSource);
String command = message.replaceFirst(""+PREFIX,"").split(" ")[0];
String[] args = message.replaceFirst(""+PREFIX,"").split(" "); //TODO remove first item from array
System.out.println("command: $"+command+"$");
if(CommandHandler.commands.get(command) != null) {
CommandHandler.commands.get(command).run(commandSource, args);
}else{
return false;
}
return true;
/*} catch (CommandSyntaxException e) {
boolean ignored = isIgnoredException(e.getType());
LOGGER.log(ignored ? Level.DEBUG : Level.WARN, "Syntax exception for client-sided command '{}'", message, e);
if (ignored) {
return false;
}
commandSource.sendError(getErrorMessage(e));
return true;*/
} catch (CommandException e) {
LOGGER.warn("Error while executing client-sided command '{}'", message, e);
commandSource.sendError(e.getTextMessage());
return true;
} catch (RuntimeException e) {
LOGGER.warn("Error while executing client-sided command '{}'", message, e);
commandSource.sendError(Text.of(e.getMessage()));
return true;
} finally {
//commandSource.getClient().getProfiler().pop();
}
}
/**
* Tests whether a command syntax exception with the type
* should be ignored and the message sent to the server.
*
* @param type the exception type
* @return true if ignored, false otherwise
*/
private static boolean isIgnoredException(CommandExceptionType type) {
BuiltInExceptionProvider builtins = CommandSyntaxException.BUILT_IN_EXCEPTIONS;
// Only ignore unknown commands and node parse exceptions.
// The argument-related dispatcher exceptions are not ignored because
// they will only happen if the user enters a correct command.
return type == builtins.dispatcherUnknownCommand() || type == builtins.dispatcherParseException();
}
// See CommandSuggestor.method_30505. That cannot be used directly as it returns an OrderedText instead of a Text.
private static Text getErrorMessage(CommandSyntaxException e) {
Text message = Texts.toText(e.getRawMessage());
String context = e.getContext();
return context != null ? new TranslatableText("command.context.parse_error", message, context) : message;
}
}

View file

@ -0,0 +1,13 @@
package net.saltymc.eaa.commands;
import net.fabricmc.fabric.api.client.command.v1.FabricClientCommandSource;
import net.minecraft.text.Text;
public class EaaCommand implements Command{
@Override
public int run(FabricClientCommandSource cs, String[] args) {
cs.sendFeedback(Text.of("command catched!"));
return 0;
}
}

View file

@ -1,11 +1,13 @@
package net.saltymc.eaa.mixin; package net.saltymc.eaa.mixin;
import net.minecraft.client.gui.screen.TitleScreen; import net.minecraft.client.gui.screen.TitleScreen;
import net.minecraft.client.network.ClientPlayerEntity;
import net.saltymc.eaa.commands.CommandHandler;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/*
@Mixin(TitleScreen.class) @Mixin(TitleScreen.class)
public class ExampleMixin { public class ExampleMixin {
@Inject(at = @At("HEAD"), method = "init()V") @Inject(at = @At("HEAD"), method = "init()V")
@ -13,3 +15,14 @@ public class ExampleMixin {
System.out.println("This line is printed by an example mod mixin!"); System.out.println("This line is printed by an example mod mixin!");
} }
} }
*/
@Mixin(ClientPlayerEntity.class)
public class ExampleMixin { //ClientPlayerEntityMixin
@Inject(method = "sendChatMessage", at = @At("HEAD"), cancellable = true)
private void onSendChatMessage(String message, CallbackInfo info) {
System.out.println("in onSendChatMessage");
if (CommandHandler.executeCommand(message)) {
info.cancel();
}
}
}