From 9bf248155cb870be9dce921d58c905f5a5c1dad3 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 10 Apr 2010 00:16:38 +0100 Subject: First stab at MSN keepalives. Only kicks in if the user goes offline during a conversation. --- protocols/msn/msn.c | 2 ++ protocols/msn/msn.h | 7 +++++++ protocols/msn/ns.c | 23 +++++++++++++++++++++-- protocols/msn/sb.c | 25 ++++++++++++++++++------- 4 files changed, 48 insertions(+), 9 deletions(-) (limited to 'protocols') diff --git a/protocols/msn/msn.c b/protocols/msn/msn.c index 8930847d..2132f3d8 100644 --- a/protocols/msn/msn.c +++ b/protocols/msn/msn.c @@ -40,6 +40,8 @@ static void msn_init( account_t *acc ) s->flags |= ACC_SET_NOSAVE | ACC_SET_ONLINE_ONLY; s = set_add( &acc->set, "mail_notifications", "false", set_eval_bool, acc ); + + s = set_add( &acc->set, "switchboard_keepalives", "false", set_eval_bool, acc ); } static void msn_login( account_t *acc ) diff --git a/protocols/msn/msn.h b/protocols/msn/msn.h index 84914bc3..68ca32f8 100644 --- a/protocols/msn/msn.h +++ b/protocols/msn/msn.h @@ -30,6 +30,7 @@ */ #define TYPING_NOTIFICATION_MESSAGE "\r\r\rBEWARE, ME R TYPINK MESSAGE!!!!\r\r\r" #define GROUPCHAT_SWITCHBOARD_MESSAGE "\r\r\rME WANT TALK TO MANY PEOPLE\r\r\r" +#define SB_KEEPALIVE_MESSAGE "\r\r\rDONT HANG UP ON ME!\r\r\r" #ifdef DEBUG_MSN #define debug( text... ) imcb_log( ic, text ); @@ -53,6 +54,10 @@ "TypingUser: %s\r\n" \ "\r\n\r\n" +#define SB_KEEPALIVE_HEADERS "MIME-Version: 1.0\r\n" \ + "Content-Type: text/x-ping\r\n" \ + "\r\n\r\n" + #define PROFILE_URL "http://members.msn.com/" struct msn_data @@ -82,6 +87,7 @@ struct msn_switchboard int fd; gint inp; struct msn_handler_data *handler; + gint keepalive; int trId; int ready; @@ -178,5 +184,6 @@ struct groupchat *msn_sb_to_chat( struct msn_switchboard *sb ); void msn_sb_destroy( struct msn_switchboard *sb ); gboolean msn_sb_connected( gpointer data, gint source, b_input_condition cond ); int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m ); +gboolean msn_sb_keepalive( gpointer data, gint source, b_input_condition cond ); #endif //_MSN_H diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c index d78d753a..1f6f8c74 100644 --- a/protocols/msn/ns.c +++ b/protocols/msn/ns.c @@ -435,12 +435,25 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts ) } else if( strcmp( cmd[0], "FLN" ) == 0 ) { - if( cmd[1] ) - imcb_buddy_status( ic, cmd[1], 0, NULL, NULL ); + struct msn_switchboard *sb; + + if( cmd[1] == NULL ) + return 1; + + imcb_buddy_status( ic, cmd[1], 0, NULL, NULL ); + + if( ( sb = msn_sb_by_handle( ic, cmd[1] ) ) && + set_getbool( &ic->acc->set, "switchboard_keepalives" ) && + sb->keepalive == 0 ) + { + msn_sb_keepalive( sb, 0, 0 ); + sb->keepalive = b_timeout_add( 20000, msn_sb_keepalive, sb ); + } } else if( strcmp( cmd[0], "NLN" ) == 0 ) { const struct msn_away_state *st; + struct msn_switchboard *sb; if( num_parts != 5 ) { @@ -462,6 +475,12 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts ) imcb_buddy_status( ic, cmd[2], OPT_LOGGED_IN | ( st != msn_away_state_list ? OPT_AWAY : 0 ), st->name, NULL ); + + if( ( sb = msn_sb_by_handle( ic, cmd[1] ) ) && sb->keepalive > 0 ) + { + b_event_remove( sb->keepalive ); + sb->keepalive = 0; + } } else if( strcmp( cmd[0], "RNG" ) == 0 ) { diff --git a/protocols/msn/sb.c b/protocols/msn/sb.c index e9526234..b4686e80 100644 --- a/protocols/msn/sb.c +++ b/protocols/msn/sb.c @@ -167,7 +167,18 @@ int msn_sb_sendmessage( struct msn_switchboard *sb, char *text ) int i, j; /* Build the message. Convert LF to CR-LF for normal messages. */ - if( strcmp( text, TYPING_NOTIFICATION_MESSAGE ) != 0 ) + if( strcmp( text, TYPING_NOTIFICATION_MESSAGE ) == 0 ) + { + i = strlen( MSN_TYPING_HEADERS ) + strlen( sb->ic->acc->user ); + buf = g_new0( char, i ); + i = g_snprintf( buf, i, MSN_TYPING_HEADERS, sb->ic->acc->user ); + } + else if( strcmp( text, SB_KEEPALIVE_MESSAGE ) == 0 ) + { + buf = g_strdup( SB_KEEPALIVE_HEADERS ); + i = strlen( buf ); + } + else { buf = g_new0( char, sizeof( MSN_MESSAGE_HEADERS ) + strlen( text ) * 2 + 1 ); i = strlen( MSN_MESSAGE_HEADERS ); @@ -181,12 +192,6 @@ int msn_sb_sendmessage( struct msn_switchboard *sb, char *text ) buf[i++] = text[j]; } } - else - { - i = strlen( MSN_TYPING_HEADERS ) + strlen( sb->ic->acc->user ); - buf = g_new0( char, i ); - i = g_snprintf( buf, i, MSN_TYPING_HEADERS, sb->ic->acc->user ); - } /* Build the final packet (MSG command + the message). */ packet = g_strdup_printf( "MSG %d N %d\r\n%s", ++sb->trId, i, buf ); @@ -763,3 +768,9 @@ static int msn_sb_message( gpointer data, char *msg, int msglen, char **cmd, int return( 1 ); } + +gboolean msn_sb_keepalive( gpointer data, gint source, b_input_condition cond ) +{ + struct msn_switchboard *sb = data; + return sb->ready && msn_sb_sendmessage( sb, SB_KEEPALIVE_MESSAGE ); +} -- cgit v1.2.3 From bb839e8ae5b6228f9dcd8dda96b4e3ac5c0f63ba Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 10 Apr 2010 02:05:39 +0100 Subject: Be more clever with keepalives; detect when a switchboard is opened with someone who's offline already. Still a hack but it eases the pain a little bit. --- protocols/msn/msn.h | 3 ++- protocols/msn/ns.c | 17 ++--------------- protocols/msn/sb.c | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 36 insertions(+), 17 deletions(-) (limited to 'protocols') diff --git a/protocols/msn/msn.h b/protocols/msn/msn.h index 68ca32f8..61101546 100644 --- a/protocols/msn/msn.h +++ b/protocols/msn/msn.h @@ -184,6 +184,7 @@ struct groupchat *msn_sb_to_chat( struct msn_switchboard *sb ); void msn_sb_destroy( struct msn_switchboard *sb ); gboolean msn_sb_connected( gpointer data, gint source, b_input_condition cond ); int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m ); -gboolean msn_sb_keepalive( gpointer data, gint source, b_input_condition cond ); +void msn_sb_start_keepalives( struct msn_switchboard *sb, gboolean initial ); +void msn_sb_stop_keepalives( struct msn_switchboard *sb ); #endif //_MSN_H diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c index 1f6f8c74..4056bad7 100644 --- a/protocols/msn/ns.c +++ b/protocols/msn/ns.c @@ -435,25 +435,16 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts ) } else if( strcmp( cmd[0], "FLN" ) == 0 ) { - struct msn_switchboard *sb; - if( cmd[1] == NULL ) return 1; imcb_buddy_status( ic, cmd[1], 0, NULL, NULL ); - if( ( sb = msn_sb_by_handle( ic, cmd[1] ) ) && - set_getbool( &ic->acc->set, "switchboard_keepalives" ) && - sb->keepalive == 0 ) - { - msn_sb_keepalive( sb, 0, 0 ); - sb->keepalive = b_timeout_add( 20000, msn_sb_keepalive, sb ); - } + msn_sb_start_keepalives( msn_sb_by_handle( ic, cmd[1] ), TRUE ); } else if( strcmp( cmd[0], "NLN" ) == 0 ) { const struct msn_away_state *st; - struct msn_switchboard *sb; if( num_parts != 5 ) { @@ -476,11 +467,7 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts ) ( st != msn_away_state_list ? OPT_AWAY : 0 ), st->name, NULL ); - if( ( sb = msn_sb_by_handle( ic, cmd[1] ) ) && sb->keepalive > 0 ) - { - b_event_remove( sb->keepalive ); - sb->keepalive = 0; - } + msn_sb_stop_keepalives( msn_sb_by_handle( ic, cmd[2] ) ); } else if( strcmp( cmd[0], "RNG" ) == 0 ) { diff --git a/protocols/msn/sb.c b/protocols/msn/sb.c index b4686e80..e2ee8570 100644 --- a/protocols/msn/sb.c +++ b/protocols/msn/sb.c @@ -254,6 +254,7 @@ void msn_sb_destroy( struct msn_switchboard *sb ) debug( "Destroying switchboard: %s", sb->who ? sb->who : sb->key ? sb->key : "" ); msn_msgq_purge( ic, &sb->msgq ); + msn_sb_stop_keepalives( sb ); if( sb->key ) g_free( sb->key ); if( sb->who ) g_free( sb->who ); @@ -475,6 +476,8 @@ static int msn_sb_command( gpointer data, char **cmd, int num_parts ) } sb->ready = 1; + + msn_sb_start_keepalives( sb, FALSE ); } else if( strcmp( cmd[0], "CAL" ) == 0 ) { @@ -524,6 +527,8 @@ static int msn_sb_command( gpointer data, char **cmd, int num_parts ) sb->msgq = g_slist_remove( sb->msgq, m ); } + msn_sb_start_keepalives( sb, FALSE ); + return( st ); } else if( sb->who ) @@ -585,6 +590,8 @@ static int msn_sb_command( gpointer data, char **cmd, int num_parts ) if( sb->who ) { + msn_sb_stop_keepalives( sb ); + /* This is a single-person chat, and the other person is leaving. */ g_free( sb->who ); sb->who = NULL; @@ -769,8 +776,32 @@ static int msn_sb_message( gpointer data, char *msg, int msglen, char **cmd, int return( 1 ); } -gboolean msn_sb_keepalive( gpointer data, gint source, b_input_condition cond ) +static gboolean msn_sb_keepalive( gpointer data, gint source, b_input_condition cond ) { struct msn_switchboard *sb = data; return sb->ready && msn_sb_sendmessage( sb, SB_KEEPALIVE_MESSAGE ); } + +void msn_sb_start_keepalives( struct msn_switchboard *sb, gboolean initial ) +{ + struct buddy *b; + + if( sb && sb->who && sb->keepalive == 0 && + ( b = imcb_find_buddy( sb->ic, sb->who ) ) && !b->present && + set_getbool( &sb->ic->acc->set, "switchboard_keepalives" ) ) + { + if( initial ) + msn_sb_keepalive( sb, 0, 0 ); + + sb->keepalive = b_timeout_add( 20000, msn_sb_keepalive, sb ); + } +} + +void msn_sb_stop_keepalives( struct msn_switchboard *sb ) +{ + if( sb && sb->keepalive > 0 ) + { + b_event_remove( sb->keepalive ); + sb->keepalive = 0; + } +} -- cgit v1.2.3