Réécriture complète en Typescript
This commit is contained in:
16
src/buttons/loop.ts
Executable file
16
src/buttons/loop.ts
Executable file
@@ -0,0 +1,16 @@
|
||||
import { ButtonInteraction } from 'discord.js'
|
||||
import { useQueue } from 'discord-player'
|
||||
|
||||
module.exports = {
|
||||
id: 'loop',
|
||||
async execute(interaction: ButtonInteraction) {
|
||||
let guild = interaction.guild
|
||||
if (!guild) return
|
||||
let queue = useQueue(guild.id)
|
||||
if (!queue) return
|
||||
|
||||
let loop = queue.repeatMode === 0 ? 1 : queue.repeatMode === 1 ? 2 : queue.repeatMode === 2 ? 3 : 0
|
||||
await queue.setRepeatMode(loop)
|
||||
await interaction.followUp({ content:`Boucle ${loop === 0 ? 'désactivée' : loop === 1 ? 'en mode Titre' : loop === 2 ? 'en mode File d\'Attente' : 'en autoplay'}.`, ephemeral: true })
|
||||
}
|
||||
}
|
||||
15
src/buttons/pause.ts
Executable file
15
src/buttons/pause.ts
Executable file
@@ -0,0 +1,15 @@
|
||||
import { ButtonInteraction } from 'discord.js'
|
||||
import { useQueue } from 'discord-player'
|
||||
|
||||
module.exports = {
|
||||
id: 'pause',
|
||||
async execute(interaction: ButtonInteraction) {
|
||||
let guild = interaction.guild
|
||||
if (!guild) return
|
||||
let queue = useQueue(guild.id)
|
||||
if (!queue) return
|
||||
|
||||
await queue.node.setPaused(!queue.node.isPaused())
|
||||
return interaction.followUp({ content: 'Musique mise en pause !', ephemeral: true })
|
||||
}
|
||||
}
|
||||
15
src/buttons/previous.ts
Executable file
15
src/buttons/previous.ts
Executable file
@@ -0,0 +1,15 @@
|
||||
import { ButtonInteraction } from 'discord.js'
|
||||
import { useHistory } from 'discord-player'
|
||||
|
||||
module.exports = {
|
||||
id: 'previous',
|
||||
async execute(interaction: ButtonInteraction) {
|
||||
let guild = interaction.guild
|
||||
if (!guild) return
|
||||
let history = useHistory(guild.id)
|
||||
if (!history) return
|
||||
|
||||
await history.previous()
|
||||
return interaction.followUp({ content: 'Musique précédente jouée !', ephemeral: true })
|
||||
}
|
||||
}
|
||||
15
src/buttons/resume.ts
Executable file
15
src/buttons/resume.ts
Executable file
@@ -0,0 +1,15 @@
|
||||
import { ButtonInteraction } from 'discord.js'
|
||||
import { useQueue } from 'discord-player'
|
||||
|
||||
module.exports = {
|
||||
id: 'resume',
|
||||
async execute(interaction: ButtonInteraction) {
|
||||
let guild = interaction.guild
|
||||
if (!guild) return
|
||||
let queue = useQueue(guild.id)
|
||||
if (!queue) return
|
||||
|
||||
await queue.node.setPaused(!queue.node.isPaused())
|
||||
return interaction.followUp({ content: 'Musique reprise !', ephemeral: true })
|
||||
}
|
||||
}
|
||||
15
src/buttons/shuffle.ts
Executable file
15
src/buttons/shuffle.ts
Executable file
@@ -0,0 +1,15 @@
|
||||
import { ButtonInteraction } from 'discord.js'
|
||||
import { useQueue } from 'discord-player'
|
||||
|
||||
module.exports = {
|
||||
id: 'shuffle',
|
||||
async execute(interaction: ButtonInteraction) {
|
||||
let guild = interaction.guild
|
||||
if (!guild) return
|
||||
let queue = useQueue(guild.id)
|
||||
if (!queue) return
|
||||
|
||||
await queue.tracks.shuffle()
|
||||
return interaction.followUp({ content: 'File d\'attente mélangée !', ephemeral: true })
|
||||
}
|
||||
}
|
||||
15
src/buttons/skip.ts
Executable file
15
src/buttons/skip.ts
Executable file
@@ -0,0 +1,15 @@
|
||||
import { ButtonInteraction } from 'discord.js'
|
||||
import { useQueue } from 'discord-player'
|
||||
|
||||
module.exports = {
|
||||
id: 'skip',
|
||||
async execute(interaction: ButtonInteraction) {
|
||||
let guild = interaction.guild
|
||||
if (!guild) return
|
||||
let queue = useQueue(guild.id)
|
||||
if (!queue) return
|
||||
|
||||
await queue.node.skip()
|
||||
return interaction.followUp({ content: 'Musique passée !', ephemeral: true })
|
||||
}
|
||||
}
|
||||
15
src/buttons/stop.ts
Executable file
15
src/buttons/stop.ts
Executable file
@@ -0,0 +1,15 @@
|
||||
import { ButtonInteraction } from 'discord.js'
|
||||
import { useQueue } from 'discord-player'
|
||||
|
||||
module.exports = {
|
||||
id: 'stop',
|
||||
async execute(interaction: ButtonInteraction) {
|
||||
let guild = interaction.guild
|
||||
if (!guild) return
|
||||
let queue = useQueue(guild.id)
|
||||
if (!queue) return
|
||||
|
||||
await queue.delete()
|
||||
return interaction.followUp({ content: 'Musique arrêtée !', ephemeral: true })
|
||||
}
|
||||
}
|
||||
16
src/buttons/volume_down.ts
Executable file
16
src/buttons/volume_down.ts
Executable file
@@ -0,0 +1,16 @@
|
||||
import { ButtonInteraction } from 'discord.js'
|
||||
import { useQueue } from 'discord-player'
|
||||
|
||||
module.exports = {
|
||||
id: 'volume_down',
|
||||
async execute(interaction: ButtonInteraction) {
|
||||
let guild = interaction.guild
|
||||
if (!guild) return
|
||||
let queue = useQueue(guild.id)
|
||||
if (!queue) return
|
||||
|
||||
let volume = queue.node.volume - 10
|
||||
await queue.node.setVolume(volume)
|
||||
return interaction.followUp({ content: `🔉 | Volume modifié à ${volume}% !`, ephemeral: true })
|
||||
}
|
||||
}
|
||||
16
src/buttons/volume_up.ts
Executable file
16
src/buttons/volume_up.ts
Executable file
@@ -0,0 +1,16 @@
|
||||
import { ButtonInteraction } from 'discord.js'
|
||||
import { useQueue } from 'discord-player'
|
||||
|
||||
module.exports = {
|
||||
id: 'volume_up',
|
||||
async execute(interaction: ButtonInteraction) {
|
||||
let guild = interaction.guild
|
||||
if (!guild) return
|
||||
let queue = useQueue(guild.id)
|
||||
if (!queue) return
|
||||
|
||||
let volume = queue.node.volume + 10
|
||||
await queue.node.setVolume(volume)
|
||||
return interaction.followUp({ content: `🔊 | Volume modifié à ${volume}% !`, ephemeral: true })
|
||||
}
|
||||
}
|
||||
198
src/commands/global/amp.ts
Executable file
198
src/commands/global/amp.ts
Executable file
@@ -0,0 +1,198 @@
|
||||
import { SlashCommandBuilder, ChatInputCommandInteraction, AutocompleteInteraction, EmbedBuilder, inlineCode } from 'discord.js'
|
||||
import * as AMP from '../../utils/amp'
|
||||
import 'dotenv/config'
|
||||
|
||||
interface ListInstancesResult {
|
||||
status: string
|
||||
data: {
|
||||
result: [
|
||||
Host: {
|
||||
AvailableInstances: any[]
|
||||
FriendlyName: string
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
interface InstanceFields {
|
||||
name: string
|
||||
value: string
|
||||
inline: boolean
|
||||
}
|
||||
|
||||
interface failData {
|
||||
Title: string
|
||||
Message: string
|
||||
}
|
||||
interface errorData {
|
||||
error_code: string
|
||||
}
|
||||
|
||||
function failMsg(data: any) { return `La commande a échouée !\n${inlineCode(`${data.Title}: ${data.Message}`)}` }
|
||||
function errorMsg(data: any) { return `Y'a eu une erreur !\n${inlineCode(`${data.error_code}`)}` }
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder().setName('amp').setDescription('Accède à mon panel de jeu AMP !')
|
||||
.addSubcommand(subcommand => subcommand.setName('login').setDescription("Connectez-vous avant d'effectuer une autre commande !")
|
||||
.addStringOption(option => option.setName('username').setDescription("Nom d'Utilisateur").setRequired(true))
|
||||
.addStringOption(option => option.setName('password').setDescription('Mot de Passe').setRequired(true))
|
||||
.addBooleanOption(option => option.setName('remember').setDescription('Mémoriser les identifiants').setRequired(true))
|
||||
.addStringOption(option => option.setName('otp').setDescription('Code de double authentification')))
|
||||
|
||||
.addSubcommandGroup(subcommandgroup => subcommandgroup.setName('instances').setDescription('Intéragir avec les instances AMP.')
|
||||
.addSubcommand(subcommand => subcommand.setName('list').setDescription('Liste toutes les instances disponibles.'))
|
||||
|
||||
.addSubcommand(subcommand => subcommand.setName('manage').setDescription('Gérer une instance.')
|
||||
.addStringOption(option => option.setName('instance').setDescription("Nom de l'instance").setRequired(true).setAutocomplete(true)))
|
||||
|
||||
/*.addSubcommand(subcommand => subcommand.setName('restart').setDescription('Redémarre une instance.')
|
||||
.addStringOption(option => option.setName('name').setDescription("Nom de l'instance").setRequired(true)))*/),
|
||||
|
||||
async autocompleteRun(interaction: AutocompleteInteraction) {
|
||||
let query = interaction.options.getString('instance', true)
|
||||
|
||||
// Check if the SessionID is still valid
|
||||
//let sessionID = dotenv.config().parsed.AMP_SESSIONID
|
||||
let sessionID = process.env.AMP_SESSIONID as string
|
||||
let session = await AMP.CheckSession(sessionID)
|
||||
if (session.status === 'fail') {
|
||||
if (process.env.AMP_REMEMBER_TOKEN) {
|
||||
// Refresh the SessionID if the RememberMeToken is available
|
||||
let details = {
|
||||
username: process.env.AMP_USERNAME,
|
||||
password: '',
|
||||
token: process.env.AMP_REMEMBER_TOKEN,
|
||||
rememberMe: true
|
||||
}
|
||||
let result = await AMP.Core.Login(details)
|
||||
console.log(result)
|
||||
if (result.status === 'success') sessionID = result.data.sessionID
|
||||
else if (result.status === 'fail') return interaction.respond([])
|
||||
else if (result.status === 'error') return interaction.respond([])
|
||||
}
|
||||
else {
|
||||
// If no RememberMeToken is available, ask to login
|
||||
//return await interaction.followUp(`Tu dois te connecter avant d'effectuer une autre commande !`)
|
||||
return await interaction.respond([])
|
||||
}
|
||||
}
|
||||
else if (session.status === 'error') return interaction.respond([])
|
||||
|
||||
let choices: any = []
|
||||
let result = await AMP.ADSModule.GetInstances(sessionID)
|
||||
if (result.status === 'success') {
|
||||
let hosts = result.data.result as any[]
|
||||
hosts.forEach(host => {
|
||||
let instances = host.AvailableInstances as any[]
|
||||
instances.forEach(instance => {
|
||||
if (instance.FriendlyName.includes(query)) choices.push({ name: `${host.FriendlyName} - ${instance.FriendlyName}`, value: instance.InstanceID })
|
||||
})
|
||||
})
|
||||
}
|
||||
else if (result.status === 'fail') return interaction.respond([])
|
||||
else if (result.status === 'error') return interaction.respond([])
|
||||
|
||||
return interaction.respond(choices)
|
||||
},
|
||||
async execute(interaction: ChatInputCommandInteraction) {
|
||||
// Let the user login
|
||||
if (interaction.options.getSubcommand() == 'login') {
|
||||
// Get a SessionID and a RememberMeToken if wanted
|
||||
await interaction.deferReply({ ephemeral: true })
|
||||
|
||||
let details = {
|
||||
username: interaction.options.getString('username'),
|
||||
password: interaction.options.getString('password'),
|
||||
token: interaction.options.getString('otp') || '',
|
||||
rememberMe: interaction.options.getBoolean('remember')
|
||||
}
|
||||
|
||||
let result = await AMP.Core.Login(details)
|
||||
if (result.status === 'success') return await interaction.followUp(`Tu es connecté au panel sous **${result.data.userInfo.Username}** !`)
|
||||
else if (result.status === 'fail') return await interaction.followUp(failMsg(result.data))
|
||||
else if (result.status === 'error') return await interaction.followUp(errorMsg(result.data))
|
||||
}
|
||||
await interaction.deferReply()
|
||||
|
||||
// Check if the SessionID is still valid
|
||||
//let sessionID = dotenv.config().parsed.AMP_SESSIONID
|
||||
let sessionID = process.env.AMP_SESSIONID as string
|
||||
let session = await AMP.CheckSession(sessionID)
|
||||
|
||||
if (session.status === 'fail') {
|
||||
console.log(session)
|
||||
if (process.env.AMP_REMEMBER_TOKEN) {
|
||||
// Refresh the SessionID if the RememberMeToken is available
|
||||
let details = {
|
||||
username: process.env.AMP_USERNAME,
|
||||
password: '',
|
||||
token: process.env.AMP_REMEMBER_TOKEN,
|
||||
rememberMe: true
|
||||
}
|
||||
let result = await AMP.Core.Login(details)
|
||||
console.log(result)
|
||||
if (result.status === 'success') sessionID = result.data.sessionID
|
||||
else if (result.status === 'fail') return await interaction.followUp(failMsg(result.data))
|
||||
else if (result.status === 'error') return await interaction.followUp(errorMsg(result.data))
|
||||
}
|
||||
else {
|
||||
// If no RememberMeToken is available, ask to login
|
||||
return await interaction.followUp(`Tu dois te connecter avant d'effectuer une autre commande !`)
|
||||
}
|
||||
}
|
||||
else if (session.status === 'error') return await interaction.followUp(errorMsg(session.data))
|
||||
|
||||
if (interaction.options.getSubcommandGroup() == 'instances') {
|
||||
if (interaction.options.getSubcommand() == 'list') {
|
||||
let result = await AMP.ADSModule.GetInstances(sessionID) as ListInstancesResult
|
||||
|
||||
if (result.status === 'success') {
|
||||
await interaction.followUp({ content: `${result.data.result.length} hôtes trouvés !` })
|
||||
result.data.result.forEach(async host => {
|
||||
let fields = [] as InstanceFields[]
|
||||
host.AvailableInstances.forEach(instance => {
|
||||
fields.push({
|
||||
name: instance.FriendlyName,
|
||||
value: `**Running:** ${instance.Running}\n**Port:** ${instance.Port}\n**Module:** ${instance.Module}`,
|
||||
inline: true
|
||||
})
|
||||
})
|
||||
let embed = new EmbedBuilder()
|
||||
.setTitle(host.FriendlyName)
|
||||
.setDescription(`Liste des ${host.AvailableInstances.length} instances :`)
|
||||
.setColor(interaction.guild?.members.me?.displayColor || '#ffc370')
|
||||
.setTimestamp()
|
||||
.setFields(fields)
|
||||
return await interaction.channel?.send({ embeds: [embed] })
|
||||
})
|
||||
}
|
||||
else if (result.status === 'fail') return await interaction.followUp(failMsg(result.data))
|
||||
else if (result.status === 'error') return await interaction.followUp(errorMsg(result.data))
|
||||
}
|
||||
else if (interaction.options.getSubcommand() == 'manage') {
|
||||
let instanceID = interaction.options.getString('instance', true)
|
||||
let result = await AMP.ADSModule.ManageInstance(sessionID, instanceID)
|
||||
|
||||
if (result.status === 'success') {
|
||||
let server = await AMP.ADSModule.Servers(sessionID, instanceID)
|
||||
console.log(server)
|
||||
|
||||
if (server.status === 'success') return await interaction.followUp(`Ok !`)
|
||||
else if (server.status === 'fail') return await interaction.followUp(failMsg(server.data))
|
||||
else if (server.status === 'error') return await interaction.followUp(errorMsg(server.data))
|
||||
}
|
||||
else if (result.status === 'fail') return await interaction.followUp(failMsg(result.data))
|
||||
else if (result.status === 'error') return await interaction.followUp(errorMsg(result.data))
|
||||
}
|
||||
else if (interaction.options.getSubcommand() == 'restart') {
|
||||
let query = interaction.options.getString('name')
|
||||
if (!query) return
|
||||
|
||||
let result = await AMP.ADSModule.RestartInstance(sessionID, query)
|
||||
|
||||
if (result.status === 'success') return await interaction.followUp(`Ok !`)
|
||||
else if (result.status === 'fail') return await interaction.followUp(failMsg(result.data))
|
||||
else if (result.status === 'error') return await interaction.followUp(errorMsg(result.data))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
58
src/commands/global/crack.ts
Executable file
58
src/commands/global/crack.ts
Executable file
@@ -0,0 +1,58 @@
|
||||
import { SlashCommandBuilder, EmbedBuilder, ChatInputCommandInteraction, MessageReaction, User }from 'discord.js'
|
||||
import * as crack from '../../utils/crack'
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder().setName('crack').setDescription('Télécharge un crack sur le site online-fix.me !')
|
||||
.addStringOption(option => option.setName('jeu').setDescription('Quel jeu tu veux DL ?').setRequired(true)),
|
||||
async execute(interaction: ChatInputCommandInteraction) {
|
||||
await interaction.deferReply()
|
||||
|
||||
let query = interaction.options.getString('jeu')
|
||||
if (!query) return
|
||||
|
||||
let games = await crack.search(query) as crack.Game[]
|
||||
if (!Array.isArray(games)) {
|
||||
//if (games.toString() == "TypeError: Cannot read properties of undefined (reading 'split')") return interaction.followUp({ content: `J'ai rien trouvé pour "${query}" !` })
|
||||
//else return interaction.followUp({ content: "Une erreur s'est produite ! ```" + games + "```" })
|
||||
return interaction.followUp({ content: `J'ai rien trouvé pour "${query}" !` })
|
||||
}
|
||||
|
||||
let game = {} as crack.Game
|
||||
if (games.length > 1) {
|
||||
games = games.slice(0, 9)
|
||||
let list = ''
|
||||
for (let i = 0; i < games.length; i++) list += `\n${i + 1}. ${games[i].name} (${games[i].link})`
|
||||
let message = await interaction.followUp({ content: `J'ai trouvé plusieurs jeux pour "${query}" ! ${list}` })
|
||||
|
||||
let emojis = ['1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣']
|
||||
for (let i = 0; i < games.length; i++) await message.react(emojis[i])
|
||||
|
||||
// Wait for a reaction to be added by the interaction author.
|
||||
const filter: any = (reaction: MessageReaction, user: User) => { if (reaction.emoji.name) return emojis.includes(reaction.emoji.name) && user.id === interaction.user.id }
|
||||
await message.awaitReactions({ filter, max: 1, time: 5000, errors: ['time'] }).then(collected => {
|
||||
console.log(collected)
|
||||
if (!collected.first) return
|
||||
let reaction = collected.first()
|
||||
let index = emojis.indexOf(reaction?.emoji.name ?? '')
|
||||
game = games[index]
|
||||
}).catch(() => { return interaction.followUp({ content: 'T\'as mis trop de temps à choisir !' }) })
|
||||
}
|
||||
else game = games[0]
|
||||
|
||||
let url = await crack.repo(game)
|
||||
if (!url) return
|
||||
let file = await crack.torrent(url)
|
||||
if (!file) return
|
||||
let filePath = await crack.download(url, file)
|
||||
if (!filePath) return
|
||||
let link = await crack.magnet(filePath)
|
||||
|
||||
let embed = new EmbedBuilder()
|
||||
.setColor('#ffc370')
|
||||
.setTitle(game.name)
|
||||
.setURL(game.link)
|
||||
.setDescription(`Voici ce que j'ai trouvé pour "${query}".\nTu peux aussi cliquer sur [ce lien](https://angels-dev.fr/magnet/${link}) pour pouvoir télécharger le jeu direct !`)
|
||||
|
||||
await interaction.followUp({ embeds: [embed], files: [filePath] })
|
||||
}
|
||||
}
|
||||
34
src/commands/global/papa.ts
Executable file
34
src/commands/global/papa.ts
Executable file
@@ -0,0 +1,34 @@
|
||||
import { SlashCommandBuilder, ChatInputCommandInteraction, GuildMember } from 'discord.js'
|
||||
import { getVoiceConnection, joinVoiceChannel } from '@discordjs/voice'
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('papa')
|
||||
.setDescription('Si papa m\'appelle, je le rejoins !'),
|
||||
async execute(interaction: ChatInputCommandInteraction) {
|
||||
if (interaction.user.id !== '223831938346123275') return interaction.reply({ content: 'T\'es pas mon père, dégage !' })
|
||||
|
||||
let guild = interaction.guild
|
||||
if (!guild) return interaction.reply({ content: 'Je ne peux pas rejoindre ton vocal en message privé, papa !' })
|
||||
|
||||
let member = interaction.member as GuildMember
|
||||
|
||||
let botChannel = guild.members.me?.voice.channel
|
||||
let papaChannel = member.voice.channel
|
||||
|
||||
if (!papaChannel && botChannel) {
|
||||
const voiceConnection = getVoiceConnection(guild.id);
|
||||
if (voiceConnection) voiceConnection.destroy()
|
||||
return interaction.reply({ content: 'Je quitte le vocal, papa !' })
|
||||
}
|
||||
else if (papaChannel && (!botChannel || botChannel.id !== papaChannel.id)) {
|
||||
joinVoiceChannel({
|
||||
channelId: papaChannel.id,
|
||||
guildId: papaChannel.guild.id,
|
||||
adapterCreator: papaChannel.guild.voiceAdapterCreator,
|
||||
})
|
||||
return interaction.reply({ content: 'Je rejoins ton vocal, papa !' })
|
||||
}
|
||||
else return interaction.reply({ content: 'Je suis déjà dans ton vocal, papa !' })
|
||||
}
|
||||
}
|
||||
79
src/commands/global/parle.ts
Executable file
79
src/commands/global/parle.ts
Executable file
@@ -0,0 +1,79 @@
|
||||
import { SlashCommandBuilder, ChatInputCommandInteraction, GuildMember } from 'discord.js'
|
||||
import { joinVoiceChannel, createAudioPlayer, createAudioResource, AudioPlayerStatus, EndBehaviorType } from '@discordjs/voice'
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('parle')
|
||||
.setDescription('Fais moi parler par dessus quelqu\'un de chiant dans le vocal')
|
||||
.addUserOption(option => option.setName('user').setDescription('La personne en question').setRequired(true)),
|
||||
async execute(interaction: ChatInputCommandInteraction) {
|
||||
if (interaction.user.id !== '223831938346123275') return await interaction.reply({ content: 'Tu n\'as pas le droit d\'utiliser cette commande !', ephemeral: true })
|
||||
|
||||
let user = interaction.options.getUser('user')
|
||||
if (!user) return
|
||||
let guild = interaction.guild
|
||||
if (!guild) return
|
||||
let member = guild.members.cache.get(user.id) as GuildMember
|
||||
if (!member) return
|
||||
let caller = interaction.member as GuildMember
|
||||
if (!caller) return
|
||||
|
||||
if (!caller.voice.channel) return await interaction.reply({ content: 'You must be in a voice channel to use this command.', ephemeral: true })
|
||||
if (!member.voice.channel) return await interaction.reply({ content: 'The member must be in a voice channel to use this command.', ephemeral: true })
|
||||
if (caller.voice.channelId !== member.voice.channelId) return await interaction.reply({ content: 'You must be in the same voice channel than the member to use this command.', ephemeral: true })
|
||||
|
||||
await interaction.reply({ content: 'Je vais parler par dessus cette personne !', ephemeral: true })
|
||||
|
||||
/*
|
||||
// Searches for audio files uploaded in the channel
|
||||
let messages = await interaction.channel.messages.fetch({ limit: 10, cache: false })
|
||||
messages = messages.filter(m => m.attachments.size > 0)
|
||||
|
||||
let files = []
|
||||
await messages.forEach(m => m.attachments.forEach(a => {
|
||||
if (a.contentType === 'audio/mpeg') files.push(a)
|
||||
}))
|
||||
if (files.size === 0) return await interaction.editReply({ content: 'Aucun fichier audio trouvé dans ce channel.', ephemeral: true })
|
||||
|
||||
// Limit the number of files to the last 10
|
||||
//files = files.sort((a, b) => b.createdTimestamp - a.createdTimestamp).first(10)
|
||||
|
||||
// Ask the user to choose a file
|
||||
let file = await interaction.channel.send({ content: 'Choisissez un fichier audio :', files: files })
|
||||
let filter = m => m.author.id === interaction.user.id && !isNaN(m.content) && parseInt(m.content) > 0 && parseInt(m.content) <= files.size
|
||||
let response = await interaction.channel.awaitMessages({ filter, max: 1, time: 30000, errors: ['time'] })
|
||||
file = files.get(files.keyArray()[response.first().content - 1])
|
||||
*/
|
||||
|
||||
let playing = false
|
||||
let player = createAudioPlayer()
|
||||
player.on(AudioPlayerStatus.Idle, () => { playing = false })
|
||||
|
||||
let connection = joinVoiceChannel({
|
||||
channelId: caller.voice.channelId as string,
|
||||
guildId: interaction.guildId as string,
|
||||
adapterCreator: guild.voiceAdapterCreator,
|
||||
selfDeaf: false
|
||||
})
|
||||
connection.subscribe(player)
|
||||
|
||||
let stream = connection.receiver.subscribe(user.id, { end: { behavior: EndBehaviorType.Manual } })
|
||||
stream.on('data', (chunk) => {
|
||||
if (!user) return
|
||||
if (connection.receiver.speaking.users.has(user.id) && !playing) {
|
||||
playing = true
|
||||
let resource = createAudioResource('../../static/parle.mp3', { inlineVolume: true })
|
||||
//let resource = createAudioResource(file.attachments.first().url, { inlineVolume: true })
|
||||
if (resource.volume) resource.volume.setVolume(0.2)
|
||||
player.play(resource)
|
||||
}
|
||||
})
|
||||
|
||||
interaction.client.on('voiceStateUpdate', (oldState, newState) => {
|
||||
if (oldState.id === member.id && newState.channelId !== caller.voice.channelId) {
|
||||
stream.destroy()
|
||||
connection.disconnect()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
11
src/commands/global/ping.ts
Executable file
11
src/commands/global/ping.ts
Executable file
@@ -0,0 +1,11 @@
|
||||
import { SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js'
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('ping')
|
||||
.setDescription('Check the latency of the bot'),
|
||||
async execute(interaction: ChatInputCommandInteraction) {
|
||||
let sent = await interaction.reply({ content: 'Pinging...', fetchReply: true })
|
||||
interaction.editReply(`Websocket heartbeat: ${interaction.client.ws.ping}ms.\nRoundtrip latency: ${sent.createdTimestamp - interaction.createdTimestamp}ms`)
|
||||
}
|
||||
}
|
||||
29
src/commands/global/spam.ts
Executable file
29
src/commands/global/spam.ts
Executable file
@@ -0,0 +1,29 @@
|
||||
import { SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js'
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('spam')
|
||||
.setDescription('Spam')
|
||||
.addUserOption(option => option.setName('user').setDescription('Spam').setRequired(true))
|
||||
.addStringOption(option => option.setName('string').setDescription('Spam').setRequired(true))
|
||||
.addIntegerOption(option => option.setName('integer').setDescription('Spam').setRequired(true)),
|
||||
async execute(interaction: ChatInputCommandInteraction) {
|
||||
let user = interaction.options.getUser('user')
|
||||
let string = interaction.options.getString('string')
|
||||
let integer = interaction.options.getInteger('integer')
|
||||
|
||||
await interaction.reply({ content: 'Spam', ephemeral: true })
|
||||
let i = 0
|
||||
function myLoop() {
|
||||
setTimeout(function () {
|
||||
if (!user) return
|
||||
if (!string) return
|
||||
if (!integer) return
|
||||
user.send(string).catch(error => console.error(error))
|
||||
i++
|
||||
if (i < integer) myLoop()
|
||||
}, 1000)
|
||||
}
|
||||
myLoop()
|
||||
}
|
||||
}
|
||||
19
src/commands/global/update.ts
Executable file
19
src/commands/global/update.ts
Executable file
@@ -0,0 +1,19 @@
|
||||
import { SlashCommandBuilder, ChatInputCommandInteraction, Guild } from 'discord.js'
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('update')
|
||||
.setDescription('Update the member count channel.'),
|
||||
async execute(interaction: ChatInputCommandInteraction) {
|
||||
let guild = interaction.guild as Guild
|
||||
|
||||
guild.members.fetch().then(() => {
|
||||
var i = 0
|
||||
guild.members.cache.forEach(async member => { if (!member.user.bot) i++ })
|
||||
let channel = guild.channels.cache.get('1091140609139560508')
|
||||
if (!channel) return
|
||||
channel.setName(`${i} Gens Posés`)
|
||||
interaction.reply(`${i} Gens Posés !`)
|
||||
}).catch(console.error)
|
||||
}
|
||||
}
|
||||
21
src/commands/player/loop.ts
Executable file
21
src/commands/player/loop.ts
Executable file
@@ -0,0 +1,21 @@
|
||||
import { ChatInputCommandInteraction, SlashCommandBuilder } from 'discord.js'
|
||||
import { useQueue } from'discord-player'
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('loop')
|
||||
.setDescription('Boucler la musique en cours de lecture.')
|
||||
.addIntegerOption(option => option.setName('loop')
|
||||
.setDescription('Mode de boucle (0 = Off, 1 = Titre, 2 = File d\'Attente; 3 = Autoplay)')
|
||||
.setRequired(true)
|
||||
.setMinValue(0)
|
||||
.setMaxValue(3)),
|
||||
async execute(interaction: ChatInputCommandInteraction) {
|
||||
let loop = interaction.options.getInteger('loop')
|
||||
let queue = useQueue(interaction.guild?.id ?? '')
|
||||
if (!queue) return interaction.followUp({ content: 'Aucune file d\'attente en cours, recherche une musique plutôt !' })
|
||||
|
||||
queue.setRepeatMode(loop as number)
|
||||
return await interaction.reply(`Boucle ${loop === 0 ? 'désactivée' : loop === 1 ? 'en mode Titre' : loop === 2 ? 'en mode File d\'Attente' : 'en autoplay'}.`)
|
||||
}
|
||||
}
|
||||
45
src/commands/player/lyrics.ts
Executable file
45
src/commands/player/lyrics.ts
Executable file
@@ -0,0 +1,45 @@
|
||||
import { ChatInputCommandInteraction, SlashCommandBuilder, EmbedBuilder } from 'discord.js'
|
||||
import { useQueue } from 'discord-player'
|
||||
import { lyricsExtractor } from '@discord-player/extractor'
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('lyrics')
|
||||
.setDescription('Rechercher les paroles d\'une musique.')
|
||||
.addStringOption(option => option.setName('recherche').setDescription('Chercher une musique spécifique')),
|
||||
async execute(interaction: ChatInputCommandInteraction) {
|
||||
await interaction.deferReply()
|
||||
|
||||
let query = interaction.options.getString('recherche', false)
|
||||
if (!query) {
|
||||
let queue = useQueue(interaction.guild?.id ?? '')
|
||||
if (!queue) return interaction.followUp({ content: 'Aucune file d\'attente en cours, recherche une musique plutôt !' })
|
||||
let track = queue.currentTrack
|
||||
if (!track) return interaction.followUp({ content: 'Aucune musique en cours, recherche en une plutôt !' })
|
||||
|
||||
if (track.raw.source === 'spotify') query = `${track.author} ${track.title}`
|
||||
else query = track.title
|
||||
}
|
||||
|
||||
let lyricsFinder = lyricsExtractor()
|
||||
|
||||
let lyrics = await lyricsFinder.search(query).catch(() => null)
|
||||
if (!lyrics) return interaction.followUp({ content: 'Pas de paroles trouvées !' })
|
||||
|
||||
let trimmedLyrics = lyrics.lyrics.substring(0, 1997)
|
||||
|
||||
let embed = new EmbedBuilder()
|
||||
.setColor('#ffc370')
|
||||
.setTitle(lyrics.title)
|
||||
.setURL(lyrics.url)
|
||||
.setThumbnail(lyrics.thumbnail)
|
||||
.setAuthor({
|
||||
name: lyrics.artist.name,
|
||||
iconURL: lyrics.artist.image,
|
||||
url: lyrics.artist.url
|
||||
})
|
||||
.setDescription(trimmedLyrics.length === 1997 ? `${trimmedLyrics}...` : trimmedLyrics)
|
||||
|
||||
return interaction.followUp({ embeds: [embed] })
|
||||
}
|
||||
}
|
||||
15
src/commands/player/pause.ts
Executable file
15
src/commands/player/pause.ts
Executable file
@@ -0,0 +1,15 @@
|
||||
import { SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js'
|
||||
import { useQueue } from 'discord-player'
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('pause')
|
||||
.setDescription('Met en pause la musique.'),
|
||||
async execute(interaction: ChatInputCommandInteraction) {
|
||||
let queue = useQueue(interaction.guild?.id ?? '')
|
||||
if (!queue) return interaction.followUp({ content: 'Aucune file d\'attente en cours, recherche une musique plutôt !' })
|
||||
|
||||
queue.node.setPaused(!queue.node.isPaused())
|
||||
return await interaction.reply('Musique mise en pause !')
|
||||
}
|
||||
}
|
||||
91
src/commands/player/play.ts
Executable file
91
src/commands/player/play.ts
Executable file
@@ -0,0 +1,91 @@
|
||||
import { SlashCommandBuilder, ChatInputCommandInteraction, AutocompleteInteraction, GuildMember } from 'discord.js'
|
||||
import { useMainPlayer, useQueue, QueryType } from 'discord-player'
|
||||
import writeEnv from '../../utils/writeEnv'
|
||||
|
||||
export interface TrackSearchResult { name: string, value: string }
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('play')
|
||||
.setDescription('Jouer une musique.')
|
||||
.addStringOption(option => option.setName('recherche').setDescription('Titre de la musique à chercher').setRequired(true).setAutocomplete(true)),
|
||||
async autocompleteRun(interaction: AutocompleteInteraction) {
|
||||
let query = interaction.options.getString('recherche', true)
|
||||
if (!query) return interaction.respond([])
|
||||
|
||||
let player = useMainPlayer()
|
||||
|
||||
const resultsYouTube = await player.search(query, { searchEngine: QueryType.YOUTUBE })
|
||||
const resultsSpotify = await player.search(query, { searchEngine: QueryType.SPOTIFY_SEARCH })
|
||||
|
||||
const tracksYouTube = resultsYouTube.tracks.slice(0, 5).map((t) => ({
|
||||
name: `YouTube: ${`${t.title} - ${t.author} (${t.duration})`.length > 75 ? `${`${t.title} - ${t.author}`.substring(0, 75)}... (${t.duration})` : `${t.title} - ${t.author} (${t.duration})`}`,
|
||||
value: t.url
|
||||
}))
|
||||
const tracksSpotify = resultsSpotify.tracks.slice(0, 5).map((t) => ({
|
||||
name: `Spotify: ${`${t.title} - ${t.author} (${t.duration})`.length > 75 ? `${`${t.title} - ${t.author}`.substring(0, 75)}... (${t.duration})` : `${t.title} - ${t.author} (${t.duration})`}`,
|
||||
value: t.url
|
||||
}))
|
||||
|
||||
const tracks: TrackSearchResult[] = []
|
||||
tracksYouTube.forEach((t) => tracks.push({ name: t.name, value: t.value }))
|
||||
tracksSpotify.forEach((t) => tracks.push({ name: t.name, value: t.value }))
|
||||
|
||||
return interaction.respond(tracks)
|
||||
},
|
||||
async execute(interaction: ChatInputCommandInteraction) {
|
||||
let member = interaction.member as GuildMember
|
||||
let voiceChannel = member.voice.channel
|
||||
if (!voiceChannel) return await interaction.reply({ content: 'T\'es pas dans un vocal, idiot !', ephemeral: true })
|
||||
|
||||
let botChannel = interaction.guild?.members.me?.voice.channel
|
||||
if (botChannel && voiceChannel.id !== botChannel.id) return await interaction.reply({ content: 'T\'es pas dans mon vocal !', ephemeral: true })
|
||||
|
||||
await interaction.deferReply()
|
||||
|
||||
let query = interaction.options.getString('recherche', true)
|
||||
let player = useMainPlayer()
|
||||
let queue = useQueue(interaction.guild?.id ?? '')
|
||||
|
||||
if (!queue) {
|
||||
if (interaction.guild) queue = player.nodes.create(interaction.guild, {
|
||||
metadata: {
|
||||
channel: interaction.channel,
|
||||
client: interaction.guild.members.me,
|
||||
requestedBy: interaction.user
|
||||
},
|
||||
selfDeaf: true,
|
||||
volume: 20,
|
||||
leaveOnEmpty: true,
|
||||
leaveOnEmptyCooldown: 30000,
|
||||
leaveOnEnd: true,
|
||||
leaveOnEndCooldown: 300000
|
||||
})
|
||||
else return
|
||||
}
|
||||
try { if (!queue.connection) await queue.connect(voiceChannel) }
|
||||
catch (error: any) { console.error(error); return interaction.followUp(`Y'a eu un problème, <@223831938346123275> ! (${error.message})`) }
|
||||
|
||||
// Write the values in the .env file to recover the player if the bot restarts
|
||||
writeEnv('DISCORD_MUSIC_TEXTCHANNEL_ID', interaction.channel?.id ?? '')
|
||||
writeEnv('DISCORD_MUSIC_VOICECHANNEL_ID', voiceChannel.id)
|
||||
|
||||
// Search the song
|
||||
let result = await player.search(query, { requestedBy: interaction.user })
|
||||
if (!result.hasTracks()) return interaction.followUp(`Aucune musique trouvée pour **${query}** !`)
|
||||
let track = result.tracks[0]
|
||||
console.log(track.duration)
|
||||
console.log(track.durationMS)
|
||||
|
||||
let entry = queue.tasksQueue.acquire()
|
||||
await entry.getTask()
|
||||
queue.addTrack(track)
|
||||
|
||||
try {
|
||||
if (!queue.isPlaying()) await queue.node.play()
|
||||
let track_source = track.source === 'youtube' ? 'Youtube' : track.source === 'spotify' ? 'Spotify' : 'Inconnu'
|
||||
return interaction.followUp(`Chargement de la musique **${track.title}** de **${track.author}** sur **${track_source}**...`)
|
||||
} catch (error: any) { console.error(error); return interaction.followUp(`Y'a eu un problème, <@223831938346123275> ! (${error.message})`) }
|
||||
finally { queue.tasksQueue.release() }
|
||||
}
|
||||
}
|
||||
15
src/commands/player/previous.ts
Executable file
15
src/commands/player/previous.ts
Executable file
@@ -0,0 +1,15 @@
|
||||
import { SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js'
|
||||
import { useHistory } from 'discord-player'
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('previous')
|
||||
.setDescription('Joue la musique précédente.'),
|
||||
async execute(interaction: ChatInputCommandInteraction) {
|
||||
let history = useHistory(interaction.guild?.id ?? '')
|
||||
if (!history) return await interaction.reply('Il n\'y a pas d\'historique de musique !')
|
||||
|
||||
await history.previous()
|
||||
return await interaction.reply('Musique précédente jouée !')
|
||||
}
|
||||
}
|
||||
15
src/commands/player/resume.ts
Executable file
15
src/commands/player/resume.ts
Executable file
@@ -0,0 +1,15 @@
|
||||
import { SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js'
|
||||
import { useQueue } from 'discord-player'
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('resume')
|
||||
.setDescription('Reprendre la musique.'),
|
||||
async execute(interaction: ChatInputCommandInteraction) {
|
||||
let queue = useQueue(interaction.guild?.id ?? '')
|
||||
if (!queue) return interaction.followUp({ content: 'Aucune file d\'attente en cours, recherche une musique plutôt !' })
|
||||
|
||||
queue.node.setPaused(!queue.node.isPaused())
|
||||
return await interaction.reply('Musique reprise !')
|
||||
}
|
||||
}
|
||||
15
src/commands/player/shuffle.ts
Executable file
15
src/commands/player/shuffle.ts
Executable file
@@ -0,0 +1,15 @@
|
||||
import { SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js'
|
||||
import { useQueue } from 'discord-player'
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('shuffle')
|
||||
.setDescription('Mélange la file d\'attente.'),
|
||||
async execute(interaction: ChatInputCommandInteraction) {
|
||||
let queue = useQueue(interaction.guild?.id ?? '')
|
||||
if (!queue) return interaction.followUp({ content: 'Aucune file d\'attente en cours, recherche une musique plutôt !' })
|
||||
|
||||
queue.tracks.shuffle()
|
||||
return await interaction.reply('File d\'attente mélangée !')
|
||||
}
|
||||
}
|
||||
15
src/commands/player/skip.ts
Executable file
15
src/commands/player/skip.ts
Executable file
@@ -0,0 +1,15 @@
|
||||
import { SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js'
|
||||
import { useQueue } from 'discord-player'
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('skip')
|
||||
.setDescription('Passer la musique en cours.'),
|
||||
async execute(interaction: ChatInputCommandInteraction) {
|
||||
let queue = useQueue(interaction.guild?.id ?? '')
|
||||
if (!queue) return interaction.followUp({ content: 'Aucune file d\'attente en cours, recherche une musique plutôt !' })
|
||||
|
||||
queue.node.skip()
|
||||
return await interaction.reply('Musique passée !')
|
||||
}
|
||||
}
|
||||
21
src/commands/player/stop.ts
Executable file
21
src/commands/player/stop.ts
Executable file
@@ -0,0 +1,21 @@
|
||||
import { SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js'
|
||||
import { useQueue } from 'discord-player'
|
||||
import writeEnv from '../../utils/writeEnv'
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('stop')
|
||||
.setDescription('Arrêter la musique.'),
|
||||
async execute(interaction: ChatInputCommandInteraction) {
|
||||
let queue = useQueue(interaction.guild?.id ?? '')
|
||||
if (!queue) return interaction.followUp({ content: 'Aucune file d\'attente en cours, recherche une musique plutôt !' })
|
||||
|
||||
queue.delete()
|
||||
writeEnv('DISCORD_MUSIC_TEXTCHANNEL_ID', '')
|
||||
writeEnv('DISCORD_MUSIC_VOICECHANNEL_ID', '')
|
||||
writeEnv('DISCORD_MUSIC_CURRENT_TRACK', '')
|
||||
writeEnv('DISCORD_MUSIC_CURRENT_PROGRESS', '')
|
||||
|
||||
return await interaction.reply('Musique arrêtée !')
|
||||
}
|
||||
}
|
||||
21
src/commands/player/volume.ts
Executable file
21
src/commands/player/volume.ts
Executable file
@@ -0,0 +1,21 @@
|
||||
import { SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js'
|
||||
import { useQueue } from 'discord-player'
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('volume')
|
||||
.setDescription('Modifie le volume de la musique.')
|
||||
.addIntegerOption(option => option.setName('volume')
|
||||
.setDescription('Le volume à mettre (%)')
|
||||
.setRequired(true)
|
||||
.setMinValue(1)
|
||||
.setMaxValue(100)),
|
||||
async execute(interaction: ChatInputCommandInteraction) {
|
||||
let volume = interaction.options.getInteger('volume')
|
||||
let queue = useQueue(interaction.guild?.id ?? '')
|
||||
if (!queue) return interaction.followUp({ content: 'Aucune file d\'attente en cours, recherche une musique plutôt !' })
|
||||
|
||||
queue.node.setVolume(volume as number)
|
||||
return await interaction.reply(`Volume modifié à ${volume}% !`)
|
||||
}
|
||||
}
|
||||
8
src/events/error.ts
Executable file
8
src/events/error.ts
Executable file
@@ -0,0 +1,8 @@
|
||||
import { Events } from 'discord.js'
|
||||
|
||||
module.exports = {
|
||||
name: Events.Error,
|
||||
execute(error: any) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
19
src/events/guildMemberAdd.ts
Executable file
19
src/events/guildMemberAdd.ts
Executable file
@@ -0,0 +1,19 @@
|
||||
import { Events, GuildMember } from 'discord.js'
|
||||
|
||||
module.exports = {
|
||||
name: Events.GuildMemberAdd,
|
||||
async execute(member: GuildMember) {
|
||||
if (member.guild.id !== '1086577543651524699') return
|
||||
member.guild.members.fetch().then(() => {
|
||||
var i = 0
|
||||
member.guild.members.cache.forEach(async member => { if (!member.user.bot) i++ })
|
||||
let channel = member.guild.channels.cache.get('1091140609139560508')
|
||||
if (!channel) return
|
||||
|
||||
console.log(channel.name)
|
||||
console.log(`${i} Gens Posés`)
|
||||
channel.setName('Changement...')
|
||||
channel.setName(`${i} Gens Posés`)
|
||||
}).catch(console.error)
|
||||
}
|
||||
}
|
||||
19
src/events/guildMemberRemove.ts
Executable file
19
src/events/guildMemberRemove.ts
Executable file
@@ -0,0 +1,19 @@
|
||||
import { Events, GuildMember } from 'discord.js'
|
||||
|
||||
module.exports = {
|
||||
name: Events.GuildMemberRemove,
|
||||
async execute(member: GuildMember) {
|
||||
if (member.guild.id !== '1086577543651524699') return
|
||||
member.guild.members.fetch().then(() => {
|
||||
var i = 0
|
||||
member.guild.members.cache.forEach(async member => { if (!member.user.bot) i++ })
|
||||
let channel = member.guild.channels.cache.get('1091140609139560508')
|
||||
if (!channel) return
|
||||
|
||||
console.log(channel.name)
|
||||
console.log(`${i} Gens Posés`)
|
||||
channel.setName('Changement...')
|
||||
channel.setName(`${i} Gens Posés`)
|
||||
}).catch(console.error)
|
||||
}
|
||||
}
|
||||
43
src/events/interactionCreate.ts
Executable file
43
src/events/interactionCreate.ts
Executable file
@@ -0,0 +1,43 @@
|
||||
import { Events, Interaction, ChatInputCommandInteraction, AutocompleteInteraction, ButtonInteraction } from 'discord.js'
|
||||
import editPlayer from '../utilsPlayer/edit'
|
||||
import playerButtons from '../utilsPlayer/buttons'
|
||||
|
||||
module.exports = {
|
||||
name: Events.InteractionCreate,
|
||||
async execute(interaction: Interaction) {
|
||||
//if (!interaction.isAutocomplete() && !interaction.isChatInputCommand() && !interaction.isButton()) return console.error(`Interaction ${interaction.commandName} is not a command.`)
|
||||
|
||||
if (interaction.isChatInputCommand()) {
|
||||
interaction = interaction as ChatInputCommandInteraction
|
||||
let chatInputCommand = interaction.client.commands.get(interaction.commandName)
|
||||
if (!chatInputCommand) return console.error(`No chat input command matching ${interaction.commandName} was found.`)
|
||||
|
||||
console.log(`Command '${interaction.commandName}' launched by ${interaction.user.tag}`)
|
||||
|
||||
try { await chatInputCommand.execute(interaction) }
|
||||
catch (error) { console.error(`Error executing ${interaction.commandName}:`, error) }
|
||||
}
|
||||
else if (interaction.isAutocomplete()) {
|
||||
interaction = interaction as AutocompleteInteraction
|
||||
let autoCompleteRun = interaction.client.commands.get(interaction.commandName)
|
||||
if (!autoCompleteRun) return console.error(`No autoCompleteRun matching ${interaction.commandName} was found.`)
|
||||
|
||||
console.log(`AutoCompleteRun '${interaction.commandName}' launched by ${interaction.user.tag}`)
|
||||
|
||||
try { await autoCompleteRun.autocompleteRun(interaction) }
|
||||
catch (error) { console.error(`Error autocompleting ${interaction.commandName}:`, error) }
|
||||
}
|
||||
else if (interaction.isButton()) {
|
||||
interaction = interaction as ButtonInteraction
|
||||
let button = interaction.client.buttons.get(interaction.customId)
|
||||
if (!button) return console.error(`No button id matching ${interaction.customId} was found.`)
|
||||
|
||||
console.log(`Button '${interaction.customId}' clicked by ${interaction.user.tag}`)
|
||||
|
||||
if (playerButtons.includes(interaction.customId)) { await editPlayer(interaction) }
|
||||
|
||||
try { await button.execute(interaction) }
|
||||
catch (error) { console.error(`Error clicking ${interaction.customId}:`, error) }
|
||||
}
|
||||
}
|
||||
}
|
||||
30
src/events/ready.ts
Executable file
30
src/events/ready.ts
Executable file
@@ -0,0 +1,30 @@
|
||||
import { Events, Client, ActivityType } from 'discord.js'
|
||||
import { useMainPlayer } from 'discord-player'
|
||||
import replay from '../utilsPlayer/replay'
|
||||
import disco from '../utilsPlayer/disco'
|
||||
import 'dotenv/config'
|
||||
|
||||
declare module "discord.js" {
|
||||
export interface Client {
|
||||
disco: { interval: NodeJS.Timeout }
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
name: Events.ClientReady,
|
||||
once: true,
|
||||
async execute(client: Client) {
|
||||
console.log(`Ready! Logged in as ${client.user?.tag ?? 'unknown'}`)
|
||||
client.user?.setActivity('some bangers...', { type: ActivityType.Listening })
|
||||
|
||||
await useMainPlayer().extractors.loadDefault(ext => ext === 'YouTubeExtractor' || ext === 'SpotifyExtractor').then(() => console.log('YouTube and Spotify extractors loaded.')).catch(console.error)
|
||||
|
||||
if (process.env.DISCORD_MUSIC_CURRENT_TRACK) await replay(client)
|
||||
|
||||
client.disco = { interval: {} as NodeJS.Timeout }
|
||||
client.disco.interval = setInterval(async () => {
|
||||
let state = await disco(client)
|
||||
if (state === 'clear') clearInterval(client.disco.interval)
|
||||
}, 2000)
|
||||
}
|
||||
}
|
||||
59
src/events/voiceStateUpdate.ts
Executable file
59
src/events/voiceStateUpdate.ts
Executable file
@@ -0,0 +1,59 @@
|
||||
import { Events, VoiceState } from 'discord.js'
|
||||
|
||||
module.exports = {
|
||||
name: Events.VoiceStateUpdate,
|
||||
async execute(oldState: VoiceState, newState: VoiceState) {
|
||||
/*
|
||||
let oldMute = oldState.serverMute
|
||||
let newMute = newState.serverMute
|
||||
let oldDeaf = oldState.serverDeaf
|
||||
let newDeaf = newState.serverDeaf
|
||||
let oldChannel = oldState.channelId
|
||||
let newChannel = newState.channelId
|
||||
console.log(oldChannel)
|
||||
console.log(newChannel)
|
||||
let guild = newState.guild
|
||||
let member = newState.member
|
||||
let channel = guild.channels.cache.get('1076215868863819848')
|
||||
let angels = guild.members.cache.get('223831938346123275')
|
||||
if (oldChannel !== newChannel) {
|
||||
let executor = await logMoveOrKick('channel_id')
|
||||
//if (!executor) channel.send(`Impossible de savoir qui a déplacé <@${member.id}> !`)
|
||||
//else if (member.id === executor.id) channel.send(`<@${member.id}> s'est déplacé lui-même le con...`)
|
||||
//else {
|
||||
// channel.send(`<@${member.id}> a été mis en sourdine par <@${executor.id}> !`)
|
||||
//}
|
||||
} else if (!oldMute && newMute) {
|
||||
let executor = await logMuteOrDeaf('mute')
|
||||
if (!executor) channel.send(`Impossible de savoir qui a muté <@${member.id}> !`)
|
||||
else if (member.id === executor.id) channel.send(`<@${member.id}> s'est muté lui-même le con...`)
|
||||
else {
|
||||
channel.send(`<@${member.id}> a été muté par <@${executor.id}> !`)
|
||||
}
|
||||
} else if (!oldDeaf && newDeaf) {
|
||||
let executor = await logMuteOrDeaf('deaf')
|
||||
if (!executor) channel.send(`Impossible de savoir qui a mis en sourdine <@${member.id}> !`)
|
||||
else if (member.id === executor.id) channel.send(`<@${member.id}> s'est mis en sourdine lui-même le con...`)
|
||||
else {
|
||||
channel.send(`<@${member.id}> a été mis en sourdine par <@${executor.id}> !`)
|
||||
}
|
||||
}
|
||||
async function logMoveOrKick() {
|
||||
let auditLogs = await guild.fetchAuditLogs({ limit: 1, type: AuditLogEvent.MemberMove })
|
||||
console.log(auditLogs.entries.find(entry => { return entry }))
|
||||
let log = await auditLogs.entries.find(entry => { return entry.extra.channel.id === newChannel })
|
||||
console.log(log)
|
||||
if (!log) return undefined
|
||||
let executor = await guild.members.cache.get(log.executor.id)
|
||||
return executor
|
||||
}
|
||||
async function logMuteOrDeaf(type) {
|
||||
let auditLogs = await guild.fetchAuditLogs({ limit: 1, type: AuditLogEvent.MemberUpdate })
|
||||
let log = await auditLogs.entries.find(entry => { return entry.target.id === member.id && entry.changes[0].key === type && entry.changes[0].new === true })
|
||||
if (!log) return undefined
|
||||
let executor = await guild.members.cache.get(log.executor.id)
|
||||
return executor
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
10
src/eventsPlayer/audioTrackAdd.ts
Executable file
10
src/eventsPlayer/audioTrackAdd.ts
Executable file
@@ -0,0 +1,10 @@
|
||||
import { GuildQueue, Track } from 'discord-player'
|
||||
import { PlayerMetadata } from '../utilsPlayer/metadata'
|
||||
|
||||
export default {
|
||||
name: 'audioTrackAdd',
|
||||
async execute(queue: GuildQueue<PlayerMetadata>, track: Track) {
|
||||
// Emitted when the player adds a single song to its queue
|
||||
queue.metadata.channel.send(`Musique **${track.title}** de **${track.author}** ajoutée à la file d'attente !`)
|
||||
}
|
||||
}
|
||||
10
src/eventsPlayer/audioTracksAdd.ts
Executable file
10
src/eventsPlayer/audioTracksAdd.ts
Executable file
@@ -0,0 +1,10 @@
|
||||
import { GuildQueue, Track } from 'discord-player'
|
||||
import { PlayerMetadata } from '../utilsPlayer/metadata'
|
||||
|
||||
export default {
|
||||
name: 'audioTracksAdd',
|
||||
async execute(queue: GuildQueue<PlayerMetadata>, track: Array<Track>) {
|
||||
// Emitted when the player adds multiple songs to its queue
|
||||
queue.metadata.channel.send(`Ajout de ${track.length} musiques à la file d'attente !`)
|
||||
}
|
||||
}
|
||||
10
src/eventsPlayer/debug.ts
Executable file
10
src/eventsPlayer/debug.ts
Executable file
@@ -0,0 +1,10 @@
|
||||
import { GuildQueue } from 'discord-player'
|
||||
|
||||
export default {
|
||||
name: 'debug',
|
||||
async execute(queue: GuildQueue, message: string) {
|
||||
// Emitted when the player queue sends debug info
|
||||
// Useful for seeing what state the current queue is at
|
||||
console.log(`Player debug event: ${message}`)
|
||||
}
|
||||
}
|
||||
16
src/eventsPlayer/disconnect.ts
Executable file
16
src/eventsPlayer/disconnect.ts
Executable file
@@ -0,0 +1,16 @@
|
||||
import { GuildQueue, Track } from 'discord-player'
|
||||
import { PlayerMetadata } from '../utilsPlayer/metadata'
|
||||
import writeEnv from '../utils/writeEnv'
|
||||
|
||||
export default {
|
||||
name: 'disconnect',
|
||||
async execute(queue: GuildQueue<PlayerMetadata>, track: Track) {
|
||||
// Emitted when the bot leaves the voice channel
|
||||
queue.metadata.channel.send("J'ai quitté le vocal !")
|
||||
|
||||
writeEnv('DISCORD_MUSIC_TEXTCHANNEL_ID', '')
|
||||
writeEnv('DISCORD_MUSIC_VOICECHANNEL_ID', '')
|
||||
writeEnv('DISCORD_MUSIC_CURRENT_TRACK', '')
|
||||
writeEnv('DISCORD_MUSIC_CURRENT_PROGRESS', '')
|
||||
}
|
||||
}
|
||||
11
src/eventsPlayer/emptyChannel.ts
Executable file
11
src/eventsPlayer/emptyChannel.ts
Executable file
@@ -0,0 +1,11 @@
|
||||
import { GuildQueue, Track } from 'discord-player'
|
||||
import { PlayerMetadata } from '../utilsPlayer/metadata'
|
||||
|
||||
export default {
|
||||
name: 'emptyChannel',
|
||||
async execute(queue: GuildQueue<PlayerMetadata>, track: Track) {
|
||||
// Emitted when the voice channel has been empty for the set threshold
|
||||
// Bot will automatically leave the voice channel with this event
|
||||
queue.metadata.channel.send(`Je quitte le vocal car il est vide depuis trop longtemps.`)
|
||||
}
|
||||
}
|
||||
10
src/eventsPlayer/emptyQueue.ts
Executable file
10
src/eventsPlayer/emptyQueue.ts
Executable file
@@ -0,0 +1,10 @@
|
||||
import { GuildQueue, Track } from 'discord-player'
|
||||
import { PlayerMetadata } from '../utilsPlayer/metadata'
|
||||
|
||||
export default {
|
||||
name: 'emptyQueue',
|
||||
async execute(queue: GuildQueue<PlayerMetadata>) {
|
||||
// Emitted when the player queue has finished
|
||||
queue.metadata.channel.send("File d'attente vide !")
|
||||
}
|
||||
}
|
||||
10
src/eventsPlayer/error.ts
Executable file
10
src/eventsPlayer/error.ts
Executable file
@@ -0,0 +1,10 @@
|
||||
import { GuildQueue } from 'discord-player'
|
||||
|
||||
export default {
|
||||
name: 'error',
|
||||
async execute(queue: GuildQueue, error: Error) {
|
||||
// Emitted when the player queue encounters error
|
||||
console.log(`General player error event: ${error.message}`)
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
10
src/eventsPlayer/playerError.ts
Executable file
10
src/eventsPlayer/playerError.ts
Executable file
@@ -0,0 +1,10 @@
|
||||
import { GuildQueue } from 'discord-player'
|
||||
|
||||
export default {
|
||||
name: 'playerError',
|
||||
async execute(queue: GuildQueue, error: Error) {
|
||||
// Emitted when the audio player errors while streaming audio track
|
||||
console.log(`\u001b[1;31m Player error event: ${error.message}`)
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
10
src/eventsPlayer/playerSkip.ts
Executable file
10
src/eventsPlayer/playerSkip.ts
Executable file
@@ -0,0 +1,10 @@
|
||||
import { GuildQueue, Track } from 'discord-player'
|
||||
import { PlayerMetadata } from '../utilsPlayer/metadata'
|
||||
|
||||
export default {
|
||||
name: 'playerSkip',
|
||||
async execute(queue: GuildQueue<PlayerMetadata>, track: Track) {
|
||||
// Emitted when the audio player fails to load the stream for a song
|
||||
queue.metadata.channel.send(`Musique **${track.title}** de **${track.author}** passée !`)
|
||||
}
|
||||
}
|
||||
13
src/eventsPlayer/playerStart.ts
Executable file
13
src/eventsPlayer/playerStart.ts
Executable file
@@ -0,0 +1,13 @@
|
||||
import { GuildQueue, Track } from 'discord-player'
|
||||
import { PlayerMetadata } from '../utilsPlayer/metadata'
|
||||
import writeEnv from '../utils/writeEnv'
|
||||
|
||||
export default {
|
||||
name: 'playerStart',
|
||||
async execute(queue: GuildQueue<PlayerMetadata>, track: Track) {
|
||||
// Emitted when the player starts to play a song
|
||||
queue.metadata.channel.send(`Lecture de **${track.title}** de **${track.author}** !`)
|
||||
|
||||
writeEnv(`DISCORD_MUSIC_CURRENT_TRACK`, track.url)
|
||||
}
|
||||
}
|
||||
89
src/index.ts
Executable file
89
src/index.ts
Executable file
@@ -0,0 +1,89 @@
|
||||
// PACKAGES
|
||||
import { Client, Collection, GatewayIntentBits, REST, Routes, ChatInputCommandInteraction, AutocompleteInteraction, ButtonInteraction } from 'discord.js'
|
||||
import { Player } from 'discord-player'
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
import 'dotenv/config'
|
||||
|
||||
export interface Command {
|
||||
name: string,
|
||||
description: string,
|
||||
data: any,
|
||||
autocompleteRun: (interaction: AutocompleteInteraction) => any,
|
||||
execute: (interaction: ChatInputCommandInteraction) => any
|
||||
}
|
||||
export interface Button {
|
||||
name: string,
|
||||
description: string,
|
||||
id: string,
|
||||
execute: (interaction: ButtonInteraction) => any
|
||||
}
|
||||
|
||||
declare module 'discord.js' {
|
||||
export interface Client {
|
||||
commands: Collection<unknown, Command>
|
||||
buttons: Collection<unknown, Button>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// CLIENT INITIALIZATION
|
||||
let intents = [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildVoiceStates]
|
||||
const client = new Client({ intents })
|
||||
|
||||
// EVENTS HANDLING
|
||||
const eventFiles = fs.readdirSync(path.join(__dirname, './events')).filter(file => file.endsWith('.ts'))
|
||||
eventFiles.forEach(file => {
|
||||
let event = require(path.join(__dirname, './events', file))
|
||||
if (event.once) client.once(event.name, (...args) => { event.execute(...args) })
|
||||
else client.on(event.name, (...args) => { event.execute(...args) })
|
||||
})
|
||||
|
||||
// COMMANDS HANDLING
|
||||
client.commands = new Collection()
|
||||
|
||||
const commandFolders = fs.readdirSync(path.join(__dirname, './commands'))
|
||||
commandFolders.forEach(folder => {
|
||||
let folderPath = path.join(__dirname, './commands', folder)
|
||||
let commandFiles = fs.readdirSync(folderPath).filter(file => file.endsWith('.ts'))
|
||||
commandFiles.forEach(file => {
|
||||
let command = require(path.join(folderPath, file))
|
||||
if ('data' in command && 'execute' in command) {
|
||||
const commandData = command.data.toJSON()
|
||||
if (commandData) client.commands.set(commandData.name, command)
|
||||
} else console.log(`[WARNING] The command at ${`${folderPath}/${file}`} is missing a required "data" or "execute" property.`)
|
||||
})
|
||||
})
|
||||
|
||||
// COMMANDS REGISTERING
|
||||
const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_TOKEN as string)
|
||||
async () => {
|
||||
try { await rest.put(Routes.applicationCommands(process.env.DISCORD_APP_ID as string), { body: client.commands }) }
|
||||
catch (error) { console.error(error) }
|
||||
}
|
||||
|
||||
// BUTTONS HANDLING
|
||||
client.buttons = new Collection()
|
||||
|
||||
const buttonFiles = fs.readdirSync(path.join(__dirname, './buttons')).filter(file => file.endsWith('.ts'))
|
||||
buttonFiles.forEach(file => {
|
||||
let button = require(path.join(__dirname, './buttons', file))
|
||||
if ('id' in button && 'execute' in button) client.buttons.set(button.id, button)
|
||||
else console.log(`[WARNING] The button ${file} is missing a required "id" or "execute" property.`)
|
||||
})
|
||||
|
||||
|
||||
// PLAYER INITIALIZATION
|
||||
const player = new Player(client)
|
||||
|
||||
// PLAYER EVENTS HANDLING
|
||||
const eventPlayerFiles = fs.readdirSync(path.join(__dirname, './eventsPlayer')).filter(file => file.endsWith('.ts'))
|
||||
eventPlayerFiles.forEach(async file => {
|
||||
let event = await import(path.join(__dirname, './eventsPlayer', file))
|
||||
if (event.default.name === 'debug') return
|
||||
player.events.on(event.default.name, (...args: any[]) => event.default.execute(...args))
|
||||
})
|
||||
|
||||
|
||||
// LAUNCH
|
||||
client.login()
|
||||
BIN
src/static/parle.mp3
Executable file
BIN
src/static/parle.mp3
Executable file
Binary file not shown.
BIN
src/static/stronger_shorter.mp3
Executable file
BIN
src/static/stronger_shorter.mp3
Executable file
Binary file not shown.
95
src/utils/amp.ts
Normal file
95
src/utils/amp.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import axios from 'axios'
|
||||
import writeEnv from './writeEnv'
|
||||
|
||||
export const ADSModule = {
|
||||
async GetInstances(SESSIONID: string) {
|
||||
return await axios.post(`${process.env.AMP_HOST}/API/ADSModule/GetInstances`, {
|
||||
SESSIONID
|
||||
}).then(response => {
|
||||
if (!response.data.result) return { status: 'fail', data: response.data }
|
||||
return { status: 'success', data: response.data }
|
||||
}).catch(error => {
|
||||
console.error(error)
|
||||
return { status: 'error', data: error }
|
||||
})
|
||||
},
|
||||
|
||||
async ManageInstance(SESSIONID: string, InstanceId: string) {
|
||||
return await axios.post(`${process.env.AMP_HOST}/API/ADSModule/ManageInstance`, {
|
||||
SESSIONID,
|
||||
InstanceId
|
||||
}).then(response => {
|
||||
console.log(response.data)
|
||||
|
||||
if (!response.data.result) return { status: 'fail', data: response.data }
|
||||
return { status: 'success', data: response.data }
|
||||
}).catch(error => {
|
||||
console.error(error)
|
||||
return { status: 'error', data: error }
|
||||
})
|
||||
},
|
||||
|
||||
async RestartInstance(SESSIONID: string, InstanceName: string) {
|
||||
return await axios.post(`${process.env.AMP_HOST}/API/ADSModule/RestartInstance`, {
|
||||
SESSIONID,
|
||||
InstanceName
|
||||
}).then(response => {
|
||||
console.log(response.data)
|
||||
|
||||
//if (!response.data.success) return { status: 'fail', data: response.data }
|
||||
return { status: 'success', data: response.data }
|
||||
}).catch(error => {
|
||||
console.error(error)
|
||||
return { status: 'error', data: error }
|
||||
})
|
||||
},
|
||||
|
||||
async Servers(SESSIONID: string, InstanceId: string) {
|
||||
return await axios.get(`${process.env.AMP_HOST}/API/ADSModule/Servers`, {
|
||||
data: {
|
||||
SESSIONID,
|
||||
InstanceId
|
||||
}
|
||||
}).then(response => {
|
||||
console.log(response)
|
||||
console.log(response.data)
|
||||
|
||||
if (!response.data.result) return { status: 'fail', data: response.data }
|
||||
return { status: 'success', data: response.data }
|
||||
}).catch(error => {
|
||||
console.error(error)
|
||||
return { status: 'error', data: error }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const Core = {
|
||||
async Login(details: any) {
|
||||
return await axios.post(`${process.env.AMP_HOST}/API/Core/Login`,
|
||||
details
|
||||
).then(response => {
|
||||
if (!response.data.success) return { status: 'fail', data: response.data }
|
||||
|
||||
writeEnv('AMP_USERNAME', response.data.userInfo.Username)
|
||||
writeEnv('AMP_SESSIONID', response.data.sessionID)
|
||||
writeEnv('AMP_REMEMBER_TOKEN', response.data.rememberMeToken)
|
||||
|
||||
return { status: 'success', data: response.data }
|
||||
}).catch(error => {
|
||||
console.error(error)
|
||||
return { status: 'error', data: error }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export async function CheckSession(SESSIONID: string) {
|
||||
return await axios.post(`${process.env.AMP_HOST}/API/ADSModule/GetInstances`, {
|
||||
SESSIONID
|
||||
}).then(response => {
|
||||
if (!response.data.result) return { status: 'fail', data: response.data }
|
||||
return { status: 'success', data: response.data }
|
||||
}).catch(error => {
|
||||
console.error(error)
|
||||
return { status: 'error', data: error }
|
||||
})
|
||||
}
|
||||
98
src/utils/crack.ts
Normal file
98
src/utils/crack.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import parseTorrent, { toMagnetURI } from 'parse-torrent'
|
||||
import iconv from 'iconv-lite'
|
||||
import axios from 'axios'
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
|
||||
export declare class Game {
|
||||
name: string
|
||||
link: string
|
||||
}
|
||||
|
||||
const headers = {
|
||||
h1: {
|
||||
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
||||
"x-requested-with": "XMLHttpRequest"
|
||||
},
|
||||
h2: {
|
||||
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
||||
"accept-language": "fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7",
|
||||
"cache-control": "no-cache",
|
||||
"pragma": "no-cache",
|
||||
"sec-ch-ua": "\"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"110\", \"Opera GX\";v=\"96\"",
|
||||
"sec-ch-ua-mobile": "?0",
|
||||
"sec-ch-ua-platform": "\"Windows\"",
|
||||
"sec-fetch-dest": "document",
|
||||
"sec-fetch-mode": "navigate",
|
||||
"sec-fetch-site": "none",
|
||||
"sec-fetch-user": "?1",
|
||||
"upgrade-insecure-requests": "1",
|
||||
"cookie": "online_fix_auth=gAAAAABkKM0s9WNLe_V6euTnJD7UQjppVty9B7OOyHBYOyVcbcejj8F6KveBcLxlf3mlx_vE7JEFPHlrpj-Aq6BFJyKPGzxds_wpcPV2MdXPyDGQLsz4mAvt3qgTgGg25MapWo_fSIOMiAAsF4Gv_uh4kUOiR_jgbHCZWJGPgpNQwU2HFFyvahYR6MzR7nYE9-fCmrev3obkRbro43vIVTTX4UyJMRHadrsY5Q-722TzinCZVmAuJfc=; dle_password=89465c26673e0199e5272e4730772c35; _ym_uid=1670534560361937997; _ym_d=1680394955; _ym_isad=2; dle_user_id=2619796; PHPSESSID=3v8sd281sr0n1n9f1p66q25sa2",
|
||||
"Referer": "https://online-fix.me/",
|
||||
"Referrer-Policy": "strict-origin-when-cross-origin"
|
||||
}
|
||||
}
|
||||
|
||||
export async function search(query: string) {
|
||||
let body = await fetch("https://online-fix.me/engine/ajax/search.php", { headers: headers.h1, body: `query=${query}`, method: "POST" })
|
||||
.then(response => response.arrayBuffer())
|
||||
.then(arrayBuffer => { return iconv.decode(Buffer.from(arrayBuffer), 'win1251') })
|
||||
.catch(console.error)
|
||||
try {
|
||||
if (!body) return
|
||||
let matches = body.split('</div>')[1].split('<span class="seperator fastfullsearch">')[0].split('</a>')
|
||||
let games = [] as Game[]
|
||||
matches.pop()
|
||||
matches.forEach(async match => {
|
||||
let name = match.split('"><span class="searchheading">')[1].split('</span>')[0].slice(0, -8)
|
||||
let link = match.split('<a href="')[1].split('"><span class="searchheading">')[0]
|
||||
games.push({ name, link })
|
||||
})
|
||||
return games
|
||||
} catch (error) { return error }
|
||||
}
|
||||
|
||||
export async function repo(game: Game) {
|
||||
let body = await fetch(game.link, { headers: headers.h2, body: null, method: "GET" })
|
||||
.then(response => response.arrayBuffer())
|
||||
.then(arrayBuffer => { return iconv.decode(Buffer.from(arrayBuffer), 'win1251') })
|
||||
.catch(console.error)
|
||||
try {
|
||||
if (!body) return
|
||||
let name = body.split('https://uploads.online-fix.me:2053/torrents/')[1].split('"')[0]
|
||||
let url = `https://uploads.online-fix.me:2053/torrents/${name}`
|
||||
return url
|
||||
} catch (error) { console.error(error) }
|
||||
}
|
||||
|
||||
export async function torrent(url: string) {
|
||||
let response = await fetch(url, { headers: headers.h2, body: null, method: "GET" }).catch(console.error)
|
||||
try {
|
||||
if (!response) return
|
||||
let body = await response.text()
|
||||
let file = body.split('<a href="')[2].split('">')[0]
|
||||
return file
|
||||
} catch (error) { console.error(error) }
|
||||
}
|
||||
|
||||
export async function download(url: string, file: string) {
|
||||
let filePath = path.join(__dirname, '../../public/cracks/', file)
|
||||
let writer = fs.createWriteStream(filePath)
|
||||
try {
|
||||
await axios({ url: url + file, method: 'GET', responseType: 'stream', headers: headers.h2 }).then(response => {
|
||||
return new Promise((resolve, reject) => {
|
||||
response.data.pipe(writer)
|
||||
let error = null as unknown as Error
|
||||
writer.on('error', err => { error = err; writer.close(); reject(err) })
|
||||
writer.on('close', () => { if (!error) resolve(true) })
|
||||
})
|
||||
}).catch(console.error)
|
||||
return filePath
|
||||
} catch (error) { console.error(error) }
|
||||
}
|
||||
|
||||
export async function magnet(filePath: string) {
|
||||
let torrentData = parseTorrent(fs.readFileSync(filePath))
|
||||
let uri = toMagnetURI(torrentData)
|
||||
return uri
|
||||
}
|
||||
10
src/utils/getUptime.ts
Executable file
10
src/utils/getUptime.ts
Executable file
@@ -0,0 +1,10 @@
|
||||
import { Client } from 'discord.js'
|
||||
|
||||
export default function (uptime: Client["uptime"]) {
|
||||
if (!uptime) return '0J, 0H, 0M et 0S'
|
||||
let days = Math.floor(uptime / 86400000)
|
||||
let hours = Math.floor(uptime / 3600000) % 24
|
||||
let minutes = Math.floor(uptime / 60000) % 60
|
||||
let seconds = Math.floor(uptime / 1000) % 60
|
||||
return `${days}J, ${hours}H, ${minutes}M et ${seconds}S`
|
||||
}
|
||||
7
src/utils/writeEnv.ts
Executable file
7
src/utils/writeEnv.ts
Executable file
@@ -0,0 +1,7 @@
|
||||
import fs from 'fs'
|
||||
|
||||
export default ((variable: string, value: string) => {
|
||||
let parsedFile = fs.readFileSync('./.env', 'utf8')
|
||||
parsedFile = parsedFile.replace(new RegExp(`${variable} = .*`, 'g'), `${variable} = ${value}`)
|
||||
fs.writeFileSync('./.env', parsedFile)
|
||||
})
|
||||
13
src/utilsAMP/ADSModule/GetInstances.ts
Executable file
13
src/utilsAMP/ADSModule/GetInstances.ts
Executable file
@@ -0,0 +1,13 @@
|
||||
const axios = require('axios')
|
||||
|
||||
module.exports = (async (SESSIONID) => {
|
||||
return await axios.post(`${process.env.AMP_HOST}/API/${__filename.split('utilsAMP/')[1].split('.js')[0]}`, {
|
||||
SESSIONID
|
||||
}).then(response => {
|
||||
if (!response.data.result) return { status: 'fail', data: response.data }
|
||||
return { status: 'success', data: response.data }
|
||||
}).catch(error => {
|
||||
console.error(error)
|
||||
return { status: 'error', data: error }
|
||||
})
|
||||
})
|
||||
16
src/utilsAMP/ADSModule/ManageInstance.ts
Executable file
16
src/utilsAMP/ADSModule/ManageInstance.ts
Executable file
@@ -0,0 +1,16 @@
|
||||
const axios = require('axios')
|
||||
|
||||
module.exports = (async (SESSIONID, InstanceId) => {
|
||||
return await axios.post(`${process.env.AMP_HOST}/API/${__filename.split('utilsAMP/')[1].split('.js')[0]}`, {
|
||||
SESSIONID,
|
||||
InstanceId
|
||||
}).then(response => {
|
||||
console.log(response.data)
|
||||
|
||||
if (!response.data.result) return { status: 'fail', data: response.data }
|
||||
return { status: 'success', data: response.data }
|
||||
}).catch(error => {
|
||||
console.error(error)
|
||||
return { status: 'error', data: error }
|
||||
})
|
||||
})
|
||||
16
src/utilsAMP/ADSModule/RestartInstance.ts
Executable file
16
src/utilsAMP/ADSModule/RestartInstance.ts
Executable file
@@ -0,0 +1,16 @@
|
||||
const axios = require('axios')
|
||||
|
||||
module.exports = (async (SESSIONID, InstanceName) => {
|
||||
return await axios.post(`${process.env.AMP_HOST}/API/${__filename.split('utilsAMP/')[1].split('.js')[0]}`, {
|
||||
SESSIONID,
|
||||
InstanceName
|
||||
}).then(response => {
|
||||
console.log(response.data)
|
||||
|
||||
//if (!response.data.success) return { status: 'fail', data: response.data }
|
||||
return { status: 'success', data: response.data }
|
||||
}).catch(error => {
|
||||
console.error(error)
|
||||
return { status: 'error', data: error }
|
||||
})
|
||||
})
|
||||
17
src/utilsAMP/ADSModule/Servers.ts
Executable file
17
src/utilsAMP/ADSModule/Servers.ts
Executable file
@@ -0,0 +1,17 @@
|
||||
const axios = require('axios')
|
||||
|
||||
module.exports = (async (SESSIONID, InstanceId) => {
|
||||
return await axios.get(`${process.env.AMP_HOST}/API/${__filename.split('utilsAMP/')[1].split('.js')[0]}`, {
|
||||
SESSIONID,
|
||||
InstanceId
|
||||
}).then(response => {
|
||||
console.log(response)
|
||||
console.log(response.data)
|
||||
|
||||
if (!response.data.result) return { status: 'fail', data: response.data }
|
||||
return { status: 'success', data: response.data }
|
||||
}).catch(error => {
|
||||
console.error(error)
|
||||
return { status: 'error', data: error }
|
||||
})
|
||||
})
|
||||
13
src/utilsAMP/CheckSession.ts
Executable file
13
src/utilsAMP/CheckSession.ts
Executable file
@@ -0,0 +1,13 @@
|
||||
const axios = require('axios')
|
||||
|
||||
module.exports = (async (SESSIONID) => {
|
||||
return await axios.post(`${process.env.AMP_HOST}/API/ADSModule/GetInstances`, {
|
||||
SESSIONID
|
||||
}).then(response => {
|
||||
if (!response.data.result) return { status: 'fail', data: response.data }
|
||||
return { status: 'success', data: response.data }
|
||||
}).catch(error => {
|
||||
console.error(error)
|
||||
return { status: 'error', data: error }
|
||||
})
|
||||
})
|
||||
21
src/utilsAMP/Core/Login.ts
Executable file
21
src/utilsAMP/Core/Login.ts
Executable file
@@ -0,0 +1,21 @@
|
||||
const axios = require('axios')
|
||||
|
||||
const appDir = require('path').dirname(require.main.filename)
|
||||
const writeEnv = require(appDir + '/utils/writeEnv')
|
||||
|
||||
module.exports = (async (details) => {
|
||||
return await axios.post(`${process.env.AMP_HOST}/API/${__filename.split('utilsAMP/')[1].split('.js')[0]}`,
|
||||
details
|
||||
).then(response => {
|
||||
if (!response.data.success) return { status: 'fail', data: response.data }
|
||||
|
||||
writeEnv('AMP_USERNAME', response.data.userInfo.Username)
|
||||
writeEnv('AMP_SESSIONID', response.data.sessionID)
|
||||
writeEnv('AMP_REMEMBER_TOKEN', response.data.rememberMeToken)
|
||||
|
||||
return { status: 'success', data: response.data }
|
||||
}).catch(error => {
|
||||
console.error(error)
|
||||
return { status: 'error', data: error }
|
||||
})
|
||||
})
|
||||
18
src/utilsCrack/download.ts
Executable file
18
src/utilsCrack/download.ts
Executable file
@@ -0,0 +1,18 @@
|
||||
const axios = require('axios')
|
||||
const fs = require('fs')
|
||||
|
||||
module.exports = download = (async (url, file, headers) => {
|
||||
let path = `./cracks/${file}`
|
||||
let writer = fs.createWriteStream(path)
|
||||
try {
|
||||
await axios({ url: url + file, method: 'GET', responseType: 'stream', headers }).then(response => {
|
||||
return new Promise((resolve, reject) => {
|
||||
response.data.pipe(writer)
|
||||
let error = null
|
||||
writer.on('error', err => { error = err; writer.close(); reject(err) })
|
||||
writer.on('close', () => { if (!error) resolve(true) })
|
||||
})
|
||||
}).catch(console.error)
|
||||
return path
|
||||
} catch (error) { console.error(error) }
|
||||
})
|
||||
23
src/utilsCrack/headers.ts
Executable file
23
src/utilsCrack/headers.ts
Executable file
@@ -0,0 +1,23 @@
|
||||
const h1 = {
|
||||
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
||||
"x-requested-with": "XMLHttpRequest"
|
||||
}
|
||||
const h2 = {
|
||||
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
||||
"accept-language": "fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7",
|
||||
"cache-control": "no-cache",
|
||||
"pragma": "no-cache",
|
||||
"sec-ch-ua": "\"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"110\", \"Opera GX\";v=\"96\"",
|
||||
"sec-ch-ua-mobile": "?0",
|
||||
"sec-ch-ua-platform": "\"Windows\"",
|
||||
"sec-fetch-dest": "document",
|
||||
"sec-fetch-mode": "navigate",
|
||||
"sec-fetch-site": "none",
|
||||
"sec-fetch-user": "?1",
|
||||
"upgrade-insecure-requests": "1",
|
||||
"cookie": "online_fix_auth=gAAAAABkKM0s9WNLe_V6euTnJD7UQjppVty9B7OOyHBYOyVcbcejj8F6KveBcLxlf3mlx_vE7JEFPHlrpj-Aq6BFJyKPGzxds_wpcPV2MdXPyDGQLsz4mAvt3qgTgGg25MapWo_fSIOMiAAsF4Gv_uh4kUOiR_jgbHCZWJGPgpNQwU2HFFyvahYR6MzR7nYE9-fCmrev3obkRbro43vIVTTX4UyJMRHadrsY5Q-722TzinCZVmAuJfc=; dle_password=89465c26673e0199e5272e4730772c35; _ym_uid=1670534560361937997; _ym_d=1680394955; _ym_isad=2; dle_user_id=2619796; PHPSESSID=3v8sd281sr0n1n9f1p66q25sa2",
|
||||
"Referer": "https://online-fix.me/",
|
||||
"Referrer-Policy": "strict-origin-when-cross-origin"
|
||||
}
|
||||
|
||||
module.exports = headers = { h1, h2 }
|
||||
12
src/utilsCrack/magnet.ts
Executable file
12
src/utilsCrack/magnet.ts
Executable file
@@ -0,0 +1,12 @@
|
||||
const fs = require('fs')
|
||||
|
||||
module.exports = magnet = (async path => {
|
||||
const parseTorrent = await import('parse-torrent')
|
||||
const parse = parseTorrent.default
|
||||
const magnetURI = parseTorrent.toMagnetURI
|
||||
|
||||
let data = await parse(fs.readFileSync(path))
|
||||
let uri = await magnetURI({ infoHash: data.infoHash })
|
||||
|
||||
return uri
|
||||
})
|
||||
13
src/utilsCrack/repo.ts
Executable file
13
src/utilsCrack/repo.ts
Executable file
@@ -0,0 +1,13 @@
|
||||
const iconv = require('iconv-lite')
|
||||
|
||||
module.exports = repo = (async (game, headers) => {
|
||||
let body = await fetch(game.link, { headers, body: null, method: "GET" })
|
||||
.then(response => response.arrayBuffer())
|
||||
.then(arrayBuffer => { return iconv.decode(Buffer.from(arrayBuffer), 'win1251') })
|
||||
.catch(console.error)
|
||||
try {
|
||||
let name = body.split('https://uploads.online-fix.me:2053/torrents/')[1].split('"')[0]
|
||||
let url = `https://uploads.online-fix.me:2053/torrents/${name}`
|
||||
return url
|
||||
} catch (error) { console.error(error) }
|
||||
})
|
||||
19
src/utilsCrack/search.ts
Executable file
19
src/utilsCrack/search.ts
Executable file
@@ -0,0 +1,19 @@
|
||||
const iconv = require('iconv-lite')
|
||||
|
||||
module.exports = search = (async (query, headers) => {
|
||||
let body = await fetch("https://online-fix.me/engine/ajax/search.php", { headers, body: `query=${query}`, method: "POST" })
|
||||
.then(response => response.arrayBuffer())
|
||||
.then(arrayBuffer => { return iconv.decode(Buffer.from(arrayBuffer), 'win1251') })
|
||||
.catch(console.error)
|
||||
try {
|
||||
let matches = body.split('</div>')[1].split('<span class="seperator fastfullsearch">')[0].split('</a>')
|
||||
let games = []
|
||||
matches.pop()
|
||||
matches.forEach(async match => {
|
||||
let name = match.split('"><span class="searchheading">')[1].split('</span>')[0].slice(0, -8)
|
||||
let link = match.split('<a href="')[1].split('"><span class="searchheading">')[0]
|
||||
games.push({ name, link })
|
||||
})
|
||||
return games
|
||||
} catch (error) { return error }
|
||||
})
|
||||
8
src/utilsCrack/torrent.ts
Executable file
8
src/utilsCrack/torrent.ts
Executable file
@@ -0,0 +1,8 @@
|
||||
module.exports = torrent = (async (url, headers) => {
|
||||
let response = await fetch(url, { headers, body: null, method: "GET" }).catch(console.error)
|
||||
try {
|
||||
let body = await response.text()
|
||||
let file = body.split('<a href="')[2].split('">')[0]
|
||||
return file
|
||||
} catch (error) { console.error(error) }
|
||||
})
|
||||
1
src/utilsPlayer/buttons.ts
Executable file
1
src/utilsPlayer/buttons.ts
Executable file
@@ -0,0 +1 @@
|
||||
export default ['loop', 'pause', 'previous', 'resume', 'shuffle', 'skip', 'stop', 'volume_down', 'volume_up']
|
||||
40
src/utilsPlayer/disco.ts
Executable file
40
src/utilsPlayer/disco.ts
Executable file
@@ -0,0 +1,40 @@
|
||||
import { Client, TextChannel } from 'discord.js'
|
||||
import { useQueue } from 'discord-player'
|
||||
import getUptime from '../utils/getUptime'
|
||||
import writeEnv from '../utils/writeEnv'
|
||||
import generate from './generate'
|
||||
|
||||
export default async (client: Client) => {
|
||||
let guild = client.guilds.cache.get(process.env.DISCORD_GUILD_ID as string)
|
||||
if (!guild) {
|
||||
clearInterval(client.disco.interval)
|
||||
console.log(`Aucun serveur trouvé avec l'id \`${process.env.DISCORD_GUILD_ID}\`, veuillez utiliser la commande \`/setchannel\` !`)
|
||||
return 'clear'
|
||||
}
|
||||
|
||||
// Keep track of the music progress if the bot reboots
|
||||
let queue = useQueue(guild.id)
|
||||
if (queue) if (queue.isPlaying()) writeEnv('DISCORD_MUSIC_CURRENT_PROGRESS', queue.node.playbackTime.toString())
|
||||
|
||||
let channel = client.channels.cache.get(process.env.DISCORD_PLAYERCHANNEL_ID as string) as TextChannel
|
||||
if (!channel) {
|
||||
clearInterval(client.disco.interval)
|
||||
console.log(`Aucun channel trouvé avec l'id \`${process.env.DISCORD_PLAYERCHANNEL_ID}\`, veuillez utiliser la commande \`/setchannel\` !`)
|
||||
return 'clear'
|
||||
}
|
||||
|
||||
let { embed, components } = await generate(guild)
|
||||
if (components && embed.data.footer) embed.setFooter({ text: `Uptime: ${getUptime(client.uptime)} \n ${embed.data.footer.text}` })
|
||||
else embed.setFooter({ text: `Uptime: ${getUptime(client.uptime)}` })
|
||||
|
||||
let messages = await channel.messages.fetch()
|
||||
messages.forEach(msg => { if (msg.member) if (!msg.author.bot && !msg.member.roles.cache.has(process.env.DISCORD_ROLE_ID as string)) msg.delete() })
|
||||
|
||||
let botMessage = messages.find(msg => client.user && msg.author.id === client.user.id)
|
||||
if (botMessage) {
|
||||
if (!components && botMessage.components.length > 0) {
|
||||
await botMessage.delete()
|
||||
return channel.send({ embeds: [embed] })
|
||||
} else if (components) return botMessage.edit({ embeds: [embed], components })
|
||||
} else return channel.send({ embeds: [embed] })
|
||||
}
|
||||
13
src/utilsPlayer/edit.ts
Executable file
13
src/utilsPlayer/edit.ts
Executable file
@@ -0,0 +1,13 @@
|
||||
import { ButtonInteraction } from 'discord.js'
|
||||
import generatePlayer from './generate'
|
||||
|
||||
export default async (interaction: ButtonInteraction) => {
|
||||
let guild = interaction.guild
|
||||
if (!guild) return await interaction.reply({ content: 'Cette commande n\'est pas disponible en message privé.', ephemeral: true })
|
||||
|
||||
let { components } = await generatePlayer(guild)
|
||||
if (!components) return
|
||||
|
||||
components.forEach((actionRow) => actionRow.components.forEach((button) => button.setDisabled(true)))
|
||||
await interaction.update({ components })
|
||||
}
|
||||
76
src/utilsPlayer/generate.ts
Executable file
76
src/utilsPlayer/generate.ts
Executable file
@@ -0,0 +1,76 @@
|
||||
import { EmbedBuilder, ButtonBuilder, ActionRowBuilder, Guild } from 'discord.js'
|
||||
import { useQueue } from 'discord-player'
|
||||
|
||||
export default async (guild: Guild) => {
|
||||
let embed = new EmbedBuilder().setColor('#ffc370')
|
||||
|
||||
let queue = useQueue(guild.id)
|
||||
if (!queue) {
|
||||
embed.setTitle('Aucune session d\'écoute en cours !')
|
||||
return ({ embed, components: null })
|
||||
}
|
||||
|
||||
let track = queue.currentTrack
|
||||
if (!track) {
|
||||
embed.setTitle('Aucune musique en cours de lecture !')
|
||||
return ({ embed, components: null })
|
||||
}
|
||||
|
||||
embed.setTitle(track.title)
|
||||
.setAuthor({ name: track.author })
|
||||
.setURL(track.url)
|
||||
.setImage(track.thumbnail)
|
||||
.addFields(
|
||||
{ name: 'Durée', value: track.duration, inline: true },
|
||||
{ name: 'Source', value: track.source === 'youtube' ? 'Youtube' : track.source === 'spotify' ? 'Spotify' : 'Inconnu', inline: true },
|
||||
{ name: 'Volume', value: `${queue.node.volume}%`, inline: true },
|
||||
{ name: queue.node.isPaused() ? 'Progression (en pause)' : 'Progression', value: queue.node.createProgressBar() || 'Aucune' },
|
||||
{ name: 'Loop', value: queue.repeatMode === 3 ? 'Autoplay' : queue.repeatMode === 2 ? 'File d\'Attente' : queue.repeatMode === 1 ? 'Titre' : 'Off', inline: true }
|
||||
)
|
||||
.setDescription(`**Musique suivante :** ${queue.tracks.data[0] ? queue.tracks.data[0].title : 'Aucune'}`)
|
||||
.setFooter({ text: `Demandé par ${track.requestedBy ? track.requestedBy.tag : 'Inconnu'}` })
|
||||
|
||||
let components = [
|
||||
new ActionRowBuilder<ButtonBuilder>().addComponents(
|
||||
new ButtonBuilder()
|
||||
.setLabel(queue.node.isPaused() ? '▶️' : '⏸️')
|
||||
.setStyle(2)
|
||||
.setCustomId(queue.node.isPaused() ? 'resume' : 'pause'),
|
||||
new ButtonBuilder()
|
||||
.setLabel('⏹️')
|
||||
.setStyle(2)
|
||||
.setCustomId('stop'),
|
||||
new ButtonBuilder()
|
||||
.setLabel('⏭️')
|
||||
.setStyle(2)
|
||||
.setCustomId('skip')
|
||||
.setDisabled(queue.tracks.data.length !== 0),
|
||||
new ButtonBuilder()
|
||||
.setLabel('🔉')
|
||||
.setStyle(2)
|
||||
.setCustomId('volume_down')
|
||||
.setDisabled(queue.node.volume === 0),
|
||||
new ButtonBuilder()
|
||||
.setLabel('🔊')
|
||||
.setStyle(2)
|
||||
.setCustomId('volume_up')
|
||||
.setDisabled(queue.node.volume === 100)
|
||||
),
|
||||
new ActionRowBuilder<ButtonBuilder>().addComponents(
|
||||
new ButtonBuilder()
|
||||
.setLabel('🔀')
|
||||
.setStyle(2)
|
||||
.setCustomId('shuffle'),
|
||||
new ButtonBuilder()
|
||||
.setLabel('🔁')
|
||||
.setStyle(2)
|
||||
.setCustomId('loop'),
|
||||
new ButtonBuilder()
|
||||
.setLabel('⏮️')
|
||||
.setStyle(2)
|
||||
.setCustomId('previous')
|
||||
.setDisabled(queue.history.previousTrack ? false : true)
|
||||
)
|
||||
]
|
||||
return ({ embed, components })
|
||||
}
|
||||
24
src/utilsPlayer/metadata.ts
Normal file
24
src/utilsPlayer/metadata.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { CommandInteraction, Guild, GuildChannel, TextBasedChannel, VoiceChannel } from 'discord.js'
|
||||
|
||||
type ChannelInferrable = {
|
||||
channel: TextBasedChannel | VoiceChannel
|
||||
guild?: Guild
|
||||
}
|
||||
|
||||
export class PlayerMetadata {
|
||||
public constructor(public data: ChannelInferrable) {
|
||||
if (data.channel.isDMBased()) { throw new Error('PlayerMetadata cannot be created from a DM') }
|
||||
if (!data.channel) { throw new Error('PlayerMetadata can only be created from a channel') }
|
||||
}
|
||||
public get channel() { return this.data.channel! }
|
||||
public get guild() { return this.data.guild || (this.data.channel as GuildChannel).guild }
|
||||
|
||||
public static create(data: ChannelInferrable | CommandInteraction) {
|
||||
if (data instanceof CommandInteraction) {
|
||||
if (!data.inGuild()) { throw new Error('PlayerMetadata cannot be created from a DM') }
|
||||
|
||||
return new PlayerMetadata({ channel: data.channel!, guild: data.guild! })
|
||||
}
|
||||
return new PlayerMetadata(data);
|
||||
}
|
||||
}
|
||||
42
src/utilsPlayer/replay.ts
Executable file
42
src/utilsPlayer/replay.ts
Executable file
@@ -0,0 +1,42 @@
|
||||
import { Client, TextChannel, VoiceChannel } from 'discord.js'
|
||||
import { useMainPlayer } from 'discord-player'
|
||||
|
||||
export default async (client: Client) => {
|
||||
let textChannel = client.channels.cache.get(process.env.DISCORD_MUSIC_TEXTCHANNEL_ID as string) as TextChannel
|
||||
if (!textChannel) return console.log(`Aucun channel trouvé avec l'id \`${process.env.DISCORD_MUSIC_TEXTCHANNEL_ID}\`, veuillez utiliser la commande \`/setchannel\` !`)
|
||||
let voiceChannel = client.channels.cache.get(process.env.DISCORD_MUSIC_VOICECHANNEL_ID as string) as VoiceChannel
|
||||
if (!voiceChannel) return console.log(`Aucun channel trouvé avec l'id \`${process.env.DISCORD_MUSIC_VOICECHANNEL_ID}\`, veuillez utiliser la commande \`/setchannel\` !`)
|
||||
|
||||
let player = useMainPlayer()
|
||||
let queue = player.nodes.create(textChannel.guild, {
|
||||
metadata: {
|
||||
channel: textChannel,
|
||||
client: textChannel.guild.members.me,
|
||||
requestedBy: client.user
|
||||
},
|
||||
selfDeaf: true,
|
||||
volume: 20,
|
||||
leaveOnEmpty: true,
|
||||
leaveOnEmptyCooldown: 30000,
|
||||
leaveOnEnd: true,
|
||||
leaveOnEndCooldown: 300000
|
||||
})
|
||||
|
||||
try { if (!queue.connection) await queue.connect(voiceChannel) }
|
||||
catch (error: any) { console.error(error); await textChannel.send(`Y'a eu un problème, <@223831938346123275> ! (${error.message})`) }
|
||||
|
||||
let result = await player.search(process.env.DISCORD_MUSIC_CURRENT_TRACK as string, { requestedBy: client.user || undefined })
|
||||
if (!result.hasTracks()) await textChannel.send(`Aucune musique trouvée pour **${process.env.DISCORD_MUSIC_CURRENT_TRACK}** !`)
|
||||
let track = result.tracks[0]
|
||||
|
||||
let entry = queue.tasksQueue.acquire()
|
||||
await entry.getTask()
|
||||
queue.addTrack(track)
|
||||
|
||||
try {
|
||||
await queue.node.play()
|
||||
await queue.node.seek(Number(process.env.DISCORD_MUSIC_CURRENT_PROGRESS))
|
||||
await textChannel.send(`Relancement de la musique suite à mon redémarrage...`)
|
||||
} catch (error: any) { console.error(error); await textChannel.send(`Y'a eu un problème, <@223831938346123275> ! (${error.message})`) }
|
||||
finally { queue.tasksQueue.release() }
|
||||
}
|
||||
Reference in New Issue
Block a user