Improved Secret Chats:

Support layer 144 : big documents, silent
(layer not yet supported by other clients)
List of ISecretChat with detailed properties
Fix PFS issue losing a message...
This commit is contained in:
Wizou 2022-11-11 00:33:29 +01:00
parent 8fa00a8cc6
commit a038be87af
9 changed files with 326 additions and 275 deletions

2
.github/dev.yml vendored
View file

@ -2,7 +2,7 @@ pr: none
trigger:
- master
name: 3.0.4-dev.$(Rev:r)
name: 3.1.1-dev.$(Rev:r)
pool:
vmImage: ubuntu-latest

2
.github/release.yml vendored
View file

@ -1,7 +1,7 @@
pr: none
trigger: none
name: 3.0.$(Rev:r)
name: 3.1.$(Rev:r)
pool:
vmImage: ubuntu-latest

View file

@ -4,23 +4,24 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
using TL;
using WTelegram;
namespace WTelegramClientTest
{
static class Program_SecretChats
{
static WTelegram.Client Client;
static WTelegram.SecretChats Secrets;
static InputEncryptedChat ActiveChat; // the secret chat currently selected
static Client Client;
static SecretChats Secrets;
static ISecretChat ActiveChat; // the secret chat currently selected
static readonly Dictionary<long, User> Users = new();
static readonly Dictionary<long, ChatBase> Chats = new();
// go to Project Properties > Debug > Environment variables and add at least these: api_id, api_hash, phone_number
static async Task Main()
{
WTelegram.Helpers.Log = (l, s) => System.Diagnostics.Debug.WriteLine(s);
Client = new WTelegram.Client(Environment.GetEnvironmentVariable);
Secrets = new WTelegram.SecretChats(Client, "Secrets.bin");
Helpers.Log = (l, s) => System.Diagnostics.Debug.WriteLine(s);
Client = new Client(Environment.GetEnvironmentVariable);
Secrets = new SecretChats(Client, "Secrets.bin");
AppDomain.CurrentDomain.ProcessExit += (s, e) => { Secrets.Dispose(); Client.Dispose(); };
SelectActiveChat();
@ -46,9 +47,9 @@ Type a command, or a message to send to the active secret chat:");
var line = Console.ReadLine();
if (line.StartsWith('/'))
{
if (line == "/discard delete") { await Secrets.Discard(ActiveChat, true); SelectActiveChat(); }
else if (line == "/discard") { await Secrets.Discard(ActiveChat, false); SelectActiveChat(); }
else if (line == "/read") await Client.Messages_ReadEncryptedHistory(ActiveChat, DateTime.UtcNow);
if (line == "/discard delete") { await Secrets.Discard(ActiveChat.ChatId, true); SelectActiveChat(); }
else if (line == "/discard") { await Secrets.Discard(ActiveChat.ChatId, false); SelectActiveChat(); }
else if (line == "/read") await Client.Messages_ReadEncryptedHistory(ActiveChat.Peer, DateTime.UtcNow);
else if (line == "/users") foreach (var user in Users.Values) Console.WriteLine($"{user.id,-10} {user}");
else if (line.StartsWith("/select ")) SelectActiveChat(int.Parse(line[8..]));
else if (line.StartsWith("/request "))
@ -58,15 +59,15 @@ Type a command, or a message to send to the active secret chat:");
Console.WriteLine("User not found");
else if (line.StartsWith("/photo "))
{
var media = new TL.Layer45.DecryptedMessageMediaPhoto { caption = line[7..] };
var media = new TL.Layer46.DecryptedMessageMediaPhoto { caption = line[7..] };
var file = await Secrets.UploadFile(File.OpenRead(line[7..]), media);
var sent = await Secrets.SendMessage(ActiveChat, new TL.Layer73.DecryptedMessage { random_id = WTelegram.Helpers.RandomLong(),
var sent = await Secrets.SendMessage(ActiveChat.ChatId, new TL.Layer73.DecryptedMessage { random_id = Helpers.RandomLong(),
media = media, flags = TL.Layer73.DecryptedMessage.Flags.has_media }, file: file);
}
else Console.WriteLine("Unrecognized command");
}
else if (ActiveChat == null) Console.WriteLine("No active secret chat");
else await Secrets.SendMessage(ActiveChat, new TL.Layer73.DecryptedMessage { message = line, random_id = WTelegram.Helpers.RandomLong() });
else await Secrets.SendMessage(ActiveChat.ChatId, new TL.Layer73.DecryptedMessage { message = line, random_id = Helpers.RandomLong() });
}
catch (Exception ex)
{
@ -86,7 +87,7 @@ Type a command, or a message to send to the active secret chat:");
await Secrets.HandleUpdate(ue);
break;
case UpdateNewEncryptedMessage unem: // Encrypted message or service message:
if (unem.message.ChatId != ActiveChat?.chat_id) SelectActiveChat(unem.message.ChatId);
if (unem.message.ChatId != ActiveChat?.ChatId) SelectActiveChat(unem.message.ChatId);
foreach (var msg in Secrets.DecryptMessage(unem.message))
{
if (msg.Media != null && unem.message is EncryptedMessage { file: EncryptedFile ef })
@ -110,8 +111,8 @@ Type a command, or a message to send to the active secret chat:");
private static void SelectActiveChat(int newActiveChat = 0)
{
ActiveChat = Secrets.Peers.FirstOrDefault(sc => newActiveChat == 0 || sc.chat_id == newActiveChat);
Console.WriteLine("Active secret chat ID: " + ActiveChat?.chat_id);
ActiveChat = Secrets.Chats.FirstOrDefault(sc => newActiveChat == 0 || sc.ChatId == newActiveChat);
Console.WriteLine("Active secret chat ID: " + ActiveChat?.ChatId);
}
}
}

2
FAQ.md
View file

@ -140,7 +140,7 @@ Some additional advices from me:
5. Avoid repetitive polling or repetitive sequence of actions/requests: Save the initial results of your queries, and update those results when you're informed of a change through `OnUpdate` events.
6. Don't buy fake user accounts/sessions and don't extract api_id/hash/authkey/sessions from official clients, this is [specifically forbidden by API TOS](https://core.telegram.org/api/terms#2-transparency). You must use your own api_id and create your own sessions associated with it.
7. If a phone number is brand new, it will be closely monitored by Telegram for abuse, and it can even already be considered a bad user due to bad behavior from the previous owner of that phone number (which may happens often with VoIP or other easy-to-buy-online numbers, so expect fast ban)
7. If a phone number is brand new, it will be closely monitored by Telegram for abuse, and it can even already be considered a bad user due to bad behavior from the previous owner of that phone number (which may happen often with VoIP or other easy-to-buy-online numbers, so expect fast ban)
8. You may want to use your new phone number account with an official Telegram client and act like a normal user for some time (some weeks/months), before using it for automation with WTelegramClient.
9. When creating a new API ID/Hash, I recommend you use your own phone number with long history of normal Telegram usage, rather than a brand new phone number with short history.
In particular, DON'T create an API ID/Hash for every phone numbers you will control. One API ID/Hash represents your application, which can be used to control several user accounts.

View file

@ -531,7 +531,7 @@ j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB
private readonly ICryptoTransform aesCrypto;
private readonly byte[] prevBytes;
public AES_IGE_Stream(Stream stream, int size, byte[] key, byte[] iv) : this(stream, key, iv, false) { ContentLength = size; }
public AES_IGE_Stream(Stream stream, long size, byte[] key, byte[] iv) : this(stream, key, iv, false) { ContentLength = size; }
public AES_IGE_Stream(Stream stream, byte[] key, byte[] iv, bool encrypt) : base(stream)
{
aesCrypto = encrypt ? Encryption.AesECB.CreateEncryptor(key, null) : Encryption.AesECB.CreateDecryptor(key, null);

View file

@ -13,6 +13,14 @@ using static WTelegram.Encryption;
namespace WTelegram
{
public interface ISecretChat
{
int ChatId { get; }
long RemoteUserId { get; }
InputEncryptedChat Peer { get; }
int RemoteLayer { get; }
}
public sealed class SecretChats : IDisposable
{
public event Action OnChanged;
@ -28,7 +36,7 @@ namespace WTelegram
private const int ThresholdPFS = 100;
[TLDef(0xFEFEFEFE)]
internal class SecretChat : IObject
internal class SecretChat : IObject, ISecretChat
{
[Flags] public enum Flags : uint { requestChat = 1, renewKey = 2, acceptKey = 4, originator = 8, commitKey = 16 }
public Flags flags;
@ -43,8 +51,12 @@ namespace WTelegram
public long exchange_id;
public int ChatId => peer.chat_id;
public long RemoteUserId => participant_id;
public InputEncryptedChat Peer => peer;
public int RemoteLayer => remoteLayer;
internal long key_fingerprint;
internal SortedList<int, TL.Layer17.DecryptedMessageLayer> pendingMsgs = new();
internal SortedList<int, TL.Layer23.DecryptedMessageLayer> pendingMsgs = new();
internal void Discarded() // clear out fields for more security
{
Array.Clear(authKey, 0, authKey.Length);
@ -67,13 +79,7 @@ namespace WTelegram
}
public void Dispose() { OnChanged?.Invoke(); storage?.Dispose(); sha256.Dispose(); sha1.Dispose(); }
public List<InputEncryptedChat> Peers => chats.Values.Select(sc => sc.peer).ToList();
/// <summary>Return secret chats with the given remote user ID</summary>
/// <param name="participant_id">remote user ID</param>
/// <returns>List of matching secret chat ids/access_hash</returns>
public List<InputEncryptedChat> FindChatsByParticipant(long participant_id)
=> chats.Where(kvp => kvp.Value.participant_id == participant_id).Select(kvp => kvp.Value.peer).ToList();
public List<ISecretChat> Chats => chats.Values.ToList<ISecretChat>();
public bool IsChatActive(int chat_id) => !(chats.GetValueOrDefault(chat_id)?.flags.HasFlag(SecretChat.Flags.requestChat) ?? true);
@ -253,16 +259,16 @@ namespace WTelegram
private async Task SendNotifyLayer(SecretChat chat)
{
await SendMessage(chat.ChatId, new TL.Layer17.DecryptedMessageService { random_id = Helpers.RandomLong(),
action = new TL.Layer17.DecryptedMessageActionNotifyLayer { layer = Layer.SecretChats } });
await SendMessage(chat.ChatId, new TL.Layer23.DecryptedMessageService { random_id = Helpers.RandomLong(),
action = new TL.Layer23.DecryptedMessageActionNotifyLayer { layer = Layer.SecretChats } });
if (chat.remoteLayer < Layer.MTProto2) chat.remoteLayer = Layer.MTProto2;
}
/// <summary>Encrypt and send a message on a secret chat</summary>
/// <remarks>You would typically pass an instance of <see cref="TL.Layer73.DecryptedMessage"/> or <see cref="TL.Layer17.DecryptedMessageService"/> that you created and filled
/// <remarks>You would typically pass an instance of <see cref="TL.Layer73.DecryptedMessage"/> or <see cref="TL.Layer23.DecryptedMessageService"/> that you created and filled
/// <br/>Remember to fill <c>random_id</c> with <see cref="WTelegram.Helpers.RandomLong"/>, and the <c>flags</c> field if necessary</remarks>
/// <param name="chatId">Secret Chat ID</param>
/// <param name="msg">The pre-filled <see cref="TL.Layer73.DecryptedMessage">DecryptedMessage</see> or <see cref="TL.Layer17.DecryptedMessageService">DecryptedMessageService </see> to send</param>
/// <param name="msg">The pre-filled <see cref="TL.Layer73.DecryptedMessage">DecryptedMessage</see> or <see cref="TL.Layer23.DecryptedMessageService">DecryptedMessageService </see> to send</param>
/// <param name="silent">Send encrypted message without a notification</param>
/// <param name="file">Optional file attachment. See method <see cref="UploadFile">UploadFile</see></param>
/// <returns>Confirmation of sent message</returns>
@ -271,7 +277,7 @@ namespace WTelegram
if (!chats.TryGetValue(chatId, out var chat)) throw new ApplicationException("Secret chat not found");
try
{
var dml = new TL.Layer17.DecryptedMessageLayer
var dml = new TL.Layer23.DecryptedMessageLayer
{
layer = Math.Min(chat.remoteLayer, Layer.SecretChats),
random_bytes = new byte[15],
@ -290,7 +296,7 @@ namespace WTelegram
}
}
private async Task<Messages_SentEncryptedMessage> SendMessage(SecretChat chat, TL.Layer17.DecryptedMessageLayer dml, bool silent = false, InputEncryptedFileBase file = null)
private async Task<Messages_SentEncryptedMessage> SendMessage(SecretChat chat, TL.Layer23.DecryptedMessageLayer dml, bool silent = false, InputEncryptedFileBase file = null)
{
RNG.GetBytes(dml.random_bytes);
int x = 8 - (int)(chat.flags & SecretChat.Flags.originator);
@ -321,7 +327,7 @@ namespace WTelegram
CheckPFS(chat);
if (file != null)
return await client.Messages_SendEncryptedFile(chat.peer, dml.message.RandomId, data, file, silent);
else if (dml.message is TL.Layer17.DecryptedMessageService or TL.Layer8.DecryptedMessageService)
else if (dml.message is TL.Layer23.DecryptedMessageService or TL.Layer8.DecryptedMessageService)
return await client.Messages_SendEncryptedService(chat.peer, dml.message.RandomId, data);
else
return await client.Messages_SendEncrypted(chat.peer, dml.message.RandomId, data, silent);
@ -360,7 +366,7 @@ namespace WTelegram
/// <summary>Decrypt an encrypted message obtained in <see cref="UpdateNewEncryptedMessage"/></summary>
/// <param name="msg">Encrypted <see cref="UpdateNewEncryptedMessage.message"/></param>
/// <param name="fillGaps">If messages are missing or received in wrong order, automatically request to resend missing messages</param>
/// <returns>An array of <see cref="TL.Layer73.DecryptedMessage">DecryptedMessage</see> or <see cref="TL.Layer17.DecryptedMessageService">DecryptedMessageService </see> from various TL.LayerXX namespaces.<br/>
/// <returns>An array of <see cref="TL.Layer73.DecryptedMessage">DecryptedMessage</see> or <see cref="TL.Layer23.DecryptedMessageService">DecryptedMessageService </see> from various TL.LayerXX namespaces.<br/>
/// You can use the generic properties to access their fields
/// <para>May return an empty array if msg was already previously received or is not the next message in sequence.
/// <br/>May return multiple messages if missing messages are finally received (using <paramref name="fillGaps"/> = true)</para></returns>
@ -371,7 +377,7 @@ namespace WTelegram
try
{
var obj = Decrypt(chat, msg.Bytes, msg.Bytes.Length);
if (obj is not TL.Layer17.DecryptedMessageLayer dml) throw new ApplicationException("Decrypted object is not DecryptedMessageLayer");
if (obj is not TL.Layer23.DecryptedMessageLayer dml) throw new ApplicationException("Decrypted object is not DecryptedMessageLayer");
if (dml.random_bytes.Length < 15) throw new ApplicationException("Not enough random_bytes");
if (((dml.out_seq_no ^ dml.in_seq_no) & 1) != 1 || ((dml.out_seq_no ^ chat.in_seq_no) & 1) != 0) throw new ApplicationException("Invalid seq_no parities");
if (dml.layer > chat.remoteLayer) chat.remoteLayer = dml.layer;
@ -384,8 +390,8 @@ namespace WTelegram
if (lastPending == 0) lastPending = chat.in_seq_no;
chat.pendingMsgs[dml.out_seq_no] = dml;
if (dml.out_seq_no > lastPending + 2) // send request to resend missing gap asynchronously
_ = SendMessage(chat.ChatId, new TL.Layer17.DecryptedMessageService { random_id = Helpers.RandomLong(),
action = new TL.Layer17.DecryptedMessageActionResend { start_seq_no = lastPending + 2, end_seq_no = dml.out_seq_no - 2 } });
_ = SendMessage(chat.ChatId, new TL.Layer23.DecryptedMessageService { random_id = Helpers.RandomLong(),
action = new TL.Layer23.DecryptedMessageActionResend { start_seq_no = lastPending + 2, end_seq_no = dml.out_seq_no - 2 } });
return Array.Empty<DecryptedMessageBase>();
}
chat.in_seq_no = dml.out_seq_no;
@ -423,13 +429,13 @@ namespace WTelegram
{
switch (action)
{
case TL.Layer17.DecryptedMessageActionNotifyLayer dmanl:
case TL.Layer23.DecryptedMessageActionNotifyLayer dmanl:
chat.remoteLayer = dmanl.layer;
return true;
case TL.Layer17.DecryptedMessageActionResend resend:
case TL.Layer23.DecryptedMessageActionResend resend:
Helpers.Log(1, $"SC{(short)chat.ChatId:X4}> Resend {resend.start_seq_no}-{resend.end_seq_no}");
var msgSvc = new TL.Layer17.DecryptedMessageService { action = new TL.Layer20.DecryptedMessageActionNoop() };
var dml = new TL.Layer17.DecryptedMessageLayer
var msgSvc = new TL.Layer23.DecryptedMessageService { action = new TL.Layer23.DecryptedMessageActionNoop() };
var dml = new TL.Layer23.DecryptedMessageLayer
{
layer = Math.Min(chat.remoteLayer, Layer.SecretChats),
random_bytes = new byte[15],
@ -442,13 +448,13 @@ namespace WTelegram
_ = SendMessage(chat, dml);
}
return true;
case TL.Layer20.DecryptedMessageActionNoop:
case TL.Layer23.DecryptedMessageActionNoop:
Helpers.Log(1, $"SC{(short)chat.ChatId:X4}> Noop");
return true;
case TL.Layer20.DecryptedMessageActionRequestKey:
case TL.Layer20.DecryptedMessageActionAcceptKey:
case TL.Layer20.DecryptedMessageActionCommitKey:
case TL.Layer20.DecryptedMessageActionAbortKey:
case TL.Layer23.DecryptedMessageActionRequestKey:
case TL.Layer23.DecryptedMessageActionAcceptKey:
case TL.Layer23.DecryptedMessageActionCommitKey:
case TL.Layer23.DecryptedMessageActionAbortKey:
Helpers.Log(1, $"SC{(short)chat.ChatId:X4}> PFS {action.GetType().Name[22..]}");
HandlePFS(chat, action);
return true;
@ -465,16 +471,17 @@ namespace WTelegram
else { Helpers.Log(4, "SC{(short)chat.ChatId:X4}> PFS Failure"); _ = Discard(chat.ChatId); return; }
try
{
chat.flags |= SecretChat.Flags.renewKey;
Helpers.Log(1, $"SC{(short)chat.ChatId:X4}> PFS RenewKey");
await Task.Delay(100);
chat.salt = new byte[256];
RNG.GetBytes(chat.salt);
var a = BigEndianInteger(chat.salt);
var g_a = BigInteger.ModPow(dh.g, a, dh_prime);
CheckGoodGaAndGb(g_a, dh_prime);
chat.flags |= SecretChat.Flags.renewKey;
chat.exchange_id = Helpers.RandomLong();
await SendMessage(chat.ChatId, new TL.Layer17.DecryptedMessageService { random_id = Helpers.RandomLong(),
action = new TL.Layer20.DecryptedMessageActionRequestKey { exchange_id = chat.exchange_id, g_a = g_a.To256Bytes() } });
await SendMessage(chat.ChatId, new TL.Layer23.DecryptedMessageService { random_id = Helpers.RandomLong(),
action = new TL.Layer23.DecryptedMessageActionRequestKey { exchange_id = chat.exchange_id, g_a = g_a.To256Bytes() } });
}
catch (Exception ex)
{
@ -489,7 +496,7 @@ namespace WTelegram
{
switch (action)
{
case TL.Layer20.DecryptedMessageActionRequestKey request:
case TL.Layer23.DecryptedMessageActionRequestKey request:
switch (chat.flags & (SecretChat.Flags.requestChat | SecretChat.Flags.renewKey | SecretChat.Flags.acceptKey))
{
case SecretChat.Flags.renewKey: // Concurrent Re-Keying
@ -517,10 +524,10 @@ namespace WTelegram
chat.salt = gab.To256Bytes();
chat.exchange_id = request.exchange_id;
var key_fingerprint = BinaryPrimitives.ReadInt64LittleEndian(sha1.ComputeHash(chat.salt).AsSpan(12));
await SendMessage(chat.ChatId, new TL.Layer17.DecryptedMessageService { random_id = Helpers.RandomLong(),
action = new TL.Layer20.DecryptedMessageActionAcceptKey { exchange_id = request.exchange_id, g_b = g_b.To256Bytes(), key_fingerprint = key_fingerprint } });
await SendMessage(chat.ChatId, new TL.Layer23.DecryptedMessageService { random_id = Helpers.RandomLong(),
action = new TL.Layer23.DecryptedMessageActionAcceptKey { exchange_id = request.exchange_id, g_b = g_b.To256Bytes(), key_fingerprint = key_fingerprint } });
break;
case TL.Layer20.DecryptedMessageActionAcceptKey accept:
case TL.Layer23.DecryptedMessageActionAcceptKey accept:
if ((chat.flags & (SecretChat.Flags.requestChat | SecretChat.Flags.renewKey | SecretChat.Flags.acceptKey)) != SecretChat.Flags.renewKey)
throw new ApplicationException("Invalid AcceptKey");
if (accept.exchange_id != chat.exchange_id)
@ -533,13 +540,13 @@ namespace WTelegram
key_fingerprint = BinaryPrimitives.ReadInt64LittleEndian(sha1.ComputeHash(authKey).AsSpan(12));
if (accept.key_fingerprint != key_fingerprint)
throw new ApplicationException("AcceptKey: key_fingerprint mismatch");
_ = SendMessage(chat.ChatId, new TL.Layer17.DecryptedMessageService { random_id = Helpers.RandomLong(),
action = new TL.Layer20.DecryptedMessageActionCommitKey { exchange_id = accept.exchange_id, key_fingerprint = accept.key_fingerprint } });
_ = SendMessage(chat.ChatId, new TL.Layer23.DecryptedMessageService { random_id = Helpers.RandomLong(),
action = new TL.Layer23.DecryptedMessageActionCommitKey { exchange_id = accept.exchange_id, key_fingerprint = accept.key_fingerprint } });
chat.salt = chat.authKey; // A may only discard the previous key after a message encrypted with the new key has been received.
SetAuthKey(chat, authKey);
chat.flags = chat.flags & ~SecretChat.Flags.renewKey | SecretChat.Flags.commitKey;
break;
case TL.Layer20.DecryptedMessageActionCommitKey commit:
case TL.Layer23.DecryptedMessageActionCommitKey commit:
if ((chat.flags & (SecretChat.Flags.requestChat | SecretChat.Flags.renewKey | SecretChat.Flags.acceptKey)) != SecretChat.Flags.acceptKey)
throw new ApplicationException("Invalid RequestKey");
key_fingerprint = BinaryPrimitives.ReadInt64LittleEndian(sha1.ComputeHash(chat.salt).AsSpan(12));
@ -549,10 +556,10 @@ namespace WTelegram
authKey = chat.authKey;
SetAuthKey(chat, chat.salt);
Array.Clear(authKey, 0, authKey.Length); // the old key must be securely discarded
await SendMessage(chat.ChatId, new TL.Layer17.DecryptedMessageService { random_id = Helpers.RandomLong(),
action = new TL.Layer20.DecryptedMessageActionNoop() });
await SendMessage(chat.ChatId, new TL.Layer23.DecryptedMessageService { random_id = Helpers.RandomLong(),
action = new TL.Layer23.DecryptedMessageActionNoop() });
break;
case TL.Layer20.DecryptedMessageActionAbortKey abort:
case TL.Layer23.DecryptedMessageActionAbortKey abort:
if ((chat.flags & (SecretChat.Flags.renewKey | SecretChat.Flags.acceptKey)) == 0 ||
chat.flags.HasFlag(SecretChat.Flags.commitKey) || abort.exchange_id != chat.exchange_id)
return;
@ -579,7 +586,7 @@ namespace WTelegram
byte[] aes_key = new byte[32], aes_iv = new byte[32];
RNG.GetBytes(aes_key);
RNG.GetBytes(aes_iv);
media.SizeKeyIV = (checked((int)stream.Length), aes_key, aes_iv);
media.SizeKeyIV = (stream.Length, aes_key, aes_iv);
using var md5 = MD5.Create();
md5.TransformBlock(aes_key, 0, 32, null, 0);

View file

@ -13179,7 +13179,7 @@ namespace TL
public DocumentBase static_icon;
/// <summary>The animated sticker to show when the user opens the reaction dropdown</summary>
public DocumentBase appear_animation;
/// <summary>The animated sticker to show when the user selects this reaction</summary>
/// <summary>The animated sticker to show when the user hovers over the reaction</summary>
public DocumentBase select_animation;
/// <summary>The animated sticker to show when the reaction is chosen and activated</summary>
public DocumentBase activate_animation;

View file

@ -32,7 +32,7 @@ namespace TL
public abstract class DecryptedMessageMedia : IObject
{
public virtual string MimeType { get; }
internal virtual (int size, byte[] key, byte[] iv) SizeKeyIV { get => default; set => throw new ApplicationException("Incompatible DecryptedMessageMedia"); }
internal virtual (long size, byte[] key, byte[] iv) SizeKeyIV { get => default; set => throw new ApplicationException("Incompatible DecryptedMessageMedia"); }
}
/// <summary>Object describes the action to which a service message is linked. <para>See <a href="https://corefork.telegram.org/type/DecryptedMessageAction"/></para></summary>
@ -110,7 +110,7 @@ namespace TL
public byte[] iv;
public override string MimeType => "image/jpeg";
internal override (int, byte[], byte[]) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = (checked((int)value.size), value.key, value.iv); }
}
/// <summary>Video attached to an encrypted message. <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageMediaVideo"/></para></summary>
[TLDef(0x4CEE6EF3)]
@ -135,7 +135,7 @@ namespace TL
/// <summary>Initialization vector</summary>
public byte[] iv;
internal override (int, byte[], byte[]) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = (checked((int)value.size), value.key, value.iv); }
}
/// <summary>GeoPoint attached to an encrypted message. <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageMediaGeoPoint"/></para></summary>
[TLDef(0x35480A59)]
@ -182,7 +182,7 @@ namespace TL
/// <summary>File MIME-type</summary>
public override string MimeType => mime_type;
internal override (int, byte[], byte[]) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = (checked((int)value.size), value.key, value.iv); }
}
/// <summary>Audio file attached to a secret chat message. <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageMediaAudio"/></para></summary>
[TLDef(0x6080758F)]
@ -197,7 +197,7 @@ namespace TL
/// <summary>Initialization vector</summary>
public byte[] iv;
internal override (int, byte[], byte[]) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = (checked((int)value.size), value.key, value.iv); }
}
/// <summary>Setting of a message lifetime after reading. <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageActionSetMessageTTL"/></para></summary>
@ -233,8 +233,43 @@ namespace TL
public class DecryptedMessageActionFlushHistory : DecryptedMessageAction { }
}
namespace Layer17
namespace Layer23
{
/// <summary>Image description. <para>See <a href="https://corefork.telegram.org/constructor/photoSize"/></para></summary>
[TLDef(0x77BFB61B)]
public partial class PhotoSize : PhotoSizeBase
{
/// <summary><a href="https://corefork.telegram.org/api/files#image-thumbnail-types">Thumbnail type »</a></summary>
public string type;
public FileLocationBase location;
/// <summary>Image width</summary>
public int w;
/// <summary>Image height</summary>
public int h;
/// <summary>File size</summary>
public int size;
/// <summary><a href="https://corefork.telegram.org/api/files#image-thumbnail-types">Thumbnail type »</a></summary>
public override string Type => type;
}
/// <summary>Description of an image and its content. <para>See <a href="https://corefork.telegram.org/constructor/photoCachedSize"/></para></summary>
[TLDef(0xE9A734FA)]
public partial class PhotoCachedSize : PhotoSizeBase
{
/// <summary>Thumbnail type</summary>
public string type;
public FileLocationBase location;
/// <summary>Image width</summary>
public int w;
/// <summary>Image height</summary>
public int h;
/// <summary>Binary data, file content</summary>
public byte[] bytes;
/// <summary>Thumbnail type</summary>
public override string Type => type;
}
/// <summary>User is uploading a video. <para>See <a href="https://corefork.telegram.org/constructor/sendMessageUploadVideoAction"/></para></summary>
[TLDef(0x92042FF7)]
public class SendMessageUploadVideoAction : SendMessageAction { }
@ -248,6 +283,28 @@ namespace TL
[TLDef(0x8FAEE98E)]
public class SendMessageUploadDocumentAction : SendMessageAction { }
/// <summary>Defines a sticker <para>See <a href="https://corefork.telegram.org/constructor/documentAttributeSticker"/></para></summary>
[TLDef(0xFB0A5727)]
public class DocumentAttributeSticker : DocumentAttribute { }
/// <summary>Defines a video <para>See <a href="https://corefork.telegram.org/constructor/documentAttributeVideo"/></para></summary>
[TLDef(0x5910CCCB)]
public class DocumentAttributeVideo : DocumentAttribute
{
/// <summary>Duration in seconds</summary>
public int duration;
/// <summary>Video width</summary>
public int w;
/// <summary>Video height</summary>
public int h;
}
/// <summary>Represents an audio file <para>See <a href="https://corefork.telegram.org/constructor/documentAttributeAudio"/></para></summary>
[TLDef(0x051448E5)]
public class DocumentAttributeAudio : DocumentAttribute
{
/// <summary>Duration in seconds</summary>
public int duration;
}
/// <summary>Contents of an encrypted message. <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessage"/></para></summary>
[TLDef(0x204D3878)]
public class DecryptedMessage : DecryptedMessageBase
@ -313,7 +370,7 @@ namespace TL
/// <summary>MIME-type of the video file<br/>Parameter added in Layer 17.</summary>
public override string MimeType => mime_type;
internal override (int, byte[], byte[]) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = (checked((int)value.size), value.key, value.iv); }
}
/// <summary>Audio file attached to a secret chat message. <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageMediaAudio"/></para></summary>
[TLDef(0x57E0A9CB)]
@ -333,7 +390,31 @@ namespace TL
/// <summary>MIME-type of the audio file<br/>Parameter added in Layer 13.</summary>
public override string MimeType => mime_type;
internal override (int, byte[], byte[]) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = (checked((int)value.size), value.key, value.iv); }
}
/// <summary>Non-e2e documented forwarded from non-secret chat <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageMediaExternalDocument"/></para></summary>
[TLDef(0xFA95B0DD)]
public class DecryptedMessageMediaExternalDocument : DecryptedMessageMedia
{
/// <summary>Document ID</summary>
public long id;
/// <summary>access hash</summary>
public long access_hash;
/// <summary>Date</summary>
public DateTime date;
/// <summary>Mime type</summary>
public string mime_type;
/// <summary>Size</summary>
public int size;
/// <summary>Thumbnail</summary>
public PhotoSizeBase thumb;
/// <summary>DC ID</summary>
public int dc_id;
/// <summary>Attributes for media types</summary>
public DocumentAttribute[] attributes;
/// <summary>Mime type</summary>
public override string MimeType => mime_type;
}
/// <summary>Request for the other party in a Secret Chat to automatically resend a contiguous range of previously sent messages, as explained in <a href="https://corefork.telegram.org/api/end-to-end/seq_no">Sequence number is Secret Chats</a>. <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageActionResend"/></para></summary>
@ -359,6 +440,45 @@ namespace TL
/// <summary>Type of action</summary>
public SendMessageAction action;
}
/// <summary>Request rekeying, see <a href="https://corefork.telegram.org/api/end-to-end/pfs">rekeying process</a> <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageActionRequestKey"/></para></summary>
[TLDef(0xF3C9611B)]
public class DecryptedMessageActionRequestKey : DecryptedMessageAction
{
/// <summary>Exchange ID</summary>
public long exchange_id;
/// <summary>g_a, see <a href="https://corefork.telegram.org/api/end-to-end/pfs">rekeying process</a></summary>
public byte[] g_a;
}
/// <summary>Accept new key <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageActionAcceptKey"/></para></summary>
[TLDef(0x6FE1735B)]
public class DecryptedMessageActionAcceptKey : DecryptedMessageAction
{
/// <summary>Exchange ID</summary>
public long exchange_id;
/// <summary>B parameter, see <a href="https://corefork.telegram.org/api/end-to-end/pfs">rekeying process</a></summary>
public byte[] g_b;
/// <summary>Key fingerprint, see <a href="https://corefork.telegram.org/api/end-to-end/pfs">rekeying process</a></summary>
public long key_fingerprint;
}
/// <summary>Abort rekeying <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageActionAbortKey"/></para></summary>
[TLDef(0xDD05EC6B)]
public class DecryptedMessageActionAbortKey : DecryptedMessageAction
{
/// <summary>Exchange ID</summary>
public long exchange_id;
}
/// <summary>Commit new key, see <a href="https://corefork.telegram.org/api/end-to-end/pfs">rekeying process</a> <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageActionCommitKey"/></para></summary>
[TLDef(0xEC2E0B9B)]
public class DecryptedMessageActionCommitKey : DecryptedMessageAction
{
/// <summary>Exchange ID, see <a href="https://corefork.telegram.org/api/end-to-end/pfs">rekeying process</a></summary>
public long exchange_id;
/// <summary>Key fingerprint, see <a href="https://corefork.telegram.org/api/end-to-end/pfs">rekeying process</a></summary>
public long key_fingerprint;
}
/// <summary>NOOP action <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageActionNoop"/></para></summary>
[TLDef(0xA82FDD63)]
public class DecryptedMessageActionNoop : DecryptedMessageAction { }
/// <summary>Sets the layer number for the contents of an encrypted message. <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageLayer"/></para></summary>
[TLDef(0x1BE31789)]
@ -375,19 +495,49 @@ namespace TL
/// <summary>The content of message itself</summary>
public DecryptedMessageBase message;
}
/// <summary>File is currently unavailable. <para>See <a href="https://corefork.telegram.org/constructor/fileLocationUnavailable"/></para></summary>
[TLDef(0x7C596B46)]
public class FileLocationUnavailable : FileLocationBase
{
/// <summary>Server volume</summary>
public long volume_id;
/// <summary>File ID</summary>
public int local_id;
/// <summary>Checksum to access the file</summary>
public long secret;
/// <summary>Server volume</summary>
public override long VolumeId => volume_id;
/// <summary>File ID</summary>
public override int LocalId => local_id;
/// <summary>Checksum to access the file</summary>
public override long Secret => secret;
}
/// <summary>File location. <para>See <a href="https://corefork.telegram.org/constructor/fileLocation"/></para></summary>
[TLDef(0x53D69076)]
public class FileLocation : FileLocationBase
{
/// <summary>Number of the data center holding the file</summary>
public int dc_id;
/// <summary>Server volume</summary>
public long volume_id;
/// <summary>File ID</summary>
public int local_id;
/// <summary>Checksum to access the file</summary>
public long secret;
/// <summary>Server volume</summary>
public override long VolumeId => volume_id;
/// <summary>File ID</summary>
public override int LocalId => local_id;
/// <summary>Checksum to access the file</summary>
public override long Secret => secret;
}
}
namespace Layer45
{
/// <summary>Defines a sticker <para>See <a href="https://corefork.telegram.org/constructor/documentAttributeSticker"/></para></summary>
[TLDef(0x3A556302)]
public class DocumentAttributeSticker : DocumentAttribute
{
/// <summary>Alternative emoji representation of sticker</summary>
public string alt;
/// <summary>Associated stickerset</summary>
public InputStickerSet stickerset;
}
/// <summary>Represents an audio file <para>See <a href="https://corefork.telegram.org/constructor/documentAttributeAudio"/></para></summary>
[TLDef(0xDED218E0)]
public class DocumentAttributeAudio : DocumentAttribute
@ -399,6 +549,27 @@ namespace TL
/// <summary>Performer</summary>
public string performer;
}
}
namespace Layer46
{
/// <summary>Defines a sticker <para>See <a href="https://corefork.telegram.org/constructor/documentAttributeSticker"/></para></summary>
[TLDef(0x3A556302)]
public class DocumentAttributeSticker : DocumentAttribute
{
/// <summary>Alternative emoji representation of sticker</summary>
public string alt;
/// <summary>Associated stickerset</summary>
public InputStickerSet stickerset;
}
/// <summary>Message entity representing a <a href="https://corefork.telegram.org/api/mentions">user mention</a>: for <em>creating</em> a mention use <see cref="InputMessageEntityMentionName"/>. <para>See <a href="https://corefork.telegram.org/constructor/messageEntityMentionName"/></para></summary>
[TLDef(0x352DCA58, inheritBefore = true)]
public class MessageEntityMentionName : MessageEntityMention
{
/// <summary>Identifier of the user that was mentioned</summary>
public int user_id;
}
/// <summary>Contents of an encrypted message. <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessage"/></para></summary>
[TLDef(0x36B091DE)]
@ -475,7 +646,7 @@ namespace TL
public string caption;
public override string MimeType => "image/jpeg";
internal override (int, byte[], byte[]) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = (checked((int)value.size), value.key, value.iv); }
}
/// <summary>Video attached to an encrypted message. <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageMediaVideo"/></para></summary>
[TLDef(0x970C8C0E)]
@ -507,7 +678,7 @@ namespace TL
/// <summary>MIME-type of the video file<br/>Parameter added in Layer 17.</summary>
public override string MimeType => mime_type;
internal override (int, byte[], byte[]) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = (checked((int)value.size), value.key, value.iv); }
}
/// <summary>Document attached to a message in a secret chat. <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageMediaDocument"/></para></summary>
[TLDef(0x7AFE8AE2)]
@ -535,7 +706,7 @@ namespace TL
/// <summary>File MIME-type</summary>
public override string MimeType => mime_type;
internal override (int, byte[], byte[]) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = (checked((int)value.size), value.key, value.iv); }
}
/// <summary>Venue <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageMediaVenue"/></para></summary>
[TLDef(0x8A0DF56F)]
@ -563,6 +734,13 @@ namespace TL
}
}
namespace Layer66
{
/// <summary>User is uploading a round video <para>See <a href="https://corefork.telegram.org/constructor/sendMessageUploadRoundAction"/></para></summary>
[TLDef(0xBB718624)]
public class SendMessageUploadRoundAction : SendMessageAction { }
}
namespace Layer73
{
/// <summary>Contents of an encrypted message. <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessage"/></para></summary>
@ -592,6 +770,8 @@ namespace TL
{
/// <summary>Field <see cref="reply_to_random_id"/> has a value</summary>
has_reply_to_random_id = 0x8,
/// <summary>Whether this is a silent message (no notification triggered)</summary>
silent = 0x20,
/// <summary>Field <see cref="entities"/> has a value</summary>
has_entities = 0x80,
/// <summary>Field <see cref="media"/> has a value</summary>
@ -623,180 +803,41 @@ namespace TL
}
}
namespace Layer20
namespace Layer101
{ }
namespace Layer143
{
/// <summary>Request rekeying, see <a href="https://corefork.telegram.org/api/end-to-end/pfs">rekeying process</a> <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageActionRequestKey"/></para></summary>
[TLDef(0xF3C9611B)]
public class DecryptedMessageActionRequestKey : DecryptedMessageAction
/// <summary>Document attached to a message in a secret chat. <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageMediaDocument"/></para></summary>
[TLDef(0x6ABD9782)]
public class DecryptedMessageMediaDocument : DecryptedMessageMedia
{
/// <summary>Exchange ID</summary>
public long exchange_id;
/// <summary>g_a, see <a href="https://corefork.telegram.org/api/end-to-end/pfs">rekeying process</a></summary>
public byte[] g_a;
}
/// <summary>Accept new key <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageActionAcceptKey"/></para></summary>
[TLDef(0x6FE1735B)]
public class DecryptedMessageActionAcceptKey : DecryptedMessageAction
{
/// <summary>Exchange ID</summary>
public long exchange_id;
/// <summary>B parameter, see <a href="https://corefork.telegram.org/api/end-to-end/pfs">rekeying process</a></summary>
public byte[] g_b;
/// <summary>Key fingerprint, see <a href="https://corefork.telegram.org/api/end-to-end/pfs">rekeying process</a></summary>
public long key_fingerprint;
}
/// <summary>Abort rekeying <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageActionAbortKey"/></para></summary>
[TLDef(0xDD05EC6B)]
public class DecryptedMessageActionAbortKey : DecryptedMessageAction
{
/// <summary>Exchange ID</summary>
public long exchange_id;
}
/// <summary>Commit new key, see <a href="https://corefork.telegram.org/api/end-to-end/pfs">rekeying process</a> <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageActionCommitKey"/></para></summary>
[TLDef(0xEC2E0B9B)]
public class DecryptedMessageActionCommitKey : DecryptedMessageAction
{
/// <summary>Exchange ID, see <a href="https://corefork.telegram.org/api/end-to-end/pfs">rekeying process</a></summary>
public long exchange_id;
/// <summary>Key fingerprint, see <a href="https://corefork.telegram.org/api/end-to-end/pfs">rekeying process</a></summary>
public long key_fingerprint;
}
/// <summary>NOOP action <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageActionNoop"/></para></summary>
[TLDef(0xA82FDD63)]
public class DecryptedMessageActionNoop : DecryptedMessageAction { }
}
namespace Layer23
{
/// <summary>Image description. <para>See <a href="https://corefork.telegram.org/constructor/photoSize"/></para></summary>
[TLDef(0x77BFB61B)]
public partial class PhotoSize : PhotoSizeBase
{
/// <summary><a href="https://corefork.telegram.org/api/files#image-thumbnail-types">Thumbnail type »</a></summary>
public string type;
public FileLocationBase location;
/// <summary>Image width</summary>
public int w;
/// <summary>Image height</summary>
public int h;
/// <summary>File size</summary>
public int size;
/// <summary><a href="https://corefork.telegram.org/api/files#image-thumbnail-types">Thumbnail type »</a></summary>
public override string Type => type;
}
/// <summary>Description of an image and its content. <para>See <a href="https://corefork.telegram.org/constructor/photoCachedSize"/></para></summary>
[TLDef(0xE9A734FA)]
public partial class PhotoCachedSize : PhotoSizeBase
{
/// <summary>Thumbnail type</summary>
public string type;
public FileLocationBase location;
/// <summary>Image width</summary>
public int w;
/// <summary>Image height</summary>
public int h;
/// <summary>Binary data, file content</summary>
public byte[] bytes;
/// <summary>Thumbnail type</summary>
public override string Type => type;
}
/// <summary>Defines a sticker <para>See <a href="https://corefork.telegram.org/constructor/documentAttributeSticker"/></para></summary>
[TLDef(0xFB0A5727)]
public class DocumentAttributeSticker : DocumentAttribute { }
/// <summary>Defines a video <para>See <a href="https://corefork.telegram.org/constructor/documentAttributeVideo"/></para></summary>
[TLDef(0x5910CCCB)]
public class DocumentAttributeVideo : DocumentAttribute
{
/// <summary>Duration in seconds</summary>
public int duration;
/// <summary>Video width</summary>
public int w;
/// <summary>Video height</summary>
public int h;
}
/// <summary>Represents an audio file <para>See <a href="https://corefork.telegram.org/constructor/documentAttributeAudio"/></para></summary>
[TLDef(0x051448E5)]
public class DocumentAttributeAudio : DocumentAttribute
{
/// <summary>Duration in seconds</summary>
public int duration;
}
/// <summary>Non-e2e documented forwarded from non-secret chat <para>See <a href="https://corefork.telegram.org/constructor/decryptedMessageMediaExternalDocument"/></para></summary>
[TLDef(0xFA95B0DD)]
public class DecryptedMessageMediaExternalDocument : DecryptedMessageMedia
{
/// <summary>Document ID</summary>
public long id;
/// <summary>access hash</summary>
public long access_hash;
/// <summary>Date</summary>
public DateTime date;
/// <summary>Mime type</summary>
/// <summary>Thumbnail-file contents (JPEG-file, quality 55, set in a 90x90 square)</summary>
public byte[] thumb;
/// <summary>Thumbnail width</summary>
public int thumb_w;
/// <summary>Thumbnail height</summary>
public int thumb_h;
/// <summary>File MIME-type</summary>
public string mime_type;
/// <summary>Size</summary>
public int size;
/// <summary>Thumbnail</summary>
public PhotoSizeBase thumb;
/// <summary>DC ID</summary>
public int dc_id;
/// <summary>Attributes for media types</summary>
/// <summary>Document size (<see cref="int"/> on layer &lt;143, <see cref="long"/> on layer &gt;=143)</summary>
public long size;
/// <summary>Key to decrypt the attached document file</summary>
public byte[] key;
/// <summary>Initialization</summary>
public byte[] iv;
/// <summary>Document attributes for media types</summary>
public DocumentAttribute[] attributes;
/// <summary>Caption</summary>
public string caption;
/// <summary>Mime type</summary>
/// <summary>File MIME-type</summary>
public override string MimeType => mime_type;
}
/// <summary>File is currently unavailable. <para>See <a href="https://corefork.telegram.org/constructor/fileLocationUnavailable"/></para></summary>
[TLDef(0x7C596B46)]
public class FileLocationUnavailable : FileLocationBase
{
/// <summary>Server volume</summary>
public long volume_id;
/// <summary>File ID</summary>
public int local_id;
/// <summary>Checksum to access the file</summary>
public long secret;
/// <summary>Server volume</summary>
public override long VolumeId => volume_id;
/// <summary>File ID</summary>
public override int LocalId => local_id;
/// <summary>Checksum to access the file</summary>
public override long Secret => secret;
}
/// <summary>File location. <para>See <a href="https://corefork.telegram.org/constructor/fileLocation"/></para></summary>
[TLDef(0x53D69076)]
public class FileLocation : FileLocationBase
{
/// <summary>Number of the data center holding the file</summary>
public int dc_id;
/// <summary>Server volume</summary>
public long volume_id;
/// <summary>File ID</summary>
public int local_id;
/// <summary>Checksum to access the file</summary>
public long secret;
/// <summary>Server volume</summary>
public override long VolumeId => volume_id;
/// <summary>File ID</summary>
public override int LocalId => local_id;
/// <summary>Checksum to access the file</summary>
public override long Secret => secret;
internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
}
}
namespace Layer66
{
/// <summary>User is uploading a round video <para>See <a href="https://corefork.telegram.org/constructor/sendMessageUploadRoundAction"/></para></summary>
[TLDef(0xBB718624)]
public class SendMessageUploadRoundAction : SendMessageAction { }
}
namespace Layer46
namespace Layer144
{ }
}

View file

@ -7,7 +7,7 @@ namespace TL
public static class Layer
{
public const int Version = 148; // fetched 01/11/2022 17:33:23
internal const int SecretChats = 101;
internal const int SecretChats = 144;
internal const int MTProto2 = 73;
internal const uint VectorCtor = 0x1CB5C415;
internal const uint NullCtor = 0x56730BCC;
@ -1047,54 +1047,56 @@ namespace TL
[0x71701DA9] = typeof(ForumTopic),
[0x367617D3] = typeof(Messages_ForumTopics),
// from TL.Secret:
[0x6ABD9782] = typeof(Layer143.DecryptedMessageMediaDocument),
[0x91CC4674] = typeof(Layer73.DecryptedMessage),
[0xBB718624] = typeof(Layer66.SendMessageUploadRoundAction),
[0xE50511D8] = typeof(Layer45.DecryptedMessageMediaWebPage),
[0x8A0DF56F] = typeof(Layer45.DecryptedMessageMediaVenue),
[0xE50511D8] = typeof(Layer46.DecryptedMessageMediaWebPage),
[0x8A0DF56F] = typeof(Layer46.DecryptedMessageMediaVenue),
[0x352DCA58] = typeof(Layer46.MessageEntityMentionName),
[0x3A556302] = typeof(Layer46.DocumentAttributeSticker),
[0x7AFE8AE2] = typeof(Layer46.DecryptedMessageMediaDocument),
[0x970C8C0E] = typeof(Layer46.DecryptedMessageMediaVideo),
[0xF1FA8D78] = typeof(Layer46.DecryptedMessageMediaPhoto),
[0x36B091DE] = typeof(Layer46.DecryptedMessage),
[0xDED218E0] = typeof(Layer45.DocumentAttributeAudio),
[0xFA95B0DD] = typeof(Layer23.DecryptedMessageMediaExternalDocument),
[0x53D69076] = typeof(Layer23.FileLocation),
[0x7C596B46] = typeof(Layer23.FileLocationUnavailable),
[0xE9A734FA] = typeof(Layer23.PhotoCachedSize),
[0x77BFB61B] = typeof(Layer23.PhotoSize),
[0xDED218E0] = typeof(Layer45.DocumentAttributeAudio),
[0x051448E5] = typeof(Layer23.DocumentAttributeAudio),
[0x5910CCCB] = typeof(Layer23.DocumentAttributeVideo),
[0x3A556302] = typeof(Layer45.DocumentAttributeSticker),
[0xFB0A5727] = typeof(Layer23.DocumentAttributeSticker),
[0xA82FDD63] = typeof(Layer20.DecryptedMessageActionNoop),
[0xEC2E0B9B] = typeof(Layer20.DecryptedMessageActionCommitKey),
[0xDD05EC6B] = typeof(Layer20.DecryptedMessageActionAbortKey),
[0x6FE1735B] = typeof(Layer20.DecryptedMessageActionAcceptKey),
[0xF3C9611B] = typeof(Layer20.DecryptedMessageActionRequestKey),
[0xCCB27641] = typeof(Layer17.DecryptedMessageActionTyping),
[0xF3048883] = typeof(Layer17.DecryptedMessageActionNotifyLayer),
[0x511110B0] = typeof(Layer17.DecryptedMessageActionResend),
[0x8FAEE98E] = typeof(Layer17.SendMessageUploadDocumentAction),
[0x990A3C1A] = typeof(Layer17.SendMessageUploadPhotoAction),
[0xE6AC8A6F] = typeof(Layer17.SendMessageUploadAudioAction),
[0x92042FF7] = typeof(Layer17.SendMessageUploadVideoAction),
[0x1BE31789] = typeof(Layer17.DecryptedMessageLayer),
[0xA82FDD63] = typeof(Layer23.DecryptedMessageActionNoop),
[0xEC2E0B9B] = typeof(Layer23.DecryptedMessageActionCommitKey),
[0xDD05EC6B] = typeof(Layer23.DecryptedMessageActionAbortKey),
[0x6FE1735B] = typeof(Layer23.DecryptedMessageActionAcceptKey),
[0xF3C9611B] = typeof(Layer23.DecryptedMessageActionRequestKey),
[0xCCB27641] = typeof(Layer23.DecryptedMessageActionTyping),
[0xF3048883] = typeof(Layer23.DecryptedMessageActionNotifyLayer),
[0x511110B0] = typeof(Layer23.DecryptedMessageActionResend),
[0x8FAEE98E] = typeof(Layer23.SendMessageUploadDocumentAction),
[0x990A3C1A] = typeof(Layer23.SendMessageUploadPhotoAction),
[0xE6AC8A6F] = typeof(Layer23.SendMessageUploadAudioAction),
[0x92042FF7] = typeof(Layer23.SendMessageUploadVideoAction),
[0x1BE31789] = typeof(Layer23.DecryptedMessageLayer),
[0x57E0A9CB] = typeof(Layer23.DecryptedMessageMediaAudio),
[0x524A415D] = typeof(Layer23.DecryptedMessageMediaVideo),
[0x73164160] = typeof(Layer23.DecryptedMessageService),
[0x204D3878] = typeof(Layer23.DecryptedMessage),
[0x6719E45C] = typeof(Layer8.DecryptedMessageActionFlushHistory),
[0x8AC1F475] = typeof(Layer8.DecryptedMessageActionScreenshotMessages),
[0x65614304] = typeof(Layer8.DecryptedMessageActionDeleteMessages),
[0x0C4F40BE] = typeof(Layer8.DecryptedMessageActionReadMessages),
[0x57E0A9CB] = typeof(Layer17.DecryptedMessageMediaAudio),
[0x6080758F] = typeof(Layer8.DecryptedMessageMediaAudio),
[0x7AFE8AE2] = typeof(Layer45.DecryptedMessageMediaDocument),
[0xB095434B] = typeof(Layer8.DecryptedMessageMediaDocument),
[0xA1733AEC] = typeof(Layer8.DecryptedMessageActionSetMessageTTL),
[0x588A0A97] = typeof(Layer8.DecryptedMessageMediaContact),
[0x35480A59] = typeof(Layer8.DecryptedMessageMediaGeoPoint),
[0x970C8C0E] = typeof(Layer45.DecryptedMessageMediaVideo),
[0x524A415D] = typeof(Layer17.DecryptedMessageMediaVideo),
[0x4CEE6EF3] = typeof(Layer8.DecryptedMessageMediaVideo),
[0xF1FA8D78] = typeof(Layer45.DecryptedMessageMediaPhoto),
[0x32798A8C] = typeof(Layer8.DecryptedMessageMediaPhoto),
[0x089F5C4A] = null,//Layer8.DecryptedMessageMediaEmpty
[0x73164160] = typeof(Layer17.DecryptedMessageService),
[0xAA48327D] = typeof(Layer8.DecryptedMessageService),
[0x91CC4674] = typeof(Layer73.DecryptedMessage),
[0x36B091DE] = typeof(Layer45.DecryptedMessage),
[0x204D3878] = typeof(Layer17.DecryptedMessage),
[0x1F814F1F] = typeof(Layer8.DecryptedMessage),
};