Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sisilicon
GitHub Repository: sisilicon/worldedit-be
Path: blob/master/src/library/Minecraft.ts
1782 views
1
import { world, system, PlayerSpawnAfterEvent, WatchdogTerminateReason } from "@minecraft/server";
2
import { shutdownTimers } from "./utils/scheduling.js";
3
import { shutdownThreads } from "./utils/multithreading.js";
4
import { RawText } from "./utils/index.js";
5
6
// eslint-disable-next-line prefer-const
7
let _server: ServerBuild;
8
9
system.beforeEvents.watchdogTerminate.subscribe((ev) => {
10
if (ev.terminateReason == WatchdogTerminateReason.Hang) {
11
ev.cancel = true;
12
shutdownTimers();
13
shutdownThreads();
14
if (_server) _server.shutdown();
15
16
const players = Array.from(world.getPlayers());
17
if (players.length == 0) {
18
const event = (ev: PlayerSpawnAfterEvent) => {
19
if (!ev.initialSpawn) return;
20
world.afterEvents.playerSpawn.unsubscribe(event);
21
RawText.translate("script.watchdog.error.hang").print(ev.player);
22
};
23
system.run(() => world.afterEvents.playerSpawn.subscribe(event));
24
} else {
25
for (const player of players) {
26
RawText.translate("script.watchdog.error.hang").print(player);
27
}
28
}
29
}
30
});
31
32
export * from "./utils/index.js";
33
34
import { Player as PlayerBuilder } from "./classes/playerBuilder.js";
35
import { Command } from "./classes/commandBuilder.js";
36
import { ServerBuilder } from "./classes/serverBuilder.js";
37
import { UIForms } from "./classes/uiFormBuilder.js";
38
import { Block } from "./classes/blockBuilder.js";
39
40
export { CustomArgType, CommandPosition } from "./classes/commandBuilder.js";
41
export type { commandSyntaxError, registerInformation as CommandInfo } from "./@types/classes/CommandBuilder";
42
export { Databases } from "./classes/databaseBuilder.js";
43
export { configuration } from "./configurations.js";
44
45
class ServerBuild extends ServerBuilder {
46
public block = Block;
47
public player = PlayerBuilder;
48
public command = Command;
49
public uiForms = UIForms;
50
51
constructor() {
52
super();
53
this._buildEvent();
54
this._buildCommands();
55
}
56
/**
57
* @private
58
*/
59
private _buildEvent() {
60
const beforeEvents = world.beforeEvents;
61
const afterEvents = world.afterEvents;
62
63
beforeEvents.chatSend.subscribe((data) => {
64
/**
65
* Emit to 'beforeMessage' event listener
66
*/
67
this.emit("beforeMessage", data);
68
/**
69
* This is for the command builder and a emitter
70
*/
71
const msg = data.message;
72
if (!msg.startsWith(this.command.prefix)) return;
73
data.cancel = true;
74
const command = msg.split(/\s+/)[0].slice(this.command.prefix.length);
75
try {
76
this.command.callCommand(data.sender, command, msg.substring(msg.indexOf(command) + command.length).trim());
77
} catch (e) {
78
if (e instanceof RawText) e.printError(data.sender);
79
else RawText.text(e).printError(data.sender);
80
}
81
});
82
83
/**
84
* Emit to 'beforeExplosion' event listener
85
*/
86
beforeEvents.explosion.subscribe((data) => this.emit("beforeExplosion", data));
87
/**
88
* Emit to 'blockExplode' event listener
89
*/
90
afterEvents.blockExplode.subscribe((data) => this.emit("blockExplode", data));
91
/**
92
* Emit to 'beforeExplosion' event listener
93
*/
94
beforeEvents.explosion.subscribe((data) => this.emit("explosion", data));
95
/**
96
* Emit to 'pistonActivate' event listener
97
*/
98
afterEvents.pistonActivate.subscribe((data) => this.emit("pistonActivate", data));
99
/**
100
* Emit to 'itemUse' event listener
101
*/
102
beforeEvents.itemUse.subscribe((data) => this.emit("itemUseBefore", data));
103
104
/**
105
* Emit to 'itemUseBeforeOn' event listener
106
*/
107
beforeEvents.playerInteractWithBlock.subscribe((data) => this.emit("itemUseOnBefore", data));
108
109
/**
110
* Emit to 'messageCreate' event listener
111
*/
112
afterEvents.chatSend.subscribe((data) => this.emit("messageCreate", data));
113
/**
114
* Emit to 'entityEffected' event listener
115
*/
116
afterEvents.effectAdd.subscribe((data) => this.emit("entityEffected", data));
117
/**
118
* Emit to 'weatherChange' event listener
119
*/
120
afterEvents.weatherChange.subscribe((data) => this.emit("weatherChange", data));
121
/**
122
* Emit to 'blockBreak' event listener
123
*/
124
beforeEvents.playerBreakBlock.subscribe((data) => this.emit("blockBreak", data));
125
/**
126
* Emit to 'blockHit' event listener
127
*/
128
afterEvents.entityHitBlock.subscribe((data) => this.emit("blockHit", data));
129
/**
130
* Emit to 'worldInitialize' event listener
131
*/
132
afterEvents.worldLoad.subscribe(() => this.emit("ready", { loadTime: tickCount }));
133
/**
134
* Emit to 'playerChangeDimension' event listener
135
*/
136
afterEvents.playerDimensionChange.subscribe((data) => this.emit("playerChangeDimension", { player: data.player, dimension: data.player.dimension }));
137
138
/**
139
* Emit to 'entityCreate' event listener
140
*/
141
afterEvents.entitySpawn.subscribe((data) => {
142
if (data.entity?.isValid) this.emit("entityCreate", data);
143
});
144
145
let tickCount = 0;
146
let prevTime = Date.now();
147
system.runInterval(() => {
148
tickCount++;
149
150
this.emit("tick", {
151
currentTick: tickCount,
152
deltaTime: Date.now() - prevTime,
153
});
154
155
prevTime = Date.now();
156
});
157
158
/**
159
* Emit to 'playerSpawn' event listener
160
*/
161
afterEvents.playerSpawn.subscribe((data) => {
162
if (data.initialSpawn) {
163
this.emit("playerLoaded", data);
164
}
165
});
166
/**
167
* Emit to 'playerJoin' event listener
168
*/
169
afterEvents.playerJoin.subscribe((data) => {
170
this.emit("playerJoin", { playerName: data.playerName });
171
});
172
/**
173
* Emit to 'playerLeave' event listener
174
*/
175
afterEvents.playerLeave.subscribe((data) => {
176
this.emit("playerLeave", data);
177
});
178
}
179
180
private _buildCommands() {
181
// system.beforeEvents.startup.subscribe((ev) => {
182
// for (const command of this.command.getAllRegistation()) {
183
// if (command.name === "help") continue;
184
// const names = [command.name, ...(command.aliases ?? [])];
185
// type Parameters = { mandatoryParameters: CustomCommandParameter[]; optionalParameters: CustomCommandParameter[] };
186
// const usages: Array<[string[], Parameters]> = [];
187
// const accumulate = (params: Parameters, subs: Array<string>, argDefs: commandArgList, subName = "") => {
188
// params = { mandatoryParameters: [...params.mandatoryParameters], optionalParameters: [...params.optionalParameters] };
189
// subs = [...subs];
190
// let hasSubCommand = false;
191
// if (subName) subs.push(subName);
192
// argDefs?.forEach((arg) => {
193
// if ("subName" in arg) {
194
// hasSubCommand = true;
195
// accumulate(params, subs, arg.args, arg.subName);
196
// } else {
197
// const list = "default" in arg ? params.optionalParameters : params.mandatoryParameters;
198
// const types = {
199
// bool: CustomCommandParamType.Boolean,
200
// int: CustomCommandParamType.Integer,
201
// float: CustomCommandParamType.Float,
202
// string: CustomCommandParamType.String,
203
// xyz: CustomCommandParamType.Location,
204
// enum: CustomCommandParamType.Enum,
205
// }[arg.type];
206
// let name = arg.name;
207
// const customEnumValues = this.command.getCustomArgEnums(arg.type);
208
// if (arg.type === "enum" || customEnumValues) {
209
// name = `wedit:${name}`;
210
// try {
211
// ev.customCommandRegistry.registerEnum(name, (<commandEnum>arg).values ?? customEnumValues);
212
// } catch {
213
// if (!customEnumValues) contentLog.warn("Warning: Enum name already exists", name);
214
// }
215
// } else {
216
// name += types === undefined ? `: ${arg.type}` : "";
217
// }
218
// list.push({ name, type: types ?? (customEnumValues ? CustomCommandParamType.Enum : CustomCommandParamType.String) });
219
// }
220
// });
221
// if (!hasSubCommand) usages.push([subs, params]);
222
// };
223
// accumulate({ mandatoryParameters: [], optionalParameters: [] }, [], this.command.getRegistration(command.name).usage ?? []);
224
// for (const name of names) {
225
// for (const [subCommands, params] of usages) {
226
// ev.customCommandRegistry.registerCommand(
227
// {
228
// name: `wedit:${
229
// name +
230
// (subCommands.length
231
// ? subCommands
232
// .map((sub) => "_" + sub.replace(/^_+|_+$/g, ""))
233
// .filter((str) => str !== "_")
234
// .join("")
235
// : "")
236
// }`,
237
// description: command.description,
238
// permissionLevel: CommandPermissionLevel.Any,
239
// ...params,
240
// },
241
// (origin, ...args) => {
242
// if (!origin.sourceEntity?.matches({ type: "player" })) return { message: "WorldEdit commands can only be ran by players", status: CustomCommandStatus.Failure };
243
// this.command.callCommand(
244
// <Player>origin.sourceEntity,
245
// command.name,
246
// args.map((arg) => `${arg}`),
247
// subCommands
248
// );
249
// return { message: "", status: CustomCommandStatus.Success };
250
// }
251
// );
252
// }
253
// }
254
// }
255
// });
256
}
257
}
258
259
_server = new ServerBuild();
260
export const Server = _server;
261
262