Version 1: Basic functionality #1

Merged
andrewlalis merged 10 commits from development into master 2017-06-21 14:48:08 +00:00
7 changed files with 221 additions and 161 deletions
Showing only changes of commit 0ceedf293d - Show all commits

View File

@ -1,10 +1,6 @@
package handiebot; package handiebot;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers;
import handiebot.command.CommandHandler; import handiebot.command.CommandHandler;
import handiebot.lavaplayer.GuildMusicManager;
import handiebot.lavaplayer.MusicPlayer; import handiebot.lavaplayer.MusicPlayer;
import sx.blah.discord.api.ClientBuilder; import sx.blah.discord.api.ClientBuilder;
import sx.blah.discord.api.IDiscordClient; import sx.blah.discord.api.IDiscordClient;
@ -13,8 +9,7 @@ import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedE
import sx.blah.discord.util.DiscordException; import sx.blah.discord.util.DiscordException;
import sx.blah.discord.util.RateLimitException; import sx.blah.discord.util.RateLimitException;
import java.util.HashMap; import java.util.logging.Logger;
import java.util.Map;
/** /**
* @author Andrew Lalis * @author Andrew Lalis
@ -22,29 +17,16 @@ import java.util.Map;
*/ */
public class HandieBot { public class HandieBot {
public static Logger log = Logger.getLogger("HandieBotLog");
private static final String TOKEN = "MjgzNjUyOTg5MjEyNjg4Mzg0.C45A_Q.506b0G6my1FEFa7_YY39lxLBHUY"; private static final String TOKEN = "MjgzNjUyOTg5MjEyNjg4Mzg0.C45A_Q.506b0G6my1FEFa7_YY39lxLBHUY";
private static IDiscordClient client; private static IDiscordClient client;
private CommandHandler commandHandler; private CommandHandler commandHandler;
public static void main(String[] args) throws DiscordException, RateLimitException {
System.out.println("Logging bot in...");
client = new ClientBuilder().withToken(TOKEN).build();
client.getDispatcher().registerListener(new HandieBot());
client.login();
}
private final AudioPlayerManager playerManager;
private final Map<Long, GuildMusicManager> musicManagers;
private MusicPlayer musicPlayer; private MusicPlayer musicPlayer;
private HandieBot() { private HandieBot() {
this.musicManagers = new HashMap<>();
this.playerManager = new DefaultAudioPlayerManager();
AudioSourceManagers.registerRemoteSources(playerManager);
AudioSourceManagers.registerLocalSource(playerManager);
this.commandHandler = new CommandHandler(this); this.commandHandler = new CommandHandler(this);
this.musicPlayer = new MusicPlayer(); this.musicPlayer = new MusicPlayer();
} }
@ -58,5 +40,11 @@ public class HandieBot {
this.commandHandler.handleCommand(event); this.commandHandler.handleCommand(event);
} }
public static void main(String[] args) throws DiscordException, RateLimitException {
System.out.println("Logging bot in.");
client = new ClientBuilder().withToken(TOKEN).build();
client.getDispatcher().registerListener(new HandieBot());
client.login();
}
} }

View File

@ -2,6 +2,7 @@ package handiebot.command;
import com.sun.istack.internal.NotNull; import com.sun.istack.internal.NotNull;
import handiebot.HandieBot; import handiebot.HandieBot;
import handiebot.utils.DisappearingMessage;
import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent; import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent;
import sx.blah.discord.handle.obj.*; import sx.blah.discord.handle.obj.*;
import sx.blah.discord.util.EmbedBuilder; import sx.blah.discord.util.EmbedBuilder;
@ -34,16 +35,24 @@ public class CommandHandler {
String command = extractCommand(message); String command = extractCommand(message);
String[] args = extractArgs(message); String[] args = extractArgs(message);
if (guild != null && command != null){ if (guild != null && command != null){
DisappearingMessage.deleteMessageAfter(2000, message);
if (command.equals("play") && args.length == 1){ if (command.equals("play") && args.length == 1){
//Play or queue a song.
this.bot.getMusicPlayer().loadToQueue(guild, args[0]); this.bot.getMusicPlayer().loadToQueue(guild, args[0]);
} else if (command.equals("skip") && args.length == 0){ } else if (command.equals("skip") && args.length == 0){
//Skip the current song.
this.bot.getMusicPlayer().skipTrack(guild); this.bot.getMusicPlayer().skipTrack(guild);
} else if (command.equals("help")){ } else if (command.equals("help")){
this.sendHelpInfo(user); //Send a PM to the user with help info.
this.sendHelpInfo(user);//TODO finish the help command and fill in with new descriptions each time.
} else if (command.equals("queue") && args.length == 0){ } else if (command.equals("queue") && args.length == 0){
//Display the first few items of the queue.
this.bot.getMusicPlayer().showQueueList(guild); this.bot.getMusicPlayer().showQueueList(guild);
} else if (command.equals("repeat")){ } else if (command.equals("repeat")){
this.bot.getMusicPlayer().toggleRepeat(guild); //Toggle repeat.
//TODO implement repeat command.
} else if (command.equals("clear")){
//TODO clear command.
} }
} }
} }

View File

@ -1,40 +0,0 @@
package handiebot.lavaplayer;
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
/**
* @author Andrew Lalis
*/
public class AudioLoadResultHandler implements com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler {
private TrackScheduler scheduler;
public AudioLoadResultHandler(TrackScheduler scheduler){
this.scheduler = scheduler;
}
@Override
public void trackLoaded(AudioTrack audioTrack) {
System.out.println("Adding to queue "+ audioTrack.getInfo().title);
scheduler.queue(audioTrack);
}
@Override
public void playlistLoaded(AudioPlaylist audioPlaylist) {
System.out.println("Adding playlist to queue.");
audioPlaylist.getTracks().forEach(track -> this.scheduler.queue(track));
}
@Override
public void noMatches() {
System.out.println("No matches!");
}
@Override
public void loadFailed(FriendlyException e) {
System.out.println("Load failed.");
e.printStackTrace();
}
}

View File

@ -2,6 +2,7 @@ package handiebot.lavaplayer;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
import sx.blah.discord.handle.obj.IGuild;
/** /**
* @author Andrew Lalis * @author Andrew Lalis
@ -13,9 +14,9 @@ public class GuildMusicManager {
public final TrackScheduler scheduler; public final TrackScheduler scheduler;
public GuildMusicManager(AudioPlayerManager manager){ public GuildMusicManager(AudioPlayerManager manager, IGuild guild){
this.player = manager.createPlayer(); this.player = manager.createPlayer();
this.scheduler = new TrackScheduler(this.player); this.scheduler = new TrackScheduler(this.player, guild);
this.player.addListener(this.scheduler); this.player.addListener(this.scheduler);
} }

View File

@ -8,14 +8,17 @@ import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack; import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
import handiebot.command.CommandHandler; import handiebot.command.CommandHandler;
import handiebot.utils.DisappearingMessage;
import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IGuild; import sx.blah.discord.handle.obj.IGuild;
import sx.blah.discord.handle.obj.IMessage;
import sx.blah.discord.handle.obj.IVoiceChannel; import sx.blah.discord.handle.obj.IVoiceChannel;
import sx.blah.discord.util.EmbedBuilder; import sx.blah.discord.util.EmbedBuilder;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit;
/** /**
* @author Andrew Lalis * @author Andrew Lalis
@ -24,37 +27,94 @@ import java.util.Map;
*/ */
public class MusicPlayer { public class MusicPlayer {
private static String CHANNEL_NAME = "music"; //Name for the message and voice channels dedicated to this bot.
public static String CHANNEL_NAME = "HandieBotMusic";
private final AudioPlayerManager playerManager; private final AudioPlayerManager playerManager;
private final Map<Long, GuildMusicManager> musicManagers;
/*
Mappings of music managers, channels and voice channels for each guild.
*/
private Map<IGuild, GuildMusicManager> musicManagers;
private Map<IGuild, IChannel> chatChannels;
private Map<IGuild, IVoiceChannel> voiceChannels;
public MusicPlayer(){ public MusicPlayer(){
this.musicManagers = new HashMap<>(); //Initialize player manager.
this.playerManager = new DefaultAudioPlayerManager(); this.playerManager = new DefaultAudioPlayerManager();
AudioSourceManagers.registerLocalSource(playerManager); AudioSourceManagers.registerLocalSource(playerManager);
AudioSourceManagers.registerRemoteSources(playerManager); AudioSourceManagers.registerRemoteSources(playerManager);
//Initialize all maps.
this.musicManagers = new HashMap<>();
this.chatChannels = new HashMap<>();
this.voiceChannels = new HashMap<>();
} }
/** /**
* Toggles the playlist's repeating. * Gets the music manager specific to a particular guild.
* @param guild The guild to perform the action on. * @param guild The guild to get the music manager for.
* @return The music manager for a guild.
*/ */
public void toggleRepeat(IGuild guild){ private GuildMusicManager getMusicManager(IGuild guild){
GuildMusicManager musicManager = this.getGuildMusicManager(guild); if (!this.musicManagers.containsKey(guild)){
musicManager.scheduler.setRepeat(!musicManager.scheduler.isRepeating()); System.out.println("Registering guild, creating audio provider.");
this.getMessageChannel(guild).sendMessage("**Repeat** is now *"+(musicManager.scheduler.isRepeating() ? "On" : "Off")+"*."); this.musicManagers.put(guild, new GuildMusicManager(this.playerManager, guild));
guild.getAudioManager().setAudioProvider(this.musicManagers.get(guild).getAudioProvider());
}
return this.musicManagers.get(guild);
}
/**
* Gets the chat channel specific to a particular guild. This channel is used send updates about playback and
* responses to people's commands. If none exists, the bot will attempt to make a channel.
* @param guild The guild to get the channel from.
* @return A message channel on a particular guild that is specifically for music.
*/
private IChannel getChatChannel(IGuild guild){
if (!this.chatChannels.containsKey(guild)){
List<IChannel> channels = guild.getChannelsByName(CHANNEL_NAME.toLowerCase());
if (channels.isEmpty()){
System.out.println("Found "+channels.size()+" matches for message channel, creating new one.");
this.chatChannels.put(guild, guild.createChannel(CHANNEL_NAME.toLowerCase()));
} else {
this.chatChannels.put(guild, channels.get(0));
}
}
return this.chatChannels.get(guild);
}
/**
* Gets the voice channel associated with a particular guild. This channel is used for audio playback. If none
* exists, the bot will attempt to make a voice channel.
* @param guild The guild to get the channel from.
* @return The voice channel on a guild that is for this bot.
*/
private IVoiceChannel getVoiceChannel(IGuild guild){
if (!this.voiceChannels.containsKey(guild)){
List<IVoiceChannel> channels = guild.getVoiceChannelsByName(CHANNEL_NAME);
if (channels.isEmpty()){
System.out.println("Found "+channels.size()+" matches for voice channel, creating new one.");
this.voiceChannels.put(guild, guild.createVoiceChannel(CHANNEL_NAME));
} else {
this.voiceChannels.put(guild, channels.get(0));
}
}
IVoiceChannel vc = this.voiceChannels.get(guild);
if (!vc.isConnected()){
System.out.println("Joined voice channel.");
vc.join();
}
return vc;
} }
/** /**
* Sends a formatted message to the guild about the first few items in a queue. * Sends a formatted message to the guild about the first few items in a queue.
* @param guild The guild to show the queue for.
*/ */
public void showQueueList(IGuild guild){ public void showQueueList(IGuild guild){
GuildMusicManager musicManager = this.getGuildMusicManager(guild); List<AudioTrack> tracks = getMusicManager(guild).scheduler.queueList();
List<AudioTrack> tracks = musicManager.scheduler.queueList();
if (tracks.size() == 0) { if (tracks.size() == 0) {
this.getMessageChannel(guild).sendMessage("The queue is empty. Use **"+ CommandHandler.PREFIX+"play** *URL* to add songs."); new DisappearingMessage(getChatChannel(guild), "The queue is empty. Use **"+ CommandHandler.PREFIX+"play** *URL* to add songs.", 3000);
} else { } else {
EmbedBuilder builder = new EmbedBuilder(); EmbedBuilder builder = new EmbedBuilder();
builder.withColor(255, 0, 0); builder.withColor(255, 0, 0);
@ -74,22 +134,22 @@ public class MusicPlayer {
sb.append(seconds % 60); sb.append(seconds % 60);
sb.append("]\n"); sb.append("]\n");
} }
builder.appendField("Showing " + (tracks.size() <= 10 ? tracks.size() : "the first 10") + " tracks.", sb.toString(), false); builder.withTimestamp(System.currentTimeMillis());
this.getMessageChannel(guild).sendMessage(builder.build()); builder.appendField("Showing " + (tracks.size() <= 10 ? tracks.size() : "the first 10") + " track"+(tracks.size() > 1 ? "s" : "")+".", sb.toString(), false);
getChatChannel(guild).sendMessage(builder.build());
} }
} }
/** /**
* Loads a URL to the queue, or outputs an error message if it fails. * Loads a URL to the queue, or outputs an error message if it fails.
* @param guild The guild to load the URL to.
* @param trackURL A string representing a youtube/soundcloud URL. * @param trackURL A string representing a youtube/soundcloud URL.
*/ */
public void loadToQueue(IGuild guild, String trackURL){ public void loadToQueue(IGuild guild, String trackURL){
GuildMusicManager musicManager = this.getGuildMusicManager(guild); this.playerManager.loadItemOrdered(getMusicManager(guild), trackURL, new AudioLoadResultHandler() {
this.playerManager.loadItemOrdered(musicManager, trackURL, new AudioLoadResultHandler() {
@Override @Override
public void trackLoaded(AudioTrack audioTrack) { public void trackLoaded(AudioTrack audioTrack) {
addToQueue(guild, musicManager, audioTrack); System.out.println("Track successfully loaded: "+audioTrack.getInfo().title);
addToQueue(guild, audioTrack);
} }
@Override @Override
@ -99,92 +159,59 @@ public class MusicPlayer {
if (firstTrack == null){ if (firstTrack == null){
firstTrack = audioPlaylist.getTracks().get(0); firstTrack = audioPlaylist.getTracks().get(0);
} }
addToQueue(guild, musicManager,firstTrack); addToQueue(guild, firstTrack);
} }
} }
@Override @Override
public void noMatches() { public void noMatches() {
getMessageChannel(guild).sendMessage("Unable to find a result for: "+trackURL); new DisappearingMessage(getChatChannel(guild), "Unable to find a result for: "+trackURL, 3000);
} }
@Override @Override
public void loadFailed(FriendlyException e) { public void loadFailed(FriendlyException e) {
getMessageChannel(guild).sendMessage("Unable to load. "+e.getMessage()); new DisappearingMessage(getChatChannel(guild), "Unable to load. "+e.getMessage(), 3000);
} }
}); });
} }
/** /**
* Adds a track to the queue and sends a message to the appropriate channel notifying users. * Adds a track to the queue and sends a message to the appropriate channel notifying users.
* @param guild The guild to queue the track in.
* @param musicManager The music manager to use.
* @param track The track to queue. * @param track The track to queue.
*/ */
public void addToQueue(IGuild guild, GuildMusicManager musicManager, AudioTrack track){ public void addToQueue(IGuild guild, AudioTrack track){
IVoiceChannel voiceChannel = this.connectToMusicChannel(guild); IVoiceChannel voiceChannel = getVoiceChannel(guild);
if (voiceChannel != null){ if (voiceChannel != null){
musicManager.scheduler.queue(track); //Check to make sure sound can be played.
IChannel channel = this.getMessageChannel(guild); if (guild.getAudioManager().getAudioProvider() == null){
channel.sendMessage("Added **"+track.getInfo().title+"** to the queue."); new DisappearingMessage(getChatChannel(guild), "Audio provider not set. Please try again.", 3000);
guild.getAudioManager().setAudioProvider(getMusicManager(guild).getAudioProvider());
return;
}
long timeUntilPlay = getMusicManager(guild).scheduler.getTimeUntilDone();
getMusicManager(guild).scheduler.queue(track);
//Build message.
StringBuilder sb = new StringBuilder();
sb.append("Added **").append(track.getInfo().title).append("** to the queue.");
//If there's some tracks in the queue, get the time until this one plays.
if (timeUntilPlay != 0){
sb.append(String.format("\nTime until play: %d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes(timeUntilPlay),
TimeUnit.MILLISECONDS.toSeconds(timeUntilPlay) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timeUntilPlay))
));
}
IMessage message = getChatChannel(guild).sendMessage(sb.toString());
DisappearingMessage.deleteMessageAfter(3000, message);
} }
} }
/** /**
* Skips the current track. * Skips the current track.
* @param guild The guild to perform the skip on.
*/ */
public void skipTrack(IGuild guild){ public void skipTrack(IGuild guild){
this.getGuildMusicManager(guild).scheduler.nextTrack(); getMusicManager(guild).scheduler.nextTrack();
this.getMessageChannel(guild).sendMessage("Skipping the current track."); new DisappearingMessage(getChatChannel(guild), "Skipping the current track.", 3000);
}
/**
* Gets or creates a music manager for a specific guild.
* @param guild The guild to get a manager for.
* @return A Music Manager for the guild.
*/
private synchronized GuildMusicManager getGuildMusicManager(IGuild guild){
long guildId = Long.parseLong(guild.getStringID());
GuildMusicManager musicManager = this.musicManagers.get(guildId);
if (musicManager == null){
musicManager = new GuildMusicManager(this.playerManager);
musicManagers.put(guildId, musicManager);
}
guild.getAudioManager().setAudioProvider(musicManager.getAudioProvider());
return musicManager;
}
/**
* Searches for and attempts to connect to a channel called 'music'.
* @param guild the guild to get voice channels from.
* @return The voice channel the bot is now connected to.
*/
private IVoiceChannel connectToMusicChannel(IGuild guild){
List<IVoiceChannel> voiceChannels = guild.getVoiceChannelsByName(CHANNEL_NAME);
if (voiceChannels.size() == 1){
if (!voiceChannels.get(0).isConnected())
voiceChannels.get(0).join();
return voiceChannels.get(0);
}
IVoiceChannel voiceChannel = guild.createVoiceChannel(CHANNEL_NAME);
voiceChannel.join();
return voiceChannel;
}
/**
* Returns a 'music' message channel where the bot can post info on playing songs, user requests,
* etc.
* @param guild The guild to get channels from.
* @return The channel with that name.
*/
private IChannel getMessageChannel(IGuild guild){
List<IChannel> channels = guild.getChannelsByName(CHANNEL_NAME);
if (channels.size() == 1){
return channels.get(0);
}
return guild.createChannel(CHANNEL_NAME);
} }
} }

View File

@ -5,6 +5,8 @@ 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 sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IGuild;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -18,15 +20,18 @@ public class TrackScheduler extends AudioEventAdapter {
private final AudioPlayer player; private final AudioPlayer player;
private final BlockingQueue<AudioTrack> queue; private final BlockingQueue<AudioTrack> queue;
private boolean repeat = false; private boolean repeat = false;
private AudioTrack currentTrack = null;
private IGuild guild;
/** /**
* Constructs a new track scheduler with the given player. * Constructs a new track scheduler with the given player.
* @param player The audio player this scheduler uses. * @param player The audio player this scheduler uses.
*/ */
public TrackScheduler(AudioPlayer player){ public TrackScheduler(AudioPlayer player, IGuild guild){
this.player = player; this.player = player;
this.guild = guild;
this.queue = new LinkedBlockingQueue<>(); this.queue = new LinkedBlockingQueue<>();
} }
@ -46,13 +51,38 @@ public class TrackScheduler extends AudioEventAdapter {
return this.repeat; return this.repeat;
} }
/**
* Returns the time until the bot is done playing sound, at the current rate.
* @return The milliseconds until music stops.
*/
public long getTimeUntilDone(){
long t = 0;
AudioTrack currentTrack = this.player.getPlayingTrack();
if (currentTrack != null){
t += currentTrack.getDuration() - currentTrack.getPosition();
}
for (AudioTrack track : this.queueList()){
t += track.getDuration();
}
return t;
}
/**
* Returns a list of tracks in the queue.
* @return A list of tracks in the queue.
*/
public List<AudioTrack> queueList(){
return new ArrayList<>(this.queue);
}
/** /**
* Add the next track to the queue or play right away if nothing is in the queue. * Add the next track to the queue or play right away if nothing is in the queue.
* @param track The track to play or add to the queue. * @param track The track to play or add to the queue.
*/ */
public void queue(AudioTrack track){ public void queue(AudioTrack track){
if (!player.startTrack(track, true)){ if (player.getPlayingTrack() == null){
System.out.println("Unable to start track immediately, adding to queue."); player.startTrack(track, false);
} else {
queue.offer(track); queue.offer(track);
} }
} }
@ -63,28 +93,28 @@ public class TrackScheduler extends AudioEventAdapter {
public void nextTrack(){ public void nextTrack(){
AudioTrack track = queue.poll(); AudioTrack track = queue.poll();
player.startTrack(track, false); player.startTrack(track, false);
this.currentTrack = track;
if (this.repeat){ if (this.repeat){
this.queue.add(track); this.queue.add(track);
} }
} }
@Override @Override
public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) { public void onTrackStart(AudioPlayer player, AudioTrack track) {
if (endReason.mayStartNext){ System.out.println("Started audio track: "+track.getInfo().title);
nextTrack(); List<IChannel> channels = this.guild.getChannelsByName(MusicPlayer.CHANNEL_NAME.toLowerCase());
} else { if (channels.size() > 0){
this.currentTrack = null; channels.get(0).sendMessage("Now playing: **"+track.getInfo().title+"**.");
System.out.println(endReason.toString());
} }
} }
/** @Override
* Returns a list of tracks in the queue. public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) {
* @return A list of tracks in the queue. System.out.println("Track ended.");
*/ if (endReason.mayStartNext){
public List<AudioTrack> queueList(){ nextTrack();
return new ArrayList<>(this.queue); } else {
System.out.println(endReason.toString());
}
} }
@Override @Override
@ -96,4 +126,5 @@ public class TrackScheduler extends AudioEventAdapter {
public void onTrackStuck(AudioPlayer player, AudioTrack track, long thresholdMs) { public void onTrackStuck(AudioPlayer player, AudioTrack track, long thresholdMs) {
super.onTrackStuck(player, track, thresholdMs); super.onTrackStuck(player, track, thresholdMs);
} }
} }

View File

@ -0,0 +1,44 @@
package handiebot.utils;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IMessage;
/**
* @author Andrew Lalis
* Creates a message on a channel that will disappear after some time.
*/
public class DisappearingMessage extends Thread implements Runnable {
/**
* Creates a new disappearing message that times out after some time.
* @param channel The channel to write the message in.
* @param message The message content.
* @param timeout How long until the message is deleted.
*/
public DisappearingMessage(IChannel channel, String message, long timeout){
IMessage sentMessage = channel.sendMessage(message);
try {
sleep(timeout);
} catch (InterruptedException e) {
e.printStackTrace();
}
sentMessage.delete();
}
/**
* Deletes a message after a set amount of time.
* @param timeout The delay until deletion, in milliseconds.
* @param message The message to delete.
*/
public static void deleteMessageAfter(long timeout, IMessage message){
new Thread(() -> {
try {
sleep(timeout);
message.delete();
} catch (InterruptedException e){
e.printStackTrace();
}
}).start();
}
}