NullPointerException

Discussion in 'Plugin Development' started by woox2k, Feb 5, 2011.

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

    woox2k

    It's my first post, so Hello!
    I have problem with very simple plugin, it should remove any block with single left click and put that block into inventory
    Code:
        public void onBlockDamage (BlockDamageEvent event) {
            Player player = event.getPlayer();
            if (player.isPlayer() == true) {
                Block block = event.getBlock();
                int test = block.getTypeId();
                ItemStack remblock = new ItemStack(test,1);
                //------
                try {
                    player.getInventory().addItem(remblock);
                }
                catch (NullPointerException e){
                    player.sendMessage("NPE!");
                }
                block.setTypeId(0);
            }
        }
    it all almost works (plugin gets called, block is removed and given into inventory) but it randomly throws NullpointerException into console.
    try-catch is there just to test out when exactly it throws it (easier than looking into the console)

    Also it looks like plugin is called when i release left mouse button, if i keep holding it then it breaks block normally (and because of that i cannot remove multiple blocks with single click by moving mouse or myself around) <- that's all okay for me
    But it starts to throw NPE then this don't work anymore and i can just keep holding mouse button and all blocks get replaced with 0 (seems like bukkit constantly calls for my plugin)

    I'm just a beginner in java so there may be some silly errors in code that causes this problem.

    I hope someone can help me with this!
     
  2. Offline

    Redecouverte

    Code:
     public void onBlockDamage (BlockDamageEvent event) {
               Player player = event.getPlayer();
    
                Block block = event.getBlock();
                Material mat = block.getType();
    
                ItemStack remblock = new ItemStack(mat,1);
    
                try {
                    if(player.getInventory() != null)
                        player.getInventory().addItem(remblock);
                }
                catch (NullPointerException e){
                    player.sendMessage("NPE!");
                }
                block.setType(Material.AIR);
    
               event.setCancelled(true);
    
        }
    
    
    - block ids do not always match their item ids, if you use Material it should work (i guess)

    - if you remove the block it would be better to cancel the event

    - if (player.isPlayer() == true) is not required, as that will always be true
     
  3. Offline

    woox2k

    can you say why is that so?


    and i'll use other suggestions. Thanks!

    Edit: wait someone said earlier in IRC that when mobs are doing damage to blocks, my plugin gets called too and player == null then, is that right?
     
  4. Offline

    Redecouverte

    updated :)
    --- merged: Feb 5, 2011 11:21 AM ---
    that would be weird, because mobs are not instances of Player but of other Entity classes, so i do not think this event is called for mobs,*ill check that right now*

    update:
    that's the code craftbukkit uses:
    Code:
      public boolean isPlayer() {
        return true;
      }
    
    -> you can safely remove it :),
    also this event is currently called only for players, not mobs
     
  5. Offline

    woox2k

    There seems to be no MaterialID (or i'm doing something wrong) also if block ID is not item ID, then logically give block should not work at all (but it does)

    Also offtopic question: is there an event when player places a block and it gets removed from inventory (i would like to cancel that removing part to give players unlimited blocks)

    Edit: I removed "if player" and thanks for that but it doesn't solve problem, what is logical because it didn't do anything
    Cancelling event after my code did not solve it either :(
     
  6. Offline

    Redecouverte

    - it's called Material, use import org.bukkit.Material;

    - there are item's that cannot be used as blocks, but it should work the other way round, yes

    - if you cancel the place event and place the block manually (setType() and setData() to the block) it should work, or don't cancel it and just add the item back to the inventory
    --- merged: Feb 5, 2011 11:34 AM ---
    you could use:

    Code:
                catch (NullPointerException e) {
                      e.printStackTrace();
                     player.sendMessage("NPE!");
    }
    and post the stack trace here


    and also check if(player != null)
     
  7. Offline

    woox2k

    Code:
    java.lang.NullPointerException
            at org.bukkit.craftbukkit.inventory.CraftItemStack.getMaxStackSize(Craft
    ItemStack.java:124)
            at org.bukkit.craftbukkit.inventory.CraftInventory.firstPartial(CraftInv
    entory.java:170)
            at org.bukkit.craftbukkit.inventory.CraftInventory.addItem(CraftInventor
    y.java:198)
            at com.bukkit.woox2k.CreativeMode.CreativeModeBlockListener.onBlockDamag
    e(CreativeModeBlockListener.java:34)
            at org.bukkit.plugin.java.JavaPluginLoader$18.execute(JavaPluginLoader.j
    ava:210)
            at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.jav
    a:60)
            at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.j
    ava:213)
            at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:355)
            at net.minecraft.server.Packet14BlockDig.a(SourceFile:42)
            at net.minecraft.server.NetworkManager.a(SourceFile:232)
            at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:71)
            at net.minecraft.server.NetworkListenThread.a(SourceFile:104)
            at net.minecraft.server.MinecraftServer.h(MinecraftServer.java:283)
            at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:209)
            at net.minecraft.server.ThreadServerApplication.run(SourceFile:512)
    java.lang.NullPointerException
            at org.bukkit.craftbukkit.inventory.CraftItemStack.getMaxStackSize(Craft
    ItemStack.java:124)
            at org.bukkit.craftbukkit.inventory.CraftInventory.firstPartial(CraftInv
    entory.java:170)
            at org.bukkit.craftbukkit.inventory.CraftInventory.addItem(CraftInventor
    y.java:198)
            at com.bukkit.woox2k.CreativeMode.CreativeModeBlockListener.onBlockDamag
    e(CreativeModeBlockListener.java:34)
            at org.bukkit.plugin.java.JavaPluginLoader$18.execute(JavaPluginLoader.j
    ava:210)
            at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.jav
    a:60)
            at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.j
    ava:213)
            at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:339)
            at net.minecraft.server.Packet14BlockDig.a(SourceFile:42)
            at net.minecraft.server.NetworkManager.a(SourceFile:232)
            at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:71)
            at net.minecraft.server.NetworkListenThread.a(SourceFile:104)
            at net.minecraft.server.MinecraftServer.h(MinecraftServer.java:283)
            at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:209)
            at net.minecraft.server.ThreadServerApplication.run(SourceFile:512)
    i'll try that player != null but again if player is null then i should not get anything into my inv but still it works, even when it throws NPE
     
  8. Offline

    Redecouverte

    thanks, the cause of this error is: the item id is invalid

    did you already try it with material instead of id?

    and for what blocks does it crash? (maybe log the material/id)
     
  9. Offline

    woox2k

    yeah still no luck... i have material imported but i cannot find how to get it :/
    sorry i'm being so dumb but can you give me exact thing that outputs that block materialID?
     
  10. Offline

    Redecouverte

    it's
    block.getType()

    but it most likely wont fix the issue, i guess the best thing would be to log the material type and/or the ids and check for which it is crashing
     
  11. Offline

    woox2k

    yea i tried that earlier too... (i thought there is another thing that outputs correct ID, that's why i got confused) now it wont give me any blocks so i guess now ID is really wrong (i get only NPE)

    Edit: i messed around with it and it seems for some odd reason it got id right 2 times (i played and randomly clicking blocks... now i have 1 water and 1 stone block in my inv. That makes no sense for me :/ (water is most interesting because i thought there's no way to "click" water, usually it's like air... you touch block behind it)
     
  12. Offline

    Redecouverte

    ill debug it :)
    --- merged: Feb 5, 2011 11:58 AM ---
    fixed!
    Code:
                Block block = event.getBlock();
                Material mat = block.getType();
    
                if (mat != Material.AIR) {
                    Player player = event.getPlayer();
                    ItemStack remblock = new ItemStack(mat, 1);
                    player.getInventory().addItem(remblock);
                    block.setType(Material.AIR);
                    event.setCancelled(true);
                }
    
    if you click a block it fires around 4 events, 1 for the actual block and about 3 others with Type set to Material.Air
     
  13. Offline

    woox2k

    it looks like it's fine now Thanks for helping!
    but can you say why is this better? is there some bugs in bukkit or why ID won't work? :/ (then i know what to avoid in future and personally i like ID-s more)
     
  14. Offline

    Redecouverte

    you can also use IDs, it will be all the same, you just cannot add an air block to the inventory, thats the problem
     
  15. Offline

    woox2k

    okay thanks, it makes sense too :D
     
Thread Status:
Not open for further replies.

Share This Page