cajonzero 0.1.3 → 0.2.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/LICENSE +21 -21
- package/README.md +36 -53
- package/dist/bin/cj0.js +2145 -1553
- package/dist/catalog-BRO-mQoP.d.ts +67 -0
- package/dist/{config-B32NDXlr.d.ts → config-glwUbUbx.d.ts} +1 -1
- package/dist/core.d.ts +10 -7
- package/dist/core.js +15035 -312
- package/dist/index.d.ts +7 -5
- package/dist/index.js +31958 -9898
- package/dist/maps.d.ts +182 -0
- package/dist/maps.js +14062 -0
- package/dist/{providers-BwJKzGkd.d.ts → providers-Bu0-iMVs.d.ts} +114 -58
- package/dist/quickjs.wasm +0 -0
- package/dist/scaffold.d.ts +18 -15
- package/dist/scaffold.js +67 -45
- package/dist/serve.d.ts +2 -1
- package/dist/serve.js +32749 -10689
- package/dist/ui/assets/index-Bf4Kjuyg.js +4404 -0
- package/dist/ui/assets/index-ZzhH55rc.css +2 -0
- package/dist/ui/assets/{main-DTcEV4JE.js → main-DB66UjcY.js} +4 -4
- package/dist/ui/assets/{voxel.worker-CvX1GY4o.js → voxel.worker-BFiKMi1W.js} +1 -1
- package/dist/ui/index.html +2 -2
- package/package.json +103 -95
- package/dist/ui/assets/index-Bhv7LV8L.css +0 -2
- package/dist/ui/assets/index-CNHWg0_t.js +0 -4404
package/dist/bin/cj0.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { spawnSync } from 'child_process';
|
|
3
|
-
import {
|
|
3
|
+
import { existsSync, mkdirSync, renameSync, rmSync, cpSync, writeFileSync, readFileSync, mkdtempSync, statSync, readdirSync } from 'fs';
|
|
4
4
|
import { createRequire } from 'module';
|
|
5
|
+
import { tmpdir } from 'os';
|
|
5
6
|
import path4 from 'path';
|
|
6
7
|
import { createInterface } from 'readline/promises';
|
|
7
|
-
import { gzipSync } from 'zlib';
|
|
8
|
+
import { gunzipSync, gzipSync } from 'zlib';
|
|
8
9
|
import { vec3, vec4, vec2, mat3 } from 'gl-matrix';
|
|
9
10
|
import { fileURLToPath } from 'url';
|
|
10
|
-
import {
|
|
11
|
+
import { createHash, randomBytes } from 'crypto';
|
|
11
12
|
|
|
12
13
|
// src/core/maps/catalog.ts
|
|
13
14
|
var MAP_CATALOG_VERSION = 1;
|
|
@@ -65,30 +66,28 @@ function normalizeRootUrl(raw) {
|
|
|
65
66
|
}
|
|
66
67
|
return url.toString();
|
|
67
68
|
}
|
|
68
|
-
function
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
function normalizeRelativeMapRoot(raw) {
|
|
70
|
+
const trimmed = raw.trim();
|
|
71
|
+
if (!trimmed.startsWith("/")) {
|
|
72
|
+
fail("INVALID_ROOT", `map root must start with "/": ${raw}`);
|
|
73
|
+
}
|
|
74
|
+
if (trimmed.includes("\\") || trimmed.includes("\0") || trimmed.includes("?") || trimmed.includes("#")) {
|
|
75
|
+
fail("INVALID_ROOT", `map root contains an unsupported character: ${raw}`);
|
|
71
76
|
}
|
|
72
|
-
if (relPath.startsWith("/")) fail("INVALID_PATH", `absolute map path "${relPath}"`);
|
|
73
77
|
const parts = [];
|
|
74
|
-
for (const part of
|
|
78
|
+
for (const part of trimmed.split("/")) {
|
|
75
79
|
if (part === "" || part === ".") continue;
|
|
76
|
-
if (part === "..") fail("
|
|
80
|
+
if (part === "..") fail("INVALID_ROOT", `map root escapes the site root: ${raw}`);
|
|
77
81
|
parts.push(part);
|
|
78
82
|
}
|
|
79
|
-
if (parts.length === 0) fail("
|
|
80
|
-
return parts.join("/")
|
|
83
|
+
if (parts.length === 0) fail("INVALID_ROOT", "map root must not be the site root");
|
|
84
|
+
return `/${parts.join("/")}/`;
|
|
81
85
|
}
|
|
82
|
-
function
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const url = new URL(relative, base);
|
|
86
|
-
if (url.origin !== base.origin || !url.pathname.startsWith(base.pathname)) {
|
|
87
|
-
fail("INVALID_PATH", `map path escapes the root: "${relPath}"`);
|
|
86
|
+
function normalizeMapRoot(raw) {
|
|
87
|
+
if (typeof raw !== "string" || raw.trim().length === 0) {
|
|
88
|
+
fail("INVALID_ROOT", "map root must be a non-empty URL or path");
|
|
88
89
|
}
|
|
89
|
-
|
|
90
|
-
url.hash = "";
|
|
91
|
-
return url.toString();
|
|
90
|
+
return raw.trim().startsWith("/") ? normalizeRelativeMapRoot(raw) : normalizeRootUrl(raw);
|
|
92
91
|
}
|
|
93
92
|
function optionalString(value, label, code = "INVALID_MAP") {
|
|
94
93
|
if (value === void 0) return void 0;
|
|
@@ -107,7 +106,7 @@ function parseEntry(value, index) {
|
|
|
107
106
|
assertMapSlug(slug);
|
|
108
107
|
const rootRaw = optionalString(record.root, `maps[${index}].root`, "INVALID_ROOT");
|
|
109
108
|
if (rootRaw === void 0) fail("INVALID_ROOT", `maps[${slug}].root is required`);
|
|
110
|
-
const root =
|
|
109
|
+
const root = normalizeMapRoot(rootRaw);
|
|
111
110
|
const worldId = optionalString(record.worldId, `maps[${index}].worldId`);
|
|
112
111
|
const assetRoot = optionalString(record.assetRoot, `maps[${index}].assetRoot`, "INVALID_ROOT");
|
|
113
112
|
const name = optionalString(record.name, `maps[${index}].name`);
|
|
@@ -115,6 +114,7 @@ function parseEntry(value, index) {
|
|
|
115
114
|
const version = optionalString(record.version, `maps[${index}].version`);
|
|
116
115
|
const etag = optionalString(record.etag, `maps[${index}].etag`);
|
|
117
116
|
const cover = optionalString(record.cover, `maps[${index}].cover`);
|
|
117
|
+
const scriptsFile = optionalString(record.scriptsFile, `maps[${index}].scriptsFile`);
|
|
118
118
|
return {
|
|
119
119
|
slug,
|
|
120
120
|
root,
|
|
@@ -124,7 +124,8 @@ function parseEntry(value, index) {
|
|
|
124
124
|
...version !== void 0 ? { version } : {},
|
|
125
125
|
...etag !== void 0 ? { etag } : {},
|
|
126
126
|
...cover !== void 0 ? { cover } : {},
|
|
127
|
-
...assetRoot !== void 0 ? { assetRoot:
|
|
127
|
+
...assetRoot !== void 0 ? { assetRoot: normalizeMapRoot(assetRoot) } : {},
|
|
128
|
+
...scriptsFile !== void 0 ? { scriptsFile } : {}
|
|
128
129
|
};
|
|
129
130
|
}
|
|
130
131
|
function parseMapCatalog(input) {
|
|
@@ -151,6 +152,167 @@ function parseMapCatalog(input) {
|
|
|
151
152
|
function findMap(catalog, slug) {
|
|
152
153
|
return catalog.maps.find((entry) => entry.slug === slug);
|
|
153
154
|
}
|
|
155
|
+
var BOXPLAY_FORMAT_VERSION = 1;
|
|
156
|
+
var BOXPLAY_BUNDLE_TYPE = "map-group-play-bundle";
|
|
157
|
+
var DEFAULT_BOXPLAY_LIMITS = {
|
|
158
|
+
maxExpandedBytes: 2 * 1024 * 1024 * 1024,
|
|
159
|
+
maxEntries: 2e5
|
|
160
|
+
};
|
|
161
|
+
var BoxplayError = class extends Error {
|
|
162
|
+
code;
|
|
163
|
+
constructor(code, message) {
|
|
164
|
+
super(message);
|
|
165
|
+
this.name = "BoxplayError";
|
|
166
|
+
this.code = code;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
var decoder = new TextDecoder();
|
|
170
|
+
function fail2(code, message) {
|
|
171
|
+
throw new BoxplayError(code, message);
|
|
172
|
+
}
|
|
173
|
+
function cString(block, offset, length) {
|
|
174
|
+
let end = offset;
|
|
175
|
+
const limit = Math.min(offset + length, block.length);
|
|
176
|
+
while (end < limit && block[end] !== 0) end += 1;
|
|
177
|
+
return decoder.decode(block.subarray(offset, end));
|
|
178
|
+
}
|
|
179
|
+
function octal(block, offset, length) {
|
|
180
|
+
const value = parseInt(cString(block, offset, length).replace(/[\0 ]/g, ""), 8);
|
|
181
|
+
return Number.isNaN(value) ? 0 : value;
|
|
182
|
+
}
|
|
183
|
+
function isZero(block) {
|
|
184
|
+
for (const byte of block) if (byte !== 0) return false;
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
function normalizeArchivePath(raw) {
|
|
188
|
+
if (raw.includes("\0") || raw.includes("\\")) fail2("UNSAFE_PATH", `invalid path: ${raw}`);
|
|
189
|
+
if (raw.startsWith("/") || /^[a-zA-Z]:/.test(raw)) fail2("UNSAFE_PATH", `absolute path: ${raw}`);
|
|
190
|
+
const parts = [];
|
|
191
|
+
for (const part of raw.split("/")) {
|
|
192
|
+
if (part === "" || part === ".") continue;
|
|
193
|
+
if (part === "..") fail2("UNSAFE_PATH", `path escapes the archive: ${raw}`);
|
|
194
|
+
parts.push(part);
|
|
195
|
+
}
|
|
196
|
+
if (parts.length === 0) fail2("UNSAFE_PATH", "empty archive path");
|
|
197
|
+
return parts.join("/");
|
|
198
|
+
}
|
|
199
|
+
function* parseTar(tar, limits = DEFAULT_BOXPLAY_LIMITS) {
|
|
200
|
+
let offset = 0;
|
|
201
|
+
let count = 0;
|
|
202
|
+
let longName = null;
|
|
203
|
+
while (offset + 512 <= tar.length) {
|
|
204
|
+
const header = tar.subarray(offset, offset + 512);
|
|
205
|
+
if (isZero(header)) break;
|
|
206
|
+
const name = cString(header, 0, 100);
|
|
207
|
+
const size = octal(header, 124, 12);
|
|
208
|
+
const typeflag = String.fromCharCode(header[156] ?? 0);
|
|
209
|
+
const prefix = cString(header, 345, 155);
|
|
210
|
+
const dataStart = offset + 512;
|
|
211
|
+
const dataEnd = dataStart + size;
|
|
212
|
+
if (dataEnd > tar.length) fail2("CORRUPT", `entry overruns archive: ${name}`);
|
|
213
|
+
count += 1;
|
|
214
|
+
if (count > limits.maxEntries) {
|
|
215
|
+
fail2("TOO_MANY_FILES", `archive exceeds ${limits.maxEntries} entries`);
|
|
216
|
+
}
|
|
217
|
+
const data = tar.subarray(dataStart, dataEnd);
|
|
218
|
+
offset = dataStart + Math.ceil(size / 512) * 512;
|
|
219
|
+
if (typeflag === "L") {
|
|
220
|
+
longName = decoder.decode(data).replace(/\0+$/, "");
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
const resolved = longName ?? (prefix ? `${prefix}/${name}` : name);
|
|
224
|
+
longName = null;
|
|
225
|
+
if (typeflag === "5") {
|
|
226
|
+
yield { path: normalizeArchivePath(resolved), kind: "dir" };
|
|
227
|
+
} else if (typeflag === "0" || typeflag === "\0") {
|
|
228
|
+
yield { path: normalizeArchivePath(resolved), kind: "file", data };
|
|
229
|
+
} else {
|
|
230
|
+
fail2("UNSUPPORTED_ENTRY", `unsupported tar entry ${typeflag}: ${resolved}`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
function parseBoxplayBytes(input, limits = DEFAULT_BOXPLAY_LIMITS) {
|
|
235
|
+
if (input.length < 2 || input[0] !== 31 || input[1] !== 139) {
|
|
236
|
+
fail2("NOT_GZIP", "not a gzip stream");
|
|
237
|
+
}
|
|
238
|
+
let tar;
|
|
239
|
+
try {
|
|
240
|
+
tar = gunzipSync(input);
|
|
241
|
+
} catch (error) {
|
|
242
|
+
fail2("CORRUPT", `gzip failed: ${error.message}`);
|
|
243
|
+
}
|
|
244
|
+
if (tar.length > limits.maxExpandedBytes) {
|
|
245
|
+
fail2("TOO_LARGE", `archive expands to ${tar.length} bytes`);
|
|
246
|
+
}
|
|
247
|
+
const files = [];
|
|
248
|
+
const manifests = /* @__PURE__ */ new Map();
|
|
249
|
+
const dataFiles = /* @__PURE__ */ new Map();
|
|
250
|
+
let bundleBytes = null;
|
|
251
|
+
for (const entry of parseTar(tar, limits)) {
|
|
252
|
+
if (entry.kind === "dir") continue;
|
|
253
|
+
files.push({ path: entry.path, data: entry.data, size: entry.data.length });
|
|
254
|
+
if (entry.path === "bundle.json") {
|
|
255
|
+
bundleBytes = entry.data;
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
const manifest = /^worlds\/([^/]+)\/manifest\.json$/.exec(entry.path);
|
|
259
|
+
if (manifest) {
|
|
260
|
+
const worldId = manifest[1];
|
|
261
|
+
const parsed = JSON.parse(decoder.decode(entry.data));
|
|
262
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
263
|
+
fail2("MISSING_WORLD", `worlds/${worldId}/manifest.json is not an object`);
|
|
264
|
+
}
|
|
265
|
+
manifests.set(worldId, parsed);
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
const data = /^worlds\/([^/]+)\/data\/(.+)$/.exec(entry.path);
|
|
269
|
+
if (data) {
|
|
270
|
+
const worldId = data[1];
|
|
271
|
+
const list = dataFiles.get(worldId) ?? [];
|
|
272
|
+
list.push(entry.path);
|
|
273
|
+
dataFiles.set(worldId, list);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
if (bundleBytes === null) fail2("MISSING_BUNDLE", "archive has no bundle.json");
|
|
277
|
+
let bundle;
|
|
278
|
+
try {
|
|
279
|
+
const raw = JSON.parse(decoder.decode(bundleBytes));
|
|
280
|
+
if (typeof raw !== "object" || raw === null) throw new Error("not an object");
|
|
281
|
+
const value = raw;
|
|
282
|
+
if (value.formatVersion !== BOXPLAY_FORMAT_VERSION) throw new Error("bad formatVersion");
|
|
283
|
+
if (value.type !== BOXPLAY_BUNDLE_TYPE) throw new Error("bad type");
|
|
284
|
+
bundle = {
|
|
285
|
+
...value,
|
|
286
|
+
formatVersion: BOXPLAY_FORMAT_VERSION,
|
|
287
|
+
type: BOXPLAY_BUNDLE_TYPE,
|
|
288
|
+
mapGroupId: String(value.mapGroupId),
|
|
289
|
+
version: String(value.version),
|
|
290
|
+
members: Array.isArray(value.members) ? value.members : []
|
|
291
|
+
};
|
|
292
|
+
} catch (error) {
|
|
293
|
+
fail2("INVALID_BUNDLE", `invalid bundle.json: ${error.message}`);
|
|
294
|
+
}
|
|
295
|
+
if (manifests.size === 0) fail2("MISSING_WORLD", "archive has no world manifest");
|
|
296
|
+
return {
|
|
297
|
+
bundle,
|
|
298
|
+
worlds: [...manifests].map(([worldId, manifest]) => ({
|
|
299
|
+
worldId,
|
|
300
|
+
manifest,
|
|
301
|
+
dataFiles: (dataFiles.get(worldId) ?? []).sort()
|
|
302
|
+
})),
|
|
303
|
+
files,
|
|
304
|
+
expandedBytes: tar.length
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
function readBoxplayFile(file, limits = DEFAULT_BOXPLAY_LIMITS) {
|
|
308
|
+
let bytes;
|
|
309
|
+
try {
|
|
310
|
+
bytes = readFileSync(file);
|
|
311
|
+
} catch (error) {
|
|
312
|
+
fail2("CORRUPT", `cannot read ${file}: ${error.message}`);
|
|
313
|
+
}
|
|
314
|
+
return parseBoxplayBytes(bytes, limits);
|
|
315
|
+
}
|
|
154
316
|
|
|
155
317
|
// src/vendor/mudb/schema/void.ts
|
|
156
318
|
var MuVoid = class {
|
|
@@ -2339,631 +2501,975 @@ var MuDate = class {
|
|
|
2339
2501
|
}
|
|
2340
2502
|
};
|
|
2341
2503
|
|
|
2342
|
-
// src/vendor/mudb/box-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
while (l < h) {
|
|
2356
|
-
const m = interpolate(objects, l, h, id);
|
|
2357
|
-
const x = objects[m].id;
|
|
2358
|
-
if (x === id) {
|
|
2359
|
-
return m;
|
|
2360
|
-
} else if (x < id) {
|
|
2361
|
-
l = m + 1;
|
|
2362
|
-
} else {
|
|
2363
|
-
h = m - 1;
|
|
2364
|
-
}
|
|
2504
|
+
// src/vendor/mudb/box-schema/content-server/index.ts
|
|
2505
|
+
var HashSchema = new MuASCII();
|
|
2506
|
+
|
|
2507
|
+
// src/vendor/mudb/box-schema/utils/ref-schema.ts
|
|
2508
|
+
var _noSerialize = () => {
|
|
2509
|
+
throw new Error("cannot serialize references");
|
|
2510
|
+
};
|
|
2511
|
+
var MuRefSchema = class {
|
|
2512
|
+
identity = null;
|
|
2513
|
+
muType = "ref";
|
|
2514
|
+
muData = { type: "ref" };
|
|
2515
|
+
json = { type: "ref" };
|
|
2516
|
+
constructor() {
|
|
2365
2517
|
}
|
|
2366
|
-
|
|
2367
|
-
|
|
2518
|
+
diff = _noSerialize;
|
|
2519
|
+
patch = _noSerialize;
|
|
2520
|
+
toJSON = _noSerialize;
|
|
2521
|
+
fromJSON = _noSerialize;
|
|
2522
|
+
alloc() {
|
|
2523
|
+
return null;
|
|
2368
2524
|
}
|
|
2369
|
-
|
|
2370
|
-
}
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
const
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2525
|
+
free() {
|
|
2526
|
+
}
|
|
2527
|
+
assign(dst, src) {
|
|
2528
|
+
return src;
|
|
2529
|
+
}
|
|
2530
|
+
clone(x) {
|
|
2531
|
+
return x;
|
|
2532
|
+
}
|
|
2533
|
+
equal(a, b) {
|
|
2534
|
+
return a === b;
|
|
2535
|
+
}
|
|
2536
|
+
};
|
|
2537
|
+
|
|
2538
|
+
// src/vendor/mudb/box-schema/utils/relative-array.ts
|
|
2539
|
+
var RelativeArray = class {
|
|
2540
|
+
identity;
|
|
2541
|
+
muType = "relative array";
|
|
2542
|
+
muData;
|
|
2543
|
+
json;
|
|
2544
|
+
arraySchema;
|
|
2545
|
+
alloc;
|
|
2546
|
+
free;
|
|
2547
|
+
clone;
|
|
2548
|
+
equal;
|
|
2549
|
+
assign;
|
|
2550
|
+
toJSON;
|
|
2551
|
+
fromJSON;
|
|
2552
|
+
constructor(schema, capacity, identity2) {
|
|
2553
|
+
const arraySchema = this.arraySchema = new MuArray(
|
|
2554
|
+
schema,
|
|
2555
|
+
capacity,
|
|
2556
|
+
identity2
|
|
2557
|
+
);
|
|
2558
|
+
this.json = {
|
|
2559
|
+
type: "relative array",
|
|
2560
|
+
value: schema.json
|
|
2561
|
+
};
|
|
2562
|
+
this.muData = schema;
|
|
2563
|
+
this.identity = arraySchema.identity;
|
|
2564
|
+
this.alloc = arraySchema.alloc;
|
|
2565
|
+
this.free = arraySchema.free;
|
|
2566
|
+
this.clone = arraySchema.clone;
|
|
2567
|
+
this.equal = arraySchema.equal;
|
|
2568
|
+
this.assign = arraySchema.assign;
|
|
2569
|
+
this.toJSON = arraySchema.toJSON;
|
|
2570
|
+
this.fromJSON = arraySchema.fromJSON;
|
|
2571
|
+
}
|
|
2572
|
+
diff(base, target, stream) {
|
|
2573
|
+
const prefixOffset = stream.offset;
|
|
2574
|
+
const targetLength = target.length;
|
|
2575
|
+
const numTrackers = Math.ceil(targetLength / 8);
|
|
2576
|
+
stream.grow(4 + numTrackers);
|
|
2577
|
+
stream.writeUint32(targetLength);
|
|
2578
|
+
let trackerOffset = stream.offset;
|
|
2579
|
+
stream.offset = trackerOffset + numTrackers;
|
|
2580
|
+
let tracker = 0;
|
|
2581
|
+
let numPatch = 0;
|
|
2582
|
+
const baseLength = base.length;
|
|
2583
|
+
const valueSchema = this.muData;
|
|
2584
|
+
let prev = base.length > 0 ? base[0] : valueSchema.identity;
|
|
2585
|
+
for (let i = 0; i < target.length; ++i) {
|
|
2586
|
+
if (valueSchema.diff(prev, target[i], stream)) {
|
|
2587
|
+
tracker |= 1 << (i & 7);
|
|
2588
|
+
++numPatch;
|
|
2589
|
+
}
|
|
2590
|
+
if ((i & 7) === 7) {
|
|
2591
|
+
stream.writeUint8At(trackerOffset++, tracker);
|
|
2592
|
+
tracker = 0;
|
|
2593
|
+
}
|
|
2594
|
+
prev = target[i];
|
|
2414
2595
|
}
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
patch: (base, inp) => {
|
|
2418
|
-
const v = vec3Pool.pop() || vec3.create();
|
|
2419
|
-
const flags = inp.readUint8();
|
|
2420
|
-
v[0] = flags & 1 ? inp.readFloat32() : base[0];
|
|
2421
|
-
v[1] = flags & 2 ? inp.readFloat32() : base[1];
|
|
2422
|
-
v[2] = flags & 4 ? inp.readFloat32() : base[2];
|
|
2423
|
-
return v;
|
|
2424
|
-
},
|
|
2425
|
-
clone: (v) => {
|
|
2426
|
-
const x = vec3Pool.pop();
|
|
2427
|
-
if (x) {
|
|
2428
|
-
x[0] = v[0];
|
|
2429
|
-
x[1] = v[1];
|
|
2430
|
-
x[2] = v[2];
|
|
2431
|
-
return x;
|
|
2596
|
+
if (targetLength & 7) {
|
|
2597
|
+
stream.writeUint8At(trackerOffset, tracker);
|
|
2432
2598
|
}
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
toJSON: (v) => [v[0], v[1], v[2]],
|
|
2436
|
-
fromJSON: (json) => {
|
|
2437
|
-
let v = vec3Pool.pop();
|
|
2438
|
-
if (Array.isArray(json)) {
|
|
2439
|
-
v = v || vec3.create();
|
|
2440
|
-
v[0] = +json[0] || 0;
|
|
2441
|
-
v[1] = +json[1] || 0;
|
|
2442
|
-
v[2] = +json[2] || 0;
|
|
2443
|
-
return v;
|
|
2444
|
-
} else if (v) {
|
|
2445
|
-
v[0] = v[1] = v[2] = 0;
|
|
2446
|
-
return v;
|
|
2447
|
-
} else {
|
|
2448
|
-
return vec3.create();
|
|
2599
|
+
if (numPatch > 0 || baseLength !== targetLength) {
|
|
2600
|
+
return true;
|
|
2449
2601
|
}
|
|
2602
|
+
stream.offset = prefixOffset;
|
|
2603
|
+
return false;
|
|
2450
2604
|
}
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
return dst;
|
|
2472
|
-
},
|
|
2473
|
-
equal: (dst, src) => {
|
|
2474
|
-
return dst[0] === src[0] && dst[1] === src[1] && dst[2] === src[2] && dst[3] === src[3];
|
|
2475
|
-
},
|
|
2476
|
-
diff: (base, target, out) => {
|
|
2477
|
-
const s0 = (base[0] !== target[0]) << 0;
|
|
2478
|
-
const s1 = (base[1] !== target[1]) << 1;
|
|
2479
|
-
const s2 = (base[2] !== target[2]) << 2;
|
|
2480
|
-
const s3 = (base[3] !== target[3]) << 3;
|
|
2481
|
-
const flags = s0 + s1 + s2 + s3;
|
|
2482
|
-
if (flags === 0) {
|
|
2483
|
-
return false;
|
|
2484
|
-
}
|
|
2485
|
-
out.grow(17);
|
|
2486
|
-
out.writeUint8(flags);
|
|
2487
|
-
if (s0) {
|
|
2488
|
-
out.writeFloat32(target[0]);
|
|
2489
|
-
}
|
|
2490
|
-
if (s1) {
|
|
2491
|
-
out.writeFloat32(target[1]);
|
|
2492
|
-
}
|
|
2493
|
-
if (s2) {
|
|
2494
|
-
out.writeFloat32(target[2]);
|
|
2495
|
-
}
|
|
2496
|
-
if (s3) {
|
|
2497
|
-
out.writeFloat32(target[3]);
|
|
2498
|
-
}
|
|
2499
|
-
return true;
|
|
2500
|
-
},
|
|
2501
|
-
patch: (base, inp) => {
|
|
2502
|
-
const v = vec4Pool.pop() || vec4.create();
|
|
2503
|
-
const flags = inp.readUint8();
|
|
2504
|
-
v[0] = flags & 1 ? inp.readFloat32() : base[0];
|
|
2505
|
-
v[1] = flags & 2 ? inp.readFloat32() : base[1];
|
|
2506
|
-
v[2] = flags & 4 ? inp.readFloat32() : base[2];
|
|
2507
|
-
v[3] = flags & 8 ? inp.readFloat32() : base[3];
|
|
2508
|
-
return v;
|
|
2509
|
-
},
|
|
2510
|
-
clone: (v) => {
|
|
2511
|
-
const x = vec4Pool.pop();
|
|
2512
|
-
if (x) {
|
|
2513
|
-
x[0] = v[0];
|
|
2514
|
-
x[1] = v[1];
|
|
2515
|
-
x[2] = v[2];
|
|
2516
|
-
x[3] = v[3];
|
|
2517
|
-
return x;
|
|
2518
|
-
}
|
|
2519
|
-
return vec4.clone(v);
|
|
2520
|
-
},
|
|
2521
|
-
toJSON: (v) => [v[0], v[1], v[2], v[3]],
|
|
2522
|
-
fromJSON: (json) => {
|
|
2523
|
-
let v = vec4Pool.pop();
|
|
2524
|
-
if (Array.isArray(json)) {
|
|
2525
|
-
v = v || vec4.create();
|
|
2526
|
-
v[0] = +json[0] || 0;
|
|
2527
|
-
v[1] = +json[1] || 0;
|
|
2528
|
-
v[2] = +json[2] || 0;
|
|
2529
|
-
v[3] = +json[3] || 0;
|
|
2530
|
-
return v;
|
|
2531
|
-
} else if (v) {
|
|
2532
|
-
v[0] = v[1] = v[2] = v[3] = 0;
|
|
2533
|
-
return v;
|
|
2534
|
-
} else {
|
|
2535
|
-
return vec4.create();
|
|
2605
|
+
patch(base, stream) {
|
|
2606
|
+
const result = this.clone(base);
|
|
2607
|
+
const targetLength = stream.readUint32();
|
|
2608
|
+
result.length = targetLength;
|
|
2609
|
+
let trackerOffset = stream.offset;
|
|
2610
|
+
const numTrackers = Math.ceil(targetLength / 8);
|
|
2611
|
+
stream.offset = trackerOffset + numTrackers;
|
|
2612
|
+
let tracker = 0;
|
|
2613
|
+
const valueSchema = this.muData;
|
|
2614
|
+
let prev = base.length > 0 ? base[0] : valueSchema.identity;
|
|
2615
|
+
for (let i = 0; i < targetLength; ++i) {
|
|
2616
|
+
const mod8 = i & 7;
|
|
2617
|
+
if (!mod8) {
|
|
2618
|
+
tracker = stream.readUint8At(trackerOffset++);
|
|
2619
|
+
}
|
|
2620
|
+
if (1 << mod8 & tracker) {
|
|
2621
|
+
prev = result[i] = valueSchema.patch(prev, stream);
|
|
2622
|
+
} else {
|
|
2623
|
+
result[i] = valueSchema.clone(prev);
|
|
2624
|
+
}
|
|
2536
2625
|
}
|
|
2626
|
+
return result;
|
|
2537
2627
|
}
|
|
2538
2628
|
};
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
var
|
|
2629
|
+
|
|
2630
|
+
// src/vendor/mudb/box-schema/voxel/block-schema.ts
|
|
2631
|
+
var BlockInfoSchema = new MuStruct({
|
|
2632
|
+
// voxel info
|
|
2633
|
+
ids: new RelativeArray(new MuRelativeVarint(), Infinity, [0]),
|
|
2634
|
+
names: new MuArray(new MuUTF8(), Infinity, ["air"]),
|
|
2635
|
+
// run length encode these arrays
|
|
2636
|
+
emissive: new RelativeArray(new MuVarint(), Infinity, [0]),
|
|
2637
|
+
texture: new RelativeArray(
|
|
2638
|
+
new MuRelativeVarint(),
|
|
2639
|
+
Infinity,
|
|
2640
|
+
[0, 0, 0, 0, 0, 0]
|
|
2641
|
+
),
|
|
2642
|
+
animLength: new RelativeArray(new MuVarint(1), Infinity, [1, 1, 1, 1, 1, 1]),
|
|
2643
|
+
friction: new RelativeArray(new MuQuantizedFloat(1 / 256, 1), Infinity, [0]),
|
|
2644
|
+
restitution: new RelativeArray(new MuQuantizedFloat(1 / 256, 0), Infinity, [
|
|
2645
|
+
0
|
|
2646
|
+
]),
|
|
2647
|
+
velocity: new RelativeArray(new MuFloat32(0), Infinity, [0, 0, 0]),
|
|
2648
|
+
// fluids
|
|
2649
|
+
fluids: new MuArray(
|
|
2650
|
+
new MuStruct({
|
|
2651
|
+
id: new MuVarint(),
|
|
2652
|
+
info: new MuUint32(),
|
|
2653
|
+
mass: new MuFloat64(1)
|
|
2654
|
+
}),
|
|
2655
|
+
Infinity,
|
|
2656
|
+
[
|
|
2657
|
+
{
|
|
2658
|
+
id: 0,
|
|
2659
|
+
info: 0,
|
|
2660
|
+
mass: 0
|
|
2661
|
+
}
|
|
2662
|
+
]
|
|
2663
|
+
),
|
|
2664
|
+
// category list
|
|
2665
|
+
category: new MuDictionary(
|
|
2666
|
+
new RelativeArray(new MuRelativeVarint(), Infinity),
|
|
2667
|
+
Infinity,
|
|
2668
|
+
{
|
|
2669
|
+
default: [0]
|
|
2670
|
+
}
|
|
2671
|
+
),
|
|
2672
|
+
// texture info
|
|
2673
|
+
atlasRadius: new MuVarint(16),
|
|
2674
|
+
blockBumpShift: new MuVarint(6),
|
|
2675
|
+
blockColorShift: new MuVarint(4),
|
|
2676
|
+
// texture atlases
|
|
2677
|
+
colorAtlas: new MuArray(HashSchema, Infinity),
|
|
2678
|
+
materialAtlas: new MuArray(HashSchema, Infinity),
|
|
2679
|
+
bumpAtlas: new MuArray(HashSchema, Infinity)
|
|
2680
|
+
});
|
|
2542
2681
|
new MuStruct({
|
|
2543
|
-
|
|
2544
|
-
|
|
2682
|
+
id: new MuDictionary(new MuVarint(), Infinity, { air: 0 }),
|
|
2683
|
+
valid: new MuArray(new MuBoolean(false), Infinity),
|
|
2684
|
+
name: new MuArray(new MuUTF8(), Infinity, ["air"]),
|
|
2685
|
+
emissive: new MuArray(new MuUint16(), Infinity, [0]),
|
|
2686
|
+
texture: new MuArray(new MuUint32(), Infinity, [0, 0, 0, 0, 0, 0]),
|
|
2687
|
+
mass: new MuArray(new MuFloat64(), Infinity, [0]),
|
|
2688
|
+
restitution: new MuArray(new MuFloat64(), Infinity, [0]),
|
|
2689
|
+
friction: new MuArray(new MuFloat64(), Infinity, [0]),
|
|
2690
|
+
fluid: new MuArray(new MuVarint(), Infinity, [1]),
|
|
2691
|
+
fluidInfo: new MuArray(new MuUint32(), Infinity, [0, 0]),
|
|
2692
|
+
velocity: new MuArray(new MuFloat32(0), Infinity, [0, 0, 0]),
|
|
2693
|
+
isFluid: new MuRefSchema()
|
|
2545
2694
|
});
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2695
|
+
var decodeUTF8;
|
|
2696
|
+
{
|
|
2697
|
+
new TextEncoder();
|
|
2698
|
+
const decoder2 = new TextDecoder();
|
|
2699
|
+
decodeUTF8 = (bytes) => decoder2.decode(bytes);
|
|
2700
|
+
}
|
|
2701
|
+
var MuBuffer = class {
|
|
2702
|
+
buffer;
|
|
2703
|
+
dataView;
|
|
2704
|
+
uint8;
|
|
2705
|
+
constructor(buffer) {
|
|
2706
|
+
this.buffer = buffer;
|
|
2707
|
+
this.dataView = new DataView(buffer);
|
|
2708
|
+
this.uint8 = new Uint8Array(buffer);
|
|
2555
2709
|
}
|
|
2556
|
-
|
|
2557
|
-
|
|
2710
|
+
};
|
|
2711
|
+
var bufferPool = new Array(31);
|
|
2712
|
+
for (let i = 0; i < 31; ++i) {
|
|
2713
|
+
bufferPool[i] = [];
|
|
2714
|
+
}
|
|
2715
|
+
var LITTLE_ENDIAN = true;
|
|
2716
|
+
var MuReadStream = class {
|
|
2717
|
+
buffer;
|
|
2718
|
+
offset;
|
|
2719
|
+
length;
|
|
2720
|
+
constructor(data) {
|
|
2721
|
+
this.buffer = new MuBuffer(data.buffer);
|
|
2722
|
+
this.offset = data.byteOffset;
|
|
2723
|
+
this.length = data.byteLength + data.byteOffset;
|
|
2558
2724
|
}
|
|
2559
|
-
|
|
2725
|
+
bytes() {
|
|
2726
|
+
return this.buffer.uint8.subarray(this.offset, this.length);
|
|
2560
2727
|
}
|
|
2561
|
-
|
|
2562
|
-
|
|
2728
|
+
checkBounds() {
|
|
2729
|
+
if (this.offset > this.length) {
|
|
2730
|
+
throw new Error("out of bounds");
|
|
2731
|
+
}
|
|
2563
2732
|
}
|
|
2564
|
-
|
|
2565
|
-
|
|
2733
|
+
readInt8() {
|
|
2734
|
+
const offset = this.offset;
|
|
2735
|
+
this.offset += 1;
|
|
2736
|
+
this.checkBounds();
|
|
2737
|
+
return this.buffer.dataView.getInt8(offset);
|
|
2566
2738
|
}
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
actionMeta = {
|
|
2573
|
-
type: "table",
|
|
2574
|
-
table: {}
|
|
2575
|
-
};
|
|
2576
|
-
action = {};
|
|
2577
|
-
emptyStore;
|
|
2578
|
-
constructor(stateSchema) {
|
|
2579
|
-
this.stateSchema = stateSchema;
|
|
2580
|
-
this.storeSchema = stateSchema;
|
|
2581
|
-
this.emptyStore = new MuRDAConstantStore(stateSchema.identity);
|
|
2739
|
+
readInt16() {
|
|
2740
|
+
const offset = this.offset;
|
|
2741
|
+
this.offset += 2;
|
|
2742
|
+
this.checkBounds();
|
|
2743
|
+
return this.buffer.dataView.getInt16(offset, LITTLE_ENDIAN);
|
|
2582
2744
|
}
|
|
2583
|
-
|
|
2584
|
-
|
|
2745
|
+
readInt32() {
|
|
2746
|
+
const offset = this.offset;
|
|
2747
|
+
this.offset += 4;
|
|
2748
|
+
this.checkBounds();
|
|
2749
|
+
return this.buffer.dataView.getInt32(offset, LITTLE_ENDIAN);
|
|
2585
2750
|
}
|
|
2586
|
-
|
|
2587
|
-
|
|
2751
|
+
readUint8() {
|
|
2752
|
+
const offset = this.offset;
|
|
2753
|
+
this.offset += 1;
|
|
2754
|
+
this.checkBounds();
|
|
2755
|
+
return this.buffer.dataView.getUint8(offset);
|
|
2588
2756
|
}
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
}
|
|
2595
|
-
var MuRDARegisterStore = class {
|
|
2596
|
-
value;
|
|
2597
|
-
constructor(initial) {
|
|
2598
|
-
this.value = initial;
|
|
2599
|
-
}
|
|
2600
|
-
state(rda, out) {
|
|
2601
|
-
return rda.stateSchema.assign(out, this.value);
|
|
2757
|
+
readUint16() {
|
|
2758
|
+
const offset = this.offset;
|
|
2759
|
+
this.offset += 2;
|
|
2760
|
+
this.checkBounds();
|
|
2761
|
+
return this.buffer.dataView.getUint16(offset, LITTLE_ENDIAN);
|
|
2602
2762
|
}
|
|
2603
|
-
|
|
2604
|
-
|
|
2763
|
+
readUint32() {
|
|
2764
|
+
const offset = this.offset;
|
|
2765
|
+
this.offset += 4;
|
|
2766
|
+
this.checkBounds();
|
|
2767
|
+
return this.buffer.dataView.getUint32(offset, LITTLE_ENDIAN);
|
|
2605
2768
|
}
|
|
2606
|
-
|
|
2607
|
-
|
|
2769
|
+
readFloat32() {
|
|
2770
|
+
const offset = this.offset;
|
|
2771
|
+
this.offset += 4;
|
|
2772
|
+
this.checkBounds();
|
|
2773
|
+
return this.buffer.dataView.getFloat32(offset, LITTLE_ENDIAN);
|
|
2608
2774
|
}
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2775
|
+
readFloat64() {
|
|
2776
|
+
const offset = this.offset;
|
|
2777
|
+
this.offset += 8;
|
|
2778
|
+
this.checkBounds();
|
|
2779
|
+
return this.buffer.dataView.getFloat64(offset, LITTLE_ENDIAN);
|
|
2612
2780
|
}
|
|
2613
|
-
|
|
2614
|
-
|
|
2781
|
+
readVarint() {
|
|
2782
|
+
const bytes = this.buffer.uint8;
|
|
2783
|
+
let offset = this.offset;
|
|
2784
|
+
const x0 = bytes[offset++];
|
|
2785
|
+
if (x0 < 128) {
|
|
2786
|
+
this.offset = offset;
|
|
2787
|
+
this.checkBounds();
|
|
2788
|
+
return x0;
|
|
2789
|
+
}
|
|
2790
|
+
const x1 = bytes[offset++];
|
|
2791
|
+
if (x1 < 128) {
|
|
2792
|
+
this.offset = offset;
|
|
2793
|
+
this.checkBounds();
|
|
2794
|
+
return x0 & 127 | x1 << 7;
|
|
2795
|
+
}
|
|
2796
|
+
const x2 = bytes[offset++];
|
|
2797
|
+
if (x2 < 128) {
|
|
2798
|
+
this.offset = offset;
|
|
2799
|
+
this.checkBounds();
|
|
2800
|
+
return x0 & 127 | (x1 & 127) << 7 | x2 << 14;
|
|
2801
|
+
}
|
|
2802
|
+
const x3 = bytes[offset++];
|
|
2803
|
+
if (x3 < 128) {
|
|
2804
|
+
this.offset = offset;
|
|
2805
|
+
this.checkBounds();
|
|
2806
|
+
return x0 & 127 | (x1 & 127) << 7 | (x2 & 127) << 14 | x3 << 21;
|
|
2807
|
+
}
|
|
2808
|
+
const x4 = bytes[offset++];
|
|
2809
|
+
this.offset = offset;
|
|
2810
|
+
this.checkBounds();
|
|
2811
|
+
return (x0 & 127) + ((x1 & 127) << 7) + ((x2 & 127) << 14) + ((x3 & 127) << 21) + x4 * (1 << 28);
|
|
2615
2812
|
}
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
emptyStore;
|
|
2626
|
-
constrain;
|
|
2627
|
-
constructor(stateSchema, constrain) {
|
|
2628
|
-
this.stateSchema = this.actionSchema = this.storeSchema = stateSchema;
|
|
2629
|
-
this.constrain = constrain || identity;
|
|
2630
|
-
this.emptyStore = new MuRDARegisterStore(stateSchema.identity);
|
|
2813
|
+
readASCII(length) {
|
|
2814
|
+
const head = this.offset;
|
|
2815
|
+
this.offset += length;
|
|
2816
|
+
this.checkBounds();
|
|
2817
|
+
let str = "";
|
|
2818
|
+
for (let i = head; i < this.offset; ++i) {
|
|
2819
|
+
str += String.fromCharCode(this.buffer.uint8[i]);
|
|
2820
|
+
}
|
|
2821
|
+
return str;
|
|
2631
2822
|
}
|
|
2632
|
-
|
|
2633
|
-
|
|
2823
|
+
readString() {
|
|
2824
|
+
const byteLength = this.readVarint();
|
|
2825
|
+
const head = this.offset;
|
|
2826
|
+
this.offset += byteLength;
|
|
2827
|
+
this.checkBounds();
|
|
2828
|
+
const bytes = this.buffer.uint8.subarray(head, this.offset);
|
|
2829
|
+
return decodeUTF8(bytes);
|
|
2634
2830
|
}
|
|
2635
|
-
|
|
2636
|
-
return
|
|
2831
|
+
readUint8At(offset) {
|
|
2832
|
+
return this.buffer.dataView.getUint8(offset);
|
|
2637
2833
|
}
|
|
2638
2834
|
};
|
|
2639
2835
|
|
|
2640
|
-
// src/
|
|
2641
|
-
var
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2836
|
+
// src/core/maps/block-info.ts
|
|
2837
|
+
var BLOCK_INFO_HASH = "QmW2E9E8ipYUifsCfkMj5SULYMYbFQvP6BQxo52atXw7Zj";
|
|
2838
|
+
async function readBlockInfoBytes(reader, worldId, hash = BLOCK_INFO_HASH) {
|
|
2839
|
+
try {
|
|
2840
|
+
const bytes = await reader.read(`worlds/${worldId}/data/blobs/${hash}`);
|
|
2841
|
+
if (bytes === null || bytes.length === 0) return null;
|
|
2842
|
+
return bytes;
|
|
2843
|
+
} catch {
|
|
2844
|
+
return null;
|
|
2645
2845
|
}
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2846
|
+
}
|
|
2847
|
+
|
|
2848
|
+
// src/vendor/mudb/box-utils/id.ts
|
|
2849
|
+
function compareId(a, b) {
|
|
2850
|
+
return a.id - b.id;
|
|
2851
|
+
}
|
|
2852
|
+
function interpolate(objects, l, h, id) {
|
|
2853
|
+
const a = objects[l].id;
|
|
2854
|
+
const b = objects[h].id;
|
|
2855
|
+
const t = (id - a) / (b - a);
|
|
2856
|
+
return Math.max(l, Math.min(h, Math.round((1 - t) * l + t * h) | 0));
|
|
2857
|
+
}
|
|
2858
|
+
function indexEqRange(objects, id, _l, _h) {
|
|
2859
|
+
let l = _l;
|
|
2860
|
+
let h = _h;
|
|
2861
|
+
while (l < h) {
|
|
2862
|
+
const m = interpolate(objects, l, h, id);
|
|
2863
|
+
const x = objects[m].id;
|
|
2864
|
+
if (x === id) {
|
|
2865
|
+
return m;
|
|
2866
|
+
} else if (x < id) {
|
|
2867
|
+
l = m + 1;
|
|
2868
|
+
} else {
|
|
2869
|
+
h = m - 1;
|
|
2651
2870
|
}
|
|
2652
|
-
return out;
|
|
2653
|
-
}
|
|
2654
|
-
apply(rda, action) {
|
|
2655
|
-
return this.stores[action.type].apply(rda.rdas[action.type], action.data);
|
|
2656
2871
|
}
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
result.type = action.type;
|
|
2660
|
-
result.data = this.stores[action.type].inverse(
|
|
2661
|
-
rda.rdas[action.type],
|
|
2662
|
-
action.data
|
|
2663
|
-
);
|
|
2664
|
-
return result;
|
|
2872
|
+
if (l === h && objects[l].id === id) {
|
|
2873
|
+
return l;
|
|
2665
2874
|
}
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2875
|
+
return -1;
|
|
2876
|
+
}
|
|
2877
|
+
new MuFloat32();
|
|
2878
|
+
var Vec2Schema = new MuVector(new MuFloat32(), 2);
|
|
2879
|
+
var vec3Pool = [];
|
|
2880
|
+
var Vec3Schema = {
|
|
2881
|
+
muType: "vector",
|
|
2882
|
+
identity: vec3.create(),
|
|
2883
|
+
json: {
|
|
2884
|
+
type: "vector",
|
|
2885
|
+
data: [0, 0, 0]
|
|
2886
|
+
},
|
|
2887
|
+
alloc: () => {
|
|
2888
|
+
return vec3Pool.pop() || vec3.create();
|
|
2889
|
+
},
|
|
2890
|
+
free: (v) => {
|
|
2891
|
+
vec3Pool.push(v);
|
|
2892
|
+
},
|
|
2893
|
+
assign: (dst, src) => {
|
|
2894
|
+
dst[0] = src[0];
|
|
2895
|
+
dst[1] = src[1];
|
|
2896
|
+
dst[2] = src[2];
|
|
2897
|
+
return dst;
|
|
2898
|
+
},
|
|
2899
|
+
equal: (dst, src) => {
|
|
2900
|
+
return dst[0] === src[0] && dst[1] === src[1] && dst[2] === src[2];
|
|
2901
|
+
},
|
|
2902
|
+
diff: (base, target, out) => {
|
|
2903
|
+
const s0 = (base[0] !== target[0]) << 0;
|
|
2904
|
+
const s1 = (base[1] !== target[1]) << 1;
|
|
2905
|
+
const s2 = (base[2] !== target[2]) << 2;
|
|
2906
|
+
const flags = s0 + s1 + s2;
|
|
2907
|
+
if (flags === 0) {
|
|
2908
|
+
return false;
|
|
2671
2909
|
}
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
for (let i = 0; i < ids.length; ++i) {
|
|
2677
|
-
const id = ids[i];
|
|
2678
|
-
this.stores[id].free(rda.rdas[id]);
|
|
2910
|
+
out.grow(13);
|
|
2911
|
+
out.writeUint8(flags);
|
|
2912
|
+
if (s0) {
|
|
2913
|
+
out.writeFloat32(target[0]);
|
|
2679
2914
|
}
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
var MuRDAStruct = class {
|
|
2683
|
-
rdas;
|
|
2684
|
-
stateSchema;
|
|
2685
|
-
actionSchema;
|
|
2686
|
-
storeSchema;
|
|
2687
|
-
actionMeta;
|
|
2688
|
-
action;
|
|
2689
|
-
emptyStore;
|
|
2690
|
-
_saveStore = null;
|
|
2691
|
-
_wrapDispatch(id, rda) {
|
|
2692
|
-
const self = this;
|
|
2693
|
-
function wrapPartial(root, dispatch) {
|
|
2694
|
-
const savedPartial = { data: null };
|
|
2695
|
-
function wrapPartialRec(meta, index) {
|
|
2696
|
-
if (meta.type === "unit") {
|
|
2697
|
-
return new Function(
|
|
2698
|
-
"rda",
|
|
2699
|
-
"partial",
|
|
2700
|
-
`/* ${id}:${index} */ return function() { var result = rda.actionSchema.alloc(); result.type = "${id}"; result.data = partial.data${index}.apply(null, arguments); return result; }`
|
|
2701
|
-
)(self, savedPartial);
|
|
2702
|
-
} else if (meta.type === "table") {
|
|
2703
|
-
const result = {};
|
|
2704
|
-
const keys = Object.keys(meta.table);
|
|
2705
|
-
for (let i = 0; i < keys.length; ++i) {
|
|
2706
|
-
const key = keys[i];
|
|
2707
|
-
result[key] = wrapPartialRec(meta.table[key], `${index}["${key}"]`);
|
|
2708
|
-
}
|
|
2709
|
-
return result;
|
|
2710
|
-
} else if (meta.type === "partial") {
|
|
2711
|
-
return wrapPartial(
|
|
2712
|
-
meta.action,
|
|
2713
|
-
new Function(
|
|
2714
|
-
"partial",
|
|
2715
|
-
`/* ${id}:${index} */ return function () { return partial.data${index}.apply(null, arguments); }`
|
|
2716
|
-
)(savedPartial)
|
|
2717
|
-
);
|
|
2718
|
-
}
|
|
2719
|
-
return {};
|
|
2720
|
-
}
|
|
2721
|
-
return new Function(
|
|
2722
|
-
"dispatch",
|
|
2723
|
-
"partial",
|
|
2724
|
-
"wrappedDispatch",
|
|
2725
|
-
`/* ${id} */ return function () { partial.data = dispatch.apply(null, arguments); return wrappedDispatch; }`
|
|
2726
|
-
)(dispatch, savedPartial, wrapPartialRec(root, ""));
|
|
2915
|
+
if (s1) {
|
|
2916
|
+
out.writeFloat32(target[1]);
|
|
2727
2917
|
}
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
return function(...args) {
|
|
2731
|
-
const result = self.actionSchema.alloc();
|
|
2732
|
-
result.type = id;
|
|
2733
|
-
result.data = dispatch.apply(null, args);
|
|
2734
|
-
return result;
|
|
2735
|
-
};
|
|
2736
|
-
} else if (meta.type === "table") {
|
|
2737
|
-
const result = {};
|
|
2738
|
-
const ids = Object.keys(meta.table);
|
|
2739
|
-
for (let i = 0; i < ids.length; ++i) {
|
|
2740
|
-
const key = ids[i];
|
|
2741
|
-
result[key] = wrapAction(meta.table[key], dispatch);
|
|
2742
|
-
}
|
|
2743
|
-
return result;
|
|
2744
|
-
} else if (meta.type === "partial") {
|
|
2745
|
-
return wrapPartial(meta.action, dispatch);
|
|
2746
|
-
}
|
|
2747
|
-
return {};
|
|
2918
|
+
if (s2) {
|
|
2919
|
+
out.writeFloat32(target[2]);
|
|
2748
2920
|
}
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
meta.action,
|
|
2767
|
-
new Function(
|
|
2768
|
-
"rda",
|
|
2769
|
-
"dispatch",
|
|
2770
|
-
`/* ${id}:${index} */ return function() { return dispatch(rda._saveStore.stores["${id}"])${index}.apply(null, arguments); }`
|
|
2771
|
-
)(self, rda.action)
|
|
2772
|
-
);
|
|
2773
|
-
}
|
|
2774
|
-
return {};
|
|
2921
|
+
return true;
|
|
2922
|
+
},
|
|
2923
|
+
patch: (base, inp) => {
|
|
2924
|
+
const v = vec3Pool.pop() || vec3.create();
|
|
2925
|
+
const flags = inp.readUint8();
|
|
2926
|
+
v[0] = flags & 1 ? inp.readFloat32() : base[0];
|
|
2927
|
+
v[1] = flags & 2 ? inp.readFloat32() : base[1];
|
|
2928
|
+
v[2] = flags & 4 ? inp.readFloat32() : base[2];
|
|
2929
|
+
return v;
|
|
2930
|
+
},
|
|
2931
|
+
clone: (v) => {
|
|
2932
|
+
const x = vec3Pool.pop();
|
|
2933
|
+
if (x) {
|
|
2934
|
+
x[0] = v[0];
|
|
2935
|
+
x[1] = v[1];
|
|
2936
|
+
x[2] = v[2];
|
|
2937
|
+
return x;
|
|
2775
2938
|
}
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2939
|
+
return vec3.clone(v);
|
|
2940
|
+
},
|
|
2941
|
+
toJSON: (v) => [v[0], v[1], v[2]],
|
|
2942
|
+
fromJSON: (json) => {
|
|
2943
|
+
let v = vec3Pool.pop();
|
|
2944
|
+
if (Array.isArray(json)) {
|
|
2945
|
+
v = v || vec3.create();
|
|
2946
|
+
v[0] = +json[0] || 0;
|
|
2947
|
+
v[1] = +json[1] || 0;
|
|
2948
|
+
v[2] = +json[2] || 0;
|
|
2949
|
+
return v;
|
|
2950
|
+
} else if (v) {
|
|
2951
|
+
v[0] = v[1] = v[2] = 0;
|
|
2952
|
+
return v;
|
|
2779
2953
|
} else {
|
|
2780
|
-
|
|
2781
|
-
return wrapStore(rda.actionMeta.action, "");
|
|
2954
|
+
return vec3.create();
|
|
2782
2955
|
}
|
|
2783
2956
|
}
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2957
|
+
};
|
|
2958
|
+
var vec4Pool = [];
|
|
2959
|
+
var Vec4Schema = {
|
|
2960
|
+
muType: "vector",
|
|
2961
|
+
identity: vec4.create(),
|
|
2962
|
+
json: {
|
|
2963
|
+
type: "vector",
|
|
2964
|
+
data: [0, 0, 0, 0]
|
|
2965
|
+
},
|
|
2966
|
+
alloc: () => {
|
|
2967
|
+
return vec4Pool.pop() || vec4.create();
|
|
2968
|
+
},
|
|
2969
|
+
free: (v) => {
|
|
2970
|
+
vec4Pool.push(v);
|
|
2971
|
+
},
|
|
2972
|
+
assign: (dst, src) => {
|
|
2973
|
+
dst[0] = src[0];
|
|
2974
|
+
dst[1] = src[1];
|
|
2975
|
+
dst[2] = src[2];
|
|
2976
|
+
dst[3] = src[3];
|
|
2977
|
+
return dst;
|
|
2978
|
+
},
|
|
2979
|
+
equal: (dst, src) => {
|
|
2980
|
+
return dst[0] === src[0] && dst[1] === src[1] && dst[2] === src[2] && dst[3] === src[3];
|
|
2981
|
+
},
|
|
2982
|
+
diff: (base, target, out) => {
|
|
2983
|
+
const s0 = (base[0] !== target[0]) << 0;
|
|
2984
|
+
const s1 = (base[1] !== target[1]) << 1;
|
|
2985
|
+
const s2 = (base[2] !== target[2]) << 2;
|
|
2986
|
+
const s3 = (base[3] !== target[3]) << 3;
|
|
2987
|
+
const flags = s0 + s1 + s2 + s3;
|
|
2988
|
+
if (flags === 0) {
|
|
2989
|
+
return false;
|
|
2798
2990
|
}
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
this.actionMeta = {
|
|
2804
|
-
type: "store",
|
|
2805
|
-
action: {
|
|
2806
|
-
type: "table",
|
|
2807
|
-
table: {}
|
|
2808
|
-
}
|
|
2809
|
-
};
|
|
2810
|
-
const storeDispatch = {};
|
|
2811
|
-
for (let i = 0; i < props.length; ++i) {
|
|
2812
|
-
const prop = props[i];
|
|
2813
|
-
storeDispatch[prop] = this._wrapDispatch(prop, spec[prop]);
|
|
2991
|
+
out.grow(17);
|
|
2992
|
+
out.writeUint8(flags);
|
|
2993
|
+
if (s0) {
|
|
2994
|
+
out.writeFloat32(target[0]);
|
|
2814
2995
|
}
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
return storeDispatch;
|
|
2818
|
-
});
|
|
2819
|
-
}
|
|
2820
|
-
createStore(state) {
|
|
2821
|
-
const stores = {};
|
|
2822
|
-
const ids = Object.keys(this.rdas);
|
|
2823
|
-
for (let i = 0; i < ids.length; ++i) {
|
|
2824
|
-
const id = ids[i];
|
|
2825
|
-
stores[id] = this.rdas[id].createStore(state[id]);
|
|
2996
|
+
if (s1) {
|
|
2997
|
+
out.writeFloat32(target[1]);
|
|
2826
2998
|
}
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2999
|
+
if (s2) {
|
|
3000
|
+
out.writeFloat32(target[2]);
|
|
3001
|
+
}
|
|
3002
|
+
if (s3) {
|
|
3003
|
+
out.writeFloat32(target[3]);
|
|
3004
|
+
}
|
|
3005
|
+
return true;
|
|
3006
|
+
},
|
|
3007
|
+
patch: (base, inp) => {
|
|
3008
|
+
const v = vec4Pool.pop() || vec4.create();
|
|
3009
|
+
const flags = inp.readUint8();
|
|
3010
|
+
v[0] = flags & 1 ? inp.readFloat32() : base[0];
|
|
3011
|
+
v[1] = flags & 2 ? inp.readFloat32() : base[1];
|
|
3012
|
+
v[2] = flags & 4 ? inp.readFloat32() : base[2];
|
|
3013
|
+
v[3] = flags & 8 ? inp.readFloat32() : base[3];
|
|
3014
|
+
return v;
|
|
3015
|
+
},
|
|
3016
|
+
clone: (v) => {
|
|
3017
|
+
const x = vec4Pool.pop();
|
|
3018
|
+
if (x) {
|
|
3019
|
+
x[0] = v[0];
|
|
3020
|
+
x[1] = v[1];
|
|
3021
|
+
x[2] = v[2];
|
|
3022
|
+
x[3] = v[3];
|
|
3023
|
+
return x;
|
|
3024
|
+
}
|
|
3025
|
+
return vec4.clone(v);
|
|
3026
|
+
},
|
|
3027
|
+
toJSON: (v) => [v[0], v[1], v[2], v[3]],
|
|
3028
|
+
fromJSON: (json) => {
|
|
3029
|
+
let v = vec4Pool.pop();
|
|
3030
|
+
if (Array.isArray(json)) {
|
|
3031
|
+
v = v || vec4.create();
|
|
3032
|
+
v[0] = +json[0] || 0;
|
|
3033
|
+
v[1] = +json[1] || 0;
|
|
3034
|
+
v[2] = +json[2] || 0;
|
|
3035
|
+
v[3] = +json[3] || 0;
|
|
3036
|
+
return v;
|
|
3037
|
+
} else if (v) {
|
|
3038
|
+
v[0] = v[1] = v[2] = v[3] = 0;
|
|
3039
|
+
return v;
|
|
3040
|
+
} else {
|
|
3041
|
+
return vec4.create();
|
|
2835
3042
|
}
|
|
2836
|
-
return new MuRDAStructStore(stores);
|
|
2837
3043
|
}
|
|
2838
3044
|
};
|
|
3045
|
+
var QuatSchema = Vec4Schema;
|
|
3046
|
+
new MuVector(new MuFloat32(), 9);
|
|
3047
|
+
var Mat4Schema = new MuVector(new MuFloat32(), 16);
|
|
3048
|
+
new MuStruct({
|
|
3049
|
+
lo: Vec3Schema,
|
|
3050
|
+
hi: Vec3Schema
|
|
3051
|
+
});
|
|
2839
3052
|
|
|
2840
|
-
// src/vendor/mudb/rda/
|
|
2841
|
-
|
|
2842
|
-
return a < b ? -1 : b < a ? 1 : 0;
|
|
2843
|
-
}
|
|
2844
|
-
function compareStoreElements(a, b) {
|
|
2845
|
-
return a.sequence - b.sequence || a.id - b.id;
|
|
2846
|
-
}
|
|
2847
|
-
function compareNum(a, b) {
|
|
2848
|
-
return a - b;
|
|
2849
|
-
}
|
|
2850
|
-
var MuRDAMapStoreElement = class {
|
|
2851
|
-
constructor(id, sequence, deleted, key, value) {
|
|
2852
|
-
this.id = id;
|
|
2853
|
-
this.sequence = sequence;
|
|
2854
|
-
this.deleted = deleted;
|
|
2855
|
-
this.key = key;
|
|
2856
|
-
this.value = value;
|
|
2857
|
-
}
|
|
2858
|
-
id;
|
|
2859
|
-
sequence;
|
|
2860
|
-
deleted;
|
|
2861
|
-
key;
|
|
3053
|
+
// src/vendor/mudb/rda/constant.ts
|
|
3054
|
+
var MuRDAConstantStore = class {
|
|
2862
3055
|
value;
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
3056
|
+
constructor(initial) {
|
|
3057
|
+
this.value = initial;
|
|
3058
|
+
}
|
|
3059
|
+
state(rda, out) {
|
|
3060
|
+
return rda.stateSchema.assign(out, this.value);
|
|
3061
|
+
}
|
|
3062
|
+
apply() {
|
|
3063
|
+
return false;
|
|
3064
|
+
}
|
|
3065
|
+
inverse() {
|
|
3066
|
+
}
|
|
3067
|
+
serialize(rda, out) {
|
|
3068
|
+
return rda.storeSchema.assign(out, this.value);
|
|
3069
|
+
}
|
|
3070
|
+
free(rda) {
|
|
3071
|
+
rda.stateSchema.free(this.value);
|
|
3072
|
+
}
|
|
2866
3073
|
};
|
|
2867
|
-
var
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
3074
|
+
var MuRDAConstant = class {
|
|
3075
|
+
stateSchema;
|
|
3076
|
+
actionSchema = new MuVoid();
|
|
3077
|
+
storeSchema;
|
|
3078
|
+
actionMeta = {
|
|
3079
|
+
type: "table",
|
|
3080
|
+
table: {}
|
|
3081
|
+
};
|
|
3082
|
+
action = {};
|
|
3083
|
+
emptyStore;
|
|
3084
|
+
constructor(stateSchema) {
|
|
3085
|
+
this.stateSchema = stateSchema;
|
|
3086
|
+
this.storeSchema = stateSchema;
|
|
3087
|
+
this.emptyStore = new MuRDAConstantStore(stateSchema.identity);
|
|
3088
|
+
}
|
|
3089
|
+
createStore(initialState) {
|
|
3090
|
+
return new MuRDAConstantStore(this.stateSchema.clone(initialState));
|
|
3091
|
+
}
|
|
3092
|
+
parse(store) {
|
|
3093
|
+
return new MuRDAConstantStore(this.stateSchema.clone(store));
|
|
3094
|
+
}
|
|
3095
|
+
};
|
|
3096
|
+
|
|
3097
|
+
// src/vendor/mudb/rda/register.ts
|
|
3098
|
+
function identity(x) {
|
|
3099
|
+
return x;
|
|
3100
|
+
}
|
|
3101
|
+
var MuRDARegisterStore = class {
|
|
3102
|
+
value;
|
|
3103
|
+
constructor(initial) {
|
|
3104
|
+
this.value = initial;
|
|
2878
3105
|
}
|
|
2879
3106
|
state(rda, out) {
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
3107
|
+
return rda.stateSchema.assign(out, this.value);
|
|
3108
|
+
}
|
|
3109
|
+
inverse(rda) {
|
|
3110
|
+
return rda.actionSchema.clone(this.value);
|
|
3111
|
+
}
|
|
3112
|
+
free(rda) {
|
|
3113
|
+
rda.stateSchema.free(this.value);
|
|
3114
|
+
}
|
|
3115
|
+
apply(rda, action) {
|
|
3116
|
+
this.value = rda.stateSchema.assign(this.value, rda.constrain(action));
|
|
3117
|
+
return true;
|
|
3118
|
+
}
|
|
3119
|
+
serialize(rda, out) {
|
|
3120
|
+
return rda.storeSchema.assign(out, this.value);
|
|
3121
|
+
}
|
|
3122
|
+
};
|
|
3123
|
+
var MuRDARegister = class {
|
|
3124
|
+
stateSchema;
|
|
3125
|
+
actionSchema;
|
|
3126
|
+
storeSchema;
|
|
3127
|
+
actionMeta = { type: "unit" };
|
|
3128
|
+
action = (value) => {
|
|
3129
|
+
return this.actionSchema.clone(this.constrain(value));
|
|
3130
|
+
};
|
|
3131
|
+
emptyStore;
|
|
3132
|
+
constrain;
|
|
3133
|
+
constructor(stateSchema, constrain) {
|
|
3134
|
+
this.stateSchema = this.actionSchema = this.storeSchema = stateSchema;
|
|
3135
|
+
this.constrain = constrain || identity;
|
|
3136
|
+
this.emptyStore = new MuRDARegisterStore(stateSchema.identity);
|
|
3137
|
+
}
|
|
3138
|
+
createStore(initialState) {
|
|
3139
|
+
return new MuRDARegisterStore(this.stateSchema.clone(initialState));
|
|
3140
|
+
}
|
|
3141
|
+
parse(store) {
|
|
3142
|
+
return new MuRDARegisterStore(this.stateSchema.clone(store));
|
|
3143
|
+
}
|
|
3144
|
+
};
|
|
3145
|
+
|
|
3146
|
+
// src/vendor/mudb/rda/struct.ts
|
|
3147
|
+
var MuRDAStructStore = class {
|
|
3148
|
+
stores;
|
|
3149
|
+
constructor(stores) {
|
|
3150
|
+
this.stores = stores;
|
|
3151
|
+
}
|
|
3152
|
+
state(rda, out) {
|
|
3153
|
+
const ids = Object.keys(this.stores);
|
|
3154
|
+
for (let i = 0; i < ids.length; ++i) {
|
|
3155
|
+
const id = ids[i];
|
|
3156
|
+
out[id] = this.stores[id].state(rda.rdas[id], out[id]);
|
|
2899
3157
|
}
|
|
2900
3158
|
return out;
|
|
2901
3159
|
}
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
const
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
3160
|
+
apply(rda, action) {
|
|
3161
|
+
return this.stores[action.type].apply(rda.rdas[action.type], action.data);
|
|
3162
|
+
}
|
|
3163
|
+
inverse(rda, action) {
|
|
3164
|
+
const result = rda.actionSchema.alloc();
|
|
3165
|
+
result.type = action.type;
|
|
3166
|
+
result.data = this.stores[action.type].inverse(
|
|
3167
|
+
rda.rdas[action.type],
|
|
3168
|
+
action.data
|
|
3169
|
+
);
|
|
3170
|
+
return result;
|
|
3171
|
+
}
|
|
3172
|
+
serialize(rda, out) {
|
|
3173
|
+
const ids = Object.keys(this.stores);
|
|
3174
|
+
for (let i = 0; i < ids.length; ++i) {
|
|
3175
|
+
const id = ids[i];
|
|
3176
|
+
out[id] = this.stores[id].serialize(rda.rdas[id], out[id]);
|
|
2919
3177
|
}
|
|
2920
|
-
|
|
2921
|
-
|
|
3178
|
+
return out;
|
|
3179
|
+
}
|
|
3180
|
+
free(rda) {
|
|
3181
|
+
const ids = Object.keys(this.stores);
|
|
3182
|
+
for (let i = 0; i < ids.length; ++i) {
|
|
3183
|
+
const id = ids[i];
|
|
3184
|
+
this.stores[id].free(rda.rdas[id]);
|
|
2922
3185
|
}
|
|
2923
|
-
element.next = element.prev = null;
|
|
2924
|
-
element.key = key;
|
|
2925
|
-
this._insertElement(element);
|
|
2926
3186
|
}
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
3187
|
+
};
|
|
3188
|
+
var MuRDAStruct = class {
|
|
3189
|
+
rdas;
|
|
3190
|
+
stateSchema;
|
|
3191
|
+
actionSchema;
|
|
3192
|
+
storeSchema;
|
|
3193
|
+
actionMeta;
|
|
3194
|
+
action;
|
|
3195
|
+
emptyStore;
|
|
3196
|
+
_saveStore = null;
|
|
3197
|
+
_wrapDispatch(id, rda) {
|
|
3198
|
+
const self = this;
|
|
3199
|
+
function wrapPartial(root, dispatch) {
|
|
3200
|
+
const savedPartial = { data: null };
|
|
3201
|
+
function wrapPartialRec(meta, index) {
|
|
3202
|
+
if (meta.type === "unit") {
|
|
3203
|
+
return new Function(
|
|
3204
|
+
"rda",
|
|
3205
|
+
"partial",
|
|
3206
|
+
`/* ${id}:${index} */ return function() { var result = rda.actionSchema.alloc(); result.type = "${id}"; result.data = partial.data${index}.apply(null, arguments); return result; }`
|
|
3207
|
+
)(self, savedPartial);
|
|
3208
|
+
} else if (meta.type === "table") {
|
|
3209
|
+
const result = {};
|
|
3210
|
+
const keys = Object.keys(meta.table);
|
|
3211
|
+
for (let i = 0; i < keys.length; ++i) {
|
|
3212
|
+
const key = keys[i];
|
|
3213
|
+
result[key] = wrapPartialRec(meta.table[key], `${index}["${key}"]`);
|
|
2950
3214
|
}
|
|
2951
|
-
|
|
3215
|
+
return result;
|
|
3216
|
+
} else if (meta.type === "partial") {
|
|
3217
|
+
return wrapPartial(
|
|
3218
|
+
meta.action,
|
|
3219
|
+
new Function(
|
|
3220
|
+
"partial",
|
|
3221
|
+
`/* ${id}:${index} */ return function () { return partial.data${index}.apply(null, arguments); }`
|
|
3222
|
+
)(savedPartial)
|
|
3223
|
+
);
|
|
2952
3224
|
}
|
|
3225
|
+
return {};
|
|
2953
3226
|
}
|
|
2954
|
-
|
|
2955
|
-
|
|
3227
|
+
return new Function(
|
|
3228
|
+
"dispatch",
|
|
3229
|
+
"partial",
|
|
3230
|
+
"wrappedDispatch",
|
|
3231
|
+
`/* ${id} */ return function () { partial.data = dispatch.apply(null, arguments); return wrappedDispatch; }`
|
|
3232
|
+
)(dispatch, savedPartial, wrapPartialRec(root, ""));
|
|
2956
3233
|
}
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
3234
|
+
function wrapAction(meta, dispatch) {
|
|
3235
|
+
if (meta.type === "unit") {
|
|
3236
|
+
return function(...args) {
|
|
3237
|
+
const result = self.actionSchema.alloc();
|
|
3238
|
+
result.type = id;
|
|
3239
|
+
result.data = dispatch.apply(null, args);
|
|
3240
|
+
return result;
|
|
3241
|
+
};
|
|
3242
|
+
} else if (meta.type === "table") {
|
|
3243
|
+
const result = {};
|
|
3244
|
+
const ids = Object.keys(meta.table);
|
|
3245
|
+
for (let i = 0; i < ids.length; ++i) {
|
|
3246
|
+
const key = ids[i];
|
|
3247
|
+
result[key] = wrapAction(meta.table[key], dispatch);
|
|
3248
|
+
}
|
|
3249
|
+
return result;
|
|
3250
|
+
} else if (meta.type === "partial") {
|
|
3251
|
+
return wrapPartial(meta.action, dispatch);
|
|
3252
|
+
}
|
|
3253
|
+
return {};
|
|
3254
|
+
}
|
|
3255
|
+
function wrapStore(meta, index) {
|
|
3256
|
+
if (meta.type === "unit") {
|
|
3257
|
+
return new Function(
|
|
3258
|
+
"rda",
|
|
3259
|
+
"dispatch",
|
|
3260
|
+
`/* ${id}:${index} */ return function() { var result = rda.actionSchema.alloc(); result.type = "${id}"; result.data = dispatch(rda._saveStore.stores["${id}"])${index}.apply(null, arguments); return result; }`
|
|
3261
|
+
)(self, rda.action);
|
|
3262
|
+
} else if (meta.type === "table") {
|
|
3263
|
+
const result = {};
|
|
3264
|
+
const ids = Object.keys(meta.table);
|
|
3265
|
+
for (let i = 0; i < ids.length; ++i) {
|
|
3266
|
+
const key = ids[i];
|
|
3267
|
+
result[key] = wrapStore(meta.table[key], `${index}["${key}"]`);
|
|
3268
|
+
}
|
|
3269
|
+
return result;
|
|
3270
|
+
} else if (meta.type === "partial") {
|
|
3271
|
+
return wrapPartial(
|
|
3272
|
+
meta.action,
|
|
3273
|
+
new Function(
|
|
3274
|
+
"rda",
|
|
3275
|
+
"dispatch",
|
|
3276
|
+
`/* ${id}:${index} */ return function() { return dispatch(rda._saveStore.stores["${id}"])${index}.apply(null, arguments); }`
|
|
3277
|
+
)(self, rda.action)
|
|
3278
|
+
);
|
|
3279
|
+
}
|
|
3280
|
+
return {};
|
|
3281
|
+
}
|
|
3282
|
+
if (rda.actionMeta.type !== "store") {
|
|
3283
|
+
this.actionMeta.action.table[id] = rda.actionMeta;
|
|
3284
|
+
return wrapAction(rda.actionMeta, rda.action);
|
|
3285
|
+
} else {
|
|
3286
|
+
this.actionMeta.action.table[id] = rda.actionMeta.action;
|
|
3287
|
+
return wrapStore(rda.actionMeta.action, "");
|
|
3288
|
+
}
|
|
3289
|
+
}
|
|
3290
|
+
constructor(spec) {
|
|
3291
|
+
this.rdas = spec;
|
|
3292
|
+
const stateSpec = {};
|
|
3293
|
+
const actionSpec = {};
|
|
3294
|
+
const storeSpec = {};
|
|
3295
|
+
const emptyStores = {};
|
|
3296
|
+
const props = Object.keys(spec);
|
|
3297
|
+
for (let i = 0; i < props.length; ++i) {
|
|
3298
|
+
const prop = props[i];
|
|
3299
|
+
const rda = spec[prop];
|
|
3300
|
+
stateSpec[prop] = rda.stateSchema;
|
|
3301
|
+
actionSpec[prop] = rda.actionSchema;
|
|
3302
|
+
storeSpec[prop] = rda.storeSchema;
|
|
3303
|
+
emptyStores[prop] = rda.emptyStore;
|
|
3304
|
+
}
|
|
3305
|
+
this.stateSchema = new MuStruct(stateSpec);
|
|
3306
|
+
this.actionSchema = new MuUnion(actionSpec);
|
|
3307
|
+
this.storeSchema = new MuStruct(storeSpec);
|
|
3308
|
+
this.emptyStore = new MuRDAStructStore(emptyStores);
|
|
3309
|
+
this.actionMeta = {
|
|
3310
|
+
type: "store",
|
|
3311
|
+
action: {
|
|
3312
|
+
type: "table",
|
|
3313
|
+
table: {}
|
|
3314
|
+
}
|
|
3315
|
+
};
|
|
3316
|
+
const storeDispatch = {};
|
|
3317
|
+
for (let i = 0; i < props.length; ++i) {
|
|
3318
|
+
const prop = props[i];
|
|
3319
|
+
storeDispatch[prop] = this._wrapDispatch(prop, spec[prop]);
|
|
3320
|
+
}
|
|
3321
|
+
this.action = ((store) => {
|
|
3322
|
+
this._saveStore = store;
|
|
3323
|
+
return storeDispatch;
|
|
3324
|
+
});
|
|
3325
|
+
}
|
|
3326
|
+
createStore(state) {
|
|
3327
|
+
const stores = {};
|
|
3328
|
+
const ids = Object.keys(this.rdas);
|
|
3329
|
+
for (let i = 0; i < ids.length; ++i) {
|
|
3330
|
+
const id = ids[i];
|
|
3331
|
+
stores[id] = this.rdas[id].createStore(state[id]);
|
|
3332
|
+
}
|
|
3333
|
+
return new MuRDAStructStore(stores);
|
|
3334
|
+
}
|
|
3335
|
+
parse(store) {
|
|
3336
|
+
const stores = {};
|
|
3337
|
+
const ids = Object.keys(this.rdas);
|
|
3338
|
+
for (let i = 0; i < ids.length; ++i) {
|
|
3339
|
+
const id = ids[i];
|
|
3340
|
+
stores[id] = this.rdas[id].parse(store[id]);
|
|
3341
|
+
}
|
|
3342
|
+
return new MuRDAStructStore(stores);
|
|
3343
|
+
}
|
|
3344
|
+
};
|
|
3345
|
+
|
|
3346
|
+
// src/vendor/mudb/rda/map.ts
|
|
3347
|
+
function compareKey(a, b) {
|
|
3348
|
+
return a < b ? -1 : b < a ? 1 : 0;
|
|
3349
|
+
}
|
|
3350
|
+
function compareStoreElements(a, b) {
|
|
3351
|
+
return a.sequence - b.sequence || a.id - b.id;
|
|
3352
|
+
}
|
|
3353
|
+
function compareNum(a, b) {
|
|
3354
|
+
return a - b;
|
|
3355
|
+
}
|
|
3356
|
+
var MuRDAMapStoreElement = class {
|
|
3357
|
+
constructor(id, sequence, deleted, key, value) {
|
|
3358
|
+
this.id = id;
|
|
3359
|
+
this.sequence = sequence;
|
|
3360
|
+
this.deleted = deleted;
|
|
3361
|
+
this.key = key;
|
|
3362
|
+
this.value = value;
|
|
3363
|
+
}
|
|
3364
|
+
id;
|
|
3365
|
+
sequence;
|
|
3366
|
+
deleted;
|
|
3367
|
+
key;
|
|
3368
|
+
value;
|
|
3369
|
+
// currently a linked list, though this should probably be replaced by a pairing heap to prevent adversarial attacks
|
|
3370
|
+
next = null;
|
|
3371
|
+
prev = null;
|
|
3372
|
+
};
|
|
3373
|
+
var MuRDAMapStore = class {
|
|
3374
|
+
keyIndex = {};
|
|
3375
|
+
idIndex = {};
|
|
3376
|
+
constructor(elements) {
|
|
3377
|
+
const { idIndex } = this;
|
|
3378
|
+
for (let i = 0; i < elements.length; ++i) {
|
|
3379
|
+
const element = elements[i];
|
|
3380
|
+
const id = element.id;
|
|
3381
|
+
idIndex[id] = element;
|
|
3382
|
+
this._insertElement(element);
|
|
3383
|
+
}
|
|
3384
|
+
}
|
|
3385
|
+
state(rda, out) {
|
|
3386
|
+
const keyIndex = this.keyIndex;
|
|
3387
|
+
const outKeys = Object.keys(out);
|
|
3388
|
+
for (let i = 0; i < outKeys.length; ++i) {
|
|
3389
|
+
const key = outKeys[i];
|
|
3390
|
+
const cur = keyIndex[key];
|
|
3391
|
+
if (!cur || cur.deleted) {
|
|
3392
|
+
rda.valueRDA.stateSchema.free(out[key]);
|
|
3393
|
+
delete out[key];
|
|
3394
|
+
}
|
|
3395
|
+
}
|
|
3396
|
+
const keys = Object.keys(keyIndex);
|
|
3397
|
+
const valueRDA = rda.valueRDA;
|
|
3398
|
+
const valueSchema = valueRDA.stateSchema;
|
|
3399
|
+
for (let i = 0; i < keys.length; ++i) {
|
|
3400
|
+
const key = keys[i];
|
|
3401
|
+
const final = keyIndex[key];
|
|
3402
|
+
if (!final.deleted) {
|
|
3403
|
+
out[key] = final.value.state(valueRDA, out[key] || valueSchema.alloc());
|
|
3404
|
+
}
|
|
3405
|
+
}
|
|
3406
|
+
return out;
|
|
3407
|
+
}
|
|
3408
|
+
_moveElement(element, key) {
|
|
3409
|
+
if (key === element.key) {
|
|
3410
|
+
return;
|
|
3411
|
+
}
|
|
3412
|
+
const { next, prev, sequence } = element;
|
|
3413
|
+
if (this.keyIndex[element.key] === element) {
|
|
3414
|
+
if (next) {
|
|
3415
|
+
this.keyIndex[element.key] = next;
|
|
3416
|
+
if (next.sequence >= sequence) {
|
|
3417
|
+
next.deleted = false;
|
|
3418
|
+
}
|
|
3419
|
+
} else {
|
|
3420
|
+
delete this.keyIndex[element.key];
|
|
3421
|
+
}
|
|
3422
|
+
}
|
|
3423
|
+
if (next) {
|
|
3424
|
+
next.prev = prev;
|
|
3425
|
+
}
|
|
3426
|
+
if (prev) {
|
|
3427
|
+
prev.next = next;
|
|
3428
|
+
}
|
|
3429
|
+
element.next = element.prev = null;
|
|
3430
|
+
element.key = key;
|
|
3431
|
+
this._insertElement(element);
|
|
3432
|
+
}
|
|
3433
|
+
_insertElement(element) {
|
|
3434
|
+
const key = element.key;
|
|
3435
|
+
const head = this.keyIndex[key];
|
|
3436
|
+
if (head) {
|
|
3437
|
+
if (compareStoreElements(head, element) < 0) {
|
|
3438
|
+
element.next = head;
|
|
3439
|
+
head.prev = element;
|
|
3440
|
+
head.deleted = true;
|
|
3441
|
+
this.keyIndex[key] = element;
|
|
3442
|
+
} else {
|
|
3443
|
+
let prev = head;
|
|
3444
|
+
while (prev) {
|
|
3445
|
+
const next = prev.next;
|
|
3446
|
+
if (!next) {
|
|
3447
|
+
prev.next = element;
|
|
3448
|
+
element.prev = prev;
|
|
3449
|
+
break;
|
|
3450
|
+
} else if (compareStoreElements(next, element) < 0) {
|
|
3451
|
+
prev.next = element;
|
|
3452
|
+
next.prev = element;
|
|
3453
|
+
element.next = next;
|
|
3454
|
+
element.prev = prev;
|
|
3455
|
+
break;
|
|
3456
|
+
}
|
|
3457
|
+
prev = next;
|
|
3458
|
+
}
|
|
3459
|
+
}
|
|
3460
|
+
} else {
|
|
3461
|
+
this.keyIndex[key] = element;
|
|
3462
|
+
}
|
|
3463
|
+
}
|
|
3464
|
+
_applyUpsert(valueRDA, upsertAction) {
|
|
3465
|
+
const prev = this.idIndex[upsertAction.id];
|
|
3466
|
+
if (prev) {
|
|
3467
|
+
prev.id = upsertAction.id;
|
|
3468
|
+
prev.deleted = upsertAction.deleted;
|
|
3469
|
+
prev.sequence = upsertAction.sequence;
|
|
3470
|
+
prev.value.free(valueRDA);
|
|
3471
|
+
prev.value = valueRDA.parse(upsertAction.value);
|
|
3472
|
+
this._moveElement(prev, upsertAction.key);
|
|
2967
3473
|
} else {
|
|
2968
3474
|
const element = new MuRDAMapStoreElement(
|
|
2969
3475
|
upsertAction.id,
|
|
@@ -4240,9 +4746,6 @@ var MuRDAList = class {
|
|
|
4240
4746
|
return new MuRDAListStore(nodes);
|
|
4241
4747
|
}
|
|
4242
4748
|
};
|
|
4243
|
-
|
|
4244
|
-
// src/vendor/mudb/box-schema/content-server/index.ts
|
|
4245
|
-
var HashSchema = new MuASCII();
|
|
4246
4749
|
var SCHROEPPEL23 = 2863311530;
|
|
4247
4750
|
function readShroeppel(stream) {
|
|
4248
4751
|
const x = stream.readVarint();
|
|
@@ -8139,284 +8642,95 @@ var DamageEventSchema = new MuStruct({
|
|
|
8139
8642
|
die: new MuArray(new MuVarint(), Infinity)
|
|
8140
8643
|
});
|
|
8141
8644
|
|
|
8142
|
-
// src/vendor/mudb/box-schema/events/script-events.ts
|
|
8143
|
-
new MuStruct({
|
|
8144
|
-
damage: DamageEventSchema
|
|
8145
|
-
});
|
|
8146
|
-
|
|
8147
|
-
// src/vendor/mudb/box-schema/physics/collision-filter-schema.ts
|
|
8148
|
-
var CollisionGroupSchema = new MuSortedArray(
|
|
8149
|
-
new MuVarint(),
|
|
8150
|
-
Infinity,
|
|
8151
|
-
(a, b) => a - b
|
|
8152
|
-
);
|
|
8153
|
-
var CollisionFilterSchema = new MuArray(
|
|
8154
|
-
CollisionGroupSchema,
|
|
8155
|
-
Infinity
|
|
8156
|
-
);
|
|
8157
|
-
|
|
8158
|
-
// src/vendor/mudb/box-schema/zone/zone-schema.ts
|
|
8159
|
-
var ZoneSchema = new MuStruct({
|
|
8160
|
-
id: new MuVarint(),
|
|
8161
|
-
// bounds
|
|
8162
|
-
minX: new MuQuantizedFloat(1 / 16, 0),
|
|
8163
|
-
minY: new MuQuantizedFloat(1 / 16, 0),
|
|
8164
|
-
minZ: new MuQuantizedFloat(1 / 16, 0),
|
|
8165
|
-
maxX: new MuQuantizedFloat(1 / 16, 0),
|
|
8166
|
-
maxY: new MuQuantizedFloat(1 / 16, 0),
|
|
8167
|
-
maxZ: new MuQuantizedFloat(1 / 16, 0)
|
|
8168
|
-
});
|
|
8169
|
-
var ZoneSelectorGroupSchema = new MuStruct({
|
|
8170
|
-
id: new MuVarint(),
|
|
8171
|
-
groupBits: new MuSortedArray(new MuVarint(), Infinity, (a, b) => a - b)
|
|
8172
|
-
});
|
|
8173
|
-
var ZoneSelectorGroupSetSchema = new MuSortedArray(
|
|
8174
|
-
ZoneSelectorGroupSchema,
|
|
8175
|
-
Infinity,
|
|
8176
|
-
compareId
|
|
8177
|
-
);
|
|
8178
|
-
var PhysicsZoneSchema = new MuStruct({
|
|
8179
|
-
// selector group for this zone
|
|
8180
|
-
selectorGroup: new MuVarint(0),
|
|
8181
|
-
// physics effects
|
|
8182
|
-
massScale: new MuQuantizedFloat(1 / 256, 0),
|
|
8183
|
-
fx: new MuQuantizedFloat(1 / 1024, 0),
|
|
8184
|
-
fy: new MuQuantizedFloat(1 / 1024, 0),
|
|
8185
|
-
fz: new MuQuantizedFloat(1 / 1024, 0),
|
|
8186
|
-
...ZoneSchema.muData
|
|
8187
|
-
});
|
|
8188
|
-
var PhysicsZoneSetSchema = new MuSortedArray(
|
|
8189
|
-
PhysicsZoneSchema,
|
|
8190
|
-
Infinity,
|
|
8191
|
-
compareId
|
|
8192
|
-
);
|
|
8193
|
-
var EnvironmentZoneSchema = new MuStruct({
|
|
8194
|
-
// weather effects
|
|
8195
|
-
overrideFog: new MuBoolean(false),
|
|
8196
|
-
fog: FogRDA.stateSchema,
|
|
8197
|
-
overrideSky: new MuBoolean(false),
|
|
8198
|
-
sky: SkyRDA.stateSchema,
|
|
8199
|
-
overrideSnow: new MuBoolean(false),
|
|
8200
|
-
snow: SnowRDA.stateSchema,
|
|
8201
|
-
overrideRain: new MuBoolean(false),
|
|
8202
|
-
rain: RainRDA.stateSchema,
|
|
8203
|
-
...ZoneSchema.muData
|
|
8204
|
-
});
|
|
8205
|
-
var EnvironmentZoneSetSchema = new MuSortedArray(
|
|
8206
|
-
EnvironmentZoneSchema,
|
|
8207
|
-
Infinity,
|
|
8208
|
-
compareId
|
|
8209
|
-
);
|
|
8210
|
-
|
|
8211
|
-
// src/vendor/mudb/box-schema/environment/environment-schema.ts
|
|
8212
|
-
var EnvironmentParamSchema = EnvironmentRDA.stateSchema;
|
|
8213
|
-
new MuStruct({
|
|
8214
|
-
timeOfDay: new MuFloat64(0),
|
|
8215
|
-
sunUp: new MuBoolean(false),
|
|
8216
|
-
globalLight: new MuFloat64(0),
|
|
8217
|
-
gamma: new MuFloat32(1.3),
|
|
8218
|
-
drawDistance: new MuFloat32(512),
|
|
8219
|
-
freezeDrawDistance: new MuBoolean(false),
|
|
8220
|
-
sunDirection: Vec3Schema,
|
|
8221
|
-
sunColor: Vec3Schema,
|
|
8222
|
-
skyLeft: Vec3Schema,
|
|
8223
|
-
skyRight: Vec3Schema,
|
|
8224
|
-
skyTop: Vec3Schema,
|
|
8225
|
-
skyBottom: Vec3Schema,
|
|
8226
|
-
skyFront: Vec3Schema,
|
|
8227
|
-
skyBack: Vec3Schema,
|
|
8228
|
-
fogParams: Vec4Schema,
|
|
8229
|
-
fogParams2: Vec4Schema,
|
|
8230
|
-
fogParams3: Vec4Schema
|
|
8231
|
-
});
|
|
8232
|
-
|
|
8233
|
-
// src/vendor/mudb/box-schema/utils/ref-schema.ts
|
|
8234
|
-
var _noSerialize = () => {
|
|
8235
|
-
throw new Error("cannot serialize references");
|
|
8236
|
-
};
|
|
8237
|
-
var MuRefSchema = class {
|
|
8238
|
-
identity = null;
|
|
8239
|
-
muType = "ref";
|
|
8240
|
-
muData = { type: "ref" };
|
|
8241
|
-
json = { type: "ref" };
|
|
8242
|
-
constructor() {
|
|
8243
|
-
}
|
|
8244
|
-
diff = _noSerialize;
|
|
8245
|
-
patch = _noSerialize;
|
|
8246
|
-
toJSON = _noSerialize;
|
|
8247
|
-
fromJSON = _noSerialize;
|
|
8248
|
-
alloc() {
|
|
8249
|
-
return null;
|
|
8250
|
-
}
|
|
8251
|
-
free() {
|
|
8252
|
-
}
|
|
8253
|
-
assign(dst, src) {
|
|
8254
|
-
return src;
|
|
8255
|
-
}
|
|
8256
|
-
clone(x) {
|
|
8257
|
-
return x;
|
|
8258
|
-
}
|
|
8259
|
-
equal(a, b) {
|
|
8260
|
-
return a === b;
|
|
8261
|
-
}
|
|
8262
|
-
};
|
|
8263
|
-
|
|
8264
|
-
// src/vendor/mudb/box-schema/utils/relative-array.ts
|
|
8265
|
-
var RelativeArray = class {
|
|
8266
|
-
identity;
|
|
8267
|
-
muType = "relative array";
|
|
8268
|
-
muData;
|
|
8269
|
-
json;
|
|
8270
|
-
arraySchema;
|
|
8271
|
-
alloc;
|
|
8272
|
-
free;
|
|
8273
|
-
clone;
|
|
8274
|
-
equal;
|
|
8275
|
-
assign;
|
|
8276
|
-
toJSON;
|
|
8277
|
-
fromJSON;
|
|
8278
|
-
constructor(schema, capacity, identity2) {
|
|
8279
|
-
const arraySchema = this.arraySchema = new MuArray(
|
|
8280
|
-
schema,
|
|
8281
|
-
capacity,
|
|
8282
|
-
identity2
|
|
8283
|
-
);
|
|
8284
|
-
this.json = {
|
|
8285
|
-
type: "relative array",
|
|
8286
|
-
value: schema.json
|
|
8287
|
-
};
|
|
8288
|
-
this.muData = schema;
|
|
8289
|
-
this.identity = arraySchema.identity;
|
|
8290
|
-
this.alloc = arraySchema.alloc;
|
|
8291
|
-
this.free = arraySchema.free;
|
|
8292
|
-
this.clone = arraySchema.clone;
|
|
8293
|
-
this.equal = arraySchema.equal;
|
|
8294
|
-
this.assign = arraySchema.assign;
|
|
8295
|
-
this.toJSON = arraySchema.toJSON;
|
|
8296
|
-
this.fromJSON = arraySchema.fromJSON;
|
|
8297
|
-
}
|
|
8298
|
-
diff(base, target, stream) {
|
|
8299
|
-
const prefixOffset = stream.offset;
|
|
8300
|
-
const targetLength = target.length;
|
|
8301
|
-
const numTrackers = Math.ceil(targetLength / 8);
|
|
8302
|
-
stream.grow(4 + numTrackers);
|
|
8303
|
-
stream.writeUint32(targetLength);
|
|
8304
|
-
let trackerOffset = stream.offset;
|
|
8305
|
-
stream.offset = trackerOffset + numTrackers;
|
|
8306
|
-
let tracker = 0;
|
|
8307
|
-
let numPatch = 0;
|
|
8308
|
-
const baseLength = base.length;
|
|
8309
|
-
const valueSchema = this.muData;
|
|
8310
|
-
let prev = base.length > 0 ? base[0] : valueSchema.identity;
|
|
8311
|
-
for (let i = 0; i < target.length; ++i) {
|
|
8312
|
-
if (valueSchema.diff(prev, target[i], stream)) {
|
|
8313
|
-
tracker |= 1 << (i & 7);
|
|
8314
|
-
++numPatch;
|
|
8315
|
-
}
|
|
8316
|
-
if ((i & 7) === 7) {
|
|
8317
|
-
stream.writeUint8At(trackerOffset++, tracker);
|
|
8318
|
-
tracker = 0;
|
|
8319
|
-
}
|
|
8320
|
-
prev = target[i];
|
|
8321
|
-
}
|
|
8322
|
-
if (targetLength & 7) {
|
|
8323
|
-
stream.writeUint8At(trackerOffset, tracker);
|
|
8324
|
-
}
|
|
8325
|
-
if (numPatch > 0 || baseLength !== targetLength) {
|
|
8326
|
-
return true;
|
|
8327
|
-
}
|
|
8328
|
-
stream.offset = prefixOffset;
|
|
8329
|
-
return false;
|
|
8330
|
-
}
|
|
8331
|
-
patch(base, stream) {
|
|
8332
|
-
const result = this.clone(base);
|
|
8333
|
-
const targetLength = stream.readUint32();
|
|
8334
|
-
result.length = targetLength;
|
|
8335
|
-
let trackerOffset = stream.offset;
|
|
8336
|
-
const numTrackers = Math.ceil(targetLength / 8);
|
|
8337
|
-
stream.offset = trackerOffset + numTrackers;
|
|
8338
|
-
let tracker = 0;
|
|
8339
|
-
const valueSchema = this.muData;
|
|
8340
|
-
let prev = base.length > 0 ? base[0] : valueSchema.identity;
|
|
8341
|
-
for (let i = 0; i < targetLength; ++i) {
|
|
8342
|
-
const mod8 = i & 7;
|
|
8343
|
-
if (!mod8) {
|
|
8344
|
-
tracker = stream.readUint8At(trackerOffset++);
|
|
8345
|
-
}
|
|
8346
|
-
if (1 << mod8 & tracker) {
|
|
8347
|
-
prev = result[i] = valueSchema.patch(prev, stream);
|
|
8348
|
-
} else {
|
|
8349
|
-
result[i] = valueSchema.clone(prev);
|
|
8350
|
-
}
|
|
8351
|
-
}
|
|
8352
|
-
return result;
|
|
8353
|
-
}
|
|
8354
|
-
};
|
|
8355
|
-
|
|
8356
|
-
// src/vendor/mudb/box-schema/voxel/block-schema.ts
|
|
8357
|
-
var BlockInfoSchema = new MuStruct({
|
|
8358
|
-
// voxel info
|
|
8359
|
-
ids: new RelativeArray(new MuRelativeVarint(), Infinity, [0]),
|
|
8360
|
-
names: new MuArray(new MuUTF8(), Infinity, ["air"]),
|
|
8361
|
-
// run length encode these arrays
|
|
8362
|
-
emissive: new RelativeArray(new MuVarint(), Infinity, [0]),
|
|
8363
|
-
texture: new RelativeArray(
|
|
8364
|
-
new MuRelativeVarint(),
|
|
8365
|
-
Infinity,
|
|
8366
|
-
[0, 0, 0, 0, 0, 0]
|
|
8367
|
-
),
|
|
8368
|
-
animLength: new RelativeArray(new MuVarint(1), Infinity, [1, 1, 1, 1, 1, 1]),
|
|
8369
|
-
friction: new RelativeArray(new MuQuantizedFloat(1 / 256, 1), Infinity, [0]),
|
|
8370
|
-
restitution: new RelativeArray(new MuQuantizedFloat(1 / 256, 0), Infinity, [
|
|
8371
|
-
0
|
|
8372
|
-
]),
|
|
8373
|
-
velocity: new RelativeArray(new MuFloat32(0), Infinity, [0, 0, 0]),
|
|
8374
|
-
// fluids
|
|
8375
|
-
fluids: new MuArray(
|
|
8376
|
-
new MuStruct({
|
|
8377
|
-
id: new MuVarint(),
|
|
8378
|
-
info: new MuUint32(),
|
|
8379
|
-
mass: new MuFloat64(1)
|
|
8380
|
-
}),
|
|
8381
|
-
Infinity,
|
|
8382
|
-
[
|
|
8383
|
-
{
|
|
8384
|
-
id: 0,
|
|
8385
|
-
info: 0,
|
|
8386
|
-
mass: 0
|
|
8387
|
-
}
|
|
8388
|
-
]
|
|
8389
|
-
),
|
|
8390
|
-
// category list
|
|
8391
|
-
category: new MuDictionary(
|
|
8392
|
-
new RelativeArray(new MuRelativeVarint(), Infinity),
|
|
8393
|
-
Infinity,
|
|
8394
|
-
{
|
|
8395
|
-
default: [0]
|
|
8396
|
-
}
|
|
8397
|
-
),
|
|
8398
|
-
// texture info
|
|
8399
|
-
atlasRadius: new MuVarint(16),
|
|
8400
|
-
blockBumpShift: new MuVarint(6),
|
|
8401
|
-
blockColorShift: new MuVarint(4),
|
|
8402
|
-
// texture atlases
|
|
8403
|
-
colorAtlas: new MuArray(HashSchema, Infinity),
|
|
8404
|
-
materialAtlas: new MuArray(HashSchema, Infinity),
|
|
8405
|
-
bumpAtlas: new MuArray(HashSchema, Infinity)
|
|
8645
|
+
// src/vendor/mudb/box-schema/events/script-events.ts
|
|
8646
|
+
new MuStruct({
|
|
8647
|
+
damage: DamageEventSchema
|
|
8648
|
+
});
|
|
8649
|
+
|
|
8650
|
+
// src/vendor/mudb/box-schema/physics/collision-filter-schema.ts
|
|
8651
|
+
var CollisionGroupSchema = new MuSortedArray(
|
|
8652
|
+
new MuVarint(),
|
|
8653
|
+
Infinity,
|
|
8654
|
+
(a, b) => a - b
|
|
8655
|
+
);
|
|
8656
|
+
var CollisionFilterSchema = new MuArray(
|
|
8657
|
+
CollisionGroupSchema,
|
|
8658
|
+
Infinity
|
|
8659
|
+
);
|
|
8660
|
+
|
|
8661
|
+
// src/vendor/mudb/box-schema/zone/zone-schema.ts
|
|
8662
|
+
var ZoneSchema = new MuStruct({
|
|
8663
|
+
id: new MuVarint(),
|
|
8664
|
+
// bounds
|
|
8665
|
+
minX: new MuQuantizedFloat(1 / 16, 0),
|
|
8666
|
+
minY: new MuQuantizedFloat(1 / 16, 0),
|
|
8667
|
+
minZ: new MuQuantizedFloat(1 / 16, 0),
|
|
8668
|
+
maxX: new MuQuantizedFloat(1 / 16, 0),
|
|
8669
|
+
maxY: new MuQuantizedFloat(1 / 16, 0),
|
|
8670
|
+
maxZ: new MuQuantizedFloat(1 / 16, 0)
|
|
8671
|
+
});
|
|
8672
|
+
var ZoneSelectorGroupSchema = new MuStruct({
|
|
8673
|
+
id: new MuVarint(),
|
|
8674
|
+
groupBits: new MuSortedArray(new MuVarint(), Infinity, (a, b) => a - b)
|
|
8675
|
+
});
|
|
8676
|
+
var ZoneSelectorGroupSetSchema = new MuSortedArray(
|
|
8677
|
+
ZoneSelectorGroupSchema,
|
|
8678
|
+
Infinity,
|
|
8679
|
+
compareId
|
|
8680
|
+
);
|
|
8681
|
+
var PhysicsZoneSchema = new MuStruct({
|
|
8682
|
+
// selector group for this zone
|
|
8683
|
+
selectorGroup: new MuVarint(0),
|
|
8684
|
+
// physics effects
|
|
8685
|
+
massScale: new MuQuantizedFloat(1 / 256, 0),
|
|
8686
|
+
fx: new MuQuantizedFloat(1 / 1024, 0),
|
|
8687
|
+
fy: new MuQuantizedFloat(1 / 1024, 0),
|
|
8688
|
+
fz: new MuQuantizedFloat(1 / 1024, 0),
|
|
8689
|
+
...ZoneSchema.muData
|
|
8690
|
+
});
|
|
8691
|
+
var PhysicsZoneSetSchema = new MuSortedArray(
|
|
8692
|
+
PhysicsZoneSchema,
|
|
8693
|
+
Infinity,
|
|
8694
|
+
compareId
|
|
8695
|
+
);
|
|
8696
|
+
var EnvironmentZoneSchema = new MuStruct({
|
|
8697
|
+
// weather effects
|
|
8698
|
+
overrideFog: new MuBoolean(false),
|
|
8699
|
+
fog: FogRDA.stateSchema,
|
|
8700
|
+
overrideSky: new MuBoolean(false),
|
|
8701
|
+
sky: SkyRDA.stateSchema,
|
|
8702
|
+
overrideSnow: new MuBoolean(false),
|
|
8703
|
+
snow: SnowRDA.stateSchema,
|
|
8704
|
+
overrideRain: new MuBoolean(false),
|
|
8705
|
+
rain: RainRDA.stateSchema,
|
|
8706
|
+
...ZoneSchema.muData
|
|
8406
8707
|
});
|
|
8708
|
+
var EnvironmentZoneSetSchema = new MuSortedArray(
|
|
8709
|
+
EnvironmentZoneSchema,
|
|
8710
|
+
Infinity,
|
|
8711
|
+
compareId
|
|
8712
|
+
);
|
|
8713
|
+
|
|
8714
|
+
// src/vendor/mudb/box-schema/environment/environment-schema.ts
|
|
8715
|
+
var EnvironmentParamSchema = EnvironmentRDA.stateSchema;
|
|
8407
8716
|
new MuStruct({
|
|
8408
|
-
|
|
8409
|
-
|
|
8410
|
-
|
|
8411
|
-
|
|
8412
|
-
|
|
8413
|
-
|
|
8414
|
-
|
|
8415
|
-
|
|
8416
|
-
|
|
8417
|
-
|
|
8418
|
-
|
|
8419
|
-
|
|
8717
|
+
timeOfDay: new MuFloat64(0),
|
|
8718
|
+
sunUp: new MuBoolean(false),
|
|
8719
|
+
globalLight: new MuFloat64(0),
|
|
8720
|
+
gamma: new MuFloat32(1.3),
|
|
8721
|
+
drawDistance: new MuFloat32(512),
|
|
8722
|
+
freezeDrawDistance: new MuBoolean(false),
|
|
8723
|
+
sunDirection: Vec3Schema,
|
|
8724
|
+
sunColor: Vec3Schema,
|
|
8725
|
+
skyLeft: Vec3Schema,
|
|
8726
|
+
skyRight: Vec3Schema,
|
|
8727
|
+
skyTop: Vec3Schema,
|
|
8728
|
+
skyBottom: Vec3Schema,
|
|
8729
|
+
skyFront: Vec3Schema,
|
|
8730
|
+
skyBack: Vec3Schema,
|
|
8731
|
+
fogParams: Vec4Schema,
|
|
8732
|
+
fogParams2: Vec4Schema,
|
|
8733
|
+
fogParams3: Vec4Schema
|
|
8420
8734
|
});
|
|
8421
8735
|
|
|
8422
8736
|
// src/vendor/mudb/box-schema/script/script-protocol.ts
|
|
@@ -12906,146 +13220,6 @@ new MuSortedArray(
|
|
|
12906
13220
|
Infinity,
|
|
12907
13221
|
compareNetPublic
|
|
12908
13222
|
);
|
|
12909
|
-
var decodeUTF8;
|
|
12910
|
-
{
|
|
12911
|
-
new TextEncoder();
|
|
12912
|
-
const decoder = new TextDecoder();
|
|
12913
|
-
decodeUTF8 = (bytes) => decoder.decode(bytes);
|
|
12914
|
-
}
|
|
12915
|
-
var MuBuffer = class {
|
|
12916
|
-
buffer;
|
|
12917
|
-
dataView;
|
|
12918
|
-
uint8;
|
|
12919
|
-
constructor(buffer) {
|
|
12920
|
-
this.buffer = buffer;
|
|
12921
|
-
this.dataView = new DataView(buffer);
|
|
12922
|
-
this.uint8 = new Uint8Array(buffer);
|
|
12923
|
-
}
|
|
12924
|
-
};
|
|
12925
|
-
var bufferPool = new Array(31);
|
|
12926
|
-
for (let i = 0; i < 31; ++i) {
|
|
12927
|
-
bufferPool[i] = [];
|
|
12928
|
-
}
|
|
12929
|
-
var LITTLE_ENDIAN = true;
|
|
12930
|
-
var MuReadStream = class {
|
|
12931
|
-
buffer;
|
|
12932
|
-
offset;
|
|
12933
|
-
length;
|
|
12934
|
-
constructor(data) {
|
|
12935
|
-
this.buffer = new MuBuffer(data.buffer);
|
|
12936
|
-
this.offset = data.byteOffset;
|
|
12937
|
-
this.length = data.byteLength + data.byteOffset;
|
|
12938
|
-
}
|
|
12939
|
-
bytes() {
|
|
12940
|
-
return this.buffer.uint8.subarray(this.offset, this.length);
|
|
12941
|
-
}
|
|
12942
|
-
checkBounds() {
|
|
12943
|
-
if (this.offset > this.length) {
|
|
12944
|
-
throw new Error("out of bounds");
|
|
12945
|
-
}
|
|
12946
|
-
}
|
|
12947
|
-
readInt8() {
|
|
12948
|
-
const offset = this.offset;
|
|
12949
|
-
this.offset += 1;
|
|
12950
|
-
this.checkBounds();
|
|
12951
|
-
return this.buffer.dataView.getInt8(offset);
|
|
12952
|
-
}
|
|
12953
|
-
readInt16() {
|
|
12954
|
-
const offset = this.offset;
|
|
12955
|
-
this.offset += 2;
|
|
12956
|
-
this.checkBounds();
|
|
12957
|
-
return this.buffer.dataView.getInt16(offset, LITTLE_ENDIAN);
|
|
12958
|
-
}
|
|
12959
|
-
readInt32() {
|
|
12960
|
-
const offset = this.offset;
|
|
12961
|
-
this.offset += 4;
|
|
12962
|
-
this.checkBounds();
|
|
12963
|
-
return this.buffer.dataView.getInt32(offset, LITTLE_ENDIAN);
|
|
12964
|
-
}
|
|
12965
|
-
readUint8() {
|
|
12966
|
-
const offset = this.offset;
|
|
12967
|
-
this.offset += 1;
|
|
12968
|
-
this.checkBounds();
|
|
12969
|
-
return this.buffer.dataView.getUint8(offset);
|
|
12970
|
-
}
|
|
12971
|
-
readUint16() {
|
|
12972
|
-
const offset = this.offset;
|
|
12973
|
-
this.offset += 2;
|
|
12974
|
-
this.checkBounds();
|
|
12975
|
-
return this.buffer.dataView.getUint16(offset, LITTLE_ENDIAN);
|
|
12976
|
-
}
|
|
12977
|
-
readUint32() {
|
|
12978
|
-
const offset = this.offset;
|
|
12979
|
-
this.offset += 4;
|
|
12980
|
-
this.checkBounds();
|
|
12981
|
-
return this.buffer.dataView.getUint32(offset, LITTLE_ENDIAN);
|
|
12982
|
-
}
|
|
12983
|
-
readFloat32() {
|
|
12984
|
-
const offset = this.offset;
|
|
12985
|
-
this.offset += 4;
|
|
12986
|
-
this.checkBounds();
|
|
12987
|
-
return this.buffer.dataView.getFloat32(offset, LITTLE_ENDIAN);
|
|
12988
|
-
}
|
|
12989
|
-
readFloat64() {
|
|
12990
|
-
const offset = this.offset;
|
|
12991
|
-
this.offset += 8;
|
|
12992
|
-
this.checkBounds();
|
|
12993
|
-
return this.buffer.dataView.getFloat64(offset, LITTLE_ENDIAN);
|
|
12994
|
-
}
|
|
12995
|
-
readVarint() {
|
|
12996
|
-
const bytes = this.buffer.uint8;
|
|
12997
|
-
let offset = this.offset;
|
|
12998
|
-
const x0 = bytes[offset++];
|
|
12999
|
-
if (x0 < 128) {
|
|
13000
|
-
this.offset = offset;
|
|
13001
|
-
this.checkBounds();
|
|
13002
|
-
return x0;
|
|
13003
|
-
}
|
|
13004
|
-
const x1 = bytes[offset++];
|
|
13005
|
-
if (x1 < 128) {
|
|
13006
|
-
this.offset = offset;
|
|
13007
|
-
this.checkBounds();
|
|
13008
|
-
return x0 & 127 | x1 << 7;
|
|
13009
|
-
}
|
|
13010
|
-
const x2 = bytes[offset++];
|
|
13011
|
-
if (x2 < 128) {
|
|
13012
|
-
this.offset = offset;
|
|
13013
|
-
this.checkBounds();
|
|
13014
|
-
return x0 & 127 | (x1 & 127) << 7 | x2 << 14;
|
|
13015
|
-
}
|
|
13016
|
-
const x3 = bytes[offset++];
|
|
13017
|
-
if (x3 < 128) {
|
|
13018
|
-
this.offset = offset;
|
|
13019
|
-
this.checkBounds();
|
|
13020
|
-
return x0 & 127 | (x1 & 127) << 7 | (x2 & 127) << 14 | x3 << 21;
|
|
13021
|
-
}
|
|
13022
|
-
const x4 = bytes[offset++];
|
|
13023
|
-
this.offset = offset;
|
|
13024
|
-
this.checkBounds();
|
|
13025
|
-
return (x0 & 127) + ((x1 & 127) << 7) + ((x2 & 127) << 14) + ((x3 & 127) << 21) + x4 * (1 << 28);
|
|
13026
|
-
}
|
|
13027
|
-
readASCII(length) {
|
|
13028
|
-
const head = this.offset;
|
|
13029
|
-
this.offset += length;
|
|
13030
|
-
this.checkBounds();
|
|
13031
|
-
let str = "";
|
|
13032
|
-
for (let i = head; i < this.offset; ++i) {
|
|
13033
|
-
str += String.fromCharCode(this.buffer.uint8[i]);
|
|
13034
|
-
}
|
|
13035
|
-
return str;
|
|
13036
|
-
}
|
|
13037
|
-
readString() {
|
|
13038
|
-
const byteLength = this.readVarint();
|
|
13039
|
-
const head = this.offset;
|
|
13040
|
-
this.offset += byteLength;
|
|
13041
|
-
this.checkBounds();
|
|
13042
|
-
const bytes = this.buffer.uint8.subarray(head, this.offset);
|
|
13043
|
-
return decodeUTF8(bytes);
|
|
13044
|
-
}
|
|
13045
|
-
readUint8At(offset) {
|
|
13046
|
-
return this.buffer.dataView.getUint8(offset);
|
|
13047
|
-
}
|
|
13048
|
-
};
|
|
13049
13223
|
|
|
13050
13224
|
// src/core/engine/world-seed.ts
|
|
13051
13225
|
var WORLD_SEED_VERSION = 2;
|
|
@@ -13074,6 +13248,21 @@ function asQuat(value) {
|
|
|
13074
13248
|
asNumber(w, 1)
|
|
13075
13249
|
];
|
|
13076
13250
|
}
|
|
13251
|
+
function archiveToWorldSeedSource(archive) {
|
|
13252
|
+
const world = archive.worlds[0];
|
|
13253
|
+
if (!world) {
|
|
13254
|
+
throw new Error("cajonzero: boxplay archive contains no world to seed");
|
|
13255
|
+
}
|
|
13256
|
+
const files = /* @__PURE__ */ new Map();
|
|
13257
|
+
for (const file of archive.files) {
|
|
13258
|
+
files.set(file.path, file.data);
|
|
13259
|
+
}
|
|
13260
|
+
return {
|
|
13261
|
+
worldId: world.worldId,
|
|
13262
|
+
manifest: world.manifest,
|
|
13263
|
+
reader: { read: (relPath) => files.get(relPath) ?? null }
|
|
13264
|
+
};
|
|
13265
|
+
}
|
|
13077
13266
|
async function readJsonFile(source, relPath) {
|
|
13078
13267
|
const bytes = await source.reader.read(`worlds/${source.worldId}/${relPath}`);
|
|
13079
13268
|
if (!bytes) return null;
|
|
@@ -13129,6 +13318,45 @@ function entityToSeedBody(entity) {
|
|
|
13129
13318
|
const bounds = asVec3(value.bounds) ?? [1, 1, 1];
|
|
13130
13319
|
const scale = asVec3(value.scale) ?? [1, 1, 1];
|
|
13131
13320
|
const orientation = asQuat(value.orientation);
|
|
13321
|
+
const [qx, qy, qz, qw] = orientation;
|
|
13322
|
+
const x2 = qx + qx;
|
|
13323
|
+
const y2 = qy + qy;
|
|
13324
|
+
const z2 = qz + qz;
|
|
13325
|
+
const xx = qx * x2;
|
|
13326
|
+
const yx = qy * x2;
|
|
13327
|
+
const yy = qy * y2;
|
|
13328
|
+
const zx = qz * x2;
|
|
13329
|
+
const zy = qz * y2;
|
|
13330
|
+
const zz = qz * z2;
|
|
13331
|
+
const wx = qw * x2;
|
|
13332
|
+
const wy = qw * y2;
|
|
13333
|
+
const wz = qw * z2;
|
|
13334
|
+
const m0 = 1 - yy - zz;
|
|
13335
|
+
const m1 = yx + wz;
|
|
13336
|
+
const m2 = zx - wy;
|
|
13337
|
+
const m3 = yx - wz;
|
|
13338
|
+
const m4 = 1 - xx - zz;
|
|
13339
|
+
const m5 = zy + wx;
|
|
13340
|
+
const m6 = zx + wy;
|
|
13341
|
+
const m7 = zy - wx;
|
|
13342
|
+
const m8 = 1 - xx - yy;
|
|
13343
|
+
const sx = scale[0];
|
|
13344
|
+
const sy = scale[1];
|
|
13345
|
+
const sz = scale[2];
|
|
13346
|
+
const bx = bounds[0];
|
|
13347
|
+
const by = bounds[1];
|
|
13348
|
+
const bz = bounds[2];
|
|
13349
|
+
let rx = 0;
|
|
13350
|
+
let ry = 0;
|
|
13351
|
+
let rz = 0;
|
|
13352
|
+
for (let i = 0; i < 8; i += 1) {
|
|
13353
|
+
const x = 0.5 * (i & 1 ? sx : -sx) * bx;
|
|
13354
|
+
const y = 0.5 * (i & 2 ? sy : -sy) * by;
|
|
13355
|
+
const z = 0.5 * (i & 4 ? sz : -sz) * bz;
|
|
13356
|
+
rx = Math.max(rx, Math.abs(x * m0 + y * m3 + z * m6));
|
|
13357
|
+
ry = Math.max(ry, Math.abs(x * m1 + y * m4 + z * m7));
|
|
13358
|
+
rz = Math.max(rz, Math.abs(x * m2 + y * m5 + z * m8));
|
|
13359
|
+
}
|
|
13132
13360
|
let flags = 0;
|
|
13133
13361
|
if (value.collision === true) flags |= 2 /* COLLIDES */;
|
|
13134
13362
|
if (value.gravity === true) flags |= 4 /* GRAVITY */;
|
|
@@ -13139,9 +13367,9 @@ function entityToSeedBody(entity) {
|
|
|
13139
13367
|
px: position[0],
|
|
13140
13368
|
py: position[1],
|
|
13141
13369
|
pz: position[2],
|
|
13142
|
-
rx
|
|
13143
|
-
ry
|
|
13144
|
-
rz
|
|
13370
|
+
rx,
|
|
13371
|
+
ry,
|
|
13372
|
+
rz,
|
|
13145
13373
|
qx: orientation[0],
|
|
13146
13374
|
qy: orientation[1],
|
|
13147
13375
|
qz: orientation[2],
|
|
@@ -13173,6 +13401,40 @@ async function mapLimit(items, limit, fn) {
|
|
|
13173
13401
|
await Promise.all(workers);
|
|
13174
13402
|
return results;
|
|
13175
13403
|
}
|
|
13404
|
+
async function resolveScripts(source, head, warnings) {
|
|
13405
|
+
const assetsRef = await resolveRef(source, head.scriptAssets);
|
|
13406
|
+
if (!isRecord(assetsRef)) return void 0;
|
|
13407
|
+
const rawIndex = typeof head.scriptIndex === "string" ? head.scriptIndex : "";
|
|
13408
|
+
const modules = {};
|
|
13409
|
+
for (const [path6, raw] of Object.entries(assetsRef)) {
|
|
13410
|
+
if (!isRecord(raw)) continue;
|
|
13411
|
+
if (raw.isClient === true || raw.type === 7) continue;
|
|
13412
|
+
const hash = typeof raw.hash === "string" ? raw.hash : "";
|
|
13413
|
+
if (hash.length === 0) {
|
|
13414
|
+
warnings.push(`script module "${path6}" has no hash`);
|
|
13415
|
+
continue;
|
|
13416
|
+
}
|
|
13417
|
+
const bytes = await source.reader.read(
|
|
13418
|
+
`worlds/${source.worldId}/data/blobs/${hash}`
|
|
13419
|
+
);
|
|
13420
|
+
if (!bytes) {
|
|
13421
|
+
warnings.push(`script module "${path6}" is missing (${hash.slice(0, 12)}\u2026)`);
|
|
13422
|
+
continue;
|
|
13423
|
+
}
|
|
13424
|
+
modules[path6] = {
|
|
13425
|
+
hash,
|
|
13426
|
+
source: textDecoder.decode(bytes),
|
|
13427
|
+
order: asNumber(raw.order, 0),
|
|
13428
|
+
...typeof raw.name === "string" && raw.name.length > 0 ? { name: raw.name } : {}
|
|
13429
|
+
};
|
|
13430
|
+
}
|
|
13431
|
+
if (Object.keys(modules).length === 0) return void 0;
|
|
13432
|
+
const index = /^_+migrated_index\.js$/.test(rawIndex) && modules["index.js"] !== void 0 ? "index.js" : rawIndex;
|
|
13433
|
+
if (index.length > 0 && modules[index] === void 0) {
|
|
13434
|
+
warnings.push(`scriptIndex "${index}" does not exist in scriptAssets`);
|
|
13435
|
+
}
|
|
13436
|
+
return { index, modules };
|
|
13437
|
+
}
|
|
13176
13438
|
async function resolveRenderAssets(source, entities, projectState, warnings) {
|
|
13177
13439
|
const extraProjectHash = typeof projectState.extraProjectHash === "string" && projectState.extraProjectHash.length > 0 ? projectState.extraProjectHash : void 0;
|
|
13178
13440
|
if (extraProjectHash === void 0) {
|
|
@@ -13235,22 +13497,22 @@ async function resolveRenderAssets(source, entities, projectState, warnings) {
|
|
|
13235
13497
|
}
|
|
13236
13498
|
const meshes = [];
|
|
13237
13499
|
const paths = [...referenced.keys()].sort();
|
|
13238
|
-
await mapLimit(paths, 8, async (
|
|
13239
|
-
const asset = referenced.get(
|
|
13500
|
+
await mapLimit(paths, 8, async (path6) => {
|
|
13501
|
+
const asset = referenced.get(path6);
|
|
13240
13502
|
if (!asset) return;
|
|
13241
13503
|
const metadataHash = typeof asset.hash === "string" ? asset.hash : "";
|
|
13242
13504
|
if (metadataHash.length === 0) {
|
|
13243
|
-
warnings.push(`mesh ${
|
|
13505
|
+
warnings.push(`mesh ${path6} has no metadata hash`);
|
|
13244
13506
|
return;
|
|
13245
13507
|
}
|
|
13246
13508
|
const metadata = await readBlobJson(source, metadataHash);
|
|
13247
13509
|
if (!isRecord(metadata)) {
|
|
13248
|
-
warnings.push(`mesh ${
|
|
13510
|
+
warnings.push(`mesh ${path6} metadata ${metadataHash} is missing/undecodable`);
|
|
13249
13511
|
return;
|
|
13250
13512
|
}
|
|
13251
13513
|
const dataHash = typeof metadata.dataHash === "string" ? metadata.dataHash : "";
|
|
13252
13514
|
if (dataHash.length === 0) {
|
|
13253
|
-
warnings.push(`mesh ${
|
|
13515
|
+
warnings.push(`mesh ${path6} metadata has no dataHash`);
|
|
13254
13516
|
return;
|
|
13255
13517
|
}
|
|
13256
13518
|
const bounds = asVec3(metadata.bounds) ?? [1, 1, 1];
|
|
@@ -13261,13 +13523,14 @@ async function resolveRenderAssets(source, entities, projectState, warnings) {
|
|
|
13261
13523
|
})) : [];
|
|
13262
13524
|
const renderBoxOffset = asVec3(metadata.renderBoxOffset);
|
|
13263
13525
|
meshes.push({
|
|
13264
|
-
path:
|
|
13526
|
+
path: path6,
|
|
13265
13527
|
modelId: asNumber(asset.modelId, 0),
|
|
13266
13528
|
metadataHash,
|
|
13267
13529
|
dataHash,
|
|
13268
13530
|
bounds,
|
|
13269
13531
|
motionList,
|
|
13270
|
-
...renderBoxOffset ? { renderBoxOffset } : {}
|
|
13532
|
+
...renderBoxOffset ? { renderBoxOffset } : {},
|
|
13533
|
+
...typeof metadata.hashType === "string" ? { hashType: metadata.hashType } : typeof asset.hashType === "string" ? { hashType: asset.hashType } : {}
|
|
13271
13534
|
});
|
|
13272
13535
|
});
|
|
13273
13536
|
meshes.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
@@ -13338,6 +13601,19 @@ async function resolveWorldSeed(source, options = {}) {
|
|
|
13338
13601
|
for (const [reason, count] of skipReasons) {
|
|
13339
13602
|
warnings.push(`skipped ${count} entit${count === 1 ? "y" : "ies"}: ${reason}`);
|
|
13340
13603
|
}
|
|
13604
|
+
const seedInfo = [];
|
|
13605
|
+
for (const raw of entities) {
|
|
13606
|
+
if (!isRecord(raw)) continue;
|
|
13607
|
+
const value = isRecord(raw.value) ? raw.value : void 0;
|
|
13608
|
+
if (value === void 0) continue;
|
|
13609
|
+
const rawId = raw.id;
|
|
13610
|
+
const id = typeof rawId === "string" ? Number(rawId) : typeof rawId === "number" ? rawId : NaN;
|
|
13611
|
+
if (!Number.isFinite(id) || id <= 0) continue;
|
|
13612
|
+
const name = typeof value.name === "string" ? value.name : typeof raw.name === "string" ? raw.name : "";
|
|
13613
|
+
const tags = Array.isArray(value.tags) ? value.tags.filter((tag) => typeof tag === "string") : [];
|
|
13614
|
+
seedInfo.push({ id, name, tags });
|
|
13615
|
+
}
|
|
13616
|
+
seedInfo.sort((a, b) => a.id - b.id);
|
|
13341
13617
|
const voxelsRef = await resolveRef(source, head.voxels);
|
|
13342
13618
|
let voxels = null;
|
|
13343
13619
|
if (isRecord(voxelsRef)) {
|
|
@@ -13370,6 +13646,15 @@ async function resolveWorldSeed(source, options = {}) {
|
|
|
13370
13646
|
}
|
|
13371
13647
|
}
|
|
13372
13648
|
const render = await resolveRenderAssets(source, entities, stateRecord, warnings);
|
|
13649
|
+
const scripts = await resolveScripts(source, head, warnings);
|
|
13650
|
+
const audioRef = await resolveRef(source, head.audioAssets);
|
|
13651
|
+
const audioAssets = [];
|
|
13652
|
+
if (isRecord(audioRef)) {
|
|
13653
|
+
for (const [path6, raw] of Object.entries(audioRef)) {
|
|
13654
|
+
if (!isRecord(raw) || typeof raw.hash !== "string" || raw.hash.length === 0) continue;
|
|
13655
|
+
audioAssets.push({ path: path6, hash: raw.hash });
|
|
13656
|
+
}
|
|
13657
|
+
}
|
|
13373
13658
|
return {
|
|
13374
13659
|
version: WORLD_SEED_VERSION,
|
|
13375
13660
|
mapId: source.worldId,
|
|
@@ -13382,30 +13667,14 @@ async function resolveWorldSeed(source, options = {}) {
|
|
|
13382
13667
|
bodies,
|
|
13383
13668
|
voxels,
|
|
13384
13669
|
render,
|
|
13670
|
+
...scripts !== void 0 ? { scripts } : {},
|
|
13671
|
+
...seedInfo.length > 0 ? { seedInfo } : {},
|
|
13672
|
+
...audioAssets.length > 0 ? { audioAssets } : {},
|
|
13385
13673
|
entityCount: entities.length,
|
|
13386
13674
|
warnings
|
|
13387
13675
|
};
|
|
13388
13676
|
}
|
|
13389
13677
|
|
|
13390
|
-
// src/core/maps/block-info.ts
|
|
13391
|
-
var BLOCK_INFO_HASH = "QmW2E9E8ipYUifsCfkMj5SULYMYbFQvP6BQxo52atXw7Zj";
|
|
13392
|
-
function decodeBlockInfo(bytes) {
|
|
13393
|
-
try {
|
|
13394
|
-
return BlockInfoSchema.patch(BlockInfoSchema.identity, new MuReadStream(bytes));
|
|
13395
|
-
} catch {
|
|
13396
|
-
return null;
|
|
13397
|
-
}
|
|
13398
|
-
}
|
|
13399
|
-
async function readBlockInfoBytes(reader, worldId, hash = BLOCK_INFO_HASH) {
|
|
13400
|
-
try {
|
|
13401
|
-
const bytes = await reader.read(`worlds/${worldId}/data/blobs/${hash}`);
|
|
13402
|
-
if (bytes === null || bytes.length === 0) return null;
|
|
13403
|
-
return bytes;
|
|
13404
|
-
} catch {
|
|
13405
|
-
return null;
|
|
13406
|
-
}
|
|
13407
|
-
}
|
|
13408
|
-
|
|
13409
13678
|
// src/core/maps/seed-pack.ts
|
|
13410
13679
|
var SEED_PACK_VERSION = 1;
|
|
13411
13680
|
var SEED_PACK_FORMAT = "cajonzero-seed";
|
|
@@ -13417,14 +13686,35 @@ function bytesToBase64(bytes) {
|
|
|
13417
13686
|
}
|
|
13418
13687
|
return btoa(binary);
|
|
13419
13688
|
}
|
|
13420
|
-
|
|
13421
|
-
|
|
13689
|
+
var SCRIPT_PACK_FORMAT = "cajonzero-scripts";
|
|
13690
|
+
var SCRIPT_PACK_VERSION = 1;
|
|
13691
|
+
function encodeScriptsPack(seed, slug) {
|
|
13692
|
+
const scripts = seed.scripts;
|
|
13693
|
+
if (scripts === void 0) throw new Error("seed has no scripts");
|
|
13694
|
+
const document = {
|
|
13695
|
+
format: SCRIPT_PACK_FORMAT,
|
|
13696
|
+
version: SCRIPT_PACK_VERSION,
|
|
13697
|
+
slug,
|
|
13698
|
+
mapId: seed.mapId,
|
|
13699
|
+
index: scripts.index,
|
|
13700
|
+
modules: scripts.modules,
|
|
13701
|
+
...scripts.revision !== void 0 && scripts.revision.length > 0 ? { revision: scripts.revision } : {}
|
|
13702
|
+
};
|
|
13703
|
+
return new TextEncoder().encode(JSON.stringify(document));
|
|
13704
|
+
}
|
|
13705
|
+
function encodeSeedPack(seed, blockInfoBytes, options = {}) {
|
|
13706
|
+
const {
|
|
13707
|
+
blockInfo: _decodedPalette,
|
|
13708
|
+
scripts: _privateScripts,
|
|
13709
|
+
...jsonSeed
|
|
13710
|
+
} = seed;
|
|
13422
13711
|
const document = {
|
|
13423
13712
|
format: SEED_PACK_FORMAT,
|
|
13424
13713
|
version: SEED_PACK_VERSION,
|
|
13425
13714
|
mapId: seed.mapId,
|
|
13426
13715
|
seed: {
|
|
13427
13716
|
...jsonSeed,
|
|
13717
|
+
...options.includeScripts === true && seed.scripts !== void 0 ? { scripts: seed.scripts } : {},
|
|
13428
13718
|
voxels: seed.voxels === null || seed.voxels === void 0 ? null : {
|
|
13429
13719
|
shape: seed.voxels.shape,
|
|
13430
13720
|
chunkCount: seed.voxels.chunkCount,
|
|
@@ -13437,143 +13727,330 @@ function encodeSeedPack(seed, blockInfoBytes) {
|
|
|
13437
13727
|
return new TextEncoder().encode(JSON.stringify(document));
|
|
13438
13728
|
}
|
|
13439
13729
|
|
|
13440
|
-
// src/
|
|
13441
|
-
var
|
|
13730
|
+
// src/maps/import.ts
|
|
13731
|
+
var DEFAULT_MAPS_FILE = "cajonzero/maps.json";
|
|
13732
|
+
var DEFAULT_PUBLIC_DIR = "public";
|
|
13733
|
+
var DEFAULT_SCRIPTS_DIR = path4.join("cajonzero", "private");
|
|
13734
|
+
var MapImportError = class extends Error {
|
|
13442
13735
|
code;
|
|
13443
13736
|
constructor(code, message) {
|
|
13444
13737
|
super(message);
|
|
13445
|
-
this.name = "
|
|
13738
|
+
this.name = "MapImportError";
|
|
13446
13739
|
this.code = code;
|
|
13447
13740
|
}
|
|
13448
13741
|
};
|
|
13449
|
-
|
|
13450
|
-
|
|
13451
|
-
|
|
13452
|
-
|
|
13453
|
-
|
|
13454
|
-
|
|
13455
|
-
|
|
13456
|
-
|
|
13742
|
+
function resolveOptions(options) {
|
|
13743
|
+
const cwd = options.cwd ?? process.cwd();
|
|
13744
|
+
return {
|
|
13745
|
+
cwd,
|
|
13746
|
+
mapsPath: path4.resolve(cwd, options.maps ?? DEFAULT_MAPS_FILE),
|
|
13747
|
+
publicDir: path4.resolve(cwd, options.publicDir ?? DEFAULT_PUBLIC_DIR),
|
|
13748
|
+
scriptsDir: path4.resolve(cwd, options.scriptsDir ?? DEFAULT_SCRIPTS_DIR),
|
|
13749
|
+
gzip: options.gzip ?? true,
|
|
13750
|
+
resetRoot: options.resetRoot ?? false
|
|
13751
|
+
};
|
|
13457
13752
|
}
|
|
13458
|
-
|
|
13459
|
-
|
|
13460
|
-
|
|
13461
|
-
|
|
13462
|
-
|
|
13463
|
-
|
|
13464
|
-
|
|
13465
|
-
|
|
13466
|
-
|
|
13467
|
-
|
|
13468
|
-
|
|
13469
|
-
|
|
13470
|
-
|
|
13471
|
-
}
|
|
13472
|
-
|
|
13473
|
-
|
|
13474
|
-
const relative = assertRelativeMapPath(relPath);
|
|
13475
|
-
if (this.cache.has(relative)) return this.cache.get(relative) ?? null;
|
|
13476
|
-
let pending = this.inflight.get(relative);
|
|
13477
|
-
if (pending === void 0) {
|
|
13478
|
-
pending = this.fetchFile(relative);
|
|
13479
|
-
this.inflight.set(relative, pending);
|
|
13480
|
-
}
|
|
13481
|
-
let bytes;
|
|
13482
|
-
try {
|
|
13483
|
-
bytes = await pending;
|
|
13484
|
-
} finally {
|
|
13485
|
-
this.inflight.delete(relative);
|
|
13753
|
+
function readMapCatalogFile(mapsPath) {
|
|
13754
|
+
if (!existsSync(mapsPath)) return EMPTY_MAP_CATALOG;
|
|
13755
|
+
let parsed;
|
|
13756
|
+
try {
|
|
13757
|
+
parsed = JSON.parse(readFileSync(mapsPath, "utf8").replace(/^\uFEFF/, ""));
|
|
13758
|
+
} catch (error) {
|
|
13759
|
+
throw new MapImportError(
|
|
13760
|
+
"INVALID_CATALOG",
|
|
13761
|
+
`${mapsPath} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`
|
|
13762
|
+
);
|
|
13763
|
+
}
|
|
13764
|
+
try {
|
|
13765
|
+
return parseMapCatalog(parsed);
|
|
13766
|
+
} catch (error) {
|
|
13767
|
+
if (error instanceof MapCatalogError) {
|
|
13768
|
+
throw new MapImportError("INVALID_CATALOG", `${mapsPath}: ${error.message}`);
|
|
13486
13769
|
}
|
|
13487
|
-
|
|
13488
|
-
return bytes;
|
|
13770
|
+
throw error;
|
|
13489
13771
|
}
|
|
13490
|
-
|
|
13491
|
-
|
|
13492
|
-
|
|
13493
|
-
|
|
13772
|
+
}
|
|
13773
|
+
function writeFileAtomic(filePath, data) {
|
|
13774
|
+
mkdirSync(path4.dirname(filePath), { recursive: true });
|
|
13775
|
+
const temp = `${filePath}.tmp-${process.pid}-${Date.now().toString(36)}`;
|
|
13776
|
+
writeFileSync(temp, data);
|
|
13777
|
+
renameSync(temp, filePath);
|
|
13778
|
+
}
|
|
13779
|
+
function writeCatalog(mapsPath, catalog) {
|
|
13780
|
+
const document = {
|
|
13781
|
+
version: catalog.version,
|
|
13782
|
+
maps: catalog.maps
|
|
13783
|
+
};
|
|
13784
|
+
writeFileAtomic(mapsPath, `${JSON.stringify(document, null, 2)}
|
|
13785
|
+
`);
|
|
13786
|
+
}
|
|
13787
|
+
function deriveMapSlug(archive, override) {
|
|
13788
|
+
if (override !== void 0) {
|
|
13494
13789
|
try {
|
|
13495
|
-
return
|
|
13790
|
+
return assertMapSlug(override);
|
|
13496
13791
|
} catch {
|
|
13497
|
-
|
|
13792
|
+
throw new MapImportError("INVALID_SLUG", `invalid map slug "${override}"`);
|
|
13498
13793
|
}
|
|
13499
13794
|
}
|
|
13500
|
-
|
|
13501
|
-
|
|
13502
|
-
|
|
13503
|
-
|
|
13504
|
-
|
|
13505
|
-
|
|
13506
|
-
|
|
13507
|
-
|
|
13508
|
-
const
|
|
13509
|
-
|
|
13510
|
-
|
|
13511
|
-
|
|
13512
|
-
|
|
13513
|
-
|
|
13514
|
-
|
|
13515
|
-
|
|
13516
|
-
|
|
13517
|
-
|
|
13518
|
-
|
|
13519
|
-
|
|
13520
|
-
|
|
13521
|
-
|
|
13522
|
-
|
|
13523
|
-
|
|
13524
|
-
|
|
13525
|
-
|
|
13526
|
-
|
|
13527
|
-
|
|
13528
|
-
|
|
13529
|
-
|
|
13530
|
-
|
|
13531
|
-
|
|
13532
|
-
|
|
13533
|
-
|
|
13534
|
-
|
|
13535
|
-
|
|
13536
|
-
|
|
13795
|
+
const world = archive.worlds[0];
|
|
13796
|
+
const candidates = [
|
|
13797
|
+
archive.bundle.permanentMapGroupId,
|
|
13798
|
+
archive.bundle.mapGroupId,
|
|
13799
|
+
world?.worldId
|
|
13800
|
+
];
|
|
13801
|
+
for (const candidate of candidates) {
|
|
13802
|
+
if (typeof candidate !== "string") continue;
|
|
13803
|
+
const slug = toMapSlug(candidate);
|
|
13804
|
+
if (slug.length > 0) return slug;
|
|
13805
|
+
}
|
|
13806
|
+
throw new MapImportError(
|
|
13807
|
+
"INVALID_SLUG",
|
|
13808
|
+
"cannot derive a slug from the archive; pass --slug <slug>"
|
|
13809
|
+
);
|
|
13810
|
+
}
|
|
13811
|
+
function toMapSlug(raw) {
|
|
13812
|
+
const slug = raw.toLowerCase().replace(/[^a-z0-9-_]+/g, "-").replace(/^[-_]+/, "").replace(/[-_]+$/, "").slice(0, 63);
|
|
13813
|
+
return isMapSlug(slug) ? slug : "";
|
|
13814
|
+
}
|
|
13815
|
+
function mapPublicDir(publicDir, slug) {
|
|
13816
|
+
return path4.join(publicDir, "maps", slug);
|
|
13817
|
+
}
|
|
13818
|
+
function seedPackName(gzip) {
|
|
13819
|
+
return gzip ? "seed.json.gz" : "seed.json";
|
|
13820
|
+
}
|
|
13821
|
+
function scriptsPackPath(scriptsDir, slug, gzip) {
|
|
13822
|
+
return path4.join(scriptsDir, `${slug}.json${gzip ? ".gz" : ""}`);
|
|
13823
|
+
}
|
|
13824
|
+
function publicRoot(slug) {
|
|
13825
|
+
return `/maps/${slug}/`;
|
|
13826
|
+
}
|
|
13827
|
+
function readArchive(archivePath) {
|
|
13828
|
+
if (!existsSync(archivePath) || !statSync(archivePath).isFile()) {
|
|
13829
|
+
throw new MapImportError("ARCHIVE_NOT_FOUND", `archive not found: ${archivePath}`);
|
|
13830
|
+
}
|
|
13831
|
+
try {
|
|
13832
|
+
return readBoxplayFile(archivePath);
|
|
13833
|
+
} catch (error) {
|
|
13834
|
+
throw new MapImportError(
|
|
13835
|
+
"INVALID_ARCHIVE",
|
|
13836
|
+
`cannot read ${path4.basename(archivePath)}: ${error instanceof Error ? error.message : String(error)}`
|
|
13837
|
+
);
|
|
13838
|
+
}
|
|
13839
|
+
}
|
|
13840
|
+
async function importMap(action, archivePath, options, slugOverride) {
|
|
13841
|
+
const resolved = resolveOptions(options);
|
|
13842
|
+
const archive = readArchive(path4.resolve(resolved.cwd, archivePath));
|
|
13843
|
+
const slug = deriveMapSlug(archive, slugOverride ?? options.slug);
|
|
13844
|
+
const catalog = readMapCatalogFile(resolved.mapsPath);
|
|
13845
|
+
const existing = findMap(catalog, slug);
|
|
13846
|
+
const targetDir = mapPublicDir(resolved.publicDir, slug);
|
|
13847
|
+
const targetExists = existsSync(targetDir);
|
|
13848
|
+
if (action === "add") {
|
|
13849
|
+
if (existing !== void 0 || targetExists) {
|
|
13850
|
+
throw new MapImportError(
|
|
13851
|
+
"SLUG_EXISTS",
|
|
13852
|
+
`map "${slug}" already exists; use: cj0 update ${slug} <file.boxplay>`
|
|
13537
13853
|
);
|
|
13538
13854
|
}
|
|
13539
|
-
|
|
13855
|
+
} else if (existing === void 0) {
|
|
13856
|
+
throw new MapImportError(
|
|
13857
|
+
"MAP_NOT_FOUND",
|
|
13858
|
+
`map "${slug}" is not in ${path4.relative(resolved.cwd, resolved.mapsPath)}; use: cj0 add <file.boxplay> --slug ${slug}`
|
|
13859
|
+
);
|
|
13540
13860
|
}
|
|
13541
|
-
|
|
13542
|
-
|
|
13543
|
-
|
|
13544
|
-
}
|
|
13545
|
-
|
|
13546
|
-
const
|
|
13547
|
-
|
|
13548
|
-
|
|
13549
|
-
|
|
13550
|
-
|
|
13551
|
-
|
|
13552
|
-
|
|
13553
|
-
|
|
13554
|
-
|
|
13555
|
-
return assertWorldId(candidate);
|
|
13556
|
-
}
|
|
13557
|
-
async function loadWorldSeedGraphFromHttp(entry, options = {}) {
|
|
13558
|
-
const source = new HttpMapSource(entry.root, options);
|
|
13559
|
-
const worldId = entry.worldId ?? await resolveWorldId(source);
|
|
13560
|
-
const manifest = await source.readJson(
|
|
13561
|
-
`worlds/${worldId}/manifest.json`
|
|
13562
|
-
);
|
|
13563
|
-
if (manifest === null) {
|
|
13564
|
-
fail2("MAP_NO_WORLD", `worlds/${worldId}/manifest.json is missing or not JSON`);
|
|
13861
|
+
const world = archive.worlds[0];
|
|
13862
|
+
if (world === void 0) {
|
|
13863
|
+
throw new MapImportError("INVALID_ARCHIVE", "archive contains no world");
|
|
13864
|
+
}
|
|
13865
|
+
const worldId = world.worldId;
|
|
13866
|
+
const source = archiveToWorldSeedSource(archive);
|
|
13867
|
+
let seed;
|
|
13868
|
+
try {
|
|
13869
|
+
seed = await resolveWorldSeed(source);
|
|
13870
|
+
} catch (error) {
|
|
13871
|
+
throw new MapImportError(
|
|
13872
|
+
"INVALID_ARCHIVE",
|
|
13873
|
+
`cannot resolve the map seed: ${error instanceof Error ? error.message : String(error)}`
|
|
13874
|
+
);
|
|
13565
13875
|
}
|
|
13566
|
-
const
|
|
13567
|
-
|
|
13568
|
-
|
|
13876
|
+
const blockInfoBytes = await readBlockInfoBytes(source.reader, seed.mapId) ?? void 0;
|
|
13877
|
+
const scriptBlobs = new Set(
|
|
13878
|
+
Object.values(seed.scripts?.modules ?? {}).map(
|
|
13879
|
+
(module) => `worlds/${seed.mapId}/data/blobs/${module.hash}`
|
|
13880
|
+
)
|
|
13569
13881
|
);
|
|
13570
|
-
const
|
|
13571
|
-
const
|
|
13882
|
+
const seedPack = encodeSeedPack(seed, blockInfoBytes);
|
|
13883
|
+
const seedData = resolved.gzip ? gzipSync(seedPack, { level: 9 }) : seedPack;
|
|
13884
|
+
const scriptPack = seed.scripts !== void 0 ? (() => {
|
|
13885
|
+
seed.scripts.revision = versionOf(archive, existing) ?? "";
|
|
13886
|
+
const packed = encodeScriptsPack(seed, slug);
|
|
13887
|
+
return resolved.gzip ? gzipSync(packed, { level: 9 }) : packed;
|
|
13888
|
+
})() : void 0;
|
|
13889
|
+
const mapsDir = path4.join(resolved.publicDir, "maps");
|
|
13890
|
+
mkdirSync(mapsDir, { recursive: true });
|
|
13891
|
+
const tempDir = path4.join(mapsDir, `.tmp-${slug}-${process.pid}-${Date.now().toString(36)}`);
|
|
13892
|
+
let files = 0;
|
|
13893
|
+
let bytes = 0;
|
|
13894
|
+
try {
|
|
13895
|
+
mkdirSync(tempDir, { recursive: true });
|
|
13896
|
+
for (const file of archive.files) {
|
|
13897
|
+
if (scriptBlobs.has(file.path)) continue;
|
|
13898
|
+
const destination = path4.join(tempDir, ...file.path.split("/"));
|
|
13899
|
+
mkdirSync(path4.dirname(destination), { recursive: true });
|
|
13900
|
+
writeFileSync(destination, file.data);
|
|
13901
|
+
files += 1;
|
|
13902
|
+
bytes += file.data.length;
|
|
13903
|
+
}
|
|
13904
|
+
const seedName = seedPackName(resolved.gzip);
|
|
13905
|
+
writeFileSync(path4.join(tempDir, seedName), seedData);
|
|
13906
|
+
files += 1;
|
|
13907
|
+
bytes += seedData.length;
|
|
13908
|
+
installPublicDir(tempDir, targetDir);
|
|
13909
|
+
} catch (error) {
|
|
13910
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
13911
|
+
throw error;
|
|
13912
|
+
}
|
|
13913
|
+
const scriptsPath = scriptsPackPath(resolved.scriptsDir, slug, resolved.gzip);
|
|
13914
|
+
if (scriptPack !== void 0) {
|
|
13915
|
+
writeFileAtomic(scriptsPath, scriptPack);
|
|
13916
|
+
rmSync(scriptsPackPath(resolved.scriptsDir, slug, !resolved.gzip), { force: true });
|
|
13917
|
+
} else {
|
|
13918
|
+
rmSync(scriptsPackPath(resolved.scriptsDir, slug, true), { force: true });
|
|
13919
|
+
rmSync(scriptsPackPath(resolved.scriptsDir, slug, false), { force: true });
|
|
13920
|
+
}
|
|
13921
|
+
const name = seed.projectName ?? existing?.name;
|
|
13922
|
+
const author = seed.author ?? existing?.author;
|
|
13923
|
+
const version = versionOf(archive, existing);
|
|
13924
|
+
const root = action === "update" && !resolved.resetRoot && existing !== void 0 ? existing.root : publicRoot(slug);
|
|
13925
|
+
const entry = {
|
|
13926
|
+
slug,
|
|
13927
|
+
root,
|
|
13928
|
+
worldId,
|
|
13929
|
+
...name !== void 0 ? { name } : {},
|
|
13930
|
+
...author !== void 0 ? { author } : {},
|
|
13931
|
+
...version !== void 0 ? { version } : {},
|
|
13932
|
+
...action === "update" && !resolved.resetRoot && existing?.assetRoot !== void 0 ? { assetRoot: existing.assetRoot } : {},
|
|
13933
|
+
...action === "update" && !resolved.resetRoot && existing?.cover !== void 0 ? { cover: existing.cover } : {},
|
|
13934
|
+
...scriptPack !== void 0 ? { scriptsFile: projectRelative(resolved.cwd, scriptsPath) } : {}
|
|
13935
|
+
};
|
|
13936
|
+
const maps = [...catalog.maps.filter((map) => map.slug !== slug), entry];
|
|
13937
|
+
writeCatalog(resolved.mapsPath, { version: catalog.version, maps });
|
|
13938
|
+
return {
|
|
13939
|
+
action,
|
|
13940
|
+
slug,
|
|
13941
|
+
root,
|
|
13942
|
+
worldId,
|
|
13943
|
+
mapId: seed.mapId,
|
|
13944
|
+
...name !== void 0 ? { name } : {},
|
|
13945
|
+
...version !== void 0 ? { version } : {},
|
|
13946
|
+
publicDir: targetDir,
|
|
13947
|
+
seedPack: path4.join(targetDir, seedPackName(resolved.gzip)),
|
|
13948
|
+
...scriptPack !== void 0 ? {
|
|
13949
|
+
scriptsPack: scriptsPath,
|
|
13950
|
+
scriptsFile: projectRelative(resolved.cwd, scriptsPath)
|
|
13951
|
+
} : {},
|
|
13952
|
+
files,
|
|
13953
|
+
bytes,
|
|
13954
|
+
seedPackBytes: seedData.length,
|
|
13955
|
+
scriptModules: Object.keys(seed.scripts?.modules ?? {}).length,
|
|
13956
|
+
warnings: seed.warnings
|
|
13957
|
+
};
|
|
13958
|
+
}
|
|
13959
|
+
function projectRelative(cwd, dir) {
|
|
13960
|
+
return path4.relative(cwd, dir).split(path4.sep).join("/") || ".";
|
|
13961
|
+
}
|
|
13962
|
+
function defaultScriptPackFile(entry, scriptsDir) {
|
|
13963
|
+
const gz = scriptsPackPath(scriptsDir, entry.slug, true);
|
|
13964
|
+
return existsSync(gz) ? gz : scriptsPackPath(scriptsDir, entry.slug, false);
|
|
13965
|
+
}
|
|
13966
|
+
function mapScriptsFile(entry, options = {}) {
|
|
13967
|
+
const resolved = resolveOptions(options);
|
|
13968
|
+
return entry.scriptsFile !== void 0 ? path4.resolve(resolved.cwd, entry.scriptsFile) : defaultScriptPackFile(entry, resolved.scriptsDir);
|
|
13969
|
+
}
|
|
13970
|
+
function listScriptPackLocations(options = {}) {
|
|
13971
|
+
return readMapCatalogFile(resolveOptions(options).mapsPath).maps.flatMap((entry) => {
|
|
13972
|
+
const file = mapScriptsFile(entry, options);
|
|
13973
|
+
return existsSync(file) ? [{ slug: entry.slug, file }] : [];
|
|
13974
|
+
});
|
|
13975
|
+
}
|
|
13976
|
+
function versionOf(archive, existing) {
|
|
13977
|
+
const value = archive.bundle.version;
|
|
13978
|
+
if (typeof value === "string" && value.length > 0) return value;
|
|
13979
|
+
return existing?.version;
|
|
13980
|
+
}
|
|
13981
|
+
function installPublicDir(tempDir, targetDir) {
|
|
13982
|
+
const backup = `${targetDir}.bak-${process.pid}-${Date.now().toString(36)}`;
|
|
13983
|
+
const hadTarget = existsSync(targetDir);
|
|
13984
|
+
if (hadTarget) renameSync(targetDir, backup);
|
|
13985
|
+
try {
|
|
13986
|
+
renameSync(tempDir, targetDir);
|
|
13987
|
+
if (hadTarget) rmSync(backup, { recursive: true, force: true });
|
|
13988
|
+
} catch (error) {
|
|
13989
|
+
rmSync(targetDir, { recursive: true, force: true });
|
|
13990
|
+
if (hadTarget && existsSync(backup)) renameSync(backup, targetDir);
|
|
13991
|
+
throw error;
|
|
13992
|
+
}
|
|
13993
|
+
}
|
|
13994
|
+
function addMap(archivePath, options = {}) {
|
|
13995
|
+
return importMap("add", archivePath, options);
|
|
13996
|
+
}
|
|
13997
|
+
function updateMap(slug, archivePath, options = {}) {
|
|
13998
|
+
return importMap("update", archivePath, options, slug);
|
|
13999
|
+
}
|
|
14000
|
+
function listMaps(options = {}) {
|
|
14001
|
+
const resolved = resolveOptions(options);
|
|
14002
|
+
const catalog = readMapCatalogFile(resolved.mapsPath);
|
|
14003
|
+
return catalog.maps.map((entry) => {
|
|
14004
|
+
const dir = mapPublicDir(resolved.publicDir, entry.slug);
|
|
14005
|
+
const imported = existsSync(dir);
|
|
14006
|
+
const seeded = existsSync(path4.join(dir, seedPackName(true))) || existsSync(path4.join(dir, seedPackName(false)));
|
|
14007
|
+
const hasScripts = existsSync(mapScriptsFile(entry, options));
|
|
14008
|
+
return {
|
|
14009
|
+
slug: entry.slug,
|
|
14010
|
+
root: entry.root,
|
|
14011
|
+
...entry.worldId !== void 0 ? { worldId: entry.worldId } : {},
|
|
14012
|
+
...entry.name !== void 0 ? { name: entry.name } : {},
|
|
14013
|
+
...entry.version !== void 0 ? { version: entry.version } : {},
|
|
14014
|
+
imported,
|
|
14015
|
+
seeded,
|
|
14016
|
+
hasScripts
|
|
14017
|
+
};
|
|
14018
|
+
});
|
|
14019
|
+
}
|
|
14020
|
+
function removeMap(slug, options = {}) {
|
|
14021
|
+
const resolved = resolveOptions(options);
|
|
14022
|
+
const catalog = readMapCatalogFile(resolved.mapsPath);
|
|
14023
|
+
const existing = findMap(catalog, slug);
|
|
14024
|
+
if (existing === void 0) {
|
|
14025
|
+
throw new MapImportError("MAP_NOT_FOUND", `map "${slug}" is not in the catalog`);
|
|
14026
|
+
}
|
|
14027
|
+
const dir = mapPublicDir(resolved.publicDir, slug);
|
|
14028
|
+
const removedDir = existsSync(dir) ? dir : void 0;
|
|
14029
|
+
rmSync(dir, { recursive: true, force: true });
|
|
14030
|
+
const removedScripts = [];
|
|
14031
|
+
const scriptFiles = /* @__PURE__ */ new Set([
|
|
14032
|
+
mapScriptsFile(existing, options),
|
|
14033
|
+
scriptsPackPath(resolved.scriptsDir, slug, true),
|
|
14034
|
+
scriptsPackPath(resolved.scriptsDir, slug, false)
|
|
14035
|
+
]);
|
|
14036
|
+
for (const file of scriptFiles) {
|
|
14037
|
+
if (!existsSync(file)) continue;
|
|
14038
|
+
rmSync(file, { force: true });
|
|
14039
|
+
removedScripts.push(file);
|
|
14040
|
+
}
|
|
14041
|
+
const maps = catalog.maps.filter((map) => map.slug !== slug);
|
|
14042
|
+
writeCatalog(resolved.mapsPath, { version: catalog.version, maps });
|
|
13572
14043
|
return {
|
|
13573
|
-
|
|
13574
|
-
...
|
|
14044
|
+
slug,
|
|
14045
|
+
...removedDir !== void 0 ? { removedDir } : {},
|
|
14046
|
+
removedScripts
|
|
13575
14047
|
};
|
|
13576
14048
|
}
|
|
14049
|
+
function readScriptsPackText(file) {
|
|
14050
|
+
if (!existsSync(file)) return void 0;
|
|
14051
|
+
const raw = readFileSync(file);
|
|
14052
|
+
return file.endsWith(".gz") ? gunzipSync(raw).toString("utf8") : raw.toString("utf8");
|
|
14053
|
+
}
|
|
13577
14054
|
|
|
13578
14055
|
// src/scaffold/templates.ts
|
|
13579
14056
|
var SCAFFOLD_ENTRY_PATH = "src/index.ts";
|
|
@@ -13643,7 +14120,7 @@ var SCAFFOLD_CONFIG_CONTENT = `${JSON.stringify(
|
|
|
13643
14120
|
`;
|
|
13644
14121
|
var SCAFFOLD_MAPS_CONTENT = `${JSON.stringify({ version: 1, maps: [] }, null, 2)}
|
|
13645
14122
|
`;
|
|
13646
|
-
var
|
|
14123
|
+
var SCAFFOLD_PUBLIC_KEEP_PATH = "public/.gitkeep";
|
|
13647
14124
|
function packageJson(options) {
|
|
13648
14125
|
const manifest = {
|
|
13649
14126
|
name: options.packageName,
|
|
@@ -13651,14 +14128,12 @@ function packageJson(options) {
|
|
|
13651
14128
|
private: true,
|
|
13652
14129
|
type: "module",
|
|
13653
14130
|
scripts: {
|
|
13654
|
-
dev:
|
|
13655
|
-
|
|
13656
|
-
//
|
|
13657
|
-
|
|
13658
|
-
|
|
13659
|
-
|
|
13660
|
-
// ready-to-deploy project. Seed packs are network work and stay out of it.
|
|
13661
|
-
prepare: PREPARE_ASSETS
|
|
14131
|
+
dev: "wrangler dev",
|
|
14132
|
+
// `cj0 deploy` syncs the packaged UI, uploads the private map-script
|
|
14133
|
+
// packs, then runs `wrangler deploy` — one command, no build chain.
|
|
14134
|
+
deploy: "cj0 deploy",
|
|
14135
|
+
sync: "cj0 sync",
|
|
14136
|
+
maps: "cj0 list"
|
|
13662
14137
|
},
|
|
13663
14138
|
dependencies: {
|
|
13664
14139
|
cajonzero: options.cajonzeroRange,
|
|
@@ -13683,11 +14158,16 @@ function wranglerConfig(options) {
|
|
|
13683
14158
|
` "compatibility_date": ${JSON.stringify(options.compatibilityDate)},`,
|
|
13684
14159
|
" // Deliberately NO `nodejs_compat`: cajonzero's worker path is Node-free.",
|
|
13685
14160
|
' "compatibility_flags": [],',
|
|
13686
|
-
" //
|
|
13687
|
-
" //
|
|
14161
|
+
" // QuickJS is a build-time-compiled WASM module; workerd forbids runtime",
|
|
14162
|
+
" // WebAssembly codegen. Keep this rule when editing the config.",
|
|
14163
|
+
' "rules": [',
|
|
14164
|
+
' { "type": "CompiledWasm", "globs": ["**/*.wasm"], "fallthrough": true }',
|
|
14165
|
+
" ],",
|
|
14166
|
+
" // Static UI + imported maps (play lobby + owner admin console).",
|
|
14167
|
+
" // `cj0 sync` writes the packaged UI here; `cj0 add` writes public/maps/.",
|
|
13688
14168
|
' "assets": {',
|
|
13689
|
-
' "directory": "
|
|
13690
|
-
" // Binding so the room can read seed packs
|
|
14169
|
+
' "directory": "public",',
|
|
14170
|
+
" // Binding so the room can read imported maps + seed packs at runtime.",
|
|
13691
14171
|
' "binding": "ASSETS",',
|
|
13692
14172
|
" // History routing: deep links (/play/x, /admin/bans) boot index.html.",
|
|
13693
14173
|
' "not_found_handling": "single-page-application",',
|
|
@@ -13774,24 +14254,25 @@ function readme(options) {
|
|
|
13774
14254
|
"",
|
|
13775
14255
|
"## \u5730\u56FE",
|
|
13776
14256
|
"",
|
|
13777
|
-
"\u5730\u56FE\
|
|
13778
|
-
"\u518D\u5728 `cajonzero/maps.json` \u767B\u8BB0\uFF1A",
|
|
14257
|
+
"\u5730\u56FE\u5728\u672C\u5730\u5BFC\u5165\uFF0C\u968F worker \u4E00\u6B21\u90E8\u7F72\uFF08\u9759\u6001\u8D44\u6E90 `public/`\uFF09\uFF1A",
|
|
13779
14258
|
"",
|
|
13780
|
-
"```
|
|
13781
|
-
"
|
|
13782
|
-
|
|
13783
|
-
|
|
13784
|
-
"
|
|
13785
|
-
' "slug": "omega",',
|
|
13786
|
-
' "root": "https://cdn.example.com/cajonzero/omega/",',
|
|
13787
|
-
' "worldId": "project-omega",',
|
|
13788
|
-
' "name": "Omega City Reloaded"',
|
|
13789
|
-
" }",
|
|
13790
|
-
" ]",
|
|
13791
|
-
"}",
|
|
14259
|
+
"```bash",
|
|
14260
|
+
"npx cj0 add ./race.boxplay # \u89E3\u5305\u5230 public/maps/race/ \u5E76\u751F\u6210 seed",
|
|
14261
|
+
"npx cj0 update race ./race-v2.boxplay # \u8986\u76D6\u5DF2\u6709 slug",
|
|
14262
|
+
"npx cj0 list # \u67E5\u770B catalog + \u672C\u5730\u5BFC\u5165\u72B6\u6001",
|
|
14263
|
+
"npx cj0 remove race # \u5220\u9664\u5730\u56FE\u3001\u79C1\u6709\u811A\u672C\u4E0E catalog \u6761\u76EE",
|
|
13792
14264
|
"```",
|
|
13793
14265
|
"",
|
|
13794
|
-
"`
|
|
14266
|
+
"`add/update` \u4F1A\uFF1A",
|
|
14267
|
+
"",
|
|
14268
|
+
"1. \u628A\u516C\u5F00\u5730\u56FE\u8D44\u6E90\u89E3\u5305\u5230 `public/maps/<slug>/`\uFF1B",
|
|
14269
|
+
"2. \u5728\u672C\u5730\u89E3\u6790\u4E16\u754C\u56FE\u5E76\u5199\u5165 `public/maps/<slug>/seed.json.gz`\uFF1B",
|
|
14270
|
+
"3. \u628A**\u670D\u52A1\u7AEF\u811A\u672C**\u5199\u5230 `cajonzero/private/<slug>.json.gz`\uFF0C\u4E0D\u8FDB\u5165 `public/`\uFF1B",
|
|
14271
|
+
'4. \u5728 `cajonzero/maps.json` \u5199\u5165 `"root": "/maps/<slug>/"`\uFF0C\u5E76\u628A\u670D\u52A1\u7AEF\u811A\u672C\u6587\u4EF6\u8BB0\u5F55\u4E3A',
|
|
14272
|
+
' `"scriptsFile": "cajonzero/private/<slug>.json.gz"`\uFF08\u8BE5\u76EE\u5F55\u4F1A\u63D0\u4EA4\uFF0CCF \u6784\u5EFA\u65F6 `cj0 deploy` \u53EF\u4E0A\u4F20\uFF09\u3002',
|
|
14273
|
+
"",
|
|
14274
|
+
"\u9700\u8981\u72EC\u7ACB CDN \u65F6\uFF0C\u624B\u52A8\u628A\u8BE5\u6761\u76EE\u7684 `root` \u6539\u6210 `https://cdn.example.com/.../` \u5373\u53EF\uFF1B",
|
|
14275
|
+
"`cj0 update` \u9ED8\u8BA4\u4FDD\u7559\u4F60\u6539\u8FC7\u7684 `root`\uFF08`--reset-root` \u53EF\u6062\u590D\uFF09\u3002",
|
|
13795
14276
|
"",
|
|
13796
14277
|
"## \u90E8\u7F72",
|
|
13797
14278
|
"",
|
|
@@ -13799,6 +14280,9 @@ function readme(options) {
|
|
|
13799
14280
|
"npm run deploy",
|
|
13800
14281
|
"```",
|
|
13801
14282
|
"",
|
|
14283
|
+
"`cj0 deploy` \u4F1A\u540C\u6B65\u6253\u5305\u7684 UI \u5230 `public/`\u3001\u4E0A\u4F20\u79C1\u6709\u811A\u672C\uFF0C\u7136\u540E\u6267\u884C",
|
|
14284
|
+
"`wrangler deploy`\u3002\u9996\u6B21\u90E8\u7F72\u524D\u5148\u8FD0\u884C `npx cj0 setup`\u3002",
|
|
14285
|
+
"",
|
|
13802
14286
|
"\u5927\u5385\u5728 `/`\uFF0C\u7BA1\u7406\u540E\u53F0\u5728 `/admin`\u3002",
|
|
13803
14287
|
""
|
|
13804
14288
|
].join("\n");
|
|
@@ -13813,6 +14297,7 @@ function buildScaffoldFiles(options) {
|
|
|
13813
14297
|
content: SCAFFOLD_CONFIG_CONTENT.replace("<project-name>", options.packageName)
|
|
13814
14298
|
},
|
|
13815
14299
|
{ path: "cajonzero/maps.json", content: SCAFFOLD_MAPS_CONTENT },
|
|
14300
|
+
{ path: SCAFFOLD_PUBLIC_KEEP_PATH, content: "" },
|
|
13816
14301
|
{ path: ".gitignore", content: gitignore() },
|
|
13817
14302
|
{ path: "README.md", content: readme(options) }
|
|
13818
14303
|
];
|
|
@@ -14254,7 +14739,8 @@ function applySetup(options) {
|
|
|
14254
14739
|
return { configPath, devVarsPath, vars, secrets, ...kvId !== void 0 ? { kvId } : {} };
|
|
14255
14740
|
}
|
|
14256
14741
|
var ASSETS_STAMP_FILE = ".cajonzero-assets.json";
|
|
14257
|
-
var
|
|
14742
|
+
var ASSETS_MAPS_DIR = "maps";
|
|
14743
|
+
var ASSETS_KEEP_FILE = ".gitkeep";
|
|
14258
14744
|
var DEFAULT_CONFIG = "wrangler.jsonc";
|
|
14259
14745
|
function resolvePackageRoot() {
|
|
14260
14746
|
try {
|
|
@@ -14334,7 +14820,7 @@ function assertSafeTarget(targetDir, sourceDir, configDir) {
|
|
|
14334
14820
|
throw new Error(`assets \u76EE\u5F55\u4E0D\u80FD\u5305\u542B\u9879\u76EE\u914D\u7F6E/cajonzero \u8D44\u6E90\u76EE\u5F55\uFF1A${targetDir}`);
|
|
14335
14821
|
}
|
|
14336
14822
|
}
|
|
14337
|
-
async function
|
|
14823
|
+
async function syncPublicAssets(options = {}) {
|
|
14338
14824
|
const cwd = options.cwd ?? process.cwd();
|
|
14339
14825
|
const configPath = path4.resolve(cwd, options.configPath ?? DEFAULT_CONFIG);
|
|
14340
14826
|
const configDir = path4.dirname(configPath);
|
|
@@ -14365,17 +14851,25 @@ async function prepareWorkerAssets(options = {}) {
|
|
|
14365
14851
|
bytes: source.bytes
|
|
14366
14852
|
};
|
|
14367
14853
|
}
|
|
14368
|
-
const
|
|
14369
|
-
const
|
|
14370
|
-
|
|
14371
|
-
|
|
14372
|
-
|
|
14373
|
-
|
|
14374
|
-
|
|
14375
|
-
|
|
14376
|
-
|
|
14377
|
-
|
|
14378
|
-
|
|
14854
|
+
const mapsDir = path4.join(targetDir, ASSETS_MAPS_DIR);
|
|
14855
|
+
const mapsBackup = path4.join(configDir, `.cajonzero-maps-backup-${process.pid}`);
|
|
14856
|
+
const keepFile = path4.join(targetDir, ASSETS_KEEP_FILE);
|
|
14857
|
+
const keepBackup = path4.join(configDir, `.cajonzero-keep-backup-${process.pid}`);
|
|
14858
|
+
if (!existsSync(mapsDir) && existsSync(mapsBackup)) {
|
|
14859
|
+
mkdirSync(path4.dirname(mapsDir), { recursive: true });
|
|
14860
|
+
renameSync(mapsBackup, mapsDir);
|
|
14861
|
+
}
|
|
14862
|
+
let hasMaps = false;
|
|
14863
|
+
if (existsSync(mapsDir)) {
|
|
14864
|
+
rmSync(mapsBackup, { recursive: true, force: true });
|
|
14865
|
+
renameSync(mapsDir, mapsBackup);
|
|
14866
|
+
hasMaps = true;
|
|
14867
|
+
}
|
|
14868
|
+
let hasKeep = false;
|
|
14869
|
+
if (existsSync(keepFile)) {
|
|
14870
|
+
rmSync(keepBackup, { force: true });
|
|
14871
|
+
renameSync(keepFile, keepBackup);
|
|
14872
|
+
hasKeep = true;
|
|
14379
14873
|
}
|
|
14380
14874
|
try {
|
|
14381
14875
|
rmSync(targetDir, { recursive: true, force: true });
|
|
@@ -14386,10 +14880,15 @@ async function prepareWorkerAssets(options = {}) {
|
|
|
14386
14880
|
filter: (from) => path4.basename(from) !== ASSETS_STAMP_FILE
|
|
14387
14881
|
});
|
|
14388
14882
|
} finally {
|
|
14389
|
-
if (
|
|
14883
|
+
if (hasMaps && existsSync(mapsBackup)) {
|
|
14884
|
+
mkdirSync(targetDir, { recursive: true });
|
|
14885
|
+
rmSync(mapsDir, { recursive: true, force: true });
|
|
14886
|
+
renameSync(mapsBackup, mapsDir);
|
|
14887
|
+
}
|
|
14888
|
+
if (hasKeep && existsSync(keepBackup)) {
|
|
14390
14889
|
mkdirSync(targetDir, { recursive: true });
|
|
14391
|
-
rmSync(
|
|
14392
|
-
renameSync(
|
|
14890
|
+
rmSync(keepFile, { force: true });
|
|
14891
|
+
renameSync(keepBackup, keepFile);
|
|
14393
14892
|
}
|
|
14394
14893
|
}
|
|
14395
14894
|
const next = {
|
|
@@ -14416,41 +14915,37 @@ Usage:
|
|
|
14416
14915
|
cj0 <command> [options]
|
|
14417
14916
|
|
|
14418
14917
|
Commands:
|
|
14419
|
-
create <folder>
|
|
14420
|
-
setup [--config <file>]
|
|
14421
|
-
|
|
14422
|
-
|
|
14423
|
-
|
|
14424
|
-
|
|
14425
|
-
|
|
14426
|
-
|
|
14427
|
-
--
|
|
14428
|
-
--assets <dir> Override assets.directory (relative to the config file)
|
|
14429
|
-
--force Re-copy even when the fingerprint already matches
|
|
14430
|
-
-h, --help Show this help
|
|
14918
|
+
create <folder> Scaffold a deployable project
|
|
14919
|
+
setup [--config <file>] Configure ENV values + KV namespace
|
|
14920
|
+
add <file.boxplay> [--slug <slug>] Import a map (public/maps + seed)
|
|
14921
|
+
update <slug> <file.boxplay> Replace an existing map
|
|
14922
|
+
list [--json] Show the map catalog
|
|
14923
|
+
remove <slug> Delete a map from the catalog
|
|
14924
|
+
sync [--config <file>] Copy the packaged UI into public/
|
|
14925
|
+
deploy [--config <file>] Sync UI, upload scripts, wrangler deploy
|
|
14926
|
+
serve [--port <port>] [--host <host>] Run the cajonzero server locally (workerd)
|
|
14431
14927
|
|
|
14432
|
-
|
|
14433
|
-
--
|
|
14434
|
-
--
|
|
14435
|
-
--
|
|
14436
|
-
--
|
|
14437
|
-
--no-gzip
|
|
14438
|
-
-
|
|
14928
|
+
Map options (add/update/list/remove):
|
|
14929
|
+
--maps <file> Catalog path (default: cajonzero/maps.json)
|
|
14930
|
+
--public <dir> Static-asset dir (default: public)
|
|
14931
|
+
--scripts <dir> Private scripts dir (default: cajonzero/private)
|
|
14932
|
+
--slug <slug> Override the slug (add only)
|
|
14933
|
+
--no-gzip Write plain JSON instead of gzip packs
|
|
14934
|
+
--reset-root update: reset a custom root back to /maps/<slug>/
|
|
14935
|
+
--json Machine-readable summary (add/update/list/remove)
|
|
14936
|
+
-h, --help Show this help
|
|
14439
14937
|
|
|
14440
|
-
|
|
14441
|
-
--
|
|
14442
|
-
--
|
|
14443
|
-
--no-
|
|
14444
|
-
-h, --help
|
|
14938
|
+
Sync/deploy options:
|
|
14939
|
+
--config <file> Wrangler config (default: wrangler.jsonc)
|
|
14940
|
+
--no-ui deploy: do not copy the packaged UI
|
|
14941
|
+
--no-scripts deploy: do not upload private map scripts
|
|
14942
|
+
-h, --help Show this help
|
|
14445
14943
|
|
|
14446
14944
|
Serve options:
|
|
14447
|
-
--port <port>
|
|
14448
|
-
--host <host>
|
|
14449
|
-
--config <file>
|
|
14450
|
-
-h, --help
|
|
14451
|
-
|
|
14452
|
-
Maps: unpack the .boxplay, upload the directory to OSS/CDN, and list its root
|
|
14453
|
-
in cajonzero/maps.json. The CLI does not import map archives.
|
|
14945
|
+
--port <port> Listener port (default: 8787)
|
|
14946
|
+
--host <host> Listener host (default: 127.0.0.1)
|
|
14947
|
+
--config <file> Wrangler config (default: wrangler.jsonc)
|
|
14948
|
+
-h, --help Show this help
|
|
14454
14949
|
`;
|
|
14455
14950
|
var DEFAULT_SERVE_PORT = 8787;
|
|
14456
14951
|
var DEFAULT_SERVE_HOST = "127.0.0.1";
|
|
@@ -14466,33 +14961,389 @@ function localDevVars() {
|
|
|
14466
14961
|
}
|
|
14467
14962
|
return Object.keys(vars).length > 0 ? vars : void 0;
|
|
14468
14963
|
}
|
|
14469
|
-
function printUsage() {
|
|
14470
|
-
process.stdout.write(USAGE);
|
|
14964
|
+
function printUsage() {
|
|
14965
|
+
process.stdout.write(USAGE);
|
|
14966
|
+
}
|
|
14967
|
+
function fail3(message) {
|
|
14968
|
+
process.stderr.write(`cajonzero: ${message}
|
|
14969
|
+
`);
|
|
14970
|
+
process.exitCode = 1;
|
|
14971
|
+
}
|
|
14972
|
+
function errorLabel(error) {
|
|
14973
|
+
if (error instanceof ScaffoldError) {
|
|
14974
|
+
return `${error.code}: ${error.message}`;
|
|
14975
|
+
}
|
|
14976
|
+
return error instanceof Error ? error.message : String(error);
|
|
14977
|
+
}
|
|
14978
|
+
function readFlagValue(args, index, flag) {
|
|
14979
|
+
const inline = args[index];
|
|
14980
|
+
if (inline !== void 0 && inline.startsWith(`${flag}=`)) {
|
|
14981
|
+
return inline.slice(flag.length + 1);
|
|
14982
|
+
}
|
|
14983
|
+
const value = args[index + 1];
|
|
14984
|
+
if (value === void 0 || value.startsWith("-")) {
|
|
14985
|
+
throw new Error(`${flag} requires a value`);
|
|
14986
|
+
}
|
|
14987
|
+
return value;
|
|
14988
|
+
}
|
|
14989
|
+
function formatBytes(bytes) {
|
|
14990
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
14991
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
14992
|
+
return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
|
|
14993
|
+
}
|
|
14994
|
+
async function runCreate(args) {
|
|
14995
|
+
const [folder] = args;
|
|
14996
|
+
if (folder === void 0) {
|
|
14997
|
+
fail3("create requires: cj0 create <folder>");
|
|
14998
|
+
return;
|
|
14999
|
+
}
|
|
15000
|
+
const result = createProject(folder);
|
|
15001
|
+
process.stdout.write(
|
|
15002
|
+
`created project in ${result.target} (${result.files.length} files)
|
|
15003
|
+
${result.files.join(", ")}
|
|
15004
|
+
`
|
|
15005
|
+
);
|
|
15006
|
+
try {
|
|
15007
|
+
const sync = await syncPublicAssets({ cwd: result.target });
|
|
15008
|
+
process.stdout.write(
|
|
15009
|
+
` UI: ${sync.files} assets (${formatBytes(sync.bytes)}) -> ${path4.relative(
|
|
15010
|
+
result.target,
|
|
15011
|
+
sync.targetDir
|
|
15012
|
+
) || "."}
|
|
15013
|
+
`
|
|
15014
|
+
);
|
|
15015
|
+
} catch (error) {
|
|
15016
|
+
process.stdout.write(
|
|
15017
|
+
` UI: \u672A\u540C\u6B65\uFF08${error instanceof Error ? error.message : String(error)}\uFF09\uFF1B\u7A0D\u540E\u8FD0\u884C cj0 sync
|
|
15018
|
+
`
|
|
15019
|
+
);
|
|
15020
|
+
}
|
|
15021
|
+
process.stdout.write(
|
|
15022
|
+
` next: cd ${folder} && npm install && npx cj0 setup && npm run dev
|
|
15023
|
+
`
|
|
15024
|
+
);
|
|
15025
|
+
}
|
|
15026
|
+
function parseSyncFlags(args, allowDeployFlags) {
|
|
15027
|
+
let config = DEFAULT_CONFIG2;
|
|
15028
|
+
let noUi = false;
|
|
15029
|
+
let noScripts = false;
|
|
15030
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
15031
|
+
const arg = args[i];
|
|
15032
|
+
if (arg === void 0) continue;
|
|
15033
|
+
if (arg === "--config" || arg.startsWith("--config=")) {
|
|
15034
|
+
config = readFlagValue(args, i, "--config");
|
|
15035
|
+
if (!arg.includes("=")) i += 1;
|
|
15036
|
+
} else if (allowDeployFlags && arg === "--no-ui") {
|
|
15037
|
+
noUi = true;
|
|
15038
|
+
} else if (allowDeployFlags && arg === "--no-scripts") {
|
|
15039
|
+
noScripts = true;
|
|
15040
|
+
} else {
|
|
15041
|
+
throw new Error(`unexpected ${allowDeployFlags ? "deploy" : "sync"} option "${arg}"`);
|
|
15042
|
+
}
|
|
15043
|
+
}
|
|
15044
|
+
return { config, noUi, noScripts };
|
|
15045
|
+
}
|
|
15046
|
+
async function runSync(args) {
|
|
15047
|
+
const flags = parseSyncFlags(args, false);
|
|
15048
|
+
const result = await syncPublicAssets({ configPath: flags.config });
|
|
15049
|
+
const target = path4.relative(process.cwd(), result.targetDir) || ".";
|
|
15050
|
+
process.stdout.write(
|
|
15051
|
+
`${result.copied ? "synced" : "up to date"}: ${result.files} assets, ${formatBytes(result.bytes)} -> ${target}
|
|
15052
|
+
`
|
|
15053
|
+
);
|
|
15054
|
+
}
|
|
15055
|
+
function parseMapFlags(args, command) {
|
|
15056
|
+
let maps = DEFAULT_MAPS_FILE;
|
|
15057
|
+
let publicDir = DEFAULT_PUBLIC_DIR;
|
|
15058
|
+
let scriptsDir = DEFAULT_SCRIPTS_DIR;
|
|
15059
|
+
let slug;
|
|
15060
|
+
let gzip = true;
|
|
15061
|
+
let resetRoot = false;
|
|
15062
|
+
let json = false;
|
|
15063
|
+
const positional = [];
|
|
15064
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
15065
|
+
const arg = args[i];
|
|
15066
|
+
if (arg === void 0) continue;
|
|
15067
|
+
if (arg === "--maps" || arg.startsWith("--maps=")) {
|
|
15068
|
+
maps = readFlagValue(args, i, "--maps");
|
|
15069
|
+
if (!arg.includes("=")) i += 1;
|
|
15070
|
+
} else if (arg === "--public" || arg.startsWith("--public=")) {
|
|
15071
|
+
publicDir = readFlagValue(args, i, "--public");
|
|
15072
|
+
if (!arg.includes("=")) i += 1;
|
|
15073
|
+
} else if (arg === "--scripts" || arg.startsWith("--scripts=")) {
|
|
15074
|
+
scriptsDir = readFlagValue(args, i, "--scripts");
|
|
15075
|
+
if (!arg.includes("=")) i += 1;
|
|
15076
|
+
} else if (arg === "--slug" || arg.startsWith("--slug=")) {
|
|
15077
|
+
slug = readFlagValue(args, i, "--slug");
|
|
15078
|
+
if (!arg.includes("=")) i += 1;
|
|
15079
|
+
} else if (arg === "--no-gzip") {
|
|
15080
|
+
gzip = false;
|
|
15081
|
+
} else if (arg === "--reset-root") {
|
|
15082
|
+
resetRoot = true;
|
|
15083
|
+
} else if (arg === "--json") {
|
|
15084
|
+
json = true;
|
|
15085
|
+
} else if (arg.startsWith("-")) {
|
|
15086
|
+
throw new Error(`unexpected ${command} option "${arg}"`);
|
|
15087
|
+
} else {
|
|
15088
|
+
positional.push(arg);
|
|
15089
|
+
}
|
|
15090
|
+
}
|
|
15091
|
+
return {
|
|
15092
|
+
maps,
|
|
15093
|
+
publicDir,
|
|
15094
|
+
scriptsDir,
|
|
15095
|
+
...slug !== void 0 ? { slug } : {},
|
|
15096
|
+
gzip,
|
|
15097
|
+
resetRoot,
|
|
15098
|
+
json,
|
|
15099
|
+
positional
|
|
15100
|
+
};
|
|
15101
|
+
}
|
|
15102
|
+
function mapOptions(flags) {
|
|
15103
|
+
return {
|
|
15104
|
+
maps: flags.maps,
|
|
15105
|
+
publicDir: flags.publicDir,
|
|
15106
|
+
scriptsDir: flags.scriptsDir,
|
|
15107
|
+
...flags.slug !== void 0 ? { slug: flags.slug } : {},
|
|
15108
|
+
gzip: flags.gzip,
|
|
15109
|
+
resetRoot: flags.resetRoot
|
|
15110
|
+
};
|
|
15111
|
+
}
|
|
15112
|
+
function printImportResult(result) {
|
|
15113
|
+
process.stdout.write(
|
|
15114
|
+
`${result.action === "add" ? "added" : "updated"} "${result.slug}" (${result.worldId}) -> ${result.root}
|
|
15115
|
+
map: ${result.files} files, ${formatBytes(result.bytes)} (seed ${formatBytes(result.seedPackBytes)})
|
|
15116
|
+
seed: ${path4.relative(process.cwd(), result.seedPack)}
|
|
15117
|
+
`
|
|
15118
|
+
);
|
|
15119
|
+
if (result.scriptsPack !== void 0) {
|
|
15120
|
+
process.stdout.write(
|
|
15121
|
+
` scripts: ${result.scriptModules} modules -> ${path4.relative(
|
|
15122
|
+
process.cwd(),
|
|
15123
|
+
result.scriptsPack
|
|
15124
|
+
)}
|
|
15125
|
+
`
|
|
15126
|
+
);
|
|
15127
|
+
}
|
|
15128
|
+
for (const warning of result.warnings) process.stdout.write(` warning: ${warning}
|
|
15129
|
+
`);
|
|
15130
|
+
}
|
|
15131
|
+
async function runAdd(args) {
|
|
15132
|
+
const flags = parseMapFlags(args, "add");
|
|
15133
|
+
const archive = flags.positional[0];
|
|
15134
|
+
if (archive === void 0) {
|
|
15135
|
+
throw new Error("add requires: cj0 add <file.boxplay> [--slug <slug>]");
|
|
15136
|
+
}
|
|
15137
|
+
if (flags.positional.length > 1) {
|
|
15138
|
+
throw new Error(`unexpected argument "${flags.positional[1]}"`);
|
|
15139
|
+
}
|
|
15140
|
+
const result = await addMap(archive, mapOptions(flags));
|
|
15141
|
+
if (flags.json) {
|
|
15142
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}
|
|
15143
|
+
`);
|
|
15144
|
+
return;
|
|
15145
|
+
}
|
|
15146
|
+
printImportResult(result);
|
|
15147
|
+
}
|
|
15148
|
+
async function runUpdate(args) {
|
|
15149
|
+
const flags = parseMapFlags(args, "update");
|
|
15150
|
+
const [slug, archive] = flags.positional;
|
|
15151
|
+
if (slug === void 0 || archive === void 0) {
|
|
15152
|
+
throw new Error("update requires: cj0 update <slug> <file.boxplay>");
|
|
15153
|
+
}
|
|
15154
|
+
if (flags.positional.length > 2) {
|
|
15155
|
+
throw new Error(`unexpected argument "${flags.positional[2]}"`);
|
|
15156
|
+
}
|
|
15157
|
+
const result = await updateMap(slug, archive, mapOptions(flags));
|
|
15158
|
+
if (flags.json) {
|
|
15159
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}
|
|
15160
|
+
`);
|
|
15161
|
+
return;
|
|
15162
|
+
}
|
|
15163
|
+
printImportResult(result);
|
|
15164
|
+
}
|
|
15165
|
+
function runList(args) {
|
|
15166
|
+
const flags = parseMapFlags(args, "list");
|
|
15167
|
+
if (flags.positional.length > 0) {
|
|
15168
|
+
throw new Error(`unexpected argument "${flags.positional[0]}"`);
|
|
15169
|
+
}
|
|
15170
|
+
const entries = listMaps({
|
|
15171
|
+
maps: flags.maps,
|
|
15172
|
+
publicDir: flags.publicDir,
|
|
15173
|
+
scriptsDir: flags.scriptsDir
|
|
15174
|
+
});
|
|
15175
|
+
if (flags.json) {
|
|
15176
|
+
process.stdout.write(`${JSON.stringify(entries, null, 2)}
|
|
15177
|
+
`);
|
|
15178
|
+
return;
|
|
15179
|
+
}
|
|
15180
|
+
if (entries.length === 0) {
|
|
15181
|
+
process.stdout.write("no maps; import one with: cj0 add <file.boxplay>\n");
|
|
15182
|
+
return;
|
|
15183
|
+
}
|
|
15184
|
+
for (const entry of entries) {
|
|
15185
|
+
const state = [
|
|
15186
|
+
entry.imported ? "imported" : "catalog-only",
|
|
15187
|
+
entry.seeded ? "seeded" : "no-seed",
|
|
15188
|
+
entry.hasScripts ? "scripts" : "no-scripts"
|
|
15189
|
+
].join(", ");
|
|
15190
|
+
process.stdout.write(
|
|
15191
|
+
`${entry.slug.padEnd(16)} ${entry.root}
|
|
15192
|
+
${entry.name ?? "(unnamed)"}${entry.version !== void 0 ? ` v${entry.version}` : ""} [${state}]
|
|
15193
|
+
`
|
|
15194
|
+
);
|
|
15195
|
+
}
|
|
14471
15196
|
}
|
|
14472
|
-
function
|
|
14473
|
-
|
|
15197
|
+
function runRemove(args) {
|
|
15198
|
+
const flags = parseMapFlags(args, "remove");
|
|
15199
|
+
const slug = flags.positional[0];
|
|
15200
|
+
if (slug === void 0) {
|
|
15201
|
+
throw new Error("remove requires: cj0 remove <slug>");
|
|
15202
|
+
}
|
|
15203
|
+
if (flags.positional.length > 1) {
|
|
15204
|
+
throw new Error(`unexpected argument "${flags.positional[1]}"`);
|
|
15205
|
+
}
|
|
15206
|
+
const result = removeMap(slug, {
|
|
15207
|
+
maps: flags.maps,
|
|
15208
|
+
publicDir: flags.publicDir,
|
|
15209
|
+
scriptsDir: flags.scriptsDir
|
|
15210
|
+
});
|
|
15211
|
+
if (flags.json) {
|
|
15212
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}
|
|
14474
15213
|
`);
|
|
14475
|
-
|
|
15214
|
+
return;
|
|
15215
|
+
}
|
|
15216
|
+
process.stdout.write(`removed "${result.slug}"
|
|
15217
|
+
`);
|
|
15218
|
+
if (result.removedDir !== void 0) {
|
|
15219
|
+
process.stdout.write(` dir: ${path4.relative(process.cwd(), result.removedDir)}
|
|
15220
|
+
`);
|
|
15221
|
+
}
|
|
15222
|
+
for (const file of result.removedScripts) {
|
|
15223
|
+
process.stdout.write(` scripts: ${path4.relative(process.cwd(), file)}
|
|
15224
|
+
`);
|
|
15225
|
+
}
|
|
14476
15226
|
}
|
|
14477
|
-
function
|
|
14478
|
-
|
|
14479
|
-
|
|
15227
|
+
function resolveWranglerBin() {
|
|
15228
|
+
try {
|
|
15229
|
+
const require2 = createRequire(import.meta.url);
|
|
15230
|
+
const packagePath = require2.resolve("wrangler/package.json");
|
|
15231
|
+
const pkg = JSON.parse(readFileSync(packagePath, "utf8"));
|
|
15232
|
+
const bin = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.["wrangler"];
|
|
15233
|
+
return bin !== void 0 ? path4.resolve(path4.dirname(packagePath), bin) : void 0;
|
|
15234
|
+
} catch {
|
|
15235
|
+
return void 0;
|
|
14480
15236
|
}
|
|
14481
|
-
return error instanceof Error ? error.message : String(error);
|
|
14482
15237
|
}
|
|
14483
|
-
function
|
|
14484
|
-
|
|
14485
|
-
|
|
14486
|
-
|
|
14487
|
-
|
|
15238
|
+
function scriptsKvBinding(configPath) {
|
|
15239
|
+
if (!existsSync(configPath)) return void 0;
|
|
15240
|
+
const parsed = parseJsoncObject(readFileSync(configPath, "utf8"));
|
|
15241
|
+
const namespaces = Array.isArray(parsed["kv_namespaces"]) ? parsed["kv_namespaces"] : [];
|
|
15242
|
+
const bindings = namespaces.map(
|
|
15243
|
+
(entry) => typeof entry === "object" && entry !== null ? entry["binding"] : void 0
|
|
15244
|
+
).filter((binding) => typeof binding === "string");
|
|
15245
|
+
return bindings.includes("CAJONZERO_SCRIPTS") ? "CAJONZERO_SCRIPTS" : bindings.includes("CAJONZERO_KV") ? "CAJONZERO_KV" : void 0;
|
|
15246
|
+
}
|
|
15247
|
+
function uploadScriptPacks(cwd, configPath, locations, binding, target) {
|
|
15248
|
+
const wrangler = resolveWranglerBin();
|
|
15249
|
+
if (wrangler === void 0) {
|
|
15250
|
+
throw new Error("wrangler is not installed; cannot upload map scripts");
|
|
15251
|
+
}
|
|
15252
|
+
if (locations.length === 0) return 0;
|
|
15253
|
+
const temp = mkdtempSync(path4.join(tmpdir(), "cajonzero-scripts-"));
|
|
15254
|
+
let uploaded = 0;
|
|
15255
|
+
try {
|
|
15256
|
+
for (const { slug, file: source } of locations) {
|
|
15257
|
+
const text = readScriptsPackText(source);
|
|
15258
|
+
if (text === void 0) continue;
|
|
15259
|
+
const parsed = JSON.parse(text);
|
|
15260
|
+
const revision = typeof parsed.revision === "string" && parsed.revision.length > 0 ? parsed.revision : void 0;
|
|
15261
|
+
const file = path4.join(temp, `${slug}.json`);
|
|
15262
|
+
writeFileSync(file, text, "utf8");
|
|
15263
|
+
const keys = [
|
|
15264
|
+
...revision !== void 0 ? [`scripts:${slug}:${revision}`] : [],
|
|
15265
|
+
`scripts:${slug}`
|
|
15266
|
+
];
|
|
15267
|
+
for (const key of keys) {
|
|
15268
|
+
const args = [
|
|
15269
|
+
wrangler,
|
|
15270
|
+
"kv",
|
|
15271
|
+
"key",
|
|
15272
|
+
"put",
|
|
15273
|
+
key,
|
|
15274
|
+
"--binding",
|
|
15275
|
+
binding,
|
|
15276
|
+
"--path",
|
|
15277
|
+
file,
|
|
15278
|
+
"--config",
|
|
15279
|
+
configPath
|
|
15280
|
+
];
|
|
15281
|
+
if (target.remote) {
|
|
15282
|
+
args.push("--remote");
|
|
15283
|
+
} else {
|
|
15284
|
+
args.push("--local");
|
|
15285
|
+
if (target.persistTo !== void 0) args.push("--persist-to", target.persistTo);
|
|
15286
|
+
}
|
|
15287
|
+
const result = spawnSync(process.execPath, args, { cwd, stdio: "inherit" });
|
|
15288
|
+
if (result.error !== void 0 || result.status !== 0) {
|
|
15289
|
+
throw new Error(`failed to upload ${key}`);
|
|
15290
|
+
}
|
|
15291
|
+
uploaded += 1;
|
|
15292
|
+
}
|
|
15293
|
+
}
|
|
15294
|
+
} finally {
|
|
15295
|
+
rmSync(temp, { recursive: true, force: true });
|
|
14488
15296
|
}
|
|
14489
|
-
|
|
14490
|
-
|
|
14491
|
-
|
|
14492
|
-
|
|
14493
|
-
|
|
15297
|
+
return uploaded;
|
|
15298
|
+
}
|
|
15299
|
+
async function runDeploy(args) {
|
|
15300
|
+
const flags = parseSyncFlags(args, true);
|
|
15301
|
+
const cwd = process.cwd();
|
|
15302
|
+
const configPath = path4.resolve(cwd, flags.config);
|
|
15303
|
+
if (!flags.noUi) {
|
|
15304
|
+
try {
|
|
15305
|
+
const sync = await syncPublicAssets({ cwd, configPath: flags.config });
|
|
15306
|
+
process.stdout.write(
|
|
15307
|
+
`UI ${sync.copied ? "synced" : "up to date"}: ${sync.files} assets
|
|
15308
|
+
`
|
|
15309
|
+
);
|
|
15310
|
+
} catch (error) {
|
|
15311
|
+
throw new Error(
|
|
15312
|
+
`cannot sync the packaged UI: ${error instanceof Error ? error.message : String(error)}`
|
|
15313
|
+
);
|
|
15314
|
+
}
|
|
15315
|
+
}
|
|
15316
|
+
if (!flags.noScripts) {
|
|
15317
|
+
const binding = scriptsKvBinding(configPath);
|
|
15318
|
+
const locations = listScriptPackLocations({ cwd, scriptsDir: DEFAULT_SCRIPTS_DIR });
|
|
15319
|
+
if (binding !== void 0) {
|
|
15320
|
+
const uploaded = uploadScriptPacks(cwd, configPath, locations, binding, {
|
|
15321
|
+
remote: true
|
|
15322
|
+
});
|
|
15323
|
+
if (uploaded > 0) {
|
|
15324
|
+
process.stdout.write(`map scripts: ${uploaded} KV key(s) -> ${binding}
|
|
15325
|
+
`);
|
|
15326
|
+
}
|
|
15327
|
+
} else if (locations.length > 0) {
|
|
15328
|
+
process.stdout.write(
|
|
15329
|
+
`map scripts: no CAJONZERO_SCRIPTS/CAJONZERO_KV binding in ${flags.config}; skipping upload
|
|
14494
15330
|
`
|
|
15331
|
+
);
|
|
15332
|
+
}
|
|
15333
|
+
}
|
|
15334
|
+
const wrangler = resolveWranglerBin();
|
|
15335
|
+
if (wrangler === void 0) {
|
|
15336
|
+
throw new Error("wrangler is not installed; run npm install first");
|
|
15337
|
+
}
|
|
15338
|
+
const result = spawnSync(
|
|
15339
|
+
process.execPath,
|
|
15340
|
+
[wrangler, "deploy", "--config", flags.config],
|
|
15341
|
+
{ cwd, stdio: "inherit" }
|
|
14495
15342
|
);
|
|
15343
|
+
if (result.error !== void 0) throw result.error;
|
|
15344
|
+
if (result.status !== 0) {
|
|
15345
|
+
throw new Error(`wrangler deploy exited with status ${result.status ?? "unknown"}`);
|
|
15346
|
+
}
|
|
14496
15347
|
}
|
|
14497
15348
|
function parseSetupFlags(args) {
|
|
14498
15349
|
let config = DEFAULT_CONFIG2;
|
|
@@ -14508,17 +15359,6 @@ function parseSetupFlags(args) {
|
|
|
14508
15359
|
}
|
|
14509
15360
|
return { config };
|
|
14510
15361
|
}
|
|
14511
|
-
function resolveWranglerBin() {
|
|
14512
|
-
try {
|
|
14513
|
-
const require2 = createRequire(import.meta.url);
|
|
14514
|
-
const packagePath = require2.resolve("wrangler/package.json");
|
|
14515
|
-
const pkg = JSON.parse(readFileSync(packagePath, "utf8"));
|
|
14516
|
-
const bin = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.["wrangler"];
|
|
14517
|
-
return bin !== void 0 ? path4.resolve(path4.dirname(packagePath), bin) : void 0;
|
|
14518
|
-
} catch {
|
|
14519
|
-
return void 0;
|
|
14520
|
-
}
|
|
14521
|
-
}
|
|
14522
15362
|
function createKvNamespace(cwd, configPath) {
|
|
14523
15363
|
const bin = resolveWranglerBin();
|
|
14524
15364
|
if (bin === void 0) return void 0;
|
|
@@ -14636,17 +15476,6 @@ async function runSetup(args) {
|
|
|
14636
15476
|
}
|
|
14637
15477
|
}
|
|
14638
15478
|
}
|
|
14639
|
-
function readFlagValue(args, index, flag) {
|
|
14640
|
-
const inline = args[index];
|
|
14641
|
-
if (inline !== void 0 && inline.startsWith(`${flag}=`)) {
|
|
14642
|
-
return inline.slice(flag.length + 1);
|
|
14643
|
-
}
|
|
14644
|
-
const value = args[index + 1];
|
|
14645
|
-
if (value === void 0 || value.startsWith("-")) {
|
|
14646
|
-
throw new Error(`${flag} requires a value`);
|
|
14647
|
-
}
|
|
14648
|
-
return value;
|
|
14649
|
-
}
|
|
14650
15479
|
function parseServeFlags(args) {
|
|
14651
15480
|
let port = DEFAULT_SERVE_PORT;
|
|
14652
15481
|
let host = DEFAULT_SERVE_HOST;
|
|
@@ -14674,286 +15503,6 @@ function parseServeFlags(args) {
|
|
|
14674
15503
|
}
|
|
14675
15504
|
return { port, host, config };
|
|
14676
15505
|
}
|
|
14677
|
-
function parseMapsPackFlags(args) {
|
|
14678
|
-
let slug;
|
|
14679
|
-
let maps = "cajonzero/maps.json";
|
|
14680
|
-
let out;
|
|
14681
|
-
let gzip = true;
|
|
14682
|
-
for (let i = 0; i < args.length; i += 1) {
|
|
14683
|
-
const arg = args[i];
|
|
14684
|
-
if (arg === void 0) continue;
|
|
14685
|
-
if (arg === "--maps" || arg.startsWith("--maps=")) {
|
|
14686
|
-
maps = readFlagValue(args, i, "--maps");
|
|
14687
|
-
if (!arg.includes("=")) i += 1;
|
|
14688
|
-
} else if (arg === "--out" || arg.startsWith("--out=")) {
|
|
14689
|
-
out = readFlagValue(args, i, "--out");
|
|
14690
|
-
if (!arg.includes("=")) i += 1;
|
|
14691
|
-
} else if (arg === "--no-gzip") {
|
|
14692
|
-
gzip = false;
|
|
14693
|
-
} else if (arg.startsWith("-")) {
|
|
14694
|
-
throw new Error(`unexpected maps pack option "${arg}"`);
|
|
14695
|
-
} else if (slug === void 0) {
|
|
14696
|
-
slug = arg;
|
|
14697
|
-
} else {
|
|
14698
|
-
throw new Error(`unexpected argument "${arg}"`);
|
|
14699
|
-
}
|
|
14700
|
-
}
|
|
14701
|
-
if (slug === void 0) throw new Error("maps pack requires a map slug");
|
|
14702
|
-
return { slug, maps, ...out !== void 0 ? { out } : {}, gzip };
|
|
14703
|
-
}
|
|
14704
|
-
function readMapCatalogFile(mapsPath, label) {
|
|
14705
|
-
if (!existsSync(mapsPath)) {
|
|
14706
|
-
throw new Error(`\u627E\u4E0D\u5230\u5730\u56FE\u76EE\u5F55 ${label}\uFF0C\u8BF7\u5728\u9879\u76EE\u76EE\u5F55\u4E2D\u8FD0\u884C`);
|
|
14707
|
-
}
|
|
14708
|
-
let raw;
|
|
14709
|
-
try {
|
|
14710
|
-
raw = JSON.parse(readFileSync(mapsPath, "utf8").replace(/^\uFEFF/, ""));
|
|
14711
|
-
} catch (error) {
|
|
14712
|
-
throw new Error(
|
|
14713
|
-
`${label} \u4E0D\u662F\u5408\u6CD5 JSON\uFF1A${error instanceof Error ? error.message : String(error)}`
|
|
14714
|
-
);
|
|
14715
|
-
}
|
|
14716
|
-
return parseMapCatalog(raw);
|
|
14717
|
-
}
|
|
14718
|
-
async function runMapsPack(args) {
|
|
14719
|
-
const flags = parseMapsPackFlags(args);
|
|
14720
|
-
const cwd = process.cwd();
|
|
14721
|
-
const catalog = readMapCatalogFile(path4.resolve(cwd, flags.maps), flags.maps);
|
|
14722
|
-
const entry = findMap(catalog, flags.slug);
|
|
14723
|
-
if (entry === void 0) {
|
|
14724
|
-
throw new Error(`${flags.maps} \u4E2D\u6CA1\u6709 slug "${flags.slug}"`);
|
|
14725
|
-
}
|
|
14726
|
-
process.stdout.write(`resolving ${entry.slug} from ${entry.root}
|
|
14727
|
-
`);
|
|
14728
|
-
const { seed, blockInfoBytes } = await loadWorldSeedGraphFromHttp(entry);
|
|
14729
|
-
for (const warning of seed.warnings) process.stdout.write(` warning: ${warning}
|
|
14730
|
-
`);
|
|
14731
|
-
const pack = encodeSeedPack(seed, blockInfoBytes);
|
|
14732
|
-
const data = flags.gzip ? gzipSync(pack, { level: 9 }) : pack;
|
|
14733
|
-
const fileName = `seed.json${flags.gzip ? ".gz" : ""}`;
|
|
14734
|
-
const outPath = path4.resolve(cwd, flags.out ?? `${entry.slug}.${fileName}`);
|
|
14735
|
-
writeFileSync(outPath, data);
|
|
14736
|
-
const chunks = seed.voxels?.chunkCount ?? 0;
|
|
14737
|
-
process.stdout.write(
|
|
14738
|
-
`packed ${seed.bodies.length} bodies, ${chunks} voxel chunks, ${seed.render?.meshes.length ?? 0} meshes
|
|
14739
|
-
wrote ${path4.relative(cwd, outPath)} (${formatBytes(data.length)}${flags.gzip ? ", gzip" : ""})
|
|
14740
|
-
upload it to: ${entry.root}${fileName}
|
|
14741
|
-
room startup becomes 1 request instead of one per blob.
|
|
14742
|
-
`
|
|
14743
|
-
);
|
|
14744
|
-
}
|
|
14745
|
-
async function runMaps(args) {
|
|
14746
|
-
const [subcommand, ...rest] = args;
|
|
14747
|
-
if (subcommand === void 0 || subcommand === "--help" || subcommand === "-h" || subcommand === "help") {
|
|
14748
|
-
printUsage();
|
|
14749
|
-
return;
|
|
14750
|
-
}
|
|
14751
|
-
if (subcommand === "pack") {
|
|
14752
|
-
if (rest.includes("-h") || rest.includes("--help")) {
|
|
14753
|
-
printUsage();
|
|
14754
|
-
return;
|
|
14755
|
-
}
|
|
14756
|
-
await runMapsPack(rest);
|
|
14757
|
-
return;
|
|
14758
|
-
}
|
|
14759
|
-
throw new Error(`unknown maps command "${subcommand}"`);
|
|
14760
|
-
}
|
|
14761
|
-
function parseBuildSeedFlags(args) {
|
|
14762
|
-
const slugs = [];
|
|
14763
|
-
let config = DEFAULT_CONFIG2;
|
|
14764
|
-
let maps = "cajonzero/maps.json";
|
|
14765
|
-
let assets;
|
|
14766
|
-
let force = false;
|
|
14767
|
-
let gzip = true;
|
|
14768
|
-
for (let i = 0; i < args.length; i += 1) {
|
|
14769
|
-
const arg = args[i];
|
|
14770
|
-
if (arg === void 0) continue;
|
|
14771
|
-
if (arg === "--config" || arg.startsWith("--config=")) {
|
|
14772
|
-
config = readFlagValue(args, i, "--config");
|
|
14773
|
-
if (!arg.includes("=")) i += 1;
|
|
14774
|
-
} else if (arg === "--maps" || arg.startsWith("--maps=")) {
|
|
14775
|
-
maps = readFlagValue(args, i, "--maps");
|
|
14776
|
-
if (!arg.includes("=")) i += 1;
|
|
14777
|
-
} else if (arg === "--assets" || arg.startsWith("--assets=")) {
|
|
14778
|
-
assets = readFlagValue(args, i, "--assets");
|
|
14779
|
-
if (!arg.includes("=")) i += 1;
|
|
14780
|
-
} else if (arg === "--force") {
|
|
14781
|
-
force = true;
|
|
14782
|
-
} else if (arg === "--no-gzip") {
|
|
14783
|
-
gzip = false;
|
|
14784
|
-
} else if (arg.startsWith("-")) {
|
|
14785
|
-
throw new Error(`unexpected worker build-seed option "${arg}"`);
|
|
14786
|
-
} else {
|
|
14787
|
-
slugs.push(arg);
|
|
14788
|
-
}
|
|
14789
|
-
}
|
|
14790
|
-
return { slugs, config, maps, ...assets !== void 0 ? { assets } : {}, force, gzip };
|
|
14791
|
-
}
|
|
14792
|
-
function readSeedMeta(metaPath) {
|
|
14793
|
-
try {
|
|
14794
|
-
return JSON.parse(readFileSync(metaPath, "utf8"));
|
|
14795
|
-
} catch {
|
|
14796
|
-
return void 0;
|
|
14797
|
-
}
|
|
14798
|
-
}
|
|
14799
|
-
async function runWorkerBuildSeed(args) {
|
|
14800
|
-
const flags = parseBuildSeedFlags(args);
|
|
14801
|
-
const cwd = process.cwd();
|
|
14802
|
-
const configPath = path4.resolve(cwd, flags.config);
|
|
14803
|
-
const configDir = path4.dirname(configPath);
|
|
14804
|
-
const assetsRel = flags.assets ?? readWranglerAssetsDirectory(configPath);
|
|
14805
|
-
if (assetsRel === void 0) {
|
|
14806
|
-
throw new Error(
|
|
14807
|
-
`${path4.basename(configPath)} \u672A\u914D\u7F6E assets.directory\uFF1B\u7528 --assets <dir> \u6307\u5B9A\u8F93\u51FA\u76EE\u5F55`
|
|
14808
|
-
);
|
|
14809
|
-
}
|
|
14810
|
-
const assetsDir = path4.resolve(configDir, assetsRel);
|
|
14811
|
-
const seedDir = path4.join(assetsDir, ASSETS_SEED_DIR);
|
|
14812
|
-
mkdirSync(seedDir, { recursive: true });
|
|
14813
|
-
const catalog = readMapCatalogFile(path4.resolve(cwd, flags.maps), flags.maps);
|
|
14814
|
-
const selected = flags.slugs.length > 0 ? flags.slugs.map((slug) => {
|
|
14815
|
-
const entry = findMap(catalog, slug);
|
|
14816
|
-
if (entry === void 0) throw new Error(`${flags.maps} \u4E2D\u6CA1\u6709 slug "${slug}"`);
|
|
14817
|
-
return entry;
|
|
14818
|
-
}) : [...catalog.maps];
|
|
14819
|
-
if (selected.length === 0) {
|
|
14820
|
-
process.stdout.write(`no maps in ${flags.maps}; nothing to build
|
|
14821
|
-
`);
|
|
14822
|
-
return;
|
|
14823
|
-
}
|
|
14824
|
-
let failures = 0;
|
|
14825
|
-
for (const entry of selected) {
|
|
14826
|
-
const suffix = flags.gzip ? ".json.gz" : ".json";
|
|
14827
|
-
const packPath = path4.join(seedDir, `${entry.slug}${suffix}`);
|
|
14828
|
-
const staleSuffix = flags.gzip ? ".json" : ".json.gz";
|
|
14829
|
-
const meta = {
|
|
14830
|
-
root: entry.root,
|
|
14831
|
-
...entry.worldId !== void 0 ? { worldId: entry.worldId } : {},
|
|
14832
|
-
...entry.version !== void 0 ? { version: entry.version } : {},
|
|
14833
|
-
...entry.etag !== void 0 ? { etag: entry.etag } : {},
|
|
14834
|
-
gzip: flags.gzip
|
|
14835
|
-
};
|
|
14836
|
-
if (!flags.force && existsSync(packPath)) {
|
|
14837
|
-
const previous = readSeedMeta(path4.join(seedDir, `${entry.slug}.meta.json`));
|
|
14838
|
-
if (previous !== void 0 && JSON.stringify(previous) === JSON.stringify(meta)) {
|
|
14839
|
-
process.stdout.write(`up to date: ${path4.relative(cwd, packPath)}
|
|
14840
|
-
`);
|
|
14841
|
-
continue;
|
|
14842
|
-
}
|
|
14843
|
-
}
|
|
14844
|
-
try {
|
|
14845
|
-
process.stdout.write(`resolving ${entry.slug} from ${entry.root}
|
|
14846
|
-
`);
|
|
14847
|
-
const { seed, blockInfoBytes } = await loadWorldSeedGraphFromHttp(entry);
|
|
14848
|
-
for (const warning of seed.warnings) process.stdout.write(` warning: ${warning}
|
|
14849
|
-
`);
|
|
14850
|
-
const pack = encodeSeedPack(seed, blockInfoBytes);
|
|
14851
|
-
const data = flags.gzip ? gzipSync(pack, { level: 9 }) : pack;
|
|
14852
|
-
writeFileSync(packPath, data);
|
|
14853
|
-
writeFileSync(
|
|
14854
|
-
path4.join(seedDir, `${entry.slug}.meta.json`),
|
|
14855
|
-
`${JSON.stringify(meta, null, 2)}
|
|
14856
|
-
`,
|
|
14857
|
-
"utf8"
|
|
14858
|
-
);
|
|
14859
|
-
rmSync(path4.join(seedDir, `${entry.slug}${staleSuffix}`), { force: true });
|
|
14860
|
-
process.stdout.write(
|
|
14861
|
-
`seeded ${entry.slug}: ${seed.bodies.length} bodies, ${seed.voxels?.chunkCount ?? 0} voxel chunks, ${seed.render?.meshes.length ?? 0} meshes -> ${path4.relative(cwd, packPath)} (${formatBytes(data.length)})
|
|
14862
|
-
`
|
|
14863
|
-
);
|
|
14864
|
-
} catch (error) {
|
|
14865
|
-
failures += 1;
|
|
14866
|
-
process.stderr.write(
|
|
14867
|
-
`cajonzero: build-seed failed for "${entry.slug}": ${errorLabel(error)}
|
|
14868
|
-
`
|
|
14869
|
-
);
|
|
14870
|
-
}
|
|
14871
|
-
}
|
|
14872
|
-
if (failures > 0) {
|
|
14873
|
-
throw new Error(`${failures} map(s) failed to build; refusing to deploy without a seed`);
|
|
14874
|
-
}
|
|
14875
|
-
const known = new Set(catalog.maps.map((map) => map.slug));
|
|
14876
|
-
let pruned = 0;
|
|
14877
|
-
for (const name of readdirSync(seedDir)) {
|
|
14878
|
-
const match = /^(.+?)(?:\.meta)?\.json(?:\.gz)?$/.exec(name);
|
|
14879
|
-
const slug = match?.[1];
|
|
14880
|
-
if (slug === void 0 || known.has(slug)) continue;
|
|
14881
|
-
rmSync(path4.join(seedDir, name), { force: true });
|
|
14882
|
-
pruned += 1;
|
|
14883
|
-
}
|
|
14884
|
-
if (pruned > 0) {
|
|
14885
|
-
process.stdout.write(`pruned ${pruned} stale seed asset(s)
|
|
14886
|
-
`);
|
|
14887
|
-
}
|
|
14888
|
-
process.stdout.write(
|
|
14889
|
-
`seed assets: ${path4.relative(cwd, seedDir)} (served at /seed/<slug>.json[.gz])
|
|
14890
|
-
`
|
|
14891
|
-
);
|
|
14892
|
-
}
|
|
14893
|
-
function parseWorkerPrepareFlags(args) {
|
|
14894
|
-
let config = DEFAULT_CONFIG2;
|
|
14895
|
-
let assets;
|
|
14896
|
-
let force = false;
|
|
14897
|
-
for (let i = 0; i < args.length; i += 1) {
|
|
14898
|
-
const arg = args[i];
|
|
14899
|
-
if (arg === void 0) continue;
|
|
14900
|
-
if (arg === "--config" || arg.startsWith("--config=")) {
|
|
14901
|
-
config = readFlagValue(args, i, "--config");
|
|
14902
|
-
if (!arg.includes("=")) i += 1;
|
|
14903
|
-
} else if (arg === "--assets" || arg.startsWith("--assets=")) {
|
|
14904
|
-
assets = readFlagValue(args, i, "--assets");
|
|
14905
|
-
if (!arg.includes("=")) i += 1;
|
|
14906
|
-
} else if (arg === "--force") {
|
|
14907
|
-
force = true;
|
|
14908
|
-
} else {
|
|
14909
|
-
throw new Error(`unexpected worker prepare option "${arg}"`);
|
|
14910
|
-
}
|
|
14911
|
-
}
|
|
14912
|
-
return { config, ...assets !== void 0 ? { assets } : {}, force };
|
|
14913
|
-
}
|
|
14914
|
-
function formatBytes(bytes) {
|
|
14915
|
-
if (bytes < 1024) return `${bytes} B`;
|
|
14916
|
-
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
14917
|
-
return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
|
|
14918
|
-
}
|
|
14919
|
-
async function runWorkerPrepare(args) {
|
|
14920
|
-
const flags = parseWorkerPrepareFlags(args);
|
|
14921
|
-
const result = await prepareWorkerAssets({
|
|
14922
|
-
cwd: process.cwd(),
|
|
14923
|
-
configPath: flags.config,
|
|
14924
|
-
...flags.assets !== void 0 ? { assetsDir: flags.assets } : {},
|
|
14925
|
-
force: flags.force
|
|
14926
|
-
});
|
|
14927
|
-
const target = path4.relative(process.cwd(), result.targetDir) || ".";
|
|
14928
|
-
process.stdout.write(
|
|
14929
|
-
`${result.copied ? "synced" : "up to date"}: ${result.files} assets, ${formatBytes(result.bytes)} -> ${target}
|
|
14930
|
-
`
|
|
14931
|
-
);
|
|
14932
|
-
}
|
|
14933
|
-
async function runWorker(args) {
|
|
14934
|
-
const [subcommand, ...rest] = args;
|
|
14935
|
-
if (subcommand === void 0 || subcommand === "--help" || subcommand === "-h" || subcommand === "help") {
|
|
14936
|
-
printUsage();
|
|
14937
|
-
return;
|
|
14938
|
-
}
|
|
14939
|
-
if (subcommand === "prepare") {
|
|
14940
|
-
if (rest.includes("-h") || rest.includes("--help")) {
|
|
14941
|
-
printUsage();
|
|
14942
|
-
return;
|
|
14943
|
-
}
|
|
14944
|
-
await runWorkerPrepare(rest);
|
|
14945
|
-
return;
|
|
14946
|
-
}
|
|
14947
|
-
if (subcommand === "build-seed") {
|
|
14948
|
-
if (rest.includes("-h") || rest.includes("--help")) {
|
|
14949
|
-
printUsage();
|
|
14950
|
-
return;
|
|
14951
|
-
}
|
|
14952
|
-
await runWorkerBuildSeed(rest);
|
|
14953
|
-
return;
|
|
14954
|
-
}
|
|
14955
|
-
throw new Error(`unknown worker command "${subcommand}"`);
|
|
14956
|
-
}
|
|
14957
15506
|
async function runServe(args) {
|
|
14958
15507
|
const flags = parseServeFlags(args);
|
|
14959
15508
|
const { unstable_dev, unstable_readConfig } = await import('wrangler');
|
|
@@ -14964,14 +15513,41 @@ async function runServe(args) {
|
|
|
14964
15513
|
}
|
|
14965
15514
|
const assetsDir = config.assets?.directory;
|
|
14966
15515
|
if (typeof assetsDir === "string" && assetsDir.length > 0) {
|
|
14967
|
-
|
|
15516
|
+
try {
|
|
15517
|
+
await syncPublicAssets({ cwd: process.cwd(), configPath: flags.config, assetsDir });
|
|
15518
|
+
} catch (error) {
|
|
15519
|
+
process.stdout.write(
|
|
15520
|
+
`cajonzero: UI sync skipped (${error instanceof Error ? error.message : String(error)})
|
|
15521
|
+
`
|
|
15522
|
+
);
|
|
15523
|
+
}
|
|
14968
15524
|
}
|
|
14969
15525
|
const secrets = localDevVars();
|
|
15526
|
+
const persistTo = path4.resolve(
|
|
15527
|
+
path4.dirname(path4.resolve(flags.config)),
|
|
15528
|
+
".wrangler",
|
|
15529
|
+
"state"
|
|
15530
|
+
);
|
|
15531
|
+
const scriptsBinding = scriptsKvBinding(path4.resolve(flags.config));
|
|
15532
|
+
if (scriptsBinding !== void 0) {
|
|
15533
|
+
const uploaded = uploadScriptPacks(
|
|
15534
|
+
process.cwd(),
|
|
15535
|
+
flags.config,
|
|
15536
|
+
path4.resolve(process.cwd(), DEFAULT_SCRIPTS_DIR),
|
|
15537
|
+
scriptsBinding,
|
|
15538
|
+
{ remote: false, persistTo }
|
|
15539
|
+
);
|
|
15540
|
+
if (uploaded > 0) {
|
|
15541
|
+
process.stdout.write(`map scripts: ${uploaded} local KV key(s) -> ${scriptsBinding}
|
|
15542
|
+
`);
|
|
15543
|
+
}
|
|
15544
|
+
}
|
|
14970
15545
|
const worker = await unstable_dev(entry, {
|
|
14971
15546
|
config: flags.config,
|
|
14972
15547
|
ip: flags.host,
|
|
14973
15548
|
port: flags.port,
|
|
14974
15549
|
local: true,
|
|
15550
|
+
persistTo,
|
|
14975
15551
|
logLevel: "info",
|
|
14976
15552
|
// Inject local-dev secrets (from the environment) on top of the config
|
|
14977
15553
|
// `vars` so auth/session work locally without `wrangler secret put`.
|
|
@@ -15015,22 +15591,38 @@ async function main(argv) {
|
|
|
15015
15591
|
printUsage();
|
|
15016
15592
|
return;
|
|
15017
15593
|
}
|
|
15594
|
+
if (rest.includes("-h") || rest.includes("--help")) {
|
|
15595
|
+
printUsage();
|
|
15596
|
+
return;
|
|
15597
|
+
}
|
|
15018
15598
|
try {
|
|
15019
15599
|
switch (command) {
|
|
15020
15600
|
case "serve":
|
|
15021
15601
|
await runServe(rest);
|
|
15022
15602
|
return;
|
|
15023
15603
|
case "create":
|
|
15024
|
-
runCreate(rest);
|
|
15604
|
+
await runCreate(rest);
|
|
15025
15605
|
return;
|
|
15026
15606
|
case "setup":
|
|
15027
15607
|
await runSetup(rest);
|
|
15028
15608
|
return;
|
|
15029
|
-
case "
|
|
15030
|
-
await
|
|
15609
|
+
case "add":
|
|
15610
|
+
await runAdd(rest);
|
|
15611
|
+
return;
|
|
15612
|
+
case "update":
|
|
15613
|
+
await runUpdate(rest);
|
|
15614
|
+
return;
|
|
15615
|
+
case "list":
|
|
15616
|
+
runList(rest);
|
|
15617
|
+
return;
|
|
15618
|
+
case "remove":
|
|
15619
|
+
runRemove(rest);
|
|
15620
|
+
return;
|
|
15621
|
+
case "sync":
|
|
15622
|
+
await runSync(rest);
|
|
15031
15623
|
return;
|
|
15032
|
-
case "
|
|
15033
|
-
await
|
|
15624
|
+
case "deploy":
|
|
15625
|
+
await runDeploy(rest);
|
|
15034
15626
|
return;
|
|
15035
15627
|
default:
|
|
15036
15628
|
process.stderr.write(`cajonzero: unknown command "${command}"
|