Implements #1
All checks were successful
KnarCraft/PlaceholderSigns/pipeline/head This commit looks good
All checks were successful
KnarCraft/PlaceholderSigns/pipeline/head This commit looks good
This commit is contained in:
@@ -6,11 +6,14 @@ import net.knarcraft.knarlib.property.ColorConversion;
|
||||
import net.knarcraft.placeholdersigns.command.CopySignCommand;
|
||||
import net.knarcraft.placeholdersigns.command.CopySignTextCommand;
|
||||
import net.knarcraft.placeholdersigns.command.EditSignCommand;
|
||||
import net.knarcraft.placeholdersigns.command.SetPlaceholderUpdateDelayCommand;
|
||||
import net.knarcraft.placeholdersigns.command.UnWaxSignCommand;
|
||||
import net.knarcraft.placeholdersigns.command.ViewSignCommand;
|
||||
import net.knarcraft.placeholdersigns.config.PlaceholderSignMessage;
|
||||
import net.knarcraft.placeholdersigns.handler.PlaceholderSignHandler;
|
||||
import net.knarcraft.placeholdersigns.handler.PlaceholderSignRequestHandler;
|
||||
import net.knarcraft.placeholdersigns.handler.PlaceholderSignUpdateQueueHandler;
|
||||
import net.knarcraft.placeholdersigns.listener.ChunkListener;
|
||||
import net.knarcraft.placeholdersigns.listener.SignBreakListener;
|
||||
import net.knarcraft.placeholdersigns.listener.SignClickListener;
|
||||
import net.knarcraft.placeholdersigns.listener.SignTextListener;
|
||||
@@ -18,6 +21,7 @@ import net.knarcraft.placeholdersigns.runnable.SignUpdate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -31,7 +35,9 @@ public final class PlaceholderSigns extends JavaPlugin {
|
||||
private static PlaceholderSigns instance;
|
||||
private PlaceholderSignHandler signHandler;
|
||||
private PlaceholderSignRequestHandler requestHandler;
|
||||
private PlaceholderSignUpdateQueueHandler updateQueueHandler;
|
||||
private StringFormatter stringFormatter;
|
||||
private int signUpdateDelay;
|
||||
|
||||
/**
|
||||
* Gets an instance of this plugin
|
||||
@@ -53,21 +59,51 @@ public final class PlaceholderSigns extends JavaPlugin {
|
||||
return this.signHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this instance's placeholder sign request handler
|
||||
*
|
||||
* @return <p>The request handler</p>
|
||||
*/
|
||||
@NotNull
|
||||
public PlaceholderSignRequestHandler getRequestHandler() {
|
||||
return this.requestHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this instance's update queue handler
|
||||
*
|
||||
* @return <p>The update queue handler</p>
|
||||
*/
|
||||
@NotNull
|
||||
public PlaceholderSignUpdateQueueHandler getUpdateQueueHandler() {
|
||||
return this.updateQueueHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string formatter to use for formatting messages
|
||||
*
|
||||
* @return <p>The string formatter</p>
|
||||
*/
|
||||
@NotNull
|
||||
public StringFormatter getStringFormatter() {
|
||||
return this.stringFormatter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default sign update delay
|
||||
*
|
||||
* @return <p>The sign update delay</p>
|
||||
*/
|
||||
public int getSignUpdateDelay() {
|
||||
return this.signUpdateDelay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
getConfig().options().copyDefaults(true);
|
||||
saveConfig();
|
||||
|
||||
Translator translator = new Translator();
|
||||
translator.registerMessageCategory(PlaceholderSignMessage.SUCCESS_CLICK_SIGN_TO_EDIT);
|
||||
translator.setColorConversion(ColorConversion.RGB);
|
||||
@@ -77,9 +113,15 @@ public final class PlaceholderSigns extends JavaPlugin {
|
||||
this.stringFormatter.setNamePrefix("#A5682A[&r&l");
|
||||
this.stringFormatter.setNameSuffix("&r#A5682A]");
|
||||
|
||||
signUpdateDelay = getConfig().getInt("defaultSignUpdateTicks", 100);
|
||||
if (signUpdateDelay < 1) {
|
||||
signUpdateDelay = 100;
|
||||
}
|
||||
|
||||
this.signHandler = new PlaceholderSignHandler();
|
||||
this.signHandler.load();
|
||||
this.requestHandler = new PlaceholderSignRequestHandler();
|
||||
this.updateQueueHandler = new PlaceholderSignUpdateQueueHandler();
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") == null) {
|
||||
getLogger().log(Level.WARNING, "Could not find PlaceholderAPI! This plugin is required.");
|
||||
@@ -87,18 +129,20 @@ public final class PlaceholderSigns extends JavaPlugin {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update signs' placeholders every second
|
||||
Bukkit.getScheduler().runTaskTimer(this, new SignUpdate(this.signHandler), 20 * 10, 20 * 5);
|
||||
Bukkit.getScheduler().runTaskTimer(this, new SignUpdate(this.signHandler), 20, 1);
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(new SignBreakListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new SignTextListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new SignClickListener(), this);
|
||||
PluginManager pluginManager = Bukkit.getPluginManager();
|
||||
pluginManager.registerEvents(new SignBreakListener(), this);
|
||||
pluginManager.registerEvents(new SignTextListener(), this);
|
||||
pluginManager.registerEvents(new SignClickListener(), this);
|
||||
pluginManager.registerEvents(new ChunkListener(), this);
|
||||
|
||||
registerCommand("setSignLine", new EditSignCommand());
|
||||
registerCommand("viewSign", new ViewSignCommand());
|
||||
registerCommand("copySign", new CopySignCommand());
|
||||
registerCommand("unWaxSign", new UnWaxSignCommand());
|
||||
registerCommand("copySignText", new CopySignTextCommand());
|
||||
registerCommand("setPlaceholderUpdateDelay", new SetPlaceholderUpdateDelayCommand());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -0,0 +1,77 @@
|
||||
package net.knarcraft.placeholdersigns.command;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.knarlib.util.TabCompletionHelper;
|
||||
import net.knarcraft.placeholdersigns.PlaceholderSigns;
|
||||
import net.knarcraft.placeholdersigns.config.PlaceholderSignMessage;
|
||||
import net.knarcraft.placeholdersigns.container.PlaceholderSign;
|
||||
import net.knarcraft.placeholdersigns.handler.PlaceholderSignHandler;
|
||||
import net.knarcraft.placeholdersigns.util.TabCompleteHelper;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SetPlaceholderUpdateDelayCommand implements TabExecutor {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] arguments) {
|
||||
PlaceholderSigns placeholderSigns = PlaceholderSigns.getInstance();
|
||||
StringFormatter stringFormatter = placeholderSigns.getStringFormatter();
|
||||
if (!(commandSender instanceof Player player)) {
|
||||
stringFormatter.displayErrorMessage(commandSender, PlaceholderSignMessage.ERROR_PLAYER_ONLY);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (arguments.length < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Block targetBlock = player.getTargetBlockExact(7);
|
||||
if (targetBlock == null || !(targetBlock.getState() instanceof Sign sign)) {
|
||||
stringFormatter.displayErrorMessage(commandSender, PlaceholderSignMessage.ERROR_NOT_LOOKING_AT_SIGN);
|
||||
return false;
|
||||
}
|
||||
|
||||
Integer updateDelay = null;
|
||||
try {
|
||||
updateDelay = Integer.parseInt(arguments[0]);
|
||||
} catch (NumberFormatException exception) {
|
||||
if (!arguments[0].equalsIgnoreCase("null")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
PlaceholderSignHandler signHandler = placeholderSigns.getSignHandler();
|
||||
PlaceholderSign placeholderSign = signHandler.getFromLocation(sign.getLocation());
|
||||
if (placeholderSign != null) {
|
||||
placeholderSign.setUpdateDelay(updateDelay);
|
||||
signHandler.save();
|
||||
stringFormatter.displaySuccessMessage(player, PlaceholderSignMessage.SUCCESS_UPDATE_DELAY_CHANGED);
|
||||
return true;
|
||||
} else {
|
||||
stringFormatter.displayErrorMessage(player, PlaceholderSignMessage.ERROR_NOT_LOOKING_AT_PLACEHOLDER_SIGN);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] arguments) {
|
||||
if (arguments.length == 1) {
|
||||
return TabCompletionHelper.filterMatchingStartsWith(TabCompleteHelper.getDelays(), arguments[0]);
|
||||
} else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -160,7 +160,7 @@ public class ViewSignCommand implements TabExecutor {
|
||||
return getSignText(lines, raw);
|
||||
}
|
||||
|
||||
Map<Integer, String> placeholders = placeholderSign.placeholders().get(side);
|
||||
Map<Integer, String> placeholders = placeholderSign.getPlaceholders().get(side);
|
||||
if (placeholders != null) {
|
||||
for (Map.Entry<Integer, String> entry : placeholders.entrySet()) {
|
||||
lines[entry.getKey()] = entry.getValue();
|
||||
|
@@ -67,6 +67,16 @@ public enum PlaceholderSignMessage implements TranslatableMessage {
|
||||
* The message displayed when a sign has been successfully un-waxed
|
||||
*/
|
||||
SUCCESS_SIGN_UN_WAXED,
|
||||
|
||||
/**
|
||||
* The message displayed when the player isn't looking at a placeholder sign when required
|
||||
*/
|
||||
ERROR_NOT_LOOKING_AT_PLACEHOLDER_SIGN,
|
||||
|
||||
/**
|
||||
* The message displayed when a placeholder sign update delay has been changed
|
||||
*/
|
||||
SUCCESS_UPDATE_DELAY_CHANGED,
|
||||
;
|
||||
|
||||
@Override
|
||||
|
@@ -3,15 +3,78 @@ package net.knarcraft.placeholdersigns.container;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.sign.Side;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A sign containing one or more placeholders
|
||||
*
|
||||
* @param location <p>The location of the sign</p>
|
||||
* @param placeholders <p>The original placeholders typed on the sign</p>
|
||||
*/
|
||||
public record PlaceholderSign(@NotNull Location location, @NotNull Map<Side, Map<Integer, String>> placeholders) {
|
||||
public final class PlaceholderSign {
|
||||
|
||||
private final @NotNull Location location;
|
||||
private final @NotNull Map<Side, Map<Integer, String>> placeholders;
|
||||
private @Nullable Integer updateDelay;
|
||||
|
||||
/**
|
||||
* Instantiates a new placeholder sign
|
||||
*
|
||||
* @param location <p>The location of the sign</p>
|
||||
* @param placeholders <p>The original placeholders typed on the sign</p>
|
||||
* @param updateDelay <p>The delay in ticks between each time this sign's placeholders are updated</p>
|
||||
*/
|
||||
public PlaceholderSign(@NotNull Location location, @NotNull Map<Side, Map<Integer, String>> placeholders,
|
||||
@Nullable Integer updateDelay) {
|
||||
this.location = location;
|
||||
this.placeholders = placeholders;
|
||||
this.updateDelay = updateDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the location of this placeholder sign
|
||||
*
|
||||
* @return <p>The location of this placeholder sign</p>
|
||||
*/
|
||||
@NotNull
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the placeholders stored on this sign
|
||||
*
|
||||
* @return <p>The stored placeholders</p>
|
||||
*/
|
||||
@NotNull
|
||||
public Map<Side, Map<Integer, String>> getPlaceholders() {
|
||||
return placeholders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the update delay for this placeholder sign
|
||||
*
|
||||
* @return <p>The update delay</p>
|
||||
*/
|
||||
@Nullable
|
||||
public Integer getUpdateDelay() {
|
||||
return updateDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the update delay for this placeholder sign
|
||||
*
|
||||
* @param updateDelay <p>The new update delay</p>
|
||||
*/
|
||||
public void setUpdateDelay(@Nullable Integer updateDelay) {
|
||||
this.updateDelay = updateDelay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@NotNull Object object) {
|
||||
if (object instanceof PlaceholderSign otherSign) {
|
||||
return this.location.equals(otherSign.location);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,19 @@
|
||||
package net.knarcraft.placeholdersigns.container;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A placeholder sign that's queued to be updated
|
||||
*
|
||||
* @param placeholderSign <p>The queued placeholder sign</p>
|
||||
* @param updateTimestamp <p>The timestamp (long milliseconds) that the placeholder sign should be updated at</p>
|
||||
*/
|
||||
public record QueuedPlaceholderSign(@NotNull PlaceholderSign placeholderSign,
|
||||
long updateTimestamp) implements Comparable<QueuedPlaceholderSign> {
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull QueuedPlaceholderSign other) {
|
||||
return Long.compare(this.updateTimestamp, other.updateTimestamp);
|
||||
}
|
||||
|
||||
}
|
@@ -3,6 +3,7 @@ package net.knarcraft.placeholdersigns.handler;
|
||||
import net.knarcraft.placeholdersigns.PlaceholderSigns;
|
||||
import net.knarcraft.placeholdersigns.container.PlaceholderSign;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.sign.Side;
|
||||
@@ -29,15 +30,7 @@ public class PlaceholderSignHandler {
|
||||
|
||||
private Set<PlaceholderSign> placeholderSigns;
|
||||
private Map<Location, PlaceholderSign> locationLookup;
|
||||
|
||||
/**
|
||||
* Gets all registered signs
|
||||
*
|
||||
* @return <p>All registered signs</p>
|
||||
*/
|
||||
public @NotNull Set<PlaceholderSign> getSigns() {
|
||||
return new HashSet<>(placeholderSigns);
|
||||
}
|
||||
private Map<Chunk, Set<PlaceholderSign>> signsInChunk;
|
||||
|
||||
/**
|
||||
* Gets a placeholder sign from the given location
|
||||
@@ -57,8 +50,11 @@ public class PlaceholderSignHandler {
|
||||
*/
|
||||
public void registerSign(@NotNull PlaceholderSign sign) {
|
||||
this.placeholderSigns.add(sign);
|
||||
locationLookup.put(sign.location(), sign);
|
||||
save();
|
||||
this.locationLookup.put(sign.getLocation(), sign);
|
||||
|
||||
Chunk chunk = sign.getLocation().getChunk();
|
||||
this.signsInChunk.putIfAbsent(chunk, new HashSet<>());
|
||||
this.signsInChunk.get(chunk).add(sign);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,9 +63,24 @@ public class PlaceholderSignHandler {
|
||||
* @param sign <p>The sign to un-register</p>
|
||||
*/
|
||||
public void unregisterSign(@NotNull PlaceholderSign sign) {
|
||||
locationLookup.remove(sign.location());
|
||||
this.locationLookup.remove(sign.getLocation());
|
||||
this.placeholderSigns.remove(sign);
|
||||
save();
|
||||
this.signsInChunk.get(sign.getLocation().getChunk()).remove(sign);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all placeholder signs in the given chunk
|
||||
*
|
||||
* @param chunk <p>The chunk to check</p>
|
||||
* @return <p>All placeholder signs in the chunk</p>
|
||||
*/
|
||||
@NotNull
|
||||
public Set<PlaceholderSign> getFromChunk(@NotNull Chunk chunk) {
|
||||
if (this.signsInChunk.containsKey(chunk)) {
|
||||
return this.signsInChunk.get(chunk);
|
||||
} else {
|
||||
return new HashSet<>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,6 +89,7 @@ public class PlaceholderSignHandler {
|
||||
public void load() {
|
||||
this.placeholderSigns = new HashSet<>();
|
||||
this.locationLookup = new HashMap<>();
|
||||
this.signsInChunk = new HashMap<>();
|
||||
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(signsFile);
|
||||
ConfigurationSection signSection = configuration.getConfigurationSection("signs");
|
||||
@@ -104,9 +116,16 @@ public class PlaceholderSignHandler {
|
||||
allPlaceholders.put(Side.FRONT, frontPlaceholders);
|
||||
allPlaceholders.put(Side.BACK, backPlaceholders);
|
||||
|
||||
PlaceholderSign sign = new PlaceholderSign(signLocation, allPlaceholders);
|
||||
this.placeholderSigns.add(sign);
|
||||
this.locationLookup.put(signLocation, sign);
|
||||
String updateDelayKey = key + ".updateDelay";
|
||||
int updateDelay = -1;
|
||||
if (signSection.contains(updateDelayKey)) {
|
||||
updateDelay = signSection.getInt(updateDelayKey, -1);
|
||||
}
|
||||
if (updateDelay < 1) {
|
||||
updateDelay = PlaceholderSigns.getInstance().getSignUpdateDelay();
|
||||
}
|
||||
|
||||
registerSign(new PlaceholderSign(signLocation, allPlaceholders, updateDelay));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +172,7 @@ public class PlaceholderSignHandler {
|
||||
* @param sign <p>The sign to save</p>
|
||||
*/
|
||||
private void saveSign(@NotNull ConfigurationSection section, @NotNull PlaceholderSign sign) {
|
||||
Location location = sign.location();
|
||||
Location location = sign.getLocation();
|
||||
if (location.getWorld() == null) {
|
||||
return;
|
||||
}
|
||||
@@ -163,19 +182,21 @@ public class PlaceholderSignHandler {
|
||||
String frontKey = key + ".placeholders.front";
|
||||
String backKey = key + ".placeholders.back";
|
||||
|
||||
Map<Integer, String> frontPlaceholders = sign.placeholders().get(Side.FRONT);
|
||||
Map<Integer, String> frontPlaceholders = sign.getPlaceholders().get(Side.FRONT);
|
||||
if (frontPlaceholders != null) {
|
||||
for (Map.Entry<Integer, String> entry : frontPlaceholders.entrySet()) {
|
||||
section.set(frontKey + "." + entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
Map<Integer, String> backPlaceholders = sign.placeholders().get(Side.BACK);
|
||||
Map<Integer, String> backPlaceholders = sign.getPlaceholders().get(Side.BACK);
|
||||
if (backPlaceholders != null) {
|
||||
for (Map.Entry<Integer, String> entry : backPlaceholders.entrySet()) {
|
||||
section.set(backKey + "." + entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
section.set(key + ".updateDelay", sign.getUpdateDelay());
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,77 @@
|
||||
package net.knarcraft.placeholdersigns.handler;
|
||||
|
||||
import net.knarcraft.placeholdersigns.container.PlaceholderSign;
|
||||
import net.knarcraft.placeholdersigns.container.QueuedPlaceholderSign;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
/**
|
||||
* A handler for dealing with the placeholder sign update queue
|
||||
*/
|
||||
public class PlaceholderSignUpdateQueueHandler {
|
||||
|
||||
private final PriorityQueue<QueuedPlaceholderSign> signUpdateQueue;
|
||||
|
||||
/**
|
||||
* Instantiates a new placeholder sign update queue handler
|
||||
*/
|
||||
public PlaceholderSignUpdateQueueHandler() {
|
||||
this.signUpdateQueue = new PriorityQueue<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Polls the queue for any placeholder signs due for update
|
||||
*
|
||||
* <p>No placeholder sign will be returned unless they are due to be updated.</p>
|
||||
*
|
||||
* @return <p>The next queued placeholder sign, or null if no such placeholder sign exists</p>
|
||||
*/
|
||||
@Nullable
|
||||
public PlaceholderSign pollQueue() {
|
||||
QueuedPlaceholderSign nextSign = signUpdateQueue.peek();
|
||||
if (nextSign == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
long currentTime = System.currentTimeMillis();
|
||||
if (nextSign.updateTimestamp() < currentTime) {
|
||||
nextSign = signUpdateQueue.poll();
|
||||
if (nextSign != null) {
|
||||
return nextSign.placeholderSign();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Peeks at the next item in the queue
|
||||
*
|
||||
* @return <p>The next item in the queue, or null if empty</p>
|
||||
*/
|
||||
@Nullable
|
||||
public QueuedPlaceholderSign peekQueue() {
|
||||
return signUpdateQueue.peek();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified queued sign to the queue
|
||||
*
|
||||
* @param queuedSign <p>The queued sign to queue</p>
|
||||
*/
|
||||
public void queueSign(@NotNull QueuedPlaceholderSign queuedSign) {
|
||||
this.signUpdateQueue.add(queuedSign);
|
||||
}
|
||||
|
||||
/**
|
||||
* '
|
||||
* Removes the specified placeholder sign from the queue
|
||||
*
|
||||
* @param placeholderSign <p>The placeholder sign to remove</p>
|
||||
*/
|
||||
public void unQueueSign(@NotNull PlaceholderSign placeholderSign) {
|
||||
this.signUpdateQueue.removeIf((item) -> item.placeholderSign().equals(placeholderSign));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
package net.knarcraft.placeholdersigns.listener;
|
||||
|
||||
import net.knarcraft.placeholdersigns.PlaceholderSigns;
|
||||
import net.knarcraft.placeholdersigns.container.PlaceholderSign;
|
||||
import net.knarcraft.placeholdersigns.container.QueuedPlaceholderSign;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A listener for the loading and unloading of chunks with placeholder signs
|
||||
*/
|
||||
public class ChunkListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onChunkLoad(@NotNull ChunkLoadEvent event) {
|
||||
PlaceholderSigns instance = PlaceholderSigns.getInstance();
|
||||
Set<PlaceholderSign> signsAtChunk = instance.getSignHandler().getFromChunk(event.getChunk());
|
||||
long queueTime = System.currentTimeMillis();
|
||||
for (PlaceholderSign sign : signsAtChunk) {
|
||||
instance.getUpdateQueueHandler().queueSign(new QueuedPlaceholderSign(sign, queueTime++));
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onChunkUnload(@NotNull ChunkUnloadEvent event) {
|
||||
PlaceholderSigns instance = PlaceholderSigns.getInstance();
|
||||
Set<PlaceholderSign> signsAtChunk = instance.getSignHandler().getFromChunk(event.getChunk());
|
||||
for (PlaceholderSign sign : signsAtChunk) {
|
||||
instance.getUpdateQueueHandler().unQueueSign(sign);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -27,6 +27,7 @@ public class SignBreakListener implements Listener {
|
||||
PlaceholderSign sign = signHandler.getFromLocation(block.getLocation());
|
||||
if (sign != null) {
|
||||
signHandler.unregisterSign(sign);
|
||||
signHandler.save();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -133,7 +133,7 @@ public class SignClickListener implements Listener {
|
||||
|
||||
String text = signTextCopyRequest.sign().getSide(signTextCopyRequest.side()).getLine(sourceLine);
|
||||
if (sourcePlaceholderSign != null) {
|
||||
Map<Side, Map<Integer, String>> placeholders = sourcePlaceholderSign.placeholders();
|
||||
Map<Side, Map<Integer, String>> placeholders = sourcePlaceholderSign.getPlaceholders();
|
||||
if (placeholders.containsKey(sourceSide) && placeholders.get(sourceSide).containsKey(sourceLine)) {
|
||||
text = placeholders.get(sourceSide).get(sourceLine);
|
||||
}
|
||||
@@ -162,12 +162,12 @@ public class SignClickListener implements Listener {
|
||||
// Remove old placeholders from the sign side
|
||||
Map<Integer, String> oldPlaceholders = null;
|
||||
if (targetPlaceholderSign != null) {
|
||||
oldPlaceholders = targetPlaceholderSign.placeholders().remove(clickedSide);
|
||||
oldPlaceholders = targetPlaceholderSign.getPlaceholders().remove(clickedSide);
|
||||
}
|
||||
if (pasteSignSide(sourceSide, clickedSide, sourceSign, targetSign,
|
||||
sourcePlaceholderSign, player) && targetPlaceholderSign != null) {
|
||||
// Restore the old placeholders if the sign change didn't finish
|
||||
targetPlaceholderSign.placeholders().put(clickedSide, oldPlaceholders);
|
||||
targetPlaceholderSign.getPlaceholders().put(clickedSide, oldPlaceholders);
|
||||
}
|
||||
|
||||
// Save any placeholder changes
|
||||
@@ -307,7 +307,7 @@ public class SignClickListener implements Listener {
|
||||
@NotNull Player player) {
|
||||
String[] sideLines = signSide.getLines();
|
||||
if (placeholderSign != null) {
|
||||
Map<Side, Map<Integer, String>> placeholders = placeholderSign.placeholders();
|
||||
Map<Side, Map<Integer, String>> placeholders = placeholderSign.getPlaceholders();
|
||||
loadPlaceholders(sourceSide, sideLines, placeholders);
|
||||
}
|
||||
|
||||
@@ -385,7 +385,7 @@ public class SignClickListener implements Listener {
|
||||
String oldPlaceholder = null;
|
||||
if (targetPlaceholderSign != null) {
|
||||
// Remove the old placeholder
|
||||
oldPlaceholder = targetPlaceholderSign.placeholders().get(targetSide).remove(destinationLine);
|
||||
oldPlaceholder = targetPlaceholderSign.getPlaceholders().get(targetSide).remove(destinationLine);
|
||||
}
|
||||
|
||||
lines[destinationLine] = newText;
|
||||
@@ -396,7 +396,7 @@ public class SignClickListener implements Listener {
|
||||
if (changeEvent.isCancelled()) {
|
||||
if (targetPlaceholderSign != null) {
|
||||
// Restore the old placeholder if the action didn't complete
|
||||
targetPlaceholderSign.placeholders().get(targetSide).put(destinationLine, oldPlaceholder);
|
||||
targetPlaceholderSign.getPlaceholders().get(targetSide).put(destinationLine, oldPlaceholder);
|
||||
}
|
||||
PlaceholderSigns.getInstance().getStringFormatter().displayErrorMessage(player,
|
||||
PlaceholderSignMessage.ERROR_CANCELLED_BY_PROTECTION);
|
||||
|
@@ -61,11 +61,12 @@ public class SignTextListener implements Listener {
|
||||
placeholderSide.put(event.getSide(), placeholders);
|
||||
|
||||
// Register a new placeholder sign
|
||||
PlaceholderSign placeholderSign = new PlaceholderSign(event.getBlock().getLocation(), placeholderSide);
|
||||
PlaceholderSign placeholderSign = new PlaceholderSign(event.getBlock().getLocation(), placeholderSide, null);
|
||||
signHandler.registerSign(placeholderSign);
|
||||
signHandler.save();
|
||||
} else if (!placeholders.isEmpty()) {
|
||||
// Overwrite the placeholders of the existing placeholder sign
|
||||
Map<Integer, String> existing = existingSign.placeholders().computeIfAbsent(event.getSide(), k -> new HashMap<>());
|
||||
Map<Integer, String> existing = existingSign.getPlaceholders().computeIfAbsent(event.getSide(), k -> new HashMap<>());
|
||||
existing.putAll(placeholders);
|
||||
signHandler.save();
|
||||
}
|
||||
|
@@ -3,8 +3,11 @@ package net.knarcraft.placeholdersigns.runnable;
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import net.knarcraft.knarlib.property.ColorConversion;
|
||||
import net.knarcraft.knarlib.util.ColorHelper;
|
||||
import net.knarcraft.placeholdersigns.PlaceholderSigns;
|
||||
import net.knarcraft.placeholdersigns.container.PlaceholderSign;
|
||||
import net.knarcraft.placeholdersigns.container.QueuedPlaceholderSign;
|
||||
import net.knarcraft.placeholdersigns.handler.PlaceholderSignHandler;
|
||||
import net.knarcraft.placeholdersigns.handler.PlaceholderSignUpdateQueueHandler;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.sign.Side;
|
||||
@@ -31,40 +34,67 @@ public class SignUpdate implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (PlaceholderSign placeholderSign : signHandler.getSigns()) {
|
||||
// Ignore signs away from players
|
||||
Location location = placeholderSign.location();
|
||||
if (!location.getChunk().isLoaded()) {
|
||||
continue;
|
||||
PlaceholderSigns instance = PlaceholderSigns.getInstance();
|
||||
PlaceholderSignUpdateQueueHandler queueHandler = instance.getUpdateQueueHandler();
|
||||
|
||||
long startTime = System.nanoTime();
|
||||
long currentTime = System.currentTimeMillis();
|
||||
while (queueHandler.peekQueue() != null && System.nanoTime() - startTime < 25000000) {
|
||||
PlaceholderSign placeholderSign = instance.getUpdateQueueHandler().pollQueue();
|
||||
if (placeholderSign == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
// If no longer a sign, remove
|
||||
if (!(location.getBlock().getState() instanceof Sign sign)) {
|
||||
signHandler.unregisterSign(placeholderSign);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Update placeholders
|
||||
SignSide front = sign.getSide(Side.FRONT);
|
||||
SignSide back = sign.getSide(Side.BACK);
|
||||
Map<Side, Map<Integer, String>> placeholders = placeholderSign.placeholders();
|
||||
String[] frontLines = front.getLines();
|
||||
String[] backLines = back.getLines();
|
||||
|
||||
// Only update the sign if the text has changed
|
||||
boolean updateNecessary = false;
|
||||
if (placeholders.get(Side.FRONT) != null) {
|
||||
updateNecessary |= updatePlaceholders(frontLines, placeholders.get(Side.FRONT), front);
|
||||
}
|
||||
if (placeholders.get(Side.BACK) != null) {
|
||||
updateNecessary |= updatePlaceholders(backLines, placeholders.get(Side.BACK), back);
|
||||
}
|
||||
if (updateNecessary) {
|
||||
sign.update();
|
||||
}
|
||||
updatePlaceholderSign(placeholderSign, currentTime);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the contents of a single placeholder sign
|
||||
*
|
||||
* @param placeholderSign <p>The placeholder sign to update</p>
|
||||
* @param currentTime <p>The current time, used for re-queuing the sign</p>
|
||||
*/
|
||||
private void updatePlaceholderSign(@NotNull PlaceholderSign placeholderSign, long currentTime) {
|
||||
PlaceholderSigns instance = PlaceholderSigns.getInstance();
|
||||
|
||||
// Ignore signs away from players
|
||||
Location location = placeholderSign.getLocation();
|
||||
|
||||
// If no longer a sign, remove
|
||||
if (!(location.getBlock().getState() instanceof Sign sign)) {
|
||||
this.signHandler.unregisterSign(placeholderSign);
|
||||
this.signHandler.save();
|
||||
return;
|
||||
}
|
||||
|
||||
// Update placeholders
|
||||
SignSide front = sign.getSide(Side.FRONT);
|
||||
SignSide back = sign.getSide(Side.BACK);
|
||||
Map<Side, Map<Integer, String>> placeholders = placeholderSign.getPlaceholders();
|
||||
String[] frontLines = front.getLines();
|
||||
String[] backLines = back.getLines();
|
||||
|
||||
// Only update the sign if the text has changed
|
||||
boolean updateNecessary = false;
|
||||
if (placeholders.get(Side.FRONT) != null) {
|
||||
updateNecessary |= updatePlaceholders(frontLines, placeholders.get(Side.FRONT), front);
|
||||
}
|
||||
if (placeholders.get(Side.BACK) != null) {
|
||||
updateNecessary |= updatePlaceholders(backLines, placeholders.get(Side.BACK), back);
|
||||
}
|
||||
if (updateNecessary) {
|
||||
sign.update();
|
||||
}
|
||||
|
||||
Integer updateDelay = placeholderSign.getUpdateDelay();
|
||||
if (updateDelay == null) {
|
||||
updateDelay = instance.getSignUpdateDelay();
|
||||
}
|
||||
|
||||
instance.getUpdateQueueHandler().queueSign(new QueuedPlaceholderSign(placeholderSign, currentTime + (updateDelay * 50)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the values of placeholders on a sign
|
||||
*
|
||||
|
@@ -13,6 +13,7 @@ public final class TabCompleteHelper {
|
||||
|
||||
private static final List<String> lineNumbers;
|
||||
private static final List<String> signSides;
|
||||
private static final List<String> updateDelays;
|
||||
|
||||
static {
|
||||
lineNumbers = new ArrayList<>();
|
||||
@@ -24,12 +25,24 @@ public final class TabCompleteHelper {
|
||||
for (Side side : Side.values()) {
|
||||
signSides.add(side.name());
|
||||
}
|
||||
|
||||
updateDelays = List.of("null", "1", "5", "10", "20", "40", "60", "80", "100");
|
||||
}
|
||||
|
||||
private TabCompleteHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets possible sign update delays
|
||||
*
|
||||
* @return <p>Possible sign update delays</p>
|
||||
*/
|
||||
@NotNull
|
||||
public static List<String> getDelays() {
|
||||
return new ArrayList<>(updateDelays);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets possible sign line numbers
|
||||
*
|
||||
|
Reference in New Issue
Block a user