/*Canopy - The next generation of stoner streaming software Copyright (C) 2024-2025 Rainbownapkin and the TTN Community This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see .*/ //local imports const connectedUser = require('./connectedUser'); const flairModel = require('../../schemas/flairSchema'); const permissionModel = require('../../schemas/permissionSchema'); module.exports = class{ constructor(server, chanDB){ this.server = server; this.name = chanDB.name; this.tokeCommands = chanDB.tokeCommands; //Keeping these in a map was originally a vestige but it's more preformant than an array or object so :P this.userList = new Map(); } async handleConnection(userDB, chanDB, socket){ //get current user object from the userlist var userObj = this.userList.get(userDB.user); //get channel rank for current user const chanRank = await chanDB.getChannelRankByUserDoc(userDB); //If user is already connected if(userObj){ //Add this socket on to the userobject userObj.sockets.push(socket.id); //If the user is joining the channel }else{ //Grab flair await userDB.populate('flair'); //Set user object userObj = new connectedUser(userDB, chanRank, this, socket); } //Set user entry in userlist this.userList.set(userDB.user, userObj); //if everything looks good, admit the connection to the channel socket.join(socket.chan); await userObj.handleConnection(userDB, chanDB, socket) //Send out the userlist this.broadcastUserList(socket.chan); } handleDisconnect(socket, reason){ //If we have more than one active connection if(this.userList.get(socket.user.user).sockets.length > 1){ //temporarily store userObj var userObj = this.userList.get(socket.user.user); //Filter out disconnecting socket from socket list, and set as current socket list for user userObj.sockets = userObj.sockets.filter((id) => { return id != socket.id; }); //Update the userlist this.userList.set(socket.user.user, userObj); }else{ //If this is the last connection for this user, remove them from the userlist this.userList.delete(socket.user.user); } //and send out the filtered list this.broadcastUserList(socket.chan); } broadcastUserList(){ //Create a userlist object with the tokebot user pre-loaded var userList = [{ user: "Tokebot", flair: "classic", highLevel: "∞", }]; this.userList.forEach((userObj, user) => { userList.push({ user: user, flair: userObj.flair, highLevel: userObj.highLevel }); }); this.server.io.in(this.name).emit("userList", userList); } async broadcastChanEmotes(chanDB){ //if we wherent handed a channel document if(chanDB == null){ //Pull it based on channel name chanDB = await channelModel.findOne({name: this.name}); } //Get emote list from channel document const emoteList = chanDB.getEmotes(); //Broadcast that sumbitch this.server.io.in(this.name).emit('chanEmotes', emoteList); } }