redsign helper methods into a wrapper and utilize caching
This commit is contained in:
parent
d542755a49
commit
a84fe51953
5
pom.xml
5
pom.xml
@ -82,5 +82,10 @@
|
|||||||
<version>v2.0.0-BETA-9</version>
|
<version>v2.0.0-BETA-9</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||||
|
<artifactId>caffeine</artifactId>
|
||||||
|
<version>3.1.8</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
40
src/main/java/me/xginko/villageroptimizer/VillagerCache.java
Normal file
40
src/main/java/me/xginko/villageroptimizer/VillagerCache.java
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package me.xginko.villageroptimizer;
|
||||||
|
|
||||||
|
import com.github.benmanes.caffeine.cache.Cache;
|
||||||
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
|
import me.xginko.villageroptimizer.models.WrappedVillager;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Villager;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class VillagerCache {
|
||||||
|
private final Cache<UUID, WrappedVillager> villagerCache = Caffeine.newBuilder().expireAfterWrite(Duration.ofSeconds(30)).build();
|
||||||
|
|
||||||
|
public VillagerCache(JavaPlugin plugin) {
|
||||||
|
plugin.getServer().getGlobalRegionScheduler().run(plugin, populateCache -> {
|
||||||
|
for (World world : plugin.getServer().getWorlds()) {
|
||||||
|
for (Entity entity : world.getEntities()) {
|
||||||
|
if (entity instanceof Villager villager) {
|
||||||
|
this.villagerCache.put(villager.getUniqueId(), new WrappedVillager(villager));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrappedVillager getVillager(Villager villager) {
|
||||||
|
WrappedVillager wrappedVillager = villagerCache.getIfPresent(villager.getUniqueId());
|
||||||
|
if (wrappedVillager == null) wrappedVillager = new WrappedVillager(villager);
|
||||||
|
this.villagerCache.put(villager.getUniqueId(), wrappedVillager);
|
||||||
|
return wrappedVillager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<UUID, WrappedVillager> get() {
|
||||||
|
return this.villagerCache.asMap();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package me.xginko.villageroptimizer.enums;
|
||||||
|
|
||||||
|
import me.xginko.villageroptimizer.VillagerOptimizer;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
|
||||||
|
public enum NamespacedKeys {
|
||||||
|
|
||||||
|
OPTIMIZED(VillagerOptimizer.getKey("optimized")),
|
||||||
|
COOLDOWN_RESTOCK(VillagerOptimizer.getKey("restock-cooldown")),
|
||||||
|
COOLDOWN_EXPERIENCE(VillagerOptimizer.getKey("experience-cooldown")),
|
||||||
|
GAME_TIME(VillagerOptimizer.getKey("game-time"));
|
||||||
|
|
||||||
|
private final NamespacedKey key;
|
||||||
|
|
||||||
|
NamespacedKeys(NamespacedKey key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamespacedKey get() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package me.xginko.villageroptimizer.enums;
|
||||||
|
|
||||||
|
public enum OptimizationType {
|
||||||
|
|
||||||
|
COMMAND,
|
||||||
|
NAMETAG,
|
||||||
|
WORKSTATION,
|
||||||
|
BLOCK,
|
||||||
|
OFF
|
||||||
|
|
||||||
|
}
|
@ -1,17 +0,0 @@
|
|||||||
package me.xginko.villageroptimizer.models;
|
|
||||||
|
|
||||||
import org.bukkit.entity.Villager;
|
|
||||||
|
|
||||||
public class OptimizedVillager {
|
|
||||||
|
|
||||||
private final Villager villager;
|
|
||||||
|
|
||||||
|
|
||||||
public OptimizedVillager(Villager villager) {
|
|
||||||
this.villager = villager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Villager villager() {
|
|
||||||
return villager;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,67 @@
|
|||||||
|
package me.xginko.villageroptimizer.models;
|
||||||
|
|
||||||
|
import me.xginko.villageroptimizer.enums.NamespacedKeys;
|
||||||
|
import me.xginko.villageroptimizer.enums.OptimizationType;
|
||||||
|
import org.bukkit.entity.Villager;
|
||||||
|
import org.bukkit.persistence.PersistentDataContainer;
|
||||||
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
|
||||||
|
public record WrappedVillager(Villager villager) {
|
||||||
|
|
||||||
|
public long getLevel() {
|
||||||
|
// Villager Level depending on their XP (source: https://minecraft.fandom.com/wiki/Trading#Mechanics)
|
||||||
|
final int experience = villager.getVillagerExperience();
|
||||||
|
if (experience >= 250) return 5;
|
||||||
|
if (experience >= 150) return 4;
|
||||||
|
if (experience >= 70) return 3;
|
||||||
|
if (experience >= 10) return 2;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOptimized() {
|
||||||
|
return villager.getPersistentDataContainer().has(NamespacedKeys.OPTIMIZED.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOptimization(OptimizationType type) {
|
||||||
|
if (type.equals(OptimizationType.OFF) && isOptimized()) {
|
||||||
|
villager.getPersistentDataContainer().remove(NamespacedKeys.OPTIMIZED.get());
|
||||||
|
} else {
|
||||||
|
villager.getPersistentDataContainer().set(NamespacedKeys.OPTIMIZED.get(), PersistentDataType.STRING, type.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public OptimizationType getOptimizationType() {
|
||||||
|
return isOptimized() ? OptimizationType.valueOf(villager().getPersistentDataContainer().get(NamespacedKeys.OPTIMIZED.get(), PersistentDataType.STRING)) : OptimizationType.OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRestockCooldown(long milliseconds) {
|
||||||
|
villager.getPersistentDataContainer().set(NamespacedKeys.COOLDOWN_RESTOCK.get(), PersistentDataType.LONG, System.currentTimeMillis() + milliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean shouldRestock() {
|
||||||
|
PersistentDataContainer villagerData = villager.getPersistentDataContainer();
|
||||||
|
return villagerData.has(NamespacedKeys.COOLDOWN_RESTOCK.get(), PersistentDataType.LONG) && villagerData.get(NamespacedKeys.COOLDOWN_RESTOCK.get(), PersistentDataType.LONG) <= System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void restock() {
|
||||||
|
villager.getRecipes().forEach(recipe -> recipe.setUses(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpCooldown(long milliseconds) {
|
||||||
|
villager.getPersistentDataContainer().set(NamespacedKeys.COOLDOWN_EXPERIENCE.get(), PersistentDataType.LONG, System.currentTimeMillis() + milliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOnExpCooldown() {
|
||||||
|
PersistentDataContainer villagerData = villager.getPersistentDataContainer();
|
||||||
|
return villagerData.has(NamespacedKeys.COOLDOWN_EXPERIENCE.get(), PersistentDataType.LONG) && villagerData.get(NamespacedKeys.COOLDOWN_EXPERIENCE.get(), PersistentDataType.LONG) <= System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveWorldTime() {
|
||||||
|
villager.getPersistentDataContainer().set(NamespacedKeys.GAME_TIME.get(), PersistentDataType.LONG, villager.getWorld().getFullTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSavedWorldTime() {
|
||||||
|
PersistentDataContainer villagerData = villager.getPersistentDataContainer();
|
||||||
|
return villagerData.has(NamespacedKeys.GAME_TIME.get(), PersistentDataType.LONG) ? villagerData.get(NamespacedKeys.GAME_TIME.get(), PersistentDataType.LONG) : villager.getWorld().getFullTime();
|
||||||
|
}
|
||||||
|
}
|
@ -1,21 +0,0 @@
|
|||||||
package me.xginko.villageroptimizer.utils;
|
|
||||||
|
|
||||||
import org.bukkit.entity.Villager;
|
|
||||||
|
|
||||||
public class CalculateLevel {
|
|
||||||
public static long villagerEXP (Villager vil) {
|
|
||||||
|
|
||||||
int vilEXP = vil.getVillagerExperience();
|
|
||||||
|
|
||||||
// Villager Level depending on their XP
|
|
||||||
// source: https://minecraft.fandom.com/wiki/Trading#Mechanics
|
|
||||||
|
|
||||||
if (vilEXP >= 250) return 5;
|
|
||||||
if (vilEXP >= 150) return 4;
|
|
||||||
if (vilEXP >= 70) return 3;
|
|
||||||
if (vilEXP >= 10) return 2;
|
|
||||||
|
|
||||||
// default level is 1
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
package me.xginko.villageroptimizer.utils;
|
|
||||||
|
|
||||||
import me.xginko.villageroptimizer.VillagerOptimizer;
|
|
||||||
import org.bukkit.NamespacedKey;
|
|
||||||
|
|
||||||
public enum NamespacedKeys {
|
|
||||||
|
|
||||||
COOLDOWN(VillagerOptimizer.getKey("cooldown")),
|
|
||||||
TIME(VillagerOptimizer.getKey("time")),
|
|
||||||
LEVEL_COOLDOWN(VillagerOptimizer.getKey("level-cooldown")),
|
|
||||||
NAMETAG_DISABLED(VillagerOptimizer.getKey("nametag-disabled")),
|
|
||||||
BLOCK_DISABLED(VillagerOptimizer.getKey("block-disabled")),
|
|
||||||
WORKSTATION_DISABLED(VillagerOptimizer.getKey("workstation-disabled"));
|
|
||||||
|
|
||||||
private final NamespacedKey key;
|
|
||||||
|
|
||||||
NamespacedKeys(NamespacedKey key) {
|
|
||||||
this.key = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NamespacedKey get() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +1,14 @@
|
|||||||
package me.xginko.villageroptimizer.utils;
|
package me.xginko.villageroptimizer.utils;
|
||||||
|
|
||||||
import me.xginko.villageroptimizer.VillagerOptimizer;
|
import me.xginko.villageroptimizer.VillagerOptimizer;
|
||||||
|
import me.xginko.villageroptimizer.models.WrappedVillager;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.entity.Villager;
|
import org.bukkit.entity.Villager;
|
||||||
import org.bukkit.inventory.MerchantRecipe;
|
|
||||||
import org.bukkit.persistence.PersistentDataType;
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class VillagerUtils {
|
public class VillagerUtils {
|
||||||
|
|
||||||
public static boolean isDisabled(Villager villager) {
|
|
||||||
return hasDisabledByBlock(villager) || hasDisabledByWorkstation(villager) || hasMarker(villager);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void restockTrades(Villager villager) {
|
|
||||||
for (MerchantRecipe recipe : villager.getRecipes()) {
|
|
||||||
recipe.setUses(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean shouldDisable(Villager villager) {
|
public static boolean shouldDisable(Villager villager) {
|
||||||
// Check nametag
|
// Check nametag
|
||||||
Component nameTag = villager.customName();
|
Component nameTag = villager.customName();
|
||||||
@ -38,80 +24,6 @@ public class VillagerUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check Workstation
|
// Check Workstation
|
||||||
return getDisabledByWorkstation(villager).orElse(false);
|
return new WrappedVillager(villager).isOptimized();
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Helper Methods for storing and reading data inside villagers using PersistentDataContainer
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
|
|
||||||
// Disabled by Block
|
|
||||||
public static void setDisabledByBlock(Villager villager, boolean state) {
|
|
||||||
villager.getPersistentDataContainer().set(NamespacedKeys.BLOCK_DISABLED.get(), PersistentDataType.BOOLEAN, state);
|
|
||||||
}
|
|
||||||
public static boolean isDisabledByBlock(Villager villager) {
|
|
||||||
if (villager.getPersistentDataContainer().has(NamespacedKeys.BLOCK_DISABLED.get(), PersistentDataType.BOOLEAN)) {
|
|
||||||
return villager.getPersistentDataContainer().get(NamespacedKeys.BLOCK_DISABLED.get(), PersistentDataType.BOOLEAN);
|
|
||||||
} else {
|
|
||||||
setDisabledByBlock(villager, false);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disabled by Workstation
|
|
||||||
public static void setDisabledByWorkstation(Villager villager, Boolean state) {
|
|
||||||
villager.getPersistentDataContainer().set(NamespacedKeys.WORKSTATION_DISABLED.get(), PersistentDataType.BOOLEAN, state);
|
|
||||||
}
|
|
||||||
public static boolean hasDisabledByWorkstation(Villager villager) {
|
|
||||||
return villager.getPersistentDataContainer().has(NamespacedKeys.WORKSTATION_DISABLED.get(), PersistentDataType.BOOLEAN);
|
|
||||||
}
|
|
||||||
public static Optional<Boolean> getDisabledByWorkstation(Villager villager) {
|
|
||||||
return Optional.ofNullable(villager.getPersistentDataContainer().get(NamespacedKeys.WORKSTATION_DISABLED.get(), PersistentDataType.BOOLEAN));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cooldown
|
|
||||||
public static void setCooldown(Villager villager, long cooldown_millis) {
|
|
||||||
villager.getPersistentDataContainer().set(NamespacedKeys.COOLDOWN.get(), PersistentDataType.LONG, System.currentTimeMillis() + cooldown_millis);
|
|
||||||
}
|
|
||||||
public static boolean hasCooldown(Villager villager) {
|
|
||||||
return villager.getPersistentDataContainer().has(NamespacedKeys.COOLDOWN.get(), PersistentDataType.LONG);
|
|
||||||
}
|
|
||||||
public static Optional<Long> getCooldown(Villager villager) {
|
|
||||||
return Optional.ofNullable(villager.getPersistentDataContainer().get(NamespacedKeys.COOLDOWN.get(), PersistentDataType.LONG));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Time
|
|
||||||
public static void setTime(Villager villager) {
|
|
||||||
villager.getPersistentDataContainer().set(NamespacedKeys.TIME.get(), PersistentDataType.LONG, villager.getWorld().getFullTime());
|
|
||||||
}
|
|
||||||
public static boolean hasTime(Villager villager) {
|
|
||||||
return villager.getPersistentDataContainer().has(NamespacedKeys.TIME.get(), PersistentDataType.LONG);
|
|
||||||
}
|
|
||||||
public static Optional<Long> getTime(Villager villager) {
|
|
||||||
return Optional.ofNullable(villager.getPersistentDataContainer().get(NamespacedKeys.TIME.get(), PersistentDataType.LONG));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Level Cooldown
|
|
||||||
public static void setLevelCooldown(Villager villager, long cooldown_millis) {
|
|
||||||
villager.getPersistentDataContainer().set(NamespacedKeys.LEVEL_COOLDOWN.get(), PersistentDataType.LONG, System.currentTimeMillis() + cooldown_millis);
|
|
||||||
}
|
|
||||||
public static boolean hasLevelCooldown(Villager villager, JavaPlugin plugin) {
|
|
||||||
return villager.getPersistentDataContainer().has(NamespacedKeys.LEVEL_COOLDOWN.get(), PersistentDataType.LONG);
|
|
||||||
}
|
|
||||||
public static Optional<Long> getLevelCooldown(Villager villager) {
|
|
||||||
return Optional.ofNullable(villager.getPersistentDataContainer().get(NamespacedKeys.LEVEL_COOLDOWN.get(), PersistentDataType.LONG));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marker
|
|
||||||
public static void setMarker(Villager villager) {
|
|
||||||
villager.getPersistentDataContainer().set(NamespacedKeys.NAMETAG_DISABLED.get(), PersistentDataType.BYTE, (byte)1);
|
|
||||||
}
|
|
||||||
public static boolean hasMarker(Villager villager) {
|
|
||||||
return villager.getPersistentDataContainer().has(NamespacedKeys.NAMETAG_DISABLED.get(), PersistentDataType.BYTE);
|
|
||||||
}
|
|
||||||
public static void removeMarker(Villager villager) {
|
|
||||||
villager.getPersistentDataContainer().remove(NamespacedKeys.NAMETAG_DISABLED.get());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user