diff options
Diffstat (limited to 'bouncer')
-rw-r--r-- | bouncer/core.h | 2 | ||||
-rw-r--r-- | bouncer/ircserver.cpp | 86 | ||||
-rw-r--r-- | bouncer/window.cpp | 44 |
3 files changed, 129 insertions, 3 deletions
diff --git a/bouncer/core.h b/bouncer/core.h index 5a43215..a0b9cfe 100644 --- a/bouncer/core.h +++ b/bouncer/core.h @@ -103,6 +103,7 @@ public: void handleNick(const UserRef &user, const char *newNick); void handleMode(const UserRef &user, const char *str); void handlePrivmsg(const UserRef &user, const char *str); + void handleCtcp(const UserRef &user, const char *type, const char *params); void handleTopic(const UserRef &user, const char *message); void handleTopicInfo(const char *user, int timestamp); @@ -124,6 +125,7 @@ public: void handleQuit(const char *message); void handlePrivmsg(const char *str); + void handleCtcp(const char *type, const char *params); void showNickChange(const UserRef &user, const char *newNick); void renamePartner(const char *_partner); diff --git a/bouncer/ircserver.cpp b/bouncer/ircserver.cpp index b1e541a..818478f 100644 --- a/bouncer/ircserver.cpp +++ b/bouncer/ircserver.cpp @@ -310,16 +310,96 @@ void IRCServer::lineReceivedEvent(char *line, int size) { } } else if (strcmp(cmdBuf, "PRIVMSG") == 0) { + + int endPos = strlen(paramsAfterFirst) - 1; + bool requireQueryWindow = true; + const char *ctcpType = NULL, *ctcpParams = NULL; + + if ((endPos > 0) && + (paramsAfterFirst[0] == 1) && + (paramsAfterFirst[endPos] == 1)) + { + // Try to parse a CTCP + // Cut off the 01 char at the end + paramsAfterFirst[endPos] = 0; + + // Split the string into type + params + char *space = strchr(paramsAfterFirst, ' '); + + ctcpType = ¶msAfterFirst[1]; + + if (space) { + *space = 0; + ctcpParams = space + 1; + } else { + ctcpParams = ""; + } + + if (strcmp(ctcpType, "ACTION") != 0) + requireQueryWindow = false; + + // This needs to be extracted into a separate + // method at some point + if (strcmp(ctcpType, "VERSION") == 0) { + char reply[1000]; + snprintf(reply, sizeof(reply), + "NOTICE %s :\x01VERSION boop:boop:boop\x01", + user.nick.c_str()); + sendLine(reply); + + } else if (strcmp(ctcpType, "PING") == 0) { + char reply[1000]; + snprintf(reply, sizeof(reply), + "NOTICE %s :\x01PING %s\x01", + user.nick.c_str(), + ctcpParams); + sendLine(reply); + + } else if (strcmp(ctcpType, "TIME") == 0) { + char reply[1000], formatTime[200]; + time_t now = time(NULL); + tm *nowtm = localtime(&now); + + strftime(formatTime, sizeof(formatTime), + "%c", nowtm); + + snprintf(reply, sizeof(reply), + "NOTICE %s :\x01TIME :%s\x01", + user.nick.c_str(), + formatTime); + sendLine(reply); + } + } + + if (strcmp(targetBuf, currentNick) == 0) { - Query *q = findQuery(user.nick.c_str(), true); + Query *q = findQuery(user.nick.c_str(), requireQueryWindow); if (q) { - q->handlePrivmsg(paramsAfterFirst); + if (ctcpType) + q->handleCtcp(ctcpType, ctcpParams); + else + q->handlePrivmsg(paramsAfterFirst); + return; + } else if (ctcpType) { + // This CTCP didn't require a query window to be + // open, and we don't already have one, so + // dump a notification into the status window. + char buf[1000]; + snprintf(buf, sizeof(buf), + "CTCP from %s : %s %s", + user.nick.c_str(), + ctcpType, + ctcpParams); + status.pushMessage(buf); return; } } else { Channel *c = findChannel(targetBuf, true); if (c) { - c->handlePrivmsg(user, paramsAfterFirst); + if (ctcpType) + c->handleCtcp(user, ctcpType, ctcpParams); + else + c->handlePrivmsg(user, paramsAfterFirst); return; } } diff --git a/bouncer/window.cpp b/bouncer/window.cpp index dd22e7e..dbfe3b5 100644 --- a/bouncer/window.cpp +++ b/bouncer/window.cpp @@ -492,6 +492,30 @@ void Channel::handlePrivmsg(const UserRef &user, const char *str) { pushMessage(buf); } +void Channel::handleCtcp(const UserRef &user, const char *type, const char *params) { + char buf[15000]; + + if (strcmp(type, "ACTION") == 0) { + char prefix[2]; + prefix[0] = getEffectivePrefixChar(user.nick.c_str()); + prefix[1] = 0; + + snprintf(buf, sizeof(buf), + "* %s%s %s", + prefix, + user.nick.c_str(), + params); + + } else { + snprintf(buf, sizeof(buf), + "CTCP from %s : %s %s", + user.nick.c_str(), + type, + params); + } + + pushMessage(buf); +} @@ -643,6 +667,26 @@ void Query::handlePrivmsg(const char *str) { pushMessage(buf); } +void Query::handleCtcp(const char *type, const char *params) { + char buf[15000]; + + if (strcmp(type, "ACTION") == 0) { + snprintf(buf, sizeof(buf), + "* %s %s", + partner.c_str(), + params); + + } else { + snprintf(buf, sizeof(buf), + "CTCP from %s : %s %s", + partner.c_str(), + type, + params); + } + + pushMessage(buf); +} + void Query::renamePartner(const char *_partner) { Buffer packet; packet.writeU32(id); |