From a295002feee2987a93d813ab8f74e3b59863cb29 Mon Sep 17 00:00:00 2001 From: SebClem Date: Thu, 23 Jun 2022 12:45:58 +0200 Subject: [PATCH] :hammer: Add disconnect endpoint --- .../Api/Controllers/AudioController.java | 14 +++- .../net/Broken/Api/Data/Music/Status.java | 2 + .../CustomMethodSecurityExpressionRoot.java | 18 +++++ .../net/Broken/Api/Services/AudioService.java | 78 +++++++++++-------- src/main/java/net/Broken/BotListener.java | 2 +- src/main/java/net/Broken/audio/AudioM.java | 21 ++--- src/main/resources/log4j2.xml | 10 +-- 7 files changed, 94 insertions(+), 51 deletions(-) diff --git a/src/main/java/net/Broken/Api/Controllers/AudioController.java b/src/main/java/net/Broken/Api/Controllers/AudioController.java index daea520..5539ffb 100644 --- a/src/main/java/net/Broken/Api/Controllers/AudioController.java +++ b/src/main/java/net/Broken/Api/Controllers/AudioController.java @@ -23,7 +23,7 @@ public class AudioController { @GetMapping("/{guildId}/status") @PreAuthorize("isInGuild(#guildId)") - public Status getMusicStatus(@PathVariable String guildId, Authentication authentication){ + public Status getMusicStatus(@PathVariable String guildId, Authentication authentication) { JwtPrincipal principal = (JwtPrincipal) authentication.getPrincipal(); return audioService.getGuildAudioStatus(guildId, principal.user().getDiscordId()); } @@ -31,7 +31,15 @@ public class AudioController { @PostMapping("/{guildId}/connect") @PreAuthorize("isInGuild(#guildId) && canInteractWithVoiceChannel(#guildId, #body)") - public ResponseEntity connect(@PathVariable String guildId, @RequestBody Connect body){ - return audioService.connect(guildId, body); + public ResponseEntity connect(@PathVariable String guildId, @RequestBody Connect body, Authentication authentication) { + JwtPrincipal principal = (JwtPrincipal) authentication.getPrincipal(); + return audioService.connect(guildId, body, principal.user().getDiscordId()); + } + + @PostMapping("/{guildId}/disconnect") + @PreAuthorize("isInGuild(#guildId) && canInteractWithVoiceChannel(#guildId)") + public ResponseEntity disconnect(@PathVariable String guildId, Authentication authentication) { + JwtPrincipal principal = (JwtPrincipal) authentication.getPrincipal(); + return audioService.disconnect(guildId, principal.user().getDiscordId()); } } diff --git a/src/main/java/net/Broken/Api/Data/Music/Status.java b/src/main/java/net/Broken/Api/Data/Music/Status.java index 5f64836..99fafa9 100644 --- a/src/main/java/net/Broken/Api/Data/Music/Status.java +++ b/src/main/java/net/Broken/Api/Data/Music/Status.java @@ -2,10 +2,12 @@ package net.Broken.Api.Data.Music; import com.fasterxml.jackson.annotation.JsonInclude; import net.Broken.Api.Data.Guild.Channel; +import net.dv8tion.jda.api.audio.hooks.ConnectionStatus; @JsonInclude(JsonInclude.Include.NON_NULL) public record Status( Boolean connected, + ConnectionStatus connectionStatus, Channel channel, Boolean canView, Boolean canInteract, diff --git a/src/main/java/net/Broken/Api/Security/Expression/CustomMethodSecurityExpressionRoot.java b/src/main/java/net/Broken/Api/Security/Expression/CustomMethodSecurityExpressionRoot.java index 894a4fb..fc87d0c 100644 --- a/src/main/java/net/Broken/Api/Security/Expression/CustomMethodSecurityExpressionRoot.java +++ b/src/main/java/net/Broken/Api/Security/Expression/CustomMethodSecurityExpressionRoot.java @@ -4,6 +4,7 @@ import net.Broken.Api.Data.Music.Connect; import net.Broken.Api.Security.Data.JwtPrincipal; import net.Broken.MainBot; import net.Broken.Tools.CacheTools; +import net.Broken.audio.AudioM; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; @@ -58,6 +59,23 @@ public class CustomMethodSecurityExpressionRoot && member.hasPermission(channel, Permission.VOICE_SPEAK); } + public boolean canInteractWithVoiceChannel(String guildId) { + JwtPrincipal jwtPrincipal = (JwtPrincipal) authentication.getPrincipal(); + Guild guild = MainBot.jda.getGuildById(guildId); + AudioM audioM = AudioM.getInstance(guild); + VoiceChannel channel = audioM.getPlayedChanel(); + + if (channel == null) { + return false; + } + + Member member = guild.getMemberById(jwtPrincipal.user().getDiscordId()); + return (member.hasPermission(channel, Permission.VOICE_CONNECT) + || member.getVoiceState() != null + && member.getVoiceState().getChannel() == channel) + && member.hasPermission(channel, Permission.VOICE_SPEAK); + } + @Override public void setFilterObject(Object filterObject) { this.filterObject = filterObject; diff --git a/src/main/java/net/Broken/Api/Services/AudioService.java b/src/main/java/net/Broken/Api/Services/AudioService.java index 540a302..cb95755 100644 --- a/src/main/java/net/Broken/Api/Services/AudioService.java +++ b/src/main/java/net/Broken/Api/Services/AudioService.java @@ -9,73 +9,87 @@ import net.Broken.MainBot; import net.Broken.audio.AudioM; import net.Broken.audio.UserAudioTrack; import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.audio.hooks.ConnectionStatus; import net.dv8tion.jda.api.entities.Guild; -import net.dv8tion.jda.api.entities.GuildVoiceState; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.VoiceChannel; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; @Service public class AudioService { + + final Logger logger = LogManager.getLogger(); + public Status getGuildAudioStatus(String guildId, String userId) { Guild guild = MainBot.jda.getGuildById(guildId); Member member = guild.getMemberById(userId); - GuildVoiceState voiceState = guild.getSelfMember().getVoiceState(); - if (voiceState != null) { - VoiceChannel channel = voiceState.getChannel(); - if (channel != null) { + + VoiceChannel channel = guild.getAudioManager().getConnectedChannel(); + ConnectionStatus status = guild.getAudioManager().getConnectionStatus(); + if (channel != null) { // The user can view the audio status if: // -> He can view the voice channel // -> OR He can *not* view the voice channel, but he is connected to this voice channel - boolean canView = member.hasPermission(channel, Permission.VIEW_CHANNEL) - || (member.getVoiceState() != null - && member.getVoiceState().getChannel() == channel); - if (canView) { + boolean canView = member.hasPermission(channel, Permission.VIEW_CHANNEL) + || (member.getVoiceState() != null + && member.getVoiceState().getChannel() == channel); + AudioM audioM = AudioM.getInstance(guild); + + if (canView) { // The user can interact with the audio if: // -> He can connect to this voice channel // -> OR he is connected to this voice channel // -> AND He can speak in this voice channel - boolean canInteract = (member.hasPermission(channel, Permission.VOICE_CONNECT) - || member.getVoiceState() != null - && member.getVoiceState().getChannel() == channel) - && member.hasPermission(channel, Permission.VOICE_SPEAK); + boolean canInteract = (member.hasPermission(channel, Permission.VOICE_CONNECT) + || member.getVoiceState() != null + && member.getVoiceState().getChannel() == channel) + && member.hasPermission(channel, Permission.VOICE_SPEAK); - AudioM audioM = AudioM.getInstance(guild); - boolean stopped = audioM.getGuildAudioPlayer().player.getPlayingTrack() == null; - PlayBackInfo playBackInfo; - if (!stopped) { - boolean paused = audioM.getGuildAudioPlayer().player.isPaused(); - long position = audioM.getGuildAudioPlayer().player.getPlayingTrack().getPosition(); - UserAudioTrack userAudioTrack = audioM.getGuildAudioPlayer().scheduler.getCurrentPlayingTrack(); - playBackInfo = new PlayBackInfo(paused, false, position, new TrackInfo(userAudioTrack)); + boolean stopped = audioM.getGuildAudioPlayer().player.getPlayingTrack() == null; + PlayBackInfo playBackInfo; + if (!stopped) { + boolean paused = audioM.getGuildAudioPlayer().player.isPaused(); + long position = audioM.getGuildAudioPlayer().player.getPlayingTrack().getPosition(); + UserAudioTrack userAudioTrack = audioM.getGuildAudioPlayer().scheduler.getCurrentPlayingTrack(); - } else { - playBackInfo = new PlayBackInfo(false, true, null, null); - } - Channel channelApi = new Channel(channel.getId(), channel.getName()); - return new Status(true, channelApi, true, canInteract, playBackInfo); + playBackInfo = new PlayBackInfo(paused, false, position, new TrackInfo(userAudioTrack)); } else { - return new Status(true, null, false, false, null); + playBackInfo = new PlayBackInfo(false, true, null, null); } + Channel channelApi = new Channel(channel.getId(), channel.getName()); + return new Status(true, status, channelApi, true, canInteract, playBackInfo); - + } else { + return new Status(true, status, null, false, false, null); } } - return new Status(false, null, null, null, null); + return new Status(false, status, null, null, null, null); } - - public ResponseEntity connect(String guildId, Connect body){ + + public ResponseEntity connect(String guildId, Connect body, String userId) { Guild guild = MainBot.jda.getGuildById(guildId); AudioM audioM = AudioM.getInstance(guild); VoiceChannel voiceChannel = guild.getVoiceChannelById(body.channelId()); audioM.getGuildAudioPlayer(); guild.getAudioManager().openAudioConnection(voiceChannel); audioM.setPlayedChanel(voiceChannel); - return new ResponseEntity<>("OK", HttpStatus.OK); + + Status status = getGuildAudioStatus(guildId, userId); + return new ResponseEntity<>(status, HttpStatus.OK); + } + + public ResponseEntity disconnect(String guildId, String userId) { + Guild guild = MainBot.jda.getGuildById(guildId); + AudioM audioM = AudioM.getInstance(guild); + audioM.disconnect(); + Status status = getGuildAudioStatus(guildId, userId); + return new ResponseEntity<>(status, HttpStatus.OK); } } diff --git a/src/main/java/net/Broken/BotListener.java b/src/main/java/net/Broken/BotListener.java index 589bb48..6627756 100644 --- a/src/main/java/net/Broken/BotListener.java +++ b/src/main/java/net/Broken/BotListener.java @@ -153,7 +153,7 @@ public class BotListener extends ListenerAdapter { case "play" -> audioM.resume(event); case "next" -> audioM.skipTrack(event); case "stop" -> audioM.stop(event); - case "disconnect" -> audioM.disconect(event); + case "disconnect" -> audioM.disconnect(event); } } diff --git a/src/main/java/net/Broken/audio/AudioM.java b/src/main/java/net/Broken/audio/AudioM.java index 28f7a79..7409a8e 100644 --- a/src/main/java/net/Broken/audio/AudioM.java +++ b/src/main/java/net/Broken/audio/AudioM.java @@ -18,7 +18,6 @@ import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent; import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; import net.dv8tion.jda.api.interactions.components.ActionRow; import net.dv8tion.jda.api.interactions.components.Button; -import net.dv8tion.jda.api.interactions.components.ComponentLayout; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -391,13 +390,8 @@ public class AudioM { } } - public void disconect(GenericInteractionCreateEvent event){ - GuildMusicManager musicManager = getGuildAudioPlayer(); - musicManager.scheduler.stop(); - musicManager.scheduler.flush(); - playedChanel = null; - guild.getAudioManager().closeAudioConnection(); - clearLastButton(); + public void disconnect(GenericInteractionCreateEvent event){ + disconnect(); Message message = new MessageBuilder().setEmbeds( EmbedMessageUtils.buildStandar( new EmbedBuilder() @@ -408,6 +402,15 @@ public class AudioM { event.getHook().sendMessage(message).queue(); } + public void disconnect(){ + GuildMusicManager musicManager = getGuildAudioPlayer(); + musicManager.scheduler.stop(); + musicManager.scheduler.flush(); + playedChanel = null; + guild.getAudioManager().closeAudioConnection(); + clearLastButton(); + } + /** * Stop current playing track and flush playlist (no confirmation message) */ @@ -416,8 +419,6 @@ public class AudioM { GuildMusicManager musicManager = getGuildAudioPlayer(); musicManager.scheduler.stop(); musicManager.scheduler.flush(); - playedChanel = null; - guild.getAudioManager().closeAudioConnection(); clearLastButton(); } diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml index 228b4d9..db13abd 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -38,11 +38,11 @@ - - - - - + + + + +