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