🔨 Add disconnect endpoint

This commit is contained in:
SebClem 2022-06-23 12:45:58 +02:00
parent c0146fa0c3
commit a295002fee
Signed by: sebclem
GPG Key ID: 5A4308F6A359EA50
7 changed files with 94 additions and 51 deletions

View File

@ -23,7 +23,7 @@ public class AudioController {
@GetMapping("/{guildId}/status") @GetMapping("/{guildId}/status")
@PreAuthorize("isInGuild(#guildId)") @PreAuthorize("isInGuild(#guildId)")
public Status getMusicStatus(@PathVariable String guildId, Authentication authentication){ public Status getMusicStatus(@PathVariable String guildId, Authentication authentication) {
JwtPrincipal principal = (JwtPrincipal) authentication.getPrincipal(); JwtPrincipal principal = (JwtPrincipal) authentication.getPrincipal();
return audioService.getGuildAudioStatus(guildId, principal.user().getDiscordId()); return audioService.getGuildAudioStatus(guildId, principal.user().getDiscordId());
} }
@ -31,7 +31,15 @@ public class AudioController {
@PostMapping("/{guildId}/connect") @PostMapping("/{guildId}/connect")
@PreAuthorize("isInGuild(#guildId) && canInteractWithVoiceChannel(#guildId, #body)") @PreAuthorize("isInGuild(#guildId) && canInteractWithVoiceChannel(#guildId, #body)")
public ResponseEntity<String> connect(@PathVariable String guildId, @RequestBody Connect body){ public ResponseEntity<Status> connect(@PathVariable String guildId, @RequestBody Connect body, Authentication authentication) {
return audioService.connect(guildId, body); JwtPrincipal principal = (JwtPrincipal) authentication.getPrincipal();
return audioService.connect(guildId, body, principal.user().getDiscordId());
}
@PostMapping("/{guildId}/disconnect")
@PreAuthorize("isInGuild(#guildId) && canInteractWithVoiceChannel(#guildId)")
public ResponseEntity<Status> disconnect(@PathVariable String guildId, Authentication authentication) {
JwtPrincipal principal = (JwtPrincipal) authentication.getPrincipal();
return audioService.disconnect(guildId, principal.user().getDiscordId());
} }
} }

View File

@ -2,10 +2,12 @@ package net.Broken.Api.Data.Music;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import net.Broken.Api.Data.Guild.Channel; import net.Broken.Api.Data.Guild.Channel;
import net.dv8tion.jda.api.audio.hooks.ConnectionStatus;
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public record Status( public record Status(
Boolean connected, Boolean connected,
ConnectionStatus connectionStatus,
Channel channel, Channel channel,
Boolean canView, Boolean canView,
Boolean canInteract, Boolean canInteract,

View File

@ -4,6 +4,7 @@ import net.Broken.Api.Data.Music.Connect;
import net.Broken.Api.Security.Data.JwtPrincipal; import net.Broken.Api.Security.Data.JwtPrincipal;
import net.Broken.MainBot; import net.Broken.MainBot;
import net.Broken.Tools.CacheTools; import net.Broken.Tools.CacheTools;
import net.Broken.audio.AudioM;
import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Member;
@ -58,6 +59,23 @@ public class CustomMethodSecurityExpressionRoot
&& member.hasPermission(channel, Permission.VOICE_SPEAK); && 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 @Override
public void setFilterObject(Object filterObject) { public void setFilterObject(Object filterObject) {
this.filterObject = filterObject; this.filterObject = filterObject;

View File

@ -9,73 +9,87 @@ import net.Broken.MainBot;
import net.Broken.audio.AudioM; import net.Broken.audio.AudioM;
import net.Broken.audio.UserAudioTrack; import net.Broken.audio.UserAudioTrack;
import net.dv8tion.jda.api.Permission; 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.Guild;
import net.dv8tion.jda.api.entities.GuildVoiceState;
import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.VoiceChannel; 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.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Service @Service
public class AudioService { public class AudioService {
final Logger logger = LogManager.getLogger();
public Status getGuildAudioStatus(String guildId, String userId) { public Status getGuildAudioStatus(String guildId, String userId) {
Guild guild = MainBot.jda.getGuildById(guildId); Guild guild = MainBot.jda.getGuildById(guildId);
Member member = guild.getMemberById(userId); Member member = guild.getMemberById(userId);
GuildVoiceState voiceState = guild.getSelfMember().getVoiceState();
if (voiceState != null) {
VoiceChannel channel = voiceState.getChannel(); VoiceChannel channel = guild.getAudioManager().getConnectedChannel();
if (channel != null) { ConnectionStatus status = guild.getAudioManager().getConnectionStatus();
if (channel != null) {
// The user can view the audio status if: // The user can view the audio status if:
// -> He can view the voice channel // -> He can view the voice channel
// -> OR He can *not* view the voice channel, but he is connected to this 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) boolean canView = member.hasPermission(channel, Permission.VIEW_CHANNEL)
|| (member.getVoiceState() != null || (member.getVoiceState() != null
&& member.getVoiceState().getChannel() == channel); && member.getVoiceState().getChannel() == channel);
if (canView) { AudioM audioM = AudioM.getInstance(guild);
if (canView) {
// The user can interact with the audio if: // The user can interact with the audio if:
// -> He can connect to this voice channel // -> He can connect to this voice channel
// -> OR he is connected to this voice channel // -> OR he is connected to this voice channel
// -> AND He can speak in this voice channel // -> AND He can speak in this voice channel
boolean canInteract = (member.hasPermission(channel, Permission.VOICE_CONNECT) boolean canInteract = (member.hasPermission(channel, Permission.VOICE_CONNECT)
|| member.getVoiceState() != null || member.getVoiceState() != null
&& member.getVoiceState().getChannel() == channel) && member.getVoiceState().getChannel() == channel)
&& member.hasPermission(channel, Permission.VOICE_SPEAK); && 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(paused, false, position, new TrackInfo(userAudioTrack));
playBackInfo = new PlayBackInfo(false, true, null, null);
}
Channel channelApi = new Channel(channel.getId(), channel.getName());
return new Status(true, channelApi, true, canInteract, playBackInfo);
} else { } 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<String> connect(String guildId, Connect body){ public ResponseEntity<Status> connect(String guildId, Connect body, String userId) {
Guild guild = MainBot.jda.getGuildById(guildId); Guild guild = MainBot.jda.getGuildById(guildId);
AudioM audioM = AudioM.getInstance(guild); AudioM audioM = AudioM.getInstance(guild);
VoiceChannel voiceChannel = guild.getVoiceChannelById(body.channelId()); VoiceChannel voiceChannel = guild.getVoiceChannelById(body.channelId());
audioM.getGuildAudioPlayer(); audioM.getGuildAudioPlayer();
guild.getAudioManager().openAudioConnection(voiceChannel); guild.getAudioManager().openAudioConnection(voiceChannel);
audioM.setPlayedChanel(voiceChannel); audioM.setPlayedChanel(voiceChannel);
return new ResponseEntity<>("OK", HttpStatus.OK);
Status status = getGuildAudioStatus(guildId, userId);
return new ResponseEntity<>(status, HttpStatus.OK);
}
public ResponseEntity<Status> 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);
} }
} }

View File

@ -153,7 +153,7 @@ public class BotListener extends ListenerAdapter {
case "play" -> audioM.resume(event); case "play" -> audioM.resume(event);
case "next" -> audioM.skipTrack(event); case "next" -> audioM.skipTrack(event);
case "stop" -> audioM.stop(event); case "stop" -> audioM.stop(event);
case "disconnect" -> audioM.disconect(event); case "disconnect" -> audioM.disconnect(event);
} }
} }

View File

@ -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.events.interaction.SlashCommandEvent;
import net.dv8tion.jda.api.interactions.components.ActionRow; import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.Button; 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.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -391,13 +390,8 @@ public class AudioM {
} }
} }
public void disconect(GenericInteractionCreateEvent event){ public void disconnect(GenericInteractionCreateEvent event){
GuildMusicManager musicManager = getGuildAudioPlayer(); disconnect();
musicManager.scheduler.stop();
musicManager.scheduler.flush();
playedChanel = null;
guild.getAudioManager().closeAudioConnection();
clearLastButton();
Message message = new MessageBuilder().setEmbeds( Message message = new MessageBuilder().setEmbeds(
EmbedMessageUtils.buildStandar( EmbedMessageUtils.buildStandar(
new EmbedBuilder() new EmbedBuilder()
@ -408,6 +402,15 @@ public class AudioM {
event.getHook().sendMessage(message).queue(); 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) * Stop current playing track and flush playlist (no confirmation message)
*/ */
@ -416,8 +419,6 @@ public class AudioM {
GuildMusicManager musicManager = getGuildAudioPlayer(); GuildMusicManager musicManager = getGuildAudioPlayer();
musicManager.scheduler.stop(); musicManager.scheduler.stop();
musicManager.scheduler.flush(); musicManager.scheduler.flush();
playedChanel = null;
guild.getAudioManager().closeAudioConnection();
clearLastButton(); clearLastButton();
} }

View File

@ -38,11 +38,11 @@
<AppenderRef ref="current"/> <AppenderRef ref="current"/>
<AppenderRef ref="RollingFile"/> <AppenderRef ref="RollingFile"/>
</Logger> </Logger>
<Logger name="org.springframework.security" level="${env:LOG_LEVEL}" additivity="false"> <!-- <Logger name="org.springframework.security" level="${env:LOG_LEVEL}" additivity="false">-->
<AppenderRef ref="Console"/> <!-- <AppenderRef ref="Console"/>-->
<AppenderRef ref="current"/> <!-- <AppenderRef ref="current"/>-->
<AppenderRef ref="RollingFile"/> <!-- <AppenderRef ref="RollingFile"/>-->
</Logger> <!-- </Logger>-->
<Root level="debug"> <Root level="debug">
<AppenderRef ref="Console" level="info"/> <AppenderRef ref="Console" level="info"/>
<AppenderRef ref="RollingFile" level="info"/> <AppenderRef ref="RollingFile" level="info"/>