diff --git a/loop.c b/loop.c index b51a71d..dae5586 100644 --- a/loop.c +++ b/loop.c @@ -629,25 +629,6 @@ void network_export_registration() fflush (stderr); } -/** - * Fetch all unknown messages of the current session - */ -void session_get_difference() -{ - do_get_difference(); - net_loop (0, dgot); -} - -extern int contacts_got; -int cupdate_got() { - return contacts_got; -} -void session_update_contact_list() -{ - do_update_contact_list(); - net_loop(0, cupdate_got); -} - int start_loop (char* code, char* auth_mode) { logprintf("Calling start_loop()\n"); logprintf("auth_state %i\n", auth_state); diff --git a/purple-plugin/telegram-purple.c b/purple-plugin/telegram-purple.c index 8a7fd98..ea99879 100644 --- a/purple-plugin/telegram-purple.c +++ b/purple-plugin/telegram-purple.c @@ -48,6 +48,7 @@ #include "msglog.h" #include "mtproto-client.h" #include "mtproto-common.h" +#include "structures.h" // telegram-purple includes #include "loop.h" @@ -77,8 +78,7 @@ void tg_cli_log_cb(const char* format, va_list ap) } void on_new_message(struct message *M); -void user_allocated_handler(peer_t *user); -void chat_allocated_handler(peer_t *chat); +void peer_allocated_handler(peer_t *user); /** * Returns the base icon name for the given buddy and account. @@ -227,22 +227,25 @@ static void tgprpl_login(PurpleAccount * acct) purple_blist_add_group(tggroup, NULL); } - purple_debug_info(PLUGIN_ID, "Fetching Network Info\n"); on_update_new_message(on_new_message); - on_user_allocated(user_allocated_handler); - on_chat_allocated(chat_allocated_handler); + on_peer_allocated(peer_allocated_handler); // get all current contacts purple_debug_info(PLUGIN_ID, "Fetching all current contacts...\n"); - session_update_contact_list(); + do_update_contact_list(); + + purple_debug_info(PLUGIN_ID, "Fetching all current chats...\n"); + do_get_dialog_list(); // get new messages - session_get_difference(); + purple_debug_info(PLUGIN_ID, "Fetching new messages...\n"); + do_get_difference(); + flush_queries(); // Our protocol data, that will be delivered to us // through purple connection telegram_conn *conn = g_new0(telegram_conn, 1); - conn->gc = gc; + conn->gc = gc; conn->account = acct; purple_connection_set_protocol_data(gc, conn); @@ -258,30 +261,113 @@ void on_new_message(struct message *M) g_free(who); } -void user_allocated_handler(peer_t *user) -{ - gchar *name = g_strdup_printf("%d", get_peer_id(user->id)); - // TODO: this should probably be freed again somwhere - char *alias = malloc(BUDDYNAME_MAX_LENGTH); - if (user_get_alias(user, alias, BUDDYNAME_MAX_LENGTH) < 0) { - purple_debug_info(PLUGIN_ID, "Buddyalias of (%d) too long, not adding to buddy list.\n", - get_peer_id(user->id)); - return; +/* + * Search chats in hash table + * + * TODO: There has to be an easier way to do this + */ +static PurpleChat *blist_find_chat_by_hasht_cond(PurpleConnection *gc, int (*fn)(GHashTable *hasht, void *data), void *data) +{ + PurpleAccount *account = purple_connection_get_account(gc); + PurpleBlistNode *node = purple_blist_get_root(); + GHashTable *hasht; + while (node) { + if (PURPLE_BLIST_NODE_IS_CHAT(node)) { + PurpleChat *ch = PURPLE_CHAT(node); + if (purple_chat_get_account(ch) == account) { + hasht = purple_chat_get_components(ch); + if (fn(hasht, data)) + return ch; + } + } + node = purple_blist_node_next(node, FALSE); } - PurpleBuddy *buddy = purple_find_buddy(_pa, name); - if (!buddy) { - purple_debug_info(PLUGIN_ID, "Adding %s to buddy list ", name); - buddy = purple_buddy_new(_pa, name, alias); - purple_blist_add_buddy(buddy, NULL, tggroup, NULL); - } - purple_buddy_set_protocol_data(buddy, (gpointer)&user->id); - g_free(name); + return NULL; +} +static int hasht_cmp_id(GHashTable *hasht, void *data) +{ + return !strcmp(g_hash_table_lookup(hasht, "id"), *((char **)data)); +} +static PurpleChat *blist_find_chat_by_id(PurpleConnection *gc, const char *id) +{ + return blist_find_chat_by_hasht_cond(gc, hasht_cmp_id, &id); } -void chat_allocated_handler(peer_t *chat) + +void peer_allocated_handler(peer_t *user) { - purple_debug_info(PLUGIN_ID, "Chat Allocated: %s\n", chat->print_name); + gchar *name = g_strdup_printf("%d", get_peer_id(user->id)); + logprintf("Allocated peer: %s\n", name); + + switch (user->id.type) { + case PEER_USER: { + logprintf("Peer type: user.\n"); + // TODO: this should probably be freed again somwhere + char *alias = malloc(BUDDYNAME_MAX_LENGTH); + if (user_get_alias(user, alias, BUDDYNAME_MAX_LENGTH) < 0) { + purple_debug_info(PLUGIN_ID, "Buddyalias of (%d) too long, not adding to buddy list.\n", + get_peer_id(user->id)); + return; + } + PurpleBuddy *buddy = purple_find_buddy(_pa, name); + if (!buddy) { + purple_debug_info(PLUGIN_ID, "Adding %s to buddy list\n", name); + buddy = purple_buddy_new(_pa, name, alias); + purple_blist_add_buddy(buddy, NULL, tggroup, NULL); + } + purple_buddy_set_protocol_data(buddy, (gpointer)&user->id); + g_free(name); + } + break; + case PEER_CHAT: { + logprintf("Peer type: chat.\n"); + PurpleChat *ch = blist_find_chat_by_id(_gc, name); + if (!ch) { + gchar *admin = g_strdup_printf("%d", user->chat.admin_id); + 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"), user->chat.title); + g_hash_table_insert(htable, g_strdup("id"), name); + g_hash_table_insert(htable, g_strdup("owner"), admin); + logprintf("Adding chat to blist: %s (%s, %s)\n", user->chat.title, name, admin); + ch = purple_chat_new(_pa, user->chat.title, htable); + purple_blist_add_chat(ch, NULL, NULL); + } + + GHashTable *gh = purple_chat_get_components(ch); + //char const *id = g_hash_table_lookup(gh, "id"); + char const *owner = g_hash_table_lookup(gh, "owner"); + + PurpleConversation *conv = purple_find_chat(_gc, atoi(name)); + + purple_conv_chat_clear_users(purple_conversation_get_chat_data(conv)); + if (conv) { + struct chat_user *usr = user->chat.user_list; + int size = user->chat.user_list_size; + int i; + for (i = 0; i < size; i++) { + struct chat_user *cu = (usr + i); + // TODO: Inviter ID + // peer_id_t u = MK_USER (cu->user_id); + // peer_t *uchat = user_chat_get(u); + const char *cuname = g_strdup_printf("%d", cu->user_id); + logprintf("Adding user %s to chat %s\n", cuname, name); + purple_conv_chat_add_user(purple_conversation_get_chat_data(conv), cuname, "", + PURPLE_CBFLAGS_NONE | (!strcmp(owner, cuname) ? PURPLE_CBFLAGS_FOUNDER : 0), FALSE); + } + } + } + break; + case PEER_GEO_CHAT: + logprintf("Peer type: geo-chat.\n"); + break; + case PEER_ENCR_CHAT: + logprintf("Peer type: encrypted chat.\n"); + break; + case PEER_UNKNOWN: + logprintf("Peer type: unknown.\n"); + break; + } } /** diff --git a/queries.c b/queries.c index 7d561e2..0197f8d 100644 --- a/queries.c +++ b/queries.c @@ -2639,11 +2639,13 @@ int get_difference_on_answer (struct query *q UU) { } assert (fetch_int () == CODE_vector); n = fetch_int (); + logprintf("Found %d chats\n", n); for (i = 0; i < n; i++) { fetch_alloc_chat (); } assert (fetch_int () == CODE_vector); n = fetch_int (); + logprintf("Found %d users\n", n); for (i = 0; i < n; i++) { fetch_alloc_user (); } diff --git a/structures.c b/structures.c index 78b75e8..a06290b 100644 --- a/structures.c +++ b/structures.c @@ -1527,6 +1527,7 @@ static int id_cmp (struct message *M1, struct message *M2) { } struct user *fetch_alloc_user (void) { + logprintf("fetch_alloc_user()\n"); int send_event = 0; int data[2]; prefetch_data (data, 8); @@ -1542,12 +1543,13 @@ struct user *fetch_alloc_user (void) { } fetch_user (&U->user); if (send_event) { - event_user_allocated(U); + event_peer_allocated(U); } return &U->user; } struct secret_chat *fetch_alloc_encrypted_chat (void) { + logprintf("fetch_alloc_encrypted_chat()\n"); int data[2]; prefetch_data (data, 8); peer_t *U = user_chat_get (MK_ENCR_CHAT (data[1])); @@ -1560,6 +1562,7 @@ struct secret_chat *fetch_alloc_encrypted_chat (void) { Peers[peer_num ++] = U; } fetch_encrypted_chat (&U->encr_chat); + event_peer_allocated(U); return &U->encr_chat; } @@ -1806,6 +1809,7 @@ void message_del_peer (struct message *M) { } struct message *fetch_alloc_message (void) { + logprintf("fetch_alloc_message()\n"); int data[2]; prefetch_data (data, 8); struct message *M = message_get (data[1]); @@ -1821,6 +1825,7 @@ struct message *fetch_alloc_message (void) { } struct message *fetch_alloc_geo_message (void) { + logprintf("fetch_alloc_geo_message()\n"); struct message *M = talloc (sizeof (*M)); fetch_geo_message (M); struct message *M1 = tree_lookup_message (message_tree, M); @@ -1844,6 +1849,7 @@ struct message *fetch_alloc_geo_message (void) { } struct message *fetch_alloc_encrypted_message (void) { + logprintf("fetch_alloc_encrypted_message()\n"); int data[3]; prefetch_data (data, 12); struct message *M = message_get (*(long long *)(data + 1)); @@ -1891,12 +1897,13 @@ struct message *fetch_alloc_message_short_chat (void) { } struct chat *fetch_alloc_chat (void) { - int send_event = 0; + logprintf("fetch_alloc_chat()\n"); int data[2]; prefetch_data (data, 8); peer_t *U = user_chat_get (MK_CHAT (data[1])); + logprintf("id %d\n", U->id.id); + logprintf("type %d\n", U->id.type); if (!U) { - send_event = 1; chats_allocated ++; U = talloc0 (sizeof (*U)); U->id = MK_CHAT (data[1]); @@ -1905,9 +1912,7 @@ struct chat *fetch_alloc_chat (void) { Peers[peer_num ++] = U; } fetch_chat (&U->chat); - if (send_event) { - event_chat_allocated(U); - } + event_peer_allocated(U); return &U->chat; } diff --git a/telegram.c b/telegram.c index 0fdb88d..071dc63 100755 --- a/telegram.c +++ b/telegram.c @@ -21,30 +21,15 @@ void event_update_new_message(struct message *M) { } /* - * User allocated + * Peer allocated */ -void (*on_user_allocated_handler)(peer_t *user); -void on_user_allocated(void (*handler)(peer_t *user)) { - on_user_allocated_handler = handler; +void (*on_peer_allocated_handler)(peer_t *peer); +void on_peer_allocated(void (*handler)(peer_t *peer)) { + on_peer_allocated_handler = handler; } -void event_user_allocated(peer_t *user) { - if (on_user_allocated_handler) { - on_user_allocated_handler(user); - } -} - -/* - * Chat allocated - */ -void (*on_chat_allocated_handler)(peer_t *chat); -void on_chat_allocated(void (*handler)(peer_t *chat)) -{ - on_chat_allocated_handler = handler; -} -void event_chat_allocated(peer_t *chat) -{ - if (on_chat_allocated_handler) { - on_chat_allocated_handler(chat); +void event_peer_allocated(peer_t *peer) { + if (on_peer_allocated_handler) { + on_peer_allocated_handler(peer); } } diff --git a/telegram.h b/telegram.h index a63ac99..597014d 100644 --- a/telegram.h +++ b/telegram.h @@ -2,7 +2,7 @@ * libtelegram * =========== * - * Telegram library based on the telegram cli application by vysheng (see https://github.com/vysheng/tg) + * Telegram library based on the telegram cli application, that was originally made by vysheng (see https://github.com/vysheng/tg) */ #define MAX_DC_NUM 9 @@ -140,20 +140,14 @@ void on_update_chat_participants(); /* * Load known users and chats on connect */ -void on_user_allocated(); -void on_user_allocated(void (*handler)(peer_t *user)); -void event_user_allocated(peer_t *user); - -void on_chat_allocated(void (*handler)(peer_t *chat)); -void event_chat_allocated(peer_t *chat); +void on_peer_allocated(void (*handler)(peer_t *peer)); +void event_peer_allocated(peer_t *peer); // template //void on_blarg(void (*on_msg)(struct message *M)); //void event_blarg(struct message *M); -void on_chat_allocated(); - /** * Set a function to use as a handle to read from a network resource * instead of the regular socket read function