From 7e7bc2a404f8ac1fb2b8eb3a20b4b219c878c14f Mon Sep 17 00:00:00 2001 From: Matthew R Date: Sat, 27 Jun 2020 23:51:15 -0400 Subject: [PATCH 1/4] add express version to info cmd --- src/commands/info.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/commands/info.ts b/src/commands/info.ts index 278c9f9..0015822 100644 --- a/src/commands/info.ts +++ b/src/commands/info.ts @@ -2,6 +2,7 @@ import { Message } from 'eris'; import { totalmem } from 'os'; import { Client, Command, RichEmbed } from '../class'; import { version as erisVersion } from '../../node_modules/eris/package.json'; +import { version as expressVersion } from '../../node_modules/express/package.json'; import { version as mongooseVersion } from '../../node_modules/mongoose/package.json'; export default class Info extends Command { @@ -21,6 +22,7 @@ export default class Info extends Command { embed.setThumbnail(this.client.user.avatarURL); embed.addField('Language(s)', '<:TypeScript:703451285789343774> TypeScript', true); embed.addField('Discord Library', `Eris (${erisVersion})`, true); + embed.addField('HTTP Server Library', `Express (${expressVersion})`, true); embed.addField('Database Library', `MongoDB w/ Mongoose ODM (${mongooseVersion})`, true); embed.addField('Repository', 'https://gitlab.libraryofcode.org/engineering/communityrelations | Licensed under GNU Affero General Public License V3', true); embed.addField('Memory Usage', `${Math.round(process.memoryUsage().rss / 1024 / 1024)} MB / ${Math.round(totalmem() / 1024 / 1024 / 1024)} GB`, true); From 74009f649948633c3c976485a6849cb5252d74e9 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Sat, 27 Jun 2020 23:51:36 -0400 Subject: [PATCH 2/4] fix issue where page logs for email are showing up as [DISCORD] --- src/commands/page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/page.ts b/src/commands/page.ts index c7e3388..6f65c8d 100644 --- a/src/commands/page.ts +++ b/src/commands/page.ts @@ -133,7 +133,7 @@ export default class Page extends Command { const recipient = this.client.guilds.get(this.client.config.guildID).members.get(recipientEntry.individualAssignID); const sender = this.client.guilds.get(this.client.config.guildID).members.get(senderEntry.individualAssignID); if (!recipient || !sender) { - this.logPage({ number: senderNumber, user: 'N/A' }, { number: recipientNumber, user: 'N/A' }, 'discord', code); + this.logPage({ number: senderNumber, user: 'N/A' }, { number: recipientNumber, user: 'N/A' }, 'email', code); } else { this.logPage({ number: senderNumber, user: `${sender.username}#${sender.discriminator}` }, { number: recipientNumber, user: `${recipient.username}#${recipient.discriminator}` }, 'email', code); } From e1fcb15747fb6b2c855b3822ff36762cab7a20ff Mon Sep 17 00:00:00 2001 From: Matthew R Date: Sat, 27 Jun 2020 23:51:47 -0400 Subject: [PATCH 3/4] remove unneeded comments from whois cmd --- src/commands/whois.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/commands/whois.ts b/src/commands/whois.ts index 60d9cf6..b4ee0cf 100644 --- a/src/commands/whois.ts +++ b/src/commands/whois.ts @@ -29,15 +29,6 @@ export default class Whois extends Command { } const embed = new RichEmbed(); embed.setAuthor(`${member.user.username}#${member.user.discriminator}`, member.user.avatarURL); - /* if (member.roles.includes('453689940140883988')) { - embed.setThumbnail('https://static.libraryofcode.org/library_of_code_associate-badge.png'); - } else if (member.roles.includes('455972169449734144')) { - embed.setThumbnail('https://static.libraryofcode.org/library_of_code_sheriff-badge.png'); - } else if (member.roles.includes('662163685439045632')) { - embed.setThumbnail('https://static.libraryofcode.org/library_of_code_marshal-badge.png'); - } else { - embed.setThumbnail(member.avatarURL); - } */ embed.setThumbnail(member.avatarURL); const ackResolve = this.resolveStaffInformation(member.id); let description = ''; From e39ebfd140968148da52ae65a27c757c91af49b2 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Sun, 5 Jul 2020 14:42:38 -0400 Subject: [PATCH 4/4] changes --- src/commands/additem.ts | 120 +++++------ src/commands/addredirect.ts | 76 +++---- src/commands/ban.ts | 106 ++++----- src/commands/delitem.ts | 92 ++++---- src/commands/delredirect.ts | 52 ++--- src/commands/djs.ts | 74 +++---- src/commands/eval.ts | 136 ++++++------ src/commands/game.ts | 128 +++++------ src/commands/help.ts | 230 ++++++++++---------- src/commands/index.ts | 36 ++-- src/commands/info.ts | 72 +++---- src/commands/kick.ts | 74 +++---- src/commands/listredirects.ts | 104 ++++----- src/commands/npm.ts | 128 +++++------ src/commands/page.ts | 307 +++++++++++++------------- src/commands/ping.ts | 46 ++-- src/commands/roleinfo.ts | 120 +++++------ src/commands/unban.ts | 74 +++---- src/commands/whois.ts | 394 +++++++++++++++++----------------- 19 files changed, 1185 insertions(+), 1184 deletions(-) diff --git a/src/commands/additem.ts b/src/commands/additem.ts index d487a70..109ada1 100644 --- a/src/commands/additem.ts +++ b/src/commands/additem.ts @@ -1,60 +1,60 @@ -import { Message } from 'eris'; -import { Client, Command, RichEmbed } from '../class'; - -export default class AddItem extends Command { - constructor(client: Client) { - super(client); - this.name = 'additem'; - this.description = 'Adds information to your whois embed.'; - this.usage = 'additem [code]'; - this.permissions = 0; - this.enabled = true; - } - - public async run(message: Message, args: string[]) { - try { - if (args.length < 1) { - const embed = new RichEmbed(); - embed.setTitle('Whois Data Codes'); - embed.addField('Languages', '**Assembly Language:** lang-asm\n**C/C++:** lang-cfam\n**C#:** lang-csharp\n**Go:** lang-go\n**Java:** lang-java\n**JavaScript:** lang-js\n**Kotlin:** lang-kt\n**Python:** lang-py\n**Ruby:** lang-rb\n**Rust:** lang-rs\n**Swift:** lang-swift\n**TypeScript:** lang-ts'); - embed.addField('Operating Systems', '**Arch:** os-arch\n**Debian:** os-deb\n**CentOS:** os-cent\n**Fedora:** os-fedora\n**macOS:** os-mdarwin\n**Manjaro:** os-manjaro\n**RedHat:** os-redhat\n**Ubuntu:** os-ubuntu\n**Windows:** os-win'); - embed.setFooter(this.client.user.username, this.client.user.avatarURL); - embed.setTimestamp(); - return message.channel.createMessage({ embed }); - } - if (args[0].split('-')[0] === 'os' && ['arch', 'deb', 'cent', 'fedora', 'manjaro', 'mdarwin', 'redhat', 'ubuntu', 'win'].includes(args[0].split('-')[1])) { - const account = await this.client.db.Member.findOne({ userID: message.member.id }); - if (!account) { - const newAccount = new this.client.db.Member({ - userID: message.member.id, - additional: { - operatingSystems: [args[0].split('-')[1]], - }, - }); - await newAccount.save(); - } else { - await account.updateOne({ $addToSet: { 'additional.operatingSystems': args[0].split('-')[1] } }); - } - return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Added OS code ${args[0]} to profile.***`); - } - if (args[0].split('-')[0] === 'lang' && ['js', 'py', 'rb', 'ts', 'rs', 'go', 'cfam', 'csharp', 'swift', 'java', 'kt', 'asm'].includes(args[0].split('-')[1])) { - const account = await this.client.db.Member.findOne({ userID: message.member.id }); - if (!account) { - const newAccount = new this.client.db.Member({ - userID: message.member.id, - additional: { - langs: [args[0].split('-')[1]], - }, - }); - await newAccount.save(); - } else { - await account.updateOne({ $addToSet: { 'additional.langs': args[0].split('-')[1] } }); - } - return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Added language code ${args[0]} to profile.***`); - } - return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Invalid data code.***`); - } catch (err) { - return this.client.util.handleError(err, message, this); - } - } -} +import { Message } from 'eris'; +import { Client, Command, RichEmbed } from '../class'; + +export default class AddItem extends Command { + constructor(client: Client) { + super(client); + this.name = 'additem'; + this.description = 'Adds information to your whois embed.'; + this.usage = 'additem [code]'; + this.permissions = 0; + this.enabled = true; + } + + public async run(message: Message, args: string[]) { + try { + if (args.length < 1) { + const embed = new RichEmbed(); + embed.setTitle('Whois Data Codes'); + embed.addField('Languages', '**Assembly Language:** lang-asm\n**C/C++:** lang-cfam\n**C#:** lang-csharp\n**Go:** lang-go\n**Java:** lang-java\n**JavaScript:** lang-js\n**Kotlin:** lang-kt\n**Python:** lang-py\n**Ruby:** lang-rb\n**Rust:** lang-rs\n**Swift:** lang-swift\n**TypeScript:** lang-ts'); + embed.addField('Operating Systems', '**Arch:** os-arch\n**Debian:** os-deb\n**CentOS:** os-cent\n**Fedora:** os-fedora\n**macOS:** os-mdarwin\n**Manjaro:** os-manjaro\n**RedHat:** os-redhat\n**Ubuntu:** os-ubuntu\n**Windows:** os-win'); + embed.setFooter(this.client.user.username, this.client.user.avatarURL); + embed.setTimestamp(); + return message.channel.createMessage({ embed }); + } + if (args[0].split('-')[0] === 'os' && ['arch', 'deb', 'cent', 'fedora', 'manjaro', 'mdarwin', 'redhat', 'ubuntu', 'win'].includes(args[0].split('-')[1])) { + const account = await this.client.db.Member.findOne({ userID: message.member.id }); + if (!account) { + const newAccount = new this.client.db.Member({ + userID: message.member.id, + additional: { + operatingSystems: [args[0].split('-')[1]], + }, + }); + await newAccount.save(); + } else { + await account.updateOne({ $addToSet: { 'additional.operatingSystems': args[0].split('-')[1] } }); + } + return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Added OS code ${args[0]} to profile.***`); + } + if (args[0].split('-')[0] === 'lang' && ['js', 'py', 'rb', 'ts', 'rs', 'go', 'cfam', 'csharp', 'swift', 'java', 'kt', 'asm'].includes(args[0].split('-')[1])) { + const account = await this.client.db.Member.findOne({ userID: message.member.id }); + if (!account) { + const newAccount = new this.client.db.Member({ + userID: message.member.id, + additional: { + langs: [args[0].split('-')[1]], + }, + }); + await newAccount.save(); + } else { + await account.updateOne({ $addToSet: { 'additional.langs': args[0].split('-')[1] } }); + } + return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Added language code ${args[0]} to profile.***`); + } + return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Invalid data code.***`); + } catch (err) { + return this.client.util.handleError(err, message, this); + } + } +} diff --git a/src/commands/addredirect.ts b/src/commands/addredirect.ts index ad5956e..98a5da5 100644 --- a/src/commands/addredirect.ts +++ b/src/commands/addredirect.ts @@ -1,38 +1,38 @@ -import { Message } from 'eris'; -import { Client, Command } from '../class'; - -export default class AddRedirect extends Command { - constructor(client: Client) { - super(client); - this.name = 'addredirect'; - this.description = 'Adds a redirect link for \'loc.sh\''; - this.usage = 'addredirect '; - this.aliases = ['ar']; - this.permissions = 6; - this.enabled = true; - } - - public async run(message: Message, args: string[]) { - try { - if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); - const check = await this.client.db.Redirect.findOne({ key: args[1].toLowerCase() }); - if (check) return this.error(message.channel, `Redirect key ${args[1].toLowerCase()} already exists. Linked to: ${check.to}`); - try { - const test = new URL(args[0]); - if (test.protocol !== 'https:') return this.error(message.channel, 'Protocol must be HTTPS.'); - } catch { - return this.error(message.channel, 'This doesn\'t appear to be a valid URL.'); - } - if ((/^[a-zA-Z0-9]+$/gi.test(args[1].toLowerCase().replace('-', '').trim()) === false) || args[1].toLowerCase().length > 15) return this.error(message.channel, 'Invalid key. The key must be alphanumeric and less than 16 characters.'); - const redirect = new this.client.db.Redirect({ - key: args[1].toLowerCase(), - to: args[0], - visitedCount: 0, - }); - await redirect.save(); - return this.success(message.channel, `Redirect https://loc.sh/${args[1].toLowerCase()} -> ${args[0]} is now active.`); - } catch (err) { - return this.client.util.handleError(err, message, this); - } - } -} +import { Message } from 'eris'; +import { Client, Command } from '../class'; + +export default class AddRedirect extends Command { + constructor(client: Client) { + super(client); + this.name = 'addredirect'; + this.description = 'Adds a redirect link for \'loc.sh\''; + this.usage = 'addredirect '; + this.aliases = ['ar']; + this.permissions = 6; + this.enabled = true; + } + + public async run(message: Message, args: string[]) { + try { + if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); + const check = await this.client.db.Redirect.findOne({ key: args[1].toLowerCase() }); + if (check) return this.error(message.channel, `Redirect key ${args[1].toLowerCase()} already exists. Linked to: ${check.to}`); + try { + const test = new URL(args[0]); + if (test.protocol !== 'https:') return this.error(message.channel, 'Protocol must be HTTPS.'); + } catch { + return this.error(message.channel, 'This doesn\'t appear to be a valid URL.'); + } + if ((/^[a-zA-Z0-9]+$/gi.test(args[1].toLowerCase().replace('-', '').trim()) === false) || args[1].toLowerCase().length > 15) return this.error(message.channel, 'Invalid key. The key must be alphanumeric and less than 16 characters.'); + const redirect = new this.client.db.Redirect({ + key: args[1].toLowerCase(), + to: args[0], + visitedCount: 0, + }); + await redirect.save(); + return this.success(message.channel, `Redirect https://loc.sh/${args[1].toLowerCase()} -> ${args[0]} is now active.`); + } catch (err) { + return this.client.util.handleError(err, message, this); + } + } +} diff --git a/src/commands/ban.ts b/src/commands/ban.ts index 87c93c3..160eeec 100644 --- a/src/commands/ban.ts +++ b/src/commands/ban.ts @@ -1,53 +1,53 @@ -import moment, { unitOfTime } from 'moment'; -import { Message, User, GuildTextableChannel } from 'eris'; -import { Client, Command } from '../class'; - -export default class Ban extends Command { - constructor(client: Client) { - super(client); - this.name = 'ban'; - this.description = 'Bans a member from the guild.'; - this.usage = 'ban [time] [reason]'; - this.permissions = 3; - this.guildOnly = true; - this.enabled = true; - } - - public async run(message: Message, args: string[]) { - try { - if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); - const member = this.client.util.resolveMember(args[0], message.guild); - let user: User; - if (!member) { - try { - user = await this.client.getRESTUser(args[0]); - } catch { - return this.error(message.channel, 'Cannot find user.'); - } - } else { - user = member.user; - } - try { - await message.guild.getBan(args[0]); - return this.error(message.channel, 'This user is already banned.'); - } catch {} // eslint-disable-line no-empty - if (member && !this.client.util.moderation.checkPermissions(member, message.member)) return this.error(message.channel, 'Permission Denied.'); - message.delete(); - - let momentMilliseconds: number; - let reason: string; - if (args.length > 1) { - const lockLength = args[1].match(/[a-z]+|[^a-z]+/gi); - const length = Number(lockLength[0]); - const unit = lockLength[1] as unitOfTime.Base; - momentMilliseconds = moment.duration(length, unit).asMilliseconds(); - reason = momentMilliseconds ? args.slice(2).join(' ') : args.slice(1).join(' '); - if (reason.length > 512) return this.error(message.channel, 'Ban reasons cannot be longer than 512 characters.'); - } - await this.client.util.moderation.ban(user, message.member, momentMilliseconds, reason); - return this.success(message.channel, `${user.username}#${user.discriminator} has been banned.`); - } catch (err) { - return this.client.util.handleError(err, message, this, false); - } - } -} +import moment, { unitOfTime } from 'moment'; +import { Message, User, GuildTextableChannel } from 'eris'; +import { Client, Command } from '../class'; + +export default class Ban extends Command { + constructor(client: Client) { + super(client); + this.name = 'ban'; + this.description = 'Bans a member from the guild.'; + this.usage = 'ban [time] [reason]'; + this.permissions = 3; + this.guildOnly = true; + this.enabled = true; + } + + public async run(message: Message, args: string[]) { + try { + if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); + const member = this.client.util.resolveMember(args[0], message.guild); + let user: User; + if (!member) { + try { + user = await this.client.getRESTUser(args[0]); + } catch { + return this.error(message.channel, 'Cannot find user.'); + } + } else { + user = member.user; + } + try { + await message.guild.getBan(args[0]); + return this.error(message.channel, 'This user is already banned.'); + } catch {} // eslint-disable-line no-empty + if (member && !this.client.util.moderation.checkPermissions(member, message.member)) return this.error(message.channel, 'Permission Denied.'); + message.delete(); + + let momentMilliseconds: number; + let reason: string; + if (args.length > 1) { + const lockLength = args[1].match(/[a-z]+|[^a-z]+/gi); + const length = Number(lockLength[0]); + const unit = lockLength[1] as unitOfTime.Base; + momentMilliseconds = moment.duration(length, unit).asMilliseconds(); + reason = momentMilliseconds ? args.slice(2).join(' ') : args.slice(1).join(' '); + if (reason.length > 512) return this.error(message.channel, 'Ban reasons cannot be longer than 512 characters.'); + } + await this.client.util.moderation.ban(user, message.member, momentMilliseconds, reason); + return this.success(message.channel, `${user.username}#${user.discriminator} has been banned.`); + } catch (err) { + return this.client.util.handleError(err, message, this, false); + } + } +} diff --git a/src/commands/delitem.ts b/src/commands/delitem.ts index 164a3af..2500f2f 100644 --- a/src/commands/delitem.ts +++ b/src/commands/delitem.ts @@ -1,46 +1,46 @@ -import { Message } from 'eris'; -import { Client, Command, RichEmbed } from '../class'; - -export default class DelItem extends Command { - constructor(client: Client) { - super(client); - this.name = 'delitem'; - this.description = 'Removes information to your whois embed.'; - this.usage = 'delitem [code]'; - this.permissions = 0; - this.enabled = true; - } - - public async run(message: Message, args: string[]) { - try { - if (args.length < 1) { - const embed = new RichEmbed(); - embed.setTitle('Whois Data Codes'); - embed.addField('Languages', '**Assembly Language:** lang-asm\n**C/C++:** lang-cfam\n**C#:** lang-csharp\n**Go:** lang-go\n**Java:** lang-java\n**JavaScript:** lang-js\n**Kotlin:** lang-kt\n**Python:** lang-py\n**Ruby:** lang-rb\n**Rust:** lang-rs\n**Swift:** lang-swift\n**TypeScript:** lang-ts'); - embed.addField('Operating Systems', '**Arch:** os-arch\n**Debian:** os-deb\n**CentOS:** os-cent\n**Fedora:** os-fedora\n**macOS:** os-mdarwin\n**Manjaro:** os-manjaro\n**RedHat:** os-redhat\n**Ubuntu:** os-ubuntu\n**Windows:** os-win'); - embed.setFooter(this.client.user.username, this.client.user.avatarURL); - embed.setTimestamp(); - return message.channel.createMessage({ embed }); - } - if (args[0].split('-')[0] === 'os' && ['arch', 'deb', 'cent', 'fedora', 'manjaro', 'mdarwin', 'redhat', 'ubuntu', 'win'].includes(args[0].split('-')[1])) { - const account = await this.client.db.Member.findOne({ userID: message.member.id }); - if (account?.additional.operatingSystems.length < 1) { - return message.channel.createMessage(`***${this.client.util.emojis.ERROR} You don't have any operating systems to remove.***`); - } - await account.updateOne({ $pull: { 'additional.operatingSystems': args[0].split('-')[1] } }); - return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Removed OS code ${args[0]} from profile.***`); - } - if (args[0].split('-')[0] === 'lang' && ['js', 'py', 'rb', 'ts', 'rs', 'go', 'cfam', 'csharp', 'swift', 'java', 'kt', 'asm'].includes(args[0].split('-')[1])) { - const account = await this.client.db.Member.findOne({ userID: message.member.id }); - if (account?.additional.langs.length < 1) { - return message.channel.createMessage(`***${this.client.util.emojis.ERROR} You don't have any languages to remove.***`); - } - await account.updateOne({ $pull: { 'additional.langs': args[0].split('-')[1] } }); - return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Removed language code ${args[0]} from profile.***`); - } - return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Invalid data code.***`); - } catch (err) { - return this.client.util.handleError(err, message, this); - } - } -} +import { Message } from 'eris'; +import { Client, Command, RichEmbed } from '../class'; + +export default class DelItem extends Command { + constructor(client: Client) { + super(client); + this.name = 'delitem'; + this.description = 'Removes information to your whois embed.'; + this.usage = 'delitem [code]'; + this.permissions = 0; + this.enabled = true; + } + + public async run(message: Message, args: string[]) { + try { + if (args.length < 1) { + const embed = new RichEmbed(); + embed.setTitle('Whois Data Codes'); + embed.addField('Languages', '**Assembly Language:** lang-asm\n**C/C++:** lang-cfam\n**C#:** lang-csharp\n**Go:** lang-go\n**Java:** lang-java\n**JavaScript:** lang-js\n**Kotlin:** lang-kt\n**Python:** lang-py\n**Ruby:** lang-rb\n**Rust:** lang-rs\n**Swift:** lang-swift\n**TypeScript:** lang-ts'); + embed.addField('Operating Systems', '**Arch:** os-arch\n**Debian:** os-deb\n**CentOS:** os-cent\n**Fedora:** os-fedora\n**macOS:** os-mdarwin\n**Manjaro:** os-manjaro\n**RedHat:** os-redhat\n**Ubuntu:** os-ubuntu\n**Windows:** os-win'); + embed.setFooter(this.client.user.username, this.client.user.avatarURL); + embed.setTimestamp(); + return message.channel.createMessage({ embed }); + } + if (args[0].split('-')[0] === 'os' && ['arch', 'deb', 'cent', 'fedora', 'manjaro', 'mdarwin', 'redhat', 'ubuntu', 'win'].includes(args[0].split('-')[1])) { + const account = await this.client.db.Member.findOne({ userID: message.member.id }); + if (account?.additional.operatingSystems.length < 1) { + return message.channel.createMessage(`***${this.client.util.emojis.ERROR} You don't have any operating systems to remove.***`); + } + await account.updateOne({ $pull: { 'additional.operatingSystems': args[0].split('-')[1] } }); + return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Removed OS code ${args[0]} from profile.***`); + } + if (args[0].split('-')[0] === 'lang' && ['js', 'py', 'rb', 'ts', 'rs', 'go', 'cfam', 'csharp', 'swift', 'java', 'kt', 'asm'].includes(args[0].split('-')[1])) { + const account = await this.client.db.Member.findOne({ userID: message.member.id }); + if (account?.additional.langs.length < 1) { + return message.channel.createMessage(`***${this.client.util.emojis.ERROR} You don't have any languages to remove.***`); + } + await account.updateOne({ $pull: { 'additional.langs': args[0].split('-')[1] } }); + return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Removed language code ${args[0]} from profile.***`); + } + return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Invalid data code.***`); + } catch (err) { + return this.client.util.handleError(err, message, this); + } + } +} diff --git a/src/commands/delredirect.ts b/src/commands/delredirect.ts index 1dd8ae9..669da97 100644 --- a/src/commands/delredirect.ts +++ b/src/commands/delredirect.ts @@ -1,26 +1,26 @@ -import { Message } from 'eris'; -import { Client, Command } from '../class'; - -export default class DelRedirect extends Command { - constructor(client: Client) { - super(client); - this.name = 'delredirect'; - this.description = 'Delete a redirect link for \'loc.sh\''; - this.usage = 'delredirect '; - this.aliases = ['dr']; - this.permissions = 6; - this.enabled = true; - } - - public async run(message: Message, args: string[]) { - try { - if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); - const check = await this.client.db.Redirect.findOne({ key: args[0].toLowerCase() }); - if (!check) return this.error(message.channel, `Redirect key ${args[0].toLowerCase()} doesn't exist.`); - await this.client.db.Redirect.deleteOne({ key: args[0].toLowerCase() }); - return this.success(message.channel, `Deleted redirect https://loc.sh/${args[0].toLowerCase()}.`); - } catch (err) { - return this.client.util.handleError(err, message, this); - } - } -} +import { Message } from 'eris'; +import { Client, Command } from '../class'; + +export default class DelRedirect extends Command { + constructor(client: Client) { + super(client); + this.name = 'delredirect'; + this.description = 'Delete a redirect link for \'loc.sh\''; + this.usage = 'delredirect '; + this.aliases = ['dr']; + this.permissions = 6; + this.enabled = true; + } + + public async run(message: Message, args: string[]) { + try { + if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); + const check = await this.client.db.Redirect.findOne({ key: args[0].toLowerCase() }); + if (!check) return this.error(message.channel, `Redirect key ${args[0].toLowerCase()} doesn't exist.`); + await this.client.db.Redirect.deleteOne({ key: args[0].toLowerCase() }); + return this.success(message.channel, `Deleted redirect https://loc.sh/${args[0].toLowerCase()}.`); + } catch (err) { + return this.client.util.handleError(err, message, this); + } + } +} diff --git a/src/commands/djs.ts b/src/commands/djs.ts index 405e0ac..a03f1b7 100644 --- a/src/commands/djs.ts +++ b/src/commands/djs.ts @@ -1,37 +1,37 @@ -import { Message, EmbedOptions } from 'eris'; -import axios, { AxiosResponse } from 'axios'; -import { Client, Command, RichEmbed } from '../class'; - -export default class DJS extends Command { - constructor(client: Client) { - super(client); - this.name = 'djs'; - this.description = 'Get information about Discord.js.'; - this.usage = 'djs '; - this.permissions = 0; - this.guildOnly = false; - this.enabled = true; - } - - public async run(message: Message, args: string[]) { - try { - if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); - - let res: AxiosResponse; - try { - res = await axios.get(`https://djsdocs.sorta.moe/v2/embed?src=master&q=${args[0]}`); - } catch (err) { - return this.error(message.channel, 'Please try again later, something unexpected happened.'); - } - - if (!res.data) return this.error(message.channel, 'Could not find information. Try something else.'); - - const embed = new RichEmbed(res.data); - embed.setFooter(this.client.user.username, this.client.user.avatarURL); - embed.setTimestamp(); - return message.channel.createMessage({ embed }); - } catch (err) { - return this.client.util.handleError(err, message, this); - } - } -} +import { Message, EmbedOptions } from 'eris'; +import axios, { AxiosResponse } from 'axios'; +import { Client, Command, RichEmbed } from '../class'; + +export default class DJS extends Command { + constructor(client: Client) { + super(client); + this.name = 'djs'; + this.description = 'Get information about Discord.js.'; + this.usage = 'djs '; + this.permissions = 0; + this.guildOnly = false; + this.enabled = true; + } + + public async run(message: Message, args: string[]) { + try { + if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); + + let res: AxiosResponse; + try { + res = await axios.get(`https://djsdocs.sorta.moe/v2/embed?src=master&q=${args[0]}`); + } catch (err) { + return this.error(message.channel, 'Please try again later, something unexpected happened.'); + } + + if (!res.data) return this.error(message.channel, 'Could not find information. Try something else.'); + + const embed = new RichEmbed(res.data); + embed.setFooter(this.client.user.username, this.client.user.avatarURL); + embed.setTimestamp(); + return message.channel.createMessage({ embed }); + } catch (err) { + return this.client.util.handleError(err, message, this); + } + } +} diff --git a/src/commands/eval.ts b/src/commands/eval.ts index e749d4d..2bfc068 100644 --- a/src/commands/eval.ts +++ b/src/commands/eval.ts @@ -1,68 +1,68 @@ -import axios from 'axios'; -import { inspect } from 'util'; -import { Message } from 'eris'; -import { Client, Command } from '../class'; - -export default class Eval extends Command { - constructor(client: Client) { - super(client); - this.name = 'eval'; - this.description = 'Evaluates native JS code'; - this.aliases = ['e']; - this.permissions = 7; - this.enabled = true; - this.guildOnly = false; - } - - public async run(message: Message, args: string[]) { - try { - const evalMessage = message.content.slice(this.client.config.prefix.length).trim().split(' ').slice(1); - let evalString = evalMessage.join(' ').trim(); - let evaled: any; - let depth = 0; - - if (args[0] && args[0].startsWith('-d')) { - depth = Number(args[0].replace('-d', '')); - if (!depth || depth < 0) depth = 0; - const index = evalMessage.findIndex((v) => v.startsWith('-d')) + 1; - evalString = evalMessage.slice(index).join(' ').trim(); - } - if (args[0] === '-a') { - const index = evalMessage.findIndex((v) => v === '-a') + 1; - evalString = `(async () => { ${evalMessage.slice(index).join(' ').trim()} })()`; - } - - try { - // eslint-disable-next-line no-eval - evaled = await eval(evalString); - if (typeof evaled !== 'string') { - evaled = inspect(evaled, { depth }); - } - if (evaled === undefined) { - evaled = 'undefined'; - } - } catch (error) { - evaled = error.stack; - } - - evaled = evaled.replace(new RegExp(this.client.config.token, 'gi'), 'juul'); - // evaled = evaled.replace(new RegExp(this.client.config.emailPass, 'gi'), 'juul'); - // evaled = evaled.replace(new RegExp(this.client.config.cloudflare, 'gi'), 'juul'); - - - const display = this.client.util.splitString(evaled, 1975); - if (display[5]) { - try { - const { data } = await axios.post('https://snippets.cloud.libraryofcode.org/documents', display.join('')); - return this.success(message.channel, `Your evaluation evaled can be found on https://snippets.cloud.libraryofcode.org/${data.key}`); - } catch (error) { - return this.error(message.channel, `${error}`); - } - } - - return display.forEach((m) => message.channel.createMessage(`\`\`\`js\n${m}\n\`\`\``)); - } catch (err) { - return this.client.util.handleError(err, message, this, false); - } - } -} +import axios from 'axios'; +import { inspect } from 'util'; +import { Message } from 'eris'; +import { Client, Command } from '../class'; + +export default class Eval extends Command { + constructor(client: Client) { + super(client); + this.name = 'eval'; + this.description = 'Evaluates native JS code'; + this.aliases = ['e']; + this.permissions = 7; + this.enabled = true; + this.guildOnly = false; + } + + public async run(message: Message, args: string[]) { + try { + const evalMessage = message.content.slice(this.client.config.prefix.length).trim().split(' ').slice(1); + let evalString = evalMessage.join(' ').trim(); + let evaled: any; + let depth = 0; + + if (args[0] && args[0].startsWith('-d')) { + depth = Number(args[0].replace('-d', '')); + if (!depth || depth < 0) depth = 0; + const index = evalMessage.findIndex((v) => v.startsWith('-d')) + 1; + evalString = evalMessage.slice(index).join(' ').trim(); + } + if (args[0] === '-a') { + const index = evalMessage.findIndex((v) => v === '-a') + 1; + evalString = `(async () => { ${evalMessage.slice(index).join(' ').trim()} })()`; + } + + try { + // eslint-disable-next-line no-eval + evaled = await eval(evalString); + if (typeof evaled !== 'string') { + evaled = inspect(evaled, { depth }); + } + if (evaled === undefined) { + evaled = 'undefined'; + } + } catch (error) { + evaled = error.stack; + } + + evaled = evaled.replace(new RegExp(this.client.config.token, 'gi'), 'juul'); + // evaled = evaled.replace(new RegExp(this.client.config.emailPass, 'gi'), 'juul'); + // evaled = evaled.replace(new RegExp(this.client.config.cloudflare, 'gi'), 'juul'); + + + const display = this.client.util.splitString(evaled, 1975); + if (display[5]) { + try { + const { data } = await axios.post('https://snippets.cloud.libraryofcode.org/documents', display.join('')); + return this.success(message.channel, `Your evaluation evaled can be found on https://snippets.cloud.libraryofcode.org/${data.key}`); + } catch (error) { + return this.error(message.channel, `${error}`); + } + } + + return display.forEach((m) => message.channel.createMessage(`\`\`\`js\n${m}\n\`\`\``)); + } catch (err) { + return this.client.util.handleError(err, message, this, false); + } + } +} diff --git a/src/commands/game.ts b/src/commands/game.ts index 382b640..075a7aa 100644 --- a/src/commands/game.ts +++ b/src/commands/game.ts @@ -1,64 +1,64 @@ -/* eslint-disable prefer-destructuring */ -import { Activity, Member, Message } from 'eris'; -import { Client, Command, RichEmbed } from '../class'; - -enum ActivityType { - PLAYING, - STREAMING, - LISTENING, - WATCHING, - CUSTOM_STATUS -} - -export default class Game extends Command { - constructor(client: Client) { - super(client); - this.name = 'game'; - this.description = 'Displays information about the member\'s game.'; - this.usage = 'game [member]'; - this.permissions = 0; - this.aliases = ['activity']; - this.guildOnly = true; - this.enabled = true; - } - - public async run(message: Message, args: string[]) { - try { - let member: Member; - if (!args[0]) member = message.member; - else { - member = this.client.util.resolveMember(args.join(' '), message.guild); - if (!member) { - return this.error(message.channel, 'Member not found.'); - } - } - if (member.activities.length <= 0) return this.error(message.channel, 'Cannot find a game for this member.'); - const embed = new RichEmbed(); - let mainStatus: Activity; - if (member.activities[0].type === ActivityType.CUSTOM_STATUS) { - mainStatus = member.activities[1]; - embed.setDescription(`*${member.activities[0].state}*`); - } else { - mainStatus = member.activities[0]; - } - embed.setAuthor(member.user.username, member.user.avatarURL); - if (mainStatus.type === ActivityType.LISTENING) { - embed.setTitle('Spotify'); - embed.setColor('#1ed760'); - embed.addField('Song', mainStatus.details, true); - embed.addField('Artist', mainStatus.state, true); - embed.addField('Album', mainStatus.assets.large_text); - embed.addField('Start', `${new Date(mainStatus.timestamps.start).toLocaleTimeString('en-us')} ET`, true); - embed.addField('End', `${new Date(mainStatus.timestamps.end).toLocaleTimeString('en-us')} ET`, true); - embed.setThumbnail(`https://i.scdn.co/image/${mainStatus.assets.large_image.split(':')[1]}`); - embed.setFooter(`Listening to Spotify | ${this.client.user.username}`, 'https://media.discordapp.net/attachments/358674161566220288/496894273304920064/2000px-Spotify_logo_without_text.png'); - embed.setTimestamp(); - } else { - return this.error(message.channel, 'Only Spotify games are supported at this time.'); - } - return message.channel.createMessage({ embed }); - } catch (err) { - return this.client.util.handleError(err, message, this); - } - } -} +/* eslint-disable prefer-destructuring */ +import { Activity, Member, Message } from 'eris'; +import { Client, Command, RichEmbed } from '../class'; + +enum ActivityType { + PLAYING, + STREAMING, + LISTENING, + WATCHING, + CUSTOM_STATUS +} + +export default class Game extends Command { + constructor(client: Client) { + super(client); + this.name = 'game'; + this.description = 'Displays information about the member\'s game.'; + this.usage = 'game [member]'; + this.permissions = 0; + this.aliases = ['activity']; + this.guildOnly = true; + this.enabled = true; + } + + public async run(message: Message, args: string[]) { + try { + let member: Member; + if (!args[0]) member = message.member; + else { + member = this.client.util.resolveMember(args.join(' '), message.guild); + if (!member) { + return this.error(message.channel, 'Member not found.'); + } + } + if (member.activities.length <= 0) return this.error(message.channel, 'Cannot find a game for this member.'); + const embed = new RichEmbed(); + let mainStatus: Activity; + if (member.activities[0].type === ActivityType.CUSTOM_STATUS) { + mainStatus = member.activities[1]; + embed.setDescription(`*${member.activities[0].state}*`); + } else { + mainStatus = member.activities[0]; + } + embed.setAuthor(member.user.username, member.user.avatarURL); + if (mainStatus.type === ActivityType.LISTENING) { + embed.setTitle('Spotify'); + embed.setColor('#1ed760'); + embed.addField('Song', mainStatus.details, true); + embed.addField('Artist', mainStatus.state, true); + embed.addField('Album', mainStatus.assets.large_text); + embed.addField('Start', `${new Date(mainStatus.timestamps.start).toLocaleTimeString('en-us')} ET`, true); + embed.addField('End', `${new Date(mainStatus.timestamps.end).toLocaleTimeString('en-us')} ET`, true); + embed.setThumbnail(`https://i.scdn.co/image/${mainStatus.assets.large_image.split(':')[1]}`); + embed.setFooter(`Listening to Spotify | ${this.client.user.username}`, 'https://media.discordapp.net/attachments/358674161566220288/496894273304920064/2000px-Spotify_logo_without_text.png'); + embed.setTimestamp(); + } else { + return this.error(message.channel, 'Only Spotify games are supported at this time.'); + } + return message.channel.createMessage({ embed }); + } catch (err) { + return this.client.util.handleError(err, message, this); + } + } +} diff --git a/src/commands/help.ts b/src/commands/help.ts index bed8280..cc19db1 100644 --- a/src/commands/help.ts +++ b/src/commands/help.ts @@ -1,115 +1,115 @@ -import { createPaginationEmbed } from 'eris-pagination'; -import { Message } from 'eris'; -import { Client, Command, RichEmbed } from '../class'; - -export default class Help extends Command { - constructor(client: Client) { - super(client); - this.name = 'help'; - this.description = 'Information about commands.'; - this.usage = 'help [command]'; - this.permissions = 0; - this.enabled = true; - } - - public async run(message: Message, args: string[]) { - try { - if (args.length > 0) { - const command = this.client.commands.get(args[0].toLowerCase()); - if (!command) return this.error(message.channel, 'The command you provided doesn\'t exist.'); - const embed = new RichEmbed(); - embed.setTitle(`${this.client.config.prefix}${command.name}`); - embed.addField('Description', command.description ?? '-'); - embed.addField('Usage', command.usage ?? '-'); - if (command.aliases.length > 0) { - embed.addField('Aliases', command.aliases.map((alias) => `${this.client.config.prefix}${alias}`).join(', ')); - } - let description: string = ''; - if (!command.enabled) { - description += 'This command is disabled.'; - } - if (command.guildOnly) { - description += 'This command can only be ran in a guild.'; - } - embed.setDescription(description); - switch (command.permissions) { - case 0: - break; - case 1: - embed.addField('Permissions', 'Associates+'); - break; - case 2: - embed.addField('Permissions', 'Core Team+'); - break; - case 3: - embed.addField('Permissions', 'Moderators, Supervisor, & Board of Directors'); - break; - case 4: - embed.addField('Permissions', 'Technicians, Supervisor, & Board of Directors'); - break; - case 5: - embed.addField('Permissions', 'Moderators, Technicians, Supervisor, & Board of Directors'); - break; - case 6: - embed.addField('Permissions', 'Supervisor+'); - break; - case 7: - embed.addField('Permissions', 'Board of Directors'); - break; - default: - break; - } - embed.setFooter(this.client.user.username, this.client.user.avatarURL); - embed.setTimestamp(); - return message.channel.createMessage({ embed }); - } - const cmdList: Command[] = []; - this.client.commands.forEach((c) => cmdList.push(c)); - const commands = this.client.commands.map((c) => { - const aliases = c.aliases.map((alias) => `${this.client.config.prefix}${alias}`).join(', '); - let perm: string; - switch (c.permissions) { - case 0: - break; - case 1: - perm = 'Associates+'; - break; - case 2: - perm = 'Core Team+'; - break; - case 3: - perm = 'Moderators, Supervisor, & Board of Directors'; - break; - case 4: - perm = 'Technicians, Supervisor, & Board of Directors'; - break; - case 5: - perm = 'Moderators, Technicians, Supervisor, & Board of Directors'; - break; - case 6: - perm = 'Supervisor+'; - break; - case 7: - perm = 'Board of Directors'; - break; - default: - break; - } - return { name: `${this.client.config.prefix}${c.name}`, value: `**Description:** ${c.description}\n**Aliases:** ${aliases}\n**Usage:** ${c.usage}\n**Permissions:** ${perm ?? ''}`, inline: false }; - }); - const splitCommands = this.client.util.splitFields(commands); - const cmdPages: RichEmbed[] = []; - splitCommands.forEach((splitCmd) => { - const embed = new RichEmbed(); - embed.setTimestamp(); embed.setFooter(this.client.user.username, this.client.user.avatarURL); - embed.setDescription(`Command list for ${this.client.user.username}`); - splitCmd.forEach((c) => embed.addField(c.name, c.value, c.inline)); - return cmdPages.push(embed); - }); - if (cmdPages.length === 1) return message.channel.createMessage({ embed: cmdPages[0] }); - return createPaginationEmbed(message, cmdPages); - } catch (err) { - return this.client.util.handleError(err, message, this, false); - } - } -} +import { createPaginationEmbed } from 'eris-pagination'; +import { Message } from 'eris'; +import { Client, Command, RichEmbed } from '../class'; + +export default class Help extends Command { + constructor(client: Client) { + super(client); + this.name = 'help'; + this.description = 'Information about commands.'; + this.usage = 'help [command]'; + this.permissions = 0; + this.enabled = true; + } + + public async run(message: Message, args: string[]) { + try { + if (args.length > 0) { + const command = this.client.commands.get(args[0].toLowerCase()); + if (!command) return this.error(message.channel, 'The command you provided doesn\'t exist.'); + const embed = new RichEmbed(); + embed.setTitle(`${this.client.config.prefix}${command.name}`); + embed.addField('Description', command.description ?? '-'); + embed.addField('Usage', command.usage ?? '-'); + if (command.aliases.length > 0) { + embed.addField('Aliases', command.aliases.map((alias) => `${this.client.config.prefix}${alias}`).join(', ')); + } + let description: string = ''; + if (!command.enabled) { + description += 'This command is disabled.'; + } + if (command.guildOnly) { + description += 'This command can only be ran in a guild.'; + } + embed.setDescription(description); + switch (command.permissions) { + case 0: + break; + case 1: + embed.addField('Permissions', 'Associates+'); + break; + case 2: + embed.addField('Permissions', 'Core Team+'); + break; + case 3: + embed.addField('Permissions', 'Moderators, Supervisor, & Board of Directors'); + break; + case 4: + embed.addField('Permissions', 'Technicians, Supervisor, & Board of Directors'); + break; + case 5: + embed.addField('Permissions', 'Moderators, Technicians, Supervisor, & Board of Directors'); + break; + case 6: + embed.addField('Permissions', 'Supervisor+'); + break; + case 7: + embed.addField('Permissions', 'Board of Directors'); + break; + default: + break; + } + embed.setFooter(this.client.user.username, this.client.user.avatarURL); + embed.setTimestamp(); + return message.channel.createMessage({ embed }); + } + const cmdList: Command[] = []; + this.client.commands.forEach((c) => cmdList.push(c)); + const commands = this.client.commands.map((c) => { + const aliases = c.aliases.map((alias) => `${this.client.config.prefix}${alias}`).join(', '); + let perm: string; + switch (c.permissions) { + case 0: + break; + case 1: + perm = 'Associates+'; + break; + case 2: + perm = 'Core Team+'; + break; + case 3: + perm = 'Moderators, Supervisor, & Board of Directors'; + break; + case 4: + perm = 'Technicians, Supervisor, & Board of Directors'; + break; + case 5: + perm = 'Moderators, Technicians, Supervisor, & Board of Directors'; + break; + case 6: + perm = 'Supervisor+'; + break; + case 7: + perm = 'Board of Directors'; + break; + default: + break; + } + return { name: `${this.client.config.prefix}${c.name}`, value: `**Description:** ${c.description}\n**Aliases:** ${aliases}\n**Usage:** ${c.usage}\n**Permissions:** ${perm ?? ''}`, inline: false }; + }); + const splitCommands = this.client.util.splitFields(commands); + const cmdPages: RichEmbed[] = []; + splitCommands.forEach((splitCmd) => { + const embed = new RichEmbed(); + embed.setTimestamp(); embed.setFooter(this.client.user.username, this.client.user.avatarURL); + embed.setDescription(`Command list for ${this.client.user.username}`); + splitCmd.forEach((c) => embed.addField(c.name, c.value, c.inline)); + return cmdPages.push(embed); + }); + if (cmdPages.length === 1) return message.channel.createMessage({ embed: cmdPages[0] }); + return createPaginationEmbed(message, cmdPages); + } catch (err) { + return this.client.util.handleError(err, message, this, false); + } + } +} diff --git a/src/commands/index.ts b/src/commands/index.ts index 313b0dc..4ed5246 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -1,18 +1,18 @@ -export { default as additem } from './additem'; -export { default as addredirect } from './addredirect'; -export { default as ban } from './ban'; -export { default as delitem } from './delitem'; -export { default as delredirect } from './delredirect'; -export { default as djs } from './djs'; -export { default as eval } from './eval'; -export { default as game } from './game'; -export { default as help } from './help'; -export { default as info } from './info'; -export { default as kick } from './kick'; -export { default as listredirects } from './listredirects'; -export { default as npm } from './npm'; -export { default as page } from './page'; -export { default as ping } from './ping'; -export { default as roleinfo } from './roleinfo'; -export { default as unban } from './unban'; -export { default as whois } from './whois'; +export { default as additem } from './additem'; +export { default as addredirect } from './addredirect'; +export { default as ban } from './ban'; +export { default as delitem } from './delitem'; +export { default as delredirect } from './delredirect'; +export { default as djs } from './djs'; +export { default as eval } from './eval'; +export { default as game } from './game'; +export { default as help } from './help'; +export { default as info } from './info'; +export { default as kick } from './kick'; +export { default as listredirects } from './listredirects'; +export { default as npm } from './npm'; +export { default as page } from './page'; +export { default as ping } from './ping'; +export { default as roleinfo } from './roleinfo'; +export { default as unban } from './unban'; +export { default as whois } from './whois'; diff --git a/src/commands/info.ts b/src/commands/info.ts index 0015822..8b994ff 100644 --- a/src/commands/info.ts +++ b/src/commands/info.ts @@ -1,36 +1,36 @@ -import { Message } from 'eris'; -import { totalmem } from 'os'; -import { Client, Command, RichEmbed } from '../class'; -import { version as erisVersion } from '../../node_modules/eris/package.json'; -import { version as expressVersion } from '../../node_modules/express/package.json'; -import { version as mongooseVersion } from '../../node_modules/mongoose/package.json'; - -export default class Info extends Command { - constructor(client: Client) { - super(client); - this.name = 'info'; - this.description = 'System information.'; - this.usage = 'info'; - this.permissions = 0; - this.enabled = true; - } - - public async run(message: Message) { - try { - const embed = new RichEmbed(); - embed.setTitle('Information'); - embed.setThumbnail(this.client.user.avatarURL); - embed.addField('Language(s)', '<:TypeScript:703451285789343774> TypeScript', true); - embed.addField('Discord Library', `Eris (${erisVersion})`, true); - embed.addField('HTTP Server Library', `Express (${expressVersion})`, true); - embed.addField('Database Library', `MongoDB w/ Mongoose ODM (${mongooseVersion})`, true); - embed.addField('Repository', 'https://gitlab.libraryofcode.org/engineering/communityrelations | Licensed under GNU Affero General Public License V3', true); - embed.addField('Memory Usage', `${Math.round(process.memoryUsage().rss / 1024 / 1024)} MB / ${Math.round(totalmem() / 1024 / 1024 / 1024)} GB`, true); - embed.setFooter(this.client.user.username, this.client.user.avatarURL); - embed.setTimestamp(); - message.channel.createMessage({ embed }); - } catch (err) { - this.client.util.handleError(err, message, this); - } - } -} +import { Message } from 'eris'; +import { totalmem } from 'os'; +import { Client, Command, RichEmbed } from '../class'; +import { version as erisVersion } from '../../node_modules/eris/package.json'; +import { version as expressVersion } from '../../node_modules/express/package.json'; +import { version as mongooseVersion } from '../../node_modules/mongoose/package.json'; + +export default class Info extends Command { + constructor(client: Client) { + super(client); + this.name = 'info'; + this.description = 'System information.'; + this.usage = 'info'; + this.permissions = 0; + this.enabled = true; + } + + public async run(message: Message) { + try { + const embed = new RichEmbed(); + embed.setTitle('Information'); + embed.setThumbnail(this.client.user.avatarURL); + embed.addField('Language(s)', '<:TypeScript:703451285789343774> TypeScript', true); + embed.addField('Discord Library', `Eris (${erisVersion})`, true); + embed.addField('HTTP Server Library', `Express (${expressVersion})`, true); + embed.addField('Database Library', `MongoDB w/ Mongoose ODM (${mongooseVersion})`, true); + embed.addField('Memory Usage', `${Math.round(process.memoryUsage().rss / 1024 / 1024)} MB / ${Math.round(totalmem() / 1024 / 1024 / 1024)} GB`, true); + embed.addField('Repository', 'https://loc.sh/crgit | Licensed under GNU Affero General Public License V3', true); + embed.setFooter(this.client.user.username, this.client.user.avatarURL); + embed.setTimestamp(); + message.channel.createMessage({ embed }); + } catch (err) { + this.client.util.handleError(err, message, this); + } + } +} diff --git a/src/commands/kick.ts b/src/commands/kick.ts index 8ad74e3..69dbff4 100644 --- a/src/commands/kick.ts +++ b/src/commands/kick.ts @@ -1,37 +1,37 @@ -import { Message, User, Member } from 'eris'; -import { Client, Command } from '../class'; - -export default class Kick extends Command { - constructor(client: Client) { - super(client); - this.name = 'kick'; - this.description = 'Kicks a member from the guild.'; - this.usage = 'kick [reason]'; - this.permissions = 3; - this.guildOnly = true; - this.enabled = true; - } - - public async run(message: Message, args: string[]) { - try { - if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); - let user: Member = this.client.util.resolveMember(args[0], message.guild); - if (!user) { - try { - user = await this.client.getRESTGuildMember(this.client.config.guildID, args[0]); - } catch { - return this.error(message.channel, 'Cannot find user.'); - } - } - if (user && !this.client.util.moderation.checkPermissions(user, message.member)) return this.error(message.channel, 'Permission Denied.'); - message.delete(); - - const reason: string = args[1]; - if (reason.length > 512) return this.error(message.channel, 'Kick reasons cannot be longer than 512 characters.'); - await this.client.util.moderation.kick(user, message.member, reason); - return this.success(message.channel, `${user.username}#${user.id} has been kicked.`); - } catch (err) { - return this.client.util.handleError(err, message, this, false); - } - } -} +import { Message, User, Member } from 'eris'; +import { Client, Command } from '../class'; + +export default class Kick extends Command { + constructor(client: Client) { + super(client); + this.name = 'kick'; + this.description = 'Kicks a member from the guild.'; + this.usage = 'kick [reason]'; + this.permissions = 3; + this.guildOnly = true; + this.enabled = true; + } + + public async run(message: Message, args: string[]) { + try { + if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); + let user: Member = this.client.util.resolveMember(args[0], message.guild); + if (!user) { + try { + user = await this.client.getRESTGuildMember(this.client.config.guildID, args[0]); + } catch { + return this.error(message.channel, 'Cannot find user.'); + } + } + if (user && !this.client.util.moderation.checkPermissions(user, message.member)) return this.error(message.channel, 'Permission Denied.'); + message.delete(); + + const reason: string = args[1]; + if (reason.length > 512) return this.error(message.channel, 'Kick reasons cannot be longer than 512 characters.'); + await this.client.util.moderation.kick(user, message.member, reason); + return this.success(message.channel, `${user.username}#${user.id} has been kicked.`); + } catch (err) { + return this.client.util.handleError(err, message, this, false); + } + } +} diff --git a/src/commands/listredirects.ts b/src/commands/listredirects.ts index ae9a11e..6744651 100644 --- a/src/commands/listredirects.ts +++ b/src/commands/listredirects.ts @@ -1,52 +1,52 @@ -import { Message } from 'eris'; -import { createPaginationEmbed } from 'eris-pagination'; -import { Client, Command, RichEmbed } from '../class'; - -export default class DelRedirect extends Command { - constructor(client: Client) { - super(client); - this.name = 'listredirects'; - this.description = 'Delete a redirect link for \'loc.sh\''; - this.usage = 'listredirects [key || redirect to]'; - this.aliases = ['getredirect', 'lsredirects', 'listlinks', 'lsr', 'gr']; - this.permissions = 6; - this.enabled = true; - } - - public async run(message: Message, args: string[]) { - try { - if (args[0]) { - const redirects = await this.client.db.Redirect.find({ $or: [{ key: args[0].toLowerCase() }, { to: args[0].toLowerCase() }] }); - if (redirects.length <= 0) return this.error(message.channel, 'Could not find an entry matching that query.'); - const embed = new RichEmbed(); - embed.setTitle('Redirect Information'); - for (const redirect of redirects) { - embed.addField(`${redirect.key} | visited ${redirect.visitedCount} times`, redirect.to); - } - embed.setFooter(this.client.user.username, this.client.user.avatarURL); - embed.setTimestamp(); - return message.channel.createMessage({ embed }); - } - const redirects = await this.client.db.Redirect.find(); - if (!redirects) return this.error(message.channel, 'No redirect links found.'); - const redirectArray: [{ name: string, value: string }?] = []; - for (const redirect of redirects) { - redirectArray.push({ name: `${redirect.key} | visited ${redirect.visitedCount} times`, value: redirect.to }); - } - const splitRedirects = this.client.util.splitFields(redirectArray); - const cmdPages: RichEmbed[] = []; - splitRedirects.forEach((split) => { - const embed = new RichEmbed(); - embed.setTitle('Redirect Information'); - embed.setTimestamp(); - embed.setFooter(this.client.user.username, this.client.user.avatarURL); - split.forEach((c) => embed.addField(c.name, c.value)); - return cmdPages.push(embed); - }); - if (cmdPages.length === 1) return message.channel.createMessage({ embed: cmdPages[0] }); - return createPaginationEmbed(message, cmdPages); - } catch (err) { - return this.client.util.handleError(err, message, this); - } - } -} +import { Message } from 'eris'; +import { createPaginationEmbed } from 'eris-pagination'; +import { Client, Command, RichEmbed } from '../class'; + +export default class DelRedirect extends Command { + constructor(client: Client) { + super(client); + this.name = 'listredirects'; + this.description = 'Delete a redirect link for \'loc.sh\''; + this.usage = 'listredirects [key || redirect to]'; + this.aliases = ['getredirect', 'lsredirects', 'listlinks', 'lsr', 'gr']; + this.permissions = 6; + this.enabled = true; + } + + public async run(message: Message, args: string[]) { + try { + if (args[0]) { + const redirects = await this.client.db.Redirect.find({ $or: [{ key: args[0].toLowerCase() }, { to: args[0].toLowerCase() }] }); + if (redirects.length <= 0) return this.error(message.channel, 'Could not find an entry matching that query.'); + const embed = new RichEmbed(); + embed.setTitle('Redirect Information'); + for (const redirect of redirects) { + embed.addField(`${redirect.key} | visited ${redirect.visitedCount} times`, redirect.to); + } + embed.setFooter(this.client.user.username, this.client.user.avatarURL); + embed.setTimestamp(); + return message.channel.createMessage({ embed }); + } + const redirects = await this.client.db.Redirect.find(); + if (!redirects) return this.error(message.channel, 'No redirect links found.'); + const redirectArray: [{ name: string, value: string }?] = []; + for (const redirect of redirects) { + redirectArray.push({ name: `${redirect.key} | visited ${redirect.visitedCount} times`, value: redirect.to }); + } + const splitRedirects = this.client.util.splitFields(redirectArray); + const cmdPages: RichEmbed[] = []; + splitRedirects.forEach((split) => { + const embed = new RichEmbed(); + embed.setTitle('Redirect Information'); + embed.setTimestamp(); + embed.setFooter(this.client.user.username, this.client.user.avatarURL); + split.forEach((c) => embed.addField(c.name, c.value)); + return cmdPages.push(embed); + }); + if (cmdPages.length === 1) return message.channel.createMessage({ embed: cmdPages[0] }); + return createPaginationEmbed(message, cmdPages); + } catch (err) { + return this.client.util.handleError(err, message, this); + } + } +} diff --git a/src/commands/npm.ts b/src/commands/npm.ts index 5fec51d..062f90e 100644 --- a/src/commands/npm.ts +++ b/src/commands/npm.ts @@ -1,64 +1,64 @@ -import { Message } from 'eris'; -import axios from 'axios'; -import { Client, Command, RichEmbed } from '../class'; - -export default class NPM extends Command { - constructor(client: Client) { - super(client); - this.name = 'npm'; - this.description = 'Get information about npm modules.'; - this.usage = 'npm '; - this.permissions = 0; - this.guildOnly = false; - this.enabled = true; - } - - public async run(message: Message, args: string[]) { - try { - if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); - - const res = await axios.get(`https://registry.npmjs.com/${args[0]}`, { validateStatus: (_) => true }); - - if (res.status === 404) return this.error(message.channel, 'Could not find the library, try something else.'); - - const { data } = res; - - const bugs: string = data.bugs?.url || ''; - const description: string = data.description || 'None'; - const version: string = data['dist-tags']?.latest || 'Unknown'; - const homepage: string = data.homepage || ''; - let license: string = 'None'; - if (typeof data.license === 'object') { - license = data.license.type; - } else if (typeof data.license === 'string') { - license = data.license; - } - let dependencies: string = 'None'; - if (version !== 'Unknown' && data.versions[version].dependencies !== undefined && Object.keys(data.versions[version].dependencies).length > 0) { - dependencies = Object.keys(data.versions[version].dependencies).join(', '); - } - const name: string = data.name || 'None'; - const repository: string = bugs.replace('/issues', '') || ''; - const creation: string = data.time.created ? new Date(data.time.created).toLocaleString('en') : 'None'; - const modification: string = data.time.modified ? new Date(data.time.modified).toLocaleString('en') : 'None'; - - const embed = new RichEmbed(); - embed.setColor(0xCC3534); - embed.setTimestamp(); - embed.setFooter(this.client.user.username, this.client.user.avatarURL); - embed.setAuthor('NPM', 'https://i.imgur.com/ErKf5Y0.png', 'https://www.npmjs.com/'); - embed.setDescription(`[NPM](https://www.npmjs.com/package/${args[0]}) | [Homepage](${homepage}) | [Repository](${repository}) | [Bugs](${bugs})`); - embed.addField('Name', name, true); - embed.addField('Latest version', version, true); - embed.addField('License', license, true); - embed.addField('Description', description, false); - embed.addField('Dependencies', dependencies, false); - embed.addField('Creation Date', creation, true); - embed.addField('Modification Date', modification, true); - - return message.channel.createMessage({ embed }); - } catch (err) { - return this.client.util.handleError(err, message, this); - } - } -} +import { Message } from 'eris'; +import axios from 'axios'; +import { Client, Command, RichEmbed } from '../class'; + +export default class NPM extends Command { + constructor(client: Client) { + super(client); + this.name = 'npm'; + this.description = 'Get information about npm modules.'; + this.usage = 'npm '; + this.permissions = 0; + this.guildOnly = false; + this.enabled = true; + } + + public async run(message: Message, args: string[]) { + try { + if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); + + const res = await axios.get(`https://registry.npmjs.com/${args[0]}`, { validateStatus: (_) => true }); + + if (res.status === 404) return this.error(message.channel, 'Could not find the library, try something else.'); + + const { data } = res; + + const bugs: string = data.bugs?.url || ''; + const description: string = data.description || 'None'; + const version: string = data['dist-tags']?.latest || 'Unknown'; + const homepage: string = data.homepage || ''; + let license: string = 'None'; + if (typeof data.license === 'object') { + license = data.license.type; + } else if (typeof data.license === 'string') { + license = data.license; + } + let dependencies: string = 'None'; + if (version !== 'Unknown' && data.versions[version].dependencies !== undefined && Object.keys(data.versions[version].dependencies).length > 0) { + dependencies = Object.keys(data.versions[version].dependencies).join(', '); + } + const name: string = data.name || 'None'; + const repository: string = bugs.replace('/issues', '') || ''; + const creation: string = data.time.created ? new Date(data.time.created).toLocaleString('en') : 'None'; + const modification: string = data.time.modified ? new Date(data.time.modified).toLocaleString('en') : 'None'; + + const embed = new RichEmbed(); + embed.setColor(0xCC3534); + embed.setTimestamp(); + embed.setFooter(this.client.user.username, this.client.user.avatarURL); + embed.setAuthor('NPM', 'https://i.imgur.com/ErKf5Y0.png', 'https://www.npmjs.com/'); + embed.setDescription(`[NPM](https://www.npmjs.com/package/${args[0]}) | [Homepage](${homepage}) | [Repository](${repository}) | [Bugs](${bugs})`); + embed.addField('Name', name, true); + embed.addField('Latest version', version, true); + embed.addField('License', license, true); + embed.addField('Description', description, false); + embed.addField('Dependencies', dependencies, false); + embed.addField('Creation Date', creation, true); + embed.addField('Modification Date', modification, true); + + return message.channel.createMessage({ embed }); + } catch (err) { + return this.client.util.handleError(err, message, this); + } + } +} diff --git a/src/commands/page.ts b/src/commands/page.ts index 6f65c8d..1297a9b 100644 --- a/src/commands/page.ts +++ b/src/commands/page.ts @@ -1,153 +1,154 @@ -/* eslint-disable no-case-declarations */ -/* eslint-disable no-continue */ -/* eslint-disable no-await-in-loop */ -import { Message, TextableChannel, Textable } from 'eris'; -import { Client, Command, RichEmbed } from '../class'; - -export default class Page extends Command { - public local: { emergencyNumbers: string[], departmentNumbers: string[], validPagerCodes: string[], codeDict: Map, }; - - constructor(client: Client) { - super(client); - this.name = 'page'; - this.description = 'Pages the specified emergency number, department number, or individual number with the specified pager code.'; - this.usage = 'page '; - this.aliases = ['p']; - this.permissions = 1; - this.enabled = true; - this.guildOnly = true; - this.local = { - emergencyNumbers: ['#0', '#1', '#2', '#3'], - departmentNumbers: ['00', '01', '10', '20', '21', '22'], - validPagerCodes: ['911', '811', '210', '265', '411', '419', '555', '556'], - codeDict: new Map(), - }; - this.init(); - } - - public init() { - this.local.codeDict.set('911', 'Sender is requesting EMERGENCY assistance.'); - this.local.codeDict.set('811', 'Sender is requesting immediate/ASAP assistance.'); - this.local.codeDict.set('210', 'Sender is informing you they acknowledged your request, usually sent in response to OK the initial page. (10-4)'); - this.local.codeDict.set('265', 'Sender is requesting that you check your email.'); - this.local.codeDict.set('411', 'Sender is requesting information/counsel from you.'); - this.local.codeDict.set('419', 'Sender didn\'t recognize your request.'); - this.local.codeDict.set('555', 'Sender is requesting that you contact them.'); - this.local.codeDict.set('556', 'Sender is requesting that you contact them via DMs.'); - } - - public async run(message: Message, args: string[]) { - try { - if (!args[0]) { - this.client.commands.get('help').run(message, [this.name]); - const embed = new RichEmbed(); - embed.setTitle('Special Emergency/Department Numbers & Pager Codes'); - embed.addField('Special Emergency Numbers', '`#0` | Broadcast - all Staff/Associates\n`#1` | Authoritative Broadcast - all Directors, Supervisors, Technicians, and Moderators\n`#2` | Systems Administrators/Technicians Broadcast - Matthew, Bsian, NightRaven, and all Technicians\n`#3` | Community/Moderation Team Broadcast - all Directors, Supervisors, Moderators, and Core Team'); - embed.addField('Department Numbers', '`00` | Board of Directors\n`01` | Supervisors\n`10` | Technicians\n`20` | Moderators\n`21` | Core Team\n`22` | Associates'); - embed.addField('Pager Codes', '"Pager" term in this field refers to the Staff member that initially paged. This is a list of valid codes you can send via a page.\n\n`911` - Pager is requesting EMERGENCY assistance\n`811` - Pager is requesting immediate/ASAP assistance\n`210` - Pager is informing you they acknowledged your request, usually sent in response to OK the initial page.\n`265` - Pager is requesting that you check your email\n`411` - Pager is requesting information/counsel from you\n`419` - Pager didn\'t recognize your request\n`555` - Pager is requesting that you contact them\n`556` - Pager is requesting that you contact them via DMs'); - embed.setFooter(this.client.user.username, this.client.user.avatarURL); - embed.setTimestamp(); - return message.channel.createMessage({ embed }); - } - message.delete(); - const loading = await this.loading(message.channel, 'Paging...'); - const sender = await this.client.db.PagerNumber.findOne({ individualAssignID: message.author.id }); - const page = await this.page(args[0], sender.num, args[1], message); - if (page.status === true) { - loading.delete(); - return this.success(message.channel, page.message); - } - loading.delete(); - return this.error(message.channel, page.message); - } catch (err) { - return this.client.util.handleError(err, message, this); - } - } - - public logPage(sender: { number: string, user?: string }, recipient: { number: string, user?:string }, type: 'discord' | 'email', code: string): void { - const chan = this.client.guilds.get(this.client.config.guildID).channels.get('722636436716781619'); - chan.createMessage(`***[${type.toUpperCase()}] \`${sender.number} (${sender.user ? sender.user : ''})\` sent a page to \`${recipient.number} (${recipient.user ? recipient.user : ''})\` with code \`${code}\`.***`); - this.client.util.signale.log(`PAGE (${type.toUpperCase()})| TO: ${recipient.number}, FROM: ${sender.number}, CODE: ${code}`); - } - - public async page(recipientNumber: string, senderNumber: string, code: string, message: Message, options?: { emergencyNumber: string }): Promise<{status: boolean, message: string}> { - try { - const senderEntry = await this.client.db.PagerNumber.findOne({ num: senderNumber }); - if (!senderEntry) { - return { status: false, message: 'You do not have a Pager Number.' }; - } - if (this.local.emergencyNumbers.includes(recipientNumber)) { - switch (recipientNumber) { - case '#0': - this.local.departmentNumbers.forEach(async (num) => { - await this.page(num, senderNumber, code, message, { emergencyNumber: '0' }); - }); - break; - case '#1': - await this.page('00', senderNumber, code, message, { emergencyNumber: '0' }); - await this.page('01', senderNumber, code, message, { emergencyNumber: '0' }); - await this.page('10', senderNumber, code, message, { emergencyNumber: '0' }); - await this.page('20', senderNumber, code, message, { emergencyNumber: '0' }); - break; - case '#2': - const matthew = await this.client.db.PagerNumber.findOne({ individualAssignID: '278620217221971968' }); - const bsian = await this.client.db.PagerNumber.findOne({ individualAssignID: '253600545972027394' }); - const nightraven = await this.client.db.PagerNumber.findOne({ individualAssignID: '239261547959025665' }); - await this.page(matthew?.num, senderNumber, code, message, { emergencyNumber: '0' }); - await this.page(bsian?.num, senderNumber, code, message, { emergencyNumber: '0' }); - await this.page(nightraven?.num, senderNumber, code, message, { emergencyNumber: '0' }); - await this.page('10', senderNumber, code, message, { emergencyNumber: '0' }); - break; - case '#3': - await this.page('00', senderNumber, code, message, { emergencyNumber: '0' }); - await this.page('01', senderNumber, code, message, { emergencyNumber: '0' }); - await this.page('20', senderNumber, code, message, { emergencyNumber: '0' }); - await this.page('21', senderNumber, code, message, { emergencyNumber: '0' }); - break; - default: - break; - } - return { status: true, message: `Page to \`${recipientNumber}\` sent.` }; - } - const recipientEntry = await this.client.db.PagerNumber.findOne({ num: recipientNumber }); - if (!recipientEntry) { - return { status: false, message: `Pager Number \`${recipientNumber}\` does not exist.` }; - } - if (!this.local.validPagerCodes.includes(code)) { - return { status: false, message: 'The Pager Code you provided is invalid.' }; - } - - for (const id of recipientEntry.discordIDs) { - const recipient = this.client.guilds.get(this.client.config.guildID).members.get(recipientEntry.individualAssignID); - const sender = this.client.guilds.get(this.client.config.guildID).members.get(senderEntry.individualAssignID); - const chan = await this.client.getDMChannel(id); - if (!chan) continue; - if (!recipient || !sender) { - this.logPage({ number: senderNumber, user: 'N/A' }, { number: recipientNumber, user: 'N/A' }, 'discord', code); - } else { - this.logPage({ number: senderNumber, user: `${sender.username}#${sender.discriminator}` }, { number: recipientNumber, user: `${recipient.username}#${recipient.discriminator}` }, 'discord', code); - } - chan.createMessage(`${options?.emergencyNumber ? `[SEN#${options.emergencyNumber}] ` : ''}__**Page**__\n**Recipient PN:** ${recipientNumber}\n**Sender PN:** ${senderNumber} (${sender ? `${sender.username}#${sender.discriminator}` : ''})\n**Initial Command:** https://discordapp.com/channels/${message.guild.id}/${message.channel.id}/${message.id} (<#${message.channel.id}>)\n\n**Pager Code:** ${code} (${this.local.codeDict.get(code)})`); - } - for (const email of recipientEntry.emailAddresses) { - const recipient = this.client.guilds.get(this.client.config.guildID).members.get(recipientEntry.individualAssignID); - const sender = this.client.guilds.get(this.client.config.guildID).members.get(senderEntry.individualAssignID); - if (!recipient || !sender) { - this.logPage({ number: senderNumber, user: 'N/A' }, { number: recipientNumber, user: 'N/A' }, 'email', code); - } else { - this.logPage({ number: senderNumber, user: `${sender.username}#${sender.discriminator}` }, { number: recipientNumber, user: `${recipient.username}#${recipient.discriminator}` }, 'email', code); - } - await this.client.util.transporter.sendMail({ - from: '"LOC Paging System" ', - to: email, - subject: `PAGE FROM ${recipientNumber}`, - html: `

Page

${options?.emergencyNumber ? `

[SEN#${options.emergencyNumber}]` : ''}Recipient PN: ${recipientNumber}
Sender PN: ${senderNumber} (${sender ? `${sender.username}#${sender.discriminator}` : ''})
Initial Command: https://discordapp.com/channels/${message.guild.id}/${message.channel.id}/${message.id} (<#${message.channel.id}>)

Pager Code: ${code} (${this.local.codeDict.get(code)})`, - }); - } - return { status: true, message: `Page to \`${recipientNumber}\` sent.` }; - } catch (err) { - this.client.util.signale.error(err); - return { status: false, message: `Error during Processing: ${err}` }; - } - } -} +/* eslint-disable no-case-declarations */ +/* eslint-disable no-continue */ +/* eslint-disable no-await-in-loop */ +import { Message, TextableChannel } from 'eris'; +import { Client, Command, RichEmbed } from '../class'; + +export default class Page extends Command { + public local: { emergencyNumbers: string[], departmentNumbers: string[], validPagerCodes: string[], codeDict: Map, }; + + constructor(client: Client) { + super(client); + this.name = 'page'; + this.description = 'Pages the specified emergency number, department number, or individual number with the specified pager code.'; + this.usage = 'page [optional message]'; + this.aliases = ['p']; + this.permissions = 1; + this.enabled = true; + this.guildOnly = true; + this.local = { + emergencyNumbers: ['#0', '#1', '#2', '#3'], + departmentNumbers: ['00', '01', '10', '20', '21', '22'], + validPagerCodes: ['911', '811', '210', '265', '411', '419', '555', '556'], + codeDict: new Map(), + }; + this.init(); + } + + public init() { + this.local.codeDict.set('911', 'Sender is requesting EMERGENCY assistance.'); + this.local.codeDict.set('811', 'Sender is requesting immediate/ASAP assistance.'); + this.local.codeDict.set('210', 'Sender is informing you they acknowledged your request, usually sent in response to OK the initial page. (10-4)'); + this.local.codeDict.set('265', 'Sender is requesting that you check your email.'); + this.local.codeDict.set('411', 'Sender is requesting information/counsel from you.'); + this.local.codeDict.set('419', 'Sender didn\'t recognize your request.'); + this.local.codeDict.set('555', 'Sender is requesting that you contact them.'); + this.local.codeDict.set('556', 'Sender is requesting that you contact them via DMs.'); + } + + public async run(message: Message, args: string[]) { + try { + if (!args[0]) { + this.client.commands.get('help').run(message, [this.name]); + const embed = new RichEmbed(); + embed.setTitle('Special Emergency/Department Numbers & Pager Codes'); + embed.addField('Special Emergency Numbers', '`#0` | Broadcast - all Staff/Associates\n`#1` | Authoritative Broadcast - all Directors, Supervisors, Technicians, and Moderators\n`#2` | Systems Administrators/Technicians Broadcast - Matthew, Bsian, NightRaven, and all Technicians\n`#3` | Community/Moderation Team Broadcast - all Directors, Supervisors, Moderators, and Core Team'); + embed.addField('Department Numbers', '`00` | Board of Directors\n`01` | Supervisors\n`10` | Technicians\n`20` | Moderators\n`21` | Core Team\n`22` | Associates'); + embed.addField('Pager Codes', '"Pager" term in this field refers to the Staff member that initially paged. This is a list of valid codes you can send via a page.\n\n`911` - Pager is requesting EMERGENCY assistance\n`811` - Pager is requesting immediate/ASAP assistance\n`210` - Pager is informing you they acknowledged your request, usually sent in response to OK the initial page.\n`265` - Pager is requesting that you check your email\n`411` - Pager is requesting information/counsel from you\n`419` - Pager didn\'t recognize your request\n`555` - Pager is requesting that you contact them\n`556` - Pager is requesting that you contact them via DMs'); + embed.setFooter(this.client.user.username, this.client.user.avatarURL); + embed.setTimestamp(); + return message.channel.createMessage({ embed }); + } + message.delete(); + const loading = await this.loading(message.channel, 'Paging...'); + const sender = await this.client.db.PagerNumber.findOne({ individualAssignID: message.author.id }); + const page = await this.page(args[0], sender.num, args[1], message, args[2] ? args.slice(2).join(' ') : undefined); + if (page.status === true) { + loading.delete(); + return this.success(message.channel, page.message); + } + loading.delete(); + return this.error(message.channel, page.message); + } catch (err) { + return this.client.util.handleError(err, message, this); + } + } + + public logPage(sender: { number: string, user?: string }, recipient: { number: string, user?: string }, type: 'discord' | 'email', code: string): void { + const chan = this.client.guilds.get(this.client.config.guildID).channels.get('722636436716781619'); + chan.createMessage(`***[${type.toUpperCase()}] \`${sender.number} (${sender.user ? sender.user : ''})\` sent a page to \`${recipient.number} (${recipient.user ? recipient.user : ''})\` with code \`${code}\`.***`); + this.client.util.signale.log(`PAGE (${type.toUpperCase()})| TO: ${recipient.number}, FROM: ${sender.number}, CODE: ${code}`); + } + + public async page(recipientNumber: string, senderNumber: string, code: string, message: Message, txt?: string, options?: { emergencyNumber: string }): Promise<{status: boolean, message: string}> { + try { + if (txt?.length >= 140) return { status: false, message: 'Your message must be less than 141 characters.' }; + const senderEntry = await this.client.db.PagerNumber.findOne({ num: senderNumber }); + if (!senderEntry) { + return { status: false, message: 'You do not have a Pager Number.' }; + } + if (this.local.emergencyNumbers.includes(recipientNumber)) { + switch (recipientNumber) { + case '#0': + this.local.departmentNumbers.forEach(async (num) => { + await this.page(num, senderNumber, code, message, txt, { emergencyNumber: '0' }); + }); + break; + case '#1': + await this.page('00', senderNumber, code, message, txt, { emergencyNumber: '0' }); + await this.page('01', senderNumber, code, message, txt, { emergencyNumber: '0' }); + await this.page('10', senderNumber, code, message, txt, { emergencyNumber: '0' }); + await this.page('20', senderNumber, code, message, txt, { emergencyNumber: '0' }); + break; + case '#2': + const matthew = await this.client.db.PagerNumber.findOne({ individualAssignID: '278620217221971968' }); + const bsian = await this.client.db.PagerNumber.findOne({ individualAssignID: '253600545972027394' }); + const nightraven = await this.client.db.PagerNumber.findOne({ individualAssignID: '239261547959025665' }); + await this.page(matthew?.num, senderNumber, code, message, txt, { emergencyNumber: '0' }); + await this.page(bsian?.num, senderNumber, code, message, txt, { emergencyNumber: '0' }); + await this.page(nightraven?.num, senderNumber, code, message, txt, { emergencyNumber: '0' }); + await this.page('10', senderNumber, code, message, txt, { emergencyNumber: '0' }); + break; + case '#3': + await this.page('00', senderNumber, code, message, txt, { emergencyNumber: '0' }); + await this.page('01', senderNumber, code, message, txt, { emergencyNumber: '0' }); + await this.page('20', senderNumber, code, message, txt, { emergencyNumber: '0' }); + await this.page('21', senderNumber, code, message, txt, { emergencyNumber: '0' }); + break; + default: + break; + } + return { status: true, message: `Page to \`${recipientNumber}\` sent.` }; + } + const recipientEntry = await this.client.db.PagerNumber.findOne({ num: recipientNumber }); + if (!recipientEntry) { + return { status: false, message: `Pager Number \`${recipientNumber}\` does not exist.` }; + } + if (!this.local.validPagerCodes.includes(code)) { + return { status: false, message: 'The Pager Code you provided is invalid.' }; + } + + for (const id of recipientEntry.discordIDs) { + const recipient = this.client.guilds.get(this.client.config.guildID).members.get(recipientEntry.individualAssignID); + const sender = this.client.guilds.get(this.client.config.guildID).members.get(senderEntry.individualAssignID); + const chan = await this.client.getDMChannel(id); + if (!chan) continue; + if (!recipient || !sender) { + this.logPage({ number: senderNumber, user: 'N/A' }, { number: recipientNumber, user: 'N/A' }, 'discord', code); + } else { + this.logPage({ number: senderNumber, user: `${sender.username}#${sender.discriminator}` }, { number: recipientNumber, user: `${recipient.username}#${recipient.discriminator}` }, 'discord', code); + } + chan.createMessage(`${options?.emergencyNumber ? `[SEN#${options.emergencyNumber}] ` : ''}__**Page**__\n**Recipient PN:** ${recipientNumber}\n**Sender PN:** ${senderNumber} (${sender ? `${sender.username}#${sender.discriminator}` : ''})\n**Initial Command:** https://discordapp.com/channels/${message.guild.id}/${message.channel.id}/${message.id} (<#${message.channel.id}>)\n\n**Pager Code:** ${code} (${this.local.codeDict.get(code)})${txt ? `\n**Message:** ${txt}` : ''}`); + } + for (const email of recipientEntry.emailAddresses) { + const recipient = this.client.guilds.get(this.client.config.guildID).members.get(recipientEntry.individualAssignID); + const sender = this.client.guilds.get(this.client.config.guildID).members.get(senderEntry.individualAssignID); + if (!recipient || !sender) { + this.logPage({ number: senderNumber, user: 'N/A' }, { number: recipientNumber, user: 'N/A' }, 'email', code); + } else { + this.logPage({ number: senderNumber, user: `${sender.username}#${sender.discriminator}` }, { number: recipientNumber, user: `${recipient.username}#${recipient.discriminator}` }, 'email', code); + } + await this.client.util.transporter.sendMail({ + from: '"LOC Paging System" ', + to: email, + subject: `PAGE FROM ${recipientNumber}`, + html: `

Page

${options?.emergencyNumber ? `

[SEN#${options.emergencyNumber}]` : ''}Recipient PN: ${recipientNumber}
Sender PN: ${senderNumber} (${sender ? `${sender.username}#${sender.discriminator}` : ''})
Initial Command: https://discordapp.com/channels/${message.guild.id}/${message.channel.id}/${message.id} (<#${message.channel.id}>)

Pager Code: ${code} (${this.local.codeDict.get(code)})${txt ? `
Message: ${txt}` : ''}`, + }); + } + return { status: true, message: `Page to \`${recipientNumber}\` sent.` }; + } catch (err) { + this.client.util.signale.error(err); + return { status: false, message: `Error during Processing: ${err}` }; + } + } +} diff --git a/src/commands/ping.ts b/src/commands/ping.ts index 6f20184..1845d2f 100644 --- a/src/commands/ping.ts +++ b/src/commands/ping.ts @@ -1,23 +1,23 @@ -import { Message } from 'eris'; -import { Client, Command } from '../class'; - -export default class Ping extends Command { - constructor(client: Client) { - super(client); - this.name = 'ping'; - this.description = 'Pings the bot'; - this.usage = 'ping'; - this.permissions = 0; - this.enabled = true; - } - - public async run(message: Message) { - try { - const clientStart: number = Date.now(); - const msg: Message = await message.channel.createMessage('🏓 Pong!'); - msg.edit(`🏓 Pong!\nClient: \`${Date.now() - clientStart}ms\`\nResponse: \`${msg.createdAt - message.createdAt}ms\``); - } catch (err) { - this.client.util.handleError(err, message, this); - } - } -} +import { Message } from 'eris'; +import { Client, Command } from '../class'; + +export default class Ping extends Command { + constructor(client: Client) { + super(client); + this.name = 'ping'; + this.description = 'Pings the bot'; + this.usage = 'ping'; + this.permissions = 0; + this.enabled = true; + } + + public async run(message: Message) { + try { + const clientStart: number = Date.now(); + const msg: Message = await message.channel.createMessage('🏓 Pong!'); + msg.edit(`🏓 Pong!\nClient: \`${Date.now() - clientStart}ms\`\nResponse: \`${msg.createdAt - message.createdAt}ms\``); + } catch (err) { + this.client.util.handleError(err, message, this); + } + } +} diff --git a/src/commands/roleinfo.ts b/src/commands/roleinfo.ts index 59ed6b4..aff53e8 100644 --- a/src/commands/roleinfo.ts +++ b/src/commands/roleinfo.ts @@ -1,60 +1,60 @@ -import moment from 'moment'; -import { Message, Role } from 'eris'; -import { Client, Command, RichEmbed } from '../class'; - -export default class Roleinfo extends Command { - constructor(client: Client) { - super(client); - this.name = 'roleinfo'; - this.description = 'Get information about a role.'; - this.usage = 'roleinfo [role ID or role name]'; - this.permissions = 0; - this.guildOnly = true; - this.enabled = true; - } - - public async run(message: Message, args: string[]) { - try { - if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); - - let role: Role = message.guild.roles.find((r: Role) => r.id === args[0]); - if (!role) { // if it's a role name - role = message.guild.roles.find((r: Role) => r.name.toLowerCase().includes(args.join(' ').toLowerCase())); - } - if (!role) return this.error(message.channel, 'Could not find role.'); - - const perms = role.permissions; - const permsArray: string[] = []; - if (perms.has('administrator')) permsArray.push('Administrator'); - if (perms.has('manageGuild')) permsArray.push('Manage Server'); - if (perms.has('manageChannels')) permsArray.push('Manage Channels'); - if (perms.has('manageRoles')) permsArray.push('Manage Roles'); - if (perms.has('manageMessages')) permsArray.push('Manage Messages'); - if (perms.has('manageNicknames')) permsArray.push('Manage Nicknames'); - if (perms.has('manageEmojis')) permsArray.push('Manage Emojis'); - if (perms.has('banMembers')) permsArray.push('Ban Members'); - if (perms.has('kickMembers')) permsArray.push('Kick Members'); - - const embed = new RichEmbed(); - embed.setTitle('Role Information'); - embed.setDescription(`<@&${role.id}> ID: \`${role.id}\``); - embed.setColor(role.color); - embed.addField('Name', role.name, true); - embed.addField('Color', role.color ? this.client.util.decimalToHex(role.color) : 'None', true); - embed.addField('Members', String(this.client.guilds.get(this.client.config.guildID).members.filter((m) => m.roles.includes(role.id)).length), true); - embed.addField('Hoisted', role.hoist ? 'Yes' : 'No', true); - embed.addField('Position', String(role.position), true); - embed.addField('Creation Date', `${moment(new Date(role.createdAt)).format('dddd, MMMM Do YYYY, h:mm:ss A')} ET`, true); - embed.addField('Mentionable', role.mentionable ? 'Yes' : 'No', true); - embed.setFooter(this.client.user.username, this.client.user.avatarURL); - embed.setTimestamp(); - - if (permsArray.length > 0) { - embed.addField('Permissions', permsArray.join(', '), true); - } - return message.channel.createMessage({ embed }); - } catch (err) { - return this.client.util.handleError(err, message, this); - } - } -} +import moment from 'moment'; +import { Message, Role } from 'eris'; +import { Client, Command, RichEmbed } from '../class'; + +export default class Roleinfo extends Command { + constructor(client: Client) { + super(client); + this.name = 'roleinfo'; + this.description = 'Get information about a role.'; + this.usage = 'roleinfo [role ID or role name]'; + this.permissions = 0; + this.guildOnly = true; + this.enabled = true; + } + + public async run(message: Message, args: string[]) { + try { + if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); + + let role: Role = message.guild.roles.find((r: Role) => r.id === args[0]); + if (!role) { // if it's a role name + role = message.guild.roles.find((r: Role) => r.name.toLowerCase().includes(args.join(' ').toLowerCase())); + } + if (!role) return this.error(message.channel, 'Could not find role.'); + + const perms = role.permissions; + const permsArray: string[] = []; + if (perms.has('administrator')) permsArray.push('Administrator'); + if (perms.has('manageGuild')) permsArray.push('Manage Server'); + if (perms.has('manageChannels')) permsArray.push('Manage Channels'); + if (perms.has('manageRoles')) permsArray.push('Manage Roles'); + if (perms.has('manageMessages')) permsArray.push('Manage Messages'); + if (perms.has('manageNicknames')) permsArray.push('Manage Nicknames'); + if (perms.has('manageEmojis')) permsArray.push('Manage Emojis'); + if (perms.has('banMembers')) permsArray.push('Ban Members'); + if (perms.has('kickMembers')) permsArray.push('Kick Members'); + + const embed = new RichEmbed(); + embed.setTitle('Role Information'); + embed.setDescription(`<@&${role.id}> ID: \`${role.id}\``); + embed.setColor(role.color); + embed.addField('Name', role.name, true); + embed.addField('Color', role.color ? this.client.util.decimalToHex(role.color) : 'None', true); + embed.addField('Members', String(this.client.guilds.get(this.client.config.guildID).members.filter((m) => m.roles.includes(role.id)).length), true); + embed.addField('Hoisted', role.hoist ? 'Yes' : 'No', true); + embed.addField('Position', String(role.position), true); + embed.addField('Creation Date', `${moment(new Date(role.createdAt)).format('dddd, MMMM Do YYYY, h:mm:ss A')} ET`, true); + embed.addField('Mentionable', role.mentionable ? 'Yes' : 'No', true); + embed.setFooter(this.client.user.username, this.client.user.avatarURL); + embed.setTimestamp(); + + if (permsArray.length > 0) { + embed.addField('Permissions', permsArray.join(', '), true); + } + return message.channel.createMessage({ embed }); + } catch (err) { + return this.client.util.handleError(err, message, this); + } + } +} diff --git a/src/commands/unban.ts b/src/commands/unban.ts index 1bcfc9d..0fd7777 100644 --- a/src/commands/unban.ts +++ b/src/commands/unban.ts @@ -1,37 +1,37 @@ -import { Message, User } from 'eris'; -import { Client, Command } from '../class'; - -export default class Unban extends Command { - constructor(client: Client) { - super(client); - this.name = 'unban'; - this.description = 'Unbans a member from the guild.'; - this.usage = 'unban [reason]'; - this.permissions = 3; - this.guildOnly = true; - this.enabled = true; - } - - public async run(message: Message, args: string[]) { - try { - if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); - let user: User; - try { - user = await this.client.getRESTUser(args[0]); - } catch { - return this.error(message.channel, 'Could find find user.'); - } - try { - await message.guild.getBan(args[0]); - } catch { - return this.error(message.channel, 'This user is not banned.'); - } - message.delete(); - - await this.client.util.moderation.unban(user.id, message.member, args.slice(1).join(' ')); - return this.success(message.channel, `${user.username}#${user.discriminator} has been unbanned.`); - } catch (err) { - return this.client.util.handleError(err, message, this, false); - } - } -} +import { Message, User } from 'eris'; +import { Client, Command } from '../class'; + +export default class Unban extends Command { + constructor(client: Client) { + super(client); + this.name = 'unban'; + this.description = 'Unbans a member from the guild.'; + this.usage = 'unban [reason]'; + this.permissions = 3; + this.guildOnly = true; + this.enabled = true; + } + + public async run(message: Message, args: string[]) { + try { + if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); + let user: User; + try { + user = await this.client.getRESTUser(args[0]); + } catch { + return this.error(message.channel, 'Could find find user.'); + } + try { + await message.guild.getBan(args[0]); + } catch { + return this.error(message.channel, 'This user is not banned.'); + } + message.delete(); + + await this.client.util.moderation.unban(user.id, message.member, args.slice(1).join(' ')); + return this.success(message.channel, `${user.username}#${user.discriminator} has been unbanned.`); + } catch (err) { + return this.client.util.handleError(err, message, this, false); + } + } +} diff --git a/src/commands/whois.ts b/src/commands/whois.ts index b4ee0cf..abe7891 100644 --- a/src/commands/whois.ts +++ b/src/commands/whois.ts @@ -1,197 +1,197 @@ -/* eslint-disable no-bitwise */ -import moment from 'moment'; -import { Message, Member } from 'eris'; -import { Client, Command, RichEmbed } from '../class'; -import acknowledgements from '../configs/acknowledgements.json'; -import { whois as emotes } from '../configs/emotes.json'; - -export default class Whois extends Command { - constructor(client: Client) { - super(client); - this.name = 'whois'; - this.description = 'Provides information on a member.'; - this.usage = 'whois [member]'; - this.permissions = 0; - this.guildOnly = true; - this.enabled = true; - } - - public async run(message: Message, args: string[]) { - try { - let member: Member; - if (!args[0]) member = message.member; - else { - member = this.client.util.resolveMember(args.join(' '), message.guild); - } - - if (!member) { - return this.error(message.channel, 'Member not found.'); - } - const embed = new RichEmbed(); - embed.setAuthor(`${member.user.username}#${member.user.discriminator}`, member.user.avatarURL); - embed.setThumbnail(member.avatarURL); - const ackResolve = this.resolveStaffInformation(member.id); - let description = ''; - let titleAndDepartment = ''; - if (ackResolve?.title && ackResolve?.dept) { - titleAndDepartment += `${emotes.titleAndDepartment} __**${ackResolve.title}**__, __${ackResolve.dept}__\n\n`; - } else if (ackResolve?.dept) { - titleAndDepartment += `${emotes.titleAndDepartment} __${ackResolve.dept}__\n\n`; - } - if (titleAndDepartment.length > 0) description += titleAndDepartment; - if (ackResolve?.emailAddress) { - description += `${emotes.email} ${ackResolve.emailAddress}\n`; - } - const pager = await this.client.db.PagerNumber.findOne({ individualAssignID: member.user.id }).lean().exec(); - if (pager?.num) { - description += `📡 ${pager.num}\n`; - } - if (ackResolve?.gitlab) { - description += `${emotes.gitlab} ${ackResolve.gitlab}\n`; - } - if (ackResolve?.github) { - description += `${emotes.github} ${ackResolve.github}\n`; - } - if (ackResolve?.bio) { - description += `${emotes.bio} *${ackResolve.bio}*\n`; - } - description += `\n<@${member.id}>`; - embed.setDescription(description); - - for (const role of member.roles.map((r) => message.guild.roles.get(r)).sort((a, b) => b.position - a.position)) { - if (role?.color !== 0) { - embed.setColor(role.color); - break; - } - } - embed.addField('Status', member.status === 'dnd' ? 'Do Not Disturb' : this.capsFirstLetter(member.status) || 'Unknown', true); - // const platform = member.bot && member.status !== 'offline' ? 'API/WebSocket' : Object.entries(message.member.clientStatus).filter((a) => a[1] !== 'offline').map((a) => this.capsFirstLetter(a[0])).join(', '); - // if (platform) embed.addField('Platform', platform, true); - embed.addField('Joined At', `${moment(new Date(member.joinedAt)).format('dddd, MMMM Do YYYY, h:mm:ss A')} ET`, true); - embed.addField('Created At', `${moment(new Date(member.user.createdAt)).format('dddd, MMMM Do YYYY, h:mm:ss A')} ET`, true); - if (member.roles.length > 0) { - embed.addField(`Roles [${member.roles.length}]`, member.roles.map((r) => message.guild.roles.get(r)).sort((a, b) => b.position - a.position).map((r) => `<@&${r.id}>`).join(', ')); - } - const permissions: string[] = []; - const serverAcknowledgements: string[] = []; - const bit = member.permission.allow; - if (message.guild.ownerID === member.id) serverAcknowledgements.push('Server Owner'); - if (bit & 8) { permissions.push('Administrator'); serverAcknowledgements.push('Server Admin'); } - if (bit & 32) { permissions.push('Manage Server'); serverAcknowledgements.push('Server Manager'); } - if (bit & 16) permissions.push('Manage Channels'); - if (bit & 268435456) permissions.push('Manage Roles'); - if (bit & 8192) { permissions.push('Manage Messages'); serverAcknowledgements.push('Server Moderator'); } - if (bit & 134217728) permissions.push('Manage Nicknames'); - if (bit & 1073741824) permissions.push('Manage Emojis'); - if (bit & 4) permissions.push('Ban Members'); - if (bit & 2) permissions.push('Kick Members'); - const account = await this.client.db.Member.findOne({ userID: member.id }).lean().exec(); - if (account?.additional?.langs?.length > 0) { - const langs: string[] = []; - for (const lang of account.additional.langs.sort((a, b) => a.localeCompare(b))) { - switch (lang) { - case 'asm': - langs.push('<:AssemblyLanguage:703448714248716442> Assembly Language'); - break; - case 'cfam': - langs.push('<:clang:553684262193332278> C/C++'); - break; - case 'csharp': - langs.push('<:csharp:553684277280112660> C#'); - break; - case 'go': - langs.push('<:Go:703449475405971466> Go'); - break; - case 'java': - langs.push('<:Java:703449725181100135> Java'); - break; - case 'js': - langs.push('<:JavaScriptECMA:703449987916496946> JavaScript'); - break; - case 'kt': - langs.push('<:Kotlin:703450201838321684> Kotlin'); - break; - case 'py': - langs.push('<:python:553682965482176513> Python'); - break; - case 'rb': - langs.push('<:ruby:604812470451699712> Ruby'); - break; - case 'rs': - langs.push('<:Rust:703450901960196206> Rust'); - break; - case 'swift': - langs.push('<:Swift:703451096093294672> Swift'); - break; - case 'ts': - langs.push('<:TypeScript:703451285789343774> TypeScript'); - break; - default: - break; - } - } - embed.addField('Known Languages', langs.join(', ')); - } - if (account?.additional?.operatingSystems?.length > 0) { - const operatingSystems: string[] = []; - for (const os of account.additional.operatingSystems.sort((a, b) => a.localeCompare(b))) { - switch (os) { - case 'arch': - operatingSystems.push('<:arch:707694976523304960> Arch'); - break; - case 'deb': - operatingSystems.push('<:debian:707695042617147589> Debian'); - break; - case 'cent': - operatingSystems.push('<:centos:707702165816213525> CentOS'); - break; - case 'fedora': - operatingSystems.push('<:fedora:707695073151680543> Fedora'); - break; - case 'manjaro': - operatingSystems.push('<:manjaro:707701473680556062> Manjaro'); - break; - case 'mdarwin': - operatingSystems.push('<:mac:707695427754917919> macOS'); - break; - case 'redhat': - operatingSystems.push('<:redhat:707695102159749271> RedHat Enterprise Linux'); - break; - case 'ubuntu': - operatingSystems.push('<:ubuntu:707695136888586300> Ubuntu'); - break; - case 'win': - operatingSystems.push('<:windows10:707695160259248208> Windows'); - break; - default: - break; - } - } - embed.addField('Used Operating Systems', operatingSystems.join(', ')); - } - if (permissions.length > 0) { - embed.addField('Permissions', permissions.join(', ')); - } - if (serverAcknowledgements.length > 0) { - embed.addField('Acknowledgements', serverAcknowledgements[0]); - } - if (ackResolve?.acknowledgements) { - embed.addField('Bot Acknowledgements', ackResolve.acknowledgements.join(', ')); - } - embed.setFooter(this.client.user.username, this.client.user.avatarURL); - embed.setTimestamp(); - return message.channel.createMessage({ embed }); - } catch (err) { - return this.client.util.handleError(err, message, this); - } - } - - public resolveStaffInformation(id: string) { - return acknowledgements.find((m) => m.id === id); - } - - public capsFirstLetter(string?: string): string | void { - if (typeof string !== 'string') return undefined; - return string.substring(0, 1).toUpperCase() + string.substring(1); - } -} +/* eslint-disable no-bitwise */ +import moment from 'moment'; +import { Message, Member } from 'eris'; +import { Client, Command, RichEmbed } from '../class'; +import acknowledgements from '../configs/acknowledgements.json'; +import { whois as emotes } from '../configs/emotes.json'; + +export default class Whois extends Command { + constructor(client: Client) { + super(client); + this.name = 'whois'; + this.description = 'Provides information on a member.'; + this.usage = 'whois [member]'; + this.permissions = 0; + this.guildOnly = true; + this.enabled = true; + } + + public async run(message: Message, args: string[]) { + try { + let member: Member; + if (!args[0]) member = message.member; + else { + member = this.client.util.resolveMember(args.join(' '), message.guild); + } + + if (!member) { + return this.error(message.channel, 'Member not found.'); + } + const embed = new RichEmbed(); + embed.setAuthor(`${member.user.username}#${member.user.discriminator}`, member.user.avatarURL); + embed.setThumbnail(member.avatarURL); + const ackResolve = this.resolveStaffInformation(member.id); + let description = ''; + let titleAndDepartment = ''; + if (ackResolve?.title && ackResolve?.dept) { + titleAndDepartment += `${emotes.titleAndDepartment} __**${ackResolve.title}**__, __${ackResolve.dept}__\n\n`; + } else if (ackResolve?.dept) { + titleAndDepartment += `${emotes.titleAndDepartment} __${ackResolve.dept}__\n\n`; + } + if (titleAndDepartment.length > 0) description += titleAndDepartment; + if (ackResolve?.emailAddress) { + description += `${emotes.email} ${ackResolve.emailAddress}\n`; + } + const pager = await this.client.db.PagerNumber.findOne({ individualAssignID: member.user.id }).lean().exec(); + if (pager?.num) { + description += `📡 ${pager.num}\n`; + } + if (ackResolve?.gitlab) { + description += `${emotes.gitlab} ${ackResolve.gitlab}\n`; + } + if (ackResolve?.github) { + description += `${emotes.github} ${ackResolve.github}\n`; + } + if (ackResolve?.bio) { + description += `${emotes.bio} *${ackResolve.bio}*\n`; + } + description += `\n<@${member.id}>`; + embed.setDescription(description); + + for (const role of member.roles.map((r) => message.guild.roles.get(r)).sort((a, b) => b.position - a.position)) { + if (role?.color !== 0) { + embed.setColor(role.color); + break; + } + } + embed.addField('Status', member.status === 'dnd' ? 'Do Not Disturb' : this.capsFirstLetter(member.status) || 'Unknown', true); + // const platform = member.bot && member.status !== 'offline' ? 'API/WebSocket' : Object.entries(message.member.clientStatus).filter((a) => a[1] !== 'offline').map((a) => this.capsFirstLetter(a[0])).join(', '); + // if (platform) embed.addField('Platform', platform, true); + embed.addField('Joined At', `${moment(new Date(member.joinedAt)).format('dddd, MMMM Do YYYY, h:mm:ss A')} ET`, true); + embed.addField('Created At', `${moment(new Date(member.user.createdAt)).format('dddd, MMMM Do YYYY, h:mm:ss A')} ET`, true); + if (member.roles.length > 0) { + embed.addField(`Roles [${member.roles.length}]`, member.roles.map((r) => message.guild.roles.get(r)).sort((a, b) => b.position - a.position).map((r) => `<@&${r.id}>`).join(', ')); + } + const permissions: string[] = []; + const serverAcknowledgements: string[] = []; + const bit = member.permission.allow; + if (message.guild.ownerID === member.id) serverAcknowledgements.push('Server Owner'); + if (bit & 8) { permissions.push('Administrator'); serverAcknowledgements.push('Server Admin'); } + if (bit & 32) { permissions.push('Manage Server'); serverAcknowledgements.push('Server Manager'); } + if (bit & 16) permissions.push('Manage Channels'); + if (bit & 268435456) permissions.push('Manage Roles'); + if (bit & 8192) { permissions.push('Manage Messages'); serverAcknowledgements.push('Server Moderator'); } + if (bit & 134217728) permissions.push('Manage Nicknames'); + if (bit & 1073741824) permissions.push('Manage Emojis'); + if (bit & 4) permissions.push('Ban Members'); + if (bit & 2) permissions.push('Kick Members'); + const account = await this.client.db.Member.findOne({ userID: member.id }).lean().exec(); + if (account?.additional?.langs?.length > 0) { + const langs: string[] = []; + for (const lang of account.additional.langs.sort((a, b) => a.localeCompare(b))) { + switch (lang) { + case 'asm': + langs.push('<:AssemblyLanguage:703448714248716442> Assembly Language'); + break; + case 'cfam': + langs.push('<:clang:553684262193332278> C/C++'); + break; + case 'csharp': + langs.push('<:csharp:553684277280112660> C#'); + break; + case 'go': + langs.push('<:Go:703449475405971466> Go'); + break; + case 'java': + langs.push('<:Java:703449725181100135> Java'); + break; + case 'js': + langs.push('<:JavaScriptECMA:703449987916496946> JavaScript'); + break; + case 'kt': + langs.push('<:Kotlin:703450201838321684> Kotlin'); + break; + case 'py': + langs.push('<:python:553682965482176513> Python'); + break; + case 'rb': + langs.push('<:ruby:604812470451699712> Ruby'); + break; + case 'rs': + langs.push('<:Rust:703450901960196206> Rust'); + break; + case 'swift': + langs.push('<:Swift:703451096093294672> Swift'); + break; + case 'ts': + langs.push('<:TypeScript:703451285789343774> TypeScript'); + break; + default: + break; + } + } + embed.addField('Known Languages', langs.join(', ')); + } + if (account?.additional?.operatingSystems?.length > 0) { + const operatingSystems: string[] = []; + for (const os of account.additional.operatingSystems.sort((a, b) => a.localeCompare(b))) { + switch (os) { + case 'arch': + operatingSystems.push('<:arch:707694976523304960> Arch'); + break; + case 'deb': + operatingSystems.push('<:debian:707695042617147589> Debian'); + break; + case 'cent': + operatingSystems.push('<:centos:707702165816213525> CentOS'); + break; + case 'fedora': + operatingSystems.push('<:fedora:707695073151680543> Fedora'); + break; + case 'manjaro': + operatingSystems.push('<:manjaro:707701473680556062> Manjaro'); + break; + case 'mdarwin': + operatingSystems.push('<:mac:707695427754917919> macOS'); + break; + case 'redhat': + operatingSystems.push('<:redhat:707695102159749271> RedHat Enterprise Linux'); + break; + case 'ubuntu': + operatingSystems.push('<:ubuntu:707695136888586300> Ubuntu'); + break; + case 'win': + operatingSystems.push('<:windows10:707695160259248208> Windows'); + break; + default: + break; + } + } + embed.addField('Used Operating Systems', operatingSystems.join(', ')); + } + if (permissions.length > 0) { + embed.addField('Permissions', permissions.join(', ')); + } + if (serverAcknowledgements.length > 0) { + embed.addField('Acknowledgements', serverAcknowledgements[0]); + } + if (ackResolve?.acknowledgements) { + embed.addField('Bot Acknowledgements', ackResolve.acknowledgements.join(', ')); + } + embed.setFooter(this.client.user.username, this.client.user.avatarURL); + embed.setTimestamp(); + return message.channel.createMessage({ embed }); + } catch (err) { + return this.client.util.handleError(err, message, this); + } + } + + public resolveStaffInformation(id: string) { + return acknowledgements.find((m) => m.id === id); + } + + public capsFirstLetter(string?: string): string | void { + if (typeof string !== 'string') return undefined; + return string.substring(0, 1).toUpperCase() + string.substring(1); + } +}