summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2024-02-22 22:05:15 +0100
committerLinnea Gräf <nea@nea.moe>2024-02-22 22:06:01 +0100
commitaef074886b587745bd814fe965d55e7b4cf11a07 (patch)
treeacc62b9aaf9f95bdce17a85683c42cbec93fe800
parente8196b0b5e02ec21f75109ab7aba8d48220c8d05 (diff)
downloadKowalski-aef074886b587745bd814fe965d55e7b4cf11a07.tar.gz
Kowalski-aef074886b587745bd814fe965d55e7b4cf11a07.tar.bz2
Kowalski-aef074886b587745bd814fe965d55e7b4cf11a07.zip
Add event cancellation watcher
-rw-r--r--build.gradle.kts1
-rw-r--r--src/main/java/moe/nea/kowalski/KowalskiCommand.kt61
-rw-r--r--src/main/java/moe/nea/kowalski/init/EventClassTransformer.java47
-rw-r--r--src/main/java/moe/nea/kowalski/init/KowalskiTweaker.java29
-rw-r--r--src/main/kotlin/moe/nea/kowalski/ExampleMod.kt22
-rw-r--r--src/main/kotlin/moe/nea/kowalski/Kowalski.kt51
-rw-r--r--src/main/kotlin/moe/nea/kowalski/mixin/MixinGuiMainMenu.java16
-rw-r--r--src/main/resources/assets/test/test.txt3
8 files changed, 189 insertions, 41 deletions
diff --git a/build.gradle.kts b/build.gradle.kts
index 98f7efa..018de40 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -31,6 +31,7 @@ loom {
property("mixin.debug", "true")
property("asmhelper.verbose", "true")
arg("--tweakClass", "org.spongepowered.asm.launch.MixinTweaker")
+ arg("--tweakClass", "moe.nea.kowalski.init.KowalskiTweaker")
}
}
runConfigs {
diff --git a/src/main/java/moe/nea/kowalski/KowalskiCommand.kt b/src/main/java/moe/nea/kowalski/KowalskiCommand.kt
new file mode 100644
index 0000000..b2a975a
--- /dev/null
+++ b/src/main/java/moe/nea/kowalski/KowalskiCommand.kt
@@ -0,0 +1,61 @@
+package moe.nea.kowalski
+
+import net.minecraft.client.Minecraft
+import net.minecraft.command.CommandBase
+import net.minecraft.command.ICommandSender
+import net.minecraft.util.BlockPos
+import net.minecraft.util.ChatComponentText
+
+object KowalskiCommand : CommandBase() {
+ override fun getCommandName(): String {
+ return "kowalski"
+ }
+
+ override fun canCommandSenderUseCommand(sender: ICommandSender?): Boolean {
+ return true
+ }
+
+ override fun getCommandUsage(sender: ICommandSender?): String {
+ return ""
+ }
+
+
+ override fun addTabCompletionOptions(
+ sender: ICommandSender?,
+ args: Array<out String>,
+ pos: BlockPos?
+ ): List<String> {
+ return when (args.size) {
+ 1 -> getListOfStringsMatchingLastWord(args, "whocancels")
+ 2 -> when (args[0]) {
+ "whocancels" -> getListOfStringsMatchingLastWord(args, "ClientChatReceivedEvent")
+ else -> emptyList()
+ }
+ else -> emptyList()
+ }
+ }
+
+ fun chat(text: String) {
+ Minecraft.getMinecraft().ingameGUI.chatGUI.printChatMessage(ChatComponentText("§e[§fKW§e]§r $text"))
+ }
+
+ override fun processCommand(sender: ICommandSender, args: Array<out String>) {
+ when (args.firstOrNull()) {
+ "whocancels" -> {
+ if (args.size != 2) {
+ chat("§cPlease provide an event to listen to: §bwhocancels <eventname>")
+ return
+ }
+ val eventName = args[1]
+ if (eventName in Kowalski.watchedEvents) {
+ Kowalski.watchedEvents.remove(eventName)
+ chat("§fRemoved §c$eventName §ffrom watched events")
+ } else {
+ Kowalski.watchedEvents.add(eventName)
+ chat("§fAdded §b$eventName §fto watched events")
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/moe/nea/kowalski/init/EventClassTransformer.java b/src/main/java/moe/nea/kowalski/init/EventClassTransformer.java
new file mode 100644
index 0000000..a80a5b5
--- /dev/null
+++ b/src/main/java/moe/nea/kowalski/init/EventClassTransformer.java
@@ -0,0 +1,47 @@
+package moe.nea.kowalski.init;
+
+import net.minecraft.launchwrapper.IClassTransformer;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.*;
+
+import java.util.ListIterator;
+
+public class EventClassTransformer implements IClassTransformer {
+ @Override
+ public byte[] transform(String name, String transformedName, byte[] basicClass) {
+ if (!"net.minecraftforge.fml.common.eventhandler.Event".equals(name))
+ return basicClass;
+ ClassNode classNode = new ClassNode();
+ ClassReader classReader = new ClassReader(basicClass);
+ classReader.accept(classNode, 0);
+ for (MethodNode method : classNode.methods) {
+ if (method.name.equals("setCanceled")) {
+ transformCancelMethod(method);
+ }
+ }
+ ClassWriter writer = new ClassWriter(0);
+ classNode.accept(writer);
+ return writer.toByteArray();
+ }
+
+ private void transformCancelMethod(MethodNode method) {
+ ListIterator<AbstractInsnNode> iterator =
+ method.instructions.iterator();
+ while (iterator.hasNext()) {
+ AbstractInsnNode insn = iterator.next();
+ if (insn.getOpcode() != Opcodes.PUTFIELD) {
+ continue;
+ }
+ method.instructions.insert(insn, buildCallKowalski());
+ }
+ }
+
+ private InsnList buildCallKowalski() {
+ InsnList insnList = new InsnList();
+ insnList.add(new VarInsnNode(Opcodes.ALOAD, 0));
+ insnList.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "moe/nea/kowalski/Kowalski", "eventIsBeingCancelled", "(Lnet/minecraftforge/fml/common/eventhandler/Event;)V", false));
+ return insnList;
+ }
+}
diff --git a/src/main/java/moe/nea/kowalski/init/KowalskiTweaker.java b/src/main/java/moe/nea/kowalski/init/KowalskiTweaker.java
new file mode 100644
index 0000000..4cb836c
--- /dev/null
+++ b/src/main/java/moe/nea/kowalski/init/KowalskiTweaker.java
@@ -0,0 +1,29 @@
+package moe.nea.kowalski.init;
+
+import net.minecraft.launchwrapper.ITweaker;
+import net.minecraft.launchwrapper.LaunchClassLoader;
+
+import java.io.File;
+import java.util.List;
+
+public class KowalskiTweaker implements ITweaker {
+ @Override
+ public void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) {
+
+ }
+
+ @Override
+ public void injectIntoClassLoader(LaunchClassLoader classLoader) {
+classLoader.registerTransformer("moe.nea.kowalski.init.EventClassTransformer");
+ }
+
+ @Override
+ public String getLaunchTarget() {
+ return null;
+ }
+
+ @Override
+ public String[] getLaunchArguments() {
+ return new String[0];
+ }
+}
diff --git a/src/main/kotlin/moe/nea/kowalski/ExampleMod.kt b/src/main/kotlin/moe/nea/kowalski/ExampleMod.kt
deleted file mode 100644
index a622a6c..0000000
--- a/src/main/kotlin/moe/nea/kowalski/ExampleMod.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package moe.nea.kowalski
-
-import net.minecraft.client.Minecraft
-import net.minecraft.init.Blocks
-import net.minecraftforge.fml.common.Mod
-import net.minecraftforge.fml.common.event.FMLInitializationEvent
-
-@Mod(modid = "kowalski", useMetadata = true)
-class ExampleMod {
- @Mod.EventHandler
- fun init(event: FMLInitializationEvent) {
- try {
- val resource: net.minecraft.client.resources.IResource = Minecraft.getMinecraft().getResourceManager()
- .getResource(net.minecraft.util.ResourceLocation("test:test.txt"))
- org.apache.commons.io.IOUtils.copy(resource.getInputStream(), java.lang.System.out)
- } catch (e: java.io.IOException) {
- throw java.lang.RuntimeException(e)
- }
-
- println("Dirt: ${Blocks.dirt.unlocalizedName}")
- }
-}
diff --git a/src/main/kotlin/moe/nea/kowalski/Kowalski.kt b/src/main/kotlin/moe/nea/kowalski/Kowalski.kt
new file mode 100644
index 0000000..2bede19
--- /dev/null
+++ b/src/main/kotlin/moe/nea/kowalski/Kowalski.kt
@@ -0,0 +1,51 @@
+package moe.nea.kowalski
+
+import net.minecraftforge.client.ClientCommandHandler
+import net.minecraftforge.client.event.ClientChatReceivedEvent
+import net.minecraftforge.common.MinecraftForge
+import net.minecraftforge.fml.common.Mod
+import net.minecraftforge.fml.common.event.FMLInitializationEvent
+import net.minecraftforge.fml.common.eventhandler.Event
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+@Mod(modid = "kowalski", useMetadata = true)
+class Kowalski {
+
+ companion object {
+ val watchedEvents = mutableSetOf<String>()
+
+ @JvmStatic
+ fun eventIsBeingCancelled(event: Event) {
+ if (event.javaClass.simpleName !in watchedEvents) {
+ return
+ }
+ val interestingStack = Thread.currentThread()
+ .stackTrace
+ .dropWhile { it.className.startsWith("java.lang.") }
+ .dropWhile { it.className.startsWith("moe.nea.kowalski.") }
+ .drop(1)
+ KowalskiCommand.chat(
+ "§c§k!!!§c RED ALERT §k!!!§c\n" +
+ "AN EVENT HAS BEEN CANCELLED\n" +
+ "§c=================\n" +
+ "§e${interestingStack.joinToString("\n§e")}\n" +
+ "§c================="
+ )
+ }
+ }
+
+
+ @SubscribeEvent
+ fun cancelMessages(event: ClientChatReceivedEvent) {
+ if (event.message.unformattedText.contains("verboten"))
+ event.isCanceled = true
+ }
+
+ @Mod.EventHandler
+ fun init(event: FMLInitializationEvent) {
+ ClientCommandHandler.instance.registerCommand(KowalskiCommand)
+ MinecraftForge.EVENT_BUS.register(this)
+ }
+
+
+}
diff --git a/src/main/kotlin/moe/nea/kowalski/mixin/MixinGuiMainMenu.java b/src/main/kotlin/moe/nea/kowalski/mixin/MixinGuiMainMenu.java
deleted file mode 100644
index 4ddc1b4..0000000
--- a/src/main/kotlin/moe/nea/kowalski/mixin/MixinGuiMainMenu.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package moe.nea.kowalski.mixin;
-
-import net.minecraft.client.gui.GuiMainMenu;
-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(GuiMainMenu.class)
-public class MixinGuiMainMenu {
-
- @Inject(method = "initGui", at = @At("HEAD"))
- public void onInitGui(CallbackInfo ci) {
- System.out.println("Hello from Main Menu!");
- }
-}
diff --git a/src/main/resources/assets/test/test.txt b/src/main/resources/assets/test/test.txt
deleted file mode 100644
index ea839e2..0000000
--- a/src/main/resources/assets/test/test.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-test
-from resource pack
-