diff --git a/src/main/java/net/locusworks/discord/eighttrack/adaptors/MusicListenerAdaptor.java b/src/main/java/net/locusworks/discord/eighttrack/adaptors/MusicListenerAdaptor.java index a5ca8f4..1a7113e 100644 --- a/src/main/java/net/locusworks/discord/eighttrack/adaptors/MusicListenerAdaptor.java +++ b/src/main/java/net/locusworks/discord/eighttrack/adaptors/MusicListenerAdaptor.java @@ -29,8 +29,18 @@ package net.locusworks.discord.eighttrack.adaptors; import java.io.IOException; import java.nio.file.Path; +import java.time.Duration; +import java.time.OffsetDateTime; +import java.util.Iterator; import java.util.Map; +import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; import net.locusworks.discord.eighttrack.handlers.GuildMusicHandler; @@ -43,13 +53,41 @@ public class MusicListenerAdaptor extends ListenerAdapter { private ApplicationLogger logger; private Map playerMap; + private JDA client; - public MusicListenerAdaptor(Path musicDir) throws IOException { + public MusicListenerAdaptor(Path musicDir, JDA client) throws IOException { this.logger = ApplicationLoggerFactory.getLogger(MusicListenerAdaptor.class); this.playerMap = new ConcurrentHashMap<>(); this.musicDir = musicDir; + this.client = client; + + ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); + executor.scheduleWithFixedDelay(()->checkPlayers(), 1, 1, TimeUnit.MINUTES); + } + private void checkPlayers() { + logger.debug("Checking players to see if anyone is listening"); + OffsetDateTime now = OffsetDateTime.now(); + for(Iterator> iterator = playerMap.entrySet().iterator(); iterator.hasNext();) { + Entry entry = iterator.next(); + GuildMusicHandler gmh = entry.getValue(); + long guildId = entry.getKey(); + + OffsetDateTime lastPlayed = gmh.getLastPlayed(); + Duration duration = Duration.between(lastPlayed, now); + if (duration.getSeconds() > 300) { + Guild guild = client.getGuildById(guildId); + if (guild == null) { + iterator.remove(); + continue; + } + guild.getAudioManager().closeAudioConnection(); + iterator.remove(); + } + } + } + @Override public void onGuildMessageReceived(GuildMessageReceivedEvent event) { if (event.getAuthor().isBot()) return; @@ -66,6 +104,7 @@ public class MusicListenerAdaptor extends ListenerAdapter { playerMap.put(event.getGuild().getIdLong(), new GuildMusicHandler(musicDir)); } GuildMusicHandler gmh = playerMap.get(event.getGuild().getIdLong()); + gmh.accept((id) -> playerMap.remove(id)); String command = event.getMessage().getContentRaw().trim().toLowerCase(); switch (command) { diff --git a/src/main/java/net/locusworks/discord/eighttrack/handlers/GuildMusicHandler.java b/src/main/java/net/locusworks/discord/eighttrack/handlers/GuildMusicHandler.java index 4da92be..177e862 100644 --- a/src/main/java/net/locusworks/discord/eighttrack/handlers/GuildMusicHandler.java +++ b/src/main/java/net/locusworks/discord/eighttrack/handlers/GuildMusicHandler.java @@ -33,6 +33,7 @@ import java.nio.file.Path; import java.time.OffsetDateTime; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; import java.util.stream.Collectors; import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; @@ -42,6 +43,8 @@ import com.sedmelluq.discord.lavaplayer.track.AudioTrack; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.ChannelType; +import net.dv8tion.jda.api.entities.GuildChannel; import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.entities.VoiceChannel; import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; @@ -58,12 +61,18 @@ public class GuildMusicHandler { private ApplicationLogger logger; private AudioPlayer player; private AtomicBoolean playing; + private Long voiceChannelId; + + private OffsetDateTime lastPlayed; + + private Consumer callback; public GuildMusicHandler(Path musicDir) throws IOException { this.logger = ApplicationLoggerFactory.getLogger(GuildMusicHandler.class); this.playing = new AtomicBoolean(false); this.musicDir = musicDir; - + this.lastPlayed = OffsetDateTime.now(); + this.apm = new DefaultAudioPlayerManager(); AudioSourceManagers.registerLocalSource(apm); @@ -74,6 +83,14 @@ public class GuildMusicHandler { indexFiles(); } + public OffsetDateTime getLastPlayed() { + return lastPlayed; + } + + public void accept(Consumer callback) { + this.callback = callback; + } + public void isPlaying(boolean playing) { this.playing.set(playing); } @@ -127,6 +144,15 @@ public class GuildMusicHandler { } public void next(GuildMessageReceivedEvent event) { + + GuildChannel gc = event.getGuild().getGuildChannelById(ChannelType.VOICE, voiceChannelId); + if (gc != null && gc.getMembers().size() == 1) { + event.getChannel().sendMessage("Going silent since no one is currently listening to the channel").queue(); + event.getGuild().getAudioManager().closeAudioConnection(); + if (callback != null) callback.accept(event.getGuild().getIdLong()); + return; + } + playing.set(false); stop(event); play(event); @@ -143,12 +169,14 @@ public class GuildMusicHandler { event.getChannel().sendMessage(String.format("<@%s> you are not in a voice channel to play music", event.getMember().getId())).queue(); return; } - + if (!event.getGuild().getSelfMember().hasPermission(vc, Permission.VOICE_CONNECT, Permission.VOICE_SPEAK)) { event.getChannel().sendMessage(String.format("<@%s>, I cannot play my music in channel %s as I dont have permission to", event.getMember().getId(), vc.getName())).queue(); return; } + + voiceChannelId = vc.getIdLong(); AudioManager manager = event.getGuild().getAudioManager(); manager.openAudioConnection(vc); @@ -156,8 +184,10 @@ public class GuildMusicHandler { manager.setSendingHandler(new EightTrackAudioSendHandler(player)); if (ts.hasTracks()) { + lastPlayed = OffsetDateTime.now(); + AudioTrack track = ts.getNextTrack(); - + MessageEmbed embed = new EmbedBuilder() .setAuthor(event.getMember().getEffectiveName(), null, event.getAuthor().getAvatarUrl()) .setTitle("Now Playing:")