Greatly improves display of text

Makes output text configurable
Adds improved formatting and colors when displaying sign contents
Adds information about applied dye and glow status for signs
Properly cancels the default event when using the viewSign and viewSignRaw commands
This commit is contained in:
2024-04-21 21:26:16 +02:00
parent 6129eda989
commit e8c93baac4
12 changed files with 413 additions and 196 deletions

View File

@ -0,0 +1,103 @@
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.container.PlaceholderSign;
import net.knarcraft.placeholdersigns.handler.PlaceholderSignHandler;
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() {
for (PlaceholderSign placeholderSign : signHandler.getSigns()) {
// Ignore signs away from players
Location location = placeholderSign.location();
if (!location.getChunk().isLoaded()) {
continue;
}
// 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();
}
}
}
/**
* 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;
}
}