diff --git a/interface.c b/interface.c index f3cad4b..16ec86a 100644 --- a/interface.c +++ b/interface.c @@ -64,6 +64,7 @@ char *commands[] = { "send_video", "send_text", "chat_info", + "user_info", "show_license", 0 }; @@ -78,6 +79,7 @@ int commands_flags[] = { 0732, 0732, 074, + 072, 07, }; @@ -330,6 +332,17 @@ void interpreter (char *line UU) { if (index < user_num + chat_num && Peers[index]->id < 0) { do_get_chat_info (Peers[index]); } + } else if (!memcmp (line, "user_info", 9)) { + char *q = line + 10; + int len; + char *text = get_token (&q, &len); + int index = 0; + while (index < user_num + chat_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len))) { + index ++; + } + if (index < user_num + chat_num && Peers[index]->id > 0) { + do_get_user_info (Peers[index]); + } } else if (!memcmp (line, "history", 7)) { char *q = line + 7; int len; @@ -363,6 +376,7 @@ void interpreter (char *line UU) { "send_video - sends video to peer\n" "send_text - sends text file as plain messages\n" "chat_info - prints info about chat\n" + "user_info - prints info about user\n" ); pop_color (); print_end (); diff --git a/queries.c b/queries.c index 910c9c0..d0f6239 100644 --- a/queries.c +++ b/queries.c @@ -911,6 +911,39 @@ void do_get_chat_info (union user_chat *chat) { send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &chat_info_methods, 0); } +int user_info_on_answer (struct query *q UU) { + struct user *U = fetch_alloc_user_full (); + union user_chat *C = (void *)U; + print_start (); + push_color (COLOR_YELLOW); + printf ("User "); + print_user_name (U->id, C); + printf (":\n"); + printf ("\t real name: %s %s\n", U->real_first_name, U->real_last_name); + printf ("\t phone: %s\n", U->phone); + pop_color (); + print_end (); + return 0; +} + +struct query_methods user_info_methods = { + .on_answer = user_info_on_answer +}; + +void do_get_user_info (union user_chat *U) { + clear_packet (); + out_int (CODE_users_get_full_user); + if (U->user.access_hash) { + out_int (CODE_input_user_foreign); + out_int (U->id); + out_long (U->user.access_hash); + } else { + out_int (CODE_input_user_contact); + out_int (U->id); + } + send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &user_info_methods, 0); +} + int user_list_info_silent_on_answer (struct query *q UU) { assert (fetch_int () == CODE_vector); int n = fetch_int (); diff --git a/queries.h b/queries.h index dc245c9..89e9160 100644 --- a/queries.h +++ b/queries.h @@ -74,5 +74,6 @@ void do_get_dialog_list (void); void do_send_photo (int type, int to_id, char *file_name); void do_get_chat_info (union user_chat *chat); void do_get_user_list_info_silent (int num, int *list); +void do_get_user_info (union user_chat *user); #endif diff --git a/structures.c b/structures.c index fb9bbca..fbbe35e 100644 --- a/structures.c +++ b/structures.c @@ -133,6 +133,44 @@ void fetch_user (struct user *U) { } } +void fetch_notify_settings (void); +void fetch_user_full (struct user *U) { + assert (fetch_int () == CODE_user_full); + fetch_alloc_user (); + unsigned x; + assert (fetch_int () == (int)CODE_contacts_link); + x = fetch_int (); + assert (x == CODE_contacts_my_link_empty || x == CODE_contacts_my_link_requested || x == CODE_contacts_my_link_contact); + U->flags &= ~(FLAG_USER_IN_CONTACT | FLAG_USER_OUT_CONTACT); + if (x == CODE_contacts_my_link_contact) { + U->flags |= FLAG_USER_IN_CONTACT; + } + if (x == CODE_contacts_my_link_requested) { + fetch_bool (); + } + x = fetch_int (); + assert (x == CODE_contacts_foreign_link_unknown || x == CODE_contacts_foreign_link_requested || x == CODE_contacts_foreign_link_mutual); + U->flags &= ~(FLAG_USER_IN_CONTACT | FLAG_USER_OUT_CONTACT); + if (x == CODE_contacts_foreign_link_mutual) { + U->flags |= FLAG_USER_IN_CONTACT | FLAG_USER_OUT_CONTACT; + } + if (x == CODE_contacts_my_link_requested) { + U->flags |= FLAG_USER_OUT_CONTACT; + fetch_bool (); + } + fetch_alloc_user (); + if (U->flags & FLAG_HAS_PHOTO) { + free_photo (&U->photo); + } + fetch_photo (&U->photo); + fetch_notify_settings (); + U->blocked = fetch_int (); + if (U->real_first_name) { free (U->real_first_name); } + if (U->real_last_name) { free (U->real_last_name); } + U->real_first_name = fetch_str_dup (); + U->real_last_name = fetch_str_dup (); +} + void fetch_chat (struct chat *C) { unsigned x = fetch_int (); assert (x == CODE_chat_empty || x == CODE_chat || x == CODE_chat_forbidden); @@ -468,6 +506,25 @@ struct user *fetch_alloc_user (void) { } } +struct user *fetch_alloc_user_full (void) { + int data[3]; + prefetch_data (data, 12); + union user_chat *U = user_chat_get (data[2]); + if (U) { + fetch_user_full (&U->user); + return &U->user; + } else { + users_allocated ++; + U = malloc (sizeof (*U)); + memset (U, 0, sizeof (*U)); + U->id = data[2]; + peer_tree = tree_insert_peer (peer_tree, U, lrand48 ()); + fetch_user_full (&U->user); + Peers[chat_num + (user_num ++ )] = U; + return &U->user; + } +} + void free_user (struct user *U) { if (U->first_name) { free (U->first_name); } if (U->last_name) { free (U->last_name); } diff --git a/structures.h b/structures.h index 6178c75..e08c1f1 100644 --- a/structures.h +++ b/structures.h @@ -27,6 +27,8 @@ #define FLAG_USER_SELF 128 #define FLAG_USER_FOREIGN 256 #define FLAG_USER_CONTACT 512 +#define FLAG_USER_IN_CONTACT 1024 +#define FLAG_USER_OUT_CONTACT 2048 #define FLAG_CHAT_IN_CHAT 128 @@ -79,6 +81,9 @@ struct user { char *phone; long long access_hash; struct user_status status; + int blocked; + char *real_first_name; + char *real_last_name; }; struct chat_user { @@ -185,11 +190,12 @@ void fetch_file_location (struct file_location *loc); void fetch_user_status (struct user_status *S); void fetch_user (struct user *U); struct user *fetch_alloc_user (void); +struct user *fetch_alloc_user_full (void); struct chat *fetch_alloc_chat (void); +struct chat *fetch_alloc_chat_full (void); struct message *fetch_alloc_message (void); struct message *fetch_alloc_message_short (void); struct message *fetch_alloc_message_short_chat (void); -struct chat *fetch_alloc_chat_full (void); int fetch_peer_id (void); void free_user (struct user *U);