progress baby

This commit is contained in:
xGinko 2023-09-06 22:20:27 +02:00
parent f2850d11ab
commit 84e9542f19
6 changed files with 114 additions and 31 deletions

View File

@ -21,8 +21,10 @@ import org.jetbrains.annotations.NotNull;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.*; import java.util.HashMap;
import java.util.jar.JarEntry; import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -146,12 +148,11 @@ public final class VillagerOptimizer extends JavaPlugin {
private Set<String> getDefaultLanguageFiles() { private Set<String> getDefaultLanguageFiles() {
Set<String> languageFiles = new HashSet<>(); Set<String> languageFiles = new HashSet<>();
try (JarFile jarFile = new JarFile(this.getFile())) { try (JarFile jarFile = new JarFile(this.getFile())) {
Iterator<JarEntry> defFileIterator = jarFile.entries().asIterator(); jarFile.entries().asIterator().forEachRemaining(jarEntry -> {
while (defFileIterator.hasNext()) { final String path = jarEntry.getName();
final String path = defFileIterator.next().getName();
if (path.startsWith("lang/") && path.endsWith(".yml")) if (path.startsWith("lang/") && path.endsWith(".yml"))
languageFiles.add(path); languageFiles.add(path);
} });
} catch (IOException e) { } catch (IOException e) {
logger.severe("Error while getting default language file names! - " + e.getLocalizedMessage()); logger.severe("Error while getting default language file names! - " + e.getLocalizedMessage());
e.printStackTrace(); e.printStackTrace();

View File

@ -14,13 +14,24 @@ public class LanguageCache {
private final MiniMessage miniMessage; private final MiniMessage miniMessage;
public final Component no_permission; public final Component no_permission;
public final List<Component> 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 { public LanguageCache(String lang) throws Exception {
this.lang = loadLang(new File(VillagerOptimizer.getInstance().getDataFolder() + File.separator + "lang", lang + ".yml")); this.lang = loadLang(new File(VillagerOptimizer.getInstance().getDataFolder() + File.separator + "lang", lang + ".yml"));
this.miniMessage = MiniMessage.miniMessage(); this.miniMessage = MiniMessage.miniMessage();
// No Permission this.no_permission = getTranslation("messages.no-permission", "<red>You don't have permission to use this command.");
this.no_permission = getTranslation("no-permission", "<red>You don't have permission to use this command.", false); this.nametag_optimize_success = getListTranslation("messages.nametag.optimize-success", List.of("<green>Successfully optimized villager by using a nametag."));
this.nametag_on_optimize_cooldown = getListTranslation("messages.nametag.optimize-on-cooldown", List.of("<gray>You need to wait %time% until you can optimize this villager again."));
this.nametag_unoptimize_success = getListTranslation("messages.nametag.unoptimize-success", List.of("<green>Successfully unoptimized villager by using a nametag."));
this.block_optimization_success = getListTranslation("messages.block.optimize-success", List.of("<green>%villagertype% villager successfully optimized using block %blocktype%."));
this.block_on_optimize_cooldown = getListTranslation("messages.block.optimize-on-cooldown", List.of("<gray>You need to wait %time% until you can optimize this villager again."));
this.block_unoptimize_success = getListTranslation("messages.block.unoptimize-success", List.of("<green>Successfully unoptimized villager by moving it off a %blocktype% block."));
this.workstation_optimization_success = getListTranslation("messages.workstation.optimize-success", List.of("<green>%villagertype% villager successfully optimized using workstation block %blocktype%."));
this.workstation_on_optimize_cooldown = getListTranslation("messages.workstation.optimize-on-cooldown", List.of("<gray>You need to wait %time% until you can optimize this villager again."));
this.workstation_unoptimize_success = getListTranslation("messages.workstation.unoptimize-success", List.of("<green>Successfully unoptimized villager by removing workstation block %blocktype%."));
saveLang(); 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); 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); 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<Component> getListTranslation(String path, List<String> defaultTranslation, boolean upperCase) { public List<Component> getListTranslation(String path, List<String> defaultTranslation) {
lang.addDefault(path, 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<Component> getListTranslation(String path, List<String> defaultTranslation, boolean upperCase, String comment) { public List<Component> getListTranslation(String path, List<String> defaultTranslation, String comment) {
lang.addDefault(path, defaultTranslation, 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();
} }
} }

View File

@ -6,22 +6,23 @@ import me.xginko.villageroptimizer.enums.OptimizationType;
import org.bukkit.entity.Villager; import org.bukkit.entity.Villager;
import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType; import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
public final class WrappedVillager { public final class WrappedVillager {
private final Villager villager; private final @NotNull Villager villager;
private final PersistentDataContainer villagerData; private final @NotNull PersistentDataContainer villagerData;
public WrappedVillager(Villager villager) { public WrappedVillager(@NotNull Villager villager) {
this.villager = villager; this.villager = villager;
this.villagerData = villager.getPersistentDataContainer(); this.villagerData = villager.getPersistentDataContainer();
} }
public Villager villager() { public @NotNull Villager villager() {
return villager; return villager;
} }
public static WrappedVillager fromVillager(Villager villager) { public static @NotNull WrappedVillager fromVillager(Villager villager) {
return VillagerOptimizer.getVillagerCache().get(villager); return VillagerOptimizer.getVillagerCache().get(villager);
} }
@ -29,24 +30,25 @@ public final class WrappedVillager {
return villagerData.has(Keys.OPTIMIZED.key()); return villagerData.has(Keys.OPTIMIZED.key());
} }
public boolean setOptimization(OptimizationType type) { public @NotNull OptimizationType computePossibleOptimization() {
if (isOnOptimizeCooldown()) return false; return VillagerOptimizer.computeOptimization(this);
}
public boolean setOptimization(OptimizationType type) {
if (type.equals(OptimizationType.OFF) && isOptimized()) { if (type.equals(OptimizationType.OFF) && isOptimized()) {
villagerData.remove(Keys.OPTIMIZED.key()); villagerData.remove(Keys.OPTIMIZED.key());
villager.setAware(true); villager.setAware(true);
villager.setAI(true); villager.setAI(true);
setOptimizeCooldown(VillagerOptimizer.getConfiguration().state_change_cooldown);
} else { } else {
if (isOnOptimizeCooldown()) return false;
setOptimizeCooldown(VillagerOptimizer.getConfiguration().state_change_cooldown);
villagerData.set(Keys.OPTIMIZED.key(), PersistentDataType.STRING, type.name()); villagerData.set(Keys.OPTIMIZED.key(), PersistentDataType.STRING, type.name());
villager.setAware(false); villager.setAware(false);
setOptimizeCooldown(VillagerOptimizer.getConfiguration().state_change_cooldown);
} }
return true; return true;
} }
public OptimizationType getOptimizationType() { public @NotNull OptimizationType getOptimizationType() {
return isOptimized() ? OptimizationType.valueOf(villagerData.get(Keys.OPTIMIZED.key(), PersistentDataType.STRING)) : OptimizationType.OFF; 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); 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() { public boolean isOnOptimizeCooldown() {
return villagerData.has(Keys.COOLDOWN_OPTIMIZE.key(), PersistentDataType.LONG) && villagerData.get(Keys.COOLDOWN_OPTIMIZE.key(), PersistentDataType.LONG) <= System.currentTimeMillis(); return villagerData.has(Keys.COOLDOWN_OPTIMIZE.key(), PersistentDataType.LONG) && villagerData.get(Keys.COOLDOWN_OPTIMIZE.key(), PersistentDataType.LONG) <= System.currentTimeMillis();
} }

View File

@ -6,9 +6,12 @@ import me.xginko.villageroptimizer.config.Config;
import me.xginko.villageroptimizer.enums.OptimizationType; import me.xginko.villageroptimizer.enums.OptimizationType;
import me.xginko.villageroptimizer.models.VillagerCache; import me.xginko.villageroptimizer.models.VillagerCache;
import me.xginko.villageroptimizer.models.WrappedVillager; import me.xginko.villageroptimizer.models.WrappedVillager;
import me.xginko.villageroptimizer.utils.CommonUtils;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.entity.Villager; import org.bukkit.entity.Villager;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
@ -19,12 +22,13 @@ public class NametagOptimization implements VillagerOptimizerModule, Listener {
private final VillagerCache cache; private final VillagerCache cache;
private final Config config; private final Config config;
private final boolean shouldLog; private final boolean shouldLog, shouldNotifyPlayer;
protected NametagOptimization() { protected NametagOptimization() {
this.cache = VillagerOptimizer.getVillagerCache(); this.cache = VillagerOptimizer.getVillagerCache();
this.config = VillagerOptimizer.getConfiguration(); this.config = VillagerOptimizer.getConfiguration();
this.shouldLog = config.getBoolean("optimization.methods.by-nametag.log", false); this.shouldLog = config.getBoolean("optimization.methods.by-nametag.log", false);
this.shouldNotifyPlayer = config.getBoolean("optimization.methods.by-nametag.notify-player", true);
} }
@Override @Override
@ -54,13 +58,31 @@ public class NametagOptimization implements VillagerOptimizerModule, Listener {
if (config.nametags.contains(nameTag.toLowerCase())) { if (config.nametags.contains(nameTag.toLowerCase())) {
if (!wVillager.isOptimized()) { if (!wVillager.isOptimized()) {
wVillager.setOptimization(OptimizationType.NAMETAG); if (wVillager.setOptimization(OptimizationType.NAMETAG)) {
if (shouldLog) VillagerOptimizer.getLog().info(event.getPlayer().getName() + " optimized a villager using nametag: '" + 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 { } else {
if (wVillager.isOptimized()) { if (wVillager.isOptimized()) {
wVillager.setOptimization(OptimizationType.OFF); 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 + "'");
} }
} }
} }

View File

@ -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);
}
}
}

View File

@ -0,0 +1,23 @@
messages:
no-permission: "<red>You don't have permission to use this command."
nametag:
optimize-success:
- "<green>Successfully optimized villager by using a nametag."
optimize-on-cooldown:
- "<gray>You need to wait %time% until you can optimize this villager again."
unoptimize-success:
- "<green>Successfully unoptimized villager by using a nametag."
block:
optimize-success:
- "<green>%villagertype% villager successfully optimized using block %blocktype%."
optimize-on-cooldown:
- "<gray>You need to wait %time% until you can optimize this villager again."
unoptimize-success:
- "<green>Successfully unoptimized villager by moving it off a %blocktype% block."
workstation:
optimize-success:
- "<green>%villagertype% villager successfully optimized using workstation block %blocktype%."
optimize-on-cooldown:
- "<gray>You need to wait %time% until you can optimize this villager again."
unoptimize-success:
- "<green>Successfully unoptimized villager by removing workstation block %blocktype%."