NPE on ChunkLoadEvent with getTileEntites()

Discussion in 'Plugin Development' started by Digi, Mar 11, 2012.

Thread Status:
Not open for further replies.
  1. People reported this error with my RecipeManager plugin:
    The code at those lines:
    Code:
    	public void chunkFurnaces(final Chunk chunk, final boolean add)
    	{
    		final BlockState titleEnts[] = chunk.getTileEntities();
    		
    		for(final BlockState ent : titleEnts)
    		{
    			if(ent != null && ent instanceof Furnace)
    			{
    				if(add)
    					RecipeManager.burningFurnacesList.put(ent.getBlock().getLocation(), (double)0);
    				else
    					RecipeManager.burningFurnacesList.remove(ent.getBlock().getLocation());
    			}
    		}
    	}
    And all the events that call chunkFurnaces():
    Code:
    	@EventHandler(priority = EventPriority.MONITOR)
    	public void onChunkLoad(final ChunkLoadEvent event)
    	{ // this was the event that triggered the method which had the error triggered
    		if(!event.isNewChunk())
    			chunkFurnaces(event.getChunk(), true);
    	}
    	
    	@EventHandler(priority = EventPriority.MONITOR)
    	public void onChunkUnload(final ChunkUnloadEvent event)
    	{
    		chunkFurnaces(event.getChunk(), false);
    	}
    	// I suspect is this one...
    	public void worldLoad(final World world)
    	{
    		final Chunk chunks[] = world.getLoadedChunks();
    		
    		for(final Chunk chunk : chunks)
    			chunkFurnaces(chunk, true);
    	}

    EDIT: I think the chunk variable was NULL when it was get by event.getChunk(), but why ? Did I need to use .clone() or wtf ?

    EDIT#2: would cancelling the event by other plugin make event.getChunk() return null in my plugin ? because that would explain it...
     
  2. Here it triggered again on someone: http://pastie.org/3630594

    What I can get from that is the error is inside bukkit's getTileEntities() code, not my code...

    From CraftChunk class:
    Code:
    public BlockState[] getTileEntities() {
            int index = 0;
            net.minecraft.server.Chunk chunk = getHandle();
            BlockState[] entities = new BlockState[chunk.tileEntities.size()];
    
            for (Object obj : chunk.tileEntities.keySet().toArray()) {
                if (!(obj instanceof ChunkPosition)) {
                    continue;
                }
    
                ChunkPosition position = (ChunkPosition) obj;
    
                // Line where the error points to:
                entities[index++] = worldServer.getWorld().getBlockAt(position.x + (chunk.x << 4), position.y, position.z + (chunk.z << 4)).getState();
            }
            return entities;
        }
    CraftBlock returns new CraftSign instance and at CraftSign line 17 there's:
    Code:
        public CraftSign(final Block block) {
            super(block);
    
            CraftWorld world = (CraftWorld) block.getWorld();
            sign = (TileEntitySign) world.getTileEntityAt(getX(), getY(), getZ());
            lines = new String[sign.lines.length]; // <<< line 17
            System.arraycopy(sign.lines, 0, lines, 0, lines.length);
        }
    Anyone got a clue what is this error about ?
     
  3. Offline

    bleachisback

    Something tells me that chunk.getTileEntities() is returning null, and you're not checking for it. Then, when your for loop runs, it's shooting off the error.
     
  4. Well it doesn't return null because it returns the array it created, look at it's code.

    And the more annoying part is that I can't replicate the error, if I could I would've tried stuff myself :/
     
  5. Update on this, it seems it also causes placing duplicate blocks after teleporting in nether, but if you reconnect it's fine...
    I even replaced the code with this:
    Code:
    		Block block;
    		
    		for(int x = 0; x < 16; x++)
    		{
    			for(int y = 0; y < 16; y++)
    			{
    				for(int z = 0; z < 16; z++)
    				{
    					block = chunk.getBlock(x, y, z);
    					
    					switch(block.getType())
    					{
    						case FURNACE:
    						case BURNING_FURNACE:
    						{
    							if(add)
    								RecipeManager.burningFurnacesList.put(block.getLocation(), (double)0);
    							else
    								RecipeManager.burningFurnacesList.remove(block.getLocation());
    							
    							break;
    						}
    					}
    				}
    			}
    		}
    And the dupe glitch persists, if I comment that code out, the glitch is no more.
    I also tried commenting out only this:
    Code:
    if(add)
    								RecipeManager.burningFurnacesList.put(block.getLocation(), (double)0);
    							else
    								RecipeManager.burningFurnacesList.remove(block.getLocation());
    							
    							break;
    But it seems the glitch still happens without it... so the only code there is block = chunk.getBlock(x, y, z)... I really don't understand what's wrong with that chunk.

    Does anyone have any clue wth are these glitches all about that circle around that on chunk load in nether ?
     
  6. I've isolated the code into a single small plugin to make the infinite block placing in nether after teleporting in nether on survival:

    Show Spoiler
    Code:
    package digi.test;
     
    import org.bukkit.event.*;
    import org.bukkit.event.world.*;
    import org.bukkit.plugin.java.JavaPlugin;
     
    public class Test extends JavaPlugin implements Listener
    {
    @Override
    public void onEnable()
    {
    getServer().getPluginManager().registerEvents(this, this);
    }
     
    @Override
    public void onDisable()
    {
    }
     
    @EventHandler
    public void onChunkLoad(final ChunkLoadEvent event)
    {
    // glitch code 1:
    event.getChunk().getTileEntities();
     
    // glitch code 2:
    // event.getChunk().getBlock(0, 0, 0).getType();
    }
    }

    How to identify the glitch:
    The glitch only works after you teleport to nether using the default portal, if you reconnect in nether or just start the server in nether it won't work.
    Just have a single block, place it and if you placed it succesfully and you still have it, that's the glitch.


    Also, I must specify that I get no errors what so ever, I never did, the errors I posted were from other people that experiecend them but I can't replicate them, which triggers on the same code that this glitch occurs, however this glitch is worse since it can enable people to duplicate blocks.

    So, can anyone tell me why the hell does it act like this ?

    md_5TheYeti
    Sorry to tag you guys but it seems nobody else knows anything about this.
    EDIT by md_5: Remove extra tags
    EDIT: Used CB 1.1 R8 server and compiled against as well.
     
Thread Status:
Not open for further replies.

Share This Page