Files

104 lines
2.7 KiB
JavaScript

const {
app,
BrowserWindow,
protocol,
session,
Menu,
dialog,
} = require("electron");
const path = require("node:path");
const { readGame } = require("./protocol.cjs");
const settings = require("./game-config.json");
protocol.registerSchemesAsPrivileged([
{
scheme: "forma",
privileges: {
standard: true,
secure: true,
supportFetchAPI: true,
corsEnabled: true,
stream: true,
},
},
]);
app.setName(settings.name);
let win;
async function createWindow() {
win = new BrowserWindow({
title: settings.name,
width: settings.width,
height: settings.height,
minWidth: 320,
minHeight: 320,
fullscreen: settings.fullscreen,
backgroundColor: "#151719",
show: false,
autoHideMenuBar: true,
webPreferences: {
sandbox: true,
contextIsolation: true,
nodeIntegration: false,
nodeIntegrationInWorker: false,
webSecurity: true,
devTools: settings.mode === "debug",
},
});
win.webContents.setWindowOpenHandler(() => ({ action: "deny" }));
win.webContents.on("will-navigate", (e, url) => {
if (url !== "forma://game/index.html") e.preventDefault();
});
win.webContents.on("will-attach-webview", (e) => e.preventDefault());
win.webContents.on("before-input-event", (e, input) => {
if (input.type === "keyDown" && input.key === "F11") {
win.setFullScreen(!win.isFullScreen());
e.preventDefault();
}
if (
input.type === "keyDown" &&
input.key === "Escape" &&
win.isFullScreen()
)
win.setFullScreen(false);
});
win.once("ready-to-show", () => win.show());
await win.loadURL("forma://game/index.html");
}
app
.whenReady()
.then(async () => {
if (app.commandLine.hasSwitch("no-sandbox")) {
dialog.showErrorBox(
"Sandbox unavailable",
"This game requires Chromium sandbox support. Enable unprivileged user namespaces on Linux, then restart without --no-sandbox.",
);
app.exit(1);
return;
}
Menu.setApplicationMenu(null);
session.defaultSession.setPermissionRequestHandler((_wc, _p, cb) =>
cb(false),
);
session.defaultSession.setPermissionCheckHandler(() => false);
session.defaultSession.webRequest.onBeforeRequest((details, cb) =>
cb({
cancel:
!details.url.startsWith("forma://game/") &&
!details.url.startsWith("blob:forma://game/"),
}),
);
protocol.handle("forma", async (request) => {
const r = await readGame(
path.join(__dirname, "game"),
request.url,
request.method,
);
return new Response(r.body, r);
});
await createWindow();
})
.catch((e) => {
console.error(e);
app.exit(1);
});
app.on("window-all-closed", () => app.quit());