Skip to content

Commit 706175a

Browse files
authored
Merge pull request #97 from sebampuero/impr-flighttime-fmt
Elytra flight time as human readable format
2 parents 4fe4c2b + 256581f commit 706175a

File tree

7 files changed

+132
-10
lines changed

7 files changed

+132
-10
lines changed

src/main/java/lol/hyper/toolstats/commands/CommandToolStats.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,8 @@ private void fixItemLore(ItemStack original, Player player) {
210210

211211
if (flightTime != null) {
212212
if (toolStats.config.getBoolean("enabled.flight-time")) {
213-
Component line = toolStats.configTools.formatLore("flight-time", "{time}", toolStats.numberFormat.formatDouble((double) flightTime / 1000));
213+
Map<String, String> flightTimeFormatted = toolStats.numberFormat.formatTime(flightTime);
214+
Component line = toolStats.configTools.formatLoreMultiplePlaceholders("flight-time", flightTimeFormatted);
214215
lore.add(line);
215216
}
216217
}

src/main/java/lol/hyper/toolstats/tools/ItemLore.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
import java.util.ArrayList;
2929
import java.util.List;
30+
import java.util.Map;
3031

3132
public class ItemLore {
3233

@@ -767,8 +768,8 @@ public ItemMeta updateFlightTime(ItemStack elytra, long duration) {
767768
}
768769
container.remove(toolStats.flightTime);
769770
if (meta.hasLore()) {
770-
String oldFlightTimeFormatted = toolStats.numberFormat.formatDouble(flightTime);
771-
Component lineToRemove = toolStats.configTools.formatLore("flight-time", "{time}", oldFlightTimeFormatted);
771+
Map<String, String> oldFlightTimeFormatted = toolStats.numberFormat.formatTime(flightTime);
772+
Component lineToRemove = toolStats.configTools.formatLoreMultiplePlaceholders("flight-time", oldFlightTimeFormatted);
772773
List<Component> newLore = removeLore(meta.lore(), lineToRemove);
773774
meta.lore(newLore);
774775
}
@@ -815,10 +816,10 @@ public ItemMeta updateFlightTime(ItemStack elytra, long duration) {
815816
}
816817

817818
container.set(toolStats.flightTime, PersistentDataType.LONG, flightTime + duration);
818-
String oldFlightFormatted = toolStats.numberFormat.formatDouble((double) flightTime / 1000);
819-
String newFlightFormatted = toolStats.numberFormat.formatDouble((double) (flightTime + duration) / 1000);
820-
Component oldLine = toolStats.configTools.formatLore("flight-time", "{time}", oldFlightFormatted);
821-
Component newLine = toolStats.configTools.formatLore("flight-time", "{time}", newFlightFormatted);
819+
Map<String, String> oldFlightFormatted = toolStats.numberFormat.formatTime(flightTime);
820+
Map<String, String> newFlightFormatted = toolStats.numberFormat.formatTime(flightTime + duration);
821+
Component oldLine = toolStats.configTools.formatLoreMultiplePlaceholders("flight-time", oldFlightFormatted);
822+
Component newLine = toolStats.configTools.formatLoreMultiplePlaceholders("flight-time", newFlightFormatted);
822823
if (oldLine == null || newLine == null) {
823824
return null;
824825
}

src/main/java/lol/hyper/toolstats/tools/NumberFormat.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
import java.text.DecimalFormatSymbols;
2424
import java.text.SimpleDateFormat;
2525
import java.util.Date;
26+
import java.util.HashMap;
2627
import java.util.Locale;
28+
import java.util.Map;
2729

2830
public class NumberFormat {
2931

@@ -136,4 +138,59 @@ public String formatDouble(double number) {
136138
public String formatDate(Date date) {
137139
return DATE_FORMAT.format(date);
138140
}
141+
142+
/**
143+
* Returns a human readable form of time in milliseconds.
144+
* E.g. given 3752348000L outputs 1 years, 5 months, 3 days, 14 hours, 12 minutes, 28 seconds.
145+
* @param time The time in ms.
146+
* @return Map with units as keys and time value, e.g. "years" (key) -> 1 (value)
147+
*/
148+
public Map<String, String> formatTime(Long time) {
149+
final int SECONDS_PER_MINUTE = 60;
150+
final int MINUTES_PER_HOUR = 60;
151+
final int HOURS_PER_DAY = 24;
152+
final int DAYS_PER_MONTH = 30; // Approximation
153+
final int DAYS_PER_YEAR = 365; // Approximation
154+
155+
long totalSeconds = time / 1000;
156+
157+
Map<String, String> timeUnits = new HashMap<>();
158+
159+
long years = totalSeconds / (DAYS_PER_YEAR * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
160+
if (years > 0) {
161+
timeUnits.put("years", Long.toString(years));
162+
}
163+
totalSeconds %= (DAYS_PER_YEAR * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
164+
165+
long months = totalSeconds / (DAYS_PER_MONTH * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
166+
if (months > 0) {
167+
timeUnits.put("months", Long.toString(months));
168+
}
169+
totalSeconds %= (DAYS_PER_MONTH * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
170+
171+
long days = totalSeconds / (HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
172+
if (days > 0) {
173+
timeUnits.put("days", Long.toString(days));
174+
}
175+
totalSeconds %= (HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
176+
177+
long hours = totalSeconds / (MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
178+
if (hours > 0) {
179+
timeUnits.put("hours", Long.toString(hours));
180+
}
181+
totalSeconds %= (MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
182+
183+
long minutes = totalSeconds / SECONDS_PER_MINUTE;
184+
if (minutes > 0) {
185+
timeUnits.put("minutes", Long.toString(minutes));
186+
}
187+
totalSeconds %= SECONDS_PER_MINUTE;
188+
189+
long seconds = totalSeconds;
190+
if (seconds > 0 || timeUnits.isEmpty()) { // Always include seconds if everything else is zero
191+
timeUnits.put("seconds", Long.toString(seconds));
192+
}
193+
194+
return timeUnits;
195+
}
139196
}

src/main/java/lol/hyper/toolstats/tools/config/ConfigTools.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.ArrayList;
2828
import java.util.Collections;
2929
import java.util.List;
30+
import java.util.Map;
3031
import java.util.regex.Matcher;
3132
import java.util.regex.Pattern;
3233

@@ -133,6 +134,65 @@ public Component formatLore(String configName, String placeHolder, Object value)
133134
return component.decorationIfAbsent(TextDecoration.ITALIC, TextDecoration.State.FALSE);
134135
}
135136

137+
/**
138+
* Format a string with several placeholders to be ready for lore usage.
139+
*
140+
* @param configName The message to use.
141+
* @param placeHoldersValues Map containing placeholders names as keys and values.
142+
* @return Formatted string, null if the configName doesn't exist.
143+
*/
144+
public Component formatLoreMultiplePlaceholders(String configName, Map<String, String> placeHoldersValues) {
145+
String lore = toolStats.config.getString("messages." + configName);
146+
if (lore == null) {
147+
toolStats.logger.warning("Unable to find config message for: messages." + configName);
148+
return null;
149+
}
150+
151+
// if the config message is empty, don't send it
152+
if (lore.isEmpty()) {
153+
return null;
154+
}
155+
156+
Pattern pattern = Pattern.compile("\\{([^}]+)\\}(\\S*)\\s*");
157+
Matcher matcher = pattern.matcher(lore);
158+
159+
StringBuilder result = new StringBuilder();
160+
int lastEnd = 0;
161+
162+
while (matcher.find()) {
163+
String placeholder = matcher.group(1);
164+
String unit = matcher.group(2);
165+
166+
result.append(lore, lastEnd, matcher.start());
167+
168+
if (placeHoldersValues.containsKey(placeholder)) {
169+
result.append(placeHoldersValues.get(placeholder)).append(unit).append(" ");
170+
}
171+
172+
// Update lastEnd to end of the match
173+
lastEnd = matcher.end();
174+
}
175+
if (lastEnd < lore.length()) {
176+
result.append(lore.substring(lastEnd));
177+
}
178+
179+
Component component;
180+
// Clean output text
181+
String outputText = result.toString().replaceAll("\\s+", " ").trim();
182+
183+
// if we match the old color codes, then format them as so
184+
Matcher hexMatcher = CONFIG_HEX_PATTERN.matcher(outputText);
185+
Matcher colorMatcher = COLOR_CODES.matcher(outputText);
186+
if (hexMatcher.find() || colorMatcher.find()) {
187+
component = LegacyComponentSerializer.legacyAmpersand().deserialize(outputText);
188+
} else {
189+
// otherwise format them normally
190+
component = MiniMessage.miniMessage().deserialize(outputText);
191+
}
192+
193+
return component.decorationIfAbsent(TextDecoration.ITALIC, TextDecoration.State.FALSE);
194+
}
195+
136196
/**
137197
* Format a string from the config.
138198
*

src/main/java/lol/hyper/toolstats/tools/config/ConfigUpdater.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,4 @@ public void updateConfig() {
6262
version11.update();
6363
}
6464
}
65-
}
65+
}

src/main/java/lol/hyper/toolstats/tools/config/versions/Version11.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ public void update() {
8686
toolStats.logger.info("Adding enabled.damage-done.bow to config.yml");
8787
toolStats.logger.info("Adding enabled.damage-done.mace to config.yml");
8888

89+
toolStats.logger.info("Updating entry for messages.flight-time");
90+
toolStats.config.set("messages.flight-time", "&7Flight time: &8{years}y {months}m {days}d {hours}h {minutes}m {seconds}s");
91+
8992
// save the config and reload it
9093
try {
9194
toolStats.config.save("plugins" + File.separator + "ToolStats" + File.separator + "config.yml");
@@ -96,4 +99,4 @@ public void update() {
9699
toolStats.loadConfig();
97100
toolStats.logger.info("Config has been updated to version 11. A copy of version 10 has been saved as config-10.yml");
98101
}
99-
}
102+
}

src/main/resources/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ messages:
196196
dropped-by: "&7Dropped by: &8{name}" # name will be player/mob name
197197
damage-taken: "&7Damage taken: &8{damage}"
198198
arrows-shot: "&7Arrows shot: &8{arrows}"
199-
flight-time: "&7Flight time: &8{time}"
199+
flight-time: "&7Flight time: &8{years}y {months}m {days}d {hours}h {minutes}m {seconds}s"
200200
damage-done: "&7Damage done: &8{damage}"
201201
# Set display name for mobs. See: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/entity/EntityType.html
202202
mobs:

0 commit comments

Comments
 (0)