2014-08-21 18:02:43 -04:00
|
|
|
/*
|
|
|
|
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 2013-2014
|
|
|
|
*/
|
2014-08-14 14:03:33 -04:00
|
|
|
#include "tgl.h"
|
|
|
|
#include "updates.h"
|
|
|
|
#include "mtproto-common.h"
|
|
|
|
#include "binlog.h"
|
|
|
|
#include "auto.h"
|
2014-08-14 18:16:01 -04:00
|
|
|
#include "structures.h"
|
2014-08-14 14:03:33 -04:00
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
void tglu_fetch_pts (void) {
|
|
|
|
int p = fetch_int ();
|
|
|
|
if (p <= tgl_state.pts) { return; }
|
2014-08-21 11:38:51 -04:00
|
|
|
/*if (p != tgl_state.pts + 1) {
|
2014-08-14 14:03:33 -04:00
|
|
|
if (tgl_state.pts) {
|
|
|
|
//vlogprintf (E_NOTICE, "Hole in pts p = %d, pts = %d\n", p, tgl_state.pts);
|
|
|
|
|
|
|
|
// get difference should be here
|
|
|
|
tgl_state.pts = p;
|
|
|
|
} else {
|
|
|
|
tgl_state.pts = p;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
tgl_state.pts ++;
|
2014-08-21 11:38:51 -04:00
|
|
|
}*/
|
2014-08-14 14:03:33 -04:00
|
|
|
bl_do_set_pts (tgl_state.pts);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tglu_fetch_qts (void) {
|
|
|
|
int p = fetch_int ();
|
|
|
|
if (p <= tgl_state.qts) { return; }
|
2014-08-21 11:38:51 -04:00
|
|
|
/*if (p != tgl_state.qts + 1) {
|
2014-08-14 14:03:33 -04:00
|
|
|
if (tgl_state.qts) {
|
|
|
|
//logprintf ("Hole in qts\n");
|
|
|
|
// get difference should be here
|
|
|
|
tgl_state.qts = p;
|
|
|
|
} else {
|
|
|
|
tgl_state.qts = p;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
tgl_state.qts ++;
|
2014-08-21 11:38:51 -04:00
|
|
|
}*/
|
2014-08-14 14:03:33 -04:00
|
|
|
bl_do_set_qts (tgl_state.qts);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tglu_fetch_date (void) {
|
|
|
|
int p = fetch_int ();
|
|
|
|
if (p > tgl_state.date) {
|
2014-08-21 11:38:51 -04:00
|
|
|
//tgl_state.date = p;
|
2014-08-14 14:03:33 -04:00
|
|
|
bl_do_set_date (tgl_state.date);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void tglu_fetch_seq (void) {
|
|
|
|
int x = fetch_int ();
|
|
|
|
if (x > tgl_state.seq + 1) {
|
|
|
|
vlogprintf (E_NOTICE, "Hole in seq: seq = %d, x = %d\n", tgl_state.seq, x);
|
|
|
|
//tgl_do_get_difference ();
|
|
|
|
//seq = x;
|
|
|
|
} else if (x == tgl_state.seq + 1) {
|
|
|
|
tgl_state.seq = x;
|
|
|
|
bl_do_set_seq (tgl_state.seq);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fetch_dc_option (void) {
|
|
|
|
assert (fetch_int () == CODE_dc_option);
|
|
|
|
int id = fetch_int ();
|
|
|
|
int l1 = prefetch_strlen ();
|
|
|
|
char *name = fetch_str (l1);
|
|
|
|
int l2 = prefetch_strlen ();
|
|
|
|
char *ip = fetch_str (l2);
|
|
|
|
int port = fetch_int ();
|
|
|
|
vlogprintf (E_DEBUG, "id = %d, name = %.*s ip = %.*s port = %d\n", id, l1, name, l2, ip, port);
|
|
|
|
|
|
|
|
bl_do_dc_option (id, l1, name, l2, ip, port);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tglu_work_update (struct connection *c, long long msg_id) {
|
|
|
|
unsigned op = fetch_int ();
|
|
|
|
switch (op) {
|
|
|
|
case CODE_update_new_message:
|
|
|
|
{
|
|
|
|
struct tgl_message *M = tglf_fetch_alloc_message ();
|
|
|
|
assert (M);
|
|
|
|
tglu_fetch_pts ();
|
|
|
|
|
|
|
|
//if (tgl_state.callback.new_msg) {
|
|
|
|
// tgl_state.callback.new_msg (M);
|
|
|
|
//}
|
|
|
|
//unread_messages ++;
|
|
|
|
//print_message (M);
|
|
|
|
//update_prompt ();
|
|
|
|
break;
|
|
|
|
};
|
|
|
|
case CODE_update_message_i_d:
|
|
|
|
{
|
|
|
|
int id = fetch_int (); // id
|
|
|
|
int new = fetch_long (); // random_id
|
|
|
|
struct tgl_message *M = tgl_message_get (new);
|
|
|
|
if (M) {
|
|
|
|
bl_do_set_msg_id (M, id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_read_messages:
|
|
|
|
{
|
|
|
|
assert (fetch_int () == (int)CODE_vector);
|
|
|
|
int n = fetch_int ();
|
|
|
|
|
|
|
|
//int p = 0;
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
int id = fetch_int ();
|
|
|
|
struct tgl_message *M = tgl_message_get (id);
|
|
|
|
if (M) {
|
|
|
|
bl_do_set_unread (M, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tglu_fetch_pts ();
|
|
|
|
/*if (log_level >= 1) {
|
|
|
|
print_start ();
|
|
|
|
push_color (COLOR_YELLOW);
|
|
|
|
print_date (time (0));
|
|
|
|
printf (" %d messages marked as read\n", n);
|
|
|
|
pop_color ();
|
|
|
|
print_end ();
|
|
|
|
}*/
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_user_typing:
|
|
|
|
{
|
|
|
|
tgl_peer_id_t id = TGL_MK_USER (fetch_int ());
|
|
|
|
tgl_peer_t *U = tgl_peer_get (id);
|
|
|
|
|
|
|
|
if (tgl_state.callback.type_notification && U) {
|
|
|
|
tgl_state.callback.type_notification ((void *)U);
|
|
|
|
}
|
|
|
|
/*if (log_level >= 2) {
|
|
|
|
print_start ();
|
|
|
|
push_color (COLOR_YELLOW);
|
|
|
|
print_date (time (0));
|
|
|
|
printf (" User ");
|
|
|
|
print_user_name (id, U);
|
|
|
|
printf (" is typing....\n");
|
|
|
|
pop_color ();
|
|
|
|
print_end ();
|
|
|
|
}*/
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_chat_user_typing:
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
|
|
|
|
if (U && C) {
|
|
|
|
if (tgl_state.callback.type_in_chat_notification) {
|
|
|
|
tgl_state.callback.type_in_chat_notification ((void *)U, (void *)C);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*if (log_level >= 2) {
|
|
|
|
print_start ();
|
|
|
|
push_color (COLOR_YELLOW);
|
|
|
|
print_date (time (0));
|
|
|
|
printf (" User ");
|
|
|
|
print_user_name (id, U);
|
|
|
|
printf (" is typing in chat ");
|
|
|
|
print_chat_name (chat_id, C);
|
|
|
|
printf ("....\n");
|
|
|
|
pop_color ();
|
|
|
|
print_end ();
|
|
|
|
}*/
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_user_status:
|
|
|
|
{
|
|
|
|
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
|
|
|
|
tgl_peer_t *U = tgl_peer_get (user_id);
|
|
|
|
if (U) {
|
|
|
|
tglf_fetch_user_status (&U->user.status);
|
|
|
|
|
|
|
|
if (tgl_state.callback.status_notification) {
|
|
|
|
tgl_state.callback.status_notification ((void *)U);
|
|
|
|
}
|
|
|
|
/*if (log_level >= 3) {
|
|
|
|
print_start ();
|
|
|
|
push_color (COLOR_YELLOW);
|
|
|
|
print_date (time (0));
|
|
|
|
printf (" User ");
|
|
|
|
print_user_name (user_id, U);
|
|
|
|
printf (" is now ");
|
|
|
|
printf ("%s\n", (U->user.status.online > 0) ? "online" : "offline");
|
|
|
|
pop_color ();
|
|
|
|
print_end ();
|
|
|
|
}*/
|
|
|
|
} else {
|
|
|
|
struct tgl_user_status t;
|
|
|
|
tglf_fetch_user_status (&t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_user_name:
|
|
|
|
{
|
|
|
|
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
|
|
|
|
tgl_peer_t *UC = tgl_peer_get (user_id);
|
|
|
|
if (UC && (UC->flags & FLAG_CREATED)) {
|
|
|
|
int l1 = prefetch_strlen ();
|
|
|
|
char *f = fetch_str (l1);
|
|
|
|
int l2 = prefetch_strlen ();
|
|
|
|
char *l = fetch_str (l2);
|
|
|
|
struct tgl_user *U = &UC->user;
|
|
|
|
bl_do_user_set_real_name (U, f, l1, l, l2);
|
|
|
|
/*print_start ();
|
|
|
|
push_color (COLOR_YELLOW);
|
|
|
|
print_date (time (0));
|
|
|
|
printf (" User ");
|
|
|
|
print_user_name (user_id, UC);
|
|
|
|
printf (" changed name to ");
|
|
|
|
print_user_name (user_id, UC);
|
|
|
|
printf ("\n");
|
|
|
|
pop_color ();
|
|
|
|
print_end ();*/
|
|
|
|
} else {
|
|
|
|
fetch_skip_str ();
|
|
|
|
fetch_skip_str ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_user_photo:
|
|
|
|
{
|
|
|
|
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
|
|
|
|
tgl_peer_t *UC = tgl_peer_get (user_id);
|
|
|
|
tglu_fetch_date ();
|
|
|
|
if (UC && (UC->flags & FLAG_CREATED)) {
|
|
|
|
struct tgl_user *U = &UC->user;
|
|
|
|
unsigned y = fetch_int ();
|
|
|
|
long long photo_id;
|
|
|
|
struct tgl_file_location big;
|
|
|
|
struct tgl_file_location small;
|
|
|
|
memset (&big, 0, sizeof (big));
|
|
|
|
memset (&small, 0, sizeof (small));
|
|
|
|
if (y == CODE_user_profile_photo_empty) {
|
|
|
|
photo_id = 0;
|
|
|
|
big.dc = -2;
|
|
|
|
small.dc = -2;
|
|
|
|
} else {
|
|
|
|
assert (y == CODE_user_profile_photo);
|
|
|
|
photo_id = fetch_long ();
|
|
|
|
tglf_fetch_file_location (&small);
|
|
|
|
tglf_fetch_file_location (&big);
|
|
|
|
}
|
|
|
|
bl_do_set_user_profile_photo (U, photo_id, &big, &small);
|
|
|
|
|
|
|
|
/*print_start ();
|
|
|
|
push_color (COLOR_YELLOW);
|
|
|
|
print_date (time (0));
|
|
|
|
printf (" User ");
|
|
|
|
print_user_name (user_id, UC);
|
|
|
|
printf (" updated profile photo\n");
|
|
|
|
pop_color ();
|
|
|
|
print_end ();*/
|
|
|
|
} else {
|
|
|
|
struct tgl_file_location t;
|
|
|
|
unsigned y = fetch_int ();
|
|
|
|
if (y == CODE_user_profile_photo_empty) {
|
|
|
|
} else {
|
|
|
|
assert (y == CODE_user_profile_photo);
|
|
|
|
fetch_long (); // photo_id
|
|
|
|
tglf_fetch_file_location (&t);
|
|
|
|
tglf_fetch_file_location (&t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fetch_bool ();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_restore_messages:
|
|
|
|
{
|
|
|
|
assert (fetch_int () == CODE_vector);
|
|
|
|
int n = fetch_int ();
|
|
|
|
/*print_start ();
|
|
|
|
push_color (COLOR_YELLOW);
|
|
|
|
print_date (time (0));
|
|
|
|
printf (" Restored %d messages\n", n);
|
|
|
|
pop_color ();
|
|
|
|
print_end ();*/
|
|
|
|
fetch_skip (n);
|
|
|
|
tglu_fetch_pts ();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_delete_messages:
|
|
|
|
{
|
|
|
|
assert (fetch_int () == CODE_vector);
|
|
|
|
int n = fetch_int ();
|
|
|
|
/*print_start ();
|
|
|
|
push_color (COLOR_YELLOW);
|
|
|
|
print_date (time (0));
|
|
|
|
printf (" Deleted %d messages\n", n);
|
|
|
|
pop_color ();
|
|
|
|
print_end ();*/
|
|
|
|
fetch_skip (n);
|
|
|
|
tglu_fetch_pts ();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_chat_participants:
|
|
|
|
{
|
|
|
|
unsigned x = fetch_int ();
|
|
|
|
assert (x == CODE_chat_participants || x == CODE_chat_participants_forbidden);
|
|
|
|
tgl_peer_id_t chat_id = TGL_MK_CHAT (fetch_int ());
|
|
|
|
int n = 0;
|
|
|
|
tgl_peer_t *C = tgl_peer_get (chat_id);
|
|
|
|
if (C && (C->flags & FLAG_CREATED)) {
|
|
|
|
if (x == CODE_chat_participants) {
|
|
|
|
bl_do_chat_set_admin (&C->chat, fetch_int ());
|
|
|
|
assert (fetch_int () == CODE_vector);
|
|
|
|
n = fetch_int ();
|
|
|
|
struct tgl_chat_user *users = talloc (12 * n);
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
assert (fetch_int () == (int)CODE_chat_participant);
|
|
|
|
users[i].user_id = fetch_int ();
|
|
|
|
users[i].inviter_id = fetch_int ();
|
|
|
|
users[i].date = fetch_int ();
|
|
|
|
}
|
|
|
|
int version = fetch_int ();
|
|
|
|
bl_do_chat_set_participants (&C->chat, version, n, users);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (x == CODE_chat_participants) {
|
|
|
|
fetch_int (); // admin_id
|
|
|
|
assert (fetch_int () == CODE_vector);
|
|
|
|
n = fetch_int ();
|
|
|
|
fetch_skip (n * 4);
|
|
|
|
fetch_int (); // version
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*print_start ();
|
|
|
|
push_color (COLOR_YELLOW);
|
|
|
|
print_date (time (0));
|
|
|
|
printf (" Chat ");
|
|
|
|
print_chat_name (chat_id, C);
|
|
|
|
if (x == CODE_chat_participants) {
|
|
|
|
printf (" changed list: now %d members\n", n);
|
|
|
|
} else {
|
|
|
|
printf (" changed list, but we are forbidden to know about it (Why this update even was sent to us?\n");
|
|
|
|
}
|
|
|
|
pop_color ();
|
|
|
|
print_end ();*/
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_contact_registered:
|
|
|
|
{
|
|
|
|
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
|
|
|
|
tgl_peer_t *U = tgl_peer_get (user_id);
|
|
|
|
fetch_int (); // date
|
|
|
|
if (tgl_state.callback.user_registered && U) {
|
|
|
|
tgl_state.callback.user_registered ((void *)U);
|
|
|
|
}
|
|
|
|
/*print_start ();
|
|
|
|
push_color (COLOR_YELLOW);
|
|
|
|
print_date (time (0));
|
|
|
|
printf (" User ");
|
|
|
|
print_user_name (user_id, U);
|
|
|
|
printf (" registered\n");
|
|
|
|
pop_color ();
|
|
|
|
print_end ();*/
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_contact_link:
|
|
|
|
{
|
|
|
|
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
|
|
|
|
tgl_peer_t *U = tgl_peer_get (user_id);
|
|
|
|
/*print_start ();
|
|
|
|
push_color (COLOR_YELLOW);
|
|
|
|
print_date (time (0));
|
|
|
|
printf (" Updated link with user ");
|
|
|
|
print_user_name (user_id, U);
|
|
|
|
printf ("\n");
|
|
|
|
pop_color ();
|
|
|
|
print_end ();*/
|
|
|
|
unsigned t = fetch_int ();
|
|
|
|
assert (t == CODE_contacts_my_link_empty || t == CODE_contacts_my_link_requested || t == CODE_contacts_my_link_contact);
|
|
|
|
if (t == CODE_contacts_my_link_requested) {
|
|
|
|
fetch_bool (); // has_phone
|
|
|
|
}
|
|
|
|
t = fetch_int ();
|
|
|
|
assert (t == CODE_contacts_foreign_link_unknown || t == CODE_contacts_foreign_link_requested || t == CODE_contacts_foreign_link_mutual);
|
|
|
|
if (t == CODE_contacts_foreign_link_requested) {
|
|
|
|
fetch_bool (); // has_phone
|
|
|
|
}
|
|
|
|
if (U) {}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_activation:
|
|
|
|
{
|
|
|
|
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
|
|
|
|
tgl_peer_t *U = tgl_peer_get (user_id);
|
|
|
|
|
|
|
|
if (tgl_state.callback.user_activated && U) {
|
|
|
|
tgl_state.callback.user_activated ((void *)U);
|
|
|
|
}
|
|
|
|
/*print_start ();
|
|
|
|
push_color (COLOR_YELLOW);
|
|
|
|
print_date (time (0));
|
|
|
|
printf (" User ");
|
|
|
|
print_user_name (user_id, U);
|
|
|
|
printf (" activated\n");
|
|
|
|
pop_color ();
|
|
|
|
print_end ();*/
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_new_authorization:
|
|
|
|
{
|
|
|
|
fetch_long (); // auth_key_id
|
|
|
|
fetch_int (); // date
|
|
|
|
char *s = fetch_str_dup ();
|
|
|
|
char *location = fetch_str_dup ();
|
|
|
|
/*print_start ();
|
|
|
|
push_color (COLOR_YELLOW);
|
|
|
|
print_date (time (0));
|
|
|
|
printf (" New autorization: device='%s' location='%s'\n",
|
|
|
|
s, location);
|
|
|
|
pop_color ();
|
|
|
|
print_end ();*/
|
|
|
|
if (tgl_state.callback.new_authorization) {
|
|
|
|
tgl_state.callback.new_authorization (s, location);
|
|
|
|
}
|
|
|
|
tfree_str (s);
|
|
|
|
tfree_str (location);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_new_geo_chat_message:
|
|
|
|
{
|
|
|
|
struct tgl_message *M = tglf_fetch_alloc_geo_message ();
|
|
|
|
assert (M);
|
|
|
|
//if (tgl_state.callback.new_msg) {
|
|
|
|
// tgl_state.callback.new_msg (M);
|
|
|
|
//}
|
|
|
|
//unread_messages ++;
|
|
|
|
//print_message (M);
|
|
|
|
//update_prompt ();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_new_encrypted_message:
|
|
|
|
{
|
|
|
|
struct tgl_message *M = tglf_fetch_alloc_encrypted_message ();
|
|
|
|
assert (M);
|
|
|
|
//unread_messages ++;
|
|
|
|
//print_message (M);
|
|
|
|
//update_prompt ();
|
|
|
|
tglu_fetch_qts ();
|
|
|
|
//if (tgl_state.callback.new_msg) {
|
|
|
|
// tgl_state.callback.new_msg (M);
|
|
|
|
//}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_encryption:
|
|
|
|
{
|
|
|
|
struct tgl_secret_chat *E = tglf_fetch_alloc_encrypted_chat ();
|
|
|
|
vlogprintf (E_DEBUG, "Secret chat state = %d\n", E->state);
|
|
|
|
/*print_start ();
|
|
|
|
push_color (COLOR_YELLOW);
|
|
|
|
print_date (time (0));
|
|
|
|
switch (E->state) {
|
|
|
|
case sc_none:
|
|
|
|
break;
|
|
|
|
case sc_waiting:
|
|
|
|
printf (" Encrypted chat ");
|
|
|
|
print_encr_chat_name (E->id, (void *)E);
|
|
|
|
printf (" is now in wait state\n");
|
|
|
|
break;
|
|
|
|
case sc_request:
|
|
|
|
printf (" Encrypted chat ");
|
|
|
|
print_encr_chat_name (E->id, (void *)E);
|
|
|
|
printf (" is now in request state. Sending request ok\n");
|
|
|
|
break;
|
|
|
|
case sc_ok:
|
|
|
|
printf (" Encrypted chat ");
|
|
|
|
print_encr_chat_name (E->id, (void *)E);
|
|
|
|
printf (" is now in ok state\n");
|
|
|
|
break;
|
|
|
|
case sc_deleted:
|
|
|
|
printf (" Encrypted chat ");
|
|
|
|
print_encr_chat_name (E->id, (void *)E);
|
|
|
|
printf (" is now in deleted state\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
pop_color ();
|
|
|
|
print_end ();*/
|
|
|
|
|
2014-08-19 08:57:55 -04:00
|
|
|
/*if (E->state == sc_request) {
|
|
|
|
if (tgl_state.callback.secret_chat_update) {
|
2014-08-14 14:03:33 -04:00
|
|
|
tgl_state.callback.secret_chat_request (E);
|
|
|
|
}
|
|
|
|
} else if (E->state == sc_ok) {
|
|
|
|
if (tgl_state.callback.secret_chat_established) {
|
|
|
|
tgl_state.callback.secret_chat_established (E);
|
|
|
|
}
|
|
|
|
} else if (E->state == sc_deleted) {
|
|
|
|
if (tgl_state.callback.secret_chat_deleted) {
|
|
|
|
tgl_state.callback.secret_chat_deleted (E);
|
|
|
|
}
|
2014-08-19 08:57:55 -04:00
|
|
|
}*/
|
2014-08-14 14:03:33 -04:00
|
|
|
if (E->state == sc_ok) {
|
|
|
|
tgl_do_send_encr_chat_layer (E);
|
|
|
|
}
|
|
|
|
fetch_int (); // date
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_encrypted_chat_typing:
|
|
|
|
{
|
|
|
|
tgl_peer_id_t id = TGL_MK_ENCR_CHAT (fetch_int ());
|
|
|
|
tgl_peer_t *P = tgl_peer_get (id);
|
|
|
|
|
|
|
|
if (P) {
|
|
|
|
if (tgl_state.callback.type_in_secret_chat_notification) {
|
|
|
|
tgl_state.callback.type_in_secret_chat_notification ((void *)P);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*print_start ();
|
|
|
|
push_color (COLOR_YELLOW);
|
|
|
|
print_date (time (0));
|
|
|
|
if (P) {
|
|
|
|
printf (" User ");
|
|
|
|
tgl_peer_id_t user_id = TGL_MK_USER (P->encr_chat.user_id);
|
|
|
|
print_user_name (user_id, tgl_peer_get (user_id));
|
|
|
|
printf (" typing in secret chat ");
|
|
|
|
print_encr_chat_name (id, P);
|
|
|
|
printf ("\n");
|
|
|
|
} else {
|
|
|
|
printf (" Some user is typing in unknown secret chat\n");
|
|
|
|
}
|
|
|
|
pop_color ();
|
|
|
|
print_end ();*/
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_encrypted_messages_read:
|
|
|
|
{
|
|
|
|
tgl_peer_id_t id = TGL_MK_ENCR_CHAT (fetch_int ()); // chat_id
|
|
|
|
fetch_int (); // max_date
|
|
|
|
fetch_int (); // date
|
|
|
|
tgl_peer_t *P = tgl_peer_get (id);
|
|
|
|
//int x = -1;
|
|
|
|
if (P && P->last) {
|
|
|
|
//x = 0;
|
|
|
|
struct tgl_message *M = P->last;
|
|
|
|
while (M && (!M->out || M->unread)) {
|
|
|
|
if (M->out) {
|
|
|
|
bl_do_set_unread (M, 0);
|
|
|
|
}
|
|
|
|
M = M->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*if (log_level >= 1) {
|
|
|
|
print_start ();
|
|
|
|
push_color (COLOR_YELLOW);
|
|
|
|
print_date (time (0));
|
|
|
|
printf (" Encrypted chat ");
|
|
|
|
print_encr_chat_name_full (id, tgl_peer_get (id));
|
|
|
|
printf (": %d messages marked read \n", x);
|
|
|
|
pop_color ();
|
|
|
|
print_end ();
|
|
|
|
}*/
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_chat_participant_add:
|
|
|
|
{
|
|
|
|
tgl_peer_id_t chat_id = TGL_MK_CHAT (fetch_int ());
|
|
|
|
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
|
|
|
|
tgl_peer_id_t inviter_id = TGL_MK_USER (fetch_int ());
|
|
|
|
int version = fetch_int ();
|
|
|
|
|
|
|
|
tgl_peer_t *C = tgl_peer_get (chat_id);
|
|
|
|
if (C && (C->flags & FLAG_CREATED)) {
|
|
|
|
bl_do_chat_add_user (&C->chat, version, tgl_get_peer_id (user_id), tgl_get_peer_id (inviter_id), time (0));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*print_start ();
|
|
|
|
push_color (COLOR_YELLOW);
|
|
|
|
print_date (time (0));
|
|
|
|
printf (" Chat ");
|
|
|
|
print_chat_name (chat_id, tgl_peer_get (chat_id));
|
|
|
|
printf (": user ");
|
|
|
|
print_user_name (user_id, tgl_peer_get (user_id));
|
|
|
|
printf (" added by user ");
|
|
|
|
print_user_name (inviter_id, tgl_peer_get (inviter_id));
|
|
|
|
printf ("\n");
|
|
|
|
pop_color ();
|
|
|
|
print_end ();*/
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_chat_participant_delete:
|
|
|
|
{
|
|
|
|
tgl_peer_id_t chat_id = TGL_MK_CHAT (fetch_int ());
|
|
|
|
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
|
|
|
|
int version = fetch_int ();
|
|
|
|
|
|
|
|
tgl_peer_t *C = tgl_peer_get (chat_id);
|
|
|
|
if (C && (C->flags & FLAG_CREATED)) {
|
|
|
|
bl_do_chat_del_user (&C->chat, version, tgl_get_peer_id (user_id));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*print_start ();
|
|
|
|
push_color (COLOR_YELLOW);
|
|
|
|
print_date (time (0));
|
|
|
|
printf (" Chat ");
|
|
|
|
print_chat_name (chat_id, tgl_peer_get (chat_id));
|
|
|
|
printf (": user ");
|
|
|
|
print_user_name (user_id, tgl_peer_get (user_id));
|
|
|
|
printf (" deleted\n");
|
|
|
|
pop_color ();
|
|
|
|
print_end ();*/
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_dc_options:
|
|
|
|
{
|
|
|
|
assert (fetch_int () == CODE_vector);
|
|
|
|
int n = fetch_int ();
|
|
|
|
assert (n >= 0);
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
fetch_dc_option ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_user_blocked:
|
|
|
|
{
|
|
|
|
int id = fetch_int ();
|
|
|
|
int blocked = fetch_bool ();
|
|
|
|
tgl_peer_t *P = tgl_peer_get (TGL_MK_USER (id));
|
|
|
|
if (P && (P->flags & FLAG_CREATED)) {
|
|
|
|
bl_do_user_set_blocked (&P->user, blocked);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CODE_update_notify_settings:
|
|
|
|
{
|
|
|
|
assert (skip_type_any (TYPE_TO_PARAM (notify_peer)) >= 0);
|
|
|
|
assert (skip_type_any (TYPE_TO_PARAM (peer_notify_settings)) >= 0);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
vlogprintf (E_ERROR, "Unknown update type %08x\n", op);
|
|
|
|
;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void tglu_work_update_short (struct connection *c, long long msg_id) {
|
|
|
|
int *save = in_ptr;
|
|
|
|
assert (!skip_type_any (TYPE_TO_PARAM (updates)));
|
|
|
|
int *save_end = in_ptr;
|
|
|
|
in_ptr = save;
|
|
|
|
|
|
|
|
assert (fetch_int () == CODE_update_short);
|
|
|
|
tglu_work_update (c, msg_id);
|
|
|
|
tglu_fetch_date ();
|
|
|
|
|
|
|
|
assert (save_end == in_ptr);
|
|
|
|
}
|
2014-08-20 12:36:45 -04:00
|
|
|
|
|
|
|
static int do_skip_seq (int seq) {
|
|
|
|
if (tgl_state.seq) {
|
|
|
|
if (seq <= tgl_state.seq) {
|
|
|
|
vlogprintf (E_NOTICE, "Duplicate message with seq=%d\n", seq);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (seq > tgl_state.seq + 1) {
|
|
|
|
vlogprintf (E_NOTICE, "Hole in seq (seq = %d, cur_seq = %d)\n", seq, tgl_state.seq);
|
|
|
|
tgl_do_get_difference (0, 0, 0);
|
|
|
|
return -1;
|
|
|
|
}
|
2014-08-21 11:38:51 -04:00
|
|
|
if (tgl_state.locks & TGL_LOCK_DIFF) {
|
|
|
|
return -1;
|
|
|
|
}
|
2014-08-20 12:36:45 -04:00
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2014-08-14 14:03:33 -04:00
|
|
|
|
|
|
|
void tglu_work_updates (struct connection *c, long long msg_id) {
|
|
|
|
int *save = in_ptr;
|
|
|
|
assert (!skip_type_any (TYPE_TO_PARAM (updates)));
|
2014-08-20 12:36:45 -04:00
|
|
|
if (do_skip_seq (*(in_ptr - 1)) < 0) {
|
|
|
|
return;
|
|
|
|
}
|
2014-08-14 14:03:33 -04:00
|
|
|
int *save_end = in_ptr;
|
|
|
|
in_ptr = save;
|
|
|
|
assert (fetch_int () == CODE_updates);
|
|
|
|
assert (fetch_int () == CODE_vector);
|
|
|
|
int n = fetch_int ();
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
tglu_work_update (c, msg_id);
|
|
|
|
}
|
|
|
|
assert (fetch_int () == CODE_vector);
|
|
|
|
n = fetch_int ();
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
tglf_fetch_alloc_user ();
|
|
|
|
}
|
|
|
|
assert (fetch_int () == CODE_vector);
|
|
|
|
n = fetch_int ();
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
tglf_fetch_alloc_chat ();
|
|
|
|
}
|
|
|
|
bl_do_set_date (fetch_int ());
|
2014-08-20 12:36:45 -04:00
|
|
|
//bl_do_set_seq (fetch_int ());
|
|
|
|
fetch_int ();
|
2014-08-14 14:03:33 -04:00
|
|
|
assert (save_end == in_ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tglu_work_update_short_message (struct connection *c, long long msg_id) {
|
|
|
|
int *save = in_ptr;
|
|
|
|
assert (!skip_type_any (TYPE_TO_PARAM (updates)));
|
2014-08-20 12:36:45 -04:00
|
|
|
if (do_skip_seq (*(in_ptr - 1)) < 0) {
|
|
|
|
return;
|
|
|
|
}
|
2014-08-14 14:03:33 -04:00
|
|
|
int *save_end = in_ptr;
|
|
|
|
in_ptr = save;
|
|
|
|
|
|
|
|
assert (fetch_int () == (int)CODE_update_short_message);
|
|
|
|
struct tgl_message *M = tglf_fetch_alloc_message_short ();
|
|
|
|
assert (M);
|
|
|
|
/*unread_messages ++;
|
|
|
|
print_message (M);
|
|
|
|
update_prompt ();
|
|
|
|
if (M->date > last_date) {
|
|
|
|
last_date = M->date;
|
|
|
|
}*/
|
|
|
|
|
|
|
|
assert (save_end == in_ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tglu_work_update_short_chat_message (struct connection *c, long long msg_id) {
|
|
|
|
int *save = in_ptr;
|
|
|
|
assert (!skip_type_any (TYPE_TO_PARAM (updates)));
|
2014-08-20 12:36:45 -04:00
|
|
|
if (do_skip_seq (*(in_ptr - 1)) < 0) {
|
|
|
|
return;
|
|
|
|
}
|
2014-08-14 14:03:33 -04:00
|
|
|
int *save_end = in_ptr;
|
|
|
|
in_ptr = save;
|
|
|
|
|
|
|
|
assert (fetch_int () == CODE_update_short_chat_message);
|
|
|
|
struct tgl_message *M = tglf_fetch_alloc_message_short_chat ();
|
|
|
|
assert (M);
|
|
|
|
/*unread_messages ++;
|
|
|
|
print_message (M);
|
|
|
|
update_prompt ();
|
|
|
|
if (M->date > last_date) {
|
|
|
|
last_date = M->date;
|
|
|
|
}*/
|
|
|
|
assert (save_end == in_ptr);
|
2014-08-20 12:36:45 -04:00
|
|
|
|
|
|
|
bl_do_msg_seq_update (M->id);
|
2014-08-14 14:03:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void tglu_work_updates_to_long (struct connection *c, long long msg_id) {
|
|
|
|
assert (fetch_int () == (int)CODE_updates_too_long);
|
2014-08-19 08:57:55 -04:00
|
|
|
vlogprintf (E_NOTICE, "updates too long... Getting difference\n");
|
2014-08-14 14:03:33 -04:00
|
|
|
tgl_do_get_difference (0, 0, 0);
|
|
|
|
}
|