diff --git a/pom.xml b/pom.xml index 6d92885..1d449b0 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ net.dv8tion JDA - 4.2.0_212 + 4.2.0_214 com.jagrosh diff --git a/src/main/java/com/jagrosh/vortex/Vortex.java b/src/main/java/com/jagrosh/vortex/Vortex.java index 5e175ba..fa73dcc 100644 --- a/src/main/java/com/jagrosh/vortex/Vortex.java +++ b/src/main/java/com/jagrosh/vortex/Vortex.java @@ -40,6 +40,8 @@ import com.jagrosh.vortex.logging.ModLogger; import com.jagrosh.vortex.logging.TextUploader; import com.jagrosh.vortex.utils.FormatUtil; +import com.jagrosh.vortex.utils.MultiBotManager; +import com.jagrosh.vortex.utils.MultiBotManager.MultiBotManagerBuilder; import com.jagrosh.vortex.utils.OtherUtil; import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; @@ -50,7 +52,6 @@ import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.exceptions.PermissionException; import net.dv8tion.jda.api.requests.restaction.MessageAction; -import net.dv8tion.jda.api.sharding.DefaultShardManagerBuilder; import net.dv8tion.jda.api.sharding.ShardManager; import net.dv8tion.jda.api.utils.MemberCachePolicy; import net.dv8tion.jda.api.utils.cache.CacheFlag; @@ -65,7 +66,7 @@ private final ScheduledExecutorService threadpool; private final Database database; private final TextUploader uploader; - private final ShardManager shards; + private final MultiBotManager shards; private final ModLogger modlog; private final BasicLogger basiclog; private final MessageCache messages; @@ -183,7 +184,17 @@ //.setCarbonitexKey(config.getString("listing.carbon")) .build(); MessageAction.setDefaultMentions(Arrays.asList(Message.MentionType.EMOTE, Message.MentionType.CHANNEL)); - shards = DefaultShardManagerBuilder.create(config.getString("bot-token"), Constants.INTENTS) + shards = new MultiBotManager.MultiBotManagerBuilder() + .addBot(config.getString("pro-token"), Constants.INTENTS) + .addBot(config.getString("bot-token"), Constants.INTENTS) + .setMemberCachePolicy(MemberCachePolicy.ALL) + .enableCache(CacheFlag.MEMBER_OVERRIDES, CacheFlag.VOICE_STATE) + .disableCache(CacheFlag.EMOTE, CacheFlag.ACTIVITY, CacheFlag.CLIENT_STATUS) + .addEventListeners(new Listener(this), client, waiter) + .setStatus(OnlineStatus.DO_NOT_DISTURB) + .setActivity(Activity.playing("loading...")) + .build(); + /*shards = DefaultShardManagerBuilder.create(config.getString("bot-token"), Constants.INTENTS) .setMemberCachePolicy(MemberCachePolicy.ALL) .enableCache(CacheFlag.MEMBER_OVERRIDES, CacheFlag.VOICE_STATE) .disableCache(CacheFlag.EMOTE, CacheFlag.ACTIVITY, CacheFlag.CLIENT_STATUS) @@ -193,7 +204,7 @@ .setActivity(Activity.playing("loading...")) .setBulkDeleteSplittingEnabled(false) .setRequestTimeoutRetry(true) - .build(); + .build();*/ modlog.start(); @@ -223,7 +234,7 @@ return uploader; } - public ShardManager getShardManager() + public MultiBotManager getShardManager() { return shards; } @@ -278,7 +289,7 @@ public void leavePointlessGuilds() { - shards.getGuilds().stream().filter(g -> + shards.getShardManagers().stream().flatMap(s -> s.getGuilds().stream()).filter(g -> { if(!g.isLoaded()) return false; diff --git a/src/main/java/com/jagrosh/vortex/commands/owner/DebugCmd.java b/src/main/java/com/jagrosh/vortex/commands/owner/DebugCmd.java index c234bed..9eb3836 100644 --- a/src/main/java/com/jagrosh/vortex/commands/owner/DebugCmd.java +++ b/src/main/java/com/jagrosh/vortex/commands/owner/DebugCmd.java @@ -22,7 +22,10 @@ import com.jagrosh.vortex.Vortex; import com.jagrosh.vortex.utils.FormatUtil; import java.time.temporal.ChronoUnit; +import java.util.stream.Stream; import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.sharding.ShardManager; /** * @@ -49,15 +52,21 @@ long usedMb = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/(1024*1024); StringBuilder sb = new StringBuilder("**"+event.getSelfUser().getName()+"** statistics:" + "\nLast Startup: "+FormatUtil.secondsToTime(Constants.STARTUP.until(OffsetDateTime.now(), ChronoUnit.SECONDS))+" ago" - + "\nGuilds: **"+vortex.getShardManager().getGuildCache().size()+"**" - + "\nMemory: **"+usedMb+"**Mb / **"+totalMb+"**Mb" - + "\nAverage Ping: **"+vortex.getShardManager().getAverageGatewayPing()+"**ms" - + "\nShard Total: **"+vortex.getShardManager().getShardsTotal()+"**" - + "\nShard Connectivity: ```diff"); - vortex.getShardManager().getShards().forEach(jda -> sb.append("\n").append(jda.getStatus()==JDA.Status.CONNECTED ? "+ " : "- ") - .append(jda.getShardInfo().getShardId()<10 ? "0" : "").append(jda.getShardInfo().getShardId()).append(": ").append(jda.getStatus()) - .append(" ~ ").append(jda.getGuildCache().size()).append(" guilds")); - sb.append("\n```"); + + "\nMemory: **"+usedMb+"**Mb / **"+totalMb+"**Mb"); + vortex.getShardManager().getShardManagers().forEach(bot -> + //Stream.of(vortex.getShardManager()).forEach(bot -> + { + User self = bot.getShards().get(0).getSelfUser(); + sb.append("\n\n__**").append(self.getName()).append("** (").append(self.getId()).append(")__") + .append("\nGuilds: **").append(bot.getGuildCache().size()).append("**") + .append("\nAverage Ping: **").append(bot.getAverageGatewayPing()).append("**ms") + .append("\nShard Total: **").append(bot.getShardsTotal()).append("**") + .append("\nShard Connectivity: ```diff"); + bot.getShards().forEach(jda -> sb.append("\n").append(jda.getStatus()==JDA.Status.CONNECTED ? "+ " : "- ") + .append(jda.getShardInfo().getShardId()<10 ? "0" : "").append(jda.getShardInfo().getShardId()).append(": ").append(jda.getStatus()) + .append(" ~ ").append(jda.getGuildCache().size()).append(" guilds")); + sb.append("\n```"); + }); event.reply(sb.toString().trim()); } } diff --git a/src/main/java/com/jagrosh/vortex/logging/MessageCache.java b/src/main/java/com/jagrosh/vortex/logging/MessageCache.java index 12dd3e6..e6a810c 100644 --- a/src/main/java/com/jagrosh/vortex/logging/MessageCache.java +++ b/src/main/java/com/jagrosh/vortex/logging/MessageCache.java @@ -16,6 +16,7 @@ package com.jagrosh.vortex.logging; import com.jagrosh.vortex.utils.FixedCache; +import com.jagrosh.vortex.utils.MultiBotManager; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -83,6 +84,11 @@ return attachments; } + public User getAuthor(MultiBotManager botManager) + { + return botManager.getUserById(author); + } + public User getAuthor(ShardManager shardManager) { return shardManager.getUserById(author); @@ -103,6 +109,16 @@ return author; } + public TextChannel getTextChannel(MultiBotManager botManager) + { + if (guild == 0L) + return null; + Guild g = botManager.getGuildById(guild); + if (g == null) + return null; + return g.getTextChannelById(channel); + } + public TextChannel getTextChannel(ShardManager shardManager) { if (guild == 0L) @@ -123,6 +139,13 @@ return guild.getTextChannelById(channel); } + public Guild getGuild(MultiBotManager botManager) + { + if (guild == 0L) + return null; + return botManager.getGuildById(guild); + } + public Guild getGuild(ShardManager shardManager) { if (guild == 0L) diff --git a/src/main/java/com/jagrosh/vortex/utils/ConditionalEventManager.java b/src/main/java/com/jagrosh/vortex/utils/ConditionalEventManager.java index b358587..013549a 100644 --- a/src/main/java/com/jagrosh/vortex/utils/ConditionalEventManager.java +++ b/src/main/java/com/jagrosh/vortex/utils/ConditionalEventManager.java @@ -15,24 +15,36 @@ */ package com.jagrosh.vortex.utils; +import java.util.List; import net.dv8tion.jda.api.events.GenericEvent; import net.dv8tion.jda.api.events.guild.GenericGuildEvent; import net.dv8tion.jda.api.hooks.InterfacedEventManager; +import net.dv8tion.jda.api.sharding.ShardManager; /** * * @author John Grosh (john.a.grosh@gmail.com) */ -public class ConditionalEventManager extends InterfacedEventManager +public abstract class ConditionalEventManager extends InterfacedEventManager { + protected abstract List getOrderedShardManagers(); + @Override public void handle(GenericEvent ge) { // check if this guild is already loaded by some other shard if(ge instanceof GenericGuildEvent) { + long selfId = ge.getJDA().getSelfUser().getIdLong(); long gid = ((GenericGuildEvent) ge).getGuild().getIdLong(); + for(ShardManager bot: getOrderedShardManagers()) + { + if(bot.getShards().get(0).getSelfUser().getIdLong() == selfId) + break; + if(bot.getGuildById(gid) != null) + return; + } } // otherwise, continue as normal diff --git a/src/main/java/com/jagrosh/vortex/utils/LogUtil.java b/src/main/java/com/jagrosh/vortex/utils/LogUtil.java index b492b5f..a916c22 100644 --- a/src/main/java/com/jagrosh/vortex/utils/LogUtil.java +++ b/src/main/java/com/jagrosh/vortex/utils/LogUtil.java @@ -20,9 +20,11 @@ import java.time.OffsetDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; +import java.util.ArrayDeque; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Message; @@ -121,14 +123,17 @@ StringBuilder sb = new StringBuilder("-- "+title+" -- #"+deltc.getName()+" ("+deltc.getId()+") -- "+delg.getName()+" ("+delg.getId()+") --"); Message m; for(int i=0; i sb.append("\n").append(att.getUrl())); - } + appendMessage(sb, messages.get(i)); + return sb.toString().trim(); + } + + public static String logCachedMessagesForwards(String title, List messages, MultiBotManager botManager) + { + TextChannel deltc = messages.get(0).getTextChannel(botManager); + Guild delg = deltc.getGuild(); + StringBuilder sb = new StringBuilder("-- "+title+" -- #"+deltc.getName()+" ("+deltc.getId()+") -- "+delg.getName()+" ("+delg.getId()+") --"); + for(int i=0; i sb.append("\n").append(att.getUrl())); - } + appendMessage(sb, messages.get(i), messages.get(i).getAuthor(shardManager)); return sb.toString().trim(); } @@ -162,17 +154,32 @@ StringBuilder sb = new StringBuilder("-- "+title+" -- #"+deltc.getName()+" ("+deltc.getId()+") -- "+delg.getName()+" ("+delg.getId()+") --"); Message m; for(int i=messages.size()-1; i>=0; i--) - { - m = messages.get(i); - sb.append("\r\n\r\n[") - .append(m.getTimeCreated().format(DateTimeFormatter.RFC_1123_DATE_TIME)) - .append("] ").append(m.getAuthor().getName()).append("#").append(m.getAuthor().getDiscriminator()) - .append(" (").append(m.getAuthor().getId()).append(") : ").append(m.getContentRaw()); - m.getAttachments().forEach(att -> sb.append("\n").append(att.getUrl())); - } + appendMessage(sb, messages.get(i)); return sb.toString().trim(); } + private static void appendMessage(StringBuilder sb, Message m) + { + sb.append("\r\n\r\n[") + .append(m.getTimeCreated().format(DateTimeFormatter.RFC_1123_DATE_TIME)) + .append("] ").append(m.getAuthor().getName()).append("#").append(m.getAuthor().getDiscriminator()) + .append(" (").append(m.getAuthor().getId()).append(") : ").append(m.getContentRaw()); + m.getAttachments().forEach(att -> sb.append("\n").append(att.getUrl())); + } + + private static void appendMessage(StringBuilder sb, CachedMessage m, User author) + { + sb.append("\r\n\r\n[") + .append(m.getTimeCreated().format(DateTimeFormatter.RFC_1123_DATE_TIME)) + .append("] "); + if(author==null) + sb.append(m.getUsername()).append("#").append(m.getDiscriminator()).append(" (").append(m.getAuthorId()); + else + sb.append(author.getName()).append("#").append(author.getDiscriminator()).append(" (").append(author.getId()); + sb.append(") : ").append(m.getContentRaw()); + m.getAttachments().forEach(att -> sb.append("\n").append(att.getUrl())); + } + // Audit logging formats private final static String A_MOD = "%s#%s"; private final static String A_TIME = " (%dm)"; diff --git a/src/main/java/com/jagrosh/vortex/utils/MultiBotManager.java b/src/main/java/com/jagrosh/vortex/utils/MultiBotManager.java new file mode 100644 index 0000000..f892b44 --- /dev/null +++ b/src/main/java/com/jagrosh/vortex/utils/MultiBotManager.java @@ -0,0 +1,163 @@ +/* + * Copyright 2020 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.vortex.utils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import javax.security.auth.login.LoginException; +import net.dv8tion.jda.api.OnlineStatus; +import net.dv8tion.jda.api.entities.Activity; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.TextChannel; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.requests.GatewayIntent; +import net.dv8tion.jda.api.requests.RestAction; +import net.dv8tion.jda.api.sharding.DefaultShardManagerBuilder; +import net.dv8tion.jda.api.sharding.ShardManager; +import net.dv8tion.jda.api.utils.MemberCachePolicy; +import net.dv8tion.jda.api.utils.cache.CacheFlag; + +/** + * + * @author John Grosh (john.a.grosh@gmail.com) + */ +public class MultiBotManager +{ + private final MultiBotEventManager mbem; + private final List bots; + + protected MultiBotManager(List builders) throws LoginException, IllegalArgumentException + { + this.mbem = new MultiBotEventManager(); + this.bots = new ArrayList<>(); + for(DefaultShardManagerBuilder b: builders) + { + b.setEventManagerProvider(i -> mbem); + b.setBulkDeleteSplittingEnabled(false); + b.setRequestTimeoutRetry(true); + bots.add(b.build()); + } + } + + public List getShardManagers() + { + return bots; + } + + public RestAction retrieveUserById(long id) + { + if(!bots.isEmpty()) + return bots.get(0).retrieveUserById(id); + return null; + } + + public Guild getGuildById(long id) + { + for(ShardManager shards: bots) + if(shards.getGuildById(id) != null) + return shards.getGuildById(id); + return null; + } + + public User getUserById(long id) + { + for(ShardManager shards: bots) + if(shards.getUserById(id) != null) + return shards.getUserById(id); + return null; + } + + public TextChannel getTextChannelById(long id) + { + for(ShardManager shards: bots) + if(shards.getTextChannelById(id) != null) + return shards.getTextChannelById(id); + return null; + } + + private class MultiBotEventManager extends ConditionalEventManager + { + @Override + protected List getOrderedShardManagers() + { + return bots; + } + } + + public static class MultiBotManagerBuilder + { + private final List builders = new ArrayList<>(); + + public MultiBotManagerBuilder addBot(String token, Collection intents) + { + builders.add(DefaultShardManagerBuilder.create(token, intents)); + return this; + } + + public MultiBotManagerBuilder setMemberCachePolicy(MemberCachePolicy policy) + { + builders.forEach(b -> b.setMemberCachePolicy(policy)); + return this; + } + + public MultiBotManagerBuilder enableCache(CacheFlag... flags) + { + return enableCache(Arrays.asList(flags)); + } + + public MultiBotManagerBuilder enableCache(Collection flags) + { + builders.forEach(b -> b.enableCache(flags)); + return this; + } + + public MultiBotManagerBuilder disableCache(CacheFlag... flags) + { + return disableCache(Arrays.asList(flags)); + } + + public MultiBotManagerBuilder disableCache(Collection flags) + { + builders.forEach(b -> b.disableCache(flags)); + return this; + } + + public MultiBotManagerBuilder addEventListeners(Object... listeners) + { + builders.forEach(b -> b.addEventListeners(listeners)); + return this; + } + + public MultiBotManagerBuilder setStatus(OnlineStatus status) + { + builders.forEach(b -> b.setStatus(status)); + return this; + } + + public MultiBotManagerBuilder setActivity(Activity activity) + { + builders.forEach(b -> b.setActivity(activity)); + return this; + } + + public MultiBotManager build() throws LoginException, IllegalArgumentException + { + return new MultiBotManager(builders); + } + } +} diff --git a/src/main/java/com/jagrosh/vortex/utils/MultiBotShardManager.java b/src/main/java/com/jagrosh/vortex/utils/MultiBotShardManager.java deleted file mode 100644 index 0f213e3..0000000 --- a/src/main/java/com/jagrosh/vortex/utils/MultiBotShardManager.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2020 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.vortex.utils; - -/** - * - * @author John Grosh (john.a.grosh@gmail.com) - */ -public class MultiBotShardManager -{ - -}