update to discord-player-v6 #76
27 changed files with 368 additions and 3237 deletions
|
@ -7,6 +7,7 @@ pipeline:
|
||||||
auto_tag: true
|
auto_tag: true
|
||||||
registry: git.mylloon.fr
|
registry: git.mylloon.fr
|
||||||
username: ${CI_REPO_OWNER}
|
username: ${CI_REPO_OWNER}
|
||||||
|
dockerfile: Docker/Dockerfile.debian
|
||||||
password:
|
password:
|
||||||
from_secret: cb_token
|
from_secret: cb_token
|
||||||
when:
|
when:
|
||||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -12,3 +12,6 @@ dist/
|
||||||
|
|
||||||
# Databse
|
# Databse
|
||||||
*.sqlite3
|
*.sqlite3
|
||||||
|
|
||||||
|
# Debug file
|
||||||
|
src/events/player/debug.ts
|
||||||
|
|
|
@ -5,9 +5,9 @@ Lisez attentivement si vous êtes un nouveau contributeur.
|
||||||
|
|
||||||
Ce guide n'est pas fixe et est mis à jour régulièrement. Si vous
|
Ce guide n'est pas fixe et est mis à jour régulièrement. Si vous
|
||||||
trouvez un problème quelconque, n'hésitez pas à le signaler par le biais
|
trouvez un problème quelconque, n'hésitez pas à le signaler par le biais
|
||||||
d'un [ticket](https://git.kennel.ml/ConfrerieDuKassoulait/Botanique/issues) ou
|
d'un [ticket](https://git.mylloon.fr/ConfrerieDuKassoulait/Botanique/issues) ou
|
||||||
à le corriger directement en soumettant
|
à le corriger directement en soumettant
|
||||||
une [Pull Request](https://git.kennel.ml/ConfrerieDuKassoulait/Botanique/pulls).
|
une [Pull Request](https://git.mylloon.fr/ConfrerieDuKassoulait/Botanique/pulls).
|
||||||
|
|
||||||
## Sommaire <!-- omit in toc -->
|
## Sommaire <!-- omit in toc -->
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ une [Pull Request](https://git.kennel.ml/ConfrerieDuKassoulait/Botanique/pulls).
|
||||||
- [Projet](#projet)
|
- [Projet](#projet)
|
||||||
- [Ajouter une commande](#ajouter-une-commande)
|
- [Ajouter une commande](#ajouter-une-commande)
|
||||||
- [Ajouter un évènement](#ajouter-un-évènement)
|
- [Ajouter un évènement](#ajouter-un-évènement)
|
||||||
|
- [Player](#player)
|
||||||
- [Modèles](#modèles)
|
- [Modèles](#modèles)
|
||||||
- [Boutons](#boutons)
|
- [Boutons](#boutons)
|
||||||
- [Modifier du code](#modifier-du-code)
|
- [Modifier du code](#modifier-du-code)
|
||||||
|
@ -157,6 +158,9 @@ Vous devez aussi ajouter **obligatoirement** :
|
||||||
- `"c_COMMANDE_desc": "DESCRIPTION"` au fichier de langue, avec `COMMANDE`
|
- `"c_COMMANDE_desc": "DESCRIPTION"` au fichier de langue, avec `COMMANDE`
|
||||||
le nom de la commande et `DESCRIPTION` la description de votre commande.
|
le nom de la commande et `DESCRIPTION` la description de votre commande.
|
||||||
|
|
||||||
|
> Note: Il est possible d'ajouter de l'autocomplétion via
|
||||||
|
> un 4ème élément : `autocomplete`.
|
||||||
|
|
||||||
## Ajouter un évènement
|
## Ajouter un évènement
|
||||||
|
|
||||||
Pour ajouter le support d'un évènement au bot, créez un fichier
|
Pour ajouter le support d'un évènement au bot, créez un fichier
|
||||||
|
@ -174,6 +178,23 @@ De préférence, merci de mettre un lien en commentaire vers la documentation
|
||||||
de discord.js de l'évènement
|
de discord.js de l'évènement
|
||||||
([exemple ici pour l'évènement `ready`](./src/events/client/ready.ts#L3))
|
([exemple ici pour l'évènement `ready`](./src/events/client/ready.ts#L3))
|
||||||
|
|
||||||
|
### Player
|
||||||
|
|
||||||
|
Les évènement du player ont la même logique les autres, mais sont placés
|
||||||
|
dans le dossier [`player`](./src/events/player/).
|
||||||
|
|
||||||
|
> Pour débogguer le player, il est possible d'ajouter un évènement `debug`, en
|
||||||
|
> voici un exemple :
|
||||||
|
>
|
||||||
|
> ```ts
|
||||||
|
> import { GuildQueue } from "discord-player";
|
||||||
|
>
|
||||||
|
> /** https://discord-player.js.org/docs/types/discord-player/GuildQueueEvents */
|
||||||
|
> export default (_: GuildQueue, message: string) => {
|
||||||
|
> console.info(message);
|
||||||
|
> };
|
||||||
|
> ```
|
||||||
|
|
||||||
## Modèles
|
## Modèles
|
||||||
|
|
||||||
Les modèles sont gérés [en dehors séparément du reste](./src/modals/).
|
Les modèles sont gérés [en dehors séparément du reste](./src/modals/).
|
||||||
|
@ -194,11 +215,11 @@ Quand vous modifiez quelque chose, pensez à mettre-à-jour les langues. Si vous
|
||||||
ne savez pas traduire dans une langue, ne vous forcez pas, supprimer simplement
|
ne savez pas traduire dans une langue, ne vous forcez pas, supprimer simplement
|
||||||
la traduction.
|
la traduction.
|
||||||
|
|
||||||
- [Créez un fork](https://git.kennel.ml/repo/fork/76) et poussez
|
- [Créez un fork](https://git.mylloon.fr/repo/fork/76) et poussez
|
||||||
vos modifications dans ce dernier.
|
vos modifications dans ce dernier.
|
||||||
|
|
||||||
Pour commencer, vous pouvez jeté un oeil aux
|
Pour commencer, vous pouvez jeté un oeil aux
|
||||||
[tickets facilement résolvable](https://git.kennel.ml/ConfrerieDuKassoulait/Botanique/issues?state=open&labels=82).
|
[tickets facilement résolvable](https://git.mylloon.fr/ConfrerieDuKassoulait/Botanique/issues?state=open&labels=82).
|
||||||
|
|
||||||
- De préférences, les fonctions, méthodes et variables seront écrites
|
- De préférences, les fonctions, méthodes et variables seront écrites
|
||||||
en anglais, ainsi que les commits afin que chacun puisse contribuer.
|
en anglais, ainsi que les commits afin que chacun puisse contribuer.
|
||||||
|
@ -219,7 +240,7 @@ Pour commencer, vous pouvez jeté un oeil aux
|
||||||
fonctionneront avec `npm run main`, ainsi que dans l'image Docker.
|
fonctionneront avec `npm run main`, ainsi que dans l'image Docker.
|
||||||
|
|
||||||
4. Lorsque vous vous sentez confiant dans vos modifications, ouvrez
|
4. Lorsque vous vous sentez confiant dans vos modifications, ouvrez
|
||||||
une [Pull Request](https://git.kennel.ml/ConfrerieDuKassoulait/Botanique/pulls)
|
une [Pull Request](https://git.mylloon.fr/ConfrerieDuKassoulait/Botanique/pulls)
|
||||||
afin que votre code puisse être revu et fusionné. Vous pouvez suivre cette
|
afin que votre code puisse être revu et fusionné. Vous pouvez suivre cette
|
||||||
[condition de nommage](https://gist.github.com/joshbuchea/6f47e86d2510bce28f8e7f42ae84c716#example),
|
[condition de nommage](https://gist.github.com/joshbuchea/6f47e86d2510bce28f8e7f42ae84c716#example),
|
||||||
ça aide à s'y retrouver plus rapidement.
|
ça aide à s'y retrouver plus rapidement.
|
||||||
|
@ -237,7 +258,7 @@ Pour commencer, vous pouvez jeté un oeil aux
|
||||||
- On ne push jamais directement sur la branche `main`.
|
- On ne push jamais directement sur la branche `main`.
|
||||||
- Quand on merge des modifications vers `main`, on fait un _squash_,
|
- Quand on merge des modifications vers `main`, on fait un _squash_,
|
||||||
l'historique des modifications reste disponible dans
|
l'historique des modifications reste disponible dans
|
||||||
[le graph](https://git.kennel.ml/ConfrerieDuKassoulait/Botanique/graph).
|
[le graph](https://git.mylloon.fr/ConfrerieDuKassoulait/Botanique/graph).
|
||||||
- De préférences, suivre les indications de
|
- De préférences, suivre les indications de
|
||||||
[ce post](https://gist.github.com/revett/88ee5abf5a9a097b4c88) (c'est un peu la
|
[ce post](https://gist.github.com/revett/88ee5abf5a9a097b4c88) (c'est un peu la
|
||||||
même que dans le `4.` de [la partie précédente](#soumettre-ses-modifications)).
|
même que dans le `4.` de [la partie précédente](#soumettre-ses-modifications)).
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
FROM node:19.4.0-alpine3.16
|
FROM node:19.7.0-alpine3.17
|
||||||
|
|
||||||
ENV DOCKERIZED=1
|
ENV DOCKERIZED=1
|
||||||
RUN mkdir /config
|
RUN mkdir /config
|
||||||
|
@ -12,10 +12,10 @@ WORKDIR /app
|
||||||
|
|
||||||
COPY --chown=node:node . .
|
COPY --chown=node:node . .
|
||||||
|
|
||||||
RUN npm ci --only=production --legacy-peer-deps
|
RUN npm ci --only=production
|
||||||
RUN npx tsc
|
RUN npx tsc
|
||||||
|
|
||||||
RUN rm -r src/ tsconfig.json
|
RUN rm -r src/ tsconfig.json
|
||||||
RUN npm uninstall typescript @types/sqlite3 --legacy-peer-deps
|
RUN npm uninstall typescript @types/sqlite3
|
||||||
|
|
||||||
CMD ["dumb-init", "node", "./dist/index.js"]
|
CMD ["dumb-init", "node", "./dist/index.js"]
|
22
Docker/Dockerfile.debian
Normal file
22
Docker/Dockerfile.debian
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
|
FROM node:19.7.0-bullseye-slim
|
||||||
|
|
||||||
|
ENV DOCKERIZED=1
|
||||||
|
RUN mkdir /config
|
||||||
|
RUN chown node:node /config
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
RUN apt-get install -y dumb-init
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY --chown=node:node . .
|
||||||
|
|
||||||
|
RUN npm ci --only=production
|
||||||
|
RUN npx tsc
|
||||||
|
|
||||||
|
RUN rm -r src/ tsconfig.json
|
||||||
|
RUN npm uninstall typescript @types/sqlite3
|
||||||
|
|
||||||
|
CMD ["dumb-init", "node", "./dist/index.js"]
|
|
@ -13,7 +13,7 @@
|
||||||
> Installer les dépendances du bot
|
> Installer les dépendances du bot
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install --legacy-peer-deps
|
npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
> Lancer le bot
|
> Lancer le bot
|
||||||
|
|
3371
package-lock.json
generated
3371
package-lock.json
generated
File diff suppressed because it is too large
Load diff
11
package.json
11
package.json
|
@ -11,28 +11,29 @@
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git@git.kennel.ml:ConfrerieDuKassoulait/Botanique.git"
|
"url": "git@git.mylloon.fr:ConfrerieDuKassoulait/Botanique.git"
|
||||||
},
|
},
|
||||||
"author": "La confrérie du Kassoulait",
|
"author": "La confrérie du Kassoulait",
|
||||||
"license": "GPL-3.0-only",
|
"license": "GPL-3.0-only",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@discord-player/extractor": "^4.0.0",
|
"@discord-player/extractor": "^4.1.1",
|
||||||
"@discordjs/opus": "^0.9.0",
|
"@discordjs/opus": "^0.9.0",
|
||||||
"@discordjs/rest": "^1.5.0",
|
"@discordjs/rest": "^1.5.0",
|
||||||
"@types/sqlite3": "^3.1.8",
|
"@types/sqlite3": "^3.1.8",
|
||||||
"@types/uuid": "^9.0.0",
|
"@types/uuid": "^9.0.0",
|
||||||
"discord-api-types": "^0.37.32",
|
"discord-player": "^6.1.0",
|
||||||
"discord-player": "^5.4.1-dev.0",
|
|
||||||
"discord.js": "^14.7.1",
|
"discord.js": "^14.7.1",
|
||||||
"ffmpeg-static": "^5.1.0",
|
"ffmpeg-static": "^5.1.0",
|
||||||
"genius-lyrics": "^4.4.3",
|
"genius-lyrics": "^4.4.3",
|
||||||
"node-fetch": "^2.6.9",
|
"node-fetch": "^2.6.9",
|
||||||
"play-dl": "^1.9.6",
|
"play-dl": "^1.9.6",
|
||||||
"prism-media": "^1.3.4",
|
|
||||||
"sqlite3": "^5.1.4",
|
"sqlite3": "^5.1.4",
|
||||||
"typescript": "^4.9.5",
|
"typescript": "^4.9.5",
|
||||||
"uuid": "^9.0.0"
|
"uuid": "^9.0.0"
|
||||||
},
|
},
|
||||||
|
"overrides": {
|
||||||
|
"discord-api-types": "0.37.34"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@typescript-eslint/eslint-plugin": "^5.30.7",
|
"@typescript-eslint/eslint-plugin": "^5.30.7",
|
||||||
"@typescript-eslint/parser": "^5.30.7",
|
"@typescript-eslint/parser": "^5.30.7",
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { useQueue } from "discord-player";
|
||||||
import {
|
import {
|
||||||
ActionRowBuilder,
|
ActionRowBuilder,
|
||||||
ButtonBuilder,
|
ButtonBuilder,
|
||||||
|
@ -30,7 +31,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get queue
|
// Get queue
|
||||||
const queue = client.player.queues.get(interaction.guildId ?? "");
|
const queue = useQueue(interaction.guildId ?? "");
|
||||||
|
|
||||||
const embed = new EmbedBuilder();
|
const embed = new EmbedBuilder();
|
||||||
const rows = [];
|
const rows = [];
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { useQueue } from "discord-player";
|
||||||
import {
|
import {
|
||||||
ActionRowBuilder,
|
ActionRowBuilder,
|
||||||
ButtonBuilder,
|
ButtonBuilder,
|
||||||
|
@ -30,7 +31,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get queue
|
// Get queue
|
||||||
const queue = client.player.queues.get(interaction.guildId ?? "");
|
const queue = useQueue(interaction.guildId ?? "");
|
||||||
|
|
||||||
const embed = new EmbedBuilder();
|
const embed = new EmbedBuilder();
|
||||||
const rows = [];
|
const rows = [];
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||||
|
import { Player, useMasterPlayer, useQueue } from "discord-player";
|
||||||
import { ChatInputCommandInteraction, Client, EmbedBuilder } from "discord.js";
|
import { ChatInputCommandInteraction, Client, EmbedBuilder } from "discord.js";
|
||||||
import { getLocale, getLocalizations } from "../../utils/locales";
|
import { getLocale, getLocalizations } from "../../utils/locales";
|
||||||
import { getFilename } from "../../utils/misc";
|
import { getFilename } from "../../utils/misc";
|
||||||
|
@ -44,19 +45,20 @@ export default {
|
||||||
let data = null;
|
let data = null;
|
||||||
await interaction.deferReply();
|
await interaction.deferReply();
|
||||||
|
|
||||||
|
const player = useMasterPlayer() as Player;
|
||||||
if (request) {
|
if (request) {
|
||||||
try {
|
try {
|
||||||
data = await client.player.lyrics.search(request);
|
data = await player.lyrics.search(request);
|
||||||
} catch {
|
} catch {
|
||||||
return await interaction.followUp(`❌ | ${loc.get("c_lyrics2")} \`${request}\``);
|
return await interaction.followUp(`❌ | ${loc.get("c_lyrics2")} \`${request}\``);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const queue = client.player.queues.get(interaction.guildId ?? "");
|
const queue = useQueue(interaction.guildId ?? "");
|
||||||
if (queue) {
|
if (queue) {
|
||||||
const title = queue.current?.title;
|
const title = queue.history.currentTrack?.title;
|
||||||
if (title) {
|
if (title) {
|
||||||
try {
|
try {
|
||||||
data = await client.player.lyrics.search(title + " " + queue.current.author);
|
data = await player.lyrics.search(title + " " + queue.history.currentTrack?.author);
|
||||||
} catch {
|
} catch {
|
||||||
return await interaction.followUp(`❌ | ${loc.get("c_lyrics2")} \`${title}\``);
|
return await interaction.followUp(`❌ | ${loc.get("c_lyrics2")} \`${title}\``);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||||
|
import { useQueue } from "discord-player";
|
||||||
import { ChatInputCommandInteraction, Client, EmbedBuilder } from "discord.js";
|
import { ChatInputCommandInteraction, Client, EmbedBuilder } from "discord.js";
|
||||||
import { getLocale, getLocalizations } from "../../utils/locales";
|
import { getLocale, getLocalizations } from "../../utils/locales";
|
||||||
import { getFilename } from "../../utils/misc";
|
import { getFilename } from "../../utils/misc";
|
||||||
|
@ -22,17 +23,17 @@ export default {
|
||||||
|
|
||||||
interaction: async (interaction: ChatInputCommandInteraction, client: Client) => {
|
interaction: async (interaction: ChatInputCommandInteraction, client: Client) => {
|
||||||
const loc = getLocale(client, interaction.locale);
|
const loc = getLocale(client, interaction.locale);
|
||||||
const queue = client.player.queues.get(interaction.guildId ?? "");
|
const queue = useQueue(interaction.guildId ?? "");
|
||||||
|
|
||||||
if (queue) {
|
if (queue) {
|
||||||
const embed = new EmbedBuilder();
|
const embed = new EmbedBuilder();
|
||||||
if (queue.paused) {
|
if (queue.node.isPaused()) {
|
||||||
queue.resume();
|
queue.node.resume();
|
||||||
|
|
||||||
embed.setDescription(loc.get("c_pause1"));
|
embed.setDescription(loc.get("c_pause1"));
|
||||||
return await interaction.reply({ embeds: [embed] });
|
return await interaction.reply({ embeds: [embed] });
|
||||||
} else {
|
} else {
|
||||||
queue.pause();
|
queue.node.pause();
|
||||||
|
|
||||||
embed.setDescription(loc.get("c_pause2"));
|
embed.setDescription(loc.get("c_pause2"));
|
||||||
return await interaction.reply({ embeds: [embed] });
|
return await interaction.reply({ embeds: [embed] });
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||||
import {
|
import {
|
||||||
|
AutocompleteInteraction,
|
||||||
ChatInputCommandInteraction,
|
ChatInputCommandInteraction,
|
||||||
Client,
|
Client,
|
||||||
EmbedBuilder,
|
EmbedBuilder,
|
||||||
|
@ -9,6 +10,7 @@ import {
|
||||||
import { Metadata } from "../../utils/metadata";
|
import { Metadata } from "../../utils/metadata";
|
||||||
import { getLocale, getLocalizations } from "../../utils/locales";
|
import { getLocale, getLocalizations } from "../../utils/locales";
|
||||||
import { getFilename } from "../../utils/misc";
|
import { getFilename } from "../../utils/misc";
|
||||||
|
import { Player, useMasterPlayer, useQueue } from "discord-player";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
scope: () => [],
|
scope: () => [],
|
||||||
|
@ -34,6 +36,7 @@ export default {
|
||||||
.setDescription(loc_default.get(`c_${filename}_opt1_desc`) ?? "")
|
.setDescription(loc_default.get(`c_${filename}_opt1_desc`) ?? "")
|
||||||
.setNameLocalizations(getLocalizations(client, `c_${filename}_opt1_name`, true))
|
.setNameLocalizations(getLocalizations(client, `c_${filename}_opt1_name`, true))
|
||||||
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_opt1_desc`))
|
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_opt1_desc`))
|
||||||
|
.setAutocomplete(true)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -68,17 +71,18 @@ export default {
|
||||||
loc_default?.get(`c_${filename}_opt1_name`) as string
|
loc_default?.get(`c_${filename}_opt1_name`) as string
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const player = useMasterPlayer() as Player;
|
||||||
if (!query) {
|
if (!query) {
|
||||||
// Now playing
|
// Now playing
|
||||||
|
|
||||||
const queue = client.player.queues.get(interaction.guildId ?? "");
|
const queue = useQueue(interaction.guildId ?? "");
|
||||||
|
|
||||||
if (queue) {
|
if (queue) {
|
||||||
const track = queue.nowPlaying();
|
const track = queue.history.currentTrack;
|
||||||
if (track) {
|
if (track) {
|
||||||
const embed = new EmbedBuilder()
|
const embed = new EmbedBuilder()
|
||||||
.setDescription(
|
.setDescription(
|
||||||
`${queue.createProgressBar()}\n\n${loc.get("c_play8")} ${track.requestedBy}`
|
`${queue.node.createProgressBar()}\n\n${loc.get("c_play8")} ${track.requestedBy}`
|
||||||
)
|
)
|
||||||
.setTitle(track.title + " • " + track.author)
|
.setTitle(track.title + " • " + track.author)
|
||||||
.setURL(track.url)
|
.setURL(track.url)
|
||||||
|
@ -93,7 +97,7 @@ export default {
|
||||||
return await interaction.reply({ embeds: [embed] });
|
return await interaction.reply({ embeds: [embed] });
|
||||||
}
|
}
|
||||||
|
|
||||||
const queue = client.player.createQueue(interaction.guild as GuildResolvable, {
|
const queue = player.nodes.create(interaction.guild as GuildResolvable, {
|
||||||
metadata: {
|
metadata: {
|
||||||
channel: interaction.channel,
|
channel: interaction.channel,
|
||||||
} as Metadata,
|
} as Metadata,
|
||||||
|
@ -103,7 +107,7 @@ export default {
|
||||||
try {
|
try {
|
||||||
if (!queue.connection) await queue.connect(member.voice.channel as VoiceBasedChannel);
|
if (!queue.connection) await queue.connect(member.voice.channel as VoiceBasedChannel);
|
||||||
} catch {
|
} catch {
|
||||||
queue.destroy();
|
queue.delete();
|
||||||
return await interaction.reply({
|
return await interaction.reply({
|
||||||
content: `❌ | ${loc.get("c_play3")}`,
|
content: `❌ | ${loc.get("c_play3")}`,
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
|
@ -111,35 +115,57 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
await interaction.deferReply();
|
await interaction.deferReply();
|
||||||
const result = await client.player
|
const result = await player
|
||||||
.search(query, {
|
.search(query, {
|
||||||
requestedBy: interaction.user,
|
requestedBy: interaction.user,
|
||||||
})
|
})
|
||||||
.then((x) => x);
|
.then((x) => x);
|
||||||
|
|
||||||
if (!result.tracks[0]) {
|
if (result.isEmpty()) {
|
||||||
const embed = new EmbedBuilder().setDescription(`❌ | \`${query}\` ${loc.get("c_play4")}.`);
|
const embed = new EmbedBuilder().setDescription(`❌ | \`${query}\` ${loc.get("c_play4")}.`);
|
||||||
return await interaction.followUp({ embeds: [embed] });
|
return await interaction.followUp({ embeds: [embed] });
|
||||||
}
|
}
|
||||||
|
|
||||||
let title;
|
let title;
|
||||||
if (result.playlist) {
|
if (result.playlist) {
|
||||||
queue.addTracks(result.playlist.tracks);
|
queue.addTrack(result.playlist.tracks);
|
||||||
title = result.playlist.title;
|
title = result.playlist.title;
|
||||||
} else {
|
} else {
|
||||||
// TODO: Ask user which result to choose
|
|
||||||
const track = result.tracks[0];
|
const track = result.tracks[0];
|
||||||
|
|
||||||
queue.addTrack(track);
|
queue.addTrack(track);
|
||||||
title = track.title;
|
title = track.title;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!queue.playing) {
|
if (!queue.node.isPlaying()) {
|
||||||
queue.play();
|
queue.node.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: When added to an existing queue (size of queue > 0):
|
||||||
|
// - Add position in queue
|
||||||
|
// - Add estimated time until playing
|
||||||
return await interaction.followUp({
|
return await interaction.followUp({
|
||||||
content: `⏱️ | \`${title}\` ${loc.get("c_play5")}.`,
|
content: `⏱️ | \`${title}\` ${loc.get("c_play5")}.`,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
autocomplete: async (interaction: AutocompleteInteraction) => {
|
||||||
|
const loc_default = interaction.client.locales.get(interaction.client.config.default_lang);
|
||||||
|
const filename = getFilename(__filename);
|
||||||
|
|
||||||
|
const player = useMasterPlayer() as Player;
|
||||||
|
const query = interaction.options.getString(
|
||||||
|
loc_default?.get(`c_${filename}_opt1_name`) as string,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
const results = await player.search(query);
|
||||||
|
|
||||||
|
// Returns a list of songs with their title
|
||||||
|
return interaction.respond(
|
||||||
|
results.tracks.slice(0, 10).map((t) => ({
|
||||||
|
name: t.title,
|
||||||
|
value: t.url,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||||
|
import { useQueue } from "discord-player";
|
||||||
import {
|
import {
|
||||||
ActionRowBuilder,
|
ActionRowBuilder,
|
||||||
ButtonBuilder,
|
ButtonBuilder,
|
||||||
|
@ -92,7 +93,7 @@ export default {
|
||||||
const filename = getFilename(__filename);
|
const filename = getFilename(__filename);
|
||||||
|
|
||||||
const loc = getLocale(client, interaction.locale);
|
const loc = getLocale(client, interaction.locale);
|
||||||
const queue = client.player.queues.get(interaction.guildId ?? "");
|
const queue = useQueue(interaction.guildId ?? "");
|
||||||
|
|
||||||
const embed = new EmbedBuilder();
|
const embed = new EmbedBuilder();
|
||||||
const rows = [];
|
const rows = [];
|
||||||
|
@ -136,7 +137,7 @@ export default {
|
||||||
|
|
||||||
// Shuffle Queue
|
// Shuffle Queue
|
||||||
case loc_default?.get(`c_${filename}_sub2_name`)?.toLowerCase() ?? "": {
|
case loc_default?.get(`c_${filename}_sub2_name`)?.toLowerCase() ?? "": {
|
||||||
queue.shuffle();
|
queue.tracks.shuffle();
|
||||||
|
|
||||||
embed.setDescription(loc.get("c_queue3"));
|
embed.setDescription(loc.get("c_queue3"));
|
||||||
break;
|
break;
|
||||||
|
@ -148,7 +149,7 @@ export default {
|
||||||
loc_default?.get(`c_${filename}_sub3_opt1_name`) as string
|
loc_default?.get(`c_${filename}_sub3_opt1_name`) as string
|
||||||
) as number;
|
) as number;
|
||||||
|
|
||||||
const track = queue.remove(id - 1);
|
const track = queue.removeTrack(id - 1);
|
||||||
|
|
||||||
if (track) {
|
if (track) {
|
||||||
embed.setDescription(
|
embed.setDescription(
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||||
import { QueueRepeatMode } from "discord-player";
|
import { QueueRepeatMode, useQueue } from "discord-player";
|
||||||
import { ChatInputCommandInteraction, Client } from "discord.js";
|
import { ChatInputCommandInteraction, Client } from "discord.js";
|
||||||
import { getLocale, getLocalizations } from "../../utils/locales";
|
import { getLocale, getLocalizations } from "../../utils/locales";
|
||||||
import { getFilename } from "../../utils/misc";
|
import { getFilename } from "../../utils/misc";
|
||||||
|
@ -64,7 +64,7 @@ export default {
|
||||||
const filename = getFilename(__filename);
|
const filename = getFilename(__filename);
|
||||||
|
|
||||||
const loc = getLocale(client, interaction.locale);
|
const loc = getLocale(client, interaction.locale);
|
||||||
const queue = client.player.queues.get(interaction.guildId ?? "");
|
const queue = useQueue(interaction.guildId ?? "");
|
||||||
|
|
||||||
if (queue) {
|
if (queue) {
|
||||||
const subcommand = interaction.options.getSubcommand();
|
const subcommand = interaction.options.getSubcommand();
|
||||||
|
@ -91,7 +91,7 @@ export default {
|
||||||
case loc_default?.get(`c_${filename}_sub2_name`)?.toLowerCase() ?? "": {
|
case loc_default?.get(`c_${filename}_sub2_name`)?.toLowerCase() ?? "": {
|
||||||
queue.setRepeatMode(QueueRepeatMode.TRACK);
|
queue.setRepeatMode(QueueRepeatMode.TRACK);
|
||||||
return interaction.reply(
|
return interaction.reply(
|
||||||
`${loc.get("c_repeat5")} ${queue.nowPlaying()?.title} ${loc.get("c_repeat6")}.`
|
`${loc.get("c_repeat5")} ${queue.history.currentTrack?.title} ${loc.get("c_repeat6")}.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||||
|
import { useQueue } from "discord-player";
|
||||||
import { ChatInputCommandInteraction, Client } from "discord.js";
|
import { ChatInputCommandInteraction, Client } from "discord.js";
|
||||||
import { getLocale, getLocalizations } from "../../utils/locales";
|
import { getLocale, getLocalizations } from "../../utils/locales";
|
||||||
import { getFilename } from "../../utils/misc";
|
import { getFilename } from "../../utils/misc";
|
||||||
|
@ -36,17 +37,17 @@ export default {
|
||||||
const filename = getFilename(__filename);
|
const filename = getFilename(__filename);
|
||||||
|
|
||||||
const loc = getLocale(client, interaction.locale);
|
const loc = getLocale(client, interaction.locale);
|
||||||
const queue = client.player.queues.get(interaction.guildId ?? "");
|
const queue = useQueue(interaction.guildId ?? "");
|
||||||
|
|
||||||
const id = interaction.options.getNumber(loc_default?.get(`c_${filename}_opt1_name`) as string);
|
const id = interaction.options.getNumber(loc_default?.get(`c_${filename}_opt1_name`) as string);
|
||||||
|
|
||||||
if (queue) {
|
if (queue) {
|
||||||
let msg;
|
let msg;
|
||||||
if (id) {
|
if (id) {
|
||||||
queue.skipTo(id - 1);
|
queue.node.skipTo(id - 1);
|
||||||
msg = loc.get("c_skip3") + " #" + id + "...";
|
msg = loc.get("c_skip3") + " #" + id + "...";
|
||||||
} else {
|
} else {
|
||||||
queue.skip();
|
queue.node.skip();
|
||||||
msg = loc.get("c_skip1") + "...";
|
msg = loc.get("c_skip1") + "...";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { ChatInputCommandInteraction, Client, GuildResolvable } from "discord.js
|
||||||
import { Metadata } from "../../utils/metadata";
|
import { Metadata } from "../../utils/metadata";
|
||||||
import { getLocale, getLocalizations } from "../../utils/locales";
|
import { getLocale, getLocalizations } from "../../utils/locales";
|
||||||
import { getFilename } from "../../utils/misc";
|
import { getFilename } from "../../utils/misc";
|
||||||
|
import { Player, useMasterPlayer } from "discord-player";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
scope: () => [],
|
scope: () => [],
|
||||||
|
@ -24,17 +25,18 @@ export default {
|
||||||
interaction: async (interaction: ChatInputCommandInteraction, client: Client) => {
|
interaction: async (interaction: ChatInputCommandInteraction, client: Client) => {
|
||||||
const loc = getLocale(client, interaction.locale);
|
const loc = getLocale(client, interaction.locale);
|
||||||
|
|
||||||
const queue = client.player.createQueue(interaction.guild as GuildResolvable, {
|
const player = useMasterPlayer() as Player;
|
||||||
|
const queue = player.nodes.create(interaction.guild as GuildResolvable, {
|
||||||
metadata: {
|
metadata: {
|
||||||
channel: interaction.channel,
|
channel: interaction.channel,
|
||||||
} as Metadata,
|
} as Metadata,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!(queue.connection || queue.playing)) {
|
if (!(queue.connection || queue.node.isPlaying())) {
|
||||||
return interaction.reply(`❌ | ${loc.get("c_stop1")}`);
|
return interaction.reply(`❌ | ${loc.get("c_stop1")}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
queue.destroy();
|
queue.delete();
|
||||||
|
|
||||||
interaction.reply(loc.get("c_stop2"));
|
interaction.reply(loc.get("c_stop2"));
|
||||||
},
|
},
|
||||||
|
|
|
@ -29,6 +29,19 @@ export default (interaction: Interaction, client: Client) => {
|
||||||
return modal.interaction(interaction, client);
|
return modal.interaction(interaction, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case InteractionType.ApplicationCommandAutocomplete: {
|
||||||
|
const command = client.commands.list.get(interaction.commandName);
|
||||||
|
if (!command) {
|
||||||
|
return console.error(loc.get("e_interacreate_no_command"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.autocomplete) {
|
||||||
|
return command.autocomplete(interaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
return console.error(loc.get("e_interacreate_no_autocomplete"));
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { PlayerEvents } from "discord-player";
|
import { Player, PlayerEvents, useMasterPlayer } from "discord-player";
|
||||||
import { Client } from "discord.js";
|
import { Client } from "discord.js";
|
||||||
import { readdir } from "fs/promises";
|
import { readdir } from "fs/promises";
|
||||||
|
|
||||||
|
@ -29,14 +29,15 @@ export default async (client: Client) => {
|
||||||
const event_type = event_type_ext.join(".");
|
const event_type = event_type_ext.join(".");
|
||||||
|
|
||||||
if (event_category == "player") {
|
if (event_category == "player") {
|
||||||
|
const player = useMasterPlayer() as Player;
|
||||||
if (once) {
|
if (once) {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
return client.player.once(event_type as keyof PlayerEvents, (...args: any[]) => {
|
return player.events.once(event_type as keyof PlayerEvents, (...args: any[]) => {
|
||||||
execute(...args, client);
|
execute(...args, client);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
return client.player.on(event_type as keyof PlayerEvents, (...args: any[]) => {
|
return player.events.on(event_type as keyof PlayerEvents, (...args: any[]) => {
|
||||||
execute(...args, client);
|
execute(...args, client);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Queue } from "discord-player";
|
import { GuildQueue } from "discord-player";
|
||||||
import { Metadata } from "../../utils/metadata";
|
import { Metadata } from "../../utils/metadata";
|
||||||
|
|
||||||
/** https://discord-player.js.org/docs/main/master/typedef/PlayerEvents */
|
/** https://discord-player.js.org/docs/main/master/typedef/PlayerEvents */
|
||||||
export default (_: Queue<Metadata>, error: Error) => {
|
export default (_: GuildQueue<Metadata>, error: Error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Queue } from "discord-player";
|
import { GuildQueue } from "discord-player";
|
||||||
import { Metadata } from "../../utils/metadata";
|
import { Metadata } from "../../utils/metadata";
|
||||||
|
|
||||||
/** https://discord-player.js.org/docs/main/master/typedef/PlayerEvents */
|
/** https://discord-player.js.org/docs/main/master/typedef/PlayerEvents */
|
||||||
export default (_: Queue<Metadata>, error: Error) => {
|
export default (_: GuildQueue<Metadata>, error: Error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
};
|
};
|
|
@ -1,11 +1,11 @@
|
||||||
import { EmbedBuilder } from "@discordjs/builders";
|
import { EmbedBuilder } from "@discordjs/builders";
|
||||||
import { Queue, Track } from "discord-player";
|
import { GuildQueue, Track } from "discord-player";
|
||||||
import { Client } from "discord.js";
|
import { Client } from "discord.js";
|
||||||
import { Metadata } from "../../utils/metadata";
|
import { Metadata } from "../../utils/metadata";
|
||||||
import { emojiPng } from "../../utils/misc";
|
import { emojiPng } from "../../utils/misc";
|
||||||
|
|
||||||
/** https://discord-player.js.org/docs/main/master/typedef/PlayerEvents */
|
/** https://discord-player.js.org/docs/types/discord-player/GuildQueueEvents */
|
||||||
export default (queue: Queue<Metadata>, track: Track, client: Client) => {
|
export default (queue: GuildQueue<Metadata>, track: Track, client: Client) => {
|
||||||
const loc_default = client.locales.get(client.config.default_lang);
|
const loc_default = client.locales.get(client.config.default_lang);
|
||||||
|
|
||||||
const embed = new EmbedBuilder()
|
const embed = new EmbedBuilder()
|
|
@ -21,7 +21,7 @@ const run = async () => {
|
||||||
const client_name = "Client";
|
const client_name = "Client";
|
||||||
await loadClient()
|
await loadClient()
|
||||||
.then(async (client) => {
|
.then(async (client) => {
|
||||||
// Events Discord.JS
|
// Events Discord.JS and Player
|
||||||
const events_name = "Events";
|
const events_name = "Events";
|
||||||
await loadEvents(client)
|
await loadEvents(client)
|
||||||
.then(() => console.log(logStart(events_name, true)))
|
.then(() => console.log(logStart(events_name, true)))
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
"e_interacreate_no_command": "Désolé, la commande n'existe plus...",
|
"e_interacreate_no_command": "Désolé, la commande n'existe plus...",
|
||||||
"e_interacreate_no_modal": "Désolé, le modèle n'existe plus...",
|
"e_interacreate_no_modal": "Désolé, le modèle n'existe plus...",
|
||||||
"e_interacreate_no_button": "Désolé, le bouton n'existe plus...",
|
"e_interacreate_no_button": "Désolé, le bouton n'existe plus...",
|
||||||
|
"e_interacreate_no_autocomplete": "Désolé, pas d'autocomplétion existe pour cette commande...",
|
||||||
|
|
||||||
"c_ping_name": "Ping",
|
"c_ping_name": "Ping",
|
||||||
"c_ping_desc": "Pong!",
|
"c_ping_desc": "Pong!",
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { Collection } from "discord.js";
|
import { Collection } from "discord.js";
|
||||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||||
import { Database } from "sqlite3";
|
import { Database } from "sqlite3";
|
||||||
import { Player } from "discord-player";
|
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
|
||||||
|
@ -80,11 +79,11 @@ declare module "discord.js" {
|
||||||
data: SlashCommandBuilder;
|
data: SlashCommandBuilder;
|
||||||
/** How the command interact */
|
/** How the command interact */
|
||||||
interaction: (interaction: CommandInteraction, client: Client) => unknown;
|
interaction: (interaction: CommandInteraction, client: Client) => unknown;
|
||||||
|
/** Autocomplete logic */
|
||||||
|
autocomplete: undefined | ((interaction: AutocompleteInteraction) => unknown);
|
||||||
}
|
}
|
||||||
>;
|
>;
|
||||||
};
|
};
|
||||||
/** Music player */
|
|
||||||
player: Player;
|
|
||||||
/** Store all the localizations */
|
/** Store all the localizations */
|
||||||
locales: Map<string, Map<string, string>>;
|
locales: Map<string, Map<string, string>>;
|
||||||
db: Database;
|
db: Database;
|
||||||
|
|
|
@ -38,13 +38,14 @@ export default async () => {
|
||||||
list: new Collection(),
|
list: new Collection(),
|
||||||
};
|
};
|
||||||
|
|
||||||
client.player = new Player(client, {
|
const player = Player.singleton(client, {
|
||||||
ytdlOptions: {
|
ytdlOptions: {
|
||||||
filter: "audioonly",
|
filter: "audioonly",
|
||||||
|
quality: "highestaudio",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
client.player.lyrics = lyricsExtractor();
|
player.lyrics = lyricsExtractor();
|
||||||
|
|
||||||
console.log("Translations progression :");
|
console.log("Translations progression :");
|
||||||
client.locales = await loadLocales(client.config.default_lang);
|
client.locales = await loadLocales(client.config.default_lang);
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
import { EmbedBuilder } from "@discordjs/builders";
|
import { EmbedBuilder } from "@discordjs/builders";
|
||||||
import { Queue, QueueRepeatMode, Track } from "discord-player";
|
import { GuildQueue, QueueRepeatMode, Track } from "discord-player";
|
||||||
import { Client } from "discord.js";
|
import { Client } from "discord.js";
|
||||||
import { getLocale } from "./locales";
|
import { getLocale } from "./locales";
|
||||||
|
|
||||||
export const embedListQueue = (
|
export const embedListQueue = (
|
||||||
client: Client,
|
client: Client,
|
||||||
embed: EmbedBuilder,
|
embed: EmbedBuilder,
|
||||||
queue: Queue,
|
queue: GuildQueue,
|
||||||
page: number,
|
page: number,
|
||||||
local: string
|
local: string
|
||||||
) => {
|
) => {
|
||||||
const loc = getLocale(client, local);
|
const loc = getLocale(client, local);
|
||||||
const tracks = queue.tracks.slice();
|
const tracks = queue.tracks.toArray();
|
||||||
|
|
||||||
// Add the current song at the top of the list
|
// Add the current song at the top of the list
|
||||||
tracks.unshift(queue.current as Track);
|
tracks.unshift(queue.history.currentTrack as Track);
|
||||||
|
|
||||||
// Limit of discord is 25
|
// Limit of discord is 25
|
||||||
const limit_fields = 25;
|
const limit_fields = 25;
|
||||||
|
|
Loading…
Reference in a new issue