mirror of
https://github.com/keanuplayz/TravBot-v3.git
synced 2024-08-15 02:33:12 +00:00
Merge branch 'typescript' of github.com:keanuplayz/TravBot-v3 into typescript
This commit is contained in:
commit
0e1d8f3907
10 changed files with 79 additions and 56 deletions
5
package-lock.json
generated
5
package-lock.json
generated
|
@ -854,11 +854,6 @@
|
|||
"mimic-fn": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"os": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/os/-/os-0.1.1.tgz",
|
||||
"integrity": "sha1-IIhF6J4ZOtTZcUdLk5R3NqVtE/M="
|
||||
},
|
||||
"os-tmpdir": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
|
||||
|
|
|
@ -10,8 +10,7 @@
|
|||
"discord.js-lavalink-lib": "^0.1.8",
|
||||
"inquirer": "^7.3.3",
|
||||
"moment": "^2.29.1",
|
||||
"ms": "^2.1.3",
|
||||
"os": "^0.1.1"
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/inquirer": "^6.5.0",
|
||||
|
|
|
@ -124,14 +124,15 @@ export default new Command({
|
|||
number: new Command({
|
||||
description: "Amount of messages to delete.",
|
||||
async run($: CommonLibrary): Promise<any> {
|
||||
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]
|
||||
});
|
||||
$.channel
|
||||
/// @ts-ignore
|
||||
.bulkDelete(fetched)
|
||||
.catch((error: any) => $.channel.send(`Error: ${error}`));
|
||||
await $.channel.bulkDelete(fetched);
|
||||
}
|
||||
})
|
||||
}),
|
||||
|
@ -157,8 +158,7 @@ export default new Command({
|
|||
permission: Command.PERMISSIONS.BOT_SUPPORT,
|
||||
async run($: CommonLibrary): Promise<any> {
|
||||
const nickName = $.args.join(" ");
|
||||
const trav = $.guild?.members.cache.find((member) => member.id === $.client.user?.id);
|
||||
await trav?.setNickname(nickName);
|
||||
await $.guild?.me?.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}));
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
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";
|
||||
|
@ -9,6 +7,8 @@ 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,13 +36,6 @@ export default new Command({
|
|||
async run($: CommonLibrary): Promise<any> {
|
||||
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})`,
|
||||
|
@ -71,6 +64,11 @@ 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);
|
||||
}
|
||||
}),
|
||||
|
@ -78,10 +76,13 @@ export default new Command({
|
|||
description: "Displays info about the current guild.",
|
||||
async run($: CommonLibrary): Promise<any> {
|
||||
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});
|
||||
|
@ -145,7 +146,7 @@ export default new Command({
|
|||
description: "Displays info about mentioned user.",
|
||||
async run($: CommonLibrary): Promise<any> {
|
||||
// Transforms the User object into a GuildMember object of the current guild.
|
||||
const member = $.guild?.members.resolve($.args[0]) ?? (await $.guild?.members.fetch($.args[0]));
|
||||
const member = await $.guild?.members.fetch($.args[0]);
|
||||
|
||||
if (!member)
|
||||
return $.channel.send(
|
||||
|
@ -156,8 +157,7 @@ export default new Command({
|
|||
.sort((a: {position: number}, b: {position: number}) => b.position - a.position)
|
||||
.map((role: {toString: () => any}) => role.toString())
|
||||
.slice(0, -1);
|
||||
// @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 userFlags = (await member.user.fetchFlags()).toArray();
|
||||
|
||||
const embed = new MessageEmbed()
|
||||
.setThumbnail(member.user.displayAvatarURL({dynamic: true, size: 512}))
|
||||
|
@ -183,10 +183,7 @@ 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);
|
||||
|
|
|
@ -9,15 +9,14 @@ export default new Command({
|
|||
|
||||
if (!voiceChannel) return $.channel.send("You are not in a voice channel.");
|
||||
|
||||
if (!$.guild?.me?.hasPermission("MANAGE_CHANNELS"))
|
||||
if (!voiceChannel.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 changeVC = $.guild.channels.resolve(voiceChannel.id);
|
||||
$.channel
|
||||
.send(`Changed channel name from "${voiceChannel}" to "${$.args.join(" ")}".`)
|
||||
/// @ts-ignore
|
||||
.then(changeVC?.setName($.args.join(" ")));
|
||||
const prevName = voiceChannel.name;
|
||||
const newName = $.args.join(" ");
|
||||
await voiceChannel.setName(newName);
|
||||
await $.channel.send(`Changed channel name from "${prevName}" to "${newName}".`);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -12,7 +12,6 @@ export default new Command({
|
|||
async run({guild, channel, message, args}) {
|
||||
let output = "";
|
||||
for (const query of args) output += queryClosestEmoteByName(query).toString();
|
||||
if (botHasPermission(guild, Permissions.FLAGS.MANAGE_MESSAGES)) message.delete();
|
||||
channel.send(output);
|
||||
}
|
||||
})
|
||||
|
|
|
@ -182,12 +182,16 @@ export async function loadCommands(): Promise<Collection<string, Command>> {
|
|||
if (cmd.isDirectory()) {
|
||||
if (cmd.name === "subcommands") continue;
|
||||
else $.warn(`You can't have multiple levels of directories! From: "dist/commands/${cmd.name}"`);
|
||||
} else loadCommand(cmd.name, list, selected.name);
|
||||
} else if (cmd.name.endsWith(".js")) {
|
||||
loadCommand(cmd.name, list, selected.name);
|
||||
}
|
||||
}
|
||||
|
||||
subdir.close();
|
||||
categories.set(category, list);
|
||||
} else loadCommand(selected.name, listMisc);
|
||||
} else if (selected.name.endsWith(".js")) {
|
||||
loadCommand(selected.name, listMisc);
|
||||
}
|
||||
}
|
||||
|
||||
dir.close();
|
||||
|
@ -236,7 +240,7 @@ export default new Command({
|
|||
permission: null,
|
||||
aliases: [],
|
||||
async run($: CommonLibrary): Promise<any> {
|
||||
|
||||
|
||||
},
|
||||
subcommands: {
|
||||
layer: new Command({
|
||||
|
@ -246,7 +250,7 @@ export default new Command({
|
|||
permission: null,
|
||||
aliases: [],
|
||||
async run($: CommonLibrary): Promise<any> {
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
|
@ -256,7 +260,7 @@ export default new Command({
|
|||
usage: '',
|
||||
permission: null,
|
||||
async run($: CommonLibrary): Promise<any> {
|
||||
|
||||
|
||||
}
|
||||
}),
|
||||
number: new Command({
|
||||
|
@ -265,7 +269,7 @@ export default new Command({
|
|||
usage: '',
|
||||
permission: null,
|
||||
async run($: CommonLibrary): Promise<any> {
|
||||
|
||||
|
||||
}
|
||||
}),
|
||||
any: new Command({
|
||||
|
@ -274,7 +278,7 @@ export default new Command({
|
|||
usage: '',
|
||||
permission: null,
|
||||
async run($: CommonLibrary): Promise<any> {
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
});`;
|
||||
|
|
|
@ -172,7 +172,7 @@ export function formatUTCTimestamp(now = new Date()) {
|
|||
}
|
||||
|
||||
export function botHasPermission(guild: Guild | null, permission: number): boolean {
|
||||
return !!(client.user && guild?.members.resolve(client.user)?.hasPermission(permission));
|
||||
return !!guild?.me?.hasPermission(permission);
|
||||
}
|
||||
|
||||
export function updateGlobalEmoteRegistry(): void {
|
||||
|
@ -216,20 +216,22 @@ $.paginate = async (
|
|||
|
||||
callback(page);
|
||||
};
|
||||
const BACKWARDS_EMOJI = "⬅️";
|
||||
const FORWARDS_EMOJI = "➡️";
|
||||
const handle = (emote: string, reacterID: string) => {
|
||||
switch (emote) {
|
||||
case "⬅️":
|
||||
case BACKWARDS_EMOJI:
|
||||
turn(-1);
|
||||
break;
|
||||
case "➡️":
|
||||
case FORWARDS_EMOJI:
|
||||
turn(1);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
// Listen for reactions and call the handler.
|
||||
await message.react("⬅️");
|
||||
await message.react("➡️");
|
||||
let backwardsReaction = await message.react(BACKWARDS_EMOJI);
|
||||
let forwardsReaction = await message.react(FORWARDS_EMOJI);
|
||||
eventListeners.set(message.id, handle);
|
||||
await message.awaitReactions(
|
||||
(reaction, user) => {
|
||||
|
@ -248,8 +250,8 @@ $.paginate = async (
|
|||
);
|
||||
// When time's up, remove the bot's own reactions.
|
||||
eventListeners.delete(message.id);
|
||||
message.reactions.cache.get("⬅️")?.users.remove(message.author);
|
||||
message.reactions.cache.get("➡️")?.users.remove(message.author);
|
||||
backwardsReaction.users.remove(message.author);
|
||||
forwardsReaction.users.remove(message.author);
|
||||
};
|
||||
|
||||
// Waits for the sender to either confirm an action or let it pass (and delete the message).
|
||||
|
@ -554,7 +556,6 @@ 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;
|
||||
|
|
32
src/index.ts
32
src/index.ts
|
@ -1,4 +1,4 @@
|
|||
import {Client} from "discord.js";
|
||||
import * as discord from "discord.js";
|
||||
import setup from "./setup";
|
||||
import {Config} from "./core/structures";
|
||||
import {loadCommands} from "./core/command";
|
||||
|
@ -6,9 +6,37 @@ 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:
|
||||
// <https://github.com/discordjs/discord.js/blob/cee6cf70ce76e9b06dc7f25bfd77498e18d7c8d4/src/structures/Presence.js#L81-L110>.
|
||||
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 Client();
|
||||
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
|
||||
// <https://github.com/discordjs/discord.js/blob/cee6cf70ce76e9b06dc7f25bfd77498e18d7c8d4/src/client/actions/PresenceUpdate.js#L7-L41>.
|
||||
(client["actions"] as any)["PresenceUpdate"].handle = () => {};
|
||||
|
||||
(client as any).music = LavalinkMusic(client, {
|
||||
lavalink: {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"compilerOptions": {
|
||||
"rootDir": "src",
|
||||
"outDir": "dist",
|
||||
"target": "ES6",
|
||||
"target": "es2019",
|
||||
"module": "CommonJS",
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
|
@ -11,7 +11,8 @@
|
|||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"strictPropertyInitialization": true,
|
||||
"removeComments": true
|
||||
"removeComments": true,
|
||||
"sourceMap": true
|
||||
},
|
||||
"exclude": ["test"]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue