为什么“< = 1”不按预期工作?

时间:2012-04-23 18:33:13

标签: java bukkit

我有以下代码

@EventHandler
public void onPlayerQuit(PlayerQuitEvent event){
    Player player = event.getPlayer();
    final Player[] playerlist = getServer().getOnlinePlayers();
    if (playerlist.length <=1) { // if no players are online
        getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable(){
            // this is a scheduler.
            public void run(){
                 if(playerlist.length <=1){
                     getServer().shutdown();
                 }
            }
        }, 6000L); // runs every 6000 ticks, which is every 300 seconds, which is every 5 minutes.
 }
}

当玩家离开时,它会检查他是否是最后一个,如果他是,那么在5分钟之后,它再次检查,如果仍然没有人在它应该停止服务器。< / p>

在这一行:

if (playerlist.length <=1) { // if no players are online

我必须将它作为&lt; = 1或它根本不起作用,但是如果我离开它也将停止服务器,并且加入并且我是唯一一个。当我在= 0并且只是<1时它没有工作。

有什么想法吗?

这是我的更新代码(仍然无效):

 @EventHandler
public void onPlayerQuit(PlayerQuitEvent event){
    Player player = event.getPlayer();
    final Player[] playerlist = getServer().getOnlinePlayers();
    if (playerlist.length <=1) { // if no players are online
        getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable(){
            // this is a scheduler.
            public void run(){
                final Player[] playerlist = getServer().getOnlinePlayers(); 
                if(playerlist.length <=1){
                     getServer().shutdown();
                 }
            }
        }, 500L); // runs every 6000 ticks, which is every 300 seconds, which is every 5 minutes.
 }
}

4 个答案:

答案 0 :(得分:3)

你写的东西不起作用的原因是你使用<=。如果有人注销并且没有人离开,则安排任务。如果有人在5分钟或更短时间内重新登录并保持联机状态,则当计划任务检查服务器是否应关闭时,1 <= 1true,以便服务器关闭。

您提到只使用=不起作用,这是因为在布尔语句中,必须使用==来检查是否相等。

尝试使用:

if (playerlist.length == 0) { // if no players are online
    // Do stuff
}

更新(在评论中讨论): 我不太了解Bukkit API,但我认为这是正在发生的事情:在onPlayerQuit()执行后更新在线播放器列表。试试这个:在onPlayerQuit()方法内,尝试检查playerlist.length == 1并在任务内部,检查playerlist.length == 0

答案 1 :(得分:0)

我不知道你是否已经解决了这个问题,但我认为部分问题在于你正在尝试重新初始化已经初始化的最终变量......再次,就像回复中的其他一些变量一样,我不知道Bukkit API,因为我正在尝试学习它,但你不能重新初始化一个最终变量......所以我要么建议拿走最后一部分,要么如果它必须保留,我会为它做一个新的数组run()方法...当你第二次检查是否有人在线时...如果你改变阵列也没关系,因为你正在改变在线玩家的数量,不管怎么说...因为它是最后,当你重新运行玩家列表最终数组的长度时,它总是为1 ...

答案 2 :(得分:0)

当运行中的延迟任务时,您的代码不会刷新playerlist变量,在实际运行任务时从不检测某人是否已加入。

更好的代码实现是:

@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
    Player player = event.getPlayer();
    boolean playersOnServer = false;
    for(Player p : getServer().getOnlinePlayers()) {
        if(p==player) continue;
        playersOnServer = true;
        break;
    }
    if (!playersOnServer) {
        getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable(){
            public void run(){
                //Redo players check
                boolean playersOnServer = false;
                for(Player p : getServer().getOnlinePlayers()) {
                    playersOnServer = true;
                    break;
                }
                if(!playersOnServer){
                    getServer().shutdown();
                }
            }
        }, 6000L);
    }
}

在上面的代码中,我使用了for循环而不是简单的检查,以查看是否有任何在线玩家,使其与旧bukkit中的旧播放器数组一起使用,以及来自新bukkit的新收集方法

这种检测仍有其缺陷,例如,如果最后一个人退出,然后直接加入,然后在再次离开之前等待4分59秒,它将在他离开时直接关闭服务器。

答案 3 :(得分:-1)

当有人重新登录时,您永远不会取消任务。由于您永远不会取消任务,即使有人在5米时间范围内重新登录,它也会执行。