From bdbdb57fc3ae81c0dbb46c4e6ffdd6c0205a81c0 Mon Sep 17 00:00:00 2001 From: Treeki Date: Sat, 25 Jan 2014 01:34:11 +0100 Subject: add channel topic tracking --- bouncer/core.h | 3 +++ bouncer/ircserver.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ bouncer/window.cpp | 37 +++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+) (limited to 'bouncer') diff --git a/bouncer/core.h b/bouncer/core.h index 7236ff7..1d6b9db 100644 --- a/bouncer/core.h +++ b/bouncer/core.h @@ -102,6 +102,8 @@ 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 handleTopic(const UserRef &user, const char *message); + void handleTopicInfo(const char *user, int timestamp); char getEffectivePrefixChar(const char *nick) const; @@ -173,6 +175,7 @@ struct Packet { B2C_CHANNEL_USER_REMOVE = 0x121, B2C_CHANNEL_USER_RENAME = 0x122, B2C_CHANNEL_USER_MODES = 0x123, + B2C_CHANNEL_TOPIC = 0x124, C2B_OOB_LOGIN = 0x8001, diff --git a/bouncer/ircserver.cpp b/bouncer/ircserver.cpp index ecf5c64..3b09d49 100644 --- a/bouncer/ircserver.cpp +++ b/bouncer/ircserver.cpp @@ -233,6 +233,13 @@ void IRCServer::lineReceivedEvent(char *line, int size) { return; } + } else if (strcmp(cmdBuf, "TOPIC") == 0) { + Channel *c = findChannel(targetBuf, false); + if (c) { + c->handleTopic(user, paramsAfterFirst); + return; + } + } else if (strcmp(cmdBuf, "PRIVMSG") == 0) { Channel *c = findChannel(targetBuf, true); if (c) { @@ -251,6 +258,56 @@ void IRCServer::lineReceivedEvent(char *line, int size) { processISupport(paramsAfterFirst); return; + } else if (strcmp(cmdBuf, "331") == 0) { + // RPL_NOTOPIC: + // Params: Channel name, *maybe* text we can ignore + + char *space = strchr(paramsAfterFirst, ' '); + if (space) + *space = 0; + + Channel *c = findChannel(paramsAfterFirst, false); + if (c) { + c->handleTopic(UserRef(), ""); + return; + } + + } else if (strcmp(cmdBuf, "332") == 0) { + // RPL_TOPIC: + // Params: Channel name, text + + char *space = strchr(paramsAfterFirst, ' '); + if (space) { + *space = 0; + + char *topic = space + 1; + if (*topic == ':') + ++topic; + + Channel *c = findChannel(paramsAfterFirst, false); + if (c) { + c->handleTopic(UserRef(), topic); + return; + } + } + + } else if (strcmp(cmdBuf, "333") == 0) { + // Topic set + + char *strtok_var; + char *chanName = strtok_r(paramsAfterFirst, " ", &strtok_var); + char *setBy = strtok_r(NULL, " ", &strtok_var); + char *when = strtok_r(NULL, " ", &strtok_var); + + if (chanName && setBy && when) { + Channel *c = findChannel(chanName, false); + + if (c) { + c->handleTopicInfo(setBy, atoi(when)); + return; + } + } + } else if (strcmp(cmdBuf, "353") == 0) { // RPL_NAMEREPLY: // Target is always us diff --git a/bouncer/window.cpp b/bouncer/window.cpp index bf50325..5371176 100644 --- a/bouncer/window.cpp +++ b/bouncer/window.cpp @@ -447,6 +447,43 @@ void Channel::handlePrivmsg(const UserRef &user, const char *str) { } + + +void Channel::handleTopic(const UserRef &user, const char *message) { + char buf[1024]; + + if (user.isValid) { + snprintf(buf, sizeof(buf), + "%s changed the topic to: %s", + user.nick.c_str(), + message); + } else { + snprintf(buf, sizeof(buf), + "Topic: %s", + message); + } + pushMessage(buf); + + topic = message; + + Buffer packet; + packet.writeU32(id); + packet.writeStr(message); + server->bouncer->sendToClients( + Packet::B2C_CHANNEL_TOPIC, packet); +} + +void Channel::handleTopicInfo(const char *user, int timestamp) { + char buf[1024]; + snprintf(buf, sizeof(buf), + "Topic set by %s at %d", + user, + timestamp); + pushMessage(buf); +} + + + char Channel::getEffectivePrefixChar(const char *nick) const { auto i = users.find(nick); if (i == users.end()) -- cgit v1.2.3