omegga 1.3.0 → 1.4.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.
Files changed (121) hide show
  1. package/.claude/settings.local.json +17 -0
  2. package/README.md +39 -10
  3. package/bin/omegga +1 -1
  4. package/dist/brickadia/server.js +4 -8
  5. package/dist/brickadia/server.js.map +1 -1
  6. package/dist/index.js +6 -6
  7. package/dist/main.js +8 -7
  8. package/dist/main.js.map +1 -1
  9. package/dist/omegga/player.js +59 -25
  10. package/dist/omegga/player.js.map +1 -1
  11. package/dist/omegga/plugin/plugin_jsonrpc_stdio.js +54 -0
  12. package/dist/omegga/plugin/plugin_jsonrpc_stdio.js.map +1 -1
  13. package/dist/omegga/plugin/plugin_node_unsafe.js +6 -0
  14. package/dist/omegga/plugin/plugin_node_unsafe.js.map +1 -1
  15. package/dist/omegga/server.js +35 -1
  16. package/dist/omegga/server.js.map +1 -1
  17. package/dist/omegga/wrapper.js +1 -0
  18. package/dist/omegga/wrapper.js.map +1 -1
  19. package/dist/plugin.js +1 -2
  20. package/dist/plugin.js.map +1 -1
  21. package/dist/softconfig.js +33 -15
  22. package/dist/softconfig.js.map +1 -1
  23. package/dist/updater/steam.js +65 -12
  24. package/dist/updater/steam.js.map +1 -1
  25. package/dist/util/brick/checkBounds.js +1 -2
  26. package/dist/util/brick/checkBounds.js.map +1 -1
  27. package/dist/util/brick/displayName.js +1 -2
  28. package/dist/util/brick/displayName.js.map +1 -1
  29. package/dist/util/brick/getBounds.js +1 -2
  30. package/dist/util/brick/getBounds.js.map +1 -1
  31. package/dist/util/brick/getBrickSize.js +1 -2
  32. package/dist/util/brick/getBrickSize.js.map +1 -1
  33. package/dist/util/brick/getScaleAxis.js +1 -2
  34. package/dist/util/brick/getScaleAxis.js.map +1 -1
  35. package/dist/util/brick/setOwnership.js +1 -2
  36. package/dist/util/brick/setOwnership.js.map +1 -1
  37. package/dist/webserver/backend/api.js +2 -1
  38. package/dist/webserver/backend/api.js.map +1 -1
  39. package/dist/webserver/backend/database.js +3 -1
  40. package/dist/webserver/backend/database.js.map +1 -1
  41. package/package.json +3 -2
  42. package/public/app.html +18 -18
  43. package/public/assets/IconArrowRight-BuVxhqKX.js +2 -0
  44. package/public/assets/{IconArrowRight-CA5_cccJ.js.map → IconArrowRight-BuVxhqKX.js.map} +1 -1
  45. package/public/assets/IconCheck-DOe3u7iH.js +2 -0
  46. package/public/assets/{IconCheck-Dyq5qyY1.js.map → IconCheck-DOe3u7iH.js.map} +1 -1
  47. package/public/assets/IconLockOpen-Bs7Tsf6u.js +2 -0
  48. package/public/assets/{IconLockOpen-D95XLORK.js.map → IconLockOpen-Bs7Tsf6u.js.map} +1 -1
  49. package/public/assets/IconWorld-B6GK5qpx.js +2 -0
  50. package/public/assets/{IconWorld-DtARpBKX.js.map → IconWorld-B6GK5qpx.js.map} +1 -1
  51. package/public/assets/IconWorldPlus-DpfueG8_.js +2 -0
  52. package/public/assets/{IconWorldPlus-CGBAsLNj.js.map → IconWorldPlus-DpfueG8_.js.map} +1 -1
  53. package/public/assets/IconX-CvmO0bbE.js +2 -0
  54. package/public/assets/{IconX-SYtbnYKI.js.map → IconX-CvmO0bbE.js.map} +1 -1
  55. package/public/assets/app-S3WcjD4u.js +6 -0
  56. package/public/assets/{app-BtOlgo__.js.map → app-S3WcjD4u.js.map} +1 -1
  57. package/public/assets/{auth-CvxEWAMc.js → auth-6N37o421.js} +2 -2
  58. package/public/assets/{auth-CvxEWAMc.js.map → auth-6N37o421.js.map} +1 -1
  59. package/public/assets/client-BT1QYH0O.js +10 -0
  60. package/public/assets/{client-C5T7_OK9.js.map → client-BT1QYH0O.js.map} +1 -1
  61. package/public/assets/index-2cgXLhrt.js +2 -0
  62. package/public/assets/{index-CRRRLlCc.js.map → index-2cgXLhrt.js.map} +1 -1
  63. package/public/assets/{index-i4mjW0og.js → index-CrN8I5Az.js} +2 -2
  64. package/public/assets/index-CrN8I5Az.js.map +1 -0
  65. package/public/assets/index-CtCtK5BX.js +2 -0
  66. package/public/assets/{index-DqHVrEeL.js.map → index-CtCtK5BX.js.map} +1 -1
  67. package/public/assets/index-Cz1Unv84.js +10 -0
  68. package/public/assets/{index-Bq9C9SqB.js.map → index-Cz1Unv84.js.map} +1 -1
  69. package/public/assets/index-D0OPOe3j.js +2 -0
  70. package/public/assets/{index-c0qeY2gs.js.map → index-D0OPOe3j.js.map} +1 -1
  71. package/public/assets/{index-DYcAgWjJ.js → index-DY750sgZ.js} +2 -2
  72. package/public/assets/{index-DYcAgWjJ.js.map → index-DY750sgZ.js.map} +1 -1
  73. package/public/assets/jsx-runtime-BX5r4UiA.js +2 -0
  74. package/public/assets/jsx-runtime-BX5r4UiA.js.map +1 -0
  75. package/public/assets/jsx-runtime-DldvXD6N.js +2 -0
  76. package/public/assets/{jsx-runtime-Bw5QeaCk.js.map → jsx-runtime-DldvXD6N.js.map} +1 -1
  77. package/public/assets/shared/@components-Bt_lv7Wa.js +2 -0
  78. package/public/assets/shared/@components-Bt_lv7Wa.js.map +1 -0
  79. package/public/assets/shared/{@hooks-DfTzYBIL.js → @hooks-Ch_hJYh0.js} +2 -2
  80. package/public/assets/shared/{@hooks-DfTzYBIL.js.map → @hooks-Ch_hJYh0.js.map} +1 -1
  81. package/public/assets/shared/{@nanostores_react-HTG3s0lp.js → @nanostores_react-DJPF1Eqx.js} +2 -2
  82. package/public/assets/shared/{@nanostores_react-HTG3s0lp.js.map → @nanostores_react-DJPF1Eqx.js.map} +1 -1
  83. package/public/assets/shared/@tabler_icons-react-B4bN8gHc.js +3 -0
  84. package/public/assets/shared/{@tabler_icons-react--FJWdUou.js.map → @tabler_icons-react-B4bN8gHc.js.map} +1 -1
  85. package/public/assets/shared/nanostores-BFqqIY_c.js.map +1 -1
  86. package/public/assets/shared/react-dom-8Rcmh_FG.js +2 -0
  87. package/public/assets/shared/{react-dom-BznoGTRX.js.map → react-dom-8Rcmh_FG.js.map} +1 -1
  88. package/public/assets/shared/react-iXLZ_Bod.js +2 -0
  89. package/public/assets/shared/{react-CR6vSpIu.js.map → react-iXLZ_Bod.js.map} +1 -1
  90. package/public/assets/shared/react_jsx-runtime-BwhiLcBy.js +2 -0
  91. package/public/assets/shared/{react_jsx-runtime-C15Zu6_p.js.map → react_jsx-runtime-BwhiLcBy.js.map} +1 -1
  92. package/public/assets/shared/{wouter-DbmGxXTo.js → wouter-CUC1caxu.js} +2 -2
  93. package/public/assets/shared/wouter-CUC1caxu.js.map +1 -0
  94. package/public/auth.html +14 -14
  95. package/templates/safe-ts/omegga.d.ts +30 -0
  96. package/public/assets/IconArrowRight-CA5_cccJ.js +0 -7
  97. package/public/assets/IconCheck-Dyq5qyY1.js +0 -17
  98. package/public/assets/IconLockOpen-D95XLORK.js +0 -7
  99. package/public/assets/IconWorld-DtARpBKX.js +0 -72
  100. package/public/assets/IconWorldPlus-CGBAsLNj.js +0 -182
  101. package/public/assets/IconX-SYtbnYKI.js +0 -12
  102. package/public/assets/app-BtOlgo__.js +0 -6
  103. package/public/assets/client-C5T7_OK9.js +0 -26
  104. package/public/assets/index-Bq9C9SqB.js +0 -10
  105. package/public/assets/index-CRRRLlCc.js +0 -10
  106. package/public/assets/index-DqHVrEeL.js +0 -10
  107. package/public/assets/index-c0qeY2gs.js +0 -10
  108. package/public/assets/index-i4mjW0og.js.map +0 -1
  109. package/public/assets/jsx-runtime-Bw5QeaCk.js +0 -10
  110. package/public/assets/jsx-runtime-DoEZbXM1.js +0 -2
  111. package/public/assets/jsx-runtime-DoEZbXM1.js.map +0 -1
  112. package/public/assets/shared/@components-DVehBp7v.js +0 -2
  113. package/public/assets/shared/@components-DVehBp7v.js.map +0 -1
  114. package/public/assets/shared/@tabler_icons-react--FJWdUou.js +0 -29458
  115. package/public/assets/shared/react-CR6vSpIu.js +0 -2
  116. package/public/assets/shared/react-dom-BznoGTRX.js +0 -2
  117. package/public/assets/shared/react_jsx-runtime-C15Zu6_p.js +0 -2
  118. package/public/assets/shared/wouter-DbmGxXTo.js.map +0 -1
  119. package/vite.backend.config.mts +0 -46
  120. package/vite.frontend.config.mts +0 -58
  121. package/vitest.backend.config.mts +0 -7
@@ -0,0 +1,17 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "WebFetch(domain:raw.githubusercontent.com)",
5
+ "WebFetch(domain:steam.readthedocs.io)",
6
+ "WebSearch",
7
+ "WebFetch(domain:docs.linuxgsm.com)",
8
+ "WebFetch(domain:github.com)",
9
+ "mcp__brickadia-luau__execute_lua",
10
+ "mcp__brickadia-luau__search_types",
11
+ "mcp__brickadia-luau__get_module_types",
12
+ "Bash(npx tsc:*)",
13
+ "mcp__brickadia-luau__reload_plugin",
14
+ "Bash(npx prettier:*)"
15
+ ]
16
+ }
17
+ }
package/README.md CHANGED
@@ -731,6 +731,8 @@ Cleanup is important as code can still be running after the plugin is unloaded r
731
731
 
732
732
  Register custom `/commands` by returning `{registeredCommands: ['foo', 'bar']}` (registers command `/foo` and `/bar`) in the `async init()` method.
733
733
 
734
+ By defining an `async pluginEvent(event, from, ...args)` method in your plugin class, you can respond to events from other plugins, where `from` is the name of the other plugin, `event` is the name of the custom event, and `args` is an array of any passed arguments.
735
+
734
736
  ### Globals
735
737
 
736
738
  - `OMEGGA_UTIL` - access to the `src/util/index.js` module
@@ -770,6 +772,13 @@ class PluginName {
770
772
  .removeAllListeners('chatcmd:ping')
771
773
  .removeAllListeners('chatcmd:pos');
772
774
  }
775
+
776
+ // optional: respond to events from other plugins
777
+ async pluginEvent(event, from, ...args) {
778
+ if (event === 'greeting') {
779
+ return `Hello from ${from}!`;
780
+ }
781
+ }
773
782
  }
774
783
 
775
784
  module.exports = PluginName;
@@ -821,16 +830,32 @@ Register custom `/commands` by returning `{registeredCommands: ['foo', 'bar']}`
821
830
  | `loadSaveDataOnPlayer` | {data: object, player: string, offX, offY, offY} | Builds brs file from data, loads the file onto a player's clipboard | |
822
831
  | `changeMap` | map (string) | Change map to specified map name, returns success | Boolean |
823
832
  | `player.get` | target (string) | Gets the player by their name or UUID. | `{name, id, controller, state, host: bool}` |
824
- | `player.getRoles` | target (string) | Target's roles | |
825
- | `player.getPermissions` | target (string) | Target's permissions | List of Strings |
826
- | `player.getNameColor` | target (string) | Target's name color | _RGB Hex Object_ (int, int ,int) |
827
- | `player.getPosition` | target (string) | Target's position | _Position Object_ |
828
- | `player.getGhostBrick` | target (string) | Target's ghost brick | {targetGrid, location(_Location_), orientation} |
829
- | `player.getPaint` | target (string) | Target's current paint selection | {materialIndex, materialAlpha, material, color)} |
830
- | `player.getTemplateBounds` | target (string) | Target's template/selection bounds | {minBound, maxBound, Center} |
831
- | `player.getTemplateBoundsData` | target (string) | Target's template/selection as brs-js save data | _Brick Object_ |
832
- | `player.loadSaveData` | {target, data, offX, offY, offZ} | Loads brs-js save data to the targets clipboard | |
833
- | `player.loadDataAtGhostBrick` | {target, data, rotate=true, offX, offY, offZ, quiet} | Loads brs-js save data at the target's selection bounds | |
833
+ | `player.getRoles` | target (string) | Target's roles | List of Strings |
834
+ | `player.getPermissions` | target (string) | Target's permissions | Record<string, boolean> |
835
+ | `player.getNameColor` | target (string) | Target's name color | _RGB Hex String_ |
836
+ | `player.getPosition` | target (string) | Target's position | [number, number, number] or null |
837
+ | `player.getPawn` | target (string) | Target's pawn name | string or null |
838
+ | `player.getGhostBrick` | target (string) | Target's ghost brick | {targetGrid, location, orientation} |
839
+ | `player.getPaint` | target (string) | Target's current paint selection | {materialIndex, materialAlpha, material, color} |
840
+ | `player.isCrouched` | target (string) | Check if target is crouched | boolean |
841
+ | `player.isDead` | target (string) | Check if target is dead | boolean |
842
+ | `player.getTemplateBounds` | target (string) | Target's template/selection bounds | {minBound, maxBound, center} |
843
+ | `player.getTemplateBoundsData` | target (string) | Target's template/selection as brs-js save data | _BRS Object_ |
844
+ | `player.clearBricks` | {target, quiet} | Clears target's bricks | |
845
+ | `player.loadBricks` | {target, saveName} | Loads save file to target's clipboard | |
846
+ | `player.loadSaveData` | {target, data, offX, offY, offZ} | Loads brs-js save data to target's clipboard | |
847
+ | `player.loadDataAtGhostBrick` | {target, data, rotate=true, offX, offY, offZ, quiet} | Loads brs-js save data at target's selection bounds | |
848
+ | `player.kill` | target (string) | Kills the target player | |
849
+ | `player.damage` | {target, amount} | Damages target by amount | |
850
+ | `player.heal` | {target, amount} | Heals target by amount | |
851
+ | `player.giveItem` | {target, item} | Gives target an item | |
852
+ | `player.takeItem` | {target, item} | Removes item from target | |
853
+ | `player.setTeam` | {target, teamIndex} | Sets target's team | |
854
+ | `player.setMinigame` | {target, index} | Adds target to minigame at index | |
855
+ | `player.setScore` | {target, minigameIndex, score} | Sets target's score in minigame | |
856
+ | `player.getScore` | target (string) | Gets target's score in minigame | number |
857
+ | `player.setLeaderboard` | {target, key, value} | Sets leaderboard value for target | |
858
+ | `player.getLeaderboard` | target (string) | Gets leaderboard value for target | number or null |
834
859
  | `plugin.get` | target (string) | Gets info on the target plugin | Object |
835
860
  | `plugin.emit` | [target (string), event (string), ...args (any)] | Emit a custom event to the target plugin | |
836
861
 
@@ -1014,6 +1039,8 @@ rpc.addMethod('stop', async () => 'ok');
1014
1039
 
1015
1040
  ## Environment Variables
1016
1041
 
1042
+ These can be set in your shell or in a `.env` file the same directory as a `omegga-config.yml` file.
1043
+
1017
1044
  `omegga` accepts the following environment variables:
1018
1045
 
1019
1046
  - `BRICKADIA_TOKEN` - Specify hosting token instead of using config
@@ -1024,6 +1051,8 @@ rpc.addMethod('stop', async () => 'ok');
1024
1051
  - `BRICKADIA_DIR` - Override the need to use steamcmd and point to a Brickadia install directory (eg. `/home/<USER>/.config/omegga/steam_installs/main/Brickadia`)
1025
1052
  - `STEAM_INSTALLS_DIR` - Set where omegga installs brickadia via steamcmd (default `~/.config/omegga/steam_installs`)
1026
1053
  - `STEAM_APP_ID` - Set the Steam App ID for Brickadia (default `3017590`)
1054
+ - `STEAM_USERNAME` - Set the Steam username for downloading Brickadia via steamcmd
1055
+ - `STEAM_PASSWORD` - Set the Steam password for downloading Brickadia via steamcmd
1027
1056
  - `VERBOSE` - Set to `true` to enable verbose logging (default `false`)
1028
1057
  - `PACKAGE_NOTIFIER` - When set to `false`, disables the npm update notifier
1029
1058
  - `STEAM_NOTIFIER` - When set to `false`, disables the SteamCMD update notifier
package/bin/omegga CHANGED
@@ -1,3 +1,3 @@
1
- #!/usr/bin/env -S node --enable-source-maps
1
+ #!/usr/bin/env -S node --enable-source-maps --disable-warning=DEP0040
2
2
 
3
3
  require('../dist/main.js');
@@ -5,9 +5,9 @@ const softconfig = require("../softconfig.js");
5
5
  const auth = require("../cli/auth.js");
6
6
  const wsl = require("../util/wsl.js");
7
7
  require("colors");
8
- const fs = require("node:fs");
9
8
  const node_child_process = require("node:child_process");
10
9
  const EventEmitter = require("node:events");
10
+ const fs = require("node:fs");
11
11
  const path = require("node:path");
12
12
  const node_process = require("node:process");
13
13
  const readline = require("readline");
@@ -129,17 +129,13 @@ class BrickadiaServer extends EventEmitter {
129
129
  }
130
130
  const isSteam = !this.config.server.branch;
131
131
  const steamBeta = this.config.server.steambeta ?? "main";
132
- const overrideBinary = softconfig.OVERRIDE_GAME_DIR && path.join(
133
- softconfig.OVERRIDE_GAME_DIR,
134
- // from BRICKADIA_DIR env
135
- softconfig.GAME_BIN_PATH
136
- );
132
+ const overrideBinary = softconfig.getOverrideGameBinary();
137
133
  const steamBinary = path.join(
138
- softconfig.GAME_INSTALL_DIR,
134
+ softconfig.getSteamInstallDir(),
139
135
  // steam install directory
140
136
  steamBeta,
141
137
  // steam beta branch (or main)
142
- softconfig.GAME_DIRNAME,
138
+ softconfig.getSteamGameDir(),
143
139
  // Brickadia
144
140
  softconfig.GAME_BIN_PATH
145
141
  // path to binary
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sources":["../../src/brickadia/server.ts"],"sourcesContent":["/*\n Brickadia Server Wrapper\n Manages IO with the game server\n*/\n\nimport Logger from '@/logger';\nimport {\n ACTIVE_WORLD_FILE,\n CONFIG_SAVED_DIR,\n GAME_BIN_PATH,\n GAME_DIRNAME,\n GAME_INSTALL_DIR,\n OVERRIDE_GAME_DIR,\n} from '@/softconfig';\nimport { getGlobalToken } from '@cli/auth';\nimport { IConfig } from '@config/types';\nimport { checkWsl } from '@util/wsl';\nimport 'colors';\nimport { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { ChildProcessWithoutNullStreams, spawn } from 'node:child_process';\nimport EventEmitter from 'node:events';\nimport path from 'node:path';\nimport { env } from 'node:process';\nimport readline from 'readline';\nimport stripAnsi from 'strip-ansi';\n\n// list of errors that can be solved by yelling at the user\nconst knownErrors: {\n name: string;\n solution?: string;\n match: RegExp;\n message?: string;\n}[] = [\n {\n name: 'MISSING_LIBGL',\n solution: 'apt-get install libgl1-mesa-glx libglib2.0-0',\n match:\n /error while loading shared libraries: libGL\\.so\\.1: cannot open shared object file/,\n },\n {\n name: 'MISSING_GLIB',\n solution: 'apt-get install libgl1-mesa-glx libglib2.0-0',\n match:\n /error while loading shared libraries: libgthread-2\\.0\\.so\\.0: cannot open shared object file/,\n },\n];\n\n/** Start a brickadia server */\nexport default class BrickadiaServer extends EventEmitter {\n #child: ChildProcessWithoutNullStreams = null;\n #errInterface: readline.Interface = null;\n #outInterface: readline.Interface = null;\n\n config: IConfig;\n path: string;\n\n constructor(dataPath: string, config: IConfig) {\n super();\n\n this.config = config;\n // use the data path if it's absolute, otherwise build an absolute path\n this.path =\n path.isAbsolute(dataPath) || dataPath.startsWith('/')\n ? dataPath\n : path.join(process.cwd(), dataPath);\n\n this.lineListener = this.lineListener.bind(this);\n this.errorListener = this.errorListener.bind(this);\n this.exitListener = this.exitListener.bind(this);\n }\n\n getActiveWorldFile(): string {\n return path.join(this.path, ACTIVE_WORLD_FILE);\n }\n\n /** A world specified by the active world file */\n getActiveWorld(): string | null {\n const activeWorldFile = this.getActiveWorldFile();\n if (existsSync(activeWorldFile)) {\n try {\n return readFileSync(activeWorldFile, 'utf8').trim();\n } catch (err) {\n Logger.errorp(\n 'Failed to read active world file',\n activeWorldFile.yellow,\n err,\n );\n return null;\n }\n }\n return null;\n }\n\n /** Set the world to use next startup */\n setActiveWorld(world: string | null): boolean {\n const activeWorldFile = this.getActiveWorldFile();\n if (!world || world === null) {\n if (existsSync(activeWorldFile)) {\n Logger.verbose('Removing active world file', activeWorldFile.yellow);\n unlinkSync(activeWorldFile);\n }\n return true;\n }\n\n if (!this.worldExists(world)) {\n Logger.verbose(\n 'Cannot set active world to',\n world.yellow,\n 'as it does not exist',\n );\n return false;\n }\n\n Logger.verbose('Setting active world to', world.yellow);\n try {\n writeFileSync(activeWorldFile, world, 'utf8');\n return true;\n } catch (err) {\n Logger.errorp(\n 'Failed to write active world file',\n activeWorldFile.yellow,\n err,\n );\n return false;\n }\n }\n\n /** A world specified by the config */\n getConfigWorld(): string | null {\n return this.config?.server?.world ?? null;\n }\n\n /** A world specified by the BRICKADIA_WORLD env variable */\n getEnvWorld(): string | null {\n return env.BRICKADIA_WORLD || null;\n }\n\n /** Check if a world exists */\n worldExists(world: string): boolean {\n const savedDir = this.config?.server?.savedDir ?? CONFIG_SAVED_DIR;\n const worldPath = path.join(this.path, savedDir, 'Worlds', world + '.brdb');\n return existsSync(worldPath);\n }\n\n /** Get the world that will be used next startup */\n getNextWorld() {\n const candidates = [\n { source: 'file', file: this.getActiveWorld() },\n { source: 'config', file: this.getConfigWorld() },\n { source: 'env', file: this.getEnvWorld() },\n ];\n\n return (\n candidates.find(({ file }) => file && this.worldExists(file)) ?? null\n );\n }\n\n // start the server child process\n start() {\n const {\n email,\n password,\n token: confToken,\n }: { email?: string; password?: string; token?: string } = this.config\n .credentials || {};\n\n const token = confToken || process.env.BRICKADIA_TOKEN || getGlobalToken();\n\n if (token) {\n Logger.verbose('Starting server with hosting token');\n } else {\n Logger.verbose(\n 'Starting server',\n (!email && !password ? 'without' : 'with').yellow,\n 'credentials',\n );\n }\n\n const isSteam = !this.config.server.branch;\n const steamBeta = this.config.server.steambeta ?? 'main';\n const overrideBinary =\n OVERRIDE_GAME_DIR &&\n path.join(\n OVERRIDE_GAME_DIR, // from BRICKADIA_DIR env\n GAME_BIN_PATH,\n );\n const steamBinary = path.join(\n GAME_INSTALL_DIR, // steam install directory\n steamBeta, // steam beta branch (or main)\n GAME_DIRNAME, // Brickadia\n GAME_BIN_PATH, // path to binary\n );\n\n let gameBinary = steamBinary;\n\n if (overrideBinary) {\n if (!existsSync(overrideBinary)) {\n Logger.error(\n 'Override binary',\n overrideBinary.yellow,\n 'does not exist!',\n );\n throw new Error(`Override binary ${overrideBinary} does not exist!`);\n }\n\n Logger.verbose(\n 'Using override binary',\n overrideBinary.yellow,\n 'instead of',\n steamBinary.yellow,\n );\n gameBinary = overrideBinary;\n } else if (isSteam) {\n Logger.verbose('Using steam binary', steamBeta.yellow);\n } else {\n Logger.verbose(\n 'Running',\n (this.config.server.__LOCAL\n ? path.join(__dirname, '../../tools/brickadia.sh')\n : 'brickadia launcher'\n ).yellow,\n );\n if (typeof this.config.server.branch === 'string')\n Logger.verbose('Using branch', this.config.server.branch.yellow);\n }\n\n // handle local launcher support\n const launchArgs = isSteam\n ? [gameBinary]\n : [\n this.config.server.__LOCAL\n ? path.join(__dirname, '../../tools/brickadia.sh')\n : 'brickadia',\n this.config.server.branch && `--branch=${this.config.server.branch}`,\n '--server',\n '--',\n ];\n\n const world = this.getNextWorld();\n if (world) {\n Logger.verbose(\n 'Using world',\n world.file.yellow,\n 'from',\n world.source.yellow,\n );\n } else if (this.config.server.map) {\n Logger.verbose('Using map', this.config.server.map.yellow, 'from config');\n }\n\n const params = [\n '--output=L',\n '--',\n ...launchArgs,\n !world &&\n this.config.server.map &&\n `-Environment=\"${this.config.server.map}\"`,\n world && `-World=\"${world.file}\"`,\n '-NotInstalled',\n '-log',\n checkWsl() === 1 ? '-OneThread' : null,\n this.path ? `-UserDir=\"${this.path}\"` : null,\n token ? `-Token=\"${token}\"` : null, // remove token argument if not provided\n !token && email ? `-User=\"${email}\"` : null, // remove email argument if not provided or token is provided\n !token && password ? `-Password=\"${password}\"` : null, // remove password argument if not provided or token is provided\n `-port=\"${this.config.server.port}\"`,\n this.config.server.launchArgs,\n ].filter(Boolean); // remove unused arguments\n Logger.verbose(\n 'Params for spawn',\n params\n .join(' ')\n .replace(/-User=\".*?\"/, '-User=\"<hidden>\"')\n .replace(/-Password=\".*?\"/, '-Password=\"<hidden>\"')\n .replace(/-Token=\".*?\"/, '-Token=\"<hidden>\"'),\n );\n\n // Either unbuffer or stdbuf must be used because brickadia's output is buffered\n // this means that multiple lines can be bundled together if the output buffer is not full\n // unfortunately without stdbuf or unbuffer, the output would not happen immediately\n this.#child = spawn('stdbuf', params);\n\n Logger.verbose(\n 'Spawn process',\n this.#child ? this.#child.pid : 'failed'.red,\n );\n\n this.#child.stdin.setDefaultEncoding('utf8');\n this.#outInterface = readline.createInterface({\n input: this.#child.stdout,\n terminal: false,\n });\n this.#errInterface = readline.createInterface({\n input: this.#child.stderr,\n terminal: false,\n });\n this.attachListeners();\n Logger.verbose('Attached listeners');\n }\n\n // write a string to the child process\n write(line: string) {\n if (line.length >= 512) {\n // show a warning\n Logger.warn(\n 'WARNING'.yellow,\n 'The following line was called and is',\n 'longer than allowed limit'.red,\n );\n Logger.warn(line.replace(/\\n$/, ''));\n // throw a fake error to get the line number\n try {\n throw new Error('Console Line Too Long');\n } catch (err) {\n Logger.warn(err);\n }\n return;\n }\n if (this.#child) {\n Logger.verbose('WRITE'.green, line.replace(/\\n$/, ''));\n this.#child.stdin.write(line);\n }\n }\n\n // write a line to the child process\n writeln(line: string) {\n this.write(line + '\\n');\n }\n\n // forcibly kills the server\n stop() {\n if (!this.#child) {\n Logger.verbose('Cannot stop server as no subprocess exists');\n return;\n }\n\n Logger.verbose('Forcibly stopping server');\n // kill the process\n this.#child.kill('SIGINT');\n\n // ...kill it again just to make sure it's dead\n spawn('kill', ['-9', this.#child.pid + '']);\n }\n\n // detaches listeners\n cleanup() {\n if (!this.#child) return;\n\n Logger.verbose('Cleaning up brickadia server');\n\n // detach listener\n this.detachListeners();\n\n this.#child = null;\n this.#outInterface = null;\n this.#errInterface = null;\n }\n\n // attaches proxy event listeners\n attachListeners() {\n this.#outInterface.on('line', this.lineListener);\n this.#errInterface.on('line', this.errorListener);\n this.#child.on('exit', this.exitListener);\n this.#child.on('close', () => {});\n }\n\n // removes previously attached proxy event listeners\n detachListeners() {\n this.#outInterface.off('line', this.lineListener);\n this.#errInterface.off('line', this.errorListener);\n this.#child.off('exit', this.exitListener);\n this.#child.removeAllListeners('close');\n }\n\n // -- listeners for basic events (line, err, exit)\n errorListener(line: string) {\n Logger.verbose('ERROR'.red, line);\n this.emit('err', line);\n for (const { match, solution, name, message } of knownErrors) {\n if (line.match(match)) {\n Logger.error(\n `Encountered ${name.red}. ${\n solution ? 'Known fix:\\n ' + solution : message || 'Unknown error.'\n }`,\n );\n }\n }\n }\n\n exitListener(...args: any[]) {\n Logger.verbose('Exit listener fired');\n this.emit('closed', ...args);\n this.cleanup();\n }\n\n lineListener(line: string) {\n this.emit('line', stripAnsi(line));\n }\n}\n"],"names":["ACTIVE_WORLD_FILE","existsSync","readFileSync","Logger","unlinkSync","writeFileSync","env","CONFIG_SAVED_DIR","getGlobalToken","OVERRIDE_GAME_DIR","GAME_BIN_PATH","GAME_INSTALL_DIR","GAME_DIRNAME","checkWsl","spawn"],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sources":["../../src/brickadia/server.ts"],"sourcesContent":["/*\n Brickadia Server Wrapper\n Manages IO with the game server\n*/\n\nimport Logger from '@/logger';\nimport {\n ACTIVE_WORLD_FILE,\n CONFIG_SAVED_DIR,\n GAME_BIN_PATH,\n getOverrideGameBinary,\n getSteamGameDir,\n getSteamInstallDir,\n} from '@/softconfig';\nimport { getGlobalToken } from '@cli/auth';\nimport { IConfig } from '@config/types';\nimport { checkWsl } from '@util/wsl';\nimport 'colors';\nimport { ChildProcessWithoutNullStreams, spawn } from 'node:child_process';\nimport EventEmitter from 'node:events';\nimport { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { env } from 'node:process';\nimport readline from 'readline';\nimport stripAnsi from 'strip-ansi';\n\n// list of errors that can be solved by yelling at the user\nconst knownErrors: {\n name: string;\n solution?: string;\n match: RegExp;\n message?: string;\n}[] = [\n {\n name: 'MISSING_LIBGL',\n solution: 'apt-get install libgl1-mesa-glx libglib2.0-0',\n match:\n /error while loading shared libraries: libGL\\.so\\.1: cannot open shared object file/,\n },\n {\n name: 'MISSING_GLIB',\n solution: 'apt-get install libgl1-mesa-glx libglib2.0-0',\n match:\n /error while loading shared libraries: libgthread-2\\.0\\.so\\.0: cannot open shared object file/,\n },\n];\n\n/** Start a brickadia server */\nexport default class BrickadiaServer extends EventEmitter {\n #child: ChildProcessWithoutNullStreams = null;\n #errInterface: readline.Interface = null;\n #outInterface: readline.Interface = null;\n\n config: IConfig;\n path: string;\n\n constructor(dataPath: string, config: IConfig) {\n super();\n\n this.config = config;\n // use the data path if it's absolute, otherwise build an absolute path\n this.path =\n path.isAbsolute(dataPath) || dataPath.startsWith('/')\n ? dataPath\n : path.join(process.cwd(), dataPath);\n\n this.lineListener = this.lineListener.bind(this);\n this.errorListener = this.errorListener.bind(this);\n this.exitListener = this.exitListener.bind(this);\n }\n\n getActiveWorldFile(): string {\n return path.join(this.path, ACTIVE_WORLD_FILE);\n }\n\n /** A world specified by the active world file */\n getActiveWorld(): string | null {\n const activeWorldFile = this.getActiveWorldFile();\n if (existsSync(activeWorldFile)) {\n try {\n return readFileSync(activeWorldFile, 'utf8').trim();\n } catch (err) {\n Logger.errorp(\n 'Failed to read active world file',\n activeWorldFile.yellow,\n err,\n );\n return null;\n }\n }\n return null;\n }\n\n /** Set the world to use next startup */\n setActiveWorld(world: string | null): boolean {\n const activeWorldFile = this.getActiveWorldFile();\n if (!world || world === null) {\n if (existsSync(activeWorldFile)) {\n Logger.verbose('Removing active world file', activeWorldFile.yellow);\n unlinkSync(activeWorldFile);\n }\n return true;\n }\n\n if (!this.worldExists(world)) {\n Logger.verbose(\n 'Cannot set active world to',\n world.yellow,\n 'as it does not exist',\n );\n return false;\n }\n\n Logger.verbose('Setting active world to', world.yellow);\n try {\n writeFileSync(activeWorldFile, world, 'utf8');\n return true;\n } catch (err) {\n Logger.errorp(\n 'Failed to write active world file',\n activeWorldFile.yellow,\n err,\n );\n return false;\n }\n }\n\n /** A world specified by the config */\n getConfigWorld(): string | null {\n return this.config?.server?.world ?? null;\n }\n\n /** A world specified by the BRICKADIA_WORLD env variable */\n getEnvWorld(): string | null {\n return env.BRICKADIA_WORLD || null;\n }\n\n /** Check if a world exists */\n worldExists(world: string): boolean {\n const savedDir = this.config?.server?.savedDir ?? CONFIG_SAVED_DIR;\n const worldPath = path.join(this.path, savedDir, 'Worlds', world + '.brdb');\n return existsSync(worldPath);\n }\n\n /** Get the world that will be used next startup */\n getNextWorld() {\n const candidates = [\n { source: 'file', file: this.getActiveWorld() },\n { source: 'config', file: this.getConfigWorld() },\n { source: 'env', file: this.getEnvWorld() },\n ];\n\n return (\n candidates.find(({ file }) => file && this.worldExists(file)) ?? null\n );\n }\n\n // start the server child process\n start() {\n const {\n email,\n password,\n token: confToken,\n }: { email?: string; password?: string; token?: string } = this.config\n .credentials || {};\n\n const token = confToken || process.env.BRICKADIA_TOKEN || getGlobalToken();\n\n if (token) {\n Logger.verbose('Starting server with hosting token');\n } else {\n Logger.verbose(\n 'Starting server',\n (!email && !password ? 'without' : 'with').yellow,\n 'credentials',\n );\n }\n\n const isSteam = !this.config.server.branch;\n const steamBeta = this.config.server.steambeta ?? 'main';\n const overrideBinary = getOverrideGameBinary();\n const steamBinary = path.join(\n getSteamInstallDir(), // steam install directory\n steamBeta, // steam beta branch (or main)\n getSteamGameDir(), // Brickadia\n GAME_BIN_PATH, // path to binary\n );\n\n let gameBinary = steamBinary;\n\n if (overrideBinary) {\n if (!existsSync(overrideBinary)) {\n Logger.error(\n 'Override binary',\n overrideBinary.yellow,\n 'does not exist!',\n );\n throw new Error(`Override binary ${overrideBinary} does not exist!`);\n }\n\n Logger.verbose(\n 'Using override binary',\n overrideBinary.yellow,\n 'instead of',\n steamBinary.yellow,\n );\n gameBinary = overrideBinary;\n } else if (isSteam) {\n Logger.verbose('Using steam binary', steamBeta.yellow);\n } else {\n Logger.verbose(\n 'Running',\n (this.config.server.__LOCAL\n ? path.join(__dirname, '../../tools/brickadia.sh')\n : 'brickadia launcher'\n ).yellow,\n );\n if (typeof this.config.server.branch === 'string')\n Logger.verbose('Using branch', this.config.server.branch.yellow);\n }\n\n // handle local launcher support\n const launchArgs = isSteam\n ? [gameBinary]\n : [\n this.config.server.__LOCAL\n ? path.join(__dirname, '../../tools/brickadia.sh')\n : 'brickadia',\n this.config.server.branch && `--branch=${this.config.server.branch}`,\n '--server',\n '--',\n ];\n\n const world = this.getNextWorld();\n if (world) {\n Logger.verbose(\n 'Using world',\n world.file.yellow,\n 'from',\n world.source.yellow,\n );\n } else if (this.config.server.map) {\n Logger.verbose('Using map', this.config.server.map.yellow, 'from config');\n }\n\n const params = [\n '--output=L',\n '--',\n ...launchArgs,\n !world &&\n this.config.server.map &&\n `-Environment=\"${this.config.server.map}\"`,\n world && `-World=\"${world.file}\"`,\n '-NotInstalled',\n '-log',\n checkWsl() === 1 ? '-OneThread' : null,\n this.path ? `-UserDir=\"${this.path}\"` : null,\n token ? `-Token=\"${token}\"` : null, // remove token argument if not provided\n !token && email ? `-User=\"${email}\"` : null, // remove email argument if not provided or token is provided\n !token && password ? `-Password=\"${password}\"` : null, // remove password argument if not provided or token is provided\n `-port=\"${this.config.server.port}\"`,\n this.config.server.launchArgs,\n ].filter(Boolean); // remove unused arguments\n Logger.verbose(\n 'Params for spawn',\n params\n .join(' ')\n .replace(/-User=\".*?\"/, '-User=\"<hidden>\"')\n .replace(/-Password=\".*?\"/, '-Password=\"<hidden>\"')\n .replace(/-Token=\".*?\"/, '-Token=\"<hidden>\"'),\n );\n\n // Either unbuffer or stdbuf must be used because brickadia's output is buffered\n // this means that multiple lines can be bundled together if the output buffer is not full\n // unfortunately without stdbuf or unbuffer, the output would not happen immediately\n this.#child = spawn('stdbuf', params);\n\n Logger.verbose(\n 'Spawn process',\n this.#child ? this.#child.pid : 'failed'.red,\n );\n\n this.#child.stdin.setDefaultEncoding('utf8');\n this.#outInterface = readline.createInterface({\n input: this.#child.stdout,\n terminal: false,\n });\n this.#errInterface = readline.createInterface({\n input: this.#child.stderr,\n terminal: false,\n });\n this.attachListeners();\n Logger.verbose('Attached listeners');\n }\n\n // write a string to the child process\n write(line: string) {\n if (line.length >= 512) {\n // show a warning\n Logger.warn(\n 'WARNING'.yellow,\n 'The following line was called and is',\n 'longer than allowed limit'.red,\n );\n Logger.warn(line.replace(/\\n$/, ''));\n // throw a fake error to get the line number\n try {\n throw new Error('Console Line Too Long');\n } catch (err) {\n Logger.warn(err);\n }\n return;\n }\n if (this.#child) {\n Logger.verbose('WRITE'.green, line.replace(/\\n$/, ''));\n this.#child.stdin.write(line);\n }\n }\n\n // write a line to the child process\n writeln(line: string) {\n this.write(line + '\\n');\n }\n\n // forcibly kills the server\n stop() {\n if (!this.#child) {\n Logger.verbose('Cannot stop server as no subprocess exists');\n return;\n }\n\n Logger.verbose('Forcibly stopping server');\n // kill the process\n this.#child.kill('SIGINT');\n\n // ...kill it again just to make sure it's dead\n spawn('kill', ['-9', this.#child.pid + '']);\n }\n\n // detaches listeners\n cleanup() {\n if (!this.#child) return;\n\n Logger.verbose('Cleaning up brickadia server');\n\n // detach listener\n this.detachListeners();\n\n this.#child = null;\n this.#outInterface = null;\n this.#errInterface = null;\n }\n\n // attaches proxy event listeners\n attachListeners() {\n this.#outInterface.on('line', this.lineListener);\n this.#errInterface.on('line', this.errorListener);\n this.#child.on('exit', this.exitListener);\n this.#child.on('close', () => {});\n }\n\n // removes previously attached proxy event listeners\n detachListeners() {\n this.#outInterface.off('line', this.lineListener);\n this.#errInterface.off('line', this.errorListener);\n this.#child.off('exit', this.exitListener);\n this.#child.removeAllListeners('close');\n }\n\n // -- listeners for basic events (line, err, exit)\n errorListener(line: string) {\n Logger.verbose('ERROR'.red, line);\n this.emit('err', line);\n for (const { match, solution, name, message } of knownErrors) {\n if (line.match(match)) {\n Logger.error(\n `Encountered ${name.red}. ${\n solution ? 'Known fix:\\n ' + solution : message || 'Unknown error.'\n }`,\n );\n }\n }\n }\n\n exitListener(...args: any[]) {\n Logger.verbose('Exit listener fired');\n this.emit('closed', ...args);\n this.cleanup();\n }\n\n lineListener(line: string) {\n this.emit('line', stripAnsi(line));\n }\n}\n"],"names":["ACTIVE_WORLD_FILE","existsSync","readFileSync","Logger","unlinkSync","writeFileSync","env","CONFIG_SAVED_DIR","getGlobalToken","getOverrideGameBinary","getSteamInstallDir","getSteamGameDir","GAME_BIN_PATH","checkWsl","spawn"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -4,16 +4,16 @@ const plugin = require("./plugin.js");
4
4
  const server$1 = require("./brickadia/server.js");
5
5
  const config = require("./brickadia/config.js");
6
6
  const server = require("./omegga/server.js");
7
- const index = require("./omegga/index.js");
8
- const index$1 = require("./util/index.js");
9
- const index$2 = require("./config/index.js");
7
+ const index$1 = require("./omegga/index.js");
8
+ const index$2 = require("./util/index.js");
9
+ const index = require("./config/index.js");
10
10
  const brickadia = { Server: server$1, config };
11
11
  exports.OmeggaPlugin = plugin.OmeggaPlugin;
12
12
  exports._OMEGGA_UTILS_IMPORT = plugin._OMEGGA_UTILS_IMPORT;
13
13
  exports.Omegga = server.default;
14
14
  exports.default = server.default;
15
- exports.omegga = index;
16
- exports.util = index$1;
17
- exports.config = index$2;
15
+ exports.omegga = index$1;
16
+ exports.util = index$2;
17
+ exports.config = index;
18
18
  exports.brickadia = brickadia;
19
19
  //# sourceMappingURL=index.js.map
package/dist/main.js CHANGED
@@ -6,6 +6,7 @@ const server = require("./omegga/server.js");
6
6
  const file = require("./util/file.js");
7
7
  require("colors");
8
8
  const commander = require("commander");
9
+ const dotenv = require("dotenv");
9
10
  const hasbin = require("hasbin");
10
11
  const fs = require("node:fs");
11
12
  const path = require("node:path");
@@ -15,6 +16,7 @@ const index$1 = require("./cli/index.js");
15
16
  const logger = require("./logger.js");
16
17
  const steam = require("./updater/steam.js");
17
18
  const version = require("./version.js");
19
+ dotenv.config({ quiet: true });
18
20
  const notifier = process.env.PACKAGE_NOTIFIER !== "false" ? updateNotifier({
19
21
  pkg: version.PKG,
20
22
  updateCheckInterval: 1e3 * 60 * 60 * 24
@@ -66,11 +68,7 @@ const program = commander.description(version.PKG.description).version(version.V
66
68
  logger.default.verbose(error);
67
69
  }
68
70
  }
69
- const overrideBinary = softconfig.OVERRIDE_GAME_DIR && path.join(
70
- softconfig.OVERRIDE_GAME_DIR,
71
- // from BRICKADIA_DIR env
72
- softconfig.GAME_BIN_PATH
73
- );
71
+ const overrideBinary = softconfig.getOverrideGameBinary();
74
72
  const isSteam = !conf?.server?.branch;
75
73
  if (overrideBinary) {
76
74
  if (!fs.existsSync(overrideBinary)) {
@@ -96,6 +94,9 @@ const program = commander.description(version.PKG.description).version(version.V
96
94
  "Brickadia will be launched with",
97
95
  "non-steam launcher".yellow
98
96
  );
97
+ logger.default.warnp(
98
+ "New versions of Brickadia are not published on the old launcher.".yellow
99
+ );
99
100
  if (fs.existsSync(softconfig.default.LOCAL_LAUNCHER)) {
100
101
  logger.default.verbose("Using omegga's brickadia-launcher");
101
102
  conf.server.__LOCAL = true;
@@ -398,11 +399,11 @@ async function setupSteam(config2, forceUpdate = false) {
398
399
  const steambeta = config2?.server?.steambeta;
399
400
  const steambetaPassword = config2?.server?.steambetaPassword;
400
401
  const binaryPath = path.join(
401
- softconfig.GAME_INSTALL_DIR,
402
+ softconfig.getSteamInstallDir(),
402
403
  // steam install directory
403
404
  steambeta ?? "main",
404
405
  // steam beta branch (or main)
405
- softconfig.GAME_DIRNAME,
406
+ softconfig.getSteamGameDir(),
406
407
  // Brickadia
407
408
  softconfig.GAME_BIN_PATH
408
409
  // path to binary
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sources":["../src/main.ts"],"sourcesContent":["import soft, { GAME_DIRNAME, OVERRIDE_GAME_DIR } from '@/softconfig';\nimport { installLauncher } from '@cli/installer';\nimport * as config from '@config';\nimport Omegga from '@omegga/server';\nimport * as file from '@util/file';\nimport 'colors';\nimport commander from 'commander';\nimport hasbin from 'hasbin';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport prompts from 'prompts';\nimport updateNotifier from 'update-notifier-cjs';\nimport { auth, config as omeggaConfig, pluginUtil, Terminal } from './cli';\nimport { IConfig } from './config/types';\nimport Logger from './logger';\nimport { GAME_BIN_PATH, GAME_INSTALL_DIR, STEAMCMD_PATH } from './softconfig';\nimport {\n hasSteamUpdate,\n steamcmdDownloadGame,\n steamcmdDownloadSelf,\n} from './updater';\nimport { PKG, VERSION } from './version';\n\nconst notifier =\n process.env.PACKAGE_NOTIFIER !== 'false'\n ? updateNotifier({\n pkg: PKG,\n updateCheckInterval: 1000 * 60 * 60 * 24,\n })\n : null;\nnotifier?.notify();\n\n// TODO: let omegga bundle config (roles, bans, server config) to zip\n// TODO: let omegga unbundle config from zip to current omegga dir\n\n// write a default config file\nconst createDefaultConfig = () => {\n Logger.logp('Created default config file');\n config.write(soft.CONFIG_FILENAMES[0] + '.yml', config.defaultConfig);\n file.mkdir(`data/${soft.CONFIG_SAVED_DIR}/Builds`);\n file.mkdir('plugins');\n return config.defaultConfig;\n};\n\nconst program = commander\n .description(PKG.description)\n .version(VERSION)\n .option(\n '-d, --debug',\n 'Print all console logs rather than just chat messages',\n )\n .option(\n '-u, --update',\n 'Check for brickadia updates (on steam) and install them if available',\n )\n .option('-v, --verbose', 'Print extra messages for debugging purposes')\n .action(async () => {\n const { debug, verbose, update } = program.opts();\n if (program.args.length > 0) {\n program.help();\n process.exit(1);\n }\n Logger.VERBOSE = Boolean(verbose);\n\n // default working directory is the one specified in config\n let workDir = config.store.get('defaultOmegga');\n Logger.verbose('Using working directory', workDir?.yellow);\n\n // if there's a config in the current directory, use that one instead\n if (config.find('.')) workDir = '.';\n\n // check if configured path exists\n if (!fs.existsSync(workDir)) {\n Logger.errorp('configured omegga default path does not exist');\n process.exit(1);\n }\n if (!fs.statSync(workDir).isDirectory) {\n Logger.errorp('configured omegga default path is not a directory');\n process.exit(1);\n }\n\n // find the config for the working directory\n const configFile = config.find(workDir);\n Logger.verbose('Target config file:', configFile?.yellow);\n let conf: IConfig;\n\n // create a default config file if it does not already exist, otherwise load in the existing one\n if (!configFile) {\n Logger.verbose('Creating a new config');\n conf = createDefaultConfig();\n } else {\n Logger.verbose('Reading config file');\n try {\n conf = config.read(configFile);\n } catch (error) {\n Logger.errorp('Error reading config file');\n Logger.verbose(error);\n }\n }\n\n const overrideBinary =\n OVERRIDE_GAME_DIR &&\n path.join(\n OVERRIDE_GAME_DIR, // from BRICKADIA_DIR env\n GAME_BIN_PATH,\n );\n\n const isSteam = !conf?.server?.branch;\n if (overrideBinary) {\n if (!fs.existsSync(overrideBinary)) {\n Logger.error(\n 'Binary',\n overrideBinary.yellow,\n 'in',\n 'BRICKADIA_DIR'.yellow,\n 'does not exist!',\n );\n process.exit(1);\n }\n\n Logger.verbose(\n 'Using override binary',\n overrideBinary.yellow,\n '- skipping download.',\n );\n } else if (isSteam) {\n conf.__STEAM = true;\n await setupSteam(conf, update);\n } else {\n Logger.warnp(\n 'Brickadia will be launched with',\n 'non-steam launcher'.yellow,\n );\n\n // Check if the local launcher is installed\n if (fs.existsSync(soft.LOCAL_LAUNCHER)) {\n Logger.verbose(\"Using omegga's brickadia-launcher\");\n conf.server.__LOCAL = true;\n } else {\n Logger.verbose(\"Installing launcher as it's missing\");\n await installLauncher();\n }\n }\n\n const globalToken = auth.getGlobalToken();\n\n const hasHostingToken = Boolean(\n conf?.credentials?.token || process.env.BRICKADIA_TOKEN || globalToken,\n );\n\n // Skip auth when the hosting token is present\n if (hasHostingToken) {\n Logger.verbose(\n 'Skipping auth token generation due to host token presence',\n );\n if (conf?.credentials?.token)\n Logger.verbose('Found token in config file');\n else if (process.env.BRICKADIA_TOKEN)\n Logger.verbose('Found token in', 'BRICKADIA_TOKEN'.yellow);\n else if (globalToken)\n Logger.verbose('Found token in omegga global config');\n else Logger.verbose('unreachable - no token found');\n\n // check if the auth files don't exist\n } else if (\n !auth.exists(\n path.join(\n workDir,\n soft.DATA_PATH,\n conf?.server?.savedDir ?? soft.CONFIG_SAVED_DIR,\n conf?.server?.authDir ?? soft.CONFIG_AUTH_DIR,\n ),\n )\n ) {\n const success = await auth.prompt({\n debug,\n email: conf?.credentials?.['email'] ?? process.env.BRICKADIA_USER,\n password: conf?.credentials?.['password'] ?? process.env.BRICKADIA_PASS,\n isSteam,\n branch: conf?.server?.branch,\n authDir: conf?.server?.authDir,\n savedDir: conf?.server?.savedDir,\n launchArgs: conf?.server?.launchArgs,\n });\n if (!success) {\n Logger.errorp('Start aborted - could not generate auth tokens');\n process.exit(1);\n }\n } else {\n Logger.verbose(\n 'Skipping auth token generation due to existing auth files',\n );\n }\n\n // build options\n const options = {\n // default enable web ui (set to false)\n noweb: typeof conf.omegga?.webui === 'boolean' && !conf.omegga?.webui,\n // default enable https (set to true, will not be https if it can't generate)\n https: typeof conf.omegga?.https !== 'boolean' || conf.omegga?.https,\n port: conf.omegga?.port || soft.DEFAULT_PORT,\n debug,\n };\n\n Logger.verbose('Launching with options', options);\n\n // setup the server\n const server = new Omegga(workDir, conf, options);\n Logger.verbose('Created omegga object');\n\n if (verbose) {\n server.on(\n '*',\n (ev: string) => ev !== 'line' && Logger.verbose('EVENT'.green, ev),\n );\n }\n\n // create a terminal\n Logger.setTerminal(new Terminal(server, options));\n\n if (notifier?.update) {\n Logger.logp(\n `Omegga update is available (${('v' + notifier.update.latest).yellow})! Run`,\n 'npm i -g omegga'.yellow,\n 'to update!',\n );\n }\n\n if (\n conf.__STEAM &&\n !update &&\n !conf.server?.steambetaPassword &&\n process.env.STEAM_NOTIFIER !== 'false'\n ) {\n hasSteamUpdate(conf.server?.steambeta).then(hasUpdate => {\n if (hasUpdate) {\n Logger.logp('A server update is available!'.brightBlue);\n Logger.log(\n ' Restart with',\n 'omegga --update'.yellow,\n 'to update every start.',\n );\n Logger.log(' Run', '/update'.yellow, 'to update', 'now'.green + '!');\n } else {\n Logger.verbose('No server updates available.');\n }\n });\n }\n\n Logger.logp(\n `Launching brickadia server on port ${\n ('' + (conf.server.port || 7777)).green\n }...`,\n );\n\n // start the server\n Logger.verbose('Starting Omegga');\n server.start();\n });\n\nprogram\n .command('init')\n .description('Sets up the current directory as a brickadia server')\n .action(async () => {\n const configFile = config.find('.');\n if (configFile) {\n Logger.errorp('Config file already exists:', configFile.yellow.underline);\n process.exit(1);\n }\n createDefaultConfig();\n });\n\nprogram\n .command('config [field] [value]')\n .description(\n \"Configure Omegga's default behavior.\\n\" +\n 'Type ' +\n 'omegga config list'.yellow.underline +\n ' for current settings and available fields',\n )\n .action((field, value) => {\n if (!field) field = 'list';\n omeggaConfig(field, value, program.opts());\n });\n\nprogram\n .command('auth')\n .option('-g, --global', 'Remove global auth files')\n .option('-l, --local', 'Remove local auth files')\n .option('-w, --workdir', 'Remove configured location auth files')\n .option('-u, --email <email>', 'User email (must provide password)')\n .option('-p, --pass <password>', 'User password (must provide email)')\n .option('-v, --verbose', 'Print extra messages for debugging purposes')\n .description(\n 'Generates server auth tokens from brickadia account email+password',\n )\n .action(\n async ({\n email,\n pass: password,\n local: localAuth,\n workDir,\n global: globalAuth,\n }) => {\n const { verbose, debug } = program.opts();\n Logger.VERBOSE = Boolean(verbose);\n\n let branch: string, authDir: string, savedDir: string, launchArgs: string;\n let isSteam: boolean;\n\n // if there's a config in the current directory, use that one instead\n if (config.find('.')) workDir = '.';\n\n // check if configured path exists\n if (fs.existsSync(workDir) && fs.statSync(workDir).isDirectory) {\n Logger.verbose('Using working directory', workDir.yellow);\n // find the config for the working directory\n const configFile = config.find(workDir);\n Logger.verbose('Target config file:', configFile?.yellow);\n try {\n // read the config and extract the branch\n const conf = config.read(configFile);\n Logger.verbose(\n 'Auth config:',\n conf?.server ?? 'no server config'.grey,\n );\n branch = conf?.server?.branch;\n authDir = conf?.server?.authDir;\n savedDir = conf?.server?.savedDir;\n launchArgs = conf?.server?.launchArgs;\n isSteam = !conf?.server?.branch;\n\n if (localAuth && conf?.credentials?.token) {\n Logger.logp(\n \"This server's auth is managed by the token in\",\n configFile.yellow,\n );\n return;\n }\n } catch (error) {\n Logger.errorp('Error reading config file');\n Logger.verbose(error);\n }\n } else {\n Logger.verbose('Using default working directory', workDir.yellow);\n }\n\n savedDir ??= soft.CONFIG_SAVED_DIR;\n\n const workdirPath = path.join(\n config.store.get('defaultOmegga'),\n `data/${savedDir}/Auth`,\n );\n\n if (globalAuth || localAuth) {\n if (globalAuth) {\n const globalAuthPath = path.join(\n soft.CONFIG_HOME,\n savedDir !== soft.CONFIG_SAVED_DIR ? savedDir : '',\n authDir ?? soft.CONFIG_AUTH_DIR,\n );\n Logger.logp('Clearing auth files from', globalAuthPath.yellow);\n auth.clean(globalAuthPath);\n }\n if (workDir) {\n Logger.logp('Clearing auth files from', workdirPath.yellow);\n await file.rmdir(workdirPath);\n }\n if (localAuth) {\n const localPath = path.resolve(\n `data/${savedDir}/`,\n authDir ?? soft.CONFIG_AUTH_DIR,\n );\n Logger.logp('Clearing auth files from', localPath.yellow);\n await file.rmdir(localPath);\n }\n return;\n }\n\n if (!isSteam) {\n Logger.warnp('Authenticating with', 'non-steam launcher'.yellow);\n }\n\n auth.prompt({\n email,\n password,\n debug,\n branch,\n authDir,\n savedDir,\n launchArgs,\n });\n },\n );\n\nprogram\n .command('info')\n .alias('n')\n .description(\n 'Shows server name, description, port, install info, and installed plugins',\n )\n .action(async () => {\n Logger.errorp('not implemented yet');\n // TODO: implement config parsing\n });\n\nprogram\n .command('install <pluginUrl...>')\n .alias('i')\n .option('-f, --force', 'Forcefully re-install existing plugin') // TODO: implement install --force\n .option('-v, --verbose', 'Print extra messages for debugging purposes')\n .description('Installs a plugin to the current brickadia server')\n .action(async plugins => {\n if (!hasbin.sync('git')) {\n Logger.errorp('git'.yellow, 'must be installed to install plugins.');\n process.exit(1);\n }\n\n if (!config.find('.')) {\n Logger.errorp(\n 'Not an omegga directory, run ',\n 'omegga init'.yellow,\n 'to setup one.',\n );\n process.exit(1);\n }\n const { verbose, force } = program.opts();\n Logger.VERBOSE = Boolean(verbose);\n pluginUtil.install(plugins, { verbose, force });\n });\n\nprogram\n .command('update [pluginNames...]')\n .alias('u')\n .option('-f, --force', 'Forcefully re-upgrade existing plugin') // TODO: implement update --force\n .option('-v, --verbose', 'Print extra messages for debugging purposes')\n .description('Updates all or selected installed plugins to latest versions')\n .action(async plugins => {\n if (!config.find('.')) {\n Logger.errorp(\n 'Not an omegga directory, run ',\n 'omegga init'.yellow,\n 'to setup one.',\n );\n process.exit(1);\n }\n const { verbose, force } = program.opts();\n Logger.VERBOSE = Boolean(verbose);\n pluginUtil.update(plugins, { verbose, force });\n });\n\nprogram\n .command('check [pluginNames...]')\n .option('-v, --verbose', 'Print extra messages for debugging purposes')\n .description('Checks plugins for compatibility issues')\n .action(async plugins => {\n if (!config.find('.')) {\n Logger.errorp(\n 'Not an omegga directory, run ',\n 'omegga init'.yellow,\n 'to setup one.',\n );\n process.exit(1);\n }\n const { verbose } = program.opts();\n Logger.VERBOSE = Boolean(verbose);\n pluginUtil.check(plugins, { verbose });\n });\n\nprogram\n .command('init-plugin')\n .option('-v, --verbose', 'Print extra messages for debugging purposes')\n .description('Initializes a new plugin with the given name and settings')\n .action(async () => {\n const { verbose } = program.opts();\n Logger.VERBOSE = Boolean(verbose);\n\n pluginUtil.init();\n });\n\nprogram\n .command('plugin-init')\n .description('Alias for ' + 'init-plugin'.yellow.underline)\n .option('-v, --verbose', 'Print extra messages for debugging purposes')\n .action(async () => {\n const { verbose } = program.opts();\n Logger.VERBOSE = Boolean(verbose);\n\n pluginUtil.init();\n });\n\nprogram\n .command('get-config <pluginName> [configName]')\n .option('-v, --verbose', 'Print extra messages for debugging purposes')\n .option('-j, --json', 'Print config as json')\n .description(\n 'Gets a config for a plugin. If ' +\n 'configName'.yellow.underline +\n ' is omitted, returns all config values.',\n )\n .action(async (pluginName, configName) => {\n if (!config.find('.')) {\n Logger.errorp(\n 'Not an omegga directory, run ',\n 'omegga init'.yellow,\n 'to setup one.',\n );\n process.exit(1);\n }\n const { verbose } = program.opts();\n const json = program.args.includes('-j') || program.args.includes('--json');\n Logger.VERBOSE = Boolean(verbose);\n if (!configName) {\n pluginUtil.listConfig(pluginName, json);\n } else {\n pluginUtil.getConfig(pluginName, configName, json);\n }\n });\n\nprogram\n .command('set-config <pluginName> [configName] [configValue]')\n .option('-y, --yes', 'Skip confirmation prompt')\n .option('-v, --verbose', 'Print extra messages for debugging purposes')\n .description(\n 'Sets a config for a plugin. If ' +\n 'configValue'.yellow.underline +\n ' is omitted, the config will be reset. If ' +\n 'configName'.yellow.underline +\n ' is omitted, the entire plugin config will be reset.',\n )\n .action(async (pluginName, configName, configValue) => {\n if (!config.find('.')) {\n Logger.errorp(\n 'Not an omegga directory, run ',\n 'omegga init'.yellow,\n 'to setup one.',\n );\n process.exit(1);\n }\n const { verbose } = program.opts();\n const yes = program.args.includes('-y') || program.args.includes('--yes');\n Logger.VERBOSE = Boolean(verbose);\n if (!configName) {\n pluginUtil.resetAllConfigs(pluginName, yes);\n } else if (!configValue) {\n pluginUtil.resetConfig(pluginName, configName);\n } else {\n pluginUtil.setConfig(pluginName, configName, configValue);\n }\n });\n\nprogram.parseAsync(process.argv);\n\nasync function setupSteam(config: config.IConfig, forceUpdate = false) {\n const steambeta = config?.server?.steambeta;\n const steambetaPassword = config?.server?.steambetaPassword;\n\n const binaryPath = path.join(\n GAME_INSTALL_DIR, // steam install directory\n steambeta ?? 'main', // steam beta branch (or main)\n GAME_DIRNAME, // Brickadia\n GAME_BIN_PATH, // path to binary\n );\n\n if (!forceUpdate && fs.existsSync(binaryPath)) {\n Logger.verbose(\n 'Game binary already exists at',\n binaryPath.yellow,\n '- skipping download.',\n );\n return;\n }\n\n // Check if steamcmd is installed\n if (!fs.existsSync(STEAMCMD_PATH)) {\n // Lookup steamcmd in path\n const hasSteamcmd = hasbin.sync('steamcmd');\n\n if (!hasSteamcmd) {\n // Prompt to install steamcmd\n const { install } =\n process.env.SKIP_STEAMCMD_PROMPT === 'true'\n ? { install: true }\n : await prompts({\n type: 'confirm',\n name: 'install',\n message: 'SteamCMD is not installed. OK to download it?',\n initial: true,\n });\n\n if (!install) {\n Logger.errorp('SteamCMD is required for steam support. Exiting...');\n process.exit(1);\n }\n\n Logger.logp('Downloading SteamCMD...');\n }\n\n try {\n steamcmdDownloadSelf();\n if (!fs.existsSync(STEAMCMD_PATH)) {\n Logger.errorp('Failed to setup SteamCMD. Exiting...');\n process.exit(1);\n }\n } catch (err) {\n Logger.errorp('Error setting up SteamCMD:', err);\n process.exit(1);\n }\n }\n\n Logger.logp('Downloading Brickadia', (steambeta ?? 'main').yellow, '...');\n try {\n steamcmdDownloadGame({ steambeta, steambetaPassword });\n } catch (err) {\n Logger.errorp('Error downloading Brickadia:', err);\n process.exit(1);\n }\n}\n"],"names":["PKG","Logger","config.write","soft","config.defaultConfig","file.mkdir","VERSION","config.store","config.find","config.read","OVERRIDE_GAME_DIR","GAME_BIN_PATH","installLauncher","auth","server","Omegga","Terminal","hasSteamUpdate","omeggaConfig","file.rmdir","pluginUtil","config","GAME_INSTALL_DIR","GAME_DIRNAME","STEAMCMD_PATH","steamcmdDownloadSelf","steamcmdDownloadGame"],"mappings":"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"}
1
+ {"version":3,"file":"main.js","sources":["../src/main.ts"],"sourcesContent":["import soft, {\n getOverrideGameBinary,\n getSteamGameDir,\n getSteamInstallDir,\n} from '@/softconfig';\nimport { installLauncher } from '@cli/installer';\nimport * as config from '@config';\nimport Omegga from '@omegga/server';\nimport * as file from '@util/file';\nimport 'colors';\nimport commander from 'commander';\nimport dotenv from 'dotenv';\nimport hasbin from 'hasbin';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport prompts from 'prompts';\nimport updateNotifier from 'update-notifier-cjs';\nimport { auth, config as omeggaConfig, pluginUtil, Terminal } from './cli';\nimport { IConfig } from './config/types';\nimport Logger from './logger';\nimport { GAME_BIN_PATH, STEAMCMD_PATH } from './softconfig';\nimport {\n hasSteamUpdate,\n steamcmdDownloadGame,\n steamcmdDownloadSelf,\n} from './updater';\nimport { PKG, VERSION } from './version';\n\ndotenv.config({ quiet: true });\n\nconst notifier =\n process.env.PACKAGE_NOTIFIER !== 'false'\n ? updateNotifier({\n pkg: PKG,\n updateCheckInterval: 1000 * 60 * 60 * 24,\n })\n : null;\nnotifier?.notify();\n\n// TODO: let omegga bundle config (roles, bans, server config) to zip\n// TODO: let omegga unbundle config from zip to current omegga dir\n\n// write a default config file\nconst createDefaultConfig = () => {\n Logger.logp('Created default config file');\n config.write(soft.CONFIG_FILENAMES[0] + '.yml', config.defaultConfig);\n file.mkdir(`data/${soft.CONFIG_SAVED_DIR}/Builds`);\n file.mkdir('plugins');\n return config.defaultConfig;\n};\n\nconst program = commander\n .description(PKG.description)\n .version(VERSION)\n .option(\n '-d, --debug',\n 'Print all console logs rather than just chat messages',\n )\n .option(\n '-u, --update',\n 'Check for brickadia updates (on steam) and install them if available',\n )\n .option('-v, --verbose', 'Print extra messages for debugging purposes')\n .action(async () => {\n const { debug, verbose, update } = program.opts();\n if (program.args.length > 0) {\n program.help();\n process.exit(1);\n }\n Logger.VERBOSE = Boolean(verbose);\n\n // default working directory is the one specified in config\n let workDir = config.store.get('defaultOmegga');\n Logger.verbose('Using working directory', workDir?.yellow);\n\n // if there's a config in the current directory, use that one instead\n if (config.find('.')) workDir = '.';\n\n // check if configured path exists\n if (!fs.existsSync(workDir)) {\n Logger.errorp('configured omegga default path does not exist');\n process.exit(1);\n }\n if (!fs.statSync(workDir).isDirectory) {\n Logger.errorp('configured omegga default path is not a directory');\n process.exit(1);\n }\n\n // find the config for the working directory\n const configFile = config.find(workDir);\n Logger.verbose('Target config file:', configFile?.yellow);\n let conf: IConfig;\n\n // create a default config file if it does not already exist, otherwise load in the existing one\n if (!configFile) {\n Logger.verbose('Creating a new config');\n conf = createDefaultConfig();\n } else {\n Logger.verbose('Reading config file');\n try {\n conf = config.read(configFile);\n } catch (error) {\n Logger.errorp('Error reading config file');\n Logger.verbose(error);\n }\n }\n\n const overrideBinary = getOverrideGameBinary();\n const isSteam = !conf?.server?.branch;\n if (overrideBinary) {\n if (!fs.existsSync(overrideBinary)) {\n Logger.error(\n 'Binary',\n overrideBinary.yellow,\n 'in',\n 'BRICKADIA_DIR'.yellow,\n 'does not exist!',\n );\n process.exit(1);\n }\n\n Logger.verbose(\n 'Using override binary',\n overrideBinary.yellow,\n '- skipping download.',\n );\n } else if (isSteam) {\n conf.__STEAM = true;\n await setupSteam(conf, update);\n } else {\n Logger.warnp(\n 'Brickadia will be launched with',\n 'non-steam launcher'.yellow,\n );\n Logger.warnp(\n 'New versions of Brickadia are not published on the old launcher.'\n .yellow,\n );\n\n // Check if the local launcher is installed\n if (fs.existsSync(soft.LOCAL_LAUNCHER)) {\n Logger.verbose(\"Using omegga's brickadia-launcher\");\n conf.server.__LOCAL = true;\n } else {\n Logger.verbose(\"Installing launcher as it's missing\");\n await installLauncher();\n }\n }\n\n const globalToken = auth.getGlobalToken();\n\n const hasHostingToken = Boolean(\n conf?.credentials?.token || process.env.BRICKADIA_TOKEN || globalToken,\n );\n\n // Skip auth when the hosting token is present\n if (hasHostingToken) {\n Logger.verbose(\n 'Skipping auth token generation due to host token presence',\n );\n if (conf?.credentials?.token)\n Logger.verbose('Found token in config file');\n else if (process.env.BRICKADIA_TOKEN)\n Logger.verbose('Found token in', 'BRICKADIA_TOKEN'.yellow);\n else if (globalToken)\n Logger.verbose('Found token in omegga global config');\n else Logger.verbose('unreachable - no token found');\n\n // check if the auth files don't exist\n } else if (\n !auth.exists(\n path.join(\n workDir,\n soft.DATA_PATH,\n conf?.server?.savedDir ?? soft.CONFIG_SAVED_DIR,\n conf?.server?.authDir ?? soft.CONFIG_AUTH_DIR,\n ),\n )\n ) {\n const success = await auth.prompt({\n debug,\n email: conf?.credentials?.['email'] ?? process.env.BRICKADIA_USER,\n password: conf?.credentials?.['password'] ?? process.env.BRICKADIA_PASS,\n isSteam,\n branch: conf?.server?.branch,\n authDir: conf?.server?.authDir,\n savedDir: conf?.server?.savedDir,\n launchArgs: conf?.server?.launchArgs,\n });\n if (!success) {\n Logger.errorp('Start aborted - could not generate auth tokens');\n process.exit(1);\n }\n } else {\n Logger.verbose(\n 'Skipping auth token generation due to existing auth files',\n );\n }\n\n // build options\n const options = {\n // default enable web ui (set to false)\n noweb: typeof conf.omegga?.webui === 'boolean' && !conf.omegga?.webui,\n // default enable https (set to true, will not be https if it can't generate)\n https: typeof conf.omegga?.https !== 'boolean' || conf.omegga?.https,\n port: conf.omegga?.port || soft.DEFAULT_PORT,\n debug,\n };\n\n Logger.verbose('Launching with options', options);\n\n // setup the server\n const server = new Omegga(workDir, conf, options);\n Logger.verbose('Created omegga object');\n\n if (verbose) {\n server.on(\n '*',\n (ev: string) => ev !== 'line' && Logger.verbose('EVENT'.green, ev),\n );\n }\n\n // create a terminal\n Logger.setTerminal(new Terminal(server, options));\n\n if (notifier?.update) {\n Logger.logp(\n `Omegga update is available (${('v' + notifier.update.latest).yellow})! Run`,\n 'npm i -g omegga'.yellow,\n 'to update!',\n );\n }\n\n if (\n conf.__STEAM &&\n !update &&\n !conf.server?.steambetaPassword &&\n process.env.STEAM_NOTIFIER !== 'false'\n ) {\n hasSteamUpdate(conf.server?.steambeta).then(hasUpdate => {\n if (hasUpdate) {\n Logger.logp('A server update is available!'.brightBlue);\n Logger.log(\n ' Restart with',\n 'omegga --update'.yellow,\n 'to update every start.',\n );\n Logger.log(' Run', '/update'.yellow, 'to update', 'now'.green + '!');\n } else {\n Logger.verbose('No server updates available.');\n }\n });\n }\n\n Logger.logp(\n `Launching brickadia server on port ${\n ('' + (conf.server.port || 7777)).green\n }...`,\n );\n\n // start the server\n Logger.verbose('Starting Omegga');\n server.start();\n });\n\nprogram\n .command('init')\n .description('Sets up the current directory as a brickadia server')\n .action(async () => {\n const configFile = config.find('.');\n if (configFile) {\n Logger.errorp('Config file already exists:', configFile.yellow.underline);\n process.exit(1);\n }\n createDefaultConfig();\n });\n\nprogram\n .command('config [field] [value]')\n .description(\n \"Configure Omegga's default behavior.\\n\" +\n 'Type ' +\n 'omegga config list'.yellow.underline +\n ' for current settings and available fields',\n )\n .action((field, value) => {\n if (!field) field = 'list';\n omeggaConfig(field, value, program.opts());\n });\n\nprogram\n .command('auth')\n .option('-g, --global', 'Remove global auth files')\n .option('-l, --local', 'Remove local auth files')\n .option('-w, --workdir', 'Remove configured location auth files')\n .option('-u, --email <email>', 'User email (must provide password)')\n .option('-p, --pass <password>', 'User password (must provide email)')\n .option('-v, --verbose', 'Print extra messages for debugging purposes')\n .description(\n 'Generates server auth tokens from brickadia account email+password',\n )\n .action(\n async ({\n email,\n pass: password,\n local: localAuth,\n workDir,\n global: globalAuth,\n }) => {\n const { verbose, debug } = program.opts();\n Logger.VERBOSE = Boolean(verbose);\n\n let branch: string, authDir: string, savedDir: string, launchArgs: string;\n let isSteam: boolean;\n\n // if there's a config in the current directory, use that one instead\n if (config.find('.')) workDir = '.';\n\n // check if configured path exists\n if (fs.existsSync(workDir) && fs.statSync(workDir).isDirectory) {\n Logger.verbose('Using working directory', workDir.yellow);\n // find the config for the working directory\n const configFile = config.find(workDir);\n Logger.verbose('Target config file:', configFile?.yellow);\n try {\n // read the config and extract the branch\n const conf = config.read(configFile);\n Logger.verbose(\n 'Auth config:',\n conf?.server ?? 'no server config'.grey,\n );\n branch = conf?.server?.branch;\n authDir = conf?.server?.authDir;\n savedDir = conf?.server?.savedDir;\n launchArgs = conf?.server?.launchArgs;\n isSteam = !conf?.server?.branch;\n\n if (localAuth && conf?.credentials?.token) {\n Logger.logp(\n \"This server's auth is managed by the token in\",\n configFile.yellow,\n );\n return;\n }\n } catch (error) {\n Logger.errorp('Error reading config file');\n Logger.verbose(error);\n }\n } else {\n Logger.verbose('Using default working directory', workDir.yellow);\n }\n\n savedDir ??= soft.CONFIG_SAVED_DIR;\n\n const workdirPath = path.join(\n config.store.get('defaultOmegga'),\n `data/${savedDir}/Auth`,\n );\n\n if (globalAuth || localAuth) {\n if (globalAuth) {\n const globalAuthPath = path.join(\n soft.CONFIG_HOME,\n savedDir !== soft.CONFIG_SAVED_DIR ? savedDir : '',\n authDir ?? soft.CONFIG_AUTH_DIR,\n );\n Logger.logp('Clearing auth files from', globalAuthPath.yellow);\n auth.clean(globalAuthPath);\n }\n if (workDir) {\n Logger.logp('Clearing auth files from', workdirPath.yellow);\n await file.rmdir(workdirPath);\n }\n if (localAuth) {\n const localPath = path.resolve(\n `data/${savedDir}/`,\n authDir ?? soft.CONFIG_AUTH_DIR,\n );\n Logger.logp('Clearing auth files from', localPath.yellow);\n await file.rmdir(localPath);\n }\n return;\n }\n\n if (!isSteam) {\n Logger.warnp('Authenticating with', 'non-steam launcher'.yellow);\n }\n\n auth.prompt({\n email,\n password,\n debug,\n branch,\n authDir,\n savedDir,\n launchArgs,\n });\n },\n );\n\nprogram\n .command('info')\n .alias('n')\n .description(\n 'Shows server name, description, port, install info, and installed plugins',\n )\n .action(async () => {\n Logger.errorp('not implemented yet');\n // TODO: implement config parsing\n });\n\nprogram\n .command('install <pluginUrl...>')\n .alias('i')\n .option('-f, --force', 'Forcefully re-install existing plugin') // TODO: implement install --force\n .option('-v, --verbose', 'Print extra messages for debugging purposes')\n .description('Installs a plugin to the current brickadia server')\n .action(async plugins => {\n if (!hasbin.sync('git')) {\n Logger.errorp('git'.yellow, 'must be installed to install plugins.');\n process.exit(1);\n }\n\n if (!config.find('.')) {\n Logger.errorp(\n 'Not an omegga directory, run ',\n 'omegga init'.yellow,\n 'to setup one.',\n );\n process.exit(1);\n }\n const { verbose, force } = program.opts();\n Logger.VERBOSE = Boolean(verbose);\n pluginUtil.install(plugins, { verbose, force });\n });\n\nprogram\n .command('update [pluginNames...]')\n .alias('u')\n .option('-f, --force', 'Forcefully re-upgrade existing plugin') // TODO: implement update --force\n .option('-v, --verbose', 'Print extra messages for debugging purposes')\n .description('Updates all or selected installed plugins to latest versions')\n .action(async plugins => {\n if (!config.find('.')) {\n Logger.errorp(\n 'Not an omegga directory, run ',\n 'omegga init'.yellow,\n 'to setup one.',\n );\n process.exit(1);\n }\n const { verbose, force } = program.opts();\n Logger.VERBOSE = Boolean(verbose);\n pluginUtil.update(plugins, { verbose, force });\n });\n\nprogram\n .command('check [pluginNames...]')\n .option('-v, --verbose', 'Print extra messages for debugging purposes')\n .description('Checks plugins for compatibility issues')\n .action(async plugins => {\n if (!config.find('.')) {\n Logger.errorp(\n 'Not an omegga directory, run ',\n 'omegga init'.yellow,\n 'to setup one.',\n );\n process.exit(1);\n }\n const { verbose } = program.opts();\n Logger.VERBOSE = Boolean(verbose);\n pluginUtil.check(plugins, { verbose });\n });\n\nprogram\n .command('init-plugin')\n .option('-v, --verbose', 'Print extra messages for debugging purposes')\n .description('Initializes a new plugin with the given name and settings')\n .action(async () => {\n const { verbose } = program.opts();\n Logger.VERBOSE = Boolean(verbose);\n\n pluginUtil.init();\n });\n\nprogram\n .command('plugin-init')\n .description('Alias for ' + 'init-plugin'.yellow.underline)\n .option('-v, --verbose', 'Print extra messages for debugging purposes')\n .action(async () => {\n const { verbose } = program.opts();\n Logger.VERBOSE = Boolean(verbose);\n\n pluginUtil.init();\n });\n\nprogram\n .command('get-config <pluginName> [configName]')\n .option('-v, --verbose', 'Print extra messages for debugging purposes')\n .option('-j, --json', 'Print config as json')\n .description(\n 'Gets a config for a plugin. If ' +\n 'configName'.yellow.underline +\n ' is omitted, returns all config values.',\n )\n .action(async (pluginName, configName) => {\n if (!config.find('.')) {\n Logger.errorp(\n 'Not an omegga directory, run ',\n 'omegga init'.yellow,\n 'to setup one.',\n );\n process.exit(1);\n }\n const { verbose } = program.opts();\n const json = program.args.includes('-j') || program.args.includes('--json');\n Logger.VERBOSE = Boolean(verbose);\n if (!configName) {\n pluginUtil.listConfig(pluginName, json);\n } else {\n pluginUtil.getConfig(pluginName, configName, json);\n }\n });\n\nprogram\n .command('set-config <pluginName> [configName] [configValue]')\n .option('-y, --yes', 'Skip confirmation prompt')\n .option('-v, --verbose', 'Print extra messages for debugging purposes')\n .description(\n 'Sets a config for a plugin. If ' +\n 'configValue'.yellow.underline +\n ' is omitted, the config will be reset. If ' +\n 'configName'.yellow.underline +\n ' is omitted, the entire plugin config will be reset.',\n )\n .action(async (pluginName, configName, configValue) => {\n if (!config.find('.')) {\n Logger.errorp(\n 'Not an omegga directory, run ',\n 'omegga init'.yellow,\n 'to setup one.',\n );\n process.exit(1);\n }\n const { verbose } = program.opts();\n const yes = program.args.includes('-y') || program.args.includes('--yes');\n Logger.VERBOSE = Boolean(verbose);\n if (!configName) {\n pluginUtil.resetAllConfigs(pluginName, yes);\n } else if (!configValue) {\n pluginUtil.resetConfig(pluginName, configName);\n } else {\n pluginUtil.setConfig(pluginName, configName, configValue);\n }\n });\n\nprogram.parseAsync(process.argv);\n\nasync function setupSteam(config: config.IConfig, forceUpdate = false) {\n const steambeta = config?.server?.steambeta;\n const steambetaPassword = config?.server?.steambetaPassword;\n\n const binaryPath = path.join(\n getSteamInstallDir(), // steam install directory\n steambeta ?? 'main', // steam beta branch (or main)\n getSteamGameDir(), // Brickadia\n GAME_BIN_PATH, // path to binary\n );\n\n if (!forceUpdate && fs.existsSync(binaryPath)) {\n Logger.verbose(\n 'Game binary already exists at',\n binaryPath.yellow,\n '- skipping download.',\n );\n return;\n }\n\n // Check if steamcmd is installed\n if (!fs.existsSync(STEAMCMD_PATH)) {\n // Lookup steamcmd in path\n const hasSteamcmd = hasbin.sync('steamcmd');\n\n if (!hasSteamcmd) {\n // Prompt to install steamcmd\n const { install } =\n process.env.SKIP_STEAMCMD_PROMPT === 'true'\n ? { install: true }\n : await prompts({\n type: 'confirm',\n name: 'install',\n message: 'SteamCMD is not installed. OK to download it?',\n initial: true,\n });\n\n if (!install) {\n Logger.errorp('SteamCMD is required for steam support. Exiting...');\n process.exit(1);\n }\n\n Logger.logp('Downloading SteamCMD...');\n }\n\n try {\n steamcmdDownloadSelf();\n if (!fs.existsSync(STEAMCMD_PATH)) {\n Logger.errorp('Failed to setup SteamCMD. Exiting...');\n process.exit(1);\n }\n } catch (err) {\n Logger.errorp('Error setting up SteamCMD:', err);\n process.exit(1);\n }\n }\n\n Logger.logp('Downloading Brickadia', (steambeta ?? 'main').yellow, '...');\n try {\n steamcmdDownloadGame({ steambeta, steambetaPassword });\n } catch (err) {\n Logger.errorp('Error downloading Brickadia:', err);\n process.exit(1);\n }\n}\n"],"names":["PKG","Logger","config.write","soft","config.defaultConfig","file.mkdir","VERSION","config.store","config.find","config.read","getOverrideGameBinary","installLauncher","auth","server","Omegga","Terminal","hasSteamUpdate","omeggaConfig","file.rmdir","pluginUtil","config","getSteamInstallDir","getSteamGameDir","GAME_BIN_PATH","STEAMCMD_PATH","steamcmdDownloadSelf","steamcmdDownloadGame"],"mappings":"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"}
@@ -147,31 +147,59 @@ class Player {
147
147
  }
148
148
  static async getScore(omegga, target, minigameIndex) {
149
149
  if (typeof target === "string") target = omegga.getPlayer(target);
150
- if (target?.name) {
151
- const name = target?.name;
152
- const id = target?.id;
153
- const match = await omegga.addWatcher(
154
- (line, match2) => {
155
- if (match2 && match2.groups.generator === "LogConsoleCommands") {
156
- const test = match2.groups.data.match(
157
- /^(?<uuid>.+) leaderboard value (?<minigame>\d+) = (?<score>-?\d+)$/
158
- );
159
- if (!test) return;
160
- if (test.groups.uuid !== id) return;
161
- if (Number(test.groups.minigame) !== minigameIndex) return;
162
- return test;
163
- }
164
- },
165
- {
166
- timeoutDelay: 1e3,
167
- exec: () => omegga.writeln(
168
- `Server.Players.PrintLeaderboardValue "${name}" ${minigameIndex}`
169
- )
170
- }
171
- );
172
- if (match) return Number(match[0].groups.score);
173
- }
174
- return 0;
150
+ if (!target?.name) return 0;
151
+ const name = target?.name;
152
+ const id = target?.id;
153
+ const match = await omegga.addWatcher(
154
+ (line, match2) => {
155
+ if (match2?.groups.generator !== "LogConsoleCommands") return;
156
+ const test = match2.groups.data.match(
157
+ /^(?<uuid>.+) leaderboard value (?<minigame>\d+) = (?<score>-?\d+)$/
158
+ );
159
+ if (!test) return;
160
+ if (test.groups.uuid !== id) return;
161
+ if (Number(test.groups.minigame) !== minigameIndex) return;
162
+ return test;
163
+ },
164
+ {
165
+ timeoutDelay: 1e3,
166
+ exec: () => omegga.writeln(
167
+ `Server.Players.PrintLeaderboardValue "${name}" ${minigameIndex}`
168
+ )
169
+ }
170
+ );
171
+ if (match) return Number(match[0].groups.score);
172
+ }
173
+ static setLeaderboard(omegga, target, key, value) {
174
+ if (typeof target === "string") target = omegga.getPlayer(target);
175
+ if (!target?.name) return null;
176
+ omegga.writeln(
177
+ `Server.Players.SetLeaderboardValue "${target.name}" "${key}" "${value}"`
178
+ );
179
+ }
180
+ static async getLeaderboard(omegga, target, key) {
181
+ if (typeof target === "string") target = omegga.getPlayer(target);
182
+ if (!target?.name) return null;
183
+ const match = await omegga.addWatcher(
184
+ (line, match2) => {
185
+ if (match2?.groups.generator !== "LogConsoleCommands") return;
186
+ const test = match2.groups.data.match(
187
+ /^(?<uuid>.+) leaderboard value (?<key>.+) = (?<value>-?\d+)$/
188
+ );
189
+ if (!test) return;
190
+ if (test.groups.uuid !== target.id) return;
191
+ if (test.groups.key !== key) return;
192
+ return test;
193
+ },
194
+ {
195
+ timeoutDelay: 1e3,
196
+ exec: () => omegga.writeln(
197
+ `Server.Players.PrintLeaderboardValue "${target.name}" "${key}"`
198
+ )
199
+ }
200
+ ).catch(() => null);
201
+ if (match) return Number(match[0].groups.value);
202
+ return null;
175
203
  }
176
204
  /**
177
205
  * players are not to be constructed
@@ -537,6 +565,12 @@ class Player {
537
565
  getScore(minigameIndex) {
538
566
  return Player.getScore(this.#omegga, this, minigameIndex);
539
567
  }
568
+ setLeaderboard(key, value) {
569
+ Player.setLeaderboard(this.#omegga, this, key, value);
570
+ }
571
+ async getLeaderboard(key) {
572
+ return Player.getLeaderboard(this.#omegga, this, key);
573
+ }
540
574
  }
541
575
  global.Player = Player;
542
576
  exports.default = Player;