-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathmain.ts
More file actions
117 lines (104 loc) · 3 KB
/
Copy pathmain.ts
File metadata and controls
117 lines (104 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import { app, BrowserWindow } from "electron";
import http from "http";
import fs from "fs";
import path from "path";
const ALLOWED_PATH_PREFIX = "/trials";
function getMimeType(filePath: string): string {
const ext = path.extname(filePath).toLowerCase();
const types: Record<string, string> = {
".html": "text/html",
".js": "application/javascript",
".css": "text/css",
".json": "application/json",
".png": "image/png",
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".gif": "image/gif",
".svg": "image/svg+xml",
".ico": "image/x-icon",
".wasm": "application/wasm",
".woff": "font/woff",
".woff2": "font/woff2",
".ttf": "font/ttf",
".mp3": "audio/mpeg",
".ogg": "audio/ogg",
".wav": "audio/wav",
".webp": "image/webp",
".webm": "video/webm",
".mp4": "video/mp4",
};
return types[ext] || "application/octet-stream";
}
function startLocalServer(distPath: string): Promise<number> {
return new Promise((resolve) => {
const server = http.createServer((req, res) => {
const url = new URL(req.url || "/", "http://localhost");
let filePath = path.join(distPath, url.pathname);
// Serve index.html for SPA routes
if (!fs.existsSync(filePath) || fs.statSync(filePath).isDirectory()) {
filePath = path.join(distPath, "index.html");
}
try {
const data = fs.readFileSync(filePath);
res.writeHead(200, { "Content-Type": getMimeType(filePath) });
res.end(data);
} catch {
res.writeHead(404);
res.end("Not found");
}
});
server.listen(0, "127.0.0.1", () => {
const addr = server.address();
const port = typeof addr === "object" && addr ? addr.port : 0;
resolve(port);
});
});
}
async function createWindow() {
const win = new BrowserWindow({
width: 1440,
height: 900,
title: "Loot Survivor 2",
webPreferences: {
contextIsolation: true,
nodeIntegration: false,
preload: path.join(__dirname, "preload.js"),
},
});
// Block navigation to routes outside /trials
win.webContents.on("will-navigate", (event, url) => {
try {
const parsed = new URL(url);
if (
!parsed.pathname.startsWith(ALLOWED_PATH_PREFIX) &&
parsed.pathname !== "/"
) {
event.preventDefault();
}
} catch {
event.preventDefault();
}
});
const isDev = !app.isPackaged;
if (isDev) {
await win.loadURL(`http://localhost:5173${ALLOWED_PATH_PREFIX}`);
} else {
const distPath = path.join(app.getAppPath(), "dist");
const port = await startLocalServer(distPath);
await win.loadURL(`http://127.0.0.1:${port}${ALLOWED_PATH_PREFIX}`);
}
}
app.whenReady().then(createWindow).catch((err) => {
console.error("Failed to create window:", err);
app.quit();
});
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});