diff --git a/src/main/java/org/camelia/studio/kiss/shot/acerola/audio/TrackScheduler.java b/src/main/java/org/camelia/studio/kiss/shot/acerola/audio/TrackScheduler.java index 6c80bed..548ed9f 100644 --- a/src/main/java/org/camelia/studio/kiss/shot/acerola/audio/TrackScheduler.java +++ b/src/main/java/org/camelia/studio/kiss/shot/acerola/audio/TrackScheduler.java @@ -11,6 +11,8 @@ import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason; public class TrackScheduler extends AudioEventAdapter { private final AudioPlayer player; private final Queue queue; + private boolean loop = false; + private boolean repeat = false; public TrackScheduler(AudioPlayer player) { this.player = player; @@ -31,13 +33,27 @@ public class TrackScheduler extends AudioEventAdapter { } public void nextTrack() { - player.startTrack(queue.poll(), false); + AudioTrack track = queue.poll(); + + if (loop) { + queue.offer(track.makeClone()); + } else if (repeat) { + // ON ajoute la track au début de la queue + LinkedList list = new LinkedList<>(queue); + queue.clear(); + queue.offer(track.makeClone()); + while (!list.isEmpty()) { + queue.offer(list.poll()); + } + } + player.startTrack(track, false); } public void nextTrack(int nextTrack) { if (nextTrack < 1) { return; } + for (int i = 0; i < nextTrack - 1; i++) { queue.poll(); } @@ -47,8 +63,25 @@ public class TrackScheduler extends AudioEventAdapter { public Queue getQueue() { return queue; } - + public void clearQueue() { queue.clear(); } + + public void shuffle() { + LinkedList list = new LinkedList<>(queue); + queue.clear(); + while (!list.isEmpty()) { + int index = (int) (Math.random() * list.size()); + queue.offer(list.remove(index)); + } + } + + public void setLoop(boolean loop) { + this.loop = loop; + } + + public void setRepeat(boolean repeat) { + this.repeat = repeat; + } } \ No newline at end of file diff --git a/src/main/java/org/camelia/studio/kiss/shot/acerola/commands/audio/PauseCommand.java b/src/main/java/org/camelia/studio/kiss/shot/acerola/commands/audio/PauseCommand.java index c99fa62..f61f5c4 100644 --- a/src/main/java/org/camelia/studio/kiss/shot/acerola/commands/audio/PauseCommand.java +++ b/src/main/java/org/camelia/studio/kiss/shot/acerola/commands/audio/PauseCommand.java @@ -38,6 +38,12 @@ public class PauseCommand implements ISlashCommand { return; } + if (member.getVoiceState().getChannel() != audioManager.getConnectedChannel()) { + event.getHook().editOriginal("Vous devez être dans le même salon vocal que moi pour utiliser cette commande !") + .queue(); + return; + } + GuildMusicManager musicManager = PlayerManager.getInstance().getMusicManager(event.getGuild()); boolean isPaused = musicManager.audioPlayer.isPaused(); diff --git a/src/main/java/org/camelia/studio/kiss/shot/acerola/commands/audio/PlayCommand.java b/src/main/java/org/camelia/studio/kiss/shot/acerola/commands/audio/PlayCommand.java index 78dbd08..17bc237 100644 --- a/src/main/java/org/camelia/studio/kiss/shot/acerola/commands/audio/PlayCommand.java +++ b/src/main/java/org/camelia/studio/kiss/shot/acerola/commands/audio/PlayCommand.java @@ -47,6 +47,15 @@ public class PlayCommand implements ISlashCommand { AudioManager audioManager = event.getGuild().getAudioManager(); + if (!audioManager.isConnected()) { + audioManager.openAudioConnection(voiceState.getChannel()); + PlayerManager.getInstance().getMusicManager(event.getGuild()).audioPlayer.setVolume(25); + } else if (member.getVoiceState().getChannel() != audioManager.getConnectedChannel()) { + event.getHook().editOriginal("Vous devez être dans le même salon vocal que moi pour utiliser cette commande !") + .queue(); + return; + } + audioManager.setConnectionListener(new ConnectionListener() { @Override public void onStatusChange(ConnectionStatus status) { @@ -64,11 +73,6 @@ public class PlayCommand implements ISlashCommand { } }); - if (!audioManager.isConnected()) { - audioManager.openAudioConnection(voiceState.getChannel()); - PlayerManager.getInstance().getMusicManager(event.getGuild()).audioPlayer.setVolume(25); - } - PlayerManager.getInstance().loadAndPlay(event.getChannel().asGuildMessageChannel(), url); event.getHook().editOriginal("Chargement du fichier audio en cours...").queue(); } diff --git a/src/main/java/org/camelia/studio/kiss/shot/acerola/commands/audio/RepeatCommand.java b/src/main/java/org/camelia/studio/kiss/shot/acerola/commands/audio/RepeatCommand.java new file mode 100644 index 0000000..db993dd --- /dev/null +++ b/src/main/java/org/camelia/studio/kiss/shot/acerola/commands/audio/RepeatCommand.java @@ -0,0 +1,87 @@ +package org.camelia.studio.kiss.shot.acerola.commands.audio; + +import java.util.List; + +import org.camelia.studio.kiss.shot.acerola.audio.GuildMusicManager; +import org.camelia.studio.kiss.shot.acerola.audio.PlayerManager; +import org.camelia.studio.kiss.shot.acerola.interfaces.ISlashCommand; + +import net.dv8tion.jda.api.entities.GuildVoiceState; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; +import net.dv8tion.jda.api.managers.AudioManager; + +public class RepeatCommand implements ISlashCommand { + + @Override + public String getName() { + return "repeat"; + } + + @Override + public String getDescription() { + return "Permet de répéter la musique en cours"; + } + + @Override + public List getOptions() { + return List.of( + new OptionData(OptionType.STRING, "mode", "Le mode de répétition").addChoice("Toute la queue", "all") + .addChoice("La musique actuelle", "one").addChoice("Désactiver la répétition", "off") + .setRequired(true)); + } + + @Override + public void execute(SlashCommandInteractionEvent event) { + event.deferReply().queue(); + + Member member = event.getMember(); + GuildVoiceState voiceState = member.getVoiceState(); + + if (!voiceState.inAudioChannel()) { + event.getHook().editOriginal("Vous devez être connecté à un salon vocal pour utiliser cette commande !") + .queue(); + return; + } + + AudioManager audioManager = event.getGuild().getAudioManager(); + if (!audioManager.isConnected()) { + event.getHook().editOriginal("Je ne suis pas connecté à un canal vocal !").queue(); + return; + } + + if (member.getVoiceState().getChannel() != audioManager.getConnectedChannel()) { + event.getHook() + .editOriginal("Vous devez être dans le même salon vocal que moi pour utiliser cette commande !") + .queue(); + return; + } + + String mode = event.getOption("mode").getAsString(); + GuildMusicManager musicManager = PlayerManager.getInstance().getMusicManager(event.getGuild()); + + switch (mode) { + case "all": + musicManager.scheduler.setLoop(true); + musicManager.scheduler.setRepeat(false); + + event.getHook().editOriginal("Toute la queue sera répétée !").queue(); + break; + case "one": + musicManager.scheduler.setLoop(false); + musicManager.scheduler.setRepeat(true); + + event.getHook().editOriginal("La musique actuelle sera répétée !").queue(); + break; + case "off": + musicManager.scheduler.setLoop(false); + musicManager.scheduler.setRepeat(false); + + event.getHook().editOriginal("La répétition a été désactivée !").queue(); + break; + } + } + +} diff --git a/src/main/java/org/camelia/studio/kiss/shot/acerola/commands/audio/ShuffleCommand.java b/src/main/java/org/camelia/studio/kiss/shot/acerola/commands/audio/ShuffleCommand.java new file mode 100644 index 0000000..04fb0c3 --- /dev/null +++ b/src/main/java/org/camelia/studio/kiss/shot/acerola/commands/audio/ShuffleCommand.java @@ -0,0 +1,53 @@ +package org.camelia.studio.kiss.shot.acerola.commands.audio; + +import org.camelia.studio.kiss.shot.acerola.audio.GuildMusicManager; +import org.camelia.studio.kiss.shot.acerola.audio.PlayerManager; +import org.camelia.studio.kiss.shot.acerola.interfaces.ISlashCommand; + +import net.dv8tion.jda.api.entities.GuildVoiceState; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.managers.AudioManager; + +public class ShuffleCommand implements ISlashCommand { + + @Override + public String getName() { + return "shuffle"; + } + + @Override + public String getDescription() { + return "Permet de mélanger la file d'attente"; + } + + @Override + public void execute(SlashCommandInteractionEvent event) { + event.deferReply().queue(); + + // Vérifier si l'utilisateur est dans un canal vocal + GuildVoiceState voiceState = event.getMember().getVoiceState(); + if (!voiceState.inAudioChannel()) { + event.getHook().editOriginal("Vous devez être dans un canal vocal pour utiliser cette commande !").queue(); + return; + } + + // Vérifier si le bot est dans le même canal vocal + AudioManager audioManager = event.getGuild().getAudioManager(); + if (!audioManager.isConnected()) { + event.getHook().editOriginal("Je ne suis pas connecté à un canal vocal !").queue(); + return; + } + + if (voiceState.getChannel() != audioManager.getConnectedChannel()) { + event.getHook().editOriginal("Vous devez être dans le même canal vocal que moi !").queue(); + return; + } + + // On passe aux musiques suivantes + GuildMusicManager musicManager = PlayerManager.getInstance().getMusicManager(event.getGuild()); + musicManager.scheduler.shuffle(); + + event.getHook().editOriginal("La file d'attente a été mélangée !").queue(); + } + +} diff --git a/src/main/java/org/camelia/studio/kiss/shot/acerola/commands/audio/VolumeCommand.java b/src/main/java/org/camelia/studio/kiss/shot/acerola/commands/audio/VolumeCommand.java index 34dfd73..c6f91c1 100644 --- a/src/main/java/org/camelia/studio/kiss/shot/acerola/commands/audio/VolumeCommand.java +++ b/src/main/java/org/camelia/studio/kiss/shot/acerola/commands/audio/VolumeCommand.java @@ -4,6 +4,7 @@ import org.camelia.studio.kiss.shot.acerola.audio.GuildMusicManager; import org.camelia.studio.kiss.shot.acerola.audio.PlayerManager; import org.camelia.studio.kiss.shot.acerola.interfaces.ISlashCommand; +import net.dv8tion.jda.api.entities.GuildVoiceState; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.interactions.commands.OptionType; import net.dv8tion.jda.api.interactions.commands.build.OptionData; @@ -34,12 +35,23 @@ public class VolumeCommand implements ISlashCommand { public void execute(SlashCommandInteractionEvent event) { event.deferReply().queue(); + GuildVoiceState voiceState = event.getMember().getVoiceState(); + if (!voiceState.inAudioChannel()) { + event.reply("Vous devez être dans un canal vocal pour utiliser cette commande !").queue(); + return; + } + AudioManager audioManager = event.getGuild().getAudioManager(); if (!audioManager.isConnected()) { event.getHook().editOriginal("Je ne suis pas connecté à un canal vocal !").queue(); return; } + if (voiceState.getChannel() != audioManager.getConnectedChannel()) { + event.getHook().editOriginal("Vous devez être dans le même canal vocal que moi !").queue(); + return; + } + GuildMusicManager musicManager = PlayerManager.getInstance().getMusicManager(event.getGuild()); int volume = Integer.parseInt(event.getOption("volume").getAsString());