From 469603731bd15d7ba2b852072d4c6a0cc66d5832 Mon Sep 17 00:00:00 2001
From: PuzzlingGGG <138084889+PuzzlingGGG@users.noreply.github.com>
Date: Sun, 28 Jul 2024 22:00:01 -0400
Subject: [PATCH 03/13] Update download-project.js
---
src/packager/download-project.js | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/packager/download-project.js b/src/packager/download-project.js
index 18282ca1..2716e46d 100644
--- a/src/packager/download-project.js
+++ b/src/packager/download-project.js
@@ -5,6 +5,7 @@ const unknownAnalysis = () => ({
stageVariables: [],
stageComments: [],
usesMusic: true,
+ usesSteamworks: false,
extensions: []
});
@@ -40,6 +41,7 @@ const analyzeScratch3 = (projectData) => {
.map((i) => i.text);
// TODO: usesMusic has possible false negatives
const usesMusic = projectData.extensions.includes('music');
+ const usesSteamworks = projectData.extensions.includes('steamworks');
const extensions = projectData.extensionURLs ? Object.values(projectData.extensionURLs) : [];
return {
...unknownAnalysis(),
From e752f9d9502461807522e2a70b4991c1400cc553 Mon Sep 17 00:00:00 2001
From: PuzzlingGGG <138084889+PuzzlingGGG@users.noreply.github.com>
Date: Sun, 28 Jul 2024 22:21:19 -0400
Subject: [PATCH 04/13] Update packager.js
---
src/packager/packager.js | 178 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 176 insertions(+), 2 deletions(-)
diff --git a/src/packager/packager.js b/src/packager/packager.js
index 2246d6cf..310fe1d1 100644
--- a/src/packager/packager.js
+++ b/src/packager/packager.js
@@ -526,6 +526,7 @@ cd "$(dirname "$0")"
const contentsPrefix = isMac ? `${rootPrefix}${packageName}.app/Contents/` : rootPrefix;
const resourcesPrefix = isMac ? `${contentsPrefix}Resources/app/` : `${contentsPrefix}resources/app/`;
const electronMainName = 'electron-main.js';
+ const electronPreloadName = 'electron-preload.js';
const iconName = 'icon.png';
const icon = await Adapter.getAppIcon(this.options.app.icon);
@@ -538,8 +539,8 @@ cd "$(dirname "$0")"
};
zip.file(`${resourcesPrefix}package.json`, JSON.stringify(manifest, null, 4));
- const mainJS = `'use strict';
-const {app, BrowserWindow, Menu, shell, screen, dialog} = require('electron');
+ let mainJS = `'use strict';
+const {app, BrowserWindow, Menu, shell, screen, dialog, ipcMain} = require('electron');
const path = require('path');
const isWindows = process.platform === 'win32';
@@ -572,6 +573,7 @@ const createWindow = (windowOptions) => {
sandbox: true,
contextIsolation: true,
nodeIntegration: false,
+ preload: path.resolve(__dirname, ${JSON.stringify(electronPreloadName)}),
},
show: true,
width: 480,
@@ -720,7 +722,173 @@ app.whenReady().then(() => {
createProjectWindow(defaultProjectURL);
});
`;
+
+ let preloadJS = `'use strict';
+const {contextBridge, ipcRenderer} = require('electron');
+`;
+
+ if (this.project.analysis.usesSteamworks) {
+ mainJS += `
+ const enableSteamworks = () => {
+ const APP_ID = +${JSON.stringify(this.options.steamworks.appId)};
+ const steamworks = require('./steamworks.js/');
+ const client = steamworks.init(APP_ID);
+ const async = (event, callback) => ipcMain.handle(event, (e, ...args) => {
+ return callback(...args);
+ });
+ const sync = (event, callback) => ipcMain.on(event, (e, ...args) => {
+ e.returnValue = callback(...args);
+ });
+ async('Steamworks.achievement.activate', (achievement) => client.achievement.activate(achievement));
+ async('Steamworks.achievement.clear', (achievement) => client.achievement.clear(achievement));
+ sync('Steamworks.achievement.isActivated', (achievement) => client.achievement.isActivated(achievement));
+ sync('Steamworks.apps.isDlcInstalled', (dlc) => client.apps.isDlcInstalled(dlc));
+ sync('Steamworks.localplayer.getName', () => client.localplayer.getName());
+ sync('Steamworks.localplayer.getLevel', () => client.localplayer.getLevel());
+ sync('Steamworks.localplayer.getIpCountry', () => client.localplayer.getIpCountry());
+ sync('Steamworks.localplayer.getSteamId', () => client.localplayer.getSteamId());
+ async('Steamworks.overlay.activateToWebPage', (url) => client.overlay.activateToWebPage(url));
+
+ //-----NEW PENGUINMOD STUFF-----
+ sync('Steamworks.init', (appId) => client.init(appId));
+ sync('Steamworks.restartAppIfNecessary', (appId) => client.restartAppIfNecessary(appId));
+ sync('Steamworks.runCallbacks', () => client.runCallbacks());
+
+ async('Steamworks.auth.getSessionTicketWithSteamId', (steamId64, timeoutSeconds) => client.auth.getSessionTicketWithSteamId(steamId64, timeoutSeconds));
+ async('Steamworks.auth.getSessionTicketWithIp', (ip, timeoutSeconds) => client.auth.getSessionTicketWithIp(ip, timeoutSeconds));
+ async('Steamworks.auth.getAuthTicketForWebApi', (identity, timeoutSeconds) => client.auth.getAuthTicketForWebApi(identity, timeoutSeconds));
+
+ sync('Steamworks.apps.isSubscribedApp', (appId) => client.apps.isSubscribedApp(appId));
+ sync('Steamworks.apps.isAppInstalled', (appId) => client.apps.isAppInstalled(appId));
+ sync('Steamworks.apps.isSubscribedFromFreeWeekend', () => client.apps.isSubscribedFromFreeWeekend());
+ sync('Steamworks.apps.isVacBanned', () => client.apps.isVacBanned());
+ sync('Steamworks.apps.isCybercafe', () => client.apps.isCybercafe());
+ sync('Steamworks.apps.isLowViolence', () => client.apps.isLowViolence());
+ sync('Steamworks.apps.isSubscribed', () => client.apps.isSubscribed());
+ sync('Steamworks.apps.appBuildId', () => client.apps.appBuildId());
+ sync('Steamworks.apps.appInstallDir', (appId) => client.apps.appInstallDir(appId));
+ sync('Steamworks.apps.appOwner', () => client.apps.appOwner());
+ sync('Steamworks.apps.availableGameLanguages', () => client.apps.availableGameLanguages());
+ sync('Steamworks.apps.currentGameLanguage', () => client.apps.currentGameLanguage());
+ sync('Steamworks.apps.currentBetaName', () => client.apps.currentBetaName());
+
+ sync('Steamworks.cloud.isEnabledForAccount', () => client.cloud.isEnabledForAccount());
+ sync('Steamworks.cloud.isEnabledForApp', () => client.cloud.isEnabledForApp());
+ sync('Steamworks.cloud.listFiles', () => client.cloud.listFiles());
+
+ sync('Steamworks.input.init', () => client.input.init());
+ sync('Steamworks.input.getControllers', () => client.input.getControllers());
+ sync('Steamworks.input.getActionSet', (actionSetName) => client.input.getActionSet(actionSetName));
+ sync('Steamworks.input.getDigitalAction', (actionName) => client.input.getDigitalAction(actionName));
+ sync('Steamworks.input.getAnalogAction', (actionName) => client.input.getAnalogAction(actionName));
+ sync('Steamworks.input.shutdown', () => client.input.shutdown());
+
+ async('Steamworks.matchmaking.createLobby', (lobbyType, maxMembers) => client.matchmaking.createLobby(lobbyType, maxMembers));
+ async('Steamworks.matchmaking.joinLobby', (lobbyId) => client.matchmaking.joinLobby(lobbyId));
+ async('Steamworks.matchmaking.getLobbies', () => client.matchmaking.getLobbies());
+
+ async('Steamworks.networking.sendP2PPacket', (steamId64, sendType, data) => client.networking.sendP2PPacket(steamId64, sendType, data));
+ sync('Steamworks.networking.acceptP2PSession', (steamId64) => client.networking.acceptP2PSession(steamId64));
+
+ sync('Steamworks.overlay.activateDialog', (dialog) => client.overlay.activateDialog(dialog));
+ sync('Steamworks.overlay.activateDialogToUser', (dialog, steamId64) => client.overlay.activateDialogToUser(dialog, steamId64));
+ sync('Steamworks.overlay.activateInviteDialog', (lobbyId) => client.overlay.activateInviteDialog(lobbyId));
+ sync('Steamworks.overlay.activateToStore', (appId, flag) => client.overlay.activateToStore(appId, flag));
+
+ sync('Steamworks.stats.getInt', (name) => client.stats.getInt(name));
+ sync('Steamworks.stats.setInt', (name, value) => client.stats.setInt(name, value));
+ sync('Steamworks.stats.store', () => client.stats.store());
+ sync('Steamworks.stats.resetAll', (achievementsToo) => client.stats.resetAll(achievementsToo));
+
+ sync('Steamworks.utils.getAppId', () => client.utils.getAppId());
+ sync('Steamworks.utils.getServerRealTime', () => client.utils.getServerRealTime());
+ sync('Steamworks.utils.isSteamRunningOnSteamDeck', () => client.utils.isSteamRunningOnSteamDeck());
+ async('Steamworks.utils.showGamepadTextInput', (inputMode, inputLineMode, description, maxCharacters, existingText) => client.utils.showGamepadTextInput(inputMode, inputLineMode, description, maxCharacters, existingText));
+ async('Steamworks.utils.showFloatingGamepadTextInput', (keyboardMode, x, y, width, height) => client.utils.showFloatingGamepadTextInput(keyboardMode, x, y, width, height));
+
+ async('Steamworks.workshop.createItem', (appId) => client.workshop.createItem(appId));
+ async('Steamworks.workshop.updateItem', (itemId, updateDetails, appId) => client.workshop.updateItem(itemId, updateDetails, appId));
+ async('Steamworks.workshop.updateItemWithCallback', (itemId, updateDetails, appId, successCallback, errorCallback, progressCallback, progressCallbackIntervalMs) => client.workshop.updateItemWithCallback(itemId, updateDetails, appId, successCallback, errorCallback, progressCallback, progressCallbackIntervalMs));
+ async('Steamworks.workshop.subscribe', (itemId) => client.workshop.subscribe(itemId));
+ async('Steamworks.workshop.unsubscribe', (itemId) => client.workshop.unsubscribe(itemId));
+ sync('Steamworks.workshop.state', (itemId) => client.workshop.state(itemId));
+ sync('Steamworks.workshop.installInfo', (itemId) => client.workshop.installInfo(itemId));
+ sync('Steamworks.workshop.downloadInfo', (itemId) => client.workshop.downloadInfo(itemId));
+ sync('Steamworks.workshop.download', (itemId, highPriority) => client.workshop.download(itemId, highPriority));
+ sync('Steamworks.workshop.getSubscribedItems', () => client.workshop.getSubscribedItems());
+ async('Steamworks.workshop.getItem', (item, queryConfig) => client.workshop.getItem(item, queryConfig));
+ async('Steamworks.workshop.getItems', (items, queryConfig) => client.workshop.getItems(items, queryConfig));
+ async('Steamworks.workshop.getAllItems', (page, queryType, itemType, creatorAppId, consumerAppId, queryConfig) => client.workshop.getAllItems(page, queryType, itemType, creatorAppId, consumerAppId, queryConfig));
+ async('Steamworks.workshop.getUserItems', (page, accountId, listType, itemType, sortOrder, creatorAppId, consumerAppId, queryConfig) => client.workshop.getUserItems(page, accountId, listType, itemType, sortOrder, creatorAppId, consumerAppId, queryConfig));
+
+ steamworks.electronEnableSteamOverlay();
+ sync('Steamworks.ok', () => true);
+ };
+ try {
+ enableSteamworks();
+ } catch (e) {
+ console.error(e);
+ ipcMain.on('Steamworks.ok', (e) => {
+ e.returnValue = false;
+ });
+ app.whenReady().then(() => {
+ const ON_ERROR = ${JSON.stringify(this.options.steamworks.onError)};
+ const window = BrowserWindow.getAllWindows()[0];
+ if (ON_ERROR === 'warning') {
+ dialog.showMessageBox(window, {
+ type: 'error',
+ message: 'Error initializing Steamworks: ' + e,
+ });
+ } else if (ON_ERROR === 'error') {
+ dialog.showMessageBoxSync(window, {
+ type: 'error',
+ message: 'Error initializing Steamworks: ' + e,
+ });
+ app.quit();
+ }
+ });
+ }`;
+
+ preloadJS += `
+ const enableSteamworks = () => {
+ const sync = (event) => (...args) => ipcRenderer.sendSync(event, ...args);
+ const async = (event) => (...args) => ipcRenderer.invoke(event, ...args);
+ contextBridge.exposeInMainWorld('Steamworks', {
+ ok: sync('Steamworks.ok'),
+ achievement: {
+ activate: async('Steamworks.achievement.activate'),
+ clear: async('Steamworks.achievement.clear'),
+ isActivated: sync('Steamworks.achievement.isActivated'),
+ },
+ apps: {
+ isDlcInstalled: async('Steamworks.apps.isDlcInstalled'),
+ },
+ leaderboard: {
+ uploadScore: async('Steamworks.leaderboard.uploadScore'),
+ },
+ localplayer: {
+ getName: sync('Steamworks.localplayer.getName'),
+ getLevel: sync('Steamworks.localplayer.getLevel'),
+ getIpCountry: sync('Steamworks.localplayer.getIpCountry'),
+ getSteamId: sync('Steamworks.localplayer.getSteamId'),
+ },
+ overlay: {
+ activateToWebPage: async('Steamworks.overlay.activateToWebPage'),
+ },
+ });
+ };
+ enableSteamworks();`;
+
+ const steamworksBuffer = await this.fetchLargeAsset('steamworks.js', 'arraybuffer');
+ const steamworksZip = await (await getJSZip()).loadAsync(steamworksBuffer);
+ for (const [path, file] of Object.entries(steamworksZip.files)) {
+ const newPath = path.replace(/^package\//, 'steamworks.js/');
+ setFileFast(zip, `${resourcesPrefix}${newPath}`, file);
+ }
+ }
+
zip.file(`${resourcesPrefix}${electronMainName}`, mainJS);
+ zip.file(`${resourcesPrefix}${electronPreloadName}`, preloadJS);
for (const [path, data] of Object.entries(projectZip.files)) {
setFileFast(zip, `${resourcesPrefix}${path}`, data);
@@ -1672,6 +1840,12 @@ Packager.DEFAULT_OPTIONS = () => ({
y: 0
}
},
+ steamworks: {
+ // 480 is Spacewar, the Steamworks demo game
+ appId: '480',
+ // 'ignore' (no alert), 'warning' (alert and continue), or 'error' (alert and exit)
+ onError: 'warning'
+ },
extensions: [],
bakeExtensions: true,
maxTextureDimension: 2048
From db5dac20329947ac50a1d1fc0decd0033352e3f0 Mon Sep 17 00:00:00 2001
From: PuzzlingGGG <138084889+PuzzlingGGG@users.noreply.github.com>
Date: Sun, 28 Jul 2024 22:25:31 -0400
Subject: [PATCH 05/13] Update en.json
---
src/locales/en.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/locales/en.json b/src/locales/en.json
index 459d8af2..2cff37b7 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -457,11 +457,11 @@
"string": "Zip, combine assets into single file (not recommended)"
},
"application-win32": {
- "string": "{type} Windows application (32-bit or 64-bit)",
+ "string": "{type} Windows application (32-bit)",
"context": "type will become something like 'NW.js' or 'Electron'. Do not translate 'Windows'."
},
"application-win64": {
- "string": "{type} Windows application (64-bit only, not recommended)",
+ "string": "{type} Windows application (64-bit)",
"context": "type will become something like 'NW.js' or 'Electron'. Do not translate 'Windows'."
},
"application-win-arm": {
@@ -522,7 +522,7 @@
"string": "Increase max vector costume resolution to make large costumes look better. May increase memory use and cause crashes."
},
"steamworksUnavailable": {
- "string": "To enable the Steamworks extension, you must use one of the Electron environments."
+ "string": "To enable the Steamworks extension, you must use one of these environments:"
},
"steamworksAvailable": {
"string": "This project is using the Steamworks extension. You can find your game's app ID in Steamworks. 480 is the ID of the Steamworks demo game (Spacewar)."
From e77fea8032ec2dd9e05bd0377f4133802bd82810 Mon Sep 17 00:00:00 2001
From: PuzzlingGGG <138084889+PuzzlingGGG@users.noreply.github.com>
Date: Sun, 28 Jul 2024 22:27:03 -0400
Subject: [PATCH 06/13] Update PackagerOptions.svelte
---
src/p4/PackagerOptions.svelte | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/p4/PackagerOptions.svelte b/src/p4/PackagerOptions.svelte
index 59df800a..7b5655a6 100644
--- a/src/p4/PackagerOptions.svelte
+++ b/src/p4/PackagerOptions.svelte
@@ -1034,7 +1034,7 @@
}}
>
Steamworks
- {#if $options.target.startsWith('electron-')}
+ {#if ['electron-win64', 'electron-linux64', 'electron-mac'].includes($options.target)}
{$_('options.steamworksAvailable')}
{:else}
{$_('options.steamworksUnavailable')}
+
+ - {$_('options.application-win64').replace('{type}', 'Electron')}
+ - {$_('options.application-mac').replace('{type}', 'Electron')}
+ - {$_('options.application-linux64').replace('{type}', 'Electron')}
+
{/if}
{/if}
From a119dc43947cf33f990def159399f99e096d5c09 Mon Sep 17 00:00:00 2001
From: PuzzlingGGG <138084889+PuzzlingGGG@users.noreply.github.com>
Date: Sun, 28 Jul 2024 22:28:15 -0400
Subject: [PATCH 07/13] Update packager.js
---
src/packager/packager.js | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/packager/packager.js b/src/packager/packager.js
index 310fe1d1..3c240192 100644
--- a/src/packager/packager.js
+++ b/src/packager/packager.js
@@ -727,7 +727,10 @@ app.whenReady().then(() => {
const {contextBridge, ipcRenderer} = require('electron');
`;
- if (this.project.analysis.usesSteamworks) {
+ if (
+ this.project.analysis.usesSteamworks &&
+ ['electron-win64', 'electron-linux64', 'electron-mac'].includes(this.options.target)
+ ) {
mainJS += `
const enableSteamworks = () => {
const APP_ID = +${JSON.stringify(this.options.steamworks.appId)};
From 0666e0233fa235ac12fed0311091cc5c70e639a6 Mon Sep 17 00:00:00 2001
From: PuzzlingGGG <138084889+PuzzlingGGG@users.noreply.github.com>
Date: Sun, 28 Jul 2024 22:29:04 -0400
Subject: [PATCH 08/13] Update en.json
---
src/locales/en.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/locales/en.json b/src/locales/en.json
index 2cff37b7..9efd3d0d 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -473,7 +473,7 @@
"context": "type will become something like 'NW.js' or 'Electron'. Do not translate 'macOS'."
},
"application-linux64": {
- "string": "{type} Linux application (64-bit only)",
+ "string": "{type} Linux application (64-bit)",
"context": "type will become something like 'NW.js' or 'Electron'. Do not translate 'Linux'."
},
"application-linux-arm32": {
From 32b614d26d769a43e57fd4494fd45e81111b3b16 Mon Sep 17 00:00:00 2001
From: PuzzlingGGG <138084889+PuzzlingGGG@users.noreply.github.com>
Date: Sun, 28 Jul 2024 22:30:45 -0400
Subject: [PATCH 09/13] Update packager.js
---
src/packager/packager.js | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/src/packager/packager.js b/src/packager/packager.js
index 3c240192..6047e208 100644
--- a/src/packager/packager.js
+++ b/src/packager/packager.js
@@ -663,12 +663,23 @@ const openLink = (url) => {
}
};
+const createProcessCrashMessage = (details) => {
+ let message = details.type ? details.type + ' child process' : 'Renderer process';
+ message += ' crashed: ' + details.reason + ' (' + details.exitCode + ')\\n\\n';
+ if (process.arch === 'ia32') {
+ message += 'Usually this means the project was too big for the 32-bit Electron environment or your computer is out of memory. Ask the creator to use the 64-bit environment instead.';
+ } else {
+ message += 'Usually this means your computer is out of memory.';
+ }
+ return message;
+};
+
app.on('render-process-gone', (event, webContents, details) => {
const window = BrowserWindow.fromWebContents(webContents);
dialog.showMessageBoxSync(window, {
type: 'error',
title: 'Error',
- message: 'Renderer process crashed: ' + details.reason + ' (' + details.exitCode + ')'
+ message: createProcessCrashMessage(details)
});
});
@@ -676,7 +687,7 @@ app.on('child-process-gone', (event, details) => {
dialog.showMessageBoxSync({
type: 'error',
title: 'Error',
- message: details.type + ' child process crashed: ' + details.reason + ' (' + details.exitCode + ')'
+ message: createProcessCrashMessage(details)
});
});
From 945338caf46cc798f158e23bcc8eb471b9e45088 Mon Sep 17 00:00:00 2001
From: PuzzlingGGG <138084889+PuzzlingGGG@users.noreply.github.com>
Date: Sun, 28 Jul 2024 22:33:36 -0400
Subject: [PATCH 10/13] Update en.json
---
src/locales/en.json | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/src/locales/en.json b/src/locales/en.json
index 9efd3d0d..80e9b00e 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -521,11 +521,19 @@
"maxTextureDimension": {
"string": "Increase max vector costume resolution to make large costumes look better. May increase memory use and cause crashes."
},
+ "steamworksExtension": {
+ "string": "Steamworks Extension",
+ "context": "Title of section that appears when using the Steamworks extension"
+ },
+ "steamworksDocumentation": {
+ "string": "See the extension's documentation for more details.",
+ "context": "Link to more documentation about the Steamworks extension"
+ },
"steamworksUnavailable": {
"string": "To enable the Steamworks extension, you must use one of these environments:"
},
"steamworksAvailable": {
- "string": "This project is using the Steamworks extension. You can find your game's app ID in Steamworks. 480 is the ID of the Steamworks demo game (Spacewar)."
+ "string": "This project is using the Steamworks extension. You can find your game's App ID in Steamworks, or use {n} for testing with the Steamworks demo game."
},
"steamworksAppId": {
"string": "App ID"
From 8f2d6d600c43e26a29427e64d27543a05fd6001f Mon Sep 17 00:00:00 2001
From: PuzzlingGGG <138084889+PuzzlingGGG@users.noreply.github.com>
Date: Sun, 28 Jul 2024 22:35:44 -0400
Subject: [PATCH 11/13] Update PackagerOptions.svelte
---
src/p4/PackagerOptions.svelte | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/p4/PackagerOptions.svelte b/src/p4/PackagerOptions.svelte
index 7b5655a6..c91e8699 100644
--- a/src/p4/PackagerOptions.svelte
+++ b/src/p4/PackagerOptions.svelte
@@ -1033,9 +1033,9 @@
]);
}}
>
-
Steamworks
+
{$_('options.steamworksExtension')}
{#if ['electron-win64', 'electron-linux64', 'electron-mac'].includes($options.target)}
-
{$_('options.steamworksAvailable')}
+
{$_('options.steamworksAvailable').replace('{n}', '480')}