@dzbot/dzstudio-mcp 0.0.0-stage → 0.1.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.
Files changed (49) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +162 -2
  3. package/dist/config/config.js +172 -0
  4. package/dist/config/config.js.map +1 -0
  5. package/dist/config/sessions.js +67 -0
  6. package/dist/config/sessions.js.map +1 -0
  7. package/dist/index.js +16 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/mcp/agent.js +1148 -0
  10. package/dist/mcp/agent.js.map +1 -0
  11. package/dist/mcp/server.js +263 -0
  12. package/dist/mcp/server.js.map +1 -0
  13. package/dist/protocol/client.js +134 -0
  14. package/dist/protocol/client.js.map +1 -0
  15. package/dist/protocol/session.js +837 -0
  16. package/dist/protocol/session.js.map +1 -0
  17. package/dist/protocol/transport.js +66 -0
  18. package/dist/protocol/transport.js.map +1 -0
  19. package/dist/scene/chunks.js +30 -0
  20. package/dist/scene/chunks.js.map +1 -0
  21. package/dist/scene/edits.js +183 -0
  22. package/dist/scene/edits.js.map +1 -0
  23. package/dist/scene/float32.js +167 -0
  24. package/dist/scene/float32.js.map +1 -0
  25. package/dist/scene/ids.js +43 -0
  26. package/dist/scene/ids.js.map +1 -0
  27. package/dist/scene/index.js +9 -0
  28. package/dist/scene/index.js.map +1 -0
  29. package/dist/scene/json.js +294 -0
  30. package/dist/scene/json.js.map +1 -0
  31. package/dist/scene/projectload.js +652 -0
  32. package/dist/scene/projectload.js.map +1 -0
  33. package/dist/scene/scene.js +506 -0
  34. package/dist/scene/scene.js.map +1 -0
  35. package/dist/scene/srcjson.js +297 -0
  36. package/dist/scene/srcjson.js.map +1 -0
  37. package/dist/scene/textform.js +257 -0
  38. package/dist/scene/textform.js.map +1 -0
  39. package/dist/scene/types.js +35 -0
  40. package/dist/scene/types.js.map +1 -0
  41. package/dist/world/data.js +604 -0
  42. package/dist/world/data.js.map +1 -0
  43. package/dist/world/format.js +205 -0
  44. package/dist/world/format.js.map +1 -0
  45. package/dist/world/source.js +267 -0
  46. package/dist/world/source.js.map +1 -0
  47. package/dist/world/tools.js +530 -0
  48. package/dist/world/tools.js.map +1 -0
  49. package/package.json +48 -4
@@ -0,0 +1,205 @@
1
+ import { createHash } from 'node:crypto';
2
+ /**
3
+ * The binary files of world data format 1: 256 m map tiles (`DZWT`) and model rasters (`DZWS`), both gzip over
4
+ * little-endian bytes. Lengths in the files are whole centimetres (heights, positions) or millimetres (raster grid).
5
+ */
6
+ export const FORMAT = 1;
7
+ export const TILE = 256;
8
+ export const POINTS = TILE + 1;
9
+ export const REVISION = /^[0-9]+\.[0-9]+-[1-9][0-9]*$/;
10
+ export const CHANNELS = ['f', 'v', 'g', 'r'];
11
+ /** First 16 hex characters of the SHA-1 over the lower-case model path. */
12
+ export function modelId(shape) {
13
+ return createHash('sha1').update(shape.toLowerCase(), 'utf8').digest('hex').slice(0, 16);
14
+ }
15
+ export function sha256(buf) {
16
+ return createHash('sha256').update(buf).digest('hex');
17
+ }
18
+ export function cmpVersion(a, b) {
19
+ const pa = a.split('.').map(Number);
20
+ const pb = b.split('.').map(Number);
21
+ for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
22
+ const d = (pa[i] ?? 0) - (pb[i] ?? 0);
23
+ if (d)
24
+ return d;
25
+ }
26
+ return 0;
27
+ }
28
+ /** Orders revisions `<major>.<minor>-<n>`. */
29
+ export function cmpRevision(a, b) {
30
+ const [va = '', na = '0'] = a.split('-');
31
+ const [vb = '', nb = '0'] = b.split('-');
32
+ return cmpVersion(va, vb) || Number(na) - Number(nb);
33
+ }
34
+ class Reader {
35
+ buf;
36
+ view;
37
+ off = 0;
38
+ constructor(buf) {
39
+ this.buf = buf;
40
+ this.view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
41
+ }
42
+ u8() {
43
+ return this.view.getUint8(this.off++);
44
+ }
45
+ u16() {
46
+ const v = this.view.getUint16(this.off, true);
47
+ this.off += 2;
48
+ return v;
49
+ }
50
+ i16() {
51
+ const v = this.view.getInt16(this.off, true);
52
+ this.off += 2;
53
+ return v;
54
+ }
55
+ u32() {
56
+ const v = this.view.getUint32(this.off, true);
57
+ this.off += 4;
58
+ return v;
59
+ }
60
+ i32() {
61
+ const v = this.view.getInt32(this.off, true);
62
+ this.off += 4;
63
+ return v;
64
+ }
65
+ ascii(n) {
66
+ let s = '';
67
+ for (let i = 0; i < n; i++)
68
+ s += String.fromCharCode(this.buf[this.off + i]);
69
+ this.off += n;
70
+ return s;
71
+ }
72
+ varint() {
73
+ let v = 0;
74
+ let shift = 0;
75
+ let b;
76
+ do {
77
+ b = this.buf[this.off++];
78
+ v += (b & 0x7f) * 2 ** shift;
79
+ shift += 7;
80
+ } while (b & 0x80);
81
+ return v;
82
+ }
83
+ sub(n) {
84
+ const r = new Reader(this.buf.subarray(this.off, this.off + n));
85
+ this.off += n;
86
+ return r;
87
+ }
88
+ }
89
+ export function decodeTile(raw) {
90
+ const r = new Reader(raw);
91
+ if (r.ascii(4) !== 'DZWT')
92
+ throw new Error('not a tile');
93
+ const format = r.u16();
94
+ if (format !== FORMAT)
95
+ throw new Error(`tile format ${format}`);
96
+ const tx = r.u16();
97
+ const tz = r.u16();
98
+ const count = r.u16();
99
+ const N = POINTS * POINTS;
100
+ let heights = new Int32Array(N);
101
+ let matl = new Uint16Array(N);
102
+ let road = { k: new Int32Array(0), shape: new Int32Array(0), dh: new Int32Array(0) };
103
+ let objs = {
104
+ n: 0,
105
+ tab: new Int32Array(0),
106
+ x: new Int32Array(0),
107
+ z: new Int32Array(0),
108
+ y: new Int32Array(0),
109
+ m: new Int32Array(0),
110
+ };
111
+ for (let s = 0; s < count; s++) {
112
+ const id = r.ascii(4);
113
+ const enc = r.u8();
114
+ r.off += 3;
115
+ const len = r.u32();
116
+ const p = r.sub(len);
117
+ if (id === 'HGHT') {
118
+ const base = p.i32();
119
+ const h = new Int32Array(N);
120
+ for (let row = 0; row < POINTS; row++) {
121
+ for (let c = 0; c < POINTS; c++) {
122
+ const i = row * POINTS + c;
123
+ if (enc === 1)
124
+ h[i] = c === 0 ? base + p.i16() : h[i - 1] + p.i16();
125
+ else
126
+ h[i] = base + p.i32();
127
+ }
128
+ }
129
+ heights = h;
130
+ }
131
+ else if (id === 'MATL') {
132
+ const m = new Uint16Array(N);
133
+ for (let i = 0; i < N; i++)
134
+ m[i] = enc === 1 ? p.u8() : p.u16();
135
+ matl = m;
136
+ }
137
+ else if (id === 'ROAD') {
138
+ const n = p.u32();
139
+ const k = new Int32Array(n);
140
+ const shape = new Int32Array(n);
141
+ const dh = new Int32Array(n);
142
+ let prev = 0;
143
+ for (let i = 0; i < n; i++) {
144
+ prev += p.varint();
145
+ k[i] = prev;
146
+ }
147
+ for (let i = 0; i < n; i++)
148
+ shape[i] = p.varint();
149
+ for (let i = 0; i < n; i++)
150
+ dh[i] = p.i32();
151
+ road = { k, shape, dh };
152
+ }
153
+ else if (id === 'OBJS') {
154
+ const n = p.u32();
155
+ const tab = new Int32Array(n);
156
+ const x = new Int32Array(n);
157
+ const z = new Int32Array(n);
158
+ const y = new Int32Array(n);
159
+ const m = new Int32Array(n * 9);
160
+ for (let i = 0; i < n; i++)
161
+ tab[i] = p.varint();
162
+ for (let i = 0; i < n; i++)
163
+ x[i] = p.i32();
164
+ for (let i = 0; i < n; i++)
165
+ z[i] = p.i32();
166
+ for (let i = 0; i < n; i++)
167
+ y[i] = p.i32();
168
+ for (let k = 0; k < 9; k++)
169
+ for (let i = 0; i < n; i++)
170
+ m[i * 9 + k] = p.i32();
171
+ objs = { n, tab, x, z, y, m };
172
+ }
173
+ }
174
+ return { tx, tz, heights, matl, road, objs };
175
+ }
176
+ export const NO_HIT = -2147483648;
177
+ export function decodeRaster(raw) {
178
+ const r = new Reader(raw);
179
+ if (r.ascii(4) !== 'DZWS')
180
+ throw new Error('not a raster');
181
+ const format = r.u16();
182
+ if (format !== FORMAT)
183
+ throw new Error(`raster format ${format}`);
184
+ const nx = r.u16();
185
+ const nz = r.u16();
186
+ const count = r.u8();
187
+ r.u8();
188
+ const out = { nx, nz, stepMm: r.u32(), x0Mm: r.i32(), z0Mm: r.i32(), channels: {} };
189
+ for (let c = 0; c < count; c++) {
190
+ const ch = r.ascii(1);
191
+ const enc = r.u8();
192
+ const vals = new Int32Array(nx * nz);
193
+ for (let k = 0; k < nx * nz; k++) {
194
+ if (enc === 1) {
195
+ const v = r.i16();
196
+ vals[k] = v === -32768 ? NO_HIT : v;
197
+ }
198
+ else
199
+ vals[k] = r.i32();
200
+ }
201
+ out.channels[ch] = vals;
202
+ }
203
+ return out;
204
+ }
205
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/world/format.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;GAGG;AAEH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,CAAC;AACxB,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,CAAC;AACxB,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC;AAC/B,MAAM,CAAC,MAAM,QAAQ,GAAG,8BAA8B,CAAC;AACvD,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAU,CAAC;AAGtD,2EAA2E;AAC3E,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC3F,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,GAAe;IACpC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,CAAS,EAAE,CAAS;IAC7C,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACxD,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,WAAW,CAAC,CAAS,EAAE,CAAS;IAC9C,MAAM,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACzC,MAAM,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACzC,OAAO,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,MAAM;IAIW,GAAG;IAHP,IAAI,CAAW;IAChC,GAAG,GAAG,CAAC,CAAC;IAER,YAAqB,GAAe;mBAAf,GAAG;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IACvE,CAAC;IAED,EAAE;QACA,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACxC,CAAC;IACD,GAAG;QACD,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QACd,OAAO,CAAC,CAAC;IACX,CAAC;IACD,GAAG;QACD,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QACd,OAAO,CAAC,CAAC;IACX,CAAC;IACD,GAAG;QACD,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QACd,OAAO,CAAC,CAAC;IACX,CAAC;IACD,GAAG;QACD,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QACd,OAAO,CAAC,CAAC;IACX,CAAC;IACD,KAAK,CAAC,CAAS;QACb,IAAI,CAAC,GAAG,EAAE,CAAC;QACX,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAAE,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAE,CAAC,CAAC;QAC9E,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QACd,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM;QACJ,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,CAAS,CAAC;QACd,GAAG,CAAC;YACF,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,CAAE,CAAC;YAC1B,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC;YAC7B,KAAK,IAAI,CAAC,CAAC;QACb,CAAC,QAAQ,CAAC,GAAG,IAAI,EAAE;QACnB,OAAO,CAAC,CAAC;IACX,CAAC;IACD,GAAG,CAAC,CAAS;QACX,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QAChE,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QACd,OAAO,CAAC,CAAC;IACX,CAAC;CACF;AA2BD,MAAM,UAAU,UAAU,CAAC,GAAe;IACxC,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IACvB,IAAI,MAAM,KAAK,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,eAAe,MAAM,EAAE,CAAC,CAAC;IAChE,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IACnB,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IACnB,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IACtB,MAAM,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC;IAC1B,IAAI,OAAO,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IAChC,IAAI,IAAI,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,IAAI,GAAG,EAAE,CAAC,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IACrF,IAAI,IAAI,GAAgB;QACtB,CAAC,EAAE,CAAC;QACJ,GAAG,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC;QACtB,CAAC,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC;QACpB,CAAC,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC;QACpB,CAAC,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC;QACpB,CAAC,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC;KACrB,CAAC;IACF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,GAAG,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC;QACnB,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACX,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QACpB,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrB,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;YAClB,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YACrB,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;YAC5B,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;gBACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBAChC,MAAM,CAAC,GAAG,GAAG,GAAG,MAAM,GAAG,CAAC,CAAC;oBAC3B,IAAI,GAAG,KAAK,CAAC;wBAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;;wBAChE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;gBAC7B,CAAC;YACH,CAAC;YACD,OAAO,GAAG,CAAC,CAAC;QACd,CAAC;aAAM,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;YACzB,MAAM,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;YAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBAAE,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;YAChE,IAAI,GAAG,CAAC,CAAC;QACX,CAAC;aAAM,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;YACzB,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YAClB,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;YAC5B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;YAChC,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;YAC7B,IAAI,IAAI,GAAG,CAAC,CAAC;YACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3B,IAAI,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;gBACnB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;YACd,CAAC;YACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;YAClD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YAC5C,IAAI,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QAC1B,CAAC;aAAM,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;YACzB,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YAClB,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;YAC9B,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;YAC5B,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;YAC5B,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;YAC5B,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;YAChD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;oBAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YAC/E,IAAI,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QAChC,CAAC;IACH,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC;AAYlC,MAAM,UAAU,YAAY,CAAC,GAAe;IAC1C,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IACvB,IAAI,MAAM,KAAK,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,MAAM,EAAE,CAAC,CAAC;IAClE,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IACnB,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IACnB,MAAM,KAAK,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC;IACrB,CAAC,CAAC,EAAE,EAAE,CAAC;IACP,MAAM,GAAG,GAAW,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAC5F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAY,CAAC;QACjC,MAAM,GAAG,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC;QACnB,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YACjC,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;gBACd,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;gBAClB,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YACtC,CAAC;;gBAAM,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QAC3B,CAAC;QACD,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;IAC1B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,267 @@
1
+ import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, statSync, utimesSync, writeFileSync } from 'node:fs';
2
+ import { dirname, join, relative, sep } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { cmpRevision, FORMAT, REVISION, sha256 } from './format.js';
5
+ export const DEFAULT_BASE = 'https://uploads.dzbot.de/world-data/';
6
+ export const DEFAULT_POINTER = 'https://dzbot.de/api/public/world-data';
7
+ const POINTER_TTL_MS = 5 * 60_000;
8
+ export const DEFAULT_CACHE_LIMIT = 2 * 1024 ** 3;
9
+ /** Data that cannot be had right now (offline, not published). */
10
+ export class DataUnavailable extends Error {
11
+ }
12
+ /** A file whose size or checksum does not match, even after loading it again. */
13
+ export class DataCorrupt extends Error {
14
+ }
15
+ export class NewerFormat extends Error {
16
+ constructor() {
17
+ super('World data in a newer format — update the MCP');
18
+ }
19
+ }
20
+ function slash(url) {
21
+ return url.endsWith('/') ? url : url + '/';
22
+ }
23
+ function cacheName(base) {
24
+ return base
25
+ .replace(/^[a-z]+:\/\//, '')
26
+ .replace(/[^A-Za-z0-9.-]+/g, '_')
27
+ .replace(/_+$/, '');
28
+ }
29
+ function writeAtomic(path, data) {
30
+ mkdirSync(dirname(path), { recursive: true });
31
+ const tmp = `${path}.${process.pid}.tmp`;
32
+ writeFileSync(tmp, data);
33
+ renameSync(tmp, path);
34
+ }
35
+ function latestIn(dir) {
36
+ if (!existsSync(dir))
37
+ return undefined;
38
+ const revs = readdirSync(dir).filter((r) => REVISION.test(r));
39
+ revs.sort(cmpRevision);
40
+ return revs[revs.length - 1];
41
+ }
42
+ /**
43
+ * Reads world data from a local folder or a base address. Downloaded files are kept on disk below their revision and
44
+ * never requested again; tiles and rasters are checked against size and SHA-256 on every load, and a mismatch in the
45
+ * cache is discarded and loaded once more.
46
+ */
47
+ export class WorldDataSource {
48
+ base;
49
+ local;
50
+ pointerUrl;
51
+ cache;
52
+ fetchFn;
53
+ pointerAt = 0;
54
+ pointerValue;
55
+ cacheLimit;
56
+ /** Cached files below the base (path relative to it, with `/`): size and last use. */
57
+ cached;
58
+ inUse = () => [];
59
+ constructor(opts) {
60
+ const base = slash(opts.base ?? DEFAULT_BASE);
61
+ this.base = base;
62
+ this.fetchFn = opts.fetch ?? fetch;
63
+ this.cacheLimit = opts.cacheLimit ?? DEFAULT_CACHE_LIMIT;
64
+ if (base.startsWith('file:')) {
65
+ this.local = fileURLToPath(base);
66
+ }
67
+ else if (/^https?:/.test(base)) {
68
+ this.cache = join(opts.cacheDir, cacheName(base));
69
+ }
70
+ else {
71
+ this.local = base;
72
+ }
73
+ this.pointerUrl = opts.pointer ?? (!this.local && base === DEFAULT_BASE ? DEFAULT_POINTER : undefined);
74
+ }
75
+ /** The current revisions; at most every 5 minutes from the network, otherwise the last answer. */
76
+ async pointer() {
77
+ if (this.pointerValue && Date.now() - this.pointerAt < POINTER_TTL_MS)
78
+ return this.pointerValue;
79
+ let p;
80
+ if (this.pointerUrl) {
81
+ const stored = this.cache ? join(this.cache, 'pointer.json') : undefined;
82
+ try {
83
+ const bytes = await this.download(this.pointerUrl);
84
+ p = JSON.parse(Buffer.from(bytes).toString('utf8'));
85
+ if (stored)
86
+ writeAtomic(stored, bytes);
87
+ }
88
+ catch (e) {
89
+ if (this.pointerValue)
90
+ return this.pointerValue;
91
+ if (stored && existsSync(stored))
92
+ p = JSON.parse(readFileSync(stored, 'utf8'));
93
+ else
94
+ throw e instanceof DataUnavailable ? e : new DataUnavailable(e.message);
95
+ }
96
+ }
97
+ else if (this.local) {
98
+ p = this.scanLocal();
99
+ }
100
+ else {
101
+ throw new DataUnavailable(`No pointer configured for ${this.base}`);
102
+ }
103
+ if (typeof p.format !== 'number' || p.format > FORMAT)
104
+ throw new NewerFormat();
105
+ this.pointerValue = p;
106
+ this.pointerAt = Date.now();
107
+ return p;
108
+ }
109
+ /** A pointer built from a local folder: the newest revision of every world and of the class data. */
110
+ scanLocal() {
111
+ const root = this.local;
112
+ const worlds = [];
113
+ const worldsDir = join(root, 'worlds');
114
+ if (existsSync(worldsDir)) {
115
+ for (const world of readdirSync(worldsDir).sort()) {
116
+ const revision = latestIn(join(worldsDir, world));
117
+ if (!revision)
118
+ continue;
119
+ const entry = { world, revision };
120
+ try {
121
+ const m = JSON.parse(readFileSync(join(worldsDir, world, revision, 'manifest.json'), 'utf8'));
122
+ if (typeof m.map === 'string')
123
+ entry.map = m.map;
124
+ if (typeof m.game === 'string')
125
+ entry.game = m.game;
126
+ }
127
+ catch {
128
+ continue;
129
+ }
130
+ worlds.push(entry);
131
+ }
132
+ }
133
+ const classes = latestIn(join(root, 'classes'));
134
+ if (!classes && !worlds.length)
135
+ throw new DataUnavailable(`No world data in ${root}`);
136
+ return { format: FORMAT, classes: classes ?? '', worlds };
137
+ }
138
+ async download(url) {
139
+ let res;
140
+ try {
141
+ res = await this.fetchFn(url, { signal: AbortSignal.timeout(30_000) });
142
+ }
143
+ catch (e) {
144
+ throw new DataUnavailable(`not reachable: ${url} (${e.message})`);
145
+ }
146
+ if (res.status === 404)
147
+ throw new DataUnavailable(`not published: ${url}`);
148
+ if (!res.ok)
149
+ throw new DataUnavailable(`HTTP ${res.status}: ${url}`);
150
+ return new Uint8Array(await res.arrayBuffer());
151
+ }
152
+ /** Bytes of an immutable file below the base (a path under a revision). */
153
+ async file(rel) {
154
+ if (this.local) {
155
+ const p = join(this.local, ...rel.split('/'));
156
+ if (!existsSync(p))
157
+ throw new DataUnavailable(`missing: ${rel}`);
158
+ return readFileSync(p);
159
+ }
160
+ const p = join(this.cache, ...rel.split('/'));
161
+ if (existsSync(p)) {
162
+ const bytes = readFileSync(p);
163
+ this.touch(rel, p, bytes.length);
164
+ return bytes;
165
+ }
166
+ const bytes = await this.download(this.base + rel);
167
+ writeAtomic(p, bytes);
168
+ this.touch(rel, p, bytes.length);
169
+ this.trim();
170
+ return bytes;
171
+ }
172
+ /**
173
+ * Names the revisions that must stay in the cache: a function returning path prefixes below the base, such as
174
+ * `worlds/chernarusplus/1.30-1/` or `classes/1.30-1/`. Nothing below them is ever evicted.
175
+ */
176
+ protect(inUse) {
177
+ this.inUse = inUse;
178
+ }
179
+ index() {
180
+ if (this.cached)
181
+ return this.cached;
182
+ const out = new Map();
183
+ const walk = (dir) => {
184
+ if (!existsSync(dir))
185
+ return;
186
+ for (const e of readdirSync(dir, { withFileTypes: true })) {
187
+ const full = join(dir, e.name);
188
+ if (e.isDirectory())
189
+ walk(full);
190
+ else if (e.isFile() && !e.name.endsWith('.tmp')) {
191
+ const rel = relative(this.cache, full).split(sep).join('/');
192
+ if (rel === 'pointer.json')
193
+ continue;
194
+ const st = statSync(full);
195
+ out.set(rel, { bytes: st.size, used: st.mtimeMs });
196
+ }
197
+ }
198
+ };
199
+ walk(this.cache);
200
+ this.cached = out;
201
+ return out;
202
+ }
203
+ /** Records a use; the file's modification time carries it across restarts. */
204
+ touch(rel, path, bytes) {
205
+ const now = Date.now();
206
+ const idx = this.index();
207
+ const prev = idx.get(rel);
208
+ idx.delete(rel);
209
+ idx.set(rel, { bytes, used: Math.max(now, (prev?.used ?? 0) + 1) });
210
+ try {
211
+ utimesSync(path, new Date(now), new Date(now));
212
+ }
213
+ catch {
214
+ // the use still counts for this run
215
+ }
216
+ }
217
+ forget(rel) {
218
+ rmSync(join(this.cache, ...rel.split('/')), { force: true });
219
+ this.cached?.delete(rel);
220
+ }
221
+ /** Bytes the disk cache holds now. */
222
+ get cacheBytes() {
223
+ let n = 0;
224
+ if (this.cache)
225
+ for (const e of this.index().values())
226
+ n += e.bytes;
227
+ return n;
228
+ }
229
+ /** Deletes the least recently used files until the cache fits its limit, sparing the revisions in use. */
230
+ trim() {
231
+ if (!this.cache)
232
+ return;
233
+ const idx = this.index();
234
+ let total = this.cacheBytes;
235
+ if (total <= this.cacheLimit)
236
+ return;
237
+ const keep = [...this.inUse()];
238
+ const order = [...idx.entries()].sort((a, b) => a[1].used - b[1].used);
239
+ for (const [rel, e] of order) {
240
+ if (total <= this.cacheLimit)
241
+ break;
242
+ if (keep.some((k) => rel.startsWith(k)))
243
+ continue;
244
+ this.forget(rel);
245
+ total -= e.bytes;
246
+ }
247
+ }
248
+ async json(rel) {
249
+ return JSON.parse(Buffer.from(await this.file(rel)).toString('utf8'));
250
+ }
251
+ /** A file the manifest or class index lists with size and SHA-256. */
252
+ async verified(rel, bytes, sum) {
253
+ const ok = (b) => b.length === bytes && sha256(b) === sum;
254
+ const first = await this.file(rel);
255
+ if (ok(first))
256
+ return first;
257
+ if (this.local)
258
+ throw new DataCorrupt(`map data corrupt: ${rel}`);
259
+ this.forget(rel);
260
+ const again = await this.file(rel);
261
+ if (ok(again))
262
+ return again;
263
+ this.forget(rel);
264
+ throw new DataCorrupt(`map data corrupt: ${rel}`);
265
+ }
266
+ }
267
+ //# sourceMappingURL=source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.js","sourceRoot":"","sources":["../../src/world/source.ts"],"names":[],"mappings":"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"}