summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreeki <treeki@gmail.com>2014-01-25 01:34:11 +0100
committerTreeki <treeki@gmail.com>2014-01-25 01:34:11 +0100
commitbdbdb57fc3ae81c0dbb46c4e6ffdd6c0205a81c0 (patch)
tree452d25a6fc233199272c634c42a4f72c46af2488
parentf83687cc5e99d66153c296e7632b88de2594b79d (diff)
downloadbounce4-bdbdb57fc3ae81c0dbb46c4e6ffdd6c0205a81c0.tar.gz
bounce4-bdbdb57fc3ae81c0dbb46c4e6ffdd6c0205a81c0.zip
add channel topic tracking
-rw-r--r--bouncer/core.h3
-rw-r--r--bouncer/ircserver.cpp57
-rw-r--r--bouncer/window.cpp37
-rw-r--r--python_client.py18
4 files changed, 113 insertions, 2 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())
diff --git a/python_client.py b/python_client.py
index 11c4a50..4e7f1a3 100644
--- a/python_client.py
+++ b/python_client.py
@@ -61,7 +61,7 @@ def reader():
pos = 0
bufsize = len(readbuf)
- print('[bufsize: %d]' % bufsize)
+ #print('[bufsize: %d]' % bufsize)
while True:
if (pos + 8) > bufsize:
break
@@ -107,7 +107,7 @@ def reader():
pos += size
- print('[processed %d bytes]' % pos)
+ #print('[processed %d bytes]' % pos)
readbuf = readbuf[pos:]
def writePacket(type, data, allowUnauthed=False):
@@ -179,11 +179,14 @@ class ChannelTab(WindowTab):
def __init__(self, parent=None):
WindowTab.__init__(self, parent)
+ self.topicLabel = QtWidgets.QLabel(self)
+ self.topicLabel.setWordWrap(True)
self.userList = QtWidgets.QListWidget(self)
self.users = {}
def makeLayout(self):
sublayout = QtWidgets.QVBoxLayout()
+ sublayout.addWidget(self.topicLabel)
sublayout.addWidget(self.output)
sublayout.addWidget(self.input)
@@ -217,6 +220,8 @@ class ChannelTab(WindowTab):
self.topic = pdata[pos:pos+topiclen].decode('utf-8', 'replace')
pos += topiclen
+ self.topicLabel.setText(self.topic)
+
return pos
def addUsers(self, pdata):
@@ -284,6 +289,11 @@ class ChannelTab(WindowTab):
uo.prefix = prefix
uo.syncItemText()
+ def changeTopic(self, pdata):
+ tlen = u32.unpack_from(pdata, 4)[0]
+ self.topic = pdata[8:8+tlen].decode('utf-8', 'replace')
+ self.topicLabel.setText(self.topic)
+
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
@@ -370,6 +380,10 @@ class MainWindow(QtWidgets.QMainWindow):
# Change user modes in channel
wndID = u32.unpack_from(pdata, 0)[0]
self.tabLookup[wndID].changeUserMode(pdata)
+ elif ptype == 0x124:
+ # Change topic in channel
+ wndID = u32.unpack_from(pdata, 0)[0]
+ self.tabLookup[wndID].changeTopic(pdata)
return True
else: