Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ A plugin that integrate with Pipelab <br>
Author: Armaldio <br>
Website: https://github.com/CynToolkit/construct-plugin <br>
Addon Url: https://github.com/CynToolkit/construct-plugin <br>
Download Latest Version : [Version: 2.2.0](https://github.com/CynToolkit/construct-plugin/releases/latest) <br>
Download Latest Version : [Version: 2.3.0](https://github.com/CynToolkit/construct-plugin/releases/latest) <br>
<sub>Made using [c3ide2-framework](https://github.com/ConstructFund/c3ide2-framework) </sub><br>

## Table of Contents
Expand Down Expand Up @@ -145,6 +145,10 @@ When Download type is Around the user, the offsets are the amount of entries aro
| Download scores | Download scores from a leaderboard
When Download type is Regular, offset are absolute.
When Download type is Around the user, the offsets are the amount of entries around the user to fetch. | Leaderboard *(string)* <br>Download type *(combo)* <br>Start *(number)* <br>End *(number)* <br>Output *(object)* <br> |
| Activate Steam overlay to web page (synchronous) | Activates Steam Overlay web browser directly to the specified URL (synchronous) | URL *(string)* <br>Mode *(combo)* <br>Tag *(string)* <br> |
| Activate Steam overlay to web page | Activates Steam Overlay web browser directly to the specified URL | URL *(string)* <br>Mode *(combo)* <br> |
| Activate Steam overlay to store (synchronous) | Activates the Steam Overlay to the Steam store page for the provided app (synchronous) | App ID *(number)* <br>Flag *(combo)* <br>Tag *(string)* <br> |
| Activate Steam overlay to store | Activates the Steam Overlay to the Steam store page for the provided app | App ID *(number)* <br>Flag *(combo)* <br> |


---
Expand Down Expand Up @@ -335,7 +339,16 @@ When Download type is Around the user, the offsets are the amount of entries aro
| On any "LeaderboardDownloadScore" success | Trigger when any of the "LeaderboardDownloadScore" are executed with success. | |
| On "LeaderboardDownloadScore" error | Trigger when the "LeaderboardDownloadScore" failed to execute. | Tag *(string)* <br> |
| On any "LeaderboardDownloadScore" error | Trigger when any of the "LeaderboardDownloadScore" failed to execute. | |
| On "ActivateToWebPage" success | Trigger when the "ActivateToWebPage" is executed with success. | Tag *(string)* <br> |
| On any "ActivateToWebPage" success | Trigger when any of the "ActivateToWebPage" are executed with success. | |
| On "ActivateToWebPage" error | Trigger when the "ActivateToWebPage" failed to execute. | Tag *(string)* <br> |
| On any "ActivateToWebPage" error | Trigger when any of the "ActivateToWebPage" failed to execute. | |
| On "ActivateToStore" success | Trigger when the "ActivateToStore" is executed with success. | Tag *(string)* <br> |
| 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)* <br> |
| On any "ActivateToStore" error | Trigger when any of the "ActivateToStore" failed to execute. | |
| Is engine | Return true if the engine running the app is the one selected | Engine *(combo)* <br> |
| 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)* <br> |
| Last checked path exists | Returns true if the last checked path exists. | |

Expand Down Expand Up @@ -436,6 +449,10 @@ When Download type is Around the user, the offsets are the amount of entries aro
| LeaderboardUploadScoreWithMetadataResult | The result of the "LeaderboardUploadScoreWithMetadata last call" | string | |
| LeaderboardDownloadScoreError | The error of the "LeaderboardDownloadScore last call" | string | |
| LeaderboardDownloadScoreResult | The result of the "LeaderboardDownloadScore last call" | string | |
| ActivateToWebPageError | The error of the "ActivateToWebPage last call" | string | |
| 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 | |
| ArgumentAt | Get the argument at the given index. | string | Index *(number)* <br> |
| ArgumentCount | Get the number of arguments. | number | |
| AppFolderURL | Return the URL of the folder of the current app. | string | |
Expand Down Expand Up @@ -480,6 +497,7 @@ When Download type is Around the user, the offsets are the amount of entries aro
| SteamLevel | Get the Steam level. | number | |
| SteamIpCountry | Get the Steam IP country. | string | |
| SteamIsRunningOnSteamDeck | Return true if the app is running on a Steam Deck. | number | |
| SteamAppId | Get the currently used Steam App ID. | number | |

## Paths
**ProjectFilesFolder**: Direct path to your games's content
Expand Down
157 changes: 157 additions & 0 deletions src/instance.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,17 @@ const defaultSteamId = {
steamId64: '',
}

// Simple path utility for POSIX-style path operations
const posixPath = {
dirname: (path) => {
const lastSlash = path.lastIndexOf('/');
return lastSlash === -1 ? '.' : path.substring(0, lastSlash);
},
join: (dirname, filename) => {
return dirname.endsWith('/') ? dirname + filename : dirname + '/' + filename;
}
};

let DOM_COMPONENT_ID = ''
//<-- DOM_COMPONENT_ID -->

Expand Down Expand Up @@ -355,11 +366,24 @@ function getInstanceJs(parentClass, addonTriggers, C3) {
/** @type {string} */
_arch = ''

/** @type {number} */
_steam_AppId = -1

/** @type {string} */
_ListFilesErrorValue = ''
/** @type {import("@pipelab/core").FileFolder[]} */
_ListFilesResultValue = []

/** @type {string} */
_ActivateToWebPageErrorValue = ''
/** @type {boolean} */
_ActivateToWebPageResultValue = false

/** @type {string} */
_ActivateToStoreErrorValue = ''
/** @type {boolean} */
_ActivateToStoreResultValue = false

/**
* Description
* @param {ISDKInstanceBase_} inst
Expand Down Expand Up @@ -681,6 +705,20 @@ function getInstanceJs(parentClass, addonTriggers, C3) {
this._arch = response?.body.arch ?? "";
})

promises.push(async () => {
/** @type {import('@pipelab/core').MakeInputOutput<import('@pipelab/core').SteamRaw<'utils', 'getAppId'>, 'input'>} */
const order = {
url: '/steam/raw',
body: {
namespace: 'utils',
method: 'getAppId',
args: [],
},
};
const response = await this.ws?.sendAndWaitForResponse(order);
this._steam_AppId = response?.body.data ?? -1;
})

const results = await Promise.allSettled(promises.map(x => x()))

// -----------------------------------------------------------------------
Expand Down Expand Up @@ -2136,6 +2174,94 @@ function getInstanceJs(parentClass, addonTriggers, C3) {
_DiscordSetActivitySync = this._DiscordSetActivityBase
_DiscordSetActivity = this._DiscordSetActivityBase

_ActivateToWebPageBase = this.wrap(super._ActivateToWebPage, async (
/** @type {string} */ url,
/** @type {number} */ mode,
/** @type {Tag} */ tag
) => {
try {
// Map Construct3 combo values to Steam constants
// 0 = "default", 1 = "modal"
const steamMode = mode === 1 ? 1 : 0; // k_EActivateGameOverlayToWebPageMode_Modal : k_EActivateGameOverlayToWebPageMode_Default

/** @type {import('@pipelab/core').MakeInputOutput<import('@pipelab/core').SteamRaw<'overlay', 'activateToWebPage'>, 'input'>} */
const order = {
url: '/steam/raw',
body: {
namespace: 'overlay',
method: 'activateToWebPage',
args: [url, steamMode],
},
};
const answer = await this.ws?.sendAndWaitForResponse(order);
if (answer?.body.success === false) {
throw new Error('Failed')
}
this._ActivateToWebPageResultValue = answer?.body.success
this._ActivateToWebPageErrorValue = ''

await this.trigger(tag, [
C3.Plugins.pipelabv2.Cnds.OnActivateToWebPageSuccess,
C3.Plugins.pipelabv2.Cnds.OnAnyActivateToWebPageSuccess
])
} catch (e) {
if (e instanceof Error) {
this._ActivateToWebPageErrorValue = e.message
this._ActivateToWebPageResultValue = false
await this.trigger(tag, [
C3.Plugins.pipelabv2.Cnds.OnActivateToWebPageError,
C3.Plugins.pipelabv2.Cnds.OnAnyActivateToWebPageError
])
}
}
}, this.unsupportedEngine)
_ActivateToWebPage = this._ActivateToWebPageBase
_ActivateToWebPageSync = this._ActivateToWebPageBase

_ActivateToStoreBase = this.wrap(super._ActivateToStore, async (
/** @type {number} */ appId,
/** @type {number} */ flag,
/** @type {Tag} */ tag
) => {
try {
// Map Construct3 combo values to Steam constants
// 0 = "none", 1 = "addToCartAndShow"
const steamFlag = flag === 1 ? 2 : 0; // k_EOverlayToStoreFlag_AddToCartAndShow : k_EOverlayToStoreFlag_None

/** @type {import('@pipelab/core').MakeInputOutput<import('@pipelab/core').SteamRaw<'overlay', 'activateToStore'>, 'input'>} */
const order = {
url: '/steam/raw',
body: {
namespace: 'overlay',
method: 'activateToStore',
args: [appId, steamFlag],
},
};
const answer = await this.ws?.sendAndWaitForResponse(order);
if (answer?.body.success === false) {
throw new Error('Failed')
}
this._ActivateToStoreResultValue = answer?.body.success
this._ActivateToStoreErrorValue = ''

await this.trigger(tag, [
C3.Plugins.pipelabv2.Cnds.OnActivateToStoreSuccess,
C3.Plugins.pipelabv2.Cnds.OnAnyActivateToStoreSuccess
])
} catch (e) {
if (e instanceof Error) {
this._ActivateToStoreErrorValue = e.message
this._ActivateToStoreResultValue = false
await this.trigger(tag, [
C3.Plugins.pipelabv2.Cnds.OnActivateToStoreError,
C3.Plugins.pipelabv2.Cnds.OnAnyActivateToStoreError
])
}
}
}, this.unsupportedEngine)
_ActivateToStore = this._ActivateToStoreBase
_ActivateToStoreSync = this._ActivateToStoreBase

// #region Cnds
_OnInitializeSuccess = this.wrap(super._OnInitializeSuccess, (/** @type {Tag} */ tag) => {
return this._currentTag === tag;
Expand Down Expand Up @@ -2500,13 +2626,27 @@ function getInstanceJs(parentClass, addonTriggers, C3) {
return true
})

_OnActivateToWebPageSuccess = this.wrap(super._OnActivateToWebPageSuccess, (/** @type {Tag} */ tag) => this._currentTag === tag)
_OnAnyActivateToWebPageSuccess = this.wrap(super._OnAnyActivateToWebPageSuccess, () => true)
_OnActivateToWebPageError = this.wrap(super._OnActivateToWebPageError, (/** @type {Tag} */ tag) => this._currentTag === tag)
_OnAnyActivateToWebPageError = this.wrap(super._OnAnyActivateToWebPageError, () => true)

_OnActivateToStoreSuccess = this.wrap(super._OnActivateToStoreSuccess, (/** @type {Tag} */ tag) => this._currentTag === tag)
_OnAnyActivateToStoreSuccess = this.wrap(super._OnAnyActivateToStoreSuccess, () => true)
_OnActivateToStoreError = this.wrap(super._OnActivateToStoreError, (/** @type {Tag} */ tag) => this._currentTag === tag)
_OnAnyActivateToStoreError = this.wrap(super._OnAnyActivateToStoreError, () => true)

_IsFullScreen = this.wrap(super._IsFullScreen, (state) => {
return this._fullscreenState === state
}, () => false)

_LastCheckedPathExists = this.wrap(super._LastCheckedPathExists, (state) => {
return this._CheckIfPathExistErrorValue === ''
}, () => false)

_IsInitialized = this.wrap(super._IsInitialized, () => {
return this._isInitialized
}, () => false)
// #endregion

// #region Exps
Expand Down Expand Up @@ -2674,6 +2814,9 @@ function getInstanceJs(parentClass, addonTriggers, C3) {
_SteamIsRunningOnSteamDeck = this.exprs(super._SteamIsRunningOnSteamDeck, () => {
return this._steam_IsRunningOnSteamDeck ? 1 : 0
})
_SteamAppId = this.exprs(super._SteamAppId, () => {
return this._steam_AppId
})

_InitializeError = this.exprs(super._InitializeError, () => {
return this._InitializeErrorValue
Expand Down Expand Up @@ -2956,6 +3099,20 @@ function getInstanceJs(parentClass, addonTriggers, C3) {
return this._DiscordSetActivityResultValue
})

_ActivateToWebPageError = this.exprs(super._ActivateToWebPageError, () => {
return this._ActivateToWebPageErrorValue
})
_ActivateToWebPageResult = this.exprs(super._ActivateToWebPageResult, () => {
return this._ActivateToWebPageResultValue
})

_ActivateToStoreError = this.exprs(super._ActivateToStoreError, () => {
return this._ActivateToStoreErrorValue
})
_ActivateToStoreResult = this.exprs(super._ActivateToStoreResult, () => {
return this._ActivateToStoreResultValue
})

//

_saveToJson() {
Expand Down
83 changes: 83 additions & 0 deletions src/pluginConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,62 @@ const DiscordSetActivity = ACEGenerator("DiscordSetActivity", /** @type {const}
description: "Set the discord activity (aka Rich presence).",
}))

const ActivateToWebPage = ACEGenerator("ActivateToWebPage", /** @type {const} */ ({
category: "steam",
highlight: false,
deprecated: false,
params: [
{
id: 'url',
desc: "The webpage to open. A fully qualified address with the protocol is required (e.g. 'http://www.steampowered.com')",
name: "URL",
type: 'string',
initialValue: "\"\"",
},
{
id: 'mode',
desc: "Mode for the web page.",
name: "Mode",
type: 'combo',
items: [
{ "default": "Default" },
{ "modal": "Modal" },
]
}
],
listName: "Activate Steam overlay to web page",
displayText: "Activate Steam overlay to web page [b]{0}[/b] (mode: {1})",
description: "Activates Steam Overlay web browser directly to the specified URL",
}))

const ActivateToStore = ACEGenerator("ActivateToStore", /** @type {const} */ ({
category: "steam",
highlight: false,
deprecated: false,
params: [
{
id: 'appId',
desc: "The app ID to show the store page of",
name: "App ID",
type: 'number',
initialValue: "0",
},
{
id: 'flag',
desc: "Flags to modify the behavior when the page opens",
name: "Flag",
type: 'combo',
items: [
{ "none": "None" },
{ "addToCartAndShow": "Add to cart and show" },
]
}
],
listName: "Activate Steam overlay to store",
displayText: "Activate Steam overlay to store for app [b]{0}[/b] (flag: {1})",
description: "Activates the Steam Overlay to the Steam store page for the provided app",
}))

/**
* @satisfies {import('./sdk.js').Config<import('./sdk.js').Categories>}
*/
Expand Down Expand Up @@ -1329,6 +1385,8 @@ const Config = /** @type {const} */({
...LeaderboardUploadScore.actions,
...LeaderboardUploadScoreWithMetadata.actions,
...LeaderboardDownloadScore.actions,
...ActivateToWebPage.actions,
...ActivateToStore.actions,
},
Cnds: {
...Initialize.conditions,
Expand Down Expand Up @@ -1377,6 +1435,8 @@ const Config = /** @type {const} */({
...LeaderboardUploadScore.conditions,
...LeaderboardUploadScoreWithMetadata.conditions,
...LeaderboardDownloadScore.conditions,
...ActivateToWebPage.conditions,
...ActivateToStore.conditions,
IsEngine: {
category: "general",
forward: "_IsEngine",
Expand All @@ -1399,6 +1459,19 @@ const Config = /** @type {const} */({
listName: "Is engine",
},

IsInitialized: {
category: "general",
forward: "_IsInitialized",
highlight: false,
deprecated: false,
description: "Returns true if the Pipelab integration has been initialized",
displayText: "Is initialized",
listName: "Is initialized",
isInvertible: true,
isTrigger: false,
params: []
},

IsFullScreen: {
category: "window",
forward: "_IsFullScreen",
Expand Down Expand Up @@ -1483,6 +1556,8 @@ const Config = /** @type {const} */({
...LeaderboardUploadScore.expressions,
...LeaderboardUploadScoreWithMetadata.expressions,
...LeaderboardDownloadScore.expressions,
...ActivateToWebPage.expressions,
...ActivateToStore.expressions,

// command line
ArgumentAt: {
Expand Down Expand Up @@ -1881,6 +1956,14 @@ const Config = /** @type {const} */({
returnType: 'number',
description: "Return true if the app is running on a Steam Deck.",
},
SteamAppId: {
category: "steam",
forward: "_SteamAppId",
highlight: false,
deprecated: false,
returnType: 'number',
description: "Get the currently used Steam App ID.",
},
},
});

Expand Down