From cfe5e65ed892cea71f19d219d5dfb2518ec65137 Mon Sep 17 00:00:00 2001 From: Bsian Date: Fri, 17 Apr 2020 03:56:52 +0100 Subject: [PATCH 01/42] Fix everything Matt please don't change the ECMA target --- package.json | 2 +- src/class/Collection.ts | 12 ++++++------ src/class/Command.ts | 14 +++++++++++++- src/class/Moderation.ts | 5 +++-- src/class/RichEmbed.ts | 27 ++++++++++++++++++--------- src/class/Util.ts | 32 +++++++++++++++++++++++--------- src/commands/ban.ts | 19 ++++++++----------- src/commands/eval.ts | 4 ++-- src/commands/game.ts | 11 +++++------ src/commands/roleinfo.ts | 24 +++++++++--------------- src/commands/unban.ts | 14 +++----------- src/commands/whois.ts | 30 +++++++++++++----------------- src/events/ready.ts | 4 ++-- tsconfig.json | 2 +- 14 files changed, 107 insertions(+), 93 deletions(-) diff --git a/package.json b/package.json index 81eb46a..0fbd1f2 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ }, "dependencies": { "axios": "^0.19.2", - "eris": "^0.11.2", + "eris": "abalabahaha/eris#dev", "moment": "^2.24.0", "mongoose": "^5.9.9", "signale": "^1.4.0", diff --git a/src/class/Collection.ts b/src/class/Collection.ts index 80120b4..044e12c 100644 --- a/src/class/Collection.ts +++ b/src/class/Collection.ts @@ -2,12 +2,12 @@ * Hold a bunch of something */ export default class Collection extends Map { - baseObject: any + baseObject: new (...args: any[]) => V; /** * Creates an instance of Collection */ - constructor(iterable: any[]|object = null) { + constructor(iterable: Iterable<[string, V]>|object = null) { if (iterable && iterable instanceof Array) { super(iterable); } else if (iterable && iterable instanceof Object) { @@ -33,8 +33,8 @@ export default class Collection extends Map { * { key: value, key: value, key: value } * ``` */ - toObject(): object { - const obj: object = {}; + toObject(): { [key: string]: V } { + const obj: { [key: string]: V } = {}; for (const [key, value] of this.entries()) { obj[key] = value; } @@ -90,7 +90,7 @@ export default class Collection extends Map { * Return all the objects that make the function evaluate true * @param func A function that takes an object and returns true if it matches */ - filter(func: Function): V[] { + filter(func: (value: V) => boolean): V[] { const arr = []; for (const item of this.values()) { if (func(item)) { @@ -104,7 +104,7 @@ export default class Collection extends Map { * Test if at least one element passes the test implemented by the provided function. Returns true if yes, or false if not. * @param func A function that takes an object and returns true if it matches */ - some(func: Function) { + some(func: (value: V) => boolean) { for (const item of this.values()) { if (func(item)) { return true; diff --git a/src/class/Command.ts b/src/class/Command.ts index 9a8fc92..2fa7faa 100644 --- a/src/class/Command.ts +++ b/src/class/Command.ts @@ -1,4 +1,4 @@ -import { Member, Message } from 'eris'; +import { Member, Message, TextableChannel } from 'eris'; import { Client } from '.'; export default class Command { @@ -68,4 +68,16 @@ export default class Command { return false; } } + + public error(channel: TextableChannel, text: string): Promise { + return channel.createMessage(`***${this.client.util.emojis.ERROR} ${text}***`); + } + + public success(channel: TextableChannel, text: string): Promise { + return channel.createMessage(`***${this.client.util.emojis.SUCCESS} ${text}***`); + } + + public loading(channel: TextableChannel, text: string): Promise { + return channel.createMessage(`***${this.client.util.emojis.LOADING} ${text}***`); + } } diff --git a/src/class/Moderation.ts b/src/class/Moderation.ts index 13ba195..71fcb22 100644 --- a/src/class/Moderation.ts +++ b/src/class/Moderation.ts @@ -41,13 +41,14 @@ export default class Moderation { } public async ban(user: User, moderator: Member, duration: number, reason?: string): Promise { + if (reason && reason.length > 512) throw new Error('Ban reason cannot be longer than 512 characters'); await this.client.guilds.get(this.client.config.guildID).banMember(user.id, 7, reason); const logID = uuid(); const mod = new ModerationModel({ userID: user.id, logID, moderatorID: moderator.id, - reason: reason ?? null, + reason: reason || null, type: 5, date: new Date(), }); @@ -89,7 +90,7 @@ export default class Moderation { userID, logID, moderatorID: moderator.id, - reason: reason ?? null, + reason: reason || null, type: 4, date: new Date(), }); diff --git a/src/class/RichEmbed.ts b/src/class/RichEmbed.ts index 4f95f3b..307f9c5 100644 --- a/src/class/RichEmbed.ts +++ b/src/class/RichEmbed.ts @@ -1,6 +1,20 @@ /* eslint-disable no-param-reassign */ -export default class RichEmbed { +export interface EmbedData { + title?: string + description?: string + url?: string + timestamp?: Date + color?: number + footer?: { text: string, icon_url?: string, proxy_icon_url?: string} + image?: { url: string, proxy_url?: string, height?: number, width?: number } + thumbnail?: { url: string, proxy_url?: string, height?: number, width?: number } + video?: { url: string, height?: number, width?: number } + author?: { name: string, url?: string, proxy_icon_url?: string, icon_url?: string} + fields?: {name: string, value: string, inline?: boolean}[] +} + +export default class RichEmbed implements EmbedData { title?: string type?: string @@ -17,7 +31,7 @@ export default class RichEmbed { image?: { url: string, proxy_url?: string, height?: number, width?: number } - thumbnail?: { url?: string, proxy_url?: string, height?: number, width?: number } + thumbnail?: { url: string, proxy_url?: string, height?: number, width?: number } video?: { url: string, height?: number, width?: number } @@ -27,12 +41,7 @@ export default class RichEmbed { fields?: {name: string, value: string, inline?: boolean}[] - constructor(data: { - title?: string, type?: string, description?: string, url?: string, timestamp?: Date, color?: number, fields?: {name: string, value: string, inline?: boolean}[] - footer?: { text: string, icon_url?: string, proxy_icon_url?: string}, image?: { url: string, proxy_url?: string, height?: number, width?: number }, - thumbnail?: { url: string, proxy_url?: string, height?: number, width?: number }, video?: { url: string, height?: number, width?: number }, - provider?: { name: string, url?: string}, author?: { name: string, url?: string, proxy_icon_url?: string, icon_url?: string}, - } = {}) { + constructor(data: EmbedData = {}) { /* let types: { title?: string, type?: string, description?: string, url?: string, timestamp?: Date, color?: number, fields?: {name: string, value: string, inline?: boolean}[] @@ -79,7 +88,7 @@ export default class RichEmbed { setURL(url: string) { if (typeof url !== 'string') throw new TypeError('RichEmbed URLs must be a string.'); if (!url.startsWith('http://') || !url.startsWith('https://')) url = `https://${url}`; - this.url = url; + this.url = encodeURI(url); return this; } diff --git a/src/class/Util.ts b/src/class/Util.ts index 1c6d3e9..f31a4ca 100644 --- a/src/class/Util.ts +++ b/src/class/Util.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-bitwise */ import signale from 'signale'; import { Member, Message, Guild, PrivateChannel, GroupChannel, Role, AnyGuildChannel } from 'eris'; import { Client, Command, Moderation, RichEmbed } from '.'; @@ -50,19 +51,23 @@ export default class Util { } } - public resolveGuildChannel(query: string, { channels }: Guild): AnyGuildChannel | undefined { - const nchannels = channels.map((c) => c).sort((a: AnyGuildChannel, b: AnyGuildChannel) => a.type - b.type); - return nchannels.find((c) => (c.id === query || c.name === query || c.name.toLowerCase() === query.toLowerCase() || c.name.toLowerCase().startsWith(query.toLowerCase()))); + public resolveGuildChannel(query: string, { channels }: Guild, categories = false): AnyGuildChannel | undefined { + const ch: AnyGuildChannel[] = channels.filter((c) => (!categories ? c.type !== 4 : true)); + return ch.find((c) => c.id === query.replace(/[<#>]/g, '') || c.name === query) + || ch.find((c) => c.name.toLowerCase() === query.toLowerCase()) + || ch.find((c) => c.name.toLowerCase().startsWith(query.toLowerCase())); } public resolveRole(query: string, { roles }: Guild): Role | undefined { - return roles.find((r) => r.id === query || r.name === query || r.name.toLowerCase() === query.toLowerCase() || r.name.toLowerCase().startsWith(query.toLowerCase())); + return roles.find((r) => r.id === query.replace(/[<@&>]/g, '') || r.name === query) + || roles.find((r) => r.name.toLowerCase() === query.toLowerCase()) + || roles.find((r) => r.name.toLowerCase().startsWith(query.toLowerCase())); } public resolveMember(query: string, { members }: Guild): Member | undefined { - return members.find((m) => m.mention.replace('!', '') === query.replace('!', '') || `${m.username}#${m.discriminator}` === query || m.username === query || m.id === query || m.nick === query) // Exact match for mention, username+discrim, username and user ID - || members.find((m) => `${m.username.toLowerCase()}#${m.discriminator}` === query.toLowerCase() || m.username.toLowerCase() === query.toLowerCase() || (m.nick && m.nick.toLowerCase() === query.toLowerCase())) // Case insensitive match for username+discrim, username - || members.find((m) => m.username.toLowerCase().startsWith(query.toLowerCase()) || (m.nick && m.nick.toLowerCase().startsWith(query.toLowerCase()))); + return members.find((m) => `${m.username}#${m.discriminator}` === query || m.username === query || m.id === query.replace(/[<@!>]/g, '') || m.nick === query) // Exact match for mention, username+discrim, username and user ID + || members.find((m) => `${m.username.toLowerCase()}#${m.discriminator}` === query.toLowerCase() || m.username.toLowerCase() === query.toLowerCase() || (m.nick && m.nick.toLowerCase() === query.toLowerCase())) // Case insensitive match for username+discrim, username + || members.find((m) => m.username.toLowerCase().startsWith(query.toLowerCase()) || (m.nick && m.nick.toLowerCase().startsWith(query.toLowerCase()))); } public async handleError(error: Error, message?: Message, command?: Command, disable?: boolean): Promise { @@ -85,10 +90,10 @@ export default class Util { info.embed = embed; } await this.client.createMessage('595788220764127272', info); - const msg = message.content.slice(this.client.config.prefix.length).trim().split(/ +/g); + const msg = message ? message.content.slice(this.client.config.prefix.length).trim().split(/ +/g) : []; // eslint-disable-next-line no-param-reassign if (command && disable) this.resolveCommand(msg).then((c) => { c.cmd.enabled = false; }); - if (message) message.channel.createMessage(`***${this.emojis.ERROR} An unexpected error has occured - please contact a Faculty Marshal.${command ? ' This command has been disabled.' : ''}***`); + if (message) message.channel.createMessage(`***${this.emojis.ERROR} An unexpected error has occured - please contact a Faculty Marshal.${command && disable ? ' This command has been disabled.' : ''}***`); } catch (err) { this.signale.error(err); } @@ -112,4 +117,13 @@ export default class Util { } return arrayString; } + + public decimalToHex(int: number): string { + const red = (int && 0x0000ff) << 16; + const green = int && 0x00ff00; + const blue = (int && 0xff0000) >>> 16; + const number = red | green | blue; + const asHex = number.toString(16); + return '#000000'.substring(0, 7 - asHex.length) + asHex; + } } diff --git a/src/commands/ban.ts b/src/commands/ban.ts index 4562e1d..d6977f7 100644 --- a/src/commands/ban.ts +++ b/src/commands/ban.ts @@ -1,5 +1,5 @@ import moment, { unitOfTime } from 'moment'; -import { Message, User } from 'eris'; +import { Message, User, PrivateChannel, GroupChannel } from 'eris'; import { Client, Command } from '../class'; export default class Ban extends Command { @@ -15,24 +15,20 @@ export default class Ban extends Command { public async run(message: Message, args: string[]) { try { - // @ts-ignore - const member = this.client.util.resolveMember(args[0], message.channel.guild); + const member = this.client.util.resolveMember(args[0], message.member.guild); let user: User; if (!member) { try { user = await this.client.getRESTUser(args[0]); } catch { - return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Cannot find user.***`); + return this.error(message.channel, 'Cannot find user.'); } } try { await this.client.guilds.get(this.client.config.guildID).getBan(args[0]); - return message.channel.createMessage(`***${this.client.util.emojis.ERROR} This user is already banned.***`); - } catch { - // eslint-disable-next-line no-unused-expressions - undefined; - } - if (member && !this.client.util.moderation.checkPermissions(member, message.member)) return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Permission denied.***`); + 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; @@ -43,9 +39,10 @@ export default class Ban extends Command { 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 message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} ${user.username}#${user.id} has been banned.***`); + return this.success(message.channel, `${user.username}#${user.id} has been banned.`); } catch (err) { return this.client.util.handleError(err, message, this, false); } diff --git a/src/commands/eval.ts b/src/commands/eval.ts index 6e78ba1..f62fc7a 100644 --- a/src/commands/eval.ts +++ b/src/commands/eval.ts @@ -54,9 +54,9 @@ export default class Eval extends Command { if (display[5]) { try { const { data } = await axios.post('https://snippets.cloud.libraryofcode.org/documents', display.join('')); - return message.channel.createMessage(`${this.client.util.emojis.SUCCESS} Your evaluation evaled can be found on https://snippets.cloud.libraryofcode.org/${data.key}`); + return this.success(message.channel, `Your evaluation evaled can be found on https://snippets.cloud.libraryofcode.org/${data.key}`); } catch (error) { - return message.channel.createMessage(`${this.client.util.emojis.ERROR} ${error}`); + return this.error(message.channel, `${error}`); } } diff --git a/src/commands/game.ts b/src/commands/game.ts index a8f82a3..f1d18d2 100644 --- a/src/commands/game.ts +++ b/src/commands/game.ts @@ -1,5 +1,5 @@ /* eslint-disable prefer-destructuring */ -import { Activity, Member, Message } from 'eris'; +import { Activity, Member, Message, PrivateChannel, GroupChannel } from 'eris'; import { Client, Command, RichEmbed } from '../class'; export default class Game extends Command { @@ -19,10 +19,9 @@ export default class Game extends Command { let member: Member; if (!args[0]) member = message.member; else { - // @ts-ignore - member = this.client.util.resolveMember(message, args[0], message.channel.guild); + member = this.client.util.resolveMember(args.join(' '), message.member.guild); if (!member) { - return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Member not found.***`); + return this.error(message.channel, 'Member not found.'); } } if (member.activities.length <= 0) return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Cannot find a game for this member.***`); @@ -35,7 +34,7 @@ export default class Game extends Command { mainStatus = member.activities[0]; } embed.setAuthor(member.user.username, member.user.avatarURL); - if (mainStatus?.name === 'Spotify') { + if (mainStatus.type === 4) { embed.setTitle('Spotify'); embed.setColor('#1ed760'); embed.addField('Song', mainStatus.details, true); @@ -51,7 +50,7 @@ export default class Game extends Command { 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 message.channel.createMessage(`***${this.client.util.emojis.ERROR} Only Spotify games are supported at this time.***`); + return this.error(message.channel, 'Only Spotify games are supported at this time.'); } return message.channel.createMessage({ embed }); } catch (err) { diff --git a/src/commands/roleinfo.ts b/src/commands/roleinfo.ts index 673c705..574a7d0 100644 --- a/src/commands/roleinfo.ts +++ b/src/commands/roleinfo.ts @@ -14,19 +14,13 @@ export default class Roleinfo extends Command { public async run(message: Message, args: string[]) { try { - if (!args[0]) return message.channel.createMessage(`***${this.client.util.emojis.ERROR} You need to specifiy a role ID or a role name.***`); + if (!args[0]) return this.error(message.channel, 'You need to specifiy a role ID or a role name.'); - // @ts-ignore - let role: Role = message.channel.guild.roles.find((r: Role) => r.id === args[0]); + let role: Role = message.member.guild.roles.find((r: Role) => r.id === args[0]); if (!role) { // if it's a role name - // @ts-ignore - role = message.channel.guild.roles.find((r: Role) => r.name.toLowerCase().includes(args.join(' ').toLowerCase())); + role = message.member.guild.roles.find((r: Role) => r.name.toLowerCase().includes(args.join(' ').toLowerCase())); } - if (!role) return this.client.createMessage(message.channel.id, `***${this.client.util.emojis.ERROR} Could not find role.***`); - - const ms = role.createdAt; - const date = new Date(ms).toLocaleDateString('en-us'); - const time = new Date(ms).toLocaleTimeString('en-us'); + if (!role) return this.error(message.channel, 'Could not find role.'); const perms = role.permissions; const permsArray: string[] = []; @@ -45,11 +39,11 @@ export default class Roleinfo extends Command { embed.setDescription(`<@&${role.id}> ID: \`${role.id}\``); embed.setColor(role.color); embed.addField('Name', role.name, true); - embed.addField('Color', `#${role.color.toString(16)}`, true); - embed.addField('Hoisted', role.hoist.toString(), true); - embed.addField('Position', role.position.toString(), true); - embed.addField('Creation Date', `${date} ${time}`, true); - embed.addField('Mentionnable', role.mentionable.toString(), true); + embed.addField('Color', role.color ? this.client.util.decimalToHex(role.color) : 'None', true); + embed.addField('Hoisted', role.hoist ? 'Yes' : 'No', true); + embed.addField('Position', role.position ? 'Yes' : 'No', true); + embed.addField('Creation Date', new Date(role.createdAt).toLocaleString(), true); + embed.addField('Mentionable', role.mentionable ? 'Yes' : 'No', true); embed.setFooter(this.client.user.username, this.client.user.avatarURL); embed.setTimestamp(); diff --git a/src/commands/unban.ts b/src/commands/unban.ts index 34efd89..025758c 100644 --- a/src/commands/unban.ts +++ b/src/commands/unban.ts @@ -14,29 +14,21 @@ export default class Unban extends Command { public async run(message: Message, args: string[]) { try { - // @ts-ignore let user: User; try { user = await this.client.getRESTUser(args[0]); } catch { - return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Could find find user.***`); - } - try { - if (await this.client.getRESTGuildMember(this.client.config.guildID, args[0])) return message.channel.createMessage(`***${this.client.util.emojis.ERROR} This member exists in the server.***`); - } catch { - // eslint-disable-next-line no-unused-expressions - undefined; + return this.error(message.channel, 'Could find find user.'); } try { await this.client.guilds.get(this.client.config.guildID).getBan(args[0]); } catch { - return message.channel.createMessage(`***${this.client.util.emojis.ERROR} This user is not banned.***`); + return this.error(message.channel, 'This user is not banned.'); } - if (!user) return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Unable to locate user.***`); message.delete(); await this.client.util.moderation.unban(user.id, message.member, args.slice(1).join(' ')); - return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} ${user.username}#${user.discriminator} has been unbanned.***`); + 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 4c65a3e..e5be07b 100644 --- a/src/commands/whois.ts +++ b/src/commands/whois.ts @@ -1,6 +1,6 @@ /* eslint-disable no-bitwise */ import moment from 'moment'; -import { Message, Member } from 'eris'; +import { Message, Member, PrivateChannel, GroupChannel } from 'eris'; import { Client, Command, RichEmbed } from '../class'; import acknowledgements from '../configs/acknowledgements.json'; import { whois as emotes } from '../configs/emotes.json'; @@ -21,11 +21,11 @@ export default class Whois extends Command { let member: Member; if (!args[0]) member = message.member; else { - // @ts-ignore - member = this.client.util.resolveMember(args.join(' '), message.channel.guild); - if (!member) { - return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Member not found.***`); - } + member = this.client.util.resolveMember(args.join(' '), message.member.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); @@ -58,18 +58,15 @@ export default class Whois extends Command { } description += `\n<@${member.id}>`; embed.setDescription(description); - // @ts-ignore - for (const role of member.roles.map((r) => message.channel.guild.roles.get(r)).sort((a, b) => b.position - a.position)) { - if (role.color !== 0) { - embed.setColor(role.color); - break; - } - } + + const roles = member.roles.map((r) => message.member.guild.roles.get(r)).sort((a, b) => b.position - a.position); + + const { color } = roles.find((r) => r.color); + embed.setColor(color); embed.addField('Status', `${member.status[0].toUpperCase()}${member.status.slice(1)}`, true); embed.addField('Joined At', `${moment(new Date(message.member.joinedAt)).format('dddd, MMMM Do YYYY, h:mm:ss A')} ET`, true); embed.addField('Created At', `${moment(new Date(message.author.createdAt)).format('dddd, MMMM Do YYYY, h:mm:ss A')} ET`, true); - // @ts-ignore - embed.addField(`Roles [${member.roles.length}]`, member.roles.map((r) => message.channel.guild.roles.get(r)).sort((a, b) => b.position - a.position).map((r) => `<@&${r.id}>`).join(', ')); + embed.addField(`Roles [${roles.length}]`, roles.map((r) => `<@&${r.id}>`).join(', ')); const permissions: string[] = []; const serverAcknowledgements: string[] = []; const bit = member.permission.allow; @@ -101,7 +98,6 @@ export default class Whois extends Command { } public resolveStaffInformation(id: string) { - const ack = acknowledgements.find((m) => m.id === id); - return ack; + return acknowledgements.find((m) => m.id === id); } } diff --git a/src/events/ready.ts b/src/events/ready.ts index 142f42b..908e189 100644 --- a/src/events/ready.ts +++ b/src/events/ready.ts @@ -16,8 +16,8 @@ export default class { this.client.util.handleError(err); process.exit(1); }); - process.on('unhandledRejection', (err) => { - this.client.util.handleError(new Error(err.toString())); + process.on('unhandledRejection', (err: Error) => { + this.client.util.handleError(err); }); } } diff --git a/tsconfig.json b/tsconfig.json index 251319b..fc5e133 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { /* Basic Options */ // "incremental": true, /* Enable incremental compilation */ - "target": "ES2017", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ + "target": "ES2020", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ -- 2.20.1 From 99ef533121903cd3281535c2bb9457bba2cf3b63 Mon Sep 17 00:00:00 2001 From: Bsian Date: Fri, 17 Apr 2020 04:07:33 +0100 Subject: [PATCH 02/42] Remove optional chaining --- src/commands/whois.ts | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/commands/whois.ts b/src/commands/whois.ts index e5be07b..495e64a 100644 --- a/src/commands/whois.ts +++ b/src/commands/whois.ts @@ -41,20 +41,22 @@ export default class Whois extends Command { embed.setThumbnail(member.avatarURL); const ackResolve = this.resolveStaffInformation(member.id); let description = ''; - if (ackResolve?.title && ackResolve?.dept) { - description += `${emotes.titleAndDepartment} __**${ackResolve.title}**__, ${ackResolve.dept}\n\n`; - } - if (ackResolve?.emailAddress) { - description += `${emotes.email} ${ackResolve.emailAddress}\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`; + if (ackResolve) { + if (ackResolve.title && ackResolve.dept) { + description += `${emotes.titleAndDepartment} __**${ackResolve.title}**__, ${ackResolve.dept}\n\n`; + } + if (ackResolve.emailAddress) { + description += `${emotes.email} ${ackResolve.emailAddress}\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); @@ -86,7 +88,7 @@ export default class Whois extends Command { if (serverAcknowledgements.length > 0) { embed.addField('Acknowledgements', serverAcknowledgements[0]); } - if (ackResolve?.acknowledgements) { + if (ackResolve && ackResolve.acknowledgements) { embed.addField('Bot Acknowledgements', ackResolve.acknowledgements.join(', ')); } embed.setFooter(this.client.user.username, this.client.user.avatarURL); -- 2.20.1 From c72d5c1f1b1ed66fde8233b445957d4b3ac22909 Mon Sep 17 00:00:00 2001 From: Bsian Date: Fri, 17 Apr 2020 04:27:46 +0100 Subject: [PATCH 03/42] Add activity type enum --- src/commands/game.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/commands/game.ts b/src/commands/game.ts index f1d18d2..f7bd914 100644 --- a/src/commands/game.ts +++ b/src/commands/game.ts @@ -1,7 +1,15 @@ /* eslint-disable prefer-destructuring */ -import { Activity, Member, Message, PrivateChannel, GroupChannel } from 'eris'; +import { Activity, Member, Message } from 'eris'; import { Client, Command, RichEmbed } from '../class'; +enum ActivityType { + PLAYING = 0, + STREAMING = 1, + LISTENING = 2, + WATCHING = 3, + CUSTOM_STATUS = 4 +} + export default class Game extends Command { constructor(client: Client) { super(client); @@ -27,14 +35,14 @@ export default class Game extends Command { if (member.activities.length <= 0) return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Cannot find a game for this member.***`); const embed = new RichEmbed(); let mainStatus: Activity; - if (member.activities[0].type === 4) { + 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 === 4) { + if (mainStatus.type === ActivityType.LISTENING) { embed.setTitle('Spotify'); embed.setColor('#1ed760'); embed.addField('Song', mainStatus.details, true); -- 2.20.1 From f35317c43cce65f4a1ff0b57f91c072f418234fe Mon Sep 17 00:00:00 2001 From: Bsian Date: Fri, 17 Apr 2020 04:29:17 +0100 Subject: [PATCH 04/42] Remove imports --- src/commands/ban.ts | 2 +- src/commands/whois.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/ban.ts b/src/commands/ban.ts index d6977f7..a5afa43 100644 --- a/src/commands/ban.ts +++ b/src/commands/ban.ts @@ -1,5 +1,5 @@ import moment, { unitOfTime } from 'moment'; -import { Message, User, PrivateChannel, GroupChannel } from 'eris'; +import { Message, User } from 'eris'; import { Client, Command } from '../class'; export default class Ban extends Command { diff --git a/src/commands/whois.ts b/src/commands/whois.ts index 495e64a..e6bdad9 100644 --- a/src/commands/whois.ts +++ b/src/commands/whois.ts @@ -1,6 +1,6 @@ /* eslint-disable no-bitwise */ import moment from 'moment'; -import { Message, Member, PrivateChannel, GroupChannel } from 'eris'; +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'; -- 2.20.1 From 41cd6869f52cab70cdc7777395310b0387f2cdad Mon Sep 17 00:00:00 2001 From: Bsian Date: Fri, 17 Apr 2020 04:35:56 +0100 Subject: [PATCH 05/42] Use error function --- src/commands/game.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/game.ts b/src/commands/game.ts index f7bd914..6d1aa68 100644 --- a/src/commands/game.ts +++ b/src/commands/game.ts @@ -32,7 +32,7 @@ export default class Game extends Command { return this.error(message.channel, 'Member not found.'); } } - if (member.activities.length <= 0) return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Cannot find a game for this member.***`); + 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) { -- 2.20.1 From 178aa9f37b3c9d99a21aa4d06020f7f7a5843bff Mon Sep 17 00:00:00 2001 From: Bsian Date: Fri, 17 Apr 2020 15:17:04 +0100 Subject: [PATCH 06/42] Conflict --- package.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/package.json b/package.json index 322f8ad..bf1c286 100644 --- a/package.json +++ b/package.json @@ -22,11 +22,7 @@ }, "dependencies": { "axios": "^0.19.2", -<<<<<<< HEAD - "eris": "abalabahaha/eris#dev", -======= "eris": "bsian03/eris#bsian", ->>>>>>> dev "moment": "^2.24.0", "mongoose": "^5.9.9", "signale": "^1.4.0", -- 2.20.1 From 6cf4f9c8e3f91a90c76a1a5601e121f97247b091 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Wed, 22 Apr 2020 14:45:49 -0400 Subject: [PATCH 07/42] perms fix (@dedshot) --- src/class/Command.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/class/Command.ts b/src/class/Command.ts index 7fc00f5..7a2e5c5 100644 --- a/src/class/Command.ts +++ b/src/class/Command.ts @@ -68,8 +68,10 @@ export default class Command { case 4: return member.roles.some((r) => ['701454780828221450', '701454855952138300', '662163685439045632'].includes(r)); case 5: - return member.roles.some((r) => ['701454855952138300', '662163685439045632'].includes(r)); + return member.roles.some((r) => ['455972169449734144', '701454780828221450', '701454855952138300', '662163685439045632'].includes(r)); case 6: + return member.roles.some((r) => ['701454855952138300', '662163685439045632'].includes(r)); + case 7: return member.roles.includes('662163685439045632'); default: return false; -- 2.20.1 From cd6a10480b3a4542c9627df7d6fdb92187570c5e Mon Sep 17 00:00:00 2001 From: Matthew R Date: Fri, 24 Apr 2020 18:57:56 -0400 Subject: [PATCH 08/42] platform information in whois cmd --- src/commands/whois.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/commands/whois.ts b/src/commands/whois.ts index ece051c..8ca5ff0 100644 --- a/src/commands/whois.ts +++ b/src/commands/whois.ts @@ -68,6 +68,15 @@ export default class Whois extends Command { } } embed.addField('Status', `${member.status[0].toUpperCase()}${member.status.slice(1)}`, true); + if (member.bot) { + embed.addField('Platform', 'API/WebSocket', true); + } else if (member.clientStatus.web) { + embed.addField('Platform', 'Web', true); + } else if (member.clientStatus.desktop) { + embed.addField('Platform', 'Desktop', true); + } else if (member.clientStatus.mobile) { + embed.addField('Platform', 'Mobile', 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) { -- 2.20.1 From 9ddc800e2a30f60600fa700e01eb460deb084ef1 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Fri, 24 Apr 2020 23:46:29 -0400 Subject: [PATCH 09/42] add new Member model --- src/class/Client.ts | 6 +++--- src/models/Member.ts | 17 +++++++++++++++++ src/models/index.ts | 1 + 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 src/models/Member.ts diff --git a/src/class/Client.ts b/src/class/Client.ts index 589ff0f..29212bb 100644 --- a/src/class/Client.ts +++ b/src/class/Client.ts @@ -2,7 +2,7 @@ import eris from 'eris'; import mongoose from 'mongoose'; import { promises as fs } from 'fs'; import { Collection, Command, Util } from '.'; -import { Moderation, ModerationInterface } from '../models'; +import { Member, MemberInterface, Moderation, ModerationInterface } from '../models'; export default class Client extends eris.Client { public config: { token: string, prefix: string, guildID: string, mongoDB: string }; @@ -13,14 +13,14 @@ export default class Client extends eris.Client { public util: Util; - public db: { moderation: mongoose.Model }; + public db: { member: mongoose.Model, moderation: mongoose.Model }; // eslint-disable-next-line @typescript-eslint/no-useless-constructor constructor(token: string, options?: eris.ClientOptions) { super(token, options); this.commands = new Collection(); this.intervals = new Collection(); - this.db = { moderation: Moderation }; + this.db = { member: Member, moderation: Moderation }; } public async loadDatabase() { diff --git a/src/models/Member.ts b/src/models/Member.ts new file mode 100644 index 0000000..f8c496b --- /dev/null +++ b/src/models/Member.ts @@ -0,0 +1,17 @@ +import { Document, Schema, model } from 'mongoose'; + +export interface MemberInterface extends Document { + userID: string + additional: { + langs: ['js', 'py', 'rb', 'ts', 'rs', 'go', 'cfam', 'csharp', 'swift', 'java', 'kt', 'asm'], + }, +} + +const Member: Schema = new Schema({ + userID: String, + additional: { + langs: Array, + }, +}); + +export default model('Member', Member); diff --git a/src/models/index.ts b/src/models/index.ts index a149275..81202ce 100644 --- a/src/models/index.ts +++ b/src/models/index.ts @@ -1 +1,2 @@ +export { default as Member, MemberInterface } from './Member'; export { default as Moderation, ModerationInterface } from './Moderation'; -- 2.20.1 From 07951e289f705aa5c45cb0906d6d1cebaae17067 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Fri, 24 Apr 2020 23:46:43 -0400 Subject: [PATCH 10/42] fix typo in roleinfo (@dedshot) --- src/commands/roleinfo.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/roleinfo.ts b/src/commands/roleinfo.ts index 9fc6052..a617ec3 100644 --- a/src/commands/roleinfo.ts +++ b/src/commands/roleinfo.ts @@ -15,7 +15,7 @@ export default class Roleinfo extends Command { public async run(message: Message, args: string[]) { try { - if (!args[0]) return this.error(message.channel, 'You need to specifiy a role ID or a role name.'); + if (!args[0]) return this.error(message.channel, 'You need to specify a role ID or a role name.'); let role: Role = this.client.guilds.get(this.client.config.guildID).roles.find((r: Role) => r.id === args[0]); if (!role) { // if it's a role name -- 2.20.1 From ebdb1671e22f7e3b02ca4bf6fb36e5e36326b735 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Fri, 24 Apr 2020 23:46:54 -0400 Subject: [PATCH 11/42] add command to add known langs --- src/commands/additem.ts | 45 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/commands/additem.ts diff --git a/src/commands/additem.ts b/src/commands/additem.ts new file mode 100644 index 0000000..f99d524 --- /dev/null +++ b/src/commands/additem.ts @@ -0,0 +1,45 @@ +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.setFooter(this.client.user.username, this.client.user.avatarURL); + embed.setTimestamp(); + return message.channel.createMessage({ embed }); + } + if (['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) { + // eslint-disable-next-line new-cap + const newAccount = new this.client.db.member({ + userID: message.member.id, + additional: { + langs: [args[0].split('-')[1]], + }, + }); + await newAccount.save(); + return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Added langauge code ${args[0]} to profile.***`); + } + await account.updateOne({ $addToSet: { 'additional.langs': args[0].split('-')[1] } }); + return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Added langauge code ${args[0]} to profile.***`); + } + return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Invalid language code.***`); + } catch (err) { + return this.client.util.handleError(err, message, this); + } + } +} -- 2.20.1 From f052fa76058f2753bf9c069101b3f3e2bdf9ba00 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Fri, 24 Apr 2020 23:47:07 -0400 Subject: [PATCH 12/42] add known languages list to whois --- src/commands/whois.ts | 44 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/commands/whois.ts b/src/commands/whois.ts index 8ca5ff0..172afaf 100644 --- a/src/commands/whois.ts +++ b/src/commands/whois.ts @@ -95,6 +95,50 @@ export default class Whois extends Command { if ((bit | 1073741824) === bit) permissions.push('Manage Emojis'); if ((bit | 4) === bit) permissions.push('Ban Members'); if ((bit | 2) === bit) permissions.push('Kick Members'); + const account = await this.client.db.member.findOne({ userID: member.id }); + if (account?.additional?.langs.length > 0) { + const langs: string[] = []; + for (const lang of account.additional.langs) { + switch (lang) { + case 'asm': + langs.push('<:AssemblyLanguage:703448714248716442> Assembly Language'); + break; + case 'cfam': + langs.push('<:clang:553684262193332278> C/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 (permissions.length > 0) { embed.addField('Permissions', permissions.join(', ')); } -- 2.20.1 From 3edcebae4362a183195f2677ad066cace5250b02 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Sat, 25 Apr 2020 00:01:40 -0400 Subject: [PATCH 13/42] fix issue with whois platform --- src/commands/whois.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/commands/whois.ts b/src/commands/whois.ts index 172afaf..96b9de5 100644 --- a/src/commands/whois.ts +++ b/src/commands/whois.ts @@ -70,11 +70,11 @@ export default class Whois extends Command { embed.addField('Status', `${member.status[0].toUpperCase()}${member.status.slice(1)}`, true); if (member.bot) { embed.addField('Platform', 'API/WebSocket', true); - } else if (member.clientStatus.web) { + } else if (member.clientStatus.web === 'online' || member.clientStatus.web === 'idle' || member.clientStatus.web === 'dnd') { embed.addField('Platform', 'Web', true); - } else if (member.clientStatus.desktop) { + } else if (member.clientStatus.desktop === 'online' || member.clientStatus.desktop === 'idle' || member.clientStatus.desktop === 'dnd') { embed.addField('Platform', 'Desktop', true); - } else if (member.clientStatus.mobile) { + } else if (member.clientStatus.mobile === 'online' || member.clientStatus.mobile === 'idle' || member.clientStatus.mobile === 'dnd') { embed.addField('Platform', 'Mobile', true); } embed.addField('Joined At', `${moment(new Date(member.joinedAt)).format('dddd, MMMM Do YYYY, h:mm:ss A')} ET`, true); -- 2.20.1 From b44289f51e76e3caf269cfb565e4e26ade6778ae Mon Sep 17 00:00:00 2001 From: Matthew R Date: Sat, 25 Apr 2020 00:09:40 -0400 Subject: [PATCH 14/42] delitem cmd --- src/commands/delitem.ts | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/commands/delitem.ts diff --git a/src/commands/delitem.ts b/src/commands/delitem.ts new file mode 100644 index 0000000..d62bff1 --- /dev/null +++ b/src/commands/delitem.ts @@ -0,0 +1,37 @@ +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.setFooter(this.client.user.username, this.client.user.avatarURL); + embed.setTimestamp(); + return message.channel.createMessage({ embed }); + } + if (['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 || !account?.additional.langs || 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 langauge code ${args[0]} to profile.***`); + } + return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Invalid language code.***`); + } catch (err) { + return this.client.util.handleError(err, message, this); + } + } +} -- 2.20.1 From 2488c52c9adae42373de4c90da8a7074a4101bc2 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Sat, 25 Apr 2020 00:32:45 -0400 Subject: [PATCH 15/42] fix typos --- src/commands/additem.ts | 4 ++-- src/commands/delitem.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/commands/additem.ts b/src/commands/additem.ts index f99d524..666489d 100644 --- a/src/commands/additem.ts +++ b/src/commands/additem.ts @@ -32,10 +32,10 @@ export default class AddItem extends Command { }, }); await newAccount.save(); - return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Added langauge code ${args[0]} to profile.***`); + return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Added language code ${args[0]} to profile.***`); } await account.updateOne({ $addToSet: { 'additional.langs': args[0].split('-')[1] } }); - return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Added langauge code ${args[0]} to profile.***`); + 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 language code.***`); } catch (err) { diff --git a/src/commands/delitem.ts b/src/commands/delitem.ts index d62bff1..cf802d2 100644 --- a/src/commands/delitem.ts +++ b/src/commands/delitem.ts @@ -27,7 +27,7 @@ export default class DelItem extends Command { 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 langauge code ${args[0]} to profile.***`); + return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Removed language code ${args[0]} to profile.***`); } return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Invalid language code.***`); } catch (err) { -- 2.20.1 From 2bb92ccabc7a98e8529c77d238ca42867ee58bee Mon Sep 17 00:00:00 2001 From: Matthew R Date: Sat, 25 Apr 2020 00:32:56 -0400 Subject: [PATCH 16/42] info command --- src/commands/info.ts | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/commands/info.ts diff --git a/src/commands/info.ts b/src/commands/info.ts new file mode 100644 index 0000000..278c9f9 --- /dev/null +++ b/src/commands/info.ts @@ -0,0 +1,34 @@ +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 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('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); + } + } +} -- 2.20.1 From aff0d0650267387158b29f79dcbf83de5ee0f614 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Sat, 25 Apr 2020 00:33:08 -0400 Subject: [PATCH 17/42] add missing c# case in switch statement --- src/commands/whois.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/commands/whois.ts b/src/commands/whois.ts index 96b9de5..00ffdd8 100644 --- a/src/commands/whois.ts +++ b/src/commands/whois.ts @@ -106,6 +106,9 @@ export default class Whois extends Command { 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; -- 2.20.1 From 74d50b192f7b42deb7fee47f33e08dd65a459caf Mon Sep 17 00:00:00 2001 From: Matthew R Date: Sat, 25 Apr 2020 00:39:47 -0400 Subject: [PATCH 18/42] sort whois langs alphabetical order --- src/commands/whois.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/whois.ts b/src/commands/whois.ts index 00ffdd8..3c5f13f 100644 --- a/src/commands/whois.ts +++ b/src/commands/whois.ts @@ -98,7 +98,7 @@ export default class Whois extends Command { const account = await this.client.db.member.findOne({ userID: member.id }); if (account?.additional?.langs.length > 0) { const langs: string[] = []; - for (const lang of account.additional.langs) { + for (const lang of account.additional.langs.sort((a, b) => a.localeCompare(b))) { switch (lang) { case 'asm': langs.push('<:AssemblyLanguage:703448714248716442> Assembly Language'); -- 2.20.1 From e037b89fbf53d85f08420e51ece7de4f76c513f7 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Sat, 25 Apr 2020 16:24:09 -0400 Subject: [PATCH 19/42] fixes for undefined platforms --- src/commands/whois.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/commands/whois.ts b/src/commands/whois.ts index 3c5f13f..c592a81 100644 --- a/src/commands/whois.ts +++ b/src/commands/whois.ts @@ -70,11 +70,11 @@ export default class Whois extends Command { embed.addField('Status', `${member.status[0].toUpperCase()}${member.status.slice(1)}`, true); if (member.bot) { embed.addField('Platform', 'API/WebSocket', true); - } else if (member.clientStatus.web === 'online' || member.clientStatus.web === 'idle' || member.clientStatus.web === 'dnd') { + } else if (member.clientStatus?.web === 'online' || member.clientStatus?.web === 'idle' || member.clientStatus?.web === 'dnd') { embed.addField('Platform', 'Web', true); - } else if (member.clientStatus.desktop === 'online' || member.clientStatus.desktop === 'idle' || member.clientStatus.desktop === 'dnd') { + } else if (member.clientStatus?.desktop === 'online' || member.clientStatus?.desktop === 'idle' || member.clientStatus?.desktop === 'dnd') { embed.addField('Platform', 'Desktop', true); - } else if (member.clientStatus.mobile === 'online' || member.clientStatus.mobile === 'idle' || member.clientStatus.mobile === 'dnd') { + } else if (member.clientStatus?.mobile === 'online' || member.clientStatus?.mobile === 'idle' || member.clientStatus?.mobile === 'dnd') { embed.addField('Platform', 'Mobile', true); } embed.addField('Joined At', `${moment(new Date(member.joinedAt)).format('dddd, MMMM Do YYYY, h:mm:ss A')} ET`, true); -- 2.20.1 From a3c82eaf13fda1f78e9f35959348f77bd271e3e4 Mon Sep 17 00:00:00 2001 From: hector6704 Date: Tue, 28 Apr 2020 15:24:44 +0200 Subject: [PATCH 20/42] add kick command and fix typo in .gitignore --- .gitignore | 2 +- src/class/Moderation.ts | 29 +++++++++++++++++++++++++++++ src/commands/kick.ts | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/commands/kick.ts diff --git a/.gitignore b/.gitignore index 99dbe56..196dea3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ # Package Management & Libraries node_modules yarn.lock -package-json.lock +package-lock.json # Configuration Files config.yaml diff --git a/src/class/Moderation.ts b/src/class/Moderation.ts index e7d3975..0f730d9 100644 --- a/src/class/Moderation.ts +++ b/src/class/Moderation.ts @@ -110,4 +110,33 @@ export default class Moderation { this.client.createMessage(this.logChannels.modlogs, { embed }); return mod.save(); } + + public async kick(user: User, moderator: Member, reason?: string): Promise { + if (reason && reason.length > 512) throw new Error('Kick reason cannot be longer than 512 characters'); + await this.client.guilds.get(this.client.config.guildID).kickMember(user.id, reason); + const logID = randomBytes(2).toString('hex'); + const mod = new ModerationModel({ + userID: user.id, + logID, + moderatorID: moderator.id, + reason: reason || null, + type: 5, + date: new Date(), + }); + + const embed = new RichEmbed(); + embed.setTitle(`Case ${logID} | Kick`); + embed.setColor('#e74c3c'); + embed.setAuthor(user.username, user.avatarURL); + embed.setThumbnail(user.avatarURL); + embed.addField('User', `<@${user.id}>`, true); + embed.addField('Moderator', `<@${moderator.id}>`, true); + if (reason) { + embed.addField('Reason', reason, true); + } + embed.setFooter(this.client.user.username, this.client.user.avatarURL); + embed.setTimestamp(); + this.client.createMessage(this.logChannels.modlogs, { embed }); + return mod.save(); + } } diff --git a/src/commands/kick.ts b/src/commands/kick.ts new file mode 100644 index 0000000..72e2574 --- /dev/null +++ b/src/commands/kick.ts @@ -0,0 +1,38 @@ +import moment, { unitOfTime } from 'moment'; +import { Message, User } 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 { + const member = this.client.util.resolveMember(args[0], this.client.guilds.get(this.client.config.guildID)); + let user: User; + if (!member) { + try { + user = await this.client.getRESTUser(args[0]); + } catch { + return this.error(message.channel, 'Cannot find user.'); + } + } + if (member && !this.client.util.moderation.checkPermissions(member, 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); + } + } +} -- 2.20.1 From 4e492dfe2a3175fa9051b59032cf69ad89d5756e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DedShot=E2=84=A2=239195?= Date: Thu, 30 Apr 2020 02:18:15 -0400 Subject: [PATCH 21/42] Added npm command --- src/commands/mdn.ts | 54 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/commands/mdn.ts diff --git a/src/commands/mdn.ts b/src/commands/mdn.ts new file mode 100644 index 0000000..cd5e084 --- /dev/null +++ b/src/commands/mdn.ts @@ -0,0 +1,54 @@ +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.error(message.channel, 'You need to specify a module name.'); + + const res = await axios.get(`https://registry.npmjs.com/${args[0]}`, { validateStatus: (_) => true }); + + if (res.status == 404) 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 || ''; + const license: string = data.license || 'None'; + const dependencies: string = Object.keys(data.versions[version].dependencies).join(', ') || 'None'; + 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.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); + } + } +} -- 2.20.1 From fa9eaf060be5a6a47ffc5a4aac70fb2bc70093b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DedShot=E2=84=A2=239195?= Date: Thu, 30 Apr 2020 02:34:15 -0400 Subject: [PATCH 22/42] Added timestamp and footer to the embed --- src/commands/mdn.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/commands/mdn.ts b/src/commands/mdn.ts index cd5e084..5ef7e3c 100644 --- a/src/commands/mdn.ts +++ b/src/commands/mdn.ts @@ -36,6 +36,8 @@ export default class Npm extends Command { 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); -- 2.20.1 From 1a98387fe6501739fd0b92d6b5875963964d7a1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DedShot=E2=84=A2=239195?= Date: Thu, 30 Apr 2020 02:35:04 -0400 Subject: [PATCH 23/42] changed file name from mdn to npm --- src/commands/{mdn.ts => npm.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/commands/{mdn.ts => npm.ts} (100%) diff --git a/src/commands/mdn.ts b/src/commands/npm.ts similarity index 100% rename from src/commands/mdn.ts rename to src/commands/npm.ts -- 2.20.1 From 5ffc3a5eb7e39ddc3c6cca858b3a5396dfa4e52e Mon Sep 17 00:00:00 2001 From: Matthew R Date: Thu, 30 Apr 2020 21:57:02 -0400 Subject: [PATCH 24/42] fixes to npm command --- src/commands/npm.ts | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/commands/npm.ts b/src/commands/npm.ts index 5ef7e3c..98a489f 100644 --- a/src/commands/npm.ts +++ b/src/commands/npm.ts @@ -2,7 +2,7 @@ import { Message } from 'eris'; import axios from 'axios'; import { Client, Command, RichEmbed } from '../class'; -export default class Npm extends Command { +export default class NPM extends Command { constructor(client: Client) { super(client); this.name = 'npm'; @@ -19,16 +19,24 @@ export default class Npm extends Command { const res = await axios.get(`https://registry.npmjs.com/${args[0]}`, { validateStatus: (_) => true }); - if (res.status == 404) this.error(message.channel, 'Could not find the library, try something else.'); + if (res.status === 404) this.error(message.channel, 'Could not find the library, try something else.'); const { data } = res; - const bugs: string = data.bugs.url || ''; + const bugs: string = data.bugs?.url || ''; const description: string = data.description || 'None'; - const version: string = data['dist-tags'].latest || 'Unknown'; + const version: string = data['dist-tags']?.latest || 'Unknown'; const homepage: string = data.homepage || ''; - const license: string = data.license || 'None'; - const dependencies: string = Object.keys(data.versions[version].dependencies).join(', ') || 'None'; + 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) { + 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'; @@ -39,7 +47,7 @@ export default class Npm extends Command { 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.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); -- 2.20.1 From d8c1e87b9cfdb623b10a045e6efebfe92dbadcf5 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Fri, 1 May 2020 00:41:13 -0400 Subject: [PATCH 25/42] fixes to whois perm calculations --- src/commands/whois.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/whois.ts b/src/commands/whois.ts index c592a81..80fde1a 100644 --- a/src/commands/whois.ts +++ b/src/commands/whois.ts @@ -87,8 +87,8 @@ export default class Whois extends Command { const bit = member.permission.allow; if (this.client.guilds.get(this.client.config.guildID).ownerID === member.id) serverAcknowledgements.push('Server Owner'); if ((bit | 8) === bit) { permissions.push('Administrator'); serverAcknowledgements.push('Server Admin'); } - if ((bit | 20) === bit) { permissions.push('Manage Server'); serverAcknowledgements.push('Server Manager'); } - if ((bit | 10) === bit) permissions.push('Manage Channels'); + if ((bit | 32) === bit) { permissions.push('Manage Server'); serverAcknowledgements.push('Server Manager'); } + if ((bit | 16) === bit) permissions.push('Manage Channels'); if ((bit | 268435456) === bit) permissions.push('Manage Roles'); if ((bit | 8192) === bit) { permissions.push('Manage Messages'); serverAcknowledgements.push('Server Moderator'); } if ((bit | 134217728) === bit) permissions.push('Manage Nicknames'); -- 2.20.1 From aff802cf766e3813d4e3835ad1ea899b3bdcbbf9 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Fri, 1 May 2020 00:41:29 -0400 Subject: [PATCH 26/42] acknowledgement changes --- src/configs/acknowledgements.json | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/configs/acknowledgements.json b/src/configs/acknowledgements.json index c7e92d3..7f124e1 100644 --- a/src/configs/acknowledgements.json +++ b/src/configs/acknowledgements.json @@ -57,6 +57,14 @@ "github": "https://github.com/TheSkele27", "bio": "Is water wet?" }, + { + "name": "Catbirby", + "id": "131953641371205632", + "title": "Supervisor", + "emailAddress": "catbirby@staff.libraryofcode.org", + "github": "https://github.com/catbirby", + "bio": "Computer Tech/Networking Nerd/Sysadmin/Graphic Designer/Audiophile. I don't do much coding but know my way around most languages." + }, { "name": "Besero", "id": "283318906024886272", @@ -121,9 +129,19 @@ { "name": "Ryan", "id": "186679073764802560", + "title": "Associate", + "emailAddress": "wbdvryan@staff.libraryofcode.org", "gitlab": "https://gitlab.libraryofcode.org/plainRyan", "acknowledgements": ["Contributor"] }, + { + "name": "Zloth", + "id": "382368885267234816", + "title": "Associate", + "emailAddress": "zloth@staff.libraryofcode.org", + "github": "https://github.com/gavintjhxx", + "bio": "Undergoing education, codes as a hobby" + }, { "name": "Null", "id": "323673862971588609", -- 2.20.1 From effad4c499156b28dae850f6fb8458392f68c688 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Fri, 1 May 2020 01:46:13 -0400 Subject: [PATCH 27/42] add help cmd --- Makefile | 2 +- package.json | 1 + src/class/Util.ts | 10 ++++ src/commands/help.ts | 116 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 src/commands/help.ts diff --git a/Makefile b/Makefile index b44d381..6bb691c 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ clean: @-rm -rf build build: - tsc -p ./tsconfig.json + -tsc -p ./tsconfig.json run: cd build && node main diff --git a/package.json b/package.json index bf1c286..31d1f91 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "dependencies": { "axios": "^0.19.2", "eris": "bsian03/eris#bsian", + "eris-pagination": "bsian03/eris-pagination#dev", "moment": "^2.24.0", "mongoose": "^5.9.9", "signale": "^1.4.0", diff --git a/src/class/Util.ts b/src/class/Util.ts index 10a0702..c0798c5 100644 --- a/src/class/Util.ts +++ b/src/class/Util.ts @@ -118,6 +118,16 @@ export default class Util { return arrayString; } + public splitFields(fields: { name: string, value: string, inline?: boolean }[]): { name: string, value: string, inline?: boolean }[][] { + let index = 0; + const array: {name: string, value: string, inline?: boolean}[][] = [[]]; + while (fields.length) { + if (array[index].length >= 25) { index += 1; array[index] = []; } + array[index].push(fields[0]); fields.shift(); + } + return array; + } + public decimalToHex(int: number): string { const hex = int.toString(16); return '#000000'.substring(0, 7 - hex.length) + hex; diff --git a/src/commands/help.ts b/src/commands/help.ts new file mode 100644 index 0000000..4c468d2 --- /dev/null +++ b/src/commands/help.ts @@ -0,0 +1,116 @@ +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; + } + + // eslint-disable-next-line consistent-return + 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) { + this.client.util.handleError(err, message, this); + } + } +} -- 2.20.1 From e309104a1b0717849d6d770ec8266069671020cf Mon Sep 17 00:00:00 2001 From: Matthew R Date: Fri, 1 May 2020 01:48:40 -0400 Subject: [PATCH 28/42] changes to help cmd --- src/commands/help.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/help.ts b/src/commands/help.ts index 4c468d2..0a46112 100644 --- a/src/commands/help.ts +++ b/src/commands/help.ts @@ -96,7 +96,7 @@ export default class Help extends Command { 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 }; + 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[] = []; -- 2.20.1 From 708a526a46af9822af3d4ac8c1be4bbf9bedca5f Mon Sep 17 00:00:00 2001 From: Matthew R Date: Fri, 1 May 2020 01:48:51 -0400 Subject: [PATCH 29/42] jsdoc changes on Command class --- src/class/Command.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/class/Command.ts b/src/class/Command.ts index 7a2e5c5..8a57e4b 100644 --- a/src/class/Command.ts +++ b/src/class/Command.ts @@ -28,9 +28,9 @@ export default class Command { * - **0:** Everyone * - **1:** Associates+ * - **2:** Core Team+ - * - **3:** Moderators, Supervisor, Board of Directors - * - **4:** Technicians, Supervisor, Board of Directors - * - **5:** Moderators, Technicians, Supervisor, Board of Directors + * - **3:** Moderators, Supervisor, & Board of Directors + * - **4:** Technicians, Supervisor, & Board of Directors + * - **5:** Moderators, Technicians, Supervisor, & Board of Directors * - **6:** Supervisor+ * - **7:** Board of Directors */ -- 2.20.1 From c10ec03ae6784f08de4e820cfa8e7c05fa838176 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Fri, 1 May 2020 01:50:57 -0400 Subject: [PATCH 30/42] npm cmd bug fixes --- src/commands/npm.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/npm.ts b/src/commands/npm.ts index 98a489f..fae9cff 100644 --- a/src/commands/npm.ts +++ b/src/commands/npm.ts @@ -19,7 +19,7 @@ export default class NPM extends Command { const res = await axios.get(`https://registry.npmjs.com/${args[0]}`, { validateStatus: (_) => true }); - if (res.status === 404) this.error(message.channel, 'Could not find the library, try something else.'); + if (res.status === 404) return this.error(message.channel, 'Could not find the library, try something else.'); const { data } = res; -- 2.20.1 From 5d597ca7c8749299798f3e0cd415f4308c83457d Mon Sep 17 00:00:00 2001 From: Matthew R Date: Fri, 1 May 2020 01:53:00 -0400 Subject: [PATCH 31/42] acknowledgements for ryan --- src/configs/acknowledgements.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/configs/acknowledgements.json b/src/configs/acknowledgements.json index 7f124e1..4d9eae4 100644 --- a/src/configs/acknowledgements.json +++ b/src/configs/acknowledgements.json @@ -132,6 +132,7 @@ "title": "Associate", "emailAddress": "wbdvryan@staff.libraryofcode.org", "gitlab": "https://gitlab.libraryofcode.org/plainRyan", + "bio": "Experiment, learn, share, repeat.", "acknowledgements": ["Contributor"] }, { -- 2.20.1 From d2d70bae0ec3ba579812b04c647ccbb5cae2132e Mon Sep 17 00:00:00 2001 From: Matthew R Date: Fri, 1 May 2020 01:58:08 -0400 Subject: [PATCH 32/42] matt bio change --- src/configs/acknowledgements.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/configs/acknowledgements.json b/src/configs/acknowledgements.json index 4d9eae4..f173976 100644 --- a/src/configs/acknowledgements.json +++ b/src/configs/acknowledgements.json @@ -6,7 +6,7 @@ "emailAddress": "matthew@staff.libraryofcode.org", "gitlab": "https://gitlab.libraryofcode.org/matthew", "github": "https://github.com/matthew119427", - "bio": "If you removed all the arteries, veins, & capillaries from a person’s body, and tied them end-to-end…the person will die. - Dr. Niel deGrasse Tyson", + "bio": "so baby come light me up, and baby ill let you on it. a little bit dangerous, but baby thats how i want it. a little less conversation and a little more touch my body. cuz im so into you... ~ Ariana Grande, Into You - Dangerous Woman", "acknowledgements": ["Maintainer & Lead Developer"] }, { -- 2.20.1 From 33fb4a24dfb176e9560009bb4bdaedb8f9633ea2 Mon Sep 17 00:00:00 2001 From: hector6704 Date: Fri, 1 May 2020 16:27:32 +0200 Subject: [PATCH 33/42] remove useless import --- src/commands/kick.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/commands/kick.ts b/src/commands/kick.ts index 72e2574..af1439c 100644 --- a/src/commands/kick.ts +++ b/src/commands/kick.ts @@ -1,4 +1,3 @@ -import moment, { unitOfTime } from 'moment'; import { Message, User } from 'eris'; import { Client, Command } from '../class'; -- 2.20.1 From 668064fbfdcec8aacf87612ad077f674b2022584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DedShot=E2=84=A2=239195?= Date: Fri, 1 May 2020 15:16:33 -0400 Subject: [PATCH 34/42] Fix npm command dependencies variable --- src/commands/npm.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/npm.ts b/src/commands/npm.ts index fae9cff..031d21b 100644 --- a/src/commands/npm.ts +++ b/src/commands/npm.ts @@ -34,7 +34,7 @@ export default class NPM extends Command { license = data.license; } let dependencies: string = 'None'; - if (version !== 'Unknown' && data.versions[version].dependencies) { + if (version !== 'Unknown' && data.versions[version].hasOwnProperty('dependencies') && Object.keys(data.versions[version].dependencies).length > 0) { dependencies = Object.keys(data.versions[version].dependencies).join(', '); } const name: string = data.name || 'None'; -- 2.20.1 From b814db8dd6d0e3df0d78388e9a1d410eede8e6e8 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Sat, 2 May 2020 21:03:34 -0400 Subject: [PATCH 35/42] fixes for command arguments --- src/commands/ban.ts | 1 + src/commands/npm.ts | 2 +- src/commands/roleinfo.ts | 2 +- src/commands/unban.ts | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/commands/ban.ts b/src/commands/ban.ts index e8e43d5..eee1893 100644 --- a/src/commands/ban.ts +++ b/src/commands/ban.ts @@ -15,6 +15,7 @@ export default class Ban extends Command { 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], this.client.guilds.get(this.client.config.guildID)); let user: User; if (!member) { diff --git a/src/commands/npm.ts b/src/commands/npm.ts index fae9cff..2ed756e 100644 --- a/src/commands/npm.ts +++ b/src/commands/npm.ts @@ -15,7 +15,7 @@ export default class NPM extends Command { public async run(message: Message, args: string[]) { try { - if (!args[0]) return this.error(message.channel, 'You need to specify a module name.'); + 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 }); diff --git a/src/commands/roleinfo.ts b/src/commands/roleinfo.ts index a617ec3..fb39158 100644 --- a/src/commands/roleinfo.ts +++ b/src/commands/roleinfo.ts @@ -15,7 +15,7 @@ export default class Roleinfo extends Command { public async run(message: Message, args: string[]) { try { - if (!args[0]) return this.error(message.channel, 'You need to specify a role ID or a role name.'); + if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); let role: Role = this.client.guilds.get(this.client.config.guildID).roles.find((r: Role) => r.id === args[0]); if (!role) { // if it's a role name diff --git a/src/commands/unban.ts b/src/commands/unban.ts index a0a4fbc..3eb0cae 100644 --- a/src/commands/unban.ts +++ b/src/commands/unban.ts @@ -14,6 +14,7 @@ export default class Unban extends Command { 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]); -- 2.20.1 From fbdc2e050baeb5da342318338f9b54641436aee5 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Sat, 2 May 2020 21:03:44 -0400 Subject: [PATCH 36/42] acknowledgements update --- src/configs/acknowledgements.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/configs/acknowledgements.json b/src/configs/acknowledgements.json index f173976..4f6c05f 100644 --- a/src/configs/acknowledgements.json +++ b/src/configs/acknowledgements.json @@ -105,7 +105,7 @@ { "name": "Hector", "id": "377781496292835339", - "title": "Associate", + "title": "Core Team", "emailAddress": "hector@staff.libraryofcode.org", "gitlab": "https://gitlab.libraryofcode.org/Hector", "github": "https://github.com/Hector6704", -- 2.20.1 From 777249a0affd37a9abb47b9f96c0277189075dac Mon Sep 17 00:00:00 2001 From: Matthew R Date: Sun, 3 May 2020 14:58:50 -0400 Subject: [PATCH 37/42] various changes to contributing guidelines --- CONTRIBUTING.md | 5 +++++ package.json | 3 +++ 2 files changed, 8 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c41473a..14e178b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,3 +9,8 @@ We accept contributions from the community, however there's a few steps you need ## Issues If you're interested in tackling an issue, please comment on that particular issue that you're handling it so Maintainers can label it appropriately. + +## Other Information +* Make sure your contributions match the current style of the code, run `yarn run lint` to find issues with the style. Requests will be denied if they do not comply with styling. +* Submit your merge requests to the **dev** branch only. +* If you can use TypeScript functionality, do it. For example, don't declare something as `any` if it can be typed. diff --git a/package.json b/package.json index 31d1f91..09b59aa 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,9 @@ "version": "1.0.0", "description": "The official system for handling Community Relations in the LOC Discord server.", "main": "build/main.js", + "scripts": { + "lint": "eslint -c ./.eslintrc.json src --ext ts" + }, "repository": "https://gitlab.libraryofcode.org/engineering/communityrelations.git", "author": "Matthew R ", "license": "AGPL-3.0", -- 2.20.1 From 62b4533f57a80e0f6b83940ab3f9b4493492d600 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Sun, 3 May 2020 14:59:27 -0400 Subject: [PATCH 38/42] return help on kick if no args specified --- src/commands/kick.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/commands/kick.ts b/src/commands/kick.ts index af1439c..45c3de4 100644 --- a/src/commands/kick.ts +++ b/src/commands/kick.ts @@ -14,6 +14,7 @@ export default class Kick extends Command { 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], this.client.guilds.get(this.client.config.guildID)); let user: User; if (!member) { -- 2.20.1 From 98c73ca2e909c8737cbd634c7dff6810644b1a40 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Sun, 3 May 2020 14:59:35 -0400 Subject: [PATCH 39/42] eslint ignore --- src/commands/npm.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/commands/npm.ts b/src/commands/npm.ts index e1a04b8..7cb8c74 100644 --- a/src/commands/npm.ts +++ b/src/commands/npm.ts @@ -34,6 +34,7 @@ export default class NPM extends Command { license = data.license; } let dependencies: string = 'None'; + // eslint-disable-next-line no-prototype-builtins if (version !== 'Unknown' && data.versions[version].hasOwnProperty('dependencies') && Object.keys(data.versions[version].dependencies).length > 0) { dependencies = Object.keys(data.versions[version].dependencies).join(', '); } -- 2.20.1 From 256ad170cb86b6d335eba262590e920c4f8e2641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DedShot=E2=84=A2=239195?= Date: Tue, 5 May 2020 08:51:20 -0400 Subject: [PATCH 40/42] Added discord.js docs command --- src/commands/djs.ts | 53 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/commands/djs.ts diff --git a/src/commands/djs.ts b/src/commands/djs.ts new file mode 100644 index 0000000..fde99d9 --- /dev/null +++ b/src/commands/djs.ts @@ -0,0 +1,53 @@ +import { Message } from 'eris'; +import axios 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]); + + return axios.get(`https://djsdocs.sorta.moe/v2/embed?src=master&q=${args[0]}`) + .then((res) => { + const { data } = res; + if (!data) return this.error(message.channel, 'Could not find information. Try something else.'); + + const name = data.author?.name || ''; + const icon_url = data.author?.icon_url || ''; + const author_url = data.author?.url || ''; + const description = data.description || 'None'; + const title = data.title || ''; + + const embed = new RichEmbed(); + embed.setAuthor(name, icon_url, author_url); + embed.setColor(0x2296f3); + embed.setTitle(title); + embed.setDescription(description); + if (data.fields !== undefined && data.fields.length > 0) { + data.fields.forEach((field) => { + embed.addField(field.name, field.value); + }); + } + embed.setFooter(this.client.user.username, this.client.user.avatarURL); + embed.setTimestamp(); + return message.channel.createMessage({ embed }); + }) + .catch((err) => { + this.error(message.channel, 'Please try again later, something unexpected happened.'); + this.client.util.handleError(err, message, this); + }); + } catch (err) { + return this.client.util.handleError(err, message, this); + } + } +} -- 2.20.1 From c1fe2de75a53bf11ad3fb8e298e82d8348ba2bca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DedShot=E2=84=A2=239195?= Date: Tue, 5 May 2020 09:36:40 -0400 Subject: [PATCH 41/42] defined variables type --- src/commands/djs.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/commands/djs.ts b/src/commands/djs.ts index fde99d9..129083e 100644 --- a/src/commands/djs.ts +++ b/src/commands/djs.ts @@ -22,11 +22,11 @@ export default class DJS extends Command { const { data } = res; if (!data) return this.error(message.channel, 'Could not find information. Try something else.'); - const name = data.author?.name || ''; - const icon_url = data.author?.icon_url || ''; - const author_url = data.author?.url || ''; - const description = data.description || 'None'; - const title = data.title || ''; + const name: string = data.author?.name || ''; + const icon_url: string = data.author?.icon_url || ''; + const author_url: string = data.author?.url || ''; + const description: string = data.description || 'None'; + const title: string = data.title || ''; const embed = new RichEmbed(); embed.setAuthor(name, icon_url, author_url); -- 2.20.1 From da7d68d7fbab370b184e668615a67fbf34cdb8df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DedShot=E2=84=A2=239195?= Date: Sat, 9 May 2020 22:01:51 -0400 Subject: [PATCH 42/42] used await instead of .then().catch() (KhaaZ) --- src/commands/djs.ts | 52 ++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/commands/djs.ts b/src/commands/djs.ts index 129083e..9060c82 100644 --- a/src/commands/djs.ts +++ b/src/commands/djs.ts @@ -17,35 +17,35 @@ export default class DJS extends Command { try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); - return axios.get(`https://djsdocs.sorta.moe/v2/embed?src=master&q=${args[0]}`) - .then((res) => { - const { data } = res; - if (!data) return this.error(message.channel, 'Could not find information. Try something else.'); + let res; + try { + res = await axios.get(`https://djsdocs.sorta.moe/v2/embed?src=master&q=${args[0]}`); + } catch (err) { + this.error(message.channel, 'Please try again later, something unexpected happened.'); + return this.client.util.handleError(err, message, this); + } + const { data } = res; + if (!data) return this.error(message.channel, 'Could not find information. Try something else.'); - const name: string = data.author?.name || ''; - const icon_url: string = data.author?.icon_url || ''; - const author_url: string = data.author?.url || ''; - const description: string = data.description || 'None'; - const title: string = data.title || ''; + const name: string = data.author?.name || ''; + const icon_url: string = data.author?.icon_url || ''; + const author_url: string = data.author?.url || ''; + const description: string = data.description || 'None'; + const title: string = data.title || ''; - const embed = new RichEmbed(); - embed.setAuthor(name, icon_url, author_url); - embed.setColor(0x2296f3); - embed.setTitle(title); - embed.setDescription(description); - if (data.fields !== undefined && data.fields.length > 0) { - data.fields.forEach((field) => { - embed.addField(field.name, field.value); - }); - } - embed.setFooter(this.client.user.username, this.client.user.avatarURL); - embed.setTimestamp(); - return message.channel.createMessage({ embed }); - }) - .catch((err) => { - this.error(message.channel, 'Please try again later, something unexpected happened.'); - this.client.util.handleError(err, message, this); + const embed = new RichEmbed(); + embed.setAuthor(name, icon_url, author_url); + embed.setColor(0x2296f3); + embed.setTitle(title); + embed.setDescription(description); + if (data.fields !== undefined && data.fields.length > 0) { + data.fields.forEach((field) => { + embed.addField(field.name, field.value); }); + } + 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); } -- 2.20.1