mirror of
https://github.com/tobspr-games/shapez.io.git
synced 2025-12-06 02:30:37 -08:00
Start to prepare wegame build
This commit is contained in:
parent
a3fb3c432a
commit
6e9fa89792
8 changed files with 902 additions and 0 deletions
280
electron_wegame/index.js
Normal file
280
electron_wegame/index.js
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
/* eslint-disable quotes,no-undef */
|
||||
|
||||
const { app, BrowserWindow, Menu, MenuItem, ipcMain, shell } = require("electron");
|
||||
const path = require("path");
|
||||
const url = require("url");
|
||||
const fs = require("fs");
|
||||
const wegame = require("./wegame");
|
||||
const asyncLock = require("async-lock");
|
||||
|
||||
const isDev = process.argv.indexOf("--dev") >= 0;
|
||||
const isLocal = process.argv.indexOf("--local") >= 0;
|
||||
|
||||
const roamingFolder =
|
||||
process.env.APPDATA ||
|
||||
(process.platform == "darwin"
|
||||
? process.env.HOME + "/Library/Preferences"
|
||||
: process.env.HOME + "/.local/share");
|
||||
let storePath = path.join(roamingFolder, "shapez.io", "saves");
|
||||
|
||||
if (!fs.existsSync(storePath)) {
|
||||
// No try-catch by design
|
||||
fs.mkdirSync(storePath, { recursive: true });
|
||||
}
|
||||
|
||||
/** @type {BrowserWindow} */
|
||||
let win = null;
|
||||
let menu = null;
|
||||
|
||||
function createWindow() {
|
||||
let faviconExtension = ".png";
|
||||
if (process.platform === "win32") {
|
||||
faviconExtension = ".ico";
|
||||
}
|
||||
|
||||
win = new BrowserWindow({
|
||||
width: 1280,
|
||||
height: 800,
|
||||
show: false,
|
||||
backgroundColor: "#222428",
|
||||
useContentSize: true,
|
||||
minWidth: 800,
|
||||
minHeight: 600,
|
||||
title: "shapez.io Standalone",
|
||||
transparent: false,
|
||||
icon: path.join(__dirname, "favicon" + faviconExtension),
|
||||
// fullscreen: true,
|
||||
autoHideMenuBar: true,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
webSecurity: false,
|
||||
},
|
||||
allowRunningInsecureContent: false,
|
||||
});
|
||||
|
||||
if (isLocal) {
|
||||
win.loadURL("http://localhost:3005");
|
||||
} else {
|
||||
win.loadURL(
|
||||
url.format({
|
||||
pathname: path.join(__dirname, "index.html"),
|
||||
protocol: "file:",
|
||||
slashes: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
win.webContents.session.clearCache();
|
||||
win.webContents.session.clearStorageData();
|
||||
|
||||
win.webContents.on("new-window", (event, pth) => {
|
||||
event.preventDefault();
|
||||
shell.openExternal(pth);
|
||||
});
|
||||
|
||||
win.on("closed", () => {
|
||||
console.log("Window closed");
|
||||
win = null;
|
||||
});
|
||||
|
||||
if (isDev) {
|
||||
menu = new Menu();
|
||||
|
||||
const mainItem = new MenuItem({
|
||||
label: "Toggle Dev Tools",
|
||||
click: () => win.toggleDevTools(),
|
||||
accelerator: "F12",
|
||||
});
|
||||
menu.append(mainItem);
|
||||
|
||||
const reloadItem = new MenuItem({
|
||||
label: "Restart",
|
||||
click: () => win.reload(),
|
||||
accelerator: "F5",
|
||||
});
|
||||
menu.append(reloadItem);
|
||||
|
||||
const fullscreenItem = new MenuItem({
|
||||
label: "Fullscreen",
|
||||
click: () => win.setFullScreen(!win.isFullScreen()),
|
||||
accelerator: "F11",
|
||||
});
|
||||
menu.append(fullscreenItem);
|
||||
|
||||
Menu.setApplicationMenu(menu);
|
||||
} else {
|
||||
Menu.setApplicationMenu(null);
|
||||
}
|
||||
|
||||
win.once("ready-to-show", () => {
|
||||
win.show();
|
||||
win.focus();
|
||||
});
|
||||
}
|
||||
|
||||
if (!app.requestSingleInstanceLock()) {
|
||||
app.exit(0);
|
||||
} else {
|
||||
app.on("second-instance", (event, commandLine, workingDirectory) => {
|
||||
// Someone tried to run a second instance, we should focus
|
||||
if (win) {
|
||||
if (win.isMinimized()) {
|
||||
win.restore();
|
||||
}
|
||||
win.focus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
app.on("ready", createWindow);
|
||||
|
||||
app.on("window-all-closed", () => {
|
||||
console.log("All windows closed");
|
||||
app.quit();
|
||||
});
|
||||
|
||||
ipcMain.on("set-fullscreen", (event, flag) => {
|
||||
win.setFullScreen(flag);
|
||||
});
|
||||
|
||||
ipcMain.on("exit-app", (event, flag) => {
|
||||
win.close();
|
||||
app.quit();
|
||||
});
|
||||
|
||||
let renameCounter = 1;
|
||||
|
||||
const fileLock = new asyncLock({
|
||||
timeout: 30000,
|
||||
maxPending: 1000,
|
||||
});
|
||||
|
||||
function niceFileName(filename) {
|
||||
return filename.replace(storePath, "@");
|
||||
}
|
||||
|
||||
async function writeFileSafe(filename, contents) {
|
||||
++renameCounter;
|
||||
const prefix = "[ " + renameCounter + ":" + niceFileName(filename) + " ] ";
|
||||
const transactionId = String(new Date().getTime()) + "." + renameCounter;
|
||||
|
||||
if (fileLock.isBusy()) {
|
||||
console.warn(prefix, "Concurrent write process on", filename);
|
||||
}
|
||||
|
||||
fileLock.acquire(filename, async () => {
|
||||
console.log(prefix, "Starting write on", niceFileName(filename), "in transaction", transactionId);
|
||||
|
||||
if (!fs.existsSync(filename)) {
|
||||
// this one is easy
|
||||
console.log(prefix, "Writing file instantly because it does not exist:", niceFileName(filename));
|
||||
await fs.promises.writeFile(filename, contents, { encoding: "utf8" });
|
||||
return;
|
||||
}
|
||||
|
||||
// first, write a temporary file (.tmp-XXX)
|
||||
const tempName = filename + ".tmp-" + transactionId;
|
||||
console.log(prefix, "Writing temporary file", niceFileName(tempName));
|
||||
await fs.promises.writeFile(tempName, contents, { encoding: "utf8" });
|
||||
|
||||
// now, rename the original file to (.backup-XXX)
|
||||
const oldTemporaryName = filename + ".backup-" + transactionId;
|
||||
console.log(
|
||||
prefix,
|
||||
"Renaming old file",
|
||||
niceFileName(filename),
|
||||
"to",
|
||||
niceFileName(oldTemporaryName)
|
||||
);
|
||||
await fs.promises.rename(filename, oldTemporaryName);
|
||||
|
||||
// now, rename the temporary file (.tmp-XXX) to the target
|
||||
console.log(
|
||||
prefix,
|
||||
"Renaming the temporary file",
|
||||
niceFileName(tempName),
|
||||
"to the original",
|
||||
niceFileName(filename)
|
||||
);
|
||||
await fs.promises.rename(tempName, filename);
|
||||
|
||||
// we are done now, try to create a backup, but don't fail if the backup fails
|
||||
try {
|
||||
// check if there is an old backup file
|
||||
const backupFileName = filename + ".backup";
|
||||
if (fs.existsSync(backupFileName)) {
|
||||
console.log(prefix, "Deleting old backup file", niceFileName(backupFileName));
|
||||
// delete the old backup
|
||||
await fs.promises.unlink(backupFileName);
|
||||
}
|
||||
|
||||
// rename the old file to the new backup file
|
||||
console.log(prefix, "Moving", niceFileName(oldTemporaryName), "to the backup file location");
|
||||
await fs.promises.rename(oldTemporaryName, backupFileName);
|
||||
} catch (ex) {
|
||||
console.error(prefix, "Failed to switch backup files:", ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function performFsJob(job) {
|
||||
const fname = path.join(storePath, job.filename);
|
||||
|
||||
switch (job.type) {
|
||||
case "read": {
|
||||
if (!fs.existsSync(fname)) {
|
||||
return {
|
||||
// Special FILE_NOT_FOUND error code
|
||||
error: "file_not_found",
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const data = await fs.promises.readFile(fname, { encoding: "utf8" });
|
||||
return {
|
||||
success: true,
|
||||
data,
|
||||
};
|
||||
} catch (ex) {
|
||||
return {
|
||||
error: ex,
|
||||
};
|
||||
}
|
||||
}
|
||||
case "write": {
|
||||
try {
|
||||
await writeFileSafe(fname, job.contents);
|
||||
return {
|
||||
success: true,
|
||||
data: job.contents,
|
||||
};
|
||||
} catch (ex) {
|
||||
return {
|
||||
error: ex,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
case "delete": {
|
||||
try {
|
||||
await fs.promises.unlink(fname);
|
||||
} catch (ex) {
|
||||
return {
|
||||
error: ex,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
|
||||
default:
|
||||
throw new Error("Unkown fs job: " + job.type);
|
||||
}
|
||||
}
|
||||
|
||||
ipcMain.handle("fs-job", (event, arg) => performFsJob(arg));
|
||||
|
||||
wegame.init(isDev);
|
||||
wegame.listen();
|
||||
Loading…
Add table
Add a link
Reference in a new issue