From 9dab377235822abc6b6d8b316593a55a25da8e29 Mon Sep 17 00:00:00 2001 From: Bsian Date: Fri, 17 Apr 2020 02:56:52 +0000 Subject: [PATCH 1/7] Fix everything Matt please don't change the ECMA target (cherry picked from commit cfe5e65ed892cea71f19d219d5dfb2518ec65137) --- 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. */ From 65b5cedb4ec1f55cacaace962b6f10d759c18048 Mon Sep 17 00:00:00 2001 From: Bsian Date: Fri, 17 Apr 2020 03:07:33 +0000 Subject: [PATCH 2/7] Remove optional chaining (cherry picked from commit 99ef533121903cd3281535c2bb9457bba2cf3b63) --- 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); From b126486a0ab9c383c3629b07f4d770dfa5217e8a Mon Sep 17 00:00:00 2001 From: Bsian Date: Fri, 17 Apr 2020 03:27:46 +0000 Subject: [PATCH 3/7] Add activity type enum (cherry picked from commit c72d5c1f1b1ed66fde8233b445957d4b3ac22909) --- 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); From ca662aaa2f58437ff6d3e101d6726e0d046ffd08 Mon Sep 17 00:00:00 2001 From: Bsian Date: Fri, 17 Apr 2020 03:29:17 +0000 Subject: [PATCH 4/7] Remove imports (cherry picked from commit f35317c43cce65f4a1ff0b57f91c072f418234fe) --- 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'; From e780777adb914b8a61dfab83cb3547c102f3d1b9 Mon Sep 17 00:00:00 2001 From: Bsian Date: Fri, 17 Apr 2020 03:35:56 +0000 Subject: [PATCH 5/7] Use error function (cherry picked from commit 41cd6869f52cab70cdc7777395310b0387f2cdad) --- 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) { From 2c6cf8e552dce5701242bfaef77ffd0daa2fa058 Mon Sep 17 00:00:00 2001 From: Bsian Date: Fri, 17 Apr 2020 13:42:25 +0100 Subject: [PATCH 6/7] Improvements --- src/class/Util.ts | 5 +++++ src/commands/ban.ts | 5 +++-- src/commands/game.ts | 3 ++- src/commands/roleinfo.ts | 5 +++-- src/commands/unban.ts | 3 ++- src/commands/whois.ts | 7 ++++--- src/events/messageCreate.ts | 4 ++-- 7 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/class/Util.ts b/src/class/Util.ts index f31a4ca..2f2f643 100644 --- a/src/class/Util.ts +++ b/src/class/Util.ts @@ -126,4 +126,9 @@ export default class Util { const asHex = number.toString(16); return '#000000'.substring(0, 7 - asHex.length) + asHex; } + + public guildFromMessage(message: Message): Guild | null { + if (message.channel instanceof PrivateChannel || message.channel instanceof GroupChannel) return null; + return message.channel.guild; + } } diff --git a/src/commands/ban.ts b/src/commands/ban.ts index a5afa43..3a6c90f 100644 --- a/src/commands/ban.ts +++ b/src/commands/ban.ts @@ -15,7 +15,8 @@ export default class Ban extends Command { public async run(message: Message, args: string[]) { try { - const member = this.client.util.resolveMember(args[0], message.member.guild); + const guild = this.client.util.guildFromMessage(message); + const member = this.client.util.resolveMember(args[0], guild); let user: User; if (!member) { try { @@ -25,7 +26,7 @@ export default class Ban extends Command { } } try { - await this.client.guilds.get(this.client.config.guildID).getBan(args[0]); + await 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.'); diff --git a/src/commands/game.ts b/src/commands/game.ts index 6d1aa68..4371880 100644 --- a/src/commands/game.ts +++ b/src/commands/game.ts @@ -24,10 +24,11 @@ export default class Game extends Command { public async run(message: Message, args: string[]) { try { + const guild = this.client.util.guildFromMessage(message); let member: Member; if (!args[0]) member = message.member; else { - member = this.client.util.resolveMember(args.join(' '), message.member.guild); + member = this.client.util.resolveMember(args.join(' '), guild); if (!member) { return this.error(message.channel, 'Member not found.'); } diff --git a/src/commands/roleinfo.ts b/src/commands/roleinfo.ts index 574a7d0..a0bf5cc 100644 --- a/src/commands/roleinfo.ts +++ b/src/commands/roleinfo.ts @@ -14,11 +14,12 @@ export default class Roleinfo extends Command { public async run(message: Message, args: string[]) { try { + const guild = this.client.util.guildFromMessage(message); if (!args[0]) return this.error(message.channel, 'You need to specifiy a role ID or a role name.'); - let role: Role = message.member.guild.roles.find((r: Role) => r.id === args[0]); + let role: Role = guild.roles.find((r: Role) => r.id === args[0]); if (!role) { // if it's a role name - role = message.member.guild.roles.find((r: Role) => r.name.toLowerCase().includes(args.join(' ').toLowerCase())); + role = guild.roles.find((r: Role) => r.name.toLowerCase().includes(args.join(' ').toLowerCase())); } if (!role) return this.error(message.channel, 'Could not find role.'); diff --git a/src/commands/unban.ts b/src/commands/unban.ts index 025758c..c1ff2cb 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 { + const guild = this.client.util.guildFromMessage(message); let user: User; try { user = await this.client.getRESTUser(args[0]); @@ -21,7 +22,7 @@ export default class Unban extends Command { return this.error(message.channel, 'Could find find user.'); } try { - await this.client.guilds.get(this.client.config.guildID).getBan(args[0]); + await guild.getBan(args[0]); } catch { return this.error(message.channel, 'This user is not banned.'); } diff --git a/src/commands/whois.ts b/src/commands/whois.ts index e6bdad9..24b3e88 100644 --- a/src/commands/whois.ts +++ b/src/commands/whois.ts @@ -18,10 +18,11 @@ export default class Whois extends Command { public async run(message: Message, args: string[]) { try { + const guild = this.client.util.guildFromMessage(message); let member: Member; if (!args[0]) member = message.member; else { - member = this.client.util.resolveMember(args.join(' '), message.member.guild); + member = this.client.util.resolveMember(args.join(' '), guild); } if (!member) { @@ -61,7 +62,7 @@ export default class Whois extends Command { description += `\n<@${member.id}>`; embed.setDescription(description); - const roles = member.roles.map((r) => message.member.guild.roles.get(r)).sort((a, b) => b.position - a.position); + const roles = member.roles.map((r) => guild.roles.get(r)).sort((a, b) => b.position - a.position); const { color } = roles.find((r) => r.color); embed.setColor(color); @@ -72,7 +73,7 @@ export default class Whois extends Command { const permissions: string[] = []; const serverAcknowledgements: string[] = []; const bit = member.permission.allow; - if (this.client.guilds.get(this.client.config.guildID).ownerID === member.id) serverAcknowledgements.push('Server Owner'); + if (guild.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'); diff --git a/src/events/messageCreate.ts b/src/events/messageCreate.ts index 72a1b65..cae3794 100644 --- a/src/events/messageCreate.ts +++ b/src/events/messageCreate.ts @@ -1,5 +1,5 @@ /* eslint-disable no-useless-return */ -import { Message, TextChannel } from 'eris'; +import { Message, TextChannel, NewsChannel } from 'eris'; import { Client } from '../class'; export default class { @@ -16,7 +16,7 @@ export default class { const noPrefix: string[] = message.content.slice(this.client.config.prefix.length).trim().split(/ +/g); const resolved = await this.client.util.resolveCommand(noPrefix); if (!resolved) return; - if (resolved.cmd.guildOnly && !(message.channel instanceof TextChannel)) return; + if (resolved.cmd.guildOnly && !(message.channel instanceof TextChannel || message.channel instanceof NewsChannel)) return; if (!resolved.cmd.enabled) { message.channel.createMessage(`***${this.client.util.emojis.ERROR} This command has been disabled***`); return; } if (!resolved.cmd.checkPermissions(message.member)) return; this.client.util.signale.info(`User '${message.author.username}#${message.author.discriminator}' ran command '${resolved.cmd.name}' in '${message.channel.id}'.`); From 1a41999e42e0d4c25351ca274bf8d0a4a9097c9f Mon Sep 17 00:00:00 2001 From: Bsian Date: Fri, 17 Apr 2020 14:45:18 +0100 Subject: [PATCH 7/7] more improvements --- .eslintrc.json | 2 +- package.json | 2 +- src/commands/ban.ts | 5 ++--- src/commands/game.ts | 3 +-- src/commands/roleinfo.ts | 5 ++--- src/commands/unban.ts | 3 +-- src/commands/whois.ts | 7 +++---- 7 files changed, 11 insertions(+), 16 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index af3e032..cf9a1af 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -19,7 +19,7 @@ }, "parser": "@typescript-eslint/parser", "parserOptions": { - "ecmaVersion": 2018, + "ecmaVersion": 2020, "sourceType": "module" }, "plugins": [ diff --git a/package.json b/package.json index 0fbd1f2..bf1c286 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ }, "dependencies": { "axios": "^0.19.2", - "eris": "abalabahaha/eris#dev", + "eris": "bsian03/eris#bsian", "moment": "^2.24.0", "mongoose": "^5.9.9", "signale": "^1.4.0", diff --git a/src/commands/ban.ts b/src/commands/ban.ts index 3a6c90f..887192d 100644 --- a/src/commands/ban.ts +++ b/src/commands/ban.ts @@ -15,8 +15,7 @@ export default class Ban extends Command { public async run(message: Message, args: string[]) { try { - const guild = this.client.util.guildFromMessage(message); - const member = this.client.util.resolveMember(args[0], guild); + const member = this.client.util.resolveMember(args[0], message.guild); let user: User; if (!member) { try { @@ -26,7 +25,7 @@ export default class Ban extends Command { } } try { - await guild.getBan(args[0]); + 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.'); diff --git a/src/commands/game.ts b/src/commands/game.ts index 4371880..50f3ac9 100644 --- a/src/commands/game.ts +++ b/src/commands/game.ts @@ -24,11 +24,10 @@ export default class Game extends Command { public async run(message: Message, args: string[]) { try { - const guild = this.client.util.guildFromMessage(message); let member: Member; if (!args[0]) member = message.member; else { - member = this.client.util.resolveMember(args.join(' '), guild); + member = this.client.util.resolveMember(args.join(' '), message.guild); if (!member) { return this.error(message.channel, 'Member not found.'); } diff --git a/src/commands/roleinfo.ts b/src/commands/roleinfo.ts index a0bf5cc..aa68eb0 100644 --- a/src/commands/roleinfo.ts +++ b/src/commands/roleinfo.ts @@ -14,12 +14,11 @@ export default class Roleinfo extends Command { public async run(message: Message, args: string[]) { try { - const guild = this.client.util.guildFromMessage(message); if (!args[0]) return this.error(message.channel, 'You need to specifiy a role ID or a role name.'); - let role: Role = guild.roles.find((r: Role) => r.id === args[0]); + let role: Role = message.guild.roles.find((r: Role) => r.id === args[0]); if (!role) { // if it's a role name - role = guild.roles.find((r: Role) => r.name.toLowerCase().includes(args.join(' ').toLowerCase())); + 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.'); diff --git a/src/commands/unban.ts b/src/commands/unban.ts index c1ff2cb..1e0ed94 100644 --- a/src/commands/unban.ts +++ b/src/commands/unban.ts @@ -14,7 +14,6 @@ export default class Unban extends Command { public async run(message: Message, args: string[]) { try { - const guild = this.client.util.guildFromMessage(message); let user: User; try { user = await this.client.getRESTUser(args[0]); @@ -22,7 +21,7 @@ export default class Unban extends Command { return this.error(message.channel, 'Could find find user.'); } try { - await guild.getBan(args[0]); + await message.guild.getBan(args[0]); } catch { return this.error(message.channel, 'This user is not banned.'); } diff --git a/src/commands/whois.ts b/src/commands/whois.ts index 24b3e88..44a020d 100644 --- a/src/commands/whois.ts +++ b/src/commands/whois.ts @@ -18,11 +18,10 @@ export default class Whois extends Command { public async run(message: Message, args: string[]) { try { - const guild = this.client.util.guildFromMessage(message); let member: Member; if (!args[0]) member = message.member; else { - member = this.client.util.resolveMember(args.join(' '), guild); + member = this.client.util.resolveMember(args.join(' '), message.guild); } if (!member) { @@ -62,7 +61,7 @@ export default class Whois extends Command { description += `\n<@${member.id}>`; embed.setDescription(description); - const roles = member.roles.map((r) => guild.roles.get(r)).sort((a, b) => b.position - a.position); + const roles = member.roles.map((r) => message.guild.roles.get(r)).sort((a, b) => b.position - a.position); const { color } = roles.find((r) => r.color); embed.setColor(color); @@ -73,7 +72,7 @@ export default class Whois extends Command { const permissions: string[] = []; const serverAcknowledgements: string[] = []; const bit = member.permission.allow; - if (guild.ownerID === member.id) serverAcknowledgements.push('Server Owner'); + if (message.guild.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');