265 lines
10 KiB
Java
265 lines
10 KiB
Java
package com.earth2me.essentials.commands;
|
|
|
|
import com.earth2me.essentials.User;
|
|
import com.earth2me.essentials.utils.FormatUtil;
|
|
import com.earth2me.essentials.utils.NumberUtil;
|
|
import com.earth2me.essentials.utils.VersionUtil;
|
|
import com.google.common.collect.Lists;
|
|
import net.ess3.api.TranslatableException;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.ChatColor;
|
|
import org.bukkit.Server;
|
|
import org.bukkit.block.Block;
|
|
import org.bukkit.block.BlockFace;
|
|
import org.bukkit.block.Sign;
|
|
import org.bukkit.block.data.BlockData;
|
|
import org.bukkit.block.data.type.HangingSign;
|
|
import org.bukkit.block.data.type.WallHangingSign;
|
|
import org.bukkit.block.data.type.WallSign;
|
|
import org.bukkit.block.sign.Side;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.event.block.SignChangeEvent;
|
|
import org.bukkit.util.Vector;
|
|
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
|
|
public class Commandeditsign extends EssentialsCommand {
|
|
public Commandeditsign() {
|
|
super("editsign");
|
|
}
|
|
|
|
@Override
|
|
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
|
if (args.length == 0 || (args.length > 1 && !NumberUtil.isInt(args[1]))) {
|
|
throw new NotEnoughArgumentsException();
|
|
}
|
|
|
|
final Block target = user.getTargetBlock(5); //5 is a good number
|
|
if (!(target.getState() instanceof Sign)) {
|
|
throw new TranslatableException("editsignCommandTarget");
|
|
}
|
|
final ModifiableSign sign = wrapSign((Sign) target.getState(), user);
|
|
try {
|
|
if (args[0].equalsIgnoreCase("set") && args.length > 2) {
|
|
final String[] existingLines = sign.getLines();
|
|
final int line = Integer.parseInt(args[1]) - 1;
|
|
final String text = FormatUtil.formatString(user, "essentials.editsign", getFinalArg(args, 2)).trim();
|
|
if (ChatColor.stripColor(text).length() > 15 && !user.isAuthorized("essentials.editsign.unlimited")) {
|
|
throw new TranslatableException("editsignCommandLimit");
|
|
}
|
|
existingLines[line] = text;
|
|
if (callSignEvent(sign, user.getBase(), existingLines)) {
|
|
return;
|
|
}
|
|
|
|
user.sendTl("editsignCommandSetSuccess", line + 1, text);
|
|
} else if (args[0].equalsIgnoreCase("clear")) {
|
|
if (args.length == 1) {
|
|
final String[] existingLines = sign.getLines();
|
|
for (int i = 0; i < 4; i++) { // A whole one line of line savings!
|
|
existingLines[i] = "";
|
|
}
|
|
|
|
if (callSignEvent(sign, user.getBase(), existingLines)) {
|
|
return;
|
|
}
|
|
|
|
user.sendTl("editsignCommandClear");
|
|
} else {
|
|
final String[] existingLines = sign.getLines();
|
|
final int line = Integer.parseInt(args[1]) - 1;
|
|
existingLines[line] = "";
|
|
|
|
if (callSignEvent(sign, user.getBase(), existingLines)) {
|
|
return;
|
|
}
|
|
|
|
user.sendTl("editsignCommandClearLine", line + 1);
|
|
}
|
|
} else if (args[0].equalsIgnoreCase("copy")) {
|
|
final int line = args.length == 1 ? -1 : Integer.parseInt(args[1]) - 1;
|
|
|
|
if (line == -1) {
|
|
for (int i = 0; i < 4; i++) {
|
|
// We use unformat here to prevent players from copying signs with colors that they do not have permission to use.
|
|
user.getSignCopy().set(i, FormatUtil.unformatString(user, "essentials.editsign", sign.getLine(i)));
|
|
}
|
|
user.sendTl("editsignCopy", commandLabel);
|
|
} else {
|
|
// We use unformat here to prevent players from copying signs with colors that they do not have permission to use.
|
|
user.getSignCopy().set(line, FormatUtil.unformatString(user, "essentials.editsign", sign.getLine(line)));
|
|
user.sendTl("editsignCopyLine", line + 1, commandLabel);
|
|
}
|
|
|
|
} else if (args[0].equalsIgnoreCase("paste")) {
|
|
final int line = args.length == 1 ? -1 : Integer.parseInt(args[1]) - 1;
|
|
|
|
final String[] existingLines = sign.getLines();
|
|
if (line == -1) {
|
|
for (int i = 0; i < 4; i++) {
|
|
existingLines[i] = FormatUtil.formatString(user, "essentials.editsign", user.getSignCopy().get(i));
|
|
}
|
|
user.sendTl("editsignPaste", commandLabel);
|
|
} else {
|
|
existingLines[line] = FormatUtil.formatString(user, "essentials.editsign", user.getSignCopy().get(line));
|
|
user.sendTl("editsignPasteLine", line + 1, commandLabel);
|
|
}
|
|
|
|
callSignEvent(sign, user.getBase(), existingLines);
|
|
} else {
|
|
throw new NotEnoughArgumentsException();
|
|
}
|
|
} catch (final IndexOutOfBoundsException e) {
|
|
throw new TranslatableException(e, "editsignCommandNoLine");
|
|
}
|
|
}
|
|
|
|
private boolean callSignEvent(final ModifiableSign sign, final Player player, final String[] lines) {
|
|
final SignChangeEvent event;
|
|
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_20_1_R01)) {
|
|
if (sign.isWaxed() && !player.hasPermission("essentials.editsign.waxed.exempt")) {
|
|
return true;
|
|
}
|
|
event = new SignChangeEvent(sign.getBlock(), player, lines, sign.isFront() ? Side.FRONT : Side.BACK);
|
|
} else {
|
|
//noinspection deprecation
|
|
event = new SignChangeEvent(sign.getBlock(), player, lines);
|
|
}
|
|
|
|
Bukkit.getServer().getPluginManager().callEvent(event);
|
|
if (event.isCancelled()) {
|
|
if (ess.getSettings().isDebug()) {
|
|
ess.getLogger().info("SignChangeEvent canceled for /editsign execution by " + player.getName());
|
|
}
|
|
return true;
|
|
}
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
sign.setLine(i, lines[i]);
|
|
}
|
|
sign.update();
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
|
if (args.length == 1) {
|
|
return Lists.newArrayList("set", "clear", "copy", "paste");
|
|
} else if (args.length == 2) {
|
|
return Lists.newArrayList("1", "2", "3", "4");
|
|
} else if (args.length == 3 && args[0].equalsIgnoreCase("set") && NumberUtil.isPositiveInt(args[1])) {
|
|
final int line = Integer.parseInt(args[1]);
|
|
final Block target = user.getTargetBlock(5);
|
|
if (target.getState() instanceof Sign && line <= 4) {
|
|
final ModifiableSign sign = wrapSign((Sign) target.getState(), user);
|
|
return Lists.newArrayList(FormatUtil.unformatString(user, "essentials.editsign", sign.getLine(line - 1)));
|
|
}
|
|
return Collections.emptyList();
|
|
} else {
|
|
return Collections.emptyList();
|
|
}
|
|
}
|
|
|
|
private ModifiableSign wrapSign(final Sign sign, final User user) {
|
|
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_20_1_R01)) {
|
|
final Vector eyeLocLessSign = user.getBase().getEyeLocation().toVector().subtract(sign.getLocation().add(.5, .5, .5).toVector());
|
|
final BlockData signBlockData = sign.getBlockData();
|
|
|
|
final BlockFace signDirection;
|
|
if (signBlockData instanceof org.bukkit.block.data.type.Sign) {
|
|
signDirection = ((org.bukkit.block.data.type.Sign) signBlockData).getRotation();
|
|
} else if (signBlockData instanceof WallSign) {
|
|
signDirection = ((WallSign) signBlockData).getFacing();
|
|
} else if (signBlockData instanceof HangingSign) {
|
|
signDirection = ((HangingSign) signBlockData).getRotation();
|
|
} else if (signBlockData instanceof WallHangingSign) {
|
|
signDirection = ((WallHangingSign) signBlockData).getFacing();
|
|
} else {
|
|
throw new IllegalStateException("Unknown block data for sign: " + signBlockData.getClass());
|
|
}
|
|
|
|
final Side side = eyeLocLessSign.dot(signDirection.getDirection()) > 0 ? Side.FRONT : Side.BACK;
|
|
|
|
return new ModifiableSign(sign) {
|
|
@Override
|
|
String[] getLines() {
|
|
return sign.getSide(side).getLines();
|
|
}
|
|
|
|
@Override
|
|
String getLine(int line) {
|
|
return sign.getSide(side).getLine(line);
|
|
}
|
|
|
|
@Override
|
|
void setLine(int line, String text) {
|
|
sign.getSide(side).setLine(line, text);
|
|
}
|
|
|
|
@Override
|
|
boolean isFront() {
|
|
return side == Side.FRONT;
|
|
}
|
|
|
|
@Override
|
|
boolean isWaxed() {
|
|
return sign.isWaxed();
|
|
}
|
|
};
|
|
}
|
|
return new ModifiableSign(sign) {
|
|
@Override
|
|
String[] getLines() {
|
|
return sign.getLines();
|
|
}
|
|
|
|
@Override
|
|
String getLine(int line) {
|
|
return sign.getLine(line);
|
|
}
|
|
|
|
@Override
|
|
void setLine(int line, String text) {
|
|
sign.setLine(line, text);
|
|
}
|
|
|
|
@Override
|
|
boolean isFront() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
boolean isWaxed() {
|
|
return false;
|
|
}
|
|
};
|
|
}
|
|
|
|
private abstract static class ModifiableSign {
|
|
protected final Sign sign;
|
|
|
|
protected ModifiableSign(final Sign sign) {
|
|
this.sign = sign;
|
|
}
|
|
|
|
abstract String getLine(int line);
|
|
|
|
abstract String[] getLines();
|
|
|
|
abstract void setLine(int line, String text);
|
|
|
|
abstract boolean isFront();
|
|
|
|
abstract boolean isWaxed();
|
|
|
|
Block getBlock() {
|
|
return sign.getBlock();
|
|
}
|
|
|
|
void update() {
|
|
sign.update();
|
|
}
|
|
}
|
|
}
|