Commit a8a18a80 authored by Vysheng's avatar Vysheng

Sometimes updates work

parent baa56b70
...@@ -198,6 +198,18 @@ void interpreter (char *line UU) { ...@@ -198,6 +198,18 @@ void interpreter (char *line UU) {
static char stat_buf[1 << 15]; static char stat_buf[1 << 15];
print_stat (stat_buf, (1 << 15) - 1); print_stat (stat_buf, (1 << 15) - 1);
printf ("%s\n", stat_buf); printf ("%s\n", stat_buf);
} else if (!memcmp (line, "msg ", 4)) {
char *q = line + 4;
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) || Peers[index]->id < 0)) {
index ++;
}
while (*q && (*q == ' ' || *q == '\t')) { q ++; }
if (*q && index < user_num + chat_num) {
do_send_message (Peers[index], q);
}
} }
} }
...@@ -276,3 +288,14 @@ void logprintf (const char *format, ...) { ...@@ -276,3 +288,14 @@ void logprintf (const char *format, ...) {
free(saved_line); free(saved_line);
} }
} }
void print_message (struct message *M) {
union user_chat *U = user_chat_get (M->from_id);
if (!M->service) {
if (U && U->id > 0) {
rprintf (COLOR_RED "%s %s " COLOR_GREEN " >>> " COLOR_NORMAL " %s\n", U->user.first_name, U->user.last_name, M->message);
} else {
rprintf (COLOR_RED "User #%d " COLOR_GREEN " >>> " COLOR_NORMAL " %s\n", M->from_id, M->message);
}
}
}
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#define COLOR_NORMAL "\033[0m" #define COLOR_NORMAL "\033[0m"
#define COLOR_GREEN "\033[32;1m" #define COLOR_GREEN "\033[32;1m"
#define COLOR_GREY "\033[37;1m" #define COLOR_GREY "\033[37;1m"
#define COLOR_YELLOW "\033[33;1m"
char *get_default_prompt (void); char *get_default_prompt (void);
...@@ -16,4 +17,7 @@ void rprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2))); ...@@ -16,4 +17,7 @@ void rprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2)));
void iprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2))); void iprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2)));
void logprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2))); void logprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2)));
void hexdump (int *in_ptr, int *in_end); void hexdump (int *in_ptr, int *in_end);
struct message;
void print_message (struct message *M);
#endif #endif
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "queries.h" #include "queries.h"
#include "loop.h" #include "loop.h"
#include "interface.h" #include "interface.h"
#include "structures.h"
#define sha1 SHA1 #define sha1 SHA1
...@@ -611,6 +612,181 @@ int auth_work_start (struct connection *c UU) { ...@@ -611,6 +612,181 @@ int auth_work_start (struct connection *c UU) {
} }
void rpc_execute_answer (struct connection *c, long long msg_id UU); void rpc_execute_answer (struct connection *c, long long msg_id UU);
void work_update (struct connection *c UU, long long msg_id UU) {
unsigned op = fetch_int ();
switch (op) {
case CODE_update_new_message:
{
struct message *M = fetch_alloc_message ();
print_message (M);
break;
};
case CODE_update_message_i_d:
{
int id = fetch_int (); // id
int new = fetch_long (); // random_id
struct message *M = message_get (new);
update_message_id (M, id);
}
break;
case CODE_update_read_messages:
{
assert (fetch_int () == (int)CODE_vector);
int n = fetch_int ();
int i;
for (i = 0; i < n; i++) {
int id = fetch_int ();
struct message *M = message_get (id);
if (M) {
M->unread = 0;
}
}
fetch_int (); //pts
}
break;
case CODE_update_user_typing:
{
int id = fetch_int ();
union user_chat *U = user_chat_get (id);
if (U) {
rprintf (COLOR_YELLOW "User " COLOR_RED "%s %s" COLOR_YELLOW " is typing....\n" COLOR_NORMAL, U->user.first_name, U->user.last_name);
}
}
break;
case CODE_update_chat_user_typing:
{
int chat_id = fetch_int ();
int id = fetch_int ();
union user_chat *C = user_chat_get (-chat_id);
union user_chat *U = user_chat_get (id);
if (U && C) {
rprintf (COLOR_YELLOW "User " COLOR_RED "%s %s" COLOR_YELLOW " is typing in chat %s....\n" COLOR_NORMAL, U->user.first_name, U->user.last_name, C->chat.title);
}
}
break;
case CODE_update_user_status:
{
int user_id = fetch_int ();
union user_chat *U = user_chat_get (user_id);
if (U) {
fetch_user_status (&U->user.status);
rprintf (COLOR_YELLOW "User " COLOR_RED "%s %s" COLOR_YELLOW " is now %s\n" COLOR_NORMAL, U->user.first_name, U->user.last_name, (U->user.status.online > 0) ? "online" : "offline");
} else {
struct user_status t;
fetch_user_status (&t);
}
}
break;
case CODE_update_user_name:
{
int user_id = fetch_int ();
union user_chat *UC = user_chat_get (user_id);
if (UC) {
struct user *U = &UC->user;
if (U->first_name) { free (U->first_name); }
if (U->last_name) { free (U->first_name); }
if (U->print_name) { free (U->first_name); }
U->first_name = fetch_str_dup ();
U->last_name = fetch_str_dup ();
if (!strlen (U->first_name)) {
if (!strlen (U->last_name)) {
U->print_name = strdup ("none");
} else {
U->print_name = strdup (U->last_name);
}
} else {
if (!strlen (U->last_name)) {
U->print_name = strdup (U->first_name);
} else {
U->print_name = malloc (strlen (U->first_name) + strlen (U->last_name) + 2);
sprintf (U->print_name, "%s_%s", U->first_name, U->last_name);
}
}
} else {
int l;
l = prefetch_strlen ();
fetch_str (l);
l = prefetch_strlen ();
fetch_str (l);
l = prefetch_strlen ();
fetch_str (l);
}
}
break;
case CODE_update_user_photo:
{
int user_id = fetch_int ();
union user_chat *UC = user_chat_get (user_id);
if (UC) {
struct user *U = &UC->user;
unsigned y = fetch_int ();
if (y == CODE_user_profile_photo_empty) {
U->photo_big.dc = -2;
U->photo_small.dc = -2;
} else {
assert (y == CODE_user_profile_photo);
fetch_file_location (&U->photo_small);
fetch_file_location (&U->photo_big);
}
} else {
struct file_location t;
unsigned y = fetch_int ();
if (y == CODE_user_profile_photo_empty) {
} else {
assert (y == CODE_user_profile_photo);
fetch_file_location (&t);
fetch_file_location (&t);
}
}
}
break;
default:
logprintf ("Unknown update type %08x\n", op);
}
}
void work_update_short (struct connection *c, long long msg_id) {
assert (fetch_int () == CODE_update_short);
work_update (c, msg_id);
fetch_int (); // date
}
void work_updates (struct connection *c, long long msg_id) {
assert (fetch_int () == CODE_updates);
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
int i;
for (i = 0; i < n; i++) {
work_update (c, msg_id);
}
assert (fetch_int () == CODE_vector);
n = fetch_int ();
for (i = 0; i < n; i++) {
fetch_alloc_user ();
}
assert (fetch_int () == CODE_vector);
n = fetch_int ();
for (i = 0; i < n; i++) {
fetch_alloc_chat ();
}
fetch_int (); // date
fetch_int (); // seq
}
void work_update_short_message (struct connection *c UU, long long msg_id UU) {
assert (fetch_int () == (int)CODE_update_short_message);
struct message *M = fetch_alloc_message_short ();
print_message (M);
}
void work_update_short_chat_message (struct connection *c UU, long long msg_id UU) {
assert (fetch_int () == CODE_update_short_chat_message);
struct message *M = fetch_alloc_message_short_chat ();
print_message (M);
}
void work_container (struct connection *c, long long msg_id UU) { void work_container (struct connection *c, long long msg_id UU) {
if (verbosity) { if (verbosity) {
logprintf ( "work_container: msg_id = %lld\n", msg_id); logprintf ( "work_container: msg_id = %lld\n", msg_id);
...@@ -671,6 +847,9 @@ void work_rpc_result (struct connection *c UU, long long msg_id UU) { ...@@ -671,6 +847,9 @@ void work_rpc_result (struct connection *c UU, long long msg_id UU) {
} }
void rpc_execute_answer (struct connection *c, long long msg_id UU) { void rpc_execute_answer (struct connection *c, long long msg_id UU) {
if (verbosity >= 5) {
hexdump_in ();
}
int op = prefetch_int (); int op = prefetch_int ();
switch (op) { switch (op) {
case CODE_msg_container: case CODE_msg_container:
...@@ -685,6 +864,18 @@ void rpc_execute_answer (struct connection *c, long long msg_id UU) { ...@@ -685,6 +864,18 @@ void rpc_execute_answer (struct connection *c, long long msg_id UU) {
case CODE_rpc_result: case CODE_rpc_result:
work_rpc_result (c, msg_id); work_rpc_result (c, msg_id);
return; return;
case CODE_update_short:
work_update_short (c, msg_id);
return;
case CODE_updates:
work_updates (c, msg_id);
return;
case CODE_update_short_message:
work_update_short_message (c, msg_id);
return;
case CODE_update_short_chat_message:
work_update_short_chat_message (c, msg_id);
return;
} }
logprintf ( "Unknown message: \n"); logprintf ( "Unknown message: \n");
hexdump_in (); hexdump_in ();
......
...@@ -255,8 +255,12 @@ static inline int prefetch_strlen (void) { ...@@ -255,8 +255,12 @@ static inline int prefetch_strlen (void) {
} }
} }
extern int verbosity;
static inline char *fetch_str (int len) { static inline char *fetch_str (int len) {
assert (len >= 0);
if (verbosity > 6) {
logprintf ("fetch_string: len = %d\n", len);
}
if (len < 254) { if (len < 254) {
char *str = (char *) in_ptr + 1; char *str = (char *) in_ptr + 1;
in_ptr += 1 + (len >> 2); in_ptr += 1 + (len >> 2);
...@@ -289,6 +293,9 @@ static inline long have_prefetch_ints (void) { ...@@ -289,6 +293,9 @@ static inline long have_prefetch_ints (void) {
int fetch_bignum (BIGNUM *x); int fetch_bignum (BIGNUM *x);
static inline int fetch_int (void) { static inline int fetch_int (void) {
if (verbosity > 6) {
logprintf ("fetch_int: 0x%08x (%d)\n", *in_ptr, *in_ptr);
}
return *(in_ptr ++); return *(in_ptr ++);
} }
......
...@@ -391,6 +391,7 @@ void connections_poll_result (struct pollfd *fds, int max) { ...@@ -391,6 +391,7 @@ void connections_poll_result (struct pollfd *fds, int max) {
int send_all_acks (struct session *S) { int send_all_acks (struct session *S) {
clear_packet (); clear_packet ();
out_int (CODE_msgs_ack);
out_int (tree_count_int (S->ack_tree)); out_int (tree_count_int (S->ack_tree));
while (S->ack_tree) { while (S->ack_tree) {
int x = tree_get_min_int (S->ack_tree); int x = tree_get_min_int (S->ack_tree);
......
...@@ -46,6 +46,7 @@ struct query *send_query (struct dc *DC, int ints, void *data, struct query_meth ...@@ -46,6 +46,7 @@ struct query *send_query (struct dc *DC, int ints, void *data, struct query_meth
logprintf ( "Sending query of size %d to DC (%s:%d)\n", 4 * ints, DC->ip, DC->port); logprintf ( "Sending query of size %d to DC (%s:%d)\n", 4 * ints, DC->ip, DC->port);
} }
struct query *q = malloc (sizeof (*q)); struct query *q = malloc (sizeof (*q));
memset (q, 0, sizeof (*q));
q->data_len = ints; q->data_len = ints;
q->data = malloc (4 * ints); q->data = malloc (4 * ints);
memcpy (q->data, data, 4 * ints); memcpy (q->data, data, 4 * ints);
...@@ -68,7 +69,10 @@ struct query *send_query (struct dc *DC, int ints, void *data, struct query_meth ...@@ -68,7 +69,10 @@ struct query *send_query (struct dc *DC, int ints, void *data, struct query_meth
void query_ack (long long id) { void query_ack (long long id) {
struct query *q = query_get (id); struct query *q = query_get (id);
if (q) { q->flags |= QUERY_ACK_RECEIVED; } if (q) {
remove_event_timer (&q->ev);
q->flags |= QUERY_ACK_RECEIVED;
}
} }
void query_error (long long id) { void query_error (long long id) {
...@@ -85,7 +89,9 @@ void query_error (long long id) { ...@@ -85,7 +89,9 @@ void query_error (long long id) {
logprintf ( "No such query\n"); logprintf ( "No such query\n");
} }
} else { } else {
remove_event_timer (&q->ev); if (!(q->flags & QUERY_ACK_RECEIVED)) {
remove_event_timer (&q->ev);
}
queries_tree = tree_delete_query (queries_tree, q); queries_tree = tree_delete_query (queries_tree, q);
if (q->methods && q->methods->on_error) { if (q->methods && q->methods->on_error) {
q->methods->on_error (q, error_code, error_len, error); q->methods->on_error (q, error_code, error_len, error);
...@@ -143,7 +149,9 @@ void query_result (long long id UU) { ...@@ -143,7 +149,9 @@ void query_result (long long id UU) {
logprintf ( "No such query\n"); logprintf ( "No such query\n");
} }
} else { } else {
remove_event_timer (&q->ev); if (!(q->flags & QUERY_ACK_RECEIVED)) {
remove_event_timer (&q->ev);
}
queries_tree = tree_delete_query (queries_tree, q); queries_tree = tree_delete_query (queries_tree, q);
if (q->methods && q->methods->on_answer) { if (q->methods && q->methods->on_answer) {
q->methods->on_answer (q); q->methods->on_answer (q);
...@@ -191,6 +199,10 @@ void work_timers (void) { ...@@ -191,6 +199,10 @@ void work_timers (void) {
assert (ev); assert (ev);
if (ev->timeout > t) { break; } if (ev->timeout > t) { break; }
remove_event_timer (ev); remove_event_timer (ev);
assert (ev->alarm);
if (verbosity) {
logprintf ("Alarm\n");
}
ev->alarm (ev->self); ev->alarm (ev->self);
} }
} }
...@@ -405,3 +417,48 @@ void do_update_contact_list (void) { ...@@ -405,3 +417,48 @@ void do_update_contact_list (void) {
out_string (""); out_string ("");
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_contacts_methods); send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_contacts_methods);
} }
int msg_send_on_answer (struct query *q UU) {
assert (fetch_int () == (int)CODE_messages_sent_message);
int uid = fetch_int (); // uid
int date = fetch_int (); // date
int ptr = fetch_int (); // ptr
int seq = fetch_int (); // seq
logprintf ("Sent: uid = %d, date = %d, ptr = %d, seq = %d\n", uid, date, ptr, seq);
return 0;
}
struct query_methods msg_send_methods = {
.on_answer = msg_send_on_answer
};
int out_message_num;
void do_send_message (union user_chat *U, const char *msg) {
if (!out_message_num) {
out_message_num = lrand48 ();
}
clear_packet ();
out_int (CODE_messages_send_message);
if (U->id < 0) {
out_int (CODE_input_peer_chat);
out_int (-U->id);
} else {
if (U->user.access_hash) {
out_int (CODE_input_peer_foreign);
out_int (U->id);
out_long (U->user.access_hash);
} else {
out_int (CODE_input_peer_contact);
out_int (U->id);
}
}
out_string (msg);
out_long (out_message_num ++);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &msg_send_methods);
if (U->id < 0) {
rprintf (COLOR_RED "%s" COLOR_GREEN " <<< " COLOR_NORMAL "%s\n", U->chat.title, msg);
} else {
rprintf (COLOR_RED "%s %s" COLOR_GREEN " <<< " COLOR_NORMAL "%s\n", U->user.first_name, U->user.last_name, msg);
}
}
...@@ -44,4 +44,6 @@ int do_send_code_result (const char *code); ...@@ -44,4 +44,6 @@ int do_send_code_result (const char *code);
double get_double_time (void); double get_double_time (void);
void do_update_contact_list (void); void do_update_contact_list (void);
union user_chat;
void do_send_message (union user_chat *U, const char *msg);
#endif #endif
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "telegram.h" #include "telegram.h"
#include "tree.h" #include "tree.h"
int verbosity;
void fetch_file_location (struct file_location *loc) { void fetch_file_location (struct file_location *loc) {
int x = fetch_int (); int x = fetch_int ();
if (x == CODE_file_location_unavailable) { if (x == CODE_file_location_unavailable) {
...@@ -234,6 +236,28 @@ void fetch_message_action (struct message_action *M) { ...@@ -234,6 +236,28 @@ void fetch_message_action (struct message_action *M) {
} }
} }
void fetch_message_short (struct message *M) {
memset (M, 0, sizeof (*M));
M->id = fetch_int ();
M->from_id = fetch_int ();
M->message = fetch_str_dup ();
fetch_int (); // pts
M->date = fetch_int ();
fetch_int (); // seq
}
void fetch_message_short_chat (struct message *M) {
memset (M, 0, sizeof (*M));
M->id = fetch_int ();
M->from_id = fetch_int ();
M->to_id = fetch_int ();
M->message = fetch_str_dup ();
fetch_int (); // pts
M->date = fetch_int ();
fetch_int (); // seq
}
void fetch_message_media (struct message_media *M) { void fetch_message_media (struct message_media *M) {
memset (M, 0, sizeof (*M)); memset (M, 0, sizeof (*M));
M->type = fetch_int (); M->type = fetch_int ();
...@@ -442,6 +466,49 @@ struct message *fetch_alloc_message (void) { ...@@ -442,6 +466,49 @@ struct message *fetch_alloc_message (void) {
} }
} }
struct message *fetch_alloc_message_short (void) {
struct message *M = malloc (sizeof (*M));
fetch_message_short (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_chat (void) {
struct message *M = malloc (sizeof (*M));
fetch_message_short_chat (M);
if (verbosity >= 2) {
logprintf ("Read message with id %d\n", M->id);
}
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 chat *fetch_alloc_chat (void) { struct chat *fetch_alloc_chat (void) {
union user_chat *U = malloc (sizeof (*U)); union user_chat *U = malloc (sizeof (*U));
fetch_chat (&U->chat); fetch_chat (&U->chat);
...@@ -475,3 +542,21 @@ int print_stat (char *s, int len) { ...@@ -475,3 +542,21 @@ int print_stat (char *s, int len) {
messages_allocated messages_allocated
); );
} }
union user_chat *user_chat_get (int id) {
union user_chat U;
U.id = id;
return tree_lookup_peer (peer_tree, &U);
}
struct message *message_get (int id) {
struct message M;
M.id = id;
return tree_lookup_message (message_tree, &M);
}
void update_message_id (struct message *M, int id) {
message_tree = tree_delete_message (message_tree, M);
M->id = id;
message_tree = tree_insert_message (message_tree, M, lrand48 ());
}
...@@ -142,12 +142,19 @@ struct message { ...@@ -142,12 +142,19 @@ struct message {
}; };
void fetch_file_location (struct file_location *loc); void fetch_file_location (struct file_location *loc);
void fetch_user_status (struct user_status *S);
void fetch_user (struct user *U); void fetch_user (struct user *U);
struct user *fetch_alloc_user (void); struct user *fetch_alloc_user (void);
struct chat *fetch_alloc_chat (void); struct chat *fetch_alloc_chat (void);
struct message *fetch_alloc_message (void);
struct message *fetch_alloc_message_short (void);
struct message *fetch_alloc_message_short_chat (void);
void free_user (struct user *U); void free_user (struct user *U);
void free_chat (struct chat *U); void free_chat (struct chat *U);
int print_stat (char *s, int len); int print_stat (char *s, int len);
union user_chat *user_chat_get (int id);
struct message *message_get (int id);
void update_message_id (struct message *M, int id);
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment