You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

106 lines
2.5 KiB

import { serve } from "https://deno.land/std@0.162.0/http/server.ts";
import config from "./config.ts";
interface SockClient {
ws: WebSocket;
pinger: number;
}
// TODO: Read this from config
const debugMode = config.websocket.debug;
export const connected: Record<string, SockClient> = {};
function debug(msg: string) {
if (debugMode) console.log(`debug: ${msg}`);
}
function handleConnected(_event: Event, ws: WebSocket) {
debug("Client connected!");
const pinger = setInterval(() => {
// i'm not sorry for this
debug(`Pinging client ${Object.keys(connected).length - 1}...`);
ws.send("__PING__");
}, 10000);
connected[Object.keys(connected).length] = {
ws: ws,
pinger: pinger,
};
}
function handleDisconnected(_event: CloseEvent, ws: WebSocket) {
Object.keys(connected).forEach((val) => {
if (connected[val].ws == ws) {
debug(`Client ${val} disconnected!`);
clearInterval(connected[val].pinger);
delete connected[val];
}
});
}
function handleMessage(event: MessageEvent) {
if (event.data == "__PONG__") {
debug("Recieved pong!");
}
}
function reqHandler(req: Request) {
if (req.headers.get("upgrade") != "websocket") {
return new Response(null, { status: 501 });
}
const { socket: ws, response } = Deno.upgradeWebSocket(req);
ws.onopen = (event) => handleConnected(event, ws);
ws.onclose = (event) => handleDisconnected(event, ws);
ws.onmessage = (event) => handleMessage(event);
return response;
}
export default function initialize(hostname: string, port: number) {
serve(reqHandler, { hostname, port });
}
function sendLog(type: string, data: Record<string, unknown>) {
Object.keys(connected).forEach((val) => {
if (connected[val]) {
connected[val].ws.send(
JSON.stringify({
type,
...data,
}),
);
}
});
}
export function sendMessageLog(
name: string,
message: string,
channel: string,
description = "",
) {
sendLog("MessageLog", {
name,
description,
message,
channel,
});
}
export function sendInteractionLog(
name: string,
command: string,
args: string, // funny javascript moment
channel: string,
) {
sendLog("InteractionLog", {
name,
command,
arguments: args,
channel,
});
}