From 80ef3e7af77003fc8d455ab419a21c0cfc8fdf96 Mon Sep 17 00:00:00 2001 From: xGinko Date: Tue, 5 Sep 2023 20:44:39 +0200 Subject: [PATCH] add first features and fix some stuff --- .../villageroptimizer/VillagerOptimizer.java | 15 +++--- .../villageroptimizer/config/Config.java | 29 ++++++---- .../xginko/villageroptimizer/enums/Keys.java | 1 + .../models/WrappedVillager.java | 3 ++ .../modules/AntiVillagerDamage.java | 53 +++++++++++++++++++ .../modules/AntiVillagerTargetting.java | 50 +++++++++++++++++ .../villageroptimizer/modules/ChunkLimit.java | 2 +- .../modules/VillagerOptimizerModule.java | 5 +- 8 files changed, 136 insertions(+), 22 deletions(-) create mode 100644 src/main/java/me/xginko/villageroptimizer/modules/AntiVillagerDamage.java create mode 100644 src/main/java/me/xginko/villageroptimizer/modules/AntiVillagerTargetting.java diff --git a/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java b/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java index 97ce50d..beec686 100644 --- a/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java +++ b/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java @@ -40,7 +40,6 @@ public final class VillagerOptimizer extends JavaPlugin { public void onEnable() { instance = this; logger = getLogger(); - villagerCache = new VillagerCache(30); logger.info("Loading Translations"); reloadLang(); logger.info("Loading Config"); @@ -99,7 +98,6 @@ public final class VillagerOptimizer extends JavaPlugin { } public void reloadPlugin() { - villagerCache = new VillagerCache(30); reloadLang(); reloadConfiguration(); } @@ -107,10 +105,11 @@ public final class VillagerOptimizer extends JavaPlugin { private void reloadConfiguration() { try { config = new Config(); + villagerCache = new VillagerCache(config.cache_keep_time_seconds); VillagerOptimizerModule.reloadModules(); config.saveConfig(); } catch (Exception e) { - logger.severe("Failed to load config file! - " + e.getLocalizedMessage()); + logger.severe("Failed to load config! - " + e.getLocalizedMessage()); e.printStackTrace(); } } @@ -147,12 +146,11 @@ public final class VillagerOptimizer extends JavaPlugin { private Set getDefaultLanguageFiles() { Set languageFiles = new HashSet<>(); try (JarFile jarFile = new JarFile(this.getFile())) { - Enumeration entries = jarFile.entries(); - while (entries.hasMoreElements()) { - String path = entries.nextElement().getName(); - if (path.startsWith("lang/") && path.endsWith(".yml")) { + Iterator defFileIterator = jarFile.entries().asIterator(); + while (defFileIterator.hasNext()) { + final String path = defFileIterator.next().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()); @@ -197,6 +195,7 @@ public final class VillagerOptimizer extends JavaPlugin { public static Logger getLog() { return logger; } + public static VillagerCache getVillagerCache() { return villagerCache; } diff --git a/src/main/java/me/xginko/villageroptimizer/config/Config.java b/src/main/java/me/xginko/villageroptimizer/config/Config.java index 8522320..04749dc 100644 --- a/src/main/java/me/xginko/villageroptimizer/config/Config.java +++ b/src/main/java/me/xginko/villageroptimizer/config/Config.java @@ -17,11 +17,13 @@ public class Config { private final ConfigFile config; public final Locale default_lang; - public final boolean auto_lang, enable_nametag_optimization, enable_workstation_optimization, enable_block_optimization; + public final boolean auto_lang, enable_nametag_optimization, enable_workstation_optimization, enable_block_optimization, + cache_enabled; public final double workstation_max_distance; + public final long cache_keep_time_seconds; public final HashSet nametags = new HashSet<>(2); - public final HashSet blocks_that_disable = new HashSet<>(2); + public final HashSet blocks_that_disable = new HashSet<>(3); public final HashSet workstations_that_disable = new HashSet<>(13); public Config() throws Exception { @@ -35,23 +37,28 @@ public class Config { "The default language that will be used if auto-language is false or no matching language file was found.") .replace("_", "-")); this.auto_lang = getBoolean("language.auto-language", true, "If set to true, will display messages based on client language"); + /** + * General + */ + this.cache_enabled = getBoolean("general.plugin-cache.enable", true, "Leave enabled if you don't know what you're doing and or don't experience any issues."); + this.cache_keep_time_seconds = getInt("general.plugin-cache.expire-after-x-seconds", 30, "The amount of time in seconds a villager will be kept in cache."); /** * Optimization */ // Nametags - this.enable_nametag_optimization = getBoolean("optimization.by-nametag.enable", true); - this.nametags.addAll(getList("optimization.by-nametag.names", List.of("Optimize", "DisableAI"), "Names are case insensitive") + this.enable_nametag_optimization = getBoolean("optimization.methods.by-nametag.enable", true); + this.nametags.addAll(getList("optimization.methods.by-nametag.names", List.of("Optimize", "DisableAI"), "Names are case insensitive") .stream().map(String::toLowerCase).toList()); // Workstations - this.enable_workstation_optimization = getBoolean("optimization.by-workstation.enable", true, + this.enable_workstation_optimization = getBoolean("optimization.methods.by-workstation.enable", true, """ Optimize villagers that are standing near their acquired workstations /s Values here need to be valid bukkit Material enums for your server version. """ ); - this.workstation_max_distance = getDouble("optimization.by-workstation.", 4.0, + this.workstation_max_distance = getDouble("optimization.methods.by-workstation.", 4.0, "How close in blocks a villager needs to be to get optimized by its workstation"); - this.getList("optimization.by-workstation.workstation-materials", List.of( + this.getList("optimization.methods.by-workstation.workstation-materials", List.of( "COMPOSTER", "SMOKER", "BARREL", "LOOM", "BLAST_FURNACE", "BREWING_STAND", "CAULDRON", "FLETCHING_TABLE", "CARTOGRAPHY_TABLE", "LECTERN", "SMITHING_TABLE", "STONECUTTER", "GRINDSTONE" )).forEach(configuredMaterial -> { @@ -59,24 +66,24 @@ public class Config { Material disableBlock = Material.valueOf(configuredMaterial); this.blocks_that_disable.add(disableBlock); } catch (IllegalArgumentException e) { - LogUtils.materialNotRecognized("optimization.by-workstation", configuredMaterial); + LogUtils.materialNotRecognized("optimization.methods.by-workstation", configuredMaterial); } }); // Blocks - this.enable_block_optimization = getBoolean("optimization.by-specific-block.enable", true, + this.enable_block_optimization = getBoolean("optimization.methods.by-specific-block.enable", true, """ Optimize villagers that are standing on these specific block materials /s Values here need to be valid bukkit Material enums for your server version. """ ); - this.getList("optimization.by-specific-block.materials", List.of( + this.getList("optimization.methods.by-specific-block.materials", List.of( "LAPIS_BLOCK", "GLOWSTONE", "IRON_BLOCK" )).forEach(configuredMaterial -> { try { Material disableBlock = Material.valueOf(configuredMaterial); this.blocks_that_disable.add(disableBlock); } catch (IllegalArgumentException e) { - LogUtils.materialNotRecognized("optimization.by-specific-block", configuredMaterial); + LogUtils.materialNotRecognized("optimization.methods.by-specific-block", configuredMaterial); } }); } diff --git a/src/main/java/me/xginko/villageroptimizer/enums/Keys.java b/src/main/java/me/xginko/villageroptimizer/enums/Keys.java index 73f807f..e8b313f 100644 --- a/src/main/java/me/xginko/villageroptimizer/enums/Keys.java +++ b/src/main/java/me/xginko/villageroptimizer/enums/Keys.java @@ -6,6 +6,7 @@ import org.bukkit.NamespacedKey; public enum Keys { OPTIMIZED(VillagerOptimizer.getKey("optimized")), + COOLDOWN_OPTIMIZE(VillagerOptimizer.getKey("optimization-toggle-cooldown")), COOLDOWN_RESTOCK(VillagerOptimizer.getKey("restock-cooldown")), COOLDOWN_EXPERIENCE(VillagerOptimizer.getKey("experience-cooldown")), WORLDTIME(VillagerOptimizer.getKey("world-time")); diff --git a/src/main/java/me/xginko/villageroptimizer/models/WrappedVillager.java b/src/main/java/me/xginko/villageroptimizer/models/WrappedVillager.java index e16d4a7..3bf3db8 100644 --- a/src/main/java/me/xginko/villageroptimizer/models/WrappedVillager.java +++ b/src/main/java/me/xginko/villageroptimizer/models/WrappedVillager.java @@ -20,8 +20,11 @@ public record WrappedVillager(Villager villager) { public void setOptimization(OptimizationType type) { if (type.equals(OptimizationType.OFF) && isOptimized()) { villager.getPersistentDataContainer().remove(Keys.OPTIMIZED.key()); + villager.setAware(true); + villager.setAI(true); } else { villager.getPersistentDataContainer().set(Keys.OPTIMIZED.key(), PersistentDataType.STRING, type.name()); + villager.setAware(false); } } diff --git a/src/main/java/me/xginko/villageroptimizer/modules/AntiVillagerDamage.java b/src/main/java/me/xginko/villageroptimizer/modules/AntiVillagerDamage.java new file mode 100644 index 0000000..a3cfc95 --- /dev/null +++ b/src/main/java/me/xginko/villageroptimizer/modules/AntiVillagerDamage.java @@ -0,0 +1,53 @@ +package me.xginko.villageroptimizer.modules; + +import io.papermc.paper.event.entity.EntityPushedByEntityAttackEvent; +import me.xginko.villageroptimizer.VillagerOptimizer; +import me.xginko.villageroptimizer.models.VillagerCache; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Villager; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent; + +public class AntiVillagerDamage implements VillagerOptimizerModule, Listener { + + private final VillagerCache cache; + + protected AntiVillagerDamage() { + this.cache = VillagerOptimizer.getVillagerCache(); + } + + @Override + public void enable() { + VillagerOptimizer plugin = VillagerOptimizer.getInstance(); + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @Override + public void disable() { + HandlerList.unregisterAll(this); + } + + @Override + public boolean shouldEnable() { + return VillagerOptimizer.getConfiguration().getBoolean("optimization.behavior.optimized-villagers-dont-take-damage", true); + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + private void onDamage(EntityDamageEvent event) { + if (!event.getEntity().getType().equals(EntityType.VILLAGER)) return; + if (cache.get((Villager) event.getEntity()).isOptimized()) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + private void onPathfind(EntityPushedByEntityAttackEvent event) { + if (!event.getEntity().getType().equals(EntityType.VILLAGER)) return; + if (cache.get((Villager) event.getEntity()).isOptimized()) { + event.setCancelled(true); + } + } +} diff --git a/src/main/java/me/xginko/villageroptimizer/modules/AntiVillagerTargetting.java b/src/main/java/me/xginko/villageroptimizer/modules/AntiVillagerTargetting.java new file mode 100644 index 0000000..a0c5f91 --- /dev/null +++ b/src/main/java/me/xginko/villageroptimizer/modules/AntiVillagerTargetting.java @@ -0,0 +1,50 @@ +package me.xginko.villageroptimizer.modules; + +import com.destroystokyo.paper.event.entity.EntityPathfindEvent; +import me.xginko.villageroptimizer.VillagerOptimizer; +import me.xginko.villageroptimizer.models.VillagerCache; +import org.bukkit.entity.Villager; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; + +public class AntiVillagerTargetting implements VillagerOptimizerModule, Listener { + + private final VillagerCache cache; + + protected AntiVillagerTargetting() { + this.cache = VillagerOptimizer.getVillagerCache(); + } + + @Override + public void enable() { + VillagerOptimizer plugin = VillagerOptimizer.getInstance(); + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @Override + public void disable() { + HandlerList.unregisterAll(this); + } + + @Override + public boolean shouldEnable() { + return VillagerOptimizer.getConfiguration().getBoolean("optimization.behavior.optimized-villagers-dont-get-targeted", true); + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + private void onTarget(EntityTargetLivingEntityEvent event) { + if (event.getTarget() instanceof Villager villager && cache.get(villager).isOptimized()) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + private void onTarget(EntityPathfindEvent event) { + if (event.getTargetEntity() instanceof Villager villager && cache.get(villager).isOptimized()) { + event.setCancelled(true); + } + } +} diff --git a/src/main/java/me/xginko/villageroptimizer/modules/ChunkLimit.java b/src/main/java/me/xginko/villageroptimizer/modules/ChunkLimit.java index e52a584..90b09fa 100644 --- a/src/main/java/me/xginko/villageroptimizer/modules/ChunkLimit.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/ChunkLimit.java @@ -30,7 +30,7 @@ public class ChunkLimit implements VillagerOptimizerModule, Listener { private final boolean logIsEnabled; private final long checkPeriod; - public ChunkLimit() { + protected ChunkLimit() { shouldEnable(); this.plugin = VillagerOptimizer.getInstance(); Config config = VillagerOptimizer.getConfiguration(); diff --git a/src/main/java/me/xginko/villageroptimizer/modules/VillagerOptimizerModule.java b/src/main/java/me/xginko/villageroptimizer/modules/VillagerOptimizerModule.java index 8743654..36c6d0d 100644 --- a/src/main/java/me/xginko/villageroptimizer/modules/VillagerOptimizerModule.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/VillagerOptimizerModule.java @@ -14,8 +14,9 @@ public interface VillagerOptimizerModule { modules.forEach(VillagerOptimizerModule::disable); modules.clear(); - // Modules here - + modules.add(new AntiVillagerDamage()); + modules.add(new AntiVillagerTargetting()); + modules.add(new ChunkLimit()); for (VillagerOptimizerModule module : modules) { if (module.shouldEnable()) module.enable();