Réécriture complète 4.0
Some checks failed
Build and Push Docker Image / build-and-push (push) Failing after 6m16s
Some checks failed
Build and Push Docker Image / build-and-push (push) Failing after 6m16s
This commit is contained in:
@@ -1,58 +1,70 @@
|
||||
import { SlashCommandBuilder, EmbedBuilder, ChatInputCommandInteraction, MessageReaction, User }from 'discord.js'
|
||||
import * as crack from '../../utils/crack'
|
||||
|
||||
export default {
|
||||
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 = (reaction: MessageReaction, user: User) => { if (reaction.emoji.name) { return emojis.includes(reaction.emoji.name) && user.id === interaction.user.id } return false }
|
||||
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] })
|
||||
}
|
||||
}
|
||||
import { SlashCommandBuilder, EmbedBuilder, MessageFlags } from "discord.js"
|
||||
import type { ChatInputCommandInteraction, MessageReaction, User } from "discord.js"
|
||||
import { search, repo, torrent, download, magnet } from "@/utils/crack"
|
||||
import type { CrackGame } from "@/types"
|
||||
import { t } from "@/utils/i18n"
|
||||
|
||||
export const data = new SlashCommandBuilder()
|
||||
.setName("crack")
|
||||
.setDescription("Download a crack from online-fix.me")
|
||||
.setDescriptionLocalizations({ fr: "Télécharge un crack sur online-fix.me" })
|
||||
.addStringOption(option => option
|
||||
.setName("game")
|
||||
.setDescription("What game do you want to download?")
|
||||
.setNameLocalizations({ fr: "jeu" })
|
||||
.setDescriptionLocalizations({ fr: "Quel jeu tu veux télécharger ?" })
|
||||
.setRequired(true)
|
||||
)
|
||||
|
||||
export async function execute(interaction: ChatInputCommandInteraction) {
|
||||
await interaction.deferReply()
|
||||
|
||||
const query = interaction.options.getString("game", true)
|
||||
let games = await search(query)
|
||||
if (!Array.isArray(games)) return interaction.followUp({ content: t(interaction.locale, "salonpostam.crack.no_games_found", { query }), flags: MessageFlags.Ephemeral })
|
||||
|
||||
let game = {} as CrackGame
|
||||
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})`
|
||||
const message = await interaction.followUp({ content: t(interaction.locale, "salonpostam.crack.multiple_games_found", { query, list }) })
|
||||
|
||||
const 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 = (reaction: MessageReaction, user: User) => {
|
||||
if (reaction.emoji.name) return (emojis.includes(reaction.emoji.name) && user.id === interaction.user.id)
|
||||
return false
|
||||
}
|
||||
await message.awaitReactions({ filter, max: 1, time: 5000, errors: ["time"] }).then(collected => {
|
||||
console.log(collected)
|
||||
const reaction = collected.first()
|
||||
const index = emojis.indexOf(reaction?.emoji.name ?? "")
|
||||
|
||||
if (!games) return
|
||||
game = games[index]
|
||||
})
|
||||
.catch(() => { return interaction.followUp({ content: t(interaction.locale, "salonpostam.crack.selection_timeout"), flags: MessageFlags.Ephemeral }) })
|
||||
} else game = games[0]
|
||||
|
||||
const url = await repo(game)
|
||||
if (!url) return
|
||||
|
||||
const file = await torrent(url)
|
||||
if (!file) return
|
||||
|
||||
const filePath = await download(url, file)
|
||||
if (!filePath) return
|
||||
|
||||
const link = magnet(filePath)
|
||||
const embed = new EmbedBuilder()
|
||||
.setColor("#ffc370")
|
||||
.setTitle(game.name)
|
||||
.setURL(game.link)
|
||||
.setDescription(t(interaction.locale, "salonpostam.crack.game_found", { query, link: `https://angels-dev.fr/magnet/${link}` }))
|
||||
|
||||
await interaction.followUp({ embeds: [embed], files: [filePath] })
|
||||
}
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
import { SlashCommandBuilder, ChatInputCommandInteraction, EmbedBuilder, Message, inlineCode } from 'discord.js'
|
||||
import * as Freebox from '../../utils/freebox'
|
||||
import dbGuild from '../../schemas/guild'
|
||||
import crypto from 'crypto'
|
||||
import https from 'https'
|
||||
//import path from 'path'
|
||||
//import fs from 'fs'
|
||||
|
||||
interface ReturnMsgData {
|
||||
status: string
|
||||
error_code?: string
|
||||
Title?: string
|
||||
Message?: string
|
||||
}
|
||||
|
||||
function returnMsg(result: ReturnMsgData) {
|
||||
if (result.status === 'fail') return `La commande a échouée !\n${inlineCode(`${result.Title}: ${result.Message}`)}`
|
||||
if (result.status === 'error') return `Y'a eu une erreur !\n${inlineCode(`${result.error_code}`)}`
|
||||
}
|
||||
|
||||
export default {
|
||||
data: new SlashCommandBuilder().setName('freebox').setDescription("Accéder à l'API FreeboxOS !")
|
||||
.addSubcommand(subcommand => subcommand.setName('import').setDescription("Envoyer un fichier d'autorité de certification."))
|
||||
.addSubcommand(subcommand => subcommand.setName('version').setDescription("Afficher la version de l'API."))
|
||||
.addSubcommand(subcommand => subcommand.setName('init').setDescription("Créer une app sur la Freebox pour s'authentifier."))
|
||||
.addSubcommandGroup(subcommandGroup => subcommandGroup.setName('get').setDescription('Récupérer des données.')
|
||||
.addSubcommand(subcommand => subcommand.setName('connection').setDescription('Récupérer les informations de connexion.'))
|
||||
),
|
||||
|
||||
async execute(interaction: ChatInputCommandInteraction) {
|
||||
let guildProfile = await dbGuild.findOne({ guildId: interaction?.guild?.id })
|
||||
if (!guildProfile) return interaction.reply({ content: `Database data for **${interaction.guild?.name}** does not exist, please initialize with \`/database init\` !` })
|
||||
|
||||
let dbData = guildProfile.get('guildFbx')
|
||||
if (!dbData?.enabled) return interaction.reply({ content: `Freebox module is disabled for **${interaction.guild?.name}**, please activate with \`/database edit guildFbx.enabled True\` !` })
|
||||
|
||||
let host = dbData.host as string
|
||||
if (!host) return interaction.reply({ content: `Freebox host is not set for **${interaction.guild?.name}**, please set with \`/database edit guildFbx.host <host>\` !` })
|
||||
let version = dbData.version as number
|
||||
if (!version) return interaction.reply({ content: `Freebox API version is not set for **${interaction.guild?.name}**, please set with \`/database edit guildFbx.version <version>\` !` })
|
||||
|
||||
let httpsOptions = {}
|
||||
//let caCrt = fs.readFileSync(path.resolve(__dirname, '../../static/freebox-ecc-root-ca.crt'))
|
||||
// MIME Type : application/x-x509-ca-cert
|
||||
//if (caCrt) httpsOptions = { ca: caCrt }
|
||||
let httpsAgent = new https.Agent(httpsOptions)
|
||||
|
||||
|
||||
if (interaction.options.getSubcommand() === 'import') {
|
||||
let filter = (m: Message) => m.author.id === interaction.user.id
|
||||
|
||||
await interaction.reply({ content: 'Please send another message with the CA file attached, you have one minute.', fetchReply: true }).then(async () => {
|
||||
console.log('waiting for message')
|
||||
await interaction.channel?.awaitMessages({ filter, time: 60_000, errors: ['time'] }).then(async collected => {
|
||||
console.log(collected)
|
||||
let message = collected.first()
|
||||
if (!message?.attachments.size) return interaction.followUp('No file was sent in your message!')
|
||||
|
||||
let attachment = message.attachments.first()
|
||||
console.log(attachment)
|
||||
|
||||
// Save the file to the database // TODO
|
||||
|
||||
interaction.followUp(`File saved, you can now interact with your Freebox!`)
|
||||
}).catch(() => interaction.followUp('No message was sent before the time limit!'))
|
||||
})
|
||||
}
|
||||
else if (interaction.options.getSubcommand() === 'version') {
|
||||
let result = await Freebox.Core.Version(host, httpsAgent)
|
||||
if (result.status === 'success') {
|
||||
let embed = new EmbedBuilder()
|
||||
embed.setTitle('FreeboxOS API Version')
|
||||
embed.setDescription(`Version: ${result.data.api_version}`)
|
||||
return await interaction.reply({ embeds: [embed] })
|
||||
}
|
||||
else if (result.status === 'fail') return await interaction.reply({ content: `Failed to retrieve the API version: ${result.data}`, ephemeral: true })
|
||||
else if (result.status === 'error') return await interaction.reply({ content: `An error occurred while retrieving the API version: ${result.data}`, ephemeral: true })
|
||||
}
|
||||
else if (interaction.options.getSubcommand() === 'init') {
|
||||
await interaction.deferReply({ ephemeral: true })
|
||||
|
||||
let app = {
|
||||
app_id: 'fr.angels.bot_tamiseur',
|
||||
app_name: 'Bot Tamiseur',
|
||||
app_version: '2.3.0',
|
||||
device_name: 'Bot Discord NodeJS'
|
||||
}
|
||||
let result = await Freebox.Core.Init(host, version, httpsAgent, app, '')
|
||||
if (result.status === 'success') {
|
||||
let appToken = result.data.app_token
|
||||
let trackId = result.data.track_id
|
||||
|
||||
let initCheck = setInterval(async () => {
|
||||
let result = await Freebox.Core.Init(host, version, httpsAgent, app, trackId)
|
||||
if (result.status !== 'success') return await interaction.followUp(returnMsg(result) as string)
|
||||
|
||||
let status = result.data.status
|
||||
if (status === 'granted') {
|
||||
clearInterval(initCheck)
|
||||
let password_salt = result.data.password_salt
|
||||
|
||||
if (!dbData) return
|
||||
dbData['appToken'] = appToken
|
||||
dbData['password_salt'] = password_salt
|
||||
|
||||
if (!guildProfile) return
|
||||
guildProfile.set('guildFbx', dbData)
|
||||
guildProfile.markModified('guildFbx')
|
||||
await guildProfile.save().catch(console.error)
|
||||
|
||||
return await interaction.followUp('Done !')
|
||||
}
|
||||
else if (status === 'denied') {
|
||||
clearInterval(initCheck)
|
||||
return await interaction.followUp('The user denied the app access to the Freebox.')
|
||||
}
|
||||
else if (status === 'pending') return
|
||||
}, 2000)
|
||||
} else return await interaction.followUp({ content: returnMsg(result) as string, ephemeral: true })
|
||||
}
|
||||
else if (interaction.options.getSubcommandGroup() === 'get') {
|
||||
let appToken = dbData.appToken as string
|
||||
if (!appToken) return await interaction.reply({ content: `Freebox appToken is not set for **${interaction.guild?.name}**, please init the app with \`/freebox init\` !` })
|
||||
console.log(appToken)
|
||||
|
||||
let challengeData = await Freebox.Login.Challenge(host, version, httpsAgent)
|
||||
if (!challengeData) return await interaction.reply({ content: `Failed to retrieve the challenge for **${interaction.guild?.name}** !` })
|
||||
let challenge = challengeData.data.challenge
|
||||
console.log(challenge)
|
||||
|
||||
let password = crypto.createHmac('sha1', appToken).update(challenge).digest('hex')
|
||||
console.log(password)
|
||||
|
||||
let session = await Freebox.Login.Session(host, version, httpsAgent, 'fr.angels.bot_tamiseur', password)
|
||||
if (!session) return await interaction.reply({ content: `Failed to retrieve the session for **${interaction.guild?.name}** !` })
|
||||
|
||||
let sessionToken = dbData['sessionToken'] = session.data.session_token
|
||||
|
||||
guildProfile.set('guildFbx', dbData)
|
||||
guildProfile.markModified('guildFbx')
|
||||
await guildProfile.save().catch(console.error)
|
||||
|
||||
if (interaction.options.getSubcommand() === 'connection') {
|
||||
let connection = await Freebox.Get.Connection(host, version, httpsAgent, sessionToken)
|
||||
if (!connection) return await interaction.reply({ content: `Failed to retrieve the connection details for **${interaction.guild?.name}** !` })
|
||||
|
||||
return await interaction.reply({ content: `Connection details for **${interaction.guild?.name}**:\n${inlineCode(JSON.stringify(connection))}` })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
15
src/commands/salonpostam/index.ts
Normal file
15
src/commands/salonpostam/index.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import * as crack from "./crack"
|
||||
import * as papa from "./papa"
|
||||
import * as parle from "./parle"
|
||||
import * as spam from "./spam"
|
||||
import * as update from "./update"
|
||||
|
||||
import type { Command } from "@/types"
|
||||
|
||||
export default [
|
||||
crack,
|
||||
papa,
|
||||
parle,
|
||||
spam,
|
||||
update
|
||||
] as Command[]
|
||||
@@ -1,34 +1,34 @@
|
||||
import { SlashCommandBuilder, ChatInputCommandInteraction, GuildMember } from 'discord.js'
|
||||
import { getVoiceConnection, joinVoiceChannel } from '@discordjs/voice'
|
||||
|
||||
export default {
|
||||
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 !' })
|
||||
}
|
||||
}
|
||||
import { SlashCommandBuilder } from "discord.js"
|
||||
import type { ChatInputCommandInteraction, GuildMember } from "discord.js"
|
||||
import { getVoiceConnection, joinVoiceChannel } from "@discordjs/voice"
|
||||
import { t } from "@/utils/i18n"
|
||||
|
||||
export const data = new SlashCommandBuilder()
|
||||
.setName("papa")
|
||||
.setDescription("If daddy calls me, I join him")
|
||||
.setDescriptionLocalizations({ fr: "Si papa m'appelle, je le rejoins" })
|
||||
|
||||
export async function execute(interaction: ChatInputCommandInteraction) {
|
||||
if (interaction.user.id !== "223831938346123275") return interaction.reply({ content: t(interaction.locale, "salonpostam.papa.not_your_father") })
|
||||
|
||||
const guild = interaction.guild
|
||||
if (!guild) return interaction.reply({ content: t(interaction.locale, "salonpostam.papa.no_dm") })
|
||||
|
||||
const member = interaction.member as GuildMember
|
||||
|
||||
const botChannel = guild.members.me?.voice.channel
|
||||
const papaChannel = member.voice.channel
|
||||
|
||||
if (!papaChannel && botChannel) {
|
||||
const voiceConnection = getVoiceConnection(guild.id)
|
||||
if (voiceConnection) voiceConnection.destroy()
|
||||
return interaction.reply({ content: t(interaction.locale, "salonpostam.papa.leaving_voice") })
|
||||
} else if (papaChannel && (!botChannel || botChannel.id !== papaChannel.id)) {
|
||||
joinVoiceChannel({
|
||||
channelId: papaChannel.id,
|
||||
guildId: papaChannel.guild.id,
|
||||
adapterCreator: papaChannel.guild.voiceAdapterCreator,
|
||||
})
|
||||
return interaction.reply({ content: t(interaction.locale, "salonpostam.papa.joining_voice") })
|
||||
} else return interaction.reply({ content: t(interaction.locale, "salonpostam.papa.already_connected") })
|
||||
}
|
||||
|
||||
@@ -1,79 +1,84 @@
|
||||
import { SlashCommandBuilder, ChatInputCommandInteraction, GuildMember } from 'discord.js'
|
||||
import { joinVoiceChannel, createAudioPlayer, createAudioResource, AudioPlayerStatus, EndBehaviorType } from '@discordjs/voice'
|
||||
|
||||
export default {
|
||||
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', () => {
|
||||
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()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
import { SlashCommandBuilder, MessageFlags } from "discord.js"
|
||||
import type { ChatInputCommandInteraction, GuildMember } from "discord.js"
|
||||
import { joinVoiceChannel, createAudioPlayer, createAudioResource, AudioPlayerStatus, EndBehaviorType } from "@discordjs/voice"
|
||||
import { t } from "@/utils/i18n"
|
||||
|
||||
export const data = new SlashCommandBuilder()
|
||||
.setName("speak")
|
||||
.setDescription("Make me talk over someone annoying in voice chat")
|
||||
.setNameLocalizations({ fr: "parle" })
|
||||
.setDescriptionLocalizations({ fr: "Fais moi parler par dessus quelqu'un d'ennuyant dans le vocal" })
|
||||
.addUserOption(option => option
|
||||
.setName("user")
|
||||
.setDescription("The person in question")
|
||||
.setNameLocalizations({ fr: "utilisateur" })
|
||||
.setDescriptionLocalizations({ fr: "La personne en question" })
|
||||
.setRequired(true)
|
||||
)
|
||||
|
||||
export async function execute(interaction: ChatInputCommandInteraction) {
|
||||
const guild = interaction.guild
|
||||
if (!guild) return
|
||||
|
||||
const user = interaction.options.getUser("user", true)
|
||||
const member = await guild.members.fetch(user.id)
|
||||
const caller = interaction.member as GuildMember
|
||||
|
||||
if (!caller.voice.channel) return interaction.reply({ content: t(interaction.locale, "salonpostam.parle.not_in_voice"), flags: MessageFlags.Ephemeral })
|
||||
if (!member.voice.channel) return interaction.reply({ content: t(interaction.locale, "salonpostam.parle.member_not_in_voice"), flags: MessageFlags.Ephemeral })
|
||||
if (caller.voice.channelId !== member.voice.channelId) return interaction.reply({ content: t(interaction.locale, "salonpostam.parle.not_same_channel"), flags: MessageFlags.Ephemeral })
|
||||
|
||||
await interaction.reply({ content: t(interaction.locale, "salonpostam.parle.will_speak_over"), flags: MessageFlags.Ephemeral })
|
||||
|
||||
/*
|
||||
// Searches for audio files uploaded in the channel
|
||||
const messages = await interaction.channel.messages.fetch({ limit: 10, cache: false }).filter(m => m.attachments.size > 0)
|
||||
|
||||
const files = []
|
||||
await messages.forEach(m => m.attachments.forEach(a => {
|
||||
if (a.contentType === 'audio/mpeg') files.push(a)
|
||||
}))
|
||||
if (files.size === 0) return interaction.editReply({ content: t(interaction.locale, "player.no_audio_found"), flags: MessageFlags.Ephemeral })
|
||||
|
||||
// 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 })
|
||||
const filter = m => m.author.id === interaction.user.id && !isNaN(m.content) && parseInt(m.content) > 0 && parseInt(m.content) <= files.size
|
||||
const response = await interaction.channel.awaitMessages({ filter, max: 1, time: 30000, errors: ['time'] })
|
||||
file = files.get(files.keyArray()[response.first().content - 1])
|
||||
*/
|
||||
|
||||
let playing = false
|
||||
const player = createAudioPlayer()
|
||||
player.on(AudioPlayerStatus.Idle, () => { playing = false })
|
||||
|
||||
const connection = joinVoiceChannel({
|
||||
channelId: caller.voice.channelId ?? "",
|
||||
guildId: interaction.guildId ?? "",
|
||||
adapterCreator: guild.voiceAdapterCreator,
|
||||
selfDeaf: false
|
||||
})
|
||||
connection.subscribe(player)
|
||||
|
||||
const stream = connection.receiver.subscribe(user.id, {
|
||||
end: { behavior: EndBehaviorType.Manual }
|
||||
})
|
||||
stream.on("data", () => {
|
||||
if (connection.receiver.speaking.users.has(user.id) && !playing) {
|
||||
playing = true
|
||||
const resource = createAudioResource("@/static/parle.mp3", { inlineVolume: true })
|
||||
//const 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()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,29 +1,47 @@
|
||||
import { SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js'
|
||||
|
||||
export default {
|
||||
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()
|
||||
}
|
||||
}
|
||||
import { SlashCommandBuilder, MessageFlags } from "discord.js"
|
||||
import type { ChatInputCommandInteraction } from "discord.js"
|
||||
import { t } from "@/utils/i18n"
|
||||
|
||||
export const data = new SlashCommandBuilder()
|
||||
.setName("spam")
|
||||
.setDescription("Spam a user with a message")
|
||||
.setDescriptionLocalizations({ fr: "Spammer un utilisateur avec un message" })
|
||||
.addUserOption(option => option
|
||||
.setName("user")
|
||||
.setDescription("Target user")
|
||||
.setNameLocalizations({ fr: "utilisateur" })
|
||||
.setDescriptionLocalizations({ fr: "Utilisateur cible" })
|
||||
.setRequired(true)
|
||||
)
|
||||
.addStringOption(option => option
|
||||
.setName("message")
|
||||
.setDescription("Message to spam")
|
||||
.setDescriptionLocalizations({ fr: "Message à spammer" })
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption(option => option
|
||||
.setName("count")
|
||||
.setDescription("Number of times to spam")
|
||||
.setNameLocalizations({ fr: "nombre" })
|
||||
.setDescriptionLocalizations({ fr: "Nombre de fois à spammer" })
|
||||
.setRequired(true)
|
||||
.setMinValue(1)
|
||||
.setMaxValue(100)
|
||||
)
|
||||
|
||||
export async function execute(interaction: ChatInputCommandInteraction) {
|
||||
const user = interaction.options.getUser("user", true)
|
||||
const string = interaction.options.getString("message", true)
|
||||
const integer = interaction.options.getInteger("count", true)
|
||||
|
||||
await interaction.reply({ content: t(interaction.locale, "salonpostam.spam.started"), flags: MessageFlags.Ephemeral })
|
||||
let i = 0
|
||||
function myLoop() {
|
||||
setTimeout(() => {
|
||||
user.send(string).catch(console.error)
|
||||
i++
|
||||
if (i < integer) myLoop()
|
||||
}, 1000)
|
||||
}
|
||||
myLoop()
|
||||
}
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
import { SlashCommandBuilder, ChatInputCommandInteraction, Guild } from 'discord.js'
|
||||
|
||||
export default {
|
||||
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(() => {
|
||||
let 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)
|
||||
}
|
||||
}
|
||||
import { SlashCommandBuilder, MessageFlags } from "discord.js"
|
||||
import type { ChatInputCommandInteraction } from "discord.js"
|
||||
import { t } from "@/utils/i18n"
|
||||
|
||||
export const data = new SlashCommandBuilder()
|
||||
.setName("update")
|
||||
.setDescription("Update the member count channel")
|
||||
.setDescriptionLocalizations({ fr: "Mettre à jour le canal de nombre de membres" })
|
||||
|
||||
export async function execute(interaction: ChatInputCommandInteraction) {
|
||||
const guild = interaction.guild
|
||||
if (!guild) return interaction.reply({ content: t(interaction.locale, "common.command_server_only"), flags: MessageFlags.Ephemeral })
|
||||
|
||||
guild.members.fetch().then(async () => {
|
||||
let i = 0
|
||||
guild.members.cache.forEach(member => { if (!member.user.bot) i++ })
|
||||
const channel = guild.channels.cache.get("1091140609139560508")
|
||||
if (!channel) return
|
||||
await channel.setName(`${i} Gens Posés`)
|
||||
return interaction.reply(t(interaction.locale, "salonpostam.update.members_updated", { count: i }))
|
||||
}).catch(console.error)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user