From e8c93baac496626b10b3036244fce23f740a2618 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 21 Apr 2024 21:26:16 +0200 Subject: [PATCH] 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 --- pom.xml | 10 + .../placeholdersigns/PlaceholderSigns.java | 186 +++++------------- .../command/EditSignCommand.java | 6 +- .../command/ViewSignCommand.java | 19 +- .../config/PlaceholderSignMessage.java | 52 +++++ .../PlaceholderSignRequestHandler.java | 75 +++++++ .../listener/SignClickListener.java | 103 ++++++++-- .../placeholdersigns/runnable/SignUpdate.java | 103 ++++++++++ .../placeholdersigns/util/ColorHelper.java | 34 ---- src/main/resources/config.yml | 2 + src/main/resources/plugin.yml | 4 + src/main/resources/strings.yml | 15 ++ 12 files changed, 413 insertions(+), 196 deletions(-) create mode 100644 src/main/java/net/knarcraft/placeholdersigns/config/PlaceholderSignMessage.java create mode 100644 src/main/java/net/knarcraft/placeholdersigns/handler/PlaceholderSignRequestHandler.java create mode 100644 src/main/java/net/knarcraft/placeholdersigns/runnable/SignUpdate.java delete mode 100644 src/main/java/net/knarcraft/placeholdersigns/util/ColorHelper.java create mode 100644 src/main/resources/strings.yml diff --git a/pom.xml b/pom.xml index 20ab57f..c058648 100644 --- a/pom.xml +++ b/pom.xml @@ -65,6 +65,10 @@ placeholder-api https://repo.extendedclip.com/content/repositories/placeholderapi/ + + knarcraft-repo + https://git.knarcraft.net/api/packages/EpicKnarvik97/maven + @@ -97,5 +101,11 @@ 2.10.0 provided + + net.knarcraft + knarlib + 1.2.5 + compile + diff --git a/src/main/java/net/knarcraft/placeholdersigns/PlaceholderSigns.java b/src/main/java/net/knarcraft/placeholdersigns/PlaceholderSigns.java index a5e6c32..58a55e7 100644 --- a/src/main/java/net/knarcraft/placeholdersigns/PlaceholderSigns.java +++ b/src/main/java/net/knarcraft/placeholdersigns/PlaceholderSigns.java @@ -1,28 +1,23 @@ package net.knarcraft.placeholdersigns; -import me.clip.placeholderapi.PlaceholderAPI; +import net.knarcraft.knarlib.formatting.StringFormatter; +import net.knarcraft.knarlib.formatting.Translator; +import net.knarcraft.knarlib.property.ColorConversion; import net.knarcraft.placeholdersigns.command.EditSignCommand; import net.knarcraft.placeholdersigns.command.ViewSignCommand; -import net.knarcraft.placeholdersigns.container.PlaceholderSign; -import net.knarcraft.placeholdersigns.container.SignLineChangeRequest; +import net.knarcraft.placeholdersigns.config.PlaceholderSignMessage; import net.knarcraft.placeholdersigns.handler.PlaceholderSignHandler; +import net.knarcraft.placeholdersigns.handler.PlaceholderSignRequestHandler; import net.knarcraft.placeholdersigns.listener.SignBreakListener; import net.knarcraft.placeholdersigns.listener.SignClickListener; import net.knarcraft.placeholdersigns.listener.SignTextListener; -import net.knarcraft.placeholdersigns.util.ColorHelper; +import net.knarcraft.placeholdersigns.runnable.SignUpdate; import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.block.Sign; -import org.bukkit.block.sign.Side; -import org.bukkit.block.sign.SignSide; +import org.bukkit.command.CommandExecutor; import org.bukkit.command.PluginCommand; -import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.util.HashMap; -import java.util.Map; import java.util.logging.Level; /** @@ -32,15 +27,16 @@ public final class PlaceholderSigns extends JavaPlugin { private static PlaceholderSigns instance; private PlaceholderSignHandler signHandler; - private Map signChangeRequests; - private Map signViewRequests; + private PlaceholderSignRequestHandler requestHandler; + private StringFormatter stringFormatter; /** * Gets an instance of this plugin * * @return

A plugin instance

*/ - public static @NotNull PlaceholderSigns getInstance() { + @NotNull + public static PlaceholderSigns getInstance() { return instance; } @@ -49,63 +45,38 @@ public final class PlaceholderSigns extends JavaPlugin { * * @return

The sign handler

*/ - public @NotNull PlaceholderSignHandler getSignHandler() { + @NotNull + public PlaceholderSignHandler getSignHandler() { return this.signHandler; } - /** - * Registers a sign change request - * - *

A sign change request is basically the result of running the editSign command, which must be stored until the - * player clicks a sign.

- * - * @param request

The sign change request to register

- */ - public void addSignChangeRequest(@NotNull SignLineChangeRequest request) { - signChangeRequests.put(request.player(), request); + @NotNull + public PlaceholderSignRequestHandler getRequestHandler() { + return this.requestHandler; } - /** - * Gets a sign change request - * - * @param player

The player to get the request for

- * @return

The sign change request, or null if not found

- */ - public @Nullable SignLineChangeRequest getSignChangeRequest(@NotNull Player player) { - return signChangeRequests.remove(player); - } - - /** - * Registers a sign view request - * - * @param player

The player requesting to view a sign

- */ - public void addSignViewRequest(@NotNull Player player) { - signViewRequests.put(player, null); - } - - /** - * Checks whether the given player has a sign view request - * - * @param player

The player to check

- * @return

True if the player has requested to view a sign

- */ - public boolean hasSignViewRequest(@NotNull Player player) { - if (signViewRequests.containsKey(player)) { - signViewRequests.remove(player); - return true; - } else { - return false; - } + @NotNull + public StringFormatter getStringFormatter() { + return this.stringFormatter; } @Override public void onEnable() { instance = this; - signHandler = new PlaceholderSignHandler(); - signChangeRequests = new HashMap<>(); - signViewRequests = new HashMap<>(); - signHandler.load(); + getConfig().options().copyDefaults(true); + saveConfig(); + Translator translator = new Translator(); + translator.registerMessageCategory(PlaceholderSignMessage.SUCCESS_CLICK_SIGN_TO_EDIT); + translator.setColorConversion(ColorConversion.RGB); + translator.loadLanguages(this.getDataFolder(), "en", getConfig().getString("language", "en")); + this.stringFormatter = new StringFormatter(this.getDescription().getName(), translator); + this.stringFormatter.setColorConversion(ColorConversion.RGB); + this.stringFormatter.setNamePrefix("#A5682A[&r&l"); + this.stringFormatter.setNameSuffix("&r#A5682A]"); + + this.signHandler = new PlaceholderSignHandler(); + this.signHandler.load(); + this.requestHandler = new PlaceholderSignRequestHandler(); if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") == null) { getLogger().log(Level.WARNING, "Could not find PlaceholderAPI! This plugin is required."); @@ -114,21 +85,15 @@ public final class PlaceholderSigns extends JavaPlugin { } // Update signs' placeholders every second - Bukkit.getScheduler().runTaskTimer(this, this::updateSigns, 20 * 10, 20 * 5); + Bukkit.getScheduler().runTaskTimer(this, new SignUpdate(this.signHandler), 20 * 10, 20 * 5); Bukkit.getPluginManager().registerEvents(new SignBreakListener(), this); Bukkit.getPluginManager().registerEvents(new SignTextListener(), this); Bukkit.getPluginManager().registerEvents(new SignClickListener(), this); - PluginCommand editCommand = Bukkit.getPluginCommand("editSign"); - if (editCommand != null) { - editCommand.setExecutor(new EditSignCommand()); - } - - PluginCommand viewCommand = Bukkit.getPluginCommand("viewSign"); - if (viewCommand != null) { - viewCommand.setExecutor(new ViewSignCommand()); - } + registerCommand("editSign", new EditSignCommand()); + registerCommand("viewSign", new ViewSignCommand(false)); + registerCommand("viewSignRaw", new ViewSignCommand(true)); } @Override @@ -137,77 +102,18 @@ public final class PlaceholderSigns extends JavaPlugin { } /** - * Updates all loaded and registered placeholder signs - */ - private void updateSigns() { - 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> 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 + * Registers a command executor * - * @param lines

The sign's current lines

- * @param placeholders

The sign's original placeholder lines

- * @param signSide

The side of the sign to update placeholders for

- * @return

True if text has been changed, and the sign needs to be updated

+ * @param commandName

The name of the command

+ * @param executor

The command's executor

*/ - private boolean updatePlaceholders(@NotNull String[] lines, @NotNull Map 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.translateAllColorCodes(newText); - - // Only change the line if the text has changed - if (!newText.equals(oldText)) { - signSide.setLine(i, newText); - changed = true; - } + private void registerCommand(@NotNull String commandName, @NotNull CommandExecutor executor) { + PluginCommand command = Bukkit.getPluginCommand(commandName); + if (command != null) { + command.setExecutor(executor); + } else { + getLogger().log(Level.SEVERE, "Unable to register command " + commandName); } - - return changed; } - } diff --git a/src/main/java/net/knarcraft/placeholdersigns/command/EditSignCommand.java b/src/main/java/net/knarcraft/placeholdersigns/command/EditSignCommand.java index a9d2d15..c926fd6 100644 --- a/src/main/java/net/knarcraft/placeholdersigns/command/EditSignCommand.java +++ b/src/main/java/net/knarcraft/placeholdersigns/command/EditSignCommand.java @@ -1,6 +1,7 @@ package net.knarcraft.placeholdersigns.command; import net.knarcraft.placeholdersigns.PlaceholderSigns; +import net.knarcraft.placeholdersigns.config.PlaceholderSignMessage; import net.knarcraft.placeholdersigns.container.SignLineChangeRequest; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; @@ -60,9 +61,10 @@ public class EditSignCommand implements TabExecutor { // Register the line change request SignLineChangeRequest request = new SignLineChangeRequest(player, lineNumber - 1, builder.toString()); - PlaceholderSigns.getInstance().addSignChangeRequest(request); + PlaceholderSigns.getInstance().getRequestHandler().addSignChangeRequest(request); - commandSender.sendMessage("Please click the sign you want to change."); + PlaceholderSigns.getInstance().getStringFormatter().displaySuccessMessage(commandSender, + PlaceholderSignMessage.SUCCESS_CLICK_SIGN_TO_EDIT); return true; } diff --git a/src/main/java/net/knarcraft/placeholdersigns/command/ViewSignCommand.java b/src/main/java/net/knarcraft/placeholdersigns/command/ViewSignCommand.java index 5d26722..53b215e 100644 --- a/src/main/java/net/knarcraft/placeholdersigns/command/ViewSignCommand.java +++ b/src/main/java/net/knarcraft/placeholdersigns/command/ViewSignCommand.java @@ -1,6 +1,7 @@ package net.knarcraft.placeholdersigns.command; import net.knarcraft.placeholdersigns.PlaceholderSigns; +import net.knarcraft.placeholdersigns.config.PlaceholderSignMessage; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabExecutor; @@ -15,6 +16,18 @@ import java.util.List; * A command for viewing lines on a sign */ public class ViewSignCommand implements TabExecutor { + + boolean raw; + + /** + * Instantiates a new view sign command + * + * @param raw

Whether this sign displays the raw text or not

+ */ + public ViewSignCommand(boolean raw) { + this.raw = raw; + } + @Override public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { @@ -23,9 +36,10 @@ public class ViewSignCommand implements TabExecutor { } // Register the sign view request - PlaceholderSigns.getInstance().addSignViewRequest(player); + PlaceholderSigns.getInstance().getRequestHandler().addSignViewRequest(player, this.raw); - commandSender.sendMessage("Please click the sign you want to view."); + PlaceholderSigns.getInstance().getStringFormatter().displaySuccessMessage(commandSender, + PlaceholderSignMessage.SUCCESS_CLICK_SIGN_TO_VIEW); return true; } @@ -35,4 +49,5 @@ public class ViewSignCommand implements TabExecutor { @NotNull String[] args) { return new ArrayList<>(); } + } diff --git a/src/main/java/net/knarcraft/placeholdersigns/config/PlaceholderSignMessage.java b/src/main/java/net/knarcraft/placeholdersigns/config/PlaceholderSignMessage.java new file mode 100644 index 0000000..5166969 --- /dev/null +++ b/src/main/java/net/knarcraft/placeholdersigns/config/PlaceholderSignMessage.java @@ -0,0 +1,52 @@ +package net.knarcraft.placeholdersigns.config; + +import net.knarcraft.knarlib.formatting.TranslatableMessage; +import org.jetbrains.annotations.NotNull; + +/** + * Translatable plugin messages + */ +public enum PlaceholderSignMessage implements TranslatableMessage { + + /** + * The message to display when waiting for a sign selection (edit) + */ + SUCCESS_CLICK_SIGN_TO_EDIT, + + /** + * The message to display when waiting for a sign selection (view) + */ + SUCCESS_CLICK_SIGN_TO_VIEW, + + /** + * The message displayed when a player tries to edit a waxed sign without the necessary permission + */ + ERROR_WAXED_NO_PERMISSION, + + /** + * The message displayed when a sign line has been successfully changed + */ + SUCCESS_SIGN_CHANGED, + + /** + * The format used when printing current sign lines + */ + SUCCESS_SIGN_CONTENTS, + + /** + * The string displayed when a sign is confirmed to be glowing + */ + GLOWING_CONFIRM, + + /** + * The string displayed when a sign is not glowing + */ + GLOWING_DENY, + ; + + @Override + public @NotNull TranslatableMessage[] getAllMessages() { + return PlaceholderSignMessage.values(); + } + +} diff --git a/src/main/java/net/knarcraft/placeholdersigns/handler/PlaceholderSignRequestHandler.java b/src/main/java/net/knarcraft/placeholdersigns/handler/PlaceholderSignRequestHandler.java new file mode 100644 index 0000000..b27d348 --- /dev/null +++ b/src/main/java/net/knarcraft/placeholdersigns/handler/PlaceholderSignRequestHandler.java @@ -0,0 +1,75 @@ +package net.knarcraft.placeholdersigns.handler; + +import net.knarcraft.placeholdersigns.container.SignLineChangeRequest; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; + +/** + * A class for keeping track of placeholder sign requests + */ +public class PlaceholderSignRequestHandler { + + private final Map signChangeRequests; + private final Map signViewRequests; + + /** + * Instantiates a new placeholder sign request handler + */ + public PlaceholderSignRequestHandler() { + this.signChangeRequests = new HashMap<>(); + this.signViewRequests = new HashMap<>(); + } + + /** + * Registers a sign change request + * + *

A sign change request is basically the result of running the editSign command, which must be stored until the + * player clicks a sign.

+ * + * @param request

The sign change request to register

+ */ + public void addSignChangeRequest(@NotNull SignLineChangeRequest request) { + signChangeRequests.put(request.player(), request); + } + + /** + * Gets a sign change request + * + * @param player

The player to get the request for

+ * @return

The sign change request, or null if not found

+ */ + @Nullable + public SignLineChangeRequest getSignChangeRequest(@NotNull Player player) { + return signChangeRequests.remove(player); + } + + /** + * Registers a sign view request + * + * @param player

The player requesting to view a sign

+ * @param raw

Whether to display the raw text (visible formatting codes)

+ */ + public void addSignViewRequest(@NotNull Player player, boolean raw) { + signViewRequests.put(player, raw); + } + + /** + * Checks whether the given player has a sign view request + * + * @param player

The player to check

+ * @return

True if the player has requested to view a sign

+ */ + @Nullable + public Boolean getSignViewRequest(@NotNull Player player) { + if (signViewRequests.containsKey(player)) { + return signViewRequests.remove(player); + } else { + return null; + } + } + +} diff --git a/src/main/java/net/knarcraft/placeholdersigns/listener/SignClickListener.java b/src/main/java/net/knarcraft/placeholdersigns/listener/SignClickListener.java index d65615c..5d96268 100644 --- a/src/main/java/net/knarcraft/placeholdersigns/listener/SignClickListener.java +++ b/src/main/java/net/knarcraft/placeholdersigns/listener/SignClickListener.java @@ -1,10 +1,16 @@ package net.knarcraft.placeholdersigns.listener; +import net.knarcraft.knarlib.formatting.StringFormatter; +import net.knarcraft.knarlib.formatting.StringReplacer; +import net.knarcraft.knarlib.property.ColorConversion; +import net.knarcraft.knarlib.util.ColorHelper; import net.knarcraft.placeholdersigns.PlaceholderSigns; +import net.knarcraft.placeholdersigns.config.PlaceholderSignMessage; import net.knarcraft.placeholdersigns.container.SignLineChangeRequest; -import net.knarcraft.placeholdersigns.util.ColorHelper; +import net.knarcraft.placeholdersigns.handler.PlaceholderSignRequestHandler; import net.md_5.bungee.api.ChatColor; import org.bukkit.Bukkit; +import org.bukkit.DyeColor; import org.bukkit.block.Sign; import org.bukkit.block.sign.Side; import org.bukkit.block.sign.SignSide; @@ -32,18 +38,24 @@ public class SignClickListener implements Listener { } Player player = event.getPlayer(); - boolean hasSignViewRequest = PlaceholderSigns.getInstance().hasSignViewRequest(player); - if (hasSignViewRequest) { - printSign(sign, player); + PlaceholderSignRequestHandler requestHandler = PlaceholderSigns.getInstance().getRequestHandler(); + Boolean hasSignViewRequest = requestHandler.getSignViewRequest(player); + + if (hasSignViewRequest != null) { + printSign(sign, player, hasSignViewRequest); + // Cancel the event to prevent vanilla behavior + event.setCancelled(true); + return; } if (sign.isWaxed() && !player.hasPermission("placeholdersigns.edit.bypass-waxed")) { - player.sendMessage(ChatColor.RED + "You do not have the necessary permissions to edit a waxed sign."); + PlaceholderSigns.getInstance().getStringFormatter().displayErrorMessage(player, + PlaceholderSignMessage.ERROR_WAXED_NO_PERMISSION); return; } // Check if the player has run the /editSign command - SignLineChangeRequest request = PlaceholderSigns.getInstance().getSignChangeRequest(player); + SignLineChangeRequest request = requestHandler.getSignChangeRequest(player); if (request != null) { SignSide standingOn = sign.getTargetSide(player); Side side = sign.getSide(Side.FRONT).equals(standingOn) ? Side.FRONT : Side.BACK; @@ -56,26 +68,80 @@ public class SignClickListener implements Listener { * * @param sign

The sign to print

* @param player

The player to display the contents to

+ * @param raw

Whether to get the raw text with used formatting codes

*/ - private void printSign(@NotNull Sign sign, @NotNull Player player) { - StringBuilder builder = new StringBuilder(); - getSignText(sign.getSide(Side.FRONT), "Front:", builder); - getSignText(sign.getSide(Side.BACK), "Back:", builder); - player.sendMessage(builder.toString()); + private void printSign(@NotNull Sign sign, @NotNull Player player, boolean raw) { + SignSide front = sign.getSide(Side.FRONT); + SignSide back = sign.getSide(Side.BACK); + String frontLines = getSignText(front, raw); + String backLines = getSignText(back, raw); + StringFormatter stringFormatter = PlaceholderSigns.getInstance().getStringFormatter(); + StringReplacer replacer = new StringReplacer(stringFormatter.getUnformattedColoredMessage( + PlaceholderSignMessage.SUCCESS_SIGN_CONTENTS)); + replacer.add("{frontLines}", frontLines); + replacer.add("{backLines}", backLines); + replacer.add("{frontDye}", getDye(front)); + replacer.add("{frontGlow}", getGlow(front)); + replacer.add("{backDye}", getDye(back)); + replacer.add("{backGlow}", getGlow(back)); + player.sendMessage(replacer.replace()); + } + + /** + * Gets a description of the glow of a sign + * + * @param signSide

The sign side to get the dye of

+ * @return

The description of the applied dye

+ */ + @NotNull + private String getGlow(@NotNull SignSide signSide) { + boolean glowing = signSide.isGlowingText(); + StringFormatter stringFormatter = PlaceholderSigns.getInstance().getStringFormatter(); + if (glowing) { + return stringFormatter.getUnformattedColoredMessage(PlaceholderSignMessage.GLOWING_CONFIRM); + } else { + return stringFormatter.getUnformattedColoredMessage(PlaceholderSignMessage.GLOWING_DENY); + } + } + + /** + * Gets a description of a dye applied to a sign + * + * @param signSide

The sign side to get the dye of

+ * @return

The description of the applied dye

+ */ + @NotNull + private String getDye(@NotNull SignSide signSide) { + DyeColor dyeColor = signSide.getColor(); + if (dyeColor == null) { + return "None"; + } + + ChatColor color = ColorHelper.fromColor(dyeColor.getColor()); + return color + signSide.getColor().name(); } /** * Gets text from a sign side, and appends it to the given string builder * * @param signSide

The sign side to get text from

- * @param header

The header to display before printing the sign test

- * @param builder

The string builder to append the text to

+ * @param raw

Whether to get the raw text with used formatting codes

*/ - private void getSignText(@NotNull SignSide signSide, @NotNull String header, @NotNull StringBuilder builder) { - builder.append(header).append("\n"); + @NotNull + private String getSignText(@NotNull SignSide signSide, boolean raw) { + StringBuilder output = new StringBuilder(); for (int i = 0; i < 4; i++) { - builder.append(signSide.getLine(i)).append("\n"); + output.append(i + 1).append(". "); + + String line = signSide.getLine(i); + if (raw) { + output.append(line.replace(ChatColor.COLOR_CHAR, '&')); + } else { + output.append(line); + } + output.append("\n"); } + return output.toString(); } /** @@ -107,11 +173,12 @@ public class SignClickListener implements Listener { // Update the sign with the new text String[] finalLines = changeEvent.getLines(); for (int i = 0; i < finalLines.length; i++) { - signSide.setLine(i, ColorHelper.translateAllColorCodes(finalLines[i])); + signSide.setLine(i, ColorHelper.translateColorCodes(finalLines[i], ColorConversion.RGB)); } sign.update(); - player.sendMessage("The sign line was successfully changed."); + PlaceholderSigns.getInstance().getStringFormatter().displaySuccessMessage(player, + PlaceholderSignMessage.SUCCESS_SIGN_CHANGED); } } diff --git a/src/main/java/net/knarcraft/placeholdersigns/runnable/SignUpdate.java b/src/main/java/net/knarcraft/placeholdersigns/runnable/SignUpdate.java new file mode 100644 index 0000000..93cd251 --- /dev/null +++ b/src/main/java/net/knarcraft/placeholdersigns/runnable/SignUpdate.java @@ -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

The sign handler to get signs from

+ */ + 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> 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

The sign's current lines

+ * @param placeholders

The sign's original placeholder lines

+ * @param signSide

The side of the sign to update placeholders for

+ * @return

True if text has been changed, and the sign needs to be updated

+ */ + private boolean updatePlaceholders(@NotNull String[] lines, @NotNull Map 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; + } + +} diff --git a/src/main/java/net/knarcraft/placeholdersigns/util/ColorHelper.java b/src/main/java/net/knarcraft/placeholdersigns/util/ColorHelper.java deleted file mode 100644 index a29ebd6..0000000 --- a/src/main/java/net/knarcraft/placeholdersigns/util/ColorHelper.java +++ /dev/null @@ -1,34 +0,0 @@ -package net.knarcraft.placeholdersigns.util; - -import net.md_5.bungee.api.ChatColor; -import org.jetbrains.annotations.NotNull; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * A helper class for dealing with colors and formatting codes - */ -public final class ColorHelper { - - private ColorHelper() { - - } - - /** - * Translates all found color codes to formatting in a string - * - * @param message

The string to search for color codes

- * @return

The message with color codes translated

- */ - public static String translateAllColorCodes(@NotNull String message) { - message = ChatColor.translateAlternateColorCodes('&', message); - Pattern pattern = Pattern.compile("&?(#[a-fA-F0-9]{6})"); - Matcher matcher = pattern.matcher(message); - while (matcher.find()) { - message = message.replace(matcher.group(), "" + ChatColor.of(matcher.group(1))); - } - return message; - } - -} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index e69de29..7858036 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -0,0 +1,2 @@ +# The chosen language for PlaceholderSigns. You can use "en" or any custom language specified in strings.yml +language: en \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 7cf3169..220cc43 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -14,6 +14,10 @@ commands: usage: / permission: placeholdersigns.view description: Displays the contents of a sign in the chat (useful for lines exceeding the viewable area) + viewSignRaw: + usage: / + permission: placeholdersigns.view + description: Displays the raw contents of a sign in the chat (useful for lines exceeding the viewable area, or to see formatting used) permissions: placeholdersigns.*: diff --git a/src/main/resources/strings.yml b/src/main/resources/strings.yml new file mode 100644 index 0000000..7dd4f16 --- /dev/null +++ b/src/main/resources/strings.yml @@ -0,0 +1,15 @@ +en: + SUCCESS_CLICK_SIGN_TO_EDIT: "Please click the sign you want to change." + SUCCESS_CLICK_SIGN_TO_VIEW: "Please click the sign you want to view." + ERROR_WAXED_NO_PERMISSION: "You do not have the necessary permissions to edit a waxed sign." + SUCCESS_SIGN_CHANGED: "The sign line was successfully changed." + SUCCESS_SIGN_CONTENTS: | + #17A057Front:&r + {frontLines} + #8899A5Dye&r {frontDye}&r, #8899A5Glowing&r {frontGlow}&r + + #A01760Back:&r + {backLines} + #8899A5Dye&r {backDye}&r, #8899A5Glowing&r {backGlow}&r + GLOWING_CONFIRM: "#FDFFC8Yes" + GLOWING_DENY: "#CAC8FFNo" \ No newline at end of file