From 36c53cfd41c9ba77e09646609b53f27ae58c171f Mon Sep 17 00:00:00 2001 From: Michaili K Date: Wed, 13 Jan 2021 01:58:21 +0100 Subject: [PATCH 1/3] Add "alone time until stop" feature & config --- src/main/java/com/jagrosh/jmusicbot/Bot.java | 9 ++ .../java/com/jagrosh/jmusicbot/BotConfig.java | 8 +- .../java/com/jagrosh/jmusicbot/Listener.java | 10 ++- .../jmusicbot/audio/AloneInVoiceHandler.java | 90 +++++++++++++++++++ src/main/resources/reference.conf | 7 ++ 5 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/jagrosh/jmusicbot/audio/AloneInVoiceHandler.java diff --git a/src/main/java/com/jagrosh/jmusicbot/Bot.java b/src/main/java/com/jagrosh/jmusicbot/Bot.java index a283833..b2f8f33 100644 --- a/src/main/java/com/jagrosh/jmusicbot/Bot.java +++ b/src/main/java/com/jagrosh/jmusicbot/Bot.java @@ -18,6 +18,7 @@ package com.jagrosh.jmusicbot; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import com.jagrosh.jdautilities.commons.waiter.EventWaiter; +import com.jagrosh.jmusicbot.audio.AloneInVoiceHandler; import com.jagrosh.jmusicbot.audio.AudioHandler; import com.jagrosh.jmusicbot.audio.NowplayingHandler; import com.jagrosh.jmusicbot.audio.PlayerManager; @@ -42,6 +43,7 @@ public class Bot private final PlayerManager players; private final PlaylistLoader playlists; private final NowplayingHandler nowplaying; + private final AloneInVoiceHandler aloneInVoiceHandler; private boolean shuttingDown = false; private JDA jda; @@ -58,6 +60,8 @@ public class Bot this.players.init(); this.nowplaying = new NowplayingHandler(this); this.nowplaying.init(); + this.aloneInVoiceHandler = new AloneInVoiceHandler(this); + this.aloneInVoiceHandler.init(); } public BotConfig getConfig() @@ -94,6 +98,11 @@ public class Bot { return nowplaying; } + + public AloneInVoiceHandler getAloneInVoiceHandler() + { + return aloneInVoiceHandler; + } public JDA getJDA() { diff --git a/src/main/java/com/jagrosh/jmusicbot/BotConfig.java b/src/main/java/com/jagrosh/jmusicbot/BotConfig.java index b0b50ae..9f61612 100644 --- a/src/main/java/com/jagrosh/jmusicbot/BotConfig.java +++ b/src/main/java/com/jagrosh/jmusicbot/BotConfig.java @@ -42,7 +42,7 @@ public class BotConfig private String token, prefix, altprefix, helpWord, playlistsFolder, successEmoji, warningEmoji, errorEmoji, loadingEmoji, searchingEmoji; private boolean stayInChannel, songInGame, npImages, updatealerts, useEval, dbots; - private long owner, maxSeconds; + private long owner, maxSeconds, aloneTimeUntilStop; private OnlineStatus status; private Activity game; private Config aliases; @@ -94,6 +94,7 @@ public class BotConfig updatealerts = config.getBoolean("updatealerts"); useEval = config.getBoolean("eval"); maxSeconds = config.getLong("maxtime"); + aloneTimeUntilStop = config.getLong("alonetimeuntilstop"); playlistsFolder = config.getString("playlistsfolder"); aliases = config.getConfig("aliases"); dbots = owner == 113156185389092864L; @@ -298,6 +299,11 @@ public class BotConfig { return FormatUtil.formatTime(maxSeconds * 1000); } + + public long getAloneTimeUntilStop() + { + return aloneTimeUntilStop; + } public boolean isTooLong(AudioTrack track) { diff --git a/src/main/java/com/jagrosh/jmusicbot/Listener.java b/src/main/java/com/jagrosh/jmusicbot/Listener.java index 0605498..df7bb32 100644 --- a/src/main/java/com/jagrosh/jmusicbot/Listener.java +++ b/src/main/java/com/jagrosh/jmusicbot/Listener.java @@ -24,8 +24,10 @@ import net.dv8tion.jda.api.entities.VoiceChannel; import net.dv8tion.jda.api.events.ReadyEvent; import net.dv8tion.jda.api.events.ShutdownEvent; import net.dv8tion.jda.api.events.guild.GuildJoinEvent; +import net.dv8tion.jda.api.events.guild.voice.GuildVoiceUpdateEvent; import net.dv8tion.jda.api.events.message.guild.GuildMessageDeleteEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; +import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -89,7 +91,13 @@ public class Listener extends ListenerAdapter { bot.getNowplayingHandler().onMessageDelete(event.getGuild(), event.getMessageIdLong()); } - + + @Override + public void onGuildVoiceUpdate(@NotNull GuildVoiceUpdateEvent event) + { + bot.getAloneInVoiceHandler().onVoiceUpdate(event); + } + @Override public void onShutdown(ShutdownEvent event) { diff --git a/src/main/java/com/jagrosh/jmusicbot/audio/AloneInVoiceHandler.java b/src/main/java/com/jagrosh/jmusicbot/audio/AloneInVoiceHandler.java new file mode 100644 index 0000000..0556ca5 --- /dev/null +++ b/src/main/java/com/jagrosh/jmusicbot/audio/AloneInVoiceHandler.java @@ -0,0 +1,90 @@ +/* + * Copyright 2021 John Grosh . + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jagrosh.jmusicbot.audio; + +import com.jagrosh.jmusicbot.Bot; +import net.dv8tion.jda.api.entities.*; +import net.dv8tion.jda.api.events.guild.voice.GuildVoiceUpdateEvent; + +import java.time.Instant; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * + * @author Michaili K (mysteriouscursor+git@protonmail.com) + */ +public class AloneInVoiceHandler +{ + private final Bot bot; + private final HashMap aloneSince = new HashMap<>(); + private long aloneTimeUntilStop = 0; + + public AloneInVoiceHandler(Bot bot) + { + this.bot = bot; + } + + public void init() + { + aloneTimeUntilStop = bot.getConfig().getAloneTimeUntilStop(); + if(aloneTimeUntilStop > 0) + bot.getThreadpool().scheduleWithFixedDelay(() -> check(), 0, 5, TimeUnit.SECONDS); + } + + private void check() + { + Set toRemove = new HashSet<>(); + for(Map.Entry entrySet: aloneSince.entrySet()) + { + if(entrySet.getValue().getEpochSecond() > Instant.now().getEpochSecond()- aloneTimeUntilStop) continue; + + ((AudioHandler) entrySet.getKey().getAudioManager().getSendingHandler()).stopAndClear(); + entrySet.getKey().getAudioManager().closeAudioConnection(); + + toRemove.add(entrySet.getKey()); + } + toRemove.forEach(id -> aloneSince.remove(id)); + } + + public void onVoiceUpdate(GuildVoiceUpdateEvent event) + { + if(aloneTimeUntilStop <= 0) return; + + Guild guild = event.getEntity().getGuild(); + if(!bot.getPlayerManager().hasHandler(guild)) return; + + boolean alone = isAlone(guild); + boolean inList = aloneSince.containsKey(guild); + + if(!alone && inList) + aloneSince.remove(guild); + else if(alone && !inList) + aloneSince.put(guild, Instant.now()); + } + + private boolean isAlone(Guild guild) + { + if(guild.getAudioManager().getConnectedChannel() == null) return false; + return guild.getAudioManager().getConnectedChannel().getMembers().stream() + .noneMatch(x -> + !x.getVoiceState().isDeafened() + && x.getIdLong() != bot.getJDA().getSelfUser().getIdLong()); + } +} diff --git a/src/main/resources/reference.conf b/src/main/resources/reference.conf index 1e9e7bc..c7ea2a7 100644 --- a/src/main/resources/reference.conf +++ b/src/main/resources/reference.conf @@ -100,6 +100,13 @@ stayinchannel = false maxtime = 0 +// This sets the amount of seconds the bot will stay alone on a voice channel until it +// automatically leaves the voice channel and clears the queue. If not set or set +// to any number less than or equal to zero, the bot won't leave when alone. + +alonetimeuntilstop = 0 + + // This sets an alternative folder to be used as the Playlists folder // This can be a relative or absolute path From 18e142ed880a1fcfe27d9babd804871b38bf4c21 Mon Sep 17 00:00:00 2001 From: Michaili K Date: Tue, 9 Feb 2021 15:09:59 +0100 Subject: [PATCH 2/3] Store guild ID instead of the guild object in AloneInVoiceHandler --- .../jmusicbot/audio/AloneInVoiceHandler.java | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/jagrosh/jmusicbot/audio/AloneInVoiceHandler.java b/src/main/java/com/jagrosh/jmusicbot/audio/AloneInVoiceHandler.java index 0556ca5..b4084de 100644 --- a/src/main/java/com/jagrosh/jmusicbot/audio/AloneInVoiceHandler.java +++ b/src/main/java/com/jagrosh/jmusicbot/audio/AloneInVoiceHandler.java @@ -16,7 +16,7 @@ package com.jagrosh.jmusicbot.audio; import com.jagrosh.jmusicbot.Bot; -import net.dv8tion.jda.api.entities.*; +import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.events.guild.voice.GuildVoiceUpdateEvent; import java.time.Instant; @@ -33,7 +33,7 @@ import java.util.concurrent.TimeUnit; public class AloneInVoiceHandler { private final Bot bot; - private final HashMap aloneSince = new HashMap<>(); + private final HashMap aloneSince = new HashMap<>(); private long aloneTimeUntilStop = 0; public AloneInVoiceHandler(Bot bot) @@ -50,13 +50,21 @@ public class AloneInVoiceHandler private void check() { - Set toRemove = new HashSet<>(); - for(Map.Entry entrySet: aloneSince.entrySet()) + Set toRemove = new HashSet<>(); + for(Map.Entry entrySet: aloneSince.entrySet()) { - if(entrySet.getValue().getEpochSecond() > Instant.now().getEpochSecond()- aloneTimeUntilStop) continue; + if(entrySet.getValue().getEpochSecond() > Instant.now().getEpochSecond() - aloneTimeUntilStop) continue; - ((AudioHandler) entrySet.getKey().getAudioManager().getSendingHandler()).stopAndClear(); - entrySet.getKey().getAudioManager().closeAudioConnection(); + Guild guild = bot.getJDA().getGuildById(entrySet.getKey()); + + if(guild == null) + { + toRemove.add(entrySet.getKey()); + continue; + } + + ((AudioHandler) guild.getAudioManager().getSendingHandler()).stopAndClear(); + guild.getAudioManager().closeAudioConnection(); toRemove.add(entrySet.getKey()); } @@ -71,12 +79,12 @@ public class AloneInVoiceHandler if(!bot.getPlayerManager().hasHandler(guild)) return; boolean alone = isAlone(guild); - boolean inList = aloneSince.containsKey(guild); + boolean inList = aloneSince.containsKey(guild.getIdLong()); if(!alone && inList) - aloneSince.remove(guild); + aloneSince.remove(guild.getIdLong()); else if(alone && !inList) - aloneSince.put(guild, Instant.now()); + aloneSince.put(guild.getIdLong(), Instant.now()); } private boolean isAlone(Guild guild) From 6527afb88c3f504e8ba1856e2351e387b721705a Mon Sep 17 00:00:00 2001 From: Michaili K Date: Tue, 9 Feb 2021 15:52:41 +0100 Subject: [PATCH 3/3] Ignore all bots when checking if the bot is alone --- .../java/com/jagrosh/jmusicbot/audio/AloneInVoiceHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/jagrosh/jmusicbot/audio/AloneInVoiceHandler.java b/src/main/java/com/jagrosh/jmusicbot/audio/AloneInVoiceHandler.java index b4084de..d1873f8 100644 --- a/src/main/java/com/jagrosh/jmusicbot/audio/AloneInVoiceHandler.java +++ b/src/main/java/com/jagrosh/jmusicbot/audio/AloneInVoiceHandler.java @@ -93,6 +93,6 @@ public class AloneInVoiceHandler return guild.getAudioManager().getConnectedChannel().getMembers().stream() .noneMatch(x -> !x.getVoiceState().isDeafened() - && x.getIdLong() != bot.getJDA().getSelfUser().getIdLong()); + && !x.getUser().isBot()); } }