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,255 +1,226 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.default = default_1;
7
- const logger_1 = __importDefault(require("../../logger"));
8
- const softconfig_1 = __importDefault(require("../../softconfig"));
9
- const steam_1 = require("../../updater/steam");
10
- const error = (...args) => logger_1.default.error(...args);
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
+ const logger = require("../../logger.js");
4
+ const softconfig = require("../../softconfig.js");
5
+ const steam = require("../../updater/steam.js");
6
+ const error = (...args) => logger.default.error(...args);
11
7
  let lastRestart = 0;
12
- const sleep = t => new Promise(resolve => setTimeout(resolve, t));
13
- function default_1(server, io) {
14
- const { database, omegga } = server;
15
- // server status is checked every minute
16
- clearInterval(server.serverStatusInterval);
17
- // heartbeat happens every 60 seconds
18
- let empties = 0;
19
- // last heartbeat hour
20
- let lastHour = -1;
21
- // players that have joined in the last hour
22
- let hourlyPlayers = [];
23
- const exitOnStop = () => {
24
- if (omegga.stopping || !omegga.started)
25
- throw new Error('Omegga is already closing');
8
+ const sleep = (t) => new Promise((resolve) => setTimeout(resolve, t));
9
+ function setupMetrics(server, io) {
10
+ const { database, omegga } = server;
11
+ clearInterval(server.serverStatusInterval);
12
+ let empties = 0;
13
+ let lastHour = -1;
14
+ let hourlyPlayers = [];
15
+ const exitOnStop = () => {
16
+ if (omegga.stopping || !omegga.started)
17
+ throw new Error("Omegga is already closing");
18
+ };
19
+ async function restartServer(config, update) {
20
+ lastRestart = Date.now();
21
+ const iconfig = {
22
+ players: config.playersEnabled,
23
+ announcement: config.announcementEnabled,
24
+ saveWorld: config.saveWorld
26
25
  };
27
- async function restartServer(config, update) {
28
- var _a, _b;
29
- lastRestart = Date.now();
30
- const iconfig = {
31
- players: config.playersEnabled,
32
- announcement: config.announcementEnabled,
33
- saveWorld: config.saveWorld,
34
- };
35
- omegga.emit('autorestart', iconfig);
36
- await sleep(1000);
37
- exitOnStop();
38
- const action = update ? 'Updating' : 'Restarting';
39
- if (config.announcementEnabled) {
40
- database.addChatLog('server', {}, action + ' in 30 seconds...');
41
- logger_1.default.logp(action + ' in 30 seconds...');
42
- const announce = (t) => omegga.broadcast(`<size="20">${action} in <b><color="ffffbb">${t} second${t !== 1 ? 's' : ''}</></></>`);
43
- announce(30);
44
- await sleep(15000);
45
- announce(15);
46
- await sleep(10000);
47
- announce(5);
48
- await sleep(1000);
49
- announce(4);
50
- await sleep(1000);
51
- announce(3);
52
- await sleep(1000);
53
- announce(2);
54
- await sleep(1000);
55
- announce(1);
56
- await sleep(1000);
57
- }
58
- exitOnStop();
59
- await omegga.saveServer(iconfig);
60
- logger_1.default.logp(action + '...');
61
- database.addChatLog('server', {}, action + ' server...');
62
- omegga.once('mapchange', () => {
63
- omegga.restoreServer();
26
+ omegga.emit("autorestart", iconfig);
27
+ await sleep(1e3);
28
+ exitOnStop();
29
+ const action = update ? "Updating" : "Restarting";
30
+ if (config.announcementEnabled) {
31
+ database.addChatLog("server", {}, action + " in 30 seconds...");
32
+ logger.default.logp(action + " in 30 seconds...");
33
+ const announce = (t) => omegga.broadcast(
34
+ `<size="20">${action} in <b><color="ffffbb">${t} second${t !== 1 ? "s" : ""}</></></>`
35
+ );
36
+ announce(30);
37
+ await sleep(15e3);
38
+ announce(15);
39
+ await sleep(1e4);
40
+ announce(5);
41
+ await sleep(1e3);
42
+ announce(4);
43
+ await sleep(1e3);
44
+ announce(3);
45
+ await sleep(1e3);
46
+ announce(2);
47
+ await sleep(1e3);
48
+ announce(1);
49
+ await sleep(1e3);
50
+ }
51
+ exitOnStop();
52
+ await omegga.saveServer(iconfig);
53
+ logger.default.logp(action + "...");
54
+ database.addChatLog("server", {}, action + " server...");
55
+ omegga.once("mapchange", () => {
56
+ omegga.restoreServer();
57
+ });
58
+ if (update && omegga.config.__STEAM && !omegga.config.server?.steambetaPassword) {
59
+ logger.default.logp("Stopping server for auto-update...");
60
+ await omegga.stop();
61
+ logger.default.logp("Downloading update...");
62
+ try {
63
+ steam.steamcmdDownloadGame({
64
+ steambeta: omegga.config.server?.steambeta
64
65
  });
65
- if (update &&
66
- omegga.config.__STEAM &&
67
- !((_a = omegga.config.server) === null || _a === void 0 ? void 0 : _a.steambetaPassword)) {
68
- logger_1.default.logp('Stopping server for auto-update...');
69
- await omegga.stop();
70
- logger_1.default.logp('Downloading update...');
71
- try {
72
- (0, steam_1.steamcmdDownloadGame)({
73
- steambeta: (_b = omegga.config.server) === null || _b === void 0 ? void 0 : _b.steambeta,
74
- });
75
- }
76
- catch (e) {
77
- error('An error occurred while downloading the update:', e);
78
- }
79
- logger_1.default.logp('Starting server after update...');
80
- await omegga.start();
81
- }
82
- else {
83
- await omegga.restartServer();
84
- }
66
+ } catch (e) {
67
+ error("An error occurred while downloading the update:", e);
68
+ }
69
+ logger.default.logp("Starting server after update...");
70
+ await omegga.start();
71
+ } else {
72
+ await omegga.restartServer();
85
73
  }
86
- async function checkAutoRestart(status) {
87
- var _a, _b;
88
- const now = new Date();
89
- const currHour = now.getHours();
90
- const currMinute = now.getMinutes();
91
- /// skip restart check if we sent restart command within 5 minutes
92
- if (lastRestart > now.getTime() - 5 * 60 * 1000) {
93
- logger_1.default.verbose('Skipping autorestart');
94
- return;
95
- }
96
- const config = await database.getAutoRestartConfig();
97
- logger_1.default.verbose('Autorestart check', config);
98
- const uptimeMinutes = Math.floor(status.time / 1000 / 60);
99
- const uptimeHours = Math.floor(uptimeMinutes / 60);
100
- if (config.maxUptimeEnabled && uptimeHours >= config.maxUptime) {
101
- logger_1.default.verbose('Restarting due to max uptime');
102
- return await restartServer(config);
103
- }
104
- if (config.emptyUptimeEnabled &&
105
- uptimeHours >= config.emptyUptime &&
106
- status.players.length === 0) {
107
- logger_1.default.verbose('Restarting due to max empty uptime');
108
- return await restartServer(config);
109
- }
110
- if (config.dailyHourEnabled &&
111
- currHour === config.dailyHour &&
112
- uptimeMinutes > currMinute) {
113
- logger_1.default.verbose('Restarting due to daily schedule');
114
- return await restartServer(config);
115
- }
116
- // Cannot auto-update on steam betas with passwords
117
- const lastCheck = (0, steam_1.getLastSteamUpdateCheck)();
118
- if (omegga.config.__STEAM &&
119
- config.autoUpdateEnabled &&
120
- !((_a = omegga.config.server) === null || _a === void 0 ? void 0 : _a.steambetaPassword)) {
121
- const now = Date.now();
122
- if (
123
- // If there is no update
124
- !lastCheck.available &&
125
- // And the last update was too recent
126
- now - lastCheck.attempt < config.autoUpdateIntervalMins * 60 * 1000) {
127
- // Skip this check
128
- logger_1.default.verbose(`Skipping auto update check, last check was ${Math.floor((now - lastCheck.attempt) / 1000 / 60)} minutes ago`);
129
- return;
130
- }
131
- logger_1.default.verbose('Checking for steam update');
132
- const hasUpdate = await (0, steam_1.hasSteamUpdate)((_b = omegga.config.server) === null || _b === void 0 ? void 0 : _b.steambeta);
133
- if (hasUpdate) {
134
- (0, steam_1.clearLastSteamUpdateCheck)();
135
- return await restartServer(config, true);
136
- }
137
- logger_1.default.verbose('No steam update found');
138
- }
74
+ }
75
+ async function checkAutoRestart(status) {
76
+ const now = /* @__PURE__ */ new Date();
77
+ const currHour = now.getHours();
78
+ const currMinute = now.getMinutes();
79
+ if (lastRestart > now.getTime() - 5 * 60 * 1e3) {
80
+ logger.default.verbose("Skipping autorestart");
81
+ return;
139
82
  }
140
- server.lastReportedStatus = null;
141
- server.serverStatusInterval = setInterval(async () => {
142
- if (!omegga.started)
143
- return;
144
- try {
145
- // get the server status
146
- const status = await omegga.getServerStatus();
147
- if (!status)
148
- return;
149
- try {
150
- await checkAutoRestart(status);
151
- }
152
- catch (err) {
153
- error('Error in autorestart check', err);
154
- }
155
- // get players by id
156
- const players = status.players.map(p => p.id);
157
- // send the unaltered status to the frontend
158
- server.lastReportedStatus = status;
159
- io.to('status').emit('server.status', status);
160
- try {
161
- omegga.emit('metrics:heartbeat', status);
162
- }
163
- catch (e) {
164
- // prevent the omegga callback handlers from crashing this
165
- error('Error in heartbeat emit', e);
166
- }
167
- // stop recording metrics after 3 empty server statuses
168
- if (players.length === 0 &&
169
- ++empties > softconfig_1.default.METRIC_EMPTIES_BEFORE_PAUSE) {
170
- return;
171
- }
172
- const now = new Date();
173
- const hour = now.getUTCHours();
174
- // check if it's a new hour (for punchcard unique player tracking)
175
- if (hour !== lastHour) {
176
- lastHour = hour;
177
- hourlyPlayers = [];
178
- }
179
- // find all the players unique to this hour
180
- const newPlayers = players.filter(p => !hourlyPlayers.includes(p));
181
- if (newPlayers.length > 0) {
182
- // update the punchcard
183
- await database.updatePlayerPunchcard(newPlayers.length);
184
- // mark those players as previously joined players
185
- hourlyPlayers.push(...newPlayers);
186
- }
187
- // server is not empty, reset the counter
188
- empties = 0;
189
- const data = {
190
- // number of bricks
191
- bricks: status.bricks,
192
- // unique players by id
193
- players: players.filter((p, i) => players.indexOf(p) === i),
194
- // addresses by player id
195
- ips: Object.fromEntries(status.players.map(p => [p.id, p.address])),
196
- };
197
- // hand the server status off to the database
198
- await database.addHeartbeat(data);
199
- }
200
- catch (e) {
201
- // probably an issue getting server status
202
- error('Server Not Responding...');
203
- }
204
- }, softconfig_1.default.METRIC_HEARTBEAT_INTERVAL);
205
- // chat events
206
- omegga.on('chat', async (name, message) => {
207
- const p = omegga.getPlayer(name);
208
- const user = {
209
- id: p.id,
210
- name,
211
- displayName: p.displayName,
212
- color: p.getNameColor(),
213
- };
214
- // tell web users about a chat message
215
- io.to('chat').emit('chat', await database.addChatLog('msg', user, message));
216
- });
217
- // player leave events
218
- omegga.on('leave', async ({ id, name, displayName }) => {
219
- // tell web users a player left
220
- io.to('chat').emit('chat', await database.addChatLog('leave', { id, name, displayName }));
221
- });
222
- // player join events
223
- omegga.on('join', async ({ id, name, displayName }) => {
224
- // add the visit to the database
225
- const isFirst = await database.addVisit({ id, name, displayName });
226
- // tell web users a player joined (and if it's their first time joining)
227
- io.to('chat').emit('chat', await database.addChatLog('join', {
228
- id,
229
- name,
230
- displayName,
231
- ...(isFirst ? { isFirst } : {}),
232
- }));
233
- });
234
- // tell web users plugin status
235
- omegga.on('plugin:status', (shortPath, info) => {
236
- io.to('plugins').emit('plugin', shortPath, info);
237
- });
238
- // server status events
239
- omegga.on('start', () => io
240
- .to('server')
241
- .emit('status', { started: true, starting: false, stopping: false }));
242
- omegga.on('server:starting', () => io
243
- .to('server')
244
- .emit('status', { started: false, starting: true, stopping: false }));
245
- omegga.on('mapchange', () => io
246
- .to('server')
247
- .emit('status', { started: true, starting: false, stopping: false }));
248
- omegga.on('server:stopped', () => io
249
- .to('server')
250
- .emit('status', { started: false, starting: false, stopping: false }));
251
- omegga.on('server:stopping', () => io
252
- .to('server')
253
- .emit('status', { started: true, starting: false, stopping: true }));
83
+ const config = await database.getAutoRestartConfig();
84
+ logger.default.verbose("Autorestart check", config);
85
+ const uptimeMinutes = Math.floor(status.time / 1e3 / 60);
86
+ const uptimeHours = Math.floor(uptimeMinutes / 60);
87
+ if (config.maxUptimeEnabled && uptimeHours >= config.maxUptime) {
88
+ logger.default.verbose("Restarting due to max uptime");
89
+ return await restartServer(config);
90
+ }
91
+ if (config.emptyUptimeEnabled && uptimeHours >= config.emptyUptime && status.players.length === 0) {
92
+ logger.default.verbose("Restarting due to max empty uptime");
93
+ return await restartServer(config);
94
+ }
95
+ if (config.dailyHourEnabled && currHour === config.dailyHour && uptimeMinutes > currMinute) {
96
+ logger.default.verbose("Restarting due to daily schedule");
97
+ return await restartServer(config);
98
+ }
99
+ const lastCheck = steam.getLastSteamUpdateCheck();
100
+ if (omegga.config.__STEAM && config.autoUpdateEnabled && !omegga.config.server?.steambetaPassword) {
101
+ const now2 = Date.now();
102
+ if (
103
+ // If there is no update
104
+ !lastCheck.available && // And the last update was too recent
105
+ now2 - lastCheck.attempt < config.autoUpdateIntervalMins * 60 * 1e3
106
+ ) {
107
+ logger.default.verbose(
108
+ `Skipping auto update check, last check was ${Math.floor(
109
+ (now2 - lastCheck.attempt) / 1e3 / 60
110
+ )} minutes ago`
111
+ );
112
+ return;
113
+ }
114
+ logger.default.verbose("Checking for steam update");
115
+ const hasUpdate = await steam.hasSteamUpdate(omegga.config.server?.steambeta);
116
+ if (hasUpdate) {
117
+ steam.clearLastSteamUpdateCheck();
118
+ return await restartServer(config, true);
119
+ }
120
+ logger.default.verbose("No steam update found");
121
+ }
122
+ }
123
+ server.lastReportedStatus = null;
124
+ server.serverStatusInterval = setInterval(async () => {
125
+ if (!omegga.started) return;
126
+ try {
127
+ const status = await omegga.getServerStatus();
128
+ if (!status) return;
129
+ try {
130
+ await checkAutoRestart(status);
131
+ } catch (err) {
132
+ error("Error in autorestart check", err);
133
+ }
134
+ const players = status.players.map((p) => p.id);
135
+ server.lastReportedStatus = status;
136
+ io.to("status").emit("server.status", status);
137
+ try {
138
+ omegga.emit("metrics:heartbeat", status);
139
+ } catch (e) {
140
+ error("Error in heartbeat emit", e);
141
+ }
142
+ if (players.length === 0 && ++empties > softconfig.default.METRIC_EMPTIES_BEFORE_PAUSE) {
143
+ return;
144
+ }
145
+ const now = /* @__PURE__ */ new Date();
146
+ const hour = now.getUTCHours();
147
+ if (hour !== lastHour) {
148
+ lastHour = hour;
149
+ hourlyPlayers = [];
150
+ }
151
+ const newPlayers = players.filter((p) => !hourlyPlayers.includes(p));
152
+ if (newPlayers.length > 0) {
153
+ await database.updatePlayerPunchcard(newPlayers.length);
154
+ hourlyPlayers.push(...newPlayers);
155
+ }
156
+ empties = 0;
157
+ const data = {
158
+ // number of bricks
159
+ bricks: status.bricks,
160
+ // unique players by id
161
+ players: players.filter((p, i) => players.indexOf(p) === i),
162
+ // addresses by player id
163
+ ips: Object.fromEntries(status.players.map((p) => [p.id, p.address]))
164
+ };
165
+ await database.addHeartbeat(data);
166
+ } catch (e) {
167
+ error("Server Not Responding...");
168
+ }
169
+ }, softconfig.default.METRIC_HEARTBEAT_INTERVAL);
170
+ omegga.on("chat", async (name, message) => {
171
+ const p = omegga.getPlayer(name);
172
+ const user = {
173
+ id: p.id,
174
+ name,
175
+ displayName: p.displayName,
176
+ color: p.getNameColor()
177
+ };
178
+ io.to("chat").emit("chat", await database.addChatLog("msg", user, message));
179
+ });
180
+ omegga.on("leave", async ({ id, name, displayName }) => {
181
+ io.to("chat").emit(
182
+ "chat",
183
+ await database.addChatLog("leave", { id, name, displayName })
184
+ );
185
+ });
186
+ omegga.on("join", async ({ id, name, displayName }) => {
187
+ const isFirst = await database.addVisit({ id, name, displayName });
188
+ io.to("chat").emit(
189
+ "chat",
190
+ await database.addChatLog("join", {
191
+ id,
192
+ name,
193
+ displayName,
194
+ ...isFirst ? { isFirst } : {}
195
+ })
196
+ );
197
+ });
198
+ omegga.on(
199
+ "plugin:status",
200
+ (shortPath, info) => {
201
+ io.to("plugins").emit("plugin", shortPath, info);
202
+ }
203
+ );
204
+ omegga.on(
205
+ "start",
206
+ () => io.to("server").emit("status", { started: true, starting: false, stopping: false })
207
+ );
208
+ omegga.on(
209
+ "server:starting",
210
+ () => io.to("server").emit("status", { started: false, starting: true, stopping: false })
211
+ );
212
+ omegga.on(
213
+ "mapchange",
214
+ () => io.to("server").emit("status", { started: true, starting: false, stopping: false })
215
+ );
216
+ omegga.on(
217
+ "server:stopped",
218
+ () => io.to("server").emit("status", { started: false, starting: false, stopping: false })
219
+ );
220
+ omegga.on(
221
+ "server:stopping",
222
+ () => io.to("server").emit("status", { started: true, starting: false, stopping: true })
223
+ );
254
224
  }
255
- //# sourceMappingURL=metrics.js.map
225
+ exports.default = setupMetrics;
226
+ //# sourceMappingURL=metrics.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../../src/webserver/backend/metrics.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"metrics.js","sources":["../../../src/webserver/backend/metrics.ts"],"sourcesContent":["import Logger from '@/logger';\nimport { AutoRestartConfig, IServerStatus } from '@/plugin';\nimport soft from '@/softconfig';\nimport {\n clearLastSteamUpdateCheck,\n getLastSteamUpdateCheck,\n hasSteamUpdate,\n steamcmdDownloadGame,\n} from '@/updater/steam';\nimport type Webserver from './index';\nimport { IStoreAutoRestartConfig, OmeggaSocketIo } from './types';\n\nconst error = (...args: any[]) => Logger.error(...args);\nlet lastRestart = 0;\n\nconst sleep = t => new Promise(resolve => setTimeout(resolve, t));\n\nexport default function (server: Webserver, io: OmeggaSocketIo) {\n const { database, omegga } = server;\n\n // server status is checked every minute\n clearInterval(server.serverStatusInterval);\n // heartbeat happens every 60 seconds\n let empties = 0;\n\n // last heartbeat hour\n let lastHour = -1;\n // players that have joined in the last hour\n let hourlyPlayers: string[] = [];\n\n const exitOnStop = () => {\n if (omegga.stopping || !omegga.started)\n throw new Error('Omegga is already closing');\n };\n\n async function restartServer(\n config: IStoreAutoRestartConfig,\n update?: boolean,\n ) {\n lastRestart = Date.now();\n const iconfig: AutoRestartConfig = {\n players: config.playersEnabled,\n announcement: config.announcementEnabled,\n saveWorld: config.saveWorld,\n };\n omegga.emit('autorestart', iconfig);\n await sleep(1000);\n exitOnStop();\n\n const action = update ? 'Updating' : 'Restarting';\n\n if (config.announcementEnabled) {\n database.addChatLog('server', {}, action + ' in 30 seconds...');\n Logger.logp(action + ' in 30 seconds...');\n const announce = (t: number) =>\n omegga.broadcast(\n `<size=\"20\">${action} in <b><color=\"ffffbb\">${t} second${\n t !== 1 ? 's' : ''\n }</></></>`,\n );\n announce(30);\n await sleep(15000);\n announce(15);\n await sleep(10000);\n announce(5);\n await sleep(1000);\n announce(4);\n await sleep(1000);\n announce(3);\n await sleep(1000);\n announce(2);\n await sleep(1000);\n announce(1);\n await sleep(1000);\n }\n\n exitOnStop();\n\n await omegga.saveServer(iconfig);\n\n Logger.logp(action + '...');\n database.addChatLog('server', {}, action + ' server...');\n omegga.once('mapchange', () => {\n omegga.restoreServer();\n });\n\n if (\n update &&\n omegga.config.__STEAM &&\n !omegga.config.server?.steambetaPassword\n ) {\n Logger.logp('Stopping server for auto-update...');\n await omegga.stop();\n Logger.logp('Downloading update...');\n try {\n steamcmdDownloadGame({\n steambeta: omegga.config.server?.steambeta,\n });\n } catch (e) {\n error('An error occurred while downloading the update:', e);\n }\n Logger.logp('Starting server after update...');\n await omegga.start();\n } else {\n await omegga.restartServer();\n }\n }\n\n async function checkAutoRestart(status: IServerStatus) {\n const now = new Date();\n const currHour = now.getHours();\n const currMinute = now.getMinutes();\n\n /// skip restart check if we sent restart command within 5 minutes\n if (lastRestart > now.getTime() - 5 * 60 * 1000) {\n Logger.verbose('Skipping autorestart');\n return;\n }\n\n const config = await database.getAutoRestartConfig();\n Logger.verbose('Autorestart check', config);\n\n const uptimeMinutes = Math.floor(status.time / 1000 / 60);\n const uptimeHours = Math.floor(uptimeMinutes / 60);\n\n if (config.maxUptimeEnabled && uptimeHours >= config.maxUptime) {\n Logger.verbose('Restarting due to max uptime');\n return await restartServer(config);\n }\n\n if (\n config.emptyUptimeEnabled &&\n uptimeHours >= config.emptyUptime &&\n status.players.length === 0\n ) {\n Logger.verbose('Restarting due to max empty uptime');\n return await restartServer(config);\n }\n\n if (\n config.dailyHourEnabled &&\n currHour === config.dailyHour &&\n uptimeMinutes > currMinute\n ) {\n Logger.verbose('Restarting due to daily schedule');\n return await restartServer(config);\n }\n\n // Cannot auto-update on steam betas with passwords\n const lastCheck = getLastSteamUpdateCheck();\n if (\n omegga.config.__STEAM &&\n config.autoUpdateEnabled &&\n !omegga.config.server?.steambetaPassword\n ) {\n const now = Date.now();\n if (\n // If there is no update\n !lastCheck.available &&\n // And the last update was too recent\n now - lastCheck.attempt < config.autoUpdateIntervalMins * 60 * 1000\n ) {\n // Skip this check\n Logger.verbose(\n `Skipping auto update check, last check was ${Math.floor(\n (now - lastCheck.attempt) / 1000 / 60,\n )} minutes ago`,\n );\n return;\n }\n Logger.verbose('Checking for steam update');\n const hasUpdate = await hasSteamUpdate(omegga.config.server?.steambeta);\n if (hasUpdate) {\n clearLastSteamUpdateCheck();\n return await restartServer(config, true);\n }\n Logger.verbose('No steam update found');\n }\n }\n\n server.lastReportedStatus = null;\n server.serverStatusInterval = setInterval(async () => {\n if (!omegga.started) return;\n try {\n // get the server status\n const status = await omegga.getServerStatus();\n if (!status) return;\n\n try {\n await checkAutoRestart(status);\n } catch (err) {\n error('Error in autorestart check', err);\n }\n\n // get players by id\n const players = status.players.map(p => p.id);\n\n // send the unaltered status to the frontend\n server.lastReportedStatus = status;\n io.to('status').emit('server.status', status);\n try {\n omegga.emit('metrics:heartbeat', status);\n } catch (e) {\n // prevent the omegga callback handlers from crashing this\n error('Error in heartbeat emit', e);\n }\n\n // stop recording metrics after 3 empty server statuses\n if (\n players.length === 0 &&\n ++empties > soft.METRIC_EMPTIES_BEFORE_PAUSE\n ) {\n return;\n }\n\n const now = new Date();\n const hour = now.getUTCHours();\n // check if it's a new hour (for punchcard unique player tracking)\n if (hour !== lastHour) {\n lastHour = hour;\n hourlyPlayers = [];\n }\n\n // find all the players unique to this hour\n const newPlayers = players.filter(p => !hourlyPlayers.includes(p));\n if (newPlayers.length > 0) {\n // update the punchcard\n await database.updatePlayerPunchcard(newPlayers.length);\n // mark those players as previously joined players\n hourlyPlayers.push(...newPlayers);\n }\n\n // server is not empty, reset the counter\n empties = 0;\n\n const data = {\n // number of bricks\n bricks: status.bricks,\n // unique players by id\n players: players.filter((p, i) => players.indexOf(p) === i),\n // addresses by player id\n ips: Object.fromEntries(status.players.map(p => [p.id, p.address])),\n };\n\n // hand the server status off to the database\n await database.addHeartbeat(data);\n } catch (e) {\n // probably an issue getting server status\n error('Server Not Responding...');\n }\n }, soft.METRIC_HEARTBEAT_INTERVAL);\n\n // chat events\n omegga.on('chat', async (name, message) => {\n const p = omegga.getPlayer(name);\n const user = {\n id: p.id,\n name,\n displayName: p.displayName,\n color: p.getNameColor(),\n };\n\n // tell web users about a chat message\n io.to('chat').emit('chat', await database.addChatLog('msg', user, message));\n });\n\n // player leave events\n omegga.on('leave', async ({ id, name, displayName }) => {\n // tell web users a player left\n io.to('chat').emit(\n 'chat',\n await database.addChatLog('leave', { id, name, displayName }),\n );\n });\n\n // player join events\n omegga.on('join', async ({ id, name, displayName }) => {\n // add the visit to the database\n const isFirst = await database.addVisit({ id, name, displayName });\n\n // tell web users a player joined (and if it's their first time joining)\n io.to('chat').emit(\n 'chat',\n await database.addChatLog('join', {\n id,\n name,\n displayName,\n ...(isFirst ? { isFirst } : {}),\n }),\n );\n });\n\n // tell web users plugin status\n omegga.on(\n 'plugin:status',\n (\n shortPath: string,\n info: { name: string; isLoaded: boolean; isEnabled: boolean },\n ) => {\n io.to('plugins').emit('plugin', shortPath, info);\n },\n );\n\n // server status events\n omegga.on('start', () =>\n io\n .to('server')\n .emit('status', { started: true, starting: false, stopping: false }),\n );\n omegga.on('server:starting', () =>\n io\n .to('server')\n .emit('status', { started: false, starting: true, stopping: false }),\n );\n omegga.on('mapchange', () =>\n io\n .to('server')\n .emit('status', { started: true, starting: false, stopping: false }),\n );\n omegga.on('server:stopped', () =>\n io\n .to('server')\n .emit('status', { started: false, starting: false, stopping: false }),\n );\n omegga.on('server:stopping', () =>\n io\n .to('server')\n .emit('status', { started: true, starting: false, stopping: true }),\n );\n}\n"],"names":["Logger","steamcmdDownloadGame","getLastSteamUpdateCheck","now","hasSteamUpdate","clearLastSteamUpdateCheck","soft"],"mappings":"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"}