119 lines
3.9 KiB
JavaScript
119 lines
3.9 KiB
JavaScript
/*Canopy - The next generation of stoner streaming software
|
|
Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.*/
|
|
|
|
//Local Imports
|
|
const channelModel = require('../../schemas/channelSchema');
|
|
const flairModel = require('../../schemas/flairSchema');
|
|
const userModel = require('../../schemas/userSchema');
|
|
const loggerUtils = require('../../utils/loggerUtils');
|
|
const activeChannel = require('./activeChannel');
|
|
const chatHandler = require('./chatHandler');
|
|
|
|
module.exports = class{
|
|
constructor(io){
|
|
//Set the socket.io server
|
|
this.io = io;
|
|
|
|
//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
|
|
if(socket.request.session.user != null){
|
|
try{
|
|
//Authenticate socket
|
|
const userDB = await this.authSocket(socket);
|
|
|
|
//Get the active channel based on the socket
|
|
var activeChan = await this.getActiveChan(socket);
|
|
|
|
//Define listeners
|
|
this.defineListeners(socket);
|
|
this.chatHandler.defineListeners(socket);
|
|
|
|
//Connect the socket to it's given channel
|
|
activeChan.handleConnection(userDB, socket);
|
|
}catch(err){
|
|
//Flip a table if something fucks up
|
|
return loggerUtils.socketCriticalExceptionHandler(socket, err);
|
|
}
|
|
}else{
|
|
//Toss out anon's
|
|
socket.disconnect("Unauthenticated");
|
|
return;
|
|
}
|
|
}
|
|
|
|
async authSocket(socket){
|
|
//Find the user in the Database since the session won't store enough data to fulfill our needs :P
|
|
const userDB = await userModel.findOne({user: socket.request.session.user.user});
|
|
|
|
if(userDB == null){
|
|
throw new Error("User not found!");
|
|
}
|
|
|
|
//Set socket user and channel values
|
|
socket.user = {
|
|
id: userDB.id,
|
|
user: userDB.user,
|
|
};
|
|
|
|
return userDB;
|
|
}
|
|
|
|
async getActiveChan(socket){
|
|
socket.chan = socket.handshake.headers.referer.split('/c/')[1];
|
|
|
|
//Check if channel exists
|
|
if(await channelModel.findOne({name: socket.chan}) == null){
|
|
throw new Error("Channel not found!")
|
|
}
|
|
|
|
//Check if current channel is active
|
|
var activeChan = this.activeChannels.get(socket.chan);
|
|
|
|
if(!activeChan){
|
|
//If not, make it so
|
|
activeChan = new activeChannel(this, socket.chan);
|
|
this.activeChannels.set(socket.chan, activeChan);
|
|
}
|
|
|
|
//Return whatever the active channel is (new or old)
|
|
return activeChan;
|
|
}
|
|
|
|
defineListeners(socket){
|
|
//Socket Listeners
|
|
socket.conn.on("close", (reason) => {this.handleDisconnect(socket, reason)});
|
|
}
|
|
|
|
handleDisconnect(socket, reason){
|
|
var activeChan = this.activeChannels.get(socket.chan);
|
|
activeChan.handleDisconnect(socket, reason);
|
|
}
|
|
|
|
getSocketInfo(socket){
|
|
const channel = this.activeChannels.get(socket.chan);
|
|
return channel.userList.get(socket.user.user);
|
|
}
|
|
} |