diff options
Diffstat (limited to 'server/src/commands/core')
-rw-r--r-- | server/src/commands/core/changenick.js | 67 | ||||
-rw-r--r-- | server/src/commands/core/chat.js | 69 | ||||
-rw-r--r-- | server/src/commands/core/emote.js | 53 | ||||
-rw-r--r-- | server/src/commands/core/help.js | 47 | ||||
-rw-r--r-- | server/src/commands/core/invite.js | 37 | ||||
-rw-r--r-- | server/src/commands/core/join.js | 67 | ||||
-rw-r--r-- | server/src/commands/core/morestats.js | 42 | ||||
-rw-r--r-- | server/src/commands/core/move.js | 49 | ||||
-rw-r--r-- | server/src/commands/core/ping.js | 11 | ||||
-rw-r--r-- | server/src/commands/core/stats.js | 22 | ||||
-rw-r--r-- | server/src/commands/core/whisper.js | 69 |
11 files changed, 273 insertions, 260 deletions
diff --git a/server/src/commands/core/changenick.js b/server/src/commands/core/changenick.js index cb6d1d0..632da83 100644 --- a/server/src/commands/core/changenick.js +++ b/server/src/commands/core/changenick.js @@ -6,43 +6,43 @@ const verifyNickname = (nick) => /^[a-zA-Z0-9_]{1,24}$/.test(nick); // module main -exports.run = async (core, server, socket, data) => { - if (server.police.frisk(socket.remoteAddress, 6)) { +export async function run(core, server, socket, data) { + if (server.police.frisk(socket.address, 6)) { return server.reply({ cmd: 'warn', - text: 'You are changing nicknames too fast. Wait a moment before trying again.' + text: 'You are changing nicknames too fast. Wait a moment before trying again.', }, socket); } // verify user data is string if (typeof data.nick !== 'string') { - return; + return true; } // make sure requested nickname meets standards - let newNick = data.nick.trim(); + const newNick = data.nick.trim(); if (!verifyNickname(newNick)) { return server.reply({ cmd: 'warn', - text: 'Nickname must consist of up to 24 letters, numbers, and underscores' + text: 'Nickname must consist of up to 24 letters, numbers, and underscores', }, socket); } // prevent admin impersonation // TODO: prevent mod impersonation - if (newNick.toLowerCase() == core.config.adminName.toLowerCase()) { - server.police.frisk(socket.remoteAddress, 4); + if (newNick.toLowerCase() === core.config.adminName.toLowerCase()) { + server.police.frisk(socket.address, 4); return server.reply({ cmd: 'warn', - text: 'You are not the admin, liar!' + text: 'You are not the admin, liar!', }, socket); } // find any sockets that have the same nickname - let userExists = server.findSockets({ + const userExists = server.findSockets({ channel: socket.channel, - nick: (targetNick) => targetNick.toLowerCase() === newNick.toLowerCase() + nick: (targetNick) => targetNick.toLowerCase() === newNick.toLowerCase(), }); // return error if found @@ -50,82 +50,83 @@ exports.run = async (core, server, socket, data) => { // That nickname is already in that channel return server.reply({ cmd: 'warn', - text: 'Nickname taken' + text: 'Nickname taken', }, socket); } // build join and leave notices // TODO: this is a legacy client holdover, name changes in the future will // have thieir own event - let leaveNotice = { + const leaveNotice = { cmd: 'onlineRemove', - nick: socket.nick + nick: socket.nick, }; - let joinNotice = { + const joinNotice = { cmd: 'onlineAdd', nick: newNick, trip: socket.trip || 'null', - hash: socket.hash + hash: socket.hash, }; // broadcast remove event and join event with new name, this is to support legacy clients and bots - server.broadcast( leaveNotice, { channel: socket.channel }); - server.broadcast( joinNotice, { channel: socket.channel }); + server.broadcast(leaveNotice, { channel: socket.channel }); + server.broadcast(joinNotice, { channel: socket.channel }); // notify channel that the user has changed their name - server.broadcast( { + server.broadcast({ cmd: 'info', - text: `${socket.nick} is now ${newNick}` + text: `${socket.nick} is now ${newNick}`, }, { channel: socket.channel }); // commit change to nickname socket.nick = newNick; -}; + + return true; +} // module hook functions -exports.initHooks = (server) => { +export function initHooks(server) { server.registerHook('in', 'chat', this.nickCheck, 29); -}; +} // hooks chat commands checking for /nick -exports.nickCheck = (core, server, socket, payload) => { +export function nickCheck(core, server, socket, payload) { if (typeof payload.text !== 'string') { return false; } if (payload.text.startsWith('/nick')) { - let input = payload.text.split(' '); + const input = payload.text.split(' '); // If there is no nickname target parameter if (input[1] === undefined) { server.reply({ cmd: 'warn', - text: 'Refer to `/help nick` for instructions on how to use this command.' + text: 'Refer to `/help nick` for instructions on how to use this command.', }, socket); return false; } - let newNick = input[1].replace(/@/g, ''); + const newNick = input[1].replace(/@/g, ''); this.run(core, server, socket, { cmd: 'changenick', - nick: newNick + nick: newNick, }); return false; } return payload; -}; +} -// module meta -exports.requiredData = ['nick']; -exports.info = { +export const requiredData = ['nick']; +export const info = { name: 'changenick', description: 'This will change your current connections nickname', usage: ` API: { cmd: 'changenick', nick: '<new nickname>' } - Text: /nick <new nickname>` + Text: /nick <new nickname>`, }; diff --git a/server/src/commands/core/chat.js b/server/src/commands/core/chat.js index 7b7e79e..8d0098b 100644 --- a/server/src/commands/core/chat.js +++ b/server/src/commands/core/chat.js @@ -9,43 +9,45 @@ const parseText = (text) => { return false; } + let sanitizedText = text; + // strip newlines from beginning and end - text = text.replace(/^\s*\n|^\s+$|\n\s*$/g, ''); + sanitizedText = sanitizedText.replace(/^\s*\n|^\s+$|\n\s*$/g, ''); // replace 3+ newlines with just 2 newlines - text = text.replace(/\n{3,}/g, "\n\n"); + sanitizedText = sanitizedText.replace(/\n{3,}/g, '\n\n'); - return text; + return sanitizedText; }; // module main -exports.run = async (core, server, socket, data) => { +export async function run(core, server, socket, data) { // check user input - let text = parseText(data.text); + const text = parseText(data.text); if (!text) { // lets not send objects or empty text, yea? - return server.police.frisk(socket.remoteAddress, 13); + return server.police.frisk(socket.address, 13); } // check for spam - let score = text.length / 83 / 4; - if (server.police.frisk(socket.remoteAddress, score)) { + const score = text.length / 83 / 4; + if (server.police.frisk(socket.address, score)) { return server.reply({ cmd: 'warn', - text: 'You are sending too much text. Wait a moment and try again.\nPress the up arrow key to restore your last message.' + text: 'You are sending too much text. Wait a moment and try again.\nPress the up arrow key to restore your last message.', }, socket); } // build chat payload - let payload = { + const payload = { cmd: 'chat', nick: socket.nick, - text: text + text, }; - if (socket.uType == 'admin') { + if (socket.uType === 'admin') { payload.admin = true; - } else if (socket.uType == 'mod') { + } else if (socket.uType === 'mod') { payload.mod = true; } @@ -54,20 +56,22 @@ exports.run = async (core, server, socket, data) => { } // broadcast to channel peers - server.broadcast( payload, { channel: socket.channel}); + server.broadcast(payload, { channel: socket.channel }); // stats are fun core.stats.increment('messages-sent'); -}; + + return true; +} // module hook functions -exports.initHooks = (server) => { +export function initHooks(server) { server.registerHook('in', 'chat', this.commandCheckIn, 20); server.registerHook('in', 'chat', this.finalCmdCheck, 254); -}; +} // checks for miscellaneous '/' based commands -exports.commandCheckIn = (core, server, socket, payload) => { +export function commandCheckIn(core, server, socket, payload) { if (typeof payload.text !== 'string') { return false; } @@ -75,16 +79,16 @@ exports.commandCheckIn = (core, server, socket, payload) => { if (payload.text.startsWith('/myhash')) { server.reply({ cmd: 'info', - text: `Your hash: ${socket.hash}` + text: `Your hash: ${socket.hash}`, }, socket); return false; } return payload; -}; +} -exports.finalCmdCheck = (core, server, socket, payload) => { +export function finalCmdCheck(core, server, socket, payload) { if (typeof payload.text !== 'string') { return false; } @@ -97,26 +101,23 @@ exports.finalCmdCheck = (core, server, socket, payload) => { payload.text = payload.text.substr(1); return payload; - } else { - server.reply({ - cmd: 'warn', - text: `Unknown command: ${payload.text}` - }, socket); - - return false; } - return payload; -}; + server.reply({ + cmd: 'warn', + text: `Unknown command: ${payload.text}`, + }, socket); + + return false; +} -// module meta -exports.requiredData = ['text']; -exports.info = { +export const requiredData = ['text']; +export const info = { name: 'chat', description: 'Broadcasts passed `text` field to the calling users channel', usage: ` API: { cmd: 'chat', text: '<text to send>' } Text: Uuuuhm. Just kind type in that little box at the bottom and hit enter.\n Bonus super secret hidden commands: - /myhash` + /myhash`, }; diff --git a/server/src/commands/core/emote.js b/server/src/commands/core/emote.js index b0203cc..f244d74 100644 --- a/server/src/commands/core/emote.js +++ b/server/src/commands/core/emote.js @@ -9,91 +9,94 @@ const parseText = (text) => { return false; } + let sanitizedText = text; + // strip newlines from beginning and end - text = text.replace(/^\s*\n|^\s+$|\n\s*$/g, ''); + sanitizedText = sanitizedText.replace(/^\s*\n|^\s+$|\n\s*$/g, ''); // replace 3+ newlines with just 2 newlines - text = text.replace(/\n{3,}/g, "\n\n"); + sanitizedText = sanitizedText.replace(/\n{3,}/g, '\n\n'); - return text; + return sanitizedText; }; // module main -exports.run = async (core, server, socket, payload) => { +export async function run(core, server, socket, payload) { // check user input - let text = parseText(payload.text); + const text = parseText(payload.text); if (!text) { // lets not send objects or empty text, yea? - return server.police.frisk(socket.remoteAddress, 8); + return server.police.frisk(socket.address, 8); } // check for spam - let score = text.length / 83 / 4; - if (server.police.frisk(socket.remoteAddress, score)) { + const score = text.length / 83 / 4; + if (server.police.frisk(socket.address, score)) { return server.reply({ cmd: 'warn', - text: 'You are sending too much text. Wait a moment and try again.\nPress the up arrow key to restore your last message.' + text: 'You are sending too much text. Wait a moment and try again.\nPress the up arrow key to restore your last message.', }, socket); } - let newPayload = { + const newPayload = { cmd: 'info', type: 'emote', nick: socket.nick, - text: `@${socket.nick} ${text}` + text: `@${socket.nick} ${text}`, }; if (socket.trip) { newPayload.trip = socket.trip; } // broadcast to channel peers - server.broadcast( newPayload, { channel: socket.channel}); -}; + server.broadcast(newPayload, { channel: socket.channel }); + + return true; +} // module hook functions -exports.initHooks = (server) => { +export function initHooks(server) { server.registerHook('in', 'chat', this.emoteCheck, 30); -}; +} // hooks chat commands checking for /me -exports.emoteCheck = (core, server, socket, payload) => { +export function emoteCheck(core, server, socket, payload) { if (typeof payload.text !== 'string') { return false; } if (payload.text.startsWith('/me ')) { - let input = payload.text.split(' '); + const input = payload.text.split(' '); // If there is no emote target parameter if (input[1] === undefined) { server.reply({ cmd: 'warn', - text: 'Refer to `/help emote` for instructions on how to use this command.' + text: 'Refer to `/help emote` for instructions on how to use this command.', }, socket); return false; } input.splice(0, 1); - let actionText = input.join(' '); + const actionText = input.join(' '); this.run(core, server, socket, { cmd: 'emote', - text: actionText + text: actionText, }); return false; } return payload; -}; +} -// module meta -exports.requiredData = ['text']; -exports.info = { +export const requiredData = ['text']; +export const info = { name: 'emote', description: 'Typical emote / action text', usage: ` API: { cmd: 'emote', text: '<emote/action text>' } - Text: /me <emote/action text>` + Text: /me <emote/action text>`, }; diff --git a/server/src/commands/core/help.js b/server/src/commands/core/help.js index 8eccdb6..25f8844 100644 --- a/server/src/commands/core/help.js +++ b/server/src/commands/core/help.js @@ -3,21 +3,21 @@ */ // module support functions -const stripIndents = require('common-tags').stripIndents; +const { stripIndents } = require('common-tags'); // module main -exports.run = async (core, server, socket, payload) => { +export async function run(core, server, socket, payload) { // check for spam - if (server.police.frisk(socket.remoteAddress, 2)) { + if (server.police.frisk(socket.address, 2)) { return server.reply({ cmd: 'warn', - text: 'You are sending too much text. Wait a moment and try again.\nPress the up arrow key to restore your last message.' + text: 'You are sending too much text. Wait a moment and try again.\nPress the up arrow key to restore your last message.', }, socket); } // verify user input if (typeof payload.command !== 'undefined' && typeof payload.command !== 'string') { - return; + return true; } let reply = ''; @@ -27,21 +27,21 @@ exports.run = async (core, server, socket, payload) => { API: {cmd: 'help', command: '<command name>'}`; reply += '\n\n-------------------------------------\n\n'; - let categories = core.commands.categoriesList.sort(); - for (let i = 0, j = categories.length; i < j; i++) { - reply += `${categories[i].replace('../src/commands/', '').replace(/^\w/, c => c.toUpperCase())} Commands:\n`; - let catCommands = core.commands.all(categories[i]).sort((a, b) => a.info.name.localeCompare(b.info.name)); - reply += ` ${catCommands.map(c => `${c.info.name}`).join(', ')}\n\n`; + const categories = core.commands.categoriesList.sort(); + for (let i = 0, j = categories.length; i < j; i += 1) { + reply += `${categories[i].replace('../src/commands/', '').replace(/^\w/, (c) => c.toUpperCase())} Commands:\n`; + const catCommands = core.commands.all(categories[i]).sort((a, b) => a.info.name.localeCompare(b.info.name)); + reply += ` ${catCommands.map((c) => `${c.info.name}`).join(', ')}\n\n`; } } else { - let command = core.commands.get(payload.command); + const command = core.commands.get(payload.command); if (typeof command === 'undefined') { reply = 'Unknown command'; } else { reply = stripIndents`Name: ${command.info.name} Aliases: ${typeof command.info.aliases !== 'undefined' ? command.info.aliases.join(', ') : 'None'} - Category: ${command.info.category.replace('../src/commands/', '').replace(/^\w/, c => c.toUpperCase())} + Category: ${command.info.category.replace('../src/commands/', '').replace(/^\w/, (c) => c.toUpperCase())} Required Parameters: ${command.requiredData || 'None'}\n Description: ${command.info.description || '¯\_(ツ)_/¯'}\n Usage: ${command.info.usage || command.info.name}`; @@ -51,40 +51,41 @@ exports.run = async (core, server, socket, payload) => { // output reply server.reply({ cmd: 'info', - text: reply + text: reply, }, socket); -}; + + return true; +} // module hook functions -exports.initHooks = (server) => { +export function initHooks(server) { server.registerHook('in', 'chat', this.helpCheck, 28); -}; +} // hooks chat commands checking for /whisper -exports.helpCheck = (core, server, socket, payload) => { +export function helpCheck(core, server, socket, payload) { if (typeof payload.text !== 'string') { return false; } if (payload.text.startsWith('/help')) { - let input = payload.text.substr(1).split(' ', 2); + const input = payload.text.substr(1).split(' ', 2); this.run(core, server, socket, { cmd: input[0], - command: input[1] + command: input[1], }); return false; } return payload; -}; +} -// module meta -exports.info = { +export const info = { name: 'help', description: 'Outputs information about the servers current protocol', usage: ` API: { cmd: 'help', command: '<optional command name>' } - Text: /help <optional command name>` + Text: /help <optional command name>`, }; diff --git a/server/src/commands/core/invite.js b/server/src/commands/core/invite.js index 70393b1..1811e8b 100644 --- a/server/src/commands/core/invite.js +++ b/server/src/commands/core/invite.js @@ -6,47 +6,47 @@ const verifyNickname = (nick) => /^[a-zA-Z0-9_]{1,24}$/.test(nick); // module main -exports.run = async (core, server, socket, data) => { +export async function run(core, server, socket, data) { // check for spam - if (server.police.frisk(socket.remoteAddress, 2)) { + if (server.police.frisk(socket.address, 2)) { return server.reply({ cmd: 'warn', - text: 'You are sending invites too fast. Wait a moment before trying again.' + text: 'You are sending invites too fast. Wait a moment before trying again.', }, socket); } // verify user input if (typeof data.nick !== 'string' || !verifyNickname(data.nick)) { - return; + return true; } // why would you invite yourself? - if (data.nick == socket.nick) { - return; + if (data.nick === socket.nick) { + return true; } // generate common channel - let channel = Math.random().toString(36).substr(2, 8); + const channel = Math.random().toString(36).substr(2, 8); // build and send invite - let payload = { + const payload = { cmd: 'info', type: 'invite', from: socket.nick, invite: channel, - text: `${socket.nick} invited you to ?${channel}` + text: `${socket.nick} invited you to ?${channel}`, }; - let inviteSent = server.broadcast( payload, { + const inviteSent = server.broadcast(payload, { channel: socket.channel, - nick: data.nick + nick: data.nick, }); // server indicates the user was not found if (!inviteSent) { return server.reply({ cmd: 'warn', - text: 'Could not find user in channel' + text: 'Could not find user in channel', }, socket); } @@ -55,18 +55,19 @@ exports.run = async (core, server, socket, data) => { cmd: 'info', type: 'invite', invite: channel, - text: `You invited ${data.nick} to ?${channel}` + text: `You invited ${data.nick} to ?${channel}`, }, socket); // stats are fun core.stats.increment('invites-sent'); -}; -// module meta -exports.requiredData = ['nick']; -exports.info = { + return true; +} + +export const requiredData = ['nick']; +export const info = { name: 'invite', description: 'Generates a unique (more or less) room name and passes it to two clients', usage: ` - API: { cmd: 'invite', nick: '<target nickname>' }` + API: { cmd: 'invite', nick: '<target nickname>' }`, }; diff --git a/server/src/commands/core/join.js b/server/src/commands/core/join.js index 965a8bc..644470e 100644 --- a/server/src/commands/core/join.js +++ b/server/src/commands/core/join.js @@ -6,7 +6,7 @@ const crypto = require('crypto'); const hash = (password) => { - let sha = crypto.createHash('sha256'); + const sha = crypto.createHash('sha256'); sha.update(password); return sha.digest('base64').substr(0, 6); }; @@ -15,15 +15,15 @@ const verifyNickname = (nick) => /^[a-zA-Z0-9_]{1,24}$/.test(nick); // exposed "login" function to allow hooks to verify user join events // returns object containing user info or string if error -exports.parseNickname = (core, data) => { - let userInfo = { +export function parseNickname(core, data) { + const userInfo = { nick: '', uType: 'user', trip: null, }; // seperate nick from password - let nickArray = data.nick.split('#', 2); + const nickArray = data.nick.split('#', 2); userInfo.nick = nickArray[0].trim(); if (!verifyNickname(userInfo.nick)) { @@ -31,90 +31,92 @@ exports.parseNickname = (core, data) => { return 'Nickname must consist of up to 24 letters, numbers, and underscores'; } - let password = nickArray[1]; + const password = nickArray[1]; if (hash(password + core.config.tripSalt) === core.config.adminTrip) { userInfo.uType = 'admin'; userInfo.trip = 'Admin'; - } else if (userInfo.nick.toLowerCase() == core.config.adminName.toLowerCase()) { // they've got the main-admin name while not being an admin + } else if (userInfo.nick.toLowerCase() === core.config.adminName.toLowerCase()) { + // they've got the main-admin name while not being an admin return 'You are not the admin, liar!'; } else if (password) { userInfo.trip = hash(password + core.config.tripSalt); } // TODO: disallow moderator impersonation - for (let mod of core.config.mods) { + // for (const mod of core.config.mods) { + core.config.mods.forEach((mod) => { if (userInfo.trip === mod.trip) { userInfo.uType = 'mod'; } - } + }); return userInfo; -}; +} // module main -exports.run = async (core, server, socket, data) => { +export async function run(core, server, socket, data) { // check for spam - if (server.police.frisk(socket.remoteAddress, 3)) { + if (server.police.frisk(socket.address, 3)) { return server.reply({ cmd: 'warn', - text: 'You are joining channels too fast. Wait a moment and try again.' + text: 'You are joining channels too fast. Wait a moment and try again.', }, socket); } // calling socket already in a channel if (typeof socket.channel !== 'undefined') { - return; + return true; } // check user input if (typeof data.channel !== 'string' || typeof data.nick !== 'string') { - return; + return true; } - let channel = data.channel.trim(); + const channel = data.channel.trim(); if (!channel) { // must join a non-blank channel - return; + return true; } - let userInfo = this.parseNickname(core, data); + const userInfo = this.parseNickname(core, data); if (typeof userInfo === 'string') { return server.reply({ cmd: 'warn', - text: userInfo + text: userInfo, }, socket); } // check if the nickname already exists in the channel - let userExists = server.findSockets({ + const userExists = server.findSockets({ channel: data.channel, - nick: (targetNick) => targetNick.toLowerCase() === userInfo.nick.toLowerCase() + nick: (targetNick) => targetNick.toLowerCase() === userInfo.nick.toLowerCase(), }); if (userExists.length > 0) { // that nickname is already in that channel return server.reply({ cmd: 'warn', - text: 'Nickname taken' + text: 'Nickname taken', }, socket); } userInfo.userHash = server.getSocketHash(socket); // prepare to notify channel peers - let newPeerList = server.findSockets({ channel: data.channel }); - let nicks = []; + const newPeerList = server.findSockets({ channel: data.channel }); + const nicks = []; - let joinAnnouncement = { + const joinAnnouncement = { cmd: 'onlineAdd', nick: userInfo.nick, trip: userInfo.trip || 'null', - hash: userInfo.userHash + hash: userInfo.userHash, }; // send join announcement and prep online set - for (let i = 0, l = newPeerList.length; i < l; i++) { + for (let i = 0, l = newPeerList.length; i < l; i += 1) { server.reply(joinAnnouncement, newPeerList[i]); nicks.push(newPeerList[i].nick); } @@ -131,18 +133,19 @@ exports.run = async (core, server, socket, data) => { // reply with channel peer list server.reply({ cmd: 'onlineSet', - nicks: nicks + nicks, }, socket); // stats are fun core.stats.increment('users-joined'); -}; -// module meta -exports.requiredData = ['channel', 'nick']; -exports.info = { + return true; +} + +export const requiredData = ['channel', 'nick']; +export const info = { name: 'join', description: 'Place calling socket into target channel with target nick & broadcast event to channel', usage: ` - API: { cmd: 'join', nick: '<your nickname>', channel: '<target channel>' }` + API: { cmd: 'join', nick: '<your nickname>', channel: '<target channel>' }`, }; diff --git a/server/src/commands/core/morestats.js b/server/src/commands/core/morestats.js index a71729c..3cbf8f3 100644 --- a/server/src/commands/core/morestats.js +++ b/server/src/commands/core/morestats.js @@ -3,37 +3,38 @@ */ // module support functions -const stripIndents = require('common-tags').stripIndents; +const { stripIndents } = require('common-tags'); const formatTime = (time) => { let seconds = time[0] + time[1] / 1e9; let minutes = Math.floor(seconds / 60); - seconds = seconds % 60; + seconds %= 60; let hours = Math.floor(minutes / 60); - minutes = minutes % 60; + minutes %= 60; - let days = Math.floor(hours / 24); - hours = hours % 24; + const days = Math.floor(hours / 24); + hours %= 24; return `${days.toFixed(0)}d ${hours.toFixed(0)}h ${minutes.toFixed(0)}m ${seconds.toFixed(0)}s`; }; // module main -exports.run = async (core, server, socket, data) => { +export async function run(core, server, socket) { // gather connection and channel count let ips = {}; let channels = {}; - for (let client of server.clients) { + // for (const client of server.clients) { + this.clients.forEach((client) => { if (client.channel) { channels[client.channel] = true; - ips[client.remoteAddress] = true; + ips[client.address] = true; } - } + }); - let uniqueClientCount = Object.keys(ips).length; - let uniqueChannels = Object.keys(channels).length; + const uniqueClientCount = Object.keys(ips).length; + const uniqueChannels = Object.keys(channels).length; ips = null; channels = null; @@ -49,40 +50,39 @@ exports.run = async (core, server, socket, data) => { users-banned: ${(core.stats.get('users-banned') || 0)} users-kicked: ${(core.stats.get('users-kicked') || 0)} stats-requested: ${(core.stats.get('stats-requested') || 0)} - server-uptime: ${formatTime(process.hrtime(core.stats.get('start-time')))}` + server-uptime: ${formatTime(process.hrtime(core.stats.get('start-time')))}`, }, socket); // stats are fun core.stats.increment('stats-requested'); -}; +} // module hook functions -exports.initHooks = (server) => { +export function initHooks(server) { server.registerHook('in', 'chat', this.statsCheck, 26); -}; +} // hooks chat commands checking for /stats -exports.statsCheck = (core, server, socket, payload) => { +export function statsCheck(core, server, socket, payload) { if (typeof payload.text !== 'string') { return false; } if (payload.text.startsWith('/stats')) { this.run(core, server, socket, { - cmd: 'morestats' + cmd: 'morestats', }); return false; } return payload; -}; +} -// module meta -exports.info = { +export const info = { name: 'morestats', description: 'Sends back current server stats to the calling client', usage: ` API: { cmd: 'morestats' } - Text: /stats` + Text: /stats`, }; diff --git a/server/src/commands/core/move.js b/server/src/commands/core/move.js index 8e97a06..7eda88c 100644 --- a/server/src/commands/core/move.js +++ b/server/src/commands/core/move.js @@ -3,67 +3,67 @@ */ // module main -exports.run = async (core, server, socket, data) => { +export async function run(core, server, socket, data) { // check for spam - if (server.police.frisk(socket.remoteAddress, 6)) { + if (server.police.frisk(socket.address, 6)) { return server.reply({ cmd: 'warn', - text: 'You are changing channels too fast. Wait a moment before trying again.' + text: 'You are changing channels too fast. Wait a moment before trying again.', }, socket); } // check user input if (typeof data.channel !== 'string') { - return; + return true; } if (data.channel === socket.channel) { // they are trying to rejoin the channel - return; + return true; } // check that the nickname isn't already in target channel const currentNick = socket.nick.toLowerCase(); - let userExists = server.findSockets({ + const userExists = server.findSockets({ channel: data.channel, - nick: (targetNick) => targetNick.toLowerCase() === currentNick + nick: (targetNick) => targetNick.toLowerCase() === currentNick, }); if (userExists.length > 0) { // That nickname is already in that channel - return; + return true; } // broadcast leave notice to peers - let peerList = server.findSockets({ channel: socket.channel }); + const peerList = server.findSockets({ channel: socket.channel }); if (peerList.length > 1) { - for (let i = 0, l = peerList.length; i < l; i++) { + for (let i = 0, l = peerList.length; i < l; i += 1) { server.reply({ cmd: 'onlineRemove', - nick: peerList[i].nick + nick: peerList[i].nick, }, socket); - if (socket.nick !== peerList[i].nick){ + if (socket.nick !== peerList[i].nick) { server.reply({ cmd: 'onlineRemove', - nick: socket.nick + nick: socket.nick, }, peerList[i]); } } } // broadcast join notice to new peers - let newPeerList = server.findSockets({ channel: data.channel }); - let moveAnnouncement = { + const newPeerList = server.findSockets({ channel: data.channel }); + const moveAnnouncement = { cmd: 'onlineAdd', nick: socket.nick, trip: socket.trip || 'null', - hash: socket.hash + hash: socket.hash, }; - let nicks = []; + const nicks = []; - for (let i = 0, l = newPeerList.length; i < l; i++) { + for (let i = 0, l = newPeerList.length; i < l; i += 1) { server.reply(moveAnnouncement, newPeerList[i]); nicks.push(newPeerList[i].nick); } @@ -73,18 +73,19 @@ exports.run = async (core, server, socket, data) => { // reply with new user list server.reply({ cmd: 'onlineSet', - nicks: nicks + nicks, }, socket); // commit change socket.channel = data.channel; -}; -// module meta -exports.requiredData = ['channel']; -exports.info = { + return true; +} + +export const requiredData = ['channel']; +export const info = { name: 'move', description: 'This will change your current channel to the new one provided', usage: ` - API: { cmd: 'move', channel: '<target channel>' }` + API: { cmd: 'move', channel: '<target channel>' }`, }; diff --git a/server/src/commands/core/ping.js b/server/src/commands/core/ping.js index 1e710e5..7d8623d 100644 --- a/server/src/commands/core/ping.js +++ b/server/src/commands/core/ping.js @@ -3,12 +3,11 @@ */ // module main -exports.run = async (core, server, socket, data) => { - return; -}; +export async function run() { + +} -// module meta -exports.info = { +export const info = { name: 'ping', - description: 'This module is only in place to supress error notices legacy sources may get' + description: 'This module is only in place to supress error notices legacy sources may get', }; diff --git a/server/src/commands/core/stats.js b/server/src/commands/core/stats.js index ff4b1ef..8badd5b 100644 --- a/server/src/commands/core/stats.js +++ b/server/src/commands/core/stats.js @@ -3,19 +3,20 @@ */ // module main -exports.run = async (core, server, socket, data) => { +export async function run(core, server, socket) { // gather connection and channel count let ips = {}; let channels = {}; - for (let client of server.clients) { + // for (const client of server.clients) { + this.clients.forEach((client) => { if (client.channel) { channels[client.channel] = true; - ips[client.remoteAddress] = true; + ips[client.address] = true; } - } + }); - let uniqueClientCount = Object.keys(ips).length; - let uniqueChannels = Object.keys(channels).length; + const uniqueClientCount = Object.keys(ips).length; + const uniqueChannels = Object.keys(channels).length; ips = null; channels = null; @@ -23,17 +24,16 @@ exports.run = async (core, server, socket, data) => { // dispatch info server.reply({ cmd: 'info', - text: `${uniqueClientCount} unique IPs in ${uniqueChannels} channels` + text: `${uniqueClientCount} unique IPs in ${uniqueChannels} channels`, }, socket); // stats are fun core.stats.increment('stats-requested'); -}; +} -// module meta -exports.info = { +export const info = { name: 'stats', description: 'Sends back legacy server stats to the calling client', usage: ` - API: { cmd: 'stats' }` + API: { cmd: 'stats' }`, }; diff --git a/server/src/commands/core/whisper.js b/server/src/commands/core/whisper.js index 109889d..1cfa157 100644 --- a/server/src/commands/core/whisper.js +++ b/server/src/commands/core/whisper.js @@ -11,36 +11,38 @@ const parseText = (text) => { return false; } + let sanitizedText = text; + // strip newlines from beginning and end - text = text.replace(/^\s*\n|^\s+$|\n\s*$/g, ''); + sanitizedText = sanitizedText.replace(/^\s*\n|^\s+$|\n\s*$/g, ''); // replace 3+ newlines with just 2 newlines - text = text.replace(/\n{3,}/g, "\n\n"); + sanitizedText = sanitizedText.replace(/\n{3,}/g, '\n\n'); - return text; + return sanitizedText; }; // module main -exports.run = async (core, server, socket, payload) => { +export async function run(core, server, socket, payload) { // check user input - let text = parseText(payload.text); + const text = parseText(payload.text); if (!text) { // lets not send objects or empty text, yea? - return server.police.frisk(socket.remoteAddress, 13); + return server.police.frisk(socket.address, 13); } // check for spam - let score = text.length / 83 / 4; - if (server.police.frisk(socket.remoteAddress, score)) { + const score = text.length / 83 / 4; + if (server.police.frisk(socket.address, score)) { return server.reply({ cmd: 'warn', - text: 'You are sending too much text. Wait a moment and try again.\nPress the up arrow key to restore your last message.' + text: 'You are sending too much text. Wait a moment and try again.\nPress the up arrow key to restore your last message.', }, socket); } - let targetNick = payload.nick; + const targetNick = payload.nick; if (!verifyNickname(targetNick)) { - return; + return true; } // find target user @@ -49,18 +51,18 @@ exports.run = async (core, server, socket, payload) => { if (targetClient.length === 0) { return server.reply({ cmd: 'warn', - text: 'Could not find user in channel' + text: 'Could not find user in channel', }, socket); } - targetClient = targetClient[0]; + [targetClient] = targetClient; server.reply({ cmd: 'info', type: 'whisper', from: socket.nick, trip: socket.trip || 'null', - text: `${socket.nick} whispered: ${text}` + text: `${socket.nick} whispered: ${text}`, }, targetClient); targetClient.whisperReply = socket.nick; @@ -68,42 +70,44 @@ exports.run = async (core, server, socket, payload) => { server.reply({ cmd: 'info', type: 'whisper', - text: `You whispered to @${targetNick}: ${text}` + text: `You whispered to @${targetNick}: ${text}`, }, socket); -}; + + return true; +} // module hook functions -exports.initHooks = (server) => { +export function initHooks(server) { server.registerHook('in', 'chat', this.whisperCheck, 20); -}; +} // hooks chat commands checking for /whisper -exports.whisperCheck = (core, server, socket, payload) => { +export function whisperCheck(core, server, socket, payload) { if (typeof payload.text !== 'string') { return false; } if (payload.text.startsWith('/whisper')) { - let input = payload.text.split(' '); + const input = payload.text.split(' '); // If there is no nickname target parameter if (input[1] === undefined) { server.reply({ cmd: 'warn', - text: 'Refer to `/help whisper` for instructions on how to use this command.' + text: 'Refer to `/help whisper` for instructions on how to use this command.', }, socket); return false; } - let target = input[1].replace(/@/g, ''); + const target = input[1].replace(/@/g, ''); input.splice(0, 2); - let whisperText = input.join(' '); + const whisperText = input.join(' '); this.run(core, server, socket, { cmd: 'whisper', nick: target, - text: whisperText + text: whisperText, }); return false; @@ -113,35 +117,34 @@ exports.whisperCheck = (core, server, socket, payload) => { if (typeof socket.whisperReply === 'undefined') { server.reply({ cmd: 'warn', - text: 'Cannot reply to nobody' + text: 'Cannot reply to nobody', }, socket); return false; } - let input = payload.text.split(' '); + const input = payload.text.split(' '); input.splice(0, 1); - let whisperText = input.join(' '); + const whisperText = input.join(' '); this.run(core, server, socket, { cmd: 'whisper', nick: socket.whisperReply, - text: whisperText + text: whisperText, }); return false; } return payload; -}; +} -// module meta -exports.requiredData = ['nick', 'text']; -exports.info = { +export const requiredData = ['nick', 'text']; +export const info = { name: 'whisper', description: 'Display text on targets screen that only they can see', usage: ` API: { cmd: 'whisper', nick: '<target name>', text: '<text to whisper>' } Text: /whisper <target name> <text to whisper> - Alt Text: /r <text to whisper, this will auto reply to the last person who whispered to you>` + Alt Text: /r <text to whisper, this will auto reply to the last person who whispered to you>`, }; |