cleanup wrappers

This commit is contained in:
xGinko 2024-08-09 14:24:45 +02:00
parent 1360be9917
commit f90d3ac3f2
22 changed files with 130 additions and 185 deletions

View File

@ -1,11 +1,14 @@
package me.xginko.villageroptimizer;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import me.xginko.villageroptimizer.commands.VillagerOptimizerCommand;
import me.xginko.villageroptimizer.config.Config;
import me.xginko.villageroptimizer.config.LanguageCache;
import me.xginko.villageroptimizer.enums.Permissions;
import me.xginko.villageroptimizer.modules.VillagerOptimizerModule;
import me.xginko.villageroptimizer.utils.Util;
import me.xginko.villageroptimizer.wrapper.WrappedVillager;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
@ -16,6 +19,7 @@ import org.apache.logging.log4j.core.config.Configurator;
import org.bstats.bukkit.Metrics;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.entity.Villager;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import space.arim.morepaperlib.MorePaperLib;
@ -41,9 +45,9 @@ import java.util.zip.ZipEntry;
public final class VillagerOptimizer extends JavaPlugin {
private static VillagerOptimizer instance;
private static WrapperCache wrapperCache;
private static CommandRegistration commandRegistration;
private static GracefulScheduling scheduling;
private static Cache<Villager, WrappedVillager> wrapperCache;
private static Map<String, LanguageCache> languageCacheMap;
private static Config config;
private static BukkitAudiences audiences;
@ -128,7 +132,7 @@ public final class VillagerOptimizer extends JavaPlugin {
VillagerOptimizerCommand.COMMANDS.forEach(VillagerOptimizerCommand::disable);
VillagerOptimizerCommand.COMMANDS.clear();
if (wrapperCache != null) {
wrapperCache.disable();
wrapperCache.cleanUp();
wrapperCache = null;
}
if (scheduling != null) {
@ -156,7 +160,7 @@ public final class VillagerOptimizer extends JavaPlugin {
public static @NotNull Config config() {
return config;
}
public static @NotNull WrapperCache getCache() {
public static @NotNull Cache<Villager, WrappedVillager> getCache() {
return wrapperCache;
}
public static @NotNull CommandRegistration commandRegistration() {
@ -190,9 +194,8 @@ public final class VillagerOptimizer extends JavaPlugin {
private void reloadConfiguration() {
try {
config = new Config();
if (wrapperCache != null) wrapperCache.disable();
wrapperCache = new WrapperCache(config.cache_keep_time);
wrapperCache.enable();
if (wrapperCache != null) wrapperCache.cleanUp();
wrapperCache = Caffeine.newBuilder().expireAfterWrite(config.cache_keep_time).build();
VillagerOptimizerCommand.reloadCommands();
VillagerOptimizerModule.reloadModules();
config.saveConfig();

View File

@ -1,49 +0,0 @@
package me.xginko.villageroptimizer;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import me.xginko.villageroptimizer.utils.Disableable;
import me.xginko.villageroptimizer.utils.Enableable;
import me.xginko.villageroptimizer.wrapper.WrappedVillager;
import org.bukkit.entity.Villager;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
import org.jetbrains.annotations.NotNull;
import java.time.Duration;
import java.util.UUID;
public final class WrapperCache implements Enableable, Disableable, Listener {
private final @NotNull Cache<UUID, WrappedVillager> wrapperCache;
public WrapperCache(Duration cacheDuration) {
this.wrapperCache = Caffeine.newBuilder().expireAfterWrite(cacheDuration).build();
}
@Override
public void enable() {
VillagerOptimizer plugin = VillagerOptimizer.getInstance();
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@Override
public void disable() {
HandlerList.unregisterAll(this);
this.wrapperCache.invalidateAll();
this.wrapperCache.cleanUp();
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
private void onEntityDeath(EntityDeathEvent event) {
this.wrapperCache.invalidate(event.getEntity().getUniqueId());
}
@SuppressWarnings("DataFlowIssue")
public @NotNull WrappedVillager get(@NotNull Villager villager) {
return this.wrapperCache.get(villager.getUniqueId(), k -> new WrappedVillager(villager));
}
}

View File

@ -1,6 +1,5 @@
package me.xginko.villageroptimizer.commands.optimizevillagers;
import me.xginko.villageroptimizer.WrapperCache;
import me.xginko.villageroptimizer.VillagerOptimizer;
import me.xginko.villageroptimizer.commands.VillagerOptimizerCommand;
import me.xginko.villageroptimizer.config.Config;
@ -90,7 +89,6 @@ public class OptVillagersRadius extends VillagerOptimizerCommand {
return true;
}
WrapperCache wrapperCache = VillagerOptimizer.getCache();
int successCount = 0;
int failCount = 0;
final boolean player_has_cooldown_bypass = player.hasPermission(Permissions.Bypass.COMMAND_COOLDOWN.get());
@ -101,7 +99,7 @@ public class OptVillagersRadius extends VillagerOptimizerCommand {
Villager.Profession profession = villager.getProfession();
if (profession.equals(Villager.Profession.NITWIT) || profession.equals(Villager.Profession.NONE)) continue;
WrappedVillager wVillager = wrapperCache.get(villager);
WrappedVillager wVillager = VillagerOptimizer.getCache().get(villager, WrappedVillager::new);
if (player_has_cooldown_bypass || wVillager.canOptimize(cooldown)) {
VillagerOptimizeEvent optimizeEvent = new VillagerOptimizeEvent(wVillager, OptimizationType.COMMAND, player);

View File

@ -1,6 +1,5 @@
package me.xginko.villageroptimizer.commands.unoptimizevillagers;
import me.xginko.villageroptimizer.WrapperCache;
import me.xginko.villageroptimizer.VillagerOptimizer;
import me.xginko.villageroptimizer.commands.VillagerOptimizerCommand;
import me.xginko.villageroptimizer.enums.OptimizationType;
@ -85,7 +84,6 @@ public class UnOptVillagersRadius extends VillagerOptimizerCommand {
return true;
}
WrapperCache wrapperCache = VillagerOptimizer.getCache();
int successCount = 0;
for (Entity entity : player.getNearbyEntities(safeRadius, safeRadius, safeRadius)) {
@ -94,7 +92,7 @@ public class UnOptVillagersRadius extends VillagerOptimizerCommand {
Villager.Profession profession = villager.getProfession();
if (profession.equals(Villager.Profession.NITWIT) || profession.equals(Villager.Profession.NONE)) continue;
WrappedVillager wVillager = wrapperCache.get(villager);
WrappedVillager wVillager = VillagerOptimizer.getCache().get(villager, WrappedVillager::new);
if (wVillager.isOptimized()) {
VillagerUnoptimizeEvent unOptimizeEvent = new VillagerUnoptimizeEvent(wVillager, player, OptimizationType.COMMAND);

View File

@ -4,6 +4,7 @@ import com.cryptomorin.xseries.XEntityType;
import me.xginko.villageroptimizer.utils.ExpiringSet;
import me.xginko.villageroptimizer.utils.LocationUtil;
import me.xginko.villageroptimizer.utils.Util;
import me.xginko.villageroptimizer.wrapper.WrappedVillager;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.entity.Entity;
@ -183,7 +184,7 @@ public class VillagerChunkLimit extends VillagerOptimizerModule implements Runna
// Ignore villager if profession is not in the whitelist
if (use_whitelist && profession_whitelist.contains(villager.getProfession())) continue;
if (wrapperCache.get(villager).isOptimized()) {
if (wrapperCache.get(villager, WrappedVillager::new).isOptimized()) {
optimized_villagers.add(villager);
} else {
not_optimized_villagers.add(villager);

View File

@ -1,10 +1,12 @@
package me.xginko.villageroptimizer.modules;
import com.github.benmanes.caffeine.cache.Cache;
import me.xginko.villageroptimizer.VillagerOptimizer;
import me.xginko.villageroptimizer.WrapperCache;
import me.xginko.villageroptimizer.config.Config;
import me.xginko.villageroptimizer.utils.Disableable;
import me.xginko.villageroptimizer.utils.Enableable;
import me.xginko.villageroptimizer.wrapper.WrappedVillager;
import org.bukkit.entity.Villager;
import org.reflections.Reflections;
import org.reflections.scanners.Scanners;
import space.arim.morepaperlib.scheduling.GracefulScheduling;
@ -23,7 +25,7 @@ public abstract class VillagerOptimizerModule implements Enableable, Disableable
protected final VillagerOptimizer plugin;
protected final Config config;
protected final WrapperCache wrapperCache;
protected final Cache<Villager, WrappedVillager> wrapperCache;
protected final GracefulScheduling scheduling;
public final String configPath;
private final String logFormat;

View File

@ -4,6 +4,7 @@ import com.cryptomorin.xseries.XEntityType;
import com.cryptomorin.xseries.XMaterial;
import me.xginko.villageroptimizer.modules.VillagerOptimizerModule;
import me.xginko.villageroptimizer.utils.LocationUtil;
import me.xginko.villageroptimizer.wrapper.WrappedVillager;
import org.bukkit.GameMode;
import org.bukkit.entity.Player;
import org.bukkit.entity.Villager;
@ -53,7 +54,7 @@ public class EnableLeashingVillagers extends VillagerOptimizerModule implements
final Villager villager = (Villager) event.getRightClicked();
if (villager.isLeashed()) return;
if (only_optimized && !wrapperCache.get(villager).isOptimized()) return;
if (only_optimized && !wrapperCache.get(villager, WrappedVillager::new).isOptimized()) return;
event.setCancelled(true); // Cancel the event, so we don't interact with the villager

View File

@ -39,7 +39,7 @@ public class FixOptimisationAfterCure extends VillagerOptimizerModule implements
) {
Villager villager = (Villager) event.getTransformedEntity();
scheduling.entitySpecificScheduler(villager).runDelayed(() -> {
WrappedVillager wVillager = wrapperCache.get(villager);
WrappedVillager wVillager = wrapperCache.get(villager, WrappedVillager::new);
wVillager.setOptimizationType(wVillager.getOptimizationType());
}, null, 40L);
}

View File

@ -65,7 +65,7 @@ public class LevelOptimizedProfession extends VillagerOptimizerModule implements
&& event.getInventory().getHolder() instanceof Villager
) {
final Villager villager = (Villager) event.getInventory().getHolder();
final WrappedVillager wVillager = wrapperCache.get(villager);
final WrappedVillager wVillager = wrapperCache.get(villager, WrappedVillager::new);
if (!wVillager.isOptimized()) return;
if (wVillager.canLevelUp(cooldown_millis)) {

View File

@ -2,6 +2,7 @@ package me.xginko.villageroptimizer.modules.gameplay;
import com.cryptomorin.xseries.XEntityType;
import me.xginko.villageroptimizer.modules.VillagerOptimizerModule;
import me.xginko.villageroptimizer.wrapper.WrappedVillager;
import org.bukkit.entity.Villager;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -65,7 +66,7 @@ public class PreventOptimizedDamage extends VillagerOptimizerModule implements L
if (
event.getEntityType() == XEntityType.VILLAGER.get()
&& damage_causes_to_cancel.contains(event.getCause())
&& wrapperCache.get((Villager) event.getEntity()).isOptimized()
&& wrapperCache.get((Villager) event.getEntity(), WrappedVillager::new).isOptimized()
) {
event.setCancelled(true);
}
@ -76,7 +77,7 @@ public class PreventOptimizedDamage extends VillagerOptimizerModule implements L
if (
cancel_knockback
&& event.getEntityType() == XEntityType.VILLAGER.get()
&& wrapperCache.get((Villager) event.getEntity()).isOptimized()
&& wrapperCache.get((Villager) event.getEntity(), WrappedVillager::new).isOptimized()
) {
event.setCancelled(true);
}

View File

@ -2,6 +2,7 @@ package me.xginko.villageroptimizer.modules.gameplay;
import com.cryptomorin.xseries.XEntityType;
import me.xginko.villageroptimizer.modules.VillagerOptimizerModule;
import me.xginko.villageroptimizer.wrapper.WrappedVillager;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Mob;
import org.bukkit.entity.Villager;
@ -41,7 +42,7 @@ public class PreventOptimizedTargeting extends VillagerOptimizerModule implement
if (
target != null
&& target.getType() == XEntityType.VILLAGER.get()
&& wrapperCache.get((Villager) target).isOptimized()
&& wrapperCache.get((Villager) target, WrappedVillager::new).isOptimized()
) {
event.setTarget(null);
event.setCancelled(true);
@ -54,7 +55,7 @@ public class PreventOptimizedTargeting extends VillagerOptimizerModule implement
if (
target != null
&& target.getType() == XEntityType.VILLAGER.get()
&& wrapperCache.get((Villager) target).isOptimized()
&& wrapperCache.get((Villager) target, WrappedVillager::new).isOptimized()
) {
event.setCancelled(true);
}
@ -65,7 +66,7 @@ public class PreventOptimizedTargeting extends VillagerOptimizerModule implement
if (
event.getEntityType() == XEntityType.VILLAGER.get()
&& event.getDamager() instanceof Mob
&& wrapperCache.get((Villager) event.getEntity()).isOptimized()
&& wrapperCache.get((Villager) event.getEntity(), WrappedVillager::new).isOptimized()
) {
((Mob) event.getDamager()).setTarget(null);
}

View File

@ -4,6 +4,7 @@ import me.xginko.villageroptimizer.VillagerOptimizer;
import me.xginko.villageroptimizer.enums.Permissions;
import me.xginko.villageroptimizer.modules.VillagerOptimizerModule;
import me.xginko.villageroptimizer.utils.KyoriUtil;
import me.xginko.villageroptimizer.wrapper.WrappedVillager;
import org.bukkit.entity.Player;
import org.bukkit.entity.Villager;
import org.bukkit.event.EventHandler;
@ -48,7 +49,7 @@ public class PreventUnoptimizedTrading extends VillagerOptimizerModule implement
if (event.getInventory().getType() != InventoryType.MERCHANT) return;
if (event.getWhoClicked().hasPermission(Permissions.Bypass.TRADE_PREVENTION.get())) return;
if (!(event.getInventory().getHolder() instanceof Villager)) return;
if (wrapperCache.get((Villager) event.getInventory().getHolder()).isOptimized()) return;
if (wrapperCache.get((Villager) event.getInventory().getHolder(), WrappedVillager::new).isOptimized()) return;
event.setCancelled(true);
@ -63,7 +64,7 @@ public class PreventUnoptimizedTrading extends VillagerOptimizerModule implement
if (event.getInventory().getType() != InventoryType.MERCHANT) return;
if (event.getWhoClicked().hasPermission(Permissions.Bypass.TRADE_PREVENTION.get())) return;
if (!(event.getInventory().getHolder() instanceof Villager)) return;
if (wrapperCache.get((Villager) event.getInventory().getHolder()).isOptimized()) return;
if (wrapperCache.get((Villager) event.getInventory().getHolder(), WrappedVillager::new).isOptimized()) return;
event.setCancelled(true);

View File

@ -55,27 +55,27 @@ public class RestockOptimizedTrades extends VillagerOptimizerModule implements L
private void onInteract(PlayerInteractEntityEvent event) {
if (event.getRightClicked().getType() != XEntityType.VILLAGER.get()) return;
final WrappedVillager wVillager = wrapperCache.get((Villager) event.getRightClicked());
if (!wVillager.isOptimized()) return;
final WrappedVillager wrapped = wrapperCache.get((Villager) event.getRightClicked(), WrappedVillager::new);
if (!wrapped.isOptimized()) return;
final Player player = event.getPlayer();
final boolean player_bypassing = player.hasPermission(Permissions.Bypass.RESTOCK_COOLDOWN.get());
if (!wVillager.canRestock(restock_delay_millis) && !player_bypassing) return;
if (!wrapped.canRestock(restock_delay_millis) && !player_bypassing) return;
wVillager.restock();
wVillager.saveRestockTime();
wrapped.restock();
wrapped.saveRestockTime();
if (notify_player && !player_bypassing) {
final TextReplacementConfig timeLeft = TextReplacementConfig.builder()
.matchLiteral("%time%")
.replacement(Util.formatDuration(Duration.ofMillis(wVillager.getRestockCooldownMillis(restock_delay_millis))))
.replacement(Util.formatDuration(Duration.ofMillis(wrapped.getRestockCooldownMillis(restock_delay_millis))))
.build();
VillagerOptimizer.getLang(player.locale()).trades_restocked
.forEach(line -> KyoriUtil.sendMessage(player, line.replaceText(timeLeft)));
}
if (log_enabled) {
info("Restocked optimized villager at " + LocationUtil.toString(wVillager.villager().getLocation()));
info("Restocked optimized villager at " + LocationUtil.toString(wrapped.villager.getLocation()));
}
}
}

View File

@ -35,9 +35,9 @@ public class UnoptimizeOnJobLoose extends VillagerOptimizerModule implements Lis
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
private void onJobReset(VillagerCareerChangeEvent event) {
if (event.getReason() != VillagerCareerChangeEvent.ChangeReason.LOSING_JOB) return;
final WrappedVillager wrappedVillager = wrapperCache.get(event.getEntity());
if (wrappedVillager.isOptimized()) {
wrappedVillager.setOptimizationType(OptimizationType.NONE);
final WrappedVillager wrapped = wrapperCache.get(event.getEntity(), WrappedVillager::new);
if (wrapped.isOptimized()) {
wrapped.setOptimizationType(OptimizationType.NONE);
}
}
}

View File

@ -34,7 +34,7 @@ public class VisuallyHighlightOptimized extends VillagerOptimizerModule implemen
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
private void onOptimize(VillagerOptimizeEvent event) {
Villager villager = event.getWrappedVillager().villager();
Villager villager = event.getWrappedVillager().villager;
scheduling.entitySpecificScheduler(villager).run(glow -> {
if (!villager.isGlowing()) villager.setGlowing(true);
}, null);
@ -42,7 +42,7 @@ public class VisuallyHighlightOptimized extends VillagerOptimizerModule implemen
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
private void onUnOptimize(VillagerUnoptimizeEvent event) {
Villager villager = event.getWrappedVillager().villager();
Villager villager = event.getWrappedVillager().villager;
scheduling.entitySpecificScheduler(villager).run(unGlow -> {
if (villager.isGlowing()) villager.setGlowing(false);
}, null);

View File

@ -111,7 +111,7 @@ public class OptimizeByBlock extends VillagerOptimizerModule implements Listener
final double distance = LocationUtil.relDistance3DSquared(villager.getLocation(), blockLoc);
if (distance >= closestDistance) continue;
final WrappedVillager wVillager = wrapperCache.get(villager);
final WrappedVillager wVillager = wrapperCache.get(villager, WrappedVillager::new);
if (wVillager.canOptimize(cooldown_millis)) {
closestOptimizableVillager = wVillager;
closestDistance = distance;
@ -135,7 +135,7 @@ public class OptimizeByBlock extends VillagerOptimizerModule implements Listener
if (notify_player) {
final TextReplacementConfig vilProfession = TextReplacementConfig.builder()
.matchLiteral("%vil_profession%")
.replacement(Util.toNiceString(closestOptimizableVillager.villager().getProfession()))
.replacement(Util.toNiceString(closestOptimizableVillager.villager.getProfession()))
.build();
final TextReplacementConfig placedMaterial = TextReplacementConfig.builder()
.matchLiteral("%blocktype%")
@ -147,7 +147,7 @@ public class OptimizeByBlock extends VillagerOptimizerModule implements Listener
if (log_enabled) {
info(player.getName() + " optimized villager at " +
LocationUtil.toString(closestOptimizableVillager.villager().getLocation()));
LocationUtil.toString(closestOptimizableVillager.villager.getLocation()));
}
} else {
closestOptimizableVillager.sayNo();
@ -178,7 +178,7 @@ public class OptimizeByBlock extends VillagerOptimizerModule implements Listener
final double distance = LocationUtil.relDistance3DSquared(villager.getLocation(), blockLoc);
if (distance >= closestDistance) continue;
final WrappedVillager wVillager = wrapperCache.get(villager);
final WrappedVillager wVillager = wrapperCache.get(villager, WrappedVillager::new);
if (wVillager.isOptimized()) {
closestOptimizedVillager = wVillager;
closestDistance = distance;
@ -200,7 +200,7 @@ public class OptimizeByBlock extends VillagerOptimizerModule implements Listener
if (notify_player) {
final TextReplacementConfig vilProfession = TextReplacementConfig.builder()
.matchLiteral("%vil_profession%")
.replacement(Util.toNiceString(closestOptimizedVillager.villager().getProfession()))
.replacement(Util.toNiceString(closestOptimizedVillager.villager.getProfession()))
.build();
final TextReplacementConfig brokenMaterial = TextReplacementConfig.builder()
.matchLiteral("%blocktype%")
@ -212,7 +212,7 @@ public class OptimizeByBlock extends VillagerOptimizerModule implements Listener
if (log_enabled) {
info(player.getName() + " unoptimized villager using " + Util.toNiceString(broken.getType()) +
LocationUtil.toString(closestOptimizedVillager.villager().getLocation()));
LocationUtil.toString(closestOptimizedVillager.villager.getLocation()));
}
}
}

View File

@ -85,13 +85,12 @@ public class OptimizeByNametag extends VillagerOptimizerModule implements Listen
if (!meta.hasDisplayName()) return;
final String nameTagPlainText = ChatColor.stripColor(meta.getDisplayName());
final Villager villager = (Villager) event.getRightClicked();
final WrappedVillager wVillager = wrapperCache.get(villager);
final WrappedVillager wrapped = wrapperCache.get((Villager) event.getRightClicked(), WrappedVillager::new);
if (nametags.contains(nameTagPlainText.toLowerCase())) {
if (wVillager.canOptimize(cooldown) || player.hasPermission(Permissions.Bypass.NAMETAG_COOLDOWN.get())) {
if (wrapped.canOptimize(cooldown) || player.hasPermission(Permissions.Bypass.NAMETAG_COOLDOWN.get())) {
VillagerOptimizeEvent optimizeEvent = new VillagerOptimizeEvent(
wVillager,
wrapped,
OptimizationType.NAMETAG,
player,
event.isAsynchronous()
@ -104,8 +103,8 @@ public class OptimizeByNametag extends VillagerOptimizerModule implements Listen
player.updateInventory();
}
wVillager.setOptimizationType(optimizeEvent.getOptimizationType());
wVillager.saveOptimizeTime();
wrapped.setOptimizationType(optimizeEvent.getOptimizationType());
wrapped.saveOptimizeTime();
if (notify_player) {
VillagerOptimizer.getLang(player.locale()).nametag_optimize_success
@ -114,31 +113,31 @@ public class OptimizeByNametag extends VillagerOptimizerModule implements Listen
if (log_enabled) {
info(player.getName() + " optimized villager using nametag '" + nameTagPlainText + "' at " +
LocationUtil.toString(wVillager.villager().getLocation()));
LocationUtil.toString(wrapped.villager.getLocation()));
}
} else {
event.setCancelled(true);
wVillager.sayNo();
wrapped.sayNo();
if (notify_player) {
final TextReplacementConfig timeLeft = TextReplacementConfig.builder()
.matchLiteral("%time%")
.replacement(Util.formatDuration(Duration.ofMillis(wVillager.getOptimizeCooldownMillis(cooldown))))
.replacement(Util.formatDuration(Duration.ofMillis(wrapped.getOptimizeCooldownMillis(cooldown))))
.build();
VillagerOptimizer.getLang(player.locale()).nametag_on_optimize_cooldown
.forEach(line -> KyoriUtil.sendMessage(player, line.replaceText(timeLeft)));
}
}
} else {
if (wVillager.isOptimized()) {
if (wrapped.isOptimized()) {
VillagerUnoptimizeEvent unOptimizeEvent = new VillagerUnoptimizeEvent(
wVillager,
wrapped,
player,
OptimizationType.NAMETAG,
event.isAsynchronous()
);
if (!unOptimizeEvent.callEvent()) return;
wVillager.setOptimizationType(OptimizationType.NONE);
wrapped.setOptimizationType(OptimizationType.NONE);
if (notify_player) {
VillagerOptimizer.getLang(player.locale()).nametag_unoptimize_success
@ -147,7 +146,7 @@ public class OptimizeByNametag extends VillagerOptimizerModule implements Listen
if (log_enabled) {
info(player.getName() + " unoptimized villager using nametag '" + nameTagPlainText + "' at " +
LocationUtil.toString(wVillager.villager().getLocation()));
LocationUtil.toString(wrapped.villager.getLocation()));
}
}
}

View File

@ -94,7 +94,7 @@ public class OptimizeByWorkstation extends VillagerOptimizerModule implements Li
for (Villager villager : workstationLoc.getNearbyEntitiesByType(Villager.class, search_radius)) {
scheduling.entitySpecificScheduler(villager).run(() -> {
if (villager.getProfession() != workstationProfession) return;
WrappedVillager wrapped = wrapperCache.get(villager);
WrappedVillager wrapped = wrapperCache.get(villager, WrappedVillager::new);
Location jobSite = wrapped.getJobSite();
if (jobSite == null || jobSite.getWorld().getUID() != workstationLoc.getWorld().getUID()) return;
@ -131,7 +131,7 @@ public class OptimizeByWorkstation extends VillagerOptimizerModule implements Li
if (notify_player) {
final TextReplacementConfig vilProfession = TextReplacementConfig.builder()
.matchLiteral("%vil_profession%")
.replacement(Util.toNiceString(wrapped.villager().getProfession()))
.replacement(Util.toNiceString(wrapped.villager.getProfession()))
.build();
final TextReplacementConfig placedWorkstation = TextReplacementConfig.builder()
.matchLiteral("%blocktype%")
@ -143,7 +143,7 @@ public class OptimizeByWorkstation extends VillagerOptimizerModule implements Li
if (log_enabled) {
info(player.getName() + " optimized villager using workstation " + Util.toNiceString(placed.getType()) + " at " +
LocationUtil.toString(wrapped.villager().getLocation()));
LocationUtil.toString(wrapped.villager.getLocation()));
}
taskComplete.set(true);
@ -171,7 +171,7 @@ public class OptimizeByWorkstation extends VillagerOptimizerModule implements Li
final double distance = LocationUtil.relDistance3DSquared(villager.getLocation(), workstationLoc);
if (distance >= closestDistance) continue;
WrappedVillager wrapped = wrapperCache.get(villager);
WrappedVillager wrapped = wrapperCache.get(villager, WrappedVillager::new);
if (wrapped.isOptimized()) {
closestOptimized = wrapped;
@ -195,7 +195,7 @@ public class OptimizeByWorkstation extends VillagerOptimizerModule implements Li
if (notify_player) {
final TextReplacementConfig vilProfession = TextReplacementConfig.builder()
.matchLiteral("%vil_profession%")
.replacement(Util.toNiceString(closestOptimized.villager().getProfession()))
.replacement(Util.toNiceString(closestOptimized.villager.getProfession()))
.build();
final TextReplacementConfig brokenWorkstation = TextReplacementConfig.builder()
.matchLiteral("%blocktype%")
@ -207,7 +207,7 @@ public class OptimizeByWorkstation extends VillagerOptimizerModule implements Li
if (log_enabled) {
info(player.getName() + " unoptimized villager using workstation " + Util.toNiceString(broken.getType()) + " at " +
LocationUtil.toString(closestOptimized.villager().getLocation()));
LocationUtil.toString(closestOptimized.villager.getLocation()));
}
}
}

View File

@ -4,51 +4,58 @@ import me.xginko.villageroptimizer.VillagerOptimizer;
import me.xginko.villageroptimizer.enums.Keyring;
import me.xginko.villageroptimizer.enums.OptimizationType;
import org.bukkit.entity.Villager;
import org.bukkit.persistence.PersistentDataContainer;
import org.jetbrains.annotations.NotNull;
public interface VillagerDataHandler {
public abstract class PDCWrapper {
static VillagerDataHandler[] forVillager(Villager villager) {
public final Villager villager;
public final PersistentDataContainer dataContainer;
public PDCWrapper(Villager villager) {
this.villager = villager;
this.dataContainer = villager.getPersistentDataContainer();
}
public static PDCWrapper[] forVillager(Villager villager) {
if (VillagerOptimizer.config().support_other_plugins) {
return new VillagerDataHandler[]{
new MainVillagerDataHandlerImpl(villager),
new AVLVillagerDataHandlerImpl(villager)
};
return new PDCWrapper[]{new PDCWrapperVO(villager), new PDCWrapperAVL(villager)};
} else {
return new VillagerDataHandler[]{ new MainVillagerDataHandlerImpl(villager) };
return new PDCWrapper[]{new PDCWrapperVO(villager)};
}
}
/**
* @return The namespace of the handler
*/
Keyring.Space getSpace();
public abstract Keyring.Space getSpace();
/**
* @return True if the villager is optimized by plugin, otherwise false.
*/
boolean isOptimized();
public abstract boolean isOptimized();
/**
* @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.
*/
boolean canOptimize(long cooldown_millis);
public abstract boolean canOptimize(long cooldown_millis);
/**
* @param type OptimizationType the villager should be set to.
*/
void setOptimizationType(OptimizationType type);
public abstract void setOptimizationType(OptimizationType type);
/**
* @return The current OptimizationType of the villager.
*/
@NotNull OptimizationType getOptimizationType();
@NotNull
public abstract OptimizationType getOptimizationType();
/**
* Saves the system time when the villager was last optimized.
*/
void saveOptimizeTime();
public abstract void saveOptimizeTime();
/**
* For convenience so the remaining millis since the last stored optimize time
@ -58,7 +65,7 @@ public interface VillagerDataHandler {
* @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.
*/
long getOptimizeCooldownMillis(long cooldown_millis);
public abstract long getOptimizeCooldownMillis(long cooldown_millis);
/**
* For convenience so the remaining millis since the last stored restock time
@ -67,12 +74,12 @@ public interface VillagerDataHandler {
* @param cooldown_millis The configured cooldown in milliseconds you want to check against.
* @return True if the villager has been loaded long enough.
*/
boolean canRestock(long cooldown_millis);
public abstract boolean canRestock(long cooldown_millis);
/**
* Saves the time of when the entity was last restocked.
*/
void saveRestockTime();
public abstract void saveRestockTime();
/**
* For convenience so the remaining millis since the last stored restock time
@ -82,18 +89,18 @@ public interface VillagerDataHandler {
* @param cooldown_millis The configured cooldown in milliseconds you want to check against.
* @return The time left in millis until the villager can be restocked again.
*/
long getRestockCooldownMillis(long cooldown_millis);
public abstract long getRestockCooldownMillis(long cooldown_millis);
/**
* @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
*/
boolean canLevelUp(long cooldown_millis);
public abstract boolean canLevelUp(long cooldown_millis);
/**
* Saves the time of the in-game world when the entity was last leveled up.
*/
void saveLastLevelUp();
public abstract void saveLastLevelUp();
/**
* Here for convenience so the remaining millis since the last stored level-up time
@ -101,5 +108,5 @@ public interface VillagerDataHandler {
*
* @return The time of the in-game world when the entity was last leveled up.
*/
long getLevelCooldownMillis(long cooldown_millis);
public abstract long getLevelCooldownMillis(long cooldown_millis);
}

View File

@ -4,20 +4,15 @@ import me.xginko.villageroptimizer.VillagerOptimizer;
import me.xginko.villageroptimizer.enums.Keyring;
import me.xginko.villageroptimizer.enums.OptimizationType;
import org.bukkit.entity.Villager;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.TimeUnit;
public class AVLVillagerDataHandlerImpl implements VillagerDataHandler {
public final class PDCWrapperAVL extends PDCWrapper {
private final @NotNull Villager villager;
private final @NotNull PersistentDataContainer dataContainer;
AVLVillagerDataHandlerImpl(@NotNull Villager villager) {
this.villager = villager;
this.dataContainer = villager.getPersistentDataContainer();
PDCWrapperAVL(@NotNull Villager villager) {
super(villager);
}
@Override

View File

@ -4,18 +4,13 @@ import me.xginko.villageroptimizer.VillagerOptimizer;
import me.xginko.villageroptimizer.enums.Keyring;
import me.xginko.villageroptimizer.enums.OptimizationType;
import org.bukkit.entity.Villager;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
public class MainVillagerDataHandlerImpl implements VillagerDataHandler {
public final class PDCWrapperVO extends PDCWrapper {
private final @NotNull Villager villager;
private final @NotNull PersistentDataContainer dataContainer;
MainVillagerDataHandlerImpl(@NotNull Villager villager) {
this.villager = villager;
this.dataContainer = villager.getPersistentDataContainer();
PDCWrapperVO(@NotNull Villager villager) {
super(villager);
}
@Override

View File

@ -10,21 +10,13 @@ import org.bukkit.inventory.MerchantRecipe;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class WrappedVillager implements VillagerDataHandler {
public class WrappedVillager extends PDCWrapper {
private final @NotNull Villager villager;
private final @NotNull VillagerDataHandler[] dataHandlers;
private final @NotNull PDCWrapper[] pdcWrappers;
public WrappedVillager(@NotNull Villager villager) {
this.villager = villager;
this.dataHandlers = VillagerDataHandler.forVillager(villager);
}
/**
* @return The villager inside the wrapper.
*/
public @NotNull Villager villager() {
return villager;
super(villager);
this.pdcWrappers = PDCWrapper.forVillager(villager);
}
/**
@ -50,7 +42,7 @@ public class WrappedVillager implements VillagerDataHandler {
}
/**
* @return true if the villager can loose his acquired profession by having their workstation destroyed.
* @return true if the villager can lose its acquired profession by having its workstation destroyed.
*/
public boolean canLooseProfession() {
// A villager with a level of 1 and no trading experience is liable to lose its profession.
@ -76,8 +68,8 @@ public class WrappedVillager implements VillagerDataHandler {
@Override
public boolean isOptimized() {
for (VillagerDataHandler handler : dataHandlers) {
if (handler.isOptimized()) {
for (PDCWrapper pdcWrapper : pdcWrappers) {
if (pdcWrapper.isOptimized()) {
return true;
}
}
@ -86,8 +78,8 @@ public class WrappedVillager implements VillagerDataHandler {
@Override
public boolean canOptimize(long cooldown_millis) {
for (VillagerDataHandler handler : dataHandlers) {
if (!handler.canOptimize(cooldown_millis)) {
for (PDCWrapper pdcWrapper : pdcWrappers) {
if (!pdcWrapper.canOptimize(cooldown_millis)) {
return false;
}
}
@ -96,18 +88,18 @@ public class WrappedVillager implements VillagerDataHandler {
@Override
public void setOptimizationType(OptimizationType type) {
for (VillagerDataHandler handler : dataHandlers) {
handler.setOptimizationType(type);
for (PDCWrapper pdcWrapper : pdcWrappers) {
pdcWrapper.setOptimizationType(type);
}
}
@Override
public @NotNull OptimizationType getOptimizationType() {
OptimizationType result = OptimizationType.NONE;
for (VillagerDataHandler handler : dataHandlers) {
OptimizationType type = handler.getOptimizationType();
for (PDCWrapper pdcWrapper : pdcWrappers) {
OptimizationType type = pdcWrapper.getOptimizationType();
if (type != OptimizationType.NONE) {
if (handler.getSpace() == Keyring.Space.VillagerOptimizer) {
if (pdcWrapper.getSpace() == Keyring.Space.VillagerOptimizer) {
return type;
} else {
result = type;
@ -119,24 +111,24 @@ public class WrappedVillager implements VillagerDataHandler {
@Override
public void saveOptimizeTime() {
for (VillagerDataHandler handler : dataHandlers) {
handler.saveOptimizeTime();
for (PDCWrapper pdcWrapper : pdcWrappers) {
pdcWrapper.saveOptimizeTime();
}
}
@Override
public long getOptimizeCooldownMillis(long cooldown_millis) {
long cooldown = 0L;
for (VillagerDataHandler handler : dataHandlers) {
cooldown = Math.max(cooldown, handler.getOptimizeCooldownMillis(cooldown_millis));
for (PDCWrapper pdcWrapper : pdcWrappers) {
cooldown = Math.max(cooldown, pdcWrapper.getOptimizeCooldownMillis(cooldown_millis));
}
return cooldown;
}
@Override
public boolean canRestock(long cooldown_millis) {
for (VillagerDataHandler handler : dataHandlers) {
if (!handler.canRestock(cooldown_millis)) {
for (PDCWrapper pdcWrapper : pdcWrappers) {
if (!pdcWrapper.canRestock(cooldown_millis)) {
return false;
}
}
@ -145,24 +137,24 @@ public class WrappedVillager implements VillagerDataHandler {
@Override
public void saveRestockTime() {
for (VillagerDataHandler handler : dataHandlers) {
handler.saveRestockTime();
for (PDCWrapper pdcWrapper : pdcWrappers) {
pdcWrapper.saveRestockTime();
}
}
@Override
public long getRestockCooldownMillis(long cooldown_millis) {
long cooldown = cooldown_millis;
for (VillagerDataHandler handler : dataHandlers) {
cooldown = Math.max(cooldown, handler.getRestockCooldownMillis(cooldown_millis));
for (PDCWrapper pdcWrapper : pdcWrappers) {
cooldown = Math.max(cooldown, pdcWrapper.getRestockCooldownMillis(cooldown_millis));
}
return cooldown;
}
@Override
public boolean canLevelUp(long cooldown_millis) {
for (VillagerDataHandler handler : dataHandlers) {
if (!handler.canLevelUp(cooldown_millis)) {
for (PDCWrapper pdcWrapper : pdcWrappers) {
if (!pdcWrapper.canLevelUp(cooldown_millis)) {
return false;
}
}
@ -171,16 +163,16 @@ public class WrappedVillager implements VillagerDataHandler {
@Override
public void saveLastLevelUp() {
for (VillagerDataHandler handler : dataHandlers) {
handler.saveLastLevelUp();
for (PDCWrapper pdcWrapper : pdcWrappers) {
pdcWrapper.saveLastLevelUp();
}
}
@Override
public long getLevelCooldownMillis(long cooldown_millis) {
long cooldown = cooldown_millis;
for (VillagerDataHandler handler : dataHandlers) {
cooldown = Math.max(cooldown, handler.getLevelCooldownMillis(cooldown_millis));
for (PDCWrapper pdcWrapper : pdcWrappers) {
cooldown = Math.max(cooldown, pdcWrapper.getLevelCooldownMillis(cooldown_millis));
}
return cooldown;
}