Complete crafting jobs on networks without discretizer (#225)

This commit is contained in:
Demiu authored and GitHub committed 2024-08-27 11:30:49 +02:00
1 parent a3eee96d75
commit b2e74d8ea0
4 files changed
+162 -46

No files matched your search

@@ -7,6 +7,7 @@ import org.objectweb.asm.ClassVisitor;
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 class FCClassTransformer implements IClassTransformer {
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;
@@ -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 net.minecraftforge.fluids.FluidStack;
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 class CoreModHooks {
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<? extends IGridHost> 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<IGridNode> 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 class CoreModHooks {
} else return aeStack.getStackSize();
}
public static List<IMEInventoryHandler> 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);
@@ -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();
}
}
}
@@ -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<IAEFluidStack> {
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<IAEFluidStack> getAvailableItems(IItemList<IAEFluidStack> 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);
}
}