Création Repo pour mon bot Le Tamiseur

This commit is contained in:
Zachary Guénot
2023-04-23 19:30:04 +02:00
commit a879b38c3e
50 changed files with 7159 additions and 0 deletions

9
.eslintrc.json Normal file
View File

@@ -0,0 +1,9 @@
{
"parserOptions": {
"ecmaVersion": "latest"
},
"env": {
"es6": true
}
}

63
.gitattributes vendored Normal file
View File

@@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

370
.gitignore vendored Normal file
View File

@@ -0,0 +1,370 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Oo]ut/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
history.txt
test.js
.env
/.vs/Topos/
/public/css/
/public/download/

167
.npmrc Executable file
View File

@@ -0,0 +1,167 @@
;;;;
; npm projectconfig file: C:\Users\Zachary\source\repos\Discord\.npmrc
; this is a simple ini-formatted file
; lines that start with semi-colons are comments
; run `npm help 7 config` for documentation of the various options
;
; Configs like `@scope:registry` map a scope to a given registry url.
;
; Configs like `//<hostname>/:_authToken` are auth that is restricted
; to the registry host specified.
;;;;
; all available options shown below with default values
;;;;
; _auth=null
; access=null
; all=false
; allow-same-version=false
; also=null
; audit=true
; audit-level=null
; auth-type=web
; before=null
; bin-links=true
; browser=null
; ca=null
; cache=C:\Users\Zachary\AppData\Local/npm-cache
; cache-max=null
; cache-min=0
; cafile=null
; call=
; cert=null
; ci-name=null
; cidr=null
; color=true
; commit-hooks=true
; depth=null
; description=true
; dev=false
;
; diff-ignore-all-space=false
; diff-name-only=false
; diff-no-prefix=false
; diff-dst-prefix=b/
; diff-src-prefix=a/
; diff-text=false
; diff-unified=3
; dry-run=false
; editor=C:\Windows\notepad.exe
; engine-strict=false
; fetch-retries=2
; fetch-retry-factor=10
; fetch-retry-maxtimeout=60000
; fetch-retry-mintimeout=10000
; fetch-timeout=300000
; force=false
; foreground-scripts=false
; format-package-lock=true
; fund=true
; git=git
; git-tag-version=true
; global=false
; globalconfig=
; global-style=false
; heading=npm
; https-proxy=null
; if-present=false
; ignore-scripts=false
;
; include-staged=false
; include-workspace-root=false
; init-author-email=
; init-author-name=
; init-author-url=
; init-license=ISC
; init-module=~/.npm-init.js
; init-version=1.0.0
; init.author.email=
; init.author.name=
; init.author.url=
; init.license=ISC
; init.module=~/.npm-init.js
; init.version=1.0.0
; install-links=true
; install-strategy=hoisted
; json=false
; key=null
; legacy-bundling=false
; legacy-peer-deps=false
; link=false
; local-address=null
; location=user
; lockfile-version=null
; loglevel=notice
; logs-dir=null
; logs-max=10
; long=false
; maxsockets=15
; message=%s
; node-options=null
; noproxy=
; offline=false
;
; omit-lockfile-registry-resolved=false
; only=null
; optional=null
; otp=null
;
; package-lock=true
; package-lock-only=false
; pack-destination=.
; parseable=false
; prefer-offline=false
; prefer-online=false
; prefix=
; preid=
; production=null
; progress=true
; proxy=null
; read-only=false
; rebuild-bundle=true
; registry=https://registry.npmjs.org/
; replace-registry-host=npmjs
; save=true
; save-bundle=false
; save-dev=false
; save-exact=false
; save-optional=false
; save-peer=false
; save-prefix=^
; save-prod=false
; scope=
; script-shell=null
; searchexclude=
; searchlimit=20
; searchopts=
; searchstaleness=900
; shell=C:\Windows\system32\cmd.exe
; shrinkwrap=true
; sign-git-commit=false
; sign-git-tag=false
; strict-peer-deps=false
; strict-ssl=true
; tag=latest
; tag-version-prefix=v
; timing=false
; tmp=C:\Users\Zachary\AppData\Local\Temp
; umask=0
; unicode=false
; update-notifier=true
; usage=false
; user-agent=npm/{npm-version} node/{node-version} {platform} {arch} workspaces/{workspaces} {ci}
; userconfig=~/.npmrc
; version=false
; versions=false
; viewer=browser
; which=null
;
; workspaces=null
; workspaces-update=true
; yes=null
msvs_version=2022

26
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,26 @@
{
// Utilisez IntelliSense pour en savoir plus sur les attributs possibles.
// Pointez pour afficher la description des attributs existants.
// Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch",
"program": "${workspaceFolder}/app.js",
"skipFiles": ["<node_internals>/**"]
},
{
"type": "node",
"request": "launch",
"name": "Nodemon",
"program": "${workspaceFolder}/app.js",
"skipFiles": ["<node_internals>/**"],
"runtimeExecutable": "nodemon",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"restart": true
}
]
}

3
README.md Executable file
View File

@@ -0,0 +1,3 @@
# Discord

56
Tamiseur.njsproj Executable file
View File

@@ -0,0 +1,56 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<Name>Tamiseur</Name>
<RootNamespace>Tamiseur</RootNamespace>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>622ae81e-ec50-404b-93cc-b651fb21151e</ProjectGuid>
<ProjectHome>.</ProjectHome>
<StartupFile>app.js</StartupFile>
<StartWebBrowser>False</StartWebBrowser>
<SearchPath>
</SearchPath>
<WorkingDirectory>.</WorkingDirectory>
<OutputPath>.</OutputPath>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<ProjectTypeGuids>{3AF33F2E-1136-4D97-BBB7-1795711AC8B8};{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}</ProjectTypeGuids>
<StartWebBrowser>false</StartWebBrowser>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Content Include=".env" />
<Content Include=".npmrc" />
<Content Include="app.js" />
<Content Include="commands\update.js" />
<Content Include="commands\spam.js" />
<Content Include="commands\ping.js" />
<Content Include="commands\resume.js" />
<Content Include="commands\skip.js" />
<Content Include="commands\stop.js" />
<Content Include="commands\pause.js" />
<Content Include="commands\play.js" />
<Content Include="events\voiceStateUpdate.js" />
<Content Include="events\guildMemberRemove.js" />
<Content Include="events\guildMemberAdd.js" />
<Content Include="events\interactionCreate.js" />
<Content Include="events\ready.js" />
<Content Include="package.json" />
<Content Include="README.md" />
<Content Include="stronger_shorter.mp3" />
</ItemGroup>
<ItemGroup>
<Folder Include="commands\" />
<Folder Include="events\" />
</ItemGroup>
<Import Project="$(VSToolsPath)\Node.js Tools\Microsoft.NodejsToolsV2.targets" />
</Project>

25
Tamiseur.sln Executable file
View File

@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.4.33122.133
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}") = "Tamiseur", "Tamiseur.njsproj", "{622AE81E-EC50-404B-93CC-B651FB21151E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{622AE81E-EC50-404B-93CC-B651FB21151E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{622AE81E-EC50-404B-93CC-B651FB21151E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{622AE81E-EC50-404B-93CC-B651FB21151E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{622AE81E-EC50-404B-93CC-B651FB21151E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8F37C3A1-5B9D-413A-9661-15680F2A8EEA}
EndGlobalSection
EndGlobal

74
app.js Executable file
View File

@@ -0,0 +1,74 @@
// PACKAGES AND VARIABLES
const fs = require('fs')
const { Client, Collection, GatewayIntentBits, REST, Routes } = require('discord.js')
const { Player } = require("discord-player")
const { YouTubeExtractor, SpotifyExtractor } = require("@discord-player/extractor")
require('dotenv').config()
let intents = [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildVoiceStates]
const client = new Client({ intents })
// EVENTS HANDLING
const eventFiles = fs.readdirSync('./events').filter(file => file.endsWith('.js'))
for (const file of eventFiles) {
let event = require(`./events/${file}`)
if (event.once) client.once(event.name, (...args) => {
//console.log(`\u001b[1;35m Event '${event.name}' executed.`)
event.execute(...args)
})
else client.on(event.name, (...args) => {
//console.log(`\u001b[1;35m Event '${event.name}' executed.`)
event.execute(...args)
})
}
// COMMANDS HANDLING
client.commands = new Collection()
let commands = []
let commandFolders = fs.readdirSync('./commands')
for (folder of commandFolders) {
let folderPath = `./commands/${folder}`
let commandFiles = fs.readdirSync(folderPath).filter(file => file.endsWith('.js'))
for (file of commandFiles) {
let command = require(`${folderPath}/${file}`)
if ('data' in command && 'execute' in command) { commands.push(command.data.toJSON()); client.commands.set(command.data.name, command) }
else console.log(`\u001b[1;35m [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);
(async () => {
//console.log(`\u001b[1;35m Started refreshing ${commands.length} application (/) commands.`)
try {
let data = await rest.put(Routes.applicationCommands('1065047326860783636'), { body: commands })
//console.log(`\u001b[1;35m Successfully reloaded ${data.length} application (/) commands.`)
}
catch (error) { console.error(error) }
})()
// BUTTONS HANDLING
client.buttons = new Collection()
let buttonFiles = fs.readdirSync('./buttons').filter(file => file.endsWith('.js'))
for (const file of buttonFiles) {
let button = require(`./buttons/${file}`)
if ('id' in button && 'execute' in button) client.buttons.set(button.id, button)
else console.log(`\u001b[1;35m [WARNING] The button ${file} is missing a required "id" or "execute" property.`)
}
// PLAYER INITIALIZATION
const player = new Player(client, { autoRegisterExtractor: false })
player.extractors.register(YouTubeExtractor)
player.extractors.register(SpotifyExtractor)
// PLAYER EVENTS HANDLING
const eventPlayerFiles = fs.readdirSync('./eventsPlayer').filter(file => file.endsWith('.js'))
for (const file of eventPlayerFiles) {
let event = require(`./eventsPlayer/${file}`)
if (['debug'].includes(event.name)) continue
player.events.on(event.name, (...args) => event.execute(...args))
}
//player.on('debug', async (message) => { console.log(`General player debug event: ${message}`) })
// LAUNCH
client.login()

12
buttons/loop.js Normal file
View File

@@ -0,0 +1,12 @@
const { useQueue } = require("discord-player")
module.exports = {
id: 'loop',
async execute(interaction) {
let queue = useQueue(interaction.guild.id)
let loop = queue.repeatMode === 0 ? 1 : queue.repeatMode === 1 ? 2 : queue.repeatMode === 2 ? 3 : 0
queue.setRepeatMode(loop)
await interaction.reply({ content:`Boucle ${loop === 0 ? "désactivée" : loop === 1 ? "en mode Titre" : loop === 2 ? "en mode File d'Attente" : "en autoplay"}.`, ephemeral: true })
setTimeout(async () => { await interaction.deleteReply() }, 20000)
}
}

11
buttons/pause.js Normal file
View File

@@ -0,0 +1,11 @@
const { useQueue } = require("discord-player")
module.exports = {
id: 'pause',
async execute(interaction) {
let queue = useQueue(interaction.guild.id)
queue.node.setPaused(!queue.node.isPaused())
await interaction.reply({ content: 'Musique mise en pause !', ephemeral: true })
setTimeout(async () => { await interaction.deleteReply() }, 20000)
}
}

11
buttons/previous.js Normal file
View File

@@ -0,0 +1,11 @@
const { useHistory } = require("discord-player")
module.exports = {
id: 'previous',
async execute(interaction) {
let history = useHistory(interaction.guild.id)
await history.previous()
await interaction.reply({ content: 'Musique précédente jouée !', ephemeral: true })
setTimeout(async () => { await interaction.deleteReply() }, 20000)
}
}

11
buttons/resume.js Normal file
View File

@@ -0,0 +1,11 @@
const { useQueue } = require("discord-player")
module.exports = {
id: 'resume',
async execute(interaction) {
let queue = useQueue(interaction.guild.id)
queue.node.setPaused(!queue.node.isPaused())
await interaction.reply({ content: 'Musique reprise !', ephemeral: true })
setTimeout(async () => { await interaction.deleteReply() }, 20000)
}
}

11
buttons/shuffle.js Normal file
View File

@@ -0,0 +1,11 @@
const { useQueue } = require("discord-player")
module.exports = {
id: 'shuffle',
async execute(interaction) {
let queue = useQueue(interaction.guild.id)
queue.tracks.shuffle()
await interaction.reply({ content: 'File d\'attente mélangée !', ephemeral: true })
setTimeout(async () => { await interaction.deleteReply() }, 20000)
}
}

11
buttons/skip.js Normal file
View File

@@ -0,0 +1,11 @@
const { useQueue } = require("discord-player")
module.exports = {
id: 'skip',
async execute(interaction) {
let queue = useQueue(interaction.guild.id)
queue.node.skip()
await interaction.reply({ content: 'Musique passée !', ephemeral: true })
setTimeout(async () => { await interaction.deleteReply() }, 20000)
}
}

11
buttons/stop.js Normal file
View File

@@ -0,0 +1,11 @@
const { useQueue } = require("discord-player")
module.exports = {
id: 'stop',
async execute(interaction) {
let queue = useQueue(interaction.guild.id)
queue.delete()
await interaction.reply({ content: 'Musique arrêtée !', ephemeral: true })
setTimeout(async () => { await interaction.deleteReply() }, 20000)
}
}

12
buttons/volume_down.js Normal file
View File

@@ -0,0 +1,12 @@
const { useQueue } = require("discord-player")
module.exports = {
id: 'volume_down',
async execute(interaction) {
let queue = useQueue(interaction.guild.id)
let volume = queue.node.volume - 10
queue.node.setVolume(volume)
await interaction.reply({ content: `🔉 | Volume modifié à ${volume}% !`, ephemeral: true })
setTimeout(async () => { await interaction.deleteReply() }, 20000)
}
}

15
buttons/volume_up.js Normal file
View File

@@ -0,0 +1,15 @@
const { useQueue } = require("discord-player")
module.exports = {
id: 'volume_up',
async execute(interaction) {
let queue = useQueue(interaction.guild.id)
if (!queue) await interaction.reply({ content: "Aucune musique en cours de lecture.", ephemeral: true })
else {
let volume = queue.node.volume + 10
queue.node.setVolume(volume)
await interaction.reply({ content: `🔉 | Volume modifié à ${volume}% !`, ephemeral: true })
}
setTimeout(async () => { await interaction.deleteReply() }, 20000)
}
}

94
commands/global/crack.js Normal file
View File

@@ -0,0 +1,94 @@
const { SlashCommandBuilder } = require('discord.js')
const iconv = require('iconv-lite')
const axios = require('axios')
const fs = require('fs')
var headers1 = {
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
"x-requested-with": "XMLHttpRequest"
}
var headers2 = {
"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"
}
async function search(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(error => console.error(error))
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
}
async function repo(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(error => console.error(error))
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
}
async function torrent(url, headers) {
let response = await fetch(url, { headers, body: null, method: "GET" })
.catch(error => console.error(error))
let body = await response.text()
let file = body.split('<a href="')[2].split('">')[0]
return file
}
async function download(url, file, headers) {
let path = `./cracks/${file}`
let writer = fs.createWriteStream(path)
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(error => console.error(error))
return path
}
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) {
await interaction.deferReply()
let query = interaction.options.getString('jeu')
let games = await search(query, headers1)
let url = await repo(games[0], headers2)
let file = await torrent(url, headers2)
let path = await download(url, file, headers2)
await interaction.followUp({ content: `Voici ce que j'ai trouvé pour "${query}" !`, files: [path] })
await fs.unlink(path, (err) => { if (err) throw err })
}
}

11
commands/global/ping.js Executable file
View File

@@ -0,0 +1,11 @@
const { SlashCommandBuilder } = require('discord.js')
module.exports = {
data: new SlashCommandBuilder()
.setName('ping')
.setDescription('Check the latency of the bot'),
async execute(interaction) {
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`)
}
}

25
commands/global/spam.js Executable file
View File

@@ -0,0 +1,25 @@
const { SlashCommandBuilder } = require('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) {
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 () {
user.send(string).catch(error => console.error(error))
i++
if (i < integer) myLoop()
}, 1000)
}
myLoop()
}
}

17
commands/global/update.js Executable file
View File

@@ -0,0 +1,17 @@
const { SlashCommandBuilder } = require('discord.js')
module.exports = {
data: new SlashCommandBuilder()
.setName('update')
.setDescription('Update the member count channel.'),
async execute(interaction) {
let guild = interaction.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')
channel.setName(`${i} Gens Posés`)
interaction.reply(`${i} Gens Posés !`)
}).catch(console.error)
}
}

19
commands/music/loop.js Executable file
View File

@@ -0,0 +1,19 @@
const { SlashCommandBuilder } = require('discord.js')
const { useQueue } = require("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) {
let loop = interaction.options.getInteger('loop')
let queue = useQueue(interaction.guild.id)
queue.setRepeatMode(loop)
return await interaction.reply(`Boucle ${loop === 0 ? "désactivée" : loop === 1 ? "en mode Titre" : loop === 2 ? "en mode File d'Attente" : "en autoplay"}.`)
}
}

13
commands/music/pause.js Executable file
View File

@@ -0,0 +1,13 @@
const { SlashCommandBuilder } = require('discord.js')
const { useQueue } = require("discord-player")
module.exports = {
data: new SlashCommandBuilder()
.setName('pause')
.setDescription('Met en pause la musique.'),
async execute(interaction) {
let queue = useQueue(interaction.guild.id)
queue.node.setPaused(!queue.node.isPaused())
return await interaction.reply('Musique mise en pause !')
}
}

81
commands/music/play.js Executable file
View File

@@ -0,0 +1,81 @@
const { SlashCommandBuilder } = require('discord.js')
const { useMasterPlayer, useQueue, QueryType } = require('discord-player')
const reduceString = (str, length) => str.length > length ? str.substring(0, length - 3) + "..." : str
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) {
let query = interaction.options.getString('recherche', true)
if (!query) return interaction.respond([])
let player = useMasterPlayer()
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 = []
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) {
let voiceChannel = interaction.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 = useMasterPlayer()
let queue = useQueue(interaction.guild.id)
if (!queue) {
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: 300000,
leaveOnEnd: true,
leaveOnEndCooldown: 300000,
skipOnNoStream: true
})
}
try { if (!queue.connection) await queue.connect(voiceChannel) }
catch (error) { console.error(error); return await interaction.followUp(`Y'a eu un problème, <@223831938346123275> ! (${error.message})`) }
let result = await player.search(query, { requestedBy: interaction.user })
if (!result.hasTracks()) return await interaction.followUp(`Aucune musique trouvée pour **${query}** !`)
let track = result.tracks[0]
let entry = queue.tasksQueue.acquire()
await entry.getTask()
queue.addTrack(track)
try {
if (!queue.isPlaying()) await queue.node.play()
track.source = track.source === 'youtube' ? 'Youtube' : track.source === 'spotify' ? 'Spotify' : 'Inconnu'
return await interaction.followUp(`Chargement de la musique **${track.title}** de **${track.author}** sur **${track.source}**...`)
} catch (error) { console.error(error); return await interaction.followUp(`Y'a eu un problème, <@223831938346123275> ! (${error.message})`) }
finally { queue.tasksQueue.release() }
}
}

49
commands/music/player.js Executable file
View File

@@ -0,0 +1,49 @@
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js')
const { useQueue } = require("discord-player")
module.exports = {
data: new SlashCommandBuilder()
.setName('player')
.setDescription('Afficher une interface de contrôle de la musique.'),
async execute(interaction) {
let queue = useQueue(interaction.guild.id)
if (!queue) return await interaction.reply('Aucune session d\'écoute en cours !')
let track = queue.currentTrack
if (!track) return await interaction.reply('Aucune musique en cours de lecture !')
/*let embed = {
color: 0xffc370,
title: track.title,
url: track.url,
}
if (track.thumbnail) embed.thumbnail = { url: track.thumbnail }
embed.description = `
**Durée :** ${track.duration}
**Source :** ${track.source ? track.source === 'youtube' ? 'Youtube' : track.source === 'spotify' ? 'Spotify' : 'Inconnu' : 'Inconnu'}
**Volume :** ${queue.node.volume}%
**Progression :** ${queue.node.createProgressBar()}
**Loop :** ${queue.repeatMode ? queue.repeatMode === 2 ? "File d'Attente" : "Titre" : "Off"}
**Autoplay :** ${queue.autoplay ? "On" : "Off"}
`
if (track.requestedBy) embed.footer = { text: `Demandé par ${track.requestedBy.tag}` }
return await interaction.reply({ embeds: [embed] })*/
// Create an embed using EmbedBuilder instead of an object
const embed = new EmbedBuilder()
.setColor('#ffc370')
.setTitle(track.title)
.setAuthor({ name: track.author })
.setURL(track.url)
.setThumbnail(track.thumbnail)
.setDescription(`
**Durée :** ${track.duration}
**Source :** ${track.source ? track.source === 'youtube' ? 'Youtube' : track.source === 'spotify' ? 'Spotify' : 'Inconnu' : 'Inconnu'}
**Volume :** ${queue.node.volume}%
**Progression :** ${queue.node.createProgressBar()}
**Loop :** ${queue.repeatMode ? queue.repeatMode === 2 ? "File d'Attente" : "Titre" : "Off"}
**Autoplay :** ${queue.autoplay ? "On" : "Off"}
`)
.setFooter({ text: `Demandé par ${track.requestedBy.tag}` })
return await interaction.reply({ embeds: [embed] })
}
}

13
commands/music/previous.js Executable file
View File

@@ -0,0 +1,13 @@
const { SlashCommandBuilder } = require('discord.js')
const { useHistory } = require("discord-player")
module.exports = {
data: new SlashCommandBuilder()
.setName('previous')
.setDescription('Joue la musique précédente.'),
async execute(interaction) {
let history = useHistory(interaction.guild.id)
await history.previous()
return await interaction.reply('Musique précédente jouée !')
}
}

13
commands/music/resume.js Executable file
View File

@@ -0,0 +1,13 @@
const { SlashCommandBuilder } = require('discord.js')
const { useQueue } = require("discord-player")
module.exports = {
data: new SlashCommandBuilder()
.setName('resume')
.setDescription('Reprendre la musique.'),
async execute(interaction) {
let queue = useQueue(interaction.guild.id)
queue.node.setPaused(!queue.node.isPaused())
return await interaction.reply('Musique reprise !')
}
}

13
commands/music/shuffle.js Executable file
View File

@@ -0,0 +1,13 @@
const { SlashCommandBuilder } = require('discord.js')
const { useQueue } = require("discord-player")
module.exports = {
data: new SlashCommandBuilder()
.setName('shuffle')
.setDescription('Mélange la file d\'attente.'),
async execute(interaction) {
let queue = useQueue(interaction.guild.id)
queue.tracks.shuffle()
return await interaction.reply('File d\'attente mélangée !')
}
}

13
commands/music/skip.js Executable file
View File

@@ -0,0 +1,13 @@
const { SlashCommandBuilder } = require('discord.js')
const { useQueue } = require("discord-player")
module.exports = {
data: new SlashCommandBuilder()
.setName('skip')
.setDescription('Passer la musique en cours.'),
async execute(interaction) {
let queue = useQueue(interaction.guild.id)
queue.node.skip()
return await interaction.reply('Musique passée !')
}
}

13
commands/music/stop.js Executable file
View File

@@ -0,0 +1,13 @@
const { SlashCommandBuilder } = require('discord.js')
const { useQueue } = require("discord-player")
module.exports = {
data: new SlashCommandBuilder()
.setName('stop')
.setDescription('Arrêter la musique.'),
async execute(interaction) {
let queue = useQueue(interaction.guild.id)
queue.delete()
return await interaction.reply('Musique arrêtée !')
}
}

19
commands/music/volume.js Executable file
View File

@@ -0,0 +1,19 @@
const { SlashCommandBuilder } = require('discord.js')
const { useQueue } = require("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) {
let volume = interaction.options.getInteger('volume')
let queue = useQueue(interaction.guild.id)
queue.node.setVolume(volume)
return await interaction.reply(`Volume modifié à ${volume}% !`)
}
}

16
events/guildMemberAdd.js Executable file
View File

@@ -0,0 +1,16 @@
const { Events } = require('discord.js')
module.exports = {
name: Events.GuildMemberAdd,
async execute(member) {
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')
console.log(channel.name)
console.log(`${i} Gens Posés`)
channel.setName('Changement...')
channel.setName(`${i} Gens Posés`)
}).catch(console.error)
}
}

16
events/guildMemberRemove.js Executable file
View File

@@ -0,0 +1,16 @@
const { Events } = require('discord.js')
module.exports = {
name: Events.GuildMemberRemove,
async execute(member) {
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')
console.log(channel.name)
console.log(`${i} Gens Posés`)
channel.setName('Changement...')
channel.setName(`${i} Gens Posés`)
}).catch(console.error)
}
}

34
events/interactionCreate.js Executable file
View File

@@ -0,0 +1,34 @@
const { Events } = require('discord.js')
module.exports = {
name: Events.InteractionCreate,
async execute(interaction) {
if (interaction.isButton()) {
let button = interaction.client.buttons.get(interaction.customId)
if (!button) return console.error(`No button id matching ${interaction.customId} was found.`)
console.log(`\u001b[1;33m Button '${interaction.customId}' clicked by ${interaction.user.tag}`)
try { await button.execute(interaction) }
catch (error) { console.error(`Error executing ${interaction.customId}:`, error) }
}
if (!interaction.isAutocomplete() && !interaction.isChatInputCommand()) return //console.error(`Interaction ${interaction.commandName} is not a command.`)
let command = interaction.client.commands.get(interaction.commandName)
if (!command) return console.error(`No command matching ${interaction.commandName} was found.`)
if (interaction.isAutocomplete()) {
console.log(`\u001b[1;33m AutoCompleteRun '${interaction.commandName}' launched by ${interaction.user.tag}`)
try { await command.autocompleteRun(interaction) }
catch (error) { console.error(`Error autocompleting ${interaction.commandName}:`, error) }
}
else if (interaction.isChatInputCommand()) {
console.log(`\u001b[1;33m Command '${interaction.commandName}' launched by ${interaction.user.tag}`)
try { await command.execute(interaction) }
catch (error) { console.error(`Error executing ${interaction.commandName}:`, error) }
}
}
}

99
events/ready.js Executable file
View File

@@ -0,0 +1,99 @@
const { Events, EmbedBuilder, ButtonBuilder, ActionRowBuilder } = require('discord.js')
const { useQueue } = require("discord-player")
const dance = async function (bot_id, channel, embed, components) {
let messages = await channel.messages.fetch()
let botMessage = messages.find(msg => msg.author.id === bot_id)
if (!botMessage || (!components && botMessage.components.length > 0)) {
await channel.bulkDelete(messages)
return await channel.send({ embeds: [embed] })
} else {
await botMessage.edit({ embeds: [embed], components })
}
}
const getUptime = function (uptime) {
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`
}
module.exports = {
name: Events.ClientReady,
once: true,
execute(client) {
console.log(`\u001b[1;35m Ready! Logged in as ${client.user.tag}`)
setInterval(async () => {
let guild = client.guilds.cache.get('1086577543651524699')
let channel = guild.channels.cache.get('1099542278764245096')
let queue = useQueue(guild.id)
if (!queue) return await dance(client.user.id, channel, new EmbedBuilder().setColor('#ffc370').setTitle('Aucune session d\'écoute en cours !').setFooter({ text: `Uptime: ${getUptime(client.uptime)}` }))
let track = queue.currentTrack
if (!track) return await dance(client.user.id, channel, new EmbedBuilder().setColor('#ffc370').setTitle('Aucune musique en cours de lecture !').setFooter({ text: `Uptime: ${getUptime(client.uptime)}` }))
let embed = new EmbedBuilder()
.setColor('#ffc370')
.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() },
{ name: 'Loop', value: queue.repeatMode ? queue.repeatMode === 2 ? "File d'Attente" : "Titre" : "Off", inline: true },
{ name: 'Autoplay', value: queue.autoplay ? "On" : "Off", inline: true }
)
.setDescription(`**Musique suivante :** ${queue.tracks[0] ? queue.tracks[0].title : 'Aucune'}`)
.setFooter({ text: `Uptime: ${getUptime(client.uptime)} / Demandé par ${track.requestedBy.tag}` })
let components = [
new ActionRowBuilder().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.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().addComponents(
new ButtonBuilder()
.setLabel('🔀')
.setStyle(2)
.setCustomId('shuffle'),
new ButtonBuilder()
.setLabel('🔁')
.setStyle(2)
.setCustomId('loop'),
new ButtonBuilder()
.setLabel('⏮️')
.setStyle(2)
.setCustomId('previous')
.setDisabled(queue.previousTracks ? !queue.previousTracks[0] : true)
)
]
await dance(client.user.id, channel, embed, components)
}, 4000)
}
}

59
events/voiceStateUpdate.js Executable file
View File

@@ -0,0 +1,59 @@
const { Events, AuditLogEvent } = require('discord.js')
module.exports = {
name: Events.VoiceStateUpdate,
async execute(oldState, newState) {
/*
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
}
*/
}
}

View File

@@ -0,0 +1,7 @@
module.exports = {
name: 'audioTrackAdd',
async execute(queue, 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 !`)
}
}

View File

@@ -0,0 +1,7 @@
module.exports = {
name: 'audioTracksAdd',
async execute(queue, track) {
// Emitted when the player adds multiple songs to its queue
queue.metadata.channel.send(`Ajout de ${track.length} musiques à la file d'attente !`)
}
}

8
eventsPlayer/debug.js Normal file
View File

@@ -0,0 +1,8 @@
module.exports = {
name: 'debug',
async execute (queue, message) {
// Emitted when the player queue sends debug info
// Useful for seeing what state the current queue is at
console.log(`Player debug event: ${message}`)
}
}

View File

@@ -0,0 +1,7 @@
module.exports = {
name: 'disconnect',
async execute(queue, track) {
// Emitted when the bot leaves the voice channel
queue.metadata.channel.send("J'ai quitté le vocal !")
}
}

View File

@@ -0,0 +1,8 @@
module.exports = {
name: 'emptyChannel',
async execute(queue, 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.`)
}
}

View File

@@ -0,0 +1,7 @@
module.exports = {
name: 'emptyQueue',
async execute(queue, track) {
// Emitted when the player queue has finished
queue.metadata.channel.send("File d'attente vide !")
}
}

8
eventsPlayer/error.js Normal file
View File

@@ -0,0 +1,8 @@
module.exports = {
name: 'error',
async execute(queue, error) {
// Emitted when the player queue encounters error
console.log(`\u001b[1;31m General player error event: ${error.message}`)
console.error(error)
}
}

View File

@@ -0,0 +1,8 @@
module.exports = {
name: 'playerError',
async execute(queue, error) {
// Emitted when the audio player errors while streaming audio track
console.log(`\u001b[1;31m Player error event: ${error.message}`)
console.error(error)
}
}

View File

@@ -0,0 +1,7 @@
module.exports = {
name: 'playerSkip',
async execute(queue, 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 !`)
}
}

View File

@@ -0,0 +1,7 @@
module.exports = {
name: 'playerStart',
async execute(queue, track) {
// Emitted when the player starts to play a song
queue.metadata.channel.send(`Lecture de **${track.title}** de **${track.author}** !`)
}
}

5532
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

38
package.json Executable file
View File

@@ -0,0 +1,38 @@
{
"name": "tamiseur",
"version": "1.0.0",
"description": "Tamiseur",
"main": "app.js",
"scripts": {
"format": "prettier --write .",
"start": "node app.js",
"dev": "nodemon -e js"
},
"author": {
"name": "Zachary Guénot"
},
"devDependencies": {
"eslint": "^8.39.0",
"nodemon": "^2.0.22",
"prettier": "^2.8.7"
},
"eslintConfig": {},
"dependencies": {
"@discord-player/equalizer": "^0.2.1",
"@discord-player/extractor": "^4.2.1",
"@discordjs/opus": "^0.9.0",
"@discordjs/voice": "^0.16.0",
"axios": "^1.3.6",
"bufferutil": "^4.0.7",
"discord-player": "^6.2.1",
"discord.js": "^14.9.0",
"dotenv": "^16.0.3",
"iconv-lite": "^0.6.3",
"libsodium-wrappers": "^0.7.11",
"npm": "^9.6.5",
"opusscript": "^0.0.8",
"play-dl": "^1.9.6",
"utf-8-validate": "^6.0.3",
"zlib-sync": "^0.1.8"
}
}

BIN
stronger_shorter.mp3 Executable file

Binary file not shown.