Browse Source

container click hook

Kajetan Johannes Hammerle 2 years ago
parent
commit
2256d4444e

+ 8 - 4
.gitignore

@@ -4,7 +4,11 @@
 gradle.properties
 gradlew
 /.gradle
-/.nb-gradle
-.nb-gradle-properties
-runClient.launch
-runServer.launch
+/libs
+LineCounter.jar
+uploadMod.sh
+uploadModMentos.sh
+.classpath
+.project
+.settings
+bin

+ 9 - 0
src/main/java/me/kcm/ContainerClick.java

@@ -0,0 +1,9 @@
+package me.kcm;
+
+import net.minecraft.inventory.container.ClickType;
+import net.minecraft.inventory.container.Container;
+import net.minecraft.entity.player.PlayerEntity;
+
+public interface ContainerClick {
+    public boolean onClick(Container c, int slot, int dragType, ClickType ct, PlayerEntity p);
+}

+ 24 - 6
src/main/java/me/kcm/Hooks.java

@@ -2,7 +2,6 @@ package me.kcm;
 
 import java.util.Collections;
 import java.util.List;
-import java.util.function.Consumer;
 import javax.annotation.Nullable;
 import net.minecraft.block.BlockState;
 import net.minecraft.entity.Entity;
@@ -18,6 +17,8 @@ import net.minecraft.util.registry.DynamicRegistries;
 import net.minecraft.world.World;
 import net.minecraft.world.server.ServerWorld;
 import net.minecraft.world.storage.PlayerData;
+import net.minecraft.inventory.container.ClickType;
+import net.minecraft.inventory.container.Container;
 
 public class Hooks {
     @FunctionalInterface
@@ -26,15 +27,20 @@ public class Hooks {
     }
 
     private static PlayerListFunction playerListFunction = null;
-    private static BlockHarvest blockHarvest = (state, w, pos, tileEnt, ent, stack) -> Collections.EMPTY_LIST;
+    private static BlockHarvest blockHarvest =
+            (state, w, pos, tileEnt, ent, stack) -> Collections.EMPTY_LIST;
     private static Craft craft = (id, w, p, cInv, slot) -> {
     };
+    private static ContainerClick click = (c, slot, dragType, ct, p) -> {
+        return false;
+    };
 
     public static void setPlayerListFunction(PlayerListFunction c) {
         playerListFunction = c;
     }
 
-    public static void setPlayerList(DedicatedServer server, DynamicRegistries.Impl impl, PlayerData pd) {
+    public static void setPlayerList(DedicatedServer server, DynamicRegistries.Impl impl,
+            PlayerData pd) {
         System.out.println("trying to update player list ...");
         if(playerListFunction != null) {
             playerListFunction.accept(server, impl, pd);
@@ -58,15 +64,27 @@ public class Hooks {
         craft = c;
     }
 
-    public static List<ItemStack> getDropsA(BlockState state, ServerWorld w, BlockPos pos, @Nullable TileEntity tileEnt) {
+    public static void setContainerClick(ContainerClick c) {
+        click = c;
+    }
+
+    public static List<ItemStack> getDropsA(BlockState state, ServerWorld w, BlockPos pos,
+            @Nullable TileEntity tileEnt) {
         return blockHarvest.onBlockHarvest(state, w, pos, tileEnt, null, null);
     }
 
-    public static List<ItemStack> getDropsB(BlockState state, ServerWorld w, BlockPos pos, @Nullable TileEntity tileEnt, @Nullable Entity ent, ItemStack stack) {
+    public static List<ItemStack> getDropsB(BlockState state, ServerWorld w, BlockPos pos,
+            @Nullable TileEntity tileEnt, @Nullable Entity ent, ItemStack stack) {
         return blockHarvest.onBlockHarvest(state, w, pos, tileEnt, ent, stack);
     }
 
-    public static void onCraft(int id, World w, PlayerEntity p, CraftingInventory cInv, CraftResultInventory slot) {
+    public static void onCraft(int id, World w, PlayerEntity p, CraftingInventory cInv,
+            CraftResultInventory slot) {
         craft.onCraft(id, w, p, cInv, slot);
     }
+
+    public static boolean onSlotClick(Container c, int slot, int dragType, ClickType ct,
+            PlayerEntity p) {
+        return click.onClick(c, slot, dragType, ct, p);
+    }
 }

+ 2 - 1
src/main/resources/META-INF/coremods.json

@@ -1,5 +1,6 @@
 {
     "Dedicated Server Transformer": "class_transformer/playerlist.js",
     "Block Transformer": "class_transformer/block.js",
-    "Crafting Transformer": "class_transformer/craft.js"
+    "Crafting Transformer": "class_transformer/craft.js",
+    "Container Transformer": "class_transformer/container.js"
 }

+ 55 - 0
src/main/resources/class_transformer/container.js

@@ -0,0 +1,55 @@
+var transformerName = "Dedicated Server Transformer";
+var ASMAPI = Java.type('net.minecraftforge.coremod.api.ASMAPI');
+var Opcodes = Java.type('org.objectweb.asm.Opcodes');
+var VarInsnNode = Java.type("org.objectweb.asm.tree.VarInsnNode");
+var MethodInsnNode = Java.type("org.objectweb.asm.tree.MethodInsnNode");
+var LineNumberNode = Java.type("org.objectweb.asm.tree.LineNumberNode");
+var FieldInsnNode = Java.type("org.objectweb.asm.tree.FieldInsnNode");
+var JumpInsnNode = Java.type("org.objectweb.asm.tree.JumpInsnNode");
+var LabelNode = Java.type("org.objectweb.asm.tree.LabelNode");
+var InsnNode = Java.type("org.objectweb.asm.tree.InsnNode");
+
+function initializeCoreMod() {
+    return {
+        transformerName: {
+            'target': {
+                'type': 'CLASS',
+                'name': 'net.minecraft.inventory.container.Container'
+            },
+            'transformer': function (classNode) {
+                var methods = classNode.methods;
+
+                var targetMethodName = ASMAPI.mapMethod("func_184996_a"); // slotClick
+                var targetMethodDesc = "(IILnet/minecraft/inventory/container/ClickType;Lnet/minecraft/entity/player/PlayerEntity;)Lnet/minecraft/item/ItemStack;";
+
+                for (var i in methods) {
+                    var method = methods[i];
+                    if (method.name.equals(targetMethodName) && method.desc.equals(targetMethodDesc)) {
+                        transform(method);
+                        break;
+                    }
+                }
+                return classNode;
+            }
+        }
+    };
+}
+
+function transform(method) {
+    var instrList = method.instructions;
+    instrList.insert(instrList.get(0), new VarInsnNode(Opcodes.ALOAD, 0));
+    instrList.insert(instrList.get(1), new VarInsnNode(Opcodes.ILOAD, 1));
+    instrList.insert(instrList.get(2), new VarInsnNode(Opcodes.ILOAD, 2));
+    instrList.insert(instrList.get(3), new VarInsnNode(Opcodes.ALOAD, 3));
+    instrList.insert(instrList.get(4), new VarInsnNode(Opcodes.ALOAD, 4));
+    instrList.insert(instrList.get(5), new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/Hooks",
+        "onSlotClick",
+        "(Lnet/minecraft/inventory/container/Container;IILnet/minecraft/inventory/container/ClickType;Lnet/minecraft/entity/player/PlayerEntity;)Z", false));
+    var label = new LabelNode();
+    instrList.insert(instrList.get(6), new JumpInsnNode(Opcodes.IFEQ, label));
+    instrList.insert(instrList.get(7), new FieldInsnNode(Opcodes.GETSTATIC, "net/minecraft/item/ItemStack",
+        "EMPTY",
+        "Lnet/minecraft/item/ItemStack;"));
+    instrList.insert(instrList.get(8), new InsnNode(Opcodes.ARETURN));
+    instrList.insert(instrList.get(9), label);
+}

+ 25 - 32
src/main/resources/class_transformer/test.js

@@ -4,6 +4,10 @@ var Opcodes = Java.type('org.objectweb.asm.Opcodes');
 var VarInsnNode = Java.type("org.objectweb.asm.tree.VarInsnNode");
 var MethodInsnNode = Java.type("org.objectweb.asm.tree.MethodInsnNode");
 var LineNumberNode = Java.type("org.objectweb.asm.tree.LineNumberNode");
+var FieldInsnNode = Java.type("org.objectweb.asm.tree.FieldInsnNode");
+var JumpInsnNode = Java.type("org.objectweb.asm.tree.JumpInsnNode");
+var LabelNode = Java.type("org.objectweb.asm.tree.LabelNode");
+var InsnNode = Java.type("org.objectweb.asm.tree.InsnNode");
 
 function initializeCoreMod() {
     return {
@@ -18,13 +22,11 @@ function initializeCoreMod() {
                 var targetMethodName = ASMAPI.mapMethod("func_71197_b"); // init
                 var targetMethodDesc = "()Z";
 
-                for (var i in methods)
-                {
+                for (var i in methods) {
                     var method = methods[i];
 
                     print(method.name + " " + method.desc);
-                    if (method.name.equals(targetMethodName) && method.desc.equals(targetMethodDesc))
-                    {
+                    if (method.name.equals(targetMethodName) && method.desc.equals(targetMethodDesc)) {
                         transform(method);
                         break;
                     }
@@ -35,45 +37,40 @@ function initializeCoreMod() {
     };
 }
 
-function transform(method)
-{
+function transform(method) {
     print("Match found " + method.name + " " + method.desc);
     var instrList = method.instructions;
-    
+
     /*instrList.remove(instrList.get(2));
     instrList.insert(instrList.get(1), new VarInsnNode(Opcodes.ALOAD, 0));
     instrList.insert(instrList.get(2), new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks", 
         "onGetTabListDisplayName", "(Lnet/minecraft/entity/player/EntityPlayerMP;)Lnet/minecraft/util/text/ITextComponent;", false));*/
-    
-    for(var i = 0; i < instrList.size(); ++i) 
-    {
+
+    for (var i = 0; i < instrList.size(); ++i) {
         var instr = instrList.get(i);
-        if(instr.getOpcode() == 183 && instr instanceof MethodInsnNode && instr.owner == "net/minecraft/server/dedicated/DedicatedPlayerList")
-        {
+        if (instr.getOpcode() == 183 && instr instanceof MethodInsnNode && instr.owner == "net/minecraft/server/dedicated/DedicatedPlayerList") {
             print("_________________________________________");
-            for(var j = -10; j < 10; j++)
-            {
+            for (var j = -10; j < 10; j++) {
                 printInstr(instrList.get(i + j));
             }
-                           
+
             instrList.remove(instrList.get(i - 4));
             instrList.remove(instrList.get(i - 4));
             instrList.remove(instrList.get(i - 4));
             instrList.remove(instrList.get(i - 4));
             instrList.remove(instrList.get(i - 4));
             instrList.remove(instrList.get(i - 4));
-            
+
             instrList.insert(instrList.get(i - 5), new VarInsnNode(Opcodes.ALOAD, 0));
             //instrList.insert(instrList.get(i - 4), new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks", 
             //    "newPlayerList", "(Lnet/minecraft/server/dedicated/DedicatedServer;)Lnet/minecraft/server/dedicated/DedicatedPlayerList;", false));
             //instrList.insert(instrList.get(i - 3), new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks", 
             //    "newPlayerList", "()Lnet/minecraft/server/dedicated/DedicatedPlayerList;", false));
-            instrList.insert(instrList.get(i - 4), new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks", 
+            instrList.insert(instrList.get(i - 4), new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks",
                 "setPlayerList", "(Lnet/minecraft/server/dedicated/DedicatedServer;)V", false));
-                
+
             print("_________________________________________");
-            for(var j = -10; j < 10; j++)
-            {
+            for (var j = -10; j < 10; j++) {
                 printInstr(instrList.get(i + j));
             }
             break;
@@ -81,29 +78,25 @@ function transform(method)
     }
 }
 
-function printInstr(instr)
-{
-    if(instr.getOpcode() == -1)
-    {
+function printInstr(instr) {
+    if (instr.getOpcode() == -1) {
         return;
     }
     var out = "> ";
     out += instr.getOpcode();
     out += "_";
     out += instr.getType();
-    
-    if(instr instanceof VarInsnNode)
-    {
+
+    if (instr instanceof VarInsnNode) {
         out += " Var: " + instr.var;
     }
-    else if(instr instanceof MethodInsnNode)
-    {
+    else if (instr instanceof MethodInsnNode) {
         out += " " + instr.owner + "." + instr.name + ":" + instr.desc;
     }
-    else if(instr instanceof FieldInsnNode)
-    {
+    else if (instr instanceof FieldInsnNode) {
         out += " " + instr.owner + "." + instr.name + ":" + instr.desc;
+    } else if (instr instanceof JumpInsnNode) {
+        out += " " + instr.label + " " + instr.label.getLabel();
     }
-    //out += " " + instr;
     print(out);
 }