Added dump-tl binary. Updated to 17 layer

This commit is contained in:
vvaltman 2014-09-29 16:11:48 +04:00
parent b9878e5c1a
commit 11bf4177cc
17 changed files with 1291 additions and 33 deletions

View File

@ -23,10 +23,11 @@ LIB_LIST=${LIB}/libtgl.a
TG_OBJECTS=${OBJ}/main.o ${OBJ}/loop.o ${OBJ}/interface.o ${OBJ}/lua-tg.o
TGL_OBJECTS=${OBJ}/net.o ${OBJ}/mtproto-common.o ${OBJ}/mtproto-client.o ${OBJ}/queries.o ${OBJ}/structures.o ${OBJ}/binlog.o ${OBJ}/auto/auto.o ${OBJ}/tgl.o ${OBJ}/updates.o
TLC_OBJECTS=${OBJ}/tlc.o ${OBJ}/tl-parser.o ${OBJ}/crc32.o
TLD_OBJECTS=${OBJ}/dump-tl-file.o
GENERATE_OBJECTS=${OBJ}/generate.o
COMMON_OBJECTS=${OBJ}/tools.o
OBJ_LIST=${TG_OBJECTS} ${TLC_OBJECTS} ${GENERATE_OBJECTS} ${COMMON_OBJECTS} ${TGL_OBJECTS}
OBJ_C=${TLC_OBJECTS} ${GENERATE_OBJECTS} ${COMMON_OBJECTS} ${TGL_OBJECTS}
OBJ_LIST=${TG_OBJECTS} ${TLC_OBJECTS} ${GENERATE_OBJECTS} ${COMMON_OBJECTS} ${TGL_OBJECTS} ${TLD_OBJECTS}
OBJ_C=${TLC_OBJECTS} ${GENERATE_OBJECTS} ${COMMON_OBJECTS} ${TGL_OBJECTS} ${TLD_OBJECTS}
DEPENDENCE=$(subst ${OBJ}/,${DEP}/,$(patsubst %.o,%.d,${OBJ_LIST}))
DEPENDENCE_LIST=${DEPENDENCE}
@ -41,6 +42,7 @@ CC=@CC@
all: ${EXE_LIST} ${DIR_LIST} ${LIB_LIST}
create_dirs_and_headers: ${DIR_LIST} ${AUTO}/auto.c ${AUTO}/auto-header.h ${AUTO}/constants.h
create_dirs: ${DIR_LIST}
dump-tl: ${EXE}/dump-tl-file
${DIR_LIST}:
@test -d $@ || mkdir -p $@
@ -85,6 +87,9 @@ ${AUTO}/auto-header.h: ${AUTO}/scheme.tlo ${EXE}/generate
${AUTO}/constants.h: ${AUTO}/scheme2.tl ${srcdir}/gen_constants_h.awk
awk -f ${srcdir}/gen_constants_h.awk < $< > $@
${EXE}/dump-tl-file: ${OBJ}/auto/auto.o ${TLD_OBJECTS}
${CC} ${OBJ}/auto/auto.o ${TLD_OBJECTS} ${LINK_FLAGS} -o $@
clean:
rm -rf ${DIR_LIST} config.log config.status > /dev/null || echo "all clean"

461
auto-static-print.c Normal file
View File

@ -0,0 +1,461 @@
/*
This file is part of tgl-library
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Vitaly Valtman 2014
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
static int cur_token_len;
static char *cur_token;
static int cur_token_real_len;
static int cur_token_quoted;
static int multiline_output = 1;
static int multiline_offset;
static int multiline_offset_size = 2;
static int *in_ptr, *in_end;
static inline int fetch_int (void) {
return *(in_ptr ++);
}
static inline int fetch_long (void) {
long long r = *(long long *)in_ptr;
in_ptr += 2;
return r;
}
static inline int fetch_long (void) {
long long r = *(long long *)in_ptr;
in_ptr += 2;
return r;
}
static inline void out_int (int a) {}
static inline void out_double (double a) {}
static inline void out_string (char *s, int l) {}
static inline void out_long (long long a) {}
static int disable_field_names;
#define expect_token(token,len) \
if (len != cur_token_len || memcmp (cur_token, token, cur_token_len)) { return -1; } \
local_next_token ();
#define expect_token_ptr(token,len) \
if (len != cur_token_len || memcmp (cur_token, token, cur_token_len)) { return 0; } \
local_next_token ();
#define expect_token_autocomplete(token,len) \
if (cur_token_len == -3 && len >= cur_token_real_len && !memcmp (cur_token, token, cur_token_real_len)) { set_autocomplete_string (token); return -1; }\
if (len != cur_token_len || memcmp (cur_token, token, cur_token_len)) { return -1; } \
local_next_token ();
#define expect_token_ptr_autocomplete(token,len) \
if (cur_token_len == -3 && len >= cur_token_real_len && !memcmp (cur_token, token, cur_token_real_len)) { set_autocomplete_string (token); return 0; }\
if (len != cur_token_len || memcmp (cur_token, token, cur_token_len)) { return 0; } \
local_next_token ();
static int autocomplete_mode;
static char *autocomplete_string;
static int (*autocomplete_fun)(const char *, int, int, char **);
static void set_autocomplete_string (const char *s) {
if (autocomplete_string) { free (autocomplete_string); }
autocomplete_string = strdup (s);
assert (autocomplete_string);
autocomplete_mode = 1;
}
static void set_autocomplete_type (int (*f)(const char *, int, int, char **)) {
autocomplete_fun = f;
autocomplete_mode = 2;
}
static int is_int (void) {
if (cur_token_len <= 0) { return 0; }
char c = cur_token[cur_token_len];
cur_token[cur_token_len] = 0;
char *p = 0;
if (strtoll (cur_token, &p, 10)) {}
cur_token[cur_token_len] = c;
return p == cur_token + cur_token_len;
}
static long long get_int (void) {
if (cur_token_len <= 0) { return 0; }
char c = cur_token[cur_token_len];
cur_token[cur_token_len] = 0;
char *p = 0;
long long val = strtoll (cur_token, &p, 0);
cur_token[cur_token_len] = c;
return val;
}
static int is_double (void) {
if (cur_token_len <= 0) { return 0; }
char c = cur_token[cur_token_len];
cur_token[cur_token_len] = 0;
char *p = 0;
if (strtod (cur_token, &p)) {}
cur_token[cur_token_len] = c;
return p == cur_token + cur_token_len;
}
static double get_double (void) {
if (cur_token_len <= 0) { return 0; }
char c = cur_token[cur_token_len];
cur_token[cur_token_len] = 0;
char *p = 0;
double val = strtod (cur_token, &p);
cur_token[cur_token_len] = c;
return val;
}
static struct paramed_type *paramed_type_dup (struct paramed_type *P) {
if (ODDP (P)) { return P; }
struct paramed_type *R = malloc (sizeof (*R));
assert (R);
R->type = malloc (sizeof (*R->type));
assert (R->type);
memcpy (R->type, P->type, sizeof (*P->type));
R->type->id = strdup (P->type->id);
assert (R->type->id);
if (P->type->params_num) {
R->params = malloc (sizeof (void *) * P->type->params_num);
assert (R->params);
int i;
for (i = 0; i < P->type->params_num; i++) {
R->params[i] = paramed_type_dup (P->params[i]);
}
}
return R;
}
void tgl_paramed_type_free (struct paramed_type *P) {
if (ODDP (P)) { return; }
if (P->type->params_num) {
int i;
for (i = 0; i < P->type->params_num; i++) {
tgl_paramed_type_free (P->params[i]);
}
free (P->params);
}
free (P->type->id);
free (P->type);
free (P);
}
static char *buffer_pos, *buffer_end;
static int is_wspc (char c) {
return c <= 32 && c > 0;
}
static void skip_wspc (void) {
while (buffer_pos < buffer_end && is_wspc (*buffer_pos)) {
buffer_pos ++;
}
}
static int is_letter (char c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '.' || c == '_' || c == '-';
}
static char exp_buffer[1 << 25];;
static int exp_buffer_pos;
static inline int is_hex (char c) {
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
}
static inline int hex2dec (char c) {
if (c >= '0' && c <= '9') { return c - '0'; }
else { return c - 'a' + 10; }
}
static void expand_backslashed (char *s, int len) {
int backslashed = 0;
exp_buffer_pos = 0;
int i = 0;
while (i < len) {
assert (i + 3 <= (1 << 25));
if (backslashed) {
backslashed = 0;
switch (s[i ++]) {
case 'n':
exp_buffer[exp_buffer_pos ++] = '\n';
break;
case 'r':
exp_buffer[exp_buffer_pos ++] = '\r';
break;
case 't':
exp_buffer[exp_buffer_pos ++] = '\t';
break;
case 'b':
exp_buffer[exp_buffer_pos ++] = '\b';
break;
case 'a':
exp_buffer[exp_buffer_pos ++] = '\a';
break;
case '\\':
exp_buffer[exp_buffer_pos ++] = '\\';
break;
case 'x':
if (i + 2 > len || !is_hex (s[i]) || !is_hex (s[i + 1])) {
exp_buffer_pos = -1;
return;
}
exp_buffer[exp_buffer_pos ++] = hex2dec (s[i]) * 16 + hex2dec (s[i + 1]);
i += 2;
break;
default:
break;
}
} else {
if (s[i] == '\\') {
backslashed = 1;
i ++;
} else {
exp_buffer[exp_buffer_pos ++] = s[i ++];
}
}
}
}
static void local_next_token (void) {
skip_wspc ();
cur_token_quoted = 0;
if (buffer_pos >= buffer_end) {
cur_token_len = -3;
cur_token_real_len = 0;
return;
}
char c = *buffer_pos;
if (is_letter (c)) {
cur_token = buffer_pos;
while (buffer_pos < buffer_end && is_letter (*buffer_pos)) {
buffer_pos ++;
}
if (buffer_pos < buffer_end) {
cur_token_len = buffer_pos - cur_token;
} else {
cur_token_real_len = buffer_pos - cur_token;
cur_token_len = -3;
}
return;
} else if (c == '"') {
cur_token_quoted = 1;
cur_token = buffer_pos ++;
int backslashed = 0;
while (buffer_pos < buffer_end && (*buffer_pos != '"' || backslashed)) {
if (*buffer_pos == '\\') {
backslashed ^= 1;
} else {
backslashed = 0;
}
buffer_pos ++;
}
if (*buffer_pos == '"') {
buffer_pos ++;
expand_backslashed (cur_token + 1, buffer_pos - cur_token - 2);
if (exp_buffer_pos < 0) {
cur_token_len = -2;
} else {
cur_token_len = exp_buffer_pos;
cur_token = exp_buffer;
}
} else {
cur_token_len = -2;
}
return;
} else {
if (c) {
cur_token = buffer_pos ++;
cur_token_len = 1;
} else {
cur_token_len = -3;
cur_token_real_len = 0;
}
}
}
#define MAX_FVARS 100
static struct paramed_type *fvars[MAX_FVARS];
static int fvars_pos;
static void add_var_to_be_freed (struct paramed_type *P) {
assert (fvars_pos < MAX_FVARS);
fvars[fvars_pos ++] = P;
}
static void free_vars_to_be_freed (void) {
int i;
for (i = 0; i < fvars_pos; i++) {
tgl_paramed_type_free (fvars[i]);
}
fvars_pos = 0;
}
int tglf_extf_autocomplete (const char *text, int text_len, int index, char **R, char *data, int data_len) {
if (index == -1) {
buffer_pos = data;
buffer_end = data + data_len;
autocomplete_mode = 0;
local_next_token ();
struct paramed_type *P = autocomplete_function_any ();
free_vars_to_be_freed ();
if (P) { tgl_paramed_type_free (P); }
}
if (autocomplete_mode == 0) { return -1; }
int len = strlen (text);
if (autocomplete_mode == 1) {
if (index >= 0) { return -1; }
index = 0;
if (!strncmp (text, autocomplete_string, len)) {
*R = strdup (autocomplete_string);
assert (*R);
return index;
} else {
return -1;
}
} else {
return autocomplete_fun (text, len, index, R);
}
}
struct paramed_type *tglf_extf_store (const char *data, int data_len) {
buffer_pos = (char *)data;
buffer_end = (char *)(data + data_len);
local_next_token ();
return store_function_any ();
}
#define OUT_BUF_SIZE (1 << 25)
static char out_buf[OUT_BUF_SIZE];
static int out_buf_pos;
#define eprintf(...) \
do { \
out_buf_pos += snprintf (out_buf + out_buf_pos, OUT_BUF_SIZE - out_buf_pos, __VA_ARGS__);\
assert (out_buf_pos < OUT_BUF_SIZE);\
} while (0)\
static int valid_utf8_char (const char *str) {
unsigned char c = (unsigned char) *str;
int n = 0;
if ((c & 0x80) == 0x00) {
n = 0;
} else if ((c & 0xe0) == 0xc0) {
n = 1;
} else if ((c & 0xf0) == 0xe0) {
n = 2;
} else if ((c & 0xf8) == 0xf0) {
n = 3;
} else if ((c & 0xfc) == 0xf8) {
n = 4;
} else if ((c & 0xfe) == 0xfc) {
n = 5;
} else {
return -1;
}
int i;
for (i = 0; i < n; i ++) {
if ((((unsigned char)(str[i + 1])) & 0xc0) != 0x80) {
return -1;
}
}
return n + 1;
}
static void print_escaped_string (const char *str, int len) {
eprintf ("\"");
const char *end = str + len;
while (str < end) {
int n = valid_utf8_char (str);
if (n < 0) {
eprintf ("\\x%02x", (int)(unsigned char)*str);
str ++;
} else if (n >= 2) {
int i;
for (i = 0; i < n; i++) {
eprintf ("%c", *(str ++));
}
} else if (((unsigned char)*str) >= ' ' && *str != '"' && *str != '\\') {
eprintf ("%c", *str);
str ++;
} else {
switch (*str) {
case '\n':
eprintf("\\n");
break;
case '\r':
eprintf("\\r");
break;
case '\t':
eprintf("\\t");
break;
case '\b':
eprintf("\\b");
break;
case '\a':
eprintf("\\a");
break;
case '\\':
eprintf ("\\\\");
break;
case '"':
eprintf ("\\\"");
break;
default:
eprintf ("\\x%02x", (int)(unsigned char)*str);
break;
}
str ++;
}
}
eprintf ("\"");
}
static void print_offset (void) {
int i;
for (i = 0; i < multiline_offset; i++) {
eprintf (" ");
}
}
char *tglf_extf_fetch (struct paramed_type *T) {
out_buf_pos = 0;
fetch_type_any (T);
return out_buf;
}

View File

@ -432,6 +432,6 @@ static void print_offset (void) {
char *tglf_extf_fetch (struct paramed_type *T) {
out_buf_pos = 0;
fetch_type_any (T);
if (fetch_type_any (T) < 0) { return 0; }
return out_buf;
}

View File

@ -782,6 +782,12 @@ static int fetch_comb_binlog_send_message_text (void *extra) {
}
M->to_id = tgl_set_peer_id (t, fetch_int ());
if (t == TGL_PEER_ENCR_CHAT) {
tgl_peer_t *P = tgl_peer_get (M->to_id);
if (P) {
P->encr_chat.out_seq_no ++;
}
}
M->date = fetch_int ();
int l = prefetch_strlen ();
@ -825,6 +831,11 @@ static int fetch_comb_binlog_send_message_action_encr (void *extra) {
M->media.type = tgl_message_media_none;
tglf_fetch_message_action_encrypted (&M->action);
tgl_peer_t *P = tgl_peer_get (M->to_id);
if (P) {
P->encr_chat.out_seq_no ++;
}
M->unread = 1;
M->out = tgl_get_peer_id (M->from_id) == tgl_state.our_id;
M->service = 1;
@ -953,6 +964,11 @@ static int fetch_comb_binlog_create_message_media_encr_pending (void *extra) {
M->to_id = tgl_set_peer_id (t, fetch_int ());
M->date = fetch_int ();
tgl_peer_t *P = tgl_peer_get (M->to_id);
if (P) {
P->encr_chat.out_seq_no ++;
}
int l = prefetch_strlen ();
M->message = talloc (l + 1);
memcpy (M->message, fetch_str (l), l);

73
dump-tl-file.c Normal file
View File

@ -0,0 +1,73 @@
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdarg.h>
#include <fcntl.h>
#include <assert.h>
#include <string.h>
#include "auto.h"
int *tgl_in_ptr, *tgl_in_end;
int tgl_packet_buffer[0];
int *tgl_packet_ptr;
char *tgl_strdup (char *s) {
return strdup (s);
}
void tgl_out_cstring (const char *str, long len) {}
char *tglf_extf_fetch (struct paramed_type *T);
#define LEN (1 << 28)
static int x[LEN / 4];
int main (int argc, char **argv) {
int i;
int dump_binlog = 0;
while ((i = getopt (argc, argv, "b")) != -1) {
switch (i) {
case 'b':
dump_binlog = 1;
break;
default:
printf ("unknown option '%c'\n", (char)i);
exit (1);
}
}
if (!dump_binlog) {
exit (1);
}
if (optind + 1 != argc) {
exit (1);
}
int fd = open (argv[optind], O_RDONLY);
if (fd < 0) {
perror ("open");
exit (1);
}
int r = read (fd, x, LEN);
if (r <= 0) {
perror ("read");
exit (1);
}
if (r == LEN) {
printf ("Too long file\n");
exit (1);
}
assert (!(r & 3));
tgl_in_ptr = x;
tgl_in_end = x + (r / 4);
while (tgl_in_ptr < tgl_in_end) {
if (dump_binlog) {
char *R = tglf_extf_fetch (TYPE_TO_PARAM(binlog_update));
if (!R) {
printf ("Can not fetch\n");
exit (1);
}
printf ("%s\n", R);
}
}
return 0;
}

View File

@ -1 +1 @@
encrypted_scheme16.tl
encrypted_scheme17.tl

30
encrypted_scheme17.tl Normal file
View File

@ -0,0 +1,30 @@
---types---
decryptedMessageLayer#99a438cf layer:int message:DecryptedMessage = DecryptedMessageLayer;
decryptedMessage_l16#1f814f1f random_id:long random_bytes:bytes message:string media:DecryptedMessageMedia = DecryptedMessage;
decryptedMessageService_l16#aa48327d random_id:long random_bytes:bytes action:DecryptedMessageAction = DecryptedMessage;
decryptedMessage#20a6d4e2 in_seq_no:int out_seq_no:int ttl:int random_id:long random_bytes:bytes message:string media:DecryptedMessageMedia = DecryptedMessage;
decryptedMessageService#9bb84a4e in_seq_no:int out_seq_no:int random_id:long random_bytes:bytes action:DecryptedMessageAction = DecryptedMessage;
decryptedMessageMediaEmpty#89f5c4a = DecryptedMessageMedia;
decryptedMessageMediaPhoto#32798a8c thumb:bytes thumb_w:int thumb_h:int w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
//decryptedMessageMediaVideo#4cee6ef3 thumb:bytes thumb_w:int thumb_h:int duration:int w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
decryptedMessageMediaGeoPoint#35480a59 lat:double long:double = DecryptedMessageMedia;
decryptedMessageMediaContact#588a0a97 phone_number:string first_name:string last_name:string user_id:int = DecryptedMessageMedia;
decryptedMessageActionSetMessageTTL#a1733aec ttl_seconds:int = DecryptedMessageAction;
decryptedMessageMediaDocument#b095434b thumb:bytes thumb_w:int thumb_h:int file_name:string mime_type:string size:int key:bytes iv:bytes = DecryptedMessageMedia;
//decryptedMessageMediaAudio#6080758f duration:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
decryptedMessageMediaVideo#524a415d thumb:bytes thumb_w:int thumb_h:int duration:int mime_type:string w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
decryptedMessageMediaAudio#57e0a9cb duration:int mime_type:string size:int key:bytes iv:bytes = DecryptedMessageMedia;
decryptedMessageActionReadMessages#c4f40be random_ids:Vector<long> = DecryptedMessageAction;
decryptedMessageActionDeleteMessages#65614304 random_ids:Vector<long> = DecryptedMessageAction;
decryptedMessageActionScreenshotMessages#8ac1f475 random_ids:Vector<long> = DecryptedMessageAction;
decryptedMessageActionFlushHistory#6719e45c = DecryptedMessageAction;
decryptedMessageActionNotifyLayer#f3048883 layer:int = DecryptedMessageAction;
decryptedMessageActionTyping#ccb27641 action:SendMessageAction = DecryptedMessageAction;
---functions---

View File

@ -1594,26 +1594,68 @@ void mark_read_upd (int num, struct tgl_message *list[]) {
}
}
void type_notification_upd (struct tgl_user *U) {
void print_typing (struct in_ev *ev, enum tgl_typing_status status) {
switch (status) {
case tgl_typing_none:
mprintf (ev, "doing nothing");
break;
case tgl_typing_typing:
mprintf (ev, "typing");
break;
case tgl_typing_cancel:
mprintf (ev, "deleting typed message");
break;
case tgl_typing_record_video:
mprintf (ev, "recording video");
break;
case tgl_typing_upload_video:
mprintf (ev, "uploading video");
break;
case tgl_typing_record_audio:
mprintf (ev, "recording audio");
break;
case tgl_typing_upload_audio:
mprintf (ev, "uploading audio");
break;
case tgl_typing_upload_photo:
mprintf (ev, "uploading photo");
break;
case tgl_typing_upload_document:
mprintf (ev, "uploading document");
break;
case tgl_typing_geo:
mprintf (ev, "choosing location");
break;
case tgl_typing_choose_contact:
mprintf (ev, "choosing contact");
break;
}
}
void type_notification_upd (struct tgl_user *U, enum tgl_typing_status status) {
if (log_level < 2 || (disable_output && !notify_ev)) { return; }
struct in_ev *ev = notify_ev;
mprint_start (ev);
mpush_color (ev, COLOR_YELLOW);
mprintf (ev, "User ");
print_user_name (ev, U->id, (void *)U);
mprintf (ev, " is typing\n");
mprintf (ev, " is ");
print_typing (ev, status);
mprintf (ev, "\n");
mpop_color (ev);
mprint_end (ev);
}
void type_in_chat_notification_upd (struct tgl_user *U, struct tgl_chat *C) {
void type_in_chat_notification_upd (struct tgl_user *U, struct tgl_chat *C, enum tgl_typing_status status) {
if (log_level < 2 || (disable_output && !notify_ev)) { return; }
struct in_ev *ev = notify_ev;
mprint_start (ev);
mpush_color (ev, COLOR_YELLOW);
mprintf (ev, "User ");
print_user_name (ev, U->id, (void *)U);
mprintf (ev, " is typing in chat ");
mprintf (ev, " is ");
print_typing (ev, status);
mprintf (ev, " in chat ");
print_chat_name (ev, C->id, (void *)C);
mprintf (ev, "\n");
mpop_color (ev);
@ -2385,6 +2427,10 @@ void print_service_message (struct in_ev *ev, struct tgl_message *M) {
case tgl_message_action_notify_layer:
mprintf (ev, " updated layer to %d\n", M->action.layer);
break;
case tgl_message_action_typing:
mprintf (ev, " is ");
print_typing (ev, M->action.typing);
break;
default:
assert (0);
}

View File

@ -201,7 +201,6 @@ static inline int prefetch_strlen (void) {
static inline char *fetch_str (int len) {
assert (len >= 0);
vlogprintf (E_DEBUG + 3, "fetch_string: len = %d\n", len);
if (len < 254) {
char *str = (char *) in_ptr + 1;
in_ptr += 1 + (len >> 2);
@ -294,12 +293,10 @@ int tgl_fetch_bignum (BIGNUM *x);
static inline int fetch_int (void) {
assert (in_ptr + 1 <= in_end);
vlogprintf (E_DEBUG + 3, "fetch_int: 0x%08x (%d)\n", *in_ptr, *in_ptr);
return *(in_ptr ++);
}
static inline int fetch_bool (void) {
vlogprintf (E_DEBUG + 3, "fetch_bool: 0x%08x (%d)\n", *in_ptr, *in_ptr);
assert (in_ptr + 1 <= in_end);
assert (*(in_ptr) == (int)CODE_bool_true || *(in_ptr) == (int)CODE_bool_false);
return *(in_ptr ++) == (int)CODE_bool_true;

View File

@ -314,7 +314,7 @@ static void out_random (int n) {
int allow_send_linux_version;
void tgl_do_insert_header (void) {
out_int (CODE_invoke_with_layer16);
out_int (CODE_invoke_with_layer17);
out_int (CODE_init_connection);
out_int (TG_APP_ID);
if (allow_send_linux_version) {
@ -957,7 +957,13 @@ void tgl_do_send_encr_msg_action (struct tgl_message *M, void (*callback)(void *
out_long (P->encr_chat.access_hash);
out_long (M->id);
encr_start ();
if (P->encr_chat.layer <= 16) {
out_int (CODE_decrypted_message_service_l16);
} else {
out_int (CODE_decrypted_message_service);
out_int (2 * P->encr_chat.in_seq_no + (P->encr_chat.admin_id != tgl_state.our_id));
out_int (2 * P->encr_chat.out_seq_no + (P->encr_chat.admin_id == tgl_state.our_id));
}
out_long (M->id);
static int buf[4];
tglt_secure_random (buf, 16);
@ -1001,7 +1007,14 @@ void tgl_do_send_encr_msg (struct tgl_message *M, void (*callback)(void *callbac
out_long (P->encr_chat.access_hash);
out_long (M->id);
encr_start ();
if (P->encr_chat.layer <= 16) {
out_int (CODE_decrypted_message_l16);
} else {
out_int (CODE_decrypted_message);
out_int (2 * P->encr_chat.in_seq_no + (P->encr_chat.admin_id != tgl_state.our_id));
out_int (2 * P->encr_chat.out_seq_no + (P->encr_chat.admin_id == tgl_state.our_id));
out_int (0);
}
out_long (M->id);
static int buf[4];
tglt_secure_random (buf, 16);
@ -1141,6 +1154,7 @@ void tgl_do_messages_mark_read (tgl_peer_id_t id, int max_id, int offset, void (
out_peer_id (id);
out_int (max_id);
out_int (offset);
out_int (CODE_bool_true);
int *t = talloc (12);
t[0] = tgl_get_peer_type (id);
t[1] = tgl_get_peer_id (id);
@ -1738,7 +1752,14 @@ static void send_part (struct send_file *f, void *callback, void *callback_extra
tglt_secure_random (&r, 8);
out_long (r);
encr_start ();
if (P->encr_chat.layer <= 16) {
out_int (CODE_decrypted_message_l16);
} else {
out_int (CODE_decrypted_message);
out_int (2 * P->encr_chat.in_seq_no + (P->encr_chat.admin_id != tgl_state.our_id));
out_int (2 * P->encr_chat.out_seq_no + (P->encr_chat.admin_id == tgl_state.our_id) + 2);
out_int (0);
}
out_long (r);
out_random (15 + 4 * (lrand48 () % 3));
out_string ("");
@ -2906,6 +2927,9 @@ static int send_encr_accept_on_answer (struct query *q UU) {
print_end ();
}*/
if (E->state == sc_ok) {
tgl_do_send_encr_chat_layer (E);
}
if (q->callback) {
((void (*)(void *, int, struct tgl_secret_chat *))q->callback) (q->callback_extra, E->state == sc_ok, E);
}

View File

@ -1 +1 @@
scheme16.tl
scheme17.tl

528
scheme17.tl Normal file
View File

@ -0,0 +1,528 @@
int ?= Int;
long ?= Long;
double ?= Double;
string ?= String;
bytes string = Bytes;
boolFalse#bc799737 = Bool;
boolTrue#997275b5 = Bool;
vector#1cb5c415 {t:Type} # [ t ] = Vector t;
error#c4b9f9bb code:int text:string = Error;
null#56730bcc = Null;
inputPeerEmpty#7f3b18ea = InputPeer;
inputPeerSelf#7da07ec9 = InputPeer;
inputPeerContact#1023dbe8 user_id:int = InputPeer;
inputPeerForeign#9b447325 user_id:int access_hash:long = InputPeer;
inputPeerChat#179be863 chat_id:int = InputPeer;
inputUserEmpty#b98886cf = InputUser;
inputUserSelf#f7c1b13f = InputUser;
inputUserContact#86e94f65 user_id:int = InputUser;
inputUserForeign#655e74ff user_id:int access_hash:long = InputUser;
inputPhoneContact#f392b7f4 client_id:long phone:string first_name:string last_name:string = InputContact;
inputFile#f52ff27f id:long parts:int name:string md5_checksum:string = InputFile;
inputMediaEmpty#9664f57f = InputMedia;
inputMediaUploadedPhoto#2dc53a7d file:InputFile = InputMedia;
inputMediaPhoto#8f2ab2ec id:InputPhoto = InputMedia;
inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia;
inputMediaContact#a6e45987 phone_number:string first_name:string last_name:string = InputMedia;
inputMediaUploadedVideo#133ad6f6 file:InputFile duration:int w:int h:int mime_type:string = InputMedia;
inputMediaUploadedThumbVideo#9912dabf file:InputFile thumb:InputFile duration:int w:int h:int mime_type:string = InputMedia;
inputMediaVideo#7f023ae6 id:InputVideo = InputMedia;
inputChatPhotoEmpty#1ca48f57 = InputChatPhoto;
inputChatUploadedPhoto#94254732 file:InputFile crop:InputPhotoCrop = InputChatPhoto;
inputChatPhoto#b2e1bf08 id:InputPhoto crop:InputPhotoCrop = InputChatPhoto;
inputGeoPointEmpty#e4c123d6 = InputGeoPoint;
inputGeoPoint#f3b7acc9 lat:double long:double = InputGeoPoint;
inputPhotoEmpty#1cd7bf0d = InputPhoto;
inputPhoto#fb95c6c4 id:long access_hash:long = InputPhoto;
inputVideoEmpty#5508ec75 = InputVideo;
inputVideo#ee579652 id:long access_hash:long = InputVideo;
inputFileLocation#14637196 volume_id:long local_id:int secret:long = InputFileLocation;
inputVideoFileLocation#3d0364ec id:long access_hash:long = InputFileLocation;
inputPhotoCropAuto#ade6b004 = InputPhotoCrop;
inputPhotoCrop#d9915325 crop_left:double crop_top:double crop_width:double = InputPhotoCrop;
inputAppEvent#770656a8 time:double type:string peer:long data:string = InputAppEvent;
peerUser#9db1bc6d user_id:int = Peer;
peerChat#bad0e5bb chat_id:int = Peer;
storage.fileUnknown#aa963b05 = storage.FileType;
storage.fileJpeg#7efe0e = storage.FileType;
storage.fileGif#cae1aadf = storage.FileType;
storage.filePng#a4f63c0 = storage.FileType;
storage.filePdf#ae1e508d = storage.FileType;
storage.fileMp3#528a0677 = storage.FileType;
storage.fileMov#4b09ebbc = storage.FileType;
storage.filePartial#40bc6f52 = storage.FileType;
storage.fileMp4#b3cea0e4 = storage.FileType;
storage.fileWebp#1081464c = storage.FileType;
fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileLocation;
fileLocation#53d69076 dc_id:int volume_id:long local_id:int secret:long = FileLocation;
userEmpty#200250ba id:int = User;
userSelf#720535ec id:int first_name:string last_name:string phone:string photo:UserProfilePhoto status:UserStatus inactive:Bool = User;
userContact#f2fb8319 id:int first_name:string last_name:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User;
userRequest#22e8ceb0 id:int first_name:string last_name:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User;
userForeign#5214c89d id:int first_name:string last_name:string access_hash:long photo:UserProfilePhoto status:UserStatus = User;
userDeleted#b29ad7cc id:int first_name:string last_name:string = User;
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
userProfilePhoto#d559d8c8 photo_id:long photo_small:FileLocation photo_big:FileLocation = UserProfilePhoto;
userStatusEmpty#9d05049 = UserStatus;
userStatusOnline#edb93949 expires:int = UserStatus;
userStatusOffline#8c703f was_online:int = UserStatus;
chatEmpty#9ba2d800 id:int = Chat;
chat#6e9c9bc7 id:int title:string photo:ChatPhoto participants_count:int date:int left:Bool version:int = Chat;
chatForbidden#fb0ccc41 id:int title:string date:int = Chat;
chatFull#630e61be id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings = ChatFull;
chatParticipant#c8d7493e user_id:int inviter_id:int date:int = ChatParticipant;
chatParticipantsForbidden#fd2bb8a chat_id:int = ChatParticipants;
chatParticipants#7841b415 chat_id:int admin_id:int participants:Vector<ChatParticipant> version:int = ChatParticipants;
chatPhotoEmpty#37c1011c = ChatPhoto;
chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto;
messageEmpty#83e5de54 id:int = Message;
//message#22eb6aba id:int from_id:int to_id:Peer out:Bool unread:Bool date:int message:string media:MessageMedia = Message;
//messageForwarded#5f46804 id:int fwd_from_id:int fwd_date:int from_id:int to_id:Peer out:Bool unread:Bool date:int message:string media:MessageMedia = Message;
//messageService#9f8d60bb id:int from_id:int to_id:Peer out:Bool unread:Bool date:int action:MessageAction = Message;
messageMediaEmpty#3ded6320 = MessageMedia;
messageMediaPhoto#c8c45a2a photo:Photo = MessageMedia;
messageMediaVideo#a2d24290 video:Video = MessageMedia;
messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
messageMediaContact#5e7d2f39 phone_number:string first_name:string last_name:string user_id:int = MessageMedia;
messageMediaUnsupported#29632a36 bytes:bytes = MessageMedia;
messageActionEmpty#b6aef7b0 = MessageAction;
messageActionChatCreate#a6638b9a title:string users:Vector<int> = MessageAction;
messageActionChatEditTitle#b5a1ce5a title:string = MessageAction;
messageActionChatEditPhoto#7fcb13a8 photo:Photo = MessageAction;
messageActionChatDeletePhoto#95e3fbef = MessageAction;
messageActionChatAddUser#5e3cfc4b user_id:int = MessageAction;
messageActionChatDeleteUser#b2ae9b0c user_id:int = MessageAction;
dialog#ab3a99ac peer:Peer top_message:int unread_count:int notify_settings:PeerNotifySettings = Dialog;
photoEmpty#2331b22d id:long = Photo;
photo#22b56751 id:long access_hash:long user_id:int date:int caption:string geo:GeoPoint sizes:Vector<PhotoSize> = Photo;
photoSizeEmpty#e17e23c type:string = PhotoSize;
photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize;
photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize;
videoEmpty#c10658a8 id:long = Video;
video#388fa391 id:long access_hash:long user_id:int date:int caption:string duration:int mime_type:string size:int thumb:PhotoSize dc_id:int w:int h:int = Video;
geoPointEmpty#1117dd5f = GeoPoint;
geoPoint#2049d70c long:double lat:double = GeoPoint;
auth.checkedPhone#e300cc3b phone_registered:Bool phone_invited:Bool = auth.CheckedPhone;
auth.sentCode#efed51d9 phone_registered:Bool phone_code_hash:string send_call_timeout:int is_password:Bool = auth.SentCode;
auth.authorization#f6b673a4 expires:int user:User = auth.Authorization;
auth.exportedAuthorization#df969c2d id:int bytes:bytes = auth.ExportedAuthorization;
inputNotifyPeer#b8bc5b0c peer:InputPeer = InputNotifyPeer;
inputNotifyUsers#193b4417 = InputNotifyPeer;
inputNotifyChats#4a95e84e = InputNotifyPeer;
inputNotifyAll#a429b886 = InputNotifyPeer;
inputPeerNotifyEventsEmpty#f03064d8 = InputPeerNotifyEvents;
inputPeerNotifyEventsAll#e86a2c74 = InputPeerNotifyEvents;
inputPeerNotifySettings#46a2ce98 mute_until:int sound:string show_previews:Bool events_mask:int = InputPeerNotifySettings;
peerNotifyEventsEmpty#add53cb3 = PeerNotifyEvents;
peerNotifyEventsAll#6d1ded88 = PeerNotifyEvents;
peerNotifySettingsEmpty#70a68512 = PeerNotifySettings;
peerNotifySettings#8d5e11ee mute_until:int sound:string show_previews:Bool events_mask:int = PeerNotifySettings;
wallPaper#ccb03657 id:int title:string sizes:Vector<PhotoSize> color:int = WallPaper;
userFull#771095da user:User link:contacts.Link profile_photo:Photo notify_settings:PeerNotifySettings blocked:Bool real_first_name:string real_last_name:string = UserFull;
contact#f911c994 user_id:int mutual:Bool = Contact;
importedContact#d0028438 user_id:int client_id:long = ImportedContact;
contactBlocked#561bc879 user_id:int date:int = ContactBlocked;
contactFound#ea879f95 user_id:int = ContactFound;
contactSuggested#3de191a1 user_id:int mutual_contacts:int = ContactSuggested;
contactStatus#aa77b873 user_id:int expires:int = ContactStatus;
chatLocated#3631cf4c chat_id:int distance:int = ChatLocated;
contacts.foreignLinkUnknown#133421f8 = contacts.ForeignLink;
contacts.foreignLinkRequested#a7801f47 has_phone:Bool = contacts.ForeignLink;
contacts.foreignLinkMutual#1bea8ce1 = contacts.ForeignLink;
contacts.myLinkEmpty#d22a1c60 = contacts.MyLink;
contacts.myLinkRequested#6c69efee contact:Bool = contacts.MyLink;
contacts.myLinkContact#c240ebd9 = contacts.MyLink;
contacts.link#eccea3f5 my_link:contacts.MyLink foreign_link:contacts.ForeignLink user:User = contacts.Link;
contacts.contacts#6f8b8cb2 contacts:Vector<Contact> users:Vector<User> = contacts.Contacts;
contacts.contactsNotModified#b74ba9d2 = contacts.Contacts;
contacts.importedContacts#ad524315 imported:Vector<ImportedContact> retry_contacts:Vector<long> users:Vector<User> = contacts.ImportedContacts;
contacts.blocked#1c138d15 blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked;
contacts.blockedSlice#900802a1 count:int blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked;
contacts.found#566000e results:Vector<ContactFound> users:Vector<User> = contacts.Found;
contacts.suggested#5649dcc5 results:Vector<ContactSuggested> users:Vector<User> = contacts.Suggested;
messages.dialogs#15ba6c40 dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesSlice#b446ae3 count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messageEmpty#3f4e0648 = messages.Message;
messages.message#ff90c417 message:Message chats:Vector<Chat> users:Vector<User> = messages.Message;
messages.statedMessages#969478bb messages:Vector<Message> chats:Vector<Chat> users:Vector<User> pts:int seq:int = messages.StatedMessages;
messages.statedMessage#d07ae726 message:Message chats:Vector<Chat> users:Vector<User> pts:int seq:int = messages.StatedMessage;
messages.sentMessage#d1f4d35c id:int date:int pts:int seq:int = messages.SentMessage;
messages.chat#40e9002a chat:Chat users:Vector<User> = messages.Chat;
messages.chats#8150cbd8 chats:Vector<Chat> users:Vector<User> = messages.Chats;
messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector<Chat> users:Vector<User> = messages.ChatFull;
messages.affectedHistory#b7de36f2 pts:int seq:int offset:int = messages.AffectedHistory;
inputMessagesFilterEmpty#57e2f66c = MessagesFilter;
inputMessagesFilterPhotos#9609a51c = MessagesFilter;
inputMessagesFilterVideo#9fc00e65 = MessagesFilter;
inputMessagesFilterPhotoVideo#56e9f0e4 = MessagesFilter;
inputMessagesFilterDocument#9eddf188 = MessagesFilter;
inputMessagesFilterAudio#cfc87522 = MessagesFilter;
updateNewMessage#13abdb3 message:Message pts:int = Update;
updateMessageID#4e90bfd6 id:int random_id:long = Update;
updateReadMessages#c6649e31 messages:Vector<int> pts:int = Update;
updateDeleteMessages#a92bfe26 messages:Vector<int> pts:int = Update;
updateRestoreMessages#d15de04d messages:Vector<int> pts:int = Update;
//updateUserTyping#6baa8508 user_id:int = Update;
//updateChatUserTyping#3c46cfe6 chat_id:int user_id:int = Update;
updateChatParticipants#7761198 participants:ChatParticipants = Update;
updateUserStatus#1bfbd823 user_id:int status:UserStatus = Update;
updateUserName#da22d9ad user_id:int first_name:string last_name:string = Update;
updateUserPhoto#95313b0c user_id:int date:int photo:UserProfilePhoto previous:Bool = Update;
updateContactRegistered#2575bbb9 user_id:int date:int = Update;
updateContactLink#51a48a9a user_id:int my_link:contacts.MyLink foreign_link:contacts.ForeignLink = Update;
updateActivation#6f690963 user_id:int = Update;
updateNewAuthorization#8f06529a auth_key_id:long date:int device:string location:string = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
updates.differenceEmpty#5d75a138 date:int seq:int = updates.Difference;
updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> state:updates.State = updates.Difference;
updates.differenceSlice#a8fb1981 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> intermediate_state:updates.State = updates.Difference;
updatesTooLong#e317af7e = Updates;
updateShortMessage#d3f45784 id:int from_id:int message:string pts:int date:int seq:int = Updates;
updateShortChatMessage#2b2fbd4e id:int from_id:int chat_id:int message:string pts:int date:int seq:int = Updates;
updateShort#78d4dec1 update:Update date:int = Updates;
updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates;
updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;
photos.photos#8dca6aa5 photos:Vector<Photo> users:Vector<User> = photos.Photos;
photos.photosSlice#15051f54 count:int photos:Vector<Photo> users:Vector<User> = photos.Photos;
photos.photo#20212ca8 photo:Photo users:Vector<User> = photos.Photo;
upload.file#96a18d5 type:storage.FileType mtime:int bytes:bytes = upload.File;
dcOption#2ec2a43c id:int hostname:string ip_address:string port:int = DcOption;
config#2e54dd74 date:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int broadcast_size_max:int = Config;
nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc;
help.appUpdate#8987f311 id:int critical:Bool url:string text:string = help.AppUpdate;
help.noAppUpdate#c45a6536 = help.AppUpdate;
help.inviteText#18cb9f78 message:string = help.InviteText;
messages.statedMessagesLinks#3e74f5c6 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> links:Vector<contacts.Link> pts:int seq:int = messages.StatedMessages;
messages.statedMessageLink#a9af2881 message:Message chats:Vector<Chat> users:Vector<User> links:Vector<contacts.Link> pts:int seq:int = messages.StatedMessage;
messages.sentMessageLink#e9db4a3f id:int date:int pts:int seq:int links:Vector<contacts.Link> = messages.SentMessage;
inputGeoChat#74d456fa chat_id:int access_hash:long = InputGeoChat;
inputNotifyGeoChatPeer#4d8ddec8 peer:InputGeoChat = InputNotifyPeer;
geoChat#75eaea5a id:int access_hash:long title:string address:string venue:string geo:GeoPoint photo:ChatPhoto participants_count:int date:int checked_in:Bool version:int = Chat;
geoChatMessageEmpty#60311a9b chat_id:int id:int = GeoChatMessage;
geoChatMessage#4505f8e1 chat_id:int id:int from_id:int date:int message:string media:MessageMedia = GeoChatMessage;
geoChatMessageService#d34fa24e chat_id:int id:int from_id:int date:int action:MessageAction = GeoChatMessage;
geochats.statedMessage#17b1578b message:GeoChatMessage chats:Vector<Chat> users:Vector<User> seq:int = geochats.StatedMessage;
geochats.located#48feb267 results:Vector<ChatLocated> messages:Vector<GeoChatMessage> chats:Vector<Chat> users:Vector<User> = geochats.Located;
geochats.messages#d1526db1 messages:Vector<GeoChatMessage> chats:Vector<Chat> users:Vector<User> = geochats.Messages;
geochats.messagesSlice#bc5863e8 count:int messages:Vector<GeoChatMessage> chats:Vector<Chat> users:Vector<User> = geochats.Messages;
messageActionGeoChatCreate#6f038ebc title:string address:string = MessageAction;
messageActionGeoChatCheckin#c7d53de = MessageAction;
updateNewGeoChatMessage#5a68e3f7 message:GeoChatMessage = Update;
wallPaperSolid#63117f24 id:int title:string bg_color:int color:int = WallPaper;
updateNewEncryptedMessage#12bcbd9a message:EncryptedMessage qts:int = Update;
updateEncryptedChatTyping#1710f156 chat_id:int = Update;
updateEncryption#b4a2e88d chat:EncryptedChat date:int = Update;
updateEncryptedMessagesRead#38fe25b7 chat_id:int max_date:int date:int = Update;
encryptedChatEmpty#ab7ec0a0 id:int = EncryptedChat;
encryptedChatWaiting#3bf703dc id:int access_hash:long date:int admin_id:int participant_id:int = EncryptedChat;
encryptedChatRequested#c878527e id:int access_hash:long date:int admin_id:int participant_id:int g_a:bytes = EncryptedChat;
encryptedChat#fa56ce36 id:int access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long = EncryptedChat;
encryptedChatDiscarded#13d6dd27 id:int = EncryptedChat;
inputEncryptedChat#f141b5e1 chat_id:int access_hash:long = InputEncryptedChat;
encryptedFileEmpty#c21f497e = EncryptedFile;
encryptedFile#4a70994c id:long access_hash:long size:int dc_id:int key_fingerprint:int = EncryptedFile;
inputEncryptedFileEmpty#1837c364 = InputEncryptedFile;
inputEncryptedFileUploaded#64bd0306 id:long parts:int md5_checksum:string key_fingerprint:int = InputEncryptedFile;
inputEncryptedFile#5a17b5e5 id:long access_hash:long = InputEncryptedFile;
inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation;
encryptedMessage#ed18c118 random_id:long chat_id:int date:int bytes:bytes file:EncryptedFile = EncryptedMessage;
encryptedMessageService#23734b06 random_id:long chat_id:int date:int bytes:bytes = EncryptedMessage;
messages.dhConfigNotModified#c0e24635 random:bytes = messages.DhConfig;
messages.dhConfig#2c221edd g:int p:bytes version:int random:bytes = messages.DhConfig;
messages.sentEncryptedMessage#560f8935 date:int = messages.SentEncryptedMessage;
messages.sentEncryptedFile#9493ff32 date:int file:EncryptedFile = messages.SentEncryptedMessage;
inputFileBig#fa4f0bb5 id:long parts:int name:string = InputFile;
inputEncryptedFileBigUploaded#2dc173c8 id:long parts:int key_fingerprint:int = InputEncryptedFile;
updateChatParticipantAdd#3a0eeb22 chat_id:int user_id:int inviter_id:int version:int = Update;
updateChatParticipantDelete#6e5f8c22 chat_id:int user_id:int version:int = Update;
updateDcOptions#8e5e9873 dc_options:Vector<DcOption> = Update;
inputMediaUploadedAudio#4e498cab file:InputFile duration:int mime_type:string = InputMedia;
inputMediaAudio#89938781 id:InputAudio = InputMedia;
inputMediaUploadedDocument#34e794bd file:InputFile file_name:string mime_type:string = InputMedia;
inputMediaUploadedThumbDocument#3e46de5d file:InputFile thumb:InputFile file_name:string mime_type:string = InputMedia;
inputMediaDocument#d184e841 id:InputDocument = InputMedia;
messageMediaDocument#2fda2204 document:Document = MessageMedia;
messageMediaAudio#c6b68300 audio:Audio = MessageMedia;
inputAudioEmpty#d95adc84 = InputAudio;
inputAudio#77d440ff id:long access_hash:long = InputAudio;
inputDocumentEmpty#72f0eaae = InputDocument;
inputDocument#18798952 id:long access_hash:long = InputDocument;
inputAudioFileLocation#74dc404d id:long access_hash:long = InputFileLocation;
inputDocumentFileLocation#4e45abe9 id:long access_hash:long = InputFileLocation;
audioEmpty#586988d8 id:long = Audio;
audio#c7ac6496 id:long access_hash:long user_id:int date:int duration:int mime_type:string size:int dc_id:int = Audio;
documentEmpty#36f8c871 id:long = Document;
document#9efc6326 id:long access_hash:long user_id:int date:int file_name:string mime_type:string size:int thumb:PhotoSize dc_id:int = Document;
help.support#17c6b5f6 phone_number:string user:User = help.Support;
notifyPeer#9fd40bd8 peer:Peer = NotifyPeer;
notifyUsers#b4c83b4c = NotifyPeer;
notifyChats#c007cec3 = NotifyPeer;
notifyAll#74d07c60 = NotifyPeer;
updateUserBlocked#80ece81a user_id:int blocked:Bool = Update;
updateNotifySettings#bec268ef peer:NotifyPeer notify_settings:PeerNotifySettings = Update;
auth.sentAppCode#e325edcf phone_registered:Bool phone_code_hash:string send_call_timeout:int is_password:Bool = auth.SentCode;
updateUserTyping#5c486927 user_id:int action:SendMessageAction = Update;
updateChatUserTyping#9a65ea1f chat_id:int user_id:int action:SendMessageAction = Update;
message#567699b3 flags:int id:int from_id:int to_id:Peer date:int message:string media:MessageMedia = Message;
messageForwarded#a367e716 flags:int id:int fwd_from_id:int fwd_date:int from_id:int to_id:Peer date:int message:string media:MessageMedia = Message;
messageService#1d86f70e flags:int id:int from_id:int to_id:Peer date:int action:MessageAction = Message;
sendMessageTypingAction#16bf744e = SendMessageAction;
sendMessageCancelAction#fd5ec8f5 = SendMessageAction;
sendMessageRecordVideoAction#a187d66f = SendMessageAction;
sendMessageUploadVideoAction#92042ff7 = SendMessageAction;
sendMessageRecordAudioAction#d52f73f7 = SendMessageAction;
sendMessageUploadAudioAction#e6ac8a6f = SendMessageAction;
sendMessageUploadPhotoAction#990a3c1a = SendMessageAction;
sendMessageUploadDocumentAction#8faee98e = SendMessageAction;
sendMessageGeoLocationAction#176f8ba1 = SendMessageAction;
sendMessageChooseContactAction#628cbc6f = SendMessageAction;
---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
invokeAfterMsgs#3dc4b4f0 {X:Type} msg_ids:Vector<long> query:!X = X;
auth.checkPhone#6fe51dfb phone_number:string = auth.CheckedPhone;
auth.sendCode#768d5f4d phone_number:string sms_type:int api_id:int api_hash:string lang_code:string = auth.SentCode;
auth.sendCall#3c51564 phone_number:string phone_code_hash:string = Bool;
auth.signUp#1b067634 phone_number:string phone_code_hash:string phone_code:string first_name:string last_name:string = auth.Authorization;
auth.signIn#bcd51581 phone_number:string phone_code_hash:string phone_code:string = auth.Authorization;
auth.logOut#5717da40 = Bool;
auth.resetAuthorizations#9fab0d1a = Bool;
auth.sendInvites#771c1d97 phone_numbers:Vector<string> message:string = Bool;
auth.exportAuthorization#e5bfffcd dc_id:int = auth.ExportedAuthorization;
auth.importAuthorization#e3ef9613 id:int bytes:bytes = auth.Authorization;
auth.bindTempAuthKey#cdd42a05 perm_auth_key_id:long nonce:long expires_at:int encrypted_message:bytes = Bool;
account.registerDevice#446c712c token_type:int token:string device_model:string system_version:string app_version:string app_sandbox:Bool lang_code:string = Bool;
account.unregisterDevice#65c55b40 token_type:int token:string = Bool;
account.updateNotifySettings#84be5b93 peer:InputNotifyPeer settings:InputPeerNotifySettings = Bool;
account.getNotifySettings#12b3ad31 peer:InputNotifyPeer = PeerNotifySettings;
account.resetNotifySettings#db7e1747 = Bool;
account.updateProfile#f0888d68 first_name:string last_name:string = User;
account.updateStatus#6628562c offline:Bool = Bool;
account.getWallPapers#c04cfac2 = Vector<WallPaper>;
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
users.getFullUser#ca30a5b1 id:InputUser = UserFull;
contacts.getStatuses#c4a353ee = Vector<ContactStatus>;
contacts.getContacts#22c6aa08 hash:string = contacts.Contacts;
contacts.importContacts#da30b32d contacts:Vector<InputContact> replace:Bool = contacts.ImportedContacts;
contacts.search#11f812d8 q:string limit:int = contacts.Found;
contacts.getSuggested#cd773428 limit:int = contacts.Suggested;
contacts.deleteContact#8e953744 id:InputUser = contacts.Link;
contacts.deleteContacts#59ab389e id:Vector<InputUser> = Bool;
contacts.block#332b49fc id:InputUser = Bool;
contacts.unblock#e54100bd id:InputUser = Bool;
contacts.getBlocked#f57c350f offset:int limit:int = contacts.Blocked;
contacts.exportCard#84e53737 = Vector<int>;
contacts.importCard#4fe196fe export_card:Vector<int> = User;
messages.getMessages#4222fa74 id:Vector<int> = messages.Messages;
messages.getDialogs#eccf1df6 offset:int max_id:int limit:int = messages.Dialogs;
messages.getHistory#92a1df2f peer:InputPeer offset:int max_id:int limit:int = messages.Messages;
messages.search#7e9f2ab peer:InputPeer q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = messages.Messages;
messages.readHistory#eed884c6 peer:InputPeer max_id:int offset:int read_contents:Bool = messages.AffectedHistory;
messages.deleteHistory#f4f8fb61 peer:InputPeer offset:int = messages.AffectedHistory;
messages.deleteMessages#14f2dd0a id:Vector<int> = Vector<int>;
messages.restoreMessages#395f9d7e id:Vector<int> = Vector<int>;
messages.receivedMessages#28abcb68 max_id:int = Vector<int>;
messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool;
messages.sendMessage#4cde0aab peer:InputPeer message:string random_id:long = messages.SentMessage;
messages.sendMedia#a3c85d76 peer:InputPeer media:InputMedia random_id:long = messages.StatedMessage;
messages.forwardMessages#514cd10f peer:InputPeer id:Vector<int> = messages.StatedMessages;
messages.getChats#3c6aa187 id:Vector<int> = messages.Chats;
messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull;
messages.editChatTitle#b4bc68b5 chat_id:int title:string = messages.StatedMessage;
messages.editChatPhoto#d881821d chat_id:int photo:InputChatPhoto = messages.StatedMessage;
messages.addChatUser#2ee9ee9e chat_id:int user_id:InputUser fwd_limit:int = messages.StatedMessage;
messages.deleteChatUser#c3c5cd23 chat_id:int user_id:InputUser = messages.StatedMessage;
messages.createChat#419d9aee users:Vector<InputUser> title:string = messages.StatedMessage;
updates.getState#edd4882a = updates.State;
updates.getDifference#a041495 pts:int date:int qts:int = updates.Difference;
photos.updateProfilePhoto#eef579a0 id:InputPhoto crop:InputPhotoCrop = UserProfilePhoto;
photos.uploadProfilePhoto#d50f9c88 file:InputFile caption:string geo_point:InputGeoPoint crop:InputPhotoCrop = photos.Photo;
upload.saveFilePart#b304a621 file_id:long file_part:int bytes:bytes = Bool;
upload.getFile#e3a6cfb5 location:InputFileLocation offset:int limit:int = upload.File;
help.getConfig#c4f9186b = Config;
help.getNearestDc#1fb33026 = NearestDc;
help.getAppUpdate#c812ac7e device_model:string system_version:string app_version:string lang_code:string = help.AppUpdate;
help.saveAppLog#6f02f748 events:Vector<InputAppEvent> = Bool;
help.getInviteText#a4a95186 lang_code:string = help.InviteText;
photos.getUserPhotos#b7ee553c user_id:InputUser offset:int max_id:int limit:int = photos.Photos;
messages.forwardMessage#3f3f4f2 peer:InputPeer id:int random_id:long = messages.StatedMessage;
messages.sendBroadcast#41bb0972 contacts:Vector<InputUser> message:string media:InputMedia = messages.StatedMessages;
geochats.getLocated#7f192d8f geo_point:InputGeoPoint radius:int limit:int = geochats.Located;
geochats.getRecents#e1427e6f offset:int limit:int = geochats.Messages;
geochats.checkin#55b3e8fb peer:InputGeoChat = geochats.StatedMessage;
geochats.getFullChat#6722dd6f peer:InputGeoChat = messages.ChatFull;
geochats.editChatTitle#4c8e2273 peer:InputGeoChat title:string address:string = geochats.StatedMessage;
geochats.editChatPhoto#35d81a95 peer:InputGeoChat photo:InputChatPhoto = geochats.StatedMessage;
geochats.search#cfcdc44d peer:InputGeoChat q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = geochats.Messages;
geochats.getHistory#b53f7a68 peer:InputGeoChat offset:int max_id:int limit:int = geochats.Messages;
geochats.setTyping#8b8a729 peer:InputGeoChat typing:Bool = Bool;
geochats.sendMessage#61b0044 peer:InputGeoChat message:string random_id:long = geochats.StatedMessage;
geochats.sendMedia#b8f0deff peer:InputGeoChat media:InputMedia random_id:long = geochats.StatedMessage;
geochats.createGeoChat#e092e16 title:string geo_point:InputGeoPoint address:string venue:string = geochats.StatedMessage;
messages.getDhConfig#26cf8950 version:int random_length:int = messages.DhConfig;
messages.requestEncryption#f64daf43 user_id:InputUser random_id:int g_a:bytes = EncryptedChat;
messages.acceptEncryption#3dbc0415 peer:InputEncryptedChat g_b:bytes key_fingerprint:long = EncryptedChat;
messages.discardEncryption#edd923c5 chat_id:int = Bool;
messages.setEncryptedTyping#791451ed peer:InputEncryptedChat typing:Bool = Bool;
messages.readEncryptedHistory#7f4b690a peer:InputEncryptedChat max_date:int = Bool;
messages.sendEncrypted#a9776773 peer:InputEncryptedChat random_id:long data:bytes = messages.SentEncryptedMessage;
messages.sendEncryptedFile#9a901b66 peer:InputEncryptedChat random_id:long data:bytes file:InputEncryptedFile = messages.SentEncryptedMessage;
messages.sendEncryptedService#32d439a4 peer:InputEncryptedChat random_id:long data:bytes = messages.SentEncryptedMessage;
messages.receivedQueue#55a5bb66 max_qts:int = Vector<long>;
upload.saveBigFilePart#de7b673d file_id:long file_part:int file_total_parts:int bytes:bytes = Bool;
initConnection#69796de9 {X:Type} api_id:int device_model:string system_version:string app_version:string lang_code:string query:!X = X;
help.getSupport#9cdf08cd = help.Support;
auth.sendSms#da9f3e8 phone_number:string phone_code_hash:string = Bool;
messages.readMessageContents id:Vector<int> = Vector<int>;
invokeWithLayer17#50858a19 {X:Type} query:!X = X;

View File

@ -108,6 +108,34 @@ char *tgls_default_create_print_name (tgl_peer_id_t id, const char *a1, const ch
return tstrdup (s);
}
enum tgl_typing_status tglf_fetch_typing (void) {
switch (fetch_int ()) {
case CODE_send_message_typing_action:
return tgl_typing_typing;
case CODE_send_message_cancel_action:
return tgl_typing_cancel;
case CODE_send_message_record_video_action:
return tgl_typing_record_video;
case CODE_send_message_upload_video_action:
return tgl_typing_upload_video;
case CODE_send_message_record_audio_action:
return tgl_typing_record_audio;
case CODE_send_message_upload_audio_action:
return tgl_typing_upload_audio;
case CODE_send_message_upload_photo_action:
return tgl_typing_upload_photo;
case CODE_send_message_upload_document_action:
return tgl_typing_upload_document;
case CODE_send_message_geo_location_action:
return tgl_typing_geo;
case CODE_send_message_choose_contact_action:
return tgl_typing_choose_contact;
default:
assert (0);
return tgl_typing_none;
}
}
/* {{{ Fetch */
int tglf_fetch_file_location (struct tgl_file_location *loc) {
@ -990,6 +1018,10 @@ void tglf_fetch_message_action_encrypted (struct tgl_message_action *M) {
case CODE_decrypted_message_action_flush_history:
M->type = tgl_message_action_flush_history;
break;
case CODE_decrypted_message_action_typing:
M->type = tgl_message_action_typing;
M->typing = tglf_fetch_typing ();
break;
default:
vlogprintf (E_ERROR, "x = 0x%08x\n", x);
assert (0);
@ -1009,6 +1041,10 @@ tgl_peer_id_t tglf_fetch_peer_id (void) {
void tglf_fetch_message (struct tgl_message *M) {
unsigned x = fetch_int ();
assert (x == CODE_message_empty || x == CODE_message || x == CODE_message_forwarded || x == CODE_message_service);
int flags = 0;
if (x != CODE_message_empty) {
flags = fetch_int ();
}
int id = fetch_int ();
assert (M->id == id);
if (x == CODE_message_empty) {
@ -1024,11 +1060,12 @@ void tglf_fetch_message (struct tgl_message *M) {
int from_id = fetch_int ();
tgl_peer_id_t to_id = tglf_fetch_peer_id ();
fetch_bool (); // out.
//fetch_bool (); // out.
int unread = fetch_bool ();
//int unread = fetch_bool ();
int date = fetch_int ();
int unread = (flags & 1) != 0;
int new = !(M->flags & FLAG_CREATED);
if (x == CODE_message_service) {
@ -1190,12 +1227,30 @@ void tglf_fetch_encrypted_message (struct tgl_message *M) {
assert (layer >= 0);
x = fetch_int ();
}
assert (x == CODE_decrypted_message || x == CODE_decrypted_message_service);
assert (x == CODE_decrypted_message || x == CODE_decrypted_message_service || x == CODE_decrypted_message_l16 || x == CODE_decrypted_message_service_l16);
//assert (id == fetch_long ());
if (x == CODE_decrypted_message || x == CODE_decrypted_message_service) {
int out_seq_no = fetch_int ();
int in_seq_no = fetch_int ();
if (in_seq_no / 2 <= P->encr_chat.in_seq_no) {
vlogprintf (E_WARNING, "Hole in seq in secret chat. in_seq_no = %d, expect_seq_no = %d\n", in_seq_no / 2, P->encr_chat.in_seq_no + 1);
}
if (in_seq_no / 2 > P->encr_chat.in_seq_no + 1) {
vlogprintf (E_WARNING, "Hole in seq in secret chat. in_seq_no = %d, expect_seq_no = %d\n", in_seq_no / 2, P->encr_chat.in_seq_no + 1);
}
//vlogprintf (E_WARNING, "in = %d, out = %d\n", in_seq_no, out_seq_no);
assert (out_seq_no / 2 <= P->encr_chat.out_seq_no);
P->encr_chat.in_seq_no = in_seq_no / 2;
if (x == CODE_decrypted_message) {
fetch_int (); // ttl
}
} else {
P->encr_chat.in_seq_no ++;
}
fetch_long ();
ll = prefetch_strlen ();
fetch_str (ll); // random_bytes
if (x == CODE_decrypted_message) {
if (x == CODE_decrypted_message || x == CODE_decrypted_message_l16) {
l = prefetch_strlen ();
s = fetch_str (l);
start = in_ptr;
@ -1216,9 +1271,9 @@ void tglf_fetch_encrypted_message (struct tgl_message *M) {
if (ok) {
int *start_file = in_ptr;
assert (skip_type_any (TYPE_TO_PARAM (encrypted_file)) >= 0);
if (x == CODE_decrypted_message) {
if (x == CODE_decrypted_message || x == CODE_decrypted_message_l16) {
bl_do_create_message_media_encr (id, P->encr_chat.user_id, TGL_PEER_ENCR_CHAT, to_id, date, l, s, start, end - start, start_file, in_ptr - start_file);
} else if (x == CODE_decrypted_message_service) {
} else if (x == CODE_decrypted_message_service || x == CODE_decrypted_message_service_l16) {
bl_do_create_message_service_encr (id, P->encr_chat.user_id, TGL_PEER_ENCR_CHAT, to_id, date, start, end - start);
}
} else {
@ -1226,7 +1281,7 @@ void tglf_fetch_encrypted_message (struct tgl_message *M) {
M->media.type = CODE_message_media_empty;
}
} else {
if (ok && x == CODE_decrypted_message_service) {
if (ok && (x == CODE_decrypted_message_service || x == CODE_decrypted_message_service_l16)) {
bl_do_create_message_service_encr (id, P->encr_chat.user_id, TGL_PEER_ENCR_CHAT, to_id, date, start, end - start);
}
}
@ -1310,12 +1365,12 @@ struct tgl_user *tglf_fetch_alloc_user_full (void) {
}
struct tgl_message *tglf_fetch_alloc_message (void) {
int data[2];
prefetch_data (data, 8);
struct tgl_message *M = tgl_message_get (data[1]);
int data[3];
prefetch_data (data, 12);
struct tgl_message *M = tgl_message_get (data[0] != (int)CODE_message_empty ? data[2] : data[1]);
if (!M) {
M = tglm_message_alloc (data[1]);
M = tglm_message_alloc (data[0] != (int)CODE_message_empty ? data[2] : data[1]);
}
tglf_fetch_message (M);
return M;

View File

@ -51,5 +51,6 @@ void tglp_peer_delete_name (tgl_peer_t *P);
void tglp_insert_encrypted_chat (tgl_peer_t *P);
void tglp_insert_user (tgl_peer_t *P);
void tglp_insert_chat (tgl_peer_t *P);
enum tgl_typing_status tglf_fetch_typing (void);
#endif

View File

@ -120,7 +120,22 @@ enum tgl_message_action_type {
tgl_message_action_delete_messages,
tgl_message_action_screenshot_messages,
tgl_message_action_flush_history,
tgl_message_action_notify_layer
tgl_message_action_notify_layer,
tgl_message_action_typing
};
enum tgl_typing_status {
tgl_typing_none,
tgl_typing_typing,
tgl_typing_cancel,
tgl_typing_record_video,
tgl_typing_upload_video,
tgl_typing_record_audio,
tgl_typing_upload_audio,
tgl_typing_upload_photo,
tgl_typing_upload_document,
tgl_typing_geo,
tgl_typing_choose_contact
};
struct tgl_file_location {
@ -288,6 +303,8 @@ struct tgl_secret_chat {
int date;
int ttl;
int layer;
int in_seq_no;
int out_seq_no;
long long access_hash;
unsigned char *g_key;
unsigned char *nonce;
@ -367,6 +384,7 @@ struct tgl_message_action {
int read_cnt;
int delete_cnt;
int screenshot_cnt;
enum tgl_typing_status typing;
};
};

6
tgl.h
View File

@ -33,7 +33,7 @@
#define TGL_BUILD "2014"
#define TGL_VERSION "1.0.5"
#define TGL_ENCRYPTED_LAYER 16
#define TGL_ENCRYPTED_LAYER 17
struct connection;
struct mtproto_methods;
@ -70,8 +70,8 @@ struct tgl_update_callback {
void (*new_msg)(struct tgl_message *M);
void (*marked_read)(int num, struct tgl_message *list[]);
void (*logprintf)(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
void (*type_notification)(struct tgl_user *U);
void (*type_in_chat_notification)(struct tgl_user *U, struct tgl_chat *C);
void (*type_notification)(struct tgl_user *U, enum tgl_typing_status status);
void (*type_in_chat_notification)(struct tgl_user *U, struct tgl_chat *C, enum tgl_typing_status status);
void (*type_in_secret_chat_notification)(struct tgl_secret_chat *E);
void (*status_notification)(struct tgl_user *U);
void (*user_registered)(struct tgl_user *U);

View File

@ -99,24 +99,28 @@ void tglu_work_update (struct connection *c, long long msg_id) {
break;
case CODE_update_user_typing:
{
//vlogprintf (E_ERROR, "user typing\n");
tgl_peer_id_t id = TGL_MK_USER (fetch_int ());
tgl_peer_t *U = tgl_peer_get (id);
enum tgl_typing_status status = tglf_fetch_typing ();
if (tgl_state.callback.type_notification && U) {
tgl_state.callback.type_notification ((void *)U);
tgl_state.callback.type_notification ((void *)U, status);
}
}
break;
case CODE_update_chat_user_typing:
{
//vlogprintf (E_ERROR, "chat typing\n");
tgl_peer_id_t chat_id = TGL_MK_CHAT (fetch_int ());
tgl_peer_id_t id = TGL_MK_USER (fetch_int ());
tgl_peer_t *C = tgl_peer_get (chat_id);
tgl_peer_t *U = tgl_peer_get (id);
enum tgl_typing_status status = tglf_fetch_typing ();
if (U && C) {
if (tgl_state.callback.type_in_chat_notification) {
tgl_state.callback.type_in_chat_notification ((void *)U, (void *)C);
tgl_state.callback.type_in_chat_notification ((void *)U, (void *)C, status);
}
}
}