Files
PlaceholderSigns/src/main/java/net/knarcraft/placeholdersigns/runnable/SignUpdate.java
EpicKnarvik97 f8ca5705a5
All checks were successful
KnarCraft/PlaceholderSigns/pipeline/head This commit looks good
Implements #1
2024-04-30 03:09:47 +02:00

134 lines
4.9 KiB
Java

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;
import org.bukkit.block.sign.SignSide;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
/**
* A runnable that updates signs
*/
public class SignUpdate implements Runnable {
private final @NotNull PlaceholderSignHandler signHandler;
/**
* Instantiates a new sign update runnable
*
* @param signHandler <p>The sign handler to get signs from</p>
*/
public SignUpdate(@NotNull PlaceholderSignHandler signHandler) {
this.signHandler = signHandler;
}
@Override
public void run() {
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;
}
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
*
* @param lines <p>The sign's current lines</p>
* @param placeholders <p>The sign's original placeholder lines</p>
* @param signSide <p>The side of the sign to update placeholders for</p>
* @return <p>True if text has been changed, and the sign needs to be updated</p>
*/
private boolean updatePlaceholders(@NotNull String[] lines, @NotNull Map<Integer, String> placeholders,
@NotNull SignSide signSide) {
boolean changed = false;
for (int i = 0; i < lines.length; i++) {
String oldText = signSide.getLine(i);
// The new text of the sign is either the same, or the original placeholder
String newText;
if (!placeholders.containsKey(i) || placeholders.get(i) == null) {
newText = oldText;
} else {
newText = PlaceholderAPI.setPlaceholders(null, placeholders.get(i));
}
// Convert color codes
newText = ColorHelper.translateColorCodes(newText, ColorConversion.RGB);
// Only change the line if the text has changed
if (!newText.equals(oldText)) {
signSide.setLine(i, newText);
changed = true;
}
}
return changed;
}
}