diff options
-rw-r--r-- | irc.c | 4 | ||||
-rw-r--r-- | irc.h | 3 | ||||
-rw-r--r-- | irc_channel.c | 16 | ||||
-rw-r--r-- | irc_im.c | 4 | ||||
-rw-r--r-- | irc_send.c | 61 |
5 files changed, 81 insertions, 7 deletions
@@ -639,6 +639,10 @@ int irc_check_login( irc_t *irc ) irc_channel_set_topic( ic, CONTROL_TOPIC, irc->root ); irc_channel_add_user( ic, irc->user ); + if( strcmp( set_getstr( &irc->b->set, "ops" ), "both" ) == 0 || + strcmp( set_getstr( &irc->b->set, "ops" ), "user" ) == 0 ) + irc_channel_user_set_mode( ic, irc->user, IRC_CHANNEL_USER_OP ); + irc->last_root_cmd = g_strdup( ROOT_CHAN ); irc_send_msg( irc->root, "PRIVMSG", ROOT_CHAN, @@ -195,6 +195,7 @@ int irc_channel_add_user( irc_channel_t *ic, irc_user_t *iu ); int irc_channel_del_user( irc_channel_t *ic, irc_user_t *iu ); irc_channel_user_t *irc_channel_has_user( irc_channel_t *ic, irc_user_t *iu ); int irc_channel_set_topic( irc_channel_t *ic, const char *topic, const irc_user_t *who ); +void irc_channel_user_set_mode( irc_channel_t *ic, irc_user_t *iu, irc_channel_user_flags_t flags ); gboolean irc_channel_name_ok( const char *name ); /* irc_commands.c */ @@ -215,6 +216,8 @@ void irc_send_msg( irc_user_t *iu, const char *type, const char *dst, const char void irc_send_msg_raw( irc_user_t *iu, const char *type, const char *dst, const char *msg ); void irc_send_msg_f( irc_user_t *iu, const char *type, const char *dst, const char *format, ... ) G_GNUC_PRINTF( 4, 5 ); void irc_send_nick( irc_user_t *iu, const char *new ); +void irc_send_channel_user_mode_diff( irc_channel_t *ic, irc_user_t *iu, + irc_channel_user_flags_t old, irc_channel_user_flags_t new ); /* irc_user.c */ irc_user_t *irc_user_new( irc_t *irc, const char *nick ); diff --git a/irc_channel.c b/irc_channel.c index 17ea64d3..fd79ba71 100644 --- a/irc_channel.c +++ b/irc_channel.c @@ -42,6 +42,9 @@ irc_channel_t *irc_channel_new( irc_t *irc, const char *name ) strcpy( ic->mode, CMODE ); irc_channel_add_user( ic, irc->root ); + if( strcmp( set_getstr( &irc->b->set, "ops" ), "both" ) == 0 || + strcmp( set_getstr( &irc->b->set, "ops" ), "root" ) == 0 ) + irc_channel_user_set_mode( ic, irc->root, IRC_CHANNEL_USER_OP ); irc->channels = g_slist_prepend( irc->channels, ic ); @@ -158,6 +161,19 @@ int irc_channel_set_topic( irc_channel_t *ic, const char *topic, const irc_user_ return 1; } +void irc_channel_user_set_mode( irc_channel_t *ic, irc_user_t *iu, irc_channel_user_flags_t flags ) +{ + irc_channel_user_t *icu = irc_channel_has_user( ic, iu ); + + if( icu->flags == flags ) + return; + + if( ic->flags & IRC_CHANNEL_JOINED ) + irc_send_channel_user_mode_diff( ic, iu, icu->flags, flags ); + + icu->flags = flags; +} + gboolean irc_channel_name_ok( const char *name ) { return strchr( CTYPES, name[0] ) != NULL && nick_ok( name + 1 ); @@ -91,6 +91,10 @@ static gboolean bee_irc_user_status( bee_t *bee, bee_user_t *bu, bee_user_t *old iu->host, (int) time( NULL ), "logged online" ); irc_channel_add_user( ic, iu ); + + if( set_getbool( &bee->set, "away_devoice" ) ) + irc_channel_user_set_mode( ic, iu, ( bu->flags & BEE_USER_AWAY ) ? + 0 : IRC_CHANNEL_USER_VOICE ); } else { @@ -156,7 +156,6 @@ void irc_send_names( irc_channel_t *ic ) { GSList *l; char namelist[385] = ""; - //char *ops = set_getstr( &ic->irc->b->set, "ops" ); /* RFCs say there is no error reply allowed on NAMES, so when the channel is invalid, just give an empty reply. */ @@ -171,13 +170,12 @@ void irc_send_names( irc_channel_t *ic ) *namelist = 0; } - /* - if( u->ic && !u->away && set_getbool( &irc->set, "away_devoice" ) ) - strcat( namelist, "+" ); - else if( ( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) == 0 ) ) || - ( strcmp( u->nick, irc->nick ) == 0 && ( strcmp( ops, "user" ) == 0 || strcmp( ops, "both" ) == 0 ) ) ) + if( icu->flags & IRC_CHANNEL_USER_OP ) strcat( namelist, "@" ); - */ + else if( icu->flags & IRC_CHANNEL_USER_HALFOP ) + strcat( namelist, "%" ); + else if( icu->flags & IRC_CHANNEL_USER_VOICE ) + strcat( namelist, "+" ); strcat( namelist, iu->nick ); strcat( namelist, " " ); @@ -326,3 +324,52 @@ void irc_send_nick( irc_user_t *iu, const char *new ) irc_write( iu->irc, ":%s!%s@%s NICK %s", iu->nick, iu->user, iu->host, new ); } + +/* Send an update of a user's mode inside a channel, compared to what it was. */ +void irc_send_channel_user_mode_diff( irc_channel_t *ic, irc_user_t *iu, + irc_channel_user_flags_t old, irc_channel_user_flags_t new ) +{ + char changes[3*(5+strlen(iu->nick))]; + char from[strlen(ic->irc->root->nick)+strlen(ic->irc->root->user)+strlen(ic->irc->root->host)+3]; + int n; + + *changes = '\0'; n = 0; + if( ( old & IRC_CHANNEL_USER_OP ) != ( new & IRC_CHANNEL_USER_OP ) ) + { + n ++; + if( new & IRC_CHANNEL_USER_OP ) + strcat( changes, "+o" ); + else + strcat( changes, "-o" ); + } + if( ( old & IRC_CHANNEL_USER_HALFOP ) != ( new & IRC_CHANNEL_USER_HALFOP ) ) + { + n ++; + if( new & IRC_CHANNEL_USER_HALFOP ) + strcat( changes, "+h" ); + else + strcat( changes, "-h" ); + } + if( ( old & IRC_CHANNEL_USER_VOICE ) != ( new & IRC_CHANNEL_USER_VOICE ) ) + { + n ++; + if( new & IRC_CHANNEL_USER_VOICE ) + strcat( changes, "+v" ); + else + strcat( changes, "-v" ); + } + while( n ) + { + strcat( changes, " " ); + strcat( changes, iu->nick ); + n --; + } + + if( set_getbool( &ic->irc->b->set, "simulate_netsplit" ) ) + g_snprintf( from, sizeof( from ), "%s", ic->irc->root->host ); + else + g_snprintf( from, sizeof( from ), "%s!%s@%s", ic->irc->root->nick, + ic->irc->root->user, ic->irc->root->host ); + + irc_write( ic->irc, ":%s MODE %s %s", from, ic->name, changes ); +} |