aboutsummaryrefslogtreecommitdiffstats
path: root/server/src/commands
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--server/src/commands/admin/addmod.js27
-rw-r--r--server/src/commands/admin/listusers.js35
-rw-r--r--server/src/commands/admin/reload.js21
-rw-r--r--server/src/commands/admin/removemod.js29
-rw-r--r--server/src/commands/admin/saveconfig.js23
-rw-r--r--server/src/commands/admin/shout.js19
-rw-r--r--server/src/commands/core/changenick.js67
-rw-r--r--server/src/commands/core/chat.js69
-rw-r--r--server/src/commands/core/emote.js53
-rw-r--r--server/src/commands/core/help.js47
-rw-r--r--server/src/commands/core/invite.js37
-rw-r--r--server/src/commands/core/join.js67
-rw-r--r--server/src/commands/core/morestats.js42
-rw-r--r--server/src/commands/core/move.js49
-rw-r--r--server/src/commands/core/ping.js11
-rw-r--r--server/src/commands/core/stats.js22
-rw-r--r--server/src/commands/core/whisper.js69
-rw-r--r--server/src/commands/internal/disconnect.js17
-rw-r--r--server/src/commands/internal/legacylayer.js19
-rw-r--r--server/src/commands/internal/socketreply.js15
-rw-r--r--server/src/commands/mod/ban.js31
-rw-r--r--server/src/commands/mod/dumb.js85
-rw-r--r--server/src/commands/mod/kick.js37
-rw-r--r--server/src/commands/mod/moveuser.js59
-rw-r--r--server/src/commands/mod/speak.js33
-rw-r--r--server/src/commands/mod/unban.js22
-rw-r--r--server/src/commands/mod/unbanall.js19
27 files changed, 532 insertions, 492 deletions
diff --git a/server/src/commands/admin/addmod.js b/server/src/commands/admin/addmod.js
index 6853a42..26cec40 100644
--- a/server/src/commands/admin/addmod.js
+++ b/server/src/commands/admin/addmod.js
@@ -3,26 +3,26 @@
*/
// module main
-exports.run = async (core, server, socket, data) => {
+export async function run(core, server, socket, data) {
// increase rate limit chance and ignore if not admin
- if (socket.uType != 'admin') {
- return server.police.frisk(socket.remoteAddress, 20);
+ if (socket.uType !== 'admin') {
+ return server.police.frisk(socket.address, 20);
}
// add new trip to config
core.config.mods.push({ trip: data.trip });
// find targets current connections
- let newMod = server.findSockets({ trip: data.trip });
+ const newMod = server.findSockets({ trip: data.trip });
if (newMod.length !== 0) {
- for (let i = 0, l = newMod.length; i < l; i++) {
+ for (let i = 0, l = newMod.length; i < l; i += 1) {
// upgrade privilages
newMod[i].uType = 'mod';
// inform new mod
server.send({
cmd: 'info',
- text: 'You are now a mod.'
+ text: 'You are now a mod.',
}, newMod[i]);
}
}
@@ -30,21 +30,22 @@ exports.run = async (core, server, socket, data) => {
// return success message
server.reply({
cmd: 'info',
- text: `Added mod trip: ${data.trip}, remember to run 'saveconfig' to make it permanent`
+ text: `Added mod trip: ${data.trip}, remember to run 'saveconfig' to make it permanent`,
}, socket);
// notify all mods
server.broadcast({
cmd: 'info',
- text: `Added mod: ${data.trip}`
+ text: `Added mod: ${data.trip}`,
}, { uType: 'mod' });
-};
-// module meta
-exports.requiredData = ['trip'];
-exports.info = {
+ return true;
+}
+
+export const requiredData = ['trip'];
+export const info = {
name: 'addmod',
description: 'Adds target trip to the config as a mod and upgrades the socket type',
usage: `
- API: { cmd: 'addmod', trip: '<target trip>' }`
+ API: { cmd: 'addmod', trip: '<target trip>' }`,
};
diff --git a/server/src/commands/admin/listusers.js b/server/src/commands/admin/listusers.js
index 5ff350f..0b0199f 100644
--- a/server/src/commands/admin/listusers.js
+++ b/server/src/commands/admin/listusers.js
@@ -3,46 +3,47 @@
*/
// module main
-exports.run = async (core, server, socket, data) => {
+export async function run(core, server, socket) {
// increase rate limit chance and ignore if not admin
- if (socket.uType != 'admin') {
- return server.police.frisk(socket.remoteAddress, 20);
+ if (socket.uType !== 'admin') {
+ return server.police.frisk(socket.address, 20);
}
// find all users currently in a channel
- let currentUsers = server.findSockets({
- channel: (channel) => true
+ const currentUsers = server.findSockets({
+ channel: (channel) => true,
});
// compile channel and user list
- let channels = {};
- for (let i = 0, j = currentUsers.length; i < j; i++) {
+ const channels = {};
+ for (let i = 0, j = currentUsers.length; i < j; i += 1) {
if (typeof channels[currentUsers[i].channel] === 'undefined') {
channels[currentUsers[i].channel] = [];
}
-
+
channels[currentUsers[i].channel].push(
- `[${currentUsers[i].trip||'null'}]${currentUsers[i].nick}`
+ `[${currentUsers[i].trip || 'null'}]${currentUsers[i].nick}`,
);
}
// build output
- let lines = [];
- for (let channel in channels) {
- lines.push(`?${channel} ${channels[channel].join(", ")}`);
+ const lines = [];
+ for (const channel in channels) {
+ lines.push(`?${channel} ${channels[channel].join(', ')}`);
}
// send reply
server.reply({
cmd: 'info',
- text: lines.join("\n")
+ text: lines.join('\n'),
}, socket);
-};
-// module meta
-exports.info = {
+ return true;
+}
+
+export const info = {
name: 'listusers',
description: 'Outputs all current channels and sockets in those channels',
usage: `
- API: { cmd: 'listusers' }`
+ API: { cmd: 'listusers' }`,
};
diff --git a/server/src/commands/admin/reload.js b/server/src/commands/admin/reload.js
index 588d1c5..206e2ca 100644
--- a/server/src/commands/admin/reload.js
+++ b/server/src/commands/admin/reload.js
@@ -3,10 +3,10 @@
*/
// module main
-exports.run = async (core, server, socket, data) => {
+export async function run(core, server, socket, data) {
// increase rate limit chance and ignore if not admin
- if (socket.uType != 'admin') {
- return server.police.frisk(socket.remoteAddress, 20);
+ if (socket.uType !== 'admin') {
+ return server.police.frisk(socket.address, 20);
}
// do command reload and store results
@@ -17,7 +17,7 @@ exports.run = async (core, server, socket, data) => {
server.loadHooks();
// build reply based on reload results
- if (loadResult == '') {
+ if (loadResult === '') {
loadResult = `Reloaded ${core.commands.commands.length} commands, 0 errors`;
} else {
loadResult = `Reloaded ${core.commands.commands.length} commands, error(s):
@@ -31,20 +31,21 @@ exports.run = async (core, server, socket, data) => {
// reply with results
server.reply({
cmd: 'info',
- text: loadResult
+ text: loadResult,
}, socket);
// notify mods of reload #transparency
server.broadcast({
cmd: 'info',
- text: loadResult
+ text: loadResult,
}, { uType: 'mod' });
-};
-// module meta
-exports.info = {
+ return true;
+}
+
+export const info = {
name: 'reload',
description: '(Re)loads any new commands into memory, outputs errors if any',
usage: `
- API: { cmd: 'reload', reason: '<optional reason append>' }`
+ API: { cmd: 'reload', reason: '<optional reason append>' }`,
};
diff --git a/server/src/commands/admin/removemod.js b/server/src/commands/admin/removemod.js
index a2d862c..9190dd6 100644
--- a/server/src/commands/admin/removemod.js
+++ b/server/src/commands/admin/removemod.js
@@ -3,26 +3,26 @@
*/
// module main
-exports.run = async (core, server, socket, data) => {
+export async function run(core, server, socket, data) {
// increase rate limit chance and ignore if not admin
- if (socket.uType != 'admin') {
- return server.police.frisk(socket.remoteAddress, 20);
+ if (socket.uType !== 'admin') {
+ return server.police.frisk(socket.address, 20);
}
// remove trip from config
- core.config.mods = core.config.mods.filter(mod => mod.trip !== data.trip);
+ core.config.mods = core.config.mods.filter((mod) => mod.trip !== data.trip);
// find targets current connections
- let targetMod = server.findSockets({ trip: data.trip });
+ const targetMod = server.findSockets({ trip: data.trip });
if (targetMod.length !== 0) {
- for (let i = 0, l = targetMod.length; i < l; i++) {
+ for (let i = 0, l = targetMod.length; i < l; i += 1) {
// downgrade privilages
targetMod[i].uType = 'user';
// inform ex-mod
server.send({
cmd: 'info',
- text: 'You are now a user.'
+ text: 'You are now a user.',
}, targetMod[i]);
}
}
@@ -32,21 +32,22 @@ exports.run = async (core, server, socket, data) => {
cmd: 'info',
text: `Removed mod trip: ${
data.trip
- }, remember to run 'saveconfig' to make it permanent`
+ }, remember to run 'saveconfig' to make it permanent`,
}, socket);
// notify all mods
server.broadcast({
cmd: 'info',
- text: `Removed mod: ${data.trip}`
+ text: `Removed mod: ${data.trip}`,
}, { uType: 'mod' });
-};
-// module meta
-exports.requiredData = ['trip'];
-exports.info = {
+ return true;
+}
+
+export const requiredData = ['trip'];
+export const info = {
name: 'removemod',
description: 'Removes target trip from the config as a mod and downgrades the socket type',
usage: `
- API: { cmd: 'removemod', trip: '<target trip>' }`
+ API: { cmd: 'removemod', trip: '<target trip>' }`,
};
diff --git a/server/src/commands/admin/saveconfig.js b/server/src/commands/admin/saveconfig.js
index 65fff0e..6c713b4 100644
--- a/server/src/commands/admin/saveconfig.js
+++ b/server/src/commands/admin/saveconfig.js
@@ -3,37 +3,38 @@
*/
// module main
-exports.run = async (core, server, socket, data) => {
+export async function run(core, server, socket) {
// increase rate limit chance and ignore if not admin
- if (socket.uType != 'admin') {
- return server.police.frisk(socket.remoteAddress, 20);
+ if (socket.uType !== 'admin') {
+ return server.police.frisk(socket.address, 20);
}
// attempt save, notify of failure
if (!core.configManager.save()) {
return server.reply({
cmd: 'warn',
- text: 'Failed to save config, check logs.'
- }, client);
+ text: 'Failed to save config, check logs.',
+ }, socket);
}
// return success message
server.reply({
cmd: 'info',
- text: 'Config saved!'
+ text: 'Config saved!',
}, socket);
// notify mods #transparency
server.broadcast({
cmd: 'info',
- text: 'Config saved!'
+ text: 'Config saved!',
}, { uType: 'mod' });
-};
-// module meta
-exports.info = {
+ return true;
+}
+
+export const info = {
name: 'saveconfig',
description: 'Writes the current config to disk',
usage: `
- API: { cmd: 'saveconfig' }`
+ API: { cmd: 'saveconfig' }`,
};
diff --git a/server/src/commands/admin/shout.js b/server/src/commands/admin/shout.js
index 821a22a..73b0734 100644
--- a/server/src/commands/admin/shout.js
+++ b/server/src/commands/admin/shout.js
@@ -3,24 +3,25 @@
*/
// module main
-exports.run = async (core, server, socket, data) => {
+export async function run(core, server, socket, data) {
// increase rate limit chance and ignore if not admin
- if (socket.uType != 'admin') {
- return server.police.frisk(socket.remoteAddress, 20);
+ if (socket.uType !== 'admin') {
+ return server.police.frisk(socket.address, 20);
}
// send text to all channels
server.broadcast({
cmd: 'info',
- text: `Server Notice: ${data.text}`
+ text: `Server Notice: ${data.text}`,
}, {});
-};
-// module meta
-exports.requiredData = ['text'];
-exports.info = {
+ return true;
+}
+
+export const requiredData = ['text'];
+export const info = {
name: 'shout',
description: 'Displays passed text to every client connected',
usage: `
- API: { cmd: 'shout', text: '<shout text>' }`
+ API: { cmd: 'shout', text: '<shout text>' }`,
};
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>`,
};
diff --git a/server/src/commands/internal/disconnect.js b/server/src/commands/internal/disconnect.js
index 520f8cb..07a125e 100644
--- a/server/src/commands/internal/disconnect.js
+++ b/server/src/commands/internal/disconnect.js
@@ -4,28 +4,29 @@
*/
// module main
-exports.run = async (core, server, socket, data) => {
+export async function run(core, server, socket, data) {
if (data.cmdKey !== server.cmdKey) {
// internal command attempt by client, increase rate limit chance and ignore
- return server.police.frisk(socket.remoteAddress, 20);
+ return server.police.frisk(socket.address, 20);
}
// send leave notice to client peers
if (socket.channel) {
server.broadcast({
cmd: 'onlineRemove',
- nick: socket.nick
+ nick: socket.nick,
}, { channel: socket.channel });
}
// commit close just in case
socket.terminate();
-};
-// module meta
-exports.requiredData = ['cmdKey'];
-exports.info = {
+ return true;
+}
+
+export const requiredData = ['cmdKey'];
+export const info = {
name: 'disconnect',
usage: 'Internal Use Only',
- description: 'Internally used to relay `onlineRemove` event to clients'
+ description: 'Internally used to relay `onlineRemove` event to clients',
};
diff --git a/server/src/commands/internal/legacylayer.js b/server/src/commands/internal/legacylayer.js
index 50f5fd7..c0daa13 100644
--- a/server/src/commands/internal/legacylayer.js
+++ b/server/src/commands/internal/legacylayer.js
@@ -3,18 +3,19 @@
*/
// module main
-exports.run = async (core, server, socket, data) => {
- return;
-};
+export async function run(core, server, socket, data) {
+ /**
+ * @todo
+ */
+}
// module hook functions
-exports.initHooks = (server) => {
+export function initHooks(server) {
// module is only a placeholder
- //server.registerHook('out', '', this.);
-};
+ // server.registerHook('out', '', this.);
+}
-// module meta
-exports.info = {
+export const info = {
name: 'legacylayer',
- description: 'This module adjusts outgoing data, making it compatible with legacy clients'
+ description: 'This module adjusts outgoing data, making it compatible with legacy clients',
};
diff --git a/server/src/commands/internal/socketreply.js b/server/src/commands/internal/socketreply.js
index 5dadaf6..1ba8df2 100644
--- a/server/src/commands/internal/socketreply.js
+++ b/server/src/commands/internal/socketreply.js
@@ -3,20 +3,21 @@
*/
// module main
-exports.run = async (core, server, socket, data) => {
+export async function run(core, server, socket, data) {
if (data.cmdKey !== server.cmdKey) {
// internal command attempt by client, increase rate limit chance and ignore
- return server.police.frisk(socket.remoteAddress, 20);
+ return server.police.frisk(socket.address, 20);
}
// send warning to target socket
server.reply({ cmd: 'warn', text: data.text }, socket);
-};
-// module meta
-exports.requiredData = ['cmdKey', 'text'];
-exports.info = {
+ return true;
+}
+
+export const requiredData = ['cmdKey', 'text'];
+export const info = {
name: 'socketreply',
usage: 'Internal Use Only',
- description: 'Internally used to relay warnings to clients'
+ description: 'Internally used to relay warnings to clients',
};
diff --git a/server/src/commands/mod/ban.js b/server/src/commands/mod/ban.js
index 9c8eb4f..dd5f01e 100644
--- a/server/src/commands/mod/ban.js
+++ b/server/src/commands/mod/ban.js
@@ -3,53 +3,53 @@
*/
// module main
-exports.run = async (core, server, socket, data) => {
+export async function run(core, server, socket, data) {
// increase rate limit chance and ignore if not admin or mod
if (socket.uType === 'user') {
- return server.police.frisk(socket.remoteAddress, 10);
+ return server.police.frisk(socket.address, 10);
}
// check user input
if (typeof data.nick !== 'string') {
- return;
+ return true;
}
// find target user
- let targetNick = data.nick;
+ const targetNick = data.nick;
let badClient = server.findSockets({ channel: socket.channel, nick: targetNick });
if (badClient.length === 0) {
return server.reply({
cmd: 'warn',
- text: 'Could not find user in channel'
+ text: 'Could not find user in channel',
}, socket);
}
- badClient = badClient[0];
+ [badClient] = badClient;
// i guess banning mods or admins isn't the best idea?
if (badClient.uType !== 'user') {
return server.reply({
cmd: 'warn',
- text: 'Cannot ban other mods, how rude'
+ text: 'Cannot ban other mods, how rude',
}, socket);
}
// commit arrest record
- server.police.arrest(badClient.remoteAddress, badClient.hash);
+ server.police.arrest(badClient.address, badClient.hash);
console.log(`${socket.nick} [${socket.trip}] banned ${targetNick} in ${socket.channel}`);
// notify normal users
server.broadcast({
cmd: 'info',
- text: `Banned ${targetNick}`
+ text: `Banned ${targetNick}`,
}, { channel: socket.channel, uType: 'user' });
// notify mods
server.broadcast({
cmd: 'info',
- text: `${socket.nick} banned ${targetNick} in ${socket.channel}, userhash: ${badClient.hash}`
+ text: `${socket.nick} banned ${targetNick} in ${socket.channel}, userhash: ${badClient.hash}`,
}, { uType: 'mod' });
// force connection closed
@@ -57,13 +57,14 @@ exports.run = async (core, server, socket, data) => {
// stats are fun
core.stats.increment('users-banned');
-};
-// module meta
-exports.requiredData = ['nick'];
-exports.info = {
+ return true;
+}
+
+export const requiredData = ['nick'];
+export const info = {
name: 'ban',
description: 'Disconnects the target nickname in the same channel as calling socket & adds to ratelimiter',
usage: `
- API: { cmd: 'ban', nick: '<target nickname>' }`
+ API: { cmd: 'ban', nick: '<target nickname>' }`,
};
diff --git a/server/src/commands/mod/dumb.js b/server/src/commands/mod/dumb.js
index d5e8fee..644bd4f 100644
--- a/server/src/commands/mod/dumb.js
+++ b/server/src/commands/mod/dumb.js
@@ -4,22 +4,22 @@
*/
// module constructor
-exports.init = (core) => {
+export function init(core) {
if (typeof core.muzzledHashes === 'undefined') {
core.muzzledHashes = {};
}
-};
+}
// module main
-exports.run = async (core, server, socket, data) => {
+export async function run(core, server, socket, data) {
// increase rate limit chance and ignore if not admin or mod
if (socket.uType === 'user') {
- return server.police.frisk(socket.remoteAddress, 10);
+ return server.police.frisk(socket.address, 10);
}
// check user input
if (typeof data.nick !== 'string') {
- return;
+ return true;
}
// find target user
@@ -28,56 +28,58 @@ exports.run = async (core, server, socket, data) => {
if (badClient.length === 0) {
return server.reply({
cmd: 'warn',
- text: 'Could not find user in channel'
+ text: 'Could not find user in channel',
}, socket);
}
- badClient = badClient[0];
+ [badClient] = badClient;
// likely dont need this, muting mods and admins is fine
if (badClient.uType !== 'user') {
return server.reply({
cmd: 'warn',
- text: 'This trick wont work on mods and admin'
+ text: 'This trick wont work on mods and admin',
}, socket);
}
// store hash in mute list
- let record = core.muzzledHashes[badClient.hash] = {
- dumb: true
- }
+ const record = core.muzzledHashes[badClient.hash] = {
+ dumb: true,
+ };
// store allies if needed
- if(data.allies && Array.isArray(data.allies)){
- record.allies = data.allies;
+ if (data.allies && Array.isArray(data.allies)) {
+ record.allies = data.allies;
}
// notify mods
server.broadcast({
cmd: 'info',
- text: `${socket.nick} muzzled ${data.nick} in ${socket.channel}, userhash: ${badClient.hash}`
+ text: `${socket.nick} muzzled ${data.nick} in ${socket.channel}, userhash: ${badClient.hash}`,
}, { uType: 'mod' });
-};
+
+ return true;
+}
// module hook functions
-exports.initHooks = (server) => {
+export function initHooks(server) {
server.registerHook('in', 'chat', this.chatCheck, 25);
server.registerHook('in', 'invite', this.inviteCheck, 25);
// TODO: add whisper hook, need hook priorities todo finished first
-};
+}
// hook incoming chat commands, shadow-prevent chat if they are muzzled
-exports.chatCheck = (core, server, socket, payload) => {
+export function chatCheck(core, server, socket, payload) {
if (typeof payload.text !== 'string') {
return false;
}
- if(core.muzzledHashes[socket.hash]){
+ if (core.muzzledHashes[socket.hash]) {
// build fake chat payload
- mutedPayload = {
+ const mutedPayload = {
cmd: 'chat',
nick: socket.nick,
- text: payload.text
+ text: payload.text,
};
if (socket.trip) {
@@ -85,50 +87,59 @@ exports.chatCheck = (core, server, socket, payload) => {
}
// broadcast to any duplicate connections in channel
- server.broadcast( mutedPayload, { channel: socket.channel, hash: socket.hash });
+ server.broadcast(mutedPayload, { channel: socket.channel, hash: socket.hash });
// broadcast to allies, if any
- if(core.muzzledHashes[socket.hash].allies){
- server.broadcast( mutedPayload, { channel: socket.channel, nick: core.muzzledHashes[socket.hash].allies });
+ if (core.muzzledHashes[socket.hash].allies) {
+ server.broadcast(
+ mutedPayload,
+ {
+ channel: socket.channel,
+ nick: core.muzzledHashes[socket.hash].allies,
+ },
+ );
}
- // blanket "spam" protection, may expose the ratelimiting lines from `chat` and use that, TODO: one day #lazydev
- server.police.frisk(socket.remoteAddress, 9);
+ /**
+ * Blanket "spam" protection.
+ * May expose the ratelimiting lines from `chat` and use that
+ * @todo one day #lazydev
+ */
+ server.police.frisk(socket.address, 9);
return false;
}
return payload;
-};
+}
// shadow-prevent all invites from muzzled users
-exports.inviteCheck = (core, server, socket, payload) => {
+export function inviteCheck(core, server, socket, payload) {
if (typeof payload.nick !== 'string') {
return false;
}
- if(core.muzzledHashes[socket.hash]){
+ if (core.muzzledHashes[socket.hash]) {
// generate common channel
- let channel = Math.random().toString(36).substr(2, 8);
+ const channel = Math.random().toString(36).substr(2, 8);
// send fake reply
server.reply({
cmd: 'info',
- text: `You invited ${payload.nick} to ?${channel}`
+ text: `You invited ${payload.nick} to ?${channel}`,
}, socket);
return false;
}
return payload;
-};
+}
-// module meta
-exports.requiredData = ['nick'];
-exports.info = {
+export const requiredData = ['nick'];
+export const info = {
name: 'dumb',
description: 'Globally shadow mute a connection. Optional allies array will see muted messages.',
usage: `
- API: { cmd: 'dumb', nick: '<target nick>', allies: ['<optional nick array>', ...] }`
+ API: { cmd: 'dumb', nick: '<target nick>', allies: ['<optional nick array>', ...] }`,
};
-exports.info.aliases = ['muzzle', 'mute'];
+info.aliases = ['muzzle', 'mute'];
diff --git a/server/src/commands/mod/kick.js b/server/src/commands/mod/kick.js
index f3bc7ca..cb01d5c 100644
--- a/server/src/commands/mod/kick.js
+++ b/server/src/commands/mod/kick.js
@@ -3,37 +3,37 @@
*/
// module main
-exports.run = async (core, server, socket, data) => {
+export async function run(core, server, socket, data) {
// increase rate limit chance and ignore if not admin or mod
if (socket.uType === 'user') {
- return server.police.frisk(socket.remoteAddress, 10);
+ return server.police.frisk(socket.address, 10);
}
// check user input
if (typeof data.nick !== 'string') {
if (typeof data.nick !== 'object' && !Array.isArray(data.nick)) {
- return;
+ return true;
}
}
// find target user(s)
- let badClients = server.findSockets({ channel: socket.channel, nick: data.nick });
+ const badClients = server.findSockets({ channel: socket.channel, nick: data.nick });
if (badClients.length === 0) {
return server.reply({
cmd: 'warn',
- text: 'Could not find user(s) in channel'
+ text: 'Could not find user(s) in channel',
}, socket);
}
// check if found targets are kickable, commit kick
let newChannel = '';
- let kicked = [];
- for (let i = 0, j = badClients.length; i < j; i++) {
+ const kicked = [];
+ for (let i = 0, j = badClients.length; i < j; i += 1) {
if (badClients[i].uType !== 'user') {
server.reply({
cmd: 'warn',
- text: 'Cannot kick other mods, how rude'
+ text: 'Cannot kick other mods, how rude',
}, socket);
} else {
newChannel = Math.random().toString(36).substr(2, 8);
@@ -42,7 +42,7 @@ exports.run = async (core, server, socket, data) => {
// inform mods with where they were sent
server.broadcast({
cmd: 'info',
- text: `${badClients[i].nick} was banished to ?${newChannel}`
+ text: `${badClients[i].nick} was banished to ?${newChannel}`,
}, { channel: socket.channel, uType: 'mod' });
kicked.push(badClients[i].nick);
@@ -51,32 +51,33 @@ exports.run = async (core, server, socket, data) => {
}
if (kicked.length === 0) {
- return;
+ return true;
}
// broadcast client leave event
- for (let i = 0, j = kicked.length; i < j; i++) {
+ for (let i = 0, j = kicked.length; i < j; i += 1) {
server.broadcast({
cmd: 'onlineRemove',
- nick: kicked[i]
+ nick: kicked[i],
}, { channel: socket.channel });
}
// publicly broadcast kick event
server.broadcast({
cmd: 'info',
- text: `Kicked ${kicked.join(', ')}`
+ text: `Kicked ${kicked.join(', ')}`,
}, { channel: socket.channel, uType: 'user' });
// stats are fun
core.stats.increment('users-kicked', kicked.length);
-};
-// module meta
-exports.requiredData = ['nick'];
-exports.info = {
+ return true;
+}
+
+export const requiredData = ['nick'];
+export const info = {
name: 'kick',
description: 'Silently forces target client(s) into another channel. `nick` may be string or array of strings',
usage: `
- API: { cmd: 'kick', nick: '<target nick>' }`
+ API: { cmd: 'kick', nick: '<target nick>' }`,
};
diff --git a/server/src/commands/mod/moveuser.js b/server/src/commands/mod/moveuser.js
index c7fc4bf..b55c207 100644
--- a/server/src/commands/mod/moveuser.js
+++ b/server/src/commands/mod/moveuser.js
@@ -3,79 +3,79 @@
*/
// module main
-exports.run = async (core, server, socket, data) => {
+export async function run(core, server, socket, data) {
// increase rate limit chance and ignore if not admin or mod
if (socket.uType === 'user') {
- return server.police.frisk(socket.remoteAddress, 10);
+ return server.police.frisk(socket.address, 10);
}
// check user input
if (typeof data.nick !== 'string' || typeof data.channel !== 'string') {
- return;
+ return true;
}
if (data.channel === socket.channel) {
// moving them into the same channel? y u do this?
- return;
+ return true;
}
- let badClients = server.findSockets({ channel: socket.channel, nick: data.nick });
+ const badClients = server.findSockets({ channel: socket.channel, nick: data.nick });
if (badClients.length === 0) {
return server.reply({
cmd: 'warn',
- text: 'Could not find user in channel'
+ text: 'Could not find user in channel',
}, socket);
}
- let badClient = badClients[0];
+ const badClient = badClients[0];
if (badClient.uType !== 'user') {
return server.reply({
cmd: 'warn',
- text: 'Cannot move other mods, how rude'
+ text: 'Cannot move other mods, how rude',
}, socket);
}
const currentNick = badClient.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;
}
- 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,
}, badClient);
- if (badClient.nick !== peerList[i].nick){
+ if (badClient.nick !== peerList[i].nick) {
server.reply({
cmd: 'onlineRemove',
- nick: badClient.nick
+ nick: badClient.nick,
}, peerList[i]);
}
}
}
- let newPeerList = server.findSockets({ channel: data.channel });
- let moveAnnouncement = {
+ const newPeerList = server.findSockets({ channel: data.channel });
+ const moveAnnouncement = {
cmd: 'onlineAdd',
nick: badClient.nick,
trip: badClient.trip || 'null',
- hash: server.getSocketHash(badClient)
+ hash: server.getSocketHash(badClient),
};
- 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);
}
@@ -84,22 +84,23 @@ exports.run = async (core, server, socket, data) => {
server.reply({
cmd: 'onlineSet',
- nicks: nicks
+ nicks,
}, badClient);
badClient.channel = data.channel;
- server.broadcast( {
+ server.broadcast({
cmd: 'info',
- text: `${badClient.nick} was moved into ?${data.channel}`
+ text: `${badClient.nick} was moved into ?${data.channel}`,
}, { channel: data.channel });
-};
-// module meta
-exports.requiredData = ['nick', 'channel'];
-exports.info = {
+ return true;
+}
+
+export const requiredData = ['nick', 'channel'];
+export const info = {
name: 'moveuser',
description: 'This will move the target user nick into another channel',
usage: `
- API: { cmd: 'moveuser', nick: '<target nick>', channel: '<new channel>' }`
+ API: { cmd: 'moveuser', nick: '<target nick>', channel: '<new channel>' }`,
};
diff --git a/server/src/commands/mod/speak.js b/server/src/commands/mod/speak.js
index 23fc4de..5514545 100644
--- a/server/src/commands/mod/speak.js
+++ b/server/src/commands/mod/speak.js
@@ -3,32 +3,32 @@
* Author: simple
*/
- // module constructor
- exports.init = (core) => {
- if (typeof core.muzzledHashes === 'undefined') {
- core.muzzledHashes = {};
- }
- };
+// module constructor
+export function init(core) {
+ if (typeof core.muzzledHashes === 'undefined') {
+ core.muzzledHashes = {};
+ }
+}
// module main
-exports.run = async (core, server, socket, data) => {
+export async function run(core, server, socket, data) {
// increase rate limit chance and ignore if not admin or mod
if (socket.uType === 'user') {
- return server.police.frisk(socket.remoteAddress, 10);
+ return server.police.frisk(socket.address, 10);
}
// check user input
if (typeof data.ip !== 'string' && typeof data.hash !== 'string') {
return server.reply({
cmd: 'warn',
- text: "hash:'targethash' or ip:'1.2.3.4' is required"
+ text: "hash:'targethash' or ip:'1.2.3.4' is required",
}, socket);
}
// find target & remove mute status
let target;
if (typeof data.ip === 'string') {
- target = getSocketHash(data.ip);
+ target = server.getSocketHash(data.ip);
} else {
target = data.hash;
}
@@ -38,15 +38,16 @@ exports.run = async (core, server, socket, data) => {
// notify mods
server.broadcast({
cmd: 'info',
- text: `${socket.nick} unmuzzled : ${target}`
+ text: `${socket.nick} unmuzzled : ${target}`,
}, { uType: 'mod' });
-};
-// module meta
-exports.info = {
+ return true;
+}
+
+export const info = {
name: 'speak',
description: 'Pardon a dumb user to be able to speak again',
usage: `
- API: { cmd: 'speak', ip/hash: '<target ip or hash' }`
+ API: { cmd: 'speak', ip/hash: '<target ip or hash' }`,
};
-exports.info.aliases = ['unmuzzle', 'unmute'];
+info.aliases = ['unmuzzle', 'unmute'];
diff --git a/server/src/commands/mod/unban.js b/server/src/commands/mod/unban.js
index 6744d9d..0d1e469 100644
--- a/server/src/commands/mod/unban.js
+++ b/server/src/commands/mod/unban.js
@@ -3,22 +3,23 @@
*/
// module main
-exports.run = async (core, server, socket, data) => {
+export async function run(core, server, socket, data) {
// increase rate limit chance and ignore if not admin or mod
if (socket.uType === 'user') {
- return server.police.frisk(socket.remoteAddress, 10);
+ return server.police.frisk(socket.address, 10);
}
// check user input
if (typeof data.ip !== 'string' && typeof data.hash !== 'string') {
return server.reply({
cmd: 'warn',
- text: "hash:'targethash' or ip:'1.2.3.4' is required"
+ text: "hash:'targethash' or ip:'1.2.3.4' is required",
}, socket);
}
// find target
- let mode, target;
+ let mode; let
+ target;
if (typeof data.ip === 'string') {
mode = 'ip';
target = data.ip;
@@ -39,23 +40,24 @@ exports.run = async (core, server, socket, data) => {
// reply with success
server.reply({
cmd: 'info',
- text: `Unbanned ${target}`
+ text: `Unbanned ${target}`,
}, socket);
// notify mods
server.broadcast({
cmd: 'info',
- text: `${socket.nick} unbanned: ${target}`
+ text: `${socket.nick} unbanned: ${target}`,
}, { uType: 'mod' });
// stats are fun
core.stats.decrement('users-banned');
-};
-// module meta
-exports.info = {
+ return true;
+}
+
+export const info = {
name: 'unban',
description: 'Removes target ip from the ratelimiter',
usage: `
- API: { cmd: 'unban', ip/hash: '<target ip or hash>' }`
+ API: { cmd: 'unban', ip/hash: '<target ip or hash>' }`,
};
diff --git a/server/src/commands/mod/unbanall.js b/server/src/commands/mod/unbanall.js
index c285b80..49eeee5 100644
--- a/server/src/commands/mod/unbanall.js
+++ b/server/src/commands/mod/unbanall.js
@@ -3,34 +3,35 @@
*/
// module main
-exports.run = async (core, server, socket, data) => {
+export async function run(core, server, socket) {
// increase rate limit chance and ignore if not admin or mod
if (socket.uType === 'user') {
- return server.police.frisk(socket.remoteAddress, 10);
+ return server.police.frisk(socket.address, 10);
}
// remove arrest records
- server.police.records = {};
+ server.police.clear();
console.log(`${socket.nick} [${socket.trip}] unbanned all`);
// reply with success
server.reply({
cmd: 'info',
- text: `Unbanned all ip addresses`
+ text: 'Unbanned all ip addresses',
}, socket);
// notify mods
server.broadcast({
cmd: 'info',
- text: `${socket.nick} unbanned all ip addresses`
+ text: `${socket.nick} unbanned all ip addresses`,
}, { uType: 'mod' });
-};
-// module meta
-exports.info = {
+ return true;
+}
+
+export const info = {
name: 'unbanall',
description: 'Clears all banned ip addresses',
usage: `
- API: { cmd: 'unbanall' }`
+ API: { cmd: 'unbanall' }`,
};