Ejemplo n.º 1
0
void irc_msg_nick(struct irc_conn *irc, const char *name, const char *from, char **args)
{
	PurpleConnection *gc = purple_account_get_connection(irc->account);
	PurpleConversation *conv;
	GSList *chats;
	char *nick = irc_mask_nick(from);

	irc->nickused = FALSE;

	if (!gc) {
		g_free(nick);
		return;
	}
	chats = gc->buddy_chats;

	if (!purple_utf8_strcasecmp(nick, purple_connection_get_display_name(gc))) {
		purple_connection_set_display_name(gc, args[0]);
	}

	while (chats) {
		PurpleConvChat *chat = PURPLE_CONV_CHAT(chats->data);
		/* This is ugly ... */
		if (purple_conv_chat_find_user(chat, nick))
			purple_conv_chat_rename_user(chat, nick, args[0]);
		chats = chats->next;
	}

	conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, nick,
						   irc->account);
	if (conv != NULL)
		purple_conversation_set_name(conv, args[0]);

	g_free(nick);
}
Ejemplo n.º 2
0
/* refresh online member in group conversation window */
void qq_group_conv_refresh_online_member(PurpleConnection *gc, qq_group *group)
{
	GList *names, *list, *flags;
	qq_buddy *member;
	gchar *member_name, *member_uid;
	PurpleConversation *conv;
	gint flag;
	g_return_if_fail(group != NULL);

	names = NULL;
	flags = NULL;
	conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
			group->group_name_utf8, purple_connection_get_account(gc));
	if (conv != NULL && group->members != NULL) {
		list = group->members;
		while (list != NULL) {
			member = (qq_buddy *) list->data;

			/* we need unique identifiers for everyone in the chat or else we'll
			 * run into problems with functions like get_cb_real_name from qq.c */
			member_name =   (member->nickname != NULL && *(member->nickname) != '\0') ?
					g_strdup_printf("%s (qq-%u)", member->nickname, member->uid) :
					g_strdup_printf("(qq-%u)", member->uid);
			member_uid = g_strdup_printf("(qq-%u)", member->uid);

			flag = 0;
			/* TYPING to put online above OP and FOUNDER */
			if (is_online(member->status))
				flag |= (PURPLE_CBFLAGS_TYPING | PURPLE_CBFLAGS_VOICE);
			if(1 == (member->role & 1)) flag |= PURPLE_CBFLAGS_OP;
			if(member->uid == group->creator_uid) flag |= PURPLE_CBFLAGS_FOUNDER;

			if (purple_conv_chat_find_user(PURPLE_CONV_CHAT(conv), member_name))
			{
				purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(conv),
						member_name,
						flag);
			} else if (purple_conv_chat_find_user(PURPLE_CONV_CHAT(conv), member_uid))
			{
				purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(conv),
						member_uid,
						flag);
				purple_conv_chat_rename_user(PURPLE_CONV_CHAT(conv), member_uid, member_name);
			} else {
				/* always put it even offline */
				names = g_list_append(names, member_name);
				flags = g_list_append(flags, GINT_TO_POINTER(flag));
			}
			g_free(member_uid);
			list = list->next;
		}

		purple_conv_chat_add_users(PURPLE_CONV_CHAT(conv), names, NULL, flags, FALSE);
	}
	/* clean up names */
	while (names != NULL) {
		member_name = (gchar *) names->data;
		names = g_list_remove(names, member_name);
		g_free(member_name);
	}
	g_list_free(flags);
}
Ejemplo n.º 3
0
static gboolean
handle_presence_chat(JabberStream *js, JabberPresence *presence, xmlnode *packet)
{
	static int i = 1;
	PurpleConvChatBuddyFlags flags = PURPLE_CBFLAGS_NONE;
	JabberChat *chat = presence->chat;

	if (presence->state == JABBER_BUDDY_STATE_ERROR) {
		char *title, *msg = jabber_parse_error(js, packet, NULL);

		if (!chat->conv) {
			title = g_strdup_printf(_("Error joining chat %s"), presence->from);
			purple_serv_got_join_chat_failed(js->gc, chat->components);
		} else {
			title = g_strdup_printf(_("Error in chat %s"), presence->from);
			if (g_hash_table_size(chat->members) == 0)
				serv_got_chat_left(js->gc, chat->id);
		}
		purple_notify_error(js->gc, title, title, msg);
		g_free(title);
		g_free(msg);

		if (g_hash_table_size(chat->members) == 0)
			/* Only destroy the chat if the error happened while joining */
			jabber_chat_destroy(chat);
		return FALSE;
	}

	if (presence->type == JABBER_PRESENCE_AVAILABLE) {
		const char *jid = NULL;
		const char *affiliation = NULL;
		const char *role = NULL;
		gboolean is_our_resource = FALSE; /* Is the presence about us? */
		JabberBuddyResource *jbr;

		/*
		 * XEP-0045 mandates the presence to include a resource (which is
		 * treated as the chat nick). Some non-compliant servers allow
		 * joining without a nick.
		 */
		if (!presence->jid_from->resource)
			return FALSE;

		if (presence->chat_info.item) {
			jid = xmlnode_get_attrib(presence->chat_info.item, "jid");
			affiliation = xmlnode_get_attrib(presence->chat_info.item, "affiliation");
			role = xmlnode_get_attrib(presence->chat_info.item, "role");
		}

		if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(110)) ||
				g_str_equal(presence->jid_from->resource, chat->handle) ||
				purple_strequal(presence->to, jid))
			is_our_resource = TRUE;

		if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(201))) {
			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 (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(210))) {
			/* server rewrote room-nick */
			g_free(chat->handle);
			chat->handle = g_strdup(presence->jid_from->resource);
		}

		if (purple_strequal(affiliation, "owner"))
			flags |= PURPLE_CBFLAGS_FOUNDER;
		if (role) {
			if (g_str_equal(role, "moderator"))
				flags |= PURPLE_CBFLAGS_OP;
			else if (g_str_equal(role, "participant"))
				flags |= PURPLE_CBFLAGS_VOICE;
		}

		if(!chat->conv) {
			char *room_jid = g_strdup_printf("%s@%s", presence->jid_from->node, presence->jid_from->domain);
			chat->id = i++;
			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);
			g_free(room_jid);
		}

		jbr = jabber_buddy_track_resource(presence->jb, presence->jid_from->resource, presence->priority, presence->state, presence->status);
		jbr->commands_fetched = TRUE;

		jabber_chat_track_handle(chat, presence->jid_from->resource, jid, affiliation, role);

		if(!jabber_chat_find_buddy(chat->conv, presence->jid_from->resource))
			purple_conv_chat_add_user(PURPLE_CONV_CHAT(chat->conv), presence->jid_from->resource,
					jid, flags, chat->joined > 0 && ((!presence->delayed) || (presence->sent > chat->joined)));
		else
			purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(chat->conv), presence->jid_from->resource,
					flags);

		if (is_our_resource && chat->joined == 0)
			chat->joined = time(NULL);

	} else if (presence->type == JABBER_PRESENCE_UNAVAILABLE) {
		gboolean nick_change = FALSE;
		gboolean kick = FALSE;
		gboolean is_our_resource = FALSE; /* Is the presence about us? */

		const char *jid = NULL;

		/* If the chat nick is invalid, we haven't yet joined, or we've
		 * already left (it was probably us leaving after we closed the
		 * chat), we don't care.
		 */
		if (!presence->jid_from->resource || !chat->conv || chat->left) {
			if (chat->left &&
					presence->jid_from->resource && chat->handle && !strcmp(presence->jid_from->resource, chat->handle))
				jabber_chat_destroy(chat);
			return FALSE;
		}

		is_our_resource = g_str_equal(presence->jid_from->resource, chat->handle);

		jabber_buddy_remove_resource(presence->jb, presence->jid_from->resource);

		if (presence->chat_info.item)
			jid = xmlnode_get_attrib(presence->chat_info.item, "jid");

		if (chat->muc) {
			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(110))) {
				is_our_resource = TRUE;
				chat->joined = 0;
			}

			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(301))) {
				/* XXX: We got banned.  YAY! (No GIR, that's bad) */
			}


			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(303))) {
				const char *nick = NULL;
				if (presence->chat_info.item)
					nick = xmlnode_get_attrib(presence->chat_info.item, "nick");

				/* nick change */
				if (!nick) {
					purple_debug_warning("jabber", "Chat presence indicating a nick change, but no new nickname!\n");
				} else {
					nick_change = TRUE;

					if (g_str_equal(presence->jid_from->resource, chat->handle)) {
						/* Changing our own nickname */
						g_free(chat->handle);
						/* TODO: This should be resourceprep'd */
						chat->handle = g_strdup(nick);
					}

					purple_conv_chat_rename_user(PURPLE_CONV_CHAT(chat->conv),
					                             presence->jid_from->resource,
					                             nick);
					jabber_chat_remove_handle(chat,
					                          presence->jid_from->resource);
				}
			}

			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(307))) {
				/* Someone was kicked from the room */
				const char *actor = NULL;
				char *reason = NULL;
				char *tmp;

				kick = TRUE;

				if (presence->chat_info.item) {
					xmlnode *node;

					node = xmlnode_get_child(presence->chat_info.item, "actor");
					if (node)
						actor = xmlnode_get_attrib(node, "jid");
					node = xmlnode_get_child(presence->chat_info.item, "reason");
					if (node)
						reason = xmlnode_get_data(node);
				}

				if (reason == NULL)
					reason = g_strdup(_("No reason"));

				if (is_our_resource) {
					if (actor)
						tmp = g_strdup_printf(_("You have been kicked by %s: (%s)"),
								actor, reason);
					else
						tmp = g_strdup_printf(_("You have been kicked: (%s)"),
								reason);
				} else {
					if (actor)
						tmp = g_strdup_printf(_("Kicked by %s (%s)"),
								actor, reason);
					else
						tmp = g_strdup_printf(_("Kicked (%s)"),
								reason);
				}

				g_free(presence->status);
				presence->status = tmp;

				g_free(reason);
			}

			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(321))) {
				/* XXX: removed due to an affiliation change */
			}

			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(322))) {
				/* XXX: removed because room is now members-only */
			}

			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(332))) {
				/* XXX: removed due to system shutdown */
			}
		}

		/*
		 * Possibly another connected resource of our JID (see XEP-0045
		 * v1.24 section 7.1.10) being disconnected. Should be
		 * distinguished by the item_jid.
		 * Also possibly works around bits of an Openfire bug. See
		 * #8319.
		 */
		if (is_our_resource && jid && !purple_strequal(presence->to, jid)) {
			/* TODO: When the above is a loop, this needs to still act
			 * sanely for all cases (this code is a little fragile). */
			if (!kick && !nick_change)
				/* Presumably, kicks and nick changes also affect us. */
				is_our_resource = FALSE;
		}

		if(!nick_change) {
			if (is_our_resource) {
				if (kick)
					purple_conv_chat_write(PURPLE_CONV_CHAT(chat->conv), presence->jid_from->resource,
							presence->status, PURPLE_MESSAGE_SYSTEM, time(NULL));

				serv_got_chat_left(js->gc, chat->id);
				jabber_chat_destroy(chat);
			} else {
				purple_conv_chat_remove_user(PURPLE_CONV_CHAT(chat->conv), presence->jid_from->resource,
						presence->status);
				jabber_chat_remove_handle(chat, presence->jid_from->resource);
			}
		}
	}

	return TRUE;
}
Ejemplo n.º 4
0
/* refresh online member in group conversation window */
void qq_room_conv_set_onlines(PurpleConnection *gc, qq_room_data *rmd)
{
	GList *names, *list, *flags;
	qq_buddy_data *bd;
	gchar *member_name, *member_uid;
	PurpleConversation *conv;
	gint flag;
	gboolean is_find;

	g_return_if_fail(rmd != NULL);

	conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
			rmd->title_utf8, purple_connection_get_account(gc));
	if (conv == NULL) {
		purple_debug_warning("QQ", "Conversation \"%s\" is not opened\n", rmd->title_utf8);
		return;
	}
	g_return_if_fail(rmd->members != NULL);

	names = NULL;
	flags = NULL;

	list = rmd->members;
	while (list != NULL) {
		bd = (qq_buddy_data *) list->data;

		/* we need unique identifiers for everyone in the chat or else we'll
		 * run into problems with functions like get_cb_real_name from qq.c */
		member_name =   (bd->nickname != NULL && *(bd->nickname) != '\0') ?
				g_strdup_printf("%s (%u)", bd->nickname, bd->uid) :
				g_strdup_printf("(%u)", bd->uid);
		member_uid = g_strdup_printf("(%u)", bd->uid);

		flag = 0;
		/* TYPING to put online above OP and FOUNDER */
		if (is_online(bd->status)) flag |= (PURPLE_CBFLAGS_TYPING | PURPLE_CBFLAGS_VOICE);
		if(1 == (bd->role & 1)) flag |= PURPLE_CBFLAGS_OP;
		if(bd->uid == rmd->creator_uid) flag |= PURPLE_CBFLAGS_FOUNDER;

		is_find = TRUE;
		if (purple_conv_chat_find_user(PURPLE_CONV_CHAT(conv), member_name))
		{
			purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(conv),
					member_name,
					flag);
		} else if (purple_conv_chat_find_user(PURPLE_CONV_CHAT(conv), member_uid))
		{
			purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(conv),
					member_uid,
					flag);
			purple_conv_chat_rename_user(PURPLE_CONV_CHAT(conv), member_uid, member_name);
		} else {
			is_find = FALSE;
		}
		if (!is_find) {
			/* always put it even offline */
			names = g_list_append(names, member_name);
			flags = g_list_append(flags, GINT_TO_POINTER(flag));
		} else {
			g_free(member_name);
		}
		g_free(member_uid);
		list = list->next;
	}

	if (names != NULL && flags != NULL) {
		purple_conv_chat_add_users(PURPLE_CONV_CHAT(conv), names, NULL, flags, FALSE);
	}

	/* clean up names */
	while (names != NULL) {
		member_name = (gchar *) names->data;
		names = g_list_remove(names, member_name);
		g_free(member_name);
	}
	g_list_free(flags);
}