diff --git a/build.gradle.kts b/build.gradle.kts index 2616410..d307a48 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -27,8 +27,8 @@ repositories { } dependencies { - compileOnly("com.destroystokyo.paper:paper-api:1.12.2-R0.1-SNAPSHOT") compileOnly("org.jetbrains:annotations:24.1.0") + compileOnly("com.destroystokyo.paper:paper-api:1.12.2-R0.1-SNAPSHOT") compileOnly("me.clip:placeholderapi:2.11.5") implementation("net.kyori:adventure-platform-bukkit:4.3.2") diff --git a/src/main/java/me/xginko/betterworldstats/BetterWorldStats.java b/src/main/java/me/xginko/betterworldstats/BetterWorldStats.java index 6770e52..f829203 100644 --- a/src/main/java/me/xginko/betterworldstats/BetterWorldStats.java +++ b/src/main/java/me/xginko/betterworldstats/BetterWorldStats.java @@ -3,16 +3,14 @@ import me.xginko.betterworldstats.commands.BWSCmd; import me.xginko.betterworldstats.config.Config; import me.xginko.betterworldstats.config.LanguageCache; +import me.xginko.betterworldstats.hooks.BWSHook; +import me.xginko.betterworldstats.hooks.PAPIExpansion; import me.xginko.betterworldstats.utils.KyoriUtil; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.Style; -import net.kyori.adventure.text.format.TextColor; -import net.kyori.adventure.text.format.TextDecoration; import net.kyori.adventure.text.logger.slf4j.ComponentLogger; import org.bstats.bukkit.Metrics; import org.bukkit.command.CommandSender; -import org.bukkit.event.HandlerList; import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; @@ -24,36 +22,34 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; -import java.util.zip.ZipEntry; public final class BetterWorldStats extends JavaPlugin { - public static final TextColor COLOR = TextColor.color(0,204,34); - public static final Style STYLE = Style.style(COLOR, TextDecoration.BOLD); - + private static final Pattern langPattern = Pattern.compile("([a-z]{1,3}_[a-z]{1,3})(\\.yml)", Pattern.CASE_INSENSITIVE); private static BetterWorldStats instance; private static Map languageCacheMap; private static Config config; private static Statistics statistics; - private static PAPIExpansion papiExpansion; private static BukkitAudiences audiences; private static ComponentLogger logger; - private static Metrics metrics; + private static Metrics bStats; @Override public void onEnable() { instance = this; audiences = BukkitAudiences.create(this); logger = ComponentLogger.logger(getLogger().getName()); - metrics = new Metrics(this, 17204); - logger.info(Component.text(" ").style(STYLE)); - logger.info(Component.text(" ___ _ _ ").style(STYLE)); - logger.info(Component.text(" | _ ) ___| |_| |_ ___ _ _ ").style(STYLE)); - logger.info(Component.text(" | _ \\/ -_) _| _/ -_) '_| ").style(STYLE)); - logger.info(Component.text(" __|___/\\___|\\__|\\__\\___|_|_ _ _ ").style(STYLE)); - logger.info(Component.text(" \\ \\ / /__ _ _| |__| / __| |_ __ _| |_ ___").style(STYLE)); - logger.info(Component.text(" \\ \\/\\/ / _ \\ '_| / _` \\__ \\ _/ _` | _(_-<").style(STYLE)); - logger.info(Component.text(" \\_/\\_/\\___/_| |_\\__,_|___/\\__\\__,_|\\__/__/").style(STYLE)); - logger.info(Component.text(" ").style(STYLE)); + bStats = new Metrics(this, 17204); + + logger.info(Component.text(" ").style(KyoriUtil.GUPPIE_GREEN_BOLD)); + logger.info(Component.text(" ___ _ _ ").style(KyoriUtil.GUPPIE_GREEN_BOLD)); + logger.info(Component.text(" | _ ) ___| |_| |_ ___ _ _ ").style(KyoriUtil.GUPPIE_GREEN_BOLD)); + logger.info(Component.text(" | _ \\/ -_) _| _/ -_) '_| ").style(KyoriUtil.GUPPIE_GREEN_BOLD)); + logger.info(Component.text(" __|___/\\___|\\__|\\__\\___|_|_ _ _ ").style(KyoriUtil.GUPPIE_GREEN_BOLD)); + logger.info(Component.text(" \\ \\ / /__ _ _| |__| / __| |_ __ _| |_ ___").style(KyoriUtil.GUPPIE_GREEN_BOLD)); + logger.info(Component.text(" \\ \\/\\/ / _ \\ '_| / _` \\__ \\ _/ _` | _(_-<").style(KyoriUtil.GUPPIE_GREEN_BOLD)); + logger.info(Component.text(" \\_/\\_/\\___/_| |_\\__,_|___/\\__\\__,_|\\__/__/").style(KyoriUtil.GUPPIE_GREEN_BOLD)); + logger.info(Component.text(" ").style(KyoriUtil.GUPPIE_GREEN_BOLD)); + logger.info("Loading languages"); reloadLang(); logger.info("Loading config"); @@ -65,20 +61,19 @@ public void onEnable() { @Override public void onDisable() { - HandlerList.unregisterAll(this); + BWSHook.HOOKS.forEach(BWSHook::unHook); + if (statistics != null) { + statistics.shutdown(); + statistics = null; + } if (audiences != null) { audiences.close(); audiences = null; } - if (papiExpansion != null) { - papiExpansion.unregister(); - papiExpansion = null; - } - if (metrics != null) { - metrics.shutdown(); - metrics = null; + if (bStats != null) { + bStats.shutdown(); + bStats = null; } - statistics = null; config = null; languageCacheMap = null; logger = null; @@ -126,13 +121,11 @@ public void reloadPlugin() { private void reloadConfiguration() { try { - if (statistics != null) statistics.shutdown(); + if (statistics != null) + statistics.shutdown(); config = new Config(); statistics = new Statistics(); - if (getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { - if (papiExpansion != null) papiExpansion.unregister(); - papiExpansion = new PAPIExpansion(); - } + BWSHook.reloadHooks(); config.saveConfig(); } catch (Exception e) { logger.error("Failed loading config!", e); @@ -144,35 +137,44 @@ public void reloadLang() { try { File langDirectory = new File(getDataFolder() + "/lang"); Files.createDirectories(langDirectory.toPath()); - for (String fileName : getDefaultLanguageFiles()) { - final String localeString = fileName.substring(fileName.lastIndexOf('/') + 1, fileName.lastIndexOf('.')); + Set locales = new HashSet<>(); + locales.addAll(getDefaultLocales(getFile())); + locales.addAll(getPresentLocales(langDirectory)); + for (String localeString : locales) { logger.info("Found language file for " + localeString); languageCacheMap.put(localeString, new LanguageCache(localeString)); } - final Pattern langPattern = Pattern.compile("([a-z]{1,3}_[a-z]{1,3})(\\.yml)", Pattern.CASE_INSENSITIVE); - for (File langFile : langDirectory.listFiles()) { - final Matcher langMatcher = langPattern.matcher(langFile.getName()); - if (langMatcher.find()) { - final String localeString = langMatcher.group(1).toLowerCase(); - if (!languageCacheMap.containsKey(localeString)) { // make sure it wasn't a default file that we already loaded - logger.info("Found language file for " + localeString); - languageCacheMap.put(localeString, new LanguageCache(localeString)); - } - } - } - } catch (Exception e) { - logger.error("Error loading language files!", e); + } catch (Throwable t) { + logger.error("Error loading language files!", t); } } - private @NotNull Set getDefaultLanguageFiles() { - try (final JarFile pluginJarFile = new JarFile(this.getFile())) { + private @NotNull Set getDefaultLocales(File jarFile) { + try (final JarFile pluginJarFile = new JarFile(jarFile)) { return pluginJarFile.stream() - .map(ZipEntry::getName) - .filter(name -> name.startsWith("lang/") && name.endsWith(".yml")) + .map(zipEntry -> { + Matcher matcher = langPattern.matcher(zipEntry.getName()); + return matcher.find() ? matcher.group(1) : null; + }) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + } catch (Throwable t) { + logger.error("Failed getting default lang files!", t); + return Collections.emptySet(); + } + } + + private @NotNull Set getPresentLocales(File folder) { + try { + return Arrays.stream(Objects.requireNonNull(folder.listFiles())) + .map(file -> { + Matcher matcher = langPattern.matcher(file.getName()); + return matcher.find() ? matcher.group(1) : null; + }) + .filter(Objects::nonNull) .collect(Collectors.toSet()); - } catch (IOException e) { - logger.error("Failed getting default lang files!", e); + } catch (Throwable t) { + logger.error("Failed getting lang files from plugin folder!", t); return Collections.emptySet(); } } diff --git a/src/main/java/me/xginko/betterworldstats/PAPIExpansion.java b/src/main/java/me/xginko/betterworldstats/PAPIExpansion.java deleted file mode 100644 index e75977b..0000000 --- a/src/main/java/me/xginko/betterworldstats/PAPIExpansion.java +++ /dev/null @@ -1,76 +0,0 @@ -package me.xginko.betterworldstats; - -import me.clip.placeholderapi.expansion.PlaceholderExpansion; -import me.xginko.betterworldstats.config.Config; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public final class PAPIExpansion extends PlaceholderExpansion { - - private final @NotNull Statistics statistics; - - PAPIExpansion() { - this.statistics = BetterWorldStats.getStatistics(); - this.register(); - } - - @Override - public boolean persist() { - return true; - } - - @Override - public boolean canRegister() { - return true; - } - - @Override - public @NotNull String getAuthor() { - return "xGinko"; - } - - @Override - public @NotNull String getIdentifier() { - return "worldstats"; - } - - @Override - public @NotNull String getVersion() { - return BetterWorldStats.getInstance().getDescription().getVersion(); - } - - @Override - public @Nullable String onPlaceholderRequest(Player player, @NotNull String identifier) { - switch (identifier) { - case "size": - return statistics.fileStats.getSize(); - case "spoofsize": - return statistics.fileStats.getSpoofedSize(); - case "file_count": - return statistics.fileStats.getFileCount(); - case "folder_count": - return statistics.fileStats.getFolderCount(); - case "chunk_count": - return statistics.fileStats.getChunkCount(); - case "entity_count": - return statistics.fileStats.getEntityCount(); - case "players": - return statistics.players.getUniqueJoins(); - case "days": - return statistics.mapAge.getDaysPart().toString(); - case "months": - return statistics.mapAge.getMonthsPart().toString(); - case "years": - return statistics.mapAge.getYearsPart().toString(); - case "age_in_days": - return statistics.mapAge.asDays().toString(); - case "age_in_months": - return statistics.mapAge.asMonths().toString(); - case "age_in_years": - return statistics.mapAge.asYears().toString(); - default: - return null; - } - } -} \ No newline at end of file diff --git a/src/main/java/me/xginko/betterworldstats/Statistics.java b/src/main/java/me/xginko/betterworldstats/Statistics.java index e67d76f..7aa6e4e 100644 --- a/src/main/java/me/xginko/betterworldstats/Statistics.java +++ b/src/main/java/me/xginko/betterworldstats/Statistics.java @@ -1,24 +1,23 @@ package me.xginko.betterworldstats; -import me.xginko.betterworldstats.stats.FileStats; -import me.xginko.betterworldstats.stats.MapAge; -import me.xginko.betterworldstats.stats.Players; -import org.bukkit.event.HandlerList; +import me.xginko.betterworldstats.stats.WorldStats; +import me.xginko.betterworldstats.stats.BirthCalendar; +import me.xginko.betterworldstats.stats.PlayerStats; import org.jetbrains.annotations.NotNull; -public class Statistics { +public final class Statistics { - public final @NotNull MapAge mapAge; - public final @NotNull FileStats fileStats; - public final @NotNull Players players; + public final @NotNull BirthCalendar birthCalendar; + public final @NotNull WorldStats worldStats; + public final @NotNull PlayerStats playerStats; public Statistics() { - this.fileStats = new FileStats(); - this.mapAge = new MapAge(); - this.players = new Players(); + this.worldStats = new WorldStats(); + this.birthCalendar = new BirthCalendar(); + this.playerStats = new PlayerStats(); } public void shutdown() { - HandlerList.unregisterAll(players); + playerStats.disable(); } } diff --git a/src/main/java/me/xginko/betterworldstats/commands/betterworldstats/BetterWorldStatsCmd.java b/src/main/java/me/xginko/betterworldstats/commands/betterworldstats/BetterWorldStatsCmd.java index 4fec05d..00ec426 100644 --- a/src/main/java/me/xginko/betterworldstats/commands/betterworldstats/BetterWorldStatsCmd.java +++ b/src/main/java/me/xginko/betterworldstats/commands/betterworldstats/BetterWorldStatsCmd.java @@ -1,6 +1,5 @@ package me.xginko.betterworldstats.commands.betterworldstats; -import me.xginko.betterworldstats.BetterWorldStats; import me.xginko.betterworldstats.commands.BWSCmd; import me.xginko.betterworldstats.commands.SubCmd; import me.xginko.betterworldstats.commands.betterworldstats.subcommands.ReloadSubCmd; @@ -58,11 +57,11 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command } private void sendCommandOverview(CommandSender sender) { - KyoriUtil.sendMessage(sender, Component.text("-----------------------------------------------------").color(BetterWorldStats.COLOR)); - KyoriUtil.sendMessage(sender, Component.text("BetterWorldStats Commands").color(BetterWorldStats.COLOR)); - KyoriUtil.sendMessage(sender, Component.text("-----------------------------------------------------").color(BetterWorldStats.COLOR)); + KyoriUtil.sendMessage(sender, Component.text("-----------------------------------------------------").color(KyoriUtil.GUPPIE_GREEN)); + KyoriUtil.sendMessage(sender, Component.text("BetterWorldStats Commands").color(KyoriUtil.GUPPIE_GREEN)); + KyoriUtil.sendMessage(sender, Component.text("-----------------------------------------------------").color(KyoriUtil.GUPPIE_GREEN)); for (SubCmd subCmd : subCmds) KyoriUtil.sendMessage(sender, subCmd.getSyntax().append(Component.text(" - ").color(NamedTextColor.DARK_GRAY)).append(subCmd.getDescription())); - KyoriUtil.sendMessage(sender, Component.text("-----------------------------------------------------").color(BetterWorldStats.COLOR)); + KyoriUtil.sendMessage(sender, Component.text("-----------------------------------------------------").color(KyoriUtil.GUPPIE_GREEN)); } } diff --git a/src/main/java/me/xginko/betterworldstats/commands/betterworldstats/subcommands/ReloadSubCmd.java b/src/main/java/me/xginko/betterworldstats/commands/betterworldstats/subcommands/ReloadSubCmd.java index 74d49ab..6a63604 100644 --- a/src/main/java/me/xginko/betterworldstats/commands/betterworldstats/subcommands/ReloadSubCmd.java +++ b/src/main/java/me/xginko/betterworldstats/commands/betterworldstats/subcommands/ReloadSubCmd.java @@ -24,7 +24,7 @@ public TextComponent getDescription() { @Override public TextComponent getSyntax() { - return Component.text("/bws reload").color(BetterWorldStats.COLOR); + return Component.text("/bws reload").color(KyoriUtil.GUPPIE_GREEN); } @Override diff --git a/src/main/java/me/xginko/betterworldstats/commands/betterworldstats/subcommands/VersionSubCmd.java b/src/main/java/me/xginko/betterworldstats/commands/betterworldstats/subcommands/VersionSubCmd.java index baa0d56..877c41d 100644 --- a/src/main/java/me/xginko/betterworldstats/commands/betterworldstats/subcommands/VersionSubCmd.java +++ b/src/main/java/me/xginko/betterworldstats/commands/betterworldstats/subcommands/VersionSubCmd.java @@ -26,7 +26,7 @@ public TextComponent getDescription() { @Override public TextComponent getSyntax() { - return Component.text("/bws version").color(BetterWorldStats.COLOR); + return Component.text("/bws version").color(KyoriUtil.GUPPIE_GREEN); } @Override diff --git a/src/main/java/me/xginko/betterworldstats/commands/worldstats/WorldStatsCmd.java b/src/main/java/me/xginko/betterworldstats/commands/worldstats/WorldStatsCmd.java index 5f50a39..883305e 100644 --- a/src/main/java/me/xginko/betterworldstats/commands/worldstats/WorldStatsCmd.java +++ b/src/main/java/me/xginko/betterworldstats/commands/worldstats/WorldStatsCmd.java @@ -40,19 +40,19 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command for (final Component line : BetterWorldStats.getLang(sender).worldStatsMsg( sender, - statistics.mapAge.getYearsPart().toString(), - statistics.mapAge.getMonthsPart().toString(), - statistics.mapAge.getDaysPart().toString(), - statistics.players.getUniqueJoins(), - statistics.fileStats.getSize(), - statistics.fileStats.getSpoofedSize(), - statistics.mapAge.asDays().toString(), - statistics.mapAge.asMonths().toString(), - statistics.mapAge.asYears().toString(), - statistics.fileStats.getFileCount(), - statistics.fileStats.getFolderCount(), - statistics.fileStats.getChunkCount(), - statistics.fileStats.getEntityCount() + statistics.birthCalendar.getYearsPart().toString(), + statistics.birthCalendar.getMonthsPart().toString(), + statistics.birthCalendar.getDaysPart().toString(), + statistics.playerStats.getUniqueJoins(), + statistics.worldStats.getSize(), + statistics.worldStats.getSpoofedSize(), + statistics.birthCalendar.asDays().toString(), + statistics.birthCalendar.asMonths().toString(), + statistics.birthCalendar.asYears().toString(), + statistics.worldStats.getFileCount(), + statistics.worldStats.getFolderCount(), + statistics.worldStats.getChunkCount(), + statistics.worldStats.getEntityCount() )) { KyoriUtil.sendMessage(sender, line); } diff --git a/src/main/java/me/xginko/betterworldstats/config/LanguageCache.java b/src/main/java/me/xginko/betterworldstats/config/LanguageCache.java index 2c4fed2..0494d90 100644 --- a/src/main/java/me/xginko/betterworldstats/config/LanguageCache.java +++ b/src/main/java/me/xginko/betterworldstats/config/LanguageCache.java @@ -36,14 +36,14 @@ public LanguageCache(String language) throws Exception { this.langFile.addComment( "Command Placeholders:" + - "\n %size% | %spoofsize% | %players% | %years% | %months% | %days%" + + "\n %size% | %spoofsize% | %playerStats% | %years% | %months% | %days%" + "\n %age_in_days% | %age_in_months% | %age_in_years% | %file_count% | %folder_count% | %chunk_count%" + "\n %entity_count% " ); this.world_stats_message_serialized = getListTranslation("stats-message", "-----------------------------------------------------", - " The server has spawned %players% player(s) at least once", + " The server has spawned %playerStats% player(s) at least once", " The map is %years% year(s), %months% month(s) and %days% day(s) old", " The world is a total of %size% GB", "-----------------------------------------------------" @@ -60,11 +60,7 @@ public LanguageCache(String language) throws Exception { } public @NotNull Component noPermissionMsg(CommandSender sender) { - return MiniMessage.builder() - .tags(PAPIUtil.papiTagResolver(sender)) - .tags(TagResolver.standard()) - .build() - .deserialize(no_permission_serialized); + return MiniMessage.miniMessage().deserialize(no_permission_serialized, PAPIUtil.papiTagResolver(sender)); } public @NotNull List worldStatsMsg( @@ -75,25 +71,22 @@ public LanguageCache(String language) throws Exception { String fileCount, String folderCount, String chunkCount, String entityCount ) { - final MiniMessage miniMessage = MiniMessage.builder() - .tags(PAPIUtil.papiTagResolver(sender)) - .tags(TagResolver.standard()) - .build(); return world_stats_message_serialized.stream() - .map(line -> miniMessage.deserialize(line - .replace("%years%", years) - .replace("%months%", months) - .replace("%days%", days) - .replace("%players%", players) - .replace("%size%", fileSize) - .replace("%spoofsize%", spoofSize) - .replace("%age_in_days%", ageAsDays) - .replace("%age_in_months%", ageAsMonths) - .replace("%age_in_years%", ageAsYears) - .replace("%file_count%", fileCount) - .replace("%folder_count%", folderCount) - .replace("%chunk_count%", chunkCount) - .replace("%entity_count%", entityCount) + .map(line -> MiniMessage.miniMessage().deserialize( + line.replace("%years%", years) + .replace("%months%", months) + .replace("%days%", days) + .replace("%playerStats%", players) + .replace("%size%", fileSize) + .replace("%spoofsize%", spoofSize) + .replace("%age_in_days%", ageAsDays) + .replace("%age_in_months%", ageAsMonths) + .replace("%age_in_years%", ageAsYears) + .replace("%file_count%", fileCount) + .replace("%folder_count%", folderCount) + .replace("%chunk_count%", chunkCount) + .replace("%entity_count%", entityCount), + PAPIUtil.papiTagResolver(sender) )) .collect(Collectors.toList()); } diff --git a/src/main/java/me/xginko/betterworldstats/hooks/BWSHook.java b/src/main/java/me/xginko/betterworldstats/hooks/BWSHook.java new file mode 100644 index 0000000..979d09e --- /dev/null +++ b/src/main/java/me/xginko/betterworldstats/hooks/BWSHook.java @@ -0,0 +1,32 @@ +package me.xginko.betterworldstats.hooks; + +import java.util.HashSet; +import java.util.Set; + +public interface BWSHook { + + String pluginName(); + boolean canHook(); + void hook(); + void unHook(); + + Set HOOKS = new HashSet<>(); + + static void reloadHooks() { + HOOKS.forEach(BWSHook::unHook); + HOOKS.clear(); + + try { + HOOKS.add(new PAPIExpansion()); + } catch (Throwable ignored) { + } + + for (BWSHook hook : HOOKS) { + if (hook.canHook()) { + hook.hook(); + } else { + HOOKS.remove(hook); + } + } + } +} diff --git a/src/main/java/me/xginko/betterworldstats/hooks/PAPIExpansion.java b/src/main/java/me/xginko/betterworldstats/hooks/PAPIExpansion.java new file mode 100644 index 0000000..1eb0d33 --- /dev/null +++ b/src/main/java/me/xginko/betterworldstats/hooks/PAPIExpansion.java @@ -0,0 +1,87 @@ +package me.xginko.betterworldstats.hooks; + +import me.clip.placeholderapi.expansion.PlaceholderExpansion; +import me.xginko.betterworldstats.BetterWorldStats; +import me.xginko.betterworldstats.Statistics; +import me.xginko.betterworldstats.hooks.BWSHook; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public final class PAPIExpansion extends PlaceholderExpansion implements BWSHook { + + private final @NotNull Statistics statistics; + + PAPIExpansion() { + this.statistics = BetterWorldStats.getStatistics(); + } + + @Override + public String pluginName() { + return "PlaceholderAPI"; + } + + @Override + public boolean canHook() { + return BetterWorldStats.getInstance().getServer().getPluginManager().isPluginEnabled(pluginName()); + } + + @Override + public void hook() { + register(); + } + + @Override + public void unHook() { + unregister(); + } + + @Override + public @NotNull String getAuthor() { + return BetterWorldStats.getInstance().getDescription().getAuthors().get(0); + } + + @Override + public @NotNull String getIdentifier() { + return BetterWorldStats.getLog().getName(); + } + + @Override + public @NotNull String getVersion() { + return BetterWorldStats.getInstance().getDescription().getVersion(); + } + + @Override + public @Nullable String onPlaceholderRequest(Player player, @NotNull String identifier) { + switch (identifier) { + case "size": + return statistics.worldStats.getSize(); + case "spoofsize": + return statistics.worldStats.getSpoofedSize(); + case "file_count": + return statistics.worldStats.getFileCount(); + case "folder_count": + return statistics.worldStats.getFolderCount(); + case "chunk_count": + return statistics.worldStats.getChunkCount(); + case "entity_count": + return statistics.worldStats.getEntityCount(); + case "playerStats": + return statistics.playerStats.getUniqueJoins(); + case "days": + return statistics.birthCalendar.getDaysPart().toString(); + case "months": + return statistics.birthCalendar.getMonthsPart().toString(); + case "years": + return statistics.birthCalendar.getYearsPart().toString(); + case "age_in_days": + return statistics.birthCalendar.asDays().toString(); + case "age_in_months": + return statistics.birthCalendar.asMonths().toString(); + case "age_in_years": + return statistics.birthCalendar.asYears().toString(); + default: + return null; + } + } +} \ No newline at end of file diff --git a/src/main/java/me/xginko/betterworldstats/stats/MapAge.java b/src/main/java/me/xginko/betterworldstats/stats/BirthCalendar.java similarity index 98% rename from src/main/java/me/xginko/betterworldstats/stats/MapAge.java rename to src/main/java/me/xginko/betterworldstats/stats/BirthCalendar.java index d028960..8be034b 100644 --- a/src/main/java/me/xginko/betterworldstats/stats/MapAge.java +++ b/src/main/java/me/xginko/betterworldstats/stats/BirthCalendar.java @@ -9,14 +9,14 @@ import java.util.Calendar; import java.util.concurrent.TimeUnit; -public class MapAge { +public class BirthCalendar { private final @NotNull Calendar calendar; private final @NotNull Cache cache; private enum CalendarKey { DAYS_PART, MONTHS_PART, YEARS_PART, DAYS, MONTHS }; private final long server_birth_time_millis; - public MapAge() { + public BirthCalendar() { this.calendar = Calendar.getInstance(BetterWorldStats.getConfiguration().timeZone); this.cache = Caffeine.newBuilder().expireAfterWrite(Duration.ofMinutes(1)).build(); this.server_birth_time_millis = BetterWorldStats.getConfiguration().server_birth_time_millis; diff --git a/src/main/java/me/xginko/betterworldstats/stats/Players.java b/src/main/java/me/xginko/betterworldstats/stats/PlayerStats.java similarity index 78% rename from src/main/java/me/xginko/betterworldstats/stats/Players.java rename to src/main/java/me/xginko/betterworldstats/stats/PlayerStats.java index 5b48d36..0a801ff 100644 --- a/src/main/java/me/xginko/betterworldstats/stats/Players.java +++ b/src/main/java/me/xginko/betterworldstats/stats/PlayerStats.java @@ -1,19 +1,21 @@ package me.xginko.betterworldstats.stats; import me.xginko.betterworldstats.BetterWorldStats; +import me.xginko.betterworldstats.utils.Disableable; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import org.jetbrains.annotations.NotNull; import java.util.concurrent.atomic.AtomicInteger; -public class Players implements Listener { +public class PlayerStats implements Listener, Disableable { private final @NotNull AtomicInteger uniquePlayers; - public Players() { + public PlayerStats() { BetterWorldStats plugin = BetterWorldStats.getInstance(); this.uniquePlayers = new AtomicInteger(plugin.getServer().getOfflinePlayers().length); plugin.getServer().getPluginManager().registerEvents(this, plugin); @@ -29,4 +31,9 @@ private void onPlayerJoin(PlayerJoinEvent event) { public String getUniqueJoins() { return uniquePlayers.toString(); } + + @Override + public void disable() { + HandlerList.unregisterAll(this); + } } diff --git a/src/main/java/me/xginko/betterworldstats/stats/FileStats.java b/src/main/java/me/xginko/betterworldstats/stats/WorldStats.java similarity index 96% rename from src/main/java/me/xginko/betterworldstats/stats/FileStats.java rename to src/main/java/me/xginko/betterworldstats/stats/WorldStats.java index 8030d4b..8cfe0dc 100644 --- a/src/main/java/me/xginko/betterworldstats/stats/FileStats.java +++ b/src/main/java/me/xginko/betterworldstats/stats/WorldStats.java @@ -3,6 +3,7 @@ import io.papermc.lib.PaperLib; import me.xginko.betterworldstats.BetterWorldStats; import me.xginko.betterworldstats.config.Config; +import me.xginko.betterworldstats.utils.KyoriUtil; import net.kyori.adventure.text.Component; import org.bukkit.World; import org.jetbrains.annotations.NotNull; @@ -12,14 +13,14 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; -public class FileStats { +public class WorldStats { private final @NotNull Config config; private final @NotNull AtomicReference scan_result; private final @NotNull AtomicInteger chunk_count, entity_count; private boolean scanning = false; - public FileStats() { + public WorldStats() { this.config = BetterWorldStats.getConfiguration(); this.scan_result = new AtomicReference<>(); this.chunk_count = new AtomicInteger(); @@ -39,13 +40,13 @@ private void refresh() { scanning = false; if (config.log_is_enabled) { BetterWorldStats.getLog().info(Component.text( - "Updated file stats asynchronously.").color(BetterWorldStats.COLOR)); + "Updated file stats asynchronously.").color(KyoriUtil.GUPPIE_GREEN)); BetterWorldStats.getLog().info(Component.text( "Size: " + config.filesize_format.format(result.size_in_gb) + "GB, " + "files: " + result.file_count + ", " + "folders: " + result.folder_count + ", " + "chunks: " + chunk_count + ", " + - "entities: " + entity_count).color(BetterWorldStats.COLOR)); + "entities: " + entity_count).color(KyoriUtil.GUPPIE_GREEN)); } }); diff --git a/src/main/java/me/xginko/betterworldstats/utils/Disableable.java b/src/main/java/me/xginko/betterworldstats/utils/Disableable.java new file mode 100644 index 0000000..74b493f --- /dev/null +++ b/src/main/java/me/xginko/betterworldstats/utils/Disableable.java @@ -0,0 +1,5 @@ +package me.xginko.betterworldstats.utils; + +public interface Disableable { + void disable(); +} diff --git a/src/main/java/me/xginko/betterworldstats/utils/KyoriUtil.java b/src/main/java/me/xginko/betterworldstats/utils/KyoriUtil.java index 4e05109..fe396a3 100644 --- a/src/main/java/me/xginko/betterworldstats/utils/KyoriUtil.java +++ b/src/main/java/me/xginko/betterworldstats/utils/KyoriUtil.java @@ -3,6 +3,9 @@ import me.xginko.betterworldstats.BetterWorldStats; import net.kyori.adventure.identity.Identity; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.format.TextDecoration; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; @@ -11,6 +14,9 @@ public final class KyoriUtil { + public static final TextColor GUPPIE_GREEN = TextColor.color(0,255,128); + public static final Style GUPPIE_GREEN_BOLD = Style.style(GUPPIE_GREEN, TextDecoration.BOLD); + public static void sendMessage(@NotNull CommandSender sender, @NotNull Component message) { BetterWorldStats.getAudiences().sender(sender).sendMessage(message); } diff --git a/src/main/resources/lang/de_de.yml b/src/main/resources/lang/de_de.yml index e2516d8..e547e10 100644 --- a/src/main/resources/lang/de_de.yml +++ b/src/main/resources/lang/de_de.yml @@ -3,10 +3,10 @@ # %months% # %days% # %size% -# %players% +# %playerStats% stats-message: - '-----------------------------------------------------' - - '%players% Spieler sind dem Server mindestens einmal beigetreten. ' + - '%playerStats% Spieler sind dem Server mindestens einmal beigetreten. ' - 'Die Welt ist %years% Jahr(e), %months% Monat(e) und %days% Tag(e) alt, mit einer' - 'Dateigröße von insgesamt %size% GB' - '-----------------------------------------------------' diff --git a/src/main/resources/lang/en_us.yml b/src/main/resources/lang/en_us.yml index 3cec458..e6b704e 100644 --- a/src/main/resources/lang/en_us.yml +++ b/src/main/resources/lang/en_us.yml @@ -3,10 +3,10 @@ # %months% # %days% # %size% -# %players% +# %playerStats% stats-message: - '-----------------------------------------------------' - - ' The server has spawned %players% player(s) at least once' + - ' The server has spawned %playerStats% player(s) at least once' - ' The map is %years% year(s), %months% month(s) and %days% day(s) old' - ' The world (with compression) is a total of %size% GB' - '-----------------------------------------------------' diff --git a/src/main/resources/lang/es_es.yml b/src/main/resources/lang/es_es.yml index ecd68b9..deb05f0 100644 --- a/src/main/resources/lang/es_es.yml +++ b/src/main/resources/lang/es_es.yml @@ -3,10 +3,10 @@ # %months% # %days% # %size% -# %players% +# %playerStats% stats-message: - '-----------------------------------------------------' - - ' En en Server Spawnearon %players% Jugador(s) Al menos una vez' + - ' En en Server Spawnearon %playerStats% Jugador(s) Al menos una vez' - ' El Mapa Tiene %years% Años(s), %months% Meses(s) y %days% Dias(s) De antiguedad' - ' El Mundo (Comprimido) Es un total a %size% GB' - '-----------------------------------------------------' diff --git a/src/main/resources/lang/ru_ru.yml b/src/main/resources/lang/ru_ru.yml index db276aa..b68579e 100644 --- a/src/main/resources/lang/ru_ru.yml +++ b/src/main/resources/lang/ru_ru.yml @@ -3,10 +3,10 @@ # %months% # %days% # %size% -# %players% +# %playerStats% stats-message: - '-----------------------------------------------------' - - ' Этот сервер посетило %players% игрок(ов) за всё время' + - ' Этот сервер посетило %playerStats% игрок(ов) за всё время' - ' Этому миру %years% год, %months% месяц и %days% день' - ' Мир весит %size% гигабайт' - '-----------------------------------------------------' diff --git a/src/main/resources/lang/uk_ua.yml b/src/main/resources/lang/uk_ua.yml index 89af8fc..bb76d63 100644 --- a/src/main/resources/lang/uk_ua.yml +++ b/src/main/resources/lang/uk_ua.yml @@ -3,10 +3,10 @@ # %months% # %days% # %size% -# %players% +# %playerStats% stats-message: - '-----------------------------------------------------' - - ' Цей сервер відвідало %players% гравців за увесь час' + - ' Цей сервер відвідало %playerStats% гравців за увесь час' - ' Цьому світу %years% років, %months% місяць та %days% день' - ' Світ вісить %size% гігабайт' - '-----------------------------------------------------' diff --git a/src/main/resources/lang/zh_cn.yml b/src/main/resources/lang/zh_cn.yml index 866fc9c..2472443 100644 --- a/src/main/resources/lang/zh_cn.yml +++ b/src/main/resources/lang/zh_cn.yml @@ -3,10 +3,10 @@ # %months% # %days% # %size% -# %players% +# %playerStats% stats-message: - '-----------------------------------------------------' - - ' 这个服务器有 %players% 个玩家加入过' + - ' 这个服务器有 %playerStats% 个玩家加入过' - ' 该地图大小已有 %years% 年 %months% 月 %days% 日 之久' - ' 该世界大小已经达到了 %size% GB' - '-----------------------------------------------------'