static void do_server_notice(PurpleConnection *gc, gchar *from, gchar *to, guint8 *data, gint data_len) { qq_data *qd = (qq_data *) gc->proto_data; gchar *msg, *msg_utf8; gchar *title, *content; g_return_if_fail(from != NULL && to != NULL && data_len > 0); msg = g_strndup((gchar *)data, data_len); msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT); g_free(msg); if (msg_utf8 == NULL) { purple_debug_error("QQ", "Recv NULL sys msg from %s to %s, discard\n", from, to); return; } title = g_strdup_printf(_("From %s:"), from); content = g_strdup_printf(_("Server notice From %s: \n%s"), from, msg_utf8); if (qd->is_show_notice) { qq_got_message(gc, content); } else { purple_debug_info("QQ", "QQ Server notice from %s:\n%s\n", from, msg_utf8); } g_free(msg_utf8); g_free(title); g_free(content); }
/* someone wants to add you to his buddy list */ static void server_buddy_add_request(PurpleConnection *gc, gchar *from, gchar *to, guint8 *data, gint data_len) { guint32 uid; gchar *msg, *reason; g_return_if_fail(from != NULL && to != NULL); uid = strtoul(from, NULL, 10); g_return_if_fail(uid != 0); if (purple_prefs_get_bool("/plugins/prpl/qq/auto_get_authorize_info")) { qq_request_buddy_info(gc, uid, 0, QQ_BUDDY_INFO_DISPLAY); } if (data_len <= 0) { reason = g_strdup( _("No reason given") ); } else { msg = g_strndup((gchar *)data, data_len); reason = qq_to_utf8(msg, QQ_CHARSET_DEFAULT); if (reason == NULL) reason = g_strdup( _("Unknown reason") ); g_free(msg); } buddy_add_input(gc, uid, reason); g_free(reason); }
static void do_got_sms(PurpleConnection *gc, guint8 *data, gint data_len) { gint bytes; gchar *mobile = NULL; gchar *msg = NULL; gchar *msg_utf8 = NULL; gchar *msg_formated; g_return_if_fail(data != NULL && data_len > 26); qq_show_packet("Rcv sms", data, data_len); bytes = 0; bytes += 1; /* skip 0x00 */ mobile = g_strndup((gchar *)data + bytes, 20); bytes += 20; bytes += 5; /* skip 0x(49 11 98 d5 03)*/ if (bytes < data_len) { msg = g_strndup((gchar *)data + bytes, data_len - bytes); msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT); g_free(msg); } else { msg_utf8 = g_strdup(""); } msg_formated = g_strdup_printf(_("%s:%s"), mobile, msg_utf8); qq_got_message(gc, msg_formated); g_free(msg_formated); g_free(msg_utf8); g_free(mobile); }
/* you are rejected by the person */ static void server_buddy_rejected_me(PurpleConnection *gc, gchar *from, gchar *to, guint8 *data, gint data_len) { guint32 uid; PurpleBuddy *buddy; gchar *msg, *msg_utf8; gint bytes; gchar **segments; gchar *primary, *secondary; qq_buddy_data *bd; g_return_if_fail(from != NULL && to != NULL); qq_show_packet("server_buddy_rejected_me", data, data_len); if (data_len <= 0) { msg = g_strdup( _("No reason given") ); } else { segments = g_strsplit((gchar *)data, "\x1f", 1); if (segments != NULL && segments[0] != NULL) { msg = g_strdup(segments[0]); g_strfreev(segments); bytes = strlen(msg) + 1; if (bytes < data_len) { server_buddy_check_code(gc, from, data + bytes, data_len - bytes); } } else { msg = g_strdup( _("No reason given") ); } } msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT); if (msg_utf8 == NULL) { msg_utf8 = g_strdup( _("Unknown reason") ); } g_free(msg); primary = g_strdup_printf(_("Rejected by %s"), from); secondary = g_strdup_printf(_("Message: %s"), msg_utf8); purple_notify_info(gc, _("QQ Buddy"), primary, secondary); g_free(msg_utf8); g_free(primary); g_free(secondary); uid = strtoul(from, NULL, 10); g_return_if_fail(uid != 0); buddy = qq_buddy_find(gc, uid); if (buddy != NULL && (bd = purple_buddy_get_protocol_data(buddy)) != NULL) { /* Not authorized now, free buddy data */ qq_buddy_data_free(bd); purple_buddy_set_protocol_data(buddy, NULL); } }
/* after getting info or modify myself, refresh the buddy list accordingly */ static void update_buddy_info(PurpleConnection *gc, gchar **segments) { PurpleBuddy *buddy; qq_data *qd; qq_buddy_data *bd; guint32 uid; gchar *who; gchar *alias_utf8; PurpleAccount *account = purple_connection_get_account(gc); qd = (qq_data *) gc->proto_data; uid = strtoul(segments[QQ_INFO_UID], NULL, 10); who = uid_to_purple_name(uid); qq_filter_str(segments[QQ_INFO_NICK]); alias_utf8 = qq_to_utf8(segments[QQ_INFO_NICK], QQ_CHARSET_DEFAULT); if (uid == qd->uid) { /* it is me */ purple_debug_info("QQ", "Got my info\n"); qd->my_icon = strtol(segments[QQ_INFO_FACE], NULL, 10); if (alias_utf8 != NULL) { purple_account_set_alias(account, alias_utf8); } /* add me to buddy list */ buddy = qq_buddy_find_or_new(gc, uid); } else { buddy = purple_find_buddy(gc->account, who); } if (buddy == NULL || buddy->proto_data == NULL) { g_free(who); g_free(alias_utf8); return; } /* update buddy list (including myself, if myself is the buddy) */ bd = (qq_buddy_data *)buddy->proto_data; bd->age = strtol(segments[QQ_INFO_AGE], NULL, 10); bd->gender = strtol(segments[QQ_INFO_GENDER], NULL, 10); bd->face = strtol(segments[QQ_INFO_FACE], NULL, 10); if (alias_utf8 != NULL) { if (bd->nickname) g_free(bd->nickname); bd->nickname = g_strdup(alias_utf8); } bd->last_update = time(NULL); purple_blist_server_alias_buddy(buddy, bd->nickname); /* convert face num from packet (0-299) to local face (1-100) */ qq_update_buddy_icon(gc->account, who, bd->face); g_free(who); g_free(alias_utf8); }
static void field_request_new(PurpleRequestFieldGroup *group, gint index, gchar **segments) { PurpleRequestField *field; gchar *utf8_value; int choice_num; int i; g_return_if_fail(index >=0 && segments[index] != NULL && index < QQ_INFO_LAST); switch (field_infos[index].type) { case QQ_FIELD_STRING: case QQ_FIELD_MULTI: utf8_value = qq_to_utf8(segments[index], QQ_CHARSET_DEFAULT); if (field_infos[index].type == QQ_FIELD_STRING) { field = purple_request_field_string_new( field_infos[index].id, field_infos[index].text, utf8_value, FALSE); } else { field = purple_request_field_string_new( field_infos[index].id, field_infos[index].text, utf8_value, TRUE); } purple_request_field_group_add_field(group, field); g_free(utf8_value); break; case QQ_FIELD_BOOL: field = purple_request_field_bool_new( field_infos[index].id, field_infos[index].text, strtol(segments[index], NULL, 10) ? TRUE : FALSE); purple_request_field_group_add_field(group, field); break; case QQ_FIELD_CHOICE: choice_num = strtol(segments[index], NULL, 10); if (choice_num < 0 || choice_num >= field_infos[index].choice_size) choice_num = 0; if (index == QQ_INFO_GENDER && strlen(segments[index]) != 0) { for (i = 0; i < QQ_GENDER_SIZE; i++) { if (strcmp(segments[index], genders_zh[i]) == 0) { choice_num = i; } } } field = purple_request_field_choice_new( field_infos[index].id, field_infos[index].text, choice_num); for (i = 0; i < field_infos[index].choice_size; i++) { purple_request_field_choice_add(field, field_infos[index].choice[i]); } purple_request_field_group_add_field(group, field); break; case QQ_FIELD_LABEL: default: field = purple_request_field_label_new(field_infos[index].id, segments[index]); purple_request_field_group_add_field(group, field); break; } }
/* process login reply which says wrong password */ static gint _qq_process_login_wrong_pwd(PurpleConnection *gc, guint8 *data, gint len) { gchar *server_reply, *server_reply_utf8; server_reply = g_new0(gchar, len); g_memmove(server_reply, data + 1, len - 1); server_reply_utf8 = qq_to_utf8(server_reply, QQ_CHARSET_DEFAULT); purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Wrong password, server msg in UTF8: %s\n", server_reply_utf8); g_free(server_reply); g_free(server_reply_utf8); return QQ_LOGIN_REPLY_PWD_ERROR; }
static void process_level_2007(PurpleConnection *gc, guint8 *data, gint data_len) { gint bytes; guint32 uid, onlineTime; guint16 level, timeRemainder; qq_buddy_data *bd; guint16 str_len; gchar *str; gchar *str_utf8; bytes = 0; bytes += qq_get32(&uid, data + bytes); bytes += qq_get32(&onlineTime, data + bytes); bytes += qq_get16(&level, data + bytes); bytes += qq_get16(&timeRemainder, data + bytes); purple_debug_info("QQ", "level: %d, uid %u, tmOnline: %d, tmRemainder: %d\n", level, uid, onlineTime, timeRemainder); bd = qq_buddy_data_find(gc, uid); if (bd == NULL) { purple_debug_error("QQ", "Got levels of %u not in my buddy list\n", uid); return; } bd->onlineTime = onlineTime; bd->level = level; bd->timeRemainder = timeRemainder; /* extend bytes in qq2007*/ bytes += 4; /* skip 8 bytes */ /* qq_show_packet("Buddies level", data + bytes, data_len - bytes); */ do { bytes += qq_get16(&str_len, data + bytes); if (str_len <= 0 || bytes + str_len > data_len) { purple_debug_error("QQ", "Wrong format of Get levels. Truncate %d bytes.\n", data_len - bytes); break; } str = g_strndup((gchar *)data + bytes, str_len); bytes += str_len; str_utf8 = qq_to_utf8(str, QQ_CHARSET_DEFAULT); purple_debug_info("QQ", "%s\n", str_utf8); g_free(str_utf8); g_free(str); } while (bytes < data_len); }
static void info_display_only(PurpleConnection *gc, gchar **segments) { PurpleNotifyUserInfo *user_info; gchar *utf8_value; int index; int choice_num; user_info = purple_notify_user_info_new(); for (index = 1; segments[index] != NULL && index < QQ_INFO_LAST; index++) { if (field_infos[index].iclass == QQ_FIELD_UNUSED) { continue; } switch (field_infos[index].type) { case QQ_FIELD_BOOL: purple_notify_user_info_add_pair(user_info, field_infos[index].text, strtol(segments[index], NULL, 10) ? _("True") : _("False")); break; case QQ_FIELD_CHOICE: choice_num = strtol(segments[index], NULL, 10); if (choice_num < 0 || choice_num >= field_infos[index].choice_size) { choice_num = 0; } purple_notify_user_info_add_pair(user_info, field_infos[index].text, field_infos[index].choice[choice_num]); break; case QQ_FIELD_LABEL: case QQ_FIELD_STRING: case QQ_FIELD_MULTI: default: if (strlen(segments[index]) != 0) { utf8_value = qq_to_utf8(segments[index], QQ_CHARSET_DEFAULT); purple_notify_user_info_add_pair(user_info, field_infos[index].text, utf8_value); g_free(utf8_value); } break; } } purple_notify_userinfo(gc, segments[0], user_info, NULL, NULL); purple_notify_user_info_destroy(user_info); g_strfreev(segments); }
static void process_room_cmd_notify(PurpleConnection *gc, guint8 room_cmd, guint8 room_id, guint8 reply, guint8 *data, gint data_len) { gchar *prim; gchar *msg, *msg_utf8; g_return_if_fail(data != NULL && data_len > 0); msg = g_strndup((gchar *) data, data_len); /* it will append 0x00 */ msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT); g_free(msg); prim = g_strdup_printf(_("Error reply of %s(0x%02X)\nRoom %u, reply 0x%02X"), qq_get_room_cmd_desc(room_cmd), room_cmd, room_id, reply); purple_notify_error(gc, _("QQ Qun Command"), prim, msg_utf8); g_free(prim); g_free(msg_utf8); }
static void info_debug(gchar **segments) { #if 0 int index; gchar *utf8_str; for (index = 0; segments[index] != NULL && index < QQ_INFO_LAST; index++) { if (field_infos[index].type == QQ_FIELD_STRING || field_infos[index].type == QQ_FIELD_LABEL || field_infos[index].type == QQ_FIELD_MULTI || index == QQ_INFO_GENDER) { utf8_str = qq_to_utf8(segments[index], QQ_CHARSET_DEFAULT); purple_debug_info("QQ_BUDDY_INFO", "%s: %s\n", field_infos[index].text, utf8_str); g_free(utf8_str); continue; } purple_debug_info("QQ_BUDDY_INFO", "%s: %s\n", field_infos[index].text, segments[index]); } #endif }
/* process reply to add_buddy_auth request */ void qq_process_add_buddy_auth(guint8 *data, gint data_len, PurpleConnection *gc) { qq_data *qd; gchar **segments, *msg_utf8; g_return_if_fail(data != NULL && data_len != 0); qd = (qq_data *) gc->proto_data; if (data[0] == '0') { purple_debug_info("QQ", "Reply OK for sending authorize\n"); return; } if (NULL == (segments = split_data(data, data_len, "\x1f", 2))) { purple_notify_error(gc, _("QQ Buddy"), _("Failed sending authorize"), NULL); return; } msg_utf8 = qq_to_utf8(segments[1], QQ_CHARSET_DEFAULT); purple_notify_error(gc, _("QQ Buddy"), _("Failed sending authorize"), msg_utf8); g_free(msg_utf8); }
/* recv an IM from a group chat */ void qq_process_room_im(guint8 *data, gint data_len, guint32 id, PurpleConnection *gc, guint16 msg_type) { qq_data *qd; gchar *msg_smiley, *msg_fmt, *msg_utf8; gint bytes, tail_len; struct { guint32 ext_id; guint8 type8; guint32 member_uid; guint16 unknown; guint16 msg_seq; time_t send_time; guint32 version; guint16 msg_len; gchar *msg; } im_text; guint32 temp_id; guint16 content_type; guint8 frag_count, frag_index; guint16 msg_id; qq_im_format *fmt = NULL; /* at least include im_text.msg_len */ g_return_if_fail(data != NULL && data_len > 23); qd = (qq_data *) gc->proto_data; /* qq_show_packet("ROOM_IM", data, data_len); */ memset(&im_text, 0, sizeof(im_text)); bytes = 0; bytes += qq_get32(&(im_text.ext_id), data + bytes); bytes += qq_get8(&(im_text.type8), data + bytes); if(QQ_MSG_TEMP_QUN_IM == msg_type) { bytes += qq_get32(&temp_id, data + bytes); } bytes += qq_get32(&(im_text.member_uid), bytes + data); bytes += qq_get16(&im_text.unknown, data + bytes); /* 0x0001? */ bytes += qq_get16(&(im_text.msg_seq), data + bytes); bytes += qq_getime(&im_text.send_time, data + bytes); bytes += qq_get32(&im_text.version, data + bytes); bytes += qq_get16(&(im_text.msg_len), data + bytes); purple_debug_info("QQ", "Room IM, ext id %u, seq %u, version 0x%04X, len %u\n", im_text.ext_id, im_text.msg_seq, im_text.version, im_text.msg_len); if (im_text.msg_len != data_len - bytes) { purple_debug_warning("QQ", "Room IM length %d should be %d\n", im_text.msg_len, data_len - bytes); im_text.msg_len = data_len - bytes; } g_return_if_fail(im_text.msg_len > 0 && bytes + im_text.msg_len <= data_len); if(msg_type != QQ_MSG_QUN_IM_UNKNOWN) { g_return_if_fail(im_text.msg_len >= 10); bytes += qq_get16(&content_type, data + bytes); bytes += qq_get8(&frag_count, data + bytes); bytes += qq_get8(&frag_index, data + bytes); bytes += qq_get16(&msg_id, data + bytes); bytes += 4; /* skip 0x(00 00 00 00) */ purple_debug_info("QQ", "Room IM, content %d, frag %d-%d, msg id %u\n", content_type, frag_count, frag_index, msg_id); im_text.msg_len -= 10; } g_return_if_fail(im_text.msg_len > 0); /* qq_show_packet("Message", data + bytes, data_len - bytes); */ if (frag_count <= 1 || frag_count == frag_index + 1) { fmt = qq_im_fmt_new(); tail_len = qq_get_im_tail(fmt, data + bytes, data_len - bytes); im_text.msg = g_strndup((gchar *)(data + bytes), data_len - tail_len); } else { im_text.msg = g_strndup((gchar *)(data + bytes), data_len - bytes); } /* group im_group has no flag to indicate whether it has font_attr or not */ msg_smiley = qq_emoticon_to_purple(im_text.msg); if (fmt != NULL) { msg_fmt = qq_im_fmt_to_purple(fmt, msg_smiley); msg_utf8 = qq_to_utf8(msg_fmt, QQ_CHARSET_DEFAULT); g_free(msg_fmt); qq_im_fmt_free(fmt); } else { msg_utf8 = qq_to_utf8(msg_smiley, QQ_CHARSET_DEFAULT); } g_free(msg_smiley); purple_debug_info("QQ", "Room (%u) IM from %u: %s\n", im_text.ext_id, im_text.member_uid, msg_utf8); qq_room_got_chat_in(gc, id, im_text.member_uid, msg_utf8, im_text.send_time); g_free(msg_utf8); g_free(im_text.msg); }
/* process received extended (2007) text IM */ static void process_extend_im_text(PurpleConnection *gc, guint8 *data, gint len, qq_im_header *im_header) { qq_data *qd; guint16 purple_msg_type; gchar *who; gchar *msg_smiley, *msg_fmt, *msg_utf8; PurpleBuddy *buddy; qq_buddy_data *bd; gint bytes, tail_len; qq_im_format *fmt = NULL; struct { /* now comes the part for text only */ guint16 msg_seq; guint32 send_time; guint16 sender_icon; guint32 has_font_attr; guint8 unknown1[8]; guint8 fragment_count; guint8 fragment_index; guint8 msg_id; guint8 unknown2; guint8 msg_type; gchar *msg; /* no fixed length, ends with 0x00 */ guint8 fromMobileQQ; } im_text; g_return_if_fail (data != NULL && len > 0); g_return_if_fail(im_header != NULL); qd = (qq_data *) gc->proto_data; memset(&im_text, 0, sizeof(im_text)); /* qq_show_packet("Extend IM text", data, len); */ bytes = 0; bytes += qq_get16(&(im_text.msg_seq), data + bytes); bytes += qq_get32(&(im_text.send_time), data + bytes); bytes += qq_get16(&(im_text.sender_icon), data + bytes); bytes += qq_get32(&(im_text.has_font_attr), data + bytes); bytes += qq_getdata(im_text.unknown1, sizeof(im_text.unknown1), data + bytes); bytes += qq_get8(&(im_text.fragment_count), data + bytes); bytes += qq_get8(&(im_text.fragment_index), data + bytes); bytes += qq_get8(&(im_text.msg_id), data + bytes); bytes += 1; /* skip 0x00 */ bytes += qq_get8(&(im_text.msg_type), data + bytes); purple_debug_info("QQ", "IM Seq %u, id %04X, fragment %d-%d, type %d, %s\n", im_text.msg_seq, im_text.msg_id, im_text.fragment_count, im_text.fragment_index, im_text.msg_type, im_text.has_font_attr ? "exist font atrr" : ""); if (im_text.has_font_attr) { fmt = qq_im_fmt_new(); tail_len = qq_get_im_tail(fmt, data + bytes, len - bytes); im_text.msg = g_strndup((gchar *)(data + bytes), len - tail_len); } else { im_text.msg = g_strndup((gchar *)(data + bytes), len - bytes); } /* qq_show_packet("IM text", (guint8 *)im_text.msg , strlen(im_text.msg)); */ if(im_text.fragment_count == 0) im_text.fragment_count = 1; who = uid_to_purple_name(im_header->uid_from); buddy = purple_find_buddy(gc->account, who); if (buddy == NULL) { /* create no-auth buddy */ buddy = qq_buddy_new(gc, im_header->uid_from); } bd = (buddy == NULL) ? NULL : purple_buddy_get_protocol_data(buddy); if (bd != NULL) { bd->client_tag = im_header->version_from; bd->face = im_text.sender_icon; qq_update_buddy_icon(gc->account, who, bd->face); } purple_msg_type = 0; msg_smiley = qq_emoticon_to_purple(im_text.msg); if (fmt != NULL) { msg_fmt = qq_im_fmt_to_purple(fmt, msg_smiley); msg_utf8 = qq_to_utf8(msg_fmt, QQ_CHARSET_DEFAULT); g_free(msg_fmt); qq_im_fmt_free(fmt); } else { msg_utf8 = qq_to_utf8(msg_smiley, QQ_CHARSET_DEFAULT); } g_free(msg_smiley); /* send encoded to purple, note that we use im_text.send_time, * not the time we receive the message * as it may have been delayed when I am not online. */ serv_got_im(gc, who, msg_utf8, purple_msg_type, (time_t) im_text.send_time); g_free(msg_utf8); g_free(who); g_free(im_text.msg); }
/* recv an IM from a group chat */ void qq_process_recv_group_im(guint8 *data, guint8 **cursor, gint data_len, guint32 internal_group_id, GaimConnection *gc, guint16 im_type) { gchar *msg_with_gaim_smiley, *msg_utf8_encoded, *im_src_name, *hex_dump; guint16 unknown; guint32 unknown4; GaimConversation *conv; qq_data *qd; qq_buddy *member; qq_group *group; qq_recv_group_im *im_group; gint skip_len; g_return_if_fail(data != NULL && data_len > 0); qd = (qq_data *) gc->proto_data; hex_dump = hex_dump_to_str(*cursor, data_len - (*cursor - data)); gaim_debug(GAIM_DEBUG_INFO, "QQ", "group im hex dump\n%s\n", hex_dump); if (*cursor >= (data + data_len - 1)) { gaim_debug(GAIM_DEBUG_WARNING, "QQ", "Received group im_group is empty\n"); return; } im_group = g_newa(qq_recv_group_im, 1); read_packet_dw(data, cursor, data_len, &(im_group->external_group_id)); read_packet_b(data, cursor, data_len, &(im_group->group_type)); if(QQ_RECV_IM_TEMP_QUN_IM == im_type) { read_packet_dw(data, cursor, data_len, &(internal_group_id)); } read_packet_dw(data, cursor, data_len, &(im_group->member_uid)); read_packet_w(data, cursor, data_len, &unknown); /* 0x0001? */ read_packet_w(data, cursor, data_len, &(im_group->msg_seq)); read_packet_dw(data, cursor, data_len, (guint32 *) & (im_group->send_time)); read_packet_dw(data, cursor, data_len, &unknown4); /* versionID */ /* * length includes font_attr * this msg_len includes msg and font_attr **** the format is **** * length of all * 1. unknown 10 bytes * 2. 0-ended string * 3. font_attr */ read_packet_w(data, cursor, data_len, &(im_group->msg_len)); g_return_if_fail(im_group->msg_len > 0); /* * 10 bytes from lumaqq * contentType = buf.getChar(); * totalFragments = buf.get() & 255; * fragmentSequence = buf.get() & 255; * messageId = buf.getChar(); * buf.getInt(); */ if(im_type != QQ_RECV_IM_UNKNOWN_QUN_IM) skip_len = 10; else skip_len = 0; *cursor += skip_len; im_group->msg = g_strdup((gchar *) *cursor); *cursor += strlen(im_group->msg) + 1; /* there might not be any font_attr, check it */ im_group->font_attr_len = im_group->msg_len - strlen(im_group->msg) - 1 - skip_len; if (im_group->font_attr_len > 0) im_group->font_attr = g_memdup(*cursor, im_group->font_attr_len); else im_group->font_attr = NULL; /* group im_group has no flag to indicate whether it has font_attr or not */ msg_with_gaim_smiley = qq_smiley_to_gaim(im_group->msg); if (im_group->font_attr_len > 0) msg_utf8_encoded = qq_encode_to_gaim(im_group->font_attr, im_group->font_attr_len, msg_with_gaim_smiley); else msg_utf8_encoded = qq_to_utf8(msg_with_gaim_smiley, QQ_CHARSET_DEFAULT); group = qq_group_find_by_id(gc, internal_group_id, QQ_INTERNAL_ID); g_return_if_fail(group != NULL); conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, group->group_name_utf8, gaim_connection_get_account(gc)); if (conv == NULL && gaim_prefs_get_bool("/plugins/prpl/qq/prompt_group_msg_on_recv")) { serv_got_joined_chat(gc, qd->channel++, group->group_name_utf8); conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, group->group_name_utf8, gaim_connection_get_account(gc)); } if (conv != NULL) { member = qq_group_find_member_by_uid(group, im_group->member_uid); if (member == NULL || member->nickname == NULL) im_src_name = uid_to_gaim_name(im_group->member_uid); else im_src_name = g_strdup(member->nickname); serv_got_chat_in(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT (conv)), im_src_name, 0, msg_utf8_encoded, im_group->send_time); g_free(im_src_name); } g_free(hex_dump); g_free(msg_with_gaim_smiley); g_free(msg_utf8_encoded); g_free(im_group->msg); g_free(im_group->font_attr); }