+70
-2
packages/core-extensions/src/moonbase/webpackModules/crashScreen.tsx
+70
-2
packages/core-extensions/src/moonbase/webpackModules/crashScreen.tsx
···
4
4
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
5
5
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
6
6
import { RepositoryManifest, UpdateState } from "../types";
7
+
import { ConfigExtension, DetectedExtension } from "@moonlight-mod/types";
7
8
8
9
const { Button, TabBar } = Components;
9
10
const TabBarClasses = spacepack.findByCode(/tabBar:"tabBar_[a-z0-9]+",tabBarItem:"tabBarItem_[a-z0-9]+"/)[0].exports;
11
+
12
+
const MODULE_REGEX = /Webpack-Module-(\d+)/g;
10
13
11
14
const logger = moonlight.getLogger("moonbase/crashScreen");
12
15
···
83
86
);
84
87
}
85
88
89
+
function ExtensionDisableCard({ ext }: { ext: DetectedExtension }) {
90
+
function disableWithDependents() {
91
+
const disable = new Set<string>();
92
+
disable.add(ext.id);
93
+
for (const [id, dependencies] of moonlightNode.processedExtensions.dependencyGraph) {
94
+
if (dependencies?.has(ext.id)) disable.add(id);
95
+
}
96
+
97
+
const config = structuredClone(moonlightNode.config);
98
+
for (const id in config.extensions) {
99
+
if (!disable.has(id)) continue;
100
+
if (typeof config.extensions[id] === "boolean") config.extensions[id] = false;
101
+
else (config.extensions[id] as ConfigExtension).enabled = false;
102
+
}
103
+
104
+
let msg = `Are you sure you want to disable "${ext.manifest.meta?.name ?? ext.id}"`;
105
+
if (disable.size > 1) {
106
+
msg += ` and its ${disable.size - 1} dependent${disable.size - 1 === 1 ? "" : "s"}`;
107
+
}
108
+
msg += "?";
109
+
110
+
if (confirm(msg)) {
111
+
moonlightNode.writeConfig(config);
112
+
window.location.reload();
113
+
}
114
+
}
115
+
116
+
return (
117
+
<div className="moonbase-crash-extensionCard">
118
+
<div className="moonbase-crash-extensionCard-meta">
119
+
<div className="moonbase-crash-extensionCard-title">{ext.manifest.meta?.name ?? ext.id}</div>
120
+
<div className="moonbase-crash-extensionCard-version">{`v${ext.manifest.version ?? "???"}`}</div>
121
+
</div>
122
+
<div className="moonbase-crash-extensionCard-button">
123
+
<Button color={Button.Colors.RED} onClick={disableWithDependents}>
124
+
Disable
125
+
</Button>
126
+
</div>
127
+
</div>
128
+
);
129
+
}
130
+
86
131
export function wrapAction({ action, state }: WrapperProps) {
87
132
const [tab, setTab] = React.useState("crash");
88
133
···
94
139
};
95
140
});
96
141
142
+
const causes = React.useMemo(() => {
143
+
const causes = new Set<string>();
144
+
if (state.error.stack) {
145
+
for (const [, id] of state.error.stack.matchAll(MODULE_REGEX))
146
+
for (const ext of moonlight.patched.get(id) ?? []) causes.add(ext);
147
+
}
148
+
for (const [, id] of state.info.componentStack.matchAll(MODULE_REGEX))
149
+
for (const ext of moonlight.patched.get(id) ?? []) causes.add(ext);
150
+
return [...causes];
151
+
}, []);
152
+
97
153
return (
98
154
<div className="moonbase-crash-wrapper">
99
155
{action}
···
104
160
onItemSelect={(v) => setTab(v)}
105
161
>
106
162
<TabBar.Item className={TabBarClasses.tabBarItem} id="crash">
107
-
Crash Details
163
+
Crash details
108
164
</TabBar.Item>
109
165
<TabBar.Item className={TabBarClasses.tabBarItem} id="extensions" disabled={updateCount === 0}>
110
-
{`Extension Updates (${updateCount})`}
166
+
{`Extension updates (${updateCount})`}
167
+
</TabBar.Item>
168
+
<TabBar.Item className={TabBarClasses.tabBarItem} id="causes" disabled={causes.length === 0}>
169
+
{`Possible causes (${causes.length})`}
111
170
</TabBar.Item>
112
171
</TabBar>
113
172
{tab === "crash" ? (
···
126
185
{updates.map(([id, ext]) => (
127
186
<ExtensionUpdateCard id={Number(id)} ext={ext} />
128
187
))}
188
+
</div>
189
+
) : null}
190
+
{tab === "causes" ? (
191
+
<div className="moonbase-crash-extensions">
192
+
{causes
193
+
.map((ext) => moonlightNode.extensions.find((e) => e.id === ext)!)
194
+
.map((ext) => (
195
+
<ExtensionDisableCard ext={ext} />
196
+
))}
129
197
</div>
130
198
) : null}
131
199
</div>
+4
packages/core/src/patch.ts
+4
packages/core/src/patch.ts
···
111
111
const mappedName = moonlight.moonmap.modules[id];
112
112
let modified = false;
113
113
114
+
const exts = new Set<string>();
115
+
114
116
for (let i = 0; i < patches.length; i++) {
115
117
const patch = patches[i];
116
118
if (patch.prerequisite != null && !patch.prerequisite()) {
···
169
171
if (!hardFailed) {
170
172
moduleString = replaced;
171
173
modified = true;
174
+
exts.add(patch.ext);
172
175
}
173
176
174
177
moonlight.unpatched.delete(patch);
···
179
182
if (modified) {
180
183
patchModule(id, patchedStr.join(", "), moduleString);
181
184
moduleCache[id] = moduleString;
185
+
moonlight.patched.set(id, exts);
182
186
}
183
187
184
188
try {
+1
packages/types/src/globals.ts
+1
packages/types/src/globals.ts