diff --git a/src/main/java/com/extendedae_plus/mixin/advancedae/accessor/AdvCraftingCPUAccessor.java b/src/main/java/com/extendedae_plus/mixin/advancedae/accessor/AdvCraftingCPUAccessor.java new file mode 100644 index 0000000..dd24ad9 --- /dev/null +++ b/src/main/java/com/extendedae_plus/mixin/advancedae/accessor/AdvCraftingCPUAccessor.java @@ -0,0 +1,12 @@ +package com.extendedae_plus.mixin.advancedae.accessor; + +import appeng.api.stacks.GenericStack; +import net.pedroksl.advanced_ae.common.cluster.AdvCraftingCPU; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(value = AdvCraftingCPU.class, remap = false) +public interface AdvCraftingCPUAccessor { + @Invoker("updateOutput") + void eap$invokeUpdateOutput(GenericStack stack); +} diff --git a/src/main/java/com/extendedae_plus/mixin/advancedae/accessor/AdvCraftingCPULogicAccessor.java b/src/main/java/com/extendedae_plus/mixin/advancedae/accessor/AdvCraftingCPULogicAccessor.java index c505380..4c7ad28 100644 --- a/src/main/java/com/extendedae_plus/mixin/advancedae/accessor/AdvCraftingCPULogicAccessor.java +++ b/src/main/java/com/extendedae_plus/mixin/advancedae/accessor/AdvCraftingCPULogicAccessor.java @@ -4,10 +4,14 @@ import net.pedroksl.advanced_ae.common.logic.AdvCraftingCPULogic; import net.pedroksl.advanced_ae.common.logic.ExecutingCraftingJob; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.gen.Invoker; @Mixin(value = AdvCraftingCPULogic.class, remap = false) public interface AdvCraftingCPULogicAccessor { @Accessor("job") ExecutingCraftingJob eap$getAdvJob(); + + @Invoker("finishJob") + void eap$invokeAdvFinishJob(boolean success); } diff --git a/src/main/java/com/extendedae_plus/mixin/advancedae/compat/PatternProviderLogicVirtualCompletionMixin.java b/src/main/java/com/extendedae_plus/mixin/advancedae/compat/PatternProviderLogicVirtualCompletionMixin.java index c8b5d76..a67c94d 100644 --- a/src/main/java/com/extendedae_plus/mixin/advancedae/compat/PatternProviderLogicVirtualCompletionMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/advancedae/compat/PatternProviderLogicVirtualCompletionMixin.java @@ -6,15 +6,19 @@ import appeng.api.networking.crafting.ICraftingService; import appeng.api.stacks.KeyCounter; import appeng.helpers.patternprovider.PatternProviderLogic; import com.extendedae_plus.compat.PatternProviderLogicVirtualCompatBridge; +import com.extendedae_plus.mixin.advancedae.accessor.AdvCraftingCPUAccessor; import com.extendedae_plus.mixin.advancedae.accessor.AdvCraftingCPULogicAccessor; import com.extendedae_plus.mixin.advancedae.accessor.AdvExecutingCraftingJobAccessor; import com.extendedae_plus.mixin.advancedae.accessor.AdvExecutingCraftingJobTaskProgressAccessor; import net.pedroksl.advanced_ae.common.cluster.AdvCraftingCPU; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import java.util.Map; + /** * AdvancedAE 版本的虚拟完成兼容逻辑。 */ @@ -85,8 +89,20 @@ public abstract class PatternProviderLogicVirtualCompletionMixin { } if (progress instanceof AdvExecutingCraftingJobTaskProgressAccessor advProgressAccessor) { - if (advProgressAccessor.eap$getAdvValue() <= 1) { - advCpu.cancelJob(); + if (this.eap$advancedaeShouldCancelWholeJob(tasks, advProgressAccessor)) { + boolean finished = false; + try { + ((AdvCraftingCPUAccessor) (Object) advCpu).eap$invokeUpdateOutput(null); + } catch (Throwable ignored) { + } + try { + advLogicAccessor.eap$invokeAdvFinishJob(true); + finished = true; + } catch (Throwable ignored) { + } + if (!finished) { + advCpu.cancelJob(); + } break; } } @@ -95,4 +111,31 @@ public abstract class PatternProviderLogicVirtualCompletionMixin { } } } + + @Unique + private boolean eap$advancedaeShouldCancelWholeJob( + Map tasks, + AdvExecutingCraftingJobTaskProgressAccessor matchedProgress) { + if (matchedProgress.eap$getAdvValue() > 1) { + return false; + } + + for (var entry : tasks.entrySet()) { + var taskProgress = entry.getValue(); + if (!(taskProgress instanceof AdvExecutingCraftingJobTaskProgressAccessor advTaskProgress)) { + continue; + } + + long remaining = advTaskProgress.eap$getAdvValue(); + if (taskProgress == matchedProgress) { + remaining -= 1; + } + + if (remaining > 0) { + return false; + } + } + + return true; + } } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/accessor/CraftingCPUClusterAccessor.java b/src/main/java/com/extendedae_plus/mixin/ae2/accessor/CraftingCPUClusterAccessor.java new file mode 100644 index 0000000..742ad5c --- /dev/null +++ b/src/main/java/com/extendedae_plus/mixin/ae2/accessor/CraftingCPUClusterAccessor.java @@ -0,0 +1,12 @@ +package com.extendedae_plus.mixin.ae2.accessor; + +import appeng.api.stacks.GenericStack; +import appeng.me.cluster.implementations.CraftingCPUCluster; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(value = CraftingCPUCluster.class, remap = false) +public interface CraftingCPUClusterAccessor { + @Invoker("updateOutput") + void eap$invokeUpdateOutput(GenericStack finalOutput); +} diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/accessor/CraftingCpuLogicAccessor.java b/src/main/java/com/extendedae_plus/mixin/ae2/accessor/CraftingCpuLogicAccessor.java index 2508d37..0a355c1 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/accessor/CraftingCpuLogicAccessor.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/accessor/CraftingCpuLogicAccessor.java @@ -4,9 +4,13 @@ import appeng.crafting.execution.CraftingCpuLogic; import appeng.crafting.execution.ExecutingCraftingJob; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.gen.Invoker; @Mixin(value = CraftingCpuLogic.class, remap = false) public interface CraftingCpuLogicAccessor { @Accessor("job") ExecutingCraftingJob eap$getJob(); + + @Invoker("finishJob") + void eap$invokeFinishJob(boolean success); } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java index 87bc318..c25c192 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java @@ -21,6 +21,7 @@ import com.extendedae_plus.api.bridge.PatternProviderLogicUpgradeCompatBridge; import com.extendedae_plus.compat.PatternProviderLogicVirtualCompatBridge; import com.extendedae_plus.compat.UpgradeSlotCompat; import com.extendedae_plus.init.ModItems; +import com.extendedae_plus.mixin.ae2.accessor.CraftingCPUClusterAccessor; import com.extendedae_plus.mixin.ae2.accessor.CraftingCpuLogicAccessor; import com.extendedae_plus.mixin.ae2.accessor.ExecutingCraftingJobAccessor; import com.extendedae_plus.mixin.appflux.accessor.PatternProviderLogicAppfluxAccessor; @@ -38,6 +39,8 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import java.util.Map; + import java.util.List; import java.util.UUID; @@ -483,8 +486,20 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr } } - if (progress != null && progress.eap$getValue() <= 1) { - cluster.cancelJob(); + if (this.eap$compatShouldCancelWholeJob(tasks, progress)) { + boolean finished = false; + try { + ((CraftingCPUClusterAccessor) (Object) cluster).eap$invokeUpdateOutput(null); + } catch (Throwable ignored) { + } + try { + logicAccessor.eap$invokeFinishJob(true); + finished = true; + } catch (Throwable ignored) { + } + if (!finished) { + cluster.cancelJob(); + } break; } } @@ -503,6 +518,33 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr return this.mainNode; } + @Unique + private boolean eap$compatShouldCancelWholeJob( + Map tasks, + com.extendedae_plus.mixin.ae2.accessor.ExecutingCraftingJobTaskProgressAccessor matchedProgress) { + if (matchedProgress == null || matchedProgress.eap$getValue() > 1) { + return false; + } + + for (var entry : tasks.entrySet()) { + var taskProgress = entry.getValue(); + if (taskProgress == null) { + continue; + } + + long remaining = taskProgress.eap$getValue(); + if (taskProgress == matchedProgress) { + remaining -= 1; + } + + if (remaining > 0) { + return false; + } + } + + return true; + } + @Unique private void eap$compatSyncVirtualCraftingState() { try { diff --git a/src/main/resources/extendedae_plus.mixins.json b/src/main/resources/extendedae_plus.mixins.json index baa6d9f..d230e40 100644 --- a/src/main/resources/extendedae_plus.mixins.json +++ b/src/main/resources/extendedae_plus.mixins.json @@ -6,6 +6,7 @@ "mixins": [ "advancedae.AdvPatternProviderLogicContainsRedirectMixin", "advancedae.AdvProcessingPatternMixin", + "advancedae.accessor.AdvCraftingCPUAccessor", "advancedae.accessor.AdvCraftingCPULogicAccessor", "advancedae.accessor.AdvExecutingCraftingJobAccessor", "advancedae.accessor.AdvExecutingCraftingJobTaskProgressAccessor", @@ -19,6 +20,7 @@ "ae2.AEProcessingPatternMixin", "ae2.CraftingCalculationMixin", "ae2.CraftingCPUClusterMixin", + "ae2.accessor.CraftingCPUClusterAccessor", "ae2.EncodedPatternItemMixin", "ae2.accessor.CraftingCpuLogicAccessor", "ae2.accessor.ExecutingCraftingJobAccessor",