diff --git a/src/main/java/cc/fascinated/bat/event/EventListener.java b/src/main/java/cc/fascinated/bat/event/EventListener.java index 80f8951..8ab8d5b 100644 --- a/src/main/java/cc/fascinated/bat/event/EventListener.java +++ b/src/main/java/cc/fascinated/bat/event/EventListener.java @@ -19,6 +19,7 @@ import net.dv8tion.jda.api.events.guild.member.GuildMemberRoleAddEvent; import net.dv8tion.jda.api.events.guild.member.GuildMemberRoleRemoveEvent; import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateNicknameEvent; import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateTimeOutEvent; +import net.dv8tion.jda.api.events.guild.voice.GenericGuildVoiceEvent; import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent; import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent; @@ -232,6 +233,15 @@ public interface EventListener { default void onUserUpdateAvatar(@NonNull BatUser user, String oldAvatarUrl, String newAvatarUrl, @NonNull UserUpdateAvatarEvent event) { } + /** + * Called when a user joins or leaves a voice channel + * + * @param guild the guild that the user joined or left the voice channel in + * @param user the user that joined or left the voice channel + */ + default void onGuildVoiceUpdate(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull GenericGuildVoiceEvent event) { + } + /** * Called when Spring is shutting down */ diff --git a/src/main/java/cc/fascinated/bat/features/logging/LogType.java b/src/main/java/cc/fascinated/bat/features/logging/LogType.java index d780b58..49e996e 100644 --- a/src/main/java/cc/fascinated/bat/features/logging/LogType.java +++ b/src/main/java/cc/fascinated/bat/features/logging/LogType.java @@ -35,7 +35,9 @@ public enum LogType { * Channel Events */ CHANNEL_CREATE(LogCategory.CHANNEL, "Channel Create"), - CHANNEL_DELETE(LogCategory.CHANNEL, "Channel Delete"); + CHANNEL_DELETE(LogCategory.CHANNEL, "Channel Delete"), + VOICE_CHANNEL_JOIN(LogCategory.CHANNEL, "Voice Channel Join"), + VOICE_CHANNEL_LEAVE(LogCategory.CHANNEL, "Voice Channel Leave"); /** * The category of the log type diff --git a/src/main/java/cc/fascinated/bat/features/logging/listeners/ChannelListener.java b/src/main/java/cc/fascinated/bat/features/logging/listeners/ChannelListener.java index 0e014f5..077626d 100644 --- a/src/main/java/cc/fascinated/bat/features/logging/listeners/ChannelListener.java +++ b/src/main/java/cc/fascinated/bat/features/logging/listeners/ChannelListener.java @@ -7,22 +7,33 @@ import cc.fascinated.bat.event.EventListener; import cc.fascinated.bat.features.logging.LogFeature; import cc.fascinated.bat.features.logging.LogType; import cc.fascinated.bat.model.BatGuild; +import cc.fascinated.bat.model.BatUser; import lombok.NonNull; import lombok.extern.log4j.Log4j2; import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; +import net.dv8tion.jda.api.entities.channel.unions.AudioChannelUnion; import net.dv8tion.jda.api.entities.channel.unions.ChannelUnion; import net.dv8tion.jda.api.events.channel.ChannelCreateEvent; import net.dv8tion.jda.api.events.channel.ChannelDeleteEvent; +import net.dv8tion.jda.api.events.guild.voice.GenericGuildVoiceEvent; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; +import java.util.HashMap; +import java.util.Map; + /** * @author Fascinated (fascinated7) */ @Component @Log4j2 public class ChannelListener implements EventListener { + /** + * A map of users and the last voice channel they were in + */ + private final Map lastVoiceChannel = new HashMap<>(); private final LogFeature logFeature; @Autowired @@ -53,4 +64,25 @@ public class ChannelListener implements EventListener { } logFeature.sendLog(guild, LogType.CHANNEL_DELETE, EmbedUtils.errorEmbed().setDescription(description.build()).build()); } + + @Override + public void onGuildVoiceUpdate(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull GenericGuildVoiceEvent event) { + AudioChannelUnion channel = event.getVoiceState().getChannel(); + if (channel != null) { + VoiceChannel voiceChannel = channel.asVoiceChannel(); + lastVoiceChannel.put(user, voiceChannel); + } + VoiceChannel voiceChannel = lastVoiceChannel.get(user); + boolean joined = voiceChannel.getMembers().contains(event.getMember()); + if (!joined) { + lastVoiceChannel.remove(user); + } + log.info("User \"{}\" {} voice channel \"{}\" in guild \"{}\"", user.getId(), joined ? "joined" : "left", voiceChannel.getName(), guild.getName()); + logFeature.sendLog(guild, joined ? LogType.VOICE_CHANNEL_JOIN : LogType.VOICE_CHANNEL_LEAVE, EmbedUtils.successEmbed() + .setDescription(new EmbedDescriptionBuilder("User %s Voice Channel".formatted(joined ? "Joined" : "Left")) + .appendLine("User: %s".formatted(user.getDiscordUser().getAsMention()), true) + .appendLine("Channel: %s".formatted(voiceChannel.getAsMention()), true) + .build()) + .build()); + } } diff --git a/src/main/java/cc/fascinated/bat/service/EventService.java b/src/main/java/cc/fascinated/bat/service/EventService.java index 7a672e9..4fd2fcc 100644 --- a/src/main/java/cc/fascinated/bat/service/EventService.java +++ b/src/main/java/cc/fascinated/bat/service/EventService.java @@ -16,6 +16,7 @@ import net.dv8tion.jda.api.events.guild.member.GuildMemberRoleAddEvent; import net.dv8tion.jda.api.events.guild.member.GuildMemberRoleRemoveEvent; import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateNicknameEvent; import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateTimeOutEvent; +import net.dv8tion.jda.api.events.guild.voice.GuildVoiceUpdateEvent; import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent; import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent; @@ -290,4 +291,17 @@ public class EventService extends ListenerAdapter { listener.onUserUpdateAvatar(user, event.getOldAvatarUrl(), event.getNewAvatarUrl(), event); } } + + @Override + public void onGuildVoiceUpdate(@NotNull GuildVoiceUpdateEvent event) { + if (event.getEntity().getUser().isBot()) { + return; + } + BatGuild guild = guildService.getGuild(event.getEntity().getGuild().getId()); + BatUser user = userService.getUser(event.getEntity().getUser().getId()); + + for (EventListener listener : LISTENERS) { + listener.onGuildVoiceUpdate(guild, user, event); + } + } }