diff options
-rw-r--r-- | irc.h | 2 | ||||
-rw-r--r-- | irc_channel.c | 48 | ||||
-rw-r--r-- | irc_im.c | 35 |
3 files changed, 71 insertions, 14 deletions
@@ -179,6 +179,7 @@ typedef enum IRC_CHANNEL_USER_OP = 1, IRC_CHANNEL_USER_HALFOP = 2, IRC_CHANNEL_USER_VOICE = 4, + IRC_CHANNEL_USER_NONE = 8, } irc_channel_user_flags_t; typedef struct irc_channel_user @@ -202,6 +203,7 @@ struct irc_control_channel struct bee_group *group; struct account *account; struct prpl *protocol; + char modes[4]; }; extern const struct bee_ui_funcs irc_ui_funcs; diff --git a/irc_channel.c b/irc_channel.c index 6f9de637..b3058e0e 100644 --- a/irc_channel.c +++ b/irc_channel.c @@ -535,6 +535,7 @@ static char *set_eval_by_account( set_t *set, char *value ); static char *set_eval_fill_by( set_t *set, char *value ); static char *set_eval_by_group( set_t *set, char *value ); static char *set_eval_by_protocol( set_t *set, char *value ); +static char *set_eval_show_users( set_t *set, char *value ); static gboolean control_channel_init( irc_channel_t *ic ) { @@ -544,10 +545,14 @@ static gboolean control_channel_init( irc_channel_t *ic ) set_add( &ic->set, "fill_by", "all", set_eval_fill_by, ic ); set_add( &ic->set, "group", NULL, set_eval_by_group, ic ); set_add( &ic->set, "protocol", NULL, set_eval_by_protocol, ic ); + set_add( &ic->set, "show_users", "online+,away", set_eval_show_users, ic ); ic->data = icc = g_new0( struct irc_control_channel, 1 ); icc->type = IRC_CC_TYPE_DEFAULT; + /* Have to run the evaluator to initialize icc->modes. */ + set_setstr( &ic->set, "show_users", set_getstr( &ic->set, "show_users" ) ); + return TRUE; } @@ -624,6 +629,49 @@ static char *set_eval_by_protocol( set_t *set, char *value ) return value; } +static char *set_eval_show_users( set_t *set, char *value ) +{ + struct irc_channel *ic = set->data; + struct irc_control_channel *icc = ic->data; + char **parts = g_strsplit( value, ",", 0 ), **part; + char modes[4]; + + memset( modes, 0, 4 ); + for( part = parts; *part; part ++ ) + { + char last, modechar = IRC_CHANNEL_USER_NONE; + + if( **part == '\0' ) + goto fail; + + last = (*part)[strlen(*part+1)]; + if( last == '+' ) + modechar = IRC_CHANNEL_USER_VOICE; + else if( last == '%' ) + modechar = IRC_CHANNEL_USER_HALFOP; + else if( last == '@' ) + modechar = IRC_CHANNEL_USER_OP; + + if( strncmp( *part, "offline", 7 ) == 0 ) + modes[0] = modechar; + else if( strncmp( *part, "away", 4 ) == 0 ) + modes[1] = modechar; + else if( strncmp( *part, "online", 6 ) == 0 ) + modes[2] = modechar; + else + goto fail; + } + memcpy( icc->modes, modes, 4 ); + bee_irc_channel_update( ic->irc, ic, NULL ); + + g_strfreev( parts ); + return value; + +fail: + g_strfreev( parts ); + return SET_INVALID; +} + static gboolean control_channel_free( irc_channel_t *ic ) { struct irc_control_channel *icc = ic->data; @@ -142,7 +142,7 @@ void bee_irc_channel_update( irc_t *irc, irc_channel_t *ic, irc_user_t *iu ) { struct irc_control_channel *icc; GSList *l; - gboolean show = FALSE; + gboolean match = FALSE; if( ic == NULL ) { @@ -169,30 +169,37 @@ void bee_irc_channel_update( irc_t *irc, irc_channel_t *ic, irc_user_t *iu ) icc = ic->data; - if( !( iu->bu->flags & BEE_USER_ONLINE ) ) - show = FALSE; - else if( icc->type == IRC_CC_TYPE_DEFAULT ) - show = TRUE; + if( icc->type == IRC_CC_TYPE_DEFAULT ) + match = TRUE; else if( icc->type == IRC_CC_TYPE_GROUP ) - show = iu->bu->group == icc->group; + match = iu->bu->group == icc->group; else if( icc->type == IRC_CC_TYPE_ACCOUNT ) - show = iu->bu->ic->acc == icc->account; + match = iu->bu->ic->acc == icc->account; else if( icc->type == IRC_CC_TYPE_PROTOCOL ) - show = iu->bu->ic->acc->prpl == icc->protocol; + match = iu->bu->ic->acc->prpl == icc->protocol; - if( !show ) + if( !match ) { irc_channel_del_user( ic, iu, IRC_CDU_PART, NULL ); } else { - irc_channel_add_user( ic, iu ); + int mode = 0; - if( set_getbool( &irc->b->set, "away_devoice" ) ) - irc_channel_user_set_mode( ic, iu, ( iu->bu->flags & BEE_USER_AWAY ) ? - 0 : IRC_CHANNEL_USER_VOICE ); + if( !( iu->bu->flags & BEE_USER_ONLINE ) ) + mode = icc->modes[0]; + else if( iu->bu->flags & BEE_USER_AWAY ) + mode = icc->modes[1]; else - irc_channel_user_set_mode( ic, iu, 0 ); + mode = icc->modes[2]; + + if( !mode ) + irc_channel_del_user( ic, iu, IRC_CDU_PART, NULL ); + else + { + irc_channel_add_user( ic, iu ); + irc_channel_user_set_mode( ic, iu, mode ); + } } } |