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