Skip to content

Commit 1f6d86e

Browse files
author
Kazero00
committed
feat: MiaoNet 与 CelesteNet.Client 互为替代
- 任一启用时,另一个的依赖视为已满足(不再报「依赖·缺失/未启用」) - 在被替代的 Mod 行末尾显示「{alt} 已开启」徽标(深蓝白字) - 修正 excludeFromAutoEnableList 中 'Miao.CelesteNet.Client' 的笔误为 实际 Mod 名 'MiaoNet'(MiaoNet 装好后的 Everest 名即 "MiaoNet", 见 main.rs get_installed_miaonet 的 p.name == "MiaoNet")
1 parent 9aaeb47 commit 1f6d86e

7 files changed

Lines changed: 53 additions & 3 deletions

File tree

src/celemod-ui/locales/de-DE.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@
128128
"禁用全部": "Alle deaktivieren",
129129
"启用全部": "Alle aktivieren",
130130
"启用全部依赖": "Alle Abhängigkeiten aktivieren",
131+
"{alt} 已开启": "{alt} aktiviert",
132+
"{alt} 已开启,可替代本 Mod": "{alt} ist aktiviert, ersetzt dieses Mod",
131133
"应用修改": "Änderungen übernehmen",
132134
"主树隐藏依赖": "Hauptbaumabgrenzung verstecken",
133135
"检查可选依赖": "Optionale Abhängigkeiten überprüfen",

src/celemod-ui/locales/en-US.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@
116116
"禁用全部": "Disable All",
117117
"启用全部": "Enable All",
118118
"启用全部依赖": "Enable All Deps",
119+
"{alt} 已开启": "{alt} enabled",
120+
"{alt} 已开启,可替代本 Mod": "{alt} is enabled, substitutes this mod",
119121
"检查可选依赖": "Check Optional Deps",
120122
"显示完整树": "Full Tree",
121123
"显示更新": "Show Updates",

src/celemod-ui/locales/fr-FR.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@
128128
"禁用全部": "Désactiver tous les",
129129
"启用全部": "Activer tout",
130130
"启用全部依赖": "Activer toutes les dépendances",
131+
"{alt} 已开启": "{alt} activé",
132+
"{alt} 已开启,可替代本 Mod": "{alt} est activé, remplace ce mod",
131133
"应用修改": "Modification de l'application",
132134
"主树隐藏依赖": "Dépendance cachée de l'arbre principal",
133135
"检查可选依赖": "Vérifier les dépendances facultatives",

src/celemod-ui/locales/pt-BR.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@
114114
"禁用全部": "Desativar Todos",
115115
"启用全部": "Ativar Todos",
116116
"启用全部依赖": "Ativar Todas as Dependências",
117+
"{alt} 已开启": "{alt} ativado",
118+
"{alt} 已开启,可替代本 Mod": "{alt} está ativado, substitui este mod",
117119
"检查可选依赖": "Checar Dependências Opcionais",
118120
"显示完整树": "Lista Inteira",
119121
"显示更新": "Exibir Atualizações",

src/celemod-ui/locales/ru-RU.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@
116116
"禁用全部": "Отключить все",
117117
"启用全部": "Включить все",
118118
"启用全部依赖": "Включить все зависимости",
119+
"{alt} 已开启": "{alt} включён",
120+
"{alt} 已开启,可替代本 Mod": "{alt} включён, заменяет этот мод",
119121
"检查可选依赖": "Проверять дополнительные зависимости",
120122
"显示完整树": "Всё дерево",
121123
"显示更新": "Показать обновления",

src/celemod-ui/locales/zh-CN.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@
116116
"禁用全部": "禁用全部",
117117
"启用全部": "启用全部",
118118
"启用全部依赖": "启用全部依赖",
119+
"{alt} 已开启": "{alt} 已开启",
120+
"{alt} 已开启,可替代本 Mod": "{alt} 已开启,可替代本 Mod",
119121
"检查可选依赖": "检查可选依赖",
120122
"显示完整树": "显示完整树",
121123
"显示更新": "显示更新",

src/celemod-ui/src/routes/Manage.tsx

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,22 @@ type ModDepInfo = ModInfoProbablyMissing & {
8181
optional: boolean;
8282
};
8383

84+
// Mods that can stand in for one another: if any one in the list is enabled,
85+
// a dependency on any *other* member is treated as satisfied. Special-case for
86+
// the multiplayer clients — CelesteNet.Client and its CN fork MiaoNet.
87+
// (MiaoNet's installed name is literally "MiaoNet"; see main.rs
88+
// get_installed_miaonet.)
89+
const CELESTENET_ALT_LIST = ['CelesteNet.Client', 'MiaoNet'];
90+
const MOD_FRIENDLY_NAME: Record<string, string> = {
91+
'CelesteNet.Client': 'CelesteNet',
92+
'MiaoNet': 'MiaoNet',
93+
};
94+
// Returns the (raw) name of an enabled alternative covering `name`, else undefined.
95+
const altCovering = (name: string, modMap: Map<string, ModInfo>) => {
96+
if (!CELESTENET_ALT_LIST.includes(name)) return undefined;
97+
return CELESTENET_ALT_LIST.find((alt) => alt !== name && modMap.get(alt)?.enabled);
98+
};
99+
84100
const modListContext = createContext<{
85101
switchMod: (id: string, enabled: boolean, recursive?: boolean) => void;
86102
switchProfile: (name: string) => void;
@@ -95,6 +111,7 @@ const modListContext = createContext<{
95111
showDetailed: boolean;
96112
alwaysOnMods: string[];
97113
switchAlwaysOn: (name: string, enabled: boolean) => void;
114+
isCoveredByAlt: (name: string) => string | undefined;
98115
autoDisableNewMods: boolean;
99116
hasUpdateMods: {
100117
name: string;
@@ -252,6 +269,7 @@ const ModLocal = ({
252269
}, [name, ctx.hasUpdateMods]);
253270

254271
const isAlwaysOn = ctx?.alwaysOnMods.includes(name);
272+
const coveredByAlt = ctx?.isCoveredByAlt?.(name);
255273

256274
const [editingComment, setEditingComment] = useState(false);
257275
const refCommentInput = useRef<HTMLInputElement>(null);
@@ -381,6 +399,20 @@ const ModLocal = ({
381399
</ModBadge>
382400
)}
383401

402+
{coveredByAlt && (
403+
<ModBadge
404+
bg="#0d47a1"
405+
color="white"
406+
title={_i18n.t('{alt} 已开启,可替代本 Mod', {
407+
alt: MOD_FRIENDLY_NAME[coveredByAlt] ?? coveredByAlt,
408+
})}
409+
>
410+
{_i18n.t('{alt} 已开启', {
411+
alt: MOD_FRIENDLY_NAME[coveredByAlt] ?? coveredByAlt,
412+
})}
413+
</ModBadge>
414+
)}
415+
384416
<span
385417
className="modName"
386418
onClick={() => setEditingComment(true)}
@@ -656,7 +688,9 @@ export const Manage = () => {
656688
}
657689

658690
if (!modMap.has(dep.name)) {
659-
mergeSM({ status: 'missing', message: '' }, dep.name);
691+
if (!altCovering(dep.name, modMap)) {
692+
mergeSM({ status: 'missing', message: '' }, dep.name);
693+
}
660694
continue;
661695
}
662696

@@ -671,7 +705,7 @@ export const Manage = () => {
671705
);
672706
}
673707

674-
if (!installedDep.enabled) {
708+
if (!installedDep.enabled && !altCovering(dep.name, modMap)) {
675709
mergeSM(
676710
{
677711
status: 'not-enabled',
@@ -898,6 +932,7 @@ export const Manage = () => {
898932
if (enabled) setAlwaysOnMods([...alwaysOnMods, name]);
899933
else setAlwaysOnMods(alwaysOnMods.filter((v) => v !== name));
900934
},
935+
isCoveredByAlt: (name: string) => altCovering(name, installedModMap),
901936
alwaysOnMods,
902937
autoDisableNewMods,
903938
modComments, setModComment(name: string, comment: string) {
@@ -970,9 +1005,11 @@ export const Manage = () => {
9701005
}
9711006

9721007
const switchList: string[] = [];
1008+
// Alternatives the user must pick between — don't auto-enable them when
1009+
// a dependent is toggled on. See DEPENDENCY_ALTERNATIVES above.
9731010
const excludeFromAutoEnableList = [
9741011
'CelesteNet.Client',
975-
'Miao.CelesteNet.Client',
1012+
'MiaoNet',
9761013
];
9771014

9781015
const visited = new Set<string>();
@@ -1165,6 +1202,7 @@ export const Manage = () => {
11651202
[
11661203
currentProfile,
11671204
installedMods,
1205+
installedModMap,
11681206
gamePath,
11691207
modPath,
11701208
fullTree,

0 commit comments

Comments
 (0)