首页 | 数据结构 | 文件列表 | 数据字段 | 全局定义

buddy_status.c

浏览该文件的文档。
00001 
00023 // START OF FILE
00024 /*****************************************************************************/
00025 #include <string.h>             // g_memmove
00026 #include "debug.h"              // gaim_debug
00027 #include "prefs.h"              // gaim_prefs_get_bool
00028 
00029 #include "utils.h"              // get_ip_str
00030 #include "packet_parse.h"       // create_packet,
00031 #include "buddy_status.h"
00032 #include "crypt.h"              // qq_crypt.h
00033 #include "header_info.h"        // cmd alias
00034 #include "keep_alive.h"         // qq_update_buddy_contact
00035 #include "send_core.h"          // qq_send_cmd
00036 
00037 #define QQ_MISC_STATUS_HAVING_VIIDEO      0x00000001
00038 
00039 #define QQ_ICON_SUFFIX_DEFAULT            QQ_ICON_SUFFIX_OFFLINE
00040 #define QQ_CHANGE_ONLINE_STATUS_REPLY_OK        0x30    // ASCii value of "0"
00041 
00042 enum {
00043         QQ_ICON_SUFFIX_NORMAL = 1,
00044         QQ_ICON_SUFFIX_OFFLINE = 2,
00045         QQ_ICON_SUFFIX_AWAY = 3,
00046 };
00047 
00048 /*****************************************************************************/
00049 void _qq_buddy_status_dump_unclear(qq_buddy_status * s)
00050 {
00051         GString *dump;
00052 
00053         g_return_if_fail(s != NULL);
00054 
00055         dump = g_string_new("");
00056         g_string_append_printf(dump, "unclear fields for [%d]:\n", s->uid);
00057         g_string_append_printf(dump, "004:     %02x   (unknown)\n", s->unknown1);
00058         g_string_append_printf(dump, "011:     %02x   (unknown)\n", s->unknown2);
00059 
00060         gaim_debug(GAIM_DEBUG_INFO, "QQ", "Buddy status entry, %s", dump->str);
00061         g_string_free(dump, TRUE);
00062 }                               // _qq_buddy_status_dump_unclear
00063 
00064 /*****************************************************************************/
00065 // parse the data into qq_buddy_status
00066 gint _qq_buddy_status_read(guint8 * data, guint8 ** cursor, gint len, qq_buddy_status * s) {
00067         gint bytes;
00068 
00069         g_return_val_if_fail(data != NULL && *cursor != NULL && s != NULL, -1);
00070 
00071         bytes = 0;
00072 
00073         // 000-003: uid
00074         bytes += read_packet_dw(data, cursor, len, &s->uid);
00075         // 004-004: 0x01
00076         bytes += read_packet_b(data, cursor, len, &s->unknown1);
00077         // 005-008: ip
00078         s->ip = g_new0(guint8, 4);
00079         bytes += read_packet_data(data, cursor, len, s->ip, 4);
00080         // 009-010: port
00081         bytes += read_packet_w(data, cursor, len, &s->port);
00082         // 011-011: 0x00
00083         bytes += read_packet_b(data, cursor, len, &s->unknown2);
00084         // 012-012: status
00085         bytes += read_packet_b(data, cursor, len, &s->status);
00086         // 013-014: client_version 
00087         bytes += read_packet_w(data, cursor, len, &s->client_version);
00088         // 015-030: unknown key
00089         s->unknown_key = g_new0(guint8, QQ_KEY_LENGTH);
00090         bytes += read_packet_data(data, cursor, len, s->unknown_key, QQ_KEY_LENGTH);
00091 
00092         if (s->uid == 0 || bytes != 31)
00093                 return -1;
00094 
00095         return bytes;
00096 
00097 }                               // _qq_buddy_status_read
00098 
00099 /*****************************************************************************/
00100 // check if status means online or offline
00101 gboolean is_online(guint8 status)
00102 {
00103         return (status == QQ_BUDDY_ONLINE_NORMAL ? TRUE : (status == QQ_BUDDY_ONLINE_AWAY ? TRUE : FALSE));
00104 }                               // is_online
00105 
00106 /*****************************************************************************/
00107 // the icon suffix is detemined by status
00108 // although QQ server may return the right icon, I set it here myself
00109 gchar get_suffix_from_status(guint8 status)
00110 {
00111         switch (status) {
00112         case QQ_BUDDY_ONLINE_NORMAL:
00113                 return QQ_ICON_SUFFIX_NORMAL;
00114         case QQ_BUDDY_ONLINE_AWAY:
00115                 return QQ_ICON_SUFFIX_AWAY;
00116         case QQ_BUDDY_ONLINE_INVISIBLE:
00117         case QQ_BUDDY_ONLINE_OFFLINE:
00118                 return QQ_ICON_SUFFIX_OFFLINE;
00119         default:
00120                 return QQ_ICON_SUFFIX_DEFAULT;
00121         }                       // switch
00122 }                               // get_suffix_from_status
00123 
00124 /*****************************************************************************/
00125 // send a packet to change my online status
00126 void qq_send_packet_change_status(GaimConnection * gc)
00127 {
00128         qq_data *qd;
00129         guint8 *raw_data, *cursor, away_cmd;
00130         guint32 misc_status;
00131         gboolean fake_video;
00132 
00133         g_return_if_fail(gc != NULL && gc->proto_data != NULL);
00134 
00135         qd = (qq_data *) gc->proto_data;
00136         if (!qd->logged_in)
00137                 return;
00138 
00139         switch (qd->status) {
00140         case QQ_SELF_STATUS_AVAILABLE:
00141                 away_cmd = QQ_BUDDY_ONLINE_NORMAL;
00142                 break;
00143         case QQ_SELF_STATUS_INVISIBLE:
00144                 away_cmd = QQ_BUDDY_ONLINE_INVISIBLE;
00145                 break;
00146         case QQ_SELF_STATUS_AWAY:
00147         case QQ_SELF_STATUS_IDLE:
00148         case QQ_SELF_STATUS_CUSTOM:
00149                 away_cmd = QQ_BUDDY_ONLINE_AWAY;
00150                 break;
00151         default:
00152                 away_cmd = QQ_BUDDY_ONLINE_NORMAL;
00153         }                       // switch
00154 
00155         raw_data = g_new0(guint8, 5);
00156         cursor = raw_data;
00157         misc_status = 0x00000000;
00158 
00159         fake_video = gaim_prefs_get_bool("/plugins/prpl/qq/show_fake_video");
00160         if (fake_video)
00161                 misc_status |= QQ_MISC_STATUS_HAVING_VIIDEO;
00162 
00163         create_packet_b(raw_data, &cursor, away_cmd);
00164         create_packet_dw(raw_data, &cursor, misc_status);
00165 
00166         qq_send_cmd(gc, QQ_CMD_CHANGE_ONLINE_STATUS, TRUE, 0, TRUE, raw_data, 5);
00167 
00168         g_free(raw_data);
00169 }                               // qq_send_packet_change_status
00170 
00171 /*****************************************************************************/
00172 // parse the reply packet for change_status
00173 void qq_process_change_status_reply(guint8 * buf, gint buf_len, GaimConnection * gc) {
00174         qq_data *qd;
00175         gint len;
00176         guint8 *data, *cursor, reply;
00177 
00178         g_return_if_fail(gc != NULL && gc->proto_data != NULL);
00179         g_return_if_fail(buf != NULL && buf_len != 0);
00180 
00181         qd = (qq_data *) gc->proto_data;
00182         len = buf_len;
00183         data = g_newa(guint8, len);
00184 
00185         if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) {
00186                 cursor = data;
00187                 read_packet_b(data, &cursor, len, &reply);
00188                 if (reply != QQ_CHANGE_ONLINE_STATUS_REPLY_OK) {
00189                         gaim_debug(GAIM_DEBUG_WARNING, "QQ", "Change status fail\n");
00190                 } else
00191                         gaim_debug(GAIM_DEBUG_INFO, "QQ", "Change status OK\n");
00192         } else
00193                 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Error decrypt chg status reply\n");
00194 
00195 }                               // qq_process_change_status_reply
00196 
00197 /*****************************************************************************/
00198 // it is a server message 
00199 // indicating that one of my buddies changes its status
00200 void qq_process_friend_change_status(guint8 * buf, gint buf_len, GaimConnection * gc) {
00201         qq_data *qd;
00202         gint len, bytes;
00203         guint32 my_uid;
00204         guint8 *data, *cursor;
00205         GaimBuddy *b;
00206         qq_buddy *q_bud;
00207         qq_buddy_status *s;
00208         gchar *name;
00209 
00210         g_return_if_fail(gc != NULL && gc->proto_data != NULL);
00211         g_return_if_fail(buf != NULL && buf_len != 0);
00212 
00213         qd = (qq_data *) gc->proto_data;
00214         len = buf_len;
00215         data = g_newa(guint8, len);
00216         cursor = data;
00217 
00218         if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) {
00219                 s = g_new0(qq_buddy_status, 1);
00220                 bytes = 0;
00221                 // 000-030: qq_buddy_status;
00222                 bytes += _qq_buddy_status_read(data, &cursor, len, s);
00223                 // 031-034: my uid
00224                 bytes += read_packet_dw(data, &cursor, len, &my_uid);
00225 
00226                 if (my_uid == 0 || bytes != 35) {
00227                         g_free(s->ip);
00228                         g_free(s->unknown_key);
00229                         g_free(s);
00230                         return;
00231                 }
00232                 if (QQ_DEBUG)
00233                         _qq_buddy_status_dump_unclear(s);
00234 
00235                 name = uid_to_gaim_name(s->uid);        //by gfhuang
00236                 b = gaim_find_buddy(gc->account, name);
00237                 g_free(name);
00238                 q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data;
00239                 if (q_bud) {
00240                         gaim_debug(GAIM_DEBUG_INFO, "QQ", "s->uid = %d, q_bud->uid = %d\n", s->uid , q_bud->uid);
00241                         if(0 != *((guint32 *)s->ip)) { //by gfhuang
00242                         g_memmove(q_bud->ip, s->ip, 4);
00243                         q_bud->port = s->port;
00244                         }
00245                         q_bud->status = s->status;
00246                         if(0 != s->client_version) 
00247                                 q_bud->client_version = s->client_version;  //gfhuang
00248                         qq_update_buddy_contact(gc, q_bud);
00249                 }
00250                 g_free(s->ip);
00251                 g_free(s->unknown_key);
00252                 g_free(s);
00253         } else
00254                 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Error decrypt buddy status change packet\n");
00255 
00256 }                               // qq_process_friend_change_status
00257 
00258 /*****************************************************************************/
00259 // END OF FILE

Generated at Mon May 8 15:41:23 2006 for OpenQ by  doxygen 1.4.4