diff --git a/Makefile.in b/Makefile.in index bdc8725..9cece7e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -15,7 +15,7 @@ OBJ=objs LIB=libs DIR_LIST=${DEP} ${AUTO} ${EXE} ${OBJ} ${LIB} ${DEP}/auto ${OBJ}/auto ${DEP}/lodepng ${OBJ}/lodepng -PLUGIN_OBJECTS=${OBJ}/tgp-net.o ${OBJ}/tgp-timers.o ${OBJ}/msglog.o ${OBJ}/telegram-base.o ${OBJ}/telegram-purple.o ${OBJ}/tgp-2prpl.o ${OBJ}/tgp-structs.o ${OBJ}/tgp-utils.o ${OBJ}/lodepng/lodepng.o +PLUGIN_OBJECTS=${OBJ}/tgp-net.o ${OBJ}/tgp-timers.o ${OBJ}/msglog.o ${OBJ}/telegram-base.o ${OBJ}/telegram-purple.o ${OBJ}/tgp-2prpl.o ${OBJ}/tgp-structs.o ${OBJ}/tgp-utils.o ${OBJ}/tgp-chat.o ${OBJ}/lodepng/lodepng.o ALL_OBJS=${PLUGIN_OBJECTS} .SUFFIXES: diff --git a/telegram-base.c b/telegram-base.c index 8482112..a83a25e 100644 --- a/telegram-base.c +++ b/telegram-base.c @@ -555,58 +555,6 @@ void telegram_login (struct tgl_state *TLS) { conn->login_timer = purple_timeout_add (100, check_all_authorized, TLS); } -PurpleConversation *chat_show (PurpleConnection *gc, int id) { - debug ("show chat"); - connection_data *conn = purple_connection_get_protocol_data(gc); - - PurpleConversation *convo = purple_find_chat(gc, id); - if (! convo) { - gchar *name = g_strdup_printf ("%d", id); - if (! g_hash_table_lookup (conn->joining_chats, name)) { - g_hash_table_insert (conn->joining_chats, name, (void *)1); - tgl_do_get_chat_info (conn->TLS, TGL_MK_CHAT(id), 0, on_chat_get_info, NULL); - } else { - g_free(name); - } - } - return convo; -} - -int chat_add_message (struct tgl_state *TLS, struct tgl_message *M, char *text) { - connection_data *conn = TLS->ev_base; - - if (chat_show (conn->gc, tgl_get_peer_id (M->to_id))) { - p2tgl_got_chat_in(TLS, M->to_id, M->from_id, text ? text : M->message, - M->service ? PURPLE_MESSAGE_SYSTEM : PURPLE_MESSAGE_RECV, M->date); - - pending_reads_add (conn->pending_reads, M->to_id); - if (p2tgl_status_is_present(purple_account_get_active_status(conn->pa))) { - pending_reads_send_all (conn->pending_reads, conn->TLS); - } - return 1; - } else { - // add message once the chat was initialised - struct message_text *mt = message_text_init (M, text); - g_queue_push_tail (conn->new_messages, mt); - return 0; - } -} - -void chat_add_all_users (PurpleConversation *pc, struct tgl_chat *chat) { - struct tgl_chat_user *curr = chat->user_list; - if (!curr) { - warning ("add_all_users_to_chat: chat contains no user list, cannot add users\n."); - return; - } - - int i; - for (i = 0; i < chat->user_list_size; i++) { - struct tgl_chat_user *uid = (curr + i); - int flags = (chat->admin_id == uid->user_id ? PURPLE_CBFLAGS_FOUNDER : PURPLE_CBFLAGS_NONE); - p2tgl_conv_add_user(pc, *uid, NULL, flags, 0); - } -} - /** * This function generates a png image to visualize the sha1 key from an encrypted chat. */ diff --git a/telegram-base.h b/telegram-base.h index c93d80a..3a89e4f 100644 --- a/telegram-base.h +++ b/telegram-base.h @@ -31,9 +31,6 @@ void read_secret_chat_file (struct tgl_state *TLS); void write_secret_chat_file (struct tgl_state *TLS); void telegram_login (struct tgl_state *TLS); -PurpleConversation *chat_show (PurpleConnection *gc, int id); -int chat_add_message (struct tgl_state *TLS, struct tgl_message *M, char *text); -void chat_add_all_users (PurpleConversation *pc, struct tgl_chat *chat); void request_code_entered (gpointer data, const gchar *code); int generate_ident_icon(struct tgl_state *TLS, unsigned char* sha1_key); diff --git a/telegram-purple.c b/telegram-purple.c index d814125..81a8b54 100755 --- a/telegram-purple.c +++ b/telegram-purple.c @@ -67,6 +67,7 @@ #include "telegram-purple.h" #include "msglog.h" #include "tgp-utils.h" +#include "tgp-chat.h" #define _(m) m @@ -74,14 +75,8 @@ PurplePlugin *_telegram_protocol = NULL; PurpleGroup *tggroup; const char *config_dir = ".telegram-purple"; const char *pk_path = "/etc/telegram-purple/server.pub"; -void tgprpl_login_on_connected(); -void on_user_get_info (struct tgl_state *TLS, void *info_data, int success, struct tgl_user *U); -static connection_data *get_conn_from_buddy (PurpleBuddy *buddy) { - connection_data *c = purple_connection_get_protocol_data ( - purple_account_get_connection (purple_buddy_get_account (buddy))); - return c; -} +void on_user_get_info (struct tgl_state *TLS, void *info_data, int success, struct tgl_user *U); static char *format_status (struct tgl_user_status *status) { return status->online ? "Online" : "Mobile"; @@ -269,30 +264,10 @@ static void tgl_do_send_unescape_message (struct tgl_state *TLS, const char *mes static void start_secret_chat (PurpleBlistNode *node, gpointer data) { PurpleBuddy *buddy = data; - connection_data *conn = purple_connection_get_protocol_data ( - purple_account_get_connection (purple_buddy_get_account(buddy))); - - tgl_do_create_secret_chat(conn->TLS, TGL_MK_USER(atoi (purple_buddy_get_name (buddy))), - 0, 0); -} -static void on_update_user_name (struct tgl_state *TLS, tgl_peer_t *user) __attribute__ ((unused)); -static void on_update_user_name (struct tgl_state *TLS, tgl_peer_t *user) { - p2tgl_got_alias(TLS, user->id, p2tgl_strdup_alias(user)); -} - -static void on_update_chat_participants (struct tgl_state *TLS, struct tgl_chat *chat) { - PurpleConversation *pc = purple_find_chat(tg_get_conn(TLS), tgl_get_peer_id(chat->id)); - if (pc) { - purple_conv_chat_clear_users (purple_conversation_get_chat_data(pc)); - chat_add_all_users (pc, chat); - } -} - -static void on_update_new_user_status (struct tgl_state *TLS, void *peer) __attribute__ ((unused)); -static void on_update_new_user_status (struct tgl_state *TLS, void *peer) { - tgl_peer_t *p = peer; - p2tgl_prpl_got_user_status(TLS, p->id, &p->user.status); + connection_data *conn = get_conn_from_buddy (buddy); + const char *name = purple_buddy_get_name (buddy); + tgl_do_create_secret_chat (conn->TLS, TGL_MK_USER(atoi (name)), 0, 0); } static void update_message_received (struct tgl_state *TLS, struct tgl_message *M); @@ -527,24 +502,19 @@ static void update_secret_chat_handler (struct tgl_state *TLS, struct tgl_secret static void update_chat_handler (struct tgl_state *TLS, struct tgl_chat *chat, unsigned flags) { PurpleChat *ch = p2tgl_chat_find (TLS, chat->id); - + if (flags & TGL_UPDATE_CREATED) { - if (!ch) { - ch = p2tgl_chat_new (TLS, chat); - purple_blist_add_chat(ch, NULL, NULL); - } + tgl_do_get_chat_info (TLS, chat->id, 0, on_chat_get_info, 0); } if (flags & TGL_UPDATE_TITLE && ch) { purple_blist_alias_chat (ch, chat->print_title); } if (flags & (TGL_UPDATE_MEMBERS | TGL_UPDATE_ADMIN) && ch) { - on_update_chat_participants (TLS, chat); + chat_users_update (TLS, chat); } if (flags & TGL_UPDATE_DELETED && ch) { purple_blist_remove_chat (ch); } - - // TODO: check if user is a member of the current chat and don't display the chat in that case } static void update_user_typing (struct tgl_state *TLS, struct tgl_user *U, enum tgl_typing_status status) { @@ -618,34 +588,17 @@ void on_user_get_info (struct tgl_state *TLS, void *info_data, int success, stru } void on_chat_get_info (struct tgl_state *TLS, void *extra, int success, struct tgl_chat *C) { - assert (success); - - debug ("on_chat_joined(%d)\n", tgl_get_peer_id (C->id)); - connection_data *conn = TLS->ev_base; - - PurpleConversation *conv; - if (!(conv = purple_find_chat (conn->gc, tgl_get_peer_id(C->id)))) { - // chat conversation is not existing, create it - conv = serv_got_joined_chat (conn->gc, tgl_get_peer_id(C->id), C->title); - } - purple_conv_chat_clear_users (purple_conversation_get_chat_data(conv)); - chat_add_all_users (conv, C); - - struct message_text *mt = 0; - while ((mt = g_queue_pop_head (conn->new_messages))) { - if (!chat_add_message(TLS, mt->M, mt->text)) { - warning ("WARNING, chat %d still not existing... \n", tgl_get_peer_id (C->id)); - break; - } - if (mt->text) { - g_free (mt->text); - } - free (mt); + if (!success || !chat_is_member (TLS->our_id, C)) { + return; } - gchar *name = g_strdup_printf ("%d", tgl_get_peer_id (C->id)); - g_hash_table_remove (conn->joining_chats, name); - g_free (name); + PurpleChat *PC = p2tgl_chat_find (TLS, C->id); + if (!PC) { + PC = p2tgl_chat_new (TLS, C); + purple_blist_add_chat (PC, NULL, NULL); + } + + chat_users_update (TLS, C); } void on_ready (struct tgl_state *TLS) { @@ -896,7 +849,6 @@ static void tgprpl_remove_buddy (PurpleConnection * gc, PurpleBuddy * buddy, Pur // telegram peer not existing, orphaned buddy return; } - switch (tgl_get_peer_type(peer->id)) { case TGL_PEER_ENCR_CHAT: /* TODO: implement the api call cancel secret chats. Currently the chat will only be marked as @@ -923,17 +875,9 @@ static void tgprpl_chat_join (PurpleConnection * gc, GHashTable * data) { debug ("tgprpl_chat_join()\n"); connection_data *conn = purple_connection_get_protocol_data (gc); - const char *groupname = g_hash_table_lookup (data, "subject"); - - char *id = g_hash_table_lookup(data, "id"); - if (!id) { - warning ("Got no chat id, aborting...\n"); - return; - } - if (!purple_find_chat(gc, atoi(id))) { - tgl_do_get_chat_info (conn->TLS, TGL_MK_CHAT(atoi(id)), 0, on_chat_get_info, 0); - } else { - serv_got_joined_chat(conn->gc, atoi(id), groupname); + int id = atoi (g_hash_table_lookup (data, "id")); + if (id) { + chat_show (conn->gc, id); } } diff --git a/tgp-2prpl.c b/tgp-2prpl.c index a3e6d17..d3f6d8f 100644 --- a/tgp-2prpl.c +++ b/tgp-2prpl.c @@ -94,9 +94,9 @@ void p2tgl_got_chat_left (struct tgl_state *TLS, tgl_peer_id_t chat) { } void p2tgl_got_chat_in (struct tgl_state *TLS, tgl_peer_id_t chat, tgl_peer_id_t who, const char *message, int flags, time_t when) { - char *name = p2tgl_peer_strdup_id(who); + char *name = p2tgl_peer_strdup_id (who); - serv_got_chat_in(tg_get_conn(TLS), tgl_get_peer_id (chat), name, flags, message, when); + serv_got_chat_in (tg_get_conn(TLS), tgl_get_peer_id (chat), name, flags, message, when); g_free (name); } diff --git a/tgp-chat.c b/tgp-chat.c new file mode 100644 index 0000000..2aa6932 --- /dev/null +++ b/tgp-chat.c @@ -0,0 +1,71 @@ +/* + This file is part of telegram-purple + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + + Copyright Matthias Jentsch 2014 + */ + +#include "tgp-chat.h" + +void chat_add_all_users (PurpleConversation *pc, struct tgl_chat *chat) { + for (int i = 0; i < chat->user_list_size; i++) { + struct tgl_chat_user *uid = (chat->user_list + i); + int flags = (chat->admin_id == uid->user_id ? PURPLE_CBFLAGS_FOUNDER : PURPLE_CBFLAGS_NONE); + p2tgl_conv_add_user (pc, *uid, NULL, flags, 0); + } +} + +void chat_users_update (struct tgl_state *TLS, struct tgl_chat *chat) { + PurpleConversation *pc = purple_find_chat(tg_get_conn(TLS), tgl_get_peer_id(chat->id)); + if (pc) { + purple_conv_chat_clear_users (purple_conversation_get_chat_data(pc)); + chat_add_all_users (pc, chat); + } +} + +PurpleConversation *chat_show (PurpleConnection *gc, int id) { + connection_data *conn = purple_connection_get_protocol_data(gc); + + PurpleConversation *convo = purple_find_chat (gc, id); + if (! convo) { + tgl_peer_t *P = tgl_peer_get (conn->TLS, TGL_MK_CHAT(id)); + convo = p2tgl_got_joined_chat (conn->TLS, &P->chat); + chat_users_update (conn->TLS, &P->chat); + } + return convo; +} + +int chat_add_message (struct tgl_state *TLS, struct tgl_message *M, char *text) { + connection_data *conn = TLS->ev_base; + + if (chat_show (conn->gc, tgl_get_peer_id (M->to_id))) { + p2tgl_got_chat_in(TLS, M->to_id, M->from_id, text ? text : M->message, M->service ? PURPLE_MESSAGE_SYSTEM : PURPLE_MESSAGE_RECV, M->date); + + pending_reads_add (conn->pending_reads, M->to_id); + if (p2tgl_status_is_present (purple_account_get_active_status (conn->pa))) { + pending_reads_send_all (conn->pending_reads, conn->TLS); + } + return 1; + } + return 0; +} + +int chat_is_member (int who, struct tgl_chat *chat) { + for (int i = 0; i < chat->user_list_size; i++) if ((chat->user_list + i)->user_id) { + return TRUE; + } + return FALSE; +} diff --git a/tgp-chat.h b/tgp-chat.h new file mode 100644 index 0000000..d4de13b --- /dev/null +++ b/tgp-chat.h @@ -0,0 +1,34 @@ +/* + This file is part of telegram-purple + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + + Copyright Matthias Jentsch 2014 + */ + +#ifndef __telegram_adium__tgp_chat__ +#define __telegram_adium__tgp_chat__ + +#include "telegram-purple.h" +#include "tgp-structs.h" +#include "tgp-2prpl.h" +#include + +PurpleConversation *chat_show (PurpleConnection *gc, int id); +void chat_users_update (struct tgl_state *TLS, struct tgl_chat *chat); +int chat_add_message (struct tgl_state *TLS, struct tgl_message *M, char *text); +int chat_is_member (int who, struct tgl_chat *chat); + +#endif diff --git a/tgp-structs.c b/tgp-structs.c index da48d8d..5648cbe 100644 --- a/tgp-structs.c +++ b/tgp-structs.c @@ -90,7 +90,6 @@ connection_data *connection_data_init (struct tgl_state *TLS, PurpleConnection * conn->pa = pa; conn->new_messages = g_queue_new (); conn->pending_reads = g_queue_new (); - conn->joining_chats = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); return conn; } @@ -100,7 +99,6 @@ void *connection_data_free (connection_data *conn) { tgp_g_queue_free_full (conn->pending_reads, pending_reads_free_cb); tgp_g_queue_free_full (conn->new_messages, message_text_free); - g_hash_table_destroy (conn->joining_chats); g_list_free_full (conn->used_images, used_image_free); tgl_free_all (conn->TLS); free (conn->TLS); diff --git a/tgp-structs.h b/tgp-structs.h index 7b67864..fac458d 100755 --- a/tgp-structs.h +++ b/tgp-structs.h @@ -35,7 +35,6 @@ typedef struct { GQueue *new_messages; GQueue *pending_reads; GList *used_images; - GHashTable *joining_chats; guint write_timer; guint login_timer; int in_fallback_chat; diff --git a/tgp-utils.c b/tgp-utils.c index cafa54c..8a979ab 100644 --- a/tgp-utils.c +++ b/tgp-utils.c @@ -19,7 +19,13 @@ */ #include "tgp-utils.h" -#include "purple.h" +#include + +connection_data *get_conn_from_buddy (PurpleBuddy *buddy) { + connection_data *c = purple_connection_get_protocol_data ( + purple_account_get_connection (purple_buddy_get_account (buddy))); + return c; +} const char *format_time (time_t date) { struct tm *datetime = localtime(&date); diff --git a/tgp-utils.h b/tgp-utils.h index 894e1b2..21c3191 100644 --- a/tgp-utils.h +++ b/tgp-utils.h @@ -20,11 +20,14 @@ #ifndef __telegram_adium__tgp_util__ #define __telegram_adium__tgp_util__ +#include "tgp-structs.h" + #include #include #include #include +connection_data *get_conn_from_buddy (PurpleBuddy *buddy); tgl_peer_t *tgp_encr_chat_get_partner (struct tgl_state *TLS, struct tgl_secret_chat *chat); tgl_peer_t *find_peer_by_name (struct tgl_state *TLS, const char *who);