[Bukkit Bug?] unloadWorld fails sporadically

Discussion in 'Plugin Development' started by dreadiscool, Jun 24, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    dreadiscool

    Hey guys,

    I came across an interesting glitch with Bukkit [at least I think it is!] that I'm not able to solve.

    In order to create a resettable arena, I have world saving set to disabled, and when I need to reset the map, I unload the world and then reload it. However, once in a while, there is a chance that the world does not unload, and I'm pulling my hair out trying to figure out why.

    Here is my reset code

    Show Spoiler
    Code:
            // Teleport everyone to spawn
            Player[] players = Bukkit.getOnlinePlayers();
            for (int i = 0; i < players.length; i++) {
                players[i].teleport(Bukkit.getWorld("world").getSpawnLocation());
            }
     
            // Unload the world
            List<Player> worldPlayers1 = Bukkit.getWorld("Bridge").getPlayers();
            for (Player p : worldPlayers1) {
                p.kickPlayer("Internal Server Error code 1");
            }
            if (Bukkit.unloadWorld(Bukkit.getWorld("Bridge"), false)) {
                System.out.println("[Bridge] Unloaded world");
            }
            else {
                System.out.println("[Bridge] FAILED TO UNLOAD WORLD OH NOES");
                if (Bukkit.getWorld("Bridge") == null) {
                    System.out.println("WORLD WAS NULL NOOOO");
                }
                List<Player> worldPlayers = Bukkit.getWorld("Bridge").getPlayers();
                if (worldPlayers.size() > 0) {
                    System.out.println("THERE WERE PLAYERS GAH");
                    StringBuilder sbp = new StringBuilder();
                    for (Player p : worldPlayers) {
                        sbp.append(p.getName() + ", ");
                    }
                    sbp.setLength(sbp.length() - 2);
                    System.out.println(sbp.toString());
                }
            }
     
            // Load the world
            Bukkit.createWorld(new WorldCreator("Bridge"));
            Bukkit.getWorld("Bridge").setAutoSave(false);
    


    I also kick players with Internal Server Error code 1, because apparently, even after I teleport players out of the world, sometimes, there is 1 or 2 people still in the world [so i have to kick them]

    However, there is a chance that even after this, the world still does not unload. Any help?

    Thanks in advance!
    - dreadiscool
     
  2. Offline

    TomFromCollege

    Well I can't give you code, but perhaps I can point you in the right direction...
    I remember having the same issues, I had to manually unbind the regionfile cache
     
  3. Offline

    dreadiscool


    Would you mind sharing :3

    Bump, this problem is still trolling at large

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 2, 2016
  4. Offline

    TomFromCollege

  5. Offline

    dreadiscool

    TomFromCollege

    I don't see what they are doing differently compared to my code. This bug is still at large

    This is still a problem at large :3

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 2, 2016
  6. Offline

    skipperguy12

    I made this method a long time ago:
    http://forums.bukkit.org/threads/map-rollback-method-very-simple.132155/

    And it works like yours, but people were also telling me if wasn't working, with the same problem as you. Because of that, I released this:
    Removed

    Take a look at it, it uses apache commons-io FileUtils to copy the file to a temporary directory, then you can simply teleport everyone out, and delete the file. It's better, because there is no real "rollback" to be done.
     
    dark navi likes this.
  7. Offline

    dreadiscool

    skipperguy12 Thanks, but this method will still fail if the unloadWorld() method fails, because Java has file locks on the files in the temp directories, preventing it from being deleted. Even if your force delete it, you would be wrecking the server apart since the server relies on being able to access those files at all times.

    An alternative solution would be to create a new random folder each time, but that also isn't ideal.
     
  8. Offline

    skipperguy12

    dreadiscool
    Huh? It works fine for me :p
    You just need to be careful, make sure to teleport everyone out of there, and don't use unload world. Just delete the temporary directory, Java will not prevent you from doing this.
     
  9. Offline

    dreadiscool

    skipperguy12 I understand, but this problem does not occur all the time and only happens on production servers. I do indeed teleport everyone outside, as is shown in my code example. There is also a bug where sometimes, 1 - 2 players do not get teleported out (why? I don't know) so I have to kick those players as well (as shown in my code). However, sometimes, even when the world has no players, unloading fails.

    And yes, while you can delete the directories even if the world is still running, doing so would be disastrous. The memory leaks would be over 9001
     
  10. Offline

    skipperguy12

    dreadiscool
    Restart the server after ~40 times. Not reload, like actual restart from a script (PM me if you need one :p).

    As for the 1-2 players who don't get teleported, that's really strange. Just add a 2 second delay between teleporting people out of the map and unloading the world.
     
  11. Offline

    dreadiscool

    skipperguy12 I end up just kicking the players who are still "in the world" even after I teleport them out, because I don't want to wait even a single tick before teleporting them back (otherwise the players see my temporary world, which I don't want).

    As for the restart script, thanks for your offer but I use spigot, which has restarting built in. I could try that, but I wouldn't want to disconnect all my players. I suppose I could do some hackery to make BungeeCord teleport them back in, but it would be a lot simpler if Bukkit would just fix this bug :p
     
  12. Offline

    dreadiscool

    This problem is still a problem :(
     
Thread Status:
Not open for further replies.

Share This Page