Dependencies update + minor fixes

This commit is contained in:
Vladimir Eremin committed 2022-08-31 11:21:15 +03:00
1 parent 145867cdde
commit 8a4f5806f3
28 files changed
+4396 -4293

No files matched your search

+1
View File
@@ -0,0 +1 @@
node_modules
+21
View File
@@ -0,0 +1,21 @@
FROM node:16
RUN apt -y update
RUN apt install -y ffmpeg
RUN apt install -y python3-pip
WORKDIR /usr/src/app
RUN mkdir bin
RUN curl -L https://yt-dl.org/downloads/latest/youtube-dl -o /usr/src/app/bin/youtube-dl
RUN chmod a+rx /usr/src/app/bin/youtube-dl
COPY package*.json ./
RUN npm install
COPY . .
run npm run build
CMD [ "npm", "start" ]
-1
View File
@@ -1 +0,0 @@
worker: npm start
+3965 -3821
View File
File diff suppressed because it is too large. Load diff
+42 -43
View File
@@ -1,45 +1,44 @@
{ {
"name": "quetza-bot", "name": "quetza-bot",
"engines": { "engines": {
"node": "16.14.x", "node": "16.x.x",
"npm": "*" "npm": "*"
}, },
"version": "2205.3.0", "version": "2205.3.0",
"description": "Discord multifunctional bot", "description": "Discord multifunctional bot",
"author": { "author": {
"name": "unknowableshade", "name": "unknowableshade",
"email": "60275123+unknowableshade@users.noreply.github.com", "email": "60275123+unknowableshade@users.noreply.github.com",
"url": "https://unknowableshade.ru" "url": "https://unknowableshade.ru"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/unknowableshade/quetza-bot.git" "url": "git+https://github.com/unknowableshade/quetza-bot.git"
}, },
"bugs": { "bugs": {
"url": "https://github.com/unknowableshade/quetza-bot/issues" "url": "https://github.com/unknowableshade/quetza-bot/issues"
}, },
"readme": "https://github.com/unknowableshade/quetza-bot#readme", "readme": "https://github.com/unknowableshade/quetza-bot#readme",
"license": "MIT", "license": "MIT",
"main": "dist/index.js", "main": "dist/index.js",
"scripts": { "scripts": {
"start": "node dist/index.js", "start": "node dist/index.js",
"build": "tsc --build", "build": "tsc --build",
"clean": "tsc --build --clean", "clean": "tsc --build --clean"
"postinstall": "npm run build" },
}, "dependencies": {
"dependencies": { "@discordjs/opus": "^0.8.0",
"@discordjs/opus": "^0.7.0", "@discordjs/voice": "^0.11.0",
"@discordjs/voice": "^0.8.0", "discord-ytdl-core": "^5.0.4",
"discord-ytdl-core": "^5.0.4", "discord.js": "^14.3.0",
"discord.js": "^13.6.0", "tweetnacl": "^1.0.3",
"tweetnacl": "^1.0.3", "ytdl-core": "^4.11.1"
"ytdl-core": "^4.10.1" },
}, "devDependencies": {
"devDependencies": { "@types/node": "^18.7.13",
"@types/node": "^17.0.17", "@typescript-eslint/eslint-plugin": "^5.35.1",
"@typescript-eslint/eslint-plugin": "^5.26.0", "@typescript-eslint/parser": "^5.35.1",
"@typescript-eslint/parser": "^5.26.0", "eslint": "^8.22.0",
"eslint": "^8.16.0", "typescript": "^4.8.2"
"typescript": "^4.5.5" }
}
} }
+6 -7
View File
@@ -1,7 +1,7 @@
import Client from "../lib/Client"; import Client from "../lib/Client";
import { CommandInteraction } from "discord.js"; import { CommandInteraction, SlashCommandBuilder } from "discord.js";
import I8n from "../lib/I8n"; import I18n from "../lib/I18n";
export async function run(client: Client, ctx: CommandInteraction) { export async function run(client: Client, ctx: CommandInteraction) {
if (!ctx.guild || !ctx.channel) return; if (!ctx.guild || !ctx.channel) return;
@@ -14,12 +14,11 @@ export async function run(client: Client, ctx: CommandInteraction) {
player.clear(); player.clear();
await ctx.reply({ embeds: [I8n.en.cleared(amount)] }); await ctx.reply({ embeds: [I18n.en.cleared(amount)] });
} }
const data = { const data = new SlashCommandBuilder()
name: "clear", .setName("clear")
description: "Clears the player's queue.", .setDescription("Clear the player's queue.");
};
export { data }; export { data };
+8 -9
View File
@@ -1,7 +1,7 @@
import Client from "../lib/Client"; import Client from "../lib/Client";
import { CommandInteraction, GuildMember } from "discord.js"; import { CommandInteraction, GuildMember, SlashCommandBuilder } from "discord.js";
import I8n from "../lib/I8n"; import I18n from "../lib/I18n";
export async function run(client: Client, ctx: CommandInteraction) { export async function run(client: Client, ctx: CommandInteraction) {
if (!ctx.guild || !ctx.channel || !ctx.member) return; if (!ctx.guild || !ctx.channel || !ctx.member) return;
@@ -17,23 +17,22 @@ export async function run(client: Client, ctx: CommandInteraction) {
if (channel) { if (channel) {
player.connect(channel); player.connect(channel);
await ctx.editReply({ embeds: [I8n.en.okConnected(channel.name)] }); await ctx.editReply({ embeds: [I18n.en.okConnected(channel.name)] });
} else { } else {
client.modules.music.del(ctx.guild.id); client.modules.music.del(ctx.guild.id);
await ctx.editReply({ embeds: [I8n.en.notConnected()] }); await ctx.editReply({ embeds: [I18n.en.notConnected()] });
return undefined; return undefined;
} }
} else { } else {
await ctx.editReply({ embeds: [I8n.en.wasConnected()] }); await ctx.editReply({ embeds: [I18n.en.wasConnected()] });
} }
return player; return player;
} }
const data = { const data = new SlashCommandBuilder()
name: "connect", .setName("connect")
description: "Connects me to a voice channel.", .setDescription("Connect me to a voice channel.");
};
export { data }; export { data };
+105 -110
View File
@@ -1,9 +1,9 @@
import { CommandInteraction } from "discord.js"; import { CommandInteraction, SlashCommandBuilder } from "discord.js";
import Client from "../lib/Client"; import Client from "../lib/Client";
import I8n from "../lib/I8n"; import I18n from "../lib/I18n";
export async function run(client: Client, ctx: CommandInteraction) { export async function run(client: Client, ctx: CommandInteraction) {
const filter = ctx.options.getString("filter"); const filter = ctx.options.get("filter")?.value as string;
if (!ctx.guild || !ctx.channel) return; if (!ctx.guild || !ctx.channel) return;
@@ -13,114 +13,109 @@ export async function run(client: Client, ctx: CommandInteraction) {
player.setFilter(filter || undefined); player.setFilter(filter || undefined);
await ctx.reply({ embeds: [I8n.en.filtered(filter || undefined)] }); await ctx.reply({ embeds: [I18n.en.filtered(filter || undefined)] });
} }
const data = { const data = new SlashCommandBuilder()
name: "filter", .setName("filter")
description: "Apply unique filters to the player's tracks.", .setDescription("Apply unique filters to the tracks.")
options: [ .addStringOption(option => option
{ .setName("filter")
name: "filter", .setDescription("Filter to apply.")
description: "Filter to apply...", .setChoices(
type: "STRING", {
choices: [ name: "bassboost_low",
{ value: "bassboost_low",
name: "bassboost_low", },
value: "bassboost_low", {
}, name: "bassboost",
{ value: "bassboost",
name: "bassboost", },
value: "bassboost", {
}, name: "bassboost_high",
{ value: "bassboost_high",
name: "bassboost_high", },
value: "bassboost_high", {
}, name: "8D",
{ value: "8D",
name: "8D", },
value: "8D", {
}, name: "vaporwave",
{ value: "vaporwave",
name: "vaporwave", },
value: "vaporwave", {
}, name: "nightcore",
{ value: "nightcore",
name: "nightcore", },
value: "nightcore", {
}, name: "phaser",
{ value: "phaser",
name: "phaser", },
value: "phaser", {
}, name: "tremolo",
{ value: "tremolo",
name: "tremolo", },
value: "tremolo", {
}, name: "vibrato",
{ value: "vibrato",
name: "vibrato", },
value: "vibrato", {
}, name: "reverse",
{ value: "reverse",
name: "reverse", },
value: "reverse", {
}, name: "treble",
{ value: "treble",
name: "treble", },
value: "treble", {
}, name: "normalizer",
{ value: "normalizer",
name: "normalizer", },
value: "normalizer", {
}, name: "surrounding",
{ value: "surrounding",
name: "surrounding", },
value: "surrounding", {
}, name: "pulsator",
{ value: "pulsator",
name: "pulsator", },
value: "pulsator", {
}, name: "subboost",
{ value: "subboost",
name: "subboost", },
value: "subboost", {
}, name: "mono",
{ value: "mono",
name: "mono", },
value: "mono", {
}, name: "compressor",
{ value: "compressor",
name: "compressor", },
value: "compressor", {
}, name: "expander",
{ value: "expander",
name: "expander", },
value: "expander", {
}, name: "softlimiter",
{ value: "softlimiter",
name: "softlimiter", },
value: "softlimiter", {
}, name: "chorus",
{ value: "chorus",
name: "chorus", },
value: "chorus", {
}, name: "fadein",
{ value: "fadein",
name: "fadein", },
value: "fadein", {
}, name: "dim",
{ value: "dim",
name: "dim", },
value: "dim", {
}, name: "earrape",
{ value: "earrape",
name: "earrape", })
value: "earrape", .setRequired(true)
}, );
],
required: false,
},
],
};
export { data }; export { data };
+6 -7
View File
@@ -1,7 +1,7 @@
import Client from "../lib/Client"; import Client from "../lib/Client";
import { CommandInteraction } from "discord.js"; import { CommandInteraction, SlashCommandBuilder } from "discord.js";
import I8n from "../lib/I8n"; import I18n from "../lib/I18n";
export async function run(client: Client, ctx: CommandInteraction) { export async function run(client: Client, ctx: CommandInteraction) {
if (!ctx.guild || !ctx.channel || !ctx.member) return; if (!ctx.guild || !ctx.channel || !ctx.member) return;
@@ -10,12 +10,11 @@ export async function run(client: Client, ctx: CommandInteraction) {
const player = client.modules.music.get(ctx.guild.id, ctx.channel); const player = client.modules.music.get(ctx.guild.id, ctx.channel);
await ctx.editReply({ embeds: [I8n.en.playerInfo(player)] }); await ctx.editReply({ embeds: [I18n.en.playerInfo(player)] });
} }
const data = { const data = new SlashCommandBuilder()
name: "info", .setName("info")
description: "Information about the server's player.", .setDescription("Information about the playback.");
};
export { data }; export { data };
+18 -23
View File
@@ -1,10 +1,10 @@
import { CommandInteraction } from "discord.js"; import { CommandInteraction, SlashCommandBuilder } from "discord.js";
import Client from "../lib/Client"; import Client from "../lib/Client";
import I8n from "../lib/I8n"; import I18n from "../lib/I18n";
export async function run(client: Client, ctx: CommandInteraction) { export async function run(client: Client, ctx: CommandInteraction) {
const pos = ctx.options.getInteger("position"); const pos = ctx.options.get("position")?.value as number;
const query = ctx.options.getString("query"); const query = ctx.options.get("query")?.value as string;
if (!ctx.guild || !query || !pos || !ctx.channel) return; if (!ctx.guild || !query || !pos || !ctx.channel) return;
@@ -16,26 +16,21 @@ export async function run(client: Client, ctx: CommandInteraction) {
const track = await player.add(query, ctx.user, pos - 1); const track = await player.add(query, ctx.user, pos - 1);
await ctx.editReply({ embeds: [I8n.en.appended(track)] }); await ctx.editReply({ embeds: [I18n.en.appended(track)] });
} }
const data = { const data = new SlashCommandBuilder()
name: "insert", .setName("insert")
description: "Insert a new track to specific position in the queue.", .setDescription("Insert a new track to specific position in the queue.")
options: [ .addStringOption(option => option
{ .setName("query")
name: "query", .setDescription("Title or URL of the song.")
description: "Title or URL of the song.", .setRequired(true)
type: "STRING", )
required: true, .addIntegerOption(option => option
}, .setName("position")
{ .setDescription("Position to insert.",)
name: "position", .setRequired(true)
description: "Position to insert.", );
type: "INTEGER",
required: true,
},
],
};
export { data }; export { data };
+12 -16
View File
@@ -1,9 +1,9 @@
import { CommandInteraction } from "discord.js"; import { CommandInteraction, SlashCommandBuilder } from "discord.js";
import Client from "../lib/Client"; import Client from "../lib/Client";
import I8n from "../lib/I8n"; import I18n from "../lib/I18n";
export async function run(client: Client, ctx: CommandInteraction) { export async function run(client: Client, ctx: CommandInteraction) {
const query = ctx.options.getString("query"); const query = ctx.options.get("query")?.value as string;
if (!ctx.guild || !query || !ctx.channel) return; if (!ctx.guild || !query || !ctx.channel) return;
@@ -13,20 +13,16 @@ export async function run(client: Client, ctx: CommandInteraction) {
const state = !isNaN(+query) && isFinite(+query) && !/e/i.test(query) ? player.jump(parseInt(query) - 1) : player.jump(query); const state = !isNaN(+query) && isFinite(+query) && !/e/i.test(query) ? player.jump(parseInt(query) - 1) : player.jump(query);
await ctx.reply({ embeds: [I8n.en.jumped(state)] }); await ctx.reply({ embeds: [I18n.en.jumped(state)] });
} }
const data = { const data = new SlashCommandBuilder()
name: "jump", .setName("jump")
description: "Jump to specific track in the queue.", .setDescription("Jump to specific track in the queue.")
options: [ .addStringOption(option => option
{ .setName("query")
name: "query", .setDescription("Position or title to jump to.")
description: "Position or title to jump to.", .setRequired(true)
type: "STRING", );
required: true,
},
],
};
export { data }; export { data };
+15 -22
View File
@@ -1,10 +1,10 @@
import { CommandInteraction } from "discord.js"; import { CommandInteraction, SlashCommandBuilder } from "discord.js";
import Client from "../lib/Client"; import Client from "../lib/Client";
import { loopOption } from "../lib/Types"; import { loopOption } from "../lib/Types";
import I8n from "../lib/I8n"; import I18n from "../lib/I18n";
export async function run(client: Client, ctx: CommandInteraction) { export async function run(client: Client, ctx: CommandInteraction) {
const query = ctx.options.getString("option"); const query = ctx.options.get("option")?.value as string;
if (!ctx.guild || !query || !ctx.channel) return; if (!ctx.guild || !query || !ctx.channel) return;
@@ -14,26 +14,19 @@ export async function run(client: Client, ctx: CommandInteraction) {
player.Queue.Loop = query as loopOption; player.Queue.Loop = query as loopOption;
await ctx.reply({ embeds: [I8n.en.looped(query as loopOption)] }); await ctx.reply({ embeds: [I18n.en.looped(query as loopOption)] });
} }
const data = { const data = new SlashCommandBuilder()
name: "loop", .setName("loop")
description: "Select player's loop mode.", .setDescription("Select player's loop mode.")
options: [ .addStringOption(option => option
{ .setName("option")
name: "option", .setDescription("Select loop option.")
description: "Loop options.", .setChoices( { name: "loop queue", value: "LOOP" },
type: "STRING", { name: "loop single track", value: "SONG" },
required: true, { name: "Till end", value: "NONE" },
choices: [ { name: "Random order", value: "AUTO" })
{ name: "loop queue", value: "LOOP" }, .setRequired(true));
{ name: "loop single track", value: "SONG" },
{ name: "Till end", value: "NONE" },
{ name: "Random order", value: "AUTO" },
],
},
],
};
export { data }; export { data };
+6 -7
View File
@@ -1,6 +1,6 @@
import { CommandInteraction } from "discord.js"; import { CommandInteraction, SlashCommandBuilder } from "discord.js";
import Client from "../lib/Client"; import Client from "../lib/Client";
import I8n from "../lib/I8n"; import I18n from "../lib/I18n";
export async function run(client: Client, ctx: CommandInteraction) { export async function run(client: Client, ctx: CommandInteraction) {
if (!ctx.guild || !ctx.channel) return; if (!ctx.guild || !ctx.channel) return;
@@ -11,12 +11,11 @@ export async function run(client: Client, ctx: CommandInteraction) {
player.skip(); player.skip();
await ctx.reply({ embeds: [I8n.en.skipped()] }); await ctx.reply({ embeds: [I18n.en.skipped()] });
} }
const data = { const data = new SlashCommandBuilder()
name: "next", .setName("next")
description: "Skip to the next song.", .setDescription("Skip current song.");
};
export { data }; export { data };
+6 -7
View File
@@ -1,6 +1,6 @@
import { CommandInteraction } from "discord.js"; import { CommandInteraction, SlashCommandBuilder } from "discord.js";
import Client from "../lib/Client"; import Client from "../lib/Client";
import I8n from "../lib/I8n"; import I18n from "../lib/I18n";
export async function run(client: Client, ctx: CommandInteraction) { export async function run(client: Client, ctx: CommandInteraction) {
if (!ctx.guild || !ctx.channel) return; if (!ctx.guild || !ctx.channel) return;
@@ -11,12 +11,11 @@ export async function run(client: Client, ctx: CommandInteraction) {
const state = player.pause(); const state = player.pause();
await ctx.reply({ embeds: [I8n.en.paused(state)] }); await ctx.reply({ embeds: [I18n.en.paused(state)] });
} }
const data = { const data = new SlashCommandBuilder()
name: "pause", .setName("pause")
description: "Toggle pause on player.", .setDescription("Toggle pause on player.");
};
export { data }; export { data };
+7 -8
View File
@@ -1,23 +1,22 @@
import { CommandInteraction } from "discord.js"; import { CommandInteraction, SlashCommandBuilder } from "discord.js";
import Client from "../lib/Client"; import Client from "../lib/Client";
import I8n from "../lib/I8n"; import I18n from "../lib/I18n";
export async function run(client: Client, ctx: CommandInteraction) { export async function run(client: Client, ctx: CommandInteraction) {
const start = Date.now(); const start = Date.now();
if (!client.application) { if (!client.application) {
await ctx.reply({ embeds: [I8n.en.ping(undefined)] }); await ctx.reply({ embeds: [I18n.en.ping(undefined)] });
return; return;
} }
await client.application.fetch(); await client.application.fetch();
await ctx.reply({ embeds: [I8n.en.ping(Date.now() - start)] }); await ctx.reply({ embeds: [I18n.en.ping(Date.now() - start)] });
} }
const data = { const data = new SlashCommandBuilder()
name: "ping", .setName("ping")
description: "Try to ping me.", .setDescription("Try to ping me.");
};
export { data }; export { data };
+11 -15
View File
@@ -1,10 +1,10 @@
import { CommandInteraction } from "discord.js"; import { CommandInteraction, SlashCommandBuilder } from "discord.js";
import Client from "../lib/Client"; import Client from "../lib/Client";
import { run as connect } from "./connect"; import { run as connect } from "./connect";
import I8n from "../lib/I8n"; import I18n from "../lib/I18n";
export async function run(client: Client, ctx: CommandInteraction) { export async function run(client: Client, ctx: CommandInteraction) {
const query = ctx.options.getString("query"); const query = ctx.options.get("query")?.value as string;
const player = await connect(client, ctx); const player = await connect(client, ctx);
@@ -13,7 +13,7 @@ export async function run(client: Client, ctx: CommandInteraction) {
if (query) { if (query) {
const track = await player.add(query, ctx.user); const track = await player.add(query, ctx.user);
await ctx.editReply({ embeds: [I8n.en.appended(track)] }); await ctx.editReply({ embeds: [I18n.en.appended(track)] });
} }
if (!player.Resource) { if (!player.Resource) {
@@ -21,16 +21,12 @@ export async function run(client: Client, ctx: CommandInteraction) {
} }
} }
const data = { const data = new SlashCommandBuilder()
name: "play", .setName("play")
description: "Launch player and add songs to the queue.", .setDescription("Launch player and add songs to the queue.")
options: [ .addStringOption(option => option
{ .setName("query")
name: "query", .setDescription("Title or URL of the song.")
description: "Title or URL of the song.", );
type: "STRING"
},
],
};
export { data }; export { data };
+21 -19
View File
@@ -1,13 +1,16 @@
import { import {
ActionRowBuilder,
ButtonBuilder,
ButtonInteraction, ButtonInteraction,
ButtonStyle,
CommandInteraction, CommandInteraction,
Message, Message,
MessageActionRow, MessageActionRowComponentBuilder,
MessageButton, SlashCommandBuilder
} from "discord.js"; } from "discord.js";
import Client from "../lib/Client"; import Client from "../lib/Client";
import I8n from "../lib/I8n"; import I18n from "../lib/I18n";
export async function run(client: Client, ctx: CommandInteraction) { export async function run(client: Client, ctx: CommandInteraction) {
if (!ctx.guild || !ctx.channel) return; if (!ctx.guild || !ctx.channel) return;
@@ -19,33 +22,33 @@ export async function run(client: Client, ctx: CommandInteraction) {
await ctx.deferReply(); await ctx.deferReply();
if (player.Queue.empty()) { if (player.Queue.empty()) {
await ctx.editReply({ embeds: [I8n.en.queueEmpty()] }); await ctx.editReply({ embeds: [I18n.en.queueEmpty()] });
return; return;
} }
let page = 0; let page = 0;
const row = new MessageActionRow().addComponents( const row = new ActionRowBuilder<MessageActionRowComponentBuilder>().addComponents(
new MessageButton() new ButtonBuilder()
.setCustomId("QueueTop") .setCustomId("QueueTop")
.setLabel("🔼") .setLabel("🔼")
.setStyle("PRIMARY"), .setStyle(ButtonStyle.Primary),
new MessageButton() new ButtonBuilder()
.setCustomId("QueueUp") .setCustomId("QueueUp")
.setLabel("🔺") .setLabel("🔺")
.setStyle("SECONDARY"), .setStyle(ButtonStyle.Secondary),
new MessageButton() new ButtonBuilder()
.setCustomId("QueueDown") .setCustomId("QueueDown")
.setLabel("🔻") .setLabel("🔻")
.setStyle("SECONDARY"), .setStyle(ButtonStyle.Secondary),
new MessageButton() new ButtonBuilder()
.setCustomId("QueueEnd") .setCustomId("QueueEnd")
.setLabel("🔽") .setLabel("🔽")
.setStyle("PRIMARY") .setStyle(ButtonStyle.Primary)
); );
const message = (await ctx.editReply({ const message = (await ctx.editReply({
embeds: [I8n.en.queueDesigner(player.Queue, 0, player.Resource)], embeds: [I18n.en.queueDesigner(player.Queue, 0, player.Resource)],
components: [row], components: [row],
})) as Message; })) as Message;
@@ -70,14 +73,13 @@ export async function run(client: Client, ctx: CommandInteraction) {
} }
await btn.update({ await btn.update({
embeds: [I8n.en.queueDesigner(player.Queue, page, player.Resource)], embeds: [I18n.en.queueDesigner(player.Queue, page, player.Resource)],
}); });
}); });
} }
const data = { const data = new SlashCommandBuilder()
name: "queue", .setName("queue")
description: "Print out the queue.", .setDescription("Print out the queue.");
};
export { data }; export { data };
+12 -16
View File
@@ -1,9 +1,9 @@
import { CommandInteraction } from "discord.js"; import { CommandInteraction, SlashCommandBuilder } from "discord.js";
import Client from "../lib/Client"; import Client from "../lib/Client";
import I8n from "../lib/I8n"; import I18n from "../lib/I18n";
export async function run(client: Client, ctx: CommandInteraction) { export async function run(client: Client, ctx: CommandInteraction) {
const query = ctx.options.getString("query"); const query = ctx.options.get("query")?.value as string;
if (!ctx.guild || !query || !ctx.channel) return; if (!ctx.guild || !query || !ctx.channel) return;
@@ -13,20 +13,16 @@ export async function run(client: Client, ctx: CommandInteraction) {
const track = !isNaN(+query) && isFinite(+query) && !/e/i.test(query) ? player.remove(parseInt(query) - 1) : player.remove(query); const track = !isNaN(+query) && isFinite(+query) && !/e/i.test(query) ? player.remove(parseInt(query) - 1) : player.remove(query);
await ctx.reply({ embeds: [I8n.en.removed(track)] }); await ctx.reply({ embeds: [I18n.en.removed(track)] });
} }
const data = { const data = new SlashCommandBuilder()
name: "remove", .setName("remove")
description: "Remove specific track in the queue.", .setDescription("Remove specific track in the queue.")
options: [ .addStringOption(option => option
{ .setName("query")
name: "query", .setDescription("Position or title to remove.")
description: "Position or title to remove.", .setRequired(true)
type: "STRING", );
required: true,
},
],
};
export { data }; export { data };
+6 -7
View File
@@ -1,6 +1,6 @@
import { CommandInteraction } from "discord.js"; import { CommandInteraction, SlashCommandBuilder } from "discord.js";
import Client from "../lib/Client"; import Client from "../lib/Client";
import I8n from "../lib/I8n"; import I18n from "../lib/I18n";
export async function run(client: Client, ctx: CommandInteraction) { export async function run(client: Client, ctx: CommandInteraction) {
if (!ctx.guild || !ctx.channel) return; if (!ctx.guild || !ctx.channel) return;
@@ -11,12 +11,11 @@ export async function run(client: Client, ctx: CommandInteraction) {
player.shuffle(); player.shuffle();
await ctx.reply({ embeds: [I8n.en.reshuffle()] }); await ctx.reply({ embeds: [I18n.en.reshuffle()] });
} }
const data = { const data = new SlashCommandBuilder()
name: "reshuffle", .setName("reshuffle")
description: "Shuffle the queue.", .setDescription("Shuffle the queue.");
};
export { data }; export { data };
+21 -30
View File
@@ -1,11 +1,11 @@
import { CommandInteraction } from "discord.js"; import { CommandInteraction, SlashCommandBuilder } from "discord.js";
import Client from "../lib/Client"; import Client from "../lib/Client";
import I8n from "../lib/I8n"; import I18n from "../lib/I18n";
export async function run(client: Client, ctx: CommandInteraction) { export async function run(client: Client, ctx: CommandInteraction) {
const hours = ctx.options.getInteger("hrs") || 0; const hours = ctx.options.get("hrs")?.value as number || 0;
const minutes = ctx.options.getInteger("mins") || 0; const minutes = ctx.options.get("mins")?.value as number || 0;
const seconds = ctx.options.getInteger("secs") || 0; const seconds = ctx.options.get("secs")?.value as number || 0;
if (!ctx.guild || !ctx.channel) return; if (!ctx.guild || !ctx.channel) return;
@@ -18,33 +18,24 @@ export async function run(client: Client, ctx: CommandInteraction) {
player.seek(time * 1000); player.seek(time * 1000);
await ctx.reply({ await ctx.reply({
embeds: [I8n.en.fastForwarded(time)], embeds: [I18n.en.fastForwarded(time)],
}); });
} }
const data = { const data = new SlashCommandBuilder()
name: "seek", .setName("seek")
description: "Fast-forward to the timecode.", .setDescription("Fast-forward by the time.")
options: [ .addIntegerOption(option => option
{ .setName("hrs")
name: "hrs", .setDescription("Hours to seek.")
description: "Hours to seek.", )
type: "INTEGER", .addIntegerOption(option => option
required: false, .setName("mins")
}, .setDescription("Minutes to seek.")
{ )
name: "mins", .addIntegerOption(option => option
description: "Minutes to seek.", .setName("secs")
type: "INTEGER", .setDescription("Seconds to seek.")
required: false, );
},
{
name: "secs",
description: "Seconds to seek.",
type: "INTEGER",
required: false,
},
],
};
export { data }; export { data };
+6 -7
View File
@@ -1,6 +1,6 @@
import { CommandInteraction } from "discord.js"; import { CommandInteraction, SlashCommandBuilder } from "discord.js";
import Client from "../lib/Client"; import Client from "../lib/Client";
import I8n from "../lib/I8n"; import I18n from "../lib/I18n";
export async function run(client: Client, ctx: CommandInteraction) { export async function run(client: Client, ctx: CommandInteraction) {
if (!ctx.guild || !ctx.channel) return; if (!ctx.guild || !ctx.channel) return;
@@ -11,12 +11,11 @@ export async function run(client: Client, ctx: CommandInteraction) {
player.destroy(); player.destroy();
await ctx.reply({ embeds: [I8n.en.destroyed()] }); await ctx.reply({ embeds: [I18n.en.destroyed()] });
} }
const data = { const data = new SlashCommandBuilder()
name: "stop", .setName("stop")
description: "Destroys the player.", .setDescription("Destroy the player.");
};
export { data }; export { data };
+12 -16
View File
@@ -1,9 +1,9 @@
import { CommandInteraction } from "discord.js"; import { CommandInteraction, SlashCommandBuilder } from "discord.js";
import Client from "../lib/Client"; import Client from "../lib/Client";
import I8n from "../lib/I8n"; import I18n from "../lib/I18n";
export async function run(client: Client, ctx: CommandInteraction) { export async function run(client: Client, ctx: CommandInteraction) {
const volume = ctx.options.getInteger("volume") || 100; const volume = ctx.options.get("volume")?.value as number || 100;
if (!ctx.guild || !ctx.channel) return; if (!ctx.guild || !ctx.channel) return;
@@ -13,20 +13,16 @@ export async function run(client: Client, ctx: CommandInteraction) {
player.Volume = volume; player.Volume = volume;
await ctx.reply({ embeds: [I8n.en.volumeSet(player.Volume)] }); await ctx.reply({ embeds: [I18n.en.volumeSet(player.Volume)] });
} }
const data = { const data = new SlashCommandBuilder()
name: "volume", .setName("volume")
description: "Change player's volume amount.", .setDescription("Change player's volume amount.")
options: [ .addIntegerOption(option => option
{ .setName("volume")
name: "volume", .setDescription("Volume in percents.")
description: "Volume in percents.", .setRequired(true)
type: "INTEGER", );
required: true,
},
],
};
export { data }; export { data };
+2 -1
View File
@@ -1,5 +1,6 @@
import Client from "../lib/Client"; import Client from "../lib/Client";
import { generateDependencyReport } from "@discordjs/voice"; import { generateDependencyReport } from "@discordjs/voice";
import { ActivityType } from "discord.js";
export async function run(client: Client): Promise<void> { export async function run(client: Client): Promise<void> {
if (!client.user || !client.application) { if (!client.user || !client.application) {
@@ -9,7 +10,7 @@ export async function run(client: Client): Promise<void> {
console.log(`${client.user.username} logged in as ${client.user.tag}!`); console.log(`${client.user.username} logged in as ${client.user.tag}!`);
console.log(generateDependencyReport()); console.log(generateDependencyReport());
client.user.setActivity("over you", { type: "WATCHING" }); client.user.setActivity("over you", { type: ActivityType.Watching });
const restCommands = Array.from(client.Commands.values()).map( const restCommands = Array.from(client.Commands.values()).map(
value => value.data value => value.data
+2 -2
View File
@@ -1,5 +1,5 @@
import { VoiceState } from "discord.js"; import { VoiceState } from "discord.js";
import I8n from "../lib/I8n"; import I18n from "../lib/I18n";
import Client from "../lib/Client"; import Client from "../lib/Client";
import { asleep } from "../lib/Misc"; import { asleep } from "../lib/Misc";
@@ -14,7 +14,7 @@ export async function run(client: Client, args: VoiceState[]): Promise<void> {
if (oldState.channel.members.filter(value => value.user !== client.user).size === 0) { if (oldState.channel.members.filter(value => value.user !== client.user).size === 0) {
await asleep(30000); await asleep(30000);
if (oldState.channel.members.filter(value => value.user !== client.user).size === 0) { if (oldState.channel.members.filter(value => value.user !== client.user).size === 0) {
await player.Channel.send({ embeds: [I8n.en.fullyAlone()] }); await player.Channel.send({ embeds: [I18n.en.fullyAlone()] });
player.destroy(); player.destroy();
} }
} }
+4 -5
View File
@@ -1,6 +1,5 @@
import { import {
Client as DiscordClient, Client as DiscordClient
Intents,
} from "discord.js"; } from "discord.js";
import { existsSync, readdirSync } from "fs"; import { existsSync, readdirSync } from "fs";
import path from "path"; import path from "path";
@@ -22,9 +21,9 @@ export default class Client extends DiscordClient {
public constructor() { public constructor() {
super({ super({
intents: [ intents: [
Intents.FLAGS.GUILDS, "Guilds",
Intents.FLAGS.GUILD_MESSAGES, "GuildMessages",
Intents.FLAGS.GUILD_VOICE_STATES, "GuildVoiceStates",
], ],
}); });
+62 -73
View File
@@ -1,15 +1,15 @@
import { MessageEmbed } from "discord.js";
import Player from "./Player"; import Player from "./Player";
import { loopOption, track } from "./Types"; import { loopOption, track } from "./Types";
import { loopMoji, secToISO, statusBarGenerator, volumeMoji } from "./Misc"; import { loopMoji, secToISO, statusBarGenerator, volumeMoji } from "./Misc";
import Queue from "./Queue"; import Queue from "./Queue";
import { AudioResource } from "@discordjs/voice"; import { AudioResource } from "@discordjs/voice";
import { EmbedBuilder } from "discord.js";
export default class I8n { export default class I18n {
public static en = { public static en = {
nowPlaying: (track: track) => { nowPlaying: (track: track) => {
return new MessageEmbed() return new EmbedBuilder()
.setColor("LUMINOUS_VIVID_PINK") .setColor("LuminousVividPink")
.setAuthor({ .setAuthor({
iconURL: track.requester.avatarURL() || undefined, iconURL: track.requester.avatarURL() || undefined,
name: track.requester.tag, name: track.requester.tag,
@@ -20,42 +20,42 @@ export default class I8n {
.setThumbnail(track.thumbnail); .setThumbnail(track.thumbnail);
}, },
cleared: (amount: number) => { cleared: (amount: number) => {
return new MessageEmbed() return new EmbedBuilder()
.setColor("GREEN") .setColor("Green")
.setTitle( .setTitle(
`**♻️ ${amount} tracks have been cleared from the queue.**` `**♻️ ${amount} tracks have been cleared from the queue.**`
) )
.setTimestamp(new Date()); .setTimestamp(new Date());
}, },
okConnected: (channel: string) => { okConnected: (channel: string) => {
return new MessageEmbed() return new EmbedBuilder()
.setColor("GREEN") .setColor("Green")
.setTitle(`**✅ Successfuly connected to:** _${channel}_.`); .setTitle(`**✅ Successfuly connected to:** _${channel}_.`);
}, },
notConnected: () => { notConnected: () => {
return new MessageEmbed() return new EmbedBuilder()
.setColor("RED") .setColor("Red")
.setTitle( .setTitle(
"**🚫 Make yourself connected to a voice channel beforehand.**" "**🚫 Make yourself connected to a voice channel beforehand.**"
); );
}, },
wasConnected: () => { wasConnected: () => {
return new MessageEmbed() return new EmbedBuilder()
.setColor("YELLOW") .setColor("Yellow")
.setTitle("**⚠️ Already connected to a voice channel.**"); .setTitle("**⚠️ Already connected to a voice channel.**");
}, },
filtered: (filter?: string) => { filtered: (filter?: string) => {
return new MessageEmbed() return new EmbedBuilder()
.setColor("GREEN") .setColor("Green")
.setTitle(filter ? `**✅ ${filter} was applied to the player.**` : "**✅ All filters were declined.**"); .setTitle(filter ? `**✅ ${filter} was applied to the player.**` : "**✅ All filters were declined.**");
}, },
appended: (track?: track) => { appended: (track?: track) => {
return !track return !track
? new MessageEmbed() ? new EmbedBuilder()
.setColor("RED") .setColor("Red")
.setTitle("**🚫 Could not add track to the queue.**") .setTitle("**🚫 Could not add track to the queue.**")
: new MessageEmbed() : new EmbedBuilder()
.setColor("GREEN") .setColor("Green")
.setTitle(track.title) .setTitle(track.title)
.setURL(track.url) .setURL(track.url)
.setThumbnail(track.thumbnail) .setThumbnail(track.thumbnail)
@@ -68,69 +68,69 @@ export default class I8n {
}, },
jumped: (state: boolean) => { jumped: (state: boolean) => {
return state return state
? new MessageEmbed() ? new EmbedBuilder()
.setColor("GREEN") .setColor("Green")
.setTitle("_**Perfoming jump.**_") .setTitle("_**Perfoming jump.**_")
: new MessageEmbed() : new EmbedBuilder()
.setColor("RED") .setColor("Red")
.setTitle("**❗ Bad _jump_ request.**"); .setTitle("**❗ Bad _jump_ request.**");
}, },
looped: (query: loopOption) => { looped: (query: loopOption) => {
switch (query) { switch (query) {
case "AUTO": { case "AUTO": {
return new MessageEmbed() return new EmbedBuilder()
.setColor("LUMINOUS_VIVID_PINK") .setColor("LuminousVividPink")
.setTitle( .setTitle(
"**🔀 Shuffle mode** _(does not affect the queue order)_." "**🔀 Shuffle mode** _(does not affect the queue order)_."
); );
} }
case "LOOP": { case "LOOP": {
return new MessageEmbed() return new EmbedBuilder()
.setColor("BLUE") .setColor("Blue")
.setTitle("**🔁 Looping over the queue.**"); .setTitle("**🔁 Looping over the queue.**");
} }
case "NONE": { case "NONE": {
return new MessageEmbed() return new EmbedBuilder()
.setColor("RED") .setColor("Red")
.setTitle("**⤵️ Player will stop on the queue end.**"); .setTitle("**⤵️ Player will stop on the queue end.**");
} }
case "SONG": { case "SONG": {
return new MessageEmbed() return new EmbedBuilder()
.setColor("YELLOW") .setColor("Yellow")
.setTitle("**🔂 Looping a single track.**"); .setTitle("**🔂 Looping a single track.**");
} }
} }
}, },
skipped: () => { skipped: () => {
return new MessageEmbed() return new EmbedBuilder()
.setColor("GREEN") .setColor("Green")
.setTitle("**⏭️ Skipping.**"); .setTitle("**⏭️ Skipping.**");
}, },
paused: (state: boolean) => { paused: (state: boolean) => {
return state return state
? new MessageEmbed() ? new EmbedBuilder()
.setColor("GREEN") .setColor("Green")
.setTitle("_**▶️ Resumed.**_") .setTitle("_**▶️ Resumed.**_")
: new MessageEmbed() : new EmbedBuilder()
.setColor("YELLOW") .setColor("Yellow")
.setTitle("_**⏸️ Paused.**_"); .setTitle("_**⏸️ Paused.**_");
}, },
removed: (track?: track) => { removed: (track?: track) => {
return track return track
? new MessageEmbed() ? new EmbedBuilder()
.setColor("GREEN") .setColor("Green")
.setTitle(track.title) .setTitle(track.title)
.setDescription("**was removed from the queue.**") .setDescription("**was removed from the queue.**")
.setTimestamp(new Date()) .setTimestamp(new Date())
.setURL(track.url) .setURL(track.url)
.setThumbnail(track.thumbnail) .setThumbnail(track.thumbnail)
: new MessageEmbed() : new EmbedBuilder()
.setColor("RED") .setColor("Red")
.setTitle("**❗ Bad _remove_ request.**"); .setTitle("**❗ Bad _remove_ request.**");
}, },
fastForwarded: (amount: number) => { fastForwarded: (amount: number) => {
return new MessageEmbed() return new EmbedBuilder()
.setColor("BLUE") .setColor("Blue")
.setTitle( .setTitle(
`**⏩ Fast-forwarding to ${secToISO( `**⏩ Fast-forwarding to ${secToISO(
amount amount
@@ -138,29 +138,29 @@ export default class I8n {
); );
}, },
destroyed: () => { destroyed: () => {
return new MessageEmbed() return new EmbedBuilder()
.setColor("RED") .setColor("Red")
.setTitle("**💀 Destroying the player.**"); .setTitle("**💀 Destroying the player.**");
}, },
volumeSet: (amount: number) => { volumeSet: (amount: number) => {
return new MessageEmbed() return new EmbedBuilder()
.setColor("GREEN") .setColor("Green")
.setTitle(`**${volumeMoji(amount)} Volume has been set to ${amount}%**`); .setTitle(`**${volumeMoji(amount)} Volume has been set to ${amount}%**`);
}, },
queueEmpty: () => { queueEmpty: () => {
return new MessageEmbed() return new EmbedBuilder()
.setColor("YELLOW") .setColor("Yellow")
.setTitle("**❎ Queue is empty.**"); .setTitle("**❎ Queue is empty.**");
}, },
playerInfo: (player?: Player) => { playerInfo: (player?: Player) => {
if (!player) if (!player)
return new MessageEmbed() return new EmbedBuilder()
.setColor("RED") .setColor("Red")
.setTitle("**🚫 Player does not exist.**"); .setTitle("**🚫 Player does not exist.**");
if (player.Resource) { if (player.Resource) {
return new MessageEmbed() return new EmbedBuilder()
.setColor("LUMINOUS_VIVID_PINK") .setColor("LuminousVividPink")
.setTitle( .setTitle(
`${player.Queue.Position + 1}. ${player.Resource.metadata.title}` `${player.Queue.Position + 1}. ${player.Resource.metadata.title}`
) )
@@ -208,8 +208,8 @@ export default class I8n {
}, },
]); ]);
} else { } else {
return new MessageEmbed() return new EmbedBuilder()
.setColor("BLUE") .setColor("Blue")
.setTitle("💿 Insert the disk...") .setTitle("💿 Insert the disk...")
.setDescription(statusBarGenerator(0, 0)) .setDescription(statusBarGenerator(0, 0))
.setURL( .setURL(
@@ -262,8 +262,8 @@ export default class I8n {
Math.min(Math.floor(queue.Tracks.length / 11), page) Math.min(Math.floor(queue.Tracks.length / 11), page)
); );
return new MessageEmbed() return new EmbedBuilder()
.setColor("LUMINOUS_VIVID_PINK") .setColor("LuminousVividPink")
.setTitle( .setTitle(
resource resource
? `${queue.Position + 1}. ${resource.metadata.title}` ? `${queue.Position + 1}. ${resource.metadata.title}`
@@ -301,29 +301,18 @@ export default class I8n {
); );
}, },
fullyAlone: () => { fullyAlone: () => {
return new MessageEmbed() return new EmbedBuilder()
.setColor("LUMINOUS_VIVID_PINK") .setColor("LuminousVividPink")
.setTitle("🥬 I have decided to leave to conserve my energy.") .setTitle("🥬 I have decided to leave to conserve my energy.")
.setDescription( .setDescription(
"_**Since there was nobody in the voice channel.**_" "_**Since there was nobody in the voice channel.**_"
); );
}, },
reshuffle: () => { reshuffle: () => {
return new MessageEmbed() return new EmbedBuilder()
.setColor("GREEN") .setColor("Green")
.setTitle("**✅ Successfuly reshuffled queue.**"); .setTitle("**✅ Successfuly reshuffled queue.**");
}, },
savedQueue: (title: string) => {
return new MessageEmbed()
.setColor("GREEN")
.setTitle(`**✅ Successfuly saved ${title} to the server's storage.**`);
},
savedExceed: (title: string) => {
return new MessageEmbed()
.setColor("RED")
.setTitle(`**🚫 Could not save ${title} to the storage.**`)
.setDescription("_**Delete your old one beforehand...**_");
},
ping: (ping?: number) => { ping: (ping?: number) => {
const title = ping ? `I have pinged ${ping} ms late.` : "There is no application."; const title = ping ? `I have pinged ${ping} ms late.` : "There is no application.";
@@ -331,8 +320,8 @@ export default class I8n {
ping > 200 ? "I can do better than this." : ping > 200 ? "I can do better than this." :
"Dream's speed!"; "Dream's speed!";
return new MessageEmbed() return new EmbedBuilder()
.setColor("RANDOM") .setColor("Random")
.setTitle(`**${title}**`) .setTitle(`**${title}**`)
.setDescription(`_**${comment}**_`); .setDescription(`_**${comment}**_`);
} }
+2 -2
View File
@@ -23,7 +23,7 @@ import Music from "./Music";
import Filter from "./Filter"; import Filter from "./Filter";
import Queue from "./Queue"; import Queue from "./Queue";
import { fetchStream } from "./Fetch"; import { fetchStream } from "./Fetch";
import I8n from "./I8n"; import I18n from "./I18n";
import ytdl from "discord-ytdl-core"; import ytdl from "discord-ytdl-core";
import { track } from "./Types"; import { track } from "./Types";
@@ -136,7 +136,7 @@ export default class Player {
if (this.message) await this.message.delete(); if (this.message) await this.message.delete();
this.message = await this.channel.send({ this.message = await this.channel.send({
embeds: [I8n.en.nowPlaying(track)], embeds: [I18n.en.nowPlaying(track)],
}); });
} }
+17 -19
View File
@@ -1,21 +1,19 @@
{ {
"compilerOptions": { "compilerOptions": {
"baseUrl": "src", "strict": true,
"module": "CommonJS",
"outDir": "./dist", "module": "CommonJS",
"strict": true, "moduleResolution": "node",
"target": "ESNext", "outDir": "dist",
"esModuleInterop": true, "removeComments": false,
"moduleResolution": "Node", "sourceMap": true,
"lib": [ "ESNext" ], "esModuleInterop": true,
"sourceMap": true,
"types": [ "node" ] "target": "ESNext",
}, "lib": ["ESNext"],
"include": [ "types": ["node"],
"src/**/*" "skipLibCheck": true
], },
"exclude": [ "include": ["src/**/*"],
"node_modules", "exclude": ["node_modules", "dist"]
"dist"
]
} }