The IrcBot class can connect to a channel on an IRC network. Users on the same network can send messages to the bot that are parsed by message handlers. The included handlers read digital/analog inputs and write digital outputs or echo messages back to the command sender/channel. Users can write their own message handlers inheriting from the MessageHandler class to perform different actions.

IrcBot.cpp

Committer:
NickRyder
Date:
2014-08-02
Revision:
2:e4c74eb20586
Parent:
1:cf586c9bbb52

File content as of revision 2:e4c74eb20586:

#include "IrcBot.h"

IrcMessage::IrcMessage(char * f, char * t, char * m) {
    sprintf(from, "%s", f);
    sprintf(to, "%s", t);
    sprintf(msg, "%s", m);    
}

IrcMessage::IrcMessage() {
    from[0] = '\0';
    to[0] = '\0';
    msg[0] = '\0';
}

IrcBot::IrcBot(char * nick, char * net, int p, char * chan) :
        pc(USBTX, USBRX), sock(), port(p), ident(false), connected(false),
        setup(false), joined(false), parseindex(0)
{
    sprintf(nickname, "%s", nick);
    sprintf(password, "%s", "");
    sprintf(network, "%s", net);
    sprintf(channel, "%s", chan);
    pc.printf("Created IrcBot obj for %s.\n", nickname);
}

void IrcBot::connect() {
    pc.printf("Connecting to %s:%d...\n", network, port);
    sock.connect(network, port);
    pc.printf("Done.\n");
    connected = true;
}

void IrcBot::disconnect() {
    if (connected) {
        pc.printf("Disconnecting.\n");
        sock.close();
        connected = false;
    }
}

void IrcBot::add(MessageHandler * handler) {
    handlers.push_back(handler);
}

bool IrcBot::read() {
    if (!connected) return 0;
    int ret = sock.receive(readbuffer, sizeof(readbuffer) - 1);
    bool parsed = false;
    if (ret >= 0) {
        readbuffer[ret] = '\0';
        pc.printf("Received %d chars: ---%s--\n", ret, readbuffer);
        for (int i = 0; i < ret; i++) {
            parsebuffer[parseindex] = readbuffer[i];
            parseindex++;
            if (readbuffer[i] == '\n') {
                parsebuffer[parseindex] = '\0';
                parse();
                parsed = true;
                parseindex = 0;
            }
        }
    }
    return parsed;
}

void IrcBot::send(char * cmd) {
    if (!connected) return;
    int i = 0;
    bool ok = true;
    while (cmd[i] != '\0') {
        i++;
        if (i > 512) {
            ok = false;
            break;    
        }  
    }
    if (!ok) return;
    pc.printf("Sending: ---%s---\n", cmd);
    sock.send_all(cmd, i);
}

void IrcBot::handle(IrcMessage msg) {
    pc.printf("Handling message from %s, to %s: %s\n", msg.from, msg.to, msg.msg);    
    for (int i = 0; i < handlers.size(); i++) {
        IrcMessage out = handlers.at(i)->handle(msg);
        if (out.to[0] != '\0') {
            sprintf(out.from, "%s", nickname);
            pc.printf("Need to send: ---%s--- from %s to %s.\n", out.msg, out.from, out.to);
            char cmd[512];
            sprintf(cmd, "PRIVMSG %s :%s\r\n", out.to, out.msg);
            send(cmd);
        }
    }
}

void IrcBot::parse() {
    pc.printf("Parsing: --%s--\n", parsebuffer);
    if (setup && (!joined)) {
        char cmd[256];
        sprintf(cmd, ":source JOIN :%s\r\n", channel);
        send(cmd);
        joined = true;
        return;   
    }
    if (!setup) {
        char cmd[256];
        sprintf(cmd, "NICK %s\r\nUSER %s 0 * :Lester\r\n", nickname, nickname);
        send(cmd);
        setup = true;
        return;
    }
    char * c = NULL;
    c = strstr(parsebuffer, "PING");
    if (c != NULL) {
        char cmd[] = "PONG\r\n";
        send(cmd);    
    }
    c = strstr(parsebuffer, "PRIVMSG");
    if (c != NULL) {
        char f[32];
        char t[32];
        char m[256];
        int i;
        for (i = 1; i < 32; i++) {
            if (parsebuffer[i] == '!') {
                f[i - 1] = '\0';    
                break;
            }
            f[i - 1] = parsebuffer[i];   
        }
        int nspace = 0;
        bool inmsg = false;
        int toindex = 0, msgindex = 0;
        for (; i < sizeof(parsebuffer); i++) {
            if (parsebuffer[i] == '\r') break;
            if (parsebuffer[i] == '\n') break;
            if (parsebuffer[i] == '\0') break;
            if (parsebuffer[i] == ' ') {
                nspace++;    
            }
            if ((nspace == 2) && (parsebuffer[i] != ' ')) {
                t[toindex] = parsebuffer[i];
                toindex++;
            }
            if (inmsg) {
                m[msgindex] = parsebuffer[i];
                msgindex++;    
            }
            if ((parsebuffer[i] == ':') && (!inmsg)) {
                inmsg = true;
            }
        }
        t[toindex] = '\0';
        m[msgindex] = '\0';
        IrcMessage msg(f, t, m);
        handle(msg);
    }
}