Search in sources :

Example 6 with Context

use of net.kodehawa.mantarobot.core.modules.commands.base.Context in project MantaroBot by Mantaro.

the class PlayerCmds method badges.

@Subscribe
public void badges(CommandRegistry cr) {
    final Random r = new Random();
    ITreeCommand badgeCommand = cr.register("badges", new TreeCommand(CommandCategory.CURRENCY) {

        @Override
        public Command defaultTrigger(Context ctx, String mainCommand, String commandName) {
            return new SubCommand() {

                @Override
                protected void call(Context ctx, I18nContext languageContext, String content) {
                    var optionalArguments = ctx.getOptionalArguments();
                    content = Utils.replaceArguments(optionalArguments, content, "brief");
                    // Lambdas strike again.
                    var contentFinal = content;
                    ctx.findMember(content, members -> {
                        var member = CustomFinderUtil.findMemberDefault(contentFinal, members, ctx, ctx.getMember());
                        if (member == null) {
                            return;
                        }
                        var toLookup = member.getUser();
                        Player player = ctx.getPlayer(toLookup);
                        PlayerData playerData = player.getData();
                        DBUser dbUser = ctx.getDBUser();
                        if (!optionalArguments.isEmpty() && optionalArguments.containsKey("brief")) {
                            ctx.sendLocalized("commands.badges.brief_success", member.getEffectiveName(), playerData.getBadges().stream().sorted().map(Badge::getDisplay).collect(Collectors.joining(", ")));
                            return;
                        }
                        var badges = playerData.getBadges();
                        Collections.sort(badges);
                        var embed = new EmbedBuilder().setAuthor(String.format(languageContext.get("commands.badges.header"), toLookup.getName())).setColor(ctx.getMemberColor()).setThumbnail(toLookup.getEffectiveAvatarUrl());
                        List<MessageEmbed.Field> fields = new LinkedList<>();
                        for (var b : badges) {
                            // God DAMNIT discord, I want it to look cute, stop trimming my spaces.
                            fields.add(new MessageEmbed.Field(b.toString(), "**\u2009\u2009\u2009\u2009- " + b.description + "**", false));
                        }
                        if (badges.isEmpty()) {
                            embed.setDescription(languageContext.get("commands.badges.no_badges"));
                            ctx.send(embed.build());
                            return;
                        }
                        var common = languageContext.get("commands.badges.profile_notice") + languageContext.get("commands.badges.info_notice") + ((r.nextInt(2) == 0 && !dbUser.isPremium() ? languageContext.get("commands.badges.donate_notice") : "\n") + String.format(languageContext.get("commands.badges.total_badges"), badges.size()));
                        DiscordUtils.sendPaginatedEmbed(ctx, embed, DiscordUtils.divideFields(6, fields), common);
                    });
                }
            };
        }

        @Override
        public HelpContent help() {
            return new HelpContent.Builder().setDescription("Shows your (or another person)'s badges.").setUsage("If you want to check out the badges of another person just mention them.\n" + "You can use `~>badges -brief` to get a brief versions of the badge showcase.").build();
        }
    });
    badgeCommand.addSubCommand("info", new SubCommand() {

        @Override
        public String description() {
            return "Shows info about a badge.";
        }

        @Override
        protected void call(Context ctx, I18nContext languageContext, String content) {
            if (content.isEmpty()) {
                ctx.sendLocalized("commands.badges.info.not_specified", EmoteReference.ERROR);
                return;
            }
            var badge = Badge.lookupFromString(content);
            if (badge == null || badge == Badge.DJ) {
                ctx.sendLocalized("commands.badges.info.not_found", EmoteReference.ERROR);
                return;
            }
            var player = ctx.getPlayer();
            var message = new MessageBuilder().setEmbeds(new EmbedBuilder().setAuthor(String.format(languageContext.get("commands.badges.info.header"), badge.display)).setDescription(String.join("\n", EmoteReference.BLUE_SMALL_MARKER + "**" + languageContext.get("general.name") + ":** " + badge.display, EmoteReference.BLUE_SMALL_MARKER + "**" + languageContext.get("general.description") + ":** " + badge.description, EmoteReference.BLUE_SMALL_MARKER + "**" + languageContext.get("commands.badges.info.achieved") + ":** " + player.getData().getBadges().stream().anyMatch(b -> b == badge))).setThumbnail("attachment://icon.png").setColor(Color.CYAN).build()).build();
            ctx.getChannel().sendMessage(message).addFile(badge.icon, "icon.png").queue();
        }
    });
    badgeCommand.addSubCommand("list", new SubCommand() {

        @Override
        public String description() {
            return "Lists all the obtainable badges.";
        }

        @Override
        protected void call(Context ctx, I18nContext languageContext, String content) {
            var badges = Badge.values();
            var builder = new EmbedBuilder().setAuthor(languageContext.get("commands.badges.ls.header"), null, ctx.getAuthor().getEffectiveAvatarUrl()).setColor(Color.PINK).setFooter(languageContext.get("general.requested_by").formatted(ctx.getMember().getEffectiveName()), null);
            var player = ctx.getPlayer();
            List<MessageEmbed.Field> fields = new LinkedList<>();
            for (Badge badge : badges) {
                if (!badge.isObtainable()) {
                    continue;
                }
                fields.add(new MessageEmbed.Field("%s\u2009\u2009\u2009%s".formatted(badge.unicode, badge.display), badge.getDescription() + "\n" + String.format(languageContext.get("commands.badges.ls.obtained"), player.getData().hasBadge(badge)), false));
            }
            DiscordUtils.sendPaginatedEmbed(ctx, builder, DiscordUtils.divideFields(7, fields), languageContext.get("commands.badges.ls.desc"));
        }
    });
    badgeCommand.createSubCommandAlias("list", "ls");
    badgeCommand.createSubCommandAlias("list", "1ist");
    badgeCommand.createSubCommandAlias("list", "Is");
    badgeCommand.createSubCommandAlias("list", "is");
    badgeCommand.createSubCommandAlias("list", "1s");
    cr.registerAlias("badges", "badge");
}
Also used : Context(net.kodehawa.mantarobot.core.modules.commands.base.Context) I18nContext(net.kodehawa.mantarobot.core.modules.commands.i18n.I18nContext) Badge(net.kodehawa.mantarobot.commands.currency.profile.Badge) Color(java.awt.Color) Module(net.kodehawa.mantarobot.core.modules.Module) Command(net.kodehawa.mantarobot.core.modules.commands.base.Command) HelpContent(net.kodehawa.mantarobot.core.modules.commands.help.HelpContent) PlayerData(net.kodehawa.mantarobot.db.entities.helpers.PlayerData) Utils(net.kodehawa.mantarobot.utils.Utils) Random(java.util.Random) User(net.dv8tion.jda.api.entities.User) InteractiveOperation(net.kodehawa.mantarobot.core.listeners.operations.core.InteractiveOperation) CustomFinderUtil(net.kodehawa.mantarobot.utils.commands.CustomFinderUtil) ITreeCommand(net.kodehawa.mantarobot.core.modules.commands.base.ITreeCommand) PlayerEquipment(net.kodehawa.mantarobot.commands.currency.item.PlayerEquipment) CommandRegistry(net.kodehawa.mantarobot.core.CommandRegistry) DBUser(net.kodehawa.mantarobot.db.entities.DBUser) Subscribe(com.google.common.eventbus.Subscribe) SimpleCommand(net.kodehawa.mantarobot.core.modules.commands.SimpleCommand) Context(net.kodehawa.mantarobot.core.modules.commands.base.Context) LinkedList(java.util.LinkedList) ItemHelper(net.kodehawa.mantarobot.commands.currency.item.ItemHelper) ItemStack(net.kodehawa.mantarobot.commands.currency.item.ItemStack) DiscordUtils(net.kodehawa.mantarobot.utils.commands.DiscordUtils) Player(net.kodehawa.mantarobot.db.entities.Player) SubCommand(net.kodehawa.mantarobot.core.modules.commands.SubCommand) ItemReference(net.kodehawa.mantarobot.commands.currency.item.ItemReference) InteractiveOperations(net.kodehawa.mantarobot.core.listeners.operations.InteractiveOperations) Predicate(java.util.function.Predicate) IncreasingRateLimiter(net.kodehawa.mantarobot.utils.commands.ratelimit.IncreasingRateLimiter) UnifiedPlayer(net.kodehawa.mantarobot.commands.currency.seasons.helpers.UnifiedPlayer) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) Collectors(java.util.stream.Collectors) TreeCommand(net.kodehawa.mantarobot.core.modules.commands.TreeCommand) TimeUnit(java.util.concurrent.TimeUnit) Breakable(net.kodehawa.mantarobot.commands.currency.item.special.helpers.Breakable) List(java.util.List) RatelimitUtils(net.kodehawa.mantarobot.utils.commands.ratelimit.RatelimitUtils) OffsetDateTime(java.time.OffsetDateTime) ChronoUnit(java.time.temporal.ChronoUnit) CommandCategory(net.kodehawa.mantarobot.core.modules.commands.base.CommandCategory) I18nContext(net.kodehawa.mantarobot.core.modules.commands.i18n.I18nContext) MessageBuilder(net.dv8tion.jda.api.MessageBuilder) EmoteReference(net.kodehawa.mantarobot.utils.commands.EmoteReference) MantaroData(net.kodehawa.mantarobot.data.MantaroData) MessageEmbed(net.dv8tion.jda.api.entities.MessageEmbed) Collections(java.util.Collections) Player(net.kodehawa.mantarobot.db.entities.Player) UnifiedPlayer(net.kodehawa.mantarobot.commands.currency.seasons.helpers.UnifiedPlayer) SubCommand(net.kodehawa.mantarobot.core.modules.commands.SubCommand) MessageEmbed(net.dv8tion.jda.api.entities.MessageEmbed) HelpContent(net.kodehawa.mantarobot.core.modules.commands.help.HelpContent) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) MessageBuilder(net.dv8tion.jda.api.MessageBuilder) Badge(net.kodehawa.mantarobot.commands.currency.profile.Badge) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) Random(java.util.Random) MessageBuilder(net.dv8tion.jda.api.MessageBuilder) Command(net.kodehawa.mantarobot.core.modules.commands.base.Command) ITreeCommand(net.kodehawa.mantarobot.core.modules.commands.base.ITreeCommand) SimpleCommand(net.kodehawa.mantarobot.core.modules.commands.SimpleCommand) SubCommand(net.kodehawa.mantarobot.core.modules.commands.SubCommand) TreeCommand(net.kodehawa.mantarobot.core.modules.commands.TreeCommand) ITreeCommand(net.kodehawa.mantarobot.core.modules.commands.base.ITreeCommand) DBUser(net.kodehawa.mantarobot.db.entities.DBUser) LinkedList(java.util.LinkedList) List(java.util.List) PlayerData(net.kodehawa.mantarobot.db.entities.helpers.PlayerData) ITreeCommand(net.kodehawa.mantarobot.core.modules.commands.base.ITreeCommand) TreeCommand(net.kodehawa.mantarobot.core.modules.commands.TreeCommand) I18nContext(net.kodehawa.mantarobot.core.modules.commands.i18n.I18nContext) Subscribe(com.google.common.eventbus.Subscribe)

Example 7 with Context

use of net.kodehawa.mantarobot.core.modules.commands.base.Context in project MantaroBot by Mantaro.

the class MoneyCmds method loot.

@Subscribe
public void loot(CommandRegistry cr) {
    final IncreasingRateLimiter rateLimiter = new IncreasingRateLimiter.Builder().limit(1).spamTolerance(2).cooldown(3, TimeUnit.MINUTES).maxCooldown(3, TimeUnit.MINUTES).randomIncrement(false).premiumAware(true).pool(MantaroData.getDefaultJedisPool()).prefix("loot").build();
    final ZoneId zoneId = ZoneId.systemDefault();
    final SecureRandom random = new SecureRandom();
    cr.register("loot", new SimpleCommand(CommandCategory.CURRENCY) {

        @Override
        public void call(Context ctx, String content, String[] args) {
            var unifiedPlayer = UnifiedPlayer.of(ctx.getAuthor(), ctx.getConfig().getCurrentSeason());
            var player = unifiedPlayer.getPlayer();
            var playerData = player.getData();
            var dbUser = ctx.getDBUser();
            var languageContext = ctx.getLanguageContext();
            if (player.isLocked()) {
                ctx.sendLocalized("commands.loot.player_locked", EmoteReference.ERROR);
                return;
            }
            if (!RatelimitUtils.ratelimit(rateLimiter, ctx)) {
                return;
            }
            var today = LocalDate.now(zoneId);
            var eventStart = today.withMonth(Month.DECEMBER.getValue()).withDayOfMonth(23);
            // Up to the 25th
            var eventStop = eventStart.plusDays(3);
            var ground = TextChannelGround.of(ctx.getEvent());
            if (today.isEqual(eventStart) || (today.isAfter(eventStart) && today.isBefore(eventStop))) {
                ground.dropItemWithChance(ItemReference.CHRISTMAS_TREE_SPECIAL, 4);
                ground.dropItemWithChance(ItemReference.BELL_SPECIAL, 4);
            }
            if (random.nextInt(100) > 95) {
                ground.dropItem(ItemReference.LOOT_CRATE);
                if (playerData.addBadgeIfAbsent(Badge.LUCKY)) {
                    player.saveUpdating();
                }
            }
            var loot = ground.collectItems();
            var moneyFound = ground.collectMoney() + Math.max(0, random.nextInt(70));
            // Make the credits minimum 10, instead of... 1
            if (moneyFound != 0) {
                moneyFound = Math.max(10, moneyFound);
            }
            if (dbUser.isPremium() && moneyFound > 0) {
                int extra = (int) (moneyFound * 1.5);
                moneyFound += random.nextInt(extra);
            }
            var extraMessage = "";
            // Sellout
            if (playerData.shouldSeeCampaign()) {
                extraMessage += Campaign.PREMIUM.getStringFromCampaign(languageContext, dbUser.isPremium());
                playerData.markCampaignAsSeen();
            }
            if (!loot.isEmpty()) {
                var stack = ItemStack.toString(ItemStack.reduce(loot));
                if (player.getInventory().merge(loot))
                    extraMessage += languageContext.withRoot("commands", "loot.item_overflow");
                if (moneyFound != 0) {
                    if (unifiedPlayer.addMoney(moneyFound)) {
                        ctx.sendLocalized("commands.loot.with_item.found", EmoteReference.POPPER, stack, moneyFound, extraMessage);
                    } else {
                        ctx.sendLocalized("commands.loot.with_item.found_but_overflow", EmoteReference.POPPER, stack, moneyFound, extraMessage);
                    }
                } else {
                    ctx.sendLocalized("commands.loot.with_item.found_only_item_but_overflow", EmoteReference.MEGA, stack, extraMessage);
                }
            } else {
                if (moneyFound != 0) {
                    if (unifiedPlayer.addMoney(moneyFound)) {
                        ctx.sendLocalized("commands.loot.without_item.found", EmoteReference.POPPER, moneyFound, extraMessage);
                    } else {
                        ctx.sendLocalized("commands.loot.without_item.found_but_overflow", EmoteReference.POPPER, moneyFound);
                    }
                } else {
                    var dust = dbUser.getData().increaseDustLevel(random.nextInt(2));
                    var msg = languageContext.withRoot("commands", "loot.dust").formatted(dust);
                    dbUser.save();
                    if (random.nextInt(100) > 93) {
                        msg += languageContext.withRoot("commands", "loot.easter");
                    }
                    ctx.send(EmoteReference.SAD + msg);
                }
            }
            unifiedPlayer.saveUpdating();
        }

        @Override
        public HelpContent help() {
            return new HelpContent.Builder().setDescription("Loot the current chat for items, for usage in Mantaro's currency system. " + "You have a random chance of getting collectible items from here.").build();
        }
    });
}
Also used : Context(net.kodehawa.mantarobot.core.modules.commands.base.Context) ZoneId(java.time.ZoneId) SimpleCommand(net.kodehawa.mantarobot.core.modules.commands.SimpleCommand) HelpContent(net.kodehawa.mantarobot.core.modules.commands.help.HelpContent) IncreasingRateLimiter(net.kodehawa.mantarobot.utils.commands.ratelimit.IncreasingRateLimiter) SecureRandom(java.security.SecureRandom) Subscribe(com.google.common.eventbus.Subscribe)

Example 8 with Context

use of net.kodehawa.mantarobot.core.modules.commands.base.Context in project MantaroBot by Mantaro.

the class OptsCmd method register.

@Subscribe
public void register(CommandRegistry registry) {
    registry.register("opts", optsCmd = new SimpleCommand(CommandCategory.MODERATION, CommandPermission.ADMIN) {

        @Override
        protected void call(Context ctx, String content, String[] args) {
            if (args.length == 0) {
                ctx.sendLocalized("options.error_general", EmoteReference.WARNING);
                return;
            }
            var languageContext = ctx.getLanguageContext();
            if (args.length == 1 && args[0].equalsIgnoreCase("list") || args[0].equalsIgnoreCase("ls")) {
                var builder = new StringBuilder();
                for (var opt : Option.getAvaliableOptions()) {
                    builder.append(opt).append("\n");
                }
                var dividedMessages = DiscordUtils.divideString(builder);
                List<String> messages = new LinkedList<>();
                for (var msgs : dividedMessages) {
                    messages.add(String.format(languageContext.get("commands.opts.list.header"), languageContext.get("general.button_react"), String.format("```prolog\n%s```", msgs)));
                }
                DiscordUtils.listButtons(ctx, 45, messages);
                return;
            }
            if (args.length < 2) {
                ctx.sendLocalized("options.error_general", EmoteReference.WARNING);
                return;
            }
            var name = new StringBuilder();
            if (args[0].equalsIgnoreCase("help")) {
                for (int i = 1; i < args.length; i++) {
                    var s = args[i];
                    if (name.length() > 0) {
                        name.append(":");
                    }
                    name.append(s);
                    var option = Option.getOptionMap().get(name.toString());
                    if (option != null) {
                        try {
                            var builder = new EmbedBuilder().setAuthor(option.getOptionName(), null, ctx.getAuthor().getEffectiveAvatarUrl()).setDescription(option.getDescription()).setThumbnail("https://i.imgur.com/lFTJSE4.png").addField(EmoteReference.PENCIL.toHeaderString() + "Type", option.getType().toString(), false);
                            ctx.send(builder.build());
                        } catch (IndexOutOfBoundsException ignored) {
                        }
                        return;
                    }
                }
                ctx.sendLocalized("commands.opts.option_not_found", EmoteReference.ERROR);
                return;
            }
            for (int i = 0; i < args.length; i++) {
                var str = args[i];
                if (name.length() > 0) {
                    name.append(":");
                }
                name.append(str);
                var option = Option.getOptionMap().get(name.toString());
                if (option != null) {
                    var callable = option.getEventConsumer();
                    try {
                        String[] a;
                        if (++i < args.length) {
                            a = Arrays.copyOfRange(args, i, args.length);
                        } else {
                            a = StringUtils.EMPTY_ARRAY;
                        }
                        callable.accept(ctx, a);
                        var player = MantaroData.db().getPlayer(ctx.getAuthor());
                        if (player.getData().addBadgeIfAbsent(Badge.DID_THIS_WORK)) {
                            player.saveUpdating();
                        }
                    } catch (IndexOutOfBoundsException ignored) {
                    }
                    return;
                }
            }
            ctx.sendLocalized("options.error_general", EmoteReference.WARNING);
        }

        @Override
        public HelpContent help() {
            return new HelpContent.Builder().setDescription("This command allows you to change Mantaro settings for this server.\n" + "All values set are local and NOT global, meaning that they will only effect this server. " + "No, you can't give away currency or give yourself coins or anything like that.").setUsage("Check https://github.com/Mantaro/MantaroBot/wiki/Configuration for a guide on how to use opts. Welcome to the jungle.").build();
        }
    }).addOption("check:data", new Option("Data check.", "Checks the data values you have set on this server. **THIS IS NOT USER-FRIENDLY**. " + "If you wanna send this to the support server, use -print at the end.", OptionType.GENERAL).setAction((ctx, args) -> {
        var dbGuild = ctx.getDBGuild();
        var guildData = dbGuild.getData();
        var lang = ctx.getLanguageContext();
        // Map as follows: name, value
        // This filters out unused configs.
        var fieldMap = mapConfigObjects(guildData);
        if (fieldMap == null) {
            ctx.sendLocalized("options.check_data.retrieve_failure", EmoteReference.ERROR);
            return;
        }
        final var guild = ctx.getGuild();
        var opts = StringUtils.parseArguments(args);
        if (opts.containsKey("print") || opts.containsKey("paste")) {
            var builder = new StringBuilder();
            for (var entry : fieldMap.entrySet()) {
                builder.append("* ").append(entry.getKey()).append(": ").append(entry.getValue().getRight()).append("\n");
            }
            ctx.sendFormat("Send this: %s", Utils.paste(builder.toString()));
            return;
        }
        var embedBuilder = new EmbedBuilder();
        embedBuilder.setAuthor("Option Debug", null, ctx.getAuthor().getEffectiveAvatarUrl()).setDescription(String.format(lang.get("options.check_data.header") + lang.get("options.check_data.terminology"), guild.getName())).setThumbnail(guild.getIconUrl()).setFooter(lang.get("options.check_data.footer"), null);
        List<MessageEmbed.Field> fields = new LinkedList<>();
        for (var e : fieldMap.entrySet()) {
            fields.add(new MessageEmbed.Field(EmoteReference.BLUE_SMALL_MARKER + e.getKey() + ":\n" + e.getValue().getLeft() + "", e.getValue() == null ? lang.get("options.check_data.null_set") : String.valueOf(e.getValue().getRight()), false));
        }
        var splitFields = DiscordUtils.divideFields(6, fields);
        DiscordUtils.listButtons(ctx, 200, embedBuilder, splitFields);
    }).setShortDescription("Checks the data values you have set on this server.")).addOption("reset:all", new Option("Options reset.", "Resets all options set on this server.", OptionType.GENERAL).setAction((ctx) -> {
        // Temporary stuff.
        var dbGuild = ctx.getDBGuild();
        // New object?
        var temp = ctx.getDBGuild().getData();
        // The persistent data we wish to maintain.
        var premiumKey = temp.getPremiumKey();
        var quoteLastId = temp.getQuoteLastId();
        var ranPolls = temp.getQuoteLastId();
        var gameTimeoutExpectedAt = temp.getGameTimeoutExpectedAt();
        var cases = temp.getCases();
        var allowedBirthdays = temp.getAllowedBirthdays();
        var notified = temp.isNotifiedFromBirthdayChange();
        var greetReceived = temp.hasReceivedGreet();
        // Assign everything all over again
        var newDbGuild = DBGuild.of(dbGuild.getId(), dbGuild.getPremiumUntil());
        var newTmp = newDbGuild.getData();
        newTmp.setGameTimeoutExpectedAt(gameTimeoutExpectedAt);
        newTmp.setRanPolls(ranPolls);
        newTmp.setCases(cases);
        newTmp.setPremiumKey(premiumKey);
        newTmp.setQuoteLastId(quoteLastId);
        newTmp.setAllowedBirthdays(allowedBirthdays);
        newTmp.setNotifiedFromBirthdayChange(notified);
        newTmp.setHasReceivedGreet(greetReceived);
        newDbGuild.saveAsync();
        ctx.sendLocalized("options.reset_all.success", EmoteReference.CORRECT);
    }));
}
Also used : Context(net.kodehawa.mantarobot.core.modules.commands.base.Context) Badge(net.kodehawa.mantarobot.commands.currency.profile.Badge) DiscordUtils(net.kodehawa.mantarobot.utils.commands.DiscordUtils) Module(net.kodehawa.mantarobot.core.modules.Module) Arrays(java.util.Arrays) HelpContent(net.kodehawa.mantarobot.core.modules.commands.help.HelpContent) StringUtils(net.kodehawa.mantarobot.utils.StringUtils) Utils(net.kodehawa.mantarobot.utils.Utils) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) DBGuild(net.kodehawa.mantarobot.db.entities.DBGuild) Option(net.kodehawa.mantarobot.options.core.Option) List(java.util.List) Utils.mapConfigObjects(net.kodehawa.mantarobot.utils.Utils.mapConfigObjects) CommandCategory(net.kodehawa.mantarobot.core.modules.commands.base.CommandCategory) CommandPermission(net.kodehawa.mantarobot.core.modules.commands.base.CommandPermission) CommandRegistry(net.kodehawa.mantarobot.core.CommandRegistry) EmoteReference(net.kodehawa.mantarobot.utils.commands.EmoteReference) MantaroData(net.kodehawa.mantarobot.data.MantaroData) Subscribe(com.google.common.eventbus.Subscribe) SimpleCommand(net.kodehawa.mantarobot.core.modules.commands.SimpleCommand) Context(net.kodehawa.mantarobot.core.modules.commands.base.Context) OptionType(net.kodehawa.mantarobot.options.core.OptionType) MessageEmbed(net.dv8tion.jda.api.entities.MessageEmbed) LinkedList(java.util.LinkedList) MessageEmbed(net.dv8tion.jda.api.entities.MessageEmbed) HelpContent(net.kodehawa.mantarobot.core.modules.commands.help.HelpContent) LinkedList(java.util.LinkedList) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) SimpleCommand(net.kodehawa.mantarobot.core.modules.commands.SimpleCommand) Option(net.kodehawa.mantarobot.options.core.Option) List(java.util.List) LinkedList(java.util.LinkedList) Subscribe(com.google.common.eventbus.Subscribe)

Example 9 with Context

use of net.kodehawa.mantarobot.core.modules.commands.base.Context in project MantaroBot by Mantaro.

the class MessageCmds method prune.

@Subscribe
public void prune(CommandRegistry cr) {
    var pruneCmd = cr.register("prune", new TreeCommand(CommandCategory.MODERATION) {

        @Override
        public Command defaultTrigger(Context context, String mainCommand, String commandName) {
            return new SubCommand() {

                @Override
                protected void call(Context ctx, I18nContext languageContext, String content) {
                    var args = ctx.getArguments();
                    if (content.isEmpty()) {
                        ctx.sendLocalized("commands.prune.no_messages_specified", EmoteReference.ERROR);
                        return;
                    }
                    var mentionedUsers = ctx.getMentionedUsers();
                    var amount = 5;
                    if (args.length > 0) {
                        try {
                            amount = Integer.parseInt(args[0]);
                            if (amount < 3) {
                                amount = 3;
                            }
                        } catch (Exception e) {
                            ctx.sendLocalized("commands.prune.not_valid", EmoteReference.ERROR);
                            return;
                        }
                    }
                    if (!mentionedUsers.isEmpty()) {
                        List<Long> users = mentionedUsers.stream().map(User::getIdLong).collect(Collectors.toList());
                        final var finalAmount = amount;
                        ctx.getChannel().getHistory().retrievePast(100).queue(messageHistory -> getMessageHistory(ctx, messageHistory, finalAmount, "commands.prune.mention_no_messages", message -> users.contains(message.getAuthor().getIdLong())), error -> ctx.sendLocalized("commands.prune.error_retrieving", EmoteReference.ERROR, error.getClass().getSimpleName(), error.getMessage()));
                        return;
                    }
                    ctx.getChannel().getHistory().retrievePast(Math.min(amount, 100)).queue(messageHistory -> prune(ctx, messageHistory), error -> {
                        ctx.sendLocalized("commands.prune.error_retrieving", EmoteReference.ERROR, error.getClass().getSimpleName(), error.getMessage());
                        error.printStackTrace();
                    });
                }
            };
        }

        @Override
        public HelpContent help() {
            return new HelpContent.Builder().setDescription("Prunes X amount of messages from a channel. Requires Message Manage permission.").setUsage("`~>prune <messages> [@user...]`").addParameter("messages", "Number of messages from 4 to 100.").addParameterOptional("@user...", "Prunes messages only from mentioned users.").build();
        }
    });
    pruneCmd.setPredicate(ctx -> {
        if (!ctx.getMember().hasPermission(Permission.MESSAGE_MANAGE)) {
            ctx.sendLocalized("commands.prune.no_permissions_user", EmoteReference.ERROR);
            return false;
        }
        if (!ctx.getSelfMember().hasPermission(Permission.MESSAGE_MANAGE)) {
            ctx.sendLocalized("commands.prune.no_permissions", EmoteReference.ERROR);
            return false;
        }
        return true;
    });
    pruneCmd.addSubCommand("bot", new SubCommand() {

        @Override
        public String description() {
            return "Prune bot messages. It takes the number of messages as an argument.";
        }

        @Override
        protected void call(Context ctx, I18nContext languageContext, String content) {
            var args = ctx.getArguments();
            var amount = 100;
            if (args.length >= 1) {
                try {
                    amount = Integer.parseInt(args[0]);
                    if (amount < 3) {
                        amount = 3;
                    }
                } catch (Exception e) {
                    ctx.sendLocalized("commands.prune.not_valid", EmoteReference.ERROR);
                    return;
                }
            }
            final var finalAmount = amount;
            ctx.getChannel().getHistory().retrievePast(100).queue(messageHistory -> {
                String prefix = MantaroData.db().getGuild(ctx.getGuild()).getData().getGuildCustomPrefix();
                getMessageHistory(ctx, messageHistory, finalAmount, "commands.prune.bots_no_messages", message -> message.getAuthor().isBot() || message.getContentRaw().startsWith(prefix == null ? "~>" : prefix));
            }, error -> {
                ctx.sendLocalized("commands.prune.error_retrieving", EmoteReference.ERROR, error.getClass().getSimpleName(), error.getMessage());
                error.printStackTrace();
            });
        }
    });
    pruneCmd.addSubCommand("nopins", new SubCommand() {

        @Override
        public String description() {
            return "Prune messages that aren't pinned. It takes the number of messages as an argument.";
        }

        @Override
        protected void call(Context ctx, I18nContext languageContext, String content) {
            var args = ctx.getArguments();
            var amount = 100;
            if (args.length >= 1) {
                try {
                    amount = Integer.parseInt(args[0]);
                    if (amount < 3) {
                        amount = 3;
                    }
                } catch (Exception e) {
                    ctx.sendLocalized("commands.prune.not_valid", EmoteReference.ERROR);
                    return;
                }
            }
            final var finalAmount = amount;
            ctx.getChannel().getHistory().retrievePast(100).queue(messageHistory -> getMessageHistory(ctx, messageHistory, finalAmount, "commands.prune.no_pins_no_messages", message -> !message.isPinned()), error -> {
                ctx.sendLocalized("commands.prune.error_retrieving", EmoteReference.ERROR, error.getClass().getSimpleName(), error.getMessage());
                error.printStackTrace();
            });
        }
    });
}
Also used : I18nContext(net.kodehawa.mantarobot.core.modules.commands.i18n.I18nContext) Context(net.kodehawa.mantarobot.core.modules.commands.base.Context) Message(net.dv8tion.jda.api.entities.Message) Module(net.kodehawa.mantarobot.core.modules.Module) SubCommand(net.kodehawa.mantarobot.core.modules.commands.SubCommand) PermissionException(net.dv8tion.jda.api.exceptions.PermissionException) Command(net.kodehawa.mantarobot.core.modules.commands.base.Command) HelpContent(net.kodehawa.mantarobot.core.modules.commands.help.HelpContent) Predicate(java.util.function.Predicate) Permission(net.dv8tion.jda.api.Permission) Collectors(java.util.stream.Collectors) User(net.dv8tion.jda.api.entities.User) TreeCommand(net.kodehawa.mantarobot.core.modules.commands.TreeCommand) ModLog(net.kodehawa.mantarobot.commands.moderation.ModLog) List(java.util.List) OffsetDateTime(java.time.OffsetDateTime) CommandCategory(net.kodehawa.mantarobot.core.modules.commands.base.CommandCategory) I18nContext(net.kodehawa.mantarobot.core.modules.commands.i18n.I18nContext) CommandRegistry(net.kodehawa.mantarobot.core.CommandRegistry) EmoteReference(net.kodehawa.mantarobot.utils.commands.EmoteReference) MantaroData(net.kodehawa.mantarobot.data.MantaroData) Subscribe(com.google.common.eventbus.Subscribe) Context(net.kodehawa.mantarobot.core.modules.commands.base.Context) SubCommand(net.kodehawa.mantarobot.core.modules.commands.SubCommand) User(net.dv8tion.jda.api.entities.User) HelpContent(net.kodehawa.mantarobot.core.modules.commands.help.HelpContent) PermissionException(net.dv8tion.jda.api.exceptions.PermissionException) SubCommand(net.kodehawa.mantarobot.core.modules.commands.SubCommand) Command(net.kodehawa.mantarobot.core.modules.commands.base.Command) TreeCommand(net.kodehawa.mantarobot.core.modules.commands.TreeCommand) List(java.util.List) TreeCommand(net.kodehawa.mantarobot.core.modules.commands.TreeCommand) I18nContext(net.kodehawa.mantarobot.core.modules.commands.i18n.I18nContext) Subscribe(com.google.common.eventbus.Subscribe)

Example 10 with Context

use of net.kodehawa.mantarobot.core.modules.commands.base.Context in project MantaroBot by Mantaro.

the class MarryCmd method marry.

@Subscribe
public void marry(CommandRegistry cr) {
    final IncreasingRateLimiter rateLimiter = new IncreasingRateLimiter.Builder().limit(1).cooldown(10, TimeUnit.MINUTES).maxCooldown(40, TimeUnit.MINUTES).randomIncrement(false).pool(MantaroData.getDefaultJedisPool()).prefix("marry").build();
    ITreeCommand marryCommand = cr.register("marry", new TreeCommand(CommandCategory.CURRENCY) {

        @Override
        public Command defaultTrigger(Context ctx, String mainCommand, String commandName) {
            return new SubCommand() {

                @Override
                protected void call(Context ctx, I18nContext languageContext, String content) {
                    if (ctx.getMentionedUsers().isEmpty()) {
                        ctx.sendLocalized("commands.marry.no_mention", EmoteReference.ERROR);
                        return;
                    }
                    // We don't need to change those. I sure fucking hope we don't.
                    final DBGuild dbGuild = ctx.getDBGuild();
                    User proposingUser = ctx.getAuthor();
                    User proposedToUser = ctx.getMentionedUsers().get(0);
                    // This is just for checking purposes, so we don't need the DBUser itself.
                    UserData proposingUserData = ctx.getDBUser(proposingUser).getData();
                    UserData proposedToUserData = ctx.getDBUser(proposedToUser).getData();
                    // Again just for checking, and no need to change.
                    final Inventory proposingPlayerInventory = ctx.getPlayer(proposingUser).getInventory();
                    // Why would you do this...
                    if (proposedToUser.getId().equals(ctx.getAuthor().getId())) {
                        ctx.sendLocalized("commands.marry.marry_yourself_notice", EmoteReference.ERROR);
                        return;
                    }
                    final Marriage proposingMarriage = proposingUserData.getMarriage();
                    final Marriage proposedToMarriage = proposedToUserData.getMarriage();
                    // Proposed to is a bot user, cannot marry bots, this is still not 2100.
                    if (proposedToUser.isBot()) {
                        ctx.sendLocalized("commands.marry.marry_bot_notice", EmoteReference.ERROR);
                        return;
                    }
                    // Already married to the same person you're proposing to.
                    if ((proposingMarriage != null && proposedToMarriage != null) && proposedToUserData.getMarriage().getId().equals(proposingMarriage.getId())) {
                        ctx.sendLocalized("commands.marry.already_married_receipt", EmoteReference.ERROR);
                        return;
                    }
                    // You're already married. Huh huh.
                    if (proposingMarriage != null) {
                        ctx.sendLocalized("commands.marry.already_married", EmoteReference.ERROR);
                        return;
                    }
                    // Receipt is married, cannot continue.
                    if (proposedToMarriage != null) {
                        ctx.sendLocalized("commands.marry.receipt_married", EmoteReference.ERROR);
                        return;
                    }
                    // Not enough rings to continue. Buy more rings w.
                    if (!proposingPlayerInventory.containsItem(ItemReference.RING) || proposingPlayerInventory.getAmount(ItemReference.RING) < 2) {
                        ctx.sendLocalized("commands.marry.no_ring", EmoteReference.ERROR);
                        return;
                    }
                    // Check for rate limit
                    if (!RatelimitUtils.ratelimit(rateLimiter, ctx, ctx.getLanguageContext().get("commands.marry.ratelimit_message"), false))
                        return;
                    // Send confirmation message.
                    ctx.sendLocalized("commands.marry.confirmation", EmoteReference.MEGA, proposedToUser.getName(), ctx.getAuthor().getName(), EmoteReference.STOPWATCH);
                    InteractiveOperations.create(ctx.getChannel(), ctx.getAuthor().getIdLong(), 120, (ie) -> {
                        // Ignore all messages from anyone that isn't the user we already proposed to. Waiting for confirmation...
                        if (!ie.getAuthor().getId().equals(proposedToUser.getId()))
                            return Operation.IGNORED;
                        // Replace prefix because people seem to think you have to add the prefix before saying yes.
                        String message = ie.getMessage().getContentRaw();
                        for (String s : ctx.getConfig().prefix) {
                            if (message.toLowerCase().startsWith(s)) {
                                message = message.substring(s.length());
                            }
                        }
                        String guildCustomPrefix = dbGuild.getData().getGuildCustomPrefix();
                        if (guildCustomPrefix != null && !guildCustomPrefix.isEmpty() && message.toLowerCase().startsWith(guildCustomPrefix)) {
                            message = message.substring(guildCustomPrefix.length());
                        }
                        // Lovely~ <3
                        if (message.equalsIgnoreCase("yes")) {
                            // Here we NEED to get the Player,
                            // User and Marriage objects once again
                            // to avoid race conditions or changes on those that might have happened on the 120 seconds that this lasted for.
                            // We need to check if the marriage is empty once again before continuing, also if we have enough rings!
                            // Else we end up with really annoying to debug bugs, lol.
                            Player proposingPlayer = ctx.getPlayer(proposingUser);
                            Player proposedToPlayer = ctx.getPlayer(proposedToUser);
                            DBUser proposingUserDB = ctx.getDBUser(proposingUser);
                            DBUser proposedToUserDB = ctx.getDBUser(proposedToUser);
                            final Marriage proposingMarriageFinal = proposingUserDB.getData().getMarriage();
                            final Marriage proposedToMarriageFinal = proposedToUserDB.getData().getMarriage();
                            if (proposingMarriageFinal != null) {
                                ctx.sendLocalized("commands.marry.already_married", EmoteReference.ERROR);
                                return Operation.COMPLETED;
                            }
                            if (proposedToMarriageFinal != null) {
                                ctx.sendLocalized("commands.marry.receipt_married", EmoteReference.ERROR);
                                return Operation.COMPLETED;
                            }
                            // LAST inventory check and ring assignment is gonna happen using those.
                            final Inventory proposingPlayerFinalInventory = proposingPlayer.getInventory();
                            final Inventory proposedToPlayerInventory = proposedToPlayer.getInventory();
                            if (proposingPlayerFinalInventory.getAmount(ItemReference.RING) < 2) {
                                ctx.sendLocalized("commands.marry.ring_check_fail", EmoteReference.ERROR);
                                return Operation.COMPLETED;
                            }
                            // Remove the ring from the proposing player inventory.
                            proposingPlayerFinalInventory.process(new ItemStack(ItemReference.RING, -1));
                            // Silently scrape the rings if the receipt has more than 5000 rings.
                            if (proposedToPlayerInventory.getAmount(ItemReference.RING) < 5000) {
                                proposedToPlayerInventory.process(new ItemStack(ItemReference.RING, 1));
                            }
                            final long marriageCreationMillis = Instant.now().toEpochMilli();
                            // Onto the UUID we need to encode userId + timestamp of
                            // the proposing player and the proposed to player after the acceptance is done.
                            String marriageId = new UUID(proposingUser.getIdLong(), proposedToUser.getIdLong()).toString();
                            // Make and save the new marriage object.
                            Marriage actualMarriage = Marriage.of(marriageId, proposingUser, proposedToUser);
                            actualMarriage.getData().setMarriageCreationMillis(marriageCreationMillis);
                            actualMarriage.save();
                            // Assign the marriage ID to the respective users and save it.
                            proposingUserDB.getData().setMarriageId(marriageId);
                            proposedToUserDB.getData().setMarriageId(marriageId);
                            proposingUserDB.save();
                            proposedToUserDB.save();
                            // Send marriage confirmation message.
                            ctx.sendLocalized("commands.marry.accepted", EmoteReference.POPPER, ie.getAuthor().getName(), ie.getAuthor().getDiscriminator(), proposingUser.getName(), proposingUser.getDiscriminator());
                            // Add the badge to the married couple.
                            proposingPlayer.getData().addBadgeIfAbsent(Badge.MARRIED);
                            proposedToPlayer.getData().addBadgeIfAbsent(Badge.MARRIED);
                            // Give a love letter both to the proposing player and the one who was proposed to.
                            if (proposingPlayerFinalInventory.getAmount(ItemReference.LOVE_LETTER) < 5000) {
                                proposingPlayerFinalInventory.process(new ItemStack(ItemReference.LOVE_LETTER, 1));
                            }
                            if (proposedToPlayerInventory.getAmount(ItemReference.LOVE_LETTER) < 5000) {
                                proposedToPlayerInventory.process(new ItemStack(ItemReference.LOVE_LETTER, 1));
                            }
                            // Badge assignment saving.
                            proposingPlayer.save();
                            proposedToPlayer.save();
                            return Operation.COMPLETED;
                        }
                        if (message.equalsIgnoreCase("no")) {
                            ctx.sendLocalized("commands.marry.denied", EmoteReference.CORRECT, proposingUser.getName());
                            // Well, we have a badge for this too. Consolation prize I guess.
                            final Player proposingPlayer = ctx.getPlayer(proposingUser);
                            if (proposingPlayer.getData().addBadgeIfAbsent(Badge.DENIED)) {
                                proposingPlayer.saveUpdating();
                            }
                            return Operation.COMPLETED;
                        }
                        return Operation.IGNORED;
                    });
                }
            };
        }

        @Override
        public HelpContent help() {
            return new HelpContent.Builder().setDescription("Basically marries you with a user.").setUsage("`~>marry <@mention>` - Propose to someone\n" + "`~>marry <command>`").addParameter("@mention", "The person to propose to").addParameter("command", "The subcommand you can use. Check the subcommands section for a list and usage of each.").build();
        }
    });
    marryCommand.addSubCommand("createletter", new SubCommand() {

        @Override
        public String description() {
            return "Create a love letter for your marriage. Usage: `~>marry createletter <content>`";
        }

        @Override
        protected void call(Context ctx, I18nContext languageContext, String content) {
            final User author = ctx.getAuthor();
            Player player = ctx.getPlayer();
            Inventory playerInventory = player.getInventory();
            DBUser dbUser = ctx.getDBUser();
            // Without one love letter we cannot do much, ya know.
            if (playerInventory.containsItem(ItemReference.LOVE_LETTER)) {
                final Marriage currentMarriage = dbUser.getData().getMarriage();
                // that the love letter is less than 1500 characters long.
                if (currentMarriage == null) {
                    ctx.sendLocalized("commands.marry.loveletter.no_marriage", EmoteReference.SAD);
                    return;
                }
                if (currentMarriage.getData().getLoveLetter() != null) {
                    ctx.sendLocalized("commands.marry.loveletter.already_done", EmoteReference.ERROR);
                    return;
                }
                if (content.isEmpty()) {
                    ctx.sendLocalized("commands.marry.loveletter.empty", EmoteReference.ERROR);
                    return;
                }
                if (content.length() > 500) {
                    ctx.sendLocalized("commands.marry.loveletter.too_long", EmoteReference.ERROR);
                    return;
                }
                // Can we find the user this is married to?
                final User marriedTo = ctx.retrieveUserById(currentMarriage.getOtherPlayer(author.getId()));
                if (marriedTo == null) {
                    ctx.sendLocalized("commands.marry.loveletter.cannot_see", EmoteReference.ERROR);
                    return;
                }
                // Send a confirmation message.
                String finalContent = Utils.DISCORD_INVITE.matcher(content).replaceAll("-invite link-");
                finalContent = Utils.DISCORD_INVITE_2.matcher(finalContent).replaceAll("-invite link-");
                ctx.sendStrippedLocalized("commands.marry.loveletter.confirmation", EmoteReference.TALKING, marriedTo.getName(), marriedTo.getDiscriminator(), finalContent);
                // Start the operation.
                InteractiveOperations.create(ctx.getChannel(), author.getIdLong(), 60, e -> {
                    if (!e.getAuthor().getId().equals(author.getId())) {
                        return Operation.IGNORED;
                    }
                    // Replace prefix because people seem to think you have to add the prefix before saying yes.
                    String c = e.getMessage().getContentRaw();
                    for (String s : ctx.getConfig().prefix) {
                        if (c.toLowerCase().startsWith(s)) {
                            c = c.substring(s.length());
                        }
                    }
                    String guildCustomPrefix = ctx.getDBGuild().getData().getGuildCustomPrefix();
                    if (guildCustomPrefix != null && !guildCustomPrefix.isEmpty() && c.toLowerCase().startsWith(guildCustomPrefix)) {
                        c = c.substring(guildCustomPrefix.length());
                    }
                    // Confirmed they want to save this as the permanent love letter.
                    if (c.equalsIgnoreCase("yes")) {
                        final Player playerFinal = ctx.getPlayer();
                        final Inventory inventoryFinal = playerFinal.getInventory();
                        final Marriage currentMarriageFinal = dbUser.getData().getMarriage();
                        // We need to do most of the checks all over again just to make sure nothing important slipped through.
                        if (currentMarriageFinal == null) {
                            ctx.sendLocalized("commands.marry.loveletter.no_marriage", EmoteReference.SAD);
                            return Operation.COMPLETED;
                        }
                        if (!inventoryFinal.containsItem(ItemReference.LOVE_LETTER)) {
                            ctx.sendLocalized("commands.marry.loveletter.no_letter", EmoteReference.SAD);
                            return Operation.COMPLETED;
                        }
                        // Remove the love letter from the inventory.
                        inventoryFinal.process(new ItemStack(ItemReference.LOVE_LETTER, -1));
                        playerFinal.save();
                        // Save the love letter. The content variable is the actual letter, while c is the content of the operation itself.
                        // Yes it's confusing.
                        currentMarriageFinal.getData().setLoveLetter(content);
                        currentMarriageFinal.save();
                        ctx.sendLocalized("commands.marry.loveletter.confirmed", EmoteReference.CORRECT);
                        return Operation.COMPLETED;
                    } else if (c.equalsIgnoreCase("no")) {
                        ctx.sendLocalized("commands.marry.loveletter.scrapped", EmoteReference.CORRECT);
                        return Operation.COMPLETED;
                    }
                    return Operation.IGNORED;
                });
            } else {
                ctx.sendLocalized("commands.marry.loveletter.no_letter", EmoteReference.SAD);
            }
        }
    });
    marryCommand.addSubCommand("house", new SubCommand() {

        @Override
        public String description() {
            return "Buys a house to live in. You need to buy a house in market first. Usage: `~>marry buyhouse <name>`";
        }

        @Override
        protected void call(Context ctx, I18nContext languageContext, String content) {
            var player = ctx.getPlayer();
            var playerInventory = player.getInventory();
            var dbUser = ctx.getDBUser();
            var marriage = dbUser.getData().getMarriage();
            if (marriage == null) {
                ctx.sendLocalized("commands.marry.buyhouse.not_married", EmoteReference.ERROR);
                return;
            }
            if (!playerInventory.containsItem(ItemReference.HOUSE)) {
                ctx.sendLocalized("commands.marry.buyhouse.no_house", EmoteReference.ERROR);
                return;
            }
            if (player.getCurrentMoney() < housePrice) {
                ctx.sendLocalized("commands.marry.buyhouse.not_enough_money", EmoteReference.ERROR, housePrice);
                return;
            }
            content = content.replace("\n", "").trim();
            if (content.isEmpty()) {
                ctx.sendLocalized("commands.marry.buyhouse.no_name", EmoteReference.ERROR);
                return;
            }
            if (content.length() > 150) {
                ctx.sendLocalized("commands.pet.buy.too_long", EmoteReference.ERROR);
                return;
            }
            var finalContent = Utils.HTTP_URL.matcher(content).replaceAll("-url-");
            ctx.sendLocalized("commands.marry.buyhouse.confirm", EmoteReference.WARNING, housePrice, finalContent);
            InteractiveOperations.create(ctx.getChannel(), ctx.getAuthor().getIdLong(), 30, (e) -> {
                if (!e.getAuthor().equals(ctx.getAuthor()))
                    return Operation.IGNORED;
                if (e.getMessage().getContentRaw().equalsIgnoreCase("yes")) {
                    var playerConfirmed = ctx.getPlayer();
                    var playerInventoryConfirmed = playerConfirmed.getInventory();
                    var dbUserConfirmed = ctx.getDBUser();
                    var marriageConfirmed = dbUserConfirmed.getData().getMarriage();
                    // People like to mess around lol.
                    if (!playerInventoryConfirmed.containsItem(ItemReference.HOUSE)) {
                        ctx.sendLocalized("commands.marry.buyhouse.no_house");
                        return Operation.COMPLETED;
                    }
                    if (playerConfirmed.getCurrentMoney() < housePrice) {
                        ctx.sendLocalized("commands.marry.buyhouse.not_enough_money");
                        return Operation.COMPLETED;
                    }
                    playerInventoryConfirmed.process(new ItemStack(ItemReference.HOUSE, -1));
                    playerConfirmed.removeMoney(housePrice);
                    playerConfirmed.save();
                    marriageConfirmed.getData().setHasHouse(true);
                    marriageConfirmed.getData().setHouseName(finalContent);
                    marriageConfirmed.save();
                    ctx.sendLocalized("commands.marry.buyhouse.success", EmoteReference.POPPER, housePrice, finalContent);
                    return Operation.COMPLETED;
                }
                if (e.getMessage().getContentRaw().equalsIgnoreCase("no")) {
                    ctx.sendLocalized("commands.marry.buyhouse.cancel_success", EmoteReference.CORRECT);
                    return Operation.COMPLETED;
                }
                return Operation.IGNORED;
            });
        }
    }).createSubCommandAlias("house", "buyhouse");
    marryCommand.addSubCommand("car", new SubCommand() {

        @Override
        public String description() {
            return "Buys a car to travel in. You need to buy a ~~cat~~ car in market first. Usage: `~>marry buycar <name>`";
        }

        @Override
        protected void call(Context ctx, I18nContext languageContext, String content) {
            var player = ctx.getPlayer();
            var playerInventory = player.getInventory();
            var dbUser = ctx.getDBUser();
            var marriage = dbUser.getData().getMarriage();
            if (marriage == null) {
                ctx.sendLocalized("commands.marry.general.not_married", EmoteReference.ERROR);
                return;
            }
            if (!playerInventory.containsItem(ItemReference.CAR)) {
                ctx.sendLocalized("commands.marry.buycar.no_car", EmoteReference.ERROR);
                return;
            }
            if (player.getCurrentMoney() < carPrice) {
                ctx.sendLocalized("commands.marry.buycar.not_enough_money", EmoteReference.ERROR, carPrice);
                return;
            }
            if (content.isEmpty()) {
                ctx.sendLocalized("commands.marry.buycar.no_name", EmoteReference.ERROR);
                return;
            }
            content = content.replace("\n", "").trim();
            if (content.length() > 150) {
                ctx.sendLocalized("commands.pet.buy.too_long", EmoteReference.ERROR);
                return;
            }
            var finalContent = Utils.HTTP_URL.matcher(content).replaceAll("-url-");
            ctx.sendLocalized("commands.marry.buycar.confirm", EmoteReference.WARNING, carPrice, content);
            InteractiveOperations.create(ctx.getChannel(), ctx.getAuthor().getIdLong(), 30, (e) -> {
                if (!e.getAuthor().equals(ctx.getAuthor()))
                    return Operation.IGNORED;
                if (e.getMessage().getContentRaw().equalsIgnoreCase("yes")) {
                    var playerConfirmed = ctx.getPlayer();
                    var playerInventoryConfirmed = playerConfirmed.getInventory();
                    var dbUserConfirmed = ctx.getDBUser();
                    var marriageConfirmed = dbUserConfirmed.getData().getMarriage();
                    // People like to mess around lol.
                    if (!playerInventoryConfirmed.containsItem(ItemReference.CAR)) {
                        ctx.sendLocalized("commands.marry.buycar.no_car");
                        return Operation.COMPLETED;
                    }
                    if (playerConfirmed.getCurrentMoney() < carPrice) {
                        ctx.sendLocalized("commands.marry.buycar.not_enough_money");
                        return Operation.COMPLETED;
                    }
                    playerInventoryConfirmed.process(new ItemStack(ItemReference.CAR, -1));
                    playerConfirmed.removeMoney(carPrice);
                    playerConfirmed.save();
                    marriageConfirmed.getData().setHasCar(true);
                    marriageConfirmed.getData().setCarName(finalContent);
                    marriageConfirmed.save();
                    ctx.sendLocalized("commands.marry.buycar.success", EmoteReference.POPPER, carPrice, finalContent);
                    return Operation.COMPLETED;
                }
                if (e.getMessage().getContentRaw().equalsIgnoreCase("no")) {
                    ctx.sendLocalized("commands.marry.buycar.cancel_success", EmoteReference.CORRECT);
                    return Operation.COMPLETED;
                }
                return Operation.IGNORED;
            });
        }
    }).createSubCommandAlias("car", "buycar");
    IncreasingRateLimiter tzRatelimit = new IncreasingRateLimiter.Builder().limit(1).spamTolerance(2).cooldown(2, TimeUnit.DAYS).maxCooldown(2, TimeUnit.DAYS).randomIncrement(false).premiumAware(false).pool(MantaroData.getDefaultJedisPool()).prefix("marriage-tz").build();
    marryCommand.addSubCommand("timezone", new SubCommand() {

        @Override
        public String description() {
            return "Sets the timezone for your marriage. Useful for pet sleep times.";
        }

        @Override
        protected void call(Context ctx, I18nContext languageContext, String content) {
            var dbUser = ctx.getDBUser();
            var marriage = dbUser.getData().getMarriage();
            if (content.isEmpty()) {
                ctx.sendLocalized("commands.marry.timezone.no_content", EmoteReference.ERROR);
                return;
            }
            if (marriage == null) {
                ctx.sendLocalized("commands.marry.general.not_married", EmoteReference.ERROR);
                return;
            }
            String timezone = content;
            if (// Avoid replacing valid zone IDs / uppercasing them.
            offsetRegex.matcher(timezone).matches())
                timezone = content.toUpperCase().replace("UTC", "GMT");
            if (!Utils.isValidTimeZone(timezone)) {
                ctx.sendLocalized("commands.marry.timezone.invalid", EmoteReference.ERROR);
                return;
            }
            if (!RatelimitUtils.ratelimit(tzRatelimit, ctx)) {
                return;
            }
            marriage.getData().setTimezone(timezone);
            marriage.save();
            dbUser.save();
            ctx.sendLocalized("commands.marry.timezone.success", EmoteReference.CORRECT, timezone);
        }
    });
    marryCommand.addSubCommand("status", new SubCommand() {

        @Override
        public String description() {
            return "Check your marriage status.";
        }

        @Override
        protected void call(Context ctx, I18nContext languageContext, String content) {
            if (!ctx.getSelfMember().hasPermission(ctx.getChannel(), Permission.MESSAGE_EMBED_LINKS)) {
                ctx.sendLocalized("general.missing_embed_permissions");
                return;
            }
            final var author = ctx.getAuthor();
            final var dbUser = ctx.getDBUser();
            final var dbUserData = dbUser.getData();
            final var currentMarriage = dbUserData.getMarriage();
            // What status would we have without marriage? Well, we can be unmarried omegalul.
            if (currentMarriage == null) {
                ctx.sendLocalized("commands.marry.status.no_marriage", EmoteReference.SAD);
                return;
            }
            final var data = currentMarriage.getData();
            // Can we find the user this is married to?
            final var marriedTo = ctx.retrieveUserById(currentMarriage.getOtherPlayer(author.getId()));
            if (marriedTo == null) {
                ctx.sendLocalized("commands.marry.loveletter.cannot_see", EmoteReference.ERROR);
                return;
            }
            // Get the current love letter.
            var loveLetter = data.getLoveLetter();
            if (loveLetter == null || loveLetter.isEmpty()) {
                loveLetter = languageContext.get("general.none");
            }
            final var marriedDBUser = ctx.getDBUser(marriedTo);
            final var dateFormat = Utils.formatDate(data.getMarriageCreationMillis(), dbUserData.getLang());
            final var eitherHasWaifus = !(dbUserData.getWaifus().isEmpty() && marriedDBUser.getData().getWaifus().isEmpty());
            final var marriedToName = dbUserData.isPrivateTag() ? marriedTo.getName() : marriedTo.getAsTag();
            final var authorName = dbUserData.isPrivateTag() ? author.getName() : author.getAsTag();
            final var daysMarried = TimeUnit.of(ChronoUnit.MILLIS).toDays(System.currentTimeMillis() - data.getMarriageCreationMillis());
            EmbedBuilder embedBuilder = new EmbedBuilder().setThumbnail(author.getEffectiveAvatarUrl()).setAuthor(languageContext.get("commands.marry.status.header"), null, author.getEffectiveAvatarUrl()).setColor(ctx.getMemberColor()).setDescription(languageContext.get("commands.marry.status.description_format").formatted(EmoteReference.HEART, authorName, marriedToName)).addField(EmoteReference.CALENDAR2.toHeaderString() + languageContext.get("commands.marry.status.date"), dateFormat, false).addField(EmoteReference.CLOCK.toHeaderString() + languageContext.get("commands.marry.status.age"), daysMarried + " " + languageContext.get("general.days"), false).addField(EmoteReference.LOVE_LETTER.toHeaderString() + languageContext.get("commands.marry.status.love_letter"), loveLetter, false).addField(EmoteReference.ZAP.toHeaderString() + languageContext.get("commands.marry.status.waifus"), String.valueOf(eitherHasWaifus), false).setFooter("Marriage ID: " + currentMarriage.getId(), author.getEffectiveAvatarUrl());
            if (data.hasHouse()) {
                var houseName = data.getHouseName().replace("\n", "").trim();
                embedBuilder.addField(EmoteReference.HOUSE.toHeaderString() + languageContext.get("commands.marry.status.house"), houseName, true);
            }
            if (data.hasCar()) {
                var carName = data.getCarName().replace("\n", "").trim();
                embedBuilder.addField(EmoteReference.CAR.toHeaderString() + languageContext.get("commands.marry.status.car"), carName, true);
            }
            if (data.getPet() != null) {
                var pet = data.getPet();
                var petType = data.getPet().getType();
                embedBuilder.addField(EmoteReference.PET_HOUSE.toHeaderString() + languageContext.get("commands.marry.status.pet"), pet.getName() + " (" + petType.getName() + ")", false);
            }
            ctx.send(embedBuilder.build());
        }
    }).createSubCommandAlias("status", "stats");
    cr.registerAlias("marry", "marriage");
}
Also used : Context(net.kodehawa.mantarobot.core.modules.commands.base.Context) I18nContext(net.kodehawa.mantarobot.core.modules.commands.i18n.I18nContext) Badge(net.kodehawa.mantarobot.commands.currency.profile.Badge) Color(java.awt.Color) Module(net.kodehawa.mantarobot.core.modules.Module) Command(net.kodehawa.mantarobot.core.modules.commands.base.Command) HelpContent(net.kodehawa.mantarobot.core.modules.commands.help.HelpContent) Permission(net.dv8tion.jda.api.Permission) Utils(net.kodehawa.mantarobot.utils.Utils) User(net.dv8tion.jda.api.entities.User) ITreeCommand(net.kodehawa.mantarobot.core.modules.commands.base.ITreeCommand) CommandRegistry(net.kodehawa.mantarobot.core.CommandRegistry) DBUser(net.kodehawa.mantarobot.db.entities.DBUser) Inventory(net.kodehawa.mantarobot.db.entities.helpers.Inventory) Subscribe(com.google.common.eventbus.Subscribe) SimpleCommand(net.kodehawa.mantarobot.core.modules.commands.SimpleCommand) Context(net.kodehawa.mantarobot.core.modules.commands.base.Context) ItemStack(net.kodehawa.mantarobot.commands.currency.item.ItemStack) Player(net.kodehawa.mantarobot.db.entities.Player) SubCommand(net.kodehawa.mantarobot.core.modules.commands.SubCommand) UserData(net.kodehawa.mantarobot.db.entities.helpers.UserData) ItemReference(net.kodehawa.mantarobot.commands.currency.item.ItemReference) InteractiveOperations(net.kodehawa.mantarobot.core.listeners.operations.InteractiveOperations) Marriage(net.kodehawa.mantarobot.db.entities.Marriage) IncreasingRateLimiter(net.kodehawa.mantarobot.utils.commands.ratelimit.IncreasingRateLimiter) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) UUID(java.util.UUID) Instant(java.time.Instant) DBGuild(net.kodehawa.mantarobot.db.entities.DBGuild) TreeCommand(net.kodehawa.mantarobot.core.modules.commands.TreeCommand) TimeUnit(java.util.concurrent.TimeUnit) RatelimitUtils(net.kodehawa.mantarobot.utils.commands.ratelimit.RatelimitUtils) ChronoUnit(java.time.temporal.ChronoUnit) CommandCategory(net.kodehawa.mantarobot.core.modules.commands.base.CommandCategory) I18nContext(net.kodehawa.mantarobot.core.modules.commands.i18n.I18nContext) EmoteReference(net.kodehawa.mantarobot.utils.commands.EmoteReference) MantaroData(net.kodehawa.mantarobot.data.MantaroData) Pattern(java.util.regex.Pattern) Operation(net.kodehawa.mantarobot.core.listeners.operations.core.Operation) Player(net.kodehawa.mantarobot.db.entities.Player) SubCommand(net.kodehawa.mantarobot.core.modules.commands.SubCommand) User(net.dv8tion.jda.api.entities.User) DBUser(net.kodehawa.mantarobot.db.entities.DBUser) UserData(net.kodehawa.mantarobot.db.entities.helpers.UserData) HelpContent(net.kodehawa.mantarobot.core.modules.commands.help.HelpContent) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) IncreasingRateLimiter(net.kodehawa.mantarobot.utils.commands.ratelimit.IncreasingRateLimiter) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) DBGuild(net.kodehawa.mantarobot.db.entities.DBGuild) Command(net.kodehawa.mantarobot.core.modules.commands.base.Command) ITreeCommand(net.kodehawa.mantarobot.core.modules.commands.base.ITreeCommand) SimpleCommand(net.kodehawa.mantarobot.core.modules.commands.SimpleCommand) SubCommand(net.kodehawa.mantarobot.core.modules.commands.SubCommand) TreeCommand(net.kodehawa.mantarobot.core.modules.commands.TreeCommand) ITreeCommand(net.kodehawa.mantarobot.core.modules.commands.base.ITreeCommand) DBUser(net.kodehawa.mantarobot.db.entities.DBUser) ItemStack(net.kodehawa.mantarobot.commands.currency.item.ItemStack) UUID(java.util.UUID) Marriage(net.kodehawa.mantarobot.db.entities.Marriage) ITreeCommand(net.kodehawa.mantarobot.core.modules.commands.base.ITreeCommand) TreeCommand(net.kodehawa.mantarobot.core.modules.commands.TreeCommand) Inventory(net.kodehawa.mantarobot.db.entities.helpers.Inventory) I18nContext(net.kodehawa.mantarobot.core.modules.commands.i18n.I18nContext) Subscribe(com.google.common.eventbus.Subscribe)

Aggregations

Context (net.kodehawa.mantarobot.core.modules.commands.base.Context)20 HelpContent (net.kodehawa.mantarobot.core.modules.commands.help.HelpContent)18 Subscribe (com.google.common.eventbus.Subscribe)17 EmoteReference (net.kodehawa.mantarobot.utils.commands.EmoteReference)16 MantaroData (net.kodehawa.mantarobot.data.MantaroData)15 CommandCategory (net.kodehawa.mantarobot.core.modules.commands.base.CommandCategory)14 I18nContext (net.kodehawa.mantarobot.core.modules.commands.i18n.I18nContext)14 CommandRegistry (net.kodehawa.mantarobot.core.CommandRegistry)13 Module (net.kodehawa.mantarobot.core.modules.Module)13 Utils (net.kodehawa.mantarobot.utils.Utils)13 SimpleCommand (net.kodehawa.mantarobot.core.modules.commands.SimpleCommand)12 IncreasingRateLimiter (net.kodehawa.mantarobot.utils.commands.ratelimit.IncreasingRateLimiter)12 List (java.util.List)11 TimeUnit (java.util.concurrent.TimeUnit)11 Collectors (java.util.stream.Collectors)11 EmbedBuilder (net.dv8tion.jda.api.EmbedBuilder)11 RatelimitUtils (net.kodehawa.mantarobot.utils.commands.ratelimit.RatelimitUtils)10 Badge (net.kodehawa.mantarobot.commands.currency.profile.Badge)9 DiscordUtils (net.kodehawa.mantarobot.utils.commands.DiscordUtils)9 Color (java.awt.Color)8