October 22, 2019, 03:20:03 am


SMF - Just Installed!

[1.0] Official tutorial

Started by woder, March 02, 2015, 01:14:47 am

Previous topic - Next topic


March 02, 2015, 01:14:47 am Last Edit: March 03, 2015, 10:48:08 pm by woder
Hello! Today we will be learning how to program your first plugin!.

So for starters what is a plugin and how does it work?
A plugin is a piece of code that is loaded into the bot's main framework and is executed when certain things happen, with the plugin engine you can code anything from commands to fancy events
that can do loads of fun stuff such as display a message when you break a sign.

Alright, so how do I make one?
If you have never programmed before in you're life you might find this a bit difficult but I will try my best to make it simple.
So lets look at some code!
var name = "Test plugin";
function getName(){
return name;

This bit of code is where you tell the bot what the name of your plugin is, in this case the value of "name" was defined above the function, it was just assigned to a variable to make accessing it from other parts of the code easier. The getName() function is a function that you can not forget (its required).

Next up is the run function (it is run when the bot loads the plugin in)
function run(){ //this is the run function, this gets called when the bot loads the plugin, this means at start up and when the reload command is called **EXTREMELY IMPORTANT** DO NOT ever ever ever use any method here that can only work when the bot is logged in, this will cause stuff to go wrong and cause lots of problems, don't do it (an example of this would be calling c.chat.sendMessage(); from this, BAD!
c.gui.addText("§4General commands plugin reloaded"); //add some text to the gui, the § symbol is how to tell the bot to color the text
return true; //return true to tell the bot we started up properly

This is basically just the location where you put any initialization code. In the case of this plugin we will be simply printing to the GUI that our plugin has been reloaded.
As the comment says, do not use any function that requires the bot to be logged in..

Now would be a good time to go over what this "c" thing is.
The "c" thing is actually a reference to the main class in TorchBot, its like accessing the main part of the code. This class is called "Client" and its where all the action happens inside TorchBot, if ever you want to do some really fancy stuff with the bot you can always look in the source code on github and then use c to access it. I will go over some basic ones here:

  • c.chat.sendMessage("Message"); - This does exactly as what it looks like, it sends a message to the chat

  • c.gui.addText("Message"); - Adds the message to the GUI

  • c.move.gotoPlayer("Name"); - This runs the pathing to attempt to go to name's location

  • c.move.gotoLocation(x,y,z);  - This runs the pathing to attempt to go to x y z position

Those are some of the more basic ones, there are lot more but we wont cover them in this guide.

Moving on to the next section of this guide, we will look at the getListener function
function getListener(){ //this function tells the bot what listeners we will be using, basically lets say we want to know when a sign gets changed, you would put "onSignUpdate" here and then create a function lower in the code called onSignUpdate() with the parameters of that event (those are listed in the tutorial). To list multiple events just seperate them with a comma NO SPACE! just a comma like bellow
return "onSignUpdate,onBlockChange"; //register onSignUpdate and onBlockChange

This function simply returns a string with all the events you want to use separated by a comma.
Here is the current event list:

/* Event list so far
     * onSpawnPlayer String playername, String uuid, int x, int y, int z, byte yaw, byte pitch, short currentitem
     * onSignUpdate int x, int y, int z, String line1, String line2, String line3, String line4
     * onBlockChange int x, int y, int z, int bid, int meta
     * onChatMessage String username, String message (NOTE; this event will often return "Unknown" as user, in that case the message will contain the user AND string)
     * onEntityEquipement int entityid, int slotnum, int itemid, int itemcount, int itemdamage
     * onEntityMove int eid, double x, double y, double z
     * onEntityMoveLook int eid, double x, double y, double z, byte yaw, byte pitch
     * onEntityTeleport int eid, double x, double y, double z
     * onHealthUpdate float health, short food, float foodsat
     * onPlayerAbilities byte flags, float flyspeed, float walkspeed
     * onPlayerPosLook double x, double y, double z, byte yaw, byte pitch, boolean onground
     * onSlotUpdate byte window, int slo, int itemid, int count, int damage
     * onTimeUpdate long age, long time

A more up to date version can be found in the EventHandler.java class on github

Alright, so lets make a event handler. An even handler will ALWAYS be the full name of the event followed by the parameters, it should look something like this in our case, and remember, we registered two of them! Not one!

function onSignUpdate(x,y,z,l1,l2,l3,l4){ //this gets the x y z and the 4 different lines of a sign
c.chat.sendMessage("Sign at " + x + "," + y + "," + z + " now says: " + l1 + ";" + l2 + ";" + l3 + ";" + l4); //this displays the location of the sign along with the contents, using the "c" object as we saw earlier

function onBlockChange(x, y, z, bid, meta){ //same as above
c.chat.sendMessage("Block at " + x + "," + y + "," + z + " is now " + bid + " with meta of " + meta); //once again displays the information we gathered

So those were event handlers, they allow your plugin to react to things when certain conditions are met, such as making him yell something if someone breaks a block of diamond within 5 blocks of a specific spot. The important thing to remember with them is that they are ALWAYS declared with "function <nameOfTheEvent>(<parameters>)" where the parameters are defined either above or in the EventHandler.java class.

Now lets make a command! These are pretty simple, start out by defining the getCommands() function like this:

function getCommand(){ //this is the function that registers the commands that your plugin will need. The format of these commands is nameofcommand;description,nameofcommand;description and so on, its important to note that there is no space between the delimiters (the commas and the semi colons) as placing a space there will cause errors
c.perms.register(1, "under"); //This registers our command with the permission handlers, more on permissions later
return "under;Prints information about the block under the bot,version;Returns the version of the bot,reload;Reloads all plugins";

To return on the c.perms.register() part, as of the time of writing this permissions are in tiers, 0 being the lowest and it just keeps climbing, every one more in the tier is an additional level of trust this person requires to use this command. In other words, the command to tell you the time should probably be 0 and the command to give your self OP should probably be much much higher, such as a 7

Now on to programming the actual command, a command handler looks like this:

function under(command){ //you can do pretty much anything in here, this should only be called in game so calling game methods should be fine
    b = c.whandle.getWorld().getBlock(c.location).getRelative(0, -1, 0);
    if (b != null) {
        c.chat.sendMessage("Block is: " + b.getTypeId() + " and its meta data is: " + b.getMetaData());
    } else {
        c.chat.sendMessage("Failed :(");

Woah! where did that all come from?? Well, its not that complicated. As we saw before, to handle an event or a command you simply need to name your function the same as that command or event, now obviously since you can't have two functions with the same name you can't call your command onSignPlace or any of the other event names, those are reserved and you WILL cause problems if you try to use them as commands. The next bit is simply a call to get the block at position -1 Y from where the bot is, this is essentially just getting the block bellow the bot. We already saw how to use "c" to access core bot functions and this is just another thing you can do with that ability, if you don't know what the Block class is just look it up on the github. There you will find all sorts information on what you can do with it (unfortunately it means reading code but I'm sure you can do it!). After that we check if it's null (basically doing a check to see if the block was loaded), and if it was we will print some information on that block and if it wasn't we will send a message showing how sad we are.

And that's it! There is nothing more to it than that, from here you can do all sorts of things.
Attached is the completed version of this plugin, please attempt to write it your self before checking the full plugin for help. Inside the plugin there is also tons of comments to help with things this guide might have missed. If you have any questions don't hesitate to ask.
Note that importing ANYTHING that is not from the java packages MUST be prefixed with Packages.
So, to import the World class from the bot you do: