[UNSOLVED/BUG] Chunk regeneration not working correctly

Discussion in 'Plugin Development' started by Seadragon91, Jun 12, 2014.

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

    Seadragon91

    Hello,

    I have played around with chunk regeneration and I found out that there is a problem with the chunk refreshing method.

    I simplified the problem to that few lines
    Code:
    Chunk chunk = player.getLocation().getChunk();
    player.getLocation().getWorld().regenerateChunk(chunk.getX(), chunk.getZ());
    player.getLocation().getWorld().refreshChunk(chunk.getX(), chunk.getZ());
    The method refreshChunk doesn't work on my side. Tested it with other players.
    Problems that occurs:
    • very big lags in that chunk
    • minecraft client gets crashed
    Only solution that I know (at the moment) is: Client needs to disconnecting and reconnecting, if the client not already has crashed...
    Questions:
    Alternative solution around? Is there any craftbukkit code around that can be used to send the players the chunks that need to be refreshed?
    Other solutions? Did I forgot any line of code or are there known problems with chunk refreshing?
    Ty very much,
    Seadragon91

    Edit: Changed first line of code.
     
  2. You can also just get all the blocks that the chunk would have changed by regenerating and use world.getBlockAt(loc).setType(material);

    Or unload the chunk first and then load it again. Or instead of refresh just reload the chunk.
     
  3. Offline

    Seadragon91


    Well. I change more than 1 chunk and that are many blocks, replacing all the blocks trough air, would freeze the main thread for around a few seconds. That's a very bad idea.

    Edit: And yes I played around with unloading and loading the chunk again, that don't fix that problem.
     
  4. Well than I don't know what's the problem, I do know how to create a world generator (I'm working on one right now for a plugin I'm creating). Have you searched the Internet for other people that have the same problems or similar problems?
     
  5. Offline

    xTigerRebornx

    Seadragon91 When you say "big lag in that chunk", what do you mean by lag? And, when you say the client crashed, what type of crash is it? A crash with a stacktrace, or something else?
     
  6. Offline

    Seadragon91

    xTigerRebornx
    I get this messages on the client side
    Code:
    [22:52:47 INFO]: Client> [22:52:47] [Client thread/INFO]: Warning: Clientside chunk ticking took 5617 ms
    [22:53:15 INFO]: Client> [22:53:15] [Client thread/INFO]: Warning: Clientside chunk ticking took 3697 ms
    [22:53:18 INFO]: Client> [22:53:18] [Client thread/INFO]: Warning: Clientside chunk ticking took 3595 ms
    [22:53:28 INFO]: Client> [22:53:28] [Client thread/INFO]: Warning: Clientside chunk ticking took 5707 ms
    [22:53:33 INFO]: Client> [22:53:33] [Client thread/INFO]: Warning: Clientside chunk ticking took 3999 ms
    [22:53:37 INFO]: Client> [22:53:37] [Client thread/INFO]: Warning: Clientside chunk ticking took 2067 ms
    
    That let the client freezes and sometimes it crashes.

    My problem is that the method refreshChunk don't works as expected.
    It should resend the chunk to all clients, but It doesn't do that...

    Found know that minecraft server code and that works
    Code:
    Chunk chunk = player.getLocation().getChunk();
    player.getLocation().getWorld().regenerateChunk(chunk.getX(), chunk.getZ());
     
    List<Chunk> chunks = new ArrayList<Chunk>();
    chunks.add(player.getLocation().getChunk());
     
    int diffx, diffz;
    int view = Bukkit.getServer().getViewDistance() << 4;
    for (Chunk chunk : chunks) {
        net.minecraft.server.v1_7_R3.World world = ((CraftChunk) chunk).getHandle().world;
        for (EntityPlayer ep : (List<EntityPlayer>) world.players) {
            diffx = (int) Math.abs((int) ep.locX - chunk.getX() << 4);
            diffz = (int) Math.abs((int) ep.locZ - chunk.getZ() << 4);
            if (diffx <= view && diffz <= view) {
                ep.chunkCoordIntPairQueue.add(new ChunkCoordIntPair(chunk.getX(), chunk.getZ()));
            }
        }
    }
    The bukkit method refreshChunk should do the same like that code, if I read the correctly. But nothing happens.

    bump

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

    Seadragon91

    Updated:

    Added code that demonstrates that problem. You would need to create the project and compile the jar yourself.
    Create a fresh server for testing it.
    Link to code: http://pastebin.com/ehBXuGsc

    plugin.yml
    Code:
    name: ChunkTesting
    main: de.seadragon91.chunktesting.ChunkTesting
    version: 0.0.1
     
    commands:
      chunktesting:
        usage: /chunktesting
    Edit: Added content of plugin.yml

    Update:

    I have played around with the code and found out that the method refreshChunk() doesn't work for a air world.
    The player don't get an chunk update and then the chunk doesn't "exist" on the client side. This can cause lags or sometimes a crash.

    The nms code from 2 posts before works fine, it sends to all players in the world the chunk and then the chunk reappears on the client side.

    Workarounds:
    • using the nms code, would require a reflection class because of the version numbering
    • change a block in the regenerated chunk to a non-air block sends the player the chunk update and replacing it back later to air

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

    Seadragon91

  9. Offline

    Seadragon91

  10. Offline

    xTrollxDudex

  11. Offline

    Seadragon91

    xTrollxDudex
    If you mean the dark, yes you could think it's not lighted. But it is a not loaded chunk.
    I wasn't able to load this chunk with bukkit code, only nms code works fine.

    Demonstration code: http://pastebin.com/ehBXuGsc
     
  12. Offline

    Seadragon91

  13. Offline

    Seadragon91

    Issue ticket: https://bukkit.atlassian.net/browse/BUKKIT-5656

    I wasn't able to find any way to fix the bug that's the method regeneratingChunk() is causing.
    Now I use nms code to fix that. The problem is of the version numbering, I would need to have this code as reflection.

    Code:
    for (Chunk chunk : chunks) {
            World nmsWorld = ((CraftChunk) chunk).getHandle().world;
            for (EntityPlayer ep : (List<EntityPlayer>) nmsWorld.players) {
                    ep.chunkCoordIntPairQueue.add(new ChunkCoordIntPair(chunk.getX(), chunk.getZ()));
            }
    }
    I only need to have the lines in the for loop as reflection and I have never worked much with reflection.

    Can anyone of you "translate" me that few lines as reflection?
     
Thread Status:
Not open for further replies.

Share This Page