update number formatter
All checks were successful
Deploy to Dokku / docker (ubuntu-latest) (push) Successful in 40s
All checks were successful
Deploy to Dokku / docker (ubuntu-latest) (push) Successful in 40s
This commit is contained in:
parent
5aa56c2955
commit
729e0b482b
@ -4,7 +4,7 @@ import cc.fascinated.bat.Emojis;
|
|||||||
import cc.fascinated.bat.command.BatCommand;
|
import cc.fascinated.bat.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.common.NumberUtils;
|
import cc.fascinated.bat.common.NumberFormatter;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
@ -52,17 +52,17 @@ public class MemberCountCommand extends BatCommand {
|
|||||||
%s Idle: `%s`
|
%s Idle: `%s`
|
||||||
%s Do Not Disturb: `%s`
|
%s Do Not Disturb: `%s`
|
||||||
%s Offline: `%s`""".formatted(
|
%s Offline: `%s`""".formatted(
|
||||||
NumberUtils.formatNumberCommas(totalMembers),
|
NumberFormatter.format(totalMembers),
|
||||||
NumberUtils.formatNumberCommas(totalUsers),
|
NumberFormatter.format(totalUsers),
|
||||||
NumberUtils.formatNumberCommas(totalBots),
|
NumberFormatter.format(totalBots),
|
||||||
Emojis.ONLINE_EMOJI,
|
Emojis.ONLINE_EMOJI,
|
||||||
NumberUtils.formatNumberCommas(memberCounts.getOrDefault(OnlineStatus.ONLINE, 0)),
|
NumberFormatter.format(memberCounts.getOrDefault(OnlineStatus.ONLINE, 0)),
|
||||||
Emojis.IDLE_EMOJI,
|
Emojis.IDLE_EMOJI,
|
||||||
NumberUtils.formatNumberCommas(memberCounts.getOrDefault(OnlineStatus.IDLE, 0)),
|
NumberFormatter.format(memberCounts.getOrDefault(OnlineStatus.IDLE, 0)),
|
||||||
Emojis.DND_EMOJI,
|
Emojis.DND_EMOJI,
|
||||||
NumberUtils.formatNumberCommas(memberCounts.getOrDefault(OnlineStatus.DO_NOT_DISTURB, 0)),
|
NumberFormatter.format(memberCounts.getOrDefault(OnlineStatus.DO_NOT_DISTURB, 0)),
|
||||||
Emojis.OFFLINE_EMOJI,
|
Emojis.OFFLINE_EMOJI,
|
||||||
NumberUtils.formatNumberCommas(memberCounts.getOrDefault(OnlineStatus.OFFLINE, 0))));
|
NumberFormatter.format(memberCounts.getOrDefault(OnlineStatus.OFFLINE, 0))));
|
||||||
interaction.replyEmbeds(embed.build()).queue();
|
interaction.replyEmbeds(embed.build()).queue();
|
||||||
}
|
}
|
||||||
}
|
}
|
83
src/main/java/cc/fascinated/bat/common/NumberFormatter.java
Normal file
83
src/main/java/cc/fascinated/bat/common/NumberFormatter.java
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
public class NumberFormatter {
|
||||||
|
/**
|
||||||
|
* The suffixes for the numbers
|
||||||
|
*/
|
||||||
|
private static final String[] SUFFIXES = new String[] { "K", "M", "B", "T", "Q", "QT", "S", "SP", "O", "N", "D", "UD", "DD", "TD" };
|
||||||
|
private static final DecimalFormat FORMAT = new DecimalFormat("###.##");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format the provided double
|
||||||
|
*
|
||||||
|
* @param input the value to format
|
||||||
|
* @return the formatted double, in the format of xx.xx[suffix]
|
||||||
|
*/
|
||||||
|
public static String format(double input) {
|
||||||
|
if (Double.isNaN(input)) {
|
||||||
|
return "ERROR";
|
||||||
|
}
|
||||||
|
if (Double.isInfinite(input) || input == Double.MAX_VALUE) {
|
||||||
|
return "∞";
|
||||||
|
}
|
||||||
|
if (1000 > input) {
|
||||||
|
return FORMAT.format(input);
|
||||||
|
}
|
||||||
|
double power = (int) Math.log10(input);
|
||||||
|
int index = (int) Math.floor(power / 3) - 1;
|
||||||
|
double factor = input / Math.pow(10, 3 + index * 3);
|
||||||
|
if (index >= SUFFIXES.length) {
|
||||||
|
return "ERROR";
|
||||||
|
}
|
||||||
|
return FORMAT.format(factor) + SUFFIXES[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format the provided double with commas
|
||||||
|
*
|
||||||
|
* @param input the value to format
|
||||||
|
* @return the formatted double, in the format of xx,xxx,xxx
|
||||||
|
*/
|
||||||
|
public static String formatCommas(double input) {
|
||||||
|
return String.format("%,.0f", input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turns a provided string into a double, for example 1M -> 1000000.00
|
||||||
|
* Accepts decimal and negative values and is not case-sensitive
|
||||||
|
*
|
||||||
|
* @param input the string to convert
|
||||||
|
* @return the value the string represents
|
||||||
|
*/
|
||||||
|
public static double fromString(String input) {
|
||||||
|
if ((input = input.trim()).isEmpty()) {
|
||||||
|
return -1D;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
double value = Double.parseDouble(input); // parse pure numbers
|
||||||
|
if (Double.isNaN(value) || Double.isInfinite(value)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
input = input.toUpperCase(Locale.UK);
|
||||||
|
for (int i = SUFFIXES.length - 1; i > 0; i--) {
|
||||||
|
String suffix = SUFFIXES[i];
|
||||||
|
if (!input.endsWith(suffix)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String amount = input.substring(0, input.length() - suffix.length());
|
||||||
|
if (!amount.isEmpty()) {
|
||||||
|
return Double.parseDouble(amount) * Math.pow(10, 3 + i * 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
@ -1,27 +0,0 @@
|
|||||||
package cc.fascinated.bat.common;
|
|
||||||
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
|
|
||||||
import java.text.NumberFormat;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@UtilityClass
|
|
||||||
public class NumberUtils {
|
|
||||||
/**
|
|
||||||
* Formats a number with commas.
|
|
||||||
* <p>
|
|
||||||
* Example: 1000 -> 1,000 | Example: 1000.5 -> 1,000.5
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param number the number to format
|
|
||||||
* @return the formatted number
|
|
||||||
*/
|
|
||||||
public static String formatNumberCommas(double number) {
|
|
||||||
NumberFormat format = NumberFormat.getNumberInstance();
|
|
||||||
format.setGroupingUsed(true);
|
|
||||||
format.setMaximumFractionDigits(2);
|
|
||||||
return format.format(number);
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,14 +8,10 @@ import cc.fascinated.bat.features.FeatureProfile;
|
|||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
import cc.fascinated.bat.service.FeatureService;
|
import cc.fascinated.bat.service.FeatureService;
|
||||||
import cc.fascinated.bat.service.GuildService;
|
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package cc.fascinated.bat.features.scoresaber;
|
package cc.fascinated.bat.features.scoresaber;
|
||||||
|
|
||||||
import cc.fascinated.bat.common.NumberUtils;
|
import cc.fascinated.bat.common.NumberFormatter;
|
||||||
import cc.fascinated.bat.event.EventListener;
|
import cc.fascinated.bat.event.EventListener;
|
||||||
import cc.fascinated.bat.features.scoresaber.profile.guild.NumberOneScoreFeedProfile;
|
import cc.fascinated.bat.features.scoresaber.profile.guild.NumberOneScoreFeedProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
@ -41,7 +41,7 @@ public class NumberOneScoreFeedListener implements EventListener {
|
|||||||
log.info("A new #1 score has been set by {} on {} ({})!",
|
log.info("A new #1 score has been set by {} on {} ({})!",
|
||||||
player.getName(),
|
player.getName(),
|
||||||
leaderboard.getSongName(),
|
leaderboard.getSongName(),
|
||||||
"%s⭐".formatted(NumberUtils.formatNumberCommas(leaderboard.getStars()))
|
"%s⭐".formatted(NumberFormatter.formatCommas(leaderboard.getStars()))
|
||||||
);
|
);
|
||||||
|
|
||||||
for (Guild guild : DiscordService.JDA.getGuilds()) {
|
for (Guild guild : DiscordService.JDA.getGuilds()) {
|
||||||
|
@ -3,7 +3,7 @@ package cc.fascinated.bat.features.scoresaber;
|
|||||||
import cc.fascinated.bat.command.Category;
|
import cc.fascinated.bat.command.Category;
|
||||||
import cc.fascinated.bat.common.DateUtils;
|
import cc.fascinated.bat.common.DateUtils;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.common.NumberUtils;
|
import cc.fascinated.bat.common.NumberFormatter;
|
||||||
import cc.fascinated.bat.common.ScoreSaberUtils;
|
import cc.fascinated.bat.common.ScoreSaberUtils;
|
||||||
import cc.fascinated.bat.features.Feature;
|
import cc.fascinated.bat.features.Feature;
|
||||||
import cc.fascinated.bat.features.scoresaber.command.numberone.NumberOneFeedCommand;
|
import cc.fascinated.bat.features.scoresaber.command.numberone.NumberOneFeedCommand;
|
||||||
@ -55,10 +55,10 @@ public class ScoreSaberFeature extends Feature {
|
|||||||
);
|
);
|
||||||
|
|
||||||
String accuracy = leaderboardToken.getMaxScore() == 0 ? "N/A" :
|
String accuracy = leaderboardToken.getMaxScore() == 0 ? "N/A" :
|
||||||
String.format("%s%%", NumberUtils.formatNumberCommas(((double) scoreToken.getBaseScore() / leaderboardToken.getMaxScore()) * 100));
|
String.format("%s%%", NumberFormatter.formatCommas(((double) scoreToken.getBaseScore() / leaderboardToken.getMaxScore()) * 100));
|
||||||
|
|
||||||
String rawPp = scoreToken.getPp() == 0 ? "Unranked" : NumberUtils.formatNumberCommas(scoreToken.getPp());
|
String rawPp = scoreToken.getPp() == 0 ? "Unranked" : NumberFormatter.formatCommas(scoreToken.getPp());
|
||||||
String rank = String.format("#%s", NumberUtils.formatNumberCommas(scoreToken.getRank()));
|
String rank = String.format("#%s", NumberFormatter.formatCommas(scoreToken.getRank()));
|
||||||
String misses = String.format("%s", scoreToken.getMissedNotes());
|
String misses = String.format("%s", scoreToken.getMissedNotes());
|
||||||
String badCuts = String.format("%s", scoreToken.getBadCuts());
|
String badCuts = String.format("%s", scoreToken.getBadCuts());
|
||||||
String maxCombo = String.format("%s %s",
|
String maxCombo = String.format("%s %s",
|
||||||
|
@ -5,7 +5,7 @@ import cc.fascinated.bat.command.CommandInfo;
|
|||||||
import cc.fascinated.bat.common.Colors;
|
import cc.fascinated.bat.common.Colors;
|
||||||
import cc.fascinated.bat.common.DateUtils;
|
import cc.fascinated.bat.common.DateUtils;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.common.NumberUtils;
|
import cc.fascinated.bat.common.NumberFormatter;
|
||||||
import cc.fascinated.bat.exception.RateLimitException;
|
import cc.fascinated.bat.exception.RateLimitException;
|
||||||
import cc.fascinated.bat.features.scoresaber.profile.user.ScoreSaberProfile;
|
import cc.fascinated.bat.features.scoresaber.profile.user.ScoreSaberProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
@ -84,9 +84,9 @@ public class ScoreSaberCommand extends BatCommand {
|
|||||||
"https://cdn.scoresaber.com/avatars/%s.jpg".formatted(account.getId()))
|
"https://cdn.scoresaber.com/avatars/%s.jpg".formatted(account.getId()))
|
||||||
.addField("Name", account.getName(), true)
|
.addField("Name", account.getName(), true)
|
||||||
.addField("Country", account.getCountry(), true)
|
.addField("Country", account.getCountry(), true)
|
||||||
.addField("Rank", "#" + NumberUtils.formatNumberCommas(account.getRank()), true)
|
.addField("Rank", "#" + NumberFormatter.formatCommas(account.getRank()), true)
|
||||||
.addField("Country Rank", "#" + NumberUtils.formatNumberCommas(account.getCountryRank()), true)
|
.addField("Country Rank", "#" + NumberFormatter.formatCommas(account.getCountryRank()), true)
|
||||||
.addField("PP", NumberUtils.formatNumberCommas(account.getPp()), true)
|
.addField("PP", NumberFormatter.formatCommas(account.getPp()), true)
|
||||||
.addField("Joined", "<t:%s>".formatted(DateUtils.getDateFromString(account.getFirstSeen()).toInstant().toEpochMilli() / 1000), true)
|
.addField("Joined", "<t:%s>".formatted(DateUtils.getDateFromString(account.getFirstSeen()).toInstant().toEpochMilli() / 1000), true)
|
||||||
.setTimestamp(LocalDateTime.now())
|
.setTimestamp(LocalDateTime.now())
|
||||||
.setFooter(fetchTime > 3 ? "Fetched in %sms".formatted(fetchTime) : "Cached", "https://flagcdn.com/h120/%s.png".formatted(account.getCountry().toLowerCase()))
|
.setFooter(fetchTime > 3 ? "Fetched in %sms".formatted(fetchTime) : "Cached", "https://flagcdn.com/h120/%s.png".formatted(account.getCountry().toLowerCase()))
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package cc.fascinated.bat.service;
|
package cc.fascinated.bat.service;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.NumberFormatter;
|
||||||
import cc.fascinated.bat.common.TimerUtils;
|
import cc.fascinated.bat.common.TimerUtils;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.dv8tion.jda.api.JDA;
|
import net.dv8tion.jda.api.JDA;
|
||||||
@ -26,10 +27,9 @@ public class DiscordService {
|
|||||||
public static JDA JDA;
|
public static JDA JDA;
|
||||||
|
|
||||||
private final List<String> messages = List.of(
|
private final List<String> messages = List.of(
|
||||||
"over {guilds} guilds",
|
"{guilds} guilds",
|
||||||
"over {users} users",
|
"{users} users",
|
||||||
"over ScoreSaber scores",
|
"your ScoreSaber scores",
|
||||||
"your messages",
|
|
||||||
"/help for help"
|
"/help for help"
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -60,8 +60,8 @@ public class DiscordService {
|
|||||||
public void updateActivity() {
|
public void updateActivity() {
|
||||||
int guildCount = JDA.getGuilds().size();
|
int guildCount = JDA.getGuilds().size();
|
||||||
JDA.getPresence().setActivity(Activity.watching(messages.get(guildCount % messages.size())
|
JDA.getPresence().setActivity(Activity.watching(messages.get(guildCount % messages.size())
|
||||||
.replace("{guilds}", String.valueOf(guildCount))
|
.replace("{guilds}", NumberFormatter.format(guildCount))
|
||||||
.replace("{users}", String.valueOf(JDA.getUsers().size()))
|
.replace("{users}", NumberFormatter.format(JDA.getUsers().size()))
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,9 +12,7 @@ import org.springframework.context.ApplicationContext;
|
|||||||
import org.springframework.context.annotation.DependsOn;
|
import org.springframework.context.annotation.DependsOn;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user