omegga 1.2.8 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -1
- package/dist/brickadia/config.js +26 -90
- package/dist/brickadia/config.js.map +1 -1
- package/dist/brickadia/server.js +294 -293
- package/dist/brickadia/server.js.map +1 -1
- package/dist/cli/auth.js +149 -177
- package/dist/cli/auth.js.map +1 -1
- package/dist/cli/config.js +64 -66
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/index.js +14 -14
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/installer.js +37 -43
- package/dist/cli/installer.js.map +1 -1
- package/dist/cli/plugin.js +651 -682
- package/dist/cli/plugin.js.map +1 -1
- package/dist/cli/terminal.js +811 -733
- package/dist/cli/terminal.js.map +1 -1
- package/dist/config/formats/format_js.js +6 -6
- package/dist/config/formats/format_js.js.map +1 -1
- package/dist/config/formats/format_yml.js +7 -10
- package/dist/config/formats/format_yml.js.map +1 -1
- package/dist/config/index.js +46 -68
- package/dist/config/index.js.map +1 -1
- package/dist/config/reader.js +16 -27
- package/dist/config/reader.js.map +1 -1
- package/dist/config/validator.js +23 -25
- package/dist/config/validator.js.map +1 -1
- package/dist/config/writer.js +11 -21
- package/dist/config/writer.js.map +1 -1
- package/dist/index.js +18 -64
- package/dist/index.js.map +1 -1
- package/dist/info/default_commands.json.js +39 -0
- package/dist/info/default_commands.json.js.map +1 -0
- package/dist/logger.js +61 -60
- package/dist/logger.js.map +1 -1
- package/dist/main.js +424 -471
- package/dist/main.js.map +1 -1
- package/dist/omegga/auth.js +101 -148
- package/dist/omegga/auth.js.map +1 -1
- package/dist/omegga/commandInjector.js +261 -251
- package/dist/omegga/commandInjector.js.map +1 -1
- package/dist/omegga/index.js +14 -52
- package/dist/omegga/index.js.map +1 -1
- package/dist/omegga/logWrangler.js +224 -275
- package/dist/omegga/logWrangler.js.map +1 -1
- package/dist/omegga/matchers/auth.js +36 -50
- package/dist/omegga/matchers/auth.js.map +1 -1
- package/dist/omegga/matchers/chat.js +49 -71
- package/dist/omegga/matchers/chat.js.map +1 -1
- package/dist/omegga/matchers/command.js +25 -36
- package/dist/omegga/matchers/command.js.map +1 -1
- package/dist/omegga/matchers/exit.js +15 -18
- package/dist/omegga/matchers/exit.js.map +1 -1
- package/dist/omegga/matchers/index.js +26 -40
- package/dist/omegga/matchers/index.js.map +1 -1
- package/dist/omegga/matchers/init.js +20 -23
- package/dist/omegga/matchers/init.js.map +1 -1
- package/dist/omegga/matchers/interact.js +58 -64
- package/dist/omegga/matchers/interact.js.map +1 -1
- package/dist/omegga/matchers/join.js +74 -95
- package/dist/omegga/matchers/join.js.map +1 -1
- package/dist/omegga/matchers/leave.js +43 -56
- package/dist/omegga/matchers/leave.js.map +1 -1
- package/dist/omegga/matchers/mapChange.js +26 -35
- package/dist/omegga/matchers/mapChange.js.map +1 -1
- package/dist/omegga/matchers/minigameJoin.js +24 -31
- package/dist/omegga/matchers/minigameJoin.js.map +1 -1
- package/dist/omegga/matchers/version.js +42 -49
- package/dist/omegga/matchers/version.js.map +1 -1
- package/dist/omegga/player.js +527 -527
- package/dist/omegga/player.js.map +1 -1
- package/dist/omegga/plugin/interface.js +91 -98
- package/dist/omegga/plugin/interface.js.map +1 -1
- package/dist/omegga/plugin/plugin_jsonrpc_stdio.js +524 -429
- package/dist/omegga/plugin/plugin_jsonrpc_stdio.js.map +1 -1
- package/dist/omegga/plugin/plugin_node_safe/proxyOmegga.js +282 -294
- package/dist/omegga/plugin/plugin_node_safe/proxyOmegga.js.map +1 -1
- package/dist/omegga/plugin/plugin_node_safe.js +365 -393
- package/dist/omegga/plugin/plugin_node_safe.js.map +1 -1
- package/dist/omegga/plugin/plugin_node_unsafe.js +119 -179
- package/dist/omegga/plugin/plugin_node_unsafe.js.map +1 -1
- package/dist/omegga/plugin.js +402 -347
- package/dist/omegga/plugin.js.map +1 -1
- package/dist/omegga/server.js +742 -774
- package/dist/omegga/server.js.map +1 -1
- package/dist/omegga/wrapper.js +64 -91
- package/dist/omegga/wrapper.js.map +1 -1
- package/dist/plugin.js +11 -31
- package/dist/plugin.js.map +1 -1
- package/dist/softconfig.js +121 -100
- package/dist/softconfig.js.map +1 -1
- package/dist/updater/steam.js +97 -112
- package/dist/updater/steam.js.map +1 -1
- package/dist/util/brdb.js +496 -528
- package/dist/util/brdb.js.map +1 -1
- package/dist/util/brick/checkBounds.js +11 -15
- package/dist/util/brick/checkBounds.js.map +1 -1
- package/dist/util/brick/constants.js +723 -174
- package/dist/util/brick/constants.js.map +1 -1
- package/dist/util/brick/displayName.js +204 -211
- package/dist/util/brick/displayName.js.map +1 -1
- package/dist/util/brick/getBounds.js +29 -41
- package/dist/util/brick/getBounds.js.map +1 -1
- package/dist/util/brick/getBrickSize.js +6 -7
- package/dist/util/brick/getBrickSize.js.map +1 -1
- package/dist/util/brick/getScaleAxis.js +24 -30
- package/dist/util/brick/getScaleAxis.js.map +1 -1
- package/dist/util/brick/index.js +8 -29
- package/dist/util/brick/index.js.map +1 -1
- package/dist/util/brick/rotate.js +29 -34
- package/dist/util/brick/rotate.js.map +1 -1
- package/dist/util/brick/setOwnership.js +13 -19
- package/dist/util/brick/setOwnership.js.map +1 -1
- package/dist/util/chat.js +53 -44
- package/dist/util/chat.js.map +1 -1
- package/dist/util/color.js +112 -124
- package/dist/util/color.js.map +1 -1
- package/dist/util/file.js +54 -98
- package/dist/util/file.js.map +1 -1
- package/dist/util/index.js +84 -106
- package/dist/util/index.js.map +1 -1
- package/dist/util/map.js +18 -20
- package/dist/util/map.js.map +1 -1
- package/dist/util/pattern.js +6 -9
- package/dist/util/pattern.js.map +1 -1
- package/dist/util/time.js +31 -34
- package/dist/util/time.js.map +1 -1
- package/dist/util/uuid.js +10 -8
- package/dist/util/uuid.js.map +1 -1
- package/dist/util/wsl.js +19 -25
- package/dist/util/wsl.js.map +1 -1
- package/dist/version.js +7 -9
- package/dist/version.js.map +1 -1
- package/dist/webserver/backend/api.js +784 -874
- package/dist/webserver/backend/api.js.map +1 -1
- package/dist/webserver/backend/calendar.js +14 -17
- package/dist/webserver/backend/calendar.js.map +1 -1
- package/dist/webserver/backend/database.js +563 -613
- package/dist/webserver/backend/database.js.map +1 -1
- package/dist/webserver/backend/index.js +153 -191
- package/dist/webserver/backend/index.js.map +1 -1
- package/dist/webserver/backend/metrics.js +219 -248
- package/dist/webserver/backend/metrics.js.map +1 -1
- package/dist/webserver/backend/util.js +47 -68
- package/dist/webserver/backend/util.js.map +1 -1
- package/dist/worker.js +322 -0
- package/dist/worker.js.map +1 -0
- package/package.json +14 -10
- package/templates/safe-ts/omegga.d.ts +2 -2
- package/vite.backend.config.mts +46 -0
- package/vite.frontend.config.mts +58 -0
- package/vitest.backend.config.mts +7 -0
- package/dist/brickadia/config.d.ts +0 -3
- package/dist/brickadia/presets.d.ts +0 -65
- package/dist/brickadia/presets.js +0 -3
- package/dist/brickadia/presets.js.map +0 -1
- package/dist/brickadia/server.d.ts +0 -36
- package/dist/brickadia/types.d.ts +0 -45
- package/dist/brickadia/types.js +0 -3
- package/dist/brickadia/types.js.map +0 -1
- package/dist/cli/auth.d.ts +0 -26
- package/dist/cli/config.d.ts +0 -10
- package/dist/cli/index.d.ts +0 -30
- package/dist/cli/installer.d.ts +0 -1
- package/dist/cli/plugin.d.ts +0 -22
- package/dist/cli/terminal.d.ts +0 -25
- package/dist/config/authorizer.d.ts +0 -2
- package/dist/config/authorizer.js +0 -38
- package/dist/config/authorizer.js.map +0 -1
- package/dist/config/formats/format_js.d.ts +0 -3
- package/dist/config/formats/format_yml.d.ts +0 -3
- package/dist/config/index.d.ts +0 -18
- package/dist/config/reader.d.ts +0 -3
- package/dist/config/types.d.ts +0 -50
- package/dist/config/types.js +0 -3
- package/dist/config/types.js.map +0 -1
- package/dist/config/validator.d.ts +0 -6
- package/dist/config/writer.d.ts +0 -3
- package/dist/index.d.ts +0 -22
- package/dist/info/default_commands.json +0 -29
- package/dist/logger.d.ts +0 -41
- package/dist/main.d.ts +0 -1
- package/dist/omegga/auth.d.ts +0 -9
- package/dist/omegga/commandInjector.d.ts +0 -35
- package/dist/omegga/index.d.ts +0 -7
- package/dist/omegga/logWrangler.d.ts +0 -32
- package/dist/omegga/matchers/auth.d.ts +0 -10
- package/dist/omegga/matchers/chat.d.ts +0 -10
- package/dist/omegga/matchers/command.d.ts +0 -7
- package/dist/omegga/matchers/exit.d.ts +0 -3
- package/dist/omegga/matchers/index.d.ts +0 -3
- package/dist/omegga/matchers/init.d.ts +0 -3
- package/dist/omegga/matchers/interact.d.ts +0 -4
- package/dist/omegga/matchers/join.d.ts +0 -4
- package/dist/omegga/matchers/leave.d.ts +0 -4
- package/dist/omegga/matchers/mapChange.d.ts +0 -3
- package/dist/omegga/matchers/minigameJoin.d.ts +0 -9
- package/dist/omegga/matchers/types.d.ts +0 -5
- package/dist/omegga/matchers/types.js +0 -3
- package/dist/omegga/matchers/types.js.map +0 -1
- package/dist/omegga/matchers/version.d.ts +0 -3
- package/dist/omegga/player.d.ts +0 -81
- package/dist/omegga/plugin/interface.d.ts +0 -30
- package/dist/omegga/plugin/plugin_jsonrpc_stdio.d.ts +0 -23
- package/dist/omegga/plugin/plugin_node_safe/proxyOmegga.d.ts +0 -145
- package/dist/omegga/plugin/plugin_node_safe/worker.d.ts +0 -1
- package/dist/omegga/plugin/plugin_node_safe/worker.js +0 -367
- package/dist/omegga/plugin/plugin_node_safe/worker.js.map +0 -1
- package/dist/omegga/plugin/plugin_node_safe.d.ts +0 -23
- package/dist/omegga/plugin/plugin_node_unsafe.d.ts +0 -13
- package/dist/omegga/plugin.d.ts +0 -63
- package/dist/omegga/server.d.ts +0 -166
- package/dist/omegga/types.d.ts +0 -49
- package/dist/omegga/types.js +0 -3
- package/dist/omegga/types.js.map +0 -1
- package/dist/omegga/wrapper.d.ts +0 -32
- package/dist/plugin.d.ts +0 -916
- package/dist/softconfig.d.ts +0 -67
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/dist/updater/index.d.ts +0 -1
- package/dist/updater/index.js +0 -10
- package/dist/updater/index.js.map +0 -1
- package/dist/updater/steam.d.ts +0 -52
- package/dist/util/brdb.d.ts +0 -31
- package/dist/util/brick/checkBounds.d.ts +0 -8
- package/dist/util/brick/constants.d.ts +0 -18
- package/dist/util/brick/displayName.d.ts +0 -7
- package/dist/util/brick/getBounds.d.ts +0 -5
- package/dist/util/brick/getBrickSize.d.ts +0 -3
- package/dist/util/brick/getScaleAxis.d.ts +0 -3
- package/dist/util/brick/index.d.ts +0 -14
- package/dist/util/brick/rotate.d.ts +0 -16
- package/dist/util/brick/setOwnership.d.ts +0 -12
- package/dist/util/chat.d.ts +0 -23
- package/dist/util/color.d.ts +0 -13
- package/dist/util/file.d.ts +0 -5
- package/dist/util/index.d.ts +0 -183
- package/dist/util/map.d.ts +0 -6
- package/dist/util/pattern.d.ts +0 -1
- package/dist/util/time.d.ts +0 -39
- package/dist/util/uuid.d.ts +0 -3
- package/dist/util/wsl.d.ts +0 -2
- package/dist/version.d.ts +0 -2
- package/dist/webserver/backend/api.d.ts +0 -115
- package/dist/webserver/backend/calendar.d.ts +0 -5
- package/dist/webserver/backend/database.d.ts +0 -150
- package/dist/webserver/backend/index.d.ts +0 -30
- package/dist/webserver/backend/metrics.d.ts +0 -3
- package/dist/webserver/backend/types.d.ts +0 -114
- package/dist/webserver/backend/types.js +0 -3
- package/dist/webserver/backend/types.js.map +0 -1
- package/dist/webserver/backend/util.d.ts +0 -2
- package/dist/webserver/index.d.ts +0 -2
- package/dist/webserver/index.js +0 -9
- package/dist/webserver/index.js.map +0 -1
|
@@ -1,887 +1,797 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const logger = require("../../logger.js");
|
|
4
|
+
const steam = require("../../updater/steam.js");
|
|
5
|
+
const version = require("../../version.js");
|
|
6
|
+
const player = require("../../omegga/player.js");
|
|
7
|
+
const chat = require("../../util/chat.js");
|
|
8
|
+
const color = require("../../util/color.js");
|
|
9
|
+
const time = require("../../util/time.js");
|
|
10
|
+
const uuid = require("../../util/uuid.js");
|
|
11
|
+
const express = require("express");
|
|
12
|
+
const jsonRpc2_0 = require("json-rpc-2.0");
|
|
13
|
+
const _ = require("lodash");
|
|
14
|
+
const brdb = require("../../util/brdb.js");
|
|
15
|
+
function setupApi(server, io) {
|
|
16
|
+
const { database, omegga } = server;
|
|
17
|
+
const openApi = express.Router();
|
|
18
|
+
const api = express.Router();
|
|
19
|
+
openApi.get(
|
|
20
|
+
"/first",
|
|
21
|
+
async (req, res) => res.json(await database.isFirstUser())
|
|
22
|
+
);
|
|
23
|
+
openApi.post("/auth", async (req, res) => {
|
|
24
|
+
if (typeof req.body !== "object" || typeof req.body.username !== "string" || typeof req.body.password !== "string") {
|
|
25
|
+
return res.status(422).json({ message: "invalid body" });
|
|
7
26
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
27
|
+
const { username, password } = req.body;
|
|
28
|
+
if (!username.match(/^\w{0,32}$/)) {
|
|
29
|
+
return res.status(422).json({ message: "invalid body" });
|
|
30
|
+
}
|
|
31
|
+
const isFirst = await database.isFirstUser();
|
|
32
|
+
let user;
|
|
33
|
+
if (isFirst) {
|
|
34
|
+
user = await database.createAdminUser(
|
|
35
|
+
username,
|
|
36
|
+
username === "" ? "" : password
|
|
37
|
+
);
|
|
38
|
+
} else {
|
|
39
|
+
user = await database.authUser(username, password);
|
|
40
|
+
}
|
|
41
|
+
if (user) {
|
|
42
|
+
req.session.userId = user._id;
|
|
43
|
+
req.session.save();
|
|
44
|
+
res.status(200).json({});
|
|
45
|
+
} else {
|
|
46
|
+
res.status(404).json({ message: "no user found" });
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
api.get("/logout", (req, res) => {
|
|
50
|
+
req.session.destroy((e) => {
|
|
51
|
+
res.status(e ? 500 : 200).json({});
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
api.all("*", (req, _res, next) => {
|
|
55
|
+
(async () => {
|
|
56
|
+
const user = await database.findUserById(req.session.userId);
|
|
57
|
+
if (!user || user.isBanned) return next(new Error("unauthorized"));
|
|
58
|
+
next();
|
|
59
|
+
})();
|
|
60
|
+
});
|
|
61
|
+
io.on("connection", (socket) => {
|
|
62
|
+
socket.join("user:" + socket.data.user._id);
|
|
63
|
+
database.getRoles().then((roles) => {
|
|
64
|
+
socket.emit("data", {
|
|
65
|
+
roles,
|
|
66
|
+
version: version.VERSION,
|
|
67
|
+
brickadiaVersion: omegga.version ?? null,
|
|
68
|
+
canLogOut: socket.data.user.username !== "",
|
|
69
|
+
now: Date.now(),
|
|
70
|
+
// this can be used for the frontend to anticipate drift
|
|
71
|
+
userless: !socket.data.user.username,
|
|
72
|
+
user: {
|
|
73
|
+
username: socket.data.user.username || "Admin",
|
|
74
|
+
isOwner: socket.data.user.isOwner,
|
|
75
|
+
roles: socket.data.user.roles
|
|
76
|
+
},
|
|
77
|
+
isSteam: Boolean(omegga.config.__STEAM),
|
|
78
|
+
update: {
|
|
79
|
+
canCheck: omegga.config.__STEAM && !omegga.config.server?.steambeta,
|
|
80
|
+
lastCheck: steam.getLastSteamUpdateCheck()?.result ?? null
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
const usernameText = `[${(socket.data.user.username || "Admin").brightMagenta}]`;
|
|
85
|
+
const log = (...args) => logger.default.logp(usernameText, ...args);
|
|
86
|
+
const error = (...args) => logger.default.errorp(usernameText, ...args);
|
|
87
|
+
const rpcServer = new jsonRpc2_0.JSONRPCServer();
|
|
88
|
+
const rpcClient = new jsonRpc2_0.JSONRPCClient(async (data) => {
|
|
89
|
+
socket.emit("rpc", data);
|
|
90
|
+
});
|
|
91
|
+
const rpc = new jsonRpc2_0.JSONRPCServerAndClient(rpcServer, rpcClient);
|
|
92
|
+
socket.on("rpc", (data) => {
|
|
93
|
+
if (data && typeof data === "object") {
|
|
94
|
+
try {
|
|
95
|
+
rpc.receiveAndSend(data);
|
|
96
|
+
} catch (e) {
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
rpc.addMethod("chat", async ([message]) => {
|
|
101
|
+
if (typeof message !== "string") return;
|
|
102
|
+
if (message.length > 140) message = message.slice(0, 140);
|
|
103
|
+
const user = {
|
|
104
|
+
name: socket.data.user.username || "Admin",
|
|
105
|
+
id: socket.data.user.playerId,
|
|
106
|
+
color: "ff00ff",
|
|
107
|
+
web: true
|
|
108
|
+
};
|
|
109
|
+
io.to("chat").emit(
|
|
110
|
+
"chat",
|
|
111
|
+
await database.addChatLog("msg", user, message)
|
|
112
|
+
);
|
|
113
|
+
omegga.broadcast(
|
|
114
|
+
`"[<b><color=\\"ff00ff\\">${user.name}</></>]: ${chat.parseLinks(
|
|
115
|
+
chat.sanitize(message)
|
|
116
|
+
)}"`
|
|
117
|
+
);
|
|
118
|
+
logger.default.log(`[${user.name.brightMagenta.underline}]: ${message}`);
|
|
119
|
+
return "ok";
|
|
120
|
+
});
|
|
121
|
+
rpc.addMethod("chat.recent", () => {
|
|
122
|
+
return database.getChats({ sameServer: true });
|
|
123
|
+
});
|
|
124
|
+
rpc.addMethod(
|
|
125
|
+
"chat.history",
|
|
126
|
+
([{ after, before }] = [{}]) => {
|
|
127
|
+
return database.getChats({ after, before });
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
rpc.addMethod("chat.calendar", () => {
|
|
131
|
+
return database.calendar.years;
|
|
132
|
+
});
|
|
133
|
+
rpc.addMethod("plugins.list", () => {
|
|
134
|
+
return _.sortBy(
|
|
135
|
+
omegga.pluginLoader.plugins.map((p) => ({
|
|
136
|
+
name: p.getName(),
|
|
137
|
+
documentation: p.getDocumentation(),
|
|
138
|
+
path: p.shortPath,
|
|
139
|
+
isLoaded: p.isLoaded(),
|
|
140
|
+
isEnabled: p.isEnabled()
|
|
141
|
+
})),
|
|
142
|
+
(p) => p.name.toLowerCase()
|
|
143
|
+
);
|
|
144
|
+
});
|
|
145
|
+
rpc.addMethod("plugin.get", async ([shortPath]) => {
|
|
146
|
+
const plugin = omegga.pluginLoader.plugins.find(
|
|
147
|
+
(p) => p.shortPath === shortPath
|
|
148
|
+
);
|
|
149
|
+
if (!plugin) return null;
|
|
150
|
+
const [defaultConfig, config, objCount] = await Promise.all([
|
|
151
|
+
plugin.storage.getDefaultConfig(),
|
|
152
|
+
plugin.storage.getConfig(),
|
|
153
|
+
plugin.storage.count()
|
|
154
|
+
]);
|
|
155
|
+
return {
|
|
156
|
+
name: plugin.getName(),
|
|
157
|
+
format: plugin.constructor.getFormat(),
|
|
158
|
+
info: plugin.getInfo(),
|
|
159
|
+
documentation: plugin.getDocumentation(),
|
|
160
|
+
config,
|
|
161
|
+
defaultConfig,
|
|
162
|
+
objCount,
|
|
163
|
+
path: plugin.shortPath,
|
|
164
|
+
isLoaded: plugin.isLoaded(),
|
|
165
|
+
isEnabled: plugin.isEnabled()
|
|
166
|
+
};
|
|
167
|
+
});
|
|
168
|
+
rpc.addMethod(
|
|
169
|
+
"players.list",
|
|
170
|
+
async ([
|
|
171
|
+
{
|
|
172
|
+
page = 0,
|
|
173
|
+
search = "",
|
|
174
|
+
sort = "name",
|
|
175
|
+
direction = "1",
|
|
176
|
+
filter = ""
|
|
177
|
+
} = {}
|
|
178
|
+
]) => {
|
|
179
|
+
const banList = (omegga.getBanList() || { banList: {} }).banList;
|
|
180
|
+
const now = Date.now();
|
|
181
|
+
let limitId;
|
|
182
|
+
if (filter === "banned") {
|
|
183
|
+
limitId = Object.keys(banList).filter(
|
|
184
|
+
(b) => banList[b].expires <= banList[b].created || time.parseBrickadiaTime(banList[b].expires) > Date.now()
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
const resp = await database.getPlayers({
|
|
188
|
+
page,
|
|
189
|
+
search,
|
|
190
|
+
sort,
|
|
191
|
+
direction,
|
|
192
|
+
limitId
|
|
193
|
+
});
|
|
194
|
+
for (const player2 of resp.players) {
|
|
195
|
+
player2.seenAgo = now - player2.lastSeen;
|
|
196
|
+
player2.createdAgo = now - player2.created;
|
|
197
|
+
const foundBan = banList[player2.id];
|
|
198
|
+
if (foundBan) {
|
|
199
|
+
const created = time.parseBrickadiaTime(foundBan.created);
|
|
200
|
+
const expires = time.parseBrickadiaTime(foundBan.expires);
|
|
201
|
+
let currentBan = {
|
|
202
|
+
...foundBan,
|
|
203
|
+
// parse the times in the current ban
|
|
204
|
+
created,
|
|
205
|
+
expires,
|
|
206
|
+
duration: expires - created,
|
|
207
|
+
remainingTime: expires - now,
|
|
208
|
+
// lookup banner name
|
|
209
|
+
bannerName: _.get(
|
|
210
|
+
omegga.getNameCache(),
|
|
211
|
+
["savedPlayerNames", foundBan.bannerId],
|
|
212
|
+
""
|
|
213
|
+
)
|
|
214
|
+
};
|
|
215
|
+
if (currentBan.expires < now && currentBan.duration > 0)
|
|
216
|
+
currentBan = null;
|
|
217
|
+
player2.ban = currentBan;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return resp;
|
|
221
|
+
}
|
|
222
|
+
);
|
|
223
|
+
rpc.addMethod("player.get", async ([id]) => {
|
|
224
|
+
const entry = await database.getPlayer(id);
|
|
225
|
+
if (!entry) return null;
|
|
226
|
+
const now = Date.now();
|
|
227
|
+
entry.seenAgo = now - entry.lastSeen;
|
|
228
|
+
entry.createdAgo = now - entry.created;
|
|
229
|
+
for (const n of entry.nameHistory) n.ago = now - n.date;
|
|
230
|
+
const playerRoles = player.default.getRoles(omegga, id) || [];
|
|
231
|
+
const { roles: serverRoles = [] } = omegga.getRoleSetup() ?? {};
|
|
232
|
+
for (const b of entry.banHistory) {
|
|
233
|
+
b.duration = b.expires - b.created;
|
|
234
|
+
b.bannerName = _.get(
|
|
235
|
+
omegga.getNameCache(),
|
|
236
|
+
["savedPlayerNames", b.bannerId],
|
|
237
|
+
""
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
for (const b of entry.kickHistory) {
|
|
241
|
+
b.kickerName = _.get(
|
|
242
|
+
omegga.getNameCache(),
|
|
243
|
+
["savedPlayerNames", b.kickerId],
|
|
244
|
+
""
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
const foundBan = (omegga.getBanList() || { banList: {} }).banList[id];
|
|
248
|
+
let currentBan = null;
|
|
249
|
+
if (foundBan) {
|
|
250
|
+
const created = time.parseBrickadiaTime(foundBan.created);
|
|
251
|
+
const expires = time.parseBrickadiaTime(foundBan.expires);
|
|
252
|
+
currentBan = {
|
|
253
|
+
...foundBan,
|
|
254
|
+
created,
|
|
255
|
+
expires,
|
|
256
|
+
duration: expires - created,
|
|
257
|
+
remainingTime: expires - now,
|
|
258
|
+
// lookup banner name
|
|
259
|
+
bannerName: _.get(
|
|
260
|
+
omegga.getNameCache(),
|
|
261
|
+
["savedPlayerNames", foundBan.bannerId],
|
|
262
|
+
""
|
|
263
|
+
)
|
|
24
264
|
};
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
265
|
+
if (currentBan.expires < now && currentBan.duration > 0)
|
|
266
|
+
currentBan = null;
|
|
267
|
+
}
|
|
268
|
+
return {
|
|
269
|
+
// database results
|
|
270
|
+
...entry,
|
|
271
|
+
// player is host
|
|
272
|
+
isHost: omegga.getHostId() === id,
|
|
273
|
+
isOnline: omegga.players.some((p) => p.id === id),
|
|
274
|
+
// player's current ban state
|
|
275
|
+
currentBan,
|
|
276
|
+
// all player's roles w/ colors
|
|
277
|
+
roles: playerRoles.map((r) => {
|
|
278
|
+
let color$1 = "ffffff";
|
|
279
|
+
const role = serverRoles.find(
|
|
280
|
+
(sr) => sr.name.toLowerCase() === r.toLowerCase()
|
|
281
|
+
);
|
|
282
|
+
if (role && role.bHasColor) color$1 = color.rgbToHex(role.color);
|
|
283
|
+
return {
|
|
284
|
+
name: r,
|
|
285
|
+
color: color$1
|
|
286
|
+
};
|
|
287
|
+
})
|
|
288
|
+
};
|
|
289
|
+
});
|
|
290
|
+
rpc.addMethod(
|
|
291
|
+
"player.ban",
|
|
292
|
+
async ([id, duration = -1, reason = "No Reason"]) => {
|
|
293
|
+
if (typeof duration !== "number") return false;
|
|
294
|
+
if (typeof id !== "string" || !uuid.match(id)) return false;
|
|
295
|
+
if (typeof reason !== "string" || reason.length > 128) return false;
|
|
296
|
+
reason = reason.replace(/\n/g, " ").replace(/"/g, "'");
|
|
297
|
+
log(
|
|
298
|
+
"Banning player",
|
|
299
|
+
omegga.getNameCache()?.savedPlayerNames?.[id].yellow ?? "with id " + id.yellow
|
|
300
|
+
);
|
|
301
|
+
omegga.writeln(`Chat.Command /Ban "${id}" ${duration} "${reason}"`);
|
|
302
|
+
let listener;
|
|
303
|
+
const ok = await Promise.race([
|
|
304
|
+
new Promise((resolve) => {
|
|
305
|
+
database.on(
|
|
306
|
+
"update.bans",
|
|
307
|
+
listener = () => {
|
|
308
|
+
const banList = (omegga.getBanList() || { banList: {} }).banList;
|
|
309
|
+
if (banList[id]) {
|
|
310
|
+
const entry = {
|
|
311
|
+
type: "banHistory",
|
|
312
|
+
banned: id,
|
|
313
|
+
bannerId: null,
|
|
314
|
+
created: time.parseBrickadiaTime(banList[id].created),
|
|
315
|
+
expires: time.parseBrickadiaTime(banList[id].expires),
|
|
316
|
+
reason: banList[id].reason
|
|
317
|
+
};
|
|
318
|
+
database.stores.players.update(
|
|
319
|
+
entry,
|
|
320
|
+
{ $set: entry },
|
|
321
|
+
{ upsert: true }
|
|
322
|
+
);
|
|
323
|
+
resolve(true);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
);
|
|
327
|
+
}),
|
|
328
|
+
new Promise((resolve) => setTimeout(() => resolve(false), 5e3))
|
|
329
|
+
]);
|
|
330
|
+
database.off("update.bans", listener);
|
|
331
|
+
return ok;
|
|
332
|
+
}
|
|
333
|
+
);
|
|
334
|
+
rpc.addMethod(
|
|
335
|
+
"player.kick",
|
|
336
|
+
async ([id, reason = "No Reason"]) => {
|
|
337
|
+
if (typeof id !== "string" || !uuid.match(id)) return false;
|
|
338
|
+
if (typeof reason !== "string" || reason.length > 128) return false;
|
|
339
|
+
reason = reason.replace(/\n/g, " ").replace(/"/g, "'");
|
|
340
|
+
const player2 = omegga.players.find((p) => p.id === id);
|
|
341
|
+
if (!player2) return false;
|
|
342
|
+
log("Kicking player", player2.name.yellow);
|
|
343
|
+
omegga.writeln(`Chat.Command /Kick "${id}" "${reason}"`);
|
|
344
|
+
const ok = await Promise.race([
|
|
345
|
+
new Promise((resolve) => {
|
|
346
|
+
omegga.once("leave", async (leavingPlayer) => {
|
|
347
|
+
if (leavingPlayer.id === id) {
|
|
348
|
+
resolve(true);
|
|
349
|
+
const entry = {
|
|
350
|
+
type: "kickHistory",
|
|
351
|
+
kicked: id,
|
|
352
|
+
kickerId: null,
|
|
353
|
+
created: Date.now(),
|
|
354
|
+
reason
|
|
355
|
+
};
|
|
356
|
+
await database.stores.players.update(
|
|
357
|
+
entry,
|
|
358
|
+
{ $set: entry },
|
|
359
|
+
{ upsert: true }
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
}),
|
|
364
|
+
new Promise((resolve) => setTimeout(() => resolve(false), 5e3))
|
|
365
|
+
]);
|
|
366
|
+
return ok;
|
|
367
|
+
}
|
|
368
|
+
);
|
|
369
|
+
rpc.addMethod("player.unban", async ([id]) => {
|
|
370
|
+
if (typeof id !== "string" || !uuid.match(id)) return false;
|
|
371
|
+
const banList = (omegga.getBanList() || { banList: {} }).banList;
|
|
372
|
+
if (!banList[id]) return false;
|
|
373
|
+
log(
|
|
374
|
+
"Unbanning player",
|
|
375
|
+
omegga.getNameCache()?.savedPlayerNames?.[id].yellow ?? "with id " + id.yellow
|
|
376
|
+
);
|
|
377
|
+
omegga.writeln(`Chat.Command /Unban "${id}"`);
|
|
378
|
+
let listener;
|
|
379
|
+
const ok = await Promise.race([
|
|
380
|
+
new Promise((resolve) => {
|
|
381
|
+
database.on(
|
|
382
|
+
"update.bans",
|
|
383
|
+
listener = () => {
|
|
384
|
+
const banList2 = (omegga.getBanList() || { banList: {} }).banList;
|
|
385
|
+
if (!banList2[id] || time.parseBrickadiaTime(banList2[id].expires) < Date.now())
|
|
386
|
+
resolve(true);
|
|
387
|
+
}
|
|
388
|
+
);
|
|
389
|
+
}),
|
|
390
|
+
new Promise((resolve) => setTimeout(() => resolve(false), 5e3))
|
|
391
|
+
]);
|
|
392
|
+
database.off("update.bans", listener);
|
|
393
|
+
return ok;
|
|
394
|
+
});
|
|
395
|
+
rpc.addMethod("player.clearbricks", async ([id]) => {
|
|
396
|
+
if (typeof id !== "string" || !uuid.match(id)) return false;
|
|
397
|
+
log(
|
|
398
|
+
"Clearing bricks for player",
|
|
399
|
+
omegga.getNameCache()?.savedPlayerNames?.[id]?.yellow ?? "with id " + id.yellow
|
|
400
|
+
);
|
|
401
|
+
omegga.writeln(`Bricks.Clear "${id}"`);
|
|
402
|
+
return true;
|
|
403
|
+
});
|
|
404
|
+
rpc.addMethod(
|
|
405
|
+
"plugin.config",
|
|
406
|
+
async ([shortPath, config]) => {
|
|
407
|
+
const plugin = omegga.pluginLoader.plugins.find(
|
|
408
|
+
(p) => p.shortPath === shortPath
|
|
409
|
+
);
|
|
410
|
+
if (!plugin) return null;
|
|
411
|
+
await plugin.storage.setConfig(config);
|
|
412
|
+
return true;
|
|
413
|
+
}
|
|
414
|
+
);
|
|
415
|
+
rpc.addMethod("plugins.reload", async () => {
|
|
416
|
+
if (!omegga.pluginLoader) {
|
|
417
|
+
error("Omegga is not using plugins");
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
log("Unloading current plugins");
|
|
421
|
+
let success = await omegga.pluginLoader.unload();
|
|
422
|
+
if (!success) {
|
|
423
|
+
error("Could not unload all plugins");
|
|
424
|
+
return false;
|
|
425
|
+
}
|
|
426
|
+
log("Scanning for new plugins");
|
|
427
|
+
success = await omegga.pluginLoader.scan();
|
|
428
|
+
if (!success) {
|
|
429
|
+
error("Could not scan for plugins");
|
|
430
|
+
return false;
|
|
431
|
+
}
|
|
432
|
+
log("Starting plugins");
|
|
433
|
+
success = await omegga.pluginLoader.reload();
|
|
434
|
+
if (success) {
|
|
435
|
+
const plugins = omegga.pluginLoader.plugins.filter((p) => p.isLoaded()).map((p) => p.getName());
|
|
436
|
+
log("Loaded", (plugins.length + "").yellow, "plugins:", plugins);
|
|
437
|
+
return true;
|
|
438
|
+
} else {
|
|
439
|
+
error("Could not load all plugins");
|
|
440
|
+
return false;
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
rpc.addMethod("plugin.unload", async ([shortPath]) => {
|
|
444
|
+
const plugin = omegga.pluginLoader.plugins.find(
|
|
445
|
+
(p) => p.shortPath === shortPath
|
|
446
|
+
);
|
|
447
|
+
if (!plugin) return false;
|
|
448
|
+
if (!plugin.isLoaded()) return false;
|
|
449
|
+
log("Unloading".red, "plugin", plugin.getName().yellow);
|
|
450
|
+
return await plugin.unload();
|
|
451
|
+
});
|
|
452
|
+
rpc.addMethod("plugin.load", async ([shortPath]) => {
|
|
453
|
+
const plugin = omegga.pluginLoader.plugins.find(
|
|
454
|
+
(p) => p.shortPath === shortPath
|
|
455
|
+
);
|
|
456
|
+
if (!plugin) return false;
|
|
457
|
+
if (plugin.isLoaded() || !plugin.isEnabled()) return false;
|
|
458
|
+
log("Loading".green, "plugin", plugin.getName().yellow);
|
|
459
|
+
return await plugin.load();
|
|
460
|
+
});
|
|
461
|
+
rpc.addMethod(
|
|
462
|
+
"plugin.toggle",
|
|
463
|
+
([shortPath, enabled]) => {
|
|
464
|
+
if (typeof enabled !== "boolean") return;
|
|
465
|
+
const plugin = omegga.pluginLoader.plugins.find(
|
|
466
|
+
(p) => p.shortPath === shortPath
|
|
467
|
+
);
|
|
468
|
+
if (!plugin) return false;
|
|
469
|
+
try {
|
|
470
|
+
plugin.setEnabled(enabled);
|
|
471
|
+
log(
|
|
472
|
+
enabled ? "Enabled".green : "Disabled".red,
|
|
473
|
+
"plugin",
|
|
474
|
+
plugin.getName().yellow
|
|
475
|
+
);
|
|
476
|
+
return true;
|
|
477
|
+
} catch (e) {
|
|
478
|
+
error(
|
|
479
|
+
"Error",
|
|
480
|
+
enabled ? "enabling".green : "disabling".red,
|
|
481
|
+
"plugin",
|
|
482
|
+
plugin.getName().yellow
|
|
483
|
+
);
|
|
484
|
+
return false;
|
|
67
485
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
486
|
+
}
|
|
487
|
+
);
|
|
488
|
+
rpc.addMethod("roles.list", () => {
|
|
489
|
+
return _.sortBy(
|
|
490
|
+
omegga.getRoleSetup()?.roles ?? [],
|
|
491
|
+
(p) => p.name.toLowerCase()
|
|
492
|
+
);
|
|
493
|
+
});
|
|
494
|
+
rpc.addMethod(
|
|
495
|
+
"users.list",
|
|
496
|
+
async ([{ page = 0, search = "", sort = "name", direction = "1" } = {}]) => {
|
|
497
|
+
const resp = await database.getUsers({
|
|
498
|
+
page,
|
|
499
|
+
search,
|
|
500
|
+
sort,
|
|
501
|
+
direction
|
|
502
|
+
});
|
|
503
|
+
const now = Date.now();
|
|
504
|
+
resp.users = resp.users.map(({ hash: _2, ...user }) => ({
|
|
505
|
+
...user,
|
|
506
|
+
hash: "",
|
|
507
|
+
seenAgo: user.lastOnline ? now - user.lastOnline : Infinity,
|
|
508
|
+
createdAgo: now - user.created
|
|
509
|
+
}));
|
|
510
|
+
return resp;
|
|
511
|
+
}
|
|
512
|
+
);
|
|
513
|
+
rpc.addMethod(
|
|
514
|
+
"users.create",
|
|
515
|
+
async ([username, password]) => {
|
|
516
|
+
if (!socket.data.user.isOwner) return "missing permission";
|
|
517
|
+
if (typeof username !== "string" || typeof password !== "string")
|
|
518
|
+
return "username/password not a string";
|
|
519
|
+
if (!username.match(/^\w{0,32}$/)) return "username is not allowed";
|
|
520
|
+
if (password.length === 0 || password.length > 128)
|
|
521
|
+
return "invalid password size";
|
|
522
|
+
if (socket.data.user.isOwner && socket.data.user.username === "") {
|
|
523
|
+
try {
|
|
524
|
+
await database.stores.users.update(
|
|
525
|
+
{ _id: socket.data.user._id },
|
|
526
|
+
{
|
|
527
|
+
username,
|
|
528
|
+
hash: await database.hash(password)
|
|
529
|
+
}
|
|
530
|
+
);
|
|
531
|
+
} catch (e) {
|
|
532
|
+
error("error setting owner password", e);
|
|
533
|
+
return "error setting owner password";
|
|
534
|
+
}
|
|
535
|
+
log(`created account as "${username.yellow}"`);
|
|
536
|
+
return "";
|
|
72
537
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
538
|
+
if (await database.userExists(username)) return "user already exists";
|
|
539
|
+
try {
|
|
540
|
+
await database.createUser(username, password);
|
|
541
|
+
} catch (e) {
|
|
542
|
+
error("error creating new user", e);
|
|
543
|
+
return "error creating new user";
|
|
78
544
|
}
|
|
79
|
-
|
|
80
|
-
|
|
545
|
+
log(`created new user "${username.yellow}"`);
|
|
546
|
+
return "";
|
|
547
|
+
}
|
|
548
|
+
);
|
|
549
|
+
rpc.addMethod(
|
|
550
|
+
"users.passwd",
|
|
551
|
+
async ([username, password]) => {
|
|
552
|
+
if (!socket.data.user.isOwner && username !== socket.data.user.username)
|
|
553
|
+
return "missing permission";
|
|
554
|
+
if (typeof username !== "string" || typeof password !== "string")
|
|
555
|
+
return "username/password not a string";
|
|
556
|
+
if (!username.match(/^\w{0,32}$/)) return "username is not allowed";
|
|
557
|
+
if (!await database.userExists(username))
|
|
558
|
+
return "user does not exist";
|
|
559
|
+
try {
|
|
560
|
+
await database.userPasswd(username, password);
|
|
561
|
+
} catch (e) {
|
|
562
|
+
error("error setting user password", e);
|
|
563
|
+
return "error setting user's password";
|
|
81
564
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
565
|
+
log(`changed password for "${username.yellow}"`);
|
|
566
|
+
return "";
|
|
567
|
+
}
|
|
568
|
+
);
|
|
569
|
+
rpc.addMethod("server.autorestart.get", async () => {
|
|
570
|
+
return await database.getAutoRestartConfig();
|
|
571
|
+
});
|
|
572
|
+
const autorestartConfigFields = {
|
|
573
|
+
type: "string",
|
|
574
|
+
maxUptime: "number",
|
|
575
|
+
maxUptimeEnabled: "boolean",
|
|
576
|
+
emptyUptime: "number",
|
|
577
|
+
emptyUptimeEnabled: "boolean",
|
|
578
|
+
dailyHour: "number",
|
|
579
|
+
dailyHourEnabled: "boolean",
|
|
580
|
+
announcementEnabled: "boolean",
|
|
581
|
+
playersEnabled: "boolean",
|
|
582
|
+
saveWorld: "boolean",
|
|
583
|
+
autoUpdateEnabled: "boolean",
|
|
584
|
+
autoUpdateIntervalMins: "number"
|
|
585
|
+
};
|
|
586
|
+
rpc.addMethod(
|
|
587
|
+
"server.autorestart.set",
|
|
588
|
+
async ([config]) => {
|
|
589
|
+
if (typeof config !== "object" || !Object.entries(autorestartConfigFields).every(
|
|
590
|
+
([k, v]) => k in config && typeof config[k] === v && !Number.isNaN(v)
|
|
591
|
+
) || config.type !== "autoRestartConfig")
|
|
592
|
+
return false;
|
|
593
|
+
await database.setAutoRestartConfig(config);
|
|
594
|
+
return true;
|
|
595
|
+
}
|
|
596
|
+
);
|
|
597
|
+
rpc.addMethod("server.status", () => {
|
|
598
|
+
return server.lastReportedStatus;
|
|
599
|
+
});
|
|
600
|
+
rpc.addMethod("server.started", () => {
|
|
601
|
+
return {
|
|
602
|
+
started: omegga.started,
|
|
603
|
+
starting: omegga.starting,
|
|
604
|
+
stopping: omegga.stopping
|
|
605
|
+
};
|
|
606
|
+
});
|
|
607
|
+
rpc.addMethod("server.start", async () => {
|
|
608
|
+
if (omegga.starting || omegga.stopping || omegga.started) return;
|
|
609
|
+
log("Starting server...");
|
|
610
|
+
await omegga.start();
|
|
611
|
+
});
|
|
612
|
+
rpc.addMethod("server.stop", async () => {
|
|
613
|
+
if (omegga.starting || omegga.stopping || !omegga.started) return;
|
|
614
|
+
log("Stopping server...");
|
|
615
|
+
await omegga.stop();
|
|
616
|
+
});
|
|
617
|
+
rpc.addMethod("server.restart", async () => {
|
|
618
|
+
if (omegga.starting || omegga.stopping) return;
|
|
619
|
+
try {
|
|
620
|
+
const config = await database.getAutoRestartConfig();
|
|
621
|
+
await omegga.saveServer({
|
|
622
|
+
players: config.playersEnabled,
|
|
623
|
+
saveWorld: config.saveWorld ?? true,
|
|
624
|
+
announcement: config.announcementEnabled
|
|
625
|
+
});
|
|
626
|
+
} catch (err) {
|
|
627
|
+
error("Error while saving server setup", err);
|
|
628
|
+
}
|
|
629
|
+
database.addChatLog("server", {}, "Restarting in 5 seconds...");
|
|
630
|
+
logger.default.logp("Restarting in 5 seconds...");
|
|
631
|
+
omegga.broadcast(
|
|
632
|
+
`<size="20">Server restart in <b><color="ffffbb">${5} seconds</></></>`
|
|
633
|
+
);
|
|
634
|
+
await new Promise((resolve) => setTimeout(resolve, 5e3));
|
|
635
|
+
await omegga.restartServer();
|
|
636
|
+
});
|
|
637
|
+
rpc.addMethod("server.updatecheck", async () => {
|
|
638
|
+
if (!omegga.config.__STEAM) return null;
|
|
639
|
+
const lastUpdate = steam.getLastSteamUpdateCheck();
|
|
640
|
+
if (Date.now() - lastUpdate.attempt < 1e3 * 5) {
|
|
641
|
+
logger.default.verbose("[rpc] Using cached steam update check");
|
|
642
|
+
return lastUpdate.result;
|
|
643
|
+
}
|
|
644
|
+
logger.default.verbose("[rpc] Checking for steam update");
|
|
645
|
+
return await steam.hasSteamUpdate(omegga.config.server?.steambeta);
|
|
646
|
+
});
|
|
647
|
+
rpc.addMethod("server.update", async () => {
|
|
648
|
+
if (!omegga.config.__STEAM) return false;
|
|
649
|
+
if (omegga.stopping || omegga.starting) return false;
|
|
650
|
+
const wasStarted = omegga.started;
|
|
651
|
+
if (wasStarted) {
|
|
652
|
+
log("Stopping server to update...");
|
|
653
|
+
await omegga.stop();
|
|
654
|
+
}
|
|
655
|
+
log("Updating server...");
|
|
656
|
+
let ok = false;
|
|
657
|
+
try {
|
|
658
|
+
steam.steamcmdDownloadGame({
|
|
659
|
+
steambeta: omegga.config.server?.steambeta,
|
|
660
|
+
steambetaPassword: omegga.config.server?.steambetaPassword
|
|
661
|
+
});
|
|
662
|
+
ok = true;
|
|
663
|
+
log("Server updated successfully");
|
|
664
|
+
} catch (err) {
|
|
665
|
+
error("Error updating server", err);
|
|
666
|
+
}
|
|
667
|
+
if (wasStarted) {
|
|
668
|
+
log("Starting server...");
|
|
669
|
+
await omegga.start();
|
|
670
|
+
}
|
|
671
|
+
return ok;
|
|
672
|
+
});
|
|
673
|
+
rpc.addMethod("world.list", async () => {
|
|
674
|
+
const prefix = omegga.worldPath + "/";
|
|
675
|
+
return omegga.getWorlds().map((world) => world.replace(prefix, "").replace(/\.brdb$/, ""));
|
|
676
|
+
});
|
|
677
|
+
rpc.addMethod("world.revisions", async ([world]) => {
|
|
678
|
+
try {
|
|
679
|
+
return (await omegga.getWorldRevisions(world))?.map(
|
|
680
|
+
({ date, ...r }) => ({ ...r, date: date.getTime() })
|
|
681
|
+
);
|
|
682
|
+
} catch (_err) {
|
|
683
|
+
return null;
|
|
684
|
+
}
|
|
685
|
+
});
|
|
686
|
+
rpc.addMethod("world.meta", async ([world]) => {
|
|
687
|
+
try {
|
|
688
|
+
const path = omegga.getWorldPath(world);
|
|
689
|
+
if (!path) return null;
|
|
690
|
+
return brdb.readBrdbMeta(path);
|
|
691
|
+
} catch (err) {
|
|
692
|
+
error("Error while getting world meta", err);
|
|
693
|
+
return null;
|
|
694
|
+
}
|
|
695
|
+
});
|
|
696
|
+
rpc.addMethod("world.next", async () => {
|
|
697
|
+
return omegga.getNextWorld();
|
|
698
|
+
});
|
|
699
|
+
rpc.addMethod("world.active", async () => {
|
|
700
|
+
return omegga.getActiveWorld();
|
|
701
|
+
});
|
|
702
|
+
rpc.addMethod(
|
|
703
|
+
"world.load",
|
|
704
|
+
async ([world, revision]) => {
|
|
705
|
+
try {
|
|
706
|
+
let res = false;
|
|
707
|
+
if (revision) {
|
|
708
|
+
log("Loading world revision", revision, "of", world.yellow);
|
|
709
|
+
res = await omegga.loadWorldRevision(world, revision);
|
|
710
|
+
} else {
|
|
711
|
+
log("Loading world", world.yellow);
|
|
712
|
+
res = await omegga.loadWorld(world);
|
|
713
|
+
}
|
|
714
|
+
if (res) {
|
|
715
|
+
log("World loaded successfully");
|
|
716
|
+
} else {
|
|
717
|
+
log("World load failed");
|
|
718
|
+
}
|
|
719
|
+
return res;
|
|
720
|
+
} catch (err) {
|
|
721
|
+
error("Error while loading world", err);
|
|
722
|
+
return false;
|
|
86
723
|
}
|
|
87
|
-
|
|
88
|
-
|
|
724
|
+
}
|
|
725
|
+
);
|
|
726
|
+
rpc.addMethod("world.use", async ([world]) => {
|
|
727
|
+
try {
|
|
728
|
+
const ok = omegga.setActiveWorld(world || null);
|
|
729
|
+
if (ok) {
|
|
730
|
+
log("Set default world to", (world || "none").yellow);
|
|
89
731
|
}
|
|
732
|
+
return ok;
|
|
733
|
+
} catch (err) {
|
|
734
|
+
error("Error while using world", err);
|
|
735
|
+
return false;
|
|
736
|
+
}
|
|
90
737
|
});
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
738
|
+
rpc.addMethod(
|
|
739
|
+
"world.create",
|
|
740
|
+
async ([name, level]) => {
|
|
741
|
+
try {
|
|
742
|
+
log(
|
|
743
|
+
"Creating new world",
|
|
744
|
+
name.yellow,
|
|
745
|
+
"with level",
|
|
746
|
+
level?.yellow || "Plate"
|
|
747
|
+
);
|
|
748
|
+
const res = await omegga.createEmptyWorld(name, level);
|
|
749
|
+
if (res) {
|
|
750
|
+
log("World created successfully");
|
|
751
|
+
} else {
|
|
752
|
+
log("World creation failed");
|
|
753
|
+
}
|
|
754
|
+
return res;
|
|
755
|
+
} catch (err) {
|
|
756
|
+
error("Error while creating world", err);
|
|
757
|
+
return false;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
);
|
|
761
|
+
rpc.addMethod("world.save", async ([name]) => {
|
|
762
|
+
try {
|
|
763
|
+
let res = false;
|
|
764
|
+
if (name) {
|
|
765
|
+
log("Saving world as", name.yellow);
|
|
766
|
+
res = await omegga.saveWorldAs(name);
|
|
767
|
+
} else {
|
|
768
|
+
log("Saving current world");
|
|
769
|
+
res = await omegga.saveWorld();
|
|
770
|
+
}
|
|
771
|
+
if (res) {
|
|
772
|
+
log("World saved successfully");
|
|
773
|
+
} else {
|
|
774
|
+
log("World save failed");
|
|
775
|
+
}
|
|
776
|
+
return res;
|
|
777
|
+
} catch (err) {
|
|
778
|
+
error("Error while saving world", err);
|
|
779
|
+
return false;
|
|
780
|
+
}
|
|
96
781
|
});
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
});
|
|
107
|
-
// websocket data
|
|
108
|
-
io.on('connection', socket => {
|
|
109
|
-
// let this user receive messages directed to this user
|
|
110
|
-
socket.join('user:' + socket.data.user._id);
|
|
111
|
-
database.getRoles().then(roles => {
|
|
112
|
-
var _a, _b, _c, _d;
|
|
113
|
-
socket.emit('data', {
|
|
114
|
-
roles,
|
|
115
|
-
version: version_1.VERSION,
|
|
116
|
-
brickadiaVersion: (_a = omegga.version) !== null && _a !== void 0 ? _a : null,
|
|
117
|
-
canLogOut: socket.data.user.username !== '',
|
|
118
|
-
now: Date.now(), // this can be used for the frontend to anticipate drift
|
|
119
|
-
userless: !socket.data.user.username,
|
|
120
|
-
user: {
|
|
121
|
-
username: socket.data.user.username || 'Admin',
|
|
122
|
-
isOwner: socket.data.user.isOwner,
|
|
123
|
-
roles: socket.data.user.roles,
|
|
124
|
-
},
|
|
125
|
-
isSteam: Boolean(omegga.config.__STEAM),
|
|
126
|
-
update: {
|
|
127
|
-
canCheck: omegga.config.__STEAM && !((_b = omegga.config.server) === null || _b === void 0 ? void 0 : _b.steambeta),
|
|
128
|
-
lastCheck: (_d = (_c = (0, steam_1.getLastSteamUpdateCheck)()) === null || _c === void 0 ? void 0 : _c.result) !== null && _d !== void 0 ? _d : null,
|
|
129
|
-
},
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
// logging for this user in the console for web ui actions
|
|
133
|
-
const usernameText = `[${(socket.data.user.username || 'Admin').brightMagenta}]`;
|
|
134
|
-
const log = (...args) => logger_1.default.logp(usernameText, ...args);
|
|
135
|
-
const error = (...args) => logger_1.default.errorp(usernameText, ...args);
|
|
136
|
-
// rpc connection
|
|
137
|
-
const rpcServer = new json_rpc_2_0_1.JSONRPCServer();
|
|
138
|
-
const rpcClient = new json_rpc_2_0_1.JSONRPCClient(async (data) => {
|
|
139
|
-
socket.emit('rpc', data);
|
|
140
|
-
});
|
|
141
|
-
const rpc = new json_rpc_2_0_1.JSONRPCServerAndClient(rpcServer, rpcClient);
|
|
142
|
-
socket.on('rpc', data => {
|
|
143
|
-
if (data && typeof data === 'object') {
|
|
144
|
-
try {
|
|
145
|
-
rpc.receiveAndSend(data);
|
|
146
|
-
}
|
|
147
|
-
catch (e) {
|
|
148
|
-
// silently discard broken rpc requests
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
// send chat message from web ui
|
|
153
|
-
// TODO: check if this user has a role with permission to chat
|
|
154
|
-
rpc.addMethod('chat', async ([message]) => {
|
|
155
|
-
if (typeof message !== 'string')
|
|
156
|
-
return;
|
|
157
|
-
if (message.length > 140)
|
|
158
|
-
message = message.slice(0, 140);
|
|
159
|
-
// create fake user
|
|
160
|
-
const user = {
|
|
161
|
-
name: socket.data.user.username || 'Admin',
|
|
162
|
-
id: socket.data.user.playerId,
|
|
163
|
-
color: 'ff00ff',
|
|
164
|
-
web: true,
|
|
165
|
-
};
|
|
166
|
-
// create database entry, send to web ui
|
|
167
|
-
io.to('chat').emit('chat', await database.addChatLog('msg', user, message));
|
|
168
|
-
// broadcast to chat
|
|
169
|
-
omegga.broadcast(`"[<b><color=\\"ff00ff\\">${user.name}</></>]: ${(0, chat_1.parseLinks)((0, chat_1.sanitize)(message))}"`);
|
|
170
|
-
// broadcast to terminal
|
|
171
|
-
logger_1.default.log(`[${user.name.brightMagenta.underline}]: ${message}`);
|
|
172
|
-
return 'ok';
|
|
173
|
-
});
|
|
174
|
-
// read recent chat messages
|
|
175
|
-
// TODO: add permission check
|
|
176
|
-
rpc.addMethod('chat.recent', () => {
|
|
177
|
-
return database.getChats({ sameServer: true });
|
|
178
|
-
});
|
|
179
|
-
// find chat messages after a certain time
|
|
180
|
-
// TODO: add permission check
|
|
181
|
-
rpc.addMethod('chat.history', ([{ after, before }] = [{}]) => {
|
|
182
|
-
return database.getChats({ after, before });
|
|
183
|
-
});
|
|
184
|
-
// see what days chat messages were sent
|
|
185
|
-
// TODO: add permission check
|
|
186
|
-
rpc.addMethod('chat.calendar', () => {
|
|
187
|
-
return database.calendar.years;
|
|
188
|
-
});
|
|
189
|
-
// get the list of plugins
|
|
190
|
-
// TODO: add permission check
|
|
191
|
-
rpc.addMethod('plugins.list', () => {
|
|
192
|
-
return lodash_1.default.sortBy(omegga.pluginLoader.plugins.map(p => ({
|
|
193
|
-
name: p.getName(),
|
|
194
|
-
documentation: p.getDocumentation(),
|
|
195
|
-
path: p.shortPath,
|
|
196
|
-
isLoaded: p.isLoaded(),
|
|
197
|
-
isEnabled: p.isEnabled(),
|
|
198
|
-
})), p => p.name.toLowerCase());
|
|
199
|
-
});
|
|
200
|
-
// get information on a specific plugin
|
|
201
|
-
// TODO: add permission check
|
|
202
|
-
rpc.addMethod('plugin.get', async ([shortPath]) => {
|
|
203
|
-
const plugin = omegga.pluginLoader.plugins.find(p => p.shortPath === shortPath);
|
|
204
|
-
if (!plugin)
|
|
205
|
-
return null;
|
|
206
|
-
// get the plugin configs
|
|
207
|
-
const [defaultConfig, config, objCount] = await Promise.all([
|
|
208
|
-
plugin.storage.getDefaultConfig(),
|
|
209
|
-
plugin.storage.getConfig(),
|
|
210
|
-
plugin.storage.count(),
|
|
211
|
-
]);
|
|
212
|
-
return {
|
|
213
|
-
name: plugin.getName(),
|
|
214
|
-
format: plugin.constructor.getFormat(),
|
|
215
|
-
info: plugin.getInfo(),
|
|
216
|
-
documentation: plugin.getDocumentation(),
|
|
217
|
-
config,
|
|
218
|
-
defaultConfig,
|
|
219
|
-
objCount,
|
|
220
|
-
path: plugin.shortPath,
|
|
221
|
-
isLoaded: plugin.isLoaded(),
|
|
222
|
-
isEnabled: plugin.isEnabled(),
|
|
223
|
-
};
|
|
224
|
-
});
|
|
225
|
-
// get a paginated list of players
|
|
226
|
-
// TODO: add permission check
|
|
227
|
-
rpc.addMethod('players.list', async ([{ page = 0, search = '', sort = 'name', direction = '1', filter = '', } = {},]) => {
|
|
228
|
-
const banList = (omegga.getBanList() || { banList: {} }).banList;
|
|
229
|
-
// get the ban list
|
|
230
|
-
const now = Date.now();
|
|
231
|
-
let limitId;
|
|
232
|
-
// if the filter is set to banned players only, limit player results by ids in the current ban list
|
|
233
|
-
if (filter === 'banned') {
|
|
234
|
-
limitId = Object.keys(banList).filter(b => banList[b].expires <= banList[b].created ||
|
|
235
|
-
(0, time_1.parseBrickadiaTime)(banList[b].expires) > Date.now());
|
|
236
|
-
}
|
|
237
|
-
const resp = await database.getPlayers({
|
|
238
|
-
page,
|
|
239
|
-
search,
|
|
240
|
-
sort,
|
|
241
|
-
direction,
|
|
242
|
-
limitId,
|
|
243
|
-
});
|
|
244
|
-
for (const player of resp.players) {
|
|
245
|
-
player.seenAgo = now - player.lastSeen;
|
|
246
|
-
player.createdAgo = now - player.created;
|
|
247
|
-
const foundBan = banList[player.id];
|
|
248
|
-
if (foundBan) {
|
|
249
|
-
const created = (0, time_1.parseBrickadiaTime)(foundBan.created);
|
|
250
|
-
const expires = (0, time_1.parseBrickadiaTime)(foundBan.expires);
|
|
251
|
-
// create a clone of the object
|
|
252
|
-
let currentBan = {
|
|
253
|
-
...foundBan,
|
|
254
|
-
// parse the times in the current ban
|
|
255
|
-
created,
|
|
256
|
-
expires,
|
|
257
|
-
duration: expires - created,
|
|
258
|
-
remainingTime: expires - now,
|
|
259
|
-
// lookup banner name
|
|
260
|
-
bannerName: lodash_1.default.get(omegga.getNameCache(), ['savedPlayerNames', foundBan.bannerId], ''),
|
|
261
|
-
};
|
|
262
|
-
// if the ban is expired, it should not be listed
|
|
263
|
-
if (currentBan.expires < now && currentBan.duration > 0)
|
|
264
|
-
currentBan = null;
|
|
265
|
-
player.ban = currentBan;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
return resp;
|
|
269
|
-
});
|
|
270
|
-
// get a specific player's info
|
|
271
|
-
// TODO: add permission check
|
|
272
|
-
rpc.addMethod('player.get', async ([id]) => {
|
|
273
|
-
var _a;
|
|
274
|
-
const entry = await database.getPlayer(id);
|
|
275
|
-
if (!entry)
|
|
276
|
-
return null;
|
|
277
|
-
const now = Date.now();
|
|
278
|
-
entry.seenAgo = now - entry.lastSeen;
|
|
279
|
-
entry.createdAgo = now - entry.created;
|
|
280
|
-
for (const n of entry.nameHistory)
|
|
281
|
-
n.ago = now - n.date;
|
|
282
|
-
// combine player roles with server roles
|
|
283
|
-
const playerRoles = player_1.default.getRoles(omegga, id) || [];
|
|
284
|
-
const { roles: serverRoles = [] } = (_a = omegga.getRoleSetup()) !== null && _a !== void 0 ? _a : {};
|
|
285
|
-
// Get banner name and duration from list of bans
|
|
286
|
-
for (const b of entry.banHistory) {
|
|
287
|
-
b.duration = b.expires - b.created;
|
|
288
|
-
// lookup banner name
|
|
289
|
-
b.bannerName = lodash_1.default.get(omegga.getNameCache(), ['savedPlayerNames', b.bannerId], '');
|
|
290
|
-
}
|
|
291
|
-
// Get kicker name from list of kicks
|
|
292
|
-
for (const b of entry.kickHistory) {
|
|
293
|
-
// lookup banner name
|
|
294
|
-
b.kickerName = lodash_1.default.get(omegga.getNameCache(), ['savedPlayerNames', b.kickerId], '');
|
|
295
|
-
}
|
|
296
|
-
const foundBan = (omegga.getBanList() || { banList: {} }).banList[id];
|
|
297
|
-
let currentBan = null;
|
|
298
|
-
if (foundBan) {
|
|
299
|
-
// parse the times in the current ban
|
|
300
|
-
const created = (0, time_1.parseBrickadiaTime)(foundBan.created);
|
|
301
|
-
const expires = (0, time_1.parseBrickadiaTime)(foundBan.expires);
|
|
302
|
-
// create a clone of the object
|
|
303
|
-
currentBan = {
|
|
304
|
-
...foundBan,
|
|
305
|
-
created,
|
|
306
|
-
expires,
|
|
307
|
-
duration: expires - created,
|
|
308
|
-
remainingTime: expires - now,
|
|
309
|
-
// lookup banner name
|
|
310
|
-
bannerName: lodash_1.default.get(omegga.getNameCache(), ['savedPlayerNames', foundBan.bannerId], ''),
|
|
311
|
-
};
|
|
312
|
-
// if the ban is expired, it should not be listed
|
|
313
|
-
if (currentBan.expires < now && currentBan.duration > 0)
|
|
314
|
-
currentBan = null;
|
|
315
|
-
}
|
|
316
|
-
return {
|
|
317
|
-
// database results
|
|
318
|
-
...entry,
|
|
319
|
-
// player is host
|
|
320
|
-
isHost: omegga.getHostId() === id,
|
|
321
|
-
isOnline: omegga.players.some(p => p.id === id),
|
|
322
|
-
// player's current ban state
|
|
323
|
-
currentBan,
|
|
324
|
-
// all player's roles w/ colors
|
|
325
|
-
roles: playerRoles.map(r => {
|
|
326
|
-
// default role color is white
|
|
327
|
-
let color = 'ffffff';
|
|
328
|
-
// find the role (if it exists) and get the color
|
|
329
|
-
const role = serverRoles.find(sr => sr.name.toLowerCase() === r.toLowerCase());
|
|
330
|
-
if (role && role.bHasColor)
|
|
331
|
-
color = (0, color_1.rgbToHex)(role.color);
|
|
332
|
-
return {
|
|
333
|
-
name: r,
|
|
334
|
-
color: color,
|
|
335
|
-
};
|
|
336
|
-
}),
|
|
337
|
-
};
|
|
338
|
-
});
|
|
339
|
-
rpc.addMethod('player.ban', async ([id, duration = -1, reason = 'No Reason']) => {
|
|
340
|
-
var _a, _b, _c;
|
|
341
|
-
// validate inputs
|
|
342
|
-
if (typeof duration !== 'number')
|
|
343
|
-
return false;
|
|
344
|
-
if (typeof id !== 'string' || !uuid.match(id))
|
|
345
|
-
return false;
|
|
346
|
-
if (typeof reason !== 'string' || reason.length > 128)
|
|
347
|
-
return false;
|
|
348
|
-
reason = reason.replace(/\n/g, ' ').replace(/"/g, "'");
|
|
349
|
-
log('Banning player', (_c = (_b = (_a = omegga.getNameCache()) === null || _a === void 0 ? void 0 : _a.savedPlayerNames) === null || _b === void 0 ? void 0 : _b[id].yellow) !== null && _c !== void 0 ? _c : 'with id ' + id.yellow);
|
|
350
|
-
// ban the user
|
|
351
|
-
omegga.writeln(`Chat.Command /Ban "${id}" ${duration} "${reason}"`);
|
|
352
|
-
let listener;
|
|
353
|
-
// wait for the ban to update
|
|
354
|
-
const ok = await Promise.race([
|
|
355
|
-
new Promise(resolve => {
|
|
356
|
-
database.on('update.bans', (listener = () => {
|
|
357
|
-
const banList = (omegga.getBanList() || { banList: {} })
|
|
358
|
-
.banList;
|
|
359
|
-
if (banList[id]) {
|
|
360
|
-
const entry = {
|
|
361
|
-
type: 'banHistory',
|
|
362
|
-
banned: id,
|
|
363
|
-
bannerId: null,
|
|
364
|
-
created: (0, time_1.parseBrickadiaTime)(banList[id].created),
|
|
365
|
-
expires: (0, time_1.parseBrickadiaTime)(banList[id].expires),
|
|
366
|
-
reason: banList[id].reason,
|
|
367
|
-
};
|
|
368
|
-
database.stores.players.update(entry, { $set: entry }, { upsert: true });
|
|
369
|
-
resolve(true);
|
|
370
|
-
}
|
|
371
|
-
}));
|
|
372
|
-
}),
|
|
373
|
-
new Promise(resolve => setTimeout(() => resolve(false), 5000)),
|
|
374
|
-
]);
|
|
375
|
-
database.off('update.bans', listener);
|
|
376
|
-
return ok;
|
|
377
|
-
});
|
|
378
|
-
rpc.addMethod('player.kick', async ([id, reason = 'No Reason']) => {
|
|
379
|
-
// validate inputs
|
|
380
|
-
if (typeof id !== 'string' || !uuid.match(id))
|
|
381
|
-
return false;
|
|
382
|
-
if (typeof reason !== 'string' || reason.length > 128)
|
|
383
|
-
return false;
|
|
384
|
-
reason = reason.replace(/\n/g, ' ').replace(/"/g, "'");
|
|
385
|
-
// ensure player exists
|
|
386
|
-
const player = omegga.players.find(p => p.id === id);
|
|
387
|
-
if (!player)
|
|
388
|
-
return false;
|
|
389
|
-
log('Kicking player', player.name.yellow);
|
|
390
|
-
// kick the user
|
|
391
|
-
omegga.writeln(`Chat.Command /Kick "${id}" "${reason}"`);
|
|
392
|
-
// wait for the player to disconnect
|
|
393
|
-
const ok = await Promise.race([
|
|
394
|
-
new Promise(resolve => {
|
|
395
|
-
omegga.once('leave', async (leavingPlayer) => {
|
|
396
|
-
if (leavingPlayer.id === id) {
|
|
397
|
-
resolve(true);
|
|
398
|
-
// add kick to database
|
|
399
|
-
const entry = {
|
|
400
|
-
type: 'kickHistory',
|
|
401
|
-
kicked: id,
|
|
402
|
-
kickerId: null,
|
|
403
|
-
created: Date.now(),
|
|
404
|
-
reason,
|
|
405
|
-
};
|
|
406
|
-
await database.stores.players.update(entry, { $set: entry }, { upsert: true });
|
|
407
|
-
}
|
|
408
|
-
});
|
|
409
|
-
}),
|
|
410
|
-
new Promise(resolve => setTimeout(() => resolve(false), 5000)),
|
|
411
|
-
]);
|
|
412
|
-
return ok;
|
|
413
|
-
});
|
|
414
|
-
rpc.addMethod('player.unban', async ([id]) => {
|
|
415
|
-
var _a, _b, _c;
|
|
416
|
-
// validate inputs
|
|
417
|
-
if (typeof id !== 'string' || !uuid.match(id))
|
|
418
|
-
return false;
|
|
419
|
-
// check if user is banned
|
|
420
|
-
const banList = (omegga.getBanList() || { banList: {} }).banList;
|
|
421
|
-
if (!banList[id])
|
|
422
|
-
return false;
|
|
423
|
-
log('Unbanning player', (_c = (_b = (_a = omegga.getNameCache()) === null || _a === void 0 ? void 0 : _a.savedPlayerNames) === null || _b === void 0 ? void 0 : _b[id].yellow) !== null && _c !== void 0 ? _c : 'with id ' + id.yellow);
|
|
424
|
-
// unban the user
|
|
425
|
-
omegga.writeln(`Chat.Command /Unban "${id}"`);
|
|
426
|
-
let listener;
|
|
427
|
-
// wait for the ban to update
|
|
428
|
-
const ok = await Promise.race([
|
|
429
|
-
new Promise(resolve => {
|
|
430
|
-
database.on('update.bans', (listener = () => {
|
|
431
|
-
const banList = (omegga.getBanList() || { banList: {} }).banList;
|
|
432
|
-
if (!banList[id] ||
|
|
433
|
-
(0, time_1.parseBrickadiaTime)(banList[id].expires) < Date.now())
|
|
434
|
-
resolve(true);
|
|
435
|
-
}));
|
|
436
|
-
}),
|
|
437
|
-
new Promise(resolve => setTimeout(() => resolve(false), 5000)),
|
|
438
|
-
]);
|
|
439
|
-
database.off('update.bans', listener);
|
|
440
|
-
return ok;
|
|
441
|
-
});
|
|
442
|
-
rpc.addMethod('player.clearbricks', async ([id]) => {
|
|
443
|
-
var _a, _b, _c, _d;
|
|
444
|
-
// validate inputs
|
|
445
|
-
if (typeof id !== 'string' || !uuid.match(id))
|
|
446
|
-
return false;
|
|
447
|
-
log('Clearing bricks for player', (_d = (_c = (_b = (_a = omegga.getNameCache()) === null || _a === void 0 ? void 0 : _a.savedPlayerNames) === null || _b === void 0 ? void 0 : _b[id]) === null || _c === void 0 ? void 0 : _c.yellow) !== null && _d !== void 0 ? _d : 'with id ' + id.yellow);
|
|
448
|
-
// unban the user
|
|
449
|
-
omegga.writeln(`Bricks.Clear "${id}"`);
|
|
450
|
-
return true;
|
|
451
|
-
});
|
|
452
|
-
// set plugin config
|
|
453
|
-
// TODO: add permission check
|
|
454
|
-
rpc.addMethod('plugin.config', async ([shortPath, config]) => {
|
|
455
|
-
const plugin = omegga.pluginLoader.plugins.find(p => p.shortPath === shortPath);
|
|
456
|
-
if (!plugin)
|
|
457
|
-
return null;
|
|
458
|
-
await plugin.storage.setConfig(config);
|
|
459
|
-
// TODO: validate configs
|
|
460
|
-
return true;
|
|
461
|
-
});
|
|
462
|
-
// reload all plugins (and scan for new ones)
|
|
463
|
-
// TODO: add permission check
|
|
464
|
-
rpc.addMethod('plugins.reload', async () => {
|
|
465
|
-
if (!omegga.pluginLoader) {
|
|
466
|
-
error('Omegga is not using plugins');
|
|
467
|
-
return false;
|
|
468
|
-
}
|
|
469
|
-
log('Unloading current plugins');
|
|
470
|
-
let success = await omegga.pluginLoader.unload();
|
|
471
|
-
if (!success) {
|
|
472
|
-
error('Could not unload all plugins');
|
|
473
|
-
return false;
|
|
474
|
-
}
|
|
475
|
-
log('Scanning for new plugins');
|
|
476
|
-
success = await omegga.pluginLoader.scan();
|
|
477
|
-
if (!success) {
|
|
478
|
-
error('Could not scan for plugins');
|
|
479
|
-
return false;
|
|
480
|
-
}
|
|
481
|
-
log('Starting plugins');
|
|
482
|
-
success = await omegga.pluginLoader.reload();
|
|
483
|
-
if (success) {
|
|
484
|
-
const plugins = omegga.pluginLoader.plugins
|
|
485
|
-
.filter(p => p.isLoaded())
|
|
486
|
-
.map(p => p.getName());
|
|
487
|
-
log('Loaded', (plugins.length + '').yellow, 'plugins:', plugins);
|
|
488
|
-
return true;
|
|
489
|
-
}
|
|
490
|
-
else {
|
|
491
|
-
error('Could not load all plugins');
|
|
492
|
-
return false;
|
|
493
|
-
}
|
|
494
|
-
});
|
|
495
|
-
// unload a plugin
|
|
496
|
-
// TODO: add permission check
|
|
497
|
-
rpc.addMethod('plugin.unload', async ([shortPath]) => {
|
|
498
|
-
const plugin = omegga.pluginLoader.plugins.find(p => p.shortPath === shortPath);
|
|
499
|
-
if (!plugin)
|
|
500
|
-
return false;
|
|
501
|
-
if (!plugin.isLoaded())
|
|
502
|
-
return false;
|
|
503
|
-
log('Unloading'.red, 'plugin', plugin.getName().yellow);
|
|
504
|
-
return await plugin.unload();
|
|
505
|
-
});
|
|
506
|
-
// load a plugin
|
|
507
|
-
// TODO: add permission check
|
|
508
|
-
rpc.addMethod('plugin.load', async ([shortPath]) => {
|
|
509
|
-
const plugin = omegga.pluginLoader.plugins.find(p => p.shortPath === shortPath);
|
|
510
|
-
if (!plugin)
|
|
511
|
-
return false;
|
|
512
|
-
if (plugin.isLoaded() || !plugin.isEnabled())
|
|
513
|
-
return false;
|
|
514
|
-
log('Loading'.green, 'plugin', plugin.getName().yellow);
|
|
515
|
-
return await plugin.load();
|
|
516
|
-
});
|
|
517
|
-
// enable/disable a plugin
|
|
518
|
-
// TODO: add permission check
|
|
519
|
-
rpc.addMethod('plugin.toggle', ([shortPath, enabled]) => {
|
|
520
|
-
if (typeof enabled !== 'boolean')
|
|
521
|
-
return;
|
|
522
|
-
const plugin = omegga.pluginLoader.plugins.find(p => p.shortPath === shortPath);
|
|
523
|
-
if (!plugin)
|
|
524
|
-
return false;
|
|
525
|
-
try {
|
|
526
|
-
plugin.setEnabled(enabled);
|
|
527
|
-
log(enabled ? 'Enabled'.green : 'Disabled'.red, 'plugin', plugin.getName().yellow);
|
|
528
|
-
return true;
|
|
529
|
-
}
|
|
530
|
-
catch (e) {
|
|
531
|
-
error('Error', enabled ? 'enabling'.green : 'disabling'.red, 'plugin', plugin.getName().yellow);
|
|
532
|
-
return false;
|
|
533
|
-
}
|
|
534
|
-
});
|
|
535
|
-
// get a list of roles
|
|
536
|
-
// TODO: add permission check
|
|
537
|
-
rpc.addMethod('roles.list', () => {
|
|
538
|
-
var _a, _b;
|
|
539
|
-
return lodash_1.default.sortBy((_b = (_a = omegga.getRoleSetup()) === null || _a === void 0 ? void 0 : _a.roles) !== null && _b !== void 0 ? _b : [], p => p.name.toLowerCase());
|
|
540
|
-
});
|
|
541
|
-
// get a paginated list of users
|
|
542
|
-
// TODO: add permission check
|
|
543
|
-
rpc.addMethod('users.list', async ([{ page = 0, search = '', sort = 'name', direction = '1' } = {}]) => {
|
|
544
|
-
const resp = await database.getUsers({
|
|
545
|
-
page,
|
|
546
|
-
search,
|
|
547
|
-
sort,
|
|
548
|
-
direction,
|
|
549
|
-
});
|
|
550
|
-
const now = Date.now();
|
|
551
|
-
resp.users = resp.users.map(({ hash: _, ...user }) => ({
|
|
552
|
-
...user,
|
|
553
|
-
hash: '',
|
|
554
|
-
seenAgo: user.lastOnline ? now - user.lastOnline : Infinity,
|
|
555
|
-
createdAgo: now - user.created,
|
|
556
|
-
}));
|
|
557
|
-
return resp;
|
|
558
|
-
});
|
|
559
|
-
// create a new user (host only at the moment)
|
|
560
|
-
// TODO: add permission check
|
|
561
|
-
rpc.addMethod('users.create', async ([username, password]) => {
|
|
562
|
-
if (!socket.data.user.isOwner)
|
|
563
|
-
return 'missing permission';
|
|
564
|
-
// body is username and password
|
|
565
|
-
if (typeof username !== 'string' || typeof password !== 'string')
|
|
566
|
-
return 'username/password not a string';
|
|
567
|
-
// validate username
|
|
568
|
-
if (!username.match(/^\w{0,32}$/))
|
|
569
|
-
return 'username is not allowed';
|
|
570
|
-
// this validation is here for _those_ people
|
|
571
|
-
if (password.length === 0 || password.length > 128)
|
|
572
|
-
return 'invalid password size';
|
|
573
|
-
// set owner's credential as the first user
|
|
574
|
-
if (socket.data.user.isOwner && socket.data.user.username === '') {
|
|
575
|
-
// set the owner's username and password
|
|
576
|
-
try {
|
|
577
|
-
await database.stores.users.update({ _id: socket.data.user._id }, {
|
|
578
|
-
username,
|
|
579
|
-
hash: await database.hash(password),
|
|
580
|
-
});
|
|
581
|
-
}
|
|
582
|
-
catch (e) {
|
|
583
|
-
error('error setting owner password', e);
|
|
584
|
-
return 'error setting owner password';
|
|
585
|
-
}
|
|
586
|
-
log(`created account as "${username.yellow}"`);
|
|
587
|
-
// update
|
|
588
|
-
return '';
|
|
589
|
-
}
|
|
590
|
-
// check if user exists
|
|
591
|
-
if (await database.userExists(username))
|
|
592
|
-
return 'user already exists';
|
|
593
|
-
try {
|
|
594
|
-
await database.createUser(username, password);
|
|
595
|
-
}
|
|
596
|
-
catch (e) {
|
|
597
|
-
error('error creating new user', e);
|
|
598
|
-
return 'error creating new user';
|
|
599
|
-
}
|
|
600
|
-
log(`created new user "${username.yellow}"`);
|
|
601
|
-
return '';
|
|
602
|
-
});
|
|
603
|
-
// change a user's password
|
|
604
|
-
// TODO: add permission check
|
|
605
|
-
rpc.addMethod('users.passwd', async ([username, password]) => {
|
|
606
|
-
// the owner can change names and the user can change their own name
|
|
607
|
-
if (!socket.data.user.isOwner && username !== socket.data.user.username)
|
|
608
|
-
return 'missing permission';
|
|
609
|
-
// body is username and password
|
|
610
|
-
if (typeof username !== 'string' || typeof password !== 'string')
|
|
611
|
-
return 'username/password not a string';
|
|
612
|
-
// validate username
|
|
613
|
-
if (!username.match(/^\w{0,32}$/))
|
|
614
|
-
return 'username is not allowed';
|
|
615
|
-
// check if user exists
|
|
616
|
-
if (!(await database.userExists(username)))
|
|
617
|
-
return 'user does not exist';
|
|
618
|
-
try {
|
|
619
|
-
await database.userPasswd(username, password);
|
|
620
|
-
}
|
|
621
|
-
catch (e) {
|
|
622
|
-
error('error setting user password', e);
|
|
623
|
-
return "error setting user's password";
|
|
624
|
-
}
|
|
625
|
-
log(`changed password for "${username.yellow}"`);
|
|
626
|
-
return '';
|
|
627
|
-
});
|
|
628
|
-
rpc.addMethod('server.autorestart.get', async () => {
|
|
629
|
-
return await database.getAutoRestartConfig();
|
|
630
|
-
});
|
|
631
|
-
const autorestartConfigFields = {
|
|
632
|
-
type: 'string',
|
|
633
|
-
maxUptime: 'number',
|
|
634
|
-
maxUptimeEnabled: 'boolean',
|
|
635
|
-
emptyUptime: 'number',
|
|
636
|
-
emptyUptimeEnabled: 'boolean',
|
|
637
|
-
dailyHour: 'number',
|
|
638
|
-
dailyHourEnabled: 'boolean',
|
|
639
|
-
announcementEnabled: 'boolean',
|
|
640
|
-
playersEnabled: 'boolean',
|
|
641
|
-
saveWorld: 'boolean',
|
|
642
|
-
autoUpdateEnabled: 'boolean',
|
|
643
|
-
autoUpdateIntervalMins: 'number',
|
|
644
|
-
};
|
|
645
|
-
rpc.addMethod('server.autorestart.set', async ([config]) => {
|
|
646
|
-
// validate the autorestart config
|
|
647
|
-
if (typeof config !== 'object' ||
|
|
648
|
-
!Object.entries(autorestartConfigFields).every(([k, v]) => k in config && typeof config[k] === v && !Number.isNaN(v)) ||
|
|
649
|
-
config.type !== 'autoRestartConfig')
|
|
650
|
-
return false;
|
|
651
|
-
await database.setAutoRestartConfig(config);
|
|
652
|
-
return true;
|
|
653
|
-
});
|
|
654
|
-
// send server status at request
|
|
655
|
-
// TODO: server status permission check
|
|
656
|
-
rpc.addMethod('server.status', () => {
|
|
657
|
-
return server.lastReportedStatus;
|
|
658
|
-
});
|
|
659
|
-
// get server run status
|
|
660
|
-
// TODO: server status permission check
|
|
661
|
-
rpc.addMethod('server.started', () => {
|
|
662
|
-
return {
|
|
663
|
-
started: omegga.started,
|
|
664
|
-
starting: omegga.starting,
|
|
665
|
-
stopping: omegga.stopping,
|
|
666
|
-
};
|
|
667
|
-
});
|
|
668
|
-
// start the server if it's not already started
|
|
669
|
-
// TODO: server status permission check
|
|
670
|
-
rpc.addMethod('server.start', async () => {
|
|
671
|
-
if (omegga.starting || omegga.stopping || omegga.started)
|
|
672
|
-
return;
|
|
673
|
-
log('Starting server...');
|
|
674
|
-
await omegga.start();
|
|
675
|
-
});
|
|
676
|
-
// stop the server if it's not already stopped
|
|
677
|
-
// TODO: server status permission check
|
|
678
|
-
rpc.addMethod('server.stop', async () => {
|
|
679
|
-
if (omegga.starting || omegga.stopping || !omegga.started)
|
|
680
|
-
return;
|
|
681
|
-
log('Stopping server...');
|
|
682
|
-
await omegga.stop();
|
|
683
|
-
});
|
|
684
|
-
// restart the server if it's running, start the server if it's stopped
|
|
685
|
-
// TODO: server status permission check
|
|
686
|
-
rpc.addMethod('server.restart', async () => {
|
|
687
|
-
var _a;
|
|
688
|
-
if (omegga.starting || omegga.stopping)
|
|
689
|
-
return;
|
|
690
|
-
try {
|
|
691
|
-
const config = await database.getAutoRestartConfig();
|
|
692
|
-
await omegga.saveServer({
|
|
693
|
-
players: config.playersEnabled,
|
|
694
|
-
saveWorld: (_a = config.saveWorld) !== null && _a !== void 0 ? _a : true,
|
|
695
|
-
announcement: config.announcementEnabled,
|
|
696
|
-
});
|
|
697
|
-
}
|
|
698
|
-
catch (err) {
|
|
699
|
-
error('Error while saving server setup', err);
|
|
700
|
-
}
|
|
701
|
-
database.addChatLog('server', {}, 'Restarting in 5 seconds...');
|
|
702
|
-
logger_1.default.logp('Restarting in 5 seconds...');
|
|
703
|
-
omegga.broadcast(`<size="20">Server restart in <b><color="ffffbb">${5} seconds</></></>`);
|
|
704
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
705
|
-
await omegga.restartServer();
|
|
706
|
-
});
|
|
707
|
-
// check if the server has a steam update available
|
|
708
|
-
rpc.addMethod('server.updatecheck', async () => {
|
|
709
|
-
var _a;
|
|
710
|
-
if (!omegga.config.__STEAM)
|
|
711
|
-
return null;
|
|
712
|
-
const lastUpdate = (0, steam_1.getLastSteamUpdateCheck)();
|
|
713
|
-
if (Date.now() - lastUpdate.attempt < 1000 * 5) {
|
|
714
|
-
logger_1.default.verbose('[rpc] Using cached steam update check');
|
|
715
|
-
return lastUpdate.result;
|
|
716
|
-
}
|
|
717
|
-
logger_1.default.verbose('[rpc] Checking for steam update');
|
|
718
|
-
return await (0, steam_1.hasSteamUpdate)((_a = omegga.config.server) === null || _a === void 0 ? void 0 : _a.steambeta);
|
|
719
|
-
});
|
|
720
|
-
// check if the server has a steam update available
|
|
721
|
-
rpc.addMethod('server.update', async () => {
|
|
722
|
-
var _a, _b;
|
|
723
|
-
if (!omegga.config.__STEAM)
|
|
724
|
-
return false;
|
|
725
|
-
if (omegga.stopping || omegga.starting)
|
|
726
|
-
return false;
|
|
727
|
-
const wasStarted = omegga.started;
|
|
728
|
-
if (wasStarted) {
|
|
729
|
-
log('Stopping server to update...');
|
|
730
|
-
await omegga.stop();
|
|
731
|
-
}
|
|
732
|
-
log('Updating server...');
|
|
733
|
-
let ok = false;
|
|
734
|
-
try {
|
|
735
|
-
(0, updater_1.steamcmdDownloadGame)({
|
|
736
|
-
steambeta: (_a = omegga.config.server) === null || _a === void 0 ? void 0 : _a.steambeta,
|
|
737
|
-
steambetaPassword: (_b = omegga.config.server) === null || _b === void 0 ? void 0 : _b.steambetaPassword,
|
|
738
|
-
});
|
|
739
|
-
ok = true;
|
|
740
|
-
log('Server updated successfully');
|
|
741
|
-
}
|
|
742
|
-
catch (err) {
|
|
743
|
-
error('Error updating server', err);
|
|
744
|
-
}
|
|
745
|
-
if (wasStarted) {
|
|
746
|
-
log('Starting server...');
|
|
747
|
-
await omegga.start();
|
|
748
|
-
}
|
|
749
|
-
return ok;
|
|
750
|
-
});
|
|
751
|
-
// list available worlds
|
|
752
|
-
rpc.addMethod('world.list', async () => {
|
|
753
|
-
const prefix = omegga.worldPath + '/';
|
|
754
|
-
return omegga
|
|
755
|
-
.getWorlds()
|
|
756
|
-
.map(world => world.replace(prefix, '').replace(/\.brdb$/, ''));
|
|
757
|
-
});
|
|
758
|
-
// list a world's revisions (while the server is running)
|
|
759
|
-
rpc.addMethod('world.revisions', async ([world]) => {
|
|
760
|
-
var _a;
|
|
761
|
-
try {
|
|
762
|
-
return (_a = (await omegga.getWorldRevisions(world))) === null || _a === void 0 ? void 0 : _a.map(({ date, ...r }) => ({ ...r, date: date.getTime() }));
|
|
763
|
-
}
|
|
764
|
-
catch (_err) {
|
|
765
|
-
return null;
|
|
766
|
-
}
|
|
767
|
-
});
|
|
768
|
-
rpc.addMethod('world.meta', async ([world]) => {
|
|
769
|
-
try {
|
|
770
|
-
const path = omegga.getWorldPath(world);
|
|
771
|
-
if (!path)
|
|
772
|
-
return null;
|
|
773
|
-
return (0, brdb_1.readBrdbMeta)(path);
|
|
774
|
-
}
|
|
775
|
-
catch (err) {
|
|
776
|
-
error('Error while getting world meta', err);
|
|
777
|
-
return null;
|
|
778
|
-
}
|
|
779
|
-
});
|
|
780
|
-
// get the next world to load
|
|
781
|
-
rpc.addMethod('world.next', async () => {
|
|
782
|
-
return omegga.getNextWorld();
|
|
783
|
-
});
|
|
784
|
-
// get the configured default world
|
|
785
|
-
rpc.addMethod('world.active', async () => {
|
|
786
|
-
return omegga.getActiveWorld();
|
|
787
|
-
});
|
|
788
|
-
// load a world or revision of a world
|
|
789
|
-
rpc.addMethod('world.load', async ([world, revision]) => {
|
|
790
|
-
try {
|
|
791
|
-
let res = false;
|
|
792
|
-
if (revision) {
|
|
793
|
-
log('Loading world revision', revision, 'of', world.yellow);
|
|
794
|
-
res = await omegga.loadWorldRevision(world, revision);
|
|
795
|
-
}
|
|
796
|
-
else {
|
|
797
|
-
log('Loading world', world.yellow);
|
|
798
|
-
res = await omegga.loadWorld(world);
|
|
799
|
-
}
|
|
800
|
-
if (res) {
|
|
801
|
-
log('World loaded successfully');
|
|
802
|
-
}
|
|
803
|
-
else {
|
|
804
|
-
log('World load failed');
|
|
805
|
-
}
|
|
806
|
-
return res;
|
|
807
|
-
}
|
|
808
|
-
catch (err) {
|
|
809
|
-
error('Error while loading world', err);
|
|
810
|
-
return false;
|
|
811
|
-
}
|
|
812
|
-
});
|
|
813
|
-
/// set or clear the default world
|
|
814
|
-
rpc.addMethod('world.use', async ([world]) => {
|
|
815
|
-
try {
|
|
816
|
-
const ok = omegga.setActiveWorld(world || null);
|
|
817
|
-
if (ok) {
|
|
818
|
-
log('Set default world to', (world || 'none').yellow);
|
|
819
|
-
}
|
|
820
|
-
return ok;
|
|
821
|
-
}
|
|
822
|
-
catch (err) {
|
|
823
|
-
error('Error while using world', err);
|
|
824
|
-
return false;
|
|
825
|
-
}
|
|
826
|
-
});
|
|
827
|
-
// create a new world
|
|
828
|
-
rpc.addMethod('world.create', async ([name, level]) => {
|
|
829
|
-
try {
|
|
830
|
-
log('Creating new world', name.yellow, 'with level', (level === null || level === void 0 ? void 0 : level.yellow) || 'Plate');
|
|
831
|
-
const res = await omegga.createEmptyWorld(name, level);
|
|
832
|
-
if (res) {
|
|
833
|
-
log('World created successfully');
|
|
834
|
-
}
|
|
835
|
-
else {
|
|
836
|
-
log('World creation failed');
|
|
837
|
-
}
|
|
838
|
-
return res;
|
|
839
|
-
}
|
|
840
|
-
catch (err) {
|
|
841
|
-
error('Error while creating world', err);
|
|
842
|
-
return false;
|
|
843
|
-
}
|
|
844
|
-
});
|
|
845
|
-
// save a world or save as a world
|
|
846
|
-
rpc.addMethod('world.save', async ([name]) => {
|
|
847
|
-
try {
|
|
848
|
-
let res = false;
|
|
849
|
-
if (name) {
|
|
850
|
-
log('Saving world as', name.yellow);
|
|
851
|
-
res = await omegga.saveWorldAs(name);
|
|
852
|
-
}
|
|
853
|
-
else {
|
|
854
|
-
log('Saving current world');
|
|
855
|
-
res = await omegga.saveWorld();
|
|
856
|
-
}
|
|
857
|
-
if (res) {
|
|
858
|
-
log('World saved successfully');
|
|
859
|
-
}
|
|
860
|
-
else {
|
|
861
|
-
log('World save failed');
|
|
862
|
-
}
|
|
863
|
-
return res;
|
|
864
|
-
}
|
|
865
|
-
catch (err) {
|
|
866
|
-
error('Error while saving world', err);
|
|
867
|
-
return false;
|
|
868
|
-
}
|
|
869
|
-
});
|
|
870
|
-
// subscribe and unsubscribe to events
|
|
871
|
-
socket.on('subscribe', room => {
|
|
872
|
-
// TODO: permission check for certain rooms
|
|
873
|
-
if (server.rooms.includes(room)) {
|
|
874
|
-
socket.join(room);
|
|
875
|
-
}
|
|
876
|
-
});
|
|
877
|
-
socket.on('unsubscribe', room => {
|
|
878
|
-
if (server.rooms.includes(room))
|
|
879
|
-
socket.leave(room);
|
|
880
|
-
});
|
|
881
|
-
socket.on('disconnect', () => { });
|
|
782
|
+
socket.on("subscribe", (room) => {
|
|
783
|
+
if (server.rooms.includes(room)) {
|
|
784
|
+
socket.join(room);
|
|
785
|
+
}
|
|
786
|
+
});
|
|
787
|
+
socket.on("unsubscribe", (room) => {
|
|
788
|
+
if (server.rooms.includes(room)) socket.leave(room);
|
|
789
|
+
});
|
|
790
|
+
socket.on("disconnect", () => {
|
|
882
791
|
});
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
792
|
+
});
|
|
793
|
+
server.app.use("/api/v1", openApi);
|
|
794
|
+
server.app.use("/api/v1", api);
|
|
886
795
|
}
|
|
887
|
-
|
|
796
|
+
exports.default = setupApi;
|
|
797
|
+
//# sourceMappingURL=api.js.map
|