Search in sources :

Example 6 with Waiter

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

the class MarriageCommand method remove.

@Command(value = "remove", description = "Divorce someone you are currently married to")
@CommandId(269)
@Redirects({ "divorce" })
@Examples({ "marriage remove @Shea#6653", "marriage remove Shea", "marriage remove all" })
public void remove(Sx4CommandEvent event, @Argument(value = "user | all", endless = true, nullDefault = true) @AlternativeOptions("all") Alternative<Member> option) {
    User author = event.getAuthor();
    if (option == null) {
        Bson filter = Filters.or(Filters.eq("proposerId", author.getIdLong()), Filters.eq("partnerId", author.getIdLong()));
        List<Document> marriages = event.getMongo().getMarriages(filter, Projections.include("proposerId", "partnerId")).into(new ArrayList<>());
        if (marriages.isEmpty()) {
            event.replyFailure("You are not married to anyone").queue();
            return;
        }
        List<Long> userIds = marriages.stream().map(marriage -> {
            long partnerId = marriage.getLong("partnerId");
            return partnerId == author.getIdLong() ? marriage.getLong("proposerId") : partnerId;
        }).collect(Collectors.toList());
        PagedResult<Long> paged = new PagedResult<>(event.getBot(), userIds).setAuthor("Divorce", null, author.getEffectiveAvatarUrl()).setTimeout(60).setDisplayFunction(userId -> {
            User other = event.getShardManager().getUserById(userId);
            return (other == null ? "Anonymous#0000" : other.getAsTag()) + " (" + userId + ")";
        });
        paged.onTimeout(() -> event.reply("Timed out :stopwatch:").queue());
        paged.onSelect(select -> {
            long userId = select.getSelected();
            Bson deleteFilter = Filters.or(Filters.and(Filters.eq("proposerId", userId), Filters.eq("partnerId", author.getIdLong())), Filters.and(Filters.eq("proposerId", author.getIdLong()), Filters.eq("partnerId", userId)));
            event.getMongo().deleteMarriage(deleteFilter).whenComplete((result, exception) -> {
                if (ExceptionUtility.sendExceptionally(event, exception)) {
                    return;
                }
                User user = event.getShardManager().getUserById(userId);
                event.replySuccess("You are no longer married to **" + (user == null ? "Anonymous#0000" : user.getAsTag()) + "**").queue();
            });
        });
        paged.execute(event);
    } else if (option.isAlternative()) {
        List<Button> buttons = List.of(Button.success("yes", "Yes"), Button.danger("no", "No"));
        event.reply(author.getName() + ", are you sure you want to divorce everyone you are currently married to?").setActionRow(buttons).submit().thenCompose(message -> {
            return new Waiter<>(event.getBot(), ButtonClickEvent.class).setPredicate(e -> ButtonUtility.handleButtonConfirmation(e, message, event.getAuthor())).setCancelPredicate(e -> ButtonUtility.handleButtonCancellation(e, message, event.getAuthor())).onFailure(e -> ButtonUtility.handleButtonFailure(e, message)).setTimeout(60).start();
        }).whenComplete((e, exception) -> {
            Throwable cause = exception instanceof CompletionException ? exception.getCause() : exception;
            if (cause instanceof CancelException) {
                GenericEvent cancelEvent = ((CancelException) cause).getEvent();
                if (cancelEvent != null) {
                    ((ButtonClickEvent) cancelEvent).reply("Cancelled " + event.getConfig().getSuccessEmote()).queue();
                }
                return;
            } else if (cause instanceof TimeoutException) {
                event.reply("Timed out :stopwatch:").queue();
                return;
            } else if (ExceptionUtility.sendExceptionally(event, exception)) {
                return;
            }
            Bson filter = Filters.or(Filters.eq("proposerId", author.getIdLong()), Filters.eq("partnerId", author.getIdLong()));
            event.getMongo().deleteManyMarriages(filter).whenComplete((result, databaseException) -> {
                if (ExceptionUtility.sendExceptionally(event, databaseException)) {
                    return;
                }
                if (result.getDeletedCount() == 0) {
                    e.reply("You are not married to anyone " + event.getConfig().getFailureEmote()).queue();
                    return;
                }
                e.reply("You are no longer married to anyone " + event.getConfig().getSuccessEmote()).queue();
            });
        });
    } else {
        Member member = option.getValue();
        Bson filter = Filters.or(Filters.and(Filters.eq("proposerId", member.getIdLong()), Filters.eq("partnerId", author.getIdLong())), Filters.and(Filters.eq("proposerId", author.getIdLong()), Filters.eq("partnerId", member.getIdLong())));
        event.getMongo().deleteMarriage(filter).whenComplete((result, exception) -> {
            if (ExceptionUtility.sendExceptionally(event, exception)) {
                return;
            }
            if (result.getDeletedCount() == 0) {
                event.replyFailure("You are not married to that user").queue();
                return;
            }
            event.replySuccess("You are no longer married to **" + member.getUser().getAsTag() + "**").queue();
        });
    }
}
Also used : Document(org.bson.Document) CancelException(com.sx4.bot.waiter.exception.CancelException) Command(com.jockie.bot.core.command.Command) ButtonClickEvent(net.dv8tion.jda.api.events.interaction.ButtonClickEvent) Projections(com.mongodb.client.model.Projections) Cooldown(com.jockie.bot.core.command.Command.Cooldown) CommandId(com.sx4.bot.annotations.command.CommandId) Member(net.dv8tion.jda.api.entities.Member) PagedResult(com.sx4.bot.paged.PagedResult) User(net.dv8tion.jda.api.entities.User) ArrayList(java.util.ArrayList) Filters(com.mongodb.client.model.Filters) Bson(org.bson.conversions.Bson) Redirects(com.sx4.bot.annotations.command.Redirects) Alternative(com.sx4.bot.entities.argument.Alternative) ButtonUtility(com.sx4.bot.utility.ButtonUtility) Sx4CommandEvent(com.sx4.bot.core.Sx4CommandEvent) Button(net.dv8tion.jda.api.interactions.components.Button) AlternativeOptions(com.sx4.bot.annotations.argument.AlternativeOptions) Waiter(com.sx4.bot.waiter.Waiter) GenericEvent(net.dv8tion.jda.api.events.GenericEvent) ZoneOffset(java.time.ZoneOffset) EnumSet(java.util.EnumSet) Argument(com.jockie.bot.core.argument.Argument) Message(net.dv8tion.jda.api.entities.Message) Sx4Command(com.sx4.bot.core.Sx4Command) Updates(com.mongodb.client.model.Updates) CooldownMessage(com.sx4.bot.annotations.command.CooldownMessage) CompletionException(java.util.concurrent.CompletionException) TimeoutException(com.sx4.bot.waiter.exception.TimeoutException) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) ModuleCategory(com.sx4.bot.category.ModuleCategory) List(java.util.List) Examples(com.sx4.bot.annotations.command.Examples) OffsetDateTime(java.time.OffsetDateTime) Sorts(com.mongodb.client.model.Sorts) DateTimeFormatter(java.time.format.DateTimeFormatter) StringJoiner(java.util.StringJoiner) ExceptionUtility(com.sx4.bot.utility.ExceptionUtility) User(net.dv8tion.jda.api.entities.User) ButtonClickEvent(net.dv8tion.jda.api.events.interaction.ButtonClickEvent) Document(org.bson.Document) Bson(org.bson.conversions.Bson) GenericEvent(net.dv8tion.jda.api.events.GenericEvent) CompletionException(java.util.concurrent.CompletionException) ArrayList(java.util.ArrayList) List(java.util.List) CancelException(com.sx4.bot.waiter.exception.CancelException) Member(net.dv8tion.jda.api.entities.Member) TimeoutException(com.sx4.bot.waiter.exception.TimeoutException) Redirects(com.sx4.bot.annotations.command.Redirects) Command(com.jockie.bot.core.command.Command) Sx4Command(com.sx4.bot.core.Sx4Command) CommandId(com.sx4.bot.annotations.command.CommandId) Examples(com.sx4.bot.annotations.command.Examples)

Example 7 with Waiter

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

the class MarriageCommand method add.

@Command(value = "add", description = "Propose to a user and marry them if they accept")
@CommandId(268)
@Redirects({ "marry" })
@Cooldown(60)
@CooldownMessage("You already have a pending marriage :no_entry:")
@Examples({ "marriage add @Shea#6653", "marriage add Shea", "marriage add 402557516728369153" })
public void add(Sx4CommandEvent event, @Argument(value = "user", endless = true) Member member) {
    User author = event.getAuthor();
    if (member.getUser().isBot()) {
        event.replyFailure("You cannot marry bots").queue();
        return;
    }
    Bson checkFilter = Filters.or(Filters.eq("proposerId", author.getIdLong()), Filters.eq("partnerId", author.getIdLong()), Filters.eq("proposerId", member.getIdLong()), Filters.eq("partnerId", member.getIdLong()));
    List<Document> marriages = event.getMongo().getMarriages(checkFilter, Projections.include("partnerId", "proposerId")).into(new ArrayList<>());
    long userCount = marriages.stream().filter(d -> d.getLong("proposerId") == author.getIdLong() || d.getLong("partnerId") == author.getIdLong()).count();
    if (userCount >= 5) {
        event.removeCooldown();
        event.replyFailure("You cannot marry more than 5 users").queue();
        return;
    }
    long memberCount = marriages.stream().filter(d -> d.getLong("proposerId") == member.getIdLong() || d.getLong("partnerId") == member.getIdLong()).count();
    if (memberCount >= 5) {
        event.removeCooldown();
        event.replyFailure("That user is already married to 5 users").queue();
        return;
    }
    List<Button> buttons = List.of(Button.success("yes", "Yes"), Button.danger("no", "No"));
    event.reply(member.getAsMention() + ", **" + author.getName() + "** would like to marry you! Do you accept?").allowedMentions(EnumSet.of(Message.MentionType.USER)).setActionRow(buttons).submit().thenCompose(message -> {
        return new Waiter<>(event.getBot(), ButtonClickEvent.class).setPredicate(e -> ButtonUtility.handleButtonConfirmation(e, message, member.getUser())).setCancelPredicate(e -> ButtonUtility.handleButtonCancellation(e, message, member.getUser())).onFailure(e -> ButtonUtility.handleButtonFailure(e, message)).setTimeout(60).start();
    }).whenComplete((e, exception) -> {
        event.removeCooldown();
        Throwable cause = exception instanceof CompletionException ? exception.getCause() : exception;
        if (cause instanceof CancelException) {
            GenericEvent cancelEvent = ((CancelException) cause).getEvent();
            if (cancelEvent != null) {
                ((ButtonClickEvent) cancelEvent).reply("Better luck next time " + author.getName() + " :broken_heart:").queue();
            }
            return;
        } else if (cause instanceof TimeoutException) {
            event.reply("Timed out :stopwatch:").queue();
            return;
        } else if (ExceptionUtility.sendExceptionally(event, exception)) {
            return;
        }
        Bson filter = Filters.or(Filters.and(Filters.eq("proposerId", member.getIdLong()), Filters.eq("partnerId", author.getIdLong())), Filters.and(Filters.eq("proposerId", author.getIdLong()), Filters.eq("partnerId", member.getIdLong())));
        event.getMongo().updateMarriage(filter, Updates.combine(Updates.setOnInsert("proposerId", author.getIdLong()), Updates.setOnInsert("partnerId", member.getIdLong()))).whenComplete((result, databaseException) -> {
            if (ExceptionUtility.sendExceptionally(event, databaseException)) {
                return;
            }
            if (result.getMatchedCount() != 0) {
                e.reply("You're already married to that user " + event.getConfig().getFailureEmote()).queue();
                return;
            }
            e.reply("You're now married to " + member.getAsMention() + " :tada: :heart:").queue();
        });
    });
}
Also used : Document(org.bson.Document) CancelException(com.sx4.bot.waiter.exception.CancelException) Command(com.jockie.bot.core.command.Command) ButtonClickEvent(net.dv8tion.jda.api.events.interaction.ButtonClickEvent) Projections(com.mongodb.client.model.Projections) Cooldown(com.jockie.bot.core.command.Command.Cooldown) CommandId(com.sx4.bot.annotations.command.CommandId) Member(net.dv8tion.jda.api.entities.Member) PagedResult(com.sx4.bot.paged.PagedResult) User(net.dv8tion.jda.api.entities.User) ArrayList(java.util.ArrayList) Filters(com.mongodb.client.model.Filters) Bson(org.bson.conversions.Bson) Redirects(com.sx4.bot.annotations.command.Redirects) Alternative(com.sx4.bot.entities.argument.Alternative) ButtonUtility(com.sx4.bot.utility.ButtonUtility) Sx4CommandEvent(com.sx4.bot.core.Sx4CommandEvent) Button(net.dv8tion.jda.api.interactions.components.Button) AlternativeOptions(com.sx4.bot.annotations.argument.AlternativeOptions) Waiter(com.sx4.bot.waiter.Waiter) GenericEvent(net.dv8tion.jda.api.events.GenericEvent) ZoneOffset(java.time.ZoneOffset) EnumSet(java.util.EnumSet) Argument(com.jockie.bot.core.argument.Argument) Message(net.dv8tion.jda.api.entities.Message) Sx4Command(com.sx4.bot.core.Sx4Command) Updates(com.mongodb.client.model.Updates) CooldownMessage(com.sx4.bot.annotations.command.CooldownMessage) CompletionException(java.util.concurrent.CompletionException) TimeoutException(com.sx4.bot.waiter.exception.TimeoutException) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) ModuleCategory(com.sx4.bot.category.ModuleCategory) List(java.util.List) Examples(com.sx4.bot.annotations.command.Examples) OffsetDateTime(java.time.OffsetDateTime) Sorts(com.mongodb.client.model.Sorts) DateTimeFormatter(java.time.format.DateTimeFormatter) StringJoiner(java.util.StringJoiner) ExceptionUtility(com.sx4.bot.utility.ExceptionUtility) User(net.dv8tion.jda.api.entities.User) Document(org.bson.Document) Bson(org.bson.conversions.Bson) Button(net.dv8tion.jda.api.interactions.components.Button) GenericEvent(net.dv8tion.jda.api.events.GenericEvent) CompletionException(java.util.concurrent.CompletionException) CancelException(com.sx4.bot.waiter.exception.CancelException) Waiter(com.sx4.bot.waiter.Waiter) TimeoutException(com.sx4.bot.waiter.exception.TimeoutException) Redirects(com.sx4.bot.annotations.command.Redirects) Command(com.jockie.bot.core.command.Command) Sx4Command(com.sx4.bot.core.Sx4Command) Cooldown(com.jockie.bot.core.command.Command.Cooldown) CooldownMessage(com.sx4.bot.annotations.command.CooldownMessage) CommandId(com.sx4.bot.annotations.command.CommandId) Examples(com.sx4.bot.annotations.command.Examples)

Example 8 with Waiter

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

the class GuessTheNumberCommand method onCommand.

public void onCommand(Sx4CommandEvent event, @Argument(value = "user", endless = true) Member member, @Option(value = "min", description = "Choose the minimum number of the range") @Limit(min = 1) @DefaultNumber(1) int min, @Option(value = "max", description = "Choose the maximum number of the range") @Limit(min = 2) @DefaultNumber(50) int max) {
    User opponent = member.getUser();
    if (opponent.isBot()) {
        event.replyFailure("You cannot play against bots").queue();
        return;
    }
    if (opponent.getIdLong() == event.getAuthor().getIdLong()) {
        event.replyFailure("You cannot play against yourself").queue();
        return;
    }
    List<Button> buttons = List.of(Button.success("yes", "Yes"), Button.danger("no", "No"));
    event.reply(opponent.getAsMention() + ", do you want to play guess the number with **" + event.getAuthor().getName() + "**?").allowedMentions(EnumSet.of(Message.MentionType.USER)).setActionRow(buttons).submit().thenCompose(message -> {
        return new Waiter<>(event.getBot(), ButtonClickEvent.class).setPredicate(e -> ButtonUtility.handleButtonConfirmation(e, message, opponent)).setCancelPredicate(e -> ButtonUtility.handleButtonCancellation(e, message, opponent)).onFailure(e -> ButtonUtility.handleButtonFailure(e, message)).setTimeout(60).start();
    }).whenComplete((confirmEvent, confirmException) -> {
        Throwable confirmCause = confirmException instanceof CompletionException ? confirmException.getCause() : confirmException;
        if (confirmCause instanceof CancelException) {
            GenericEvent cancelEvent = ((CancelException) confirmCause).getEvent();
            if (cancelEvent != null) {
                ((ButtonClickEvent) cancelEvent).reply("Cancelled " + event.getConfig().getSuccessEmote()).queue();
            }
            return;
        } else if (confirmCause instanceof TimeoutException) {
            event.reply("Timed out :stopwatch:").queue();
            return;
        }
        confirmEvent.deferEdit().queue();
        CompletableFuture<MessageReceivedEvent> authorFuture = event.getAuthor().openPrivateChannel().submit().thenCompose(channel -> channel.sendMessage("Send a number between **" + min + "** and **" + max + "** or `cancel` to cancel").submit()).thenCompose(message -> {
            return new Waiter<>(event.getBot(), MessageReceivedEvent.class).setUnique(event.getAuthor().getIdLong(), message.getChannel().getIdLong()).setTimeout(30).setCancelPredicate(e -> e.getMessage().getContentRaw().equalsIgnoreCase("cancel")).setPredicate(e -> {
                int number;
                try {
                    number = Integer.parseInt(e.getMessage().getContentRaw());
                } catch (NumberFormatException exception) {
                    return false;
                }
                return number >= min && number <= max;
            }).start();
        });
        CompletableFuture<MessageReceivedEvent> opponentFuture = opponent.openPrivateChannel().submit().thenCompose(channel -> channel.sendMessage("Send a number between **" + min + "** and **" + max + "** or `cancel` to cancel").submit()).thenCompose(message -> {
            return new Waiter<>(event.getBot(), MessageReceivedEvent.class).setUnique(opponent.getIdLong(), message.getChannel().getIdLong()).setTimeout(30).setCancelPredicate(e -> e.getMessage().getContentRaw().equalsIgnoreCase("cancel")).setPredicate(e -> {
                int number;
                try {
                    number = Integer.parseInt(e.getMessage().getContentRaw());
                } catch (NumberFormatException exception) {
                    return false;
                }
                return number >= min && number <= max;
            }).start();
        });
        authorFuture.whenComplete((messageEvent, exception) -> {
            Throwable cause = exception instanceof CompletionException ? exception.getCause() : exception;
            if (cause instanceof CancelException) {
                opponentFuture.cancel(true);
                if (((CancelException) cause).getType() == CancelType.USER) {
                    event.getAuthor().openPrivateChannel().flatMap(channel -> channel.sendMessage("Cancelled " + event.getConfig().getSuccessEmote())).queue();
                }
                event.replyFailure("**" + event.getAuthor().getAsTag() + "** cancelled their response").queue();
                return;
            } else if (cause instanceof TimeoutException) {
                opponentFuture.cancel(true);
                event.replyFailure("**" + event.getAuthor().getAsTag() + "** took too long to respond").queue();
                return;
            } else if (cause instanceof ErrorResponseException) {
                opponentFuture.cancel(true);
                event.replyFailure("I could not send a message to **" + event.getAuthor().getAsTag() + "**").queue();
                return;
            }
            messageEvent.getChannel().sendMessage("Your number has been received, results will be sent in " + event.getTextChannel().getAsMention()).queue();
        });
        opponentFuture.whenComplete((messageEvent, exception) -> {
            Throwable cause = exception instanceof CompletionException ? exception.getCause() : exception;
            if (cause instanceof CancelException) {
                authorFuture.cancel(true);
                if (((CancelException) cause).getType() == CancelType.USER) {
                    opponent.openPrivateChannel().flatMap(channel -> channel.sendMessage("Cancelled " + event.getConfig().getSuccessEmote())).queue();
                }
                event.replyFailure("**" + opponent.getAsTag() + "** cancelled their response").queue();
                return;
            } else if (cause instanceof TimeoutException) {
                authorFuture.cancel(true);
                event.replyFailure("**" + opponent.getAsTag() + "** took too long to respond").queue();
                return;
            } else if (cause instanceof ErrorResponseException) {
                authorFuture.cancel(true);
                event.replyFailure("I could not send a message to **" + opponent.getAsTag() + "**").queue();
                return;
            }
            messageEvent.getChannel().sendMessage("Your number has been received, results will be sent in " + event.getTextChannel().getAsMention()).queue();
        });
        CompletableFuture.allOf(authorFuture, opponentFuture).whenComplete((result, exception) -> {
            if (exception != null) {
                return;
            }
            MessageReceivedEvent authorEvent = authorFuture.join(), opponentEvent = opponentFuture.join();
            ObjectId gameId = ObjectId.get();
            int authorNumber = Integer.parseInt(authorEvent.getMessage().getContentRaw());
            int opponentNumber = Integer.parseInt(opponentEvent.getMessage().getContentRaw());
            int randomNumber = event.getRandom().nextInt(max) + 1;
            Document authorData = new Document("userId", event.getAuthor().getIdLong()).append("gameId", gameId).append("type", GameType.GUESS_THE_NUMBER.getId()).append("choice", authorNumber).append("answer", randomNumber);
            Document opponentData = new Document("userId", opponent.getIdLong()).append("gameId", gameId).append("type", GameType.GUESS_THE_NUMBER.getId()).append("choice", authorNumber).append("answer", randomNumber);
            int authorDifference = Math.abs(authorNumber - randomNumber), opponentDifference = Math.abs(opponentNumber - randomNumber);
            StringBuilder content = new StringBuilder("The random number was **" + randomNumber + "**\n" + opponent.getName() + "'s number was **" + opponentNumber + "**\n" + event.getAuthor().getName() + "'s number was **" + authorNumber + "**\n\n");
            if (authorDifference == opponentDifference) {
                content.append("You both guessed the same number, It was a draw!");
                authorData.append("state", GameState.DRAW.getId());
                opponentData.append("state", GameState.DRAW.getId());
            } else if (authorDifference > opponentDifference) {
                content.append(opponent.getName()).append(" won! They were the closest to ").append(randomNumber);
                authorData.append("state", GameState.LOSS.getId());
                opponentData.append("state", GameState.WIN.getId());
            } else {
                content.append(event.getAuthor().getName()).append(" won! They were the closest to ").append(randomNumber);
                authorData.append("state", GameState.WIN.getId());
                opponentData.append("state", GameState.LOSS.getId());
            }
            event.reply(content.toString()).queue();
            event.getMongo().insertManyGames(List.of(authorData, opponentData)).whenComplete(MongoDatabase.exceptionally());
        });
    });
}
Also used : Document(org.bson.Document) CancelException(com.sx4.bot.waiter.exception.CancelException) ButtonClickEvent(net.dv8tion.jda.api.events.interaction.ButtonClickEvent) MongoDatabase(com.sx4.bot.database.mongo.MongoDatabase) CompletableFuture(java.util.concurrent.CompletableFuture) Member(net.dv8tion.jda.api.entities.Member) User(net.dv8tion.jda.api.entities.User) ButtonUtility(com.sx4.bot.utility.ButtonUtility) Sx4CommandEvent(com.sx4.bot.core.Sx4CommandEvent) Button(net.dv8tion.jda.api.interactions.components.Button) Option(com.jockie.bot.core.option.Option) Waiter(com.sx4.bot.waiter.Waiter) GenericEvent(net.dv8tion.jda.api.events.GenericEvent) GameState(com.sx4.bot.entities.games.GameState) EnumSet(java.util.EnumSet) Argument(com.jockie.bot.core.argument.Argument) Limit(com.sx4.bot.annotations.argument.Limit) CancelType(com.sx4.bot.waiter.Waiter.CancelType) Message(net.dv8tion.jda.api.entities.Message) ErrorResponseException(net.dv8tion.jda.api.exceptions.ErrorResponseException) Sx4Command(com.sx4.bot.core.Sx4Command) CompletionException(java.util.concurrent.CompletionException) TimeoutException(com.sx4.bot.waiter.exception.TimeoutException) GameType(com.sx4.bot.entities.games.GameType) ModuleCategory(com.sx4.bot.category.ModuleCategory) List(java.util.List) DefaultNumber(com.sx4.bot.annotations.argument.DefaultNumber) ObjectId(org.bson.types.ObjectId) MessageReceivedEvent(net.dv8tion.jda.api.events.message.MessageReceivedEvent) User(net.dv8tion.jda.api.entities.User) ObjectId(org.bson.types.ObjectId) Document(org.bson.Document) MessageReceivedEvent(net.dv8tion.jda.api.events.message.MessageReceivedEvent) Button(net.dv8tion.jda.api.interactions.components.Button) GenericEvent(net.dv8tion.jda.api.events.GenericEvent) CompletionException(java.util.concurrent.CompletionException) ErrorResponseException(net.dv8tion.jda.api.exceptions.ErrorResponseException) CancelException(com.sx4.bot.waiter.exception.CancelException) Waiter(com.sx4.bot.waiter.Waiter) TimeoutException(com.sx4.bot.waiter.exception.TimeoutException)

Example 9 with Waiter

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

the class FakePermissionsCommand method delete.

@Command(value = "delete", aliases = { "remove" }, description = "Deletes fake permissions for a user or role")
@CommandId(172)
@Examples({ "fake permissions delete @Shea#6653", "fake permissions delete @Mods", "fake permissions delete all" })
@AuthorPermissions(permissions = { Permission.ADMINISTRATOR })
public void delete(Sx4CommandEvent event, @Argument(value = "user | role | all", endless = true, nullDefault = true) @AlternativeOptions("all") Alternative<IPermissionHolder> option) {
    if (option == null) {
        List<Document> fakePermissions = event.getProperty("fakePermissions");
        if (fakePermissions.isEmpty()) {
            event.replyFailure("Nothing has fake permissions in this server").queue();
            return;
        }
        PagedResult<Document> paged = new PagedResult<>(event.getBot(), fakePermissions).setAuthor("User & Roles", null, event.getGuild().getIconUrl()).setTimeout(60).setDisplayFunction(data -> {
            int type = data.getInteger("type");
            long id = data.getLong("id");
            if (type == HolderType.USER.getType()) {
                User user = event.getShardManager().getUserById(id);
                return user == null ? "Anonymous#0000 (" + id + ")" : user.getAsTag();
            } else {
                Role role = event.getGuild().getRoleById(id);
                return role == null ? "Deleted Role (" + id + ")" : role.getAsMention();
            }
        });
        paged.onTimeout(() -> event.reply("Timed out :stopwatch:").queue());
        paged.onSelect(select -> {
            Document data = select.getSelected();
            boolean isRole = data.getInteger("type") == HolderType.ROLE.getType();
            long id = data.getLong("id");
            User user = isRole ? null : event.getShardManager().getUserById(id);
            Role role = isRole ? event.getGuild().getRoleById(id) : null;
            event.getMongo().updateGuildById(event.getGuild().getIdLong(), Updates.pull("fakePermissions.holders", Filters.eq("id", id))).whenComplete((result, exception) -> {
                if (ExceptionUtility.sendExceptionally(event, exception)) {
                    return;
                }
                if (result.getModifiedCount() == 0) {
                    event.replyFailure("That " + (isRole ? "role" : "user") + " doesn't have any fake permissions").queue();
                    return;
                }
                event.replySuccess((isRole ? (role == null ? "Deleted Role (" + id + ")" : role.getAsMention()) : "**" + (user == null ? "Anonymous#0000** (" + id + ")" : user.getAsTag() + "**")) + " no longer has any fake permissions").queue();
            });
        });
        paged.execute(event);
    } else if (option.isAlternative()) {
        List<Button> buttons = List.of(Button.success("yes", "Yes"), Button.danger("no", "No"));
        event.reply(event.getAuthor().getName() + ", are you sure you want to delete **all** fake permissions data?").setActionRow(buttons).submit().thenCompose(message -> {
            return new Waiter<>(event.getBot(), ButtonClickEvent.class).setPredicate(e -> ButtonUtility.handleButtonConfirmation(e, message, event.getAuthor())).setCancelPredicate(e -> ButtonUtility.handleButtonCancellation(e, message, event.getAuthor())).onFailure(e -> ButtonUtility.handleButtonFailure(e, message)).setTimeout(60).start();
        }).whenComplete((e, exception) -> {
            Throwable cause = exception instanceof CompletionException ? exception.getCause() : exception;
            if (cause instanceof CancelException) {
                GenericEvent cancelEvent = ((CancelException) cause).getEvent();
                if (cancelEvent != null) {
                    ((ButtonClickEvent) cancelEvent).reply("Cancelled " + event.getConfig().getSuccessEmote()).queue();
                }
                return;
            } else if (cause instanceof TimeoutException) {
                event.reply("Timed out :stopwatch:").queue();
                return;
            } else if (ExceptionUtility.sendExceptionally(event, exception)) {
                return;
            }
            event.getMongo().updateGuildById(event.getGuild().getIdLong(), Updates.unset("fakePermissions.holders")).whenComplete((result, databaseException) -> {
                if (ExceptionUtility.sendExceptionally(event, databaseException)) {
                    return;
                }
                e.reply("All fake permission data has been deleted in this server " + event.getConfig().getSuccessEmote()).queue();
            });
        });
    } else {
        IPermissionHolder holder = option.getValue();
        boolean role = holder instanceof Role;
        event.getMongo().updateGuildById(event.getGuild().getIdLong(), Updates.pull("fakePermissions.holders", Filters.eq("id", holder.getIdLong()))).whenComplete((result, exception) -> {
            if (ExceptionUtility.sendExceptionally(event, exception)) {
                return;
            }
            if (result.getModifiedCount() == 0) {
                event.replyFailure("That " + (role ? "role" : "user") + " doesn't have any fake permissions").queue();
                return;
            }
            event.replySuccess((role ? ((Role) holder).getAsMention() : "**" + ((Member) holder).getUser().getAsTag() + "**") + " no longer has any fake permissions").queue();
        });
    }
}
Also used : HolderType(com.sx4.bot.entities.settings.HolderType) Document(org.bson.Document) Arrays(java.util.Arrays) CancelException(com.sx4.bot.waiter.exception.CancelException) Command(com.jockie.bot.core.command.Command) ButtonClickEvent(net.dv8tion.jda.api.events.interaction.ButtonClickEvent) Permission(net.dv8tion.jda.api.Permission) Projections(com.mongodb.client.model.Projections) CommandId(com.sx4.bot.annotations.command.CommandId) Member(net.dv8tion.jda.api.entities.Member) PagedResult(com.sx4.bot.paged.PagedResult) User(net.dv8tion.jda.api.entities.User) Filters(com.mongodb.client.model.Filters) Bson(org.bson.conversions.Bson) Alternative(com.sx4.bot.entities.argument.Alternative) ButtonUtility(com.sx4.bot.utility.ButtonUtility) Role(net.dv8tion.jda.api.entities.Role) Sx4CommandEvent(com.sx4.bot.core.Sx4CommandEvent) Button(net.dv8tion.jda.api.interactions.components.Button) AlternativeOptions(com.sx4.bot.annotations.argument.AlternativeOptions) Waiter(com.sx4.bot.waiter.Waiter) GenericEvent(net.dv8tion.jda.api.events.GenericEvent) Argument(com.jockie.bot.core.argument.Argument) AuthorPermissions(com.sx4.bot.annotations.command.AuthorPermissions) Operators(com.sx4.bot.database.mongo.model.Operators) Sx4Command(com.sx4.bot.core.Sx4Command) Predicate(java.util.function.Predicate) Updates(com.mongodb.client.model.Updates) CompletionException(java.util.concurrent.CompletionException) TimeoutException(com.sx4.bot.waiter.exception.TimeoutException) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) Collectors(java.util.stream.Collectors) ModuleCategory(com.sx4.bot.category.ModuleCategory) List(java.util.List) Examples(com.sx4.bot.annotations.command.Examples) IPermissionHolder(net.dv8tion.jda.api.entities.IPermissionHolder) ExceptionUtility(com.sx4.bot.utility.ExceptionUtility) Comparator(java.util.Comparator) Collections(java.util.Collections) User(net.dv8tion.jda.api.entities.User) ButtonClickEvent(net.dv8tion.jda.api.events.interaction.ButtonClickEvent) Document(org.bson.Document) IPermissionHolder(net.dv8tion.jda.api.entities.IPermissionHolder) Role(net.dv8tion.jda.api.entities.Role) GenericEvent(net.dv8tion.jda.api.events.GenericEvent) CompletionException(java.util.concurrent.CompletionException) List(java.util.List) CancelException(com.sx4.bot.waiter.exception.CancelException) TimeoutException(com.sx4.bot.waiter.exception.TimeoutException) AuthorPermissions(com.sx4.bot.annotations.command.AuthorPermissions) Command(com.jockie.bot.core.command.Command) Sx4Command(com.sx4.bot.core.Sx4Command) CommandId(com.sx4.bot.annotations.command.CommandId) Examples(com.sx4.bot.annotations.command.Examples)

Example 10 with Waiter

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

the class PremiumCommand method add.

@Command(value = "add", description = "Make a server premium")
@CommandId(177)
@Examples({ "premium add", "premium add 31", "premium add 20 Sx4 | Support Server" })
@Premium
public void add(Sx4CommandEvent event, @Argument(value = "days") @DefaultNumber(31) @Limit(min = 1, max = 365) int days, @Argument(value = "server", endless = true, nullDefault = true) Guild guild) {
    if (guild == null) {
        guild = event.getGuild();
    }
    long guildId = guild.getIdLong();
    String guildName = guild.getName();
    int monthPrice = event.getConfig().getPremiumPrice();
    int price = (int) Math.round((monthPrice / (double) event.getConfig().getPremiumDays()) * days);
    long endAtPrior = event.getMongo().getGuildById(guildId, Projections.include("premium.endAt")).getEmbedded(List.of("premium", "endAt"), 0L);
    boolean hasPremium = endAtPrior != 0;
    MessageEmbed embed = new EmbedBuilder().setColor(event.getConfig().getOrange()).setAuthor("Premium", null, event.getAuthor().getEffectiveAvatarUrl()).setDescription(String.format("Buying %d day%s of premium will:\n\n• Make you unable to use this credit on the other version of the bot\n• Use **$%.2f** of your credit\n• %s %1$s day%2$s of premium to the server\n\n:warning: **This action cannot be reversed** :warning:", days, days == 1 ? "" : "s", price / 100D, hasPremium ? "Add an extra" : "Give")).build();
    List<Button> buttons = List.of(Button.success("confirm", "Confirm"), Button.danger("cancel", "Cancel"));
    event.reply(embed).setActionRow(buttons).submit().thenCompose(message -> {
        return new Waiter<>(event.getBot(), ButtonClickEvent.class).setPredicate(e -> ButtonUtility.handleButtonConfirmation(e, message, event.getAuthor(), "confirm")).setCancelPredicate(e -> ButtonUtility.handleButtonCancellation(e, message, event.getAuthor(), "cancel")).onFailure(e -> ButtonUtility.handleButtonFailure(e, message)).setTimeout(60).start();
    }).whenComplete((e, exception) -> {
        Throwable cause = exception instanceof CompletionException ? exception.getCause() : exception;
        if (cause instanceof CancelException) {
            GenericEvent cancelEvent = ((CancelException) cause).getEvent();
            if (cancelEvent != null) {
                ((ButtonClickEvent) cancelEvent).reply("Cancelled " + event.getConfig().getSuccessEmote()).queue();
            }
            return;
        } else if (cause instanceof TimeoutException) {
            event.reply("Timed out :stopwatch:").queue();
            return;
        } else if (ExceptionUtility.sendExceptionally(event, exception)) {
            return;
        }
        List<Bson> update = List.of(Operators.set("premium.credit", Operators.cond(Operators.gt(price, Operators.ifNull("$premium.credit", 0)), "$premium.credit", Operators.subtract("$premium.credit", price))));
        FindOneAndUpdateOptions options = new FindOneAndUpdateOptions().returnDocument(ReturnDocument.BEFORE).projection(Projections.include("premium.credit")).upsert(true);
        event.getMongoMain().findAndUpdateUserById(event.getAuthor().getIdLong(), update, options).thenCompose(data -> {
            int credit = data == null ? 0 : data.getEmbedded(List.of("premium", "credit"), 0);
            if (price > credit) {
                e.reply("You do not have enough credit to buy premium for that long " + event.getConfig().getFailureEmote()).queue();
                return CompletableFuture.completedFuture(MongoDatabase.EMPTY_DOCUMENT);
            }
            List<Bson> guildUpdate = List.of(Operators.set("premium.endAt", Operators.add(TimeUnit.DAYS.toSeconds(days), Operators.ifNull("$premium.endAt", Operators.nowEpochSecond()))));
            FindOneAndUpdateOptions guildOptions = new FindOneAndUpdateOptions().returnDocument(ReturnDocument.BEFORE).projection(Projections.include("premium.endAt")).upsert(true);
            return event.getMongo().findAndUpdateGuildById(guildId, guildUpdate, guildOptions);
        }).whenComplete((data, databaseException) -> {
            if (ExceptionUtility.sendExceptionally(event, databaseException) || (data != null && data.isEmpty())) {
                return;
            }
            long endAt = data == null ? 0L : data.getEmbedded(List.of("premium", "endAt"), 0L);
            e.replyFormat("**%s** now has premium for %s%d day%s %s", guildName, endAt == 0 ? "" : "another ", days, days == 1 ? "" : "s", event.getConfig().getSuccessEmote()).queue();
        });
    });
}
Also used : Document(org.bson.Document) CancelException(com.sx4.bot.waiter.exception.CancelException) MarkdownSanitizer(net.dv8tion.jda.api.utils.MarkdownSanitizer) Command(com.jockie.bot.core.command.Command) ButtonClickEvent(net.dv8tion.jda.api.events.interaction.ButtonClickEvent) MongoDatabase(com.sx4.bot.database.mongo.MongoDatabase) CommandId(com.sx4.bot.annotations.command.CommandId) CompletableFuture(java.util.concurrent.CompletableFuture) PagedResult(com.sx4.bot.paged.PagedResult) User(net.dv8tion.jda.api.entities.User) ArrayList(java.util.ArrayList) Bson(org.bson.conversions.Bson) Redirects(com.sx4.bot.annotations.command.Redirects) ButtonUtility(com.sx4.bot.utility.ButtonUtility) Guild(net.dv8tion.jda.api.entities.Guild) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Sx4CommandEvent(com.sx4.bot.core.Sx4CommandEvent) Button(net.dv8tion.jda.api.interactions.components.Button) Map(java.util.Map) Option(com.jockie.bot.core.option.Option) Waiter(com.sx4.bot.waiter.Waiter) GenericEvent(net.dv8tion.jda.api.events.GenericEvent) com.mongodb.client.model(com.mongodb.client.model) ZoneOffset(java.time.ZoneOffset) Argument(com.jockie.bot.core.argument.Argument) Limit(com.sx4.bot.annotations.argument.Limit) Operators(com.sx4.bot.database.mongo.model.Operators) Sx4Command(com.sx4.bot.core.Sx4Command) NumberUtility(com.sx4.bot.utility.NumberUtility) CompletionException(java.util.concurrent.CompletionException) TimeoutException(com.sx4.bot.waiter.exception.TimeoutException) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) Instant(java.time.Instant) Premium(com.sx4.bot.annotations.command.Premium) TimeUnit(java.util.concurrent.TimeUnit) ModuleCategory(com.sx4.bot.category.ModuleCategory) List(java.util.List) DefaultNumber(com.sx4.bot.annotations.argument.DefaultNumber) Examples(com.sx4.bot.annotations.command.Examples) OffsetDateTime(java.time.OffsetDateTime) MessageBuilder(net.dv8tion.jda.api.MessageBuilder) DateTimeFormatter(java.time.format.DateTimeFormatter) ExceptionUtility(com.sx4.bot.utility.ExceptionUtility) MessageEmbed(net.dv8tion.jda.api.entities.MessageEmbed) MessageEmbed(net.dv8tion.jda.api.entities.MessageEmbed) Bson(org.bson.conversions.Bson) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) Button(net.dv8tion.jda.api.interactions.components.Button) GenericEvent(net.dv8tion.jda.api.events.GenericEvent) CompletionException(java.util.concurrent.CompletionException) ArrayList(java.util.ArrayList) List(java.util.List) CancelException(com.sx4.bot.waiter.exception.CancelException) Waiter(com.sx4.bot.waiter.Waiter) TimeoutException(com.sx4.bot.waiter.exception.TimeoutException) Command(com.jockie.bot.core.command.Command) Sx4Command(com.sx4.bot.core.Sx4Command) Premium(com.sx4.bot.annotations.command.Premium) CommandId(com.sx4.bot.annotations.command.CommandId) Examples(com.sx4.bot.annotations.command.Examples)

Aggregations

Argument (com.jockie.bot.core.argument.Argument)17 ModuleCategory (com.sx4.bot.category.ModuleCategory)17 Sx4Command (com.sx4.bot.core.Sx4Command)17 Sx4CommandEvent (com.sx4.bot.core.Sx4CommandEvent)17 Waiter (com.sx4.bot.waiter.Waiter)17 CancelException (com.sx4.bot.waiter.exception.CancelException)17 TimeoutException (com.sx4.bot.waiter.exception.TimeoutException)17 CompletionException (java.util.concurrent.CompletionException)17 GenericEvent (net.dv8tion.jda.api.events.GenericEvent)17 ButtonClickEvent (net.dv8tion.jda.api.events.interaction.ButtonClickEvent)17 Button (net.dv8tion.jda.api.interactions.components.Button)17 Document (org.bson.Document)17 Command (com.jockie.bot.core.command.Command)15 PagedResult (com.sx4.bot.paged.PagedResult)15 List (java.util.List)15 AlternativeOptions (com.sx4.bot.annotations.argument.AlternativeOptions)14 Alternative (com.sx4.bot.entities.argument.Alternative)14 ButtonUtility (com.sx4.bot.utility.ButtonUtility)14 User (net.dv8tion.jda.api.entities.User)14 Bson (org.bson.conversions.Bson)14