omegga 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -10
- package/dist/brickadia/server.js +4 -8
- package/dist/brickadia/server.js.map +1 -1
- package/dist/main.js +8 -7
- package/dist/main.js.map +1 -1
- package/dist/omegga/player.js +59 -25
- package/dist/omegga/player.js.map +1 -1
- package/dist/omegga/plugin/plugin_jsonrpc_stdio.js +54 -0
- package/dist/omegga/plugin/plugin_jsonrpc_stdio.js.map +1 -1
- package/dist/plugin.js.map +1 -1
- package/dist/softconfig.js +33 -15
- package/dist/softconfig.js.map +1 -1
- package/dist/updater/steam.js +17 -12
- package/dist/updater/steam.js.map +1 -1
- package/package.json +3 -2
- package/public/app.html +18 -18
- package/public/assets/IconArrowRight-BuVxhqKX.js +2 -0
- package/public/assets/{IconArrowRight-CA5_cccJ.js.map → IconArrowRight-BuVxhqKX.js.map} +1 -1
- package/public/assets/IconCheck-DOe3u7iH.js +2 -0
- package/public/assets/{IconCheck-Dyq5qyY1.js.map → IconCheck-DOe3u7iH.js.map} +1 -1
- package/public/assets/IconLockOpen-Bs7Tsf6u.js +2 -0
- package/public/assets/{IconLockOpen-D95XLORK.js.map → IconLockOpen-Bs7Tsf6u.js.map} +1 -1
- package/public/assets/IconWorld-B6GK5qpx.js +2 -0
- package/public/assets/{IconWorld-DtARpBKX.js.map → IconWorld-B6GK5qpx.js.map} +1 -1
- package/public/assets/IconWorldPlus-DpfueG8_.js +2 -0
- package/public/assets/{IconWorldPlus-CGBAsLNj.js.map → IconWorldPlus-DpfueG8_.js.map} +1 -1
- package/public/assets/IconX-CvmO0bbE.js +2 -0
- package/public/assets/{IconX-SYtbnYKI.js.map → IconX-CvmO0bbE.js.map} +1 -1
- package/public/assets/app-nJIpyOiP.js +6 -0
- package/public/assets/{app-BtOlgo__.js.map → app-nJIpyOiP.js.map} +1 -1
- package/public/assets/{auth-CvxEWAMc.js → auth-6N37o421.js} +2 -2
- package/public/assets/{auth-CvxEWAMc.js.map → auth-6N37o421.js.map} +1 -1
- package/public/assets/client-BT1QYH0O.js +10 -0
- package/public/assets/{client-C5T7_OK9.js.map → client-BT1QYH0O.js.map} +1 -1
- package/public/assets/index-2cgXLhrt.js +2 -0
- package/public/assets/{index-CRRRLlCc.js.map → index-2cgXLhrt.js.map} +1 -1
- package/public/assets/index-3dNmNZ9B.js +10 -0
- package/public/assets/{index-Bq9C9SqB.js.map → index-3dNmNZ9B.js.map} +1 -1
- package/public/assets/{index-i4mjW0og.js → index-CrN8I5Az.js} +2 -2
- package/public/assets/index-CrN8I5Az.js.map +1 -0
- package/public/assets/index-CtCtK5BX.js +2 -0
- package/public/assets/{index-DqHVrEeL.js.map → index-CtCtK5BX.js.map} +1 -1
- package/public/assets/index-D0OPOe3j.js +2 -0
- package/public/assets/{index-c0qeY2gs.js.map → index-D0OPOe3j.js.map} +1 -1
- package/public/assets/{index-DYcAgWjJ.js → index-DY750sgZ.js} +2 -2
- package/public/assets/{index-DYcAgWjJ.js.map → index-DY750sgZ.js.map} +1 -1
- package/public/assets/jsx-runtime-BX5r4UiA.js +2 -0
- package/public/assets/jsx-runtime-BX5r4UiA.js.map +1 -0
- package/public/assets/jsx-runtime-DldvXD6N.js +2 -0
- package/public/assets/{jsx-runtime-Bw5QeaCk.js.map → jsx-runtime-DldvXD6N.js.map} +1 -1
- package/public/assets/shared/@components-DdtLZOaA.js +2 -0
- package/public/assets/shared/@components-DdtLZOaA.js.map +1 -0
- package/public/assets/shared/{@hooks-DfTzYBIL.js → @hooks-Ch_hJYh0.js} +2 -2
- package/public/assets/shared/{@hooks-DfTzYBIL.js.map → @hooks-Ch_hJYh0.js.map} +1 -1
- package/public/assets/shared/{@nanostores_react-HTG3s0lp.js → @nanostores_react-DJPF1Eqx.js} +2 -2
- package/public/assets/shared/{@nanostores_react-HTG3s0lp.js.map → @nanostores_react-DJPF1Eqx.js.map} +1 -1
- package/public/assets/shared/@tabler_icons-react-B4bN8gHc.js +3 -0
- package/public/assets/shared/{@tabler_icons-react--FJWdUou.js.map → @tabler_icons-react-B4bN8gHc.js.map} +1 -1
- package/public/assets/shared/nanostores-BFqqIY_c.js.map +1 -1
- package/public/assets/shared/react-dom-8Rcmh_FG.js +2 -0
- package/public/assets/shared/{react-dom-BznoGTRX.js.map → react-dom-8Rcmh_FG.js.map} +1 -1
- package/public/assets/shared/react-iXLZ_Bod.js +2 -0
- package/public/assets/shared/{react-CR6vSpIu.js.map → react-iXLZ_Bod.js.map} +1 -1
- package/public/assets/shared/react_jsx-runtime-BwhiLcBy.js +2 -0
- package/public/assets/shared/{react_jsx-runtime-C15Zu6_p.js.map → react_jsx-runtime-BwhiLcBy.js.map} +1 -1
- package/public/assets/shared/{wouter-DbmGxXTo.js → wouter-CUC1caxu.js} +2 -2
- package/public/assets/shared/wouter-CUC1caxu.js.map +1 -0
- package/public/auth.html +14 -14
- package/templates/safe-ts/omegga.d.ts +30 -0
- package/public/assets/IconArrowRight-CA5_cccJ.js +0 -7
- package/public/assets/IconCheck-Dyq5qyY1.js +0 -17
- package/public/assets/IconLockOpen-D95XLORK.js +0 -7
- package/public/assets/IconWorld-DtARpBKX.js +0 -72
- package/public/assets/IconWorldPlus-CGBAsLNj.js +0 -182
- package/public/assets/IconX-SYtbnYKI.js +0 -12
- package/public/assets/app-BtOlgo__.js +0 -6
- package/public/assets/client-C5T7_OK9.js +0 -26
- package/public/assets/index-Bq9C9SqB.js +0 -10
- package/public/assets/index-CRRRLlCc.js +0 -10
- package/public/assets/index-DqHVrEeL.js +0 -10
- package/public/assets/index-c0qeY2gs.js +0 -10
- package/public/assets/index-i4mjW0og.js.map +0 -1
- package/public/assets/jsx-runtime-Bw5QeaCk.js +0 -10
- package/public/assets/jsx-runtime-DoEZbXM1.js +0 -2
- package/public/assets/jsx-runtime-DoEZbXM1.js.map +0 -1
- package/public/assets/shared/@components-DVehBp7v.js +0 -2
- package/public/assets/shared/@components-DVehBp7v.js.map +0 -1
- package/public/assets/shared/@tabler_icons-react--FJWdUou.js +0 -29458
- package/public/assets/shared/react-CR6vSpIu.js +0 -2
- package/public/assets/shared/react-dom-BznoGTRX.js +0 -2
- package/public/assets/shared/react_jsx-runtime-C15Zu6_p.js +0 -2
- package/public/assets/shared/wouter-DbmGxXTo.js.map +0 -1
- package/vite.backend.config.mts +0 -46
- package/vite.frontend.config.mts +0 -58
- package/vitest.backend.config.mts +0 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"player.js","sources":["../../src/omegga/player.ts"],"sourcesContent":["import type { OmeggaLike, OmeggaPlayer, WeaponClass } from '@/plugin';\nimport { IBrickBounds } from '@util/brick';\nimport { WriteSaveObject } from 'brs-js';\nimport { brick as brickUtils, color } from '../util/';\n\nconst DEFAULT_PERMS: Record<string, string[]> = {\n moderator: [\n 'Bricks.ClearAll',\n 'Minigame.AlwaysLeave',\n 'Players.Kick',\n 'Players.TPInMinigame',\n 'Players.TPOthers',\n 'Self.Ghost',\n ],\n admin: [\n 'Bricks.ClearAll',\n 'Bricks.ClearOwn',\n 'Bricks.IgnoreTrust',\n 'Bricks.Load',\n 'Map.Environment',\n 'Minigame.AlwaysEdit',\n 'Minigame.AlwaysLeave',\n 'Minigame.AlwaysSwitchTeam',\n 'Minigame.MakeDefault',\n 'Minigame.MakePersistent',\n 'Minigame.UseAllBricks',\n 'Players.Ban',\n 'Players.Kick',\n 'Players.TPInMinigame',\n 'Players.TPOthers',\n 'Roles.Grant',\n 'Self.Ghost',\n 'Server.ChangeRoles',\n 'Server.ChangeSettings',\n 'Server.FreezeCamera',\n 'Tools.Selector.BypassLimits',\n 'Tools.Selector.BypassTimeouts',\n ],\n};\n\nclass Player implements OmeggaPlayer {\n #omegga: OmeggaLike;\n name: string;\n displayName: string;\n id: string;\n controller: string;\n state: string;\n\n static getRoles(omegga: OmeggaLike, id: string): readonly string[] {\n const data = omegga.getRoleAssignments().savedPlayerRoles[id];\n return Object.freeze(data && data.roles ? data.roles : []);\n }\n\n static getPermissions(\n omegga: OmeggaLike,\n id: string,\n ): Record<string, boolean> {\n const { roles, defaultRole } = omegga.getRoleSetup();\n\n // if the player is the host, the player has every permission\n if (omegga.host.id === id) {\n return Object.freeze(\n Object.fromEntries(\n [].concat(\n defaultRole.permissions.map(p => [p.name, true]),\n // sometimes the default role does not have every permission listed\n ...roles.map(r => r.permissions.map(p => [p.name, true])),\n ),\n ),\n );\n }\n\n // get the player's roles\n const playerRoles = Player.getRoles(omegga, id).map(r => r.toLowerCase());\n\n // default player permissions\n const permissions: Record<string, boolean> = {\n 'Bricks.ClearAll': false,\n 'Bricks.ClearOwn': true,\n 'Bricks.Delete': true,\n 'Bricks.Edit': true,\n 'Bricks.IgnoreTrust': false,\n 'Bricks.Paint': true,\n 'Bricks.Place': true,\n 'BricksItems.Spawn': true,\n 'Map.Change': false,\n 'Map.Environment': false,\n 'Map.SetSpawn': false,\n 'Minigame.AlwaysEdit': false,\n 'Minigame.AlwaysLeave': false,\n 'Minigame.AlwaysSwitchTeam': false,\n 'Minigame.Create': true,\n 'Minigame.MakePersistent': false,\n 'Minigame.UseAllBricks': false,\n 'Players.Ban': false,\n 'Players.TPInMinigame': false,\n 'Players.TPOthers': false,\n 'Players.TPSelf': true,\n 'Roles.Grant': false,\n 'Self.Flashlight': true,\n 'Self.Fly': true,\n 'Self.FreezeCamera': false,\n 'Self.Ghost': false,\n 'Self.Sprint': true,\n 'Self.Suicide': true,\n 'Tools.Selector.Use': true,\n };\n\n // apply all permissions from default role\n for (const p of defaultRole.permissions) {\n // technically this can never be Unchanged so it's always on enabled or allowed\n permissions[p.name] =\n p.state === 'Unchanged' ? permissions[p.name] : p.state === 'Allowed';\n }\n\n // loop through all the roles\n for (const role of roles) {\n // ignore ones the player does not have\n if (!playerRoles.includes(role.name.toLowerCase())) continue;\n\n const defaultPerms = DEFAULT_PERMS[role.name.toLowerCase()] || [];\n // iterate through default permissions\n for (const perm of defaultPerms) {\n // if they are not overriden, set it to true\n if (!role.permissions.find(r => r.name === perm))\n permissions[perm] = true;\n }\n\n // add all the new permissions the player now has\n for (const p of role.permissions) {\n // permission is disabled on forbidden, persisted on unchanged, and enabled on bEnabled or Allowed\n permissions[p.name] =\n p.state !== 'Forbidden' &&\n (p.state === 'Unchanged'\n ? permissions[p.name]\n : permissions[p.name] || p.state === 'Allowed');\n permissions[p.name] = permissions[p.name];\n }\n }\n\n return Object.freeze(permissions);\n }\n\n static kill(omegga: OmeggaLike, target: string | OmeggaPlayer) {\n if (typeof target === 'string') target = omegga.getPlayer(target);\n if (target?.name) omegga.writeln(`Server.Players.Kill \"${target?.name}\"`);\n }\n\n static damage(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n amount: number,\n ) {\n if (typeof target === 'string') target = omegga.getPlayer(target);\n if (amount === 0) return;\n if (target?.name)\n omegga.writeln(`Server.Players.Damage \"${target?.name}\" ${amount}`);\n }\n\n static heal(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n amount: number,\n ) {\n if (amount === 0) return;\n Player.damage(omegga, target, -amount);\n }\n\n static giveItem(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n item: WeaponClass,\n ) {\n if (typeof target === 'string') target = omegga.getPlayer(target);\n if (!item) return;\n if (target?.name)\n omegga.writeln(`Server.Players.GiveItem \"${target?.name}\" ${item}`);\n }\n\n static takeItem(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n item: WeaponClass,\n ) {\n if (typeof target === 'string') target = omegga.getPlayer(target);\n if (!item) return;\n if (target?.name)\n omegga.writeln(`Server.Players.RemoveItem \"${target?.name}\" ${item}`);\n }\n\n static setTeam(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n teamIndex: number,\n ) {\n if (typeof target === 'string') target = omegga.getPlayer(target);\n if (target?.name)\n omegga.writeln(`Server.Players.SetTeam \"${target?.name}\" ${teamIndex}`);\n }\n\n static setMinigame(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n index: number,\n ) {\n if (typeof target === 'string') target = omegga.getPlayer(target);\n if (target?.name)\n omegga.writeln(`Server.Players.SetMinigame \"${target?.name}\" ${index}`);\n }\n\n static setScore(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n minigameIndex: number,\n score: number,\n ) {\n if (typeof target === 'string') target = omegga.getPlayer(target);\n if (target?.name)\n omegga.writeln(\n `Server.Players.SetLeaderboardValue \"${target?.name}\" ${minigameIndex} ${score}`,\n );\n }\n\n static async getScore(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n minigameIndex: number,\n ): Promise<number> {\n if (typeof target === 'string') target = omegga.getPlayer(target);\n if (target?.name) {\n const name = target?.name;\n const id = target?.id;\n\n const match = await omegga.addWatcher(\n (line, match) => {\n if (match && match.groups.generator === 'LogConsoleCommands') {\n const test = match.groups.data.match(\n /^(?<uuid>.+) leaderboard value (?<minigame>\\d+) = (?<score>-?\\d+)$/,\n );\n if (!test) return;\n if (test.groups.uuid !== id) return;\n if (Number(test.groups.minigame) !== minigameIndex) return;\n return test;\n }\n },\n {\n timeoutDelay: 1000,\n exec: () =>\n omegga.writeln(\n `Server.Players.PrintLeaderboardValue \"${name}\" ${minigameIndex}`,\n ),\n },\n );\n if (match) return Number(match[0].groups.score);\n }\n return 0;\n }\n\n /**\n * players are not to be constructed\n * @constructor\n * @param omegga Omegga Instance\n * @param name Player Name\n * @param displayName Player Display Name\n * @param id Player Id\n * @param controller Player Controller\n * @param state Player State\n */\n constructor(\n omegga: OmeggaLike,\n username: string,\n displayName: string,\n id: string,\n controller: string,\n state: string,\n ) {\n this.#omegga = omegga;\n this.name = username;\n this.displayName = displayName;\n this.id = id;\n this.controller = controller;\n this.state = state;\n }\n\n getOmegga(): OmeggaLike {\n return this.#omegga;\n }\n\n clone(): OmeggaPlayer {\n return new Player(\n this.#omegga,\n this.name,\n this.displayName,\n this.id,\n this.controller,\n this.state,\n );\n }\n\n raw(): [string, string, string, string, string] {\n return [this.name, this.displayName, this.id, this.controller, this.state];\n }\n\n isHost(): boolean {\n return this.#omegga.host.id === this.id;\n }\n\n clearBricks(quiet = false) {\n this.#omegga.clearBricks(this.id, quiet);\n }\n\n getRoles(): readonly string[] {\n return Player.getRoles(this.#omegga, this.id);\n }\n\n getPermissions(): Record<string, boolean> {\n return Player.getPermissions(this.#omegga, this.id);\n }\n\n getNameColor(): string {\n const { roles, defaultRole, ownerRoleColor, bOwnerRoleHasColor } =\n this.#omegga.getRoleSetup();\n\n // host check if host has host color\n if (this.isHost() && bOwnerRoleHasColor)\n return color.rgbToHex(ownerRoleColor);\n\n // get the player's role\n const playerRoles = this.getRoles().map(r => r.toLowerCase());\n\n // only if the player actually has roles...\n if (playerRoles.length > 0) {\n // check the role list in reverse for the player's role (highest tier first)\n const found = roles\n .slice()\n .reverse()\n .find(\n role =>\n role.bHasColor && playerRoles.includes(role.name.toLowerCase()),\n );\n\n if (found) return color.rgbToHex(found.color);\n }\n\n return color.rgbToHex(\n defaultRole.bHasColor\n ? defaultRole.color\n : { r: 255, g: 255, b: 255, a: 255 },\n );\n }\n\n async getPawn(): Promise<string | null> {\n // given a player controller, match the player's pawn\n const pawnRegExp = new RegExp(\n `^(?<index>\\\\d+)\\\\) BP_PlayerController_C .+?PersistentLevel\\\\.${this.controller}\\\\.Pawn = .*?(?:BP_FigureV2_C'.+:PersistentLevel\\\\.)?(?<pawn>BP_FigureV2_C_\\\\d+|None)'?`,\n );\n\n // wait for the pawn watcher to return a pawn\n const [{ groups: { pawn = null } = {} } = {}] =\n await this.#omegga.watchLogChunk<RegExpMatchArray>(\n 'GetAll BP_PlayerController_C Pawn Name=' + this.controller,\n pawnRegExp,\n { first: 'index', timeoutDelay: 500 },\n );\n\n if (pawn === 'None') return null;\n\n return pawn;\n }\n\n async getPosition(): Promise<[number, number, number] | null> {\n // this is here because my text editor had weird syntax highlighting glitches when the other omeggas were replaced with this.#omegga...\n // guess the code is \"too new\" :egg:\n const omegga = this.#omegga;\n\n // given a player controller, match the player's pawn\n const pawnRegExp = new RegExp(\n `^(?<index>\\\\d+)\\\\) BP_PlayerController_C .+?PersistentLevel\\\\.${this.controller}\\\\.Pawn = .*?(?:BP_FigureV2_C'.+:PersistentLevel\\\\.)?(?<pawn>BP_FigureV2_C_\\\\d+|None)'?`,\n );\n\n // wait for the pawn watcher to return a pawn\n const [\n {\n groups: { pawn },\n },\n ] = await omegga.watchLogChunk<RegExpMatchArray>(\n 'GetAll BP_PlayerController_C Pawn Name=' + this.controller,\n pawnRegExp,\n { first: 'index', timeoutDelay: 100 },\n );\n\n if (pawn === 'None') return null;\n\n // given a player's pawn, match the player's position\n const posRegExp = new RegExp(\n `CapsuleComponent .+?PersistentLevel\\\\.${pawn}\\\\.CollisionCylinder\\\\.RelativeLocation = \\\\(X=(?<x>[\\\\d\\\\.-]+),Y=(?<y>[\\\\d\\\\.-]+),Z=(?<z>[\\\\d\\\\.-]+)\\\\)`,\n );\n\n // wait for the position promise\n const [\n {\n groups: { x, y, z },\n },\n ] = await omegga.addWatcher(posRegExp, {\n // request the position for this player's pawn\n exec: () =>\n omegga.writeln(\n `GetAll SceneComponent RelativeLocation Name=CollisionCylinder Outer=${pawn}`,\n ),\n timeoutDelay: 100,\n });\n\n // return the player's position as an array of numbers\n return [Number(x), Number(y), Number(z)];\n }\n\n async getGhostBrick(): Promise<{\n targetGrid: string;\n location: number[];\n orientation: string;\n }> {\n const { controller } = this;\n\n const previewClass = 'BP_ToolPreviewActor_C';\n\n const ownerRegExp = new RegExp(\n `^(?<index>\\\\d+)\\\\) ${previewClass} (.+):PersistentLevel\\\\.(?<actor>${previewClass}_\\\\d+)\\.Owner = .*?BP_PlayerController_C'(.+):PersistentLevel\\\\.(?<controller>BP_PlayerController_C_\\\\d+)'$`,\n );\n const transformParamsRegExp = new RegExp(\n `^(?<index>\\\\d+)\\\\) ${previewClass} (.+):PersistentLevel\\\\.(?<actor>${previewClass}_\\\\d+)\\\\.TransformParameters = \\\\(TargetGrid=(\"(?<targetGrid>.+)\"|None),Location=\\\\(X=(?<x>.+),Y=(?<y>.+),Z=(?<z>.+)\\\\),Orientation=(?<orientation>.+)\\\\)$`,\n );\n\n const [owners, transformParams] = await Promise.all([\n this.#omegga.watchLogChunk<RegExpMatchArray>(\n `GetAll ${previewClass} Owner`,\n ownerRegExp,\n {\n first: 'index',\n timeoutDelay: 2000,\n afterMatchDelay: 100,\n },\n ),\n this.#omegga.watchLogChunk<RegExpMatchArray>(\n `GetAll ${previewClass} TransformParameters`,\n transformParamsRegExp,\n {\n first: 'index',\n timeoutDelay: 2000,\n afterMatchDelay: 100,\n },\n ),\n ]);\n\n // get BrickGridPreviewActor by controller\n const owner = owners.find(owner => owner.groups.controller === controller);\n\n if (!owner) return;\n\n const actor = owner.groups.actor;\n // get transform parameters for the found actor\n const transformParameters = transformParams.find(\n transformParameters => transformParameters.groups.actor === actor,\n );\n\n if (!transformParameters) return;\n\n return {\n targetGrid: transformParameters.groups.targetGrid,\n location: [\n +transformParameters.groups.x,\n +transformParameters.groups.y,\n +transformParameters.groups.z,\n ],\n orientation: transformParameters.groups.orientation,\n };\n }\n\n async getPaint(): Promise<{\n materialIndex: string;\n materialAlpha: string;\n material: string;\n color: number[];\n }> {\n const { controller } = this;\n\n const match = await this.#omegga\n .addWatcher<{\n materialIndex: string;\n materialAlpha: string;\n material: string;\n color: number[];\n }>(\n line => {\n // [date][counter]0) BP_PlayerState_C /Game/Maps/Plate/Plate.Plate:PersistentLevel.BP_PlayerState_C_2147482378.ColorSelectionState = (SelectedColor=(B=6,G=73,R=246,A=255),MaterialIndex=3,MaterialAlpha=5)\n const match = line.match(\n /^\\[[^\\]]+\\]\\[[^\\]]+\\]\\d+\\) BP_PlayerState_C .+?PersistentLevel\\.(?<state>BP_PlayerState_C_\\d+)\\.ColorSelectionState = \\(SelectedColor=\\(B=(?<b>\\d+),G=(?<g>\\d+),R=(?<r>\\d+),A=(?<a>\\d+)\\),MaterialIndex=(?<materialIndex>\\d+),MaterialAlpha=(?<materialAlpha>\\d+)\\)$/,\n );\n if (!match) return;\n if (match.groups.state !== this.state) return;\n const colorRaw = [+match.groups.r, +match.groups.g, +match.groups.b];\n return {\n materialIndex: match.groups.materialIndex,\n materialAlpha: match.groups.materialAlpha,\n material:\n brickUtils.BRICK_CONSTANTS.DEFAULT_MATERIALS[\n Number(match.groups.materialIndex)\n ],\n color: colorRaw,\n };\n },\n {\n timeoutDelay: 1000,\n exec: () =>\n this.#omegga.writeln('GetAll BRPlayerState ColorSelectionState'),\n },\n )\n .catch(() => null);\n if (!match?.[0]) return;\n return match[0];\n }\n\n async isCrouched(pawn?: string): Promise<boolean> {\n if (!pawn) pawn = await this.getPawn();\n\n const reg =\n /(?<index>\\d+)\\) BP_FigureV2_C .+?PersistentLevel\\.(?<pawn>BP_FigureV2_C_\\d+)\\.bIsCrouched = (?<crouched>True|False)$/;\n\n const resp = await this.#omegga.watchLogChunk<RegExpMatchArray>(\n 'GetAll BP_FigureV2_C bIsCrouched Name=' + pawn,\n reg,\n { first: 'index', timeoutDelay: 500 },\n );\n\n const me = resp.find(r => r.groups.pawn === pawn);\n if (!me) return false;\n\n return me.groups.crouched == 'True';\n }\n\n async isDead(pawn?: string): Promise<boolean> {\n if (!pawn) pawn = await this.getPawn();\n\n const reg =\n /(?<index>\\d+)\\) BP_FigureV2_C .+?PersistentLevel\\.(?<pawn>BP_FigureV2_C_\\d+)\\.bIsDead = (?<dead>True|False)$/;\n\n const resp = await this.#omegga.watchLogChunk<RegExpMatchArray>(\n 'GetAll BP_FigureV2_C bIsDead Name=' + pawn,\n reg,\n { first: 'index', timeoutDelay: 500 },\n );\n\n const me = resp.find(r => r.groups.pawn === pawn);\n if (!me) return true;\n\n return me.groups.dead == 'True';\n }\n\n async getTemplateBounds() {\n const { controller } = this;\n\n const brickTemplateRegExp =\n /^(?<index>\\d+)\\) Tool_Selector_C (.+):PersistentLevel\\.(?<tool>Tool_Selector_C_\\d+)\\.CurrentTemplate = (.+)Brickadia.BrickBuildingTemplate'(.+)Transient.(?<templateName>BrickBuildingTemplate_\\d+)'$/;\n const brickTemplateOwnerRegExp =\n /^(?<index>\\d+)\\) Tool_Selector_C (.+):PersistentLevel\\.(?<tool>Tool_Selector_C_\\d+)\\.Owner = (.+)(?<controller>BP_PlayerController_C_\\d+)'$/;\n const minBoundsRegExp =\n /^(?<index>\\d+)\\) BrickBuildingTemplate (.+)Transient\\.(?<templateName>BrickBuildingTemplate_\\d+)\\.MinBounds = \\(X=(?<x>.+),Y=(?<y>.+),Z=(?<z>.+)\\)$/;\n const maxBoundsRegExp =\n /^(?<index>\\d+)\\) BrickBuildingTemplate (.+)Transient\\.(?<templateName>BrickBuildingTemplate_\\d+)\\.MaxBounds = \\(X=(?<x>.+),Y=(?<y>.+),Z=(?<z>.+)\\)$/;\n const centerRegExp =\n /^(?<index>\\d+)\\) BrickBuildingTemplate (.+)Transient\\.(?<templateName>BrickBuildingTemplate_\\d+)\\.Center = \\(X=(?<x>.+),Y=(?<y>.+),Z=(?<z>.+)\\)$/;\n\n const [templates, owners, minBounds, maxBounds, centers] =\n await Promise.all([\n this.#omegga.watchLogChunk<RegExpMatchArray>(\n 'GetAll Tool_Selector_C CurrentTemplate',\n brickTemplateRegExp,\n {\n first: 'index',\n timeoutDelay: 2000,\n afterMatchDelay: 100,\n },\n ),\n this.#omegga.watchLogChunk<RegExpMatchArray>(\n 'GetAll Tool_Selector_C Owner',\n brickTemplateOwnerRegExp,\n {\n first: 'index',\n timeoutDelay: 2000,\n afterMatchDelay: 100,\n },\n ),\n this.#omegga.watchLogChunk<RegExpMatchArray>(\n 'GetAll BrickBuildingTemplate MinBounds',\n minBoundsRegExp,\n {\n first: 'index',\n timeoutDelay: 2000,\n afterMatchDelay: 100,\n },\n ),\n this.#omegga.watchLogChunk<RegExpMatchArray>(\n 'GetAll BrickBuildingTemplate MaxBounds',\n maxBoundsRegExp,\n {\n first: 'index',\n timeoutDelay: 2000,\n afterMatchDelay: 100,\n },\n ),\n this.#omegga.watchLogChunk<RegExpMatchArray>(\n 'GetAll BrickBuildingTemplate Center',\n centerRegExp,\n {\n first: 'index',\n timeoutDelay: 2000,\n afterMatchDelay: 100,\n },\n ),\n ]);\n\n if (\n !templates.length ||\n !owners.length ||\n !minBounds.length ||\n !maxBounds.length ||\n !centers.length\n )\n return;\n\n // get selector for this controller, we need to handle if there are multiple selectors for the same controller\n const selectors = owners\n .filter(selectors => selectors.groups.controller === controller)\n .map(selectors => selectors.groups.tool)\n .sort();\n const selector = selectors[0]; // grab the most recently created\n\n if (!selector) {\n return;\n }\n\n // template for this selector, we need to handle if there are multiple templates for the same selector and grab the most recent one\n const brickTemplates = templates\n .filter(template => template.groups.tool === selector)\n .map(template => template.groups.templateName)\n .sort();\n const templateName = brickTemplates[0]; // grab the most recently created\n\n if (!templateName) {\n return;\n }\n\n // find all values with matching template name\n const minBound = minBounds.find(\n minBound => minBound.groups.templateName === templateName,\n );\n const maxBound = maxBounds.find(\n maxBound => maxBound.groups.templateName === templateName,\n );\n const center = centers.find(\n center => center.groups.templateName === templateName,\n );\n\n if (!minBound || !maxBound || !center) return;\n\n return {\n minBound: [+minBound.groups.x, +minBound.groups.y, +minBound.groups.z],\n maxBound: [+maxBound.groups.x, +maxBound.groups.y, +maxBound.groups.z],\n center: [+center.groups.x, +center.groups.y, +center.groups.z],\n } as IBrickBounds;\n }\n\n async getTemplateBoundsData() {\n const templateBounds = await this.getTemplateBounds();\n\n if (!templateBounds) return;\n\n const saveData = await this.#omegga.getSaveData({\n center: templateBounds.center,\n extent: [\n Math.round(\n (templateBounds.maxBound[0] - templateBounds.minBound[0]) / 2,\n ),\n Math.round(\n (templateBounds.maxBound[1] - templateBounds.minBound[1]) / 2,\n ),\n Math.round(\n (templateBounds.maxBound[2] - templateBounds.minBound[2]) / 2,\n ),\n ],\n });\n\n if (!saveData) return;\n\n // filter bricks outside the bounds\n // no longer necessary thanks to Bricks.SaveRegion\n /* saveData.bricks = (saveData.bricks as Brick[]).filter(brick => {\n return brickUtils.checkBounds(\n brick,\n saveData.brick_assets,\n templateBounds\n );\n }) as typeof saveData.bricks; */\n\n if (saveData.bricks.length > 0) {\n return saveData;\n }\n\n return undefined;\n }\n\n loadBricks(saveName: string) {\n this.#omegga.loadBricksOnPlayer(saveName, this);\n }\n\n async loadSaveData(\n saveData: WriteSaveObject,\n { offX = 0, offY = 0, offZ = 0 } = {},\n ) {\n await this.#omegga.loadSaveDataOnPlayer(saveData, this, {\n offX,\n offY,\n offZ,\n });\n }\n\n async loadDataAtGhostBrick(\n saveData: WriteSaveObject,\n { rotate = true, offX = 0, offY = 0, offZ = 0, quiet = true } = {},\n ) {\n const ghostBrickData = await this.getGhostBrick();\n\n if (!ghostBrickData || !saveData) return;\n\n // get bounds of the bricks\n const bounds = brickUtils.getBounds(saveData);\n\n if (rotate) {\n const orientation =\n brickUtils.BRICK_CONSTANTS.orientationMap[ghostBrickData.orientation];\n saveData.bricks = saveData.bricks.map(brick =>\n brickUtils.rotate(brick, orientation),\n );\n // rotate bounds, if we dont use the original bounds they are off by 1 sometimes >:(\n bounds.minBound = brickUtils.BRICK_CONSTANTS.translationTable[\n brickUtils.d2o(...orientation)\n ](bounds.minBound);\n bounds.maxBound = brickUtils.BRICK_CONSTANTS.translationTable[\n brickUtils.d2o(...orientation)\n ](bounds.maxBound);\n bounds.center = brickUtils.BRICK_CONSTANTS.translationTable[\n brickUtils.d2o(...orientation)\n ](bounds.center);\n }\n\n // calculate offset from bricks center to ghost brick center\n const offset = bounds.center.map(\n (center, index) => ghostBrickData.location[index] - center,\n );\n\n // load at offset location\n await this.#omegga.loadSaveData(saveData, {\n offX: offX + offset[0],\n offY: offY + offset[1],\n offZ: offZ + offset[2],\n quiet,\n });\n }\n\n kill() {\n Player.kill(this.#omegga, this);\n }\n\n damage(amount: number): void {\n Player.damage(this.#omegga, this, amount);\n }\n\n heal(amount: number): void {\n Player.heal(this.#omegga, this, amount);\n }\n\n giveItem(item: WeaponClass): void {\n Player.giveItem(this.#omegga, this, item);\n }\n\n takeItem(item: WeaponClass): void {\n Player.takeItem(this.#omegga, this, item);\n }\n\n setTeam(teamIndex: number): void {\n Player.setTeam(this.#omegga, this, teamIndex);\n }\n\n setMinigame(index: number): void {\n Player.setMinigame(this.#omegga, this, index);\n }\n\n setScore(minigameIndex: number, score: number): void {\n Player.setScore(this.#omegga, this, minigameIndex, score);\n }\n\n getScore(minigameIndex: number): Promise<number> {\n return Player.getScore(this.#omegga, this, minigameIndex);\n }\n}\n\nglobal.Player = Player;\n\nexport default Player;\n"],"names":["index","match","color","owner","transformParameters","brickUtils","selectors","minBound","maxBound","center"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"player.js","sources":["../../src/omegga/player.ts"],"sourcesContent":["import type { OmeggaLike, OmeggaPlayer, WeaponClass } from '@/plugin';\nimport { IBrickBounds } from '@util/brick';\nimport { WriteSaveObject } from 'brs-js';\nimport { brick as brickUtils, color } from '../util/';\n\nconst DEFAULT_PERMS: Record<string, string[]> = {\n moderator: [\n 'Bricks.ClearAll',\n 'Minigame.AlwaysLeave',\n 'Players.Kick',\n 'Players.TPInMinigame',\n 'Players.TPOthers',\n 'Self.Ghost',\n ],\n admin: [\n 'Bricks.ClearAll',\n 'Bricks.ClearOwn',\n 'Bricks.IgnoreTrust',\n 'Bricks.Load',\n 'Map.Environment',\n 'Minigame.AlwaysEdit',\n 'Minigame.AlwaysLeave',\n 'Minigame.AlwaysSwitchTeam',\n 'Minigame.MakeDefault',\n 'Minigame.MakePersistent',\n 'Minigame.UseAllBricks',\n 'Players.Ban',\n 'Players.Kick',\n 'Players.TPInMinigame',\n 'Players.TPOthers',\n 'Roles.Grant',\n 'Self.Ghost',\n 'Server.ChangeRoles',\n 'Server.ChangeSettings',\n 'Server.FreezeCamera',\n 'Tools.Selector.BypassLimits',\n 'Tools.Selector.BypassTimeouts',\n ],\n};\n\nclass Player implements OmeggaPlayer {\n #omegga: OmeggaLike;\n name: string;\n displayName: string;\n id: string;\n controller: string;\n state: string;\n\n static getRoles(omegga: OmeggaLike, id: string): readonly string[] {\n const data = omegga.getRoleAssignments().savedPlayerRoles[id];\n return Object.freeze(data && data.roles ? data.roles : []);\n }\n\n static getPermissions(\n omegga: OmeggaLike,\n id: string,\n ): Record<string, boolean> {\n const { roles, defaultRole } = omegga.getRoleSetup();\n\n // if the player is the host, the player has every permission\n if (omegga.host.id === id) {\n return Object.freeze(\n Object.fromEntries(\n [].concat(\n defaultRole.permissions.map(p => [p.name, true]),\n // sometimes the default role does not have every permission listed\n ...roles.map(r => r.permissions.map(p => [p.name, true])),\n ),\n ),\n );\n }\n\n // get the player's roles\n const playerRoles = Player.getRoles(omegga, id).map(r => r.toLowerCase());\n\n // default player permissions\n const permissions: Record<string, boolean> = {\n 'Bricks.ClearAll': false,\n 'Bricks.ClearOwn': true,\n 'Bricks.Delete': true,\n 'Bricks.Edit': true,\n 'Bricks.IgnoreTrust': false,\n 'Bricks.Paint': true,\n 'Bricks.Place': true,\n 'BricksItems.Spawn': true,\n 'Map.Change': false,\n 'Map.Environment': false,\n 'Map.SetSpawn': false,\n 'Minigame.AlwaysEdit': false,\n 'Minigame.AlwaysLeave': false,\n 'Minigame.AlwaysSwitchTeam': false,\n 'Minigame.Create': true,\n 'Minigame.MakePersistent': false,\n 'Minigame.UseAllBricks': false,\n 'Players.Ban': false,\n 'Players.TPInMinigame': false,\n 'Players.TPOthers': false,\n 'Players.TPSelf': true,\n 'Roles.Grant': false,\n 'Self.Flashlight': true,\n 'Self.Fly': true,\n 'Self.FreezeCamera': false,\n 'Self.Ghost': false,\n 'Self.Sprint': true,\n 'Self.Suicide': true,\n 'Tools.Selector.Use': true,\n };\n\n // apply all permissions from default role\n for (const p of defaultRole.permissions) {\n // technically this can never be Unchanged so it's always on enabled or allowed\n permissions[p.name] =\n p.state === 'Unchanged' ? permissions[p.name] : p.state === 'Allowed';\n }\n\n // loop through all the roles\n for (const role of roles) {\n // ignore ones the player does not have\n if (!playerRoles.includes(role.name.toLowerCase())) continue;\n\n const defaultPerms = DEFAULT_PERMS[role.name.toLowerCase()] || [];\n // iterate through default permissions\n for (const perm of defaultPerms) {\n // if they are not overriden, set it to true\n if (!role.permissions.find(r => r.name === perm))\n permissions[perm] = true;\n }\n\n // add all the new permissions the player now has\n for (const p of role.permissions) {\n // permission is disabled on forbidden, persisted on unchanged, and enabled on bEnabled or Allowed\n permissions[p.name] =\n p.state !== 'Forbidden' &&\n (p.state === 'Unchanged'\n ? permissions[p.name]\n : permissions[p.name] || p.state === 'Allowed');\n permissions[p.name] = permissions[p.name];\n }\n }\n\n return Object.freeze(permissions);\n }\n\n static kill(omegga: OmeggaLike, target: string | OmeggaPlayer) {\n if (typeof target === 'string') target = omegga.getPlayer(target);\n if (target?.name) omegga.writeln(`Server.Players.Kill \"${target?.name}\"`);\n }\n\n static damage(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n amount: number,\n ) {\n if (typeof target === 'string') target = omegga.getPlayer(target);\n if (amount === 0) return;\n if (target?.name)\n omegga.writeln(`Server.Players.Damage \"${target?.name}\" ${amount}`);\n }\n\n static heal(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n amount: number,\n ) {\n if (amount === 0) return;\n Player.damage(omegga, target, -amount);\n }\n\n static giveItem(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n item: WeaponClass,\n ) {\n if (typeof target === 'string') target = omegga.getPlayer(target);\n if (!item) return;\n if (target?.name)\n omegga.writeln(`Server.Players.GiveItem \"${target?.name}\" ${item}`);\n }\n\n static takeItem(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n item: WeaponClass,\n ) {\n if (typeof target === 'string') target = omegga.getPlayer(target);\n if (!item) return;\n if (target?.name)\n omegga.writeln(`Server.Players.RemoveItem \"${target?.name}\" ${item}`);\n }\n\n static setTeam(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n teamIndex: number,\n ) {\n if (typeof target === 'string') target = omegga.getPlayer(target);\n if (target?.name)\n omegga.writeln(`Server.Players.SetTeam \"${target?.name}\" ${teamIndex}`);\n }\n\n static setMinigame(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n index: number,\n ) {\n if (typeof target === 'string') target = omegga.getPlayer(target);\n if (target?.name)\n omegga.writeln(`Server.Players.SetMinigame \"${target?.name}\" ${index}`);\n }\n\n static setScore(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n minigameIndex: number,\n score: number,\n ) {\n if (typeof target === 'string') target = omegga.getPlayer(target);\n if (target?.name)\n omegga.writeln(\n `Server.Players.SetLeaderboardValue \"${target?.name}\" ${minigameIndex} ${score}`,\n );\n }\n\n static async getScore(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n minigameIndex: number,\n ): Promise<number> {\n if (typeof target === 'string') target = omegga.getPlayer(target);\n if (!target?.name) return 0;\n\n const name = target?.name;\n const id = target?.id;\n\n const match = await omegga.addWatcher(\n (line, match) => {\n if (match?.groups.generator !== 'LogConsoleCommands') return;\n\n const test = match.groups.data.match(\n /^(?<uuid>.+) leaderboard value (?<minigame>\\d+) = (?<score>-?\\d+)$/,\n );\n if (!test) return;\n if (test.groups.uuid !== id) return;\n if (Number(test.groups.minigame) !== minigameIndex) return;\n return test;\n },\n {\n timeoutDelay: 1000,\n exec: () =>\n omegga.writeln(\n `Server.Players.PrintLeaderboardValue \"${name}\" ${minigameIndex}`,\n ),\n },\n );\n if (match) return Number(match[0].groups.score);\n }\n\n static setLeaderboard(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n key: string,\n value: number,\n ): void {\n if (typeof target === 'string') target = omegga.getPlayer(target);\n if (!target?.name) return null;\n\n omegga.writeln(\n `Server.Players.SetLeaderboardValue \"${target.name}\" \"${key}\" \"${value}\"`,\n );\n }\n\n static async getLeaderboard(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n key: string,\n ): Promise<number | null> {\n if (typeof target === 'string') target = omegga.getPlayer(target);\n if (!target?.name) return null;\n\n // LogConsoleCommands: <uuid> leaderboard value Key = 0\n const match = await omegga\n .addWatcher<RegExpMatchArray>(\n (line, match) => {\n if (match?.groups.generator !== 'LogConsoleCommands') return;\n\n const test = match.groups.data.match(\n /^(?<uuid>.+) leaderboard value (?<key>.+) = (?<value>-?\\d+)$/,\n );\n if (!test) return;\n if (test.groups.uuid !== target.id) return;\n if (test.groups.key !== key) return;\n return test;\n },\n {\n timeoutDelay: 1000,\n exec: () =>\n omegga.writeln(\n `Server.Players.PrintLeaderboardValue \"${target.name}\" \"${key}\"`,\n ),\n },\n )\n .catch(() => null);\n if (match) return Number(match[0].groups.value);\n return null;\n }\n\n /**\n * players are not to be constructed\n * @constructor\n * @param omegga Omegga Instance\n * @param name Player Name\n * @param displayName Player Display Name\n * @param id Player Id\n * @param controller Player Controller\n * @param state Player State\n */\n constructor(\n omegga: OmeggaLike,\n username: string,\n displayName: string,\n id: string,\n controller: string,\n state: string,\n ) {\n this.#omegga = omegga;\n this.name = username;\n this.displayName = displayName;\n this.id = id;\n this.controller = controller;\n this.state = state;\n }\n\n getOmegga(): OmeggaLike {\n return this.#omegga;\n }\n\n clone(): OmeggaPlayer {\n return new Player(\n this.#omegga,\n this.name,\n this.displayName,\n this.id,\n this.controller,\n this.state,\n );\n }\n\n raw(): [string, string, string, string, string] {\n return [this.name, this.displayName, this.id, this.controller, this.state];\n }\n\n isHost(): boolean {\n return this.#omegga.host.id === this.id;\n }\n\n clearBricks(quiet = false) {\n this.#omegga.clearBricks(this.id, quiet);\n }\n\n getRoles(): readonly string[] {\n return Player.getRoles(this.#omegga, this.id);\n }\n\n getPermissions(): Record<string, boolean> {\n return Player.getPermissions(this.#omegga, this.id);\n }\n\n getNameColor(): string {\n const { roles, defaultRole, ownerRoleColor, bOwnerRoleHasColor } =\n this.#omegga.getRoleSetup();\n\n // host check if host has host color\n if (this.isHost() && bOwnerRoleHasColor)\n return color.rgbToHex(ownerRoleColor);\n\n // get the player's role\n const playerRoles = this.getRoles().map(r => r.toLowerCase());\n\n // only if the player actually has roles...\n if (playerRoles.length > 0) {\n // check the role list in reverse for the player's role (highest tier first)\n const found = roles\n .slice()\n .reverse()\n .find(\n role =>\n role.bHasColor && playerRoles.includes(role.name.toLowerCase()),\n );\n\n if (found) return color.rgbToHex(found.color);\n }\n\n return color.rgbToHex(\n defaultRole.bHasColor\n ? defaultRole.color\n : { r: 255, g: 255, b: 255, a: 255 },\n );\n }\n\n async getPawn(): Promise<string | null> {\n // given a player controller, match the player's pawn\n const pawnRegExp = new RegExp(\n `^(?<index>\\\\d+)\\\\) BP_PlayerController_C .+?PersistentLevel\\\\.${this.controller}\\\\.Pawn = .*?(?:BP_FigureV2_C'.+:PersistentLevel\\\\.)?(?<pawn>BP_FigureV2_C_\\\\d+|None)'?`,\n );\n\n // wait for the pawn watcher to return a pawn\n const [{ groups: { pawn = null } = {} } = {}] =\n await this.#omegga.watchLogChunk<RegExpMatchArray>(\n 'GetAll BP_PlayerController_C Pawn Name=' + this.controller,\n pawnRegExp,\n { first: 'index', timeoutDelay: 500 },\n );\n\n if (pawn === 'None') return null;\n\n return pawn;\n }\n\n async getPosition(): Promise<[number, number, number] | null> {\n // this is here because my text editor had weird syntax highlighting glitches when the other omeggas were replaced with this.#omegga...\n // guess the code is \"too new\" :egg:\n const omegga = this.#omegga;\n\n // given a player controller, match the player's pawn\n const pawnRegExp = new RegExp(\n `^(?<index>\\\\d+)\\\\) BP_PlayerController_C .+?PersistentLevel\\\\.${this.controller}\\\\.Pawn = .*?(?:BP_FigureV2_C'.+:PersistentLevel\\\\.)?(?<pawn>BP_FigureV2_C_\\\\d+|None)'?`,\n );\n\n // wait for the pawn watcher to return a pawn\n const [\n {\n groups: { pawn },\n },\n ] = await omegga.watchLogChunk<RegExpMatchArray>(\n 'GetAll BP_PlayerController_C Pawn Name=' + this.controller,\n pawnRegExp,\n { first: 'index', timeoutDelay: 100 },\n );\n\n if (pawn === 'None') return null;\n\n // given a player's pawn, match the player's position\n const posRegExp = new RegExp(\n `CapsuleComponent .+?PersistentLevel\\\\.${pawn}\\\\.CollisionCylinder\\\\.RelativeLocation = \\\\(X=(?<x>[\\\\d\\\\.-]+),Y=(?<y>[\\\\d\\\\.-]+),Z=(?<z>[\\\\d\\\\.-]+)\\\\)`,\n );\n\n // wait for the position promise\n const [\n {\n groups: { x, y, z },\n },\n ] = await omegga.addWatcher(posRegExp, {\n // request the position for this player's pawn\n exec: () =>\n omegga.writeln(\n `GetAll SceneComponent RelativeLocation Name=CollisionCylinder Outer=${pawn}`,\n ),\n timeoutDelay: 100,\n });\n\n // return the player's position as an array of numbers\n return [Number(x), Number(y), Number(z)];\n }\n\n async getGhostBrick(): Promise<{\n targetGrid: string;\n location: number[];\n orientation: string;\n }> {\n const { controller } = this;\n\n const previewClass = 'BP_ToolPreviewActor_C';\n\n const ownerRegExp = new RegExp(\n `^(?<index>\\\\d+)\\\\) ${previewClass} (.+):PersistentLevel\\\\.(?<actor>${previewClass}_\\\\d+)\\.Owner = .*?BP_PlayerController_C'(.+):PersistentLevel\\\\.(?<controller>BP_PlayerController_C_\\\\d+)'$`,\n );\n const transformParamsRegExp = new RegExp(\n `^(?<index>\\\\d+)\\\\) ${previewClass} (.+):PersistentLevel\\\\.(?<actor>${previewClass}_\\\\d+)\\\\.TransformParameters = \\\\(TargetGrid=(\"(?<targetGrid>.+)\"|None),Location=\\\\(X=(?<x>.+),Y=(?<y>.+),Z=(?<z>.+)\\\\),Orientation=(?<orientation>.+)\\\\)$`,\n );\n\n const [owners, transformParams] = await Promise.all([\n this.#omegga.watchLogChunk<RegExpMatchArray>(\n `GetAll ${previewClass} Owner`,\n ownerRegExp,\n {\n first: 'index',\n timeoutDelay: 2000,\n afterMatchDelay: 100,\n },\n ),\n this.#omegga.watchLogChunk<RegExpMatchArray>(\n `GetAll ${previewClass} TransformParameters`,\n transformParamsRegExp,\n {\n first: 'index',\n timeoutDelay: 2000,\n afterMatchDelay: 100,\n },\n ),\n ]);\n\n // get BrickGridPreviewActor by controller\n const owner = owners.find(owner => owner.groups.controller === controller);\n\n if (!owner) return;\n\n const actor = owner.groups.actor;\n // get transform parameters for the found actor\n const transformParameters = transformParams.find(\n transformParameters => transformParameters.groups.actor === actor,\n );\n\n if (!transformParameters) return;\n\n return {\n targetGrid: transformParameters.groups.targetGrid,\n location: [\n +transformParameters.groups.x,\n +transformParameters.groups.y,\n +transformParameters.groups.z,\n ],\n orientation: transformParameters.groups.orientation,\n };\n }\n\n async getPaint(): Promise<{\n materialIndex: string;\n materialAlpha: string;\n material: string;\n color: number[];\n }> {\n const { controller } = this;\n\n const match = await this.#omegga\n .addWatcher<{\n materialIndex: string;\n materialAlpha: string;\n material: string;\n color: number[];\n }>(\n line => {\n // [date][counter]0) BP_PlayerState_C /Game/Maps/Plate/Plate.Plate:PersistentLevel.BP_PlayerState_C_2147482378.ColorSelectionState = (SelectedColor=(B=6,G=73,R=246,A=255),MaterialIndex=3,MaterialAlpha=5)\n const match = line.match(\n /^\\[[^\\]]+\\]\\[[^\\]]+\\]\\d+\\) BP_PlayerState_C .+?PersistentLevel\\.(?<state>BP_PlayerState_C_\\d+)\\.ColorSelectionState = \\(SelectedColor=\\(B=(?<b>\\d+),G=(?<g>\\d+),R=(?<r>\\d+),A=(?<a>\\d+)\\),MaterialIndex=(?<materialIndex>\\d+),MaterialAlpha=(?<materialAlpha>\\d+)\\)$/,\n );\n if (!match) return;\n if (match.groups.state !== this.state) return;\n const colorRaw = [+match.groups.r, +match.groups.g, +match.groups.b];\n return {\n materialIndex: match.groups.materialIndex,\n materialAlpha: match.groups.materialAlpha,\n material:\n brickUtils.BRICK_CONSTANTS.DEFAULT_MATERIALS[\n Number(match.groups.materialIndex)\n ],\n color: colorRaw,\n };\n },\n {\n timeoutDelay: 1000,\n exec: () =>\n this.#omegga.writeln('GetAll BRPlayerState ColorSelectionState'),\n },\n )\n .catch(() => null);\n if (!match?.[0]) return;\n return match[0];\n }\n\n async isCrouched(pawn?: string): Promise<boolean> {\n if (!pawn) pawn = await this.getPawn();\n\n const reg =\n /(?<index>\\d+)\\) BP_FigureV2_C .+?PersistentLevel\\.(?<pawn>BP_FigureV2_C_\\d+)\\.bIsCrouched = (?<crouched>True|False)$/;\n\n const resp = await this.#omegga.watchLogChunk<RegExpMatchArray>(\n 'GetAll BP_FigureV2_C bIsCrouched Name=' + pawn,\n reg,\n { first: 'index', timeoutDelay: 500 },\n );\n\n const me = resp.find(r => r.groups.pawn === pawn);\n if (!me) return false;\n\n return me.groups.crouched == 'True';\n }\n\n async isDead(pawn?: string): Promise<boolean> {\n if (!pawn) pawn = await this.getPawn();\n\n const reg =\n /(?<index>\\d+)\\) BP_FigureV2_C .+?PersistentLevel\\.(?<pawn>BP_FigureV2_C_\\d+)\\.bIsDead = (?<dead>True|False)$/;\n\n const resp = await this.#omegga.watchLogChunk<RegExpMatchArray>(\n 'GetAll BP_FigureV2_C bIsDead Name=' + pawn,\n reg,\n { first: 'index', timeoutDelay: 500 },\n );\n\n const me = resp.find(r => r.groups.pawn === pawn);\n if (!me) return true;\n\n return me.groups.dead == 'True';\n }\n\n async getTemplateBounds() {\n const { controller } = this;\n\n const brickTemplateRegExp =\n /^(?<index>\\d+)\\) Tool_Selector_C (.+):PersistentLevel\\.(?<tool>Tool_Selector_C_\\d+)\\.CurrentTemplate = (.+)Brickadia.BrickBuildingTemplate'(.+)Transient.(?<templateName>BrickBuildingTemplate_\\d+)'$/;\n const brickTemplateOwnerRegExp =\n /^(?<index>\\d+)\\) Tool_Selector_C (.+):PersistentLevel\\.(?<tool>Tool_Selector_C_\\d+)\\.Owner = (.+)(?<controller>BP_PlayerController_C_\\d+)'$/;\n const minBoundsRegExp =\n /^(?<index>\\d+)\\) BrickBuildingTemplate (.+)Transient\\.(?<templateName>BrickBuildingTemplate_\\d+)\\.MinBounds = \\(X=(?<x>.+),Y=(?<y>.+),Z=(?<z>.+)\\)$/;\n const maxBoundsRegExp =\n /^(?<index>\\d+)\\) BrickBuildingTemplate (.+)Transient\\.(?<templateName>BrickBuildingTemplate_\\d+)\\.MaxBounds = \\(X=(?<x>.+),Y=(?<y>.+),Z=(?<z>.+)\\)$/;\n const centerRegExp =\n /^(?<index>\\d+)\\) BrickBuildingTemplate (.+)Transient\\.(?<templateName>BrickBuildingTemplate_\\d+)\\.Center = \\(X=(?<x>.+),Y=(?<y>.+),Z=(?<z>.+)\\)$/;\n\n const [templates, owners, minBounds, maxBounds, centers] =\n await Promise.all([\n this.#omegga.watchLogChunk<RegExpMatchArray>(\n 'GetAll Tool_Selector_C CurrentTemplate',\n brickTemplateRegExp,\n {\n first: 'index',\n timeoutDelay: 2000,\n afterMatchDelay: 100,\n },\n ),\n this.#omegga.watchLogChunk<RegExpMatchArray>(\n 'GetAll Tool_Selector_C Owner',\n brickTemplateOwnerRegExp,\n {\n first: 'index',\n timeoutDelay: 2000,\n afterMatchDelay: 100,\n },\n ),\n this.#omegga.watchLogChunk<RegExpMatchArray>(\n 'GetAll BrickBuildingTemplate MinBounds',\n minBoundsRegExp,\n {\n first: 'index',\n timeoutDelay: 2000,\n afterMatchDelay: 100,\n },\n ),\n this.#omegga.watchLogChunk<RegExpMatchArray>(\n 'GetAll BrickBuildingTemplate MaxBounds',\n maxBoundsRegExp,\n {\n first: 'index',\n timeoutDelay: 2000,\n afterMatchDelay: 100,\n },\n ),\n this.#omegga.watchLogChunk<RegExpMatchArray>(\n 'GetAll BrickBuildingTemplate Center',\n centerRegExp,\n {\n first: 'index',\n timeoutDelay: 2000,\n afterMatchDelay: 100,\n },\n ),\n ]);\n\n if (\n !templates.length ||\n !owners.length ||\n !minBounds.length ||\n !maxBounds.length ||\n !centers.length\n )\n return;\n\n // get selector for this controller, we need to handle if there are multiple selectors for the same controller\n const selectors = owners\n .filter(selectors => selectors.groups.controller === controller)\n .map(selectors => selectors.groups.tool)\n .sort();\n const selector = selectors[0]; // grab the most recently created\n\n if (!selector) {\n return;\n }\n\n // template for this selector, we need to handle if there are multiple templates for the same selector and grab the most recent one\n const brickTemplates = templates\n .filter(template => template.groups.tool === selector)\n .map(template => template.groups.templateName)\n .sort();\n const templateName = brickTemplates[0]; // grab the most recently created\n\n if (!templateName) {\n return;\n }\n\n // find all values with matching template name\n const minBound = minBounds.find(\n minBound => minBound.groups.templateName === templateName,\n );\n const maxBound = maxBounds.find(\n maxBound => maxBound.groups.templateName === templateName,\n );\n const center = centers.find(\n center => center.groups.templateName === templateName,\n );\n\n if (!minBound || !maxBound || !center) return;\n\n return {\n minBound: [+minBound.groups.x, +minBound.groups.y, +minBound.groups.z],\n maxBound: [+maxBound.groups.x, +maxBound.groups.y, +maxBound.groups.z],\n center: [+center.groups.x, +center.groups.y, +center.groups.z],\n } as IBrickBounds;\n }\n\n async getTemplateBoundsData() {\n const templateBounds = await this.getTemplateBounds();\n\n if (!templateBounds) return;\n\n const saveData = await this.#omegga.getSaveData({\n center: templateBounds.center,\n extent: [\n Math.round(\n (templateBounds.maxBound[0] - templateBounds.minBound[0]) / 2,\n ),\n Math.round(\n (templateBounds.maxBound[1] - templateBounds.minBound[1]) / 2,\n ),\n Math.round(\n (templateBounds.maxBound[2] - templateBounds.minBound[2]) / 2,\n ),\n ],\n });\n\n if (!saveData) return;\n\n // filter bricks outside the bounds\n // no longer necessary thanks to Bricks.SaveRegion\n /* saveData.bricks = (saveData.bricks as Brick[]).filter(brick => {\n return brickUtils.checkBounds(\n brick,\n saveData.brick_assets,\n templateBounds\n );\n }) as typeof saveData.bricks; */\n\n if (saveData.bricks.length > 0) {\n return saveData;\n }\n\n return undefined;\n }\n\n loadBricks(saveName: string) {\n this.#omegga.loadBricksOnPlayer(saveName, this);\n }\n\n async loadSaveData(\n saveData: WriteSaveObject,\n { offX = 0, offY = 0, offZ = 0 } = {},\n ) {\n await this.#omegga.loadSaveDataOnPlayer(saveData, this, {\n offX,\n offY,\n offZ,\n });\n }\n\n async loadDataAtGhostBrick(\n saveData: WriteSaveObject,\n { rotate = true, offX = 0, offY = 0, offZ = 0, quiet = true } = {},\n ) {\n const ghostBrickData = await this.getGhostBrick();\n\n if (!ghostBrickData || !saveData) return;\n\n // get bounds of the bricks\n const bounds = brickUtils.getBounds(saveData);\n\n if (rotate) {\n const orientation =\n brickUtils.BRICK_CONSTANTS.orientationMap[ghostBrickData.orientation];\n saveData.bricks = saveData.bricks.map(brick =>\n brickUtils.rotate(brick, orientation),\n );\n // rotate bounds, if we dont use the original bounds they are off by 1 sometimes >:(\n bounds.minBound = brickUtils.BRICK_CONSTANTS.translationTable[\n brickUtils.d2o(...orientation)\n ](bounds.minBound);\n bounds.maxBound = brickUtils.BRICK_CONSTANTS.translationTable[\n brickUtils.d2o(...orientation)\n ](bounds.maxBound);\n bounds.center = brickUtils.BRICK_CONSTANTS.translationTable[\n brickUtils.d2o(...orientation)\n ](bounds.center);\n }\n\n // calculate offset from bricks center to ghost brick center\n const offset = bounds.center.map(\n (center, index) => ghostBrickData.location[index] - center,\n );\n\n // load at offset location\n await this.#omegga.loadSaveData(saveData, {\n offX: offX + offset[0],\n offY: offY + offset[1],\n offZ: offZ + offset[2],\n quiet,\n });\n }\n\n kill() {\n Player.kill(this.#omegga, this);\n }\n\n damage(amount: number): void {\n Player.damage(this.#omegga, this, amount);\n }\n\n heal(amount: number): void {\n Player.heal(this.#omegga, this, amount);\n }\n\n giveItem(item: WeaponClass): void {\n Player.giveItem(this.#omegga, this, item);\n }\n\n takeItem(item: WeaponClass): void {\n Player.takeItem(this.#omegga, this, item);\n }\n\n setTeam(teamIndex: number): void {\n Player.setTeam(this.#omegga, this, teamIndex);\n }\n\n setMinigame(index: number): void {\n Player.setMinigame(this.#omegga, this, index);\n }\n\n setScore(minigameIndex: number, score: number): void {\n Player.setScore(this.#omegga, this, minigameIndex, score);\n }\n\n getScore(minigameIndex: number): Promise<number> {\n return Player.getScore(this.#omegga, this, minigameIndex);\n }\n\n setLeaderboard(key: string, value: number): void {\n Player.setLeaderboard(this.#omegga, this, key, value);\n }\n\n async getLeaderboard(key: string): Promise<number | null> {\n return Player.getLeaderboard(this.#omegga, this, key);\n }\n}\n\nglobal.Player = Player;\n\nexport default Player;\n"],"names":["index","match","color","owner","transformParameters","brickUtils","selectors","minBound","maxBound","center"],"mappings":"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"}
|
|
@@ -468,10 +468,16 @@ class RpcPlugin extends _interface.Plugin {
|
|
|
468
468
|
addPlayerMethod("getPermissions");
|
|
469
469
|
addPlayerMethod("getNameColor");
|
|
470
470
|
addPlayerMethod("getPosition");
|
|
471
|
+
addPlayerMethod("getPawn");
|
|
471
472
|
addPlayerMethod("getGhostBrick");
|
|
472
473
|
addPlayerMethod("getPaint");
|
|
474
|
+
addPlayerMethod("isCrouched");
|
|
475
|
+
addPlayerMethod("isDead");
|
|
473
476
|
addPlayerMethod("getTemplateBounds");
|
|
474
477
|
addPlayerMethod("getTemplateBoundsData");
|
|
478
|
+
addPlayerMethod("kill");
|
|
479
|
+
addPlayerMethod("getScore");
|
|
480
|
+
addPlayerMethod("getLeaderboard");
|
|
475
481
|
rpc.addMethod(
|
|
476
482
|
"player.loadDataAtGhostBrick",
|
|
477
483
|
({
|
|
@@ -494,6 +500,54 @@ class RpcPlugin extends _interface.Plugin {
|
|
|
494
500
|
offZ = 0
|
|
495
501
|
}) => this.omegga.getPlayer(target)?.loadSaveData(data, { offX, offY, offZ })
|
|
496
502
|
);
|
|
503
|
+
rpc.addMethod(
|
|
504
|
+
"player.clearBricks",
|
|
505
|
+
({ target, quiet = false }) => this.omegga.getPlayer(target)?.clearBricks(quiet)
|
|
506
|
+
);
|
|
507
|
+
rpc.addMethod(
|
|
508
|
+
"player.loadBricks",
|
|
509
|
+
({ target, saveName }) => this.omegga.getPlayer(target)?.loadBricks(saveName)
|
|
510
|
+
);
|
|
511
|
+
rpc.addMethod(
|
|
512
|
+
"player.damage",
|
|
513
|
+
({ target, amount }) => this.omegga.getPlayer(target)?.damage(amount)
|
|
514
|
+
);
|
|
515
|
+
rpc.addMethod(
|
|
516
|
+
"player.heal",
|
|
517
|
+
({ target, amount }) => this.omegga.getPlayer(target)?.heal(amount)
|
|
518
|
+
);
|
|
519
|
+
rpc.addMethod(
|
|
520
|
+
"player.giveItem",
|
|
521
|
+
({ target, item }) => this.omegga.getPlayer(target)?.giveItem(item)
|
|
522
|
+
);
|
|
523
|
+
rpc.addMethod(
|
|
524
|
+
"player.takeItem",
|
|
525
|
+
({ target, item }) => this.omegga.getPlayer(target)?.takeItem(item)
|
|
526
|
+
);
|
|
527
|
+
rpc.addMethod(
|
|
528
|
+
"player.setTeam",
|
|
529
|
+
({ target, teamIndex }) => this.omegga.getPlayer(target)?.setTeam(teamIndex)
|
|
530
|
+
);
|
|
531
|
+
rpc.addMethod(
|
|
532
|
+
"player.setMinigame",
|
|
533
|
+
({ target, index }) => this.omegga.getPlayer(target)?.setMinigame(index)
|
|
534
|
+
);
|
|
535
|
+
rpc.addMethod(
|
|
536
|
+
"player.setScore",
|
|
537
|
+
({
|
|
538
|
+
target,
|
|
539
|
+
minigameIndex,
|
|
540
|
+
score
|
|
541
|
+
}) => this.omegga.getPlayer(target)?.setScore(minigameIndex, score)
|
|
542
|
+
);
|
|
543
|
+
rpc.addMethod(
|
|
544
|
+
"player.setLeaderboard",
|
|
545
|
+
({
|
|
546
|
+
target,
|
|
547
|
+
key,
|
|
548
|
+
value
|
|
549
|
+
}) => this.omegga.getPlayer(target)?.setLeaderboard(key, value)
|
|
550
|
+
);
|
|
497
551
|
rpc.addMethod("plugin.get", async (name2) => {
|
|
498
552
|
const plugin = this.omegga.pluginLoader.plugins.find(
|
|
499
553
|
(p) => p.getName() === name2
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin_jsonrpc_stdio.js","sources":["../../../src/omegga/plugin/plugin_jsonrpc_stdio.ts"],"sourcesContent":["import Logger from '@/logger';\nimport { EnvironmentPreset } from '@brickadia/presets';\nimport Omegga from '@omegga/server';\nimport { WriteSaveObject } from 'brs-js';\nimport {\n JSONRPCClient,\n JSONRPCServer,\n JSONRPCServerAndClient,\n} from 'json-rpc-2.0';\nimport { ChildProcessWithoutNullStreams, spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport readline from 'readline';\nimport { Plugin } from './interface';\nimport { bootstrap } from './plugin_node_safe/proxyOmegga';\n\n// TODO: check if version is compatible (v1 -> v2) from file\n// TODO: write jsonrpc wrappers in a few languages, implement a few simple plugins\n// TODO: languages: [ python, go ]\n\nconst MAIN_FILE = 'omegga_plugin';\nconst DOC_FILE = 'doc.json';\nconst PLUGIN_FILE = 'plugin.json';\n\nexport default class RpcPlugin extends Plugin {\n #child: ChildProcessWithoutNullStreams;\n #rpc: JSONRPCServerAndClient;\n #errInterface: readline.Interface;\n #outInterface: readline.Interface;\n\n messageCounter: number;\n\n // all RPC plugins require a main (binary) file and a doc file\n static canLoad(pluginPath: string) {\n return (\n fs.existsSync(path.join(pluginPath, MAIN_FILE)) &&\n fs.existsSync(path.join(pluginPath, DOC_FILE))\n );\n }\n\n // websocket rpc plugin type\n static getFormat() {\n return 'jsonrpc_stdio';\n }\n\n // documentation is based on doc.json file\n getDocumentation() {\n return this.documentation;\n }\n constructor(pluginPath: string, omegga: Omegga) {\n super(pluginPath, omegga);\n\n this.messageCounter = 0;\n\n // TODO: validate documentation\n this.documentation = Plugin.readJSON(path.join(pluginPath, DOC_FILE));\n this.pluginConfig = Plugin.readJSON(path.join(pluginPath, PLUGIN_FILE));\n this.pluginFile = path.join(pluginPath, MAIN_FILE);\n\n this.eventPassthrough = this.eventPassthrough.bind(this);\n this.commands = [];\n\n this.initRPC();\n }\n\n isLoaded() {\n return !!this.#child && !this.#child.exitCode;\n }\n\n // determing if a command is registered\n isCommand(cmd: string) {\n return this.commands.includes(cmd);\n }\n\n // spawn the plugin as a child process\n async load() {\n const name = this.getName();\n const verbose = (...msg: any[]) => Logger.verbose(name.underline, ...msg);\n verbose('Load method invoked');\n let frozen = true,\n timed = false;\n this.commands = [];\n\n // can't load the plugin if the child is still running\n if (this.#child) {\n verbose('Plugin already has child process');\n return false;\n }\n\n let config;\n try {\n verbose('Getting plugin config');\n config = await this.storage.getConfig();\n } catch (e) {\n return false;\n }\n\n try {\n if (this.pluginConfig?.emitConfig) {\n verbose('Emitting plugin config');\n await fs.promises.writeFile(\n path.join(this.path, this.pluginConfig.emitConfig),\n JSON.stringify(config),\n );\n }\n verbose('Spawning child process');\n this.#child = spawn(this.pluginFile);\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 } catch (err) {\n Logger.errorp(\n 'error loading stdio rpc plugin',\n name.brightRed.underline,\n err,\n );\n await this.kill();\n this.emitStatus();\n return false;\n }\n\n return Promise.race([\n (async () => {\n try {\n // get some initial information to create an omegga proxy\n const initialData = bootstrap(this.omegga);\n\n verbose('Sending initial data');\n // send all of the mock events to the proxy omegga\n for (const ev in initialData) {\n // send some initial information\n this.notify(ev, initialData[ev]);\n }\n\n verbose('Initializing event passthrough');\n // pass events through\n this.omegga.on('*', this.eventPassthrough);\n\n try {\n // tell the plugin to start\n verbose('Waiting for plugin to start...');\n const result = await this.emit('init', config);\n\n verbose('Initialized with result:', result);\n // plugins can return a result object\n if (typeof result === 'object' && result) {\n // if registeredCommands is in the results, register the provided strings as commands\n const cmds = result.registeredCommands;\n if (\n cmds &&\n cmds instanceof Array &&\n cmds.every(i => typeof i === 'string')\n )\n this.commands = cmds;\n }\n } catch (e) {\n if (!e.message) return;\n Logger.errorp(name.brightRed.underline, 'error starting: ', e);\n }\n\n // plugin is not frozen, resolve that it has loaded\n frozen = false;\n if (timed) return;\n this.emitStatus();\n return true;\n } catch (e) {\n if (timed) return;\n Logger.errorp(\n 'error loading stdio rpc plugin',\n name.brightRed.underline,\n e,\n );\n await this.kill();\n frozen = false;\n this.emitStatus();\n return false;\n }\n })(),\n new Promise<boolean>(resolve => {\n // let user know if the child quit while launching\n this.#child.once('exit', () => {\n if (!frozen || timed) return;\n verbose('Plugin exited during init');\n frozen = false;\n this.emitStatus();\n resolve(false);\n });\n\n // check if the child is frozen (while true)\n setTimeout(() => {\n if (!frozen) return;\n Logger.errorp(\n 'I appear to be unresponsive when starting (maybe I forgot to respond to init)',\n name.brightRed.underline,\n );\n this.kill();\n timed = true;\n this.emitStatus();\n resolve(false);\n }, 5000);\n }),\n ]);\n }\n\n // kill the child process after requesting it to stop\n unload() {\n if (!this.#child || this.#child.exitCode) {\n this.detachListeners();\n this.emitStatus();\n return Promise.resolve(true);\n }\n let frozen = true,\n timed = false;\n const name = this.getName();\n\n return Promise.race([\n (async (): Promise<boolean> => {\n try {\n // let the plugin know it's time to stop, if this error it's probably because the method was not implemented\n try {\n await this.emit('stop');\n } catch (e) {\n // lazy developer - just implement stop please\n }\n\n await this.kill();\n\n frozen = false;\n if (timed) return;\n this.emitStatus();\n this.commands = [];\n return true;\n } catch (e) {\n if (timed) return;\n Logger.errorp(\n 'error unloading rpc plugin',\n name.brightRed.underline,\n e,\n );\n frozen = false;\n this.emitStatus();\n return false;\n }\n })(),\n // this is wrapped in a promise for the freeze check\n new Promise<boolean>(resolve => {\n // check if the child is frozen (while true)\n setTimeout(() => {\n if (!frozen) return;\n Logger.errorp(\n 'I appear to be unresponsive when stopping (maybe I forgot to respond to stop)',\n name.brightRed.underline,\n );\n this.kill();\n timed = true;\n this.emitStatus();\n resolve(true);\n }, 5000);\n }),\n ]);\n }\n\n // attaches event listeners\n attachListeners() {\n const name = this.getName();\n\n this.#outInterface.on('line', line => {\n try {\n const rpcData = JSON.parse(line);\n try {\n this.#rpc.receiveAndSend(rpcData);\n } catch (e) {\n Logger.error(\n this.getName().brightRed.underline,\n '!>'.red,\n 'error parsing rpc data',\n e,\n line,\n );\n }\n } catch {\n // fallback to logging\n Logger.log(name.underline, '>>'.green, line);\n }\n });\n\n // stderr - print out the errors\n this.#errInterface.on('line', err => {\n Logger.error(name.brightRed.underline, '!>'.red, err);\n });\n\n this.#child.on('error', () => this.kill());\n this.#child.on('close', () => this.kill());\n this.#child.on('exit', code => {\n Logger.errorp(\n '!>'.red,\n 'rpc plugin',\n name.brightRed.underline,\n 'exited with code',\n code,\n );\n this.kill();\n });\n }\n\n // removes previously attached event listeners\n detachListeners() {\n this.#outInterface.removeAllListeners('line');\n this.#errInterface.removeAllListeners('line');\n if (this.#child) {\n this.#child.removeAllListeners('exit');\n this.#child.removeAllListeners('close');\n this.#child.removeAllListeners('error');\n }\n }\n\n // write a string to the child process\n writeln(line: string) {\n try {\n if (this.#child && !this.#child.exitCode)\n this.#child.stdin.write(line + '\\n');\n } catch (e) {\n // the child probably died... oops!\n }\n }\n\n // forcibly kills the plugin\n async kill() {\n this.#rpc.rejectAllPendingRequests('Plugin Terminated');\n this.detachListeners();\n this.omegga.off('*', this.eventPassthrough);\n if (!this.#child) return;\n\n // create a promise for the exit of the process\n const promise = new Promise(resolve => this.#child.once('exit', resolve));\n\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 // wait for the process to exit\n await promise;\n this.#child = undefined;\n this.emitStatus();\n }\n\n eventPassthrough(type: string, ...args: any[]) {\n if (!this.#child) return;\n this.notify(type, args);\n }\n\n // setup the JSONRPC communication\n initRPC() {\n const server = new JSONRPCServer();\n const client = new JSONRPCClient(req => {\n try {\n this.writeln(JSON.stringify(req));\n return Promise.resolve();\n } catch (error) {\n return Promise.reject(error);\n }\n });\n const rpc = (this.#rpc = new JSONRPCServerAndClient(server, client));\n\n // plugin log generator function\n const ezLog =\n (\n logFn: 'log' | 'error' | 'info' | 'debug' | 'warn' | 'trace',\n name: string,\n symbol: string,\n ) =>\n (line: any) =>\n console[logFn](name.underline, symbol, line);\n\n const name = this.getName();\n\n // server can output logs special formatting for stdout\n rpc.addMethod('log', ezLog('log', name, '>>'.green));\n rpc.addMethod('error', ezLog('error', name.brightRed, '!>'.red));\n rpc.addMethod('info', ezLog('info', name, '#>'.blue));\n rpc.addMethod('debug', ezLog('debug', name, '?>'.blue));\n rpc.addMethod('warn', ezLog('warn', name.brightYellow, ':>'.yellow));\n rpc.addMethod('trace', ezLog('trace', name, 'T>'.grey));\n\n // plugin store interactions\n rpc.addMethod('store.get', key =>\n this.storage.get(key as unknown as string),\n );\n rpc.addMethod('store.set', ([key, value]: [key: string, value: any]) =>\n this.storage.set(key, value),\n );\n rpc.addMethod('store.delete', key =>\n this.storage.delete(key as unknown as string),\n );\n rpc.addMethod('store.wipe', () => this.storage.wipe());\n rpc.addMethod('store.count', () => this.storage.count());\n rpc.addMethod('store.keys', () => this.storage.keys());\n\n // server can run console commands\n rpc.addMethod('exec', line =>\n this.omegga.writeln(line as unknown as string),\n );\n rpc.addMethod('writeln', line =>\n this.omegga.writeln(line as unknown as string),\n );\n rpc.addMethod('broadcast', line =>\n this.omegga.broadcast(line as unknown as string),\n );\n rpc.addMethod(\n 'whisper',\n ({ target, line }: { target: string; line: string }) =>\n this.omegga.whisper(target, line),\n );\n rpc.addMethod(\n 'middlePrint',\n ({ target, line }: { target: string; line: string }) =>\n this.omegga.middlePrint(target, line),\n );\n rpc.addMethod('getPlayers', () => this.omegga.getPlayers());\n rpc.addMethod('getPlayerPosition', name =>\n this.omegga.getPlayer(name as unknown as string)?.getPosition(),\n ); // included for compatibility\n rpc.addMethod('getAllPlayerPositions', () =>\n this.omegga.getAllPlayerPositions(),\n );\n rpc.addMethod('getEnvironmentPresets', () =>\n this.omegga.getEnvironmentPresets(),\n );\n rpc.addMethod('resetEnvironment', () => this.omegga.resetEnvironment());\n rpc.addMethod('saveEnvironment', name =>\n this.omegga.saveEnvironment(name as unknown as string),\n );\n rpc.addMethod('loadEnvironment', name =>\n this.omegga.loadEnvironment(name as unknown as string),\n );\n rpc.addMethod('loadEnvironmentData', data =>\n this.omegga.loadEnvironmentData(data as EnvironmentPreset),\n );\n rpc.addMethod('getServerStatus', () => this.omegga.getServerStatus());\n rpc.addMethod('getMinigames', () => this.omegga.getMinigames());\n rpc.addMethod('getMinigamePresets', () => this.omegga.getMinigamePresets());\n rpc.addMethod(\n 'saveMinigame',\n ({ index, name }: { index: number; name: string }) =>\n this.omegga.saveMinigame(index, name),\n );\n rpc.addMethod(\n 'loadMinigame',\n ({ name, owner }: { name: string; owner: string }) =>\n this.omegga.loadMinigame(name, owner),\n );\n rpc.addMethod('nextRoundMinigame', index =>\n this.omegga.nextRoundMinigame(index as unknown as number),\n );\n rpc.addMethod('resetMinigame', index =>\n this.omegga.resetMinigame(index as unknown as number),\n );\n rpc.addMethod('deleteMinigame', index =>\n this.omegga.deleteMinigame(index as unknown as number),\n );\n rpc.addMethod('listMinigames', () => this.omegga.listMinigames());\n rpc.addMethod('getHostId', () => this.omegga.getHostId());\n rpc.addMethod('getRoleSetup', () => this.omegga.getRoleSetup());\n rpc.addMethod('getBanList', () => this.omegga.getBanList());\n rpc.addMethod('getSaves', () => this.omegga.getSaves());\n rpc.addMethod('getSavePath', name =>\n this.omegga.getSavePath(name as unknown as string),\n );\n rpc.addMethod(\n 'clearBricks',\n ({ target, quiet = false }: { target: string; quiet?: boolean }) =>\n this.omegga.clearBricks(target, quiet),\n );\n rpc.addMethod('clearAllBricks', quiet =>\n this.omegga.clearAllBricks(quiet as unknown as boolean),\n );\n rpc.addMethod('saveBricks', name =>\n this.omegga.saveBricks(name as unknown as string),\n );\n rpc.addMethod(\n 'loadBricks',\n ({\n name,\n offX = 0,\n offY = 0,\n offZ = 0,\n quiet = false,\n }: {\n name: string;\n offX?: number;\n offY?: number;\n offZ?: number;\n quiet?: boolean;\n }) => this.omegga.loadBricks(name, { offX, offY, offZ, quiet }),\n );\n rpc.addMethod(\n 'loadBricksOnPlayer',\n ({\n name,\n player,\n offX = 0,\n offY = 0,\n offZ = 0,\n }: {\n name: string;\n player: string;\n offX?: number;\n offY?: number;\n offZ?: number;\n quiet?: boolean;\n }) => this.omegga.loadBricksOnPlayer(name, player, { offX, offY, offZ }),\n );\n rpc.addMethod('readSaveData', name =>\n this.omegga.readSaveData(name as unknown as string),\n );\n rpc.addMethod('getSaveData', () => this.omegga.getSaveData());\n rpc.addMethod(\n 'loadSaveData',\n ({\n data,\n offX = 0,\n offY = 0,\n offZ = 0,\n quiet = false,\n }: {\n data: WriteSaveObject;\n offX?: number;\n offY?: number;\n offZ?: number;\n quiet?: boolean;\n }) => this.omegga.loadSaveData(data, { offX, offY, offZ, quiet }),\n );\n rpc.addMethod(\n 'loadSaveDataOnPlayer',\n ({\n data,\n player,\n offX = 0,\n offY = 0,\n offZ = 0,\n }: {\n data: WriteSaveObject;\n player: string;\n offX?: number;\n offY?: number;\n offZ?: number;\n quiet?: boolean;\n }) =>\n this.omegga.loadSaveDataOnPlayer(data, player, { offX, offY, offZ }),\n );\n rpc.addMethod('changeMap', map =>\n this.omegga.changeMap(map as unknown as string),\n );\n rpc.addMethod('unload', () => this.unload());\n rpc.addMethod('reload', async () => {\n await this.unload();\n await this.load();\n });\n\n // player related operations\n const addPlayerMethod = (name: string) =>\n rpc.addMethod(`player.${name}`, player =>\n (this.omegga.getPlayer(player as unknown as string) as any)?.[name](),\n );\n rpc.addMethod('player.get', target => {\n let player = this.omegga.getPlayer(target as unknown as string);\n return player && { ...player, host: player.isHost() };\n });\n addPlayerMethod('getRoles');\n addPlayerMethod('getPermissions');\n addPlayerMethod('getNameColor');\n addPlayerMethod('getPosition');\n addPlayerMethod('getGhostBrick');\n addPlayerMethod('getPaint');\n addPlayerMethod('getTemplateBounds');\n addPlayerMethod('getTemplateBoundsData');\n rpc.addMethod(\n 'player.loadDataAtGhostBrick',\n ({\n target,\n data,\n rotate = true,\n offX = 0,\n offY = 0,\n offZ = 0,\n quiet = false,\n }: {\n target: string;\n data: WriteSaveObject;\n rotate?: boolean;\n offX?: number;\n offY?: number;\n offZ?: number;\n quiet?: boolean;\n }) =>\n this.omegga\n .getPlayer(target)\n ?.loadDataAtGhostBrick(data, { rotate, offX, offY, offZ, quiet }),\n );\n rpc.addMethod(\n 'player.loadSaveData',\n ({\n target,\n data,\n offX = 0,\n offY = 0,\n offZ = 0,\n }: {\n target: string;\n data: WriteSaveObject;\n offX?: number;\n offY?: number;\n offZ?: number;\n }) =>\n this.omegga.getPlayer(target)?.loadSaveData(data, { offX, offY, offZ }),\n );\n\n // plugin related operations\n rpc.addMethod('plugin.get', async name => {\n const plugin = this.omegga.pluginLoader.plugins.find(\n p => p.getName() === (name as unknown as string),\n );\n\n if (plugin) {\n return {\n name,\n documentation: plugin.getDocumentation(),\n loaded: plugin.isLoaded(),\n };\n } else {\n return null;\n }\n });\n\n rpc.addMethod(\n 'plugin.emit',\n async ([name, event, ...args]: [string, string, ...any[]]) => {\n const plugin = this.omegga.pluginLoader.plugins.find(\n p => p.getName() === name,\n );\n\n if (plugin) {\n return plugin.emitPlugin(event, this.getName(), args);\n } else {\n return null;\n }\n },\n );\n }\n\n // emit a custom plugin event\n async emitPlugin(event: string, from: string, args: any[]) {\n return await this.emit('plugin:emit', [event, from, ...args]);\n }\n\n // emit a message to the plugin via the jsonrpc client and expect a response\n emit(type: string, arg?: any) {\n return this.#rpc.request(type, arg);\n }\n\n // emit a message to the plugin via the jsonrpc client, don't expect a response\n notify(type: string, arg?: any) {\n try {\n this.#rpc.notify(type, arg);\n } catch (e) {\n // this only happens if the RPC library is hitting some issues - probably redundant\n }\n }\n}\n"],"names":["Plugin","Logger","spawn","bootstrap","JSONRPCServer","JSONRPCClient","JSONRPCServerAndClient","name"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin_jsonrpc_stdio.js","sources":["../../../src/omegga/plugin/plugin_jsonrpc_stdio.ts"],"sourcesContent":["import Logger from '@/logger';\nimport { EnvironmentPreset } from '@brickadia/presets';\nimport Omegga from '@omegga/server';\nimport { WriteSaveObject } from 'brs-js';\nimport {\n JSONRPCClient,\n JSONRPCServer,\n JSONRPCServerAndClient,\n} from 'json-rpc-2.0';\nimport { ChildProcessWithoutNullStreams, spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport readline from 'readline';\nimport { Plugin } from './interface';\nimport { bootstrap } from './plugin_node_safe/proxyOmegga';\n\n// TODO: check if version is compatible (v1 -> v2) from file\n// TODO: write jsonrpc wrappers in a few languages, implement a few simple plugins\n// TODO: languages: [ python, go ]\n\nconst MAIN_FILE = 'omegga_plugin';\nconst DOC_FILE = 'doc.json';\nconst PLUGIN_FILE = 'plugin.json';\n\nexport default class RpcPlugin extends Plugin {\n #child: ChildProcessWithoutNullStreams;\n #rpc: JSONRPCServerAndClient;\n #errInterface: readline.Interface;\n #outInterface: readline.Interface;\n\n messageCounter: number;\n\n // all RPC plugins require a main (binary) file and a doc file\n static canLoad(pluginPath: string) {\n return (\n fs.existsSync(path.join(pluginPath, MAIN_FILE)) &&\n fs.existsSync(path.join(pluginPath, DOC_FILE))\n );\n }\n\n // websocket rpc plugin type\n static getFormat() {\n return 'jsonrpc_stdio';\n }\n\n // documentation is based on doc.json file\n getDocumentation() {\n return this.documentation;\n }\n constructor(pluginPath: string, omegga: Omegga) {\n super(pluginPath, omegga);\n\n this.messageCounter = 0;\n\n // TODO: validate documentation\n this.documentation = Plugin.readJSON(path.join(pluginPath, DOC_FILE));\n this.pluginConfig = Plugin.readJSON(path.join(pluginPath, PLUGIN_FILE));\n this.pluginFile = path.join(pluginPath, MAIN_FILE);\n\n this.eventPassthrough = this.eventPassthrough.bind(this);\n this.commands = [];\n\n this.initRPC();\n }\n\n isLoaded() {\n return !!this.#child && !this.#child.exitCode;\n }\n\n // determing if a command is registered\n isCommand(cmd: string) {\n return this.commands.includes(cmd);\n }\n\n // spawn the plugin as a child process\n async load() {\n const name = this.getName();\n const verbose = (...msg: any[]) => Logger.verbose(name.underline, ...msg);\n verbose('Load method invoked');\n let frozen = true,\n timed = false;\n this.commands = [];\n\n // can't load the plugin if the child is still running\n if (this.#child) {\n verbose('Plugin already has child process');\n return false;\n }\n\n let config;\n try {\n verbose('Getting plugin config');\n config = await this.storage.getConfig();\n } catch (e) {\n return false;\n }\n\n try {\n if (this.pluginConfig?.emitConfig) {\n verbose('Emitting plugin config');\n await fs.promises.writeFile(\n path.join(this.path, this.pluginConfig.emitConfig),\n JSON.stringify(config),\n );\n }\n verbose('Spawning child process');\n this.#child = spawn(this.pluginFile);\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 } catch (err) {\n Logger.errorp(\n 'error loading stdio rpc plugin',\n name.brightRed.underline,\n err,\n );\n await this.kill();\n this.emitStatus();\n return false;\n }\n\n return Promise.race([\n (async () => {\n try {\n // get some initial information to create an omegga proxy\n const initialData = bootstrap(this.omegga);\n\n verbose('Sending initial data');\n // send all of the mock events to the proxy omegga\n for (const ev in initialData) {\n // send some initial information\n this.notify(ev, initialData[ev]);\n }\n\n verbose('Initializing event passthrough');\n // pass events through\n this.omegga.on('*', this.eventPassthrough);\n\n try {\n // tell the plugin to start\n verbose('Waiting for plugin to start...');\n const result = await this.emit('init', config);\n\n verbose('Initialized with result:', result);\n // plugins can return a result object\n if (typeof result === 'object' && result) {\n // if registeredCommands is in the results, register the provided strings as commands\n const cmds = result.registeredCommands;\n if (\n cmds &&\n cmds instanceof Array &&\n cmds.every(i => typeof i === 'string')\n )\n this.commands = cmds;\n }\n } catch (e) {\n if (!e.message) return;\n Logger.errorp(name.brightRed.underline, 'error starting: ', e);\n }\n\n // plugin is not frozen, resolve that it has loaded\n frozen = false;\n if (timed) return;\n this.emitStatus();\n return true;\n } catch (e) {\n if (timed) return;\n Logger.errorp(\n 'error loading stdio rpc plugin',\n name.brightRed.underline,\n e,\n );\n await this.kill();\n frozen = false;\n this.emitStatus();\n return false;\n }\n })(),\n new Promise<boolean>(resolve => {\n // let user know if the child quit while launching\n this.#child.once('exit', () => {\n if (!frozen || timed) return;\n verbose('Plugin exited during init');\n frozen = false;\n this.emitStatus();\n resolve(false);\n });\n\n // check if the child is frozen (while true)\n setTimeout(() => {\n if (!frozen) return;\n Logger.errorp(\n 'I appear to be unresponsive when starting (maybe I forgot to respond to init)',\n name.brightRed.underline,\n );\n this.kill();\n timed = true;\n this.emitStatus();\n resolve(false);\n }, 5000);\n }),\n ]);\n }\n\n // kill the child process after requesting it to stop\n unload() {\n if (!this.#child || this.#child.exitCode) {\n this.detachListeners();\n this.emitStatus();\n return Promise.resolve(true);\n }\n let frozen = true,\n timed = false;\n const name = this.getName();\n\n return Promise.race([\n (async (): Promise<boolean> => {\n try {\n // let the plugin know it's time to stop, if this error it's probably because the method was not implemented\n try {\n await this.emit('stop');\n } catch (e) {\n // lazy developer - just implement stop please\n }\n\n await this.kill();\n\n frozen = false;\n if (timed) return;\n this.emitStatus();\n this.commands = [];\n return true;\n } catch (e) {\n if (timed) return;\n Logger.errorp(\n 'error unloading rpc plugin',\n name.brightRed.underline,\n e,\n );\n frozen = false;\n this.emitStatus();\n return false;\n }\n })(),\n // this is wrapped in a promise for the freeze check\n new Promise<boolean>(resolve => {\n // check if the child is frozen (while true)\n setTimeout(() => {\n if (!frozen) return;\n Logger.errorp(\n 'I appear to be unresponsive when stopping (maybe I forgot to respond to stop)',\n name.brightRed.underline,\n );\n this.kill();\n timed = true;\n this.emitStatus();\n resolve(true);\n }, 5000);\n }),\n ]);\n }\n\n // attaches event listeners\n attachListeners() {\n const name = this.getName();\n\n this.#outInterface.on('line', line => {\n try {\n const rpcData = JSON.parse(line);\n try {\n this.#rpc.receiveAndSend(rpcData);\n } catch (e) {\n Logger.error(\n this.getName().brightRed.underline,\n '!>'.red,\n 'error parsing rpc data',\n e,\n line,\n );\n }\n } catch {\n // fallback to logging\n Logger.log(name.underline, '>>'.green, line);\n }\n });\n\n // stderr - print out the errors\n this.#errInterface.on('line', err => {\n Logger.error(name.brightRed.underline, '!>'.red, err);\n });\n\n this.#child.on('error', () => this.kill());\n this.#child.on('close', () => this.kill());\n this.#child.on('exit', code => {\n Logger.errorp(\n '!>'.red,\n 'rpc plugin',\n name.brightRed.underline,\n 'exited with code',\n code,\n );\n this.kill();\n });\n }\n\n // removes previously attached event listeners\n detachListeners() {\n this.#outInterface.removeAllListeners('line');\n this.#errInterface.removeAllListeners('line');\n if (this.#child) {\n this.#child.removeAllListeners('exit');\n this.#child.removeAllListeners('close');\n this.#child.removeAllListeners('error');\n }\n }\n\n // write a string to the child process\n writeln(line: string) {\n try {\n if (this.#child && !this.#child.exitCode)\n this.#child.stdin.write(line + '\\n');\n } catch (e) {\n // the child probably died... oops!\n }\n }\n\n // forcibly kills the plugin\n async kill() {\n this.#rpc.rejectAllPendingRequests('Plugin Terminated');\n this.detachListeners();\n this.omegga.off('*', this.eventPassthrough);\n if (!this.#child) return;\n\n // create a promise for the exit of the process\n const promise = new Promise(resolve => this.#child.once('exit', resolve));\n\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 // wait for the process to exit\n await promise;\n this.#child = undefined;\n this.emitStatus();\n }\n\n eventPassthrough(type: string, ...args: any[]) {\n if (!this.#child) return;\n this.notify(type, args);\n }\n\n // setup the JSONRPC communication\n initRPC() {\n const server = new JSONRPCServer();\n const client = new JSONRPCClient(req => {\n try {\n this.writeln(JSON.stringify(req));\n return Promise.resolve();\n } catch (error) {\n return Promise.reject(error);\n }\n });\n const rpc = (this.#rpc = new JSONRPCServerAndClient(server, client));\n\n // plugin log generator function\n const ezLog =\n (\n logFn: 'log' | 'error' | 'info' | 'debug' | 'warn' | 'trace',\n name: string,\n symbol: string,\n ) =>\n (line: any) =>\n console[logFn](name.underline, symbol, line);\n\n const name = this.getName();\n\n // server can output logs special formatting for stdout\n rpc.addMethod('log', ezLog('log', name, '>>'.green));\n rpc.addMethod('error', ezLog('error', name.brightRed, '!>'.red));\n rpc.addMethod('info', ezLog('info', name, '#>'.blue));\n rpc.addMethod('debug', ezLog('debug', name, '?>'.blue));\n rpc.addMethod('warn', ezLog('warn', name.brightYellow, ':>'.yellow));\n rpc.addMethod('trace', ezLog('trace', name, 'T>'.grey));\n\n // plugin store interactions\n rpc.addMethod('store.get', key =>\n this.storage.get(key as unknown as string),\n );\n rpc.addMethod('store.set', ([key, value]: [key: string, value: any]) =>\n this.storage.set(key, value),\n );\n rpc.addMethod('store.delete', key =>\n this.storage.delete(key as unknown as string),\n );\n rpc.addMethod('store.wipe', () => this.storage.wipe());\n rpc.addMethod('store.count', () => this.storage.count());\n rpc.addMethod('store.keys', () => this.storage.keys());\n\n // server can run console commands\n rpc.addMethod('exec', line =>\n this.omegga.writeln(line as unknown as string),\n );\n rpc.addMethod('writeln', line =>\n this.omegga.writeln(line as unknown as string),\n );\n rpc.addMethod('broadcast', line =>\n this.omegga.broadcast(line as unknown as string),\n );\n rpc.addMethod(\n 'whisper',\n ({ target, line }: { target: string; line: string }) =>\n this.omegga.whisper(target, line),\n );\n rpc.addMethod(\n 'middlePrint',\n ({ target, line }: { target: string; line: string }) =>\n this.omegga.middlePrint(target, line),\n );\n rpc.addMethod('getPlayers', () => this.omegga.getPlayers());\n rpc.addMethod('getPlayerPosition', name =>\n this.omegga.getPlayer(name as unknown as string)?.getPosition(),\n ); // included for compatibility\n rpc.addMethod('getAllPlayerPositions', () =>\n this.omegga.getAllPlayerPositions(),\n );\n rpc.addMethod('getEnvironmentPresets', () =>\n this.omegga.getEnvironmentPresets(),\n );\n rpc.addMethod('resetEnvironment', () => this.omegga.resetEnvironment());\n rpc.addMethod('saveEnvironment', name =>\n this.omegga.saveEnvironment(name as unknown as string),\n );\n rpc.addMethod('loadEnvironment', name =>\n this.omegga.loadEnvironment(name as unknown as string),\n );\n rpc.addMethod('loadEnvironmentData', data =>\n this.omegga.loadEnvironmentData(data as EnvironmentPreset),\n );\n rpc.addMethod('getServerStatus', () => this.omegga.getServerStatus());\n rpc.addMethod('getMinigames', () => this.omegga.getMinigames());\n rpc.addMethod('getMinigamePresets', () => this.omegga.getMinigamePresets());\n rpc.addMethod(\n 'saveMinigame',\n ({ index, name }: { index: number; name: string }) =>\n this.omegga.saveMinigame(index, name),\n );\n rpc.addMethod(\n 'loadMinigame',\n ({ name, owner }: { name: string; owner: string }) =>\n this.omegga.loadMinigame(name, owner),\n );\n rpc.addMethod('nextRoundMinigame', index =>\n this.omegga.nextRoundMinigame(index as unknown as number),\n );\n rpc.addMethod('resetMinigame', index =>\n this.omegga.resetMinigame(index as unknown as number),\n );\n rpc.addMethod('deleteMinigame', index =>\n this.omegga.deleteMinigame(index as unknown as number),\n );\n rpc.addMethod('listMinigames', () => this.omegga.listMinigames());\n rpc.addMethod('getHostId', () => this.omegga.getHostId());\n rpc.addMethod('getRoleSetup', () => this.omegga.getRoleSetup());\n rpc.addMethod('getBanList', () => this.omegga.getBanList());\n rpc.addMethod('getSaves', () => this.omegga.getSaves());\n rpc.addMethod('getSavePath', name =>\n this.omegga.getSavePath(name as unknown as string),\n );\n rpc.addMethod(\n 'clearBricks',\n ({ target, quiet = false }: { target: string; quiet?: boolean }) =>\n this.omegga.clearBricks(target, quiet),\n );\n rpc.addMethod('clearAllBricks', quiet =>\n this.omegga.clearAllBricks(quiet as unknown as boolean),\n );\n rpc.addMethod('saveBricks', name =>\n this.omegga.saveBricks(name as unknown as string),\n );\n rpc.addMethod(\n 'loadBricks',\n ({\n name,\n offX = 0,\n offY = 0,\n offZ = 0,\n quiet = false,\n }: {\n name: string;\n offX?: number;\n offY?: number;\n offZ?: number;\n quiet?: boolean;\n }) => this.omegga.loadBricks(name, { offX, offY, offZ, quiet }),\n );\n rpc.addMethod(\n 'loadBricksOnPlayer',\n ({\n name,\n player,\n offX = 0,\n offY = 0,\n offZ = 0,\n }: {\n name: string;\n player: string;\n offX?: number;\n offY?: number;\n offZ?: number;\n quiet?: boolean;\n }) => this.omegga.loadBricksOnPlayer(name, player, { offX, offY, offZ }),\n );\n rpc.addMethod('readSaveData', name =>\n this.omegga.readSaveData(name as unknown as string),\n );\n rpc.addMethod('getSaveData', () => this.omegga.getSaveData());\n rpc.addMethod(\n 'loadSaveData',\n ({\n data,\n offX = 0,\n offY = 0,\n offZ = 0,\n quiet = false,\n }: {\n data: WriteSaveObject;\n offX?: number;\n offY?: number;\n offZ?: number;\n quiet?: boolean;\n }) => this.omegga.loadSaveData(data, { offX, offY, offZ, quiet }),\n );\n rpc.addMethod(\n 'loadSaveDataOnPlayer',\n ({\n data,\n player,\n offX = 0,\n offY = 0,\n offZ = 0,\n }: {\n data: WriteSaveObject;\n player: string;\n offX?: number;\n offY?: number;\n offZ?: number;\n quiet?: boolean;\n }) =>\n this.omegga.loadSaveDataOnPlayer(data, player, { offX, offY, offZ }),\n );\n rpc.addMethod('changeMap', map =>\n this.omegga.changeMap(map as unknown as string),\n );\n rpc.addMethod('unload', () => this.unload());\n rpc.addMethod('reload', async () => {\n await this.unload();\n await this.load();\n });\n\n // player related operations\n const addPlayerMethod = (name: string) =>\n rpc.addMethod(`player.${name}`, player =>\n (this.omegga.getPlayer(player as unknown as string) as any)?.[name](),\n );\n rpc.addMethod('player.get', target => {\n let player = this.omegga.getPlayer(target as unknown as string);\n return player && { ...player, host: player.isHost() };\n });\n addPlayerMethod('getRoles');\n addPlayerMethod('getPermissions');\n addPlayerMethod('getNameColor');\n addPlayerMethod('getPosition');\n addPlayerMethod('getPawn');\n addPlayerMethod('getGhostBrick');\n addPlayerMethod('getPaint');\n addPlayerMethod('isCrouched');\n addPlayerMethod('isDead');\n addPlayerMethod('getTemplateBounds');\n addPlayerMethod('getTemplateBoundsData');\n addPlayerMethod('kill');\n addPlayerMethod('getScore');\n addPlayerMethod('getLeaderboard');\n rpc.addMethod(\n 'player.loadDataAtGhostBrick',\n ({\n target,\n data,\n rotate = true,\n offX = 0,\n offY = 0,\n offZ = 0,\n quiet = false,\n }: {\n target: string;\n data: WriteSaveObject;\n rotate?: boolean;\n offX?: number;\n offY?: number;\n offZ?: number;\n quiet?: boolean;\n }) =>\n this.omegga\n .getPlayer(target)\n ?.loadDataAtGhostBrick(data, { rotate, offX, offY, offZ, quiet }),\n );\n rpc.addMethod(\n 'player.loadSaveData',\n ({\n target,\n data,\n offX = 0,\n offY = 0,\n offZ = 0,\n }: {\n target: string;\n data: WriteSaveObject;\n offX?: number;\n offY?: number;\n offZ?: number;\n }) =>\n this.omegga.getPlayer(target)?.loadSaveData(data, { offX, offY, offZ }),\n );\n rpc.addMethod(\n 'player.clearBricks',\n ({ target, quiet = false }: { target: string; quiet?: boolean }) =>\n this.omegga.getPlayer(target)?.clearBricks(quiet),\n );\n rpc.addMethod(\n 'player.loadBricks',\n ({ target, saveName }: { target: string; saveName: string }) =>\n this.omegga.getPlayer(target)?.loadBricks(saveName),\n );\n rpc.addMethod(\n 'player.damage',\n ({ target, amount }: { target: string; amount: number }) =>\n this.omegga.getPlayer(target)?.damage(amount),\n );\n rpc.addMethod(\n 'player.heal',\n ({ target, amount }: { target: string; amount: number }) =>\n this.omegga.getPlayer(target)?.heal(amount),\n );\n rpc.addMethod(\n 'player.giveItem',\n ({ target, item }: { target: string; item: string }) =>\n this.omegga.getPlayer(target)?.giveItem(item as any),\n );\n rpc.addMethod(\n 'player.takeItem',\n ({ target, item }: { target: string; item: string }) =>\n this.omegga.getPlayer(target)?.takeItem(item as any),\n );\n rpc.addMethod(\n 'player.setTeam',\n ({ target, teamIndex }: { target: string; teamIndex: number }) =>\n this.omegga.getPlayer(target)?.setTeam(teamIndex),\n );\n rpc.addMethod(\n 'player.setMinigame',\n ({ target, index }: { target: string; index: number }) =>\n this.omegga.getPlayer(target)?.setMinigame(index),\n );\n rpc.addMethod(\n 'player.setScore',\n ({\n target,\n minigameIndex,\n score,\n }: {\n target: string;\n minigameIndex: number;\n score: number;\n }) => this.omegga.getPlayer(target)?.setScore(minigameIndex, score),\n );\n rpc.addMethod(\n 'player.setLeaderboard',\n ({\n target,\n key,\n value,\n }: {\n target: string;\n key: string;\n value: number;\n }) => this.omegga.getPlayer(target)?.setLeaderboard(key, value),\n );\n\n // plugin related operations\n rpc.addMethod('plugin.get', async name => {\n const plugin = this.omegga.pluginLoader.plugins.find(\n p => p.getName() === (name as unknown as string),\n );\n\n if (plugin) {\n return {\n name,\n documentation: plugin.getDocumentation(),\n loaded: plugin.isLoaded(),\n };\n } else {\n return null;\n }\n });\n\n rpc.addMethod(\n 'plugin.emit',\n async ([name, event, ...args]: [string, string, ...any[]]) => {\n const plugin = this.omegga.pluginLoader.plugins.find(\n p => p.getName() === name,\n );\n\n if (plugin) {\n return plugin.emitPlugin(event, this.getName(), args);\n } else {\n return null;\n }\n },\n );\n }\n\n // emit a custom plugin event\n async emitPlugin(event: string, from: string, args: any[]) {\n return await this.emit('plugin:emit', [event, from, ...args]);\n }\n\n // emit a message to the plugin via the jsonrpc client and expect a response\n emit(type: string, arg?: any) {\n return this.#rpc.request(type, arg);\n }\n\n // emit a message to the plugin via the jsonrpc client, don't expect a response\n notify(type: string, arg?: any) {\n try {\n this.#rpc.notify(type, arg);\n } catch (e) {\n // this only happens if the RPC library is hitting some issues - probably redundant\n }\n }\n}\n"],"names":["Plugin","Logger","spawn","bootstrap","JSONRPCServer","JSONRPCClient","JSONRPCServerAndClient","name"],"mappings":"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"}
|
package/dist/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sources":["../src/plugin.ts"],"sourcesContent":["import { EnvironmentPreset } from '@brickadia/presets';\nimport {\n BRBanList,\n BRPlayerNameCache,\n BRRoleAssignments,\n BRRoleSetup,\n} from '@brickadia/types';\nimport {\n ILogMinigame,\n IMinigameList,\n IPlayerPositions,\n IServerStatus,\n} from '@omegga/types';\nimport util from '@util';\nimport { ReadSaveObject, WriteSaveObject } from 'brs-js';\n\nexport const _OMEGGA_UTILS_IMPORT = util;\ndeclare global {\n export var Omegga: OmeggaLike;\n export var Player: StaticPlayer;\n export var OMEGGA_UTIL: typeof _OMEGGA_UTILS_IMPORT;\n}\n\nexport * from '@brickadia/types';\nexport * from '@omegga/types';\nexport { OmeggaPlugin };\n\nexport type OL = OmeggaLike;\nexport type OP = OmeggaPlugin;\nexport type PC<T extends Record<string, unknown> = Record<string, unknown>> =\n PluginConfig<T>;\nexport type PS<T extends Record<string, unknown> = Record<string, unknown>> =\n PluginStore<T>;\n\nexport interface BrickBounds {\n minBound: [number, number, number];\n maxBound: [number, number, number];\n center: [number, number, number];\n}\n\n/** Created when a player clicks on a brick with an interact component */\nexport interface BrickInteraction {\n /** Brick name from catalog (Turkey Body, 4x Cube) */\n brick_name: string;\n /** Brick asset name */\n brick_asset: string;\n /** Brick size */\n brick_size: [number, number, number];\n /** Player information, id, name, controller, and pawn */\n player: { id: string; name: string; controller: string; pawn: string };\n /** Brick center position */\n position: [number, number, number];\n\n /** message sent from a brick click interaction */\n message: string;\n /** data parsed from the line (if it starts with json:) */\n data: null | number | string | boolean | Record<string, unknown>;\n /** True when there was a json payload */\n json: boolean;\n /** True when there was a parse error */\n error: boolean;\n}\n\n/** AutoRestart options */\nexport type AutoRestartConfig = {\n players: boolean;\n announcement: boolean;\n saveWorld: boolean;\n};\n\nexport interface OmeggaPlayer {\n /** player name */\n name: string;\n\n /** player display name */\n displayName: string;\n\n /** player uuid */\n id: string;\n\n /** player controller id */\n controller: string;\n\n /** player state id */\n state: string;\n\n /**\n * Returns omegga\n */\n getOmegga(): OmeggaLike;\n\n /**\n * Clone a player\n */\n clone(): OmeggaPlayer;\n\n /**\n * Get raw player info (to feed into a constructor)\n */\n raw(): [string, string, string, string, string];\n\n /**\n * True if the player is the host\n */\n isHost(): boolean;\n\n /**\n * Clear player's bricks\n * @param quiet clear bricks quietly\n */\n clearBricks(quiet?: boolean): void;\n\n /**\n * Get player's roles, if any\n */\n getRoles(): readonly string[];\n\n /**\n * Get player's permissions in a map like `{\"Bricks.ClearOwn\": true, ...}`\n * @return permissions map\n */\n getPermissions(): Record<string, boolean>;\n\n /**\n * Get player's name color\n * @return 6 character hex string\n */\n getNameColor(): string;\n\n /**\n * Get the player's pawn\n * @return pawn\n */\n getPawn(): Promise<string>;\n\n /**\n * Get player's position\n * @return [x, y, z] coordinates\n */\n getPosition(): Promise<[number, number, number]>;\n\n /**\n * Gets a user's ghost brick info (by uuid, name, controller, or player object)\n * @return ghost brick data\n */\n getGhostBrick(): Promise<{\n targetGrid: string;\n location: number[];\n orientation: string;\n }>;\n\n /**\n * gets a user's paint tool properties\n */\n getPaint(): Promise<{\n materialIndex: string;\n materialAlpha: string;\n material: string;\n color: number[];\n }>;\n\n /**\n * gets whether or not the player is crouching\n */\n isCrouched(pawn?: string): Promise<boolean>;\n\n /**\n * gets whether or not the player is dead\n */\n isDead(pawn?: string): Promise<boolean>;\n\n /**\n * Gets the bounds of the template in the user's clipboard (bounds of original selection box)\n * @return template bounds\n */\n getTemplateBounds(): Promise<BrickBounds>;\n\n /**\n * Get bricks inside template bounds\n * @return BRS JS Save Data\n */\n getTemplateBoundsData(): Promise<ReadSaveObject>;\n\n /**\n * Load bricks at ghost brick location\n * @param saveData save data to load\n */\n loadDataAtGhostBrick(\n saveData: WriteSaveObject,\n options?: {\n rotate?: boolean;\n offX?: number;\n offY?: number;\n offZ?: number;\n quiet?: boolean;\n },\n ): Promise<void>;\n\n /**\n * Load bricks on this player's clipboard\n * @param saveName Save to load\n */\n loadBricks(saveName: string): void;\n\n /**\n * Load bricks on this player's clipboard passing save data\n * @param saveData save data to load\n */\n loadSaveData(\n saveData: WriteSaveObject,\n options?: {\n rotate?: boolean;\n offX?: number;\n offY?: number;\n offZ?: number;\n quiet?: boolean;\n },\n ): Promise<void>;\n\n /**\n * Kills this player\n */\n kill(): void;\n\n /**\n * Damages a player\n * @param amount Amount to damage\n */\n damage(amount: number): void;\n\n /**\n * Heal this player\n * @param amount to heal\n */\n heal(amount: number): void;\n\n /**\n * Gives a player an item\n * @param item Item name (Weapon_Bow)\n */\n giveItem(item: WeaponClass): void;\n\n /**\n * Removes an item from a player's inventory\n * @param item Item name (Weapon_Bow)\n */\n takeItem(item: WeaponClass): void;\n\n /**\n * Changes a player's team\n * @param teamIndex Team index\n */\n setTeam(teamIndex: number): void;\n\n /**\n * Changes a player's minigame\n * @param index Minigame index\n */\n setMinigame(index: number): void;\n\n /**\n * Changes a player's score\n * @param minigameIndex minigame index\n * @param score Score\n */\n setScore(minigameIndex: number, score: number): void;\n\n /**\n * Fetch a player's score\n * @param minigameIndex minigame index\n */\n getScore(minigameIndex: number): Promise<number>;\n}\n\nexport interface StaticPlayer {\n /**\n * get a player's roles, if any\n * @param omegga omegga instance\n * @param id player uuid\n * @return list of roles\n */\n getRoles(omegga: OmeggaLike, id: string): readonly string[];\n\n /**\n * get a player's permissions in a map like `{\"Bricks.ClearOwn\": true, ...}`\n * @param omegga Omegga instance\n * @param id player uuid\n * @return permissions map\n */\n getPermissions(omegga: OmeggaLike, id: string): Record<string, boolean>;\n\n /**\n * Kills a player\n * @param omegga Omegga instance\n * @param target Player or player name/id\n */\n kill(omegga: OmeggaLike, target: string | OmeggaPlayer): void;\n\n /**\n * Damages a player\n * @param omegga Omegga instance\n * @param target Player or player name/id\n * @param amount Damage amount\n */\n damage(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n amount: number,\n ): void;\n\n /**\n * Heal a player\n * @param omegga Omegga instance\n * @param target Player or player name/id\n * @param amount Heal amount\n */\n heal(omegga: OmeggaLike, target: string | OmeggaPlayer, amount: number): void;\n\n /**\n * Gives a player an item\n * @param omegga Omegga instance\n * @param target Player or player name/id\n * @param item Item name (Weapon_Bow)\n */\n giveItem(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n item: WeaponClass,\n ): void;\n\n /**\n * Removes an item from a player's inventory\n * @param omegga Omegga instance\n * @param target Player or player name/id\n * @param item Item name (Weapon_Bow)\n */\n takeItem(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n item: WeaponClass,\n ): void;\n\n /**\n * Changes a player's team\n * @param omegga Omegga instance\n * @param target Player or player name/id\n * @param teamIndex Team name? index?\n */\n setTeam(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n teamIndex: number,\n ): void;\n\n /**\n * Changes a player's minigame\n * @param omegga Omegga instance\n * @param target Player or player name/id\n * @param index Minigame index\n */\n setMinigame(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n index: number,\n ): void;\n\n /**\n * Changes a player's score\n * @param omegga Omegga instance\n * @param target Player or player name/id\n * @param minigameIndex minigame index\n * @param score Score\n */\n setScore(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n minigameIndex: number,\n score: number,\n ): void;\n\n /**\n * Fetches a player's score\n * @param omegga Omegga instance\n * @param target Player or player name/id\n * @param minigameIndex minigame index\n */\n getScore(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n minigameIndex: number,\n ): Promise<number>;\n}\n\nexport interface InjectedCommands {\n /** Get server status */\n getServerStatus(this: OmeggaLike): Promise<IServerStatus>;\n /** Get a list of minigames and their indices */\n listMinigames(this: OmeggaLike): Promise<IMinigameList>;\n // /** Get all pawn data */\n // getAllPawnData(this: OmeggaLike, fields: PawnDataField[]): void;\n /** Get all player positions and pawns */\n getAllPlayerPositions(this: OmeggaLike): Promise<IPlayerPositions>;\n /** Get minigames and members */\n getMinigames(this: OmeggaLike): Promise<ILogMinigame[]>;\n}\n\nexport interface MockEventEmitter {\n addListener(event: string, listener: Function): this;\n emit(event: string, ...args: any[]): boolean;\n eventNames(): (string | symbol)[];\n getMaxListeners(): number;\n listenerCount(event: string): number;\n listeners(event: string): Function[];\n off(event: string, listener: Function): this;\n on(event: string, listener: Function): this;\n once(event: string, listener: Function): this;\n prependListener(event: string, listener: Function): this;\n prependOnceListener(event: string, listener: Function): this;\n rawListeners(event: string): Function[];\n removeAllListeners(event?: string): this;\n removeListener(event: string, listener: Function): this;\n setMaxListeners(maxListeners: number): this;\n\n on(event: 'close', listener: () => void): this;\n on(event: 'line', listener: (line: string) => void): this;\n on(event: 'start', listener: (info: { map: string }) => void): this;\n on(event: 'version', listener: (version: number) => void): this;\n on(event: 'unauthorized', listener: () => void): this;\n on(event: 'join', listener: (player: OmeggaPlayer) => void): this;\n on(event: 'leave', listener: (player: OmeggaPlayer) => void): this;\n on(event: 'chat', listener: (name: string, message: string) => void): this;\n on(event: 'mapchange', listener: (info: { map: string }) => void): this;\n on(event: 'autorestart', listener: (config: AutoRestartConfig) => void): this;\n on(\n event: 'interact',\n listener: (interaction: BrickInteraction) => void,\n ): this;\n on(\n event: 'minigamejoin',\n listener: (info: {\n player: { name: string; id: string };\n minigameName: string;\n }) => void,\n ): this;\n}\n\nexport interface OmeggaLike\n extends OmeggaCore,\n LogWrangling,\n InjectedCommands,\n MockEventEmitter {\n writeln(line: string): void;\n\n /** game CL version*/\n version: number;\n\n /** verbose logging is enabled*/\n verbose: boolean;\n\n /** list of players */\n players: OmeggaPlayer[];\n\n /** server host */\n host?: { id: string; name: string };\n\n /** server is started */\n started: boolean;\n /** server is starting */\n starting: boolean;\n /** server is stopping */\n stopping: boolean;\n /** current map */\n currentMap: string;\n\n /** path to config files */\n configPath: string;\n /** path to saves */\n savePath: string;\n /** path to worlds */\n worldPath: string;\n /** path to presets */\n presetPath: string;\n\n /** get a plugin's name, documentation, and loaded status\n * If run in an unsafe plugin, the emitPlugin method sends events from\n * an \"unsafe\" plugin\n */\n getPlugin(name: string): Promise<PluginInterop>;\n}\n\nexport interface OmeggaCore {\n /**\n * get a list of players\n * @return list of players {id: uuid, name: name} objects\n */\n getPlayers(): {\n id: string;\n name: string;\n displayName: string;\n controller: string;\n state: string;\n }[];\n\n /**\n * find a player by name, id, controller, or state\n * @param target - name, id, controller, or state\n */\n getPlayer(target: string): OmeggaPlayer | null;\n\n /**\n * find a player by rough name, prioritize exact matches and get fuzzier\n * @param name player name, fuzzy\n */\n findPlayerByName(name: string): OmeggaPlayer | null;\n\n /**\n * get the host's ID\n * @return Host Id\n */\n getHostId(): string;\n\n /**\n * broadcast messages to chat\n * messages are broken by new line\n * multiple arguments are additional lines\n * all messages longer than 512 characters are deleted automatically, though omegga wouldn't have sent them anyway\n * @param messages unescaped chat messages to send. may need to wrap messages with quotes\n */\n broadcast(...messages: string[]): void;\n\n /**\n * whisper messages to a player's chat\n * messages are broken by new line\n * multiple arguments are additional lines\n * all messages longer than 512 characters are deleted automatically, though omegga wouldn't have sent them anyway\n * @param target - player identifier or player object\n * @param messages - unescaped chat messages to send. may need to wrap messages with quotes\n */\n whisper(target: string | OmeggaPlayer, ...messages: string[]): void;\n\n /**\n * prints text to the middle of a player's screen\n * all messages longer than 512 characters are deleted automatically\n * @param target - player identifier or player object\n * @param message - unescaped chat messages to send. may need to wrap messages with quotes\n */\n middlePrint(target: string | OmeggaPlayer, message: string): void;\n\n /**\n * Save a minigame preset based on a minigame index\n * @param index minigame index\n * @param name preset name\n */\n saveMinigame(index: number, name: string): void;\n\n /**\n * Delete a minigame\n * @param index minigame index\n */\n deleteMinigame(index: number): void;\n\n /**\n * Reset a minigame\n * @param index minigame index\n */\n resetMinigame(index: number): void;\n\n /**\n * Force the next round in a minigame\n * @param index minigame index\n */\n nextRoundMinigame(index: number): void;\n\n /**\n * Load an Minigame preset\n * @param presetName preset name\n * @param owner owner id/name\n */\n loadMinigame(presetName: string, owner?: string): void;\n\n /**\n * Get all presets in the minigame folder and child folders\n */\n getMinigamePresets(): string[];\n\n /**\n * Reset the environment settings\n */\n resetEnvironment(): void;\n\n /**\n * Save an environment preset\n * @param presetName preset name\n */\n saveEnvironment(presetName: string): Promise<void>;\n\n /** Save a temporary environment preset and return its contents */\n getEnvironmentData(): Promise<EnvironmentPreset>;\n\n /**\n * Read environment data as json\n * @param presetName preset name\n */\n readEnvironmentData(presetName: string): void;\n\n /**\n * Load an environment preset\n * @param presetName preset name\n */\n loadEnvironment(presetName: string): void;\n\n /**\n * Load some environment preset data\n * @param preset preset data\n */\n loadEnvironmentData(\n preset: EnvironmentPreset | EnvironmentPreset['data']['groups'],\n ): void;\n\n /**\n * Get all presets in the environment folder and child folders\n */\n getEnvironmentPresets(): string[];\n\n /**\n * Clear a user's bricks (by uuid, name, controller, or player object)\n * @param target player or player identifier\n * @param quiet quietly clear bricks\n */\n clearBricks(target: string | { id: string }, quiet?: boolean): void;\n\n /**\n * Clear a region of bricks\n * @param region region to clear\n * @param options optional settings\n */\n clearRegion(\n region: {\n center: [number, number, number];\n extent: [number, number, number];\n },\n options?: {\n target?: string | OmeggaPlayer;\n },\n ): void;\n\n /**\n * Clear all bricks on the server\n * @param quiet quietly clear bricks\n */\n clearAllBricks(quiet?: boolean): void;\n\n /**\n * Save bricks under a filename\n * @param saveName save file name\n * @param region region of bricks to save\n */\n saveBricks(\n saveName: string,\n region?: {\n center: [number, number, number];\n extent: [number, number, number];\n },\n ): void;\n\n /**\n * Save bricks under a filename, with a promise\n * @param saveName save file name\n * @param region region of bricks to save\n */\n saveBricksAsync(\n saveName: string,\n region?: {\n center: [number, number, number];\n extent: [number, number, number];\n },\n ): Promise<void>;\n\n /**\n * Load bricks on the server\n */\n loadBricks(\n saveName: string,\n options?: {\n offX?: number;\n offY?: number;\n offZ?: number;\n quiet?: boolean;\n correctPalette?: boolean;\n correctCustom?: boolean;\n },\n ): void;\n\n /**\n * Load bricks on the server into a player's clipbaord\n */\n loadBricksOnPlayer(\n saveName: string,\n player: string | OmeggaPlayer,\n options?: {\n offX?: number;\n offY?: number;\n offZ?: number;\n correctPalette?: boolean;\n correctCustom?: boolean;\n },\n ): void;\n\n /**\n * Get all saves in the save folder and child folders\n */\n getSaves(): string[];\n\n /**\n * Checks if a save exists and returns an absolute path\n * @param saveName Save filename\n * @return Path to string\n */\n getSavePath(saveName: string): string;\n\n /**\n * Get all worlds in the worlds folder and child folders\n */\n getWorlds(): string[];\n\n /**\n * Checks if a world exists and returns an absolute path\n * @param worldName World name\n * @return Path to string\n */\n getWorldPath(worldName: string): string;\n\n /**\n * Get a list of revisions for a world\n * @param worldName World name\n */\n getWorldRevisions(\n worldName: string,\n ): Promise<{ index: number; date: Date; note: string }[]>;\n\n /**\n * Load a world by its name\n * @param worldName World name\n */\n loadWorld(worldName: string): Promise<boolean>;\n\n /**\n * Load a world at a specific revision\n * @param worldName World name\n */\n loadWorldRevision(worldName: string, revision: number): Promise<boolean>;\n\n /**\n * Save a world as a new name\n * @param worldName World name\n */\n saveWorldAs(worldName: string): Promise<boolean>;\n\n /**\n * Save the current world\n */\n saveWorld(): Promise<boolean>;\n\n /**\n * Create an empty world with the given name\n */\n createEmptyWorld(worldName: string): Promise<boolean>;\n\n /**\n * unsafely load save data (wrap in try/catch)\n * @param saveName save file name\n * @param saveData BRS JS Save data\n */\n writeSaveData(saveName: string, saveData: WriteSaveObject): void;\n\n /**\n * unsafely read save data (wrap in try/catch)\n * @param saveName save file name\n * @param nobricks only read save header data\n * @return BRS JS Save Data\n */\n readSaveData(saveName: string, nobricks?: boolean): ReadSaveObject;\n\n /**\n * load bricks from save data and resolve when game finishes loading\n * @param saveData BRS JS Save data\n */\n loadSaveData(\n saveData: WriteSaveObject,\n options?: {\n offX?: number;\n offY?: number;\n offZ?: number;\n quiet?: boolean;\n correctPalette?: boolean;\n correctCustom?: boolean;\n },\n ): Promise<void>;\n\n /**\n * load bricks from save data and resolve when game finishes loading\n * @param saveData BRS JS Save data\n * @param player Player name/id or player object\n */\n loadSaveDataOnPlayer(\n saveData: WriteSaveObject,\n player: string | OmeggaPlayer,\n options?: {\n offX?: number;\n offY?: number;\n offZ?: number;\n correctPalette?: boolean;\n correctCustom?: boolean;\n },\n ): Promise<void>;\n\n /**\n * get current bricks as save data\n */\n getSaveData(region?: {\n center: [number, number, number];\n extent: [number, number, number];\n }): Promise<ReadSaveObject>;\n\n /**\n * Change server map\n * @param map Map name\n */\n changeMap(map: string): Promise<boolean>;\n\n /**\n * Get up-to-date role setup from RoleSetup.json\n */\n getRoleSetup(): BRRoleSetup;\n\n /**\n * Get up-to-date role assignments from RoleAssignment.json\n */\n getRoleAssignments(): BRRoleAssignments;\n\n /**\n * Get up-to-date ban list from BanList.json\n */\n getBanList(): BRBanList;\n\n /**\n * Get up-to-date name cache from PlayerNameCache.json\n */\n getNameCache(): BRPlayerNameCache;\n}\n\n/** A simple document store for plugins */\nexport interface PluginStore<\n Storage extends Record<string, unknown> = Record<string, unknown>,\n> {\n /** Get a value from plugin storage */\n get<T extends keyof Storage>(key: T): Promise<Storage[T]>;\n /** Set a value to plugin storage */\n set<T extends keyof Storage>(key: T, value: Storage[T]): Promise<void>;\n /** Delete a value from plugin storage */\n delete(key: string): Promise<void>;\n /** Wipe all values in plugin storage */\n wipe(): Promise<void>;\n /** Count entries in plugin storage */\n count(): Promise<number>;\n /** Get a list of keys in plugin storage */\n keys(): Promise<(keyof Storage)[]>;\n}\n\n/** A config representative of the config outlined in doc.json */\nexport type PluginConfig<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = T;\n\n/** An omegga plugin */\nexport default abstract class OmeggaPlugin<\n Config extends Record<string, unknown> = Record<string, unknown>,\n Storage extends Record<string, unknown> = Record<string, unknown>,\n> {\n omegga: OmeggaLike;\n config: PluginConfig<Config>;\n store: PluginStore<Storage>;\n\n constructor(\n omegga: OmeggaLike,\n config: PluginConfig<Config>,\n store: PluginStore<Storage>,\n ) {\n this.omegga = omegga;\n this.config = config;\n this.store = store;\n }\n\n /** Run when plugin starts, returns /commands it uses */\n abstract init(): Promise<void | { registeredCommands?: string[] }>;\n\n /** Run when plugin is stopped */\n abstract stop(): Promise<void>;\n\n /** Run when another plugin tries to interact with this plugin\n * @param event Event name\n * @param from Name of origin plugin\n * @return value other plugin expects\n */\n abstract pluginEvent?(\n event: string,\n from: string,\n ...args: any[]\n ): Promise<unknown>;\n}\n\nexport interface LogWrangling {\n /** Add a passive pattern on console output that invokes callback on match */\n addMatcher<T>(\n pattern: IMatcher<T>['pattern'],\n callback: IMatcher<T>['callback'],\n ): void;\n\n /** Run an active pattern on console output that resolves a match */\n addWatcher<T = RegExpMatchArray>(\n pattern: IWatcher<T>['pattern'],\n options?: {\n timeoutDelay?: number;\n bundle?: boolean;\n debounce?: boolean;\n afterMatchDelay?: number;\n last?: IWatcher<T>['last'];\n exec?: () => void;\n },\n ): Promise<IWatcher<T>['matches']>;\n\n /** Run a command and capture bundled output */\n watchLogChunk<T = string>(\n cmd: string,\n pattern: IWatcher<T>['pattern'],\n options?: {\n first?: 'index' | ((match: T) => boolean);\n last?: IWatcher<T>['last'];\n afterMatchDelay?: number;\n timeoutDelay?: number;\n },\n ): Promise<IWatcher<T>['matches']>;\n\n /** Run a command and capture bundled output for array functions */\n watchLogArray<\n Item extends Record<string, string> = Record<string, string>,\n Member extends Record<string, string> = Record<string, string>,\n >(\n cmd: string,\n itemPattern: RegExp,\n memberPattern: RegExp,\n ): Promise<{ item: Item; members: Member[] }[]>;\n}\n\nexport type WatcherPattern<T> = (\n line: string,\n match: RegExpMatchArray,\n) => T | RegExpMatchArray | '[OMEGGA_WATCHER_DONE]';\n\nexport type IMatcher<T> =\n | {\n pattern: RegExp;\n callback: (match: RegExpMatchArray) => boolean;\n }\n | {\n pattern: (line: string, match: RegExpMatchArray) => T;\n callback: (match: RegExpMatchArray) => T;\n };\n\nexport type IWatcher<T> = {\n bundle: boolean;\n debounce: boolean;\n timeoutDelay: number;\n afterMatchDelay: number;\n last: (match: T) => boolean;\n callback: () => void;\n resolve: (...args: any[]) => void;\n remove: () => void;\n done: () => void;\n timeout: ReturnType<typeof setTimeout>;\n} & (\n | {\n pattern: WatcherPattern<T>;\n matches: T[];\n }\n | {\n pattern: RegExp;\n matches: RegExpMatchArray[];\n }\n);\n\nexport declare type IPluginConfigDefinition = {\n description: string;\n} & (\n | {\n type: 'string' | 'password' | 'role';\n default: string;\n }\n | {\n type: 'boolean';\n default: boolean;\n }\n | {\n type: 'number';\n default: number;\n }\n | {\n type: 'enum';\n options: (string | number)[];\n default: string | number;\n }\n | {\n type: 'players';\n default: {\n id: string;\n name: string;\n };\n }\n | ({\n type: 'list';\n } & (\n | {\n itemType: 'string';\n default: string[];\n }\n | {\n itemType: 'number';\n default: number[];\n }\n | {\n itemType: 'enum';\n options: (string | number)[];\n default: string | number;\n }\n ))\n);\nexport interface IPluginCommandArgument {\n name: string;\n description: string;\n required?: boolean;\n}\nexport interface IPluginCommand {\n name: string;\n description: string;\n example?: string;\n args: IPluginCommandArgument[];\n}\nexport interface IPluginDocumentation {\n name: string;\n description: string;\n author: string;\n config: Record<string, IPluginConfigDefinition>;\n commands: IPluginCommand[];\n}\n\nexport interface PluginInterop {\n name: string;\n documentation: IPluginDocumentation;\n loaded: boolean;\n emitPlugin?(event: string, args: any[]): Promise<any>;\n}\n\nexport type WeaponClass =\n | 'Weapon_APCarbine'\n | 'Weapon_AntiMaterielRifle'\n | 'Weapon_ArmingSword'\n | 'Weapon_AssaultRifle'\n | 'Weapon_AutoShotgun'\n | 'Weapon_Battleaxe'\n | 'Weapon_Bazooka'\n | 'Weapon_BoltActionRifle'\n | 'Weapon_Bow'\n | 'Weapon_BoxPistol'\n | 'Weapon_BullpupRifle'\n | 'Weapon_BullpupSMG'\n | 'Weapon_ChargedLongsword'\n | 'Weapon_CrystalKalis'\n | 'Weapon_Derringer'\n | 'Weapon_Dynamite'\n | 'Weapon_FlintlockPistol'\n | 'Weapon_GrenadeLauncher'\n | 'Weapon_GuardPistol'\n | 'Weapon_Handaxe'\n | 'Weapon_HealthPotion'\n | 'Weapon_HeavyAssaultRifle'\n | 'Weapon_HeavySMG'\n | 'Weapon_HeroSword'\n | 'Weapon_HighPowerPistol'\n | 'Weapon_HoloBlade'\n | 'Weapon_HuntingShotgun'\n | 'Weapon_Ikakalaka'\n | 'Weapon_ImpactGrenade'\n | 'Weapon_ImpactGrenadeLauncher'\n | 'Weapon_ImpulseGrenade'\n | 'Weapon_Khopesh'\n | 'Weapon_Knife'\n | 'Weapon_LeverActionRifle'\n | 'Weapon_LightMachineGun'\n | 'Weapon_LongSword'\n | 'Weapon_MagnumPistol'\n | 'Weapon_MicroSMG'\n | 'Weapon_Minigun'\n | 'Weapon_Minigun'\n | 'Weapon_MissileLauncher'\n | 'Weapon_PDW'\n | 'Weapon_Pickaxe'\n | 'Weapon_PipeBomb'\n | 'Weapon_Pistol'\n | 'Weapon_PlasmaPistol'\n | 'Weapon_PlasmaSMG'\n | 'Weapon_PulseCarbine'\n | 'Weapon_PulseRifle'\n | 'Weapon_QuadLauncher'\n | 'Weapon_Revolver'\n | 'Weapon_RocketJumper'\n | 'Weapon_RocketLauncher'\n | 'Weapon_Sabre'\n | 'Weapon_SemiAutoRifle'\n | 'Weapon_ServiceRifle'\n | 'Weapon_Shotgun'\n | 'Weapon_SlugShotgun'\n | 'Weapon_Sniper'\n | 'Weapon_SodaCan'\n | 'Weapon_Spatha'\n | 'Weapon_SportingShotgun'\n | 'Weapon_StampedSMG'\n | 'Weapon_StandardSubmachineGun'\n | 'Weapon_StickGrenade'\n | 'Weapon_SubmachineGun'\n | 'Weapon_SuperShotgun'\n | 'Weapon_SuppressedAssaultRifle'\n | 'Weapon_SuppressedBullpupSMG'\n | 'Weapon_SuppressedGuardPistol'\n | 'Weapon_SuppressedHeavySMG'\n | 'Weapon_SuppressedMicroSMG'\n | 'Weapon_SuppressedPistol'\n | 'Weapon_SuppressedServiceRifle'\n | 'Weapon_TacticalSMG'\n | 'Weapon_TacticalShotgun'\n | 'Weapon_Tomahawk'\n | 'Weapon_TwinCannon'\n | 'Weapon_TypewriterSMG'\n | 'Weapon_Zweihander';\n"],"names":["util"],"mappings":";;;AAgBO,MAAM,uBAAuBA,MAAAA;AA21BpC,MAA8B,aAG5B;AAAA,EAKA,YACE,QACA,QACA,OACA;AACA,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,QAAQ;AAAA,EACf;AAkBF;;;;"}
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["../src/plugin.ts"],"sourcesContent":["import { EnvironmentPreset } from '@brickadia/presets';\nimport {\n BRBanList,\n BRPlayerNameCache,\n BRRoleAssignments,\n BRRoleSetup,\n} from '@brickadia/types';\nimport {\n ILogMinigame,\n IMinigameList,\n IPlayerPositions,\n IServerStatus,\n} from '@omegga/types';\nimport util from '@util';\nimport { ReadSaveObject, WriteSaveObject } from 'brs-js';\n\nexport const _OMEGGA_UTILS_IMPORT = util;\ndeclare global {\n export var Omegga: OmeggaLike;\n export var Player: StaticPlayer;\n export var OMEGGA_UTIL: typeof _OMEGGA_UTILS_IMPORT;\n}\n\nexport * from '@brickadia/types';\nexport * from '@omegga/types';\nexport { OmeggaPlugin };\n\nexport type OL = OmeggaLike;\nexport type OP = OmeggaPlugin;\nexport type PC<T extends Record<string, unknown> = Record<string, unknown>> =\n PluginConfig<T>;\nexport type PS<T extends Record<string, unknown> = Record<string, unknown>> =\n PluginStore<T>;\n\nexport interface BrickBounds {\n minBound: [number, number, number];\n maxBound: [number, number, number];\n center: [number, number, number];\n}\n\n/** Created when a player clicks on a brick with an interact component */\nexport interface BrickInteraction {\n /** Brick name from catalog (Turkey Body, 4x Cube) */\n brick_name: string;\n /** Brick asset name */\n brick_asset: string;\n /** Brick size */\n brick_size: [number, number, number];\n /** Player information, id, name, controller, and pawn */\n player: { id: string; name: string; controller: string; pawn: string };\n /** Brick center position */\n position: [number, number, number];\n\n /** message sent from a brick click interaction */\n message: string;\n /** data parsed from the line (if it starts with json:) */\n data: null | number | string | boolean | Record<string, unknown>;\n /** True when there was a json payload */\n json: boolean;\n /** True when there was a parse error */\n error: boolean;\n}\n\n/** AutoRestart options */\nexport type AutoRestartConfig = {\n players: boolean;\n announcement: boolean;\n saveWorld: boolean;\n};\n\nexport interface OmeggaPlayer {\n /** player name */\n name: string;\n\n /** player display name */\n displayName: string;\n\n /** player uuid */\n id: string;\n\n /** player controller id */\n controller: string;\n\n /** player state id */\n state: string;\n\n /**\n * Returns omegga\n */\n getOmegga(): OmeggaLike;\n\n /**\n * Clone a player\n */\n clone(): OmeggaPlayer;\n\n /**\n * Get raw player info (to feed into a constructor)\n */\n raw(): [string, string, string, string, string];\n\n /**\n * True if the player is the host\n */\n isHost(): boolean;\n\n /**\n * Clear player's bricks\n * @param quiet clear bricks quietly\n */\n clearBricks(quiet?: boolean): void;\n\n /**\n * Get player's roles, if any\n */\n getRoles(): readonly string[];\n\n /**\n * Get player's permissions in a map like `{\"Bricks.ClearOwn\": true, ...}`\n * @return permissions map\n */\n getPermissions(): Record<string, boolean>;\n\n /**\n * Get player's name color\n * @return 6 character hex string\n */\n getNameColor(): string;\n\n /**\n * Get the player's pawn\n * @return pawn\n */\n getPawn(): Promise<string>;\n\n /**\n * Get player's position\n * @return [x, y, z] coordinates\n */\n getPosition(): Promise<[number, number, number]>;\n\n /**\n * Gets a user's ghost brick info (by uuid, name, controller, or player object)\n * @return ghost brick data\n */\n getGhostBrick(): Promise<{\n targetGrid: string;\n location: number[];\n orientation: string;\n }>;\n\n /**\n * gets a user's paint tool properties\n */\n getPaint(): Promise<{\n materialIndex: string;\n materialAlpha: string;\n material: string;\n color: number[];\n }>;\n\n /**\n * gets whether or not the player is crouching\n */\n isCrouched(pawn?: string): Promise<boolean>;\n\n /**\n * gets whether or not the player is dead\n */\n isDead(pawn?: string): Promise<boolean>;\n\n /**\n * Gets the bounds of the template in the user's clipboard (bounds of original selection box)\n * @return template bounds\n */\n getTemplateBounds(): Promise<BrickBounds>;\n\n /**\n * Get bricks inside template bounds\n * @return BRS JS Save Data\n */\n getTemplateBoundsData(): Promise<ReadSaveObject>;\n\n /**\n * Load bricks at ghost brick location\n * @param saveData save data to load\n */\n loadDataAtGhostBrick(\n saveData: WriteSaveObject,\n options?: {\n rotate?: boolean;\n offX?: number;\n offY?: number;\n offZ?: number;\n quiet?: boolean;\n },\n ): Promise<void>;\n\n /**\n * Load bricks on this player's clipboard\n * @param saveName Save to load\n */\n loadBricks(saveName: string): void;\n\n /**\n * Load bricks on this player's clipboard passing save data\n * @param saveData save data to load\n */\n loadSaveData(\n saveData: WriteSaveObject,\n options?: {\n rotate?: boolean;\n offX?: number;\n offY?: number;\n offZ?: number;\n quiet?: boolean;\n },\n ): Promise<void>;\n\n /**\n * Kills this player\n */\n kill(): void;\n\n /**\n * Damages a player\n * @param amount Amount to damage\n */\n damage(amount: number): void;\n\n /**\n * Heal this player\n * @param amount to heal\n */\n heal(amount: number): void;\n\n /**\n * Gives a player an item\n * @param item Item name (Weapon_Bow)\n */\n giveItem(item: WeaponClass): void;\n\n /**\n * Removes an item from a player's inventory\n * @param item Item name (Weapon_Bow)\n */\n takeItem(item: WeaponClass): void;\n\n /**\n * Changes a player's team\n * @param teamIndex Team index\n */\n setTeam(teamIndex: number): void;\n\n /**\n * Changes a player's minigame\n * @param index Minigame index\n */\n setMinigame(index: number): void;\n\n /**\n * Changes a player's score\n * @param minigameIndex minigame index\n * @param score Score\n */\n setScore(minigameIndex: number, score: number): void;\n\n /**\n * Fetch a player's score\n * @param minigameIndex minigame index\n */\n getScore(minigameIndex: number): Promise<number>;\n\n /**\n * Set leaderboard value\n * @param key leaderboard key (Score, Kills, Deaths, CorrectGuesses)\n * @param value leaderboard value\n */\n setLeaderboard(key: string, value: number): void;\n\n /**\n * Get leaderboard value\n * @param key leaderboard key (Score, Kills, Deaths, CorrectGuesses)\n * @return leaderboard value\n */\n getLeaderboard(key: string): Promise<number | null>;\n}\n\nexport interface StaticPlayer {\n /**\n * get a player's roles, if any\n * @param omegga omegga instance\n * @param id player uuid\n * @return list of roles\n */\n getRoles(omegga: OmeggaLike, id: string): readonly string[];\n\n /**\n * get a player's permissions in a map like `{\"Bricks.ClearOwn\": true, ...}`\n * @param omegga Omegga instance\n * @param id player uuid\n * @return permissions map\n */\n getPermissions(omegga: OmeggaLike, id: string): Record<string, boolean>;\n\n /**\n * Kills a player\n * @param omegga Omegga instance\n * @param target Player or player name/id\n */\n kill(omegga: OmeggaLike, target: string | OmeggaPlayer): void;\n\n /**\n * Damages a player\n * @param omegga Omegga instance\n * @param target Player or player name/id\n * @param amount Damage amount\n */\n damage(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n amount: number,\n ): void;\n\n /**\n * Heal a player\n * @param omegga Omegga instance\n * @param target Player or player name/id\n * @param amount Heal amount\n */\n heal(omegga: OmeggaLike, target: string | OmeggaPlayer, amount: number): void;\n\n /**\n * Gives a player an item\n * @param omegga Omegga instance\n * @param target Player or player name/id\n * @param item Item name (Weapon_Bow)\n */\n giveItem(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n item: WeaponClass,\n ): void;\n\n /**\n * Removes an item from a player's inventory\n * @param omegga Omegga instance\n * @param target Player or player name/id\n * @param item Item name (Weapon_Bow)\n */\n takeItem(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n item: WeaponClass,\n ): void;\n\n /**\n * Changes a player's team\n * @param omegga Omegga instance\n * @param target Player or player name/id\n * @param teamIndex Team name? index?\n */\n setTeam(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n teamIndex: number,\n ): void;\n\n /**\n * Changes a player's minigame\n * @param omegga Omegga instance\n * @param target Player or player name/id\n * @param index Minigame index\n */\n setMinigame(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n index: number,\n ): void;\n\n /**\n * Changes a player's score\n * @param omegga Omegga instance\n * @param target Player or player name/id\n * @param minigameIndex minigame index\n * @param score Score\n */\n setScore(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n minigameIndex: number,\n score: number,\n ): void;\n\n /**\n * Fetches a player's score\n * @param omegga Omegga instance\n * @param target Player or player name/id\n * @param minigameIndex minigame index\n */\n getScore(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n minigameIndex: number,\n ): Promise<number>;\n\n /**\n * Set leaderboard value\n * @param omegga Omegga instance\n * @param target Player or player name/id\n * @param key leaderboard key (Score, Kills, Deaths, CorrectGuesses)\n * @param value leaderboard value\n */\n setLeaderboard(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n key: string,\n value: number,\n ): void;\n\n /**\n * Get leaderboard value\n * @param omegga Omegga instance\n * @param target Player or player name/id\n * @param key leaderboard key (Score, Kills, Deaths, CorrectGuesses)\n * @return leaderboard value\n */\n getLeaderboard(\n omegga: OmeggaLike,\n target: string | OmeggaPlayer,\n key: string,\n ): Promise<number | null>;\n}\n\nexport interface InjectedCommands {\n /** Get server status */\n getServerStatus(this: OmeggaLike): Promise<IServerStatus>;\n /** Get a list of minigames and their indices */\n listMinigames(this: OmeggaLike): Promise<IMinigameList>;\n // /** Get all pawn data */\n // getAllPawnData(this: OmeggaLike, fields: PawnDataField[]): void;\n /** Get all player positions and pawns */\n getAllPlayerPositions(this: OmeggaLike): Promise<IPlayerPositions>;\n /** Get minigames and members */\n getMinigames(this: OmeggaLike): Promise<ILogMinigame[]>;\n}\n\nexport interface MockEventEmitter {\n addListener(event: string, listener: Function): this;\n emit(event: string, ...args: any[]): boolean;\n eventNames(): (string | symbol)[];\n getMaxListeners(): number;\n listenerCount(event: string): number;\n listeners(event: string): Function[];\n off(event: string, listener: Function): this;\n on(event: string, listener: Function): this;\n once(event: string, listener: Function): this;\n prependListener(event: string, listener: Function): this;\n prependOnceListener(event: string, listener: Function): this;\n rawListeners(event: string): Function[];\n removeAllListeners(event?: string): this;\n removeListener(event: string, listener: Function): this;\n setMaxListeners(maxListeners: number): this;\n\n on(event: 'close', listener: () => void): this;\n on(event: 'line', listener: (line: string) => void): this;\n on(event: 'start', listener: (info: { map: string }) => void): this;\n on(event: 'version', listener: (version: number) => void): this;\n on(event: 'unauthorized', listener: () => void): this;\n on(event: 'join', listener: (player: OmeggaPlayer) => void): this;\n on(event: 'leave', listener: (player: OmeggaPlayer) => void): this;\n on(event: 'chat', listener: (name: string, message: string) => void): this;\n on(event: 'mapchange', listener: (info: { map: string }) => void): this;\n on(event: 'autorestart', listener: (config: AutoRestartConfig) => void): this;\n on(\n event: 'interact',\n listener: (interaction: BrickInteraction) => void,\n ): this;\n on(\n event: 'minigamejoin',\n listener: (info: {\n player: { name: string; id: string };\n minigameName: string;\n }) => void,\n ): this;\n}\n\nexport interface OmeggaLike\n extends OmeggaCore,\n LogWrangling,\n InjectedCommands,\n MockEventEmitter {\n writeln(line: string): void;\n\n /** game CL version*/\n version: number;\n\n /** verbose logging is enabled*/\n verbose: boolean;\n\n /** list of players */\n players: OmeggaPlayer[];\n\n /** server host */\n host?: { id: string; name: string };\n\n /** server is started */\n started: boolean;\n /** server is starting */\n starting: boolean;\n /** server is stopping */\n stopping: boolean;\n /** current map */\n currentMap: string;\n\n /** path to config files */\n configPath: string;\n /** path to saves */\n savePath: string;\n /** path to worlds */\n worldPath: string;\n /** path to presets */\n presetPath: string;\n /** path to containing dir */\n path: string;\n\n /** get a plugin's name, documentation, and loaded status\n * If run in an unsafe plugin, the emitPlugin method sends events from\n * an \"unsafe\" plugin\n */\n getPlugin(name: string): Promise<PluginInterop>;\n}\n\nexport interface OmeggaCore {\n /**\n * get a list of players\n * @return list of players {id: uuid, name: name} objects\n */\n getPlayers(): {\n id: string;\n name: string;\n displayName: string;\n controller: string;\n state: string;\n }[];\n\n /**\n * find a player by name, id, controller, or state\n * @param target - name, id, controller, or state\n */\n getPlayer(target: string): OmeggaPlayer | null;\n\n /**\n * find a player by rough name, prioritize exact matches and get fuzzier\n * @param name player name, fuzzy\n */\n findPlayerByName(name: string): OmeggaPlayer | null;\n\n /**\n * get the host's ID\n * @return Host Id\n */\n getHostId(): string;\n\n /**\n * broadcast messages to chat\n * messages are broken by new line\n * multiple arguments are additional lines\n * all messages longer than 512 characters are deleted automatically, though omegga wouldn't have sent them anyway\n * @param messages unescaped chat messages to send. may need to wrap messages with quotes\n */\n broadcast(...messages: string[]): void;\n\n /**\n * whisper messages to a player's chat\n * messages are broken by new line\n * multiple arguments are additional lines\n * all messages longer than 512 characters are deleted automatically, though omegga wouldn't have sent them anyway\n * @param target - player identifier or player object\n * @param messages - unescaped chat messages to send. may need to wrap messages with quotes\n */\n whisper(target: string | OmeggaPlayer, ...messages: string[]): void;\n\n /**\n * prints text to the middle of a player's screen\n * all messages longer than 512 characters are deleted automatically\n * @param target - player identifier or player object\n * @param message - unescaped chat messages to send. may need to wrap messages with quotes\n */\n middlePrint(target: string | OmeggaPlayer, message: string): void;\n\n /**\n * Save a minigame preset based on a minigame index\n * @param index minigame index\n * @param name preset name\n */\n saveMinigame(index: number, name: string): void;\n\n /**\n * Delete a minigame\n * @param index minigame index\n */\n deleteMinigame(index: number): void;\n\n /**\n * Reset a minigame\n * @param index minigame index\n */\n resetMinigame(index: number): void;\n\n /**\n * Force the next round in a minigame\n * @param index minigame index\n */\n nextRoundMinigame(index: number): void;\n\n /**\n * Load an Minigame preset\n * @param presetName preset name\n * @param owner owner id/name\n */\n loadMinigame(presetName: string, owner?: string): void;\n\n /**\n * Get all presets in the minigame folder and child folders\n */\n getMinigamePresets(): string[];\n\n /**\n * Reset the environment settings\n */\n resetEnvironment(): void;\n\n /**\n * Save an environment preset\n * @param presetName preset name\n */\n saveEnvironment(presetName: string): Promise<void>;\n\n /** Save a temporary environment preset and return its contents */\n getEnvironmentData(): Promise<EnvironmentPreset>;\n\n /**\n * Read environment data as json\n * @param presetName preset name\n */\n readEnvironmentData(presetName: string): void;\n\n /**\n * Load an environment preset\n * @param presetName preset name\n */\n loadEnvironment(presetName: string): void;\n\n /**\n * Load some environment preset data\n * @param preset preset data\n */\n loadEnvironmentData(\n preset: EnvironmentPreset | EnvironmentPreset['data']['groups'],\n ): void;\n\n /**\n * Get all presets in the environment folder and child folders\n */\n getEnvironmentPresets(): string[];\n\n /**\n * Clear a user's bricks (by uuid, name, controller, or player object)\n * @param target player or player identifier\n * @param quiet quietly clear bricks\n */\n clearBricks(target: string | { id: string }, quiet?: boolean): void;\n\n /**\n * Clear a region of bricks\n * @param region region to clear\n * @param options optional settings\n */\n clearRegion(\n region: {\n center: [number, number, number];\n extent: [number, number, number];\n },\n options?: {\n target?: string | OmeggaPlayer;\n },\n ): void;\n\n /**\n * Clear all bricks on the server\n * @param quiet quietly clear bricks\n */\n clearAllBricks(quiet?: boolean): void;\n\n /**\n * Save bricks under a filename\n * @param saveName save file name\n * @param region region of bricks to save\n */\n saveBricks(\n saveName: string,\n region?: {\n center: [number, number, number];\n extent: [number, number, number];\n },\n ): void;\n\n /**\n * Save bricks under a filename, with a promise\n * @param saveName save file name\n * @param region region of bricks to save\n */\n saveBricksAsync(\n saveName: string,\n region?: {\n center: [number, number, number];\n extent: [number, number, number];\n },\n ): Promise<void>;\n\n /**\n * Load bricks on the server\n */\n loadBricks(\n saveName: string,\n options?: {\n offX?: number;\n offY?: number;\n offZ?: number;\n quiet?: boolean;\n correctPalette?: boolean;\n correctCustom?: boolean;\n },\n ): void;\n\n /**\n * Load bricks on the server into a player's clipbaord\n */\n loadBricksOnPlayer(\n saveName: string,\n player: string | OmeggaPlayer,\n options?: {\n offX?: number;\n offY?: number;\n offZ?: number;\n correctPalette?: boolean;\n correctCustom?: boolean;\n },\n ): void;\n\n /**\n * Get all saves in the save folder and child folders\n */\n getSaves(): string[];\n\n /**\n * Checks if a save exists and returns an absolute path\n * @param saveName Save filename\n * @return Path to string\n */\n getSavePath(saveName: string): string;\n\n /**\n * Get all worlds in the worlds folder and child folders\n */\n getWorlds(): string[];\n\n /**\n * Checks if a world exists and returns an absolute path\n * @param worldName World name\n * @return Path to string\n */\n getWorldPath(worldName: string): string;\n\n /**\n * Get a list of revisions for a world\n * @param worldName World name\n */\n getWorldRevisions(\n worldName: string,\n ): Promise<{ index: number; date: Date; note: string }[]>;\n\n /**\n * Load a world by its name\n * @param worldName World name\n */\n loadWorld(worldName: string): Promise<boolean>;\n\n /**\n * Load a world at a specific revision\n * @param worldName World name\n */\n loadWorldRevision(worldName: string, revision: number): Promise<boolean>;\n\n /**\n * Save a world as a new name\n * @param worldName World name\n */\n saveWorldAs(worldName: string): Promise<boolean>;\n\n /**\n * Save the current world\n */\n saveWorld(): Promise<boolean>;\n\n /**\n * Create an empty world with the given name\n */\n createEmptyWorld(worldName: string): Promise<boolean>;\n\n /**\n * unsafely load save data (wrap in try/catch)\n * @param saveName save file name\n * @param saveData BRS JS Save data\n */\n writeSaveData(saveName: string, saveData: WriteSaveObject): void;\n\n /**\n * unsafely read save data (wrap in try/catch)\n * @param saveName save file name\n * @param nobricks only read save header data\n * @return BRS JS Save Data\n */\n readSaveData(saveName: string, nobricks?: boolean): ReadSaveObject;\n\n /**\n * load bricks from save data and resolve when game finishes loading\n * @param saveData BRS JS Save data\n */\n loadSaveData(\n saveData: WriteSaveObject,\n options?: {\n offX?: number;\n offY?: number;\n offZ?: number;\n quiet?: boolean;\n correctPalette?: boolean;\n correctCustom?: boolean;\n },\n ): Promise<void>;\n\n /**\n * load bricks from save data and resolve when game finishes loading\n * @param saveData BRS JS Save data\n * @param player Player name/id or player object\n */\n loadSaveDataOnPlayer(\n saveData: WriteSaveObject,\n player: string | OmeggaPlayer,\n options?: {\n offX?: number;\n offY?: number;\n offZ?: number;\n correctPalette?: boolean;\n correctCustom?: boolean;\n },\n ): Promise<void>;\n\n /**\n * get current bricks as save data\n */\n getSaveData(region?: {\n center: [number, number, number];\n extent: [number, number, number];\n }): Promise<ReadSaveObject>;\n\n /**\n * Change server map\n * @param map Map name\n */\n changeMap(map: string): Promise<boolean>;\n\n /**\n * Get up-to-date role setup from RoleSetup.json\n */\n getRoleSetup(): BRRoleSetup;\n\n /**\n * Get up-to-date role assignments from RoleAssignment.json\n */\n getRoleAssignments(): BRRoleAssignments;\n\n /**\n * Get up-to-date ban list from BanList.json\n */\n getBanList(): BRBanList;\n\n /**\n * Get up-to-date name cache from PlayerNameCache.json\n */\n getNameCache(): BRPlayerNameCache;\n}\n\n/** A simple document store for plugins */\nexport interface PluginStore<\n Storage extends Record<string, unknown> = Record<string, unknown>,\n> {\n /** Get a value from plugin storage */\n get<T extends keyof Storage>(key: T): Promise<Storage[T]>;\n /** Set a value to plugin storage */\n set<T extends keyof Storage>(key: T, value: Storage[T]): Promise<void>;\n /** Delete a value from plugin storage */\n delete(key: string): Promise<void>;\n /** Wipe all values in plugin storage */\n wipe(): Promise<void>;\n /** Count entries in plugin storage */\n count(): Promise<number>;\n /** Get a list of keys in plugin storage */\n keys(): Promise<(keyof Storage)[]>;\n}\n\n/** A config representative of the config outlined in doc.json */\nexport type PluginConfig<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = T;\n\n/** An omegga plugin */\nexport default abstract class OmeggaPlugin<\n Config extends Record<string, unknown> = Record<string, unknown>,\n Storage extends Record<string, unknown> = Record<string, unknown>,\n> {\n omegga: OmeggaLike;\n config: PluginConfig<Config>;\n store: PluginStore<Storage>;\n\n constructor(\n omegga: OmeggaLike,\n config: PluginConfig<Config>,\n store: PluginStore<Storage>,\n ) {\n this.omegga = omegga;\n this.config = config;\n this.store = store;\n }\n\n /** Run when plugin starts, returns /commands it uses */\n abstract init(): Promise<void | { registeredCommands?: string[] }>;\n\n /** Run when plugin is stopped */\n abstract stop(): Promise<void>;\n\n /** Run when another plugin tries to interact with this plugin\n * @param event Event name\n * @param from Name of origin plugin\n * @return value other plugin expects\n */\n abstract pluginEvent?(\n event: string,\n from: string,\n ...args: any[]\n ): Promise<unknown>;\n}\n\nexport interface LogWrangling {\n /** Add a passive pattern on console output that invokes callback on match */\n addMatcher<T>(\n pattern: IMatcher<T>['pattern'],\n callback: IMatcher<T>['callback'],\n ): void;\n\n /** Run an active pattern on console output that resolves a match */\n addWatcher<T = RegExpMatchArray>(\n pattern: IWatcher<T>['pattern'],\n options?: {\n timeoutDelay?: number;\n bundle?: boolean;\n debounce?: boolean;\n afterMatchDelay?: number;\n last?: IWatcher<T>['last'];\n exec?: () => void;\n },\n ): Promise<IWatcher<T>['matches']>;\n\n /** Run a command and capture bundled output */\n watchLogChunk<T = string>(\n cmd: string,\n pattern: IWatcher<T>['pattern'],\n options?: {\n first?: 'index' | ((match: T) => boolean);\n last?: IWatcher<T>['last'];\n afterMatchDelay?: number;\n timeoutDelay?: number;\n },\n ): Promise<IWatcher<T>['matches']>;\n\n /** Run a command and capture bundled output for array functions */\n watchLogArray<\n Item extends Record<string, string> = Record<string, string>,\n Member extends Record<string, string> = Record<string, string>,\n >(\n cmd: string,\n itemPattern: RegExp,\n memberPattern: RegExp,\n ): Promise<{ item: Item; members: Member[] }[]>;\n}\n\nexport type WatcherPattern<T> = (\n line: string,\n match: RegExpMatchArray,\n) => T | RegExpMatchArray | '[OMEGGA_WATCHER_DONE]';\n\nexport type IMatcher<T> =\n | {\n pattern: RegExp;\n callback: (match: RegExpMatchArray) => boolean;\n }\n | {\n pattern: (line: string, match: RegExpMatchArray) => T;\n callback: (match: RegExpMatchArray) => T;\n };\n\nexport type IWatcher<T> = {\n bundle: boolean;\n debounce: boolean;\n timeoutDelay: number;\n afterMatchDelay: number;\n last: (match: T) => boolean;\n callback: () => void;\n resolve: (...args: any[]) => void;\n remove: () => void;\n done: () => void;\n timeout: ReturnType<typeof setTimeout>;\n} & (\n | {\n pattern: WatcherPattern<T>;\n matches: T[];\n }\n | {\n pattern: RegExp;\n matches: RegExpMatchArray[];\n }\n);\n\nexport declare type IPluginConfigDefinition = {\n description: string;\n} & (\n | {\n type: 'string' | 'password' | 'role';\n default: string;\n }\n | {\n type: 'boolean';\n default: boolean;\n }\n | {\n type: 'number';\n default: number;\n }\n | {\n type: 'enum';\n options: (string | number)[];\n default: string | number;\n }\n | {\n type: 'players';\n default: {\n id: string;\n name: string;\n };\n }\n | ({\n type: 'list';\n } & (\n | {\n itemType: 'string';\n default: string[];\n }\n | {\n itemType: 'number';\n default: number[];\n }\n | {\n itemType: 'enum';\n options: (string | number)[];\n default: string | number;\n }\n ))\n);\nexport interface IPluginCommandArgument {\n name: string;\n description: string;\n required?: boolean;\n}\nexport interface IPluginCommand {\n name: string;\n description: string;\n example?: string;\n args: IPluginCommandArgument[];\n}\nexport interface IPluginDocumentation {\n name: string;\n description: string;\n author: string;\n config: Record<string, IPluginConfigDefinition>;\n commands: IPluginCommand[];\n}\n\nexport interface PluginInterop {\n name: string;\n documentation: IPluginDocumentation;\n loaded: boolean;\n emitPlugin?(event: string, args: any[]): Promise<any>;\n}\n\nexport type WeaponClass =\n | 'Weapon_APCarbine'\n | 'Weapon_AntiMaterielRifle'\n | 'Weapon_ArmingSword'\n | 'Weapon_AssaultRifle'\n | 'Weapon_AutoShotgun'\n | 'Weapon_Battleaxe'\n | 'Weapon_Bazooka'\n | 'Weapon_BoltActionRifle'\n | 'Weapon_Bow'\n | 'Weapon_BoxPistol'\n | 'Weapon_BullpupRifle'\n | 'Weapon_BullpupSMG'\n | 'Weapon_ChargedLongsword'\n | 'Weapon_CrystalKalis'\n | 'Weapon_Derringer'\n | 'Weapon_Dynamite'\n | 'Weapon_FlintlockPistol'\n | 'Weapon_GrenadeLauncher'\n | 'Weapon_GuardPistol'\n | 'Weapon_Handaxe'\n | 'Weapon_HealthPotion'\n | 'Weapon_HeavyAssaultRifle'\n | 'Weapon_HeavySMG'\n | 'Weapon_HeroSword'\n | 'Weapon_HighPowerPistol'\n | 'Weapon_HoloBlade'\n | 'Weapon_HuntingShotgun'\n | 'Weapon_Ikakalaka'\n | 'Weapon_ImpactGrenade'\n | 'Weapon_ImpactGrenadeLauncher'\n | 'Weapon_ImpulseGrenade'\n | 'Weapon_Khopesh'\n | 'Weapon_Knife'\n | 'Weapon_LeverActionRifle'\n | 'Weapon_LightMachineGun'\n | 'Weapon_LongSword'\n | 'Weapon_MagnumPistol'\n | 'Weapon_MicroSMG'\n | 'Weapon_Minigun'\n | 'Weapon_Minigun'\n | 'Weapon_MissileLauncher'\n | 'Weapon_PDW'\n | 'Weapon_Pickaxe'\n | 'Weapon_PipeBomb'\n | 'Weapon_Pistol'\n | 'Weapon_PlasmaPistol'\n | 'Weapon_PlasmaSMG'\n | 'Weapon_PulseCarbine'\n | 'Weapon_PulseRifle'\n | 'Weapon_QuadLauncher'\n | 'Weapon_Revolver'\n | 'Weapon_RocketJumper'\n | 'Weapon_RocketLauncher'\n | 'Weapon_Sabre'\n | 'Weapon_SemiAutoRifle'\n | 'Weapon_ServiceRifle'\n | 'Weapon_Shotgun'\n | 'Weapon_SlugShotgun'\n | 'Weapon_Sniper'\n | 'Weapon_SodaCan'\n | 'Weapon_Spatha'\n | 'Weapon_SportingShotgun'\n | 'Weapon_StampedSMG'\n | 'Weapon_StandardSubmachineGun'\n | 'Weapon_StickGrenade'\n | 'Weapon_SubmachineGun'\n | 'Weapon_SuperShotgun'\n | 'Weapon_SuppressedAssaultRifle'\n | 'Weapon_SuppressedBullpupSMG'\n | 'Weapon_SuppressedGuardPistol'\n | 'Weapon_SuppressedHeavySMG'\n | 'Weapon_SuppressedMicroSMG'\n | 'Weapon_SuppressedPistol'\n | 'Weapon_SuppressedServiceRifle'\n | 'Weapon_TacticalSMG'\n | 'Weapon_TacticalShotgun'\n | 'Weapon_Tomahawk'\n | 'Weapon_TwinCannon'\n | 'Weapon_TypewriterSMG'\n | 'Weapon_Zweihander';\n"],"names":["util"],"mappings":";;;AAgBO,MAAM,uBAAuBA,MAAAA;AAs4BpC,MAA8B,aAG5B;AAAA,EAKA,YACE,QACA,QACA,OACA;AACA,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,QAAQ;AAAA,EACf;AAkBF;;;;"}
|