More slash commands, rework soundboard commands, added generic music and soundboard commands, tweak speechbubble

This commit is contained in:
Essem 2022-04-04 22:05:28 -05:00
parent c821d91254
commit a91c73b5bd
No known key found for this signature in database
GPG key ID: 7D497397CC3A2A8C
68 changed files with 502 additions and 389 deletions

View file

@ -2,6 +2,8 @@ export const commands = new Map();
export const paths = new Map();
export const aliases = new Map();
export const info = new Map();
export const sounds = new Map();
export const categories = new Map();
class TimedMap extends Map {
set(key, value) {

View file

@ -1,4 +1,4 @@
import { paths, commands, info, aliases as _aliases } from "./collections.js";
import { paths, commands, info, sounds, categories, aliases as _aliases } from "./collections.js";
import { log } from "./logger.js";
let queryValue = 0;
@ -13,21 +13,27 @@ export async function load(client, cluster, worker, ipc, command, soundStatus, s
}
const commandArray = command.split("/");
const commandName = commandArray[commandArray.length - 1].split(".")[0];
props.init();
paths.set(commandName, command);
commands.set(commandName, props);
const propsInstance = new props(client, cluster, worker, ipc, {});
if (Object.getPrototypeOf(props).name === "SoundboardCommand") sounds.set(commandName, props.file);
const category = commandArray[commandArray.length - 2];
info.set(commandName, {
category: commandArray[commandArray.length - 2],
category: category,
description: props.description,
aliases: props.aliases,
params: props.arguments,
flags: propsInstance.flags ?? props.flags,
flags: props.flags,
slashAllowed: props.slashAllowed
});
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) => {
@ -37,7 +43,7 @@ export async function load(client, cluster, worker, ipc, command, soundStatus, s
name: commandName,
type: 1,
description: props.description,
options: propsInstance.flags ?? props.flags
options: props.flags
});
}
@ -49,3 +55,30 @@ export async function load(client, cluster, worker, ipc, command, soundStatus, s
}
return commandName;
}
export async function update() {
const commandArray = [];
for (const [name, command] of commands.entries()) {
let cmdInfo = info.get(name);
if (command.postInit) {
const cmd = command.postInit();
//commands.set(name, cmd);
cmdInfo = {
category: cmdInfo.category,
description: cmd.description,
aliases: cmd.aliases,
params: cmd.arguments,
flags: cmd.flags,
slashAllowed: cmd.slashAllowed
};
info.set(name, cmdInfo);
}
if (cmdInfo && cmdInfo.slashAllowed) commandArray.push({
name,
type: 1,
description: cmdInfo.description,
options: cmdInfo.flags
});
}
return commandArray;
}

View file

@ -133,7 +133,7 @@ export default async (client, cmdMessage, interaction, options, extraReturnTypes
// we can get a raw attachment or a URL in the interaction itself
if (options) {
if (options.image) {
const result = await getImage(options.image.proxy_url, options.image.url, video);
const result = await getImage(interaction.data.resolved.attachments[options.image].proxy_url, interaction.data.resolved.attachments[options.image].url, video);
if (result !== false) return result;
} else if (options.link) {
const result = await getImage(options.link, options.link, video);

View file

@ -1,37 +0,0 @@
// eris doesn't come with an awaitMessages method by default, so we make our own
import { EventEmitter } from "events";
class MessageCollector extends EventEmitter {
constructor(client, channel, filter, options = {}) {
super();
this.filter = filter;
this.channel = channel;
this.options = options;
this.ended = false;
this.collected = [];
this.bot = client;
this.listener = message => this.verify(message);
this.bot.on("messageCreate", this.listener);
if (options.time) setTimeout(() => this.stop("time"), options.time);
}
verify(message) {
if (this.channel.id !== message.channel.id) return false;
if (this.filter(message)) {
this.collected.push(message);
this.emit("message", message);
if (this.collected.length >= this.options.maxMatches) this.stop("maxMatches");
return true;
}
return false;
}
stop(reason) {
if (this.ended) return;
this.ended = true;
this.bot.removeListener("messageCreate", this.listener);
this.emit("end", this.collected, reason);
}
}
export default MessageCollector;

View file

@ -50,15 +50,15 @@ export async function connect(client) {
return length;
}
export async function play(client, sound, message, music = false) {
export async function play(client, sound, options, music = false) {
if (!manager) return "The sound commands are still starting up!";
if (!message.channel.guild) return "This command only works in servers!";
if (!message.member.voiceState.channelID) return "You need to be in a voice channel first!";
if (!message.channel.guild.permissionsOf(client.user.id).has("voiceConnect")) return "I can't join this voice channel!";
const voiceChannel = message.channel.guild.channels.get(message.member.voiceState.channelID);
if (!options.channel.guild) return "This command only works in servers!";
if (!options.author.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!";
const voiceChannel = options.channel.guild.channels.get(options.author.voiceState.channelID);
if (!voiceChannel.permissionsOf(client.user.id).has("voiceConnect")) return "I don't have permission to join this voice channel!";
const player = players.get(message.channel.guild.id);
if (!music && manager.voiceStates.has(message.channel.guild.id) && (player && player.type === "music")) return "I can't play a sound effect while playing music!";
const player = players.get(options.channel.guild.id);
if (!music && manager.voiceStates.has(options.channel.guild.id) && (player && player.type === "music")) return "I can't play a sound effect while playing music!";
let node = manager.idealNodes[0];
if (!node) {
const status = await checkStatus();
@ -92,12 +92,12 @@ export async function play(client, sound, message, music = false) {
if (oldQueue && oldQueue.length !== 0 && music) {
return `Your ${playlistInfo.name ? "playlist" : "tune"} \`${playlistInfo.name ? playlistInfo.name.trim() : (tracks[0].info.title !== "" ? tracks[0].info.title.trim() : "(blank)")}\` has been added to the queue!`;
} else {
nextSong(client, message, connection, tracks[0].track, tracks[0].info, music, voiceChannel, player ? player.host : message.author.id, player ? player.loop : false, player ? player.shuffle : false);
nextSong(client, options, connection, tracks[0].track, tracks[0].info, music, voiceChannel, player ? player.host : options.author.id, player ? player.loop : false, player ? player.shuffle : false);
return;
}
}
export async function nextSong(client, message, connection, track, info, music, voiceChannel, host, loop = false, shuffle = false, lastTrack = null) {
export async function nextSong(client, options, connection, track, info, music, voiceChannel, host, loop = false, shuffle = false, lastTrack = null) {
skipVotes.delete(voiceChannel.guild.id);
const parts = Math.floor((0 / info.length) * 10);
let playingMessage;
@ -114,7 +114,7 @@ export async function nextSong(client, message, connection, track, info, music,
playingMessage = players.get(voiceChannel.guild.id).playMessage;
} else {
try {
playingMessage = await client.createMessage(message.channel.id, !music ? "🔊 Playing sound..." : {
const content = !music ? "🔊 Playing sound..." : {
embeds: [{
color: 16711680,
author: {
@ -138,7 +138,13 @@ export async function nextSong(client, message, connection, track, info, music,
value: `0:00/${info.isStream ? "∞" : format(info.length)}`
}]
}]
});
};
if (options.type === "classic") {
playingMessage = await client.createMessage(options.channel.id, content);
} else {
await options.interaction[options.interaction.acknowledged ? "editOriginalMessage" : "createMessage"](content);
playingMessage = await options.interaction.getOriginalMessage();
}
} catch {
// no-op
}
@ -147,7 +153,7 @@ export async function nextSong(client, message, connection, track, info, music,
connection.removeAllListeners("end");
await connection.play(track);
await connection.volume(75);
players.set(voiceChannel.guild.id, { player: connection, type: music ? "music" : "sound", host: host, voiceChannel: voiceChannel, originalChannel: message.channel, loop: loop, shuffle: shuffle, playMessage: playingMessage });
players.set(voiceChannel.guild.id, { player: connection, type: music ? "music" : "sound", host: host, voiceChannel: voiceChannel, originalChannel: options.channel, loop: loop, shuffle: shuffle, playMessage: playingMessage });
connection.once("error", async (error) => {
try {
if (playingMessage.channel.messages.has(playingMessage.id)) await playingMessage.delete();
@ -166,7 +172,7 @@ export async function nextSong(client, message, connection, track, info, music,
players.delete(voiceChannel.guild.id);
queues.delete(voiceChannel.guild.id);
logger.error(error);
await client.createMessage(message.channel.id, `🔊 Looks like there was an error regarding sound playback:\n\`\`\`${error.type}: ${error.error}\`\`\``);
await (options.type === "classic" ? options.channel.createMessage : options.interaction.createMessage)(`🔊 Looks like there was an error regarding sound playback:\n\`\`\`${error.type}: ${error.error}\`\`\``);
});
connection.on("end", async (data) => {
if (data.reason === "REPLACED") return;
@ -194,7 +200,7 @@ export async function nextSong(client, message, connection, track, info, music,
queues.set(voiceChannel.guild.id, newQueue);
if (newQueue.length !== 0) {
const newTrack = await Rest.decode(connection.node, newQueue[0]);
nextSong(client, message, connection, newQueue[0], newTrack, music, voiceChannel, host, player.loop, player.shuffle, track);
nextSong(client, options, connection, newQueue[0], newTrack, music, voiceChannel, host, player.loop, player.shuffle, track);
try {
if (newQueue[0] !== track && playingMessage.channel.messages.has(playingMessage.id)) await playingMessage.delete();
if (newQueue[0] !== track && player.playMessage.channel.messages.has(player.playMessage.id)) await player.playMessage.delete();
@ -207,7 +213,7 @@ export async function nextSong(client, message, connection, track, info, music,
players.delete(voiceChannel.guild.id);
queues.delete(voiceChannel.guild.id);
skipVotes.delete(voiceChannel.guild.id);
if (music) await client.createMessage(message.channel.id, "🔊 The current voice channel session has ended.");
if (music) await (options.type === "classic" ? options.channel.createMessage : options.interaction.createMessage)("🔊 The current voice channel session has ended.");
try {
if (playingMessage.channel.messages.has(playingMessage.id)) await playingMessage.delete();
if (player && player.playMessage.channel.messages.has(player.playMessage.id)) await player.playMessage.delete();