From aec5e573da74bfbd2fe4dcb4aedd077b148779b3 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Mon, 22 Jun 2020 15:00:34 +0200 Subject: [PATCH] Store serena toggle persistently on player Previously the toggles done by serena would not persist through a server restart, as it was purely maintained in an in-memory queue cache. As this was rather inconvinient for the players, this commit now offers a new implementation for the player toggle register, based on the persistent data container api provided by spigot, which stores the toggle value of serena directly on the player nbt tags. New version: 1.0.4-SNAPSHOT --- pom.xml | 2 +- src/main/java/dev/lynxplay/serena/Serena.java | 16 +++-- .../PersistentPlayerToggleRegister.java | 65 +++++++++++++++++++ .../player/QueuePlayerToggleRegistry.java | 42 ------------ 4 files changed, 75 insertions(+), 50 deletions(-) create mode 100644 src/main/java/dev/lynxplay/serena/player/PersistentPlayerToggleRegister.java delete mode 100644 src/main/java/dev/lynxplay/serena/player/QueuePlayerToggleRegistry.java diff --git a/pom.xml b/pom.xml index f000d05..59f2461 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ dev.lynxplay serena - 1.0.3-SNAPSHOT + 1.0.4-SNAPSHOT UTF-8 diff --git a/src/main/java/dev/lynxplay/serena/Serena.java b/src/main/java/dev/lynxplay/serena/Serena.java index 880c9dc..9dba5bb 100644 --- a/src/main/java/dev/lynxplay/serena/Serena.java +++ b/src/main/java/dev/lynxplay/serena/Serena.java @@ -2,6 +2,11 @@ import dev.lynxplay.serena.commands.SerenaReloadCommand; import dev.lynxplay.serena.commands.SerenaToggleCommand; +import dev.lynxplay.serena.configuration.ConfigurationFactory; +import dev.lynxplay.serena.configuration.language.ImmutableLanguageConfigurationFactory; +import dev.lynxplay.serena.configuration.language.LanguageConfiguration; +import dev.lynxplay.serena.configuration.properties.ImmutablePropertyConfigurationFactory; +import dev.lynxplay.serena.configuration.properties.PropertyConfiguration; import dev.lynxplay.serena.cooldown.CooldownContainer; import dev.lynxplay.serena.cooldown.HashedCooldownContainer; import dev.lynxplay.serena.listener.PlayerConnectionListener; @@ -9,13 +14,10 @@ import dev.lynxplay.serena.listener.PlayerThrowListener; import dev.lynxplay.serena.permission.PlayerPermissionChecker; import dev.lynxplay.serena.permission.SimplePlayerPermissionChecker; +import dev.lynxplay.serena.player.PersistentPlayerToggleRegister; import dev.lynxplay.serena.player.PlayerToggleRegistry; -import dev.lynxplay.serena.player.QueuePlayerToggleRegistry; -import dev.lynxplay.serena.configuration.ConfigurationFactory; -import dev.lynxplay.serena.configuration.language.ImmutableLanguageConfigurationFactory; -import dev.lynxplay.serena.configuration.language.LanguageConfiguration; -import dev.lynxplay.serena.configuration.properties.ImmutablePropertyConfigurationFactory; -import dev.lynxplay.serena.configuration.properties.PropertyConfiguration; +import org.bukkit.Bukkit; +import org.bukkit.NamespacedKey; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; @@ -51,7 +53,7 @@ public void onEnable() { this.cooldownContainer = new HashedCooldownContainer(); this.playerPermissionChecker = new SimplePlayerPermissionChecker(); - this.playerToggleRegistry = new QueuePlayerToggleRegistry(); + this.playerToggleRegistry = new PersistentPlayerToggleRegister(Bukkit::getPlayer, new NamespacedKey(this, "ToggleValue")); this.fixedScheduler = (r, l) -> getServer().getScheduler().runTaskLater(this, r, l); diff --git a/src/main/java/dev/lynxplay/serena/player/PersistentPlayerToggleRegister.java b/src/main/java/dev/lynxplay/serena/player/PersistentPlayerToggleRegister.java new file mode 100644 index 0000000..608a279 --- /dev/null +++ b/src/main/java/dev/lynxplay/serena/player/PersistentPlayerToggleRegister.java @@ -0,0 +1,65 @@ +package dev.lynxplay.serena.player; + +import org.bukkit.NamespacedKey; +import org.bukkit.entity.Player; +import org.bukkit.persistence.PersistentDataHolder; +import org.bukkit.persistence.PersistentDataType; + +import java.util.Optional; +import java.util.UUID; +import java.util.function.Function; + +/** + * The persistent player toggle register uses the {@link org.bukkit.persistence.PersistentDataHolder} interface provided + * by spigot to store the current toggle value for a player. + */ +public class PersistentPlayerToggleRegister implements PlayerToggleRegistry { + + private final Function playerLookup; + private final NamespacedKey toggleNamespace; + + public PersistentPlayerToggleRegister(final Function playerLookup, + final NamespacedKey toggleNamespace) { + this.playerLookup = playerLookup; + this.toggleNamespace = toggleNamespace; + } + + /** + * Returns the current toggle value, being {@code true} if the toggle is enabled, else {@code false} + * + * @param uuid the uuid to check against + * @return the toggle value + */ + @Override + public boolean getCurrentToggle(UUID uuid) { + return Optional.of(uuid) + .map(this.playerLookup) + .map(PersistentDataHolder::getPersistentDataContainer) + .map(c -> c.get(this.toggleNamespace, PersistentDataType.BYTE)) + .map(b -> b == 1) + .orElse(false); + } + + /** + * Sets the toggle value + * + * @param uuid the uuid to update + * @param value the new value for the given uuid + * @return the previous value + */ + @Override + public boolean setToggle(UUID uuid, boolean value) { + return Optional.of(uuid) + .map(this.playerLookup) + .map(PersistentDataHolder::getPersistentDataContainer) + .map(c -> { + final boolean previousValue = Optional.ofNullable(c.get(this.toggleNamespace, PersistentDataType.BYTE)) + .map(b -> b == 1) + .orElse(false); + + c.set(this.toggleNamespace, PersistentDataType.BYTE, (byte) (value ? 1 : 0)); + return previousValue; + }) + .orElse(false); + } +} diff --git a/src/main/java/dev/lynxplay/serena/player/QueuePlayerToggleRegistry.java b/src/main/java/dev/lynxplay/serena/player/QueuePlayerToggleRegistry.java deleted file mode 100644 index 669f5b0..0000000 --- a/src/main/java/dev/lynxplay/serena/player/QueuePlayerToggleRegistry.java +++ /dev/null @@ -1,42 +0,0 @@ -package dev.lynxplay.serena.player; - -import java.util.Queue; -import java.util.UUID; -import java.util.concurrent.ConcurrentLinkedQueue; - -public class QueuePlayerToggleRegistry implements PlayerToggleRegistry { - - private final Queue playerQueue = new ConcurrentLinkedQueue<>(); - - /** - * Returns the current toggle value, being {@code true} if the toggle is enabled, else {@code false} - * - * @param uuid the uuid to check against - * - * @return the toggle value - */ - @Override - public boolean getCurrentToggle(UUID uuid) { - return this.playerQueue.contains(uuid); - } - - /** - * Sets the toggle value - * - * @param uuid the uuid to update - * @param value the new value for the given uuid - * - * @return the previous value - */ - @Override - public boolean setToggle(UUID uuid, boolean value) { - boolean current = getCurrentToggle(uuid); - - if (value && !current) { - this.playerQueue.add(uuid); - } else if (!value && current) { - this.playerQueue.remove(uuid); - } - return current; - } -}