use of net.kodehawa.mantarobot.core.modules.commands.i18n.I18nContext in project MantaroBot by Mantaro.
the class I18nTest method testI18n.
@Test
public void testI18n() throws LanguageKeyNotFoundException {
// Should default to en_US
I18nContext context = new I18nContext(new GuildData(), null);
Assertions.assertEquals("en_US", context.getContextLanguage());
String localized = context.get("test.inherited");
Assertions.assertNotNull(localized);
Assertions.assertEquals("owo", localized);
}
use of net.kodehawa.mantarobot.core.modules.commands.i18n.I18nContext in project MantaroBot by Mantaro.
the class WaifuCmd method waifu.
@Subscribe
public void waifu(CommandRegistry cr) {
IncreasingRateLimiter rl = new IncreasingRateLimiter.Builder().limit(1).spamTolerance(2).cooldown(5, TimeUnit.SECONDS).maxCooldown(5, TimeUnit.SECONDS).randomIncrement(true).pool(MantaroData.getDefaultJedisPool()).prefix("waifu").build();
TreeCommand waifu = cr.register("waifu", 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) {
// IMPLEMENTATION NOTES FOR THE WAIFU SYSTEM
// You get 3 free slots to put "waifus" in.
// Each extra slot (up to 9) costs exponentially more than the last one (2x more than the costs of the last one)
// Every waifu has a "claim" price which increases in the following situations:
// For every 100000 money owned, it increases by 3% base value (base: 1500)
// For every 10 badges, it increases by 20% base value.
// For every 1000 experience, the value increases by 20% of the base value.
// After all those calculations are complete,
// the value then is calculated using final * (reputation scale / 10)
// where reputation scale goes up by 1 every 10 reputation points.
// Maximum waifu value is Integer.MAX_VALUE.
// Having a common waifu with your married partner will increase some marriage stats.
// If you claim a waifu, and then your waifu claims you, that will unlock the "Mutual" achievement.
// If the waifu status is mutual,
// the MP game boost will go up by 20% and giving your daily to that waifu will increase the amount of money that your
// waifu will receive.
final var opts = ctx.getOptionalArguments();
// Default call will bring out the waifu list.
final var dbUser = ctx.getDBUser();
final var userData = dbUser.getData();
final var player = ctx.getPlayer();
if (player.getData().isWaifuout()) {
ctx.sendLocalized("commands.waifu.optout.notice", EmoteReference.ERROR);
return;
}
if (!ctx.getSelfMember().hasPermission(ctx.getChannel(), Permission.MESSAGE_EMBED_LINKS)) {
ctx.sendLocalized("general.missing_embed_permissions");
return;
}
final var description = userData.getWaifus().isEmpty() ? languageContext.get("commands.waifu.waifu_header") + "\n" + languageContext.get("commands.waifu.no_waifu") : languageContext.get("commands.waifu.waifu_header");
final var waifusEmbed = new EmbedBuilder().setAuthor(languageContext.get("commands.waifu.header"), null, ctx.getAuthor().getEffectiveAvatarUrl()).setThumbnail("https://i.imgur.com/2JlMtCe.png").setColor(Color.CYAN).setFooter(languageContext.get("commands.waifu.footer").formatted(userData.getWaifus().size(), userData.getWaifuSlots() - userData.getWaifus().size()), null);
if (userData.getWaifus().isEmpty()) {
waifusEmbed.setDescription(description);
ctx.send(waifusEmbed.build());
return;
}
final var id = opts.containsKey("id");
List<String> toRemove = new ArrayList<>();
List<MessageEmbed.Field> fields = new LinkedList<>();
for (String waifu : userData.getWaifus().keySet()) {
// This fixes the issue of cross-node waifus not appearing.
User user = ctx.retrieveUserById(waifu);
if (user == null) {
fields.add(new MessageEmbed.Field("%sUnknown User (ID: %s)".formatted(EmoteReference.BLUE_SMALL_MARKER, waifu), languageContext.get("commands.waifu.value_format") + " unknown\n" + languageContext.get("commands.waifu.value_b_format") + " " + userData.getWaifus().get(waifu) + languageContext.get("commands.waifu.credits_format"), false));
} else {
Player waifuClaimed = ctx.getPlayer(user);
if (waifuClaimed.getData().isWaifuout()) {
toRemove.add(waifu);
continue;
}
fields.add(new MessageEmbed.Field(EmoteReference.BLUE_SMALL_MARKER + user.getName() + (!userData.isPrivateTag() ? "#" + user.getDiscriminator() : ""), (id ? languageContext.get("commands.waifu.id") + " " + user.getId() + "\n" : "") + languageContext.get("commands.waifu.value_format") + " " + waifuClaimed.getData().getWaifuCachedValue() + " " + languageContext.get("commands.waifu.credits_format") + "\n" + languageContext.get("commands.waifu.value_b_format") + " " + userData.getWaifus().get(waifu) + languageContext.get("commands.waifu.credits_format"), false));
}
}
final var toSend = languageContext.get("commands.waifu.description_header").formatted(userData.getWaifuSlots()) + description;
DiscordUtils.sendPaginatedEmbed(ctx, waifusEmbed, DiscordUtils.divideFields(4, fields), toSend);
if (!toRemove.isEmpty()) {
for (String remove : toRemove) {
dbUser.getData().getWaifus().remove(remove);
}
player.saveAsync();
}
}
};
}
@Override
public HelpContent help() {
return new HelpContent.Builder().setDescription("This command is the hub for all waifu operations. Yeah, it's all fiction.").setUsage("`~>waifu` - Shows a list of all your waifus and their current value.\n" + "`~>waifu [command] [@user]`").addParameterOptional("command", "The subcommand to use." + " Check the sub-command section for more information on which ones you can use.").addParameterOptional("@user", "The user you want to do the action with.").addParameterOptional("-id", "Shows the user id.").build();
}
});
cr.registerAlias("waifu", "waifus");
waifu.setPredicate(ctx -> RatelimitUtils.ratelimit(rl, ctx, false));
waifu.addSubCommand("optout", new SubCommand() {
@Override
public String description() {
return "Opt-out of the waifu stuff. This will disable the waifu system, remove all of your claims and make you unable to be claimed.";
}
@Override
protected void call(Context ctx, I18nContext languageContext, String content) {
final var player = ctx.getPlayer();
if (player.getData().isWaifuout()) {
ctx.sendLocalized("commands.waifu.optout.notice", EmoteReference.ERROR);
return;
}
ctx.sendLocalized("commands.waifu.optout.warning", EmoteReference.WARNING);
InteractiveOperations.create(ctx.getChannel(), ctx.getAuthor().getIdLong(), 60, e -> {
if (!e.getAuthor().getId().equals(ctx.getAuthor().getId())) {
return Operation.IGNORED;
}
final var c = e.getMessage().getContentRaw();
if (c.equalsIgnoreCase("Yes, I want to opt out of the waifu system completely and irreversibly")) {
player.getData().setWaifuout(true);
ctx.sendLocalized("commands.waifu.optout.success", EmoteReference.CORRECT);
player.saveUpdating();
return Operation.COMPLETED;
} else if (c.equalsIgnoreCase("no")) {
ctx.sendLocalized("commands.waifu.optout.cancelled", EmoteReference.CORRECT);
return Operation.COMPLETED;
}
return Operation.IGNORED;
});
}
});
waifu.addSubCommand("stats", new SubCommand() {
@Override
public String description() {
return "Shows your waifu stats or the stats or someone's (by mentioning them)";
}
@Override
protected void call(Context ctx, I18nContext languageContext, String content) {
final var player = ctx.getPlayer();
final var playerData = player.getData();
if (playerData.isWaifuout()) {
ctx.sendLocalized("commands.waifu.optout.notice", EmoteReference.ERROR);
return;
}
if (!ctx.getSelfMember().hasPermission(ctx.getChannel(), Permission.MESSAGE_EMBED_LINKS)) {
ctx.sendLocalized("general.missing_embed_permissions");
return;
}
ctx.findMember(content, members -> {
final var member = CustomFinderUtil.findMemberDefault(content, members, ctx, ctx.getMember());
if (member == null)
return;
final var toLookup = member.getUser();
if (toLookup.isBot()) {
ctx.sendLocalized("commands.waifu.bot", EmoteReference.ERROR);
return;
}
final var waifuClaimed = ctx.getPlayer(toLookup);
if (waifuClaimed.getData().isWaifuout()) {
ctx.sendLocalized("commands.waifu.optout.lookup_notice", EmoteReference.ERROR);
return;
}
final var waifuStats = calculateWaifuValue(waifuClaimed, toLookup);
final var finalValue = waifuStats.getFinalValue();
EmbedBuilder statsBuilder = new EmbedBuilder().setThumbnail(toLookup.getEffectiveAvatarUrl()).setAuthor(toLookup == ctx.getAuthor() ? languageContext.get("commands.waifu.stats.header") : languageContext.get("commands.waifu.stats.header_other").formatted(toLookup.getName()), null, toLookup.getEffectiveAvatarUrl()).setColor(Color.PINK).setDescription(languageContext.get("commands.waifu.stats.format").formatted(EmoteReference.BLUE_SMALL_MARKER, waifuStats.getMoneyValue(), waifuStats.getBadgeValue(), waifuStats.getExperienceValue(), waifuStats.getClaimValue(), waifuStats.getReputationMultiplier())).addField(EmoteReference.ZAP.toHeaderString() + languageContext.get("commands.waifu.stats.performance"), waifuStats.getPerformance() + "wp", true).addField(EmoteReference.MONEY.toHeaderString() + languageContext.get("commands.waifu.stats.value"), languageContext.get("commands.waifu.stats.credits").formatted(finalValue), false).setFooter(languageContext.get("commands.waifu.notice"), null);
ctx.send(statsBuilder.build());
});
}
});
waifu.addSubCommand("claim", new SubCommand() {
@Override
public String description() {
return "Claim a waifu. You need to mention the person you want to claim. Usage: `~>waifu claim <@mention>`";
}
@Override
protected void call(Context ctx, I18nContext languageContext, String content) {
final var player = ctx.getPlayer();
if (player.getData().isWaifuout()) {
ctx.sendLocalized("commands.waifu.optout.notice", EmoteReference.ERROR);
return;
}
if (ctx.getMentionedUsers().isEmpty()) {
ctx.sendLocalized("commands.waifu.claim.no_user", EmoteReference.ERROR);
return;
}
final var toLookup = ctx.getMentionedUsers().get(0);
if (toLookup.isBot()) {
ctx.sendLocalized("commands.waifu.bot", EmoteReference.ERROR);
return;
}
final var claimerPlayer = ctx.getPlayer();
final var claimerPlayerData = claimerPlayer.getData();
final var claimerUser = ctx.getDBUser();
final var claimerUserData = claimerUser.getData();
final var claimedPlayer = ctx.getPlayer(toLookup);
final var claimedPlayerData = claimedPlayer.getData();
final var claimedUser = ctx.getDBUser(toLookup);
final var claimedUserData = claimedUser.getData();
if (claimedPlayerData.isWaifuout()) {
ctx.sendLocalized("commands.waifu.optout.claim_notice", EmoteReference.ERROR);
return;
}
// Waifu object declaration.
final Waifu waifuToClaim = calculateWaifuValue(claimedPlayer, toLookup);
final long waifuFinalValue = waifuToClaim.getFinalValue();
// Checks.
if (toLookup.getIdLong() == ctx.getAuthor().getIdLong()) {
ctx.sendLocalized("commands.waifu.claim.yourself", EmoteReference.ERROR);
return;
}
if (claimerUser.getData().getWaifus().entrySet().stream().anyMatch((w) -> w.getKey().equals(toLookup.getId()))) {
ctx.sendLocalized("commands.waifu.claim.already_claimed", EmoteReference.ERROR);
return;
}
// If the to-be claimed has the claim key in their inventory, it cannot be claimed.
if (claimedPlayerData.isClaimLocked()) {
ctx.sendLocalized("commands.waifu.claim.key_locked", EmoteReference.ERROR);
return;
}
if (claimerPlayer.isLocked()) {
ctx.sendLocalized("commands.waifu.claim.locked", EmoteReference.ERROR);
return;
}
// Deduct from balance and checks for money.
if (!claimerPlayer.removeMoney(waifuFinalValue)) {
ctx.sendLocalized("commands.waifu.claim.not_enough_money", EmoteReference.ERROR, waifuFinalValue);
return;
}
if (claimerUserData.getWaifus().size() >= claimerUserData.getWaifuSlots()) {
ctx.sendLocalized("commands.waifu.claim.not_enough_slots", EmoteReference.ERROR, claimerUserData.getWaifuSlots(), claimerUserData.getWaifus().size());
return;
}
if (waifuFinalValue > 100_000) {
claimerPlayerData.addBadgeIfAbsent(Badge.GOLD_VALUE);
}
// Add waifu to claimer list.
claimerUserData.getWaifus().put(toLookup.getId(), waifuFinalValue);
claimedUserData.setTimesClaimed(claimedUserData.getTimesClaimed() + 1);
boolean badgesAdded = false;
// Add badges
if (claimedUserData.getWaifus().containsKey(ctx.getAuthor().getId()) && claimerUserData.getWaifus().containsKey(toLookup.getId())) {
claimerPlayerData.addBadgeIfAbsent(Badge.MUTUAL);
badgesAdded = claimedPlayerData.addBadgeIfAbsent(Badge.MUTUAL);
}
claimerPlayerData.addBadgeIfAbsent(Badge.WAIFU_CLAIMER);
if (badgesAdded || claimedPlayerData.addBadgeIfAbsent(Badge.CLAIMED)) {
claimedPlayer.saveAsync();
}
// Massive saving operation owo.
claimerPlayer.saveAsync();
claimedUser.saveAsync();
claimerUser.saveAsync();
// Send confirmation message
ctx.sendLocalized("commands.waifu.claim.success", EmoteReference.CORRECT, toLookup.getName(), waifuFinalValue, claimerUserData.getWaifus().size());
}
});
waifu.addSubCommand("unclaim", new SubCommand() {
@Override
public String description() {
return "Unclaims a waifu. You need to mention them, or you can also use their user id if they're not in any servers you share. Usage: `~>waifu unclaim <@mention>`";
}
@Override
protected void call(Context ctx, I18nContext languageContext, String content) {
final var optionalArguments = ctx.getOptionalArguments();
content = Utils.replaceArguments(optionalArguments, content, "unknown");
final var isId = content.matches("\\d{16,20}");
final var player = ctx.getPlayer();
if (player.getData().isWaifuout()) {
ctx.sendLocalized("commands.waifu.optout.notice", EmoteReference.ERROR);
return;
}
if (content.isEmpty() && !isId) {
ctx.sendLocalized("commands.waifu.unclaim.no_user", EmoteReference.ERROR);
return;
}
// This is hacky as heck, but assures us we get an empty result on id lookup.
final var lookup = isId ? "" : content;
// Lambdas strike again.
final var finalContent = content;
ctx.findMember(lookup, members -> {
// This is hacky again, but search *will* fail if we pass a empty list to this method.
final var member = isId ? null : CustomFinderUtil.findMember(lookup, members, ctx);
if (member == null && !isId) {
return;
}
final var toLookup = isId ? ctx.retrieveUserById(finalContent) : member.getUser();
final var isUnknown = isId && optionalArguments.containsKey("unknown") && toLookup == null;
if (toLookup == null && !isUnknown) {
ctx.sendLocalized("commands.waifu.unclaim.not_found", EmoteReference.ERROR);
return;
}
// It'll only be null if -unknown is passed with an unknown ID. This is unclaim, so this check is a bit irrelevant though.
if (!isUnknown && toLookup.isBot()) {
ctx.sendLocalized("commands.waifu.bot", EmoteReference.ERROR);
return;
}
final var userId = isUnknown ? finalContent : toLookup.getId();
final var name = isUnknown ? "Unknown User" : toLookup.getName();
final var claimerUser = ctx.getDBUser();
final var data = claimerUser.getData();
final var value = data.getWaifus().get(userId);
if (value == null) {
ctx.sendLocalized("commands.waifu.not_claimed", EmoteReference.ERROR);
return;
}
final var claimedPlayer = ctx.getPlayer(toLookup);
final var currentValue = calculateWaifuValue(claimedPlayer, toLookup).getFinalValue();
final var valuePayment = (long) (currentValue * 0.15);
// Send confirmation message.
ctx.sendLocalized("commands.waifu.unclaim.confirmation", EmoteReference.MEGA, name, valuePayment, EmoteReference.STOPWATCH);
InteractiveOperations.create(ctx.getChannel(), ctx.getAuthor().getIdLong(), 60, (ie) -> {
if (!ie.getAuthor().getId().equals(ctx.getAuthor().getId())) {
return Operation.IGNORED;
}
// Replace prefix because people seem to think you have to add the prefix before saying yes.
var ctn = ie.getMessage().getContentRaw();
for (var s : ctx.getConfig().prefix) {
if (ctn.toLowerCase().startsWith(s)) {
ctn = ctn.substring(s.length());
}
}
final var guildCustomPrefix = ctx.getDBGuild().getData().getGuildCustomPrefix();
if (guildCustomPrefix != null && !guildCustomPrefix.isEmpty() && ctn.toLowerCase().startsWith(guildCustomPrefix)) {
ctn = ctn.substring(guildCustomPrefix.length());
}
if (ctn.equalsIgnoreCase("yes")) {
final var p = ctx.getPlayer();
final var user = ctx.getDBUser();
final var userData = user.getData();
if (p.getCurrentMoney() < valuePayment) {
ctx.sendLocalized("commands.waifu.unclaim.not_enough_money", EmoteReference.ERROR);
return Operation.COMPLETED;
}
if (p.isLocked()) {
ctx.sendLocalized("commands.waifu.unclaim.player_locked", EmoteReference.ERROR);
return Operation.COMPLETED;
}
p.removeMoney(valuePayment);
userData.getWaifus().remove(userId);
user.save();
p.save();
ctx.sendLocalized("commands.waifu.unclaim.success", EmoteReference.CORRECT, name, valuePayment);
return Operation.COMPLETED;
} else if (ctn.equalsIgnoreCase("no")) {
ctx.sendLocalized("commands.waifu.unclaim.scrapped", EmoteReference.CORRECT);
return Operation.COMPLETED;
}
return Operation.IGNORED;
});
});
}
});
waifu.addSubCommand("buyslot", new SubCommand() {
@Override
public String description() {
return "Buys a new waifu slot. Maximum slots are 30, costs get increasingly higher.";
}
@Override
protected void call(Context ctx, I18nContext languageContext, String content) {
final var baseValue = 3000;
final var user = ctx.getDBUser();
final var player = ctx.getPlayer();
final var userData = user.getData();
if (player.getData().isWaifuout()) {
ctx.sendLocalized("commands.waifu.optout.notice", EmoteReference.ERROR);
return;
}
final var currentSlots = userData.getWaifuSlots();
final var baseMultiplier = (currentSlots / 3) + 1;
final var finalValue = baseValue * baseMultiplier;
if (player.isLocked()) {
ctx.sendLocalized("commands.waifu.buyslot.locked", EmoteReference.ERROR);
return;
}
if (player.getCurrentMoney() < finalValue) {
ctx.sendLocalized("commands.waifu.buyslot.not_enough_money", EmoteReference.ERROR, finalValue);
return;
}
if (userData.getWaifuSlots() >= 30) {
ctx.sendLocalized("commands.waifu.buyslot.too_many", EmoteReference.ERROR);
return;
}
player.removeMoney(finalValue);
userData.setWaifuSlots(currentSlots + 1);
user.save();
player.save();
ctx.sendLocalized("commands.waifu.buyslot.success", EmoteReference.CORRECT, finalValue, userData.getWaifuSlots(), (userData.getWaifuSlots() - userData.getWaifus().size()));
}
});
}
use of net.kodehawa.mantarobot.core.modules.commands.i18n.I18nContext in project MantaroBot by Mantaro.
the class LeaderboardCmd method richest.
@Subscribe
public void richest(CommandRegistry cr) {
final IncreasingRateLimiter rateLimiter = new IncreasingRateLimiter.Builder().spamTolerance(3).limit(1).cooldown(2, TimeUnit.SECONDS).cooldownPenaltyIncrease(20, TimeUnit.SECONDS).maxCooldown(5, TimeUnit.MINUTES).pool(MantaroData.getDefaultJedisPool()).prefix("leaderboard").build();
SimpleTreeCommand leaderboards = cr.register("leaderboard", new SimpleTreeCommand(CommandCategory.CURRENCY) {
@Override
public Command defaultTrigger(Context ctx, String mainCommand, String commandName) {
ctx.sendLocalized("commands.leaderboard.main_page_redirect", EmoteReference.PENCIL);
return null;
}
@Override
public HelpContent help() {
return new HelpContent.Builder().setDescription("Returns the currency leaderboard. See subcommands for the available leaderboards.").build();
}
});
leaderboards.setPredicate(ctx -> {
if (!ctx.getSelfMember().hasPermission(ctx.getChannel(), Permission.MESSAGE_EMBED_LINKS)) {
ctx.sendLocalized("general.missing_embed_permissions");
return false;
}
return RatelimitUtils.ratelimit(rateLimiter, ctx, null);
});
leaderboards.addSubCommand("gamble", new SubCommand() {
@Override
public String description() {
return "Returns the gamble (times) leaderboard";
}
@Override
protected void call(Context ctx, I18nContext languageContext, String content) {
var gambleLeaderboard = getLeaderboard("playerstats", "gambleWins", player -> player.pluck("id", "gambleWins"));
send(ctx, generateLeaderboardEmbed(ctx, languageContext.get("commands.leaderboard.inner.gamble").formatted(EmoteReference.MONEY), "commands.leaderboard.gamble", gambleLeaderboard, map -> Pair.of(getMember(ctx, map.get("id").toString().split(":")[0]), map.get("gambleWins").toString()), "%s**%s#%s** - %,d", false).build());
}
});
leaderboards.addSubCommand("slots", new SubCommand() {
@Override
public String description() {
return "Returns the slots (times) leaderboard";
}
@Override
protected void call(Context ctx, I18nContext languageContext, String content) {
var slotsLeaderboard = getLeaderboard("playerstats", "slotsWins", player -> player.pluck("id", "slotsWins"));
send(ctx, generateLeaderboardEmbed(ctx, languageContext.get("commands.leaderboard.inner.slots").formatted(EmoteReference.MONEY), "commands.leaderboard.slots", slotsLeaderboard, map -> Pair.of(getMember(ctx, map.get("id").toString().split(":")[0]), map.get("slotsWins").toString()), "%s**%s#%s** - %,d", false).build());
}
});
if (!config.isPremiumBot) {
leaderboards.addSubCommand("money", new SubCommand() {
@Override
public String description() {
return "Returns the money leaderboard";
}
@Override
@SuppressWarnings("unchecked")
protected void call(Context ctx, I18nContext languageContext, String content) {
var seasonal = ctx.isSeasonal();
var tableName = seasonal ? "seasonalplayers" : "players";
var indexName = seasonal ? "money" : "newMoney";
var moneyLeaderboard = getLeaderboard(tableName, indexName, player -> player.g("id"), player -> {
if (seasonal) {
return player.pluck("id", "money");
} else {
return player.pluck("id", "newMoney", r.hashMap("data", "newMoney"));
}
});
send(ctx, generateLeaderboardEmbed(ctx, seasonal ? languageContext.get("commands.leaderboard.inner.seasonal_money").formatted(EmoteReference.MONEY) : languageContext.get("commands.leaderboard.inner.money").formatted(EmoteReference.MONEY), "commands.leaderboard.money", moneyLeaderboard, map -> {
Object money;
if (seasonal) {
money = map.get("money");
} else {
money = ((Map<String, Object>) map.get("data")).get("newMoney");
}
return Pair.of(getMember(ctx, map.get("id").toString().split(":")[0]), money.toString());
}, "%s**%s#%s** - $%,d", seasonal).build());
}
});
}
leaderboards.addSubCommand(config.isPremiumBot ? "money" : "oldmoney", new SubCommand() {
@Override
public String description() {
if (config.isPremiumBot) {
return "Returns the money leaderboard";
} else {
return "Returns the (old) pre-reset money leaderboard";
}
}
@Override
protected void call(Context ctx, I18nContext languageContext, String content) {
var tableName = "players";
var moneyLeaderboard = getLeaderboard(tableName, "money", player -> player.g("id"), player -> player.pluck("id", "money"));
send(ctx, generateLeaderboardEmbed(ctx, languageContext.get("commands.leaderboard.inner.money_old").formatted(EmoteReference.MONEY), "commands.leaderboard.money", moneyLeaderboard, map -> Pair.of(getMember(ctx, map.get("id").toString().split(":")[0]), map.get("money").toString()), "%s**%s#%s** - $%,d", false).build());
}
});
leaderboards.addSubCommand("lvl", new SubCommand() {
@Override
public String description() {
return "Returns the level leaderboard";
}
@Override
protected void call(Context ctx, I18nContext languageContext, String content) {
var levelLeaderboard = getLeaderboard("players", "level", player -> player.g("id"), player -> player.pluck("id", "level", r.hashMap("data", "experience")));
send(ctx, generateLeaderboardEmbed(ctx, languageContext.get("commands.leaderboard.inner.lvl").formatted(EmoteReference.ZAP), "commands.leaderboard.level", levelLeaderboard, map -> {
@SuppressWarnings("unchecked") var experience = ((Map<String, Object>) map.get("data")).get("experience");
return Pair.of(getMember(ctx, map.get("id").toString().split(":")[0]), map.get("level").toString() + "\n -" + languageContext.get("commands.leaderboard.inner.experience") + ":** " + experience + "**");
}, "%s**%s#%s** - %s", false).build());
}
});
leaderboards.addSubCommand("rep", new SubCommand() {
@Override
public String description() {
return "Returns the reputation leaderboard";
}
@Override
protected void call(Context ctx, I18nContext languageContext, String content) {
var seasonal = ctx.isSeasonal();
var tableName = seasonal ? "seasonalplayers" : "players";
var reputationLeaderboard = getLeaderboard(tableName, "reputation", player -> player.g("id"), player -> player.pluck("id", "reputation"));
send(ctx, generateLeaderboardEmbed(ctx, languageContext.get("commands.leaderboard.inner.rep").formatted(EmoteReference.REP), "commands.leaderboard.reputation", reputationLeaderboard, map -> Pair.of(getMember(ctx, map.get("id").toString().split(":")[0]), map.get("reputation").toString()), "%s**%s#%s** - %,d", seasonal).build());
}
});
leaderboards.addSubCommand("streak", new SubCommand() {
@Override
public String description() {
return "Returns the daily streak leaderboard";
}
@Override
protected void call(Context ctx, I18nContext languageContext, String content) {
var dailyLeaderboard = getLeaderboard("players", "userDailyStreak", player -> player.g("id"), player -> player.pluck("id", r.hashMap("data", "dailyStrike")));
send(ctx, generateLeaderboardEmbed(ctx, languageContext.get("commands.leaderboard.inner.streak").formatted(EmoteReference.POPPER), "commands.leaderboard.daily", dailyLeaderboard, map -> {
@SuppressWarnings("unchecked") var strike = ((Map<String, Object>) (map.get("data"))).get("dailyStrike").toString();
return Pair.of(getMember(ctx, map.get("id").toString().split(":")[0]), strike);
}, "%s**%s#%s** - %sx", false).build());
}
});
leaderboards.addSubCommand("claim", new SubCommand() {
@Override
public String description() {
return "Returns the waifu claim leaderboard";
}
@Override
protected void call(Context ctx, I18nContext languageContext, String content) {
List<Map<String, Object>> claimLeaderboard = getLeaderboard("users", "timesClaimed", player -> player.pluck("id", r.hashMap("data", "timesClaimed")));
send(ctx, generateLeaderboardEmbed(ctx, languageContext.get("commands.leaderboard.inner.claim").formatted(EmoteReference.HEART), "commands.leaderboard.claim", claimLeaderboard, map -> {
@SuppressWarnings("unchecked") var timesClaimed = ((Map<String, Object>) (map.get("data"))).get("timesClaimed").toString();
return Pair.of(getMember(ctx, map.get("id").toString().split(":")[0]), timesClaimed);
}, "%s**%s#%s** - %,d", false).build());
}
});
leaderboards.addSubCommand("games", new SubCommand() {
@Override
public String description() {
return "Returns the games wins leaderboard";
}
@Override
protected void call(Context ctx, I18nContext languageContext, String content) {
var seasonal = ctx.isSeasonal();
var tableName = seasonal ? "seasonalplayers" : "players";
List<Map<String, Object>> gameLeaderboard = getLeaderboard(tableName, "gameWins", player -> player.g("id"), player -> player.pluck("id", r.hashMap("data", "gamesWon")));
send(ctx, generateLeaderboardEmbed(ctx, languageContext.get("commands.leaderboard.inner.game").formatted(EmoteReference.ZAP), "commands.leaderboard.game", gameLeaderboard, map -> {
@SuppressWarnings("unchecked") var gamesWon = ((Map<String, Object>) (map.get("data"))).get("gamesWon").toString();
return Pair.of(getMember(ctx, map.get("id").toString().split(":")[0]), gamesWon);
}, "%s**%s#%s** - %,d", seasonal).build());
}
});
leaderboards.createSubCommandAlias("rep", "reputation");
leaderboards.createSubCommandAlias("lvl", "level");
leaderboards.createSubCommandAlias("streak", "daily");
leaderboards.createSubCommandAlias("games", "wins");
cr.registerAlias("leaderboard", "richest");
cr.registerAlias("leaderboard", "top");
cr.registerAlias("leaderboard", "lb");
}
use of net.kodehawa.mantarobot.core.modules.commands.i18n.I18nContext in project MantaroBot by Mantaro.
the class BirthdayCmd method birthday.
@Subscribe
public void birthday(CommandRegistry registry) {
TreeCommand birthdayCommand = registry.register("birthday", new TreeCommand(CommandCategory.UTILS) {
@Override
public Command defaultTrigger(Context context, String mainCommand, String commandName) {
return new SubCommand() {
@Override
protected void call(Context ctx, I18nContext languageContext, String content) {
if (content.isEmpty()) {
ctx.sendLocalized("commands.birthday.no_content", EmoteReference.ERROR);
return;
}
// Twice. Yep.
var parseFormat = DateTimeFormatter.ofPattern("dd-MM-yyyy");
var displayFormat = DateTimeFormatter.ofPattern("dd-MM");
MonthDay birthdayDate;
String date;
var extra = "";
try {
String birthday;
birthday = content.replace("/", "-");
var parts = new ArrayList<>(Arrays.asList(birthday.split("-")));
if (Integer.parseInt(parts.get(0)) > 31 || Integer.parseInt(parts.get(1)) > 12) {
ctx.sendLocalized("commands.birthday.error_date", EmoteReference.ERROR);
return;
}
if (parts.size() > 2) {
ctx.sendLocalized("commands.birthday.new_format", EmoteReference.ERROR);
return;
}
// Add a year so it parses and saves using the old format. Yes, this is also cursed.
parts.add("2037");
date = String.join("-", parts);
birthdayDate = MonthDay.parse(birthday, displayFormat);
} catch (Exception e) {
ctx.sendStrippedLocalized("commands.birthday.error_date", EmoteReference.ERROR);
return;
}
final var display = displayFormat.format(birthdayDate);
// This whole leap year stuff is cursed when you work with dates using raw strings tbh.
// Only I could come up with such an idea like this on 2016. Now I regret it with pain... peko.
var leap = display.equals("29-02");
if (leap) {
extra += "\n" + languageContext.get("commands.birthday.leap");
// Cursed workaround since 2036 is a leap.
date = date.replace("2037", "2036");
}
final var birthdayFormat = parseFormat.format(parseFormat.parse(date));
// Actually save it to the user's profile.
DBUser dbUser = ctx.getDBUser();
dbUser.getData().setBirthday(birthdayFormat);
dbUser.saveUpdating();
ctx.sendLocalized("commands.birthday.added_birthdate", EmoteReference.CORRECT, display, extra);
}
};
}
@Override
public HelpContent help() {
return new HelpContent.Builder().setDescription("Sets your birthday date. Only useful if the server has enabled this functionality").setUsage("`~>birthday <date>`").addParameter("date", "A date in dd-mm format (13-02 for example). Check subcommands for more options.").build();
}
});
birthdayCommand.addSubCommand("allowserver", new SubCommand() {
public String description() {
return "Allows the server where you send this command to announce your birthday.";
}
@Override
protected void call(Context ctx, I18nContext languageContext, String content) {
var dbGuild = ctx.getDBGuild();
var guildData = dbGuild.getData();
if (guildData.getAllowedBirthdays().contains(ctx.getAuthor().getId())) {
ctx.sendLocalized("commands.birthday.already_allowed", EmoteReference.ERROR);
return;
}
guildData.getAllowedBirthdays().add(ctx.getAuthor().getId());
dbGuild.save();
var cached = guildBirthdayCache.getIfPresent(ctx.getGuild().getIdLong());
var cachedBirthday = ctx.getBot().getBirthdayCacher().getCachedBirthdays().get(ctx.getUser().getIdLong());
if (cached != null && cachedBirthday != null) {
cached.put(ctx.getUser().getIdLong(), cachedBirthday);
}
ctx.sendLocalized("commands.birthday.allowed_server", EmoteReference.CORRECT);
}
});
birthdayCommand.addSubCommand("denyserver", new SubCommand() {
public String description() {
return "Denies the server where you send this command to announce your birthday.";
}
@Override
protected void call(Context ctx, I18nContext languageContext, String content) {
var dbGuild = ctx.getDBGuild();
var guildData = dbGuild.getData();
if (!guildData.getAllowedBirthdays().contains(ctx.getAuthor().getId())) {
ctx.sendLocalized("commands.birthday.already_denied", EmoteReference.CORRECT);
return;
}
guildData.getAllowedBirthdays().remove(ctx.getAuthor().getId());
dbGuild.save();
var cached = guildBirthdayCache.getIfPresent(ctx.getGuild().getIdLong());
if (cached != null) {
cached.remove(ctx.getUser().getIdLong());
}
ctx.sendLocalized("commands.birthday.denied", EmoteReference.CORRECT);
}
});
birthdayCommand.addSubCommand("remove", new SubCommand() {
@Override
public String description() {
return "Removes your set birthday date.";
}
@Override
protected void call(Context ctx, I18nContext languageContext, String content) {
var user = ctx.getDBUser();
user.getData().setBirthday(null);
user.save();
ctx.sendLocalized("commands.birthday.reset", EmoteReference.CORRECT);
}
});
birthdayCommand.addSubCommand("list", new SubCommand() {
@Override
public String description() {
return "Gives all of the birthdays for this server.";
}
@Override
protected void call(Context ctx, I18nContext languageContext, String content) {
BirthdayCacher cacher = MantaroBot.getInstance().getBirthdayCacher();
try {
if (cacher != null) {
var globalBirthdays = cacher.getCachedBirthdays();
if (globalBirthdays.isEmpty()) {
ctx.sendLocalized("commands.birthday.no_global_birthdays", EmoteReference.SAD);
return;
}
var guild = ctx.getGuild();
var data = ctx.getDBGuild().getData();
var ids = data.getAllowedBirthdays().stream().map(Long::parseUnsignedLong).collect(Collectors.toList());
if (ids.isEmpty()) {
ctx.sendLocalized("commands.birthday.no_guild_birthdays", EmoteReference.ERROR);
return;
}
var guildCurrentBirthdays = getBirthdayMap(ctx.getGuild().getIdLong(), ids);
if (guildCurrentBirthdays.isEmpty()) {
ctx.sendLocalized("commands.birthday.no_guild_birthdays", EmoteReference.ERROR);
return;
}
var birthdays = guildCurrentBirthdays.entrySet().stream().sorted(Comparator.comparingLong(i -> i.getValue().day)).filter(birthday -> ids.contains(birthday.getKey())).limit(100).collect(Collectors.toList());
var bdIds = birthdays.stream().map(Map.Entry::getKey).collect(Collectors.toList());
guild.retrieveMembersByIds(bdIds).onSuccess(members -> sendBirthdayList(ctx, members, guildCurrentBirthdays, null, false));
} else {
ctx.sendLocalized("commands.birthday.cache_not_running", EmoteReference.SAD);
}
} catch (Exception e) {
ctx.sendLocalized("commands.birthday.error", EmoteReference.SAD);
log.error("Error on birthday list display!", e);
}
}
});
birthdayCommand.addSubCommand("month", new SubCommand() {
@Override
public String description() {
return "Checks the current birthday date for the specified month. Example: `~>birthday month 1`";
}
@Override
protected void call(Context ctx, I18nContext languageContext, String content) {
var args = ctx.getArguments();
var cacher = MantaroBot.getInstance().getBirthdayCacher();
var calendar = Calendar.getInstance();
var month = calendar.get(Calendar.MONTH);
var msg = "";
if (args.length == 1) {
msg = args[0];
}
if (!msg.isEmpty()) {
try {
month = Integer.parseInt(msg);
if (month < 1 || month > 12) {
ctx.sendLocalized("commands.birthday.invalid_month", EmoteReference.ERROR);
return;
}
// Substract here so we can do the check properly up there.
month = month - 1;
} catch (NumberFormatException e) {
ctx.sendLocalized("commands.birthday.invalid_month", EmoteReference.ERROR);
return;
}
}
calendar.set(calendar.get(Calendar.YEAR), month, Calendar.MONDAY);
try {
if (cacher != null) {
final var cachedBirthdays = cacher.getCachedBirthdays();
if (cachedBirthdays.isEmpty()) {
ctx.sendLocalized("commands.birthday.no_global_birthdays", EmoteReference.SAD);
return;
}
var data = ctx.getDBGuild().getData();
var ids = data.getAllowedBirthdays().stream().map(Long::parseUnsignedLong).collect(Collectors.toList());
var guildCurrentBirthdays = getBirthdayMap(ctx.getGuild().getIdLong(), ids);
if (ids.isEmpty()) {
ctx.sendLocalized("commands.birthday.no_guild_birthdays", EmoteReference.ERROR);
return;
}
var calendarMonth = calendar.get(Calendar.MONTH) + 1;
var birthdays = guildCurrentBirthdays.entrySet().stream().filter(bds -> bds.getValue().month == calendarMonth).sorted(Comparator.comparingLong(i -> i.getValue().day)).limit(100).collect(Collectors.toList());
if (birthdays.isEmpty()) {
ctx.sendLocalized("commands.birthday.no_guild_month_birthdays", EmoteReference.ERROR, month + 1, EmoteReference.BLUE_SMALL_MARKER);
return;
}
var bdIds = birthdays.stream().map(Map.Entry::getKey).collect(Collectors.toList());
ctx.getGuild().retrieveMembersByIds(bdIds).onSuccess(members -> sendBirthdayList(ctx, members, guildCurrentBirthdays, calendar, true));
} else {
ctx.sendLocalized("commands.birthday.cache_not_running", EmoteReference.SAD);
}
} catch (Exception e) {
ctx.sendLocalized("commands.birthday.error", EmoteReference.SAD);
log.error("Error on birthday month display!", e);
}
}
});
}
use of net.kodehawa.mantarobot.core.modules.commands.i18n.I18nContext 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");
}
Aggregations