Search in sources :

Example 1 with Option

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

the class YouTubeCommand method onCommand.

public void onCommand(Sx4CommandEvent event, @Argument(value = "query", endless = true) String query, @Option(value = "channel", description = "Only return a channel") boolean channel, @Option(value = "playlist", description = "Only return a playlist") boolean playlist, @Option(value = "video", description = "Only return a video") boolean video) {
    String type = channel ? "channel" : video ? "video" : playlist ? "playlist" : null;
    Request request = new Request.Builder().url(String.format("https://www.googleapis.com/youtube/v3/search?key=%s&part=snippet&maxResults=50&safeSearch=none&q=%s%s", event.getConfig().getYouTube(), URLEncoder.encode(query, StandardCharsets.UTF_8), type == null ? "" : "&type=" + type)).build();
    event.getHttpClient().newCall(request).enqueue((HttpCallback) response -> {
        Document json = Document.parse(response.body().string());
        List<Document> items = json.getList("items", Document.class);
        if (items.isEmpty()) {
            event.replyFailure("I could not find any results").queue();
            return;
        }
        PagedResult<Document> paged = new PagedResult<>(event.getBot(), items).setAuthor("YouTube Results", null, "https://media-thumbs.golden.com/4hBhjfnhOC6J3uJZglZG0quRsPU=/200x200/smart/golden-media.s3.amazonaws.com%2Ftopic_images%2F6c3fdb0966b049eba2b9c2331da224f0.png").setAutoSelect(true).setDisplayFunction(data -> {
            Document id = data.get("id", Document.class);
            String kind = id.getString("kind");
            return "[" + data.getEmbedded(List.of("snippet", "title"), String.class) + "](" + this.getUrlFromId(id) + ")" + " (" + StringUtility.title(kind.substring(kind.indexOf('#') + 1)) + ")";
        });
        paged.onSelect(select -> {
            Document result = select.getSelected();
            Document id = result.get("id", Document.class);
            Document snippet = result.get("snippet", Document.class);
            Document thumbnails = snippet.get("thumbnails", Document.class);
            ZonedDateTime uploadedAt = ZonedDateTime.parse(snippet.getString("publishedAt"));
            EmbedBuilder embed = new EmbedBuilder();
            embed.setColor(16711680);
            embed.setDescription(snippet.getString("description"));
            embed.setImage(thumbnails.getEmbedded(List.of("high", "url"), String.class));
            embed.setTitle(snippet.getString("title"), this.getUrlFromId(id));
            String kind = id.getString("kind");
            if (kind.equals("youtube#channel")) {
                embed.addField("Created At", uploadedAt.format(this.formatter), true);
            } else if (kind.equals("youtube#video")) {
                String state = snippet.getString("liveBroadcastContent");
                embed.addField("Uploaded By", "[" + snippet.getString("channelTitle") + "](https://www.youtube.com/channel/" + snippet.getString("channelId") + ")", true);
                embed.addField("Uploaded At", uploadedAt.format(this.formatter), true);
                embed.addField("State", state.equals("live") ? "Live Now" : state.equals("upcoming") ? "Scheduled" : "Uploaded", true);
                Request metaDataRequest = new Request.Builder().url("https://api.jockiemusic.com/v1/youtube/videos/" + id.getString("videoId") + "/metadata").build();
                event.reply(embed.build()).queue(message -> {
                    event.getHttpClient().newCall(metaDataRequest).enqueue((HttpCallback) metaDataResponse -> {
                        if (metaDataResponse.code() == 404) {
                            return;
                        }
                        Document data = Document.parse(metaDataResponse.body().string()).get("data", Document.class);
                        Document metaData = data.get("metadata", Document.class);
                        Document rating = metaData.get("rating", Document.class);
                        long likes = rating.get("likes", Number.class).longValue(), dislikes = rating.get("dislikes", Number.class).longValue();
                        double ratingPercent = ((double) likes / (likes + dislikes)) * 100D;
                        embed.addField("Duration", TimeUtility.getMusicTimeString(metaData.get("length", Number.class).longValue(), TimeUnit.MILLISECONDS), true);
                        embed.addField("Views", String.format("%,d", metaData.get("views", Number.class).longValue()), true);
                        embed.addField("Likes/Dislikes", String.format("%,d \\\uD83D\uDC4D\n%,d \\\uD83D\uDC4E", likes, dislikes), true);
                        embed.addField("Rating", NumberUtility.DEFAULT_DECIMAL_FORMAT.format(ratingPercent) + "%", true);
                        embed.setFooter("Views and Ratings last updated");
                        embed.setTimestamp(Instant.ofEpochSecond(data.get("lastUpdated", Number.class).longValue()));
                        message.editMessageEmbeds(embed.build()).queue();
                    });
                });
                return;
            } else {
                embed.addField("Uploaded By", "[" + snippet.getString("channelTitle") + "](https://www.youtube.com/channel/" + snippet.getString("channelId") + ")", true);
                embed.addField("Uploaded At", uploadedAt.format(this.formatter), true);
            }
            event.reply(embed.build()).queue();
        });
        paged.execute(event);
    });
}
Also used : Document(org.bson.Document) Request(okhttp3.Request) HttpCallback(com.sx4.bot.http.HttpCallback) Sx4Command(com.sx4.bot.core.Sx4Command) NumberUtility(com.sx4.bot.utility.NumberUtility) Permission(net.dv8tion.jda.api.Permission) ZonedDateTime(java.time.ZonedDateTime) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) Instant(java.time.Instant) PagedResult(com.sx4.bot.paged.PagedResult) StandardCharsets(java.nio.charset.StandardCharsets) TimeUnit(java.util.concurrent.TimeUnit) ModuleCategory(com.sx4.bot.category.ModuleCategory) URLEncoder(java.net.URLEncoder) List(java.util.List) Sx4CommandEvent(com.sx4.bot.core.Sx4CommandEvent) TimeUtility(com.sx4.bot.utility.TimeUtility) DateTimeFormatter(java.time.format.DateTimeFormatter) Option(com.jockie.bot.core.option.Option) StringUtility(com.sx4.bot.utility.StringUtility) Argument(com.jockie.bot.core.argument.Argument) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) ZonedDateTime(java.time.ZonedDateTime) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) Request(okhttp3.Request) List(java.util.List) Document(org.bson.Document) PagedResult(com.sx4.bot.paged.PagedResult)

Example 2 with Option

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

the class RoleCommand method add.

@Command(value = "add", description = "Add a role to a member")
@CommandId(250)
@Redirects({ "addrole", "add role", "ar" })
@Examples({ "role add @Shea#6653 Role", "role add Shea 345718366373150720", "role add @Role" })
@AuthorPermissions(permissions = { Permission.MANAGE_ROLES })
@BotPermissions(permissions = { Permission.MANAGE_ROLES })
public void add(Sx4CommandEvent event, @Argument(value = "user", nullDefault = true) @AlternativeOptions("all") Alternative<Member> option, @Argument(value = "role", endless = true) Role role) {
    if (role.isManaged()) {
        event.replyFailure("I cannot give managed roles").queue();
        return;
    }
    if (role.isPublicRole()) {
        event.replyFailure("I cannot give the @everyone role").queue();
        return;
    }
    if (!event.getMember().canInteract(role)) {
        event.replyFailure("You cannot give a role higher or equal than your top role").queue();
        return;
    }
    if (!event.getSelfMember().canInteract(role)) {
        event.replyFailure("I cannot give a role higher or equal than my top role").queue();
        return;
    }
    if (option != null && option.isAlternative()) {
        List<Member> members = event.getGuild().getMemberCache().applyStream(stream -> stream.filter(member -> !member.getRoles().contains(role)).collect(Collectors.toList()));
        if (members.size() == 0) {
            event.replyFailure("All users already have that role").queue();
            return;
        }
        if (!this.pending.add(event.getGuild().getIdLong())) {
            event.replyFailure("You can only have 1 concurrent role being added to all users").queue();
            return;
        }
        event.replyFormat("Adding %s to **%,d** user%s, another message will be sent once this is done %s", role.getAsMention(), members.size(), members.size() == 1 ? "" : "s", event.getConfig().getSuccessEmote()).queue();
        List<CompletableFuture<Integer>> futures = new ArrayList<>();
        for (Member member : members) {
            futures.add(event.getGuild().addRoleToMember(member, role).submit().handle((result, exception) -> exception == null ? 1 : 0));
        }
        FutureUtility.allOf(futures).whenComplete((completed, exception) -> {
            this.pending.remove(event.getGuild().getIdLong());
            int count = completed.stream().reduce(0, Integer::sum);
            event.replyFormat("Successfully added the role %s to **%,d/%,d** user%s %s", role.getAsMention(), count, members.size(), count == 1 ? "" : "s", event.getConfig().getSuccessEmote()).queue();
        });
    } else {
        Member effectiveMember = option == null ? event.getMember() : option.getValue();
        event.getGuild().addRoleToMember(effectiveMember, role).flatMap($ -> event.replySuccess(role.getAsMention() + " has been added to **" + effectiveMember.getUser().getAsTag() + "**")).queue();
    }
}
Also used : Command(com.jockie.bot.core.command.Command) Sx4Command(com.sx4.bot.core.Sx4Command) Permission(net.dv8tion.jda.api.Permission) Set(java.util.Set) CompletableFuture(java.util.concurrent.CompletableFuture) Member(net.dv8tion.jda.api.entities.Member) Colour(com.sx4.bot.annotations.argument.Colour) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ModuleCategory(com.sx4.bot.category.ModuleCategory) Alternative(com.sx4.bot.entities.argument.Alternative) List(java.util.List) Role(net.dv8tion.jda.api.entities.Role) Sx4CommandEvent(com.sx4.bot.core.Sx4CommandEvent) Option(com.jockie.bot.core.option.Option) AlternativeOptions(com.sx4.bot.annotations.argument.AlternativeOptions) FutureUtility(com.sx4.bot.utility.FutureUtility) com.sx4.bot.annotations.command(com.sx4.bot.annotations.command) Argument(com.jockie.bot.core.argument.Argument) Limit(com.sx4.bot.annotations.argument.Limit) CompletableFuture(java.util.concurrent.CompletableFuture) ArrayList(java.util.ArrayList) Member(net.dv8tion.jda.api.entities.Member) Command(com.jockie.bot.core.command.Command) Sx4Command(com.sx4.bot.core.Sx4Command)

Example 3 with Option

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

the class IGDBCommand method onCommand.

public void onCommand(Sx4CommandEvent event, @Argument(value = "game", endless = true, nullDefault = true) String game, @Option(value = "sort", description = "Sort results by `name` (default), `rating` and `release`") IGDBSort sort, @Option(value = "reverse", description = "Reverses sorting order") boolean reverse) {
    IGDBParser parser = new IGDBParser().setFilter("category = 0").limit(500).addFields("name", "total_rating", "total_rating_count", "first_release_date", "genres.name", "url", "summary", "cover.image_id", "platforms.name");
    if (game != null && sort == null && !reverse) {
        parser.search(String.format("\"%s\"", game));
    } else {
        parser.sort(sort == null ? "name" : sort.getName(), !reverse).appendFilter(filter -> IGDBFilter.and(filter, (sort == null ? "name" : sort.getName()) + " != n"));
        if (game != null) {
            parser.appendFilter(filter -> IGDBFilter.and(filter, String.format("name ~ \"%s\"*", game)));
        }
    }
    Request request = new Request.Builder().url("https://api.igdb.com/v4/games/").post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), parser.parse())).addHeader("Client-ID", event.getConfig().getTwitchClientId()).addHeader("Authorization", "Bearer " + event.getConfig().getTwitch()).build();
    event.getHttpClient().newCall(request).enqueue((HttpCallback) response -> {
        String body = String.format("{\"data\":%s}", response.body().string());
        List<Document> results = Document.parse(body).getList("data", Document.class);
        if (results.isEmpty()) {
            event.replyFailure("I could not find any games with that filter").queue();
            return;
        }
        PagedResult<Document> paged = new PagedResult<>(event.getBot(), results).setAutoSelect(true).setIncreasedIndex(true).setAuthor("IGDB Search", null, "http://bit.ly/2NXGwMz").setDisplayFunction(data -> data.getString("name"));
        paged.onSelect(select -> {
            Document data = select.getSelected();
            EmbedBuilder embed = new EmbedBuilder();
            embed.setAuthor(data.getString("name"), data.getString("url"), "http://bit.ly/2NXGwMz");
            embed.setDescription(StringUtility.limit(data.get("summary", "This game has no description :("), MessageEmbed.DESCRIPTION_MAX_LENGTH, "... [Read More](" + data.getString("url") + ")"));
            embed.setThumbnail(data.containsKey("cover") ? String.format("https://images.igdb.com/igdb/image/upload/t_thumb/%s.jpg", data.getEmbedded(List.of("cover", "image_id"), String.class)) : null);
            int ratings = data.get("total_rating_count", 0);
            embed.addField("Rating", data.containsKey("total_rating") ? String.format("%.2f out of %,d rating%s", data.getDouble("total_rating"), ratings, ratings == 1 ? "" : "s") : "Unknown", true);
            embed.addField("Release Date", data.containsKey("first_release_date") ? Instant.ofEpochSecond(data.getInteger("first_release_date")).atOffset(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern("dd LLLL yyyy")) : "Unknown", true);
            embed.addField("Genres", data.containsKey("genres") ? data.getList("genres", Document.class).stream().map(genre -> genre.getString("name")).collect(Collectors.joining("\n")) : "None", true);
            embed.addField("Platforms", data.containsKey("platforms") ? data.getList("platforms", Document.class).stream().map(platform -> platform.getString("name")).collect(Collectors.joining("\n")) : "None", true);
            event.reply(embed.build()).queue();
        });
        paged.execute(event);
    });
}
Also used : Document(org.bson.Document) Request(okhttp3.Request) HttpCallback(com.sx4.bot.http.HttpCallback) Sx4Command(com.sx4.bot.core.Sx4Command) Permission(net.dv8tion.jda.api.Permission) IGDBFilter(com.sx4.bot.entities.info.IGDBFilter) IGDBSort(com.sx4.bot.entities.info.IGDBSort) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) Instant(java.time.Instant) PagedResult(com.sx4.bot.paged.PagedResult) Collectors(java.util.stream.Collectors) RequestBody(okhttp3.RequestBody) ModuleCategory(com.sx4.bot.category.ModuleCategory) List(java.util.List) IGDBParser(com.sx4.bot.entities.info.IGDBParser) Sx4CommandEvent(com.sx4.bot.core.Sx4CommandEvent) DateTimeFormatter(java.time.format.DateTimeFormatter) Option(com.jockie.bot.core.option.Option) MessageEmbed(net.dv8tion.jda.api.entities.MessageEmbed) ZoneOffset(java.time.ZoneOffset) StringUtility(com.sx4.bot.utility.StringUtility) MediaType(okhttp3.MediaType) Argument(com.jockie.bot.core.argument.Argument) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) Request(okhttp3.Request) List(java.util.List) IGDBParser(com.sx4.bot.entities.info.IGDBParser) Document(org.bson.Document) PagedResult(com.sx4.bot.paged.PagedResult)

Example 4 with Option

use of com.jockie.bot.core.option.Option 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 5 with Option

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

the class CSGOSkinCommand method onCommand.

public void onCommand(Sx4CommandEvent event, @Argument(value = "skin name", endless = true) String query, @Option(value = "sort", description = "You can sort by `price`, `age`, `deal`, `popularity`, `wear or `discount`") Sort sort, @Option(value = "reverse", description = "Reverse the order of the sorting") boolean reverse, @Option(value = "wear", description = "What wear you would like to filter by, options are `fn`, `mw`, `ft`, `ww` and `bs`") Wear wear, @Option(value = "phase", description = "Filter by phase of a knife") @Lowercase String phase, @Option(value = "currency", description = "What currency to use for the prices of items") @Uppercase @DefaultString("GBP") String currency) {
    SkinPortManager manager = event.getBot().getSkinPortManager();
    String cookie = manager.getCSRFCookie();
    double rate = manager.getCurrencyRate(currency);
    if (rate == -1D) {
        event.replyFailure("SkinPort does not support that currency").queue();
        return;
    }
    FormBody body = new FormBody.Builder().add("prefix", query).add("_csrf", manager.getCSRFToken()).build();
    Request suggestionRequest = new Request.Builder().url("https://skinport.com/api/suggestions/730").post(body).addHeader("Content-Type", "application/x-www-form-urlencoded").addHeader("Cookie", cookie).build();
    event.getHttpClient().newCall(suggestionRequest).enqueue((HttpCallback) suggestionResponse -> {
        Document data = Document.parse(suggestionResponse.body().string());
        List<Document> variants = data.getList("suggestions", Document.class);
        if (variants.isEmpty()) {
            event.replyFailure("I could not find any skins from that query").queue();
            return;
        }
        PagedResult<Document> suggestions = new PagedResult<>(event.getBot(), variants).setAuthor("SkinPort", null, "https://skinport.com/static/favicon-32x32.png").setDisplayFunction(suggestion -> {
            String type = suggestion.getString("type");
            return (type == null ? "" : type + " | ") + suggestion.getString("item");
        }).setIndexed(true).setAutoSelect(true);
        suggestions.onSelect(select -> {
            Document selected = select.getSelected();
            String type = selected.getString("type");
            StringBuilder url = new StringBuilder("https://skinport.com/api/browse/730?cat=" + URLEncoder.encode(selected.getString("category"), StandardCharsets.UTF_8) + (type != null ? "&type=" + URLEncoder.encode(type, StandardCharsets.UTF_8) : "") + "&item=" + URLEncoder.encode(selected.getString("item"), StandardCharsets.UTF_8));
            if (wear != null) {
                url.append("&exterior=").append(wear.getId());
            }
            if (sort != null) {
                url.append("&sort=").append(sort.getIdentifier()).append("&order=").append(reverse ? "desc" : "asc");
            }
            if (phase != null) {
                int phaseId = this.phases.getOrDefault(phase, -1);
                if (phaseId != -1) {
                    url.append("&phase=").append(phaseId);
                }
            }
            Request request = new Request.Builder().url(url.toString()).addHeader("Cookie", cookie).build();
            event.getHttpClient().newCall(request).enqueue((HttpCallback) response -> {
                Document skinData = Document.parse(response.body().string());
                List<Document> items = skinData.getList("items", Document.class);
                if (items.isEmpty()) {
                    event.replyFailure("There are no skins listed with those filters").queue();
                    return;
                }
                PagedResult<Document> skins = new PagedResult<>(event.getBot(), items).setPerPage(1).setSelect().setCustomFunction(page -> {
                    List<MessageEmbed> embeds = new ArrayList<>();
                    EmbedBuilder embed = new EmbedBuilder();
                    embed.setFooter("Skin " + page.getPage() + "/" + page.getMaxPage());
                    page.forEach((d, index) -> {
                        double steamPrice = (d.getInteger("suggestedPrice") / 100D) * rate;
                        double price = (d.getInteger("salePrice") / 100D) * rate;
                        double increase = steamPrice - price;
                        embed.setTitle(d.getString("marketName"), "https://skinport.com/item/" + d.getString("url") + "/" + d.getInteger("saleId"));
                        embed.setImage("https://community.cloudflare.steamstatic.com/economy/image/" + d.getString("image"));
                        embed.addField("Price", String.format("~~%,.2f %s~~ %,.2f %2$s (%s%.2f%%)", steamPrice, currency, price, increase > 0 ? "-" : "+", Math.abs((increase / steamPrice) * 100D)), true);
                        String exterior = d.getString("exterior");
                        if (exterior != null) {
                            embed.addField("Wear", exterior, true);
                            embed.addField("Float", String.format("%.3f", d.get("wear", Number.class).doubleValue()), true);
                        }
                        String lock = d.getString("lock");
                        embed.addField("Trade Locked", lock == null ? "No" : this.formatter.parse(Duration.between(OffsetDateTime.now(ZoneOffset.UTC), OffsetDateTime.parse(lock))), true);
                        embeds.add(embed.build());
                        if (d.getBoolean("canHaveScreenshots")) {
                            embed.setImage("https://cdn.skinport.com/images/screenshots/" + d.getInteger("assetId") + "/backside_512x384.png");
                            embeds.add(embed.build());
                            embed.setImage("https://cdn.skinport.com/images/screenshots/" + d.getInteger("assetId") + "/playside_512x384.png");
                            embeds.add(embed.build());
                        }
                    });
                    return new MessageBuilder().setEmbeds(embeds);
                });
                skins.execute(event);
            });
        });
        suggestions.execute(event);
    });
}
Also used : Document(org.bson.Document) Uppercase(com.sx4.bot.annotations.argument.Uppercase) HashMap(java.util.HashMap) SkinPortManager(com.sx4.bot.managers.SkinPortManager) PagedResult(com.sx4.bot.paged.PagedResult) ArrayList(java.util.ArrayList) FormBody(okhttp3.FormBody) Sx4CommandEvent(com.sx4.bot.core.Sx4CommandEvent) TimeUtility(com.sx4.bot.utility.TimeUtility) Duration(java.time.Duration) Map(java.util.Map) Option(com.jockie.bot.core.option.Option) TimeFormatter(com.sx4.bot.entities.utility.TimeFormatter) ZoneOffset(java.time.ZoneOffset) Argument(com.jockie.bot.core.argument.Argument) Lowercase(com.sx4.bot.annotations.argument.Lowercase) Request(okhttp3.Request) HttpCallback(com.sx4.bot.http.HttpCallback) Sx4Command(com.sx4.bot.core.Sx4Command) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) StandardCharsets(java.nio.charset.StandardCharsets) ModuleCategory(com.sx4.bot.category.ModuleCategory) URLEncoder(java.net.URLEncoder) List(java.util.List) OffsetDateTime(java.time.OffsetDateTime) MessageBuilder(net.dv8tion.jda.api.MessageBuilder) MessageEmbed(net.dv8tion.jda.api.entities.MessageEmbed) DefaultString(com.sx4.bot.annotations.argument.DefaultString) MessageEmbed(net.dv8tion.jda.api.entities.MessageEmbed) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) MessageBuilder(net.dv8tion.jda.api.MessageBuilder) FormBody(okhttp3.FormBody) Request(okhttp3.Request) HttpCallback(com.sx4.bot.http.HttpCallback) ArrayList(java.util.ArrayList) DefaultString(com.sx4.bot.annotations.argument.DefaultString) Document(org.bson.Document) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) SkinPortManager(com.sx4.bot.managers.SkinPortManager) MessageBuilder(net.dv8tion.jda.api.MessageBuilder) ArrayList(java.util.ArrayList) List(java.util.List) PagedResult(com.sx4.bot.paged.PagedResult)

Aggregations

Argument (com.jockie.bot.core.argument.Argument)13 Option (com.jockie.bot.core.option.Option)13 ModuleCategory (com.sx4.bot.category.ModuleCategory)13 Sx4Command (com.sx4.bot.core.Sx4Command)13 Sx4CommandEvent (com.sx4.bot.core.Sx4CommandEvent)13 HttpCallback (com.sx4.bot.http.HttpCallback)11 Request (okhttp3.Request)11 Document (org.bson.Document)10 EmbedBuilder (net.dv8tion.jda.api.EmbedBuilder)9 Permission (net.dv8tion.jda.api.Permission)9 List (java.util.List)8 PagedResult (com.sx4.bot.paged.PagedResult)7 StandardCharsets (java.nio.charset.StandardCharsets)6 MessageEmbed (net.dv8tion.jda.api.entities.MessageEmbed)6 URLEncoder (java.net.URLEncoder)5 StringUtility (com.sx4.bot.utility.StringUtility)4 ZoneOffset (java.time.ZoneOffset)4 ArrayList (java.util.ArrayList)4 CompletableFuture (java.util.concurrent.CompletableFuture)4 Collectors (java.util.stream.Collectors)4