From ea3f25e27879aac0b43da178358e466c2dcd06c6 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 5 Apr 2023 22:02:29 +0200 Subject: [PATCH] Initial commit --- .gitignore | 113 +++++++++++ README.md | 28 +++ pom.xml | 90 +++++++++ .../placeholdersigns/PlaceholderSigns.java | 181 ++++++++++++++++++ .../command/EditSignCommand.java | 72 +++++++ .../container/LineChangeRequest.java | 13 ++ .../container/PlaceholderSign.java | 39 ++++ .../handler/PlaceholderSignHandler.java | 118 ++++++++++++ .../listener/SignBreakListener.java | 32 ++++ .../listener/SignClickListener.java | 53 +++++ .../listener/SignTextListener.java | 53 +++++ src/main/resources/config.yml | 0 src/main/resources/plugin.yml | 17 ++ 13 files changed, 809 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 pom.xml create mode 100644 src/main/java/net/knarcraft/placeholdersigns/PlaceholderSigns.java create mode 100644 src/main/java/net/knarcraft/placeholdersigns/command/EditSignCommand.java create mode 100644 src/main/java/net/knarcraft/placeholdersigns/container/LineChangeRequest.java create mode 100644 src/main/java/net/knarcraft/placeholdersigns/container/PlaceholderSign.java create mode 100644 src/main/java/net/knarcraft/placeholdersigns/handler/PlaceholderSignHandler.java create mode 100644 src/main/java/net/knarcraft/placeholdersigns/listener/SignBreakListener.java create mode 100644 src/main/java/net/knarcraft/placeholdersigns/listener/SignClickListener.java create mode 100644 src/main/java/net/knarcraft/placeholdersigns/listener/SignTextListener.java create mode 100644 src/main/resources/config.yml create mode 100644 src/main/resources/plugin.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4788b4b --- /dev/null +++ b/.gitignore @@ -0,0 +1,113 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +target/ + +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next + +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +.flattened-pom.xml + +# Common working directory +run/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..fd3c91c --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +# Placeholder Signs + +This is a minimal plugin created for a single purpose: Displaying placeholders from PlaceholderAPI on signs. Note that +this plugin only works for placeholders which do not require a player, as the same text will be displayed to everyone! + +How it works: After installing this plugin, whenever a sign is changed to contain a placeholder replaced by +PlaceholderAPI, the location of the sign, and the lines containing placeholders are saved. Those lines are updated at a +set pace by using the saved original lines, and letting PlaceholderAPI replace them. Any color, formatting or RGB color +codes in the original text will be converted each time the sign is updated. + +The /editSign command is basically just a command to allow placeholders that won't fit on a sign to be used. As an +additional benefit, formatting, color and RGB color codes are automatically converted whenever the command is used to +change sign text. + +Note that when clicking a sign after using /editSign, a SignChangeEvent is triggered. This means that the sign text +won't be changed unless the player passes all world protection checks. + +## Commands + +| Command | Arguments | Description | +|-----------|-----------------------------|-----------------------------------------------------------------------------------------------| +| /editSign | \ \ \ ... | Sets the text of the sign line (1-4) to the given input. Then right-click the sign to update. | + +## Permissions + +| Permission | Description | +|-----------------------|-----------------------------------------| +| placeholdersigns.edit | Allows the use of the /editSign command | \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..0229e73 --- /dev/null +++ b/pom.xml @@ -0,0 +1,90 @@ + + + 4.0.0 + + net.knarcraft + PlaceholderSigns + 1.0-SNAPSHOT + jar + + PlaceholderSigns + + + 16 + UTF-8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 16 + 16 + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + false + + + + + + + + src/main/resources + true + + + + + + + spigotmc-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + sonatype + https://oss.sonatype.org/content/groups/public/ + + + placeholderapi + https://repo.extendedclip.com/content/repositories/placeholderapi/ + + + + + + org.spigotmc + spigot-api + 1.19.4-R0.1-SNAPSHOT + provided + + + org.jetbrains + annotations + 24.0.1 + provided + + + me.clip + placeholderapi + 2.10.0 + provided + + + diff --git a/src/main/java/net/knarcraft/placeholdersigns/PlaceholderSigns.java b/src/main/java/net/knarcraft/placeholdersigns/PlaceholderSigns.java new file mode 100644 index 0000000..5ad9f59 --- /dev/null +++ b/src/main/java/net/knarcraft/placeholdersigns/PlaceholderSigns.java @@ -0,0 +1,181 @@ +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.container.PlaceholderSign; +import net.knarcraft.placeholdersigns.handler.PlaceholderSignHandler; +import net.knarcraft.placeholdersigns.listener.SignBreakListener; +import net.knarcraft.placeholdersigns.listener.SignClickListener; +import net.knarcraft.placeholdersigns.listener.SignTextListener; +import net.md_5.bungee.api.ChatColor; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.block.Sign; +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; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * This plugin's main class + */ +public final class PlaceholderSigns extends JavaPlugin { + + private static PlaceholderSigns instance; + private PlaceholderSignHandler signHandler; + private Map changeRequests; + + /** + * Gets an instance of this plugin + * + * @return

A plugin instance

+ */ + public static @NotNull PlaceholderSigns getInstance() { + return instance; + } + + /** + * Gets this instance's placeholder sign handler + * + * @return

The sign handler

+ */ + public @NotNull 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 addChangeRequest(@NotNull LineChangeRequest request) { + changeRequests.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

+ */ + public @Nullable LineChangeRequest getChangeRequest(@NotNull Player player) { + return changeRequests.remove(player); + } + + @Override + public void onLoad() { + super.onLoad(); + // Register serialization classes + ConfigurationSerialization.registerClass(PlaceholderSign.class); + ConfigurationSerialization.registerClass(PlaceholderSignHandler.class); + } + + @Override + public void onEnable() { + instance = this; + signHandler = new PlaceholderSignHandler(); + changeRequests = new HashMap<>(); + signHandler.load(); + + if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") == null) { + getLogger().log(Level.WARNING, "Could not find PlaceholderAPI! This plugin is required."); + Bukkit.getPluginManager().disablePlugin(this); + return; + } + + // Update signs' placeholders every second + Bukkit.getScheduler().runTaskTimer(this, this::updateSigns, 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()); + } + } + + @Override + public void onDisable() { + // Plugin shutdown logic + } + + /** + * 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 + Map placeholders = placeholderSign.placeholders(); + String[] lines = sign.getLines(); + boolean updateRequired = false; + for (int i = 0; i < lines.length; i++) { + String oldText = sign.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 = translateAllColorCodes(newText); + + // Only change the line if the text has changed + if (!newText.equals(oldText)) { + sign.setLine(i, newText); + updateRequired = true; + } + } + + // Only update the sign if the text has changed + if (updateRequired) { + sign.update(); + } + } + } + + /** + * 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

+ */ + private static String translateAllColorCodes(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/java/net/knarcraft/placeholdersigns/command/EditSignCommand.java b/src/main/java/net/knarcraft/placeholdersigns/command/EditSignCommand.java new file mode 100644 index 0000000..405ae4d --- /dev/null +++ b/src/main/java/net/knarcraft/placeholdersigns/command/EditSignCommand.java @@ -0,0 +1,72 @@ +package net.knarcraft.placeholdersigns.command; + +import net.knarcraft.placeholdersigns.PlaceholderSigns; +import net.knarcraft.placeholdersigns.container.LineChangeRequest; +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 setting a sign's text to anything longer than normally possible + */ +public class EditSignCommand implements TabExecutor { + + private static final List lineNumbers; + + static { + lineNumbers = new ArrayList<>(); + for (int i = 1; i < 5; i++) { + lineNumbers.add(String.valueOf(i)); + } + } + + @Override + public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, + @NotNull String[] args) { + if (args.length < 2 || !(commandSender instanceof Player player)) { + return false; + } + + // Parse the specified line number + int lineNumber; + try { + lineNumber = Integer.parseInt(args[0]); + if (lineNumber < 0 || lineNumber > 4) { + return false; + } + } catch (NumberFormatException exception) { + return false; + } + + // Get all arguments as a space-separated string + StringBuilder builder = new StringBuilder(args[1]); + for (int i = 2; i < args.length; i++) { + builder.append(" ").append(args[i]); + } + + // Register the line change request + LineChangeRequest request = new LineChangeRequest(player, lineNumber - 1, builder.toString()); + PlaceholderSigns.getInstance().addChangeRequest(request); + + commandSender.sendMessage("Please click the sign you want to change."); + return true; + } + + @Nullable + @Override + public List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, + @NotNull String[] args) { + if (args.length == 1) { + return lineNumbers; + } else { + return new ArrayList<>(); + } + } + +} diff --git a/src/main/java/net/knarcraft/placeholdersigns/container/LineChangeRequest.java b/src/main/java/net/knarcraft/placeholdersigns/container/LineChangeRequest.java new file mode 100644 index 0000000..6a88bd9 --- /dev/null +++ b/src/main/java/net/knarcraft/placeholdersigns/container/LineChangeRequest.java @@ -0,0 +1,13 @@ +package net.knarcraft.placeholdersigns.container; + +import org.bukkit.entity.Player; + +/** + * A record of a player's request to change a sign + * + * @param player

The player requesting the sign change

+ * @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) { +} diff --git a/src/main/java/net/knarcraft/placeholdersigns/container/PlaceholderSign.java b/src/main/java/net/knarcraft/placeholdersigns/container/PlaceholderSign.java new file mode 100644 index 0000000..eb9da0e --- /dev/null +++ b/src/main/java/net/knarcraft/placeholdersigns/container/PlaceholderSign.java @@ -0,0 +1,39 @@ +package net.knarcraft.placeholdersigns.container; + +import org.bukkit.Location; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; + +/** + * A sign containing one or more placeholders + * + * @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")); + } + +} diff --git a/src/main/java/net/knarcraft/placeholdersigns/handler/PlaceholderSignHandler.java b/src/main/java/net/knarcraft/placeholdersigns/handler/PlaceholderSignHandler.java new file mode 100644 index 0000000..ed8dff0 --- /dev/null +++ b/src/main/java/net/knarcraft/placeholdersigns/handler/PlaceholderSignHandler.java @@ -0,0 +1,118 @@ +package net.knarcraft.placeholdersigns.handler; + +import net.knarcraft.placeholdersigns.PlaceholderSigns; +import net.knarcraft.placeholdersigns.container.PlaceholderSign; +import org.bukkit.Location; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; + +/** + * A handler for keeping track of placeholder signs + */ +public class PlaceholderSignHandler implements ConfigurationSerializable { + + private static final File signsFile = new File(PlaceholderSigns.getInstance().getDataFolder(), "signs.yml"); + + private Set placeholderSigns; + private Map locationLookup; + + /** + * Gets all registered signs + * + * @return

All registered signs

+ */ + public @NotNull Set getSigns() { + return new HashSet<>(placeholderSigns); + } + + /** + * Gets a placeholder sign from the given location + * + * @param location

The location of the sign

+ * @return

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

+ */ + public PlaceholderSign getFromLocation(@NotNull Location location) { + return locationLookup.get(location); + } + + /** + * Registers a new placeholder sign + * + * @param sign

The sign to register

+ */ + public void registerSign(@NotNull PlaceholderSign sign) { + this.placeholderSigns.add(sign); + locationLookup.put(sign.location(), sign); + save(); + } + + /** + * Un-registers a placeholder sign + * + * @param sign

The sign to un-register

+ */ + public void unregisterSign(@NotNull PlaceholderSign sign) { + locationLookup.remove(sign.location()); + this.placeholderSigns.remove(sign); + save(); + } + + /** + * Loads all placeholder signs from disk + */ + public void load() { + 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<>(); + } + + /** + * Saves all current placeholder signs + */ + public void save() { + try { + YamlConfiguration configuration = new YamlConfiguration(); + configuration.set("signHandler", this); + 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 + * + * @param data

The data to deserialize

+ * @return

The deserialized sign handler

+ */ + @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); + } + 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 new file mode 100644 index 0000000..fac5a37 --- /dev/null +++ b/src/main/java/net/knarcraft/placeholdersigns/listener/SignBreakListener.java @@ -0,0 +1,32 @@ +package net.knarcraft.placeholdersigns.listener; + +import net.knarcraft.placeholdersigns.PlaceholderSigns; +import net.knarcraft.placeholdersigns.container.PlaceholderSign; +import net.knarcraft.placeholdersigns.handler.PlaceholderSignHandler; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; + +/** + * A listener for placeholder signs being broken + */ +public class SignBreakListener implements Listener { + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onSignBreak(BlockBreakEvent event) { + Block block = event.getBlock(); + + if (!(block.getState() instanceof Sign)) { + return; + } + PlaceholderSignHandler signHandler = PlaceholderSigns.getInstance().getSignHandler(); + PlaceholderSign sign = signHandler.getFromLocation(block.getLocation()); + if (sign != null) { + signHandler.unregisterSign(sign); + } + } + +} diff --git a/src/main/java/net/knarcraft/placeholdersigns/listener/SignClickListener.java b/src/main/java/net/knarcraft/placeholdersigns/listener/SignClickListener.java new file mode 100644 index 0000000..262f4dd --- /dev/null +++ b/src/main/java/net/knarcraft/placeholdersigns/listener/SignClickListener.java @@ -0,0 +1,53 @@ +package net.knarcraft.placeholdersigns.listener; + +import net.knarcraft.placeholdersigns.PlaceholderSigns; +import net.knarcraft.placeholdersigns.container.LineChangeRequest; +import org.bukkit.Bukkit; +import org.bukkit.block.Sign; +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; + +/** + * A listener for placeholder signs being clicked + */ +public class SignClickListener implements Listener { + + @EventHandler(priority = EventPriority.MONITOR) + public void onSignClick(PlayerInteractEvent event) { + // Ignore if not a clicked sign + if (!event.hasBlock() || event.getClickedBlock() == null || + !(event.getClickedBlock().getState() instanceof Sign sign)) { + return; + } + + + // Check if the player has run the /editSign command + LineChangeRequest request = PlaceholderSigns.getInstance().getChangeRequest(event.getPlayer()); + if (request == null) { + return; + } + + String[] lines = sign.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(), event.getPlayer(), lines); + Bukkit.getPluginManager().callEvent(changeEvent); + if (changeEvent.isCancelled()) { + return; + } + + // Update the sign with the new text + String[] finalLines = changeEvent.getLines(); + for (int i = 0; i < finalLines.length; i++) { + sign.setLine(i, finalLines[i]); + } + sign.update(); + + event.getPlayer().sendMessage("The sign line was successfully changed."); + } + +} diff --git a/src/main/java/net/knarcraft/placeholdersigns/listener/SignTextListener.java b/src/main/java/net/knarcraft/placeholdersigns/listener/SignTextListener.java new file mode 100644 index 0000000..38dc772 --- /dev/null +++ b/src/main/java/net/knarcraft/placeholdersigns/listener/SignTextListener.java @@ -0,0 +1,53 @@ +package net.knarcraft.placeholdersigns.listener; + +import me.clip.placeholderapi.PlaceholderAPI; +import net.knarcraft.placeholdersigns.PlaceholderSigns; +import net.knarcraft.placeholdersigns.container.PlaceholderSign; +import net.knarcraft.placeholdersigns.handler.PlaceholderSignHandler; +import org.bukkit.Location; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.SignChangeEvent; + +import java.util.HashMap; +import java.util.Map; + +/** + * A listener for signs being changed to contain on or more placeholders + */ +public class SignTextListener implements Listener { + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onSignCreate(SignChangeEvent event) { + String[] lines = event.getLines(); + Map placeholders = new HashMap<>(); + + // Register any lines PlaceholderAPI wants to change + for (int i = 0; i < lines.length; i++) { + String line = lines[i]; + String replaced = PlaceholderAPI.setPlaceholders(null, line); + if (line.equalsIgnoreCase(replaced)) { + continue; + } + placeholders.put(i, line); + } + + Location location = event.getBlock().getLocation(); + PlaceholderSignHandler signHandler = PlaceholderSigns.getInstance().getSignHandler(); + PlaceholderSign existingSign = signHandler.getFromLocation(location); + + // Register the placeholder sign + if (!placeholders.isEmpty() && existingSign == null) { + PlaceholderSign placeholderSign = new PlaceholderSign(event.getBlock().getLocation(), placeholders); + 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()); + } + signHandler.save(); + } + } + +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..3144b03 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,17 @@ +name: PlaceholderSigns +version: '${project.version}' +main: net.knarcraft.placeholdersigns.PlaceholderSigns +api-version: 1.19 +depend: + - PlaceholderAPI + +commands: + editSign: + usage: / [text] ... + permission: placeholdersigns.edit + description: Changes the line of a sign without a text limit + +permissions: + placeholdersigns.edit: + description: Allows a player to use the /editSign command + default: op \ No newline at end of file