From e01b8b0462ffbc0051ed7371e86467a75588f23e Mon Sep 17 00:00:00 2001 From: xGinko Date: Wed, 12 Jun 2024 15:21:43 +0200 Subject: [PATCH] use abstract class instead of interface --- pom.xml | 11 +- .../villageroptimizer/VillagerCache.java | 2 +- .../villageroptimizer/VillagerOptimizer.java | 8 +- .../optimizevillagers/OptVillagersRadius.java | 4 +- .../UnOptVillagersRadius.java | 4 +- .../villageroptimizer/config/Config.java | 11 +- .../config/LanguageCache.java | 4 +- .../modules/VillagerChunkLimit.java | 44 +++---- .../modules/VillagerOptimizerModule.java | 108 ++++++++++-------- .../gameplay/EnableLeashingVillagers.java | 29 ++--- .../gameplay/FixOptimisationAfterCure.java | 17 +-- .../gameplay/LevelOptimizedProfession.java | 30 ++--- .../gameplay/MakeVillagersSpawnAdult.java | 22 ++-- .../gameplay/PreventOptimizedDamage.java | 34 ++---- .../gameplay/PreventOptimizedTargeting.java | 25 ++-- .../gameplay/PreventUnoptimizedTrading.java | 31 ++--- .../gameplay/RestockOptimizedTrades.java | 31 ++--- .../gameplay/UnoptimizeOnJobLoose.java | 23 ++-- .../gameplay/VisuallyHighlightOptimized.java | 19 +-- .../modules/optimization/OptimizeByBlock.java | 37 +++--- .../optimization/OptimizeByNametag.java | 37 +++--- .../optimization/OptimizeByWorkstation.java | 44 +++---- .../wrapper/VillagerDataHandler.java | 2 +- 23 files changed, 226 insertions(+), 351 deletions(-) diff --git a/pom.xml b/pom.xml index 4e98146..1c28632 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ me.xginko VillagerOptimizer - 1.5.5 + 1.6.0 jar VillagerOptimizer @@ -61,6 +61,10 @@ io.github.thatsmusic99.configurationmaster me.xginko.villageroptimizer.libs.configmaster + + org.reflections + me.xginko.villageroptimizer.libs.reflections + @@ -112,6 +116,11 @@ 1.20.4-R0.1-SNAPSHOT provided + + org.reflections + reflections + 0.10.2 + net.kyori diff --git a/src/main/java/me/xginko/villageroptimizer/VillagerCache.java b/src/main/java/me/xginko/villageroptimizer/VillagerCache.java index 00e6bb2..e06b148 100644 --- a/src/main/java/me/xginko/villageroptimizer/VillagerCache.java +++ b/src/main/java/me/xginko/villageroptimizer/VillagerCache.java @@ -26,7 +26,7 @@ public final class VillagerCache { this.villagerCache.asMap().clear(); } - public @NotNull WrappedVillager getOrAdd(@NotNull Villager villager) { + public @NotNull WrappedVillager createIfAbsent(@NotNull Villager villager) { WrappedVillager wrappedVillager = this.villagerCache.getIfPresent(villager.getUniqueId()); return wrappedVillager == null ? this.add(new WrappedVillager(villager)) : this.add(wrappedVillager); } diff --git a/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java b/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java index 41f6fda..fa9529c 100644 --- a/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java +++ b/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java @@ -94,8 +94,8 @@ public final class VillagerOptimizer extends JavaPlugin { @Override public void onDisable() { - VillagerOptimizerModule.MODULES.forEach(VillagerOptimizerModule::disable); - VillagerOptimizerModule.MODULES.clear(); + VillagerOptimizerModule.ENABLED_MODULES.forEach(VillagerOptimizerModule::disable); + VillagerOptimizerModule.ENABLED_MODULES.clear(); if (foliaLib != null) { foliaLib.getImpl().cancelAllTasks(); foliaLib = null; @@ -121,7 +121,7 @@ public final class VillagerOptimizer extends JavaPlugin { public static @NotNull VillagerOptimizer getInstance() { return instance; } - public static @NotNull Config getConfiguration() { + public static @NotNull Config config() { return config; } public static @NotNull VillagerCache getCache() { @@ -130,7 +130,7 @@ public final class VillagerOptimizer extends JavaPlugin { public static @NotNull FoliaLib getFoliaLib() { return foliaLib; } - public static @NotNull ComponentLogger getPrefixedLogger() { + public static @NotNull ComponentLogger logger() { return logger; } public static @NotNull BukkitAudiences getAudiences() { diff --git a/src/main/java/me/xginko/villageroptimizer/commands/optimizevillagers/OptVillagersRadius.java b/src/main/java/me/xginko/villageroptimizer/commands/optimizevillagers/OptVillagersRadius.java index b65f5f6..9212995 100644 --- a/src/main/java/me/xginko/villageroptimizer/commands/optimizevillagers/OptVillagersRadius.java +++ b/src/main/java/me/xginko/villageroptimizer/commands/optimizevillagers/OptVillagersRadius.java @@ -30,7 +30,7 @@ public class OptVillagersRadius implements VillagerOptimizerCommand { private final int max_radius; public OptVillagersRadius() { - Config config = VillagerOptimizer.getConfiguration(); + Config config = VillagerOptimizer.config(); this.max_radius = config.getInt("optimization-methods.commands.optimizevillagers.max-block-radius", 100); this.cooldown = config.getInt("optimization-methods.commands.optimizevillagers.cooldown-seconds", 600, "Cooldown in seconds until a villager can be optimized again using the command.\n" + @@ -100,7 +100,7 @@ public class OptVillagersRadius implements VillagerOptimizerCommand { Villager.Profession profession = villager.getProfession(); if (profession.equals(Villager.Profession.NITWIT) || profession.equals(Villager.Profession.NONE)) continue; - WrappedVillager wVillager = villagerCache.getOrAdd(villager); + WrappedVillager wVillager = villagerCache.createIfAbsent(villager); if (player_has_cooldown_bypass || wVillager.canOptimize(cooldown)) { VillagerOptimizeEvent optimizeEvent = new VillagerOptimizeEvent(wVillager, OptimizationType.COMMAND, player); diff --git a/src/main/java/me/xginko/villageroptimizer/commands/unoptimizevillagers/UnOptVillagersRadius.java b/src/main/java/me/xginko/villageroptimizer/commands/unoptimizevillagers/UnOptVillagersRadius.java index 145ec04..ff9342d 100644 --- a/src/main/java/me/xginko/villageroptimizer/commands/unoptimizevillagers/UnOptVillagersRadius.java +++ b/src/main/java/me/xginko/villageroptimizer/commands/unoptimizevillagers/UnOptVillagersRadius.java @@ -28,7 +28,7 @@ public class UnOptVillagersRadius implements VillagerOptimizerCommand { private final int max_radius; public UnOptVillagersRadius() { - this.max_radius = VillagerOptimizer.getConfiguration() + this.max_radius = VillagerOptimizer.config() .getInt("optimization-methods.commands.unoptimizevillagers.max-block-radius", 100); } @@ -93,7 +93,7 @@ public class UnOptVillagersRadius implements VillagerOptimizerCommand { Villager.Profession profession = villager.getProfession(); if (profession.equals(Villager.Profession.NITWIT) || profession.equals(Villager.Profession.NONE)) continue; - WrappedVillager wVillager = villagerCache.getOrAdd(villager); + WrappedVillager wVillager = villagerCache.createIfAbsent(villager); if (wVillager.isOptimized()) { VillagerUnoptimizeEvent unOptimizeEvent = new VillagerUnoptimizeEvent(wVillager, player, OptimizationType.COMMAND); diff --git a/src/main/java/me/xginko/villageroptimizer/config/Config.java b/src/main/java/me/xginko/villageroptimizer/config/Config.java index 8799cb0..36926e1 100644 --- a/src/main/java/me/xginko/villageroptimizer/config/Config.java +++ b/src/main/java/me/xginko/villageroptimizer/config/Config.java @@ -23,22 +23,25 @@ public class Config { this.default_lang = Locale.forLanguageTag( getString("general.default-language", "en_us", - "The default language that will be used if auto-language is false or no matching language file was found.") + "The default language that will be used if auto-language is false\n" + + "or no matching language file was found.") .replace("_", "-")); this.auto_lang = getBoolean("general.auto-language", true, "If set to true, will display messages based on client language"); this.cache_keep_time_seconds = getInt("general.cache-keep-time-seconds", 30, "The amount of time in seconds a villager will be kept in the plugin's cache."); this.support_other_plugins = getBoolean("general.support-avl-villagers", false, - "Enable if you have previously used AntiVillagerLag (https://www.spigotmc.org/resources/antivillagerlag.102949/).\n" + - "Tries to read pre-existing info like optimization state so players don't need to reoptimize their villagers."); + "Enable if you have previously used AntiVillagerLag\n" + + "(https://www.spigotmc.org/resources/antivillagerlag.102949/).\n" + + "Tries to read pre-existing info like optimization state so players\n" + + "don't need to reoptimize their villagers."); } public void saveConfig() { try { this.config.save(); } catch (Throwable throwable) { - VillagerOptimizer.getPrefixedLogger().error("Failed to save config file!", throwable); + VillagerOptimizer.logger().error("Failed to save config file!", throwable); } } diff --git a/src/main/java/me/xginko/villageroptimizer/config/LanguageCache.java b/src/main/java/me/xginko/villageroptimizer/config/LanguageCache.java index 9f145b2..b3549a7 100644 --- a/src/main/java/me/xginko/villageroptimizer/config/LanguageCache.java +++ b/src/main/java/me/xginko/villageroptimizer/config/LanguageCache.java @@ -30,7 +30,7 @@ public class LanguageCache { // Check if the lang folder has already been created File parent = langYML.getParentFile(); if (!parent.exists() && !parent.mkdir()) - VillagerOptimizer.getPrefixedLogger().error("Failed to create lang directory."); + VillagerOptimizer.logger().error("Failed to create lang directory."); // Check if the file already exists and save the one from the plugin's resources folder if it does not if (!langYML.exists()) plugin.saveResource("lang/" + locale + ".yml", false); @@ -86,7 +86,7 @@ public class LanguageCache { try { this.lang.save(); } catch (Throwable throwable) { - VillagerOptimizer.getPrefixedLogger().error("Failed to save language file: " + langYML.getName(), throwable); + VillagerOptimizer.logger().error("Failed to save language file: " + langYML.getName(), throwable); } } diff --git a/src/main/java/me/xginko/villageroptimizer/modules/VillagerChunkLimit.java b/src/main/java/me/xginko/villageroptimizer/modules/VillagerChunkLimit.java index 9ac5742..50c500e 100644 --- a/src/main/java/me/xginko/villageroptimizer/modules/VillagerChunkLimit.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/VillagerChunkLimit.java @@ -1,12 +1,9 @@ package me.xginko.villageroptimizer.modules; -import com.tcoded.folialib.impl.ServerImplementation; import com.tcoded.folialib.wrapper.task.WrappedTask; -import me.xginko.villageroptimizer.VillagerCache; import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.config.Config; -import me.xginko.villageroptimizer.utils.Util; import me.xginko.villageroptimizer.utils.LocationUtil; +import me.xginko.villageroptimizer.utils.Util; import org.bukkit.Chunk; import org.bukkit.Server; import org.bukkit.World; @@ -21,14 +18,15 @@ import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; -public class VillagerChunkLimit implements VillagerOptimizerModule, Listener { +public class VillagerChunkLimit extends VillagerOptimizerModule implements Listener { - private final ServerImplementation scheduler; - private final VillagerCache villagerCache; private WrappedTask periodic_chunk_check; private final List non_optimized_removal_priority, optimized_removal_priority; private final long check_period; @@ -36,20 +34,17 @@ public class VillagerChunkLimit implements VillagerOptimizerModule, Listener { private final boolean log_enabled, skip_unloaded_entity_chunks; protected VillagerChunkLimit() { - shouldEnable(); - this.scheduler = VillagerOptimizer.getFoliaLib().getImpl(); - this.villagerCache = VillagerOptimizer.getCache(); - Config config = VillagerOptimizer.getConfiguration(); - config.master().addComment(configPath() + ".enable", + super("villager-chunk-limit"); + config.master().addComment(configPath + ".enable", "Checks chunks for too many villagers and removes excess villagers based on priority."); - this.check_period = config.getInt(configPath() + ".check-period-in-ticks", 600, + this.check_period = config.getInt(configPath + ".check-period-in-ticks", 600, "Check all loaded chunks every X ticks. 1 second = 20 ticks\n" + "A shorter delay in between checks is more efficient but is also more resource intense.\n" + "A larger delay is less resource intense but could become inefficient."); - this.skip_unloaded_entity_chunks = config.getBoolean(configPath() + ".skip-if-chunk-has-not-loaded-entities", true, + this.skip_unloaded_entity_chunks = config.getBoolean(configPath + ".skip-if-chunk-has-not-loaded-entities", true, "Does not check chunks that don't have their entities loaded."); - this.log_enabled = config.getBoolean(configPath() + ".log-removals", true); - this.non_optimized_max_per_chunk = config.getInt(configPath() + ".unoptimized.max-per-chunk", 20, + this.log_enabled = config.getBoolean(configPath + ".log-removals", true); + this.non_optimized_max_per_chunk = config.getInt(configPath + ".unoptimized.max-per-chunk", 20, "The maximum amount of unoptimized villagers per chunk."); final List defaults = Stream.of( "NONE", "NITWIT", "SHEPHERD", "FISHERMAN", "BUTCHER", "CARTOGRAPHER", "LEATHERWORKER", @@ -63,7 +58,7 @@ public class VillagerChunkLimit implements VillagerOptimizerModule, Listener { return false; } }).collect(Collectors.toList()); - this.non_optimized_removal_priority = config.getList(configPath() + ".unoptimized.removal-priority", defaults, + this.non_optimized_removal_priority = config.getList(configPath + ".unoptimized.removal-priority", defaults, "Professions that are in the top of the list are going to be scheduled for removal first.\n" + "Use enums from https://jd.papermc.io/paper/1.20/org/bukkit/entity/Villager.Profession.html") .stream() @@ -79,9 +74,9 @@ public class VillagerChunkLimit implements VillagerOptimizerModule, Listener { }) .filter(Objects::nonNull) .collect(Collectors.toList()); - this.optimized_max_per_chunk = config.getInt(configPath() + ".optimized.max-per-chunk", 60, + this.optimized_max_per_chunk = config.getInt(configPath + ".optimized.max-per-chunk", 60, "The maximum amount of optimized villagers per chunk."); - this.optimized_removal_priority = config.getList(configPath() + ".optimized.removal-priority", defaults) + this.optimized_removal_priority = config.getList(configPath + ".optimized.removal-priority", defaults) .stream() .map(configuredProfession -> { try { @@ -97,11 +92,6 @@ public class VillagerChunkLimit implements VillagerOptimizerModule, Listener { .collect(Collectors.toList()); } - @Override - public String configPath() { - return "villager-chunk-limit"; - } - @Override public void enable() { final VillagerOptimizer plugin = VillagerOptimizer.getInstance(); @@ -121,7 +111,7 @@ public class VillagerChunkLimit implements VillagerOptimizerModule, Listener { @Override public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean(configPath() + ".enable", false); + return VillagerOptimizer.config().getBoolean(configPath + ".enable", false); } @Override @@ -152,7 +142,7 @@ public class VillagerChunkLimit implements VillagerOptimizerModule, Listener { for (Entity entity : chunk.getEntities()) { if (entity.getType().equals(EntityType.VILLAGER)) { Villager villager = (Villager) entity; - if (villagerCache.getOrAdd(villager).isOptimized()) { + if (villagerCache.createIfAbsent(villager).isOptimized()) { optimized_villagers.add(villager); } else { not_optimized_villagers.add(villager); diff --git a/src/main/java/me/xginko/villageroptimizer/modules/VillagerOptimizerModule.java b/src/main/java/me/xginko/villageroptimizer/modules/VillagerOptimizerModule.java index 4130745..81adb04 100644 --- a/src/main/java/me/xginko/villageroptimizer/modules/VillagerOptimizerModule.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/VillagerOptimizerModule.java @@ -1,73 +1,83 @@ package me.xginko.villageroptimizer.modules; +import com.tcoded.folialib.impl.ServerImplementation; +import me.xginko.villageroptimizer.VillagerCache; import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.modules.gameplay.*; -import me.xginko.villageroptimizer.modules.optimization.OptimizeByBlock; -import me.xginko.villageroptimizer.modules.optimization.OptimizeByNametag; -import me.xginko.villageroptimizer.modules.optimization.OptimizeByWorkstation; -import me.xginko.villageroptimizer.utils.Util; -import net.kyori.adventure.text.Component; +import me.xginko.villageroptimizer.config.Config; +import org.reflections.Reflections; +import org.reflections.scanners.Scanners; +import java.lang.reflect.Modifier; import java.util.HashSet; +import java.util.Set; -public interface VillagerOptimizerModule { +public abstract class VillagerOptimizerModule { - String configPath(); - void enable(); - void disable(); - boolean shouldEnable(); + private static final Reflections MODULES_PACKAGE = new Reflections(VillagerOptimizerModule.class.getPackage().getName()); + public static final Set ENABLED_MODULES = new HashSet<>(); - HashSet MODULES = new HashSet<>(14); + public abstract void enable(); + public abstract void disable(); + public abstract boolean shouldEnable(); - static void reloadModules() { - MODULES.forEach(VillagerOptimizerModule::disable); - MODULES.clear(); + protected final VillagerOptimizer plugin; + protected final Config config; + protected final VillagerCache villagerCache; + protected final ServerImplementation scheduler; + public final String configPath; + private final String logFormat; - MODULES.add(new OptimizeByNametag()); - MODULES.add(new OptimizeByBlock()); - MODULES.add(new OptimizeByWorkstation()); - - MODULES.add(new EnableLeashingVillagers()); - MODULES.add(new FixOptimisationAfterCure()); - MODULES.add(new RestockOptimizedTrades()); - MODULES.add(new LevelOptimizedProfession()); - MODULES.add(new VisuallyHighlightOptimized()); - MODULES.add(new MakeVillagersSpawnAdult()); - MODULES.add(new PreventUnoptimizedTrading()); - MODULES.add(new PreventOptimizedTargeting()); - MODULES.add(new PreventOptimizedDamage()); - MODULES.add(new UnoptimizeOnJobLoose()); - - MODULES.add(new VillagerChunkLimit()); - - MODULES.forEach(module -> { - if (module.shouldEnable()) module.enable(); - }); + public VillagerOptimizerModule(String configPath) { + this.plugin = VillagerOptimizer.getInstance(); + this.config = VillagerOptimizer.config(); + this.villagerCache = VillagerOptimizer.getCache(); + this.scheduler = VillagerOptimizer.getFoliaLib().getImpl(); + this.configPath = configPath; + shouldEnable(); // Ensure enable option is always first + String[] paths = configPath.split("\\."); + if (paths.length <= 2) { + this.logFormat = "<" + configPath + "> {}"; + } else { + this.logFormat = "<" + paths[paths.length - 2] + "." + paths[paths.length - 1] + "> {}"; + } } - default void trace(String prefix, String message, Throwable t) { - VillagerOptimizer.getPrefixedLogger().trace("<{}> {}", prefix, message, t); + public static void reloadModules() { + ENABLED_MODULES.forEach(VillagerOptimizerModule::disable); + ENABLED_MODULES.clear(); + + for (Class clazz : MODULES_PACKAGE.get(Scanners.SubTypes.of(VillagerOptimizerModule.class).asClass())) { + if (clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers())) continue; + + try { + VillagerOptimizerModule module = (VillagerOptimizerModule) clazz.getDeclaredConstructor().newInstance(); + if (module.shouldEnable()) { + module.enable(); + ENABLED_MODULES.add(module); + } + } catch (Throwable t) { + VillagerOptimizer.logger().error("Failed to load module {}", clazz.getSimpleName(), t); + } + } } - default void error(String message, Throwable t) { - VillagerOptimizer.getPrefixedLogger().error("<{}> {}", logPrefix(), message, t); + protected void error(String message, Throwable throwable) { + VillagerOptimizer.logger().error(logFormat, message, throwable); } - default void error(String message) { - VillagerOptimizer.getPrefixedLogger().error("<{}> {}", logPrefix(), message); + protected void error(String message) { + VillagerOptimizer.logger().error(logFormat, message); } - default void warn(String message) { - VillagerOptimizer.getPrefixedLogger().warn("<{}> {}", logPrefix(), message); + protected void warn(String message) { + VillagerOptimizer.logger().warn(logFormat, message); } - default void info(String message) { - VillagerOptimizer.getPrefixedLogger().info(Component.text("<" + logPrefix() + "> " + message).color(Util.PL_COLOR)); + protected void info(String message) { + VillagerOptimizer.logger().info(logFormat, message); } - default String logPrefix() { - String[] split = configPath().split("\\."); - if (split.length <= 2) return configPath(); - return split[split.length - 2] + "." + split[split.length - 1]; + protected void notRecognized(Class clazz, String unrecognized) { + warn("Unable to parse " + clazz.getSimpleName() + " at '" + unrecognized + "'. Please check your configuration."); } } diff --git a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/EnableLeashingVillagers.java b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/EnableLeashingVillagers.java index 1c066d8..c167f57 100644 --- a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/EnableLeashingVillagers.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/EnableLeashingVillagers.java @@ -1,9 +1,5 @@ package me.xginko.villageroptimizer.modules.gameplay; -import com.tcoded.folialib.impl.ServerImplementation; -import me.xginko.villageroptimizer.VillagerCache; -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.config.Config; import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; import me.xginko.villageroptimizer.utils.LocationUtil; import org.bukkit.GameMode; @@ -19,32 +15,21 @@ import org.bukkit.event.entity.PlayerLeashEntityEvent; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.inventory.ItemStack; -public class EnableLeashingVillagers implements VillagerOptimizerModule, Listener { +public class EnableLeashingVillagers extends VillagerOptimizerModule implements Listener { - private final ServerImplementation scheduler; - private final VillagerCache villagerCache; private final boolean only_optimized, log_enabled; public EnableLeashingVillagers() { - shouldEnable(); - this.scheduler = VillagerOptimizer.getFoliaLib().getImpl(); - this.villagerCache = VillagerOptimizer.getCache(); - Config config = VillagerOptimizer.getConfiguration(); - config.master().addComment(configPath() + ".enable", + super("gameplay.villagers-can-be-leashed"); + config.master().addComment(configPath + ".enable", "Enable leashing of villagers, enabling players to easily move villagers to where they want them to be."); - this.only_optimized = config.getBoolean(configPath() + ".only-optimized", false, + this.only_optimized = config.getBoolean(configPath + ".only-optimized", false, "If set to true, only optimized villagers can be leashed."); - this.log_enabled = config.getBoolean(configPath() + ".log", false); - } - - @Override - public String configPath() { - return "gameplay.villagers-can-be-leashed"; + this.log_enabled = config.getBoolean(configPath + ".log", false); } @Override public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); plugin.getServer().getPluginManager().registerEvents(this, plugin); } @@ -55,7 +40,7 @@ public class EnableLeashingVillagers implements VillagerOptimizerModule, Listene @Override public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean(configPath() + ".enable", false); + return config.getBoolean(configPath + ".enable", false); } @SuppressWarnings("deprecation") @@ -68,7 +53,7 @@ public class EnableLeashingVillagers implements VillagerOptimizerModule, Listene final Villager villager = (Villager) event.getRightClicked(); if (villager.isLeashed()) return; - if (only_optimized && !villagerCache.getOrAdd(villager).isOptimized()) return; + if (only_optimized && !villagerCache.createIfAbsent(villager).isOptimized()) return; event.setCancelled(true); // Cancel the event, so we don't interact with the villager diff --git a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/FixOptimisationAfterCure.java b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/FixOptimisationAfterCure.java index 8868b39..5f72eec 100644 --- a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/FixOptimisationAfterCure.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/FixOptimisationAfterCure.java @@ -1,8 +1,7 @@ package me.xginko.villageroptimizer.modules.gameplay; -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.wrapper.WrappedVillager; import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; +import me.xginko.villageroptimizer.wrapper.WrappedVillager; import org.bukkit.entity.EntityType; import org.bukkit.entity.Villager; import org.bukkit.event.EventHandler; @@ -13,18 +12,14 @@ import org.bukkit.event.entity.EntityTransformEvent; import java.util.concurrent.TimeUnit; -public class FixOptimisationAfterCure implements VillagerOptimizerModule, Listener { +public class FixOptimisationAfterCure extends VillagerOptimizerModule implements Listener { - public FixOptimisationAfterCure() {} - - @Override - public String configPath() { - return "post-cure-optimization-fix"; + public FixOptimisationAfterCure() { + super("post-cure-optimization-fix"); } @Override public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); plugin.getServer().getPluginManager().registerEvents(this, plugin); } @@ -45,8 +40,8 @@ public class FixOptimisationAfterCure implements VillagerOptimizerModule, Listen && event.getTransformedEntity().getType().equals(EntityType.VILLAGER) ) { Villager villager = (Villager) event.getTransformedEntity(); - VillagerOptimizer.getFoliaLib().getImpl().runAtEntityLater(villager, () -> { - WrappedVillager wVillager = VillagerOptimizer.getCache().getOrAdd(villager); + scheduler.runAtEntityLater(villager, () -> { + WrappedVillager wVillager = villagerCache.createIfAbsent(villager); wVillager.setOptimizationType(wVillager.getOptimizationType()); }, 2, TimeUnit.SECONDS); } diff --git a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/LevelOptimizedProfession.java b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/LevelOptimizedProfession.java index e94c5f6..48cb364 100644 --- a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/LevelOptimizedProfession.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/LevelOptimizedProfession.java @@ -1,13 +1,11 @@ package me.xginko.villageroptimizer.modules.gameplay; -import com.tcoded.folialib.impl.ServerImplementation; import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.VillagerCache; import me.xginko.villageroptimizer.config.Config; -import me.xginko.villageroptimizer.wrapper.WrappedVillager; import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; -import me.xginko.villageroptimizer.utils.Util; import me.xginko.villageroptimizer.utils.KyoriUtil; +import me.xginko.villageroptimizer.utils.Util; +import me.xginko.villageroptimizer.wrapper.WrappedVillager; import net.kyori.adventure.text.TextReplacementConfig; import org.bukkit.entity.Player; import org.bukkit.entity.Villager; @@ -23,37 +21,27 @@ import org.bukkit.potion.PotionEffectType; import java.time.Duration; import java.util.concurrent.TimeUnit; -public class LevelOptimizedProfession implements VillagerOptimizerModule, Listener { +public class LevelOptimizedProfession extends VillagerOptimizerModule implements Listener { - private final ServerImplementation scheduler; - private final VillagerCache villagerCache; private final boolean notify_player; private final long cooldown_millis; public LevelOptimizedProfession() { - shouldEnable(); - this.scheduler = VillagerOptimizer.getFoliaLib().getImpl(); - this.villagerCache = VillagerOptimizer.getCache(); - Config config = VillagerOptimizer.getConfiguration(); - config.master().addComment(configPath(), + super("gameplay.level-optimized-profession"); + Config config = VillagerOptimizer.config(); + config.master().addComment(configPath, "This is needed to allow optimized villagers to level up.\n" + "Temporarily enables the villagers AI to allow it to level up and then disables it again."); this.cooldown_millis = TimeUnit.SECONDS.toMillis( - config.getInt(configPath() + ".level-check-cooldown-seconds", 5, + config.getInt(configPath + ".level-check-cooldown-seconds", 5, "Cooldown in seconds until the level of a villager will be checked and updated again.\n" + "Recommended to leave as is.")); - this.notify_player = config.getBoolean(configPath() + ".notify-player", true, + this.notify_player = config.getBoolean(configPath + ".notify-player", true, "Tell players to wait when a villager is leveling up."); } - @Override - public String configPath() { - return "gameplay.level-optimized-profession"; - } - @Override public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); plugin.getServer().getPluginManager().registerEvents(this, plugin); } @@ -74,7 +62,7 @@ public class LevelOptimizedProfession implements VillagerOptimizerModule, Listen && event.getInventory().getHolder() instanceof Villager ) { final Villager villager = (Villager) event.getInventory().getHolder(); - final WrappedVillager wVillager = villagerCache.getOrAdd(villager); + final WrappedVillager wVillager = villagerCache.createIfAbsent(villager); if (!wVillager.isOptimized()) return; if (wVillager.canLevelUp(cooldown_millis)) { diff --git a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/MakeVillagersSpawnAdult.java b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/MakeVillagersSpawnAdult.java index f9c8db5..6b758e6 100644 --- a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/MakeVillagersSpawnAdult.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/MakeVillagersSpawnAdult.java @@ -1,6 +1,5 @@ package me.xginko.villageroptimizer.modules.gameplay; -import me.xginko.villageroptimizer.VillagerOptimizer; import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; import org.bukkit.entity.EntityType; import org.bukkit.entity.Villager; @@ -10,18 +9,19 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.entity.CreatureSpawnEvent; -public class MakeVillagersSpawnAdult implements VillagerOptimizerModule, Listener { +public class MakeVillagersSpawnAdult extends VillagerOptimizerModule implements Listener { - public MakeVillagersSpawnAdult() {} - - @Override - public String configPath() { - return "gameplay.villagers-spawn-as-adults"; + public MakeVillagersSpawnAdult() { + super("gameplay.villagers-spawn-as-adults"); + config.master().addComment(configPath + ".enable", + "Spawned villagers will immediately be adults.\n" + + "This is to save some more resources as players don't have to keep unoptimized\n" + + "villagers loaded because they have to wait for them to turn into adults before they can\n" + + "optimize them."); } @Override public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); plugin.getServer().getPluginManager().registerEvents(this, plugin); } @@ -32,11 +32,7 @@ public class MakeVillagersSpawnAdult implements VillagerOptimizerModule, Listene @Override public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean(configPath() + ".enable", false, - "Spawned villagers will immediately be adults.\n" + - "This is to save some more resources as players don't have to keep unoptimized\n" + - "villagers loaded because they have to wait for them to turn into adults before they can\n" + - "optimize them."); + return config.getBoolean(configPath + ".enable", false); } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) diff --git a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedDamage.java b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedDamage.java index 7e6aead..cf4ca1a 100644 --- a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedDamage.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedDamage.java @@ -1,11 +1,7 @@ package me.xginko.villageroptimizer.modules.gameplay; import com.destroystokyo.paper.event.entity.EntityKnockbackByEntityEvent; -import me.xginko.villageroptimizer.VillagerCache; -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.config.Config; import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; -import org.bukkit.Material; import org.bukkit.entity.EntityType; import org.bukkit.entity.Villager; import org.bukkit.event.EventHandler; @@ -14,24 +10,24 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDamageEvent; -import java.util.*; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Objects; +import java.util.Set; import java.util.stream.Collectors; -public class PreventOptimizedDamage implements VillagerOptimizerModule, Listener { +public class PreventOptimizedDamage extends VillagerOptimizerModule implements Listener { - private final VillagerCache villagerCache; private final Set damage_causes_to_cancel; private final boolean cancel_knockback; public PreventOptimizedDamage() { - shouldEnable(); - this.villagerCache = VillagerOptimizer.getCache(); - Config config = VillagerOptimizer.getConfiguration(); - config.master().addComment(configPath() + ".enable", + super("gameplay.prevent-damage-to-optimized"); + config.master().addComment(configPath + ".enable", "Configure what kind of damage you want to cancel for optimized villagers here."); - this.cancel_knockback = config.getBoolean(configPath() + ".prevent-knockback-from-entity", true, + this.cancel_knockback = config.getBoolean(configPath + ".prevent-knockback-from-entity", true, "Prevents optimized villagers from getting knocked back by an attacking entity"); - this.damage_causes_to_cancel = config.getList(configPath() + ".damage-causes-to-cancel", + this.damage_causes_to_cancel = config.getList(configPath + ".damage-causes-to-cancel", Arrays.stream(EntityDamageEvent.DamageCause.values()).map(Enum::name).sorted().collect(Collectors.toList()), "These are all current entries in the game. Remove what you do not need blocked.\n" + "If you want a description or need to add a previously removed type, refer to:\n" + @@ -50,14 +46,8 @@ public class PreventOptimizedDamage implements VillagerOptimizerModule, Listener .collect(Collectors.toCollection(() -> EnumSet.noneOf(EntityDamageEvent.DamageCause.class))); } - @Override - public String configPath() { - return "gameplay.prevent-damage-to-optimized"; - } - @Override public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); plugin.getServer().getPluginManager().registerEvents(this, plugin); } @@ -68,7 +58,7 @@ public class PreventOptimizedDamage implements VillagerOptimizerModule, Listener @Override public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean(configPath() + ".enable", true); + return config.getBoolean(configPath + ".enable", true); } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @@ -76,7 +66,7 @@ public class PreventOptimizedDamage implements VillagerOptimizerModule, Listener if ( event.getEntityType().equals(EntityType.VILLAGER) && damage_causes_to_cancel.contains(event.getCause()) - && villagerCache.getOrAdd((Villager) event.getEntity()).isOptimized() + && villagerCache.createIfAbsent((Villager) event.getEntity()).isOptimized() ) { event.setCancelled(true); } @@ -87,7 +77,7 @@ public class PreventOptimizedDamage implements VillagerOptimizerModule, Listener if ( cancel_knockback && event.getEntityType().equals(EntityType.VILLAGER) - && villagerCache.getOrAdd((Villager) event.getEntity()).isOptimized() + && villagerCache.createIfAbsent((Villager) event.getEntity()).isOptimized() ) { event.setCancelled(true); } diff --git a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedTargeting.java b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedTargeting.java index d0e860b..654ef80 100644 --- a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedTargeting.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedTargeting.java @@ -1,8 +1,6 @@ package me.xginko.villageroptimizer.modules.gameplay; import com.destroystokyo.paper.event.entity.EntityPathfindEvent; -import me.xginko.villageroptimizer.VillagerCache; -import me.xginko.villageroptimizer.VillagerOptimizer; import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; @@ -15,22 +13,16 @@ import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityTargetEvent; -public class PreventOptimizedTargeting implements VillagerOptimizerModule, Listener { - - private final VillagerCache villagerCache; +public class PreventOptimizedTargeting extends VillagerOptimizerModule implements Listener { public PreventOptimizedTargeting() { - this.villagerCache = VillagerOptimizer.getCache(); - } - - @Override - public String configPath() { - return "gameplay.prevent-entities-from-targeting-optimized"; + super("gameplay.prevent-entities-from-targeting-optimized"); + config.master().addComment(configPath + ".enable", + "Prevents hostile entities from targeting optimized villagers."); } @Override public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); plugin.getServer().getPluginManager().registerEvents(this, plugin); } @@ -41,8 +33,7 @@ public class PreventOptimizedTargeting implements VillagerOptimizerModule, Liste @Override public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean(configPath() + ".enable", true, - "Prevents hostile entities from targeting optimized villagers."); + return config.getBoolean(configPath + ".enable", true); } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @@ -51,7 +42,7 @@ public class PreventOptimizedTargeting implements VillagerOptimizerModule, Liste if ( target != null && target.getType().equals(EntityType.VILLAGER) - && villagerCache.getOrAdd((Villager) target).isOptimized() + && villagerCache.createIfAbsent((Villager) target).isOptimized() ) { event.setTarget(null); event.setCancelled(true); @@ -64,7 +55,7 @@ public class PreventOptimizedTargeting implements VillagerOptimizerModule, Liste if ( target != null && target.getType().equals(EntityType.VILLAGER) - && villagerCache.getOrAdd((Villager) target).isOptimized() + && villagerCache.createIfAbsent((Villager) target).isOptimized() ) { event.setCancelled(true); } @@ -75,7 +66,7 @@ public class PreventOptimizedTargeting implements VillagerOptimizerModule, Liste if ( event.getEntityType().equals(EntityType.VILLAGER) && event.getDamager() instanceof Mob - && villagerCache.getOrAdd((Villager) event.getEntity()).isOptimized() + && villagerCache.createIfAbsent((Villager) event.getEntity()).isOptimized() ) { ((Mob) event.getDamager()).setTarget(null); } diff --git a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventUnoptimizedTrading.java b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventUnoptimizedTrading.java index 0575ed2..c2f6713 100644 --- a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventUnoptimizedTrading.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventUnoptimizedTrading.java @@ -1,8 +1,6 @@ package me.xginko.villageroptimizer.modules.gameplay; import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.VillagerCache; -import me.xginko.villageroptimizer.config.Config; import me.xginko.villageroptimizer.enums.Permissions; import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; import me.xginko.villageroptimizer.utils.KyoriUtil; @@ -16,31 +14,22 @@ import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.inventory.TradeSelectEvent; -public class PreventUnoptimizedTrading implements VillagerOptimizerModule, Listener { +public class PreventUnoptimizedTrading extends VillagerOptimizerModule implements Listener { - private final VillagerCache villagerCache; private final boolean notify_player; public PreventUnoptimizedTrading() { - shouldEnable(); - this.villagerCache = VillagerOptimizer.getCache(); - Config config = VillagerOptimizer.getConfiguration(); - config.master().addComment(configPath() + ".enable", + super("gameplay.prevent-trading-with-unoptimized"); + config.master().addComment(configPath + ".enable", "Will prevent players from selecting and using trades of unoptimized villagers.\n" + "Use this if you have a lot of villagers and therefore want to force your players to optimize them.\n" + "Inventories can still be opened so players can move villagers around."); - this.notify_player = config.getBoolean(configPath() + ".notify-player", true, + this.notify_player = config.getBoolean(configPath + ".notify-player", true, "Sends players a message when they try to trade with an unoptimized villager."); } - @Override - public String configPath() { - return "gameplay.prevent-trading-with-unoptimized"; - } - @Override public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); plugin.getServer().getPluginManager().registerEvents(this, plugin); } @@ -51,7 +40,7 @@ public class PreventUnoptimizedTrading implements VillagerOptimizerModule, Liste @Override public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean(configPath() + ".enable", false); + return config.getBoolean(configPath + ".enable", false); } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @@ -59,14 +48,13 @@ public class PreventUnoptimizedTrading implements VillagerOptimizerModule, Liste if (!event.getInventory().getType().equals(InventoryType.MERCHANT)) return; if (event.getWhoClicked().hasPermission(Permissions.Bypass.TRADE_PREVENTION.get())) return; if (!(event.getInventory().getHolder() instanceof Villager)) return; - if (villagerCache.getOrAdd((Villager) event.getInventory().getHolder()).isOptimized()) return; + if (villagerCache.createIfAbsent((Villager) event.getInventory().getHolder()).isOptimized()) return; event.setCancelled(true); if (notify_player) { Player player = (Player) event.getWhoClicked(); - VillagerOptimizer.getLang(player.locale()).optimize_for_trading - .forEach(line -> KyoriUtil.sendMessage(player, line)); + VillagerOptimizer.getLang(player.locale()).optimize_for_trading.forEach(line -> KyoriUtil.sendMessage(player, line)); } } @@ -75,14 +63,13 @@ public class PreventUnoptimizedTrading implements VillagerOptimizerModule, Liste if (!event.getInventory().getType().equals(InventoryType.MERCHANT)) return; if (event.getWhoClicked().hasPermission(Permissions.Bypass.TRADE_PREVENTION.get())) return; if (!(event.getInventory().getHolder() instanceof Villager)) return; - if (villagerCache.getOrAdd((Villager) event.getInventory().getHolder()).isOptimized()) return; + if (villagerCache.createIfAbsent((Villager) event.getInventory().getHolder()).isOptimized()) return; event.setCancelled(true); if (notify_player) { Player player = (Player) event.getWhoClicked(); - VillagerOptimizer.getLang(player.locale()).optimize_for_trading - .forEach(line -> KyoriUtil.sendMessage(player, line)); + VillagerOptimizer.getLang(player.locale()).optimize_for_trading.forEach(line -> KyoriUtil.sendMessage(player, line)); } } } diff --git a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RestockOptimizedTrades.java b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RestockOptimizedTrades.java index b500e7a..8fe4a5b 100644 --- a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RestockOptimizedTrades.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RestockOptimizedTrades.java @@ -1,14 +1,12 @@ package me.xginko.villageroptimizer.modules.gameplay; -import me.xginko.villageroptimizer.VillagerCache; import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.utils.LocationUtil; -import me.xginko.villageroptimizer.wrapper.WrappedVillager; -import me.xginko.villageroptimizer.config.Config; import me.xginko.villageroptimizer.enums.Permissions; import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; -import me.xginko.villageroptimizer.utils.Util; import me.xginko.villageroptimizer.utils.KyoriUtil; +import me.xginko.villageroptimizer.utils.LocationUtil; +import me.xginko.villageroptimizer.utils.Util; +import me.xginko.villageroptimizer.wrapper.WrappedVillager; import net.kyori.adventure.text.TextReplacementConfig; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; @@ -21,34 +19,25 @@ import org.bukkit.event.player.PlayerInteractEntityEvent; import java.time.Duration; -public class RestockOptimizedTrades implements VillagerOptimizerModule, Listener { +public class RestockOptimizedTrades extends VillagerOptimizerModule implements Listener { - private final VillagerCache villagerCache; private final long restock_delay_millis; private final boolean log_enabled, notify_player; public RestockOptimizedTrades() { - shouldEnable(); - this.villagerCache = VillagerOptimizer.getCache(); - Config config = VillagerOptimizer.getConfiguration(); - config.master().addComment(configPath(), + super("gameplay.restock-optimized-trades"); + config.master().addComment(configPath, "This is for automatic restocking of trades for optimized villagers. Optimized Villagers\n" + "don't have enough AI to restock their trades naturally, so this is here as a workaround."); - this.restock_delay_millis = config.getInt(configPath() + ".delay-in-ticks", 1000, + this.restock_delay_millis = config.getInt(configPath + ".delay-in-ticks", 1000, "1 second = 20 ticks. There are 24.000 ticks in a single minecraft day.") * 50L; - this.notify_player = config.getBoolean(configPath() + ".notify-player", true, + this.notify_player = config.getBoolean(configPath + ".notify-player", true, "Sends the player a message when the trades were restocked on a clicked villager."); - this.log_enabled = config.getBoolean(configPath() + ".log", false); - } - - @Override - public String configPath() { - return "gameplay.restock-optimized-trades"; + this.log_enabled = config.getBoolean(configPath + ".log", false); } @Override public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); plugin.getServer().getPluginManager().registerEvents(this, plugin); } @@ -66,7 +55,7 @@ public class RestockOptimizedTrades implements VillagerOptimizerModule, Listener private void onInteract(PlayerInteractEntityEvent event) { if (!event.getRightClicked().getType().equals(EntityType.VILLAGER)) return; - final WrappedVillager wVillager = villagerCache.getOrAdd((Villager) event.getRightClicked()); + final WrappedVillager wVillager = villagerCache.createIfAbsent((Villager) event.getRightClicked()); if (!wVillager.isOptimized()) return; final Player player = event.getPlayer(); diff --git a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/UnoptimizeOnJobLoose.java b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/UnoptimizeOnJobLoose.java index ccca153..0e4a71f 100644 --- a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/UnoptimizeOnJobLoose.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/UnoptimizeOnJobLoose.java @@ -1,32 +1,24 @@ package me.xginko.villageroptimizer.modules.gameplay; -import me.xginko.villageroptimizer.VillagerCache; -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.wrapper.WrappedVillager; import me.xginko.villageroptimizer.enums.OptimizationType; import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; +import me.xginko.villageroptimizer.wrapper.WrappedVillager; 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.VillagerCareerChangeEvent; -public class UnoptimizeOnJobLoose implements VillagerOptimizerModule, Listener { - - private final VillagerCache villagerCache; +public class UnoptimizeOnJobLoose extends VillagerOptimizerModule implements Listener { public UnoptimizeOnJobLoose() { - this.villagerCache = VillagerOptimizer.getCache(); - } - - @Override - public String configPath() { - return "gameplay.unoptimize-on-job-loose"; + super("gameplay.unoptimize-on-job-loose"); + config.master().addComment(configPath + ".enable", + "Villagers that get their jobs reset will become unoptimized again."); } @Override public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); plugin.getServer().getPluginManager().registerEvents(this, plugin); } @@ -37,14 +29,13 @@ public class UnoptimizeOnJobLoose implements VillagerOptimizerModule, Listener { @Override public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean(configPath() + ".enable", true, - "Villagers that get their jobs reset will become unoptimized again."); + return config.getBoolean(configPath + ".enable", true); } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) private void onJobReset(VillagerCareerChangeEvent event) { if (!event.getReason().equals(VillagerCareerChangeEvent.ChangeReason.LOSING_JOB)) return; - final WrappedVillager wrappedVillager = villagerCache.getOrAdd(event.getEntity()); + final WrappedVillager wrappedVillager = villagerCache.createIfAbsent(event.getEntity()); if (wrappedVillager.isOptimized()) { wrappedVillager.setOptimizationType(OptimizationType.NONE); } diff --git a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/VisuallyHighlightOptimized.java b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/VisuallyHighlightOptimized.java index 08ce57c..229da2b 100644 --- a/src/main/java/me/xginko/villageroptimizer/modules/gameplay/VisuallyHighlightOptimized.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/VisuallyHighlightOptimized.java @@ -1,8 +1,5 @@ package me.xginko.villageroptimizer.modules.gameplay; -import com.tcoded.folialib.impl.ServerImplementation; -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.config.Config; import me.xginko.villageroptimizer.events.VillagerOptimizeEvent; import me.xginko.villageroptimizer.events.VillagerUnoptimizeEvent; import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; @@ -12,26 +9,16 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; -public class VisuallyHighlightOptimized implements VillagerOptimizerModule, Listener { - - private final ServerImplementation scheduler; +public class VisuallyHighlightOptimized extends VillagerOptimizerModule implements Listener { public VisuallyHighlightOptimized() { - shouldEnable(); - this.scheduler = VillagerOptimizer.getFoliaLib().getImpl(); - Config config = VillagerOptimizer.getConfiguration(); + super("gameplay.outline-optimized-villagers"); config.master().addComment("gameplay.outline-optimized-villagers.enable", "Will make optimized villagers glow."); } - @Override - public String configPath() { - return "gameplay.outline-optimized-villagers"; - } - @Override public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); plugin.getServer().getPluginManager().registerEvents(this, plugin); } @@ -42,7 +29,7 @@ public class VisuallyHighlightOptimized implements VillagerOptimizerModule, List @Override public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean("gameplay.outline-optimized-villagers.enable", false); + return config.getBoolean("gameplay.outline-optimized-villagers.enable", false); } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) diff --git a/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByBlock.java b/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByBlock.java index 2103e8f..4851ded 100644 --- a/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByBlock.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByBlock.java @@ -1,16 +1,14 @@ package me.xginko.villageroptimizer.modules.optimization; -import me.xginko.villageroptimizer.VillagerCache; import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.config.Config; import me.xginko.villageroptimizer.enums.OptimizationType; import me.xginko.villageroptimizer.enums.Permissions; import me.xginko.villageroptimizer.events.VillagerOptimizeEvent; import me.xginko.villageroptimizer.events.VillagerUnoptimizeEvent; import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; -import me.xginko.villageroptimizer.utils.Util; import me.xginko.villageroptimizer.utils.KyoriUtil; import me.xginko.villageroptimizer.utils.LocationUtil; +import me.xginko.villageroptimizer.utils.Util; import me.xginko.villageroptimizer.wrapper.WrappedVillager; import net.kyori.adventure.text.TextReplacementConfig; import org.bukkit.Location; @@ -33,22 +31,19 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -public class OptimizeByBlock implements VillagerOptimizerModule, Listener { +public class OptimizeByBlock extends VillagerOptimizerModule implements Listener { - private final VillagerCache villagerCache; private final Set blocks_that_disable; private final long cooldown_millis; private final double search_radius; private final boolean only_while_sneaking, notify_player, log_enabled; public OptimizeByBlock() { - shouldEnable(); - this.villagerCache = VillagerOptimizer.getCache(); - Config config = VillagerOptimizer.getConfiguration(); - config.master().addComment(configPath() + ".enable", + super("optimization-methods.block-optimization"); + config.master().addComment(configPath + ".enable", "When enabled, the closest villager standing near a configured block being placed will be optimized.\n" + "If a configured block is broken nearby, the closest villager will become unoptimized again."); - this.blocks_that_disable = config.getList(configPath() + ".materials", Arrays.asList( + this.blocks_that_disable = config.getList(configPath + ".materials", Arrays.asList( "LAPIS_BLOCK", "GLOWSTONE", "IRON_BLOCK" ), "Values here need to be valid bukkit Material enums for your server version.") .stream() @@ -64,27 +59,21 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener { .filter(Objects::nonNull) .collect(Collectors.toCollection(() -> EnumSet.noneOf(Material.class))); this.cooldown_millis = TimeUnit.SECONDS.toMillis( - config.getInt(configPath() + ".optimize-cooldown-seconds", 600, + config.getInt(configPath + ".optimize-cooldown-seconds", 600, "Cooldown in seconds until a villager can be optimized again by using specific blocks.\n" + "Here for configuration freedom. Recommended to leave as is to not enable any exploitable behavior.")); - this.search_radius = config.getDouble(configPath() + ".search-radius-in-blocks", 2.0, + this.search_radius = config.getDouble(configPath + ".search-radius-in-blocks", 2.0, "The radius in blocks a villager can be away from the player when he places an optimize block.\n" + "The closest unoptimized villager to the player will be optimized.") / 2; - this.only_while_sneaking = config.getBoolean(configPath() + ".only-when-sneaking", true, + this.only_while_sneaking = config.getBoolean(configPath + ".only-when-sneaking", true, "Only optimize/unoptimize by block when player is sneaking during place or break."); - this.notify_player = config.getBoolean(configPath() + ".notify-player", true, + this.notify_player = config.getBoolean(configPath + ".notify-player", true, "Sends players a message when they successfully optimized or unoptimized a villager."); - this.log_enabled = config.getBoolean(configPath() + ".log", false); - } - - @Override - public String configPath() { - return "optimization-methods.block-optimization"; + this.log_enabled = config.getBoolean(configPath + ".log", false); } @Override public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); plugin.getServer().getPluginManager().registerEvents(this, plugin); } @@ -95,7 +84,7 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener { @Override public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean(configPath() + ".enable", false); + return config.getBoolean(configPath + ".enable", false); } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @@ -117,7 +106,7 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener { final double distance = LocationUtil.relDistance3DSquared(villager.getLocation(), blockLoc); if (distance >= closestDistance) continue; - final WrappedVillager wVillager = villagerCache.getOrAdd(villager); + final WrappedVillager wVillager = villagerCache.createIfAbsent(villager); if (wVillager.canOptimize(cooldown_millis)) { closestOptimizableVillager = wVillager; closestDistance = distance; @@ -184,7 +173,7 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener { final double distance = LocationUtil.relDistance3DSquared(villager.getLocation(), blockLoc); if (distance >= closestDistance) continue; - final WrappedVillager wVillager = villagerCache.getOrAdd(villager); + final WrappedVillager wVillager = villagerCache.createIfAbsent(villager); if (wVillager.isOptimized()) { closestOptimizedVillager = wVillager; closestDistance = distance; diff --git a/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByNametag.java b/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByNametag.java index bde740e..4154116 100644 --- a/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByNametag.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByNametag.java @@ -1,17 +1,15 @@ package me.xginko.villageroptimizer.modules.optimization; -import me.xginko.villageroptimizer.VillagerCache; import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.utils.LocationUtil; -import me.xginko.villageroptimizer.wrapper.WrappedVillager; -import me.xginko.villageroptimizer.config.Config; import me.xginko.villageroptimizer.enums.OptimizationType; import me.xginko.villageroptimizer.enums.Permissions; import me.xginko.villageroptimizer.events.VillagerOptimizeEvent; import me.xginko.villageroptimizer.events.VillagerUnoptimizeEvent; import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; -import me.xginko.villageroptimizer.utils.Util; import me.xginko.villageroptimizer.utils.KyoriUtil; +import me.xginko.villageroptimizer.utils.LocationUtil; +import me.xginko.villageroptimizer.utils.Util; +import me.xginko.villageroptimizer.wrapper.WrappedVillager; import net.kyori.adventure.text.TextReplacementConfig; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -33,42 +31,33 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -public class OptimizeByNametag implements VillagerOptimizerModule, Listener { +public class OptimizeByNametag extends VillagerOptimizerModule implements Listener { - private final VillagerCache villagerCache; private final Set nametags; private final long cooldown; private final boolean consume_nametag, notify_player, log_enabled; public OptimizeByNametag() { - shouldEnable(); - this.villagerCache = VillagerOptimizer.getCache(); - Config config = VillagerOptimizer.getConfiguration(); - config.master().addComment(configPath() + ".enable", + super("optimization-methods.nametag-optimization"); + config.master().addComment(configPath + ".enable", "Enable optimization by naming villagers to one of the names configured below.\n" + "Nametag optimized villagers will be unoptimized again when they are renamed to something else."); - this.nametags = config.getList(configPath() + ".names", Arrays.asList("Optimize", "DisableAI"), + this.nametags = config.getList(configPath + ".names", Arrays.asList("Optimize", "DisableAI"), "Names are case insensitive, capital letters won't matter.") .stream().map(String::toLowerCase).collect(Collectors.toCollection(HashSet::new)); - this.consume_nametag = config.getBoolean(configPath() + ".nametags-get-consumed", true, + this.consume_nametag = config.getBoolean(configPath + ".nametags-get-consumed", true, "Enable or disable consumption of the used nametag item."); this.cooldown = TimeUnit.SECONDS.toMillis( - config.getInt(configPath() + ".optimize-cooldown-seconds", 600, + config.getInt(configPath + ".optimize-cooldown-seconds", 600, "Cooldown in seconds until a villager can be optimized again using a nametag.\n" + "Here for configuration freedom. Recommended to leave as is to not enable any exploitable behavior.")); - this.notify_player = config.getBoolean(configPath() + ".notify-player", true, + this.notify_player = config.getBoolean(configPath + ".notify-player", true, "Sends players a message when they successfully optimized a villager."); - this.log_enabled = config.getBoolean(configPath() + ".log", false); - } - - @Override - public String configPath() { - return "optimization-methods.nametag-optimization"; + this.log_enabled = config.getBoolean(configPath + ".log", false); } @Override public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); plugin.getServer().getPluginManager().registerEvents(this, plugin); } @@ -79,7 +68,7 @@ public class OptimizeByNametag implements VillagerOptimizerModule, Listener { @Override public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean(configPath() + ".enable", true); + return config.getBoolean(configPath + ".enable", true); } @SuppressWarnings("deprecation") @@ -97,7 +86,7 @@ public class OptimizeByNametag implements VillagerOptimizerModule, Listener { final String nameTagPlainText = ChatColor.stripColor(meta.getDisplayName()); final Villager villager = (Villager) event.getRightClicked(); - final WrappedVillager wVillager = villagerCache.getOrAdd(villager); + final WrappedVillager wVillager = villagerCache.createIfAbsent(villager); if (nametags.contains(nameTagPlainText.toLowerCase())) { if (wVillager.canOptimize(cooldown) || player.hasPermission(Permissions.Bypass.NAMETAG_COOLDOWN.get())) { diff --git a/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByWorkstation.java b/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByWorkstation.java index aac3598..97c9f95 100644 --- a/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByWorkstation.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByWorkstation.java @@ -1,18 +1,15 @@ package me.xginko.villageroptimizer.modules.optimization; -import com.tcoded.folialib.impl.ServerImplementation; -import me.xginko.villageroptimizer.VillagerCache; import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.utils.LocationUtil; -import me.xginko.villageroptimizer.wrapper.WrappedVillager; -import me.xginko.villageroptimizer.config.Config; import me.xginko.villageroptimizer.enums.OptimizationType; import me.xginko.villageroptimizer.enums.Permissions; import me.xginko.villageroptimizer.events.VillagerOptimizeEvent; import me.xginko.villageroptimizer.events.VillagerUnoptimizeEvent; import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; -import me.xginko.villageroptimizer.utils.Util; import me.xginko.villageroptimizer.utils.KyoriUtil; +import me.xginko.villageroptimizer.utils.LocationUtil; +import me.xginko.villageroptimizer.utils.Util; +import me.xginko.villageroptimizer.wrapper.WrappedVillager; import net.kyori.adventure.text.TextReplacementConfig; import org.bukkit.Location; import org.bukkit.block.Block; @@ -30,48 +27,37 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -public class OptimizeByWorkstation implements VillagerOptimizerModule, Listener { +public class OptimizeByWorkstation extends VillagerOptimizerModule implements Listener { - private final ServerImplementation scheduler; - private final VillagerCache villagerCache; private final long cooldown_millis; private final double search_radius; private final int check_duration_ticks; private final boolean only_while_sneaking, log_enabled, notify_player; public OptimizeByWorkstation() { - shouldEnable(); - this.scheduler = VillagerOptimizer.getFoliaLib().getImpl(); - this.villagerCache = VillagerOptimizer.getCache(); - Config config = VillagerOptimizer.getConfiguration(); - config.master().addComment(configPath() + ".enable", + super("optimization-methods.workstation-optimization"); + config.master().addComment(configPath + ".enable", "When enabled, villagers that have a job and have been traded with at least once will become optimized,\n" + "if near their workstation. If the workstation is broken, the villager will become unoptimized again."); - this.check_duration_ticks = Math.max(config.getInt(configPath() + ".check-linger-duration-ticks", 100, + this.check_duration_ticks = Math.max(config.getInt(configPath + ".check-linger-duration-ticks", 100, "After a workstation has been placed, the plugin will wait for the configured amount of time in ticks\n" + "for a villager to claim that workstation. Not recommended to go below 100 ticks."), 1); - this.search_radius = config.getDouble(configPath() + ".search-radius-in-blocks", 2.0, + this.search_radius = config.getDouble(configPath + ".search-radius-in-blocks", 2.0, "The radius in blocks a villager can be away from the player when he places a workstation.\n" + "The closest unoptimized villager to the player will be optimized."); this.cooldown_millis = TimeUnit.SECONDS.toMillis( - Math.max(1, config.getInt(configPath() + ".optimize-cooldown-seconds", 600, + Math.max(1, config.getInt(configPath + ".optimize-cooldown-seconds", 600, "Cooldown in seconds until a villager can be optimized again using a workstation.\n" + "Here for configuration freedom. Recommended to leave as is to not enable any exploitable behavior."))); - this.only_while_sneaking = config.getBoolean(configPath() + ".only-when-sneaking", true, + this.only_while_sneaking = config.getBoolean(configPath + ".only-when-sneaking", true, "Only optimize/unoptimize by workstation when player is sneaking during place or break. Useful for villager rolling."); - this.notify_player = config.getBoolean(configPath() + ".notify-player", true, + this.notify_player = config.getBoolean(configPath + ".notify-player", true, "Sends players a message when they successfully optimized a villager."); - this.log_enabled = config.getBoolean(configPath() + ".log", false); - } - - @Override - public String configPath() { - return "optimization-methods.workstation-optimization"; + this.log_enabled = config.getBoolean(configPath + ".log", false); } @Override public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); plugin.getServer().getPluginManager().registerEvents(this, plugin); } @@ -82,7 +68,7 @@ public class OptimizeByWorkstation implements VillagerOptimizerModule, Listener @Override public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean(configPath() + ".enable", false); + return config.getBoolean(configPath + ".enable", false); } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @@ -107,7 +93,7 @@ public class OptimizeByWorkstation implements VillagerOptimizerModule, Listener for (Villager villager : workstationLoc.getNearbyEntitiesByType(Villager.class, search_radius)) { if (villager.getProfession() != workstationProfession) continue; - WrappedVillager wrapped = villagerCache.getOrAdd(villager); + WrappedVillager wrapped = villagerCache.createIfAbsent(villager); if (wrapped.getJobSite() == null) continue; if (wrapped.getJobSite().getWorld().getUID() != workstationLoc.getWorld().getUID()) continue; if (LocationUtil.relDistance3DSquared(wrapped.getJobSite(), workstationLoc) > 1) continue; @@ -181,7 +167,7 @@ public class OptimizeByWorkstation implements VillagerOptimizerModule, Listener final double distance = LocationUtil.relDistance3DSquared(villager.getLocation(), workstationLoc); if (distance >= closestDistance) continue; - WrappedVillager wrapped = villagerCache.getOrAdd(villager); + WrappedVillager wrapped = villagerCache.createIfAbsent(villager); if (wrapped.isOptimized()) { closestOptimized = wrapped; diff --git a/src/main/java/me/xginko/villageroptimizer/wrapper/VillagerDataHandler.java b/src/main/java/me/xginko/villageroptimizer/wrapper/VillagerDataHandler.java index 9eb13fc..fb5bf3d 100644 --- a/src/main/java/me/xginko/villageroptimizer/wrapper/VillagerDataHandler.java +++ b/src/main/java/me/xginko/villageroptimizer/wrapper/VillagerDataHandler.java @@ -9,7 +9,7 @@ import org.jetbrains.annotations.NotNull; public interface VillagerDataHandler { static VillagerDataHandler[] forVillager(Villager villager) { - if (VillagerOptimizer.getConfiguration().support_other_plugins) { + if (VillagerOptimizer.config().support_other_plugins) { return new VillagerDataHandler[]{ new MainVillagerDataHandlerImpl(villager), new AVLVillagerDataHandlerImpl(villager)