From 9969a175904e072a9e27805956603982c211bce6 Mon Sep 17 00:00:00 2001 From: sophie Date: Fri, 19 Jul 2024 20:03:15 +0300 Subject: [PATCH] save room ownership and chats --- .gitignore | 1 + src/Room.ts | 79 +++++++++++++++++++++++++++++++++------------------ src/Server.ts | 20 ++++++++++++- 3 files changed, 72 insertions(+), 28 deletions(-) diff --git a/.gitignore b/.gitignore index 94ea1f4..e9752ba 100644 --- a/.gitignore +++ b/.gitignore @@ -174,3 +174,4 @@ dist # Finder (MacOS) folder config .DS_Store DATABASE.db +chats \ No newline at end of file diff --git a/src/Room.ts b/src/Room.ts index 4c783ea..57ffb50 100644 --- a/src/Room.ts +++ b/src/Room.ts @@ -4,7 +4,8 @@ import { Client } from "./Client"; import { proto } from "pianoverse"; import { addRoomBan, getRoomBans } from "./Database"; import { Server } from "./Server"; - +import { writeFileSync, existsSync, readFileSync } from "fs"; +import { join } from "path"; interface Ban { banTime: number; minutes: number; @@ -19,32 +20,54 @@ export class Room { constructor(name: string, owner: string) { this.name = name; - if(this.name == "Lobby" || this.name == "Backrooms") { + if (Server.specialRooms.includes(this.name)) { this.owner = ""; } else { this.owner = owner; } - this.systemMessage("This is a development server. Instability may occur. Written by @fucksophie") + if (existsSync("chats/" + this.name)) { + const welcome = proto.ServerMessage.fromBinary( + readFileSync("chats/" + this.name) + ).welcome; + if (!welcome) return; + + this.chats = welcome.chat; + this.owner = welcome.owner; + } else { + this.systemMessage( + "This is a development server. Instability may occur. Written by @fucksophie" + ); + } } - + private addToChatArray(chat: proto.ServerMessage_Chat) { this.chats.push(chat); if (this.chats.length > 150) this.chats.shift(); + writeFileSync( + join("chats", this.name), + new proto.ServerMessage({ + event: proto.ServerMessage_EventType.WELCOME, + welcome: { + chat: this!.chats, + owner: this.owner, + }, + }).toBinary() + ); } - + systemMessage(message: string) { const system = Server.systemMessage(message); this.addToChatArray(system.chat!); this.particpiants.forEach((z) => { - z.clients.forEach(g => { + z.clients.forEach((g) => { g.send(system); - }) + }); }); } chat(ws: ServerWebSocket, message: string) { const profile = Server.profiles.get(ws.data.id); - if(!profile) return; - + if (!profile) return; + const chatPacket = new proto.ServerMessage({ event: proto.ServerMessage_EventType.CHAT, chat: { @@ -63,17 +86,17 @@ export class Room { } ban(ws: ServerWebSocket, minutes: number) { - if(this.name == 'Backrooms') return; - addRoomBan(ws.data.id, this.name, minutes, Date.now()) + if (this.name == "Backrooms") return; + addRoomBan(ws.data.id, this.name, minutes, Date.now()); ws.data.backrooms(); } checkBan(ws: ServerWebSocket) { - const ban = getRoomBans(this.name)?.find(z=> z.id == ws.data.id); - if(!ban) return false; - const time = ban.banTime - (Date.now() - (ban.minutes * 60 * 1000)); + const ban = getRoomBans(this.name)?.find((z) => z.id == ws.data.id); + if (!ban) return false; + const time = ban.banTime - (Date.now() - ban.minutes * 60 * 1000); - if(time <= 0) { + if (time <= 0) { return false; // Database.ts automatically removes the ban } else { return time; @@ -91,18 +114,20 @@ export class Room { particpiant.addClient(ws.data); } - ws.data.send(new proto.ServerMessage({ - event: proto.ServerMessage_EventType.WELCOME, - welcome: { - id: ws.data.id, - name: particpiant.profile.name, - color: particpiant.profile.color, - room: ws.data.room!.name, - owner: ws.data.room!.owner, - chat: ws.data.room!.chats, - role: particpiant.profile.role, - }, - })); + ws.data.send( + new proto.ServerMessage({ + event: proto.ServerMessage_EventType.WELCOME, + welcome: { + id: ws.data.id, + name: particpiant.profile.name, + color: particpiant.profile.color, + room: ws.data.room!.name, + owner: ws.data.room!.owner, + chat: ws.data.room!.chats, + role: particpiant.profile.role, + }, + }) + ); if (particpiant.clients.length <= 1) { //#region Annouce to everyone that the user has joined const joinMessage = new proto.ServerMessage({ diff --git a/src/Server.ts b/src/Server.ts index 1ccaca0..63ce17a 100644 --- a/src/Server.ts +++ b/src/Server.ts @@ -4,6 +4,7 @@ import type { ServerWebSocket } from "bun"; import { Room } from "./Room"; import { Profile } from "./Profile"; import { addSiteBan, getSiteBan, removeSiteBan } from "./Database"; +import * as fs from "fs"; const CEventType = proto.ClientMessage_EventType; const SEventType = proto.ServerMessage_EventType; @@ -13,6 +14,7 @@ export class Server { static rooms = new Map(); static profiles = new Map(); + static specialRooms = ["Lobby", "Backrooms"]; static systemMessage(message: string): proto.ServerMessage { return new proto.ServerMessage({ event: proto.ServerMessage_EventType.CHAT, @@ -38,6 +40,22 @@ export class Server { } constructor(port: number) { + try { + fs.mkdirSync("chats"); + } catch {} + setInterval(() => { + let allStats: { stat: fs.Stats; name: string }[] = []; + for (const name of fs.readdirSync("chats/")) { + if (Server.specialRooms.includes(name)) return; + + allStats.push({ stat: fs.statSync("chats/" + name), name }); + } + allStats = allStats.sort( + (a, b) => b.stat.mtime.getTime() - a.stat.mtime.getTime() + ); + const deleteThese = allStats.slice(5); + deleteThese.forEach((z) => fs.unlinkSync("chats/" + z.name)); + }, 5000); Bun.serve({ // #region WS upgrading fetch(req, server) { @@ -198,7 +216,7 @@ export class Server { if (!ws.data.room) return; const profile = Server.profiles.get(ws.data.id); if (!profile) return; - if(!ws.data.room.owner) return; + if (!ws.data.room.owner) return; if (profile.role !== proto.Role.DEVELOPER) { if (ws.data.room.owner != ws.data.id) return; }