Adds a copySign command and stuff
All checks were successful
KnarCraft/PlaceholderSigns/pipeline/head This commit looks good
All checks were successful
KnarCraft/PlaceholderSigns/pipeline/head This commit looks good
Adds a new copySign command that copies all info about a sign, including current lines, placeholders, waxed state, dye for each side, and glow state for each side. Renames editSign to setSignLine to avoid collision with EssentialsX's editSign Reduces viewSign to a single command Makes viewSign display the looked at sign, instead of creating a session Adds some additional messages Adds missing documentation to the README
This commit is contained in:
@@ -3,8 +3,8 @@ package net.knarcraft.placeholdersigns;
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.knarlib.formatting.Translator;
|
||||
import net.knarcraft.knarlib.property.ColorConversion;
|
||||
import net.knarcraft.placeholdersigns.command.CopySignCommand;
|
||||
import net.knarcraft.placeholdersigns.command.EditSignCommand;
|
||||
import net.knarcraft.placeholdersigns.command.ViewPlaceholderSignCommand;
|
||||
import net.knarcraft.placeholdersigns.command.ViewSignCommand;
|
||||
import net.knarcraft.placeholdersigns.config.PlaceholderSignMessage;
|
||||
import net.knarcraft.placeholdersigns.handler.PlaceholderSignHandler;
|
||||
@@ -92,11 +92,9 @@ public final class PlaceholderSigns extends JavaPlugin {
|
||||
Bukkit.getPluginManager().registerEvents(new SignTextListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new SignClickListener(), this);
|
||||
|
||||
registerCommand("editSign", new EditSignCommand());
|
||||
registerCommand("viewSign", new ViewSignCommand(false));
|
||||
registerCommand("viewSignRaw", new ViewSignCommand(true));
|
||||
registerCommand("viewPlaceholderSign", new ViewPlaceholderSignCommand(false));
|
||||
registerCommand("viewPlaceholderSignRaw", new ViewPlaceholderSignCommand(true));
|
||||
registerCommand("setSignLine", new EditSignCommand());
|
||||
registerCommand("viewSign", new ViewSignCommand());
|
||||
registerCommand("copySign", new CopySignCommand());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -0,0 +1,54 @@
|
||||
package net.knarcraft.placeholdersigns.command;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.placeholdersigns.PlaceholderSigns;
|
||||
import net.knarcraft.placeholdersigns.config.PlaceholderSignMessage;
|
||||
import net.knarcraft.placeholdersigns.container.SignCopyRequest;
|
||||
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;
|
||||
|
||||
/**
|
||||
* A command for copying signs, including placeholders
|
||||
*/
|
||||
public class CopySignCommand implements TabExecutor {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] strings) {
|
||||
PlaceholderSigns placeholderSigns = PlaceholderSigns.getInstance();
|
||||
StringFormatter stringFormatter = placeholderSigns.getStringFormatter();
|
||||
if (!(commandSender instanceof Player player)) {
|
||||
stringFormatter.displayErrorMessage(commandSender, PlaceholderSignMessage.ERROR_PLAYER_ONLY);
|
||||
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;
|
||||
}
|
||||
|
||||
SignCopyRequest signCopyRequest = new SignCopyRequest(player, sign);
|
||||
placeholderSigns.getRequestHandler().addSignCopyRequest(signCopyRequest);
|
||||
|
||||
stringFormatter.displaySuccessMessage(commandSender, PlaceholderSignMessage.SUCCESS_CLICK_SIGN_TO_PASTE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] strings) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
package net.knarcraft.placeholdersigns.command;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.placeholdersigns.PlaceholderSigns;
|
||||
import net.knarcraft.placeholdersigns.config.PlaceholderSignMessage;
|
||||
import net.knarcraft.placeholdersigns.container.SignLineChangeRequest;
|
||||
@@ -30,7 +31,13 @@ public class EditSignCommand implements TabExecutor {
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] args) {
|
||||
if (args.length < 1 || !(commandSender instanceof Player player)) {
|
||||
PlaceholderSigns placeholderSigns = PlaceholderSigns.getInstance();
|
||||
StringFormatter stringFormatter = placeholderSigns.getStringFormatter();
|
||||
if (!(commandSender instanceof Player player)) {
|
||||
stringFormatter.displayErrorMessage(commandSender, PlaceholderSignMessage.ERROR_PLAYER_ONLY);
|
||||
return false;
|
||||
}
|
||||
if (args.length < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -61,11 +68,9 @@ public class EditSignCommand implements TabExecutor {
|
||||
|
||||
// Register the line change request
|
||||
SignLineChangeRequest request = new SignLineChangeRequest(player, lineNumber - 1, builder.toString());
|
||||
PlaceholderSigns placeholderSigns = PlaceholderSigns.getInstance();
|
||||
placeholderSigns.getRequestHandler().addSignChangeRequest(request);
|
||||
|
||||
placeholderSigns.getStringFormatter().displaySuccessMessage(commandSender,
|
||||
PlaceholderSignMessage.SUCCESS_CLICK_SIGN_TO_EDIT);
|
||||
stringFormatter.displaySuccessMessage(commandSender, PlaceholderSignMessage.SUCCESS_CLICK_SIGN_TO_EDIT);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -1,53 +0,0 @@
|
||||
package net.knarcraft.placeholdersigns.command;
|
||||
|
||||
import net.knarcraft.placeholdersigns.PlaceholderSigns;
|
||||
import net.knarcraft.placeholdersigns.config.PlaceholderSignMessage;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A command for viewing placeholders on a sign
|
||||
*/
|
||||
public class ViewPlaceholderSignCommand implements TabExecutor {
|
||||
|
||||
private final boolean raw;
|
||||
|
||||
/**
|
||||
* Instantiates a new view sign command
|
||||
*
|
||||
* @param raw <p>Whether this sign displays the raw text or not</p>
|
||||
*/
|
||||
public ViewPlaceholderSignCommand(boolean raw) {
|
||||
this.raw = raw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String label,
|
||||
@NotNull String[] args) {
|
||||
if (!(commandSender instanceof Player player)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Register the sign view request
|
||||
PlaceholderSigns.getInstance().getRequestHandler().addPlaceholderSignViewRequest(player, this.raw);
|
||||
|
||||
PlaceholderSigns.getInstance().getStringFormatter().displaySuccessMessage(commandSender,
|
||||
PlaceholderSignMessage.SUCCESS_CLICK_SIGN_TO_VIEW);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
|
||||
@NotNull String[] args) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
@@ -1,7 +1,19 @@
|
||||
package net.knarcraft.placeholdersigns.command;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.knarlib.formatting.StringReplacer;
|
||||
import net.knarcraft.knarlib.util.ColorHelper;
|
||||
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.md_5.bungee.api.ChatColor;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.sign.Side;
|
||||
import org.bukkit.block.sign.SignSide;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
@@ -11,43 +23,172 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A command for viewing lines on a sign
|
||||
* A generic sign view command
|
||||
*/
|
||||
public class ViewSignCommand implements TabExecutor {
|
||||
|
||||
private final boolean raw;
|
||||
|
||||
/**
|
||||
* Instantiates a new view sign command
|
||||
*
|
||||
* @param raw <p>Whether this sign displays the raw text or not</p>
|
||||
*/
|
||||
public ViewSignCommand(boolean raw) {
|
||||
this.raw = raw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String label,
|
||||
@NotNull String[] args) {
|
||||
@NotNull String[] arguments) {
|
||||
StringFormatter stringFormatter = PlaceholderSigns.getInstance().getStringFormatter();
|
||||
if (!(commandSender instanceof Player player)) {
|
||||
stringFormatter.displayErrorMessage(commandSender, PlaceholderSignMessage.ERROR_PLAYER_ONLY);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Register the sign view request
|
||||
PlaceholderSigns.getInstance().getRequestHandler().addSignViewRequest(player, this.raw);
|
||||
boolean showRawText = true;
|
||||
boolean showPlaceholders = true;
|
||||
if (arguments.length > 0) {
|
||||
showRawText = Boolean.parseBoolean(arguments[0]);
|
||||
}
|
||||
if (arguments.length > 1) {
|
||||
showPlaceholders = Boolean.parseBoolean(arguments[1]);
|
||||
}
|
||||
|
||||
PlaceholderSigns.getInstance().getStringFormatter().displaySuccessMessage(commandSender,
|
||||
PlaceholderSignMessage.SUCCESS_CLICK_SIGN_TO_VIEW);
|
||||
Block targetBlock = player.getTargetBlockExact(7);
|
||||
if (targetBlock == null || !(targetBlock.getState() instanceof Sign sign)) {
|
||||
stringFormatter.displayErrorMessage(commandSender, PlaceholderSignMessage.ERROR_NOT_LOOKING_AT_SIGN);
|
||||
return false;
|
||||
}
|
||||
|
||||
printSign(sign, player, showRawText, showPlaceholders);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
|
||||
@NotNull String[] args) {
|
||||
return new ArrayList<>();
|
||||
@NotNull String[] arguments) {
|
||||
if (arguments.length == 1) {
|
||||
return getBooleanTabCompletions(arguments[0]);
|
||||
} else if (arguments.length == 2) {
|
||||
return getBooleanTabCompletions(arguments[1]);
|
||||
} else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets boolean tab-completions
|
||||
*
|
||||
* @param filter <p>The input argument to filter by</p>
|
||||
* @return <p>The the resulting boolean tab-completions</p>
|
||||
*/
|
||||
@NotNull
|
||||
private List<String> getBooleanTabCompletions(@NotNull String filter) {
|
||||
return TabCompletionHelper.filterMatchingStartsWith(List.of("true", "false"), filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the current contents of a sign to a player
|
||||
*
|
||||
* @param sign <p>The sign to print</p>
|
||||
* @param player <p>The player to display the contents to</p>
|
||||
*/
|
||||
private void printSign(@NotNull Sign sign, @NotNull Player player, boolean showRawText, boolean showPlaceholders) {
|
||||
Location location = sign.getLocation();
|
||||
SignSide front = sign.getSide(Side.FRONT);
|
||||
SignSide back = sign.getSide(Side.BACK);
|
||||
String frontLines = showPlaceholders ? getPlaceholderSignText(location, front, Side.FRONT, showRawText) :
|
||||
getSignText(front.getLines(), showRawText);
|
||||
String backLines = showPlaceholders ? getPlaceholderSignText(location, back, Side.BACK, showRawText) :
|
||||
getSignText(back.getLines(), showRawText);
|
||||
|
||||
StringFormatter stringFormatter = PlaceholderSigns.getInstance().getStringFormatter();
|
||||
StringReplacer replacer = new StringReplacer(stringFormatter.getUnformattedColoredMessage(
|
||||
PlaceholderSignMessage.SUCCESS_SIGN_CONTENTS));
|
||||
replacer.add("{frontLines}", frontLines);
|
||||
replacer.add("{backLines}", backLines);
|
||||
replacer.add("{frontDye}", getDye(front));
|
||||
replacer.add("{frontGlow}", getStatus(front.isGlowingText()));
|
||||
replacer.add("{backDye}", getDye(back));
|
||||
replacer.add("{backGlow}", getStatus(back.isGlowingText()));
|
||||
replacer.add("{waxed}", getStatus(sign.isWaxed()));
|
||||
player.sendMessage(replacer.replace());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a description of the status of a sign property
|
||||
*
|
||||
* @param isTrue <p>Whether the property is true</p>
|
||||
* @return <p>A description of the property's current status</p>
|
||||
*/
|
||||
@NotNull
|
||||
private String getStatus(boolean isTrue) {
|
||||
StringFormatter stringFormatter = PlaceholderSigns.getInstance().getStringFormatter();
|
||||
if (isTrue) {
|
||||
return stringFormatter.getUnformattedColoredMessage(PlaceholderSignMessage.SIGN_PROPERTY_CONFIRM);
|
||||
} else {
|
||||
return stringFormatter.getUnformattedColoredMessage(PlaceholderSignMessage.SIGN_PROPERTY_DENY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a description of a dye applied to a sign
|
||||
*
|
||||
* @param signSide <p>The sign side to get the dye of</p>
|
||||
* @return <p>The description of the applied dye</p>
|
||||
*/
|
||||
@NotNull
|
||||
private String getDye(@NotNull SignSide signSide) {
|
||||
DyeColor dyeColor = signSide.getColor();
|
||||
if (dyeColor == null) {
|
||||
return "None";
|
||||
}
|
||||
|
||||
ChatColor color = ColorHelper.fromColor(dyeColor.getColor());
|
||||
return color + signSide.getColor().name();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets text from a sign side, and appends it to the given string builder
|
||||
*
|
||||
* @param signLocation <p>The location of the sign</p>
|
||||
* @param signSide <p>The sign side to get text from</p>
|
||||
* @param side <p>The side of the sign to get placeholders from</p>
|
||||
* @param raw <p>Whether to get the raw text with used formatting codes</p>
|
||||
*/
|
||||
@NotNull
|
||||
private String getPlaceholderSignText(@NotNull Location signLocation, @NotNull SignSide signSide,
|
||||
@NotNull Side side, boolean raw) {
|
||||
String[] lines = signSide.getLines();
|
||||
PlaceholderSign placeholderSign = PlaceholderSigns.getInstance().getSignHandler().getFromLocation(signLocation);
|
||||
if (placeholderSign == null) {
|
||||
return getSignText(lines, raw);
|
||||
}
|
||||
|
||||
Map<Integer, String> placeholders = placeholderSign.placeholders().get(side);
|
||||
for (Map.Entry<Integer, String> entry : placeholders.entrySet()) {
|
||||
lines[entry.getKey()] = entry.getValue();
|
||||
}
|
||||
|
||||
return getSignText(lines, raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets text from a sign side, and appends it to the given string builder
|
||||
*
|
||||
* @param lines <p>The lines on the sign</p>
|
||||
* @param raw <p>Whether to get the raw text with used formatting codes</p>
|
||||
*/
|
||||
@NotNull
|
||||
private String getSignText(@NotNull String[] lines, boolean raw) {
|
||||
StringBuilder output = new StringBuilder();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
output.append(i + 1).append(". ");
|
||||
|
||||
String line = lines[i];
|
||||
if (raw) {
|
||||
output.append(line.replace(ChatColor.COLOR_CHAR, '&'));
|
||||
} else {
|
||||
output.append(line);
|
||||
}
|
||||
output.append(ChatColor.COLOR_CHAR).append("r\n");
|
||||
}
|
||||
return output.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -13,11 +13,6 @@ public enum PlaceholderSignMessage implements TranslatableMessage {
|
||||
*/
|
||||
SUCCESS_CLICK_SIGN_TO_EDIT,
|
||||
|
||||
/**
|
||||
* The message to display when waiting for a sign selection (view)
|
||||
*/
|
||||
SUCCESS_CLICK_SIGN_TO_VIEW,
|
||||
|
||||
/**
|
||||
* The message displayed when a player tries to edit a waxed sign without the necessary permission
|
||||
*/
|
||||
@@ -42,6 +37,31 @@ public enum PlaceholderSignMessage implements TranslatableMessage {
|
||||
* The string displayed when a sign property is denied
|
||||
*/
|
||||
SIGN_PROPERTY_DENY,
|
||||
|
||||
/**
|
||||
* The message displayed when a player command is used from the console
|
||||
*/
|
||||
ERROR_PLAYER_ONLY,
|
||||
|
||||
/**
|
||||
* The message to display when the player is not looking at a sign, which is required
|
||||
*/
|
||||
ERROR_NOT_LOOKING_AT_SIGN,
|
||||
|
||||
/**
|
||||
* The message displayed when ready to paste a sign
|
||||
*/
|
||||
SUCCESS_CLICK_SIGN_TO_PASTE,
|
||||
|
||||
/**
|
||||
* The message displayed when a sign is successfully pasted
|
||||
*/
|
||||
SUCCESS_SIGN_PASTED,
|
||||
|
||||
/**
|
||||
* The message displayed when a protection plugin cancels the sign change event
|
||||
*/
|
||||
ERROR_CANCELLED_BY_PROTECTION,
|
||||
;
|
||||
|
||||
@Override
|
||||
|
@@ -0,0 +1,14 @@
|
||||
package net.knarcraft.placeholdersigns.container;
|
||||
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A record of a player's request to copy a sign
|
||||
*
|
||||
* @param player <p>The player requesting the sign copy</p>
|
||||
* @param sign <p>The sign the player wants to copy</p>
|
||||
*/
|
||||
public record SignCopyRequest(@NotNull Player player, @NotNull Sign sign) {
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
package net.knarcraft.placeholdersigns.handler;
|
||||
|
||||
import net.knarcraft.placeholdersigns.container.SignCopyRequest;
|
||||
import net.knarcraft.placeholdersigns.container.SignLineChangeRequest;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -13,17 +14,38 @@ import java.util.Map;
|
||||
*/
|
||||
public class PlaceholderSignRequestHandler {
|
||||
|
||||
private final Map<Player, SignLineChangeRequest> signChangeRequests;
|
||||
private final Map<Player, Boolean> signViewRequests;
|
||||
private final Map<Player, Boolean> placeholderSignViewRequests;
|
||||
private final @NotNull Map<Player, SignLineChangeRequest> signChangeRequests;
|
||||
private final Map<Player, SignCopyRequest> signCopyRequests;
|
||||
|
||||
/**
|
||||
* Instantiates a new placeholder sign request handler
|
||||
*/
|
||||
public PlaceholderSignRequestHandler() {
|
||||
this.signChangeRequests = new HashMap<>();
|
||||
this.signViewRequests = new HashMap<>();
|
||||
this.placeholderSignViewRequests = new HashMap<>();
|
||||
this.signCopyRequests = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a sign copy request
|
||||
*
|
||||
* <p>A sign copy request is basically the result of running the copySign command, which must be stored until the
|
||||
* player clicks a sign.</p>
|
||||
*
|
||||
* @param request <p>The sign copy request to register</p>
|
||||
*/
|
||||
public void addSignCopyRequest(@NotNull SignCopyRequest request) {
|
||||
this.signCopyRequests.put(request.player(), request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a sign copy request
|
||||
*
|
||||
* @param player <p>The player to get the request for</p>
|
||||
* @return <p>The sign copy request, or null if not found</p>
|
||||
*/
|
||||
@Nullable
|
||||
public SignCopyRequest getSignCopyRequest(@NotNull Player player) {
|
||||
return this.signCopyRequests.remove(player);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,54 +71,4 @@ public class PlaceholderSignRequestHandler {
|
||||
return this.signChangeRequests.remove(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a sign view request
|
||||
*
|
||||
* @param player <p>The player requesting to view a sign</p>
|
||||
* @param raw <p>Whether to display the raw text (visible formatting codes)</p>
|
||||
*/
|
||||
public void addSignViewRequest(@NotNull Player player, boolean raw) {
|
||||
this.signViewRequests.put(player, raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given player has a sign view request
|
||||
*
|
||||
* @param player <p>The player to check</p>
|
||||
* @return <p>Not null if the player has requested to view a sign</p>
|
||||
*/
|
||||
@Nullable
|
||||
public Boolean getSignViewRequest(@NotNull Player player) {
|
||||
if (this.signViewRequests.containsKey(player)) {
|
||||
return this.signViewRequests.remove(player);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a placeholder view request
|
||||
*
|
||||
* @param player <p>The player requesting to view a placeholder sign</p>
|
||||
* @param raw <p>Whether to display the raw text (visible formatting codes)</p>
|
||||
*/
|
||||
public void addPlaceholderSignViewRequest(Player player, boolean raw) {
|
||||
this.placeholderSignViewRequests.put(player, raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given player has a placeholder sign view request
|
||||
*
|
||||
* @param player <p>The player to check</p>
|
||||
* @return <p>Not null if the player has requested to view a sign</p>
|
||||
*/
|
||||
@Nullable
|
||||
public Boolean getPlaceholderSignViewRequest(@NotNull Player player) {
|
||||
if (this.placeholderSignViewRequests.containsKey(player)) {
|
||||
return this.placeholderSignViewRequests.remove(player);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,19 +1,16 @@
|
||||
package net.knarcraft.placeholdersigns.listener;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.knarlib.formatting.StringReplacer;
|
||||
import net.knarcraft.knarlib.property.ColorConversion;
|
||||
import net.knarcraft.knarlib.util.ColorHelper;
|
||||
import net.knarcraft.placeholdersigns.PlaceholderSigns;
|
||||
import net.knarcraft.placeholdersigns.config.PlaceholderSignMessage;
|
||||
import net.knarcraft.placeholdersigns.container.PlaceholderSign;
|
||||
import net.knarcraft.placeholdersigns.container.SignCopyRequest;
|
||||
import net.knarcraft.placeholdersigns.container.SignLineChangeRequest;
|
||||
import net.knarcraft.placeholdersigns.handler.PlaceholderSignHandler;
|
||||
import net.knarcraft.placeholdersigns.handler.PlaceholderSignRequestHandler;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.sign.Side;
|
||||
import org.bukkit.block.sign.SignSide;
|
||||
@@ -24,6 +21,7 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -44,17 +42,13 @@ public class SignClickListener implements Listener {
|
||||
Player player = event.getPlayer();
|
||||
PlaceholderSignRequestHandler requestHandler = PlaceholderSigns.getInstance().getRequestHandler();
|
||||
|
||||
Boolean hasSignViewRequest = requestHandler.getSignViewRequest(player);
|
||||
if (hasSignViewRequest != null) {
|
||||
printSign(sign, player, hasSignViewRequest, false);
|
||||
// Cancel the event to prevent vanilla behavior
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
SignCopyRequest signCopyRequest = requestHandler.getSignCopyRequest(player);
|
||||
if (signCopyRequest != null) {
|
||||
if (checkWaxEdit(sign, player, "placeholdersigns.copy.bypass-waxed")) {
|
||||
return;
|
||||
}
|
||||
|
||||
Boolean hasPlaceholderSignViewRequest = requestHandler.getPlaceholderSignViewRequest(player);
|
||||
if (hasPlaceholderSignViewRequest != null) {
|
||||
printSign(sign, player, hasPlaceholderSignViewRequest, true);
|
||||
pasteSign(signCopyRequest.sign(), sign, player);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
@@ -62,9 +56,7 @@ public class SignClickListener implements Listener {
|
||||
// Check if the player has run the /editSign command
|
||||
SignLineChangeRequest request = requestHandler.getSignChangeRequest(player);
|
||||
if (request != null) {
|
||||
if (sign.isWaxed() && !player.hasPermission("placeholdersigns.edit.bypass-waxed")) {
|
||||
PlaceholderSigns.getInstance().getStringFormatter().displayErrorMessage(player,
|
||||
PlaceholderSignMessage.ERROR_WAXED_NO_PERMISSION);
|
||||
if (checkWaxEdit(sign, player, "placeholdersigns.edit.bypass-waxed")) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -75,114 +67,138 @@ public class SignClickListener implements Listener {
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the current contents of a sign to a player
|
||||
* Checks if the player is trying to edit/modify a waxed sign without permission
|
||||
*
|
||||
* @param sign <p>The sign to print</p>
|
||||
* @param player <p>The player to display the contents to</p>
|
||||
* @param raw <p>Whether to get the raw text with used formatting codes</p>
|
||||
* @param showPlaceholders <p>Whether to show the actual placeholders stored on the sign</p>
|
||||
* @param sign <p>The sign the player is trying to edit</p>
|
||||
* @param player <p>The player trying to edit the sign</p>
|
||||
* @return <p>True if the player is trying to edit a waxed sign without permission</p>
|
||||
*/
|
||||
private void printSign(@NotNull Sign sign, @NotNull Player player, boolean raw, boolean showPlaceholders) {
|
||||
Location location = sign.getLocation();
|
||||
SignSide front = sign.getSide(Side.FRONT);
|
||||
SignSide back = sign.getSide(Side.BACK);
|
||||
String frontLines = showPlaceholders ? getPlaceholderSignText(location, front, Side.FRONT, raw) :
|
||||
getSignText(front.getLines(), raw);
|
||||
String backLines = showPlaceholders ? getPlaceholderSignText(location, back, Side.BACK, raw) :
|
||||
getSignText(back.getLines(), raw);
|
||||
|
||||
StringFormatter stringFormatter = PlaceholderSigns.getInstance().getStringFormatter();
|
||||
StringReplacer replacer = new StringReplacer(stringFormatter.getUnformattedColoredMessage(
|
||||
PlaceholderSignMessage.SUCCESS_SIGN_CONTENTS));
|
||||
replacer.add("{frontLines}", frontLines);
|
||||
replacer.add("{backLines}", backLines);
|
||||
replacer.add("{frontDye}", getDye(front));
|
||||
replacer.add("{frontGlow}", getStatus(front.isGlowingText()));
|
||||
replacer.add("{backDye}", getDye(back));
|
||||
replacer.add("{backGlow}", getStatus(back.isGlowingText()));
|
||||
replacer.add("{waxed}", getStatus(sign.isWaxed()));
|
||||
player.sendMessage(replacer.replace());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a description of the status of a sign property
|
||||
*
|
||||
* @param isTrue <p>Whether the property is true</p>
|
||||
* @return <p>A description of the property's current status</p>
|
||||
*/
|
||||
@NotNull
|
||||
private String getStatus(boolean isTrue) {
|
||||
StringFormatter stringFormatter = PlaceholderSigns.getInstance().getStringFormatter();
|
||||
if (isTrue) {
|
||||
return stringFormatter.getUnformattedColoredMessage(PlaceholderSignMessage.SIGN_PROPERTY_CONFIRM);
|
||||
private boolean checkWaxEdit(@NotNull Sign sign, @NotNull Player player, @NotNull String permissionNode) {
|
||||
if (sign.isWaxed() && !player.hasPermission(permissionNode)) {
|
||||
PlaceholderSigns.getInstance().getStringFormatter().displayErrorMessage(player,
|
||||
PlaceholderSignMessage.ERROR_WAXED_NO_PERMISSION);
|
||||
return true;
|
||||
} else {
|
||||
return stringFormatter.getUnformattedColoredMessage(PlaceholderSignMessage.SIGN_PROPERTY_DENY);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a description of a dye applied to a sign
|
||||
* Pastes the data from the source sign to the target sign
|
||||
*
|
||||
* @param signSide <p>The sign side to get the dye of</p>
|
||||
* @return <p>The description of the applied dye</p>
|
||||
* @param source <p>The source sign to copy data from</p>
|
||||
* @param target <p>The target sign to paste to</p>
|
||||
* @param player <p>The player pasting the sign</p>
|
||||
*/
|
||||
@NotNull
|
||||
private String getDye(@NotNull SignSide signSide) {
|
||||
DyeColor dyeColor = signSide.getColor();
|
||||
if (dyeColor == null) {
|
||||
return "None";
|
||||
private void pasteSign(@NotNull Sign source, @NotNull Sign target, @NotNull Player player) {
|
||||
StringFormatter stringFormatter = PlaceholderSigns.getInstance().getStringFormatter();
|
||||
PlaceholderSign placeholderSign = PlaceholderSigns.getInstance().getSignHandler().getFromLocation(source.getLocation());
|
||||
SignSide sourceFront = source.getSide(Side.FRONT);
|
||||
SignSide sourceBack = source.getSide(Side.BACK);
|
||||
SignSide targetFront = target.getSide(Side.FRONT);
|
||||
SignSide targetBack = target.getSide(Side.BACK);
|
||||
|
||||
// Get the lines, with placeholders replaced, and the sign change event processed
|
||||
String[] frontLines = getFinalLines(target, sourceFront, Side.FRONT, placeholderSign, player);
|
||||
if (frontLines == null) {
|
||||
stringFormatter.displayErrorMessage(player, PlaceholderSignMessage.ERROR_CANCELLED_BY_PROTECTION);
|
||||
return;
|
||||
}
|
||||
String[] backLines = getFinalLines(target, sourceBack, Side.BACK, placeholderSign, player);
|
||||
if (backLines == null) {
|
||||
stringFormatter.displayErrorMessage(player, PlaceholderSignMessage.ERROR_CANCELLED_BY_PROTECTION);
|
||||
return;
|
||||
}
|
||||
|
||||
ChatColor color = ColorHelper.fromColor(dyeColor.getColor());
|
||||
return color + signSide.getColor().name();
|
||||
// Update the lines on both sides of the target sign
|
||||
for (int i = 0; i < frontLines.length; i++) {
|
||||
targetFront.setLine(i, ColorHelper.translateColorCodes(frontLines[i], ColorConversion.RGB));
|
||||
}
|
||||
for (int i = 0; i < backLines.length; i++) {
|
||||
targetBack.setLine(i, ColorHelper.translateColorCodes(backLines[i], ColorConversion.RGB));
|
||||
}
|
||||
|
||||
// Copy options
|
||||
copySignOptions(source, target);
|
||||
|
||||
// Apply changes
|
||||
target.update();
|
||||
|
||||
stringFormatter.displaySuccessMessage(player, PlaceholderSignMessage.SUCCESS_SIGN_PASTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets text from a sign side, and appends it to the given string builder
|
||||
* Gets the final lines from a sign side, after inserting placeholders and running a sign change event
|
||||
*
|
||||
* @param signLocation <p>The location of the sign</p>
|
||||
* @param signSide <p>The sign side to get text from</p>
|
||||
* @param side <p>The side of the sign to get placeholders from</p>
|
||||
* @param raw <p>Whether to get the raw text with used formatting codes</p>
|
||||
* @param sign <p>The sign that's changed</p>
|
||||
* @param signSide <p>The side of the sign to get lines from</p>
|
||||
* @param side <p>The side that's processed</p>
|
||||
* @param placeholderSign <p>The placeholder sign corresponding to the sign, if any</p>
|
||||
* @param player <p>The player attempting to paste the sign</p>
|
||||
* @return <p>The final lines, or null if the event was cancelled</p>
|
||||
*/
|
||||
@NotNull
|
||||
private String getPlaceholderSignText(@NotNull Location signLocation, @NotNull SignSide signSide,
|
||||
@NotNull Side side, boolean raw) {
|
||||
String[] lines = signSide.getLines();
|
||||
PlaceholderSign placeholderSign = PlaceholderSigns.getInstance().getSignHandler().getFromLocation(signLocation);
|
||||
if (placeholderSign == null) {
|
||||
return getSignText(lines, raw);
|
||||
@Nullable
|
||||
private String[] getFinalLines(@NotNull Sign sign, @NotNull SignSide signSide, @NotNull Side side,
|
||||
@Nullable PlaceholderSign placeholderSign, @NotNull Player player) {
|
||||
String[] sideLines = signSide.getLines();
|
||||
if (placeholderSign != null) {
|
||||
Map<Side, Map<Integer, String>> placeholders = placeholderSign.placeholders();
|
||||
loadPlaceholders(side, sideLines, placeholders);
|
||||
}
|
||||
|
||||
Map<Integer, String> placeholders = placeholderSign.placeholders().get(side);
|
||||
for (Map.Entry<Integer, String> entry : placeholders.entrySet()) {
|
||||
lines[entry.getKey()] = entry.getValue();
|
||||
// Run the sign change event to allow protection plugins to cancel, and allow the sign text listener to trigger
|
||||
SignChangeEvent changeEvent = new SignChangeEvent(Objects.requireNonNull(sign.getBlock()), player, sideLines, side);
|
||||
Bukkit.getPluginManager().callEvent(changeEvent);
|
||||
if (changeEvent.isCancelled()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getSignText(lines, raw);
|
||||
return changeEvent.getLines();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets text from a sign side, and appends it to the given string builder
|
||||
* Copies all sign option (dye, glowing, waxed) from the source to the target
|
||||
*
|
||||
* @param lines <p>The lines on the sign</p>
|
||||
* @param raw <p>Whether to get the raw text with used formatting codes</p>
|
||||
* @param source <p>The source sign</p>
|
||||
* @param target <p>The target sign</p>
|
||||
*/
|
||||
@NotNull
|
||||
private String getSignText(@NotNull String[] lines, boolean raw) {
|
||||
StringBuilder output = new StringBuilder();
|
||||
private void copySignOptions(@NotNull Sign source, @NotNull Sign target) {
|
||||
SignSide sourceFront = source.getSide(Side.FRONT);
|
||||
SignSide sourceBack = source.getSide(Side.BACK);
|
||||
SignSide targetFront = target.getSide(Side.FRONT);
|
||||
SignSide targetBack = target.getSide(Side.BACK);
|
||||
|
||||
// Copy glowing state
|
||||
targetFront.setGlowingText(sourceFront.isGlowingText());
|
||||
targetBack.setGlowingText(sourceBack.isGlowingText());
|
||||
|
||||
// Copy applied dye
|
||||
targetFront.setColor(sourceFront.getColor());
|
||||
targetBack.setColor(sourceBack.getColor());
|
||||
|
||||
// Apply waxed state
|
||||
target.setWaxed(source.isWaxed());
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads placeholders from one side of a sign
|
||||
*
|
||||
* @param side <p>The side to load from</p>
|
||||
* @param lines <p>The array to write placeholders to</p>
|
||||
* @param placeholders <p>The placeholders to load</p>
|
||||
*/
|
||||
private void loadPlaceholders(@NotNull Side side, @NotNull String[] lines,
|
||||
@NotNull Map<Side, Map<Integer, String>> placeholders) {
|
||||
if (!placeholders.containsKey(side)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<Integer, String> sidePlaceholders = placeholders.get(side);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
output.append(i + 1).append(". ");
|
||||
|
||||
String line = lines[i];
|
||||
if (raw) {
|
||||
output.append(line.replace(ChatColor.COLOR_CHAR, '&'));
|
||||
} else {
|
||||
output.append(line);
|
||||
if (sidePlaceholders.containsKey(i)) {
|
||||
lines[i] = sidePlaceholders.get(i);
|
||||
}
|
||||
output.append(ChatColor.COLOR_CHAR).append("r\n");
|
||||
}
|
||||
return output.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -220,6 +236,8 @@ public class SignClickListener implements Listener {
|
||||
// Restore the old placeholder if the action didn't complete
|
||||
placeholderSign.placeholders().get(side).put(request.line(), oldPlaceholder);
|
||||
}
|
||||
PlaceholderSigns.getInstance().getStringFormatter().displayErrorMessage(player,
|
||||
PlaceholderSignMessage.ERROR_CANCELLED_BY_PROTECTION);
|
||||
return;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user