diff --git a/pom.xml b/pom.xml index de85bc8..20ab57f 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ org.spigotmc spigot-api - 1.20.1-R0.1-SNAPSHOT + 1.20.4-R0.1-SNAPSHOT provided diff --git a/src/main/java/net/knarcraft/placeholdersigns/PlaceholderSigns.java b/src/main/java/net/knarcraft/placeholdersigns/PlaceholderSigns.java index e8ef9f9..df0f150 100644 --- a/src/main/java/net/knarcraft/placeholdersigns/PlaceholderSigns.java +++ b/src/main/java/net/knarcraft/placeholdersigns/PlaceholderSigns.java @@ -2,8 +2,9 @@ package net.knarcraft.placeholdersigns; import me.clip.placeholderapi.PlaceholderAPI; import net.knarcraft.placeholdersigns.command.EditSignCommand; -import net.knarcraft.placeholdersigns.container.LineChangeRequest; +import net.knarcraft.placeholdersigns.command.ViewSignCommand; import net.knarcraft.placeholdersigns.container.PlaceholderSign; +import net.knarcraft.placeholdersigns.container.SignLineChangeRequest; import net.knarcraft.placeholdersigns.handler.PlaceholderSignHandler; import net.knarcraft.placeholdersigns.listener.SignBreakListener; import net.knarcraft.placeholdersigns.listener.SignClickListener; @@ -13,8 +14,8 @@ 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.PluginCommand; -import org.bukkit.configuration.serialization.ConfigurationSerialization; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; @@ -31,7 +32,8 @@ public final class PlaceholderSigns extends JavaPlugin { private static PlaceholderSigns instance; private PlaceholderSignHandler signHandler; - private Map changeRequests; + private Map signChangeRequests; + private Map signViewRequests; /** * Gets an instance of this plugin @@ -59,8 +61,8 @@ public final class PlaceholderSigns extends JavaPlugin { * * @param request

The sign change request to register

*/ - public void addChangeRequest(@NotNull LineChangeRequest request) { - changeRequests.put(request.player(), request); + public void addSignChangeRequest(@NotNull SignLineChangeRequest request) { + signChangeRequests.put(request.player(), request); } /** @@ -69,23 +71,40 @@ public final class PlaceholderSigns extends JavaPlugin { * @param player

The player to get the request for

* @return

The sign change request, or null if not found

*/ - public @Nullable LineChangeRequest getChangeRequest(@NotNull Player player) { - return changeRequests.remove(player); + public @Nullable SignLineChangeRequest getSignChangeRequest(@NotNull Player player) { + return signChangeRequests.remove(player); } - @Override - public void onLoad() { - super.onLoad(); - // Register serialization classes - ConfigurationSerialization.registerClass(PlaceholderSign.class); - ConfigurationSerialization.registerClass(PlaceholderSignHandler.class); + /** + * 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; + } } @Override public void onEnable() { instance = this; signHandler = new PlaceholderSignHandler(); - changeRequests = new HashMap<>(); + signChangeRequests = new HashMap<>(); + signViewRequests = new HashMap<>(); signHandler.load(); if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") == null) { @@ -105,6 +124,11 @@ public final class PlaceholderSigns extends JavaPlugin { if (editCommand != null) { editCommand.setExecutor(new EditSignCommand()); } + + PluginCommand viewCommand = Bukkit.getPluginCommand("viewSign"); + if (viewCommand != null) { + viewCommand.setExecutor(new ViewSignCommand()); + } } @Override @@ -130,36 +154,52 @@ public final class PlaceholderSigns extends JavaPlugin { } // Update placeholders - Map placeholders = placeholderSign.placeholders(); - String[] lines = sign.getSide(Side.FRONT).getLines(); - boolean updateRequired = false; - for (int i = 0; i < lines.length; i++) { - String oldText = sign.getSide(Side.FRONT).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)) { - sign.getSide(Side.FRONT).setLine(i, newText); - updateRequired = true; - } - } + Map> placeholders = placeholderSign.placeholders(); + String[] frontLines = sign.getSide(Side.FRONT).getLines(); + String[] backLines = sign.getSide(Side.BACK).getLines(); // Only update the sign if the text has changed - if (updateRequired) { + if (updatePlaceholders(frontLines, placeholders.get(Side.FRONT), sign.getSide(Side.FRONT)) || + updatePlaceholders(backLines, placeholders.get(Side.BACK), sign.getSide(Side.BACK))) { 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.translateAllColorCodes(newText); + + // 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/command/EditSignCommand.java b/src/main/java/net/knarcraft/placeholdersigns/command/EditSignCommand.java index 127aaa0..a9d2d15 100644 --- a/src/main/java/net/knarcraft/placeholdersigns/command/EditSignCommand.java +++ b/src/main/java/net/knarcraft/placeholdersigns/command/EditSignCommand.java @@ -1,7 +1,7 @@ package net.knarcraft.placeholdersigns.command; import net.knarcraft.placeholdersigns.PlaceholderSigns; -import net.knarcraft.placeholdersigns.container.LineChangeRequest; +import net.knarcraft.placeholdersigns.container.SignLineChangeRequest; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabExecutor; @@ -59,8 +59,8 @@ public class EditSignCommand implements TabExecutor { } // Register the line change request - LineChangeRequest request = new LineChangeRequest(player, lineNumber - 1, builder.toString()); - PlaceholderSigns.getInstance().addChangeRequest(request); + SignLineChangeRequest request = new SignLineChangeRequest(player, lineNumber - 1, builder.toString()); + PlaceholderSigns.getInstance().addSignChangeRequest(request); commandSender.sendMessage("Please click the sign you want to change."); return true; diff --git a/src/main/java/net/knarcraft/placeholdersigns/command/ViewSignCommand.java b/src/main/java/net/knarcraft/placeholdersigns/command/ViewSignCommand.java new file mode 100644 index 0000000..5d26722 --- /dev/null +++ b/src/main/java/net/knarcraft/placeholdersigns/command/ViewSignCommand.java @@ -0,0 +1,38 @@ +package net.knarcraft.placeholdersigns.command; + +import net.knarcraft.placeholdersigns.PlaceholderSigns; +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; + +/** + * A command for viewing lines on a sign + */ +public class ViewSignCommand implements TabExecutor { + @Override + public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String label, + @NotNull String[] args) { + if (!(commandSender instanceof Player player)) { + return false; + } + + // Register the sign view request + PlaceholderSigns.getInstance().addSignViewRequest(player); + + commandSender.sendMessage("Please click the sign you want to view."); + return true; + } + + @Nullable + @Override + public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, + @NotNull String[] args) { + return new ArrayList<>(); + } +} diff --git a/src/main/java/net/knarcraft/placeholdersigns/container/PlaceholderSign.java b/src/main/java/net/knarcraft/placeholdersigns/container/PlaceholderSign.java index eb9da0e..c1306fb 100644 --- a/src/main/java/net/knarcraft/placeholdersigns/container/PlaceholderSign.java +++ b/src/main/java/net/knarcraft/placeholdersigns/container/PlaceholderSign.java @@ -1,10 +1,9 @@ package net.knarcraft.placeholdersigns.container; import org.bukkit.Location; -import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.block.sign.Side; import org.jetbrains.annotations.NotNull; -import java.util.HashMap; import java.util.Map; /** @@ -13,27 +12,6 @@ import java.util.Map; * @param location

The location of the sign

* @param placeholders

The original placeholders typed on the sign

*/ -public record PlaceholderSign(Location location, - Map placeholders) implements ConfigurationSerializable { - - @Override - @NotNull - public Map serialize() { - Map data = new HashMap<>(); - data.put("location", location); - data.put("placeholders", placeholders); - return data; - } - - /** - * Deserializes the placeholder-sign specified in the given data - * - * @param data

The data to deserialize

- * @return

The deserialized placeholder sign

- */ - @SuppressWarnings({"unchecked", "unused"}) - public static PlaceholderSign deserialize(Map data) { - return new PlaceholderSign((Location) data.get("location"), (Map) data.get("placeholders")); - } +public record PlaceholderSign(@NotNull Location location, @NotNull Map> placeholders) { } diff --git a/src/main/java/net/knarcraft/placeholdersigns/container/LineChangeRequest.java b/src/main/java/net/knarcraft/placeholdersigns/container/SignLineChangeRequest.java similarity index 71% rename from src/main/java/net/knarcraft/placeholdersigns/container/LineChangeRequest.java rename to src/main/java/net/knarcraft/placeholdersigns/container/SignLineChangeRequest.java index 6a88bd9..5d09177 100644 --- a/src/main/java/net/knarcraft/placeholdersigns/container/LineChangeRequest.java +++ b/src/main/java/net/knarcraft/placeholdersigns/container/SignLineChangeRequest.java @@ -1,6 +1,7 @@ package net.knarcraft.placeholdersigns.container; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; /** * A record of a player's request to change a sign @@ -9,5 +10,5 @@ import org.bukkit.entity.Player; * @param line

The line the player wants to change

* @param text

The new text the player provided for the line

*/ -public record LineChangeRequest(Player player, int line, String text) { +public record SignLineChangeRequest(@NotNull Player player, int line, @NotNull String text) { } diff --git a/src/main/java/net/knarcraft/placeholdersigns/handler/PlaceholderSignHandler.java b/src/main/java/net/knarcraft/placeholdersigns/handler/PlaceholderSignHandler.java index ed8dff0..fcaeb98 100644 --- a/src/main/java/net/knarcraft/placeholdersigns/handler/PlaceholderSignHandler.java +++ b/src/main/java/net/knarcraft/placeholdersigns/handler/PlaceholderSignHandler.java @@ -2,10 +2,14 @@ package net.knarcraft.placeholdersigns.handler; import net.knarcraft.placeholdersigns.PlaceholderSigns; import net.knarcraft.placeholdersigns.container.PlaceholderSign; +import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.sign.Side; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; @@ -13,12 +17,13 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.UUID; import java.util.logging.Level; /** * A handler for keeping track of placeholder signs */ -public class PlaceholderSignHandler implements ConfigurationSerializable { +public class PlaceholderSignHandler { private static final File signsFile = new File(PlaceholderSigns.getInstance().getDataFolder(), "signs.yml"); @@ -40,6 +45,7 @@ public class PlaceholderSignHandler implements ConfigurationSerializable { * @param location

The location of the sign

* @return

The sign at the location, or null if no such sign exists

*/ + @Nullable public PlaceholderSign getFromLocation(@NotNull Location location) { return locationLookup.get(location); } @@ -70,10 +76,58 @@ public class PlaceholderSignHandler implements ConfigurationSerializable { * Loads all placeholder signs from disk */ public void load() { + this.placeholderSigns = new HashSet<>(); + this.locationLookup = new HashMap<>(); + YamlConfiguration configuration = YamlConfiguration.loadConfiguration(signsFile); - PlaceholderSignHandler loadedHandler = (PlaceholderSignHandler) configuration.get("signHandler"); - this.placeholderSigns = loadedHandler != null ? loadedHandler.placeholderSigns : new HashSet<>(); - this.locationLookup = loadedHandler != null ? loadedHandler.locationLookup : new HashMap<>(); + ConfigurationSection signSection = configuration.getConfigurationSection("signs"); + if (signSection == null) { + PlaceholderSigns.getInstance().getLogger().log(Level.INFO, "PlaceholderSigns found no signs to load"); + return; + } + + for (String key : signSection.getKeys(false)) { + String[] locationInfo = key.split(","); + World world = Bukkit.getWorld(UUID.fromString(locationInfo[0])); + double x = Integer.parseInt(locationInfo[1]); + double y = Integer.parseInt(locationInfo[2]); + double z = Integer.parseInt(locationInfo[3]); + Location signLocation = new Location(world, x, y, z); + + Map> allPlaceholders = new HashMap<>(); + Map frontPlaceholders = new HashMap<>(); + Map backPlaceholders = new HashMap<>(); + + loadPlaceholders(signSection, key + ".placeholders.front.", frontPlaceholders); + loadPlaceholders(signSection, key + ".placeholders.back.", backPlaceholders); + + 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); + } + } + + /** + * Loads placeholders from one side of a sign + * + * @param signSection

The configuration section to read

+ * @param configurationKey

The configuration key pointing to the placeholders

+ * @param placeholderMap

The map to add read placeholders to

+ */ + private void loadPlaceholders(@NotNull ConfigurationSection signSection, @NotNull String configurationKey, + @NotNull Map placeholderMap) { + for (int i = 0; i < 4; i++) { + String placeholderKey = configurationKey + i; + if (!signSection.contains(placeholderKey)) { + continue; + } + + String placeholder = signSection.getString(placeholderKey); + placeholderMap.put(i, placeholder); + } } /** @@ -82,37 +136,46 @@ public class PlaceholderSignHandler implements ConfigurationSerializable { public void save() { try { YamlConfiguration configuration = new YamlConfiguration(); - configuration.set("signHandler", this); + ConfigurationSection signsSection = configuration.createSection("signs"); + for (PlaceholderSign sign : placeholderSigns) { + saveSign(signsSection, sign); + } configuration.save(signsFile); } catch (IOException exception) { PlaceholderSigns.getInstance().getLogger().log(Level.SEVERE, "Unable to save placeholder signs!"); } } - @NotNull - @Override - public Map serialize() { - Map data = new HashMap<>(); - data.put("signs", this.placeholderSigns); - return data; - } - /** - * Deserializes the given placeholder sign handler data + * Saves a sign to the given configuration section * - * @param data

The data to deserialize

- * @return

The deserialized sign handler

+ * @param section

The configuration section to save to

+ * @param sign

The sign to save

*/ - @SuppressWarnings({"unchecked", "unused"}) - public static PlaceholderSignHandler deserialize(@NotNull Map data) { - PlaceholderSignHandler placeholderSignHandler = new PlaceholderSignHandler(); - placeholderSignHandler.placeholderSigns = (Set) data.get("signs"); - Map lookup = new HashMap<>(); - for (PlaceholderSign sign : placeholderSignHandler.placeholderSigns) { - lookup.put(sign.location(), sign); + private void saveSign(@NotNull ConfigurationSection section, @NotNull PlaceholderSign sign) { + Location location = sign.location(); + if (location.getWorld() == null) { + return; + } + + String key = location.getWorld().getUID() + "," + location.getBlockX() + "," + location.getBlockY() + + "," + location.getBlockZ(); + String frontKey = key + ".placeholders.front"; + String backKey = key + ".placeholders.back"; + + Map frontPlaceholders = sign.placeholders().get(Side.FRONT); + if (frontPlaceholders != null) { + for (Map.Entry entry : frontPlaceholders.entrySet()) { + section.set(frontKey + "." + entry.getKey(), entry.getValue()); + } + } + + Map backPlaceholders = sign.placeholders().get(Side.BACK); + if (backPlaceholders != null) { + for (Map.Entry entry : backPlaceholders.entrySet()) { + section.set(backKey + "." + entry.getKey(), entry.getValue()); + } } - placeholderSignHandler.locationLookup = lookup; - return placeholderSignHandler; } } diff --git a/src/main/java/net/knarcraft/placeholdersigns/listener/SignBreakListener.java b/src/main/java/net/knarcraft/placeholdersigns/listener/SignBreakListener.java index fac5a37..f750dce 100644 --- a/src/main/java/net/knarcraft/placeholdersigns/listener/SignBreakListener.java +++ b/src/main/java/net/knarcraft/placeholdersigns/listener/SignBreakListener.java @@ -9,6 +9,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.BlockBreakEvent; +import org.jetbrains.annotations.NotNull; /** * A listener for placeholder signs being broken @@ -16,7 +17,7 @@ import org.bukkit.event.block.BlockBreakEvent; public class SignBreakListener implements Listener { @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) - public void onSignBreak(BlockBreakEvent event) { + public void onSignBreak(@NotNull BlockBreakEvent event) { Block block = event.getBlock(); if (!(block.getState() instanceof Sign)) { diff --git a/src/main/java/net/knarcraft/placeholdersigns/listener/SignClickListener.java b/src/main/java/net/knarcraft/placeholdersigns/listener/SignClickListener.java index 113ffa7..57bacf1 100644 --- a/src/main/java/net/knarcraft/placeholdersigns/listener/SignClickListener.java +++ b/src/main/java/net/knarcraft/placeholdersigns/listener/SignClickListener.java @@ -1,18 +1,22 @@ package net.knarcraft.placeholdersigns.listener; import net.knarcraft.placeholdersigns.PlaceholderSigns; -import net.knarcraft.placeholdersigns.container.LineChangeRequest; +import net.knarcraft.placeholdersigns.container.SignLineChangeRequest; import net.knarcraft.placeholdersigns.util.ColorHelper; import net.md_5.bungee.api.ChatColor; import org.bukkit.Bukkit; import org.bukkit.block.Sign; import org.bukkit.block.sign.Side; +import org.bukkit.block.sign.SignSide; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; /** * A listener for placeholder signs being clicked @@ -20,7 +24,7 @@ import org.bukkit.event.player.PlayerInteractEvent; public class SignClickListener implements Listener { @EventHandler(priority = EventPriority.MONITOR) - public void onSignClick(PlayerInteractEvent event) { + public void onSignClick(@NotNull PlayerInteractEvent event) { // Ignore if not a clicked sign if (!event.hasBlock() || event.getClickedBlock() == null || !(event.getClickedBlock().getState() instanceof Sign sign)) { @@ -28,25 +32,70 @@ public class SignClickListener implements Listener { } Player player = event.getPlayer(); + boolean hasSignViewRequest = PlaceholderSigns.getInstance().hasSignViewRequest(player); + if (hasSignViewRequest) { + printSign(sign, player); + } + 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."); return; } // Check if the player has run the /editSign command - LineChangeRequest request = PlaceholderSigns.getInstance().getChangeRequest(player); - if (request == null) { - return; + SignLineChangeRequest request = PlaceholderSigns.getInstance().getSignChangeRequest(player); + if (request != null) { + doSignChange(sign, request, event, player); } + } + /** + * Prints the current contents of a sign to a player + * + * @param sign

The sign to print

+ * @param player

The player to display the contents to

+ */ + 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()); + } + + /** + * 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

+ */ + private void getSignText(@NotNull SignSide signSide, @NotNull String header, @NotNull StringBuilder builder) { + builder.append(header).append("\n"); + for (int i = 0; i < 4; i++) { + builder.append(signSide.getLine(i)).append("\n"); + } + } + + /** + * Perform the changing of a sign according to the given sign change request + * + * @param sign

The sign to be changed

+ * @param request

The sign line change request to perform

+ * @param event

The interaction event that triggered this

+ * @param player

The player triggering the sign change

+ */ + private void doSignChange(@NotNull Sign sign, @NotNull SignLineChangeRequest request, + @NotNull PlayerInteractEvent event, @NotNull Player player) { // Cancel the event to prevent vanilla behavior event.setCancelled(true); String[] lines = sign.getSide(Side.FRONT).getLines(); + lines[request.line()] = request.text(); // Run the sign change event to allow protection plugins to cancel, and allow the sign text listener to trigger - SignChangeEvent changeEvent = new SignChangeEvent(event.getClickedBlock(), player, lines, Side.FRONT); + SignChangeEvent changeEvent = new SignChangeEvent(Objects.requireNonNull(event.getClickedBlock()), + player, lines, Side.FRONT); Bukkit.getPluginManager().callEvent(changeEvent); if (changeEvent.isCancelled()) { return; diff --git a/src/main/java/net/knarcraft/placeholdersigns/listener/SignTextListener.java b/src/main/java/net/knarcraft/placeholdersigns/listener/SignTextListener.java index bc55b47..6af1d3d 100644 --- a/src/main/java/net/knarcraft/placeholdersigns/listener/SignTextListener.java +++ b/src/main/java/net/knarcraft/placeholdersigns/listener/SignTextListener.java @@ -5,10 +5,12 @@ import net.knarcraft.placeholdersigns.PlaceholderSigns; import net.knarcraft.placeholdersigns.container.PlaceholderSign; import net.knarcraft.placeholdersigns.handler.PlaceholderSignHandler; import org.bukkit.Location; +import org.bukkit.block.sign.Side; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.SignChangeEvent; +import org.jetbrains.annotations.NotNull; import java.util.HashMap; import java.util.Map; @@ -19,7 +21,7 @@ import java.util.Map; public class SignTextListener implements Listener { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onSignCreateOrEdit(SignChangeEvent event) { + public void onSignCreateOrEdit(@NotNull SignChangeEvent event) { // Only check for placeholders if the player is allowed to if (!event.getPlayer().hasPermission("placeholdersigns.placeholder")) { return; @@ -43,14 +45,16 @@ public class SignTextListener implements Listener { PlaceholderSign existingSign = signHandler.getFromLocation(location); if (!placeholders.isEmpty() && existingSign == null) { + Map> placeholderSide = new HashMap<>(); + placeholderSide.put(event.getSide(), placeholders); + // Register a new placeholder sign - PlaceholderSign placeholderSign = new PlaceholderSign(event.getBlock().getLocation(), placeholders); + PlaceholderSign placeholderSign = new PlaceholderSign(event.getBlock().getLocation(), placeholderSide); signHandler.registerSign(placeholderSign); } else if (!placeholders.isEmpty()) { // Overwrite the placeholders of the existing placeholder sign - for (Map.Entry entry : placeholders.entrySet()) { - existingSign.placeholders().put(entry.getKey(), entry.getValue()); - } + Map existing = existingSign.placeholders().get(event.getSide()); + existing.putAll(placeholders); signHandler.save(); } } diff --git a/src/main/java/net/knarcraft/placeholdersigns/util/ColorHelper.java b/src/main/java/net/knarcraft/placeholdersigns/util/ColorHelper.java index a68107e..a29ebd6 100644 --- a/src/main/java/net/knarcraft/placeholdersigns/util/ColorHelper.java +++ b/src/main/java/net/knarcraft/placeholdersigns/util/ColorHelper.java @@ -1,6 +1,7 @@ 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; @@ -20,7 +21,7 @@ public final class ColorHelper { * @param message

The string to search for color codes

* @return

The message with color codes translated

*/ - public static String translateAllColorCodes(String message) { + 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); diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index cdffed0..8aba459 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -10,6 +10,10 @@ commands: usage: / [text] [text] ... permission: placeholdersigns.edit description: Changes the line of a sign, without a text limit, and with color conversion + viewSign: + usage: / [text] [text] ... + permission: placeholdersigns.view + description: Displays the contents of a sign in the chat (useful for lines exceeding the viewable area) permissions: placeholdersigns.*: @@ -31,4 +35,7 @@ permissions: default: false placeholdersigns.placeholder: description: Allows a player to make signs containing placeholders - default: false \ No newline at end of file + default: false + placeholdersigns.view: + description: Allows a player to see the full text of a sign in the chat + default: true \ No newline at end of file