use of com.sx4.bot.core.Sx4CommandEvent in project Sx4 by sx4-discord-bot.
the class AdventCalendarCommand method onCommand.
public void onCommand(Sx4CommandEvent event) {
ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
int day = now.getDayOfMonth();
if (now.getMonthValue() != 12 || day > 24) {
event.replyFormat("There's no advent calendar box for the %s %s :no_entry:", NumberUtility.getSuffixed(day), now.getMonth().getDisplayName(TextStyle.FULL, Locale.UK)).queue();
return;
}
EconomyManager manager = event.getBot().getEconomyManager();
event.getMongo().withTransaction(session -> {
Document data = event.getMongo().getUsers().findOneAndUpdate(session, Filters.eq("_id", event.getAuthor().getIdLong()), Updates.addToSet("economy.opened", day), new FindOneAndUpdateOptions().upsert(true));
List<Integer> opened = data == null ? Collections.emptyList() : data.getEmbedded(List.of("economy", "opened"), Collections.emptyList());
if (opened.contains(day)) {
long secondsTillTomorrow = now.toLocalDate().atStartOfDay(ZoneOffset.UTC).plusDays(1).toEpochSecond() - now.toEpochSecond();
event.replyFormat("You've already opened today's box on your advent calendar%s :no_entry:", day != 24 ? ", you can open tomorrows in **" + TimeUtility.LONG_TIME_FORMATTER.parse(Duration.of(secondsTillTomorrow, ChronoUnit.SECONDS)) + "**" : "").queue();
session.abortTransaction();
return null;
}
List<Item> items = manager.getItems();
items.sort(Comparator.comparingLong(Item::getPrice).reversed());
Item item = items.get(items.size() - 1);
for (Item winnableItem : items) {
if (winnableItem instanceof Tool) {
continue;
}
int equation = (int) Math.ceil(winnableItem.getPrice() / Math.pow(day * 3, 2));
if (manager.getRandom().nextInt(equation + 1) == 0) {
item = winnableItem;
break;
}
}
if (opened.size() == 23) {
Crate present = manager.getItemById(PRESENT_CRATE, Crate.class);
List<Bson> update = List.of(Operators.set("item", present.toData()), Operators.set("amount", Operators.add(Operators.ifNull("$amount", 0L), 1L)));
event.getMongo().getItems().updateOne(session, Filters.and(Filters.eq("userId", event.getAuthor().getIdLong()), Filters.eq("item.id", item.getId())), update, new UpdateOptions().upsert(true));
}
List<Bson> update = List.of(Operators.set("item", item.toData()), Operators.set("amount", Operators.add(Operators.ifNull("$amount", 0L), 1L)));
event.getMongo().getItems().updateOne(session, Filters.and(Filters.eq("userId", event.getAuthor().getIdLong()), Filters.eq("item.id", item.getId())), update, new UpdateOptions().upsert(true));
return "You opened your advent calendar for the " + NumberUtility.getSuffixed(day) + " and got **" + item.getName() + "**" + (opened.size() == 23 ? " and a **Present Crate**" : "") + " :christmas_tree:";
}).whenComplete((content, exception) -> {
if (ExceptionUtility.sendExceptionally(event, exception) || content == null) {
return;
}
event.reply(content).queue();
});
}
use of com.sx4.bot.core.Sx4CommandEvent in project Sx4 by sx4-discord-bot.
the class AxeCommand method upgrade.
@Command(value = "upgrade", description = "Upgrade your axe by a certain attribute")
@CommandId(429)
@Examples({ "axe upgrade multiplier", "axe upgrade durability 5" })
public void upgrade(Sx4CommandEvent event, @Argument(value = "upgrade") Upgrade upgrade, @Argument(value = "upgrades") @DefaultNumber(1) @Limit(min = 1, max = 100) int upgrades) {
if (!upgrade.containsType(ItemType.AXE)) {
event.replyFailure("You can not use that upgrade on a axe").queue();
return;
}
event.getMongo().withTransaction(session -> {
Document data = event.getMongo().getItems().find(session, Filters.and(Filters.eq("userId", event.getAuthor().getIdLong()), Filters.eq("item.type", ItemType.AXE.getId()))).first();
if (data == null) {
event.replyFailure("You do not have a axe").queue();
session.abortTransaction();
return null;
}
Document item = data.get("item", Document.class);
Axe defaultAxe = event.getBot().getEconomyManager().getItemById(item.getInteger("id"), Axe.class);
Axe axe = new Axe(item, defaultAxe);
int currentUpgrades = axe.getUpgrades();
long price = 0;
for (int i = 0; i < upgrades; i++) {
price += Math.round(0.015D * defaultAxe.getPrice() * currentUpgrades++ + 0.025D * defaultAxe.getPrice());
}
UpdateResult result = event.getMongo().getUsers().updateOne(session, Filters.eq("_id", event.getAuthor().getIdLong()), List.of(EconomyUtility.decreaseBalanceUpdate(price)));
if (result.getModifiedCount() == 0) {
event.replyFormat("You do not have **$%,d** %s", price, event.getConfig().getFailureEmote()).queue();
session.abortTransaction();
return null;
}
List<Bson> update = new ArrayList<>();
update.add(Operators.set("item.upgrades", Operators.add(Operators.ifNull("$item.upgrades", 0), upgrades)));
update.add(Operators.set("item.price", Operators.add("$item.price", Math.round(defaultAxe.getPrice() * 0.015D) * upgrades)));
if (upgrade == Upgrade.DURABILITY) {
int increase = (int) upgrade.getValue() * upgrades;
update.add(Operators.set("item.durability", Operators.add("$item.durability", increase)));
update.add(Operators.set("item.maxDurability", Operators.add("$item.maxDurability", increase)));
} else if (upgrade == Upgrade.MULTIPLIER) {
double increase = defaultAxe.getMultiplier() * upgrade.getValue() * upgrades;
update.add(Operators.set("item.multiplier", Operators.add("$item.multiplier", increase)));
}
event.getMongo().getItems().updateOne(session, Filters.and(Filters.eq("userId", event.getAuthor().getIdLong()), Filters.eq("item.id", axe.getId())), update);
return String.format("You just upgraded %s %d time%s for your `%s` for **$%,d**", upgrade.getName().toLowerCase(), upgrades, (upgrades == 1 ? "" : "s"), axe.getName(), price);
}).whenComplete((message, exception) -> {
if (ExceptionUtility.sendExceptionally(event, exception) || message == null) {
return;
}
event.replySuccess(message).queue();
});
}
use of com.sx4.bot.core.Sx4CommandEvent in project Sx4 by sx4-discord-bot.
the class ChopCommand method onCommand.
public void onCommand(Sx4CommandEvent event) {
EmbedBuilder embed = new EmbedBuilder();
event.getMongo().withTransaction(session -> {
Bson filter = Filters.and(Filters.eq("userId", event.getAuthor().getIdLong()), Filters.eq("item.type", ItemType.AXE.getId()));
Document data = event.getMongo().getItems().find(session, filter).first();
if (data == null) {
event.replyFailure("You do not have a axe").queue();
session.abortTransaction();
return;
}
CooldownItemStack<Axe> axeStack = new CooldownItemStack<>(event.getBot().getEconomyManager(), data);
long usableAmount = axeStack.getUsableAmount();
if (usableAmount == 0) {
event.reply("Slow down! You can chop some trees down again in " + TimeUtility.LONG_TIME_FORMATTER.parse(axeStack.getTimeRemaining()) + " :stopwatch:").queue();
session.abortTransaction();
return;
}
Axe axe = axeStack.getItem();
List<ItemStack<Wood>> materialStacks = axe.getWoodYield();
String materials = materialStacks.stream().map(ItemStack::toString).collect(Collectors.joining(", "));
embed.setAuthor(event.getAuthor().getName(), null, event.getAuthor().getEffectiveAvatarUrl()).setColor(event.getMember().getColorRaw()).setDescription(String.format("You chopped down some trees :axe:\nWood found: %s", materialStacks.isEmpty() ? "Nothing" : materials));
if (axe.getDurability() == 2) {
embed.appendDescription("\n\nYour axe will break the next time you use it :warning:");
} else if (axe.getDurability() == 1) {
embed.appendDescription("\n\nYour axe broke in the process");
}
Bson itemFilter = Filters.and(Filters.eq("userId", event.getAuthor().getIdLong()), Filters.eq("item.id", axe.getId()));
if (axe.getDurability() == 1) {
event.getMongo().getItems().deleteOne(session, itemFilter);
} else {
List<Bson> update = List.of(EconomyUtility.getResetsUpdate(usableAmount, ChopCommand.COOLDOWN), Operators.set("item.durability", Operators.subtract("$item.durability", 1)));
event.getMongo().getItems().updateOne(session, itemFilter, update);
}
for (ItemStack<?> stack : materialStacks) {
Item item = stack.getItem();
List<Bson> update = List.of(Operators.set("item", item.toData()), Operators.set("amount", Operators.add(Operators.ifNull("$amount", 0L), stack.getAmount())));
Bson materialFilter = Filters.and(Filters.eq("userId", event.getAuthor().getIdLong()), Filters.eq("item.id", item.getId()));
event.getMongo().getItems().updateOne(session, materialFilter, update, new UpdateOptions().upsert(true));
}
}).whenComplete((updated, exception) -> {
if (ExceptionUtility.sendExceptionally(event, exception)) {
return;
}
if (updated) {
event.reply(embed.build()).queue();
}
});
}
use of com.sx4.bot.core.Sx4CommandEvent in project Sx4 by sx4-discord-bot.
the class GiveItemCommand method onCommand.
public void onCommand(Sx4CommandEvent event, @Argument(value = "user") Member member, @Argument(value = "item", endless = true) ItemStack<Item> stack) {
User user = member.getUser();
if (user.isBot()) {
event.replyFailure("You can not give items to bots").queue();
return;
}
if (user.getIdLong() == event.getAuthor().getIdLong()) {
event.replyFailure("You can not give items to yourself").queue();
return;
}
long amount = stack.getAmount();
if (amount < 1) {
event.replyFailure("You need to give at least 1 item").queue();
return;
}
Item item = stack.getItem();
if (item instanceof Tool) {
event.replyFailure("You cannot give tools").queue();
return;
}
long price = stack.getTotalPrice();
long tax = (long) Math.ceil(price * 0.05D);
event.getMongo().withTransaction(session -> {
UpdateResult balanceResult = event.getMongo().getUsers().updateOne(session, Filters.eq("_id", event.getAuthor().getIdLong()), List.of(EconomyUtility.decreaseBalanceUpdate(tax)));
if (balanceResult.getModifiedCount() == 0) {
event.replyFormat("You do not have enough to pay the tax for this item (**$%,d**) %s", tax, event.getConfig().getFailureEmote()).queue();
session.abortTransaction();
return null;
}
FindOneAndUpdateOptions options = new FindOneAndUpdateOptions().returnDocument(ReturnDocument.BEFORE).projection(Projections.include("amount", "resets"));
Bson authorFilter = Filters.and(Filters.eq("userId", event.getAuthor().getIdLong()), Filters.eq("item.id", item.getId()));
List<Bson> authorUpdate = List.of(Operators.set("amount", Operators.let(new Document("amount", Operators.ifNull("$amount", 0L)), Operators.cond(Operators.lt(Operators.subtract("$$amount", Operators.sum(Operators.map(Operators.filter(Operators.ifNull("$resets", Collections.EMPTY_LIST), Operators.gt("$$this.time", Operators.nowEpochSecond())), "$$this.amount"))), amount), "$$amount", Operators.subtract("$$amount", amount)))));
Document authorData = event.getMongo().getItems().findOneAndUpdate(session, authorFilter, authorUpdate, options);
long authorAmount = authorData == null ? 0L : authorData.get("amount", 0L);
if (authorAmount < amount) {
event.replyFailure("You do not have `" + amount + " " + item.getName() + "`").queue();
session.abortTransaction();
return null;
}
CooldownItemStack<Item> cooldownStack = new CooldownItemStack<>(item, authorData);
long cooldownAmount = cooldownStack.getCooldownAmount();
if (authorAmount - cooldownAmount < amount) {
event.replyFormat("You have `%,d %s` but **%,d** %s on cooldown %s", authorAmount, item.getName(), cooldownAmount, cooldownAmount == 1 ? "is" : "are", event.getConfig().getFailureEmote()).queue();
session.abortTransaction();
return null;
}
Bson userFilter = Filters.and(Filters.eq("userId", member.getIdLong()), Filters.eq("item.id", item.getId()));
List<Bson> userUpdate = List.of(Operators.set("item", item.toData()), Operators.set("amount", Operators.add(Operators.ifNull("$amount", 0L), stack.getAmount())));
Document userData = event.getMongo().getItems().findOneAndUpdate(session, userFilter, userUpdate, options.upsert(true));
event.getMongo().getUsers().updateOne(session, Filters.eq("_id", event.getSelfUser().getIdLong()), Updates.inc("economy.balance", tax));
EmbedBuilder embed = new EmbedBuilder().setColor(event.getMember().getColor()).setAuthor(event.getAuthor().getName() + " → " + member.getUser().getName(), null, "https://cdn0.iconfinder.com/data/icons/social-messaging-ui-color-shapes/128/money-circle-green-3-512.png").setDescription(String.format("You have gifted **%,d %s** to **%s**\n\n%s's new %s amount: **%,d %s**\n%s's new %s amount: **%,d %s**", amount, item.getName(), user.getName(), event.getAuthor().getName(), item.getName(), authorAmount - amount, item.getName(), user.getName(), item.getName(), (userData == null ? 0L : userData.getLong("amount")) + amount, item.getName())).setFooter(String.format("$%,d (%d%%) tax was taken", tax, Math.round((double) tax / price * 100)), null);
return embed.build();
}).whenComplete((embed, exception) -> {
if (ExceptionUtility.sendExceptionally(event, exception) || embed == null) {
return;
}
event.reply(embed).queue();
});
}
use of com.sx4.bot.core.Sx4CommandEvent in project Sx4 by sx4-discord-bot.
the class LeaderboardCommand method networth.
@Command(value = "networth", description = "View the leaderboard for the networth of users")
@CommandId(370)
@Examples({ "leaderboard networth", "leaderboard networth --server" })
@BotPermissions(permissions = { Permission.MESSAGE_EMBED_LINKS })
public void networth(Sx4CommandEvent event, @Option(value = "server", aliases = { "guild" }, description = "View the leaderboard with a server filter") boolean guild) {
List<Bson> userPipeline = List.of(Aggregates.project(Projections.computed("total", "$economy.balance")), Aggregates.match(Filters.and(Filters.exists("total"), Filters.ne("total", 0))));
List<Bson> pipeline = List.of(Aggregates.project(Projections.fields(Projections.computed("_id", "$userId"), Projections.computed("total", Operators.cond(Operators.exists("$item.durability"), Operators.toLong(Operators.multiply(Operators.divide("$item.price", "$item.maxDurability"), "$item.durability")), Operators.multiply("$item.price", "$amount"))))), Aggregates.match(Filters.and(Filters.ne("_id", event.getJDA().getSelfUser().getIdLong()), Filters.ne("amount", 0))), Aggregates.unionWith("users", userPipeline), Aggregates.group("$_id", Accumulators.sum("total", "$total")), Aggregates.sort(Sorts.descending("total")));
event.getMongo().aggregateItems(pipeline).whenCompleteAsync((documents, exception) -> {
if (ExceptionUtility.sendExceptionally(event, exception)) {
return;
}
List<Map.Entry<User, Long>> users = new ArrayList<>();
AtomicInteger userIndex = new AtomicInteger(-1);
int i = 0;
for (Document data : documents) {
User user = event.getShardManager().getUserById(data.getLong("_id"));
if (user == null) {
continue;
}
if (!event.getGuild().isMember(user) && guild) {
continue;
}
i++;
users.add(Map.entry(user, data.getLong("total")));
if (user.getIdLong() == event.getAuthor().getIdLong()) {
userIndex.set(i);
}
}
if (users.isEmpty()) {
event.replyFailure("There are no users which fit into this leaderboard").queue();
return;
}
PagedResult<Map.Entry<User, Long>> paged = new PagedResult<>(event.getBot(), users).setPerPage(10).setCustomFunction(page -> {
int rank = userIndex.get();
EmbedBuilder embed = new EmbedBuilder().setTitle("Networth Leaderboard").setFooter(event.getAuthor().getName() + "'s Rank: " + (rank == -1 ? "N/A" : NumberUtility.getSuffixed(rank)) + " | Page " + page.getPage() + "/" + page.getMaxPage(), event.getAuthor().getEffectiveAvatarUrl());
page.forEach((entry, index) -> embed.appendDescription(String.format("%d. `%s` - $%,d\n", index + 1, MarkdownSanitizer.escape(entry.getKey().getAsTag()), entry.getValue())));
return new MessageBuilder().setEmbeds(embed.build());
});
paged.execute(event);
});
}
Aggregations