fix(MusicManager): missing checks and reworked logic of who is the DJ

DJ is now the first user who makes the bot connect to a voice channel and doesn't change until the voice channel changes
This commit is contained in:
anthorob committed 2024-10-09 12:27:41 -04:00
1 parent 0ccc2d5e9c
commit bcf78920e9
25 files changed
+278 -356

No files matched your search

+1 -1
View File
@@ -1,4 +1,4 @@
FROM eclipse-temurin:17-jdk-alpine as build FROM eclipse-temurin:17-jdk-alpine AS build
COPY .mvn/ .mvn COPY .mvn/ .mvn
COPY mvnw pom.xml ./ COPY mvnw pom.xml ./
+3 -3
View File
@@ -101,17 +101,17 @@
<dependency> <dependency>
<groupId>net.dv8tion</groupId> <groupId>net.dv8tion</groupId>
<artifactId>JDA</artifactId> <artifactId>JDA</artifactId>
<version>5.1.0</version> <version>5.1.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>dev.arbjerg</groupId> <groupId>dev.arbjerg</groupId>
<artifactId>lavaplayer</artifactId> <artifactId>lavaplayer</artifactId>
<version>2.2.1</version> <version>2.2.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>dev.lavalink.youtube</groupId> <groupId>dev.lavalink.youtube</groupId>
<artifactId>v2</artifactId> <artifactId>v2</artifactId>
<version>1.7.2</version> <version>1.8.3</version>
</dependency> </dependency>
<dependency> <dependency>
@@ -52,10 +52,10 @@ public class BitconnectCommand extends AbstractMusicCommand {
@Override @Override
public CommandExecutionResult execute(SlashCommandContext context) { public CommandExecutionResult execute(SlashCommandContext context) {
MusicManager player = MusicManager.get(context.getGuild()); MusicManager manager = MusicManager.get(context.getGuild());
context.ephemeral(); context.ephemeral();
player.play("https://www.youtube.com/watch?v=e5nyQmaq4k4", context, true); manager.play("https://www.youtube.com/watch?v=e5nyQmaq4k4", context, true);
return CommandExecutionResult.success("Ready to invest?"); return CommandExecutionResult.success("Ready to invest?");
} }
} }
@@ -7,11 +7,9 @@ package me.bobert.netneutrality.command.music;
*/ */
import me.bobert.netneutrality.command.AbstractMusicCommand; import me.bobert.netneutrality.command.AbstractMusicCommand;
import me.bobert.netneutrality.context.MessageCommandContext;
import me.bobert.netneutrality.context.SlashCommandContext; import me.bobert.netneutrality.context.SlashCommandContext;
import me.bobert.netneutrality.core.command.CommandExecutionResult; import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.music.MusicManager; import me.bobert.netneutrality.music.MusicManager;
import me.bobert.netneutrality.utils.MessageFunction;
import me.bobert.netneutrality.utils.MusicUtils; import me.bobert.netneutrality.utils.MusicUtils;
import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData;
@@ -42,58 +40,16 @@ public class ClearQueueCommand extends AbstractMusicCommand {
} }
@Override
public CommandExecutionResult execute(MessageCommandContext context) {
MusicManager player = MusicManager.get(context.getGuild());
if (!MusicUtils.checkIfConnected(context))
return CommandExecutionResult.none();
if (context.getArgs().length == 0) {
context.reply("Select the track you want to delete from the queue (track# or all)");
context.reply(MessageFunction.buildViewQueueMessage(player, true));
}
if (context.getArgs().length > 0) {
int queueSize = player.getQueueSize();
if (context.getArgument(0).equals("all")) {
if (queueSize > 0) {
player.getScheduler().getQueueManager().clearQueue();
context.reply(String.format("Removed %d track%s from the queue", queueSize--, (queueSize > 1 ? "s" : "")));
} else {
context.reply("Queue is empty!");
}
} else {
try {
int num = Integer.parseInt(context.getArgument(0));
if (num > 0) {
return player.getScheduler().getQueueManager().removeFromQueue(num);
} else {
context.reply("Number out of range");
}
} catch (NumberFormatException e) {
context.reply("Please enter a number");
}
}
}
return CommandExecutionResult.none();
}
@Override @Override
public CommandExecutionResult execute(SlashCommandContext context) { public CommandExecutionResult execute(SlashCommandContext context) {
MusicManager manager = MusicManager.get(context.getGuild()); MusicManager manager = MusicManager.get(context.getGuild());
context.ack(); context.ack();
if (!MusicUtils.checkIfConnected(context)) if (MusicUtils.checkIfConnected(context)) {
return manager.getQueueManager().clearQueue();
}
return CommandExecutionResult.none(); return CommandExecutionResult.none();
return manager.getScheduler().getQueueManager().clearQueue();
} }
} }
@@ -37,10 +37,8 @@ public class JoinCommand extends AbstractMusicCommand {
@Override @Override
public CommandExecutionResult execute(MessageCommandContext context) { public CommandExecutionResult execute(MessageCommandContext context) {
if (MusicUtils.checkIfNotConnected(context)) { if (MusicUtils.connect(context)) {
context.reply("Joining current voice channel"); context.reply("Joining current voice channel");
MusicUtils.connect(context, true);
} }
return CommandExecutionResult.none(); return CommandExecutionResult.none();
@@ -48,10 +46,8 @@ public class JoinCommand extends AbstractMusicCommand {
@Override @Override
public CommandExecutionResult execute(SlashCommandContext context) { public CommandExecutionResult execute(SlashCommandContext context) {
if (MusicUtils.checkIfNotConnected(context)) { if (MusicUtils.connect(context)) {
context.reply("Joining current voice channel"); context.reply("Joining current voice channel");
MusicUtils.connect(context, true);
} }
return CommandExecutionResult.none(); return CommandExecutionResult.none();
@@ -38,11 +38,11 @@ public class LeaveCommand extends AbstractMusicCommand {
@Override @Override
public CommandExecutionResult execute(MessageCommandContext context) { public CommandExecutionResult execute(MessageCommandContext context) {
MusicManager player = MusicManager.get(context.getGuild()); MusicManager manager = MusicManager.get(context.getGuild());
if (MusicUtils.checkIfConnected(context)) { if (MusicUtils.checkIfConnected(context)) {
context.reply("Leaving voice channel and clearing queue"); context.reply("Leaving voice channel and clearing queue");
player.leave(); manager.disconnect();
} }
return CommandExecutionResult.none(); return CommandExecutionResult.none();
@@ -50,11 +50,11 @@ public class LeaveCommand extends AbstractMusicCommand {
@Override @Override
public CommandExecutionResult execute(SlashCommandContext context) { public CommandExecutionResult execute(SlashCommandContext context) {
MusicManager player = MusicManager.get(context.getGuild()); MusicManager manager = MusicManager.get(context.getGuild());
if (MusicUtils.checkIfConnected(context)) { if (MusicUtils.checkIfConnected(context)) {
context.reply("Leaving voice channel and clearing queue"); context.reply("Leaving voice channel and clearing queue");
player.leave(); manager.disconnect();
} }
return CommandExecutionResult.none(); return CommandExecutionResult.none();
@@ -6,10 +6,10 @@ package me.bobert.netneutrality.command.music;
*/ */
import me.bobert.netneutrality.command.AbstractMusicCommand; import me.bobert.netneutrality.command.AbstractMusicCommand;
import me.bobert.netneutrality.context.MessageCommandContext;
import me.bobert.netneutrality.context.SlashCommandContext; import me.bobert.netneutrality.context.SlashCommandContext;
import me.bobert.netneutrality.core.command.CommandExecutionResult; import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.music.MusicManager; import me.bobert.netneutrality.music.MusicManager;
import me.bobert.netneutrality.music.QueueManager;
import me.bobert.netneutrality.utils.MessageFunction; import me.bobert.netneutrality.utils.MessageFunction;
import me.bobert.netneutrality.utils.MusicUtils; import me.bobert.netneutrality.utils.MusicUtils;
import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Member;
@@ -59,77 +59,35 @@ public class QueueCommand extends AbstractMusicCommand {
); );
} }
@Override
public CommandExecutionResult execute(MessageCommandContext context) {
MusicManager player = MusicManager.get(context.getGuild());
if (!MusicUtils.checkIfConnected(context))
return CommandExecutionResult.none();
if (context.getArgs().length == 0) {
context.reply("Select the track you want to delete from the queue (track# or all)");
context.reply(MessageFunction.buildViewQueueMessage(player, true));
}
if (context.getArgs().length > 0) {
int queueSize = player.getQueueSize();
if (context.getArgument(0).equals("all")) {
if (queueSize > 0) {
player.getScheduler().getQueueManager().clearQueue();
context.reply(String.format("Removed %d track%s from the queue", queueSize--, (queueSize > 1 ? "s" : "")));
} else {
context.reply("Queue is empty!");
}
} else {
try {
int num = Integer.parseInt(context.getArgument(0));
if (num > 0) {
return player.getScheduler().getQueueManager().removeFromQueue(num);
} else {
context.reply("Number out of range");
}
} catch (NumberFormatException e) {
context.reply("Please enter a number");
}
}
}
return CommandExecutionResult.none();
}
@Override @Override
public CommandExecutionResult execute(SlashCommandContext context) { public CommandExecutionResult execute(SlashCommandContext context) {
MusicManager manager = MusicManager.get(context.getGuild()); MusicManager manager = MusicManager.get(context.getGuild());
QueueManager queueManager = manager.getQueueManager();
context.ack(); context.ack();
String sub = context.getEvent().getFullCommandName().split(" ")[1]; String sub = context.getSubCommand();
if (MusicUtils.checkIfConnected(context)) { if (MusicUtils.checkIfConnected(context)) {
switch (sub) { switch (sub) {
case "clear-all" -> { case "clear-all" -> {
return manager.getScheduler().getQueueManager().clearQueue(); return queueManager.clearQueue();
} }
case "delete-track" -> { case "delete-track" -> {
int position = context.getEvent().getOption("position", 0, OptionMapping::getAsInt); int position = context.getEvent().getOption("position", 0, OptionMapping::getAsInt);
return manager.getScheduler().getQueueManager().removeFromQueue(position); return queueManager.removeFromQueue(position);
} }
case "show-queue" -> { case "show-queue" -> {
if (manager.getQueueSize() == 0) { if (queueManager.getQueueSize() == 0) {
return CommandExecutionResult.info("Queue is empty!"); return CommandExecutionResult.info("Queue is empty!");
} }
context.reply(MessageFunction.buildViewQueueMessage(manager, true)); context.reply(MessageFunction.buildViewQueueMessage(manager));
} }
case "shuffle" -> { case "shuffle" -> {
return manager.getScheduler().getQueueManager().shuffle(); return queueManager.shuffle();
} }
case "from-user" -> { case "from-user" -> {
@@ -147,16 +105,12 @@ public class QueueCommand extends AbstractMusicCommand {
return CommandExecutionResult.warn("The user isn't from this guild"); return CommandExecutionResult.warn("The user isn't from this guild");
} }
int size = manager.getScheduler() int size = queueManager.getQueueWithFilter(trackInfo -> member.equals(trackInfo.getRequester())).size();
.getQueueManager()
.getQueueWithFilter(trackInfo -> member.equals(trackInfo.getRequester()))
.size();
if (size == 0) { if (size == 0) {
return CommandExecutionResult.info(String.format("No tracks added by user %s", member.getEffectiveName())); return CommandExecutionResult.info(String.format("No tracks added by user %s", member.getEffectiveName()));
} }
manager.getScheduler().getQueueManager().removeTracksFromUser(member); queueManager.removeTracksFromUser(member);
context.reply("Removed all tracks from user %s", member.getEffectiveName()); context.reply("Removed all tracks from user %s", member.getEffectiveName());
} }
} }
@@ -0,0 +1,45 @@
package me.bobert.netneutrality.command.music;/*
* Copyright (c) anthorob
*
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.command.AbstractMusicCommand;
import me.bobert.netneutrality.context.SlashCommandContext;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.music.MusicManager;
import me.bobert.netneutrality.utils.MusicUtils;
import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData;
public class ResumeCommand extends AbstractMusicCommand {
@Override
public boolean isEnabled() {
return true;
}
@Override
public String getCommandName() {
return "resume";
}
@Override
public String getDescription() {
return "Resume the music player at the next track if it was stopped using the command /stop";
}
@Override
public void registerSlashCommandOptions(SlashCommandData data) {
}
@Override
public CommandExecutionResult execute(SlashCommandContext context) {
MusicManager manager = MusicManager.get(context.getGuild());
if (MusicUtils.checkIfConnected(context)) {
return manager.getQueueManager().skip();
}
return CommandExecutionResult.none();
}
}
@@ -40,7 +40,7 @@ public class ShuffleCommand extends AbstractMusicCommand {
context.ack(); context.ack();
if (MusicUtils.checkIfConnected(context)) { if (MusicUtils.checkIfConnected(context)) {
return manager.getScheduler().getQueueManager().shuffle(); return manager.getQueueManager().shuffle();
} }
return CommandExecutionResult.none(); return CommandExecutionResult.none();
@@ -43,27 +43,25 @@ public class SkipCommand extends AbstractMusicCommand {
@Override @Override
public CommandExecutionResult execute(MessageCommandContext context) { public CommandExecutionResult execute(MessageCommandContext context) {
MusicManager player = MusicManager.get(context.getGuild()); MusicManager manager = MusicManager.get(context.getGuild());
if (!MusicUtils.checkIfConnected(context)) if (!MusicUtils.checkIfConnected(context)) {
return CommandExecutionResult.none(); return CommandExecutionResult.none();
}
if (UserFunction.isAdmin(context.getGuildUser()) || MusicUtils.isUserDj(context.getGuildUser())) { if (UserFunction.isAdmin(context.getGuildUser()) || MusicUtils.isUserDj(context.getGuildUser())) {
if (UserFunction.isAdmin(context.getGuildUser()) && context.getArgs().length > 0) { if (UserFunction.isAdmin(context.getGuildUser()) && context.getArgs().length > 0) {
try { try {
int skips = Integer.parseInt(context.getArgument(0)); int skips = Integer.parseInt(context.getArgument(0));
player.getScheduler().getQueueManager().skip(skips); return manager.getQueueManager().skip(skips);
context.reply("Skipping %s track%s", skips, (skips > 1 ? "s" : ""));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
context.reply("Please enter how many track(s) to skip"); context.reply("Please enter how many track(s) to skip");
} }
} else { } else {
player.getScheduler().getQueueManager().skip(1); return manager.getQueueManager().skip(1);
context.reply("Skipping current track");
} }
} else { } else {
player.voteSkip(context); return manager.voteSkip(context);
} }
return CommandExecutionResult.none(); return CommandExecutionResult.none();
@@ -72,11 +70,11 @@ public class SkipCommand extends AbstractMusicCommand {
@Override @Override
public CommandExecutionResult execute(SlashCommandContext context) { public CommandExecutionResult execute(SlashCommandContext context) {
MusicManager manager = MusicManager.get(context.getGuild()); MusicManager manager = MusicManager.get(context.getGuild());
int skips = context.getEvent().getOption("skip", 1, OptionMapping::getAsInt);
context.ack(); context.ack();
if (MusicUtils.checkIfConnected(context)) { if (MusicUtils.checkIfConnected(context)) {
return manager.getScheduler().getQueueManager().skip(skips); int skips = context.getEvent().getOption("skip", 1, OptionMapping::getAsInt);
return manager.getQueueManager().skip(skips);
} }
return CommandExecutionResult.none(); return CommandExecutionResult.none();
@@ -39,16 +39,15 @@ public class StopCommand extends AbstractMusicCommand {
@Override @Override
public CommandExecutionResult execute(MessageCommandContext context) { public CommandExecutionResult execute(MessageCommandContext context) {
MusicManager player = MusicManager.get(context.getGuild()); MusicManager manager = MusicManager.get(context.getGuild());
if (!MusicUtils.checkIfConnected(context))
return CommandExecutionResult.none();
if (MusicUtils.checkIfConnected(context)) {
// Need a resume command before // Need a resume command before
if (UserFunction.isAdmin(context.getGuildUser())) { if (UserFunction.isAdmin(context.getGuildUser())) {
player.stopTrack(); manager.stopTrack();
context.reply("Stopping current track"); context.reply("Stopping current track");
} }
}
return CommandExecutionResult.none(); return CommandExecutionResult.none();
} }
@@ -38,12 +38,12 @@ public class ViewQueueCommand extends AbstractMusicCommand {
@Override @Override
public CommandExecutionResult execute(MessageCommandContext context) { public CommandExecutionResult execute(MessageCommandContext context) {
MusicManager player = MusicManager.get(context.getGuild()); MusicManager manager = MusicManager.get(context.getGuild());
if (MusicUtils.checkIfConnected(context)) { if (MusicUtils.checkIfConnected(context)) {
int queueSize = player.getQueueSize(); int queueSize = manager.getQueueSize();
if (queueSize > 0) { if (queueSize > 0) {
context.reply(MessageFunction.buildViewQueueMessage(player, true)); context.reply(MessageFunction.buildViewQueueMessage(manager));
} else { } else {
context.reply("Queue is empty!"); context.reply("Queue is empty!");
} }
@@ -63,7 +63,7 @@ public class ViewQueueCommand extends AbstractMusicCommand {
return CommandExecutionResult.warn("Queue is empty!"); return CommandExecutionResult.warn("Queue is empty!");
} }
context.reply(MessageFunction.buildViewQueueMessage(manager, true)); context.reply(MessageFunction.buildViewQueueMessage(manager));
} }
return CommandExecutionResult.none(); return CommandExecutionResult.none();
@@ -43,7 +43,7 @@ public class VolumeCommand extends AbstractMusicCommand {
@Override @Override
public CommandExecutionResult execute(MessageCommandContext context) { public CommandExecutionResult execute(MessageCommandContext context) {
MusicManager player = MusicManager.get(context.getGuild()); MusicManager manager = MusicManager.get(context.getGuild());
if (!MusicUtils.checkIfConnected(context)) if (!MusicUtils.checkIfConnected(context))
return CommandExecutionResult.none(); return CommandExecutionResult.none();
@@ -53,7 +53,7 @@ public class VolumeCommand extends AbstractMusicCommand {
int volume = Integer.parseInt(context.getArgument(0)); int volume = Integer.parseInt(context.getArgument(0));
if (volume > 0 && volume <= 100) { if (volume > 0 && volume <= 100) {
player.setVolume(volume); manager.setVolume(volume);
context.reply("Volume set to %s", volume); context.reply("Volume set to %s", volume);
} else } else
throw new NumberFormatException(); throw new NumberFormatException();
@@ -7,6 +7,7 @@ package me.bobert.netneutrality.context;
import me.bobert.netneutrality.core.AsyncMessage; import me.bobert.netneutrality.core.AsyncMessage;
import me.bobert.netneutrality.core.context.AbstractContext; import me.bobert.netneutrality.core.context.AbstractContext;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
import net.dv8tion.jda.api.events.Event; import net.dv8tion.jda.api.events.Event;
import net.dv8tion.jda.api.interactions.InteractionHook; import net.dv8tion.jda.api.interactions.InteractionHook;
@@ -18,8 +19,8 @@ import java.util.function.Consumer;
public class MusicChannelContext extends AbstractContext { public class MusicChannelContext extends AbstractContext {
public MusicChannelContext(GuildMessageChannel channel) { public MusicChannelContext(GuildMessageChannel channel, Member member) {
super(channel.getJDA(), channel.getGuild(), channel, null, null); super(channel.getJDA(), channel.getGuild(), channel, member, member.getUser());
} }
@Override @Override
@@ -23,7 +23,6 @@ import me.bobert.netneutrality.thread.MusicPlayerAutoDisconnectThread;
import me.bobert.netneutrality.utils.MusicUtils; import me.bobert.netneutrality.utils.MusicUtils;
import me.bobert.netneutrality.utils.Settings; import me.bobert.netneutrality.utils.Settings;
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.channel.middleman.AudioChannel; import net.dv8tion.jda.api.entities.channel.middleman.AudioChannel;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@@ -78,6 +77,29 @@ public class MusicManager {
dev.lavalink.youtube.clients.Web.setPoTokenAndVisitorData(po, visitor); dev.lavalink.youtube.clients.Web.setPoTokenAndVisitorData(po, visitor);
} }
public static void disconnectPlayers() {
for (MusicManager mm : managers.values()) {
mm.getQueueManager().clearQueue();
mm.player.destroy();
}
}
public TrackScheduler getScheduler() {
return scheduler;
}
public QueueManager getQueueManager() {
return scheduler.getQueueManager();
}
public AudioPlayer getPlayer() {
return player;
}
public Guild getGuild() {
return guild;
}
public boolean isNotConnectedTo(AudioChannel vChannel) { public boolean isNotConnectedTo(AudioChannel vChannel) {
return vChannel == null || !vChannel.equals(guild.getAudioManager().getConnectedChannel()); return vChannel == null || !vChannel.equals(guild.getAudioManager().getConnectedChannel());
} }
@@ -96,6 +118,21 @@ public class MusicManager {
} }
} }
public synchronized void disconnect() {
if (guild != null && guild.getAudioManager().getConnectedChannel() != null) {
logger.debug("Guild {}: disconnecting from voice channel {}", guild.getId(), guild.getAudioManager().getConnectedChannel().getId());
player.stopTrack();
guild.getAudioManager().closeAudioConnection();
}
scheduler.detachContext();
if (autoDisconnectThread != null) {
autoDisconnectThread.cancel(true);
autoDisconnectThread = null;
}
}
public boolean isConnected() { public boolean isConnected() {
return guild != null && guild.getAudioManager().getConnectedChannel() != null; return guild != null && guild.getAudioManager().getConnectedChannel() != null;
} }
@@ -108,45 +145,6 @@ public class MusicManager {
return player.getPlayingTrack() != null; return player.getPlayingTrack() != null;
} }
public synchronized Member getRequesterOfCurrentTrack() {
QueueManager.TrackInfo info = scheduler.getQueueManager().peekHeadOfQueue();
if (info == null)
return null;
return info.getRequester();
}
protected AudioPlayer getPlayer() {
return player;
}
public Guild getGuild() {
return guild;
}
public synchronized void leave() {
if (guild != null && guild.getAudioManager().getConnectedChannel() != null) {
logger.debug("Guild {}: leaving voice channel {}", guild.getId(), guild.getAudioManager().getConnectedChannel().getId());
player.stopTrack();
guild.getAudioManager().closeAudioConnection();
}
scheduler.detachTextChannel();
if (autoDisconnectThread != null) {
autoDisconnectThread.cancel(true);
autoDisconnectThread = null;
}
}
public static void disconnectPlayers() {
for (MusicManager mm : managers.values()) {
mm.getScheduler().getQueueManager().clearQueue();
mm.player.destroy();
}
}
public synchronized void play(String query, CommandContext context) { public synchronized void play(String query, CommandContext context) {
play(query, context, false); play(query, context, false);
} }
@@ -173,7 +171,6 @@ public class MusicManager {
public synchronized CommandExecutionResult voteSkip(CommandContext context) { public synchronized CommandExecutionResult voteSkip(CommandContext context) {
AudioChannel audioChannel = guild.getAudioManager().getConnectedChannel(); AudioChannel audioChannel = guild.getAudioManager().getConnectedChannel();
if (audioChannel == null) { if (audioChannel == null) {
return CommandExecutionResult.warn("Bot is not connected to a voice channel"); return CommandExecutionResult.warn("Bot is not connected to a voice channel");
} }
@@ -182,7 +179,7 @@ public class MusicManager {
return CommandExecutionResult.warn("No tracks are currently playing"); return CommandExecutionResult.warn("No tracks are currently playing");
} }
QueueManager.TrackInfo info = scheduler.getQueueManager().peekHeadOfQueue(); TrackInfo info = getQueueManager().peekHeadOfQueue();
if (info == null) { if (info == null) {
return CommandExecutionResult.warn("Queue is empty"); return CommandExecutionResult.warn("Queue is empty");
} }
@@ -191,7 +188,7 @@ public class MusicManager {
int connected = audioChannel.getMembers().size() - 1; int connected = audioChannel.getMembers().size() - 1;
if (connected < 3) { if (connected < 3) {
scheduler.getQueueManager().skip(); getQueueManager().skip();
return CommandExecutionResult.info("Skipping current track since not enough people are connected to the voice channel."); return CommandExecutionResult.info("Skipping current track since not enough people are connected to the voice channel.");
} }
@@ -202,7 +199,7 @@ public class MusicManager {
logger.debug("VoteSkip: guild={}, connected={}, needed={}, skips={}, user={}", context.getGuild().getId(), connected, needed, info.getSkips().size(), context.getGuildUser().getId()); logger.debug("VoteSkip: guild={}, connected={}, needed={}, skips={}, user={}", context.getGuild().getId(), connected, needed, info.getSkips().size(), context.getGuildUser().getId());
if (info.getSkips().size() > needed) { if (info.getSkips().size() > needed) {
return scheduler.getQueueManager().skip(); return getQueueManager().skip();
} }
return CommandExecutionResult.success(String.format("Adding your vote to skip the current track. Current votes: %d/%d", return CommandExecutionResult.success(String.format("Adding your vote to skip the current track. Current votes: %d/%d",
@@ -216,10 +213,6 @@ public class MusicManager {
} }
public int getQueueSize() { public int getQueueSize() {
return scheduler.getQueueManager().getQueueSize(); return getQueueManager().getQueueSize();
}
public TrackScheduler getScheduler() {
return scheduler;
} }
} }
@@ -18,68 +18,7 @@ import java.util.concurrent.LinkedBlockingDeque;
import java.util.function.Predicate; import java.util.function.Predicate;
public class QueueManager { public class QueueManager {
public static class TrackInfo {
private final AudioTrack track;
private final Member member;
private final Set<String> skips;
private static final Logger logger = LogManager.getLogger(QueueManager.class);
public TrackInfo(AudioTrack track, Member member) {
this.track = track;
this.member = member;
this.skips = new HashSet<>();
}
public AudioTrack getTrack() {
return track;
}
public Set<String> getSkips() {
return skips;
}
public void addSkip(Member member) {
if (!hasSkip(member)) {
logger.debug("VoteSkip: user={}, skip doesn't exist, before={}, after={}", member.getId(), skips.size(), skips.size() + 1);
skips.add(member.getId());
}
}
public boolean hasSkip(Member member) {
return skips.contains(member.getId());
}
public Member getRequester() {
return member;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TrackInfo trackInfo = (TrackInfo) o;
return track.equals(trackInfo.track);
}
@Override
public int hashCode() {
return Objects.hash(track);
}
@Override
public String toString() {
return "TrackInfo{" +
"track=" + track.getInfo().title +
", member=" + member.getEffectiveName() +
", skips=" + skips +
'}';
}
}
private final Logger logger = LogManager.getLogger(QueueManager.class); private final Logger logger = LogManager.getLogger(QueueManager.class);
private final TrackScheduler scheduler; private final TrackScheduler scheduler;
private final AudioPlayer player; private final AudioPlayer player;
private final Guild guild; private final Guild guild;
@@ -99,10 +38,6 @@ public class QueueManager {
} }
} }
public TrackScheduler getScheduler() {
return scheduler;
}
public Guild getGuild() { public Guild getGuild() {
return guild; return guild;
} }
@@ -138,7 +73,7 @@ public class QueueManager {
} }
public CommandExecutionResult clearQueue() { public CommandExecutionResult clearQueue() {
scheduler.getMusicManager().leave(); scheduler.getMusicManager().disconnect();
if (queue.isEmpty()) { if (queue.isEmpty()) {
return CommandExecutionResult.warn("Queue is empty!"); return CommandExecutionResult.warn("Queue is empty!");
@@ -175,7 +110,7 @@ public class QueueManager {
} }
} }
public ArrayList<AudioTrack> getAllQueuedTrack() { public List<AudioTrack> getAllQueuedTracks() {
synchronized (queue) { synchronized (queue) {
ArrayList<AudioTrack> tracks = new ArrayList<>(); ArrayList<AudioTrack> tracks = new ArrayList<>();
@@ -228,13 +163,18 @@ public class QueueManager {
} }
public CommandExecutionResult skip(int nbTrack) { public CommandExecutionResult skip(int nbTrack) {
if (nbTrack == 0) { if (nbTrack < 1) {
nbTrack = 1; nbTrack = 1;
} }
if (queue.isEmpty()) {
scheduler.getMusicManager().disconnect();
return CommandExecutionResult.info("Queue is empty, leaving voice channel");
}
synchronized (queue) { synchronized (queue) {
if (queue.isEmpty()) { if (queue.isEmpty()) {
scheduler.getMusicManager().leave(); scheduler.getMusicManager().disconnect();
return CommandExecutionResult.info("Queue is empty, leaving voice channel"); return CommandExecutionResult.info("Queue is empty, leaving voice channel");
} }
@@ -248,7 +188,7 @@ public class QueueManager {
} }
if (queue.isEmpty()) { if (queue.isEmpty()) {
scheduler.getMusicManager().leave(); scheduler.getMusicManager().disconnect();
return CommandExecutionResult.info("Queue is empty, leaving voice channel"); return CommandExecutionResult.info("Queue is empty, leaving voice channel");
} }
@@ -259,12 +199,15 @@ public class QueueManager {
} }
public CommandExecutionResult shuffle() { public CommandExecutionResult shuffle() {
if (queue.size() > 3) { if (queue.size() <= 3) {
return CommandExecutionResult.none(); return CommandExecutionResult.warn("The queue is too small to be shuffled");
} }
synchronized (queue) { synchronized (queue) {
if (queue.size() > 3) { if (queue.size() <= 3) {
return CommandExecutionResult.warn("The queue is too small to be shuffled");
}
logger.debug("Guild {}: shuffling queue", guild.getId()); logger.debug("Guild {}: shuffling queue", guild.getId());
TrackInfo current = queue.poll(); TrackInfo current = queue.poll();
@@ -276,10 +219,7 @@ public class QueueManager {
queue.add(current); queue.add(current);
queue.addAll(newQueue); queue.addAll(newQueue);
return CommandExecutionResult.success("Queue is now shuffled."); return CommandExecutionResult.success("The queue is now shuffled.");
}
return CommandExecutionResult.none();
} }
} }
@@ -0,0 +1,72 @@
package me.bobert.netneutrality.music;/*
* Copyright (c) anthorob
*
* https://discord.gg/qUa6zNFZsd
*/
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
import net.dv8tion.jda.api.entities.Member;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
public class TrackInfo {
private final AudioTrack track;
private final Member member;
private final Set<String> skips;
private static final Logger logger = LogManager.getLogger(QueueManager.class);
public TrackInfo(AudioTrack track, Member member) {
this.track = track;
this.member = member;
this.skips = new HashSet<>();
}
public AudioTrack getTrack() {
return track;
}
public Set<String> getSkips() {
return skips;
}
public void addSkip(Member member) {
if (!hasSkip(member)) {
logger.debug("VoteSkip: user={}, skip doesn't exist, before={}, after={}", member.getId(), skips.size(), skips.size() + 1);
skips.add(member.getId());
}
}
public boolean hasSkip(Member member) {
return skips.contains(member.getId());
}
public Member getRequester() {
return member;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TrackInfo trackInfo = (TrackInfo) o;
return track.equals(trackInfo.track);
}
@Override
public int hashCode() {
return Objects.hash(track);
}
@Override
public String toString() {
return "TrackInfo{" +
"track=" + track.getInfo().title +
", member=" + member.getEffectiveName() +
", skips=" + skips +
'}';
}
}
@@ -27,7 +27,7 @@ public class TrackLoadingHandler implements AudioLoadResultHandler {
private final SourceFinder.AudioSourceType type; private final SourceFinder.AudioSourceType type;
private final boolean silent; private final boolean silent;
private final Guild guild; private final Guild guild;
private final TrackScheduler scheduler; private final QueueManager queueManager;
private final CommandContext context; private final CommandContext context;
public TrackLoadingHandler(CommandContext context, MusicManager manager, String identifier, SourceFinder.AudioSourceType type, boolean silent) { public TrackLoadingHandler(CommandContext context, MusicManager manager, String identifier, SourceFinder.AudioSourceType type, boolean silent) {
@@ -35,18 +35,17 @@ public class TrackLoadingHandler implements AudioLoadResultHandler {
this.type = type; this.type = type;
this.silent = silent; this.silent = silent;
this.guild = manager.getGuild(); this.guild = manager.getGuild();
this.scheduler = manager.getScheduler(); this.queueManager = manager.getQueueManager();
this.context = context; this.context = context;
} }
@Override @Override
public void trackLoaded(AudioTrack audioTrack) { public void trackLoaded(AudioTrack audioTrack) {
context.deleteMessage();
logger.debug("Guild {}: track loaded: {}", guild.getId(), audioTrack.getIdentifier()); logger.debug("Guild {}: track loaded: {}", guild.getId(), audioTrack.getIdentifier());
context.deleteMessage();
if (MusicUtils.connect(context)) { if (MusicUtils.connect(context)) {
scheduler.getQueueManager().queue(audioTrack, context.getGuildUser()); queueManager.queue(audioTrack, context.getGuildUser());
if (!silent) { if (!silent) {
context.reply(MessageFunction.buildAddingTrackMessage(audioTrack, context.getGuildUser(), type)); context.reply(MessageFunction.buildAddingTrackMessage(audioTrack, context.getGuildUser(), type));
@@ -12,21 +12,20 @@ import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason; import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason;
import me.bobert.netneutrality.context.MusicChannelContext; import me.bobert.netneutrality.context.MusicChannelContext;
import me.bobert.netneutrality.core.LogHandler; import me.bobert.netneutrality.core.LogHandler;
import me.bobert.netneutrality.core.context.Context;
import me.bobert.netneutrality.utils.MessageFunction; import me.bobert.netneutrality.utils.MessageFunction;
import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
public class TrackScheduler extends AudioEventAdapter { public class TrackScheduler extends AudioEventAdapter {
private static final Logger logger = LogManager.getLogger(TrackScheduler.class); private static final Logger logger = LogManager.getLogger(TrackScheduler.class);
private final QueueManager queueManager; private final QueueManager queueManager;
private final MusicManager manager; private final MusicManager manager;
private final AudioPlayer player; private final AudioPlayer player;
private final Guild guild; private final Guild guild;
private MusicChannelContext context; private Context context;
private AudioTrack lastStuckTrack = null; private AudioTrack lastStuckTrack = null;
public TrackScheduler(MusicManager manager) { public TrackScheduler(MusicManager manager) {
@@ -52,17 +51,19 @@ public class TrackScheduler extends AudioEventAdapter {
return guild; return guild;
} }
public MusicChannelContext getCurrentContext() { public Member getDj() {
return context; if (context != null) {
return context.getGuildUser();
} }
public synchronized void attachChannel(MessageChannel channel) { return null;
if (channel instanceof GuildMessageChannel guildMessageChannel) {
this.context = new MusicChannelContext(guildMessageChannel);
}
} }
public synchronized void detachTextChannel() { public synchronized void attachContext(MusicChannelContext context) {
this.context = context;
}
public synchronized void detachContext() {
this.context = null; this.context = null;
} }
@@ -128,7 +129,7 @@ public class TrackScheduler extends AudioEventAdapter {
logger.debug("Trying to load stuck track again: {}", track.getIdentifier()); logger.debug("Trying to load stuck track again: {}", track.getIdentifier());
context.async("Current track is stuck, trying to load it again", asyncMessage -> { context.async("Current track is stuck, trying to load it again", asyncMessage -> {
try { try {
QueueManager.TrackInfo info = queueManager.peekHeadOfQueue(); TrackInfo info = queueManager.peekHeadOfQueue();
if (info != null && info.getTrack().getIdentifier().equals(track.getIdentifier())) { if (info != null && info.getTrack().getIdentifier().equals(track.getIdentifier())) {
AudioTrack clone = track.makeClone(); AudioTrack clone = track.makeClone();
long lastPosition = track.getPosition(); long lastPosition = track.getPosition();
@@ -41,13 +41,11 @@ public class AddAllTracksTask extends ButtonTask implements WithParent<LoadPlayl
@Override @Override
public void execute(ButtonTaskContext context) { public void execute(ButtonTaskContext context) {
MusicManager manager = MusicManager.get(context.getGuild()); MusicManager manager = MusicManager.get(context.getGuild());
TrackScheduler scheduler = manager.getScheduler();
Member member = context.getGuildUser(); Member member = context.getGuildUser();
if (MusicUtils.connect(context)) { if (MusicUtils.connect(context)) {
for (AudioTrack track : tracks) { for (AudioTrack track : tracks) {
scheduler.getQueueManager().queue(track, member); manager.getQueueManager().queue(track, member);
} }
context.reply(MessageFunction.buildAddingPlaylistMessage(tracks, parentTask.getPlaylist().getName(), member, SourceFinder.AudioSourceType.Youtube)); context.reply(MessageFunction.buildAddingPlaylistMessage(tracks, parentTask.getPlaylist().getName(), member, SourceFinder.AudioSourceType.Youtube));
@@ -97,7 +97,7 @@ public class LoadPlaylistTask extends ButtonTask implements WithChildren, Deleta
MusicManager manager = MusicManager.get(context.getGuild()); MusicManager manager = MusicManager.get(context.getGuild());
if (MusicUtils.connect(context)) { if (MusicUtils.connect(context)) {
for (AudioTrack track : tracks) { for (AudioTrack track : tracks) {
manager.getScheduler().getQueueManager().queue(track, context.getGuildUser()); manager.getQueueManager().queue(track, context.getGuildUser());
} }
context.edit(MessageFunction.buildAddingPlaylistMessage(tracks, playlist.getName(), context.getGuildUser(), Youtube)); context.edit(MessageFunction.buildAddingPlaylistMessage(tracks, playlist.getName(), context.getGuildUser(), Youtube));
@@ -11,7 +11,6 @@ import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.core.tasks.trait.WithParent; import me.bobert.netneutrality.core.tasks.trait.WithParent;
import me.bobert.netneutrality.music.MusicManager; import me.bobert.netneutrality.music.MusicManager;
import me.bobert.netneutrality.music.SourceFinder; import me.bobert.netneutrality.music.SourceFinder;
import me.bobert.netneutrality.music.TrackScheduler;
import me.bobert.netneutrality.tasks.ButtonTask; import me.bobert.netneutrality.tasks.ButtonTask;
import me.bobert.netneutrality.utils.MessageFunction; import me.bobert.netneutrality.utils.MessageFunction;
import me.bobert.netneutrality.utils.MusicUtils; import me.bobert.netneutrality.utils.MusicUtils;
@@ -39,12 +38,10 @@ public class LoadTrackFromPlaylistTask extends ButtonTask implements WithParent<
@Override @Override
public void execute(ButtonTaskContext context) { public void execute(ButtonTaskContext context) {
MusicManager manager = MusicManager.get(context.getGuild()); MusicManager manager = MusicManager.get(context.getGuild());
TrackScheduler scheduler = manager.getScheduler();
Member member = context.getGuildUser(); Member member = context.getGuildUser();
if (MusicUtils.connect(context)) { if (MusicUtils.connect(context)) {
scheduler.getQueueManager().queue(track, member); manager.getQueueManager().queue(track, member);
context.reply(MessageFunction.buildAddingTrackMessage(track, member, SourceFinder.AudioSourceType.Youtube)); context.reply(MessageFunction.buildAddingTrackMessage(track, member, SourceFinder.AudioSourceType.Youtube));
} }
@@ -38,7 +38,7 @@ public class MusicPlayerAutoDisconnectThread implements Runnable {
if (conditionsMetToDisconnect(channel)) { if (conditionsMetToDisconnect(channel)) {
logger.debug("Guild {}: auto-disconnect player from voice channel: {}", guild.getId(), channel.getId()); logger.debug("Guild {}: auto-disconnect player from voice channel: {}", guild.getId(), channel.getId());
manager.leave(); manager.disconnect();
} }
} }
} }
@@ -50,6 +50,6 @@ public class MusicPlayerAutoDisconnectThread implements Runnable {
private boolean conditionsMetToDisconnect(AudioChannel channel) { private boolean conditionsMetToDisconnect(AudioChannel channel) {
List<Member> members = channel.getMembers().stream().filter(member -> !member.getId().equals(NetNeutrality.getSelf().getId())).toList(); List<Member> members = channel.getMembers().stream().filter(member -> !member.getId().equals(NetNeutrality.getSelf().getId())).toList();
return members.isEmpty() || manager.getScheduler().getQueueManager().isEmpty(); return members.isEmpty() || manager.getQueueManager().isEmpty();
} }
} }
@@ -18,13 +18,12 @@ import me.bobert.netneutrality.core.context.Context;
import me.bobert.netneutrality.core.context.TaskContext; import me.bobert.netneutrality.core.context.TaskContext;
import me.bobert.netneutrality.exceptions.ContextException; import me.bobert.netneutrality.exceptions.ContextException;
import me.bobert.netneutrality.music.MusicManager; import me.bobert.netneutrality.music.MusicManager;
import me.bobert.netneutrality.music.QueueManager;
import me.bobert.netneutrality.music.SourceFinder; import me.bobert.netneutrality.music.SourceFinder;
import me.bobert.netneutrality.music.TrackInfo;
import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import org.apache.commons.lang3.time.DurationFormatUtils; import org.apache.commons.lang3.time.DurationFormatUtils;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
@@ -110,37 +109,39 @@ public class MessageFunction {
return message.build(); return message.build();
} }
public static MessageEmbed buildViewQueueMessage(MusicManager manager, boolean currentlyPlaying) { public static String buildViewQueueMessage(MusicManager manager) {
ArrayList<AudioTrack> tracks = manager.getScheduler().getQueueManager().getAllQueuedTrack(); int limit = 15;
List<AudioTrack> tracks = manager.getQueueManager().getAllQueuedTracks();
AudioTrack current = manager.getCurrentlyPlaying(); AudioTrack current = manager.getCurrentlyPlaying();
int numberofTracksShown = Math.min(tracks.size(), 10); int numberofTracksShown = Math.min(tracks.size(), limit);
EmbedBuilder message = new EmbedBuilder(); StringBuilder message = new StringBuilder();
message.setTitle(String.format("Current queue (showing %d out of %d items):", numberofTracksShown, tracks.size())); message.append("Here is the current queue of the bot ")
message.setColor(Color.BLUE); .append("(showing ")
.append(numberofTracksShown)
.append(" out of ")
.append(tracks.size())
.append(" items):\n");
int index = 0; int index = 0;
for (AudioTrack track : tracks) { for (AudioTrack track : tracks) {
AudioTrackInfo info = track.getInfo(); AudioTrackInfo info = track.getInfo();
if (current != null && current.getInfo().title.equals(info.title) && currentlyPlaying) { message.append("\n");
message.addField("Track #" + ++index + " (Currently playing)", info.title, false); if (current != null && current.getInfo().title.equals(info.title)) {
message.append("**").append(++index).append(". ").append(info.title).append("**");
} else { } else {
message.addField("Track #" + ++index, info.title, false); message.append(++index).append(". ").append(info.title);
} }
if (index == 10) break; if (index == limit) break;
} }
message.setTimestamp(OffsetDateTime.now()); return message.toString();
return message.build();
} }
public static MessageEmbed buildUserTracksMessage(MusicManager manager, Member member) { public static MessageEmbed buildUserTracksMessage(MusicManager manager, Member member) {
List<QueueManager.TrackInfo> tracks = manager.getScheduler() List<TrackInfo> tracks = manager.getQueueManager().getQueueWithFilter(trackInfo -> member.equals(trackInfo.getRequester()));
.getQueueManager()
.getQueueWithFilter(trackInfo -> member.equals(trackInfo.getRequester()));
AudioTrack current = manager.getCurrentlyPlaying(); AudioTrack current = manager.getCurrentlyPlaying();
int numberofTracksShown = Math.min(tracks.size(), 10); int numberofTracksShown = Math.min(tracks.size(), 10);
@@ -149,7 +150,7 @@ public class MessageFunction {
message.setColor(Color.BLUE); message.setColor(Color.BLUE);
int index = 0; int index = 0;
for (QueueManager.TrackInfo track : tracks) { for (TrackInfo track : tracks) {
AudioTrackInfo info = track.getTrack().getInfo(); AudioTrackInfo info = track.getTrack().getInfo();
if (current != null && current.getInfo().title.equals(info.title)) { if (current != null && current.getInfo().title.equals(info.title)) {
@@ -5,23 +5,26 @@ package me.bobert.netneutrality.utils;
* https://discord.gg/qUa6zNFZsd * https://discord.gg/qUa6zNFZsd
*/ */
import me.bobert.netneutrality.context.MusicChannelContext;
import me.bobert.netneutrality.core.context.Context; import me.bobert.netneutrality.core.context.Context;
import me.bobert.netneutrality.exceptions.ContextException; import me.bobert.netneutrality.exceptions.ContextException;
import me.bobert.netneutrality.music.MusicManager; import me.bobert.netneutrality.music.MusicManager;
import net.dv8tion.jda.api.entities.GuildVoiceState; 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.channel.middleman.AudioChannel; import net.dv8tion.jda.api.entities.channel.middleman.AudioChannel;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
public class MusicUtils { public class MusicUtils {
public static boolean connect(Context context) { public static boolean connect(Context context) {
return connect(context, false); return connect(context, false, false);
} }
public static boolean connect(Context context, boolean skipChecks) { public static boolean connect(Context context, boolean skipChecks, boolean checkOnly) {
MusicManager manager = MusicManager.get(context.getGuild()); MusicManager manager = MusicManager.get(context.getGuild());
Member member = context.getGuildUser(); Member member = context.getGuildUser();
if (member == null) { if (member == null) {
context.reply("Context doesn't have a Guild user, can't continue");
return false; return false;
} }
@@ -36,31 +39,16 @@ public class MusicUtils {
return false; return false;
} }
if (manager.isNotConnectedTo(audioChannel)) { if (!checkOnly && manager.isNotConnectedTo(audioChannel)) {
manager.connect(audioChannel); manager.connect(audioChannel);
manager.getScheduler().attachChannel(context.getChannel()); manager.getScheduler().attachContext(new MusicChannelContext((GuildMessageChannel) context.getChannel(), context.getGuildUser()));
} }
return true; return true;
} }
public static boolean canConnect(Context context) { public static boolean canConnect(Context context) {
return canConnect(context, false); return connect(context, false, true);
}
public static boolean canConnect(Context context, boolean skipChecks) {
MusicManager manager = MusicManager.get(context.getGuild());
Member member = context.getGuildUser();
if (member == null) {
return false;
}
AudioChannel audioChannel = getVoiceChannel(context);
if (audioChannel == null) {
return false;
}
return skipChecks || isUserDj(member) || (!manager.isConnected() || !manager.isNotConnectedTo(audioChannel));
} }
public static boolean checkIfConnected(Context context) { public static boolean checkIfConnected(Context context) {
@@ -85,23 +73,6 @@ public class MusicUtils {
return true; return true;
} }
public static boolean checkIfNotConnected(Context context) {
MusicManager manager = MusicManager.get(context.getGuild());
AudioChannel voiceChannel = getVoiceChannel(context);
if (voiceChannel == null) {
context.reply("You are not in a voice channel");
return false;
}
if (manager.isConnected()) {
context.reply("The bot is already in a voice channel");
return false;
}
return manager.isNotConnectedTo(voiceChannel);
}
public static AudioChannel getVoiceChannel(Context context) { public static AudioChannel getVoiceChannel(Context context) {
GuildVoiceState memberVoiceState = context.getGuildUser().getVoiceState(); GuildVoiceState memberVoiceState = context.getGuildUser().getVoiceState();
@@ -118,11 +89,12 @@ public class MusicUtils {
public static boolean isUserDj(Member member) { public static boolean isUserDj(Member member) {
MusicManager manager = MusicManager.get(member.getGuild()); MusicManager manager = MusicManager.get(member.getGuild());
Member dj = manager.getScheduler().getDj();
if (manager.isCurrentlyPlaying()) { if (manager.isCurrentlyPlaying() && dj != null) {
return manager.getRequesterOfCurrentTrack().equals(member); return dj.equals(member);
} }
return false; return manager.getQueueSize() == 0 || !manager.isCurrentlyPlaying();
} }
} }