diff --git a/README.md b/README.md index 9bad8db..8ff1d71 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ A plugin that integrate with Pipelab
Author: Armaldio
Website: https://github.com/CynToolkit/construct-plugin
Addon Url: https://github.com/CynToolkit/construct-plugin
-Download Latest Version : [Version: 2.4.0](https://github.com/CynToolkit/construct-plugin/releases/latest)
+Download Latest Version : [Version: 2.4.1](https://github.com/CynToolkit/construct-plugin/releases/latest)
Made using [c3ide2-framework](https://github.com/ConstructFund/c3ide2-framework)
## Table of Contents @@ -149,6 +149,18 @@ When Download type is Around the user, the offsets are the amount of entries aro | Activate Steam overlay to web page | Activates Steam Overlay web browser directly to the specified URL | URL *(string)*
Mode *(combo)*
| | Activate Steam overlay to store (synchronous) | Activates the Steam Overlay to the Steam store page for the provided app (synchronous) | App ID *(number)*
Flag *(combo)*
Tag *(string)*
| | Activate Steam overlay to store | Activates the Steam Overlay to the Steam store page for the provided app | App ID *(number)*
Flag *(combo)*
| +| Trigger screenshot (synchronous) | Captures the current screen and saves to Steam screenshot library (synchronous) | Tag *(string)*
| +| Trigger screenshot | Captures the current screen and saves to Steam screenshot library | | +| Check DLC is installed (synchronous) | Checks if the user owns and has installed a specific DLC (synchronous) | DLC App ID *(number)*
Tag *(string)*
| +| Check DLC is installed | Checks if the user owns and has installed a specific DLC | DLC App ID *(number)*
| +| Create workshop item (synchronous) | Creates a new workshop item for the specified Steam App ID and returns its ID (synchronous) | App ID *(number)*
Tag *(string)*
| +| Create workshop item | Creates a new workshop item for the specified Steam App ID and returns its ID | App ID *(number)*
| +| Upload workshop item (synchronous) | Uploads content to a workshop item (synchronous) | App ID *(number)*
Item ID *(string)*
Title *(string)*
Description *(string)*
Content Folder Path *(string)*
Preview Image Path *(string)*
Tags *(string)*
Visibility *(combo)*
Tag *(string)*
| +| Upload workshop item | Uploads content to a workshop item | App ID *(number)*
Item ID *(string)*
Title *(string)*
Description *(string)*
Content Folder Path *(string)*
Preview Image Path *(string)*
Tags *(string)*
Visibility *(combo)*
| +| Get subscribed items with metadata (synchronous) | Gets all subscribed workshop items with their metadata and install info (synchronous) | Tag *(string)*
| +| Get subscribed items with metadata | Gets all subscribed workshop items with their metadata and install info | | +| Download workshop item (synchronous) | Downloads or updates a workshop item (synchronous) | Item ID *(string)*
High Priority *(boolean)*
Tag *(string)*
| +| Download workshop item | Downloads or updates a workshop item | Item ID *(string)*
High Priority *(boolean)*
| --- @@ -347,6 +359,30 @@ When Download type is Around the user, the offsets are the amount of entries aro | On any "ActivateToStore" success | Trigger when any of the "ActivateToStore" are executed with success. | | | On "ActivateToStore" error | Trigger when the "ActivateToStore" failed to execute. | Tag *(string)*
| | On any "ActivateToStore" error | Trigger when any of the "ActivateToStore" failed to execute. | | +| On "TriggerScreenshot" success | Trigger when the "TriggerScreenshot" is executed with success. | Tag *(string)*
| +| On any "TriggerScreenshot" success | Trigger when any of the "TriggerScreenshot" are executed with success. | | +| On "TriggerScreenshot" error | Trigger when the "TriggerScreenshot" failed to execute. | Tag *(string)*
| +| On any "TriggerScreenshot" error | Trigger when any of the "TriggerScreenshot" failed to execute. | | +| On "CheckDLCIsInstalled" success | Trigger when the "CheckDLCIsInstalled" is executed with success. | Tag *(string)*
| +| On any "CheckDLCIsInstalled" success | Trigger when any of the "CheckDLCIsInstalled" are executed with success. | | +| On "CheckDLCIsInstalled" error | Trigger when the "CheckDLCIsInstalled" failed to execute. | Tag *(string)*
| +| On any "CheckDLCIsInstalled" error | Trigger when any of the "CheckDLCIsInstalled" failed to execute. | | +| On "CreateWorkshopItem" success | Trigger when the "CreateWorkshopItem" is executed with success. | Tag *(string)*
| +| On any "CreateWorkshopItem" success | Trigger when any of the "CreateWorkshopItem" are executed with success. | | +| On "CreateWorkshopItem" error | Trigger when the "CreateWorkshopItem" failed to execute. | Tag *(string)*
| +| On any "CreateWorkshopItem" error | Trigger when any of the "CreateWorkshopItem" failed to execute. | | +| On "UploadWorkshopItem" success | Trigger when the "UploadWorkshopItem" is executed with success. | Tag *(string)*
| +| On any "UploadWorkshopItem" success | Trigger when any of the "UploadWorkshopItem" are executed with success. | | +| On "UploadWorkshopItem" error | Trigger when the "UploadWorkshopItem" failed to execute. | Tag *(string)*
| +| On any "UploadWorkshopItem" error | Trigger when any of the "UploadWorkshopItem" failed to execute. | | +| On "GetSubscribedItemsWithMetadata" success | Trigger when the "GetSubscribedItemsWithMetadata" is executed with success. | Tag *(string)*
| +| On any "GetSubscribedItemsWithMetadata" success | Trigger when any of the "GetSubscribedItemsWithMetadata" are executed with success. | | +| On "GetSubscribedItemsWithMetadata" error | Trigger when the "GetSubscribedItemsWithMetadata" failed to execute. | Tag *(string)*
| +| On any "GetSubscribedItemsWithMetadata" error | Trigger when any of the "GetSubscribedItemsWithMetadata" failed to execute. | | +| On "DownloadWorkshopItem" success | Trigger when the "DownloadWorkshopItem" is executed with success. | Tag *(string)*
| +| On any "DownloadWorkshopItem" success | Trigger when any of the "DownloadWorkshopItem" are executed with success. | | +| On "DownloadWorkshopItem" error | Trigger when the "DownloadWorkshopItem" failed to execute. | Tag *(string)*
| +| On any "DownloadWorkshopItem" error | Trigger when any of the "DownloadWorkshopItem" failed to execute. | | | Is engine | Return true if the engine running the app is the one selected | Engine *(combo)*
| | Is initialized | Returns true if the Pipelab integration has been initialized | | | Is full screen | Returns true if the window is in full screen mode. | State *(combo)*
| @@ -453,6 +489,38 @@ When Download type is Around the user, the offsets are the amount of entries aro | ActivateToWebPageResult | The result of the "ActivateToWebPage last call" | string | | | ActivateToStoreError | The error of the "ActivateToStore last call" | string | | | ActivateToStoreResult | The result of the "ActivateToStore last call" | string | | +| TriggerScreenshotError | The error of the "TriggerScreenshot last call" | string | | +| TriggerScreenshotResult | The result of the "TriggerScreenshot last call" | string | | +| CheckDLCIsInstalledError | The error of the "CheckDLCIsInstalled last call" | string | | +| CheckDLCIsInstalledResult | The result of the "CheckDLCIsInstalled last call" | string | | +| CreateWorkshopItemError | The error of the "CreateWorkshopItem last call" | string | | +| CreateWorkshopItemResult | The result of the "CreateWorkshopItem last call" | string | | +| UploadWorkshopItemError | The error of the "UploadWorkshopItem last call" | string | | +| UploadWorkshopItemResult | The result of the "UploadWorkshopItem last call" | string | | +| GetSubscribedItemsWithMetadataError | The error of the "GetSubscribedItemsWithMetadata last call" | string | | +| GetSubscribedItemsWithMetadataResult | The result of the "GetSubscribedItemsWithMetadata last call" | string | | +| DownloadWorkshopItemError | The error of the "DownloadWorkshopItem last call" | string | | +| DownloadWorkshopItemResult | The result of the "DownloadWorkshopItem last call" | string | | +| SubscribedItemsCount | Get the number of subscribed workshop items | number | | +| SubscribedItemIdAt | Get the workshop item ID at the given index | string | Index *(number)*
| +| WorkshopItemTitle | Get the title of a workshop item | string | Item ID *(string)*
| +| WorkshopItemDescription | Get the description of a workshop item | string | Item ID *(string)*
| +| WorkshopItemOwnerSteamId64 | Get the owner's Steam ID64 of a workshop item | string | Item ID *(string)*
| +| WorkshopItemOwnerAccountId | Get the owner's account ID of a workshop item | number | Item ID *(string)*
| +| WorkshopItemTags | Get the tags of a workshop item (comma-separated) | string | Item ID *(string)*
| +| WorkshopItemUpvotes | Get the number of upvotes for a workshop item | number | Item ID *(string)*
| +| WorkshopItemDownvotes | Get the number of downvotes for a workshop item | number | Item ID *(string)*
| +| WorkshopItemPreviewUrl | Get the preview image URL of a workshop item | string | Item ID *(string)*
| +| WorkshopItemUrl | Get the Steam Workshop URL of a workshop item | string | Item ID *(string)*
| +| WorkshopItemTimeCreated | Get the creation timestamp of a workshop item (Unix epoch) | number | Item ID *(string)*
| +| WorkshopItemTimeUpdated | Get the last update timestamp of a workshop item (Unix epoch) | number | Item ID *(string)*
| +| WorkshopItemState | Get the state bitfield of a workshop item | number | Item ID *(string)*
| +| WorkshopItemIsInstalled | Check if a workshop item is installed (returns 0 or 1) | number | Item ID *(string)*
| +| WorkshopItemIsDownloading | Check if a workshop item is downloading (returns 0 or 1) | number | Item ID *(string)*
| +| WorkshopItemNeedsUpdate | Check if a workshop item needs an update (returns 0 or 1) | number | Item ID *(string)*
| +| WorkshopItemInstallFolder | Get the installation folder path of a workshop item | string | Item ID *(string)*
| +| WorkshopItemSizeOnDisk | Get the size on disk of a workshop item in bytes | number | Item ID *(string)*
| +| WorkshopItemTimestamp | Get the install timestamp of a workshop item | number | Item ID *(string)*
| | ArgumentAt | Get the argument at the given index. | string | Index *(number)*
| | ArgumentCount | Get the number of arguments. | number | | | AppFolderURL | Return the URL of the folder of the current app. | string | | diff --git a/package.json b/package.json index fa17a1b..7094fba 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ }, "name": "@pipelab/construct-plugin", "description": "Pipelab construct plugin", - "version": "2.4.0", + "version": "2.4.1", "packageManager": "pnpm@9.10.0", "type": "module", "scripts": { diff --git a/src/instance.js b/src/instance.js index 8733f42..5c1dc58 100644 --- a/src/instance.js +++ b/src/instance.js @@ -56,7 +56,7 @@ class WebSocketClient { }; this.socket.onmessage = (event) => { - const parsedData = JSON.parse(event.data); + let parsedData = JSON.parse(event.data); // Assuming the server sends a 'correlationId' with every message if (parsedData.correlationId && this.responseResolvers.has(parsedData.correlationId)) { const resolver = this.responseResolvers.get(parsedData.correlationId); @@ -2262,6 +2262,342 @@ function getInstanceJs(parentClass, addonTriggers, C3) { _ActivateToStore = this._ActivateToStoreBase _ActivateToStoreSync = this._ActivateToStoreBase + // Steam Screenshots + _TriggerScreenshotBase = this.wrap(super._TriggerScreenshot, async ( + /** @type {Tag} */ tag + ) => { + try { + /** @type {import('@pipelab/core').MakeInputOutput, 'input'>} */ + const order = { + url: '/steam/raw', + body: { + namespace: 'screenshots', + method: 'triggerScreenshot', + args: [], + }, + }; + const answer = await this.ws?.sendAndWaitForResponse(order); + if (answer?.body.success === false) { + throw new Error('Failed') + } + this._TriggerScreenshotResultValue = answer?.body.data + this._TriggerScreenshotErrorValue = '' + + await this.trigger(tag, [ + C3.Plugins.pipelabv2.Cnds.OnTriggerScreenshotSuccess, + C3.Plugins.pipelabv2.Cnds.OnAnyTriggerScreenshotSuccess + ]) + } catch (e) { + if (e instanceof Error) { + this._TriggerScreenshotErrorValue = e.message + this._TriggerScreenshotResultValue = -1 + await this.trigger(tag, [ + C3.Plugins.pipelabv2.Cnds.OnTriggerScreenshotError, + C3.Plugins.pipelabv2.Cnds.OnAnyTriggerScreenshotError + ]) + } + } + }, this.unsupportedEngine) + _TriggerScreenshot = this._TriggerScreenshotBase + _TriggerScreenshotSync = this._TriggerScreenshotBase + + // Steam DLC + _CheckDLCIsInstalledBase = this.wrap(super._CheckDLCIsInstalled, async ( + /** @type {number} */ appId, + /** @type {Tag} */ tag + ) => { + try { + /** @type {import('@pipelab/core').MakeInputOutput, 'input'>} */ + const order = { + url: '/steam/raw', + body: { + namespace: 'apps', + method: 'isDlcInstalled', + args: [appId], + }, + }; + const answer = await this.ws?.sendAndWaitForResponse(order); + if (answer?.body.success === false) { + throw new Error('Failed') + } + this._CheckDLCIsInstalledResultValue = answer?.body.data + this._CheckDLCIsInstalledErrorValue = '' + + await this.trigger(tag, [ + C3.Plugins.pipelabv2.Cnds.OnCheckDLCIsInstalledSuccess, + C3.Plugins.pipelabv2.Cnds.OnAnyCheckDLCIsInstalledSuccess + ]) + } catch (e) { + if (e instanceof Error) { + this._CheckDLCIsInstalledErrorValue = e.message + this._CheckDLCIsInstalledResultValue = false + await this.trigger(tag, [ + C3.Plugins.pipelabv2.Cnds.OnCheckDLCIsInstalledError, + C3.Plugins.pipelabv2.Cnds.OnAnyCheckDLCIsInstalledError + ]) + } + } + }, this.unsupportedEngine) + _CheckDLCIsInstalled = this._CheckDLCIsInstalledBase + _CheckDLCIsInstalledSync = this._CheckDLCIsInstalledBase + + // Steam Workshop + /** @type {Map} */ + _workshopItemsMap = new Map() + /** @type {string[]} */ + _subscribedItemIds = [] + + _CreateWorkshopItemBase = this.wrap(super._CreateWorkshopItem, async ( + /** @type {number} */ appID, + /** @type {Tag} */ tag + ) => { + try { + /** @type {import('@pipelab/core').MakeInputOutput, 'input'>} */ + const order = { + url: '/steam/raw', + body: { + namespace: 'workshop', + method: 'createItem', + args: [appID], + }, + }; + const answer = await this.ws?.sendAndWaitForResponse(order); + if (answer?.body.success === false) { + throw new Error('Failed') + } + const result = answer?.body.data + // @ts-expect-error - API returns UgcResult + this._CreateWorkshopItemResultValue = result?.itemId?.toString() ?? '' + // @ts-expect-error - API returns UgcResult + this._CreateWorkshopItemNeedsAgreementValue = result?.needsToAcceptAgreement ? 1 : 0 + this._CreateWorkshopItemErrorValue = '' + + await this.trigger(tag, [ + C3.Plugins.pipelabv2.Cnds.OnCreateWorkshopItemSuccess, + C3.Plugins.pipelabv2.Cnds.OnAnyCreateWorkshopItemSuccess + ]) + } catch (e) { + if (e instanceof Error) { + this._CreateWorkshopItemErrorValue = e.message + this._CreateWorkshopItemResultValue = '' + this._CreateWorkshopItemNeedsAgreementValue = 0 + await this.trigger(tag, [ + C3.Plugins.pipelabv2.Cnds.OnCreateWorkshopItemError, + C3.Plugins.pipelabv2.Cnds.OnAnyCreateWorkshopItemError + ]) + } + } + }, this.unsupportedEngine) + _CreateWorkshopItem = this._CreateWorkshopItemBase + _CreateWorkshopItemSync = this._CreateWorkshopItemBase + + _UploadWorkshopItemBase = this.wrap(super._UploadWorkshopItem, async ( + /** @type {number} */ appID, + /** @type {string} */ itemId, + /** @type {string} */ title, + /** @type {string} */ description, + /** @type {string} */ contentFolderPath, + /** @type {string} */ previewImagePath, + /** @type {string} */ tags, + /** @type {number} */ visibility, + /** @type {Tag} */ tag + ) => { + try { + const tagArray = tags.split(',').map(t => t.trim()).filter(t => t.length > 0) + /** @type {import('@pipelab/core').MakeInputOutput, 'input'>} */ + const order = { + url: '/steam/workshop/update-item', + body: { + itemId, + updateDetails:{ + title, + description, + contentPath: contentFolderPath, + previewPath: previewImagePath, + tags: tagArray, + visibility + }, + appID, + }, + }; + const answer = await this.ws?.sendAndWaitForResponse(order); + if (answer?.body.success === false) { + throw new Error('Failed') + } + const result = answer?.body.data + // @ts-expect-error - API returns UgcResult + this._UploadWorkshopItemResultValue = result?.itemId?.toString() ?? '' + // @ts-expect-error - API returns UgcResult + this._UploadWorkshopItemNeedsAgreementValue = result?.needsToAcceptAgreement ? 1 : 0 + this._UploadWorkshopItemErrorValue = '' + + await this.trigger(tag, [ + C3.Plugins.pipelabv2.Cnds.OnUploadWorkshopItemSuccess, + C3.Plugins.pipelabv2.Cnds.OnAnyUploadWorkshopItemSuccess + ]) + } catch (e) { + if (e instanceof Error) { + this._UploadWorkshopItemErrorValue = e.message + this._UploadWorkshopItemResultValue = '' + this._UploadWorkshopItemNeedsAgreementValue = 0 + await this.trigger(tag, [ + C3.Plugins.pipelabv2.Cnds.OnUploadWorkshopItemError, + C3.Plugins.pipelabv2.Cnds.OnAnyUploadWorkshopItemError + ]) + } + } + }, this.unsupportedEngine) + _UploadWorkshopItem = this._UploadWorkshopItemBase + _UploadWorkshopItemSync = this._UploadWorkshopItemBase + + _GetSubscribedItemsWithMetadataBase = this.wrap(super._GetSubscribedItemsWithMetadata, async ( + /** @type {Tag} */ tag + ) => { + try { + // Get subscribed items + /** @type {import('@pipelab/core').MakeInputOutput, 'input'>} */ + const orderSubscribed = { + url: '/steam/raw', + body: { + namespace: 'workshop', + method: 'getSubscribedItems', + args: [false], + }, + }; + const subscribedAnswer = await this.ws?.sendAndWaitForResponse(orderSubscribed); + if (subscribedAnswer?.body.success === false) { + throw new Error('Failed to get subscribed items') + } + + const itemIds = subscribedAnswer?.body.data ?? [] + this._subscribedItemIds = itemIds.map(id => id.toString()) + + if (itemIds.length === 0) { + this._workshopItemsMap.clear() + this._GetSubscribedItemsWithMetadataErrorValue = '' + await this.trigger(tag, [ + C3.Plugins.pipelabv2.Cnds.OnGetSubscribedItemsWithMetadataSuccess, + C3.Plugins.pipelabv2.Cnds.OnAnyGetSubscribedItemsWithMetadataSuccess + ]) + return + } + + // Get metadata for all items + /** @type {import('@pipelab/core').MakeInputOutput, 'input'>} */ + const orderMetadata = { + url: '/steam/workshop/get-items', + body: { + itemIds + } + }; + const metadataAnswer = await this.ws?.sendAndWaitForResponse(orderMetadata); + if (metadataAnswer?.body.success === false) { + throw new Error('Failed to get item metadata') + } + + // @ts-expect-error - API returns WorkshopItemsResult + const items = metadataAnswer?.body.data?.items ?? [] + + // Store items in map and get state/install info for each + this._workshopItemsMap.clear() + for (const item of items) { + if (!item) continue + const itemId = item.publishedFileId.toString() + + // Get state + /** @type {import('@pipelab/core').MakeInputOutput, 'input'>} */ + const orderState = { + url: '/steam/raw', + body: { + namespace: 'workshop', + method: 'state', + args: [item.publishedFileId], + }, + }; + const stateAnswer = await this.ws?.sendAndWaitForResponse(orderState); + const state = stateAnswer?.body.data ?? 0 + + // Get install info + /** @type {import('@pipelab/core').MakeInputOutput, 'input'>} */ + const orderInstall = { + url: '/steam/raw', + body: { + namespace: 'workshop', + method: 'installInfo', + args: [item.publishedFileId], + }, + }; + const installAnswer = await this.ws?.sendAndWaitForResponse(orderInstall); + const installInfo = installAnswer?.body.data + + // Store combined data + this._workshopItemsMap.set(itemId, { + ...item, + state, + installInfo + }) + } + + this._GetSubscribedItemsWithMetadataErrorValue = '' + await this.trigger(tag, [ + C3.Plugins.pipelabv2.Cnds.OnGetSubscribedItemsWithMetadataSuccess, + C3.Plugins.pipelabv2.Cnds.OnAnyGetSubscribedItemsWithMetadataSuccess + ]) + } catch (e) { + if (e instanceof Error) { + this._GetSubscribedItemsWithMetadataErrorValue = e.message + this._subscribedItemIds = [] + this._workshopItemsMap.clear() + await this.trigger(tag, [ + C3.Plugins.pipelabv2.Cnds.OnGetSubscribedItemsWithMetadataError, + C3.Plugins.pipelabv2.Cnds.OnAnyGetSubscribedItemsWithMetadataError + ]) + } + } + }, this.unsupportedEngine) + _GetSubscribedItemsWithMetadata = this._GetSubscribedItemsWithMetadataBase + _GetSubscribedItemsWithMetadataSync = this._GetSubscribedItemsWithMetadataBase + + _DownloadWorkshopItemBase = this.wrap(super._DownloadWorkshopItem, async ( + /** @type {string} */ itemId, + /** @type {boolean} */ highPriority, + /** @type {Tag} */ tag + ) => { + try { + /** @type {import('@pipelab/core').MakeInputOutput, 'input'>} */ + const order = { + url: '/steam/raw', + body: { + namespace: 'workshop', + method: 'download', + args: [itemId, highPriority], + }, + }; + const answer = await this.ws?.sendAndWaitForResponse(order); + if (answer?.body.success === false) { + throw new Error('Failed') + } + this._DownloadWorkshopItemResultValue = answer?.body.data ? 1 : 0 + this._DownloadWorkshopItemErrorValue = '' + + await this.trigger(tag, [ + C3.Plugins.pipelabv2.Cnds.OnDownloadWorkshopItemSuccess, + C3.Plugins.pipelabv2.Cnds.OnAnyDownloadWorkshopItemSuccess + ]) + } catch (e) { + if (e instanceof Error) { + this._DownloadWorkshopItemErrorValue = e.message + this._DownloadWorkshopItemResultValue = 0 + await this.trigger(tag, [ + C3.Plugins.pipelabv2.Cnds.OnDownloadWorkshopItemError, + C3.Plugins.pipelabv2.Cnds.OnAnyDownloadWorkshopItemError + ]) + } + } + }, this.unsupportedEngine) + _DownloadWorkshopItem = this._DownloadWorkshopItemBase + _DownloadWorkshopItemSync = this._DownloadWorkshopItemBase + // #region Cnds _OnInitializeSuccess = this.wrap(super._OnInitializeSuccess, (/** @type {Tag} */ tag) => { return this._currentTag === tag; @@ -2636,6 +2972,36 @@ function getInstanceJs(parentClass, addonTriggers, C3) { _OnActivateToStoreError = this.wrap(super._OnActivateToStoreError, (/** @type {Tag} */ tag) => this._currentTag === tag) _OnAnyActivateToStoreError = this.wrap(super._OnAnyActivateToStoreError, () => true) + _OnTriggerScreenshotSuccess = this.wrap(super._OnTriggerScreenshotSuccess, (/** @type {Tag} */ tag) => this._currentTag === tag) + _OnAnyTriggerScreenshotSuccess = this.wrap(super._OnAnyTriggerScreenshotSuccess, () => true) + _OnTriggerScreenshotError = this.wrap(super._OnTriggerScreenshotError, (/** @type {Tag} */ tag) => this._currentTag === tag) + _OnAnyTriggerScreenshotError = this.wrap(super._OnAnyTriggerScreenshotError, () => true) + + _OnCheckDLCIsInstalledSuccess = this.wrap(super._OnCheckDLCIsInstalledSuccess, (/** @type {Tag} */ tag) => this._currentTag === tag) + _OnAnyCheckDLCIsInstalledSuccess = this.wrap(super._OnAnyCheckDLCIsInstalledSuccess, () => true) + _OnCheckDLCIsInstalledError = this.wrap(super._OnCheckDLCIsInstalledError, (/** @type {Tag} */ tag) => this._currentTag === tag) + _OnAnyCheckDLCIsInstalledError = this.wrap(super._OnAnyCheckDLCIsInstalledError, () => true) + + _OnCreateWorkshopItemSuccess = this.wrap(super._OnCreateWorkshopItemSuccess, (/** @type {Tag} */ tag) => this._currentTag === tag) + _OnAnyCreateWorkshopItemSuccess = this.wrap(super._OnAnyCreateWorkshopItemSuccess, () => true) + _OnCreateWorkshopItemError = this.wrap(super._OnCreateWorkshopItemError, (/** @type {Tag} */ tag) => this._currentTag === tag) + _OnAnyCreateWorkshopItemError = this.wrap(super._OnAnyCreateWorkshopItemError, () => true) + + _OnUploadWorkshopItemSuccess = this.wrap(super._OnUploadWorkshopItemSuccess, (/** @type {Tag} */ tag) => this._currentTag === tag) + _OnAnyUploadWorkshopItemSuccess = this.wrap(super._OnAnyUploadWorkshopItemSuccess, () => true) + _OnUploadWorkshopItemError = this.wrap(super._OnUploadWorkshopItemError, (/** @type {Tag} */ tag) => this._currentTag === tag) + _OnAnyUploadWorkshopItemError = this.wrap(super._OnAnyUploadWorkshopItemError, () => true) + + _OnGetSubscribedItemsWithMetadataSuccess = this.wrap(super._OnGetSubscribedItemsWithMetadataSuccess, (/** @type {Tag} */ tag) => this._currentTag === tag) + _OnAnyGetSubscribedItemsWithMetadataSuccess = this.wrap(super._OnAnyGetSubscribedItemsWithMetadataSuccess, () => true) + _OnGetSubscribedItemsWithMetadataError = this.wrap(super._OnGetSubscribedItemsWithMetadataError, (/** @type {Tag} */ tag) => this._currentTag === tag) + _OnAnyGetSubscribedItemsWithMetadataError = this.wrap(super._OnAnyGetSubscribedItemsWithMetadataError, () => true) + + _OnDownloadWorkshopItemSuccess = this.wrap(super._OnDownloadWorkshopItemSuccess, (/** @type {Tag} */ tag) => this._currentTag === tag) + _OnAnyDownloadWorkshopItemSuccess = this.wrap(super._OnAnyDownloadWorkshopItemSuccess, () => true) + _OnDownloadWorkshopItemError = this.wrap(super._OnDownloadWorkshopItemError, (/** @type {Tag} */ tag) => this._currentTag === tag) + _OnAnyDownloadWorkshopItemError = this.wrap(super._OnAnyDownloadWorkshopItemError, () => true) + _IsFullScreen = this.wrap(super._IsFullScreen, (state) => { return this._fullscreenState === state }, () => false) @@ -3113,6 +3479,154 @@ function getInstanceJs(parentClass, addonTriggers, C3) { return this._ActivateToStoreResultValue }) + _TriggerScreenshotError = this.exprs(super._TriggerScreenshotError, () => { + return this._TriggerScreenshotErrorValue + }) + _TriggerScreenshotResult = this.exprs(super._TriggerScreenshotResult, () => { + return this._TriggerScreenshotResultValue + }) + + _CheckDLCIsInstalledError = this.exprs(super._CheckDLCIsInstalledError, () => { + return this._CheckDLCIsInstalledErrorValue + }) + _CheckDLCIsInstalledResult = this.exprs(super._CheckDLCIsInstalledResult, () => { + return this._CheckDLCIsInstalledResultValue + }) + + // Workshop expressions + _CreateWorkshopItemError = this.exprs(super._CreateWorkshopItemError, () => { + return this._CreateWorkshopItemErrorValue + }) + _CreateWorkshopItemResult = this.exprs(super._CreateWorkshopItemResult, () => { + return this._CreateWorkshopItemResultValue + }) + _CreateWorkshopItemNeedsAgreement = this.exprs(super._CreateWorkshopItemNeedsAgreement, () => { + return this._CreateWorkshopItemNeedsAgreementValue + }) + + _UploadWorkshopItemError = this.exprs(super._UploadWorkshopItemError, () => { + return this._UploadWorkshopItemErrorValue + }) + _UploadWorkshopItemResult = this.exprs(super._UploadWorkshopItemResult, () => { + return this._UploadWorkshopItemResultValue + }) + _UploadWorkshopItemNeedsAgreement = this.exprs(super._UploadWorkshopItemNeedsAgreement, () => { + return this._UploadWorkshopItemNeedsAgreementValue + }) + + _GetSubscribedItemsWithMetadataError = this.exprs(super._GetSubscribedItemsWithMetadataError, () => { + return this._GetSubscribedItemsWithMetadataErrorValue + }) + _GetSubscribedItemsWithMetadataResult = this.exprs(super._GetSubscribedItemsWithMetadataResult, () => { + return 1 // Success indicator + }) + + _DownloadWorkshopItemError = this.exprs(super._DownloadWorkshopItemError, () => { + return this._DownloadWorkshopItemErrorValue + }) + _DownloadWorkshopItemResult = this.exprs(super._DownloadWorkshopItemResult, () => { + return this._DownloadWorkshopItemResultValue + }) + + _SubscribedItemsCount = this.exprs(super._SubscribedItemsCount, () => { + return this._subscribedItemIds.length + }) + + _SubscribedItemIdAt = this.exprs(super._SubscribedItemIdAt, (/** @type {number} */ index) => { + if (index < 0 || index >= this._subscribedItemIds.length) return '' + return this._subscribedItemIds[index] + }) + + _WorkshopItemTitle = this.exprs(super._WorkshopItemTitle, (/** @type {string} */ itemId) => { + const item = this._workshopItemsMap.get(itemId) + return item?.title ?? '' + }) + + _WorkshopItemDescription = this.exprs(super._WorkshopItemDescription, (/** @type {string} */ itemId) => { + const item = this._workshopItemsMap.get(itemId) + return item?.description ?? '' + }) + + _WorkshopItemOwnerSteamId64 = this.exprs(super._WorkshopItemOwnerSteamId64, (/** @type {string} */ itemId) => { + const item = this._workshopItemsMap.get(itemId) + return item?.owner?.steamId64?.toString() ?? '' + }) + + _WorkshopItemOwnerAccountId = this.exprs(super._WorkshopItemOwnerAccountId, (/** @type {string} */ itemId) => { + const item = this._workshopItemsMap.get(itemId) + return item?.owner?.accountId ?? 0 + }) + + _WorkshopItemTags = this.exprs(super._WorkshopItemTags, (/** @type {string} */ itemId) => { + const item = this._workshopItemsMap.get(itemId) + return item?.tags?.join(', ') ?? '' + }) + + _WorkshopItemUpvotes = this.exprs(super._WorkshopItemUpvotes, (/** @type {string} */ itemId) => { + const item = this._workshopItemsMap.get(itemId) + return item?.numUpvotes ?? 0 + }) + + _WorkshopItemDownvotes = this.exprs(super._WorkshopItemDownvotes, (/** @type {string} */ itemId) => { + const item = this._workshopItemsMap.get(itemId) + return item?.numDownvotes ?? 0 + }) + + _WorkshopItemPreviewUrl = this.exprs(super._WorkshopItemPreviewUrl, (/** @type {string} */ itemId) => { + const item = this._workshopItemsMap.get(itemId) + return item?.previewUrl ?? '' + }) + + _WorkshopItemUrl = this.exprs(super._WorkshopItemUrl, (/** @type {string} */ itemId) => { + const item = this._workshopItemsMap.get(itemId) + return item?.url ?? '' + }) + + _WorkshopItemTimeCreated = this.exprs(super._WorkshopItemTimeCreated, (/** @type {string} */ itemId) => { + const item = this._workshopItemsMap.get(itemId) + return item?.timeCreated ?? 0 + }) + + _WorkshopItemTimeUpdated = this.exprs(super._WorkshopItemTimeUpdated, (/** @type {string} */ itemId) => { + const item = this._workshopItemsMap.get(itemId) + return item?.timeUpdated ?? 0 + }) + + _WorkshopItemState = this.exprs(super._WorkshopItemState, (/** @type {string} */ itemId) => { + const item = this._workshopItemsMap.get(itemId) + return item?.state ?? 0 + }) + + _WorkshopItemIsInstalled = this.exprs(super._WorkshopItemIsInstalled, (/** @type {string} */ itemId) => { + const item = this._workshopItemsMap.get(itemId) + return item?.state && (item.state & 4) ? 1 : 0 + }) + + _WorkshopItemIsDownloading = this.exprs(super._WorkshopItemIsDownloading, (/** @type {string} */ itemId) => { + const item = this._workshopItemsMap.get(itemId) + return item?.state && (item.state & 16) ? 1 : 0 + }) + + _WorkshopItemNeedsUpdate = this.exprs(super._WorkshopItemNeedsUpdate, (/** @type {string} */ itemId) => { + const item = this._workshopItemsMap.get(itemId) + return item?.state && (item.state & 8) ? 1 : 0 + }) + + _WorkshopItemInstallFolder = this.exprs(super._WorkshopItemInstallFolder, (/** @type {string} */ itemId) => { + const item = this._workshopItemsMap.get(itemId) + return item?.installInfo?.folder ?? '' + }) + + _WorkshopItemSizeOnDisk = this.exprs(super._WorkshopItemSizeOnDisk, (/** @type {string} */ itemId) => { + const item = this._workshopItemsMap.get(itemId) + return Number(item?.installInfo?.sizeOnDisk ?? 0) + }) + + _WorkshopItemTimestamp = this.exprs(super._WorkshopItemTimestamp, (/** @type {string} */ itemId) => { + const item = this._workshopItemsMap.get(itemId) + return item?.installInfo?.timestamp ?? 0 + }) + // _saveToJson() { diff --git a/src/pluginConfig.js b/src/pluginConfig.js index 1c9f770..d961f0f 100644 --- a/src/pluginConfig.js +++ b/src/pluginConfig.js @@ -1205,6 +1205,160 @@ const ActivateToStore = ACEGenerator("ActivateToStore", /** @type {const} */ ({ description: "Activates the Steam Overlay to the Steam store page for the provided app", })) +// Steam Screenshots +const TriggerScreenshot = ACEGenerator("TriggerScreenshot", /** @type {const} */ ({ + category: "steam", + highlight: false, + deprecated: false, + params: [], + listName: "Trigger screenshot", + displayText: "Trigger Steam screenshot", + description: "Captures the current screen and saves to Steam screenshot library", +})) + +// Steam DLC +const CheckDLCIsInstalled = ACEGenerator("CheckDLCIsInstalled", /** @type {const} */ ({ + category: "steam", + highlight: false, + deprecated: false, + params: [ + { + id: 'appId', + desc: "The App ID of the DLC to check", + name: "DLC App ID", + type: 'number', + initialValue: "0", + } + ], + listName: "Check DLC is installed", + displayText: "Check DLC [b]{0}[/b] is installed", + description: "Checks if the user owns and has installed a specific DLC", +})) + +// Steam Workshop +const CreateWorkshopItem = ACEGenerator("CreateWorkshopItem", /** @type {const} */ ({ + category: "steam-workshop", + highlight: false, + deprecated: false, + params: [ + { + id: 'appID', + desc: "The Steam App ID for the workshop item", + name: "App ID", + type: 'number', + } + ], + listName: "Create workshop item", + displayText: "Create workshop item for app [b]{0}[/b]", + description: "Creates a new workshop item for the specified Steam App ID and returns its ID", +})) + +const UploadWorkshopItem = ACEGenerator("UploadWorkshopItem", /** @type {const} */ ({ + category: "steam-workshop", + highlight: false, + deprecated: false, + params: [ + { + id: 'appID', + desc: "The Steam App ID for the workshop item", + name: "App ID", + type: 'number', + }, + { + id: 'itemId', + desc: "The Workshop Item ID", + name: "Item ID", + type: 'string', + initialValue: '""', + }, + { + id: 'title', + desc: "The title of the workshop item", + name: "Title", + type: 'string', + initialValue: '""', + }, + { + id: 'description', + desc: "The description of the workshop item", + name: "Description", + type: 'string', + initialValue: '""', + }, + { + id: 'contentFolderPath', + desc: "Absolute path to the folder containing the workshop content", + name: "Content Folder Path", + type: 'string', + initialValue: '""', + }, + { + id: 'previewImagePath', + desc: "Absolute path to the preview image file", + name: "Preview Image Path", + type: 'string', + initialValue: '""', + }, + { + id: 'tags', + desc: "Comma-separated list of tags", + name: "Tags", + type: 'string', + initialValue: '""', + }, + { + id: 'visibility', + desc: "Visibility setting (0=Public, 1=FriendsOnly, 2=Private, 3=Unlisted)", + name: "Visibility", + type: 'combo', + items: [ + { "public": "Public" }, + { "friendsOnly": "Friends Only" }, + { "private": "Private" }, + { "unlisted": "Unlisted" }, + ] + } + ], + listName: "Upload workshop item", + displayText: "Upload workshop item [b]{1}[/b] for app [b]{0}[/b] (title: {2}, description: {3}, content: {4}, preview: {5}, tags: {6}, visibility: {7})", + description: "Uploads content to a workshop item", +})) + +const GetSubscribedItemsWithMetadata = ACEGenerator("GetSubscribedItemsWithMetadata", /** @type {const} */ ({ + category: "steam-workshop", + highlight: false, + deprecated: false, + params: [], + listName: "Get subscribed items with metadata", + displayText: "Get subscribed items with metadata", + description: "Gets all subscribed workshop items with their metadata and install info", +})) + +const DownloadWorkshopItem = ACEGenerator("DownloadWorkshopItem", /** @type {const} */ ({ + category: "steam-workshop", + highlight: false, + deprecated: false, + params: [ + { + id: 'itemId', + desc: "The Workshop Item ID", + name: "Item ID", + type: 'string', + initialValue: '""', + }, + { + id: 'highPriority', + desc: "Whether to download with high priority", + name: "High Priority", + type: 'boolean', + initialValue: 'false', + }, + ], + listName: "Download workshop item", + displayText: "Download workshop item [b]{0}[/b] (priority: {1})", + description: "Downloads or updates a workshop item", +})) + /** * @satisfies {import('./sdk.js').Config} */ @@ -1333,6 +1487,7 @@ const Config = /** @type {const} */({ 'file-dialogs': "File Dialogs", 'command-line': "Command line", 'steam': "Steam", + 'steam-workshop': "Steam Workshop", 'discord': "Discord" }, Acts: /** @type {const} */ { @@ -1387,6 +1542,12 @@ const Config = /** @type {const} */({ ...LeaderboardDownloadScore.actions, ...ActivateToWebPage.actions, ...ActivateToStore.actions, + ...TriggerScreenshot.actions, + ...CheckDLCIsInstalled.actions, + ...CreateWorkshopItem.actions, + ...UploadWorkshopItem.actions, + ...GetSubscribedItemsWithMetadata.actions, + ...DownloadWorkshopItem.actions, }, Cnds: { ...Initialize.conditions, @@ -1437,6 +1598,12 @@ const Config = /** @type {const} */({ ...LeaderboardDownloadScore.conditions, ...ActivateToWebPage.conditions, ...ActivateToStore.conditions, + ...TriggerScreenshot.conditions, + ...CheckDLCIsInstalled.conditions, + ...CreateWorkshopItem.conditions, + ...UploadWorkshopItem.conditions, + ...GetSubscribedItemsWithMetadata.conditions, + ...DownloadWorkshopItem.conditions, IsEngine: { category: "general", forward: "_IsEngine", @@ -1558,6 +1725,326 @@ const Config = /** @type {const} */({ ...LeaderboardDownloadScore.expressions, ...ActivateToWebPage.expressions, ...ActivateToStore.expressions, + ...TriggerScreenshot.expressions, + ...CheckDLCIsInstalled.expressions, + ...CreateWorkshopItem.expressions, + ...UploadWorkshopItem.expressions, + ...GetSubscribedItemsWithMetadata.expressions, + ...DownloadWorkshopItem.expressions, + + // Steam Workshop - Additional Expressions + SubscribedItemsCount: { + category: "steam-workshop", + forward: "_SubscribedItemsCount", + highlight: false, + deprecated: false, + returnType: 'number', + description: "Get the number of subscribed workshop items", + }, + SubscribedItemIdAt: { + category: "steam-workshop", + forward: "_SubscribedItemIdAt", + highlight: false, + deprecated: false, + returnType: 'string', + params: [ + { + id: 'index', + desc: "The index of the item (0 to count-1)", + name: "Index", + type: 'number', + } + ], + description: "Get the workshop item ID at the given index", + }, + WorkshopItemTitle: { + category: "steam-workshop", + forward: "_WorkshopItemTitle", + highlight: false, + deprecated: false, + returnType: 'string', + params: [ + { + id: 'itemId', + desc: "The workshop item ID", + name: "Item ID", + type: 'string', + } + ], + description: "Get the title of a workshop item", + }, + WorkshopItemDescription: { + category: "steam-workshop", + forward: "_WorkshopItemDescription", + highlight: false, + deprecated: false, + returnType: 'string', + params: [ + { + id: 'itemId', + desc: "The workshop item ID", + name: "Item ID", + type: 'string', + } + ], + description: "Get the description of a workshop item", + }, + WorkshopItemOwnerSteamId64: { + category: "steam-workshop", + forward: "_WorkshopItemOwnerSteamId64", + highlight: false, + deprecated: false, + returnType: 'string', + params: [ + { + id: 'itemId', + desc: "The workshop item ID", + name: "Item ID", + type: 'string', + } + ], + description: "Get the owner's Steam ID64 of a workshop item", + }, + WorkshopItemOwnerAccountId: { + category: "steam-workshop", + forward: "_WorkshopItemOwnerAccountId", + highlight: false, + deprecated: false, + returnType: 'number', + params: [ + { + id: 'itemId', + desc: "The workshop item ID", + name: "Item ID", + type: 'string', + } + ], + description: "Get the owner's account ID of a workshop item", + }, + WorkshopItemTags: { + category: "steam-workshop", + forward: "_WorkshopItemTags", + highlight: false, + deprecated: false, + returnType: 'string', + params: [ + { + id: 'itemId', + desc: "The workshop item ID", + name: "Item ID", + type: 'string', + } + ], + description: "Get the tags of a workshop item (comma-separated)", + }, + WorkshopItemUpvotes: { + category: "steam-workshop", + forward: "_WorkshopItemUpvotes", + highlight: false, + deprecated: false, + returnType: 'number', + params: [ + { + id: 'itemId', + desc: "The workshop item ID", + name: "Item ID", + type: 'string', + } + ], + description: "Get the number of upvotes for a workshop item", + }, + WorkshopItemDownvotes: { + category: "steam-workshop", + forward: "_WorkshopItemDownvotes", + highlight: false, + deprecated: false, + returnType: 'number', + params: [ + { + id: 'itemId', + desc: "The workshop item ID", + name: "Item ID", + type: 'string', + } + ], + description: "Get the number of downvotes for a workshop item", + }, + WorkshopItemPreviewUrl: { + category: "steam-workshop", + forward: "_WorkshopItemPreviewUrl", + highlight: false, + deprecated: false, + returnType: 'string', + params: [ + { + id: 'itemId', + desc: "The workshop item ID", + name: "Item ID", + type: 'string', + } + ], + description: "Get the preview image URL of a workshop item", + }, + WorkshopItemUrl: { + category: "steam-workshop", + forward: "_WorkshopItemUrl", + highlight: false, + deprecated: false, + returnType: 'string', + params: [ + { + id: 'itemId', + desc: "The workshop item ID", + name: "Item ID", + type: 'string', + } + ], + description: "Get the Steam Workshop URL of a workshop item", + }, + WorkshopItemTimeCreated: { + category: "steam-workshop", + forward: "_WorkshopItemTimeCreated", + highlight: false, + deprecated: false, + returnType: 'number', + params: [ + { + id: 'itemId', + desc: "The workshop item ID", + name: "Item ID", + type: 'string', + } + ], + description: "Get the creation timestamp of a workshop item (Unix epoch)", + }, + WorkshopItemTimeUpdated: { + category: "steam-workshop", + forward: "_WorkshopItemTimeUpdated", + highlight: false, + deprecated: false, + returnType: 'number', + params: [ + { + id: 'itemId', + desc: "The workshop item ID", + name: "Item ID", + type: 'string', + } + ], + description: "Get the last update timestamp of a workshop item (Unix epoch)", + }, + WorkshopItemState: { + category: "steam-workshop", + forward: "_WorkshopItemState", + highlight: false, + deprecated: false, + returnType: 'number', + params: [ + { + id: 'itemId', + desc: "The workshop item ID", + name: "Item ID", + type: 'string', + } + ], + description: "Get the state bitfield of a workshop item", + }, + WorkshopItemIsInstalled: { + category: "steam-workshop", + forward: "_WorkshopItemIsInstalled", + highlight: false, + deprecated: false, + returnType: 'number', + params: [ + { + id: 'itemId', + desc: "The workshop item ID", + name: "Item ID", + type: 'string', + } + ], + description: "Check if a workshop item is installed (returns 0 or 1)", + }, + WorkshopItemIsDownloading: { + category: "steam-workshop", + forward: "_WorkshopItemIsDownloading", + highlight: false, + deprecated: false, + returnType: 'number', + params: [ + { + id: 'itemId', + desc: "The workshop item ID", + name: "Item ID", + type: 'string', + } + ], + description: "Check if a workshop item is downloading (returns 0 or 1)", + }, + WorkshopItemNeedsUpdate: { + category: "steam-workshop", + forward: "_WorkshopItemNeedsUpdate", + highlight: false, + deprecated: false, + returnType: 'number', + params: [ + { + id: 'itemId', + desc: "The workshop item ID", + name: "Item ID", + type: 'string', + } + ], + description: "Check if a workshop item needs an update (returns 0 or 1)", + }, + WorkshopItemInstallFolder: { + category: "steam-workshop", + forward: "_WorkshopItemInstallFolder", + highlight: false, + deprecated: false, + returnType: 'string', + params: [ + { + id: 'itemId', + desc: "The workshop item ID", + name: "Item ID", + type: 'string', + } + ], + description: "Get the installation folder path of a workshop item", + }, + WorkshopItemSizeOnDisk: { + category: "steam-workshop", + forward: "_WorkshopItemSizeOnDisk", + highlight: false, + deprecated: false, + returnType: 'number', + params: [ + { + id: 'itemId', + desc: "The workshop item ID", + name: "Item ID", + type: 'string', + } + ], + description: "Get the size on disk of a workshop item in bytes", + }, + WorkshopItemTimestamp: { + category: "steam-workshop", + forward: "_WorkshopItemTimestamp", + highlight: false, + deprecated: false, + returnType: 'number', + params: [ + { + id: 'itemId', + desc: "The workshop item ID", + name: "Item ID", + type: 'string', + } + ], + description: "Get the install timestamp of a workshop item", + }, // command line ArgumentAt: { diff --git a/src/sdk.d.ts b/src/sdk.d.ts index 6995556..c371b4f 100644 --- a/src/sdk.d.ts +++ b/src/sdk.d.ts @@ -29,7 +29,7 @@ type MyExpression = params: PARAMS } -type Categories = 'general' | 'window' | 'filesystem' | 'file-dialogs' | 'command-line' | 'steam' | 'discord' +type Categories = 'general' | 'window' | 'filesystem' | 'file-dialogs' | 'command-line' | 'steam' | 'steam-workshop' | 'discord' type Config = import("c3ide2-types").Plugin;