1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2025-12-16 19:51:50 +00:00

Temporary mod support and cleanup in ipc event

This commit is contained in:
Даниїл Григор'єв 2022-01-14 16:55:18 +02:00
parent ebda1c5024
commit 1a6742eac1
No known key found for this signature in database
GPG Key ID: B890DF16341D8C1D

View File

@ -1,28 +1,29 @@
/* eslint-disable quotes,no-undef */ /* eslint-disable quotes,no-undef */
const { app, BrowserWindow, Menu, MenuItem, ipcMain, shell } = require("electron"); const { app, BrowserWindow, Menu, MenuItem, ipcMain, shell } = require("electron");
const path = require("path"); const { join, dirname, resolve } = require("path");
const url = require("url"); const url = require("url");
const fs = require("fs"); const fs = require("fs");
const steam = require("./steam"); const steam = require("./steam");
const asyncLock = require("async-lock"); const asyncLock = require("async-lock");
const isDev = process.argv.indexOf("--dev") >= 0; const isDev = app.commandLine.hasSwitch("dev");
const isLocal = process.argv.indexOf("--local") >= 0; const isLocal = app.commandLine.hasSwitch("local");
const safeMode = process.argv.indexOf("--safe-mode") >= 0; const temporaryMod = app.commandLine.getSwitchValue("load-mod");
const safeMode = app.commandLine.hasSwitch("safe-mode");
const roamingFolder = const roamingFolder =
process.env.APPDATA || process.env.APPDATA ||
(process.platform == "darwin" (process.platform == "darwin"
? process.env.HOME + "/Library/Preferences" ? process.env.HOME + "/Library/Preferences"
: process.env.HOME + "/.local/share"); : process.env.HOME + "/.local/share");
let storePath = path.join(roamingFolder, "shapez.io", "saves");
let modsPath = path.join(path.dirname(app.getPath("exe")), "mods");
if (!fs.existsSync(storePath)) { const storePath = join(roamingFolder, "shapez.io", "saves");
// No try-catch by design const modsPath = join(dirname(app.getPath("exe")), "mods");
fs.mkdirSync(storePath, { recursive: true });
} // No try-catch by design
fs.mkdirSync(storePath, { recursive: true });
/** @type {BrowserWindow} */ /** @type {BrowserWindow} */
let win = null; let win = null;
@ -44,7 +45,7 @@ function createWindow() {
minHeight: 600, minHeight: 600,
title: "shapez.io Standalone", title: "shapez.io Standalone",
transparent: false, transparent: false,
icon: path.join(__dirname, "favicon" + faviconExtension), icon: join(__dirname, "favicon" + faviconExtension),
// fullscreen: true, // fullscreen: true,
autoHideMenuBar: true, autoHideMenuBar: true,
webPreferences: { webPreferences: {
@ -59,7 +60,7 @@ function createWindow() {
} else { } else {
win.loadURL( win.loadURL(
url.format({ url.format({
pathname: path.join(__dirname, "index.html"), pathname: join(__dirname, "index.html"),
protocol: "file:", protocol: "file:",
slashes: true, slashes: true,
}) })
@ -136,11 +137,11 @@ app.on("window-all-closed", () => {
app.quit(); app.quit();
}); });
ipcMain.on("set-fullscreen", (event, flag) => { ipcMain.on("set-fullscreen", (_event, flag) => {
win.setFullScreen(flag); win.setFullScreen(flag);
}); });
ipcMain.on("exit-app", (event, flag) => { ipcMain.on("exit-app", (_event, _flag) => {
win.close(); win.close();
app.quit(); app.quit();
}); });
@ -171,14 +172,14 @@ async function writeFileSafe(filename, contents) {
if (!fs.existsSync(filename)) { if (!fs.existsSync(filename)) {
// this one is easy // this one is easy
console.log(prefix, "Writing file instantly because it does not exist:", niceFileName(filename)); console.log(prefix, "Writing file instantly because it does not exist:", niceFileName(filename));
await fs.promises.writeFile(filename, contents, { encoding: "utf8" }); await fs.promises.writeFile(filename, contents, "utf-8");
return; return;
} }
// first, write a temporary file (.tmp-XXX) // first, write a temporary file (.tmp-XXX)
const tempName = filename + ".tmp-" + transactionId; const tempName = filename + ".tmp-" + transactionId;
console.log(prefix, "Writing temporary file", niceFileName(tempName)); console.log(prefix, "Writing temporary file", niceFileName(tempName));
await fs.promises.writeFile(tempName, contents, { encoding: "utf8" }); await fs.promises.writeFile(tempName, contents, "utf-8");
// now, rename the original file to (.backup-XXX) // now, rename the original file to (.backup-XXX)
const oldTemporaryName = filename + ".backup-" + transactionId; const oldTemporaryName = filename + ".backup-" + transactionId;
@ -221,7 +222,7 @@ async function writeFileSafe(filename, contents) {
} }
async function performFsJob(job) { async function performFsJob(job) {
const fname = path.join(storePath, job.filename); const fname = join(storePath, job.filename);
switch (job.type) { switch (job.type) {
case "read": { case "read": {
@ -233,7 +234,7 @@ async function performFsJob(job) {
} }
try { try {
const data = await fs.promises.readFile(fname, { encoding: "utf8" }); const data = await fs.promises.readFile(fname, "utf-8");
return { return {
success: true, success: true,
data, data,
@ -274,7 +275,7 @@ async function performFsJob(job) {
} }
default: default:
throw new Error("Unkown fs job: " + job.type); throw new Error("Unknown fs job: " + job.type);
} }
} }
@ -287,20 +288,49 @@ ipcMain.on("open-mods-folder", async () => {
shell.openPath(modsPath); shell.openPath(modsPath);
}); });
ipcMain.handle("get-mods", async (event, arg) => { async function searchForMods() {
if (safeMode) { const files = [];
console.warn("Not loading mods due to safe mode"); console.log("Searching for mods in %s", modsPath);
return [];
}
if (!fs.existsSync(modsPath)) {
console.warn("Mods folder not found:", modsPath);
return [];
}
try { try {
console.log("Loading mods from", modsPath); for (const file of await fs.promises.readdir(modsPath)) {
let entries = fs.readdirSync(modsPath); if (file.endsWith(".js")) {
entries = entries.filter(entry => entry.endsWith(".js")); modFiles.push(resolve(modsPath, file));
return entries.map(filename => fs.readFileSync(path.join(modsPath, filename), { encoding: "utf8" })); }
}
} catch (err) {
// Most likely, the directory does not exist (ENOENT)
console.warn("Failed to load mods from %s:", modsPath, err);
}
return files;
}
ipcMain.handle("get-mods", async (_event, _arg) => {
const modFiles = [];
if (temporaryMod) {
// Load mod specified on the command line.
// Together with --safe-mode, it's possible to load only
// this mod.
modFiles.push(resolve(temporaryMod));
}
if (!safeMode) {
modFiles.push(...(await searchForMods()));
} else {
console.log("Safe mode is turned on, skipping mod search");
}
try {
const modContents = [];
console.log("Loading %d mod(s)", modFiles.length);
for (const modFile of modFiles) {
modContents.push(await fs.promises.readFile(modFile, "utf-8"));
}
return modContents;
} catch (ex) { } catch (ex) {
throw new Error(ex); throw new Error(ex);
} }