Improved channelManager and chatHandler

This commit is contained in:
rainbownapkin 2024-11-20 05:27:05 -05:00
parent 4b4cb2ed3d
commit 985f8a250f
3 changed files with 154 additions and 117 deletions

View file

@ -21,10 +21,22 @@ const userModel = require('../../schemas/userSchema');
const activeChannel = require('./activeChannel'); const activeChannel = require('./activeChannel');
const chatHandler = require('./chatHandler'); const chatHandler = require('./chatHandler');
//local variables module.exports = class{
var activeChannels = new Map; constructor(io){
//Set the socket.io server
this.io = io;
module.exports.handleConnection = async function(io, socket){ //Load
this.activeChannels = new Map;
//Load server components
this.chatHandler = new chatHandler(this);
//Handle connections from socket.io
io.on("connection", this.handleConnection.bind(this) );
}
async handleConnection(socket){
//Prevent logged out connections and authenticate socket //Prevent logged out connections and authenticate socket
if(socket.request.session.user != null){ if(socket.request.session.user != null){
try{ try{
@ -35,8 +47,6 @@ module.exports.handleConnection = async function(io, socket){
socket.user = { socket.user = {
id: userDB.id, id: userDB.id,
user: userDB.user, user: userDB.user,
rank: userDB.rank,
flair: userDB.flair
}; };
socket.chanName = socket.handshake.headers.referer.split('/c/')[1]; socket.chanName = socket.handshake.headers.referer.split('/c/')[1];
@ -48,31 +58,38 @@ module.exports.handleConnection = async function(io, socket){
} }
//Check if current channel is active //Check if current channel is active
var activeChan = activeChannels.get(socket.chan); var activeChan = this.activeChannels.get(socket.chan);
if(!activeChan){ if(!activeChan){
//If not, make it so //If not, make it so
activeChan = new activeChannel(socket.chan); activeChan = new activeChannel(socket.chan);
activeChannels.set(socket.chan, activeChan); this.activeChannels.set(socket.chan, activeChan);
} }
//Check if this user is already connected //Check if this user is already connected
if(activeChan.userList.get(socket.user.user)){ if(activeChan.userList.get(socket.user.user)){
//get current list of socket connnections of selected user //get current list of socket connnections of selected user
var socketList = activeChan.userList.get(socket.user.user); var userObj = activeChan.userList.get(userDB.user);
//Add this one on //Add this one on
socketList.push(socket.id); userObj.sockets.push(socket.id);
//Set the user back socket list back //Set the user back socket list back
activeChan.userList.set(socket.user.user, socketList); activeChan.userList.set(userDB.user, userObj);
}else{ }else{
//if this is the first connection, initialize the socket array for this user //if this is the first connection, initialize the socket array for this user
activeChan.userList.set(socket.user.user, [socket.id]); var userObj = {
id: userDB.id,
rank: userDB.rank,
flair: userDB.flair,
sockets: [socket.id]
}
activeChan.userList.set(userDB.user, userObj);
} }
//if everything looks good, admit the connection to the channel //if everything looks good, admit the connection to the channel
socket.join(socket.chan); socket.join(socket.chan);
//Send out the userlist //Send out the userlist
module.exports.broadcastUserList(io, socket.chan); this.broadcastUserList(socket.chan);
}catch(err){ }catch(err){
socket.disconnect("Server Error During Channel Connection Initialization"); socket.disconnect("Server Error During Channel Connection Initialization");
@ -88,36 +105,47 @@ module.exports.handleConnection = async function(io, socket){
//Socket Listeners //Socket Listeners
socket.conn.on("close", (reason) => { socket.conn.on("close", (reason) => {
//Get active channel //Get active channel
var activeChan = activeChannels.get(socket.chan); var activeChan = this.activeChannels.get(socket.chan);
//If we have more than one active connection //If we have more than one active connection
if(activeChan.userList.get(socket.user.user).length > 1){ if(activeChan.userList.get(socket.user.user).sockets.length > 1){
//temporarily store list of active user sockets //temporarily store userObj
var socketList = activeChan.userList.get(socket.user.user); var userObj = activeChan.userList.get(socket.user.user);
//Filter out disconnecting socket from socket list, and set as current socket list for user //Filter out disconnecting socket from socket list, and set as current socket list for user
activeChan.userList.set(socket.user.user,socketList.filter((id) => { userObj.sockets = userObj.sockets.filter((id) => {
return id != socket.id; return id != socket.id;
})) });
//Update the userlist
activeChan.userList.set(socket.user.user, userObj);
}else{ }else{
//If this is the last connection for this user, remove them from the userlist
activeChan.userList.delete(socket.user.user); activeChan.userList.delete(socket.user.user);
} }
//and send out the filtered list //and send out the filtered list
module.exports.broadcastUserList(io, socket.chan); this.broadcastUserList(socket.chan);
}); });
//define chat listeners //define chat listeners
chatHandler.defineListeners(io, socket); this.chatHandler.defineListeners(socket);
} }
module.exports.broadcastUserList = function(io, chan){ broadcastUserList(chan){
var activeChan = activeChannels.get(chan); var activeChan = this.activeChannels.get(chan);
var userList = []; var userList = [];
activeChan.userList.forEach((socketlist, user) => { activeChan.userList.forEach((socketlist, user) => {
userList.push(user); userList.push(user);
}); });
io.in(chan).emit("user-list", userList); this.io.in(chan).emit("user-list", userList);
}
socketToUser(socket){
const channel = this.activeChannels.get(socket.chan);
return channel.userList.get(socket.user.user);
}
} }

View file

@ -16,16 +16,26 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
//NPM Imports //NPM Imports
const validator = require('validator');//No express here, so regular validator it is! const validator = require('validator');//No express here, so regular validator it is!
//local imports
const loggerUtils = require('../../utils/loggerUtils'); const loggerUtils = require('../../utils/loggerUtils');
const userModel = require('../../schemas/userSchema'); const userModel = require('../../schemas/userSchema');
const channelManager = require('./channelManager');
module.exports.defineListeners = function(io, socket){ module.exports = class{
constructor(server){
this.server = server;
}
defineListeners(socket){
socket.on("chatMessage", (data) => { socket.on("chatMessage", (data) => {
//Trim and Sanatize for XSS //Trim and Sanatize for XSS
const msg = validator.trim(validator.escape(data.msg)); const msg = validator.trim(validator.escape(data.msg));
//make sure high is an int //make sure high is an int
const high = validator.toInt(data.high); const high = validator.toInt(data.high);
const user = this.server.socketToUser(socket);
//nuke the message if its empty or huge //nuke the message if its empty or huge
if(!validator.isLength(msg, {min: 1, max: 255})){ if(!validator.isLength(msg, {min: 1, max: 255})){
return; return;
@ -36,7 +46,7 @@ module.exports.defineListeners = function(io, socket){
return; return;
} }
io.in(socket.chan).emit("chatMessage", {user: socket.user.user, flair: socket.user.flair, high, msg}); this.server.io.in(socket.chan).emit("chatMessage", {user: socket.user.user, flair: user.flair, high, msg});
}); });
socket.on("setFlair", async (data) => { socket.on("setFlair", async (data) => {
@ -51,7 +61,6 @@ module.exports.defineListeners = function(io, socket){
return loggerUtils.socketExceptionHandler(socket, err); return loggerUtils.socketExceptionHandler(socket, err);
} }
} }
}); });
}
} }

View file

@ -110,7 +110,7 @@ statModel.incrementLaunchCount();
flairModel.loadDefaults(); flairModel.loadDefaults();
//Hand over general-namespace socket.io connections to the channel manager //Hand over general-namespace socket.io connections to the channel manager
io.on("connection", (socket) => {channelManager.handleConnection(io, socket)} ); module.exports.channelManager = new channelManager(io)
//Listen Function //Listen Function
httpServer.listen(port, () => { httpServer.listen(port, () => {