use of com.jockie.bot.core.argument.Argument 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();
});
});
}
use of com.jockie.bot.core.argument.Argument in project Sx4 by sx4-discord-bot.
the class WhitelistCommand method remove.
@Command(value = "remove", description = "Remove a role/user from being whitelisted from a specified command/module in a channel")
@CommandId(185)
@Examples({ "whitelist remove #general @Shea#6653 fish", "whitelist remove #bots @Members ban" })
@AuthorPermissions(permissions = { Permission.MANAGE_SERVER })
public void remove(Sx4CommandEvent event, @Argument(value = "channel", nullDefault = true) TextChannel channel, @Argument(value = "user | role") IPermissionHolder holder, @Argument(value = "command | module", endless = true) List<Sx4Command> commands) {
List<TextChannel> channels = channel == null ? event.getGuild().getTextChannels() : List.of(channel);
boolean role = holder instanceof Role;
BitSet bitSet = new BitSet();
commands.stream().map(Sx4Command::getId).forEach(bitSet::set);
List<Long> longArray = Arrays.stream(bitSet.toLongArray()).boxed().collect(Collectors.toList());
List<Bson> update = List.of(Operators.set("holders", Operators.let(new Document("holder", Operators.filter("$holders", Operators.eq("$$this.id", holder.getIdLong()))), Operators.cond(Operators.or(Operators.extinct("$holders"), Operators.isEmpty("$$holder")), "$holders", Operators.concatArrays(Operators.filter("$holders", Operators.ne("$$this.id", holder.getIdLong())), Operators.let(new Document("result", Operators.bitSetAndNot(Operators.ifNull(Operators.first(Operators.map("$$holder", "$$this.whitelisted")), Collections.EMPTY_LIST), longArray)), Operators.cond(Operators.and(Operators.isEmpty(Operators.ifNull(Operators.first(Operators.map("$$holder", "$$this.blacklisted")), Collections.EMPTY_LIST)), Operators.bitSetIsEmpty("$$result")), Collections.EMPTY_LIST, List.of(Operators.cond(Operators.bitSetIsEmpty("$$result"), Operators.removeObject(Operators.first("$$holder"), "whitelisted"), Operators.mergeObjects(Operators.first("$$holder"), new Document("whitelisted", "$$result")))))))))));
List<WriteModel<Document>> bulkData = channels.stream().map(textChannel -> new UpdateOneModel<Document>(Filters.eq("channelId", textChannel.getIdLong()), update, new UpdateOptions())).collect(Collectors.toList());
event.getMongo().bulkWriteBlacklists(bulkData).whenComplete((result, exception) -> {
if (ExceptionUtility.sendExceptionally(event, exception)) {
return;
}
if (result.getModifiedCount() == 0) {
event.replyFailure((commands.size() == 1 ? "That command is" : "Those commands are") + " not whitelisted for that " + (role ? "role" : "user") + " in those channels").queue();
return;
}
event.replySuccess((commands.size() == 1 ? "That command is" : "Those commands are") + " no longer whitelisted for that " + (role ? "role" : "user") + " in **" + result.getModifiedCount() + "** channel" + (result.getModifiedCount() == 1 ? "" : "s")).queue();
});
}
use of com.jockie.bot.core.argument.Argument in project Sx4 by sx4-discord-bot.
the class WhitelistCommand method add.
@Command(value = "add", description = "Add a role/user to be whitelisted from a specified command/module in a channel")
@CommandId(184)
@Examples({ "whitelist add #general @Shea#6653 fish", "whitelist add #bots @Members ban" })
@AuthorPermissions(permissions = { Permission.MANAGE_SERVER })
public void add(Sx4CommandEvent event, @Argument(value = "channel", nullDefault = true) TextChannel channel, @Argument(value = "user | role") IPermissionHolder holder, @Argument(value = "command | module", endless = true) List<Sx4Command> commands) {
List<TextChannel> channels = channel == null ? event.getGuild().getTextChannels() : List.of(channel);
boolean role = holder instanceof Role;
int type = role ? HolderType.ROLE.getType() : HolderType.USER.getType();
BitSet bitSet = new BitSet();
commands.stream().map(Sx4Command::getId).forEach(bitSet::set);
Document defaultData = new Document("id", holder.getIdLong()).append("type", type).append("whitelisted", Collections.EMPTY_LIST);
List<Long> longArray = Arrays.stream(bitSet.toLongArray()).boxed().collect(Collectors.toList());
List<Bson> update = List.of(Operators.set("holders", Operators.let(new Document("holders", Operators.ifNull("$holders", Collections.EMPTY_LIST)), Operators.let(new Document("holder", Operators.filter("$$holders", Operators.eq("$$this.id", holder.getIdLong()))), Operators.concatArrays(Operators.ifNull(Operators.filter("$$holders", Operators.ne("$$this.id", holder.getIdLong())), Collections.EMPTY_LIST), List.of(Operators.mergeObjects(Operators.ifNull(Operators.first("$$holder"), defaultData), new Document("whitelisted", Operators.bitSetOr(longArray, Operators.ifNull(Operators.first(Operators.map("$$holder", "$$this.whitelisted")), Collections.EMPTY_LIST))))))))), Operators.setOnInsert("guildId", event.getGuild().getIdLong()));
List<WriteModel<Document>> bulkData = channels.stream().map(textChannel -> new UpdateOneModel<Document>(Filters.eq("channelId", textChannel.getIdLong()), update, new UpdateOptions().upsert(true))).collect(Collectors.toList());
event.getMongo().bulkWriteBlacklists(bulkData).whenComplete((result, exception) -> {
if (ExceptionUtility.sendExceptionally(event, exception)) {
return;
}
if (result.getModifiedCount() == 0) {
event.replyFailure((commands.size() == 1 ? "That command is" : "Those commands are") + " already whitelisted for that " + (role ? "role" : "user") + " in those channels").queue();
return;
}
event.replySuccess((commands.size() == 1 ? "That command is" : "Those commands are") + " now whitelisted for that " + (role ? "role" : "user") + " in **" + result.getModifiedCount() + "** extra channel" + (result.getModifiedCount() == 1 ? "" : "s")).queue();
});
}
use of com.jockie.bot.core.argument.Argument in project Sx4 by sx4-discord-bot.
the class WhitelistCommand method list.
@Command(value = "list", description = "Lists the commands roles/users whitelisted from using in a specific channel")
@CommandId(187)
@Examples({ "whitelist list", "whitelist list #channel" })
public void list(Sx4CommandEvent event, @Argument(value = "channel", nullDefault = true, endless = true) TextChannel channel) {
List<TextChannel> channels = channel == null ? event.getGuild().getTextChannels() : List.of(channel);
PagedResult<TextChannel> channelPaged = new PagedResult<>(event.getBot(), channels).setAutoSelect(true).setAuthor("Channels", null, event.getGuild().getIconUrl()).setDisplayFunction(TextChannel::getAsMention);
channelPaged.onSelect(channelSelect -> {
TextChannel selectedChannel = channelSelect.getSelected();
Document blacklist = event.getMongo().getBlacklist(Filters.eq("channelId", selectedChannel.getIdLong()), Projections.include("holders"));
if (blacklist == null) {
event.replyFailure("Nothing is whitelisted in " + selectedChannel.getAsMention()).queue();
return;
}
List<Document> holders = blacklist.getList("holders", Document.class).stream().filter(holder -> !holder.getList("whitelisted", Long.class, Collections.emptyList()).isEmpty()).sorted(Comparator.comparingInt(a -> a.getInteger("type"))).collect(Collectors.toList());
if (holders.isEmpty()) {
event.replyFailure("Nothing is whitelisted in " + selectedChannel.getAsMention()).queue();
return;
}
PagedResult<Document> holderPaged = new PagedResult<>(event.getBot(), holders).setAuthor("Users/Roles", null, event.getGuild().getIconUrl()).setDisplayFunction(holder -> {
long id = holder.getLong("id");
int type = holder.getInteger("type");
if (type == HolderType.ROLE.getType()) {
Role role = event.getGuild().getRoleById(id);
return role == null ? "Deleted Role (" + id + ")" : role.getAsMention();
} else {
User user = event.getShardManager().getUserById(id);
return user == null ? "Unknown User (" + id + ")" : user.getAsTag();
}
});
holderPaged.onSelect(holderSelect -> {
Document holder = holderSelect.getSelected();
List<Long> whitelisted = holder.getList("whitelisted", Long.class, Collections.emptyList());
BitSet bitSet = BitSet.valueOf(whitelisted.stream().mapToLong(l -> l).toArray());
List<Sx4Command> commands = event.getCommandListener().getAllCommands().stream().map(Sx4Command.class::cast).filter(command -> bitSet.get(command.getId())).collect(Collectors.toList());
PagedResult<Sx4Command> commandPaged = new PagedResult<>(event.getBot(), commands).setAuthor("Whitelisted Commands", null, event.getGuild().getIconUrl()).setDisplayFunction(Sx4Command::getCommandTrigger).setSelect().setIndexed(false);
commandPaged.execute(event);
});
holderPaged.execute(event);
});
channelPaged.execute(event);
}
use of com.jockie.bot.core.argument.Argument in project Sx4 by sx4-discord-bot.
the class FactoryCommand method buy.
@Command(value = "buy", description = "Buy a factory with some materials")
@CommandId(396)
@Examples({ "factory buy 5 Shoe Factory", "factory buy Shoe Factory", "factory buy all" })
@BotPermissions(permissions = { Permission.MESSAGE_EMBED_LINKS })
public void buy(Sx4CommandEvent event, @Argument(value = "factories", endless = true) @AlternativeOptions("all") Alternative<ItemStack<Factory>> option) {
ItemStack<Factory> stack = option.getValue();
event.getMongo().withTransaction(session -> {
Bson userFilter = Filters.eq("userId", event.getAuthor().getIdLong()), filter;
List<Factory> factories;
if (stack == null) {
filter = Filters.and(userFilter, Filters.eq("item.type", ItemType.MATERIAL.getId()));
factories = event.getBot().getEconomyManager().getItems(Factory.class);
} else {
Factory factory = stack.getItem();
filter = Filters.and(userFilter, Filters.eq("item.id", factory.getCost().getItem().getId()));
factories = List.of(factory);
}
List<Document> materials = event.getMongo().getItems().find(session, filter).projection(Projections.include("amount", "item.id")).into(new ArrayList<>());
List<ItemStack<Factory>> boughtFactories = new ArrayList<>();
Factories: for (Factory factory : factories) {
ItemStack<Material> cost = factory.getCost();
Material costMaterial = cost.getItem();
for (Document material : materials) {
int id = material.getEmbedded(List.of("item", "id"), Integer.class);
if (costMaterial.getId() == id) {
long buyableAmount = (long) Math.floor((double) material.getLong("amount") / cost.getAmount());
long amount = stack == null ? buyableAmount : stack.getAmount();
if (amount == 0 || amount > buyableAmount) {
continue Factories;
}
event.getMongo().getItems().updateOne(session, Filters.and(userFilter, Filters.eq("item.id", id)), Updates.inc("amount", -amount * cost.getAmount()));
List<Bson> update = List.of(Operators.set("item", factory.toData()), Operators.set("amount", Operators.add(Operators.ifNull("$amount", 0L), amount)));
event.getMongo().getItems().updateOne(session, Filters.and(userFilter, Filters.eq("item.id", factory.getId())), update, new UpdateOptions().upsert(true));
boughtFactories.add(new ItemStack<>(factory, amount));
}
}
}
return boughtFactories;
}).whenComplete((factories, exception) -> {
if (ExceptionUtility.sendExceptionally(event, exception)) {
return;
}
if (factories.isEmpty()) {
event.replyFailure("You cannot afford " + (stack == null ? "any factories" : "`" + stack.getAmount() + " " + stack.getItem().getName() + "`")).queue();
return;
}
String factoriesBought = factories.stream().sorted(Collections.reverseOrder(Comparator.comparingLong(ItemStack::getAmount))).map(ItemStack::toString).collect(Collectors.joining("\n• "));
EmbedBuilder embed = new EmbedBuilder().setColor(event.getMember().getColor()).setAuthor(event.getAuthor().getName(), null, event.getAuthor().getEffectiveAvatarUrl()).setDescription("With all your materials you have bought the following factories\n\n• " + factoriesBought);
event.reply(embed.build()).queue();
});
}
Aggregations