diff --git a/CommonCore/SQL/src/de/steamwar/sql/SteamwarUser.kt b/CommonCore/SQL/src/de/steamwar/sql/SteamwarUser.kt index 7466a96d..0d19c712 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/SteamwarUser.kt +++ b/CommonCore/SQL/src/de/steamwar/sql/SteamwarUser.kt @@ -25,6 +25,7 @@ import org.jetbrains.exposed.v1.core.dao.id.EntityID import org.jetbrains.exposed.v1.core.dao.id.IntIdTable import org.jetbrains.exposed.v1.core.eq import org.jetbrains.exposed.v1.core.inList +import org.jetbrains.exposed.v1.core.neq import org.jetbrains.exposed.v1.dao.IntEntity import org.jetbrains.exposed.v1.dao.IntEntityClass import org.jetbrains.exposed.v1.jdbc.insert @@ -136,6 +137,12 @@ class SteamwarUser(id: EntityID) : IntEntity(id) { .select(SteamwarUserTable.fields).where { UserPermTable.perm eq perm }.map { wrapRow(it) } } + @JvmStatic + fun getUsersWithDiscordId() = + useDb { + find { SteamwarUserTable.discordId neq null }.toList() + } + @JvmStatic fun getServerTeam() = useDb { diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java index cdcb8e51..9cbd4061 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java @@ -22,6 +22,7 @@ package de.steamwar.velocitycore.discord; import de.steamwar.command.SWCommand; import de.steamwar.messages.Chatter; import de.steamwar.sql.Event; +import de.steamwar.sql.SteamwarUser; import de.steamwar.velocitycore.VelocityCore; import de.steamwar.velocitycore.discord.channels.*; import de.steamwar.velocitycore.discord.listeners.ChannelListener; @@ -52,12 +53,12 @@ import net.dv8tion.jda.api.utils.MemberCachePolicy; import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; import java.awt.*; -import java.util.ArrayList; -import java.util.HashMap; +import java.util.*; import java.util.List; -import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; +import java.util.stream.Collectors; public class DiscordBot { public static final String ARGUMENT_NAME = "arguments"; @@ -169,7 +170,7 @@ public class DiscordBot { eventChannel = new StaticMessageChannel(config.channel("events"), EventChannel::get); checklistChannel = new ChecklistChannel(config.channel("checklist")); - config.getCouncilThread().forEach((roleId, threadId) -> new CouncilChannel(DiscordBot.getGuild().getRoleById(roleId), DiscordBot.getGuild().getThreadChannelById(threadId))); + CouncilChannel.initCouncilChannels(); announcementChannel = new DiscordChannel(config.channel("announcement"), 0) { @Override diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/CouncilChannel.java b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/CouncilChannel.java index b64c16de..ac563005 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/CouncilChannel.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/CouncilChannel.java @@ -20,47 +20,97 @@ package de.steamwar.velocitycore.discord.channels; import de.steamwar.sql.SteamwarUser; -import de.steamwar.velocitycore.VelocityCore; import de.steamwar.velocitycore.discord.DiscordBot; import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Role; import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; public class CouncilChannel extends StaticMessageChannel { private static final Set channels = new HashSet<>(); + private static final Set roleSet = DiscordBot.getInstance() + .getConfig() + .getCouncilThread() + .keySet() + .stream() + .map(roleId -> DiscordBot.getGuild().getRoleById(roleId)) + .collect(Collectors.toSet()); + + private static final Map> membersByRole = new HashMap<>(); + + private static void initRolesAndMembers(Runnable loaded) { + List discordIds = SteamwarUser.getUsersWithDiscordId().stream() + .map(SteamwarUser::getDiscordId) + .collect(Collectors.toList()); + + membersByRole.clear(); + AtomicInteger countdown = new AtomicInteger(0); + for (int i = 0; i < discordIds.size(); i += 100) { + countdown.incrementAndGet(); + + List retrieveIds = discordIds.subList(i, Math.min(discordIds.size(), i + 100)); + + DiscordBot.getGuild().retrieveMembersByIds(retrieveIds) + .onSuccess(members -> { + members.forEach(member -> { + for (Role role : roleSet) { + if (member.getUnsortedRoles().contains(role)) { + membersByRole.computeIfAbsent(role, __ -> new ArrayList<>()).add(member); + } + } + }); + + if (countdown.decrementAndGet() == 0) { + loaded.run(); + } + }); + } + } + + public static void initCouncilChannels() { + initRolesAndMembers(() -> { + DiscordBot.getInstance() + .getConfig() + .getCouncilThread() + .forEach((roleId, threadId) -> { + new CouncilChannel(DiscordBot.getGuild().getRoleById(roleId), DiscordBot.getGuild().getThreadChannelById(threadId)); + }); + }); + } + public static void updateAll() { - channels.forEach(StaticMessageChannel::update); + initRolesAndMembers(() -> { + channels.forEach(StaticMessageChannel::update); + }); } public CouncilChannel(Role role, ThreadChannel threadChannel) { - super(threadChannel, (consumer) -> { + super(threadChannel, () -> { MessageCreateBuilder messageCreateBuilder = new MessageCreateBuilder(); messageCreateBuilder.setContent("# Ratsmitglieder"); - DiscordBot.getGuild().findMembersWithRoles(role).onError(throwable -> { - VelocityCore.getLogger().warning("Could not get members for " + role.getName()); - consumer.accept(messageCreateBuilder); - }).onSuccess(members -> { - members.stream() - .map(member -> { - SteamwarUser steamwarUser = SteamwarUser.get(member.getIdLong()); - String name = steamwarUser == null ? member.getEffectiveName() : steamwarUser.getUserName(); - UUID uuid = steamwarUser == null ? null : steamwarUser.getUUID(); - return Map.entry(name, uuid); - }) - .sorted(Comparator.comparing(Map.Entry::getKey)) - .forEach(entry -> { - messageCreateBuilder.addEmbeds(new EmbedBuilder() - .setTitle(entry.getKey()) - .setImage(entry.getValue() == null ? null : "https://api.steamwar.de/data/skin/" + entry.getValue().toString()) - .build()); - }); - consumer.accept(messageCreateBuilder); - }); + membersByRole.get(role) + .stream() + .map(member -> { + SteamwarUser steamwarUser = SteamwarUser.get(member.getIdLong()); + String name = steamwarUser == null ? member.getEffectiveName() : steamwarUser.getUserName(); + UUID uuid = steamwarUser == null ? null : steamwarUser.getUUID(); + return Map.entry(name, uuid); + }) + .sorted(Map.Entry.comparingByKey()) + .forEach(entry -> { + messageCreateBuilder.addEmbeds(new EmbedBuilder() + .setTitle(entry.getKey()) + .setImage(entry.getValue() == null ? null : "https://api.steamwar.de/data/skin/" + entry.getValue()) + .build()); + }); + return messageCreateBuilder; }, event -> { }); diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/StaticMessageChannel.java b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/StaticMessageChannel.java index d52c1354..afd276a3 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/StaticMessageChannel.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/StaticMessageChannel.java @@ -40,7 +40,7 @@ public class StaticMessageChannel extends DiscordChannel { } private Message message; - private final Consumer> supplier; + private final Supplier supplier; private final Consumer interaction; public StaticMessageChannel(String channel, Supplier supplier) { @@ -50,12 +50,12 @@ public class StaticMessageChannel extends DiscordChannel { public StaticMessageChannel(String channel, Supplier supplier, Consumer interaction) { super(channel, 0); - this.supplier = messageCreateBuilderConsumer -> supplier.get(); + this.supplier = supplier; this.interaction = interaction; init(); } - public StaticMessageChannel(MessageChannel channel, Consumer> supplier, Consumer interaction) { + public StaticMessageChannel(MessageChannel channel, Supplier supplier, Consumer interaction) { super(channel, 0); this.supplier = supplier; this.interaction = interaction; @@ -77,13 +77,11 @@ public class StaticMessageChannel extends DiscordChannel { } public void update() { - supplier.accept(messageCreateBuilder -> { - if (message == null) { - getChannel().sendMessage(messageCreateBuilder.build()).queue(m -> message = m); - } else { - message.editMessage(MessageEditData.fromCreateData(messageCreateBuilder.build())).queue(); - } - }); + if (message == null) { + getChannel().sendMessage(supplier.get().build()).queue(m -> message = m); + } else { + message.editMessage(MessageEditData.fromCreateData(supplier.get().build())).queue(); + } } @Override diff --git a/settings.gradle.kts b/settings.gradle.kts index b84535d4..3c5497f6 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -125,7 +125,7 @@ dependencyResolutionManagement { library("velocityapi", "com.velocitypowered:velocity-api:3.5.0-SNAPSHOT") library("viaapi", "com.viaversion:viaversion-api:4.3.1") library("viavelocity", "com.viaversion:viaversion-velocity:4.3.1") - library("jda", "net.dv8tion:JDA:5.5.1") + library("jda", "net.dv8tion:JDA:6.4.1") library("msgpack", "org.msgpack:msgpack-core:0.9.8") library("logback", "ch.qos.logback:logback-classic:1.5.6")