better renaming logic

This commit is contained in:
xGinko 2023-09-29 17:42:10 +02:00
parent 9da5d13333
commit 91871fd7de
12 changed files with 279 additions and 105 deletions

View File

@ -13,6 +13,7 @@ import org.bukkit.NamespacedKey;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.io.File; import java.io.File;
@ -93,6 +94,9 @@ public final class VillagerOptimizer extends JavaPlugin {
public static LanguageCache getLang(String lang) { public static LanguageCache getLang(String lang) {
return config.auto_lang ? languageCacheMap.getOrDefault(lang.replace("-", "_"), languageCacheMap.get(config.default_lang.toString().toLowerCase())) : languageCacheMap.get(config.default_lang.toString().toLowerCase()); return config.auto_lang ? languageCacheMap.getOrDefault(lang.replace("-", "_"), languageCacheMap.get(config.default_lang.toString().toLowerCase())) : languageCacheMap.get(config.default_lang.toString().toLowerCase());
} }
public static void callEvent(Event event) {
instance.getServer().getPluginManager().callEvent(event);
}
public void reloadPlugin() { public void reloadPlugin() {
reloadLang(false); reloadLang(false);

View File

@ -2,10 +2,15 @@ package me.xginko.villageroptimizer;
import me.xginko.villageroptimizer.enums.Keys; import me.xginko.villageroptimizer.enums.Keys;
import me.xginko.villageroptimizer.enums.OptimizationType; 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.entity.Villager;
import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType; import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
public final class WrappedVillager { public final class WrappedVillager {
@ -24,6 +29,13 @@ public final class WrappedVillager {
return 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. * @return True if the villager is optimized by this plugin, otherwise false.
*/ */
@ -167,4 +179,34 @@ public final class WrappedVillager {
public long getLevelCooldownMillis(final long cooldown_millis) { 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; 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 renameForOptimization(final @Nullable Component newName, final boolean replace_existing_name) {
if (replace_existing_name) {
villager.customName(newName);
if (newName == null) dataContainer.remove(Keys.LAST_OPTIMIZE_NAME.key());
else saveOptimizeName(newName);
} else {
Component currentName = villager.customName();
if (currentName == null) {
villager.customName(newName);
if (newName == null) dataContainer.remove(Keys.LAST_OPTIMIZE_NAME.key());
else saveOptimizeName(newName);
} else {
Component lastName = getOptimizeName();
if (Objects.equals(currentName, lastName)) {
villager.customName(newName);
if (newName == null) dataContainer.remove(Keys.LAST_OPTIMIZE_NAME.key());
else saveOptimizeName(newName);
}
}
}
}
public void saveOptimizeName(final Component customName) {
dataContainer.set(Keys.LAST_OPTIMIZE_NAME.key(), PersistentDataType.STRING, MiniMessage.miniMessage().serialize(customName));
}
public @Nullable Component getOptimizeName() {
return dataContainer.has(Keys.LAST_OPTIMIZE_NAME.key()) ? MiniMessage.miniMessage().deserialize(dataContainer.get(Keys.LAST_OPTIMIZE_NAME.key(), PersistentDataType.STRING)) : null;
}
} }

View File

@ -1,17 +1,17 @@
package me.xginko.villageroptimizer.commands.optimizevillagers; package me.xginko.villageroptimizer.commands.optimizevillagers;
import me.xginko.villageroptimizer.VillagerOptimizer;
import me.xginko.villageroptimizer.VillagerCache; 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.commands.VillagerOptimizerCommand;
import me.xginko.villageroptimizer.config.Config; import me.xginko.villageroptimizer.config.Config;
import me.xginko.villageroptimizer.enums.OptimizationType; import me.xginko.villageroptimizer.enums.OptimizationType;
import me.xginko.villageroptimizer.enums.Permissions; import me.xginko.villageroptimizer.enums.Permissions;
import me.xginko.villageroptimizer.WrappedVillager; import me.xginko.villageroptimizer.events.VillagerOptimizeEvent;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextReplacementConfig; import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration; import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter; import org.bukkit.command.TabCompleter;
@ -28,10 +28,8 @@ import java.util.List;
public class OptVillagersRadius implements VillagerOptimizerCommand, TabCompleter { public class OptVillagersRadius implements VillagerOptimizerCommand, TabCompleter {
private final List<String> tabCompletes = List.of("5", "10", "25", "50"); private final List<String> tabCompletes = List.of("5", "10", "25", "50");
private final Component optimizeName;
private final long cooldown; private final long cooldown;
private final int maxRadius; private final int maxRadius;
private final boolean shouldRename, overwrite_name;
public OptVillagersRadius() { public OptVillagersRadius() {
Config config = VillagerOptimizer.getConfiguration(); Config config = VillagerOptimizer.getConfiguration();
@ -39,12 +37,6 @@ public class OptVillagersRadius implements VillagerOptimizerCommand, TabComplete
this.cooldown = config.getInt("optimization-methods.commands.optimizevillagers.cooldown-seconds", 600, """ 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 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; Here for configuration freedom. Recommended to leave as is to not enable any exploitable behavior.""") * 1000L;
this.shouldRename = config.getBoolean("optimization-methods.commands.rename-optimized-villagers.enable", true,
"Renames villagers to what you configure below when they're optimized.");
this.overwrite_name = config.getBoolean("optimization-methods.commands.rename-optimized-villagers.overwrite-previous-name", false,
"Whether to overwrite the previous name or not.");
this.optimizeName = MiniMessage.miniMessage().deserialize(config.getString("optimization-methods.commands.rename-optimized-villagers.name", "<green>Optimized",
"The MiniMessage formatted name to give optimized villagers."));
} }
@Override @Override
@ -96,19 +88,13 @@ public class OptVillagersRadius implements VillagerOptimizerCommand, TabComplete
WrappedVillager wVillager = villagerCache.getOrAdd(villager); WrappedVillager wVillager = villagerCache.getOrAdd(villager);
if (wVillager.canOptimize(cooldown)) { if (wVillager.canOptimize(cooldown)) {
wVillager.setOptimization(OptimizationType.COMMAND); VillagerOptimizeEvent optimizeEvent = new VillagerOptimizeEvent(wVillager, OptimizationType.COMMAND);
VillagerOptimizer.callEvent(optimizeEvent);
if (!optimizeEvent.isCancelled()) {
wVillager.setOptimization(optimizeEvent.getOptimizationType());
wVillager.saveOptimizeTime(); wVillager.saveOptimizeTime();
if (shouldRename) {
if (overwrite_name) {
villager.customName(optimizeName);
} else {
if (villager.customName() == null)
villager.customName(optimizeName);
}
}
successCount++; successCount++;
}
} else { } else {
failCount++; failCount++;
} }

View File

@ -4,15 +4,13 @@ import me.xginko.villageroptimizer.VillagerCache;
import me.xginko.villageroptimizer.VillagerOptimizer; import me.xginko.villageroptimizer.VillagerOptimizer;
import me.xginko.villageroptimizer.WrappedVillager; import me.xginko.villageroptimizer.WrappedVillager;
import me.xginko.villageroptimizer.commands.VillagerOptimizerCommand; import me.xginko.villageroptimizer.commands.VillagerOptimizerCommand;
import me.xginko.villageroptimizer.config.Config;
import me.xginko.villageroptimizer.enums.OptimizationType; import me.xginko.villageroptimizer.enums.OptimizationType;
import me.xginko.villageroptimizer.enums.Permissions; import me.xginko.villageroptimizer.enums.Permissions;
import me.xginko.villageroptimizer.events.VillagerUnoptimizeEvent;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextReplacementConfig; import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration; import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter; import org.bukkit.command.TabCompleter;
@ -29,15 +27,10 @@ import java.util.List;
public class UnOptVillagersRadius implements VillagerOptimizerCommand, TabCompleter { public class UnOptVillagersRadius implements VillagerOptimizerCommand, TabCompleter {
private final List<String> tabCompletes = List.of("5", "10", "25", "50"); private final List<String> tabCompletes = List.of("5", "10", "25", "50");
private final String optimizeName;
private final int maxRadius; private final int maxRadius;
private final boolean shouldRename;
public UnOptVillagersRadius() { public UnOptVillagersRadius() {
Config config = VillagerOptimizer.getConfiguration(); this.maxRadius = VillagerOptimizer.getConfiguration().getInt("optimization-methods.commands.unoptimizevillagers.max-block-radius", 100);
this.maxRadius = config.getInt("optimization-methods.commands.unoptimizevillagers.max-block-radius", 100);
this.shouldRename = config.getBoolean("optimization-methods.commands.rename-optimized-villagers.enable", true);
this.optimizeName = MiniMessage.miniMessage().stripTags(config.getString("optimization-methods.commands.rename-optimized-villagers.name", "<green>Optimized"));
} }
@Override @Override
@ -88,18 +81,14 @@ public class UnOptVillagersRadius implements VillagerOptimizerCommand, TabComple
WrappedVillager wVillager = villagerCache.getOrAdd(villager); WrappedVillager wVillager = villagerCache.getOrAdd(villager);
if (wVillager.isOptimized()) { if (wVillager.isOptimized()) {
VillagerUnoptimizeEvent unOptimizeEvent = new VillagerUnoptimizeEvent(wVillager);
VillagerOptimizer.callEvent(unOptimizeEvent);
if (!unOptimizeEvent.isCancelled()) {
wVillager.setOptimization(OptimizationType.NONE); wVillager.setOptimization(OptimizationType.NONE);
if (shouldRename) {
Component vilName = villager.customName();
if (vilName != null && PlainTextComponentSerializer.plainText().serialize(vilName).equalsIgnoreCase(optimizeName)) {
villager.customName(null);
}
}
successCount++; successCount++;
} }
} }
}
if (successCount <= 0) { if (successCount <= 0) {
final TextReplacementConfig radius = TextReplacementConfig.builder() final TextReplacementConfig radius = TextReplacementConfig.builder()

View File

@ -8,7 +8,8 @@ public enum Keys {
OPTIMIZATION_TYPE(VillagerOptimizer.getKey("optimization-type")), OPTIMIZATION_TYPE(VillagerOptimizer.getKey("optimization-type")),
LAST_OPTIMIZE(VillagerOptimizer.getKey("last-optimize")), LAST_OPTIMIZE(VillagerOptimizer.getKey("last-optimize")),
LAST_LEVELUP(VillagerOptimizer.getKey("last-levelup")), LAST_LEVELUP(VillagerOptimizer.getKey("last-levelup")),
LAST_RESTOCK(VillagerOptimizer.getKey("last-restock")); LAST_RESTOCK(VillagerOptimizer.getKey("last-restock")),
LAST_OPTIMIZE_NAME(VillagerOptimizer.getKey("last-optimize-name"));
private final NamespacedKey key; private final NamespacedKey key;

View File

@ -0,0 +1,62 @@
package me.xginko.villageroptimizer.events;
import me.xginko.villageroptimizer.WrappedVillager;
import me.xginko.villageroptimizer.enums.OptimizationType;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
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 boolean isCancelled = false;
public VillagerOptimizeEvent(@NotNull WrappedVillager wrappedVillager, @NotNull OptimizationType type, boolean isAsync) throws IllegalArgumentException {
super(isAsync);
this.wrappedVillager = wrappedVillager;
this.type = type;
if (type.equals(OptimizationType.NONE)) {
throw new IllegalArgumentException("Type can't be NONE.");
}
}
public VillagerOptimizeEvent(@NotNull WrappedVillager wrappedVillager, @NotNull OptimizationType type) throws IllegalArgumentException {
this.wrappedVillager = wrappedVillager;
this.type = type;
if (type.equals(OptimizationType.NONE)) {
throw new IllegalArgumentException("Type can't be NONE.");
}
}
public @NotNull WrappedVillager getWrappedVillager() {
return wrappedVillager;
}
public @NotNull OptimizationType getOptimizationType() {
return type;
}
public void setOptimizationType(@NotNull OptimizationType type) {
this.type = type;
}
@Override
public void setCancelled(boolean cancel) {
isCancelled = cancel;
}
@Override
public boolean isCancelled() {
return isCancelled;
}
@Override
public @NotNull HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,42 @@
package me.xginko.villageroptimizer.events;
import me.xginko.villageroptimizer.WrappedVillager;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class VillagerUnoptimizeEvent extends Event implements Cancellable {
private static final @NotNull HandlerList handlers = new HandlerList();
private final @NotNull WrappedVillager wrappedVillager;
private boolean isCancelled = false;
public VillagerUnoptimizeEvent(@NotNull WrappedVillager wrappedVillager, boolean isAsync) {
super(isAsync);
this.wrappedVillager = wrappedVillager;
}
public VillagerUnoptimizeEvent(@NotNull WrappedVillager wrappedVillager) {
this.wrappedVillager = wrappedVillager;
}
public @NotNull WrappedVillager getWrappedVillager() {
return wrappedVillager;
}
@Override
public boolean isCancelled() {
return isCancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.isCancelled = cancel;
}
@Override
public @NotNull HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,64 @@
package me.xginko.villageroptimizer.modules;
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 net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
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;
protected RenameOptimizedVillagers() {
this.plugin = VillagerOptimizer.getInstance();
Config config = VillagerOptimizer.getConfiguration();
config.addComment("general.rename-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("general.rename-villagers.optimized-name", "<green>Optimized",
"The name that will be used to mark optimized villagers. Uses MiniMessage format."));
this.overwrite_previous_name = config.getBoolean("general.rename-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 void disable() {
HandlerList.unregisterAll(this);
}
@Override
public boolean shouldEnable() {
return VillagerOptimizer.getConfiguration().getBoolean("general.rename-villagers.enable", true);
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
private void onOptimize(VillagerOptimizeEvent event) {
WrappedVillager wVillager = event.getWrappedVillager();
wVillager.villager().getScheduler().runDelayed(plugin, rename -> {
wVillager.renameForOptimization(optimized_name, overwrite_previous_name);
}, null, 10L);
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
private void onUnOptimize(VillagerUnoptimizeEvent event) {
WrappedVillager wVillager = event.getWrappedVillager();
wVillager.villager().getScheduler().runDelayed(plugin, rename -> {
wVillager.renameForOptimization(null, overwrite_previous_name);
}, null, 10L);
}
}

View File

@ -24,8 +24,6 @@ public interface VillagerOptimizerModule {
modules.forEach(VillagerOptimizerModule::disable); modules.forEach(VillagerOptimizerModule::disable);
modules.clear(); modules.clear();
modules.add(new VillagerChunkLimit());
modules.add(new OptimizeByNametag()); modules.add(new OptimizeByNametag());
modules.add(new OptimizeByBlock()); modules.add(new OptimizeByBlock());
modules.add(new OptimizeByWorkstation()); modules.add(new OptimizeByWorkstation());
@ -38,6 +36,9 @@ public interface VillagerOptimizerModule {
modules.add(new PreventVillagerDamage()); modules.add(new PreventVillagerDamage());
modules.add(new PreventVillagerTargetting()); modules.add(new PreventVillagerTargetting());
modules.add(new VillagerChunkLimit());
modules.add(new RenameOptimizedVillagers());
modules.forEach(module -> { modules.forEach(module -> {
if (module.shouldEnable()) module.enable(); if (module.shouldEnable()) module.enable();
}); });

View File

@ -6,13 +6,12 @@ import me.xginko.villageroptimizer.WrappedVillager;
import me.xginko.villageroptimizer.config.Config; import me.xginko.villageroptimizer.config.Config;
import me.xginko.villageroptimizer.enums.OptimizationType; import me.xginko.villageroptimizer.enums.OptimizationType;
import me.xginko.villageroptimizer.enums.Permissions; 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.modules.VillagerOptimizerModule;
import me.xginko.villageroptimizer.utils.CommonUtil; import me.xginko.villageroptimizer.utils.CommonUtil;
import me.xginko.villageroptimizer.utils.LogUtil; import me.xginko.villageroptimizer.utils.LogUtil;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextReplacementConfig; import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -34,10 +33,9 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener {
private final VillagerCache villagerCache; private final VillagerCache villagerCache;
private final HashSet<Material> blocks_that_disable = new HashSet<>(4); private final HashSet<Material> blocks_that_disable = new HashSet<>(4);
private final Component optimizeName;
private final long cooldown; private final long cooldown;
private final double search_radius; private final double search_radius;
private final boolean onlyWhileSneaking, shouldRename, overwrite_name, shouldLog, shouldNotifyPlayer; private final boolean onlyWhileSneaking, shouldNotifyPlayer, shouldLog;
public OptimizeByBlock() { public OptimizeByBlock() {
shouldEnable(); shouldEnable();
@ -67,12 +65,6 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener {
"Only optimize/unoptimize by workstation when player is sneaking during place or break."); "Only optimize/unoptimize by workstation when player is sneaking during place or break.");
this.shouldNotifyPlayer = config.getBoolean("optimization-methods.block-optimization.notify-player", true, this.shouldNotifyPlayer = config.getBoolean("optimization-methods.block-optimization.notify-player", true,
"Sends players a message when they successfully optimized or unoptimized a villager."); "Sends players a message when they successfully optimized or unoptimized a villager.");
this.shouldRename = config.getBoolean("optimization-methods.block-optimization.rename-optimized-villagers.enable", true,
"Renames villagers to what you configure below when they're optimized.");
this.overwrite_name = config.getBoolean("optimization-methods.block-optimization.rename-optimized-villagers.overwrite-previous-name", false,
"Whether to overwrite the previous name or not.");
this.optimizeName = MiniMessage.miniMessage().deserialize(config.getString("optimization-methods.block-optimization.rename-optimized-villagers.name", "<green>Block Optimized",
"The MiniMessage formatted name to give optimized villagers."));
this.shouldLog = config.getBoolean("optimization-methods.block-optimization.log", false); this.shouldLog = config.getBoolean("optimization-methods.block-optimization.log", false);
} }
@ -122,17 +114,12 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener {
if (closestOptimizableVillager == null) return; if (closestOptimizableVillager == null) return;
if (closestOptimizableVillager.canOptimize(cooldown) || player.hasPermission(Permissions.Bypass.BLOCK_COOLDOWN.get())) { if (closestOptimizableVillager.canOptimize(cooldown) || player.hasPermission(Permissions.Bypass.BLOCK_COOLDOWN.get())) {
closestOptimizableVillager.setOptimization(OptimizationType.BLOCK); VillagerOptimizeEvent optimizeEvent = new VillagerOptimizeEvent(closestOptimizableVillager, OptimizationType.BLOCK, event.isAsynchronous());
closestOptimizableVillager.saveOptimizeTime(); VillagerOptimizer.callEvent(optimizeEvent);
if (optimizeEvent.isCancelled()) return;
if (shouldRename) { closestOptimizableVillager.setOptimization(optimizeEvent.getOptimizationType());
if (overwrite_name) { closestOptimizableVillager.saveOptimizeTime();
closestOptimizableVillager.villager().customName(optimizeName);
} else {
Villager villager = closestOptimizableVillager.villager();
if (villager.customName() == null) villager.customName(optimizeName);
}
}
if (shouldNotifyPlayer) { if (shouldNotifyPlayer) {
final TextReplacementConfig vilProfession = TextReplacementConfig.builder() final TextReplacementConfig vilProfession = TextReplacementConfig.builder()
@ -189,21 +176,16 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener {
if (closestOptimizedVillager == null) return; if (closestOptimizedVillager == null) return;
VillagerUnoptimizeEvent unOptimizeEvent = new VillagerUnoptimizeEvent(closestOptimizedVillager, event.isAsynchronous());
VillagerOptimizer.callEvent(unOptimizeEvent);
if (unOptimizeEvent.isCancelled()) return;
closestOptimizedVillager.setOptimization(OptimizationType.NONE); closestOptimizedVillager.setOptimization(OptimizationType.NONE);
Villager villager = closestOptimizedVillager.villager();
if (shouldRename) {
Component vilName = villager.customName();
if (vilName != null && PlainTextComponentSerializer.plainText().serialize(vilName).equalsIgnoreCase(PlainTextComponentSerializer.plainText().serialize(optimizeName))) {
villager.customName(null);
}
}
if (shouldNotifyPlayer) { if (shouldNotifyPlayer) {
final TextReplacementConfig vilProfession = TextReplacementConfig.builder() final TextReplacementConfig vilProfession = TextReplacementConfig.builder()
.matchLiteral("%vil_profession%") .matchLiteral("%vil_profession%")
.replacement(villager.getProfession().toString().toLowerCase()) .replacement(closestOptimizedVillager.villager().getProfession().toString().toLowerCase())
.build(); .build();
final TextReplacementConfig brokenMaterial = TextReplacementConfig.builder() final TextReplacementConfig brokenMaterial = TextReplacementConfig.builder()
.matchLiteral("%blocktype%") .matchLiteral("%blocktype%")

View File

@ -6,6 +6,8 @@ import me.xginko.villageroptimizer.WrappedVillager;
import me.xginko.villageroptimizer.config.Config; import me.xginko.villageroptimizer.config.Config;
import me.xginko.villageroptimizer.enums.OptimizationType; import me.xginko.villageroptimizer.enums.OptimizationType;
import me.xginko.villageroptimizer.enums.Permissions; 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.modules.VillagerOptimizerModule;
import me.xginko.villageroptimizer.utils.CommonUtil; import me.xginko.villageroptimizer.utils.CommonUtil;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -31,7 +33,7 @@ public class OptimizeByNametag implements VillagerOptimizerModule, Listener {
private final VillagerCache villagerCache; private final VillagerCache villagerCache;
private final HashSet<String> nametags = new HashSet<>(4); private final HashSet<String> nametags = new HashSet<>(4);
private final long cooldown; private final long cooldown;
private final boolean shouldLog, shouldNotifyPlayer, consumeNametag; private final boolean consumeNametag, shouldNotifyPlayer, shouldLog;
public OptimizeByNametag() { public OptimizeByNametag() {
shouldEnable(); shouldEnable();
@ -82,19 +84,22 @@ public class OptimizeByNametag implements VillagerOptimizerModule, Listener {
// Get component name first, so we can manually name the villager when canceling the event to avoid item consumption. // Get component name first, so we can manually name the villager when canceling the event to avoid item consumption.
Component newVillagerName = meta.displayName(); Component newVillagerName = meta.displayName();
assert newVillagerName != null; // Legitimate since we checked for hasDisplayName() assert newVillagerName != null; // Legitimate since we checked for hasDisplayName()
final String name = PlainTextComponentSerializer.plainText().serialize(newVillagerName);
Villager villager = (Villager) event.getRightClicked(); 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())) {
if (!consumeNametag) { if (!consumeNametag) {
event.setCancelled(true); event.setCancelled(true);
villager.customName(newVillagerName); villager.customName(newVillagerName);
} }
final String name = PlainTextComponentSerializer.plainText().serialize(newVillagerName); VillagerOptimizeEvent optimizeEvent = new VillagerOptimizeEvent(wVillager, OptimizationType.NAMETAG, event.isAsynchronous());
WrappedVillager wVillager = villagerCache.getOrAdd(villager); VillagerOptimizer.callEvent(optimizeEvent);
if (optimizeEvent.isCancelled()) return;
if (nametags.contains(name.toLowerCase())) { wVillager.setOptimization(optimizeEvent.getOptimizationType());
if (wVillager.canOptimize(cooldown) || player.hasPermission(Permissions.Bypass.NAMETAG_COOLDOWN.get())) {
wVillager.setOptimization(OptimizationType.NAMETAG);
wVillager.saveOptimizeTime(); wVillager.saveOptimizeTime();
if (shouldNotifyPlayer) if (shouldNotifyPlayer)
@ -114,7 +119,12 @@ public class OptimizeByNametag implements VillagerOptimizerModule, Listener {
} }
} else { } else {
if (wVillager.isOptimized()) { if (wVillager.isOptimized()) {
VillagerUnoptimizeEvent unOptimizeEvent = new VillagerUnoptimizeEvent(wVillager, event.isAsynchronous());
VillagerOptimizer.callEvent(unOptimizeEvent);
if (unOptimizeEvent.isCancelled()) return;
wVillager.setOptimization(OptimizationType.NONE); wVillager.setOptimization(OptimizationType.NONE);
if (shouldNotifyPlayer) if (shouldNotifyPlayer)
VillagerOptimizer.getLang(player.locale()).nametag_unoptimize_success.forEach(player::sendMessage); VillagerOptimizer.getLang(player.locale()).nametag_unoptimize_success.forEach(player::sendMessage);
if (shouldLog) if (shouldLog)

View File

@ -6,12 +6,13 @@ import me.xginko.villageroptimizer.WrappedVillager;
import me.xginko.villageroptimizer.config.Config; import me.xginko.villageroptimizer.config.Config;
import me.xginko.villageroptimizer.enums.OptimizationType; import me.xginko.villageroptimizer.enums.OptimizationType;
import me.xginko.villageroptimizer.enums.Permissions; 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.modules.VillagerOptimizerModule;
import me.xginko.villageroptimizer.utils.CommonUtil; import me.xginko.villageroptimizer.utils.CommonUtil;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextReplacementConfig; import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -106,17 +107,12 @@ public class OptimizeByWorkstation implements VillagerOptimizerModule, Listener
if (closestOptimizableVillager == null) return; if (closestOptimizableVillager == null) return;
if (closestOptimizableVillager.canOptimize(cooldown) || player.hasPermission(Permissions.Bypass.WORKSTATION_COOLDOWN.get())) { if (closestOptimizableVillager.canOptimize(cooldown) || player.hasPermission(Permissions.Bypass.WORKSTATION_COOLDOWN.get())) {
closestOptimizableVillager.setOptimization(OptimizationType.WORKSTATION); VillagerOptimizeEvent optimizeEvent = new VillagerOptimizeEvent(closestOptimizableVillager, OptimizationType.WORKSTATION, event.isAsynchronous());
closestOptimizableVillager.saveOptimizeTime(); VillagerOptimizer.callEvent(optimizeEvent);
if (optimizeEvent.isCancelled()) return;
if (shouldRename) { closestOptimizableVillager.setOptimization(optimizeEvent.getOptimizationType());
if (overwrite_name) { closestOptimizableVillager.saveOptimizeTime();
closestOptimizableVillager.villager().customName(optimizeName);
} else {
Villager villager = closestOptimizableVillager.villager();
if (villager.customName() == null) villager.customName(optimizeName);
}
}
if (shouldNotifyPlayer) { if (shouldNotifyPlayer) {
final TextReplacementConfig vilProfession = TextReplacementConfig.builder() final TextReplacementConfig vilProfession = TextReplacementConfig.builder()
@ -177,21 +173,16 @@ public class OptimizeByWorkstation implements VillagerOptimizerModule, Listener
if (closestOptimizedVillager == null) return; if (closestOptimizedVillager == null) return;
VillagerUnoptimizeEvent unOptimizeEvent = new VillagerUnoptimizeEvent(closestOptimizedVillager, event.isAsynchronous());
VillagerOptimizer.callEvent(unOptimizeEvent);
if (unOptimizeEvent.isCancelled()) return;
closestOptimizedVillager.setOptimization(OptimizationType.NONE); closestOptimizedVillager.setOptimization(OptimizationType.NONE);
Villager villager = closestOptimizedVillager.villager();
if (shouldRename) {
Component vilName = villager.customName();
if (vilName != null && PlainTextComponentSerializer.plainText().serialize(vilName).equalsIgnoreCase(PlainTextComponentSerializer.plainText().serialize(optimizeName))) {
villager.customName(null);
}
}
if (shouldNotifyPlayer) { if (shouldNotifyPlayer) {
final TextReplacementConfig vilProfession = TextReplacementConfig.builder() final TextReplacementConfig vilProfession = TextReplacementConfig.builder()
.matchLiteral("%vil_profession%") .matchLiteral("%vil_profession%")
.replacement(villager.getProfession().toString().toLowerCase()) .replacement(closestOptimizedVillager.villager().getProfession().toString().toLowerCase())
.build(); .build();
final TextReplacementConfig brokenWorkstation = TextReplacementConfig.builder() final TextReplacementConfig brokenWorkstation = TextReplacementConfig.builder()
.matchLiteral("%workstation%") .matchLiteral("%workstation%")