From bce3562b2599ce966ca7ca5332fa779dc788355e Mon Sep 17 00:00:00 2001 From: C-H716 <1536152356@qq.com> Date: Mon, 24 Nov 2025 20:29:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=86=E7=A6=BBADV=E7=9A=84=E9=80=82?= =?UTF-8?q?=E9=85=8Dmixin=E5=88=B0=E5=8D=95=E7=8B=ACmixin&mixinPlugin?= =?UTF-8?q?=E4=B8=AD=E5=A2=9E=E5=8A=A0=E5=88=A4=E6=96=AD=E6=98=AF=E5=90=A6?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E8=AF=A5mixin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modMetadata/META-INF/neoforge.mods.toml | 87 ++++++++-------- ...tternProviderLogicVirtualCompatBridge.java | 9 ++ .../mixin/ExtendedAEPlusMixinPlugin.java | 23 ++++- ...rnProviderLogicVirtualCompletionMixin.java | 98 +++++++++++++++++++ .../PatternProviderLogicCompatMixin.java | 53 +++------- .../resources/extendedae_plus.mixins.json | 19 ++-- 6 files changed, 187 insertions(+), 102 deletions(-) create mode 100644 src/main/java/com/extendedae_plus/compat/PatternProviderLogicVirtualCompatBridge.java create mode 100644 src/main/java/com/extendedae_plus/mixin/advancedae/compat/PatternProviderLogicVirtualCompletionMixin.java diff --git a/build/generated/sources/modMetadata/META-INF/neoforge.mods.toml b/build/generated/sources/modMetadata/META-INF/neoforge.mods.toml index 4eba2b3..85db319 100644 --- a/build/generated/sources/modMetadata/META-INF/neoforge.mods.toml +++ b/build/generated/sources/modMetadata/META-INF/neoforge.mods.toml @@ -5,30 +5,24 @@ # Find more information on toml format here: https://github.com/toml-lang/toml # The name of the mod loader type to load - for regular FML @Mod mods it should be javafml -modLoader="javafml" #mandatory +modLoader = "javafml" #mandatory # A version range to match for said mod loader - for regular FML @Mod it will be the FML version. This is currently 2. -loaderVersion="[1,)" #mandatory +loaderVersion = "[1,)" #mandatory # The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties. # Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here. -license="All Rights Reserved" +license = "LGPL-3.0-or-later" # A URL to refer people to when problems occur with this mod -#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional # A list of mods - how many allowed here is determined by the individual mod loader -[[mods]] #mandatory - -# The modid of the mod -modId="extendedae_plus" #mandatory - -# The version number of the mod -version="1.21.1-1.4.3" #mandatory - -# A display name for the mod -displayName="ExtendedAE-Plus" #mandatory - +[[mods]] +modId = "extendedae_plus" +version = "1.21.1-1.4.3" +displayName = "ExtendedAE-Plus" +issueTrackerURL = "https://github.com/GaLicn/ExtendedAE_Plus/issues" +displayURL = "https://github.com/GaLicn/ExtendedAE_Plus" # A URL to query for updates for this mod. See the JSON update specification https://docs.neoforged.net/docs/misc/updatechecker/ #updateJSONURL="https://change.me.example.invalid/updates.json" #optional @@ -42,15 +36,14 @@ displayName="ExtendedAE-Plus" #mandatory #credits="" #optional # A text field displayed in the mod UI -authors="YourNameHere, OtherNameHere" #optional +authors = "GaLi, C-H716" #optional # The description text for the mod (multi line!) (#mandatory) -description='''Example mod description. -Newline characters can be used and will be replaced properly.''' +description = '''Add more practical features and auxiliary operations to the Applied Energistics 2 mod''' # The [[mixins]] block allows you to declare your mixin config to FML so that it gets loaded. [[mixins]] -config="extendedae_plus.mixins.json" +config = "extendedae_plus.mixins.json" # The [[accessTransformers]] block allows you to declare where your AT file is. # If this block is omitted, a fallback attempt will be made to load an AT from META-INF/accesstransformer.cfg @@ -61,40 +54,40 @@ config="extendedae_plus.mixins.json" # A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. [[dependencies.extendedae_plus]] #optional - # the modid of the dependency - modId="neoforge" #mandatory - # The type of the dependency. Can be one of "required", "optional", "incompatible" or "discouraged" (case insensitive). - # 'required' requires the mod to exist, 'optional' does not - # 'incompatible' will prevent the game from loading when the mod exists, and 'discouraged' will show a warning - type="required" #mandatory - # Optional field describing why the dependency is required or why it is incompatible - # reason="..." - # The version range of the dependency - versionRange="[21.1.1,)" #mandatory - # An ordering relationship for the dependency. - # BEFORE - This mod is loaded BEFORE the dependency - # AFTER - This mod is loaded AFTER the dependency - ordering="NONE" - # Side this dependency is applied on - BOTH, CLIENT, or SERVER - side="BOTH" +# the modid of the dependency +modId = "neoforge" #mandatory +# The type of the dependency. Can be one of "required", "optional", "incompatible" or "discouraged" (case insensitive). +# 'required' requires the mod to exist, 'optional' does not +# 'incompatible' will prevent the game from loading when the mod exists, and 'discouraged' will show a warning +type = "required" #mandatory +# Optional field describing why the dependency is required or why it is incompatible +# reason="..." +# The version range of the dependency +versionRange = "[21.1.1,)" #mandatory +# An ordering relationship for the dependency. +# BEFORE - This mod is loaded BEFORE the dependency +# AFTER - This mod is loaded AFTER the dependency +ordering = "NONE" +# Side this dependency is applied on - BOTH, CLIENT, or SERVER +side = "BOTH" # Here's another dependency [[dependencies.extendedae_plus]] - modId="minecraft" - type="required" - # This version range declares a minimum of the current minecraft version up to but not including the next major version - versionRange="[1.21.1]" - ordering="NONE" - side="BOTH" +modId = "minecraft" +type = "required" +# This version range declares a minimum of the current minecraft version up to but not including the next major version +versionRange = "[1.21.1]" +ordering = "NONE" +side = "BOTH" # Require ExtendedAE (ExtendedAE-1.21-2.2.21-neoforge) to be present [[dependencies.extendedae_plus]] - modId="extendedae" - type="required" - # Use a permissive range to tolerate upstream version string variations (e.g. 1.21-2.2.21-neoforge) - versionRange="*" - ordering="AFTER" - side="BOTH" +modId = "extendedae" +type = "required" +# Use a permissive range to tolerate upstream version string variations (e.g. 1.21-2.2.21-neoforge) +versionRange = "*" +ordering = "AFTER" +side = "BOTH" # Features are specific properties of the game environment, that you may want to declare you require. This example declares # that your mod requires GL version 3.2 or higher. Other features will be added. They are side aware so declaring this won't diff --git a/src/main/java/com/extendedae_plus/compat/PatternProviderLogicVirtualCompatBridge.java b/src/main/java/com/extendedae_plus/compat/PatternProviderLogicVirtualCompatBridge.java new file mode 100644 index 0000000..718bd31 --- /dev/null +++ b/src/main/java/com/extendedae_plus/compat/PatternProviderLogicVirtualCompatBridge.java @@ -0,0 +1,9 @@ +package com.extendedae_plus.compat; + +import appeng.api.networking.IManagedGridNode; + +public interface PatternProviderLogicVirtualCompatBridge { + boolean eap$compatIsVirtualCraftingEnabled(); + + IManagedGridNode eap$compatGetMainNode(); +} diff --git a/src/main/java/com/extendedae_plus/mixin/ExtendedAEPlusMixinPlugin.java b/src/main/java/com/extendedae_plus/mixin/ExtendedAEPlusMixinPlugin.java index aefb88e..69a5024 100644 --- a/src/main/java/com/extendedae_plus/mixin/ExtendedAEPlusMixinPlugin.java +++ b/src/main/java/com/extendedae_plus/mixin/ExtendedAEPlusMixinPlugin.java @@ -8,16 +8,24 @@ import java.util.List; import java.util.Set; public class ExtendedAEPlusMixinPlugin implements IMixinConfigPlugin { - private static boolean isJeiPresent() { + private static boolean isClassPresent(String className) { try { ClassLoader cl = Thread.currentThread().getContextClassLoader(); - Class.forName("mezz.jei.api.IModPlugin", false, cl); + Class.forName(className, false, cl); return true; } catch (Throwable ignored) { return false; } } + private static boolean isJeiPresent() { + return isClassPresent("mezz.jei.api.IModPlugin"); + } + + private static boolean isAdvancedAePresent() { + return isClassPresent("net.pedroksl.advanced_ae.AdvancedAE"); + } + @Override public void onLoad(String mixinPackage) { } @@ -31,18 +39,23 @@ public class ExtendedAEPlusMixinPlugin implements IMixinConfigPlugin { if (mixinClassName.startsWith("com.extendedae_plus.mixin.jei")) return false; if (mixinClassName.equals("com.extendedae_plus.mixin.ae2.menu.CraftConfirmMenuGoBackMixin")) return false; } + if (!isAdvancedAePresent()) { + if (mixinClassName.equals("com.extendedae_plus.mixin.advancedae.compat.PatternProviderLogicVirtualCompletionMixin")) { + return false; + } + } return true; } @Override - public void acceptTargets(Set myTargets, Set otherTargets) { } + public void acceptTargets(Set myTargets, Set otherTargets) {} @Override - public List getMixins() { return null; } + public List getMixins() {return null;} @Override public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { } @Override public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { } -} \ No newline at end of file +} \ No newline at end of file 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 new file mode 100644 index 0000000..c8b5d76 --- /dev/null +++ b/src/main/java/com/extendedae_plus/mixin/advancedae/compat/PatternProviderLogicVirtualCompletionMixin.java @@ -0,0 +1,98 @@ +package com.extendedae_plus.mixin.advancedae.compat; + +import appeng.api.crafting.IPatternDetails; +import appeng.api.networking.crafting.ICraftingCPU; +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.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.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +/** + * AdvancedAE 版本的虚拟完成兼容逻辑。 + */ +@Mixin(value = PatternProviderLogic.class, priority = 850, remap = false) +public abstract class PatternProviderLogicVirtualCompletionMixin { + + @Inject(method = "pushPattern", at = @At("RETURN")) + private void eap$advancedaeVirtualCompletion(IPatternDetails patternDetails, KeyCounter[] inputHolder, + CallbackInfoReturnable cir) { + if (!cir.getReturnValueZ()) { + return; + } + if (!(this instanceof PatternProviderLogicVirtualCompatBridge bridge)) { + return; + } + if (!bridge.eap$compatIsVirtualCraftingEnabled()) { + return; + } + + var mainNode = bridge.eap$compatGetMainNode(); + if (mainNode == null) { + return; + } + + var node = mainNode.getNode(); + if (node == null) { + return; + } + + var grid = node.getGrid(); + if (grid == null) { + return; + } + + ICraftingService craftingService = grid.getCraftingService(); + if (craftingService == null) { + return; + } + + for (ICraftingCPU cpu : craftingService.getCpus()) { + if (!cpu.isBusy()) { + continue; + } + + if (cpu instanceof AdvCraftingCPU advCpu) { + var logic = advCpu.craftingLogic; + if (logic instanceof AdvCraftingCPULogicAccessor advLogicAccessor) { + var job = advLogicAccessor.eap$getAdvJob(); + if (job != null && job instanceof AdvExecutingCraftingJobAccessor advJobAccessor) { + var tasks = advJobAccessor.eap$getAdvTasks(); + var progress = tasks.get(patternDetails); + if (progress == null && patternDetails != null) { + var patternDefinition = patternDetails.getDefinition(); + for (var entry : tasks.entrySet()) { + var taskPattern = entry.getKey(); + if (taskPattern == patternDetails) { + progress = entry.getValue(); + break; + } + if (taskPattern != null && patternDefinition != null) { + var taskDefinition = taskPattern.getDefinition(); + if (taskDefinition != null && taskDefinition.equals(patternDefinition)) { + progress = entry.getValue(); + break; + } + } + } + } + + if (progress instanceof AdvExecutingCraftingJobTaskProgressAccessor advProgressAccessor) { + if (advProgressAccessor.eap$getAdvValue() <= 1) { + advCpu.cancelJob(); + break; + } + } + } + } + } + } + } +} 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 d9a55bb..4f07dc6 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 @@ -16,19 +16,16 @@ import com.extendedae_plus.ae.wireless.WirelessSlaveLink; import com.extendedae_plus.ae.wireless.endpoint.GenericNodeEndpointImpl; import com.extendedae_plus.api.bridge.CompatUpgradeProvider; import com.extendedae_plus.api.bridge.InterfaceWirelessLinkBridge; +import com.extendedae_plus.compat.PatternProviderLogicVirtualCompatBridge; import com.extendedae_plus.compat.UpgradeSlotCompat; import com.extendedae_plus.init.ModItems; import com.extendedae_plus.items.materials.ChannelCardItem; -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 com.extendedae_plus.mixin.ae2.accessor.CraftingCpuLogicAccessor; import com.extendedae_plus.mixin.ae2.accessor.ExecutingCraftingJobAccessor; import com.extendedae_plus.util.ExtendedAELogger; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; -import net.pedroksl.advanced_ae.common.cluster.AdvCraftingCPU; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -47,7 +44,7 @@ import java.util.List; * - 建立到无线主站的网格连接。 */ @Mixin(value = PatternProviderLogic.class, priority = 900, remap = false) -public abstract class PatternProviderLogicCompatMixin implements CompatUpgradeProvider, InterfaceWirelessLinkBridge { +public abstract class PatternProviderLogicCompatMixin implements CompatUpgradeProvider, InterfaceWirelessLinkBridge, PatternProviderLogicVirtualCompatBridge { @Unique private IUpgradeInventory eap$compatUpgrades = UpgradeInventories.empty(); @@ -486,7 +483,6 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr } } - @Unique private void eap$compatTryVirtualCompletion(IPatternDetails patternDetails) { if (!this.eap$compatVirtualCraftingEnabled) { @@ -542,45 +538,20 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr } } } - continue; - } - if (cpu instanceof AdvCraftingCPU advCpu) { - var logic = advCpu.craftingLogic; - if (logic instanceof AdvCraftingCPULogicAccessor advLogicAccessor) { - var job = advLogicAccessor.eap$getAdvJob(); - if (job != null && job instanceof AdvExecutingCraftingJobAccessor advJobAccessor) { - var tasks = advJobAccessor.eap$getAdvTasks(); - var progress = tasks.get(patternDetails); - if (progress == null && patternDetails != null) { - var patternDefinition = patternDetails.getDefinition(); - for (var entry : tasks.entrySet()) { - var taskPattern = entry.getKey(); - if (taskPattern == patternDetails) { - progress = entry.getValue(); - break; - } - if (taskPattern != null && patternDefinition != null) { - var taskDefinition = taskPattern.getDefinition(); - if (taskDefinition != null && taskDefinition.equals(patternDefinition)) { - progress = entry.getValue(); - break; - } - } - } - } - - if (progress instanceof AdvExecutingCraftingJobTaskProgressAccessor advProgressAccessor) { - if (advProgressAccessor.eap$getAdvValue() <= 1) { - advCpu.cancelJob(); - break; - } - } - } - } } } } + @Override + public boolean eap$compatIsVirtualCraftingEnabled() { + return this.eap$compatVirtualCraftingEnabled; + } + + @Override + public IManagedGridNode eap$compatGetMainNode() { + return this.mainNode; + } + @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 733ca40..f8ddb72 100644 --- a/src/main/resources/extendedae_plus.mixins.json +++ b/src/main/resources/extendedae_plus.mixins.json @@ -5,11 +5,12 @@ "plugin": "com.extendedae_plus.mixin.ExtendedAEPlusMixinPlugin", "mixins": [ "advancedae.AdvPatternProviderLogicContainsRedirectMixin", - "advancedae.accessor.AdvPatternProviderLogicPatternsAccessor", - "advancedae.accessor.AdvPatternProviderMenuAdvancedAccessor", "advancedae.accessor.AdvCraftingCPULogicAccessor", "advancedae.accessor.AdvExecutingCraftingJobAccessor", "advancedae.accessor.AdvExecutingCraftingJobTaskProgressAccessor", + "advancedae.accessor.AdvPatternProviderLogicPatternsAccessor", + "advancedae.accessor.AdvPatternProviderMenuAdvancedAccessor", + "advancedae.compat.PatternProviderLogicVirtualCompletionMixin", "advancedae.helpers.AdvPatternProviderLogicAdvancedMixin", "advancedae.helpers.AdvPatternProviderLogicDoublingMixin", "advancedae.menu.AdvPatternProviderMenuAdvancedMixin", @@ -17,12 +18,12 @@ "ae2.CraftingCalculationMixin", "ae2.CraftingCPUClusterMixin", "ae2.EncodedPatternItemMixin", - "ae2.accessor.MEStorageMenuAccessor", - "ae2.accessor.PatternEncodingTermMenuAccessor", - "ae2.accessor.PatternProviderLogicAccessor", "ae2.accessor.CraftingCpuLogicAccessor", "ae2.accessor.ExecutingCraftingJobAccessor", "ae2.accessor.ExecutingCraftingJobTaskProgressAccessor", + "ae2.accessor.MEStorageMenuAccessor", + "ae2.accessor.PatternEncodingTermMenuAccessor", + "ae2.accessor.PatternProviderLogicAccessor", "ae2.accessor.PatternProviderLogicPatternInputsAccessor", "ae2.accessor.PatternProviderLogicPatternsAccessor", "ae2.accessor.PatternProviderMenuAdvancedAccessor", @@ -39,16 +40,16 @@ "ae2.helpers.PatternProviderLogicDoublingMixin", "ae2.helpers.PatternProviderLogicUpgradesMixin", "ae2.helpers.patternprovider.PatternProviderLogicTickerMixin", - "ae2.menu.InterfaceMenuUpgradesMixin", "ae2.menu.AEBaseMenuUpgradesDedupMixin", - "ae2.menu.PatternProviderMenuUpgradesMixin", - "ae2.parts.automation.IOBusPartChannelCardMixin", - "ae2.parts.storagebus.StorageBusPartChannelCardMixin", "ae2.menu.ContainerPatternEncodingTermMenuMixin", + "ae2.menu.InterfaceMenuUpgradesMixin", "ae2.menu.MEStorageMenuMixin", "ae2.menu.PatternEncodingTermMenuMixin", "ae2.menu.PatternProviderMenuAdvancedMixin", "ae2.menu.PatternProviderMenuDoublingMixin", + "ae2.menu.PatternProviderMenuUpgradesMixin", + "ae2.parts.automation.IOBusPartChannelCardMixin", + "ae2.parts.storagebus.StorageBusPartChannelCardMixin", "ae2WTlib.ContainerUWirelessExPatternTerminalMixin", "extendedae.common.PartExPatternProviderMixin", "extendedae.common.TileExPatternProviderMixin",