Implements #1
All checks were successful
KnarCraft/PlaceholderSigns/pipeline/head This commit looks good
All checks were successful
KnarCraft/PlaceholderSigns/pipeline/head This commit looks good
This commit is contained in:
parent
a34c63b7e2
commit
f8ca5705a5
16
README.md
16
README.md
@ -21,13 +21,14 @@ Note that commands have some restrictions in place, so giving the weakest permis
|
|||||||
- All sign changes are run through the SignChangeEvent, so the player cannot edit a sign if any protection plugin would
|
- All sign changes are run through the SignChangeEvent, so the player cannot edit a sign if any protection plugin would
|
||||||
prevent them from editing the sign normally.
|
prevent them from editing the sign normally.
|
||||||
|
|
||||||
| Command | Arguments | Description |
|
| Command | Arguments | Description |
|
||||||
|---------------|----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|----------------------------|----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| /setSignLine | \<line> \<text> \<text> ... | Sets the text of the sign line (1-4) to the given input. Then right-click the sign to update. |
|
| /setSignLine | \<line> \<text> \<text> ... | Sets the text of the sign line (1-4) to the given input. Then right-click the sign to update. |
|
||||||
| /viewSign | \[raw true/false] \[placeholders true/false] | Shows the full contents and details of the sign you are currently looking at. If "raw" is true, formatting codes are displayed. If placeholders is true, stored placeholders are displayed. |
|
| /viewSign | \[raw true/false] \[placeholders true/false] | Shows the full contents and details of the sign you are currently looking at. If "raw" is true, formatting codes are displayed. If placeholders is true, stored placeholders are displayed. |
|
||||||
| /copySign | | Copies the sign you are currently looking at to another sign, including placeholders, formatting codes, dye and waxed state. |
|
| /copySign | | Copies the sign you are currently looking at to another sign, including placeholders, formatting codes, dye and waxed state. |
|
||||||
| /copySignText | \[side] \[source line] \[target line] | Copies the text of the sign you are currently looking at to another sign, including placeholders and formatting codes. If no argument is given, both sides are copied, and the front text is copies to the side of the target sign you click. If a side is specified, the text of that side is copied, and pasted to the sign side you click (use `this` as the sign side to select the side you are looking at when executing the command). The source line argument is used to only copy a single line from the selected sign side. The target line argument is used to specify the line to paste to (defaults to same as the source line) on the clicked side. |
|
| /copySignText | \[side] \[source line] \[target line] | Copies the text of the sign you are currently looking at to another sign, including placeholders and formatting codes. If no argument is given, both sides are copied, and the front text is copies to the side of the target sign you click. If a side is specified, the text of that side is copied, and pasted to the sign side you click (use `this` as the sign side to select the side you are looking at when executing the command). The source line argument is used to only copy a single line from the selected sign side. The target line argument is used to specify the line to paste to (defaults to same as the source line) on the clicked side. |
|
||||||
| /unWaxSign | | Removes the wax from the sign you are currently looking at. |
|
| /unWaxSign | | Removes the wax from the sign you are currently looking at. |
|
||||||
|
| /setPlaceholderUpdateDelay | \<delay> | Sets the update delay in ticks for the placeholder sign you are currently looking at. Use "null" to un-set the value. 1 second = 20 ticks. |
|
||||||
|
|
||||||
## Permissions
|
## Permissions
|
||||||
|
|
||||||
@ -44,3 +45,4 @@ Note that commands have some restrictions in place, so giving the weakest permis
|
|||||||
| placeholdersigns.copy.use | false | Allows use of the /copySign and /copySignText commands. |
|
| placeholdersigns.copy.use | false | Allows use of the /copySign and /copySignText commands. |
|
||||||
| placeholdersigns.copy.bypass-waxed | false | Allows pasting a sign copied with /copySign and /copySignText onto a waxed sign. |
|
| placeholdersigns.copy.bypass-waxed | false | Allows pasting a sign copied with /copySign and /copySignText onto a waxed sign. |
|
||||||
| placeholdersigns.unwax | false | Allows use of the /unWaxSign command |
|
| placeholdersigns.unwax | false | Allows use of the /unWaxSign command |
|
||||||
|
| placeholdersigns.setdelay | false | Allows use of the /setPlaceholderUpdateDelay command |
|
@ -6,11 +6,14 @@ import net.knarcraft.knarlib.property.ColorConversion;
|
|||||||
import net.knarcraft.placeholdersigns.command.CopySignCommand;
|
import net.knarcraft.placeholdersigns.command.CopySignCommand;
|
||||||
import net.knarcraft.placeholdersigns.command.CopySignTextCommand;
|
import net.knarcraft.placeholdersigns.command.CopySignTextCommand;
|
||||||
import net.knarcraft.placeholdersigns.command.EditSignCommand;
|
import net.knarcraft.placeholdersigns.command.EditSignCommand;
|
||||||
|
import net.knarcraft.placeholdersigns.command.SetPlaceholderUpdateDelayCommand;
|
||||||
import net.knarcraft.placeholdersigns.command.UnWaxSignCommand;
|
import net.knarcraft.placeholdersigns.command.UnWaxSignCommand;
|
||||||
import net.knarcraft.placeholdersigns.command.ViewSignCommand;
|
import net.knarcraft.placeholdersigns.command.ViewSignCommand;
|
||||||
import net.knarcraft.placeholdersigns.config.PlaceholderSignMessage;
|
import net.knarcraft.placeholdersigns.config.PlaceholderSignMessage;
|
||||||
import net.knarcraft.placeholdersigns.handler.PlaceholderSignHandler;
|
import net.knarcraft.placeholdersigns.handler.PlaceholderSignHandler;
|
||||||
import net.knarcraft.placeholdersigns.handler.PlaceholderSignRequestHandler;
|
import net.knarcraft.placeholdersigns.handler.PlaceholderSignRequestHandler;
|
||||||
|
import net.knarcraft.placeholdersigns.handler.PlaceholderSignUpdateQueueHandler;
|
||||||
|
import net.knarcraft.placeholdersigns.listener.ChunkListener;
|
||||||
import net.knarcraft.placeholdersigns.listener.SignBreakListener;
|
import net.knarcraft.placeholdersigns.listener.SignBreakListener;
|
||||||
import net.knarcraft.placeholdersigns.listener.SignClickListener;
|
import net.knarcraft.placeholdersigns.listener.SignClickListener;
|
||||||
import net.knarcraft.placeholdersigns.listener.SignTextListener;
|
import net.knarcraft.placeholdersigns.listener.SignTextListener;
|
||||||
@ -18,6 +21,7 @@ import net.knarcraft.placeholdersigns.runnable.SignUpdate;
|
|||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.CommandExecutor;
|
import org.bukkit.command.CommandExecutor;
|
||||||
import org.bukkit.command.PluginCommand;
|
import org.bukkit.command.PluginCommand;
|
||||||
|
import org.bukkit.plugin.PluginManager;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@ -31,7 +35,9 @@ public final class PlaceholderSigns extends JavaPlugin {
|
|||||||
private static PlaceholderSigns instance;
|
private static PlaceholderSigns instance;
|
||||||
private PlaceholderSignHandler signHandler;
|
private PlaceholderSignHandler signHandler;
|
||||||
private PlaceholderSignRequestHandler requestHandler;
|
private PlaceholderSignRequestHandler requestHandler;
|
||||||
|
private PlaceholderSignUpdateQueueHandler updateQueueHandler;
|
||||||
private StringFormatter stringFormatter;
|
private StringFormatter stringFormatter;
|
||||||
|
private int signUpdateDelay;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets an instance of this plugin
|
* Gets an instance of this plugin
|
||||||
@ -53,21 +59,51 @@ public final class PlaceholderSigns extends JavaPlugin {
|
|||||||
return this.signHandler;
|
return this.signHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets this instance's placeholder sign request handler
|
||||||
|
*
|
||||||
|
* @return <p>The request handler</p>
|
||||||
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public PlaceholderSignRequestHandler getRequestHandler() {
|
public PlaceholderSignRequestHandler getRequestHandler() {
|
||||||
return this.requestHandler;
|
return this.requestHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets this instance's update queue handler
|
||||||
|
*
|
||||||
|
* @return <p>The update queue handler</p>
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public PlaceholderSignUpdateQueueHandler getUpdateQueueHandler() {
|
||||||
|
return this.updateQueueHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the string formatter to use for formatting messages
|
||||||
|
*
|
||||||
|
* @return <p>The string formatter</p>
|
||||||
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public StringFormatter getStringFormatter() {
|
public StringFormatter getStringFormatter() {
|
||||||
return this.stringFormatter;
|
return this.stringFormatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the default sign update delay
|
||||||
|
*
|
||||||
|
* @return <p>The sign update delay</p>
|
||||||
|
*/
|
||||||
|
public int getSignUpdateDelay() {
|
||||||
|
return this.signUpdateDelay;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
instance = this;
|
instance = this;
|
||||||
getConfig().options().copyDefaults(true);
|
getConfig().options().copyDefaults(true);
|
||||||
saveConfig();
|
saveConfig();
|
||||||
|
|
||||||
Translator translator = new Translator();
|
Translator translator = new Translator();
|
||||||
translator.registerMessageCategory(PlaceholderSignMessage.SUCCESS_CLICK_SIGN_TO_EDIT);
|
translator.registerMessageCategory(PlaceholderSignMessage.SUCCESS_CLICK_SIGN_TO_EDIT);
|
||||||
translator.setColorConversion(ColorConversion.RGB);
|
translator.setColorConversion(ColorConversion.RGB);
|
||||||
@ -77,9 +113,15 @@ public final class PlaceholderSigns extends JavaPlugin {
|
|||||||
this.stringFormatter.setNamePrefix("#A5682A[&r&l");
|
this.stringFormatter.setNamePrefix("#A5682A[&r&l");
|
||||||
this.stringFormatter.setNameSuffix("&r#A5682A]");
|
this.stringFormatter.setNameSuffix("&r#A5682A]");
|
||||||
|
|
||||||
|
signUpdateDelay = getConfig().getInt("defaultSignUpdateTicks", 100);
|
||||||
|
if (signUpdateDelay < 1) {
|
||||||
|
signUpdateDelay = 100;
|
||||||
|
}
|
||||||
|
|
||||||
this.signHandler = new PlaceholderSignHandler();
|
this.signHandler = new PlaceholderSignHandler();
|
||||||
this.signHandler.load();
|
this.signHandler.load();
|
||||||
this.requestHandler = new PlaceholderSignRequestHandler();
|
this.requestHandler = new PlaceholderSignRequestHandler();
|
||||||
|
this.updateQueueHandler = new PlaceholderSignUpdateQueueHandler();
|
||||||
|
|
||||||
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") == null) {
|
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") == null) {
|
||||||
getLogger().log(Level.WARNING, "Could not find PlaceholderAPI! This plugin is required.");
|
getLogger().log(Level.WARNING, "Could not find PlaceholderAPI! This plugin is required.");
|
||||||
@ -87,18 +129,20 @@ public final class PlaceholderSigns extends JavaPlugin {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update signs' placeholders every second
|
Bukkit.getScheduler().runTaskTimer(this, new SignUpdate(this.signHandler), 20, 1);
|
||||||
Bukkit.getScheduler().runTaskTimer(this, new SignUpdate(this.signHandler), 20 * 10, 20 * 5);
|
|
||||||
|
|
||||||
Bukkit.getPluginManager().registerEvents(new SignBreakListener(), this);
|
PluginManager pluginManager = Bukkit.getPluginManager();
|
||||||
Bukkit.getPluginManager().registerEvents(new SignTextListener(), this);
|
pluginManager.registerEvents(new SignBreakListener(), this);
|
||||||
Bukkit.getPluginManager().registerEvents(new SignClickListener(), this);
|
pluginManager.registerEvents(new SignTextListener(), this);
|
||||||
|
pluginManager.registerEvents(new SignClickListener(), this);
|
||||||
|
pluginManager.registerEvents(new ChunkListener(), this);
|
||||||
|
|
||||||
registerCommand("setSignLine", new EditSignCommand());
|
registerCommand("setSignLine", new EditSignCommand());
|
||||||
registerCommand("viewSign", new ViewSignCommand());
|
registerCommand("viewSign", new ViewSignCommand());
|
||||||
registerCommand("copySign", new CopySignCommand());
|
registerCommand("copySign", new CopySignCommand());
|
||||||
registerCommand("unWaxSign", new UnWaxSignCommand());
|
registerCommand("unWaxSign", new UnWaxSignCommand());
|
||||||
registerCommand("copySignText", new CopySignTextCommand());
|
registerCommand("copySignText", new CopySignTextCommand());
|
||||||
|
registerCommand("setPlaceholderUpdateDelay", new SetPlaceholderUpdateDelayCommand());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,77 @@
|
|||||||
|
package net.knarcraft.placeholdersigns.command;
|
||||||
|
|
||||||
|
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||||
|
import net.knarcraft.knarlib.util.TabCompletionHelper;
|
||||||
|
import net.knarcraft.placeholdersigns.PlaceholderSigns;
|
||||||
|
import net.knarcraft.placeholdersigns.config.PlaceholderSignMessage;
|
||||||
|
import net.knarcraft.placeholdersigns.container.PlaceholderSign;
|
||||||
|
import net.knarcraft.placeholdersigns.handler.PlaceholderSignHandler;
|
||||||
|
import net.knarcraft.placeholdersigns.util.TabCompleteHelper;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.Sign;
|
||||||
|
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;
|
||||||
|
|
||||||
|
public class SetPlaceholderUpdateDelayCommand implements TabExecutor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||||
|
@NotNull String[] arguments) {
|
||||||
|
PlaceholderSigns placeholderSigns = PlaceholderSigns.getInstance();
|
||||||
|
StringFormatter stringFormatter = placeholderSigns.getStringFormatter();
|
||||||
|
if (!(commandSender instanceof Player player)) {
|
||||||
|
stringFormatter.displayErrorMessage(commandSender, PlaceholderSignMessage.ERROR_PLAYER_ONLY);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arguments.length < 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block targetBlock = player.getTargetBlockExact(7);
|
||||||
|
if (targetBlock == null || !(targetBlock.getState() instanceof Sign sign)) {
|
||||||
|
stringFormatter.displayErrorMessage(commandSender, PlaceholderSignMessage.ERROR_NOT_LOOKING_AT_SIGN);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer updateDelay = null;
|
||||||
|
try {
|
||||||
|
updateDelay = Integer.parseInt(arguments[0]);
|
||||||
|
} catch (NumberFormatException exception) {
|
||||||
|
if (!arguments[0].equalsIgnoreCase("null")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PlaceholderSignHandler signHandler = placeholderSigns.getSignHandler();
|
||||||
|
PlaceholderSign placeholderSign = signHandler.getFromLocation(sign.getLocation());
|
||||||
|
if (placeholderSign != null) {
|
||||||
|
placeholderSign.setUpdateDelay(updateDelay);
|
||||||
|
signHandler.save();
|
||||||
|
stringFormatter.displaySuccessMessage(player, PlaceholderSignMessage.SUCCESS_UPDATE_DELAY_CHANGED);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
stringFormatter.displayErrorMessage(player, PlaceholderSignMessage.ERROR_NOT_LOOKING_AT_PLACEHOLDER_SIGN);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||||
|
@NotNull String[] arguments) {
|
||||||
|
if (arguments.length == 1) {
|
||||||
|
return TabCompletionHelper.filterMatchingStartsWith(TabCompleteHelper.getDelays(), arguments[0]);
|
||||||
|
} else {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -160,7 +160,7 @@ public class ViewSignCommand implements TabExecutor {
|
|||||||
return getSignText(lines, raw);
|
return getSignText(lines, raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<Integer, String> placeholders = placeholderSign.placeholders().get(side);
|
Map<Integer, String> placeholders = placeholderSign.getPlaceholders().get(side);
|
||||||
if (placeholders != null) {
|
if (placeholders != null) {
|
||||||
for (Map.Entry<Integer, String> entry : placeholders.entrySet()) {
|
for (Map.Entry<Integer, String> entry : placeholders.entrySet()) {
|
||||||
lines[entry.getKey()] = entry.getValue();
|
lines[entry.getKey()] = entry.getValue();
|
||||||
|
@ -67,6 +67,16 @@ public enum PlaceholderSignMessage implements TranslatableMessage {
|
|||||||
* The message displayed when a sign has been successfully un-waxed
|
* The message displayed when a sign has been successfully un-waxed
|
||||||
*/
|
*/
|
||||||
SUCCESS_SIGN_UN_WAXED,
|
SUCCESS_SIGN_UN_WAXED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The message displayed when the player isn't looking at a placeholder sign when required
|
||||||
|
*/
|
||||||
|
ERROR_NOT_LOOKING_AT_PLACEHOLDER_SIGN,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The message displayed when a placeholder sign update delay has been changed
|
||||||
|
*/
|
||||||
|
SUCCESS_UPDATE_DELAY_CHANGED,
|
||||||
;
|
;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -3,15 +3,78 @@ package net.knarcraft.placeholdersigns.container;
|
|||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.block.sign.Side;
|
import org.bukkit.block.sign.Side;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A sign containing one or more placeholders
|
* 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(@NotNull Location location, @NotNull Map<Side, Map<Integer, String>> placeholders) {
|
public final class PlaceholderSign {
|
||||||
|
|
||||||
|
private final @NotNull Location location;
|
||||||
|
private final @NotNull Map<Side, Map<Integer, String>> placeholders;
|
||||||
|
private @Nullable Integer updateDelay;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new placeholder sign
|
||||||
|
*
|
||||||
|
* @param location <p>The location of the sign</p>
|
||||||
|
* @param placeholders <p>The original placeholders typed on the sign</p>
|
||||||
|
* @param updateDelay <p>The delay in ticks between each time this sign's placeholders are updated</p>
|
||||||
|
*/
|
||||||
|
public PlaceholderSign(@NotNull Location location, @NotNull Map<Side, Map<Integer, String>> placeholders,
|
||||||
|
@Nullable Integer updateDelay) {
|
||||||
|
this.location = location;
|
||||||
|
this.placeholders = placeholders;
|
||||||
|
this.updateDelay = updateDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the location of this placeholder sign
|
||||||
|
*
|
||||||
|
* @return <p>The location of this placeholder sign</p>
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public Location getLocation() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the placeholders stored on this sign
|
||||||
|
*
|
||||||
|
* @return <p>The stored placeholders</p>
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public Map<Side, Map<Integer, String>> getPlaceholders() {
|
||||||
|
return placeholders;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the update delay for this placeholder sign
|
||||||
|
*
|
||||||
|
* @return <p>The update delay</p>
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public Integer getUpdateDelay() {
|
||||||
|
return updateDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the update delay for this placeholder sign
|
||||||
|
*
|
||||||
|
* @param updateDelay <p>The new update delay</p>
|
||||||
|
*/
|
||||||
|
public void setUpdateDelay(@Nullable Integer updateDelay) {
|
||||||
|
this.updateDelay = updateDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(@NotNull Object object) {
|
||||||
|
if (object instanceof PlaceholderSign otherSign) {
|
||||||
|
return this.location.equals(otherSign.location);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
package net.knarcraft.placeholdersigns.container;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A placeholder sign that's queued to be updated
|
||||||
|
*
|
||||||
|
* @param placeholderSign <p>The queued placeholder sign</p>
|
||||||
|
* @param updateTimestamp <p>The timestamp (long milliseconds) that the placeholder sign should be updated at</p>
|
||||||
|
*/
|
||||||
|
public record QueuedPlaceholderSign(@NotNull PlaceholderSign placeholderSign,
|
||||||
|
long updateTimestamp) implements Comparable<QueuedPlaceholderSign> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(@NotNull QueuedPlaceholderSign other) {
|
||||||
|
return Long.compare(this.updateTimestamp, other.updateTimestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -3,6 +3,7 @@ package net.knarcraft.placeholdersigns.handler;
|
|||||||
import net.knarcraft.placeholdersigns.PlaceholderSigns;
|
import net.knarcraft.placeholdersigns.PlaceholderSigns;
|
||||||
import net.knarcraft.placeholdersigns.container.PlaceholderSign;
|
import net.knarcraft.placeholdersigns.container.PlaceholderSign;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.sign.Side;
|
import org.bukkit.block.sign.Side;
|
||||||
@ -29,15 +30,7 @@ public class PlaceholderSignHandler {
|
|||||||
|
|
||||||
private Set<PlaceholderSign> placeholderSigns;
|
private Set<PlaceholderSign> placeholderSigns;
|
||||||
private Map<Location, PlaceholderSign> locationLookup;
|
private Map<Location, PlaceholderSign> locationLookup;
|
||||||
|
private Map<Chunk, Set<PlaceholderSign>> signsInChunk;
|
||||||
/**
|
|
||||||
* 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
|
* Gets a placeholder sign from the given location
|
||||||
@ -57,8 +50,11 @@ public class PlaceholderSignHandler {
|
|||||||
*/
|
*/
|
||||||
public void registerSign(@NotNull PlaceholderSign sign) {
|
public void registerSign(@NotNull PlaceholderSign sign) {
|
||||||
this.placeholderSigns.add(sign);
|
this.placeholderSigns.add(sign);
|
||||||
locationLookup.put(sign.location(), sign);
|
this.locationLookup.put(sign.getLocation(), sign);
|
||||||
save();
|
|
||||||
|
Chunk chunk = sign.getLocation().getChunk();
|
||||||
|
this.signsInChunk.putIfAbsent(chunk, new HashSet<>());
|
||||||
|
this.signsInChunk.get(chunk).add(sign);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,9 +63,24 @@ public class PlaceholderSignHandler {
|
|||||||
* @param sign <p>The sign to un-register</p>
|
* @param sign <p>The sign to un-register</p>
|
||||||
*/
|
*/
|
||||||
public void unregisterSign(@NotNull PlaceholderSign sign) {
|
public void unregisterSign(@NotNull PlaceholderSign sign) {
|
||||||
locationLookup.remove(sign.location());
|
this.locationLookup.remove(sign.getLocation());
|
||||||
this.placeholderSigns.remove(sign);
|
this.placeholderSigns.remove(sign);
|
||||||
save();
|
this.signsInChunk.get(sign.getLocation().getChunk()).remove(sign);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all placeholder signs in the given chunk
|
||||||
|
*
|
||||||
|
* @param chunk <p>The chunk to check</p>
|
||||||
|
* @return <p>All placeholder signs in the chunk</p>
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public Set<PlaceholderSign> getFromChunk(@NotNull Chunk chunk) {
|
||||||
|
if (this.signsInChunk.containsKey(chunk)) {
|
||||||
|
return this.signsInChunk.get(chunk);
|
||||||
|
} else {
|
||||||
|
return new HashSet<>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,6 +89,7 @@ public class PlaceholderSignHandler {
|
|||||||
public void load() {
|
public void load() {
|
||||||
this.placeholderSigns = new HashSet<>();
|
this.placeholderSigns = new HashSet<>();
|
||||||
this.locationLookup = new HashMap<>();
|
this.locationLookup = new HashMap<>();
|
||||||
|
this.signsInChunk = new HashMap<>();
|
||||||
|
|
||||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(signsFile);
|
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(signsFile);
|
||||||
ConfigurationSection signSection = configuration.getConfigurationSection("signs");
|
ConfigurationSection signSection = configuration.getConfigurationSection("signs");
|
||||||
@ -104,9 +116,16 @@ public class PlaceholderSignHandler {
|
|||||||
allPlaceholders.put(Side.FRONT, frontPlaceholders);
|
allPlaceholders.put(Side.FRONT, frontPlaceholders);
|
||||||
allPlaceholders.put(Side.BACK, backPlaceholders);
|
allPlaceholders.put(Side.BACK, backPlaceholders);
|
||||||
|
|
||||||
PlaceholderSign sign = new PlaceholderSign(signLocation, allPlaceholders);
|
String updateDelayKey = key + ".updateDelay";
|
||||||
this.placeholderSigns.add(sign);
|
int updateDelay = -1;
|
||||||
this.locationLookup.put(signLocation, sign);
|
if (signSection.contains(updateDelayKey)) {
|
||||||
|
updateDelay = signSection.getInt(updateDelayKey, -1);
|
||||||
|
}
|
||||||
|
if (updateDelay < 1) {
|
||||||
|
updateDelay = PlaceholderSigns.getInstance().getSignUpdateDelay();
|
||||||
|
}
|
||||||
|
|
||||||
|
registerSign(new PlaceholderSign(signLocation, allPlaceholders, updateDelay));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +172,7 @@ public class PlaceholderSignHandler {
|
|||||||
* @param sign <p>The sign to save</p>
|
* @param sign <p>The sign to save</p>
|
||||||
*/
|
*/
|
||||||
private void saveSign(@NotNull ConfigurationSection section, @NotNull PlaceholderSign sign) {
|
private void saveSign(@NotNull ConfigurationSection section, @NotNull PlaceholderSign sign) {
|
||||||
Location location = sign.location();
|
Location location = sign.getLocation();
|
||||||
if (location.getWorld() == null) {
|
if (location.getWorld() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -163,19 +182,21 @@ public class PlaceholderSignHandler {
|
|||||||
String frontKey = key + ".placeholders.front";
|
String frontKey = key + ".placeholders.front";
|
||||||
String backKey = key + ".placeholders.back";
|
String backKey = key + ".placeholders.back";
|
||||||
|
|
||||||
Map<Integer, String> frontPlaceholders = sign.placeholders().get(Side.FRONT);
|
Map<Integer, String> frontPlaceholders = sign.getPlaceholders().get(Side.FRONT);
|
||||||
if (frontPlaceholders != null) {
|
if (frontPlaceholders != null) {
|
||||||
for (Map.Entry<Integer, String> entry : frontPlaceholders.entrySet()) {
|
for (Map.Entry<Integer, String> entry : frontPlaceholders.entrySet()) {
|
||||||
section.set(frontKey + "." + entry.getKey(), entry.getValue());
|
section.set(frontKey + "." + entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<Integer, String> backPlaceholders = sign.placeholders().get(Side.BACK);
|
Map<Integer, String> backPlaceholders = sign.getPlaceholders().get(Side.BACK);
|
||||||
if (backPlaceholders != null) {
|
if (backPlaceholders != null) {
|
||||||
for (Map.Entry<Integer, String> entry : backPlaceholders.entrySet()) {
|
for (Map.Entry<Integer, String> entry : backPlaceholders.entrySet()) {
|
||||||
section.set(backKey + "." + entry.getKey(), entry.getValue());
|
section.set(backKey + "." + entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
section.set(key + ".updateDelay", sign.getUpdateDelay());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,77 @@
|
|||||||
|
package net.knarcraft.placeholdersigns.handler;
|
||||||
|
|
||||||
|
import net.knarcraft.placeholdersigns.container.PlaceholderSign;
|
||||||
|
import net.knarcraft.placeholdersigns.container.QueuedPlaceholderSign;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A handler for dealing with the placeholder sign update queue
|
||||||
|
*/
|
||||||
|
public class PlaceholderSignUpdateQueueHandler {
|
||||||
|
|
||||||
|
private final PriorityQueue<QueuedPlaceholderSign> signUpdateQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new placeholder sign update queue handler
|
||||||
|
*/
|
||||||
|
public PlaceholderSignUpdateQueueHandler() {
|
||||||
|
this.signUpdateQueue = new PriorityQueue<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Polls the queue for any placeholder signs due for update
|
||||||
|
*
|
||||||
|
* <p>No placeholder sign will be returned unless they are due to be updated.</p>
|
||||||
|
*
|
||||||
|
* @return <p>The next queued placeholder sign, or null if no such placeholder sign exists</p>
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public PlaceholderSign pollQueue() {
|
||||||
|
QueuedPlaceholderSign nextSign = signUpdateQueue.peek();
|
||||||
|
if (nextSign == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
long currentTime = System.currentTimeMillis();
|
||||||
|
if (nextSign.updateTimestamp() < currentTime) {
|
||||||
|
nextSign = signUpdateQueue.poll();
|
||||||
|
if (nextSign != null) {
|
||||||
|
return nextSign.placeholderSign();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Peeks at the next item in the queue
|
||||||
|
*
|
||||||
|
* @return <p>The next item in the queue, or null if empty</p>
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public QueuedPlaceholderSign peekQueue() {
|
||||||
|
return signUpdateQueue.peek();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the specified queued sign to the queue
|
||||||
|
*
|
||||||
|
* @param queuedSign <p>The queued sign to queue</p>
|
||||||
|
*/
|
||||||
|
public void queueSign(@NotNull QueuedPlaceholderSign queuedSign) {
|
||||||
|
this.signUpdateQueue.add(queuedSign);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* '
|
||||||
|
* Removes the specified placeholder sign from the queue
|
||||||
|
*
|
||||||
|
* @param placeholderSign <p>The placeholder sign to remove</p>
|
||||||
|
*/
|
||||||
|
public void unQueueSign(@NotNull PlaceholderSign placeholderSign) {
|
||||||
|
this.signUpdateQueue.removeIf((item) -> item.placeholderSign().equals(placeholderSign));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package net.knarcraft.placeholdersigns.listener;
|
||||||
|
|
||||||
|
import net.knarcraft.placeholdersigns.PlaceholderSigns;
|
||||||
|
import net.knarcraft.placeholdersigns.container.PlaceholderSign;
|
||||||
|
import net.knarcraft.placeholdersigns.container.QueuedPlaceholderSign;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.world.ChunkLoadEvent;
|
||||||
|
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A listener for the loading and unloading of chunks with placeholder signs
|
||||||
|
*/
|
||||||
|
public class ChunkListener implements Listener {
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onChunkLoad(@NotNull ChunkLoadEvent event) {
|
||||||
|
PlaceholderSigns instance = PlaceholderSigns.getInstance();
|
||||||
|
Set<PlaceholderSign> signsAtChunk = instance.getSignHandler().getFromChunk(event.getChunk());
|
||||||
|
long queueTime = System.currentTimeMillis();
|
||||||
|
for (PlaceholderSign sign : signsAtChunk) {
|
||||||
|
instance.getUpdateQueueHandler().queueSign(new QueuedPlaceholderSign(sign, queueTime++));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onChunkUnload(@NotNull ChunkUnloadEvent event) {
|
||||||
|
PlaceholderSigns instance = PlaceholderSigns.getInstance();
|
||||||
|
Set<PlaceholderSign> signsAtChunk = instance.getSignHandler().getFromChunk(event.getChunk());
|
||||||
|
for (PlaceholderSign sign : signsAtChunk) {
|
||||||
|
instance.getUpdateQueueHandler().unQueueSign(sign);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -27,6 +27,7 @@ public class SignBreakListener implements Listener {
|
|||||||
PlaceholderSign sign = signHandler.getFromLocation(block.getLocation());
|
PlaceholderSign sign = signHandler.getFromLocation(block.getLocation());
|
||||||
if (sign != null) {
|
if (sign != null) {
|
||||||
signHandler.unregisterSign(sign);
|
signHandler.unregisterSign(sign);
|
||||||
|
signHandler.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ public class SignClickListener implements Listener {
|
|||||||
|
|
||||||
String text = signTextCopyRequest.sign().getSide(signTextCopyRequest.side()).getLine(sourceLine);
|
String text = signTextCopyRequest.sign().getSide(signTextCopyRequest.side()).getLine(sourceLine);
|
||||||
if (sourcePlaceholderSign != null) {
|
if (sourcePlaceholderSign != null) {
|
||||||
Map<Side, Map<Integer, String>> placeholders = sourcePlaceholderSign.placeholders();
|
Map<Side, Map<Integer, String>> placeholders = sourcePlaceholderSign.getPlaceholders();
|
||||||
if (placeholders.containsKey(sourceSide) && placeholders.get(sourceSide).containsKey(sourceLine)) {
|
if (placeholders.containsKey(sourceSide) && placeholders.get(sourceSide).containsKey(sourceLine)) {
|
||||||
text = placeholders.get(sourceSide).get(sourceLine);
|
text = placeholders.get(sourceSide).get(sourceLine);
|
||||||
}
|
}
|
||||||
@ -162,12 +162,12 @@ public class SignClickListener implements Listener {
|
|||||||
// Remove old placeholders from the sign side
|
// Remove old placeholders from the sign side
|
||||||
Map<Integer, String> oldPlaceholders = null;
|
Map<Integer, String> oldPlaceholders = null;
|
||||||
if (targetPlaceholderSign != null) {
|
if (targetPlaceholderSign != null) {
|
||||||
oldPlaceholders = targetPlaceholderSign.placeholders().remove(clickedSide);
|
oldPlaceholders = targetPlaceholderSign.getPlaceholders().remove(clickedSide);
|
||||||
}
|
}
|
||||||
if (pasteSignSide(sourceSide, clickedSide, sourceSign, targetSign,
|
if (pasteSignSide(sourceSide, clickedSide, sourceSign, targetSign,
|
||||||
sourcePlaceholderSign, player) && targetPlaceholderSign != null) {
|
sourcePlaceholderSign, player) && targetPlaceholderSign != null) {
|
||||||
// Restore the old placeholders if the sign change didn't finish
|
// Restore the old placeholders if the sign change didn't finish
|
||||||
targetPlaceholderSign.placeholders().put(clickedSide, oldPlaceholders);
|
targetPlaceholderSign.getPlaceholders().put(clickedSide, oldPlaceholders);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save any placeholder changes
|
// Save any placeholder changes
|
||||||
@ -307,7 +307,7 @@ public class SignClickListener implements Listener {
|
|||||||
@NotNull Player player) {
|
@NotNull Player player) {
|
||||||
String[] sideLines = signSide.getLines();
|
String[] sideLines = signSide.getLines();
|
||||||
if (placeholderSign != null) {
|
if (placeholderSign != null) {
|
||||||
Map<Side, Map<Integer, String>> placeholders = placeholderSign.placeholders();
|
Map<Side, Map<Integer, String>> placeholders = placeholderSign.getPlaceholders();
|
||||||
loadPlaceholders(sourceSide, sideLines, placeholders);
|
loadPlaceholders(sourceSide, sideLines, placeholders);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,7 +385,7 @@ public class SignClickListener implements Listener {
|
|||||||
String oldPlaceholder = null;
|
String oldPlaceholder = null;
|
||||||
if (targetPlaceholderSign != null) {
|
if (targetPlaceholderSign != null) {
|
||||||
// Remove the old placeholder
|
// Remove the old placeholder
|
||||||
oldPlaceholder = targetPlaceholderSign.placeholders().get(targetSide).remove(destinationLine);
|
oldPlaceholder = targetPlaceholderSign.getPlaceholders().get(targetSide).remove(destinationLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
lines[destinationLine] = newText;
|
lines[destinationLine] = newText;
|
||||||
@ -396,7 +396,7 @@ public class SignClickListener implements Listener {
|
|||||||
if (changeEvent.isCancelled()) {
|
if (changeEvent.isCancelled()) {
|
||||||
if (targetPlaceholderSign != null) {
|
if (targetPlaceholderSign != null) {
|
||||||
// Restore the old placeholder if the action didn't complete
|
// Restore the old placeholder if the action didn't complete
|
||||||
targetPlaceholderSign.placeholders().get(targetSide).put(destinationLine, oldPlaceholder);
|
targetPlaceholderSign.getPlaceholders().get(targetSide).put(destinationLine, oldPlaceholder);
|
||||||
}
|
}
|
||||||
PlaceholderSigns.getInstance().getStringFormatter().displayErrorMessage(player,
|
PlaceholderSigns.getInstance().getStringFormatter().displayErrorMessage(player,
|
||||||
PlaceholderSignMessage.ERROR_CANCELLED_BY_PROTECTION);
|
PlaceholderSignMessage.ERROR_CANCELLED_BY_PROTECTION);
|
||||||
|
@ -61,11 +61,12 @@ public class SignTextListener implements Listener {
|
|||||||
placeholderSide.put(event.getSide(), placeholders);
|
placeholderSide.put(event.getSide(), placeholders);
|
||||||
|
|
||||||
// Register a new placeholder sign
|
// Register a new placeholder sign
|
||||||
PlaceholderSign placeholderSign = new PlaceholderSign(event.getBlock().getLocation(), placeholderSide);
|
PlaceholderSign placeholderSign = new PlaceholderSign(event.getBlock().getLocation(), placeholderSide, null);
|
||||||
signHandler.registerSign(placeholderSign);
|
signHandler.registerSign(placeholderSign);
|
||||||
|
signHandler.save();
|
||||||
} else if (!placeholders.isEmpty()) {
|
} else if (!placeholders.isEmpty()) {
|
||||||
// Overwrite the placeholders of the existing placeholder sign
|
// Overwrite the placeholders of the existing placeholder sign
|
||||||
Map<Integer, String> existing = existingSign.placeholders().computeIfAbsent(event.getSide(), k -> new HashMap<>());
|
Map<Integer, String> existing = existingSign.getPlaceholders().computeIfAbsent(event.getSide(), k -> new HashMap<>());
|
||||||
existing.putAll(placeholders);
|
existing.putAll(placeholders);
|
||||||
signHandler.save();
|
signHandler.save();
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,11 @@ package net.knarcraft.placeholdersigns.runnable;
|
|||||||
import me.clip.placeholderapi.PlaceholderAPI;
|
import me.clip.placeholderapi.PlaceholderAPI;
|
||||||
import net.knarcraft.knarlib.property.ColorConversion;
|
import net.knarcraft.knarlib.property.ColorConversion;
|
||||||
import net.knarcraft.knarlib.util.ColorHelper;
|
import net.knarcraft.knarlib.util.ColorHelper;
|
||||||
|
import net.knarcraft.placeholdersigns.PlaceholderSigns;
|
||||||
import net.knarcraft.placeholdersigns.container.PlaceholderSign;
|
import net.knarcraft.placeholdersigns.container.PlaceholderSign;
|
||||||
|
import net.knarcraft.placeholdersigns.container.QueuedPlaceholderSign;
|
||||||
import net.knarcraft.placeholdersigns.handler.PlaceholderSignHandler;
|
import net.knarcraft.placeholdersigns.handler.PlaceholderSignHandler;
|
||||||
|
import net.knarcraft.placeholdersigns.handler.PlaceholderSignUpdateQueueHandler;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.block.Sign;
|
import org.bukkit.block.Sign;
|
||||||
import org.bukkit.block.sign.Side;
|
import org.bukkit.block.sign.Side;
|
||||||
@ -31,40 +34,67 @@ public class SignUpdate implements Runnable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
for (PlaceholderSign placeholderSign : signHandler.getSigns()) {
|
PlaceholderSigns instance = PlaceholderSigns.getInstance();
|
||||||
// Ignore signs away from players
|
PlaceholderSignUpdateQueueHandler queueHandler = instance.getUpdateQueueHandler();
|
||||||
Location location = placeholderSign.location();
|
|
||||||
if (!location.getChunk().isLoaded()) {
|
long startTime = System.nanoTime();
|
||||||
continue;
|
long currentTime = System.currentTimeMillis();
|
||||||
|
while (queueHandler.peekQueue() != null && System.nanoTime() - startTime < 25000000) {
|
||||||
|
PlaceholderSign placeholderSign = instance.getUpdateQueueHandler().pollQueue();
|
||||||
|
if (placeholderSign == null) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no longer a sign, remove
|
updatePlaceholderSign(placeholderSign, currentTime);
|
||||||
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<Side, Map<Integer, String>> 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 contents of a single placeholder sign
|
||||||
|
*
|
||||||
|
* @param placeholderSign <p>The placeholder sign to update</p>
|
||||||
|
* @param currentTime <p>The current time, used for re-queuing the sign</p>
|
||||||
|
*/
|
||||||
|
private void updatePlaceholderSign(@NotNull PlaceholderSign placeholderSign, long currentTime) {
|
||||||
|
PlaceholderSigns instance = PlaceholderSigns.getInstance();
|
||||||
|
|
||||||
|
// Ignore signs away from players
|
||||||
|
Location location = placeholderSign.getLocation();
|
||||||
|
|
||||||
|
// If no longer a sign, remove
|
||||||
|
if (!(location.getBlock().getState() instanceof Sign sign)) {
|
||||||
|
this.signHandler.unregisterSign(placeholderSign);
|
||||||
|
this.signHandler.save();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update placeholders
|
||||||
|
SignSide front = sign.getSide(Side.FRONT);
|
||||||
|
SignSide back = sign.getSide(Side.BACK);
|
||||||
|
Map<Side, Map<Integer, String>> placeholders = placeholderSign.getPlaceholders();
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer updateDelay = placeholderSign.getUpdateDelay();
|
||||||
|
if (updateDelay == null) {
|
||||||
|
updateDelay = instance.getSignUpdateDelay();
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.getUpdateQueueHandler().queueSign(new QueuedPlaceholderSign(placeholderSign, currentTime + (updateDelay * 50)));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the values of placeholders on a sign
|
* Updates the values of placeholders on a sign
|
||||||
*
|
*
|
||||||
|
@ -13,6 +13,7 @@ public final class TabCompleteHelper {
|
|||||||
|
|
||||||
private static final List<String> lineNumbers;
|
private static final List<String> lineNumbers;
|
||||||
private static final List<String> signSides;
|
private static final List<String> signSides;
|
||||||
|
private static final List<String> updateDelays;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
lineNumbers = new ArrayList<>();
|
lineNumbers = new ArrayList<>();
|
||||||
@ -24,12 +25,24 @@ public final class TabCompleteHelper {
|
|||||||
for (Side side : Side.values()) {
|
for (Side side : Side.values()) {
|
||||||
signSides.add(side.name());
|
signSides.add(side.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateDelays = List.of("null", "1", "5", "10", "20", "40", "60", "80", "100");
|
||||||
}
|
}
|
||||||
|
|
||||||
private TabCompleteHelper() {
|
private TabCompleteHelper() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets possible sign update delays
|
||||||
|
*
|
||||||
|
* @return <p>Possible sign update delays</p>
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static List<String> getDelays() {
|
||||||
|
return new ArrayList<>(updateDelays);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets possible sign line numbers
|
* Gets possible sign line numbers
|
||||||
*
|
*
|
||||||
|
@ -1,2 +1,8 @@
|
|||||||
# The chosen language for PlaceholderSigns. You can use "en" or any custom language specified in strings.yml
|
# The chosen language for PlaceholderSigns. You can use "en" or any custom language specified in strings.yml
|
||||||
language: en
|
language: en
|
||||||
|
|
||||||
|
# How often to update placeholders by default in ticks. 1 second = 20 ticks. The default is 100 ticks = 5 seconds. Note
|
||||||
|
# that only loaded chunks will have their signs updated to reduce lag and RAM usage from chunk loading. Still, it is
|
||||||
|
# recommended to set this to a higher value, and only reduce the update delay for individual signs where updated
|
||||||
|
# information is critical. 1 is the minimal accepted value.
|
||||||
|
defaultSignUpdateTicks: 100
|
@ -21,6 +21,7 @@ commands:
|
|||||||
unWaxSign:
|
unWaxSign:
|
||||||
usage: /<command>
|
usage: /<command>
|
||||||
permission: placeholdersigns.unwax
|
permission: placeholdersigns.unwax
|
||||||
|
description: Removes the wax from a waxed sign
|
||||||
copySignText:
|
copySignText:
|
||||||
usage: |
|
usage: |
|
||||||
/<command> [side] [sourceLine] [destinationLine]
|
/<command> [side] [sourceLine] [destinationLine]
|
||||||
@ -29,6 +30,10 @@ commands:
|
|||||||
destinationLine = The destination sign line to overwrite. If not set, it's the same as sourceLine
|
destinationLine = The destination sign line to overwrite. If not set, it's the same as sourceLine
|
||||||
permission: placeholdersigns.copy.use
|
permission: placeholdersigns.copy.use
|
||||||
description: Copies all text, or a single line, from one sign to another, either the specified side or both
|
description: Copies all text, or a single line, from one sign to another, either the specified side or both
|
||||||
|
setPlaceholderUpdateDelay:
|
||||||
|
usage: /<command> <delay in ticks>
|
||||||
|
permission: placeholdersigns.setdelay
|
||||||
|
description: Sets the update delay for a placeholder sign
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
placeholdersigns.*:
|
placeholdersigns.*:
|
||||||
@ -39,6 +44,7 @@ permissions:
|
|||||||
- placeholdersigns.view
|
- placeholdersigns.view
|
||||||
- placeholdersigns.copy
|
- placeholdersigns.copy
|
||||||
- placeholdersigns.unwax
|
- placeholdersigns.unwax
|
||||||
|
- placeholdersigns.setdelay
|
||||||
default: op
|
default: op
|
||||||
placeholdersigns.minimal:
|
placeholdersigns.minimal:
|
||||||
description: Allows minimal access to /setSignLine, /copySign, /copySignText and /viewSign
|
description: Allows minimal access to /setSignLine, /copySign, /copySignText and /viewSign
|
||||||
@ -79,3 +85,6 @@ permissions:
|
|||||||
placeholdersigns.unwax:
|
placeholdersigns.unwax:
|
||||||
description: Allows a player to use the /unWax command
|
description: Allows a player to use the /unWax command
|
||||||
default: false
|
default: false
|
||||||
|
placeholdersigns.setdelay:
|
||||||
|
description: Allows a player to use the /setPlaceholderUpdateDelay command
|
||||||
|
default: false
|
@ -19,3 +19,5 @@ en:
|
|||||||
SUCCESS_SIGN_PASTED: "&7Sign pasted!"
|
SUCCESS_SIGN_PASTED: "&7Sign pasted!"
|
||||||
ERROR_CANCELLED_BY_PROTECTION: "A protection plugin blocked the sign change"
|
ERROR_CANCELLED_BY_PROTECTION: "A protection plugin blocked the sign change"
|
||||||
SUCCESS_SIGN_UN_WAXED: "&7The sign was successfully un-waxed"
|
SUCCESS_SIGN_UN_WAXED: "&7The sign was successfully un-waxed"
|
||||||
|
ERROR_NOT_LOOKING_AT_PLACEHOLDER_SIGN: "You are not currently looking at a placeholder sign"
|
||||||
|
SUCCESS_UPDATE_DELAY_CHANGED: "&7The placeholder sign's update delay was successfully updated"
|
Loading…
Reference in New Issue
Block a user