From 84e9542f193fd695037df627411e87a0e23b945d Mon Sep 17 00:00:00 2001 From: xGinko Date: Wed, 6 Sep 2023 22:20:27 +0200 Subject: [PATCH] progress baby --- .../villageroptimizer/VillagerOptimizer.java | 13 ++++---- .../config/LanguageCache.java | 31 +++++++++++++------ .../models/WrappedVillager.java | 28 ++++++++++------- .../modules/NametagOptimization.java | 30 +++++++++++++++--- .../villageroptimizer/utils/CommonUtils.java | 20 ++++++++++++ src/main/resources/lang/en_us.yml | 23 ++++++++++++++ 6 files changed, 114 insertions(+), 31 deletions(-) create mode 100644 src/main/java/me/xginko/villageroptimizer/utils/CommonUtils.java diff --git a/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java b/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java index beec686..a13a611 100644 --- a/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java +++ b/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java @@ -21,8 +21,10 @@ import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; import java.nio.file.Files; -import java.util.*; -import java.util.jar.JarEntry; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; import java.util.jar.JarFile; import java.util.logging.Logger; import java.util.regex.Matcher; @@ -146,12 +148,11 @@ public final class VillagerOptimizer extends JavaPlugin { private Set getDefaultLanguageFiles() { Set languageFiles = new HashSet<>(); try (JarFile jarFile = new JarFile(this.getFile())) { - Iterator defFileIterator = jarFile.entries().asIterator(); - while (defFileIterator.hasNext()) { - final String path = defFileIterator.next().getName(); + jarFile.entries().asIterator().forEachRemaining(jarEntry -> { + final String path = jarEntry.getName(); if (path.startsWith("lang/") && path.endsWith(".yml")) languageFiles.add(path); - } + }); } catch (IOException e) { logger.severe("Error while getting default language file names! - " + e.getLocalizedMessage()); e.printStackTrace(); diff --git a/src/main/java/me/xginko/villageroptimizer/config/LanguageCache.java b/src/main/java/me/xginko/villageroptimizer/config/LanguageCache.java index 8a3f913..1206a30 100644 --- a/src/main/java/me/xginko/villageroptimizer/config/LanguageCache.java +++ b/src/main/java/me/xginko/villageroptimizer/config/LanguageCache.java @@ -14,13 +14,24 @@ public class LanguageCache { private final MiniMessage miniMessage; public final Component no_permission; + public final List nametag_optimize_success, nametag_on_optimize_cooldown, nametag_unoptimize_success, + block_optimization_success, block_on_optimize_cooldown, block_unoptimize_success, + workstation_optimization_success, workstation_on_optimize_cooldown, workstation_unoptimize_success; public LanguageCache(String lang) throws Exception { this.lang = loadLang(new File(VillagerOptimizer.getInstance().getDataFolder() + File.separator + "lang", lang + ".yml")); this.miniMessage = MiniMessage.miniMessage(); - // No Permission - this.no_permission = getTranslation("no-permission", "You don't have permission to use this command.", false); + this.no_permission = getTranslation("messages.no-permission", "You don't have permission to use this command."); + this.nametag_optimize_success = getListTranslation("messages.nametag.optimize-success", List.of("Successfully optimized villager by using a nametag.")); + this.nametag_on_optimize_cooldown = getListTranslation("messages.nametag.optimize-on-cooldown", List.of("You need to wait %time% until you can optimize this villager again.")); + this.nametag_unoptimize_success = getListTranslation("messages.nametag.unoptimize-success", List.of("Successfully unoptimized villager by using a nametag.")); + this.block_optimization_success = getListTranslation("messages.block.optimize-success", List.of("%villagertype% villager successfully optimized using block %blocktype%.")); + this.block_on_optimize_cooldown = getListTranslation("messages.block.optimize-on-cooldown", List.of("You need to wait %time% until you can optimize this villager again.")); + this.block_unoptimize_success = getListTranslation("messages.block.unoptimize-success", List.of("Successfully unoptimized villager by moving it off a %blocktype% block.")); + this.workstation_optimization_success = getListTranslation("messages.workstation.optimize-success", List.of("%villagertype% villager successfully optimized using workstation block %blocktype%.")); + this.workstation_on_optimize_cooldown = getListTranslation("messages.workstation.optimize-on-cooldown", List.of("You need to wait %time% until you can optimize this villager again.")); + this.workstation_unoptimize_success = getListTranslation("messages.workstation.unoptimize-success", List.of("Successfully unoptimized villager by removing workstation block %blocktype%.")); saveLang(); } @@ -43,23 +54,23 @@ public class LanguageCache { } } - public Component getTranslation(String path, String defaultTranslation, boolean upperCase) { + public Component getTranslation(String path, String defaultTranslation) { lang.addDefault(path, defaultTranslation); - return miniMessage.deserialize(upperCase ? lang.getString(path, defaultTranslation).toUpperCase() : lang.getString(path, defaultTranslation)); + return miniMessage.deserialize(lang.getString(path, defaultTranslation)); } - public Component getTranslation(String path, String defaultTranslation, boolean upperCase, String comment) { + public Component getTranslation(String path, String defaultTranslation, String comment) { lang.addDefault(path, defaultTranslation, comment); - return miniMessage.deserialize(upperCase ? lang.getString(path, defaultTranslation).toUpperCase() : lang.getString(path, defaultTranslation)); + return miniMessage.deserialize(lang.getString(path, defaultTranslation)); } - public List getListTranslation(String path, List defaultTranslation, boolean upperCase) { + public List getListTranslation(String path, List defaultTranslation) { lang.addDefault(path, defaultTranslation); - return lang.getStringList(path).stream().map(line -> miniMessage.deserialize(upperCase ? line.toUpperCase() : line)).toList(); + return lang.getStringList(path).stream().map(miniMessage::deserialize).toList(); } - public List getListTranslation(String path, List defaultTranslation, boolean upperCase, String comment) { + public List getListTranslation(String path, List defaultTranslation, String comment) { lang.addDefault(path, defaultTranslation, comment); - return lang.getStringList(path).stream().map(line -> miniMessage.deserialize(upperCase ? line.toUpperCase() : line)).toList(); + return lang.getStringList(path).stream().map(miniMessage::deserialize).toList(); } } diff --git a/src/main/java/me/xginko/villageroptimizer/models/WrappedVillager.java b/src/main/java/me/xginko/villageroptimizer/models/WrappedVillager.java index ae16abb..b40bc42 100644 --- a/src/main/java/me/xginko/villageroptimizer/models/WrappedVillager.java +++ b/src/main/java/me/xginko/villageroptimizer/models/WrappedVillager.java @@ -6,22 +6,23 @@ import me.xginko.villageroptimizer.enums.OptimizationType; import org.bukkit.entity.Villager; import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; +import org.jetbrains.annotations.NotNull; public final class WrappedVillager { - private final Villager villager; - private final PersistentDataContainer villagerData; + private final @NotNull Villager villager; + private final @NotNull PersistentDataContainer villagerData; - public WrappedVillager(Villager villager) { + public WrappedVillager(@NotNull Villager villager) { this.villager = villager; this.villagerData = villager.getPersistentDataContainer(); } - public Villager villager() { + public @NotNull Villager villager() { return villager; } - public static WrappedVillager fromVillager(Villager villager) { + public static @NotNull WrappedVillager fromVillager(Villager villager) { return VillagerOptimizer.getVillagerCache().get(villager); } @@ -29,24 +30,25 @@ public final class WrappedVillager { return villagerData.has(Keys.OPTIMIZED.key()); } - public boolean setOptimization(OptimizationType type) { - if (isOnOptimizeCooldown()) return false; + public @NotNull OptimizationType computePossibleOptimization() { + return VillagerOptimizer.computeOptimization(this); + } + public boolean setOptimization(OptimizationType type) { if (type.equals(OptimizationType.OFF) && isOptimized()) { villagerData.remove(Keys.OPTIMIZED.key()); villager.setAware(true); villager.setAI(true); - setOptimizeCooldown(VillagerOptimizer.getConfiguration().state_change_cooldown); } else { + if (isOnOptimizeCooldown()) return false; + setOptimizeCooldown(VillagerOptimizer.getConfiguration().state_change_cooldown); villagerData.set(Keys.OPTIMIZED.key(), PersistentDataType.STRING, type.name()); villager.setAware(false); - setOptimizeCooldown(VillagerOptimizer.getConfiguration().state_change_cooldown); } - return true; } - public OptimizationType getOptimizationType() { + public @NotNull OptimizationType getOptimizationType() { return isOptimized() ? OptimizationType.valueOf(villagerData.get(Keys.OPTIMIZED.key(), PersistentDataType.STRING)) : OptimizationType.OFF; } @@ -54,6 +56,10 @@ public final class WrappedVillager { villagerData.set(Keys.COOLDOWN_OPTIMIZE.key(), PersistentDataType.LONG, System.currentTimeMillis() + milliseconds); } + public long getOptimizeCooldown() { + return villagerData.has(Keys.COOLDOWN_OPTIMIZE.key(), PersistentDataType.LONG) ? System.currentTimeMillis() - villagerData.get(Keys.COOLDOWN_OPTIMIZE.key(), PersistentDataType.LONG) : 0L; + } + public boolean isOnOptimizeCooldown() { return villagerData.has(Keys.COOLDOWN_OPTIMIZE.key(), PersistentDataType.LONG) && villagerData.get(Keys.COOLDOWN_OPTIMIZE.key(), PersistentDataType.LONG) <= System.currentTimeMillis(); } diff --git a/src/main/java/me/xginko/villageroptimizer/modules/NametagOptimization.java b/src/main/java/me/xginko/villageroptimizer/modules/NametagOptimization.java index effe014..b40b555 100644 --- a/src/main/java/me/xginko/villageroptimizer/modules/NametagOptimization.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/NametagOptimization.java @@ -6,9 +6,12 @@ import me.xginko.villageroptimizer.config.Config; import me.xginko.villageroptimizer.enums.OptimizationType; import me.xginko.villageroptimizer.models.VillagerCache; import me.xginko.villageroptimizer.models.WrappedVillager; +import me.xginko.villageroptimizer.utils.CommonUtils; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextReplacementConfig; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; import org.bukkit.entity.Villager; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -19,12 +22,13 @@ public class NametagOptimization implements VillagerOptimizerModule, Listener { private final VillagerCache cache; private final Config config; - private final boolean shouldLog; + private final boolean shouldLog, shouldNotifyPlayer; protected NametagOptimization() { this.cache = VillagerOptimizer.getVillagerCache(); this.config = VillagerOptimizer.getConfiguration(); this.shouldLog = config.getBoolean("optimization.methods.by-nametag.log", false); + this.shouldNotifyPlayer = config.getBoolean("optimization.methods.by-nametag.notify-player", true); } @Override @@ -54,13 +58,31 @@ public class NametagOptimization implements VillagerOptimizerModule, Listener { if (config.nametags.contains(nameTag.toLowerCase())) { if (!wVillager.isOptimized()) { - wVillager.setOptimization(OptimizationType.NAMETAG); - if (shouldLog) VillagerOptimizer.getLog().info(event.getPlayer().getName() + " optimized a villager using nametag: '" + nameTag + "'"); + if (wVillager.setOptimization(OptimizationType.NAMETAG)) { + if (shouldNotifyPlayer) { + Player player = event.getPlayer(); + VillagerOptimizer.getLang(player.locale()).nametag_optimize_success.forEach(player::sendMessage); + } + if (shouldLog) + VillagerOptimizer.getLog().info(event.getPlayer().getName() + " optimized a villager using nametag: '" + nameTag + "'"); + } else { + if (shouldNotifyPlayer) { + Player player = event.getPlayer(); + VillagerOptimizer.getLang(player.locale()).nametag_on_optimize_cooldown.forEach(line -> + player.sendMessage(line.replaceText(TextReplacementConfig.builder().matchLiteral("%time").replacement(CommonUtils.formatTime(wVillager.getOptimizeCooldown())).build())) + ); + } + } } } else { if (wVillager.isOptimized()) { wVillager.setOptimization(OptimizationType.OFF); - if (shouldLog) VillagerOptimizer.getLog().info(event.getPlayer().getName() + " disabled optimizations for a villager using nametag: '" + nameTag + "'"); + if (shouldNotifyPlayer) { + Player player = event.getPlayer(); + VillagerOptimizer.getLang(player.locale()).nametag_unoptimize_success.forEach(player::sendMessage); + } + if (shouldLog) + VillagerOptimizer.getLog().info(event.getPlayer().getName() + " disabled optimizations for a villager using nametag: '" + nameTag + "'"); } } } diff --git a/src/main/java/me/xginko/villageroptimizer/utils/CommonUtils.java b/src/main/java/me/xginko/villageroptimizer/utils/CommonUtils.java new file mode 100644 index 0000000..de94838 --- /dev/null +++ b/src/main/java/me/xginko/villageroptimizer/utils/CommonUtils.java @@ -0,0 +1,20 @@ +package me.xginko.villageroptimizer.utils; + +import java.time.Duration; + +public class CommonUtils { + + public static String formatTime(long millis) { + Duration duration = Duration.ofMillis(millis); + final int seconds = duration.toSecondsPart(); + final int minutes = duration.toMinutesPart(); + final int hours = duration.toHoursPart(); + + if (hours > 0) { + return String.format("%02dh %02dm %02ds", hours, minutes, seconds); + } else { + return minutes > 0 ? String.format("%02dm %02ds", minutes, seconds) : String.format("%02ds", seconds); + } + } + +} diff --git a/src/main/resources/lang/en_us.yml b/src/main/resources/lang/en_us.yml index e69de29..14f2537 100644 --- a/src/main/resources/lang/en_us.yml +++ b/src/main/resources/lang/en_us.yml @@ -0,0 +1,23 @@ +messages: + no-permission: "You don't have permission to use this command." + nametag: + optimize-success: + - "Successfully optimized villager by using a nametag." + optimize-on-cooldown: + - "You need to wait %time% until you can optimize this villager again." + unoptimize-success: + - "Successfully unoptimized villager by using a nametag." + block: + optimize-success: + - "%villagertype% villager successfully optimized using block %blocktype%." + optimize-on-cooldown: + - "You need to wait %time% until you can optimize this villager again." + unoptimize-success: + - "Successfully unoptimized villager by moving it off a %blocktype% block." + workstation: + optimize-success: + - "%villagertype% villager successfully optimized using workstation block %blocktype%." + optimize-on-cooldown: + - "You need to wait %time% until you can optimize this villager again." + unoptimize-success: + - "Successfully unoptimized villager by removing workstation block %blocktype%." \ No newline at end of file