Adds commands for viewing placeholders on a sign
All checks were successful
KnarCraft/PlaceholderSigns/pipeline/head This commit looks good

This commit is contained in:
Kristian Knarvik 2024-04-22 02:26:08 +02:00
parent 080e6204f4
commit 598b6c9cb9
7 changed files with 170 additions and 39 deletions

View File

@ -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.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;
@ -94,6 +95,8 @@ public final class PlaceholderSigns extends JavaPlugin {
registerCommand("editSign", new EditSignCommand());
registerCommand("viewSign", new ViewSignCommand(false));
registerCommand("viewSignRaw", new ViewSignCommand(true));
registerCommand("viewPlaceholderSign", new ViewPlaceholderSignCommand(false));
registerCommand("viewPlaceholderSignRaw", new ViewPlaceholderSignCommand(true));
}
@Override

View File

@ -0,0 +1,53 @@
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<>();
}
}

View File

@ -34,14 +34,14 @@ public enum PlaceholderSignMessage implements TranslatableMessage {
SUCCESS_SIGN_CONTENTS,
/**
* The string displayed when a sign is confirmed to be glowing
* The string displayed when a sign property is confirmed
*/
GLOWING_CONFIRM,
SIGN_PROPERTY_CONFIRM,
/**
* The string displayed when a sign is not glowing
* The string displayed when a sign property is denied
*/
GLOWING_DENY,
SIGN_PROPERTY_DENY,
;
@Override

View File

@ -15,6 +15,7 @@ public class PlaceholderSignRequestHandler {
private final Map<Player, SignLineChangeRequest> signChangeRequests;
private final Map<Player, Boolean> signViewRequests;
private final Map<Player, Boolean> placeholderSignViewRequests;
/**
* Instantiates a new placeholder sign request handler
@ -22,6 +23,7 @@ public class PlaceholderSignRequestHandler {
public PlaceholderSignRequestHandler() {
this.signChangeRequests = new HashMap<>();
this.signViewRequests = new HashMap<>();
this.placeholderSignViewRequests = new HashMap<>();
}
/**
@ -33,7 +35,7 @@ public class PlaceholderSignRequestHandler {
* @param request <p>The sign change request to register</p>
*/
public void addSignChangeRequest(@NotNull SignLineChangeRequest request) {
signChangeRequests.put(request.player(), request);
this.signChangeRequests.put(request.player(), request);
}
/**
@ -44,7 +46,7 @@ public class PlaceholderSignRequestHandler {
*/
@Nullable
public SignLineChangeRequest getSignChangeRequest(@NotNull Player player) {
return signChangeRequests.remove(player);
return this.signChangeRequests.remove(player);
}
/**
@ -54,19 +56,44 @@ public class PlaceholderSignRequestHandler {
* @param raw <p>Whether to display the raw text (visible formatting codes)</p>
*/
public void addSignViewRequest(@NotNull Player player, boolean raw) {
signViewRequests.put(player, 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>True if the player has requested to view a sign</p>
* @return <p>Not null if the player has requested to view a sign</p>
*/
@Nullable
public Boolean getSignViewRequest(@NotNull Player player) {
if (signViewRequests.containsKey(player)) {
return signViewRequests.remove(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;
}

View File

@ -13,6 +13,7 @@ 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 +25,7 @@ import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
import java.util.Objects;
/**
@ -41,15 +43,22 @@ public class SignClickListener implements Listener {
Player player = event.getPlayer();
PlaceholderSignRequestHandler requestHandler = PlaceholderSigns.getInstance().getRequestHandler();
Boolean hasSignViewRequest = requestHandler.getSignViewRequest(player);
Boolean hasSignViewRequest = requestHandler.getSignViewRequest(player);
if (hasSignViewRequest != null) {
printSign(sign, player, hasSignViewRequest);
printSign(sign, player, hasSignViewRequest, false);
// Cancel the event to prevent vanilla behavior
event.setCancelled(true);
return;
}
Boolean hasPlaceholderSignViewRequest = requestHandler.getPlaceholderSignViewRequest(player);
if (hasPlaceholderSignViewRequest != null) {
printSign(sign, player, hasPlaceholderSignViewRequest, true);
event.setCancelled(true);
return;
}
if (sign.isWaxed() && !player.hasPermission("placeholdersigns.edit.bypass-waxed")) {
PlaceholderSigns.getInstance().getStringFormatter().displayErrorMessage(player,
PlaceholderSignMessage.ERROR_WAXED_NO_PERMISSION);
@ -68,41 +77,46 @@ public class SignClickListener implements Listener {
/**
* 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>
* @param raw <p>Whether to get the raw text with used formatting codes</p>
* @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>
*/
private void printSign(@NotNull Sign sign, @NotNull Player player, boolean raw) {
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 = getSignText(front, raw);
String backLines = getSignText(back, raw);
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}", getGlow(front));
replacer.add("{frontGlow}", getStatus(front.isGlowingText()));
replacer.add("{backDye}", getDye(back));
replacer.add("{backGlow}", getGlow(back));
replacer.add("{backGlow}", getStatus(back.isGlowingText()));
replacer.add("{waxed}", getStatus(sign.isWaxed()));
player.sendMessage(replacer.replace());
}
/**
* Gets a description of the glow of a sign
* Gets a description of the status of a sign property
*
* @param signSide <p>The sign side to get the dye of</p>
* @return <p>The description of the applied dye</p>
* @param isTrue <p>Whether the property is true</p>
* @return <p>A description of the property's current status</p>
*/
@NotNull
private String getGlow(@NotNull SignSide signSide) {
boolean glowing = signSide.isGlowingText();
private String getStatus(boolean isTrue) {
StringFormatter stringFormatter = PlaceholderSigns.getInstance().getStringFormatter();
if (glowing) {
return stringFormatter.getUnformattedColoredMessage(PlaceholderSignMessage.GLOWING_CONFIRM);
if (isTrue) {
return stringFormatter.getUnformattedColoredMessage(PlaceholderSignMessage.SIGN_PROPERTY_CONFIRM);
} else {
return stringFormatter.getUnformattedColoredMessage(PlaceholderSignMessage.GLOWING_DENY);
return stringFormatter.getUnformattedColoredMessage(PlaceholderSignMessage.SIGN_PROPERTY_DENY);
}
}
@ -126,22 +140,47 @@ public class SignClickListener implements Listener {
/**
* Gets text from a sign side, and appends it to the given string builder
*
* @param signSide <p>The sign side to get text from</p>
* @param raw <p>Whether to get the raw text with used formatting codes</p>
* @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 getSignText(@NotNull SignSide signSide, boolean raw) {
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 = signSide.getLine(i);
String line = lines[i];
if (raw) {
output.append(line.replace(ChatColor.COLOR_CHAR, '&'));
} else {
output.append(line);
}
output.append("\n");
output.append(ChatColor.COLOR_CHAR).append("r\n");
}
return output.toString();
}

View File

@ -18,6 +18,14 @@ commands:
usage: /<command>
permission: placeholdersigns.view
description: Displays the raw contents of a sign in the chat (useful for lines exceeding the viewable area, or to see formatting used)
viewPlaceholderSign:
usage: /<command>
permission: placeholdersigns.view
description: Displays the contents of a sign in the chat, including stored placeholders
viewPlaceholderSignRaw:
usage: /<command>
permission: placeholdersigns.view
description: Displays the raw contents of a sign in the chat, including stored placeholders
permissions:
placeholdersigns.*:

View File

@ -4,12 +4,13 @@ en:
ERROR_WAXED_NO_PERMISSION: "You do not have the necessary permissions to edit a waxed sign."
SUCCESS_SIGN_CHANGED: "The sign line was successfully changed."
SUCCESS_SIGN_CONTENTS: |
#78da55&lSign contents:&r
#17A057Front:&r
{frontLines}
#8899A5Dye&r {frontDye}&r, #8899A5Glowing&r {frontGlow}&r
{frontLines}#8899A5Dye&r {frontDye}&r, #8899A5Glowing&r {frontGlow}&r
#A01760Back:&r
{backLines}
#8899A5Dye&r {backDye}&r, #8899A5Glowing&r {backGlow}&r
GLOWING_CONFIRM: "#FDFFC8Yes"
GLOWING_DENY: "#CAC8FFNo"
{backLines}#8899A5Dye&r {backDye}&r, #8899A5Glowing&r {backGlow}&r
#ffdf32Waxed {waxed}
SIGN_PROPERTY_CONFIRM: "#FDFFC8Yes"
SIGN_PROPERTY_DENY: "#CAC8FFNo"