Fix session problem

This commit is contained in:
Hri7566 2023-09-10 00:15:34 -04:00
parent 797a2885b5
commit d3822fe933
4 changed files with 72 additions and 118 deletions

View File

@ -111,21 +111,12 @@ export class Channel {
let hasChangedChannel = false; let hasChangedChannel = false;
this.logger.debug("Has user?", this.hasUser(part)); this.logger.debug("Has user?", this.hasUser(part._id));
// Is user in this channel? // Is user in this channel?
if (this.hasUser(part)) { if (this.hasUser(part._id)) {
// Alreay in channel, disconnect old // Alreay in channel, add this part ID to IDs list
// TODO
const oldSocket = findSocketByPartID(part.id);
if (oldSocket) {
oldSocket.destroy();
}
// Add to channel
this.ppl.push(part);
hasChangedChannel = true;
} else { } else {
// Are we full? // Are we full?
if (!this.isFull()) { if (!this.isFull()) {
@ -142,10 +133,12 @@ export class Channel {
// Is user in any channel that isn't this one? // Is user in any channel that isn't this one?
for (const ch of channelList) { for (const ch of channelList) {
if (ch == this) continue; if (ch == this) continue;
if (ch.hasUser(part)) { if (ch.hasUser(part._id)) {
ch.leave(socket); ch.leave(socket);
} }
} }
socket.currentChannelID = this.getID();
} }
this.logger.debug("Participant list:", this.ppl); this.logger.debug("Participant list:", this.ppl);
@ -167,10 +160,10 @@ export class Channel {
this.logger.debug("Leave called"); this.logger.debug("Leave called");
const part = socket.getParticipant(); const part = socket.getParticipant();
// Same as above... // Unknown side-effects, but for type safety...
if (!part) return; if (!part) return;
if (this.hasUser(part)) { if (this.hasUser(part._id)) {
this.ppl.splice(this.ppl.indexOf(part), 1); this.ppl.splice(this.ppl.indexOf(part), 1);
} }
// TODO Broadcast channel update // TODO Broadcast channel update
@ -199,8 +192,13 @@ export class Channel {
return this.ppl; return this.ppl;
} }
public hasUser(part: Participant) { public hasUser(_id: string) {
const foundPart = this.ppl.find(p => p._id == part._id); const foundPart = this.ppl.find(p => p._id == _id);
return !!foundPart;
}
public hasParticipant(id: string) {
const foundPart = this.ppl.find(p => p.id == id);
return !!foundPart; return !!foundPart;
} }
} }

View File

@ -13,6 +13,10 @@ export function createUserID(ip: string) {
.substring(0, 24); .substring(0, 24);
} }
export function createSocketID() {
return crypto.randomUUID();
}
export function createColor(ip: string) { export function createColor(ip: string) {
return ( return (
"#" + "#" +

View File

@ -9,6 +9,8 @@ import { loadConfig } from "../util/config";
import { Gateway } from "./Gateway"; import { Gateway } from "./Gateway";
import { Channel, channelList } from "../channel/Channel"; import { Channel, channelList } from "../channel/Channel";
import { ServerWebSocket } from "bun"; import { ServerWebSocket } from "bun";
import { findSocketByUserID, socketsBySocketID } from "./server";
import { Logger } from "../util/Logger";
interface UsersConfig { interface UsersConfig {
defaultName: string; defaultName: string;
@ -22,6 +24,8 @@ const usersConfig = loadConfig<UsersConfig>("config/users.yml", {
} }
}); });
const logger = new Logger("Sockets");
export class Socket extends EventEmitter { export class Socket extends EventEmitter {
private id: string; private id: string;
private _id: string; private _id: string;
@ -43,11 +47,29 @@ export class Socket extends EventEmitter {
constructor(private ws: ServerWebSocket<unknown>) { constructor(private ws: ServerWebSocket<unknown>) {
super(); super();
this.ip = ws.remoteAddress; // Participant ID this.ip = ws.remoteAddress; // Participant ID
this.id = createID();
// User ID // User ID
this._id = createUserID(this.getIP()); this._id = createUserID(this.getIP());
// *cough* lapis
// Check if we're already connected
// We need to skip ourselves, so we loop here instead of using a helper
let foundSocket;
for (const socket of socketsBySocketID.values()) {
if (socket == this) continue;
if (socket.getUserID() == this.getUserID()) {
foundSocket = socket;
}
}
if (!foundSocket) {
// Use new session ID
this.id = createID();
} else {
// Use original session ID
this.id = foundSocket.id;
}
this.loadUser(); this.loadUser();
@ -94,6 +116,7 @@ export class Socket extends EventEmitter {
); );
channel.join(this); channel.join(this);
// TODO Give the crown upon joining // TODO Give the crown upon joining
} }
} }
@ -189,6 +212,7 @@ export class Socket extends EventEmitter {
const foundCh = channelList.find( const foundCh = channelList.find(
ch => ch.getID() == this.currentChannelID ch => ch.getID() == this.currentChannelID
); );
if (foundCh) foundCh.leave(this); if (foundCh) foundCh.leave(this);
} }

View File

@ -1,14 +1,6 @@
// import {
// App,
// DEDICATED_COMPRESSOR_8KB,
// HttpRequest,
// HttpResponse,
// WebSocket
// } from "uWebSockets.js";
import { Logger } from "../util/Logger"; import { Logger } from "../util/Logger";
import { createUserID } from "../util/id"; import { createSocketID, createUserID } from "../util/id";
import fs from "fs"; import fs from "fs";
// import { join } from "path";
import path from "path"; import path from "path";
import { handleMessage } from "./message"; import { handleMessage } from "./message";
import { decoder } from "../util/helpers"; import { decoder } from "../util/helpers";
@ -18,99 +10,28 @@ import env from "../util/env";
const logger = new Logger("WebSocket Server"); const logger = new Logger("WebSocket Server");
const usersByPartID = new Map<string, Socket>(); export const socketsBySocketID = new Map<string, Socket>();
export function findSocketByPartID(id: string) { export function findSocketByPartID(id: string) {
for (const key of usersByPartID.keys()) { for (const socket of socketsBySocketID.values()) {
if (key == id) return usersByPartID.get(key); if (socket.getParticipantID() == id) return socket;
} }
} }
// Original uWebSockets code export function findSocketByUserID(_id: string) {
// export const app = App() for (const socket of socketsBySocketID.values()) {
// .get("/*", async (res, req) => { logger.debug("User ID:", socket.getUserID());
// const url = req.getUrl(); if (socket.getUserID() == _id) return socket;
// const ip = decoder.decode(res.getRemoteAddressAsText()); }
// // logger.debug(`${req.getMethod()} ${url} ${ip}`); }
// // res.writeStatus(`200 OK`).end("HI!");
// const file = join("./public/", url);
// // TODO Cleaner file serving export function findSocketByIP(ip: string) {
// try { for (const socket of socketsBySocketID.values()) {
// const stats = lstatSync(file); if (socket.getIP() == ip) {
return socket;
// let data; }
// if (!stats.isDirectory()) { }
// data = readFileSync(file); }
// }
// // logger.debug(filename);
// if (!data) {
// const index = readFileSync("./public/index.html");
// if (!index) {
// return void res
// .writeStatus(`404 Not Found`)
// .end("uh oh :(");
// } else {
// return void res.writeStatus(`200 OK`).end(index);
// }
// }
// res.writeStatus(`200 OK`).end(data);
// } catch (err) {
// logger.warn("Unable to serve file at", file);
// logger.error(err);
// const index = readFileSync("./public/index.html");
// if (!index) {
// return void res.writeStatus(`404 Not Found`).end("uh oh :(");
// } else {
// return void res.writeStatus(`200 OK`).end(index);
// }
// }
// })
// .ws("/*", {
// idleTimeout: 25,
// maxBackpressure: 1024,
// maxPayloadLength: 8192,
// compression: DEDICATED_COMPRESSOR_8KB,
// open: ((ws: WebSocket<unknown> & { socket: Socket }) => {
// ws.socket = new Socket(ws);
// // logger.debug("Connection at " + ws.socket.getIP());
// usersByPartID.set(ws.socket.getParticipantID(), ws.socket);
// }) as (ws: WebSocket<unknown>) => void,
// message: ((
// ws: WebSocket<unknown> & { socket: Socket },
// message,
// isBinary
// ) => {
// const msg = decoder.decode(message);
// handleMessage(ws.socket, msg);
// }) as (
// ws: WebSocket<unknown>,
// message: ArrayBuffer,
// isBinary: boolean
// ) => void,
// close: ((
// ws: WebSocket<unknown> & { socket: Socket },
// code: number,
// message: ArrayBuffer
// ) => {
// logger.debug("Close called");
// ws.socket.destroy();
// usersByPartID.delete(ws.socket.getParticipantID());
// }) as (
// ws: WebSocket<unknown>,
// code: number,
// message: ArrayBuffer
// ) => void
// });
export const app = Bun.serve({ export const app = Bun.serve({
port: env.PORT, port: env.PORT,
@ -147,7 +68,7 @@ export const app = Bun.serve({
(ws as unknown as any).socket = socket; (ws as unknown as any).socket = socket;
logger.debug("Connection at " + socket.getIP()); logger.debug("Connection at " + socket.getIP());
usersByPartID.set(socket.getParticipantID(), socket); socketsBySocketID.set(createSocketID(), socket);
}, },
message: (ws, message) => { message: (ws, message) => {
@ -159,7 +80,14 @@ export const app = Bun.serve({
logger.debug("Close called"); logger.debug("Close called");
const socket = (ws as unknown as any).socket as Socket; const socket = (ws as unknown as any).socket as Socket;
socket.destroy(); socket.destroy();
usersByPartID.delete(socket.getParticipantID());
for (const sockID of socketsBySocketID.keys()) {
const sock = socketsBySocketID.get(sockID);
if (sock == socket) {
socketsBySocketID.delete(sockID);
}
}
} }
} }
}); });