degesch: process user mode changes

This commit is contained in:
Přemysl Eric Janouch 2015-06-07 04:20:39 +02:00
parent 0553ef857f
commit 9816805ee8
1 changed files with 58 additions and 11 deletions

View File

@ -1048,7 +1048,7 @@ struct server
struct str_map irc_buffer_map; ///< Maps IRC identifiers to buffers struct str_map irc_buffer_map; ///< Maps IRC identifiers to buffers
struct user *irc_user; ///< Our own user struct user *irc_user; ///< Our own user
char *irc_user_mode; ///< Our current user mode struct str irc_user_mode; ///< Our current user modes
char *irc_user_host; ///< Our current user@host char *irc_user_host; ///< Our current user@host
// Server-specific information (from RPL_ISUPPORT): // Server-specific information (from RPL_ISUPPORT):
@ -1091,6 +1091,8 @@ server_init (struct server *self, struct poller *poller)
str_init (&self->read_buffer); str_init (&self->read_buffer);
self->state = IRC_DISCONNECTED; self->state = IRC_DISCONNECTED;
str_init (&self->irc_user_mode);
// Defaults as per the RPL_ISUPPORT drafts, or RFC 1459 // Defaults as per the RPL_ISUPPORT drafts, or RFC 1459
self->irc_tolower = irc_tolower; self->irc_tolower = irc_tolower;
self->irc_strxfrm = irc_strxfrm; self->irc_strxfrm = irc_strxfrm;
@ -1151,7 +1153,7 @@ server_free (struct server *self)
if (self->irc_user) if (self->irc_user)
user_unref (self->irc_user); user_unref (self->irc_user);
free (self->irc_user_mode); str_free (&self->irc_user_mode);
free (self->irc_user_host); free (self->irc_user_host);
free (self->irc_chantypes); free (self->irc_chantypes);
@ -3184,8 +3186,7 @@ on_irc_disconnected (struct server *s)
s->irc_user = NULL; s->irc_user = NULL;
} }
free (s->irc_user_mode); str_reset (&s->irc_user_mode);
s->irc_user_mode = NULL;
free (s->irc_user_host); free (s->irc_user_host);
s->irc_user_host = NULL; s->irc_user_host = NULL;
@ -3703,8 +3704,8 @@ make_prompt (struct app_context *ctx, struct str *output)
str_append (output, channel_user->prefixes.str); str_append (output, channel_user->prefixes.str);
} }
str_append (output, s->irc_user->nickname); str_append (output, s->irc_user->nickname);
if (*s->irc_user_mode) if (s->irc_user_mode.len)
str_append_printf (output, "(%s)", s->irc_user_mode); str_append_printf (output, "(%s)", s->irc_user_mode.str);
} }
} }
@ -3985,6 +3986,8 @@ mode_processor_next_param (struct mode_processor *self)
return *self->params++; return *self->params++;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static void static void
mode_processor_do_user (struct mode_processor *self) mode_processor_do_user (struct mode_processor *self)
{ {
@ -4092,8 +4095,6 @@ mode_processor_step (struct mode_processor *self, char mode_char)
return true; return true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static void static void
irc_handle_mode_channel irc_handle_mode_channel
(struct server *s, struct channel *channel, char **params) (struct server *s, struct channel *channel, char **params)
@ -4115,6 +4116,52 @@ irc_handle_mode_channel
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static bool
mode_processor_step_user (struct mode_processor *self, char mode_char)
{
struct server *s = self->s;
if (mode_char == '+') { self->adding = true; return true; }
if (mode_char == '-') { self->adding = false; return true; }
struct str *modes = &s->irc_user_mode;
const char *pos = strchr (modes->str, mode_char);
if (self->adding == !!pos)
return true;
if (self->adding)
{
str_append_c (modes, mode_char);
// TODO: sort the modes
}
else
str_remove_slice (modes, pos - modes->str, 1);
return true;
}
static void
irc_handle_mode_user (struct server *s, char **params)
{
struct mode_processor p;
mode_processor_init (&p);
p.params = params;
p.s = s;
const char *mode_string;
while ((mode_string = mode_processor_next_param (&p)))
{
mode_processor_step (&p, '+');
while (*mode_string)
if (!mode_processor_step_user (&p, *mode_string++))
break;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static void static void
irc_handle_mode (struct server *s, const struct irc_message *msg) irc_handle_mode (struct server *s, const struct irc_message *msg)
{ {
@ -4133,8 +4180,6 @@ irc_handle_mode (struct server *s, const struct irc_message *msg)
char *modes = irc_to_utf8 (s->ctx, reconstructed); char *modes = irc_to_utf8 (s->ctx, reconstructed);
free (reconstructed); free (reconstructed);
// TODO: parse user mode changes
if (irc_is_channel (s, context)) if (irc_is_channel (s, context))
{ {
struct channel *channel = str_map_find (&s->irc_channels, context); struct channel *channel = str_map_find (&s->irc_channels, context);
@ -4154,6 +4199,8 @@ irc_handle_mode (struct server *s, const struct irc_message *msg)
} }
else if (irc_is_this_us (s, context)) else if (irc_is_this_us (s, context))
{ {
irc_handle_mode_user (s, msg->params.vector + 1);
// FIXME: logging // FIXME: logging
buffer_send_status (s->ctx, s->buffer, buffer_send_status (s->ctx, s->buffer,
"User mode [%s] by %s", modes, who); "User mode [%s] by %s", modes, who);
@ -4625,7 +4672,7 @@ static void
irc_on_registered (struct server *s, const char *nickname) irc_on_registered (struct server *s, const char *nickname)
{ {
s->irc_user = irc_get_or_make_user (s, nickname); s->irc_user = irc_get_or_make_user (s, nickname);
s->irc_user_mode = xstrdup (""); str_reset (&s->irc_user_mode);
s->irc_user_host = NULL; s->irc_user_host = NULL;
s->state = IRC_REGISTERED; s->state = IRC_REGISTERED;