diff --git a/src/main/java/command/music/JoinCommand.java b/src/main/java/command/music/JoinCommand.java index 20109a0..22ec94d 100644 --- a/src/main/java/command/music/JoinCommand.java +++ b/src/main/java/command/music/JoinCommand.java @@ -3,9 +3,7 @@ import client.NanoClient; import com.jagrosh.jdautilities.command.Command; import com.jagrosh.jdautilities.command.CommandEvent; -import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.VoiceChannel; -import service.music.CustomEmbedBuilder; import service.music.GuildMusicManager; import service.music.HelpProcess; import service.music.MusicUtils; @@ -26,12 +24,6 @@ public JoinCommand(NanoClient nanoClient) { @Override protected void execute(CommandEvent event) { - VoiceChannel channel = event.getMember().getVoiceState().getChannel(); - if (channel == null) { - event.reply(":x: | You're not connected to any voice channel"); - return; - } - GuildMusicManager musicManager = nanoClient.getGuildAudioPlayer(event.getGuild()); musicManager.scheduler.textChannel = event.getTextChannel(); @@ -41,18 +33,13 @@ protected void execute(CommandEvent event) { return; } } - event.getGuild().getAudioManager().openAudioConnection(channel); - -// if (!event.getSelfMember().hasPermission(Permission.VOICE_DEAF_OTHERS) && -// !event.getSelfMember().getVoiceState().isDeafened()) { -// CustomEmbedBuilder embedBuilder = new CustomEmbedBuilder(); -// embedBuilder.addField(":warning: Missing Permission: `Deafen Members`!", -// "Please don't undeafen me! I work better by being deafened because: " + -// "Less lag, more clear, better quality, and doesn't randomly disconnect", -// true); -// event.reply(embedBuilder.build()); -// } - - event.reply(":white_check_mark: | Connected to :loud_sound: `" + channel.getName() + "`"); + + VoiceChannel connectedChannel = nanoClient.getMusicService().joinMemberVoiceChannel(event); + + if (connectedChannel == null) { + return; + } + + event.reply(":white_check_mark: | Connected to :loud_sound: `" + connectedChannel.getName() + "`"); } } diff --git a/src/main/java/command/music/LeaveCommand.java b/src/main/java/command/music/LeaveCommand.java index 5b77a5d..254a566 100644 --- a/src/main/java/command/music/LeaveCommand.java +++ b/src/main/java/command/music/LeaveCommand.java @@ -4,6 +4,7 @@ import com.jagrosh.jdautilities.command.Command; import com.jagrosh.jdautilities.command.CommandEvent; import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.VoiceChannel; import net.dv8tion.jda.api.managers.AudioManager; import service.music.GuildMusicManager; import service.music.HelpProcess; @@ -26,7 +27,16 @@ public LeaveCommand(NanoClient nanoClient) { protected void execute(CommandEvent event) { Guild guild = event.getGuild(); - if (event.getSelfMember().getVoiceState().getChannel() == null) { + VoiceChannel selfVoiceChannel = event.getSelfMember().getVoiceState().getChannel(); + if (selfVoiceChannel == null) { + return; + } + + if (event.getMember().getVoiceState().getChannel() == null) { + return; + } + + if (!selfVoiceChannel.getId().equals(event.getMember().getVoiceState().getChannel().getId())) { return; } diff --git a/src/main/java/command/music/LyricCommand.java b/src/main/java/command/music/LyricCommand.java index fda0522..1e23ce0 100644 --- a/src/main/java/command/music/LyricCommand.java +++ b/src/main/java/command/music/LyricCommand.java @@ -45,7 +45,7 @@ protected void execute(CommandEvent event) embed.setTitle("Failed"); embed.addField( ":x:", - "Can't search lyric, because `song-title` is empty and currently no playing music.", + "Can't search lyric, because argument for `song-title` is empty and currently not playing any song.", true); event.reply(embed.build()); return; diff --git a/src/main/java/command/music/NowPlayCommand.java b/src/main/java/command/music/NowPlayCommand.java index 74e007a..199754a 100644 --- a/src/main/java/command/music/NowPlayCommand.java +++ b/src/main/java/command/music/NowPlayCommand.java @@ -27,6 +27,9 @@ protected void execute(CommandEvent event) { if (musicManager.player.getPlayingTrack() == null) { event.replyError("Not playing anything"); + if (event.getGuild().getAudioManager().getConnectedChannel() == null) { + nanoClient.getMusicManagers().remove(event.getGuild().getIdLong()); + } return; } musicManager.announceNowPlaying(event); diff --git a/src/main/java/command/music/PauseCommand.java b/src/main/java/command/music/PauseCommand.java index ae81008..b7a49f5 100644 --- a/src/main/java/command/music/PauseCommand.java +++ b/src/main/java/command/music/PauseCommand.java @@ -25,9 +25,7 @@ public PauseCommand(NanoClient nanoClient) { @Override protected void execute(CommandEvent event) { - VoiceChannel userVoiceChannel = event.getMember().getVoiceState().getChannel(); - if (userVoiceChannel == null) { - event.reply(":x: | You are not connected to any voice channel"); + if (!nanoClient.getMusicService().ensureVoiceState(event)) { return; } diff --git a/src/main/java/command/music/PlayCommand.java b/src/main/java/command/music/PlayCommand.java index ff86a1f..fc2f882 100644 --- a/src/main/java/command/music/PlayCommand.java +++ b/src/main/java/command/music/PlayCommand.java @@ -27,9 +27,7 @@ public PlayCommand(NanoClient nanoClient) { @Override protected void execute(CommandEvent event) { - VoiceChannel channel = event.getMember().getVoiceState().getChannel(); - if (channel == null) { - event.reply(":x: | You're not connected to any voice channel"); + if (!nanoClient.getMusicService().ensureVoiceState(event)) { return; } @@ -63,7 +61,7 @@ protected void execute(CommandEvent event) { if (connectedChannel == null) { // if not connected to any voice channel, try to join user voice channel. - nanoClient.getMusicService().joinUserVoiceChannel(event); + nanoClient.getMusicService().joinMemberVoiceChannel(event); } diff --git a/src/main/java/command/music/PlayUrlCommand.java b/src/main/java/command/music/PlayUrlCommand.java index 0f702f7..edf7310 100644 --- a/src/main/java/command/music/PlayUrlCommand.java +++ b/src/main/java/command/music/PlayUrlCommand.java @@ -27,9 +27,7 @@ public PlayUrlCommand(NanoClient nanoClient) { @Override protected void execute(CommandEvent event) { - VoiceChannel channel = event.getMember().getVoiceState().getChannel(); - if (channel == null) { - event.reply(":x: | You're not connected to any voice channel"); + if (!nanoClient.getMusicService().ensureVoiceState(event)) { return; } @@ -65,7 +63,7 @@ protected void execute(CommandEvent event) { if (connectedChannel == null) { // if not connected to any voice channel, try to join user voice channel. - nanoClient.getMusicService().joinUserVoiceChannel(event); + nanoClient.getMusicService().joinMemberVoiceChannel(event); } nanoClient.loadAndPlayUrl(musicManager, event.getTextChannel(), args, event.getMember()); diff --git a/src/main/java/command/music/RecommendationCommand.java b/src/main/java/command/music/RecommendationCommand.java index 6fc7e38..e8c9209 100644 --- a/src/main/java/command/music/RecommendationCommand.java +++ b/src/main/java/command/music/RecommendationCommand.java @@ -39,9 +39,7 @@ public RecommendationCommand(NanoClient nanoClient, YoutubeClient youtubeClient) @Override protected void execute(CommandEvent event) { - VoiceChannel channel = event.getMember().getVoiceState().getChannel(); - if (channel == null) { - event.reply(":x: | You're not connected to any voice channel."); + if (!nanoClient.getMusicService().ensureVoiceState(event)) { return; } diff --git a/src/main/java/command/music/RepeatCommand.java b/src/main/java/command/music/RepeatCommand.java index f0f96bf..6782368 100644 --- a/src/main/java/command/music/RepeatCommand.java +++ b/src/main/java/command/music/RepeatCommand.java @@ -3,6 +3,7 @@ import client.NanoClient; import com.jagrosh.jdautilities.command.Command; import com.jagrosh.jdautilities.command.CommandEvent; +import net.dv8tion.jda.api.entities.VoiceChannel; import service.music.GuildMusicManager; import service.music.HelpProcess; import service.music.MusicUtils; @@ -24,12 +25,11 @@ public RepeatCommand(NanoClient nanoClient) { @Override protected void execute(CommandEvent event) { - GuildMusicManager musicManager = nanoClient.getGuildAudioPlayer(event.getGuild()); - if (!nanoClient.getMusicService().isMemberInVoiceState(event.getMember())) { - event.reply("Are you sure you are in voice channel ?"); + if (!nanoClient.getMusicService().ensureVoiceState(event)) { return; } + GuildMusicManager musicManager = nanoClient.getGuildAudioPlayer(event.getGuild()); if (musicManager.player.getPlayingTrack() == null) { event.reply(":x: | Not playing anything"); return; diff --git a/src/main/java/command/music/ResumeCommand.java b/src/main/java/command/music/ResumeCommand.java index d8a2565..114265f 100644 --- a/src/main/java/command/music/ResumeCommand.java +++ b/src/main/java/command/music/ResumeCommand.java @@ -25,9 +25,7 @@ public ResumeCommand(NanoClient nanoClient) { @Override protected void execute(CommandEvent event) { - VoiceChannel userVoiceChannel = event.getMember().getVoiceState().getChannel(); - if (userVoiceChannel == null) { - event.reply(":x: | You are not connected to any voice channel"); + if (!nanoClient.getMusicService().ensureVoiceState(event)) { return; } diff --git a/src/main/java/command/music/ShowGuildStateCommand.java b/src/main/java/command/music/ShowGuildStateCommand.java index e2753b5..8a2c1c6 100644 --- a/src/main/java/command/music/ShowGuildStateCommand.java +++ b/src/main/java/command/music/ShowGuildStateCommand.java @@ -27,13 +27,12 @@ public ShowGuildStateCommand(NanoClient nanoClient) { @Override protected void execute(CommandEvent event) { - GuildMusicManager musicManager = nanoClient.getGuildAudioPlayer(event.getGuild()); - // Ensure Voice - if (!nanoClient.getMusicService().isMemberInVoiceState(event.getMember())) { - event.reply(":x: | Are you sure you are in voice channel ?"); + if (!nanoClient.getMusicService().ensureVoiceState(event)) { return; } + + GuildMusicManager musicManager = nanoClient.getGuildAudioPlayer(event.getGuild()); if (musicManager.player.getPlayingTrack() == null) { event.reply(":x: | Not playing anything"); return; diff --git a/src/main/java/command/music/ShowPaginatedQueueCommand.java b/src/main/java/command/music/ShowPaginatedQueueCommand.java index 2ddc985..77ce01f 100644 --- a/src/main/java/command/music/ShowPaginatedQueueCommand.java +++ b/src/main/java/command/music/ShowPaginatedQueueCommand.java @@ -31,13 +31,12 @@ public ShowPaginatedQueueCommand(NanoClient nanoClient) { @Override protected void execute(CommandEvent event) { - GuildMusicManager musicManager = nanoClient.getGuildAudioPlayer(event.getGuild()); - // Ensure Voice - if (!nanoClient.getMusicService().isMemberInVoiceState(event.getMember())) { - event.reply("Are you sure you are in voice channel ?"); + if (!nanoClient.getMusicService().ensureVoiceState(event)) { return; } + + GuildMusicManager musicManager = nanoClient.getGuildAudioPlayer(event.getGuild()); if (musicManager.player.getPlayingTrack() == null) { event.reply("Not playing anything"); return; diff --git a/src/main/java/command/music/ShuffleCommand.java b/src/main/java/command/music/ShuffleCommand.java index aba9c32..e937268 100644 --- a/src/main/java/command/music/ShuffleCommand.java +++ b/src/main/java/command/music/ShuffleCommand.java @@ -32,9 +32,7 @@ public ShuffleCommand(NanoClient nanoClient) { @Override protected void execute(CommandEvent event) { - VoiceChannel userVoiceChannel = event.getMember().getVoiceState().getChannel(); - if (userVoiceChannel == null) { - event.reply(":x: | You are not connected to any voice channel"); + if (!nanoClient.getMusicService().ensureVoiceState(event)) { return; } diff --git a/src/main/java/command/music/SkipCommand.java b/src/main/java/command/music/SkipCommand.java index 334ffca..717cf03 100644 --- a/src/main/java/command/music/SkipCommand.java +++ b/src/main/java/command/music/SkipCommand.java @@ -27,13 +27,11 @@ public SkipCommand(NanoClient nanoClient) { @Override protected void execute(CommandEvent event) { - GuildMusicManager musicManager = nanoClient.getGuildAudioPlayer(event.getGuild()); - - if (event.getMember().getVoiceState().getChannel() == null) { - event.reply(":x: | You are not connected to any voice channel"); + if (!nanoClient.getMusicService().ensureVoiceState(event)) { return; } + GuildMusicManager musicManager = nanoClient.getGuildAudioPlayer(event.getGuild()); // Check if player is currently playing audio if (musicManager.player.getPlayingTrack() == null) { event.getChannel().sendMessage(":x: | Not playing anything").queue(); diff --git a/src/main/java/command/music/VolumeCommand.java b/src/main/java/command/music/VolumeCommand.java index 7cee160..29cf52a 100644 --- a/src/main/java/command/music/VolumeCommand.java +++ b/src/main/java/command/music/VolumeCommand.java @@ -48,7 +48,7 @@ protected void execute(CommandEvent event) { return; } musicManager.player.setVolume(volume); - } catch (Exception e) { + } catch (NumberFormatException e) { event.reply(":x: | Invalid volume number, command e.g. `" + event.getClient().getPrefix() + "volume 25` to change volume to 25%"); return; diff --git a/src/main/java/command/music/YoutubeSearchCommand.java b/src/main/java/command/music/YoutubeSearchCommand.java index ce0d81e..7b22c9f 100644 --- a/src/main/java/command/music/YoutubeSearchCommand.java +++ b/src/main/java/command/music/YoutubeSearchCommand.java @@ -6,6 +6,7 @@ import client.NanoClient; import com.jagrosh.jdautilities.command.Command; import com.jagrosh.jdautilities.command.CommandEvent; +import net.dv8tion.jda.api.entities.VoiceChannel; import service.music.CustomEmbedBuilder; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; @@ -43,6 +44,11 @@ public YoutubeSearchCommand(NanoClient nano, YoutubeClient youtubeClient) @Override protected void execute(CommandEvent event) { + if (!this.nano.getMusicService().ensureVoiceState(event)) + { + return; + } + String keywords = event.getArgs(); if (keywords.isEmpty()) { CustomEmbedBuilder embedBuilder = new CustomEmbedBuilder(); @@ -116,14 +122,12 @@ protected void execute(CommandEvent event) List finalVideos = videos; this.nano.getWaiter().waitForEvent( GuildMessageReceivedEvent.class, - e -> e.getChannel().equals(event.getChannel()) - && e.getAuthor().getId().equals(event.getAuthor().getId()) - , + e -> e.getChannel().equals(event.getChannel())&& + e.getAuthor().getId().equals(event.getAuthor().getId()), e -> { - if (!this.nano.getMusicService().joinUserVoiceChannel(event)) + if (!this.nano.getMusicService().ensureVoiceState(event)) { - event.reply(":x: | You are not connected to any voice channel."); return; } @@ -158,8 +162,9 @@ protected void execute(CommandEvent event) this.nano.loadAndPlayUrl(musicManager, event.getTextChannel(), finalVideos.get(entry).getUrl(), event.getMember()); }, - 10, TimeUnit.SECONDS, () -> - msg.get().delete().queue() + 10, + TimeUnit.SECONDS, + () -> msg.get().delete().queue() ); } } diff --git a/src/main/java/listener/MemberVoiceListener.java b/src/main/java/listener/MemberVoiceListener.java index 26299e8..61c9244 100644 --- a/src/main/java/listener/MemberVoiceListener.java +++ b/src/main/java/listener/MemberVoiceListener.java @@ -104,7 +104,6 @@ public void onGuildVoiceMove(@NotNull GuildVoiceMoveEvent event) { else { GuildMusicManager musicManager = nanoClient.getGuildAudioPlayer(event.getGuild()); if (musicManager.isWaitingForUser()) { - System.out.println("RESUME & SET WAITING FALSE"); musicManager.setWaitingForUser(false); musicManager.player.setPaused(false); musicManager.getWaitingFuture().cancel(true); @@ -170,17 +169,6 @@ public void onGuildVoiceDeafen(@NotNull GuildVoiceDeafenEvent event) { if (event.getMember().hasPermission(Permission.VOICE_DEAF_OTHERS)) { event.getGuild().getSelfMember().deafen(true).queue(); } -// else { -// TextChannel textChannel = nanoClient.getGuildAudioPlayer(event.getGuild()).scheduler.textChannel; -// -// CustomEmbedBuilder embedBuilder = new CustomEmbedBuilder(); -// embedBuilder.addField(":warning: Missing Permission: `Deafen Members`!", -// "Please don't undeafen me! I work better by being deafened because: " + -// "Less lag, more clear, better quality, and doesn't randomly disconnect", -// true); -// -// textChannel.sendMessage(embedBuilder.build()).queue(); -// } } } diff --git a/src/main/java/listener/MusicMessageListener.java b/src/main/java/listener/MusicMessageListener.java index 3785a87..4ae932e 100644 --- a/src/main/java/listener/MusicMessageListener.java +++ b/src/main/java/listener/MusicMessageListener.java @@ -55,7 +55,7 @@ public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) { if (".play".equals(command[0]) && command.length == 2) { GuildMusicManager musicManager = getGuildAudioPlayer(event.getGuild()); - if (musicService.joinUserVoiceChannel(event)) { + if (musicService.joinMemberVoiceChannel(event)) { // Set default volume value musicManager.player.setVolume(15); musicService.loadAndPlay(playerManager, musicManager, event.getChannel(), diff --git a/src/main/java/service/music/MusicService.java b/src/main/java/service/music/MusicService.java index 10f0492..87251c8 100644 --- a/src/main/java/service/music/MusicService.java +++ b/src/main/java/service/music/MusicService.java @@ -9,9 +9,14 @@ import database.Entity.ClassicUser; import net.dv8tion.jda.api.entities.*; import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; +import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; import net.dv8tion.jda.api.managers.AudioManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class MusicService { + private static final Logger log = LoggerFactory.getLogger(MusicService.class); + public void loadAndPlay(AudioPlayerManager playerManager, GuildMusicManager musicManager, final TextChannel channel, final String trackUrl, User requester) { playerManager.loadItemOrdered(musicManager, trackUrl, new AudioLoadResultHandler() { @@ -60,7 +65,7 @@ public void adjustVolume(GuildMusicManager musicManager, int volume) { musicManager.player.setVolume(volume); } - public boolean joinUserVoiceChannel(GuildMessageReceivedEvent event) { + public boolean joinMemberVoiceChannel(GuildMessageReceivedEvent event) { Member member = event.getMember(); VoiceChannel voiceChannel = member.getVoiceState().getChannel(); if (voiceChannel == null){ @@ -69,25 +74,49 @@ public boolean joinUserVoiceChannel(GuildMessageReceivedEvent event) { } Guild guild = event.getGuild(); AudioManager audioManager = guild.getAudioManager(); - audioManager.openAudioConnection(voiceChannel); + try { + audioManager.openAudioConnection(voiceChannel); + } catch (IllegalArgumentException | InsufficientPermissionException joinException) { + log.error(joinException.getMessage()); + return false; + } return true; } - public boolean joinUserVoiceChannel(CommandEvent event) { + public VoiceChannel joinMemberVoiceChannel(CommandEvent event) { + // Redundant Code: check member voice state Member member = event.getMember(); VoiceChannel voiceChannel = member.getVoiceState().getChannel(); if (voiceChannel == null){ - return false; + event.reply(":x: | You are not connected to any voice channel"); + return null; } + Guild guild = event.getGuild(); AudioManager audioManager = guild.getAudioManager(); - audioManager.openAudioConnection(voiceChannel); - return true; + try { + audioManager.openAudioConnection(voiceChannel); + } catch (IllegalArgumentException | InsufficientPermissionException joinException) { + log.error(joinException.getMessage()); + CustomEmbedBuilder embedBuilder = new CustomEmbedBuilder(); + embedBuilder.addField(":warning: Missing Permission: VOICE_CONNECT", + "I don't have permission to connect to voice channel", + true); + event.reply(embedBuilder.build()); + return null; + } + return voiceChannel; } - public void joinVoiceChannel(Guild guild, VoiceChannel voiceChannel){ + public boolean joinVoiceChannel(Guild guild, VoiceChannel voiceChannel){ AudioManager audioManager = guild.getAudioManager(); - audioManager.openAudioConnection(voiceChannel); + try { + audioManager.openAudioConnection(voiceChannel); + } catch (IllegalArgumentException | InsufficientPermissionException joinException) { + log.error(joinException.getMessage()); + return false; + } + return true; } public void leaveVoiceChannel(Guild guild, GuildMusicManager musicManager){ @@ -99,11 +128,37 @@ public void leaveVoiceChannel(Guild guild, GuildMusicManager musicManager){ musicManager.player.destroy(); } - public boolean isMemberInVoiceState(Member member) { + public boolean isMemberConnectedToVoice(Member member) { VoiceChannel voiceChannel = member.getVoiceState().getChannel(); - if (voiceChannel == null){ + return voiceChannel != null; + } + + /** + * Check member's voice state, invoke before using command, used by some music commands. + * @param event + * @return + */ + public boolean ensureVoiceState(CommandEvent event) { + if (!this.isMemberConnectedToVoice(event.getMember())) { + event.reply(":x: | You are not connected to any voice channel"); return false; } + else + { + VoiceChannel selfVoiceChannel = event.getGuild().getAudioManager().getConnectedChannel(); + + if (selfVoiceChannel == null) + { + selfVoiceChannel = this.joinMemberVoiceChannel(event); + return selfVoiceChannel != null; + } + // Check user's voice channel. + else if (!selfVoiceChannel.getId().equals(event.getMember().getVoiceState().getChannel().getId())) + { + event.reply(":x: | You are not connected to **my voice channel**"); + return false; + } + } return true; } diff --git a/src/main/java/service/music/PremiumService.java b/src/main/java/service/music/PremiumService.java index ebf14db..168936d 100644 --- a/src/main/java/service/music/PremiumService.java +++ b/src/main/java/service/music/PremiumService.java @@ -1,10 +1,13 @@ package service.music; +import com.mysql.cj.jdbc.exceptions.MysqlDataTruncation; import database.*; import io.donatebot.api.DBClient; import io.donatebot.api.Donation; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.User; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.sql.SQLException; import java.util.concurrent.CompletableFuture; @@ -12,6 +15,7 @@ public class PremiumService { + private static final Logger log = LoggerFactory.getLogger(PremiumService.class); private String apiKey; private String serverID; @@ -62,6 +66,10 @@ public static void addHistory(String title, String url, Guild guild, User user) { userHistoryModel.addUserHistory(user.getIdLong(), url, title); } + catch (MysqlDataTruncation e) + { + log.error(e.getMessage()); + } catch (SQLException e) { e.printStackTrace();