mirror of
https://github.com/tobspr/shapez.io.git
synced 2025-12-13 18:21:51 +00:00
Start to make mods safer
This commit is contained in:
parent
e12ed11c3e
commit
a0071681e7
@ -54,8 +54,11 @@ function createWindow() {
|
|||||||
// fullscreen: true,
|
// fullscreen: true,
|
||||||
autoHideMenuBar: true,
|
autoHideMenuBar: true,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
nodeIntegration: true,
|
nodeIntegration: false,
|
||||||
webSecurity: false,
|
webSecurity: false,
|
||||||
|
// sandbox: true,
|
||||||
|
contextIsolation: true,
|
||||||
|
preload: path.join(__dirname, "preload.js"),
|
||||||
},
|
},
|
||||||
allowRunningInsecureContent: false,
|
allowRunningInsecureContent: false,
|
||||||
});
|
});
|
||||||
|
|||||||
3
electron/preload.js
Normal file
3
electron/preload.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
const { contextBridge, ipcRenderer } = require("electron");
|
||||||
|
|
||||||
|
contextBridge.exposeInMainWorld("ipcRenderer", ipcRenderer);
|
||||||
@ -19,7 +19,8 @@
|
|||||||
"publishStandalone": "yarn publishOnItch && yarn publishOnSteam",
|
"publishStandalone": "yarn publishOnItch && yarn publishOnSteam",
|
||||||
"publishWeb": "cd gulp && yarn main.deploy.prod",
|
"publishWeb": "cd gulp && yarn main.deploy.prod",
|
||||||
"publish": "yarn publishStandalone && yarn publishWeb",
|
"publish": "yarn publishStandalone && yarn publishWeb",
|
||||||
"syncTranslations": "node sync-translations.js"
|
"syncTranslations": "node sync-translations.js",
|
||||||
|
"buildTypes": "tsc src/js/application.js --declaration --allowJs --emitDeclarationOnly --skipLibCheck --out types.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "^7.5.4",
|
"@babel/core": "^7.5.4",
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { BaseItem } from "../game/base_item";
|
import { BaseItem } from "../game/base_item";
|
||||||
import { ClickDetector } from "./click_detector";
|
import { ClickDetector } from "./click_detector";
|
||||||
import { Signal } from "./signal";
|
import { Signal } from "./signal";
|
||||||
import { getIPCRenderer } from "./utils";
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ***************************************************
|
* ***************************************************
|
||||||
@ -113,13 +112,11 @@ export class FormElementInput extends FormElement {
|
|||||||
if (G_WEGAME_VERSION) {
|
if (G_WEGAME_VERSION) {
|
||||||
const value = String(this.element.value);
|
const value = String(this.element.value);
|
||||||
|
|
||||||
getIPCRenderer()
|
ipcRenderer.invoke("profanity-check", value).then(newValue => {
|
||||||
.invoke("profanity-check", value)
|
if (value !== newValue && this.element) {
|
||||||
.then(newValue => {
|
this.element.value = newValue;
|
||||||
if (value !== newValue && this.element) {
|
}
|
||||||
this.element.value = newValue;
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -42,21 +42,6 @@ export function getPlatformName() {
|
|||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the IPC renderer, or null if not within the standalone
|
|
||||||
* @returns {object|null}
|
|
||||||
*/
|
|
||||||
let ipcRenderer = null;
|
|
||||||
export function getIPCRenderer() {
|
|
||||||
if (!G_IS_STANDALONE) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (!ipcRenderer) {
|
|
||||||
ipcRenderer = eval("require")("electron").ipcRenderer;
|
|
||||||
}
|
|
||||||
return ipcRenderer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes a new 2D array with undefined contents
|
* Makes a new 2D array with undefined contents
|
||||||
* @param {number} w
|
* @param {number} w
|
||||||
|
|||||||
@ -602,7 +602,7 @@ export class RegularGameMode extends GameMode {
|
|||||||
/** @type {(typeof MetaBuilding)[]} */
|
/** @type {(typeof MetaBuilding)[]} */
|
||||||
this.hiddenBuildings = [MetaConstantProducerBuilding, MetaGoalAcceptorBuilding, MetaBlockBuilding];
|
this.hiddenBuildings = [MetaConstantProducerBuilding, MetaGoalAcceptorBuilding, MetaBlockBuilding];
|
||||||
|
|
||||||
// @ts-expect-error
|
// @ts-ignore
|
||||||
if (!(G_IS_DEV || window.sandboxMode || queryParamOptions.sandboxMode)) {
|
if (!(G_IS_DEV || window.sandboxMode || queryParamOptions.sandboxMode)) {
|
||||||
this.hiddenBuildings.push(MetaItemProducerBuilding);
|
this.hiddenBuildings.push(MetaItemProducerBuilding);
|
||||||
}
|
}
|
||||||
|
|||||||
2
src/js/globals.d.ts
vendored
2
src/js/globals.d.ts
vendored
@ -24,6 +24,8 @@ declare const G_WEGAME_VERSION: boolean;
|
|||||||
|
|
||||||
declare const shapez: any;
|
declare const shapez: any;
|
||||||
|
|
||||||
|
declare const ipcRenderer: any;
|
||||||
|
|
||||||
// Polyfills
|
// Polyfills
|
||||||
declare interface String {
|
declare interface String {
|
||||||
replaceAll(search: string, replacement: string): string;
|
replaceAll(search: string, replacement: string): string;
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
/* typehints:start */
|
/* typehints:start */
|
||||||
import { Application } from "../application";
|
import { Application } from "../application";
|
||||||
/* typehints:end */
|
/* typehints:end */
|
||||||
|
|
||||||
import { globalConfig } from "../core/config";
|
import { globalConfig } from "../core/config";
|
||||||
import { createLogger } from "../core/logging";
|
import { createLogger } from "../core/logging";
|
||||||
import { getIPCRenderer } from "../core/utils";
|
|
||||||
import { Mod } from "./mod";
|
import { Mod } from "./mod";
|
||||||
import { ModInterface } from "./mod_interface";
|
import { ModInterface } from "./mod_interface";
|
||||||
import { MOD_SIGNALS } from "./mod_signals";
|
import { MOD_SIGNALS } from "./mod_signals";
|
||||||
@ -76,12 +74,17 @@ export class ModLoader {
|
|||||||
|
|
||||||
this.exposeExports();
|
this.exposeExports();
|
||||||
|
|
||||||
|
window.registerMod = mod => {
|
||||||
|
this.modLoadQueue.push(mod);
|
||||||
|
};
|
||||||
|
|
||||||
if (G_IS_STANDALONE || G_IS_DEV) {
|
if (G_IS_STANDALONE || G_IS_DEV) {
|
||||||
try {
|
try {
|
||||||
let mods = [];
|
let mods = [];
|
||||||
if (G_IS_STANDALONE) {
|
if (G_IS_STANDALONE) {
|
||||||
mods = await getIPCRenderer().invoke("get-mods");
|
mods = await ipcRenderer.invoke("get-mods");
|
||||||
} else if (G_IS_DEV && globalConfig.debug.externalModUrl) {
|
}
|
||||||
|
if (G_IS_DEV && globalConfig.debug.externalModUrl) {
|
||||||
const mod = await (
|
const mod = await (
|
||||||
await fetch(globalConfig.debug.externalModUrl, {
|
await fetch(globalConfig.debug.externalModUrl, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
@ -91,12 +94,8 @@ export class ModLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mods.forEach(modCode => {
|
mods.forEach(modCode => {
|
||||||
window.registerMod = mod => {
|
const func = new Function(modCode);
|
||||||
this.modLoadQueue.push(mod);
|
func();
|
||||||
};
|
|
||||||
// ugh
|
|
||||||
eval(modCode);
|
|
||||||
delete window.registerMod;
|
|
||||||
});
|
});
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
alert("Failed to load mods: " + ex);
|
alert("Failed to load mods: " + ex);
|
||||||
@ -111,6 +110,8 @@ export class ModLoader {
|
|||||||
});
|
});
|
||||||
this.modLoadQueue = [];
|
this.modLoadQueue = [];
|
||||||
this.signals.postInit.dispatch();
|
this.signals.postInit.dispatch();
|
||||||
|
|
||||||
|
delete window.registerMod;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { Application } from "../application";
|
|||||||
/* typehints:end */
|
/* typehints:end */
|
||||||
import { createLogger } from "../core/logging";
|
import { createLogger } from "../core/logging";
|
||||||
import { compressX64 } from "../core/lzstring";
|
import { compressX64 } from "../core/lzstring";
|
||||||
import { getIPCRenderer } from "../core/utils";
|
|
||||||
import { T } from "../translations";
|
import { T } from "../translations";
|
||||||
|
|
||||||
const logger = createLogger("puzzle-api");
|
const logger = createLogger("puzzle-api");
|
||||||
@ -113,9 +112,7 @@ export class ClientAPI {
|
|||||||
return Promise.resolve({ token });
|
return Promise.resolve({ token });
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderer = getIPCRenderer();
|
return ipcRenderer.invoke("steam:get-ticket").then(
|
||||||
|
|
||||||
return renderer.invoke("steam:get-ticket").then(
|
|
||||||
ticket => {
|
ticket => {
|
||||||
logger.log("Got auth ticket:", ticket);
|
logger.log("Got auth ticket:", ticket);
|
||||||
return this._request("/v1/public/login", {
|
return this._request("/v1/public/login", {
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import { GameRoot } from "../../game/root";
|
|||||||
/* typehints:end */
|
/* typehints:end */
|
||||||
|
|
||||||
import { createLogger } from "../../core/logging";
|
import { createLogger } from "../../core/logging";
|
||||||
import { getIPCRenderer } from "../../core/utils";
|
|
||||||
import { ACHIEVEMENTS, AchievementCollection, AchievementProviderInterface } from "../achievement_provider";
|
import { ACHIEVEMENTS, AchievementCollection, AchievementProviderInterface } from "../achievement_provider";
|
||||||
|
|
||||||
const logger = createLogger("achievements/steam");
|
const logger = createLogger("achievements/steam");
|
||||||
@ -109,9 +108,7 @@ export class SteamAchievementProvider extends AchievementProviderInterface {
|
|||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ipc = getIPCRenderer();
|
return ipcRenderer.invoke("steam:is-initialized").then(initialized => {
|
||||||
|
|
||||||
return this.ipc.invoke("steam:is-initialized").then(initialized => {
|
|
||||||
this.initialized = initialized;
|
this.initialized = initialized;
|
||||||
|
|
||||||
if (!this.initialized) {
|
if (!this.initialized) {
|
||||||
@ -136,7 +133,7 @@ export class SteamAchievementProvider extends AchievementProviderInterface {
|
|||||||
if (!this.initialized) {
|
if (!this.initialized) {
|
||||||
promise = Promise.resolve();
|
promise = Promise.resolve();
|
||||||
} else {
|
} else {
|
||||||
promise = this.ipc.invoke("steam:activate-achievement", ACHIEVEMENT_IDS[key]);
|
promise = ipcRenderer.invoke("steam:activate-achievement", ACHIEVEMENT_IDS[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return promise
|
return promise
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { StorageInterface } from "../storage";
|
import { StorageInterface } from "../storage";
|
||||||
import { getIPCRenderer } from "../../core/utils";
|
|
||||||
import { createLogger } from "../../core/logging";
|
import { createLogger } from "../../core/logging";
|
||||||
|
|
||||||
const logger = createLogger("electron-storage");
|
const logger = createLogger("electron-storage");
|
||||||
@ -12,7 +11,7 @@ export class StorageImplElectron extends StorageInterface {
|
|||||||
this.jobs = {};
|
this.jobs = {};
|
||||||
this.jobId = 0;
|
this.jobId = 0;
|
||||||
|
|
||||||
getIPCRenderer().on("fs-response", (event, arg) => {
|
ipcRenderer.on("fs-response", (event, arg) => {
|
||||||
const id = arg.id;
|
const id = arg.id;
|
||||||
if (!this.jobs[id]) {
|
if (!this.jobs[id]) {
|
||||||
logger.warn("Got unhandled FS response, job not known:", id);
|
logger.warn("Got unhandled FS response, job not known:", id);
|
||||||
@ -37,7 +36,7 @@ export class StorageImplElectron extends StorageInterface {
|
|||||||
const jobId = ++this.jobId;
|
const jobId = ++this.jobId;
|
||||||
this.jobs[jobId] = { resolve, reject };
|
this.jobs[jobId] = { resolve, reject };
|
||||||
|
|
||||||
getIPCRenderer().send("fs-job", {
|
ipcRenderer.send("fs-job", {
|
||||||
type: "write",
|
type: "write",
|
||||||
filename,
|
filename,
|
||||||
contents,
|
contents,
|
||||||
@ -52,7 +51,7 @@ export class StorageImplElectron extends StorageInterface {
|
|||||||
const jobId = ++this.jobId;
|
const jobId = ++this.jobId;
|
||||||
this.jobs[jobId] = { resolve, reject };
|
this.jobs[jobId] = { resolve, reject };
|
||||||
|
|
||||||
getIPCRenderer().send("fs-job", {
|
ipcRenderer.send("fs-job", {
|
||||||
type: "read",
|
type: "read",
|
||||||
filename,
|
filename,
|
||||||
id: jobId,
|
id: jobId,
|
||||||
@ -65,7 +64,7 @@ export class StorageImplElectron extends StorageInterface {
|
|||||||
// ipcMain
|
// ipcMain
|
||||||
const jobId = ++this.jobId;
|
const jobId = ++this.jobId;
|
||||||
this.jobs[jobId] = { resolve, reject };
|
this.jobs[jobId] = { resolve, reject };
|
||||||
getIPCRenderer().send("fs-job", {
|
ipcRenderer.send("fs-job", {
|
||||||
type: "delete",
|
type: "delete",
|
||||||
filename,
|
filename,
|
||||||
id: jobId,
|
id: jobId,
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import { NoAchievementProvider } from "../browser/no_achievement_provider";
|
import { NoAchievementProvider } from "../browser/no_achievement_provider";
|
||||||
import { PlatformWrapperImplBrowser } from "../browser/wrapper";
|
import { PlatformWrapperImplBrowser } from "../browser/wrapper";
|
||||||
import { getIPCRenderer } from "../../core/utils";
|
|
||||||
import { createLogger } from "../../core/logging";
|
import { createLogger } from "../../core/logging";
|
||||||
import { StorageImplElectron } from "./storage";
|
import { StorageImplElectron } from "./storage";
|
||||||
import { SteamAchievementProvider } from "./steam_achievement_provider";
|
import { SteamAchievementProvider } from "./steam_achievement_provider";
|
||||||
@ -71,15 +70,13 @@ export class PlatformWrapperImplElectron extends PlatformWrapperImplBrowser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
initializeDlcStatus() {
|
initializeDlcStatus() {
|
||||||
const renderer = getIPCRenderer();
|
|
||||||
|
|
||||||
if (G_WEGAME_VERSION) {
|
if (G_WEGAME_VERSION) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.log("Checking DLC ownership ...");
|
logger.log("Checking DLC ownership ...");
|
||||||
// @todo: Don't hardcode the app id
|
// @todo: Don't hardcode the app id
|
||||||
return renderer.invoke("steam:check-app-ownership", 1625400).then(
|
return ipcRenderer.invoke("steam:check-app-ownership", 1625400).then(
|
||||||
res => {
|
res => {
|
||||||
logger.log("Got DLC ownership:", res);
|
logger.log("Got DLC ownership:", res);
|
||||||
this.dlcs.puzzle = Boolean(res);
|
this.dlcs.puzzle = Boolean(res);
|
||||||
@ -106,7 +103,7 @@ export class PlatformWrapperImplElectron extends PlatformWrapperImplBrowser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setFullscreen(flag) {
|
setFullscreen(flag) {
|
||||||
getIPCRenderer().send("set-fullscreen", flag);
|
ipcRenderer.send("set-fullscreen", flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
getSupportsAppExit() {
|
getSupportsAppExit() {
|
||||||
@ -115,6 +112,6 @@ export class PlatformWrapperImplElectron extends PlatformWrapperImplBrowser {
|
|||||||
|
|
||||||
exitApp() {
|
exitApp() {
|
||||||
logger.log(this, "Sending app exit signal");
|
logger.log(this, "Sending app exit signal");
|
||||||
getIPCRenderer().send("exit-app");
|
ipcRenderer.send("exit-app");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -405,12 +405,6 @@ export class MainMenuState extends GameState {
|
|||||||
makeButton(outerDiv, ["newGameButton", "styledButton"], T.mainMenu.newGame),
|
makeButton(outerDiv, ["newGameButton", "styledButton"], T.mainMenu.newGame),
|
||||||
this.onPlayButtonClicked
|
this.onPlayButtonClicked
|
||||||
);
|
);
|
||||||
|
|
||||||
// Mods
|
|
||||||
this.trackClicks(
|
|
||||||
makeButton(outerDiv, ["modsButton", "styledButton"], " "),
|
|
||||||
this.onModsClicked
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
// New game
|
// New game
|
||||||
this.trackClicks(
|
this.trackClicks(
|
||||||
@ -419,6 +413,9 @@ export class MainMenuState extends GameState {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mods
|
||||||
|
this.trackClicks(makeButton(outerDiv, ["modsButton", "styledButton"], " "), this.onModsClicked);
|
||||||
|
|
||||||
buttonContainer.appendChild(outerDiv);
|
buttonContainer.appendChild(outerDiv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import { THIRDPARTY_URLS } from "../core/config";
|
import { THIRDPARTY_URLS } from "../core/config";
|
||||||
import { TextualGameState } from "../core/textual_game_state";
|
import { TextualGameState } from "../core/textual_game_state";
|
||||||
import { getIPCRenderer } from "../core/utils";
|
|
||||||
import { MODS } from "../mods/modloader";
|
import { MODS } from "../mods/modloader";
|
||||||
import { T } from "../translations";
|
import { T } from "../translations";
|
||||||
|
|
||||||
@ -117,7 +116,7 @@ export class ModsState extends TextualGameState {
|
|||||||
this.dialogs.showWarning(T.global.error, T.mods.folderOnlyStandalone);
|
this.dialogs.showWarning(T.global.error, T.mods.folderOnlyStandalone);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getIPCRenderer().send("open-mods-folder");
|
ipcRenderer.send("open-mods-folder");
|
||||||
}
|
}
|
||||||
|
|
||||||
onSteamLinkClicked() {
|
onSteamLinkClicked() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user