Initial commit.

This commit is contained in:
rainbownapkin 2024-11-15 17:44:03 -05:00
commit f0c91b4e55
78 changed files with 5054 additions and 0 deletions

View file

@ -0,0 +1,22 @@
/*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/>.*/
module.exports = class{
constructor(name){
this.name = name;
this.userList = new Map();
}
}

View file

@ -0,0 +1,112 @@
/*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 activeChannel = require('./activeChannel');
const chatHandler = require('./chatHandler');
//local variables
var activeChannels = new Map;
module.exports.handleConnection = async function(io, socket){
//Prevent logged out connections and authenticate socket
if(socket.request.session.user != null){
try{
//Set socket user and channel values
socket.user = socket.request.session.user;
socket.chanName = socket.handshake.headers.referer.split('/c/')[1];
//Check if channel exists
if(await channelModel.findOne({name: socket.chanName}) == null){
socket.disconnect("Channel does not exist!");
return;
}
//Check if current channel is active
var activeChan = activeChannels.get(socket.chan);
if(!activeChan){
//If not, make it so
activeChan = new activeChannel(socket.chan);
activeChannels.set(socket.chan, activeChan);
}
//Check if this user is already connected
if(activeChan.userList.get(socket.user.user)){
//get current list of socket connnections of selected user
var socketList = activeChan.userList.get(socket.user.user);
//Add this one on
socketList.push(socket.id);
//Set the user back socket list back
activeChan.userList.set(socket.user.user, socketList);
}else{
//if this is the first connection, initialize the socket array for this user
activeChan.userList.set(socket.user.user, [socket.id]);
}
//if everything looks good, admit the connection to the channel
socket.join(socket.chan);
//Send out the userlist
module.exports.broadcastUserList(io, socket.chan);
}catch(err){
socket.disconnect("Server Error During Channel Connection Initialization");
console.log(err);
return;
}
}else{
socket.disconnect("Unauthenticated");
return;
}
//Socket Listeners
socket.conn.on("close", (reason) => {
//Get active channel
var activeChan = activeChannels.get(socket.chan);
//If we have more than one active connection
if(activeChan.userList.get(socket.user.user).length > 1){
//temporarily store list of active user sockets
var socketList = activeChan.userList.get(socket.user.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) => {
return id != socket.id;
}))
}else{
activeChan.userList.delete(socket.user.user);
}
//and send out the filtered list
module.exports.broadcastUserList(io, socket.chan);
});
//define chat listeners
chatHandler.defineListeners(io, socket);
}
module.exports.broadcastUserList = function(io, chan){
var activeChan = activeChannels.get(chan);
var userList = [];
activeChan.userList.forEach((socketlist, user) => {
userList.push(user);
});
io.in(chan).emit("user-list", userList);
}

View file

@ -0,0 +1,39 @@
/*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/>.*/
//NPM Imports
const validator = require('validator');//No express here, so regular validator it is!
module.exports.defineListeners = function(io, socket){
socket.on("chat-message", (data) => {
//Trim and Sanatize for XSS
const msg = validator.trim(validator.escape(data.msg));
//make sure high is an int
const high = validator.toInt(data.high);
//nuke the message if its empty or huge
if(!validator.isLength(msg, {min: 1, max: 255})){
return;
}
//nuke the message if the high number is wrong
if(high < 0 || high > 10){
return;
}
io.in(socket.chan).emit("chat-message", {user: socket.user.user, msg, high});
});
}