-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.js
123 lines (96 loc) · 2.93 KB
/
main.js
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
118
119
120
121
122
123
import { initDataLoop, isValidType } from "./data-loop.js";
import { handleConnection } from "./client.js";
import { initSlaves, initMasterRoutes } from "./master.js";
import { startTwitchUpdateLoop } from "./twitch.js";
import { checkAuth, parseServer, isValidLicense } from "./auth.js";
import { getSlaveData } from "./slave.js";
import { initServer } from "./server.js";
import { rejectClient } from "./functions.js";
import { registerErrorHandlers, registerConsole } from "./console.js";
import { initDatabases } from "./database.js";
import { SlaveHandler } from "./slave-handler.js";
import { success, warning } from "./colors.js";
import { parseArguments } from "./arguments.js";
import { createServer } from "node:http";
import cluster from "node:cluster";
import express from "express";
import { Server } from "socket.io";
import cors from "cors";
import { semver } from "bun";
if (!semver.satisfies(Bun.version, "^1.1.34")) {
console.error("Please use bun v1.1.34 or higher.");
process.exit(1);
}
registerErrorHandlers();
// Master handles all connections
if (cluster.isPrimary) {
registerConsole(false);
const { only } = parseArguments();
if (only) {
console.warn(warning(`Only initializing cluster ${only}!`));
}
// This is only needed once so its on the master too
startTwitchUpdateLoop();
// Initialize express server
const app = express(),
xp = createServer(app);
app.use(
cors({
origin: "*",
})
);
app.use(express.json());
// Connect to databases
await initDatabases(only);
// Wake up the slaves
initSlaves(only);
// Initialize routes
initMasterRoutes(app);
// Initialize socket.io server
const io = new Server(xp, {
cors: {
origin: "*",
methods: ["GET", "POST"],
},
});
io.on("connection", async client => {
const query = client.handshake.query,
server = parseServer(query.server),
token = query.token,
type = query.type,
license = query.license;
if (!isValidType(type) || !isValidLicense(license) || !token || !server) {
return rejectClient(client, "Invalid request");
}
if (!(await checkAuth(server.cluster, token, client.handshake.address))) {
return rejectClient(client, "Unauthorized");
}
if (!isValidType(type) || !isValidLicense(license)) {
return rejectClient(client, "Invalid request");
}
handleConnection(client, server.server, type, license);
});
// Start the server
xp.listen(9999, () => {
console.info(success("Listening on port 9999."));
});
} else {
// Get slave data first
const slave = getSlaveData();
// Register console overrides
registerConsole(slave.server);
// Initialize the server (async deferred, no await)
console.info("Initializing server...");
initServer(slave.server);
// Initialize handler
console.info("Initializing handler...");
new SlaveHandler();
// Initialize data-loop
console.info("Initializing data-loop...");
initDataLoop();
// Start the server
process.send({
type: "hello",
});
console.info("Startup complete");
}