use of com.sx4.bot.annotations.argument.UserId 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()) {
String acceptId = new CustomButtonId.Builder().setType(ButtonType.DIVORCE_ALL_CONFIRM).setTimeout(60).setOwners(author.getIdLong()).getId();
String rejectId = new CustomButtonId.Builder().setType(ButtonType.GENERIC_REJECT).setTimeout(60).setOwners(author.getIdLong()).getId();
event.reply(author.getName() + ", are you sure you want to divorce everyone you are currently married to?").setActionRow(List.of(Button.success(acceptId, "Yes"), Button.danger(rejectId, "No"))).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();
});
}
}
use of com.sx4.bot.annotations.argument.UserId in project Sx4 by sx4-discord-bot.
the class GameCommand method leaderboard.
@Command(value = "leaderboard", aliases = { "lb" }, description = "View the users who have played/won/lost/drawn the most games")
@CommandId(457)
@Redirects({ "lb games", "leaderboard games", "lb game", "leaderboard game" })
@BotPermissions(permissions = { Permission.MESSAGE_EMBED_LINKS })
public void leaderboard(Sx4CommandEvent event, @Argument(value = "games") @Endless(minArguments = 0) GameType[] gameTypes, @Option(value = "server", aliases = { "guild" }, description = "Filters by only users in the current server") boolean guild, @Option(value = "state", description = "Filters whether the leaderboard should be for wins, played, losses or draws") GameState state) {
List<Bson> filters = new ArrayList<>();
if (gameTypes.length > 0) {
filters.add(Filters.in("type", Arrays.stream(gameTypes).map(GameType::getId).collect(Collectors.toList())));
}
if (state != null) {
filters.add(Filters.eq("state", state.getId()));
}
List<Bson> pipeline = List.of(Aggregates.project(Projections.include("state", "type", "userId")), Aggregates.match(filters.isEmpty() ? Filters.empty() : Filters.and(filters)), Aggregates.group("$userId", Accumulators.sum("count", 1L)), Aggregates.sort(Sorts.descending("count")));
event.getMongo().aggregateGames(pipeline).whenComplete((games, 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 game : games) {
User user = event.getShardManager().getUserById(game.getLong("_id"));
if (user == null) {
continue;
}
if (!event.getGuild().isMember(user) && guild) {
continue;
}
i++;
users.add(Map.entry(user, game.getLong("count")));
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("Games 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 game%s\n", index + 1, MarkdownSanitizer.escape(entry.getKey().getAsTag()), entry.getValue(), entry.getValue() == 1 ? "" : "s")));
return new MessageBuilder().setEmbeds(embed.build());
});
paged.execute(event);
});
}
use of com.sx4.bot.annotations.argument.UserId in project Sx4 by sx4-discord-bot.
the class FishCommand 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.ROD.getId()));
Document data = event.getMongo().getItems().find(session, filter).first();
if (data == null) {
event.replyFailure("You do not have a fishing rod").queue();
session.abortTransaction();
return;
}
CooldownItemStack<Rod> rodStack = new CooldownItemStack<>(event.getBot().getEconomyManager(), data);
long usableAmount = rodStack.getUsableAmount();
if (usableAmount == 0) {
event.reply("Slow down! You can go fishing again in " + TimeUtility.LONG_TIME_FORMATTER.parse(rodStack.getTimeRemaining()) + " :stopwatch:").queue();
session.abortTransaction();
return;
}
Rod rod = rodStack.getItem();
long yield = rod.getYield(event.getBot().getEconomyManager());
embed.setAuthor(event.getAuthor().getName(), null, event.getAuthor().getEffectiveAvatarUrl()).setColor(event.getMember().getColorRaw()).setDescription(String.format("You fish for 5 minutes and sell your fish! (**$%,d**) :fish:", yield));
if (rod.getDurability() == 2) {
embed.appendDescription("\n\nYour fishing rod will break the next time you use it :warning:");
} else if (rod.getDurability() == 1) {
embed.appendDescription("\n\nYour fishing rod broke in the process");
}
Bson itemFilter = Filters.and(Filters.eq("userId", event.getAuthor().getIdLong()), Filters.eq("item.id", rod.getId()));
if (rod.getDurability() == 1) {
event.getMongo().getItems().deleteOne(session, itemFilter);
} else {
List<Bson> update = List.of(EconomyUtility.getResetsUpdate(usableAmount, FishCommand.COOLDOWN), Operators.set("item.durability", Operators.subtract("$item.durability", 1)));
event.getMongo().getItems().updateOne(session, itemFilter, update);
}
event.getMongo().getUsers().updateOne(session, Filters.eq("_id", event.getAuthor().getIdLong()), Updates.inc("economy.balance", yield), 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.annotations.argument.UserId in project Sx4 by sx4-discord-bot.
the class FishingRodCommand method info.
@Command(value = "info", aliases = { "information" }, description = "View information on a users fishing rod")
@CommandId(382)
@Examples({ "fishing rod info", "fishing rod info @Shea#6653", "fishing rod info Shea" })
@BotPermissions(permissions = { Permission.MESSAGE_EMBED_LINKS })
public void info(Sx4CommandEvent event, @Argument(value = "user", endless = true, nullDefault = true) Member member) {
Member effectiveMember = member == null ? event.getMember() : member;
User user = member == null ? event.getAuthor() : effectiveMember.getUser();
Bson filter = Filters.and(Filters.eq("userId", effectiveMember.getIdLong()), Filters.eq("item.type", ItemType.ROD.getId()));
Document data = event.getMongo().getItem(filter, Projections.include("item"));
if (data == null) {
event.replyFailure("That user does not have a fishing rod").queue();
return;
}
Rod rod = Rod.fromData(event.getBot().getEconomyManager(), data.get("item", Document.class));
EmbedBuilder embed = new EmbedBuilder().setAuthor(user.getName() + "'s " + rod.getName(), null, user.getEffectiveAvatarUrl()).setColor(effectiveMember.getColorRaw()).setThumbnail("https://emojipedia-us.s3.amazonaws.com/thumbs/120/twitter/147/fishing-pole-and-fish_1f3a3.png").addField("Durability", rod.getDurability() + "/" + rod.getMaxDurability(), false).addField("Current Price", String.format("$%,d", rod.getCurrentPrice()), false).addField("Price", String.format("$%,d", rod.getPrice()), false).addField("Yield", String.format("$%,d to $%,d", rod.getMinYield(), rod.getMaxYield()), false);
event.reply(embed.build()).queue();
}
use of com.sx4.bot.annotations.argument.UserId 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();
});
}
Aggregations