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

📄 presence.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		/* they are unsubscribing from our presence, we don't care */		/* Well, maybe just a little, we might want/need to start		 * acknowledging this (and the others) at some point. */		jabber_id_free(jid);		return;	} else {		if((y = xmlnode_get_child(packet, "show"))) {			char *show = xmlnode_get_data(y);			state = jabber_buddy_show_get_state(show);			g_free(show);		} else {			state = JABBER_BUDDY_STATE_ONLINE;		}	}	for(y = packet->child; y; y = y->next) {		if(y->type != XMLNODE_TYPE_TAG)			continue;		if(!strcmp(y->name, "status")) {			g_free(status);			status = xmlnode_get_data(y);		} else if(!strcmp(y->name, "priority")) {			char *p = xmlnode_get_data(y);			if(p) {				priority = atoi(p);				g_free(p);			}		} else if(!strcmp(y->name, "x")) {			const char *xmlns = xmlnode_get_namespace(y);			if(xmlns && !strcmp(xmlns, "jabber:x:delay")) {				/* XXX: compare the time.  jabber:x:delay can happen on presence packets that aren't really and truly delayed */				delayed = TRUE;			} else if(xmlns && !strcmp(xmlns, "http://jabber.org/protocol/muc#user")) {				xmlnode *z;				muc = TRUE;				if((z = xmlnode_get_child(y, "status"))) {					const char *code = xmlnode_get_attrib(z, "code");					if(code && !strcmp(code, "201")) {						if((chat = jabber_chat_find(js, jid->node, jid->domain))) {							chat->config_dialog_type = PURPLE_REQUEST_ACTION;							chat->config_dialog_handle =								purple_request_action(js->gc,										_("Create New Room"),										_("Create New Room"),										_("You are creating a new room.  Would"											" you like to configure it, or"											" accept the default settings?"),										/* Default Action */ 1,										purple_connection_get_account(js->gc), NULL, chat->conv,										chat, 2,										_("_Configure Room"), G_CALLBACK(jabber_chat_request_room_configure),										_("_Accept Defaults"), G_CALLBACK(jabber_chat_create_instant_room));						}					}				}				if((z = xmlnode_get_child(y, "item"))) {					real_jid = xmlnode_get_attrib(z, "jid");					affiliation = xmlnode_get_attrib(z, "affiliation");					role = xmlnode_get_attrib(z, "role");					if(affiliation != NULL && !strcmp(affiliation, "owner"))						flags |= PURPLE_CBFLAGS_FOUNDER;					if (role != NULL) {						if (!strcmp(role, "moderator"))							flags |= PURPLE_CBFLAGS_OP;						else if (!strcmp(role, "participant"))							flags |= PURPLE_CBFLAGS_VOICE;					}				}			} else if(xmlns && !strcmp(xmlns, "vcard-temp:x:update")) {				xmlnode *photo = xmlnode_get_child(y, "photo");				if(photo) {					g_free(avatar_hash);					avatar_hash = xmlnode_get_data(photo);				}			}		}	}	if(jid->node && (chat = jabber_chat_find(js, jid->node, jid->domain))) {		static int i = 1;		char *room_jid = g_strdup_printf("%s@%s", jid->node, jid->domain);		if(state == JABBER_BUDDY_STATE_ERROR) {			char *title, *msg = jabber_parse_error(js, packet);			if(chat->conv) {				title = g_strdup_printf(_("Error in chat %s"), from);				serv_got_chat_left(js->gc, chat->id);			} else {				title = g_strdup_printf(_("Error joining chat %s"), from);			}			purple_notify_error(js->gc, title, title, msg);			g_free(title);			g_free(msg);			jabber_chat_destroy(chat);			jabber_id_free(jid);			g_free(status);			g_free(room_jid);			g_free(avatar_hash);			return;		}		if(type && !strcmp(type, "unavailable")) {			gboolean nick_change = FALSE;			/* If we haven't joined the chat yet, we don't care that someone			 * left, or it was us leaving after we closed the chat */			if(!chat->conv) {				if(jid->resource && chat->handle && !strcmp(jid->resource, chat->handle))					jabber_chat_destroy(chat);				jabber_id_free(jid);				g_free(status);				g_free(room_jid);				g_free(avatar_hash);				return;			}			jabber_buddy_remove_resource(jb, jid->resource);			if(chat->muc) {				xmlnode *x;				for(x = xmlnode_get_child(packet, "x"); x; x = xmlnode_get_next_twin(x)) {					const char *xmlns, *nick, *code;					xmlnode *stat, *item;					if(!(xmlns = xmlnode_get_namespace(x)) ||							strcmp(xmlns, "http://jabber.org/protocol/muc#user"))						continue;					if(!(stat = xmlnode_get_child(x, "status")))						continue;					if(!(code = xmlnode_get_attrib(stat, "code")))						continue;					if(!strcmp(code, "301")) {						/* XXX: we got banned */					} else if(!strcmp(code, "303")) {						if(!(item = xmlnode_get_child(x, "item")))							continue;						if(!(nick = xmlnode_get_attrib(item, "nick")))							continue;						nick_change = TRUE;						if(!strcmp(jid->resource, chat->handle)) {							g_free(chat->handle);							chat->handle = g_strdup(nick);						}						purple_conv_chat_rename_user(PURPLE_CONV_CHAT(chat->conv), jid->resource, nick);						jabber_chat_remove_handle(chat, jid->resource);						break;					} else if(!strcmp(code, "307")) {						/* XXX: we got kicked */					} else if(!strcmp(code, "321")) {						/* XXX: removed due to an affiliation change */					} else if(!strcmp(code, "322")) {						/* XXX: removed because room is now members-only */					} else if(!strcmp(code, "332")) {						/* XXX: removed due to system shutdown */					}				}			}			if(!nick_change) {				if(!g_utf8_collate(jid->resource, chat->handle)) {					serv_got_chat_left(js->gc, chat->id);					jabber_chat_destroy(chat);				} else {					purple_conv_chat_remove_user(PURPLE_CONV_CHAT(chat->conv), jid->resource,							status);					jabber_chat_remove_handle(chat, jid->resource);				}			}		} else {			if(!chat->conv) {				chat->id = i++;				chat->muc = muc;				chat->conv = serv_got_joined_chat(js->gc, chat->id, room_jid);				purple_conv_chat_set_nick(PURPLE_CONV_CHAT(chat->conv), chat->handle);				jabber_chat_disco_traffic(chat);			}			jabber_buddy_track_resource(jb, jid->resource, priority, state,					status);			jabber_chat_track_handle(chat, jid->resource, real_jid, affiliation, role);			if(!jabber_chat_find_buddy(chat->conv, jid->resource))				purple_conv_chat_add_user(PURPLE_CONV_CHAT(chat->conv), jid->resource,						real_jid, flags, !delayed);			else				purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(chat->conv), jid->resource,						flags);		}		g_free(room_jid);	} else {		buddy_name = g_strdup_printf("%s%s%s", jid->node ? jid->node : "",				jid->node ? "@" : "", jid->domain);		if((b = purple_find_buddy(js->gc->account, buddy_name)) == NULL) {			purple_debug_warning("jabber", "Got presence for unknown buddy %s on account %s (%x)",				buddy_name, purple_account_get_username(js->gc->account), js->gc->account);			jabber_id_free(jid);			g_free(avatar_hash);			g_free(buddy_name);			g_free(status);			return;		}		if(avatar_hash) {			const char *avatar_hash2 = purple_buddy_icons_get_checksum_for_user(b);			if(!avatar_hash2 || strcmp(avatar_hash, avatar_hash2)) {				JabberIq *iq;				xmlnode *vcard;				/* XXX this is a crappy way of trying to prevent				 * someone from spamming us with presence packets				 * and causing us to DoS ourselves...what we really				 * need is a queue system that can throttle itself,				 * but i'm too tired to write that right now */				if(!g_slist_find(js->pending_avatar_requests, jb)) {					js->pending_avatar_requests = g_slist_prepend(js->pending_avatar_requests, jb);					iq = jabber_iq_new(js, JABBER_IQ_GET);					xmlnode_set_attrib(iq->node, "to", buddy_name);					vcard = xmlnode_new_child(iq->node, "vCard");					xmlnode_set_namespace(vcard, "vcard-temp");					jabber_iq_set_callback(iq, jabber_vcard_parse_avatar, NULL);					jabber_iq_send(iq);				}			}		}		if(state == JABBER_BUDDY_STATE_ERROR ||				(type && (!strcmp(type, "unavailable") ||						  !strcmp(type, "unsubscribed")))) {			PurpleConversation *conv;			jabber_buddy_remove_resource(jb, jid->resource);			if((conv = jabber_find_unnormalized_conv(from, js->gc->account)))				purple_conversation_set_name(conv, buddy_name);		} else {			jbr = jabber_buddy_track_resource(jb, jid->resource, priority,					state, status);		}		if((found_jbr = jabber_buddy_find_resource(jb, NULL))) {			if(!jbr || jbr == found_jbr) {				purple_prpl_got_user_status(js->gc->account, buddy_name, jabber_buddy_state_get_status_id(state), "priority", found_jbr->priority, found_jbr->status ? "message" : NULL, found_jbr->status, NULL);			}		} else {			purple_prpl_got_user_status(js->gc->account, buddy_name, "offline", status ? "message" : NULL, status, NULL);		}		g_free(buddy_name);	}	g_free(status);	jabber_id_free(jid);	g_free(avatar_hash);}void jabber_presence_subscription_set(JabberStream *js, const char *who, const char *type){	xmlnode *presence = xmlnode_new("presence");	xmlnode_set_attrib(presence, "to", who);	xmlnode_set_attrib(presence, "type", type);	jabber_send(js, presence);	xmlnode_free(presence);}void purple_status_to_jabber(const PurpleStatus *status, JabberBuddyState *state, char **msg, int *priority){	const char *status_id = NULL;	const char *formatted_msg = NULL;	if(state) *state = JABBER_BUDDY_STATE_UNKNOWN;	if(msg) *msg = NULL;	if(priority) *priority = 0;	if(!status) {		if(state) *state = JABBER_BUDDY_STATE_UNAVAILABLE;	} else {		if(state) {			status_id = purple_status_get_id(status);			*state = jabber_buddy_status_id_get_state(status_id);		}		if(msg) {			formatted_msg = purple_status_get_attr_string(status, "message");			/* if the message is blank, then there really isn't a message */			if(formatted_msg && !*formatted_msg)				formatted_msg = NULL;			if(formatted_msg)				*msg = purple_markup_strip_html(formatted_msg);		}		if(priority)			*priority = purple_status_get_attr_int(status, "priority");	}}

⌨️ 快捷键说明

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