Jump to content
Frequently Asked Questions
  • Are you not able to open the client? Try following our getting started guide
  • Still not working? Try downloading and running JarFix
  • Help! My bot doesn't do anything! Enable fresh start in client settings and restart the client
  • How to purchase with PayPal/OSRS/Crypto gold? You can purchase vouchers from other users
  • [Tutorial] Creating The Base Of a AIO Using Node Script pt. 1


    Notorious

    Recommended Posts

    Creating a AIO Script using NodeScript. (Fishing)


    Hello today I will be showing you how to create a base foundation for use of a AIO script. For this tutorial I have chosen to go with fishing using node script, though this logic can be applied to many different types of scripts. As a bonus, this tutorial will become the base of a open source AIO fishing script, so that writers from around the community can contribute as well!

    Though, rather creating this fishing script using a normal script type (AbstractScript), I will be focusing the using NodeScript, from our API. This class is intended to make creating a Node Framework inside your scripts a bit easier. The usage is pretty straight forward, though when I was trying to first understand the usage of Nodes is script, I could not get a clear explanation of what or how this framework even works.

    So basically a Node can be considered a container which a particular action, or set of actions are stored. To make the writers life a bit easier, I have created a simple class named TaskNode which is used inside NodeScript. If we look inside of the API, we notice that TaskNode contains three methods, two of which are abstract (meaning they must be implemented).
    The two methods that must be implemented are:

    • boolean accept(); //Determines if the node sure run or not.
    • int execute(); //Executes if accept() returns true, otherwise skips.

    The other method to remember, though is optional:

    • int priority(); //If two nodes accept() have returned true, then whichever has the highest priority will be executed. If priority() is ignored, the first to be accepted will be chosen to run.

    To start off this tutorial, I will be starting with creating a simple TaskNode since we are already on the topic, then we will move on adding it to our fishing script afterwards.

    Well assuming you have started a new project, lets begin creating our script. For this script I will be using multiple class files, so if you struggle with separating classes please refresh yourself before moving on.

    For this project, I start off with a basic project layout:
    2ce2429f7557c217aac0738680791f8d.png

    Lets focus on FishNode for now, and will move onto MainScript which will implement the nodes we create later on. As mentioned above, each class which extends TaskNode must also implement two methods as well, accept() and execute(). The accept() method returns a boolean, which determines if that Nodes execute() should be "executed" or not. The basic implementation should look as follows:

     

    import org.dreambot.api.script.TaskNode;
    import org.dreambot.settings.UserSettings;
    
    /**
     * Created with IntelliJ IDEA.
     * User: NotoriousPP
     * Date: 12/11/2014
     * Time: 6:00 PM
     */
    public class FishNode extends TaskNode {
    
        private UserSettings settings;
    
        public FishNode(UserSettings settings) {
            this.settings = settings;
        }
    
        /**
         * Used to determine the order which the nodes should be ran.
         *
         * @return int to be used to determine which node should be ran, if
         * more than one is accepted.
         */
        @Override
        public int priority() {
            return super.priority();
        }
    
        /**
         * The method which is used to determine if the
         *
         * @return boolean which determines if the execute() method
         * should be ran.
         */
        @Override
        public boolean accept() {
            return false;
        }
    
        /**
         * The method which handles the actions of the node.
         *
         * @return int the amount of time in ms to return after the
         * node has been executed.
         */
        @Override
        public int execute() {
            return 1337;
        }
    
    }
    

     




    So now that we have a skeleton from which to start from, lets start creating some logic. Since were making a Fishing script, and have created a FishNode, I guess the best place to start is actually the fishing action. My idea for this script is as follows:d5ca265e66.png

    So lets start very simple and we will begin with a Draynor Village script for now. As the diagram above shows, we first need to check were in fishing area. So let's determine the best area which can be used, which I find is:

    66aa79c400.png

    Now that we have a area which we can use, lets talk about data storage. Since this tutorial is just covering building a base of a open source script, but we need to keep in mind the it needs to be expandable, and not written for "one-time" usage. Though we are only covering Draynor, we want to make it so that we are able to add locations later easily without much hassle. For this reason, I chose to use a Enum which holds our area information, which we can retrieve easily using a identifier. I first started by creating a new package called 'data', then created a new enum file named FishingArea(Choose whatever name you please, but please remember Code Conventions).

    The hierarchy now should look similar to this:
    a194c3c644.png

    When we take a look inside of FishingArea, I have already added fishing area for Draynor, using the Area class inside of our API.

     

    import org.dreambot.api.methods.map.Area;
    import org.dreambot.api.methods.map.Tile;
    
    /**
     * Created with IntelliJ IDEA.
     * User: NotoriousPP
     * Date: 12/11/2014
     * Time: 9:23 PM
     */
    public enum FishingArea {
    
        DRAYNOR_VILLAGE(new Area(
                new Tile(3083, 3235, 0),
                new Tile(3088, 3239, 0),
                new Tile(3094, 3233, 0),
                new Tile(3094, 3224, 0),
                new Tile(3088, 3216, 0),
                new Tile(3085, 3221, 0),
                new Tile(3086, 3225, 0),
                new Tile(3085, 3230, 0)
        ));
    
        private Area area;
    
        public Area getArea() {
            return area;
        }
    
        private FishingArea (Area area) {
            this.area = area;
        }
    }
    

     

     

     

    Before we move onto the implementation, we should create another Enum while were at it, just like before, though this time it will be used to store equipment we will need/use in our script. In this enum all I will store is the ID, and show you a efficient method of storing the name of the object. Here is what the enum should look like:

     

    /**
     * Created with IntelliJ IDEA.
     * User: NotoriousPP
     * Date: 12/11/2014
     * Time: 9:23 PM
     */
    public enum FishingEquipment {
    
        SMALL_NET(303);
    
        private int id;
    
        public int getId() {
            return id;
        }
    
        private FishingEquipment(int id) {
            this.id = id;
        }
    
        @Override
        public String toString() {
            String s = super.toString().replace('_',' ');
            return s.charAt(0) + s.substring(1, s.length()).toLowerCase();
        }
    }
    

     



    Now we have a area which we can use, though we now need to think how we can make changing locations easy for us in the future. My idea for tackling this, as well as any other settings to be used by the script, it to make a class which we can set variables to be used by script. To do this, I create a simple class UserSettings inside of a new package I call 'settings', which we can use for many other things down the road. The only thing, we need to add to this class, is a variable for the settings we wish to store, and corresponding getter and setter methods so we are able to retrieve and set the variable. For example after we add a variable for the location and equipment, it should look similar to this: (I made a simple add method as well)

     

    import org.dreambot.data.FishingArea;
    import org.dreambot.data.FishingEquipment;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    /**
     * Created with IntelliJ IDEA.
     * User: NotoriousPP
     * Date: 12/11/2014
     * Time: 9:59 PM
     */
    public class UserSettings {
    
        private FishingArea fishingArea;
        private final List<FishingEquipment> equipmentList = new ArrayList<>();
    
        public List<FishingEquipment> getEquipmentList() {
            return equipmentList;
        }
    
        public void addEquipment (FishingEquipment... equipment) {
            Collections.addAll(equipmentList, equipment);
        }
    
        public FishingArea getFishingArea() {
            return fishingArea;
        }
    
        public void setFishingArea(FishingArea fishingArea) {
            this.fishingArea = fishingArea;
        }
    }
    

     



    We now need implement this class, so lets create a simple MainScript class, which will be using NodeScript. Though we are going to focus on this later, we need to have a class which we can use to implement UserSettings, so a basic skeleton of class extending NodeScript which also implements our UserSettings class should look as follow.

     

    import org.dreambot.api.script.Category;
    import org.dreambot.api.script.ScriptManifest;
    import org.dreambot.api.script.impl.NodeScript;
    import org.dreambot.data.FishingArea;
    import org.dreambot.data.FishingEquipment;
    import org.dreambot.nodes.FishNode;
    import org.dreambot.settings.UserSettings;
    
    
    /**
     * Created with IntelliJ IDEA.
     * User: NotoriousPP
     * Date: 11/24/2014
     * Time: 4:55 PM
     */
    @ScriptManifest(name = "OpenFishing", description = "Open Source Fishing", version = 1.0, category = Category.FISHING, author = "Notorious")
    public class MainScript extends NodeScript {
    
        private UserSettings settings;
    
        @Override
        public void onStart() {
            settings = new UserSettings();
            /* Later we can handle this using a GUI */
            //We add our equipment we need to use
            settings.addEquipment(FishingEquipment.SMALL_NET);
            //We set which location we want to fish at
            settings.setFishingArea(FishingArea.DRAYNOR_VILLAGE);
        }
    
        @Override
        public void onExit() {
            super.onExit();
        }
    }
    

     



    So lets head back to our FishNode, and start getting it ready to build our accept method. As the diagram above shows, we need to check our area, and since we have just made a UserSettings class, we need a way to access it easily. We can either make the variable static, or pass a instance of UserSettings, and personally I do not like static, so in this tutorial I will be passing a instance to our node. I do this by creating a constructor inside of FishNode which takes MainScript as a parameter,  which we implemented Usersettings in earlier. Which looks like so inside of FishNode:

     

     

        private MainScript script;
    
        public FishNode(MainScript script) {
            this.script = script;
        }
    

     

     

    Now we have a settings instance which we can use inside of our Node, so now we can finally start real logic of script, I promise! After all the steps above have been completely your project hierarchy should look similar to this:

    c3faf70a26.png

     

    If it looks similar to this, your on the right track!

     

    Though not overwhelm most users, I will continue this tutorial in a part 2! I really hope you enjoy the tutorial so far, and will continue reading in the next addition! :D

     

    Click Here For Part Two

    Link to comment
    Share on other sites

    • 2 weeks later...

    Archived

    This topic is now archived and is closed to further replies.

    ×
    ×
    • Create New...

    Important Information

    We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.