Merge pull request #583 from MichailiK/feature/auto-leave-when-alone

Add "alone time until stop"
This commit is contained in:
John Grosh 2021-02-09 09:55:50 -05:00 committed by GitHub
commit ebf6e43084
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 130 additions and 2 deletions

View file

@ -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()
{

View file

@ -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)
{

View file

@ -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)
{

View file

@ -0,0 +1,98 @@
/*
* Copyright 2021 John Grosh <john.a.grosh@gmail.com>.
*
* 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.Guild;
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<Long, Instant> 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<Long> toRemove = new HashSet<>();
for(Map.Entry<Long, Instant> entrySet: aloneSince.entrySet())
{
if(entrySet.getValue().getEpochSecond() > Instant.now().getEpochSecond() - aloneTimeUntilStop) continue;
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());
}
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.getIdLong());
if(!alone && inList)
aloneSince.remove(guild.getIdLong());
else if(alone && !inList)
aloneSince.put(guild.getIdLong(), 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.getUser().isBot());
}
}

View file

@ -99,6 +99,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