Ejemplo n.º 1
0
void hon_parse_channel_kick(PurpleConnection *gc,gchar* buffer){
    hon_account* hon = gc->proto_data;
    guint32 chatid,kickerid,kickedid;
    gchar* kicked,*kicker,*msg;
    PurpleConversation* chat;
    chatid = read_guint32(buffer);
    kickerid = read_guint32(buffer);
    kickedid = read_guint32(buffer);
    chat = purple_find_chat(gc,chatid);
    if (!chat)
        return;

    if (kickerid == hon->self.account_id)
        kicker = hon->self.nickname;
    else if((kicker = g_hash_table_lookup(hon->id2nick,GINT_TO_POINTER(kickerid))))
    {}
    else
        kicker = _("Someone");

    if (kickedid == hon->self.account_id)
        kicked = hon->self.nickname;
    else if((kicked = g_hash_table_lookup(hon->id2nick,GINT_TO_POINTER(kickedid))))
    {}
    else
        kicked = _("Someone");

    msg = g_strdup_printf(_("%s was kicked from the channel by %s"),kicked,kicker);
    purple_conv_chat_write(PURPLE_CONV_CHAT(chat), "", msg, PURPLE_MESSAGE_SYSTEM, time(NULL));

    if (kickedid == hon->self.account_id)
        serv_got_chat_left(gc, chatid);

    g_free(msg);
}
Ejemplo n.º 2
0
void irc_msg_kick(struct irc_conn *irc, const char *name, const char *from, char **args)
{
	PurpleConnection *gc = purple_account_get_connection(irc->account);
	PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[0], irc->account);
	char *nick = irc_mask_nick(from), *buf;

	if (!gc) {
		g_free(nick);
		return;
	}

	if (!convo) {
		purple_debug(PURPLE_DEBUG_ERROR, "irc", "Recieved a KICK for unknown channel %s\n", args[0]);
		g_free(nick);
		return;
	}

	if (!purple_utf8_strcasecmp(purple_connection_get_display_name(gc), args[1])) {
		buf = g_strdup_printf(_("You have been kicked by %s: (%s)"), nick, args[2]);
		purple_conv_chat_write(PURPLE_CONV_CHAT(convo), args[0], buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
		g_free(buf);
		serv_got_chat_left(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)));
	} else {
		buf = g_strdup_printf(_("Kicked by %s (%s)"), nick, args[2]);
		purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), args[1], buf);
		g_free(buf);
	}

	g_free(nick);
	return;
}
Ejemplo n.º 3
0
static void
out_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
{
	PurpleConnection *gc;
	MsnSwitchBoard *swboard;

	gc = cmdproc->session->account->gc;
	swboard = cmdproc->data;

	if (swboard->current_users > 1)
		serv_got_chat_left(gc, swboard->chat_id);

	msn_switchboard_disconnect(swboard);
}
Ejemplo n.º 4
0
static void irc_chat_leave (PurpleConnection *gc, int id)
{
	struct irc_conn *irc = gc->proto_data;
	PurpleConversation *convo = purple_find_chat(gc, id);
	const char *args[2];

	if (!convo)
		return;

	args[0] = purple_conversation_get_name(convo);
	args[1] = NULL;
	irc_cmd_part(irc, "part", purple_conversation_get_name(convo), args);
	serv_got_chat_left(gc, id);
}
Ejemplo n.º 5
0
static void yahoo_chat_leave(PurpleConnection *gc, const char *room, const char *dn, gboolean logout)
{
	YahooData *yd = gc->proto_data;
	struct yahoo_packet *pkt;

	char *eroom;
	gboolean utf8 = 1;

	if (yd->wm) {
		g_return_if_fail(yd->ycht != NULL);

		ycht_chat_leave(yd->ycht, room, logout);
		return;
	}

	eroom = yahoo_string_encode(gc, room, &utf8);

	pkt = yahoo_packet_new(YAHOO_SERVICE_CHATEXIT, YAHOO_STATUS_AVAILABLE, yd->session_id);
	yahoo_packet_hash(pkt, "sss", 104, eroom, 109, dn, 108, "1");
	yahoo_packet_hash_str(pkt, 112, "0"); /* what does this one mean? */
	yahoo_packet_send_and_free(pkt, yd);

	yd->in_chat = 0;
	if (yd->chat_name) {
		g_free(yd->chat_name);
		yd->chat_name = NULL;
	}

	if (purple_find_chat(gc, YAHOO_CHAT_ID) != NULL)
		serv_got_chat_left(gc, YAHOO_CHAT_ID);

	if (!logout)
		return;

	pkt = yahoo_packet_new(YAHOO_SERVICE_CHATLOGOUT,
			YAHOO_STATUS_AVAILABLE, yd->session_id);
	yahoo_packet_hash_str(pkt, 1, dn);
	yahoo_packet_send_and_free(pkt, yd);

	yd->chat_online = FALSE;
	g_free(yd->pending_chat_room);
	yd->pending_chat_room = NULL;
	g_free(yd->pending_chat_id);
	yd->pending_chat_id = NULL;
	g_free(yd->pending_chat_topic);
	yd->pending_chat_topic = NULL;
	g_free(yd->pending_chat_goto);
	yd->pending_chat_goto = NULL;
	g_free(eroom);
}
Ejemplo n.º 6
0
static void gaym_chat_leave(GaimConnection * gc, int id)
{
    struct gaym_conn *gaym = gc->proto_data;
    GaimConversation *convo = gaim_find_chat(gc, id);
    const char *args[2];

    if (!convo)
        return;

    args[0] = gaim_conversation_get_name(convo);
    args[1] = NULL;
    gaym_cmd_part(gaym, "part", gaim_conversation_get_name(convo), args);
    serv_got_chat_left(gc, id);
}
Ejemplo n.º 7
0
void hon_parse_chat_leave(PurpleConnection *gc,gchar* buffer){
    hon_account* hon = gc->proto_data;
    guint32 account_id;
    guint32 chan_id;
    gchar* nick;
    PurpleConversation* conv;
    account_id = read_guint32(buffer);
    chan_id = read_guint32(buffer);
    nick = g_hash_table_lookup(hon->id2nick,GINT_TO_POINTER(account_id));
    conv = purple_find_chat(gc,chan_id);
    if (conv && nick)
    {
        purple_conv_chat_remove_user(PURPLE_CONV_CHAT(conv),nick,"");
    }
    if (account_id == hon->self.account_id)
        serv_got_chat_left(gc, chan_id);
}
Ejemplo n.º 8
0
void yahoo_c_leave(GaimConnection *gc, int id)
{
	struct yahoo_data *yd = (struct yahoo_data *) gc->proto_data;
	GaimConversation *c;

	if (!yd)
		return;

	c = gaim_find_chat(gc, id);
	if (!c)
		return;

	if (id != YAHOO_CHAT_ID) {
		yahoo_conf_leave(yd, gaim_conversation_get_name(c),
			gaim_connection_get_display_name(gc), gaim_conv_chat_get_users(GAIM_CONV_CHAT(c)));
			yd->confs = g_slist_remove(yd->confs, c);
	} else {
		yahoo_chat_leave(gc, gaim_conversation_get_name(c), gaim_connection_get_display_name(gc), TRUE);
	}

	serv_got_chat_left(gc, id);
}
Ejemplo n.º 9
0
void yahoo_c_leave(PurpleConnection *gc, int id)
{
	YahooData *yd = (YahooData *) gc->proto_data;
	PurpleConversation *c;

	if (!yd)
		return;

	c = purple_find_chat(gc, id);
	if (!c)
		return;

	if (id != YAHOO_CHAT_ID) {
		yahoo_conf_leave(yd, purple_conversation_get_name(c),
			purple_connection_get_display_name(gc), purple_conv_chat_get_users(PURPLE_CONV_CHAT(c)));
			yd->confs = g_slist_remove(yd->confs, c);
	} else {
		yahoo_chat_leave(gc, purple_conversation_get_name(c), purple_connection_get_display_name(gc), TRUE);
	}

	serv_got_chat_left(gc, id);
}
Ejemplo n.º 10
0
/*------------------------------------------------------------------------
 * A user was kicked from the GroupChat.
 *
 *  @param session		The MXit session object
 *  @param multimx		The MultiMX room object
 *  @param nickname		The nickname of the user who was kicked
 */
static void member_kicked(struct MXitSession* session, struct multimx* multimx, const char* nickname)
{
	PurpleConversation *convo;

	purple_debug_info(MXIT_PLUGIN_ID, "member_kicked: '%s'\n", nickname);

	convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, multimx->roomname, session->acc);
	if (convo == NULL) {
		purple_debug_error(MXIT_PLUGIN_ID, "Conversation '%s' not found\n", multimx->roomname);
		return;
	}

	/* who was kicked? - compare to our original nickname */
	if (purple_utf8_strcasecmp(nickname, multimx->nickname) == 0)
	{
		/* you were kicked */
		purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "MXit", _("You have been kicked from this MultiMX."), PURPLE_MESSAGE_SYSTEM, time(NULL));
		purple_conv_chat_clear_users(PURPLE_CONV_CHAT(convo));
		serv_got_chat_left(session->con, multimx->chatid);
	}
	else
		purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), nickname, _("was kicked"));
}
Ejemplo n.º 11
0
void irc_msg_part(struct irc_conn *irc, const char *name, const char *from, char **args)
{
	PurpleConnection *gc = purple_account_get_connection(irc->account);
	PurpleConversation *convo;
	char *nick, *msg, *channel;

	if (!args || !args[0] || !gc)
		return;

	/* Undernet likes to :-quote the channel name, for no good reason
	 * that I can see.  This catches that. */
	channel = (args[0][0] == ':') ? &args[0][1] : args[0];

	convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, channel, irc->account);
	if (!convo) {
		purple_debug(PURPLE_DEBUG_INFO, "irc", "Got a PART on %s, which doesn't exist -- probably closed\n", channel);
		return;
	}

	nick = irc_mask_nick(from);
	if (!purple_utf8_strcasecmp(nick, purple_connection_get_display_name(gc))) {
		char *escaped = g_markup_escape_text(args[1], -1);
		msg = g_strdup_printf(_("You have parted the channel%s%s"),
		                      (args[1] && *args[1]) ? ": " : "",
		                      (escaped && *escaped) ? escaped : "");
		g_free(escaped);
		purple_conv_chat_write(PURPLE_CONV_CHAT(convo), channel, msg, PURPLE_MESSAGE_SYSTEM, time(NULL));
		g_free(msg);
		serv_got_chat_left(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)));
	} else {
		msg = args[1] ? irc_mirc2txt(args[1]) : NULL;
		purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), nick, msg);
		g_free(msg);
	}
	g_free(nick);
}
Ejemplo n.º 12
0
static void
nap_callback(gpointer data, gint source, PurpleInputCondition condition) {
    PurpleConnection *gc = data;
    struct nap_data *ndata = gc->proto_data;
    PurpleAccount *account = NULL;
    PurpleConversation *c = NULL;
    PurpleNotifyUserInfo *pnui = NULL;
    gchar *buf = NULL, *buf2 = NULL, *buf3 = NULL, **res = NULL;
    unsigned short header[2] = { 0 , 0 };
    int len = 0;
    int command = 0;
    int i;

    account = purple_connection_get_account(gc);

    if (read(source, (void*)header, 4) != 4) {
        purple_connection_error(gc, _("Unable to read header from server"));
        return;
    }

    len = header[0];
    command = header[1];
    buf = (gchar *)g_malloc((len + 1) * sizeof(gchar));
    buf[len] = '\0';

    i = 0;
    do {
        int tmp = read(source, buf + i, len - i);
        if (tmp <= 0) {
            g_free(buf);
            buf = g_strdup_printf(_("Unable to read message from server: %s.  Command is %hd, length is %hd."), strerror(errno), len, command);
            purple_connection_error(gc, buf);
            g_free(buf);
            return;
        }
        i += tmp;
    } while (i != len);

    purple_debug(PURPLE_DEBUG_MISC, "napster", "R %3hd: %s\n", command, buf);

    switch (command) {
    case 000: /* MSG_SERVER_ERROR */
        purple_notify_error(gc, NULL, buf, NULL);
        purple_input_remove(gc->inpa);
        gc->inpa = 0;
        close(source);
        purple_connection_error(gc, _("Unknown server error."));
        break;

    case 003: /* MSG_SERVER_EMAIL */
        purple_debug(PURPLE_DEBUG_MISC, "napster", "Registered with e-mail address: %s\n", buf);
        ndata->email = g_strdup(buf);

        /* Our signon is complete */
        purple_connection_set_state(gc, PURPLE_CONNECTED);

        /* Send the server our buddy list */
        nap_send_buddylist(gc);

        break;

    case 201: /* MSG_SERVER_SEARCH_RESULT */
        res = g_strsplit(buf, " ", 0);
        purple_prpl_got_user_status(account, res[0], "available", NULL);
        g_strfreev(res);
        break;

    case 202: /* MSG_SERVER_SEARCH_END */
        purple_prpl_got_user_status(account, buf, "offline", NULL);
        break;

    case 205: /* MSG_CLIENT_PRIVMSG */
        res = g_strsplit(buf, " ", 2);
        buf2 = g_markup_escape_text(res[1], -1);
        serv_got_im(gc, res[0], buf2, 0, time(NULL));
        g_free(buf2);
        g_strfreev(res);
        break;

    case 209: /* MSG_SERVER_USER_SIGNON */
        /* USERNAME SPEED */
        res = g_strsplit(buf, " ", 2);
        purple_prpl_got_user_status(account, res[0], "available", NULL);
        g_strfreev(res);
        break;

    case 210: /* MSG_SERVER_USER_SIGNOFF */
        /* USERNAME SPEED */
        res = g_strsplit(buf, " ", 2);
        purple_prpl_got_user_status(account, res[0], "offline", NULL);
        g_strfreev(res);
        break;

    case 214: /* MSG_SERVER_STATS */
        res = g_strsplit(buf, " ", 3);
        buf2 = g_strdup_printf(_("users: %s, files: %s, size: %sGB"), res[0], res[1], res[2]);
        serv_got_im(gc, "server", buf2, 0, time(NULL));
        g_free(buf2);
        g_strfreev(res);
        break;

    case 301: /* MSG_SERVER_HOTLIST_ACK */
        /* Our buddy was added successfully */
        break;

    case 302: /* MSG_SERVER_HOTLIST_ERROR */
        buf2 = g_strdup_printf(_("Unable to add \"%s\" to your Napster hotlist"), buf);
        purple_notify_error(gc, NULL, buf2, NULL);
        g_free(buf2);
        break;

    case 316: /* MSG_SERVER_DISCONNECTING */
        /* we have been kicked off =^( */
        purple_connection_error(gc, _("You were disconnected from the server."));
        break;

    case 401: /* MSG_CLIENT_PART */
        c = nap_find_chat(gc, buf);
        if (c)
            serv_got_chat_left(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(c)));
        break;

    case 403: /* MSG_SERVER_PUBLIC */
        res = g_strsplit(buf, " ", 3);
        c = nap_find_chat(gc, res[0]);
        if (c)
            serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(c)), res[1], 0, res[2], time((time_t)NULL));
        g_strfreev(res);
        break;

    case 404: /* MSG_SERVER_NOSUCH */
        /* abused by opennap servers to broadcast stuff */
        buf2 = g_markup_escape_text(buf, -1);
        serv_got_im(gc, "server", buf2, 0, time(NULL));
        g_free(buf2);
        break;

    case 405: /* MSG_SERVER_JOIN_ACK */
        c = nap_find_chat(gc, buf);
        if (!c)
            serv_got_joined_chat(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(c)), buf);
        break;

    case 407: /* MSG_SERVER_PART */
        res = g_strsplit(buf, " ", 0);
        c = nap_find_chat(gc, res[0]);
        purple_conv_chat_remove_user(PURPLE_CONV_CHAT(c), res[1], NULL);
        g_strfreev(res);
        break;

    case 406: /* MSG_SERVER_JOIN */
    case 408: /* MSG_SERVER_CHANNEL_USER_LIST */
        res = g_strsplit(buf, " ", 4);
        c = nap_find_chat(gc, res[0]);
        purple_conv_chat_add_user(PURPLE_CONV_CHAT(c), res[1], NULL, PURPLE_CBFLAGS_NONE, TRUE);
        g_strfreev(res);
        break;

    case 409: /* MSG_SERVER_CHANNEL_USER_LIST_END */
        break;

    case 410: /* MSG_SERVER_TOPIC */
        /* display the topic in the channel */
        res = g_strsplit(buf, " ", 2);
        c = nap_find_chat(gc, res[0]);
        purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), res[0], res[1]);
        g_strfreev(res);
        break;

    case 603: /* MSG_CLIENT_WHOIS */
        buf2 = g_strdup_printf(_("%s requested your information"), buf);
        serv_got_im(gc, "server", buf2, 0, time(NULL));
        g_free(buf2);
        break;

    case 604: /* MSG_SERVER_WHOIS_RESPONSE */
        /* XXX - Format is:   "Elite" 37 " " "Active" 0 0 0 0 "purple 0.63cvs" 0 0 192.168.1.41 32798 0 unknown flounder */
        res = g_strsplit(buf, " ", 2);
        /* res[0] == username */
        pnui = purple_notify_user_info_new();
        purple_notify_user_info_add_pair(pnui, _("Napster User Info:"), res[1]);
        purple_notify_userinfo(gc, res[0], pnui, NULL, NULL);
        g_strfreev(res);
        break;

    case 621:
    case 622: /* MSG_CLIENT_MOTD */
        /* also replaces MSG_SERVER_MOTD, so we should display it */
        buf2 = g_markup_escape_text(buf, -1);
        serv_got_im(gc, "motd", buf2, 0, time(NULL));
        g_free(buf2);
        break;

    case 627: /* MSG_CLIENT_WALLOP */
        /* abused by opennap server maintainers to broadcast stuff */
        buf2 = g_markup_escape_text(buf, -1);
        serv_got_im(gc, "wallop", buf2, 0, time(NULL));
        g_free(buf2);
        break;

    case 628: /* MSG_CLIENT_ANNOUNCE */
        buf2 = g_markup_escape_text(buf, -1);
        serv_got_im(gc, "announce", buf2, 0, time(NULL));
        g_free(buf);
        break;

    case 748: /* MSG_SERVER_GHOST */
        /* Looks like someone logged in as us! =-O */
        purple_connection_error(gc, _("You have signed on from another location."));
        break;

    case 751: /* MSG_CLIENT_PING */
        buf2 = g_strdup_printf(_("%s requested a PING"), buf);
        serv_got_im(gc, "server", buf2, 0, time(NULL));
        g_free(buf2);
        /* send back a pong */
        /* MSG_CLIENT_PONG */
        nap_write_packet(gc, 752, "%s", buf);
        break;

    case 752: /* MSG_CLIENT_PONG */
        buf2 = g_strdup_printf("Received pong from %s", buf);
        purple_notify_info(gc, NULL, buf2, NULL);
        g_free(buf2);
        break;

    case 824: /* MSG_CLIENT_EMOTE */
        res = g_strsplit(buf, " ", 3);
        buf2 = g_strndup(res[2]+1, strlen(res[2]) - 2); /* chomp off the surround quotes */
        buf3 = g_strdup_printf("/me %s", buf2);
        g_free(buf2);
        if ((c = nap_find_chat(gc, res[0]))) {
            purple_conv_chat_write(PURPLE_CONV_CHAT(c), res[1], buf3, PURPLE_MESSAGE_NICK, time(NULL));
        }
        g_free(buf3);
        g_strfreev(res);
        break;

    default:
        purple_debug(PURPLE_DEBUG_MISC, "napster", "Unknown packet %hd: %s\n", command, buf);
        break;
    }

    g_free(buf);
}
Ejemplo n.º 13
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.º 14
0
void p2tgl_got_chat_left (struct tgl_state *TLS, tgl_peer_id_t chat) {
  serv_got_chat_left(tg_get_conn(TLS), tgl_get_peer_id(chat));
}