use of com.jockie.bot.core.argument.Argument in project Sx4 by sx4-discord-bot.
the class AutoRoleCommand method remove.
@Command(value = "remove", aliases = { "delete" }, description = "Remove a role from being given when a user joins")
@CommandId(40)
@Examples({ "auto role remove @Role", "auto role remove Role", "auto role remove all" })
@AuthorPermissions(permissions = { Permission.MANAGE_ROLES })
public void remove(Sx4CommandEvent event, @Argument(value = "role | all", endless = true) @AlternativeOptions("all") Alternative<Role> option) {
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 remove every auto role in the server?").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().deleteManyAutoRoles(Filters.eq("guildId", event.getGuild().getIdLong())).whenComplete((result, databaseException) -> {
if (ExceptionUtility.sendExceptionally(event, databaseException)) {
return;
}
if (result.getDeletedCount() == 0) {
e.reply("There are no auto roles in this server " + event.getConfig().getFailureEmote()).queue();
return;
}
e.reply("All auto roles have been removed " + event.getConfig().getSuccessEmote()).queue();
});
});
} else {
Role role = option.getValue();
event.getMongo().deleteAutoRole(Filters.eq("roleId", role.getIdLong())).whenComplete((result, exception) -> {
if (ExceptionUtility.sendExceptionally(event, exception)) {
return;
}
if (result.getDeletedCount() == 0) {
event.replyFailure("That role is not an auto role").queue();
return;
}
event.replySuccess(role.getAsMention() + " is no longer an auto role").queue();
});
}
}
use of com.jockie.bot.core.argument.Argument in project Sx4 by sx4-discord-bot.
the class GiveawayCommand method delete.
@Command(value = "delete", aliases = { "remove" }, description = "Deletes a giveaway")
@CommandId(51)
@Examples({ "giveaway delete 727224132202397726", "giveaway delete all" })
@AuthorPermissions(permissions = { Permission.MANAGE_SERVER })
public void delete(Sx4CommandEvent event, @Argument(value = "message id | all") @AlternativeOptions("all") Alternative<MessageArgument> option) {
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** giveaways in this server?").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().deleteManyGiveaways(Filters.eq("guildId", event.getGuild().getIdLong())).whenComplete((result, databaseException) -> {
if (ExceptionUtility.sendExceptionally(event, databaseException)) {
return;
}
if (result.getDeletedCount() == 0) {
e.reply("There are no giveaways in this server " + event.getConfig().getFailureEmote()).queue();
return;
}
e.reply("All giveaways in this server have been deleted " + event.getConfig().getSuccessEmote()).queue();
});
});
} else {
long messageId = option.getValue().getMessageId();
event.getMongo().deleteGiveawayById(messageId).whenComplete((result, exception) -> {
if (ExceptionUtility.sendExceptionally(event, exception)) {
return;
}
if (result.getDeletedCount() == 0) {
event.replyFailure("There was no giveaway with that id").queue();
return;
}
event.replySuccess("That giveaway has been deleted").queue();
});
}
}
use of com.jockie.bot.core.argument.Argument in project Sx4 by sx4-discord-bot.
the class GiveawayCommand method setup.
@Command(value = "setup", description = "Setup giveaways for users to react to")
@CommandId(47)
@Examples({ "giveaway setup", "giveaway setup #giveaways 1 7d $10 Nitro" })
@AuthorPermissions(permissions = { Permission.MANAGE_SERVER })
public void setup(Sx4CommandEvent event, @Argument(value = "channel", nullDefault = true) TextChannel channel, @Argument(value = "winners") @DefaultNumber(0) @Limit(min = 1) int winners, @Argument(value = "duration", nullDefault = true) Duration duration, @Argument(value = "item", nullDefault = true, endless = true) String item) {
if (channel != null && winners != 0 && duration != null && item != null) {
long seconds = duration.toSeconds();
if (seconds < 1) {
event.replyFailure("The duration of a giveaway cannot be less than 1 second").queue();
return;
}
channel.sendMessageEmbeds(this.getEmbed(winners, seconds, item)).queue(message -> {
message.addReaction("🎉").queue();
Document data = new Document("messageId", message.getIdLong()).append("channelId", channel.getIdLong()).append("guildId", event.getGuild().getIdLong()).append("winnersAmount", winners).append("endAt", Clock.systemUTC().instant().getEpochSecond() + seconds).append("duration", seconds).append("item", item);
event.getMongo().insertGiveaway(data).whenComplete((result, exception) -> {
if (ExceptionUtility.sendExceptionally(event, exception)) {
return;
}
event.getBot().getGiveawayManager().putGiveaway(data, seconds);
event.reply("Your giveaway has been created in " + channel.getAsMention() + " :tada:").queue();
});
});
return;
}
AtomicReference<TextChannel> atomicChannel = new AtomicReference<>();
AtomicInteger atomicWinners = new AtomicInteger();
AtomicReference<Duration> atomicDuration = new AtomicReference<>();
AtomicReference<String> atomicItem = new AtomicReference<>();
CompletableFuture.completedFuture(true).thenCompose($ -> {
if (channel != null) {
atomicChannel.set(channel);
return CompletableFuture.completedFuture(true);
}
CompletableFuture<Boolean> future = new CompletableFuture<>();
event.reply("What channel would you like to start the giveaway in? Type `cancel` at anytime to cancel the creation.").queue(message -> {
Waiter<MessageReceivedEvent> waiter = new Waiter<>(event.getBot(), MessageReceivedEvent.class).setUnique(event.getAuthor().getIdLong(), event.getChannel().getIdLong()).setCancelPredicate(e -> e.getMessage().getContentRaw().equalsIgnoreCase("cancel")).setTimeout(30).setPredicate(e -> {
TextChannel textChannel = SearchUtility.getTextChannel(event.getGuild(), e.getMessage().getContentRaw());
if (textChannel != null) {
atomicChannel.set(textChannel);
return true;
}
event.replyFailure("I could not find that channel").queue();
return false;
});
waiter.onCancelled((type) -> {
event.replySuccess("Cancelled").queue();
future.complete(false);
});
waiter.onTimeout(() -> {
event.reply("Response timed out :stopwatch:").queue();
future.complete(false);
});
waiter.onSuccess(e -> future.complete(true));
waiter.start();
});
return future;
}).thenCompose(success -> {
if (!success) {
return CompletableFuture.completedFuture(false);
}
if (winners != 0) {
atomicWinners.set(winners);
return CompletableFuture.completedFuture(true);
}
CompletableFuture<Boolean> future = new CompletableFuture<>();
event.reply("How many winners would you like the giveaway to have?").queue(message -> {
Waiter<MessageReceivedEvent> waiter = new Waiter<>(event.getBot(), MessageReceivedEvent.class).setCancelPredicate(e -> e.getMessage().getContentRaw().equalsIgnoreCase("cancel")).setTimeout(30).setUnique(event.getAuthor().getIdLong(), event.getChannel().getIdLong()).setPredicate(e -> {
String content = e.getMessage().getContentRaw();
if (NumberUtility.isNumberUnsigned(content)) {
int number = Integer.parseInt(content);
if (number < 1) {
event.replyFailure("You have to have at least 1 winner").queue();
return false;
}
atomicWinners.set(number);
return true;
}
event.replyFailure("That is not a number").queue();
return false;
});
waiter.onCancelled((type) -> {
event.replySuccess("Cancelled").queue();
future.complete(false);
});
waiter.onTimeout(() -> {
event.reply("Response timed out :stopwatch:").queue();
future.complete(false);
});
waiter.onSuccess(e -> future.complete(true));
waiter.start();
});
return future;
}).thenCompose(success -> {
if (!success) {
return CompletableFuture.completedFuture(false);
}
if (duration != null) {
atomicDuration.set(duration);
return CompletableFuture.completedFuture(true);
}
CompletableFuture<Boolean> future = new CompletableFuture<>();
event.reply("How long would you like the giveaway to last?").queue(message -> {
Waiter<MessageReceivedEvent> waiter = new Waiter<>(event.getBot(), MessageReceivedEvent.class).setCancelPredicate(e -> e.getMessage().getContentRaw().equalsIgnoreCase("cancel")).setTimeout(30).setUnique(event.getAuthor().getIdLong(), event.getChannel().getIdLong()).setPredicate(e -> {
Duration durationReply = TimeUtility.getDurationFromString(e.getMessage().getContentRaw());
if (durationReply.toSeconds() < 1) {
event.replyFailure("The duration of a giveaway cannot be less than 1 second").queue();
return false;
}
atomicDuration.set(durationReply);
return true;
});
waiter.onCancelled((type) -> {
event.replySuccess("Cancelled").queue();
future.complete(false);
});
waiter.onTimeout(() -> {
event.reply("Response timed out :stopwatch:").queue();
future.complete(false);
});
waiter.onSuccess(e -> future.complete(true));
waiter.start();
});
return future;
}).thenCompose(success -> {
if (!success) {
return CompletableFuture.completedFuture(false);
}
if (item != null) {
atomicItem.set(item);
return CompletableFuture.completedFuture(true);
}
CompletableFuture<Boolean> future = new CompletableFuture<>();
event.reply("What would you like to giveaway?").queue(message -> {
Waiter<MessageReceivedEvent> waiter = new Waiter<>(event.getBot(), MessageReceivedEvent.class).setCancelPredicate(e -> e.getMessage().getContentRaw().equalsIgnoreCase("cancel")).setTimeout(30).setUnique(event.getAuthor().getIdLong(), event.getChannel().getIdLong()).setPredicate(e -> {
String content = e.getMessage().getContentRaw();
if (content.equalsIgnoreCase("cancel")) {
return false;
}
atomicItem.set(content);
return true;
});
waiter.onCancelled((type) -> {
event.replySuccess("Cancelled").queue();
future.complete(false);
});
waiter.onTimeout(() -> {
event.reply("Response timed out :stopwatch:").queue();
future.complete(false);
});
waiter.onSuccess(e -> future.complete(true));
waiter.start();
});
return future;
}).thenAccept(success -> {
if (!success) {
return;
}
TextChannel channelFuture = atomicChannel.get();
int winnersFuture = atomicWinners.get();
long durationFuture = atomicDuration.get().toSeconds();
String itemFuture = atomicItem.get();
channelFuture.sendMessageEmbeds(this.getEmbed(winnersFuture, durationFuture, itemFuture)).queue(message -> {
message.addReaction("🎉").queue();
Document data = new Document("messageId", message.getIdLong()).append("channelId", channelFuture.getIdLong()).append("guildId", event.getGuild().getIdLong()).append("winnersAmount", winnersFuture).append("endAt", Clock.systemUTC().instant().getEpochSecond() + durationFuture).append("duration", durationFuture).append("item", itemFuture);
event.getMongo().insertGiveaway(data).whenComplete((result, exception) -> {
if (ExceptionUtility.sendExceptionally(event, exception)) {
return;
}
event.getBot().getGiveawayManager().putGiveaway(data, durationFuture);
event.reply("Your giveaway has been created in " + channelFuture.getAsMention() + " :tada:").queue();
});
});
});
}
use of com.jockie.bot.core.argument.Argument in project Sx4 by sx4-discord-bot.
the class YouTubeNotificationCommand method add.
@Command(value = "add", description = "Add a youtube notification to be posted to a specific channel when the user uploads")
@CommandId(158)
@AuthorPermissions(permissions = { Permission.MANAGE_SERVER })
@Examples({ "youtube notification add videos mrbeast", "youtube notification add mrbeast", "youtube notification add #videos pewdiepie" })
public void add(Sx4CommandEvent event, @Argument(value = "channel", nullDefault = true) TextChannel channel, @Argument(value = "youtube channel", endless = true) String channelQuery) {
if (!event.getBot().getConnectionHandler().isReady()) {
event.replyFailure("The bot has to be fully started to use this command, try again later").queue();
return;
}
TextChannel effectiveChannel = channel == null ? event.getTextChannel() : channel;
boolean id = this.id.matcher(channelQuery).matches();
boolean search;
String queryName, query;
Matcher matcher = this.url.matcher(channelQuery);
if (!id && matcher.matches()) {
String path = matcher.group(1);
search = false;
queryName = path == null || path.equals("user") ? "forUsername" : "id";
query = matcher.group(2);
} else {
search = !id;
queryName = id ? "id" : "q";
query = channelQuery;
}
Request channelRequest = new Request.Builder().url("https://www.googleapis.com/youtube/v3/" + (search ? "search" : "channels") + "?key=" + event.getConfig().getYouTube() + "&" + queryName + "=" + URLEncoder.encode(query, StandardCharsets.UTF_8) + "&part=snippet&type=channel&maxResults=1").build();
event.getHttpClient().newCall(channelRequest).enqueue((HttpCallback) channelResponse -> {
Document json = Document.parse(channelResponse.body().string());
List<Document> items = json.getList("items", Document.class, Collections.emptyList());
if (items.isEmpty()) {
event.replyFailure("I could not find that youtube channel").queue();
return;
}
Document item = items.get(0);
String channelId = search ? item.getEmbedded(List.of("id", "channelId"), String.class) : item.getString("id");
Document notificationData = new Document("uploaderId", channelId).append("channelId", effectiveChannel.getIdLong()).append("guildId", event.getGuild().getIdLong());
if (!event.getBot().getYouTubeManager().hasExecutor(channelId)) {
RequestBody body = new MultipartBody.Builder().addFormDataPart("hub.mode", "subscribe").addFormDataPart("hub.topic", "https://www.youtube.com/xml/feeds/videos.xml?channel_id=" + channelId).addFormDataPart("hub.callback", event.getConfig().getBaseUrl() + "/api/youtube").addFormDataPart("hub.verify", "sync").addFormDataPart("hub.verify_token", event.getConfig().getYouTube()).setType(MultipartBody.FORM).build();
Request request = new Request.Builder().url("https://pubsubhubbub.appspot.com/subscribe").post(body).build();
event.getHttpClient().newCall(request).enqueue((HttpCallback) response -> {
if (response.isSuccessful()) {
event.getMongo().insertYouTubeNotification(notificationData).whenComplete((result, exception) -> {
Throwable cause = exception instanceof CompletionException ? exception.getCause() : exception;
if (cause instanceof MongoWriteException && ((MongoWriteException) cause).getError().getCategory() == ErrorCategory.DUPLICATE_KEY) {
event.replyFailure("You already have a notification setup for that youtube channel in " + effectiveChannel.getAsMention()).queue();
return;
}
if (ExceptionUtility.sendExceptionally(event, exception)) {
return;
}
event.replyFormat("Notifications will now be sent in %s when **%s** uploads with id `%s` %s", effectiveChannel.getAsMention(), item.getEmbedded(List.of("snippet", "title"), String.class), result.getInsertedId().asObjectId().getValue().toHexString(), event.getConfig().getSuccessEmote()).queue();
});
} else {
event.replyFailure("Oops something went wrong there, try again. If this repeats report this to my developer (Message: " + response.body().string() + ")").queue();
}
});
} else {
event.getMongo().insertYouTubeNotification(notificationData).whenComplete((result, exception) -> {
Throwable cause = exception instanceof CompletionException ? exception.getCause() : exception;
if (cause instanceof MongoWriteException && ((MongoWriteException) cause).getError().getCategory() == ErrorCategory.DUPLICATE_KEY) {
event.replyFailure("You already have a notification setup for that youtube channel in " + effectiveChannel.getAsMention()).queue();
return;
}
if (ExceptionUtility.sendExceptionally(event, exception)) {
return;
}
event.replyFormat("Notifications will now be sent in %s when **%s** uploads with id `%s` %s", effectiveChannel.getAsMention(), item.getEmbedded(List.of("snippet", "title"), String.class), result.getInsertedId().asObjectId().getValue().toHexString(), event.getConfig().getSuccessEmote()).queue();
});
}
});
}
use of com.jockie.bot.core.argument.Argument in project Sx4 by sx4-discord-bot.
the class SteamCommand method game.
@Command(value = "game", description = "View information about a game on steam")
@CommandId(34)
@Examples({ "steam game Grand Theft Auto", "steam game 1293830", "steam game https://store.steampowered.com/app/1293830/Forza_Horizon_4/" })
@Cooldown(5)
@BotPermissions(permissions = { Permission.MESSAGE_EMBED_LINKS })
public void game(Sx4CommandEvent event, @Argument(value = "query", endless = true, nullDefault = true) String query, @Option(value = "random", description = "Gets a random game") boolean random) {
if (query == null && !random) {
event.replyHelp().queue();
return;
}
SteamGameCache cache = event.getBot().getSteamGameCache();
if (cache.getGames().isEmpty()) {
event.replyFailure("The steam cache is currently empty, try again").queue();
return;
}
Matcher urlMatcher;
List<Document> games;
if (query == null) {
List<Document> cacheGames = cache.getGames();
games = List.of(cacheGames.get(event.getRandom().nextInt(cacheGames.size())));
} else if (NumberUtility.isNumberUnsigned(query)) {
games = List.of(new Document("appid", Integer.parseInt(query)));
} else if ((urlMatcher = this.gamePattern.matcher(query)).matches()) {
games = List.of(new Document("appid", Integer.parseInt(urlMatcher.group(1))));
} else {
games = cache.getGames(query);
if (games.isEmpty()) {
event.replyFailure("I could not find any games with that query").queue();
return;
}
}
PagedResult<Document> paged = new PagedResult<>(event.getBot(), games).setAuthor("Steam Search", null, "https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Steam_icon_logo.svg/2000px-Steam_icon_logo.svg.png").setIncreasedIndex(true).setAutoSelect(true).setTimeout(60).setDisplayFunction(game -> game.getString("name"));
paged.onSelect(select -> {
Document game = select.getSelected();
int appId = game.getInteger("appid");
Request request = new Request.Builder().url("https://store.steampowered.com/api/appdetails?cc=gb&appids=" + appId).build();
event.getHttpClient().newCall(request).enqueue((HttpCallback) response -> {
Document json = Document.parse(response.body().string()).get(String.valueOf(appId), Document.class);
if (!json.getBoolean("success")) {
event.replyFailure("Steam failed to get data for that game").queue();
return;
}
List<MessageEmbed> embeds = new ArrayList<>();
Document gameInfo = json.get("data", Document.class);
String description = Jsoup.parse(gameInfo.getString("short_description")).text();
String price;
if (gameInfo.containsKey("price_overview")) {
Document priceOverview = gameInfo.get("price_overview", Document.class);
double initialPrice = priceOverview.getInteger("initial") / 100D, finalPrice = priceOverview.getInteger("final") / 100D;
price = initialPrice == finalPrice ? String.format("£%,.2f", finalPrice) : String.format("~~£%,.2f~~ £%,.2f (-%d%%)", initialPrice, finalPrice, priceOverview.getInteger("discount_percent"));
} else {
price = gameInfo.getBoolean("is_free") ? "Free" : "Unknown";
}
EmbedBuilder embed = new EmbedBuilder();
embed.setDescription(description);
embed.setTitle(gameInfo.getString("name"), "https://store.steampowered.com/app/" + appId);
embed.setAuthor("Steam", "https://steamcommunity.com", "https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Steam_icon_logo.svg/2000px-Steam_icon_logo.svg.png");
embed.setImage(gameInfo.getString("header_image"));
embed.addField("Price", price, true);
embed.setFooter("Developed by " + (gameInfo.containsKey("developers") ? String.join(", ", gameInfo.getList("developers", String.class)) : "Unknown"), null);
Document releaseDate = gameInfo.get("release_date", Document.class);
String date = releaseDate.getString("date");
embed.addField("Release Date", String.format("%s%s", date.isBlank() ? "Unknown" : date, releaseDate.getBoolean("coming_soon") ? " (Coming Soon)" : ""), true);
Object age = gameInfo.get("required_age");
embed.addField("Required Age", age instanceof Integer ? ((int) age) == 0 ? "No Age Restriction" : String.valueOf((int) age) : (String) age, true);
embed.addField("Recommendations", String.format("%,d", gameInfo.getEmbedded(List.of("recommendations", "total"), 0)), true);
embed.addField("Supported Languages", gameInfo.containsKey("supported_languages") ? Jsoup.parse(gameInfo.getString("supported_languages")).text() : "Unknown", true);
List<Document> genres = gameInfo.getList("genres", Document.class);
embed.addField("Genres", genres == null ? "None" : genres.stream().map(genre -> genre.getString("description")).collect(Collectors.joining("\n")), true);
embeds.add(embed.build());
gameInfo.getList("screenshots", Document.class).stream().map(d -> d.getString("path_thumbnail")).limit(3).forEach(thumbnail -> {
embeds.add(new MessageEmbed("https://store.steampowered.com/app/" + appId, null, null, EmbedType.RICH, null, Role.DEFAULT_COLOR_RAW, null, null, null, null, null, new MessageEmbed.ImageInfo(thumbnail, null, 0, 0), List.of()));
});
event.getChannel().sendMessageEmbeds(embeds).queue();
});
});
paged.onTimeout(() -> event.reply("Response timed out :stopwatch:").queue());
paged.execute(event);
}
Aggregations