diff --git a/build.gradle b/build.gradle index f22d7c4..25fe6a4 100644 --- a/build.gradle +++ b/build.gradle @@ -81,7 +81,7 @@ dependencies { annotationProcessor "org.spongepowered:mixin:${mixin_version}:processor" - // modImplementation "curse.maven:applied-flux-965012:6755986" + modImplementation "curse.maven:applied-flux-965012:6755986" modCompileOnly "curse.maven:mega-cells-622112:${mega_cells_version}" modCompileOnly "curse.maven:jade-324717:${jade_version}" diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/InterfaceLogicUpgradesMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/InterfaceLogicUpgradesMixin.java new file mode 100644 index 0000000..0bc4575 --- /dev/null +++ b/src/main/java/com/extendedae_plus/mixin/ae2/InterfaceLogicUpgradesMixin.java @@ -0,0 +1,80 @@ +package com.extendedae_plus.mixin.ae2; + +import appeng.api.networking.IManagedGridNode; +import appeng.api.upgrades.IUpgradeInventory; +import appeng.api.upgrades.UpgradeInventories; +import appeng.helpers.InterfaceLogic; +import appeng.helpers.InterfaceLogicHost; +import com.extendedae_plus.compat.UpgradeSlotCompat; +import net.minecraft.world.item.Item; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +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; + +/** + * 为ME接口增加升级槽数量的Mixin + * 兼容Applied Flux模组,避免冲突 + */ +@Mixin(value = InterfaceLogic.class, remap = false, priority = 1500) +public class InterfaceLogicUpgradesMixin { + + @Final + @Mutable + @Shadow + private IUpgradeInventory upgrades; + + @Shadow + protected void onUpgradesChanged() {} + + /** + * 在InterfaceLogic构造函数末尾注入,增加升级槽数量 + * 使用高优先级(1500)确保在Applied Flux之后执行 + */ + @Inject( + method = "(Lappeng/api/networking/IManagedGridNode;Lappeng/helpers/InterfaceLogicHost;Lnet/minecraft/world/item/Item;I)V", + at = @At("TAIL") + ) + private void expandInterfaceUpgrades(IManagedGridNode gridNode, InterfaceLogicHost host, Item is, int slots, CallbackInfo ci) { + try { + System.out.println("[ExtendedAE_Plus] InterfaceLogic升级槽扩展开始"); + + // 检查Applied Flux是否已经修改了升级槽 + if (UpgradeSlotCompat.isAppfluxPresent()) { + System.out.println("[ExtendedAE_Plus] 检测到Applied Flux存在"); + // Applied Flux存在,检查当前升级槽数量 + int currentSlots = this.upgrades.size(); + System.out.println("[ExtendedAE_Plus] 当前升级槽数量: " + currentSlots); + + if (currentSlots >= 3) { + // Applied Flux已经增加了升级槽到3个或更多,我们不需要再修改 + System.out.println("[ExtendedAE_Plus] Applied Flux已经增加了足够的升级槽,跳过修改"); + return; + } else if (currentSlots == 2) { + // Applied Flux增加到2个,我们再增加1个到3个 + System.out.println("[ExtendedAE_Plus] Applied Flux增加到2个槽,我们再增加到3个"); + this.upgrades = UpgradeInventories.forMachine(is, 3, this::onUpgradesChanged); + } else { + // Applied Flux可能还没有生效,我们直接增加到3个 + System.out.println("[ExtendedAE_Plus] Applied Flux可能未生效,直接增加到3个槽"); + this.upgrades = UpgradeInventories.forMachine(is, 3, this::onUpgradesChanged); + } + } else { + System.out.println("[ExtendedAE_Plus] Applied Flux不存在"); + // Applied Flux不存在,我们将升级槽从1个增加到2个 + int currentSlots = this.upgrades.size(); + System.out.println("[ExtendedAE_Plus] 当前升级槽数量: " + currentSlots + ",增加到2个"); + this.upgrades = UpgradeInventories.forMachine(is, 2, this::onUpgradesChanged); + } + + System.out.println("[ExtendedAE_Plus] InterfaceLogic升级槽扩展完成,最终槽数: " + this.upgrades.size()); + } catch (Exception e) { + // 发生异常时不修改升级槽,确保不会崩溃 + System.err.println("[ExtendedAE_Plus] Failed to expand interface upgrades: " + e.getMessage()); + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/patternprovider/PatternProviderLogicHostUpgradesMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/patternprovider/PatternProviderLogicHostUpgradesMixin.java deleted file mode 100644 index 47f27dc..0000000 --- a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/patternprovider/PatternProviderLogicHostUpgradesMixin.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.extendedae_plus.mixin.ae2.helpers.patternprovider; - -import appeng.api.upgrades.IUpgradeInventory; -import appeng.api.upgrades.IUpgradeableObject; -import appeng.helpers.patternprovider.PatternProviderLogic; -import appeng.helpers.patternprovider.PatternProviderLogicHost; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -/** - * 让 PatternProviderLogicHost 作为 IUpgradeableObject 的代理,菜单可从 host 获取升级槽。 - */ -@Mixin(value = PatternProviderLogicHost.class, priority = 2000, remap = false) -public interface PatternProviderLogicHostUpgradesMixin extends IUpgradeableObject { - @Shadow PatternProviderLogic getLogic(); - - @Override - default IUpgradeInventory getUpgrades() { - if (!com.extendedae_plus.compat.UpgradeSlotCompat.shouldEnableUpgradeSlots()) { - return appeng.api.upgrades.UpgradeInventories.empty(); - } - return ((IUpgradeableObject) this.getLogic()).getUpgrades(); - } -} diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/patternprovider/PatternProviderLogicUpgradesMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/patternprovider/PatternProviderLogicUpgradesMixin.java deleted file mode 100644 index 59f06c9..0000000 --- a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/patternprovider/PatternProviderLogicUpgradesMixin.java +++ /dev/null @@ -1,272 +0,0 @@ -package com.extendedae_plus.mixin.ae2.helpers.patternprovider; - -import appeng.api.networking.IManagedGridNode; -import appeng.api.networking.security.IActionSource; -import appeng.api.upgrades.IUpgradeInventory; -import appeng.api.upgrades.IUpgradeableObject; -import appeng.api.upgrades.UpgradeInventories; -import appeng.helpers.patternprovider.PatternProviderLogic; -import appeng.helpers.patternprovider.PatternProviderLogicHost; -import com.extendedae_plus.ae.items.ChannelCardItem; -import com.extendedae_plus.compat.UpgradeSlotCompat; -import com.extendedae_plus.init.ModItems; -import com.extendedae_plus.wireless.WirelessSlaveLink; -import com.extendedae_plus.wireless.endpoint.GenericNodeEndpointImpl; -import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -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 net.minecraft.nbt.CompoundTag; -import net.minecraft.world.item.ItemStack; - -import java.util.List; - -/** - * 为 PatternProviderLogic 注入升级槽,实现 IUpgradeableObject。 - * 仅负责升级槽的持久化/掉落/清空与初始化,不改变原有逻辑。 - */ -@Mixin(value = PatternProviderLogic.class, priority = 2000, remap = false) -public abstract class PatternProviderLogicUpgradesMixin implements IUpgradeableObject, InterfaceWirelessLinkBridge { - @Unique - private IUpgradeInventory eap$upgrades = UpgradeInventories.empty(); - - @Unique - private WirelessSlaveLink eap$link; - - @Unique - private long eap$lastChannel = -1; - - @Unique - private boolean eap$clientConnected = false; - - @Unique - private boolean eap$hasInitialized = false; - - @Unique - private int eap$delayedInitTicks = 0; - - @Final - @Shadow - private PatternProviderLogicHost host; - - @Final - @Shadow - private IManagedGridNode mainNode; - - @Final - @Shadow - private IActionSource actionSource; - - @Unique - private void eap$onUpgradesChanged() { - this.host.saveChanges(); - // 升级变更,重置并尝试初始化 - eap$lastChannel = -1; - eap$hasInitialized = false; - eap$initializeChannelLink(); - } - - - - @Inject(method = "(Lappeng/api/networking/IManagedGridNode;Lappeng/helpers/patternprovider/PatternProviderLogicHost;I)V", - at = @At("TAIL")) - private void eap$initUpgrades(IManagedGridNode mainNode, PatternProviderLogicHost host, int patternInventorySize, CallbackInfo ci) { - // 只有在应该启用升级卡槽时才初始化 - if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) { - return; - } - - this.eap$upgrades = UpgradeInventories.forMachine(host.getTerminalIcon().getItem(), 1, this::eap$onUpgradesChanged); - } - - @Inject(method = "writeToNBT", at = @At("TAIL")) - private void eap$saveUpgrades(CompoundTag tag, CallbackInfo ci) { - if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) { - return; - } - this.eap$upgrades.writeToNBT(tag, "upgrades"); - } - - @Inject(method = "readFromNBT", at = @At("TAIL")) - private void eap$loadUpgrades(CompoundTag tag, CallbackInfo ci) { - if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) { - return; - } - this.eap$upgrades.readFromNBT(tag, "upgrades"); - // 从 NBT 加载后,重置并尝试初始化(可能刚进入世界) - eap$lastChannel = -1; - eap$hasInitialized = false; - eap$initializeChannelLink(); - } - - @Inject(method = "addDrops", at = @At("TAIL")) - private void eap$dropUpgrades(List drops, CallbackInfo ci) { - if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) { - return; - } - for (var stack : this.eap$upgrades) { - if (!stack.isEmpty()) { - drops.add(stack); - } - } - } - - @Inject(method = "clearContent", at = @At("TAIL")) - private void eap$clearUpgrades(CallbackInfo ci) { - if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) { - return; - } - this.eap$upgrades.clear(); - } - - @Override - public void eap$updateWirelessLink() { - if (eap$link != null) { - eap$link.updateStatus(); - } - } - - @Override - public IUpgradeInventory getUpgrades() { - if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) { - return UpgradeInventories.empty(); - } - return this.eap$upgrades; - } - - // ===== 频道卡初始化与延迟重试(服务端) ===== - @Unique - public void eap$initializeChannelLink() { - // 客户端早退 - if (host.getBlockEntity() != null && host.getBlockEntity().getLevel() != null && host.getBlockEntity().getLevel().isClientSide) { - return; - } - - // 避免重复初始化 - if (eap$hasInitialized) { - return; - } - - // 等待网格完成引导 - if (!mainNode.hasGridBooted()) { - // 安排短延迟,等待后续 tick 再试 - eap$delayedInitTicks = Math.max(eap$delayedInitTicks, 5); - try { - mainNode.ifPresent((grid, node) -> { - try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {} - }); - } catch (Throwable ignored) {} - return; - } - - try { - long channel = 0L; - boolean found = false; - for (ItemStack stack : this.eap$upgrades) { - if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) { - channel = ChannelCardItem.getChannel(stack); - found = true; - break; - } - } - - if (!found) { - // 无频道卡:断开并视为初始化完成 - if (eap$link != null) { - eap$link.setFrequency(0L); - eap$link.updateStatus(); - } - eap$hasInitialized = true; - return; - } - - if (eap$link == null) { - var endpoint = new GenericNodeEndpointImpl(() -> host.getBlockEntity(), () -> this.mainNode.getNode()); - eap$link = new WirelessSlaveLink(endpoint); - } - - eap$link.setFrequency(channel); - eap$link.updateStatus(); - - if (eap$link.isConnected()) { - eap$hasInitialized = true; - } else { - eap$hasInitialized = false; - eap$delayedInitTicks = Math.max(eap$delayedInitTicks, 5); - try { - mainNode.ifPresent((grid, node) -> { - try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {} - }); - } catch (Throwable ignored) {} - } - } catch (Exception ignored) { - } - } - - @Override - public void eap$setClientWirelessState(boolean connected) { - eap$clientConnected = connected; - } - - @Override - public boolean eap$isWirelessConnected() { - if (host.getBlockEntity() != null && host.getBlockEntity().getLevel() != null && host.getBlockEntity().getLevel().isClientSide) { - return eap$clientConnected; - } else { - return eap$link != null && eap$link.isConnected(); - } - } - - @Override - public boolean eap$hasTickInitialized() { - return eap$hasInitialized; - } - - @Override - public void eap$setTickInitialized(boolean initialized) { - eap$hasInitialized = initialized; - } - - @Override - public void eap$handleDelayedInit() { - // 仅服务端 - if (host.getBlockEntity() != null && host.getBlockEntity().getLevel() != null && host.getBlockEntity().getLevel().isClientSide) { - return; - } - if (!eap$hasInitialized) { - if (!mainNode.hasGridBooted()) { - if (eap$delayedInitTicks > 0) { - eap$delayedInitTicks--; - } - if (eap$delayedInitTicks == 0) { - eap$delayedInitTicks = 5; - try { - mainNode.ifPresent((grid, node) -> { - try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {} - }); - } catch (Throwable ignored) {} - } - } else { - eap$initializeChannelLink(); - } - } - } - - // 当主节点状态变化(例如 GRID_BOOT 完成)时,安排一次延迟初始化并唤醒设备 - @Inject(method = "onMainNodeStateChanged", at = @At("TAIL")) - private void eap$onMainNodeStateChangedTail(CallbackInfo ci) { - eap$lastChannel = -1; - eap$hasInitialized = false; - eap$delayedInitTicks = 10; - try { - mainNode.ifPresent((grid, node) -> { - try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {} - }); - } catch (Throwable ignored) {} - } -} diff --git a/src/main/java/com/extendedae_plus/mixin/appflux/AppfluxPatternProviderLogicMixin.java b/src/main/java/com/extendedae_plus/mixin/appflux/AppfluxPatternProviderLogicMixin.java new file mode 100644 index 0000000..201121e --- /dev/null +++ b/src/main/java/com/extendedae_plus/mixin/appflux/AppfluxPatternProviderLogicMixin.java @@ -0,0 +1,79 @@ +package com.extendedae_plus.mixin.appflux; + +import appeng.api.networking.IManagedGridNode; +import appeng.api.upgrades.IUpgradeInventory; +import appeng.api.upgrades.UpgradeInventories; +import appeng.helpers.patternprovider.PatternProviderLogic; +import appeng.helpers.patternprovider.PatternProviderLogicHost; +import com.extendedae_plus.compat.UpgradeSlotCompat; +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 java.lang.reflect.Field; + +/** + * 当appflux存在时,修改PatternProviderLogic的升级槽数量为2个 + * 优先级设置为2000,确保在appflux之后应用 + */ +@Mixin(value = PatternProviderLogic.class, priority = 2000, remap = false) +public class AppfluxPatternProviderLogicMixin { + + /** + * 在appflux初始化升级槽之后,替换为2个槽的版本 + */ + @Inject(method = "(Lappeng/api/networking/IManagedGridNode;Lappeng/helpers/patternprovider/PatternProviderLogicHost;I)V", + at = @At("TAIL")) + private void eap$modifyAppfluxUpgradeSlots(IManagedGridNode mainNode, PatternProviderLogicHost host, int patternInventorySize, CallbackInfo ci) { + try { + com.extendedae_plus.util.ExtendedAELogger.LOGGER.info("AppfluxPatternProviderLogicMixin被调用!"); + + // 只有当appflux存在且不启用我们的升级槽时才修改数量 + if (!UpgradeSlotCompat.shouldEnableUpgradeSlots() && UpgradeSlotCompat.shouldEnableChannelCard()) { + com.extendedae_plus.util.ExtendedAELogger.LOGGER.info("尝试修改appflux升级槽数量为2个"); + + // 使用反射找到appflux的升级槽字段并替换 + try { + Field upgradesField = this.getClass().getDeclaredField("af_$upgrades"); + upgradesField.setAccessible(true); + IUpgradeInventory currentUpgrades = (IUpgradeInventory) upgradesField.get(this); + + if (currentUpgrades != null) { + com.extendedae_plus.util.ExtendedAELogger.LOGGER.info("找到appflux升级槽,当前大小: {}", currentUpgrades.size()); + + // 创建新的2槽升级槽 + IUpgradeInventory newUpgrades = UpgradeInventories.forMachine( + host.getTerminalIcon().getItem(), + 2, + () -> { + try { + // 调用appflux的升级变更方法 + this.getClass().getDeclaredMethod("af_$onUpgradesChanged").invoke(this); + } catch (Exception e) { + com.extendedae_plus.util.ExtendedAELogger.LOGGER.error("调用appflux升级变更方法失败", e); + } + } + ); + + // 复制原有升级卡到新的升级槽 + for (int i = 0; i < Math.min(currentUpgrades.size(), newUpgrades.size()); i++) { + if (!currentUpgrades.getStackInSlot(i).isEmpty()) { + newUpgrades.insertItem(i, currentUpgrades.getStackInSlot(i).copy(), false); + } + } + + // 替换升级槽 + upgradesField.set(this, newUpgrades); + com.extendedae_plus.util.ExtendedAELogger.LOGGER.info("成功将appflux升级槽替换为2个槽"); + } + } catch (Exception e) { + com.extendedae_plus.util.ExtendedAELogger.LOGGER.error("反射修改appflux升级槽失败", e); + } + } + } catch (Exception e) { + com.extendedae_plus.util.ExtendedAELogger.LOGGER.error("AppfluxPatternProviderLogicMixin执行失败", e); + } + } +}