简体   繁体   中英

Why isn't “<= 1” working as expected?

I have the following code

@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.
 }
}

Which when a player leaves, it checks to see if he was the last one on, if he was, then it after 5 minutes, it checks again, and if still no one is on its supposed to stop the server.

In this line here:

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

I HAVE to have it as <=1 or it doesnt work at all, but it will also stop the server if I leave, and join back and im the only one on. When I had it at =0 and just <1 it didnt work.

Any ideas?

Here is my update code (Still doesnt work):

 @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.
 }
}

The reason why what you have written does not work is your use of <= . If someone logs off and no one is left, the task is scheduled. If someone logs back on within 5 minuets or less and remains online, when the scheduled task checks to see if the server should be shutdown, 1 <= 1 is true so the server shuts down.

You mentioned that just using = did not work, this is because in boolean statements, == must be used to check for equality.

Try using this:

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

Update (Discussed in comments): I do not know the Bukkit API very well, but this is what I assume is happening then: The online player list is updated after onPlayerQuit() is executed. Try this: Inside of your onPlayerQuit() method, try checking playerlist.length == 1 and inside of your task, check playerlist.length == 0

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

You code doesn't refresh the playerlist variable when the delayed task in run, never detecting if someone has joined when the task is actually run.

A better implementation of the code would be:

@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);
    }
}

Inside the above code, I used a for loop instead of a simple check to see if there are any players online, to make it work with the old player array from the old bukkit, and the new collections method from the new bukkit.

This kind of detection still has its bugs, for example if the last person quits, then directly joins, and then waits 4 minutes and 59 seconds before leaving again, it will shut down the server directly when he has left.

You never cancel the task when someone logs back on. Since you never cancel the task it will execute even if someone logs back on within the 5m time frame.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM