@block_factory/lib 0.0.6 → 0.0.8

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 (72) hide show
  1. package/_module/BlockFactory.ts +10 -19
  2. package/_module/util/Command.ts +1 -9
  3. package/_module/util/Forms/Form.ts +5 -31
  4. package/_module/util/Forms/FormAction.ts +2 -1
  5. package/_module/util/Forms/FormMessage.ts +2 -1
  6. package/_module/util/Forms/FormModal.ts +9 -10
  7. package/_module/util/Forms/FormRegistry.ts +20 -23
  8. package/_module/util/Forms/IForm.ts +31 -0
  9. package/_module/util/Globals.ts +26 -0
  10. package/_module/util/ISystem.ts +58 -0
  11. package/_module/util/IVector.ts +420 -0
  12. package/_module/util/Math.ts +2 -0
  13. package/_module/util/Navigation.ts +130 -0
  14. package/_module/util/TempLeaker.ts +137 -0
  15. package/_module/util/Wrapper/IEntity.ts +93 -25
  16. package/_module/util/Wrapper/IItemStack.ts +63 -0
  17. package/_module/util/Wrapper/IPlayer.ts +73 -29
  18. package/_module/util/Wrapper/_Common.ts +130 -0
  19. package/_module/util/Wrapper/{Container.ts → _Container.ts} +5 -5
  20. package/index.js +3932 -795
  21. package/package.json +9 -5
  22. package/_module/DataTypes.ts +0 -10
  23. package/_module/Framework/EntityTasks.ts +0 -164
  24. package/_module/Framework/ItemTasks.ts +0 -157
  25. package/_module/Framework/PlayerTasks.ts +0 -125
  26. package/_module/Framework/Threads.ts +0 -72
  27. package/_module/util/System.ts +0 -21
  28. package/_module/util/Vector.ts +0 -388
  29. package/_types/_module/BlockFactory.d.ts +0 -19
  30. package/_types/_module/BlockFactory.d.ts.map +0 -1
  31. package/_types/_module/DataTypes.d.ts +0 -10
  32. package/_types/_module/DataTypes.d.ts.map +0 -1
  33. package/_types/_module/Framework/EntityTasks.d.ts +0 -37
  34. package/_types/_module/Framework/EntityTasks.d.ts.map +0 -1
  35. package/_types/_module/Framework/ItemTasks.d.ts +0 -59
  36. package/_types/_module/Framework/ItemTasks.d.ts.map +0 -1
  37. package/_types/_module/Framework/PlayerTasks.d.ts +0 -28
  38. package/_types/_module/Framework/PlayerTasks.d.ts.map +0 -1
  39. package/_types/_module/Framework/Threads.d.ts +0 -22
  40. package/_types/_module/Framework/Threads.d.ts.map +0 -1
  41. package/_types/_module/Types.d.ts +0 -10
  42. package/_types/_module/Types.d.ts.map +0 -1
  43. package/_types/_module/util/Command.d.ts +0 -92
  44. package/_types/_module/util/Command.d.ts.map +0 -1
  45. package/_types/_module/util/Forms/Form.d.ts +0 -12
  46. package/_types/_module/util/Forms/Form.d.ts.map +0 -1
  47. package/_types/_module/util/Forms/FormAction.d.ts +0 -73
  48. package/_types/_module/util/Forms/FormAction.d.ts.map +0 -1
  49. package/_types/_module/util/Forms/FormMessage.d.ts +0 -24
  50. package/_types/_module/util/Forms/FormMessage.d.ts.map +0 -1
  51. package/_types/_module/util/Forms/FormModal.d.ts +0 -66
  52. package/_types/_module/util/Forms/FormModal.d.ts.map +0 -1
  53. package/_types/_module/util/Forms/FormRegistry.d.ts +0 -12
  54. package/_types/_module/util/Forms/FormRegistry.d.ts.map +0 -1
  55. package/_types/_module/util/Math.d.ts +0 -20
  56. package/_types/_module/util/Math.d.ts.map +0 -1
  57. package/_types/_module/util/RawText.d.ts +0 -60
  58. package/_types/_module/util/RawText.d.ts.map +0 -1
  59. package/_types/_module/util/Signal.d.ts +0 -70
  60. package/_types/_module/util/Signal.d.ts.map +0 -1
  61. package/_types/_module/util/System.d.ts +0 -4
  62. package/_types/_module/util/System.d.ts.map +0 -1
  63. package/_types/_module/util/Vector.d.ts +0 -212
  64. package/_types/_module/util/Vector.d.ts.map +0 -1
  65. package/_types/_module/util/Wrapper/Container.d.ts +0 -9
  66. package/_types/_module/util/Wrapper/Container.d.ts.map +0 -1
  67. package/_types/_module/util/Wrapper/IEntity.d.ts +0 -12
  68. package/_types/_module/util/Wrapper/IEntity.d.ts.map +0 -1
  69. package/_types/_module/util/Wrapper/IPlayer.d.ts +0 -13
  70. package/_types/_module/util/Wrapper/IPlayer.d.ts.map +0 -1
  71. package/_types/index.d.ts +0 -3
  72. package/_types/index.d.ts.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@block_factory/lib",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "main": "index.js",
5
5
  "types": "index.d.ts",
6
6
  "description": "Typescript Library for Minecraft Bedrock Edition",
@@ -21,16 +21,20 @@
21
21
  },
22
22
  "homepage": "https://github.com/Block-Factory-Studio/bf-mcbr-library#readme",
23
23
  "dependencies": {
24
- "@minecraft/server": "^2.4.0",
24
+ "@minecraft/server": "^2.5.0",
25
25
  "@minecraft/server-ui": "^2.0.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "esbuild": "^0.25.9",
29
- "typedoc": "^0.28.16",
30
- "typedoc-plugin-markdown": "^4.9.0"
29
+ "typedoc": "^0.28.17",
30
+ "typedoc-plugin-markdown": "^4.10.0"
31
+ },
32
+ "overrides": {
33
+ "minimatch": "^10.2.1"
31
34
  },
32
35
  "scripts": {
33
36
  "build": "node esbuild.config.mjs",
34
- "build:types": "tsc -p tsconfig.types.json"
37
+ "build:types": "tsc -p tsconfig.types.json",
38
+ "build:docs": "typedoc --options typedoc.json"
35
39
  }
36
40
  }
@@ -1,10 +0,0 @@
1
- export type Sound = {
2
- id: string,
3
- length: number
4
- }
5
-
6
- export type Animation = {
7
- id: string,
8
- length: number,
9
- loop?: boolean,
10
- }
@@ -1,164 +0,0 @@
1
- import { Entity, system, ScriptEventCommandMessageAfterEvent, ScriptEventCommandMessageAfterEventSignal, world, WorldLoadAfterEventSignal, WorldLoadAfterEvent, EntitySpawnAfterEventSignal, EntitySpawnAfterEvent, EntityRemoveBeforeEvent, EntityRemoveBeforeEventSignal } from "@minecraft/server";
2
-
3
- import { Signal } from "../util/Signal";
4
- import { IEntityWrapper, IEntity } from "../util/Wrapper/IEntity";
5
-
6
- export type EntityEmissionEvent = {
7
- iEntity: IEntity;
8
- parms: any;
9
- };
10
-
11
- class SingletonEntityHandler {
12
- private PACK_ID: string | undefined;
13
-
14
- public readonly onEntityEmission = new Signal<EntityEmissionEvent>();
15
- private readonly GLOBAL_MEMORY_ID = "GLB_MEM.ENTITY";
16
-
17
- private readonly scriptEventSignal: ScriptEventCommandMessageAfterEventSignal = system.afterEvents.scriptEventReceive;
18
- private readonly loadEventSignal: WorldLoadAfterEventSignal = world.afterEvents.worldLoad;
19
- private readonly spawnEventSignal: EntitySpawnAfterEventSignal = world.afterEvents.entitySpawn;
20
- private readonly removeBeforeEventSignal: EntityRemoveBeforeEventSignal = world.beforeEvents.entityRemove;
21
-
22
- private readonly EM_INDEX = new Map<string, Entity>();
23
- private readonly EM_KEYS: string[] = [];
24
- private readonly SEARCH_TYPES = new Set<string>();
25
-
26
- private _started: boolean = false;
27
- private _wired: boolean = false;
28
-
29
- public registerEntity(typeId: string | string[]): void {
30
- if (Array.isArray(typeId)) typeId.forEach((t) => this.SEARCH_TYPES.add(t));
31
- else this.SEARCH_TYPES.add(typeId);
32
- }
33
-
34
- public start(packId: string): void {
35
- if (this._started) throw new Error("BFLIB: EntityHandler already started;");
36
- this._started = true;
37
- this.PACK_ID = packId;
38
- this.loadEventSignal.subscribe(this.onWorldLoad);
39
- }
40
-
41
- public stop(): void {
42
- if (!this._started) return;
43
-
44
- this.loadEventSignal.unsubscribe(this.onWorldLoad);
45
- if (this._wired) {
46
- this.scriptEventSignal.unsubscribe(this.processScriptEvents);
47
- this.spawnEventSignal.unsubscribe(this.onEntitySpawned);
48
- this.removeBeforeEventSignal.unsubscribe(this.onEntityRemovedBefore);
49
- this._wired = false;
50
- }
51
-
52
- this._started = false;
53
- }
54
-
55
- /* ------------------------------------------------------------------------ */
56
- /* Event Wiring */
57
- /* ------------------------------------------------------------------------ */
58
-
59
- private onWorldLoad = (): void => {
60
- this.scriptEventSignal.subscribe(this.processScriptEvents);
61
-
62
- if (this.SEARCH_TYPES.size > 0) {
63
- this.spawnEventSignal.subscribe(this.onEntitySpawned);
64
- this.removeBeforeEventSignal.subscribe(this.onEntityRemovedBefore);
65
- }
66
-
67
- this._wired = true;
68
- this.reloadEntityMemory();
69
- this.loadEventSignal.unsubscribe(this.onWorldLoad);
70
- };
71
-
72
- private processScriptEvents = (event: ScriptEventCommandMessageAfterEvent): void => {
73
- if (!event.sourceEntity) return;
74
- if (event.id !== `${this.PACK_ID}:entity_emitter`) return;
75
-
76
- let parms: any;
77
- try {
78
- parms = JSON.parse(event.message);
79
- } catch (e) {
80
- console.error(`BFLIB: entity_emitter JSON parse failed:`, e);
81
- return;
82
- }
83
-
84
- this.onEntityEmission.emit({ iEntity: IEntityWrapper.wrap(event.sourceEntity), parms });
85
- };
86
-
87
- /* ------------------------------------------------------------------------ */
88
- /* Filters */
89
- /* ------------------------------------------------------------------------ */
90
-
91
- private isValidType(typeId: string): boolean {
92
- if (this.PACK_ID && !typeId.startsWith(this.PACK_ID)) return false;
93
- return this.SEARCH_TYPES.has(typeId);
94
- }
95
-
96
- private onEntitySpawned = (event: EntitySpawnAfterEvent): void => {
97
- const entity = event.entity;
98
- if (!this.isValidType(entity.typeId)) return;
99
- this.saveEntityInMemory(entity);
100
- };
101
-
102
- private onEntityRemovedBefore = (event: EntityRemoveBeforeEvent): void => {
103
- const entity = event.removedEntity;
104
- if (!this.isValidType(entity.typeId)) return;
105
- this.deleteEntityInMemory(entity);
106
- };
107
-
108
- /* ------------------------------------------------------------------------ */
109
- /* Persistence */
110
- /* ------------------------------------------------------------------------ */
111
-
112
- private reloadEntityMemory(): void {
113
- this.EM_INDEX.clear();
114
- this.EM_KEYS.length = 0;
115
-
116
- const raw = world.getDynamicProperty(this.GLOBAL_MEMORY_ID) as string | undefined;
117
- if (!raw) return;
118
-
119
- let parsed: string[];
120
- try {
121
- parsed = JSON.parse(raw) as string[];
122
- } catch (e) {
123
- console.error(`BFLIB: Failed to parse ${this.GLOBAL_MEMORY_ID}:`, e);
124
- return;
125
- }
126
-
127
- for (const id of parsed) {
128
- this.EM_KEYS.push(id);
129
- const entity = world.getEntity(id);
130
- if (entity) this.EM_INDEX.set(entity.id, entity);
131
- }
132
- }
133
-
134
- private persistKeys(): void {
135
- world.setDynamicProperty(this.GLOBAL_MEMORY_ID, JSON.stringify(this.EM_KEYS));
136
- }
137
-
138
- public saveEntityInMemory(entity: Entity): boolean {
139
- if (this.EM_INDEX.has(entity.id)) return false;
140
- this.EM_KEYS.push(entity.id);
141
- this.EM_INDEX.set(entity.id, entity);
142
- this.persistKeys();
143
-
144
- return true;
145
- }
146
-
147
- public deleteEntityInMemory(entity: Entity): boolean {
148
- const existed = this.EM_INDEX.delete(entity.id);
149
- if (!existed) return false;
150
-
151
- const idx = this.EM_KEYS.indexOf(entity.id);
152
- if (idx !== -1) this.EM_KEYS.splice(idx, 1);
153
-
154
- this.persistKeys();
155
-
156
- return true;
157
- }
158
-
159
- public getEntitiesInMemory(): Entity[] {
160
- return Array.from(this.EM_INDEX.values());
161
- }
162
- }
163
-
164
- export const EntityHandler = new SingletonEntityHandler();
@@ -1,157 +0,0 @@
1
- import { Signal } from "../util/Signal.js";
2
- import { ItemCompleteUseAfterEvent, ItemCompleteUseAfterEventSignal, ItemReleaseUseAfterEvent, ItemReleaseUseAfterEventSignal, ItemStack, ItemStartUseAfterEvent, ItemStartUseAfterEventSignal, ItemStartUseOnAfterEvent, ItemStartUseOnAfterEventSignal, ItemStopUseAfterEvent, ItemStopUseAfterEventSignal, ItemStopUseOnAfterEvent, ItemStopUseOnAfterEventSignal, ItemUseAfterEvent, ItemUseAfterEventSignal, ItemUseBeforeEvent, ItemUseBeforeEventSignal, Player, PlayerHotbarSelectedSlotChangeAfterEvent, PlayerHotbarSelectedSlotChangeAfterEventSignal, PlayerInventoryItemChangeAfterEvent, PlayerInventoryItemChangeAfterEventSignal, system, world, WorldLoadAfterEvent, WorldLoadAfterEventSignal } from "@minecraft/server";
3
-
4
- export type ItemRegistration = {
5
- typeId: string;
6
- emitWhileHolding?: boolean
7
- emitOnUse?: boolean;
8
- }
9
-
10
- export type WhileHoldingItemEvent = { player: Player; itemStack: ItemStack };
11
- export type OnItemHeldEvent = { player: Player; itemStack: ItemStack };
12
- export type OnItemUnheldEvent = { player: Player; itemStack: ItemStack | undefined };
13
- export type OnItemUsedEvent = { player: Player; itemStack: ItemStack };
14
-
15
- interface HoldData {
16
- instanceId: number;
17
- itemStack: ItemStack;
18
- }
19
-
20
- class SingletonItemHandler {
21
- private PACK_ID: string | undefined;
22
-
23
- public readonly whileHoldingItemEvent = new Signal<WhileHoldingItemEvent>();
24
- public readonly onItemHeldEvent = new Signal<OnItemHeldEvent>();
25
- public readonly onItemUnheldEvent = new Signal<OnItemUnheldEvent>();
26
- public readonly onItemUsedEvent = new Signal<OnItemUsedEvent>();
27
-
28
- private readonly loadEventSignal: WorldLoadAfterEventSignal = world.afterEvents.worldLoad;
29
- private readonly useBeforeSignal: ItemUseBeforeEventSignal = world.beforeEvents.itemUse;
30
- private readonly useAfterSignal: ItemUseAfterEventSignal = world.afterEvents.itemUse;
31
- private readonly completeUseSignal: ItemCompleteUseAfterEventSignal = world.afterEvents.itemCompleteUse;
32
- private readonly releaseUseSignal: ItemReleaseUseAfterEventSignal = world.afterEvents.itemReleaseUse;
33
- private readonly startUseSignal: ItemStartUseAfterEventSignal = world.afterEvents.itemStartUse;
34
- private readonly startUseOnSignal: ItemStartUseOnAfterEventSignal = world.afterEvents.itemStartUseOn;
35
- private readonly stopUseSignal: ItemStopUseAfterEventSignal = world.afterEvents.itemStopUse;
36
- private readonly stopUseOnSignal: ItemStopUseOnAfterEventSignal = world.afterEvents.itemStopUseOn;
37
- private readonly inventoryItemChangeSignal: PlayerInventoryItemChangeAfterEventSignal = world.afterEvents.playerInventoryItemChange;
38
- private readonly hotbarChangeSignal: PlayerHotbarSelectedSlotChangeAfterEventSignal = world.afterEvents.playerHotbarSelectedSlotChange;
39
-
40
- private readonly IM_INDEX = new Map<string, ItemRegistration>();
41
- private readonly HOLD_INDEX: Map<string, HoldData> = new Map<string, HoldData>();
42
-
43
- private _started = false;
44
- private _wired = false;
45
-
46
- public registerItem(itemRegistration: ItemRegistration | ItemRegistration[]): void {
47
- if (Array.isArray(itemRegistration)) itemRegistration.forEach(i => this.IM_INDEX.set(i.typeId, i));
48
- else this.IM_INDEX.set(itemRegistration.typeId, itemRegistration);
49
- }
50
-
51
- public start(packId: string): void {
52
- if (this._started) throw new Error("BFLIB: ItemHandler already started;");
53
- this._started = true;
54
- this.PACK_ID = packId;
55
- this.loadEventSignal.subscribe(this.onWorldLoad);
56
- }
57
-
58
- public stop(): void {
59
- if (!this._started) return;
60
-
61
- this.loadEventSignal.unsubscribe(this.onWorldLoad);
62
-
63
- if (this._wired) {
64
- this.useBeforeSignal.unsubscribe(this.onUseBefore);
65
- this.useAfterSignal.unsubscribe(this.onUseAfter);
66
- this.completeUseSignal.unsubscribe(this.onCompleteUse);
67
- this.releaseUseSignal.unsubscribe(this.onReleaseUse);
68
- this.startUseSignal.unsubscribe(this.onStartUse);
69
- this.startUseOnSignal.unsubscribe(this.onStartUseOn);
70
- this.stopUseSignal.unsubscribe(this.onStopUse);
71
- this.stopUseOnSignal.unsubscribe(this.onStopUseOn);
72
- this.hotbarChangeSignal.unsubscribe(this.onHotbarChange);
73
- this.inventoryItemChangeSignal.unsubscribe(this.onInventoryItemChange);
74
-
75
- this._wired = false;
76
- }
77
-
78
- this._started = false;
79
- }
80
-
81
-
82
- private onWorldLoad = (): void => {
83
- if (this.IM_INDEX.size > 0) {
84
- this.useBeforeSignal.subscribe(this.onUseBefore);
85
- this.useAfterSignal.subscribe(this.onUseAfter);
86
- this.completeUseSignal.subscribe(this.onCompleteUse);
87
- this.releaseUseSignal.subscribe(this.onReleaseUse);
88
- this.startUseSignal.subscribe(this.onStartUse);
89
- this.startUseOnSignal.subscribe(this.onStartUseOn);
90
- this.stopUseSignal.subscribe(this.onStopUse);
91
- this.stopUseOnSignal.subscribe(this.onStopUseOn);
92
- this.hotbarChangeSignal.subscribe(this.onHotbarChange);
93
- this.inventoryItemChangeSignal.subscribe(this.onInventoryItemChange);
94
-
95
- this._wired = true;
96
- }
97
-
98
- this.loadEventSignal.unsubscribe(this.onWorldLoad);
99
- };
100
-
101
-
102
- private onUseBefore = (event: ItemUseBeforeEvent): void => {
103
- const itemStack: ItemStack = event.itemStack;
104
- if (!this.isValidType(itemStack.typeId)) return;
105
- const i: ItemRegistration | undefined = this.IM_INDEX.get(itemStack.typeId);
106
- if (!i || !i.emitOnUse) return;
107
- const runId: number = system.run(() => {
108
- try { this.onItemUsedEvent.emit({ player: event.source, itemStack: event.itemStack }) }
109
- catch (error) { throw new Error(`${error}`) }
110
- finally { system.clearRun(runId) }
111
- })
112
-
113
- };
114
- private onUseAfter = (_event: ItemUseAfterEvent): void => { };
115
- private onCompleteUse = (_event: ItemCompleteUseAfterEvent): void => { };
116
- private onReleaseUse = (_event: ItemReleaseUseAfterEvent): void => { };
117
- private onStartUse = (_event: ItemStartUseAfterEvent): void => { };
118
- private onStartUseOn = (_event: ItemStartUseOnAfterEvent): void => { };
119
- private onStopUse = (_event: ItemStopUseAfterEvent): void => { };
120
- private onStopUseOn = (_event: ItemStopUseOnAfterEvent): void => { };
121
- private onInventoryItemChange = (_event: PlayerInventoryItemChangeAfterEvent): void => { };
122
-
123
- private onHotbarChange = (event: PlayerHotbarSelectedSlotChangeAfterEvent): void => {
124
- const itemStack: ItemStack | undefined = event.itemStack;
125
- if (this.HOLD_INDEX.has(event.player.id)) this.releaseHold(event.player);
126
- if (!itemStack || (itemStack && !this.isValidType(itemStack.typeId))) return;
127
- this.setNewHold(itemStack, event.player);
128
- };
129
-
130
- private setNewHold(itemStack: ItemStack, player: Player) {
131
- this.onItemHeldEvent.emit({ player: player, itemStack: itemStack });
132
-
133
- const i: ItemRegistration | undefined = this.IM_INDEX.get(itemStack.typeId);
134
- let instanceId: number = -1
135
- if (i && i.emitWhileHolding) {
136
- instanceId = system.runInterval(() => {
137
- this.whileHoldingItemEvent.emit({ player: player, itemStack: itemStack });
138
- })
139
- }
140
- this.HOLD_INDEX.set(player.id, { instanceId: instanceId, itemStack: itemStack });
141
- }
142
-
143
- private releaseHold(player: Player) {
144
- const holdData: HoldData | undefined = this.HOLD_INDEX.get(player.id);
145
- if (!holdData) return;
146
- this.onItemUnheldEvent.emit({ player: player, itemStack: holdData.itemStack });
147
- if (holdData.instanceId !== -1) system.clearRun(holdData.instanceId);
148
- this.HOLD_INDEX.delete(player.id);
149
- }
150
-
151
- private isValidType(typeId: string): boolean {
152
- if (this.PACK_ID && !typeId.startsWith(this.PACK_ID)) return false;
153
- return this.IM_INDEX.has(typeId);
154
- }
155
- }
156
-
157
- export const ItemHandler = new SingletonItemHandler();
@@ -1,125 +0,0 @@
1
- import { IPlayerWrapper, IPlayer } from "../util/Wrapper/IPlayer";
2
- import { ButtonState, InputButton, Player, PlayerButtonInputAfterEvent, PlayerButtonInputAfterEventSignal, PlayerLeaveBeforeEvent, PlayerLeaveBeforeEventSignal, PlayerSpawnAfterEvent, PlayerSpawnAfterEventSignal, world, WorldLoadAfterEvent, WorldLoadAfterEventSignal } from "@minecraft/server";
3
-
4
- class SingletonPlayerHandler {
5
- private readonly GLOBAL_MEMORY_ID = "GLB_MEM.PLAYER";
6
-
7
- private readonly loadEventSignal: WorldLoadAfterEventSignal = world.afterEvents.worldLoad;
8
- private readonly playerSpawnSignal: PlayerSpawnAfterEventSignal = world.afterEvents.playerSpawn;
9
- private readonly playerLeaveBeforeSignal: PlayerLeaveBeforeEventSignal = world.beforeEvents.playerLeave;
10
- private readonly buttonInputSignal: PlayerButtonInputAfterEventSignal = world.afterEvents.playerButtonInput;
11
-
12
- private readonly PR_INDEX = new Map<string, Player>();
13
- private readonly PR_KEYS: string[] = [];
14
-
15
- private _started: boolean = false;
16
- private _wired: boolean = false;
17
-
18
- public start(): void {
19
- if (this._started) throw new Error("BFLIB: PlayerHandler already started;");
20
- this._started = true;
21
- this.onSystemLoad();
22
- this.loadEventSignal.subscribe(this.onWorldLoad);
23
- this.buttonInputSignal.subscribe(this.onButtonPress);
24
- }
25
-
26
- public stop(): void {
27
- if (!this._started) return;
28
- if (this._wired) {
29
- this.playerSpawnSignal.unsubscribe(this.onPlayerSpawned);
30
- this.playerLeaveBeforeSignal.unsubscribe(this.onPlayerLeaveBefore);
31
- this.buttonInputSignal.unsubscribe(this.onButtonPress);
32
- this._wired = false;
33
- }
34
- this._started = false;
35
- }
36
-
37
- private onWorldLoad = (): void => {
38
- this.reloadPlayerMemory();
39
- this.loadEventSignal.unsubscribe(this.onWorldLoad);
40
- };
41
-
42
- private onSystemLoad(): void {
43
- this.playerSpawnSignal.subscribe(this.onPlayerSpawned);
44
- this.playerLeaveBeforeSignal.subscribe(this.onPlayerLeaveBefore);
45
- this._wired = true;
46
- }
47
-
48
- private onPlayerSpawned = (event: PlayerSpawnAfterEvent): void => {
49
- if (!event) return;
50
- if (this.hasPlayer(event.player.id)) return;
51
- this.savePlayerInMemory(event.player);
52
- };
53
-
54
- private onPlayerLeaveBefore = (event: PlayerLeaveBeforeEvent): void => {
55
- if (!this.hasPlayer(event.player.id)) return;
56
- this.deletePlayerInMemory(event.player);
57
- };
58
-
59
- private onButtonPress = (event: PlayerButtonInputAfterEvent): void => {
60
- if (event.button === InputButton.Jump) {
61
-
62
- }
63
- else if (event.button === InputButton.Sneak) {
64
-
65
- }
66
- console.warn(`Player ${event.player.name} pressed button ${InputButton[event.button]}: ${ButtonState[event.newButtonState]}`);
67
- };
68
-
69
- public hasPlayer(playerId: string): boolean {
70
- return this.PR_INDEX.has(playerId);
71
- }
72
-
73
- /* ------------------------------------------------------------------------ */
74
- /* Persistence */
75
- /* ------------------------------------------------------------------------ */
76
-
77
- private reloadPlayerMemory(): void {
78
- this.PR_INDEX.clear();
79
- this.PR_KEYS.length = 0;
80
-
81
- const players: Player[] = world.getAllPlayers();
82
- for (const player of players) {
83
- this.PR_INDEX.set(player.id, player);
84
- this.PR_KEYS.push(player.id);
85
- }
86
- }
87
-
88
-
89
-
90
- private persistKeys(): void {
91
- world.setDynamicProperty(this.GLOBAL_MEMORY_ID, JSON.stringify(this.PR_KEYS));
92
- }
93
-
94
- public savePlayerInMemory(player: Player): boolean {
95
- if (this.PR_INDEX.has(player.id)) return false;
96
- this.PR_KEYS.push(player.id);
97
- this.PR_INDEX.set(player.id, player);
98
- this.persistKeys();
99
-
100
- return true;
101
- }
102
-
103
- public deletePlayerInMemory(player: Player): boolean {
104
- const existed = this.PR_INDEX.delete(player.id);
105
- if (!existed) return false;
106
-
107
- const idx = this.PR_KEYS.indexOf(player.id);
108
- if (idx !== -1) this.PR_KEYS.splice(idx, 1);
109
-
110
- this.persistKeys();
111
-
112
- return true;
113
- }
114
-
115
- public getPlayersInMemory(): Player[] {
116
- return Array.from(this.PR_INDEX.values());
117
- }
118
-
119
- public getIPlayersInMemory(): IPlayer[] {
120
- return Array.from(this.PR_INDEX.values())
121
- .map(player => IPlayerWrapper.wrap(player));
122
- }
123
- }
124
-
125
- export const PlayerHandler = new SingletonPlayerHandler();
@@ -1,72 +0,0 @@
1
- import { system, TicksPerSecond } from "@minecraft/server";
2
- import { Signal } from "../util/Signal";
3
-
4
- export type ThreadConfig = {
5
- mainRate?: number; // interval ticks
6
- lateRate?: number; // interval ticks
7
- };
8
-
9
- class SingletonThreadManager {
10
- public readonly MAIN = new Signal<number>();
11
- public readonly LATE = new Signal<void>();
12
-
13
- private _mainRate = 0;
14
- private _lateRate = TicksPerSecond;
15
-
16
- private _MAIN_ID: number | undefined;
17
- private _LATE_ID: number | undefined;
18
-
19
- private _delta = this.createDeltaTimer();
20
- private _started = false;
21
-
22
- public configure(cfg: ThreadConfig) {
23
- if (this._started) throw new Error("BFLIB: _THREAD_ already started; configure before start().");
24
- if (cfg.mainRate !== undefined) this._mainRate = cfg.mainRate;
25
- if (cfg.lateRate !== undefined) this._lateRate = cfg.lateRate;
26
- }
27
-
28
- public start() {
29
- if (this._started) return; // idempotent
30
- this._started = true;
31
-
32
- this._MAIN_ID = system.runInterval(() => {
33
- if (this.MAIN.count <= 0) return;
34
- try {
35
- const delta = this._delta();
36
- this.MAIN.emit(delta);
37
- } catch (e) {
38
- console.error(`ERROR: _THREAD_.MAIN:${this._MAIN_ID} |`, e);
39
- }
40
- }, this._mainRate);
41
-
42
- this._LATE_ID = system.runInterval(() => {
43
- if (this.LATE.count <= 0) return;
44
- try {
45
- this.LATE.emit();
46
- } catch (e) {
47
- console.error(`ERROR: _THREAD_.LATE:${this._LATE_ID} |`, e);
48
- }
49
- }, this._lateRate);
50
- }
51
-
52
- public stop() {
53
- if (this._MAIN_ID !== undefined) system.clearRun(this._MAIN_ID);
54
- if (this._LATE_ID !== undefined) system.clearRun(this._LATE_ID);
55
- this._MAIN_ID = undefined;
56
- this._LATE_ID = undefined;
57
- this._started = false;
58
- this._delta = this.createDeltaTimer(); // reset delta timing
59
- }
60
-
61
- private createDeltaTimer() {
62
- let last = Date.now();
63
- return () => {
64
- const now = Date.now();
65
- const delta = (now - last) / 1000;
66
- last = now;
67
- return delta;
68
- };
69
- }
70
- }
71
-
72
- export const Thread = new SingletonThreadManager();
@@ -1,21 +0,0 @@
1
- export namespace System {
2
- export const ProxyConstructor = ((_instance: any, source: any) => {
3
- return new Proxy(_instance, {
4
- get: (target, prop) => {
5
- if (prop in target) return (target as any)[prop];
6
- const v = (source as any)[prop];
7
- return typeof v === "function" ? v.bind(source) : v;
8
- },
9
-
10
- set: (target, prop, value) => {
11
- if (prop in target) { (target as any)[prop] = value; return true; }
12
- (source as any)[prop] = value;
13
- return true;
14
- },
15
-
16
- has: (target, prop) => prop in target || prop in source,
17
- ownKeys: () => [...Reflect.ownKeys(source), ...Reflect.ownKeys(_instance)],
18
- getOwnPropertyDescriptor: (_t, prop) => Object.getOwnPropertyDescriptor((prop in _instance ? _instance : source) as any, prop)
19
- }) as any;
20
- })
21
- }