Change HTTP server to require a function call to initialize
This commit is contained in:
parent
617c8c4bc5
commit
a82839085f
2
public
2
public
|
@ -1 +1 @@
|
||||||
Subproject commit a8a0182686cec166c3042697c639c5ca8b6acf6b
|
Subproject commit 1dc00c7f885ac919a1bda7d4c749d33bd594c42f
|
|
@ -13,14 +13,13 @@
|
||||||
// There are a lot of unhinged bs comments in this repo
|
// There are a lot of unhinged bs comments in this repo
|
||||||
// Pay no attention to the ones that cuss you out
|
// Pay no attention to the ones that cuss you out
|
||||||
|
|
||||||
// If you don't load the server first, bun will literally segfault
|
|
||||||
import "./ws/server";
|
|
||||||
import { loadForcedStartupChannels } from "./channel/forceload";
|
import { loadForcedStartupChannels } from "./channel/forceload";
|
||||||
import { Logger } from "./util/Logger";
|
import { Logger } from "./util/Logger";
|
||||||
// docker hates this next one
|
// docker hates this next one
|
||||||
import { startReadline } from "./util/readline";
|
import { startReadline } from "./util/readline";
|
||||||
import { loadDefaultPermissions } from "./data/permissions";
|
import { loadDefaultPermissions } from "./data/permissions";
|
||||||
import { loadBehaviors } from "./event/behaviors";
|
import { loadBehaviors } from "./event/behaviors";
|
||||||
|
import { startHTTPServer } from "./ws/server";
|
||||||
|
|
||||||
// wrapper for some reason
|
// wrapper for some reason
|
||||||
export function startServer() {
|
export function startServer() {
|
||||||
|
@ -38,6 +37,8 @@ export function startServer() {
|
||||||
// Break the console
|
// Break the console
|
||||||
logger.info("Starting REPL");
|
logger.info("Starting REPL");
|
||||||
startReadline();
|
startReadline();
|
||||||
|
|
||||||
|
startHTTPServer();
|
||||||
logger.info("Ready");
|
logger.info("Ready");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
172
src/ws/server.ts
172
src/ws/server.ts
|
@ -7,7 +7,7 @@ import { Socket, socketsByUUID } from "./Socket";
|
||||||
import env from "../util/env";
|
import env from "../util/env";
|
||||||
import { getMOTD } from "../util/motd";
|
import { getMOTD } from "../util/motd";
|
||||||
import nunjucks from "nunjucks";
|
import nunjucks from "nunjucks";
|
||||||
import type { ServerWebSocket } from "bun";
|
import type { Server, ServerWebSocket } from "bun";
|
||||||
import { ConfigManager } from "~/util/config";
|
import { ConfigManager } from "~/util/config";
|
||||||
import { config as usersConfig } from "./usersConfig";
|
import { config as usersConfig } from "./usersConfig";
|
||||||
|
|
||||||
|
@ -59,117 +59,121 @@ async function getIndex() {
|
||||||
|
|
||||||
type ServerWebSocketMPP = ServerWebSocket<{ ip: string; socket: Socket }>;
|
type ServerWebSocketMPP = ServerWebSocket<{ ip: string; socket: Socket }>;
|
||||||
|
|
||||||
export const app = Bun.serve<{ ip: string }>({
|
export let app: Server;
|
||||||
port: env.PORT,
|
|
||||||
hostname: "0.0.0.0",
|
|
||||||
fetch: (req, server) => {
|
|
||||||
const reqip = server.requestIP(req);
|
|
||||||
if (!reqip) return;
|
|
||||||
|
|
||||||
const ip = req.headers.get("x-forwarded-for") || reqip.address;
|
export function startHTTPServer() {
|
||||||
|
app = Bun.serve<{ ip: string }>({
|
||||||
|
port: env.PORT,
|
||||||
|
hostname: "0.0.0.0",
|
||||||
|
fetch: (req, server) => {
|
||||||
|
const reqip = server.requestIP(req);
|
||||||
|
if (!reqip) return;
|
||||||
|
|
||||||
// Upgrade websocket connections
|
const ip = req.headers.get("x-forwarded-for") || reqip.address;
|
||||||
if (server.upgrade(req, { data: { ip } })) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
httpIpCache.set(ip, Date.now());
|
// Upgrade websocket connections
|
||||||
const url = new URL(req.url).pathname;
|
if (server.upgrade(req, { data: { ip } })) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// lol
|
httpIpCache.set(ip, Date.now());
|
||||||
// const ip = decoder.decode(res.getRemoteAddressAsText());
|
const url = new URL(req.url).pathname;
|
||||||
// logger.debug(`${req.getMethod()} ${url} ${ip}`);
|
|
||||||
// res.writeStatus(`200 OK`).end("HI!");
|
|
||||||
|
|
||||||
// I have no clue if this is even safe...
|
// lol
|
||||||
// wtf do I do when the user types "/../.env" in the URL?
|
// const ip = decoder.decode(res.getRemoteAddressAsText());
|
||||||
// From my testing, nothing out of the ordinary happens...
|
// logger.debug(`${req.getMethod()} ${url} ${ip}`);
|
||||||
// but just in case, if you find something wrong with URLs,
|
// res.writeStatus(`200 OK`).end("HI!");
|
||||||
// this is the most likely culprit
|
|
||||||
|
|
||||||
const file = path.join("./public/", url);
|
// I have no clue if this is even safe...
|
||||||
|
// wtf do I do when the user types "/../.env" in the URL?
|
||||||
|
// From my testing, nothing out of the ordinary happens...
|
||||||
|
// but just in case, if you find something wrong with URLs,
|
||||||
|
// this is the most likely culprit
|
||||||
|
|
||||||
// Time for unreadable blocks of confusion
|
const file = path.join("./public/", url);
|
||||||
try {
|
|
||||||
// Is it a file?
|
|
||||||
if (fs.lstatSync(file).isFile()) {
|
|
||||||
// Read the file
|
|
||||||
const data = Bun.file(file);
|
|
||||||
|
|
||||||
// Return the file
|
// Time for unreadable blocks of confusion
|
||||||
if (data) {
|
try {
|
||||||
return new Response(data);
|
// Is it a file?
|
||||||
|
if (fs.lstatSync(file).isFile()) {
|
||||||
|
// Read the file
|
||||||
|
const data = Bun.file(file);
|
||||||
|
|
||||||
|
// Return the file
|
||||||
|
if (data) {
|
||||||
|
return new Response(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return getIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the index file, since it's a channel name or something
|
||||||
|
return getIndex();
|
||||||
|
} catch (err) {
|
||||||
|
// Return the index file as a coverup of our extreme failure
|
||||||
return getIndex();
|
return getIndex();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
websocket: {
|
||||||
|
open: (ws: ServerWebSocketMPP) => {
|
||||||
|
// swimming in the pool
|
||||||
|
const socket = new Socket(ws, createSocketID());
|
||||||
|
|
||||||
// Return the index file, since it's a channel name or something
|
ws.data.socket = socket;
|
||||||
return getIndex();
|
// logger.debug("Connection at " + socket.getIP());
|
||||||
} catch (err) {
|
|
||||||
// Return the index file as a coverup of our extreme failure
|
|
||||||
return getIndex();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
websocket: {
|
|
||||||
open: (ws: ServerWebSocketMPP) => {
|
|
||||||
// swimming in the pool
|
|
||||||
const socket = new Socket(ws, createSocketID());
|
|
||||||
|
|
||||||
ws.data.socket = socket;
|
if (socket.socketID === undefined) {
|
||||||
// logger.debug("Connection at " + socket.getIP());
|
socket.socketID = createSocketID();
|
||||||
|
}
|
||||||
|
|
||||||
if (socket.socketID === undefined) {
|
socketsByUUID.set(socket.getUUID(), socket);
|
||||||
socket.socketID = createSocketID();
|
|
||||||
}
|
|
||||||
|
|
||||||
socketsByUUID.set(socket.getUUID(), socket);
|
const ip = socket.getIP();
|
||||||
|
|
||||||
const ip = socket.getIP();
|
if (httpIpCache.has(ip)) {
|
||||||
|
const date = httpIpCache.get(ip);
|
||||||
|
|
||||||
if (httpIpCache.has(ip)) {
|
if (date) {
|
||||||
const date = httpIpCache.get(ip);
|
if (Date.now() - date < 1000 * 60) {
|
||||||
|
// They got the page and we were connected in under a minute
|
||||||
if (date) {
|
socket.gateway.hasConnectedToHTTPServer = true;
|
||||||
if (Date.now() - date < 1000 * 60) {
|
} else {
|
||||||
// They got the page and we were connected in under a minute
|
// They got the page and a long time has passed
|
||||||
socket.gateway.hasConnectedToHTTPServer = true;
|
httpIpCache.delete(ip);
|
||||||
} else {
|
}
|
||||||
// They got the page and a long time has passed
|
|
||||||
httpIpCache.delete(ip);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
|
||||||
|
|
||||||
message: (ws: ServerWebSocketMPP, message: string) => {
|
message: (ws: ServerWebSocketMPP, message: string) => {
|
||||||
// Fucking string
|
// Fucking string
|
||||||
const msg = message.toString();
|
const msg = message.toString();
|
||||||
|
|
||||||
// Let's find out wtf they even sent
|
// Let's find out wtf they even sent
|
||||||
handleMessage(ws.data.socket, msg);
|
handleMessage(ws.data.socket, msg);
|
||||||
},
|
},
|
||||||
|
|
||||||
close: (ws: ServerWebSocketMPP, code, message) => {
|
close: (ws: ServerWebSocketMPP, code, message) => {
|
||||||
// This usually gets called when someone leaves,
|
// This usually gets called when someone leaves,
|
||||||
// but it's also used internally just in case
|
// but it's also used internally just in case
|
||||||
// some dickhead can't close their tab like a
|
// some dickhead can't close their tab like a
|
||||||
// normal person.
|
// normal person.
|
||||||
|
|
||||||
const socket = ws.data.socket as Socket;
|
const socket = ws.data.socket as Socket;
|
||||||
if (socket) {
|
if (socket) {
|
||||||
socket.destroy();
|
socket.destroy();
|
||||||
|
|
||||||
for (const sockID of socketsByUUID.keys()) {
|
for (const sockID of socketsByUUID.keys()) {
|
||||||
const sock = socketsByUUID.get(sockID);
|
const sock = socketsByUUID.get(sockID);
|
||||||
|
|
||||||
if (sock === socket) {
|
if (sock === socket) {
|
||||||
socketsByUUID.delete(sockID);
|
socketsByUUID.delete(sockID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
logger.info("Listening on port", env.PORT);
|
logger.info("Listening on port", env.PORT);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue