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

📄 message.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * purple - Jabber Protocol Plugin * * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * */#include "internal.h"#include "debug.h"#include "notify.h"#include "server.h"#include "util.h"#include "buddy.h"#include "chat.h"#include "google.h"#include "message.h"#include "xmlnode.h"void jabber_message_free(JabberMessage *jm){	g_free(jm->from);	g_free(jm->to);	g_free(jm->id);	g_free(jm->subject);	g_free(jm->body);	g_free(jm->xhtml);	g_free(jm->password);	g_list_free(jm->etc);	g_free(jm);}static void handle_chat(JabberMessage *jm){	JabberID *jid = jabber_id_new(jm->from);	char *from;	JabberBuddy *jb;	JabberBuddyResource *jbr;	if(!jid)		return;	jb = jabber_buddy_find(jm->js, jm->from, TRUE);	jbr = jabber_buddy_find_resource(jb, jid->resource);	if(jabber_find_unnormalized_conv(jm->from, jm->js->gc->account)) {		from = g_strdup(jm->from);	} else  if(jid->node) {		if(jid->resource) {			PurpleConversation *conv;			from = g_strdup_printf("%s@%s", jid->node, jid->domain);			conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, from, jm->js->gc->account);			if(conv) {				purple_conversation_set_name(conv, jm->from);				}			g_free(from);		}		from = g_strdup(jm->from);	} else {		from = g_strdup(jid->domain);	}	if(!jm->xhtml && !jm->body) {		if(JM_STATE_COMPOSING == jm->chat_state) {			serv_got_typing(jm->js->gc, from, 0, PURPLE_TYPING);		} else if(JM_STATE_PAUSED == jm->chat_state) {			serv_got_typing(jm->js->gc, from, 0, PURPLE_TYPED);		} else if(JM_STATE_GONE == jm->chat_state) {			PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,					from, jm->js->gc->account);			if (conv && jid->node && jid->domain) {				char buf[256];				PurpleBuddy *buddy;				g_snprintf(buf, sizeof(buf), "%s@%s", jid->node, jid->domain);				if ((buddy = purple_find_buddy(jm->js->gc->account, buf))) {					const char *who;					char *escaped;					who = purple_buddy_get_alias(buddy);					escaped = g_markup_escape_text(who, -1);					g_snprintf(buf, sizeof(buf),					           _("%s has left the conversation."), escaped);					/* At some point when we restructure PurpleConversation,					 * this should be able to be implemented by removing the					 * user from the conversation like we do with chats now. */					purple_conversation_write(conv, "", buf,					                        PURPLE_MESSAGE_SYSTEM, time(NULL));				}			}			serv_got_typing_stopped(jm->js->gc, from);					} else {			serv_got_typing_stopped(jm->js->gc, from);		}	} else {		if(jbr) {			if(JM_TS_JEP_0085 == (jm->typing_style & JM_TS_JEP_0085)) {				jbr->chat_states = JABBER_CHAT_STATES_SUPPORTED;			} else {				jbr->chat_states = JABBER_CHAT_STATES_UNSUPPORTED;			}			if(JM_TS_JEP_0022 == (jm->typing_style & JM_TS_JEP_0022)) {				jbr->capabilities |= JABBER_CAP_COMPOSING;			}			if(jbr->thread_id)				g_free(jbr->thread_id);			jbr->thread_id = g_strdup(jbr->thread_id);		}				if (jm->js->googletalk && jm->xhtml == NULL) {			char *tmp = jm->body;			jm->body = jabber_google_format_to_html(jm->body);			g_free(tmp);		}		serv_got_im(jm->js->gc, from, jm->xhtml ? jm->xhtml : jm->body, 0,				jm->sent);	}	g_free(from);	jabber_id_free(jid);}static void handle_headline(JabberMessage *jm){	char *title;	GString *body = g_string_new("");	GList *etc;	title = g_strdup_printf(_("Message from %s"), jm->from);	if(jm->xhtml)		g_string_append(body, jm->xhtml);	else if(jm->body)		g_string_append(body, jm->body);	for(etc = jm->etc; etc; etc = etc->next) {		xmlnode *x = etc->data;		const char *xmlns = xmlnode_get_namespace(x);		if(xmlns && !strcmp(xmlns, "jabber:x:oob")) {			xmlnode *url, *desc;			char *urltxt, *desctxt;			url = xmlnode_get_child(x, "url");			desc = xmlnode_get_child(x, "desc");			if(!url || !desc)				continue;			urltxt = xmlnode_get_data(url);			desctxt = xmlnode_get_data(desc);			/* I'm all about ugly hacks */			if(body->len && jm->body && !strcmp(body->str, jm->body))				g_string_printf(body, "<a href='%s'>%s</a>",						urltxt, desctxt);			else				g_string_append_printf(body, "<br/><a href='%s'>%s</a>",						urltxt, desctxt);			g_free(urltxt);			g_free(desctxt);		}	}	purple_notify_formatted(jm->js->gc, title, jm->subject ? jm->subject : title,			NULL, body->str, NULL, NULL);	g_free(title);	g_string_free(body, TRUE);}static void handle_groupchat(JabberMessage *jm){	JabberID *jid = jabber_id_new(jm->from);	JabberChat *chat;	if(!jid)		return;	chat = jabber_chat_find(jm->js, jid->node, jid->domain);	if(!chat)		return;	if(jm->subject) {		purple_conv_chat_set_topic(PURPLE_CONV_CHAT(chat->conv), jid->resource,				jm->subject);		if(!jm->xhtml && !jm->body) {			char *msg, *tmp, *tmp2;			tmp = g_markup_escape_text(jm->subject, -1);			tmp2 = purple_markup_linkify(tmp);			if(jid->resource)				msg = g_strdup_printf(_("%s has set the topic to: %s"), jid->resource, tmp2);			else				msg = g_strdup_printf(_("The topic is: %s"), tmp2);			purple_conv_chat_write(PURPLE_CONV_CHAT(chat->conv), "", msg, PURPLE_MESSAGE_SYSTEM, jm->sent);			g_free(tmp);			g_free(tmp2);			g_free(msg);		}	}	if(jm->xhtml || jm->body) {		if(jid->resource)			serv_got_chat_in(jm->js->gc, chat->id, jid->resource,							jm->delayed ? PURPLE_MESSAGE_DELAYED : 0,							jm->xhtml ? jm->xhtml : jm->body, jm->sent);		else if(chat->muc)			purple_conv_chat_write(PURPLE_CONV_CHAT(chat->conv), "",							jm->xhtml ? jm->xhtml : jm->body,							PURPLE_MESSAGE_SYSTEM, jm->sent);	}	jabber_id_free(jid);}static void handle_groupchat_invite(JabberMessage *jm){	GHashTable *components;	JabberID *jid = jabber_id_new(jm->to);	if(!jid)		return;	components = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);	g_hash_table_replace(components, "room", g_strdup(jid->node));	g_hash_table_replace(components, "server", g_strdup(jid->domain));	g_hash_table_replace(components, "handle", g_strdup(jm->js->user->node));	g_hash_table_replace(components, "password", g_strdup(jm->password));	jabber_id_free(jid);	serv_got_chat_invite(jm->js->gc, jm->to, jm->from, jm->body, components);}static void handle_error(JabberMessage *jm){	char *buf;	if(!jm->body)		return;	buf = g_strdup_printf(_("Message delivery to %s failed: %s"),			jm->from, jm->error ? jm->error : "");	purple_notify_formatted(jm->js->gc, _("XMPP Message Error"), _("XMPP Message Error"), buf,			jm->xhtml ? jm->xhtml : jm->body, NULL, NULL);	g_free(buf);}void jabber_message_parse(JabberStream *js, xmlnode *packet){	JabberMessage *jm;	const char *type;	xmlnode *child;	jm = g_new0(JabberMessage, 1);	jm->js = js;	jm->sent = time(NULL);	jm->delayed = FALSE;	type = xmlnode_get_attrib(packet, "type");	if(type) {		if(!strcmp(type, "normal"))			jm->type = JABBER_MESSAGE_NORMAL;	else if(!strcmp(type, "chat"))			jm->type = JABBER_MESSAGE_CHAT;		else if(!strcmp(type, "groupchat"))			jm->type = JABBER_MESSAGE_GROUPCHAT;		else if(!strcmp(type, "headline"))			jm->type = JABBER_MESSAGE_HEADLINE;		else if(!strcmp(type, "error"))			jm->type = JABBER_MESSAGE_ERROR;		else			jm->type = JABBER_MESSAGE_OTHER;	} else {		jm->type = JABBER_MESSAGE_NORMAL;	}	jm->from = g_strdup(xmlnode_get_attrib(packet, "from"));	jm->to = g_strdup(xmlnode_get_attrib(packet, "to"));	jm->id = g_strdup(xmlnode_get_attrib(packet, "id"));	for(child = packet->child; child; child = child->next) {		if(child->type != XMLNODE_TYPE_TAG)			continue;		if(!strcmp(child->name, "subject")) {			if(!jm->subject)				jm->subject = xmlnode_get_data(child);		} else if(!strcmp(child->name, "thread")) {			if(!jm->thread_id)				jm->thread_id = xmlnode_get_data(child);		} else if(!strcmp(child->name, "body")) {			if(!jm->body) {				char *msg = xmlnode_to_str(child, NULL);				jm->body = purple_strdup_withhtml(msg);				g_free(msg);			}		} else if(!strcmp(child->name, "html")) {			if(!jm->xhtml && xmlnode_get_child(child, "body")) {				char *c;				jm->xhtml = xmlnode_to_str(child, NULL);			        /* Convert all newlines to whitespace. Technically, even regular, non-XML HTML is supposed to ignore newlines, but Pidgin has, as convention			 	 * treated \n as a newline for compatibility with other protocols				 */				for (c = jm->xhtml; *c != '\0'; c++) {					if (*c == '\n') 						*c = ' ';				}			}		} else if(!strcmp(child->name, "active")) {			jm->chat_state = JM_STATE_ACTIVE;			jm->typing_style |= JM_TS_JEP_0085;		} else if(!strcmp(child->name, "composing")) {			jm->chat_state = JM_STATE_COMPOSING;			jm->typing_style |= JM_TS_JEP_0085;		} else if(!strcmp(child->name, "paused")) {

⌨️ 快捷键说明

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