diff --git a/Examples/Program_ListenUpdates.cs b/Examples/Program_ListenUpdates.cs index f500746..d4ebebb 100644 --- a/Examples/Program_ListenUpdates.cs +++ b/Examples/Program_ListenUpdates.cs @@ -26,7 +26,7 @@ namespace WTelegramClientTest users[my.id] = my; // note that on logging, Telegram may sends a bunch of updates/messages that happened in the past and were not acknowledged Console.WriteLine($"We are logged-in as {my.username ?? my.first_name + " " + my.last_name} (id {my.id})"); - var dialogsBase = await client.Messages_GetDialogs(default, 0, InputPeer.Empty, 0, 0); + var dialogsBase = await client.Messages_GetDialogs(default, 0, null, 0, 0); if (dialogsBase is Messages_Dialogs dialogs) while (dialogs.dialogs.Length != 0) { diff --git a/src/Encryption.cs b/src/Encryption.cs index fc7161c..f3ce552 100644 --- a/src/Encryption.cs +++ b/src/Encryption.cs @@ -360,7 +360,7 @@ j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB return output; } - internal static InputCheckPasswordSRPBase Check2FA(Account_Password accountPassword, string password) + internal static InputCheckPasswordSRP Check2FA(Account_Password accountPassword, string password) { if (accountPassword.current_algo is not PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow algo) throw new ApplicationException("2FA authentication uses an unsupported algo: " + accountPassword.current_algo?.GetType().Name); diff --git a/src/Generator.cs b/src/Generator.cs index c5c0189..32b7183 100644 --- a/src/Generator.cs +++ b/src/Generator.cs @@ -113,6 +113,7 @@ namespace WTelegram ctorToTypes[ctor.ID] = ctor.layer == 0 ? structName : $"Layer{ctor.layer}.{structName}"; var typeInfo = typeInfos.GetOrCreate(ctor.type); if (ctor.ID == 0x5BB8E511) { ctorToTypes[ctor.ID] = structName = ctor.predicate = ctor.type = "_Message"; } + else if (ctor.ID == TL.Layer.NullCtor) { ctorToTypes[ctor.ID] += "=null"; typeInfo.Nullable = ctor; } if (typeInfo.ReturnName == null) typeInfo.ReturnName = CSharpName(ctor.type); typeInfo.Structs.Add(ctor); if (structName == typeInfo.ReturnName) typeInfo.MainClass = ctor; @@ -128,6 +129,15 @@ namespace WTelegram } continue; } + if (typeInfo.Structs.All(ctor => ctor.@params.Length == 0)) + typeInfo.AsEnum = true; + var nullable = typeInfo.Structs.Where(c => c.predicate.EndsWith("Empty") || c.predicate.EndsWith("Unknown")).ToList(); + if (nullable.Count == 1 && nullable[0].@params.Length == 0 && !typeInfo.AsEnum) + { + typeInfo.Nullable = nullable[0]; + typeInfo.Structs.Remove(typeInfo.Nullable); + ctorToTypes[typeInfo.Nullable.ID] += "=null"; + } if (typeInfo.MainClass == null) { List fakeCtorParams = new(); @@ -240,11 +250,13 @@ namespace WTelegram if (needNewLine) { needNewLine = false; sw.WriteLine(); } var parentClass = ctor == typeInfo.MainClass ? "ITLObject" : typeInfo.ReturnName; var parms = ctor.@params; - if (ctorId == 0) + if (ctorId == 0) // abstract parent { if (currentJson != "TL.MTProto") sw.WriteLine($"{tabIndent}///See "); - if (typeInfo.Structs.All(ctor => ctor.@params.Length == 0)) + if (typeInfo.Nullable != null) + sw.WriteLine($"{tabIndent}///a null value means {typeInfo.Nullable.predicate}"); + if (typeInfo.AsEnum) { WriteTypeAsEnum(sw, typeInfo); return; @@ -290,6 +302,8 @@ namespace WTelegram if (currentJson != "TL.MTProto") { sw.WriteLine($"{tabIndent}///See "); + if (typeInfo.Nullable != null && ctor == typeInfo.MainClass) + sw.WriteLine($"{tabIndent}///a null value means {typeInfo.Nullable.predicate}"); sw.WriteLine($"{tabIndent}[TLDef(0x{ctor.ID:X8}{tldefReverse})]"); } else @@ -610,8 +624,10 @@ namespace WTelegram void UpdateTable(string tableCs) { + int tableId = 0; var myTag = $"\t\t\t// from {currentJson}:"; var seen_ids = new HashSet(); + var seen_nullables = new HashSet(); using (var sr = new StreamReader(tableCs)) using (var sw = new StreamWriter(tableCs + ".new", false, Encoding.UTF8)) { @@ -624,9 +640,22 @@ namespace WTelegram sw.WriteLine(line); if (line == myTag) { - foreach (var ctor in ctorToTypes) - if (seen_ids.Add(ctor.Key)) - sw.WriteLine($"\t\t\t[0x{ctor.Key:X8}] = typeof({ctor.Value}),"); + switch (++tableId) + { + case 1: + foreach (var ctor in ctorToTypes) + if (seen_ids.Add(ctor.Key)) + if (ctor.Value.EndsWith("=null")) + sw.WriteLine($"\t\t\t[0x{ctor.Key:X8}] = null,//{ctor.Value[..^5]}"); + else + sw.WriteLine($"\t\t\t[0x{ctor.Key:X8}] = typeof({ctor.Value}),"); + break; + case 2: + foreach (var typeInfo in typeInfos.Values) + if (typeInfo.Nullable != null && seen_nullables.Add(typeInfo.ReturnName)) + sw.WriteLine($"\t\t\t[typeof({typeInfo.ReturnName})]{new string(' ', 30 - typeInfo.ReturnName.Length)} = 0x{typeInfo.Nullable.ID:X8}, //{typeInfo.Nullable.predicate}"); + break; + } while ((line = sr.ReadLine()) != null) if (line.StartsWith("\t\t\t// ")) break; @@ -634,6 +663,8 @@ namespace WTelegram } else if (line.StartsWith("\t\t\t[0x")) seen_ids.Add(int.Parse(line[6..14], System.Globalization.NumberStyles.HexNumber)); + else if (line.StartsWith("\t\t\t[typeof(")) + seen_nullables.Add(line[11..line.IndexOf(')')]); } } File.Replace(tableCs + ".new", tableCs, null); @@ -672,8 +703,10 @@ namespace WTelegram { public string ReturnName; public Constructor MainClass; + public Constructor Nullable; public List Structs = new(); internal int CommonFields; // n fields are common among all those classes + internal bool AsEnum; } #pragma warning disable IDE1006 // Naming Styles diff --git a/src/Helpers.TL.cs b/src/Helpers.TL.cs index 7a412d1..a7fc6b2 100644 --- a/src/Helpers.TL.cs +++ b/src/Helpers.TL.cs @@ -6,14 +6,7 @@ using System.Web; namespace TL { - partial class InputChannel { public static InputPeerChannel Empty => new(); } - partial class InputDocument { public static InputDocumentEmpty Empty => new(); } - partial class InputPeer { public static InputPeerEmpty Empty => new(); } partial class InputPeer { public static InputPeerSelf Self => new(); } - partial class InputPhoto { public static InputPhotoEmpty Empty => new(); } - partial class InputEncryptedFile { public static InputEncryptedFileEmpty Empty => new(); } - partial class InputStickerSet { public static InputStickerSetEmpty Empty => new(); } - partial class InputUser { public static InputUserEmpty Empty => new(); } partial class InputUser { public static InputUserSelf Self => new(); } partial class ChatBase @@ -30,7 +23,7 @@ namespace TL public override long ID => id; public override string Title => null; public override bool IsBanned(ChatBannedRights.Flags flags = 0) => true; - protected override InputPeer ToInputPeer() => InputPeer.Empty; + protected override InputPeer ToInputPeer() => null; } partial class Chat { @@ -75,8 +68,8 @@ namespace TL { public override long ID => id; public override string DisplayName => null; - protected override InputPeer ToInputPeer() => InputPeer.Empty; - protected override InputUserBase ToInputUser() => InputUser.Empty; + protected override InputPeer ToInputPeer() => null; + protected override InputUserBase ToInputUser() => null; } partial class User { @@ -114,19 +107,19 @@ namespace TL partial class PhotoBase { public abstract long ID { get; } - protected abstract InputPhotoBase ToInputPhoto(); - public static implicit operator InputPhotoBase(PhotoBase photo) => photo.ToInputPhoto(); + protected abstract InputPhoto ToInputPhoto(); + public static implicit operator InputPhoto(PhotoBase photo) => photo.ToInputPhoto(); } partial class PhotoEmpty { public override long ID => id; - protected override InputPhotoBase ToInputPhoto() => InputPhoto.Empty; + protected override InputPhoto ToInputPhoto() => null; } partial class Photo { public override long ID => id; - protected override InputPhotoBase ToInputPhoto() => new InputPhoto() { id = id, access_hash = access_hash, file_reference = file_reference }; + protected override InputPhoto ToInputPhoto() => new() { id = id, access_hash = access_hash, file_reference = file_reference }; public InputPhotoFileLocation ToFileLocation() => ToFileLocation(LargestPhotoSize); public InputPhotoFileLocation ToFileLocation(PhotoSizeBase photoSize) => new() { id = id, access_hash = access_hash, file_reference = file_reference, thumb_size = photoSize.Type }; public PhotoSizeBase LargestPhotoSize => sizes.Aggregate((agg, next) => (long)next.Width * next.Height > (long)agg.Width * agg.Height ? next : agg); @@ -202,33 +195,24 @@ namespace TL partial class DocumentBase { public abstract long ID { get; } - protected abstract InputDocumentBase ToInputDocument(); - public static implicit operator InputDocumentBase(DocumentBase document) => document.ToInputDocument(); + protected abstract InputDocument ToInputDocument(); + public static implicit operator InputDocument(DocumentBase document) => document.ToInputDocument(); } partial class DocumentEmpty { public override long ID => id; - protected override InputDocumentBase ToInputDocument() => InputDocument.Empty; + protected override InputDocument ToInputDocument() => null; } partial class Document { public override long ID => id; - protected override InputDocumentBase ToInputDocument() => new InputDocument() { id = id, access_hash = access_hash, file_reference = file_reference }; + protected override InputDocument ToInputDocument() => new() { id = id, access_hash = access_hash, file_reference = file_reference }; public InputDocumentFileLocation ToFileLocation(PhotoSizeBase thumbSize = null) => new() { id = id, access_hash = access_hash, file_reference = file_reference, thumb_size = thumbSize?.Type }; } - partial class EncryptedFileBase - { - protected abstract InputEncryptedFileBase ToInputEncryptedFile(); - public static implicit operator InputEncryptedFileBase(EncryptedFileBase file) => file.ToInputEncryptedFile(); - } - partial class EncryptedFileEmpty - { - protected override InputEncryptedFileBase ToInputEncryptedFile() => InputEncryptedFile.Empty; - } partial class EncryptedFile { - protected override InputEncryptedFileBase ToInputEncryptedFile() => new InputEncryptedFile { id = id, access_hash = access_hash }; + public static implicit operator InputEncryptedFile(EncryptedFile file) => file == null ? null : new InputEncryptedFile { id = file.id, access_hash = file.access_hash }; public InputEncryptedFileLocation ToFileLocation() => new() { id = id, access_hash = access_hash }; } diff --git a/src/Session.cs b/src/Session.cs index b177293..861f527 100644 --- a/src/Session.cs +++ b/src/Session.cs @@ -42,7 +42,7 @@ namespace WTelegram private static readonly JsonSerializerOptions JsonOptions = new(Helpers.JsonOptions) { Converters = { - new Helpers.PolymorphicConverter(), + new Helpers.PolymorphicConverter(), new Helpers.PolymorphicConverter() } }; diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs index fd5e6fd..8a9ec79 100644 --- a/src/TL.Schema.cs +++ b/src/TL.Schema.cs @@ -29,14 +29,13 @@ namespace TL } ///See + ///a null value means null [TLDef(0x56730BCC)] public partial class Null : ITLObject { } ///See + ///a null value means inputPeerEmpty public abstract partial class InputPeer : ITLObject { } - ///See - [TLDef(0x7F3B18EA)] - public partial class InputPeerEmpty : InputPeer { } ///See [TLDef(0x7DA07EC9)] public partial class InputPeerSelf : InputPeer { } @@ -75,10 +74,8 @@ namespace TL } ///See + ///a null value means inputUserEmpty public abstract partial class InputUserBase : ITLObject { } - ///See - [TLDef(0xB98886CF)] - public partial class InputUserEmpty : InputUserBase { } ///See [TLDef(0xF7C1B13F)] public partial class InputUserSelf : InputUserBase { } @@ -131,10 +128,8 @@ namespace TL } ///See + ///a null value means inputMediaEmpty public abstract partial class InputMedia : ITLObject { } - ///See - [TLDef(0x9664F57F)] - public partial class InputMediaEmpty : InputMedia { } ///See [TLDef(0x1E287D04)] public partial class InputMediaUploadedPhoto : InputMedia @@ -142,7 +137,7 @@ namespace TL [Flags] public enum Flags { has_stickers = 0x1, has_ttl_seconds = 0x2 } public Flags flags; public InputFileBase file; - [IfFlag(0)] public InputDocumentBase[] stickers; + [IfFlag(0)] public InputDocument[] stickers; [IfFlag(1)] public int ttl_seconds; } ///See @@ -151,12 +146,12 @@ namespace TL { [Flags] public enum Flags { has_ttl_seconds = 0x1 } public Flags flags; - public InputPhotoBase id; + public InputPhoto id; [IfFlag(0)] public int ttl_seconds; } ///See [TLDef(0xF9C44144)] - public partial class InputMediaGeoPoint : InputMedia { public InputGeoPointBase geo_point; } + public partial class InputMediaGeoPoint : InputMedia { public InputGeoPoint geo_point; } ///See [TLDef(0xF8AB7DFB)] public partial class InputMediaContact : InputMedia @@ -176,7 +171,7 @@ namespace TL [IfFlag(2)] public InputFileBase thumb; public string mime_type; public DocumentAttribute[] attributes; - [IfFlag(0)] public InputDocumentBase[] stickers; + [IfFlag(0)] public InputDocument[] stickers; [IfFlag(1)] public int ttl_seconds; } ///See @@ -185,7 +180,7 @@ namespace TL { [Flags] public enum Flags { has_ttl_seconds = 0x1, has_query = 0x2 } public Flags flags; - public InputDocumentBase id; + public InputDocument id; [IfFlag(0)] public int ttl_seconds; [IfFlag(1)] public string query; } @@ -193,7 +188,7 @@ namespace TL [TLDef(0xC13D1C11)] public partial class InputMediaVenue : InputMedia { - public InputGeoPointBase geo_point; + public InputGeoPoint geo_point; public string title; public string address; public string provider; @@ -242,7 +237,7 @@ namespace TL { [Flags] public enum Flags { stopped = 0x1, has_period = 0x2, has_heading = 0x4, has_proximity_notification_radius = 0x8 } public Flags flags; - public InputGeoPointBase geo_point; + public InputGeoPoint geo_point; [IfFlag(2)] public int heading; [IfFlag(1)] public int period; [IfFlag(3)] public int proximity_notification_radius; @@ -263,10 +258,8 @@ namespace TL public partial class InputMediaDice : InputMedia { public string emoticon; } ///See + ///a null value means inputChatPhotoEmpty public abstract partial class InputChatPhotoBase : ITLObject { } - ///See - [TLDef(0x1CA48F57)] - public partial class InputChatPhotoEmpty : InputChatPhotoBase { } ///See [TLDef(0xC642724E)] public partial class InputChatUploadedPhoto : InputChatPhotoBase @@ -279,16 +272,12 @@ namespace TL } ///See [TLDef(0x8953AD37)] - public partial class InputChatPhoto : InputChatPhotoBase { public InputPhotoBase id; } + public partial class InputChatPhoto : InputChatPhotoBase { public InputPhoto id; } - ///See - public abstract partial class InputGeoPointBase : ITLObject { } - ///See - [TLDef(0xE4C123D6)] - public partial class InputGeoPointEmpty : InputGeoPointBase { } ///See + ///a null value means inputGeoPointEmpty [TLDef(0x48222FAF)] - public partial class InputGeoPoint : InputGeoPointBase + public partial class InputGeoPoint : ITLObject { [Flags] public enum Flags { has_accuracy_radius = 0x1 } public Flags flags; @@ -297,14 +286,10 @@ namespace TL [IfFlag(0)] public int accuracy_radius; } - ///See - public abstract partial class InputPhotoBase : ITLObject { } - ///See - [TLDef(0x1CD7BF0D)] - public partial class InputPhotoEmpty : InputPhotoBase { } ///See + ///a null value means inputPhotoEmpty [TLDef(0x3BB3B94A)] - public partial class InputPhoto : InputPhotoBase + public partial class InputPhoto : ITLObject { public long id; public long access_hash; @@ -455,7 +440,7 @@ namespace TL [IfFlag(2)] public string last_name; [IfFlag(3)] public string username; [IfFlag(4)] public string phone; - [IfFlag(5)] public UserProfilePhotoBase photo; + [IfFlag(5)] public UserProfilePhoto photo; [IfFlag(6)] public UserStatus status; [IfFlag(14)] public int bot_info_version; [IfFlag(18)] public RestrictionReason[] restriction_reason; @@ -463,14 +448,10 @@ namespace TL [IfFlag(22)] public string lang_code; } - ///See - public abstract partial class UserProfilePhotoBase : ITLObject { } - ///See - [TLDef(0x4F11BAE1)] - public partial class UserProfilePhotoEmpty : UserProfilePhotoBase { } ///See + ///a null value means userProfilePhotoEmpty [TLDef(0x82D1F706)] - public partial class UserProfilePhoto : UserProfilePhotoBase + public partial class UserProfilePhoto : ITLObject { [Flags] public enum Flags { has_video = 0x1, has_stripped_thumb = 0x2 } public Flags flags; @@ -480,10 +461,8 @@ namespace TL } ///See + ///a null value means userStatusEmpty public abstract partial class UserStatus : ITLObject { } - ///See - [TLDef(0x09D05049)] - public partial class UserStatusEmpty : UserStatus { } ///See [TLDef(0xEDB93949)] public partial class UserStatusOnline : UserStatus { public DateTime expires; } @@ -514,7 +493,7 @@ namespace TL public Flags flags; public long id; public string title; - public ChatPhotoBase photo; + public ChatPhoto photo; public int participants_count; public DateTime date; public int version; @@ -543,7 +522,7 @@ namespace TL [IfFlag(13)] public long access_hash; public string title; [IfFlag(6)] public string username; - public ChatPhotoBase photo; + public ChatPhoto photo; public DateTime date; [IfFlag(9)] public RestrictionReason[] restriction_reason; [IfFlag(14)] public ChatAdminRights admin_rights; @@ -621,7 +600,7 @@ namespace TL [IfFlag(9)] public int available_min_id; [IfFlag(11)] public int folder_id; [IfFlag(14)] public long linked_chat_id; - [IfFlag(15)] public ChannelLocationBase location; + [IfFlag(15)] public ChannelLocation location; [IfFlag(17)] public int slowmode_seconds; [IfFlag(18)] public DateTime slowmode_next_send_date; [IfFlag(12)] public int stats_dc; @@ -670,14 +649,10 @@ namespace TL public int version; } - ///See - public abstract partial class ChatPhotoBase : ITLObject { } - ///See - [TLDef(0x37C1011C)] - public partial class ChatPhotoEmpty : ChatPhotoBase { } ///See + ///a null value means chatPhotoEmpty [TLDef(0x1C6E1C11)] - public partial class ChatPhoto : ChatPhotoBase + public partial class ChatPhoto : ITLObject { [Flags] public enum Flags { has_video = 0x1, has_stripped_thumb = 0x2 } public Flags flags; @@ -744,10 +719,8 @@ namespace TL } ///See + ///a null value means messageMediaEmpty public abstract partial class MessageMedia : ITLObject { } - ///See - [TLDef(0x3DED6320)] - public partial class MessageMediaEmpty : MessageMedia { } ///See [TLDef(0x695150D7)] public partial class MessageMediaPhoto : MessageMedia @@ -759,7 +732,7 @@ namespace TL } ///See [TLDef(0x56E0D474)] - public partial class MessageMediaGeo : MessageMedia { public GeoPointBase geo; } + public partial class MessageMediaGeo : MessageMedia { public GeoPoint geo; } ///See [TLDef(0x70322949)] public partial class MessageMediaContact : MessageMedia @@ -789,7 +762,7 @@ namespace TL [TLDef(0x2EC0533F)] public partial class MessageMediaVenue : MessageMedia { - public GeoPointBase geo; + public GeoPoint geo; public string title; public string address; public string provider; @@ -819,7 +792,7 @@ namespace TL { [Flags] public enum Flags { has_heading = 0x1, has_proximity_notification_radius = 0x2 } public Flags flags; - public GeoPointBase geo; + public GeoPoint geo; [IfFlag(0)] public int heading; public int period; [IfFlag(1)] public int proximity_notification_radius; @@ -840,10 +813,8 @@ namespace TL } ///See + ///a null value means messageActionEmpty public abstract partial class MessageAction : ITLObject { } - ///See - [TLDef(0xB6AEF7B0)] - public partial class MessageActionEmpty : MessageAction { } ///See [TLDef(0xBD47CBAD)] public partial class MessageActionChatCreate : MessageAction @@ -1086,14 +1057,10 @@ namespace TL public byte[] bytes; } - ///See - public abstract partial class GeoPointBase : ITLObject { } - ///See - [TLDef(0x1117DD5F)] - public partial class GeoPointEmpty : GeoPointBase { } ///See + ///a null value means geoPointEmpty [TLDef(0xB2A2F663)] - public partial class GeoPoint : GeoPointBase + public partial class GeoPoint : ITLObject { [Flags] public enum Flags { has_accuracy_radius = 0x1 } public Flags flags; @@ -1400,10 +1367,8 @@ namespace TL } ///See + ///a null value means inputMessagesFilterEmpty public abstract partial class MessagesFilter : ITLObject { } - ///See - [TLDef(0x57E2F66C)] - public partial class InputMessagesFilterEmpty : MessagesFilter { } ///See [TLDef(0x9609A51C)] public partial class InputMessagesFilterPhotos : MessagesFilter { } @@ -1521,7 +1486,7 @@ namespace TL { public long user_id; public DateTime date; - public UserProfilePhotoBase photo; + public UserProfilePhoto photo; public bool previous; } ///See @@ -1710,7 +1675,7 @@ namespace TL public long query_id; public long user_id; public string query; - [IfFlag(0)] public GeoPointBase geo; + [IfFlag(0)] public GeoPoint geo; [IfFlag(1)] public InlineQueryPeerType peer_type; public string offset; } @@ -1722,7 +1687,7 @@ namespace TL public Flags flags; public long user_id; public string query; - [IfFlag(0)] public GeoPointBase geo; + [IfFlag(0)] public GeoPoint geo; public string id; [IfFlag(1)] public InputBotInlineMessageIDBase msg_id; } @@ -2445,14 +2410,10 @@ namespace TL public long access_hash; } - ///See - public abstract partial class EncryptedFileBase : ITLObject { } - ///See - [TLDef(0xC21F497E)] - public partial class EncryptedFileEmpty : EncryptedFileBase { } ///See + ///a null value means encryptedFileEmpty [TLDef(0x4A70994C)] - public partial class EncryptedFile : EncryptedFileBase + public partial class EncryptedFile : ITLObject { public long id; public long access_hash; @@ -2462,10 +2423,8 @@ namespace TL } ///See + ///a null value means inputEncryptedFileEmpty public abstract partial class InputEncryptedFileBase : ITLObject { } - ///See - [TLDef(0x1837C364)] - public partial class InputEncryptedFileEmpty : InputEncryptedFileBase { } ///See [TLDef(0x64BD0306)] public partial class InputEncryptedFileUploaded : InputEncryptedFileBase @@ -2501,7 +2460,7 @@ namespace TL public int chat_id; public DateTime date; public byte[] bytes; - public EncryptedFileBase file; + public EncryptedFile file; } ///See [TLDef(0x23734B06)] @@ -2533,16 +2492,12 @@ namespace TL public partial class Messages_SentEncryptedMessage : ITLObject { public DateTime date; } ///See [TLDef(0x9493FF32)] - public partial class Messages_SentEncryptedFile : Messages_SentEncryptedMessage { public EncryptedFileBase file; } + public partial class Messages_SentEncryptedFile : Messages_SentEncryptedMessage { public EncryptedFile file; } - ///See - public abstract partial class InputDocumentBase : ITLObject { } - ///See - [TLDef(0x72F0EAAE)] - public partial class InputDocumentEmpty : InputDocumentBase { } ///See + ///a null value means inputDocumentEmpty [TLDef(0x1ABFB575)] - public partial class InputDocument : InputDocumentBase + public partial class InputDocument : ITLObject { public long id; public long access_hash; @@ -3035,10 +2990,8 @@ namespace TL } ///See + ///a null value means inputStickerSetEmpty public abstract partial class InputStickerSet : ITLObject { } - ///See - [TLDef(0xFFB62B95)] - public partial class InputStickerSetEmpty : InputStickerSet { } ///See [TLDef(0x9DE7A269)] public partial class InputStickerSetID : InputStickerSet @@ -3269,10 +3222,8 @@ namespace TL public partial class MessageEntityBankCard : MessageEntity { } ///See + ///a null value means inputChannelEmpty public abstract partial class InputChannelBase : ITLObject { } - ///See - [TLDef(0xEE8C1E86)] - public partial class InputChannelEmpty : InputChannelBase { } ///See [TLDef(0xF35AEC28)] public partial class InputChannel : InputChannelBase @@ -3343,14 +3294,10 @@ namespace TL public UserBase[] users; } - ///See - public abstract partial class ChannelMessagesFilterBase : ITLObject { } - ///See - [TLDef(0x94D42EE7)] - public partial class ChannelMessagesFilterEmpty : ChannelMessagesFilterBase { } ///See + ///a null value means channelMessagesFilterEmpty [TLDef(0xCD77D957)] - public partial class ChannelMessagesFilter : ChannelMessagesFilterBase + public partial class ChannelMessagesFilter : ITLObject { [Flags] public enum Flags { exclude_new_messages = 0x2 } public Flags flags; @@ -3520,7 +3467,7 @@ namespace TL { [Flags] public enum Flags { has_heading = 0x1, has_period = 0x2, has_reply_markup = 0x4, has_proximity_notification_radius = 0x8 } - public InputGeoPointBase geo_point; + public InputGeoPoint geo_point; [IfFlag(0)] public int heading; [IfFlag(1)] public int period; [IfFlag(3)] public int proximity_notification_radius; @@ -3531,7 +3478,7 @@ namespace TL public partial class InputBotInlineMessageMediaVenue : InputBotInlineMessage { [Flags] public enum Flags { has_reply_markup = 0x4 } - public InputGeoPointBase geo_point; + public InputGeoPoint geo_point; public string title; public string address; public string provider; @@ -3595,7 +3542,7 @@ namespace TL { public string id; public string type; - public InputPhotoBase photo; + public InputPhoto photo; public InputBotInlineMessage send_message; } ///See @@ -3608,7 +3555,7 @@ namespace TL public string type; [IfFlag(1)] public string title; [IfFlag(2)] public string description; - public InputDocumentBase document; + public InputDocument document; public InputBotInlineMessage send_message; } ///See @@ -3646,7 +3593,7 @@ namespace TL { [Flags] public enum Flags { has_heading = 0x1, has_period = 0x2, has_reply_markup = 0x4, has_proximity_notification_radius = 0x8 } - public GeoPointBase geo; + public GeoPoint geo; [IfFlag(0)] public int heading; [IfFlag(1)] public int period; [IfFlag(3)] public int proximity_notification_radius; @@ -3657,7 +3604,7 @@ namespace TL public partial class BotInlineMessageMediaVenue : BotInlineMessage { [Flags] public enum Flags { has_reply_markup = 0x4 } - public GeoPointBase geo; + public GeoPoint geo; public string title; public string address; public string provider; @@ -3999,10 +3946,10 @@ namespace TL public abstract partial class InputStickeredMedia : ITLObject { } ///See [TLDef(0x4A992157)] - public partial class InputStickeredMediaPhoto : InputStickeredMedia { public InputPhotoBase id; } + public partial class InputStickeredMediaPhoto : InputStickeredMedia { public InputPhoto id; } ///See [TLDef(0x0438865B)] - public partial class InputStickeredMediaDocument : InputStickeredMedia { public InputDocumentBase id; } + public partial class InputStickeredMediaDocument : InputStickeredMedia { public InputDocument id; } ///See [TLDef(0xBDF9653B)] @@ -4054,10 +4001,8 @@ namespace TL } ///See + ///a null value means textEmpty public abstract partial class RichText : ITLObject { } - ///See - [TLDef(0xDC3D824F)] - public partial class TextEmpty : RichText { } ///See [TLDef(0x744694E0)] public partial class TextPlain : RichText { public string text; } @@ -4294,7 +4239,7 @@ namespace TL [TLDef(0xA44F3EF6)] public partial class PageBlockMap : PageBlock { - public GeoPointBase geo; + public GeoPoint geo; public int zoom; public int w; public int h; @@ -4427,7 +4372,7 @@ namespace TL [TLDef(0x9F2221C9)] public partial class InputWebFileGeoPointLocation : InputWebFileLocationBase { - public InputGeoPointBase geo_point; + public InputGeoPoint geo_point; public long access_hash; public int w; public int h; @@ -4562,7 +4507,7 @@ namespace TL { [Flags] public enum Flags { has_mask_coords = 0x1 } public Flags flags; - public InputDocumentBase document; + public InputDocument document; public string emoji; [IfFlag(0)] public MaskCoords mask_coords; } @@ -4873,8 +4818,8 @@ namespace TL [TLDef(0x0E6B76AE)] public partial class ChannelAdminLogEventActionChangeLocation : ChannelAdminLogEventAction { - public ChannelLocationBase prev_value; - public ChannelLocationBase new_value; + public ChannelLocation prev_value; + public ChannelLocation new_value; } ///See [TLDef(0x53909779)] @@ -5145,14 +5090,10 @@ namespace TL public long access_hash; } - ///See - public abstract partial class SecureFileBase : ITLObject { } - ///See - [TLDef(0x64199744)] - public partial class SecureFileEmpty : SecureFileBase { } ///See + ///a null value means secureFileEmpty [TLDef(0xE0277A62)] - public partial class SecureFile : SecureFileBase + public partial class SecureFile : ITLObject { public long id; public long access_hash; @@ -5221,11 +5162,11 @@ namespace TL public Flags flags; public SecureValueType type; [IfFlag(0)] public SecureData data; - [IfFlag(1)] public SecureFileBase front_side; - [IfFlag(2)] public SecureFileBase reverse_side; - [IfFlag(3)] public SecureFileBase selfie; - [IfFlag(6)] public SecureFileBase[] translation; - [IfFlag(4)] public SecureFileBase[] files; + [IfFlag(1)] public SecureFile front_side; + [IfFlag(2)] public SecureFile reverse_side; + [IfFlag(3)] public SecureFile selfie; + [IfFlag(6)] public SecureFile[] translation; + [IfFlag(4)] public SecureFile[] files; [IfFlag(5)] public SecurePlainData plain_data; public byte[] hash; } @@ -5351,14 +5292,10 @@ namespace TL public int length; } - ///See - public abstract partial class Help_DeepLinkInfoBase : ITLObject { } - ///See - [TLDef(0x66AFA166)] - public partial class Help_DeepLinkInfoEmpty : Help_DeepLinkInfoBase { } ///See + ///a null value means help.deepLinkInfoEmpty [TLDef(0x6A4EE832)] - public partial class Help_DeepLinkInfo : Help_DeepLinkInfoBase + public partial class Help_DeepLinkInfo : ITLObject { [Flags] public enum Flags { update_app = 0x1, has_entities = 0x2 } public Flags flags; @@ -5383,10 +5320,8 @@ namespace TL public partial class Account_Takeout : ITLObject { public long id; } ///See + ///a null value means passwordKdfAlgoUnknown public abstract partial class PasswordKdfAlgo : ITLObject { } - ///See - [TLDef(0xD45AB096)] - public partial class PasswordKdfAlgoUnknown : PasswordKdfAlgo { } ///See [TLDef(0x3A912D4A)] public partial class PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow : PasswordKdfAlgo @@ -5398,16 +5333,14 @@ namespace TL } ///See - public abstract partial class SecurePasswordKdfAlgo : ITLObject { } - ///See - [TLDef(0x004A8537)] - public partial class SecurePasswordKdfAlgoUnknown : SecurePasswordKdfAlgo { } + ///a null value means securePasswordKdfAlgoUnknown + public abstract partial class SecurePasswordKdfAlgo : ITLObject { public byte[] salt; } ///See [TLDef(0xBBF2DDA0)] - public partial class SecurePasswordKdfAlgoPBKDF2HMACSHA512iter100000 : SecurePasswordKdfAlgo { public byte[] salt; } + public partial class SecurePasswordKdfAlgoPBKDF2HMACSHA512iter100000 : SecurePasswordKdfAlgo { } ///See [TLDef(0x86471D92)] - public partial class SecurePasswordKdfAlgoSHA512 : SecurePasswordKdfAlgo { public byte[] salt; } + public partial class SecurePasswordKdfAlgoSHA512 : SecurePasswordKdfAlgo { } ///See [TLDef(0x1527BCAC)] @@ -5418,14 +5351,10 @@ namespace TL public long secure_secret_id; } - ///See - public abstract partial class InputCheckPasswordSRPBase : ITLObject { } - ///See - [TLDef(0x9880F658)] - public partial class InputCheckPasswordEmpty : InputCheckPasswordSRPBase { } ///See + ///a null value means inputCheckPasswordEmpty [TLDef(0xD27FF082)] - public partial class InputCheckPasswordSRP : InputCheckPasswordSRPBase + public partial class InputCheckPasswordSRP : ITLObject { public long srp_id; public byte[] A; @@ -5575,14 +5504,10 @@ namespace TL [TLDef(0x8C05F1C9)] public partial class Help_SupportName : ITLObject { public string name; } - ///See - public abstract partial class Help_UserInfoBase : ITLObject { } - ///See - [TLDef(0xF3AE2EED)] - public partial class Help_UserInfoEmpty : Help_UserInfoBase { } ///See + ///a null value means help.userInfoEmpty [TLDef(0x01EB3758)] - public partial class Help_UserInfo : Help_UserInfoBase + public partial class Help_UserInfo : ITLObject { public string message; public MessageEntity[] entities; @@ -5775,7 +5700,7 @@ namespace TL public Flags flags; public int id; public string title; - [IfFlag(3)] public ChatPhotoBase photo; + [IfFlag(3)] public ChatPhoto photo; } ///See @@ -5822,16 +5747,12 @@ namespace TL [TLDef(0xA9D6DB1F)] public partial class UrlAuthResultDefault : UrlAuthResult { } - ///See - public abstract partial class ChannelLocationBase : ITLObject { } - ///See - [TLDef(0xBFB5AD8B)] - public partial class ChannelLocationEmpty : ChannelLocationBase { } ///See + ///a null value means channelLocationEmpty [TLDef(0x209B82DB)] - public partial class ChannelLocation : ChannelLocationBase + public partial class ChannelLocation : ITLObject { - public GeoPointBase geo_point; + public GeoPoint geo_point; public string address; } @@ -6819,7 +6740,7 @@ namespace TL }); ///See - public static Task Auth_CheckPassword(this Client client, InputCheckPasswordSRPBase password) + public static Task Auth_CheckPassword(this Client client, InputCheckPasswordSRP password) => client.CallAsync(writer => { writer.Write(0xD18B4D16); @@ -7129,7 +7050,7 @@ namespace TL }); ///See - public static Task Account_GetPasswordSettings(this Client client, InputCheckPasswordSRPBase password) + public static Task Account_GetPasswordSettings(this Client client, InputCheckPasswordSRP password) => client.CallAsync(writer => { writer.Write(0x9CD4EAF9); @@ -7138,7 +7059,7 @@ namespace TL }); ///See - public static Task Account_UpdatePasswordSettings(this Client client, InputCheckPasswordSRPBase password, Account_PasswordInputSettings new_settings) + public static Task Account_UpdatePasswordSettings(this Client client, InputCheckPasswordSRP password, Account_PasswordInputSettings new_settings) => client.CallAsync(writer => { writer.Write(0xA59B102F); @@ -7168,7 +7089,7 @@ namespace TL }); ///See - public static Task Account_GetTmpPassword(this Client client, InputCheckPasswordSRPBase password, int period) + public static Task Account_GetTmpPassword(this Client client, InputCheckPasswordSRP password, int period) => client.CallAsync(writer => { writer.Write(0x449E0B51); @@ -7457,7 +7378,7 @@ namespace TL }); ///See - public static Task Account_CreateTheme(this Client client, string slug, string title, InputDocumentBase document = null, InputThemeSettings settings = null) + public static Task Account_CreateTheme(this Client client, string slug, string title, InputDocument document = null, InputThemeSettings settings = null) => client.CallAsync(writer => { writer.Write(0x8432C21F); @@ -7472,7 +7393,7 @@ namespace TL }); ///See - public static Task Account_UpdateTheme(this Client client, string format, InputThemeBase theme, string slug = null, string title = null, InputDocumentBase document = null, InputThemeSettings settings = null) + public static Task Account_UpdateTheme(this Client client, string format, InputThemeBase theme, string slug = null, string title = null, InputDocument document = null, InputThemeSettings settings = null) => client.CallAsync(writer => { writer.Write(0x5CB367D5); @@ -7578,7 +7499,7 @@ namespace TL }); ///See - public static Task Account_ReportProfilePhoto(this Client client, InputPeer peer, InputPhotoBase photo_id, ReportReason reason, string message) + public static Task Account_ReportProfilePhoto(this Client client, InputPeer peer, InputPhoto photo_id, ReportReason reason, string message) => client.CallAsync(writer => { writer.Write(0xFA8CC6F5); @@ -7812,7 +7733,7 @@ namespace TL }); ///See - public static Task Contacts_GetLocated(this Client client, InputGeoPointBase geo_point, bool background = false, int? self_expires = null) + public static Task Contacts_GetLocated(this Client client, InputGeoPoint geo_point, bool background = false, int? self_expires = null) => client.CallAsync(writer => { writer.Write(0xD348BC44); @@ -8416,7 +8337,7 @@ namespace TL }); ///See - public static Task Messages_SaveGif(this Client client, InputDocumentBase id, bool unsave) + public static Task Messages_SaveGif(this Client client, InputDocument id, bool unsave) => client.CallAsync(writer => { writer.Write(0x327A30CB); @@ -8426,7 +8347,7 @@ namespace TL }); ///See - public static Task Messages_GetInlineBotResults(this Client client, InputUserBase bot, InputPeer peer, string query, string offset, InputGeoPointBase geo_point = null) + public static Task Messages_GetInlineBotResults(this Client client, InputUserBase bot, InputPeer peer, string query, string offset, InputGeoPoint geo_point = null) => client.CallAsync(writer => { writer.Write(0x514E999D); @@ -8523,7 +8444,7 @@ namespace TL }); ///See - public static Task Messages_GetBotCallbackAnswer(this Client client, InputPeer peer, int msg_id, bool game = false, byte[] data = null, InputCheckPasswordSRPBase password = null) + public static Task Messages_GetBotCallbackAnswer(this Client client, InputPeer peer, int msg_id, bool game = false, byte[] data = null, InputCheckPasswordSRP password = null) => client.CallAsync(writer => { writer.Write(0x9342CA07); @@ -8613,7 +8534,7 @@ namespace TL }); ///See - public static Task Messages_SaveRecentSticker(this Client client, InputDocumentBase id, bool unsave, bool attached = false) + public static Task Messages_SaveRecentSticker(this Client client, InputDocument id, bool unsave, bool attached = false) => client.CallAsync(writer => { writer.Write(0x392718F8); @@ -8824,7 +8745,7 @@ namespace TL }); ///See - public static Task Messages_FaveSticker(this Client client, InputDocumentBase id, bool unfave) + public static Task Messages_FaveSticker(this Client client, InputDocument id, bool unfave) => client.CallAsync(writer => { writer.Write(0xB9FFC55B); @@ -8883,8 +8804,8 @@ namespace TL }); ///See - public static Task Messages_UploadEncryptedFile(this Client client, InputEncryptedChat peer, InputEncryptedFileBase file) - => client.CallAsync(writer => + public static Task Messages_UploadEncryptedFile(this Client client, InputEncryptedChat peer, InputEncryptedFileBase file) + => client.CallAsync(writer => { writer.Write(0x5057C497); writer.WriteTLObject(peer); @@ -9465,7 +9386,7 @@ namespace TL }); ///See - public static Task Updates_GetChannelDifference(this Client client, InputChannelBase channel, ChannelMessagesFilterBase filter, int pts, int limit, bool force = false) + public static Task Updates_GetChannelDifference(this Client client, InputChannelBase channel, ChannelMessagesFilter filter, int pts, int limit, bool force = false) => client.CallAsync(writer => { writer.Write(0x03173D78); @@ -9478,7 +9399,7 @@ namespace TL }); ///See - public static Task Photos_UpdateProfilePhoto(this Client client, InputPhotoBase id) + public static Task Photos_UpdateProfilePhoto(this Client client, InputPhoto id) => client.CallAsync(writer => { writer.Write(0x72D4742C); @@ -9502,7 +9423,7 @@ namespace TL }); ///See - public static Task Photos_DeletePhotos(this Client client, InputPhotoBase[] id) + public static Task Photos_DeletePhotos(this Client client, InputPhoto[] id) => client.CallAsync(writer => { writer.Write(0x87CF7F2F); @@ -9704,8 +9625,8 @@ namespace TL }); ///See - public static Task Help_GetDeepLinkInfo(this Client client, string path) - => client.CallAsync(writer => + public static Task Help_GetDeepLinkInfo(this Client client, string path) + => client.CallAsync(writer => { writer.Write(0x3FEDC75F); writer.WriteTLString(path); @@ -9747,8 +9668,8 @@ namespace TL }); ///See - public static Task Help_GetUserInfo(this Client client, InputUserBase user_id) - => client.CallAsync(writer => + public static Task Help_GetUserInfo(this Client client, InputUserBase user_id) + => client.CallAsync(writer => { writer.Write(0x038A08D3); writer.WriteTLObject(user_id); @@ -9756,8 +9677,8 @@ namespace TL }); ///See - public static Task Help_EditUserInfo(this Client client, InputUserBase user_id, string message, MessageEntity[] entities) - => client.CallAsync(writer => + public static Task Help_EditUserInfo(this Client client, InputUserBase user_id, string message, MessageEntity[] entities) + => client.CallAsync(writer => { writer.Write(0x66B91B70); writer.WriteTLObject(user_id); @@ -9896,7 +9817,7 @@ namespace TL }); ///See - public static Task Channels_CreateChannel(this Client client, string title, string about, bool broadcast = false, bool megagroup = false, bool for_import = false, InputGeoPointBase geo_point = null, string address = null) + public static Task Channels_CreateChannel(this Client client, string title, string about, bool broadcast = false, bool megagroup = false, bool for_import = false, InputGeoPoint geo_point = null, string address = null) => client.CallAsync(writer => { writer.Write(0x3D5FB10F); @@ -10126,7 +10047,7 @@ namespace TL }); ///See - public static Task Channels_EditCreator(this Client client, InputChannelBase channel, InputUserBase user_id, InputCheckPasswordSRPBase password) + public static Task Channels_EditCreator(this Client client, InputChannelBase channel, InputUserBase user_id, InputCheckPasswordSRP password) => client.CallAsync(writer => { writer.Write(0x8F38CD1F); @@ -10137,7 +10058,7 @@ namespace TL }); ///See - public static Task Channels_EditLocation(this Client client, InputChannelBase channel, InputGeoPointBase geo_point, string address) + public static Task Channels_EditLocation(this Client client, InputChannelBase channel, InputGeoPoint geo_point, string address) => client.CallAsync(writer => { writer.Write(0x58E63F6D); @@ -10325,7 +10246,7 @@ namespace TL }); ///See - public static Task Stickers_CreateStickerSet(this Client client, InputUserBase user_id, string title, string short_name, InputStickerSetItem[] stickers, bool masks = false, bool animated = false, InputDocumentBase thumb = null, string software = null) + public static Task Stickers_CreateStickerSet(this Client client, InputUserBase user_id, string title, string short_name, InputStickerSetItem[] stickers, bool masks = false, bool animated = false, InputDocument thumb = null, string software = null) => client.CallAsync(writer => { writer.Write(0x9021AB67); @@ -10342,7 +10263,7 @@ namespace TL }); ///See - public static Task Stickers_RemoveStickerFromSet(this Client client, InputDocumentBase sticker) + public static Task Stickers_RemoveStickerFromSet(this Client client, InputDocument sticker) => client.CallAsync(writer => { writer.Write(0xF7760F51); @@ -10351,7 +10272,7 @@ namespace TL }); ///See - public static Task Stickers_ChangeStickerPosition(this Client client, InputDocumentBase sticker, int position) + public static Task Stickers_ChangeStickerPosition(this Client client, InputDocument sticker, int position) => client.CallAsync(writer => { writer.Write(0xFFB6D4CA); @@ -10371,7 +10292,7 @@ namespace TL }); ///See - public static Task Stickers_SetStickerSetThumb(this Client client, InputStickerSet stickerset, InputDocumentBase thumb) + public static Task Stickers_SetStickerSetThumb(this Client client, InputStickerSet stickerset, InputDocument thumb) => client.CallAsync(writer => { writer.Write(0x9A364E30); diff --git a/src/TL.Secret.cs b/src/TL.Secret.cs index 3d7e81b..8f9e610 100644 --- a/src/TL.Secret.cs +++ b/src/TL.Secret.cs @@ -10,6 +10,7 @@ namespace TL public abstract partial class DecryptedMessageBase : ITLObject { } ///See + ///a null value means decryptedMessageMediaEmpty public abstract partial class DecryptedMessageMedia : ITLObject { } ///See @@ -38,9 +39,6 @@ namespace TL public DecryptedMessageAction action; } - ///See - [TLDef(0x089F5C4A)] - public partial class DecryptedMessageMediaEmpty : DecryptedMessageMedia { } ///See [TLDef(0x32798A8C)] public partial class DecryptedMessageMediaPhoto : DecryptedMessageMedia diff --git a/src/TL.Table.cs b/src/TL.Table.cs index 60f0178..69f6564 100644 --- a/src/TL.Table.cs +++ b/src/TL.Table.cs @@ -61,22 +61,22 @@ namespace TL // from TL.Schema: [0x3FEDD339] = typeof(True), [0xC4B9F9BB] = typeof(Error), - [0x56730BCC] = typeof(Null), - [0x7F3B18EA] = typeof(InputPeerEmpty), + [0x56730BCC] = null,//Null + [0x7F3B18EA] = null,//InputPeerEmpty [0x7DA07EC9] = typeof(InputPeerSelf), [0x35A95CB9] = typeof(InputPeerChat), [0xDDE8A54C] = typeof(InputPeerUser), [0x27BCBBFC] = typeof(InputPeerChannel), [0xA87B0A1C] = typeof(InputPeerUserFromMessage), [0xBD2A0840] = typeof(InputPeerChannelFromMessage), - [0xB98886CF] = typeof(InputUserEmpty), + [0xB98886CF] = null,//InputUserEmpty [0xF7C1B13F] = typeof(InputUserSelf), [0xF21158C6] = typeof(InputUser), [0x1DA448E2] = typeof(InputUserFromMessage), [0xF392B7F4] = typeof(InputPhoneContact), [0xF52FF27F] = typeof(InputFile), [0xFA4F0BB5] = typeof(InputFileBig), - [0x9664F57F] = typeof(InputMediaEmpty), + [0x9664F57F] = null,//InputMediaEmpty [0x1E287D04] = typeof(InputMediaUploadedPhoto), [0xB3BA0635] = typeof(InputMediaPhoto), [0xF9C44144] = typeof(InputMediaGeoPoint), @@ -91,12 +91,12 @@ namespace TL [0x971FA843] = typeof(InputMediaGeoLive), [0x0F94E5F1] = typeof(InputMediaPoll), [0xE66FBF7B] = typeof(InputMediaDice), - [0x1CA48F57] = typeof(InputChatPhotoEmpty), + [0x1CA48F57] = null,//InputChatPhotoEmpty [0xC642724E] = typeof(InputChatUploadedPhoto), [0x8953AD37] = typeof(InputChatPhoto), - [0xE4C123D6] = typeof(InputGeoPointEmpty), + [0xE4C123D6] = null,//InputGeoPointEmpty [0x48222FAF] = typeof(InputGeoPoint), - [0x1CD7BF0D] = typeof(InputPhotoEmpty), + [0x1CD7BF0D] = null,//InputPhotoEmpty [0x3BB3B94A] = typeof(InputPhoto), [0xDFDAABE1] = typeof(InputFileLocation), [0xF5235D55] = typeof(InputEncryptedFileLocation), @@ -113,9 +113,9 @@ namespace TL [0xA2A5371E] = typeof(PeerChannel), [0xD3BC4B7A] = typeof(UserEmpty), [0x3FF6ECB0] = typeof(User), - [0x4F11BAE1] = typeof(UserProfilePhotoEmpty), + [0x4F11BAE1] = null,//UserProfilePhotoEmpty [0x82D1F706] = typeof(UserProfilePhoto), - [0x09D05049] = typeof(UserStatusEmpty), + [0x09D05049] = null,//UserStatusEmpty [0xEDB93949] = typeof(UserStatusOnline), [0x008C703F] = typeof(UserStatusOffline), [0xE26F42F1] = typeof(UserStatusRecently), @@ -133,12 +133,12 @@ namespace TL [0xA0933F5B] = typeof(ChatParticipantAdmin), [0x8763D3E1] = typeof(ChatParticipantsForbidden), [0x3CBC93F8] = typeof(ChatParticipants), - [0x37C1011C] = typeof(ChatPhotoEmpty), + [0x37C1011C] = null,//ChatPhotoEmpty [0x1C6E1C11] = typeof(ChatPhoto), [0x90A6CA84] = typeof(MessageEmpty), [0x85D6CBE2] = typeof(Message), [0x2B085862] = typeof(MessageService), - [0x3DED6320] = typeof(MessageMediaEmpty), + [0x3DED6320] = null,//MessageMediaEmpty [0x695150D7] = typeof(MessageMediaPhoto), [0x56E0D474] = typeof(MessageMediaGeo), [0x70322949] = typeof(MessageMediaContact), @@ -151,7 +151,7 @@ namespace TL [0xB940C666] = typeof(MessageMediaGeoLive), [0x4BD6E798] = typeof(MessageMediaPoll), [0x3F7EE58B] = typeof(MessageMediaDice), - [0xB6AEF7B0] = typeof(MessageActionEmpty), + [0xB6AEF7B0] = null,//MessageActionEmpty [0xBD47CBAD] = typeof(MessageActionChatCreate), [0xB5A1CE5A] = typeof(MessageActionChatEditTitle), [0x7FCB13A8] = typeof(MessageActionChatEditPhoto), @@ -190,7 +190,7 @@ namespace TL [0xE0B0BC2E] = typeof(PhotoStrippedSize), [0xFA3EFB95] = typeof(PhotoSizeProgressive), [0xD8214D41] = typeof(PhotoPathSize), - [0x1117DD5F] = typeof(GeoPointEmpty), + [0x1117DD5F] = null,//GeoPointEmpty [0xB2A2F663] = typeof(GeoPoint), [0x5E002502] = typeof(Auth_SentCode), [0xCD050916] = typeof(Auth_Authorization), @@ -225,7 +225,7 @@ namespace TL [0x9CD81144] = typeof(Messages_ChatsSlice), [0xE5D7D19C] = typeof(Messages_ChatFull), [0xB45C69D1] = typeof(Messages_AffectedHistory), - [0x57E2F66C] = typeof(InputMessagesFilterEmpty), + [0x57E2F66C] = null,//InputMessagesFilterEmpty [0x9609A51C] = typeof(InputMessagesFilterPhotos), [0x9FC00E65] = typeof(InputMessagesFilterVideo), [0x56E9F0E4] = typeof(InputMessagesFilterPhotoVideo), @@ -364,9 +364,9 @@ namespace TL [0x61F0D4C7] = typeof(EncryptedChat), [0x1E1C7C45] = typeof(EncryptedChatDiscarded), [0xF141B5E1] = typeof(InputEncryptedChat), - [0xC21F497E] = typeof(EncryptedFileEmpty), + [0xC21F497E] = null,//EncryptedFileEmpty [0x4A70994C] = typeof(EncryptedFile), - [0x1837C364] = typeof(InputEncryptedFileEmpty), + [0x1837C364] = null,//InputEncryptedFileEmpty [0x64BD0306] = typeof(InputEncryptedFileUploaded), [0x5A17B5E5] = typeof(InputEncryptedFile), [0x2DC173C8] = typeof(InputEncryptedFileBigUploaded), @@ -376,7 +376,7 @@ namespace TL [0x2C221EDD] = typeof(Messages_DhConfig), [0x560F8935] = typeof(Messages_SentEncryptedMessage), [0x9493FF32] = typeof(Messages_SentEncryptedFile), - [0x72F0EAAE] = typeof(InputDocumentEmpty), + [0x72F0EAAE] = null,//InputDocumentEmpty [0x1ABFB575] = typeof(InputDocument), [0x36F8C871] = typeof(DocumentEmpty), [0x1E87342B] = typeof(Document), @@ -450,7 +450,7 @@ namespace TL [0x5A686D7C] = typeof(ChatInviteAlready), [0xDFC2F58E] = typeof(ChatInvite), [0x61695CB0] = typeof(ChatInvitePeek), - [0xFFB62B95] = typeof(InputStickerSetEmpty), + [0xFFB62B95] = null,//InputStickerSetEmpty [0x9DE7A269] = typeof(InputStickerSetID), [0x861CC8A0] = typeof(InputStickerSetShortName), [0x028703C8] = typeof(InputStickerSetAnimatedEmoji), @@ -494,7 +494,7 @@ namespace TL [0xBF0693D4] = typeof(MessageEntityStrike), [0x020DF5D0] = typeof(MessageEntityBlockquote), [0x761E6AF4] = typeof(MessageEntityBankCard), - [0xEE8C1E86] = typeof(InputChannelEmpty), + [0xEE8C1E86] = null,//InputChannelEmpty [0xF35AEC28] = typeof(InputChannel), [0x5B934F9D] = typeof(InputChannelFromMessage), [0x7F077AD9] = typeof(Contacts_ResolvedPeer), @@ -502,7 +502,7 @@ namespace TL [0x3E11AFFB] = typeof(Updates_ChannelDifferenceEmpty), [0xA4BCC6FE] = typeof(Updates_ChannelDifferenceTooLong), [0x2064674E] = typeof(Updates_ChannelDifference), - [0x94D42EE7] = typeof(ChannelMessagesFilterEmpty), + [0x94D42EE7] = null,//ChannelMessagesFilterEmpty [0xCD77D957] = typeof(ChannelMessagesFilter), [0xC00C07C0] = typeof(ChannelParticipant), [0x28A8BC67] = typeof(ChannelParticipantSelf), @@ -580,7 +580,7 @@ namespace TL [0xC331E80A] = typeof(InputGameShortName), [0x73A379EB] = typeof(HighScore), [0x9A3BFD99] = typeof(Messages_HighScores), - [0xDC3D824F] = typeof(TextEmpty), + [0xDC3D824F] = null,//TextEmpty [0x744694E0] = typeof(TextPlain), [0x6724ABC4] = typeof(TextBold), [0xD912A59C] = typeof(TextItalic), @@ -735,7 +735,7 @@ namespace TL [0x28ECF961] = typeof(Help_TermsOfServiceUpdate), [0x3334B0F0] = typeof(InputSecureFileUploaded), [0x5367E5BE] = typeof(InputSecureFile), - [0x64199744] = typeof(SecureFileEmpty), + [0x64199744] = null,//SecureFileEmpty [0xE0277A62] = typeof(SecureFile), [0x8AEABEC3] = typeof(SecureData), [0x7D6099DD] = typeof(SecurePlainPhone), @@ -755,17 +755,17 @@ namespace TL [0x33F0EA47] = typeof(SecureCredentialsEncrypted), [0xAD2E1CD8] = typeof(Account_AuthorizationForm), [0x811F854F] = typeof(Account_SentEmailCode), - [0x66AFA166] = typeof(Help_DeepLinkInfoEmpty), + [0x66AFA166] = null,//Help_DeepLinkInfoEmpty [0x6A4EE832] = typeof(Help_DeepLinkInfo), [0x1142BD56] = typeof(SavedPhoneContact), [0x4DBA4501] = typeof(Account_Takeout), - [0xD45AB096] = typeof(PasswordKdfAlgoUnknown), + [0xD45AB096] = null,//PasswordKdfAlgoUnknown [0x3A912D4A] = typeof(PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow), - [0x004A8537] = typeof(SecurePasswordKdfAlgoUnknown), + [0x004A8537] = null,//SecurePasswordKdfAlgoUnknown [0xBBF2DDA0] = typeof(SecurePasswordKdfAlgoPBKDF2HMACSHA512iter100000), [0x86471D92] = typeof(SecurePasswordKdfAlgoSHA512), [0x1527BCAC] = typeof(SecureSecretSettings), - [0x9880F658] = typeof(InputCheckPasswordEmpty), + [0x9880F658] = null,//InputCheckPasswordEmpty [0xD27FF082] = typeof(InputCheckPasswordSRP), [0x829D99DA] = typeof(SecureRequiredType), [0x027477B4] = typeof(SecureRequiredTypeOneOf), @@ -789,7 +789,7 @@ namespace TL [0xB390DC08] = typeof(PageRelatedArticle), [0x98657F0D] = typeof(Page), [0x8C05F1C9] = typeof(Help_SupportName), - [0xF3AE2EED] = typeof(Help_UserInfoEmpty), + [0xF3AE2EED] = null,//Help_UserInfoEmpty [0x01EB3758] = typeof(Help_UserInfo), [0x6CA9C2E9] = typeof(PollAnswer), [0x86E18161] = typeof(Poll), @@ -820,7 +820,7 @@ namespace TL [0x92D33A0E] = typeof(UrlAuthResultRequest), [0x8F8C0E4E] = typeof(UrlAuthResultAccepted), [0xA9D6DB1F] = typeof(UrlAuthResultDefault), - [0xBFB5AD8B] = typeof(ChannelLocationEmpty), + [0xBFB5AD8B] = null,//ChannelLocationEmpty [0x209B82DB] = typeof(ChannelLocation), [0xCA461B5D] = typeof(PeerLocated), [0xF8EC284B] = typeof(PeerSelfLocated), @@ -911,23 +911,18 @@ namespace TL [0x2A3C381F] = typeof(SponsoredMessage), [0x65A4C7D5] = typeof(Messages_SponsoredMessages), // from TL.Secret: - [0x91CC4674] = typeof(Layer73.DecryptedMessage), [0xBB718624] = typeof(Layer66.SendMessageUploadRoundAction), [0xE50511D8] = typeof(Layer45.DecryptedMessageMediaWebPage), [0x8A0DF56F] = typeof(Layer45.DecryptedMessageMediaVenue), - [0xDED218E0] = typeof(Layer45.DocumentAttributeAudio), - [0x3A556302] = typeof(Layer45.DocumentAttributeSticker), - [0x7AFE8AE2] = typeof(Layer45.DecryptedMessageMediaDocument), - [0x970C8C0E] = typeof(Layer45.DecryptedMessageMediaVideo), - [0xF1FA8D78] = typeof(Layer45.DecryptedMessageMediaPhoto), - [0x36B091DE] = typeof(Layer45.DecryptedMessage), [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), @@ -942,25 +937,67 @@ namespace TL [0xE6AC8A6F] = typeof(Layer17.SendMessageUploadAudioAction), [0x92042FF7] = typeof(Layer17.SendMessageUploadVideoAction), [0x1BE31789] = typeof(Layer17.DecryptedMessageLayer), - [0x57E0A9CB] = typeof(Layer17.DecryptedMessageMediaAudio), - [0x524A415D] = typeof(Layer17.DecryptedMessageMediaVideo), - [0x73164160] = typeof(Layer17.DecryptedMessageService), - [0x204D3878] = typeof(Layer17.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] = typeof(Layer8.DecryptedMessageMediaEmpty), + [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), // The End }; + + internal readonly static Dictionary Nullables = new() + { + // from TL.MTProto: + // from TL.Schema: + [typeof(Null)] = 0x56730BCC, //null + [typeof(InputPeer)] = 0x7F3B18EA, //inputPeerEmpty + [typeof(InputUserBase)] = 0xB98886CF, //inputUserEmpty + [typeof(InputMedia)] = 0x9664F57F, //inputMediaEmpty + [typeof(InputChatPhotoBase)] = 0x1CA48F57, //inputChatPhotoEmpty + [typeof(InputGeoPoint)] = 0xE4C123D6, //inputGeoPointEmpty + [typeof(InputPhoto)] = 0x1CD7BF0D, //inputPhotoEmpty + [typeof(UserProfilePhoto)] = 0x4F11BAE1, //userProfilePhotoEmpty + [typeof(UserStatus)] = 0x09D05049, //userStatusEmpty + [typeof(ChatPhoto)] = 0x37C1011C, //chatPhotoEmpty + [typeof(MessageMedia)] = 0x3DED6320, //messageMediaEmpty + [typeof(MessageAction)] = 0xB6AEF7B0, //messageActionEmpty + [typeof(GeoPoint)] = 0x1117DD5F, //geoPointEmpty + [typeof(MessagesFilter)] = 0x57E2F66C, //inputMessagesFilterEmpty + [typeof(EncryptedFile)] = 0xC21F497E, //encryptedFileEmpty + [typeof(InputEncryptedFileBase)] = 0x1837C364, //inputEncryptedFileEmpty + [typeof(InputDocument)] = 0x72F0EAAE, //inputDocumentEmpty + [typeof(InputStickerSet)] = 0xFFB62B95, //inputStickerSetEmpty + [typeof(InputChannelBase)] = 0xEE8C1E86, //inputChannelEmpty + [typeof(ChannelMessagesFilter)] = 0x94D42EE7, //channelMessagesFilterEmpty + [typeof(RichText)] = 0xDC3D824F, //textEmpty + [typeof(SecureFile)] = 0x64199744, //secureFileEmpty + [typeof(Help_DeepLinkInfo)] = 0x66AFA166, //help.deepLinkInfoEmpty + [typeof(PasswordKdfAlgo)] = 0xD45AB096, //passwordKdfAlgoUnknown + [typeof(SecurePasswordKdfAlgo)] = 0x004A8537, //securePasswordKdfAlgoUnknown + [typeof(InputCheckPasswordSRP)] = 0x9880F658, //inputCheckPasswordEmpty + [typeof(Help_UserInfo)] = 0xF3AE2EED, //help.userInfoEmpty + [typeof(ChannelLocation)] = 0xBFB5AD8B, //channelLocationEmpty + // from TL.Secret: + [typeof(DecryptedMessageMedia)] = 0x089F5C4A, //decryptedMessageMediaEmpty + // The End + }; } } diff --git a/src/TL.cs b/src/TL.cs index 9e1099e..0cb701c 100644 --- a/src/TL.cs +++ b/src/TL.cs @@ -29,9 +29,9 @@ namespace TL return (T)reader.ReadTLObject(); } - internal static void WriteTLObject(this BinaryWriter writer, ITLObject obj) + internal static void WriteTLObject(this BinaryWriter writer, T obj) where T : ITLObject { - if (obj == null) { writer.Write(Layer.NullCtor); return; } + if (obj == null) { writer.WriteTLNull(typeof(T)); return; } var type = obj.GetType(); var tlDef = type.GetCustomAttribute(); var ctorNb = tlDef.CtorNb; @@ -44,10 +44,7 @@ namespace TL { if (((ifFlag = field.GetCustomAttribute()) != null) && (flags & (1 << ifFlag.Bit)) == 0) continue; object value = field.GetValue(obj); - if (value == null) - writer.WriteTLNull(field.FieldType); - else - writer.WriteTLValue(value); + writer.WriteTLValue(value, field.FieldType); if (field.Name.Equals("Flags", StringComparison.OrdinalIgnoreCase)) flags = (int)value; } } @@ -55,9 +52,9 @@ namespace TL internal static ITLObject ReadTLObject(this BinaryReader reader, uint ctorNb = 0) { if (ctorNb == 0) ctorNb = reader.ReadUInt32(); - if (ctorNb == Layer.NullCtor) return null; if (!Layer.Table.TryGetValue(ctorNb, out var type)) throw new ApplicationException($"Cannot find type for ctor #{ctorNb:x}"); + if (type == null) return null; // nullable ctor (class meaning is associated with null) var tlDef = type.GetCustomAttribute(); var obj = Activator.CreateInstance(type); IEnumerable fields = type.GetFields(); @@ -75,8 +72,13 @@ namespace TL return type == typeof(GzipPacked) ? UnzipPacket((GzipPacked)obj, reader.Client) : (ITLObject)obj; } - internal static void WriteTLValue(this BinaryWriter writer, object value) + internal static void WriteTLValue(this BinaryWriter writer, object value, Type valueType) { + if (value == null) + { + writer.WriteTLNull(valueType); + return; + } var type = value.GetType(); switch (Type.GetTypeCode(type)) { @@ -153,8 +155,9 @@ namespace TL if (array == null) { writer.Write(0); return; } int count = array.Length; writer.Write(count); + var elementType = array.GetType().GetElementType(); for (int i = 0; i < count; i++) - writer.WriteTLValue(array.GetValue(i)); + writer.WriteTLValue(array.GetValue(i), elementType); } internal static Array ReadTLVector(this BinaryReader reader, Type type) @@ -232,7 +235,11 @@ namespace TL internal static void WriteTLNull(this BinaryWriter writer, Type type) { if (type == typeof(string)) { } - else if (!type.IsArray) { writer.Write(Layer.NullCtor); return; } + else if (!type.IsArray) + { + writer.Write(Layer.Nullables.TryGetValue(type, out uint nullCtor) ? nullCtor : Layer.NullCtor); + return; + } else if (type != typeof(byte[])) writer.Write(Layer.VectorCtor); // not raw bytes but a vector => needs a VectorCtor writer.Write(0); // null arrays/strings are serialized as empty