0

我有以下代码

@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 分钟后,它会再次检查,如果仍然没有人在它应该停止服务器。

在此行中:

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

我必须将它设置为 <=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

4 回答 4

2

您所写的内容不起作用的原因是您使用<=. 如果有人注销并且没有人离开,则计划任务。如果有人在 5 分钟或更短的时间内重新登录并保持在线,当计划任务检查服务器是否应该关闭时,1 <= 1服务器true就会关闭。

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

尝试使用这个:

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

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

于 2012-04-23T18:47:25.640 回答
0

我不知道你是否已经解决了这个问题,但我认为问题的一部分是你试图重新初始化一个已经初始化的最终变量......再次,就像回复中的其他一些人一样,我没有知道 Bukkit API,因为我正在尝试学习它,但是您无法重新初始化最终变量...所以我建议删除最后一部分,或者如果它必须保留,我会为运行创建一个新数组( ) 方法...当您第二次检查是否有人在线时...如果您更改数组也没关系,因为您可能正在更改在线玩家的数量...因为它是最终的,它当您重新运行播放器列表的最终数组的长度时,将始终为 1...

于 2012-07-01T04:14:30.027 回答
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 中的新集合方法一起使用。

这种检测还是有BUG的,比如最后一个人退出,直接加入,等4分59秒再离开,离开后直接关闭服务器。

于 2016-01-07T09:22:59.533 回答
-1

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

于 2012-04-23T18:40:36.097 回答