omegga 1.4.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/.claude/settings.local.json +17 -0
  2. package/README.md +9 -0
  3. package/bin/omegga +1 -1
  4. package/dist/index.js +6 -6
  5. package/dist/omegga/plugin/plugin_node_unsafe.js +6 -0
  6. package/dist/omegga/plugin/plugin_node_unsafe.js.map +1 -1
  7. package/dist/omegga/server.js +35 -1
  8. package/dist/omegga/server.js.map +1 -1
  9. package/dist/omegga/wrapper.js +1 -0
  10. package/dist/omegga/wrapper.js.map +1 -1
  11. package/dist/plugin.js +1 -2
  12. package/dist/plugin.js.map +1 -1
  13. package/dist/updater/steam.js +49 -1
  14. package/dist/updater/steam.js.map +1 -1
  15. package/dist/util/brick/checkBounds.js +1 -2
  16. package/dist/util/brick/checkBounds.js.map +1 -1
  17. package/dist/util/brick/displayName.js +1 -2
  18. package/dist/util/brick/displayName.js.map +1 -1
  19. package/dist/util/brick/getBounds.js +1 -2
  20. package/dist/util/brick/getBounds.js.map +1 -1
  21. package/dist/util/brick/getBrickSize.js +1 -2
  22. package/dist/util/brick/getBrickSize.js.map +1 -1
  23. package/dist/util/brick/getScaleAxis.js +1 -2
  24. package/dist/util/brick/getScaleAxis.js.map +1 -1
  25. package/dist/util/brick/setOwnership.js +1 -2
  26. package/dist/util/brick/setOwnership.js.map +1 -1
  27. package/dist/webserver/backend/api.js +2 -1
  28. package/dist/webserver/backend/api.js.map +1 -1
  29. package/dist/webserver/backend/database.js +3 -1
  30. package/dist/webserver/backend/database.js.map +1 -1
  31. package/package.json +1 -1
  32. package/public/app.html +3 -3
  33. package/public/assets/{app-nJIpyOiP.js → app-S3WcjD4u.js} +4 -4
  34. package/public/assets/{app-nJIpyOiP.js.map → app-S3WcjD4u.js.map} +1 -1
  35. package/public/assets/client-BT1QYH0O.js.map +1 -1
  36. package/public/assets/{index-3dNmNZ9B.js → index-Cz1Unv84.js} +5 -5
  37. package/public/assets/{index-3dNmNZ9B.js.map → index-Cz1Unv84.js.map} +1 -1
  38. package/public/assets/shared/{@components-DdtLZOaA.js → @components-Bt_lv7Wa.js} +2 -2
  39. package/public/assets/shared/@components-Bt_lv7Wa.js.map +1 -0
  40. package/public/auth.html +1 -1
  41. package/public/assets/shared/@components-DdtLZOaA.js.map +0 -1
@@ -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 /**\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;;;;"}
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;;;"}
@@ -6,6 +6,36 @@ const node_child_process = require("node:child_process");
6
6
  const fs = require("node:fs");
7
7
  const path = require("node:path");
8
8
  const acfParser = require("steam-acf2json");
9
+ const STEAM_APP_STATES = {
10
+ 1: "Uninstalled",
11
+ 2: "Update Required",
12
+ 4: "Fully Installed",
13
+ 8: "Encrypted",
14
+ 16: "Locked",
15
+ 32: "Files Missing",
16
+ 64: "App Running",
17
+ 128: "Files Corrupt",
18
+ 256: "Update Running",
19
+ 512: "Update Paused",
20
+ 1024: "Update Started",
21
+ 2048: "Uninstalling",
22
+ 4096: "Backup Running",
23
+ 65536: "Reconfiguring",
24
+ 131072: "Validating",
25
+ 262144: "Adding Files",
26
+ 524288: "Preallocating",
27
+ 1048576: "Downloading",
28
+ 2097152: "Staging",
29
+ 4194304: "Committing",
30
+ 8388608: "Update Stopping"
31
+ };
32
+ function decodeAppState(state) {
33
+ const flags = [];
34
+ for (const [bit, name] of Object.entries(STEAM_APP_STATES)) {
35
+ if (state & Number(bit)) flags.push(name);
36
+ }
37
+ return flags;
38
+ }
9
39
  function steamcmdDownloadSelf() {
10
40
  node_child_process.execSync(path.join(__dirname, "../../tools/install_steamcmd.sh"), {
11
41
  stdio: "inherit"
@@ -32,7 +62,25 @@ function steamcmdDownloadGame({
32
62
  steambeta && steambetaPassword ? `-betapassword ${steambetaPassword}` : null,
33
63
  "+quit"
34
64
  ].filter(Boolean);
35
- node_child_process.execSync(`${softconfig.STEAMCMD_PATH} ${args.join(" ")}`, { stdio: "inherit" });
65
+ try {
66
+ node_child_process.execSync(`${softconfig.STEAMCMD_PATH} ${args.join(" ")}`, { stdio: "inherit" });
67
+ } catch (err) {
68
+ if (err instanceof Error && err.message) {
69
+ const stateMatch = err.message.match(
70
+ /state is (0x[0-9A-Fa-f]+) after update job/
71
+ );
72
+ if (stateMatch) {
73
+ const state = parseInt(stateMatch[1], 16);
74
+ const flags = decodeAppState(state);
75
+ logger.default.error(
76
+ `Steam app state ${stateMatch[1]} (${state}):`,
77
+ flags.length > 0 ? flags.join(", ") : "Unknown"
78
+ );
79
+ }
80
+ err.message = err.message.replace(/\+login\s+"[^"]*"\s+"[^"]*"/, "+login <REDACTED>").replace(/\+login\s+(\S+)\s+\S+/, "+login $1 <REDACTED>").replace(/-betapassword\s+\S+/, "-betapassword <REDACTED>");
81
+ }
82
+ throw err;
83
+ }
36
84
  }
37
85
  async function fetchSteamInfo() {
38
86
  const appId = softconfig.getAppId();
@@ -1 +1 @@
1
- {"version":3,"file":"steam.js","sources":["../../src/updater/steam.ts"],"sourcesContent":["import Logger from '@/logger';\nimport { getAppId, getSteamInstallDir, STEAMCMD_PATH } from '@/softconfig';\nimport { execSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport path from 'node:path';\nimport acfParser from 'steam-acf2json';\n\nexport function steamcmdDownloadSelf() {\n execSync(path.join(__dirname, '../../tools/install_steamcmd.sh'), {\n stdio: 'inherit',\n });\n}\n\nexport function steamcmdDownloadGame({\n steambeta,\n steambetaPassword,\n}: {\n steambeta?: string;\n steambetaPassword?: string;\n} = {}) {\n let steamLogin = 'anonymous';\n if (process.env.STEAM_USERNAME && process.env.STEAM_PASSWORD) {\n Logger.verbose('Using provided Steam credentials for download.');\n steamLogin = `\"${process.env.STEAM_USERNAME}\" \"${process.env.STEAM_PASSWORD}\"`;\n }\n const installDir = getSteamInstallDir();\n const appId = getAppId();\n\n Logger.verbose('Using with steam install dir:', installDir.yellow);\n Logger.verbose('Using with app ID:', appId.yellow);\n\n const args = [\n `+force_install_dir ${path.join(installDir, steambeta ?? 'main')}`,\n `+login ${steamLogin}`,\n `+app_update ${appId}`,\n steambeta ? `-beta ${steambeta}` : null,\n steambeta && steambetaPassword\n ? `-betapassword ${steambetaPassword}`\n : null,\n '+quit',\n ].filter(Boolean);\n\n execSync(`${STEAMCMD_PATH} ${args.join(' ')}`, { stdio: 'inherit' });\n}\n\nexport type SteamInfo = {\n data: Record<\n string,\n {\n _change_number: number;\n _missing_token: boolean;\n _sha: string;\n _size: number;\n appid: number;\n common: unknown;\n config: unknown;\n depots: Record<\n string,\n {\n config: { oslist: 'linux' | 'windows' | 'macos' };\n }\n > & {\n branches: Record<\n string,\n {\n buildid: string;\n timeupdated: string;\n description?: string;\n }\n >;\n privatebranches: '1';\n };\n }\n >;\n status: 'success';\n};\n\nasync function fetchSteamInfo() {\n const appId = getAppId();\n const res = await fetch('https://api.steamcmd.net/v1/info/' + appId);\n const json = await res.json();\n return json as SteamInfo;\n}\n\nexport type SteamAcf = {\n AppState: {\n appid: string;\n buildid: string;\n lastupdated: string;\n };\n};\n\nfunction getSteamAcf(steambeta?: string) {\n const appId = getAppId();\n const installDir = path.join(getSteamInstallDir(), steambeta ?? 'main');\n const acfPath = path.join(\n installDir,\n 'steamapps',\n `appmanifest_${appId}.acf`,\n );\n if (!existsSync(acfPath)) {\n Logger.verbose(`File not found: ${acfPath}`);\n return null;\n }\n try {\n const plaintext = readFileSync(acfPath, 'utf-8');\n const json = acfParser.decode(plaintext);\n return json as SteamAcf;\n } catch (err) {\n Logger.error(`Error parsing ACF file ${acfPath}:`, err);\n return null;\n }\n}\n\nfunction getSteamDepot(info: SteamInfo, branch?: string) {\n const appId = getAppId();\n const depot =\n info.data[appId]?.depots?.branches?.[\n !branch || branch === 'main' ? 'public' : branch\n ];\n if (\n !depot ||\n typeof depot !== 'object' ||\n !('buildid' in depot) ||\n !('timeupdated' in depot)\n )\n return null;\n return {\n buildId: depot.buildid,\n timeUpdated: Number(depot.timeupdated),\n };\n}\n\nfunction getSteamAcfDepot(acf: SteamAcf) {\n const appId = getAppId();\n const appState = acf.AppState;\n if (\n !appState ||\n typeof appState !== 'object' ||\n appState.appid !== appId ||\n !('buildid' in appState) ||\n !('lastupdated' in appState)\n )\n return null;\n return {\n buildId: appState.buildid,\n timeUpdated: Number(appState.lastupdated),\n };\n}\n\nexport function getLocalSteamDepot(steambeta?: string) {\n const acf = getSteamAcf(steambeta);\n if (!acf) return null;\n const depot = getSteamAcfDepot(acf);\n if (!depot) return null;\n return depot;\n}\n\nexport async function getRemoteSteamDepot(steambeta?: string) {\n const info = await fetchSteamInfo();\n if (!info || !info.data) {\n return null;\n }\n const depot = getSteamDepot(info, steambeta);\n if (!depot) return null;\n return depot;\n}\n\nlet lastUpdateCheck = 0;\nlet lastUpdateAvailable = 0;\nlet lastUpdateResult = false;\n\nexport const getLastSteamUpdateCheck = () => ({\n attempt: lastUpdateCheck,\n available: lastUpdateAvailable,\n result: lastUpdateResult,\n});\n\nexport const clearLastSteamUpdateCheck = () => {\n lastUpdateResult = false;\n};\n\nexport async function hasSteamUpdate(steambeta?: string) {\n lastUpdateCheck = Date.now();\n const localDepot = getLocalSteamDepot(steambeta);\n if (!localDepot) return false;\n\n const remoteDepot = await getRemoteSteamDepot(steambeta);\n if (!remoteDepot) return false;\n\n lastUpdateAvailable = Date.now();\n const res =\n localDepot.buildId !== remoteDepot.buildId ||\n localDepot.timeUpdated < remoteDepot.timeUpdated;\n lastUpdateResult = res;\n\n return res;\n}\n"],"names":["execSync","Logger","getSteamInstallDir","getAppId","STEAMCMD_PATH","existsSync","readFileSync"],"mappings":"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"}
1
+ {"version":3,"file":"steam.js","sources":["../../src/updater/steam.ts"],"sourcesContent":["import Logger from '@/logger';\nimport { getAppId, getSteamInstallDir, STEAMCMD_PATH } from '@/softconfig';\nimport { execSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport path from 'node:path';\nimport acfParser from 'steam-acf2json';\n\n// Steam EAppState flags (bitmask)\nconst STEAM_APP_STATES: Record<number, string> = {\n 0x1: 'Uninstalled',\n 0x2: 'Update Required',\n 0x4: 'Fully Installed',\n 0x8: 'Encrypted',\n 0x10: 'Locked',\n 0x20: 'Files Missing',\n 0x40: 'App Running',\n 0x80: 'Files Corrupt',\n 0x100: 'Update Running',\n 0x200: 'Update Paused',\n 0x400: 'Update Started',\n 0x800: 'Uninstalling',\n 0x1000: 'Backup Running',\n 0x10000: 'Reconfiguring',\n 0x20000: 'Validating',\n 0x40000: 'Adding Files',\n 0x80000: 'Preallocating',\n 0x100000: 'Downloading',\n 0x200000: 'Staging',\n 0x400000: 'Committing',\n 0x800000: 'Update Stopping',\n};\n\nfunction decodeAppState(state: number): string[] {\n const flags: string[] = [];\n for (const [bit, name] of Object.entries(STEAM_APP_STATES)) {\n if (state & Number(bit)) flags.push(name);\n }\n return flags;\n}\n\nexport function steamcmdDownloadSelf() {\n execSync(path.join(__dirname, '../../tools/install_steamcmd.sh'), {\n stdio: 'inherit',\n });\n}\n\nexport function steamcmdDownloadGame({\n steambeta,\n steambetaPassword,\n}: {\n steambeta?: string;\n steambetaPassword?: string;\n} = {}) {\n let steamLogin = 'anonymous';\n if (process.env.STEAM_USERNAME && process.env.STEAM_PASSWORD) {\n Logger.verbose('Using provided Steam credentials for download.');\n steamLogin = `\"${process.env.STEAM_USERNAME}\" \"${process.env.STEAM_PASSWORD}\"`;\n }\n const installDir = getSteamInstallDir();\n const appId = getAppId();\n\n Logger.verbose('Using with steam install dir:', installDir.yellow);\n Logger.verbose('Using with app ID:', appId.yellow);\n\n const args = [\n `+force_install_dir ${path.join(installDir, steambeta ?? 'main')}`,\n `+login ${steamLogin}`,\n `+app_update ${appId}`,\n steambeta ? `-beta ${steambeta}` : null,\n steambeta && steambetaPassword\n ? `-betapassword ${steambetaPassword}`\n : null,\n '+quit',\n ].filter(Boolean);\n\n try {\n execSync(`${STEAMCMD_PATH} ${args.join(' ')}`, { stdio: 'inherit' });\n } catch (err) {\n if (err instanceof Error && err.message) {\n // Log decoded app state if present\n const stateMatch = err.message.match(\n /state is (0x[0-9A-Fa-f]+) after update job/,\n );\n if (stateMatch) {\n const state = parseInt(stateMatch[1], 16);\n const flags = decodeAppState(state);\n Logger.error(\n `Steam app state ${stateMatch[1]} (${state}):`,\n flags.length > 0 ? flags.join(', ') : 'Unknown',\n );\n }\n\n // Redact credentials from error messages\n err.message = err.message\n .replace(/\\+login\\s+\"[^\"]*\"\\s+\"[^\"]*\"/, '+login <REDACTED>')\n .replace(/\\+login\\s+(\\S+)\\s+\\S+/, '+login $1 <REDACTED>')\n .replace(/-betapassword\\s+\\S+/, '-betapassword <REDACTED>');\n }\n throw err;\n }\n}\n\nexport type SteamInfo = {\n data: Record<\n string,\n {\n _change_number: number;\n _missing_token: boolean;\n _sha: string;\n _size: number;\n appid: number;\n common: unknown;\n config: unknown;\n depots: Record<\n string,\n {\n config: { oslist: 'linux' | 'windows' | 'macos' };\n }\n > & {\n branches: Record<\n string,\n {\n buildid: string;\n timeupdated: string;\n description?: string;\n }\n >;\n privatebranches: '1';\n };\n }\n >;\n status: 'success';\n};\n\nasync function fetchSteamInfo() {\n const appId = getAppId();\n const res = await fetch('https://api.steamcmd.net/v1/info/' + appId);\n const json = await res.json();\n return json as SteamInfo;\n}\n\nexport type SteamAcf = {\n AppState: {\n appid: string;\n buildid: string;\n lastupdated: string;\n };\n};\n\nfunction getSteamAcf(steambeta?: string) {\n const appId = getAppId();\n const installDir = path.join(getSteamInstallDir(), steambeta ?? 'main');\n const acfPath = path.join(\n installDir,\n 'steamapps',\n `appmanifest_${appId}.acf`,\n );\n if (!existsSync(acfPath)) {\n Logger.verbose(`File not found: ${acfPath}`);\n return null;\n }\n try {\n const plaintext = readFileSync(acfPath, 'utf-8');\n const json = acfParser.decode(plaintext);\n return json as SteamAcf;\n } catch (err) {\n Logger.error(`Error parsing ACF file ${acfPath}:`, err);\n return null;\n }\n}\n\nfunction getSteamDepot(info: SteamInfo, branch?: string) {\n const appId = getAppId();\n const depot =\n info.data[appId]?.depots?.branches?.[\n !branch || branch === 'main' ? 'public' : branch\n ];\n if (\n !depot ||\n typeof depot !== 'object' ||\n !('buildid' in depot) ||\n !('timeupdated' in depot)\n )\n return null;\n return {\n buildId: depot.buildid,\n timeUpdated: Number(depot.timeupdated),\n };\n}\n\nfunction getSteamAcfDepot(acf: SteamAcf) {\n const appId = getAppId();\n const appState = acf.AppState;\n if (\n !appState ||\n typeof appState !== 'object' ||\n appState.appid !== appId ||\n !('buildid' in appState) ||\n !('lastupdated' in appState)\n )\n return null;\n return {\n buildId: appState.buildid,\n timeUpdated: Number(appState.lastupdated),\n };\n}\n\nexport function getLocalSteamDepot(steambeta?: string) {\n const acf = getSteamAcf(steambeta);\n if (!acf) return null;\n const depot = getSteamAcfDepot(acf);\n if (!depot) return null;\n return depot;\n}\n\nexport async function getRemoteSteamDepot(steambeta?: string) {\n const info = await fetchSteamInfo();\n if (!info || !info.data) {\n return null;\n }\n const depot = getSteamDepot(info, steambeta);\n if (!depot) return null;\n return depot;\n}\n\nlet lastUpdateCheck = 0;\nlet lastUpdateAvailable = 0;\nlet lastUpdateResult = false;\n\nexport const getLastSteamUpdateCheck = () => ({\n attempt: lastUpdateCheck,\n available: lastUpdateAvailable,\n result: lastUpdateResult,\n});\n\nexport const clearLastSteamUpdateCheck = () => {\n lastUpdateResult = false;\n};\n\nexport async function hasSteamUpdate(steambeta?: string) {\n lastUpdateCheck = Date.now();\n const localDepot = getLocalSteamDepot(steambeta);\n if (!localDepot) return false;\n\n const remoteDepot = await getRemoteSteamDepot(steambeta);\n if (!remoteDepot) return false;\n\n lastUpdateAvailable = Date.now();\n const res =\n localDepot.buildId !== remoteDepot.buildId ||\n localDepot.timeUpdated < remoteDepot.timeUpdated;\n lastUpdateResult = res;\n\n return res;\n}\n"],"names":["execSync","Logger","getSteamInstallDir","getAppId","STEAMCMD_PATH","existsSync","readFileSync"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const getScaleAxis = require("./getScaleAxis.js");
4
4
  const getBrickSize = require("./getBrickSize.js");
5
5
  function checkBound(brick, brick_assets, bounds, axis) {
@@ -13,5 +13,4 @@ function checkBounds(brick, brick_assets, bounds) {
13
13
  return checkBound(brick, brick_assets, bounds, 0) && checkBound(brick, brick_assets, bounds, 1) && checkBound(brick, brick_assets, bounds, 2);
14
14
  }
15
15
  exports.checkBounds = checkBounds;
16
- exports.default = checkBounds;
17
16
  //# sourceMappingURL=checkBounds.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"checkBounds.js","sources":["../../../src/util/brick/checkBounds.ts"],"sourcesContent":["import { Brick, Vector } from 'brs-js';\n\nimport { getScaleAxis } from './getScaleAxis';\nimport { getBrickSize } from './getBrickSize';\n\nexport interface IBrickBounds {\n minBound: Vector;\n maxBound: Vector;\n center: Vector;\n}\n\n// check if the brick is in bounds for 1 axis\nfunction checkBound(\n brick: Brick,\n brick_assets: string[],\n bounds: IBrickBounds,\n axis: number,\n) {\n const scaleAxis = getScaleAxis(brick, axis);\n const size = getBrickSize(brick, brick_assets);\n const upper = brick.position[axis] + size[scaleAxis];\n const lower = brick.position[axis] - size[scaleAxis];\n return upper <= bounds.maxBound[axis] && lower >= bounds.minBound[axis];\n}\n\n// check if the brick is in bounds\nexport function checkBounds(\n brick: Brick,\n brick_assets: string[],\n bounds: IBrickBounds,\n) {\n return (\n checkBound(brick, brick_assets, bounds, 0) &&\n checkBound(brick, brick_assets, bounds, 1) &&\n checkBound(brick, brick_assets, bounds, 2)\n );\n}\nexport default checkBounds;\n"],"names":["getScaleAxis","getBrickSize"],"mappings":";;;;AAYA,SAAS,WACP,OACA,cACA,QACA,MACA;AACA,QAAM,YAAYA,aAAAA,aAAa,OAAO,IAAI;AAC1C,QAAM,OAAOC,aAAAA,aAAa,OAAO,YAAY;AAC7C,QAAM,QAAQ,MAAM,SAAS,IAAI,IAAI,KAAK,SAAS;AACnD,QAAM,QAAQ,MAAM,SAAS,IAAI,IAAI,KAAK,SAAS;AACnD,SAAO,SAAS,OAAO,SAAS,IAAI,KAAK,SAAS,OAAO,SAAS,IAAI;AACxE;AAGO,SAAS,YACd,OACA,cACA,QACA;AACA,SACE,WAAW,OAAO,cAAc,QAAQ,CAAC,KACzC,WAAW,OAAO,cAAc,QAAQ,CAAC,KACzC,WAAW,OAAO,cAAc,QAAQ,CAAC;AAE7C;;;"}
1
+ {"version":3,"file":"checkBounds.js","sources":["../../../src/util/brick/checkBounds.ts"],"sourcesContent":["import { Brick, Vector } from 'brs-js';\n\nimport { getScaleAxis } from './getScaleAxis';\nimport { getBrickSize } from './getBrickSize';\n\nexport interface IBrickBounds {\n minBound: Vector;\n maxBound: Vector;\n center: Vector;\n}\n\n// check if the brick is in bounds for 1 axis\nfunction checkBound(\n brick: Brick,\n brick_assets: string[],\n bounds: IBrickBounds,\n axis: number,\n) {\n const scaleAxis = getScaleAxis(brick, axis);\n const size = getBrickSize(brick, brick_assets);\n const upper = brick.position[axis] + size[scaleAxis];\n const lower = brick.position[axis] - size[scaleAxis];\n return upper <= bounds.maxBound[axis] && lower >= bounds.minBound[axis];\n}\n\n// check if the brick is in bounds\nexport function checkBounds(\n brick: Brick,\n brick_assets: string[],\n bounds: IBrickBounds,\n) {\n return (\n checkBound(brick, brick_assets, bounds, 0) &&\n checkBound(brick, brick_assets, bounds, 1) &&\n checkBound(brick, brick_assets, bounds, 2)\n );\n}\nexport default checkBounds;\n"],"names":["getScaleAxis","getBrickSize"],"mappings":";;;;AAYA,SAAS,WACP,OACA,cACA,QACA,MACA;AACA,QAAM,YAAYA,aAAAA,aAAa,OAAO,IAAI;AAC1C,QAAM,OAAOC,aAAAA,aAAa,OAAO,YAAY;AAC7C,QAAM,QAAQ,MAAM,SAAS,IAAI,IAAI,KAAK,SAAS;AACnD,QAAM,QAAQ,MAAM,SAAS,IAAI,IAAI,KAAK,SAAS;AACnD,SAAO,SAAS,OAAO,SAAS,IAAI,KAAK,SAAS,OAAO,SAAS,IAAI;AACxE;AAGO,SAAS,YACd,OACA,cACA,QACA;AACA,SACE,WAAW,OAAO,cAAc,QAAQ,CAAC,KACzC,WAAW,OAAO,cAAc,QAAQ,CAAC,KACzC,WAAW,OAAO,cAAc,QAAQ,CAAC;AAE7C;;"}
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const constants = require("./constants.js");
4
4
  function genericBrick(name, asset) {
5
5
  if (!asset) asset = "B_" + name.replace(/\s/g, "_");
@@ -213,6 +213,5 @@ function convertDisplayName(name) {
213
213
  return null;
214
214
  }
215
215
  exports.convertDisplayName = convertDisplayName;
216
- exports.default = convertDisplayName;
217
216
  exports.displayNameMap = displayNameMap;
218
217
  //# sourceMappingURL=displayName.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"displayName.js","sources":["../../../src/util/brick/displayName.ts"],"sourcesContent":["import { brickSizeMap } from './constants';\n\ntype NameConversion = [string, [number, number, number]];\n\nfunction genericBrick(\n name: string,\n asset?: string,\n): (typeof displayNameMap)[number] {\n if (!asset) asset = 'B_' + name.replace(/\\s/g, '_');\n return [name, [asset, brickSizeMap[asset] ?? [0, 0, 0]]];\n}\n\nconst microMap: Record<string, string> = {\n 'Micro-Brick': 'PB_DefaultMicroBrick',\n 'Micro-Wedge 1/2 Inner Corner': 'PB_DefaultMicroWedgeHalfInnerCorner',\n 'Micro-Wedge Inv. 1/2 Inner Corner':\n 'PB_DefaultMicroWedgeHalfInnerCornerInverted',\n 'Micro-Wedge 1/2 Outer Corner': 'PB_DefaultMicroWedgeHalfOuterCorner',\n 'Micro-Wedge Corner': 'PB_DefaultMicroWedgeCorner',\n 'Micro-Wedge Inner Corner': 'PB_DefaultMicroWedgeInnerCorner',\n 'Micro-Wedge Outer Corner': 'PB_DefaultMicroWedgeOuterCorner',\n 'Micro-Wedge Triangle Corner': 'PB_DefaultMicroWedgeTriangleCorner',\n 'Micro-Wedge': 'PB_DefaultMicroWedge',\n};\n\nexport const displayNameMap: [\n string | RegExp,\n NameConversion | ((name: string, ...rest: string[]) => NameConversion),\n][] = [\n // Games\n genericBrick('Checkpoint', 'B_CheckPoint'),\n genericBrick('Goalpoint', 'B_GoalPoint'),\n genericBrick('Spawnpoint', 'B_SpawnPoint'),\n\n // Ramps\n genericBrick('2x1 Slipper'),\n genericBrick('2x2 Slipper'),\n\n // Rounds\n genericBrick('1x Octo'),\n genericBrick('1x Octo 90°', 'B_1x_Octo_90Deg'),\n genericBrick('1x Octo 90° Inv', 'B_1x_Octo_90Deg_Inv'),\n genericBrick('1x Octo T'),\n genericBrick('1x Octo T Inv'),\n genericBrick('1x1f Octo', 'B_1x1F_Octo'),\n genericBrick('1x1 Cone'),\n genericBrick('1x1 Round'),\n genericBrick('1x1f Round', 'B_1x1F_Round'),\n genericBrick('2x Octo'),\n genericBrick('2x Octo 90°', 'B_2x_Octo_90Deg'),\n genericBrick('2x Octo 90° Inv', 'B_2x_Octo_90Deg_Inv'),\n genericBrick('2x Octo Cone'),\n genericBrick('2x Octo T'),\n genericBrick('2x Octo T Inv'),\n genericBrick('2x2f Converter', 'B_2x2F_Octo_Converter'),\n genericBrick('2x2f Converter Inv', 'B_2x2F_Octo_Converter_Inv'),\n genericBrick('2x2f Octo', 'B_2x2F_Octo'),\n genericBrick('2x2 Cone'),\n\n // Special\n genericBrick('1x2f Plate Center'),\n genericBrick('1x2f Plate Center Inv'),\n genericBrick('2x2f Plate Center'),\n genericBrick('2x2f Plate Center Inv'),\n genericBrick('Bishop'),\n genericBrick('King'),\n genericBrick('Knight'),\n genericBrick('Pawn'),\n genericBrick('Queen'),\n genericBrick('Rook'),\n genericBrick('2x2 Corner'),\n genericBrick('8x8 Lattice Plate'),\n genericBrick('Bone', 'B_BoneStraight'),\n genericBrick('Carved Pumpkin', 'B_Pumpkin_Carved'),\n genericBrick('Coffin'),\n genericBrick('Coffin Lid'),\n genericBrick('Diagonal Bone', 'B_Bone'),\n genericBrick('Flame'),\n genericBrick('Gravestone'),\n genericBrick('Handle'),\n genericBrick('Inverted Cone'),\n genericBrick('Ladder Step', 'B_Ladder'),\n genericBrick('Pumpkin'),\n genericBrick('Round Swirl Plate', 'B_Swirl_Plate'),\n genericBrick('Sausage'),\n genericBrick('Turkey Body'),\n genericBrick('Turkey Leg'),\n genericBrick('2x4 Door Frame'),\n genericBrick('Picket Fence'),\n genericBrick('Branch'),\n genericBrick('Bush', 'B_Leaf_Bush'),\n genericBrick('Fern'),\n genericBrick('Flower'),\n genericBrick('Hedge 1x1'),\n genericBrick('Hedge 1x1 Corner'),\n genericBrick('Hedge 1x2'),\n genericBrick('Hedge 1x4'),\n genericBrick('Pine Tree'),\n genericBrick('Shrub', 'B_Bush'),\n genericBrick('Small Flower'),\n genericBrick('Cauldron'),\n genericBrick('Chalice'),\n genericBrick('Jar'),\n genericBrick('1x1 Brick Side'),\n genericBrick('1x1 Brick Side Lip'),\n genericBrick('1x2 Overhang Panel', 'B_1x2_Overhang'),\n genericBrick('1x4 Brick Side'),\n genericBrick('2x2 Overhang Panel', 'B_2x2_Overhang_Panel'),\n\n // Micros\n [\n // 8x Micro-Brick Cube\n /^(\\d+)x (Micro-.+) Cube$/,\n (_, size, micro) => [\n microMap[micro],\n [Number(size) / 2, Number(size) / 2, Number(size) / 2],\n ],\n ],\n [\n // 8x8x10 Micro-Brick\n /^(\\d+)x(\\d+)x(\\d+) (Micro-.+)$/,\n (_, x, y, z, micro) => [\n microMap[micro],\n [Number(x) / 2, Number(y) / 2, Number(z) / 2],\n ],\n ],\n\n // Rounds\n [\n // 4x2 Pole\n /^(\\d+)x(\\d+) Pole$/,\n (_, x, z) => [\n 'PB_DefaultPole',\n [Number(x) / 2, Number(x) / 2, Number(z) / 2],\n ],\n ],\n [\n // 2x Cone\n /^(\\d+)x Pole$/,\n (_, size) => [\n 'PB_DefaultPole',\n [Number(size) / 2, Number(size) / 2, Number(size) / 2],\n ],\n ],\n\n // Ramps\n [\n // 4x Inv. Cube Ramp Corner,\n // weird edge case because Inv. Cube and not Cube Inv. or Cube ... (Inverted)\n /^(\\d+)x Inv. Cube Ramp Corner/,\n (name, size) => [\n 'PB_DefaultRampCornerInverted',\n [Number(size) * 5, Number(size) * 5, Number(size) * 5],\n ],\n ],\n\n // Bricks\n [\n // 4x Cube\n /^(\\d+)}?x Cube/,\n (name, size) => [\n brickTypeSuffix(name),\n [Number(size) * 5, Number(size) * 5, Number(size) * 5],\n ],\n ],\n [\n // 1x1x4f\n /^(\\d+)x(\\d+)x([\\d.]+)f/,\n (name, x, y, z) => [\n brickTypeSuffix(name),\n [Number(x) * 5, Number(y) * 5, Number(z) * 2],\n ],\n ],\n [\n // 1x1x2\n /^(\\d+)x(\\d+)x(\\d+)/,\n (name, x, y, z) => [\n brickTypeSuffix(name),\n [Number(x) * 5, Number(y) * 5, Number(z) * 6],\n ],\n ],\n [\n // 1x1f\n /^(\\d+)x(\\d+)f/,\n (name, x, y) => [brickTypeSuffix(name), [Number(x) * 5, Number(y) * 5, 2]],\n ],\n [\n // 1x1\n /^(\\d+)x(\\d+)/,\n (name, x, y) => [brickTypeSuffix(name), [Number(x) * 5, Number(y) * 5, 6]],\n ],\n];\n\nconst brickTypeSuffixMap: [string, string][] = [\n ['Side Wedge', 'PB_DefaultSideWedge'],\n ['Wedge', 'PB_DefaultWedge'],\n ['Inner Ramp Corner', 'PB_DefaultRampInnerCorner'],\n ['Inv. Ramp Corner', 'PB_DefaultRampCornerInverted'],\n ['Ramp Inner Corner (Inverted)', 'PB_DefaultRampInnerCornerInverted'],\n ['Ramp Corner', 'PB_DefaultRampCorner'],\n ['Ramp Crest', 'PB_DefaultRampCrest'],\n ['Ramp Crest End', 'PB_DefaultRampCrestEnd'],\n ['Ramp Crest Corner', 'PB_DefaultRampCrestCorner'],\n ['Inv. Ramp', 'PB_DefaultRampInverted'],\n ['Ramp', 'PB_DefaultRamp'],\n ['Inv. Arch', 'PB_DefaultArchInverted'],\n ['Arch', 'PB_DefaultArch'],\n ['(Tile)', 'PB_DefaultTile'],\n ['(Smooth Tile)', 'PB_DefaultSmoothTile'],\n];\n\nfunction brickTypeSuffix(name: string): string {\n for (const [test, res] of brickTypeSuffixMap)\n if (name.endsWith(test)) return res;\n\n return 'PB_DefaultBrick';\n}\n\nexport function convertDisplayName(name: string): NameConversion {\n for (const matcher of displayNameMap) {\n let matchDetails: RegExpMatchArray | null = null;\n if (typeof matcher[0] === 'string') {\n if (matcher[0] !== name) continue;\n } else {\n matchDetails = name.match(matcher[0]);\n if (matchDetails == null) continue;\n }\n\n if (typeof matcher[1] === 'function') {\n return matcher[1](name, ...(matchDetails ? matchDetails.slice(1) : []));\n } else {\n return matcher[1];\n }\n }\n\n return null;\n}\n\nexport default convertDisplayName;\n"],"names":["brickSizeMap"],"mappings":"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"}
1
+ {"version":3,"file":"displayName.js","sources":["../../../src/util/brick/displayName.ts"],"sourcesContent":["import { brickSizeMap } from './constants';\n\ntype NameConversion = [string, [number, number, number]];\n\nfunction genericBrick(\n name: string,\n asset?: string,\n): (typeof displayNameMap)[number] {\n if (!asset) asset = 'B_' + name.replace(/\\s/g, '_');\n return [name, [asset, brickSizeMap[asset] ?? [0, 0, 0]]];\n}\n\nconst microMap: Record<string, string> = {\n 'Micro-Brick': 'PB_DefaultMicroBrick',\n 'Micro-Wedge 1/2 Inner Corner': 'PB_DefaultMicroWedgeHalfInnerCorner',\n 'Micro-Wedge Inv. 1/2 Inner Corner':\n 'PB_DefaultMicroWedgeHalfInnerCornerInverted',\n 'Micro-Wedge 1/2 Outer Corner': 'PB_DefaultMicroWedgeHalfOuterCorner',\n 'Micro-Wedge Corner': 'PB_DefaultMicroWedgeCorner',\n 'Micro-Wedge Inner Corner': 'PB_DefaultMicroWedgeInnerCorner',\n 'Micro-Wedge Outer Corner': 'PB_DefaultMicroWedgeOuterCorner',\n 'Micro-Wedge Triangle Corner': 'PB_DefaultMicroWedgeTriangleCorner',\n 'Micro-Wedge': 'PB_DefaultMicroWedge',\n};\n\nexport const displayNameMap: [\n string | RegExp,\n NameConversion | ((name: string, ...rest: string[]) => NameConversion),\n][] = [\n // Games\n genericBrick('Checkpoint', 'B_CheckPoint'),\n genericBrick('Goalpoint', 'B_GoalPoint'),\n genericBrick('Spawnpoint', 'B_SpawnPoint'),\n\n // Ramps\n genericBrick('2x1 Slipper'),\n genericBrick('2x2 Slipper'),\n\n // Rounds\n genericBrick('1x Octo'),\n genericBrick('1x Octo 90°', 'B_1x_Octo_90Deg'),\n genericBrick('1x Octo 90° Inv', 'B_1x_Octo_90Deg_Inv'),\n genericBrick('1x Octo T'),\n genericBrick('1x Octo T Inv'),\n genericBrick('1x1f Octo', 'B_1x1F_Octo'),\n genericBrick('1x1 Cone'),\n genericBrick('1x1 Round'),\n genericBrick('1x1f Round', 'B_1x1F_Round'),\n genericBrick('2x Octo'),\n genericBrick('2x Octo 90°', 'B_2x_Octo_90Deg'),\n genericBrick('2x Octo 90° Inv', 'B_2x_Octo_90Deg_Inv'),\n genericBrick('2x Octo Cone'),\n genericBrick('2x Octo T'),\n genericBrick('2x Octo T Inv'),\n genericBrick('2x2f Converter', 'B_2x2F_Octo_Converter'),\n genericBrick('2x2f Converter Inv', 'B_2x2F_Octo_Converter_Inv'),\n genericBrick('2x2f Octo', 'B_2x2F_Octo'),\n genericBrick('2x2 Cone'),\n\n // Special\n genericBrick('1x2f Plate Center'),\n genericBrick('1x2f Plate Center Inv'),\n genericBrick('2x2f Plate Center'),\n genericBrick('2x2f Plate Center Inv'),\n genericBrick('Bishop'),\n genericBrick('King'),\n genericBrick('Knight'),\n genericBrick('Pawn'),\n genericBrick('Queen'),\n genericBrick('Rook'),\n genericBrick('2x2 Corner'),\n genericBrick('8x8 Lattice Plate'),\n genericBrick('Bone', 'B_BoneStraight'),\n genericBrick('Carved Pumpkin', 'B_Pumpkin_Carved'),\n genericBrick('Coffin'),\n genericBrick('Coffin Lid'),\n genericBrick('Diagonal Bone', 'B_Bone'),\n genericBrick('Flame'),\n genericBrick('Gravestone'),\n genericBrick('Handle'),\n genericBrick('Inverted Cone'),\n genericBrick('Ladder Step', 'B_Ladder'),\n genericBrick('Pumpkin'),\n genericBrick('Round Swirl Plate', 'B_Swirl_Plate'),\n genericBrick('Sausage'),\n genericBrick('Turkey Body'),\n genericBrick('Turkey Leg'),\n genericBrick('2x4 Door Frame'),\n genericBrick('Picket Fence'),\n genericBrick('Branch'),\n genericBrick('Bush', 'B_Leaf_Bush'),\n genericBrick('Fern'),\n genericBrick('Flower'),\n genericBrick('Hedge 1x1'),\n genericBrick('Hedge 1x1 Corner'),\n genericBrick('Hedge 1x2'),\n genericBrick('Hedge 1x4'),\n genericBrick('Pine Tree'),\n genericBrick('Shrub', 'B_Bush'),\n genericBrick('Small Flower'),\n genericBrick('Cauldron'),\n genericBrick('Chalice'),\n genericBrick('Jar'),\n genericBrick('1x1 Brick Side'),\n genericBrick('1x1 Brick Side Lip'),\n genericBrick('1x2 Overhang Panel', 'B_1x2_Overhang'),\n genericBrick('1x4 Brick Side'),\n genericBrick('2x2 Overhang Panel', 'B_2x2_Overhang_Panel'),\n\n // Micros\n [\n // 8x Micro-Brick Cube\n /^(\\d+)x (Micro-.+) Cube$/,\n (_, size, micro) => [\n microMap[micro],\n [Number(size) / 2, Number(size) / 2, Number(size) / 2],\n ],\n ],\n [\n // 8x8x10 Micro-Brick\n /^(\\d+)x(\\d+)x(\\d+) (Micro-.+)$/,\n (_, x, y, z, micro) => [\n microMap[micro],\n [Number(x) / 2, Number(y) / 2, Number(z) / 2],\n ],\n ],\n\n // Rounds\n [\n // 4x2 Pole\n /^(\\d+)x(\\d+) Pole$/,\n (_, x, z) => [\n 'PB_DefaultPole',\n [Number(x) / 2, Number(x) / 2, Number(z) / 2],\n ],\n ],\n [\n // 2x Cone\n /^(\\d+)x Pole$/,\n (_, size) => [\n 'PB_DefaultPole',\n [Number(size) / 2, Number(size) / 2, Number(size) / 2],\n ],\n ],\n\n // Ramps\n [\n // 4x Inv. Cube Ramp Corner,\n // weird edge case because Inv. Cube and not Cube Inv. or Cube ... (Inverted)\n /^(\\d+)x Inv. Cube Ramp Corner/,\n (name, size) => [\n 'PB_DefaultRampCornerInverted',\n [Number(size) * 5, Number(size) * 5, Number(size) * 5],\n ],\n ],\n\n // Bricks\n [\n // 4x Cube\n /^(\\d+)}?x Cube/,\n (name, size) => [\n brickTypeSuffix(name),\n [Number(size) * 5, Number(size) * 5, Number(size) * 5],\n ],\n ],\n [\n // 1x1x4f\n /^(\\d+)x(\\d+)x([\\d.]+)f/,\n (name, x, y, z) => [\n brickTypeSuffix(name),\n [Number(x) * 5, Number(y) * 5, Number(z) * 2],\n ],\n ],\n [\n // 1x1x2\n /^(\\d+)x(\\d+)x(\\d+)/,\n (name, x, y, z) => [\n brickTypeSuffix(name),\n [Number(x) * 5, Number(y) * 5, Number(z) * 6],\n ],\n ],\n [\n // 1x1f\n /^(\\d+)x(\\d+)f/,\n (name, x, y) => [brickTypeSuffix(name), [Number(x) * 5, Number(y) * 5, 2]],\n ],\n [\n // 1x1\n /^(\\d+)x(\\d+)/,\n (name, x, y) => [brickTypeSuffix(name), [Number(x) * 5, Number(y) * 5, 6]],\n ],\n];\n\nconst brickTypeSuffixMap: [string, string][] = [\n ['Side Wedge', 'PB_DefaultSideWedge'],\n ['Wedge', 'PB_DefaultWedge'],\n ['Inner Ramp Corner', 'PB_DefaultRampInnerCorner'],\n ['Inv. Ramp Corner', 'PB_DefaultRampCornerInverted'],\n ['Ramp Inner Corner (Inverted)', 'PB_DefaultRampInnerCornerInverted'],\n ['Ramp Corner', 'PB_DefaultRampCorner'],\n ['Ramp Crest', 'PB_DefaultRampCrest'],\n ['Ramp Crest End', 'PB_DefaultRampCrestEnd'],\n ['Ramp Crest Corner', 'PB_DefaultRampCrestCorner'],\n ['Inv. Ramp', 'PB_DefaultRampInverted'],\n ['Ramp', 'PB_DefaultRamp'],\n ['Inv. Arch', 'PB_DefaultArchInverted'],\n ['Arch', 'PB_DefaultArch'],\n ['(Tile)', 'PB_DefaultTile'],\n ['(Smooth Tile)', 'PB_DefaultSmoothTile'],\n];\n\nfunction brickTypeSuffix(name: string): string {\n for (const [test, res] of brickTypeSuffixMap)\n if (name.endsWith(test)) return res;\n\n return 'PB_DefaultBrick';\n}\n\nexport function convertDisplayName(name: string): NameConversion {\n for (const matcher of displayNameMap) {\n let matchDetails: RegExpMatchArray | null = null;\n if (typeof matcher[0] === 'string') {\n if (matcher[0] !== name) continue;\n } else {\n matchDetails = name.match(matcher[0]);\n if (matchDetails == null) continue;\n }\n\n if (typeof matcher[1] === 'function') {\n return matcher[1](name, ...(matchDetails ? matchDetails.slice(1) : []));\n } else {\n return matcher[1];\n }\n }\n\n return null;\n}\n\nexport default convertDisplayName;\n"],"names":["brickSizeMap"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const getBrickSize = require("./getBrickSize.js");
4
4
  const getScaleAxis = require("./getScaleAxis.js");
5
5
  function minMaxBound(brick, brick_assets, bounds, axis) {
@@ -30,6 +30,5 @@ function getBounds({ bricks, brick_assets }) {
30
30
  });
31
31
  return bounds;
32
32
  }
33
- exports.default = getBounds;
34
33
  exports.getBounds = getBounds;
35
34
  //# sourceMappingURL=getBounds.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getBounds.js","sources":["../../../src/util/brick/getBounds.ts"],"sourcesContent":["import { Brick, Vector, WriteSaveObject } from 'brs-js';\nimport type { IBrickBounds } from './checkBounds';\nimport { getBrickSize } from './getBrickSize';\nimport { getScaleAxis } from './getScaleAxis';\n\nexport function getAbsoluteSize(\n brick: Brick,\n brick_assets: string[],\n): [number, number, number] {\n const size = getBrickSize(brick, brick_assets);\n return [\n size[getScaleAxis(brick, 0)],\n size[getScaleAxis(brick, 1)],\n size[getScaleAxis(brick, 2)],\n ];\n}\n\n// compare bound to see if it is new min or max, and then replace if it is\nfunction minMaxBound(\n brick: Brick,\n brick_assets: string[],\n bounds: IBrickBounds,\n axis: number,\n) {\n const scaleAxis = getScaleAxis(brick, axis);\n const size = getBrickSize(brick, brick_assets);\n const upper = brick.position[axis] + size[scaleAxis];\n const lower = brick.position[axis] - size[scaleAxis];\n if (upper > bounds.maxBound[axis] || bounds.maxBound[axis] === undefined)\n bounds.maxBound[axis] = upper;\n if (lower < bounds.minBound[axis] || bounds.minBound[axis] === undefined)\n bounds.minBound[axis] = lower;\n}\n\n// returns bounds of the array of the brick\nexport function getBounds({ bricks, brick_assets }: WriteSaveObject) {\n const bounds: IBrickBounds = {\n minBound: [],\n maxBound: [],\n center: [],\n } as unknown as IBrickBounds;\n\n bricks.forEach(brick => {\n minMaxBound(brick, brick_assets, bounds, 0);\n minMaxBound(brick, brick_assets, bounds, 1);\n minMaxBound(brick, brick_assets, bounds, 2);\n });\n\n // calculate center from min and max bounds\n bounds.center = bounds.minBound.map((min, index) => {\n const max = bounds.maxBound[index];\n const avg = (max + min) / 2;\n return Math.round(avg);\n }) as Vector;\n\n return bounds;\n}\nexport default getBounds;\n"],"names":["getScaleAxis","getBrickSize"],"mappings":";;;;AAkBA,SAAS,YACP,OACA,cACA,QACA,MACA;AACA,QAAM,YAAYA,aAAAA,aAAa,OAAO,IAAI;AAC1C,QAAM,OAAOC,aAAAA,aAAa,OAAO,YAAY;AAC7C,QAAM,QAAQ,MAAM,SAAS,IAAI,IAAI,KAAK,SAAS;AACnD,QAAM,QAAQ,MAAM,SAAS,IAAI,IAAI,KAAK,SAAS;AACnD,MAAI,QAAQ,OAAO,SAAS,IAAI,KAAK,OAAO,SAAS,IAAI,MAAM;AAC7D,WAAO,SAAS,IAAI,IAAI;AAC1B,MAAI,QAAQ,OAAO,SAAS,IAAI,KAAK,OAAO,SAAS,IAAI,MAAM;AAC7D,WAAO,SAAS,IAAI,IAAI;AAC5B;AAGO,SAAS,UAAU,EAAE,QAAQ,gBAAiC;AACnE,QAAM,SAAuB;AAAA,IAC3B,UAAU,CAAA;AAAA,IACV,UAAU,CAAA;AAAA,IACV,QAAQ,CAAA;AAAA,EAAC;AAGX,SAAO,QAAQ,CAAA,UAAS;AACtB,gBAAY,OAAO,cAAc,QAAQ,CAAC;AAC1C,gBAAY,OAAO,cAAc,QAAQ,CAAC;AAC1C,gBAAY,OAAO,cAAc,QAAQ,CAAC;AAAA,EAC5C,CAAC;AAGD,SAAO,SAAS,OAAO,SAAS,IAAI,CAAC,KAAK,UAAU;AAClD,UAAM,MAAM,OAAO,SAAS,KAAK;AACjC,UAAM,OAAO,MAAM,OAAO;AAC1B,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,CAAC;AAED,SAAO;AACT;;;"}
1
+ {"version":3,"file":"getBounds.js","sources":["../../../src/util/brick/getBounds.ts"],"sourcesContent":["import { Brick, Vector, WriteSaveObject } from 'brs-js';\nimport type { IBrickBounds } from './checkBounds';\nimport { getBrickSize } from './getBrickSize';\nimport { getScaleAxis } from './getScaleAxis';\n\nexport function getAbsoluteSize(\n brick: Brick,\n brick_assets: string[],\n): [number, number, number] {\n const size = getBrickSize(brick, brick_assets);\n return [\n size[getScaleAxis(brick, 0)],\n size[getScaleAxis(brick, 1)],\n size[getScaleAxis(brick, 2)],\n ];\n}\n\n// compare bound to see if it is new min or max, and then replace if it is\nfunction minMaxBound(\n brick: Brick,\n brick_assets: string[],\n bounds: IBrickBounds,\n axis: number,\n) {\n const scaleAxis = getScaleAxis(brick, axis);\n const size = getBrickSize(brick, brick_assets);\n const upper = brick.position[axis] + size[scaleAxis];\n const lower = brick.position[axis] - size[scaleAxis];\n if (upper > bounds.maxBound[axis] || bounds.maxBound[axis] === undefined)\n bounds.maxBound[axis] = upper;\n if (lower < bounds.minBound[axis] || bounds.minBound[axis] === undefined)\n bounds.minBound[axis] = lower;\n}\n\n// returns bounds of the array of the brick\nexport function getBounds({ bricks, brick_assets }: WriteSaveObject) {\n const bounds: IBrickBounds = {\n minBound: [],\n maxBound: [],\n center: [],\n } as unknown as IBrickBounds;\n\n bricks.forEach(brick => {\n minMaxBound(brick, brick_assets, bounds, 0);\n minMaxBound(brick, brick_assets, bounds, 1);\n minMaxBound(brick, brick_assets, bounds, 2);\n });\n\n // calculate center from min and max bounds\n bounds.center = bounds.minBound.map((min, index) => {\n const max = bounds.maxBound[index];\n const avg = (max + min) / 2;\n return Math.round(avg);\n }) as Vector;\n\n return bounds;\n}\nexport default getBounds;\n"],"names":["getScaleAxis","getBrickSize"],"mappings":";;;;AAkBA,SAAS,YACP,OACA,cACA,QACA,MACA;AACA,QAAM,YAAYA,aAAAA,aAAa,OAAO,IAAI;AAC1C,QAAM,OAAOC,aAAAA,aAAa,OAAO,YAAY;AAC7C,QAAM,QAAQ,MAAM,SAAS,IAAI,IAAI,KAAK,SAAS;AACnD,QAAM,QAAQ,MAAM,SAAS,IAAI,IAAI,KAAK,SAAS;AACnD,MAAI,QAAQ,OAAO,SAAS,IAAI,KAAK,OAAO,SAAS,IAAI,MAAM;AAC7D,WAAO,SAAS,IAAI,IAAI;AAC1B,MAAI,QAAQ,OAAO,SAAS,IAAI,KAAK,OAAO,SAAS,IAAI,MAAM;AAC7D,WAAO,SAAS,IAAI,IAAI;AAC5B;AAGO,SAAS,UAAU,EAAE,QAAQ,gBAAiC;AACnE,QAAM,SAAuB;AAAA,IAC3B,UAAU,CAAA;AAAA,IACV,UAAU,CAAA;AAAA,IACV,QAAQ,CAAA;AAAA,EAAC;AAGX,SAAO,QAAQ,CAAA,UAAS;AACtB,gBAAY,OAAO,cAAc,QAAQ,CAAC;AAC1C,gBAAY,OAAO,cAAc,QAAQ,CAAC;AAC1C,gBAAY,OAAO,cAAc,QAAQ,CAAC;AAAA,EAC5C,CAAC;AAGD,SAAO,SAAS,OAAO,SAAS,IAAI,CAAC,KAAK,UAAU;AAClD,UAAM,MAAM,OAAO,SAAS,KAAK;AACjC,UAAM,OAAO,MAAM,OAAO;AAC1B,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,CAAC;AAED,SAAO;AACT;;"}
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
- Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const constants = require("./constants.js");
4
4
  function getBrickSize(brick, brick_assets) {
5
5
  const asset = brick_assets[brick.asset_name_index];
6
6
  return constants.brickSizeMap[asset] || brick.size;
7
7
  }
8
- exports.default = getBrickSize;
9
8
  exports.getBrickSize = getBrickSize;
10
9
  //# sourceMappingURL=getBrickSize.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getBrickSize.js","sources":["../../../src/util/brick/getBrickSize.ts"],"sourcesContent":["import { Brick } from 'brs-js';\nimport { brickSizeMap } from './constants';\n\n// get brick size for special bricks\nexport function getBrickSize(brick: Brick, brick_assets: string[]) {\n const asset = brick_assets[brick.asset_name_index];\n return brickSizeMap[asset] || brick.size;\n}\nexport default getBrickSize;\n"],"names":["brickSizeMap"],"mappings":";;;AAIO,SAAS,aAAa,OAAc,cAAwB;AACjE,QAAM,QAAQ,aAAa,MAAM,gBAAgB;AACjD,SAAOA,uBAAa,KAAK,KAAK,MAAM;AACtC;;;"}
1
+ {"version":3,"file":"getBrickSize.js","sources":["../../../src/util/brick/getBrickSize.ts"],"sourcesContent":["import { Brick } from 'brs-js';\nimport { brickSizeMap } from './constants';\n\n// get brick size for special bricks\nexport function getBrickSize(brick: Brick, brick_assets: string[]) {\n const asset = brick_assets[brick.asset_name_index];\n return brickSizeMap[asset] || brick.size;\n}\nexport default getBrickSize;\n"],"names":["brickSizeMap"],"mappings":";;;AAIO,SAAS,aAAa,OAAc,cAAwB;AACjE,QAAM,QAAQ,aAAa,MAAM,gBAAgB;AACjD,SAAOA,uBAAa,KAAK,KAAK,MAAM;AACtC;;"}
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  function getScaleAxis(brick, axis) {
4
4
  const { direction, rotation } = brick;
5
5
  if ([0, 1].includes(direction)) {
@@ -26,6 +26,5 @@ function getScaleAxis(brick, axis) {
26
26
  }
27
27
  return axis;
28
28
  }
29
- exports.default = getScaleAxis;
30
29
  exports.getScaleAxis = getScaleAxis;
31
30
  //# sourceMappingURL=getScaleAxis.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getScaleAxis.js","sources":["../../../src/util/brick/getScaleAxis.ts"],"sourcesContent":["import { Brick } from 'brs-js';\n\n// get scale axis for scale when using rotation and orientation\nexport function getScaleAxis(brick: Brick, axis: number) {\n const { direction, rotation } = brick;\n if ([0, 1].includes(direction)) {\n if (axis === 0) {\n axis = 2;\n } else if (axis === 2) {\n axis = 0;\n }\n } else if ([2, 3].includes(direction)) {\n if (axis === 0) {\n axis = 1;\n } else if (axis === 1) {\n axis = 2;\n } else if (axis === 2) {\n axis = 0;\n }\n }\n\n if ([1, 3].includes(rotation)) {\n if (axis === 0) {\n axis = 1;\n } else if (axis === 1) {\n axis = 0;\n }\n }\n\n return axis;\n}\nexport default getScaleAxis;\n"],"names":[],"mappings":";;AAGO,SAAS,aAAa,OAAc,MAAc;AACvD,QAAM,EAAE,WAAW,SAAA,IAAa;AAChC,MAAI,CAAC,GAAG,CAAC,EAAE,SAAS,SAAS,GAAG;AAC9B,QAAI,SAAS,GAAG;AACd,aAAO;AAAA,IACT,WAAW,SAAS,GAAG;AACrB,aAAO;AAAA,IACT;AAAA,EACF,WAAW,CAAC,GAAG,CAAC,EAAE,SAAS,SAAS,GAAG;AACrC,QAAI,SAAS,GAAG;AACd,aAAO;AAAA,IACT,WAAW,SAAS,GAAG;AACrB,aAAO;AAAA,IACT,WAAW,SAAS,GAAG;AACrB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,CAAC,GAAG,CAAC,EAAE,SAAS,QAAQ,GAAG;AAC7B,QAAI,SAAS,GAAG;AACd,aAAO;AAAA,IACT,WAAW,SAAS,GAAG;AACrB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;;;"}
1
+ {"version":3,"file":"getScaleAxis.js","sources":["../../../src/util/brick/getScaleAxis.ts"],"sourcesContent":["import { Brick } from 'brs-js';\n\n// get scale axis for scale when using rotation and orientation\nexport function getScaleAxis(brick: Brick, axis: number) {\n const { direction, rotation } = brick;\n if ([0, 1].includes(direction)) {\n if (axis === 0) {\n axis = 2;\n } else if (axis === 2) {\n axis = 0;\n }\n } else if ([2, 3].includes(direction)) {\n if (axis === 0) {\n axis = 1;\n } else if (axis === 1) {\n axis = 2;\n } else if (axis === 2) {\n axis = 0;\n }\n }\n\n if ([1, 3].includes(rotation)) {\n if (axis === 0) {\n axis = 1;\n } else if (axis === 1) {\n axis = 0;\n }\n }\n\n return axis;\n}\nexport default getScaleAxis;\n"],"names":[],"mappings":";;AAGO,SAAS,aAAa,OAAc,MAAc;AACvD,QAAM,EAAE,WAAW,SAAA,IAAa;AAChC,MAAI,CAAC,GAAG,CAAC,EAAE,SAAS,SAAS,GAAG;AAC9B,QAAI,SAAS,GAAG;AACd,aAAO;AAAA,IACT,WAAW,SAAS,GAAG;AACrB,aAAO;AAAA,IACT;AAAA,EACF,WAAW,CAAC,GAAG,CAAC,EAAE,SAAS,SAAS,GAAG;AACrC,QAAI,SAAS,GAAG;AACd,aAAO;AAAA,IACT,WAAW,SAAS,GAAG;AACrB,aAAO;AAAA,IACT,WAAW,SAAS,GAAG;AACrB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,CAAC,GAAG,CAAC,EAAE,SAAS,QAAQ,GAAG;AAC7B,QAAI,SAAS,GAAG;AACd,aAAO;AAAA,IACT,WAAW,SAAS,GAAG;AACrB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;;"}
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  function setOwnership(player, saveData) {
4
4
  if ("brick_owners" in saveData)
5
5
  saveData.brick_owners = [
@@ -12,6 +12,5 @@ function setOwnership(player, saveData) {
12
12
  }));
13
13
  return saveData;
14
14
  }
15
- exports.default = setOwnership;
16
15
  exports.setOwnership = setOwnership;
17
16
  //# sourceMappingURL=setOwnership.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"setOwnership.js","sources":["../../../src/util/brick/setOwnership.ts"],"sourcesContent":["import { ReadSaveObject } from 'brs-js';\n\n/**\n * sets all the bricks in saveData to target's ownership\n * @param player - player\n * @param saveData - save data with unknown ownership\n * @return save data with ownership changed\n */\nexport function setOwnership(\n player: { id: string; name: string },\n saveData: ReadSaveObject,\n) {\n if ('brick_owners' in saveData)\n saveData.brick_owners = [\n { id: player.id, name: player.name, bricks: saveData.bricks.length },\n ];\n\n if (saveData.bricks.length > 0 && 'owner_index' in saveData.bricks[0])\n saveData.bricks = saveData.bricks.map(brick => ({\n ...brick,\n owner_index: 1,\n })) as typeof saveData.bricks;\n\n return saveData;\n}\n\nexport default setOwnership;\n"],"names":[],"mappings":";;AAQO,SAAS,aACd,QACA,UACA;AACA,MAAI,kBAAkB;AACpB,aAAS,eAAe;AAAA,MACtB,EAAE,IAAI,OAAO,IAAI,MAAM,OAAO,MAAM,QAAQ,SAAS,OAAO,OAAA;AAAA,IAAO;AAGvE,MAAI,SAAS,OAAO,SAAS,KAAK,iBAAiB,SAAS,OAAO,CAAC;AAClE,aAAS,SAAS,SAAS,OAAO,IAAI,CAAA,WAAU;AAAA,MAC9C,GAAG;AAAA,MACH,aAAa;AAAA,IAAA,EACb;AAEJ,SAAO;AACT;;;"}
1
+ {"version":3,"file":"setOwnership.js","sources":["../../../src/util/brick/setOwnership.ts"],"sourcesContent":["import { ReadSaveObject } from 'brs-js';\n\n/**\n * sets all the bricks in saveData to target's ownership\n * @param player - player\n * @param saveData - save data with unknown ownership\n * @return save data with ownership changed\n */\nexport function setOwnership(\n player: { id: string; name: string },\n saveData: ReadSaveObject,\n) {\n if ('brick_owners' in saveData)\n saveData.brick_owners = [\n { id: player.id, name: player.name, bricks: saveData.bricks.length },\n ];\n\n if (saveData.bricks.length > 0 && 'owner_index' in saveData.bricks[0])\n saveData.bricks = saveData.bricks.map(brick => ({\n ...brick,\n owner_index: 1,\n })) as typeof saveData.bricks;\n\n return saveData;\n}\n\nexport default setOwnership;\n"],"names":[],"mappings":";;AAQO,SAAS,aACd,QACA,UACA;AACA,MAAI,kBAAkB;AACpB,aAAS,eAAe;AAAA,MACtB,EAAE,IAAI,OAAO,IAAI,MAAM,OAAO,MAAM,QAAQ,SAAS,OAAO,OAAA;AAAA,IAAO;AAGvE,MAAI,SAAS,OAAO,SAAS,KAAK,iBAAiB,SAAS,OAAO,CAAC;AAClE,aAAS,SAAS,SAAS,OAAO,IAAI,CAAA,WAAU;AAAA,MAC9C,GAAG;AAAA,MACH,aAAa;AAAA,IAAA,EACb;AAEJ,SAAO;AACT;;"}
@@ -581,7 +581,8 @@ function setupApi(server, io) {
581
581
  playersEnabled: "boolean",
582
582
  saveWorld: "boolean",
583
583
  autoUpdateEnabled: "boolean",
584
- autoUpdateIntervalMins: "number"
584
+ autoUpdateIntervalMins: "number",
585
+ crashRestartEnabled: "boolean"
585
586
  };
586
587
  rpc.addMethod(
587
588
  "server.autorestart.set",