onChunkUnload

Discussion in 'Plugin Development' started by eisental, Feb 3, 2011.

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

    eisental

    I've been working on making my plugin chunk load/unload "compatible" in the past few days and I'm trying to get a console message whenever a chunk is loaded or unloaded. This works fine for onChunkLoaded, but onChunkUnloaded never gets called.

    I test it by warping between 2 distant points (using MyWarp). Everytime I jump to one warp point the relevant chunks get loaded, but they never get unloaded.

    So, is there something wrong with onChunkUnloaded?

    The is my world listener:
    Code:
    rcWorldListener = new WorldListener() {
    
                @Override
                public void onChunkLoaded(ChunkLoadEvent event) {
                    System.out.println("Chunk loaded: " + event.getChunk());
                }
    
                @Override
                public void onChunkUnloaded(ChunkUnloadEvent event) {
                    System.out.println("Chunk unloaded: " + event.getChunk());
                }
            };
    
    and of course:
    Code:
            pm.registerEvent(Type.CHUNK_LOADED, rcWorldListener, Priority.Monitor, this);
            pm.registerEvent(Type.CHUNK_UNLOADED, rcWorldListener, Priority.Monitor, this);
    
    in onEnable()
     
  2. Offline

    Raphfrk

    I had a look at the source and this is the chunk code.

    The list of all loaded chunks is stored in
    this.e

    Line 208 has: this.e.remove(chunkcoordinates);

    In that block, you would need something like


    Making it cancel is a little difficult. Ideally, the whole for loop would be adjusted.

    At the moment, it removes the first chunk in the "can be unloaded" set. If you block that, when it tries again, it will still try the same chunk.

    Something like change:

    Code:
    ChunkCoordinates chunkcoordinates = (ChunkCoordinates) this.a.iterator().next();
    
    to

    Code:
    Iterator itr = this.a.iterator();
    ChunkCoordinates chunkcoordinates = null;
    while(itr.hasNext() && chunkcoordinates == null) {
        chunkcoordinates = (ChunkCoordinates)itr.next();
        ChunkUnloadEvent chunkUnloadEvent = new ChunkUnLoadEvent(Type.CHUNK_UNLOADED, this.e.get(chunkcoordinates));
        server.getPluginManager().callEvent(Type.CHUNK_UNLOADED, chunkUnloadEvent);
        if(chunkUnloadEvent.isCancelled()) {
            chunkcoordinates = null;
        }
    if(chunkcoordinates==null) {
        continue;
    }
    
    This is a little inefficient though. If the first chunk in the can be unloaded Set is protected, then it will be hit every time.

    Ideally, what you want is a get a randomly ordered keySet :).

    Hmm, anyway, in conclusion :), the hook isn't present yet.
     
  3. Offline

    eisental

    Ok, thanks.
    Good to know...

    I don't really need to know when it's unloaded, just wondered what's going on.

    Btw, how come ChunkCoordinates is a CraftBukkit class? I had to duplicate it in order to keep track of my circuits chunks. Shouldn't it go into Bukkit?
     
  4. Offline

    Raphfrk

    No idea :).

    I think you are supposed to just use the Chunk class, since that includes stuff like which world it is from etc.

    What are you using ChunkCoordinates for?
     
  5. Offline

    eisental

    I'm using it as a HashMap key. I want to do chunkLookup.get(chunkCoords) and get a List<Circuit> of all the circuits in that chunk. I think that using the Chunk object as a key would cause problems when the chunk is loaded/unloaded.

    It's not really a problem to create a class with two ints, a World object, and an equals() method but other plugins would also probably find it useful at some point.
     
  6. Offline

    Raphfrk

    The CraftChunk object does contain a block cache and a reference to the minecraft chunk object. If you add it to as a key for a hashmap, it wouldn't be able to unload that data.

    Also, they don't seem to implement hashcodes anyway.

    Interestingly, if you do have a reference to a CraftChunk, it would prevent it being unloaded.
     
  7. Offline

    eisental

    Well, that would be a VERY simple way to prevent chunk unload... :)

    You could still use an object without equals() and hashCode() implementations as a key, though, if it simply stays in the same place in memory for the whole time the application is running (i.e. if key==someObj is true). I actually used Block objects as keys until I discovered today that new Block objects are created when the chunk is reloaded. Very flawed but it worked fine until I started to move around the map.
     
  8. Offline

    Raphfrk

    I mean it won't free the memory. I don't think you would still be able to actually use it.

    You would have a reference to the chunk data, but the server wouldn't.

    Well, I think that the Block object should refer to a block location, not to a block :). However, there are pluses and minuses.
     
  9. Offline

    smokesjackson

    [SEVERE] CHUNK_UNLOAD loading Minecart Mania Core v1.05 (Is it up to date?)
    java.lang.NoSuchFieldError: CHUNK_UNLOAD
    at com.afforess.minecartmaniacore.MinecartManiaCore.onEnable(MinecartManiaCore.java:51)
    at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:118)
    at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:451)
    at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:217)
    at org.bukkit.craftbukkit.CraftServer.loadPlugin(CraftServer.java:92)
    at org.bukkit.craftbukkit.CraftServer.loadPlugins(CraftServer.java:70)
    at net.minecraft.server.MinecraftServer.e(MinecraftServer.java:204)
    at net.minecraft.server.MinecraftServer.a(MinecraftServer.java:191)
    at net.minecraft.server.MinecraftServer.d(MinecraftServer.java:131)
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:246)
    at net.minecraft.server.ThreadServerApplication.run(SourceFile:366)
     
Thread Status:
Not open for further replies.

Share This Page