@modwrench/workbench 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/conflicts/README.md +39 -0
- package/data/conflicts/fallout4.json +1 -0
- package/data/conflicts/lethalcompany.json +1 -0
- package/data/conflicts/skyrimspecialedition.json +1 -0
- package/dist/conflicts/community.d.ts +3 -0
- package/dist/conflicts/community.d.ts.map +1 -0
- package/dist/conflicts/community.js +96 -0
- package/dist/conflicts/community.js.map +1 -0
- package/dist/conflicts/index.d.ts +6 -0
- package/dist/conflicts/index.d.ts.map +1 -0
- package/dist/conflicts/index.js +114 -0
- package/dist/conflicts/index.js.map +1 -0
- package/dist/conflicts/loot.d.ts +19 -0
- package/dist/conflicts/loot.d.ts.map +1 -0
- package/dist/conflicts/loot.js +148 -0
- package/dist/conflicts/loot.js.map +1 -0
- package/dist/conflicts/types.d.ts +31 -0
- package/dist/conflicts/types.d.ts.map +1 -0
- package/dist/conflicts/types.js +6 -0
- package/dist/conflicts/types.js.map +1 -0
- package/dist/crashlog/bepinex.d.ts +3 -0
- package/dist/crashlog/bepinex.d.ts.map +1 -0
- package/dist/crashlog/bepinex.js +105 -0
- package/dist/crashlog/bepinex.js.map +1 -0
- package/dist/crashlog/crashlogger-sse.d.ts +3 -0
- package/dist/crashlog/crashlogger-sse.d.ts.map +1 -0
- package/dist/crashlog/crashlogger-sse.js +226 -0
- package/dist/crashlog/crashlogger-sse.js.map +1 -0
- package/dist/crashlog/detect.d.ts +3 -0
- package/dist/crashlog/detect.d.ts.map +1 -0
- package/dist/crashlog/detect.js +44 -0
- package/dist/crashlog/detect.js.map +1 -0
- package/dist/crashlog/index.d.ts +15 -0
- package/dist/crashlog/index.d.ts.map +1 -0
- package/dist/crashlog/index.js +65 -0
- package/dist/crashlog/index.js.map +1 -0
- package/dist/crashlog/minecraft.d.ts +3 -0
- package/dist/crashlog/minecraft.d.ts.map +1 -0
- package/dist/crashlog/minecraft.js +145 -0
- package/dist/crashlog/minecraft.js.map +1 -0
- package/dist/crashlog/netscriptframework.d.ts +3 -0
- package/dist/crashlog/netscriptframework.d.ts.map +1 -0
- package/dist/crashlog/netscriptframework.js +109 -0
- package/dist/crashlog/netscriptframework.js.map +1 -0
- package/dist/crashlog/types.d.ts +35 -0
- package/dist/crashlog/types.d.ts.map +1 -0
- package/dist/crashlog/types.js +9 -0
- package/dist/crashlog/types.js.map +1 -0
- package/dist/detect/environment.d.ts +35 -0
- package/dist/detect/environment.d.ts.map +1 -0
- package/dist/detect/environment.js +65 -0
- package/dist/detect/environment.js.map +1 -0
- package/dist/detect/games.d.ts +21 -0
- package/dist/detect/games.d.ts.map +1 -0
- package/dist/detect/games.js +159 -0
- package/dist/detect/games.js.map +1 -0
- package/dist/detect/loader.d.ts +12 -0
- package/dist/detect/loader.d.ts.map +1 -0
- package/dist/detect/loader.js +20 -0
- package/dist/detect/loader.js.map +1 -0
- package/dist/detect/manager.d.ts +26 -0
- package/dist/detect/manager.d.ts.map +1 -0
- package/dist/detect/manager.js +157 -0
- package/dist/detect/manager.js.map +1 -0
- package/dist/detect/os.d.ts +21 -0
- package/dist/detect/os.d.ts.map +1 -0
- package/dist/detect/os.js +58 -0
- package/dist/detect/os.js.map +1 -0
- package/dist/detect/steam.d.ts +32 -0
- package/dist/detect/steam.d.ts.map +1 -0
- package/dist/detect/steam.js +155 -0
- package/dist/detect/steam.js.map +1 -0
- package/dist/detect/vdf.d.ts +12 -0
- package/dist/detect/vdf.d.ts.map +1 -0
- package/dist/detect/vdf.js +112 -0
- package/dist/detect/vdf.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/loadorder/index.d.ts +20 -0
- package/dist/loadorder/index.d.ts.map +1 -0
- package/dist/loadorder/index.js +76 -0
- package/dist/loadorder/index.js.map +1 -0
- package/dist/loadorder/mo2.d.ts +21 -0
- package/dist/loadorder/mo2.d.ts.map +1 -0
- package/dist/loadorder/mo2.js +201 -0
- package/dist/loadorder/mo2.js.map +1 -0
- package/dist/loadorder/r2modman.d.ts +12 -0
- package/dist/loadorder/r2modman.d.ts.map +1 -0
- package/dist/loadorder/r2modman.js +115 -0
- package/dist/loadorder/r2modman.js.map +1 -0
- package/dist/loadorder/types.d.ts +30 -0
- package/dist/loadorder/types.d.ts.map +1 -0
- package/dist/loadorder/types.js +5 -0
- package/dist/loadorder/types.js.map +1 -0
- package/dist/loadorder/vortex.d.ts +8 -0
- package/dist/loadorder/vortex.d.ts.map +1 -0
- package/dist/loadorder/vortex.js +77 -0
- package/dist/loadorder/vortex.js.map +1 -0
- package/dist/metadata/clients.d.ts +11 -0
- package/dist/metadata/clients.d.ts.map +1 -0
- package/dist/metadata/clients.js +90 -0
- package/dist/metadata/clients.js.map +1 -0
- package/dist/metadata/index.d.ts +3 -0
- package/dist/metadata/index.d.ts.map +1 -0
- package/dist/metadata/index.js +149 -0
- package/dist/metadata/index.js.map +1 -0
- package/dist/metadata/normalize.d.ts +43 -0
- package/dist/metadata/normalize.d.ts.map +1 -0
- package/dist/metadata/normalize.js +88 -0
- package/dist/metadata/normalize.js.map +1 -0
- package/dist/metadata/types.d.ts +57 -0
- package/dist/metadata/types.d.ts.map +1 -0
- package/dist/metadata/types.js +9 -0
- package/dist/metadata/types.js.map +1 -0
- package/dist/register.d.ts +13 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +209 -0
- package/dist/register.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crashlogger-sse.d.ts","sourceRoot":"","sources":["../../src/crashlog/crashlogger-sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,mBAAmB,EACnB,YAAY,EAGb,MAAM,YAAY,CAAC;AAmNpB,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,CAAC,YAAY,EAAE,iBAAiB,GAAG,UAAU,CAAC,GAC7D,mBAAmB,CA6BrB"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
// Shared parser for the FudgyDuff / NG family: Crash Logger SSE and Buffout 4
|
|
2
|
+
// emit nearly identical section-based layouts. We split into named sections
|
|
3
|
+
// first, then parse each section's content. Game-specific differences (the
|
|
4
|
+
// version line, plugin index format) are handled by passing the format.
|
|
5
|
+
//
|
|
6
|
+
// Section labels seen in real logs:
|
|
7
|
+
// SETTINGS, SYSTEM SPECS, PROBABLE CALL STACK, REGISTERS, STACK, MODULES,
|
|
8
|
+
// PLUGINS, POSSIBLE RELEVANT OBJECTS, RELEVANT OBJECTS, ENB
|
|
9
|
+
const SECTION_REGEX = /^[A-Z][A-Z0-9 _\\/-]+:$/;
|
|
10
|
+
function splitSections(lines) {
|
|
11
|
+
const sections = new Map();
|
|
12
|
+
const preamble = [];
|
|
13
|
+
let current = null;
|
|
14
|
+
let buffer = [];
|
|
15
|
+
const flush = () => {
|
|
16
|
+
if (current !== null) {
|
|
17
|
+
sections.set(current, buffer);
|
|
18
|
+
}
|
|
19
|
+
buffer = [];
|
|
20
|
+
};
|
|
21
|
+
for (const line of lines) {
|
|
22
|
+
const trimmed = line.trimEnd();
|
|
23
|
+
if (SECTION_REGEX.test(trimmed)) {
|
|
24
|
+
flush();
|
|
25
|
+
current = trimmed.slice(0, -1).trim(); // strip trailing colon
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (current === null)
|
|
29
|
+
preamble.push(line);
|
|
30
|
+
else
|
|
31
|
+
buffer.push(line);
|
|
32
|
+
}
|
|
33
|
+
flush();
|
|
34
|
+
return { preamble, sections };
|
|
35
|
+
}
|
|
36
|
+
// Preamble: 1-3 lines like:
|
|
37
|
+
// Skyrim SSE v1.6.640.0
|
|
38
|
+
// CrashLoggerSSE v1-12-1
|
|
39
|
+
// Unhandled exception "EXCEPTION_ACCESS_VIOLATION" at 0x... SkyrimSE.exe+...
|
|
40
|
+
function parsePreamble(preamble) {
|
|
41
|
+
let gameVersion;
|
|
42
|
+
let loggerVersion;
|
|
43
|
+
const exception = {};
|
|
44
|
+
for (const raw of preamble) {
|
|
45
|
+
const line = raw.trim();
|
|
46
|
+
if (!line)
|
|
47
|
+
continue;
|
|
48
|
+
if (/^(Skyrim|Fallout)\b/.test(line) && line.includes(" v")) {
|
|
49
|
+
gameVersion = line;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (/^(CrashLogger|Buffout)/i.test(line)) {
|
|
53
|
+
loggerVersion = line;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (line.startsWith("Unhandled exception")) {
|
|
57
|
+
const typeMatch = line.match(/"([^"]+)"/);
|
|
58
|
+
const addrMatch = line.match(/at\s+(0x[0-9A-Fa-f]+)/);
|
|
59
|
+
if (typeMatch)
|
|
60
|
+
exception.type = typeMatch[1];
|
|
61
|
+
if (addrMatch)
|
|
62
|
+
exception.address = addrMatch[1];
|
|
63
|
+
exception.description = line;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return { gameVersion, loggerVersion, exception };
|
|
68
|
+
}
|
|
69
|
+
// Call stack entries look like:
|
|
70
|
+
// [0] 0x7FF7B3D2A3F0 SkyrimSE.exe+1AA3A3F0 -> 0
|
|
71
|
+
// [1] 0x7FFF12345678 SomeMod.dll+12345
|
|
72
|
+
// or sometimes with symbol names attached after the offset.
|
|
73
|
+
function parseCallStack(section) {
|
|
74
|
+
if (!section)
|
|
75
|
+
return [];
|
|
76
|
+
const frames = [];
|
|
77
|
+
for (const raw of section) {
|
|
78
|
+
const line = raw.trim();
|
|
79
|
+
if (!line)
|
|
80
|
+
continue;
|
|
81
|
+
const match = line.match(/^\[(\d+)\]\s+0x[0-9A-Fa-f]+\s+([^\s+]+)(?:\+([0-9A-Fa-f]+))?(?:\s+(.+))?$/);
|
|
82
|
+
if (!match)
|
|
83
|
+
continue;
|
|
84
|
+
const frame = {
|
|
85
|
+
index: Number.parseInt(match[1] ?? "0", 10),
|
|
86
|
+
module: match[2] ?? "(unknown)",
|
|
87
|
+
};
|
|
88
|
+
if (match[3])
|
|
89
|
+
frame.offset = match[3];
|
|
90
|
+
if (match[4]) {
|
|
91
|
+
// Trailing symbol/note. "-> 0" is the indirection arrow; ignore those.
|
|
92
|
+
const trail = match[4].trim();
|
|
93
|
+
if (trail && !trail.startsWith("->"))
|
|
94
|
+
frame.function = trail;
|
|
95
|
+
}
|
|
96
|
+
frames.push(frame);
|
|
97
|
+
}
|
|
98
|
+
return frames;
|
|
99
|
+
}
|
|
100
|
+
// PLUGINS section line shapes:
|
|
101
|
+
// [00] Skyrim.esm
|
|
102
|
+
// [FE 001] LightPlugin.esl
|
|
103
|
+
// [FF] SomeOverride.esp
|
|
104
|
+
function parsePlugins(section) {
|
|
105
|
+
if (!section)
|
|
106
|
+
return [];
|
|
107
|
+
const plugins = [];
|
|
108
|
+
for (const raw of section) {
|
|
109
|
+
const line = raw.trimEnd();
|
|
110
|
+
if (!line)
|
|
111
|
+
continue;
|
|
112
|
+
const match = line.match(/^\s*\[([A-F0-9 ]+)\]\s+(.+)$/i);
|
|
113
|
+
if (!match)
|
|
114
|
+
continue;
|
|
115
|
+
plugins.push({
|
|
116
|
+
loadIndex: (match[1] ?? "").trim(),
|
|
117
|
+
name: (match[2] ?? "").trim(),
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
return plugins;
|
|
121
|
+
}
|
|
122
|
+
// REGISTERS section: "RAX 0xDEADBEEF (type info)" — one per line.
|
|
123
|
+
function parseRegisters(section) {
|
|
124
|
+
if (!section)
|
|
125
|
+
return {};
|
|
126
|
+
const out = {};
|
|
127
|
+
for (const raw of section) {
|
|
128
|
+
const line = raw.trim();
|
|
129
|
+
const match = line.match(/^(R[A-Z0-9]{2,4}|XMM\d+|RIP|RBP|RSP)\s+(\S+)/);
|
|
130
|
+
if (match && match[1] && match[2])
|
|
131
|
+
out[match[1]] = match[2];
|
|
132
|
+
}
|
|
133
|
+
return out;
|
|
134
|
+
}
|
|
135
|
+
// POSSIBLE RELEVANT OBJECTS / RELEVANT OBJECTS list FormIDs and their owning
|
|
136
|
+
// plugin when the crash logger can identify them. Example line:
|
|
137
|
+
// [ 0] 0x000165A8 SomeESP.esp -> Whiterun
|
|
138
|
+
// We extract these as suspectedRefs with the plugin as likelySource.
|
|
139
|
+
function parseRelevantObjects(section) {
|
|
140
|
+
if (!section)
|
|
141
|
+
return [];
|
|
142
|
+
const refs = [];
|
|
143
|
+
for (const raw of section) {
|
|
144
|
+
const line = raw.trim();
|
|
145
|
+
if (!line)
|
|
146
|
+
continue;
|
|
147
|
+
const idMatch = line.match(/0x([0-9A-Fa-f]{6,8})/);
|
|
148
|
+
if (!idMatch)
|
|
149
|
+
continue;
|
|
150
|
+
const ref = {
|
|
151
|
+
type: "formid",
|
|
152
|
+
value: `0x${idMatch[1]}`,
|
|
153
|
+
};
|
|
154
|
+
// Capture the plugin name as the run of chars from after the FormID up to
|
|
155
|
+
// the .esp/.esm/.esl extension. Plugin names contain spaces, so a
|
|
156
|
+
// non-greedy ".+?" is critical — earlier versions used \S+ and clipped
|
|
157
|
+
// multi-word names like "JKs Whiterun Outskirts.esp" to just "Outskirts.esp".
|
|
158
|
+
const after = line.slice(idMatch.index + idMatch[0].length);
|
|
159
|
+
const sourceMatch = after.match(/\s+(.+?\.(?:esp|esm|esl))\b/i);
|
|
160
|
+
if (sourceMatch && sourceMatch[1])
|
|
161
|
+
ref.likelySource = sourceMatch[1].trim();
|
|
162
|
+
refs.push(ref);
|
|
163
|
+
}
|
|
164
|
+
return refs;
|
|
165
|
+
}
|
|
166
|
+
// Scan call stack for FormIDs as a fallback when no RELEVANT OBJECTS section
|
|
167
|
+
// is present. Best-effort only.
|
|
168
|
+
function scanCallStackForFormIds(callStack, rawCallStack) {
|
|
169
|
+
if (!rawCallStack)
|
|
170
|
+
return [];
|
|
171
|
+
const refs = [];
|
|
172
|
+
const seen = new Set();
|
|
173
|
+
for (const line of rawCallStack) {
|
|
174
|
+
const matches = line.matchAll(/0x([0-9A-Fa-f]{6,8})\b/g);
|
|
175
|
+
for (const m of matches) {
|
|
176
|
+
const value = `0x${(m[1] ?? "").toUpperCase()}`;
|
|
177
|
+
// Skip if the value is the exception address — already captured.
|
|
178
|
+
if (value.length < 8)
|
|
179
|
+
continue;
|
|
180
|
+
if (!seen.has(value)) {
|
|
181
|
+
seen.add(value);
|
|
182
|
+
refs.push({ type: "formid", value });
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// Cap to a sane number — call stacks can be hundreds of frames.
|
|
187
|
+
return refs.slice(0, 30);
|
|
188
|
+
}
|
|
189
|
+
function rawSectionsFromMap(sections) {
|
|
190
|
+
const out = {};
|
|
191
|
+
for (const [name, lines] of sections) {
|
|
192
|
+
out[name] = lines.join("\n").trim();
|
|
193
|
+
}
|
|
194
|
+
return out;
|
|
195
|
+
}
|
|
196
|
+
export function parseCrashloggerSse(text, variant) {
|
|
197
|
+
const lines = text.split(/\r?\n/);
|
|
198
|
+
const { preamble, sections } = splitSections(lines);
|
|
199
|
+
const { gameVersion, loggerVersion, exception } = parsePreamble(preamble);
|
|
200
|
+
const callStackLines = sections.get("PROBABLE CALL STACK");
|
|
201
|
+
const callStack = parseCallStack(callStackLines);
|
|
202
|
+
const plugins = parsePlugins(sections.get("PLUGINS"));
|
|
203
|
+
const registers = parseRegisters(sections.get("REGISTERS"));
|
|
204
|
+
const relevant = sections.get("RELEVANT OBJECTS") ?? sections.get("POSSIBLE RELEVANT OBJECTS");
|
|
205
|
+
let suspectedRefs = parseRelevantObjects(relevant);
|
|
206
|
+
if (suspectedRefs.length === 0) {
|
|
207
|
+
suspectedRefs = scanCallStackForFormIds(callStack, callStackLines);
|
|
208
|
+
}
|
|
209
|
+
const result = {
|
|
210
|
+
detectedType: variant,
|
|
211
|
+
exception,
|
|
212
|
+
callStack,
|
|
213
|
+
loadedPlugins: plugins,
|
|
214
|
+
rawSections: rawSectionsFromMap(sections),
|
|
215
|
+
};
|
|
216
|
+
if (gameVersion)
|
|
217
|
+
result.gameVersion = gameVersion;
|
|
218
|
+
if (loggerVersion)
|
|
219
|
+
result.loggerVersion = loggerVersion;
|
|
220
|
+
if (Object.keys(registers).length > 0)
|
|
221
|
+
result.registers = registers;
|
|
222
|
+
if (suspectedRefs.length > 0)
|
|
223
|
+
result.suspectedRefs = suspectedRefs;
|
|
224
|
+
return result;
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=crashlogger-sse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crashlogger-sse.js","sourceRoot":"","sources":["../../src/crashlog/crashlogger-sse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/crashlog/detect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAM/C,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,YAAY,CAAC,EAAE,MAAM,GACpB,YAAY,CAgDd"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Format detection based on first ~50 lines + filename hints. Order matters:
|
|
2
|
+
// Minecraft has the most distinctive header, so check it first; SSE and
|
|
3
|
+
// Buffout 4 are close cousins so we differentiate them by the game-name line.
|
|
4
|
+
export function detectCrashlogType(text, filenameHint) {
|
|
5
|
+
const head = text.split(/\r?\n/, 60).join("\n");
|
|
6
|
+
const headLower = head.toLowerCase();
|
|
7
|
+
if (head.startsWith("---- Minecraft Crash Report ----")) {
|
|
8
|
+
return "minecraft";
|
|
9
|
+
}
|
|
10
|
+
if (headLower.includes("crashloggersse") ||
|
|
11
|
+
/^Skyrim (SSE|VR|AE) /.test(head)) {
|
|
12
|
+
return "crashlogger-sse";
|
|
13
|
+
}
|
|
14
|
+
if (headLower.includes("buffout 4") ||
|
|
15
|
+
headLower.includes("buffout4") ||
|
|
16
|
+
/^Fallout 4 v/m.test(head)) {
|
|
17
|
+
return "buffout4";
|
|
18
|
+
}
|
|
19
|
+
if (headLower.includes("netscriptframework crash log") ||
|
|
20
|
+
headLower.includes("net script framework")) {
|
|
21
|
+
return "netscriptframework";
|
|
22
|
+
}
|
|
23
|
+
// BepInEx LogOutput.log: opens with [Message: BepInEx] or similar
|
|
24
|
+
// bracketed log-level markers.
|
|
25
|
+
if (/^\[(Message|Info|Warning|Error|Fatal|Debug)\s*:\s*/m.test(head)) {
|
|
26
|
+
return "bepinex";
|
|
27
|
+
}
|
|
28
|
+
// Filename fallback — useful when content sniffing fails on a truncated log.
|
|
29
|
+
if (filenameHint) {
|
|
30
|
+
const f = filenameHint.toLowerCase();
|
|
31
|
+
if (f.includes("crash-")) {
|
|
32
|
+
if (f.includes("skyrim"))
|
|
33
|
+
return "crashlogger-sse";
|
|
34
|
+
if (f.includes("fallout"))
|
|
35
|
+
return "buffout4";
|
|
36
|
+
if (f.endsWith(".txt") && f.includes("crash-report"))
|
|
37
|
+
return "minecraft";
|
|
38
|
+
}
|
|
39
|
+
if (f === "logoutput.log" || f.endsWith("/logoutput.log"))
|
|
40
|
+
return "bepinex";
|
|
41
|
+
}
|
|
42
|
+
return "unknown";
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/crashlog/detect.ts"],"names":[],"mappings":"AAEA,6EAA6E;AAC7E,wEAAwE;AACxE,8EAA8E;AAE9E,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,YAAqB;IAErB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAErC,IAAI,IAAI,CAAC,UAAU,CAAC,kCAAkC,CAAC,EAAE,CAAC;QACxD,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IACE,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QACpC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EACjC,CAAC;QACD,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED,IACE,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC;QAC/B,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC9B,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAC1B,CAAC;QACD,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,IACE,SAAS,CAAC,QAAQ,CAAC,8BAA8B,CAAC;QAClD,SAAS,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAC1C,CAAC;QACD,OAAO,oBAAoB,CAAC;IAC9B,CAAC;IAED,oEAAoE;IACpE,+BAA+B;IAC/B,IAAI,qDAAqD,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACrE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,6EAA6E;IAC7E,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,CAAC,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;QACrC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAE,OAAO,iBAAiB,CAAC;YACnD,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAAE,OAAO,UAAU,CAAC;YAC7C,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC;gBAAE,OAAO,WAAW,CAAC;QAC3E,CAAC;QACD,IAAI,CAAC,KAAK,eAAe,IAAI,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC;YAAE,OAAO,SAAS,CAAC;IAC9E,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CrashlogParseResult, CrashlogType } from "./types.js";
|
|
2
|
+
export type ParseCrashlogInput = {
|
|
3
|
+
logContent?: string;
|
|
4
|
+
logPath?: string;
|
|
5
|
+
logType?: CrashlogType | "auto";
|
|
6
|
+
};
|
|
7
|
+
export type ParseCrashlogError = {
|
|
8
|
+
ok: false;
|
|
9
|
+
reason: string;
|
|
10
|
+
};
|
|
11
|
+
export type ParseCrashlogSuccess = CrashlogParseResult & {
|
|
12
|
+
ok: true;
|
|
13
|
+
};
|
|
14
|
+
export declare function parseCrashlog(input: ParseCrashlogInput): ParseCrashlogSuccess | ParseCrashlogError;
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/crashlog/index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEpE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,mBAAmB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,CAAC;AAEtE,wBAAgB,aAAa,CAC3B,KAAK,EAAE,kBAAkB,GACxB,oBAAoB,GAAG,kBAAkB,CA8D3C"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { basename } from "node:path";
|
|
3
|
+
import { pathExists } from "../detect/os.js";
|
|
4
|
+
import { detectCrashlogType } from "./detect.js";
|
|
5
|
+
import { parseCrashloggerSse } from "./crashlogger-sse.js";
|
|
6
|
+
import { parseBepInExLog } from "./bepinex.js";
|
|
7
|
+
import { parseMinecraftCrashReport } from "./minecraft.js";
|
|
8
|
+
import { parseNetScriptFramework } from "./netscriptframework.js";
|
|
9
|
+
export function parseCrashlog(input) {
|
|
10
|
+
let text = input.logContent;
|
|
11
|
+
let filenameHint;
|
|
12
|
+
if (!text) {
|
|
13
|
+
if (!input.logPath) {
|
|
14
|
+
return {
|
|
15
|
+
ok: false,
|
|
16
|
+
reason: "Provide either logContent or logPath.",
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
if (!pathExists(input.logPath)) {
|
|
20
|
+
return {
|
|
21
|
+
ok: false,
|
|
22
|
+
reason: `logPath does not exist: ${input.logPath}`,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
text = readFileSync(input.logPath, "utf8");
|
|
27
|
+
filenameHint = basename(input.logPath);
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
return {
|
|
31
|
+
ok: false,
|
|
32
|
+
reason: `Failed to read logPath: ${err instanceof Error ? err.message : String(err)}`,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (!text || text.trim().length === 0) {
|
|
37
|
+
return { ok: false, reason: "Crashlog content is empty." };
|
|
38
|
+
}
|
|
39
|
+
const declared = input.logType && input.logType !== "auto" ? input.logType : null;
|
|
40
|
+
const detected = declared ?? detectCrashlogType(text, filenameHint);
|
|
41
|
+
let parsed;
|
|
42
|
+
switch (detected) {
|
|
43
|
+
case "crashlogger-sse":
|
|
44
|
+
case "buffout4":
|
|
45
|
+
parsed = parseCrashloggerSse(text, detected);
|
|
46
|
+
break;
|
|
47
|
+
case "bepinex":
|
|
48
|
+
parsed = parseBepInExLog(text);
|
|
49
|
+
break;
|
|
50
|
+
case "minecraft":
|
|
51
|
+
parsed = parseMinecraftCrashReport(text);
|
|
52
|
+
break;
|
|
53
|
+
case "netscriptframework":
|
|
54
|
+
parsed = parseNetScriptFramework(text);
|
|
55
|
+
break;
|
|
56
|
+
default:
|
|
57
|
+
return {
|
|
58
|
+
ok: false,
|
|
59
|
+
reason: "Could not auto-detect the crashlog format. Pass logType explicitly " +
|
|
60
|
+
"(crashlogger-sse, buffout4, netscriptframework, bepinex, or minecraft).",
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
return { ok: true, ...parsed };
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/crashlog/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAgBlE,MAAM,UAAU,aAAa,CAC3B,KAAyB;IAEzB,IAAI,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC;IAC5B,IAAI,YAAgC,CAAC;IAErC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,uCAAuC;aAChD,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/B,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,2BAA2B,KAAK,CAAC,OAAO,EAAE;aACnD,CAAC;QACJ,CAAC;QACD,IAAI,CAAC;YACH,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC3C,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,2BACN,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACjD,EAAE;aACH,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,4BAA4B,EAAE,CAAC;IAC7D,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IAClF,MAAM,QAAQ,GAAG,QAAQ,IAAI,kBAAkB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAEpE,IAAI,MAA2B,CAAC;IAChC,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,iBAAiB,CAAC;QACvB,KAAK,UAAU;YACb,MAAM,GAAG,mBAAmB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC7C,MAAM;QACR,KAAK,SAAS;YACZ,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;YAC/B,MAAM;QACR,KAAK,WAAW;YACd,MAAM,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM;QACR,KAAK,oBAAoB;YACvB,MAAM,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;YACvC,MAAM;QACR;YACE,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,MAAM,EACJ,qEAAqE;oBACrE,yEAAyE;aAC5E,CAAC;IACN,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"minecraft.d.ts","sourceRoot":"","sources":["../../src/crashlog/minecraft.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,mBAAmB,EAEpB,MAAM,YAAY,CAAC;AAqFpB,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,CA0D3E"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// Minecraft crash-report format:
|
|
2
|
+
// ---- Minecraft Crash Report ----
|
|
3
|
+
// // <funny line>
|
|
4
|
+
//
|
|
5
|
+
// Time: 2024-01-15 14:30:00
|
|
6
|
+
// Description: Rendering screen
|
|
7
|
+
//
|
|
8
|
+
// <java exception>
|
|
9
|
+
// <java stack trace>
|
|
10
|
+
//
|
|
11
|
+
// A detailed walkthrough of the error, its code path and all known details is as follows:
|
|
12
|
+
// ---------------------------------------------------------------------------------------
|
|
13
|
+
//
|
|
14
|
+
// -- Head --
|
|
15
|
+
// ...
|
|
16
|
+
// -- Affected level --
|
|
17
|
+
// ...
|
|
18
|
+
// -- System Details --
|
|
19
|
+
// ...
|
|
20
|
+
// -- Mods Loaded -- (Forge/NeoForge)
|
|
21
|
+
// ...
|
|
22
|
+
const DASH_SECTION_REGEX = /^-- (.+) --$/;
|
|
23
|
+
const JAVA_FRAME_REGEX = /^\s*at\s+([^\s(]+)\.([^.\s(]+)\(([^)]*)\)/;
|
|
24
|
+
function splitDashSections(lines) {
|
|
25
|
+
const sections = new Map();
|
|
26
|
+
let current = null;
|
|
27
|
+
let buffer = [];
|
|
28
|
+
for (const line of lines) {
|
|
29
|
+
const match = line.match(DASH_SECTION_REGEX);
|
|
30
|
+
if (match && match[1]) {
|
|
31
|
+
if (current)
|
|
32
|
+
sections.set(current, buffer);
|
|
33
|
+
current = match[1].trim();
|
|
34
|
+
buffer = [];
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (current)
|
|
38
|
+
buffer.push(line);
|
|
39
|
+
}
|
|
40
|
+
if (current)
|
|
41
|
+
sections.set(current, buffer);
|
|
42
|
+
return sections;
|
|
43
|
+
}
|
|
44
|
+
function parseJavaFrames(lines) {
|
|
45
|
+
const frames = [];
|
|
46
|
+
for (const raw of lines) {
|
|
47
|
+
const match = raw.match(JAVA_FRAME_REGEX);
|
|
48
|
+
if (!match)
|
|
49
|
+
continue;
|
|
50
|
+
const fqcn = match[1] ?? "";
|
|
51
|
+
const method = match[2] ?? "";
|
|
52
|
+
const source = match[3] ?? "";
|
|
53
|
+
const frame = {
|
|
54
|
+
module: fqcn.split(".")[0] ?? "(unknown)",
|
|
55
|
+
function: `${fqcn}.${method}`,
|
|
56
|
+
};
|
|
57
|
+
if (source)
|
|
58
|
+
frame.offset = source;
|
|
59
|
+
frames.push(frame);
|
|
60
|
+
}
|
|
61
|
+
return frames;
|
|
62
|
+
}
|
|
63
|
+
function parseModsLoaded(lines) {
|
|
64
|
+
const out = [];
|
|
65
|
+
for (const raw of lines) {
|
|
66
|
+
const line = raw.trim();
|
|
67
|
+
if (!line || line.startsWith("Details:"))
|
|
68
|
+
continue;
|
|
69
|
+
// Forge format: "| ModName | mod_id | 1.0.0 | mod_filename.jar | ... |"
|
|
70
|
+
if (line.startsWith("|")) {
|
|
71
|
+
const parts = line.split("|").map((p) => p.trim()).filter(Boolean);
|
|
72
|
+
if (parts.length >= 3) {
|
|
73
|
+
const entry = { name: parts[1] ?? parts[0] ?? "(unnamed)" };
|
|
74
|
+
out.push(entry);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Fabric / older Forge: "modname-1.2.3.jar"
|
|
79
|
+
if (line.endsWith(".jar")) {
|
|
80
|
+
out.push({ name: line });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return out;
|
|
84
|
+
}
|
|
85
|
+
export function parseMinecraftCrashReport(text) {
|
|
86
|
+
const lines = text.split(/\r?\n/);
|
|
87
|
+
const sections = splitDashSections(lines);
|
|
88
|
+
// Time + Description live before any -- section --
|
|
89
|
+
const headerLines = [];
|
|
90
|
+
for (const line of lines) {
|
|
91
|
+
if (DASH_SECTION_REGEX.test(line))
|
|
92
|
+
break;
|
|
93
|
+
headerLines.push(line);
|
|
94
|
+
}
|
|
95
|
+
let timestamp;
|
|
96
|
+
let description;
|
|
97
|
+
for (const raw of headerLines) {
|
|
98
|
+
const line = raw.trim();
|
|
99
|
+
if (line.startsWith("Time:"))
|
|
100
|
+
timestamp = line.slice(5).trim();
|
|
101
|
+
if (line.startsWith("Description:"))
|
|
102
|
+
description = line.slice(12).trim();
|
|
103
|
+
}
|
|
104
|
+
// Java exception starts somewhere after Description and before "-- Head --"
|
|
105
|
+
// First line that isn't "Time:" / "Description:" / blank / a comment is the
|
|
106
|
+
// exception summary; subsequent indented "at ..." lines are frames.
|
|
107
|
+
const exceptionType = (() => {
|
|
108
|
+
for (const raw of headerLines) {
|
|
109
|
+
const line = raw.trim();
|
|
110
|
+
if (!line || line.startsWith("//"))
|
|
111
|
+
continue;
|
|
112
|
+
if (line.startsWith("Time:") || line.startsWith("Description:"))
|
|
113
|
+
continue;
|
|
114
|
+
if (line.startsWith("at "))
|
|
115
|
+
continue;
|
|
116
|
+
const m = line.match(/^([\w.$]+(?:Exception|Error|Throwable))/);
|
|
117
|
+
if (m && m[1])
|
|
118
|
+
return m[1];
|
|
119
|
+
}
|
|
120
|
+
return undefined;
|
|
121
|
+
})();
|
|
122
|
+
const callStack = parseJavaFrames(headerLines);
|
|
123
|
+
const modsSection = sections.get("Mods Loaded") ?? sections.get("Mods Detected");
|
|
124
|
+
const loadedPlugins = modsSection ? parseModsLoaded(modsSection) : [];
|
|
125
|
+
const rawSections = {};
|
|
126
|
+
for (const [name, content] of sections) {
|
|
127
|
+
rawSections[name] = content.join("\n").trim();
|
|
128
|
+
}
|
|
129
|
+
const exception = {};
|
|
130
|
+
if (exceptionType)
|
|
131
|
+
exception.type = exceptionType;
|
|
132
|
+
if (description)
|
|
133
|
+
exception.description = description;
|
|
134
|
+
const result = {
|
|
135
|
+
detectedType: "minecraft",
|
|
136
|
+
exception,
|
|
137
|
+
callStack,
|
|
138
|
+
loadedPlugins,
|
|
139
|
+
rawSections,
|
|
140
|
+
};
|
|
141
|
+
if (timestamp)
|
|
142
|
+
result.timestamp = timestamp;
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=minecraft.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"minecraft.js","sourceRoot":"","sources":["../../src/crashlog/minecraft.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"netscriptframework.d.ts","sourceRoot":"","sources":["../../src/crashlog/netscriptframework.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,mBAAmB,EAEpB,MAAM,YAAY,CAAC;AAgBpB,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,CAkGzE"}
|