refactor wrappercache

This commit is contained in:
xGinko 2024-07-09 04:24:23 +02:00
parent c05ec30330
commit b94e158465
20 changed files with 70 additions and 96 deletions

View File

@ -1,57 +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.wrapper.WrappedVillager;
import org.bukkit.entity.Villager;
import org.jetbrains.annotations.NotNull;
import java.time.Duration;
import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
public final class VillagerCache implements Disableable {
private final @NotNull Cache<UUID, WrappedVillager> villagerCache;
public VillagerCache(long expireAfterWriteSeconds) {
this.villagerCache = Caffeine.newBuilder().expireAfterWrite(Duration.ofSeconds(expireAfterWriteSeconds)).build();
}
public @NotNull ConcurrentMap<UUID, WrappedVillager> cacheMap() {
return this.villagerCache.asMap();
}
@Override
public void disable() {
this.villagerCache.invalidateAll();
this.villagerCache.cleanUp();
}
public @NotNull WrappedVillager createIfAbsent(@NotNull Villager villager) {
WrappedVillager wrappedVillager = this.villagerCache.getIfPresent(villager.getUniqueId());
return wrappedVillager == null ? this.add(new WrappedVillager(villager)) : this.add(wrappedVillager);
}
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());
}
}

View File

@ -41,7 +41,7 @@ import java.util.zip.ZipEntry;
public final class VillagerOptimizer extends JavaPlugin {
private static VillagerOptimizer instance;
private static VillagerCache villagerCache;
private static WrapperCache wrapperCache;
private static CommandRegistration commandRegistration;
private static GracefulScheduling scheduling;
private static Map<String, LanguageCache> languageCacheMap;
@ -121,9 +121,9 @@ public final class VillagerOptimizer extends JavaPlugin {
scheduling.cancelGlobalTasks();
scheduling = null;
}
if (villagerCache != null) {
villagerCache.disable();
villagerCache = null;
if (wrapperCache != null) {
wrapperCache.disable();
wrapperCache = null;
}
if (audiences != null) {
audiences.close();
@ -145,8 +145,8 @@ public final class VillagerOptimizer extends JavaPlugin {
public static @NotNull Config config() {
return config;
}
public static @NotNull VillagerCache getCache() {
return villagerCache;
public static @NotNull WrapperCache getCache() {
return wrapperCache;
}
public static @NotNull CommandRegistration commandRegistration() {
return commandRegistration;
@ -179,8 +179,8 @@ public final class VillagerOptimizer extends JavaPlugin {
private void reloadConfiguration() {
try {
config = new Config();
if (villagerCache != null) villagerCache.disable();
villagerCache = new VillagerCache(config.cache_keep_time_seconds);
if (wrapperCache != null) wrapperCache.disable();
wrapperCache = new WrapperCache(config.cache_keep_time);
VillagerOptimizerCommand.reloadCommands();
VillagerOptimizerModule.reloadModules();
config.saveConfig();

View File

@ -0,0 +1,31 @@
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.wrapper.WrappedVillager;
import org.bukkit.entity.Villager;
import org.jetbrains.annotations.NotNull;
import java.time.Duration;
import java.util.UUID;
public final class WrapperCache implements Disableable {
private final @NotNull Cache<UUID, WrappedVillager> wrapperCache;
public WrapperCache(Duration cacheDuration) {
this.wrapperCache = Caffeine.newBuilder().expireAfterWrite(cacheDuration).build();
}
@Override
public void disable() {
this.wrapperCache.invalidateAll();
this.wrapperCache.cleanUp();
}
@SuppressWarnings("DataFlowIssue")
public @NotNull WrappedVillager get(@NotNull Villager villager) {
return this.wrapperCache.get(villager.getUniqueId(), k -> new WrappedVillager(villager));
}
}

View File

@ -1,6 +1,6 @@
package me.xginko.villageroptimizer.commands.optimizevillagers;
import me.xginko.villageroptimizer.VillagerCache;
import me.xginko.villageroptimizer.WrapperCache;
import me.xginko.villageroptimizer.VillagerOptimizer;
import me.xginko.villageroptimizer.commands.VillagerOptimizerCommand;
import me.xginko.villageroptimizer.config.Config;
@ -90,7 +90,7 @@ public class OptVillagersRadius extends VillagerOptimizerCommand {
return true;
}
VillagerCache villagerCache = VillagerOptimizer.getCache();
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 +101,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 = villagerCache.createIfAbsent(villager);
WrappedVillager wVillager = wrapperCache.get(villager);
if (player_has_cooldown_bypass || wVillager.canOptimize(cooldown)) {
VillagerOptimizeEvent optimizeEvent = new VillagerOptimizeEvent(wVillager, OptimizationType.COMMAND, player);

View File

@ -1,6 +1,6 @@
package me.xginko.villageroptimizer.commands.unoptimizevillagers;
import me.xginko.villageroptimizer.VillagerCache;
import me.xginko.villageroptimizer.WrapperCache;
import me.xginko.villageroptimizer.VillagerOptimizer;
import me.xginko.villageroptimizer.commands.VillagerOptimizerCommand;
import me.xginko.villageroptimizer.enums.OptimizationType;
@ -85,7 +85,7 @@ public class UnOptVillagersRadius extends VillagerOptimizerCommand {
return true;
}
VillagerCache villagerCache = VillagerOptimizer.getCache();
WrapperCache wrapperCache = VillagerOptimizer.getCache();
int successCount = 0;
for (Entity entity : player.getNearbyEntities(safeRadius, safeRadius, safeRadius)) {
@ -94,7 +94,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 = villagerCache.createIfAbsent(villager);
WrappedVillager wVillager = wrapperCache.get(villager);
if (wVillager.isOptimized()) {
VillagerUnoptimizeEvent unOptimizeEvent = new VillagerUnoptimizeEvent(wVillager, player, OptimizationType.COMMAND);

View File

@ -45,7 +45,6 @@ public class DisableSubCmd extends SubCommand {
KyoriUtil.sendMessage(sender, Component.text("Disabling VillagerOptimizer...").color(NamedTextColor.RED));
VillagerOptimizerModule.ENABLED_MODULES.forEach(VillagerOptimizerModule::disable);
VillagerOptimizerModule.ENABLED_MODULES.clear();
VillagerOptimizer.getCache().cacheMap().clear();
KyoriUtil.sendMessage(sender, Component.text("Disabled all plugin listeners and tasks.").color(NamedTextColor.GREEN));
KyoriUtil.sendMessage(sender, Component.text("You can enable the plugin again using the reload command.").color(NamedTextColor.YELLOW));
return true;

View File

@ -5,6 +5,7 @@ import me.xginko.villageroptimizer.VillagerOptimizer;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.time.Duration;
import java.util.List;
import java.util.Locale;
@ -12,8 +13,8 @@ public class Config {
private final @NotNull ConfigFile config;
public final @NotNull Locale default_lang;
public final @NotNull Duration cache_keep_time;
public final boolean auto_lang, support_other_plugins;
public final long cache_keep_time_seconds;
public Config() throws Exception {
// Load config.yml with ConfigMaster
@ -28,8 +29,8 @@ public class Config {
.replace("_", "-"));
this.auto_lang = getBoolean("general.auto-language", true,
"If set to true, will display messages based on client language");
this.cache_keep_time_seconds = getInt("general.cache-keep-time-seconds", 30,
"The amount of time in seconds a villager will be kept in the plugin's cache.");
this.cache_keep_time = Duration.ofSeconds(Math.max(1, getInt("general.cache-keep-time-seconds", 30,
"The amount of time in seconds a villager will be kept in the plugin's cache.")));
this.support_other_plugins = getBoolean("general.support-avl-villagers", false,
"Enable if you have previously used AntiVillagerLag\n" +
"(https://www.spigotmc.org/resources/antivillagerlag.102949/).\n" +

View File

@ -159,7 +159,7 @@ public class VillagerChunkLimit extends VillagerOptimizerModule implements Runna
Villager villager = (Villager) entity;
if (villagerCache.createIfAbsent(villager).isOptimized()) {
if (wrapperCache.get(villager).isOptimized()) {
optimized_villagers.add(villager);
} else {
not_optimized_villagers.add(villager);

View File

@ -1,6 +1,6 @@
package me.xginko.villageroptimizer.modules;
import me.xginko.villageroptimizer.VillagerCache;
import me.xginko.villageroptimizer.WrapperCache;
import me.xginko.villageroptimizer.VillagerOptimizer;
import me.xginko.villageroptimizer.config.Config;
import me.xginko.villageroptimizer.utils.Disableable;
@ -23,7 +23,7 @@ public abstract class VillagerOptimizerModule implements Enableable, Disableable
protected final VillagerOptimizer plugin;
protected final Config config;
protected final VillagerCache villagerCache;
protected final WrapperCache wrapperCache;
protected final GracefulScheduling scheduling;
public final String configPath;
private final String logFormat;
@ -31,7 +31,7 @@ public abstract class VillagerOptimizerModule implements Enableable, Disableable
public VillagerOptimizerModule(String configPath) {
this.plugin = VillagerOptimizer.getInstance();
this.config = VillagerOptimizer.config();
this.villagerCache = VillagerOptimizer.getCache();
this.wrapperCache = VillagerOptimizer.getCache();
this.scheduling = VillagerOptimizer.scheduling();
this.configPath = configPath;
shouldEnable(); // Ensure enable option is always first

View File

@ -53,7 +53,7 @@ public class EnableLeashingVillagers extends VillagerOptimizerModule implements
final Villager villager = (Villager) event.getRightClicked();
if (villager.isLeashed()) return;
if (only_optimized && !villagerCache.createIfAbsent(villager).isOptimized()) return;
if (only_optimized && !wrapperCache.get(villager).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 = villagerCache.createIfAbsent(villager);
WrappedVillager wVillager = wrapperCache.get(villager);
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 = villagerCache.createIfAbsent(villager);
final WrappedVillager wVillager = wrapperCache.get(villager);
if (!wVillager.isOptimized()) return;
if (wVillager.canLevelUp(cooldown_millis)) {

View File

@ -65,7 +65,7 @@ public class PreventOptimizedDamage extends VillagerOptimizerModule implements L
if (
event.getEntityType() == XEntityType.VILLAGER.get()
&& damage_causes_to_cancel.contains(event.getCause())
&& villagerCache.createIfAbsent((Villager) event.getEntity()).isOptimized()
&& wrapperCache.get((Villager) event.getEntity()).isOptimized()
) {
event.setCancelled(true);
}
@ -76,7 +76,7 @@ public class PreventOptimizedDamage extends VillagerOptimizerModule implements L
if (
cancel_knockback
&& event.getEntityType() == XEntityType.VILLAGER.get()
&& villagerCache.createIfAbsent((Villager) event.getEntity()).isOptimized()
&& wrapperCache.get((Villager) event.getEntity()).isOptimized()
) {
event.setCancelled(true);
}

View File

@ -41,7 +41,7 @@ public class PreventOptimizedTargeting extends VillagerOptimizerModule implement
if (
target != null
&& target.getType() == XEntityType.VILLAGER.get()
&& villagerCache.createIfAbsent((Villager) target).isOptimized()
&& wrapperCache.get((Villager) target).isOptimized()
) {
event.setTarget(null);
event.setCancelled(true);
@ -54,7 +54,7 @@ public class PreventOptimizedTargeting extends VillagerOptimizerModule implement
if (
target != null
&& target.getType() == XEntityType.VILLAGER.get()
&& villagerCache.createIfAbsent((Villager) target).isOptimized()
&& wrapperCache.get((Villager) target).isOptimized()
) {
event.setCancelled(true);
}
@ -65,7 +65,7 @@ public class PreventOptimizedTargeting extends VillagerOptimizerModule implement
if (
event.getEntityType() == XEntityType.VILLAGER.get()
&& event.getDamager() instanceof Mob
&& villagerCache.createIfAbsent((Villager) event.getEntity()).isOptimized()
&& wrapperCache.get((Villager) event.getEntity()).isOptimized()
) {
((Mob) event.getDamager()).setTarget(null);
}

View File

@ -48,7 +48,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 (villagerCache.createIfAbsent((Villager) event.getInventory().getHolder()).isOptimized()) return;
if (wrapperCache.get((Villager) event.getInventory().getHolder()).isOptimized()) return;
event.setCancelled(true);
@ -63,7 +63,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 (villagerCache.createIfAbsent((Villager) event.getInventory().getHolder()).isOptimized()) return;
if (wrapperCache.get((Villager) event.getInventory().getHolder()).isOptimized()) return;
event.setCancelled(true);

View File

@ -55,7 +55,7 @@ public class RestockOptimizedTrades extends VillagerOptimizerModule implements L
private void onInteract(PlayerInteractEntityEvent event) {
if (event.getRightClicked().getType() != XEntityType.VILLAGER.get()) return;
final WrappedVillager wVillager = villagerCache.createIfAbsent((Villager) event.getRightClicked());
final WrappedVillager wVillager = wrapperCache.get((Villager) event.getRightClicked());
if (!wVillager.isOptimized()) return;
final Player player = event.getPlayer();

View File

@ -35,7 +35,7 @@ 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 = villagerCache.createIfAbsent(event.getEntity());
final WrappedVillager wrappedVillager = wrapperCache.get(event.getEntity());
if (wrappedVillager.isOptimized()) {
wrappedVillager.setOptimizationType(OptimizationType.NONE);
}

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 = villagerCache.createIfAbsent(villager);
final WrappedVillager wVillager = wrapperCache.get(villager);
if (wVillager.canOptimize(cooldown_millis)) {
closestOptimizableVillager = wVillager;
closestDistance = distance;
@ -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 = villagerCache.createIfAbsent(villager);
final WrappedVillager wVillager = wrapperCache.get(villager);
if (wVillager.isOptimized()) {
closestOptimizedVillager = wVillager;
closestDistance = distance;

View File

@ -86,7 +86,7 @@ public class OptimizeByNametag extends VillagerOptimizerModule implements Listen
final String nameTagPlainText = ChatColor.stripColor(meta.getDisplayName());
final Villager villager = (Villager) event.getRightClicked();
final WrappedVillager wVillager = villagerCache.createIfAbsent(villager);
final WrappedVillager wVillager = wrapperCache.get(villager);
if (nametags.contains(nameTagPlainText.toLowerCase())) {
if (wVillager.canOptimize(cooldown) || player.hasPermission(Permissions.Bypass.NAMETAG_COOLDOWN.get())) {

View File

@ -93,7 +93,7 @@ public class OptimizeByWorkstation extends VillagerOptimizerModule implements Li
for (Villager villager : workstationLoc.getNearbyEntitiesByType(Villager.class, search_radius)) {
if (villager.getProfession() != workstationProfession) continue;
WrappedVillager wrapped = villagerCache.createIfAbsent(villager);
WrappedVillager wrapped = wrapperCache.get(villager);
if (wrapped.getJobSite() == null) continue;
if (wrapped.getJobSite().getWorld().getUID() != workstationLoc.getWorld().getUID()) continue;
if (LocationUtil.relDistance3DSquared(wrapped.getJobSite(), workstationLoc) > 1) continue;
@ -167,7 +167,7 @@ public class OptimizeByWorkstation extends VillagerOptimizerModule implements Li
final double distance = LocationUtil.relDistance3DSquared(villager.getLocation(), workstationLoc);
if (distance >= closestDistance) continue;
WrappedVillager wrapped = villagerCache.createIfAbsent(villager);
WrappedVillager wrapped = wrapperCache.get(villager);
if (wrapped.isOptimized()) {
closestOptimized = wrapped;