Split queue management in its own class and use a double-ended queue instead
This commit is contained in:
1 parent
ef038c5b5b
commit
7bfadb05f7
24 files changed
+420
-238
No files matched your search
@@ -6,7 +6,10 @@ package netneutrality.command;
|
|||||||
* https://discord.gg/CdFcyQ
|
* https://discord.gg/CdFcyQ
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import net.dv8tion.jda.api.entities.*;
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Role;
|
||||||
|
import net.dv8tion.jda.api.entities.TextChannel;
|
||||||
import netneutrality.core.GuildManager;
|
import netneutrality.core.GuildManager;
|
||||||
import netneutrality.utils.UserFunction;
|
import netneutrality.utils.UserFunction;
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ package netneutrality.command.basic;
|
|||||||
import net.dv8tion.jda.api.MessageBuilder;
|
import net.dv8tion.jda.api.MessageBuilder;
|
||||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||||
import netneutrality.command.AbstractCommand;
|
import netneutrality.command.AbstractCommand;
|
||||||
import netneutrality.core.CommandManager;
|
|
||||||
import netneutrality.command.CommandType;
|
import netneutrality.command.CommandType;
|
||||||
import netneutrality.command.CommandUsage;
|
import netneutrality.command.CommandUsage;
|
||||||
|
import netneutrality.core.CommandManager;
|
||||||
import netneutrality.core.context.CommandContext;
|
import netneutrality.core.context.CommandContext;
|
||||||
import netneutrality.utils.MessageFunction;
|
import netneutrality.utils.MessageFunction;
|
||||||
import netneutrality.utils.UserFunction;
|
import netneutrality.utils.UserFunction;
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class ConfigureCommand extends AbstractCommand {
|
|||||||
@Override
|
@Override
|
||||||
public CommandUsage getUsage() {
|
public CommandUsage getUsage() {
|
||||||
return CommandUsage.create(this,
|
return CommandUsage.create(this,
|
||||||
new CommandUsage.Argument(CommandUsage.Argument.Type.REQUIRED, new String[] {"musicrole", "music-channel", "musicvolume", "debug"}, "")
|
new CommandUsage.Argument(CommandUsage.Argument.Type.REQUIRED, new String[] {"music-role", "music-channel", "music-volume", "music-topic", "debug"}, "")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ public class ConfigureCommand extends AbstractCommand {
|
|||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
|
|
||||||
// Role for music commands
|
// Role for music commands
|
||||||
if (context.getArg(0).equals("musicrole")) {
|
if (context.getArg(0).equals("music-role")) {
|
||||||
if (args.length == 1) {
|
if (args.length == 1) {
|
||||||
String roleDb = guildManager.getSetting(GuildManager.Settings.MUSIC_ROLE);
|
String roleDb = guildManager.getSetting(GuildManager.Settings.MUSIC_ROLE);
|
||||||
Role role = null;
|
Role role = null;
|
||||||
@@ -72,7 +72,7 @@ public class ConfigureCommand extends AbstractCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
context.reply("Current role needed to use music commands (default is everyone): %s", (role == null ? "Everyone" : role.getAsMention()));
|
context.reply("Current role needed to use music commands (default is everyone): %s", (role == null ? "Everyone" : role.getAsMention()));
|
||||||
context.reply("Reset role using 'conf musicrole reset' or set it using 'conf musicrole @'");
|
context.reply("Reset role using 'conf music-role reset' or set it using 'conf musicrole @'");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.length == 2) {
|
if (args.length == 2) {
|
||||||
@@ -129,12 +129,12 @@ public class ConfigureCommand extends AbstractCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Default volume for music player
|
// Default volume for music player
|
||||||
if (context.getArg(0).equals("musicvolume")) {
|
if (context.getArg(0).equals("music-volume")) {
|
||||||
if (args.length == 1) {
|
if (args.length == 1) {
|
||||||
int volume = Integer.parseInt(guildManager.getSetting(GuildManager.Settings.MUSIC_VOLUME));
|
int volume = Integer.parseInt(guildManager.getSetting(GuildManager.Settings.MUSIC_VOLUME));
|
||||||
|
|
||||||
context.reply("Default volume for music player: " + volume);
|
context.reply("Default volume for music player: %d", volume);
|
||||||
context.reply("Set using 'conf musicvolume <value between 0 and 100>'");
|
context.reply("Set using 'conf music-volume <value between 0 and 100>'");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.length == 2) {
|
if (args.length == 2) {
|
||||||
@@ -155,6 +155,28 @@ public class ConfigureCommand extends AbstractCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Music topic change
|
||||||
|
if (context.getArg(0).equals("music-topic")) {
|
||||||
|
if (args.length == 1) {
|
||||||
|
boolean enabled = "1".equals(guildManager.getSetting(GuildManager.Settings.MUSIC_TOPIC));
|
||||||
|
|
||||||
|
context.reply("Set currently playing track in text channel topic: %s", (enabled ? "enabled" : "disabled"));
|
||||||
|
context.reply("Use 'conf music-topic 0/1' to toggle between states (0 = disabled, 1 = enabled).");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.length == 2) {
|
||||||
|
String str = args[1];
|
||||||
|
boolean enabled = "1".equals(guildManager.getSetting(GuildManager.Settings.MUSIC_TOPIC));
|
||||||
|
if (str.equals("0") || str.equals("1")) {
|
||||||
|
guildManager.setSettingValue(GuildManager.Settings.MUSIC_TOPIC, str);
|
||||||
|
enabled = "1".equals(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.reply("Set currently playing track in text channel topic is now %s for this guild", (enabled ? "enabled" : "disabled"));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
if (context.getArg(0).equals("debug")) {
|
if (context.getArg(0).equals("debug")) {
|
||||||
if (args.length == 1) {
|
if (args.length == 1) {
|
||||||
|
|||||||
@@ -59,10 +59,6 @@ public class BlacklistCommand extends AbstractCommand {
|
|||||||
String[] args = context.getArgumentsAsArray();
|
String[] args = context.getArgumentsAsArray();
|
||||||
DBBlacklist controller = DBController.get("blacklist", DBBlacklist.class);
|
DBBlacklist controller = DBController.get("blacklist", DBBlacklist.class);
|
||||||
|
|
||||||
if (controller == null) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.length > 0 && args.length < 3) {
|
if (args.length > 0 && args.length < 3) {
|
||||||
String word = (args.length == 2 ? args[1] : "");
|
String word = (args.length == 2 ? args[1] : "");
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ package netneutrality.command.music;
|
|||||||
* https://discord.gg/CdFcyQ
|
* https://discord.gg/CdFcyQ
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
|
||||||
import netneutrality.command.AbstractMusicCommand;
|
import netneutrality.command.AbstractMusicCommand;
|
||||||
import netneutrality.command.CommandUsage;
|
import netneutrality.command.CommandUsage;
|
||||||
import netneutrality.core.context.CommandContext;
|
import netneutrality.core.context.CommandContext;
|
||||||
@@ -44,13 +43,10 @@ public class CurrentlyPlayingCommand extends AbstractMusicCommand {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandContext context) {
|
public void execute(CommandContext context) {
|
||||||
Member member = context.getGuildUser();
|
|
||||||
MusicManager player = MusicManager.get(context.getGuild());
|
MusicManager player = MusicManager.get(context.getGuild());
|
||||||
if (!MusicUtils.checkIfConnected(player, context))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (player.getCurrentlyPlaying() != null) {
|
if (MusicUtils.checkIfConnected(player, context) && player.isCurrentlyPlaying()) {
|
||||||
context.reply(MessageFunction.buildCurrentlyPlayingMessage(player, member));
|
context.reply(MessageFunction.buildCurrentlyPlayingMessage(player, context.getGuildUser()));
|
||||||
} else {
|
} else {
|
||||||
context.reply("Player is not playing any tracks right now");
|
context.reply("Player is not playing any tracks right now");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,11 @@ import netneutrality.utils.MusicUtils;
|
|||||||
|
|
||||||
public class DeleteQueueCommand extends AbstractMusicCommand {
|
public class DeleteQueueCommand extends AbstractMusicCommand {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean needAdmin() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return true;
|
return true;
|
||||||
@@ -47,10 +52,8 @@ public class DeleteQueueCommand extends AbstractMusicCommand {
|
|||||||
@Override
|
@Override
|
||||||
public void execute(CommandContext context) {
|
public void execute(CommandContext context) {
|
||||||
MusicManager player = MusicManager.get(context.getGuild());
|
MusicManager player = MusicManager.get(context.getGuild());
|
||||||
if (!MusicUtils.checkIfConnected(player, context))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!MusicUtils.checkIfDj(player, context))
|
if (!MusicUtils.checkIfConnected(player, context))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (context.getArgumentsAsArray().length == 0) {
|
if (context.getArgumentsAsArray().length == 0) {
|
||||||
@@ -60,12 +63,12 @@ public class DeleteQueueCommand extends AbstractMusicCommand {
|
|||||||
|
|
||||||
if (context.getArgumentsAsArray().length > 0) {
|
if (context.getArgumentsAsArray().length > 0) {
|
||||||
|
|
||||||
int queueSize = player.getScheduler().getQueue().size();
|
int queueSize = player.getQueueSize();
|
||||||
if (context.getArg(0).equals("all")) {
|
if (context.getArg(0).equals("all")) {
|
||||||
|
|
||||||
if (queueSize > 0) {
|
if (queueSize > 0) {
|
||||||
player.leave();
|
player.leave();
|
||||||
player.getScheduler().getQueue().clear();
|
player.getScheduler().getQueueManager().getQueue().clear();
|
||||||
context.reply(String.format("Removed %d track%s from the queue", queueSize--, (queueSize > 1 ? "s" : "")));
|
context.reply(String.format("Removed %d track%s from the queue", queueSize--, (queueSize > 1 ? "s" : "")));
|
||||||
} else {
|
} else {
|
||||||
context.reply("Queue is empty!");
|
context.reply("Queue is empty!");
|
||||||
|
|||||||
@@ -47,9 +47,9 @@ public class LeaveCommand extends AbstractMusicCommand {
|
|||||||
@Override
|
@Override
|
||||||
public void execute(CommandContext context) {
|
public void execute(CommandContext context) {
|
||||||
MusicManager player = MusicManager.get(context.getGuild());
|
MusicManager player = MusicManager.get(context.getGuild());
|
||||||
if (!MusicUtils.checkIfConnected(player, context))
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
if (MusicUtils.checkIfConnected(player, context)) {
|
||||||
player.leave();
|
player.leave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,8 @@ import netneutrality.command.CommandUsage;
|
|||||||
import netneutrality.core.context.CommandContext;
|
import netneutrality.core.context.CommandContext;
|
||||||
import netneutrality.music.MusicManager;
|
import netneutrality.music.MusicManager;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class PlayCommand extends AbstractMusicCommand {
|
public class PlayCommand extends AbstractMusicCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -45,12 +47,12 @@ public class PlayCommand extends AbstractMusicCommand {
|
|||||||
@Override
|
@Override
|
||||||
public void execute(CommandContext context) {
|
public void execute(CommandContext context) {
|
||||||
MusicManager player = MusicManager.get(context.getGuild());
|
MusicManager player = MusicManager.get(context.getGuild());
|
||||||
context.getMessage().delete().queue();
|
context.getMessage().delete().queueAfter(1, TimeUnit.SECONDS);
|
||||||
|
|
||||||
if (context.getArgumentsAsArray().length > 0) {
|
if (context.getArgs().length > 0) {
|
||||||
player.play(context.getMessageText(), context, false, false);
|
player.play(context.getMessageText(), context, false, false);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
//TODO: resume queue
|
||||||
context.reply(getUsage());
|
context.reply(getUsage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,18 +43,22 @@ public class SkipCommand extends AbstractMusicCommand {
|
|||||||
@Override
|
@Override
|
||||||
public void execute(CommandContext context) {
|
public void execute(CommandContext context) {
|
||||||
MusicManager player = MusicManager.get(context.getGuild());
|
MusicManager player = MusicManager.get(context.getGuild());
|
||||||
|
|
||||||
if (!MusicUtils.checkIfConnected(player, context))
|
if (!MusicUtils.checkIfConnected(player, context))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Combined fonctionality of vote skip
|
if (UserFunction.isAdmin(context.getGuildUser())) {
|
||||||
//TODO: clean ifs
|
if (context.getArgs().length > 0) {
|
||||||
if (context.getArgumentsAsArray().length > 0 && UserFunction.isAdmin(context.getGuildUser())) {
|
try {
|
||||||
int skips = Integer.parseInt(context.getArg(0));
|
int skips = Integer.parseInt(context.getArg(0));
|
||||||
player.skip(skips);
|
player.skip(skips);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
context.reply("Please enter how many track(s) to skip");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (UserFunction.isAdmin(context.getGuildUser()))
|
|
||||||
player.skip(1);
|
player.skip(1);
|
||||||
else
|
}
|
||||||
|
} else {
|
||||||
player.voteSkip(context);
|
player.voteSkip(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import netneutrality.command.CommandUsage;
|
|||||||
import netneutrality.core.context.CommandContext;
|
import netneutrality.core.context.CommandContext;
|
||||||
import netneutrality.music.MusicManager;
|
import netneutrality.music.MusicManager;
|
||||||
import netneutrality.utils.MusicUtils;
|
import netneutrality.utils.MusicUtils;
|
||||||
import netneutrality.utils.UserFunction;
|
|
||||||
|
|
||||||
public class StopCommand extends AbstractMusicCommand {
|
public class StopCommand extends AbstractMusicCommand {
|
||||||
|
|
||||||
@@ -38,17 +37,15 @@ public class StopCommand extends AbstractMusicCommand {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return "Stop the music player, emptying the queue in the process";
|
return "Stop the music player, keeping the current queue.";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandContext context) {
|
public void execute(CommandContext context) {
|
||||||
MusicManager player = MusicManager.get(context.getGuild());
|
MusicManager player = MusicManager.get(context.getGuild());
|
||||||
if (!MusicUtils.checkIfConnected(player, context))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (UserFunction.isAdmin(context.getGuildUser()) || context.getGuildUser().getId().equals(player.getRequesterOfCurrentTrack().getId())) {
|
if (MusicUtils.checkIfConnected(player, context) && MusicUtils.isDj(player, context)) {
|
||||||
player.leave();
|
player.stopTrack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,6 @@ package netneutrality.command.music;
|
|||||||
* https://discord.gg/CdFcyQ
|
* https://discord.gg/CdFcyQ
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
|
||||||
import netneutrality.command.AbstractMusicCommand;
|
import netneutrality.command.AbstractMusicCommand;
|
||||||
import netneutrality.command.CommandUsage;
|
import netneutrality.command.CommandUsage;
|
||||||
import netneutrality.core.context.CommandContext;
|
import netneutrality.core.context.CommandContext;
|
||||||
@@ -48,16 +47,16 @@ public class ViewQueueCommand extends AbstractMusicCommand {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandContext context) {
|
public void execute(CommandContext context) {
|
||||||
Member member = context.getGuildUser();
|
|
||||||
MusicManager player = MusicManager.get(context.getGuild());
|
MusicManager player = MusicManager.get(context.getGuild());
|
||||||
if (!MusicUtils.checkIfConnected(player, context))
|
|
||||||
return;
|
|
||||||
|
|
||||||
int queueSize = player.getScheduler().getQueue().size();
|
if (MusicUtils.checkIfConnected(player, context)) {
|
||||||
|
int queueSize = player.getQueueSize();
|
||||||
if (queueSize > 0) {
|
if (queueSize > 0) {
|
||||||
context.reply(MessageFunction.buildViewQueueMessage(player, member, true));
|
context.reply(MessageFunction.buildViewQueueMessage(player, context.getGuildUser(), true));
|
||||||
} else {
|
} else {
|
||||||
context.reply("Queue is empty!");
|
context.reply("Queue is empty!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,6 @@ package netneutrality.command.music;
|
|||||||
import netneutrality.command.AbstractMusicCommand;
|
import netneutrality.command.AbstractMusicCommand;
|
||||||
import netneutrality.command.CommandUsage;
|
import netneutrality.command.CommandUsage;
|
||||||
import netneutrality.core.context.CommandContext;
|
import netneutrality.core.context.CommandContext;
|
||||||
import netneutrality.exceptions.CommandErrorException;
|
|
||||||
import netneutrality.music.MusicManager;
|
import netneutrality.music.MusicManager;
|
||||||
import netneutrality.utils.MusicUtils;
|
import netneutrality.utils.MusicUtils;
|
||||||
|
|
||||||
@@ -44,12 +43,8 @@ public class VolumeCommand extends AbstractMusicCommand {
|
|||||||
@Override
|
@Override
|
||||||
public void execute(CommandContext context) {
|
public void execute(CommandContext context) {
|
||||||
MusicManager player = MusicManager.get(context.getGuild());
|
MusicManager player = MusicManager.get(context.getGuild());
|
||||||
if (!MusicUtils.checkIfConnected(player, context))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!MusicUtils.checkIfDj(player, context))
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
if (MusicUtils.checkIfConnected(player, context) && MusicUtils.isDj(player, context)) {
|
||||||
try {
|
try {
|
||||||
int volume = Integer.parseInt(context.getArg(0));
|
int volume = Integer.parseInt(context.getArg(0));
|
||||||
|
|
||||||
@@ -62,6 +57,6 @@ public class VolumeCommand extends AbstractMusicCommand {
|
|||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
context.reply("Please enter a value from 0 to 100");
|
context.reply("Please enter a value from 0 to 100");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,9 +42,9 @@ public class VoteSkipCommand extends AbstractMusicCommand {
|
|||||||
@Override
|
@Override
|
||||||
public void execute(CommandContext context) {
|
public void execute(CommandContext context) {
|
||||||
MusicManager player = MusicManager.get(context.getGuild());
|
MusicManager player = MusicManager.get(context.getGuild());
|
||||||
if (!MusicUtils.checkIfConnected(player, context))
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
if (MusicUtils.checkIfConnected(player, context)) {
|
||||||
player.voteSkip(context);
|
player.voteSkip(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@@ -38,6 +38,7 @@ public class GuildManager {
|
|||||||
MUSIC_ROLE("MUSIC_ROLE", ""),
|
MUSIC_ROLE("MUSIC_ROLE", ""),
|
||||||
MUSIC_CHANNEL("MUSIC_CHANNEL", ""),
|
MUSIC_CHANNEL("MUSIC_CHANNEL", ""),
|
||||||
MUSIC_VOLUME("MUSIC_VOLUME", "30"),
|
MUSIC_VOLUME("MUSIC_VOLUME", "30"),
|
||||||
|
MUSIC_TOPIC("MUSIC_TOPIC", "0"),
|
||||||
BLACKLIST_CHANNELS("BLACKLIST_EXCLUDE_CHANNELS", "");
|
BLACKLIST_CHANNELS("BLACKLIST_EXCLUDE_CHANNELS", "");
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|||||||
@@ -67,6 +67,10 @@ public class CommandContext {
|
|||||||
return getArgumentsAsArray()[index];
|
return getArgumentsAsArray()[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String[] getArgs() {
|
||||||
|
return getArgumentsAsArray();
|
||||||
|
}
|
||||||
|
|
||||||
public String[] getArgumentsAsArray() {
|
public String[] getArgumentsAsArray() {
|
||||||
String msg = message.getContentDisplay().trim();
|
String msg = message.getContentDisplay().trim();
|
||||||
msg = msg.substring(Settings.getInstance().get("BOT_PREFIX", "$").length()).trim();
|
msg = msg.substring(Settings.getInstance().get("BOT_PREFIX", "$").length()).trim();
|
||||||
@@ -180,6 +184,7 @@ public class CommandContext {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (command.needAdmin() && !UserFunction.isAdmin(member)) {
|
if (command.needAdmin() && !UserFunction.isAdmin(member)) {
|
||||||
|
reply("You are not powerful enough, scrub");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public class MusicManager {
|
|||||||
this.guild = guild;
|
this.guild = guild;
|
||||||
this.playerManager = new DefaultAudioPlayerManager();
|
this.playerManager = new DefaultAudioPlayerManager();
|
||||||
this.player = playerManager.createPlayer();
|
this.player = playerManager.createPlayer();
|
||||||
this.scheduler = new TrackScheduler(player);
|
this.scheduler = new TrackScheduler(player, guild);
|
||||||
this.baseVolume = Integer.parseInt(GuildManager.getManager(guild).getSetting(GuildManager.Settings.MUSIC_VOLUME));
|
this.baseVolume = Integer.parseInt(GuildManager.getManager(guild).getSetting(GuildManager.Settings.MUSIC_VOLUME));
|
||||||
|
|
||||||
AudioSourceManagers.registerRemoteSources(playerManager);
|
AudioSourceManagers.registerRemoteSources(playerManager);
|
||||||
@@ -105,8 +105,12 @@ public class MusicManager {
|
|||||||
return player.getPlayingTrack();
|
return player.getPlayingTrack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized boolean isCurrentlyPlaying() {
|
||||||
|
return player.getPlayingTrack() != null;
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized Member getRequesterOfCurrentTrack() {
|
public synchronized Member getRequesterOfCurrentTrack() {
|
||||||
TrackScheduler.TrackInfo info = scheduler.getQueue().peek();
|
QueueManager.TrackInfo info = scheduler.getQueueManager().getQueue().peek();
|
||||||
|
|
||||||
if (info == null)
|
if (info == null)
|
||||||
return null;
|
return null;
|
||||||
@@ -124,7 +128,7 @@ public class MusicManager {
|
|||||||
guild.getAudioManager().closeAudioConnection();
|
guild.getAudioManager().closeAudioConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
scheduler.resetTopic();
|
scheduler.getTopicManager().detachTextChannel();
|
||||||
|
|
||||||
if (autoDisconnectThread != null) {
|
if (autoDisconnectThread != null) {
|
||||||
boolean cancel = autoDisconnectThread.cancel(true);
|
boolean cancel = autoDisconnectThread.cancel(true);
|
||||||
@@ -138,7 +142,7 @@ public class MusicManager {
|
|||||||
for (MusicManager mm : managers.values()) {
|
for (MusicManager mm : managers.values()) {
|
||||||
mm.leave();
|
mm.leave();
|
||||||
mm.player.destroy();
|
mm.player.destroy();
|
||||||
mm.scheduler.getQueue().clear();
|
mm.scheduler.getQueueManager().getQueue().clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,12 +161,14 @@ public class MusicManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!member.getVoiceState().inVoiceChannel()) {
|
if (!member.getVoiceState().inVoiceChannel()) {
|
||||||
throw new CommandErrorException("You are not in a voice channel", context, null);
|
context.reply("You are not in a voice channel");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
VoiceChannel vChannel = member.getVoiceState().getChannel();
|
VoiceChannel vChannel = member.getVoiceState().getChannel();
|
||||||
if (needToBeConnected && !isConnectedTo(vChannel)) {
|
if (needToBeConnected && !isConnectedTo(vChannel)) {
|
||||||
throw new CommandErrorException("Not in your voice channel", context, null);
|
context.reply("The player is not in your voice channel");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isConnectedTo(vChannel)) {
|
if (!isConnectedTo(vChannel)) {
|
||||||
@@ -170,7 +176,7 @@ public class MusicManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String identifier = SourceFinder.getIdentifier(url);
|
String identifier = SourceFinder.getIdentifier(url);
|
||||||
scheduler.setTextChannel(channel);
|
scheduler.getTopicManager().attachTextChannel(channel);
|
||||||
|
|
||||||
if (identifier != null) {
|
if (identifier != null) {
|
||||||
|
|
||||||
@@ -179,12 +185,11 @@ public class MusicManager {
|
|||||||
@Override
|
@Override
|
||||||
public void trackLoaded(AudioTrack audioTrack) {
|
public void trackLoaded(AudioTrack audioTrack) {
|
||||||
logger.debug("Found results for identifier: {}", identifier);
|
logger.debug("Found results for identifier: {}", identifier);
|
||||||
|
scheduler.getQueueManager().queue(audioTrack, member);
|
||||||
|
|
||||||
if (!silent) {
|
if (!silent) {
|
||||||
channel.sendMessageEmbeds(MessageFunction.buildAddingTrackMessage(audioTrack, member, identifier)).queue();
|
channel.sendMessageEmbeds(MessageFunction.buildAddingTrackMessage(audioTrack, member, identifier)).queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
scheduler.queue(audioTrack, member);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -192,20 +197,22 @@ public class MusicManager {
|
|||||||
if (identifier.startsWith("ytsearch:")) {
|
if (identifier.startsWith("ytsearch:")) {
|
||||||
AudioTrack track = audioPlaylist.getTracks().get(0);
|
AudioTrack track = audioPlaylist.getTracks().get(0);
|
||||||
logger.debug("Found results for identifier: {}", identifier);
|
logger.debug("Found results for identifier: {}", identifier);
|
||||||
|
scheduler.getQueueManager().queue(track, member);
|
||||||
|
|
||||||
if (!silent)
|
if (!silent) {
|
||||||
channel.sendMessageEmbeds(MessageFunction.buildAddingTrackMessage(track, member, String.format("https://youtu.be/%s", track.getIdentifier()))).queue();
|
channel.sendMessageEmbeds(MessageFunction.buildAddingTrackMessage(track, member, String.format("https://youtu.be/%s", track.getIdentifier()))).queue();
|
||||||
|
}
|
||||||
|
|
||||||
scheduler.queue(track, member);
|
|
||||||
} else {
|
} else {
|
||||||
logger.debug("Found results for playlist identifier: {}", identifier);
|
logger.debug("Found results for playlist identifier: {}", identifier);
|
||||||
|
|
||||||
if (!silent)
|
if (!silent) {
|
||||||
channel.sendMessageEmbeds(MessageFunction.buildAddingPlaylistMessage(audioPlaylist, member, identifier)).queue();
|
channel.sendMessageEmbeds(MessageFunction.buildAddingPlaylistMessage(audioPlaylist, member, identifier)).queue();
|
||||||
|
}
|
||||||
|
|
||||||
for (AudioTrack track : audioPlaylist.getTracks()) {
|
for (AudioTrack track : audioPlaylist.getTracks()) {
|
||||||
synchronized (scheduler.getQueue()) {
|
synchronized (scheduler.getQueueManager().getQueue()) {
|
||||||
scheduler.queue(track, member);
|
scheduler.getQueueManager().queue(track, member);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -232,7 +239,7 @@ public class MusicManager {
|
|||||||
if (num == 1) {
|
if (num == 1) {
|
||||||
skip(1);
|
skip(1);
|
||||||
} else {
|
} else {
|
||||||
scheduler.removeFromQueue(num);
|
scheduler.getQueueManager().removeFromQueue(num);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,23 +248,23 @@ public class MusicManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void skip(int nbTrack) {
|
public synchronized void skip(int nbTrack) {
|
||||||
if (!scheduler.getQueue().isEmpty()) {
|
if (!scheduler.getQueueManager().getQueue().isEmpty()) {
|
||||||
if (nbTrack >= scheduler.getQueue().size()) {
|
if (nbTrack >= scheduler.getQueueManager().getQueue().size()) {
|
||||||
nbTrack = 1;
|
nbTrack = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
scheduler.skipAndPlay(nbTrack);
|
scheduler.getQueueManager().skipAndPlay(nbTrack);
|
||||||
} else {
|
} else {
|
||||||
leave();
|
leave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void voteSkip(CommandContext context) {
|
public synchronized void voteSkip(CommandContext context) {
|
||||||
Queue<TrackScheduler.TrackInfo> queue = scheduler.getQueue();
|
Queue<QueueManager.TrackInfo> queue = scheduler.getQueueManager().getQueue();
|
||||||
VoiceChannel voiceChannel = guild.getAudioManager().getConnectedChannel();
|
VoiceChannel voiceChannel = guild.getAudioManager().getConnectedChannel();
|
||||||
TrackScheduler.TrackInfo info = queue.peek();
|
QueueManager.TrackInfo info = queue.peek();
|
||||||
|
|
||||||
if (getCurrentlyPlaying() == null || voiceChannel == null) {
|
if (!isCurrentlyPlaying() || voiceChannel == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,15 +297,15 @@ public class MusicManager {
|
|||||||
player.setVolume(volume);
|
player.setVolume(volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getQueueSize () {
|
||||||
|
synchronized (scheduler.getQueueManager().getQueue()) {
|
||||||
|
return scheduler.getQueueManager().getQueue().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public TrackScheduler getScheduler() {
|
public TrackScheduler getScheduler() {
|
||||||
return scheduler;
|
return scheduler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized ArrayList<AudioTrack> getAllQueuedTrack() {
|
|
||||||
ArrayList<AudioTrack> tracks = new ArrayList<>();
|
|
||||||
Queue<TrackScheduler.TrackInfo> queue = scheduler.getQueue();
|
|
||||||
|
|
||||||
queue.forEach(trackInfo -> tracks.add(trackInfo.getTrack()));
|
|
||||||
return tracks;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,187 @@
|
|||||||
|
package netneutrality.music;/*
|
||||||
|
* Copyright (c) anthorob
|
||||||
|
*
|
||||||
|
* https://xtremcommunity.com/
|
||||||
|
* https://discord.gg/CdFcyQ
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
||||||
|
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||||
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.LinkedBlockingDeque;
|
||||||
|
|
||||||
|
public class QueueManager {
|
||||||
|
|
||||||
|
static class TrackInfo {
|
||||||
|
|
||||||
|
private final AudioTrack track;
|
||||||
|
private final Member member;
|
||||||
|
private final Set<String> skips;
|
||||||
|
|
||||||
|
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 toggleSkip(Member member) {
|
||||||
|
if (!hasSkip(member))
|
||||||
|
skips.add(member.getId());
|
||||||
|
else
|
||||||
|
skips.remove(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 AudioPlayer player;
|
||||||
|
private final Guild guild;
|
||||||
|
private final Deque<TrackInfo> queue;
|
||||||
|
|
||||||
|
public QueueManager(AudioPlayer player, Guild guild) {
|
||||||
|
this.player = player;
|
||||||
|
this.guild = guild;
|
||||||
|
|
||||||
|
this.queue = new LinkedBlockingDeque<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Queue<TrackInfo> getQueue() {
|
||||||
|
synchronized (queue) {
|
||||||
|
return queue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Guild getGuild() {
|
||||||
|
return guild;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<AudioTrack> getAllQueuedTrack() {
|
||||||
|
synchronized (queue) {
|
||||||
|
ArrayList<AudioTrack> tracks = new ArrayList<>();
|
||||||
|
|
||||||
|
queue.forEach(trackInfo -> tracks.add(trackInfo.getTrack()));
|
||||||
|
return tracks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void queue(AudioTrack track, Member member) {
|
||||||
|
TrackInfo info = new TrackInfo(track, member);
|
||||||
|
|
||||||
|
synchronized (queue) {
|
||||||
|
if (queue.contains(info)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.getPlayingTrack() == null && !queue.isEmpty()) {
|
||||||
|
queue.addFirst(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((player.getPlayingTrack() == null && queue.isEmpty()) || player.getPlayingTrack() != null) {
|
||||||
|
queue.add(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.getPlayingTrack() == null) {
|
||||||
|
player.startTrack(queue.peek().getTrack(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void nextTrack(AudioPlayer player) {
|
||||||
|
synchronized (queue) {
|
||||||
|
TrackInfo last = queue.poll();
|
||||||
|
|
||||||
|
if (queue.peek() != null) {
|
||||||
|
player.startTrack(queue.peek().getTrack(), false);
|
||||||
|
} else {
|
||||||
|
player.stopTrack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void skipAndPlay(int nb) {
|
||||||
|
if (nb == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
synchronized (queue) {
|
||||||
|
for (int i = 0; i < nb; i++) {
|
||||||
|
TrackInfo last = queue.poll();
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackInfo current = queue.peek();
|
||||||
|
if (current != null) {
|
||||||
|
player.startTrack(current.getTrack(), false);
|
||||||
|
} else {
|
||||||
|
player.stopTrack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shuffle() {
|
||||||
|
synchronized (queue) {
|
||||||
|
if (queue.size() > 2) {
|
||||||
|
TrackInfo current = queue.poll();
|
||||||
|
|
||||||
|
ArrayList<TrackInfo> newQueue = new ArrayList<>(queue);
|
||||||
|
newQueue.remove(0);
|
||||||
|
|
||||||
|
Collections.shuffle(newQueue);
|
||||||
|
|
||||||
|
queue.clear();
|
||||||
|
queue.add(current);
|
||||||
|
queue.addAll(newQueue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void removeFromQueue(int index) {
|
||||||
|
synchronized (queue) {
|
||||||
|
ArrayList<TrackInfo> newQueue = new ArrayList<>(queue);
|
||||||
|
newQueue.remove(index - 1);
|
||||||
|
|
||||||
|
queue.clear();
|
||||||
|
queue.addAll(newQueue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -10,7 +10,9 @@ package netneutrality.music;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
enum SourceEnum {
|
public class SourceFinder {
|
||||||
|
|
||||||
|
public enum AvailableSource {
|
||||||
Youtube,
|
Youtube,
|
||||||
Soundcloud,
|
Soundcloud,
|
||||||
Bandcamp,
|
Bandcamp,
|
||||||
@@ -20,26 +22,25 @@ enum SourceEnum {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SourceFinder {
|
|
||||||
private static final Pattern youtubePattern = Pattern.compile("^(?:https?://)?(?:(?:www\\.)?)?(?:youtube\\.com|youtu\\.be)/.*?(?:embed|e|v|watch.*?v=)?/?([-_a-z0-9]{10,})?(?:&?index=\\d+)?(?>(?:playlist\\?|&)?list=([^#\\\\&?]{12,}))?", Pattern.CASE_INSENSITIVE);
|
private static final Pattern youtubePattern = Pattern.compile("^(?:https?://)?(?:(?:www\\.)?)?(?:youtube\\.com|youtu\\.be)/.*?(?:embed|e|v|watch.*?v=)?/?([-_a-z0-9]{10,})?(?:&?index=\\d+)?(?>(?:playlist\\?|&)?list=([^#\\\\&?]{12,}))?", Pattern.CASE_INSENSITIVE);
|
||||||
private static final Pattern soundcloudPattern = Pattern.compile("^(?:https?://)?(?:www\\.)?(?:m\\.)?soundcloud\\.com/([a-zA-Z0-9-_]+)/([a-zA-Z0-9-_]+)(?:\\\\?.*|)$", Pattern.CASE_INSENSITIVE);
|
private static final Pattern soundcloudPattern = Pattern.compile("^(?:https?://)?(?:www\\.)?(?:m\\.)?soundcloud\\.com/([a-zA-Z0-9-_]+)/([a-zA-Z0-9-_]+)(?:\\\\?.*|)$", Pattern.CASE_INSENSITIVE);
|
||||||
private static Matcher BandcampMatcher;
|
private static Matcher BandcampMatcher;
|
||||||
private static Matcher vimeoMatcher;
|
private static Matcher vimeoMatcher;
|
||||||
|
|
||||||
public static SourceEnum getSource(String url) {
|
public static AvailableSource getSource(String url) {
|
||||||
Matcher youtubeMatcher = youtubePattern.matcher(url);
|
Matcher youtubeMatcher = youtubePattern.matcher(url);
|
||||||
Matcher soundcloudMatcher = soundcloudPattern.matcher(url);
|
Matcher soundcloudMatcher = soundcloudPattern.matcher(url);
|
||||||
|
|
||||||
if (youtubeMatcher.find())
|
if (youtubeMatcher.find())
|
||||||
return SourceEnum.Youtube;
|
return AvailableSource.Youtube;
|
||||||
|
|
||||||
if (soundcloudMatcher.find())
|
if (soundcloudMatcher.find())
|
||||||
return SourceEnum.Soundcloud;
|
return AvailableSource.Soundcloud;
|
||||||
|
|
||||||
if (!(url.startsWith("http://") || url.startsWith("https://")))
|
if (!(url.startsWith("http://") || url.startsWith("https://")))
|
||||||
return SourceEnum.YTSearch;
|
return AvailableSource.YTSearch;
|
||||||
|
|
||||||
return SourceEnum.Nothing;
|
return AvailableSource.Nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getIdentifier(String url) {
|
public static String getIdentifier(String url) {
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package netneutrality.music;/*
|
||||||
|
* Copyright (c) anthorob
|
||||||
|
*
|
||||||
|
* https://xtremcommunity.com/
|
||||||
|
* https://discord.gg/CdFcyQ
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||||
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import net.dv8tion.jda.api.entities.TextChannel;
|
||||||
|
import netneutrality.core.GuildManager;
|
||||||
|
import netneutrality.thread.ThreadManager;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class TopicManager {
|
||||||
|
|
||||||
|
private final ScheduledExecutorService service;
|
||||||
|
private final Guild guild;
|
||||||
|
private TextChannel channel;
|
||||||
|
private String originalTopic;
|
||||||
|
|
||||||
|
public TopicManager(Guild guild) {
|
||||||
|
this.guild = guild;
|
||||||
|
this.service = (ScheduledExecutorService) ThreadManager.getExecutor("topic-management", ThreadManager.ExecutorType.SCHEDULED);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Guild getGuild() {
|
||||||
|
return guild;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextChannel getTextChannel() {
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOriginalTopic() {
|
||||||
|
return originalTopic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void attachTextChannel(TextChannel channel) {
|
||||||
|
this.channel = channel;
|
||||||
|
|
||||||
|
if (originalTopic == null) {
|
||||||
|
String current = channel.getTopic();
|
||||||
|
originalTopic = (current == null ? "" : current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void detachTextChannel() {
|
||||||
|
updateTopic(null);
|
||||||
|
|
||||||
|
this.channel = null;
|
||||||
|
this.originalTopic = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void updateTopic(AudioTrack track) {
|
||||||
|
if (isEnabled() && channel != null) {
|
||||||
|
|
||||||
|
if (track == null) {
|
||||||
|
LogManager.getLogger(TopicManager.class).debug("Resetting topic for channel [{}] in guild [{}]", channel.getId(), guild.getId());
|
||||||
|
channel.getManager().setTopic(originalTopic).queueAfter(3, TimeUnit.SECONDS, service);
|
||||||
|
} else {
|
||||||
|
channel.getManager().setTopic(":speaker: Now playing: " + track.getInfo().title).queueAfter(3, TimeUnit.SECONDS, service);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isEnabled() {
|
||||||
|
return "1".equals(GuildManager.getManager(guild).getSetting(GuildManager.Settings.MUSIC_TOPIC));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,142 +12,35 @@ import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter;
|
|||||||
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
||||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason;
|
import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
import net.dv8tion.jda.api.entities.TextChannel;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
|
||||||
|
|
||||||
public class TrackScheduler extends AudioEventAdapter {
|
public class TrackScheduler extends AudioEventAdapter {
|
||||||
|
|
||||||
static class TrackInfo {
|
|
||||||
|
|
||||||
private final AudioTrack track;
|
|
||||||
private final Member member;
|
|
||||||
private final Set<String> skips;
|
|
||||||
|
|
||||||
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 toggleSkip(Member member) {
|
|
||||||
if (!hasSkip(member))
|
|
||||||
skips.add(member.getId());
|
|
||||||
else
|
|
||||||
skips.remove(member.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasSkip(Member member) {
|
|
||||||
return skips.contains(member.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Member getRequester() {
|
|
||||||
return member;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(TrackScheduler.class);
|
private final static Logger logger = LoggerFactory.getLogger(TrackScheduler.class);
|
||||||
|
private final QueueManager queueManager;
|
||||||
|
private final TopicManager topicManager;
|
||||||
private final AudioPlayer player;
|
private final AudioPlayer player;
|
||||||
private final Queue<TrackInfo> queue;
|
private final Guild guild;
|
||||||
private TextChannel channel;
|
|
||||||
private String originalTopic;
|
|
||||||
|
|
||||||
public TrackScheduler(AudioPlayer player) {
|
public TrackScheduler(AudioPlayer player, Guild guild) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.queue = new LinkedBlockingQueue<>();
|
this.guild = guild;
|
||||||
|
this.queueManager = new QueueManager(player, guild);
|
||||||
|
this.topicManager = new TopicManager(guild);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void queue(AudioTrack track, Member member) {
|
public QueueManager getQueueManager() {
|
||||||
// Calling startTrack with the noInterrupt set to true will start the track only if nothing is currently playing. If
|
return queueManager;
|
||||||
// something is playing, it returns false and does nothing. In that case the player was already playing so this
|
|
||||||
// track goes to the queue instead.
|
|
||||||
queue.offer(new TrackInfo(track, member));
|
|
||||||
|
|
||||||
if (player.getPlayingTrack() == null) {
|
|
||||||
player.startTrack(track, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TopicManager getTopicManager() {
|
||||||
|
return topicManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized String getOriginalTopic() {
|
public AudioPlayer getPlayer() {
|
||||||
return originalTopic;
|
return player;
|
||||||
}
|
|
||||||
|
|
||||||
public TextChannel getTextChannel() {
|
|
||||||
return channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void setTextChannel(TextChannel channel) {
|
|
||||||
this.channel = channel;
|
|
||||||
|
|
||||||
if (originalTopic == null) {
|
|
||||||
originalTopic = channel.getTopic();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void resetTextChannel() {
|
|
||||||
this.channel = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized Queue<TrackInfo> getQueue() {
|
|
||||||
return queue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void resetTopic() {
|
|
||||||
if (channel != null && (originalTopic != null && !originalTopic.isEmpty())) {
|
|
||||||
//channel.getManager().setTopic(topic).queue();
|
|
||||||
}
|
|
||||||
|
|
||||||
originalTopic = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void nextTrack(AudioPlayer player) {
|
|
||||||
TrackInfo last = queue.poll();
|
|
||||||
|
|
||||||
if (queue.peek() != null) {
|
|
||||||
player.startTrack(queue.peek().getTrack(), false);
|
|
||||||
} else
|
|
||||||
player.stopTrack();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void skipAndPlay(int nb) {
|
|
||||||
if (nb == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (int i = 0; i < nb; i++) {
|
|
||||||
TrackInfo last = queue.poll();
|
|
||||||
}
|
|
||||||
|
|
||||||
TrackInfo current = queue.peek();
|
|
||||||
if (current != null) {
|
|
||||||
player.startTrack(current.getTrack(), false);
|
|
||||||
} else {
|
|
||||||
player.stopTrack();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected synchronized void removeFromQueue(int index) {
|
|
||||||
ArrayList<TrackInfo> newQueue = new ArrayList<>(queue);
|
|
||||||
newQueue.remove(index - 1);
|
|
||||||
|
|
||||||
queue.clear();
|
|
||||||
queue.addAll(newQueue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -162,30 +55,25 @@ public class TrackScheduler extends AudioEventAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTrackStart(AudioPlayer player, AudioTrack track) {
|
public void onTrackStart(AudioPlayer player, AudioTrack track) {
|
||||||
logger.debug("Starting track on guild {}: {}", channel.getGuild().getId(), track.getIdentifier());
|
logger.debug("Starting track on guild {}: {}", guild.getId(), track.getIdentifier());
|
||||||
// A track started playing
|
topicManager.updateTopic(track);
|
||||||
//channel.getManager().setTopic(":speaker: Now playing : " + track.getInfo().title).queue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) {
|
public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) {
|
||||||
resetTopic();
|
|
||||||
|
|
||||||
// check if mayStartNext
|
// check if mayStartNext
|
||||||
if (endReason == AudioTrackEndReason.FINISHED || endReason == AudioTrackEndReason.LOAD_FAILED) {
|
if (endReason == AudioTrackEndReason.FINISHED || endReason == AudioTrackEndReason.LOAD_FAILED) {
|
||||||
//logger.debug("Queue size before next: " + queue.size());
|
queueManager.nextTrack(player);
|
||||||
nextTrack(player);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endReason == AudioTrackEndReason.STOPPED) {
|
if (endReason == AudioTrackEndReason.STOPPED) {
|
||||||
synchronized (queue) {
|
synchronized (queueManager.getQueue()) {
|
||||||
queue.poll();
|
topicManager.updateTopic(null);
|
||||||
|
queueManager.getQueue().poll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//logger.debug("Queue size after next: " + queue.size());
|
|
||||||
|
|
||||||
// endReason == FINISHED: A track finished or died by an exception (mayStartNext = true).
|
// endReason == FINISHED: A track finished or died by an exception (mayStartNext = true).
|
||||||
// endReason == LOAD_FAILED: Loading of a track failed (mayStartNext = true).
|
// endReason == LOAD_FAILED: Loading of a track failed (mayStartNext = true).
|
||||||
// endReason == STOPPED: The player was stopped.
|
// endReason == STOPPED: The player was stopped.
|
||||||
@@ -196,13 +84,13 @@ public class TrackScheduler extends AudioEventAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTrackException(AudioPlayer player, AudioTrack track, FriendlyException exception) {
|
public void onTrackException(AudioPlayer player, AudioTrack track, FriendlyException exception) {
|
||||||
resetTopic();
|
topicManager.updateTopic(null);
|
||||||
channel.sendMessage("Error while playing track: " + track.getInfo().title).queue();
|
topicManager.getTextChannel().sendMessage("Error while playing track: " + track.getInfo().title).queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTrackStuck(AudioPlayer player, AudioTrack track, long thresholdMs) {
|
public void onTrackStuck(AudioPlayer player, AudioTrack track, long thresholdMs) {
|
||||||
resetTopic();
|
topicManager.updateTopic(null);
|
||||||
nextTrack(player);
|
queueManager.nextTrack(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,15 +26,10 @@ public class MusicPlayerAutoDisconnectThread implements Runnable {
|
|||||||
Guild guild = manager.getGuild();
|
Guild guild = manager.getGuild();
|
||||||
VoiceChannel channel = guild.getAudioManager().getConnectedChannel();
|
VoiceChannel channel = guild.getAudioManager().getConnectedChannel();
|
||||||
|
|
||||||
if (manager.getCurrentlyPlaying() == null && manager.getScheduler().getQueue().isEmpty()) {
|
|
||||||
manager.leave();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (channel != null) {
|
if (channel != null) {
|
||||||
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();
|
||||||
|
|
||||||
if (members.size() == 0)
|
if (members.size() == 0 || manager.getScheduler().getQueueManager().getQueue().isEmpty())
|
||||||
manager.leave();
|
manager.leave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ public class MessageFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static MessageEmbed buildViewQueueMessage(MusicManager manager, Member user, boolean currentlyPlaying) {
|
public static MessageEmbed buildViewQueueMessage(MusicManager manager, Member user, boolean currentlyPlaying) {
|
||||||
ArrayList<AudioTrack> tracks = manager.getAllQueuedTrack();
|
ArrayList<AudioTrack> tracks = manager.getScheduler().getQueueManager().getAllQueuedTrack();
|
||||||
AudioTrack current = manager.getCurrentlyPlaying();
|
AudioTrack current = manager.getCurrentlyPlaying();
|
||||||
|
|
||||||
EmbedBuilder message = new EmbedBuilder();
|
EmbedBuilder message = new EmbedBuilder();
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ public class MusicUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
VoiceChannel vChannel = context.getGuildUser().getVoiceState().getChannel();
|
|
||||||
if (!manager.isConnected()) {
|
if (!manager.isConnected()) {
|
||||||
context.reply("You are not in a voice channel");
|
context.reply("You are not in a voice channel");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VoiceChannel vChannel = context.getGuildUser().getVoiceState().getChannel();
|
||||||
if (!manager.isConnectedTo(vChannel)) {
|
if (!manager.isConnectedTo(vChannel)) {
|
||||||
context.reply("You are not in a voice channel");
|
context.reply("You are not in a voice channel");
|
||||||
return false;
|
return false;
|
||||||
@@ -36,13 +36,14 @@ public class MusicUtils {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean checkIfDj(MusicManager manager, CommandContext context) {
|
public static boolean isDj(MusicManager manager, CommandContext context) {
|
||||||
if (manager.getCurrentlyPlaying() != null) {
|
if (manager.isCurrentlyPlaying()) {
|
||||||
if (!UserFunction.isAdmin(context.getGuildUser()) || !manager.getRequesterOfCurrentTrack().getId().equals(context.getGuildUser().getId())) {
|
if (UserFunction.isAdmin(context.getGuildUser()) || manager.getRequesterOfCurrentTrack().getId().equals(context.getGuildUser().getId())) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
context.reply("You are not powerful enough, scrub");
|
context.reply("You are not powerful enough, scrub");
|
||||||
return false;
|
return false;
|
||||||
} else
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -24,6 +24,12 @@ logger.hibernate.level = info
|
|||||||
logger.hibernate.additivity = false
|
logger.hibernate.additivity = false
|
||||||
logger.hibernate.appenderRef.rolling.ref = LogToRollingFile
|
logger.hibernate.appenderRef.rolling.ref = LogToRollingFile
|
||||||
|
|
||||||
|
logger.jda.name = net.dv8tion.jda
|
||||||
|
logger.jda.level = info
|
||||||
|
logger.jda.additivity = false
|
||||||
|
logger.jda.appenderRef.rolling.ref = LogToRollingFile
|
||||||
|
logger.jda.appenderRef.console.ref = consoleLogger
|
||||||
|
|
||||||
logger.app.name = netneutrality
|
logger.app.name = netneutrality
|
||||||
logger.app.level = debug
|
logger.app.level = debug
|
||||||
logger.app.additivity = false
|
logger.app.additivity = false
|
||||||
|
|||||||
Reference in new issue
Block a user