Bukkit - 使用静态变量导致问题

Bukkit - Using static variables causing problems

所以我已经有了正在开发的这个插件,我将解释该功能,以便您了解它应该做什么:
-/showcps : 每当指定玩家 left/right 点击

时通知发件人

所以,假设服务器上有两个玩家,Bob 和 Billy 运行 这个插件; Bob 执行命令 /showcps Billy 并在 Billy 单击时查看。然后 Billy 键入命令 /showcps Bob,现在当 Bob 单击时 Billy 会看到。问题是当 Billy 正在点击时,Bob 再也看不到了。

这是我的问题。我想我知道为什么会这样,但我不确定如何解决。我使用了全局变量,以便能够在点击侦听器和命令执行器之间互换使用它们 类。

这是监听器的代码:

@
EventHandler
public void leftClick(PlayerInteractEvent event) {
  Player player = event.getPlayer();

  if (event.getAction().equals(Action.LEFT_CLICK_AIR) | event.getAction().equals(Action.LEFT_CLICK_BLOCK)) {
    if (player.equals(ClickViewToggle.targetPlayer)) {
      ClickViewToggle.recivingPlayer.sendMessage(
        ChatColor.LIGHT_PURPLE + player.getName() + ChatColor.DARK_PURPLE + " left clicked.");
    }
  }
}

@
EventHandler
public void rightClick(PlayerInteractEvent event) {
  Player player = event.getPlayer();

  if (event.getAction().equals(Action.RIGHT_CLICK_AIR) | event.getAction().equals(Action.RIGHT_CLICK_BLOCK)) {
    if (player.equals(ClickViewToggle.targetPlayer)) {
      ClickViewToggle.recivingPlayer.sendMessage(
        ChatColor.LIGHT_PURPLE + player.getName() + ChatColor.DARK_PURPLE + " right clicked.");
    }
  }
}

命令执行器的代码如下:

public static Player targetPlayer = null;
public static Player recivingPlayer;

public boolean onCommand(CommandSender sender, Command command, String cmd, String[] args) {
  recivingPlayer = (Player) sender;
  if (args[0].isEmpty()) {
    if (sender instanceof Player) {
      sender.sendMessage(ChatColor.DARK_PURPLE + "You will now be able to see your clicks.");
      targetPlayer = (Player) sender;
      return false;
    } else {
      sender.sendMessage(ChatColor.DARK_PURPLE + "You must specify a player.");
      return false;
    }
  } else {
    boolean playerFound = false;
    for (Player player: Bukkit.getServer().getOnlinePlayers()) {
      if (player.getName().equalsIgnoreCase(args[0])) {
        sender.sendMessage(ChatColor.DARK_PURPLE + "You are now seeing " + ChatColor.LIGHT_PURPLE + player.getName() + ChatColor.DARK_PURPLE + "\'s clicks.");
        targetPlayer = player;
        playerFound = true;
        break;
      }
    }
    if (!playerFound) {
      sender.sendMessage(ChatColor.DARK_PURPLE + "Couldn't find " + ChatColor.LIGHT_PURPLE + args[0] + ChatColor.DARK_PURPLE + ".");
      targetPlayer = null;
    }
    return false;
  }
}

如你所见,receivingPlayertargetPlayer 被用在两者之间 类,但我觉得这就是他们不能同时观看不同点击的原因同时。

我该如何解决这个问题?

我建议你在学习 Bukkit 之前学习 java,因为这段代码有严重的问题。

您的问题出现了,因为您有 1 变量来存储接收播放器和发送播放器。这样,如果您更改它,那么旧的接收播放器将不会收到任何新消息。使用以发送玩家的 UUID 为键,接收玩家的 UUID 为值的哈希图,然后当玩家在地图中时,向其对应的接收者发送消息。

你代码中的其他问题:

不要滥用静态,这是一种不好的做法,请使用 getter 和 setter。

将枚举与 == 而不是 .equal 进行比较

您的插件中的事件类型应该只有 1 个事件处理程序。

切勿存储完整的玩家对象,如果您不够小心,它们可能会导致内存泄漏。

args[0].isEmpty() 只检查,如果 args[0] 等于一个 emoty 字符串,如果玩家没有指定参数,那么这将抛出一个错误。

我们在 http://bukkit.org 论坛上 90% 的时间都会遇到同样的问题。使用该论坛解决基于 Bukkit 的问题,人们可以在那里提供更多帮助。