294 lines
No EOL
11 KiB
JavaScript
294 lines
No EOL
11 KiB
JavaScript
/*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 <https://www.gnu.org/licenses/>.*/
|
|
|
|
//Local Imports
|
|
const permissionModel = require('../../schemas/permissionSchema');
|
|
const channelModel = require('../../schemas/channel/channelSchema');
|
|
|
|
/**
|
|
* Class representing global server-side chat/command processing logic
|
|
*/
|
|
class commandProcessor{
|
|
/**
|
|
* Instantiates a commandProcessor object
|
|
* @param {channelManager} server - Parent Server Object
|
|
* @param {chatHandler} chatHandler - Parent Chat Handler Object
|
|
*/
|
|
constructor(server, chatHandler){
|
|
this.server = server;
|
|
this.chatHandler = chatHandler;
|
|
}
|
|
|
|
//Command keywords get run through .toLowerCase(), so we should use lowercase method names for command methods
|
|
/**
|
|
* Command Processor method to handle the '!whisper' command
|
|
* @param {Object} commandObj - Object representing a single given command/chat request
|
|
* @returns {Boolean} True to enable send flag
|
|
*/
|
|
whisper(commandObj){
|
|
//splice out our command
|
|
commandObj.commandArray.splice(0,2);
|
|
|
|
//Mark out the current message as a whisper
|
|
commandObj.chatType = 'whisper';
|
|
|
|
//Make sure to throw the send flag
|
|
return true
|
|
}
|
|
|
|
/**
|
|
* Command Processor method to handle the '!spoiler' command
|
|
* @param {Object} commandObj - Object representing a single given command/chat request
|
|
* @returns {Boolean} True to enable send flag
|
|
*/
|
|
spoiler(commandObj){
|
|
//splice out our command
|
|
commandObj.commandArray.splice(0,2);
|
|
|
|
//Mark out the current message as a spoiler
|
|
commandObj.chatType = 'spoiler';
|
|
|
|
//Make sure to throw the send flag
|
|
return true
|
|
}
|
|
|
|
/**
|
|
* Command Processor method to handle the '!strikethrough' command
|
|
* @param {Object} commandObj - Object representing a single given command/chat request
|
|
* @returns {Boolean} True to enable send flag
|
|
*/
|
|
strikethrough(commandObj){
|
|
//splice out our command
|
|
commandObj.commandArray.splice(0,2);
|
|
|
|
//Mark out the current message as a spoiler
|
|
commandObj.chatType = 'strikethrough';
|
|
|
|
//Make sure to throw the send flag
|
|
return true
|
|
}
|
|
|
|
/**
|
|
* Command Processor method to handle the '!bold' command
|
|
* @param {Object} commandObj - Object representing a single given command/chat request
|
|
* @returns {Boolean} True to enable send flag
|
|
*/
|
|
bold(commandObj){
|
|
//splice out our command
|
|
commandObj.commandArray.splice(0,2);
|
|
|
|
//Mark out the current message as a spoiler
|
|
commandObj.chatType = 'bold';
|
|
|
|
//Make sure to throw the send flag
|
|
return true
|
|
}
|
|
|
|
/**
|
|
* Command Processor method to handle the '!italics' command
|
|
* @param {Object} commandObj - Object representing a single given command/chat request
|
|
* @returns {Boolean} True to enable send flag
|
|
*/
|
|
italics(commandObj){
|
|
//splice out our command
|
|
commandObj.commandArray.splice(0,2);
|
|
|
|
//Mark out the current message as a spoiler
|
|
commandObj.chatType = 'italics';
|
|
|
|
//Make sure to throw the send flag
|
|
return true
|
|
}
|
|
|
|
/**
|
|
* Command Processor method to handle the '!announce' command
|
|
* @param {Object} commandObj - Object representing a single given command/chat request
|
|
* @returns {Boolean} True to enable send flag on un-authorized call to shame the user
|
|
*/
|
|
async announce(commandObj, preprocessor){
|
|
//Get the current channel from the database
|
|
const chanDB = await channelModel.findOne({name: commandObj.socket.chan});
|
|
|
|
//Check if the user has permission, and publicly shame them if they don't (lmao)
|
|
if(chanDB != null && await chanDB.permCheck(commandObj.socket.user, 'announce')){
|
|
//splice out our command
|
|
commandObj.commandArray.splice(0,2);
|
|
|
|
//Prep the message using pre-processor functions chat-handling
|
|
await preprocessor.prepMessage(commandObj);
|
|
|
|
//send it
|
|
this.chatHandler.relayChannelAnnouncement(commandObj.socket.chan, commandObj.message, commandObj.links);
|
|
|
|
//throw send flag
|
|
return false;
|
|
}
|
|
|
|
//throw send flag
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Command Processor method to handle the '!serverannounce' command
|
|
* @param {Object} commandObj - Object representing a single given command/chat request
|
|
* @returns {Boolean} True to enable send flag on un-authorized call to shame the user
|
|
*/
|
|
async serverannounce(commandObj, preprocessor){
|
|
//Check if the user has permission, and publicly shame them if they don't (lmao)
|
|
if(await permissionModel.permCheck(commandObj.socket.user, 'announce')){
|
|
//splice out our command
|
|
commandObj.commandArray.splice(0,2);
|
|
|
|
//Prep the message using pre-processor functions for chat-handling
|
|
await preprocessor.prepMessage(commandObj);
|
|
|
|
//send it
|
|
this.chatHandler.relayServerAnnouncement(commandObj.message, commandObj.links);
|
|
|
|
//disble send flag
|
|
return false;
|
|
}
|
|
|
|
//throw send flag
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Command Processor method to handle the '!resettoke' command
|
|
* @param {Object} commandObj - Object representing a single given command/chat request
|
|
* @returns {Boolean} True to enable send flag on un-authorized call to shame the user
|
|
*/
|
|
async resettoke(commandObj, preprocessor){
|
|
//Check if the user has permission, and publicly shame them if they don't (lmao)
|
|
if(await permissionModel.permCheck(commandObj.socket.user, 'resetToke')){
|
|
//Acknowledge command
|
|
this.chatHandler.relayTokeWhisper(commandObj.socket, 'Toke cooldown reset.');
|
|
|
|
//Tell tokebot to reset the toke
|
|
preprocessor.tokebot.resetToke();
|
|
|
|
//disable send flag
|
|
return false;
|
|
}
|
|
|
|
//throw send flag
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Command Processor method to handle the '!clear' command
|
|
* @param {Object} commandObj - Object representing a single given command/chat request
|
|
* @returns {Boolean} True to enable send flag on un-authorized call to shame the user
|
|
*/
|
|
async clear(commandObj){
|
|
//Get the current channel from the database
|
|
const chanDB = await channelModel.findOne({name: commandObj.socket.chan});
|
|
|
|
//Check if the user has permission, and publicly shame them if they don't (lmao)
|
|
if(await chanDB.permCheck(commandObj.socket.user, 'clearChat')){
|
|
//Send off the command
|
|
this.chatHandler.clearChat(commandObj.socket.chan, commandObj.argumentArray[1]);
|
|
//disable send flag
|
|
return false;
|
|
}
|
|
|
|
//throw send flag
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Command Processor method to handle the '!kick' command
|
|
* @param {Object} commandObj - Object representing a single given command/chat request
|
|
* @returns {Boolean} True to enable send flag on un-authorized call to shame the user
|
|
*/
|
|
async kick(commandObj){
|
|
//Get the current channel from the database
|
|
const chanDB = await channelModel.findOne({name: commandObj.socket.chan});
|
|
|
|
//Check if the user has permission, and publicly shame them if they don't (lmao)
|
|
if(await chanDB.permCheck(commandObj.socket.user, 'kickUser')){
|
|
//Get username from argument array
|
|
const username = commandObj.argumentArray[1];
|
|
|
|
//Get channel
|
|
const channel = this.server.activeChannels.get(commandObj.socket.chan);
|
|
|
|
//get initiator and target user objects
|
|
const initiator = channel.userList.get(commandObj.socket.user.user);
|
|
const target = channel.userList.get(username);
|
|
|
|
//get initiator and target override abilities
|
|
const override = await permissionModel.overrideCheck(commandObj.socket.user, 'kickUser');
|
|
const targetOverride = await permissionModel.overrideCheck(target, 'kickUser');
|
|
|
|
//If there is no user
|
|
if(target == null){
|
|
//silently drop the command
|
|
return false;
|
|
}
|
|
|
|
|
|
//If the user is capable of overriding this permission based on site permissions
|
|
if(override || targetOverride){
|
|
//If the site rank is equal
|
|
if(permissionModel.rankToNum(initiator.rank) == permissionModel.rankToNum(target.rank)){
|
|
//compare chan rank
|
|
if(permissionModel.rankToNum(initiator.chanRank) <= permissionModel.rankToNum(target.chanRank)){
|
|
//shame the person running it
|
|
return true;
|
|
}
|
|
//otherwise
|
|
}else{
|
|
//compare site rank
|
|
if(permissionModel.rankToNum(initiator.rank) <= permissionModel.rankToNum(target.rank)){
|
|
//shame the person running it
|
|
return true;
|
|
}
|
|
}
|
|
}else{
|
|
//If the target has a higher chan rank than the initiator
|
|
if(permissionModel.rankToNum(initiator.chanRank) <= permissionModel.rankToNum(target.chanRank)){
|
|
//shame the person running it
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
//Splice out kick
|
|
commandObj.commandArray.splice(0,4)
|
|
|
|
//Get collect reason
|
|
var reason = commandObj.commandArray.join('');
|
|
|
|
//If no reason was given
|
|
if(reason == ''){
|
|
//Fill in a generic reason
|
|
reason = "You have been kicked from the channel!";
|
|
}
|
|
|
|
//Kick the user
|
|
target.disconnect(reason);
|
|
|
|
//throw send flag
|
|
return false;
|
|
}
|
|
|
|
//throw send flag
|
|
return true;
|
|
}
|
|
}
|
|
|
|
module.exports = commandProcessor; |