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@1:cf586c9bbb52, 2014-08-02 (annotated)
- Committer:
- NickRyder
- Date:
- Sat Aug 02 12:17:28 2014 +0000
- Revision:
- 1:cf586c9bbb52
- Parent:
- irc.cpp@0:b8fb2df56652
- Child:
- 2:e4c74eb20586
Renaming files.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
NickRyder | 1:cf586c9bbb52 | 1 | #include "IrcBot.h" |
NickRyder | 0:b8fb2df56652 | 2 | |
NickRyder | 0:b8fb2df56652 | 3 | IrcMessage::IrcMessage(char * f, char * t, char * m) { |
NickRyder | 0:b8fb2df56652 | 4 | sprintf(from, "%s", f); |
NickRyder | 0:b8fb2df56652 | 5 | sprintf(to, "%s", t); |
NickRyder | 0:b8fb2df56652 | 6 | sprintf(msg, "%s", m); |
NickRyder | 0:b8fb2df56652 | 7 | } |
NickRyder | 0:b8fb2df56652 | 8 | |
NickRyder | 0:b8fb2df56652 | 9 | IrcMessage::IrcMessage() { |
NickRyder | 0:b8fb2df56652 | 10 | from[0] = '\0'; |
NickRyder | 0:b8fb2df56652 | 11 | to[0] = '\0'; |
NickRyder | 0:b8fb2df56652 | 12 | msg[0] = '\0'; |
NickRyder | 0:b8fb2df56652 | 13 | } |
NickRyder | 0:b8fb2df56652 | 14 | |
NickRyder | 0:b8fb2df56652 | 15 | Irc::Irc(char * nick, char * net, int p, char * chan) : |
NickRyder | 0:b8fb2df56652 | 16 | pc(USBTX, USBRX), sock(), port(p), ident(false), connected(false), |
NickRyder | 0:b8fb2df56652 | 17 | setup(false), joined(false), parseindex(0) |
NickRyder | 0:b8fb2df56652 | 18 | { |
NickRyder | 0:b8fb2df56652 | 19 | sprintf(nickname, "%s", nick); |
NickRyder | 0:b8fb2df56652 | 20 | sprintf(password, "%s", ""); |
NickRyder | 0:b8fb2df56652 | 21 | sprintf(network, "%s", net); |
NickRyder | 0:b8fb2df56652 | 22 | sprintf(channel, "%s", chan); |
NickRyder | 0:b8fb2df56652 | 23 | pc.printf("Created Irc obj for %s.\n", nickname); |
NickRyder | 0:b8fb2df56652 | 24 | } |
NickRyder | 0:b8fb2df56652 | 25 | |
NickRyder | 0:b8fb2df56652 | 26 | void Irc::identify(char * pass) { |
NickRyder | 0:b8fb2df56652 | 27 | ident = true; |
NickRyder | 0:b8fb2df56652 | 28 | sprintf(password, "%s", pass); |
NickRyder | 0:b8fb2df56652 | 29 | } |
NickRyder | 0:b8fb2df56652 | 30 | |
NickRyder | 0:b8fb2df56652 | 31 | void Irc::join(char * chan) { |
NickRyder | 0:b8fb2df56652 | 32 | char cmd[64]; |
NickRyder | 0:b8fb2df56652 | 33 | sprintf(cmd, ":source JOIN :%s\r\n", chan); |
NickRyder | 0:b8fb2df56652 | 34 | send(cmd); |
NickRyder | 0:b8fb2df56652 | 35 | } |
NickRyder | 0:b8fb2df56652 | 36 | |
NickRyder | 0:b8fb2df56652 | 37 | void Irc::connect() { |
NickRyder | 0:b8fb2df56652 | 38 | pc.printf("Connecting to %s:%d...\n", network, port); |
NickRyder | 0:b8fb2df56652 | 39 | sock.connect(network, port); |
NickRyder | 0:b8fb2df56652 | 40 | pc.printf("Done.\n"); |
NickRyder | 0:b8fb2df56652 | 41 | connected = true; |
NickRyder | 0:b8fb2df56652 | 42 | } |
NickRyder | 0:b8fb2df56652 | 43 | |
NickRyder | 0:b8fb2df56652 | 44 | void Irc::disconnect() { |
NickRyder | 0:b8fb2df56652 | 45 | if (connected) { |
NickRyder | 0:b8fb2df56652 | 46 | pc.printf("Disconnecting.\n"); |
NickRyder | 0:b8fb2df56652 | 47 | sock.close(); |
NickRyder | 0:b8fb2df56652 | 48 | connected = false; |
NickRyder | 0:b8fb2df56652 | 49 | } |
NickRyder | 0:b8fb2df56652 | 50 | } |
NickRyder | 0:b8fb2df56652 | 51 | |
NickRyder | 0:b8fb2df56652 | 52 | void Irc::add(MessageHandler * handler) { |
NickRyder | 0:b8fb2df56652 | 53 | handlers.push_back(handler); |
NickRyder | 0:b8fb2df56652 | 54 | } |
NickRyder | 0:b8fb2df56652 | 55 | |
NickRyder | 0:b8fb2df56652 | 56 | bool Irc::read() { |
NickRyder | 0:b8fb2df56652 | 57 | if (!connected) return 0; |
NickRyder | 0:b8fb2df56652 | 58 | int ret = sock.receive(readbuffer, sizeof(readbuffer) - 1); |
NickRyder | 0:b8fb2df56652 | 59 | bool parsed = false; |
NickRyder | 0:b8fb2df56652 | 60 | if (ret >= 0) { |
NickRyder | 0:b8fb2df56652 | 61 | readbuffer[ret] = '\0'; |
NickRyder | 0:b8fb2df56652 | 62 | pc.printf("Received %d chars: ---%s--\n", ret, readbuffer); |
NickRyder | 0:b8fb2df56652 | 63 | for (int i = 0; i < ret; i++) { |
NickRyder | 0:b8fb2df56652 | 64 | parsebuffer[parseindex] = readbuffer[i]; |
NickRyder | 0:b8fb2df56652 | 65 | parseindex++; |
NickRyder | 0:b8fb2df56652 | 66 | if (readbuffer[i] == '\n') { |
NickRyder | 0:b8fb2df56652 | 67 | parsebuffer[parseindex] = '\0'; |
NickRyder | 0:b8fb2df56652 | 68 | parse(); |
NickRyder | 0:b8fb2df56652 | 69 | parsed = true; |
NickRyder | 0:b8fb2df56652 | 70 | parseindex = 0; |
NickRyder | 0:b8fb2df56652 | 71 | } |
NickRyder | 0:b8fb2df56652 | 72 | } |
NickRyder | 0:b8fb2df56652 | 73 | } |
NickRyder | 0:b8fb2df56652 | 74 | return parsed; |
NickRyder | 0:b8fb2df56652 | 75 | } |
NickRyder | 0:b8fb2df56652 | 76 | |
NickRyder | 0:b8fb2df56652 | 77 | void Irc::send(char * cmd) { |
NickRyder | 0:b8fb2df56652 | 78 | if (!connected) return; |
NickRyder | 0:b8fb2df56652 | 79 | int i = 0; |
NickRyder | 0:b8fb2df56652 | 80 | bool ok = true; |
NickRyder | 0:b8fb2df56652 | 81 | while (cmd[i] != '\0') { |
NickRyder | 0:b8fb2df56652 | 82 | i++; |
NickRyder | 0:b8fb2df56652 | 83 | if (i > 512) { |
NickRyder | 0:b8fb2df56652 | 84 | ok = false; |
NickRyder | 0:b8fb2df56652 | 85 | break; |
NickRyder | 0:b8fb2df56652 | 86 | } |
NickRyder | 0:b8fb2df56652 | 87 | } |
NickRyder | 0:b8fb2df56652 | 88 | if (!ok) return; |
NickRyder | 0:b8fb2df56652 | 89 | pc.printf("Sending: ---%s---\n", cmd); |
NickRyder | 0:b8fb2df56652 | 90 | sock.send_all(cmd, i); |
NickRyder | 0:b8fb2df56652 | 91 | } |
NickRyder | 0:b8fb2df56652 | 92 | |
NickRyder | 0:b8fb2df56652 | 93 | void Irc::handle(IrcMessage msg) { |
NickRyder | 0:b8fb2df56652 | 94 | pc.printf("Handling message from %s, to %s: %s\n", msg.from, msg.to, msg.msg); |
NickRyder | 0:b8fb2df56652 | 95 | for (int i = 0; i < handlers.size(); i++) { |
NickRyder | 0:b8fb2df56652 | 96 | IrcMessage out = handlers.at(i)->handle(msg); |
NickRyder | 0:b8fb2df56652 | 97 | if (out.to[0] != '\0') { |
NickRyder | 0:b8fb2df56652 | 98 | sprintf(out.from, "%s", nickname); |
NickRyder | 0:b8fb2df56652 | 99 | pc.printf("Need to send: ---%s--- from %s to %s.\n", out.msg, out.from, out.to); |
NickRyder | 0:b8fb2df56652 | 100 | char cmd[512]; |
NickRyder | 0:b8fb2df56652 | 101 | sprintf(cmd, "PRIVMSG %s :%s\r\n", out.to, out.msg); |
NickRyder | 0:b8fb2df56652 | 102 | send(cmd); |
NickRyder | 0:b8fb2df56652 | 103 | } |
NickRyder | 0:b8fb2df56652 | 104 | } |
NickRyder | 0:b8fb2df56652 | 105 | } |
NickRyder | 0:b8fb2df56652 | 106 | |
NickRyder | 0:b8fb2df56652 | 107 | void Irc::parse() { |
NickRyder | 0:b8fb2df56652 | 108 | pc.printf("Parsing: --%s--\n", parsebuffer); |
NickRyder | 0:b8fb2df56652 | 109 | if (setup && (!joined)) { |
NickRyder | 0:b8fb2df56652 | 110 | char cmd[256]; |
NickRyder | 0:b8fb2df56652 | 111 | sprintf(cmd, ":source JOIN :%s\r\n", channel); |
NickRyder | 0:b8fb2df56652 | 112 | send(cmd); |
NickRyder | 0:b8fb2df56652 | 113 | joined = true; |
NickRyder | 0:b8fb2df56652 | 114 | return; |
NickRyder | 0:b8fb2df56652 | 115 | } |
NickRyder | 0:b8fb2df56652 | 116 | if (!setup) { |
NickRyder | 0:b8fb2df56652 | 117 | char cmd[256]; |
NickRyder | 0:b8fb2df56652 | 118 | sprintf(cmd, "NICK %s\r\nUSER %s 0 * :Lester\r\n", nickname, nickname); |
NickRyder | 0:b8fb2df56652 | 119 | send(cmd); |
NickRyder | 0:b8fb2df56652 | 120 | setup = true; |
NickRyder | 0:b8fb2df56652 | 121 | return; |
NickRyder | 0:b8fb2df56652 | 122 | } |
NickRyder | 0:b8fb2df56652 | 123 | char * c = NULL; |
NickRyder | 0:b8fb2df56652 | 124 | c = strstr(parsebuffer, "PING"); |
NickRyder | 0:b8fb2df56652 | 125 | if (c != NULL) { |
NickRyder | 0:b8fb2df56652 | 126 | char cmd[] = "PONG\r\n"; |
NickRyder | 0:b8fb2df56652 | 127 | send(cmd); |
NickRyder | 0:b8fb2df56652 | 128 | } |
NickRyder | 0:b8fb2df56652 | 129 | c = strstr(parsebuffer, "PRIVMSG"); |
NickRyder | 0:b8fb2df56652 | 130 | if (c != NULL) { |
NickRyder | 0:b8fb2df56652 | 131 | char f[32]; |
NickRyder | 0:b8fb2df56652 | 132 | char t[32]; |
NickRyder | 0:b8fb2df56652 | 133 | char m[256]; |
NickRyder | 0:b8fb2df56652 | 134 | int i; |
NickRyder | 0:b8fb2df56652 | 135 | for (i = 1; i < 32; i++) { |
NickRyder | 0:b8fb2df56652 | 136 | if (parsebuffer[i] == '!') { |
NickRyder | 0:b8fb2df56652 | 137 | f[i - 1] = '\0'; |
NickRyder | 0:b8fb2df56652 | 138 | break; |
NickRyder | 0:b8fb2df56652 | 139 | } |
NickRyder | 0:b8fb2df56652 | 140 | f[i - 1] = parsebuffer[i]; |
NickRyder | 0:b8fb2df56652 | 141 | } |
NickRyder | 0:b8fb2df56652 | 142 | int nspace = 0; |
NickRyder | 0:b8fb2df56652 | 143 | bool inmsg = false; |
NickRyder | 0:b8fb2df56652 | 144 | int toindex = 0, msgindex = 0; |
NickRyder | 0:b8fb2df56652 | 145 | for (; i < sizeof(parsebuffer); i++) { |
NickRyder | 0:b8fb2df56652 | 146 | if (parsebuffer[i] == '\r') break; |
NickRyder | 0:b8fb2df56652 | 147 | if (parsebuffer[i] == '\n') break; |
NickRyder | 0:b8fb2df56652 | 148 | if (parsebuffer[i] == '\0') break; |
NickRyder | 0:b8fb2df56652 | 149 | if (parsebuffer[i] == ' ') { |
NickRyder | 0:b8fb2df56652 | 150 | nspace++; |
NickRyder | 0:b8fb2df56652 | 151 | } |
NickRyder | 0:b8fb2df56652 | 152 | if ((nspace == 2) && (parsebuffer[i] != ' ')) { |
NickRyder | 0:b8fb2df56652 | 153 | t[toindex] = parsebuffer[i]; |
NickRyder | 0:b8fb2df56652 | 154 | toindex++; |
NickRyder | 0:b8fb2df56652 | 155 | } |
NickRyder | 0:b8fb2df56652 | 156 | if (inmsg) { |
NickRyder | 0:b8fb2df56652 | 157 | m[msgindex] = parsebuffer[i]; |
NickRyder | 0:b8fb2df56652 | 158 | msgindex++; |
NickRyder | 0:b8fb2df56652 | 159 | } |
NickRyder | 0:b8fb2df56652 | 160 | if ((parsebuffer[i] == ':') && (!inmsg)) { |
NickRyder | 0:b8fb2df56652 | 161 | inmsg = true; |
NickRyder | 0:b8fb2df56652 | 162 | } |
NickRyder | 0:b8fb2df56652 | 163 | } |
NickRyder | 0:b8fb2df56652 | 164 | t[toindex] = '\0'; |
NickRyder | 0:b8fb2df56652 | 165 | m[msgindex] = '\0'; |
NickRyder | 0:b8fb2df56652 | 166 | IrcMessage msg(f, t, m); |
NickRyder | 0:b8fb2df56652 | 167 | handle(msg); |
NickRyder | 0:b8fb2df56652 | 168 | } |
NickRyder | 0:b8fb2df56652 | 169 | } |