diff --git a/VillagerOptimizer-1.16.5/pom.xml b/VillagerOptimizer-1.16.5/pom.xml deleted file mode 100644 index e8561a0..0000000 --- a/VillagerOptimizer-1.16.5/pom.xml +++ /dev/null @@ -1,99 +0,0 @@ - - - 4.0.0 - - - me.xginko.VillagerOptimizer - VillagerOptimizer - 1.0.2 - - - 1.16.5 - ${project.parent.artifactId}-${project.parent.version}--${project.artifactId} - jar - - - 16 - UTF-8 - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.11.0 - - ${java.version} - ${java.version} - - - - org.apache.maven.plugins - maven-shade-plugin - 3.5.1 - - - package - - shade - - - false - - - com.github.benmanes.caffeine - me.xginko.villageroptimizer.caffeine - - - org.bstats - me.xginko.villageroptimizer.bstats - - - - - - - - - - src/main/resources - true - - - - - - - papermc-repo - https://repo.papermc.io/repository/maven-public/ - - - sonatype - https://oss.sonatype.org/content/groups/public/ - - - - - - com.destroystokyo.paper - paper-api - 1.16.5-R0.1-SNAPSHOT - provided - - - net.kyori - adventure-text-minimessage - 4.14.0 - compile - - - net.kyori - adventure-text-serializer-plain - 4.14.0 - compile - - - diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java b/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java deleted file mode 100644 index 382574e..0000000 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java +++ /dev/null @@ -1,179 +0,0 @@ -package me.xginko.villageroptimizer; - -import me.xginko.villageroptimizer.commands.VillagerOptimizerCommand; -import me.xginko.villageroptimizer.config.Config; -import me.xginko.villageroptimizer.config.LanguageCache; -import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.Style; -import net.kyori.adventure.text.format.TextColor; -import net.kyori.adventure.text.format.TextDecoration; -import org.bstats.bukkit.Metrics; -import org.bukkit.NamespacedKey; -import org.bukkit.command.CommandSender; -import org.bukkit.command.ConsoleCommandSender; -import org.bukkit.entity.Player; -import org.bukkit.plugin.java.JavaPlugin; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.util.*; -import java.util.jar.JarFile; -import java.util.logging.Logger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.zip.ZipEntry; - -public final class VillagerOptimizer extends JavaPlugin { - - private static VillagerOptimizer instance; - private static VillagerCache villagerCache; - private static HashMap languageCacheMap; - private static Config config; - private static ConsoleCommandSender console; - private static Logger logger; - - public final static Style plugin_style = Style.style(TextColor.color(102,255,230), TextDecoration.BOLD); - - @Override - public void onEnable() { - instance = this; - logger = getLogger(); - console = getServer().getConsoleSender(); - console.sendMessage(Component.text("╭────────────────────────────────────────────────────────────╮").style(plugin_style)); - console.sendMessage(Component.text("│ │").style(plugin_style)); - console.sendMessage(Component.text("│ │").style(plugin_style)); - console.sendMessage(Component.text("│ _ __ _ __ __ │").style(plugin_style)); - console.sendMessage(Component.text("│ | | / /(_)/ // /___ _ ___ _ ___ ____ │").style(plugin_style)); - console.sendMessage(Component.text("│ | |/ // // // // _ `// _ `// -_)/ __/ │").style(plugin_style)); - console.sendMessage(Component.text("│ |___//_//_//_/ \\_,_/ \\_, / \\__//_/ │").style(plugin_style)); - console.sendMessage(Component.text("│ ____ __ _ /___/_ │").style(plugin_style)); - console.sendMessage(Component.text("│ / __ \\ ___ / /_ (_)__ _ (_)___ ___ ____ │").style(plugin_style)); - console.sendMessage(Component.text("│ / /_/ // _ \\/ __// // ' \\ / //_ // -_)/ __/ │").style(plugin_style)); - console.sendMessage(Component.text("│ \\____// .__/\\__//_//_/_/_//_/ /__/\\__//_/ │").style(plugin_style)); - console.sendMessage(Component.text("│ /_/ by xGinko │").style(plugin_style)); - console.sendMessage(Component.text("│ │").style(plugin_style)); - console.sendMessage(Component.text("│ │").style(plugin_style)); - console.sendMessage(Component.text("│ ") - .style(plugin_style).append(Component.text("https://github.com/xGinko/VillagerOptimizer") - .color(NamedTextColor.GRAY)).append(Component.text(" │").style(plugin_style))); - console.sendMessage(Component.text("│ │").style(plugin_style)); - console.sendMessage(Component.text("│ │").style(plugin_style)); - console.sendMessage(Component.text("│ ") - .style(plugin_style).append(Component.text(" ➤ Loading Translations...").style(plugin_style)) - .append(Component.text(" │").style(plugin_style))); - reloadLang(true); - console.sendMessage(Component.text("│ ") - .style(plugin_style).append(Component.text(" ➤ Loading Config...").style(plugin_style)) - .append(Component.text(" │").style(plugin_style))); - reloadConfiguration(); - console.sendMessage(Component.text("│ ") - .style(plugin_style).append(Component.text(" ✓ Done.").color(NamedTextColor.WHITE).decorate(TextDecoration.BOLD)) - .append(Component.text(" │").style(plugin_style))); - console.sendMessage(Component.text("│ │").style(plugin_style)); - console.sendMessage(Component.text("│ │").style(plugin_style)); - console.sendMessage(Component.text("╰────────────────────────────────────────────────────────────╯").style(plugin_style)); - new Metrics(this, 19954); - } - - public static VillagerOptimizer getInstance() { - return instance; - } - public static NamespacedKey getKey(String key) { - return new NamespacedKey(instance, key); - } - public static Config getConfiguration() { - return config; - } - public static VillagerCache getCache() { - return villagerCache; - } - public static ConsoleCommandSender getConsole() { - return console; - } - public static Logger getLog() { - return logger; - } - public static LanguageCache getLang(Locale locale) { - return getLang(locale.toString().toLowerCase()); - } - public static LanguageCache getLang(CommandSender commandSender) { - return commandSender instanceof Player player ? getLang(player.locale()) : getLang(config.default_lang); - } - public static LanguageCache getLang(String lang) { - if (!config.auto_lang) return languageCacheMap.get(config.default_lang.toString().toLowerCase()); - return languageCacheMap.getOrDefault(lang.replace("-", "_"), languageCacheMap.get(config.default_lang.toString().toLowerCase())); - } - - public void reloadPlugin() { - reloadLang(false); - reloadConfiguration(); - } - - private void reloadConfiguration() { - try { - config = new Config(); - villagerCache = new VillagerCache(config.cache_keep_time_seconds); - VillagerOptimizerCommand.reloadCommands(); - VillagerOptimizerModule.reloadModules(); - config.saveConfig(); - } catch (Exception e) { - logger.severe("Error loading config! - " + e.getLocalizedMessage()); - e.printStackTrace(); - } - } - - private void reloadLang(boolean startup) { - languageCacheMap = new HashMap<>(); - try { - File langDirectory = new File(getDataFolder() + File.separator + "lang"); - Files.createDirectories(langDirectory.toPath()); - for (String fileName : getDefaultLanguageFiles()) { - final String localeString = fileName.substring(fileName.lastIndexOf(File.separator) + 1, fileName.lastIndexOf('.')); - if (startup) console.sendMessage( - Component.text("│ ").style(plugin_style) - .append(Component.text(" "+localeString).color(NamedTextColor.WHITE).decorate(TextDecoration.BOLD)) - .append(Component.text(" │").style(plugin_style))); - else logger.info(String.format("Found language file for %s", localeString)); - languageCacheMap.put(localeString, new LanguageCache(localeString)); - } - final Pattern langPattern = Pattern.compile("([a-z]{1,3}_[a-z]{1,3})(\\.yml)", Pattern.CASE_INSENSITIVE); - for (File langFile : langDirectory.listFiles()) { - final Matcher langMatcher = langPattern.matcher(langFile.getName()); - if (langMatcher.find()) { - String localeString = langMatcher.group(1).toLowerCase(); - if (!languageCacheMap.containsKey(localeString)) { // make sure it wasn't a default file that we already loaded - if (startup) console.sendMessage( - Component.text("│ ").style(plugin_style) - .append(Component.text(" "+localeString).color(NamedTextColor.WHITE).decorate(TextDecoration.BOLD)) - .append(Component.text(" │").style(plugin_style))); - else logger.info(String.format("Found language file for %s", localeString)); - languageCacheMap.put(localeString, new LanguageCache(localeString)); - } - } - } - } catch (Exception e) { - if (startup) console.sendMessage( - Component.text("│ ").style(plugin_style) - .append(Component.text("LANG ERROR").color(NamedTextColor.RED).decorate(TextDecoration.BOLD)) - .append(Component.text(" │").style(plugin_style))); - else logger.severe("Error loading language files! Language files will not reload to avoid errors, make sure to correct this before restarting the server!"); - e.printStackTrace(); - } - } - - private Set getDefaultLanguageFiles() { - try (final JarFile pluginJarFile = new JarFile(this.getFile())) { - return pluginJarFile.stream() - .map(ZipEntry::getName) - .filter(name -> name.startsWith("lang" + File.separator) && name.endsWith(".yml")) - .collect(Collectors.toSet()); - } catch (IOException e) { - logger.severe("Failed getting default lang files! - "+e.getLocalizedMessage()); - return Collections.emptySet(); - } - } -} diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/DisableSubCmd.java b/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/DisableSubCmd.java deleted file mode 100644 index 7c8e6c7..0000000 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/DisableSubCmd.java +++ /dev/null @@ -1,45 +0,0 @@ -package me.xginko.villageroptimizer.commands.villageroptimizer.subcommands; - -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.commands.SubCommand; -import me.xginko.villageroptimizer.enums.Permissions; -import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.TextComponent; -import net.kyori.adventure.text.format.NamedTextColor; -import org.bukkit.command.CommandSender; -import org.bukkit.event.HandlerList; - -public class DisableSubCmd extends SubCommand { - - @Override - public String getLabel() { - return "disable"; - } - - @Override - public TextComponent getDescription() { - return Component.text("Disable all plugin tasks and listeners.").color(NamedTextColor.GRAY); - } - - @Override - public TextComponent getSyntax() { - return Component.text("/villageroptimizer disable").color(VillagerOptimizer.plugin_style.color()); - } - - @Override - public void perform(CommandSender sender, String[] args) { - if (sender.hasPermission(Permissions.Commands.DISABLE.get())) { - sender.sendMessage(Component.text("Disabling VillagerOptimizer...").color(NamedTextColor.RED)); - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); - HandlerList.unregisterAll(plugin); - plugin.getServer().getScheduler().cancelTasks(plugin); - VillagerOptimizerModule.modules.clear(); - VillagerOptimizer.getCache().cacheMap().clear(); - sender.sendMessage(Component.text("Disabled all plugin listeners and tasks.").color(NamedTextColor.GREEN)); - sender.sendMessage(Component.text("You can enable the plugin again using the reload command.").color(NamedTextColor.YELLOW)); - } else { - sender.sendMessage(VillagerOptimizer.getLang(sender).no_permission); - } - } -} \ No newline at end of file diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/config/Config.java b/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/config/Config.java deleted file mode 100644 index 9e40ef4..0000000 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/config/Config.java +++ /dev/null @@ -1,146 +0,0 @@ -package me.xginko.villageroptimizer.config; - -import io.github.thatsmusic99.configurationmaster.api.ConfigFile; -import io.github.thatsmusic99.configurationmaster.api.ConfigSection; -import me.xginko.villageroptimizer.VillagerOptimizer; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -public class Config { - - private final @NotNull ConfigFile config; - public final @NotNull Locale default_lang; - public final boolean auto_lang; - public final long cache_keep_time_seconds; - - public Config() throws Exception { - // Create plugin folder first if it does not exist yet - File pluginFolder = VillagerOptimizer.getInstance().getDataFolder(); - if (!pluginFolder.exists() && !pluginFolder.mkdir()) - VillagerOptimizer.getLog().severe("Failed to create plugin directory."); - // Load config.yml with ConfigMaster - this.config = ConfigFile.loadConfig(new File(pluginFolder, "config.yml")); - - structureConfig(); - - 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.") - .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."); - } - - public void saveConfig() { - try { - this.config.save(); - } catch (Exception e) { - VillagerOptimizer.getLog().severe("Failed to save config file! - " + e.getLocalizedMessage()); - } - } - - private void structureConfig() { - this.config.addDefault("config-version", 1.00); - this.createTitledSection("General", "general"); - this.createTitledSection("Optimization", "optimization-methods"); - this.config.addDefault("optimization-methods.commands.unoptimizevillagers", null); - this.config.addComment("optimization-methods.commands", """ - If you want to disable commands, negate the following permissions:\s - villageroptimizer.cmd.optimize\s - villageroptimizer.cmd.unoptimize - """); - this.config.addDefault("optimization-methods.nametag-optimization.enable", true); - this.createTitledSection("Villager Chunk Limit", "villager-chunk-limit"); - this.createTitledSection("Gameplay", "gameplay"); - this.config.addDefault("gameplay.restock-optimized-trades", null); - this.config.addDefault("gameplay.level-optimized-profession", null); - this.config.addDefault("gameplay.rename-optimized-villagers.enable", true); - this.config.addDefault("gameplay.villagers-spawn-as-adults.enable", false); - this.config.addDefault("gameplay.prevent-trading-with-unoptimized.enable", false); - this.config.addDefault("gameplay.prevent-entities-from-targeting-optimized.enable", true); - this.config.addDefault("gameplay.prevent-damage-to-optimized.enable", true); - } - - public void createTitledSection(@NotNull String title, @NotNull String path) { - this.config.addSection(title); - this.config.addDefault(path, null); - } - - public @NotNull ConfigFile master() { - return config; - } - - public boolean getBoolean(@NotNull String path, boolean def, @NotNull String comment) { - this.config.addDefault(path, def, comment); - return this.config.getBoolean(path, def); - } - - public boolean getBoolean(@NotNull String path, boolean def) { - this.config.addDefault(path, def); - return this.config.getBoolean(path, def); - } - - public @NotNull String getString(@NotNull String path, @NotNull String def, @NotNull String comment) { - this.config.addDefault(path, def, comment); - return this.config.getString(path, def); - } - - public @NotNull String getString(@NotNull String path, @NotNull String def) { - this.config.addDefault(path, def); - return this.config.getString(path, def); - } - - public double getDouble(@NotNull String path, @NotNull Double def, @NotNull String comment) { - this.config.addDefault(path, def, comment); - return this.config.getDouble(path, def); - } - - public double getDouble(@NotNull String path, @NotNull Double def) { - this.config.addDefault(path, def); - return this.config.getDouble(path, def); - } - - public int getInt(@NotNull String path, int def, @NotNull String comment) { - this.config.addDefault(path, def, comment); - return this.config.getInteger(path, def); - } - - public int getInt(@NotNull String path, int def) { - this.config.addDefault(path, def); - return this.config.getInteger(path, def); - } - - public @NotNull List getList(@NotNull String path, @NotNull List def, @NotNull String comment) { - this.config.addDefault(path, def, comment); - return this.config.getStringList(path); - } - - public @NotNull List getList(@NotNull String path, @NotNull List def) { - this.config.addDefault(path, def); - return this.config.getStringList(path); - } - - public @NotNull ConfigSection getConfigSection(@NotNull String path, @NotNull Map defaultKeyValue) { - this.config.addDefault(path, null); - this.config.makeSectionLenient(path); - defaultKeyValue.forEach((string, object) -> this.config.addExample(path+"."+string, object)); - return this.config.getConfigSection(path); - } - - public @NotNull ConfigSection getConfigSection(@NotNull String path, @NotNull Map defaultKeyValue, @NotNull String comment) { - this.config.addDefault(path, null, comment); - this.config.makeSectionLenient(path); - defaultKeyValue.forEach((string, object) -> this.config.addExample(path+"."+string, object)); - return this.config.getConfigSection(path); - } - - public void addComment(@NotNull String path, @NotNull String comment) { - this.config.addComment(path, comment); - } -} \ No newline at end of file diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/enums/Permissions.java b/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/enums/Permissions.java deleted file mode 100644 index 8b17eba..0000000 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/enums/Permissions.java +++ /dev/null @@ -1,45 +0,0 @@ -package me.xginko.villageroptimizer.enums; - -public class Permissions { - public enum Commands { - VERSION("villageroptimizer.cmd.version"), - RELOAD("villageroptimizer.cmd.reload"), - DISABLE("villageroptimizer.cmd.disable"), - OPTIMIZE_RADIUS("villageroptimizer.cmd.optimize"), - UNOPTIMIZE_RADIUS("villageroptimizer.cmd.unoptimize"); - private final String permission; - Commands(String permission) { - this.permission = permission; - } - public String get() { - return permission; - } - } - public enum Optimize { - NAMETAG("villageroptimizer.optimize.nametag"), - BLOCK("villageroptimizer.optimize.block"), - WORKSTATION("villageroptimizer.optimize.workstation"); - private final String permission; - Optimize(String permission) { - this.permission = permission; - } - public String get() { - return permission; - } - } - public enum Bypass { - TRADE_PREVENTION("villageroptimizer.bypass.tradeprevention"), - RESTOCK_COOLDOWN("villageroptimizer.bypass.restockcooldown"), - NAMETAG_COOLDOWN("villageroptimizer.bypass.nametagcooldown"), - BLOCK_COOLDOWN("villageroptimizer.bypass.blockcooldown"), - WORKSTATION_COOLDOWN("villageroptimizer.bypass.workstationcooldown"), - COMMAND_COOLDOWN("villageroptimizer.bypass.commandcooldown"); - private final String permission; - Bypass(String permission) { - this.permission = permission; - } - public String get() { - return permission; - } - } -} diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/events/VillagerOptimizeEvent.java b/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/events/VillagerOptimizeEvent.java deleted file mode 100644 index 2123dc5..0000000 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/events/VillagerOptimizeEvent.java +++ /dev/null @@ -1,79 +0,0 @@ -package me.xginko.villageroptimizer.events; - -import me.xginko.villageroptimizer.WrappedVillager; -import me.xginko.villageroptimizer.enums.OptimizationType; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public class VillagerOptimizeEvent extends Event implements Cancellable { - - private static final @NotNull HandlerList handlers = new HandlerList(); - private final @NotNull WrappedVillager wrappedVillager; - private @NotNull OptimizationType type; - private final @Nullable Player whoOptimised; - private boolean isCancelled = false; - - public VillagerOptimizeEvent(@NotNull WrappedVillager wrappedVillager, @NotNull OptimizationType type, @Nullable Player whoOptimised, boolean isAsync) throws IllegalArgumentException { - super(isAsync); - this.wrappedVillager = wrappedVillager; - this.whoOptimised = whoOptimised; - if (type.equals(OptimizationType.NONE)) { - throw new IllegalArgumentException("OptimizationType can't be NONE."); - } else { - this.type = type; - } - } - - public VillagerOptimizeEvent(@NotNull WrappedVillager wrappedVillager, @NotNull OptimizationType type, @Nullable Player whoOptimised) throws IllegalArgumentException { - this.wrappedVillager = wrappedVillager; - this.whoOptimised = whoOptimised; - if (type.equals(OptimizationType.NONE)) { - throw new IllegalArgumentException("OptimizationType can't be NONE."); - } else { - this.type = type; - } - } - - public @NotNull WrappedVillager getWrappedVillager() { - return wrappedVillager; - } - - public @NotNull OptimizationType getOptimizationType() { - return type; - } - - public void setOptimizationType(@NotNull OptimizationType type) throws IllegalArgumentException { - if (type.equals(OptimizationType.NONE)) { - throw new IllegalArgumentException("OptimizationType can't be NONE."); - } else { - this.type = type; - } - } - - public @Nullable Player getWhoOptimised() { - return whoOptimised; - } - - @Override - public void setCancelled(boolean cancel) { - isCancelled = cancel; - } - - @Override - public boolean isCancelled() { - return isCancelled; - } - - @Override - public @NotNull HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } -} diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/VillagerChunkLimit.java b/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/VillagerChunkLimit.java deleted file mode 100644 index 4b33159..0000000 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/VillagerChunkLimit.java +++ /dev/null @@ -1,171 +0,0 @@ -package me.xginko.villageroptimizer.modules; - -import me.xginko.villageroptimizer.VillagerCache; -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.config.Config; -import me.xginko.villageroptimizer.utils.LogUtil; -import org.bukkit.Chunk; -import org.bukkit.Server; -import org.bukkit.World; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Villager; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.CreatureSpawnEvent; -import org.bukkit.event.player.PlayerInteractEntityEvent; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.logging.Level; - -public class VillagerChunkLimit implements VillagerOptimizerModule, Listener, Runnable { - - private final Server server; - private final VillagerCache villagerCache; - private final List non_optimized_removal_priority = new ArrayList<>(16); - private final List optimized_removal_priority = new ArrayList<>(16); - private final long check_period; - private final int non_optimized_max_per_chunk, optimized_max_per_chunk; - private final boolean log_enabled; - - protected VillagerChunkLimit() { - shouldEnable(); - this.server = VillagerOptimizer.getInstance().getServer(); - this.villagerCache = VillagerOptimizer.getCache(); - Config config = VillagerOptimizer.getConfiguration(); - config.addComment("villager-chunk-limit.enable", """ - Checks chunks for too many villagers and removes excess villagers based on priority."""); - this.check_period = config.getInt("villager-chunk-limit.check-period-in-ticks", 600, """ - Check all loaded chunks every X ticks. 1 second = 20 ticks\s - A shorter delay in between checks is more efficient but is also more resource intense.\s - A larger delay is less resource intense but could become inefficient."""); - this.log_enabled = config.getBoolean("villager-chunk-limit.log-removals", false); - this.non_optimized_max_per_chunk = config.getInt("villager-chunk-limit.unoptimized.max-per-chunk", 20, - "The maximum amount of unoptimized villagers per chunk."); - config.getList("villager-chunk-limit.unoptimized.removal-priority", List.of( - "NONE", "NITWIT", "SHEPHERD", "FISHERMAN", "BUTCHER", "CARTOGRAPHER", "LEATHERWORKER", - "FLETCHER", "MASON", "FARMER", "ARMORER", "TOOLSMITH", "WEAPONSMITH", "CLERIC", "LIBRARIAN" - ), """ - Professions that are in the top of the list are going to be scheduled for removal first.\s - Use enums from https://jd.papermc.io/paper/1.20/org/bukkit/entity/Villager.Profession.html""" - ).forEach(configuredProfession -> { - try { - Villager.Profession profession = Villager.Profession.valueOf(configuredProfession); - this.non_optimized_removal_priority.add(profession); - } catch (IllegalArgumentException e) { - LogUtil.moduleLog(Level.WARNING, "villager-chunk-limit.unoptimized", - "Villager profession '"+configuredProfession+"' not recognized. " + - "Make sure you're using the correct profession enums from https://jd.papermc.io/paper/1.20/org/bukkit/entity/Villager.Profession.html."); - } - }); - this.optimized_max_per_chunk = config.getInt("villager-chunk-limit.optimized.max-per-chunk", 60, - "The maximum amount of optimized villagers per chunk."); - config.getList("villager-chunk-limit.optimized.removal-priority", List.of( - "NONE", "NITWIT", "SHEPHERD", "FISHERMAN", "BUTCHER", "CARTOGRAPHER", "LEATHERWORKER", - "FLETCHER", "MASON", "FARMER", "ARMORER", "TOOLSMITH", "WEAPONSMITH", "CLERIC", "LIBRARIAN" - )).forEach(configuredProfession -> { - try { - Villager.Profession profession = Villager.Profession.valueOf(configuredProfession); - this.optimized_removal_priority.add(profession); - } catch (IllegalArgumentException e) { - LogUtil.moduleLog(Level.WARNING, "villager-chunk-limit.optimized", - "Villager profession '"+configuredProfession+"' not recognized. " + - "Make sure you're using the correct profession enums from https://jd.papermc.io/paper/1.20/org/bukkit/entity/Villager.Profession.html."); - } - }); - } - - @Override - public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); - server.getPluginManager().registerEvents(this, plugin); - server.getScheduler().scheduleSyncRepeatingTask(plugin, this, check_period, check_period); - } - - @Override - public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean("villager-chunk-limit.enable", false); - } - - @Override - public void run() { - for (World world : server.getWorlds()) { - for (Chunk chunk : world.getLoadedChunks()) { - this.manageVillagerCount(chunk); - } - } - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - private void onCreatureSpawn(CreatureSpawnEvent event) { - Entity spawned = event.getEntity(); - if (spawned.getType().equals(EntityType.VILLAGER)) { - this.manageVillagerCount(spawned.getChunk()); - } - } - - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - private void onInteract(PlayerInteractEntityEvent event) { - Entity clicked = event.getRightClicked(); - if (clicked.getType().equals(EntityType.VILLAGER)) { - this.manageVillagerCount(clicked.getChunk()); - } - } - - private void manageVillagerCount(@NotNull Chunk chunk) { - // Collect all optimized and unoptimized villagers in that chunk - List optimized_villagers = new ArrayList<>(); - List not_optimized_villagers = new ArrayList<>(); - - for (Entity entity : chunk.getEntities()) { - if (entity.getType().equals(EntityType.VILLAGER)) { - Villager villager = (Villager) entity; - if (villagerCache.getOrAdd(villager).isOptimized()) { - optimized_villagers.add(villager); - } else { - not_optimized_villagers.add(villager); - } - } - } - - // Check if there are more unoptimized villagers in that chunk than allowed - final int not_optimized_villagers_too_many = not_optimized_villagers.size() - non_optimized_max_per_chunk; - if (not_optimized_villagers_too_many > 0) { - // Sort villagers by profession priority - not_optimized_villagers.sort(Comparator.comparingInt(villager -> { - final Villager.Profession profession = villager.getProfession(); - return non_optimized_removal_priority.contains(profession) ? non_optimized_removal_priority.indexOf(profession) : Integer.MAX_VALUE; - })); - // Remove prioritized villagers that are too many - for (int i = 0; i < not_optimized_villagers_too_many; i++) { - Villager villager = not_optimized_villagers.get(i); - villager.remove(); - if (log_enabled) LogUtil.moduleLog(Level.INFO, "villager-chunk-limit", - "Removed unoptimized villager of profession type '"+villager.getProfession().name()+"' at "+villager.getLocation() - ); - } - } - - // Check if there are more optimized villagers in that chunk than allowed - final int optimized_villagers_too_many = optimized_villagers.size() - optimized_max_per_chunk; - if (optimized_villagers_too_many > 0) { - // Sort villagers by profession priority - optimized_villagers.sort(Comparator.comparingInt(villager -> { - final Villager.Profession profession = villager.getProfession(); - return optimized_removal_priority.contains(profession) ? optimized_removal_priority.indexOf(profession) : Integer.MAX_VALUE; - })); - // Remove prioritized villagers that are too many - for (int i = 0; i < optimized_villagers_too_many; i++) { - Villager villager = optimized_villagers.get(i); - villager.remove(); - if (log_enabled) LogUtil.moduleLog(Level.INFO, "villager-chunk-limit", - "Removed optimized villager of profession type '"+villager.getProfession().name()+"' at "+villager.getLocation() - ); - } - } - } -} \ No newline at end of file diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/VillagerOptimizerModule.java b/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/VillagerOptimizerModule.java deleted file mode 100644 index 3abba6e..0000000 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/VillagerOptimizerModule.java +++ /dev/null @@ -1,43 +0,0 @@ -package me.xginko.villageroptimizer.modules; - -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 org.bukkit.event.HandlerList; - -import java.util.HashSet; - -public interface VillagerOptimizerModule { - - void enable(); - boolean shouldEnable(); - - HashSet modules = new HashSet<>(); - - static void reloadModules() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); - HandlerList.unregisterAll(plugin); - plugin.getServer().getScheduler().cancelTasks(plugin); - modules.clear(); - - modules.add(new OptimizeByNametag()); - modules.add(new OptimizeByBlock()); - modules.add(new OptimizeByWorkstation()); - - modules.add(new RestockOptimizedTrades()); - modules.add(new LevelOptimizedProfession()); - modules.add(new RenameOptimizedVillagers()); - modules.add(new MakeVillagersSpawnAdult()); - modules.add(new PreventUnoptimizedTrading()); - modules.add(new PreventOptimizedTargeting()); - modules.add(new PreventOptimizedDamage()); - - modules.add(new VillagerChunkLimit()); - - modules.forEach(module -> { - if (module.shouldEnable()) module.enable(); - }); - } -} diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/LevelOptimizedProfession.java b/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/LevelOptimizedProfession.java deleted file mode 100644 index 9f6955f..0000000 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/LevelOptimizedProfession.java +++ /dev/null @@ -1,84 +0,0 @@ -package me.xginko.villageroptimizer.modules.gameplay; - -import me.xginko.villageroptimizer.VillagerCache; -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.WrappedVillager; -import me.xginko.villageroptimizer.config.Config; -import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; -import me.xginko.villageroptimizer.utils.CommonUtil; -import net.kyori.adventure.text.TextReplacementConfig; -import org.bukkit.entity.Player; -import org.bukkit.entity.Villager; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.InventoryCloseEvent; -import org.bukkit.event.inventory.InventoryType; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; - -public class LevelOptimizedProfession implements VillagerOptimizerModule, Listener { - - private final VillagerOptimizer plugin; - private final VillagerCache villagerCache; - private final boolean notify_player; - private final long cooldown; - - public LevelOptimizedProfession() { - shouldEnable(); - this.plugin = VillagerOptimizer.getInstance(); - this.villagerCache = VillagerOptimizer.getCache(); - Config config = VillagerOptimizer.getConfiguration(); - config.addComment("gameplay.level-optimized-profession", """ - This is needed to allow optimized villagers to level up.\s - Temporarily enables the villagers AI to allow it to level up and then disables it again."""); - this.cooldown = config.getInt("gameplay.level-optimized-profession.level-check-cooldown-seconds", 5, """ - Cooldown in seconds until the level of a villager will be checked and updated again.\s - Recommended to leave as is.""") * 1000L; - this.notify_player = config.getBoolean("gameplay.level-optimized-profession.notify-player", true, - "Tell players to wait when a villager is leveling up."); - } - - @Override - public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); - plugin.getServer().getPluginManager().registerEvents(this, plugin); - } - - @Override - public boolean shouldEnable() { - return true; - } - - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - private void onTradeScreenClose(InventoryCloseEvent event) { - if ( - event.getInventory().getType().equals(InventoryType.MERCHANT) - && event.getInventory().getHolder() instanceof Villager villager - ) { - WrappedVillager wVillager = villagerCache.getOrAdd(villager); - if (!wVillager.isOptimized()) return; - - if (wVillager.canLevelUp(cooldown)) { - if (wVillager.calculateLevel() > villager.getVillagerLevel()) { - villager.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 120, 120, false, false)); - villager.setAware(true); - - plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> { - villager.setAware(false); - wVillager.saveLastLevelUp(); - }, 100L); - } - } else { - if (notify_player) { - Player player = (Player) event.getPlayer(); - final TextReplacementConfig timeLeft = TextReplacementConfig.builder() - .matchLiteral("%time%") - .replacement(CommonUtil.formatTime(wVillager.getLevelCooldownMillis(cooldown))) - .build(); - VillagerOptimizer.getLang(player.locale()).villager_leveling_up.forEach(line -> player.sendMessage(line.replaceText(timeLeft))); - } - } - } - } -} diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/MakeVillagersSpawnAdult.java b/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/MakeVillagersSpawnAdult.java deleted file mode 100644 index 31b431c..0000000 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/MakeVillagersSpawnAdult.java +++ /dev/null @@ -1,38 +0,0 @@ -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; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.CreatureSpawnEvent; - -public class MakeVillagersSpawnAdult implements VillagerOptimizerModule, Listener { - - public MakeVillagersSpawnAdult() {} - - @Override - public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); - plugin.getServer().getPluginManager().registerEvents(this, plugin); - } - - @Override - public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean("gameplay.villagers-spawn-as-adults.enable", false, """ - Spawned villagers will immediately be adults.\s - This is to save some more resources as players don't have to keep unoptimized\s - villagers loaded because they have to wait for them to turn into adults before they can\s - optimize them."""); - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - private void onVillagerSpawn(CreatureSpawnEvent event) { - if (event.getEntityType().equals(EntityType.VILLAGER)) { - Villager villager = (Villager) event.getEntity(); - if (!villager.isAdult()) villager.setAdult(); - } - } -} diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedDamage.java b/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedDamage.java deleted file mode 100644 index 114fbe2..0000000 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedDamage.java +++ /dev/null @@ -1,65 +0,0 @@ -package me.xginko.villageroptimizer.modules.gameplay; - -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.LogUtil; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Villager; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageEvent; - -import java.util.Arrays; -import java.util.HashSet; - -public class PreventOptimizedDamage implements VillagerOptimizerModule, Listener { - - private final VillagerCache villagerCache; - private final HashSet damage_causes_to_cancel = new HashSet<>(); - - public PreventOptimizedDamage() { - shouldEnable(); - this.villagerCache = VillagerOptimizer.getCache(); - Config config = VillagerOptimizer.getConfiguration(); - config.addComment("gameplay.prevent-damage-to-optimized.enable", - "Configure what kind of damage you want to cancel for optimized villagers here."); - config.getList("gameplay.prevent-damage-to-optimized.damage-causes-to-cancel", - Arrays.stream(EntityDamageEvent.DamageCause.values()).map(Enum::name).sorted().toList(), """ - These are all current entries in the game. Remove what you do not need blocked.\s - If you want a description or need to add a previously removed type, refer to:\s - https://jd.papermc.io/paper/1.20/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html""" - ).forEach(configuredDamageCause -> { - try { - EntityDamageEvent.DamageCause damageCause = EntityDamageEvent.DamageCause.valueOf(configuredDamageCause); - this.damage_causes_to_cancel.add(damageCause); - } catch (IllegalArgumentException e) { - LogUtil.damageCauseNotRecognized("prevent-damage-to-optimized", configuredDamageCause); - } - }); - } - - @Override - public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); - plugin.getServer().getPluginManager().registerEvents(this, plugin); - } - - @Override - public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean("gameplay.prevent-damage-to-optimized.enable", true); - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - private void onDamageByEntity(EntityDamageEvent event) { - if ( - event.getEntityType().equals(EntityType.VILLAGER) - && damage_causes_to_cancel.contains(event.getCause()) - && villagerCache.getOrAdd((Villager) event.getEntity()).isOptimized() - ) { - event.setCancelled(true); - } - } -} \ No newline at end of file diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedTargeting.java b/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedTargeting.java deleted file mode 100644 index dad057a..0000000 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedTargeting.java +++ /dev/null @@ -1,73 +0,0 @@ -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; -import org.bukkit.entity.Mob; -import org.bukkit.entity.Villager; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -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 PreventOptimizedTargeting() { - this.villagerCache = VillagerOptimizer.getCache(); - } - - @Override - public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); - plugin.getServer().getPluginManager().registerEvents(this, plugin); - } - - @Override - public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean("gameplay.prevent-entities-from-targeting-optimized.enable", true, - "Prevents hostile entities from targeting optimized villagers."); - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - private void onTarget(EntityTargetEvent event) { - // Yes, instanceof checks would look way more beautiful here but checking type is much faster - Entity target = event.getTarget(); - if ( - target != null - && target.getType().equals(EntityType.VILLAGER) - && villagerCache.getOrAdd((Villager) target).isOptimized() - ) { - event.setTarget(null); - event.setCancelled(true); - } - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - private void onEntityTargetVillager(EntityPathfindEvent event) { - Entity target = event.getTargetEntity(); - if ( - target != null - && target.getType().equals(EntityType.VILLAGER) - && villagerCache.getOrAdd((Villager) target).isOptimized() - ) { - event.setCancelled(true); - } - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - private void onEntityAttackVillager(EntityDamageByEntityEvent event) { - if ( - event.getEntityType().equals(EntityType.VILLAGER) - && event.getDamager() instanceof Mob attacker - && villagerCache.getOrAdd((Villager) event.getEntity()).isOptimized() - ) { - attacker.setTarget(null); - } - } - } diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventUnoptimizedTrading.java b/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventUnoptimizedTrading.java deleted file mode 100644 index 00acbed..0000000 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventUnoptimizedTrading.java +++ /dev/null @@ -1,74 +0,0 @@ -package me.xginko.villageroptimizer.modules.gameplay; - -import me.xginko.villageroptimizer.VillagerCache; -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.config.Config; -import me.xginko.villageroptimizer.enums.Permissions; -import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; -import org.bukkit.entity.Player; -import org.bukkit.entity.Villager; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryType; -import org.bukkit.event.inventory.TradeSelectEvent; - -public class PreventUnoptimizedTrading implements VillagerOptimizerModule, Listener { - - private final VillagerCache villagerCache; - private final boolean notify_player; - - public PreventUnoptimizedTrading() { - shouldEnable(); - this.villagerCache = VillagerOptimizer.getCache(); - Config config = VillagerOptimizer.getConfiguration(); - config.addComment("gameplay.prevent-trading-with-unoptimized.enable", """ - Will prevent players from selecting and using trades of unoptimized villagers.\s - Use this if you have a lot of villagers and therefore want to force your players to optimize them.\s - Inventories can still be opened so players can move villagers around."""); - this.notify_player = config.getBoolean("gameplay.prevent-trading-with-unoptimized.notify-player", true, - "Sends players a message when they try to trade with an unoptimized villager."); - } - - @Override - public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); - plugin.getServer().getPluginManager().registerEvents(this, plugin); - } - - @Override - public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean("gameplay.prevent-trading-with-unoptimized.enable", false); - } - - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - private void onTradeOpen(TradeSelectEvent event) { - Player player = (Player) event.getWhoClicked(); - if (player.hasPermission(Permissions.Bypass.TRADE_PREVENTION.get())) return; - if ( - event.getInventory().getType().equals(InventoryType.MERCHANT) - && event.getInventory().getHolder() instanceof Villager villager - && !villagerCache.getOrAdd(villager).isOptimized() - ) { - event.setCancelled(true); - if (notify_player) - VillagerOptimizer.getLang(player.locale()).optimize_for_trading.forEach(player::sendMessage); - } - } - - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - private void onInventoryClick(InventoryClickEvent event) { - Player player = (Player) event.getWhoClicked(); - if (player.hasPermission(Permissions.Bypass.TRADE_PREVENTION.get())) return; - if ( - event.getInventory().getType().equals(InventoryType.MERCHANT) - && event.getInventory().getHolder() instanceof Villager villager - && !villagerCache.getOrAdd(villager).isOptimized() - ) { - event.setCancelled(true); - if (notify_player) - VillagerOptimizer.getLang(player.locale()).optimize_for_trading.forEach(player::sendMessage); - } - } -} diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RenameOptimizedVillagers.java b/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RenameOptimizedVillagers.java deleted file mode 100644 index 50a3d10..0000000 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RenameOptimizedVillagers.java +++ /dev/null @@ -1,73 +0,0 @@ -package me.xginko.villageroptimizer.modules.gameplay; - -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.WrappedVillager; -import me.xginko.villageroptimizer.config.Config; -import me.xginko.villageroptimizer.events.VillagerOptimizeEvent; -import me.xginko.villageroptimizer.events.VillagerUnoptimizeEvent; -import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.minimessage.MiniMessage; -import org.bukkit.entity.Villager; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; - -public class RenameOptimizedVillagers implements VillagerOptimizerModule, Listener { - - private final VillagerOptimizer plugin; - private final Component optimized_name; - private final boolean overwrite_previous_name; - - public RenameOptimizedVillagers() { - shouldEnable(); - this.plugin = VillagerOptimizer.getInstance(); - Config config = VillagerOptimizer.getConfiguration(); - config.addComment("gameplay.rename-optimized-villagers.enable", """ - Will change a villager's name to the name configured below when they are optimized.\s - These names will be removed when unoptimized again if they were not changed in the meantime. - """); - this.optimized_name = MiniMessage.miniMessage().deserialize(config.getString("gameplay.rename-optimized-villagers.optimized-name", "Optimized", - "The name that will be used to mark optimized villagers. Uses MiniMessage format.")); - this.overwrite_previous_name = config.getBoolean("gameplay.rename-optimized-villagers.overwrite-existing-name", false, - "If set to true, will rename even if the villager has already been named."); - } - - @Override - public void enable() { - plugin.getServer().getPluginManager().registerEvents(this, plugin); - } - - @Override - public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean("gameplay.rename-optimized-villagers.enable", true); - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - private void onOptimize(VillagerOptimizeEvent event) { - WrappedVillager wVillager = event.getWrappedVillager(); - Villager villager = wVillager.villager(); - - plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> { - if (overwrite_previous_name || villager.customName() == null) { - villager.customName(optimized_name); - wVillager.memorizeName(optimized_name); - } - }, 10L); - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - private void onUnOptimize(VillagerUnoptimizeEvent event) { - WrappedVillager wVillager = event.getWrappedVillager(); - Villager villager = wVillager.villager(); - - plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> { - final Component currentName = villager.customName(); - final Component memorizedName = wVillager.getMemorizedName(); - if (currentName != null && currentName.equals(memorizedName)) - villager.customName(null); - if (memorizedName != null) - wVillager.forgetName(); - }, 10L); - } -} \ No newline at end of file diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RestockOptimizedTrades.java b/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RestockOptimizedTrades.java deleted file mode 100644 index bb516f5..0000000 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RestockOptimizedTrades.java +++ /dev/null @@ -1,74 +0,0 @@ -package me.xginko.villageroptimizer.modules.gameplay; - -import me.xginko.villageroptimizer.VillagerCache; -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.WrappedVillager; -import me.xginko.villageroptimizer.config.Config; -import me.xginko.villageroptimizer.enums.Permissions; -import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; -import me.xginko.villageroptimizer.utils.CommonUtil; -import net.kyori.adventure.text.TextReplacementConfig; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Player; -import org.bukkit.entity.Villager; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerInteractEntityEvent; - -public class RestockOptimizedTrades implements VillagerOptimizerModule, 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.addComment("gameplay.restock-optimized-trades", """ - This is for automatic restocking of trades for optimized villagers. Optimized Villagers\s - don't have enough AI to restock their trades naturally, so this is here as a workaround."""); - this.restock_delay_millis = config.getInt("gameplay.restock-optimized-trades.delay-in-ticks", 1000, - "1 second = 20 ticks. There are 24.000 ticks in a single minecraft day.") * 50L; - this.notify_player = config.getBoolean("gameplay.restock-optimized-trades.notify-player", true, - "Sends the player a message when the trades were restocked on a clicked villager."); - this.log_enabled = config.getBoolean("gameplay.restock-optimized-trades.log", false); - } - - @Override - public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); - plugin.getServer().getPluginManager().registerEvents(this, plugin); - } - - @Override - public boolean shouldEnable() { - return true; - } - - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - private void onInteract(PlayerInteractEntityEvent event) { - if (!event.getRightClicked().getType().equals(EntityType.VILLAGER)) return; - - WrappedVillager wVillager = villagerCache.getOrAdd((Villager) event.getRightClicked()); - if (!wVillager.isOptimized()) return; - Player player = event.getPlayer(); - - final boolean player_bypassing = player.hasPermission(Permissions.Bypass.RESTOCK_COOLDOWN.get()); - - if (wVillager.canRestock(restock_delay_millis) || player_bypassing) { - wVillager.restock(); - wVillager.saveRestockTime(); - if (notify_player && !player_bypassing) { - final TextReplacementConfig timeLeft = TextReplacementConfig.builder() - .matchLiteral("%time%") - .replacement(CommonUtil.formatTime(wVillager.getRestockCooldownMillis(restock_delay_millis))) - .build(); - VillagerOptimizer.getLang(player.locale()).trades_restocked.forEach(line -> player.sendMessage(line.replaceText(timeLeft))); - } - if (log_enabled) - VillagerOptimizer.getLog().info("Restocked optimized villager at "+ wVillager.villager().getLocation()); - } - } -} diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByBlock.java b/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByBlock.java deleted file mode 100644 index 1c15da6..0000000 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByBlock.java +++ /dev/null @@ -1,193 +0,0 @@ -package me.xginko.villageroptimizer.modules.optimization; - -import me.xginko.villageroptimizer.VillagerCache; -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.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.CommonUtil; -import me.xginko.villageroptimizer.utils.LogUtil; -import net.kyori.adventure.text.TextReplacementConfig; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Player; -import org.bukkit.entity.Villager; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockPlaceEvent; - -import java.util.HashSet; -import java.util.List; - -public class OptimizeByBlock implements VillagerOptimizerModule, Listener { - - private final VillagerCache villagerCache; - private final HashSet blocks_that_disable = new HashSet<>(4); - private final long cooldown; - 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.addComment("optimization-methods.block-optimization.enable", """ - When enabled, the closest villager standing near a configured block being placed will be optimized.\s - If a configured block is broken nearby, the closest villager will become unoptimized again."""); - config.getList("optimization-methods.block-optimization.materials", List.of( - "LAPIS_BLOCK", "GLOWSTONE", "IRON_BLOCK" - ), "Values here need to be valid bukkit Material enums for your server version." - ).forEach(configuredMaterial -> { - try { - Material disableBlock = Material.valueOf(configuredMaterial); - this.blocks_that_disable.add(disableBlock); - } catch (IllegalArgumentException e) { - LogUtil.materialNotRecognized("block-optimization", configuredMaterial); - } - }); - this.cooldown = config.getInt("optimization-methods.block-optimization.optimize-cooldown-seconds", 600, """ - Cooldown in seconds until a villager can be optimized again by using specific blocks. \s - Here for configuration freedom. Recommended to leave as is to not enable any exploitable behavior.""") * 1000L; - this.search_radius = config.getDouble("optimization-methods.block-optimization.search-radius-in-blocks", 2.0, """ - The radius in blocks a villager can be away from the player when he places an optimize block.\s - The closest unoptimized villager to the player will be optimized.""") / 2; - this.only_while_sneaking = config.getBoolean("optimization-methods.block-optimization.only-when-sneaking", true, - "Only optimize/unoptimize by workstation when player is sneaking during place or break."); - this.notify_player = config.getBoolean("optimization-methods.block-optimization.notify-player", true, - "Sends players a message when they successfully optimized or unoptimized a villager."); - this.log_enabled = config.getBoolean("optimization-methods.block-optimization.log", false); - } - - @Override - public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); - plugin.getServer().getPluginManager().registerEvents(this, plugin); - } - - @Override - public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean("optimization-methods.block-optimization.enable", false); - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - private void onBlockPlace(BlockPlaceEvent event) { - Block placed = event.getBlock(); - if (!blocks_that_disable.contains(placed.getType())) return; - Player player = event.getPlayer(); - if (!player.hasPermission(Permissions.Optimize.BLOCK.get())) return; - if (only_while_sneaking && !player.isSneaking()) return; - - final Location blockLoc = placed.getLocation(); - WrappedVillager closestOptimizableVillager = null; - double closestDistance = Double.MAX_VALUE; - - for (Entity entity : blockLoc.getNearbyEntities(search_radius, search_radius, search_radius)) { - if (!entity.getType().equals(EntityType.VILLAGER)) continue; - Villager villager = (Villager) entity; - final Villager.Profession profession = villager.getProfession(); - if (profession.equals(Villager.Profession.NONE) || profession.equals(Villager.Profession.NITWIT)) continue; - - WrappedVillager wVillager = villagerCache.getOrAdd(villager); - final double distance = entity.getLocation().distance(blockLoc); - - if (distance < closestDistance && wVillager.canOptimize(cooldown)) { - closestOptimizableVillager = wVillager; - closestDistance = distance; - } - } - - if (closestOptimizableVillager == null) return; - - if (closestOptimizableVillager.canOptimize(cooldown) || player.hasPermission(Permissions.Bypass.BLOCK_COOLDOWN.get())) { - VillagerOptimizeEvent optimizeEvent = new VillagerOptimizeEvent(closestOptimizableVillager, OptimizationType.BLOCK, player, event.isAsynchronous()); - if (!optimizeEvent.callEvent()) return; - - closestOptimizableVillager.setOptimization(optimizeEvent.getOptimizationType()); - closestOptimizableVillager.saveOptimizeTime(); - - if (notify_player) { - final TextReplacementConfig vilProfession = TextReplacementConfig.builder() - .matchLiteral("%vil_profession%") - .replacement(closestOptimizableVillager.villager().getProfession().toString().toLowerCase()) - .build(); - final TextReplacementConfig placedMaterial = TextReplacementConfig.builder() - .matchLiteral("%blocktype%") - .replacement(placed.getType().toString().toLowerCase()) - .build(); - VillagerOptimizer.getLang(player.locale()).block_optimize_success.forEach(line -> player.sendMessage(line - .replaceText(vilProfession) - .replaceText(placedMaterial) - )); - } - if (log_enabled) - VillagerOptimizer.getLog().info("Villager was optimized by block at "+closestOptimizableVillager.villager().getLocation()); - } else { - if (notify_player) { - final TextReplacementConfig timeLeft = TextReplacementConfig.builder() - .matchLiteral("%time%") - .replacement(CommonUtil.formatTime(closestOptimizableVillager.getOptimizeCooldownMillis(cooldown))) - .build(); - VillagerOptimizer.getLang(player.locale()).block_on_optimize_cooldown.forEach(line -> player.sendMessage(line.replaceText(timeLeft))); - } - } - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - private void onBlockBreak(BlockBreakEvent event) { - Block broken = event.getBlock(); - if (!blocks_that_disable.contains(broken.getType())) return; - Player player = event.getPlayer(); - if (!player.hasPermission(Permissions.Optimize.BLOCK.get())) return; - if (only_while_sneaking && !player.isSneaking()) return; - - final Location blockLoc = broken.getLocation(); - WrappedVillager closestOptimizedVillager = null; - double closestDistance = Double.MAX_VALUE; - - for (Entity entity : blockLoc.getNearbyEntities(search_radius, search_radius, search_radius)) { - if (!entity.getType().equals(EntityType.VILLAGER)) continue; - Villager villager = (Villager) entity; - - WrappedVillager wVillager = villagerCache.getOrAdd(villager); - final double distance = entity.getLocation().distance(blockLoc); - - if (distance < closestDistance && wVillager.isOptimized()) { - closestOptimizedVillager = wVillager; - closestDistance = distance; - } - } - - if (closestOptimizedVillager == null) return; - - VillagerUnoptimizeEvent unOptimizeEvent = new VillagerUnoptimizeEvent(closestOptimizedVillager, player, OptimizationType.BLOCK, event.isAsynchronous()); - if (!unOptimizeEvent.callEvent()) return; - - closestOptimizedVillager.setOptimization(OptimizationType.NONE); - - if (notify_player) { - final TextReplacementConfig vilProfession = TextReplacementConfig.builder() - .matchLiteral("%vil_profession%") - .replacement(closestOptimizedVillager.villager().getProfession().toString().toLowerCase()) - .build(); - final TextReplacementConfig brokenMaterial = TextReplacementConfig.builder() - .matchLiteral("%blocktype%") - .replacement(broken.getType().toString().toLowerCase()) - .build(); - VillagerOptimizer.getLang(player.locale()).block_unoptimize_success.forEach(line -> player.sendMessage(line - .replaceText(vilProfession) - .replaceText(brokenMaterial) - )); - } - if (log_enabled) - VillagerOptimizer.getLog().info("Villager unoptimized because nearby optimization block broken at: "+closestOptimizedVillager.villager().getLocation()); - } -} \ No newline at end of file diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByNametag.java b/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByNametag.java deleted file mode 100644 index 139bd81..0000000 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByNametag.java +++ /dev/null @@ -1,126 +0,0 @@ -package me.xginko.villageroptimizer.modules.optimization; - -import me.xginko.villageroptimizer.VillagerCache; -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.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.CommonUtil; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.TextReplacementConfig; -import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; -import org.bukkit.Material; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Player; -import org.bukkit.entity.Villager; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerInteractEntityEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.HashSet; -import java.util.List; - -public class OptimizeByNametag implements VillagerOptimizerModule, Listener { - - private final VillagerCache villagerCache; - private final HashSet nametags = new HashSet<>(4); - 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.addComment("optimization-methods.nametag-optimization.enable", """ - Enable optimization by naming villagers to one of the names configured below.\s - Nametag optimized villagers will be unoptimized again when they are renamed to something else."""); - this.nametags.addAll(config.getList("optimization-methods.nametag-optimization.names", List.of("Optimize", "DisableAI"), - "Names are case insensitive, capital letters won't matter.").stream().map(String::toLowerCase).toList()); - this.consume_nametag = config.getBoolean("optimization-methods.nametag-optimization.nametags-get-consumed", true, - "Enable or disable consumption of the used nametag item."); - this.cooldown = config.getInt("optimization-methods.nametag-optimization.optimize-cooldown-seconds", 600, """ - Cooldown in seconds until a villager can be optimized again using a nametag.\s - Here for configuration freedom. Recommended to leave as is to not enable any exploitable behavior.""") * 1000L; - this.notify_player = config.getBoolean("optimization-methods.nametag-optimization.notify-player", true, - "Sends players a message when they successfully optimized a villager."); - this.log_enabled = config.getBoolean("optimization-methods.nametag-optimization.log", false); - } - - @Override - public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); - plugin.getServer().getPluginManager().registerEvents(this, plugin); - } - - @Override - public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean("optimization-methods.nametag-optimization.enable", true); - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - private void onPlayerInteractEntity(PlayerInteractEntityEvent event) { - if (!event.getRightClicked().getType().equals(EntityType.VILLAGER)) return; - Player player = event.getPlayer(); - if (!player.hasPermission(Permissions.Optimize.NAMETAG.get())) return; - - ItemStack usedItem = player.getInventory().getItem(event.getHand()); - if (usedItem == null || !usedItem.getType().equals(Material.NAME_TAG)) return; - ItemMeta meta = usedItem.getItemMeta(); - if (!meta.hasDisplayName()) return; - - // Get component name first, so we can manually name the villager when canceling the event to avoid item consumption. - Component newVillagerName = meta.displayName(); - assert newVillagerName != null; // Legitimate since we checked for hasDisplayName() - final String name = PlainTextComponentSerializer.plainText().serialize(newVillagerName); - Villager villager = (Villager) event.getRightClicked(); - WrappedVillager wVillager = villagerCache.getOrAdd(villager); - - if (nametags.contains(name.toLowerCase())) { - if (wVillager.canOptimize(cooldown) || player.hasPermission(Permissions.Bypass.NAMETAG_COOLDOWN.get())) { - VillagerOptimizeEvent optimizeEvent = new VillagerOptimizeEvent(wVillager, OptimizationType.NAMETAG, player, event.isAsynchronous()); - if (!optimizeEvent.callEvent()) return; - - if (!consume_nametag) { - event.setCancelled(true); - villager.customName(newVillagerName); - } - - wVillager.setOptimization(optimizeEvent.getOptimizationType()); - wVillager.saveOptimizeTime(); - - if (notify_player) - VillagerOptimizer.getLang(player.locale()).nametag_optimize_success.forEach(player::sendMessage); - if (log_enabled) - VillagerOptimizer.getLog().info(player.getName() + " optimized a villager using nametag: '" + name + "'"); - } else { - event.setCancelled(true); - if (notify_player) { - final TextReplacementConfig timeLeft = TextReplacementConfig.builder() - .matchLiteral("%time%") - .replacement(CommonUtil.formatTime(wVillager.getOptimizeCooldownMillis(cooldown))) - .build(); - VillagerOptimizer.getLang(player.locale()).nametag_on_optimize_cooldown.forEach(line -> player.sendMessage(line.replaceText(timeLeft))); - } - } - } else { - if (wVillager.isOptimized()) { - VillagerUnoptimizeEvent unOptimizeEvent = new VillagerUnoptimizeEvent(wVillager, player, OptimizationType.NAMETAG, event.isAsynchronous()); - if (!unOptimizeEvent.callEvent()) return; - - wVillager.setOptimization(OptimizationType.NONE); - - if (notify_player) - VillagerOptimizer.getLang(player.locale()).nametag_unoptimize_success.forEach(player::sendMessage); - if (log_enabled) - VillagerOptimizer.getLog().info(event.getPlayer().getName() + " disabled optimizations for a villager using nametag: '" + name + "'"); - } - } - } -} \ No newline at end of file diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByWorkstation.java b/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByWorkstation.java deleted file mode 100644 index b720acc..0000000 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByWorkstation.java +++ /dev/null @@ -1,200 +0,0 @@ -package me.xginko.villageroptimizer.modules.optimization; - -import me.xginko.villageroptimizer.VillagerCache; -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.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.CommonUtil; -import net.kyori.adventure.text.TextReplacementConfig; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Player; -import org.bukkit.entity.Villager; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockPlaceEvent; - -public class OptimizeByWorkstation implements VillagerOptimizerModule, Listener { - - private final VillagerCache villagerCache; - private final long cooldown; - private final double search_radius; - private final boolean only_while_sneaking, log_enabled, notify_player; - - public OptimizeByWorkstation() { - shouldEnable(); - this.villagerCache = VillagerOptimizer.getCache(); - Config config = VillagerOptimizer.getConfiguration(); - config.addComment("optimization-methods.workstation-optimization.enable", """ - When enabled, the closest villager near a matching workstation being placed will be optimized.\s - If a nearby matching workstation is broken, the villager will become unoptimized again."""); - this.search_radius = config.getDouble("optimization-methods.workstation-optimization.search-radius-in-blocks", 2.0, """ - The radius in blocks a villager can be away from the player when he places a workstation.\s - The closest unoptimized villager to the player will be optimized.""") / 2; - this.cooldown = config.getInt("optimization-methods.workstation-optimization.optimize-cooldown-seconds", 600, """ - Cooldown in seconds until a villager can be optimized again using a workstation.\s - Here for configuration freedom. Recommended to leave as is to not enable any exploitable behavior.""") * 1000L; - this.only_while_sneaking = config.getBoolean("optimization-methods.workstation-optimization.only-when-sneaking", true, - "Only optimize/unoptimize by workstation when player is sneaking during place or break"); - this.notify_player = config.getBoolean("optimization-methods.workstation-optimization.notify-player", true, - "Sends players a message when they successfully optimized a villager."); - this.log_enabled = config.getBoolean("optimization-methods.workstation-optimization.log", false); - } - - @Override - public void enable() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); - plugin.getServer().getPluginManager().registerEvents(this, plugin); - } - - @Override - public boolean shouldEnable() { - return VillagerOptimizer.getConfiguration().getBoolean("optimization-methods.workstation-optimization.enable", false); - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - private void onBlockPlace(BlockPlaceEvent event) { - Block placed = event.getBlock(); - Villager.Profession workstationProfession = getWorkstationProfession(placed.getType()); - if (workstationProfession.equals(Villager.Profession.NONE)) return; - Player player = event.getPlayer(); - if (!player.hasPermission(Permissions.Optimize.WORKSTATION.get())) return; - if (only_while_sneaking && !player.isSneaking()) return; - - final Location workstationLoc = placed.getLocation(); - WrappedVillager closestOptimizableVillager = null; - double closestDistance = Double.MAX_VALUE; - - for (Entity entity : workstationLoc.getNearbyEntities(search_radius, search_radius, search_radius)) { - if (!entity.getType().equals(EntityType.VILLAGER)) continue; - Villager villager = (Villager) entity; - if (!villager.getProfession().equals(workstationProfession)) continue; - - WrappedVillager wVillager = villagerCache.getOrAdd(villager); - final double distance = entity.getLocation().distance(workstationLoc); - - if (distance < closestDistance && wVillager.canOptimize(cooldown)) { - closestOptimizableVillager = wVillager; - closestDistance = distance; - } - } - - if (closestOptimizableVillager == null) return; - - if (closestOptimizableVillager.canOptimize(cooldown) || player.hasPermission(Permissions.Bypass.WORKSTATION_COOLDOWN.get())) { - VillagerOptimizeEvent optimizeEvent = new VillagerOptimizeEvent(closestOptimizableVillager, OptimizationType.WORKSTATION, player, event.isAsynchronous()); - if (!optimizeEvent.callEvent()) return; - - closestOptimizableVillager.setOptimization(optimizeEvent.getOptimizationType()); - closestOptimizableVillager.saveOptimizeTime(); - - if (notify_player) { - final TextReplacementConfig vilProfession = TextReplacementConfig.builder() - .matchLiteral("%vil_profession%") - .replacement(closestOptimizableVillager.villager().getProfession().toString().toLowerCase()) - .build(); - final TextReplacementConfig placedWorkstation = TextReplacementConfig.builder() - .matchLiteral("%workstation%") - .replacement(placed.getType().toString().toLowerCase()) - .build(); - VillagerOptimizer.getLang(player.locale()).workstation_optimize_success.forEach(line -> player.sendMessage(line - .replaceText(vilProfession) - .replaceText(placedWorkstation) - )); - } - if (log_enabled) - VillagerOptimizer.getLog().info(player.getName() + " optimized a villager using workstation: '" + placed.getType().toString().toLowerCase() + "'"); - } else { - if (notify_player) { - final TextReplacementConfig timeLeft = TextReplacementConfig.builder() - .matchLiteral("%time%") - .replacement(CommonUtil.formatTime(closestOptimizableVillager.getOptimizeCooldownMillis(cooldown))) - .build(); - VillagerOptimizer.getLang(player.locale()).nametag_on_optimize_cooldown.forEach(line -> player.sendMessage(line - .replaceText(timeLeft) - )); - } - } - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - private void onBlockBreak(BlockBreakEvent event) { - Block broken = event.getBlock(); - Villager.Profession workstationProfession = getWorkstationProfession(broken.getType()); - if (workstationProfession.equals(Villager.Profession.NONE)) return; - Player player = event.getPlayer(); - if (!player.hasPermission(Permissions.Optimize.WORKSTATION.get())) return; - if (only_while_sneaking && !player.isSneaking()) return; - - final Location workstationLoc = broken.getLocation(); - WrappedVillager closestOptimizedVillager = null; - double closestDistance = Double.MAX_VALUE; - - for (Entity entity : workstationLoc.getNearbyEntities(search_radius, search_radius, search_radius)) { - if (!entity.getType().equals(EntityType.VILLAGER)) continue; - Villager villager = (Villager) entity; - if (!villager.getProfession().equals(workstationProfession)) continue; - - WrappedVillager wVillager = villagerCache.getOrAdd(villager); - final double distance = entity.getLocation().distance(workstationLoc); - - if (distance < closestDistance && wVillager.canOptimize(cooldown)) { - closestOptimizedVillager = wVillager; - closestDistance = distance; - } - } - - if (closestOptimizedVillager == null) return; - - VillagerUnoptimizeEvent unOptimizeEvent = new VillagerUnoptimizeEvent(closestOptimizedVillager, player, OptimizationType.WORKSTATION, event.isAsynchronous()); - if (!unOptimizeEvent.callEvent()) return; - - closestOptimizedVillager.setOptimization(OptimizationType.NONE); - - if (notify_player) { - final TextReplacementConfig vilProfession = TextReplacementConfig.builder() - .matchLiteral("%vil_profession%") - .replacement(closestOptimizedVillager.villager().getProfession().toString().toLowerCase()) - .build(); - final TextReplacementConfig brokenWorkstation = TextReplacementConfig.builder() - .matchLiteral("%workstation%") - .replacement(broken.getType().toString().toLowerCase()) - .build(); - VillagerOptimizer.getLang(player.locale()).workstation_unoptimize_success.forEach(line -> player.sendMessage(line - .replaceText(vilProfession) - .replaceText(brokenWorkstation) - )); - } - if (log_enabled) - VillagerOptimizer.getLog().info(player.getName() + " unoptimized a villager by breaking workstation: '" + broken.getType().toString().toLowerCase() + "'"); - } - - private Villager.Profession getWorkstationProfession(final Material workstation) { - return switch (workstation) { - case BARREL -> Villager.Profession.FISHERMAN; - case CARTOGRAPHY_TABLE -> Villager.Profession.CARTOGRAPHER; - case SMOKER -> Villager.Profession.BUTCHER; - case SMITHING_TABLE -> Villager.Profession.TOOLSMITH; - case GRINDSTONE -> Villager.Profession.WEAPONSMITH; - case BLAST_FURNACE -> Villager.Profession.ARMORER; - case CAULDRON -> Villager.Profession.LEATHERWORKER; - case BREWING_STAND -> Villager.Profession.CLERIC; - case COMPOSTER -> Villager.Profession.FARMER; - case FLETCHING_TABLE -> Villager.Profession.FLETCHER; - case LOOM -> Villager.Profession.SHEPHERD; - case LECTERN -> Villager.Profession.LIBRARIAN; - case STONECUTTER -> Villager.Profession.MASON; - default -> Villager.Profession.NONE; - }; - } -} \ No newline at end of file diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/utils/CommonUtil.java b/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/utils/CommonUtil.java deleted file mode 100644 index 1a0e2f1..0000000 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/utils/CommonUtil.java +++ /dev/null @@ -1,24 +0,0 @@ -package me.xginko.villageroptimizer.utils; - -import org.jetbrains.annotations.NotNull; - -import java.time.Duration; - -import static java.lang.String.format; - -public class CommonUtil { - public static @NotNull String formatTime(final 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 format("%02dh %02dm %02ds", hours, minutes, seconds); - } else if (minutes > 0) { - return format("%02dm %02ds", minutes, seconds); - } else { - return format("%02ds", seconds); - } - } -} diff --git a/VillagerOptimizer-1.16.5/src/main/resources/plugin.yml b/VillagerOptimizer-1.16.5/src/main/resources/plugin.yml deleted file mode 100644 index 7afb484..0000000 --- a/VillagerOptimizer-1.16.5/src/main/resources/plugin.yml +++ /dev/null @@ -1,98 +0,0 @@ -name: VillagerOptimizer -version: '${project.version}' -main: me.xginko.villageroptimizer.VillagerOptimizer -authors: [ xGinko ] -description: ${project.description} -website: ${project.url} -api-version: '1.16' -folia-supported: false -commands: - villageroptimizer: - usage: /villageroptimizer [ reload, version, disable ] - description: VillagerOptimizer admin commands - aliases: - - voptimizer - - vo - optimizevillagers: - usage: /optimizevillagers - description: Optmize villagers in a radius around you - aliases: - - optvils - - noai - unoptimizevillagers: - usage: /unoptimizevillagers - description: Unoptmize villagers in a radius around you - aliases: - - unoptvils - - noaiundo -permissions: - villageroptimizer.ignore: - description: Players with this permission won't be able to use the plugin features - children: - villageroptimizer.optimize.nametag: false - villageroptimizer.optimize.block: false - villageroptimizer.optimize.workstation: false - villageroptimizer.playerdefaults: - description: Default permissions for players - default: true - children: - villageroptimizer.cmd.optimize: true - villageroptimizer.cmd.unoptimize: true - villageroptimizer.optimize.*: true - villageroptimizer.*: - description: All plugin permissions - children: - villageroptimizer.cmd.*: true - villageroptimizer.bypass.*: true - villageroptimizer.optimize.*: true - villageroptimizer.optimize.*: - description: Optimization type permissions - children: - villageroptimizer.optimize.nametag: true - villageroptimizer.optimize.block: true - villageroptimizer.optimize.workstation: true - villageroptimizer.optimize.nametag: - description: Optimize/Unoptimize villagers using nametags - villageroptimizer.optimize.block: - description: Optimize/Unoptimize villagers using specific blocks - villageroptimizer.optimize.workstation: - description: Optimize/Unoptimize villagers using workstations - villageroptimizer.cmd.*: - description: All command permissions - children: - villageroptimizer.cmd.reload: true - villageroptimizer.cmd.disable: true - villageroptimizer.cmd.version: true - villageroptimizer.cmd.optimize: true - villageroptimizer.cmd.unoptimize: true - villageroptimizer.cmd.disable: - description: Disable the plugin - villageroptimizer.cmd.reload: - description: Reload the plugin configuration - villageroptimizer.cmd.version: - description: Show the plugin version - villageroptimizer.cmd.optimize: - description: Optimize villagers in a radius - villageroptimizer.cmd.unoptimize: - description: Unoptimize villagers in a radius - villageroptimizer.bypass.*: - description: All bypass permissions - children: - villageroptimizer.bypass.tradeprevention: true - villageroptimizer.bypass.restockcooldown: true - villageroptimizer.bypass.nametagcooldown: true - villageroptimizer.bypass.blockcooldown: true - villageroptimizer.bypass.workstationcooldown: true - villageroptimizer.bypass.commandcooldown: true - villageroptimizer.bypass.tradeprevention: - description: Bypass unoptimized trading prevention if enabled - villageroptimizer.bypass.restockcooldown: - description: Bypass permission for optimized trade restock cooldown - villageroptimizer.bypass.nametagcooldown: - description: Bypass permission for nametag optimization cooldown - villageroptimizer.bypass.blockcooldown: - description: Bypass permission for block optimization cooldown - villageroptimizer.bypass.workstationcooldown: - description: Bypass permission for workstation optimization cooldown - villageroptimizer.bypass.commandcooldown: - description: Bypass permission for command optimization cooldown \ No newline at end of file diff --git a/VillagerOptimizer-1.20.2/pom.xml b/VillagerOptimizer-1.20.2/pom.xml deleted file mode 100644 index d607e6c..0000000 --- a/VillagerOptimizer-1.20.2/pom.xml +++ /dev/null @@ -1,87 +0,0 @@ - - - 4.0.0 - - - me.xginko.VillagerOptimizer - VillagerOptimizer - 1.0.2 - - - 1.20.2 - ${project.parent.artifactId}-${project.parent.version}--${project.artifactId} - jar - - - 17 - UTF-8 - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.11.0 - - ${java.version} - ${java.version} - - - - org.apache.maven.plugins - maven-shade-plugin - 3.5.1 - - - package - - shade - - - false - - - com.github.benmanes.caffeine - me.xginko.villageroptimizer.caffeine - - - org.bstats - me.xginko.villageroptimizer.bstats - - - - - - - - - - src/main/resources - true - - - - - - - papermc-repo - https://repo.papermc.io/repository/maven-public/ - - - sonatype - https://oss.sonatype.org/content/groups/public/ - - - - - - io.papermc.paper - paper-api - 1.20.2-R0.1-SNAPSHOT - provided - - - diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/VillagerCache.java b/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/VillagerCache.java deleted file mode 100644 index 9d59b13..0000000 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/VillagerCache.java +++ /dev/null @@ -1,56 +0,0 @@ -package me.xginko.villageroptimizer; - -import com.github.benmanes.caffeine.cache.Cache; -import com.github.benmanes.caffeine.cache.Caffeine; -import org.bukkit.Bukkit; -import org.bukkit.entity.Villager; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.time.Duration; -import java.util.UUID; -import java.util.concurrent.ConcurrentMap; - -public final class VillagerCache { - - private final @NotNull Cache villagerCache; - - VillagerCache(long expireAfterWriteSeconds) { - this.villagerCache = Caffeine.newBuilder().expireAfterWrite(Duration.ofSeconds(expireAfterWriteSeconds)).build(); - } - - public @NotNull ConcurrentMap cacheMap() { - return this.villagerCache.asMap(); - } - - public @Nullable WrappedVillager get(@NotNull UUID uuid) { - WrappedVillager wrappedVillager = this.villagerCache.getIfPresent(uuid); - return wrappedVillager == null && Bukkit.getEntity(uuid) instanceof Villager villager ? this.add(villager) : wrappedVillager; - } - - public @NotNull WrappedVillager getOrAdd(@NotNull Villager villager) { - WrappedVillager wrappedVillager = this.villagerCache.getIfPresent(villager.getUniqueId()); - return wrappedVillager == null ? this.add(new WrappedVillager(villager)) : this.add(wrappedVillager); - } - - public @NotNull WrappedVillager add(@NotNull WrappedVillager villager) { - this.villagerCache.put(villager.villager().getUniqueId(), villager); - return villager; - } - - public @NotNull WrappedVillager add(@NotNull Villager villager) { - return this.add(new WrappedVillager(villager)); - } - - public boolean contains(@NotNull UUID uuid) { - return this.villagerCache.getIfPresent(uuid) != null; - } - - public boolean contains(@NotNull WrappedVillager villager) { - return this.contains(villager.villager().getUniqueId()); - } - - public boolean contains(@NotNull Villager villager) { - return this.contains(villager.getUniqueId()); - } -} \ No newline at end of file diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/WrappedVillager.java b/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/WrappedVillager.java deleted file mode 100644 index d4dbc97..0000000 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/WrappedVillager.java +++ /dev/null @@ -1,192 +0,0 @@ -package me.xginko.villageroptimizer; - -import me.xginko.villageroptimizer.enums.Keys; -import me.xginko.villageroptimizer.enums.OptimizationType; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.minimessage.MiniMessage; -import org.bukkit.entity.Villager; -import org.bukkit.persistence.PersistentDataContainer; -import org.bukkit.persistence.PersistentDataType; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public final class WrappedVillager { - - private final @NotNull Villager villager; - private final @NotNull PersistentDataContainer dataContainer; - - WrappedVillager(@NotNull Villager villager) { - this.villager = villager; - this.dataContainer = villager.getPersistentDataContainer(); - } - - /** - * @return The villager inside the wrapper. - */ - public @NotNull Villager villager() { - return villager; - } - - /** - * @return The data container inside the wrapper. - */ - public @NotNull PersistentDataContainer dataContainer() { - return dataContainer; - } - - /** - * @return True if the villager is optimized by this plugin, otherwise false. - */ - public boolean isOptimized() { - return dataContainer.has(Keys.OPTIMIZATION_TYPE.key()); - } - - /** - * @param cooldown_millis The configured cooldown in millis until the next optimization is allowed to occur. - * @return True if villager can be optimized again, otherwise false. - */ - public boolean canOptimize(final long cooldown_millis) { - return getLastOptimize() + cooldown_millis <= System.currentTimeMillis(); - } - - /** - * @param type OptimizationType the villager should be set to. - */ - public void setOptimization(OptimizationType type) { - if (type.equals(OptimizationType.NONE) && isOptimized()) { - dataContainer.remove(Keys.OPTIMIZATION_TYPE.key()); - villager.getScheduler().run(VillagerOptimizer.getInstance(), enableAI -> { - villager.setAware(true); - villager.setAI(true); - }, null); - } else { - dataContainer.set(Keys.OPTIMIZATION_TYPE.key(), PersistentDataType.STRING, type.name()); - villager.getScheduler().run(VillagerOptimizer.getInstance(), disableAI -> { - villager.setAware(false); - }, null); - } - } - - /** - * @return The current OptimizationType of the villager. - */ - public @NotNull OptimizationType getOptimizationType() { - return isOptimized() ? OptimizationType.valueOf(dataContainer.get(Keys.OPTIMIZATION_TYPE.key(), PersistentDataType.STRING)) : OptimizationType.NONE; - } - - /** - * Saves the system time in millis when the villager was last optimized. - */ - public void saveOptimizeTime() { - dataContainer.set(Keys.LAST_OPTIMIZE.key(), PersistentDataType.LONG, System.currentTimeMillis()); - } - - /** - * @return The system time in millis when the villager was last optimized, 0L if the villager was never optimized. - */ - public long getLastOptimize() { - return dataContainer.has(Keys.LAST_OPTIMIZE.key(), PersistentDataType.LONG) ? dataContainer.get(Keys.LAST_OPTIMIZE.key(), PersistentDataType.LONG) : 0L; - } - - /** - * Here for convenience so the remaining millis since the last stored optimize time - * can be easily calculated. - * This enables new configured cooldowns to instantly apply instead of them being persistent. - * - * @param cooldown_millis The configured cooldown in milliseconds you want to check against. - * @return The time left in millis until the villager can be optimized again. - */ - public long getOptimizeCooldownMillis(final long cooldown_millis) { - return dataContainer.has(Keys.LAST_OPTIMIZE.key(), PersistentDataType.LONG) ? (System.currentTimeMillis() - (dataContainer.get(Keys.LAST_OPTIMIZE.key(), PersistentDataType.LONG) + cooldown_millis)) : cooldown_millis; - } - - /** - * Here for convenience so the remaining millis since the last stored restock time - * can be easily calculated. - * - * @param cooldown_millis The configured cooldown in milliseconds you want to check against. - * @return True if the villager has been loaded long enough. - */ - public boolean canRestock(final long cooldown_millis) { - return getLastRestock() + cooldown_millis <= villager.getWorld().getFullTime(); - } - - /** - * Restock all trading recipes. - */ - public void restock() { - villager.getRecipes().forEach(recipe -> recipe.setUses(0)); - } - - /** - * Saves the time of the in-game world when the entity was last restocked. - */ - public void saveRestockTime() { - dataContainer.set(Keys.LAST_RESTOCK.key(), PersistentDataType.LONG, villager.getWorld().getFullTime()); - } - - /** - * @return The time of the in-game world when the entity was last restocked. - */ - public long getLastRestock() { - return dataContainer.has(Keys.LAST_RESTOCK.key(), PersistentDataType.LONG) ? dataContainer.get(Keys.LAST_RESTOCK.key(), PersistentDataType.LONG) : 0L; - } - - public long getRestockCooldownMillis(final long cooldown_millis) { - return dataContainer.has(Keys.LAST_RESTOCK.key(), PersistentDataType.LONG) ? (villager.getWorld().getFullTime() - (dataContainer.get(Keys.LAST_RESTOCK.key(), PersistentDataType.LONG) + cooldown_millis)) : cooldown_millis; - } - - /** - * @return The level between 1-5 calculated from the villagers experience. - */ - public int calculateLevel() { - // https://minecraft.fandom.com/wiki/Trading#Mechanics - int vilEXP = villager.getVillagerExperience(); - if (vilEXP >= 250) return 5; - if (vilEXP >= 150) return 4; - if (vilEXP >= 70) return 3; - if (vilEXP >= 10) return 2; - return 1; - } - - /** - * @param cooldown_millis The configured cooldown in milliseconds you want to check against. - * @return Whether the villager can be leveled up or not with the checked milliseconds - */ - public boolean canLevelUp(final long cooldown_millis) { - return getLastLevelUpTime() + cooldown_millis <= villager.getWorld().getFullTime(); - } - - /** - * Saves the time of the in-game world when the entity was last leveled up. - */ - public void saveLastLevelUp() { - dataContainer.set(Keys.LAST_LEVELUP.key(), PersistentDataType.LONG, villager.getWorld().getFullTime()); - } - - /** - * Here for convenience so the remaining millis since the last stored level-up time - * can be easily calculated. - * - * @return The time of the in-game world when the entity was last leveled up. - */ - public long getLastLevelUpTime() { - return dataContainer.has(Keys.LAST_LEVELUP.key(), PersistentDataType.LONG) ? dataContainer.get(Keys.LAST_LEVELUP.key(), PersistentDataType.LONG) : 0L; - } - - public long getLevelCooldownMillis(final long cooldown_millis) { - return dataContainer.has(Keys.LAST_LEVELUP.key(), PersistentDataType.LONG) ? (villager.getWorld().getFullTime() - (dataContainer.get(Keys.LAST_LEVELUP.key(), PersistentDataType.LONG) + cooldown_millis)) : cooldown_millis; - } - - public void memorizeName(final Component customName) { - dataContainer.set(Keys.LAST_OPTIMIZE_NAME.key(), PersistentDataType.STRING, MiniMessage.miniMessage().serialize(customName)); - } - - public @Nullable Component getMemorizedName() { - return dataContainer.has(Keys.LAST_OPTIMIZE_NAME.key()) ? MiniMessage.miniMessage().deserialize(dataContainer.get(Keys.LAST_OPTIMIZE_NAME.key(), PersistentDataType.STRING)) : null; - } - - public void forgetName() { - dataContainer.remove(Keys.LAST_OPTIMIZE_NAME.key()); - } -} \ No newline at end of file diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/SubCommand.java b/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/SubCommand.java deleted file mode 100644 index 4ce3d53..0000000 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/SubCommand.java +++ /dev/null @@ -1,11 +0,0 @@ -package me.xginko.villageroptimizer.commands; - -import net.kyori.adventure.text.TextComponent; -import org.bukkit.command.CommandSender; - -public abstract class SubCommand { - public abstract String getLabel(); - public abstract TextComponent getDescription(); - public abstract TextComponent getSyntax(); - public abstract void perform(CommandSender sender, String[] args); -} diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/VillagerOptimizerCommand.java b/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/VillagerOptimizerCommand.java deleted file mode 100644 index acfbcd8..0000000 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/VillagerOptimizerCommand.java +++ /dev/null @@ -1,35 +0,0 @@ -package me.xginko.villageroptimizer.commands; - -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.commands.optimizevillagers.OptVillagersRadius; -import me.xginko.villageroptimizer.commands.unoptimizevillagers.UnOptVillagersRadius; -import me.xginko.villageroptimizer.commands.villageroptimizer.VillagerOptimizerCmd; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandMap; -import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; - -import java.util.HashSet; - -public interface VillagerOptimizerCommand extends CommandExecutor { - - String label(); - - HashSet commands = new HashSet<>(); - static void reloadCommands() { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); - CommandMap commandMap = plugin.getServer().getCommandMap(); - commands.forEach(command -> plugin.getCommand(command.label()).unregister(commandMap)); - commands.clear(); - - commands.add(new VillagerOptimizerCmd()); - commands.add(new OptVillagersRadius()); - commands.add(new UnOptVillagersRadius()); - - commands.forEach(command -> plugin.getCommand(command.label()).setExecutor(command)); - } - - @Override - boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args); -} diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/optimizevillagers/OptVillagersRadius.java b/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/optimizevillagers/OptVillagersRadius.java deleted file mode 100644 index 26daa8c..0000000 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/optimizevillagers/OptVillagersRadius.java +++ /dev/null @@ -1,142 +0,0 @@ -package me.xginko.villageroptimizer.commands.optimizevillagers; - -import me.xginko.villageroptimizer.VillagerCache; -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.WrappedVillager; -import me.xginko.villageroptimizer.commands.VillagerOptimizerCommand; -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 net.kyori.adventure.text.Component; -import net.kyori.adventure.text.TextReplacementConfig; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextDecoration; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabCompleter; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Player; -import org.bukkit.entity.Villager; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -public class OptVillagersRadius implements VillagerOptimizerCommand, TabCompleter { - - private final List tabCompletes = List.of("5", "10", "25", "50"); - private final long cooldown; - private final int max_radius; - - public OptVillagersRadius() { - Config config = VillagerOptimizer.getConfiguration(); - 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.\s - Here for configuration freedom. Recommended to leave as is to not enable any exploitable behavior.""") * 1000L; - } - - @Override - public String label() { - return "optimizevillagers"; - } - - @Override - public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - return args.length == 1 ? tabCompletes : null; - } - - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { - if (!(sender instanceof Player player)) { - sender.sendMessage(Component.text("This command can only be executed by a player.") - .color(NamedTextColor.RED).decorate(TextDecoration.BOLD)); - return true; - } - - if (!sender.hasPermission(Permissions.Commands.OPTIMIZE_RADIUS.get())) { - sender.sendMessage(VillagerOptimizer.getLang(sender).no_permission); - return true; - } - - if (args.length != 1) { - VillagerOptimizer.getLang(player.locale()).command_specify_radius.forEach(player::sendMessage); - return true; - } - - try { - int specifiedRadius = Integer.parseInt(args[0]); - - if (specifiedRadius > max_radius) { - final TextReplacementConfig limit = TextReplacementConfig.builder() - .matchLiteral("%distance%") - .replacement(Integer.toString(max_radius)) - .build(); - VillagerOptimizer.getLang(player.locale()).command_radius_limit_exceed.forEach(line -> player.sendMessage(line.replaceText(limit))); - return true; - } - - VillagerCache villagerCache = VillagerOptimizer.getCache(); - int successCount = 0; - int failCount = 0; - final boolean player_has_cooldown_bypass = player.hasPermission(Permissions.Bypass.COMMAND_COOLDOWN.get()); - - for (Entity entity : player.getNearbyEntities(specifiedRadius, specifiedRadius, specifiedRadius)) { - if (!entity.getType().equals(EntityType.VILLAGER)) continue; - Villager villager = (Villager) entity; - Villager.Profession profession = villager.getProfession(); - if (profession.equals(Villager.Profession.NITWIT) || profession.equals(Villager.Profession.NONE)) continue; - - WrappedVillager wVillager = villagerCache.getOrAdd(villager); - - if (player_has_cooldown_bypass || wVillager.canOptimize(cooldown)) { - VillagerOptimizeEvent optimizeEvent = new VillagerOptimizeEvent(wVillager, OptimizationType.COMMAND, player); - if (optimizeEvent.callEvent()) { - wVillager.setOptimization(optimizeEvent.getOptimizationType()); - wVillager.saveOptimizeTime(); - successCount++; - } - } else { - failCount++; - } - } - - if (successCount <= 0 && failCount <= 0) { - final TextReplacementConfig radius = TextReplacementConfig.builder() - .matchLiteral("%radius%") - .replacement(Integer.toString(specifiedRadius)) - .build(); - VillagerOptimizer.getLang(player.locale()).command_no_villagers_nearby.forEach(line -> player.sendMessage(line.replaceText(radius))); - return true; - } - - if (successCount > 0) { - final TextReplacementConfig success_amount = TextReplacementConfig.builder() - .matchLiteral("%amount%") - .replacement(Integer.toString(successCount)) - .build(); - final TextReplacementConfig radius = TextReplacementConfig.builder() - .matchLiteral("%radius%") - .replacement(Integer.toString(specifiedRadius)) - .build(); - VillagerOptimizer.getLang(player.locale()).command_optimize_success.forEach(line -> player.sendMessage(line - .replaceText(success_amount) - .replaceText(radius) - )); - } - if (failCount > 0) { - final TextReplacementConfig alreadyOptimized = TextReplacementConfig.builder() - .matchLiteral("%amount%") - .replacement(Integer.toString(failCount)) - .build(); - VillagerOptimizer.getLang(player.locale()).command_optimize_fail.forEach(line -> player.sendMessage(line.replaceText(alreadyOptimized))); - } - } catch (NumberFormatException e) { - VillagerOptimizer.getLang(player.locale()).command_radius_invalid.forEach(player::sendMessage); - } - - return true; - } -} \ No newline at end of file diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/unoptimizevillagers/UnOptVillagersRadius.java b/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/unoptimizevillagers/UnOptVillagersRadius.java deleted file mode 100644 index 1652735..0000000 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/unoptimizevillagers/UnOptVillagersRadius.java +++ /dev/null @@ -1,121 +0,0 @@ -package me.xginko.villageroptimizer.commands.unoptimizevillagers; - -import me.xginko.villageroptimizer.VillagerCache; -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.WrappedVillager; -import me.xginko.villageroptimizer.commands.VillagerOptimizerCommand; -import me.xginko.villageroptimizer.enums.OptimizationType; -import me.xginko.villageroptimizer.enums.Permissions; -import me.xginko.villageroptimizer.events.VillagerUnoptimizeEvent; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.TextReplacementConfig; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextDecoration; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabCompleter; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Player; -import org.bukkit.entity.Villager; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -public class UnOptVillagersRadius implements VillagerOptimizerCommand, TabCompleter { - - private final List tabCompletes = List.of("5", "10", "25", "50"); - private final int max_radius; - - public UnOptVillagersRadius() { - this.max_radius = VillagerOptimizer.getConfiguration().getInt("optimization-methods.commands.unoptimizevillagers.max-block-radius", 100); - } - - @Override - public String label() { - return "unoptimizevillagers"; - } - - @Override - public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - return args.length == 1 ? tabCompletes : null; - } - - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { - if (!(sender instanceof Player player)) { - sender.sendMessage(Component.text("This command can only be executed by a player.") - .color(NamedTextColor.RED).decorate(TextDecoration.BOLD)); - return true; - } - - if (!sender.hasPermission(Permissions.Commands.UNOPTIMIZE_RADIUS.get())) { - sender.sendMessage(VillagerOptimizer.getLang(sender).no_permission); - return true; - } - - if (args.length != 1) { - VillagerOptimizer.getLang(player.locale()).command_specify_radius.forEach(player::sendMessage); - return true; - } - - try { - int specifiedRadius = Integer.parseInt(args[0]); - - if (specifiedRadius > max_radius) { - final TextReplacementConfig limit = TextReplacementConfig.builder() - .matchLiteral("%distance%") - .replacement(Integer.toString(max_radius)) - .build(); - VillagerOptimizer.getLang(player.locale()).command_radius_limit_exceed.forEach(line -> player.sendMessage(line.replaceText(limit))); - return true; - } - - VillagerCache villagerCache = VillagerOptimizer.getCache(); - int successCount = 0; - - for (Entity entity : player.getNearbyEntities(specifiedRadius, specifiedRadius, specifiedRadius)) { - if (!entity.getType().equals(EntityType.VILLAGER)) continue; - Villager villager = (Villager) entity; - Villager.Profession profession = villager.getProfession(); - if (profession.equals(Villager.Profession.NITWIT) || profession.equals(Villager.Profession.NONE)) continue; - - WrappedVillager wVillager = villagerCache.getOrAdd(villager); - - if (wVillager.isOptimized()) { - VillagerUnoptimizeEvent unOptimizeEvent = new VillagerUnoptimizeEvent(wVillager, player, OptimizationType.COMMAND); - if (unOptimizeEvent.callEvent()) { - wVillager.setOptimization(OptimizationType.NONE); - successCount++; - } - } - } - - if (successCount <= 0) { - final TextReplacementConfig radius = TextReplacementConfig.builder() - .matchLiteral("%radius%") - .replacement(Integer.toString(specifiedRadius)) - .build(); - VillagerOptimizer.getLang(player.locale()).command_no_villagers_nearby.forEach(line -> player.sendMessage(line.replaceText(radius))); - } else { - final TextReplacementConfig success_amount = TextReplacementConfig.builder() - .matchLiteral("%amount%") - .replacement(Integer.toString(successCount)) - .build(); - final TextReplacementConfig radius = TextReplacementConfig.builder() - .matchLiteral("%radius%") - .replacement(Integer.toString(specifiedRadius)) - .build(); - VillagerOptimizer.getLang(player.locale()).command_unoptimize_success.forEach(line -> player.sendMessage(line - .replaceText(success_amount) - .replaceText(radius) - )); - } - } catch (NumberFormatException e) { - VillagerOptimizer.getLang(player.locale()).command_radius_invalid.forEach(player::sendMessage); - } - - return true; - } -} \ No newline at end of file diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/VillagerOptimizerCmd.java b/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/VillagerOptimizerCmd.java deleted file mode 100644 index 9843b57..0000000 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/VillagerOptimizerCmd.java +++ /dev/null @@ -1,79 +0,0 @@ -package me.xginko.villageroptimizer.commands.villageroptimizer; - -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.commands.SubCommand; -import me.xginko.villageroptimizer.commands.VillagerOptimizerCommand; -import me.xginko.villageroptimizer.commands.villageroptimizer.subcommands.DisableSubCmd; -import me.xginko.villageroptimizer.commands.villageroptimizer.subcommands.ReloadSubCmd; -import me.xginko.villageroptimizer.commands.villageroptimizer.subcommands.VersionSubCmd; -import me.xginko.villageroptimizer.enums.Permissions; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabCompleter; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; - -public class VillagerOptimizerCmd implements TabCompleter, VillagerOptimizerCommand { - - private final List subCommands = new ArrayList<>(3); - private final List tabCompleter = new ArrayList<>(3); - - public VillagerOptimizerCmd() { - subCommands.add(new ReloadSubCmd()); - subCommands.add(new VersionSubCmd()); - subCommands.add(new DisableSubCmd()); - subCommands.forEach(subCommand -> tabCompleter.add(subCommand.getLabel())); - } - - @Override - public String label() { - return "villageroptimizer"; - } - - @Override - public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) { - return args.length == 1 ? tabCompleter : null; - } - - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { - if (args.length > 0) { - boolean cmdExists = false; - for (SubCommand subCommand : subCommands) { - if (args[0].equalsIgnoreCase(subCommand.getLabel())) { - subCommand.perform(sender, args); - cmdExists = true; - break; - } - } - if (!cmdExists) sendCommandOverview(sender); - } else { - sendCommandOverview(sender); - } - return true; - } - - private void sendCommandOverview(CommandSender sender) { - if (!sender.hasPermission(Permissions.Commands.RELOAD.get()) && !sender.hasPermission(Permissions.Commands.VERSION.get())) return; - sender.sendMessage(Component.text("-----------------------------------------------------").color(NamedTextColor.GRAY)); - sender.sendMessage(Component.text("VillagerOptimizer Commands").color(VillagerOptimizer.plugin_style.color())); - sender.sendMessage(Component.text("-----------------------------------------------------").color(NamedTextColor.GRAY)); - subCommands.forEach(subCommand -> sender.sendMessage( - subCommand.getSyntax().append(Component.text(" - ").color(NamedTextColor.DARK_GRAY)).append(subCommand.getDescription()))); - sender.sendMessage( - Component.text("/optimizevillagers ").color(VillagerOptimizer.plugin_style.color()) - .append(Component.text(" - ").color(NamedTextColor.DARK_GRAY)) - .append(Component.text("Optimize villagers in a radius").color(NamedTextColor.GRAY)) - ); - sender.sendMessage( - Component.text("/unoptmizevillagers ").color(VillagerOptimizer.plugin_style.color()) - .append(Component.text(" - ").color(NamedTextColor.DARK_GRAY)) - .append(Component.text("Unoptimize villagers in a radius").color(NamedTextColor.GRAY)) - ); - sender.sendMessage(Component.text("-----------------------------------------------------").color(NamedTextColor.GRAY)); - } -} \ No newline at end of file diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/ReloadSubCmd.java b/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/ReloadSubCmd.java deleted file mode 100644 index 5b1e099..0000000 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/ReloadSubCmd.java +++ /dev/null @@ -1,41 +0,0 @@ -package me.xginko.villageroptimizer.commands.villageroptimizer.subcommands; - -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.commands.SubCommand; -import me.xginko.villageroptimizer.enums.Permissions; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.TextComponent; -import net.kyori.adventure.text.format.NamedTextColor; -import org.bukkit.command.CommandSender; - -public class ReloadSubCmd extends SubCommand { - - @Override - public String getLabel() { - return "reload"; - } - - @Override - public TextComponent getDescription() { - return Component.text("Reload the plugin configuration.").color(NamedTextColor.GRAY); - } - - @Override - public TextComponent getSyntax() { - return Component.text("/villageroptimizer reload").color(VillagerOptimizer.plugin_style.color()); - } - - @Override - public void perform(CommandSender sender, String[] args) { - if (sender.hasPermission(Permissions.Commands.RELOAD.get())) { - sender.sendMessage(Component.text("Reloading VillagerOptimizer...").color(NamedTextColor.WHITE)); - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); - plugin.getServer().getAsyncScheduler().runNow(plugin, reloadPlugin -> { - plugin.reloadPlugin(); - sender.sendMessage(Component.text("Reload complete.").color(NamedTextColor.GREEN)); - }); - } else { - sender.sendMessage(VillagerOptimizer.getLang(sender).no_permission); - } - } -} \ No newline at end of file diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/VersionSubCmd.java b/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/VersionSubCmd.java deleted file mode 100644 index 55495c1..0000000 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/VersionSubCmd.java +++ /dev/null @@ -1,53 +0,0 @@ -package me.xginko.villageroptimizer.commands.villageroptimizer.subcommands; - -import io.papermc.paper.plugin.configuration.PluginMeta; -import me.xginko.villageroptimizer.VillagerOptimizer; -import me.xginko.villageroptimizer.commands.SubCommand; -import me.xginko.villageroptimizer.enums.Permissions; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.TextComponent; -import net.kyori.adventure.text.event.ClickEvent; -import net.kyori.adventure.text.format.NamedTextColor; -import org.bukkit.command.CommandSender; - -public class VersionSubCmd extends SubCommand { - - @Override - public String getLabel() { - return "version"; - } - - @Override - public TextComponent getDescription() { - return Component.text("Show the plugin version.").color(NamedTextColor.GRAY); - } - - @Override - public TextComponent getSyntax() { - return Component.text("/villageroptimizer version").color(VillagerOptimizer.plugin_style.color()); - } - - @Override - public void perform(CommandSender sender, String[] args) { - if (sender.hasPermission(Permissions.Commands.VERSION.get())) { - final PluginMeta pluginMeta = VillagerOptimizer.getInstance().getPluginMeta(); - sender.sendMessage( - Component.newline() - .append( - Component.text(pluginMeta.getName()+" "+pluginMeta.getVersion()) - .style(VillagerOptimizer.plugin_style) - .clickEvent(ClickEvent.openUrl(pluginMeta.getWebsite())) - ) - .append(Component.text(" by ").color(NamedTextColor.GRAY)) - .append( - Component.text(pluginMeta.getAuthors().get(0)) - .color(NamedTextColor.WHITE) - .clickEvent(ClickEvent.openUrl("https://github.com/xGinko")) - ) - .append(Component.newline()) - ); - } else { - sender.sendMessage(VillagerOptimizer.getLang(sender).no_permission); - } - } -} \ No newline at end of file diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/config/LanguageCache.java b/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/config/LanguageCache.java deleted file mode 100644 index 20086f4..0000000 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/config/LanguageCache.java +++ /dev/null @@ -1,109 +0,0 @@ -package me.xginko.villageroptimizer.config; - -import io.github.thatsmusic99.configurationmaster.api.ConfigFile; -import me.xginko.villageroptimizer.VillagerOptimizer; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.minimessage.MiniMessage; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.util.List; - -public class LanguageCache { - - private final @NotNull ConfigFile lang; - - public final @NotNull Component no_permission; - public final @NotNull List nametag_optimize_success, nametag_on_optimize_cooldown, nametag_unoptimize_success, - block_optimize_success, block_on_optimize_cooldown, block_unoptimize_success, - workstation_optimize_success, workstation_on_optimize_cooldown, workstation_unoptimize_success, - command_optimize_success, command_radius_limit_exceed, command_optimize_fail, command_unoptimize_success, - command_specify_radius, command_radius_invalid, command_no_villagers_nearby, - trades_restocked, optimize_for_trading, villager_leveling_up; - - public LanguageCache(String locale) throws Exception { - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); - File langYML = new File(plugin.getDataFolder() + File.separator + "lang", locale + ".yml"); - // Check if the lang folder has already been created - File parent = langYML.getParentFile(); - if (!parent.exists() && !parent.mkdir()) - VillagerOptimizer.getLog().severe("Failed to create lang directory."); - // Check if the file already exists and save the one from the plugins resources folder if it does not - if (!langYML.exists()) - plugin.saveResource("lang" + File.separator + locale + ".yml", false); - // Finally load the lang file with configmaster - this.lang = ConfigFile.loadConfig(langYML); - - // General - this.no_permission = getTranslation("messages.no-permission", - "You don't have permission to use this command."); - this.trades_restocked = getListTranslation("messages.trades-restocked", - List.of("All trades have been restocked! Next restock in %time%")); - this.optimize_for_trading = getListTranslation("messages.optimize-to-trade", - List.of("You need to optimize this villager before you can trade with it.")); - this.villager_leveling_up = getListTranslation("messages.villager-leveling-up", - List.of("Villager is currently leveling up! You can use the villager again in %time%.")); - // Nametag - this.nametag_optimize_success = getListTranslation("messages.nametag.optimize-success", - List.of("Successfully optimized villager by using a nametag.")); - this.nametag_on_optimize_cooldown = getListTranslation("messages.nametag.optimize-on-cooldown", - List.of("You need to wait %time% until you can optimize this villager again.")); - this.nametag_unoptimize_success = getListTranslation("messages.nametag.unoptimize-success", - List.of("Successfully unoptimized villager by using a nametag.")); - // Block - this.block_optimize_success = getListTranslation("messages.block.optimize-success", - List.of("%villagertype% villager successfully optimized using block %blocktype%.")); - this.block_on_optimize_cooldown = getListTranslation("messages.block.optimize-on-cooldown", - List.of("You need to wait %time% until you can optimize this villager again.")); - this.block_unoptimize_success = getListTranslation("messages.block.unoptimize-success", - List.of("Successfully unoptimized %villagertype% villager by removing %blocktype%.")); - // Workstation - this.workstation_optimize_success = getListTranslation("messages.workstation.optimize-success", - List.of("%villagertype% villager successfully optimized using workstation %workstation%.")); - this.workstation_on_optimize_cooldown = getListTranslation("messages.workstation.optimize-on-cooldown", - List.of("You need to wait %time% until you can optimize this villager again.")); - this.workstation_unoptimize_success = getListTranslation("messages.workstation.unoptimize-success", - List.of("Successfully unoptimized %villagertype% villager by removing workstation block %workstation%.")); - // Command - this.command_optimize_success = getListTranslation("messages.command.optimize-success", - List.of("Successfully optimized %amount% villager(s) in a radius of %radius% blocks.")); - this.command_radius_limit_exceed = getListTranslation("messages.command.radius-limit-exceed", - List.of("The radius you entered exceeds the limit of %distance% blocks.")); - this.command_optimize_fail = getListTranslation("messages.command.optimize-fail", - List.of("%amount% villagers couldn't be optimized because they have recently been optimized.")); - this.command_unoptimize_success = getListTranslation("messages.command.unoptimize-success", - List.of("Successfully unoptimized %amount% villager(s) in a radius of %radius% blocks.")); - this.command_specify_radius = getListTranslation("messages.command.specify-radius", - List.of("Please specify a radius.")); - this.command_radius_invalid = getListTranslation("messages.command.radius-invalid", - List.of("The radius you entered is not a valid number. Try again.")); - this.command_no_villagers_nearby = getListTranslation("messages.command.no-villagers-nearby", - List.of("Couldn't find any employed villagers within a radius of %radius%.")); - - try { - this.lang.save(); - } catch (Exception e) { - VillagerOptimizer.getLog().severe("Failed to save language file: "+ langYML.getName() +" - " + e.getLocalizedMessage()); - } - } - - public @NotNull Component getTranslation(@NotNull String path, @NotNull String defaultTranslation) { - this.lang.addDefault(path, defaultTranslation); - return MiniMessage.miniMessage().deserialize(this.lang.getString(path, defaultTranslation)); - } - - public @NotNull Component getTranslation(@NotNull String path, @NotNull String defaultTranslation, @NotNull String comment) { - this.lang.addDefault(path, defaultTranslation, comment); - return MiniMessage.miniMessage().deserialize(this.lang.getString(path, defaultTranslation)); - } - - public @NotNull List getListTranslation(@NotNull String path, @NotNull List defaultTranslation) { - this.lang.addDefault(path, defaultTranslation); - return this.lang.getStringList(path).stream().map(MiniMessage.miniMessage()::deserialize).toList(); - } - - public @NotNull List getListTranslation(@NotNull String path, @NotNull List defaultTranslation, @NotNull String comment) { - this.lang.addDefault(path, defaultTranslation, comment); - return this.lang.getStringList(path).stream().map(MiniMessage.miniMessage()::deserialize).toList(); - } -} \ No newline at end of file diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/enums/Keys.java b/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/enums/Keys.java deleted file mode 100644 index 4c75d96..0000000 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/enums/Keys.java +++ /dev/null @@ -1,24 +0,0 @@ -package me.xginko.villageroptimizer.enums; - -import me.xginko.villageroptimizer.VillagerOptimizer; -import org.bukkit.NamespacedKey; - -public enum Keys { - - OPTIMIZATION_TYPE(VillagerOptimizer.getKey("optimization-type")), - LAST_OPTIMIZE(VillagerOptimizer.getKey("last-optimize")), - LAST_LEVELUP(VillagerOptimizer.getKey("last-levelup")), - LAST_RESTOCK(VillagerOptimizer.getKey("last-restock")), - LAST_OPTIMIZE_NAME(VillagerOptimizer.getKey("last-optimize-name")); - - private final NamespacedKey key; - - Keys(NamespacedKey key) { - this.key = key; - } - - public NamespacedKey key() { - return key; - } - -} diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/enums/OptimizationType.java b/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/enums/OptimizationType.java deleted file mode 100644 index 09c304b..0000000 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/enums/OptimizationType.java +++ /dev/null @@ -1,11 +0,0 @@ -package me.xginko.villageroptimizer.enums; - -public enum OptimizationType { - - COMMAND, - NAMETAG, - WORKSTATION, - BLOCK, - NONE - -} diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/enums/Permissions.java b/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/enums/Permissions.java deleted file mode 100644 index 8b17eba..0000000 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/enums/Permissions.java +++ /dev/null @@ -1,45 +0,0 @@ -package me.xginko.villageroptimizer.enums; - -public class Permissions { - public enum Commands { - VERSION("villageroptimizer.cmd.version"), - RELOAD("villageroptimizer.cmd.reload"), - DISABLE("villageroptimizer.cmd.disable"), - OPTIMIZE_RADIUS("villageroptimizer.cmd.optimize"), - UNOPTIMIZE_RADIUS("villageroptimizer.cmd.unoptimize"); - private final String permission; - Commands(String permission) { - this.permission = permission; - } - public String get() { - return permission; - } - } - public enum Optimize { - NAMETAG("villageroptimizer.optimize.nametag"), - BLOCK("villageroptimizer.optimize.block"), - WORKSTATION("villageroptimizer.optimize.workstation"); - private final String permission; - Optimize(String permission) { - this.permission = permission; - } - public String get() { - return permission; - } - } - public enum Bypass { - TRADE_PREVENTION("villageroptimizer.bypass.tradeprevention"), - RESTOCK_COOLDOWN("villageroptimizer.bypass.restockcooldown"), - NAMETAG_COOLDOWN("villageroptimizer.bypass.nametagcooldown"), - BLOCK_COOLDOWN("villageroptimizer.bypass.blockcooldown"), - WORKSTATION_COOLDOWN("villageroptimizer.bypass.workstationcooldown"), - COMMAND_COOLDOWN("villageroptimizer.bypass.commandcooldown"); - private final String permission; - Bypass(String permission) { - this.permission = permission; - } - public String get() { - return permission; - } - } -} diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/events/VillagerUnoptimizeEvent.java b/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/events/VillagerUnoptimizeEvent.java deleted file mode 100644 index c84cd17..0000000 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/events/VillagerUnoptimizeEvent.java +++ /dev/null @@ -1,63 +0,0 @@ -package me.xginko.villageroptimizer.events; - -import me.xginko.villageroptimizer.WrappedVillager; -import me.xginko.villageroptimizer.enums.OptimizationType; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public class VillagerUnoptimizeEvent extends Event implements Cancellable { - - private static final @NotNull HandlerList handlers = new HandlerList(); - private final @NotNull WrappedVillager wrappedVillager; - private final @NotNull OptimizationType unoptimizeType; - private final @Nullable Player whoUnoptimized; - private boolean isCancelled = false; - - public VillagerUnoptimizeEvent(@NotNull WrappedVillager wrappedVillager, @Nullable Player whoUnoptimized, @NotNull OptimizationType unoptimizeType, boolean isAsync) { - super(isAsync); - this.wrappedVillager = wrappedVillager; - this.whoUnoptimized = whoUnoptimized; - this.unoptimizeType = unoptimizeType; - } - - public VillagerUnoptimizeEvent(@NotNull WrappedVillager wrappedVillager, @Nullable Player whoUnoptimized, @NotNull OptimizationType unoptimizeType) { - this.wrappedVillager = wrappedVillager; - this.whoUnoptimized = whoUnoptimized; - this.unoptimizeType = unoptimizeType; - } - - public @NotNull WrappedVillager getWrappedVillager() { - return wrappedVillager; - } - - public @Nullable Player getWhoUnoptimized() { - return whoUnoptimized; - } - - public @NotNull OptimizationType getWhichTypeUnoptimized() { - return unoptimizeType; - } - - @Override - public boolean isCancelled() { - return isCancelled; - } - - @Override - public void setCancelled(boolean cancel) { - this.isCancelled = cancel; - } - - @Override - public @NotNull HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } -} diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/utils/LogUtil.java b/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/utils/LogUtil.java deleted file mode 100644 index 38929e1..0000000 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/utils/LogUtil.java +++ /dev/null @@ -1,26 +0,0 @@ -package me.xginko.villageroptimizer.utils; - -import me.xginko.villageroptimizer.VillagerOptimizer; - -import java.util.logging.Level; - -public class LogUtil { - - public static void moduleLog(Level logLevel, String path, String logMessage) { - VillagerOptimizer.getLog().log(logLevel, "(" + path + ") " + logMessage); - } - - public static void materialNotRecognized(String path, String material) { - moduleLog(Level.WARNING, path, "Material '" + material + "' not recognized. Please use correct Material enums from: " + - "https://jd.papermc.io/paper/1.20/org/bukkit/Material.html"); - } - - public static void damageCauseNotRecognized(String path, String cause) { - moduleLog(Level.WARNING, path, "DamageCause '" + cause + "' not recognized. Please use correct DamageCause enums from: " + - "https://jd.papermc.io/paper/1.20/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html"); - } - - public static void entityTypeNotRecognized(String path, String entityType) { - moduleLog(Level.WARNING, path, "EntityType '" + entityType + "' not recognized. Please use correct Spigot EntityType enums for your Minecraft version!"); - } -} \ No newline at end of file diff --git a/VillagerOptimizer-1.20.2/src/main/resources/lang/de_de.yml b/VillagerOptimizer-1.20.2/src/main/resources/lang/de_de.yml deleted file mode 100644 index 80bf52f..0000000 --- a/VillagerOptimizer-1.20.2/src/main/resources/lang/de_de.yml +++ /dev/null @@ -1,44 +0,0 @@ -messages: - no-permission: "Du hast keine Berechtigung für diesen Befehl." - optimize-to-trade: - - "Optimiere den Dorfbewohner um mit ihm handeln zu können." - trades-restocked: - - "Alle Angebote sind wieder verfügbar! Nächste Auffrischung in %time%." - villager-leveling-up: - - "Dorfbewohner steigt gerade im Level auf und kann in %time% wieder handeln." - nametag: - optimize-success: - - "Dorfbewohner erfolgreich mit einem Namensschild optimiert." - optimize-on-cooldown: - - "Du musst %time% warten, bevor du diesen Dorfbewohner erneut optimieren kannst." - unoptimize-success: - - "Optimierung erfolgreich durch eine Namensschildänderung aufgehoben." - block: - optimize-success: - - "%vil_profession% Dorfbewohner erfolgreich mit %blocktype% optimiert." - optimize-on-cooldown: - - "Du musst %time% warten, bevor du diesen Dorfbewohner erneut optimieren kannst." - unoptimize-success: - - "Optimierung des %vil_profession% Dorfbewohners erfolgreich durch Abbauen von %blocktype% aufgehoben." - workstation: - optimize-success: - - "%vil_profession% Dorfbewohner erfolgreich mit Arbeitsplatz-Block %blocktype% optimiert." - optimize-on-cooldown: - - "Du musst %time% warten, bevor du diesen Dorfbewohner erneut optimieren kannst." - unoptimize-success: - - "Optimierung des %vil_profession% Dorfbewohners erfolgreich durch Abbauen von %blocktype% aufgehoben." - command: - optimize-success: - - "Erfolgreich %amount% Dorfbewohner in einem Radius von %radius% Blöcken optimiert." - optimize-fail: - - "%amount% Dorfbewohner konnten nicht optimiert werden, da sie erst vor Kurzem optimiert wurden." - radius-limit-exceed: - - "Der eingegebene Radius überschreitet das Limit von %distance% Blöcken." - unoptimize-success: - - "Optimierung von %amount% Dorfbewohnern in einem Radius von %radius% Blöcken erfolgreich aufgehoben." - specify-radius: - - "Bitte gib einen Radius an." - radius-invalid: - - "Der eingegebene Radius ist keine gültige Zahl. Versuche es erneut." - no-villagers-nearby: - - "Es wurden keine beschäftigten Dorfbewohner innerhalb eines Radius von %radius% Blöcken gefunden." \ No newline at end of file diff --git a/VillagerOptimizer-1.20.2/src/main/resources/lang/en_us.yml b/VillagerOptimizer-1.20.2/src/main/resources/lang/en_us.yml deleted file mode 100644 index 838c290..0000000 --- a/VillagerOptimizer-1.20.2/src/main/resources/lang/en_us.yml +++ /dev/null @@ -1,44 +0,0 @@ -messages: - no-permission: "You don't have permission to use this command." - optimize-to-trade: - - "You need to optimize this villager before you can trade with it." - trades-restocked: - - "All trades have been restocked! Next restock in %time%." - villager-leveling-up: - - "Villager is currently leveling up! You can use the villager again in %time%." - nametag: - optimize-success: - - "Successfully optimized villager by using a nametag." - optimize-on-cooldown: - - "You need to wait %time% until you can optimize this villager again." - unoptimize-success: - - "Successfully unoptimized villager by using a nametag." - block: - optimize-success: - - "%vil_profession% villager successfully optimized using block %blocktype%." - optimize-on-cooldown: - - "You need to wait %time% until you can optimize this villager again." - unoptimize-success: - - "Successfully unoptimized %vil_profession% villager by removing %blocktype%." - workstation: - optimize-success: - - "%vil_profession% villager successfully optimized using workstation block %blocktype%." - optimize-on-cooldown: - - "You need to wait %time% until you can optimize this villager again." - unoptimize-success: - - "Successfully unoptimized villager by removing workstation block %blocktype%." - command: - optimize-success: - - "Successfully optimized %amount% villager(s) in a radius of %radius% blocks." - optimize-fail: - - "%amount% villagers couldn't be optimized because they have recently been optimized." - radius-limit-exceed: - - "The radius you entered exceeds the limit of %distance% blocks." - unoptimize-success: - - "Successfully unoptimized %amount% villager(s) in a radius of %radius% blocks." - specify-radius: - - "Please specify a radius." - radius-invalid: - - "The radius you entered is not a valid number. Try again." - no-villagers-nearby: - - "Couldn't find any employed villagers within a radius of %radius%." \ No newline at end of file diff --git a/VillagerOptimizer-1.20.2/src/main/resources/lang/it_it.yml b/VillagerOptimizer-1.20.2/src/main/resources/lang/it_it.yml deleted file mode 100644 index 2e0605f..0000000 --- a/VillagerOptimizer-1.20.2/src/main/resources/lang/it_it.yml +++ /dev/null @@ -1,44 +0,0 @@ -messages: - no-permission: "Non hai il permesso per usare questo comando." - optimize-to-trade: - - "Devi ottimizzare il villager prima di poterci commerciare." - trades-restocked: - - "Tutti i commerci sono stati riavviati! Prossimo riavvio in %time%." - villager-leveling-up: - - "Il villager si sta ancora ottimizzando! Potrai utilizzarlo di nuovo tra %time%." - nametag: - optimize-success: - - "Villager ottimizzato correttamente utilizzando il name-tag." - optimize-on-cooldown: - - "Devi attendere %time% prima di poter ottimizzare di nuovo questo villager." - unoptimize-success: - - "Ottimizzazione rimossa con successo dal villager usando il name-tag." - block: - optimize-success: - - "%vil_profession% ottimizzato con successo usando il blocco: %blocktype%." - optimize-on-cooldown: - - "Devi attendere %time% prima di poter ottimizzare di nuovo questo villager." - unoptimize-success: - - "Ottimizzazione rimossa al villager %vil_profession% rimuovendo il blocco: %blocktype%." - workstation: - optimize-success: - - "%vil_profession% ottimizzato con successo usando la workstation: %blocktype%." - optimize-on-cooldown: - - "Devi aspettare %time% prima di poter ottimizzare il villager." - unoptimize-success: - - "Ottimizzazione rimossa al villager %vil_profession% rimuovendo la workstation: %blocktype%." - command: - optimize-success: - - "Ottimizzato con successo %amount% villager in un raggio di %radius% blocchi." - optimize-fail: - - "%amount% villager non possono essere ottimizzati poiché sono stati già ottimizzati di recente." - radius-limit-exceed: - - "Il raggio inserito supera il limite di %distance% blocchi." - unoptimize-success: - - "Ottimizzazione rimossa con successo da %amount% villager in un raggio di %radius% blocchi." - specify-radius: - - "Per favore, specifica un raggio." - radius-invalid: - - "Il raggio inserito non è un numero valido, riprova." - no-villagers-nearby: - - "Non è stato possibile trovare villager entro un raggio di %radius% blocchi." \ No newline at end of file diff --git a/VillagerOptimizer-1.20.2/src/main/resources/lang/ru_ru.yml b/VillagerOptimizer-1.20.2/src/main/resources/lang/ru_ru.yml deleted file mode 100644 index 315b06c..0000000 --- a/VillagerOptimizer-1.20.2/src/main/resources/lang/ru_ru.yml +++ /dev/null @@ -1,44 +0,0 @@ -messages: - no-permission: "У вас нет разрешения на использование данной команды." - optimize-to-trade: - - "Вам необходимо оптимизировать данного жителя перед торговлей." - trades-restocked: - - "Товары были обновлены. Следующее обновление через %time%." - villager-leveling-up: - - "Данный житель повышает свой уровень. Вы сможете торговать через %time%" - nametag: - optimize-success: - - "Житель был успешно оптимизирован биркой." - optimize-on-cooldown: - - "Подождите еще %time% для повторной оптимизации данного жителя." - unoptimize-success: - - "Оптимизация была успешно снята с жителя." - block: - optimize-success: - - "%vil_profession% был успешно оптимизирован используя %blocktype%." - optimize-on-cooldown: - - "Подождите еще %time% для повторной оптимизации данного жителя." - unoptimize-success: - - "Оптимизация была успешно снята с %vil_profession% удалением %blocktype%." - workstation: - optimize-success: - - "%vil_profession% был успешно оптимизирован используя %blocktype%." - optimize-on-cooldown: - - "Подождите еще %time% для повторной оптимизации данного жителя." - unoptimize-success: - - "Оптимизация была успешно снята с %vil_profession% удалением %blocktype%." - command: - optimize-success: - - "Успешно оптимизинованы %amount% жителей в радиусе %radius% блоков." - optimize-fail: - - "%amount% жителей не могут быть оптимизированы снова так как они уже были оптимизированы недавно." - radius-limit-exceed: - - "Укажите радиус меньше %distance% блоков." - unoptimize-success: - - "Оптимизация была успешно снята с %amount% жителей в радиусе %radius% блоков." - specify-radius: - - "Пожалуйста, укажите радиус." - radius-invalid: - - "Указанный вами радиус не является действительным значением." - no-villagers-nearby: - - "Не найдено работающих жителей в радиусе %radius% блоков." \ No newline at end of file diff --git a/VillagerOptimizer-1.20.2/src/main/resources/plugin.yml b/VillagerOptimizer-1.20.2/src/main/resources/plugin.yml deleted file mode 100644 index f7ace91..0000000 --- a/VillagerOptimizer-1.20.2/src/main/resources/plugin.yml +++ /dev/null @@ -1,98 +0,0 @@ -name: VillagerOptimizer -version: '${project.version}' -main: me.xginko.villageroptimizer.VillagerOptimizer -authors: [ xGinko ] -description: ${project.description} -website: ${project.url} -api-version: '1.19' -folia-supported: true -commands: - villageroptimizer: - usage: /villageroptimizer [ reload, version, disable ] - description: VillagerOptimizer admin commands - aliases: - - voptimizer - - vo - optimizevillagers: - usage: /optimizevillagers - description: Optmize villagers in a radius around you - aliases: - - optvils - - noai - unoptimizevillagers: - usage: /unoptimizevillagers - description: Unoptmize villagers in a radius around you - aliases: - - unoptvils - - noaiundo -permissions: - villageroptimizer.ignore: - description: Players with this permission won't be able to use the plugin features - children: - villageroptimizer.optimize.nametag: false - villageroptimizer.optimize.block: false - villageroptimizer.optimize.workstation: false - villageroptimizer.playerdefaults: - description: Default permissions for players - default: true - children: - villageroptimizer.cmd.optimize: true - villageroptimizer.cmd.unoptimize: true - villageroptimizer.optimize.*: true - villageroptimizer.*: - description: All plugin permissions - children: - villageroptimizer.cmd.*: true - villageroptimizer.bypass.*: true - villageroptimizer.optimize.*: true - villageroptimizer.optimize.*: - description: Optimization type permissions - children: - villageroptimizer.optimize.nametag: true - villageroptimizer.optimize.block: true - villageroptimizer.optimize.workstation: true - villageroptimizer.optimize.nametag: - description: Optimize/Unoptimize villagers using nametags - villageroptimizer.optimize.block: - description: Optimize/Unoptimize villagers using specific blocks - villageroptimizer.optimize.workstation: - description: Optimize/Unoptimize villagers using workstations - villageroptimizer.cmd.*: - description: All command permissions - children: - villageroptimizer.cmd.reload: true - villageroptimizer.cmd.disable: true - villageroptimizer.cmd.version: true - villageroptimizer.cmd.optimize: true - villageroptimizer.cmd.unoptimize: true - villageroptimizer.cmd.disable: - description: Disable the plugin - villageroptimizer.cmd.reload: - description: Reload the plugin configuration - villageroptimizer.cmd.version: - description: Show the plugin version - villageroptimizer.cmd.optimize: - description: Optimize villagers in a radius - villageroptimizer.cmd.unoptimize: - description: Unoptimize villagers in a radius - villageroptimizer.bypass.*: - description: All bypass permissions - children: - villageroptimizer.bypass.tradeprevention: true - villageroptimizer.bypass.restockcooldown: true - villageroptimizer.bypass.nametagcooldown: true - villageroptimizer.bypass.blockcooldown: true - villageroptimizer.bypass.workstationcooldown: true - villageroptimizer.bypass.commandcooldown: true - villageroptimizer.bypass.tradeprevention: - description: Bypass unoptimized trading prevention if enabled - villageroptimizer.bypass.restockcooldown: - description: Bypass permission for optimized trade restock cooldown - villageroptimizer.bypass.nametagcooldown: - description: Bypass permission for nametag optimization cooldown - villageroptimizer.bypass.blockcooldown: - description: Bypass permission for block optimization cooldown - villageroptimizer.bypass.workstationcooldown: - description: Bypass permission for workstation optimization cooldown - villageroptimizer.bypass.commandcooldown: - description: Bypass permission for command optimization cooldown \ No newline at end of file diff --git a/pom.xml b/pom.xml index 1bc9b5c..f750332 100644 --- a/pom.xml +++ b/pom.xml @@ -6,18 +6,15 @@ me.xginko.VillagerOptimizer VillagerOptimizer - 1.0.2 - - VillagerOptimizer-1.20.2 - VillagerOptimizer-1.16.5 - - pom + 1.1.0 + jar VillagerOptimizer Combat heavy villager lag by letting players optimize their trading halls. https://github.com/xGinko/VillagerOptimizer + 17 UTF-8 @@ -43,8 +40,20 @@ shade - false - ${project.parent.artifactId}-${project.parent.version}--${project.artifactId} + + + com.tcoded.folialib + me.xginko.villageroptimizer.libs.folialib + + + com.github.benmanes.caffeine + me.xginko.villageroptimizer.libs.caffeine + + + org.bstats + me.xginko.villageroptimizer.libs.bstats + + *:* @@ -54,6 +63,7 @@ + false @@ -69,16 +79,43 @@ - papermc - https://papermc.io/repo/repository/maven-public/ + papermc-repo + https://repo.papermc.io/repository/maven-public/ + + + sonatype + https://oss.sonatype.org/content/groups/public/ configmaster-repo https://ci.pluginwiki.us/plugin/repository/everything/ + + folialib-repo + https://nexuslite.gcnt.net/repos/other/ + + + io.papermc.paper + paper-api + 1.20.4-R0.1-SNAPSHOT + provided + + + + net.kyori + adventure-text-minimessage + 4.15.0 + compile + + + net.kyori + adventure-text-serializer-plain + 4.15.0 + compile + org.bstats @@ -93,12 +130,19 @@ v2.0.0-rc.1 compile - + com.github.ben-manes.caffeine caffeine 3.1.8 compile + + + com.tcoded + FoliaLib + 0.3.1 + compile + diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/VillagerCache.java b/src/main/java/me/xginko/villageroptimizer/VillagerCache.java similarity index 97% rename from VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/VillagerCache.java rename to src/main/java/me/xginko/villageroptimizer/VillagerCache.java index 9d59b13..7d994b8 100644 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/VillagerCache.java +++ b/src/main/java/me/xginko/villageroptimizer/VillagerCache.java @@ -15,7 +15,7 @@ public final class VillagerCache { private final @NotNull Cache villagerCache; - VillagerCache(long expireAfterWriteSeconds) { + public VillagerCache(long expireAfterWriteSeconds) { this.villagerCache = Caffeine.newBuilder().expireAfterWrite(Duration.ofSeconds(expireAfterWriteSeconds)).build(); } diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java b/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java similarity index 96% rename from VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java rename to src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java index 382574e..eff0742 100644 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java +++ b/src/main/java/me/xginko/villageroptimizer/VillagerOptimizer.java @@ -1,5 +1,7 @@ package me.xginko.villageroptimizer; +import com.tcoded.folialib.FoliaLib; +import com.tcoded.folialib.impl.ServerImplementation; import me.xginko.villageroptimizer.commands.VillagerOptimizerCommand; import me.xginko.villageroptimizer.config.Config; import me.xginko.villageroptimizer.config.LanguageCache; @@ -28,21 +30,23 @@ import java.util.stream.Collectors; import java.util.zip.ZipEntry; public final class VillagerOptimizer extends JavaPlugin { + public static final Style plugin_style = Style.style(TextColor.color(102,255,230), TextDecoration.BOLD); private static VillagerOptimizer instance; private static VillagerCache villagerCache; + private static FoliaLib foliaLib; private static HashMap languageCacheMap; private static Config config; private static ConsoleCommandSender console; private static Logger logger; - public final static Style plugin_style = Style.style(TextColor.color(102,255,230), TextDecoration.BOLD); - @Override public void onEnable() { instance = this; logger = getLogger(); console = getServer().getConsoleSender(); + foliaLib = new FoliaLib(this); + console.sendMessage(Component.text("╭────────────────────────────────────────────────────────────╮").style(plugin_style)); console.sendMessage(Component.text("│ │").style(plugin_style)); console.sendMessage(Component.text("│ │").style(plugin_style)); @@ -76,6 +80,7 @@ public final class VillagerOptimizer extends JavaPlugin { console.sendMessage(Component.text("│ │").style(plugin_style)); console.sendMessage(Component.text("│ │").style(plugin_style)); console.sendMessage(Component.text("╰────────────────────────────────────────────────────────────╯").style(plugin_style)); + new Metrics(this, 19954); } @@ -91,6 +96,12 @@ public final class VillagerOptimizer extends JavaPlugin { public static VillagerCache getCache() { return villagerCache; } + public static FoliaLib getFoliaLib() { + return foliaLib; + } + public static ServerImplementation getScheduler() { + return foliaLib.getImpl(); + } public static ConsoleCommandSender getConsole() { return console; } diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/WrappedVillager.java b/src/main/java/me/xginko/villageroptimizer/WrappedVillager.java similarity index 96% rename from VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/WrappedVillager.java rename to src/main/java/me/xginko/villageroptimizer/WrappedVillager.java index e45abc5..1a55225 100644 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/WrappedVillager.java +++ b/src/main/java/me/xginko/villageroptimizer/WrappedVillager.java @@ -55,11 +55,13 @@ public final class WrappedVillager { public void setOptimization(OptimizationType type) { if (type.equals(OptimizationType.NONE) && isOptimized()) { dataContainer.remove(Keys.OPTIMIZATION_TYPE.key()); - villager.setAware(true); - villager.setAI(true); + VillagerOptimizer.getScheduler().runAtEntity(villager, enableAI -> { + villager.setAware(true); + villager.setAI(true); + }); } else { dataContainer.set(Keys.OPTIMIZATION_TYPE.key(), PersistentDataType.STRING, type.name()); - villager.setAware(false); + VillagerOptimizer.getScheduler().runAtEntity(villager, disableAI -> villager.setAware(false)); } } diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/SubCommand.java b/src/main/java/me/xginko/villageroptimizer/commands/SubCommand.java similarity index 100% rename from VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/SubCommand.java rename to src/main/java/me/xginko/villageroptimizer/commands/SubCommand.java diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/VillagerOptimizerCommand.java b/src/main/java/me/xginko/villageroptimizer/commands/VillagerOptimizerCommand.java similarity index 100% rename from VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/VillagerOptimizerCommand.java rename to src/main/java/me/xginko/villageroptimizer/commands/VillagerOptimizerCommand.java diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/optimizevillagers/OptVillagersRadius.java b/src/main/java/me/xginko/villageroptimizer/commands/optimizevillagers/OptVillagersRadius.java similarity index 94% rename from VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/optimizevillagers/OptVillagersRadius.java rename to src/main/java/me/xginko/villageroptimizer/commands/optimizevillagers/OptVillagersRadius.java index 26daa8c..a4514f5 100644 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/optimizevillagers/OptVillagersRadius.java +++ b/src/main/java/me/xginko/villageroptimizer/commands/optimizevillagers/OptVillagersRadius.java @@ -5,8 +5,9 @@ import me.xginko.villageroptimizer.VillagerOptimizer; import me.xginko.villageroptimizer.WrappedVillager; import me.xginko.villageroptimizer.commands.VillagerOptimizerCommand; import me.xginko.villageroptimizer.config.Config; +import me.xginko.villageroptimizer.enums.permissions.Bypass; +import me.xginko.villageroptimizer.enums.permissions.Commands; import me.xginko.villageroptimizer.enums.OptimizationType; -import me.xginko.villageroptimizer.enums.Permissions; import me.xginko.villageroptimizer.events.VillagerOptimizeEvent; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextReplacementConfig; @@ -26,7 +27,7 @@ import java.util.List; public class OptVillagersRadius implements VillagerOptimizerCommand, TabCompleter { - private final List tabCompletes = List.of("5", "10", "25", "50"); + private final List radiusSuggestions = List.of("5", "10", "25", "50"); private final long cooldown; private final int max_radius; @@ -45,7 +46,7 @@ public class OptVillagersRadius implements VillagerOptimizerCommand, TabComplete @Override public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - return args.length == 1 ? tabCompletes : null; + return args.length == 1 ? radiusSuggestions : null; } @Override @@ -56,7 +57,7 @@ public class OptVillagersRadius implements VillagerOptimizerCommand, TabComplete return true; } - if (!sender.hasPermission(Permissions.Commands.OPTIMIZE_RADIUS.get())) { + if (!sender.hasPermission(Commands.OPTIMIZE_RADIUS.get())) { sender.sendMessage(VillagerOptimizer.getLang(sender).no_permission); return true; } @@ -81,7 +82,7 @@ public class OptVillagersRadius implements VillagerOptimizerCommand, TabComplete VillagerCache villagerCache = VillagerOptimizer.getCache(); int successCount = 0; int failCount = 0; - final boolean player_has_cooldown_bypass = player.hasPermission(Permissions.Bypass.COMMAND_COOLDOWN.get()); + final boolean player_has_cooldown_bypass = player.hasPermission(Bypass.COMMAND_COOLDOWN.get()); for (Entity entity : player.getNearbyEntities(specifiedRadius, specifiedRadius, specifiedRadius)) { if (!entity.getType().equals(EntityType.VILLAGER)) continue; diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/unoptimizevillagers/UnOptVillagersRadius.java b/src/main/java/me/xginko/villageroptimizer/commands/unoptimizevillagers/UnOptVillagersRadius.java similarity index 94% rename from VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/unoptimizevillagers/UnOptVillagersRadius.java rename to src/main/java/me/xginko/villageroptimizer/commands/unoptimizevillagers/UnOptVillagersRadius.java index 1652735..13a603b 100644 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/unoptimizevillagers/UnOptVillagersRadius.java +++ b/src/main/java/me/xginko/villageroptimizer/commands/unoptimizevillagers/UnOptVillagersRadius.java @@ -4,8 +4,8 @@ import me.xginko.villageroptimizer.VillagerCache; import me.xginko.villageroptimizer.VillagerOptimizer; import me.xginko.villageroptimizer.WrappedVillager; import me.xginko.villageroptimizer.commands.VillagerOptimizerCommand; +import me.xginko.villageroptimizer.enums.permissions.Commands; import me.xginko.villageroptimizer.enums.OptimizationType; -import me.xginko.villageroptimizer.enums.Permissions; import me.xginko.villageroptimizer.events.VillagerUnoptimizeEvent; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextReplacementConfig; @@ -25,7 +25,7 @@ import java.util.List; public class UnOptVillagersRadius implements VillagerOptimizerCommand, TabCompleter { - private final List tabCompletes = List.of("5", "10", "25", "50"); + private final List radiusSuggestions = List.of("5", "10", "25", "50"); private final int max_radius; public UnOptVillagersRadius() { @@ -39,7 +39,7 @@ public class UnOptVillagersRadius implements VillagerOptimizerCommand, TabComple @Override public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - return args.length == 1 ? tabCompletes : null; + return args.length == 1 ? radiusSuggestions : null; } @Override @@ -50,7 +50,7 @@ public class UnOptVillagersRadius implements VillagerOptimizerCommand, TabComple return true; } - if (!sender.hasPermission(Permissions.Commands.UNOPTIMIZE_RADIUS.get())) { + if (!sender.hasPermission(Commands.UNOPTIMIZE_RADIUS.get())) { sender.sendMessage(VillagerOptimizer.getLang(sender).no_permission); return true; } diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/VillagerOptimizerCmd.java b/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/VillagerOptimizerCmd.java similarity index 85% rename from VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/VillagerOptimizerCmd.java rename to src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/VillagerOptimizerCmd.java index 9843b57..4d60844 100644 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/VillagerOptimizerCmd.java +++ b/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/VillagerOptimizerCmd.java @@ -6,7 +6,7 @@ import me.xginko.villageroptimizer.commands.VillagerOptimizerCommand; import me.xginko.villageroptimizer.commands.villageroptimizer.subcommands.DisableSubCmd; import me.xginko.villageroptimizer.commands.villageroptimizer.subcommands.ReloadSubCmd; import me.xginko.villageroptimizer.commands.villageroptimizer.subcommands.VersionSubCmd; -import me.xginko.villageroptimizer.enums.Permissions; +import me.xginko.villageroptimizer.enums.permissions.Commands; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.command.Command; @@ -14,19 +14,16 @@ import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; import java.util.List; public class VillagerOptimizerCmd implements TabCompleter, VillagerOptimizerCommand { - private final List subCommands = new ArrayList<>(3); - private final List tabCompleter = new ArrayList<>(3); + private final List subCommands; + private final List tabCompleter; public VillagerOptimizerCmd() { - subCommands.add(new ReloadSubCmd()); - subCommands.add(new VersionSubCmd()); - subCommands.add(new DisableSubCmd()); - subCommands.forEach(subCommand -> tabCompleter.add(subCommand.getLabel())); + subCommands = List.of(new ReloadSubCmd(), new VersionSubCmd(), new DisableSubCmd()); + tabCompleter = subCommands.stream().map(SubCommand::getLabel).toList(); } @Override @@ -58,7 +55,7 @@ public class VillagerOptimizerCmd implements TabCompleter, VillagerOptimizerComm } private void sendCommandOverview(CommandSender sender) { - if (!sender.hasPermission(Permissions.Commands.RELOAD.get()) && !sender.hasPermission(Permissions.Commands.VERSION.get())) return; + if (!sender.hasPermission(Commands.RELOAD.get()) && !sender.hasPermission(Commands.VERSION.get())) return; sender.sendMessage(Component.text("-----------------------------------------------------").color(NamedTextColor.GRAY)); sender.sendMessage(Component.text("VillagerOptimizer Commands").color(VillagerOptimizer.plugin_style.color())); sender.sendMessage(Component.text("-----------------------------------------------------").color(NamedTextColor.GRAY)); diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/DisableSubCmd.java b/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/DisableSubCmd.java similarity index 92% rename from VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/DisableSubCmd.java rename to src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/DisableSubCmd.java index f9ddd3f..a633757 100644 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/DisableSubCmd.java +++ b/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/DisableSubCmd.java @@ -2,7 +2,7 @@ package me.xginko.villageroptimizer.commands.villageroptimizer.subcommands; import me.xginko.villageroptimizer.VillagerOptimizer; import me.xginko.villageroptimizer.commands.SubCommand; -import me.xginko.villageroptimizer.enums.Permissions; +import me.xginko.villageroptimizer.enums.permissions.Commands; import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; @@ -28,7 +28,7 @@ public class DisableSubCmd extends SubCommand { @Override public void perform(CommandSender sender, String[] args) { - if (sender.hasPermission(Permissions.Commands.DISABLE.get())) { + if (sender.hasPermission(Commands.DISABLE.get())) { sender.sendMessage(Component.text("Disabling VillagerOptimizer...").color(NamedTextColor.RED)); VillagerOptimizerModule.modules.forEach(VillagerOptimizerModule::disable); VillagerOptimizerModule.modules.clear(); diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/ReloadSubCmd.java b/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/ReloadSubCmd.java similarity index 72% rename from VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/ReloadSubCmd.java rename to src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/ReloadSubCmd.java index 700b736..ee9e517 100644 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/ReloadSubCmd.java +++ b/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/ReloadSubCmd.java @@ -2,7 +2,7 @@ package me.xginko.villageroptimizer.commands.villageroptimizer.subcommands; import me.xginko.villageroptimizer.VillagerOptimizer; import me.xginko.villageroptimizer.commands.SubCommand; -import me.xginko.villageroptimizer.enums.Permissions; +import me.xginko.villageroptimizer.enums.permissions.Commands; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.format.NamedTextColor; @@ -27,13 +27,10 @@ public class ReloadSubCmd extends SubCommand { @Override public void perform(CommandSender sender, String[] args) { - if (sender.hasPermission(Permissions.Commands.RELOAD.get())) { + if (sender.hasPermission(Commands.RELOAD.get())) { sender.sendMessage(Component.text("Reloading VillagerOptimizer...").color(NamedTextColor.WHITE)); - VillagerOptimizer plugin = VillagerOptimizer.getInstance(); - plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> { - plugin.reloadPlugin(); - sender.sendMessage(Component.text("Reload complete.").color(NamedTextColor.GREEN)); - }); + VillagerOptimizer.getInstance().reloadPlugin(); + sender.sendMessage(Component.text("Reload complete.").color(NamedTextColor.GREEN)); } else { sender.sendMessage(VillagerOptimizer.getLang(sender).no_permission); } diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/VersionSubCmd.java b/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/VersionSubCmd.java similarity index 80% rename from VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/VersionSubCmd.java rename to src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/VersionSubCmd.java index 6e1a910..003f072 100644 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/VersionSubCmd.java +++ b/src/main/java/me/xginko/villageroptimizer/commands/villageroptimizer/subcommands/VersionSubCmd.java @@ -2,7 +2,7 @@ package me.xginko.villageroptimizer.commands.villageroptimizer.subcommands; import me.xginko.villageroptimizer.VillagerOptimizer; import me.xginko.villageroptimizer.commands.SubCommand; -import me.xginko.villageroptimizer.enums.Permissions; +import me.xginko.villageroptimizer.enums.permissions.Commands; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.event.ClickEvent; @@ -29,18 +29,18 @@ public class VersionSubCmd extends SubCommand { @Override public void perform(CommandSender sender, String[] args) { - if (sender.hasPermission(Permissions.Commands.VERSION.get())) { - final PluginDescriptionFile pluginMeta = VillagerOptimizer.getInstance().getDescription(); + if (sender.hasPermission(Commands.VERSION.get())) { + final PluginDescriptionFile pluginYML = VillagerOptimizer.getInstance().getDescription(); sender.sendMessage( Component.newline() .append( - Component.text(pluginMeta.getName()+" "+pluginMeta.getVersion()) + Component.text(pluginYML.getName()+" "+pluginYML.getVersion()) .style(VillagerOptimizer.plugin_style) - .clickEvent(ClickEvent.openUrl(pluginMeta.getWebsite())) + .clickEvent(ClickEvent.openUrl(pluginYML.getWebsite())) ) .append(Component.text(" by ").color(NamedTextColor.GRAY)) .append( - Component.text(pluginMeta.getAuthors().get(0)) + Component.text(pluginYML.getAuthors().get(0)) .color(NamedTextColor.WHITE) .clickEvent(ClickEvent.openUrl("https://github.com/xGinko")) ) diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/config/Config.java b/src/main/java/me/xginko/villageroptimizer/config/Config.java similarity index 85% rename from VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/config/Config.java rename to src/main/java/me/xginko/villageroptimizer/config/Config.java index 1c9584c..68ded85 100644 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/config/Config.java +++ b/src/main/java/me/xginko/villageroptimizer/config/Config.java @@ -73,7 +73,7 @@ public class Config { } public @NotNull ConfigFile master() { - return config; + return this.config; } public boolean getBoolean(@NotNull String path, boolean def, @NotNull String comment) { @@ -125,22 +125,4 @@ public class Config { this.config.addDefault(path, def); return this.config.getStringList(path); } - - public @NotNull ConfigSection getConfigSection(@NotNull String path, @NotNull Map defaultKeyValue) { - this.config.addDefault(path, null); - this.config.makeSectionLenient(path); - defaultKeyValue.forEach((string, object) -> this.config.addExample(path+"."+string, object)); - return this.config.getConfigSection(path); - } - - public @NotNull ConfigSection getConfigSection(@NotNull String path, @NotNull Map defaultKeyValue, @NotNull String comment) { - this.config.addDefault(path, null, comment); - this.config.makeSectionLenient(path); - defaultKeyValue.forEach((string, object) -> this.config.addExample(path+"."+string, object)); - return this.config.getConfigSection(path); - } - - public void addComment(@NotNull String path, @NotNull String comment) { - this.config.addComment(path, comment); - } } diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/config/LanguageCache.java b/src/main/java/me/xginko/villageroptimizer/config/LanguageCache.java similarity index 100% rename from VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/config/LanguageCache.java rename to src/main/java/me/xginko/villageroptimizer/config/LanguageCache.java diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/enums/Keys.java b/src/main/java/me/xginko/villageroptimizer/enums/Keys.java similarity index 99% rename from VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/enums/Keys.java rename to src/main/java/me/xginko/villageroptimizer/enums/Keys.java index 4c75d96..85b05e6 100644 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/enums/Keys.java +++ b/src/main/java/me/xginko/villageroptimizer/enums/Keys.java @@ -4,7 +4,6 @@ import me.xginko.villageroptimizer.VillagerOptimizer; import org.bukkit.NamespacedKey; public enum Keys { - OPTIMIZATION_TYPE(VillagerOptimizer.getKey("optimization-type")), LAST_OPTIMIZE(VillagerOptimizer.getKey("last-optimize")), LAST_LEVELUP(VillagerOptimizer.getKey("last-levelup")), @@ -12,13 +11,10 @@ public enum Keys { LAST_OPTIMIZE_NAME(VillagerOptimizer.getKey("last-optimize-name")); private final NamespacedKey key; - Keys(NamespacedKey key) { this.key = key; } - public NamespacedKey key() { return key; } - } diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/enums/OptimizationType.java b/src/main/java/me/xginko/villageroptimizer/enums/OptimizationType.java similarity index 98% rename from VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/enums/OptimizationType.java rename to src/main/java/me/xginko/villageroptimizer/enums/OptimizationType.java index 09c304b..23025bf 100644 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/enums/OptimizationType.java +++ b/src/main/java/me/xginko/villageroptimizer/enums/OptimizationType.java @@ -1,11 +1,9 @@ package me.xginko.villageroptimizer.enums; public enum OptimizationType { - COMMAND, NAMETAG, WORKSTATION, BLOCK, NONE - } diff --git a/src/main/java/me/xginko/villageroptimizer/enums/permissions/Bypass.java b/src/main/java/me/xginko/villageroptimizer/enums/permissions/Bypass.java new file mode 100644 index 0000000..1913891 --- /dev/null +++ b/src/main/java/me/xginko/villageroptimizer/enums/permissions/Bypass.java @@ -0,0 +1,28 @@ +package me.xginko.villageroptimizer.enums.permissions; + +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionDefault; + +public enum Bypass { + TRADE_PREVENTION(new Permission("villageroptimizer.bypass.tradeprevention", + "Permission to bypass unoptimized trade prevention", PermissionDefault.FALSE)), + RESTOCK_COOLDOWN(new Permission("villageroptimizer.bypass.restockcooldown", + "Permission to bypass restock cooldown on optimized villagers", PermissionDefault.FALSE)), + NAMETAG_COOLDOWN(new Permission("villageroptimizer.bypass.nametagcooldown", + "Permission to bypass Nametag optimization cooldown", PermissionDefault.FALSE)), + BLOCK_COOLDOWN(new Permission("villageroptimizer.bypass.blockcooldown", + "Permission to bypass Block optimization cooldown", PermissionDefault.FALSE)), + WORKSTATION_COOLDOWN(new Permission("villageroptimizer.bypass.workstationcooldown", + "Permission to bypass Workstation optimization cooldown", PermissionDefault.FALSE)), + COMMAND_COOLDOWN(new Permission("villageroptimizer.bypass.commandcooldown", + "Permission to bypass command optimization cooldown", PermissionDefault.FALSE)); + + private final Permission permission; + Bypass(Permission permission) { + this.permission = permission; + } + + public Permission get() { + return permission; + } +} diff --git a/src/main/java/me/xginko/villageroptimizer/enums/permissions/Commands.java b/src/main/java/me/xginko/villageroptimizer/enums/permissions/Commands.java new file mode 100644 index 0000000..6c7acf9 --- /dev/null +++ b/src/main/java/me/xginko/villageroptimizer/enums/permissions/Commands.java @@ -0,0 +1,26 @@ +package me.xginko.villageroptimizer.enums.permissions; + +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionDefault; + +public enum Commands { + VERSION(new Permission("villageroptimizer.cmd.version", + "Permission get the plugin version", PermissionDefault.FALSE)), + RELOAD(new Permission("villageroptimizer.cmd.reload", + "Permission to reload the plugin config", PermissionDefault.FALSE)), + DISABLE(new Permission("villageroptimizer.cmd.disable", + "Permission to disable the plugin", PermissionDefault.FALSE)), + OPTIMIZE_RADIUS(new Permission("villageroptimizer.cmd.optimize", + "Permission to optimize villagers in a radius", PermissionDefault.TRUE)), + UNOPTIMIZE_RADIUS(new Permission("villageroptimizer.cmd.unoptimize", + "Permission to unoptimize villagers in a radius", PermissionDefault.TRUE)); + + private final Permission permission; + Commands(Permission permission) { + this.permission = permission; + } + + public Permission get() { + return permission; + } +} diff --git a/src/main/java/me/xginko/villageroptimizer/enums/permissions/Optimize.java b/src/main/java/me/xginko/villageroptimizer/enums/permissions/Optimize.java new file mode 100644 index 0000000..9962cc1 --- /dev/null +++ b/src/main/java/me/xginko/villageroptimizer/enums/permissions/Optimize.java @@ -0,0 +1,22 @@ +package me.xginko.villageroptimizer.enums.permissions; + +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionDefault; + +public enum Optimize { + NAMETAG(new Permission("villageroptimizer.optimize.nametag", + "Permission to optimize / unoptimize using Nametags", PermissionDefault.TRUE)), + BLOCK(new Permission("villageroptimizer.optimize.block", + "Permission to optimize / unoptimize using Blocks", PermissionDefault.TRUE)), + WORKSTATION(new Permission("villageroptimizer.optimize.workstation", + "Permission to optimize / unoptimize using Workstations", PermissionDefault.TRUE)); + + private final Permission permission; + Optimize(Permission permission) { + this.permission = permission; + } + + public Permission get() { + return permission; + } +} diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/events/VillagerOptimizeEvent.java b/src/main/java/me/xginko/villageroptimizer/events/VillagerOptimizeEvent.java similarity index 70% rename from VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/events/VillagerOptimizeEvent.java rename to src/main/java/me/xginko/villageroptimizer/events/VillagerOptimizeEvent.java index 2123dc5..de6ce7b 100644 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/events/VillagerOptimizeEvent.java +++ b/src/main/java/me/xginko/villageroptimizer/events/VillagerOptimizeEvent.java @@ -13,28 +13,28 @@ public class VillagerOptimizeEvent extends Event implements Cancellable { private static final @NotNull HandlerList handlers = new HandlerList(); private final @NotNull WrappedVillager wrappedVillager; - private @NotNull OptimizationType type; + private @NotNull OptimizationType optimizationType; private final @Nullable Player whoOptimised; private boolean isCancelled = false; - public VillagerOptimizeEvent(@NotNull WrappedVillager wrappedVillager, @NotNull OptimizationType type, @Nullable Player whoOptimised, boolean isAsync) throws IllegalArgumentException { + public VillagerOptimizeEvent(@NotNull WrappedVillager wrappedVillager, @NotNull OptimizationType optimizationType, @Nullable Player whoOptimised, boolean isAsync) throws IllegalArgumentException { super(isAsync); this.wrappedVillager = wrappedVillager; this.whoOptimised = whoOptimised; - if (type.equals(OptimizationType.NONE)) { + if (optimizationType.equals(OptimizationType.NONE)) { throw new IllegalArgumentException("OptimizationType can't be NONE."); } else { - this.type = type; + this.optimizationType = optimizationType; } } - public VillagerOptimizeEvent(@NotNull WrappedVillager wrappedVillager, @NotNull OptimizationType type, @Nullable Player whoOptimised) throws IllegalArgumentException { + public VillagerOptimizeEvent(@NotNull WrappedVillager wrappedVillager, @NotNull OptimizationType optimizationType, @Nullable Player whoOptimised) throws IllegalArgumentException { this.wrappedVillager = wrappedVillager; this.whoOptimised = whoOptimised; - if (type.equals(OptimizationType.NONE)) { + if (optimizationType.equals(OptimizationType.NONE)) { throw new IllegalArgumentException("OptimizationType can't be NONE."); } else { - this.type = type; + this.optimizationType = optimizationType; } } @@ -43,14 +43,14 @@ public class VillagerOptimizeEvent extends Event implements Cancellable { } public @NotNull OptimizationType getOptimizationType() { - return type; + return optimizationType; } - public void setOptimizationType(@NotNull OptimizationType type) throws IllegalArgumentException { - if (type.equals(OptimizationType.NONE)) { + public void setOptimizationType(@NotNull OptimizationType optimizationType) throws IllegalArgumentException { + if (optimizationType.equals(OptimizationType.NONE)) { throw new IllegalArgumentException("OptimizationType can't be NONE."); } else { - this.type = type; + this.optimizationType = optimizationType; } } diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/events/VillagerUnoptimizeEvent.java b/src/main/java/me/xginko/villageroptimizer/events/VillagerUnoptimizeEvent.java similarity index 87% rename from VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/events/VillagerUnoptimizeEvent.java rename to src/main/java/me/xginko/villageroptimizer/events/VillagerUnoptimizeEvent.java index c84cd17..4d53c52 100644 --- a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/events/VillagerUnoptimizeEvent.java +++ b/src/main/java/me/xginko/villageroptimizer/events/VillagerUnoptimizeEvent.java @@ -13,21 +13,21 @@ public class VillagerUnoptimizeEvent extends Event implements Cancellable { private static final @NotNull HandlerList handlers = new HandlerList(); private final @NotNull WrappedVillager wrappedVillager; - private final @NotNull OptimizationType unoptimizeType; + private final @NotNull OptimizationType unOptimizeType; private final @Nullable Player whoUnoptimized; private boolean isCancelled = false; - public VillagerUnoptimizeEvent(@NotNull WrappedVillager wrappedVillager, @Nullable Player whoUnoptimized, @NotNull OptimizationType unoptimizeType, boolean isAsync) { + public VillagerUnoptimizeEvent(@NotNull WrappedVillager wrappedVillager, @Nullable Player whoUnoptimized, @NotNull OptimizationType unOptimizeType, boolean isAsync) { super(isAsync); this.wrappedVillager = wrappedVillager; this.whoUnoptimized = whoUnoptimized; - this.unoptimizeType = unoptimizeType; + this.unOptimizeType = unOptimizeType; } - public VillagerUnoptimizeEvent(@NotNull WrappedVillager wrappedVillager, @Nullable Player whoUnoptimized, @NotNull OptimizationType unoptimizeType) { + public VillagerUnoptimizeEvent(@NotNull WrappedVillager wrappedVillager, @Nullable Player whoUnoptimized, @NotNull OptimizationType unOptimizeType) { this.wrappedVillager = wrappedVillager; this.whoUnoptimized = whoUnoptimized; - this.unoptimizeType = unoptimizeType; + this.unOptimizeType = unOptimizeType; } public @NotNull WrappedVillager getWrappedVillager() { @@ -39,7 +39,7 @@ public class VillagerUnoptimizeEvent extends Event implements Cancellable { } public @NotNull OptimizationType getWhichTypeUnoptimized() { - return unoptimizeType; + return unOptimizeType; } @Override diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/VillagerChunkLimit.java b/src/main/java/me/xginko/villageroptimizer/modules/VillagerChunkLimit.java similarity index 82% rename from VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/VillagerChunkLimit.java rename to src/main/java/me/xginko/villageroptimizer/modules/VillagerChunkLimit.java index 1c151f0..a504cdb 100644 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/VillagerChunkLimit.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/VillagerChunkLimit.java @@ -1,9 +1,11 @@ package me.xginko.villageroptimizer.modules; -import io.papermc.paper.threadedregions.scheduler.ScheduledTask; +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.CommonUtil; import me.xginko.villageroptimizer.utils.LogUtil; import org.bukkit.Chunk; import org.bukkit.Server; @@ -26,8 +28,9 @@ import java.util.logging.Level; public class VillagerChunkLimit implements VillagerOptimizerModule, Listener { + private final ServerImplementation scheduler; private final VillagerCache villagerCache; - private ScheduledTask periodic_chunk_check; + private WrappedTask periodic_chunk_check; private final List non_optimized_removal_priority = new ArrayList<>(16); private final List optimized_removal_priority = new ArrayList<>(16); private final long check_period; @@ -36,9 +39,10 @@ public class VillagerChunkLimit implements VillagerOptimizerModule, Listener { protected VillagerChunkLimit() { shouldEnable(); + this.scheduler = VillagerOptimizer.getScheduler(); this.villagerCache = VillagerOptimizer.getCache(); Config config = VillagerOptimizer.getConfiguration(); - config.addComment("villager-chunk-limit.enable", """ + config.master().addComment("villager-chunk-limit.enable", """ Checks chunks for too many villagers and removes excess villagers based on priority."""); this.check_period = config.getInt("villager-chunk-limit.check-period-in-ticks", 600, """ Check all loaded chunks every X ticks. 1 second = 20 ticks\s @@ -87,12 +91,12 @@ public class VillagerChunkLimit implements VillagerOptimizerModule, Listener { final VillagerOptimizer plugin = VillagerOptimizer.getInstance(); final Server server = plugin.getServer(); server.getPluginManager().registerEvents(this, plugin); - this.periodic_chunk_check = server.getGlobalRegionScheduler().runAtFixedRate(plugin, periodic_chunk_check -> { + + this.periodic_chunk_check = scheduler.runTimer(() -> { for (World world : server.getWorlds()) { for (Chunk chunk : world.getLoadedChunks()) { - plugin.getServer().getRegionScheduler().run( - plugin, world, chunk.getX(), chunk.getZ(), check_chunk -> this.manageVillagerCount(chunk) - ); + if (skip_unloaded_entity_chunks && !CommonUtil.isEntitiesLoaded(chunk)) continue; + this.manageVillagerCount(chunk); } } }, check_period, check_period); @@ -111,23 +115,19 @@ public class VillagerChunkLimit implements VillagerOptimizerModule, Listener { @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) private void onCreatureSpawn(CreatureSpawnEvent event) { - Entity spawned = event.getEntity(); - if (spawned.getType().equals(EntityType.VILLAGER)) { - this.manageVillagerCount(spawned.getChunk()); + if (event.getEntityType() == EntityType.VILLAGER) { + this.manageVillagerCount(event.getEntity().getChunk()); } } - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) private void onInteract(PlayerInteractEntityEvent event) { - Entity clicked = event.getRightClicked(); - if (clicked.getType().equals(EntityType.VILLAGER)) { - this.manageVillagerCount(clicked.getChunk()); + if (event.getRightClicked().getType() == EntityType.VILLAGER) { + this.manageVillagerCount(event.getRightClicked().getChunk()); } } private void manageVillagerCount(@NotNull Chunk chunk) { - if (skip_unloaded_entity_chunks && !chunk.isEntitiesLoaded()) return; - // Collect all optimized and unoptimized villagers in that chunk List optimized_villagers = new ArrayList<>(); List not_optimized_villagers = new ArrayList<>(); @@ -154,10 +154,12 @@ public class VillagerChunkLimit implements VillagerOptimizerModule, Listener { // Remove prioritized villagers that are too many for (int i = 0; i < not_optimized_villagers_too_many; i++) { Villager villager = not_optimized_villagers.get(i); - villager.remove(); - if (log_enabled) LogUtil.moduleLog(Level.INFO, "villager-chunk-limit", - "Removed unoptimized villager of profession type '"+villager.getProfession().name()+"' at "+villager.getLocation() - ); + scheduler.runAtEntity(villager, kill -> { + villager.remove(); + if (log_enabled) LogUtil.moduleLog(Level.INFO, "villager-chunk-limit", + "Removed unoptimized villager of profession type '" + villager.getProfession().name() + + "' at " + villager.getLocation()); + }); } } @@ -172,10 +174,12 @@ public class VillagerChunkLimit implements VillagerOptimizerModule, Listener { // Remove prioritized villagers that are too many for (int i = 0; i < optimized_villagers_too_many; i++) { Villager villager = optimized_villagers.get(i); - villager.remove(); - if (log_enabled) LogUtil.moduleLog(Level.INFO, "villager-chunk-limit", - "Removed optimized villager of profession type '"+villager.getProfession().name()+"' at "+villager.getLocation() - ); + scheduler.runAtEntity(villager, kill -> { + villager.remove(); + if (log_enabled) LogUtil.moduleLog(Level.INFO, "villager-chunk-limit", + "Removed optimized villager of profession type '" + villager.getProfession().name() + + "' at " + villager.getLocation()); + }); } } } diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/VillagerOptimizerModule.java b/src/main/java/me/xginko/villageroptimizer/modules/VillagerOptimizerModule.java similarity index 96% rename from VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/VillagerOptimizerModule.java rename to src/main/java/me/xginko/villageroptimizer/modules/VillagerOptimizerModule.java index 05f6088..3e6689d 100644 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/VillagerOptimizerModule.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/VillagerOptimizerModule.java @@ -1,5 +1,6 @@ package me.xginko.villageroptimizer.modules; +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; diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/LevelOptimizedProfession.java b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/LevelOptimizedProfession.java similarity index 82% rename from VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/LevelOptimizedProfession.java rename to src/main/java/me/xginko/villageroptimizer/modules/gameplay/LevelOptimizedProfession.java index ef1b7af..7c1e607 100644 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/LevelOptimizedProfession.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/LevelOptimizedProfession.java @@ -18,24 +18,25 @@ import org.bukkit.event.inventory.InventoryType; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; +import java.util.concurrent.TimeUnit; + public class LevelOptimizedProfession implements VillagerOptimizerModule, Listener { - private final VillagerOptimizer plugin; private final VillagerCache villagerCache; private final boolean notify_player; - private final long cooldown; + private final long cooldown_millis; public LevelOptimizedProfession() { shouldEnable(); - this.plugin = VillagerOptimizer.getInstance(); this.villagerCache = VillagerOptimizer.getCache(); Config config = VillagerOptimizer.getConfiguration(); - config.addComment("gameplay.level-optimized-profession", """ + config.master().addComment("gameplay.level-optimized-profession", """ This is needed to allow optimized villagers to level up.\s Temporarily enables the villagers AI to allow it to level up and then disables it again."""); - this.cooldown = config.getInt("gameplay.level-optimized-profession.level-check-cooldown-seconds", 5, """ + this.cooldown_millis = TimeUnit.SECONDS.toMillis( + config.getInt("gameplay.level-optimized-profession.level-check-cooldown-seconds", 5, """ Cooldown in seconds until the level of a villager will be checked and updated again.\s - Recommended to leave as is.""") * 1000L; + Recommended to leave as is.""")); this.notify_player = config.getBoolean("gameplay.level-optimized-profession.notify-player", true, "Tell players to wait when a villager is leveling up."); } @@ -65,23 +66,23 @@ public class LevelOptimizedProfession implements VillagerOptimizerModule, Listen WrappedVillager wVillager = villagerCache.getOrAdd(villager); if (!wVillager.isOptimized()) return; - if (wVillager.canLevelUp(cooldown)) { + if (wVillager.canLevelUp(cooldown_millis)) { if (wVillager.calculateLevel() > villager.getVillagerLevel()) { - villager.getScheduler().run(plugin, enableAI -> { + VillagerOptimizer.getScheduler().runAtEntity(villager, enableAI -> { villager.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 120, 120, false, false)); villager.setAware(true); - }, null); - villager.getScheduler().runDelayed(plugin, disableAI -> { + }); + VillagerOptimizer.getScheduler().runAtEntityLater(villager, disableAI -> { villager.setAware(false); wVillager.saveLastLevelUp(); - }, null, 100L); + }, 5, TimeUnit.SECONDS); } } else { if (notify_player) { Player player = (Player) event.getPlayer(); final TextReplacementConfig timeLeft = TextReplacementConfig.builder() .matchLiteral("%time%") - .replacement(CommonUtil.formatTime(wVillager.getLevelCooldownMillis(cooldown))) + .replacement(CommonUtil.formatTime(wVillager.getLevelCooldownMillis(cooldown_millis))) .build(); VillagerOptimizer.getLang(player.locale()).villager_leveling_up.forEach(line -> player.sendMessage(line.replaceText(timeLeft))); } diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/MakeVillagersSpawnAdult.java b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/MakeVillagersSpawnAdult.java similarity index 96% rename from VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/MakeVillagersSpawnAdult.java rename to src/main/java/me/xginko/villageroptimizer/modules/gameplay/MakeVillagersSpawnAdult.java index 94b5d25..f3918a4 100644 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/MakeVillagersSpawnAdult.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/MakeVillagersSpawnAdult.java @@ -36,7 +36,7 @@ public class MakeVillagersSpawnAdult implements VillagerOptimizerModule, Listene @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) private void onVillagerSpawn(CreatureSpawnEvent event) { - if (event.getEntityType().equals(EntityType.VILLAGER)) { + if (event.getEntityType() == EntityType.VILLAGER) { Villager villager = (Villager) event.getEntity(); if (!villager.isAdult()) villager.setAdult(); } diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedDamage.java b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedDamage.java similarity index 83% rename from VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedDamage.java rename to src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedDamage.java index a11949b..3d3c9ca 100644 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedDamage.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedDamage.java @@ -1,6 +1,6 @@ package me.xginko.villageroptimizer.modules.gameplay; -import io.papermc.paper.event.entity.EntityPushedByEntityAttackEvent; +import com.destroystokyo.paper.event.entity.EntityKnockbackByEntityEvent; import me.xginko.villageroptimizer.VillagerCache; import me.xginko.villageroptimizer.VillagerOptimizer; import me.xginko.villageroptimizer.config.Config; @@ -16,21 +16,22 @@ import org.bukkit.event.entity.EntityDamageEvent; import java.util.Arrays; import java.util.HashSet; +import java.util.Set; public class PreventOptimizedDamage implements VillagerOptimizerModule, Listener { private final VillagerCache villagerCache; - private final HashSet damage_causes_to_cancel = new HashSet<>(); - private final boolean push; + private final Set damage_causes_to_cancel = new HashSet<>(); + private final boolean cancelKnockback; public PreventOptimizedDamage() { shouldEnable(); this.villagerCache = VillagerOptimizer.getCache(); Config config = VillagerOptimizer.getConfiguration(); - config.addComment("gameplay.prevent-damage-to-optimized.enable", + config.master().addComment("gameplay.prevent-damage-to-optimized.enable", "Configure what kind of damage you want to cancel for optimized villagers here."); - this.push = config.getBoolean("gameplay.prevent-damage-to-optimized.prevent-push-from-attack", true, - "Prevents optimized villagers from getting pushed by an attacking entity"); + this.cancelKnockback = config.getBoolean("gameplay.prevent-damage-to-optimized.prevent-knockback-from-entity", true, + "Prevents optimized villagers from getting knocked back by an attacking entity"); config.getList("gameplay.prevent-damage-to-optimized.damage-causes-to-cancel", Arrays.stream(EntityDamageEvent.DamageCause.values()).map(Enum::name).sorted().toList(), """ These are all current entries in the game. Remove what you do not need blocked.\s @@ -74,9 +75,9 @@ public class PreventOptimizedDamage implements VillagerOptimizerModule, Listener } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - private void onPushByEntityAttack(EntityPushedByEntityAttackEvent event) { + private void onKnockbackByEntity(EntityKnockbackByEntityEvent event) { if ( - push + cancelKnockback && event.getEntityType().equals(EntityType.VILLAGER) && villagerCache.getOrAdd((Villager) event.getEntity()).isOptimized() ) { diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedTargeting.java b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedTargeting.java similarity index 93% rename from VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedTargeting.java rename to src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedTargeting.java index 1bd2387..6c10e2e 100644 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedTargeting.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventOptimizedTargeting.java @@ -46,7 +46,7 @@ public class PreventOptimizedTargeting implements VillagerOptimizerModule, Liste Entity target = event.getTarget(); if ( target != null - && target.getType().equals(EntityType.VILLAGER) + && target.getType() == EntityType.VILLAGER && villagerCache.getOrAdd((Villager) target).isOptimized() ) { event.setTarget(null); @@ -59,7 +59,7 @@ public class PreventOptimizedTargeting implements VillagerOptimizerModule, Liste Entity target = event.getTargetEntity(); if ( target != null - && target.getType().equals(EntityType.VILLAGER) + && target.getType() == EntityType.VILLAGER && villagerCache.getOrAdd((Villager) target).isOptimized() ) { event.setCancelled(true); @@ -69,7 +69,7 @@ public class PreventOptimizedTargeting implements VillagerOptimizerModule, Liste @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) private void onEntityAttackVillager(EntityDamageByEntityEvent event) { if ( - event.getEntityType().equals(EntityType.VILLAGER) + event.getEntityType() == EntityType.VILLAGER && event.getDamager() instanceof Mob attacker && villagerCache.getOrAdd((Villager) event.getEntity()).isOptimized() ) { diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventUnoptimizedTrading.java b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventUnoptimizedTrading.java similarity index 91% rename from VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventUnoptimizedTrading.java rename to src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventUnoptimizedTrading.java index 453ca4c..ec20b79 100644 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventUnoptimizedTrading.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/PreventUnoptimizedTrading.java @@ -3,7 +3,7 @@ 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.enums.permissions.Bypass; import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; import org.bukkit.entity.Player; import org.bukkit.entity.Villager; @@ -24,7 +24,7 @@ public class PreventUnoptimizedTrading implements VillagerOptimizerModule, Liste shouldEnable(); this.villagerCache = VillagerOptimizer.getCache(); Config config = VillagerOptimizer.getConfiguration(); - config.addComment("gameplay.prevent-trading-with-unoptimized.enable", """ + config.master().addComment("gameplay.prevent-trading-with-unoptimized.enable", """ Will prevent players from selecting and using trades of unoptimized villagers.\s Use this if you have a lot of villagers and therefore want to force your players to optimize them.\s Inventories can still be opened so players can move villagers around."""); @@ -51,7 +51,7 @@ public class PreventUnoptimizedTrading implements VillagerOptimizerModule, Liste @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) private void onTradeOpen(TradeSelectEvent event) { Player player = (Player) event.getWhoClicked(); - if (player.hasPermission(Permissions.Bypass.TRADE_PREVENTION.get())) return; + if (player.hasPermission(Bypass.TRADE_PREVENTION.get())) return; if ( event.getInventory().getType().equals(InventoryType.MERCHANT) && event.getInventory().getHolder() instanceof Villager villager @@ -66,7 +66,7 @@ public class PreventUnoptimizedTrading implements VillagerOptimizerModule, Liste @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) private void onInventoryClick(InventoryClickEvent event) { Player player = (Player) event.getWhoClicked(); - if (player.hasPermission(Permissions.Bypass.TRADE_PREVENTION.get())) return; + if (player.hasPermission(Bypass.TRADE_PREVENTION.get())) return; if ( event.getInventory().getType().equals(InventoryType.MERCHANT) && event.getInventory().getHolder() instanceof Villager villager diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RenameOptimizedVillagers.java b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RenameOptimizedVillagers.java similarity index 83% rename from VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RenameOptimizedVillagers.java rename to src/main/java/me/xginko/villageroptimizer/modules/gameplay/RenameOptimizedVillagers.java index 5d63611..38ee278 100644 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RenameOptimizedVillagers.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RenameOptimizedVillagers.java @@ -1,5 +1,6 @@ package me.xginko.villageroptimizer.modules.gameplay; +import com.tcoded.folialib.impl.ServerImplementation; import me.xginko.villageroptimizer.VillagerOptimizer; import me.xginko.villageroptimizer.WrappedVillager; import me.xginko.villageroptimizer.config.Config; @@ -16,18 +17,17 @@ import org.bukkit.event.Listener; public class RenameOptimizedVillagers implements VillagerOptimizerModule, Listener { - private final VillagerOptimizer plugin; + private final ServerImplementation scheduler; private final Component optimized_name; private final boolean overwrite_previous_name; public RenameOptimizedVillagers() { shouldEnable(); - this.plugin = VillagerOptimizer.getInstance(); + this.scheduler = VillagerOptimizer.getScheduler(); Config config = VillagerOptimizer.getConfiguration(); - config.addComment("gameplay.rename-optimized-villagers.enable", """ + config.master().addComment("gameplay.rename-optimized-villagers.enable", """ Will change a villager's name to the name configured below when they are optimized.\s - These names will be removed when unoptimized again if they were not changed in the meantime. - """); + These names will be removed when unoptimized again if they were not changed in the meantime."""); this.optimized_name = MiniMessage.miniMessage().deserialize(config.getString("gameplay.rename-optimized-villagers.optimized-name", "Optimized", "The name that will be used to mark optimized villagers. Uses MiniMessage format.")); this.overwrite_previous_name = config.getBoolean("gameplay.rename-optimized-villagers.overwrite-existing-name", false, @@ -36,6 +36,7 @@ public class RenameOptimizedVillagers implements VillagerOptimizerModule, Listen @Override public void enable() { + VillagerOptimizer plugin = VillagerOptimizer.getInstance(); plugin.getServer().getPluginManager().registerEvents(this, plugin); } @@ -54,12 +55,12 @@ public class RenameOptimizedVillagers implements VillagerOptimizerModule, Listen WrappedVillager wVillager = event.getWrappedVillager(); Villager villager = wVillager.villager(); - villager.getScheduler().runDelayed(plugin, nameOptimized -> { - if (overwrite_previous_name || villager.customName() == null) { + if (overwrite_previous_name || villager.customName() == null) { + scheduler.runAtEntityLater(villager, () -> { villager.customName(optimized_name); wVillager.memorizeName(optimized_name); - } - }, null, 10L); + }, 10L); + } } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @@ -67,13 +68,13 @@ public class RenameOptimizedVillagers implements VillagerOptimizerModule, Listen WrappedVillager wVillager = event.getWrappedVillager(); Villager villager = wVillager.villager(); - villager.getScheduler().runDelayed(plugin, unNameOptimized -> { + scheduler.runAtEntityLater(villager, () -> { final Component currentName = villager.customName(); final Component memorizedName = wVillager.getMemorizedName(); if (currentName != null && currentName.equals(memorizedName)) villager.customName(null); if (memorizedName != null) wVillager.forgetName(); - }, null, 10L); + }, 10L); } } \ No newline at end of file diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RestockOptimizedTrades.java b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RestockOptimizedTrades.java similarity index 93% rename from VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RestockOptimizedTrades.java rename to src/main/java/me/xginko/villageroptimizer/modules/gameplay/RestockOptimizedTrades.java index 3210b86..0d437d5 100644 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RestockOptimizedTrades.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/gameplay/RestockOptimizedTrades.java @@ -3,7 +3,7 @@ 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.enums.permissions.Bypass; import me.xginko.villageroptimizer.WrappedVillager; import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; import me.xginko.villageroptimizer.utils.CommonUtil; @@ -27,7 +27,7 @@ public class RestockOptimizedTrades implements VillagerOptimizerModule, Listener shouldEnable(); this.villagerCache = VillagerOptimizer.getCache(); Config config = VillagerOptimizer.getConfiguration(); - config.addComment("gameplay.restock-optimized-trades", """ + config.master().addComment("gameplay.restock-optimized-trades", """ This is for automatic restocking of trades for optimized villagers. Optimized Villagers\s don't have enough AI to restock their trades naturally, so this is here as a workaround."""); this.restock_delay_millis = config.getInt("gameplay.restock-optimized-trades.delay-in-ticks", 1000, @@ -61,7 +61,7 @@ public class RestockOptimizedTrades implements VillagerOptimizerModule, Listener if (!wVillager.isOptimized()) return; Player player = event.getPlayer(); - final boolean player_bypassing = player.hasPermission(Permissions.Bypass.RESTOCK_COOLDOWN.get()); + final boolean player_bypassing = player.hasPermission(Bypass.RESTOCK_COOLDOWN.get()); if (wVillager.canRestock(restock_delay_millis) || player_bypassing) { wVillager.restock(); diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByBlock.java b/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByBlock.java similarity index 89% rename from VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByBlock.java rename to src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByBlock.java index 1ea4b0a..31bda6b 100644 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByBlock.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByBlock.java @@ -4,8 +4,9 @@ import me.xginko.villageroptimizer.VillagerCache; import me.xginko.villageroptimizer.VillagerOptimizer; import me.xginko.villageroptimizer.WrappedVillager; import me.xginko.villageroptimizer.config.Config; +import me.xginko.villageroptimizer.enums.permissions.Bypass; import me.xginko.villageroptimizer.enums.OptimizationType; -import me.xginko.villageroptimizer.enums.Permissions; +import me.xginko.villageroptimizer.enums.permissions.Optimize; import me.xginko.villageroptimizer.events.VillagerOptimizeEvent; import me.xginko.villageroptimizer.events.VillagerUnoptimizeEvent; import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; @@ -28,12 +29,14 @@ import org.bukkit.event.block.BlockPlaceEvent; import java.util.HashSet; import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; public class OptimizeByBlock implements VillagerOptimizerModule, Listener { private final VillagerCache villagerCache; - private final HashSet blocks_that_disable = new HashSet<>(4); - private final long cooldown; + private final Set blocks_that_disable = new HashSet<>(); + private final long cooldown_millis; private final double search_radius; private final boolean only_while_sneaking, notify_player, log_enabled; @@ -41,7 +44,7 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener { shouldEnable(); this.villagerCache = VillagerOptimizer.getCache(); Config config = VillagerOptimizer.getConfiguration(); - config.addComment("optimization-methods.block-optimization.enable", """ + config.master().addComment("optimization-methods.block-optimization.enable", """ When enabled, the closest villager standing near a configured block being placed will be optimized.\s If a configured block is broken nearby, the closest villager will become unoptimized again."""); config.getList("optimization-methods.block-optimization.materials", List.of( @@ -55,9 +58,10 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener { LogUtil.materialNotRecognized("block-optimization", configuredMaterial); } }); - this.cooldown = config.getInt("optimization-methods.block-optimization.optimize-cooldown-seconds", 600, """ - Cooldown in seconds until a villager can be optimized again by using specific blocks. \s - Here for configuration freedom. Recommended to leave as is to not enable any exploitable behavior.""") * 1000L; + this.cooldown_millis = TimeUnit.SECONDS.toMillis( + config.getInt("optimization-methods.block-optimization.optimize-cooldown-seconds", 600, """ + Cooldown in seconds until a villager can be optimized again by using specific blocks.\s + Here for configuration freedom. Recommended to leave as is to not enable any exploitable behavior.""")); this.search_radius = config.getDouble("optimization-methods.block-optimization.search-radius-in-blocks", 2.0, """ The radius in blocks a villager can be away from the player when he places an optimize block.\s The closest unoptimized villager to the player will be optimized.""") / 2; @@ -89,7 +93,7 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener { Block placed = event.getBlock(); if (!blocks_that_disable.contains(placed.getType())) return; Player player = event.getPlayer(); - if (!player.hasPermission(Permissions.Optimize.BLOCK.get())) return; + if (!player.hasPermission(Optimize.BLOCK.get())) return; if (only_while_sneaking && !player.isSneaking()) return; final Location blockLoc = placed.getLocation(); @@ -105,7 +109,7 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener { WrappedVillager wVillager = villagerCache.getOrAdd(villager); final double distance = entity.getLocation().distance(blockLoc); - if (distance < closestDistance && wVillager.canOptimize(cooldown)) { + if (distance < closestDistance && wVillager.canOptimize(cooldown_millis)) { closestOptimizableVillager = wVillager; closestDistance = distance; } @@ -113,7 +117,7 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener { if (closestOptimizableVillager == null) return; - if (closestOptimizableVillager.canOptimize(cooldown) || player.hasPermission(Permissions.Bypass.BLOCK_COOLDOWN.get())) { + if (closestOptimizableVillager.canOptimize(cooldown_millis) || player.hasPermission(Bypass.BLOCK_COOLDOWN.get())) { VillagerOptimizeEvent optimizeEvent = new VillagerOptimizeEvent(closestOptimizableVillager, OptimizationType.BLOCK, player, event.isAsynchronous()); if (!optimizeEvent.callEvent()) return; @@ -137,11 +141,11 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener { if (log_enabled) VillagerOptimizer.getLog().info("Villager was optimized by block at "+closestOptimizableVillager.villager().getLocation()); } else { - closestOptimizableVillager.villager().shakeHead(); + CommonUtil.shakeHead(closestOptimizableVillager.villager()); if (notify_player) { final TextReplacementConfig timeLeft = TextReplacementConfig.builder() .matchLiteral("%time%") - .replacement(CommonUtil.formatTime(closestOptimizableVillager.getOptimizeCooldownMillis(cooldown))) + .replacement(CommonUtil.formatTime(closestOptimizableVillager.getOptimizeCooldownMillis(cooldown_millis))) .build(); VillagerOptimizer.getLang(player.locale()).block_on_optimize_cooldown.forEach(line -> player.sendMessage(line.replaceText(timeLeft))); } @@ -153,7 +157,7 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener { Block broken = event.getBlock(); if (!blocks_that_disable.contains(broken.getType())) return; Player player = event.getPlayer(); - if (!player.hasPermission(Permissions.Optimize.BLOCK.get())) return; + if (!player.hasPermission(Optimize.BLOCK.get())) return; if (only_while_sneaking && !player.isSneaking()) return; final Location blockLoc = broken.getLocation(); diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByNametag.java b/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByNametag.java similarity index 90% rename from VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByNametag.java rename to src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByNametag.java index d346eaa..3aff7fe 100644 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByNametag.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByNametag.java @@ -4,8 +4,9 @@ import me.xginko.villageroptimizer.VillagerCache; import me.xginko.villageroptimizer.VillagerOptimizer; import me.xginko.villageroptimizer.WrappedVillager; import me.xginko.villageroptimizer.config.Config; +import me.xginko.villageroptimizer.enums.permissions.Bypass; import me.xginko.villageroptimizer.enums.OptimizationType; -import me.xginko.villageroptimizer.enums.Permissions; +import me.xginko.villageroptimizer.enums.permissions.Optimize; import me.xginko.villageroptimizer.events.VillagerOptimizeEvent; import me.xginko.villageroptimizer.events.VillagerUnoptimizeEvent; import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; @@ -27,11 +28,13 @@ import org.bukkit.inventory.meta.ItemMeta; import java.util.HashSet; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; public class OptimizeByNametag implements VillagerOptimizerModule, Listener { private final VillagerCache villagerCache; - private final HashSet nametags = new HashSet<>(4); + private final Set nametags; private final long cooldown; private final boolean consume_nametag, notify_player, log_enabled; @@ -39,11 +42,12 @@ public class OptimizeByNametag implements VillagerOptimizerModule, Listener { shouldEnable(); this.villagerCache = VillagerOptimizer.getCache(); Config config = VillagerOptimizer.getConfiguration(); - config.addComment("optimization-methods.nametag-optimization.enable", """ + config.master().addComment("optimization-methods.nametag-optimization.enable", """ Enable optimization by naming villagers to one of the names configured below.\s Nametag optimized villagers will be unoptimized again when they are renamed to something else."""); - this.nametags.addAll(config.getList("optimization-methods.nametag-optimization.names", List.of("Optimize", "DisableAI"), - "Names are case insensitive, capital letters won't matter.").stream().map(String::toLowerCase).toList()); + this.nametags = config.getList("optimization-methods.nametag-optimization.names", List.of("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("optimization-methods.nametag-optimization.nametags-get-consumed", true, "Enable or disable consumption of the used nametag item."); this.cooldown = config.getInt("optimization-methods.nametag-optimization.optimize-cooldown-seconds", 600, """ @@ -74,7 +78,7 @@ public class OptimizeByNametag implements VillagerOptimizerModule, Listener { private void onPlayerInteractEntity(PlayerInteractEntityEvent event) { if (!event.getRightClicked().getType().equals(EntityType.VILLAGER)) return; Player player = event.getPlayer(); - if (!player.hasPermission(Permissions.Optimize.NAMETAG.get())) return; + if (!player.hasPermission(Optimize.NAMETAG.get())) return; ItemStack usedItem = player.getInventory().getItem(event.getHand()); if (!usedItem.getType().equals(Material.NAME_TAG)) return; @@ -89,7 +93,7 @@ public class OptimizeByNametag implements VillagerOptimizerModule, Listener { WrappedVillager wVillager = villagerCache.getOrAdd(villager); if (nametags.contains(name.toLowerCase())) { - if (wVillager.canOptimize(cooldown) || player.hasPermission(Permissions.Bypass.NAMETAG_COOLDOWN.get())) { + if (wVillager.canOptimize(cooldown) || player.hasPermission(Bypass.NAMETAG_COOLDOWN.get())) { VillagerOptimizeEvent optimizeEvent = new VillagerOptimizeEvent(wVillager, OptimizationType.NAMETAG, player, event.isAsynchronous()); if (!optimizeEvent.callEvent()) return; @@ -107,7 +111,7 @@ public class OptimizeByNametag implements VillagerOptimizerModule, Listener { VillagerOptimizer.getLog().info(player.getName() + " optimized a villager using nametag: '" + name + "'"); } else { event.setCancelled(true); - villager.shakeHead(); + CommonUtil.shakeHead(villager); if (notify_player) { final TextReplacementConfig timeLeft = TextReplacementConfig.builder() .matchLiteral("%time%") diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByWorkstation.java b/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByWorkstation.java similarity index 91% rename from VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByWorkstation.java rename to src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByWorkstation.java index fe63863..6bb86cd 100644 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByWorkstation.java +++ b/src/main/java/me/xginko/villageroptimizer/modules/optimization/OptimizeByWorkstation.java @@ -4,8 +4,9 @@ import me.xginko.villageroptimizer.VillagerCache; import me.xginko.villageroptimizer.VillagerOptimizer; import me.xginko.villageroptimizer.WrappedVillager; import me.xginko.villageroptimizer.config.Config; +import me.xginko.villageroptimizer.enums.permissions.Bypass; import me.xginko.villageroptimizer.enums.OptimizationType; -import me.xginko.villageroptimizer.enums.Permissions; +import me.xginko.villageroptimizer.enums.permissions.Optimize; import me.xginko.villageroptimizer.events.VillagerOptimizeEvent; import me.xginko.villageroptimizer.events.VillagerUnoptimizeEvent; import me.xginko.villageroptimizer.modules.VillagerOptimizerModule; @@ -25,10 +26,12 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPlaceEvent; +import java.util.concurrent.TimeUnit; + public class OptimizeByWorkstation implements VillagerOptimizerModule, Listener { private final VillagerCache villagerCache; - private final long cooldown; + private final long cooldown_millis; private final double search_radius; private final boolean only_while_sneaking, log_enabled, notify_player; @@ -36,15 +39,16 @@ public class OptimizeByWorkstation implements VillagerOptimizerModule, Listener shouldEnable(); this.villagerCache = VillagerOptimizer.getCache(); Config config = VillagerOptimizer.getConfiguration(); - config.addComment("optimization-methods.workstation-optimization.enable", """ + config.master().addComment("optimization-methods.workstation-optimization.enable", """ When enabled, the closest villager near a matching workstation being placed will be optimized.\s If a nearby matching workstation is broken, the villager will become unoptimized again."""); this.search_radius = config.getDouble("optimization-methods.workstation-optimization.search-radius-in-blocks", 2.0, """ The radius in blocks a villager can be away from the player when he places a workstation.\s The closest unoptimized villager to the player will be optimized.""") / 2; - this.cooldown = config.getInt("optimization-methods.workstation-optimization.optimize-cooldown-seconds", 600, """ + this.cooldown_millis = TimeUnit.SECONDS.toMillis( + config.getInt("optimization-methods.workstation-optimization.optimize-cooldown-seconds", 600, """ Cooldown in seconds until a villager can be optimized again using a workstation.\s - Here for configuration freedom. Recommended to leave as is to not enable any exploitable behavior.""") * 1000L; + Here for configuration freedom. Recommended to leave as is to not enable any exploitable behavior.""")); this.only_while_sneaking = config.getBoolean("optimization-methods.workstation-optimization.only-when-sneaking", true, "Only optimize/unoptimize by workstation when player is sneaking during place or break"); this.notify_player = config.getBoolean("optimization-methods.workstation-optimization.notify-player", true, @@ -74,7 +78,7 @@ public class OptimizeByWorkstation implements VillagerOptimizerModule, Listener Villager.Profession workstationProfession = getWorkstationProfession(placed.getType()); if (workstationProfession.equals(Villager.Profession.NONE)) return; Player player = event.getPlayer(); - if (!player.hasPermission(Permissions.Optimize.WORKSTATION.get())) return; + if (!player.hasPermission(Optimize.WORKSTATION.get())) return; if (only_while_sneaking && !player.isSneaking()) return; final Location workstationLoc = placed.getLocation(); @@ -89,7 +93,7 @@ public class OptimizeByWorkstation implements VillagerOptimizerModule, Listener WrappedVillager wVillager = villagerCache.getOrAdd(villager); final double distance = entity.getLocation().distance(workstationLoc); - if (distance < closestDistance && wVillager.canOptimize(cooldown)) { + if (distance < closestDistance && wVillager.canOptimize(cooldown_millis)) { closestOptimizableVillager = wVillager; closestDistance = distance; } @@ -97,7 +101,7 @@ public class OptimizeByWorkstation implements VillagerOptimizerModule, Listener if (closestOptimizableVillager == null) return; - if (closestOptimizableVillager.canOptimize(cooldown) || player.hasPermission(Permissions.Bypass.WORKSTATION_COOLDOWN.get())) { + if (closestOptimizableVillager.canOptimize(cooldown_millis) || player.hasPermission(Bypass.WORKSTATION_COOLDOWN.get())) { VillagerOptimizeEvent optimizeEvent = new VillagerOptimizeEvent(closestOptimizableVillager, OptimizationType.WORKSTATION, player, event.isAsynchronous()); if (!optimizeEvent.callEvent()) return; @@ -121,11 +125,11 @@ public class OptimizeByWorkstation implements VillagerOptimizerModule, Listener if (log_enabled) VillagerOptimizer.getLog().info(player.getName() + " optimized a villager using workstation: '" + placed.getType().toString().toLowerCase() + "'"); } else { - closestOptimizableVillager.villager().shakeHead(); + CommonUtil.shakeHead(closestOptimizableVillager.villager()); if (notify_player) { final TextReplacementConfig timeLeft = TextReplacementConfig.builder() .matchLiteral("%time%") - .replacement(CommonUtil.formatTime(closestOptimizableVillager.getOptimizeCooldownMillis(cooldown))) + .replacement(CommonUtil.formatTime(closestOptimizableVillager.getOptimizeCooldownMillis(cooldown_millis))) .build(); VillagerOptimizer.getLang(player.locale()).nametag_on_optimize_cooldown.forEach(line -> player.sendMessage(line .replaceText(timeLeft) @@ -140,7 +144,7 @@ public class OptimizeByWorkstation implements VillagerOptimizerModule, Listener Villager.Profession workstationProfession = getWorkstationProfession(broken.getType()); if (workstationProfession.equals(Villager.Profession.NONE)) return; Player player = event.getPlayer(); - if (!player.hasPermission(Permissions.Optimize.WORKSTATION.get())) return; + if (!player.hasPermission(Optimize.WORKSTATION.get())) return; if (only_while_sneaking && !player.isSneaking()) return; final Location workstationLoc = broken.getLocation(); @@ -155,7 +159,7 @@ public class OptimizeByWorkstation implements VillagerOptimizerModule, Listener WrappedVillager wVillager = villagerCache.getOrAdd(villager); final double distance = entity.getLocation().distance(workstationLoc); - if (distance < closestDistance && wVillager.canOptimize(cooldown)) { + if (distance < closestDistance && wVillager.canOptimize(cooldown_millis)) { closestOptimizedVillager = wVillager; closestDistance = distance; } diff --git a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/utils/CommonUtil.java b/src/main/java/me/xginko/villageroptimizer/utils/CommonUtil.java similarity index 62% rename from VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/utils/CommonUtil.java rename to src/main/java/me/xginko/villageroptimizer/utils/CommonUtil.java index 1a0e2f1..33f2427 100644 --- a/VillagerOptimizer-1.20.2/src/main/java/me/xginko/villageroptimizer/utils/CommonUtil.java +++ b/src/main/java/me/xginko/villageroptimizer/utils/CommonUtil.java @@ -1,5 +1,7 @@ package me.xginko.villageroptimizer.utils; +import org.bukkit.Chunk; +import org.bukkit.entity.Villager; import org.jetbrains.annotations.NotNull; import java.time.Duration; @@ -21,4 +23,18 @@ public class CommonUtil { return format("%02ds", seconds); } } + + public static boolean isEntitiesLoaded(@NotNull Chunk chunk) { + try { + return chunk.isEntitiesLoaded(); + } catch (NoSuchMethodError e) { + return chunk.isLoaded(); + } + } + + public static void shakeHead(@NotNull Villager villager) { + try { + villager.shakeHead(); + } catch (NoSuchMethodError ignored) {} + } } diff --git a/VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/utils/LogUtil.java b/src/main/java/me/xginko/villageroptimizer/utils/LogUtil.java similarity index 100% rename from VillagerOptimizer-1.16.5/src/main/java/me/xginko/villageroptimizer/utils/LogUtil.java rename to src/main/java/me/xginko/villageroptimizer/utils/LogUtil.java diff --git a/VillagerOptimizer-1.16.5/src/main/resources/lang/de_de.yml b/src/main/resources/lang/de_de.yml similarity index 100% rename from VillagerOptimizer-1.16.5/src/main/resources/lang/de_de.yml rename to src/main/resources/lang/de_de.yml diff --git a/VillagerOptimizer-1.16.5/src/main/resources/lang/en_us.yml b/src/main/resources/lang/en_us.yml similarity index 100% rename from VillagerOptimizer-1.16.5/src/main/resources/lang/en_us.yml rename to src/main/resources/lang/en_us.yml diff --git a/VillagerOptimizer-1.16.5/src/main/resources/lang/it_it.yml b/src/main/resources/lang/it_it.yml similarity index 100% rename from VillagerOptimizer-1.16.5/src/main/resources/lang/it_it.yml rename to src/main/resources/lang/it_it.yml diff --git a/VillagerOptimizer-1.16.5/src/main/resources/lang/ru_ru.yml b/src/main/resources/lang/ru_ru.yml similarity index 100% rename from VillagerOptimizer-1.16.5/src/main/resources/lang/ru_ru.yml rename to src/main/resources/lang/ru_ru.yml diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..6382929 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,28 @@ +name: VillagerOptimizer +version: '${project.version}' +main: me.xginko.villageroptimizer.VillagerOptimizer +authors: [ xGinko ] +description: ${project.description} +website: ${project.url} +api-version: '1.16' +folia-supported: true + +commands: + villageroptimizer: + usage: /villageroptimizer [ reload, version, disable ] + description: VillagerOptimizer admin commands + aliases: + - voptimizer + - vo + optimizevillagers: + usage: /optimizevillagers + description: Optmize villagers in a radius around you + aliases: + - optvils + - noai + unoptimizevillagers: + usage: /unoptimizevillagers + description: Unoptmize villagers in a radius around you + aliases: + - unoptvils + - noaiundo \ No newline at end of file