void tgp_msg_recv (struct tgl_state *TLS, struct tgl_message *M) { connection_data *conn = TLS->ev_base; struct tgp_msg_loading *C = tgp_msg_loading_init (TRUE, M); if (M->date != 0 && M->date < tgp_msg_oldest_relevant_ts (TLS)) { debug ("Message from %d on %d too old, ignored.", tgl_get_peer_id (M->from_id), M->date); return; } if (M->media.type == tgl_message_media_photo) { C->done = FALSE; tgl_do_load_photo (TLS, M->media.photo, tgp_msg_on_loaded_document, C); } if (M->media.type == tgl_message_media_document_encr && M->media.encr_document->flags & TGLDF_IMAGE && !(M->media.encr_document->flags & TGLDF_STICKER)) { C->done = FALSE; tgl_do_load_encr_document (TLS, M->media.encr_document, tgp_msg_on_loaded_document, C); } #ifdef HAVE_LIBWEBP if (M->media.type == tgl_message_media_document && M->media.document->flags & TGLDF_STICKER) { C->done = FALSE; tgl_do_load_document (TLS, M->media.document, tgp_msg_on_loaded_document, C); } #endif if (M->media.type == tgl_message_media_geo) { // TODO: load geo thumbnail } g_queue_push_tail (conn->new_messages, C); tgp_msg_process_in_ready (TLS); }
static void tgprpl_xfer_recv_init (PurpleXfer *X) { debug ("tgprpl_xfer_recv_init"); struct tgp_xfer_send_data *data = X->data; purple_xfer_start (X, -1, NULL, 0); const char *who = purple_xfer_get_remote_user (X); tgl_peer_t *P = find_peer_by_name (data->conn->TLS, who); if (P) { if (data->document) { tgl_do_load_document (data->conn->TLS, data->document, tgprpl_xfer_recv_on_finished, data); } else if (data->encr_document) { tgl_do_load_encr_document (data->conn->TLS, data->encr_document, tgprpl_xfer_recv_on_finished, data); } } else { warning ("User not found, not downloading..."); } data->timer = purple_timeout_add (100, tgprpl_xfer_upload_progress, X); }
static void tgprpl_xfer_recv_init (PurpleXfer *X) { debug ("tgprpl_xfer_recv_init(): receiving xfer accepted."); struct tgp_xfer_send_data *data = X->data; struct tgl_state *TLS = data->conn->TLS; struct tgl_message *M = data->msg; struct tgl_document *D = M->media.document; tgl_peer_t *P = NULL; purple_xfer_start (X, -1, NULL, 0); const char *who = purple_xfer_get_remote_user (X); P = tgp_blist_lookup_peer_get (TLS, who); g_return_if_fail(P); switch (M->media.type) { case tgl_message_media_document: tgl_do_load_document (TLS, D, tgprpl_xfer_recv_on_finished, data); break; case tgl_message_media_document_encr: tgl_do_load_encr_document (TLS, M->media.encr_document, tgprpl_xfer_recv_on_finished, data); break; case tgl_message_media_audio: tgl_do_load_audio (TLS, D, tgprpl_xfer_recv_on_finished, data); break; case tgl_message_media_video: tgl_do_load_video (TLS, D, tgprpl_xfer_recv_on_finished, data); break; default: failure ("Unknown message media type: %d, XFER not possible.", M->media.type); return; } // Prevent the xfer data from getting freed after cancelling to allow the file transfer to complete // without crashing. This is necessary cause loading the file in libtgl cannot be aborted once started. purple_xfer_ref (X); data->timer = purple_timeout_add (100, tgprpl_xfer_upload_progress, X); data->loading = TRUE; }
static void tgprpl_xfer_recv_init (PurpleXfer *X) { debug ("tgprpl_xfer_recv_init"); struct tgp_xfer_send_data *data = X->data; struct tgl_state *TLS = data->conn->TLS; struct tgl_message *M = data->msg; struct tgl_document *D = M->media.document; tgl_peer_t *P = NULL; purple_xfer_start (X, -1, NULL, 0); const char *who = purple_xfer_get_remote_user (X); P = find_peer_by_name (TLS, who); if (P) { switch (M->media.type) { case tgl_message_media_document: tgl_do_load_document (TLS, D, tgprpl_xfer_recv_on_finished, data); break; case tgl_message_media_document_encr: tgl_do_load_encr_document (TLS, M->media.encr_document, tgprpl_xfer_recv_on_finished, data); break; case tgl_message_media_audio: tgl_do_load_audio (TLS, D, tgprpl_xfer_recv_on_finished, data); break; case tgl_message_media_video: tgl_do_load_video (TLS, D, tgprpl_xfer_recv_on_finished, data); break; default: failure ("Unknown message media type: %d, XFER not possible.", M->media.type); break; } } else { warning ("User not found, not downloading..."); } data->timer = purple_timeout_add (100, tgprpl_xfer_upload_progress, X); }
void tgp_msg_recv (struct tgl_state *TLS, struct tgl_message *M) { connection_data *conn = TLS->ev_base; if (M->flags & (TGLMF_EMPTY | TGLMF_DELETED)) { return; } if (!(M->flags & TGLMF_CREATED)) { return; } if (!(M->flags | TGLMF_UNREAD) && M->date != 0 && M->date < tgp_msg_oldest_relevant_ts (TLS)) { debug ("Message from %d on %d too old, ignored.", tgl_get_peer_id (M->from_id), M->date); return; } struct tgp_msg_loading *C = tgp_msg_loading_init (M); if (! (M->flags & TGLMF_SERVICE)) { // handle all messages that need to load content before they can be displayed if (M->media.type != tgl_message_media_none) { switch (M->media.type) { case tgl_message_media_photo: { // include the "bad photo" check from telegram-cli interface.c:3287 to avoid crashes when fetching history // TODO: find out the reason for this behavior if (M->media.photo) { ++ C->pending; tgl_do_load_photo (TLS, M->media.photo, tgp_msg_on_loaded_document, C); } break; } // documents that are stickers or images will be displayed just like regular photo messages // and need to be lodaed beforehand case tgl_message_media_document: case tgl_message_media_video: case tgl_message_media_audio: if (M->media.document->flags & TGLDF_STICKER || M->media.document->flags & TGLDF_IMAGE) { ++ C->pending; tgl_do_load_document (TLS, M->media.document, tgp_msg_on_loaded_document, C); } break; case tgl_message_media_document_encr: if (M->media.encr_document->flags & TGLDF_STICKER || M->media.encr_document->flags & TGLDF_IMAGE) { ++ C->pending; tgl_do_load_encr_document (TLS, M->media.encr_document, tgp_msg_on_loaded_document, C); } break; case tgl_message_media_geo: // TODO: load geo thumbnail break; default: // prevent Clang warnings ... break; } } } if (tgl_get_peer_type (M->to_id) == TGL_PEER_CHAT) { tgl_peer_t *P = tgl_peer_get (TLS, M->to_id); g_warn_if_fail(P); if (P && ! P->chat.user_list_size) { // To display a chat the full name of every single user is needed, but the updates received from the server only // contain the names of users mentioned in the events. In order to display a messages we always need to fetch the // full chat info first. If the user list is empty, this means that we still haven't fetched the full chat information. // assure that there is only one chat info request for every // chat to avoid causing FLOOD_WAIT_X errors that will lead to delays or dropped messages gpointer to_ptr = GINT_TO_POINTER(tgl_get_peer_id (M->to_id)); if (! g_hash_table_lookup (conn->pending_chat_info, to_ptr)) { ++ C->pending; tgl_do_get_chat_info (TLS, M->to_id, FALSE, tgp_msg_on_loaded_chat_full, C); g_hash_table_replace (conn->pending_chat_info, to_ptr, to_ptr); } } } g_queue_push_tail (conn->new_messages, C); tgp_msg_process_in_ready (TLS); }