Repository navigation
fix(manage): 始终开启/同名重复的 Mod 不再关不掉 - #96
Open
std-external wants to merge 3 commits into
Open
std-external wants to merge 3 commits into
std-external wants to merge 3 commits into
Conversation
MiniInstaller 有时不是报安装错误,而是直接死在 .NET 运行时自己的原生代码里 (AccessViolationException 打在 relinker 的 String.StartsWith → Globalization P/Invoke 上)。这段栈对用户没有用,还会让人以为游戏或 CeleMod 坏了。 CELEMOD 侧确认过的事实:MiniInstaller 的 StandardMode 是在本进程里单线程调 MonoMod 的(DepCalls.RunMonoMod → MonoModder.AutoPatch),MonoModder 自己没有 任何 Parallel/Task,官方 Everest 也没有并行 relink/并行加载开关(那两个 EVEREST_PARALLEL_* 是 EverestUltra 的),所以这次崩溃不是重链竞态,而是进程里 被别的东西打坏了原生内存/运行时:常见是杀毒软件、显卡驱动的游戏内覆盖层之类 注入到每个进程的东西,或者游戏目录里那份 piton-runtime 被打坏。 安装失败时按栈里的特征串认出这类崩溃,在原始错误后面补一条能照做的建议 (先关实时防护和游戏内覆盖层再装一次;不行就手动解压 Main.zip 跑 MiniInstaller-win64.exe),本地包安装走同一个提示。其他安装失败原样返回。
用户反馈这类崩溃是偶发的:同一台机器、同样的步骤,之前成功过一次。所以它的 性质是「偶发 + 崩在运行时原生层」,不是确定性的环境损坏。 - everest.rs:抽出 extract_everest_archive,安装失败且错误串带原生崩溃特征 (is_installer_native_crash:AccessViolationException / 受保护内存中英文)时, 重新解压一遍再跑一次 MiniInstaller(崩溃那次会把游戏目录留在半装状态,不 重解压直接重跑不安全),只重试一次,两次都崩才把错误抛给用户。 - everest.rs:在 Windows 上给安装器子进程设 DOTNET_SYSTEM_GLOBALIZATION_USENLS=1。 MonoMod 在 FindType 里用文化相关的 String.StartsWith 比依赖名,.NET 在非 en* 区域设置下会走 ICU(dotnet/runtime#132702 是同一个栈,运行时团队判定该路径是 外部堆破坏的最早受害者);让安装器进程用 NLS 只影响这些 ASCII 前缀的比较结果 (完全一致),对子进程来说是安全的默认值。 - backend.rs:提示文案改成「已经自动重装过一遍还是崩」,并把重试放在第一位。 cargo test --lib: 119 passed(新增 3 个:崩溃特征识别、失败后确实重试并成功、连续崩两次不循环)。
管理页的状态开关对两类 Mod 是死按键:点了没反应,也没有任何提示, 用户只能看到它一直留在启用列表里。 - 始终开启(右键或长按状态按钮设的)Mod 会被静默过滤掉,而且这个标记 存在 localStorage 里,装回同一个 Mod 也会继承。现在点关闭会说明原因, 并可以一键「取消始终开启并禁用」;每行的「…」菜单也加了同样的开关, 触屏用户不必再猜右键。 - 未启用预设模式时,禁用只把状态按钮上显示的那个文件写进 blacklist.txt。 同名重复安装(文件夹 + 压缩包)时另一个文件照旧被加载,刷新后又显示 「已启用」。现在禁用会覆盖该 Mod 名下的全部文件;启用仍只放开显示的 那个文件。 测试:src/alwaysOnSwitch.test.ts(splitAlwaysOnNames / switchBlacklistFiles), blacklist.rs 的 direct_blacklist_disable_covers_every_duplicate_file。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
群里反馈:有的 Mod「赖在 CeleMod 的启用列表里不走」,点状态开关「关不掉」。定位到两处会让管理页的状态开关变成死按键:
batchSwitch会把始终开启的名字静默过滤掉(旧代码构造alwaysOnFiles后effectiveNames.length === 0直接return)。这个标记由状态按钮的右键写进 localStorage(states.ts的alwaysOnMods),删掉 Mod 再装回来也照样继承;触屏上长按就是右键,很容易误设,而界面上除了按钮文字没有任何取消入口,所以点开关完全没反应。blacklist.txt,另一个文件仍然被加载,下一次刷新这一行又变回「已启用」。修复
batchSwitch/applyProfileSoon接受本次要写入的始终开启列表,避免用旧状态再把它拉回来)。blacklist.txt(switchBlacklistFiles);启用仍只放开显示的那个文件,保持「同名只能启用一个」的既有行为。isAlwaysOnPackage/splitAlwaysOnNames/switchBlacklistFiles三个纯函数,管理页里的重复实现改为复用。验证
pnpm --dir src/celemod-ui typecheck通过。src/alwaysOnSwitch.test.ts(pnpm --dir src/celemod-ui test:always-on,5 个用例):始终开启的名字被判为 blocked、按文件匹配(重命名后仍算同一份)、已删除的陈旧名字不误判、禁用覆盖全部重复文件、启用只放开一个;manageDependencies.test.ts、modAdoption.test.ts未受影响。blacklist.rs::direct_blacklist_disable_covers_every_duplicate_file;CARGO_TARGET_DIR=… cargo test --lib blacklist→ 24 passed。来源:Celeste 蔚蓝制图群反馈(同时提到「赖在启动项里不走」和「关不掉」)。