Telegram user contacts La query per l'address book è la seguente: SQLiteCursor cursor = database.queryFinalized("SELECT us.uid, us.fname, us.sname, up.phone, up.sphone, up.deleted FROM user_contacts_v6 as us LEFT JOIN user_phones_v6 as up ON us.uid = up.uid WHERE 1"); in user_contacts_v6 sono presenti i nomi interni (user names telegram), mentre nella tabella user_phones_v6 sono presenti i numeri di telefono. message deserialization I messaggi vengono decrittati attraverso ConnectionsManager.tcpConnectionReceivedData() e salvati su database sqlite. Durante la creazione dell'Activity ChatActivity i messaggi vengono gestiti dal NotificationCenter che li loada tramite MessagesStorage.loadmessages() Dentro questa funzione viene effettivamente fatta la query al db SQLite, attraverso il metodo getMessages() il quale ricerca i messaggi in base all'user id. ... cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d ORDER BY m.mid ASC LIMIT %d,%d", dialog_id, offset_query, count_query)); while (cursor.next()) { byte[] messageData = cursor.byteArrayValue(1); if (messageData != null) { String msgd = FileLog.byteArrayToHex(messageData); FileLog.d("olli-msg-storage","message data is " + msgd); SerializedData data = new SerializedData(messageData); TLRPC.Message message = (TLRPC.Message)TLClassStore.Instance().TLdeserialize(data, data.readInt32()); int read_state = cursor.intValue(0); message.unread = (cursor.intValue(0) != 1); message.id = cursor.intValue(3); message.date = cursor.intValue(4); message.dialog_id = dialog_id; res.messages.add(message); fromUser.add(message.from_id); if (message.action != null && message.action.user_id != 0) { fromUser.add(message.action.user_id); } if (message.media != null && message.media.user_id != 0) { fromUser.add(message.media.user_id); } if (message.media != null && message.media.audio != null && message.media.audio.user_id != 0) { fromUser.add(message.media.audio.user_id); } if (message.fwd_from_id != 0) { fromUser.add(message.fwd_from_id); } message.send_state = cursor.intValue(2); if (!message.unread || message.id > 0) { message.send_state = 0; } if (lower_id == 0 && !cursor.isNull(5)) { message.random_id = cursor.longValue(5); } } } cursor.dispose(); a questo punto res.messages è un array pieno di messagi DEserializzati. La deserializzazione avviene in questa riga: TLRPC.Message message = (TLRPC.Message)TLClassStore.Instance().TLdeserialize(data, data.readInt32()); rispettivamente: public TLObject TLdeserialize(AbsSerializedData stream, int constructor) { try { return TLdeserialize(stream, constructor, null); } catch (Exception e) { return null; } } che richiama TLdeserialize public TLObject TLdeserialize(AbsSerializedData stream, int constructor, TLObject request) { Class objClass = classStore.get(constructor); if (objClass != null) { try { TLObject response = (TLObject)objClass.newInstance(); if (response instanceof TLRPC.Vector) { if (request != null) { request.parseVector((TLRPC.Vector)response, stream); } else { int size = stream.readInt32(); for (int a = 0; a < size; a++) { ((TLRPC.Vector)response).objects.add(stream.readInt32()); } } } else { response.readParams(stream); <-------------------- deserialization comes here only reading params from stream } return response; } catch (IllegalAccessException e) { FileLog.e("tmessages", "can't create class"); return null; } catch (InstantiationException e2) { FileLog.e("tmessages", "can't create class"); return null; } } else { FileLog.e("tmessages", String.format("unknown class %x", constructor)); return null; //throw new RuntimeException(String.format("unknown class %x", constructor)); } } come si evince dai log le classi coinvolte sono le seguenti: D/olli-msg-storage(21278): message deserialized class is org.telegram.messenger.TLRPC$TL_message@41b9d0d8 message qualcosa D/olli-msg-storage(21278): message deserialized class is org.telegram.messenger.TLRPC$TL_message@41c1eee8 message Sxrivi qualcoa D/olli-msg-storage(21278): message deserialized class is org.telegram.messenger.TLRPC$TL_message@41ca5ef0 message Storico D/olli-msg-storage(21278): message deserialized class is org.telegram.messenger.TLRPC$TL_message@41bf2220 message Atorico D/olli-msg-storage(21278): message deserialized class is org.telegram.messenger.TLRPC$TL_message@41cb26f0 message Non vwdo lo Sto root D/olli-msg-storage(21278): message deserialized class is org.telegram.messenger.TLRPC$TL_message@41c3a568 message ciao D/olli-msg-storage(21278): message deserialized class is org.telegram.messenger.TLRPC$TL_message@41caa5a0 message deh ecco le rispettive strutture: public class TLObject { public TLObject () { } public void readParams(AbsSerializedData stream) { } public byte[] serialize () { return null; } public void serializeToStream(AbsSerializedData stream) { } public Class responseClass () { return this.getClass(); } public int layer () { return 11; } public void parseVector(TLRPC.Vector vector, AbsSerializedData data) { } public void freeResources() { } } public static class Message extends TLObject { public int id; public int fwd_from_id; public int fwd_date; public int from_id; public Peer to_id; public boolean out; public boolean unread; public int date; public String message; public MessageMedia media; public MessageAction action; public int send_state = 0; public int fwd_msg_id = 0; public String attachPath = ""; public long random_id; public int local_id = 0; public long dialog_id; public int ttl; } public static class TL_messageForwarded extends Message { public static int constructor = 0x5f46804; public void readParams(AbsSerializedData stream) { id = stream.readInt32(); fwd_from_id = stream.readInt32(); fwd_date = stream.readInt32(); from_id = stream.readInt32(); to_id = (Peer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); out = stream.readBool(); unread = stream.readBool(); date = stream.readInt32(); message = stream.readString(); media = (MessageMedia)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); if (id < 0) { fwd_msg_id = stream.readInt32(); } if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && message != null && message.length() != 0 && message.equals("-1"))) { attachPath = stream.readString(); } } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); stream.writeInt32(id); stream.writeInt32(fwd_from_id); stream.writeInt32(fwd_date); stream.writeInt32(from_id); to_id.serializeToStream(stream); stream.writeBool(out); stream.writeBool(unread); stream.writeInt32(date); stream.writeString(message); media.serializeToStream(stream); if (id < 0) { stream.writeInt32(fwd_msg_id); } stream.writeString(attachPath); } } public static class TL_message extends Message { public static int constructor = 0x22eb6aba; public void readParams(AbsSerializedData stream) { id = stream.readInt32(); from_id = stream.readInt32(); to_id = (Peer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); out = stream.readBool(); unread = stream.readBool(); date = stream.readInt32(); message = stream.readString(); media = (MessageMedia)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && message != null && message.length() != 0 && message.equals("-1"))) { attachPath = stream.readString(); } } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); stream.writeInt32(id); stream.writeInt32(from_id); to_id.serializeToStream(stream); stream.writeBool(out); stream.writeBool(unread); stream.writeInt32(date); stream.writeString(message); media.serializeToStream(stream); stream.writeString(attachPath); } } public void writeByteArray(byte[] b, int offset, int count) { try { if(count <= 253) { if (!justCalc) { out.write(count); } else { len += 1; } } else { if (!justCalc) { out.write(254); out.write(count); out.write(count >> 8); out.write(count >> 16); } else { len += 4; } } if (!justCalc) { out.write(b, offset, count); } else { len += count; } int i = count <= 253 ? 1 : 4; while ((count + i) % 4 != 0) { if (!justCalc) { out.write(0); } else { len += 1; } i++; } } catch (Exception x) { FileLog.e("tmessages", "write byte array error"); } } "SELECT q.data, q.name, q.user, q.g, q.authkey, q.ttl, u.data, u.status FROM enc_chats as q INNER JOIN dialogs as d ON (q.uid << 32) = d.did INNER JOIN users as u ON q.user = u.uid" messaggi: public static class TL_message extends Message { public static int constructor = 0x22eb6aba; public void readParams(AbsSerializedData stream) { FileLog.d("olli-tl_message","Stream is " + stream.toString()); id = stream.readInt32(); from_id = stream.readInt32(); to_id = (Peer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); out = stream.readBool(); unread = stream.readBool(); date = stream.readInt32(); message = stream.readString(); FileLog.d("olli-tl_message","this is da message??? " + message); media = (MessageMedia)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && message != null && message.length() != 0 && message.equals("-1"))) { attachPath = stream.readString(); } } username: public static class TL_userSelf extends User { public static int constructor = 0x720535ec; public void readParams(AbsSerializedData stream) { id = stream.readInt32(); first_name = stream.readString(); last_name = stream.readString(); phone = stream.readString(); photo = (UserProfilePhoto)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); status = (UserStatus)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); inactive = stream.readBool(); } encrypted chat: public static class TL_encryptedChat extends EncryptedChat { public static int constructor = 0xfa56ce36; public void readParams(AbsSerializedData stream) { id = stream.readInt32(); access_hash = stream.readInt64(); date = stream.readInt32(); admin_id = stream.readInt32(); participant_id = stream.readInt32(); g_a_or_b = stream.readByteArray(); key_fingerprint = stream.readInt64(); } participants: public static class TL_chatParticipants extends ChatParticipants { public static int constructor = 0x7841b415; public void readParams(AbsSerializedData stream) { chat_id = stream.readInt32(); admin_id = stream.readInt32(); stream.readInt32(); int count = stream.readInt32(); for (int a = 0; a < count; a++) { participants.add((TL_chatParticipant)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); } version = stream.readInt32(); } chat: public static class TL_chat extends Chat { public static int constructor = 0x6e9c9bc7; public void readParams(AbsSerializedData stream) { id = stream.readInt32(); title = stream.readString(); photo = (ChatPhoto)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); participants_count = stream.readInt32(); date = stream.readInt32(); left = stream.readBool(); version = stream.readInt32(); }