diff --git a/src/commands/admin.ts b/src/commands/admin.ts index f174750..47279f9 100644 --- a/src/commands/admin.ts +++ b/src/commands/admin.ts @@ -124,15 +124,14 @@ export default new Command({ number: new Command({ description: "Amount of messages to delete.", async run($: CommonLibrary): Promise { - if ($.channel.type === "dm") { - await $.channel.send("Can't clear messages in the DMs!"); - return; - } $.message.delete(); const fetched = await $.channel.messages.fetch({ limit: $.args[0] }); - await $.channel.bulkDelete(fetched); + $.channel + /// @ts-ignore + .bulkDelete(fetched) + .catch((error: any) => $.channel.send(`Error: ${error}`)); } }) }), @@ -158,7 +157,8 @@ export default new Command({ permission: Command.PERMISSIONS.BOT_SUPPORT, async run($: CommonLibrary): Promise { const nickName = $.args.join(" "); - await $.guild?.me?.setNickname(nickName); + const trav = $.guild?.members.cache.find((member) => member.id === $.client.user?.id); + await trav?.setNickname(nickName); if (botHasPermission($.guild, Permissions.FLAGS.MANAGE_MESSAGES)) $.message.delete({timeout: 5000}).catch($.handler.bind($)); $.channel.send(`Nickname set to \`${nickName}\``).then((m) => m.delete({timeout: 5000})); diff --git a/src/commands/info.ts b/src/commands/info.ts index 9b7b71a..a85a2e5 100644 --- a/src/commands/info.ts +++ b/src/commands/info.ts @@ -1,4 +1,6 @@ import {MessageEmbed, version as djsversion} from "discord.js"; +/// @ts-ignore +import {version} from "../../package.json"; import ms from "ms"; import os from "os"; import Command from "../core/command"; @@ -7,8 +9,6 @@ import {verificationLevels, filterLevels, regions, flags} from "../defs/info"; import moment from "moment"; import utc from "moment"; -const {version} = require("../../package.json"); - export default new Command({ description: "Command to provide all sorts of info about the current server, a user, etc.", run: "Please provide an argument.\nFor help, run `%prefix%help info`.", @@ -36,6 +36,13 @@ export default new Command({ async run($: CommonLibrary): Promise { const core = os.cpus()[0]; const embed = new MessageEmbed() + .setThumbnail( + /// @ts-ignore + $.client.user?.displayAvatarURL({ + dynamic: true, + size: 2048 + }) + ) .setColor($.guild?.me?.displayHexColor || "BLUE") .addField("General", [ `**❯ Client:** ${$.client.user?.tag} (${$.client.user?.id})`, @@ -64,11 +71,6 @@ export default new Command({ `\u3000 • Used: ${formatBytes(process.memoryUsage().heapUsed)}` ]) .setTimestamp(); - const avatarURL = $.client.user?.displayAvatarURL({ - dynamic: true, - size: 2048 - }); - if (avatarURL) embed.setThumbnail(avatarURL); $.channel.send(embed); } }), @@ -76,13 +78,10 @@ export default new Command({ description: "Displays info about the current guild.", async run($: CommonLibrary): Promise { if ($.guild) { - const members = await $.guild.members.fetch({ - withPresences: true, - force: true - }); const roles = $.guild.roles.cache .sort((a, b) => b.position - a.position) .map((role) => role.toString()); + const members = $.guild.members.cache; const channels = $.guild.channels.cache; const emojis = $.guild.emojis.cache; const iconURL = $.guild.iconURL({dynamic: true}); @@ -146,7 +145,7 @@ export default new Command({ description: "Displays info about mentioned user.", async run($: CommonLibrary): Promise { // Transforms the User object into a GuildMember object of the current guild. - const member = await $.guild?.members.fetch($.args[0]); + const member = $.guild?.members.resolve($.args[0]) ?? (await $.guild?.members.fetch($.args[0])); if (!member) return $.channel.send( @@ -157,7 +156,8 @@ export default new Command({ .sort((a: {position: number}, b: {position: number}) => b.position - a.position) .map((role: {toString: () => any}) => role.toString()) .slice(0, -1); - const userFlags = (await member.user.fetchFlags()).toArray(); + // @ts-ignore - Discord.js' typings seem to be outdated here. According to their v12 docs, it's User.fetchFlags() instead of User.flags. + const userFlags = ((await member.user.fetchFlags()) as UserFlags).toArray(); const embed = new MessageEmbed() .setThumbnail(member.user.displayAvatarURL({dynamic: true, size: 512})) @@ -183,7 +183,10 @@ export default new Command({ `**❯ Server Join Date:** ${moment(member.joinedAt).format("LL LTS")}`, `**❯ Hoist Role:** ${member.roles.hoist ? member.roles.hoist.name : "None"}`, `**❯ Roles:** [${roles.length}]: ${ - roles.length == 0 ? "None" : roles.length <= 10 ? roles.join(", ") : trimArray(roles).join(", ") + roles.length == 0 ? "None" + : roles.length <= 10 + ? roles.join(", ") + : trimArray(roles).join(", ") }` ]); $.channel.send(embed); diff --git a/src/commands/utilities/desc.ts b/src/commands/utilities/desc.ts index c5e75f3..467053c 100644 --- a/src/commands/utilities/desc.ts +++ b/src/commands/utilities/desc.ts @@ -9,14 +9,15 @@ export default new Command({ if (!voiceChannel) return $.channel.send("You are not in a voice channel."); - if (!voiceChannel.guild.me?.hasPermission("MANAGE_CHANNELS")) + if (!$.guild?.me?.hasPermission("MANAGE_CHANNELS")) return $.channel.send("I am lacking the required permissions to perform this action."); if ($.args.length === 0) return $.channel.send("Please provide a new voice channel name."); - const prevName = voiceChannel.name; - const newName = $.args.join(" "); - await voiceChannel.setName(newName); - await $.channel.send(`Changed channel name from "${prevName}" to "${newName}".`); + const changeVC = $.guild.channels.resolve(voiceChannel.id); + $.channel + .send(`Changed channel name from "${voiceChannel}" to "${$.args.join(" ")}".`) + /// @ts-ignore + .then(changeVC?.setName($.args.join(" "))); } }); diff --git a/src/core/command.ts b/src/core/command.ts index b5fa826..7ba0f02 100644 --- a/src/core/command.ts +++ b/src/core/command.ts @@ -182,16 +182,12 @@ export async function loadCommands(): Promise> { if (cmd.isDirectory()) { if (cmd.name === "subcommands") continue; else $.warn(`You can't have multiple levels of directories! From: "dist/commands/${cmd.name}"`); - } else if (cmd.name.endsWith(".js")) { - loadCommand(cmd.name, list, selected.name); - } + } else loadCommand(cmd.name, list, selected.name); } subdir.close(); categories.set(category, list); - } else if (selected.name.endsWith(".js")) { - loadCommand(selected.name, listMisc); - } + } else loadCommand(selected.name, listMisc); } dir.close(); @@ -240,7 +236,7 @@ export default new Command({ permission: null, aliases: [], async run($: CommonLibrary): Promise { - + }, subcommands: { layer: new Command({ @@ -250,7 +246,7 @@ export default new Command({ permission: null, aliases: [], async run($: CommonLibrary): Promise { - + } }) }, @@ -260,7 +256,7 @@ export default new Command({ usage: '', permission: null, async run($: CommonLibrary): Promise { - + } }), number: new Command({ @@ -269,7 +265,7 @@ export default new Command({ usage: '', permission: null, async run($: CommonLibrary): Promise { - + } }), any: new Command({ @@ -278,7 +274,7 @@ export default new Command({ usage: '', permission: null, async run($: CommonLibrary): Promise { - + } }) });`; diff --git a/src/core/lib.ts b/src/core/lib.ts index 4cadf4d..42852d9 100644 --- a/src/core/lib.ts +++ b/src/core/lib.ts @@ -172,7 +172,7 @@ export function formatUTCTimestamp(now = new Date()) { } export function botHasPermission(guild: Guild | null, permission: number): boolean { - return !!guild?.me?.hasPermission(permission); + return !!(client.user && guild?.members.resolve(client.user)?.hasPermission(permission)); } export function updateGlobalEmoteRegistry(): void { @@ -216,22 +216,20 @@ $.paginate = async ( callback(page); }; - const BACKWARDS_EMOJI = "⬅️"; - const FORWARDS_EMOJI = "➡️"; const handle = (emote: string, reacterID: string) => { switch (emote) { - case BACKWARDS_EMOJI: + case "⬅️": turn(-1); break; - case FORWARDS_EMOJI: + case "➡️": turn(1); break; } }; // Listen for reactions and call the handler. - let backwardsReaction = await message.react(BACKWARDS_EMOJI); - let forwardsReaction = await message.react(FORWARDS_EMOJI); + await message.react("⬅️"); + await message.react("➡️"); eventListeners.set(message.id, handle); await message.awaitReactions( (reaction, user) => { @@ -250,8 +248,8 @@ $.paginate = async ( ); // When time's up, remove the bot's own reactions. eventListeners.delete(message.id); - backwardsReaction.users.remove(message.author); - forwardsReaction.users.remove(message.author); + message.reactions.cache.get("⬅️")?.users.remove(message.author); + message.reactions.cache.get("➡️")?.users.remove(message.author); }; // Waits for the sender to either confirm an action or let it pass (and delete the message). @@ -556,6 +554,7 @@ export abstract class GenericStructure { public save(asynchronous = true) { const tag = this.__meta__; + /// @ts-ignore delete this.__meta__; FileManager.write(tag, this, asynchronous); this.__meta__ = tag; diff --git a/src/index.ts b/src/index.ts index fa72c21..9721784 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import * as discord from "discord.js"; +import {Client} from "discord.js"; import setup from "./setup"; import {Config} from "./core/structures"; import {loadCommands} from "./core/command"; @@ -6,37 +6,9 @@ import {loadEvents} from "./core/event"; import "discord.js-lavalink-lib"; import LavalinkMusic from "discord.js-lavalink-lib"; -declare module "discord.js" { - interface Presence { - patch(data: any): void; - } -} - -// The terrible hacks were written by none other than The Noble Programmer On The White PC. - -// NOTE: Terrible hack ahead!!! In order to reduce the memory usage of the bot -// we only store the information from presences that we actually end up using, -// which currently is only the (online/idle/dnd/offline/...) status (see -// `src/commands/info.ts`). What data is retrieved from the `data` object -// (which contains the data received from the Gateway) and how can be seen -// here: -// . -const oldPresencePatch = discord.Presence.prototype.patch; -discord.Presence.prototype.patch = function patch(data: any) { - oldPresencePatch.call(this, {status: data.status}); -}; - // This is here in order to make it much less of a headache to access the client from other files. // This of course won't actually do anything until the setup process is complete and it logs in. -export const client = new discord.Client(); - -// NOTE: Terrible hack continued!!! Unfortunately we can't receive the presence -// data at all when the GUILD_PRESENCES intent is disabled, so while we do -// waste network bandwidth and the CPU time for decoding the incoming packets, -// the function which handles those packets is NOP-ed out, which, among other -// things, skips the code which caches the referenced users in the packet. See -// . -(client["actions"] as any)["PresenceUpdate"].handle = () => {}; +export const client = new Client(); (client as any).music = LavalinkMusic(client, { lavalink: { diff --git a/tsconfig.json b/tsconfig.json index 34245ef..ba4dd11 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "rootDir": "src", "outDir": "dist", - "target": "es2019", + "target": "ES6", "module": "CommonJS", "moduleResolution": "node", "esModuleInterop": true, @@ -11,8 +11,7 @@ "strictNullChecks": true, "strictFunctionTypes": true, "strictPropertyInitialization": true, - "removeComments": true, - "sourceMap": true + "removeComments": true }, "exclude": ["test"] }