Initial commit
This commit is contained in:
commit
ea3f25e278
113
.gitignore
vendored
Normal file
113
.gitignore
vendored
Normal file
@ -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/
|
28
README.md
Normal file
28
README.md
Normal file
@ -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 | \<line> \<text> \<text> ... | 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 |
|
90
pom.xml
Normal file
90
pom.xml
Normal file
@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>net.knarcraft</groupId>
|
||||
<artifactId>PlaceholderSigns</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>PlaceholderSigns</name>
|
||||
|
||||
<properties>
|
||||
<java.version>16</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<source>16</source>
|
||||
<target>16</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spigotmc-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>sonatype</id>
|
||||
<url>https://oss.sonatype.org/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>placeholderapi</id>
|
||||
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.19.4-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>24.0.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>me.clip</groupId>
|
||||
<artifactId>placeholderapi</artifactId>
|
||||
<version>2.10.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -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<Player, LineChangeRequest> changeRequests;
|
||||
|
||||
/**
|
||||
* Gets an instance of this plugin
|
||||
*
|
||||
* @return <p>A plugin instance</p>
|
||||
*/
|
||||
public static @NotNull PlaceholderSigns getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this instance's placeholder sign handler
|
||||
*
|
||||
* @return <p>The sign handler</p>
|
||||
*/
|
||||
public @NotNull PlaceholderSignHandler getSignHandler() {
|
||||
return this.signHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a sign change request
|
||||
*
|
||||
* <p>A sign change request is basically the result of running the editSign command, which must be stored until the
|
||||
* player clicks a sign.</p>
|
||||
*
|
||||
* @param request <p>The sign change request to register</p>
|
||||
*/
|
||||
public void addChangeRequest(@NotNull LineChangeRequest request) {
|
||||
changeRequests.put(request.player(), request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a sign change request
|
||||
*
|
||||
* @param player <p>The player to get the request for</p>
|
||||
* @return <p>The sign change request, or null if not found</p>
|
||||
*/
|
||||
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<Integer, String> 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 <p>The string to search for color codes</p>
|
||||
* @return <p>The message with color codes translated</p>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
@ -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<String> 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<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] args) {
|
||||
if (args.length == 1) {
|
||||
return lineNumbers;
|
||||
} else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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 <p>The player requesting the sign change</p>
|
||||
* @param line <p>The line the player wants to change</p>
|
||||
* @param text <p>The new text the player provided for the line</p>
|
||||
*/
|
||||
public record LineChangeRequest(Player player, int line, String text) {
|
||||
}
|
@ -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 <p>The location of the sign</p>
|
||||
* @param placeholders <p>The original placeholders typed on the sign</p>
|
||||
*/
|
||||
public record PlaceholderSign(Location location,
|
||||
Map<Integer, String> placeholders) implements ConfigurationSerializable {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Map<String, Object> serialize() {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("location", location);
|
||||
data.put("placeholders", placeholders);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the placeholder-sign specified in the given data
|
||||
*
|
||||
* @param data <p>The data to deserialize</p>
|
||||
* @return <p>The deserialized placeholder sign</p>
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "unused"})
|
||||
public static PlaceholderSign deserialize(Map<String, Object> data) {
|
||||
return new PlaceholderSign((Location) data.get("location"), (Map<Integer, String>) data.get("placeholders"));
|
||||
}
|
||||
|
||||
}
|
@ -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<PlaceholderSign> placeholderSigns;
|
||||
private Map<Location, PlaceholderSign> locationLookup;
|
||||
|
||||
/**
|
||||
* Gets all registered signs
|
||||
*
|
||||
* @return <p>All registered signs</p>
|
||||
*/
|
||||
public @NotNull Set<PlaceholderSign> getSigns() {
|
||||
return new HashSet<>(placeholderSigns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a placeholder sign from the given location
|
||||
*
|
||||
* @param location <p>The location of the sign</p>
|
||||
* @return <p>The sign at the location, or null if no such sign exists</p>
|
||||
*/
|
||||
public PlaceholderSign getFromLocation(@NotNull Location location) {
|
||||
return locationLookup.get(location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new placeholder sign
|
||||
*
|
||||
* @param sign <p>The sign to register</p>
|
||||
*/
|
||||
public void registerSign(@NotNull PlaceholderSign sign) {
|
||||
this.placeholderSigns.add(sign);
|
||||
locationLookup.put(sign.location(), sign);
|
||||
save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Un-registers a placeholder sign
|
||||
*
|
||||
* @param sign <p>The sign to un-register</p>
|
||||
*/
|
||||
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<String, Object> serialize() {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("signs", this.placeholderSigns);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the given placeholder sign handler data
|
||||
*
|
||||
* @param data <p>The data to deserialize</p>
|
||||
* @return <p>The deserialized sign handler</p>
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "unused"})
|
||||
public static PlaceholderSignHandler deserialize(@NotNull Map<String, Object> data) {
|
||||
PlaceholderSignHandler placeholderSignHandler = new PlaceholderSignHandler();
|
||||
placeholderSignHandler.placeholderSigns = (Set<PlaceholderSign>) data.get("signs");
|
||||
Map<Location, PlaceholderSign> lookup = new HashMap<>();
|
||||
for (PlaceholderSign sign : placeholderSignHandler.placeholderSigns) {
|
||||
lookup.put(sign.location(), sign);
|
||||
}
|
||||
placeholderSignHandler.locationLookup = lookup;
|
||||
return placeholderSignHandler;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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.");
|
||||
}
|
||||
|
||||
}
|
@ -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<Integer, String> 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<Integer, String> entry : placeholders.entrySet()) {
|
||||
existingSign.placeholders().put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
signHandler.save();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
0
src/main/resources/config.yml
Normal file
0
src/main/resources/config.yml
Normal file
17
src/main/resources/plugin.yml
Normal file
17
src/main/resources/plugin.yml
Normal file
@ -0,0 +1,17 @@
|
||||
name: PlaceholderSigns
|
||||
version: '${project.version}'
|
||||
main: net.knarcraft.placeholdersigns.PlaceholderSigns
|
||||
api-version: 1.19
|
||||
depend:
|
||||
- PlaceholderAPI
|
||||
|
||||
commands:
|
||||
editSign:
|
||||
usage: /<command> <line> <text> [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
|
Loading…
Reference in New Issue
Block a user