From a82839085f3133076c8e19b376dc57c35e118cb8 Mon Sep 17 00:00:00 2001 From: Hri7566 Date: Fri, 20 Sep 2024 11:13:27 -0400 Subject: [PATCH] Change HTTP server to require a function call to initialize --- public | 2 +- src/index.ts | 5 +- src/ws/server.ts | 172 ++++++++++++++++++++++++----------------------- 3 files changed, 92 insertions(+), 87 deletions(-) diff --git a/public b/public index a8a0182..1dc00c7 160000 --- a/public +++ b/public @@ -1 +1 @@ -Subproject commit a8a0182686cec166c3042697c639c5ca8b6acf6b +Subproject commit 1dc00c7f885ac919a1bda7d4c749d33bd594c42f diff --git a/src/index.ts b/src/index.ts index d2e6327..963bcf2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,14 +13,13 @@ // There are a lot of unhinged bs comments in this repo // 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 { Logger } from "./util/Logger"; // docker hates this next one import { startReadline } from "./util/readline"; import { loadDefaultPermissions } from "./data/permissions"; import { loadBehaviors } from "./event/behaviors"; +import { startHTTPServer } from "./ws/server"; // wrapper for some reason export function startServer() { @@ -38,6 +37,8 @@ export function startServer() { // Break the console logger.info("Starting REPL"); startReadline(); + + startHTTPServer(); logger.info("Ready"); } diff --git a/src/ws/server.ts b/src/ws/server.ts index abdba40..afb267a 100644 --- a/src/ws/server.ts +++ b/src/ws/server.ts @@ -7,7 +7,7 @@ import { Socket, socketsByUUID } from "./Socket"; import env from "../util/env"; import { getMOTD } from "../util/motd"; import nunjucks from "nunjucks"; -import type { ServerWebSocket } from "bun"; +import type { Server, ServerWebSocket } from "bun"; import { ConfigManager } from "~/util/config"; import { config as usersConfig } from "./usersConfig"; @@ -59,117 +59,121 @@ async function getIndex() { type ServerWebSocketMPP = ServerWebSocket<{ ip: string; socket: Socket }>; -export const app = Bun.serve<{ ip: string }>({ - port: env.PORT, - hostname: "0.0.0.0", - fetch: (req, server) => { - const reqip = server.requestIP(req); - if (!reqip) return; +export let app: Server; - 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 - if (server.upgrade(req, { data: { ip } })) { - return; - } + const ip = req.headers.get("x-forwarded-for") || reqip.address; - httpIpCache.set(ip, Date.now()); - const url = new URL(req.url).pathname; + // Upgrade websocket connections + if (server.upgrade(req, { data: { ip } })) { + return; + } - // lol - // const ip = decoder.decode(res.getRemoteAddressAsText()); - // logger.debug(`${req.getMethod()} ${url} ${ip}`); - // res.writeStatus(`200 OK`).end("HI!"); + httpIpCache.set(ip, Date.now()); + const url = new URL(req.url).pathname; - // 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 + // lol + // const ip = decoder.decode(res.getRemoteAddressAsText()); + // logger.debug(`${req.getMethod()} ${url} ${ip}`); + // res.writeStatus(`200 OK`).end("HI!"); - 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 - try { - // Is it a file? - if (fs.lstatSync(file).isFile()) { - // Read the file - const data = Bun.file(file); + const file = path.join("./public/", url); - // Return the file - if (data) { - return new Response(data); + // Time for unreadable blocks of confusion + try { + // 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(); } + }, + 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 - return getIndex(); - } 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; + // logger.debug("Connection at " + socket.getIP()); - ws.data.socket = socket; - // logger.debug("Connection at " + socket.getIP()); + if (socket.socketID === undefined) { + socket.socketID = createSocketID(); + } - if (socket.socketID === undefined) { - socket.socketID = createSocketID(); - } + socketsByUUID.set(socket.getUUID(), socket); - 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)) { - const date = httpIpCache.get(ip); - - if (date) { - if (Date.now() - date < 1000 * 60) { - // They got the page and we were connected in under a minute - socket.gateway.hasConnectedToHTTPServer = true; - } else { - // They got the page and a long time has passed - httpIpCache.delete(ip); + if (date) { + if (Date.now() - date < 1000 * 60) { + // They got the page and we were connected in under a minute + socket.gateway.hasConnectedToHTTPServer = true; + } else { + // They got the page and a long time has passed + httpIpCache.delete(ip); + } } } - } - }, + }, - message: (ws: ServerWebSocketMPP, message: string) => { - // Fucking string - const msg = message.toString(); + message: (ws: ServerWebSocketMPP, message: string) => { + // Fucking string + const msg = message.toString(); - // Let's find out wtf they even sent - handleMessage(ws.data.socket, msg); - }, + // Let's find out wtf they even sent + handleMessage(ws.data.socket, msg); + }, - close: (ws: ServerWebSocketMPP, code, message) => { - // This usually gets called when someone leaves, - // but it's also used internally just in case - // some dickhead can't close their tab like a - // normal person. + close: (ws: ServerWebSocketMPP, code, message) => { + // This usually gets called when someone leaves, + // but it's also used internally just in case + // some dickhead can't close their tab like a + // normal person. - const socket = ws.data.socket as Socket; - if (socket) { - socket.destroy(); + const socket = ws.data.socket as Socket; + if (socket) { + socket.destroy(); - for (const sockID of socketsByUUID.keys()) { - const sock = socketsByUUID.get(sockID); + for (const sockID of socketsByUUID.keys()) { + const sock = socketsByUUID.get(sockID); - if (sock === socket) { - socketsByUUID.delete(sockID); + if (sock === socket) { + socketsByUUID.delete(sockID); + } } } } } - } -}); + }); -logger.info("Listening on port", env.PORT); + logger.info("Listening on port", env.PORT); +}