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

时间:2016-06-16 23:39:32

标签: java bukkit

所以我有这个插件我正在研究,我将解释这个功能,以便你知道它应该做什么:
- / showcps:告诉发件人每当指定的玩家左/右点击

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

这是我的问题。我想我知道它为什么会发生,但我不知道如何解决它。我使用全局变量来在click侦听器和命令执行器类之间交替使用它们。

以下是听众的代码:

@
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用于两个类之间,但我觉得这就是他们无法同时观看不同点击的原因。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

我建议你在深入了解Bukkit之前学习java,因为这段代码存在严重问题。

您的问题出现了,因为您有 1 变量来存储receiveng播放器和发送播放器。这样,如果你更改它,那么旧的接收播放器将不会获得任何新消息。使用散列图将发送播放器的UUID作为密钥,将接收播放器的UUID作为值,然后当播放器在地图中时,向其相应的接收者发送消息。

yoir代码中的其他问题:

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

将枚举与==而不是.equal

进行比较

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

永远不要存储完整的玩家对象,如果你不够小心,他们会导致内存泄漏。

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

这些问题与http://bukkit.org论坛在90%的时间内遇到的问题相同。将该论坛用于基于Bukkit的问题,人们可以在那里提供更多帮助。