Added (hacky) message command support, lots of work to prepare for message content intent enforcement, improve broadcast, remove evalraw, update packages

This commit is contained in:
Essem 2022-08-31 20:00:34 -05:00
parent 3392c3c89e
commit d33a7804d7
No known key found for this signature in database
GPG key ID: 7D497397CC3A2A8C
56 changed files with 443 additions and 315 deletions

View file

@ -1,4 +1,5 @@
export const commands = new Map();
export const messageCommands = new Map();
export const paths = new Map();
export const aliases = new Map();
export const info = new Map();
@ -6,15 +7,20 @@ export const sounds = new Map();
export const categories = new Map();
class TimedMap extends Map {
constructor(time, values) {
super(values);
this.time = time;
}
set(key, value) {
super.set(key, value);
setTimeout(() => {
if (super.has(key)) super.delete(key);
}, 5000);
}, this.time);
}
}
export const runningCommands = new TimedMap();
export const runningCommands = new TimedMap(5000);
export const selectedImages = new TimedMap(180000);
class Cache extends Map {
constructor(values) {

View file

@ -1,4 +1,4 @@
import { paths, commands, info, sounds, categories, aliases as _aliases } from "./collections.js";
import { paths, commands, messageCommands, info, sounds, categories, aliases as _aliases } from "./collections.js";
import { log } from "./logger.js";
import { readFileSync } from "fs";
@ -16,46 +16,62 @@ export async function load(client, cluster, worker, ipc, command, soundStatus, s
return;
}
const commandArray = command.split("/");
const commandName = commandArray[commandArray.length - 1].split(".")[0];
let commandName = commandArray[commandArray.length - 1].split(".")[0];
const category = commandArray[commandArray.length - 2];
if (blacklist.includes(commandName)) {
log("warn", `Skipped loading blacklisted command ${command}...`);
return;
}
if (category === "message") {
const nameStringArray = commandName.split("-");
for (const index of nameStringArray.keys()) {
nameStringArray[index] = nameStringArray[index].charAt(0).toUpperCase() + nameStringArray[index].slice(1);
}
commandName = nameStringArray.join(" ");
}
props.init();
paths.set(commandName, command);
commands.set(commandName, props);
if (Object.getPrototypeOf(props).name === "SoundboardCommand") sounds.set(commandName, props.file);
const category = commandArray[commandArray.length - 2];
info.set(commandName, {
const commandInfo = {
category: category,
description: props.description,
aliases: props.aliases,
params: props.arguments,
flags: props.flags,
slashAllowed: props.slashAllowed,
directAllowed: props.directAllowed
});
directAllowed: props.directAllowed,
type: 1
};
if (category === "message") {
messageCommands.set(commandName, props);
commandInfo.type = 3;
} else {
commands.set(commandName, props);
if (slashReload && props.slashAllowed) {
const commandList = await client.getCommands();
const oldCommand = commandList.filter((item) => {
return item.name === commandName;
})[0];
await client.editCommand(oldCommand.id, {
name: commandName,
type: 1,
description: props.description,
options: props.flags
});
}
}
if (Object.getPrototypeOf(props).name === "SoundboardCommand") sounds.set(commandName, props.file);
info.set(commandName, commandInfo);
const categoryCommands = categories.get(category);
categories.set(category, categoryCommands ? [...categoryCommands, commandName] : [commandName]);
if (slashReload && props.slashAllowed) {
const commandList = await client.getCommands();
const oldCommand = commandList.filter((item) => {
return item.name === commandName;
})[0];
await client.editCommand(oldCommand.id, {
name: commandName,
type: 1,
description: props.description,
options: props.flags
});
}
if (props.aliases) {
for (const alias of props.aliases) {
@ -68,11 +84,11 @@ export async function load(client, cluster, worker, ipc, command, soundStatus, s
export async function update() {
const commandArray = [];
for (const [name, command] of commands.entries()) {
const merged = new Map([...commands, ...messageCommands]);
for (const [name, command] of merged.entries()) {
let cmdInfo = info.get(name);
if (command.postInit) {
const cmd = command.postInit();
//commands.set(name, cmd);
cmdInfo = {
category: cmdInfo.category,
description: cmd.description,
@ -80,17 +96,26 @@ export async function update() {
params: cmd.arguments,
flags: cmd.flags,
slashAllowed: cmd.slashAllowed,
directAllowed: cmd.directAllowed
directAllowed: cmd.directAllowed,
type: cmdInfo.type
};
info.set(name, cmdInfo);
}
if (cmdInfo?.slashAllowed) commandArray.push({
name,
type: 1,
description: cmdInfo.description,
options: cmdInfo.flags,
dm_permission: cmdInfo.directAllowed
});
if (cmdInfo?.type === 3) {
commandArray.push({
name: name,
type: cmdInfo.type,
dm_permission: cmdInfo.directAllowed
});
} else if (cmdInfo?.slashAllowed) {
commandArray.push({
name,
type: cmdInfo.type,
description: cmdInfo.description,
options: cmdInfo.flags,
dm_permission: cmdInfo.directAllowed
});
}
}
return commandArray;
}

View file

@ -133,7 +133,7 @@ const checkImages = async (message, extraReturnTypes, video, sticker) => {
};
// this checks for the latest message containing an image and returns the url of the image
export default async (client, cmdMessage, interaction, options, extraReturnTypes = false, video = false, sticker = false) => {
export default async (client, cmdMessage, interaction, options, extraReturnTypes = false, video = false, sticker = false, singleMessage = false) => {
// we start by determining whether or not we're dealing with an interaction or a message
if (interaction) {
// we can get a raw attachment or a URL in the interaction itself
@ -147,7 +147,8 @@ export default async (client, cmdMessage, interaction, options, extraReturnTypes
if (result !== false) return result;
}
}
} else {
}
if (cmdMessage) {
// check if the message is a reply to another message
if (cmdMessage.messageReference) {
const replyMessage = await client.getMessage(cmdMessage.messageReference.channelID, cmdMessage.messageReference.messageID).catch(() => undefined);
@ -160,15 +161,17 @@ export default async (client, cmdMessage, interaction, options, extraReturnTypes
const result = await checkImages(cmdMessage, extraReturnTypes, video, sticker);
if (result !== false) return result;
}
// if there aren't any replies or interaction attachments then iterate over the last few messages in the channel
const messages = await client.getMessages((interaction ? interaction : cmdMessage).channel.id);
// iterate over each message
for (const message of messages) {
const result = await checkImages(message, extraReturnTypes, video, sticker);
if (result === false) {
continue;
} else {
return result;
if (!singleMessage) {
// if there aren't any replies or interaction attachments then iterate over the last few messages in the channel
const messages = await client.getMessages((interaction ? interaction : cmdMessage).channel.id);
// iterate over each message
for (const message of messages) {
const result = await checkImages(message, extraReturnTypes, video, sticker);
if (result === false) {
continue;
} else {
return result;
}
}
}
};

View file

@ -60,13 +60,13 @@ export function reload() {
}
export async function play(client, sound, options, music = false) {
if (!manager) return "The sound commands are still starting up!";
if (!options.channel.guild) return "This command only works in servers!";
if (!options.member.voiceState.channelID) return "You need to be in a voice channel first!";
if (!options.channel.guild.permissionsOf(client.user.id).has("voiceConnect")) return "I can't join this voice channel!";
if (!manager) return { content: "The sound commands are still starting up!", flags: 64 };
if (!options.channel.guild) return { content: "This command only works in servers!", flags: 64 };
if (!options.member.voiceState.channelID) return { content: "You need to be in a voice channel first!", flags: 64 };
if (!options.channel.guild.permissionsOf(client.user.id).has("voiceConnect")) return { content: "I can't join this voice channel!", flags: 64 };
const voiceChannel = options.channel.guild.channels.get(options.member.voiceState.channelID);
if (!voiceChannel.permissionsOf(client.user.id).has("voiceConnect")) return "I don't have permission to join this voice channel!";
if (!music && manager.players.has(options.channel.guild.id)) return "I can't play a sound effect while other audio is playing!";
if (!voiceChannel.permissionsOf(client.user.id).has("voiceConnect")) return { content: "I don't have permission to join this voice channel!", flags: 64 };
if (!music && manager.players.has(options.channel.guild.id)) return { content: "I can't play a sound effect while other audio is playing!", flags: 64 };
let node = manager.getNode();
if (!node) {
const status = await checkStatus();
@ -81,14 +81,14 @@ export async function play(client, sound, options, music = false) {
let response;
try {
response = await node.rest.resolve(sound);
if (!response) return "🔊 I couldn't get a response from the audio server.";
if (response.loadType === "NO_MATCHES" || response.loadType === "LOAD_FAILED") return "I couldn't find that song!";
if (!response) return { content: "🔊 I couldn't get a response from the audio server.", flags: 64 };
if (response.loadType === "NO_MATCHES" || response.loadType === "LOAD_FAILED") return { content: "I couldn't find that song!", flags: 64 };
} catch (e) {
logger.error(e);
return "🔊 Hmmm, seems that all of the audio servers are down. Try again in a bit.";
return { content: "🔊 Hmmm, seems that all of the audio servers are down. Try again in a bit.", flags: 64 };
}
const oldQueue = queues.get(voiceChannel.guild.id);
if (!response.tracks || response.tracks.length === 0) return "I couldn't find that song!";
if (!response.tracks || response.tracks.length === 0) return { content: "I couldn't find that song!", flags: 64 };
if (music) {
const sortedTracks = response.tracks.map((val) => { return val.track; });
const playlistTracks = response.playlistInfo.selectedTrack ? sortedTracks : [sortedTracks[0]];