void tgp_chat_users_update (struct tgl_state *TLS, struct tgl_chat *C) { PurpleConversation *pc = purple_find_chat (tg_get_conn (TLS), tgl_get_peer_id (C->id)); if (pc) { purple_conv_chat_clear_users (purple_conversation_get_chat_data (pc)); tgp_chat_add_all_users (TLS, pc, C); } }
void p2tgl_conv_add_user (PurpleConversation *conv, struct tgl_chat_user user, char *message, int flags, int new_arrival) { PurpleConvChat *cdata = purple_conversation_get_chat_data(conv); char *name = g_strdup_printf("%d", user.user_id); purple_conv_chat_add_user(cdata, name, message, flags, new_arrival); g_free(name); }
PurpleConversation *tgp_chat_show (struct tgl_state *TLS, struct tgl_chat *C) { connection_data *conn = TLS->ev_base; PurpleConversation *convo = purple_find_chat (conn->gc, tgl_get_peer_id (C->id)); PurpleConvChat *chat = purple_conversation_get_chat_data (convo); if (! convo || (chat && purple_conv_chat_has_left (chat))) { convo = serv_got_joined_chat (conn->gc, tgl_get_peer_id (C->id), C->print_title); tgp_chat_users_update (conn->TLS, C); } return convo; }
PurpleConversation *tgp_chat_show (struct tgl_state *TLS, struct tgl_chat *C) { PurpleConvChat *chat = NULL; // check if chat is already shown PurpleConversation *conv = purple_find_chat (tls_get_conn (TLS), tgl_get_peer_id (C->id)); if (conv) { chat = purple_conversation_get_chat_data (conv); if (chat && ! purple_conv_chat_has_left (chat)) { return conv; } } // join the chat now conv = serv_got_joined_chat (tls_get_conn (TLS), tgl_get_peer_id (C->id), C->print_title); g_return_val_if_fail(conv, NULL); purple_conv_chat_clear_users (purple_conversation_get_chat_data (conv)); tgp_chat_add_all_users (TLS, conv, C); return conv; }
SpectrumMUCConversation::SpectrumMUCConversation(PurpleConversation *conv, const std::string &jid, const std::string &resource) : AbstractConversation(SPECTRUM_CONV_GROUPCHAT) { m_jid = jid; m_res = "/" + resource; m_conv = conv; m_connected = false; m_lastPresence = NULL; #ifndef TESTS m_conv->ui_data = this; PurpleConvChat *chat = purple_conversation_get_chat_data(m_conv); m_nickname = purple_conv_chat_get_nick(chat); #endif }
static PurpleCmdRet send_whisper(PurpleConversation *conv, const char *cmd, char **args, char **error, void *userdata) { const char *to_username; const char *message; const char *from_username; PurpleConvChat *chat; PurpleConvChatBuddy *chat_buddy; PurpleConnection *to; // parse args to_username = args[0]; message = args[1]; if (!to_username || strlen(to_username) == 0) { *error = g_strdup(_("Whisper is missing recipient.")); return PURPLE_CMD_RET_FAILED; } else if (!message || strlen(message) == 0) { *error = g_strdup(_("Whisper is missing message.")); return PURPLE_CMD_RET_FAILED; } from_username = conv->account->username; purple_debug_info("purplemot", "%s whispers to %s in chat room %s: %s\n", from_username, to_username, conv->name, message); chat = purple_conversation_get_chat_data(conv); chat_buddy = purple_conv_chat_cb_find(chat, to_username); to = get_purplemot_gc(to_username); if (!chat_buddy) { // this will be freed by the caller *error = g_strdup_printf(_("%s is not logged in."), to_username); return PURPLE_CMD_RET_FAILED; } else if (!to) { *error = g_strdup_printf(_("%s is not in this chat room."), to_username); return PURPLE_CMD_RET_FAILED; } else { // write the whisper in the sender's chat window char *message_to = g_strdup_printf("%s (to %s)", message, to_username); purple_conv_chat_write(chat, from_username, message_to, PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_WHISPER, time(NULL)); g_free(message_to); // send the whisper serv_chat_whisper(to, chat->id, from_username, message); return PURPLE_CMD_RET_OK; } }
void QuetzalChat::renameUser(const char *old_name, const char *new_name, const char *new_alias) { QuetzalAccount *account = reinterpret_cast<QuetzalAccount*>(m_conv->account->ui_data); PurpleConvChat *data = purple_conversation_get_chat_data(m_conv); QuetzalChatUser *user = m_users.take(old_name); account->removeChatUnit(user); user->fixId(purple_conv_chat_cb_find(data, new_name)); m_users.insert(new_name, user); user->rename(new_alias); account->addChatUnit(user); // if (!qstrcmp(old_name, data->nick)) // emit meChanged(user); }
static PurpleRoomlist * purplemot_roomlist_get_list(PurpleConnection *gc) { const char *username = gc->account->username; PurpleRoomlist *roomlist = purple_roomlist_new(gc->account); GList *fields = NULL; PurpleRoomlistField *field; GList *chats; GList *seen_ids = NULL; purple_debug_info("purplemot", "%s asks for room list; returning:\n", username); /* set up the room list */ field = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "room", "room", TRUE /* hidden */); fields = g_list_append(fields, field); field = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_INT, "Id", "Id", FALSE); fields = g_list_append(fields, field); purple_roomlist_set_fields(roomlist, fields); /* add each chat room. the chat ids are cached in seen_ids so that each room * is only returned once, even if multiple users are in it. */ for (chats = purple_get_chats(); chats; chats = g_list_next(chats)) { PurpleConversation *conv = (PurpleConversation *)chats->data; PurpleRoomlistRoom *room; const char *name = conv->name; int id = purple_conversation_get_chat_data(conv)->id; /* have we already added this room? */ if (g_list_find_custom(seen_ids, name, (GCompareFunc)strcmp)) continue; /* yes! try the next one. */ /* This cast is OK because this list is only staying around for the life * of this function and none of the conversations are being deleted * in that timespan. */ seen_ids = g_list_prepend(seen_ids, (char *)name); /* no, it's new. */ purple_debug_info("purplemot", "%s (%d), ", name, id); room = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM, name, NULL); purple_roomlist_room_add_field(roomlist, room, name); purple_roomlist_room_add_field(roomlist, room, &id); purple_roomlist_room_add(roomlist, room); } g_list_free(seen_ids); purple_timeout_add(1 /* ms */, purplemot_finish_get_roomlist, roomlist); return roomlist; }
static void waprpl_chat_invite(PurpleConnection * gc, int id, const char *message, const char *name) { whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); PurpleConversation *convo = purple_find_chat(gc, id); PurpleChat *ch = blist_find_chat_by_convo(gc, id); GHashTable *hasht = purple_chat_get_components(ch); char *chat_id = g_hash_table_lookup(hasht, "id"); if (strstr(name, "@s.whatsapp.net") == 0) name = g_strdup_printf("*****@*****.**", name); waAPI_manageparticipant(wconn->waAPI, chat_id, name, "add"); purple_conv_chat_add_user(purple_conversation_get_chat_data(convo), name, "", PURPLE_CBFLAGS_NONE, FALSE); waprpl_check_output(gc); }
PurpleConversation *chat_show (PurpleConnection *gc, int id) { connection_data *conn = purple_connection_get_protocol_data(gc); PurpleConversation *convo = purple_find_chat (gc, id); PurpleConvChat *chat = purple_conversation_get_chat_data (convo); tgl_peer_t *P = tgl_peer_get (conn->TLS, TGL_MK_CHAT(id)); if (! P) { warning ("Chat %d not existing, not showing...", id); return NULL; } if (! convo || (chat && purple_conv_chat_has_left (chat))) { convo = p2tgl_got_joined_chat (conn->TLS, &P->chat); } chat_users_update (conn->TLS, &P->chat); return convo; }
static void purplemot_set_chat_topic(PurpleConnection *gc, int id, const char *topic) { PurpleConversation *conv = purple_find_chat(gc, id); PurpleConvChat *chat = purple_conversation_get_chat_data(conv); const char *last_topic; if (!chat) return; purple_debug_info("purplemot", "%s sets topic of chat room '%s' to '%s'\n", gc->account->username, conv->name, topic); last_topic = purple_conv_chat_get_topic(chat); if ((!topic && !last_topic) || (topic && last_topic && !strcmp(topic, last_topic))) return; /* topic is unchanged, this is a noop */ }
QuetzalChat::QuetzalChat(PurpleConversation *conv) : Conference(reinterpret_cast<Account *>(conv->account->ui_data)) { m_conv = conv; m_conv->ui_data = this; m_id = m_conv->name; m_title = m_conv->title; if (m_id.isEmpty()) { // Hack for msn-like protocols m_id = QLatin1String("QuetzalChat#") + QString::number(quint64(qrand()) << 20 | quint64(qrand()), 16); } PurpleConvChat *chat = purple_conversation_get_chat_data(conv); if (!chat->left) setJoined(true); // if (account()->protocol()->id() == "msn") // m_id = "QuetzalChat#" + QString::number(chat->id); }
static void chat_msg_received_cb(PurpleAccount *account, char *sender, char *message, PurpleConversation *conv, PurpleMessageFlags flags, PurpleSoundEventID event) { PurpleConvChat *chat; if (flags & PURPLE_MESSAGE_DELAYED) return; chat = purple_conversation_get_chat_data(conv); g_return_if_fail(chat != NULL); if (purple_conv_chat_is_user_ignored(chat, sender)) return; if (chat_nick_matches_name(conv, sender)) return; if (flags & PURPLE_MESSAGE_NICK || purple_utf8_has_word(message, chat->nick)) play_conv_event(conv, PURPLE_SOUND_CHAT_NICK); else play_conv_event(conv, event); }
static void purple_chat_msg( struct groupchat *gc, char *message, int flags ) { PurpleConversation *pc = gc->data; purple_conv_chat_send( purple_conversation_get_chat_data( pc ), message ); }
xmlnode * _h_elim_message ( const char *name , const char *id , SEXP_VALUE *args , gpointer data ) { fprintf(stderr, "(elim-debug entered _h_elim_message)"); ASSERT_ALISTP( args, id, name ); elim_ping(); const char *aname = ALIST_VAL_STR( args, "account-name" ); const char *proto = ALIST_VAL_STR( args, "im-protocol" ); gpointer auid = ALIST_VAL_PTR( args, "account-uid" ); PurpleAccount *acct = auid ? find_acct_by_uid( auid ) : purple_accounts_find( aname, proto ); if( !acct ) { sexp_val_free( args ); return response_error( ENXIO, id, name, "unknown account" ); } PurpleConversationType pt = PURPLE_CONV_TYPE_UNKNOWN; gpointer cuid = ALIST_VAL_PTR( args, "conv-uid" ); const char *cname = ALIST_VAL_STR( args, "conv-name" ); PurpleConversation *pc = find_conv_by_acct_uid( acct, cuid ); if ( pc ) pt = purple_conversation_get_type( pc ); else { pt = PURPLE_CONV_TYPE_ANY; pc = purple_find_conversation_with_account( pt, cname, acct ); if( !pc ) { pt = PURPLE_CONV_TYPE_IM; pc = purple_conversation_new( pt, acct, cname ); } else { pt = purple_conversation_get_type( pc ); } } if( !pc ) { sexp_val_free( args ); return response_error( ENXIO, id, name, "new conversation failed" ); } PurpleConvIm *pci = NULL; PurpleConvChat *pcc = NULL; const char *msg = ALIST_VAL_STRING( args, "text" ); char *esc = g_markup_escape_text( msg, -1 ); int len = strlen( esc ); switch( pt ) { case PURPLE_CONV_TYPE_IM: pci = purple_conversation_get_im_data( pc ); purple_conv_im_send( pci, esc ); break; case PURPLE_CONV_TYPE_CHAT: pcc = purple_conversation_get_chat_data( pc ); purple_conv_chat_send( pcc, esc ); break; default: g_free ( esc ); sexp_val_free( args ); return response_error( EINVAL, id, name, "unknown conversation type" ); } xmlnode *rval = xnode_new( "alist" ); AL_INT( rval, "bytes" , len ); AL_PTR( rval, "conv-uid" , pc ); AL_STR( rval, "conv-name", purple_conversation_get_name(pc) ); g_free ( esc ); sexp_val_free( args ); fprintf(stderr, "(elim-debug leaving _h_elim_message)"); return response_value( 0, id, name, rval ); }
static char *format_service_msg (struct tgl_state *TLS, struct tgl_message *M) { g_return_val_if_fail(M && M->flags & TGLMF_SERVICE, NULL); connection_data *conn = TLS->ev_base; char *txt = NULL; tgl_peer_t *fromPeer = tgl_peer_get (TLS, M->from_id); g_return_val_if_fail(fromPeer != NULL, NULL); const char *txt_user = fromPeer->print_name; switch (M->action.type) { case tgl_message_action_chat_create: txt = g_strdup_printf (_("%2$s created chat %1$s."), M->action.title, txt_user); break; case tgl_message_action_chat_edit_title: txt = g_strdup_printf (_("%2$s changed title to %1$s."), M->action.new_title, txt_user); break; case tgl_message_action_chat_edit_photo: txt = g_strdup_printf (_("%s changed photo."), txt_user); break; case tgl_message_action_chat_delete_photo: txt = g_strdup_printf (_("%s deleted photo."), txt_user); break; case tgl_message_action_chat_add_user_by_link: { tgl_peer_t *actionPeer = tgl_peer_get (TLS, TGL_MK_USER (M->action.user)); if (actionPeer) { char *alias = actionPeer->print_name; PurpleConversation *conv = purple_find_chat (conn->gc, tgl_get_peer_id (M->to_id)); txt = g_strdup_printf (_("%1$s added user %2$s by link."), alias, txt_user); if (conv) { p2tgl_conv_add_user (TLS, conv, tgl_get_peer_id (fromPeer->id), NULL, 0, FALSE); } return txt; } break; } case tgl_message_action_chat_add_user: { tgl_peer_t *peer = tgl_peer_get (TLS, TGL_MK_USER (M->action.user)); if (peer) { char *alias = peer->print_name; txt = g_strdup_printf (_("%2$s added user %1$s."), alias, txt_user); PurpleConversation *conv = purple_find_chat (conn->gc, tgl_get_peer_id (M->to_id)); if (conv) { p2tgl_conv_add_user (TLS, conv, M->action.user, NULL, 0, FALSE); } } break; } case tgl_message_action_chat_delete_user: { tgl_peer_t *peer = tgl_peer_get (TLS, TGL_MK_USER (M->action.user)); if (peer) { tgl_peer_t *chatPeer = tgl_peer_get (TLS, M->to_id); g_return_val_if_fail(tgl_get_peer_type (chatPeer->id) == TGL_PEER_CHAT, NULL); // make sure that the chat is showing before deleting the user, otherwise the chat will be // initialised after removing the chat and the chat will still contain the deleted user PurpleConversation *conv = tgp_chat_show (TLS, &chatPeer->chat); if (conv) { char *alias = peer->print_name; const char *aliasLeft = tgp_blist_lookup_purple_name (TLS, TGL_MK_USER (M->action.user)); if (tgl_get_peer_id (M->from_id) != tgl_get_peer_id (peer->id)) { txt = g_strdup_printf (_("%2$s deleted user %1$s."), alias, txt_user); } g_return_val_if_fail (aliasLeft, NULL); purple_conv_chat_remove_user (purple_conversation_get_chat_data (conv), aliasLeft, txt); if (M->action.user == tgl_get_peer_id (TLS->our_id)) { purple_conv_chat_left (purple_conversation_get_chat_data (conv)); } // conv_del_user already printed a message, prevent a redundant message // from being printed by returning NULL g_free (txt); return NULL; } char *alias = peer->print_name; if (tgl_get_peer_id (M->from_id) != tgl_get_peer_id (peer->id)) { txt = g_strdup_printf (_("%2$s deleted user %1$s."), alias, txt_user); } } break; } case tgl_message_action_set_message_ttl: txt = g_strdup_printf (P_("%2$s set self destruction timer to %1$d second.", "%2$s set self destruction timer to %1$d seconds.", M->action.ttl), M->action.ttl, txt_user); break; case tgl_message_action_read_messages: txt = g_strdup_printf (P_("%2$s marked %1$d message read.", "%2$s marked %1$d messages read.", M->action.read_cnt), M->action.read_cnt, txt_user); break; case tgl_message_action_delete_messages: txt = g_strdup_printf (P_("%2$s deleted %1$d message.", "%2$s deleted %1$d messages.", M->action.delete_cnt), M->action.delete_cnt, txt_user); break; case tgl_message_action_screenshot_messages: txt = g_strdup_printf (P_("%2$s made a screenshot of %1$d message.", "%2$s made a screenshot of %1$d messages.", M->action.screenshot_cnt), M->action.screenshot_cnt, txt_user); break; default: g_warn_if_reached(); break; } return txt; }
Buddy *QuetzalChat::me() const { PurpleConvChat *data = purple_conversation_get_chat_data(m_conv); return m_users.value(m_nick.isEmpty() ? QString::fromUtf8(data->nick) : m_nick); }
static void waprpl_process_incoming_events(PurpleConnection *gc) { whatsapp_connection * wconn = purple_connection_get_protocol_data(gc); PurpleAccount * acc = purple_connection_get_account(gc); switch (waAPI_loginstatus(wconn->waAPI)) { case 0: purple_connection_update_progress(gc, "Connecting", 0, 4); break; case 1: purple_connection_update_progress(gc, "Sending auth", 1, 4); break; case 2: purple_connection_update_progress(gc, "Waiting response", 2, 4); break; case 3: purple_connection_update_progress(gc, "Connected", 3, 4); purple_connection_set_state(gc, PURPLE_CONNECTED); if (!wconn->connected) waprpl_insert_contacts(gc); wconn->connected = 1; break; default: break; }; char * msg, * who, * prev, * url, *author; int status; int size; double lat,lng; // Incoming messages while (waAPI_querychat(wconn->waAPI, &who, &msg, &author)) { purple_debug_info(WHATSAPP_ID, "Got chat message from %s: %s\n", who,msg); if (isgroup(who)) { // Search fot the combo PurpleBlistNode* node = purple_blist_get_root(); GHashTable* hasht = NULL; while (node != 0) { if (PURPLE_BLIST_NODE_IS_CHAT(node)) { PurpleChat * ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) == acc) { hasht = purple_chat_get_components(ch); if (strcmp(g_hash_table_lookup(hasht, "id"),who) == 0) { break; } } } node = purple_blist_node_next(node,FALSE); } int convo_id = chatid_to_convo(who); PurpleConversation *convo = purple_find_chat(gc, convo_id); // Create a window if it's not open yet if (!convo) waprpl_chat_join(gc,hasht); if (convo != NULL) { serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)), author, PURPLE_MESSAGE_RECV, msg, time(NULL)); }else{ printf("Received group message but could not find the group! %s\n",msg); } }else{ // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, msg, PURPLE_MESSAGE_RECV, time(NULL)); } } while (waAPI_querychatimage(wconn->waAPI, &who, &prev, &size, &url)) { printf("Got chat image %s %s\n",who,url); purple_debug_info(WHATSAPP_ID, "Got image from %s: %s\n", who,url); // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); int imgid = purple_imgstore_add_with_id(g_memdup(prev, size), size, NULL); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, g_strdup_printf("<a href=\"%s\"><img id=\"%u\"></a>",url,imgid), PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_IMAGES, time(NULL)); } while (waAPI_querychatlocation(wconn->waAPI, &who, &prev, &size, &lat, &lng)) { purple_debug_info(WHATSAPP_ID, "Got geomessage from: %s Coordinates (%f %f)\n", who,(float)lat,(float)lng); // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); int imgid = purple_imgstore_add_with_id(g_memdup(prev, size), size, NULL); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, g_strdup_printf("<a href=\"http://openstreetmap.org/?lat=%f&lon=%f&zoom=16\"><img src=\"%u\"></a>",lat,lng,imgid), PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_IMAGES, time(NULL)); } while (waAPI_querychatsound(wconn->waAPI, &who, &url)) { purple_debug_info(WHATSAPP_ID, "Got chat sound from %s: %s\n", who,url); // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, g_strdup_printf("<a href=\"%s\">%s</a>",url,url), PURPLE_MESSAGE_RECV , time(NULL)); } // User status change while (waAPI_querystatus(wconn->waAPI, &who, &status)) { if (status == 1) { purple_prpl_got_user_status(acc, who, "available", "message","", NULL); } else { purple_prpl_got_user_status(acc, who, "unavailable", "message","", NULL); } } // User typing info notify while (waAPI_querytyping(wconn->waAPI, &who, &status)) { if (status == 1) { serv_got_typing(gc,who,0,PURPLE_TYPING); } else { serv_got_typing_stopped(gc,who); } } // User profile picture char * icon, * hash; int len; while (waAPI_queryicon(wconn->waAPI, &who, &icon, &len, &hash)) { purple_buddy_icons_set_for_user(acc,who, g_memdup(icon,len),len, hash); } // Groups update if (waAPI_getgroupsupdated(wconn->waAPI)) { // Delete/update the chats that are in our list PurpleBlistNode* node = purple_blist_get_root(); while (node != 0) { if (PURPLE_BLIST_NODE_IS_CHAT(node)) { PurpleChat * ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) == acc) { int found = 0; GHashTable *hasht = purple_chat_get_components(ch); char * grid = g_hash_table_lookup(hasht, "id"); char * glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist,",",0); while (*gplist) { if (strcmp(*gplist,grid) == 0) { // The group is in the system, update the fields char *id,*sub,*own; waAPI_getgroupinfo(wconn->waAPI, *gplist, &sub, &own, 0); g_hash_table_insert(hasht, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(hasht, g_strdup("owner"), g_strdup(own)); found = 1; break; } gplist++; } // The group was deleted if (!found) { PurpleBlistNode* del = node; node = purple_blist_node_next(node,FALSE); purple_blist_remove_chat(del); } } } node = purple_blist_node_next(node,FALSE); } // Add new groups char * glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist,",",0); while (*gplist) { int found = 0; PurpleBlistNode* node = purple_blist_get_root(); PurpleChat * ch; while (node != 0) { if (PURPLE_BLIST_NODE_IS_CHAT(node)) { ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) == acc) { char * grid = g_hash_table_lookup(purple_chat_get_components(ch), "id"); if (strcmp(*gplist,grid) == 0) { found = 1; break; } } } node = purple_blist_node_next(node,FALSE); } if (!found) { char *sub,*own; waAPI_getgroupinfo(wconn->waAPI, *gplist, &sub, &own, 0); purple_debug_info("waprpl", "New group found %s %s\n", *gplist,sub); GHashTable * htable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); g_hash_table_insert(htable, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(htable, g_strdup("id"), g_strdup(*gplist)); g_hash_table_insert(htable, g_strdup("owner"), g_strdup(own)); ch = purple_chat_new(acc,sub,htable); purple_blist_add_chat(ch,NULL,NULL); } // Now update the open conversation that may exist char * id = g_hash_table_lookup(purple_chat_get_components(ch), "id"); int prplid = chatid_to_convo(id); PurpleConversation * conv = purple_find_chat(gc, prplid); if (conv) { char *subject, *owner, *part; if (!waAPI_getgroupinfo(wconn->waAPI, id, &subject, &owner, &part)) return; purple_conv_chat_clear_users(purple_conversation_get_chat_data(conv)); gchar **plist = g_strsplit(part,",",0); while (*plist) { purple_conv_chat_add_user (purple_conversation_get_chat_data(conv), *plist,"",PURPLE_CBFLAGS_NONE | (!strcmp(owner,*plist) ? PURPLE_CBFLAGS_FOUNDER : 0),FALSE); plist++; } } gplist++; } } }