diff --git a/src/main/java/com/glodblock/github/coremod/FCClassTransformer.java b/src/main/java/com/glodblock/github/coremod/FCClassTransformer.java index f43c8ebf6..74e9dbea5 100644 --- a/src/main/java/com/glodblock/github/coremod/FCClassTransformer.java +++ b/src/main/java/com/glodblock/github/coremod/FCClassTransformer.java @@ -7,6 +7,7 @@ import org.objectweb.asm.ClassWriter; import com.glodblock.github.coremod.transform.CraftingCpuTransformer; +import com.glodblock.github.coremod.transform.CraftingGridCacheTransformer; import com.glodblock.github.coremod.transform.CraftingTreeNodeTransformer; import com.glodblock.github.coremod.transform.DualityInterfaceTransformer; import com.glodblock.github.coremod.transform.ExternalStorageRegistryTransformer; @@ -20,6 +21,7 @@ public byte[] transform(String name, String transformedName, byte[] code) { Transform tform; switch (transformedName) { case "appeng.crafting.CraftingTreeNode" -> tform = CraftingTreeNodeTransformer.INSTANCE; + case "appeng.me.cache.CraftingGridCache" -> tform = CraftingGridCacheTransformer.INSTANCE; case "appeng.me.cluster.implementations.CraftingCPUCluster" -> tform = CraftingCpuTransformer.INSTANCE; case "appeng.helpers.DualityInterface" -> tform = DualityInterfaceTransformer.INSTANCE; case "appeng.client.gui.implementations.GuiCraftingCPU", "appeng.client.gui.implementations.GuiCraftConfirm", "net.p455w0rd.wirelesscraftingterminal.client.gui.GuiCraftConfirm", "appeng.client.gui.widgets.GuiCraftingTree" -> tform = GuiCraftingTransformer.INSTANCE; diff --git a/src/main/java/com/glodblock/github/coremod/hooker/CoreModHooks.java b/src/main/java/com/glodblock/github/coremod/hooker/CoreModHooks.java index 3a3f63f5a..3d7e8e925 100644 --- a/src/main/java/com/glodblock/github/coremod/hooker/CoreModHooks.java +++ b/src/main/java/com/glodblock/github/coremod/hooker/CoreModHooks.java @@ -1,7 +1,7 @@ package com.glodblock.github.coremod.hooker; -import java.util.HashSet; -import java.util.Set; +import java.util.Arrays; +import java.util.List; import javax.annotation.Nullable; @@ -15,30 +15,24 @@ import com.glodblock.github.client.gui.GuiFluidCraftConfirm; import com.glodblock.github.common.item.ItemFluidDrop; import com.glodblock.github.common.item.ItemFluidPacket; -import com.glodblock.github.common.parts.PartFluidInterface; -import com.glodblock.github.common.tile.TileFluidInterface; +import com.glodblock.github.inventory.CraftingGridCacheFluidInventoryProxyCell; import com.glodblock.github.inventory.FluidConvertingInventoryAdaptor; import com.glodblock.github.inventory.FluidConvertingInventoryCrafting; import com.glodblock.github.loader.ItemAndBlockHolder; import com.glodblock.github.util.Ae2Reflect; -import com.glodblock.github.util.SetBackedMachineSet; -import com.google.common.collect.Sets; import appeng.api.config.Actionable; import appeng.api.networking.IGrid; -import appeng.api.networking.IGridHost; -import appeng.api.networking.IGridNode; -import appeng.api.networking.IMachineSet; import appeng.api.networking.storage.IStorageGrid; import appeng.api.storage.IMEInventory; +import appeng.api.storage.IMEInventoryHandler; +import appeng.api.storage.StorageChannel; import appeng.api.storage.data.IAEFluidStack; import appeng.api.storage.data.IAEItemStack; import appeng.client.gui.IGuiTooltipHandler; import appeng.crafting.MECraftingInventory; -import appeng.me.MachineSet; +import appeng.me.cache.CraftingGridCache; import appeng.me.cluster.implementations.CraftingCPUCluster; -import appeng.parts.misc.PartInterface; -import appeng.tile.misc.TileInterface; import appeng.util.InventoryAdaptor; public class CoreModHooks { @@ -87,40 +81,6 @@ public static long getFluidDropsByteCost(long totalBytes, long originByte, IAEIt return originByte + totalBytes; } - public static IAEItemStack[] flattenFluidPackets(IAEItemStack[] stacks) { - for (int i = 0; i < stacks.length; i++) { - if (stacks[i].getItem() instanceof ItemFluidPacket) { - stacks[i] = ItemFluidDrop.newAeStack(ItemFluidPacket.getFluidStack(stacks[i])); - } - } - return stacks; - } - - public static IMachineSet getMachines(IGrid grid, Class c) { - if (c == TileInterface.class) { - return unionMachineSets(grid.getMachines(c), grid.getMachines(TileFluidInterface.class)); - } else if (c == PartInterface.class) { - return unionMachineSets(grid.getMachines(c), grid.getMachines(PartFluidInterface.class)); - } else { - return grid.getMachines(c); - } - } - - private static IMachineSet unionMachineSets(IMachineSet a, IMachineSet b) { - if (a.isEmpty()) { - return b; - } else if (b.isEmpty()) { - return a; - } else if (a instanceof MachineSet && b instanceof MachineSet) { - return new SetBackedMachineSet(TileInterface.class, Sets.union((MachineSet) a, (MachineSet) b)); - } else { - Set union = new HashSet<>(); - a.forEach(union::add); - b.forEach(union::add); - return new SetBackedMachineSet(TileInterface.class, union); - } - } - public static ItemStack displayFluid(IAEItemStack aeStack) { if (aeStack.getItemStack() != null && aeStack.getItemStack().getItem() instanceof ItemFluidDrop) { FluidStack fluid = ItemFluidDrop.getFluidStack(aeStack.getItemStack()); @@ -134,6 +94,13 @@ public static long getFluidSize(IAEItemStack aeStack) { } else return aeStack.getStackSize(); } + public static List craftingGridCacheGetCellArray(final CraftingGridCache instance, + final StorageChannel channel) { + // Equivalent to original function, but using the proxy for fluid channel + return channel == StorageChannel.ITEMS ? Arrays.asList(instance) + : Arrays.asList(new CraftingGridCacheFluidInventoryProxyCell(instance)); + } + public static void storeFluidItem(CraftingCPUCluster instance) { final IGrid g = Ae2Reflect.getGrid(instance); diff --git a/src/main/java/com/glodblock/github/coremod/transform/CraftingGridCacheTransformer.java b/src/main/java/com/glodblock/github/coremod/transform/CraftingGridCacheTransformer.java new file mode 100644 index 000000000..0a1b5e3aa --- /dev/null +++ b/src/main/java/com/glodblock/github/coremod/transform/CraftingGridCacheTransformer.java @@ -0,0 +1,67 @@ +package com.glodblock.github.coremod.transform; + +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +import com.glodblock.github.coremod.FCClassTransformer; + +public class CraftingGridCacheTransformer extends FCClassTransformer.ClassMapper { + + public static final CraftingGridCacheTransformer INSTANCE = new CraftingGridCacheTransformer(); + + private CraftingGridCacheTransformer() { + // NO-OP + } + + @Override + protected ClassVisitor getClassMapper(ClassVisitor downstream) { + return new CraftingGridCacheTransformer.TransformCraftingGridCache(Opcodes.ASM5, downstream); + } + + private static class TransformCraftingGridCache extends ClassVisitor { + + TransformCraftingGridCache(int api, ClassVisitor cv) { + super(api, cv); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + if (name.equals("getCellArray")) { + return new CraftingGridCacheTransformer.ReplaceGetCellArray( + api, + super.visitMethod(access, name, desc, signature, exceptions)); + } + return super.visitMethod(access, name, desc, signature, exceptions); + } + } + + private static class ReplaceGetCellArray extends MethodVisitor { + + private final MethodVisitor target; + + ReplaceGetCellArray(int api, MethodVisitor mv) { + // Original method is replaced + super(api, null); + target = mv; + } + + @Override + public void visitCode() { + target.visitCode(); + // Equivalent to + // return CoreModHooks::craftingGridCacheGetCellArray(this, channel); + target.visitVarInsn(Opcodes.ALOAD, 0); + target.visitVarInsn(Opcodes.ALOAD, 1); + target.visitMethodInsn( + Opcodes.INVOKESTATIC, + "com/glodblock/github/coremod/hooker/CoreModHooks", + "craftingGridCacheGetCellArray", + "(Lappeng/me/cache/CraftingGridCache;Lappeng/api/storage/StorageChannel;)Ljava/util/List;", + false); + target.visitInsn(Opcodes.ARETURN); + target.visitMaxs(2, 3); + target.visitEnd(); + } + } +} diff --git a/src/main/java/com/glodblock/github/inventory/CraftingGridCacheFluidInventoryProxyCell.java b/src/main/java/com/glodblock/github/inventory/CraftingGridCacheFluidInventoryProxyCell.java new file mode 100644 index 000000000..25722aaad --- /dev/null +++ b/src/main/java/com/glodblock/github/inventory/CraftingGridCacheFluidInventoryProxyCell.java @@ -0,0 +1,80 @@ +package com.glodblock.github.inventory; + +import org.jetbrains.annotations.NotNull; + +import com.glodblock.github.common.item.ItemFluidDrop; + +import appeng.api.config.AccessRestriction; +import appeng.api.config.Actionable; +import appeng.api.networking.security.BaseActionSource; +import appeng.api.storage.IMEInventoryHandler; +import appeng.api.storage.StorageChannel; +import appeng.api.storage.data.IAEFluidStack; +import appeng.api.storage.data.IAEItemStack; +import appeng.api.storage.data.IItemList; +import appeng.me.cache.CraftingGridCache; + +public class CraftingGridCacheFluidInventoryProxyCell implements IMEInventoryHandler { + + private final CraftingGridCache inner; + + public CraftingGridCacheFluidInventoryProxyCell(final CraftingGridCache craftingGridCache) { + inner = craftingGridCache; + } + + @Override + public IAEFluidStack injectItems(IAEFluidStack input, Actionable type, BaseActionSource src) { + return ItemFluidDrop + .getAeFluidStack((IAEItemStack) inner.injectItems(ItemFluidDrop.newAeStack(input), type, src)); + } + + @Override + public IAEFluidStack extractItems(IAEFluidStack request, Actionable mode, BaseActionSource src) { + return null; + } + + @Override + public IItemList getAvailableItems(IItemList out, int iteration) { + return out; + } + + @Override + public IAEFluidStack getAvailableItem(@NotNull IAEFluidStack request, int iteration) { + return null; + } + + @Override + public StorageChannel getChannel() { + return StorageChannel.FLUIDS; + } + + @Override + public AccessRestriction getAccess() { + return inner.getAccess(); + } + + @Override + public boolean isPrioritized(IAEFluidStack input) { + return inner.isPrioritized(input); + } + + @Override + public boolean canAccept(IAEFluidStack input) { + return inner.canAccept(ItemFluidDrop.newAeStack(input)); + } + + @Override + public int getPriority() { + return inner.getPriority(); + } + + @Override + public int getSlot() { + return inner.getSlot(); + } + + @Override + public boolean validForPass(int i) { + return inner.validForPass(i); + } +}