/* it is a normal IM, maybe text or video request */ void qq_process_im(PurpleConnection *gc, guint8 *data, gint len) { gint bytes = 0; qq_im_header im_header; g_return_if_fail (data != NULL && len > 0); bytes = get_im_header(&im_header, data, len); if (bytes < 0) { purple_debug_error("QQ", "Fail read im header, len %d\n", len); qq_show_packet ("IM Header", data, len); return; } purple_debug_info("QQ", "Got IM to %u, type: %02X from: %u ver: %s (%04X)\n", im_header.uid_to, im_header.im_type, im_header.uid_from, qq_get_ver_desc(im_header.version_from), im_header.version_from); switch (im_header.im_type) { case QQ_NORMAL_IM_TEXT: if (bytes >= len - 1) { purple_debug_warning("QQ", "Received normal IM text is empty\n"); return; } process_im_text(gc, data + bytes, len - bytes, &im_header); break; case QQ_NORMAL_IM_FILE_REJECT_UDP: qq_process_recv_file_reject(data + bytes, len - bytes, im_header.uid_from, gc); break; case QQ_NORMAL_IM_FILE_APPROVE_UDP: qq_process_recv_file_accept(data + bytes, len - bytes, im_header.uid_from, gc); break; case QQ_NORMAL_IM_FILE_REQUEST_UDP: qq_process_recv_file_request(data + bytes, len - bytes, im_header.uid_from, gc); break; case QQ_NORMAL_IM_FILE_CANCEL: qq_process_recv_file_cancel(data + bytes, len - bytes, im_header.uid_from, gc); break; case QQ_NORMAL_IM_FILE_NOTIFY: qq_process_recv_file_notify(data + bytes, len - bytes, im_header.uid_from, gc); break; case QQ_NORMAL_IM_FILE_REQUEST_TCP: /* Check ReceivedFileIM::parseContents in eva*/ /* some client use this function for detect invisable buddy*/ case QQ_NORMAL_IM_FILE_APPROVE_TCP: case QQ_NORMAL_IM_FILE_REJECT_TCP: case QQ_NORMAL_IM_FILE_PASV: case QQ_NORMAL_IM_FILE_EX_REQUEST_UDP: case QQ_NORMAL_IM_FILE_EX_REQUEST_ACCEPT: case QQ_NORMAL_IM_FILE_EX_REQUEST_CANCEL: case QQ_NORMAL_IM_FILE_EX_NOTIFY_IP: qq_show_packet ("Not support", data, len); break; default: /* a simple process here, maybe more later */ qq_show_packet ("Unknow", data + bytes, len - bytes); return; } }
/* show a brief summary of what we get from login packet */ static void action_show_account_info(PurplePluginAction *action) { PurpleConnection *gc = (PurpleConnection *) action->context; qq_data *qd; GString *info; struct tm *tm_local; int index; g_return_if_fail(NULL != gc && NULL != gc->proto_data); qd = (qq_data *) gc->proto_data; info = g_string_new("<html><body>"); tm_local = localtime(&qd->login_time); g_string_append_printf(info, _("<b>Login time</b>: %d-%d-%d, %d:%d:%d<br>\n"), (1900 +tm_local->tm_year), (1 + tm_local->tm_mon), tm_local->tm_mday, tm_local->tm_hour, tm_local->tm_min, tm_local->tm_sec); g_string_append_printf(info, _("<b>Total Online Buddies</b>: %d<br>\n"), qd->online_total); tm_local = localtime(&qd->online_last_update); g_string_append_printf(info, _("<b>Last Refresh</b>: %d-%d-%d, %d:%d:%d<br>\n"), (1900 +tm_local->tm_year), (1 + tm_local->tm_mon), tm_local->tm_mday, tm_local->tm_hour, tm_local->tm_min, tm_local->tm_sec); g_string_append(info, "<hr>"); g_string_append_printf(info, _("<b>Server</b>: %s<br>\n"), qd->curr_server); g_string_append_printf(info, _("<b>Client Tag</b>: %s<br>\n"), qq_get_ver_desc(qd->client_tag)); g_string_append_printf(info, _("<b>Connection Mode</b>: %s<br>\n"), qd->use_tcp ? "TCP" : "UDP"); g_string_append_printf(info, _("<b>My Internet IP</b>: %s:%d<br>\n"), inet_ntoa(qd->my_ip), qd->my_port); g_string_append(info, "<hr>"); g_string_append(info, "<i>Network Status</i><br>\n"); g_string_append_printf(info, _("<b>Sent</b>: %lu<br>\n"), qd->net_stat.sent); g_string_append_printf(info, _("<b>Resend</b>: %lu<br>\n"), qd->net_stat.resend); g_string_append_printf(info, _("<b>Lost</b>: %lu<br>\n"), qd->net_stat.lost); g_string_append_printf(info, _("<b>Received</b>: %lu<br>\n"), qd->net_stat.rcved); g_string_append_printf(info, _("<b>Received Duplicate</b>: %lu<br>\n"), qd->net_stat.rcved_dup); g_string_append(info, "<hr>"); g_string_append(info, "<i>Last Login Information</i><br>\n"); for (index = 0; index < sizeof(qd->last_login_time) / sizeof(time_t); index++) { tm_local = localtime(&qd->last_login_time[index]); g_string_append_printf(info, _("<b>Time</b>: %d-%d-%d, %d:%d:%d<br>\n"), (1900 +tm_local->tm_year), (1 + tm_local->tm_mon), tm_local->tm_mday, tm_local->tm_hour, tm_local->tm_min, tm_local->tm_sec); } if (qd->last_login_ip.s_addr != 0) { g_string_append_printf(info, _("<b>IP</b>: %s<br>\n"), inet_ntoa(qd->last_login_ip)); } g_string_append(info, "</body></html>"); purple_notify_formatted(gc, NULL, _("Login Information"), NULL, info->str, NULL, NULL); g_string_free(info, TRUE); }
/* a floating text when mouse is on the icon, show connection status here */ static void qq_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full) { qq_buddy_data *bd; gchar *tmp; GString *str; PurplePresence *presence; PurpleStatus *status; gchar *moodtext; g_return_if_fail(b != NULL); presence = purple_buddy_get_presence(b); bd = purple_buddy_get_protocol_data(b); if (bd == NULL) return; if (bd->level == NULL) qq_request_get_level(purple_account_get_connection(purple_buddy_get_account(b)), bd->uid); /* if (PURPLE_BUDDY_IS_ONLINE(b) && bd != NULL) */ if (bd->ip.s_addr != 0) { str = g_string_new(NULL); g_string_printf(str, "%s:%d", inet_ntoa(bd->ip), bd->port); if (bd->comm_flag & QQ_COMM_FLAG_TCP_MODE) { g_string_append(str, " TCP"); } else { g_string_append(str, " UDP"); } g_string_free(str, TRUE); } tmp = g_strdup_printf("%d", bd->age); purple_notify_user_info_add_pair(user_info, _("Age"), tmp); g_free(tmp); switch (bd->gender) { case QQ_BUDDY_GENDER_GG: purple_notify_user_info_add_pair(user_info, _("Gender"), _("Male")); break; case QQ_BUDDY_GENDER_MM: purple_notify_user_info_add_pair(user_info, _("Gender"), _("Female")); break; default: purple_notify_user_info_add_pair(user_info, _("Gender"), _("Unknown")); } if (bd->level) { tmp = g_strdup_printf("%d", bd->level); purple_notify_user_info_add_pair(user_info, _("Level"), tmp); g_free(tmp); } str = g_string_new(NULL); if (bd->comm_flag & QQ_COMM_FLAG_QQ_MEMBER) { g_string_append( str, _("Member") ); } if (bd->comm_flag & QQ_COMM_FLAG_QQ_VIP) { g_string_append( str, _(" VIP") ); } if (bd->comm_flag & QQ_COMM_FLAG_TCP_MODE) { g_string_append( str, _(" TCP") ); } if (bd->comm_flag & QQ_COMM_FLAG_MOBILE) { g_string_append( str, _(" FromMobile") ); } if (bd->comm_flag & QQ_COMM_FLAG_BIND_MOBILE) { g_string_append( str, _(" BindMobile") ); } if (bd->comm_flag & QQ_COMM_FLAG_VIDEO) { g_string_append( str, _(" Video") ); } if (bd->ext_flag & QQ_EXT_FLAG_ZONE) { g_string_append( str, _(" Zone") ); } purple_notify_user_info_add_pair(user_info, _("Flag"), str->str); g_string_free(str, TRUE); status = purple_presence_get_status(presence, PURPLE_MOOD_NAME); moodtext = purple_status_get_attr_string(status, PURPLE_MOOD_COMMENT); if (moodtext) { purple_notify_user_info_add_pair(user_info, _("Signature"), moodtext); } #ifdef DEBUG tmp = g_strdup_printf( "%s (%04X)", qq_get_ver_desc(bd->client_tag), bd->client_tag ); purple_notify_user_info_add_pair(user_info, _("Ver"), tmp); g_free(tmp); tmp = g_strdup_printf( "Ext 0x%X, Comm 0x%X", bd->ext_flag, bd->comm_flag ); purple_notify_user_info_add_pair(user_info, _("Flag"), tmp); g_free(tmp); #endif }
/* a floating text when mouse is on the icon, show connection status here */ static void qq_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full) { qq_buddy_data *bd; gchar *tmp; GString *str; g_return_if_fail(b != NULL); bd = purple_buddy_get_protocol_data(b); if (bd == NULL) return; /* if (PURPLE_BUDDY_IS_ONLINE(b) && bd != NULL) */ if (bd->ip.s_addr != 0) { str = g_string_new(NULL); g_string_printf(str, "%s:%d", inet_ntoa(bd->ip), bd->port); if (bd->comm_flag & QQ_COMM_FLAG_TCP_MODE) { g_string_append(str, " TCP"); } else { g_string_append(str, " UDP"); } g_string_free(str, TRUE); } tmp = g_strdup_printf("%d", bd->age); purple_notify_user_info_add_pair(user_info, _("Age"), tmp); g_free(tmp); switch (bd->gender) { case QQ_BUDDY_GENDER_GG: purple_notify_user_info_add_pair(user_info, _("Gender"), _("Male")); break; case QQ_BUDDY_GENDER_MM: purple_notify_user_info_add_pair(user_info, _("Gender"), _("Female")); break; case QQ_BUDDY_GENDER_UNKNOWN: purple_notify_user_info_add_pair(user_info, _("Gender"), _("Unknown")); break; default: tmp = g_strdup_printf("Error (%d)", bd->gender); purple_notify_user_info_add_pair(user_info, _("Gender"), tmp); g_free(tmp); } if (bd->level) { tmp = g_strdup_printf("%d", bd->level); purple_notify_user_info_add_pair(user_info, _("Level"), tmp); g_free(tmp); } str = g_string_new(NULL); if (bd->comm_flag & QQ_COMM_FLAG_QQ_MEMBER) { g_string_append( str, _("Member") ); } if (bd->comm_flag & QQ_COMM_FLAG_QQ_VIP) { g_string_append( str, _(" VIP") ); } if (bd->comm_flag & QQ_COMM_FLAG_TCP_MODE) { g_string_append( str, _(" TCP") ); } if (bd->comm_flag & QQ_COMM_FLAG_MOBILE) { g_string_append( str, _(" FromMobile") ); } if (bd->comm_flag & QQ_COMM_FLAG_BIND_MOBILE) { g_string_append( str, _(" BindMobile") ); } if (bd->comm_flag & QQ_COMM_FLAG_VIDEO) { g_string_append( str, _(" Video") ); } if (bd->ext_flag & QQ_EXT_FLAG_ZONE) { g_string_append( str, _(" Zone") ); } purple_notify_user_info_add_pair(user_info, _("Flag"), str->str); g_string_free(str, TRUE); #ifdef DEBUG tmp = g_strdup_printf( "%s (%04X)", qq_get_ver_desc(bd->client_tag), bd->client_tag ); purple_notify_user_info_add_pair(user_info, _("Ver"), tmp); g_free(tmp); tmp = g_strdup_printf( "Ext 0x%X, Comm 0x%X", bd->ext_flag, bd->comm_flag ); purple_notify_user_info_add_pair(user_info, _("Flag"), tmp); g_free(tmp); #endif }