diff options
| author | Treeki <treeki@gmail.com> | 2014-01-25 01:34:11 +0100 | 
|---|---|---|
| committer | Treeki <treeki@gmail.com> | 2014-01-25 01:34:11 +0100 | 
| commit | bdbdb57fc3ae81c0dbb46c4e6ffdd6c0205a81c0 (patch) | |
| tree | 452d25a6fc233199272c634c42a4f72c46af2488 | |
| parent | f83687cc5e99d66153c296e7632b88de2594b79d (diff) | |
| download | bounce4-bdbdb57fc3ae81c0dbb46c4e6ffdd6c0205a81c0.tar.gz bounce4-bdbdb57fc3ae81c0dbb46c4e6ffdd6c0205a81c0.zip  | |
add channel topic tracking
Diffstat (limited to '')
| -rw-r--r-- | bouncer/core.h | 3 | ||||
| -rw-r--r-- | bouncer/ircserver.cpp | 57 | ||||
| -rw-r--r-- | bouncer/window.cpp | 37 | ||||
| -rw-r--r-- | python_client.py | 18 | 
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:  | 
