diff --git a/src/main/java/ling/coordinateRecorder/Commands/ZbCommand.java b/src/main/java/ling/coordinateRecorder/Commands/ZbCommand.java index f3224c7..5c46f0b 100644 --- a/src/main/java/ling/coordinateRecorder/Commands/ZbCommand.java +++ b/src/main/java/ling/coordinateRecorder/Commands/ZbCommand.java @@ -42,7 +42,7 @@ public class ZbCommand implements CommandExecutor, TabCompleter { protected final static List TAB_1 = Arrays.asList("add", "remove", "help", "reload", "list", "fixed", "unfixed", "unlock", "sb", "tp", "yes", "no", "setting", - "give", "set"); + "give", "set", "return"); public ZbCommand() { @@ -520,6 +520,38 @@ public class ZbCommand implements CommandExecutor, TabCompleter { } } + /// 撤销传送 + @SuppressWarnings("DuplicatedCode") + protected void returnTp(Player player, String[] strings) { + if (strings.length > 2) { + player.sendMessage(ChatColor.RED + "命令过长!"); + return; + } + PlayerData data = PlayerMap.getCurrent().getPlayerData(player); + if (data == null) { + player.sendMessage(ChatColor.RED + "玩家未注册"); + return; + } + if (data.getTransmitData() != null) { + player.sendMessage(ChatColor.RED + "你已经在引导传送了"); + return; + } + if (data.getToMeTransmitData() != null) { + player.sendMessage(ChatColor.RED + "有人正在向你传送"); + return; + } + long key = -1; + if (strings.length == 2) { + try { + key = Long.parseLong(strings[1]); + } catch (NumberFormatException e) { + player.sendMessage(ChatColor.RED + "无法解析的参数:" + strings[1]); + return; + } + } + CoordinateRecorder.getTransmitService().addTransmitReturn(data, key); + } + protected boolean execute(Player player, String[] strings) { if (strings.length < 1) { player.sendMessage(ChatColor.RED + "语法错误:需要 [选项]"); @@ -564,6 +596,9 @@ public class ZbCommand implements CommandExecutor, TabCompleter { case "give": giveSwordOfCommand(player); break; + case "return": + returnTp(player, strings); + break; default: player.sendMessage(ChatColor.RED + "未知的选项:" + strings[0]); break; diff --git a/src/main/java/ling/coordinateRecorder/Service/TransmitService.java b/src/main/java/ling/coordinateRecorder/Service/TransmitService.java index 63d310f..bfa4dbc 100644 --- a/src/main/java/ling/coordinateRecorder/Service/TransmitService.java +++ b/src/main/java/ling/coordinateRecorder/Service/TransmitService.java @@ -1,7 +1,9 @@ package ling.coordinateRecorder.Service; import ling.coordinateRecorder.Config; +import ling.coordinateRecorder.data.PlayerData; import ling.coordinateRecorder.data.TransmitData; +import ling.coordinateRecorder.data.TransmitOriginal; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.HoverEvent; @@ -40,14 +42,11 @@ public final class TransmitService implements Service { Player player = data.getPlayer().getPlayer(); Location from = player.getLocation(); Location to = data.getTarget(); - if (to == null) - to = data.getTargetPlayer().getPlayer().getLocation(); + if (to == null) to = data.getTargetPlayer().getPlayer().getLocation(); if (data.isConfirm()) { - player.sendMessage( - "传送引导中...(将带来" + Config.getFractionTimeMessage( - getTransmitCost(from, to)) + - "点沙雕值惩罚,当前" + Config.getFractionTimeMessage(data.getPlayer().getFraction()) + - ")"); + player.sendMessage("传送引导中...(将带来" + Config.getFractionTimeMessage( + getTransmitCost(from, to)) + "点沙雕值惩罚,当前" + Config.getFractionTimeMessage( + data.getPlayer().getFraction()) + ")"); } else { player.sendMessage("正在等待目标玩家响应..."); BaseComponent message = new TextComponent("玩家 " + player.getName() + " 正在请求向你传送\n"); @@ -93,27 +92,41 @@ public final class TransmitService implements Service { unlock(); } + /// 撤销历史传送 + public void addTransmitReturn(PlayerData data, long key) { + if (data.getOriginal() == null || data.getOriginal().getTime() + 60 * 5 * 1000 < System.currentTimeMillis()) { + data.getPlayer().sendMessage(ChatColor.RED + "没有找到历史传送数据"); + return; + } + //防止撤销了过期的数据 + if (key > 0 && data.getOriginal().getTime() != key) { + data.getPlayer().sendMessage(ChatColor.RED + "请求已经失效,无法撤销!"); + return; + } + TransmitData transmit = new TransmitData(data, data.getOriginal().getLocation()); + transmit.setReturn(true); + addTransmit(transmit); + } + public void addTransmit(TransmitData data) { if (!isFractionTransmit(data)) { - data.getPlayer().getPlayer().sendMessage( - "你的沙雕值过高,被禁止传送!( >" + Config.getFractionTimeMessage(data.getPlayer().getFraction()) + - " )"); + data.getPlayer().getPlayer().sendMessage("你的沙雕值过高,被禁止传送!( >" + Config.getFractionTimeMessage( + data.getPlayer().getFraction()) + " )"); return; } // 如果目标玩家不允许任何人向它传送 if (data.getTargetPlayer() != null && !data.getTargetPlayer().isTpMe()) { data.getPlayer().getPlayer().sendMessage( "目标玩家拒绝了你的传送请求,因为:" + data.getTargetPlayer().rejectMessage()); - data.getTargetPlayer().getPlayer().sendMessage("玩家 " + data.getPlayer().getPlayer().getName() + " " + - "试图向你传送,已根据设置自动拒绝。"); + data.getTargetPlayer().getPlayer().sendMessage( + "玩家 " + data.getPlayer().getPlayer().getName() + " " + "试图向你传送,已根据设置自动拒绝。"); clearTransmitData(data); return; } lock(); sendTransmitMessage(data); data.getPlayer().setTransmitData(data); - if (data.getTargetPlayer() != null) - data.getTargetPlayer().setToMeTransmitData(data); + if (data.getTargetPlayer() != null) data.getTargetPlayer().setToMeTransmitData(data); list.put(data.getPlayer().getPlayer(), data); unlock(); } @@ -150,19 +163,53 @@ public final class TransmitService implements Service { return Math.min(value, Config.UNLOCK_PROHIBITED); } + private static BaseComponent getTitle() { + BaseComponent title = new TextComponent("[传送服务]"); + title.setColor(net.md_5.bungee.api.ChatColor.YELLOW); + title.setBold(true); + + BaseComponent message = new TextComponent(); + message.addExtra(title); + message.addExtra(" "); + return message; + } + /// 处理一个传送请求 private void success(TransmitData data) { Location from = data.getPlayer().getPlayer().getLocation(); Location to = data.getTarget(); - if (to == null) - to = data.getTargetPlayer().getPlayer().getLocation(); + if (to == null) to = data.getTargetPlayer().getPlayer().getLocation(); int value = getTransmitCost(from, to); + //撤销传送半价 + if (data.isReturn()) + value = Math.max((int) (value * 0.5), 1); try { data.getPlayer().addFraction(value); data.getPlayer().getPlayer().teleport(to); - data.getPlayer().getPlayer().sendMessage( - "传送完毕!您受到了" + Config.getFractionTimeMessage(value) + "点沙雕值惩罚!(当前:" - + Config.getFractionTimeMessage(data.getPlayer().getFraction()) + ")"); + if (data.isReturn()) { + data.getPlayer().setOriginal(null); + } else { + data.getPlayer().setOriginal(new TransmitOriginal(data)); + } + + BaseComponent title = getTitle(); + title.addExtra("传送完毕!您受到了" + Config.getFractionTimeMessage(value) + "点沙雕值惩罚!"); + title.addExtra("(当前:" + Config.getFractionTimeMessage(data.getPlayer().getFraction()) + ")"); + + if (!data.isReturn()) { + BaseComponent cancel = new TextComponent("撤销"); + cancel.setColor(net.md_5.bungee.api.ChatColor.RED); + cancel.setUnderlined(true); + cancel.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("点击撤销传送"))); + cancel.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + "/zb return " + data.getPlayer().getOriginal().getTime())); + title.addExtra(" "); + title.addExtra(cancel); + } + data.getPlayer().getPlayer().spigot().sendMessage(title); + /*data.getPlayer().getPlayer().sendMessage("传送完毕!您受到了" + Config.getFractionTimeMessage( + value) + "点沙雕值惩罚!(当前:" + Config.getFractionTimeMessage( + data.getPlayer().getFraction()) + ")");*/ } catch (SQLException e) { data.getPlayer().getPlayer().sendMessage(ChatColor.RED + "传送失败:施加沙雕值惩罚出错!"); } @@ -171,8 +218,7 @@ public final class TransmitService implements Service { /// 使一个传送请求失效 private void clearTransmitData(TransmitData data) { data.getPlayer().setTransmitData(null); - if (data.getTargetPlayer() != null) - data.getTargetPlayer().setToMeTransmitData(null); + if (data.getTargetPlayer() != null) data.getTargetPlayer().setToMeTransmitData(null); data.clear(); } @@ -194,16 +240,14 @@ public final class TransmitService implements Service { //删除已经被取消的传送请求 if (data.isInterrupt()) { data.getPlayer().getPlayer().sendMessage("传送取消!因为" + data.getInterruptMessage()); - if (data.getTargetPlayer() != null) - data.getTargetPlayer().getPlayer().sendMessage( - "玩家 " + data.getPlayer().getPlayer() - .getName() + " " + "的传送已取消,因为" + data.getInterruptMessage()); + if (data.getTargetPlayer() != null) data.getTargetPlayer().getPlayer().sendMessage( + "玩家 " + data.getPlayer().getPlayer() + .getName() + " " + "的传送已取消,因为" + data.getInterruptMessage()); clearTransmitData(data); iterator.remove(); continue; } - if (!data.isConfirm()) - continue; + if (!data.isConfirm()) continue; //处理已经引导完毕的传送请求 if (data.getTime() + Config.TRANSMIT_GUIDE_TIME < System.currentTimeMillis()) { success(data); diff --git a/src/main/java/ling/coordinateRecorder/data/PlayerData.java b/src/main/java/ling/coordinateRecorder/data/PlayerData.java index 9f2b7e2..b08d74e 100644 --- a/src/main/java/ling/coordinateRecorder/data/PlayerData.java +++ b/src/main/java/ling/coordinateRecorder/data/PlayerData.java @@ -41,6 +41,8 @@ public class PlayerData { protected TransmitData transmitData = null; protected TransmitData toMeTransmitData = null; protected PlayerHarm harm; + //传送前原始位置 + protected TransmitOriginal original; public PlayerData(Player player) throws SQLException { @@ -376,4 +378,12 @@ public class PlayerData { public void updateLocal() { ui.playerMove(); } + + public TransmitOriginal getOriginal() { + return original; + } + + public void setOriginal(TransmitOriginal original) { + this.original = original; + } } diff --git a/src/main/java/ling/coordinateRecorder/data/TransmitData.java b/src/main/java/ling/coordinateRecorder/data/TransmitData.java index 932e824..9b3084b 100644 --- a/src/main/java/ling/coordinateRecorder/data/TransmitData.java +++ b/src/main/java/ling/coordinateRecorder/data/TransmitData.java @@ -18,6 +18,7 @@ public class TransmitData { protected long time; protected boolean isInterrupt = false; protected boolean isConfirm = true; + protected boolean isReturn = false; protected BossBar bossBar = Bukkit.createBossBar(new NamespacedKey(CoordinateRecorder.getCurrent(), "transmitBar"), "正在准备传送", BarColor.BLUE, BarStyle.SOLID, BarFlag.DARKEN_SKY); protected String interruptMessage = "未知原因"; @@ -58,8 +59,7 @@ public class TransmitData { /// 打断传送 public void interrupt(@Nullable String message) { this.isInterrupt = true; - if (message != null) - this.interruptMessage = message; + if (message != null) this.interruptMessage = message; } public String getInterruptMessage() { @@ -82,6 +82,15 @@ public class TransmitData { return targetPlayer; } + public boolean isReturn() { + return isReturn; + } + + /// 是否是撤销传送 + public void setReturn(boolean aReturn) { + isReturn = aReturn; + } + public PlayerData getPlayer() { return player; } diff --git a/src/main/java/ling/coordinateRecorder/data/TransmitOriginal.java b/src/main/java/ling/coordinateRecorder/data/TransmitOriginal.java new file mode 100644 index 0000000..bab3759 --- /dev/null +++ b/src/main/java/ling/coordinateRecorder/data/TransmitOriginal.java @@ -0,0 +1,28 @@ +package ling.coordinateRecorder.data; + +import org.bukkit.Location; +import org.bukkit.entity.Player; + +/// 传送前位置 +public class TransmitOriginal { + protected final Location location; + protected final long time; + + public TransmitOriginal(Player player) { + this.location = player.getLocation(); + this.time = System.currentTimeMillis(); + } + + public TransmitOriginal(TransmitData data) { + this(data.getPlayer().getPlayer()); + } + + + public Location getLocation() { + return location; + } + + public long getTime() { + return time; + } +}