From fa57542f3c3a45e99f86c60a82919ab6ac101157 Mon Sep 17 00:00:00 2001 From: GaLicn <133291877+GaLicn@users.noreply.github.com> Date: Tue, 23 Sep 2025 20:35:54 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mixin/ae2/client/gui/InterfaceScreenMixin.java | 2 +- .../mixin/extendedae/client/gui/GuiExPatternProviderMixin.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/InterfaceScreenMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/InterfaceScreenMixin.java index 0c6f828..e5528e0 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/InterfaceScreenMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/InterfaceScreenMixin.java @@ -261,7 +261,7 @@ public abstract class InterfaceScreenMixin { int imageWidth = ((AbstractContainerScreenAccessor) (Object) this).eap$getImageWidth(); // 按照样板供应器界面一致的布局:界面右缘外侧竖排 int bx = leftPos + imageWidth + 1; - int by = topPos + 20; + int by = topPos + 70; // 向下偏移25px (从20改为45) int spacing = 22; if (eap$divideBy2Button != null) { eap$divideBy2Button.setX(bx); eap$divideBy2Button.setY(by); } if (eap$x2Button != null) { eap$x2Button.setX(bx); eap$x2Button.setY(by + spacing); } diff --git a/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java b/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java index f101fda..e9b1727 100644 --- a/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java @@ -328,7 +328,7 @@ public abstract class GuiExPatternProviderMixin extends PatternProviderScreen Date: Wed, 24 Sep 2025 11:53:46 +0800 Subject: [PATCH 2/6] changelog --- CHANGELOG.md | 19 +++++++++++++++++++ build.gradle | 2 +- gradle.properties | 2 +- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0176c3e..28f0d04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,25 @@ ## [Unreleased] +## [1.4.3] +### ⚠️ 重要提醒 / Important Notice +- **更新会导致旧版的无限盘失效,如有需要请先导盘再更新** + - **Updating will invalidate old infinite disks. Please export data before updating if needed.** + +### Added / 新增 +- 装配矩阵上传核心 - 现在必须在装配矩阵中添加该核心才能正常使用自动上传合成样板功能 + - Assembly Matrix Upload Core - now required in Assembly Matrix to use automatic pattern upload functionality. +- 频道卡 - 手持频道卡右键可调整频率,将频道卡放入AE设备将自动连接上同频率的本模组的无线收发器 + - Channel Card - right-click while holding to adjust frequency, placing in AE devices automatically connects to same-frequency wireless transceivers. + +### Fixed / 修复 +- 修复合成计划中添加缺失物品时,流体、MEK化学品出现错误书签 + - Fixed incorrect bookmarks for fluids and Mekanism chemicals when adding missing items in crafting plan. +- 修复吞噬万籁的寂静的重大bug + - Fixed critical bug in Devourer of Cosmic Silence. +- 修复JEI模组不存在时导致的崩溃问题 + - Fixed crash when JEI mod is not present. + ## [1.4.2] ### Added / 新增 - 添加实体加速器,最高可加速 1024 倍(配置文件可配置能耗、黑名单、额外消耗倍率名单) diff --git a/build.gradle b/build.gradle index 4b8c05f..22f3dca 100644 --- a/build.gradle +++ b/build.gradle @@ -106,7 +106,7 @@ dependencies { //mae2 - modRuntimeOnly "curse.maven:modern-ae2-additions-1028068:6827727" + // modRuntimeOnly "curse.maven:modern-ae2-additions-1028068:6827727" modCompileOnly "curse.maven:modern-ae2-additions-1028068:6827727" //aea diff --git a/gradle.properties b/gradle.properties index d673cb8..ba9b599 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx1G loom.platform = forge # Mod properties -mod_version = 1.4.3-beta +mod_version = 1.4.3 maven_group = com.extendedae_plus archives_name = extendedae_plus From 7bd15e7d13d41c77bbee735d95f222415d48e702 Mon Sep 17 00:00:00 2001 From: GaLicn <133291877+GaLicn@users.noreply.github.com> Date: Wed, 24 Sep 2025 12:09:17 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E5=88=A0=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../extendedae_plus/compat/CompatibilityTest.java | 7 ------- .../extendedae_plus/compat/UpgradeSlotCompat.java | 3 --- .../mixin/ae2/QuartzCuttingKnifeItemMixin.java | 1 - .../mixin/ae2/client/gui/AEBaseScreenMixin.java | 8 -------- .../mixin/ae2/client/gui/InterfaceScreenMixin.java | 12 ------------ .../ae2/compat/PatternProviderLogicCompatMixin.java | 7 ------- .../appflux/AppfluxPatternProviderLogicMixin.java | 4 ---- .../client/gui/GuiExPatternProviderMixin.java | 7 ++----- .../network/CraftingMonitorJumpC2SPacket.java | 13 ------------- 9 files changed, 2 insertions(+), 60 deletions(-) diff --git a/src/main/java/com/extendedae_plus/compat/CompatibilityTest.java b/src/main/java/com/extendedae_plus/compat/CompatibilityTest.java index 50b7687..30004e8 100644 --- a/src/main/java/com/extendedae_plus/compat/CompatibilityTest.java +++ b/src/main/java/com/extendedae_plus/compat/CompatibilityTest.java @@ -13,28 +13,21 @@ public class CompatibilityTest { * 测试模组兼容性检测 */ public static void testCompatibility() { - ExtendedAELogger.LOGGER.info("=== ExtendedAE_Plus 兼容性测试开始 ==="); // 测试appflux模组检测 boolean appfluxExists = ModList.get().isLoaded("appflux"); - ExtendedAELogger.LOGGER.info("ExtendedAE-appflux模组检测结果: {}", appfluxExists ? "存在" : "不存在"); // 测试升级卡槽功能启用状态 boolean shouldEnableUpgrades = UpgradeSlotCompat.shouldEnableUpgradeSlots(); - ExtendedAELogger.LOGGER.info("升级卡槽功能启用状态: {}", shouldEnableUpgrades ? "启用" : "禁用"); // 测试Screen升级面板添加状态 boolean shouldAddPanel = UpgradeSlotCompat.shouldAddUpgradePanelToScreen(); - ExtendedAELogger.LOGGER.info("Screen升级面板添加状态: {}", shouldAddPanel ? "启用" : "禁用"); // 输出兼容性策略 if (appfluxExists) { - ExtendedAELogger.LOGGER.info("兼容性策略: 检测到ExtendedAE-appflux模组,将使用其升级卡槽功能"); } else { - ExtendedAELogger.LOGGER.info("兼容性策略: 未检测到ExtendedAE-appflux模组,将使用我们自己的升级卡槽功能"); } - ExtendedAELogger.LOGGER.info("=== ExtendedAE_Plus 兼容性测试完成 ==="); } /** diff --git a/src/main/java/com/extendedae_plus/compat/UpgradeSlotCompat.java b/src/main/java/com/extendedae_plus/compat/UpgradeSlotCompat.java index 9768050..9aa03ff 100644 --- a/src/main/java/com/extendedae_plus/compat/UpgradeSlotCompat.java +++ b/src/main/java/com/extendedae_plus/compat/UpgradeSlotCompat.java @@ -41,13 +41,10 @@ public class UpgradeSlotCompat { */ public static boolean shouldEnableUpgradeSlots() { boolean appfluxExists = isAppfluxPresent(); - ExtendedAELogger.LOGGER.info("ExtendedAE-appflux模组检测: {}", appfluxExists ? "存在" : "不存在"); if (appfluxExists) { - ExtendedAELogger.LOGGER.info("检测到ExtendedAE-appflux模组,跳过我们的升级卡槽功能"); return false; } else { - ExtendedAELogger.LOGGER.info("未检测到ExtendedAE-appflux模组,启用我们的升级卡槽功能"); return true; } } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/QuartzCuttingKnifeItemMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/QuartzCuttingKnifeItemMixin.java index e8ddd97..420a3e6 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/QuartzCuttingKnifeItemMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/QuartzCuttingKnifeItemMixin.java @@ -196,7 +196,6 @@ public abstract class QuartzCuttingKnifeItemMixin { } } } catch (ClassNotFoundException e) { - LOGGER.info("GregTech CEu 类未找到,跳过配方翻译处理"); return null; // GTCEu 不可用 } catch (NoSuchFieldException | NoSuchMethodException | IllegalAccessException | java.lang.reflect.InvocationTargetException e) { LOGGER.error("处理 GTCEu 配方翻译失败: {}", e.getMessage()); diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/AEBaseScreenMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/AEBaseScreenMixin.java index 5f74500..f65d128 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/AEBaseScreenMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/AEBaseScreenMixin.java @@ -75,10 +75,6 @@ public abstract class AEBaseScreenMixin { if (key == null) { return; } - // Debug: 标记一次发送 - try { - LogUtils.getLogger().info("EAP: Send CraftingMonitorJumpC2SPacket: {}", key); - } catch (Throwable ignored2) {} ModNetwork.CHANNEL.sendToServer(new CraftingMonitorJumpC2SPacket(key)); cir.setReturnValue(true); } catch (Throwable ignored) { @@ -109,10 +105,6 @@ public abstract class AEBaseScreenMixin { if (key == null) { return; } - // Debug: 标记一次发送(打开供应器UI) - try { - LogUtils.getLogger().info("EAP: Send CraftingMonitorOpenProviderC2SPacket: {}", key); - } catch (Throwable ignored2) {} ModNetwork.CHANNEL.sendToServer(new CraftingMonitorOpenProviderC2SPacket(key)); cir.setReturnValue(true); } catch (Throwable ignored) { diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/InterfaceScreenMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/InterfaceScreenMixin.java index e5528e0..b03fabc 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/InterfaceScreenMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/InterfaceScreenMixin.java @@ -48,7 +48,6 @@ public abstract class InterfaceScreenMixin { if (!eap$isSupportedInterfaceScreen()) { return; } - try { LogUtils.getLogger().info("[EAP][InterfaceMixin] init tail reached, preparing scale buttons."); } catch (Throwable ignored) {} // 避免重复创建 if (eap$x2Button == null) { eap$x2Button = new ActionEPPButton((b) -> { @@ -110,7 +109,6 @@ public abstract class InterfaceScreenMixin { // 初次定位 eap$relayoutButtons(); - try { LogUtils.getLogger().info("[EAP][InterfaceMixin] buttons added and laid out."); } catch (Throwable ignored) {} } @Inject(method = "containerTick", at = @At("TAIL")) @@ -123,32 +121,26 @@ public abstract class InterfaceScreenMixin { if (eap$divideBy2Button != null && !accessor.eap$getRenderables().contains(eap$divideBy2Button)) { accessor.eap$getRenderables().add(eap$divideBy2Button); accessor.eap$getChildren().add(eap$divideBy2Button); - try { LogUtils.getLogger().info("[EAP][InterfaceMixin] re-added divide2 button to renderables."); } catch (Throwable ignored) {} } if (eap$x2Button != null && !accessor.eap$getRenderables().contains(eap$x2Button)) { accessor.eap$getRenderables().add(eap$x2Button); accessor.eap$getChildren().add(eap$x2Button); - try { LogUtils.getLogger().info("[EAP][InterfaceMixin] re-added x2 button to renderables."); } catch (Throwable ignored) {} } if (eap$divideBy5Button != null && !accessor.eap$getRenderables().contains(eap$divideBy5Button)) { accessor.eap$getRenderables().add(eap$divideBy5Button); accessor.eap$getChildren().add(eap$divideBy5Button); - try { LogUtils.getLogger().info("[EAP][InterfaceMixin] re-added divide5 button to renderables."); } catch (Throwable ignored) {} } if (eap$x5Button != null && !accessor.eap$getRenderables().contains(eap$x5Button)) { accessor.eap$getRenderables().add(eap$x5Button); accessor.eap$getChildren().add(eap$x5Button); - try { LogUtils.getLogger().info("[EAP][InterfaceMixin] re-added x5 button to renderables."); } catch (Throwable ignored) {} } if (eap$divideBy10Button != null && !accessor.eap$getRenderables().contains(eap$divideBy10Button)) { accessor.eap$getRenderables().add(eap$divideBy10Button); accessor.eap$getChildren().add(eap$divideBy10Button); - try { LogUtils.getLogger().info("[EAP][InterfaceMixin] re-added divide10 button to renderables."); } catch (Throwable ignored) {} } if (eap$x10Button != null && !accessor.eap$getRenderables().contains(eap$x10Button)) { accessor.eap$getRenderables().add(eap$x10Button); accessor.eap$getChildren().add(eap$x10Button); - try { LogUtils.getLogger().info("[EAP][InterfaceMixin] re-added x10 button to renderables."); } catch (Throwable ignored) {} } // 尺寸变化时重新定位 int curLeft = ((AbstractContainerScreenAccessor) (Object) this).eap$getLeftPos(); @@ -161,7 +153,6 @@ public abstract class InterfaceScreenMixin { eap$lastImageWidth = curImgW; eap$lastImageHeight = curImgH; eap$relayoutButtons(); - try { LogUtils.getLogger().info("[EAP][InterfaceMixin] relayout due to bounds change: left={}, top={}, w={}, h={}", curLeft, curTop, curImgW, curImgH); } catch (Throwable ignored) {} } // 每帧根据 hoveredSlot 刷新最近一次的配置槽索引 eap$updateLastConfigFromHover(); @@ -214,10 +205,8 @@ public abstract class InterfaceScreenMixin { slotField = slotFieldObj; } else if (eap$lastConfigIndex >= 0 && eap$lastConfigIndex < configSlots.size()) { slotField = eap$lastConfigIndex; - try { LogUtils.getLogger().info("[EAP][InterfaceMixin] Using last hovered config index: {}", slotField); } catch (Throwable ignored) {} } if (slotField < 0) { - try { LogUtils.getLogger().info("[EAP][InterfaceMixin] No hovered slot and no last config index; ignoring adjust."); } catch (Throwable ignored) {} return; } @@ -312,7 +301,6 @@ public abstract class InterfaceScreenMixin { if (idx != null && idx >= 0) { if (eap$lastConfigIndex != idx) { eap$lastConfigIndex = idx; - try { LogUtils.getLogger().info("[EAP][InterfaceMixin] lastConfigIndex updated: {}", eap$lastConfigIndex); } catch (Throwable ignored) {} } } } catch (Throwable ignored) {} 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 1b922e2..6017f35 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 @@ -84,7 +84,6 @@ public abstract class PatternProviderLogicCompatMixin implements IUpgradeableObj private void eap$onAppfluxUpgradesChanged(CallbackInfo ci) { try { if (UpgradeSlotCompat.shouldEnableChannelCard()) { - com.extendedae_plus.util.ExtendedAELogger.LOGGER.info("监听到appflux升级变化,处理频道卡"); // 升级变更,重置并尝试初始化频道卡 eap$compatLastChannel = -1; eap$compatHasInitialized = false; @@ -99,12 +98,10 @@ public abstract class PatternProviderLogicCompatMixin implements IUpgradeableObj at = @At("TAIL")) private void eap$compatInitUpgrades(IManagedGridNode mainNode, PatternProviderLogicHost host, int patternInventorySize, CallbackInfo ci) { try { - com.extendedae_plus.util.ExtendedAELogger.LOGGER.info("兼容性PatternProviderLogic初始化被调用"); boolean upgradeSlots = UpgradeSlotCompat.shouldEnableUpgradeSlots(); boolean channelCard = UpgradeSlotCompat.shouldEnableChannelCard(); - com.extendedae_plus.util.ExtendedAELogger.LOGGER.info("升级槽功能: {}, 频道卡功能: {}", upgradeSlots, channelCard); if (upgradeSlots) { // 只有在升级槽功能启用时才创建升级槽 @@ -113,12 +110,9 @@ public abstract class PatternProviderLogicCompatMixin implements IUpgradeableObj 1, this::eap$compatOnUpgradesChanged ); - com.extendedae_plus.util.ExtendedAELogger.LOGGER.info("创建了完整的升级槽"); } else if (channelCard) { // 如果装了appflux,我们不创建自己的升级槽,而是监听appflux的升级槽 - com.extendedae_plus.util.ExtendedAELogger.LOGGER.info("装了appflux,将监听其升级槽来处理频道卡"); } else { - com.extendedae_plus.util.ExtendedAELogger.LOGGER.info("跳过升级槽创建"); } } catch (Exception e) { com.extendedae_plus.util.ExtendedAELogger.LOGGER.error("兼容性升级初始化失败", e); @@ -261,7 +255,6 @@ public abstract class PatternProviderLogicCompatMixin implements IUpgradeableObj if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) { channel = ChannelCardItem.getChannel(stack); found = true; - com.extendedae_plus.util.ExtendedAELogger.LOGGER.info("找到频道卡,频道: {}", channel); break; } } diff --git a/src/main/java/com/extendedae_plus/mixin/appflux/AppfluxPatternProviderLogicMixin.java b/src/main/java/com/extendedae_plus/mixin/appflux/AppfluxPatternProviderLogicMixin.java index 201121e..6a1621e 100644 --- a/src/main/java/com/extendedae_plus/mixin/appflux/AppfluxPatternProviderLogicMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/appflux/AppfluxPatternProviderLogicMixin.java @@ -28,11 +28,9 @@ public class AppfluxPatternProviderLogicMixin { 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 { @@ -41,7 +39,6 @@ public class AppfluxPatternProviderLogicMixin { IUpgradeInventory currentUpgrades = (IUpgradeInventory) upgradesField.get(this); if (currentUpgrades != null) { - com.extendedae_plus.util.ExtendedAELogger.LOGGER.info("找到appflux升级槽,当前大小: {}", currentUpgrades.size()); // 创建新的2槽升级槽 IUpgradeInventory newUpgrades = UpgradeInventories.forMachine( @@ -66,7 +63,6 @@ public class AppfluxPatternProviderLogicMixin { // 替换升级槽 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); diff --git a/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java b/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java index e9b1727..4009b1b 100644 --- a/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java @@ -126,7 +126,6 @@ public abstract class GuiExPatternProviderMixin extends PatternProviderScreen {} (max={})", currentPage, newPage, maxPage); + // 强制重排(放在更新本地页码之后,确保布局读取到新页) this.repositionSlots(SlotSemantics.ENCODED_PATTERN); this.repositionSlots(SlotSemantics.STORAGE); this.hoveredSlot = null; @@ -184,8 +182,7 @@ public abstract class GuiExPatternProviderMixin extends PatternProviderScreen {} (max={})", currentPage, newPage, maxPage); + // 强制重排(放在更新本地页码之后,确保布局读取到新页) this.repositionSlots(SlotSemantics.ENCODED_PATTERN); this.repositionSlots(SlotSemantics.STORAGE); this.hoveredSlot = null; diff --git a/src/main/java/com/extendedae_plus/network/CraftingMonitorJumpC2SPacket.java b/src/main/java/com/extendedae_plus/network/CraftingMonitorJumpC2SPacket.java index eacd863..3a547aa 100644 --- a/src/main/java/com/extendedae_plus/network/CraftingMonitorJumpC2SPacket.java +++ b/src/main/java/com/extendedae_plus/network/CraftingMonitorJumpC2SPacket.java @@ -54,11 +54,9 @@ public class CraftingMonitorJumpC2SPacket { ServerPlayer player = context.getSender(); if (player == null) return; - LogUtils.getLogger().info("EAP[S]: recv CraftingMonitorJumpC2SPacket key={} from {}", msg.what, player.getGameProfile().getName()); // 必须在 CraftingCPU 界面内 if (!(player.containerMenu instanceof appeng.menu.me.crafting.CraftingCPUMenu menu)) { - LogUtils.getLogger().info("EAP[S]: not in CraftingCPUMenu, abort"); return; } @@ -69,19 +67,16 @@ public class CraftingMonitorJumpC2SPacket { grid = host.getActionableNode().getGrid(); } if (grid == null) { - LogUtils.getLogger().info("EAP[S]: grid is null, abort"); return; } var cs = grid.getCraftingService(); if (!(cs instanceof CraftingService craftingService)) { - LogUtils.getLogger().info("EAP[S]: craftingService is null/unsupported, abort"); return; } // 1) 根据 AEKey 找到可能的样板(pattern) Collection patterns = craftingService.getCraftingFor(msg.what); - LogUtils.getLogger().info("EAP[S]: patterns found={} for key={}", patterns.size(), msg.what); if (patterns.isEmpty()) { return; } @@ -92,9 +87,6 @@ public class CraftingMonitorJumpC2SPacket { int providerCount = 0; for (var provider : providers) { providerCount++; - try { - LogUtils.getLogger().info("EAP[S]: provider class={}", provider.getClass().getName()); - } catch (Throwable ignored) {} if (provider instanceof PatternProviderLogic ppl) { // 使用 accessor 获取 host(受保护字段通过 accessor 访问) PatternProviderLogicHost host = ((PatternProviderLogicAccessor) ppl).eap$host(); @@ -107,7 +99,6 @@ public class CraftingMonitorJumpC2SPacket { BlockPos targetPos = pbe.getBlockPos().relative(dir); var tbe = serverLevel.getBlockEntity(targetPos); if (tbe instanceof MenuProvider provider1) { - LogUtils.getLogger().info("EAP[S]: open screen via MenuProvider at {}", targetPos); NetworkHooks.openScreen(player, provider1, targetPos); context.setPacketHandled(true); return; @@ -115,7 +106,6 @@ public class CraftingMonitorJumpC2SPacket { var tstate = serverLevel.getBlockState(targetPos); var provider2 = tstate.getMenuProvider(serverLevel, targetPos); if (provider2 != null) { - LogUtils.getLogger().info("EAP[S]: open screen via state.getMenuProvider at {}", targetPos); NetworkHooks.openScreen(player, provider2, targetPos); context.setPacketHandled(true); return; @@ -138,7 +128,6 @@ public class CraftingMonitorJumpC2SPacket { var state2 = serverLevel.getBlockState(targetPos); var hit = new BlockHitResult(Vec3.atCenterOf(targetPos), chosen.getOpposite(), targetPos, false); InteractionResult r = state2.use(serverLevel, player, hand, hit); - LogUtils.getLogger().info("EAP[S]: simulated use on {}, face={}, result={}", targetPos, chosen, r); if (r.consumesAction()) { context.setPacketHandled(true); return; @@ -146,9 +135,7 @@ public class CraftingMonitorJumpC2SPacket { } } } - LogUtils.getLogger().info("EAP[S]: providers count for one pattern: {}", providerCount); } - LogUtils.getLogger().info("EAP[S]: no target opened for key={}", msg.what); }); context.setPacketHandled(true); } From 74309779fd752c230c6aef334039cd4fb49df29b Mon Sep 17 00:00:00 2001 From: GaLicn <133291877+GaLicn@users.noreply.github.com> Date: Fri, 26 Sep 2025 23:01:08 +0800 Subject: [PATCH 4/6] =?UTF-8?q?jei=E8=BF=90=E8=A1=8C=E6=97=B6=E6=A3=80?= =?UTF-8?q?=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../extendedae_plus/client/InputEvents.java | 9 +- .../integration/jei/JeiRuntimeProxy.java | 149 ++++-------------- 2 files changed, 33 insertions(+), 125 deletions(-) diff --git a/src/main/java/com/extendedae_plus/client/InputEvents.java b/src/main/java/com/extendedae_plus/client/InputEvents.java index 6a921a4..e52cb36 100644 --- a/src/main/java/com/extendedae_plus/client/InputEvents.java +++ b/src/main/java/com/extendedae_plus/client/InputEvents.java @@ -33,10 +33,7 @@ public final class InputEvents { if (!ModList.get().isLoaded("jei")) { return; } - // 若 JEI 运行时尚未就绪,跳过 - if (JeiRuntimeProxy.get() == null) { - return; - } + // 注意:不要在 try/catch 之外直接访问 JEI 运行时,避免类加载崩溃 // 优先处理:Shift + 左键(拉取或下单) if (event.getButton() == GLFW.GLFW_MOUSE_BUTTON_LEFT && Screen.hasShiftDown()) { try { @@ -103,9 +100,7 @@ public final class InputEvents { if (!ModList.get().isLoaded("jei")) { return; } - if (JeiRuntimeProxy.get() == null) { - return; - } + // 注意:不要在 try/catch 之外直接访问 JEI 运行时,避免类加载崩溃 if (event.getKeyCode() != GLFW.GLFW_KEY_F) return; // 仅当鼠标确实悬停在 JEI 配料上时触发 diff --git a/src/main/java/com/extendedae_plus/integration/jei/JeiRuntimeProxy.java b/src/main/java/com/extendedae_plus/integration/jei/JeiRuntimeProxy.java index bc5276e..38c3541 100644 --- a/src/main/java/com/extendedae_plus/integration/jei/JeiRuntimeProxy.java +++ b/src/main/java/com/extendedae_plus/integration/jei/JeiRuntimeProxy.java @@ -1,24 +1,16 @@ package com.extendedae_plus.integration.jei; -import com.extendedae_plus.mixin.jei.accessor.BookmarkOverlayAccessor; import mezz.jei.api.constants.VanillaTypes; -import mezz.jei.api.forge.ForgeTypes; -import mezz.jei.api.ingredients.IIngredientType; import mezz.jei.api.ingredients.ITypedIngredient; import mezz.jei.api.runtime.IBookmarkOverlay; import mezz.jei.api.runtime.IIngredientListOverlay; import mezz.jei.api.runtime.IJeiRuntime; -import mezz.jei.gui.bookmarks.BookmarkList; -import mezz.jei.gui.bookmarks.IngredientBookmark; -import mezz.jei.gui.overlay.elements.IElement; import net.minecraft.world.item.ItemStack; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fml.ModList; import org.spongepowered.asm.mixin.Pseudo; import javax.annotation.Nullable; -import java.lang.reflect.Field; -import java.lang.reflect.Method; import java.util.Collections; import java.util.List; import java.util.Optional; @@ -131,48 +123,35 @@ public final class JeiRuntimeProxy { } /** - * 获取JEI书签列表 + * 获取 JEI 书签列表。为避免在未安装 JEI GUI 时崩溃,使用反射委托到桥接类。 */ public static List> getBookmarkList() { - IJeiRuntime rt = RUNTIME; - if (rt == null) return Collections.emptyList(); - IBookmarkOverlay bookmarkOverlay = rt.getBookmarkOverlay(); - if (bookmarkOverlay instanceof BookmarkOverlayAccessor accessor) { - BookmarkList bookmarkList = accessor.eap$getBookmarkList(); - return bookmarkList.getElements().stream().map(IElement::getTypedIngredient).toList(); + try { + Class bridge = Class.forName("com.extendedae_plus.integration.jei.JeiBookmarkBridge"); + var m = bridge.getMethod("getBookmarkList"); + @SuppressWarnings("unchecked") + List> list = (List>) m.invoke(null); + return list == null ? Collections.emptyList() : list; + } catch (Throwable ignored) { + return Collections.emptyList(); } - return Collections.emptyList(); } public static void addBookmark(ItemStack stack) { - IJeiRuntime rt = RUNTIME; - if (rt == null) return; - - IBookmarkOverlay overlay = rt.getBookmarkOverlay(); - if (overlay instanceof BookmarkOverlayAccessor accessor) { - BookmarkList list = accessor.eap$getBookmarkList(); - Optional> typedOpt = rt.getIngredientManager() - .createTypedIngredient(VanillaTypes.ITEM_STACK, stack); - typedOpt.ifPresent(typed -> { - IngredientBookmark bookmark = IngredientBookmark.create(typed, rt.getIngredientManager()); - list.add(bookmark); // add 内部会自动保存到配置 - }); + try { + Class bridge = Class.forName("com.extendedae_plus.integration.jei.JeiBookmarkBridge"); + var m = bridge.getMethod("addBookmark", ItemStack.class); + m.invoke(null, stack); + } catch (Throwable ignored) { } } public static void addBookmark(FluidStack fluidStack) { - IJeiRuntime rt = RUNTIME; - if (rt == null) return; - - IBookmarkOverlay overlay = rt.getBookmarkOverlay(); - if (overlay instanceof BookmarkOverlayAccessor accessor) { - BookmarkList list = accessor.eap$getBookmarkList(); - Optional> typedOpt = rt.getIngredientManager() - .createTypedIngredient(ForgeTypes.FLUID_STACK, fluidStack); - typedOpt.ifPresent(typed -> { - IngredientBookmark bookmark = IngredientBookmark.create(typed, rt.getIngredientManager()); - list.add(bookmark); // add 内部会自动保存到配置 - }); + try { + Class bridge = Class.forName("com.extendedae_plus.integration.jei.JeiBookmarkBridge"); + var m = bridge.getMethod("addBookmark", FluidStack.class); + m.invoke(null, fluidStack); + } catch (Throwable ignored) { } } @@ -180,91 +159,25 @@ public final class JeiRuntimeProxy { * 如果存在 Mekanism/appmek,则将 Mekanism 化学堆栈添加到 JEI 书签。 */ public static void addBookmark(Object chemicalStack) { - if (!ModList.get().isLoaded("mekanism") && !ModList.get().isLoaded("appmek")) return; - - IJeiRuntime rt = RUNTIME; - if (rt == null) return; - - IBookmarkOverlay overlay = rt.getBookmarkOverlay(); - if (overlay instanceof BookmarkOverlayAccessor accessor) { - BookmarkList list = accessor.eap$getBookmarkList(); - try { - if (chemicalStack == null) return; - - // Determine Mekanism JEI ingredient type constant by runtime class name - String clsName = chemicalStack.getClass().getName(); - String mekanismJeiClass = "mekanism.client.jei.MekanismJEI"; - Class jeiCls = Class.forName(mekanismJeiClass); - Field typeField = getField(clsName, jeiCls); - - if (typeField == null) return; - Object typeConst = typeField.get(null); - - // Use ingredient manager reflectively to create a typed ingredient - Object ingredientManager = rt.getIngredientManager(); - Method createTypedIngredient = ingredientManager.getClass().getMethod("createTypedIngredient", IIngredientType.class, Object.class); - Object opt = createTypedIngredient.invoke(ingredientManager, typeConst, chemicalStack); - if (!(opt instanceof Optional typedOpt)) return; - if (typedOpt.isPresent()) { - Object typed = typedOpt.get(); - // Find a compatible static create(...) method on IngredientBookmark where - // the second parameter is assignable from the actual ingredientManager instance. - Method createMethod = null; - for (Method m : IngredientBookmark.class.getMethods()) { - if (!m.getName().equals("create")) continue; - Class[] params = m.getParameterTypes(); - if (params.length != 2) continue; - // first param should accept the typed ingredient - boolean firstOk = params[0].isAssignableFrom(typed.getClass()) || params[0].isAssignableFrom(ITypedIngredient.class); - boolean secondOk = params[1].isAssignableFrom(ingredientManager.getClass()); - if (firstOk && secondOk) { - createMethod = m; - break; - } - } - if (createMethod != null) { - Object bookmark = createMethod.invoke(null, typed, ingredientManager); - if (bookmark != null) { - list.add((IngredientBookmark) bookmark); - } - } - } - } catch (Throwable e) { - e.printStackTrace(); - } + try { + Class bridge = Class.forName("com.extendedae_plus.integration.jei.JeiBookmarkBridge"); + var m = bridge.getMethod("addBookmark", Object.class); + m.invoke(null, chemicalStack); + } catch (Throwable ignored) { } } - private static @Nullable Field getField(String clsName, Class jeiCls) throws NoSuchFieldException { - Field typeField = null; - if ("mekanism.api.chemical.gas.GasStack".equals(clsName)) { - typeField = jeiCls.getField("TYPE_GAS"); - } else if ("mekanism.api.chemical.infuse.InfusionStack".equals(clsName)) { - typeField = jeiCls.getField("TYPE_INFUSION"); - } else if ("mekanism.api.chemical.pigment.PigmentStack".equals(clsName)) { - typeField = jeiCls.getField("TYPE_PIGMENT"); - } else if ("mekanism.api.chemical.slurry.SlurryStack".equals(clsName)) { - typeField = jeiCls.getField("TYPE_SLURRY"); - } - return typeField; - } + // Note: helper methods moved to bridge to avoid referencing JEI GUI at class load time. /** - * 从 JEI 书签移除物品 + * 从 JEI 书签移除物品(反射委托) */ public static void removeBookmark(ItemStack stack) { - IJeiRuntime rt = RUNTIME; - if (rt == null) return; - - IBookmarkOverlay overlay = rt.getBookmarkOverlay(); - if (overlay instanceof BookmarkOverlayAccessor accessor) { - BookmarkList list = accessor.eap$getBookmarkList(); - Optional> typedOpt = rt.getIngredientManager() - .createTypedIngredient(VanillaTypes.ITEM_STACK, stack); - typedOpt.ifPresent(typed -> { - IngredientBookmark bookmark = IngredientBookmark.create(typed, rt.getIngredientManager()); - list.remove(bookmark); - }); + try { + Class bridge = Class.forName("com.extendedae_plus.integration.jei.JeiBookmarkBridge"); + var m = bridge.getMethod("removeBookmark", ItemStack.class); + m.invoke(null, stack); + } catch (Throwable ignored) { } } } From 8aeeb1e226f3ffa4fcdf3ad8e08b15eba4cfa23e Mon Sep 17 00:00:00 2001 From: GaLicn <133291877+GaLicn@users.noreply.github.com> Date: Sun, 28 Sep 2025 12:35:25 +0800 Subject: [PATCH 5/6] =?UTF-8?q?jei=E8=BF=90=E8=A1=8C=E6=97=B6=E6=A3=80?= =?UTF-8?q?=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../integration/jei/JeiBookmarkBridge.java | 181 ++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 src/main/java/com/extendedae_plus/integration/jei/JeiBookmarkBridge.java diff --git a/src/main/java/com/extendedae_plus/integration/jei/JeiBookmarkBridge.java b/src/main/java/com/extendedae_plus/integration/jei/JeiBookmarkBridge.java new file mode 100644 index 0000000..9e1572d --- /dev/null +++ b/src/main/java/com/extendedae_plus/integration/jei/JeiBookmarkBridge.java @@ -0,0 +1,181 @@ +package com.extendedae_plus.integration.jei; + +import com.extendedae_plus.mixin.jei.accessor.BookmarkOverlayAccessor; +import mezz.jei.api.constants.VanillaTypes; +import mezz.jei.api.forge.ForgeTypes; +import mezz.jei.api.ingredients.IIngredientType; +import mezz.jei.api.ingredients.ITypedIngredient; +import mezz.jei.api.runtime.IBookmarkOverlay; +import mezz.jei.api.runtime.IJeiRuntime; +import mezz.jei.gui.bookmarks.BookmarkList; +import mezz.jei.gui.bookmarks.IngredientBookmark; +import mezz.jei.gui.overlay.elements.IElement; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fml.ModList; +import org.spongepowered.asm.mixin.Pseudo; + +import javax.annotation.Nullable; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +/** + * 将所有会引用 JEI GUI 内部类(如 BookmarkList、IngredientBookmark、IElement 等)的逻辑 + * 隔离在此桥接类中,避免在未安装 JEI 或 JEI 组件不完整时过早类加载导致的 NoClassDefFoundError。 + * + * 该类仅会被 {@link JeiRuntimeProxy} 通过反射调用。 + */ +@Pseudo +public final class JeiBookmarkBridge { + private JeiBookmarkBridge() {} + + // 通过 JeiRuntimeProxy 的包内可见方法安全地获取 Runtime + private static @Nullable IJeiRuntime getRuntime() { + try { + Class proxy = Class.forName("com.extendedae_plus.integration.jei.JeiRuntimeProxy"); + var m = proxy.getDeclaredMethod("get"); + Object rt = m.invoke(null); + return (IJeiRuntime) rt; + } catch (Throwable ignored) { + return null; + } + } + + public static List> getBookmarkList() { + IJeiRuntime rt = getRuntime(); + if (rt == null) return Collections.emptyList(); + IBookmarkOverlay bookmarkOverlay = rt.getBookmarkOverlay(); + if (bookmarkOverlay instanceof BookmarkOverlayAccessor accessor) { + BookmarkList bookmarkList = accessor.eap$getBookmarkList(); + return bookmarkList.getElements().stream().map(IElement::getTypedIngredient).toList(); + } + return Collections.emptyList(); + } + + public static void addBookmark(ItemStack stack) { + IJeiRuntime rt = getRuntime(); + if (rt == null) return; + + IBookmarkOverlay overlay = rt.getBookmarkOverlay(); + if (overlay instanceof BookmarkOverlayAccessor accessor) { + BookmarkList list = accessor.eap$getBookmarkList(); + Optional> typedOpt = rt.getIngredientManager() + .createTypedIngredient(VanillaTypes.ITEM_STACK, stack); + typedOpt.ifPresent(typed -> { + IngredientBookmark bookmark = IngredientBookmark.create(typed, rt.getIngredientManager()); + list.add(bookmark); // add 内部会自动保存到配置 + }); + } + } + + public static void addBookmark(FluidStack fluidStack) { + IJeiRuntime rt = getRuntime(); + if (rt == null) return; + + IBookmarkOverlay overlay = rt.getBookmarkOverlay(); + if (overlay instanceof BookmarkOverlayAccessor accessor) { + BookmarkList list = accessor.eap$getBookmarkList(); + Optional> typedOpt = rt.getIngredientManager() + .createTypedIngredient(ForgeTypes.FLUID_STACK, fluidStack); + typedOpt.ifPresent(typed -> { + IngredientBookmark bookmark = IngredientBookmark.create(typed, rt.getIngredientManager()); + list.add(bookmark); // add 内部会自动保存到配置 + }); + } + } + + /** + * 如果存在 Mekanism/appmek,则将 Mekanism 化学堆栈添加到 JEI 书签。 + */ + public static void addBookmark(Object chemicalStack) { + if (!ModList.get().isLoaded("mekanism") && !ModList.get().isLoaded("appmek")) return; + + IJeiRuntime rt = getRuntime(); + if (rt == null) return; + + IBookmarkOverlay overlay = rt.getBookmarkOverlay(); + if (overlay instanceof BookmarkOverlayAccessor accessor) { + BookmarkList list = accessor.eap$getBookmarkList(); + try { + if (chemicalStack == null) return; + + // Determine Mekanism JEI ingredient type constant by runtime class name + String clsName = chemicalStack.getClass().getName(); + String mekanismJeiClass = "mekanism.client.jei.MekanismJEI"; + Class jeiCls = Class.forName(mekanismJeiClass); + Field typeField = getField(clsName, jeiCls); + + if (typeField == null) return; + Object typeConst = typeField.get(null); + + // Use ingredient manager reflectively to create a typed ingredient + Object ingredientManager = rt.getIngredientManager(); + Method createTypedIngredient = ingredientManager.getClass().getMethod("createTypedIngredient", IIngredientType.class, Object.class); + Object opt = createTypedIngredient.invoke(ingredientManager, typeConst, chemicalStack); + if (!(opt instanceof Optional typedOpt)) return; + if (typedOpt.isPresent()) { + Object typed = typedOpt.get(); + // Find a compatible static create(...) method on IngredientBookmark where + // the second parameter is assignable from the actual ingredientManager instance. + Method createMethod = null; + for (Method m : IngredientBookmark.class.getMethods()) { + if (!m.getName().equals("create")) continue; + Class[] params = m.getParameterTypes(); + if (params.length != 2) continue; + // first param should accept the typed ingredient + boolean firstOk = params[0].isAssignableFrom(typed.getClass()) || params[0].isAssignableFrom(ITypedIngredient.class); + boolean secondOk = params[1].isAssignableFrom(ingredientManager.getClass()); + if (firstOk && secondOk) { + createMethod = m; + break; + } + } + if (createMethod != null) { + Object bookmark = createMethod.invoke(null, typed, ingredientManager); + if (bookmark != null) { + list.add((IngredientBookmark) bookmark); + } + } + } + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + + private static @Nullable Field getField(String clsName, Class jeiCls) throws NoSuchFieldException { + Field typeField = null; + if ("mekanism.api.chemical.gas.GasStack".equals(clsName)) { + typeField = jeiCls.getField("TYPE_GAS"); + } else if ("mekanism.api.chemical.infuse.InfusionStack".equals(clsName)) { + typeField = jeiCls.getField("TYPE_INFUSION"); + } else if ("mekanism.api.chemical.pigment.PigmentStack".equals(clsName)) { + typeField = jeiCls.getField("TYPE_PIGMENT"); + } else if ("mekanism.api.chemical.slurry.SlurryStack".equals(clsName)) { + typeField = jeiCls.getField("TYPE_SLURRY"); + } + return typeField; + } + + /** + * 从 JEI 书签移除物品 + */ + public static void removeBookmark(ItemStack stack) { + IJeiRuntime rt = getRuntime(); + if (rt == null) return; + + IBookmarkOverlay overlay = rt.getBookmarkOverlay(); + if (overlay instanceof BookmarkOverlayAccessor accessor) { + BookmarkList list = accessor.eap$getBookmarkList(); + Optional> typedOpt = rt.getIngredientManager() + .createTypedIngredient(VanillaTypes.ITEM_STACK, stack); + typedOpt.ifPresent(typed -> { + IngredientBookmark bookmark = IngredientBookmark.create(typed, rt.getIngredientManager()); + list.remove(bookmark); + }); + } + } +} From 32cc796498cf441dbbe5801cfa32a414d35cd46d Mon Sep 17 00:00:00 2001 From: GaLicn <133291877+GaLicn@users.noreply.github.com> Date: Tue, 30 Sep 2025 12:29:49 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E6=97=B6=E6=9C=8D=E5=8A=A1=E7=AB=AF=E5=88=B0=E5=AE=A2=E6=88=B7?= =?UTF-8?q?=E7=AB=AF=E7=BF=BB=E8=AF=91=E9=94=AE=E5=9B=BA=E5=AE=9A=E8=8B=B1?= =?UTF-8?q?=E6=96=87=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/ui/ProviderSelectScreen.java | 25 ++++++++++++++++++- .../util/ExtendedAEPatternUploadUtil.java | 10 ++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/extendedae_plus/client/ui/ProviderSelectScreen.java b/src/main/java/com/extendedae_plus/client/ui/ProviderSelectScreen.java index 1984717..6b8b229 100644 --- a/src/main/java/com/extendedae_plus/client/ui/ProviderSelectScreen.java +++ b/src/main/java/com/extendedae_plus/client/ui/ProviderSelectScreen.java @@ -183,10 +183,29 @@ public class ProviderSelectScreen extends Screen { } } + /** + * 将服务器发送的名称(可能是 Component JSON)反序列化为本地化文本 + */ + private String deserializeComponentName(String name) { + try { + // 如果名称是 JSON 格式的 Component,反序列化后获取本地化文本 + if (name.startsWith("{") || name.startsWith("\"")) { + Component component = Component.Serializer.fromJson(name); + if (component != null) { + return component.getString(); + } + } + } catch (Exception e) { + // 如果不是 JSON 或解析失败,使用原始字符串 + } + return name; + } + private String buildLabel(int idx) { String name = fNames.get(idx); int totalSlots = fTotalSlots.get(idx); int count = fCount.get(idx); + // 不显示具体 id,显示合并统计:名称(总空位)x数量 return name + " (" + totalSlots + ") x" + count; } @@ -215,7 +234,11 @@ public class ProviderSelectScreen extends Screen { String name = names.get(i); long id = ids.get(i); int slots = emptySlots.get(i); - Group g = map.computeIfAbsent(name, k -> new Group()); + + // 将 Component JSON 转换为本地化文本用于分组键 + String groupKey = deserializeComponentName(name); + + Group g = map.computeIfAbsent(groupKey, k -> new Group()); g.count++; g.totalSlots += Math.max(0, slots); // 挑选空位最多的作为代表 id;若并列,保留先到者 diff --git a/src/main/java/com/extendedae_plus/util/ExtendedAEPatternUploadUtil.java b/src/main/java/com/extendedae_plus/util/ExtendedAEPatternUploadUtil.java index d9f2542..6715411 100644 --- a/src/main/java/com/extendedae_plus/util/ExtendedAEPatternUploadUtil.java +++ b/src/main/java/com/extendedae_plus/util/ExtendedAEPatternUploadUtil.java @@ -941,7 +941,9 @@ public class ExtendedAEPatternUploadUtil { // 尝试获取供应器的组信息来构建显示名称 var group = container.getTerminalGroup(); if (group != null) { - return group.name().getString(); + // 使用 Component 序列化来保持翻译键,而不是直接 getString() + // 这样客户端可以根据自己的语言设置进行翻译 + return Component.Serializer.toJson(group.name()); } } catch (Exception e) { // 忽略异常,使用默认名称 @@ -1183,7 +1185,11 @@ public class ExtendedAEPatternUploadUtil { if (container == null) return "未知供应器"; try { var group = container.getTerminalGroup(); - if (group != null) return group.name().getString(); + if (group != null) { + // 使用 Component 序列化来保持翻译键,而不是直接 getString() + // 这样客户端可以根据自己的语言设置进行翻译 + return Component.Serializer.toJson(group.name()); + } } catch (Throwable ignored) { } return "样板供应器";