diff --git a/src/main/java/com/extendedae_plus/crafting/ForcedCraftingPlan.java b/src/main/java/com/extendedae_plus/crafting/ForcedCraftingPlan.java index 6ac2bae..c35836f 100644 --- a/src/main/java/com/extendedae_plus/crafting/ForcedCraftingPlan.java +++ b/src/main/java/com/extendedae_plus/crafting/ForcedCraftingPlan.java @@ -8,6 +8,8 @@ import com.extendedae_plus.api.crafting.IForcedCraftingPlan; import java.util.Map; +import java.util.LinkedHashMap; + public class ForcedCraftingPlan implements ICraftingPlan, IForcedCraftingPlan { private final ICraftingPlan delegate; private final KeyCounter manualMissingItems; @@ -22,6 +24,14 @@ public class ForcedCraftingPlan implements ICraftingPlan, IForcedCraftingPlan { return copy(this.manualMissingItems); } + public Map eap$getManualMissingSnapshot() { + var snapshot = new LinkedHashMap(); + for (var entry : this.manualMissingItems) { + snapshot.put(entry.getKey(), entry.getLongValue()); + } + return snapshot; + } + @Override public GenericStack finalOutput() { return this.delegate.finalOutput(); diff --git a/src/main/java/com/extendedae_plus/mixin/ExtendedAEPlusMixinPlugin.java b/src/main/java/com/extendedae_plus/mixin/ExtendedAEPlusMixinPlugin.java index 76996bb..825a8bb 100644 --- a/src/main/java/com/extendedae_plus/mixin/ExtendedAEPlusMixinPlugin.java +++ b/src/main/java/com/extendedae_plus/mixin/ExtendedAEPlusMixinPlugin.java @@ -59,7 +59,7 @@ public class ExtendedAEPlusMixinPlugin implements IMixinConfigPlugin { if (mixinClassName.equals("com.extendedae_plus.mixin.ae2.menu.CraftConfirmMenuGoBackMixin")) return false; } if (!isAdvancedAePresent()) { - if (mixinClassName.equals("com.extendedae_plus.mixin.advancedae.compat.PatternProviderLogicVirtualCompletionMixin")) { + if (mixinClassName.startsWith("com.extendedae_plus.mixin.advancedae.")) { return false; } } diff --git a/src/main/java/com/extendedae_plus/mixin/advancedae/crafting/AdvCraftingCPULogicManualWaitingMixin.java b/src/main/java/com/extendedae_plus/mixin/advancedae/crafting/AdvCraftingCPULogicManualWaitingMixin.java new file mode 100644 index 0000000..8d80672 --- /dev/null +++ b/src/main/java/com/extendedae_plus/mixin/advancedae/crafting/AdvCraftingCPULogicManualWaitingMixin.java @@ -0,0 +1,148 @@ +package com.extendedae_plus.mixin.advancedae.crafting; + +import appeng.api.config.Actionable; +import appeng.api.networking.IGrid; +import appeng.api.networking.crafting.ICraftingPlan; +import appeng.api.networking.crafting.ICraftingRequester; +import appeng.api.networking.crafting.ICraftingSubmitResult; +import appeng.api.networking.security.IActionSource; +import appeng.api.stacks.AEKey; +import appeng.api.stacks.KeyCounter; +import com.extendedae_plus.api.crafting.IForcedCraftingPlan; +import com.extendedae_plus.api.crafting.IManualCraftingState; +import com.extendedae_plus.crafting.ForcedCraftingPlan; +import net.pedroksl.advanced_ae.common.logic.AdvCraftingCPULogic; +import org.jetbrains.annotations.Nullable; +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.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +@Mixin(value = AdvCraftingCPULogic.class, remap = false) +public abstract class AdvCraftingCPULogicManualWaitingMixin implements IManualCraftingState { + @Unique + private final Map eap$manualWaitingFor = new LinkedHashMap<>(); + + @Override + public void eap$setManualWaiting(KeyCounter manualWaiting) { + this.eap$clearManualWaitingInternal(); + for (var entry : manualWaiting) { + if (entry.getKey() != null && entry.getLongValue() > 0) { + this.eap$manualWaitingFor.put(entry.getKey(), entry.getLongValue()); + } + } + } + + @Override + public long eap$getManualWaitingAmount(AEKey what) { + if (what == null) { + return 0; + } + return this.eap$manualWaitingFor.getOrDefault(what, 0L); + } + + @Override + public Map eap$getManualWaitingSnapshot() { + return new LinkedHashMap<>(this.eap$manualWaitingFor); + } + + @Inject(method = "trySubmitJob", at = @At("RETURN")) + private void eap$initManualWaitingForForcedPlan(IGrid grid, ICraftingPlan plan, IActionSource src, + @Nullable ICraftingRequester requester, CallbackInfoReturnable cir) { + if (!cir.getReturnValue().successful()) { + return; + } + + KeyCounter manualMissing = null; + if (plan instanceof IForcedCraftingPlan forcedPlan) { + manualMissing = forcedPlan.eap$getManualMissingItems(); + } else if (plan instanceof ForcedCraftingPlan forcedCraftingPlan) { + manualMissing = forcedCraftingPlan.eap$getManualMissingItems(); + } + + if (manualMissing != null) { + this.eap$setManualWaiting(manualMissing); + } else { + this.eap$clearManualWaitingInternal(); + } + } + + @Inject(method = "insert", at = @At("RETURN"), cancellable = true) + private void eap$consumeManualWaitingAfterVanilla(AEKey what, long amount, Actionable type, + CallbackInfoReturnable cir) { + if (what == null) { + return; + } + + long vanillaInserted = cir.getReturnValue(); + long remainingAmount = amount - vanillaInserted; + if (remainingAmount <= 0) { + return; + } + + long manualWaiting = this.eap$getManualWaitingAmount(what); + if (manualWaiting <= 0) { + return; + } + + long consumed = Math.min(remainingAmount, manualWaiting); + if (type == Actionable.MODULATE) { + this.eap$decreaseManualWaiting(what, consumed); + } + + cir.setReturnValue(vanillaInserted + consumed); + } + + @Inject(method = "getWaitingFor", at = @At("RETURN"), cancellable = true) + private void eap$appendManualWaitingToStatus(AEKey template, CallbackInfoReturnable cir) { + if (template == null) { + return; + } + long manualWaiting = this.eap$getManualWaitingAmount(template); + if (manualWaiting > 0) { + cir.setReturnValue(cir.getReturnValue() + manualWaiting); + } + } + + @Inject(method = "getAllWaitingFor", at = @At("TAIL")) + private void eap$appendManualWaitingKeys(Set waitingFor, CallbackInfo ci) { + waitingFor.addAll(this.eap$manualWaitingFor.keySet()); + } + + @Inject(method = "getAllItems", at = @At("TAIL")) + private void eap$appendManualWaitingItems(KeyCounter out, CallbackInfo ci) { + for (var entry : this.eap$manualWaitingFor.entrySet()) { + out.add(entry.getKey(), entry.getValue()); + } + } + + @Inject(method = "finishJob", at = @At("HEAD")) + private void eap$clearManualWaitingOnFinish(boolean success, CallbackInfo ci) { + this.eap$clearManualWaitingInternal(); + } + + @Unique + private void eap$decreaseManualWaiting(AEKey what, long amount) { + long current = this.eap$manualWaitingFor.getOrDefault(what, 0L); + if (current <= amount) { + this.eap$manualWaitingFor.remove(what); + } else { + this.eap$manualWaitingFor.put(what, current - amount); + } + } + + @Unique + private void eap$clearManualWaitingInternal() { + if (this.eap$manualWaitingFor.isEmpty()) { + return; + } + this.eap$manualWaitingFor.clear(); + } +} diff --git a/src/main/java/com/extendedae_plus/mixin/advancedae/menu/CraftingCPUMenuManualStatusAdvancedMixin.java b/src/main/java/com/extendedae_plus/mixin/advancedae/menu/CraftingCPUMenuManualStatusAdvancedMixin.java new file mode 100644 index 0000000..c90e24b --- /dev/null +++ b/src/main/java/com/extendedae_plus/mixin/advancedae/menu/CraftingCPUMenuManualStatusAdvancedMixin.java @@ -0,0 +1,58 @@ +package com.extendedae_plus.mixin.advancedae.menu; + +import appeng.api.networking.crafting.ICraftingCPU; +import appeng.api.stacks.AEKey; +import appeng.menu.me.crafting.CraftingCPUMenu; +import com.extendedae_plus.api.crafting.IManualCraftingState; +import com.extendedae_plus.network.crafting.ManualCraftingStatusS2CPacket; +import net.minecraft.server.level.ServerPlayer; +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.CallbackInfo; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +@Mixin(value = CraftingCPUMenu.class, remap = false) +public abstract class CraftingCPUMenuManualStatusAdvancedMixin { + @Unique + private AdvCraftingCPU eap$advancedaeSelectedCpu; + + @Unique + private Map eap$advancedaeLastManualWaitingSnapshot = Collections.emptyMap(); + + @Inject(method = "setCPU", at = @At("HEAD")) + private void eap$trackAdvancedAeCpu(ICraftingCPU cpu, CallbackInfo ci) { + this.eap$advancedaeSelectedCpu = cpu instanceof AdvCraftingCPU advCpu ? advCpu : null; + if (this.eap$advancedaeSelectedCpu == null) { + this.eap$advancedaeLastManualWaitingSnapshot = Collections.emptyMap(); + } + } + + @Inject(method = "broadcastChanges", at = @At("TAIL")) + private void eap$syncAdvancedAeManualWaitingStatus(CallbackInfo ci) { + CraftingCPUMenu self = (CraftingCPUMenu) (Object) this; + if (self.isClientSide() || !(self.getPlayer() instanceof ServerPlayer serverPlayer)) { + return; + } + if (this.eap$advancedaeSelectedCpu == null) { + return; + } + + Map snapshot = Collections.emptyMap(); + if (this.eap$advancedaeSelectedCpu.craftingLogic instanceof IManualCraftingState manualState) { + snapshot = manualState.eap$getManualWaitingSnapshot(); + } + + if (snapshot.equals(this.eap$advancedaeLastManualWaitingSnapshot)) { + return; + } + + this.eap$advancedaeLastManualWaitingSnapshot = new LinkedHashMap<>(snapshot); + serverPlayer.connection.send(new ManualCraftingStatusS2CPacket(self.containerId, snapshot)); + } +} diff --git a/src/main/resources/extendedae_plus.mixins.json b/src/main/resources/extendedae_plus.mixins.json index 3935b6c..d8e80a1 100644 --- a/src/main/resources/extendedae_plus.mixins.json +++ b/src/main/resources/extendedae_plus.mixins.json @@ -9,6 +9,7 @@ "advancedae.accessor.AdvCraftingCPUAccessor", "advancedae.accessor.AdvCraftingCPULogicAccessor", "advancedae.accessor.AdvExecutingCraftingJobAccessor", + "advancedae.crafting.AdvCraftingCPULogicManualWaitingMixin", "advancedae.accessor.AdvExecutingCraftingJobTaskProgressAccessor", "advancedae.accessor.AdvPatternProviderLogicPatternsAccessor", "advancedae.accessor.AdvPatternProviderMenuAdvancedAccessor", @@ -17,6 +18,7 @@ "advancedae.helpers.AdvPatternProviderLogicDoublingMixin", "advancedae.menu.AdvPatternProviderMenuAdvancedMixin", "advancedae.menu.AdvPatternProviderMenuDoublingMixin", + "advancedae.menu.CraftingCPUMenuManualStatusAdvancedMixin", "ae2.AEProcessingPatternMixin", "ae2.CraftingCalculationMixin", "ae2.CraftingCPUClusterMixin",