Omnimaga

General Discussion => Technology and Development => Computer Programming => Topic started by: Ephraim B on February 05, 2015, 08:04:31 pm

Title: How to make a IRC bot
Post by: Ephraim B on February 05, 2015, 08:04:31 pm
I want to make a bot that does everything that worm in #knightos on freenode does plus other cool things like greeting me, Excedra.

Can anyone please help me?
Title: Re: How to make a IRC bot
Post by: AngelFish on February 05, 2015, 09:52:33 pm
I'm not familiar with the functions worm has. However, there are a lot of different ways to write an IRC bot. I recommend you look at a dedicated tutorial in the language of your choice. Here's one in python (http://newcoder.io/networks/intro/) and another in Haskell (https://wiki.haskell.org/Roll_your_own_IRC_bot).
Title: Re: How to make a IRC bot
Post by: bb010g on February 05, 2015, 11:49:50 pm
The problem with Roll Your Own IRC Bot on the Haskell wiki is that it hasn't been updated in a while and uses some old libraries (with exceptions mostly) IIRC.
Title: Re: How to make a IRC bot
Post by: Juju on February 06, 2015, 12:48:12 am
Here's the one I use, with a few scripts I wrote. It's in Javascript (with Node.js), if you read the API it shouldn't be really complicated.

https://github.com/Eeems/EeeZorBot/tree/re-org
https://github.com/juju2143/EeeZorBot-scripts

Otherwise, you can try Eggdrop or this old thing (https://github.com/juju2143/shadowbot) I wrote 5 years ago.
Title: Re: How to make a IRC bot
Post by: Ivoah on February 06, 2015, 08:30:49 am
Here's the source code for worm from #knightos: https://github.com/SirCmpwn/wormy
Title: Re: How to make a IRC bot
Post by: Ephraim B on February 06, 2015, 03:58:44 pm
I want to program my IRC Bot in C
Title: Re: How to make a IRC bot
Post by: Sorunome on February 06, 2015, 04:00:20 pm
Maybe this will help you? https://bbs.archlinux.org/viewtopic.php?id=64254
Title: Re: How to make a IRC bot
Post by: Eeems on February 06, 2015, 09:48:18 pm
Here's the one I use, with a few scripts I wrote. It's in Javascript (with Node.js), if you read the API it shouldn't be really complicated.

https://github.com/Eeems/EeeZorBot/tree/re-org
https://github.com/juju2143/EeeZorBot-scripts
Not to mention that version isn't fully released yet ;)
I want to program my IRC Bot in C
You might want to lead off with what language you want to work with at the start of the topic next time.
Title: Re: How to make a IRC bot
Post by: shmibs on February 07, 2015, 02:47:45 pm
C is a pretty terrible choice for an IRC bot, because manual string buffering and all that, and it's not a program that's performance-critical. you should really try using something else for this use case
Title: Re: How to make a IRC bot
Post by: Ephraim B on February 08, 2015, 03:01:29 pm
C is a pretty terrible choice for an IRC bot, because manual string buffering and all that, and it's not a program that's performance-critical. you should really try using something else for this use case

What language is the beest language for a IRC bot?
Title: Re: How to make a IRC bot
Post by: Sorunome on February 08, 2015, 03:09:58 pm
Some high level scripting language, like python, for example.
Title: Re: How to make a IRC bot
Post by: Ephraim B on February 08, 2015, 10:10:28 pm
I think Python costs money. Is Java okay? I'll need to learn Java if I want to learn Web Programming.
Title: Re: How to make a IRC bot
Post by: Hooloovoo on February 08, 2015, 10:13:52 pm
Python is free. Did you look it up? According to everywhere on the internet, Python is very free. According to me, Python is easy to use, easy to program, and is the best for projects like IRC bots.
Title: Re: How to make a IRC bot
Post by: Ephraim B on February 08, 2015, 10:17:21 pm
I want to do it with Java because I'll need to learn it eventually for Web Programming. How do I program a IRC Bot in Java?
Title: Re: How to make a IRC bot
Post by: Hooloovoo on February 08, 2015, 10:21:53 pm
Java is not used on the web anymore. Maybe you're thinking of Javascript, which is commonly used on webpages. Javascript is not very well suited to programming bots in, though.
Title: Re: How to make a IRC bot
Post by: Ephraim B on February 08, 2015, 10:27:40 pm
I feel that Python will bloat my computer and I also need to download it on my school computer if I want to program the IRC bot on he school computer. I feel that programming the IRC Bot in C will be more portable for coding. Where's the IRC Bot tutorial for C?
Title: Re: How to make a IRC bot
Post by: Hooloovoo on February 08, 2015, 10:31:23 pm
Python is more portable than C, and a C development suite is nearly impossible to install on a computer you don't own. You are making this hard for yourself and me. The forum-goers here cannot help you with programming an IRC bot in anything other than python. Everyone (to my knowlege) here who has made an IRC bot made it in python, so it is pointless to ask for help with doing it in another language. If you don't know where to look you should search something like "IRC bot C" in google and maybe that will be more helpful.
Title: Re: How to make a IRC bot
Post by: rcfreak0 on February 08, 2015, 10:37:01 pm
I feel that Python will bloat my computer and I also need to download it on my school computer if I want to program the IRC bot on he school computer. I feel that programming the IRC Bot in C will be more portable for coding. Where's the IRC Bot tutorial for C?
Python is no less bloat than any other unless you install a bunch of stuff for an IDE, if you were to use one, and as for portablity my pick is p[ython aswell.
As for the demanding demeanor in asking for something you can very easily google, espcially C irc bots which pop up on google quite quick (http://lmgtfy.com/?q=IRC+Bot+tutorial+for+C). Same with python (http://lmgtfy.com/?q=Python+irc+bot+tutorial).
I would not recommend JS or Java for an irc bot either.
Title: Re: How to make a IRC bot
Post by: alberthrocks on February 08, 2015, 11:07:44 pm
I want to do it with Java because I'll need to learn it eventually for Web Programming. How do I program a IRC Bot in Java?
I feel that Python will bloat my computer and I also need to download it on my school computer if I want to program the IRC bot on he school computer. I feel that programming the IRC Bot in C will be more portable for coding. Where's the IRC Bot tutorial for C?
Java requires installing a massive JRE (50+ MBs) and JDK (157+ MBs), and is known to have many, many security risks. Python, on the other hand, is a very minimal language, coming in only at 17 MBs - both the development environment and the things you need to run what you make.

Also, it's unlikely that your computer will have a C compiler available. Most schools (AFAIK) don't have a professional C compiler available on their systems. Installing Visual Studio or MinGW on a flash drive is also a hassle, and can easily weigh in at over 1 GB.

Therefore, I strongly recommend Python, as it's extremely portable and very handy to use.
Title: Re: How to make a IRC bot
Post by: Adriweb on February 08, 2015, 11:35:11 pm
There are also bots made in Lua, which is "similar" to Python (less common, but very lightweight and quite powerful scripting language).
Also, Lua is very portable.
Title: Re: How to make a IRC bot
Post by: AngelFish on February 09, 2015, 12:28:12 am
I feel that Python will bloat my computer and I also need to download it on my school computer if I want to program the IRC bot on he school computer. I feel that programming the IRC Bot in C will be more portable for coding. Where's the IRC Bot tutorial for C?

When C was first designed in the early 1970s, computers had extraordinarily weak processors. The first C programs did not have access to the tremendous abundance of power modern computers have. Accordingly, they had to produce efficient code simply to run at all. C allows you to produce extremely size and computation efficient programs as a result of this heritage.  The downside is that C development environments tend to be extremely large. As an example, the development environment I use at work hovers around 1GB all-built and takes over an hour to deploy to new computers. A more standard setup like that present on my home computer is "only" 863 MB. The python installation I have is much lighter by comparison, weighing in at a grand total of 107 MB.



Areas where C generally is not the best choice include:

Areas where C may be a good choice include:


My emphatic recommendation is that you use another language such as Python for this project.

Now that that's out of the way, onto the C tutorial:


To start off with, I'm just going to assume you have a C development environment set up. There are a lot of ways to do this depending on your system and a million different tutorials for it on Google. This one (http://www.cs.columbia.edu/~sedwards/classes/2013/gateway-fall/linuxvm.pdf) is straightforward to follow if you don't feel like using Google.

Secondly, we're going to copy this guy's skeleton code (https://bbs.archlinux.org/viewtopic.php?id=64254). His code is broken as shown, so I'll be guiding you through a corrected version of each section individually.


(Note that the following will not display properly in Chrome. Please use an alternative browser or copy / paste into an editor)
Spoiler For Our Final Code:
Code: (cpp) [Select]
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>

int conn;
char sbuf[512];

void raw(char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(sbuf, 512, fmt, ap);
    va_end(ap);
    printf("<< %s", sbuf);
    write(conn, sbuf, strlen(sbuf));
}

int main() {
   
    char *nick = "EphraBoT";
    char *channel = "bottest";
    char *host = "irc.choopa.net";
    char *port = "6667";
   
    char *user, *command, *where, *message, *sep, *target;
    int i, j, l, sl, o = -1, start, wordcount;
    char buf[513];
    struct addrinfo hints, *res;
   
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    getaddrinfo(host, port, &hints, &res);
    conn = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    connect(conn, res->ai_addr, res->ai_addrlen);
   
    raw("USER %s 0 0 :%s\r\n", nick, nick);
    raw("NICK %s\r\n", nick);
   
    while ((sl = read(conn, sbuf, 512))) {
        for (i = 0; i < sl; i++) {
            o++;
            buf[o] = sbuf[i];
            if ((i > 0 && sbuf[i] == '\n' && sbuf[i - 1] == '\r') || o == 512) {
                buf[o + 1] = '\0';
                l = o;
                o = -1;
               
                printf(">> %s", buf);
               
                if (!strncmp(buf, "PING", 4)) {
                    buf[1] = 'O';
                    raw(buf);
                } else if (buf[0] == ':') {
                    wordcount = 0;
                    user = command = where = message = NULL;
                    for (j = 1; j < l; j++) {
                        if (buf[j] == ' ') {
                            buf[j] = '\0';
                            wordcount++;
                            switch(wordcount) {
                                case 1: user = buf + 1; break;
                                case 2: command = buf + start; break;
                                case 3: where = buf + start; break;
                            }
                            if (j == l - 1) continue;
                            start = j + 1;
                        } else if (buf[j] == ':' && wordcount == 3) {
                            if (j < l - 1) message = buf + j + 1;
                            break;
                        }
                    }
                   
                    if (wordcount < 2) continue;
                   
                    if (!strncmp(command, "001", 3) && channel != NULL) {
                        raw("JOIN %s\r\n", channel);
                    } else if (!strncmp(command, "PRIVMSG", 7) || !strncmp(command, "NOTICE", 6)) {
                        if (where == NULL || message == NULL) continue;
                        if ((sep = strchr(user, '!')) != NULL) user[sep - user] = '\0';
                        if (where[0] == '#' || where[0] == '&' || where[0] == '+' || where[0] == '!') target = where; else target = user;
                        printf("[from: %s] [reply-with: %s] [where: %s] [reply-to: %s] %s", user, command, where, target, message);
                    }
                }
               
            }
        }
       
    }
   
    return 0;
   
}

The first section in this code is what's called our headers section. It consists of a series of lines starting with "#include" followed by brackets and a filename.

Code: (cpp) [Select]
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>

The files in brackets are part of your C installation and all of these are standard on Linux systems.

The next section is only two lines long and declares our global variables:

Code: [Select]
int conn;
char sbuf[512];

The integer conn will be used to hold a connection descriptor. This will specifically identify our IRC connection rather than one of the hundreds of other connections your computer may be handling simultaneously. sbuf is a rather odd declaration you might not understand. What this notation means is that sbuf is an array large enough to hold chars. Array declarations generally follow the form "type name[size]".


Code: [Select]
    void raw(char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(sbuf, 512, fmt, ap);
    va_end(ap);
    printf("<< %s", sbuf);
    write(conn, sbuf, strlen(sbuf));
}

This is our first function, yay! Unfortunately it's quite a doozy. This is what's known as a variadic function, which is to say it can take any number of arguments (within reason). Variadic functions are a more advanced topic than you're ready to handle, so we can ignore most of it for now. There are two things that you should note though. First of all, raw() returns void (i.e. nothing at all). That means that we get no information back about whether it succeeded or not. Secondly, the function write() as used here does not match up with the documentation you may see online. That is because C has some hand-wavy magic going on behind the scenes that says write() behaves like the function send() located in <sys/socket.h>.

Code: [Select]
int main() {
This is the single most important line in our code. Almost all C programs have a function named main() that is the first function called program executes. Don't worry about the few exceptions to this as they're all more advanced topics like variadic functions.

Code: [Select]
    char *nick = "EphraBoT";
    char *channel = "bottest";
    char *host = "irc.choopa.net";
    char *port = "6667";
   
    char *user, *command, *where, *message, *sep, *target;
    int i, j, l, sl, o = -1, start, wordcount;
    char buf[513];
    struct addrinfo hints, *res;

As before, these are variable declarations. Unlike the previous variables, they can only be accessed from within the main() function. They should be relatively self explanatory. nick is the nickname your bot will attempt to use on joining the network. channel is the name of the channel the bot will join. host is the server that will be reached, so on and so forth. The rest of these variables are simply technical overhead C forces us to carry around.

Code: [Select]
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    getaddrinfo(host, port, &hints, &res);
    conn = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    connect(conn, res->ai_addr, res->ai_addrlen);

The first 3 lines simply initialize variables to default values. In a more professional program this would be handled differently, but a more professional program would hopefully not use a language so uniquely unsuited to IRC as C.
The last 3 lines of this snippet are the important ones, as they connect to the server. There is enough behind-the-scenes magic happening with these function calls to fill a good sized book.

Code: [Select]
    raw("USER %s 0 0 :%s\r\n", nick, nick);
    raw("NICK %s\r\n", nick);

After the preceding function calls succeed, we are connected to the server. Now we have to tell it what we want our username and nickname to be. That's what these two calls do for us.

Code: [Select]
    while ((sl = read(conn, sbuf, 512))) {

This is our program's while loop. Every time we come back to this loop, it will read up to 512 bytes out of IRC and attempt to parse them. The loop will continue until forever (or the program is closed).


Code: [Select]
        for (i = 0; i < sl; i++) {

Translated: "For every byte we've read from the IRC server, do the following on it..."

Code: [Select]
            o++;
            buf[o] = sbuf[i];

Increment our counter to make sure we don't overrun our buffer space and copy the byte into the spare buffer.
           
Code: [Select]
            if ((i > 0 && sbuf[i] == '\n' && sbuf[i - 1] == '\r') || o == 512) {

The previous increment-and-copy procedure will loop until we hit an end-of-line character or we've run out of buffer space. If either of these conditions are met, do the following...

Code: [Select]
                buf[o + 1] = '\0';
                l = o;
                o = -1;
               
                printf(">> %s", buf);

C does not null terminate buffers automatically, so we need to do this manually to prevent our string routines from flying off into memory we don't control. Then we reset our variables and print the string we just received to stdout.

Code: [Select]
                if (!strncmp(buf, "PING", 4)) {
                    buf[1] = 'O';
                    raw(buf);

Now that we've received our message, we can process it. One of the messages we're expecting to get is what's called a PING. This is used by the server to make sure we're still connected. The proper response to a PING is a PONG. I also want to note that this is perhaps the worst possible way to ever respond to a PING.

Homework problem #1: See if you can figure out how PING/PONG messages work.

Homework problem #2: See if you can replace this conditional with something more reliable.

Code: [Select]
                } else if (buf[0] == ':') {

Now that we've "handled" our PINGs, we can handle all of the normal messages from the server. That is what this case statement is for.

Code: [Select]
                    wordcount = 0;
                    user = command = where = message = NULL;
                    for (j = 1; j < l; j++) {
                        if (buf[j] == ' ') {
                            buf[j] = '\0';
                            wordcount++;
                            switch(wordcount) {
                                case 1: user = buf + 1; break;
                                case 2: command = buf + start; break;
                                case 3: where = buf + start; break;
                            }
                            if (j == l - 1) continue;
                            start = j + 1;
                        } else if (buf[j] == ':' && wordcount == 3) {
                            if (j < l - 1) message = buf + j + 1;
                            break;
                        }
                    }

This section initializes the variables you'll be using to the proper values. wordcount will contain the number of words in the message, user will point to a string containing the nickname of the person who sent the message and command will point to a string containing the command name.

Code: [Select]
                    if (wordcount < 2) continue;

If there are fewer than 2 words, it's not a valid command yet. Go back to looping until we get a full command.

Code: [Select]
                    if (!strncmp(command, "001", 3) && channel != NULL) {
                        raw("JOIN %s\r\n", channel);

If our command is a particular server response code, join the channel we've specified as the default.

Code: [Select]
                    } else if (!strncmp(command, "PRIVMSG", 7) || !strncmp(command, "NOTICE", 6)) {
                        if (where == NULL || message == NULL) continue;
                        if ((sep = strchr(user, '!')) != NULL) user[sep - user] = '\0';
                        if (where[0] == '#' || where[0] == '&' || where[0] == '+' || where[0] == '!') target = where; else target = user;
                        printf("[from: %s] [reply-with: %s] [where: %s] [reply-to: %s] %s", user, command, where, target, message);
                    }

This is where we handle PRIVMSG and NOTICE commands from the server. I'll let you figure out how you want to handle PRIVMSGs, but in essence this is where most command options would go. PRIVMSGs are used to send both private messages and messages to specific channels.

If you'd like to implement more commands, Wikipedia has a comprehensive list of commands (http://en.wikipedia.org/wiki/List_of_Internet_Relay_Chat_commands). This should get you started on simply connecting to the network and staying alive.
Title: Re: How to make a IRC bot
Post by: pimathbrainiac on February 09, 2015, 06:33:15 am
My little interjection is this: It is easier to program IRC bots with Java and Python than it is in C. Java has the awesome pircbotx library (http://code.google.com/p/pircbotx/), which I use, and Python has more than a few libraries making it easy.
Title: Re: How to make a IRC bot
Post by: Ephraim B on February 09, 2015, 10:27:56 am
Any tutorials for programming an IRC Bot in Python for Windows? The link to the Python IRC Bot tutorial is for Linux.
Title: Re: How to make a IRC bot
Post by: Hooloovoo on February 09, 2015, 10:29:29 am
Python is cross-platform. All of the code should be the same. Try googling if you still don't like it.
Title: Re: How to make a IRC bot
Post by: Sorunome on February 09, 2015, 12:11:37 pm
Any python program for linux will also run on windows.
You'll just have to install the python interpreter on windows.
Just download it here: https://www.python.org/downloads/
I'd recommend you to use 3.4.2
Title: Re: How to make a IRC bot
Post by: Ephraim B on February 09, 2015, 12:19:12 pm
The tutorial is showing setting up Python with the terminal. I want to know how to do this in Windows.
Title: Re: How to make a IRC bot
Post by: Hooloovoo on February 09, 2015, 12:25:51 pm
WE ARE NOT A SEARCH ENGINE! If you need help installing Python on windows, a simple search will get you there.

Tutorials are also not meant to be followed by typing in exactly what they say; you should read a section, experiment, and continue when you understand the section.
Title: Re: How to make a IRC bot
Post by: Sorunome on February 09, 2015, 12:27:44 pm
Just download that thing and run the install file.
Later on just rightclick your py file and open with....python
Title: Re: How to make a IRC bot
Post by: alberthrocks on February 09, 2015, 12:29:23 pm
The tutorial is showing setting up Python with the terminal. I want to know how to do this in Windows.

Ignore this: [/list][/list]
Title: Re: How to make a IRC bot
Post by: TIfanx1999 on February 09, 2015, 02:36:30 pm
The tutorial is showing setting up Python with the terminal. I want to know how to do this in Windows.

This is getting ridiculous. Python.org has a plethora of information. It's literally my second search result in Google. If you can't even figure out how to install python, you probably aren't going to have any success programming. You've also gotten plenty of information on how to proceed in this thread. Pick a path and start with it. Don't expect people to do everything for you.
Title: Re: How to make a IRC bot
Post by: Ephraim B on February 10, 2015, 08:57:11 am
This Python IRC Bot tutorial is not only making me download Python but also git. Is there a Python IRC Bot tutorial that I can do everything the Windows way (create new folder in File Explorer) and not the Linux way (mkdir Project)? I don't know where everything is.
Title: Re: How to make a IRC bot
Post by: Sorunome on February 10, 2015, 09:35:28 am
What about this one? http://forum.codecall.net/topic/59608-developing-a-basic-irc-bot-with-python/

Just try to https://www.google.de/search?q=how+to+make+a+python+irc+bot
Title: Re: How to make a IRC bot
Post by: Ephraim B on February 10, 2015, 09:39:40 am
I'm struggling setting up Python and the directories. I want to make the directories through File Explorer, not Powershell.
Title: Re: How to make a IRC bot
Post by: bb010g on February 10, 2015, 09:51:52 am
I want to make the directories through File Explorer, not Powershell.
I don't think anybody's stopping you from doing so.
Title: Re: How to make a IRC bot
Post by: TravisE on February 10, 2015, 10:23:35 am
Which tutorial mentions PowerShell? You can create directories with anything you want.

If the terminal is an issue, there are GUI Python shells available. Python used to come with IDLE, I think, or it was available separately. I don't know if that is still a thing now. I haven't really used Windows in 11 or so years, so I have no idea what's available now on the Windows side.
Title: Re: How to make a IRC bot
Post by: Ephraim B on February 18, 2015, 08:42:12 pm
Is it possible to download and put the bots DoorsCS and worm to my channel?
Title: Re: How to make a IRC bot
Post by: Sorunome on February 19, 2015, 06:12:30 am
If they are open source, yes. You could ask the writers of the bots for that.