Implements #4
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:
@@ -4,6 +4,7 @@ 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.CopySignTextCommand;
|
||||
import net.knarcraft.placeholdersigns.command.EditSignCommand;
|
||||
import net.knarcraft.placeholdersigns.command.UnWaxSignCommand;
|
||||
import net.knarcraft.placeholdersigns.command.ViewSignCommand;
|
||||
@@ -97,6 +98,7 @@ public final class PlaceholderSigns extends JavaPlugin {
|
||||
registerCommand("viewSign", new ViewSignCommand());
|
||||
registerCommand("copySign", new CopySignCommand());
|
||||
registerCommand("unWaxSign", new UnWaxSignCommand());
|
||||
registerCommand("copySignText", new CopySignTextCommand());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -0,0 +1,99 @@
|
||||
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.SignTextCopyRequest;
|
||||
import net.knarcraft.placeholdersigns.util.TabCompleteHelper;
|
||||
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;
|
||||
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 a sign's text
|
||||
*/
|
||||
public class CopySignTextCommand 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;
|
||||
}
|
||||
|
||||
Block targetBlock = player.getTargetBlockExact(7);
|
||||
if (targetBlock == null || !(targetBlock.getState() instanceof Sign sign)) {
|
||||
stringFormatter.displayErrorMessage(commandSender, PlaceholderSignMessage.ERROR_NOT_LOOKING_AT_SIGN);
|
||||
return false;
|
||||
}
|
||||
|
||||
Side side = null;
|
||||
Integer sourceLine = null;
|
||||
Integer destinationLine = null;
|
||||
|
||||
if (arguments.length > 0) {
|
||||
try {
|
||||
side = Side.valueOf(arguments[0]);
|
||||
} catch (IllegalArgumentException exception) {
|
||||
// Choose the side the player is currently looking at
|
||||
if (arguments[0].equalsIgnoreCase("this")) {
|
||||
SignSide standingOn = sign.getTargetSide(player);
|
||||
side = sign.getSide(Side.FRONT).equals(standingOn) ? Side.FRONT : Side.BACK;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (arguments.length > 1) {
|
||||
try {
|
||||
sourceLine = Integer.parseInt(arguments[1]) - 1;
|
||||
} catch (NumberFormatException exception) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (arguments.length > 2) {
|
||||
try {
|
||||
destinationLine = Integer.parseInt(arguments[2]) - 1;
|
||||
} catch (NumberFormatException exception) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SignTextCopyRequest signCopyRequest = new SignTextCopyRequest(player, sign, side, sourceLine, destinationLine);
|
||||
placeholderSigns.getRequestHandler().addSignTextCopyRequest(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[] arguments) {
|
||||
if (arguments.length == 1) {
|
||||
List<String> signSides = TabCompleteHelper.getSignSides();
|
||||
signSides.add("this");
|
||||
return TabCompletionHelper.filterMatchingStartsWith(signSides, arguments[0]);
|
||||
} else if (arguments.length < 4) {
|
||||
return TabCompletionHelper.filterMatchingStartsWith(TabCompleteHelper.getLineNumbers(),
|
||||
arguments[arguments.length - 1]);
|
||||
} else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,9 +1,11 @@
|
||||
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.SignLineChangeRequest;
|
||||
import net.knarcraft.placeholdersigns.util.TabCompleteHelper;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
@@ -19,15 +21,6 @@ import java.util.List;
|
||||
*/
|
||||
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) {
|
||||
@@ -77,9 +70,9 @@ public class EditSignCommand implements TabExecutor {
|
||||
@Nullable
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] args) {
|
||||
if (args.length == 1) {
|
||||
return lineNumbers;
|
||||
@NotNull String[] arguments) {
|
||||
if (arguments.length == 1) {
|
||||
return TabCompletionHelper.filterMatchingStartsWith(TabCompleteHelper.getLineNumbers(), arguments[0]);
|
||||
} else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
@@ -0,0 +1,47 @@
|
||||
package net.knarcraft.placeholdersigns.config;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Permissions used by placeholdersigns
|
||||
*/
|
||||
public enum PlaceholderSignsPermission {
|
||||
|
||||
/**
|
||||
* The permission for bypassing the restriction on pasting onto waxed signs
|
||||
*/
|
||||
BYPASS_WAXED_COPY("placeholdersigns.copy.bypass-waxed"),
|
||||
|
||||
/**
|
||||
* The permission for bypassing the restriction on editing waxed signs
|
||||
*/
|
||||
BYPASS_WAXED_EDIT("placeholdersigns.edit.bypass-waxed"),
|
||||
|
||||
/**
|
||||
* The permission for creating new placeholder signs
|
||||
*/
|
||||
USE_PLACEHOLDERS("placeholdersigns.placeholder"),
|
||||
;
|
||||
|
||||
private final @NotNull String permissionNode;
|
||||
|
||||
/**
|
||||
* Instantiates a new placeholder signs permission
|
||||
*
|
||||
* @param permissionNode <p>The permission node belonging to this permission</p>
|
||||
*/
|
||||
PlaceholderSignsPermission(@NotNull String permissionNode) {
|
||||
this.permissionNode = permissionNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this permission's permission node
|
||||
*
|
||||
* @return <p>This permission's permission node</p>
|
||||
*/
|
||||
@NotNull
|
||||
public String getPermissionNode() {
|
||||
return this.permissionNode;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package net.knarcraft.placeholdersigns.container;
|
||||
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.sign.Side;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* 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>
|
||||
* @param side <p>The side of the sign top copy from (null = both)</p>
|
||||
* @param sourceLine <p>The line on the source sign to copy (null = all)</p>
|
||||
* @param destinationLine <p>The line on the destination sign to overwrite</p>
|
||||
*/
|
||||
public record SignTextCopyRequest(@NotNull Player player, @NotNull Sign sign, @Nullable Side side,
|
||||
@Nullable Integer sourceLine, @Nullable Integer destinationLine) {
|
||||
}
|
@@ -2,6 +2,7 @@ package net.knarcraft.placeholdersigns.handler;
|
||||
|
||||
import net.knarcraft.placeholdersigns.container.SignCopyRequest;
|
||||
import net.knarcraft.placeholdersigns.container.SignLineChangeRequest;
|
||||
import net.knarcraft.placeholdersigns.container.SignTextCopyRequest;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -15,7 +16,8 @@ import java.util.Map;
|
||||
public class PlaceholderSignRequestHandler {
|
||||
|
||||
private final @NotNull Map<Player, SignLineChangeRequest> signChangeRequests;
|
||||
private final Map<Player, SignCopyRequest> signCopyRequests;
|
||||
private final @NotNull Map<Player, SignTextCopyRequest> signTextCopyRequests;
|
||||
private final @NotNull Map<Player, SignCopyRequest> signCopyRequests;
|
||||
|
||||
/**
|
||||
* Instantiates a new placeholder sign request handler
|
||||
@@ -23,6 +25,7 @@ public class PlaceholderSignRequestHandler {
|
||||
public PlaceholderSignRequestHandler() {
|
||||
this.signChangeRequests = new HashMap<>();
|
||||
this.signCopyRequests = new HashMap<>();
|
||||
this.signTextCopyRequests = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,4 +74,24 @@ public class PlaceholderSignRequestHandler {
|
||||
return this.signChangeRequests.remove(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a sign text copy request
|
||||
*
|
||||
* @param signCopyRequest <p>The request to register</p>
|
||||
*/
|
||||
public void addSignTextCopyRequest(@NotNull SignTextCopyRequest signCopyRequest) {
|
||||
this.signTextCopyRequests.put(signCopyRequest.player(), signCopyRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a sign text copy request
|
||||
*
|
||||
* @param player <p>The player to get the request for</p>
|
||||
* @return <p>The sign text copy request, or null if not found</p>
|
||||
*/
|
||||
@Nullable
|
||||
public SignTextCopyRequest getSignTextCopyRequest(@NotNull Player player) {
|
||||
return this.signTextCopyRequests.remove(player);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -5,9 +5,11 @@ 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.config.PlaceholderSignsPermission;
|
||||
import net.knarcraft.placeholdersigns.container.PlaceholderSign;
|
||||
import net.knarcraft.placeholdersigns.container.SignCopyRequest;
|
||||
import net.knarcraft.placeholdersigns.container.SignLineChangeRequest;
|
||||
import net.knarcraft.placeholdersigns.container.SignTextCopyRequest;
|
||||
import net.knarcraft.placeholdersigns.handler.PlaceholderSignHandler;
|
||||
import net.knarcraft.placeholdersigns.handler.PlaceholderSignRequestHandler;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -26,6 +28,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static net.knarcraft.placeholdersigns.util.SignSideHelper.getOpposite;
|
||||
import static net.knarcraft.placeholdersigns.util.SignSideHelper.getSide;
|
||||
|
||||
/**
|
||||
* A listener for placeholder signs being clicked
|
||||
*/
|
||||
@@ -44,7 +49,7 @@ public class SignClickListener implements Listener {
|
||||
|
||||
SignCopyRequest signCopyRequest = requestHandler.getSignCopyRequest(player);
|
||||
if (signCopyRequest != null) {
|
||||
if (checkWaxEdit(sign, player, "placeholdersigns.copy.bypass-waxed")) {
|
||||
if (checkWaxEdit(sign, player, PlaceholderSignsPermission.BYPASS_WAXED_COPY.getPermissionNode())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -53,19 +58,167 @@ public class SignClickListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the player has run the /editSign command
|
||||
SignLineChangeRequest request = requestHandler.getSignChangeRequest(player);
|
||||
if (request != null) {
|
||||
if (checkWaxEdit(sign, player, "placeholdersigns.edit.bypass-waxed")) {
|
||||
// Check if the player has run the /setSignLine command
|
||||
SignLineChangeRequest signChangeRequest = requestHandler.getSignChangeRequest(player);
|
||||
if (signChangeRequest != null) {
|
||||
if (checkWaxEdit(sign, player, PlaceholderSignsPermission.BYPASS_WAXED_EDIT.getPermissionNode())) {
|
||||
return;
|
||||
}
|
||||
|
||||
SignSide standingOn = sign.getTargetSide(player);
|
||||
Side side = sign.getSide(Side.FRONT).equals(standingOn) ? Side.FRONT : Side.BACK;
|
||||
doSignChange(sign, request, event, player, side);
|
||||
doSignChange(sign, signChangeRequest.line(), player, getSide(sign, player), signChangeRequest.text());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
SignTextCopyRequest signTextCopyRequest = requestHandler.getSignTextCopyRequest(player);
|
||||
if (signTextCopyRequest != null) {
|
||||
if (checkWaxEdit(sign, player, PlaceholderSignsPermission.BYPASS_WAXED_COPY.getPermissionNode())) {
|
||||
return;
|
||||
}
|
||||
|
||||
pasteSignText(sign, signTextCopyRequest, player, getSide(sign, player));
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pastes sign text according to the given signTextCopyRequest
|
||||
*
|
||||
* @param targetSign <p>The sign to paste onto</p>
|
||||
* @param signTextCopyRequest <p>The requested sign text copy request to fulfill</p>
|
||||
* @param player <p>The player wanting to paste</p>
|
||||
* @param clickedSide <p>The sign side the player wants to paste onto</p>
|
||||
*/
|
||||
private void pasteSignText(@NotNull Sign targetSign, @NotNull SignTextCopyRequest signTextCopyRequest,
|
||||
@NotNull Player player, @NotNull Side clickedSide) {
|
||||
Side sourceSide = signTextCopyRequest.side();
|
||||
Sign sourceSign = signTextCopyRequest.sign();
|
||||
PlaceholderSignHandler signHandler = PlaceholderSigns.getInstance().getSignHandler();
|
||||
PlaceholderSign sourcePlaceholderSign = signHandler.getFromLocation(sourceSign.getLocation());
|
||||
PlaceholderSign targetPlaceholderSign = signHandler.getFromLocation(targetSign.getLocation());
|
||||
|
||||
if (sourceSide == null) {
|
||||
// Copy both sides
|
||||
copySignText(signHandler, sourcePlaceholderSign, targetPlaceholderSign, clickedSide, sourceSign, targetSign,
|
||||
player);
|
||||
} else if (signTextCopyRequest.sourceLine() == null) {
|
||||
// Copy the side the player looked at while executing the command
|
||||
copySignSideText(signHandler, sourcePlaceholderSign, targetPlaceholderSign, sourceSide, clickedSide,
|
||||
sourceSign, targetSign, player);
|
||||
} else {
|
||||
copySignLine(signTextCopyRequest, sourcePlaceholderSign, sourceSide, clickedSide, targetSign, player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies sign line from one sign side to another
|
||||
*
|
||||
* @param signTextCopyRequest <p>The sign text copy request to handle</p>
|
||||
* @param sourcePlaceholderSign <p>The source sign's placeholder sign, or null</p>
|
||||
* @param sourceSide <p>The side of the source sign to copy text from</p>
|
||||
* @param clickedSide <p>The side the player clicked to paste</p>
|
||||
* @param targetSign <p>The sign to paste text onto</p>
|
||||
* @param player <p>The player performing the copy paste</p>
|
||||
*/
|
||||
private void copySignLine(@NotNull SignTextCopyRequest signTextCopyRequest,
|
||||
@Nullable PlaceholderSign sourcePlaceholderSign, @NotNull Side sourceSide,
|
||||
@NotNull Side clickedSide, @NotNull Sign targetSign, @NotNull Player player) {
|
||||
if (signTextCopyRequest.side() == null || signTextCopyRequest.sourceLine() == null) {
|
||||
throw new RuntimeException("Non-null variable is null");
|
||||
}
|
||||
|
||||
int sourceLine = signTextCopyRequest.sourceLine();
|
||||
int destinationLine = signTextCopyRequest.destinationLine() != null ?
|
||||
signTextCopyRequest.destinationLine() : sourceLine;
|
||||
|
||||
String text = signTextCopyRequest.sign().getSide(signTextCopyRequest.side()).getLine(sourceLine);
|
||||
if (sourcePlaceholderSign != null) {
|
||||
Map<Side, Map<Integer, String>> placeholders = sourcePlaceholderSign.placeholders();
|
||||
if (placeholders.containsKey(sourceSide) && placeholders.get(sourceSide).containsKey(sourceLine)) {
|
||||
text = placeholders.get(sourceSide).get(sourceLine);
|
||||
}
|
||||
}
|
||||
|
||||
doSignChange(targetSign, destinationLine, player, clickedSide, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies sign text from one sign side to another
|
||||
*
|
||||
* @param signHandler <p>The sign handler to use for dealing with placeholder signs</p>
|
||||
* @param sourcePlaceholderSign <p>The source sign's placeholder sign, or null</p>
|
||||
* @param targetPlaceholderSign <p>The destination's placeholder sign, or null</p>
|
||||
* @param sourceSide <p>The side of the source sign to copy text from</p>
|
||||
* @param clickedSide <p>The side the player clicked to paste</p>
|
||||
* @param sourceSign <p>The sign to copy text from</p>
|
||||
* @param targetSign <p>The sign to paste text onto</p>
|
||||
* @param player <p>The player performing the copy paste</p>
|
||||
*/
|
||||
private void copySignSideText(@NotNull PlaceholderSignHandler signHandler,
|
||||
@Nullable PlaceholderSign sourcePlaceholderSign,
|
||||
@Nullable PlaceholderSign targetPlaceholderSign, @NotNull Side sourceSide,
|
||||
@NotNull Side clickedSide, @NotNull Sign sourceSign, @NotNull Sign targetSign,
|
||||
@NotNull Player player) {
|
||||
// Remove old placeholders from the sign side
|
||||
Map<Integer, String> oldPlaceholders = null;
|
||||
if (targetPlaceholderSign != null) {
|
||||
oldPlaceholders = targetPlaceholderSign.placeholders().remove(clickedSide);
|
||||
}
|
||||
if (pasteSignSide(sourceSide, clickedSide, sourceSign, targetSign,
|
||||
sourcePlaceholderSign, player) && targetPlaceholderSign != null) {
|
||||
// Restore the old placeholders if the sign change didn't finish
|
||||
targetPlaceholderSign.placeholders().put(clickedSide, oldPlaceholders);
|
||||
}
|
||||
|
||||
// Save any placeholder changes
|
||||
signHandler.save();
|
||||
|
||||
// Apply changes
|
||||
targetSign.update();
|
||||
|
||||
PlaceholderSigns.getInstance().getStringFormatter().displaySuccessMessage(player,
|
||||
PlaceholderSignMessage.SUCCESS_SIGN_PASTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies sign text from one sign to another
|
||||
*
|
||||
* @param signHandler <p>The sign handler to use for dealing with placeholder signs</p>
|
||||
* @param sourcePlaceholderSign <p>The source sign's placeholder sign, or null</p>
|
||||
* @param targetPlaceholderSign <p>The destination's placeholder sign, or null</p>
|
||||
* @param clickedSide <p>The side the player clicked to paste</p>
|
||||
* @param sourceSign <p>The sign to copy text from</p>
|
||||
* @param targetSign <p>The sign to paste text onto</p>
|
||||
* @param player <p>The player performing the copy paste</p>
|
||||
*/
|
||||
private void copySignText(@NotNull PlaceholderSignHandler signHandler,
|
||||
@Nullable PlaceholderSign sourcePlaceholderSign,
|
||||
@Nullable PlaceholderSign targetPlaceholderSign, @NotNull Side clickedSide,
|
||||
@NotNull Sign sourceSign, @NotNull Sign targetSign, @NotNull Player player) {
|
||||
// Un-register the old placeholder sign to remove its data
|
||||
if (targetPlaceholderSign != null) {
|
||||
signHandler.unregisterSign(targetPlaceholderSign);
|
||||
}
|
||||
|
||||
// Copy both sides of the sign. Paste the front to whichever side the player is currently looking at
|
||||
if ((pasteSignSide(Side.FRONT, clickedSide, sourceSign, targetSign, sourcePlaceholderSign, player) ||
|
||||
pasteSignSide(Side.BACK, getOpposite(clickedSide), sourceSign, targetSign, sourcePlaceholderSign, player)) &&
|
||||
targetPlaceholderSign != null) {
|
||||
// Re-register the old placeholder sign if the new text couldn't be applied
|
||||
signHandler.registerSign(targetPlaceholderSign);
|
||||
}
|
||||
|
||||
// Save any placeholder changes
|
||||
signHandler.save();
|
||||
|
||||
// Apply changes
|
||||
targetSign.update();
|
||||
|
||||
PlaceholderSigns.getInstance().getStringFormatter().displaySuccessMessage(player,
|
||||
PlaceholderSignMessage.SUCCESS_SIGN_PASTED);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the player is trying to edit/modify a waxed sign without permission
|
||||
*
|
||||
@@ -86,68 +239,80 @@ public class SignClickListener implements Listener {
|
||||
/**
|
||||
* Pastes the data from the source sign to the target sign
|
||||
*
|
||||
* @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>
|
||||
* @param sourceSign <p>The source sign to copy data from</p>
|
||||
* @param targetSign <p>The target sign to paste to</p>
|
||||
* @param player <p>The player pasting the sign</p>
|
||||
*/
|
||||
private void pasteSign(@NotNull Sign source, @NotNull Sign target, @NotNull Player player) {
|
||||
private void pasteSign(@NotNull Sign sourceSign, @NotNull Sign targetSign, @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);
|
||||
PlaceholderSign placeholderSign = PlaceholderSigns.getInstance().getSignHandler().getFromLocation(
|
||||
sourceSign.getLocation());
|
||||
|
||||
// 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);
|
||||
if (pasteSignSide(Side.FRONT, Side.FRONT, sourceSign, targetSign, placeholderSign, player) ||
|
||||
pasteSignSide(Side.BACK, Side.BACK, sourceSign, targetSign, placeholderSign, player)) {
|
||||
return;
|
||||
}
|
||||
String[] backLines = getFinalLines(target, sourceBack, Side.BACK, placeholderSign, player);
|
||||
if (backLines == null) {
|
||||
stringFormatter.displayErrorMessage(player, PlaceholderSignMessage.ERROR_CANCELLED_BY_PROTECTION);
|
||||
return;
|
||||
}
|
||||
|
||||
// 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);
|
||||
copySignOptions(sourceSign, targetSign);
|
||||
|
||||
// Apply changes
|
||||
target.update();
|
||||
targetSign.update();
|
||||
|
||||
stringFormatter.displaySuccessMessage(player, PlaceholderSignMessage.SUCCESS_SIGN_PASTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pastes one side of a sign onto another
|
||||
*
|
||||
* @param sourceSide <p>The sign side to copy</p>
|
||||
* @param destinationSide <p>The sign side to paste to</p>
|
||||
* @param source <p>The source sign</p>
|
||||
* @param target <p>The destination sign</p>
|
||||
* @param placeholderSign <p>The placeholder sign belonging to the source sign, or null</p>
|
||||
* @param player <p>The player performing the paste</p>
|
||||
* @return <p>False if the pasting completed successfully. True if blocked by another plugin.</p>
|
||||
*/
|
||||
private boolean pasteSignSide(@NotNull Side sourceSide, @NotNull Side destinationSide, @NotNull Sign source,
|
||||
@NotNull Sign target, @Nullable PlaceholderSign placeholderSign, @NotNull Player player) {
|
||||
SignSide sourceSignSide = source.getSide(sourceSide);
|
||||
SignSide targetSignSide = target.getSide(destinationSide);
|
||||
String[] frontLines = getFinalLines(target, sourceSignSide, sourceSide, destinationSide, placeholderSign, player);
|
||||
if (frontLines == null) {
|
||||
PlaceholderSigns.getInstance().getStringFormatter().displayErrorMessage(player,
|
||||
PlaceholderSignMessage.ERROR_CANCELLED_BY_PROTECTION);
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < frontLines.length; i++) {
|
||||
targetSignSide.setLine(i, ColorHelper.translateColorCodes(frontLines[i], ColorConversion.RGB));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the final lines from a sign side, after inserting placeholders and running a sign change event
|
||||
*
|
||||
* @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 sourceSide <p>The side that text is taken from</p>
|
||||
* @param targetSide <p>The side that text is changed for</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>
|
||||
*/
|
||||
@Nullable
|
||||
private String[] getFinalLines(@NotNull Sign sign, @NotNull SignSide signSide, @NotNull Side side,
|
||||
@Nullable PlaceholderSign placeholderSign, @NotNull Player player) {
|
||||
private String[] getFinalLines(@NotNull Sign sign, @NotNull SignSide signSide, @NotNull Side sourceSide,
|
||||
@NotNull Side targetSide, @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);
|
||||
loadPlaceholders(sourceSide, sideLines, placeholders);
|
||||
}
|
||||
|
||||
// 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);
|
||||
SignChangeEvent changeEvent = new SignChangeEvent(Objects.requireNonNull(sign.getBlock()), player, sideLines, targetSide);
|
||||
Bukkit.getPluginManager().callEvent(changeEvent);
|
||||
if (changeEvent.isCancelled()) {
|
||||
return null;
|
||||
@@ -202,39 +367,36 @@ public class SignClickListener implements Listener {
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the changing of a sign according to the given sign change request
|
||||
* Alters the text on a sign, taking care of placeholders and sign change event triggers
|
||||
*
|
||||
* @param sign <p>The sign to be changed</p>
|
||||
* @param request <p>The sign line change request to perform</p>
|
||||
* @param event <p>The interaction event that triggered this</p>
|
||||
* @param player <p>The player triggering the sign change</p>
|
||||
* @param targetSign <p>The sign to be changed</p>
|
||||
* @param destinationLine <p>The line to be changed on the sign</p>
|
||||
* @param player <p>The player trying to change the sign</p>
|
||||
* @param targetSide <p>The side of the sign to change the line for</p>
|
||||
* @param newText <p>The new text to apply to the sign</p>
|
||||
*/
|
||||
private void doSignChange(@NotNull Sign sign, @NotNull SignLineChangeRequest request,
|
||||
@NotNull PlayerInteractEvent event, @NotNull Player player, @NotNull Side side) {
|
||||
// Cancel the event to prevent vanilla behavior
|
||||
event.setCancelled(true);
|
||||
|
||||
SignSide signSide = sign.getSide(side);
|
||||
String[] lines = signSide.getLines();
|
||||
private void doSignChange(@NotNull Sign targetSign, int destinationLine, @NotNull Player player,
|
||||
@NotNull Side targetSide, @NotNull String newText) {
|
||||
SignSide targetSignSide = targetSign.getSide(targetSide);
|
||||
String[] lines = targetSignSide.getLines();
|
||||
|
||||
PlaceholderSignHandler signHandler = PlaceholderSigns.getInstance().getSignHandler();
|
||||
PlaceholderSign placeholderSign = PlaceholderSigns.getInstance().getSignHandler().getFromLocation(sign.getLocation());
|
||||
PlaceholderSign targetPlaceholderSign = PlaceholderSigns.getInstance().getSignHandler().getFromLocation(targetSign.getLocation());
|
||||
String oldPlaceholder = null;
|
||||
if (placeholderSign != null) {
|
||||
if (targetPlaceholderSign != null) {
|
||||
// Remove the old placeholder
|
||||
oldPlaceholder = placeholderSign.placeholders().get(side).remove(request.line());
|
||||
oldPlaceholder = targetPlaceholderSign.placeholders().get(targetSide).remove(destinationLine);
|
||||
}
|
||||
|
||||
lines[request.line()] = request.text();
|
||||
lines[destinationLine] = newText;
|
||||
|
||||
// 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(event.getClickedBlock()),
|
||||
player, lines, side);
|
||||
SignChangeEvent changeEvent = new SignChangeEvent(targetSign.getBlock(), player, lines, targetSide);
|
||||
Bukkit.getPluginManager().callEvent(changeEvent);
|
||||
if (changeEvent.isCancelled()) {
|
||||
if (placeholderSign != null) {
|
||||
if (targetPlaceholderSign != null) {
|
||||
// Restore the old placeholder if the action didn't complete
|
||||
placeholderSign.placeholders().get(side).put(request.line(), oldPlaceholder);
|
||||
targetPlaceholderSign.placeholders().get(targetSide).put(destinationLine, oldPlaceholder);
|
||||
}
|
||||
PlaceholderSigns.getInstance().getStringFormatter().displayErrorMessage(player,
|
||||
PlaceholderSignMessage.ERROR_CANCELLED_BY_PROTECTION);
|
||||
@@ -242,11 +404,9 @@ public class SignClickListener implements Listener {
|
||||
}
|
||||
|
||||
// Update the sign with the new text
|
||||
String[] finalLines = changeEvent.getLines();
|
||||
for (int i = 0; i < finalLines.length; i++) {
|
||||
signSide.setLine(i, ColorHelper.translateColorCodes(finalLines[i], ColorConversion.RGB));
|
||||
}
|
||||
sign.update();
|
||||
targetSignSide.setLine(destinationLine, ColorHelper.translateColorCodes(changeEvent.getLines()[destinationLine],
|
||||
ColorConversion.RGB));
|
||||
targetSign.update();
|
||||
|
||||
// Save any placeholder changes
|
||||
signHandler.save();
|
||||
|
@@ -2,6 +2,7 @@ package net.knarcraft.placeholdersigns.listener;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import net.knarcraft.placeholdersigns.PlaceholderSigns;
|
||||
import net.knarcraft.placeholdersigns.config.PlaceholderSignsPermission;
|
||||
import net.knarcraft.placeholdersigns.container.PlaceholderSign;
|
||||
import net.knarcraft.placeholdersigns.handler.PlaceholderSignHandler;
|
||||
import org.bukkit.Location;
|
||||
@@ -23,7 +24,7 @@ public class SignTextListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onSignCreateOrEdit(@NotNull SignChangeEvent event) {
|
||||
// Only check for placeholders if the player is allowed to
|
||||
if (!event.getPlayer().hasPermission("placeholdersigns.placeholder")) {
|
||||
if (!event.getPlayer().hasPermission(PlaceholderSignsPermission.USE_PLACEHOLDERS.getPermissionNode())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,39 @@
|
||||
package net.knarcraft.placeholdersigns.util;
|
||||
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.sign.Side;
|
||||
import org.bukkit.block.sign.SignSide;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class SignSideHelper {
|
||||
|
||||
private SignSideHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the side of the given sign the given player is standing on (which side the player clicked)
|
||||
*
|
||||
* @param sign <p>The sign to check</p>
|
||||
* @param player <p>The player to check</p>
|
||||
* @return <p>The side of the sign the player is standing on</p>
|
||||
*/
|
||||
@NotNull
|
||||
public static Side getSide(@NotNull Sign sign, @NotNull Player player) {
|
||||
SignSide standingOn = sign.getTargetSide(player);
|
||||
return sign.getSide(Side.FRONT).equals(standingOn) ? Side.FRONT : Side.BACK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the opposite sign side from the given sign side
|
||||
*
|
||||
* @param side <p>The side to get the opposite of</p>
|
||||
* @return <p>The opposite side</p>
|
||||
*/
|
||||
@NotNull
|
||||
public static Side getOpposite(@NotNull Side side) {
|
||||
return side == Side.FRONT ? Side.BACK : Side.FRONT;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
package net.knarcraft.placeholdersigns.util;
|
||||
|
||||
import org.bukkit.block.sign.Side;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A helper class for generating tab-completions
|
||||
*/
|
||||
public final class TabCompleteHelper {
|
||||
|
||||
private static final List<String> lineNumbers;
|
||||
private static final List<String> signSides;
|
||||
|
||||
static {
|
||||
lineNumbers = new ArrayList<>();
|
||||
for (int i = 1; i < 5; i++) {
|
||||
lineNumbers.add(String.valueOf(i));
|
||||
}
|
||||
|
||||
signSides = new ArrayList<>();
|
||||
for (Side side : Side.values()) {
|
||||
signSides.add(side.name());
|
||||
}
|
||||
}
|
||||
|
||||
private TabCompleteHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets possible sign line numbers
|
||||
*
|
||||
* @return <p>Possible sign line numbers</p>
|
||||
*/
|
||||
@NotNull
|
||||
public static List<String> getLineNumbers() {
|
||||
return new ArrayList<>(lineNumbers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets possible sign sides
|
||||
*
|
||||
* @return <p>Possible sign sides</p>
|
||||
*/
|
||||
@NotNull
|
||||
public static List<String> getSignSides() {
|
||||
return new ArrayList<>(signSides);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user