[Solved]Plugin unable to load, error with String + listener in main?

Discussion in 'Plugin Development' started by CRAZYxMUNK3Y, Feb 26, 2012.

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

    CRAZYxMUNK3Y

    I have started working on config files lately, with my latest being the player being damaged when breaking a block.

    Here is my code (the whole class) and here is the commit (the bits i added for the damage and config) of my plugin.
    Fixed the missing ";" on line 57

    When i break a glass block, it doesn't matter what the number is in the config (in either option), it breaks as usual, but doesn't damage the player.

    When i break a thin glass (glass pane), the player is always damaged, and a full stack is dropped, not just the one.

    What have i done wrong (this time, lol)?

    Thanks
     
  2. Some things I saw.
    1. Don't use spaces in config keys
    2. Why are you using a for loop?
    3. You missed a few {'s and your indentation was wrong, I've fixed it (see below)
    4. Why are you using two listeners if they do the same thing? (Except one for glass and one for thin_glass)
    5. This line confuses me "if (plugin.GlassDrops.contains(event.getPlayer().getName()));"
      As far as I see this won't do anything.
    Well.. Hope this helps :)

    Code:java
    1. @EventHandler(priority = EventPriority.NORMAL)
    2. public void onBlockBreak(BlockBreakEvent event) {
    3. Block block = event.getBlock();
    4. Player player = event.getPlayer();
    5.  
    6. if (block.getType() == Material.GLASS) {
    7. if (plugin.GlassDrops.contains(event.getPlayer().getName())) {
    8. for (int counter = 1; counter < 100; counter++) {
    9. damageChance = 1 + random.nextInt(100);
    10. if (damageChance <= plugin.getConfig().getInt("Glass Damage.Damage Chance")) {
    11. beforeBreakHealth = player.getHealth();
    12. playerDamage = plugin.getConfig().getInt("Glass Damage.Damage Amount");
    13. player.setHealth(beforeBreakHealth - playerDamage);
    14. }
    15. block.setType(Material.AIR);
    16. block.getWorld().dropItemNaturally(block.getLocation(), new ItemStack(Material.GLASS, 1));
    17. }
    18. }
    19. }
    20. }
    21.  
    22. @EventHandler(priority = EventPriority.NORMAL)
    23. public void BlockBreak(BlockBreakEvent event) {
    24. Block block = event.getBlock();
    25. Player player = event.getPlayer();
    26.  
    27. if (block.getType() == Material.THIN_GLASS) {
    28. for (int counter = 1; counter < 100; counter++) {
    29. damageChance = 1 + random.nextInt(100);
    30. if (damageChance <= plugin.getConfig().getInt("Glass Damage.Damage Chance")) {
    31. beforeBreakHealth = player.getHealth();
    32. playerDamage = plugin.getConfig().getInt("Glass Damage.Damage Amount");
    33. player.setHealth(beforeBreakHealth - playerDamage);
    34. }
    35. if (plugin.GlassDrops.contains(event.getPlayer().getName()));
    36. block.setType(Material.AIR);
    37. block.getWorld().dropItemNaturally(block.getLocation(), new ItemStack(Material.THIN_GLASS, 1));
    38. }
    39. }
    40. }
    41. }
     
  3. Offline

    CRAZYxMUNK3Y

    dadaemon
    I was told by some not to use - or _ and use spaces?!

    I am still learning java, so sometimes i might put the wrong thing in

    Whoops, thanks for that

    It is so they can drop two separate types of glass...

    That is used because i have a command toggle for the glass to be either dropped, or broken.

    Thanks for your reply, will try it and get back to you.
     
  4. you never call player.damage(int)
     
  5. Offline

    stelar7

    should do the same thing...
    but player.damage is easier :p
     
  6. Offline

    CRAZYxMUNK3Y

  7. You initialize your listeners before anything is loaded. Maybe that's why it's giving the error.

    I usually initialize my listeners on te onEnable method after configs etc. are loaded.

    Also, does your config contains the "Worlds.world4" string? Because the error says it's getting a null from that line.
    Code:
    Caused by: java.lang.NullPointerException
    at me.ben.GlassDrops.GlassDropListener.<init>(GlassDropListener.java:26)
    at me.ben.GlassDrops.GlassDrops.<init>(GlassDrops.java:18)
     
  8. Offline

    CRAZYxMUNK3Y

    Yes, my listener are near the bottom of my onEnable so they are loaded last.

    As for the config containing "Worlds.world4", it does contain it (In the main with cfg.addDefault)
     
  9. Nope... Your listeners are initialized when the plugin initializes.

    Code:
    public GlassDropListener glassListener = new GlassDropListener(this);
    public GlassDropsCommands commands = new GlassDropsCommands(this);

    What I do is the following
    Code:
    public GlassDropListener glassListener;
    public GlassDropsCommands commands;
    and place this in the onEnable after the config is set
    Code:
    glassListener = new GlassDropListener(this);
    commands = new GlassDropsCommands(this);
    Edit: Also it is probably better to make the config available from your plugin class by using
    Code:
    config = this.getConfig();
    and then reference that object instead of calling getConfig every time.

    Edit2: Why do you save the config at the start in the onEnable?
     
  10. Offline

    CRAZYxMUNK3Y

    Changed it, get this error
    Code:
    22:26:58 [SEVERE] Error occurred while enabling GlassDrops v1.4 (Is it up to dat
    e?): null
    java.lang.NullPointerException
            at me.ben.GlassDrops.GlassDropListener.<init>(GlassDropListener.java:25)
    
            at me.ben.GlassDrops.GlassDrops.onEnable(GlassDrops.java:43)
            at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:230)
            at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader
    .java:1057)
            at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManage
    r.java:380)
            at org.bukkit.craftbukkit.CraftServer.loadPlugin(CraftServer.java:199)
            at org.bukkit.craftbukkit.CraftServer.enablePlugins(CraftServer.java:182
    )
            at net.minecraft.server.MinecraftServer.t(MinecraftServer.java:357)
            at net.minecraft.server.MinecraftServer.a(MinecraftServer.java:344)
            at net.minecraft.server.MinecraftServer.init(MinecraftServer.java:175)
            at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:408)
            at net.minecraft.server.ThreadServerApplication.run(SourceFile:465)
    
    Here is the main if you want;
    Code:java
    1.  
    2. package me.ben.GlassDrops;
    3.  
    4. import java.util.ArrayList;
    5. import java.util.logging.Logger;
    6.  
    7. import org.bukkit.Bukkit;
    8. import org.bukkit.configuration.file.FileConfiguration;
    9. import org.bukkit.plugin.PluginDescriptionFile;
    10. import org.bukkit.plugin.PluginManager;
    11. import org.bukkit.plugin.java.JavaPlugin;
    12.  
    13. public class GlassDrops extends JavaPlugin {
    14.  
    15. Logger log = Logger.getLogger("Minecraft");
    16.  
    17. public ArrayList<String> droptoggle = new ArrayList<String>();
    18.  
    19. public GlassDropsCommands commands;
    20. public GlassDropListener listener;
    21.  
    22.  
    23. public void onEnable() {
    24.  
    25. saveConfig();
    26. FileConfiguration cfg = getConfig();
    27. cfg.options().header("Glass Drops Config File");
    28. cfg.addDefault("Message.Message", "You are not allowed to drop glass in the world!");
    29. cfg.addDefault("Message.Color", "RED");
    30. cfg.addDefault("Worlds.world", "world");
    31. cfg.addDefault("Worlds.nether", "world_nether");
    32. cfg.addDefault("Worlds.world3", "world_the_end");
    33. cfg.addDefault("Worlds.world4", "world4");
    34. cfg.addDefault("Worlds.world5", "world5");
    35. cfg.addDefault("Glass-Damage.Damage-Chance", Integer.valueOf(1));
    36. cfg.addDefault("Glass-Damage.Damage-Amount", Integer.valueOf(1));
    37. cfg.addDefault("Glass-Drops.Drop-Chance", Integer.valueOf(100));
    38. cfg.addDefault("Blocks-Dropped.Glass", Boolean.valueOf(true));
    39. cfg.addDefault("Blocks-Dropped.Glass-Panes", Boolean.valueOf(true));
    40. cfg.options().copyDefaults(true);
    41. saveConfig();
    42.  
    43. commands = new GlassDropsCommands(this);
    44. listener = new GlassDropListener(this);
    45. getCommand("gd").setExecutor(commands);
    46. getCommand("ngd").setExecutor(commands);
    47. PluginManager pm = Bukkit.getServer().getPluginManager();
    48. pm.registerEvents(this.commands, this);
    49. pm.registerEvents(this.listener, this);
    50. PluginDescriptionFile pdf = this.getDescription();
    51. log.info(pdf.getName() + " has been enabled with version " + pdf.getVersion());
    52. }
    53.  
    54. public void onDisable() {
    55. PluginDescriptionFile pdf = this.getDescription();
    56. log.info(pdf.getName() + " has been disabled");
    57. }
    58. }
    59.  

    and the error on line 25 in the listener;
    Code:java
    1.  
    2. String world1 = plugin.getConfig().getString("Worlds.world");
    3.  
     
  11. Try the following for your listener:
    Code:java
    1. private GlassDrops plugin;
    2. Random chance = new Random();
    3.  
    4. String world1;
    5. String nether;
    6. String world3;
    7. String world4;
    8. String world5;
    9. String message;
    10. String colour;
    11. int damChance;
    12. int damAmount;
    13. int dropChance;
    14. boolean glass;
    15. boolean glassPanes;
    16.  
    17. public GlassDropListener(GlassDrops instance) {
    18. plugin = instance;
    19.  
    20. FileConfiguration config = plugin.getConfig();
    21. if(config == null) {
    22. System.out.print("Why is config null?");
    23. return;
    24. }
    25.  
    26. world1 = config.getString("Worlds.world");
    27. nether = config.getString("Worlds.nether");
    28. world3 = config.getString("Worlds.world3");
    29. world4 = config.getString("Worlds.world4");
    30. world5 = config.getString("Worlds.world5");
    31. message = config.getString("Message.Message");
    32. colour = config.getString("Message.Colour");
    33. damChance = config.getInt("Glass-Damage.Damage-Chance");
    34. damAmount = config.getInt("Glass-Damage.Damage-Amount");
    35. dropChance = config.getInt("Glass-Drops.Drop-Chance");
    36. glass = config.getBoolean("Blocks-Dropped.Glass");
    37. glassPanes = config.getBoolean("Blocks-Dropped.Glass-Panes");
    38. }

    What does it do then?
     
  12. Offline

    CRAZYxMUNK3Y

    dadaemon
    It worked! Thanks, is it the way assigned the config Strings/int/booleans?
     
  13. It's probably because when your initializing the listener it goes through all your global objects first. And after that it will use the constructor.

    But because your referencing "plugin" while the constructor hasn't been run yet. "plugin" will be null.

    Hope you understand what I try to say :D

    Edit: The whole "config = plugin.getConfig()" is therefor not needed. But it will clean up your code a little bit :) Just initialize the objects inside the constructor if your referencing objects that aren't set.
     
  14. Offline

    CRAZYxMUNK3Y

    Ahk, thanks for that.

    But... (So sorry!)(Don't need to respond if you don't want to)

    A) Even when the config is set to false, it still drops
    B) I am always being damaged, even if damage chance= 1
    C) When a block is broken, it spits out just over 1.5 blocks worth of it.

    The code for when it is broken
    Code:java
    1.  
    2. @EventHandler(priority = EventPriority.HIGH)
    3. public void onBlockBreak(final BlockBreakEvent event) {
    4.  
    5. Block block = event.getBlock();
    6. Player player = event.getPlayer();
    7. String playerName = event.getPlayer().getName();
    8. World world = event.getPlayer().getWorld();
    9.  
    10. if ((world.getName().equals(world1)) || world.getName().equals(nether) || world.getName().equals(world3) || world.getName().equals(world4) || world.getName().equals(world5)) {
    11. if (block.getType() == Material.GLASS) {
    12. if (glass = true) {
    13. for (int counter = 1; counter < 100; counter++) {
    14. int damage = 1 + chance.nextInt(100);
    15. if (damage <= damChance) {
    16. player.damage(damAmount);
    17. }
    18. if (plugin.droptoggle.contains(playerName)) {
    19. block.setType(Material.AIR);
    20. block.getWorld().dropItemNaturally(block.getLocation(), new ItemStack(Material.GLASS, 1));
    21. }
    22. }
    23. }else if(glass = false){
    24. return;
    25. }
    26. }
    27.  
    28. }
    29. }
    30.  
     
  15. Don't reply. Don't reply! NOOOO! I've replied!

    I've changed the code a little bit. I added some comment too.

    Code:java
    1. @EventHandler // You don't have to add the priority, just let Bukkit handle it
    2. public void onBlockBreak(final BlockBreakEvent event) {
    3. Block block = event.getBlock();
    4. Player player = event.getPlayer();
    5. String playerName = player.getName(); // You got the player, so get the name from the player object
    6. World world = player.getWorld(); // You got the player, so get the world from the player object
    7.  
    8. //Debug code to check if objects are loaded from config
    9. System.out.print("world1: " + world1);
    10. System.out.print("nether: " + nether);
    11. System.out.print("world3: " + world3);
    12. System.out.print("world4: " + world4);
    13. System.out.print("world5: " + world5);
    14. System.out.print("glass: " + glass);
    15.  
    16. String worldName = world.getName(); // Added so the following if statement is more readable
    17.  
    18. if (worldName.equals(world1) || worldName.equals(nether) || worldName.equals(world3) || worldName.equals(world4) || worldName.equals(world5)) {
    19. if (block.getType() == Material.GLASS) {
    20. if (glass == true) { // !!!!!!! Use ==
    21. int damage = 1 + chance.nextInt(100);
    22. if (damage <= damChance) {
    23. player.damage(damAmount);
    24. }
    25. if (plugin.droptoggle.contains(playerName)) {
    26. block.setType(Material.AIR);
    27. block.getWorld().dropItemNaturally(block.getLocation(), new ItemStack(Material.GLASS, 1));
    28. event.setCancelled(true); // Cancel the event because you've done it yourself (removing of block etc.)
    29. }
    30. }else{ // No need for a new if because it is always the opposite of the first if
    31. return;
    32. }
    33. }
    34. }
    35. }


    I've added some debug code to check what the objects are holding. You can remove that part if it's working ok. This is the way I always debug when I need to check if an object is holding a value.

    Also, I've removed the for loop because I think you don't need that. (With the for loop it will do everything 100 times!)

    The biggest mistake you made was using one = in a if statement. But that happens to the best of us :)
     
  16. Offline

    CRAZYxMUNK3Y

    You sir, are amazing! You will find a tag in my plugin page and Dev page for you help :)
     
  17. Whoohoo! That's why I do this stuff! ;)

    I'm glad I could help.
     
Thread Status:
Not open for further replies.

Share This Page