summaryrefslogtreecommitdiff
path: root/bouncer
diff options
context:
space:
mode:
Diffstat (limited to 'bouncer')
-rw-r--r--bouncer/core.h2
-rw-r--r--bouncer/ircserver.cpp86
-rw-r--r--bouncer/window.cpp44
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 = &paramsAfterFirst[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);