aboutsummaryrefslogtreecommitdiff
path: root/versions/1.16.2-forge/src
diff options
context:
space:
mode:
Diffstat (limited to 'versions/1.16.2-forge/src')
-rw-r--r--versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/ClientModLoaderMixin.java24
-rw-r--r--versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/GuiIngameForgeMixin.java19
-rw-r--r--versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/KeyboardListenerMixin.java17
-rw-r--r--versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/MinecraftMixin.java66
-rw-r--r--versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/MouseHelperAccessor.java11
-rw-r--r--versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/MouseHelperMixin.java17
-rw-r--r--versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/NetHandlerPlayClientMixin.java25
-rw-r--r--versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/NetworkManagerMixin.java42
-rw-r--r--versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/TimeTrackerMixin.java22
-rw-r--r--versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/WorldClientMixin.java25
-rw-r--r--versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/utils/commands/PlatformCommandManagerImpl.java123
11 files changed, 391 insertions, 0 deletions
diff --git a/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/ClientModLoaderMixin.java b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/ClientModLoaderMixin.java
new file mode 100644
index 0000000..b0caed6
--- /dev/null
+++ b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/ClientModLoaderMixin.java
@@ -0,0 +1,24 @@
+package cc.polyfrost.oneconfig.internal.mixin;
+
+import cc.polyfrost.oneconfig.events.EventManager;
+import cc.polyfrost.oneconfig.events.event.InitializationEvent;
+import cc.polyfrost.oneconfig.internal.OneConfig;
+import net.minecraftforge.fml.client.ClientModLoader;
+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(value = ClientModLoader.class, remap = false)
+public class ClientModLoaderMixin {
+ @Inject(method = "begin", at = @At("HEAD"))
+ private static void onBegin(CallbackInfo ci) {
+ OneConfig.preLaunch();
+ }
+
+ @Inject(method = "lambda$finishModLoading$9", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/GameSettings;loadOptions()V"))
+ private static void onFinishModLoading(CallbackInfo ci) {
+ EventManager.INSTANCE.post(new InitializationEvent());
+ OneConfig.init();
+ }
+}
diff --git a/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/GuiIngameForgeMixin.java b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/GuiIngameForgeMixin.java
new file mode 100644
index 0000000..f4ea663
--- /dev/null
+++ b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/GuiIngameForgeMixin.java
@@ -0,0 +1,19 @@
+package cc.polyfrost.oneconfig.internal.mixin;
+
+import cc.polyfrost.oneconfig.events.EventManager;
+import cc.polyfrost.oneconfig.events.event.HudRenderEvent;
+import cc.polyfrost.oneconfig.libs.universal.UMatrixStack;
+import com.mojang.blaze3d.matrix.MatrixStack;
+import net.minecraftforge.client.gui.ForgeIngameGui;
+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(value = ForgeIngameGui.class, remap = false)
+public class GuiIngameForgeMixin {
+ @Inject(method = "renderIngameGui", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/client/gui/ForgeIngameGui;post(Lnet/minecraftforge/client/event/RenderGameOverlayEvent$ElementType;Lcom/mojang/blaze3d/matrix/MatrixStack;)V", shift = At.Shift.AFTER, remap = false), remap = true)
+ private void onRenderGameOverlay(MatrixStack matrixStack, float partialTicks, CallbackInfo ci) {
+ EventManager.INSTANCE.post(new HudRenderEvent(new UMatrixStack(), partialTicks));
+ }
+} \ No newline at end of file
diff --git a/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/KeyboardListenerMixin.java b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/KeyboardListenerMixin.java
new file mode 100644
index 0000000..c7e6327
--- /dev/null
+++ b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/KeyboardListenerMixin.java
@@ -0,0 +1,17 @@
+package cc.polyfrost.oneconfig.internal.mixin;
+
+import cc.polyfrost.oneconfig.events.EventManager;
+import cc.polyfrost.oneconfig.events.event.KeyInputEvent;
+import net.minecraft.client.KeyboardListener;
+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(KeyboardListener.class)
+public class KeyboardListenerMixin {
+ @Inject(method = "onKeyEvent", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/client/ForgeHooksClient;fireKeyInput(IIII)V"))
+ private void onKeyEvent(long windowPointer, int key, int scanCode, int action, int modifiers, CallbackInfo ci) {
+ EventManager.INSTANCE.post(new KeyInputEvent());
+ }
+}
diff --git a/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/MinecraftMixin.java b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/MinecraftMixin.java
new file mode 100644
index 0000000..26ede28
--- /dev/null
+++ b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/MinecraftMixin.java
@@ -0,0 +1,66 @@
+package cc.polyfrost.oneconfig.internal.mixin;
+
+import cc.polyfrost.oneconfig.events.EventManager;
+import cc.polyfrost.oneconfig.events.event.*;
+import net.minecraft.client.Minecraft;
+import net.minecraft.util.Timer;
+import net.minecraftforge.client.event.GuiOpenEvent;
+import net.minecraftforge.eventbus.api.Event;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.ModifyArg;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(Minecraft.class)
+public class MinecraftMixin {
+ @Final
+ @Shadow
+ private Timer timer;
+
+ @Inject(method = "shutdownMinecraftApplet", at = @At("HEAD"))
+ private void onShutdown(CallbackInfo ci) {
+ EventManager.INSTANCE.post(new PreShutdownEvent());
+ }
+
+ @Inject(method = "runGameLoop", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/hooks/BasicEventHooks;onRenderTickStart(F)V", shift = At.Shift.AFTER, remap = false), remap = true)
+ private void onRenderTickStart(CallbackInfo ci) {
+ EventManager.INSTANCE.post(new RenderEvent(Stage.START, timer.renderPartialTicks));
+ }
+
+ @Inject(method = "runGameLoop", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/hooks/BasicEventHooks;onRenderTickEnd(F)V", shift = At.Shift.AFTER, remap = false), remap = true)
+ private void onRenderTickEnd(CallbackInfo ci) {
+ EventManager.INSTANCE.post(new RenderEvent(Stage.END, timer.renderPartialTicks));
+ }
+
+ @Inject(method = "runTick", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/hooks/BasicEventHooks;onPreClientTick()V", shift = At.Shift.AFTER, remap = false), remap = true)
+ private void onClientTickStart(CallbackInfo ci) {
+ EventManager.INSTANCE.post(new TickEvent(Stage.START));
+ }
+
+ @Inject(method = "runTick", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/hooks/BasicEventHooks;onPostClientTick()V", shift = At.Shift.AFTER, remap = false), remap = true)
+ private void onClientTickEnd(CallbackInfo ci) {
+ EventManager.INSTANCE.post(new TickEvent(Stage.END));
+ }
+
+ @ModifyArg(method = "displayGuiScreen", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/eventbus/api/IEventBus;post(Lnet/minecraftforge/eventbus/api/Event;)Z", remap = false), remap = true)
+ private Event onGuiOpenEvent(Event a) {
+ if (a instanceof GuiOpenEvent) {
+ GuiOpenEvent forgeEvent = (GuiOpenEvent) a;
+ ScreenOpenEvent event = new ScreenOpenEvent(forgeEvent.getGui());
+ EventManager.INSTANCE.post(event);
+ if (event.isCancelled) {
+ forgeEvent.setCanceled(true);
+ }
+ return forgeEvent;
+ }
+ return a;
+ }
+
+ @Inject(method = "runGameLoop", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Timer;getPartialTicks(J)I", shift = At.Shift.AFTER))
+ private void onDeltaTickTimerUpdate(CallbackInfo ci) {
+ EventManager.INSTANCE.post(new TimerUpdateEvent(timer, true));
+ }
+} \ No newline at end of file
diff --git a/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/MouseHelperAccessor.java b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/MouseHelperAccessor.java
new file mode 100644
index 0000000..d04ecb1
--- /dev/null
+++ b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/MouseHelperAccessor.java
@@ -0,0 +1,11 @@
+package cc.polyfrost.oneconfig.internal.mixin;
+
+import net.minecraft.client.MouseHelper;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+@Mixin(MouseHelper.class)
+public interface MouseHelperAccessor {
+ @Accessor
+ double getAccumulatedScrollDelta();
+}
diff --git a/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/MouseHelperMixin.java b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/MouseHelperMixin.java
new file mode 100644
index 0000000..42dd283
--- /dev/null
+++ b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/MouseHelperMixin.java
@@ -0,0 +1,17 @@
+package cc.polyfrost.oneconfig.internal.mixin;
+
+import cc.polyfrost.oneconfig.events.EventManager;
+import cc.polyfrost.oneconfig.events.event.MouseInputEvent;
+import net.minecraft.client.MouseHelper;
+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(MouseHelper.class)
+public class MouseHelperMixin {
+ @Inject(method = "mouseButtonCallback", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/client/ForgeHooksClient;fireMouseInput(III)V"))
+ private void onMouse(long handle, int button, int action, int mods, CallbackInfo ci) {
+ EventManager.INSTANCE.post(new MouseInputEvent());
+ }
+}
diff --git a/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/NetHandlerPlayClientMixin.java b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/NetHandlerPlayClientMixin.java
new file mode 100644
index 0000000..dfee688
--- /dev/null
+++ b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/NetHandlerPlayClientMixin.java
@@ -0,0 +1,25 @@
+package cc.polyfrost.oneconfig.internal.mixin;
+
+import cc.polyfrost.oneconfig.events.EventManager;
+import cc.polyfrost.oneconfig.events.event.ChatReceiveEvent;
+import net.minecraft.client.network.play.ClientPlayNetHandler;
+import net.minecraft.network.play.server.SChatPacket;
+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(value = ClientPlayNetHandler.class, priority = Integer.MAX_VALUE)
+public class NetHandlerPlayClientMixin {
+
+ @Inject(method = "handleChat", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/event/ForgeEventFactory;onClientChat(Lnet/minecraft/util/text/ChatType;Lnet/minecraft/util/text/ITextComponent;Ljava/util/UUID;)Lnet/minecraft/util/text/ITextComponent;", remap = false), cancellable = true, remap = true)
+ private void onClientChat(SChatPacket packetIn, CallbackInfo ci) {
+ if (packetIn.getType().getId() == 0) {
+ ChatReceiveEvent event = new ChatReceiveEvent(packetIn.getChatComponent());
+ EventManager.INSTANCE.post(event);
+ if (event.isCancelled) {
+ ci.cancel();
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/NetworkManagerMixin.java b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/NetworkManagerMixin.java
new file mode 100644
index 0000000..35b987a
--- /dev/null
+++ b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/NetworkManagerMixin.java
@@ -0,0 +1,42 @@
+package cc.polyfrost.oneconfig.internal.mixin;
+
+import cc.polyfrost.oneconfig.events.EventManager;
+import cc.polyfrost.oneconfig.events.event.ReceivePacketEvent;
+import cc.polyfrost.oneconfig.events.event.SendPacketEvent;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.util.concurrent.Future;
+import io.netty.util.concurrent.GenericFutureListener;
+import net.minecraft.network.IPacket;
+import net.minecraft.network.NetworkManager;
+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(value = NetworkManager.class, priority = Integer.MAX_VALUE)
+public class NetworkManagerMixin {
+
+ @Inject(method = "sendPacket(Lnet/minecraft/network/IPacket;Lio/netty/util/concurrent/GenericFutureListener;)V", at = @At("HEAD"), cancellable = true)
+ private void onSendPacket(IPacket<?> packetIn, GenericFutureListener<? extends Future<? super Void>> genericFutureListener, CallbackInfo ci) {
+ onSendPacket(packetIn, ci);
+ }
+
+ @Inject(method = "sendPacket(Lnet/minecraft/network/IPacket;)V", at = @At("HEAD"), cancellable = true)
+ private void onSendPacket(IPacket<?> packetIn, CallbackInfo ci) {
+ SendPacketEvent event = new SendPacketEvent(packetIn);
+ EventManager.INSTANCE.post(event);
+ if (event.isCancelled) {
+ ci.cancel();
+ }
+ }
+
+
+ @Inject(method = "channelRead0(Lio/netty/channel/ChannelHandlerContext;Lnet/minecraft/network/IPacket;)V", at = @At("HEAD"), cancellable = true)
+ private void onReceivePacket(ChannelHandlerContext channelHandlerContext, IPacket<?> arg, CallbackInfo ci) {
+ ReceivePacketEvent event = new ReceivePacketEvent(arg);
+ EventManager.INSTANCE.post(event);
+ if (event.isCancelled) {
+ ci.cancel();
+ }
+ }
+} \ No newline at end of file
diff --git a/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/TimeTrackerMixin.java b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/TimeTrackerMixin.java
new file mode 100644
index 0000000..dd9920e
--- /dev/null
+++ b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/TimeTrackerMixin.java
@@ -0,0 +1,22 @@
+package cc.polyfrost.oneconfig.internal.mixin;
+
+import cc.polyfrost.oneconfig.events.EventManager;
+import cc.polyfrost.oneconfig.events.event.ShutdownEvent;
+import cc.polyfrost.oneconfig.events.event.StartEvent;
+import net.minecraft.profiler.TimeTracker;
+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;
+
+import java.util.function.IntSupplier;
+import java.util.function.LongSupplier;
+
+@Mixin(TimeTracker.class)
+public class TimeTrackerMixin {
+ @Inject(method = "<init>", at = @At("RETURN"))
+ private void onStart(LongSupplier longSupplier, IntSupplier intSupplier, CallbackInfo ci) {
+ EventManager.INSTANCE.post(new StartEvent());
+ Runtime.getRuntime().addShutdownHook(new Thread(() -> EventManager.INSTANCE.post(new ShutdownEvent())));
+ }
+}
diff --git a/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/WorldClientMixin.java b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/WorldClientMixin.java
new file mode 100644
index 0000000..d98b0db
--- /dev/null
+++ b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/internal/mixin/WorldClientMixin.java
@@ -0,0 +1,25 @@
+package cc.polyfrost.oneconfig.internal.mixin;
+
+import cc.polyfrost.oneconfig.events.EventManager;
+import cc.polyfrost.oneconfig.events.event.WorldLoadEvent;
+import net.minecraft.client.network.play.ClientPlayNetHandler;
+import net.minecraft.client.renderer.WorldRenderer;
+import net.minecraft.client.world.ClientWorld;
+import net.minecraft.profiler.IProfiler;
+import net.minecraft.util.RegistryKey;
+import net.minecraft.world.DimensionType;
+import net.minecraft.world.World;
+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;
+
+import java.util.function.Supplier;
+
+@Mixin(ClientWorld.class)
+public class WorldClientMixin {
+ @Inject(method = "<init>", at = @At("RETURN"))
+ private void onWorldLoad(ClientPlayNetHandler arg, ClientWorld.ClientWorldInfo arg2, RegistryKey<World> arg3, DimensionType arg4, int i, Supplier<IProfiler> supplier, WorldRenderer arg5, boolean bl, long l, CallbackInfo ci) {
+ EventManager.INSTANCE.post(new WorldLoadEvent());
+ }
+} \ No newline at end of file
diff --git a/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/utils/commands/PlatformCommandManagerImpl.java b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/utils/commands/PlatformCommandManagerImpl.java
new file mode 100644
index 0000000..81bc9b2
--- /dev/null
+++ b/versions/1.16.2-forge/src/main/java/cc/polyfrost/oneconfig/utils/commands/PlatformCommandManagerImpl.java
@@ -0,0 +1,123 @@
+package cc.polyfrost.oneconfig.utils.commands;
+
+import cc.polyfrost.oneconfig.libs.universal.ChatColor;
+import cc.polyfrost.oneconfig.libs.universal.UChat;
+import cc.polyfrost.oneconfig.utils.commands.annotations.Command;
+import cc.polyfrost.oneconfig.utils.commands.annotations.Greedy;
+import cc.polyfrost.oneconfig.utils.commands.arguments.ArgumentParser;
+import cc.polyfrost.oneconfig.utils.commands.arguments.Arguments;
+import com.mojang.brigadier.StringReader;
+import com.mojang.brigadier.arguments.ArgumentType;
+import com.mojang.brigadier.builder.LiteralArgumentBuilder;
+import com.mojang.brigadier.context.CommandContext;
+import com.mojang.brigadier.suggestion.Suggestions;
+import com.mojang.brigadier.suggestion.SuggestionsBuilder;
+import net.minecraft.command.CommandSource;
+import net.minecraft.command.Commands;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Parameter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.concurrent.CompletableFuture;
+
+import static cc.polyfrost.oneconfig.utils.commands.CommandManager.METHOD_RUN_ERROR;
+
+public class PlatformCommandManagerImpl extends PlatformCommandManager {
+
+ final HashMap<Class<?>, Pair<ArgumentType<Object>, ArgumentType<Object>>> parsers = new HashMap<>(); // non-greedy, greedy
+
+ @Override
+ void createCommand(CommandManager.InternalCommand root, Command annotation) {
+ LiteralArgumentBuilder<CommandSource> builder = Commands.literal(annotation.value());
+ if (!root.invokers.isEmpty()) {
+ builder.executes((context ->
+ {
+ try {
+ root.invokers.get(0).method.invoke(null);
+ return 1;
+ } catch (IllegalAccessException | InvocationTargetException | IllegalArgumentException |
+ ExceptionInInitializerError e) {
+ UChat.chat(ChatColor.RED.toString() + ChatColor.BOLD + METHOD_RUN_ERROR);
+ return 0;
+ }
+ }));
+ }
+ if (annotation.helpCommand()) {
+ builder.then(Commands.literal("help").executes((context ->
+ {
+ UChat.chat(sendHelpCommand(root));
+ return 1;
+ })));
+ }
+ for (CommandManager.InternalCommand command : root.children) {
+ loopThroughChildren(command, builder, null);
+ }
+ }
+
+ private void loopThroughChildren(CommandManager.InternalCommand command, LiteralArgumentBuilder<CommandSource> root, LiteralArgumentBuilder<CommandSource> builder) {
+ if (command.invokers.isEmpty() || command.children.isEmpty()) return;
+ if (builder == null) {
+ builder = root.then(Commands.literal(command.name));
+ } else {
+ builder = builder.then(Commands.literal(command.name));
+ }
+ for (CommandManager.InternalCommand.InternalCommandInvoker invoker : command.invokers) {
+ for (Parameter parameter : invoker.method.getParameters()) {
+ Pair<ArgumentType<Object>, ArgumentType<Object>> pair = parsers.get(parameter.getType());
+ builder.then(Commands.argument(parameter.getName(), parameter.isAnnotationPresent(Greedy.class) ? pair.getRight() : pair.getLeft()));
+ }
+ builder.executes((context ->
+ {
+ try {
+ ArrayList<Object> args = new ArrayList<>(invoker.method.getParameterCount());
+ for (Parameter parameter: invoker.method.getParameters()) {
+ args.add(context.getArgument(parameter.getName(), Object.class));
+ }
+ invoker.method.invoke(null, args);
+ return 1;
+ } catch (Exception e) {
+ e.printStackTrace();
+ UChat.chat(ChatColor.RED.toString() + ChatColor.BOLD + METHOD_RUN_ERROR);
+ return 0;
+ }
+ }));
+ }
+ for (CommandManager.InternalCommand child : command.children) {
+ loopThroughChildren(child, root, builder);
+ }
+ }
+
+ @Override
+ public void handleNewParser(ArgumentParser<?> parser, Class<?> clazz) {
+ parsers.put(clazz, new ImmutablePair<ArgumentType<Object>, ArgumentType<Object>>(new ArgumentType() {
+
+ @Override
+ public Object parse(StringReader reader) {
+ final String text = reader.getRemaining();
+ reader.setCursor(reader.getTotalLength());
+ return parser.parse(new Arguments(text.split("\\s+"), false));
+ }
+
+ @Override
+ public CompletableFuture<Suggestions> listSuggestions(CommandContext context, SuggestionsBuilder builder) {
+ return ArgumentType.super.listSuggestions(context, builder);
+ }
+ }, new ArgumentType() {
+
+ @Override
+ public Object parse(StringReader reader) {
+ final String text = reader.getRemaining();
+ reader.setCursor(reader.getTotalLength());
+ return parser.parse(new Arguments(text.split("\\s+"), true));
+ }
+
+ @Override
+ public CompletableFuture<Suggestions> listSuggestions(CommandContext context, SuggestionsBuilder builder) {
+ return ArgumentType.super.listSuggestions(context, builder);
+ }
+ }));
+ }
+}