diff options
Diffstat (limited to 'server-legacy/server')
| -rw-r--r-- | server-legacy/server/index.ts | 77 | ||||
| -rw-r--r-- | server-legacy/server/room.ts | 58 | 
2 files changed, 135 insertions, 0 deletions
| diff --git a/server-legacy/server/index.ts b/server-legacy/server/index.ts new file mode 100644 index 0000000..de2ba4e --- /dev/null +++ b/server-legacy/server/index.ts @@ -0,0 +1,77 @@ +import { Application, Router, RouterContext, send } from "https://deno.land/x/oak@v10.4.0/mod.ts"; +import { api } from "./room.ts"; +import { bundle } from "https://deno.land/x/emit@0.1.1/mod.ts"; + +const app = new Application() +const root = new Router() + + +root.get("/", async c => { await c.send({ path: "index.html", root: `${Deno.cwd()}/public` }) }) +root.get("/room/:id", async c => { await c.send({ path: "index.html", root: `${Deno.cwd()}/public` }) }) + +root.get("/licen(c|s)e", async c => { +    c.response.body = await Deno.readTextFile("LICENCE") +    c.response.headers.set("Content-Type", "text/plain") +}) + +root.get("/favicon.ico", c => { c.response.status = 204 }) + +// deno-lint-ignore no-explicit-any +function respondWithType(mimeType: string, f: () => string): (c: RouterContext<any, any, any>) => void { +    return c => { +        c.response.headers.set("Content-Type", mimeType) +        c.response.body = f() +    } +} + +let bundle_code = "" +root.get("/bundle.js", respondWithType("application/javascript", () => bundle_code)) + +root.use(api.routes()) + +function mountFilesystem(r: Router, route: string, path: string) { +    r.get(route + "/(.*)", async (context) => { +        console.log(context.request.url.pathname.substring(route.length)); +        await send(context, context.request.url.pathname.substring(route.length), { root: Deno.cwd() + path }); +    }) +} + +mountFilesystem(root, "/_style", "/public/style") +mountFilesystem(root, "/_rnnoise", "/public/rnnoise") + +app.use(root.routes()) +app.use(root.allowedMethods()) + +app.addEventListener("listen", ({ hostname, port, secure }) => { +    console.log(`listening on: ${secure ? "https://" : "http://"}${hostname}:${port}`); +}); + +app.listen({ +    hostname: Deno.env.get("HOSTNAME") ?? "127.0.0.1", +    port: parseInt(Deno.env.get("PORT") ?? "8080") +}); + + +let refresh_needed = false +let refresh_pending = false +async function refresh() { +    refresh_needed = true +    if (refresh_pending) return +    refresh_needed = false +    refresh_pending = true + +    try { +        const { code } = await bundle("source/client/index.ts", { compilerOptions: { checkJs: false } }) +        bundle_code = code +    } catch (e) { console.error(e) } + +    refresh_pending = false +    if (refresh_needed) refresh() +} + +refresh() +for await (const event of Deno.watchFs("source/client")) { +    if (event.kind == "modify" || event.kind == "create") { +        refresh() +    } +} diff --git a/server-legacy/server/room.ts b/server-legacy/server/room.ts new file mode 100644 index 0000000..d9c1a25 --- /dev/null +++ b/server-legacy/server/room.ts @@ -0,0 +1,58 @@ +import { Router } from "https://deno.land/x/oak@v10.4.0/router.ts"; +import { PacketC, PacketS } from "../packets.ts"; + +export const api = new Router() + +type Room = Map<string, WebSocket> +const rooms: Map<string, Room> = new Map() + +function send_packet(ws: WebSocket, packet: PacketC) { +    ws.send(JSON.stringify(packet)) +} + +api.get("/signaling/:id", c => { +    const ws = c.upgrade() + +    const room_name = c.params.id +    const room: Room = rooms.get(c.params.id) ?? new Map() +    let initialized = false +    let user_name = "" + +    const init = (n: string) => { +        if (room.get(n)) return ws.close() +        initialized = true +        user_name = n +        rooms.set(c.params.id, room) +        room.forEach(uws => send_packet(uws, { sender: user_name, join: true })) +        room.forEach((_, uname) => send_packet(ws, { sender: uname, join: true, stable: true })) +        room.set(user_name, ws) +        console.log(`[${room_name}] ${user_name} joined`) +    } +    ws.onclose = () => { +        room.delete(user_name) +        room.forEach(uws => send_packet(uws, { sender: user_name, leave: true })) +        if (room.size == 0) rooms.delete(room_name) +        console.log(`[${room_name}] ${user_name} left`) +    } +    ws.onmessage = ev => { +        const message = ev.data.toString() +        if (!initialized) return init(message) +        let in_packet: PacketS; +        try { in_packet = JSON.parse(message) } +        catch (_e) { return } + +        if (JSON.stringify(in_packet) == "{}") return // drop ping + +        console.log(`[${room_name}] ${user_name} -> ${in_packet.receiver ?? "*"}: ${message.substr(0, 100)}`) +        const out_packet: PacketC = { sender: user_name, data: in_packet } + +        if (in_packet.receiver) { +            const rws = room.get(in_packet.receiver) +            if (rws) send_packet(rws, out_packet) +        } else { +            room.forEach((uws, uname) => { +                if (uname != user_name) send_packet(uws, out_packet) +            }) +        } +    } +}) | 
