diff options
| author | Přemysl Janouch <p.janouch@gmail.com> | 2015-04-19 21:58:46 +0200 | 
|---|---|---|
| committer | Přemysl Janouch <p.janouch@gmail.com> | 2015-04-19 22:19:26 +0200 | 
| commit | 56ae38b19adf109973a4b081dbd7e0a61e06cc32 (patch) | |
| tree | 4fa9bd87e801be15db557a09bc6473f514197c58 /degesch.c | |
| parent | 63d01191b61ce775795b686cfbb37d27b899c9e0 (diff) | |
| download | xK-56ae38b19adf109973a4b081dbd7e0a61e06cc32.tar.gz xK-56ae38b19adf109973a4b081dbd7e0a61e06cc32.tar.xz xK-56ae38b19adf109973a4b081dbd7e0a61e06cc32.zip | |
degesch: implement JOIN handling
Diffstat (limited to 'degesch.c')
| -rw-r--r-- | degesch.c | 90 | 
1 files changed, 88 insertions, 2 deletions
| @@ -1206,8 +1206,33 @@ init_buffers (struct app_context *ctx)  	LIST_APPEND_WITH_TAIL (ctx->buffers, ctx->buffers_tail, server);  } +// --- Users, channels --------------------------------------------------------- +  // --- Supporting code --------------------------------------------------------- +static char * +irc_cut_nickname (const char *prefix) +{ +	return xstrndup (prefix, strcspn (prefix, "!@")); +} + +static bool +irc_is_this_us (struct app_context *ctx, const char *prefix) +{ +	char *nick = irc_cut_nickname (prefix); +	bool result = !irc_strcmp (nick, ctx->irc_nickname); +	free (nick); +	return result; +} + +static bool +irc_is_channel (struct app_context *ctx, const char *ident) +{ +	(void) ctx;  // TODO: parse prefixes from server features + +	return *ident && !!strchr ("#&+!", *ident); +} +  static void  irc_shutdown (struct app_context *ctx)  { @@ -1712,8 +1737,69 @@ irc_to_utf8 (struct app_context *ctx, const char *text)  static void  irc_handle_join (struct app_context *ctx, const struct irc_message *msg)  { -	// TODO: if the user is us, create a new buffer and activate it. -	// TODO: log a message +	if (!msg->prefix || msg->params.len < 1) +		return; + +	const char *target = msg->params.vector[0]; +	if (!irc_is_channel (ctx, target)) +		return; + +	struct channel *channel = str_map_find (&ctx->irc_channels, target); +	struct buffer *buffer = str_map_find (&ctx->irc_buffer_map, target); +	hard_assert ((channel && buffer) || +		(channel && !buffer) || (!channel && !buffer)); + +	// We've joined a new channel +	if (!channel && irc_is_this_us (ctx, msg->prefix)) +	{ +		channel = channel_new (); +		channel->name = xstrdup (target); +		channel->mode = xstrdup (""); +		channel->topic = NULL; +		str_map_set (&ctx->irc_channels, channel->name, channel); + +		buffer = buffer_new (); +		buffer->type = BUFFER_CHANNEL; +		buffer->name = xstrdup (target); +		buffer->channel = channel_ref (channel); +		LIST_APPEND_WITH_TAIL (ctx->buffers, ctx->buffers_tail, buffer); +		str_map_set (&ctx->irc_buffer_map, channel->name, buffer); + +		buffer_activate (ctx, buffer); +	} + +	// This is weird, ignoring +	if (!channel) +		return; + +	// Get or make a user object +	char *nickname = irc_cut_nickname (msg->prefix); +	struct user *user = str_map_find (&ctx->irc_users, nickname); +	if (!user) +	{ +		user = user_new (); +		user->nickname = nickname; +		str_map_set (&ctx->irc_users, user->nickname, user); +	} +	else +		free (nickname); + +	// Link the user with the channel +	struct user_channel *user_channel = user_channel_new (); +	user_channel->channel = channel_ref (channel); +	LIST_PREPEND (user->channels, user_channel); + +	struct channel_user *channel_user = channel_user_new (); +	channel_user->user = user_ref (user); +	channel_user->modes = xstrdup (""); +	LIST_PREPEND (channel->users, channel_user); + +	// Finally log the message +	if (buffer) +	{ +		buffer_send (ctx, buffer, BUFFER_LINE_JOIN, 0, +			msg->prefix, NULL, "%s", target); +	}  }  static void | 
