aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2010-05-03 01:39:39 +0100
committerWilmer van der Gaast <wilmer@gaast.net>2010-05-03 01:39:39 +0100
commit6a9d068e73b6d08056302fdc85dd706a2dd647a5 (patch)
treef478fc61bc2e1c53ffcbd71fc081b91ac1324667
parente54112f152c375df81a21181f755ced5f57165bc (diff)
Restore away_devoice.
-rw-r--r--irc.c4
-rw-r--r--irc.h3
-rw-r--r--irc_channel.c16
-rw-r--r--irc_im.c4
-rw-r--r--irc_send.c61
5 files changed, 81 insertions, 7 deletions
diff --git a/irc.c b/irc.c
index 93b41071..4a7ba332 100644
--- a/irc.c
+++ b/irc.c
@@ -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,
diff --git a/irc.h b/irc.h
index 0d233844..2d1987eb 100644
--- a/irc.h
+++ b/irc.h
@@ -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 );
diff --git a/irc_im.c b/irc_im.c
index 1363df4a..00ea3cd7 100644
--- a/irc_im.c
+++ b/irc_im.c
@@ -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
{
diff --git a/irc_send.c b/irc_send.c
index a1df68b2..d3485221 100644
--- a/irc_send.c
+++ b/irc_send.c
@@ -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 );
+}