Browse Source

container click event

Kajetan Johannes Hammerle 2 years ago
parent
commit
0ad12553d4

+ 1 - 1
src/main/java/me/km/Server.java

@@ -38,7 +38,7 @@ public class Server {
     private static SnuviLogger logger;
     private static ModCommandManager commands;
     private static DedicatedServer server;
-    private static SnuviScheduler scheduler;
+    public static SnuviScheduler scheduler;
     private static DataBank databank;
     private static Scripts scripts;
     public static ScriptEvents scriptEvents;

+ 161 - 0
src/main/java/me/km/snuviscript/ModContainer.java

@@ -0,0 +1,161 @@
+package me.km.snuviscript;
+
+import me.km.Server;
+import me.km.utils.ReflectionUtils;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.container.ClickType;
+import net.minecraft.inventory.container.Container;
+import net.minecraft.inventory.container.ContainerType;
+import net.minecraft.inventory.container.IContainerListener;
+import net.minecraft.inventory.container.Slot;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.IIntArray;
+import net.minecraft.util.IntReferenceHolder;
+import net.minecraft.util.NonNullList;
+import net.minecraft.world.World;
+import net.minecraft.entity.player.ServerPlayerEntity;
+
+public class ModContainer extends Container {
+    private final Container container;
+
+    private static ContainerType<?> getType(Container c) {
+        try {
+            return c.getType();
+        } catch(Exception ex) {
+            return null;
+        }
+    }
+
+    public ModContainer(Container c) {
+        super(getType(c), c.windowId);
+        this.container = c;
+    }
+
+    public String getName() {
+        return container.getClass().getSimpleName();
+    }
+
+    @Override
+    public ItemStack slotClick(int slot, int dragType, ClickType ct, PlayerEntity p) {
+        if(Server.scriptEvents.onContainerClick(this, slot, dragType, ct, p)) {
+            Server.scheduler.scheduleTask(() -> {
+                ((ServerPlayerEntity) p).sendAllContents(this, getInventory());
+            });
+            return ItemStack.EMPTY;
+        }
+        return container.slotClick(slot, dragType, ct, p);
+    }
+
+    @Override
+    public boolean canInteractWith(PlayerEntity p) {
+        return container.canInteractWith(p);
+    }
+
+    @Override
+    public ContainerType<?> getType() {
+        return container.getType();
+    }
+
+    @Override
+    protected Slot addSlot(Slot slotIn) {
+        return ReflectionUtils.addSlot(container, slotIn);
+    }
+
+    @Override
+    protected IntReferenceHolder trackInt(IntReferenceHolder intIn) {
+        return ReflectionUtils.trackInt(container, intIn);
+    }
+
+    @Override
+    protected void trackIntArray(IIntArray arrayIn) {
+        ReflectionUtils.trackIntArray(container, arrayIn);
+    }
+
+    @Override
+    public void addListener(IContainerListener listener) {
+        container.addListener(listener);
+    }
+
+    @Override
+    public NonNullList<ItemStack> getInventory() {
+        return container.getInventory();
+    }
+
+    @Override
+    public void detectAndSendChanges() {
+        container.detectAndSendChanges();
+    }
+
+    @Override
+    public boolean enchantItem(PlayerEntity playerIn, int id) {
+        return container.enchantItem(playerIn, id);
+    }
+
+    @Override
+    public Slot getSlot(int slotId) {
+        return container.getSlot(slotId);
+    }
+
+    @Override
+    public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) {
+        return container.transferStackInSlot(playerIn, index);
+    }
+
+    @Override
+    public boolean canMergeSlot(ItemStack stack, Slot slotIn) {
+        return container.canMergeSlot(stack, slotIn);
+    }
+
+    @Override
+    public void onContainerClosed(PlayerEntity playerIn) {
+        container.onContainerClosed(playerIn);
+    }
+
+    @Override
+    protected void clearContainer(PlayerEntity playerIn, World worldIn, IInventory inventoryIn) {
+        ReflectionUtils.clearContainer(container, playerIn, worldIn, inventoryIn);
+    }
+
+    @Override
+    public void onCraftMatrixChanged(IInventory inventoryIn) {
+        container.onCraftMatrixChanged(inventoryIn);
+    }
+
+    @Override
+    public void putStackInSlot(int slotID, ItemStack stack) {
+        container.putStackInSlot(slotID, stack);
+    }
+
+    @Override
+    public void updateProgressBar(int id, int data) {
+        container.updateProgressBar(id, data);
+    }
+
+    @Override
+    public boolean getCanCraft(PlayerEntity player) {
+        return container.getCanCraft(player);
+    }
+
+    @Override
+    public void setCanCraft(PlayerEntity player, boolean canCraft) {
+        container.setCanCraft(player, canCraft);
+    }
+
+    @Override
+    protected boolean mergeItemStack(ItemStack stack, int startIndex, int endIndex,
+            boolean reverseDirection) {
+        return ReflectionUtils.mergeItemStack(container, stack, startIndex, endIndex,
+                reverseDirection);
+    }
+
+    @Override
+    protected void resetDrag() {
+        ReflectionUtils.resetDrag(container);
+    }
+
+    @Override
+    public boolean canDragIntoSlot(Slot slotIn) {
+        return container.canDragIntoSlot(slotIn);
+    }
+}

+ 40 - 0
src/main/java/me/km/snuviscript/ScriptEvents.java

@@ -33,6 +33,7 @@ import net.minecraft.util.text.*;
 import net.minecraft.world.*;
 import net.minecraft.world.server.ServerWorld;
 import net.minecraftforge.event.*;
+import net.minecraftforge.event.TickEvent.PlayerTickEvent;
 import net.minecraftforge.event.entity.*;
 import net.minecraftforge.event.entity.item.ItemTossEvent;
 import net.minecraftforge.event.entity.living.*;
@@ -44,6 +45,10 @@ import net.minecraftforge.event.entity.player.PlayerEvent;
 import net.minecraftforge.eventbus.api.Event.Result;
 
 public class ScriptEvents implements BlockHarvest, Craft {
+    private static class WrappedBool {
+        public boolean wrapped;
+    }
+
     private static void setLiving(Script sc, LivingEntity ent) {
         sc.setVar("living_entity", ent);
     }
@@ -805,4 +810,39 @@ public class ScriptEvents implements BlockHarvest, Craft {
             sc.setVar("timestamp", SnuviUtils.convert(data[4]));
         });
     }
+
+    @SubscribeEvent
+    public void onContainerOpen(PlayerContainerEvent.Open e) {
+        PlayerEntity p = e.getPlayer();
+        if(!(p.openContainer instanceof ModContainer)) {
+            p.openContainer = new ModContainer(p.openContainer);
+        }
+    }
+
+    @SubscribeEvent
+    public void onPlayerTick(PlayerTickEvent e) {
+        PlayerEntity p = e.player;
+        if(!(p.openContainer instanceof ModContainer)) {
+            p.openContainer = new ModContainer(p.openContainer);
+        }
+    }
+
+    public boolean onContainerClick(ModContainer c, int slot, int dragType, ClickType ct,
+            PlayerEntity p) {
+        String name = c.getName();
+        WrappedBool b = new WrappedBool();
+        b.wrapped = false;
+        scripts.getScriptManager().callEvent("container_click", sc -> {
+            setPlayer(sc, p);
+            sc.setVar("slot", (double) slot);
+            sc.setVar("item_list", c.getInventory());
+            sc.setVar("type", name);
+            sc.setVar("drag_type", (double) dragType);
+            sc.setVar("click_type", ct.toString());
+            sc.setVar("cancel", b.wrapped);
+        }, sc -> {
+            handleVar(sc, "container_click", "cancel", v -> b.wrapped = v.getBoolean(sc));
+        });
+        return b.wrapped;
+    }
 }

+ 80 - 12
src/main/java/me/km/utils/ReflectionUtils.java

@@ -11,13 +11,20 @@ import net.minecraft.block.FireBlock;
 import net.minecraft.command.Commands;
 import net.minecraft.entity.ai.goal.GoalSelector;
 import net.minecraft.entity.ai.goal.PrioritizedGoal;
+import net.minecraft.entity.player.PlayerEntity;
 import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.container.Container;
+import net.minecraft.inventory.container.Slot;
+import net.minecraft.item.ItemStack;
 import net.minecraft.resources.DataPackRegistries;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.server.management.PlayerInteractionManager;
 import net.minecraft.server.management.PlayerList;
 import net.minecraft.tileentity.SignTileEntity;
 import net.minecraft.util.FoodStats;
+import net.minecraft.util.IIntArray;
+import net.minecraft.util.IntReferenceHolder;
 import net.minecraft.util.text.ITextComponent;
 import net.minecraft.world.Explosion;
 import net.minecraft.world.GameRules;
@@ -35,7 +42,7 @@ public class ReflectionUtils {
     public static Method getMethod(Class<?> c, String name, Class<?>... pars) {
         try {
             return ObfuscationReflectionHelper.findMethod(c, name, pars);
-        } catch (Exception ex) {
+        } catch(Exception ex) {
             LogManager.getLogger().warn(name + " - " + ex);
         }
         return null;
@@ -46,7 +53,7 @@ public class ReflectionUtils {
             Field f = c.getDeclaredField(remapName(INameMappingService.Domain.FIELD, field));
             f.setAccessible(true);
             return f;
-        } catch (Exception ex) {
+        } catch(Exception ex) {
             LogManager.getLogger().warn(field + " - " + ex);
         }
         return null;
@@ -55,8 +62,7 @@ public class ReflectionUtils {
     private static <T> void setInt(T t, Field f, int i) {
         try {
             f.setInt(t, i);
-        } catch (SecurityException | IllegalArgumentException | IllegalAccessException
-                | NullPointerException ex) {
+        } catch(Exception ex) {
             LogManager.getLogger().warn(f + " - " + ex);
         }
     }
@@ -64,8 +70,7 @@ public class ReflectionUtils {
     private static <T> void setFloat(T t, Field f, float fl) {
         try {
             f.setFloat(t, fl);
-        } catch (SecurityException | IllegalArgumentException | IllegalAccessException
-                | NullPointerException ex) {
+        } catch(Exception ex) {
             LogManager.getLogger().warn(f + " - " + ex);
         }
     }
@@ -73,8 +78,7 @@ public class ReflectionUtils {
     private static <T> float getFloat(T t, Field f, float error) {
         try {
             return f.getFloat(t);
-        } catch (SecurityException | IllegalArgumentException | IllegalAccessException
-                | NullPointerException ex) {
+        } catch(Exception ex) {
             LogManager.getLogger().warn(f + " - " + ex);
             return error;
         }
@@ -83,7 +87,7 @@ public class ReflectionUtils {
     public static <T> T getFieldValue(Class<T> cast, Object o, Field f) {
         try {
             return cast.cast(f.get(o));
-        } catch (SecurityException | IllegalAccessException | IllegalArgumentException ex) {
+        } catch(Exception ex) {
             LogManager.getLogger().warn(f + " - " + ex);
             return null;
         }
@@ -92,7 +96,7 @@ public class ReflectionUtils {
     public static void setFieldValue(Object instance, Field f, Object value) {
         try {
             f.set(instance, value);
-        } catch (SecurityException | IllegalAccessException | IllegalArgumentException ex) {
+        } catch(Exception ex) {
             LogManager.getLogger().warn(f + " - " + ex);
         }
     }
@@ -128,7 +132,7 @@ public class ReflectionUtils {
             ServerPlayerEntity source, ServerWorld sw) {
         try {
             SET_GAMETYPE.invoke(pl, target, source, sw);
-        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
+        } catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
             LogManager.getLogger().warn("setPlayerGameTypeBasedOnOther - " + ex);
         }
     }
@@ -183,7 +187,7 @@ public class ReflectionUtils {
         FireBlock fireblock = (FireBlock) Blocks.FIRE;
         try {
             SET_FIRE_INFO.invoke(fireblock, b, encouragement, flammability);
-        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
+        } catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
             LogManager.getLogger().warn("setFireInfo - " + ex);
         }
     }
@@ -215,4 +219,68 @@ public class ReflectionUtils {
     public static IServerConfiguration getDerivedWorldInfoConfiguration(DerivedWorldInfo info) {
         return getFieldValue(IServerConfiguration.class, info, DERIVED_WORLD_INFO_CONFIGURATION);
     }
+
+    private final static Method ADD_SLOT = getMethod(Container.class, "func_75146_a", Slot.class); // addSlot
+    private final static Method TRACK_INT =
+            getMethod(Container.class, "func_216958_a", IntReferenceHolder.class); // trackInt
+    private final static Method TRACK_INT_ARRAY =
+            getMethod(Container.class, "func_216961_a", IIntArray.class); // trackIntArray
+    private final static Method CLEAR_CONTAINER = getMethod(Container.class, "func_193327_a",
+            PlayerEntity.class, World.class, IInventory.class); // clearContainer
+    private final static Method MERGE_ITEM_STACK = getMethod(Container.class, "func_75135_a",
+            ItemStack.class, int.class, int.class, boolean.class); // mergeItemStack
+    private final static Method RESET_DRAG = getMethod(Container.class, "func_94533_d"); // resetDrag
+
+    public static Slot addSlot(Container c, Slot slot) {
+        try {
+            return (Slot) ADD_SLOT.invoke(c, slot);
+        } catch(Exception ex) {
+            LogManager.getLogger().warn("addSlot - " + ex);
+        }
+        return null;
+    }
+
+    public static IntReferenceHolder trackInt(Container c, IntReferenceHolder i) {
+        try {
+            return (IntReferenceHolder) TRACK_INT.invoke(c, i);
+        } catch(Exception ex) {
+            LogManager.getLogger().warn("trackInt - " + ex);
+        }
+        return null;
+    }
+
+    public static void trackIntArray(Container c, IIntArray array) {
+        try {
+            TRACK_INT_ARRAY.invoke(c, array);
+        } catch(Exception ex) {
+            LogManager.getLogger().warn("trackIntArray - " + ex);
+        }
+    }
+
+    public static void clearContainer(Container c, PlayerEntity p, World w, IInventory i) {
+        try {
+            CLEAR_CONTAINER.invoke(c, p, w, i);
+        } catch(Exception ex) {
+            LogManager.getLogger().warn("clearContainer - " + ex);
+        }
+    }
+
+    public static boolean mergeItemStack(Container c, ItemStack stack, int startIndex, int endIndex,
+            boolean reverseDirection) {
+        try {
+            return (boolean) MERGE_ITEM_STACK.invoke(c, stack, startIndex, endIndex,
+                    reverseDirection);
+        } catch(Exception ex) {
+            LogManager.getLogger().warn("mergeItemStack - " + ex);
+        }
+        return false;
+    }
+
+    public static void resetDrag(Container c) {
+        try {
+            RESET_DRAG.invoke(c);
+        } catch(Exception ex) {
+            LogManager.getLogger().warn("resetDrag - " + ex);
+        }
+    }
 }