diff --git a/src/app/channel/chatHandler.js b/src/app/channel/chatHandler.js index 2d99a7e..a8235c1 100644 --- a/src/app/channel/chatHandler.js +++ b/src/app/channel/chatHandler.js @@ -14,9 +14,6 @@ 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 .*/ -//NPM Imports -const validator = require('validator');//No express here, so regular validator it is! - //local imports const commandPreprocessor = require('./commandPreprocessor'); const loggerUtils = require('../../utils/loggerUtils'); @@ -38,19 +35,6 @@ module.exports = class{ this.commandPreprocessor.preprocess(socket, data); } - relayChat(socket, data){ - //Trim and Sanatize for XSS - const msg = validator.trim(validator.escape(data)); - const user = this.server.getSocketInfo(socket); - - //nuke the message if its empty or huge - if(!validator.isLength(msg, {min: 1, max: 255})){ - return; - } - - this.server.io.in(socket.chan).emit("chatMessage", {user: user.user, flair: user.flair, highLevel: user.highLevel, msg}); - } - async setFlair(socket, data){ var userDB = await userModel.findOne({user: socket.user.user}); @@ -94,4 +78,9 @@ module.exports = class{ } } } + + relayChat(socket, msg, type = 'chat'){ + const user = this.server.getSocketInfo(socket); + this.server.io.in(socket.chan).emit("chatMessage", {user: user.user, flair: user.flair, highLevel: user.highLevel, msg, type}); + } } \ No newline at end of file diff --git a/src/app/channel/commandPreprocessor.js b/src/app/channel/commandPreprocessor.js index 04bf731..e5bf620 100644 --- a/src/app/channel/commandPreprocessor.js +++ b/src/app/channel/commandPreprocessor.js @@ -1,48 +1,100 @@ +/*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 .*/ + +//NPM Imports +const validator = require('validator');//No express here, so regular validator it is! module.exports = class commandPreprocessor{ constructor(server){ this.server = server; - this.commandProcessor = new commandProcessor(server); + this.commandProcessor = new commandProcessor(server, this); } preprocess(socket, data){ - //Set command, socket and sendFlag - this.command = data.msg; + //Set socket, data, and sendFlag this.socket = socket; this.sendFlag = true; + this.rawData = data; - this.splitBody(); + //If we don't pass sanatization/validation turn this car around + if(!this.sanatizeCommand()){ + return; + } + + //split the command + this.splitCommand(); + //Process the command this.processServerCommand(); + //Send it as chat (assuming the flag isn't false) this.sendChat(); } - splitBody(){ + sanatizeCommand(){ + //Trim and Sanatize for XSS + this.command = validator.trim(validator.escape(this.rawData.msg)); + + //nuke the message if its empty or huge + if(!validator.isLength(this.command, {min: 1, max: 255})){ + return false; + } + + //return true to tell preprocess to continue on + return true; + } + + splitCommand(){ //Split string by words this.commandArray = this.command.split(/\b/g);//Split by word-borders this.argumentArray = this.command.match(/\b\w+\b/g);//Match by words surrounded by borders } processServerCommand(){ + //If the first word is '!' if(this.commandArray[0] == '!'){ + //if it isn't just an exclimation point, and we have a real command if(this.argumentArray != null && this.commandProcessor[this.argumentArray[0]] != null){ + //disable chat this.sendFlag = false; - this.commandProcessor[this.argumentArray[0]](this.socket, this.argumentArray); + //Process the command + this.commandProcessor[this.argumentArray[0]](); } } } sendChat(){ + //If the send flag is true if(this.sendFlag){ - this.server.chatHandler.relayChat(this.socket, this.commandArray.join('')); + //FUCKIN' SEND IT! + this.server.chatHandler.relayChat(this.socket, this.commandArray.join('').trimStart()); } } } class commandProcessor{ - constructor(server){ + constructor(server, preprocessor){ this.server = server; + this.preprocessor = preprocessor } - whisper(socket, argumentArray){ - console.log(argumentArray); + whisper(){ + //Ensure we don't double dip + this.sendFlag = false; + + //splice out our whisper + this.preprocessor.commandArray.splice(0,2); + //send it + this.server.chatHandler.relayChat(this.preprocessor.socket, this.preprocessor.commandArray.join(''), 'whisper'); } } \ No newline at end of file diff --git a/www/css/channel.css b/www/css/channel.css index 29877f9..c44d7ce 100644 --- a/www/css/channel.css +++ b/www/css/channel.css @@ -190,6 +190,10 @@ span.user-entry{ width: fit-content; } +.whisper{ + font-size: 0.7em; +} + #media-panel-aspect-lock-icon{ display: none; } diff --git a/www/js/channel/chat.js b/www/js/channel/chat.js index ce18a6f..11418e4 100644 --- a/www/js/channel/chat.js +++ b/www/js/channel/chat.js @@ -76,31 +76,31 @@ class chatBox{ }); } - displayChat(chat){ + displayChat(data){ //Create chat-entry span var chatEntry = document.createElement('span'); - chatEntry.classList.add("chat-panel-buffer","chat-entry",`chat-entry-${chat.user}`); + chatEntry.classList.add("chat-panel-buffer","chat-entry",`chat-entry-${data.user}`); //Create high-level label var highLevel = document.createElement('p'); highLevel.classList.add("chat-panel-buffer","chat-entry-high-level","high-level"); - highLevel.innerHTML = `${chat.highLevel}`; + highLevel.innerHTML = `${data.highLevel}`; chatEntry.appendChild(highLevel); //Create username label var userLabel = document.createElement('p'); userLabel.classList.add("chat-panel-buffer","chat-entry-username"); - if(chat.flair != "classic"){ - var flair = `flair-${chat.flair}`; + if(data.flair != "classic"){ + var flair = `flair-${data.flair}`; }else{ - var flair = this.client.userList.colorMap.get(chat.user); + var flair = this.client.userList.colorMap.get(data.user); } //Create color span var colorSpan = document.createElement('span'); colorSpan.classList.add("chat-entry-flair-span", flair); - colorSpan.innerHTML = `${chat.user}`; + colorSpan.innerHTML = `${data.user}`; userLabel.innerHTML = `${colorSpan.outerHTML}: `; chatEntry.appendChild(userLabel); @@ -108,11 +108,11 @@ class chatBox{ //Create chat body var chatBody = document.createElement('p'); chatBody.classList.add("chat-panel-buffer","chat-entry-body"); - chatBody.innerHTML = chat.msg; + chatBody.innerHTML = data.msg; chatEntry.appendChild(chatBody); - this.chatBuffer.appendChild(this.chatPreprocessor.preprocess(chatEntry)); + this.chatBuffer.appendChild(this.chatPreprocessor.preprocess(chatEntry, data)); //Set size to aspect on launch this.resizeAspect(); diff --git a/www/js/channel/chatPreprocessor.js b/www/js/channel/chatPreprocessor.js index 74601f8..fff1321 100644 --- a/www/js/channel/chatPreprocessor.js +++ b/www/js/channel/chatPreprocessor.js @@ -2,7 +2,8 @@ class chatPreprocessor{ constructor(){ } - preprocess(chatEntry){ + preprocess(chatEntry, rawData){ + this.rawData = rawData; //Set current chat nodes this.chatEntry = chatEntry; this.chatBody = this.chatEntry.querySelector(".chat-entry-body"); @@ -12,6 +13,9 @@ class chatPreprocessor{ //Inject whitespace into un-processed words this.addWhitespace(); + + //Sush chat if it's a whisper + this.handleChatType(); //Inject the pre-processed chat into the chatEntry node this.injectBody(); @@ -73,4 +77,10 @@ class chatPreprocessor{ } }); } + + handleChatType(){ + if(this.rawData.type == "whisper"){ + this.chatBody.classList.add('whisper'); + } + } } \ No newline at end of file diff --git a/www/js/channel/commandPreprocessor.js b/www/js/channel/commandPreprocessor.js index 6549da9..ed9ee07 100644 --- a/www/js/channel/commandPreprocessor.js +++ b/www/js/channel/commandPreprocessor.js @@ -31,7 +31,7 @@ class commandPreprocessor{ this.sendFlag = false; //Call the command with the argument array - this.commandProcessor[this.argumentArray[0]](this.argumentArray); + this.commandProcessor[this.argumentArray[0]](this.argumentArray, this.commandArray); } } }