omegga 1.5.0 → 1.5.1

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.
@@ -28,7 +28,12 @@
28
28
  "Bash(./target/debug/bearilog-cli compile *)",
29
29
  "Bash(cargo run *)",
30
30
  "Bash(./target/release/bearilog-cli compile *)",
31
- "Bash(BLESS=1 cargo test -p wirescript --test layout_snapshots)"
31
+ "Bash(BLESS=1 cargo test -p wirescript --test layout_snapshots)",
32
+ "Bash(cargo tree *)",
33
+ "Bash(wasm-pack build *)",
34
+ "Bash(/home/cake/git/brickadia/bearilog/target/release/bearilog-cli compile *)",
35
+ "Bash(cargo check *)",
36
+ "Bash(node bench.mjs)"
32
37
  ],
33
38
  "additionalDirectories": [
34
39
  "/home/cake/servers/omegga/qa",
package/CHANGELOG.md CHANGED
@@ -4,6 +4,11 @@
4
4
 
5
5
  Add new changes here as they are implemented
6
6
 
7
+ ## 1.5.1 - 2026-05-06
8
+
9
+ - Add `/uc on` and `/uc off` to toggle auto-update from the terminal
10
+ - Fix auto-updater throttle logic using wrong field for skip check
11
+
7
12
  ## 1.5.0 - 2026-04-28
8
13
 
9
14
  - Add utilization widget to the dashboard view
@@ -159,14 +159,28 @@ const COMMANDS = [
159
159
  },
160
160
  {
161
161
  aliases: ["updatecheck", "uc", "check"],
162
- desc: "check if a Steam update is available. use /uc show for details",
163
- fn(subcommand) {
162
+ desc: "check for updates. /uc show for details, /uc on|off to toggle auto-update",
163
+ async fn(subcommand) {
164
164
  if (!this.omegga.config.__STEAM) {
165
165
  err(
166
166
  "This command is only available when the server is installed via SteamCMD"
167
167
  );
168
168
  return;
169
169
  }
170
+ const db = this.omegga.webserver?.database;
171
+ if (subcommand === "on" || subcommand === "off") {
172
+ if (!db) {
173
+ err("Database not available.");
174
+ return;
175
+ }
176
+ const config = await db.getAutoRestartConfig();
177
+ config.autoUpdateEnabled = subcommand === "on";
178
+ await db.setAutoRestartConfig(config);
179
+ log(
180
+ subcommand === "on" ? "Auto-update enabled.".green : "Auto-update disabled.".yellow
181
+ );
182
+ return;
183
+ }
170
184
  log("Checking for updates...");
171
185
  const result = steam.steamcmdCheckUpdate(this.omegga.config.server?.steambeta);
172
186
  if (!result) {
@@ -189,6 +203,12 @@ const COMMANDS = [
189
203
  ].join("\n")
190
204
  );
191
205
  }
206
+ if (db) {
207
+ const config = await db.getAutoRestartConfig();
208
+ log(
209
+ config.autoUpdateEnabled ? `Auto-update: enabled (every ${config.autoUpdateIntervalMins}m)` : "Auto-update: disabled"
210
+ );
211
+ }
192
212
  }
193
213
  },
194
214
  {
@@ -1 +1 @@
1
- {"version":3,"file":"terminal.js","sources":["../../src/cli/terminal.ts"],"sourcesContent":["import Logger from '@/logger';\nimport { OmeggaPlayer } from '@/plugin';\nimport { steamcmdCheckUpdate, steamcmdDownloadGame } from '@/updater';\nimport Omegga from '@omegga/server';\nimport { IOmeggaOptions } from '@omegga/types';\nimport { sanitize } from '@util/chat';\nimport { checkWsl } from '@util/wsl';\nimport { serverEvents } from '@webserver/backend/events';\nimport readline from 'readline';\nimport { install } from './plugin';\n\ndeclare global {\n interface String {\n brightRed: string;\n brightGreen: string;\n brightYellow: string;\n brightBlue: string;\n brightMagenta: string;\n brightCyan: string;\n brightWhite: string;\n }\n}\n\nlet log: (...args: any[]) => void,\n err: (...args: any[]) => void,\n warn: (...args: any[]) => void,\n info: (...args: any[]) => void;\n\ntype TerminalCommand = {\n aliases: string[];\n desc: string;\n descLines?: () => string[];\n fn(this: Terminal, ...args: string[]): void | Promise<void>;\n};\n\nfunction gameCommand(\n aliases: string[],\n desc: string,\n usage: string,\n command: string,\n quoteArgs?: boolean,\n): TerminalCommand {\n return {\n aliases,\n desc,\n fn(...args) {\n if (!this.omegga.started) {\n err('The server is not running');\n return;\n }\n if (!args.length) {\n err('usage:', ('/' + aliases[0] + ' ' + usage).yellow);\n return;\n }\n this.omegga.writeln(\n `${command} ${quoteArgs ? '\"' : ''}${args.join(' ')}${\n quoteArgs ? '\"' : ''\n }`,\n );\n this.rl.prompt(true);\n },\n };\n}\n\nconst COMMANDS: TerminalCommand[] = [\n // Brickadia commands\n gameCommand(\n ['kick'],\n 'kick a player',\n '<name|id> [reason]',\n 'Chat.Command /Kick',\n ),\n gameCommand(\n ['ban', 'banish'],\n 'ban a player',\n '<name|id> [time] [reason]',\n 'Ban',\n ),\n gameCommand(\n ['unban', 'pardon'],\n 'unban a player',\n '<name|id>',\n 'Chat.Command /Unban',\n ),\n gameCommand(\n ['grantrole', 'giverole'],\n 'grant a role to a player',\n '<role> <name|id>',\n 'Chat.Command /GrantRole',\n ),\n gameCommand(\n ['revokerole', 'takerole'],\n 'revoke a role from a player',\n '<role> <name|id>',\n 'Chat.Command /RevokeRole',\n ),\n gameCommand(\n ['clearbricks'],\n \"clear a player's bricks\",\n '<name|id>',\n 'Bricks.Clear',\n true,\n ),\n gameCommand(['clearallbricks'], 'clear all bricks', '', 'Bricks.ClearAll'),\n\n // Help command\n {\n aliases: ['help', 'cmds', 'commands'],\n desc: 'list supported commands and their descriptions',\n fn() {\n const maxLen = Math.max(...COMMANDS.map(c => c.aliases[0].length));\n log('Omegga Help Text:\\n');\n log(\n ' Console input not starting with / will be sent in chat from a \"SERVER\" user',\n );\n log(\n ' Console input starting with / will be treated as one of the following commands\\n',\n );\n log(\n '-- Available Omegga commands (type',\n '/command'.yellow.underline,\n 'to run)',\n );\n\n for (const command of COMMANDS.sort((a, b) =>\n a.aliases[0].localeCompare(b.aliases[0]),\n )) {\n const name = command.aliases[0];\n this.log(\n ' ',\n ('/' + name).yellow.underline,\n '-'.padStart(maxLen - name.length + 1),\n command.desc,\n );\n if (command.descLines)\n for (const descLine of command.descLines())\n this.log(' ', ' '.repeat(maxLen + 1), descLine);\n }\n },\n },\n\n // Server controls\n {\n aliases: ['stop', 'exit', 'quit', 'close'],\n desc: 'stop the server and close Omegga',\n async fn() {\n log('Stopping server...');\n await this.omegga.stop();\n process.exit();\n },\n },\n {\n aliases: ['restart'],\n desc: 'trigger a server restart (without announcement or saving)',\n async fn() {\n log('Restarting server...');\n await this.omegga.restartServer();\n },\n },\n {\n aliases: ['update'],\n desc: 'try to update the server and restart if started (without announcement or saving',\n async fn() {\n if (!this.omegga.config.__STEAM) {\n err(\n 'This command is only available when the server is installed via SteamCMD',\n );\n return;\n }\n if (this.omegga.stopping || this.omegga.starting) {\n err(\n 'The server is currently starting or stopping. Please wait a moment',\n );\n return;\n }\n const wasStarted = this.omegga.started;\n if (wasStarted) {\n log('Stopping server to update...');\n await this.omegga.stop();\n }\n log('Updating server...');\n try {\n await steamcmdDownloadGame({\n steambeta: this.omegga.config.server?.steambeta,\n steambetaPassword: this.omegga.config.server?.steambetaPassword,\n });\n log('Server updated successfully.');\n } catch (e) {\n err('Error updating server:', e);\n }\n if (wasStarted) {\n log('Starting server...');\n await this.omegga.start();\n }\n },\n },\n {\n aliases: ['updatecheck', 'uc', 'check'],\n desc: 'check if a Steam update is available. use /uc show for details',\n fn(subcommand?: string) {\n if (!this.omegga.config.__STEAM) {\n err(\n 'This command is only available when the server is installed via SteamCMD',\n );\n return;\n }\n log('Checking for updates...');\n const result = steamcmdCheckUpdate(this.omegga.config.server?.steambeta);\n if (!result) {\n err('Failed to check for updates.');\n return;\n }\n const { local, remote, hasUpdate } = result;\n\n if (hasUpdate === true) log('Update available!'.green);\n else if (hasUpdate === false) log('Up to date.'.green);\n else log('Could not determine update status.'.yellow);\n\n if (subcommand === 'show') {\n const branch =\n local.betaKey && local.betaKey !== 'main' ? local.betaKey : 'public';\n const remoteBuild = remote?.branches?.[branch];\n const remotePart = remoteBuild\n ? `BuildID ${remoteBuild.buildid}` +\n (remoteBuild.timeupdated\n ? ` (${new Date(Number(remoteBuild.timeupdated) * 1000).toLocaleString()})`\n : '')\n : 'unknown (private branch?)';\n log(\n [\n ` Local: BuildID ${local.buildId} (${local.installState})`,\n ` Remote: ${remotePart}`,\n ` Branch: ${local.betaKey ?? 'public'}`,\n ].join('\\n'),\n );\n }\n },\n },\n {\n aliases: ['kill'],\n desc: 'forcefully kill brickadia server process without closing omegga',\n async fn() {\n log('Stopping server...');\n await this.omegga.stop();\n },\n },\n {\n aliases: ['start'],\n desc: 'start the server if it is stopped',\n fn() {\n if (\n !this.omegga ||\n (this.omegga && (this.omegga.starting || this.omegga.started))\n ) {\n err('The server is already running');\n return;\n }\n\n log('Starting server...');\n this.omegga.start();\n },\n },\n {\n aliases: ['cmd'],\n desc: 'run a console command on the Brickadia server. requires /debug for log to show',\n fn(...args) {\n if (!this.omegga.started) {\n err('The server is not running');\n return;\n }\n this.omegga.writeln(args.join(' '));\n },\n },\n {\n aliases: ['debug'],\n desc: 'toggle visibility of brickadia console logs',\n fn() {\n this.options.debug = !this.options.debug;\n log(\n 'Brickadia logs now',\n this.options.debug ? 'visible'.green : 'hidden'.red,\n );\n },\n },\n {\n aliases: ['status'],\n desc: 'display server status information. brick count, online players, etc',\n async fn() {\n if (!this.omegga.started) {\n err('Omegga is not running');\n return;\n }\n const msToTime = (ms: number) => new Date(ms).toISOString().slice(11, 19);\n try {\n const status = await this.omegga.getServerStatus();\n\n log('Server Status');\n this.log(`\n${status.serverName.yellow}\nBricks: ${(status.bricks + '').yellow}\nComponents: ${(status.components + '').yellow}\nUptime: ${msToTime(status.time).yellow}\nPlayers: ${status.players.length === 0 ? 'none'.grey : ''}\n ${status.players\n .map(p => `[${msToTime(p.time).grey}] ${p.name.brightYellow}`)\n .join('\\n ')}\n`);\n } catch (e) {\n err('An error occurred while getting server status');\n }\n },\n },\n\n // plugin stuff\n {\n aliases: ['reload'],\n desc: 'shorthand for /plugins reload',\n async fn() {\n await COMMANDS.find(c => c.aliases.includes('plugins')).fn.bind(this)(\n 'reload',\n );\n },\n },\n {\n aliases: ['plugins', 'plugin', 'p'],\n desc: 'manage Omegga plugins',\n descLines: () => [\n '/plugins install <...plugin names>'.yellow + ' installs plugins',\n '/plugins load <...plugin names>'.yellow +\n ' loads plugins, and enables if they were disabled',\n '/plugins unload <...plugin names>'.yellow + ' unloads plugins',\n '/plugins reload [...plugin names]'.yellow +\n ' reloads all plugins, or those specified',\n '/plugins enable <...plugin names>'.yellow + ' enables plugins',\n '/plugins disable <...plugin names>'.yellow +\n ' disables plugins, and unloads if they were loaded',\n ],\n async fn(subcommand: string, ...args: string[]) {\n if (!this.omegga.pluginLoader) {\n err('Omegga is not using plugins');\n return;\n }\n\n if (!subcommand) {\n const plugins = this.omegga.pluginLoader.plugins;\n if (plugins.length === 0) {\n log('No plugins are installed');\n log(' Install some with', '/plugins install'.yellow.underline);\n } else {\n log('Installed plugins'.yellow.underline);\n for (const plugin of plugins) {\n const name = plugin.getName();\n const docs = plugin.getDocumentation();\n if (plugin.isLoaded()) log(name.cyan.underline + ' (loaded)');\n else if (plugin.isEnabled())\n log(name.green.underline + ' (enabled, not loaded)');\n else log(name.red.underline + ' (disabled)');\n\n log(' ' + docs.description);\n log((' Author: ' + docs.author).gray);\n }\n }\n } else if (subcommand === 'install') {\n // install plugins\n await install(args, { verbose: true });\n log();\n log(\n 'Use',\n '/plugins reload'.yellow,\n 'to reload all plugins and use the installed ones',\n );\n } else if (subcommand === 'load') {\n if (args.length === 0) {\n log('Please specify at least one plugin to load');\n return;\n }\n\n for (const pluginName of args) {\n const plugin = this.omegga.pluginLoader.plugins.find(\n p => p.getName().toLowerCase() === pluginName.toLowerCase(),\n );\n\n if (!plugin) {\n warn('No plugin by the name', pluginName.cyan);\n continue;\n }\n\n const name = plugin.getName();\n if (plugin.isLoaded()) {\n warn(\n name.cyan,\n 'is already loaded, reload with',\n ('/plugins reload ' + name).yellow,\n );\n return;\n }\n\n if (!plugin.isEnabled()) {\n log('Enabling and loading', name.cyan.underline);\n plugin.setEnabled(true);\n await plugin.load();\n } else {\n log('Loading', name.cyan.underline);\n await plugin.load();\n }\n }\n } else if (subcommand === 'unload') {\n if (args.length === 0) {\n log('Please specify at least one plugin to unload');\n return;\n }\n\n for (const pluginName of args) {\n const plugin = this.omegga.pluginLoader.plugins.find(\n p => p.getName().toLowerCase() === pluginName.toLowerCase(),\n );\n\n if (!plugin) {\n warn('No plugin by the name', pluginName.cyan);\n continue;\n }\n\n const name = plugin.getName();\n if (!plugin.isLoaded()) {\n warn(\n name.cyan,\n 'is already unloaded, load with',\n ('/plugins load ' + name).yellow,\n );\n return;\n }\n\n log('Unloading', name.cyan.underline);\n await plugin.unload();\n }\n } else if (subcommand === 'reload') {\n let plugins = (\n args.length === 0\n ? this.omegga.pluginLoader.plugins\n : this.omegga.pluginLoader.plugins.filter(p =>\n args\n .map(a => a.toLowerCase())\n .includes(p.getName().toLowerCase()),\n )\n ).filter(p => p.isEnabled());\n\n const loaded = plugins.filter(p => p.isLoaded());\n log('Unloading', loaded.length, 'plugins');\n for (const plugin of loaded) await plugin.unload();\n\n if (args.length === 0) {\n log('Scanning for new plugins');\n if (!(await this.omegga.pluginLoader.scan())) {\n err('Could not scan for plugins. All plugins are unloaded');\n return;\n }\n }\n\n plugins = (\n args.length === 0\n ? this.omegga.pluginLoader.plugins\n : this.omegga.pluginLoader.plugins.filter(p =>\n args\n .map(a => a.toLowerCase())\n .includes(p.getName().toLowerCase()),\n )\n ).filter(p => p.isEnabled());\n log('Loading', plugins.length, 'plugins');\n for (const plugin of plugins) await plugin.load();\n\n log('Reloaded', plugins.length, 'plugins');\n } else if (subcommand === 'enable') {\n if (args.length === 0) {\n log('Please specify at least one plugin to enable');\n return;\n }\n\n for (const pluginName of args) {\n const plugin = this.omegga.pluginLoader.plugins.find(\n p => p.getName().toLowerCase() === pluginName.toLowerCase(),\n );\n\n if (!plugin) {\n warn('No plugin by the name', pluginName.cyan);\n continue;\n }\n\n const name = plugin.getName();\n if (plugin.isEnabled()) {\n warn(\n name.cyan,\n 'is already enabled, disable with',\n ('/plugins disable ' + name).yellow,\n );\n return;\n }\n\n log(\n 'Enabling',\n name.cyan.underline,\n '(load with',\n ('/plugins load ' + name).yellow + ')',\n );\n plugin.setEnabled(true);\n }\n } else if (subcommand === 'disable') {\n if (args.length === 0) {\n log('Please specify at least one plugin to disable');\n return;\n }\n\n for (const pluginName of args) {\n const plugin = this.omegga.pluginLoader.plugins.find(\n p => p.getName().toLowerCase() === pluginName.toLowerCase(),\n );\n\n if (!plugin) {\n warn('No plugin by the name', pluginName.cyan);\n continue;\n }\n\n const name = plugin.getName();\n if (!plugin.isEnabled()) {\n warn(\n name.cyan,\n 'is already disabled, enable with',\n ('/plugins enable ' + name).yellow,\n );\n return;\n }\n\n if (plugin.isLoaded()) {\n log('Unloading and disabling', name.cyan.underline);\n await plugin.unload();\n plugin.setEnabled(false);\n } else {\n log('Disabling', name.cyan.underline);\n plugin.setEnabled(false);\n }\n }\n }\n },\n },\n {\n aliases: ['world', 'worlds', 'w'],\n desc: 'Manage worlds on the server',\n descLines: () => ['Type /worlds load a world'],\n async fn(subcommand: string, ...args: string[]) {\n switch (subcommand) {\n default:\n const commands = [\n {\n command: '/worlds use [world]',\n desc: 'set or remove a world as the default world for startup',\n short: '/w u [world]',\n },\n {\n command: '/worlds load <world> [rev]',\n desc: 'load a world',\n short: '/w load <world> [rev]',\n },\n {\n command: '/worlds saveas <world>',\n desc: 'save the current world as a new world',\n short: '/w sa <world>',\n },\n {\n command: '/worlds save',\n desc: 'save the current world',\n short: '/w s',\n },\n {\n command: '/worlds revisions <world>',\n desc: 'list revisions of a world',\n short: '/w r <world>',\n },\n {\n command: '/worlds new',\n desc: 'create a new world',\n short: '/w new <name> [Plate|Space|Studio|Peaks]',\n },\n ];\n log(\n 'Default world is',\n this.omegga.getNextWorld()?.file?.yellow || 'none'.grey,\n );\n log('Available world commands:');\n for (const { command, desc, short } of commands) {\n this.log(' ', command.yellow, '-', desc, `(${short.yellow})`);\n }\n return;\n\n case 'use':\n case 'u':\n const world = args[0]?.replace(/\\.brdb$/, '');\n if (world && !this.omegga.worldExists(world)) {\n err(`World \"${world}\" does not exist`);\n return;\n }\n if (this.omegga.setActiveWorld(world || null)) {\n if (world) {\n log(\n `Default world set to ${world.yellow}. It will be loaded next startup.`,\n );\n } else {\n log(\n 'Default world cleared. No world will be loaded on next startup.',\n );\n }\n } else {\n err(`Failed to set default world to ${world.yellow}.`);\n }\n return;\n\n case 'list':\n case 'ls':\n // list worlds\n const worlds = this.omegga.getWorlds();\n if (worlds.length === 0) {\n log(\n 'No worlds found. Create one with',\n '/worlds saveas <world>'.yellow,\n );\n } else {\n log('Available worlds:');\n const prefix = this.omegga.worldPath + '/';\n for (const world of worlds) {\n this.log(\n ' ',\n world.replace(prefix, '').replace(/\\.brdb$/, '').yellow,\n );\n }\n }\n return;\n case 'load':\n case 'l':\n if (!this.omegga.started) {\n err('The server is not running');\n return;\n }\n\n // load a world\n if (args.length === 0) {\n err('Please specify a world to load');\n return;\n }\n const worldName = args[0].replace(/\\.brdb$/, '');\n if (!this.omegga.getWorldPath(worldName)) {\n err(`World \"${worldName}\" does not exist`);\n return;\n }\n let revision: number | undefined;\n if (args.length > 1) {\n revision = parseInt(args[1], 10);\n if (isNaN(revision) || revision < 1) {\n err(`Invalid revision number: ${args[1]}`);\n return;\n }\n }\n let loadRes: boolean = false;\n if (revision) {\n log(`Loading world ${worldName.yellow} at revision ${revision}...`);\n loadRes = await this.omegga.loadWorldRevision(worldName, revision);\n } else {\n log(`Loading world ${worldName.yellow}...`);\n loadRes = await this.omegga.loadWorld(worldName);\n }\n if (loadRes) {\n log(`World ${worldName.yellow} loaded successfully.`);\n } else {\n err(`Failed to load world ${worldName.yellow}`);\n }\n\n return;\n case 'saveas':\n case 'sa':\n if (!this.omegga.started) {\n err('The server is not running');\n return;\n }\n\n // save the current world as a new world\n if (args.length === 0) {\n err('Please specify a world to save as');\n return;\n }\n const saveWorldName = args[0].replace(/\\.brdb$/, '');\n if (this.omegga.getWorldPath(saveWorldName)) {\n err(`World \"${saveWorldName}\" already exists`);\n return;\n }\n log(`Saving current world as ${saveWorldName.yellow}...`);\n const saveAsRes = await this.omegga.saveWorldAs(saveWorldName);\n if (saveAsRes) {\n log(`Current world saved as ${saveWorldName.yellow} successfully.`);\n } else {\n err(`Failed to save current world as ${saveWorldName.yellow}`);\n }\n return;\n\n case 'save':\n case 's':\n if (!this.omegga.started) {\n err('The server is not running');\n return;\n }\n\n // save the current world\n log('Saving current world...');\n const res = await this.omegga.saveWorld();\n if (res) {\n log('Current world saved successfully.');\n } else {\n err('Failed to save the current world');\n }\n return;\n\n case 'revisions':\n case 'r':\n if (!this.omegga.started) {\n err('The server is not running');\n return;\n }\n\n // list revisions of a world\n if (args.length === 0) {\n err('Please specify a world to list revisions for');\n return;\n }\n const revisionsWorldName = args[0].replace(/\\.brdb$/, '');\n if (!this.omegga.getWorldPath(revisionsWorldName)) {\n err(`World \"${revisionsWorldName}\" does not exist`);\n return;\n }\n log(`Listing revisions for world ${revisionsWorldName.yellow}...`);\n try {\n const revisions =\n await this.omegga.getWorldRevisions(revisionsWorldName);\n if (revisions.length === 0) {\n log('No revisions found for world', revisionsWorldName.yellow);\n } else {\n log('Revisions for world', revisionsWorldName.yellow + ':');\n for (const rev of revisions) {\n this.log(\n ' ',\n `Revision ${rev.index.toString().yellow} - ${\n rev.date\n .toISOString()\n .replace('T', ' ')\n .replace('.000Z', '').blue\n }`,\n `(${rev.note})`.grey,\n );\n }\n }\n } catch (e) {\n err(\n 'An error occurred while getting world revisions:',\n e.toString(),\n );\n }\n return;\n\n case 'new':\n case 'n':\n if (!this.omegga.started) {\n err('The server is not running');\n return;\n }\n\n // create a new world\n if (args.length === 0) {\n err('Please specify a name for the new world');\n return;\n }\n const newWorldName = args[0].replace(/\\.brdb$/, '');\n if (this.omegga.getWorldPath(newWorldName)) {\n err(`World \"${newWorldName}\" already exists`);\n return;\n }\n const map = (args[1] ? args[1] : 'Plate') as\n | 'Plate'\n | 'Space'\n | 'Studio'\n | 'Peaks';\n if (!['Plate', 'Space', 'Studio', 'Peaks'].includes(map)) {\n err(`Invalid preset \"${map}\". Valid map are: Plate, Space, Studio`);\n return;\n }\n log(`Creating new world ${newWorldName.yellow}...`);\n this.omegga.createEmptyWorld(newWorldName, map);\n }\n },\n },\n];\n\n// the terminal wraps omegga and displays console output and handles console input\nexport default class Terminal {\n options: IOmeggaOptions;\n omegga: Omegga;\n rl: readline.Interface;\n constructor(omegga: Omegga, options: IOmeggaOptions = {}) {\n this.options = options;\n this.omegga = omegga;\n\n // terminal interface\n this.rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: true,\n });\n this.rl.setPrompt('> '.brightGreen);\n\n // shortand fns\n log = (...args) => this.log('>>'.green, ...args);\n err = (...args) => this.error('!>'.red, ...args);\n info = (...args) => this.log('?>'.blue, ...args);\n warn = (...args) => this.warn('W>'.yellow, ...args);\n\n // print log line if debug is enabled\n let launcherDone = false;\n let lastDoneMessage = '';\n omegga.on('line', l => {\n if (options.debug) this.log('::'.blue, l);\n else if (!launcherDone) {\n if (l.match(/Update Failed/)) {\n err(l);\n info(\n 'This might be resolved by deleting brickadia and reinstalling:',\n );\n info(' rm -rf ~/.local/share/brickadia-launcher'.grey);\n }\n if (l.startsWith('DOWNLOADING')) {\n // TODO: if someone is proactive enough in the future, you could turn these steps into a legitimate progress bar\n /* Here's some launcher log lines that might be helpful\n Grabbing manifest and checking game files...\n DOWNLOADING MANIFEST | Hold on...\n DOWNLOADING MANIFEST (100%) | Hold on...\n DOWNLOADING MANIFEST (100%) | 0 B/s - 13 KiB / 13 KiB (Unknown time remaining...)\n DOWNLOADING MANIFEST (100%) | Done!\n Checking launcher and downloading version info...\n Installing patches and booting...\n DOWNLOADING BRICKADIA (0%) | Done!\n DOWNLOADING BRICKADIA (100%) | 110 MiB/s - 584 MiB / 584 MiB (1 second remaining...)\n DOWNLOADING BRICKADIA (100%) | Nearly done...\n DOWNLOADING BRICKADIA (100%), INSTALLING BRICKADIA (86%) | Nearly done...\n */\n process.stdout.clearLine(0);\n process.stdout.cursorTo(0);\n process.stdout.write(l);\n // add a newline on \"Done!\" but prevent newlines on repeat done messages\n if (l.match(/Done!/) && l !== lastDoneMessage) {\n lastDoneMessage = l;\n process.stdout.write('\\n');\n }\n } else if (l.match(/Disabling core dumps./)) {\n launcherDone = true;\n }\n }\n\n // [2025.07.07-20.45.40:310][845]LogBRWorldManager: World successfully loaded.\n if (\n l.match(\n /^\\[[^\\]]+\\]\\[[^\\]]+\\]LogBRWorldManager: World successfully loaded\\.$/,\n )\n ) {\n info('World successfully loaded.');\n }\n });\n\n // print debug events regardless of debug status\n omegga.on('debug', l => this.log('?>'.magenta, l));\n\n // print chat events as players join/leave the server\n omegga.on('join', (p: OmeggaPlayer) =>\n this.log(\n `${p.displayName.underline} (${p.name.underline}) joined.`.brightBlue,\n ),\n );\n omegga.on('leave', (p: OmeggaPlayer) =>\n this.log(\n `${p.displayName.underline} (${p.name.underline}) left.`.brightBlue,\n ),\n );\n omegga.on('chat', (name, message) => {\n const player = omegga.getPlayer(name);\n this.log(\n `${(player.displayName ?? player.name ?? name).brightYellow.underline}: ${message}`,\n );\n });\n omegga.on('start', () => {\n const wsl = checkWsl();\n log(\n `Server has started${\n wsl === 1 ? ' in single thread mode due to WSL1' : ''\n }. Type ${'/help'.yellow} for more commands`,\n );\n if (!this.omegga.getNextWorld()) {\n info(\n 'No',\n 'default world'.yellow,\n 'is configured. Run',\n '/worlds use <world>'.yellow,\n 'to load one on startup.',\n );\n }\n\n // check if this is WSL2 and wsl2binds is installed\n if (\n wsl === 2 &&\n this.omegga.pluginLoader &&\n !this.omegga.pluginLoader.plugins.some(p => p.getName() === 'wsl2binds')\n ) {\n warn(\n '####'.yellow,\n `You are running ${'WSL2'.yellow} and you don't have the ${\n 'wsl2binds'.yellow\n } plugin.`,\n );\n warn(\n '####'.yellow,\n `The wsl2binds plugin works as a ${\n 'UDP proxy'.underline\n } between Windows and the WSL2 VM.`,\n );\n warn('####'.yellow, 'Install it by:');\n warn('####'.yellow, ' 1. Closing omegga with', '/stop'.green);\n warn(\n '####'.yellow,\n ' 2. Installing wsl2binds with',\n 'omegga install gh:Meshiest/wsl2binds'.green,\n );\n warn('####'.yellow, ' 3. Restarting', 'omegga'.green);\n }\n });\n omegga.on('mapchange', ({ map }) =>\n log('Map changed to', (map.charAt(0).toUpperCase() + map.slice(1)).green),\n );\n omegga.on('unauthorized', () => {\n err('Server failed authentication check');\n info('You can clear auth tokens with', 'omegga auth -gl'.green);\n info(\n 'This will require you to paste a new hosting token or sign-in again',\n );\n process.exit();\n });\n omegga.on('error', e => err('Server caught unhandled exception:\\n' + e));\n omegga.on('server:stopped', () =>\n log('Server has closed. Type', '/stop'.yellow, 'to close omegga'),\n );\n\n this.rl.on('line', this.handleLine.bind(this));\n // Gracefully shut down server on Ctrl+C and SIGTERM\n process.on('SIGINT', () => this.handleLine('/stop'));\n process.on('SIGTERM', () => this.handleLine('/stop'));\n }\n\n async handleLine(line: string) {\n if (line.startsWith('/')) {\n const [cmd, ...args] = line.slice(1).split(' ');\n const c = COMMANDS.find(c => c.aliases.includes(cmd));\n if (!c) {\n err(\n `unrecognized command /${cmd.underline}. Type /help for more info`\n .red,\n );\n } else {\n try {\n const res = c.fn.bind(this)(...args);\n if (res instanceof Promise) await res;\n } catch (e) {\n err('unhandled terminal error', e);\n }\n }\n } else if (line.trim().length > 0) {\n if (this.omegga.started) {\n // broadcast when the chat does not start with a command\n this.omegga.broadcast(\n `\"[<b><color=\\\\\"ff00ff\\\\\">SERVER</></>]: ${sanitize(line)}\"`,\n );\n process.stdout.clearLine(0);\n this.log(`[${'SERVER'.brightMagenta.underline}]: ${line}`);\n\n // if omegga is running a webserver - send this message in the chat log\n if (this.omegga.webserver) {\n const user = { name: 'SERVER', id: '', web: true, color: 'ff00ff' };\n // create database entry, send to web ui\n const chatLog = await this.omegga.webserver.database.addChatLog(\n 'msg',\n user,\n line,\n );\n serverEvents.emit('chat', chatLog);\n }\n } else {\n err(\n 'Server is not started yet. type'.red,\n '/help'.yellow,\n 'for more info'.red,\n );\n }\n }\n }\n\n // let readline render a log without interrupting user input\n log(...args: any[]) {\n process.stdout.clearLine(0);\n process.stdout.cursorTo(0);\n console.log(...Logger.timestamped(args));\n this.rl.prompt(true);\n }\n\n // let readline render a debug log without interrupting user input\n debug(...args: any[]) {\n process.stdout.clearLine(0);\n process.stdout.cursorTo(0);\n console.debug(...Logger.timestamped(args));\n this.rl.prompt(true);\n }\n\n // let readline render a warning log without interrupting user input\n warn(...args: any[]) {\n process.stdout.clearLine(0);\n process.stdout.cursorTo(0);\n console.warn(...Logger.timestamped(args));\n this.rl.prompt(true);\n }\n\n // let readline render an error log without interrupting user input\n error(...args: any[]) {\n process.stdout.clearLine(0);\n process.stdout.cursorTo(0);\n console.error(...Logger.timestamped(args));\n this.rl.prompt(true);\n }\n}\n"],"names":["steamcmdDownloadGame","steamcmdCheckUpdate","plugin","install","world","wsl","checkWsl","c","sanitize","serverEvents","Logger"],"mappings":"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"}
1
+ {"version":3,"file":"terminal.js","sources":["../../src/cli/terminal.ts"],"sourcesContent":["import Logger from '@/logger';\nimport { OmeggaPlayer } from '@/plugin';\nimport { steamcmdCheckUpdate, steamcmdDownloadGame } from '@/updater';\nimport Omegga from '@omegga/server';\nimport { IOmeggaOptions } from '@omegga/types';\nimport { sanitize } from '@util/chat';\nimport { checkWsl } from '@util/wsl';\nimport { serverEvents } from '@webserver/backend/events';\nimport readline from 'readline';\nimport { install } from './plugin';\n\ndeclare global {\n interface String {\n brightRed: string;\n brightGreen: string;\n brightYellow: string;\n brightBlue: string;\n brightMagenta: string;\n brightCyan: string;\n brightWhite: string;\n }\n}\n\nlet log: (...args: any[]) => void,\n err: (...args: any[]) => void,\n warn: (...args: any[]) => void,\n info: (...args: any[]) => void;\n\ntype TerminalCommand = {\n aliases: string[];\n desc: string;\n descLines?: () => string[];\n fn(this: Terminal, ...args: string[]): void | Promise<void>;\n};\n\nfunction gameCommand(\n aliases: string[],\n desc: string,\n usage: string,\n command: string,\n quoteArgs?: boolean,\n): TerminalCommand {\n return {\n aliases,\n desc,\n fn(...args) {\n if (!this.omegga.started) {\n err('The server is not running');\n return;\n }\n if (!args.length) {\n err('usage:', ('/' + aliases[0] + ' ' + usage).yellow);\n return;\n }\n this.omegga.writeln(\n `${command} ${quoteArgs ? '\"' : ''}${args.join(' ')}${\n quoteArgs ? '\"' : ''\n }`,\n );\n this.rl.prompt(true);\n },\n };\n}\n\nconst COMMANDS: TerminalCommand[] = [\n // Brickadia commands\n gameCommand(\n ['kick'],\n 'kick a player',\n '<name|id> [reason]',\n 'Chat.Command /Kick',\n ),\n gameCommand(\n ['ban', 'banish'],\n 'ban a player',\n '<name|id> [time] [reason]',\n 'Ban',\n ),\n gameCommand(\n ['unban', 'pardon'],\n 'unban a player',\n '<name|id>',\n 'Chat.Command /Unban',\n ),\n gameCommand(\n ['grantrole', 'giverole'],\n 'grant a role to a player',\n '<role> <name|id>',\n 'Chat.Command /GrantRole',\n ),\n gameCommand(\n ['revokerole', 'takerole'],\n 'revoke a role from a player',\n '<role> <name|id>',\n 'Chat.Command /RevokeRole',\n ),\n gameCommand(\n ['clearbricks'],\n \"clear a player's bricks\",\n '<name|id>',\n 'Bricks.Clear',\n true,\n ),\n gameCommand(['clearallbricks'], 'clear all bricks', '', 'Bricks.ClearAll'),\n\n // Help command\n {\n aliases: ['help', 'cmds', 'commands'],\n desc: 'list supported commands and their descriptions',\n fn() {\n const maxLen = Math.max(...COMMANDS.map(c => c.aliases[0].length));\n log('Omegga Help Text:\\n');\n log(\n ' Console input not starting with / will be sent in chat from a \"SERVER\" user',\n );\n log(\n ' Console input starting with / will be treated as one of the following commands\\n',\n );\n log(\n '-- Available Omegga commands (type',\n '/command'.yellow.underline,\n 'to run)',\n );\n\n for (const command of COMMANDS.sort((a, b) =>\n a.aliases[0].localeCompare(b.aliases[0]),\n )) {\n const name = command.aliases[0];\n this.log(\n ' ',\n ('/' + name).yellow.underline,\n '-'.padStart(maxLen - name.length + 1),\n command.desc,\n );\n if (command.descLines)\n for (const descLine of command.descLines())\n this.log(' ', ' '.repeat(maxLen + 1), descLine);\n }\n },\n },\n\n // Server controls\n {\n aliases: ['stop', 'exit', 'quit', 'close'],\n desc: 'stop the server and close Omegga',\n async fn() {\n log('Stopping server...');\n await this.omegga.stop();\n process.exit();\n },\n },\n {\n aliases: ['restart'],\n desc: 'trigger a server restart (without announcement or saving)',\n async fn() {\n log('Restarting server...');\n await this.omegga.restartServer();\n },\n },\n {\n aliases: ['update'],\n desc: 'try to update the server and restart if started (without announcement or saving',\n async fn() {\n if (!this.omegga.config.__STEAM) {\n err(\n 'This command is only available when the server is installed via SteamCMD',\n );\n return;\n }\n if (this.omegga.stopping || this.omegga.starting) {\n err(\n 'The server is currently starting or stopping. Please wait a moment',\n );\n return;\n }\n const wasStarted = this.omegga.started;\n if (wasStarted) {\n log('Stopping server to update...');\n await this.omegga.stop();\n }\n log('Updating server...');\n try {\n await steamcmdDownloadGame({\n steambeta: this.omegga.config.server?.steambeta,\n steambetaPassword: this.omegga.config.server?.steambetaPassword,\n });\n log('Server updated successfully.');\n } catch (e) {\n err('Error updating server:', e);\n }\n if (wasStarted) {\n log('Starting server...');\n await this.omegga.start();\n }\n },\n },\n {\n aliases: ['updatecheck', 'uc', 'check'],\n desc: 'check for updates. /uc show for details, /uc on|off to toggle auto-update',\n async fn(subcommand?: string) {\n if (!this.omegga.config.__STEAM) {\n err(\n 'This command is only available when the server is installed via SteamCMD',\n );\n return;\n }\n\n const db = this.omegga.webserver?.database;\n\n if (subcommand === 'on' || subcommand === 'off') {\n if (!db) {\n err('Database not available.');\n return;\n }\n const config = await db.getAutoRestartConfig();\n config.autoUpdateEnabled = subcommand === 'on';\n await db.setAutoRestartConfig(config);\n log(\n subcommand === 'on'\n ? 'Auto-update enabled.'.green\n : 'Auto-update disabled.'.yellow,\n );\n return;\n }\n\n log('Checking for updates...');\n const result = steamcmdCheckUpdate(this.omegga.config.server?.steambeta);\n if (!result) {\n err('Failed to check for updates.');\n return;\n }\n const { local, remote, hasUpdate } = result;\n\n if (hasUpdate === true) log('Update available!'.green);\n else if (hasUpdate === false) log('Up to date.'.green);\n else log('Could not determine update status.'.yellow);\n\n if (subcommand === 'show') {\n const branch =\n local.betaKey && local.betaKey !== 'main' ? local.betaKey : 'public';\n const remoteBuild = remote?.branches?.[branch];\n const remotePart = remoteBuild\n ? `BuildID ${remoteBuild.buildid}` +\n (remoteBuild.timeupdated\n ? ` (${new Date(Number(remoteBuild.timeupdated) * 1000).toLocaleString()})`\n : '')\n : 'unknown (private branch?)';\n log(\n [\n ` Local: BuildID ${local.buildId} (${local.installState})`,\n ` Remote: ${remotePart}`,\n ` Branch: ${local.betaKey ?? 'public'}`,\n ].join('\\n'),\n );\n }\n\n if (db) {\n const config = await db.getAutoRestartConfig();\n log(\n config.autoUpdateEnabled\n ? `Auto-update: enabled (every ${config.autoUpdateIntervalMins}m)`\n : 'Auto-update: disabled',\n );\n }\n },\n },\n {\n aliases: ['kill'],\n desc: 'forcefully kill brickadia server process without closing omegga',\n async fn() {\n log('Stopping server...');\n await this.omegga.stop();\n },\n },\n {\n aliases: ['start'],\n desc: 'start the server if it is stopped',\n fn() {\n if (\n !this.omegga ||\n (this.omegga && (this.omegga.starting || this.omegga.started))\n ) {\n err('The server is already running');\n return;\n }\n\n log('Starting server...');\n this.omegga.start();\n },\n },\n {\n aliases: ['cmd'],\n desc: 'run a console command on the Brickadia server. requires /debug for log to show',\n fn(...args) {\n if (!this.omegga.started) {\n err('The server is not running');\n return;\n }\n this.omegga.writeln(args.join(' '));\n },\n },\n {\n aliases: ['debug'],\n desc: 'toggle visibility of brickadia console logs',\n fn() {\n this.options.debug = !this.options.debug;\n log(\n 'Brickadia logs now',\n this.options.debug ? 'visible'.green : 'hidden'.red,\n );\n },\n },\n {\n aliases: ['status'],\n desc: 'display server status information. brick count, online players, etc',\n async fn() {\n if (!this.omegga.started) {\n err('Omegga is not running');\n return;\n }\n const msToTime = (ms: number) => new Date(ms).toISOString().slice(11, 19);\n try {\n const status = await this.omegga.getServerStatus();\n\n log('Server Status');\n this.log(`\n${status.serverName.yellow}\nBricks: ${(status.bricks + '').yellow}\nComponents: ${(status.components + '').yellow}\nUptime: ${msToTime(status.time).yellow}\nPlayers: ${status.players.length === 0 ? 'none'.grey : ''}\n ${status.players\n .map(p => `[${msToTime(p.time).grey}] ${p.name.brightYellow}`)\n .join('\\n ')}\n`);\n } catch (e) {\n err('An error occurred while getting server status');\n }\n },\n },\n\n // plugin stuff\n {\n aliases: ['reload'],\n desc: 'shorthand for /plugins reload',\n async fn() {\n await COMMANDS.find(c => c.aliases.includes('plugins')).fn.bind(this)(\n 'reload',\n );\n },\n },\n {\n aliases: ['plugins', 'plugin', 'p'],\n desc: 'manage Omegga plugins',\n descLines: () => [\n '/plugins install <...plugin names>'.yellow + ' installs plugins',\n '/plugins load <...plugin names>'.yellow +\n ' loads plugins, and enables if they were disabled',\n '/plugins unload <...plugin names>'.yellow + ' unloads plugins',\n '/plugins reload [...plugin names]'.yellow +\n ' reloads all plugins, or those specified',\n '/plugins enable <...plugin names>'.yellow + ' enables plugins',\n '/plugins disable <...plugin names>'.yellow +\n ' disables plugins, and unloads if they were loaded',\n ],\n async fn(subcommand: string, ...args: string[]) {\n if (!this.omegga.pluginLoader) {\n err('Omegga is not using plugins');\n return;\n }\n\n if (!subcommand) {\n const plugins = this.omegga.pluginLoader.plugins;\n if (plugins.length === 0) {\n log('No plugins are installed');\n log(' Install some with', '/plugins install'.yellow.underline);\n } else {\n log('Installed plugins'.yellow.underline);\n for (const plugin of plugins) {\n const name = plugin.getName();\n const docs = plugin.getDocumentation();\n if (plugin.isLoaded()) log(name.cyan.underline + ' (loaded)');\n else if (plugin.isEnabled())\n log(name.green.underline + ' (enabled, not loaded)');\n else log(name.red.underline + ' (disabled)');\n\n log(' ' + docs.description);\n log((' Author: ' + docs.author).gray);\n }\n }\n } else if (subcommand === 'install') {\n // install plugins\n await install(args, { verbose: true });\n log();\n log(\n 'Use',\n '/plugins reload'.yellow,\n 'to reload all plugins and use the installed ones',\n );\n } else if (subcommand === 'load') {\n if (args.length === 0) {\n log('Please specify at least one plugin to load');\n return;\n }\n\n for (const pluginName of args) {\n const plugin = this.omegga.pluginLoader.plugins.find(\n p => p.getName().toLowerCase() === pluginName.toLowerCase(),\n );\n\n if (!plugin) {\n warn('No plugin by the name', pluginName.cyan);\n continue;\n }\n\n const name = plugin.getName();\n if (plugin.isLoaded()) {\n warn(\n name.cyan,\n 'is already loaded, reload with',\n ('/plugins reload ' + name).yellow,\n );\n return;\n }\n\n if (!plugin.isEnabled()) {\n log('Enabling and loading', name.cyan.underline);\n plugin.setEnabled(true);\n await plugin.load();\n } else {\n log('Loading', name.cyan.underline);\n await plugin.load();\n }\n }\n } else if (subcommand === 'unload') {\n if (args.length === 0) {\n log('Please specify at least one plugin to unload');\n return;\n }\n\n for (const pluginName of args) {\n const plugin = this.omegga.pluginLoader.plugins.find(\n p => p.getName().toLowerCase() === pluginName.toLowerCase(),\n );\n\n if (!plugin) {\n warn('No plugin by the name', pluginName.cyan);\n continue;\n }\n\n const name = plugin.getName();\n if (!plugin.isLoaded()) {\n warn(\n name.cyan,\n 'is already unloaded, load with',\n ('/plugins load ' + name).yellow,\n );\n return;\n }\n\n log('Unloading', name.cyan.underline);\n await plugin.unload();\n }\n } else if (subcommand === 'reload') {\n let plugins = (\n args.length === 0\n ? this.omegga.pluginLoader.plugins\n : this.omegga.pluginLoader.plugins.filter(p =>\n args\n .map(a => a.toLowerCase())\n .includes(p.getName().toLowerCase()),\n )\n ).filter(p => p.isEnabled());\n\n const loaded = plugins.filter(p => p.isLoaded());\n log('Unloading', loaded.length, 'plugins');\n for (const plugin of loaded) await plugin.unload();\n\n if (args.length === 0) {\n log('Scanning for new plugins');\n if (!(await this.omegga.pluginLoader.scan())) {\n err('Could not scan for plugins. All plugins are unloaded');\n return;\n }\n }\n\n plugins = (\n args.length === 0\n ? this.omegga.pluginLoader.plugins\n : this.omegga.pluginLoader.plugins.filter(p =>\n args\n .map(a => a.toLowerCase())\n .includes(p.getName().toLowerCase()),\n )\n ).filter(p => p.isEnabled());\n log('Loading', plugins.length, 'plugins');\n for (const plugin of plugins) await plugin.load();\n\n log('Reloaded', plugins.length, 'plugins');\n } else if (subcommand === 'enable') {\n if (args.length === 0) {\n log('Please specify at least one plugin to enable');\n return;\n }\n\n for (const pluginName of args) {\n const plugin = this.omegga.pluginLoader.plugins.find(\n p => p.getName().toLowerCase() === pluginName.toLowerCase(),\n );\n\n if (!plugin) {\n warn('No plugin by the name', pluginName.cyan);\n continue;\n }\n\n const name = plugin.getName();\n if (plugin.isEnabled()) {\n warn(\n name.cyan,\n 'is already enabled, disable with',\n ('/plugins disable ' + name).yellow,\n );\n return;\n }\n\n log(\n 'Enabling',\n name.cyan.underline,\n '(load with',\n ('/plugins load ' + name).yellow + ')',\n );\n plugin.setEnabled(true);\n }\n } else if (subcommand === 'disable') {\n if (args.length === 0) {\n log('Please specify at least one plugin to disable');\n return;\n }\n\n for (const pluginName of args) {\n const plugin = this.omegga.pluginLoader.plugins.find(\n p => p.getName().toLowerCase() === pluginName.toLowerCase(),\n );\n\n if (!plugin) {\n warn('No plugin by the name', pluginName.cyan);\n continue;\n }\n\n const name = plugin.getName();\n if (!plugin.isEnabled()) {\n warn(\n name.cyan,\n 'is already disabled, enable with',\n ('/plugins enable ' + name).yellow,\n );\n return;\n }\n\n if (plugin.isLoaded()) {\n log('Unloading and disabling', name.cyan.underline);\n await plugin.unload();\n plugin.setEnabled(false);\n } else {\n log('Disabling', name.cyan.underline);\n plugin.setEnabled(false);\n }\n }\n }\n },\n },\n {\n aliases: ['world', 'worlds', 'w'],\n desc: 'Manage worlds on the server',\n descLines: () => ['Type /worlds load a world'],\n async fn(subcommand: string, ...args: string[]) {\n switch (subcommand) {\n default:\n const commands = [\n {\n command: '/worlds use [world]',\n desc: 'set or remove a world as the default world for startup',\n short: '/w u [world]',\n },\n {\n command: '/worlds load <world> [rev]',\n desc: 'load a world',\n short: '/w load <world> [rev]',\n },\n {\n command: '/worlds saveas <world>',\n desc: 'save the current world as a new world',\n short: '/w sa <world>',\n },\n {\n command: '/worlds save',\n desc: 'save the current world',\n short: '/w s',\n },\n {\n command: '/worlds revisions <world>',\n desc: 'list revisions of a world',\n short: '/w r <world>',\n },\n {\n command: '/worlds new',\n desc: 'create a new world',\n short: '/w new <name> [Plate|Space|Studio|Peaks]',\n },\n ];\n log(\n 'Default world is',\n this.omegga.getNextWorld()?.file?.yellow || 'none'.grey,\n );\n log('Available world commands:');\n for (const { command, desc, short } of commands) {\n this.log(' ', command.yellow, '-', desc, `(${short.yellow})`);\n }\n return;\n\n case 'use':\n case 'u':\n const world = args[0]?.replace(/\\.brdb$/, '');\n if (world && !this.omegga.worldExists(world)) {\n err(`World \"${world}\" does not exist`);\n return;\n }\n if (this.omegga.setActiveWorld(world || null)) {\n if (world) {\n log(\n `Default world set to ${world.yellow}. It will be loaded next startup.`,\n );\n } else {\n log(\n 'Default world cleared. No world will be loaded on next startup.',\n );\n }\n } else {\n err(`Failed to set default world to ${world.yellow}.`);\n }\n return;\n\n case 'list':\n case 'ls':\n // list worlds\n const worlds = this.omegga.getWorlds();\n if (worlds.length === 0) {\n log(\n 'No worlds found. Create one with',\n '/worlds saveas <world>'.yellow,\n );\n } else {\n log('Available worlds:');\n const prefix = this.omegga.worldPath + '/';\n for (const world of worlds) {\n this.log(\n ' ',\n world.replace(prefix, '').replace(/\\.brdb$/, '').yellow,\n );\n }\n }\n return;\n case 'load':\n case 'l':\n if (!this.omegga.started) {\n err('The server is not running');\n return;\n }\n\n // load a world\n if (args.length === 0) {\n err('Please specify a world to load');\n return;\n }\n const worldName = args[0].replace(/\\.brdb$/, '');\n if (!this.omegga.getWorldPath(worldName)) {\n err(`World \"${worldName}\" does not exist`);\n return;\n }\n let revision: number | undefined;\n if (args.length > 1) {\n revision = parseInt(args[1], 10);\n if (isNaN(revision) || revision < 1) {\n err(`Invalid revision number: ${args[1]}`);\n return;\n }\n }\n let loadRes: boolean = false;\n if (revision) {\n log(`Loading world ${worldName.yellow} at revision ${revision}...`);\n loadRes = await this.omegga.loadWorldRevision(worldName, revision);\n } else {\n log(`Loading world ${worldName.yellow}...`);\n loadRes = await this.omegga.loadWorld(worldName);\n }\n if (loadRes) {\n log(`World ${worldName.yellow} loaded successfully.`);\n } else {\n err(`Failed to load world ${worldName.yellow}`);\n }\n\n return;\n case 'saveas':\n case 'sa':\n if (!this.omegga.started) {\n err('The server is not running');\n return;\n }\n\n // save the current world as a new world\n if (args.length === 0) {\n err('Please specify a world to save as');\n return;\n }\n const saveWorldName = args[0].replace(/\\.brdb$/, '');\n if (this.omegga.getWorldPath(saveWorldName)) {\n err(`World \"${saveWorldName}\" already exists`);\n return;\n }\n log(`Saving current world as ${saveWorldName.yellow}...`);\n const saveAsRes = await this.omegga.saveWorldAs(saveWorldName);\n if (saveAsRes) {\n log(`Current world saved as ${saveWorldName.yellow} successfully.`);\n } else {\n err(`Failed to save current world as ${saveWorldName.yellow}`);\n }\n return;\n\n case 'save':\n case 's':\n if (!this.omegga.started) {\n err('The server is not running');\n return;\n }\n\n // save the current world\n log('Saving current world...');\n const res = await this.omegga.saveWorld();\n if (res) {\n log('Current world saved successfully.');\n } else {\n err('Failed to save the current world');\n }\n return;\n\n case 'revisions':\n case 'r':\n if (!this.omegga.started) {\n err('The server is not running');\n return;\n }\n\n // list revisions of a world\n if (args.length === 0) {\n err('Please specify a world to list revisions for');\n return;\n }\n const revisionsWorldName = args[0].replace(/\\.brdb$/, '');\n if (!this.omegga.getWorldPath(revisionsWorldName)) {\n err(`World \"${revisionsWorldName}\" does not exist`);\n return;\n }\n log(`Listing revisions for world ${revisionsWorldName.yellow}...`);\n try {\n const revisions =\n await this.omegga.getWorldRevisions(revisionsWorldName);\n if (revisions.length === 0) {\n log('No revisions found for world', revisionsWorldName.yellow);\n } else {\n log('Revisions for world', revisionsWorldName.yellow + ':');\n for (const rev of revisions) {\n this.log(\n ' ',\n `Revision ${rev.index.toString().yellow} - ${\n rev.date\n .toISOString()\n .replace('T', ' ')\n .replace('.000Z', '').blue\n }`,\n `(${rev.note})`.grey,\n );\n }\n }\n } catch (e) {\n err(\n 'An error occurred while getting world revisions:',\n e.toString(),\n );\n }\n return;\n\n case 'new':\n case 'n':\n if (!this.omegga.started) {\n err('The server is not running');\n return;\n }\n\n // create a new world\n if (args.length === 0) {\n err('Please specify a name for the new world');\n return;\n }\n const newWorldName = args[0].replace(/\\.brdb$/, '');\n if (this.omegga.getWorldPath(newWorldName)) {\n err(`World \"${newWorldName}\" already exists`);\n return;\n }\n const map = (args[1] ? args[1] : 'Plate') as\n | 'Plate'\n | 'Space'\n | 'Studio'\n | 'Peaks';\n if (!['Plate', 'Space', 'Studio', 'Peaks'].includes(map)) {\n err(`Invalid preset \"${map}\". Valid map are: Plate, Space, Studio`);\n return;\n }\n log(`Creating new world ${newWorldName.yellow}...`);\n this.omegga.createEmptyWorld(newWorldName, map);\n }\n },\n },\n];\n\n// the terminal wraps omegga and displays console output and handles console input\nexport default class Terminal {\n options: IOmeggaOptions;\n omegga: Omegga;\n rl: readline.Interface;\n constructor(omegga: Omegga, options: IOmeggaOptions = {}) {\n this.options = options;\n this.omegga = omegga;\n\n // terminal interface\n this.rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: true,\n });\n this.rl.setPrompt('> '.brightGreen);\n\n // shortand fns\n log = (...args) => this.log('>>'.green, ...args);\n err = (...args) => this.error('!>'.red, ...args);\n info = (...args) => this.log('?>'.blue, ...args);\n warn = (...args) => this.warn('W>'.yellow, ...args);\n\n // print log line if debug is enabled\n let launcherDone = false;\n let lastDoneMessage = '';\n omegga.on('line', l => {\n if (options.debug) this.log('::'.blue, l);\n else if (!launcherDone) {\n if (l.match(/Update Failed/)) {\n err(l);\n info(\n 'This might be resolved by deleting brickadia and reinstalling:',\n );\n info(' rm -rf ~/.local/share/brickadia-launcher'.grey);\n }\n if (l.startsWith('DOWNLOADING')) {\n // TODO: if someone is proactive enough in the future, you could turn these steps into a legitimate progress bar\n /* Here's some launcher log lines that might be helpful\n Grabbing manifest and checking game files...\n DOWNLOADING MANIFEST | Hold on...\n DOWNLOADING MANIFEST (100%) | Hold on...\n DOWNLOADING MANIFEST (100%) | 0 B/s - 13 KiB / 13 KiB (Unknown time remaining...)\n DOWNLOADING MANIFEST (100%) | Done!\n Checking launcher and downloading version info...\n Installing patches and booting...\n DOWNLOADING BRICKADIA (0%) | Done!\n DOWNLOADING BRICKADIA (100%) | 110 MiB/s - 584 MiB / 584 MiB (1 second remaining...)\n DOWNLOADING BRICKADIA (100%) | Nearly done...\n DOWNLOADING BRICKADIA (100%), INSTALLING BRICKADIA (86%) | Nearly done...\n */\n process.stdout.clearLine(0);\n process.stdout.cursorTo(0);\n process.stdout.write(l);\n // add a newline on \"Done!\" but prevent newlines on repeat done messages\n if (l.match(/Done!/) && l !== lastDoneMessage) {\n lastDoneMessage = l;\n process.stdout.write('\\n');\n }\n } else if (l.match(/Disabling core dumps./)) {\n launcherDone = true;\n }\n }\n\n // [2025.07.07-20.45.40:310][845]LogBRWorldManager: World successfully loaded.\n if (\n l.match(\n /^\\[[^\\]]+\\]\\[[^\\]]+\\]LogBRWorldManager: World successfully loaded\\.$/,\n )\n ) {\n info('World successfully loaded.');\n }\n });\n\n // print debug events regardless of debug status\n omegga.on('debug', l => this.log('?>'.magenta, l));\n\n // print chat events as players join/leave the server\n omegga.on('join', (p: OmeggaPlayer) =>\n this.log(\n `${p.displayName.underline} (${p.name.underline}) joined.`.brightBlue,\n ),\n );\n omegga.on('leave', (p: OmeggaPlayer) =>\n this.log(\n `${p.displayName.underline} (${p.name.underline}) left.`.brightBlue,\n ),\n );\n omegga.on('chat', (name, message) => {\n const player = omegga.getPlayer(name);\n this.log(\n `${(player.displayName ?? player.name ?? name).brightYellow.underline}: ${message}`,\n );\n });\n omegga.on('start', () => {\n const wsl = checkWsl();\n log(\n `Server has started${\n wsl === 1 ? ' in single thread mode due to WSL1' : ''\n }. Type ${'/help'.yellow} for more commands`,\n );\n if (!this.omegga.getNextWorld()) {\n info(\n 'No',\n 'default world'.yellow,\n 'is configured. Run',\n '/worlds use <world>'.yellow,\n 'to load one on startup.',\n );\n }\n\n // check if this is WSL2 and wsl2binds is installed\n if (\n wsl === 2 &&\n this.omegga.pluginLoader &&\n !this.omegga.pluginLoader.plugins.some(p => p.getName() === 'wsl2binds')\n ) {\n warn(\n '####'.yellow,\n `You are running ${'WSL2'.yellow} and you don't have the ${\n 'wsl2binds'.yellow\n } plugin.`,\n );\n warn(\n '####'.yellow,\n `The wsl2binds plugin works as a ${\n 'UDP proxy'.underline\n } between Windows and the WSL2 VM.`,\n );\n warn('####'.yellow, 'Install it by:');\n warn('####'.yellow, ' 1. Closing omegga with', '/stop'.green);\n warn(\n '####'.yellow,\n ' 2. Installing wsl2binds with',\n 'omegga install gh:Meshiest/wsl2binds'.green,\n );\n warn('####'.yellow, ' 3. Restarting', 'omegga'.green);\n }\n });\n omegga.on('mapchange', ({ map }) =>\n log('Map changed to', (map.charAt(0).toUpperCase() + map.slice(1)).green),\n );\n omegga.on('unauthorized', () => {\n err('Server failed authentication check');\n info('You can clear auth tokens with', 'omegga auth -gl'.green);\n info(\n 'This will require you to paste a new hosting token or sign-in again',\n );\n process.exit();\n });\n omegga.on('error', e => err('Server caught unhandled exception:\\n' + e));\n omegga.on('server:stopped', () =>\n log('Server has closed. Type', '/stop'.yellow, 'to close omegga'),\n );\n\n this.rl.on('line', this.handleLine.bind(this));\n // Gracefully shut down server on Ctrl+C and SIGTERM\n process.on('SIGINT', () => this.handleLine('/stop'));\n process.on('SIGTERM', () => this.handleLine('/stop'));\n }\n\n async handleLine(line: string) {\n if (line.startsWith('/')) {\n const [cmd, ...args] = line.slice(1).split(' ');\n const c = COMMANDS.find(c => c.aliases.includes(cmd));\n if (!c) {\n err(\n `unrecognized command /${cmd.underline}. Type /help for more info`\n .red,\n );\n } else {\n try {\n const res = c.fn.bind(this)(...args);\n if (res instanceof Promise) await res;\n } catch (e) {\n err('unhandled terminal error', e);\n }\n }\n } else if (line.trim().length > 0) {\n if (this.omegga.started) {\n // broadcast when the chat does not start with a command\n this.omegga.broadcast(\n `\"[<b><color=\\\\\"ff00ff\\\\\">SERVER</></>]: ${sanitize(line)}\"`,\n );\n process.stdout.clearLine(0);\n this.log(`[${'SERVER'.brightMagenta.underline}]: ${line}`);\n\n // if omegga is running a webserver - send this message in the chat log\n if (this.omegga.webserver) {\n const user = { name: 'SERVER', id: '', web: true, color: 'ff00ff' };\n // create database entry, send to web ui\n const chatLog = await this.omegga.webserver.database.addChatLog(\n 'msg',\n user,\n line,\n );\n serverEvents.emit('chat', chatLog);\n }\n } else {\n err(\n 'Server is not started yet. type'.red,\n '/help'.yellow,\n 'for more info'.red,\n );\n }\n }\n }\n\n // let readline render a log without interrupting user input\n log(...args: any[]) {\n process.stdout.clearLine(0);\n process.stdout.cursorTo(0);\n console.log(...Logger.timestamped(args));\n this.rl.prompt(true);\n }\n\n // let readline render a debug log without interrupting user input\n debug(...args: any[]) {\n process.stdout.clearLine(0);\n process.stdout.cursorTo(0);\n console.debug(...Logger.timestamped(args));\n this.rl.prompt(true);\n }\n\n // let readline render a warning log without interrupting user input\n warn(...args: any[]) {\n process.stdout.clearLine(0);\n process.stdout.cursorTo(0);\n console.warn(...Logger.timestamped(args));\n this.rl.prompt(true);\n }\n\n // let readline render an error log without interrupting user input\n error(...args: any[]) {\n process.stdout.clearLine(0);\n process.stdout.cursorTo(0);\n console.error(...Logger.timestamped(args));\n this.rl.prompt(true);\n }\n}\n"],"names":["steamcmdDownloadGame","steamcmdCheckUpdate","plugin","install","world","wsl","checkWsl","c","sanitize","serverEvents","Logger"],"mappings":"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"}
@@ -141,12 +141,12 @@ function setupMetrics(server) {
141
141
  omegga.once("mapchange", () => {
142
142
  omegga.restoreServer();
143
143
  });
144
- if (update && omegga.config.__STEAM && !omegga.config.server?.steambetaPassword) {
144
+ if (update && omegga.config.__STEAM) {
145
145
  logger.default.logp("Stopping server for auto-update...");
146
146
  await omegga.stop();
147
147
  logger.default.logp("Downloading update...");
148
148
  try {
149
- steam.steamcmdDownloadGame({
149
+ await steam.steamcmdDownloadGame({
150
150
  steambeta: omegga.config.server?.steambeta
151
151
  });
152
152
  } catch (e) {
@@ -183,13 +183,9 @@ function setupMetrics(server) {
183
183
  return await restartServer(config);
184
184
  }
185
185
  const lastCheck = steam.getLastSteamUpdateCheck();
186
- if (omegga.config.__STEAM && config.autoUpdateEnabled && !omegga.config.server?.steambetaPassword) {
186
+ if (omegga.config.__STEAM && config.autoUpdateEnabled) {
187
187
  const now2 = Date.now();
188
- if (
189
- // If there is no update
190
- !lastCheck.available && // And the last update was too recent
191
- now2 - lastCheck.attempt < config.autoUpdateIntervalMins * 60 * 1e3
192
- ) {
188
+ if (!lastCheck.result && now2 - lastCheck.attempt < config.autoUpdateIntervalMins * 60 * 1e3) {
193
189
  logger.default.verbose(
194
190
  `Skipping auto update check, last check was ${Math.floor(
195
191
  (now2 - lastCheck.attempt) / 1e3 / 60
@@ -254,7 +250,7 @@ function setupMetrics(server) {
254
250
  };
255
251
  await database.addHeartbeat(data);
256
252
  } catch (e) {
257
- error("Server Not Responding...");
253
+ error("Server Not Responding...", e);
258
254
  }
259
255
  }, softconfig.default.METRIC_HEARTBEAT_INTERVAL);
260
256
  omegga.on("chat", async (name, message) => {
@@ -1 +1 @@
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 { readFileSync, statfsSync } from 'fs';\nimport os from 'os';\nimport { serverEvents } from './events';\nimport type Webserver from './index';\nimport type { IStoreAutoRestartConfig, SystemUtilization } from './types';\n\nlet prevCpuIdle = 0;\nlet prevCpuTotal = 0;\nlet prevNetRx = 0;\nlet prevNetTx = 0;\nlet prevNetTime = 0;\n\nfunction getCpuUsage(): number {\n const cpus = os.cpus();\n let idle = 0;\n let total = 0;\n for (const cpu of cpus) {\n idle += cpu.times.idle;\n total +=\n cpu.times.user +\n cpu.times.nice +\n cpu.times.sys +\n cpu.times.irq +\n cpu.times.idle;\n }\n const dIdle = idle - prevCpuIdle;\n const dTotal = total - prevCpuTotal;\n prevCpuIdle = idle;\n prevCpuTotal = total;\n if (dTotal === 0) return 0;\n return Math.round((1 - dIdle / dTotal) * 100);\n}\n\nfunction getDiskUsage(path: string): { used: number; total: number } {\n try {\n const stat = statfsSync(path);\n const total = stat.blocks * stat.bsize;\n const free = stat.bfree * stat.bsize;\n return { used: total - free, total };\n } catch {\n return { used: 0, total: 1 };\n }\n}\n\nfunction getNetworkBytes(): { rx: number; tx: number } {\n if (process.platform !== 'linux') return { rx: 0, tx: 0 };\n try {\n const data = readFileSync('/proc/net/dev', 'utf8');\n let rx = 0;\n let tx = 0;\n for (const line of data.split('\\n').slice(2)) {\n const parts = line.trim().split(/\\s+/);\n if (!parts[0] || parts[0] === 'lo:') continue;\n rx += Number(parts[1]) || 0;\n tx += Number(parts[9]) || 0;\n }\n return { rx, tx };\n } catch {\n return { rx: 0, tx: 0 };\n }\n}\n\nconst UTILIZATION_HISTORY_LEN = 30;\nlet lastUtilization: SystemUtilization | null = null;\nconst utilizationHistory: SystemUtilization[] = [];\n\nexport function getLastUtilization(): {\n current: SystemUtilization | null;\n history: SystemUtilization[];\n} {\n return { current: lastUtilization, history: utilizationHistory };\n}\n\nfunction pushHistory(util: SystemUtilization) {\n utilizationHistory.push(util);\n if (utilizationHistory.length > UTILIZATION_HISTORY_LEN) {\n utilizationHistory.shift();\n }\n}\n\nfunction collectUtilization(omeggaPath: string): SystemUtilization {\n const cpu = getCpuUsage();\n const totalMem = os.totalmem();\n const freeMem = os.freemem();\n const disk = getDiskUsage(omeggaPath);\n const net = getNetworkBytes();\n const now = Date.now();\n const dt = prevNetTime ? (now - prevNetTime) / 1000 : 1;\n const rxSec = prevNetTime ? Math.max(0, (net.rx - prevNetRx) / dt) : 0;\n const txSec = prevNetTime ? Math.max(0, (net.tx - prevNetTx) / dt) : 0;\n prevNetRx = net.rx;\n prevNetTx = net.tx;\n prevNetTime = now;\n return {\n cpu,\n mem: { used: totalMem - freeMem, total: totalMem },\n disk,\n net: { rxSec, txSec },\n };\n}\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) {\n const { database, omegga } = server;\n\n // Prime CPU and network counters so the first real snapshot reflects a\n // short interval rather than computing a delta from zero (host uptime).\n getCpuUsage();\n getNetworkBytes();\n\n // Collect initial utilization snapshot so queries return data immediately\n lastUtilization = collectUtilization(omegga.path);\n pushHistory(lastUtilization);\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 via serverEvents\n server.lastReportedStatus = status;\n serverEvents.emit('heartbeat', status);\n\n // collect and emit system utilization metrics\n const utilization = collectUtilization(omegga.path);\n lastUtilization = utilization;\n pushHistory(utilization);\n serverEvents.emit('utilization', utilization);\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 serverEvents.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 serverEvents.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 serverEvents.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 serverEvents.emit('plugin', { shortPath, ...info });\n },\n );\n\n // server status events\n omegga.on('start', () =>\n serverEvents.emit('serverStatus', {\n started: true,\n starting: false,\n stopping: false,\n }),\n );\n omegga.on('server:starting', () =>\n serverEvents.emit('serverStatus', {\n started: false,\n starting: true,\n stopping: false,\n }),\n );\n omegga.on('mapchange', () =>\n serverEvents.emit('serverStatus', {\n started: true,\n starting: false,\n stopping: false,\n }),\n );\n omegga.on('server:stopped', () =>\n serverEvents.emit('serverStatus', {\n started: false,\n starting: false,\n stopping: false,\n }),\n );\n omegga.on('server:stopping', () =>\n serverEvents.emit('serverStatus', {\n started: true,\n starting: false,\n stopping: true,\n }),\n );\n}\n"],"names":["statfsSync","readFileSync","Logger","steamcmdDownloadGame","getLastSteamUpdateCheck","now","hasSteamUpdate","clearLastSteamUpdateCheck","serverEvents","soft"],"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 { readFileSync, statfsSync } from 'fs';\nimport os from 'os';\nimport { serverEvents } from './events';\nimport type Webserver from './index';\nimport type { IStoreAutoRestartConfig, SystemUtilization } from './types';\n\nlet prevCpuIdle = 0;\nlet prevCpuTotal = 0;\nlet prevNetRx = 0;\nlet prevNetTx = 0;\nlet prevNetTime = 0;\n\nfunction getCpuUsage(): number {\n const cpus = os.cpus();\n let idle = 0;\n let total = 0;\n for (const cpu of cpus) {\n idle += cpu.times.idle;\n total +=\n cpu.times.user +\n cpu.times.nice +\n cpu.times.sys +\n cpu.times.irq +\n cpu.times.idle;\n }\n const dIdle = idle - prevCpuIdle;\n const dTotal = total - prevCpuTotal;\n prevCpuIdle = idle;\n prevCpuTotal = total;\n if (dTotal === 0) return 0;\n return Math.round((1 - dIdle / dTotal) * 100);\n}\n\nfunction getDiskUsage(path: string): { used: number; total: number } {\n try {\n const stat = statfsSync(path);\n const total = stat.blocks * stat.bsize;\n const free = stat.bfree * stat.bsize;\n return { used: total - free, total };\n } catch {\n return { used: 0, total: 1 };\n }\n}\n\nfunction getNetworkBytes(): { rx: number; tx: number } {\n if (process.platform !== 'linux') return { rx: 0, tx: 0 };\n try {\n const data = readFileSync('/proc/net/dev', 'utf8');\n let rx = 0;\n let tx = 0;\n for (const line of data.split('\\n').slice(2)) {\n const parts = line.trim().split(/\\s+/);\n if (!parts[0] || parts[0] === 'lo:') continue;\n rx += Number(parts[1]) || 0;\n tx += Number(parts[9]) || 0;\n }\n return { rx, tx };\n } catch {\n return { rx: 0, tx: 0 };\n }\n}\n\nconst UTILIZATION_HISTORY_LEN = 30;\nlet lastUtilization: SystemUtilization | null = null;\nconst utilizationHistory: SystemUtilization[] = [];\n\nexport function getLastUtilization(): {\n current: SystemUtilization | null;\n history: SystemUtilization[];\n} {\n return { current: lastUtilization, history: utilizationHistory };\n}\n\nfunction pushHistory(util: SystemUtilization) {\n utilizationHistory.push(util);\n if (utilizationHistory.length > UTILIZATION_HISTORY_LEN) {\n utilizationHistory.shift();\n }\n}\n\nfunction collectUtilization(omeggaPath: string): SystemUtilization {\n const cpu = getCpuUsage();\n const totalMem = os.totalmem();\n const freeMem = os.freemem();\n const disk = getDiskUsage(omeggaPath);\n const net = getNetworkBytes();\n const now = Date.now();\n const dt = prevNetTime ? (now - prevNetTime) / 1000 : 1;\n const rxSec = prevNetTime ? Math.max(0, (net.rx - prevNetRx) / dt) : 0;\n const txSec = prevNetTime ? Math.max(0, (net.tx - prevNetTx) / dt) : 0;\n prevNetRx = net.rx;\n prevNetTx = net.tx;\n prevNetTime = now;\n return {\n cpu,\n mem: { used: totalMem - freeMem, total: totalMem },\n disk,\n net: { rxSec, txSec },\n };\n}\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) {\n const { database, omegga } = server;\n\n // Prime CPU and network counters so the first real snapshot reflects a\n // short interval rather than computing a delta from zero (host uptime).\n getCpuUsage();\n getNetworkBytes();\n\n // Collect initial utilization snapshot so queries return data immediately\n lastUtilization = collectUtilization(omegga.path);\n pushHistory(lastUtilization);\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 (update && omegga.config.__STEAM) {\n Logger.logp('Stopping server for auto-update...');\n await omegga.stop();\n Logger.logp('Downloading update...');\n try {\n await 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 const lastCheck = getLastSteamUpdateCheck();\n if (omegga.config.__STEAM && config.autoUpdateEnabled) {\n const now = Date.now();\n if (\n !lastCheck.result &&\n now - lastCheck.attempt < config.autoUpdateIntervalMins * 60 * 1000\n ) {\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 via serverEvents\n server.lastReportedStatus = status;\n serverEvents.emit('heartbeat', status);\n\n // collect and emit system utilization metrics\n const utilization = collectUtilization(omegga.path);\n lastUtilization = utilization;\n pushHistory(utilization);\n serverEvents.emit('utilization', utilization);\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...', e);\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 serverEvents.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 serverEvents.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 serverEvents.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 serverEvents.emit('plugin', { shortPath, ...info });\n },\n );\n\n // server status events\n omegga.on('start', () =>\n serverEvents.emit('serverStatus', {\n started: true,\n starting: false,\n stopping: false,\n }),\n );\n omegga.on('server:starting', () =>\n serverEvents.emit('serverStatus', {\n started: false,\n starting: true,\n stopping: false,\n }),\n );\n omegga.on('mapchange', () =>\n serverEvents.emit('serverStatus', {\n started: true,\n starting: false,\n stopping: false,\n }),\n );\n omegga.on('server:stopped', () =>\n serverEvents.emit('serverStatus', {\n started: false,\n starting: false,\n stopping: false,\n }),\n );\n omegga.on('server:stopping', () =>\n serverEvents.emit('serverStatus', {\n started: true,\n starting: false,\n stopping: true,\n }),\n );\n}\n"],"names":["statfsSync","readFileSync","Logger","steamcmdDownloadGame","getLastSteamUpdateCheck","now","hasSteamUpdate","clearLastSteamUpdateCheck","serverEvents","soft"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omegga",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "description": "Brickadia server installer, updater, manager, wrapper, configurator, and automator",
5
5
  "engines": {
6
6
  "node": ">=23.0.0"