degesch: process CTCP in PRIVMSG
Finally we can display /me.
This commit is contained in:
		
							
								
								
									
										66
									
								
								degesch.c
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								degesch.c
									
									
									
									
									
								
							@@ -2631,42 +2631,86 @@ irc_handle_ping (struct app_context *ctx, const struct irc_message *msg)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
irc_handle_privmsg (struct app_context *ctx, const struct irc_message *msg)
 | 
					irc_handle_ctcp_request (struct app_context *ctx,
 | 
				
			||||||
 | 
						const struct irc_message *msg, struct ctcp_chunk *chunk)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!msg->prefix || msg->params.len < 2)
 | 
						char *nickname = irc_cut_nickname (msg->prefix);
 | 
				
			||||||
		return;
 | 
						char *nickname_utf8 = irc_to_utf8 (ctx, nickname);
 | 
				
			||||||
 | 
						free (nickname);
 | 
				
			||||||
 | 
						char *tag_utf8 = irc_to_utf8 (ctx, chunk->tag.str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const char *target = msg->params.vector[0];
 | 
						buffer_send_status (ctx, ctx->server_buffer,
 | 
				
			||||||
	const char *message = msg->params.vector[1];
 | 
							"CTCP requested by %s: %s", nickname_utf8, tag_utf8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO: reply to other CTCPs;
 | 
				
			||||||
 | 
						//   see http://www.irchelp.org/irchelp/rfc/ctcpspec.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						free (nickname_utf8);
 | 
				
			||||||
 | 
						free (tag_utf8);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct buffer *
 | 
				
			||||||
 | 
					irc_get_buffer_for_message (struct app_context *ctx,
 | 
				
			||||||
 | 
						const struct irc_message *msg, const char *target)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
	struct buffer *buffer = str_map_find (&ctx->irc_buffer_map, target);
 | 
						struct buffer *buffer = str_map_find (&ctx->irc_buffer_map, target);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (irc_is_channel (ctx, target))
 | 
						if (irc_is_channel (ctx, target))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		struct channel *channel = str_map_find (&ctx->irc_channels, target);
 | 
							struct channel *channel = str_map_find (&ctx->irc_channels, target);
 | 
				
			||||||
		hard_assert ((channel && buffer) ||
 | 
							hard_assert ((channel && buffer) ||
 | 
				
			||||||
			(channel && !buffer) || (!channel && !buffer));
 | 
								(channel && !buffer) || (!channel && !buffer));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// This is weird, ignoring
 | 
							// This is weird
 | 
				
			||||||
		if (!channel)
 | 
							if (!channel)
 | 
				
			||||||
			return;
 | 
								return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if (!buffer)
 | 
						else if (!buffer)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							// Implying that the target is us
 | 
				
			||||||
		char *nickname = irc_cut_nickname (msg->prefix);
 | 
							char *nickname = irc_cut_nickname (msg->prefix);
 | 
				
			||||||
		buffer = irc_get_or_make_user_buffer (ctx, nickname);
 | 
							buffer = irc_get_or_make_user_buffer (ctx, nickname);
 | 
				
			||||||
		free (nickname);
 | 
							free (nickname);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						return buffer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					irc_handle_privmsg_text (struct app_context *ctx,
 | 
				
			||||||
 | 
						const struct irc_message *msg, struct str *text, bool is_action)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const char *target = msg->params.vector[0];
 | 
				
			||||||
 | 
						struct buffer *buffer = irc_get_buffer_for_message (ctx, msg, target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (buffer)
 | 
						if (buffer)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		// TODO: handle CTCP messages
 | 
					 | 
				
			||||||
		// TODO: highlights
 | 
							// TODO: highlights
 | 
				
			||||||
		buffer_send (ctx, buffer, BUFFER_LINE_PRIVMSG, 0,
 | 
							enum buffer_line_type type = is_action
 | 
				
			||||||
 | 
								? BUFFER_LINE_ACTION
 | 
				
			||||||
 | 
								: BUFFER_LINE_PRIVMSG;
 | 
				
			||||||
 | 
							buffer_send (ctx, buffer, type, 0,
 | 
				
			||||||
			.who  = irc_to_utf8 (ctx, msg->prefix),
 | 
								.who  = irc_to_utf8 (ctx, msg->prefix),
 | 
				
			||||||
			.text = irc_to_utf8 (ctx, message));
 | 
								.text = irc_to_utf8 (ctx, text->str));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					irc_handle_privmsg (struct app_context *ctx, const struct irc_message *msg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!msg->prefix || msg->params.len < 2)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// This ignores empty messages which we should never receive anyway
 | 
				
			||||||
 | 
						struct ctcp_chunk *chunks = ctcp_parse (msg->params.vector[1]);
 | 
				
			||||||
 | 
						LIST_FOR_EACH (struct ctcp_chunk, iter, chunks)
 | 
				
			||||||
 | 
							if (!iter->is_extended)
 | 
				
			||||||
 | 
								irc_handle_privmsg_text (ctx, msg, &iter->text, false);
 | 
				
			||||||
 | 
							else if (!strcmp (iter->tag.str, "ACTION"))
 | 
				
			||||||
 | 
								irc_handle_privmsg_text (ctx, msg, &iter->text, true);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								irc_handle_ctcp_request (ctx, msg, iter);
 | 
				
			||||||
 | 
						ctcp_destroy (chunks);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
irc_handle_quit (struct app_context *ctx, const struct irc_message *msg)
 | 
					irc_handle_quit (struct app_context *ctx, const struct irc_message *msg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user