@adhisang/minecraft-modding-mcp 1.0.0
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/CHANGELOG.md +11 -0
- package/LICENSE +21 -0
- package/README.md +765 -0
- package/dist/access-widener-parser.d.ts +24 -0
- package/dist/access-widener-parser.js +77 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +4 -0
- package/dist/config.d.ts +27 -0
- package/dist/config.js +178 -0
- package/dist/decompiler/vineflower.d.ts +15 -0
- package/dist/decompiler/vineflower.js +185 -0
- package/dist/errors.d.ts +50 -0
- package/dist/errors.js +49 -0
- package/dist/hash.d.ts +1 -0
- package/dist/hash.js +12 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +1447 -0
- package/dist/java-process.d.ts +16 -0
- package/dist/java-process.js +120 -0
- package/dist/logger.d.ts +3 -0
- package/dist/logger.js +21 -0
- package/dist/mapping-pipeline-service.d.ts +18 -0
- package/dist/mapping-pipeline-service.js +60 -0
- package/dist/mapping-service.d.ts +161 -0
- package/dist/mapping-service.js +1706 -0
- package/dist/maven-resolver.d.ts +22 -0
- package/dist/maven-resolver.js +122 -0
- package/dist/minecraft-explorer-service.d.ts +43 -0
- package/dist/minecraft-explorer-service.js +562 -0
- package/dist/mixin-parser.d.ts +34 -0
- package/dist/mixin-parser.js +194 -0
- package/dist/mixin-validator.d.ts +59 -0
- package/dist/mixin-validator.js +274 -0
- package/dist/mod-analyzer.d.ts +23 -0
- package/dist/mod-analyzer.js +346 -0
- package/dist/mod-decompile-service.d.ts +39 -0
- package/dist/mod-decompile-service.js +136 -0
- package/dist/mod-remap-service.d.ts +17 -0
- package/dist/mod-remap-service.js +186 -0
- package/dist/mod-search-service.d.ts +28 -0
- package/dist/mod-search-service.js +174 -0
- package/dist/mojang-tiny-mapping-service.d.ts +13 -0
- package/dist/mojang-tiny-mapping-service.js +351 -0
- package/dist/nbt/java-nbt-codec.d.ts +3 -0
- package/dist/nbt/java-nbt-codec.js +385 -0
- package/dist/nbt/json-patch.d.ts +3 -0
- package/dist/nbt/json-patch.js +352 -0
- package/dist/nbt/pipeline.d.ts +39 -0
- package/dist/nbt/pipeline.js +173 -0
- package/dist/nbt/typed-json.d.ts +10 -0
- package/dist/nbt/typed-json.js +205 -0
- package/dist/nbt/types.d.ts +66 -0
- package/dist/nbt/types.js +2 -0
- package/dist/observability.d.ts +88 -0
- package/dist/observability.js +165 -0
- package/dist/path-converter.d.ts +12 -0
- package/dist/path-converter.js +161 -0
- package/dist/path-resolver.d.ts +19 -0
- package/dist/path-resolver.js +78 -0
- package/dist/registry-service.d.ts +29 -0
- package/dist/registry-service.js +214 -0
- package/dist/repo-downloader.d.ts +15 -0
- package/dist/repo-downloader.js +111 -0
- package/dist/resources.d.ts +3 -0
- package/dist/resources.js +154 -0
- package/dist/search-hit-accumulator.d.ts +38 -0
- package/dist/search-hit-accumulator.js +153 -0
- package/dist/source-jar-reader.d.ts +13 -0
- package/dist/source-jar-reader.js +216 -0
- package/dist/source-resolver.d.ts +14 -0
- package/dist/source-resolver.js +274 -0
- package/dist/source-service.d.ts +404 -0
- package/dist/source-service.js +2881 -0
- package/dist/storage/artifacts-repo.d.ts +45 -0
- package/dist/storage/artifacts-repo.js +209 -0
- package/dist/storage/db.d.ts +14 -0
- package/dist/storage/db.js +132 -0
- package/dist/storage/files-repo.d.ts +78 -0
- package/dist/storage/files-repo.js +437 -0
- package/dist/storage/index-meta-repo.d.ts +35 -0
- package/dist/storage/index-meta-repo.js +97 -0
- package/dist/storage/migrations.d.ts +11 -0
- package/dist/storage/migrations.js +71 -0
- package/dist/storage/schema.d.ts +1 -0
- package/dist/storage/schema.js +160 -0
- package/dist/storage/sqlite.d.ts +20 -0
- package/dist/storage/sqlite.js +111 -0
- package/dist/storage/symbols-repo.d.ts +63 -0
- package/dist/storage/symbols-repo.js +401 -0
- package/dist/symbols/symbol-extractor.d.ts +7 -0
- package/dist/symbols/symbol-extractor.js +64 -0
- package/dist/tiny-remapper-resolver.d.ts +1 -0
- package/dist/tiny-remapper-resolver.js +62 -0
- package/dist/tiny-remapper-service.d.ts +16 -0
- package/dist/tiny-remapper-service.js +73 -0
- package/dist/types.d.ts +120 -0
- package/dist/types.js +2 -0
- package/dist/version-diff-service.d.ts +41 -0
- package/dist/version-diff-service.js +222 -0
- package/dist/version-service.d.ts +70 -0
- package/dist/version-service.js +411 -0
- package/dist/vineflower-resolver.d.ts +1 -0
- package/dist/vineflower-resolver.js +62 -0
- package/dist/workspace-mapping-service.d.ts +18 -0
- package/dist/workspace-mapping-service.js +89 -0
- package/package.json +61 -0
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { createError, ERROR_CODES } from "./errors.js";
|
|
5
|
+
import { log } from "./logger.js";
|
|
6
|
+
import { downloadToCache } from "./repo-downloader.js";
|
|
7
|
+
import { VersionService } from "./version-service.js";
|
|
8
|
+
function stripLineInfo(input) {
|
|
9
|
+
let value = input.trim();
|
|
10
|
+
while (/^\d+:\d+:/.test(value)) {
|
|
11
|
+
value = value.replace(/^\d+:\d+:/, "");
|
|
12
|
+
}
|
|
13
|
+
return value.replace(/:\d+:\d+$/, "").trim();
|
|
14
|
+
}
|
|
15
|
+
function normalizeFqn(value) {
|
|
16
|
+
return value.trim().replace(/\//g, ".");
|
|
17
|
+
}
|
|
18
|
+
function normalizeInternalName(value) {
|
|
19
|
+
return value.trim().replace(/\./g, "/");
|
|
20
|
+
}
|
|
21
|
+
function parseProguardMappings(text) {
|
|
22
|
+
const classes = [];
|
|
23
|
+
const members = [];
|
|
24
|
+
let currentClass;
|
|
25
|
+
for (const rawLine of text.split(/\r?\n/)) {
|
|
26
|
+
const line = rawLine.trim();
|
|
27
|
+
if (!line || line.startsWith("#")) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const classMatch = /^(.+?)\s+->\s+(.+):$/.exec(line);
|
|
31
|
+
if (classMatch) {
|
|
32
|
+
const mojangFqn = normalizeFqn(classMatch[1] ?? "");
|
|
33
|
+
const officialInternal = normalizeInternalName(classMatch[2] ?? "");
|
|
34
|
+
if (!mojangFqn || !officialInternal) {
|
|
35
|
+
currentClass = undefined;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
currentClass = mojangFqn;
|
|
39
|
+
classes.push({ mojangFqn, officialInternal });
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (!currentClass) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const arrowIndex = line.indexOf(" -> ");
|
|
46
|
+
if (arrowIndex < 0) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const leftRaw = stripLineInfo(line.slice(0, arrowIndex));
|
|
50
|
+
const officialName = line.slice(arrowIndex + 4).trim();
|
|
51
|
+
if (!leftRaw || !officialName) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
members.push({
|
|
55
|
+
ownerMojangFqn: currentClass,
|
|
56
|
+
leftSignature: leftRaw,
|
|
57
|
+
officialName
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return { classes, members };
|
|
61
|
+
}
|
|
62
|
+
function stripGenericTypes(value) {
|
|
63
|
+
let depth = 0;
|
|
64
|
+
let output = "";
|
|
65
|
+
for (const char of value) {
|
|
66
|
+
if (char === "<") {
|
|
67
|
+
depth += 1;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (char === ">") {
|
|
71
|
+
depth = Math.max(0, depth - 1);
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (depth === 0) {
|
|
75
|
+
output += char;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return output;
|
|
79
|
+
}
|
|
80
|
+
function splitMethodArgs(argList) {
|
|
81
|
+
const trimmed = argList.trim();
|
|
82
|
+
if (!trimmed) {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
const parts = [];
|
|
86
|
+
let depth = 0;
|
|
87
|
+
let current = "";
|
|
88
|
+
for (const char of trimmed) {
|
|
89
|
+
if (char === "<") {
|
|
90
|
+
depth += 1;
|
|
91
|
+
current += char;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (char === ">") {
|
|
95
|
+
depth = Math.max(0, depth - 1);
|
|
96
|
+
current += char;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (char === "," && depth === 0) {
|
|
100
|
+
if (current.trim()) {
|
|
101
|
+
parts.push(current.trim());
|
|
102
|
+
}
|
|
103
|
+
current = "";
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
current += char;
|
|
107
|
+
}
|
|
108
|
+
if (current.trim()) {
|
|
109
|
+
parts.push(current.trim());
|
|
110
|
+
}
|
|
111
|
+
return parts;
|
|
112
|
+
}
|
|
113
|
+
function typeToDescriptor(typeName, classMap) {
|
|
114
|
+
const primitive = {
|
|
115
|
+
byte: "B",
|
|
116
|
+
char: "C",
|
|
117
|
+
double: "D",
|
|
118
|
+
float: "F",
|
|
119
|
+
int: "I",
|
|
120
|
+
long: "J",
|
|
121
|
+
short: "S",
|
|
122
|
+
boolean: "Z",
|
|
123
|
+
void: "V"
|
|
124
|
+
};
|
|
125
|
+
let value = stripGenericTypes(typeName).trim();
|
|
126
|
+
if (!value) {
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
value = value.replace(/\s+/g, "");
|
|
130
|
+
let dimensions = 0;
|
|
131
|
+
while (value.endsWith("[]")) {
|
|
132
|
+
dimensions += 1;
|
|
133
|
+
value = value.slice(0, -2);
|
|
134
|
+
}
|
|
135
|
+
if (value.endsWith("...")) {
|
|
136
|
+
dimensions += 1;
|
|
137
|
+
value = value.slice(0, -3);
|
|
138
|
+
}
|
|
139
|
+
const primitiveDescriptor = primitive[value];
|
|
140
|
+
if (primitiveDescriptor) {
|
|
141
|
+
return `${"[".repeat(dimensions)}${primitiveDescriptor}`;
|
|
142
|
+
}
|
|
143
|
+
const normalized = normalizeFqn(value);
|
|
144
|
+
const internal = classMap.get(normalized) ?? normalized.replace(/\./g, "/");
|
|
145
|
+
return `${"[".repeat(dimensions)}L${internal};`;
|
|
146
|
+
}
|
|
147
|
+
function buildMethodDescriptor(returnType, params, classMap) {
|
|
148
|
+
const paramDescriptors = [];
|
|
149
|
+
for (const param of params) {
|
|
150
|
+
const descriptor = typeToDescriptor(param, classMap);
|
|
151
|
+
if (!descriptor) {
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
paramDescriptors.push(descriptor);
|
|
155
|
+
}
|
|
156
|
+
const returnDescriptor = typeToDescriptor(returnType, classMap);
|
|
157
|
+
if (!returnDescriptor) {
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
160
|
+
return `(${paramDescriptors.join("")})${returnDescriptor}`;
|
|
161
|
+
}
|
|
162
|
+
function normalizeMemberMappings(rawMappings, classMap, warnings) {
|
|
163
|
+
const membersByOwner = new Map();
|
|
164
|
+
const seen = new Set();
|
|
165
|
+
for (const mapping of rawMappings) {
|
|
166
|
+
for (const member of mapping.members) {
|
|
167
|
+
const ownerOfficial = classMap.get(normalizeFqn(member.ownerMojangFqn));
|
|
168
|
+
if (!ownerOfficial) {
|
|
169
|
+
warnings.push(`Skipping member mapping for "${member.ownerMojangFqn}" because class mapping is missing.`);
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
const methodMatch = /^(.+?)\s+([^\s(]+)\((.*)\)$/.exec(member.leftSignature);
|
|
173
|
+
let record;
|
|
174
|
+
if (methodMatch) {
|
|
175
|
+
const returnType = methodMatch[1]?.trim() ?? "";
|
|
176
|
+
const mojangName = methodMatch[2]?.trim() ?? "";
|
|
177
|
+
const params = splitMethodArgs(methodMatch[3] ?? "");
|
|
178
|
+
const descriptor = buildMethodDescriptor(returnType, params, classMap);
|
|
179
|
+
if (!mojangName || !descriptor) {
|
|
180
|
+
warnings.push(`Skipping method mapping "${member.leftSignature}" because descriptor conversion failed.`);
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
record = {
|
|
184
|
+
kind: "m",
|
|
185
|
+
descriptor,
|
|
186
|
+
officialName: member.officialName,
|
|
187
|
+
mojangName
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
const fieldMatch = /^(.+?)\s+([^\s]+)$/.exec(member.leftSignature);
|
|
192
|
+
if (!fieldMatch) {
|
|
193
|
+
warnings.push(`Skipping unsupported member mapping syntax "${member.leftSignature}".`);
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
const fieldType = fieldMatch[1]?.trim() ?? "";
|
|
197
|
+
const mojangName = fieldMatch[2]?.trim() ?? "";
|
|
198
|
+
const descriptor = typeToDescriptor(fieldType, classMap);
|
|
199
|
+
if (!mojangName || !descriptor) {
|
|
200
|
+
warnings.push(`Skipping field mapping "${member.leftSignature}" because descriptor conversion failed.`);
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
record = {
|
|
204
|
+
kind: "f",
|
|
205
|
+
descriptor,
|
|
206
|
+
officialName: member.officialName,
|
|
207
|
+
mojangName
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
const dedupeKey = `${ownerOfficial}|${record.kind}|${record.officialName}|` +
|
|
211
|
+
`${record.mojangName}|${record.descriptor}`;
|
|
212
|
+
if (seen.has(dedupeKey)) {
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
seen.add(dedupeKey);
|
|
216
|
+
const list = membersByOwner.get(ownerOfficial) ?? [];
|
|
217
|
+
list.push(record);
|
|
218
|
+
membersByOwner.set(ownerOfficial, list);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return membersByOwner;
|
|
222
|
+
}
|
|
223
|
+
function mergeClasses(rawMappings, warnings) {
|
|
224
|
+
const classMap = new Map();
|
|
225
|
+
for (const mapping of rawMappings) {
|
|
226
|
+
for (const clazz of mapping.classes) {
|
|
227
|
+
const mojang = normalizeFqn(clazz.mojangFqn);
|
|
228
|
+
const official = normalizeInternalName(clazz.officialInternal);
|
|
229
|
+
const existing = classMap.get(mojang);
|
|
230
|
+
if (existing && existing !== official) {
|
|
231
|
+
warnings.push(`Conflicting class mapping for "${mojang}" (${existing} vs ${official}); keeping first.`);
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
classMap.set(mojang, official);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return classMap;
|
|
238
|
+
}
|
|
239
|
+
function renderTinyV2(classMap, membersByOwner) {
|
|
240
|
+
const classEntries = [...classMap.entries()]
|
|
241
|
+
.map(([mojangFqn, officialInternal]) => ({
|
|
242
|
+
officialInternal,
|
|
243
|
+
mojangInternal: mojangFqn.replace(/\./g, "/")
|
|
244
|
+
}))
|
|
245
|
+
.sort((left, right) => left.officialInternal.localeCompare(right.officialInternal));
|
|
246
|
+
const lines = ["tiny\t2\t0\tofficial\tmojang"];
|
|
247
|
+
for (const entry of classEntries) {
|
|
248
|
+
lines.push(`c\t${entry.officialInternal}\t${entry.mojangInternal}`);
|
|
249
|
+
const members = [...(membersByOwner.get(entry.officialInternal) ?? [])].sort((left, right) => {
|
|
250
|
+
if (left.kind !== right.kind) {
|
|
251
|
+
return left.kind.localeCompare(right.kind);
|
|
252
|
+
}
|
|
253
|
+
if (left.officialName !== right.officialName) {
|
|
254
|
+
return left.officialName.localeCompare(right.officialName);
|
|
255
|
+
}
|
|
256
|
+
return left.descriptor.localeCompare(right.descriptor);
|
|
257
|
+
});
|
|
258
|
+
for (const member of members) {
|
|
259
|
+
lines.push(`\t${member.kind}\t${member.descriptor}\t${member.officialName}\t${member.mojangName}`);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return `${lines.join("\n")}\n`;
|
|
263
|
+
}
|
|
264
|
+
async function ensureMappingsFile(label, version, url, config, fetchFn) {
|
|
265
|
+
if (!url) {
|
|
266
|
+
return { warning: `${label} mappings URL is not available for ${version}.` };
|
|
267
|
+
}
|
|
268
|
+
const destination = join(config.cacheDir, "mappings", version, `${label}_mappings.txt`);
|
|
269
|
+
if (!existsSync(destination)) {
|
|
270
|
+
await mkdir(dirname(destination), { recursive: true });
|
|
271
|
+
const downloaded = await downloadToCache(url, destination, {
|
|
272
|
+
fetchFn,
|
|
273
|
+
retries: config.fetchRetries,
|
|
274
|
+
timeoutMs: config.fetchTimeoutMs
|
|
275
|
+
});
|
|
276
|
+
if (!downloaded.ok || !downloaded.path) {
|
|
277
|
+
return {
|
|
278
|
+
warning: `Failed to download ${label} mappings for ${version} from "${url}" ` +
|
|
279
|
+
`(status: ${downloaded.statusCode ?? "unknown"}).`
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return { path: destination };
|
|
284
|
+
}
|
|
285
|
+
function resolveMappingsUrls(metadata) {
|
|
286
|
+
return {
|
|
287
|
+
clientUrl: metadata.clientMappingsUrl ?? metadata.mappingsUrl,
|
|
288
|
+
serverUrl: metadata.serverMappingsUrl
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
export async function resolveMojangTinyFile(version, config, deps = {}) {
|
|
292
|
+
const cachedTiny = join(config.cacheDir, "mappings", `${version}-mojang-merged.tiny`);
|
|
293
|
+
if (existsSync(cachedTiny)) {
|
|
294
|
+
return { path: cachedTiny, warnings: [] };
|
|
295
|
+
}
|
|
296
|
+
const fetchFn = deps.fetchFn ?? globalThis.fetch;
|
|
297
|
+
const versionService = deps.versionService ?? new VersionService(config, fetchFn);
|
|
298
|
+
const metadata = await versionService.resolveVersionMappings(version);
|
|
299
|
+
const { clientUrl, serverUrl } = resolveMappingsUrls(metadata);
|
|
300
|
+
if (!clientUrl && !serverUrl) {
|
|
301
|
+
throw createError({
|
|
302
|
+
code: ERROR_CODES.MAPPING_UNAVAILABLE,
|
|
303
|
+
message: `Minecraft version "${version}" does not expose Mojang mappings URLs.`,
|
|
304
|
+
details: { version, versionDetailUrl: metadata.versionDetailUrl }
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
const warnings = [];
|
|
308
|
+
const [clientResult, serverResult] = await Promise.all([
|
|
309
|
+
ensureMappingsFile("client", version, clientUrl, config, fetchFn),
|
|
310
|
+
ensureMappingsFile("server", version, serverUrl, config, fetchFn)
|
|
311
|
+
]);
|
|
312
|
+
if (clientResult.warning) {
|
|
313
|
+
warnings.push(clientResult.warning);
|
|
314
|
+
}
|
|
315
|
+
if (serverResult.warning) {
|
|
316
|
+
warnings.push(serverResult.warning);
|
|
317
|
+
}
|
|
318
|
+
const sourcePaths = [clientResult.path, serverResult.path].filter((value) => typeof value === "string");
|
|
319
|
+
if (sourcePaths.length === 0) {
|
|
320
|
+
throw createError({
|
|
321
|
+
code: ERROR_CODES.MAPPING_UNAVAILABLE,
|
|
322
|
+
message: `Failed to retrieve Mojang mappings for "${version}".`,
|
|
323
|
+
details: { version, clientUrl, serverUrl }
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
const parsedMappings = [];
|
|
327
|
+
for (const path of sourcePaths) {
|
|
328
|
+
const content = await readFile(path, "utf8");
|
|
329
|
+
parsedMappings.push(parseProguardMappings(content));
|
|
330
|
+
}
|
|
331
|
+
const classMap = mergeClasses(parsedMappings, warnings);
|
|
332
|
+
if (classMap.size === 0) {
|
|
333
|
+
throw createError({
|
|
334
|
+
code: ERROR_CODES.MAPPING_UNAVAILABLE,
|
|
335
|
+
message: `No class mappings could be parsed for "${version}".`,
|
|
336
|
+
details: { version, sourcePaths }
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
const membersByOwner = normalizeMemberMappings(parsedMappings, classMap, warnings);
|
|
340
|
+
const tinyContent = renderTinyV2(classMap, membersByOwner);
|
|
341
|
+
await mkdir(dirname(cachedTiny), { recursive: true });
|
|
342
|
+
await writeFile(cachedTiny, tinyContent, "utf8");
|
|
343
|
+
log("info", "mojang-tiny.generated", {
|
|
344
|
+
version,
|
|
345
|
+
path: cachedTiny,
|
|
346
|
+
classes: classMap.size,
|
|
347
|
+
warnings: warnings.length
|
|
348
|
+
});
|
|
349
|
+
return { path: cachedTiny, warnings };
|
|
350
|
+
}
|
|
351
|
+
//# sourceMappingURL=mojang-tiny-mapping-service.js.map
|