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"
|
"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": {
|
"os-tmpdir": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
|
||||||
|
|
|
@ -10,8 +10,7 @@
|
||||||
"discord.js-lavalink-lib": "^0.1.8",
|
"discord.js-lavalink-lib": "^0.1.8",
|
||||||
"inquirer": "^7.3.3",
|
"inquirer": "^7.3.3",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"ms": "^2.1.3",
|
"ms": "^2.1.3"
|
||||||
"os": "^0.1.1"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/inquirer": "^6.5.0",
|
"@types/inquirer": "^6.5.0",
|
||||||
|
|
|
@ -124,14 +124,15 @@ export default new Command({
|
||||||
number: new Command({
|
number: new Command({
|
||||||
description: "Amount of messages to delete.",
|
description: "Amount of messages to delete.",
|
||||||
async run($: CommonLibrary): Promise<any> {
|
async run($: CommonLibrary): Promise<any> {
|
||||||
|
if ($.channel.type === "dm") {
|
||||||
|
await $.channel.send("Can't clear messages in the DMs!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
$.message.delete();
|
$.message.delete();
|
||||||
const fetched = await $.channel.messages.fetch({
|
const fetched = await $.channel.messages.fetch({
|
||||||
limit: $.args[0]
|
limit: $.args[0]
|
||||||
});
|
});
|
||||||
$.channel
|
await $.channel.bulkDelete(fetched);
|
||||||
/// @ts-ignore
|
|
||||||
.bulkDelete(fetched)
|
|
||||||
.catch((error: any) => $.channel.send(`Error: ${error}`));
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
|
@ -157,8 +158,7 @@ export default new Command({
|
||||||
permission: Command.PERMISSIONS.BOT_SUPPORT,
|
permission: Command.PERMISSIONS.BOT_SUPPORT,
|
||||||
async run($: CommonLibrary): Promise<any> {
|
async run($: CommonLibrary): Promise<any> {
|
||||||
const nickName = $.args.join(" ");
|
const nickName = $.args.join(" ");
|
||||||
const trav = $.guild?.members.cache.find((member) => member.id === $.client.user?.id);
|
await $.guild?.me?.setNickname(nickName);
|
||||||
await trav?.setNickname(nickName);
|
|
||||||
if (botHasPermission($.guild, Permissions.FLAGS.MANAGE_MESSAGES))
|
if (botHasPermission($.guild, Permissions.FLAGS.MANAGE_MESSAGES))
|
||||||
$.message.delete({timeout: 5000}).catch($.handler.bind($));
|
$.message.delete({timeout: 5000}).catch($.handler.bind($));
|
||||||
$.channel.send(`Nickname set to \`${nickName}\``).then((m) => m.delete({timeout: 5000}));
|
$.channel.send(`Nickname set to \`${nickName}\``).then((m) => m.delete({timeout: 5000}));
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
import {MessageEmbed, version as djsversion} from "discord.js";
|
import {MessageEmbed, version as djsversion} from "discord.js";
|
||||||
/// @ts-ignore
|
|
||||||
import {version} from "../../package.json";
|
|
||||||
import ms from "ms";
|
import ms from "ms";
|
||||||
import os from "os";
|
import os from "os";
|
||||||
import Command from "../core/command";
|
import Command from "../core/command";
|
||||||
|
@ -9,6 +7,8 @@ import {verificationLevels, filterLevels, regions, flags} from "../defs/info";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import utc from "moment";
|
import utc from "moment";
|
||||||
|
|
||||||
|
const {version} = require("../../package.json");
|
||||||
|
|
||||||
export default new Command({
|
export default new Command({
|
||||||
description: "Command to provide all sorts of info about the current server, a user, etc.",
|
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`.",
|
run: "Please provide an argument.\nFor help, run `%prefix%help info`.",
|
||||||
|
@ -36,13 +36,6 @@ export default new Command({
|
||||||
async run($: CommonLibrary): Promise<any> {
|
async run($: CommonLibrary): Promise<any> {
|
||||||
const core = os.cpus()[0];
|
const core = os.cpus()[0];
|
||||||
const embed = new MessageEmbed()
|
const embed = new MessageEmbed()
|
||||||
.setThumbnail(
|
|
||||||
/// @ts-ignore
|
|
||||||
$.client.user?.displayAvatarURL({
|
|
||||||
dynamic: true,
|
|
||||||
size: 2048
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.setColor($.guild?.me?.displayHexColor || "BLUE")
|
.setColor($.guild?.me?.displayHexColor || "BLUE")
|
||||||
.addField("General", [
|
.addField("General", [
|
||||||
`**❯ Client:** ${$.client.user?.tag} (${$.client.user?.id})`,
|
`**❯ Client:** ${$.client.user?.tag} (${$.client.user?.id})`,
|
||||||
|
@ -71,6 +64,11 @@ export default new Command({
|
||||||
`\u3000 • Used: ${formatBytes(process.memoryUsage().heapUsed)}`
|
`\u3000 • Used: ${formatBytes(process.memoryUsage().heapUsed)}`
|
||||||
])
|
])
|
||||||
.setTimestamp();
|
.setTimestamp();
|
||||||
|
const avatarURL = $.client.user?.displayAvatarURL({
|
||||||
|
dynamic: true,
|
||||||
|
size: 2048
|
||||||
|
});
|
||||||
|
if (avatarURL) embed.setThumbnail(avatarURL);
|
||||||
$.channel.send(embed);
|
$.channel.send(embed);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
@ -78,10 +76,13 @@ export default new Command({
|
||||||
description: "Displays info about the current guild.",
|
description: "Displays info about the current guild.",
|
||||||
async run($: CommonLibrary): Promise<any> {
|
async run($: CommonLibrary): Promise<any> {
|
||||||
if ($.guild) {
|
if ($.guild) {
|
||||||
|
const members = await $.guild.members.fetch({
|
||||||
|
withPresences: true,
|
||||||
|
force: true
|
||||||
|
});
|
||||||
const roles = $.guild.roles.cache
|
const roles = $.guild.roles.cache
|
||||||
.sort((a, b) => b.position - a.position)
|
.sort((a, b) => b.position - a.position)
|
||||||
.map((role) => role.toString());
|
.map((role) => role.toString());
|
||||||
const members = $.guild.members.cache;
|
|
||||||
const channels = $.guild.channels.cache;
|
const channels = $.guild.channels.cache;
|
||||||
const emojis = $.guild.emojis.cache;
|
const emojis = $.guild.emojis.cache;
|
||||||
const iconURL = $.guild.iconURL({dynamic: true});
|
const iconURL = $.guild.iconURL({dynamic: true});
|
||||||
|
@ -145,7 +146,7 @@ export default new Command({
|
||||||
description: "Displays info about mentioned user.",
|
description: "Displays info about mentioned user.",
|
||||||
async run($: CommonLibrary): Promise<any> {
|
async run($: CommonLibrary): Promise<any> {
|
||||||
// Transforms the User object into a GuildMember object of the current guild.
|
// 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)
|
if (!member)
|
||||||
return $.channel.send(
|
return $.channel.send(
|
||||||
|
@ -156,8 +157,7 @@ export default new Command({
|
||||||
.sort((a: {position: number}, b: {position: number}) => b.position - a.position)
|
.sort((a: {position: number}, b: {position: number}) => b.position - a.position)
|
||||||
.map((role: {toString: () => any}) => role.toString())
|
.map((role: {toString: () => any}) => role.toString())
|
||||||
.slice(0, -1);
|
.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()).toArray();
|
||||||
const userFlags = ((await member.user.fetchFlags()) as UserFlags).toArray();
|
|
||||||
|
|
||||||
const embed = new MessageEmbed()
|
const embed = new MessageEmbed()
|
||||||
.setThumbnail(member.user.displayAvatarURL({dynamic: true, size: 512}))
|
.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")}`,
|
`**❯ Server Join Date:** ${moment(member.joinedAt).format("LL LTS")}`,
|
||||||
`**❯ Hoist Role:** ${member.roles.hoist ? member.roles.hoist.name : "None"}`,
|
`**❯ Hoist Role:** ${member.roles.hoist ? member.roles.hoist.name : "None"}`,
|
||||||
`**❯ Roles:** [${roles.length}]: ${
|
`**❯ Roles:** [${roles.length}]: ${
|
||||||
roles.length == 0 ? "None"
|
roles.length == 0 ? "None" : roles.length <= 10 ? roles.join(", ") : trimArray(roles).join(", ")
|
||||||
: roles.length <= 10
|
|
||||||
? roles.join(", ")
|
|
||||||
: trimArray(roles).join(", ")
|
|
||||||
}`
|
}`
|
||||||
]);
|
]);
|
||||||
$.channel.send(embed);
|
$.channel.send(embed);
|
||||||
|
|
|
@ -9,15 +9,14 @@ export default new Command({
|
||||||
|
|
||||||
if (!voiceChannel) return $.channel.send("You are not in a voice channel.");
|
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.");
|
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.");
|
if ($.args.length === 0) return $.channel.send("Please provide a new voice channel name.");
|
||||||
|
|
||||||
const changeVC = $.guild.channels.resolve(voiceChannel.id);
|
const prevName = voiceChannel.name;
|
||||||
$.channel
|
const newName = $.args.join(" ");
|
||||||
.send(`Changed channel name from "${voiceChannel}" to "${$.args.join(" ")}".`)
|
await voiceChannel.setName(newName);
|
||||||
/// @ts-ignore
|
await $.channel.send(`Changed channel name from "${prevName}" to "${newName}".`);
|
||||||
.then(changeVC?.setName($.args.join(" ")));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,7 +12,6 @@ export default new Command({
|
||||||
async run({guild, channel, message, args}) {
|
async run({guild, channel, message, args}) {
|
||||||
let output = "";
|
let output = "";
|
||||||
for (const query of args) output += queryClosestEmoteByName(query).toString();
|
for (const query of args) output += queryClosestEmoteByName(query).toString();
|
||||||
if (botHasPermission(guild, Permissions.FLAGS.MANAGE_MESSAGES)) message.delete();
|
|
||||||
channel.send(output);
|
channel.send(output);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -182,12 +182,16 @@ export async function loadCommands(): Promise<Collection<string, Command>> {
|
||||||
if (cmd.isDirectory()) {
|
if (cmd.isDirectory()) {
|
||||||
if (cmd.name === "subcommands") continue;
|
if (cmd.name === "subcommands") continue;
|
||||||
else $.warn(`You can't have multiple levels of directories! From: "dist/commands/${cmd.name}"`);
|
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();
|
subdir.close();
|
||||||
categories.set(category, list);
|
categories.set(category, list);
|
||||||
} else loadCommand(selected.name, listMisc);
|
} else if (selected.name.endsWith(".js")) {
|
||||||
|
loadCommand(selected.name, listMisc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dir.close();
|
dir.close();
|
||||||
|
@ -236,7 +240,7 @@ export default new Command({
|
||||||
permission: null,
|
permission: null,
|
||||||
aliases: [],
|
aliases: [],
|
||||||
async run($: CommonLibrary): Promise<any> {
|
async run($: CommonLibrary): Promise<any> {
|
||||||
|
|
||||||
},
|
},
|
||||||
subcommands: {
|
subcommands: {
|
||||||
layer: new Command({
|
layer: new Command({
|
||||||
|
@ -246,7 +250,7 @@ export default new Command({
|
||||||
permission: null,
|
permission: null,
|
||||||
aliases: [],
|
aliases: [],
|
||||||
async run($: CommonLibrary): Promise<any> {
|
async run($: CommonLibrary): Promise<any> {
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -256,7 +260,7 @@ export default new Command({
|
||||||
usage: '',
|
usage: '',
|
||||||
permission: null,
|
permission: null,
|
||||||
async run($: CommonLibrary): Promise<any> {
|
async run($: CommonLibrary): Promise<any> {
|
||||||
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
number: new Command({
|
number: new Command({
|
||||||
|
@ -265,7 +269,7 @@ export default new Command({
|
||||||
usage: '',
|
usage: '',
|
||||||
permission: null,
|
permission: null,
|
||||||
async run($: CommonLibrary): Promise<any> {
|
async run($: CommonLibrary): Promise<any> {
|
||||||
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
any: new Command({
|
any: new Command({
|
||||||
|
@ -274,7 +278,7 @@ export default new Command({
|
||||||
usage: '',
|
usage: '',
|
||||||
permission: null,
|
permission: null,
|
||||||
async run($: CommonLibrary): Promise<any> {
|
async run($: CommonLibrary): Promise<any> {
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});`;
|
});`;
|
||||||
|
|
|
@ -172,7 +172,7 @@ export function formatUTCTimestamp(now = new Date()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function botHasPermission(guild: Guild | null, permission: number): boolean {
|
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 {
|
export function updateGlobalEmoteRegistry(): void {
|
||||||
|
@ -216,20 +216,22 @@ $.paginate = async (
|
||||||
|
|
||||||
callback(page);
|
callback(page);
|
||||||
};
|
};
|
||||||
|
const BACKWARDS_EMOJI = "⬅️";
|
||||||
|
const FORWARDS_EMOJI = "➡️";
|
||||||
const handle = (emote: string, reacterID: string) => {
|
const handle = (emote: string, reacterID: string) => {
|
||||||
switch (emote) {
|
switch (emote) {
|
||||||
case "⬅️":
|
case BACKWARDS_EMOJI:
|
||||||
turn(-1);
|
turn(-1);
|
||||||
break;
|
break;
|
||||||
case "➡️":
|
case FORWARDS_EMOJI:
|
||||||
turn(1);
|
turn(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Listen for reactions and call the handler.
|
// Listen for reactions and call the handler.
|
||||||
await message.react("⬅️");
|
let backwardsReaction = await message.react(BACKWARDS_EMOJI);
|
||||||
await message.react("➡️");
|
let forwardsReaction = await message.react(FORWARDS_EMOJI);
|
||||||
eventListeners.set(message.id, handle);
|
eventListeners.set(message.id, handle);
|
||||||
await message.awaitReactions(
|
await message.awaitReactions(
|
||||||
(reaction, user) => {
|
(reaction, user) => {
|
||||||
|
@ -248,8 +250,8 @@ $.paginate = async (
|
||||||
);
|
);
|
||||||
// When time's up, remove the bot's own reactions.
|
// When time's up, remove the bot's own reactions.
|
||||||
eventListeners.delete(message.id);
|
eventListeners.delete(message.id);
|
||||||
message.reactions.cache.get("⬅️")?.users.remove(message.author);
|
backwardsReaction.users.remove(message.author);
|
||||||
message.reactions.cache.get("➡️")?.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).
|
// 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) {
|
public save(asynchronous = true) {
|
||||||
const tag = this.__meta__;
|
const tag = this.__meta__;
|
||||||
/// @ts-ignore
|
|
||||||
delete this.__meta__;
|
delete this.__meta__;
|
||||||
FileManager.write(tag, this, asynchronous);
|
FileManager.write(tag, this, asynchronous);
|
||||||
this.__meta__ = tag;
|
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 setup from "./setup";
|
||||||
import {Config} from "./core/structures";
|
import {Config} from "./core/structures";
|
||||||
import {loadCommands} from "./core/command";
|
import {loadCommands} from "./core/command";
|
||||||
|
@ -6,9 +6,37 @@ import {loadEvents} from "./core/event";
|
||||||
import "discord.js-lavalink-lib";
|
import "discord.js-lavalink-lib";
|
||||||
import LavalinkMusic from "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 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.
|
// 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, {
|
(client as any).music = LavalinkMusic(client, {
|
||||||
lavalink: {
|
lavalink: {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"rootDir": "src",
|
"rootDir": "src",
|
||||||
"outDir": "dist",
|
"outDir": "dist",
|
||||||
"target": "ES6",
|
"target": "es2019",
|
||||||
"module": "CommonJS",
|
"module": "CommonJS",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
|
@ -11,7 +11,8 @@
|
||||||
"strictNullChecks": true,
|
"strictNullChecks": true,
|
||||||
"strictFunctionTypes": true,
|
"strictFunctionTypes": true,
|
||||||
"strictPropertyInitialization": true,
|
"strictPropertyInitialization": true,
|
||||||
"removeComments": true
|
"removeComments": true,
|
||||||
|
"sourceMap": true
|
||||||
},
|
},
|
||||||
"exclude": ["test"]
|
"exclude": ["test"]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue