aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--irc.h2
-rw-r--r--irc_channel.c48
-rw-r--r--irc_im.c35
3 files changed, 71 insertions, 14 deletions
diff --git a/irc.h b/irc.h
index 1d5bd113..69f9dfd0 100644
--- a/irc.h
+++ b/irc.h
@@ -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;
diff --git a/irc_im.c b/irc_im.c
index f467a666..8a10cede 100644
--- a/irc_im.c
+++ b/irc_im.c
@@ -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 );
+ }
}
}