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;
}
}
如你所见,receivingPlayer
和 targetPlayer
被用在两者之间 类,但我觉得这就是他们不能同时观看不同点击的原因同时。
我该如何解决这个问题?
我建议你在学习 Bukkit 之前学习 java,因为这段代码有严重的问题。
您的问题出现了,因为您有 1 变量来存储接收播放器和发送播放器。这样,如果您更改它,那么旧的接收播放器将不会收到任何新消息。使用以发送玩家的 UUID 为键,接收玩家的 UUID 为值的哈希图,然后当玩家在地图中时,向其对应的接收者发送消息。
你代码中的其他问题:
不要滥用静态,这是一种不好的做法,请使用 getter 和 setter。
将枚举与 == 而不是 .equal 进行比较
您的插件中的事件类型应该只有 1 个事件处理程序。
切勿存储完整的玩家对象,如果您不够小心,它们可能会导致内存泄漏。
args[0].isEmpty()
只检查,如果 args[0] 等于一个 emoty 字符串,如果玩家没有指定参数,那么这将抛出一个错误。
我们在 http://bukkit.org 论坛上 90% 的时间都会遇到同样的问题。使用该论坛解决基于 Bukkit 的问题,人们可以在那里提供更多帮助。
所以我已经有了正在开发的这个插件,我将解释该功能,以便您了解它应该做什么:
-/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;
}
}
如你所见,receivingPlayer
和 targetPlayer
被用在两者之间 类,但我觉得这就是他们不能同时观看不同点击的原因同时。
我该如何解决这个问题?
我建议你在学习 Bukkit 之前学习 java,因为这段代码有严重的问题。
您的问题出现了,因为您有 1 变量来存储接收播放器和发送播放器。这样,如果您更改它,那么旧的接收播放器将不会收到任何新消息。使用以发送玩家的 UUID 为键,接收玩家的 UUID 为值的哈希图,然后当玩家在地图中时,向其对应的接收者发送消息。
你代码中的其他问题:
不要滥用静态,这是一种不好的做法,请使用 getter 和 setter。
将枚举与 == 而不是 .equal 进行比较
您的插件中的事件类型应该只有 1 个事件处理程序。
切勿存储完整的玩家对象,如果您不够小心,它们可能会导致内存泄漏。
args[0].isEmpty()
只检查,如果 args[0] 等于一个 emoty 字符串,如果玩家没有指定参数,那么这将抛出一个错误。
我们在 http://bukkit.org 论坛上 90% 的时间都会遇到同样的问题。使用该论坛解决基于 Bukkit 的问题,人们可以在那里提供更多帮助。