summary refs log tree commit diff
diff options
context:
space:
mode:
authorC. McEnroe2020-02-20 04:18:25 -0500
committerC. McEnroe2020-02-20 04:18:25 -0500
commitc2c8595012a8fa7878ddc7f48569417402736360 (patch)
tree6dea486d1efb36bf962c2bac7def112d4678f071
parenta5cd2cd97ae18c3723c9edfecc946f98ebce090c (diff)
Handle MODE setting channel prefix modes
-rw-r--r--handle.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/handle.c b/handle.c
index 7dfd85a..a2d0ddd 100644
--- a/handle.c
+++ b/handle.c
@@ -240,6 +240,7 @@ static void handleReplyISupport(struct Message *msg) {
 			strsep(&msg->params[i], "(");
 			set(&network.prefixModes, strsep(&msg->params[i], ")"));
 			set(&network.prefixes, msg->params[i]);
+			assert(strlen(network.prefixes) == strlen(network.prefixModes));
 		} else if (!strcmp(key, "CHANMODES")) {
 			set(&network.listModes, strsep(&msg->params[i], ","));
 			set(&network.paramModes, strsep(&msg->params[i], ","));
@@ -484,6 +485,45 @@ static void handleTopic(struct Message *msg) {
 	}
 }
 
+static void handleMode(struct Message *msg) {
+	require(msg, true, 2);
+	if (!strchr(network.chanTypes, msg->params[0][0])) {
+		// TODO: User mode changes.
+		return;
+	}
+	uint id = idFor(msg->params[0]);
+	bool set = false;
+	uint param = 2;
+	for (char *ch = msg->params[1]; *ch; ++ch) {
+		if (*ch == '+') {
+			set = true;
+		} else if (*ch == '-') {
+			set = false;
+		} else if (strchr(network.prefixModes, *ch)) {
+			assert(param < ParamCap);
+			char *nick = msg->params[param++];
+			char *mode = strchr(network.prefixModes, *ch);
+			char prefix = network.prefixes[mode - network.prefixModes];
+			// TODO: Invert nick if targeting self?
+			uiFormat(
+				id, (!strcmp(nick, self.nick) ? Hot : Cold), tagTime(msg),
+				"\3%02d%s\3\t%s \3%02d%c%s\3",
+				hash(msg->user), msg->nick,
+				(set ? "grants" : "revokes"),
+				completeColor(id, nick), prefix, nick
+			);
+		} else if (strchr(network.listModes, *ch)) {
+			// TODO
+		} else if (strchr(network.paramModes, *ch)) {
+			// TODO
+		} else if (strchr(network.setParamModes, *ch)) {
+			// TODO
+		} else {
+			// TODO
+		}
+	}
+}
+
 static void handleErrorUserNotInChannel(struct Message *msg) {
 	require(msg, false, 4);
 	uiFormat(
@@ -828,6 +868,7 @@ static const struct Handler {
 	{ "INVITE", handleInvite },
 	{ "JOIN", handleJoin },
 	{ "KICK", handleKick },
+	{ "MODE", handleMode },
 	{ "NICK", handleNick },
 	{ "NOTICE", handlePrivmsg },
 	{ "PART", handlePart },