NullPointerException

Discussion in 'Plugin Development' started by djmaster329, May 30, 2012.

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

    djmaster329

    Hi,

    I'm trying to build my own plugin to keep the time either day or night.
    It needs to reset the time every 10 seconds (so it stays day/night).

    This is the code I have so far:
    Code:
    package me.djmaster329.Time;
     
     
    import org.bukkit.ChatColor;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.PlayerLoginEvent;
    import org.bukkit.plugin.PluginManager;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.event.EventHandler;
    import java.util.List;
    import java.util.Timer;
    import java.util.TimerTask;
     
    /*
    * extends pugin means that it is a plugin
    * implements Listener declares this class as an event listener. It makes sense to put listeners for
    * different stuff into different classes but this is just a simple example
    */
    public class Time extends JavaPlugin implements Listener {
        public static String TimeType = "Day";
        Timer timer;
        List<String> worldnames;
        Integer seconds = 10;
     
        @Override
        public void onEnable() {
            //this method is called once your plugin is enabled
     
            //this gets the plugin manager for our plugin
            PluginManager pm = this.getServer().getPluginManager();
     
            /*
            * this registers our listener. The first argument is the listener the second the plugin
            * if you put the listener into a different class you have to put an istance of that class
            * as the first argument
            */
            pm.registerEvents(this, this);
            Resettime();
       
        }
        public void run() {
            System.out.println("Time's up!");
            for (int u = 0; u < this.worldnames.size(); u++) {
                getServer().getWorld((String)this.worldnames.get(u)).setTime(6000L);
              }
       
            //timer.cancel(); //Not necessary because we call System.exit
            System.exit(0); //Stops the AWT thread (and everything else)
          }
     
        public void onDisable() {
            //this method is called once your plugin is diabled you can save stuff or clean up here
        }
     
        /*
        * The on command method is called every time a command which is registered for your plugin is called
        * @sender: this is the sender of the command. Can be a player or the command line
        * [USER=55020]CMD[/USER]: a command object. Look into the API docs for what you can do with it
        * @commandLabel: a string of which command has been issued. Useful if you have more than one command
        * @args: an array of arguments supplied to the command
        */
        /*public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){
            if(cmd.getName().equalsIgnoreCase("basic")){ // If the player typed /basic then do the following...
                //doSomething
                return true;
            } //If this has happened the function will break and return true. if this hasn't happened the a value of false will be returned.
            //you should always return true if the command has been processed by your plugin and false if not
            return false;
        }/*
     
        /*
        * this is an event hanldler event handlers have to be in classes which implement Listener
        * the @EventHandler annotation marks this method as an event handler
        * the method name can be anything you like
        * event handler have one parameter which also defines which event they handle
        */
     
        public void Resettime() {
            timer = new Timer();
            timer.schedule(new RemindTask(), 10 * 1000);
          }
     
        class RemindTask extends TimerTask {
            List<String> worldnames;
            public void run() {
              System.out.println("Timer reset!");
                  if(TimeType == "Day"){
                      for (int u = 0; u < this.worldnames.size(); u++) {
                      getServer().getWorld((String)this.worldnames.get(u)).setTime(6000L);
                      }
                  }
                 
                  if(TimeType == "Night"){
                      for (int u = 0; u < this.worldnames.size(); u++) {
                      getServer().getWorld((String)this.worldnames.get(u)).setTime(15600L);
                      }
                  } 
             
                  Resettime();
              }
          }
     
        @EventHandler
        public void loginHandler(PlayerLoginEvent event) {
            /*
            * this method is called every time a player logs in you can find out more about the event
            * via the given parameter
            * e.g. we can determine which player logged in and send him a welcome message
            */
       
        }
     
        /*
        * This is another event handler with high priority. So if there are other handlers for the same
        * event this one will be called first
        */
     
    public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){
       
            if(cmd.getName().equalsIgnoreCase("day")){
                if(TimeType == "Day"){
                    sender.sendMessage(ChatColor.GREEN + "It is already daytime!");
                }else{
                    sender.sendMessage(ChatColor.GREEN + "Time changed to Day!");
                    TimeType = "Day";
                }
                //sender.sendMessage(ChatColor.GREEN + "Rules:");
            }
            if(cmd.getName().equalsIgnoreCase("night")){
                if(TimeType == "Night"){
                    sender.sendMessage(ChatColor.GREEN + "It is already nighttime!");
                }else{
                    sender.sendMessage(ChatColor.GREEN + "Time changed to Night!");
                    TimeType = "Night";
                }
                //sender.sendMessage(ChatColor.GREEN + "Rules:");
            }
                return true;
        }
    }
    How can I keep the Timer running? Because it now only runs once.

    The NullPointerException I get when the timer tries to change the time:
    Code:
    12:17:43 [INFO] Timer reset!
    12:17:43 [SEVERE] Exception in thread "Timer-10"
    12:17:43 [SEVERE] java.lang.NullPointerException
    12:17:43 [SEVERE]      at me.djmaster329.Time.Time$RemindTask.run(Time.java:90)
     
    12:17:43 [SEVERE]      at java.util.TimerThread.mainLoop(Unknown Source)
    12:17:43 [SEVERE]      at java.util.TimerThread.run(Unknown Source)
     
  2. Offline

    theguynextdoor

    The error is on the line:

    for (int u = 0; u < this.worldnames.size(); u++) {

    and from looking at your code, i can't see where you actually initialise or put anything inside worldnames. If you do the please share. But currently in that class your are refering to a list which has not been initialised nor anything been put in.
     
  3. dont use timers, use the schedular instead, using timers can result in thread currrent effect, including big spammy errors that freeze up the server
     
  4. Offline

    djmaster329

    Hmm. I guess I still need to do that :).

    I will try that in a minute.

    What code do you suggest? :)

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

    Njol

    Read the article on the wiki: Scheduler Programming
     
  6. Code:java
    1.  
    2. BukkitScheduler sched = Bukkit.getScheduler();
    3. sched.scheduleSyncRepeatingTask(this, new Runnable(){public void run(){
    4. // Make it day at world here, this is the right place to do it
    5. }}, 20*10, 10*20);//the last are mesured at ticks, multiply the 10 sec by 20 to get the ticks
     
  7. Offline

    djmaster329

    It works now!
    Code:
    public void ResetTime(){
           
            BukkitScheduler sched = Bukkit.getScheduler();
            sched.scheduleSyncRepeatingTask(this, new Runnable(){public void run(){
                //for (int u = 0; u < this.worldnames.size(); u++) {
                if(TimeType == "Day"){
                    Bukkit.getWorld("world").setFullTime(5000);
                }else{
                    Bukkit.getWorld("world").setFullTime(14000);
                }
                // }
            // Make it day at world here, this is the right place to do it
            }}, 20*10, 10*20);//the last are mesured at ticks, multiply the 10 sec by 20 to get the ticks
           
        }
    Thanks guys :)
     
  8. Offline

    paalbra

    That bit of code shouldn't work as far as i can tell(?). Haven't tried it though.

    I have some spare time where i'm at so i kinda rewrote the plugin. Here's what i wrote(It's not really flexible and nor have i tested it, but i do believe it should work if the wordlist has been populated when the plugin loads):
    Code:java
    1. package me.djmaster329.Time;
    2.  
    3. import java.util.List;
    4.  
    5. import org.bukkit.ChatColor;
    6. import org.bukkit.World;
    7. import org.bukkit.command.Command;
    8. import org.bukkit.command.CommandSender;
    9. import org.bukkit.event.Listener;
    10. import org.bukkit.plugin.java.JavaPlugin;
    11.  
    12. public class Time extends JavaPlugin implements Listener {
    13.  
    14. public TimeType timeType = TimeType.Day;
    15. int period = 10;
    16.  
    17. @Override
    18. public void onEnable() {
    19. Runnable task = new ResetTime(this);
    20. this.getServer().getScheduler().scheduleAsyncRepeatingTask(this, task, 0, period * 20);
    21. }
    22.  
    23. public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
    24.  
    25. if (cmd.getName().equalsIgnoreCase("day")) {
    26. TimeType input = TimeType.valueOf(cmd.getName());
    27. if (timeType == input) {
    28. sender.sendMessage(ChatColor.GREEN + "It is already daytime!");
    29. } else {
    30. sender.sendMessage(ChatColor.GREEN + "Time changed to Day!");
    31. timeType = TimeType.Day;
    32. }
    33. return true;
    34. } else if (cmd.getName().equalsIgnoreCase("night")) {
    35. TimeType input = TimeType.valueOf(cmd.getName());
    36. if (timeType == input) {
    37. sender.sendMessage(ChatColor.GREEN + "It is already nighttime!");
    38. } else {
    39. sender.sendMessage(ChatColor.GREEN + "Time changed to Night!");
    40. timeType = TimeType.Night;
    41. }
    42. return true;
    43. }
    44. return false;
    45. }
    46. }
    47.  
    48. enum TimeType {
    49. Day, Night
    50. }
    51.  
    52. class ResetTime implements Runnable {
    53. private Time owner;
    54. private List<World> worlds;
    55.  
    56. public ResetTime(Time owner) {
    57. this.owner = owner;
    58. this.worlds = owner.getServer().getWorlds();
    59. }
    60.  
    61. @Override
    62. public void run() {
    63. for (World w : worlds) {
    64. if (owner.timeType == TimeType.Day)
    65. w.setTime(6000L);
    66. else
    67. w.setTime(15600L);
    68. }
    69. }
    70. }
     
Thread Status:
Not open for further replies.

Share This Page