From c325cc1d39180ec52cca901f122aad1f9b91a783 Mon Sep 17 00:00:00 2001 From: GaLicn <3096147684@qq.com> Date: Fri, 15 Aug 2025 11:06:46 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=8A=E4=BC=A0=E6=A0=B7?= =?UTF-8?q?=E6=9D=BF=E5=88=B0=E8=A3=85=E9=85=8D=E7=9F=A9=E9=98=B5=E6=A6=82?= =?UTF-8?q?=E7=8E=87=E5=A4=B1=E6=95=88=E9=97=AE=E9=A2=98=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E6=A6=82=E7=8E=87=E5=B4=A9=E7=AB=AF=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mixin/MEStorageMenuMixin.java | 61 +++++++++++++++++-- 1 file changed, 56 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/extendedae_plus/mixin/MEStorageMenuMixin.java b/src/main/java/com/extendedae_plus/mixin/MEStorageMenuMixin.java index 6ca2119..73c083b 100644 --- a/src/main/java/com/extendedae_plus/mixin/MEStorageMenuMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/MEStorageMenuMixin.java @@ -16,8 +16,8 @@ import appeng.api.config.Setting; * 而客户端 clientCM 未注册时,AE2 在同步环节会对 clientCM 执行 getSetting, * 进而抛出 UnsupportedSettingException。 * - * 方案:在服务端首次 broadcastChanges 时,将 serverCM 中的所有设置镜像注册到 clientCM, - * 以确保后续同步安全。 + * 方案:在服务端首次 broadcastChanges 时,仅为“客户端缺失”的设置执行注册补齐,且占位值与服务端不同, + * 以确保 AE2 后续仍会发送 ConfigValuePacket 完成真正的值同步,避免影响排序等行为。 */ @Mixin(MEStorageMenu.class) public abstract class MEStorageMenuMixin { @@ -40,14 +40,65 @@ public abstract class MEStorageMenuMixin { return; } for (Setting setting : server.getSettings()) { + boolean clientHasSetting = true; try { - // 使用 AE2 提供的通用复制接口,内部会处理未注册场景 - setting.copy(server, client); - } catch (Throwable ignore) { } + // 若未注册,这里会抛出异常 + client.getSetting(setting); + } catch (Throwable unsupported) { + clientHasSetting = false; + } + + if (!clientHasSetting) { + try { + Object serverValue = server.getSetting(setting); + Object placeholder = extendedae_plus$chooseDifferentEnumValue(serverValue); + if (placeholder == null) { + // 若无法选择不同的占位值(例如只有一个枚举常量),则退回服务端值 + placeholder = serverValue; + } + // 使用辅助方法,统一进行受检的泛型转换后再注册 + extendedae_plus$registerSettingCompat(client, setting, placeholder); + } catch (Throwable ignore) { + // 防御:不让异常影响主流程 + } + } } this.extendedae_plus$settingsMirrored = true; } catch (Throwable t) { // 防御:绝不让同步失败导致崩溃 } } + + @Unique + private Object extendedae_plus$chooseDifferentEnumValue(Object serverValue) { + if (!(serverValue instanceof Enum sv)) { + return null; + } + @SuppressWarnings("unchecked") + Class> enumClass = sv.getDeclaringClass(); + Object[] constants = enumClass.getEnumConstants(); + if (constants == null || constants.length == 0) { + return null; + } + for (Object c : constants) { + if (c != sv) { + return c; + } + } + return null; + } + + @Unique + @SuppressWarnings({"unchecked", "rawtypes"}) + private static > void extendedae_plus$registerSettingCompat( + IConfigManager client, Setting setting, Object value) { + // 前置校验:仅处理枚举类型的设置值 + if (!(value instanceof Enum)) { + // 非枚举则忽略(AE2 设置值通常为枚举) + return; + } + Setting typedSetting = (Setting) setting; + T typedValue = (T) value; + client.registerSetting(typedSetting, typedValue); + } }