From c992defcfc40ab13b9c374dd6bce6b1bd66a8e34 Mon Sep 17 00:00:00 2001 From: reobf <2215595288@qq.com> Date: Wed, 14 Feb 2024 22:40:58 +0800 Subject: [PATCH] fix item changes not properly synced to client --- .../BufferedDualInputHatch.java | 38 +++++++++++---- .../reobf/proghatches/main/CommonProxy.java | 4 ++ .../proghatches/main/mixin/MixinPlugin.java | 12 +++-- .../MixinRemoveUnunsedItemStackCache.java | 45 +++++++++++++++++ .../reobf/proghatches/oc/TileCoprocessor.java | 48 +++++++++++++++++++ 5 files changed, 135 insertions(+), 12 deletions(-) create mode 100644 src/main/java/reobf/proghatches/main/mixin/mixins/MixinRemoveUnunsedItemStackCache.java create mode 100644 src/main/java/reobf/proghatches/oc/TileCoprocessor.java diff --git a/src/main/java/reobf/proghatches/gt/metatileentity/BufferedDualInputHatch.java b/src/main/java/reobf/proghatches/gt/metatileentity/BufferedDualInputHatch.java index fd84968..9a53baf 100644 --- a/src/main/java/reobf/proghatches/gt/metatileentity/BufferedDualInputHatch.java +++ b/src/main/java/reobf/proghatches/gt/metatileentity/BufferedDualInputHatch.java @@ -23,6 +23,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraft.nbt.JsonToNBT; import net.minecraft.nbt.NBTException; @@ -451,7 +452,8 @@ public void firstClassify(ListeningFluidTank[] fin, ItemStack[] iin) { .orElse(null); iin[ix] = null; } - justHadNewItems = true; + justHadNewItems = true; + onClassify(); programLocal(); } @@ -521,6 +523,7 @@ public void classify(ListeningFluidTank[] fin, ItemStack[] iin) { iin[ix] = null; } justHadNewItems = true; + onClassify(); if (program) programLocal(); } @@ -630,6 +633,7 @@ public static class CallerCheck { } } public boolean highEfficiencyMode(){return false;} +public boolean prevdirty; @Override public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { super.onPostTick(aBaseMetaTileEntity, aTick); @@ -654,7 +658,7 @@ public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { inv0.clearRecipeIfNeeded(); } - + prevdirty=dirty; dirty=false; } @@ -796,7 +800,8 @@ private Function get() { @Override public void detectAndSendChanges(boolean init) { - getContext().syncSlotContent(this.getMcSlot()); + + //getContext().syncSlotContent(this.getMcSlot()); super.detectAndSendChanges(init); /* @@ -1054,8 +1059,19 @@ public void addUIWidgets(Builder builder, UIBuildContext buildContext) { builder.widget(createPowerSwitchButton(builder)); builder.widget(new SyncedWidget(){ - //player operation is more complicated, always set to true when GUI open - public void detectAndSendChanges(boolean init) {BufferedDualInputHatch.this.dirty=true;}; + + @SuppressWarnings("unchecked") + public void detectAndSendChanges(boolean init) { + //player operation is more complicated, always set to true when GUI open + BufferedDualInputHatch.this.dirty=true; + + //flush changes to client + //sometimes vanilla detection will fail so sync it manually + if(last+1>=getBaseMetaTileEntity().getTimer()) + getWindow().getContext().getContainer().inventorySlots + .forEach(s->((Slot)s).onSlotChanged()); + + }; @Override public void readOnClient(int id, PacketBuffer buf) throws IOException {} @Override public void readOnServer(int id, PacketBuffer buf) throws IOException {}}); ProghatchesUtil.attachZeroSizedStackRemover(builder,buildContext); @@ -1068,7 +1084,11 @@ public int moveButtons() { return 0; } - + public void onClassify(){ + last=getBaseMetaTileEntity().getTimer(); + } + private long last; + @Override public void loadNBTData(NBTTagCompound aNBT) { dirty=aNBT.getBoolean("dirty"); @@ -1200,8 +1220,9 @@ class RecipeTracker{ boolean broken; int times; boolean first=true; + boolean onceCompared; public void track(ItemStack recipe,ItemStack storage){ - if(recipe.getItem() instanceof ItemProgrammingCircuit){return;} + if(recipe.getItem() instanceof ItemProgrammingCircuit){onceCompared=true;return;} int a=recipe.stackSize; int b=Optional.ofNullable(storage).map(s->s.stackSize).orElse(0); track(a,b); @@ -1218,6 +1239,7 @@ public void track(int a,int b){ if(b%a!=0){broken=true;return;} t=b/a; if(t!=times){ + onceCompared=true; if(first){first=false;times=t;return;} else {broken=true;return;} } @@ -1248,7 +1270,7 @@ public void track(int a,int b){ ); - sub.setInteger("possibleCopies", rt.broken?-1:rt.times); + sub.setInteger("possibleCopies", (rt.broken||(!rt.onceCompared&&!inv.isEmpty()))?-1:rt.times); }); super.getWailaNBTData(player, tile, tag, world, x, y, z); diff --git a/src/main/java/reobf/proghatches/main/CommonProxy.java b/src/main/java/reobf/proghatches/main/CommonProxy.java index 367d68e..d68af48 100644 --- a/src/main/java/reobf/proghatches/main/CommonProxy.java +++ b/src/main/java/reobf/proghatches/main/CommonProxy.java @@ -30,6 +30,7 @@ import reobf.proghatches.oc.ItemAPICard; import reobf.proghatches.oc.ItemGTRedstoneCard; import reobf.proghatches.oc.ItemWirelessPeripheralCard; +import reobf.proghatches.oc.TileCoprocessor; import reobf.proghatches.oc.TileWirelessPeripheralStation; public class CommonProxy { @@ -45,6 +46,9 @@ public void preInit(FMLPreInitializationEvent event) { GameRegistry.registerTileEntity(TileIOHub.class, "proghatches.iohub"); GameRegistry.registerTileEntity(TileWirelessPeripheralStation.class, "proghatches.peripheral_station"); + GameRegistry.registerTileEntity(TileCoprocessor.class, "proghatches.coprocessor"); + + GameRegistry.registerItem( MyMod.progcircuit = new ItemProgrammingCircuit().setUnlocalizedName("prog_circuit") .setTextureName("?"), diff --git a/src/main/java/reobf/proghatches/main/mixin/MixinPlugin.java b/src/main/java/reobf/proghatches/main/mixin/MixinPlugin.java index 65c5525..ec9b61d 100644 --- a/src/main/java/reobf/proghatches/main/mixin/MixinPlugin.java +++ b/src/main/java/reobf/proghatches/main/mixin/MixinPlugin.java @@ -59,8 +59,8 @@ public void acceptTargets(Set myTargets, Set otherTargets) { "#set to true to disable those optional mixins if it breaks someting"+System.lineSeparator()+ "noPatternEncodingMixin=false"+System.lineSeparator()+ "noFixTossBug=false"+System.lineSeparator()+ -"noRecipeFilterForDualHatch=false"+System.lineSeparator() - +"noRecipeFilterForDualHatch=false"+System.lineSeparator()+ +"noRemoveUnusedCacheInModularUIContainer=fasle"+System.lineSeparator() ; @SuppressWarnings("unused") @Override @@ -95,12 +95,16 @@ public List getMixins() { System.out.println(pp); System.out.println("ccccccccccccccccccccccccccc"); - // NEE is neither coremod nor mixinmod so add it to path or mixin will fail + // NEE is neither coremod nor mixinmod thus it's not in URL path, so add it to path or mixin will fail loadJarOf(MixinPlugin::hasTrait,"NotEnoughEnergistics"); - // GregTech5RecipeProcessor.class.getDeclaredFields(); + ArrayList ret = new ArrayList<>(); + + if(!"true".equals(pp.get("noRemoveUnusedCacheInModularUIContainer"))) + ret.add("MixinRemoveUnunsedItemStackCache"); + if(!"true".equals(pp.get("noRecipeFilterForDualHatch"))){ ret.add("MixinGTRecipeFilter"); // GT Multiblock will not set recipe filter of DualInputHatch, set it via mixin diff --git a/src/main/java/reobf/proghatches/main/mixin/mixins/MixinRemoveUnunsedItemStackCache.java b/src/main/java/reobf/proghatches/main/mixin/mixins/MixinRemoveUnunsedItemStackCache.java new file mode 100644 index 0000000..8f0a41d --- /dev/null +++ b/src/main/java/reobf/proghatches/main/mixin/mixins/MixinRemoveUnunsedItemStackCache.java @@ -0,0 +1,45 @@ +package reobf.proghatches.main.mixin.mixins; + +import java.util.List; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.gtnewhorizons.modularui.common.internal.wrapper.ModularUIContainer; + +import io.netty.buffer.ByteBuf; +import net.minecraft.inventory.Container; + +@Mixin(value = ModularUIContainer.class, remap = false) +public abstract class MixinRemoveUnunsedItemStackCache extends Container{ + + + /* + addSlotToContainer() in Container.java will add to both inventorySlots and inventoryItemStacks + removeSlot() in ModularUIContainer.java only remove inventorySlots + that means open and close a child window with slotwidgets will lengthen inventoryItemStacks + this mixin will fix this potential leak + */ + + private int length; + @Inject(method = "removeSlot", at = @At(value = "HEAD"), require = 1, cancellable = false) + private void removeSlot0(net.minecraft.inventory.Slot slot, CallbackInfo c) + { + length=this.inventoryItemStacks.size(); + } + + @Inject(method = "removeSlot", at = @At(value = "TAIL"), require = 1, cancellable = false) + + private void removeSlot1(net.minecraft.inventory.Slot slot, CallbackInfo c) + { + if(length!=this.inventoryItemStacks.size())return;//just in case it's fixed in future version + this.inventoryItemStacks.remove(slot.slotNumber); + // System.out.println( this.inventoryItemStacks); + } + + + +} diff --git a/src/main/java/reobf/proghatches/oc/TileCoprocessor.java b/src/main/java/reobf/proghatches/oc/TileCoprocessor.java new file mode 100644 index 0000000..8c9bd44 --- /dev/null +++ b/src/main/java/reobf/proghatches/oc/TileCoprocessor.java @@ -0,0 +1,48 @@ +package reobf.proghatches.oc; + +import java.util.Optional; + +import li.cil.oc.api.network.Message; +import li.cil.oc.api.network.Node; +import li.cil.oc.api.network.Visibility; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; + +public class TileCoprocessor extends TileEntity implements li.cil.oc.api.network.Environment{ + Node node_ = li.cil.oc.api.Network.newNode(this, Visibility.Network) + .withComponent("coprocessor") + .create(); + @Override + public Node node() { + + return node_; + } +@Override +public void writeToNBT(NBTTagCompound compound) { + Optional.ofNullable(node_).ifPresent(s->s.save(compound)); + super.writeToNBT(compound); +} +@Override +public void readFromNBT(NBTTagCompound compound) { + Optional.ofNullable(node_).ifPresent(s->s.load(compound)); + super.readFromNBT(compound); +} + @Override + public void onConnect(Node node) { + + + } + + @Override + public void onDisconnect(Node node) { + + + } + + @Override + public void onMessage(Message message) { + + + } + +}