keystonemc 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,33 @@
1
+ import { world } from '@minecraft/server';
2
+ import { Listener } from './types';
3
+ /**
4
+ * AfterEventMap / BeforeEventMap を world.afterEvents / world.beforeEvents の
5
+ * subscribe のハンドラ引数から自動抽出する。
6
+ *
7
+ * 例: world.afterEvents.playerSpawn.subscribe((ev: PlayerSpawnAfterEvent) => {...})
8
+ * の ev の型を自動的に E として取り出す。
9
+ */
10
+ type ExtractSubscribeArg<T> = T extends {
11
+ subscribe: (handler: (ev: infer E) => any) => any;
12
+ } ? E : never;
13
+ export type AfterEventMap = {
14
+ [K in keyof typeof world.afterEvents]: ExtractSubscribeArg<(typeof world.afterEvents)[K]>;
15
+ };
16
+ export type BeforeEventMap = {
17
+ [K in keyof typeof world.beforeEvents]: ExtractSubscribeArg<(typeof world.beforeEvents)[K]>;
18
+ };
19
+ type AfterEventName = keyof AfterEventMap;
20
+ type BeforeEventName = keyof BeforeEventMap;
21
+ export declare class EventManager {
22
+ private static afterListeners;
23
+ private static beforeListeners;
24
+ /** init: world.beforeEvents / world.afterEvents を全自動で subscribe して dispatch に流す */
25
+ static initialize(): void;
26
+ static registerAfter<K extends AfterEventName>(eventName: K, listener: Listener<AfterEventMap[K]>): void;
27
+ static registerBefore<K extends BeforeEventName>(eventName: K, listener: Listener<BeforeEventMap[K]>): void;
28
+ private static dispatchAfter;
29
+ private static dispatchBefore;
30
+ /** 登録済みリスナーを全部クリア(Plugin 単位で実装するなら拡張する) */
31
+ private static clearAll;
32
+ }
33
+ export {};
@@ -0,0 +1,18 @@
1
+ interface WaitForOptions {
2
+ onInterval?: () => void;
3
+ onTimeout?: () => void;
4
+ interval?: number;
5
+ timeout?: number;
6
+ resolveOnInterval?: boolean;
7
+ resolveOnTimeout?: boolean;
8
+ }
9
+ /**
10
+ * イベントを条件付きで待機(タイムアウト付き)
11
+ */
12
+ export declare function waitFor<T extends object>(predicate: (event: T) => boolean, options?: WaitForOptions): Promise<T>;
13
+ /**
14
+ * 複数イベントを束ねて非同期フローを開始
15
+ * すべてのイベントで、Entityを自動検出
16
+ */
17
+ export declare function flowListen<E extends object>(...args: any[]): void;
18
+ export {};
@@ -0,0 +1,8 @@
1
+ export declare enum Priority {
2
+ LOWEST = 5,
3
+ LOW = 4,
4
+ NORMAL = 3,
5
+ HIGH = 2,
6
+ HIGHEST = 1,
7
+ MONITOR = 0
8
+ }
@@ -0,0 +1,6 @@
1
+ import { Priority } from './priority';
2
+ /** リスナー型 */
3
+ export interface Listener<T> {
4
+ handler(event: T): void;
5
+ priority?: Priority;
6
+ }
@@ -0,0 +1,6 @@
1
+ export { keystone } from './keystone';
2
+ export { Vector3 } from './math/vector3';
3
+ export { Priority } from './event/priority';
4
+ export { EventManager } from './event/eventManager';
5
+ export { debug } from './utils/debugger';
6
+ export { RepeatingTimer, DelayedTimer, repeating, delayed, sleep } from './timer/timer';
@@ -0,0 +1,5 @@
1
+ declare class Keystone {
2
+ constructor();
3
+ }
4
+ export declare const keystone: Keystone;
5
+ export {};
@@ -0,0 +1,195 @@
1
+ import { Vector3 as _Vector3 } from '@minecraft/server';
2
+ export declare class Vector3 {
3
+ x: number;
4
+ y: number;
5
+ z: number;
6
+ constructor(x: number, y: number, z: number);
7
+ /**
8
+ * ゼロベクトルで生成
9
+ * @return {Vector3}
10
+ */
11
+ static zero(): Vector3;
12
+ /**
13
+ * {x, y, z} オブジェクトから生成
14
+ * @param {_Vector3} pos
15
+ * @returns
16
+ */
17
+ static fromBDS(pos: _Vector3): Vector3;
18
+ getX(): number;
19
+ getY(): number;
20
+ getZ(): number;
21
+ getFloorX(): number;
22
+ getFloorY(): number;
23
+ getFloorZ(): number;
24
+ /**
25
+ * 加算
26
+ * @param {number} x
27
+ * @param {number} y
28
+ * @param {number} z
29
+ * @return {Vector3}
30
+ */
31
+ add(x: number, y: number, z: number): Vector3;
32
+ /**
33
+ * ベクトル単位での加算
34
+ * @param {_Vector3} v
35
+ * @returns {Vector3}
36
+ */
37
+ addVector(v: _Vector3): Vector3;
38
+ /**
39
+ * 減算
40
+ * @param {number} x
41
+ * @param {number} y
42
+ * @param {number} z
43
+ * @return {Vector3}
44
+ */
45
+ subtract(x: number, y: number, z: number): Vector3;
46
+ /**
47
+ * ベクトル単位での減算
48
+ * @param {_Vector3} v
49
+ * @return {Vector3}
50
+ */
51
+ subtractVector(v: _Vector3): Vector3;
52
+ /**
53
+ * 乗算
54
+ * @param {number} value
55
+ * @return {Vector3}
56
+ */
57
+ multiply(value: number): Vector3;
58
+ /**
59
+ * 除算
60
+ * @param {number} value
61
+ * @return {Vector3}
62
+ */
63
+ divide(value: number): Vector3;
64
+ /**
65
+ * ベクトルの内部数値小数点切り上げ
66
+ * @return {Vector3}
67
+ */
68
+ ceil(): Vector3;
69
+ /**
70
+ * ベクトルの内部数値小数点切り捨て
71
+ * @return {Vector3}
72
+ */
73
+ floor(): Vector3;
74
+ /**
75
+ * ベクトルの内部数値小数点四捨五入
76
+ * @param {number} precision
77
+ * @return {Vector3}
78
+ */
79
+ round(precision?: number): Vector3;
80
+ /**
81
+ * ベクトルの内部数値の絶対値
82
+ * @return {Vector3}
83
+ */
84
+ abs(): Vector3;
85
+ /**
86
+ * 指定した2点間のユークリッド距離
87
+ * @param {_Vector3} pos
88
+ * @return {number}
89
+ */
90
+ distance(pos: _Vector3): number;
91
+ /**
92
+ * 指定した2点間のユークリッド距離の2乗
93
+ * @param {_Vector3} pos
94
+ * @return {number}
95
+ */
96
+ distanceSquared(pos: _Vector3): number;
97
+ /**
98
+ * 内積
99
+ * @param {_Vector3} pos
100
+ * @return {number}
101
+ */
102
+ dot(pos: _Vector3): number;
103
+ /**
104
+ * 外積
105
+ * @param {_Vector3} pos
106
+ * @return {Vector3}
107
+ */
108
+ cross(pos: _Vector3): Vector3;
109
+ /**
110
+ * ベクトルの比較
111
+ * @param {_Vector3} pos
112
+ * @return {boolean}
113
+ */
114
+ equals(pos: _Vector3): boolean;
115
+ /**
116
+ * ベクトルの長さ
117
+ * @return {number}
118
+ */
119
+ length(): number;
120
+ /**
121
+ * ベクトルの長さの2乗
122
+ * @return {number}
123
+ */
124
+ lengthSquared(): number;
125
+ /**
126
+ * 正規化
127
+ * @return {Vector3}
128
+ */
129
+ normalize(): Vector3;
130
+ /**
131
+ * オブジェクトの数値指定再生成
132
+ * @param {number} x
133
+ * @param {number} y
134
+ * @param {number} z
135
+ * @return {Vector3}
136
+ */
137
+ withComponents(x?: number, y?: number, z?: number): Vector3;
138
+ /**
139
+ * X座標をxValueにしたとき線分上に存在する点を返す
140
+ * @param end 終点
141
+ * @param xValue 途中点のX値
142
+ * @returns {Vector3 | undefined}
143
+ */
144
+ getIntermediateWithXValue(end: Vector3, xValue: number): Vector3 | undefined;
145
+ /**
146
+ * Y座標をyValueにしたとき線分上に存在する点を返す
147
+ * @param end 終点
148
+ * @param yValue 途中点のY値
149
+ * @returns {Vector3 | undefined}
150
+ */
151
+ getIntermediateWithYValue(end: Vector3, yValue: number): Vector3 | undefined;
152
+ /**
153
+ * Z座標をzValueにしたとき線分上に存在する点を返す
154
+ * @param end 終点
155
+ * @param zValue 途中点のZ値
156
+ * @returns {Vector3 | undefined}
157
+ */
158
+ getIntermediateWithZValue(end: Vector3, zValue: number): Vector3 | undefined;
159
+ /**
160
+ * BDS ScriptAPIで使える {x, y, z} 形式に変換
161
+ * @returns {_Vector3}
162
+ */
163
+ toBDS(): _Vector3;
164
+ /** 通常のオブジェクトに変換 */
165
+ toObject(): {
166
+ x: number;
167
+ y: number;
168
+ z: number;
169
+ };
170
+ toString(): string;
171
+ /**
172
+ * 最大点
173
+ * @param {_Vector3} vector
174
+ * @param {_Vector3[]} vectors
175
+ * @returns {Vector3}
176
+ */
177
+ static maxComponents(vector: _Vector3, ...vectors: _Vector3[]): Vector3;
178
+ /**
179
+ * 最小点
180
+ * @param {_Vector3} vector
181
+ * @param {_Vector3[]} vectors
182
+ * @returns {Vector3}
183
+ */
184
+ static minComponents(vector: _Vector3, ...vectors: _Vector3[]): Vector3;
185
+ /**
186
+ * 合計
187
+ * @param {_Vector3[]} vectors
188
+ * @returns {Vector3}
189
+ */
190
+ static sum(...vectors: {
191
+ x: number;
192
+ y: number;
193
+ z: number;
194
+ }[]): Vector3;
195
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * ============================================================
3
+ * マスター Interval(負荷分散スケジューラ)
4
+ * ============================================================
5
+ */
6
+ export declare class TimerScheduler {
7
+ private static tasks;
8
+ private static tick;
9
+ private static started;
10
+ /** スケジューラにタスクを登録 */
11
+ static addTask(task: () => void): void;
12
+ /** タスクを削除 */
13
+ static removeTask(task: () => void): void;
14
+ /** Interval を開始(1 本だけ) */
15
+ private static ensureStarted;
16
+ }
17
+ /** 内部キャンセル結果 */
18
+ declare enum CancelResult {
19
+ SUCCESS = 0,
20
+ FORCE = 1,
21
+ FAILURE = 2
22
+ }
23
+ /**
24
+ * ============================================================
25
+ * Base Timer
26
+ * ============================================================
27
+ * スケジューラに登録され、tick ごとに管理される抽象クラス
28
+ */
29
+ declare abstract class Timer {
30
+ protected currentTick: number;
31
+ protected onRun?: (currentTick: number) => void;
32
+ protected onCancel?: () => void;
33
+ protected stopped: boolean;
34
+ protected canceled: boolean;
35
+ protected forceCanceled: boolean;
36
+ /** スケジューラに登録されたタスク */
37
+ protected task?: () => void;
38
+ constructor(onRun?: (currentTick: number) => void, onCancel?: () => void);
39
+ /** 開始(各派生クラスで実装) */
40
+ abstract start(): void;
41
+ /** 一時停止 */
42
+ stop(): void;
43
+ /** 再開 */
44
+ resume(): void;
45
+ /** 停止しているか */
46
+ isStopped(): boolean;
47
+ /** キャンセル要求 */
48
+ cancel(force?: boolean): void;
49
+ /** タイマー内部キャンセル */
50
+ protected internalCancel(force?: boolean): CancelResult;
51
+ }
52
+ export interface RepeatingOptions {
53
+ period?: number;
54
+ endless?: boolean;
55
+ silenceOnStop?: boolean;
56
+ maxElapsedTicks?: number;
57
+ onFinal?: () => void;
58
+ }
59
+ /**
60
+ * 一定間隔で実行される繰り返しタイマー
61
+ */
62
+ export declare class RepeatingTimer extends Timer {
63
+ private period;
64
+ private endless;
65
+ private silenceOnStop;
66
+ private maxElapsedTicks?;
67
+ private onFinal?;
68
+ constructor(onRun?: (currentTick: number) => void, opts?: RepeatingOptions, onCancel?: () => void);
69
+ /** タイマー開始 */
70
+ start(): void;
71
+ }
72
+ export interface DelayedOptions {
73
+ delay?: number;
74
+ }
75
+ /**
76
+ * 指定 tick 後に一度だけ実行されるタイマー
77
+ */
78
+ export declare class DelayedTimer extends Timer {
79
+ private delay;
80
+ constructor(onRun?: (currentTick: number) => void, opts?: DelayedOptions, onCancel?: () => void);
81
+ start(): void;
82
+ }
83
+ export declare function repeating(opts: {
84
+ every?: number;
85
+ endless?: boolean;
86
+ max?: number;
87
+ silenceWhenStopped?: boolean;
88
+ run?: (tick: number) => void;
89
+ cancel?: () => void;
90
+ final?: () => void;
91
+ }): RepeatingTimer;
92
+ export declare function delayed(ticks: number, run: () => void, cancel?: () => void): DelayedTimer;
93
+ export declare function sleep(tick: number): Promise<void>;
94
+ export {};
@@ -0,0 +1 @@
1
+ export declare function debug(...args: any[]): void;
package/dist/index.js ADDED
@@ -0,0 +1,770 @@
1
+ import { world, system } from "@minecraft/server";
2
+ class Keystone {
3
+ constructor() {
4
+ }
5
+ }
6
+ const keystone = new Keystone();
7
+ class Vector3 {
8
+ constructor(x, y, z) {
9
+ this.x = x;
10
+ this.y = y;
11
+ this.z = z;
12
+ }
13
+ /**
14
+ * ゼロベクトルで生成
15
+ * @return {Vector3}
16
+ */
17
+ static zero() {
18
+ return new Vector3(0, 0, 0);
19
+ }
20
+ /**
21
+ * {x, y, z} オブジェクトから生成
22
+ * @param {_Vector3} pos
23
+ * @returns
24
+ */
25
+ static fromBDS(pos) {
26
+ return new Vector3(pos.x, pos.y, pos.z);
27
+ }
28
+ // ===== 基本ゲッター =====
29
+ getX() {
30
+ return this.x;
31
+ }
32
+ getY() {
33
+ return this.y;
34
+ }
35
+ getZ() {
36
+ return this.z;
37
+ }
38
+ getFloorX() {
39
+ return Math.floor(this.x);
40
+ }
41
+ getFloorY() {
42
+ return Math.floor(this.y);
43
+ }
44
+ getFloorZ() {
45
+ return Math.floor(this.z);
46
+ }
47
+ /**
48
+ * 加算
49
+ * @param {number} x
50
+ * @param {number} y
51
+ * @param {number} z
52
+ * @return {Vector3}
53
+ */
54
+ add(x, y, z) {
55
+ return new Vector3(
56
+ this.x + x,
57
+ this.y + y,
58
+ this.z + z
59
+ );
60
+ }
61
+ /**
62
+ * ベクトル単位での加算
63
+ * @param {_Vector3} v
64
+ * @returns {Vector3}
65
+ */
66
+ addVector(v) {
67
+ return this.add(v.x, v.y, v.z);
68
+ }
69
+ /**
70
+ * 減算
71
+ * @param {number} x
72
+ * @param {number} y
73
+ * @param {number} z
74
+ * @return {Vector3}
75
+ */
76
+ subtract(x, y, z) {
77
+ return this.add(-x, -y, -z);
78
+ }
79
+ /**
80
+ * ベクトル単位での減算
81
+ * @param {_Vector3} v
82
+ * @return {Vector3}
83
+ */
84
+ subtractVector(v) {
85
+ return this.add(-v.x, -v.y, -v.z);
86
+ }
87
+ /**
88
+ * 乗算
89
+ * @param {number} value
90
+ * @return {Vector3}
91
+ */
92
+ multiply(value) {
93
+ return new Vector3(
94
+ this.x * value,
95
+ this.y * value,
96
+ this.z * value
97
+ );
98
+ }
99
+ /**
100
+ * 除算
101
+ * @param {number} value
102
+ * @return {Vector3}
103
+ */
104
+ divide(value) {
105
+ return new Vector3(
106
+ this.x / value,
107
+ this.y / value,
108
+ this.z / value
109
+ );
110
+ }
111
+ /**
112
+ * ベクトルの内部数値小数点切り上げ
113
+ * @return {Vector3}
114
+ */
115
+ ceil() {
116
+ return new Vector3(
117
+ Math.ceil(this.x),
118
+ Math.ceil(this.y),
119
+ Math.ceil(this.z)
120
+ );
121
+ }
122
+ /**
123
+ * ベクトルの内部数値小数点切り捨て
124
+ * @return {Vector3}
125
+ */
126
+ floor() {
127
+ return new Vector3(
128
+ Math.floor(this.x),
129
+ Math.floor(this.y),
130
+ Math.floor(this.z)
131
+ );
132
+ }
133
+ /**
134
+ * ベクトルの内部数値小数点四捨五入
135
+ * @param {number} precision
136
+ * @return {Vector3}
137
+ */
138
+ round(precision = 0) {
139
+ const factor = Math.pow(10, precision);
140
+ return new Vector3(
141
+ Math.round(this.x * factor) / factor,
142
+ Math.round(this.y * factor) / factor,
143
+ Math.round(this.z * factor) / factor
144
+ );
145
+ }
146
+ /**
147
+ * ベクトルの内部数値の絶対値
148
+ * @return {Vector3}
149
+ */
150
+ abs() {
151
+ return new Vector3(
152
+ Math.abs(this.x),
153
+ Math.abs(this.y),
154
+ Math.abs(this.z)
155
+ );
156
+ }
157
+ /**
158
+ * 指定した2点間のユークリッド距離
159
+ * @param {_Vector3} pos
160
+ * @return {number}
161
+ */
162
+ distance(pos) {
163
+ return Math.sqrt(this.distanceSquared(pos));
164
+ }
165
+ /**
166
+ * 指定した2点間のユークリッド距離の2乗
167
+ * @param {_Vector3} pos
168
+ * @return {number}
169
+ */
170
+ distanceSquared(pos) {
171
+ const dx = this.x - pos.x;
172
+ const dy = this.y - pos.y;
173
+ const dz = this.z - pos.z;
174
+ return dx * dx + dy * dy + dz * dz;
175
+ }
176
+ /**
177
+ * 内積
178
+ * @param {_Vector3} pos
179
+ * @return {number}
180
+ */
181
+ dot(pos) {
182
+ return this.x * pos.x + this.y * pos.y + this.z * pos.z;
183
+ }
184
+ /**
185
+ * 外積
186
+ * @param {_Vector3} pos
187
+ * @return {Vector3}
188
+ */
189
+ cross(pos) {
190
+ return new Vector3(
191
+ this.y * pos.z - this.z * pos.y,
192
+ this.z * pos.x - this.x * pos.z,
193
+ this.x * pos.y - this.y * pos.x
194
+ );
195
+ }
196
+ /**
197
+ * ベクトルの比較
198
+ * @param {_Vector3} pos
199
+ * @return {boolean}
200
+ */
201
+ equals(pos) {
202
+ return this.x === pos.x && this.y === pos.y && this.z === pos.z;
203
+ }
204
+ /**
205
+ * ベクトルの長さ
206
+ * @return {number}
207
+ */
208
+ length() {
209
+ return Math.sqrt(this.lengthSquared());
210
+ }
211
+ /**
212
+ * ベクトルの長さの2乗
213
+ * @return {number}
214
+ */
215
+ lengthSquared() {
216
+ return this.x * this.x + this.y * this.y + this.z * this.z;
217
+ }
218
+ /**
219
+ * 正規化
220
+ * @return {Vector3}
221
+ */
222
+ normalize() {
223
+ const len = this.length();
224
+ if (len > 0) {
225
+ return this.divide(len);
226
+ }
227
+ return new Vector3(0, 0, 0);
228
+ }
229
+ /**
230
+ * オブジェクトの数値指定再生成
231
+ * @param {number} x
232
+ * @param {number} y
233
+ * @param {number} z
234
+ * @return {Vector3}
235
+ */
236
+ withComponents(x, y, z) {
237
+ return new Vector3(
238
+ x !== void 0 ? x : this.x,
239
+ y !== void 0 ? y : this.y,
240
+ z !== void 0 ? z : this.z
241
+ );
242
+ }
243
+ /**
244
+ * X座標をxValueにしたとき線分上に存在する点を返す
245
+ * @param end 終点
246
+ * @param xValue 途中点のX値
247
+ * @returns {Vector3 | undefined}
248
+ */
249
+ getIntermediateWithXValue(end, xValue) {
250
+ const dx = end.x - this.x;
251
+ if (dx === 0) return;
252
+ const t = (xValue - this.x) / dx;
253
+ if (t < 0 || t > 1) return;
254
+ return new Vector3(
255
+ this.x + dx * t,
256
+ this.y + (end.y - this.y) * t,
257
+ this.z + (end.z - this.z) * t
258
+ );
259
+ }
260
+ /**
261
+ * Y座標をyValueにしたとき線分上に存在する点を返す
262
+ * @param end 終点
263
+ * @param yValue 途中点のY値
264
+ * @returns {Vector3 | undefined}
265
+ */
266
+ getIntermediateWithYValue(end, yValue) {
267
+ const dy = end.y - this.y;
268
+ if (dy === 0) return;
269
+ const t = (yValue - this.y) / dy;
270
+ if (t < 0 || t > 1) return;
271
+ return new Vector3(
272
+ this.x + (end.x - this.x) * t,
273
+ this.y + dy * t,
274
+ this.z + (end.z - this.z) * t
275
+ );
276
+ }
277
+ /**
278
+ * Z座標をzValueにしたとき線分上に存在する点を返す
279
+ * @param end 終点
280
+ * @param zValue 途中点のZ値
281
+ * @returns {Vector3 | undefined}
282
+ */
283
+ getIntermediateWithZValue(end, zValue) {
284
+ const dz = end.z - this.z;
285
+ if (dz === 0) return;
286
+ const t = (zValue - this.z) / dz;
287
+ if (t < 0 || t > 1) return;
288
+ return new Vector3(
289
+ this.x + (end.x - this.x) * t,
290
+ this.y + (end.y - this.y) * t,
291
+ this.z + dz * t
292
+ );
293
+ }
294
+ /**
295
+ * BDS ScriptAPIで使える {x, y, z} 形式に変換
296
+ * @returns {_Vector3}
297
+ */
298
+ toBDS() {
299
+ return { x: this.x, y: this.y, z: this.z };
300
+ }
301
+ /** 通常のオブジェクトに変換 */
302
+ toObject() {
303
+ return { x: this.x, y: this.y, z: this.z };
304
+ }
305
+ toString() {
306
+ return `_Vector3(x=${this.x}, y=${this.y}, z=${this.z})`;
307
+ }
308
+ /**
309
+ * 最大点
310
+ * @param {_Vector3} vector
311
+ * @param {_Vector3[]} vectors
312
+ * @returns {Vector3}
313
+ */
314
+ static maxComponents(vector, ...vectors) {
315
+ let x = vector.x;
316
+ let y = vector.y;
317
+ let z = vector.z;
318
+ for (const pos of vectors) {
319
+ x = Math.max(x, pos.x);
320
+ y = Math.max(y, pos.y);
321
+ z = Math.max(z, pos.z);
322
+ }
323
+ return new Vector3(x, y, z);
324
+ }
325
+ /**
326
+ * 最小点
327
+ * @param {_Vector3} vector
328
+ * @param {_Vector3[]} vectors
329
+ * @returns {Vector3}
330
+ */
331
+ static minComponents(vector, ...vectors) {
332
+ let x = vector.x;
333
+ let y = vector.y;
334
+ let z = vector.z;
335
+ for (const pos of vectors) {
336
+ x = Math.min(x, pos.x);
337
+ y = Math.min(y, pos.y);
338
+ z = Math.min(z, pos.z);
339
+ }
340
+ return new Vector3(x, y, z);
341
+ }
342
+ /**
343
+ * 合計
344
+ * @param {_Vector3[]} vectors
345
+ * @returns {Vector3}
346
+ */
347
+ static sum(...vectors) {
348
+ let x = 0, y = 0, z = 0;
349
+ for (const v of vectors) {
350
+ x += v.x;
351
+ y += v.y;
352
+ z += v.z;
353
+ }
354
+ return new Vector3(x, y, z);
355
+ }
356
+ }
357
+ var Priority = /* @__PURE__ */ ((Priority2) => {
358
+ Priority2[Priority2["LOWEST"] = 5] = "LOWEST";
359
+ Priority2[Priority2["LOW"] = 4] = "LOW";
360
+ Priority2[Priority2["NORMAL"] = 3] = "NORMAL";
361
+ Priority2[Priority2["HIGH"] = 2] = "HIGH";
362
+ Priority2[Priority2["HIGHEST"] = 1] = "HIGHEST";
363
+ Priority2[Priority2["MONITOR"] = 0] = "MONITOR";
364
+ return Priority2;
365
+ })(Priority || {});
366
+ const _EventManager = class _EventManager {
367
+ /** init: world.beforeEvents / world.afterEvents を全自動で subscribe して dispatch に流す */
368
+ static initialize() {
369
+ for (const name in world.afterEvents) {
370
+ world.afterEvents[name].subscribe((ev) => {
371
+ _EventManager.dispatchAfter(name, ev);
372
+ });
373
+ }
374
+ for (const name in world.beforeEvents) {
375
+ world.beforeEvents[name].subscribe((ev) => {
376
+ _EventManager.dispatchBefore(name, ev);
377
+ });
378
+ }
379
+ }
380
+ // ---------- register ----------
381
+ static registerAfter(eventName, listener) {
382
+ if (!this.afterListeners[eventName]) {
383
+ this.afterListeners[eventName] = [];
384
+ }
385
+ const arr = this.afterListeners[eventName];
386
+ arr.push(listener);
387
+ arr.sort((a, b) => (b.priority ?? Priority.NORMAL) - (a.priority ?? Priority.NORMAL));
388
+ }
389
+ static registerBefore(eventName, listener) {
390
+ if (!this.beforeListeners[eventName]) {
391
+ this.beforeListeners[eventName] = [];
392
+ }
393
+ const arr = this.beforeListeners[eventName];
394
+ arr.push(listener);
395
+ arr.sort((a, b) => (b.priority ?? Priority.NORMAL) - (a.priority ?? Priority.NORMAL));
396
+ }
397
+ // ---------- dispatch ----------
398
+ static dispatchAfter(eventName, event) {
399
+ const arr = this.afterListeners[eventName];
400
+ if (!arr) return;
401
+ for (const listener of arr) {
402
+ try {
403
+ listener.handler(event);
404
+ } catch (e) {
405
+ console.error(`[EventManager] after:${String(eventName)} handler threw:`, e);
406
+ }
407
+ }
408
+ }
409
+ static dispatchBefore(eventName, event) {
410
+ const arr = this.beforeListeners[eventName];
411
+ if (!arr) return;
412
+ for (const listener of arr) {
413
+ try {
414
+ listener.handler(event);
415
+ } catch (e) {
416
+ console.error(`[EventManager] before:${String(eventName)} handler threw:`, e);
417
+ }
418
+ }
419
+ }
420
+ // ---------- utility ----------
421
+ /** 登録済みリスナーを全部クリア(Plugin 単位で実装するなら拡張する) */
422
+ static clearAll() {
423
+ this.afterListeners = {};
424
+ this.beforeListeners = {};
425
+ }
426
+ };
427
+ _EventManager.afterListeners = {};
428
+ _EventManager.beforeListeners = {};
429
+ let EventManager = _EventManager;
430
+ const COLOR = {
431
+ reset: "\x1B[0m",
432
+ bold: "\x1B[1m",
433
+ dim: "\x1B[2m",
434
+ red: "\x1B[31m",
435
+ green: "\x1B[32m",
436
+ yellow: "\x1B[33m",
437
+ blue: "\x1B[34m",
438
+ magenta: "\x1B[35m",
439
+ cyan: "\x1B[36m",
440
+ white: "\x1B[37m",
441
+ gray: "\x1B[90m"
442
+ };
443
+ const _VLQDecoder = class _VLQDecoder {
444
+ static decode(str) {
445
+ const result = [];
446
+ let shift = 0;
447
+ let value = 0;
448
+ for (let i = 0; i < str.length; i++) {
449
+ const digit = this.BASE64_CHARS.indexOf(str[i]);
450
+ if (digit === -1) continue;
451
+ const continuation = (digit & 32) !== 0;
452
+ value += (digit & 31) << shift;
453
+ if (continuation) {
454
+ shift += 5;
455
+ } else {
456
+ const negative = (value & 1) !== 0;
457
+ value >>>= 1;
458
+ result.push(negative ? -value : value);
459
+ value = 0;
460
+ shift = 0;
461
+ }
462
+ }
463
+ return result;
464
+ }
465
+ };
466
+ _VLQDecoder.BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
467
+ let VLQDecoder = _VLQDecoder;
468
+ class SourceMapDebugger {
469
+ constructor() {
470
+ this.decodedMappings = [];
471
+ this.initialized = false;
472
+ this.initialize();
473
+ }
474
+ initialize() {
475
+ if (typeof globalThis.__SOURCE_MAP__ !== "undefined") {
476
+ this.sourceMap = globalThis.__SOURCE_MAP__;
477
+ this.decodeMappings();
478
+ this.initialized = true;
479
+ }
480
+ }
481
+ decodeMappings() {
482
+ if (!this.sourceMap?.mappings) return;
483
+ const lines = this.sourceMap.mappings.split(";");
484
+ let generatedLine = 1;
485
+ let prevOriginalLine = 0;
486
+ let prevOriginalColumn = 0;
487
+ let prevSource = 0;
488
+ let prevName = 0;
489
+ for (const line of lines) {
490
+ if (!line) {
491
+ generatedLine++;
492
+ continue;
493
+ }
494
+ const segments = line.split(",");
495
+ let generatedColumn = 0;
496
+ for (const segment of segments) {
497
+ if (!segment) continue;
498
+ const decoded = VLQDecoder.decode(segment);
499
+ if (decoded.length < 1) continue;
500
+ generatedColumn += decoded[0];
501
+ const mapping = {
502
+ generatedLine,
503
+ generatedColumn,
504
+ originalLine: 0,
505
+ originalColumn: 0,
506
+ sourceIndex: 0
507
+ };
508
+ if (decoded.length > 1) {
509
+ prevSource += decoded[1];
510
+ mapping.sourceIndex = prevSource;
511
+ if (decoded.length > 2) {
512
+ prevOriginalLine += decoded[2];
513
+ mapping.originalLine = prevOriginalLine;
514
+ if (decoded.length > 3) {
515
+ prevOriginalColumn += decoded[3];
516
+ mapping.originalColumn = prevOriginalColumn;
517
+ if (decoded.length > 4) {
518
+ prevName += decoded[4];
519
+ mapping.name = this.sourceMap.names?.[prevName];
520
+ }
521
+ }
522
+ }
523
+ }
524
+ this.decodedMappings.push(mapping);
525
+ }
526
+ generatedLine++;
527
+ }
528
+ }
529
+ getOriginalPosition(line, column) {
530
+ if (!this.initialized || this.decodedMappings.length === 0) return null;
531
+ let best = null;
532
+ let bestDistance = Infinity;
533
+ for (const m of this.decodedMappings) {
534
+ if (m.generatedLine === line) {
535
+ const distance = column !== void 0 ? Math.abs(m.generatedColumn - column) : 0;
536
+ if (distance < bestDistance) {
537
+ bestDistance = distance;
538
+ best = m;
539
+ }
540
+ } else if (m.generatedLine < line) {
541
+ if (!best || m.generatedLine > best.generatedLine) best = m;
542
+ }
543
+ }
544
+ if (best && this.sourceMap.sources?.[best.sourceIndex]) {
545
+ return {
546
+ source: this.sourceMap.sources[best.sourceIndex],
547
+ line: best.originalLine,
548
+ column: best.originalColumn,
549
+ content: this.sourceMap.sourcesContent?.[best.sourceIndex],
550
+ name: best.name
551
+ };
552
+ }
553
+ return null;
554
+ }
555
+ debug(...args) {
556
+ try {
557
+ const err = new Error();
558
+ const stack = err.stack || "";
559
+ const stackLines = stack.split("\n");
560
+ const output = [];
561
+ output.push(`${COLOR.yellow}━━━━━━━━━━━━━━━━━━━━━━${COLOR.reset}`);
562
+ output.push(`${COLOR.bold}${COLOR.cyan}📍 DEBUG${COLOR.reset}`);
563
+ let position = null;
564
+ for (let i = 2; i < Math.min(stackLines.length, 8); i++) {
565
+ const line = stackLines[i];
566
+ console.log(JSON.stringify(line));
567
+ const match = /(?:\()?(?:[A-Za-z0-9._/-]+):(\d+)(?::(\d+))?\)?$/.exec(line);
568
+ if (match) {
569
+ const lineNum = parseInt(match[1]);
570
+ const colNum = match[2] ? parseInt(match[2]) : void 0;
571
+ position = this.getOriginalPosition(lineNum, colNum);
572
+ if (position) break;
573
+ }
574
+ }
575
+ if (position) {
576
+ const file = position.source.replace(/^.*\//, "");
577
+ output.push(`${COLOR.blue}📄 ${file}:${position.line}:${position.column}${COLOR.reset}`);
578
+ if (position.name) output.push(`${COLOR.cyan}🏷 ${position.name}${COLOR.reset}`);
579
+ if (position.content) {
580
+ const lines = position.content.split("\n");
581
+ const target = position.line - 1;
582
+ const range = 2;
583
+ output.push(`${COLOR.gray}─────────────────────${COLOR.reset}`);
584
+ for (let i = Math.max(0, target - range); i <= Math.min(lines.length - 1, target + range); i++) {
585
+ const num = `${(i + 1).toString().padStart(3, " ")}`;
586
+ const content = lines[i];
587
+ if (i === target) {
588
+ output.push(`${COLOR.red}${COLOR.bold}→ ${num}: ${COLOR.white}${content}${COLOR.reset}`);
589
+ } else {
590
+ output.push(`${COLOR.gray} ${num}: ${content}${COLOR.reset}`);
591
+ }
592
+ }
593
+ }
594
+ } else {
595
+ output.push(`${COLOR.gray}📍 Location: (source map not available)${COLOR.reset}`);
596
+ }
597
+ output.push(`${COLOR.gray}─────────────────────${COLOR.reset}`);
598
+ output.push(`${COLOR.bold}${COLOR.white}💾 Values:${COLOR.reset}`);
599
+ args.forEach((arg, i) => {
600
+ let val;
601
+ if (arg === void 0) val = "undefined";
602
+ else if (arg === null) val = "null";
603
+ else if (typeof arg === "object") {
604
+ try {
605
+ val = JSON.stringify(arg, null, 2);
606
+ } catch {
607
+ val = "[Circular or Complex Object]";
608
+ }
609
+ } else if (typeof arg === "function") {
610
+ val = `[Function: ${arg.name || "anonymous"}]`;
611
+ } else {
612
+ val = String(arg);
613
+ }
614
+ output.push(`${COLOR.green}[${i}]:${COLOR.reset} ${val}`);
615
+ });
616
+ output.push(`${COLOR.yellow}━━━━━━━━━━━━━━━━━━━━━━${COLOR.reset}`);
617
+ console.log(output.join("\n"));
618
+ } catch (err) {
619
+ console.log(`${COLOR.red}[DEBUG ERROR]${COLOR.reset}`, err);
620
+ console.log(args);
621
+ }
622
+ }
623
+ }
624
+ const debuggerInstance = new SourceMapDebugger();
625
+ function debug(...args) {
626
+ debuggerInstance.debug(...args);
627
+ }
628
+ const _TimerScheduler = class _TimerScheduler {
629
+ /** スケジューラにタスクを登録 */
630
+ static addTask(task) {
631
+ this.tasks.add(task);
632
+ this.ensureStarted();
633
+ }
634
+ /** タスクを削除 */
635
+ static removeTask(task) {
636
+ this.tasks.delete(task);
637
+ }
638
+ /** Interval を開始(1 本だけ) */
639
+ static ensureStarted() {
640
+ if (this.started) return;
641
+ this.started = true;
642
+ system.runInterval(() => {
643
+ this.tick++;
644
+ for (const task of this.tasks) {
645
+ try {
646
+ task();
647
+ } catch (e) {
648
+ console.error("[TimerScheduler] Task error:", e);
649
+ }
650
+ }
651
+ }, 1);
652
+ }
653
+ };
654
+ _TimerScheduler.tasks = /* @__PURE__ */ new Set();
655
+ _TimerScheduler.tick = 0;
656
+ _TimerScheduler.started = false;
657
+ let TimerScheduler = _TimerScheduler;
658
+ class Timer {
659
+ constructor(onRun, onCancel) {
660
+ this.currentTick = 0;
661
+ this.stopped = false;
662
+ this.canceled = false;
663
+ this.forceCanceled = false;
664
+ this.onRun = onRun;
665
+ this.onCancel = onCancel;
666
+ }
667
+ /** 一時停止 */
668
+ stop() {
669
+ this.stopped = true;
670
+ }
671
+ /** 再開 */
672
+ resume() {
673
+ this.stopped = false;
674
+ }
675
+ /** 停止しているか */
676
+ isStopped() {
677
+ return this.stopped;
678
+ }
679
+ /** キャンセル要求 */
680
+ cancel(force = false) {
681
+ if (force) this.forceCanceled = true;
682
+ this.canceled = true;
683
+ }
684
+ /** タイマー内部キャンセル */
685
+ internalCancel(force = false) {
686
+ if (!this.task) return 2;
687
+ TimerScheduler.removeTask(this.task);
688
+ this.onCancel?.();
689
+ return force ? 1 : 0;
690
+ }
691
+ }
692
+ class RepeatingTimer extends Timer {
693
+ constructor(onRun, opts = {}, onCancel) {
694
+ super(onRun, onCancel);
695
+ this.period = opts.period ?? 1;
696
+ this.endless = opts.endless ?? true;
697
+ this.silenceOnStop = opts.silenceOnStop ?? true;
698
+ this.maxElapsedTicks = opts.maxElapsedTicks;
699
+ this.onFinal = opts.onFinal;
700
+ }
701
+ /** タイマー開始 */
702
+ start() {
703
+ this.task = () => {
704
+ if (this.forceCanceled) return this.internalCancel(true);
705
+ if (this.canceled) return this.internalCancel();
706
+ if (!this.endless && this.maxElapsedTicks !== void 0 && this.currentTick >= this.maxElapsedTicks) {
707
+ this.onFinal?.();
708
+ return this.internalCancel();
709
+ }
710
+ if (this.currentTick % this.period === 0) {
711
+ if (!this.stopped || this.stopped && !this.silenceOnStop)
712
+ this.onRun?.(this.currentTick);
713
+ }
714
+ if (!this.stopped) this.currentTick++;
715
+ };
716
+ TimerScheduler.addTask(this.task);
717
+ }
718
+ }
719
+ class DelayedTimer extends Timer {
720
+ constructor(onRun, opts = {}, onCancel) {
721
+ super(onRun, onCancel);
722
+ this.delay = opts.delay ?? 1;
723
+ }
724
+ start() {
725
+ this.task = () => {
726
+ if (this.forceCanceled) return this.internalCancel(true);
727
+ if (this.canceled) return this.internalCancel();
728
+ if (this.currentTick >= this.delay) {
729
+ this.onRun?.(this.currentTick);
730
+ return this.internalCancel();
731
+ }
732
+ this.currentTick++;
733
+ };
734
+ TimerScheduler.addTask(this.task);
735
+ }
736
+ }
737
+ function repeating(opts) {
738
+ const options = {
739
+ period: opts.every,
740
+ endless: opts.endless,
741
+ silenceOnStop: opts.silenceWhenStopped,
742
+ maxElapsedTicks: opts.max,
743
+ onFinal: opts.final
744
+ };
745
+ const t = new RepeatingTimer(opts.run, options, opts.cancel);
746
+ t.start();
747
+ return t;
748
+ }
749
+ function delayed(ticks, run, cancel) {
750
+ const t = new DelayedTimer(() => run(), { delay: ticks }, cancel);
751
+ t.start();
752
+ return t;
753
+ }
754
+ function sleep(tick) {
755
+ return new Promise((resolve) => {
756
+ new DelayedTimer(() => resolve(), { delay: tick }).start();
757
+ });
758
+ }
759
+ export {
760
+ DelayedTimer,
761
+ EventManager,
762
+ Priority,
763
+ RepeatingTimer,
764
+ Vector3,
765
+ debug,
766
+ delayed,
767
+ keystone,
768
+ repeating,
769
+ sleep
770
+ };
@@ -0,0 +1,11 @@
1
+ import { Plugin } from 'vite';
2
+ type PluginConfig = {
3
+ name: string;
4
+ uuid?: string;
5
+ description?: string;
6
+ authors?: string[];
7
+ version?: number[];
8
+ embedSourceMap?: boolean;
9
+ };
10
+ declare const behaviorPacker: ({ name, uuid, description, authors, version, embedSourceMap, }?: PluginConfig) => Plugin;
11
+ export default behaviorPacker;
@@ -0,0 +1,120 @@
1
+ import { resolve } from "path";
2
+ import * as crypto from "node:crypto";
3
+ import * as fs from "node:fs";
4
+ const behaviorPacker = ({
5
+ name = "my first plugin",
6
+ uuid,
7
+ description = "",
8
+ authors = [],
9
+ version = [1, 0, 0],
10
+ embedSourceMap = true
11
+ } = {
12
+ name: "my first plugin",
13
+ description: "",
14
+ authors: [],
15
+ version: [1, 0, 0],
16
+ embedSourceMap: true
17
+ }) => ({
18
+ name: "BehaviorPacker",
19
+ config: (config) => {
20
+ return {
21
+ ...config,
22
+ build: {
23
+ sourcemap: true,
24
+ minify: false,
25
+ outDir: "./dist_behavior_pack/scripts",
26
+ emptyOutDir: true,
27
+ assetsDir: "",
28
+ rollupOptions: {
29
+ external: [
30
+ "@minecraft/server",
31
+ "@minecraft/server-net",
32
+ "@minecraft/server-ui"
33
+ ],
34
+ input: {
35
+ index: resolve(process.cwd(), "./src/index.ts")
36
+ }
37
+ }
38
+ }
39
+ };
40
+ },
41
+ generateBundle(options, bundle) {
42
+ if (!embedSourceMap) return;
43
+ for (const [fileName, file] of Object.entries(bundle)) {
44
+ if (file.type === "chunk" && file.map) {
45
+ const sourceMapData = file.map;
46
+ const embeddedSourceMap = {
47
+ version: sourceMapData.version,
48
+ sources: sourceMapData.sources,
49
+ sourcesContent: sourceMapData.sourcesContent,
50
+ mappings: sourceMapData.mappings,
51
+ names: sourceMapData.names
52
+ };
53
+ const sourceMapEmbed = `// ========== Embedded Source Map ==========
54
+ globalThis.__SOURCE_MAP__ = ${JSON.stringify(embeddedSourceMap)};
55
+ // ========== End of Embedded Source Map ==========
56
+
57
+ `;
58
+ const originalCode = file.code;
59
+ const modifiedCode = sourceMapEmbed + originalCode;
60
+ file.code = modifiedCode.replace(/\/\/# sourceMappingURL=.+$/gm, "");
61
+ file.map = null;
62
+ }
63
+ }
64
+ for (const fileName in bundle) {
65
+ if (fileName.endsWith(".map")) {
66
+ delete bundle[fileName];
67
+ }
68
+ }
69
+ },
70
+ writeBundle: async (_options, bundle) => {
71
+ const entryFile = Object.values(bundle).find(
72
+ (file) => file.type === "chunk" && file.isEntry
73
+ );
74
+ if (!entryFile || entryFile.type !== "chunk") {
75
+ throw new Error("No entry file found");
76
+ }
77
+ const behaviorUUID = uuid ?? crypto.randomUUID();
78
+ const manifestStub = {
79
+ "format_version": 2,
80
+ "header": {
81
+ "name": name,
82
+ "description": description,
83
+ "uuid": behaviorUUID,
84
+ "version": version,
85
+ "min_engine_version": [1, 21, 120]
86
+ },
87
+ "modules": [
88
+ {
89
+ "description": "script",
90
+ "type": "script",
91
+ "language": "javascript",
92
+ "uuid": crypto.randomUUID(),
93
+ "version": [1, 0, 0],
94
+ "entry": `scripts/${entryFile.fileName}`
95
+ }
96
+ ],
97
+ "dependencies": [
98
+ {
99
+ "module_name": "@minecraft/server",
100
+ "version": "beta"
101
+ },
102
+ {
103
+ "module_name": "@minecraft/server-ui",
104
+ "version": "beta"
105
+ },
106
+ {
107
+ "module_name": "@minecraft/server-net",
108
+ "version": "beta"
109
+ }
110
+ ],
111
+ "metadata": {
112
+ "authors": authors
113
+ }
114
+ };
115
+ fs.writeFileSync("./dist_behavior_pack/manifest.json", JSON.stringify(manifestStub, null, 2));
116
+ }
117
+ });
118
+ export {
119
+ behaviorPacker as default
120
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keystonemc",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "ScriptAPI Wrapper",
5
5
  "type": "module",
6
6
  "scripts": {