Search in sources :

Example 11 with Sx4

use of com.sx4.bot.core.Sx4 in project Sx4 by sx4-discord-bot.

the class ModUtility method performAction.

public static CompletableFuture<? extends Action> performAction(Sx4 bot, Action action, Member target, Member moderator, Reason reason) {
    Guild guild = target.getGuild();
    switch(action.getModAction()) {
        case WARN:
            return ModUtility.warn(bot, target, moderator, reason);
        case MUTE:
        case MUTE_EXTEND:
            if (!guild.getSelfMember().hasPermission(Permission.MANAGE_ROLES)) {
                return CompletableFuture.failedFuture(new BotPermissionException(Permission.MANAGE_ROLES));
            }
            return ModUtility.mute(bot, target, moderator, Duration.ofSeconds(((TimeAction) action).getDuration()), action.getModAction().isExtend(), reason);
        case KICK:
            if (!guild.getSelfMember().hasPermission(Permission.KICK_MEMBERS)) {
                return CompletableFuture.failedFuture(new BotPermissionException(Permission.KICK_MEMBERS));
            }
            if (!guild.getSelfMember().canInteract(target)) {
                return CompletableFuture.failedFuture(new BotHierarchyException("kick"));
            }
            if (!moderator.hasPermission(Permission.KICK_MEMBERS)) {
                return CompletableFuture.failedFuture(new AuthorPermissionException(Permission.KICK_MEMBERS));
            }
            return target.kick(ModUtility.getAuditReason(reason, moderator.getUser())).submit().thenApply($ -> {
                bot.getModActionManager().onModAction(new KickEvent(moderator, target.getUser(), reason));
                return action;
            });
        case TEMPORARY_BAN:
            if (!guild.getSelfMember().hasPermission(Permission.BAN_MEMBERS)) {
                return CompletableFuture.failedFuture(new BotPermissionException(Permission.BAN_MEMBERS));
            }
            if (!guild.getSelfMember().canInteract(target)) {
                return CompletableFuture.failedFuture(new BotHierarchyException("ban"));
            }
            if (!moderator.hasPermission(Permission.BAN_MEMBERS)) {
                return CompletableFuture.failedFuture(new AuthorPermissionException(Permission.BAN_MEMBERS));
            }
            long temporaryBanDuration = ((TimeAction) action).getDuration();
            List<Bson> temporaryBanUpdate = List.of(Operators.set("unbanAt", Operators.add(Operators.nowEpochSecond(), temporaryBanDuration)));
            Bson filter = Filters.and(Filters.eq("userId", target.getIdLong()), Filters.eq("guildId", guild.getIdLong()));
            return bot.getMongo().updateTemporaryBan(filter, temporaryBanUpdate, new UpdateOptions().upsert(true)).thenCompose(temporaryBanResult -> target.ban(1).reason(ModUtility.getAuditReason(reason, moderator.getUser())).submit()).thenApply($ -> {
                bot.getModActionManager().onModAction(new TemporaryBanEvent(moderator, target.getUser(), reason, true, temporaryBanDuration));
                bot.getTemporaryBanManager().putBan(guild.getIdLong(), target.getIdLong(), temporaryBanDuration);
                return action;
            });
        case BAN:
            if (!guild.getSelfMember().hasPermission(Permission.BAN_MEMBERS)) {
                return CompletableFuture.failedFuture(new BotPermissionException(Permission.BAN_MEMBERS));
            }
            if (!guild.getSelfMember().canInteract(target)) {
                return CompletableFuture.failedFuture(new BotHierarchyException("ban"));
            }
            if (!moderator.hasPermission(Permission.BAN_MEMBERS)) {
                return CompletableFuture.failedFuture(new AuthorPermissionException(Permission.BAN_MEMBERS));
            }
            return target.ban(1).reason(ModUtility.getAuditReason(reason, moderator.getUser())).submit().thenApply($ -> {
                bot.getModActionManager().onModAction(new BanEvent(moderator, target.getUser(), reason, true));
                return action;
            });
        default:
            return CompletableFuture.completedFuture(null);
    }
}
Also used : Document(org.bson.Document) Operators(com.sx4.bot.database.mongo.model.Operators) BotPermissionException(com.sx4.bot.exceptions.mod.BotPermissionException) com.sx4.bot.entities.mod.action(com.sx4.bot.entities.mod.action) Permission(net.dv8tion.jda.api.Permission) MongoDatabase(com.sx4.bot.database.mongo.MongoDatabase) CompletableFuture(java.util.concurrent.CompletableFuture) MaxRolesException(com.sx4.bot.exceptions.mod.MaxRolesException) Member(net.dv8tion.jda.api.entities.Member) AuthorPermissionException(com.sx4.bot.exceptions.mod.AuthorPermissionException) BotHierarchyException(com.sx4.bot.exceptions.mod.BotHierarchyException) AtomicReference(java.util.concurrent.atomic.AtomicReference) User(net.dv8tion.jda.api.entities.User) Bson(org.bson.conversions.Bson) List(java.util.List) Guild(net.dv8tion.jda.api.entities.Guild) Sx4(com.sx4.bot.core.Sx4) Role(net.dv8tion.jda.api.entities.Role) Duration(java.time.Duration) Reason(com.sx4.bot.entities.mod.Reason) Clock(java.time.Clock) com.sx4.bot.events.mod(com.sx4.bot.events.mod) com.mongodb.client.model(com.mongodb.client.model) Collections(java.util.Collections) Guild(net.dv8tion.jda.api.entities.Guild) Bson(org.bson.conversions.Bson) BotPermissionException(com.sx4.bot.exceptions.mod.BotPermissionException) BotHierarchyException(com.sx4.bot.exceptions.mod.BotHierarchyException) AuthorPermissionException(com.sx4.bot.exceptions.mod.AuthorPermissionException)

Example 12 with Sx4

use of com.sx4.bot.core.Sx4 in project Sx4 by sx4-discord-bot.

the class ModUtility method mute.

public static CompletableFuture<TimeAction> mute(Sx4 bot, Member target, Member moderator, Duration time, boolean extend, Reason reason) {
    Guild guild = target.getGuild();
    long guildId = guild.getIdLong(), userId = target.getIdLong();
    Document mute = bot.getMongo().getGuildById(guildId, Projections.include("mute.roleId", "mute.defaultTime", "mute.autoUpdate")).get("mute", MongoDatabase.EMPTY_DOCUMENT);
    long duration = time == null ? mute.get("defaultTime", ModUtility.DEFAULT_MUTE_DURATION) : time.toSeconds();
    AtomicReference<Role> atomicRole = new AtomicReference<>();
    return ModUtility.upsertMuteRole(bot.getMongo(), guild, mute.get("roleId", 0L), mute.get("autoUpdate", true)).thenCompose(role -> {
        if (!guild.getSelfMember().hasPermission(Permission.MANAGE_ROLES)) {
            throw new BotPermissionException(Permission.MANAGE_ROLES);
        }
        if (!guild.getSelfMember().canInteract(role)) {
            throw new BotHierarchyException("mute");
        }
        atomicRole.set(role);
        List<Bson> update = List.of(Operators.set("unmuteAt", Operators.add(duration, Operators.cond(Operators.and(extend, Operators.exists("$unmuteAt")), "$unmuteAt", Operators.nowEpochSecond()))));
        Bson filter = Filters.and(Filters.eq("userId", userId), Filters.eq("guildId", guildId));
        return bot.getMongo().updateMute(filter, update, new UpdateOptions().upsert(true));
    }).thenCompose(result -> {
        Role role = atomicRole.get();
        boolean wasExtended = extend && result.getUpsertedId() == null;
        return guild.addRoleToMember(target, role).reason(ModUtility.getAuditReason(reason, moderator.getUser())).submit().thenApply($ -> {
            bot.getMuteManager().putMute(guild.getIdLong(), target.getIdLong(), role.getIdLong(), duration, wasExtended);
            ModActionEvent modEvent = wasExtended ? new MuteExtendEvent(moderator, target.getUser(), reason, duration) : new MuteEvent(moderator, target.getUser(), reason, duration);
            bot.getModActionManager().onModAction(modEvent);
            return new TimeAction(wasExtended ? ModAction.MUTE_EXTEND : ModAction.MUTE, duration);
        });
    });
}
Also used : Document(org.bson.Document) Operators(com.sx4.bot.database.mongo.model.Operators) BotPermissionException(com.sx4.bot.exceptions.mod.BotPermissionException) com.sx4.bot.entities.mod.action(com.sx4.bot.entities.mod.action) Permission(net.dv8tion.jda.api.Permission) MongoDatabase(com.sx4.bot.database.mongo.MongoDatabase) CompletableFuture(java.util.concurrent.CompletableFuture) MaxRolesException(com.sx4.bot.exceptions.mod.MaxRolesException) Member(net.dv8tion.jda.api.entities.Member) AuthorPermissionException(com.sx4.bot.exceptions.mod.AuthorPermissionException) BotHierarchyException(com.sx4.bot.exceptions.mod.BotHierarchyException) AtomicReference(java.util.concurrent.atomic.AtomicReference) User(net.dv8tion.jda.api.entities.User) Bson(org.bson.conversions.Bson) List(java.util.List) Guild(net.dv8tion.jda.api.entities.Guild) Sx4(com.sx4.bot.core.Sx4) Role(net.dv8tion.jda.api.entities.Role) Duration(java.time.Duration) Reason(com.sx4.bot.entities.mod.Reason) Clock(java.time.Clock) com.sx4.bot.events.mod(com.sx4.bot.events.mod) com.mongodb.client.model(com.mongodb.client.model) Collections(java.util.Collections) AtomicReference(java.util.concurrent.atomic.AtomicReference) Guild(net.dv8tion.jda.api.entities.Guild) Document(org.bson.Document) Bson(org.bson.conversions.Bson) Role(net.dv8tion.jda.api.entities.Role) BotPermissionException(com.sx4.bot.exceptions.mod.BotPermissionException) BotHierarchyException(com.sx4.bot.exceptions.mod.BotHierarchyException) List(java.util.List)

Example 13 with Sx4

use of com.sx4.bot.core.Sx4 in project Sx4 by sx4-discord-bot.

the class ModUtility method warn.

public static CompletableFuture<WarnAction> warn(Sx4 bot, Member target, Member moderator, Reason reason) {
    CompletableFuture<WarnAction> future = new CompletableFuture<>();
    Guild guild = target.getGuild();
    Document data = bot.getMongo().getGuildById(guild.getIdLong(), Projections.include("warn", "mute", "temporaryBan", "fakePermissions"));
    List<Document> fakePermissions = data.getEmbedded(List.of("fakePermissions", "holders"), Collections.emptyList());
    Document warnData = data.get("warn", MongoDatabase.EMPTY_DOCUMENT);
    List<Document> config = warnData.getList("config", Document.class, Warn.DEFAULT_CONFIG);
    boolean punishments = warnData.getBoolean("punishments", true);
    Document reset = warnData.get("reset", Document.class);
    int maxWarning = punishments ? config.stream().map(d -> d.getInteger("number")).max(Integer::compareTo).get() : Integer.MAX_VALUE;
    List<Bson> update = List.of(Operators.set("warnings", Operators.let(new Document("warnings", Operators.ifNull("$warnings", 0)), Operators.mod(Operators.cond(Operators.exists("$reset"), Operators.max(1, Operators.add(1, Operators.subtract("$$warnings", Operators.multiply(Operators.toInt(Operators.floor(Operators.divide(Operators.subtract(Operators.nowEpochSecond(), "$lastWarning"), "$reset.after"))), "$reset.amount")))), Operators.add("$$warnings", 1)), maxWarning))), Operators.set("lastWarning", Operators.nowEpochSecond()), reset == null ? Operators.unset("reset") : Operators.set("reset", reset));
    FindOneAndUpdateOptions options = new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER).projection(Projections.include("warnings")).upsert(true);
    Bson filter = Filters.and(Filters.eq("userId", target.getIdLong()), Filters.eq("guildId", guild.getIdLong()));
    bot.getMongo().findAndUpdateWarnings(filter, update, options).whenComplete((result, exception) -> {
        if (exception != null) {
            future.completeExceptionally(exception);
            return;
        }
        int warnings = result.getInteger("warnings");
        Action warnAction = new Action(ModAction.WARN);
        Action currentAction = warnAction, nextAction = warnAction;
        if (punishments) {
            for (Document configData : config) {
                int number = configData.getInteger("number");
                if (number == warnings) {
                    currentAction = Action.fromData(configData.get("action", Document.class));
                } else if (number == warnings + 1) {
                    nextAction = Action.fromData(configData.get("action", Document.class));
                }
            }
        }
        Action action = currentAction;
        Warn currentWarning = new Warn(action, warnings);
        Warn nextWarning = new Warn(nextAction, warnings + 1);
        switch(action.getModAction()) {
            case WARN:
                bot.getModActionManager().onModAction(new WarnEvent(moderator, target.getUser(), reason, currentWarning, nextWarning));
                future.complete(new WarnAction(currentWarning));
                break;
            case MUTE_EXTEND:
            case MUTE:
                if (!guild.getSelfMember().hasPermission(Permission.MANAGE_ROLES)) {
                    future.completeExceptionally(new BotPermissionException(Permission.MANAGE_ROLES));
                    return;
                }
                AtomicReference<Role> atomicRole = new AtomicReference<>();
                Document mute = data.get("mute", MongoDatabase.EMPTY_DOCUMENT);
                long muteDuration = ((TimeAction) action).getDuration();
                boolean extend = action.getModAction().isExtend();
                ModUtility.upsertMuteRole(bot.getMongo(), guild, mute.get("roleId", 0L), mute.get("autoUpdate", true)).thenCompose(role -> {
                    atomicRole.set(role);
                    List<Bson> muteUpdate = List.of(Operators.set("unmuteAt", Operators.add(muteDuration, Operators.cond(Operators.and(extend, Operators.exists("$unmuteAt")), "$unmuteAt", Operators.nowEpochSecond()))));
                    Bson muteFilter = Filters.and(Filters.eq("userId", target.getIdLong()), Filters.eq("guildId", guild.getIdLong()));
                    return bot.getMongo().updateMute(muteFilter, muteUpdate, new UpdateOptions().upsert(true));
                }).whenComplete((muteResult, muteException) -> {
                    if (muteException != null) {
                        future.completeExceptionally(muteException);
                        return;
                    }
                    Role role = atomicRole.get();
                    guild.addRoleToMember(target, role).reason(ModUtility.getAuditReason(reason, moderator.getUser())).queue($ -> {
                        bot.getMuteManager().putMute(guild.getIdLong(), target.getIdLong(), role.getIdLong(), muteDuration, extend && muteResult.getUpsertedId() == null);
                        bot.getModActionManager().onModAction(new WarnEvent(moderator, target.getUser(), reason, currentWarning, nextWarning));
                        future.complete(new WarnAction(currentWarning));
                    });
                });
                break;
            case KICK:
                if (!guild.getSelfMember().hasPermission(Permission.KICK_MEMBERS)) {
                    future.completeExceptionally(new BotPermissionException(Permission.KICK_MEMBERS));
                    return;
                }
                if (!guild.getSelfMember().canInteract(target)) {
                    future.completeExceptionally(new BotHierarchyException("kick"));
                    return;
                }
                if (!CheckUtility.hasPermissions(bot, moderator, fakePermissions, Permission.KICK_MEMBERS)) {
                    future.completeExceptionally(new AuthorPermissionException(Permission.KICK_MEMBERS));
                    return;
                }
                target.kick(ModUtility.getAuditReason(reason, moderator.getUser())).queue($ -> {
                    bot.getModActionManager().onModAction(new WarnEvent(moderator, target.getUser(), reason, currentWarning, nextWarning));
                    future.complete(new WarnAction(currentWarning));
                });
                break;
            case TEMPORARY_BAN:
                if (!guild.getSelfMember().hasPermission(Permission.BAN_MEMBERS)) {
                    future.completeExceptionally(new BotPermissionException(Permission.BAN_MEMBERS));
                    return;
                }
                if (!guild.getSelfMember().canInteract(target)) {
                    future.completeExceptionally(new BotHierarchyException("ban"));
                    return;
                }
                if (!CheckUtility.hasPermissions(bot, moderator, fakePermissions, Permission.BAN_MEMBERS)) {
                    future.completeExceptionally(new AuthorPermissionException(Permission.BAN_MEMBERS));
                    return;
                }
                long temporaryBanDuration = ((TimeAction) action).getDuration();
                Bson temporaryBanUpdate = Updates.set("unbanAt", Clock.systemUTC().instant().getEpochSecond() + temporaryBanDuration);
                Bson temporaryBanFilter = Filters.and(Filters.eq("userId", target.getIdLong()), Filters.eq("guildId", guild.getIdLong()));
                bot.getMongo().updateTemporaryBan(temporaryBanFilter, temporaryBanUpdate, new UpdateOptions().upsert(true)).whenComplete((temporaryBanResult, temporaryBanException) -> {
                    if (temporaryBanException != null) {
                        future.completeExceptionally(temporaryBanException);
                        return;
                    }
                    target.ban(1).reason(ModUtility.getAuditReason(reason, moderator.getUser())).queue($ -> {
                        bot.getModActionManager().onModAction(new WarnEvent(moderator, target.getUser(), reason, currentWarning, nextWarning));
                        bot.getTemporaryBanManager().putBan(guild.getIdLong(), target.getIdLong(), ((TimeAction) action).getDuration());
                        future.complete(new WarnAction(currentWarning));
                    });
                });
                break;
            case BAN:
                if (!guild.getSelfMember().hasPermission(Permission.BAN_MEMBERS)) {
                    future.completeExceptionally(new BotPermissionException(Permission.BAN_MEMBERS));
                    return;
                }
                if (!guild.getSelfMember().canInteract(target)) {
                    future.completeExceptionally(new BotHierarchyException("ban"));
                    return;
                }
                if (!CheckUtility.hasPermissions(bot, moderator, fakePermissions, Permission.BAN_MEMBERS)) {
                    future.completeExceptionally(new AuthorPermissionException(Permission.BAN_MEMBERS));
                    return;
                }
                target.ban(1).reason(ModUtility.getAuditReason(reason, moderator.getUser())).queue($ -> {
                    bot.getModActionManager().onModAction(new WarnEvent(moderator, target.getUser(), reason, currentWarning, nextWarning));
                    future.complete(new WarnAction(currentWarning));
                });
                break;
            default:
                break;
        }
    });
    return future;
}
Also used : Document(org.bson.Document) Operators(com.sx4.bot.database.mongo.model.Operators) BotPermissionException(com.sx4.bot.exceptions.mod.BotPermissionException) com.sx4.bot.entities.mod.action(com.sx4.bot.entities.mod.action) Permission(net.dv8tion.jda.api.Permission) MongoDatabase(com.sx4.bot.database.mongo.MongoDatabase) CompletableFuture(java.util.concurrent.CompletableFuture) MaxRolesException(com.sx4.bot.exceptions.mod.MaxRolesException) Member(net.dv8tion.jda.api.entities.Member) AuthorPermissionException(com.sx4.bot.exceptions.mod.AuthorPermissionException) BotHierarchyException(com.sx4.bot.exceptions.mod.BotHierarchyException) AtomicReference(java.util.concurrent.atomic.AtomicReference) User(net.dv8tion.jda.api.entities.User) Bson(org.bson.conversions.Bson) List(java.util.List) Guild(net.dv8tion.jda.api.entities.Guild) Sx4(com.sx4.bot.core.Sx4) Role(net.dv8tion.jda.api.entities.Role) Duration(java.time.Duration) Reason(com.sx4.bot.entities.mod.Reason) Clock(java.time.Clock) com.sx4.bot.events.mod(com.sx4.bot.events.mod) com.mongodb.client.model(com.mongodb.client.model) Collections(java.util.Collections) Guild(net.dv8tion.jda.api.entities.Guild) Document(org.bson.Document) Bson(org.bson.conversions.Bson) CompletableFuture(java.util.concurrent.CompletableFuture) BotPermissionException(com.sx4.bot.exceptions.mod.BotPermissionException) List(java.util.List) BotHierarchyException(com.sx4.bot.exceptions.mod.BotHierarchyException) AuthorPermissionException(com.sx4.bot.exceptions.mod.AuthorPermissionException) AtomicReference(java.util.concurrent.atomic.AtomicReference) Role(net.dv8tion.jda.api.entities.Role)

Example 14 with Sx4

use of com.sx4.bot.core.Sx4 in project Sx4 by sx4-discord-bot.

the class SuggestionManager method sendSuggestion.

public CompletableFuture<ReadonlyMessage> sendSuggestion(BaseGuildMessageChannel channel, Document webhookData, boolean premium, WebhookEmbed embed) {
    User selfUser = channel.getJDA().getSelfUser();
    WebhookMessage message = new WebhookMessageBuilder().setAvatarUrl(webhookData.get("avatar", selfUser.getEffectiveAvatarUrl())).setUsername(webhookData.get("name", "Sx4 - Suggestions")).addEmbeds(embed).build();
    WebhookClient webhook;
    if (this.webhooks.containsKey(channel.getIdLong())) {
        webhook = this.webhooks.get(channel.getIdLong());
    } else if (!webhookData.containsKey("id")) {
        return this.createWebhook(channel, message);
    } else {
        webhook = new WebhookClient(webhookData.getLong("id"), webhookData.getString("token"), this.executor, this.client);
        this.webhooks.put(channel.getIdLong(), webhook);
    }
    return webhook.send(message).thenApply(webhookMessage -> new ReadonlyMessage(webhookMessage, webhook.getId(), webhook.getToken())).exceptionallyCompose(exception -> {
        Throwable cause = exception instanceof CompletionException ? exception.getCause() : exception;
        if (cause instanceof HttpException && ((HttpException) cause).getCode() == 404) {
            this.webhooks.remove(channel.getIdLong());
            return this.createWebhook(channel, message);
        }
        return CompletableFuture.failedFuture(exception);
    });
}
Also used : WebhookMessage(club.minnced.discord.webhook.send.WebhookMessage) WebhookMessageBuilder(club.minnced.discord.webhook.send.WebhookMessageBuilder) Document(org.bson.Document) net.dv8tion.jda.api.entities(net.dv8tion.jda.api.entities) BotPermissionException(com.sx4.bot.exceptions.mod.BotPermissionException) Permission(net.dv8tion.jda.api.Permission) MongoDatabase(com.sx4.bot.database.mongo.MongoDatabase) Updates(com.mongodb.client.model.Updates) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) CompletionException(java.util.concurrent.CompletionException) Executors(java.util.concurrent.Executors) HttpException(club.minnced.discord.webhook.exception.HttpException) WebhookClient(com.sx4.bot.entities.webhook.WebhookClient) Bson(org.bson.conversions.Bson) OkHttpClient(okhttp3.OkHttpClient) Sx4(com.sx4.bot.core.Sx4) WebhookEmbed(club.minnced.discord.webhook.send.WebhookEmbed) Map(java.util.Map) WebhookMessage(club.minnced.discord.webhook.send.WebhookMessage) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) ReadonlyMessage(com.sx4.bot.entities.webhook.ReadonlyMessage) WebhookClient(com.sx4.bot.entities.webhook.WebhookClient) WebhookMessageBuilder(club.minnced.discord.webhook.send.WebhookMessageBuilder) CompletionException(java.util.concurrent.CompletionException) HttpException(club.minnced.discord.webhook.exception.HttpException) ReadonlyMessage(com.sx4.bot.entities.webhook.ReadonlyMessage)

Example 15 with Sx4

use of com.sx4.bot.core.Sx4 in project Sx4 by sx4-discord-bot.

the class FreeGameManager method sendFreeGameNotifications.

public CompletableFuture<List<ReadonlyMessage>> sendFreeGameNotifications(List<? extends FreeGame<?>> games) {
    if (games.isEmpty()) {
        return CompletableFuture.completedFuture(Collections.emptyList());
    }
    games.forEach(this::addAnnouncedGame);
    List<Document> gameData = games.stream().map(FreeGame::toData).collect(Collectors.toList());
    this.bot.getMongo().insertManyAnnouncedGames(gameData).whenComplete(MongoDatabase.exceptionally());
    List<Bson> guildPipeline = List.of(Aggregates.match(Operators.expr(Operators.eq("$_id", "$$guildId"))), Aggregates.project(Projections.computed("premium", Operators.lt(Operators.nowEpochSecond(), Operators.ifNull("$premium.endAt", 0L)))));
    List<Bson> pipeline = List.of(Aggregates.lookup("guilds", List.of(new Variable<>("guildId", "$guildId")), guildPipeline, "premium"), Aggregates.addFields(new Field<>("premium", Operators.cond(Operators.isEmpty("$premium"), false, Operators.get(Operators.arrayElemAt("$premium", 0), "premium")))));
    return this.bot.getMongo().aggregateFreeGameChannels(pipeline).thenComposeAsync(documents -> {
        List<WriteModel<Document>> bulkData = new ArrayList<>();
        List<CompletableFuture<List<ReadonlyMessage>>> futures = new ArrayList<>();
        for (Document data : documents) {
            if (!data.getBoolean("enabled", true)) {
                continue;
            }
            BaseGuildMessageChannel channel = this.bot.getShardManager().getChannelById(BaseGuildMessageChannel.class, data.getLong("channelId"));
            if (channel == null) {
                continue;
            }
            String avatar = channel.getJDA().getSelfUser().getEffectiveAvatarUrl();
            boolean premium = data.getBoolean("premium");
            Document webhookData = data.get("webhook", MongoDatabase.EMPTY_DOCUMENT);
            long platforms = data.get("platforms", FreeGameType.ALL);
            List<WebhookMessage> messages = new ArrayList<>();
            for (FreeGame<?> game : games) {
                long raw = game.getType().getRaw();
                if ((platforms & raw) != raw) {
                    continue;
                }
                Formatter<Document> formatter = new JsonFormatter(data.get("message", FreeGameManager.DEFAULT_MESSAGE)).addVariable("game", game);
                WebhookMessage message;
                try {
                    message = MessageUtility.fromJson(formatter.parse()).setAvatarUrl(premium ? webhookData.get("avatar", avatar) : avatar).setUsername(premium ? webhookData.get("name", "Sx4 - Free Games") : "Sx4 - Free Games").build();
                } catch (IllegalArgumentException e) {
                    bulkData.add(new UpdateOneModel<>(Filters.eq("_id", data.getObjectId("_id")), Updates.unset("message")));
                    continue;
                }
                messages.add(message);
            }
            if (messages.isEmpty()) {
                continue;
            }
            WebhookMessage firstMessage = messages.get(0);
            String firstContent = firstMessage.getContent();
            if (messages.size() == 1 || !messages.stream().skip(1).allMatch(message -> message.getContent().equals(firstContent))) {
                futures.add(this.sendFreeGameNotificationMessages(channel, webhookData, messages));
                continue;
            }
            List<WebhookMessage> updatedMessages = new ArrayList<>();
            WebhookMessageBuilder baseMessage = new WebhookMessageBuilder().setContent(firstContent).setAvatarUrl(firstMessage.getAvatarUrl()).setUsername(firstMessage.getUsername());
            int length = 0;
            List<WebhookEmbed> embeds = new ArrayList<>();
            for (WebhookMessage message : messages) {
                List<WebhookEmbed> nextEmbeds = message.getEmbeds();
                int nextLength = MessageUtility.getWebhookEmbedLength(nextEmbeds);
                if (embeds.size() + nextEmbeds.size() > WebhookMessage.MAX_EMBEDS || length + nextLength > MessageEmbed.EMBED_MAX_LENGTH_BOT) {
                    baseMessage.addEmbeds(embeds);
                    updatedMessages.add(baseMessage.build());
                    baseMessage.resetEmbeds();
                    embeds.clear();
                    embeds.addAll(nextEmbeds);
                    length = nextLength;
                    continue;
                }
                embeds.addAll(nextEmbeds);
                length += nextLength;
            }
            baseMessage.addEmbeds(embeds);
            updatedMessages.add(baseMessage.build());
            futures.add(this.sendFreeGameNotificationMessages(channel, webhookData, updatedMessages));
        }
        if (!bulkData.isEmpty()) {
            this.bot.getMongo().bulkWriteFreeGameChannels(bulkData).whenComplete(MongoDatabase.exceptionally());
        }
        return FutureUtility.allOf(futures).thenApply(list -> list.stream().flatMap(List::stream).collect(Collectors.toList()));
    });
}
Also used : WebhookMessageBuilder(club.minnced.discord.webhook.send.WebhookMessageBuilder) Document(org.bson.Document) Bson(org.bson.conversions.Bson) WebhookEmbed(club.minnced.discord.webhook.send.WebhookEmbed) BaseGuildMessageChannel(net.dv8tion.jda.api.entities.BaseGuildMessageChannel) WebhookMessage(club.minnced.discord.webhook.send.WebhookMessage) JsonFormatter(com.sx4.bot.formatter.JsonFormatter) ReadonlyMessage(com.sx4.bot.entities.webhook.ReadonlyMessage)

Aggregations

Document (org.bson.Document)28 Sx4Command (com.sx4.bot.core.Sx4Command)24 Command (com.jockie.bot.core.command.Command)23 Bson (org.bson.conversions.Bson)21 Permission (net.dv8tion.jda.api.Permission)19 CompletableFuture (java.util.concurrent.CompletableFuture)16 com.mongodb.client.model (com.mongodb.client.model)14 MongoDatabase (com.sx4.bot.database.mongo.MongoDatabase)14 Operators (com.sx4.bot.database.mongo.model.Operators)14 CompletionException (java.util.concurrent.CompletionException)13 EmbedBuilder (net.dv8tion.jda.api.EmbedBuilder)13 Argument (com.jockie.bot.core.argument.Argument)12 ModuleCategory (com.sx4.bot.category.ModuleCategory)12 Sx4 (com.sx4.bot.core.Sx4)12 Sx4CommandEvent (com.sx4.bot.core.Sx4CommandEvent)12 ExceptionUtility (com.sx4.bot.utility.ExceptionUtility)12 BaseGuildMessageChannel (net.dv8tion.jda.api.entities.BaseGuildMessageChannel)12 CommandId (com.sx4.bot.annotations.command.CommandId)11 Examples (com.sx4.bot.annotations.command.Examples)10 User (net.dv8tion.jda.api.entities.User)10