diff --git a/src/channel/Channel.ts b/src/channel/Channel.ts index d9d075c..c113f8e 100644 --- a/src/channel/Channel.ts +++ b/src/channel/Channel.ts @@ -130,8 +130,6 @@ export class Channel extends EventEmitter { const userFlags = socket.getUserFlags(); - this.logger.debug(userFlags); - if (userFlags) { if (userFlags.cant_chat) return; } @@ -157,7 +155,7 @@ export class Channel extends EventEmitter { this.emit("command", msg, socket); } } catch (err) { - this.logger.debug(err); + this.logger.error(err); } }); } @@ -233,17 +231,15 @@ export class Channel extends EventEmitter { * @returns undefined */ public join(socket: Socket) { + //! /!\ Players are forced to join the same channel on two different tabs! + //? TODO Should this be a bug or a feature? + if (this.isDestroyed()) return; const part = socket.getParticipant() as Participant; - // Unknown side-effects, but for type safety... - // if (!part) return; - let hasChangedChannel = false; let oldChannelID = socket.currentChannelID; - // this.logger.debug("Has user?", this.hasUser(part._id)); - // Is user in this channel? if (this.hasUser(part._id)) { // Alreay in channel, don't add to list, but tell them they're here @@ -256,25 +252,29 @@ export class Channel extends EventEmitter { hasChangedChannel = true; this.ppl.push(part); } else { - // Put us in full channel + // Put them in full channel return socket.setChannel(config.fullChannel); } } + // Was the move complete? if (hasChangedChannel) { + // Were they in a channel before? if (socket.currentChannelID) { + // Find the channel they were in const ch = ChannelList.getList().find( ch => ch._id == socket.currentChannelID ); - if (ch) { - ch?.leave(socket); - } + + // Tell the channel they left + if (ch) ch.leave(socket); } + // Change the thing we checked to point to us now socket.currentChannelID = this.getID(); } - // Send our data back + // Send our state data back socket.sendArray([ { m: "ch", @@ -288,12 +288,13 @@ export class Channel extends EventEmitter { } ]); + // Get our friend's cursor position const cursorPos: { x: string | number | undefined; y: string | number | undefined; } = socket.getCursorPos(); - // Broadcast participant update + // Broadcast a participant update for them this.sendArray([ { m: "p", @@ -305,6 +306,9 @@ export class Channel extends EventEmitter { y: cursorPos.y } ]); + + // Broadcast a channel update so everyone subscribed to the channel list can see us + this.emit("update", this); } /** @@ -342,7 +346,7 @@ export class Channel extends EventEmitter { } ]); - this.emit("update"); + this.emit("update", this); } /** @@ -514,7 +518,7 @@ export class Channel extends EventEmitter { this.crown.userId = part._id; this.crown.participantId = part.id; this.crown.time = Date.now(); - this.emit("update"); + this.emit("update", this); } } @@ -551,7 +555,7 @@ export class Channel extends EventEmitter { delete this.crown.participantId; - this.emit("update"); + this.emit("update", this); } } } diff --git a/src/channel/ChannelList.ts b/src/channel/ChannelList.ts index f7df01e..c96b950 100644 --- a/src/channel/ChannelList.ts +++ b/src/channel/ChannelList.ts @@ -1,9 +1,10 @@ -import { findSocketByPartID } from "../ws/Socket"; +import { type Socket, findSocketByPartID } from "../ws/Socket"; import type Channel from "./Channel"; const onChannelUpdate = (channel: Channel) => { const info = channel.getInfo(); - const ppl = channel.getParticipantList(); + // const ppl = channel.getParticipantList(); + if (info.settings.visible !== true) return; for (const partId of ChannelList.subscribers) { const socket = findSocketByPartID(partId); @@ -16,7 +17,7 @@ const onChannelUpdate = (channel: Channel) => { return; } - socket.sendChannelUpdate(info, ppl); + socket.sendChannelList([info], false); } }; @@ -26,16 +27,27 @@ export class ChannelList { public static add(channel: Channel) { this.list.push(channel); - channel.on("update", () => { - onChannelUpdate(channel); - }); + channel.on("update", onChannelUpdate); } public static remove(channel: Channel) { this.list.splice(this.list.indexOf(channel), 1); + channel.off("update", onChannelUpdate); } public static getList() { return this.list; } + + public static getPublicList() { + return this.list.filter(ch => ch.getSetting("visible") == true); + } + + public static subscribe(partId: Socket["id"]) { + this.subscribers.push(partId); + } + + public static unsubscribe(partId: Socket["id"]) { + this.subscribers.splice(this.subscribers.indexOf(partId), 1); + } } diff --git a/src/ws/Socket.ts b/src/ws/Socket.ts index ca6d373..5aa2c99 100644 --- a/src/ws/Socket.ts +++ b/src/ws/Socket.ts @@ -115,7 +115,7 @@ export class Socket extends EventEmitter { this.desiredChannel.set = set; let channel; - for (const ch of ChannelList.getList()) { + for (const ch of ChannelList.getPublicList()) { if (ch.getID() == _id) { channel = ch; } @@ -396,11 +396,30 @@ export class Socket extends EventEmitter { } public subscribeToChannelList() { - // TODO Channel list subbing + ChannelList.subscribe(this.id); + + const firstList = ChannelList.getPublicList().map(v => v.getInfo()); + this.sendChannelList(firstList); } public unsubscribeFromChannelList() { - // TODO Channel list unsubbing + ChannelList.unsubscribe(this.id); + } + + public sendChannelList(list: IChannelInfo[], complete: boolean = true) { + // logger.debug( + // "Sending channel list:", + // list, + // complete ? "(complete)" : "(incomplete)" + // ); + + this.sendArray([ + { + m: "ls", + c: complete, + u: list + } + ]); } } diff --git a/src/ws/events/admin/handlers/user_flag.ts b/src/ws/events/admin/handlers/user_flag.ts index d605128..af30a28 100644 --- a/src/ws/events/admin/handlers/user_flag.ts +++ b/src/ws/events/admin/handlers/user_flag.ts @@ -9,7 +9,7 @@ export const user_flag: ServerEventListener<"user_flag"> = { if (typeof msg.key !== "string") return; if (typeof msg.value == "undefined") return; - socket.getCurrentChannel()?.logger.debug(msg); + // socket.getCurrentChannel()?.logger.debug(msg); // Find the user data we're modifying const user = await readUser(msg._id); @@ -29,6 +29,6 @@ export const user_flag: ServerEventListener<"user_flag"> = { sock.setUserFlag(msg.key, msg.value); }); - socket.getCurrentChannel()?.logger.debug("socks:", socks); + // socket.getCurrentChannel()?.logger.debug("socks:", socks); } }; diff --git a/src/ws/events/user/handlers/admin_message.ts b/src/ws/events/user/handlers/admin_message.ts index d00a654..654ecbe 100644 --- a/src/ws/events/user/handlers/admin_message.ts +++ b/src/ws/events/user/handlers/admin_message.ts @@ -1,12 +1,16 @@ +import { Logger } from "../../../../util/Logger"; import env from "../../../../util/env"; import { ServerEventListener } from "../../../../util/types"; import { config } from "../../../usersConfig"; +const logger = new Logger("Admin Message Handler"); + export const admin_message: ServerEventListener<"admin message"> = { id: "admin message", callback: (msg, socket) => { if (typeof msg.password !== "string") return; if (msg.password !== env.ADMIN_PASS) return; + socket.admin.emit(msg.msg.m, msg.msg, socket, true); } }; diff --git a/src/ws/events/user/index.ts b/src/ws/events/user/index.ts index 8536653..38fb80f 100644 --- a/src/ws/events/user/index.ts +++ b/src/ws/events/user/index.ts @@ -9,6 +9,9 @@ import { m } from "./handlers/m"; import { a } from "./handlers/a"; import { userset } from "./handlers/userset"; import { n } from "./handlers/n"; +import { plus_ls } from "./handlers/+ls"; +import { minus_ls } from "./handlers/-ls"; +import { admin_message } from "./handlers/admin_message"; EVENTGROUP_USER.add(hi); EVENTGROUP_USER.add(devices); @@ -17,5 +20,8 @@ EVENTGROUP_USER.add(m); EVENTGROUP_USER.add(a); EVENTGROUP_USER.add(userset); EVENTGROUP_USER.add(n); +EVENTGROUP_USER.add(plus_ls); +EVENTGROUP_USER.add(minus_ls); +EVENTGROUP_USER.add(admin_message); eventGroups.push(EVENTGROUP_USER);