fix: locate stats directory under Paper's dimensions layout
Rankings returned "sem dados" because World#getWorldFolder points at the dimension directory in Paper's newer layout, so <worldFolder>/players/stats does not exist. The real path is <worldContainer>/<level-name>/players/stats. Try that first, fall back to the older locations, then climb out of the dimension folder, and warn instead of silently returning nothing. Also fixes "1 dias e 0 horas" — durations now agree in number and drop a zero remainder. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ActvLGJApdxEAd2yfKPwqv
This commit is contained in:
@@ -45,16 +45,23 @@ final class Msg {
|
||||
.append(Component.text(value, NamedTextColor.AQUA)));
|
||||
}
|
||||
|
||||
/** Renders a duration in ticks as "3 dias e 4 horas" / "5 horas" / "12 minutos". */
|
||||
/** Renders a duration in ticks as "3 dias e 4 horas" / "1 hora" / "12 minutos". */
|
||||
static String duration(long ticks) {
|
||||
long minutes = ticks / 20L / 60L;
|
||||
if (minutes < 60) {
|
||||
return minutes + " minutos";
|
||||
return plural(minutes, "minuto", "minutos");
|
||||
}
|
||||
long hours = minutes / 60;
|
||||
if (hours < 24) {
|
||||
return hours + " horas";
|
||||
return plural(hours, "hora", "horas");
|
||||
}
|
||||
return hours / 24 + " dias e " + hours % 24 + " horas";
|
||||
long days = hours / 24;
|
||||
long rest = hours % 24;
|
||||
String text = plural(days, "dia", "dias");
|
||||
return rest == 0 ? text : text + " e " + plural(rest, "hora", "horas");
|
||||
}
|
||||
|
||||
private static String plural(long value, String singular, String plural) {
|
||||
return value + " " + (value == 1 ? singular : plural);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,19 +120,46 @@ final class OfflineStats {
|
||||
}
|
||||
|
||||
/**
|
||||
* Paper writes to {@code <world>/players/stats}; older layouts used
|
||||
* {@code <world>/stats}. Try both rather than assume.
|
||||
* Locates the statistics directory.
|
||||
*
|
||||
* <p>Not as simple as it looks. Paper's newer layout puts dimensions under
|
||||
* {@code <world>/dimensions/…}, and {@code World#getWorldFolder} points at
|
||||
* the dimension rather than the world root — so {@code getWorldFolder() +
|
||||
* "/players/stats"} does not exist. The real path is
|
||||
* {@code <worldContainer>/<level-name>/players/stats}. Older servers used
|
||||
* {@code <world>/stats}. Try each in turn, then walk up from the dimension
|
||||
* folder as a last resort.
|
||||
*/
|
||||
private File statsDirectory() {
|
||||
if (Bukkit.getWorlds().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
File world = Bukkit.getWorlds().get(0).getWorldFolder();
|
||||
File modern = new File(world, "players/stats");
|
||||
if (modern.isDirectory()) {
|
||||
return modern;
|
||||
String levelName = Bukkit.getWorlds().get(0).getName();
|
||||
File worldFolder = Bukkit.getWorlds().get(0).getWorldFolder();
|
||||
|
||||
File[] candidates = {
|
||||
new File(new File(Bukkit.getWorldContainer(), levelName), "players/stats"),
|
||||
new File(worldFolder, "players/stats"),
|
||||
new File(new File(Bukkit.getWorldContainer(), levelName), "stats"),
|
||||
new File(worldFolder, "stats"),
|
||||
};
|
||||
for (File candidate : candidates) {
|
||||
if (candidate.isDirectory()) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
File legacy = new File(world, "stats");
|
||||
return legacy.isDirectory() ? legacy : null;
|
||||
|
||||
// Last resort: climb out of the dimension folder looking for players/stats.
|
||||
File current = worldFolder;
|
||||
for (int depth = 0; depth < 4 && current != null; depth++) {
|
||||
File found = new File(current, "players/stats");
|
||||
if (found.isDirectory()) {
|
||||
return found;
|
||||
}
|
||||
current = current.getParentFile();
|
||||
}
|
||||
plugin.getLogger().warning("Não encontrei o diretório de estatísticas a partir de "
|
||||
+ worldFolder.getAbsolutePath());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user