diff --git a/docker-compose.yml b/docker-compose.yml index 73e2c10..c629e45 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,7 @@ services: dockerfile: ./Dockerfile args: - JAVA_VERSION=17 - - VERSION=0.1.10 + - VERSION=0.1.11 volumes: - ./data:/app restart: unless-stopped diff --git a/pom.xml b/pom.xml index acda0fd..b684063 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.bensherriff siren - 0.1.10 + 0.1.11 jar diff --git a/src/main/java/com/bensherriff/siren/audio/AudioHandler.java b/src/main/java/com/bensherriff/siren/audio/AudioHandler.java index 99438e6..3d108a6 100644 --- a/src/main/java/com/bensherriff/siren/audio/AudioHandler.java +++ b/src/main/java/com/bensherriff/siren/audio/AudioHandler.java @@ -1,10 +1,12 @@ package com.bensherriff.siren.audio; import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; +import com.sedmelluq.discord.lavaplayer.player.event.AudioEvent; import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter; import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; import com.sedmelluq.discord.lavaplayer.track.AudioTrack; import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason; +import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame; import com.sedmelluq.discord.lavaplayer.track.playback.MutableAudioFrame; import net.dv8tion.jda.api.audio.AudioSendHandler; import net.dv8tion.jda.api.entities.Activity; @@ -38,15 +40,19 @@ public class AudioHandler extends AudioEventAdapter implements AudioSendHandler } public void addTrack(AudioTrack track) { - if (!player.startTrack(track, true)) { - if (!queue.offer(track)) { - LOGGER.error("Failed to queue track {}", track.getInfo().title); - } + if (player.getPlayingTrack() == null) { + player.playTrack(track); + } else { + LOGGER.debug("Track '{}' has been queued", track.getInfo().title); + if (!queue.offer(track)) { + LOGGER.error("Failed to queue track {}", track.getInfo().title); + } } } public void nextTrack() { - player.startTrack(queue.poll(), false); + LOGGER.debug("Playing next track"); + player.stopTrack(); } public void setPaused(boolean paused) { @@ -62,47 +68,51 @@ public class AudioHandler extends AudioEventAdapter implements AudioSendHandler } public void setVolume(int volume) { + LOGGER.debug("Set volume to {}", volume); player.setVolume(volume); } @Override public void onPlayerPause(AudioPlayer player) { - super.onPlayerPause(player); + LOGGER.debug("isPaused: {} for {}", player.isPaused(), player.getPlayingTrack().getInfo().title); } @Override public void onPlayerResume(AudioPlayer player) { - super.onPlayerResume(player); + LOGGER.debug("isPaused: {} for {}", player.isPaused(), player.getPlayingTrack().getInfo().title); } @Override public void onTrackStart(AudioPlayer player, AudioTrack track) { - manager.getListener().getJDA().getPresence().setActivity(Activity.listening(track.getInfo().title)); - super.onTrackStart(player, track); + LOGGER.debug("Starting track {}", track.getInfo().title); + manager.getListener().getJDA().getPresence().setActivity(Activity.playing(track.getInfo().title)); } @Override public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) { - LOGGER.debug("Track ended due to {}; {} ", endReason.name(), endReason.mayStartNext ? "starting next track" : "closing connection"); - if (endReason.mayStartNext) { - nextTrack(); - } else { - queue.clear(); + LOGGER.debug("Track ended due to {}; {} ", endReason.name(), endReason.mayStartNext); + if (queue.isEmpty()) { manager.getListener().closeAudioConnection(guildID); manager.getListener().getJDA().getPresence().setActivity(Activity.playing("nothing")); + } else { + player.playTrack(queue.poll()); } } + @Override + public void onEvent(AudioEvent event) { + super.onEvent(event); +// LOGGER.trace("On event {}", event.getClass().getName()); + } + @Override public void onTrackException(AudioPlayer player, AudioTrack track, FriendlyException exception) { LOGGER.warn("Exception on track '{}': {}", track.getInfo().title, exception.getMessage()); - super.onTrackException(player, track, exception); } @Override public void onTrackStuck(AudioPlayer player, AudioTrack track, long thresholdMs) { LOGGER.warn("{} - 'track {}' is stuck", guildID, track.getInfo().title); - super.onTrackStuck(player, track, thresholdMs); } @Override diff --git a/src/main/java/com/bensherriff/siren/audio/Listener.java b/src/main/java/com/bensherriff/siren/audio/Listener.java index 872566a..92968eb 100644 --- a/src/main/java/com/bensherriff/siren/audio/Listener.java +++ b/src/main/java/com/bensherriff/siren/audio/Listener.java @@ -27,13 +27,11 @@ public class Listener extends ListenerAdapter { private static final Logger LOGGER = LogManager.getLogger(Listener.class); private final PlayerManager playerManager; - private final Map musicManagers; private final Settings settings; private final Map commands = new HashMap<>(); private JDA jda; public Listener(Settings settings) { - this.musicManagers = new HashMap<>(); this.settings = settings; this.playerManager = new PlayerManager(this); @@ -51,18 +49,10 @@ public class Listener extends ListenerAdapter { return playerManager; } - public Map getMusicManagers() { - return musicManagers; - } - public Settings getSettings() { return settings; } - public Map getCommands() { - return commands; - } - public JDA getJDA() { return jda; } @@ -95,20 +85,18 @@ public class Listener extends ListenerAdapter { public synchronized AudioHandler getGuildAudioPlayer(Guild guild) throws IOException { long guildId = Long.parseLong(guild.getId()); - AudioHandler audioHandler = musicManagers.get(guildId); + AudioHandler audioHandler; - if (audioHandler == null) { + if (guild.getAudioManager().getSendingHandler() == null) { LOGGER.info("Creating Audio Handler for guild {}", guildId); if (!settings.getGuildSettings().containsKey(guildId)) { settings.getGuildSettings().put(guildId, new GuildSettings()); SettingsManager.write(settings); } audioHandler = new AudioHandler(playerManager, guildId); - musicManagers.put(guildId, audioHandler); - } - - if (!audioHandler.equals(guild.getAudioManager().getSendingHandler())) { guild.getAudioManager().setSendingHandler(audioHandler); + } else { + audioHandler = (AudioHandler) guild.getAudioManager().getSendingHandler(); } return audioHandler; @@ -132,7 +120,7 @@ public class Listener extends ListenerAdapter { try { if (commands.containsKey(command)) { - commands.get(command).doCommand(event); + commands.get(command).execute(event); } else { event.getHook().sendMessage("Unexpected command received.").queue(); } diff --git a/src/main/java/com/bensherriff/siren/commands/Command.java b/src/main/java/com/bensherriff/siren/commands/Command.java index dff016d..7f6503c 100644 --- a/src/main/java/com/bensherriff/siren/commands/Command.java +++ b/src/main/java/com/bensherriff/siren/commands/Command.java @@ -22,7 +22,7 @@ public abstract class Command { public Command(Listener listener) { this.listener = listener; } - public abstract void doCommand(SlashCommandInteractionEvent event) throws IOException; + public abstract void execute(SlashCommandInteractionEvent event) throws IOException; public SlashCommandData getSlashCommandData() { return slashCommandData; diff --git a/src/main/java/com/bensherriff/siren/commands/PauseCommand.java b/src/main/java/com/bensherriff/siren/commands/PauseCommand.java index c257303..9d3061e 100644 --- a/src/main/java/com/bensherriff/siren/commands/PauseCommand.java +++ b/src/main/java/com/bensherriff/siren/commands/PauseCommand.java @@ -16,7 +16,7 @@ public class PauseCommand extends Command { } @Override - public void doCommand(SlashCommandInteractionEvent event) throws IOException { + public void execute(SlashCommandInteractionEvent event) throws IOException { Guild guild = getGuild(event); AudioHandler audioHandler = listener.getGuildAudioPlayer(guild); if (audioHandler.isPaused()) { diff --git a/src/main/java/com/bensherriff/siren/commands/PlayCommand.java b/src/main/java/com/bensherriff/siren/commands/PlayCommand.java index ac73366..8fc9a4d 100644 --- a/src/main/java/com/bensherriff/siren/commands/PlayCommand.java +++ b/src/main/java/com/bensherriff/siren/commands/PlayCommand.java @@ -24,59 +24,74 @@ public class PlayCommand extends Command { } @Override - public void doCommand(SlashCommandInteractionEvent event) throws IOException { - String userID = event.getUser().getId(); - Guild guild = getGuild(event); + public void execute(SlashCommandInteractionEvent event) throws IOException { String trackURL = Objects.requireNonNull(event.getOption("url")).getAsString(); - AudioHandler audioHandler = listener.getGuildAudioPlayer(guild); - - listener.getPlayerManager().loadItemOrdered(audioHandler, trackURL, new AudioLoadResultHandler() { - @Override - public void trackLoaded(AudioTrack track) { - try { - playTrack(guild, userID, audioHandler, track); - event.getHook().sendMessage("Adding **" + track.getInfo().title + "** to queue...").queue(); - } catch (EmptyVoiceChannelException e) { - event.getHook().sendMessage("You must be connected to a voice channel in order to play tracks!").queue(); - } - } - - @Override - public void playlistLoaded(AudioPlaylist playlist) { - AudioTrack firstTrack = playlist.getSelectedTrack(); - - if (firstTrack == null) { - firstTrack = playlist.getTracks().get(0); - } - - try { - playTrack(guild, userID, audioHandler, firstTrack); - event.getHook().sendMessage("Adding **" + firstTrack.getInfo().title + "** to queue (first track of playlist " + playlist.getName() + ")...").queue(); - } catch (EmptyVoiceChannelException e) { - event.getHook().sendMessage("You must be connected to a voice channel in order to play tracks!").queue(); - } - } - - @Override - public void noMatches() { - event.getHook().sendMessage("Nothing found by " + trackURL).queue(); - } - - @Override - public void loadFailed(FriendlyException exception) { - String msg = "Failed to play track"; - if (exception.getMessage().contains("Unknown file format")) { - event.getHook().sendMessage(msg + ". " + exception.getMessage()).queue(); - } else { - event.getHook().sendMessage(msg + ". Please contact your administrator.").queue(); - } - LOGGER.error("{}: {}", msg, exception.getMessage()); - } - }); + listener.getPlayerManager().loadItemOrdered(event.getGuild(), trackURL, new ResultHandler(event)); } - public void playTrack(Guild guild, String userID, AudioHandler audioHandler, AudioTrack track) throws EmptyVoiceChannelException { - listener.connectToVoiceChannel(userID, guild.getAudioManager()); - audioHandler.addTrack(track); + private class ResultHandler implements AudioLoadResultHandler { + + private final Guild guild; + private final String userID; + private final AudioHandler audioHandler; + private final SlashCommandInteractionEvent event; + + private ResultHandler(SlashCommandInteractionEvent event) throws IOException { + this.event = event; + this.userID = event.getUser().getId(); + this.guild = getGuild(event); + this.audioHandler = listener.getGuildAudioPlayer(guild); + } + + private void playTrack(Guild guild, String userID, AudioHandler audioHandler, AudioTrack track) throws EmptyVoiceChannelException { + listener.connectToVoiceChannel(userID, guild.getAudioManager()); + audioHandler.addTrack(track); + } + + @Override + public void trackLoaded(AudioTrack track) { + try { + playTrack(guild, userID, audioHandler, track); + event.getHook().sendMessage("Adding **" + track.getInfo().title + "** to queue...").queue(); + } catch (EmptyVoiceChannelException e) { + event.getHook().sendMessage("You must be connected to a voice channel in order to play tracks!").queue(); + } catch (Exception e) { + LOGGER.error(e.getMessage()); + } + } + + @Override + public void playlistLoaded(AudioPlaylist playlist) { + AudioTrack firstTrack = playlist.getSelectedTrack(); + + if (firstTrack == null) { + firstTrack = playlist.getTracks().get(0); + } + + try { + playTrack(guild, userID, audioHandler, firstTrack); + event.getHook().sendMessage("Adding **" + firstTrack.getInfo().title + "** to queue (first track of playlist " + playlist.getName() + ")...").queue(); + } catch (EmptyVoiceChannelException e) { + event.getHook().sendMessage("You must be connected to a voice channel in order to play tracks!").queue(); + } catch (Exception e) { + LOGGER.error(e.getMessage()); + } + } + + @Override + public void noMatches() { + event.getHook().sendMessage("Nothing found at that URL").queue(); + } + + @Override + public void loadFailed(FriendlyException exception) { + String errorMsg = "Failed to play track"; + if (exception.getMessage().contains("Unknown file format")) { + event.getHook().sendMessage(errorMsg + ". " + exception.getMessage()).queue(); + } else { + event.getHook().sendMessage(errorMsg + ". Please contact your administrator.").queue(); + } + LOGGER.error("{}: {}", errorMsg, exception.getMessage()); + } } } diff --git a/src/main/java/com/bensherriff/siren/commands/ResumeCommand.java b/src/main/java/com/bensherriff/siren/commands/ResumeCommand.java index ac4f871..c14c801 100644 --- a/src/main/java/com/bensherriff/siren/commands/ResumeCommand.java +++ b/src/main/java/com/bensherriff/siren/commands/ResumeCommand.java @@ -16,7 +16,7 @@ public class ResumeCommand extends Command { } @Override - public void doCommand(SlashCommandInteractionEvent event) throws IOException { + public void execute(SlashCommandInteractionEvent event) throws IOException { Guild guild = getGuild(event); AudioHandler audioHandler = listener.getGuildAudioPlayer(guild); if (audioHandler.isPaused()) { diff --git a/src/main/java/com/bensherriff/siren/commands/SkipCommand.java b/src/main/java/com/bensherriff/siren/commands/SkipCommand.java index cee7044..eb26d1c 100644 --- a/src/main/java/com/bensherriff/siren/commands/SkipCommand.java +++ b/src/main/java/com/bensherriff/siren/commands/SkipCommand.java @@ -16,7 +16,7 @@ public class SkipCommand extends Command { } @Override - public void doCommand(SlashCommandInteractionEvent event) throws IOException { + public void execute(SlashCommandInteractionEvent event) throws IOException { Guild guild = getGuild(event); AudioHandler audioHandler = listener.getGuildAudioPlayer(guild); audioHandler.nextTrack(); diff --git a/src/main/java/com/bensherriff/siren/commands/StopCommand.java b/src/main/java/com/bensherriff/siren/commands/StopCommand.java index 38dfbb5..81cd81d 100644 --- a/src/main/java/com/bensherriff/siren/commands/StopCommand.java +++ b/src/main/java/com/bensherriff/siren/commands/StopCommand.java @@ -16,7 +16,7 @@ public class StopCommand extends Command { } @Override - public void doCommand(SlashCommandInteractionEvent event) throws IOException { + public void execute(SlashCommandInteractionEvent event) throws IOException { Guild guild = getGuild(event); AudioHandler audioHandler = listener.getGuildAudioPlayer(guild); audioHandler.stopTrack(); diff --git a/src/main/java/com/bensherriff/siren/commands/VolumeCommand.java b/src/main/java/com/bensherriff/siren/commands/VolumeCommand.java index 8dbe3b7..2f0af55 100644 --- a/src/main/java/com/bensherriff/siren/commands/VolumeCommand.java +++ b/src/main/java/com/bensherriff/siren/commands/VolumeCommand.java @@ -20,7 +20,7 @@ public class VolumeCommand extends Command { } @Override - public void doCommand(SlashCommandInteractionEvent event) throws IOException { + public void execute(SlashCommandInteractionEvent event) throws IOException { Guild guild = getGuild(event); int volume = Objects.requireNonNull(event.getOption("volume")).getAsInt(); listener.getSettings().getGuildSettings().get(guild.getIdLong()).setVolume(volume);