From a32f47f432fa02db13162a009fd7c51c87d5117e Mon Sep 17 00:00:00 2001 From: Hri7566 Date: Sat, 3 Aug 2024 20:00:19 -0400 Subject: [PATCH] Start implementation of channel save data --- config/users.yml | 4 +-- prisma/schema.prisma | 7 ++++ src/channel/Channel.ts | 72 ++++++++++++++++++++++++++++++++++++++++-- src/data/channel.ts | 54 +++++++++++++++++++++++++++++++ 4 files changed, 132 insertions(+), 5 deletions(-) create mode 100644 src/data/channel.ts diff --git a/config/users.yml b/config/users.yml index 54512d7..6e2012f 100644 --- a/config/users.yml +++ b/config/users.yml @@ -37,14 +37,14 @@ enableAdminEval: true # The token validation scheme. Valid values are "none", "jwt" and "uuid". # This server will still validate existing tokens generated with other schemes if not set to "none", mimicking MPP.net's server. # This is set to "none" by default because MPP.com does not have a token system. -tokenAuth: jwt +tokenAuth: none # The browser challenge scheme. Valid options are "none", "obf" and "basic". # This is to change what is sent in the "b" message. # "none" will disable the browser challenge, # "obf" will sent an obfuscated function to the client, # and "basic" will just send a simple function that expects a boolean. -browserChallenge: basic +browserChallenge: none # Scheme for generating user IDs. # Valid options are "random", "sha256", "mpp" and "uuid". diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 0ada6d6..77fc6be 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -25,3 +25,10 @@ model ChatHistory { id String @id @unique @map("_id") messages String @default("[]") // JSON messages } + +model Channel { + id String @id @unique @map("_id") + settings String @default("{}") // JSON channel settings + forceload Boolean @default(false) // Whether the channel is forceloaded + flags String @default("{}") // JSON flags object +} diff --git a/src/channel/Channel.ts b/src/channel/Channel.ts index 22d2e65..d1c5b34 100644 --- a/src/channel/Channel.ts +++ b/src/channel/Channel.ts @@ -22,6 +22,8 @@ import { saveChatHistory, getChatHistory, deleteChatHistory } from "../data/hist import { mixin, darken } from "../util/helpers"; import { User } from "@prisma/client"; import { heapStats } from "bun:jsc"; +import { deleteSavedChannel, getSavedChannel, saveChannel } from "../data/channel"; +import { forceloadChannel } from "./forceLoad"; interface CachedKickban { userId: string; @@ -59,6 +61,53 @@ export class Channel extends EventEmitter { } catch (err) { } } + private async deleteData() { + try { + await deleteSavedChannel(this.getID()); + } catch (err) { } + } + + private async save() { + this.logger.debug("Saving channel data"); + try { + const info = this.getInfo(); + + const data = { + id: info._id, + settings: JSON.stringify(info.settings), + flags: JSON.stringify(this.flags) + }; + + this.logger.debug("Channel data to save:", data); + + await saveChannel(this.getID(), data); + } catch (err) { + this.logger.debug("Error saving cannel:", err); + } + } + + private async load() { + this.logger.debug("Loading saved data"); + try { + const data = await getSavedChannel(this.getID()); + if (data) { + try { + this.changeSettings(JSON.parse(data.settings)); + this.setFlags(JSON.parse(data.flags)); + this.loadChatHistory(); + + if (data.forceload) { + forceloadChannel(this.getID()); + } + + this.logger.debug("Loaded channel data:", data); + } catch (err) { + this.logger.debug("Error loading channel data:", err); + } + } + } catch (err) { } + } + public logger: Logger; public bans = new Array(); public cursorCache = new Array<{ x: string | number; y: string | number; id: string }>(); @@ -121,8 +170,7 @@ export class Channel extends EventEmitter { this.bindEventListeners(); ChannelList.add(this); - // TODO implement owner_id - this.settings.owner_id = owner_id; + this.settings.owner_id = this.flags["owner_id"]; this.logger.info("Created"); @@ -138,7 +186,8 @@ export class Channel extends EventEmitter { private bindEventListeners() { if (this.alreadyBound) return; this.alreadyBound = true; - this.loadChatHistory(); + this.load(); + this.save(); this.logger.info("Loaded chat history"); this.on("update", (self, uuid) => { @@ -422,6 +471,9 @@ export class Channel extends EventEmitter { */ //this.logger.debug("Update from changeSettings"); + (async () => { + await this.save(); + })(); this.emit("update", this); } @@ -806,6 +858,7 @@ export class Channel extends EventEmitter { ChannelList.remove(this); this.deleteChatHistory(); + this.deleteData(); this.logger.info("Destroyed"); } @@ -1148,6 +1201,16 @@ export class Channel extends EventEmitter { return this.flags[key]; } + /** + * Set the flags on this channel + * @param flags Flags to set + **/ + public setFlags(flags: Record) { + this.flags = flags; + this.save(); + this.emit("update", this); + } + /** * Get the ID of the next lobby, useful if this channel is full and is also a lobby * @returns ID of the next lobby in numeric succession @@ -1176,6 +1239,9 @@ export class Channel extends EventEmitter { } } + /** + * Print the amount of memory the server is using in chat + **/ public printMemoryInChat() { const mem = heapStats(); this.sendChatAdmin(`Used: ${(mem.heapSize / 1000 / 1000).toFixed(2)}M / Allocated: ${(mem.heapCapacity / 1000 / 1000).toFixed(2)}M`); diff --git a/src/data/channel.ts b/src/data/channel.ts new file mode 100644 index 0000000..4c81d78 --- /dev/null +++ b/src/data/channel.ts @@ -0,0 +1,54 @@ +import { Prisma } from "@prisma/client"; +import { prisma } from "./prisma"; + +/** + * Get saved channel data from the database + * @param channelId ID of channel to get + * @returns Saved channel data + */ +export async function getSavedChannel(channelId: string) { + try { + return await prisma.channel.findUnique({ + where: { + id: channelId + } + }); + } catch (e) { + return null; + } +} + +/** + * Save channel data to the database (update if already exists) + * @param channelId ID of channel to save + * @param channel Channel data to save + */ +export async function saveChannel(channelId: string, channel: Prisma.ChannelUpdateInput & Prisma.ChannelCreateInput) { + try { + return await prisma.channel.upsert({ + where: { + id: channelId + }, + update: channel, + create: channel + }); + } catch (e) { + console.error(e); + } +} + +/** + * Delete channel data from the database + * @param channelId ID of channel to delete + */ +export async function deleteSavedChannel(channelId: string) { + try { + return await prisma.channel.delete({ + where: { + id: channelId + } + }); + } catch (e) { + console.error(e); + } +}