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.
Files changed (255) hide show
  1. package/README.md +20 -1
  2. package/dist/brickadia/config.js +26 -90
  3. package/dist/brickadia/config.js.map +1 -1
  4. package/dist/brickadia/server.js +294 -293
  5. package/dist/brickadia/server.js.map +1 -1
  6. package/dist/cli/auth.js +149 -177
  7. package/dist/cli/auth.js.map +1 -1
  8. package/dist/cli/config.js +64 -66
  9. package/dist/cli/config.js.map +1 -1
  10. package/dist/cli/index.js +14 -14
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/cli/installer.js +37 -43
  13. package/dist/cli/installer.js.map +1 -1
  14. package/dist/cli/plugin.js +651 -682
  15. package/dist/cli/plugin.js.map +1 -1
  16. package/dist/cli/terminal.js +811 -733
  17. package/dist/cli/terminal.js.map +1 -1
  18. package/dist/config/formats/format_js.js +6 -6
  19. package/dist/config/formats/format_js.js.map +1 -1
  20. package/dist/config/formats/format_yml.js +7 -10
  21. package/dist/config/formats/format_yml.js.map +1 -1
  22. package/dist/config/index.js +46 -68
  23. package/dist/config/index.js.map +1 -1
  24. package/dist/config/reader.js +16 -27
  25. package/dist/config/reader.js.map +1 -1
  26. package/dist/config/validator.js +23 -25
  27. package/dist/config/validator.js.map +1 -1
  28. package/dist/config/writer.js +11 -21
  29. package/dist/config/writer.js.map +1 -1
  30. package/dist/index.js +18 -64
  31. package/dist/index.js.map +1 -1
  32. package/dist/info/default_commands.json.js +39 -0
  33. package/dist/info/default_commands.json.js.map +1 -0
  34. package/dist/logger.js +61 -60
  35. package/dist/logger.js.map +1 -1
  36. package/dist/main.js +424 -471
  37. package/dist/main.js.map +1 -1
  38. package/dist/omegga/auth.js +101 -148
  39. package/dist/omegga/auth.js.map +1 -1
  40. package/dist/omegga/commandInjector.js +261 -251
  41. package/dist/omegga/commandInjector.js.map +1 -1
  42. package/dist/omegga/index.js +14 -52
  43. package/dist/omegga/index.js.map +1 -1
  44. package/dist/omegga/logWrangler.js +224 -275
  45. package/dist/omegga/logWrangler.js.map +1 -1
  46. package/dist/omegga/matchers/auth.js +36 -50
  47. package/dist/omegga/matchers/auth.js.map +1 -1
  48. package/dist/omegga/matchers/chat.js +49 -71
  49. package/dist/omegga/matchers/chat.js.map +1 -1
  50. package/dist/omegga/matchers/command.js +25 -36
  51. package/dist/omegga/matchers/command.js.map +1 -1
  52. package/dist/omegga/matchers/exit.js +15 -18
  53. package/dist/omegga/matchers/exit.js.map +1 -1
  54. package/dist/omegga/matchers/index.js +26 -40
  55. package/dist/omegga/matchers/index.js.map +1 -1
  56. package/dist/omegga/matchers/init.js +20 -23
  57. package/dist/omegga/matchers/init.js.map +1 -1
  58. package/dist/omegga/matchers/interact.js +58 -64
  59. package/dist/omegga/matchers/interact.js.map +1 -1
  60. package/dist/omegga/matchers/join.js +74 -95
  61. package/dist/omegga/matchers/join.js.map +1 -1
  62. package/dist/omegga/matchers/leave.js +43 -56
  63. package/dist/omegga/matchers/leave.js.map +1 -1
  64. package/dist/omegga/matchers/mapChange.js +26 -35
  65. package/dist/omegga/matchers/mapChange.js.map +1 -1
  66. package/dist/omegga/matchers/minigameJoin.js +24 -31
  67. package/dist/omegga/matchers/minigameJoin.js.map +1 -1
  68. package/dist/omegga/matchers/version.js +42 -49
  69. package/dist/omegga/matchers/version.js.map +1 -1
  70. package/dist/omegga/player.js +527 -527
  71. package/dist/omegga/player.js.map +1 -1
  72. package/dist/omegga/plugin/interface.js +91 -98
  73. package/dist/omegga/plugin/interface.js.map +1 -1
  74. package/dist/omegga/plugin/plugin_jsonrpc_stdio.js +524 -429
  75. package/dist/omegga/plugin/plugin_jsonrpc_stdio.js.map +1 -1
  76. package/dist/omegga/plugin/plugin_node_safe/proxyOmegga.js +282 -294
  77. package/dist/omegga/plugin/plugin_node_safe/proxyOmegga.js.map +1 -1
  78. package/dist/omegga/plugin/plugin_node_safe.js +365 -393
  79. package/dist/omegga/plugin/plugin_node_safe.js.map +1 -1
  80. package/dist/omegga/plugin/plugin_node_unsafe.js +119 -179
  81. package/dist/omegga/plugin/plugin_node_unsafe.js.map +1 -1
  82. package/dist/omegga/plugin.js +402 -347
  83. package/dist/omegga/plugin.js.map +1 -1
  84. package/dist/omegga/server.js +742 -774
  85. package/dist/omegga/server.js.map +1 -1
  86. package/dist/omegga/wrapper.js +64 -91
  87. package/dist/omegga/wrapper.js.map +1 -1
  88. package/dist/plugin.js +11 -31
  89. package/dist/plugin.js.map +1 -1
  90. package/dist/softconfig.js +121 -100
  91. package/dist/softconfig.js.map +1 -1
  92. package/dist/updater/steam.js +97 -112
  93. package/dist/updater/steam.js.map +1 -1
  94. package/dist/util/brdb.js +496 -528
  95. package/dist/util/brdb.js.map +1 -1
  96. package/dist/util/brick/checkBounds.js +11 -15
  97. package/dist/util/brick/checkBounds.js.map +1 -1
  98. package/dist/util/brick/constants.js +723 -174
  99. package/dist/util/brick/constants.js.map +1 -1
  100. package/dist/util/brick/displayName.js +204 -211
  101. package/dist/util/brick/displayName.js.map +1 -1
  102. package/dist/util/brick/getBounds.js +29 -41
  103. package/dist/util/brick/getBounds.js.map +1 -1
  104. package/dist/util/brick/getBrickSize.js +6 -7
  105. package/dist/util/brick/getBrickSize.js.map +1 -1
  106. package/dist/util/brick/getScaleAxis.js +24 -30
  107. package/dist/util/brick/getScaleAxis.js.map +1 -1
  108. package/dist/util/brick/index.js +8 -29
  109. package/dist/util/brick/index.js.map +1 -1
  110. package/dist/util/brick/rotate.js +29 -34
  111. package/dist/util/brick/rotate.js.map +1 -1
  112. package/dist/util/brick/setOwnership.js +13 -19
  113. package/dist/util/brick/setOwnership.js.map +1 -1
  114. package/dist/util/chat.js +53 -44
  115. package/dist/util/chat.js.map +1 -1
  116. package/dist/util/color.js +112 -124
  117. package/dist/util/color.js.map +1 -1
  118. package/dist/util/file.js +54 -98
  119. package/dist/util/file.js.map +1 -1
  120. package/dist/util/index.js +84 -106
  121. package/dist/util/index.js.map +1 -1
  122. package/dist/util/map.js +18 -20
  123. package/dist/util/map.js.map +1 -1
  124. package/dist/util/pattern.js +6 -9
  125. package/dist/util/pattern.js.map +1 -1
  126. package/dist/util/time.js +31 -34
  127. package/dist/util/time.js.map +1 -1
  128. package/dist/util/uuid.js +10 -8
  129. package/dist/util/uuid.js.map +1 -1
  130. package/dist/util/wsl.js +19 -25
  131. package/dist/util/wsl.js.map +1 -1
  132. package/dist/version.js +7 -9
  133. package/dist/version.js.map +1 -1
  134. package/dist/webserver/backend/api.js +784 -874
  135. package/dist/webserver/backend/api.js.map +1 -1
  136. package/dist/webserver/backend/calendar.js +14 -17
  137. package/dist/webserver/backend/calendar.js.map +1 -1
  138. package/dist/webserver/backend/database.js +563 -613
  139. package/dist/webserver/backend/database.js.map +1 -1
  140. package/dist/webserver/backend/index.js +153 -191
  141. package/dist/webserver/backend/index.js.map +1 -1
  142. package/dist/webserver/backend/metrics.js +219 -248
  143. package/dist/webserver/backend/metrics.js.map +1 -1
  144. package/dist/webserver/backend/util.js +47 -68
  145. package/dist/webserver/backend/util.js.map +1 -1
  146. package/dist/worker.js +322 -0
  147. package/dist/worker.js.map +1 -0
  148. package/package.json +14 -10
  149. package/templates/safe-ts/omegga.d.ts +2 -2
  150. package/vite.backend.config.mts +46 -0
  151. package/vite.frontend.config.mts +58 -0
  152. package/vitest.backend.config.mts +7 -0
  153. package/dist/brickadia/config.d.ts +0 -3
  154. package/dist/brickadia/presets.d.ts +0 -65
  155. package/dist/brickadia/presets.js +0 -3
  156. package/dist/brickadia/presets.js.map +0 -1
  157. package/dist/brickadia/server.d.ts +0 -36
  158. package/dist/brickadia/types.d.ts +0 -45
  159. package/dist/brickadia/types.js +0 -3
  160. package/dist/brickadia/types.js.map +0 -1
  161. package/dist/cli/auth.d.ts +0 -26
  162. package/dist/cli/config.d.ts +0 -10
  163. package/dist/cli/index.d.ts +0 -30
  164. package/dist/cli/installer.d.ts +0 -1
  165. package/dist/cli/plugin.d.ts +0 -22
  166. package/dist/cli/terminal.d.ts +0 -25
  167. package/dist/config/authorizer.d.ts +0 -2
  168. package/dist/config/authorizer.js +0 -38
  169. package/dist/config/authorizer.js.map +0 -1
  170. package/dist/config/formats/format_js.d.ts +0 -3
  171. package/dist/config/formats/format_yml.d.ts +0 -3
  172. package/dist/config/index.d.ts +0 -18
  173. package/dist/config/reader.d.ts +0 -3
  174. package/dist/config/types.d.ts +0 -50
  175. package/dist/config/types.js +0 -3
  176. package/dist/config/types.js.map +0 -1
  177. package/dist/config/validator.d.ts +0 -6
  178. package/dist/config/writer.d.ts +0 -3
  179. package/dist/index.d.ts +0 -22
  180. package/dist/info/default_commands.json +0 -29
  181. package/dist/logger.d.ts +0 -41
  182. package/dist/main.d.ts +0 -1
  183. package/dist/omegga/auth.d.ts +0 -9
  184. package/dist/omegga/commandInjector.d.ts +0 -35
  185. package/dist/omegga/index.d.ts +0 -7
  186. package/dist/omegga/logWrangler.d.ts +0 -32
  187. package/dist/omegga/matchers/auth.d.ts +0 -10
  188. package/dist/omegga/matchers/chat.d.ts +0 -10
  189. package/dist/omegga/matchers/command.d.ts +0 -7
  190. package/dist/omegga/matchers/exit.d.ts +0 -3
  191. package/dist/omegga/matchers/index.d.ts +0 -3
  192. package/dist/omegga/matchers/init.d.ts +0 -3
  193. package/dist/omegga/matchers/interact.d.ts +0 -4
  194. package/dist/omegga/matchers/join.d.ts +0 -4
  195. package/dist/omegga/matchers/leave.d.ts +0 -4
  196. package/dist/omegga/matchers/mapChange.d.ts +0 -3
  197. package/dist/omegga/matchers/minigameJoin.d.ts +0 -9
  198. package/dist/omegga/matchers/types.d.ts +0 -5
  199. package/dist/omegga/matchers/types.js +0 -3
  200. package/dist/omegga/matchers/types.js.map +0 -1
  201. package/dist/omegga/matchers/version.d.ts +0 -3
  202. package/dist/omegga/player.d.ts +0 -81
  203. package/dist/omegga/plugin/interface.d.ts +0 -30
  204. package/dist/omegga/plugin/plugin_jsonrpc_stdio.d.ts +0 -23
  205. package/dist/omegga/plugin/plugin_node_safe/proxyOmegga.d.ts +0 -145
  206. package/dist/omegga/plugin/plugin_node_safe/worker.d.ts +0 -1
  207. package/dist/omegga/plugin/plugin_node_safe/worker.js +0 -367
  208. package/dist/omegga/plugin/plugin_node_safe/worker.js.map +0 -1
  209. package/dist/omegga/plugin/plugin_node_safe.d.ts +0 -23
  210. package/dist/omegga/plugin/plugin_node_unsafe.d.ts +0 -13
  211. package/dist/omegga/plugin.d.ts +0 -63
  212. package/dist/omegga/server.d.ts +0 -166
  213. package/dist/omegga/types.d.ts +0 -49
  214. package/dist/omegga/types.js +0 -3
  215. package/dist/omegga/types.js.map +0 -1
  216. package/dist/omegga/wrapper.d.ts +0 -32
  217. package/dist/plugin.d.ts +0 -916
  218. package/dist/softconfig.d.ts +0 -67
  219. package/dist/tsconfig.tsbuildinfo +0 -1
  220. package/dist/updater/index.d.ts +0 -1
  221. package/dist/updater/index.js +0 -10
  222. package/dist/updater/index.js.map +0 -1
  223. package/dist/updater/steam.d.ts +0 -52
  224. package/dist/util/brdb.d.ts +0 -31
  225. package/dist/util/brick/checkBounds.d.ts +0 -8
  226. package/dist/util/brick/constants.d.ts +0 -18
  227. package/dist/util/brick/displayName.d.ts +0 -7
  228. package/dist/util/brick/getBounds.d.ts +0 -5
  229. package/dist/util/brick/getBrickSize.d.ts +0 -3
  230. package/dist/util/brick/getScaleAxis.d.ts +0 -3
  231. package/dist/util/brick/index.d.ts +0 -14
  232. package/dist/util/brick/rotate.d.ts +0 -16
  233. package/dist/util/brick/setOwnership.d.ts +0 -12
  234. package/dist/util/chat.d.ts +0 -23
  235. package/dist/util/color.d.ts +0 -13
  236. package/dist/util/file.d.ts +0 -5
  237. package/dist/util/index.d.ts +0 -183
  238. package/dist/util/map.d.ts +0 -6
  239. package/dist/util/pattern.d.ts +0 -1
  240. package/dist/util/time.d.ts +0 -39
  241. package/dist/util/uuid.d.ts +0 -3
  242. package/dist/util/wsl.d.ts +0 -2
  243. package/dist/version.d.ts +0 -2
  244. package/dist/webserver/backend/api.d.ts +0 -115
  245. package/dist/webserver/backend/calendar.d.ts +0 -5
  246. package/dist/webserver/backend/database.d.ts +0 -150
  247. package/dist/webserver/backend/index.d.ts +0 -30
  248. package/dist/webserver/backend/metrics.d.ts +0 -3
  249. package/dist/webserver/backend/types.d.ts +0 -114
  250. package/dist/webserver/backend/types.js +0 -3
  251. package/dist/webserver/backend/types.js.map +0 -1
  252. package/dist/webserver/backend/util.d.ts +0 -2
  253. package/dist/webserver/index.d.ts +0 -2
  254. package/dist/webserver/index.js +0 -9
  255. package/dist/webserver/index.js.map +0 -1
@@ -1,887 +1,797 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
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
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
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
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.default = default_1;
40
- const logger_1 = __importDefault(require("../../logger"));
41
- const updater_1 = require("../../updater");
42
- const steam_1 = require("../../updater/steam");
43
- const version_1 = require("../../version");
44
- const player_1 = __importDefault(require("../../omegga/player"));
45
- const chat_1 = require("../../util/chat");
46
- const color_1 = require("../../util/color");
47
- const time_1 = require("../../util/time");
48
- const uuid = __importStar(require("../../util/uuid"));
49
- const express_1 = __importDefault(require("express"));
50
- const json_rpc_2_0_1 = require("json-rpc-2.0");
51
- const lodash_1 = __importDefault(require("lodash"));
52
- const brdb_1 = require("../../util/brdb");
53
- function default_1(server, io) {
54
- const { database, omegga } = server;
55
- // open API is accessible without auth
56
- const openApi = express_1.default.Router();
57
- const api = express_1.default.Router();
58
- // check if this is the first user in the database
59
- openApi.get('/first', async (req, res) => res.json(await database.isFirstUser()));
60
- // login / create admin user route
61
- openApi.post('/auth', async (req, res) => {
62
- // body is username and password
63
- if (typeof req.body !== 'object' ||
64
- typeof req.body.username !== 'string' ||
65
- typeof req.body.password !== 'string') {
66
- return res.status(422).json({ message: 'invalid body' });
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
- const { username, password } = req.body;
69
- // username regex
70
- if (!username.match(/^\w{0,32}$/)) {
71
- return res.status(422).json({ message: 'invalid body' });
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
- // if this is the first user, create it as the admin user
74
- const isFirst = await database.isFirstUser();
75
- let user;
76
- if (isFirst) {
77
- user = await database.createAdminUser(username, username === '' ? '' : password);
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
- else {
80
- user = await database.authUser(username, password);
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
- if (user) {
83
- req.session.userId = user._id;
84
- req.session.save();
85
- res.status(200).json({});
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
- else {
88
- res.status(404).json({ message: 'no user found' });
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
- // kill a session
92
- api.get('/logout', (req, res) => {
93
- req.session.destroy(e => {
94
- res.status(e ? 500 : 200).json({});
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
- // authentication middleware for api
98
- api.all('*', (req, _res, next) => {
99
- (async () => {
100
- const user = await database.findUserById(req.session.userId);
101
- if (!user || user.isBanned)
102
- return next(new Error('unauthorized'));
103
- // req.user = user;
104
- next();
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
- // register routes
884
- server.app.use('/api/v1', openApi);
885
- server.app.use('/api/v1', api);
792
+ });
793
+ server.app.use("/api/v1", openApi);
794
+ server.app.use("/api/v1", api);
886
795
  }
887
- //# sourceMappingURL=api.js.map
796
+ exports.default = setupApi;
797
+ //# sourceMappingURL=api.js.map