diff --git a/src/channel/Channel.ts b/src/channel/Channel.ts index e0d2584..f5ae753 100644 --- a/src/channel/Channel.ts +++ b/src/channel/Channel.ts @@ -6,7 +6,8 @@ import { ClientEvents, Participant, ServerEvents, - IChannelInfo + IChannelInfo, + Notification } from "../util/types"; import type { Socket } from "../ws/Socket"; import { validateChannelSettings } from "./settings"; @@ -473,6 +474,10 @@ export class Channel extends EventEmitter { })); } + public getParticipantListUnsanitized() { + return this.ppl; + } + /** * Determine whether a user is in this channel (by user ID) * @param _id User ID @@ -735,6 +740,23 @@ export class Channel extends EventEmitter { c: this.chatHistory }]); } + + /** + * Send a notification to this channel + * @param notif Notification to send + **/ + public sendNotification(notif: Notification) { + this.sendArray([{ + m: "notification", + id: notif.id, + target: notif.target, + duration: notif.duration, + class: notif.class, + title: notif.title, + text: notif.text, + html: notif.html + }]); + } } export default Channel; diff --git a/src/util/types.d.ts b/src/util/types.d.ts index fdf1eae..4f8811f 100644 --- a/src/util/types.d.ts +++ b/src/util/types.d.ts @@ -233,7 +233,13 @@ declare interface ServerEvents { clear_chat: { m: "clear_chat" - } + }; + + notification: { + m: "notification" + targetChannel?: string; + targetUser?: string; + } & Notification; } declare interface ClientEvents { diff --git a/src/ws/Socket.ts b/src/ws/Socket.ts index 9a752b2..ed5d849 100644 --- a/src/ws/Socket.ts +++ b/src/ws/Socket.ts @@ -13,7 +13,8 @@ import { Participant, ServerEvents, UserFlags, - Vector2 + Vector2, + Notification } from "../util/types"; import type { User } from "@prisma/client"; import { createUser, readUser, updateUser } from "../data/user"; @@ -477,6 +478,19 @@ export class Socket extends EventEmitter { public getUUID() { return this.uuid; } + + public sendNotification(notif: Notification) { + this.sendArray([{ + m: "notification", + id: notif.id, + target: notif.target, + duration: notif.duration, + class: notif.class, + title: notif.title, + text: notif.text, + html: notif.html + }]); + } } export const socketsBySocketID = new Map(); diff --git a/src/ws/events/admin/handlers/notification.ts b/src/ws/events/admin/handlers/notification.ts new file mode 100644 index 0000000..d91c636 --- /dev/null +++ b/src/ws/events/admin/handlers/notification.ts @@ -0,0 +1,27 @@ +import { ChannelList } from "../../../../channel/ChannelList"; +import { ServerEventListener } from "../../../../util/types"; +import { socketsBySocketID } from "../../../Socket"; + +export const notification: ServerEventListener<"notification"> = { + id: "notification", + callback: async (msg, socket) => { + // Send notification to user/channel + if (typeof msg.targetChannel == "undefined" && typeof msg.targetUser == "undefined") return; + + if (typeof msg.targetChannel !== "undefined") { + for (const ch of ChannelList.getList().values()) { + if (ch.getID() == msg.targetChannel) { + ch.sendNotification(msg); + } + } + } + + if (typeof msg.targetUser !== "undefined") { + for (const socket of socketsBySocketID.values()) { + if (socket.getUserID() == msg.targetUser) { + socket.sendNotification(msg); + } + } + } + } +}; diff --git a/src/ws/events/admin/handlers/reset.ts b/src/ws/events/admin/handlers/reset.ts new file mode 100644 index 0000000..cd11201 --- /dev/null +++ b/src/ws/events/admin/handlers/reset.ts @@ -0,0 +1,26 @@ +import { readUser, updateUser } from "../../../../data/user"; +import { ServerEventListener } from "../../../../util/types"; +import { findSocketsByUserID } from "../../../Socket"; + +export const name: ServerEventListener<"name"> = { + id: "name", + callback: async (msg, socket) => { + // Change someone else's name but it's an annoying admin feature + const id = msg._id; + const name = msg.name; + + if (typeof id !== "string") return; + if (typeof name !== "string") return; + + const user = await readUser(msg._id); + if (!user) return; + + user.name = name; + await updateUser(id, user); + + const toUpdate = findSocketsByUserID(id); + toUpdate.forEach(s => { + s.userset(msg.name, undefined, true); + }); + } +}; diff --git a/src/ws/events/admin/index.ts b/src/ws/events/admin/index.ts index e504770..d5f1f0a 100644 --- a/src/ws/events/admin/index.ts +++ b/src/ws/events/admin/index.ts @@ -5,12 +5,13 @@ export const EVENT_GROUP_ADMIN = new EventGroup("admin"); import { color } from "./handlers/color"; import { name } from "./handlers/name"; +import { notification } from "./handlers/notification"; import { user_flag } from "./handlers/user_flag"; // EVENT_GROUP_ADMIN.add(color); // EVENT_GROUP_ADMIN.add(name); // EVENT_GROUP_ADMIN.add(user_flag); -EVENT_GROUP_ADMIN.addMany(color, name, user_flag, clear_chat); +EVENT_GROUP_ADMIN.addMany(color, name, user_flag, clear_chat, notification); eventGroups.push(EVENT_GROUP_ADMIN);