Many bug fixes. Added dialog_list query
This commit is contained in:
parent
a8a18a8076
commit
e40ae9590d
84
interface.c
84
interface.c
@ -13,6 +13,8 @@
|
||||
#include "interface.h"
|
||||
#include "telegram.h"
|
||||
#include "structures.h"
|
||||
|
||||
#include "mtproto-common.h"
|
||||
char *default_prompt = ">";
|
||||
|
||||
char *get_default_prompt (void) {
|
||||
@ -28,6 +30,8 @@ char *commands[] = {
|
||||
"msg",
|
||||
"contact_list",
|
||||
"stats",
|
||||
"history",
|
||||
"dialog_list",
|
||||
0 };
|
||||
|
||||
int commands_flags[] = {
|
||||
@ -35,6 +39,8 @@ int commands_flags[] = {
|
||||
072,
|
||||
07,
|
||||
07,
|
||||
072,
|
||||
07,
|
||||
};
|
||||
|
||||
char *a = 0;
|
||||
@ -194,6 +200,8 @@ void interpreter (char *line UU) {
|
||||
}
|
||||
if (!memcmp (line, "contact_list", 12)) {
|
||||
do_update_contact_list ();
|
||||
} else if (!memcmp (line, "dialog_list", 11)) {
|
||||
do_get_dialog_list ();
|
||||
} else if (!memcmp (line, "stats", 5)) {
|
||||
static char stat_buf[1 << 15];
|
||||
print_stat (stat_buf, (1 << 15) - 1);
|
||||
@ -203,13 +211,32 @@ void interpreter (char *line UU) {
|
||||
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)) {
|
||||
while (index < user_num + chat_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len))) {
|
||||
index ++;
|
||||
}
|
||||
while (*q && (*q == ' ' || *q == '\t')) { q ++; }
|
||||
if (*q && index < user_num + chat_num) {
|
||||
do_send_message (Peers[index], q);
|
||||
}
|
||||
} else if (!memcmp (line, "history", 7)) {
|
||||
char *q = line + 7;
|
||||
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 ++;
|
||||
}
|
||||
if (index < user_num + chat_num) {
|
||||
char *text = get_token (&q, &len);
|
||||
int limit = 40;
|
||||
if (text) {
|
||||
limit = atoi (text);
|
||||
if (limit <= 0 || limit >= 1000000) {
|
||||
limit = 40;
|
||||
}
|
||||
}
|
||||
do_get_history (Peers[index], limit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -289,13 +316,58 @@ void logprintf (const char *format, ...) {
|
||||
}
|
||||
}
|
||||
|
||||
const char *message_media_type_str (struct message_media *M) {
|
||||
static char buf[1000];
|
||||
switch (M->type) {
|
||||
case CODE_message_media_empty:
|
||||
return "";
|
||||
case CODE_message_media_photo:
|
||||
return "[photo]";
|
||||
case CODE_message_media_video:
|
||||
return "[video]";
|
||||
case CODE_message_media_geo:
|
||||
sprintf (buf, "[geo] %.6lf:%.6lf", M->geo.latitude, M->geo.longitude);
|
||||
return buf;
|
||||
case CODE_message_media_contact:
|
||||
snprintf (buf, 999, "[contact] " COLOR_RED "%s %s" COLOR_NORMAL " %s", M->first_name, M->last_name, M->phone);
|
||||
return buf;
|
||||
case CODE_message_media_unsupported:
|
||||
return "[unsupported]";
|
||||
default:
|
||||
assert (0);
|
||||
return "";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if (M->service) {
|
||||
rprintf ("Service message\n");
|
||||
return;
|
||||
}
|
||||
if (M->to_id >= 0) {
|
||||
if (M->out) {
|
||||
union user_chat *U = user_chat_get (M->to_id);
|
||||
assert (M->from_id >= 0);
|
||||
if (U) {
|
||||
rprintf (COLOR_RED "%s %s" COLOR_GREEN " <<< %s %s" COLOR_NORMAL "\n", U->user.first_name, U->user.last_name, M->message, message_media_type_str (&M->media));
|
||||
} else {
|
||||
rprintf (COLOR_RED "User #%d " COLOR_GREEN " >>> " COLOR_NORMAL " %s\n", M->from_id, M->message);
|
||||
rprintf (COLOR_RED "User #%d" COLOR_GREEN " <<< %s %s" COLOR_NORMAL "\n", M->from_id, M->message, message_media_type_str (&M->media));
|
||||
}
|
||||
} else {
|
||||
union user_chat *U = user_chat_get (M->from_id);
|
||||
assert (M->from_id >= 0);
|
||||
if (U) {
|
||||
rprintf (COLOR_RED "%s %s" COLOR_BLUE " >>> %s %s" COLOR_NORMAL "\n", U->user.first_name, U->user.last_name, M->message, message_media_type_str (&M->media));
|
||||
} else {
|
||||
rprintf (COLOR_RED "User #%d" COLOR_BLUE " >>> %s %s" COLOR_NORMAL "\n", M->from_id, M->message, message_media_type_str (&M->media));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rprintf ("Message to chat %d\n", -M->to_id);
|
||||
union user_chat *C = user_chat_get (M->to_id);
|
||||
if (C) {
|
||||
rprintf ("Chat %s\n", C->chat.title);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define COLOR_GREEN "\033[32;1m"
|
||||
#define COLOR_GREY "\033[37;1m"
|
||||
#define COLOR_YELLOW "\033[33;1m"
|
||||
#define COLOR_BLUE "\033[34;1m"
|
||||
|
||||
|
||||
char *get_default_prompt (void);
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <poll.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "net.h"
|
||||
#include "include.h"
|
||||
@ -619,6 +620,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
|
||||
case CODE_update_new_message:
|
||||
{
|
||||
struct message *M = fetch_alloc_message ();
|
||||
fetch_int (); //pts
|
||||
print_message (M);
|
||||
break;
|
||||
};
|
||||
@ -846,6 +848,45 @@ void work_rpc_result (struct connection *c UU, long long msg_id UU) {
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_PACKED_SIZE (1 << 20)
|
||||
void work_packed (struct connection *c, long long msg_id) {
|
||||
assert (fetch_int () == CODE_gzip_packed);
|
||||
static int in_gzip;
|
||||
static int buf[MAX_PACKED_SIZE >> 2];
|
||||
assert (!in_gzip);
|
||||
in_gzip = 1;
|
||||
|
||||
int l = prefetch_strlen ();
|
||||
char *s = fetch_str (l);
|
||||
size_t dl = MAX_PACKED_SIZE;
|
||||
|
||||
z_stream strm = {0};
|
||||
assert (inflateInit2 (&strm, 16 + MAX_WBITS) == Z_OK);
|
||||
strm.avail_in = l;
|
||||
strm.next_in = (void *)s;
|
||||
strm.avail_out = MAX_PACKED_SIZE;
|
||||
strm.next_out = (void *)buf;
|
||||
|
||||
int err = inflate (&strm, Z_FINISH);
|
||||
if (verbosity) {
|
||||
logprintf ( "inflate error = %d\n", err);
|
||||
logprintf ( "inflated %d bytes\n", (int)strm.total_out);
|
||||
}
|
||||
int *end = in_ptr;
|
||||
int *eend = in_end;
|
||||
assert (dl % 4 == 0);
|
||||
in_ptr = buf;
|
||||
in_end = in_ptr + strm.total_out / 4;
|
||||
if (verbosity >= 4) {
|
||||
logprintf ( "Unzipped data: ");
|
||||
hexdump_in ();
|
||||
}
|
||||
rpc_execute_answer (c, msg_id);
|
||||
in_ptr = end;
|
||||
in_end = eend;
|
||||
in_gzip = 0;
|
||||
}
|
||||
|
||||
void rpc_execute_answer (struct connection *c, long long msg_id UU) {
|
||||
if (verbosity >= 5) {
|
||||
hexdump_in ();
|
||||
@ -876,6 +917,9 @@ void rpc_execute_answer (struct connection *c, long long msg_id UU) {
|
||||
case CODE_update_short_chat_message:
|
||||
work_update_short_chat_message (c, msg_id);
|
||||
return;
|
||||
case CODE_gzip_packed:
|
||||
work_packed (c, msg_id);
|
||||
return;
|
||||
}
|
||||
logprintf ( "Unknown message: \n");
|
||||
hexdump_in ();
|
||||
|
@ -299,6 +299,14 @@ static inline int fetch_int (void) {
|
||||
return *(in_ptr ++);
|
||||
}
|
||||
|
||||
static inline int fetch_bool (void) {
|
||||
if (verbosity > 6) {
|
||||
logprintf ("fetch_bool: 0x%08x (%d)\n", *in_ptr, *in_ptr);
|
||||
}
|
||||
assert (*(in_ptr) == (int)CODE_bool_true || *(in_ptr) == (int)CODE_bool_false);
|
||||
return *(in_ptr ++) == (int)CODE_bool_true;
|
||||
}
|
||||
|
||||
static inline int prefetch_int (void) {
|
||||
return *(in_ptr);
|
||||
}
|
||||
|
109
queries.c
109
queries.c
@ -33,6 +33,8 @@ struct query *query_get (long long id) {
|
||||
|
||||
int alarm_query (struct query *q) {
|
||||
assert (q);
|
||||
q->ev.timeout = get_double_time () + QUERY_TIMEOUT;
|
||||
insert_event_timer (&q->ev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -69,7 +71,7 @@ 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) {
|
||||
if (q && !(q->flags & QUERY_ACK_RECEIVED)) {
|
||||
remove_event_timer (&q->ev);
|
||||
q->flags |= QUERY_ACK_RECEIVED;
|
||||
}
|
||||
@ -462,3 +464,108 @@ void do_send_message (union user_chat *U, const char *msg) {
|
||||
rprintf (COLOR_RED "%s %s" COLOR_GREEN " <<< " COLOR_NORMAL "%s\n", U->user.first_name, U->user.last_name, msg);
|
||||
}
|
||||
}
|
||||
|
||||
int get_history_on_answer (struct query *q UU) {
|
||||
static struct message *ML[10000];
|
||||
int i;
|
||||
int x = fetch_int ();
|
||||
if (x == (int)CODE_messages_messages_slice) {
|
||||
fetch_int ();
|
||||
rprintf ("...\n");
|
||||
} else {
|
||||
assert (x == (int)CODE_messages_messages);
|
||||
}
|
||||
assert (fetch_int () == CODE_vector);
|
||||
int n = fetch_int ();
|
||||
for (i = 0; i < n; i++) {
|
||||
struct message *M = fetch_alloc_message ();
|
||||
if (i <= 9999) {
|
||||
ML[i] = M;
|
||||
}
|
||||
}
|
||||
if (n > 10000) { n = 10000; }
|
||||
for (i = n - 1; i >= 0; i--) {
|
||||
print_message (ML[i]);
|
||||
}
|
||||
assert (fetch_int () == CODE_vector);
|
||||
n = fetch_int ();
|
||||
for (i = 0; i < n; i++) {
|
||||
fetch_alloc_chat ();
|
||||
}
|
||||
assert (fetch_int () == CODE_vector);
|
||||
n = fetch_int ();
|
||||
for (i = 0; i < n; i++) {
|
||||
fetch_alloc_user ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct query_methods get_history_methods = {
|
||||
.on_answer = get_history_on_answer,
|
||||
};
|
||||
|
||||
|
||||
void do_get_history (union user_chat *U, int limit) {
|
||||
clear_packet ();
|
||||
out_int (CODE_messages_get_history);
|
||||
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_int (0);
|
||||
out_int (0);
|
||||
out_int (limit);
|
||||
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_history_methods);
|
||||
}
|
||||
|
||||
int get_dialogs_on_answer (struct query *q UU) {
|
||||
assert (fetch_int () == CODE_messages_dialogs);
|
||||
assert (fetch_int () == CODE_vector);
|
||||
int n, i;
|
||||
n = fetch_int ();
|
||||
for (i = 0; i < n; i++) {
|
||||
assert (fetch_int () == CODE_dialog);
|
||||
fetch_peer_id ();
|
||||
fetch_int ();
|
||||
fetch_int ();
|
||||
}
|
||||
assert (fetch_int () == CODE_vector);
|
||||
n = fetch_int ();
|
||||
for (i = 0; i < n; i++) {
|
||||
fetch_alloc_message ();
|
||||
}
|
||||
assert (fetch_int () == CODE_vector);
|
||||
n = fetch_int ();
|
||||
for (i = 0; i < n; i++) {
|
||||
fetch_alloc_chat ();
|
||||
}
|
||||
assert (fetch_int () == CODE_vector);
|
||||
n = fetch_int ();
|
||||
for (i = 0; i < n; i++) {
|
||||
fetch_alloc_user ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct query_methods get_dialogs_methods = {
|
||||
.on_answer = get_dialogs_on_answer,
|
||||
};
|
||||
|
||||
|
||||
void do_get_dialog_list (void) {
|
||||
clear_packet ();
|
||||
out_int (CODE_messages_get_dialogs);
|
||||
out_int (0);
|
||||
out_int (0);
|
||||
out_int (1000);
|
||||
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_dialogs_methods);
|
||||
}
|
||||
|
@ -46,4 +46,6 @@ 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);
|
||||
void do_get_history (union user_chat *U, int limit);
|
||||
void do_get_dialog_list (void);
|
||||
#endif
|
||||
|
40
structures.c
40
structures.c
@ -148,6 +148,7 @@ void fetch_chat (struct chat *C) {
|
||||
}
|
||||
|
||||
void fetch_photo_size (struct photo_size *S) {
|
||||
memset (S, 0, sizeof (*S));
|
||||
unsigned x = fetch_int ();
|
||||
assert (x == CODE_photo_size || x == CODE_photo_cached_size);
|
||||
S->type = fetch_str_dup ();
|
||||
@ -162,9 +163,15 @@ void fetch_photo_size (struct photo_size *S) {
|
||||
}
|
||||
|
||||
void fetch_geo (struct geo *G) {
|
||||
assert (fetch_int () == CODE_geo_point);
|
||||
unsigned x = fetch_int ();
|
||||
if (x == CODE_geo_point) {
|
||||
G->longitude = fetch_double ();
|
||||
G->latitude = fetch_double ();
|
||||
} else {
|
||||
assert (x == CODE_geo_point_empty);
|
||||
G->longitude = 0;
|
||||
G->latitude = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void fetch_photo (struct photo *P) {
|
||||
@ -244,17 +251,19 @@ void fetch_message_short (struct message *M) {
|
||||
fetch_int (); // pts
|
||||
M->date = fetch_int ();
|
||||
fetch_int (); // seq
|
||||
M->media.type = CODE_message_media_empty;
|
||||
}
|
||||
|
||||
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->to_id = -fetch_int ();
|
||||
M->message = fetch_str_dup ();
|
||||
fetch_int (); // pts
|
||||
M->date = fetch_int ();
|
||||
fetch_int (); // seq
|
||||
M->media.type = CODE_message_media_empty;
|
||||
}
|
||||
|
||||
|
||||
@ -283,10 +292,21 @@ void fetch_message_media (struct message_media *M) {
|
||||
M->data = fetch_str_dup ();
|
||||
break;
|
||||
default:
|
||||
logprintf ("type = 0x%08x\n", M->type);
|
||||
assert (0);
|
||||
}
|
||||
}
|
||||
|
||||
int fetch_peer_id (void) {
|
||||
unsigned x =fetch_int ();
|
||||
if (x == CODE_peer_user) {
|
||||
return fetch_int ();
|
||||
} else {
|
||||
assert (CODE_peer_chat);
|
||||
return -fetch_int ();
|
||||
}
|
||||
}
|
||||
|
||||
void fetch_message (struct message *M) {
|
||||
memset (M, 0, sizeof (*M));
|
||||
unsigned x = fetch_int ();
|
||||
@ -301,9 +321,9 @@ void fetch_message (struct message *M) {
|
||||
M->fwd_date = fetch_int ();
|
||||
}
|
||||
M->from_id = fetch_int ();
|
||||
M->to_id = fetch_int ();
|
||||
M->out = (fetch_int () == (int)CODE_bool_true);
|
||||
M->unread = (fetch_int () == (int)CODE_bool_true);
|
||||
M->to_id = fetch_peer_id ();
|
||||
M->out = fetch_bool ();
|
||||
M->unread = fetch_bool ();
|
||||
M->date = fetch_int ();
|
||||
if (x == CODE_message_service) {
|
||||
M->service = 1;
|
||||
@ -360,21 +380,27 @@ void free_user (struct user *U) {
|
||||
|
||||
void free_photo_size (struct photo_size *S) {
|
||||
free (S->type);
|
||||
if (S->data) {
|
||||
free (S->data);
|
||||
}
|
||||
}
|
||||
|
||||
void free_photo (struct photo *P) {
|
||||
free (P->caption);
|
||||
if (!P->access_hash) { return; }
|
||||
if (P->caption) { free (P->caption); }
|
||||
if (P->sizes) {
|
||||
int i;
|
||||
for (i = 0; i < P->sizes_num; i++) {
|
||||
free_photo_size (&P->sizes[i]);
|
||||
}
|
||||
free (P->sizes);
|
||||
}
|
||||
}
|
||||
|
||||
void free_video (struct video *V) {
|
||||
if (!V->access_hash) { return; }
|
||||
free (V->caption);
|
||||
free (&V->thumb);
|
||||
free_photo_size (&V->thumb);
|
||||
}
|
||||
|
||||
void free_message_media (struct message_media *M) {
|
||||
|
@ -149,6 +149,7 @@ 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);
|
||||
int fetch_peer_id (void);
|
||||
|
||||
void free_user (struct user *U);
|
||||
void free_chat (struct chat *U);
|
||||
|
Loading…
Reference in New Issue
Block a user