BukkitScheduler

Discussion in 'Plugin Development' started by desmin88, Mar 12, 2011.

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

    desmin88

    What does it mean by server 'ticks' for the Bukkit Task Scheduler? Milliseconds, seconds?

    Moreover,
    long - Delay in server ticks before executing first repeat:
    long - Period in server ticks of the task: What would this argument mean?
     
  2. Offline

    Kekec852

    One 'server tick' is one server loop.
     
  3. Offline

    desmin88

    And how long is a server loop?
     
  4. Offline

    Raphfrk

    Normally, there are 20 ticks per second. However, if the server is overloaded, there may be fewer.

    On the repeat thing, the period is how often the task executes.

    delay -> how long until the first execution
    period -> how long between executions

    delay = 50
    period = 10

    would mean 2.5 seconds delay until the task executes the first time and then it executes every half a second
    [MERGETIME="1299971134"][/MERGETIME]
    Also, remember to use the sync version if you are calling Bukkit API methods.
     
  5. Offline

    desmin88

    Can you tell me how to call say, cancelTask?

    I tried every which way but being I'm new to Java I'm obviously doing something wrong.
     
  6. Offline

    Edward Hand

    cancelTask takes an integer, which is the ID of the task to cancel.

    The ID is returned by scheduleSyncRepeatingTask() or whatever you use, so you would need to do something like this:
    Code:
    int taskId = schedulerThing.scheduleSyncRepeatingTask(/*Some stuff here*/);
    
    //......later on......
    
    schedulerThing.cancelTask(taskId);
     
  7. Offline

    desmin88

    Woops, I mean't to say cancelTask, but thank you though.

    I've tried getServer().getScheduler().cancelTask("PluginName"), doesn't work.
    pluginname. getServer().getScheduler().cancelTask() Nada either.
     
  8. Offline

    Edward Hand

    ....did you read my last post at all?
     
  9. Offline

    desmin88

    Well Jeebus. I guess I didn't
    [MERGETIME="1299992107"][/MERGETIME]
    I can't seem to get the third argument to work. I define a public class that has implements Runnable, with a public void run() inside it. However, If I write the class name as the third argument it doesn't work.
     
  10. Offline

    Edward Hand

    You're close then.

    You need not the class but an instance of the class. So say you called your class myRunnable then you would have 'new myRunnable()' as your third argument.
     
  11. Offline

    desmin88

    After setting the third argument to the instance of the class I made i.e 'new SaveFunction()', it tells me

    Code:
    The method scheduleSyncRepeatingTask(Plugin, Runnable, long, long) in the type BukkitScheduler is not applicable for the arguments (String, SimpleSave.SaveFunction, long, long)    
     
  12. Offline

    Edward Hand

    Well...it looks like you passed the wrong things to the function. A String where you needed a Plugin for instance.
    If you could post the relevant bits of your code it might help us see what's going on.
     
  13. Offline

    desmin88

    Yes, thats what I did. I gave it a string instead of the plugin, because I don't know what it means when it says plugin. I assumed the plugin name.
     
  14. Offline

    Edward Hand

    If you're calling that line of code within your main plugin class (the class that extends JavaPlugin) then that parameter will just be 'this'
     
  15. Offline

    darknesschaos

    I would like to ask if you could provide some sort of example using the scheduler, every time I tried using it in the past, I failed.
     
  16. Offline

    Edward Hand

    Ok, so start by making a runnable class:
    Code:
    public class myRunnable implements Runnable
    {
      //the run function is required for classes implementing Runnable
      //it is called every time the scheduler does its thing.
      public void run()
      {
          //stuff you want to do on a timer
      }
    }
    and then once you've set that up it's simply a case of doing:
    Code:
    mainPlugin.getServer().getScheduler().scheduleSyncRepeatingTask(mainPlugin, new myRunnable(), startDelayTicks, intervalTicks);
    to set it going.

    Often you will want your myRunnable class to have some kind of constructor function so that you can pass it references to players, worlds or to the server or something.

    As for how you stop the task, that I answered earlier in the thread.
     
    TheIcarusKid likes this.
  17. Offline

    desmin88

    Edward Hand, I must thank you because your being very helpful. I used this as the plugin name and sure enough, it worked. However, now I'm getting this error, which I've never gotten before and quite frankly dont know where it came from.
    Code:
    Default constructor cannot handle exception type IOException thrown by implicit super constructor. Must define an explicit constructor 
    I put my code that assigns the scheduler task in a function that returns its taskID, then at the top of my code did int task = Scheduler() to assign the scheduler and to get the taskid.
     
  18. Offline

    Edward Hand

    If you could paste the relevant bits of your code it would help a lot.
     
  19. Offline

    desmin88

    Sorry for delay in posting, computer was not available. I'm going to post my whole code, because I dont know what would be relevant with this error.

    Code:
    package org.desmin88.simplesave;
    
    import org.bukkit.entity.Player;
    import org.bukkit.Server;
    import org.bukkit.event.Event.Priority;
    import org.bukkit.event.Event;
    import org.bukkit.plugin.PluginDescriptionFile;
    import org.bukkit.plugin.PluginLoader;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.plugin.PluginManager;
    import org.bukkit.World;
    import java.util.logging.Logger;
    import java.io.*;
    
    public class SimpleSave extends JavaPlugin {
        public boolean run = true;
        protected final Logger log = Logger.getLogger("Minecraft");
        File localCFile = new File("plugins/SimpleSave");
        File f = new File("plugins/SimpleSave/config.properties");
        String text = "10";
        Writer output = new BufferedWriter(new FileWriter(f));
        String s = readFile("plugins/SimpleSave/config.properties");
        String g = s.replaceAll("\\D", "");
        //int task = Schedule();
        int task = Schedule();
            public void onDisable() {
            getServer().getScheduler().cancelTask(task);
        }
    
        public void onEnable()  {
    
            log.info("SimpleSave: 1.1 Initialized");
            localCFile.mkdir();
            if(!f.exists()){
                  try {
                    f.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                finally {
                try {
                    output.close();
                } catch (IOException e) {
    
                    e.printStackTrace();
                }
                }
                try {
                    output.write(text);
                } catch (IOException e) {
    
                    e.printStackTrace();
                }
                finally {
                    try {
                        output.close();
                    } catch (IOException e) {
    
                        e.printStackTrace();
                    }
                }
                try {
                    output.close();
                } catch (IOException e) {
    
                    e.printStackTrace();
                }
    
            }
        }
    
        public class SaveFunction implements Runnable {
    
            public void run() {
                while(run==true){
                log.info("SimpleSave: Beginning save");
                getServer().broadcastMessage("[SimpleSave]Beginning world save");
                getServer().getWorld("world").save();
                   getServer().savePlayers();
                   log.info("SimpleSave: Data saved successfully");
                   getServer().broadcastMessage("[SimpleSave]World save complete");
              }
    
        }
    
      }
    
    public String readFile( String file ) throws IOException {
    
        BufferedReader reader = new BufferedReader( new FileReader (file));
        String line  = null;
        StringBuilder stringBuilder = new StringBuilder();
        String ls = System.getProperty("line.separator");
        while( ( line = reader.readLine() ) != null ) {
            stringBuilder.append( line );
            stringBuilder.append( ls );
        }
        return stringBuilder.toString();
    }
    
    public int Schedule() {
    
        int z = java.lang.Integer.parseInt(g);
        int fs = z * 1200;
        long sf = fs;
        int taskID = getServer().getScheduler().scheduleSyncRepeatingTask(this, new SaveFunction() ,sf,sf);
        return taskID;
    
    }
    }
    
    
    PS:
    When using dispatchcommand, when it asks for the command sender, why doesnt using 'this' work for it?
     
  20. Offline

    Edward Hand

    All of this stuff:
    Code:
    protected final Logger log = Logger.getLogger("Minecraft");
        File localCFile = new File("plugins/SimpleSave");
        File f = new File("plugins/SimpleSave/config.properties");
        String text = "10";
        Writer output = new BufferedWriter(new FileWriter(f));
        String s = readFile("plugins/SimpleSave/config.properties");
        String g = s.replaceAll("\\D", "");
    should go in your onEnable() function.
    Doing stuff like that outside of a function isn't what you would call 'good practise'.
     
  21. Offline

    desmin88

    Ok, I've put it inside onEnable(), however it still wont work.
    Heres my new code that compiles and runs in the console, but no log info is shown indicating the saving is happening.
    Also, how do you call dispatchCommand? It doesn't seem to work for me on the first argument.
    It tells me that the method is undefined for the type server.
    Code:
    package org.desmin88.simplesave;
    
    import org.bukkit.entity.Player;
    import org.bukkit.Server;
    import org.bukkit.event.Event.Priority;
    import org.bukkit.event.Event;
    import org.bukkit.plugin.PluginDescriptionFile;
    import org.bukkit.plugin.PluginLoader;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.plugin.PluginManager;
    import org.bukkit.World;
    import java.util.logging.Logger;
    import java.io.*;
    
    public class SimpleSave extends JavaPlugin {
        public void onDisable() {
            getServer().getScheduler().cancelTasks(this);
        }
    
        public void onEnable()  {
    
            final Logger log = Logger.getLogger("Minecraft");
            File localCFile = new File("plugins/SimpleSave");
            File f = new File("plugins/SimpleSave/config.properties");
            String text = "10";
            Writer output = null;
    
            log.info("SimpleSave: 2.0 Initialized");
            localCFile.mkdir();
            if(!f.exists()){
                  try {
                    f.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    output = new BufferedWriter(new FileWriter(f));
                } catch (IOException e1) {
    
                    e1.printStackTrace();
                }
    
                try {
                    output.write(text);
                } catch (IOException e) {
    
                    e.printStackTrace();
                }
                finally {
                    try {
                        output.close();
                    } catch (IOException e) {
    
                        e.printStackTrace();
                    }
                }
                try {
                    output.close();
                } catch (IOException e) {
    
                    e.printStackTrace();
                }
    
                int task = Schedule();
    
            }
        }
    
        public class SaveFunction implements Runnable {
    
            public void run() {
                final Logger log = Logger.getLogger("Minecraft");
                boolean run = true;
                while(run==true){
                log.info("SimpleSave: Beginning save");
                getServer().broadcastMessage("[SimpleSave]Beginning world save");
                getServer().getWorld("world").save();
                   getServer().savePlayers();
                   log.info("SimpleSave: Data saved successfully");
                   getServer().broadcastMessage("[SimpleSave]World save complete");
              }
    
        }
    
      }
    
    public String readFile( String file ) throws IOException {
    
        BufferedReader reader = new BufferedReader( new FileReader (file));
        String line  = null;
        StringBuilder stringBuilder = new StringBuilder();
        String ls = System.getProperty("line.separator");
        while( ( line = reader.readLine() ) != null ) {
            stringBuilder.append( line );
            stringBuilder.append( ls );
        }
        return stringBuilder.toString();
    }
    
    public int Schedule() {
        String s = null;
        try {
            s = readFile("plugins/SimpleSave/config.properties");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String g = s.replaceAll("\\D", "");
        int z = java.lang.Integer.parseInt(g);
        int fs = z * 1200;
        long sf = fs;
        int taskID = getServer().getScheduler().scheduleSyncRepeatingTask(this, new SaveFunction() ,sf,sf);
        return taskID;
    
    }
    }
    
     
  22. Offline

    Edward Hand

    Sorry. I probably wasn't very clear.

    You should define variables like Logger in the place you had them before but initialise them in functions.
    By that I mean something like this:
    Code:
    public class myPlugin extends JavaPlugin
    {
        private int myInt;
        private Server myServer;
    
        public void onEnable()
        {
            myInt=4;
            myServer = this.getServer();
        }
    
    }
    (unless they're static properties of course but that's another matter)
     
  23. Offline

    desmin88

    Thanks for teaching my proper technique. Really helps me clean the code up, however, with my latest version it still wont wont. Don't know why either.

    Code:
    package org.desmin88.simplesave;
    
    import org.bukkit.entity.Player;
    import org.bukkit.Server;
    import org.bukkit.event.Event.Priority;
    import org.bukkit.event.Event;
    import org.bukkit.plugin.PluginDescriptionFile;
    import org.bukkit.plugin.PluginLoader;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.plugin.PluginManager;
    import org.bukkit.World;
    import java.util.logging.Logger;
    import java.io.*;
    
    public class SimpleSave extends JavaPlugin {
        Logger log;
        File localCFile;
        File f;
        String text;
        Writer output = null;
        boolean run;
    
        public void onDisable() {
            getServer().getScheduler().cancelTasks(this);
        }
     
        public void onEnable()  {
    
            log = Logger.getLogger("Minecraft");
            File localCFile = new File("plugins/SimpleSave");
            File f = new File("plugins/SimpleSave/config.properties");
            String text = "10";
            run = true;
    
            log.info("SimpleSave: 2.0 Initialized");
            localCFile.mkdir();
            if(!f.exists()){
                  try {
                    f.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    output = new BufferedWriter(new FileWriter(f));
                } catch (IOException e1) {
    
                    e1.printStackTrace();
                }
     
                try {
                    output.write(text);
                } catch (IOException e) {
    
                    e.printStackTrace();
                }
                finally {
                    try {
                        output.close();
                    } catch (IOException e) {
    
                        e.printStackTrace();
                    }
                }
                try {
                    output.close();
                } catch (IOException e) {
    
                    e.printStackTrace();
                }
     
                int task = Schedule();
    
            }
        }
    
        public class SaveFunction implements Runnable {
    
            public void run() {
     
                while(run==true){
                log.info("SimpleSave: Beginning save");
                getServer().broadcastMessage("[SimpleSave]Beginning world save");
                getServer().getWorld("world").save();
                   getServer().savePlayers();
                   log.info("SimpleSave: Data saved successfully");
                   getServer().broadcastMessage("[SimpleSave]World save complete");
              }
    
        }
     
      }
     
    public String readFile( String file ) throws IOException {
    
        BufferedReader reader = new BufferedReader( new FileReader (file));
        String line  = null;
        StringBuilder stringBuilder = new StringBuilder();
        String ls = System.getProperty("line.separator");
        while( ( line = reader.readLine() ) != null ) {
            stringBuilder.append( line );
            stringBuilder.append( ls );
        }
        return stringBuilder.toString();
    }
     
    public int Schedule() {
        String s = null;
        try {
            s = readFile("plugins/SimpleSave/config.properties");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String g = s.replaceAll("\\D", "");
        int z = java.lang.Integer.parseInt(g);
        int fs = z * 1200;
        long sf = fs;
        int taskID = getServer().getScheduler().scheduleSyncRepeatingTask(this, new SaveFunction() ,sf,sf);
        return taskID;
    
    }
    }
            
    
     
  24. Offline

    Edward Hand

    Which bit isn't working? Are there errors?
     
  25. Offline

    desmin88

    Well, I've solved the problem, it now correctly gets to the SaveFunction(), however, in my scheduler function it won't read the properties file and sets the scheduler to 1 second. What is odd is that it waits the specified time (1 minute), but once it hits that it just loops like crazy for some reason.


    Heres my new code.
    Code:
    package org.desmin88.simplesave;
    
    import org.bukkit.entity.Player;
    import org.bukkit.Server;
    import org.bukkit.event.Event.Priority;
    import org.bukkit.event.Event;
    import org.bukkit.plugin.PluginDescriptionFile;
    import org.bukkit.plugin.PluginLoader;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.plugin.PluginManager;
    import org.bukkit.World;
    import java.util.logging.Logger;
    import java.io.*;
    import java.util.*;
    
    public class SimpleSave extends JavaPlugin {
        Logger log;
        File localCFile;
        File f;
        String text;
        Writer output = null;
        boolean run;
    
        public void onDisable() {
            getServer().getScheduler().cancelTasks(this);
        }
    
        public void onEnable()  {
    
            log = Logger.getLogger("Minecraft");
            int task = Schedule();
            File localCFile = new File("plugins/SimpleSave");
            File f = new File("plugins/SimpleSave/config.properties");
            String text = "10";
    
            log.info("SimpleSave: 2.0 Initialized");
            localCFile.mkdir();
            if(!f.exists()){
                  try {
                    f.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    output = new BufferedWriter(new FileWriter(f));
                } catch (IOException e1) {
    
                    e1.printStackTrace();
                }
    
                try {
                    output.write(text);
                } catch (IOException e) {
    
                    e.printStackTrace();
                }
                finally {
                    try {
                        output.close();
                    } catch (IOException e) {
    
                        e.printStackTrace();
                    }
                }
                try {
                    output.close();
                } catch (IOException e) {
    
                    e.printStackTrace();
                }
    
            }
        }
    
        public class SaveFunction implements Runnable {
    
            public void run() {
    
                run = true;
                while(run==true){
                    log.info("SimpleSave: Beginning save");
                    getServer().broadcastMessage("[SimpleSave]Beginning world save");
    
                    int i = 0;
                    List localList = getServer().getWorlds();
                    Iterator localIterator = localList.iterator();
                    while (localIterator.hasNext())
                    {
                      World localWorld = (World)localIterator.next();
                      localWorld.save();
                      i++;
                   }
                    getServer().savePlayers();
                       log.info("SimpleSave: Ending Save");
                       getServer().broadcastMessage("[SimpleSave]Ending world save");
           }
    
        }
    
      }
    
    private String readFile( String file ) throws IOException {
    
        BufferedReader reader = new BufferedReader( new FileReader (file));
        String line  = null;
        StringBuilder stringBuilder = new StringBuilder();
        String ls = System.getProperty("line.separator");
        while( ( line = reader.readLine() ) != null ) {
            stringBuilder.append( line );
            stringBuilder.append( ls );
        }
        return stringBuilder.toString();
    }
    
    public int Schedule() {
        String s = null;
        try {
            s = readFile("plugins/SimpleSave/config.properties");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        log.info(s);
        String g = s.replaceAll("\\D", "");
        int z = java.lang.Integer.parseInt(g) * 1200;
        long sf = z;
        log.info("String data of properties"  + s);
        log.info("Interval after being converted to ticks" + Integer.toString(z));
         int taskID = getServer().getScheduler().scheduleSyncRepeatingTask(this, new SaveFunction() ,sf,sf);
        return taskID;
    
    }
    }
    
    
    [MERGETIME="1300151944"][/MERGETIME]
    Ahh. I think i see the issue.
    When I looked over the JavaDocs for Bukkit, I saw the two arguments and thought the last one meant how long until it runs again, however, after going back, its not. And now I dont know where to start.
    int taskID = getServer().getScheduler().scheduleSyncRepeatingTask(this, new SaveFunction() ,sf,sf)

    And ideas?

    Wow, this is truly confusing. I looked at the JavaDocs, again, and at the wiki page for Scheduler. The last argument is supposed to be for the time until next run. Now that I know that, it seems maybe something is wrong with scheduler? Because the time until first run works, but the time until next run doesn't.
    See here
    getServer().getScheduler().scheduleSyncRepeatingTask(this,new SaveFunction(),sf,sf);

    See? Same variable as time until next run, but, once it hits the first run it loops like crazy!

    Edit: Solved problem
    I put a return in the SaveFunction(), and it works. Woohoo!

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

    TheIcarusKid

    Thanks for your help, Edward! :)
     
Thread Status:
Not open for further replies.

Share This Page