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

📄 gg.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 *//* static void ggp_bmenu_block(PurpleBlistNode *node, gpointer ignored) {{{ */static void ggp_bmenu_block(PurpleBlistNode *node, gpointer ignored){	PurpleConnection *gc;	PurpleBuddy *buddy;	GGPInfo *info;	uin_t uin;	buddy = (PurpleBuddy *)node;	gc = purple_account_get_connection(purple_buddy_get_account(buddy));	info = gc->proto_data;	uin = ggp_str_to_uin(purple_buddy_get_name(buddy));	if (purple_blist_node_get_bool(node, "blocked")) {		purple_blist_node_set_bool(node, "blocked", FALSE);		gg_remove_notify_ex(info->session, uin, GG_USER_BLOCKED);		gg_add_notify_ex(info->session, uin, GG_USER_NORMAL);		purple_debug_info("gg", "send: uin=%d; mode=NORMAL\n", uin);	} else {		purple_blist_node_set_bool(node, "blocked", TRUE);		gg_remove_notify_ex(info->session, uin, GG_USER_NORMAL);		gg_add_notify_ex(info->session, uin, GG_USER_BLOCKED);		purple_debug_info("gg", "send: uin=%d; mode=BLOCKED\n", uin);	}}/* }}} *//* ---------------------------------------------------------------------- *//* ----- INTERNAL CALLBACKS --------------------------------------------- *//* ---------------------------------------------------------------------- *//* just a prototype */static void ggp_set_status(PurpleAccount *account, PurpleStatus *status);/** * Handle change of the status of the buddy. * * @param gc     PurpleConnection * @param uin    UIN of the buddy. * @param status ID of the status. * @param descr  Description. *//* static void ggp_generic_status_handler(PurpleConnection *gc, uin_t uin, int status, const char *descr) {{{ */static void ggp_generic_status_handler(PurpleConnection *gc, uin_t uin,				       int status, const char *descr){	gchar *from;	const char *st;	gchar *msg;	from = g_strdup_printf("%ld", (unsigned long int)uin);	switch (status) {		case GG_STATUS_NOT_AVAIL:		case GG_STATUS_NOT_AVAIL_DESCR:			st = "offline";			break;		case GG_STATUS_AVAIL:		case GG_STATUS_AVAIL_DESCR:			st = "available";			break;		case GG_STATUS_BUSY:		case GG_STATUS_BUSY_DESCR:			st = "away";			break;		case GG_STATUS_BLOCKED:			/* user is blocking us.... */			st = "blocked";			break;		default:			st = "available";			purple_debug_info("gg",				"GG_EVENT_NOTIFY: Unknown status: %d\n", status);			break;	}	purple_debug_info("gg", "st = %s\n", st);	msg = charset_convert(descr, "CP1250", "UTF-8");	purple_prpl_got_user_status(purple_connection_get_account(gc),				  from, st, "message", msg, NULL);	g_free(from);	g_free(msg);}/* }}} *//* *//* static void ggp_sr_close_cb(gpointer user_data) {{{ */static void ggp_sr_close_cb(gpointer user_data){	GGPSearchForm *form = user_data;	GGPInfo *info = form->user_data;	ggp_search_remove(info->searches, form->seq);	ggp_search_form_destroy(form);}/* }}} *//** * Translate a status' ID to a more user-friendly name. * * @param id The ID of the status. * * @return The user-friendly name of the status. *//* static const char *ggp_status_by_id(unsigned int id) {{{ */static const char *ggp_status_by_id(unsigned int id){	const char *st;	purple_debug_info("gg", "ggp_status_by_id: %d\n", id);	switch (id) {		case GG_STATUS_NOT_AVAIL:			st = _("Offline");			break;		case GG_STATUS_AVAIL:			st = _("Available");			break;		case GG_STATUS_BUSY:			st = _("Away");			break;		default:			st = _("Unknown");			break;	}	return st;}/* }}} *//* *//* static void ggp_pubdir_handle_info(PurpleConnection *gc, gg_pubdir50_t req, GGPSearchForm *form) {{{ */static void ggp_pubdir_handle_info(PurpleConnection *gc, gg_pubdir50_t req,				   GGPSearchForm *form){	PurpleNotifyUserInfo *user_info;	PurpleBuddy *buddy;	char *val, *who;	user_info = purple_notify_user_info_new();	val = ggp_search_get_result(req, 0, GG_PUBDIR50_STATUS);	/* XXX: Use of ggp_str_to_uin() is an ugly hack! */	purple_notify_user_info_add_pair(user_info, _("Status"), ggp_status_by_id(ggp_str_to_uin(val)));	g_free(val);	who = ggp_search_get_result(req, 0, GG_PUBDIR50_UIN);	purple_notify_user_info_add_pair(user_info, _("UIN"), who);	val = ggp_search_get_result(req, 0, GG_PUBDIR50_FIRSTNAME);	purple_notify_user_info_add_pair(user_info, _("First Name"), val);	g_free(val);	val = ggp_search_get_result(req, 0, GG_PUBDIR50_NICKNAME);	purple_notify_user_info_add_pair(user_info, _("Nickname"), val);	g_free(val);	val = ggp_search_get_result(req, 0, GG_PUBDIR50_CITY);	purple_notify_user_info_add_pair(user_info, _("City"), val);	g_free(val);	val = ggp_search_get_result(req, 0, GG_PUBDIR50_BIRTHYEAR);	if (strncmp(val, "0", 1)) {		purple_notify_user_info_add_pair(user_info, _("Birth Year"), val);	}	g_free(val);	/*	 * Include a status message, if exists and buddy is in the blist.	 */	buddy = purple_find_buddy(purple_connection_get_account(gc), who);	if (NULL != buddy) {		PurpleStatus *status;		const char *msg;		char *text;		status = purple_presence_get_active_status(purple_buddy_get_presence(buddy));		msg = purple_status_get_attr_string(status, "message");		if (msg != NULL) {			text = g_markup_escape_text(msg, -1);			purple_notify_user_info_add_pair(user_info, _("Message"), text);			g_free(text);		}	}	val = ggp_buddy_get_name(gc, ggp_str_to_uin(who));	purple_notify_userinfo(gc, val, user_info, ggp_sr_close_cb, form);	g_free(val);	g_free(who);	purple_notify_user_info_destroy(user_info);}/* }}} *//* *//* static void ggp_pubdir_handle_full(PurpleConnection *gc, gg_pubdir50_t req, GGPSearchForm *form) {{{ */static void ggp_pubdir_handle_full(PurpleConnection *gc, gg_pubdir50_t req,				   GGPSearchForm *form){	PurpleNotifySearchResults *results;	PurpleNotifySearchColumn *column;	int res_count;	int start;	int i;	g_return_if_fail(form != NULL);	res_count = gg_pubdir50_count(req);	res_count = (res_count > PUBDIR_RESULTS_MAX) ? PUBDIR_RESULTS_MAX : res_count;	results = purple_notify_searchresults_new();	if (results == NULL) {		purple_debug_error("gg", "ggp_pubdir_reply_handler: "				 "Unable to display the search results.\n");		purple_notify_error(gc, NULL,				  _("Unable to display the search results."),				  NULL);		ggp_sr_close_cb(form);		return;	}	column = purple_notify_searchresults_column_new(_("UIN"));	purple_notify_searchresults_column_add(results, column);	column = purple_notify_searchresults_column_new(_("First Name"));	purple_notify_searchresults_column_add(results, column);	column = purple_notify_searchresults_column_new(_("Nickname"));	purple_notify_searchresults_column_add(results, column);	column = purple_notify_searchresults_column_new(_("City"));	purple_notify_searchresults_column_add(results, column);	column = purple_notify_searchresults_column_new(_("Birth Year"));	purple_notify_searchresults_column_add(results, column);	purple_debug_info("gg", "Going with %d entries\n", res_count);	start = (int)ggp_str_to_uin(gg_pubdir50_get(req, 0, GG_PUBDIR50_START));	purple_debug_info("gg", "start = %d\n", start);	for (i = 0; i < res_count; i++) {		GList *row = NULL;		char *birth = ggp_search_get_result(req, i, GG_PUBDIR50_BIRTHYEAR);		/* TODO: Status will be displayed as an icon. */		/* row = g_list_append(row, ggp_search_get_result(req, i, GG_PUBDIR50_STATUS)); */		row = g_list_append(row, ggp_search_get_result(req, i,							GG_PUBDIR50_UIN));		row = g_list_append(row, ggp_search_get_result(req, i,							GG_PUBDIR50_FIRSTNAME));		row = g_list_append(row, ggp_search_get_result(req, i,							GG_PUBDIR50_NICKNAME));		row = g_list_append(row, ggp_search_get_result(req, i,							GG_PUBDIR50_CITY));		row = g_list_append(row,			(birth && strncmp(birth, "0", 1)) ? birth : g_strdup("-"));		purple_notify_searchresults_row_add(results, row);		if (i == res_count - 1) {			g_free(form->last_uin);			form->last_uin = ggp_search_get_result(req, i, GG_PUBDIR50_UIN);		}	}	purple_notify_searchresults_button_add(results, PURPLE_NOTIFY_BUTTON_CONTINUE,					     ggp_callback_show_next);	purple_notify_searchresults_button_add(results, PURPLE_NOTIFY_BUTTON_ADD,					     ggp_callback_add_buddy);	purple_notify_searchresults_button_add(results, PURPLE_NOTIFY_BUTTON_IM,					     ggp_callback_im);	if (form->window == NULL) {		void *h = purple_notify_searchresults(gc,				_("Gadu-Gadu Public Directory"),				_("Search results"), NULL, results,				(PurpleNotifyCloseCallback)ggp_sr_close_cb,				form);		if (h == NULL) {			purple_debug_error("gg", "ggp_pubdir_reply_handler: "					 "Unable to display the search results.\n");			purple_notify_error(gc, NULL,					  _("Unable to display the search results."),					  NULL);			return;		}		form->window = h;	} else {		purple_notify_searchresults_new_rows(gc, results, form->window);	}}/* }}} *//* *//* static void ggp_pubdir_reply_handler(PurpleConnection *gc, gg_pubdir50_t req) {{{ */static void ggp_pubdir_reply_handler(PurpleConnection *gc, gg_pubdir50_t req){	GGPInfo *info = gc->proto_data;	GGPSearchForm *form;	int res_count;	guint32 seq;	seq = gg_pubdir50_seq(req);	form = ggp_search_get(info->searches, seq);	/*	 * this can happen when user will request more results	 * and close the results window before they arrive.	 */	g_return_if_fail(form != NULL);	res_count = gg_pubdir50_count(req);	if (res_count < 1) {		purple_debug_info("gg", "GG_EVENT_PUBDIR50_SEARCH_REPLY: Nothing found\n");		purple_notify_error(gc, NULL,			_("No matching users found"),			_("There are no users matching your search criteria."));		ggp_sr_close_cb(form);		return;	}	switch (form->search_type) {		case GGP_SEARCH_TYPE_INFO:			ggp_pubdir_handle_info(gc, req, form);			break;		case GGP_SEARCH_TYPE_FULL:			ggp_pubdir_handle_full(gc, req, form);			break;		default:			purple_debug_warning("gg", "Unknown search_type!\n");			break;	}}/* }}} *//** * Dispatch a message received from a buddy. * * @param gc PurpleConnection. * @param ev Gadu-Gadu event structure. *//* static void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event *ev) {{{ */static void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event *ev){	GGPInfo *info = gc->proto_data;	PurpleConversation *conv;	gchar *from;	gchar *msg;	gchar *tmp;	from = g_strdup_printf("%lu", (unsigned long int)ev->event.msg.sender);	tmp = charset_convert((const char *)ev->event.msg.message,			      "CP1250", "UTF-8");	purple_str_strip_char(tmp, '\r');	msg = g_markup_escape_text(tmp, -1);	g_free(tmp);	purple_debug_info("gg", "msg form (%s): %s (class = %d; rcpt_count = %d)\n",			from, msg, ev->event.msg.msgclass,			ev->event.msg.recipients_count);	if (ev->event.msg.recipients_count == 0) {		serv_got_im(gc, from, msg, 0, ev->event.msg.time);	} else {		const char *chat_name;		int chat_id;		char *buddy_name;		chat_name = ggp_confer_find_by_participants(gc,				ev->event.msg.recipients,				ev->event.msg.recipients_count);		if (chat_name == NULL) {			chat_name = ggp_confer_add_new(gc, NULL);			serv_got_joined_chat(gc, info->chats_count, chat_name);			ggp_confer_participants_add_uin(gc, chat_name,							ev->event.msg.sender);			ggp_confer_participants_add(gc, chat_name,						    ev->event.msg.recipients,						    ev->event.msg.recipients_count);		}		conv = ggp_confer_find_by_name(gc, chat_name);		chat_id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv));		buddy_name = ggp_buddy_get_name(gc, ev->event.msg.sender);		serv_got_chat_in(gc, chat_id, buddy_name,				 PURPLE_MESSAGE_RECV, msg, ev->event.msg.time);		g_free(buddy_name);	}	g_free(msg);	g_free(from);}/* }}} *//* *//* static void ggp_callback_recv(gpointer _gc, gint fd, PurpleInputCondition cond) {{{ */static void ggp_callback_recv(gpointer _gc, gint fd, PurpleInputCondition cond){	PurpleConnection *gc = _gc;	GGPInfo *info = gc->proto_data;	struct gg_event *ev;	int i;	if (!(ev = gg_watch_fd(info->session))) {		purple_debug_error("gg",			"ggp_callback_recv: gg_watch_fd failed -- CRITICAL!\n");		purple_connection_error(gc, _("Unable to read socket"));		return;	}	switch (ev->type) {		case GG_EVENT_NONE:			/* Nothing happened. */			break;		case GG_EVENT_MSG:			ggp_recv_message_handler(gc, ev);			break;		case GG_EVENT_ACK:			purple_debug_info("gg",				"message sent to: %ld, delivery status=%d, seq=%d\n",				ev->event.ack.recipient, ev->event.ack.status,				ev->event.ack.seq);			break;		case GG_EVENT_NOTIFY:		case GG_EVENT_NOTIFY_DESCR:			{				struct gg_notify_reply *n;				char *descr;				purple_debug_info("gg", "notify_pre: (%d) status: %d\n",						ev->event.notify->uin,						ev->event.notify->status);

⌨️ 快捷键说明

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