Adds commands for viewing placeholders on a sign
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
080e6204f4
commit
598b6c9cb9
@ -4,6 +4,7 @@ import net.knarcraft.knarlib.formatting.StringFormatter;
|
|||||||
import net.knarcraft.knarlib.formatting.Translator;
|
import net.knarcraft.knarlib.formatting.Translator;
|
||||||
import net.knarcraft.knarlib.property.ColorConversion;
|
import net.knarcraft.knarlib.property.ColorConversion;
|
||||||
import net.knarcraft.placeholdersigns.command.EditSignCommand;
|
import net.knarcraft.placeholdersigns.command.EditSignCommand;
|
||||||
|
import net.knarcraft.placeholdersigns.command.ViewPlaceholderSignCommand;
|
||||||
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;
|
||||||
@ -94,6 +95,8 @@ public final class PlaceholderSigns extends JavaPlugin {
|
|||||||
registerCommand("editSign", new EditSignCommand());
|
registerCommand("editSign", new EditSignCommand());
|
||||||
registerCommand("viewSign", new ViewSignCommand(false));
|
registerCommand("viewSign", new ViewSignCommand(false));
|
||||||
registerCommand("viewSignRaw", new ViewSignCommand(true));
|
registerCommand("viewSignRaw", new ViewSignCommand(true));
|
||||||
|
registerCommand("viewPlaceholderSign", new ViewPlaceholderSignCommand(false));
|
||||||
|
registerCommand("viewPlaceholderSignRaw", new ViewPlaceholderSignCommand(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -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<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -34,14 +34,14 @@ public enum PlaceholderSignMessage implements TranslatableMessage {
|
|||||||
SUCCESS_SIGN_CONTENTS,
|
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
|
@Override
|
||||||
|
@ -15,6 +15,7 @@ public class PlaceholderSignRequestHandler {
|
|||||||
|
|
||||||
private final Map<Player, SignLineChangeRequest> signChangeRequests;
|
private final Map<Player, SignLineChangeRequest> signChangeRequests;
|
||||||
private final Map<Player, Boolean> signViewRequests;
|
private final Map<Player, Boolean> signViewRequests;
|
||||||
|
private final Map<Player, Boolean> placeholderSignViewRequests;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new placeholder sign request handler
|
* Instantiates a new placeholder sign request handler
|
||||||
@ -22,6 +23,7 @@ public class PlaceholderSignRequestHandler {
|
|||||||
public PlaceholderSignRequestHandler() {
|
public PlaceholderSignRequestHandler() {
|
||||||
this.signChangeRequests = new HashMap<>();
|
this.signChangeRequests = new HashMap<>();
|
||||||
this.signViewRequests = 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>
|
* @param request <p>The sign change request to register</p>
|
||||||
*/
|
*/
|
||||||
public void addSignChangeRequest(@NotNull SignLineChangeRequest request) {
|
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
|
@Nullable
|
||||||
public SignLineChangeRequest getSignChangeRequest(@NotNull Player player) {
|
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>
|
* @param raw <p>Whether to display the raw text (visible formatting codes)</p>
|
||||||
*/
|
*/
|
||||||
public void addSignViewRequest(@NotNull Player player, boolean raw) {
|
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
|
* Checks whether the given player has a sign view request
|
||||||
*
|
*
|
||||||
* @param player <p>The player to check</p>
|
* @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
|
@Nullable
|
||||||
public Boolean getSignViewRequest(@NotNull Player player) {
|
public Boolean getSignViewRequest(@NotNull Player player) {
|
||||||
if (signViewRequests.containsKey(player)) {
|
if (this.signViewRequests.containsKey(player)) {
|
||||||
return signViewRequests.remove(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 {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import net.knarcraft.placeholdersigns.handler.PlaceholderSignRequestHandler;
|
|||||||
import net.md_5.bungee.api.ChatColor;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.DyeColor;
|
import org.bukkit.DyeColor;
|
||||||
|
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;
|
||||||
import org.bukkit.block.sign.SignSide;
|
import org.bukkit.block.sign.SignSide;
|
||||||
@ -24,6 +25,7 @@ import org.bukkit.event.block.SignChangeEvent;
|
|||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,15 +43,22 @@ public class SignClickListener implements Listener {
|
|||||||
|
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
PlaceholderSignRequestHandler requestHandler = PlaceholderSigns.getInstance().getRequestHandler();
|
PlaceholderSignRequestHandler requestHandler = PlaceholderSigns.getInstance().getRequestHandler();
|
||||||
Boolean hasSignViewRequest = requestHandler.getSignViewRequest(player);
|
|
||||||
|
|
||||||
|
Boolean hasSignViewRequest = requestHandler.getSignViewRequest(player);
|
||||||
if (hasSignViewRequest != null) {
|
if (hasSignViewRequest != null) {
|
||||||
printSign(sign, player, hasSignViewRequest);
|
printSign(sign, player, hasSignViewRequest, false);
|
||||||
// Cancel the event to prevent vanilla behavior
|
// Cancel the event to prevent vanilla behavior
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
return;
|
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")) {
|
if (sign.isWaxed() && !player.hasPermission("placeholdersigns.edit.bypass-waxed")) {
|
||||||
PlaceholderSigns.getInstance().getStringFormatter().displayErrorMessage(player,
|
PlaceholderSigns.getInstance().getStringFormatter().displayErrorMessage(player,
|
||||||
PlaceholderSignMessage.ERROR_WAXED_NO_PERMISSION);
|
PlaceholderSignMessage.ERROR_WAXED_NO_PERMISSION);
|
||||||
@ -68,41 +77,46 @@ public class SignClickListener implements Listener {
|
|||||||
/**
|
/**
|
||||||
* Prints the current contents of a sign to a player
|
* Prints the current contents of a sign to a player
|
||||||
*
|
*
|
||||||
* @param sign <p>The sign to print</p>
|
* @param sign <p>The sign to print</p>
|
||||||
* @param player <p>The player to display the contents to</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 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 front = sign.getSide(Side.FRONT);
|
||||||
SignSide back = sign.getSide(Side.BACK);
|
SignSide back = sign.getSide(Side.BACK);
|
||||||
String frontLines = getSignText(front, raw);
|
String frontLines = showPlaceholders ? getPlaceholderSignText(location, front, Side.FRONT, raw) :
|
||||||
String backLines = getSignText(back, raw);
|
getSignText(front.getLines(), raw);
|
||||||
|
String backLines = showPlaceholders ? getPlaceholderSignText(location, back, Side.BACK, raw) :
|
||||||
|
getSignText(back.getLines(), raw);
|
||||||
|
|
||||||
StringFormatter stringFormatter = PlaceholderSigns.getInstance().getStringFormatter();
|
StringFormatter stringFormatter = PlaceholderSigns.getInstance().getStringFormatter();
|
||||||
StringReplacer replacer = new StringReplacer(stringFormatter.getUnformattedColoredMessage(
|
StringReplacer replacer = new StringReplacer(stringFormatter.getUnformattedColoredMessage(
|
||||||
PlaceholderSignMessage.SUCCESS_SIGN_CONTENTS));
|
PlaceholderSignMessage.SUCCESS_SIGN_CONTENTS));
|
||||||
replacer.add("{frontLines}", frontLines);
|
replacer.add("{frontLines}", frontLines);
|
||||||
replacer.add("{backLines}", backLines);
|
replacer.add("{backLines}", backLines);
|
||||||
replacer.add("{frontDye}", getDye(front));
|
replacer.add("{frontDye}", getDye(front));
|
||||||
replacer.add("{frontGlow}", getGlow(front));
|
replacer.add("{frontGlow}", getStatus(front.isGlowingText()));
|
||||||
replacer.add("{backDye}", getDye(back));
|
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());
|
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>
|
* @param isTrue <p>Whether the property is true</p>
|
||||||
* @return <p>The description of the applied dye</p>
|
* @return <p>A description of the property's current status</p>
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
private String getGlow(@NotNull SignSide signSide) {
|
private String getStatus(boolean isTrue) {
|
||||||
boolean glowing = signSide.isGlowingText();
|
|
||||||
StringFormatter stringFormatter = PlaceholderSigns.getInstance().getStringFormatter();
|
StringFormatter stringFormatter = PlaceholderSigns.getInstance().getStringFormatter();
|
||||||
if (glowing) {
|
if (isTrue) {
|
||||||
return stringFormatter.getUnformattedColoredMessage(PlaceholderSignMessage.GLOWING_CONFIRM);
|
return stringFormatter.getUnformattedColoredMessage(PlaceholderSignMessage.SIGN_PROPERTY_CONFIRM);
|
||||||
} else {
|
} 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
|
* 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 signLocation <p>The location of the sign</p>
|
||||||
* @param raw <p>Whether to get the raw text with used formatting codes</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
|
@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();
|
StringBuilder output = new StringBuilder();
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
output.append(i + 1).append(". ");
|
output.append(i + 1).append(". ");
|
||||||
|
|
||||||
String line = signSide.getLine(i);
|
String line = lines[i];
|
||||||
if (raw) {
|
if (raw) {
|
||||||
output.append(line.replace(ChatColor.COLOR_CHAR, '&'));
|
output.append(line.replace(ChatColor.COLOR_CHAR, '&'));
|
||||||
} else {
|
} else {
|
||||||
output.append(line);
|
output.append(line);
|
||||||
}
|
}
|
||||||
output.append("\n");
|
output.append(ChatColor.COLOR_CHAR).append("r\n");
|
||||||
}
|
}
|
||||||
return output.toString();
|
return output.toString();
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,14 @@ commands:
|
|||||||
usage: /<command>
|
usage: /<command>
|
||||||
permission: placeholdersigns.view
|
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)
|
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:
|
permissions:
|
||||||
placeholdersigns.*:
|
placeholdersigns.*:
|
||||||
|
@ -4,12 +4,13 @@ en:
|
|||||||
ERROR_WAXED_NO_PERMISSION: "You do not have the necessary permissions to edit a waxed sign."
|
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_CHANGED: "The sign line was successfully changed."
|
||||||
SUCCESS_SIGN_CONTENTS: |
|
SUCCESS_SIGN_CONTENTS: |
|
||||||
|
#78da55&lSign contents:&r
|
||||||
#17A057Front:&r
|
#17A057Front:&r
|
||||||
{frontLines}
|
{frontLines}#8899A5Dye&r {frontDye}&r, #8899A5Glowing&r {frontGlow}&r
|
||||||
#8899A5Dye&r {frontDye}&r, #8899A5Glowing&r {frontGlow}&r
|
|
||||||
|
|
||||||
#A01760Back:&r
|
#A01760Back:&r
|
||||||
{backLines}
|
{backLines}#8899A5Dye&r {backDye}&r, #8899A5Glowing&r {backGlow}&r
|
||||||
#8899A5Dye&r {backDye}&r, #8899A5Glowing&r {backGlow}&r
|
|
||||||
GLOWING_CONFIRM: "#FDFFC8Yes"
|
#ffdf32Waxed {waxed}
|
||||||
GLOWING_DENY: "#CAC8FFNo"
|
SIGN_PROPERTY_CONFIRM: "#FDFFC8Yes"
|
||||||
|
SIGN_PROPERTY_DENY: "#CAC8FFNo"
|
Loading…
Reference in New Issue
Block a user