summaryrefslogtreecommitdiff
path: root/bouncer
diff options
context:
space:
mode:
Diffstat (limited to 'bouncer')
-rw-r--r--bouncer/core.h3
-rw-r--r--bouncer/ircserver.cpp57
-rw-r--r--bouncer/window.cpp37
3 files changed, 97 insertions, 0 deletions
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())