⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 buddy_info.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* so we only have one dialog open at a time */	qd = (qq_data *) gc->proto_data;	if (!qd->modifying_info) {		qd->modifying_info = TRUE;		fields = purple_request_fields_new();		group = setup_field_group(fields, QQ_PRIMARY_INFORMATION);		field = purple_request_field_string_new("uid", QQ_NUMBER, info->uid, FALSE);		purple_request_field_group_add_field(group, field);		purple_request_field_string_set_editable(field, FALSE);		add_string_field_to_group(group, "nick", QQ_NICKNAME, info->nick);		add_string_field_to_group(group, "name", QQ_NAME, info->name);		add_string_field_to_group(group, "age", QQ_AGE, info->age);		add_choice_field_to_group(group, "gender", QQ_GENDER, info->gender, genders, QQ_GENDER_SIZE);		add_string_field_to_group(group, "country", QQ_COUNTRY, info->country);		add_string_field_to_group(group, "province", QQ_PROVINCE, info->province);		add_string_field_to_group(group, "city", QQ_CITY, info->city);		group = setup_field_group(fields, QQ_ADDITIONAL_INFORMATION);		add_choice_field_to_group(group, "horoscope", QQ_HOROSCOPE, info->horoscope, horoscope_names, QQ_HOROSCOPE_SIZE);		add_string_field_to_group(group, "occupation", QQ_OCCUPATION, info->occupation);		add_choice_field_to_group(group, "zodiac", QQ_ZODIAC, info->zodiac, zodiac_names, QQ_ZODIAC_SIZE);		add_choice_field_to_group(group, "blood", QQ_BLOOD, info->blood, blood_types, QQ_BLOOD_SIZE);		add_string_field_to_group(group, "college", QQ_COLLEGE, info->college);		add_string_field_to_group(group, "email", QQ_EMAIL, info->email);		add_string_field_to_group(group, "address", QQ_ADDRESS, info->address);		add_string_field_to_group(group, "zipcode", QQ_ZIPCODE, info->zipcode);		add_string_field_to_group(group, "hp_num", QQ_CELL, info->hp_num);		add_string_field_to_group(group, "tel", QQ_TELEPHONE, info->tel);		add_string_field_to_group(group, "homepage", QQ_HOMEPAGE, info->homepage);		group = setup_field_group(fields, QQ_INTRO);		field = purple_request_field_string_new("intro", QQ_INTRO, info->intro, TRUE);		purple_request_field_group_add_field(group, field);		/* prepare unmodifiable info */		mid = g_new0(modify_info_data, 1);		mid->gc = gc;		/* QQ_CONTACT_FIELDS+1 so that the array is NULL-terminated and can be g_strfreev()'ed later */		mid->info = (contact_info *) g_new0(gchar *, QQ_CONTACT_FIELDS+1);		mid->info->pager_sn = g_strdup(info->pager_sn);		mid->info->pager_num = g_strdup(info->pager_num);		mid->info->pager_sp = g_strdup(info->pager_sp);		mid->info->pager_base_num = g_strdup(info->pager_base_num);		mid->info->pager_type = g_strdup(info->pager_type);		mid->info->auth_type = g_strdup(info->auth_type);		mid->info->unknown1 = g_strdup(info->unknown1);		mid->info->unknown2 = g_strdup(info->unknown2);		mid->info->face = g_strdup(info->face);		mid->info->hp_type = g_strdup(info->hp_type);		mid->info->unknown3 = g_strdup(info->unknown3);		mid->info->unknown4 = g_strdup(info->unknown4);		mid->info->unknown5 = g_strdup(info->unknown5);		/* TODO stop hiding these 2 */		mid->info->is_open_hp = g_strdup(info->is_open_hp);		mid->info->is_open_contact = g_strdup(info->is_open_contact);		mid->info->qq_show = g_strdup(info->qq_show);		mid->info->unknown6 = g_strdup(info->unknown6);		purple_request_fields(gc, _("Modify my information"),			_("Modify my information"), NULL, fields,			_("Update my information"), G_CALLBACK(modify_info_ok_cb),			_("Cancel"), G_CALLBACK(modify_info_cancel_cb),			purple_connection_get_account(gc), NULL, NULL,			mid);	}}/* process the reply of modify_info packet */void qq_process_modify_info_reply(guint8 *buf, gint buf_len, PurpleConnection *gc){	qq_data *qd;	gint len;	guint8 *data;	g_return_if_fail(buf != NULL && buf_len != 0);	qd = (qq_data *) gc->proto_data;	len = buf_len;	data = g_newa(guint8, len);	if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) {		data[len] = '\0';		if (qd->uid == atoi((gchar *) data)) {	/* return should be my uid */			purple_debug(PURPLE_DEBUG_INFO, "QQ", "Update info ACK OK\n");			purple_notify_info(gc, NULL, _("Your information has been updated"), NULL);		}	} else {		purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Error decrypt modify info reply\n");	}}static void _qq_send_packet_modify_face(PurpleConnection *gc, gint face_num){	PurpleAccount *account = purple_connection_get_account(gc);	PurplePresence *presence = purple_account_get_presence(account);	qq_data *qd = (qq_data *) gc->proto_data;	gint offset;	if(purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_INVISIBLE)) {		offset = 2;	} else if(purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_AWAY)			|| purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_EXTENDED_AWAY)) {		offset = 1;	} else {		offset = 0;	}	qd->my_icon = 3 * (face_num - 1) + offset;	qd->modifying_face = TRUE;	qq_send_packet_get_info(gc, qd->uid, FALSE);}void qq_set_buddy_icon_for_user(PurpleAccount *account, const gchar *who, const gchar *icon_num, const gchar *iconfile){	gchar *data;	gsize len;	if (!g_file_get_contents(iconfile, &data, &len, NULL))		g_return_if_reached();	else	{		purple_buddy_icons_set_for_user(account, who, data, len, icon_num);	}}/* TODO: custom faces for QQ members and users with level >= 16 */void qq_set_my_buddy_icon(PurpleConnection *gc, PurpleStoredImage *img){	gchar *icon;	gint icon_num;	gint icon_len;	PurpleAccount *account = purple_connection_get_account(gc);	const gchar *icon_path = purple_account_get_buddy_icon_path(account);	const gchar *buddy_icon_dir = qq_buddy_icon_dir();	gint prefix_len = strlen(QQ_ICON_PREFIX);	gint suffix_len = strlen(QQ_ICON_SUFFIX);	gint dir_len = strlen(buddy_icon_dir);	gchar *errmsg = g_strdup_printf(_("Setting custom faces is not currently supported. Please choose an image from %s."), buddy_icon_dir);	gboolean icon_global = purple_account_get_bool(gc->account, "use-global-buddyicon", TRUE);	if (!icon_path)		icon_path = "";	icon_len = strlen(icon_path) - dir_len - 1 - prefix_len - suffix_len;	/* make sure we're using an appropriate icon */	if (!(g_ascii_strncasecmp(icon_path, buddy_icon_dir, dir_len) == 0		&& icon_path[dir_len] == G_DIR_SEPARATOR			&& g_ascii_strncasecmp(icon_path + dir_len + 1, QQ_ICON_PREFIX, prefix_len) == 0			&& g_ascii_strncasecmp(icon_path + dir_len + 1 + prefix_len + icon_len, QQ_ICON_SUFFIX, suffix_len) == 0			&& icon_len <= 3)) {		if (icon_global)			purple_debug(PURPLE_DEBUG_ERROR, "QQ", "%s\n", errmsg);		else			purple_notify_error(gc, _("Invalid QQ Face"), errmsg, NULL);		g_free(errmsg);		return;	}	/* strip everything but number */	icon = g_strndup(icon_path + dir_len + 1 + prefix_len, icon_len);	icon_num = strtol(icon, NULL, 10);	g_free(icon);	/* ensure face number in proper range */	if (icon_num > QQ_FACES) {		if (icon_global)			purple_debug(PURPLE_DEBUG_ERROR, "QQ", "%s\n", errmsg);		else			purple_notify_error(gc, _("Invalid QQ Face"), errmsg, NULL);		g_free(errmsg);		return;	}	g_free(errmsg);	/* tell server my icon changed */	_qq_send_packet_modify_face(gc, icon_num);	/* display in blist */	qq_set_buddy_icon_for_user(account, account->username, icon, icon_path);}static void _qq_update_buddy_icon(PurpleAccount *account, const gchar *name, gint face){	PurpleBuddy *buddy;	gchar *icon_num_str = face_to_icon_str(face);	const gchar *old_icon_num = NULL;	if ((buddy = purple_find_buddy(account, name)))		old_icon_num = purple_buddy_icons_get_checksum_for_user(buddy);	if (old_icon_num == NULL ||	    strcmp(icon_num_str, old_icon_num))	{		gchar *icon_path;		icon_path = g_strconcat(qq_buddy_icon_dir(), G_DIR_SEPARATOR_S,		                        QQ_ICON_PREFIX, icon_num_str,		                        QQ_ICON_SUFFIX, NULL);		qq_set_buddy_icon_for_user(account, name, icon_num_str, icon_path);		g_free(icon_path);	}	g_free(icon_num_str);}/* after getting info or modify myself, refresh the buddy list accordingly */void qq_refresh_buddy_and_myself(contact_info *info, PurpleConnection *gc){	PurpleBuddy *b;	qq_data *qd;	qq_buddy *q_bud;	gchar *alias_utf8, *purple_name;	PurpleAccount *account = purple_connection_get_account(gc);	qd = (qq_data *) gc->proto_data;	purple_name = uid_to_purple_name(strtol(info->uid, NULL, 10));	alias_utf8 = qq_to_utf8(info->nick, QQ_CHARSET_DEFAULT);	if (qd->uid == strtol(info->uid, NULL, 10)) {	/* it is me */		qd->my_icon = strtol(info->face, NULL, 10);		if (alias_utf8 != NULL)			purple_account_set_alias(account, alias_utf8);	}	/* update buddy list (including myself, if myself is the buddy) */	b = purple_find_buddy(gc->account, purple_name);	q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data;	if (q_bud != NULL) {	/* I have this buddy */		q_bud->age = strtol(info->age, NULL, 10);		q_bud->gender = strtol(info->gender, NULL, 10);		q_bud->face = strtol(info->face, NULL, 10);		if (alias_utf8 != NULL)			q_bud->nickname = g_strdup(alias_utf8);		qq_update_buddy_contact(gc, q_bud);		_qq_update_buddy_icon(gc->account, purple_name, q_bud->face);	}	g_free(purple_name);	g_free(alias_utf8);}/* process reply to get_info packet */void qq_process_get_info_reply(guint8 *buf, gint buf_len, PurpleConnection *gc){	gint len;	guint8 *data;	gchar **segments;	qq_info_query *query;	qq_data *qd;	contact_info *info;	GList *list, *query_list;	PurpleNotifyUserInfo *user_info;	g_return_if_fail(buf != NULL && buf_len != 0);	qd = (qq_data *) gc->proto_data;	list = query_list = NULL;	len = buf_len;	data = g_newa(guint8, len);	info = NULL;	if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) {		if (NULL == (segments = split_data(data, len, "\x1e", QQ_CONTACT_FIELDS)))			return;		info = (contact_info *) segments;		if (qd->modifying_face && strtol(info->face, NULL, 10) != qd->my_icon) {			gchar *icon = g_strdup_printf("%d", qd->my_icon);			qd->modifying_face = FALSE;			g_free(info->face);			info->face = icon;			qq_send_packet_modify_info(gc, segments);		}		qq_refresh_buddy_and_myself(info, gc);		query_list = qd->info_query;		/* ensure we're processing the right query */		while (query_list) {			query = (qq_info_query *) query_list->data;			if (query->uid == atoi(info->uid)) {				if (query->show_window) {					user_info = info_to_notify_user_info(info);					purple_notify_userinfo(gc, info->uid, user_info, NULL, NULL);					purple_notify_user_info_destroy(user_info);				} else if (query->modify_info) {					create_modify_info_dialogue(gc, info);				}				qd->info_query = g_list_remove(qd->info_query, qd->info_query->data);				g_free(query);				break;			}			query_list = query_list->next;		}		g_strfreev(segments);	} else {		purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Error decrypt get info reply\n");	}}void qq_info_query_free(qq_data *qd){	gint i;	qq_info_query *p;	g_return_if_fail(qd != NULL);	i = 0;	while (qd->info_query != NULL) {		p = (qq_info_query *) (qd->info_query->data);		qd->info_query = g_list_remove(qd->info_query, p);		g_free(p);		i++;	}	purple_debug(PURPLE_DEBUG_INFO, "QQ", "%d info queries are freed!\n", i);}void qq_send_packet_get_level(PurpleConnection *gc, guint32 uid){	guint8 buf[5];	guint32 tmp = g_htonl(uid);	buf[0] = 0;	memcpy(buf+1, &tmp, 4);	qq_send_cmd(gc, QQ_CMD_GET_LEVEL, TRUE, 0, TRUE, buf, 5);}void qq_send_packet_get_buddies_levels(PurpleConnection *gc){	guint8 *buf, *tmp;	guint16 size;	qq_buddy *q_bud;	qq_data *qd = (qq_data *) gc->proto_data;	GList *node = qd->buddies;	if (qd->buddies) {		/* server only sends back levels for online buddies, no point 	 	* in asking for anyone else */		size = 4*g_list_length(qd->buddies) + 1;		buf = g_new0(guint8, size);		tmp = buf + 1;		while (node != NULL) {			guint32 tmp4;			q_bud = (qq_buddy *) node->data;			if (q_bud != NULL) {				tmp4 = g_htonl(q_bud->uid);				memcpy(tmp, &tmp4, 4);				tmp += 4;			}			node = node->next;		}		qq_send_cmd(gc, QQ_CMD_GET_LEVEL, TRUE, 0, TRUE, buf, size);		g_free(buf);	}}void qq_process_get_level_reply(guint8 *buf, gint buf_len, PurpleConnection *gc){	guint32 uid, onlineTime;	guint16 level, timeRemainder;	gchar *purple_name;	PurpleBuddy *b;	qq_buddy *q_bud;	gint decr_len, i;	guint8 *decr_buf, *tmp;	PurpleAccount *account = purple_connection_get_account(gc);	qq_data *qd = (qq_data *) gc->proto_data;		decr_len = buf_len;	decr_buf = g_new0(guint8, buf_len);	if (!qq_crypt(DECRYPT, buf, buf_len, qd->session_key, decr_buf, &decr_len)) {		purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Couldn't decrypt get level packet\n");	}	decr_len--; 	if (decr_len % 12 != 0) {		purple_debug(PURPLE_DEBUG_ERROR, "QQ", 			"Get levels list of abnormal length. Truncating last %d bytes.\n", decr_len % 12);		decr_len -= (decr_len % 12);	}			tmp = decr_buf + 1;	/* this byte seems random */	/*	purple_debug(PURPLE_DEBUG_INFO, "QQ", "Byte one of get_level packet: %d\n", buf[0]);	*/	for (i = 0; i < decr_len; i += 12) {		uid = g_ntohl(*(guint32 *) tmp);		tmp += 4;		onlineTime = g_ntohl(*(guint32 *) tmp);		tmp += 4;		level = g_ntohs(*(guint16 *) tmp);		tmp += 2;		timeRemainder = g_ntohs(*(guint16 *) tmp);		tmp += 2;		/*		purple_debug(PURPLE_DEBUG_INFO, "QQ", "Level packet entry:\nuid: %d\nonlineTime: %d\nlevel: %d\ntimeRemainder: %d\n", 				uid, onlineTime, level, timeRemainder);		*/		purple_name = uid_to_purple_name(uid);		b = purple_find_buddy(account, purple_name);		q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data;		if (q_bud != NULL || uid == qd->uid) {			if (q_bud) {				q_bud->onlineTime = onlineTime;				q_bud->level = level;				q_bud->timeRemainder = timeRemainder;			}			if (uid == qd->uid) {				qd->my_level = level;			}		} else {			purple_debug(PURPLE_DEBUG_ERROR, "QQ", 				"Got an online buddy %d, but not in my buddy list\n", uid);		}		g_free(purple_name);	}	g_free(decr_buf);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -