diff --git a/constants.h b/constants.h index cb396fa..419f1f9 100644 --- a/constants.h +++ b/constants.h @@ -252,10 +252,11 @@ #define CODE_messages_dh_config 0x2c221edd #define CODE_messages_sent_encrypted_message 0x560f8935 #define CODE_messages_sent_encrypted_file 0x9493ff32 +#define CODE_input_file_big 0xfa4f0bb5 +#define CODE_input_encrypted_file_big_uploaded 0x2dc173c8 #define CODE_invoke_after_msg 0xcb9f372d #define CODE_invoke_after_msgs 0x3dc4b4f0 #define CODE_invoke_with_layer1 0x53835315 -#define CODE_init_connection 0x3fc12e08 #define CODE_auth_check_phone 0x6fe51dfb #define CODE_auth_send_code 0x768d5f4d #define CODE_auth_send_call 0x3c51564 @@ -348,4 +349,7 @@ #define CODE_messages_send_encrypted_service 0x32d439a4 #define CODE_messages_received_queue 0x55a5bb66 #define CODE_invoke_with_layer8 0xe9abd9fd +#define CODE_upload_save_big_file_part 0xde7b673d +#define CODE_init_connection 0x69796de9 +#define CODE_invoke_with_layer9 0x76715a63 #endif diff --git a/loop.c b/loop.c index f87edac..ea9c065 100644 --- a/loop.c +++ b/loop.c @@ -311,7 +311,7 @@ int loop (void) { perror ("getline()"); exit (EXIT_FAILURE); } - if (!*code || *code == 'y') { + if (!*code || *code == 'y' || *code == 'Y') { printf ("Ok, starting registartion.\n"); } else { printf ("Then try again\n"); @@ -368,7 +368,7 @@ int loop (void) { rl_attempted_completion_function = (CPPFunction *) complete_text; rl_completion_entry_function = complete_none; - do_get_dialog_list (); + do_get_dialog_list_ex (); return main_loop (); } diff --git a/mtproto-client.c b/mtproto-client.c index 0752a5c..3fb5380 100644 --- a/mtproto-client.c +++ b/mtproto-client.c @@ -946,6 +946,41 @@ void work_update (struct connection *c UU, long long msg_id UU) { free (location); } break; + case CODE_update_new_geo_chat_message: + { + struct message *M = fetch_alloc_geo_message (); + unread_messages ++; + print_message (M); + update_prompt (); + } + break; + case CODE_update_new_encrypted_message: + { + logprintf ("New encrypted message. Unsupported yet\n"); + } + break; + case CODE_update_encryption: + { + logprintf ("New encrypted chat. Unsupported yet\n"); + } + break; + case CODE_update_encrypted_chat_typing: + { + logprintf ("Typing in encrypted chat. Unsupported yet\n"); + } + break; + case CODE_update_encrypted_messages_read: + { + fetch_int (); // chat_id + fetch_int (); // max_date + fetch_int (); // date + print_start (); + push_color (COLOR_YELLOW); + printf ("Messages in encrypted chat mark read \n"); + pop_color (); + print_end (); + } + break; default: logprintf ("Unknown update type %08x\n", op); } diff --git a/mtproto-common.h b/mtproto-common.h index 02a920e..1b93d31 100644 --- a/mtproto-common.h +++ b/mtproto-common.h @@ -377,4 +377,8 @@ int pad_aes_decrypt (char *from, int from_len, char *to, int size); static inline void hexdump_in (void) { hexdump (in_ptr, in_end); } + +static inline void hexdump_out (void) { + hexdump (packet_buffer, packet_ptr); +} #endif diff --git a/queries.c b/queries.c index 5db981e..ee3c985 100644 --- a/queries.c +++ b/queries.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "include.h" #include "mtproto-client.h" @@ -35,6 +36,7 @@ #include "loop.h" #include "structures.h" #include "interface.h" +#include "net.h" char *get_downloads_directory (void); int verbosity; @@ -280,7 +282,7 @@ int help_get_config_on_answer (struct query *q UU) { unsigned test_mode = fetch_int (); assert (test_mode == CODE_bool_true || test_mode == CODE_bool_false); - assert (test_mode == CODE_bool_false); + assert (test_mode == CODE_bool_false || test_mode == CODE_bool_true); int this_dc = fetch_int (); if (verbosity) { logprintf ( "this_dc = %d\n", this_dc); @@ -325,7 +327,7 @@ void do_help_get_config (void) { char *phone_code_hash; int send_code_on_answer (struct query *q UU) { assert (fetch_int () == CODE_auth_sent_code); - assert (fetch_bool ()); + fetch_bool (); int l = prefetch_strlen (); char *s = fetch_str (l); if (phone_code_hash) { @@ -338,9 +340,13 @@ int send_code_on_answer (struct query *q UU) { int send_code_on_error (struct query *q UU, int error_code, int l, char *error) { int s = strlen ("PHONE_MIGRATE_"); + int s2 = strlen ("NETWORK_MIGRATE_"); if (l >= s && !memcmp (error, "PHONE_MIGRATE_", s)) { int i = error[s] - '0'; want_dc_num = i; + } else if (l >= s2 && !memcmp (error, "NETWORK_MIGRATE_", s2)) { + int i = error[s2] - '0'; + want_dc_num = i; } else { logprintf ( "error_code = %d, error = %.*s\n", error_code, l, error); assert (0); @@ -364,9 +370,11 @@ int config_got (void) { char *suser; extern int dc_working_num; void do_send_code (const char *user) { + logprintf ("sending code\n"); suser = strdup (user); want_dc_num = 0; clear_packet (); + out_int (CODE_invoke_with_layer6); out_int (CODE_auth_send_code); out_string (user); out_int (0); @@ -374,6 +382,7 @@ void do_send_code (const char *user) { out_string (TG_APP_HASH); out_string ("en"); + logprintf ("send_code: dc_num = %d\n", dc_working_num); send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_code_methods, 0); net_loop (0, code_is_sent); if (want_dc_num == -1) { return; } @@ -383,8 +392,10 @@ void do_send_code (const char *user) { dc_create_session (DC_working); } dc_working_num = want_dc_num; + logprintf ("send_code: dc_num = %d\n", dc_working_num); want_dc_num = 0; clear_packet (); + out_int (CODE_invoke_with_layer6); out_int (CODE_auth_send_code); out_string (user); out_int (0); @@ -420,7 +431,7 @@ int check_phone_on_error (struct query *q UU, int error_code, int l, char *error DC_working = DC_list[i]; write_auth_file (); check_phone_result = 1; - } else if (l >= s2 && !memcmp (error, "NETWORK_MIGRATE_", s)) { + } else if (l >= s2 && !memcmp (error, "NETWORK_MIGRATE_", s2)) { int i = error[s2] - '0'; assert (DC_list[i]); dc_working_num = i; @@ -746,6 +757,7 @@ void do_get_history (peer_id_t id, int limit) { send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_history_methods, (void *)*(long *)&id); } + int get_dialogs_on_answer (struct query *q UU) { unsigned x = fetch_int (); assert (x == CODE_messages_dialogs || x == CODE_messages_dialogs_slice); @@ -823,6 +835,34 @@ void do_get_dialog_list (void) { send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_dialogs_methods, 0); } +int allow_send_linux_version = 1; +void do_get_dialog_list_ex (void) { + clear_packet (); + out_int (CODE_invoke_with_layer9); + out_int (CODE_init_connection); + out_int (TG_APP_ID); + if (allow_send_linux_version) { + struct utsname st; + uname (&st); + out_string (st.machine); + static char buf[1000000]; + sprintf (buf, "%s %s %s", st.sysname, st.release, st.version); + out_string (buf); + out_string (TG_VERSION " (build " TG_BUILD ")"); + out_string ("En"); + } else { + out_string ("A"); + out_string ("L"); + out_string ("T"); + out_string ("en"); + } + out_int (CODE_messages_get_dialogs); + out_int (0); + out_int (0); + out_int (100); + send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_dialogs_methods, 0); +} + struct send_file { int fd; long long size; diff --git a/queries.h b/queries.h index 5c2abf7..8a9cb9b 100644 --- a/queries.h +++ b/queries.h @@ -73,6 +73,7 @@ void do_send_message (peer_id_t id, const char *msg, int len); void do_send_text (peer_id_t id, char *file); void do_get_history (peer_id_t id, int limit); void do_get_dialog_list (void); +void do_get_dialog_list_ex (void); void do_send_photo (int type, peer_id_t to_id, char *file_name); void do_get_chat_info (peer_id_t id); void do_get_user_list_info_silent (int num, int *list); diff --git a/structures.c b/structures.c index 366603c..ade8162 100644 --- a/structures.c +++ b/structures.c @@ -179,7 +179,7 @@ void fetch_user (struct user *U) { } fetch_user_status (&U->status); if (x == CODE_user_self) { - assert (fetch_int () == (int)CODE_bool_false); + fetch_bool (); } if (x == CODE_user_contact) { U->flags |= FLAG_USER_CONTACT; @@ -532,6 +532,27 @@ void fetch_message (struct message *M) { } } +void fetch_geo_message (struct message *M) { + memset (M, 0, sizeof (*M)); + unsigned x = fetch_int (); + assert (x == CODE_geo_chat_message_empty || x == CODE_geo_chat_message || x == CODE_geo_chat_message_service); + M->to_id = MK_GEO_CHAT (fetch_int ()); + M->id = fetch_int (); + if (x == CODE_geo_chat_message_empty) { + M->flags |= 1; + return; + } + M->from_id = MK_USER (fetch_int ()); + M->date = fetch_int (); + if (x == CODE_geo_chat_message_service) { + M->service = 1; + fetch_message_action (&M->action); + } else { + M->message = fetch_str_dup (); + fetch_message_media (&M->media); + } +} + #define id_cmp(a,b) ((a)->id - (b)->id) #define peer_cmp(a,b) (cmp_peer_id (a->id, b->id)) @@ -711,6 +732,26 @@ struct message *fetch_alloc_message (void) { } } +struct message *fetch_alloc_geo_message (void) { + struct message *M = malloc (sizeof (*M)); + fetch_geo_message (M); + struct message *M1 = tree_lookup_message (message_tree, M); + messages_allocated ++; + if (M1) { + message_del_use (M1); + free_message (M1); + memcpy (M1, M, sizeof (*M)); + free (M); + message_add_use (M1); + messages_allocated --; + return M1; + } else { + message_add_use (M); + message_tree = tree_insert_message (message_tree, M, lrand48 ()); + return M; + } +} + struct message *fetch_alloc_message_short (void) { struct message *M = malloc (sizeof (*M)); fetch_message_short (M); diff --git a/structures.h b/structures.h index 20b36c9..462e4d8 100644 --- a/structures.h +++ b/structures.h @@ -198,6 +198,7 @@ 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_geo_message (void); struct message *fetch_alloc_message_short (void); struct message *fetch_alloc_message_short_chat (void); peer_id_t fetch_peer_id (void); @@ -215,15 +216,20 @@ void fetch_photo (struct photo *P); #define PEER_USER 1 #define PEER_CHAT 2 +#define PEER_GEO_CHAT 3 #define PEER_UNKNOWN 0 #define MK_USER(id) set_peer_id (PEER_USER,id) #define MK_CHAT(id) set_peer_id (PEER_CHAT,id) +#define MK_GEO_CHAT(id) set_peer_id (PEER_GEO_CHAT,id) static inline int get_peer_type (peer_id_t id) { if (id.id > 0) { return PEER_USER; } + if (id.id < -1000000000) { + return PEER_GEO_CHAT; + } if (id.id < 0) { return PEER_CHAT; } @@ -236,6 +242,8 @@ static inline int get_peer_id (peer_id_t id) { return id.id; case PEER_CHAT: return -id.id; + case PEER_GEO_CHAT: + return -id.id - 1000000000; default: return 0; } @@ -250,6 +258,9 @@ static inline peer_id_t set_peer_id (int type, int id) { case PEER_CHAT: ID.id = -id; return ID; + case PEER_GEO_CHAT: + ID.id = -id - 1000000000; + return ID; default: assert (0); return ID;