Commit a8a18a80 authored by Vysheng's avatar Vysheng

Sometimes updates work

parent baa56b70
......@@ -198,6 +198,18 @@ void interpreter (char *line UU) {
static char stat_buf[1 << 15];
print_stat (stat_buf, (1 << 15) - 1);
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, ...) {
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 @@
#define COLOR_NORMAL "\033[0m"
#define COLOR_GREEN "\033[32;1m"
#define COLOR_GREY "\033[37;1m"
#define COLOR_YELLOW "\033[33;1m"
char *get_default_prompt (void);
......@@ -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 logprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2)));
void hexdump (int *in_ptr, int *in_end);
struct message;
void print_message (struct message *M);
#endif
......@@ -23,6 +23,7 @@
#include "queries.h"
#include "loop.h"
#include "interface.h"
#include "structures.h"
#define sha1 SHA1
......@@ -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 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) {
if (verbosity) {
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) {
}
void rpc_execute_answer (struct connection *c, long long msg_id UU) {
if (verbosity >= 5) {
hexdump_in ();
}
int op = prefetch_int ();
switch (op) {
case CODE_msg_container:
......@@ -685,6 +864,18 @@ void rpc_execute_answer (struct connection *c, long long msg_id UU) {
case CODE_rpc_result:
work_rpc_result (c, msg_id);
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");
hexdump_in ();
......
......@@ -255,8 +255,12 @@ static inline int prefetch_strlen (void) {
}
}
extern int verbosity;
static inline char *fetch_str (int len) {
assert (len >= 0);
if (verbosity > 6) {
logprintf ("fetch_string: len = %d\n", len);
}
if (len < 254) {
char *str = (char *) in_ptr + 1;
in_ptr += 1 + (len >> 2);
......@@ -289,6 +293,9 @@ static inline long have_prefetch_ints (void) {
int fetch_bignum (BIGNUM *x);
static inline int fetch_int (void) {
if (verbosity > 6) {
logprintf ("fetch_int: 0x%08x (%d)\n", *in_ptr, *in_ptr);
}
return *(in_ptr ++);
}
......
......@@ -391,6 +391,7 @@ void connections_poll_result (struct pollfd *fds, int max) {
int send_all_acks (struct session *S) {
clear_packet ();
out_int (CODE_msgs_ack);
out_int (tree_count_int (S->ack_tree));
while (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
logprintf ( "Sending query of size %d to DC (%s:%d)\n", 4 * ints, DC->ip, DC->port);
}
struct query *q = malloc (sizeof (*q));
memset (q, 0, sizeof (*q));
q->data_len = ints;
q->data = malloc (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
void query_ack (long long 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) {
......@@ -85,7 +89,9 @@ void query_error (long long id) {
logprintf ( "No such query\n");
}
} 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);
if (q->methods && q->methods->on_error) {
q->methods->on_error (q, error_code, error_len, error);
......@@ -143,7 +149,9 @@ void query_result (long long id UU) {
logprintf ( "No such query\n");
}
} 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);
if (q->methods && q->methods->on_answer) {
q->methods->on_answer (q);
......@@ -191,6 +199,10 @@ void work_timers (void) {
assert (ev);
if (ev->timeout > t) { break; }
remove_event_timer (ev);
assert (ev->alarm);
if (verbosity) {
logprintf ("Alarm\n");
}
ev->alarm (ev->self);
}
}
......@@ -405,3 +417,48 @@ void do_update_contact_list (void) {
out_string ("");
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);
double get_double_time (void);
void do_update_contact_list (void);
union user_chat;
void do_send_message (union user_chat *U, const char *msg);
#endif
......@@ -4,6 +4,8 @@
#include "telegram.h"
#include "tree.h"
int verbosity;
void fetch_file_location (struct file_location *loc) {
int x = fetch_int ();
if (x == CODE_file_location_unavailable) {
......@@ -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) {
memset (M, 0, sizeof (*M));
M->type = fetch_int ();
......@@ -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) {
union user_chat *U = malloc (sizeof (*U));
fetch_chat (&U->chat);
......@@ -475,3 +542,21 @@ int print_stat (char *s, int len) {
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 {
};
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 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_chat (struct chat *U);
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
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