Added and improved music player controls

This commit is contained in:
Ghoti 2020-08-05 22:29:17 -05:00
parent b63ec31138
commit 6c2f1900c2
38 changed files with 958 additions and 377 deletions

View File

@ -13,34 +13,42 @@ import com.fpghoti.biscuit.commands.CommandManager;
import com.fpghoti.biscuit.commands.client.AddCommand; import com.fpghoti.biscuit.commands.client.AddCommand;
import com.fpghoti.biscuit.commands.client.ChanIDCommand; import com.fpghoti.biscuit.commands.client.ChanIDCommand;
import com.fpghoti.biscuit.commands.client.DivideCommand; import com.fpghoti.biscuit.commands.client.DivideCommand;
import com.fpghoti.biscuit.commands.client.ForceSkipCommand;
import com.fpghoti.biscuit.commands.client.GetConfigCommand; import com.fpghoti.biscuit.commands.client.GetConfigCommand;
import com.fpghoti.biscuit.commands.client.GuildIDCommand; import com.fpghoti.biscuit.commands.client.GuildIDCommand;
import com.fpghoti.biscuit.commands.client.ToggleRoleCommand; import com.fpghoti.biscuit.commands.client.ToggleRoleCommand;
import com.fpghoti.biscuit.commands.client.HelpCommand; import com.fpghoti.biscuit.commands.client.HelpCommand;
import com.fpghoti.biscuit.commands.client.LoopMusicCommand;
import com.fpghoti.biscuit.commands.client.MultiplyCommand; import com.fpghoti.biscuit.commands.client.MultiplyCommand;
import com.fpghoti.biscuit.commands.client.NotSpammerCommand; import com.fpghoti.biscuit.commands.client.NotSpammerCommand;
import com.fpghoti.biscuit.commands.client.NowPlayingCommand;
import com.fpghoti.biscuit.commands.client.PauseCommand;
import com.fpghoti.biscuit.commands.client.TogglePauseCommand;
import com.fpghoti.biscuit.commands.client.MakeInviteCommand; import com.fpghoti.biscuit.commands.client.MakeInviteCommand;
import com.fpghoti.biscuit.commands.client.PingCommand; import com.fpghoti.biscuit.commands.client.PingCommand;
import com.fpghoti.biscuit.commands.client.PlayCommand;
import com.fpghoti.biscuit.commands.client.PlayFirstCommand;
import com.fpghoti.biscuit.commands.client.PowerCommand; import com.fpghoti.biscuit.commands.client.PowerCommand;
import com.fpghoti.biscuit.commands.client.QueueCommand;
import com.fpghoti.biscuit.commands.client.RecentSpammersCommand; import com.fpghoti.biscuit.commands.client.RecentSpammersCommand;
import com.fpghoti.biscuit.commands.client.SaveConfigCommand; import com.fpghoti.biscuit.commands.client.SaveConfigCommand;
import com.fpghoti.biscuit.commands.client.SkipCommand;
import com.fpghoti.biscuit.commands.client.SoftMuteCommand; import com.fpghoti.biscuit.commands.client.SoftMuteCommand;
import com.fpghoti.biscuit.commands.client.SquareRootCommand; import com.fpghoti.biscuit.commands.client.SquareRootCommand;
import com.fpghoti.biscuit.commands.client.SubtractCommand; import com.fpghoti.biscuit.commands.client.SubtractCommand;
import com.fpghoti.biscuit.commands.client.UIDCommand; import com.fpghoti.biscuit.commands.client.UIDCommand;
import com.fpghoti.biscuit.commands.client.UnSoftMuteCommand; import com.fpghoti.biscuit.commands.client.UnSoftMuteCommand;
import com.fpghoti.biscuit.commands.client.UnpauseCommand;
import com.fpghoti.biscuit.commands.client.WikiCommand; import com.fpghoti.biscuit.commands.client.WikiCommand;
import com.fpghoti.biscuit.commands.client.WipeQueueCommand; import com.fpghoti.biscuit.commands.client.music.ClearCommand;
import com.fpghoti.biscuit.commands.client.music.ForceSkipCommand;
import com.fpghoti.biscuit.commands.client.music.ForceSkipToCommand;
import com.fpghoti.biscuit.commands.client.music.ClearUserSongsCommand;
import com.fpghoti.biscuit.commands.client.music.LoopMusicCommand;
import com.fpghoti.biscuit.commands.client.music.MoveToCommand;
import com.fpghoti.biscuit.commands.client.music.NowPlayingCommand;
import com.fpghoti.biscuit.commands.client.music.PauseCommand;
import com.fpghoti.biscuit.commands.client.music.PlayCommand;
import com.fpghoti.biscuit.commands.client.music.PlayFirstCommand;
import com.fpghoti.biscuit.commands.client.music.QueueCommand;
import com.fpghoti.biscuit.commands.client.music.RemoveCommand;
import com.fpghoti.biscuit.commands.client.music.ShuffleCommand;
import com.fpghoti.biscuit.commands.client.music.SkipAllCommand;
import com.fpghoti.biscuit.commands.client.music.SkipCommand;
import com.fpghoti.biscuit.commands.client.music.TogglePauseCommand;
import com.fpghoti.biscuit.commands.client.music.UnpauseCommand;
import com.fpghoti.biscuit.commands.client.music.VolumeCommand;
import com.fpghoti.biscuit.commands.client.music.WipeQueueCommand;
import com.fpghoti.biscuit.commands.console.GuildSayCommand; import com.fpghoti.biscuit.commands.console.GuildSayCommand;
import com.fpghoti.biscuit.commands.console.SayCommand; import com.fpghoti.biscuit.commands.console.SayCommand;
import com.fpghoti.biscuit.commands.console.ShutdownConsoleCommand; import com.fpghoti.biscuit.commands.console.ShutdownConsoleCommand;
@ -151,6 +159,9 @@ public class Main {
CommandManager.addCommand(new SaveConfigCommand()); CommandManager.addCommand(new SaveConfigCommand());
CommandManager.addCommand(new GuildIDCommand()); CommandManager.addCommand(new GuildIDCommand());
CommandManager.addCommand(new WikiCommand()); CommandManager.addCommand(new WikiCommand());
//Music Client
CommandManager.addCommand(new PlayCommand()); CommandManager.addCommand(new PlayCommand());
CommandManager.addCommand(new PlayFirstCommand()); CommandManager.addCommand(new PlayFirstCommand());
CommandManager.addCommand(new ForceSkipCommand()); CommandManager.addCommand(new ForceSkipCommand());
@ -162,6 +173,14 @@ public class Main {
CommandManager.addCommand(new NowPlayingCommand()); CommandManager.addCommand(new NowPlayingCommand());
CommandManager.addCommand(new WipeQueueCommand()); CommandManager.addCommand(new WipeQueueCommand());
CommandManager.addCommand(new LoopMusicCommand()); CommandManager.addCommand(new LoopMusicCommand());
CommandManager.addCommand(new VolumeCommand());
CommandManager.addCommand(new ShuffleCommand());
CommandManager.addCommand(new RemoveCommand());
CommandManager.addCommand(new ClearCommand());
CommandManager.addCommand(new MoveToCommand());
CommandManager.addCommand(new ForceSkipToCommand());
CommandManager.addCommand(new ClearUserSongsCommand());
CommandManager.addCommand(new SkipAllCommand());
//Console //Console

View File

@ -1,76 +0,0 @@
package com.fpghoti.biscuit.audio;
import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.biscuit.Biscuit;
import com.fpghoti.biscuit.rest.MessageText;
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
import net.dv8tion.jda.api.entities.TextChannel;
public class AudioResultHandler implements AudioLoadResultHandler {
private Biscuit biscuit;
private String uid;
private TextChannel channel;
private String searchPhrase;
private boolean search;
private boolean first;
private boolean playAfterQueue;
public AudioResultHandler(String uid, TextChannel channel, boolean search, String searchPhrase, boolean first, boolean playAfterQueue) {
this.biscuit = Biscuit.getBiscuit(channel.getGuild());
this.uid = uid;
this.channel = channel;
this.search = search;
this.searchPhrase = searchPhrase;
this.first = first;
this.playAfterQueue = playAfterQueue;
}
@Override
public void trackLoaded(AudioTrack track) {
if(first) {
biscuit.getAudioScheduler().queue(track, uid, channel, 1);
}else {
biscuit.getAudioScheduler().queue(track, uid, channel);
}
if(playAfterQueue) {
biscuit.getAudioScheduler().startPlaying();
}
}
@Override
public void playlistLoaded(AudioPlaylist playlist) {
AudioTrack track = playlist.getTracks().get(0);
if(first) {
biscuit.getAudioScheduler().queue(track, uid, channel, 1);
}else {
biscuit.getAudioScheduler().queue(track, uid, channel);
}
if(playAfterQueue) {
biscuit.getAudioScheduler().startPlaying();
}
}
@Override
public void noMatches() {
if(!search) {
biscuit.log("Exact match not found. Searching instead...");
Main.getPlayerManager().loadItemOrdered(biscuit.getGuild(),"ytsearch:" + searchPhrase, new AudioResultHandler(uid, channel, true, searchPhrase, first, false));
}else {
MessageText.send(channel, "Song match not found.");
}
}
@Override
public void loadFailed(FriendlyException exception) {
exception.printStackTrace();
MessageText.send(channel, "An error was encountered while attempting to load audio.");
}
}

View File

@ -5,6 +5,9 @@ import java.util.ArrayList;
import com.fpghoti.biscuit.Main; import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.audio.queue.AudioQueue; import com.fpghoti.biscuit.audio.queue.AudioQueue;
import com.fpghoti.biscuit.audio.queue.QueuedTrack; import com.fpghoti.biscuit.audio.queue.QueuedTrack;
import com.fpghoti.biscuit.audio.request.youtube.YTImmediateRequest;
import com.fpghoti.biscuit.audio.request.youtube.YTRequest;
import com.fpghoti.biscuit.audio.result.YTResultHandler;
import com.fpghoti.biscuit.biscuit.Biscuit; import com.fpghoti.biscuit.biscuit.Biscuit;
import com.fpghoti.biscuit.rest.MessageText; import com.fpghoti.biscuit.rest.MessageText;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
@ -13,6 +16,7 @@ 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.MessageEmbed;
import net.dv8tion.jda.api.entities.TextChannel; import net.dv8tion.jda.api.entities.TextChannel;
public class AudioScheduler extends AudioEventAdapter { public class AudioScheduler extends AudioEventAdapter {
@ -59,7 +63,8 @@ public class AudioScheduler extends AudioEventAdapter {
TextChannel channel = qt.getCommandChannel(); TextChannel channel = qt.getCommandChannel();
MessageText.send(channel, "The video selected cannot be played through the music player. An alternate track will be played if available."); MessageText.send(channel, "The video selected cannot be played through the music player. An alternate track will be played if available.");
title = title.toLowerCase().replace("vevo", "") + " lyrics"; title = title.toLowerCase().replace("vevo", "") + " lyrics";
Main.getPlayerManager().loadItemOrdered(biscuit.getGuild(),"ytsearch:" + title, new AudioResultHandler(qt.getUserId(), channel, true, title, true, !queue.isEmpty())); YTRequest request = new YTImmediateRequest(channel, qt.getUserId(), title);
Main.getPlayerManager().loadItemOrdered(biscuit.getGuild(),"ytsearch:" + title, new YTResultHandler(request));
return; return;
} }
break; break;
@ -133,6 +138,7 @@ public class AudioScheduler extends AudioEventAdapter {
return; return;
} }
biscuit.getGuild().getAudioManager().closeAudioConnection(); biscuit.getGuild().getAudioManager().closeAudioConnection();
biscuit.getAudioPlayer().setVolume(100);
skips.clear(); skips.clear();
return; return;
} }
@ -167,9 +173,17 @@ public class AudioScheduler extends AudioEventAdapter {
public AudioQueue getQueue(){ public AudioQueue getQueue(){
return queue; return queue;
} }
public void skip() { public void skip() {
skip(null);
}
public void skip(TextChannel channel) {
biscuit.getAudioPlayer().stopTrack(); biscuit.getAudioPlayer().stopTrack();
if(channel != null && queue.getNext() != null ) {
MessageEmbed next = queue.getNext().getEmbedMessage("Now Playing:");
MessageText.send(channel, next);
}
startPlaying(); startPlaying();
} }

View File

@ -0,0 +1,76 @@
package com.fpghoti.biscuit.audio;
import com.fpghoti.biscuit.biscuit.Biscuit;
import com.fpghoti.biscuit.rest.MessageText;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.entities.VoiceChannel;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.managers.AudioManager;
public class PlayCommandUtil {
public static boolean connectToChannel(GuildMessageReceivedEvent event) {
Guild guild = event.getGuild();
Biscuit biscuit = Biscuit.getBiscuit(guild);
TextChannel textChannel = event.getChannel();
String vcname = "";
if(!event.getMember().getVoiceState().inVoiceChannel()) {
MessageText.send(textChannel, "You must be in a voice channel to do this!");
return false;
}
vcname = event.getMember().getVoiceState().getChannel().getName();
String[] musicChannels = biscuit.getProperties().getMusicChannels();
if(musicChannels.length >= 1) {
boolean found = false;
for(String cname : musicChannels) {
if(event.getMember().getVoiceState().getChannel().getName().equalsIgnoreCase(cname)) {
found = true;
break;
}
}
if(found == false) {
MessageText.send(textChannel, "You are not in a channel that is authorized to use the music player.");
return false;
}
}
if(biscuit.getAudioPlayer().getPlayingTrack() != null && guild.getAudioManager().isConnected() && !guild.getAudioManager().getConnectedChannel().getMembers().contains(event.getMember())) {
MessageText.send(textChannel, "Music is already playing in a voice channel. Connect to "
+ "that channel, then queue your song.");
return false;
}
VoiceChannel voiceChannel = guild.getVoiceChannelsByName(vcname, true).get(0);
AudioManager manager = guild.getAudioManager();
manager.setSendingHandler(new AudioHandler(biscuit.getAudioPlayer()));
manager.openAudioConnection(voiceChannel);
return true;
}
public static String getSearchPhrase(String[] args) {
String searchPhrase = args[0];
if(args.length > 1) {
for(int i = 1; i < args.length; i++) {
searchPhrase = searchPhrase + " " + args[i];
}
}
return searchPhrase;
}
public static String getID(GuildMessageReceivedEvent event) {
return getID(event.getMessage().getContentRaw().split(" ")[1]);
}
public static String getID(String url) {
String[] s = url.split("=");
if(s.length > 1) {
return s[1].split("&")[0];
}
return url;
}
}

View File

@ -1,6 +1,7 @@
package com.fpghoti.biscuit.audio.queue; package com.fpghoti.biscuit.audio.queue;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import com.fpghoti.biscuit.rest.MessageText; import com.fpghoti.biscuit.rest.MessageText;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack; import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
@ -19,13 +20,13 @@ public class AudioQueue {
} }
public ArrayList<QueuedTrack> getUserTracks(String userId){ public ArrayList<QueuedTrack> getUserTracks(String userId){
ArrayList<QueuedTrack> tracks = new ArrayList<QueuedTrack>(); ArrayList<QueuedTrack> qts = new ArrayList<QueuedTrack>();
for(QueuedTrack qt : tracks) { for(QueuedTrack qt : tracks) {
if(qt.getUserId().equals(userId)) { if(qt.getUserId().equals(userId)) {
tracks.add(qt); qts.add(qt);
} }
} }
return tracks; return qts;
} }
public void removeUserTracks(String userId) { public void removeUserTracks(String userId) {
@ -33,6 +34,19 @@ public class AudioQueue {
tracks.remove(qt); tracks.remove(qt);
} }
} }
public void shuffleUserTracks(String userId) {
ArrayList<QueuedTrack> qts = getUserTracks(userId);
Collections.shuffle(qts);
int index = 0;
for(int i = 0; i < tracks.size(); i++) {
QueuedTrack track = tracks.get(i);
if(track.getUserId().equals(userId)) {
tracks.set(i, qts.get(index));
index++;
}
}
}
public void playNext() { public void playNext() {
QueuedTrack next = tracks.iterator().next(); QueuedTrack next = tracks.iterator().next();
@ -129,6 +143,26 @@ public class AudioQueue {
tracks.remove(track); tracks.remove(track);
return true; return true;
} }
//Goes by viewable place rather than index for
//easy implementation into command.
public boolean removeTracksBefore(int place) {
int index = place - 1;
if(index < 1) {
return false;
}
ArrayList<QueuedTrack> trs = new ArrayList<QueuedTrack>(tracks);
int count = 0;
for(QueuedTrack t : trs) {
if(count < index) {
tracks.remove(t);
}else {
return true;
}
count++;
}
return true;
}
public QueuedTrack getNext() { public QueuedTrack getNext() {
if(isEmpty()) { if(isEmpty()) {

View File

@ -62,7 +62,15 @@ public class QueuedTrack {
embed.setTitle(title, track.getInfo().uri); embed.setTitle(title, track.getInfo().uri);
embed.setColor(Color.CYAN); embed.setColor(Color.CYAN);
String desc = "Author: " + track.getInfo().author + "\nLength: " + Util.getTime(track.getDuration()); long duration = track.getDuration();
//Duration seems to change after track begins playing
//This is to make the embeds more consistant with each other
if(showRemaining) {
duration+=1000;
}
String desc = "Author: " + track.getInfo().author + "\nLength: " + Util.getTime(duration);
if(showRemaining) { if(showRemaining) {
desc = desc + "\nTime Remaining: " + Util.getTime(track.getDuration() - track.getPosition()); desc = desc + "\nTime Remaining: " + Util.getTime(track.getDuration() - track.getPosition());

View File

@ -0,0 +1,44 @@
package com.fpghoti.biscuit.audio.request;
import com.fpghoti.biscuit.biscuit.Biscuit;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
public abstract class PlayRequest {
private TextChannel channel;
private Biscuit biscuit;
private String authorId;
private String identifier;
public PlayRequest(Message message, String identifier) {
this(message.getTextChannel(), message.getAuthor().getId(), identifier);
}
public PlayRequest(TextChannel channel, String authorId, String identifier) {
this.channel = channel;
this.authorId = authorId;
this.identifier = identifier;
this.biscuit = Biscuit.getBiscuit(channel.getGuild());
}
public TextChannel getRequestChannel() {
return channel;
}
public Biscuit getBiscuit() {
return biscuit;
}
public String getAuthorId() {
return authorId;
}
public String getIdentifier() {
return identifier;
}
public abstract RequestType getType();
}

View File

@ -0,0 +1,9 @@
package com.fpghoti.biscuit.audio.request;
public enum RequestType {
YOUTUBE,
YOUTUBE_IMMEDIATE,
YOUTUBE_PRIORITY;
}

View File

@ -0,0 +1,23 @@
package com.fpghoti.biscuit.audio.request.youtube;
import com.fpghoti.biscuit.audio.request.RequestType;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
public class YTImmediateRequest extends YTRequest{
public YTImmediateRequest(Message message, String identifier) {
super(message, identifier);
}
public YTImmediateRequest(TextChannel channel, String authorId, String identifier) {
super(channel, authorId, identifier);
}
@Override
public RequestType getType() {
return RequestType.YOUTUBE_IMMEDIATE;
}
}

View File

@ -0,0 +1,34 @@
package com.fpghoti.biscuit.audio.request.youtube;
import com.fpghoti.biscuit.audio.request.RequestType;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
public class YTPriorityRequest extends YTRequest{
int insertSlot;
public YTPriorityRequest(Message message, String identifier, int insertSlot) {
this(message.getTextChannel(), message.getAuthor().getId(), identifier, insertSlot);
}
public YTPriorityRequest(TextChannel channel, String authorId, String identifier, int insertSlot) {
super(channel, authorId, identifier);
this.insertSlot = insertSlot;
}
public int getSlot() {
return insertSlot;
}
public void setSlot(int slotNumber) {
insertSlot = slotNumber;
}
@Override
public RequestType getType() {
return RequestType.YOUTUBE_PRIORITY;
}
}

View File

@ -0,0 +1,39 @@
package com.fpghoti.biscuit.audio.request.youtube;
import com.fpghoti.biscuit.audio.request.PlayRequest;
import com.fpghoti.biscuit.audio.request.RequestType;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
public class YTRequest extends PlayRequest{
private boolean searchMode;
public YTRequest(Message message, String identifier) {
this(message.getTextChannel(), message.getAuthor().getId(), identifier);
}
public YTRequest(TextChannel channel, String authorId, String identifier) {
super(channel, authorId, identifier);
searchMode = false;
}
public boolean inSearchMode() {
return searchMode;
}
public void enableSearchMode() {
searchMode = true;
}
public void disableSearchMode() {
searchMode = false;
}
@Override
public RequestType getType() {
return RequestType.YOUTUBE;
}
}

View File

@ -0,0 +1,85 @@
package com.fpghoti.biscuit.audio.result;
import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.audio.AudioScheduler;
import com.fpghoti.biscuit.audio.request.PlayRequest;
import com.fpghoti.biscuit.audio.request.youtube.YTPriorityRequest;
import com.fpghoti.biscuit.audio.request.youtube.YTRequest;
import com.fpghoti.biscuit.biscuit.Biscuit;
import com.fpghoti.biscuit.rest.MessageText;
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
public class YTResultHandler implements AudioLoadResultHandler {
private Biscuit biscuit;
private YTRequest request;
public YTResultHandler(YTRequest request) {
this.request = request;
this.biscuit = request.getBiscuit();
}
public PlayRequest getRequest() {
return request;
}
public void handleTrack(AudioTrack track) {
AudioScheduler sched = biscuit.getAudioScheduler();
switch(request.getType()) {
case YOUTUBE:
sched.queue(track, request.getAuthorId(), request.getRequestChannel());
break;
case YOUTUBE_PRIORITY:
YTPriorityRequest prq = (YTPriorityRequest) request;
sched.queue(track, request.getAuthorId(), request.getRequestChannel(), prq.getSlot());
break;
case YOUTUBE_IMMEDIATE:
sched.queue(track, request.getAuthorId(), request.getRequestChannel(), 1);
if(!sched.getQueue().isEmpty()) {
sched.startPlaying();
}
break;
default:
biscuit.error("YouTube result handler received an incompatible request.");
break;
}
}
@Override
public void trackLoaded(AudioTrack track) {
handleTrack(track);
}
@Override
public void playlistLoaded(AudioPlaylist playlist) {
AudioTrack track = playlist.getTracks().get(0);
handleTrack(track);
}
@Override
public void noMatches() {
if(!request.inSearchMode()) {
biscuit.log("Exact match not found. Searching instead...");
request.enableSearchMode();
Main.getPlayerManager().loadItemOrdered(biscuit.getGuild(),"ytsearch:" + request.getIdentifier(), new YTResultHandler(request));
}else {
MessageText.send(request.getRequestChannel(), "Song match not found.");
}
}
@Override
public void loadFailed(FriendlyException exception) {
exception.printStackTrace();
MessageText.send(request.getRequestChannel(), "An error was encountered while attempting to load audio.");
}
}

View File

@ -1,90 +0,0 @@
package com.fpghoti.biscuit.commands.client;
import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.audio.AudioHandler;
import com.fpghoti.biscuit.audio.AudioResultHandler;
import com.fpghoti.biscuit.biscuit.Biscuit;
import com.fpghoti.biscuit.commands.base.MusicClientCommand;
import com.fpghoti.biscuit.rest.MessageText;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.entities.VoiceChannel;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.managers.AudioManager;
public class PlayCommand extends MusicClientCommand{
public PlayCommand() {
name = "Play";
description = "Plays the specified song or plays a song found using search parameters.";
usage = Main.getMainBiscuit().getProperties().getCommandSignifier() + "play <YouTube link OR Search Phrase>";
minArgs = 1;
maxArgs = 2000;
identifiers.add("play");
}
@Override
public void execute(String[] args, GuildMessageReceivedEvent event) {
Guild guild = event.getGuild();
Biscuit b = Biscuit.getBiscuit(guild);
TextChannel tchannel = event.getChannel();
String searchPhrase = args[0];
if(args.length > 1) {
for(int i = 1; i < args.length; i++) {
searchPhrase = searchPhrase + " " + args[i];
}
}
b.log(event.getAuthor().getName() + " issued a command: -play " + searchPhrase);
String vcname = "";
if(!event.getMember().getVoiceState().inVoiceChannel()) {
MessageText.send(tchannel, "You must be in a voice channel to do this!");
return;
}
vcname = event.getMember().getVoiceState().getChannel().getName();
String[] musicChannels = b.getProperties().getMusicChannels();
if(musicChannels.length >= 1) {
boolean found = false;
for(String cname : musicChannels) {
if(event.getMember().getVoiceState().getChannel().getName().equalsIgnoreCase(cname)) {
found = true;
break;
}
}
if(found == false) {
MessageText.send(tchannel, "You are not in a channel that is authorized to use the music player.");
return;
}
}
if(b.getAudioPlayer().getPlayingTrack() != null && guild.getAudioManager().isConnected() && !guild.getAudioManager().getConnectedChannel().getMembers().contains(event.getMember())) {
MessageText.send(tchannel, "Music is already playing in a voice channel. Connect to "
+ "that channel, then queue your song.");
return;
}
VoiceChannel channel = guild.getVoiceChannelsByName(vcname, true).get(0);
AudioManager manager = guild.getAudioManager();
manager.setSendingHandler(new AudioHandler(b.getAudioPlayer()));
manager.openAudioConnection(channel);
AudioPlayerManager playerManager = Main.getPlayerManager();
String vidid = getID(event.getMessage().getContentRaw().split(" ")[1]);
playerManager.loadItemOrdered(guild, vidid, new AudioResultHandler(event.getAuthor().getId(), tchannel, false, searchPhrase, false, false));
}
private String getID(String url) {
String[] s = url.split("=");
if(s.length > 1) {
return s[1].split("&")[0];
}
return url;
}
}

View File

@ -1,97 +0,0 @@
package com.fpghoti.biscuit.commands.client;
import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.audio.AudioHandler;
import com.fpghoti.biscuit.audio.AudioResultHandler;
import com.fpghoti.biscuit.biscuit.Biscuit;
import com.fpghoti.biscuit.commands.base.MusicClientCommand;
import com.fpghoti.biscuit.rest.MessageText;
import com.fpghoti.biscuit.util.PermUtil;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.entities.VoiceChannel;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.managers.AudioManager;
public class PlayFirstCommand extends MusicClientCommand{
public PlayFirstCommand() {
name = "Play First";
description = "Places specified song at the front of the queue.";
usage = Main.getMainBiscuit().getProperties().getCommandSignifier() + "playfirst <YouTube link OR Search Phrase>";
minArgs = 1;
maxArgs = 2000;
identifiers.add("playfirst");
}
@Override
public void execute(String[] args, GuildMessageReceivedEvent event) {
Guild guild = event.getGuild();
Biscuit b = Biscuit.getBiscuit(guild);
TextChannel tchannel = event.getChannel();
String searchPhrase = args[0];
if(args.length > 1) {
for(int i = 1; i < args.length; i++) {
searchPhrase = searchPhrase + " " + args[i];
}
}
b.log(event.getAuthor().getName() + " issued a command: -play " + searchPhrase);
String vcname = "";
if(!PermUtil.isMod(event.getMember())) {
MessageText.send(tchannel, "You do not have permission to do this!");
return;
}
if(!event.getMember().getVoiceState().inVoiceChannel()) {
MessageText.send(tchannel, "You must be in a voice channel to do this!");
return;
}
vcname = event.getMember().getVoiceState().getChannel().getName();
String[] musicChannels = b.getProperties().getMusicChannels();
if(musicChannels.length >= 1) {
boolean found = false;
for(String cname : musicChannels) {
if(event.getMember().getVoiceState().getChannel().getName().equalsIgnoreCase(cname)) {
found = true;
break;
}
}
if(found == false) {
MessageText.send(tchannel, "You are not in a channel that is authorized to use the music player.");
return;
}
}
if(b.getAudioPlayer().getPlayingTrack() != null && guild.getAudioManager().isConnected() && !guild.getAudioManager().getConnectedChannel().getMembers().contains(event.getMember())) {
MessageText.send(tchannel, "Music is already playing in a voice channel. Connect to "
+ "that channel, then queue your song.");
return;
}
VoiceChannel channel = guild.getVoiceChannelsByName(vcname, true).get(0);
AudioManager manager = guild.getAudioManager();
manager.setSendingHandler(new AudioHandler(b.getAudioPlayer()));
manager.openAudioConnection(channel);
AudioPlayerManager playerManager = Main.getPlayerManager();
String vidid = getID(event.getMessage().getContentRaw().split(" ")[1]);
playerManager.loadItemOrdered(guild, vidid, new AudioResultHandler(event.getAuthor().getId(), tchannel, false, searchPhrase, true, false));
}
private String getID(String url) {
String[] s = url.split("=");
if(s.length > 1) {
return s[1].split("&")[0];
}
return url;
}
}

View File

@ -1,72 +0,0 @@
package com.fpghoti.biscuit.commands.client;
import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.biscuit.Biscuit;
import com.fpghoti.biscuit.commands.base.MusicClientCommand;
import com.fpghoti.biscuit.rest.MessageText;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
public class SkipCommand extends MusicClientCommand{
public SkipCommand() {
name = "Skip";
description = "Sends a vote to skip the song that is currently playing.";
usage = Main.getMainBiscuit().getProperties().getCommandSignifier() + "skip";
minArgs = 0;
maxArgs = 0;
identifiers.add("skip");
}
@Override
public void execute(String[] args, GuildMessageReceivedEvent event) {
//TODO Redo vote skipping. It does not function correctly.
Biscuit b = Biscuit.getBiscuit(event.getGuild());
b.log(event.getAuthor().getName() + " issued a command: -skip");
if(b.getAudioPlayer().getPlayingTrack() == null) {
MessageText.send(event.getChannel(), "There is not a song playing for you to skip!");
return;
}
if(!event.getGuild().getAudioManager().getConnectedChannel().getMembers().contains(event.getMember())) {
MessageText.send(event.getChannel(), "You need to be in the same voice channel in order to skip!");
return;
}
if(b.getAudioScheduler().getVotes() >= (event.getGuild().getAudioManager().getConnectedChannel().getMembers().size() - 1) / 2) {
MessageText.send(event.getChannel(), "Skip vote status: **[" + ( b.getAudioScheduler().getVotes() + 1) + "/"
+ (event.getGuild().getAudioManager().getConnectedChannel().getMembers().size() - 1) + "]**"
+ "\nSkipping current track.");
if(b.getAudioScheduler().getQueue().getNext() != null ) {
MessageEmbed next = b.getAudioScheduler().getQueue().getNext().getEmbedMessage("Now Playing:");
MessageText.send(event.getChannel(), next);
}
b.getAudioScheduler().skip();
return;
}
if(b.getAudioScheduler().voteSkip(event.getAuthor().getId())) {
MessageText.send(event.getChannel(), "You voted to skip the current track.");
}else {
MessageText.send(event.getChannel(), "You cannot vote to skip this track again."
+ "\nSkip vote status: **[" + b.getAudioScheduler().getVotes() + "/"
+ (event.getGuild().getAudioManager().getConnectedChannel().getMembers().size() - 1) + "]**");
}
if(b.getAudioScheduler().getVotes() >= (event.getGuild().getAudioManager().getConnectedChannel().getMembers().size() - 1) / 2) {
MessageText.send(event.getChannel(), "Skip vote status: **[" + b.getAudioScheduler().getVotes() + "/"
+ event.getGuild().getAudioManager().getConnectedChannel().getMembers().size() + "]**"
+ "\nSkipping current track.");
if(b.getAudioScheduler().getQueue().getNext() != null ) {
MessageEmbed next = b.getAudioScheduler().getQueue().getNext().getEmbedMessage("Now Playing:");
MessageText.send(event.getChannel(), next);
}
b.getAudioScheduler().skip();
}
}
}

View File

@ -0,0 +1,32 @@
package com.fpghoti.biscuit.commands.client.music;
import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.biscuit.Biscuit;
import com.fpghoti.biscuit.commands.base.MusicClientCommand;
import com.fpghoti.biscuit.rest.MessageText;
import com.fpghoti.biscuit.util.PermUtil;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
public class ClearCommand extends MusicClientCommand{
public ClearCommand() {
name = "Clear";
description = "Clears all upcoming songs from the queue.";
usage = Main.getMainBiscuit().getProperties().getCommandSignifier() + "clear";
minArgs = 0;
maxArgs = 0;
identifiers.add("clear");
}
@Override
public void execute(String[] args, GuildMessageReceivedEvent event) {
Biscuit b = Biscuit.getBiscuit(event.getGuild());
b.log(event.getAuthor().getName() + " issued a command: -clear");
if(PermUtil.hasMusicControl(event.getMember())) {
MessageText.send(event.getChannel(), "Cleared all upcoming songs from the queue.");
b.getAudioScheduler().getQueue().clear();
}
}
}

View File

@ -0,0 +1,36 @@
package com.fpghoti.biscuit.commands.client.music;
import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.biscuit.Biscuit;
import com.fpghoti.biscuit.commands.base.MusicClientCommand;
import com.fpghoti.biscuit.rest.MessageText;
import com.fpghoti.biscuit.util.PermUtil;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
public class ClearUserSongsCommand extends MusicClientCommand{
public ClearUserSongsCommand() {
name = "Clear User Songs";
description = "Clears all upcoming songs from specified user.";
usage = Main.getMainBiscuit().getProperties().getCommandSignifier() + "clearusersongs <@user>";
minArgs = 1;
maxArgs = 1;
identifiers.add("clearusersongs");
identifiers.add("cus");
}
@Override
public void execute(String[] args, GuildMessageReceivedEvent event) {
Biscuit b = Biscuit.getBiscuit(event.getGuild());
b.log(event.getAuthor().getName() + " issued a command: -clearusersongs " + args[0]);
if(PermUtil.hasMusicControl(event.getMember())) {
for(Member m : event.getMessage().getMentionedMembers()) {
MessageText.send(event.getChannel(), "Clearing all upcoming tracks added by **" + m.getEffectiveName() + "**.");
b.getAudioScheduler().getQueue().removeUserTracks(m.getId());
}
}
}
}

View File

@ -1,4 +1,4 @@
package com.fpghoti.biscuit.commands.client; package com.fpghoti.biscuit.commands.client.music;
import com.fpghoti.biscuit.Main; import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.biscuit.Biscuit; import com.fpghoti.biscuit.biscuit.Biscuit;
@ -6,7 +6,6 @@ import com.fpghoti.biscuit.commands.base.MusicClientCommand;
import com.fpghoti.biscuit.rest.MessageText; import com.fpghoti.biscuit.rest.MessageText;
import com.fpghoti.biscuit.util.PermUtil; import com.fpghoti.biscuit.util.PermUtil;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
public class ForceSkipCommand extends MusicClientCommand{ public class ForceSkipCommand extends MusicClientCommand{
@ -24,13 +23,9 @@ public class ForceSkipCommand extends MusicClientCommand{
public void execute(String[] args, GuildMessageReceivedEvent event) { public void execute(String[] args, GuildMessageReceivedEvent event) {
Biscuit b = Biscuit.getBiscuit(event.getGuild()); Biscuit b = Biscuit.getBiscuit(event.getGuild());
b.log(event.getAuthor().getName() + " issued a command: -forceskip"); b.log(event.getAuthor().getName() + " issued a command: -forceskip");
if(PermUtil.isMod(event.getMember())) { if(PermUtil.hasMusicControl(event.getMember())) {
MessageText.send(event.getChannel(), "Force skipping current song."); MessageText.send(event.getChannel(), "Force skipping current song.");
if(b.getAudioScheduler().getQueue().getNext() != null ) { b.getAudioScheduler().skip(event.getChannel());
MessageEmbed next = b.getAudioScheduler().getQueue().getNext().getEmbedMessage("Now Playing:");
MessageText.send(event.getChannel(), next);
}
b.getAudioScheduler().skip();
} }
} }

View File

@ -0,0 +1,38 @@
package com.fpghoti.biscuit.commands.client.music;
import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.biscuit.Biscuit;
import com.fpghoti.biscuit.commands.base.MusicClientCommand;
import com.fpghoti.biscuit.rest.MessageText;
import com.fpghoti.biscuit.util.PermUtil;
import com.fpghoti.biscuit.util.Util;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
public class ForceSkipToCommand extends MusicClientCommand{
public ForceSkipToCommand() {
name = "Force Skip To";
description = "Force skips all songs until the specified track.";
usage = Main.getMainBiscuit().getProperties().getCommandSignifier() + "forceskipto <Track #>";
minArgs = 1;
maxArgs = 1;
identifiers.add("forceskipto");
identifiers.add("fst");
}
@Override
public void execute(String[] args, GuildMessageReceivedEvent event) {
Biscuit b = Biscuit.getBiscuit(event.getGuild());
b.log(event.getAuthor().getName() + " issued a command: -forceskipto " + args[0]);
if(PermUtil.hasMusicControl(event.getMember())) {
if(Util.isDigit(args[0])) {
int place = Integer.parseInt(args[0]);
MessageText.send(event.getChannel(), "Force skipping to queue position **" + place + "**.");
b.getAudioScheduler().getQueue().removeTracksBefore(place);
b.getAudioScheduler().skip(event.getChannel());
}
}
}
}

View File

@ -1,4 +1,4 @@
package com.fpghoti.biscuit.commands.client; package com.fpghoti.biscuit.commands.client.music;
import com.fpghoti.biscuit.Main; import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.biscuit.Biscuit; import com.fpghoti.biscuit.biscuit.Biscuit;
@ -23,7 +23,7 @@ public class LoopMusicCommand extends MusicClientCommand{
public void execute(String[] args, GuildMessageReceivedEvent event) { public void execute(String[] args, GuildMessageReceivedEvent event) {
Biscuit b = Biscuit.getBiscuit(event.getGuild()); Biscuit b = Biscuit.getBiscuit(event.getGuild());
b.log(event.getAuthor().getName() + " issued a command: -loopmusic"); b.log(event.getAuthor().getName() + " issued a command: -loopmusic");
if(PermUtil.isMod(event.getMember())) { if(PermUtil.hasMusicControl(event.getMember())) {
if(!b.getAudioScheduler().isLooping()) { if(!b.getAudioScheduler().isLooping()) {
MessageText.send(event.getChannel(), "Setting all music to loop."); MessageText.send(event.getChannel(), "Setting all music to loop.");
b.getAudioScheduler().setLooping(true); b.getAudioScheduler().setLooping(true);

View File

@ -0,0 +1,37 @@
package com.fpghoti.biscuit.commands.client.music;
import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.biscuit.Biscuit;
import com.fpghoti.biscuit.commands.base.MusicClientCommand;
import com.fpghoti.biscuit.rest.MessageText;
import com.fpghoti.biscuit.util.PermUtil;
import com.fpghoti.biscuit.util.Util;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
public class MoveToCommand extends MusicClientCommand{
public MoveToCommand() {
name = "Move To";
description = "Moves track to specified position.";
usage = Main.getMainBiscuit().getProperties().getCommandSignifier() + "moveto <Track #>";
minArgs = 2;
maxArgs = 2;
identifiers.add("moveto");
}
@Override
public void execute(String[] args, GuildMessageReceivedEvent event) {
Biscuit b = Biscuit.getBiscuit(event.getGuild());
b.log(event.getAuthor().getName() + " issued a command: -moveto " + args[0] + " " + args[1]);
if(PermUtil.hasMusicControl(event.getMember())) {
if(Util.isDigit(args[0]) && Util.isDigit(args[1])) {
int oldPlace = Integer.parseInt(args[0]);
int newPlace = Integer.parseInt(args[1]);
MessageText.send(event.getChannel(), "The specified track was moved." );
b.getAudioScheduler().getQueue().moveToPlace(oldPlace, newPlace);
}
}
}
}

View File

@ -1,4 +1,4 @@
package com.fpghoti.biscuit.commands.client; package com.fpghoti.biscuit.commands.client.music;
import com.fpghoti.biscuit.Main; import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.biscuit.Biscuit; import com.fpghoti.biscuit.biscuit.Biscuit;

View File

@ -1,4 +1,4 @@
package com.fpghoti.biscuit.commands.client; package com.fpghoti.biscuit.commands.client.music;
import com.fpghoti.biscuit.Main; import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.biscuit.Biscuit; import com.fpghoti.biscuit.biscuit.Biscuit;
@ -23,7 +23,7 @@ public class PauseCommand extends MusicClientCommand{
public void execute(String[] args, GuildMessageReceivedEvent event) { public void execute(String[] args, GuildMessageReceivedEvent event) {
Biscuit b = Biscuit.getBiscuit(event.getGuild()); Biscuit b = Biscuit.getBiscuit(event.getGuild());
b.log(event.getAuthor().getName() + " issued a command: -pause"); b.log(event.getAuthor().getName() + " issued a command: -pause");
if(PermUtil.isMod(event.getMember())) { if(PermUtil.hasMusicControl(event.getMember())) {
if(!b.getAudioPlayer().isPaused()) { if(!b.getAudioPlayer().isPaused()) {
b.getAudioPlayer().setPaused(true); b.getAudioPlayer().setPaused(true);
MessageText.send(event.getChannel(), "Paused the current track."); MessageText.send(event.getChannel(), "Paused the current track.");

View File

@ -0,0 +1,42 @@
package com.fpghoti.biscuit.commands.client.music;
import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.audio.PlayCommandUtil;
import com.fpghoti.biscuit.audio.request.youtube.YTRequest;
import com.fpghoti.biscuit.audio.result.YTResultHandler;
import com.fpghoti.biscuit.biscuit.Biscuit;
import com.fpghoti.biscuit.commands.base.MusicClientCommand;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
public class PlayCommand extends MusicClientCommand{
public PlayCommand() {
name = "Play";
description = "Plays the specified song or plays a song found using search parameters.";
usage = Main.getMainBiscuit().getProperties().getCommandSignifier() + "play <YouTube link OR Search Phrase>";
minArgs = 1;
maxArgs = 2000;
identifiers.add("play");
}
@Override
public void execute(String[] args, GuildMessageReceivedEvent event) {
Guild guild = event.getGuild();
Biscuit b = Biscuit.getBiscuit(guild);
String searchPhrase = PlayCommandUtil.getSearchPhrase(args);
b.log(event.getAuthor().getName() + " issued a command: -play " + searchPhrase);
boolean connected = PlayCommandUtil.connectToChannel(event);
if(!connected) {
return;
}
YTRequest request = new YTRequest(event.getMessage(), searchPhrase);
Main.getPlayerManager().loadItemOrdered(guild, PlayCommandUtil.getID(event), new YTResultHandler(request));
}
}

View File

@ -0,0 +1,52 @@
package com.fpghoti.biscuit.commands.client.music;
import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.audio.PlayCommandUtil;
import com.fpghoti.biscuit.audio.request.youtube.YTPriorityRequest;
import com.fpghoti.biscuit.audio.request.youtube.YTRequest;
import com.fpghoti.biscuit.audio.result.YTResultHandler;
import com.fpghoti.biscuit.biscuit.Biscuit;
import com.fpghoti.biscuit.commands.base.MusicClientCommand;
import com.fpghoti.biscuit.rest.MessageText;
import com.fpghoti.biscuit.util.PermUtil;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
public class PlayFirstCommand extends MusicClientCommand{
public PlayFirstCommand() {
name = "Play First";
description = "Places specified song at the front of the queue.";
usage = Main.getMainBiscuit().getProperties().getCommandSignifier() + "playfirst <YouTube link OR Search Phrase>";
minArgs = 1;
maxArgs = 2000;
identifiers.add("playfirst");
}
@Override
public void execute(String[] args, GuildMessageReceivedEvent event) {
Guild guild = event.getGuild();
Biscuit b = Biscuit.getBiscuit(guild);
TextChannel tchannel = event.getChannel();
String searchPhrase = PlayCommandUtil.getSearchPhrase(args);
b.log(event.getAuthor().getName() + " issued a command: -playfirst " + searchPhrase);
if(!PermUtil.hasMusicControl(event.getMember())) {
MessageText.send(tchannel, "You do not have permission to do this!");
return;
}
boolean connected = PlayCommandUtil.connectToChannel(event);
if(!connected) {
return;
}
YTRequest request = new YTPriorityRequest(event.getMessage(), searchPhrase, 1);
Main.getPlayerManager().loadItemOrdered(guild, PlayCommandUtil.getID(event), new YTResultHandler(request));
}
}

View File

@ -1,4 +1,4 @@
package com.fpghoti.biscuit.commands.client; package com.fpghoti.biscuit.commands.client.music;
import com.fpghoti.biscuit.Main; import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.audio.queue.AudioQueue; import com.fpghoti.biscuit.audio.queue.AudioQueue;

View File

@ -0,0 +1,36 @@
package com.fpghoti.biscuit.commands.client.music;
import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.biscuit.Biscuit;
import com.fpghoti.biscuit.commands.base.MusicClientCommand;
import com.fpghoti.biscuit.rest.MessageText;
import com.fpghoti.biscuit.util.PermUtil;
import com.fpghoti.biscuit.util.Util;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
public class RemoveCommand extends MusicClientCommand{
public RemoveCommand() {
name = "Remove";
description = "Removes song from specified position in queue.";
usage = Main.getMainBiscuit().getProperties().getCommandSignifier() + "remove <Track #>";
minArgs = 1;
maxArgs = 1;
identifiers.add("remove");
}
@Override
public void execute(String[] args, GuildMessageReceivedEvent event) {
Biscuit b = Biscuit.getBiscuit(event.getGuild());
b.log(event.getAuthor().getName() + " issued a command: -remove " + args[0]);
if(PermUtil.hasMusicControl(event.getMember())) {
if(Util.isDigit(args[0])) {
int place = Integer.parseInt(args[0]);
MessageText.send(event.getChannel(), "Removing track at position **" + place + "**.");
b.getAudioScheduler().getQueue().removeTrack(place);
}
}
}
}

View File

@ -0,0 +1,33 @@
package com.fpghoti.biscuit.commands.client.music;
import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.biscuit.Biscuit;
import com.fpghoti.biscuit.commands.base.MusicClientCommand;
import com.fpghoti.biscuit.rest.MessageText;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
public class ShuffleCommand extends MusicClientCommand{
public ShuffleCommand() {
name = "Shuffle";
description = "Shuffles the sender's songs in the queue.";
usage = Main.getMainBiscuit().getProperties().getCommandSignifier() + "shuffle";
minArgs = 0;
maxArgs = 0;
identifiers.add("shuffle");
}
@Override
public void execute(String[] args, GuildMessageReceivedEvent event) {
Biscuit b = Biscuit.getBiscuit(event.getGuild());
b.log(event.getAuthor().getName() + " issued a command: -shuffle");
if(b.getAudioScheduler().getQueue().getLastTrack() != null ) {
b.getAudioScheduler().getQueue().shuffleUserTracks(event.getAuthor().getId());
MessageText.send(event.getChannel(), "All songs that you have added to the queue have been shuffled.");
}else {
MessageText.send(event.getChannel(), "No song is currently playing.");
}
}
}

View File

@ -0,0 +1,33 @@
package com.fpghoti.biscuit.commands.client.music;
import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.biscuit.Biscuit;
import com.fpghoti.biscuit.commands.base.MusicClientCommand;
import com.fpghoti.biscuit.rest.MessageText;
import com.fpghoti.biscuit.util.PermUtil;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
public class SkipAllCommand extends MusicClientCommand{
public SkipAllCommand() {
name = "Skip All";
description = "Forces the all songs to be skipped.";
usage = Main.getMainBiscuit().getProperties().getCommandSignifier() + "skipall";
minArgs = 0;
maxArgs = 0;
identifiers.add("skipall");
}
@Override
public void execute(String[] args, GuildMessageReceivedEvent event) {
Biscuit b = Biscuit.getBiscuit(event.getGuild());
b.log(event.getAuthor().getName() + " issued a command: -skipall");
if(PermUtil.hasMusicControl(event.getMember())) {
MessageText.send(event.getChannel(), "Force skipping all songs.");
b.getAudioScheduler().getQueue().clear();
b.getAudioScheduler().skip(event.getChannel());
}
}
}

View File

@ -0,0 +1,126 @@
package com.fpghoti.biscuit.commands.client.music;
import java.util.ArrayList;
import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.audio.AudioScheduler;
import com.fpghoti.biscuit.biscuit.Biscuit;
import com.fpghoti.biscuit.commands.base.MusicClientCommand;
import com.fpghoti.biscuit.rest.MessageText;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.entities.VoiceChannel;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
public class SkipCommand extends MusicClientCommand{
public SkipCommand() {
name = "Skip";
description = "Sends a vote to skip the song that is currently playing.";
usage = Main.getMainBiscuit().getProperties().getCommandSignifier() + "skip";
minArgs = 0;
maxArgs = 0;
identifiers.add("skip");
}
@Override
public void execute(String[] args, GuildMessageReceivedEvent event) {
Guild guild = event.getGuild();
Biscuit biscuit = Biscuit.getBiscuit(guild);
biscuit.log(event.getAuthor().getName() + " issued a command: -skip");
TextChannel cmdChannel = event.getChannel();
//Bot is not connected to voice channel. Do nothing.
if(!guild.getAudioManager().isConnected()) {
MessageText.send(event.getChannel(), "The music player is not connected to a voice channel!");
return;
}
VoiceChannel voice = guild.getAudioManager().getConnectedChannel();
//Bot is connected to a voice channel in the guild, and the command sender is not in the channel.
//Do nothing
if(!voice.getMembers().contains(event.getMember())) {
MessageText.send(cmdChannel, "You need to be in the same voice channel in order to skip!");
return;
}
//No song is playing. Do nothing.
if(biscuit.getAudioPlayer().getPlayingTrack() == null) {
MessageText.send(cmdChannel, "There is not a song playing for you to skip!");
return;
}
AudioScheduler sched = biscuit.getAudioScheduler();
boolean skip = false;
//Get number of users connected to the channel
int count = nonBotCount(voice);
//Determine amount of votes needed to skip
int votesNeeded = count / 2;
if(votesNeeded * 2 < count) {
votesNeeded++;
}
int votes = 1;
//If sender alone
if(count == 1) {
skip = true; //approve skip
}else{
String id = event.getAuthor().getId();
//Check if command sender has already voted
if(sched.hasSkipped(id)) {
MessageText.send(cmdChannel, "You have already voted to skip!");
return;
}
//Save vote
sched.voteSkip(id);
//Get updated vote count
votes = sched.getVotes();
//Check if enough to skip
if(votes >= votesNeeded) {
skip = true; //approve skip
}
}
if(skip) {
//Skip has been approved, so skip
MessageText.send(cmdChannel, "**" + votes + "/" + count + "** voted to skip. Skipping current track.");
sched.skip(cmdChannel);
}else {
//Skip has not been approved, so send vote update message
int remaining = votesNeeded - votes;
String words = " vote is ";
if(remaining != 1) { //make word singular/plural as needed
words = " votes are ";
}
MessageText.send(cmdChannel, "**" + votes + "/" + count + "** voted to skip. **" + remaining + "** more" + words + "needed to"
+ " skip the current track.");
}
}
private int nonBotCount(VoiceChannel c) {
int count = 0;
ArrayList<Member> members = new ArrayList<Member>(c.getMembers());
for(Member m : members) {
if(!m.getUser().isBot()) {
count++;
}
}
return count;
}
}

View File

@ -1,4 +1,4 @@
package com.fpghoti.biscuit.commands.client; package com.fpghoti.biscuit.commands.client.music;
import com.fpghoti.biscuit.Main; import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.biscuit.Biscuit; import com.fpghoti.biscuit.biscuit.Biscuit;
@ -24,7 +24,7 @@ public class TogglePauseCommand extends MusicClientCommand{
public void execute(String[] args, GuildMessageReceivedEvent event) { public void execute(String[] args, GuildMessageReceivedEvent event) {
Biscuit b = Biscuit.getBiscuit(event.getGuild()); Biscuit b = Biscuit.getBiscuit(event.getGuild());
b.log(event.getAuthor().getName() + " issued a command: -togglepause"); b.log(event.getAuthor().getName() + " issued a command: -togglepause");
if(PermUtil.isMod(event.getMember())) { if(PermUtil.hasMusicControl(event.getMember())) {
if(b.getAudioPlayer().isPaused()) { if(b.getAudioPlayer().isPaused()) {
b.getAudioPlayer().setPaused(false); b.getAudioPlayer().setPaused(false);
MessageText.send(event.getChannel(), "Unpaused the current track."); MessageText.send(event.getChannel(), "Unpaused the current track.");

View File

@ -1,14 +1,14 @@
package com.fpghoti.biscuit.commands.client; package com.fpghoti.biscuit.commands.client.music;
import com.fpghoti.biscuit.Main; import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.biscuit.Biscuit; import com.fpghoti.biscuit.biscuit.Biscuit;
import com.fpghoti.biscuit.commands.base.ClientCommand; import com.fpghoti.biscuit.commands.base.MusicClientCommand;
import com.fpghoti.biscuit.rest.MessageText; import com.fpghoti.biscuit.rest.MessageText;
import com.fpghoti.biscuit.util.PermUtil; import com.fpghoti.biscuit.util.PermUtil;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
public class UnpauseCommand extends ClientCommand{ public class UnpauseCommand extends MusicClientCommand{
public UnpauseCommand() { public UnpauseCommand() {
name = "Unpause"; name = "Unpause";
@ -17,13 +17,14 @@ public class UnpauseCommand extends ClientCommand{
minArgs = 0; minArgs = 0;
maxArgs = 0; maxArgs = 0;
identifiers.add("unpause"); identifiers.add("unpause");
identifiers.add("resume");
} }
@Override @Override
public void execute(String[] args, GuildMessageReceivedEvent event) { public void execute(String[] args, GuildMessageReceivedEvent event) {
Biscuit b = Biscuit.getBiscuit(event.getGuild()); Biscuit b = Biscuit.getBiscuit(event.getGuild());
b.log(event.getAuthor().getName() + " issued a command: -unpause"); b.log(event.getAuthor().getName() + " issued a command: -unpause");
if(PermUtil.isMod(event.getMember())) { if(PermUtil.hasMusicControl(event.getMember())) {
if(b.getAudioPlayer().isPaused()) { if(b.getAudioPlayer().isPaused()) {
b.getAudioPlayer().setPaused(false); b.getAudioPlayer().setPaused(false);
MessageText.send(event.getChannel(), "Unpaused the current track."); MessageText.send(event.getChannel(), "Unpaused the current track.");

View File

@ -0,0 +1,50 @@
package com.fpghoti.biscuit.commands.client.music;
import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.biscuit.Biscuit;
import com.fpghoti.biscuit.commands.base.MusicClientCommand;
import com.fpghoti.biscuit.rest.MessageText;
import com.fpghoti.biscuit.util.PermUtil;
import com.fpghoti.biscuit.util.Util;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
public class VolumeCommand extends MusicClientCommand{
public VolumeCommand() {
name = "Volume";
description = "Changes the player volume or displays the current volume.";
usage = Main.getMainBiscuit().getProperties().getCommandSignifier() + "volume [0-150]";
minArgs = 0;
maxArgs = 1;
identifiers.add("volume");
identifiers.add("vol");
}
@Override
public void execute(String[] args, GuildMessageReceivedEvent event) {
Biscuit b = Biscuit.getBiscuit(event.getGuild());
if(args.length < 1) {
b.log(event.getAuthor().getName() + " issued a command: -volume");
MessageText.send(event.getChannel(), "The current volume is: **" + b.getAudioPlayer().getVolume() + "**.");
return;
}
b.log(event.getAuthor().getName() + " issued a command: -volume " + args[0]);
if(PermUtil.hasMusicControl(event.getMember())) {
if(Util.isDigit(args[0])) {
int vol = Integer.parseInt(args[0]);
if(vol < 0) {
vol = 0;
}else if(vol > 150) {
vol = 150;
}
b.getAudioPlayer().setVolume(vol);
MessageText.send(event.getChannel(), "The volume was set to **" + b.getAudioPlayer().getVolume() + "**.");
}
}
}
}

View File

@ -1,4 +1,4 @@
package com.fpghoti.biscuit.commands.client; package com.fpghoti.biscuit.commands.client.music;
import com.fpghoti.biscuit.Main; import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.biscuit.Biscuit; import com.fpghoti.biscuit.biscuit.Biscuit;
@ -24,7 +24,7 @@ public class WipeQueueCommand extends MusicClientCommand{
public void execute(String[] args, GuildMessageReceivedEvent event) { public void execute(String[] args, GuildMessageReceivedEvent event) {
Biscuit b = Biscuit.getBiscuit(event.getGuild()); Biscuit b = Biscuit.getBiscuit(event.getGuild());
b.log(event.getAuthor().getName() + " issued a command: -wipequeue"); b.log(event.getAuthor().getName() + " issued a command: -wipequeue");
if(PermUtil.isMod(event.getMember())) { if(PermUtil.hasMusicControl(event.getMember())) {
b.getAudioScheduler().wipeQueue(); b.getAudioScheduler().wipeQueue();
MessageText.send(event.getChannel(), "Removed upcoming songs from the music queue."); MessageText.send(event.getChannel(), "Removed upcoming songs from the music queue.");
} }

View File

@ -180,6 +180,7 @@ public class BiscuitConfig {
added = addProperty("Kick-DM-Invite", "", prop, added, silent); added = addProperty("Kick-DM-Invite", "", prop, added, silent);
added = addProperty("Allow-Music-Bot", "true", prop, added, silent); added = addProperty("Allow-Music-Bot", "true", prop, added, silent);
added = addProperty("Music-Channels", "", prop, added, silent); added = addProperty("Music-Channels", "", prop, added, silent);
added = addProperty("Music-Controller-Role", "music-key", prop, added, silent);
if(!isMain) { if(!isMain) {
if(code != null) { if(code != null) {

View File

@ -63,10 +63,10 @@ public class BiscuitProperties {
return biscuit.getConfig().getFromConfig(key, biscuit); return biscuit.getConfig().getFromConfig(key, biscuit);
} }
public String getDontNotify(){ public String getMusicControllerRole(){
String key = "Dont-Notify-Role"; String key = "Music-Controller-Role";
if(biscuit.getConfig().getFromConfig(key, biscuit).equalsIgnoreCase("[global]") && biscuit.getGuild() != null) { if(biscuit.getConfig().getFromConfig(key, biscuit).equalsIgnoreCase("[global]") && biscuit.getGuild() != null) {
return Main.getMainBiscuit().getProperties().getDontNotify(); return Main.getMainBiscuit().getProperties().getMusicControllerRole();
} }
return biscuit.getConfig().getFromConfig(key, biscuit); return biscuit.getConfig().getFromConfig(key, biscuit);
} }

View File

@ -38,6 +38,21 @@ public class PermUtil {
return false; return false;
} }
public static boolean hasMusicControl(Member member){
Biscuit biscuit = Biscuit.getBiscuit(member.getGuild());
if(isAdmin(member) || isMod(member)){
return true;
}else{
for(Role role : member.getRoles()){
if(role.getName().equalsIgnoreCase(biscuit.getProperties().getMusicControllerRole())){
return true;
}
}
}
return false;
}
public static boolean hasRole(Member member, String role){ public static boolean hasRole(Member member, String role){
for(Role r : member.getRoles()){ for(Role r : member.getRoles()){
if(r.getName().equalsIgnoreCase(role)){ if(r.getName().equalsIgnoreCase(role)){

View File

@ -120,6 +120,10 @@ Log-Music-Player = true
#Music-Channels = Room 1, Room 2 #Music-Channels = Room 1, Room 2
Music-Channels = Music-Channels =
#Users with this role have complete control over the music player.
#Automatically granted to Mods and Admins.
Music-Controller-Role = music-key
#List your custom commands here. This line will always generate blank. #List your custom commands here. This line will always generate blank.
#Example - Custom-Command-Names = hello,botcheck,apple #Example - Custom-Command-Names = hello,botcheck,apple
Custom-Command-Names = Custom-Command-Names =