From 3784ad00ad3a66f2b3bb121d361aea5c0d33b868 Mon Sep 17 00:00:00 2001 From: Wizou <11647984+wiz0u@users.noreply.github.com> Date: Thu, 29 Sep 2022 11:53:41 +0200 Subject: [PATCH] TL abstract => virtual props --- EXAMPLES.md | 2 +- README.md | 7 +- src/TL.MTProto.cs | 6 +- src/TL.Schema.cs | 187 ++++++++++++++++++++---------------------- src/TL.SchemaFuncs.cs | 9 +- src/TL.Secret.cs | 8 +- 6 files changed, 106 insertions(+), 113 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index 5244be8..3b64eca 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -206,7 +206,7 @@ for (int offset = 0; ;) foreach (var (id, user) in participants.users) Console.WriteLine(user); offset += participants.participants.Length; - if (offset >= participants.count) break; + if (offset >= participants.count || participants.participants.Length == 0) break; } ``` diff --git a/README.md b/README.md index ef494fb..0006a19 100644 --- a/README.md +++ b/README.md @@ -140,9 +140,10 @@ or a [broadcast channel](https://corefork.telegram.org/api/channel#channels) (th - chats : In plural or general meaning, it means either `Chat` or `Channel` - `Peer` : Either a `Chat`, a `Channel` or a `User` - Dialog : Status of chat with a `Peer` *(draft, last message, unread count, pinned...)*. It represents each line from your Telegram chat list. -- DC (DataCenter) : There are a few datacenters depending on where in the world the user (or an uploaded media file) is from. - Access Hash : Telegram requires you to provide a specific `access_hash` for users, channels, and other resources before interacting with them. See [FAQ #4](https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md#access-hash) to learn more about it. +- DC (DataCenter) : There are a few datacenters depending on where in the world the user (or an uploaded media file) is from. +- Session or Authorization : Pairing between a device and a phone number. You can have several active sessions for the same phone number. # Other things to know @@ -169,8 +170,8 @@ This library can be used for any Telegram scenarios including: - Download/upload of files/media - Building a full-featured interactive client -It has been tested in a Console app, [in a WinForms app](https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md#gui), -[in ASP.NET webservice](https://github.com/wiz0u/WTelegramClient/blob/master/EXAMPLES.md#logging), and in Xamarin/Android. +It has been tested in a Console app, [in Windows Forms](https://github.com/wiz0u/WTelegramClient/raw/master/Examples/WinForms_app.zip), +[in ASP.NET webservice](https://github.com/wiz0u/WTelegramClient/raw/master/Examples/ASPnet_webapp.zip), and in Xamarin/Android. Please don't use this library for Spam or Scam. Respect Telegram [Terms of Service](https://telegram.org/tos) as well as the [API Terms of Service](https://core.telegram.org/api/terms) or you might get banned from Telegram servers. diff --git a/src/TL.MTProto.cs b/src/TL.MTProto.cs index e05fe98..d4623f1 100644 --- a/src/TL.MTProto.cs +++ b/src/TL.MTProto.cs @@ -159,9 +159,9 @@ namespace TL public abstract class MsgDetailedInfoBase : IObject { - public abstract long AnswerMsgId { get; } - public abstract int Bytes { get; } - public abstract int Status { get; } + public virtual long AnswerMsgId { get; } + public virtual int Bytes { get; } + public virtual int Status { get; } } [TLDef(0x276D3EC6)] //msg_detailed_info#276d3ec6 msg_id:long answer_msg_id:long bytes:int status:int = MsgDetailedInfo public class MsgDetailedInfo : MsgDetailedInfoBase diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs index d5ada77..c930ea4 100644 --- a/src/TL.Schema.cs +++ b/src/TL.Schema.cs @@ -132,11 +132,11 @@ namespace TL public abstract partial class InputFileBase : IObject { /// Random file identifier created by the client - public abstract long ID { get; } + public virtual long ID { get; } /// Number of parts saved - public abstract int Parts { get; } + public virtual int Parts { get; } /// Full name of the file - public abstract string Name { get; } + public virtual string Name { get; } } /// Defines a file saved in parts using the method upload.saveFilePart. See [TLDef(0xF52FF27F)] @@ -845,9 +845,9 @@ namespace TL public abstract partial class ChatBase : IObject { /// ID of the group - public abstract long ID { get; } + public virtual long ID { get; } /// Title - public abstract string Title { get; } + public virtual string Title { get; } } /// Empty constructor, group doesn't exist See [TLDef(0x29562865)] @@ -858,7 +858,6 @@ namespace TL /// Group identifier public override long ID => id; - public override string Title => default; } /// Info about a group See [TLDef(0x41CBF256)] @@ -1049,35 +1048,35 @@ namespace TL public abstract partial class ChatFullBase : IObject { /// ID of the chat - public abstract long ID { get; } + public virtual long ID { get; } /// About string for this chat - public abstract string About { get; } + public virtual string About { get; } /// Chat photo - public abstract PhotoBase ChatPhoto { get; } + public virtual PhotoBase ChatPhoto { get; } /// Notification settings - public abstract PeerNotifySettings NotifySettings { get; } + public virtual PeerNotifySettings NotifySettings { get; } /// Chat invite - public abstract ExportedChatInvite ExportedInvite { get; } + public virtual ExportedChatInvite ExportedInvite { get; } /// Info about bots that are in this chat - public abstract BotInfo[] BotInfo { get; } + public virtual BotInfo[] BotInfo { get; } /// Message ID of the last pinned message - public abstract int PinnedMsg { get; } + public virtual int PinnedMsg { get; } /// Peer folder ID, for more info click here - public abstract int Folder { get; } + public virtual int Folder { get; } /// Group call information - public abstract InputGroupCall Call { get; } + public virtual InputGroupCall Call { get; } /// Time-To-Live of messages sent by the current user to this chat - public abstract int TtlPeriod { get; } + public virtual int TtlPeriod { get; } /// When using phone.getGroupCallJoinAs to get a list of peers that can be used to join a group call, this field indicates the peer that should be selected by default. - public abstract Peer GroupcallDefaultJoinAs { get; } + public virtual Peer GroupcallDefaultJoinAs { get; } /// Emoji representing a specific chat theme - public abstract string ThemeEmoticon { get; } + public virtual string ThemeEmoticon { get; } /// Pending join requests » - public abstract int RequestsPending { get; } + public virtual int RequestsPending { get; } /// IDs of users who requested to join recently - public abstract long[] RecentRequesters { get; } + public virtual long[] RecentRequesters { get; } /// Allowed message reactions » - public abstract ChatReactions AvailableReactions { get; } + public virtual ChatReactions AvailableReactions { get; } } /// Full info about a basic group. See [TLDef(0xC9D31138)] @@ -1366,7 +1365,7 @@ namespace TL public abstract partial class ChatParticipantBase : IObject { /// Member user ID - public abstract long UserId { get; } + public virtual long UserId { get; } } /// Group member. See [TLDef(0xC02D4007)] @@ -1402,7 +1401,7 @@ namespace TL public abstract partial class ChatParticipantsBase : IObject { /// Group ID - public abstract long ChatId { get; } + public virtual long ChatId { get; } } /// Info on members is unavailable See [TLDef(0x8763D3E1)] @@ -1466,17 +1465,17 @@ namespace TL public abstract class MessageBase : IObject { /// ID of the message - public abstract int ID { get; } + public virtual int ID { get; } /// ID of the sender of the message - public abstract Peer From { get; } + public virtual Peer From { get; } /// Peer ID, the chat where this message was sent - public abstract Peer Peer { get; } + public virtual Peer Peer { get; } /// Reply information - public abstract MessageReplyHeader ReplyTo { get; } + public virtual MessageReplyHeader ReplyTo { get; } /// Date of the message - public abstract DateTime Date { get; } + public virtual DateTime Date { get; } /// Time To Live of the message, once message.date+message.ttl_period === time(), the message will be deleted on the server, and must be deleted locally as well. - public abstract int TtlPeriod { get; } + public virtual int TtlPeriod { get; } } /// Empty constructor, non-existent message. See [TLDef(0x90A6CA84)] @@ -1497,12 +1496,8 @@ namespace TL /// Message identifier public override int ID => id; - public override Peer From => default; /// Peer ID, the chat where this message was sent public override Peer Peer => peer_id; - public override MessageReplyHeader ReplyTo => default; - public override DateTime Date => default; - public override int TtlPeriod => default; } /// A message See [TLDef(0x38116EE0)] @@ -2146,9 +2141,9 @@ namespace TL public abstract class DialogBase : IObject { /// The chat - public abstract Peer Peer { get; } + public virtual Peer Peer { get; } /// The latest message ID - public abstract int TopMessage { get; } + public virtual int TopMessage { get; } } /// Chat See [TLDef(0xA8EDD0F5)] @@ -2274,7 +2269,7 @@ namespace TL public abstract partial class PhotoSizeBase : IObject { /// Thumbnail type (see. ) - public abstract string Type { get; } + public virtual string Type { get; } } /// Empty constructor. Image with this thumbnail is unavailable. See [TLDef(0x0E17E23C)] @@ -2582,9 +2577,9 @@ namespace TL public abstract class WallPaperBase : IObject { /// Identifier - public abstract long ID { get; } + public virtual long ID { get; } /// Info on how to generate the wallpaper, according to these instructions ». - public abstract WallPaperSettings Settings { get; } + public virtual WallPaperSettings Settings { get; } } /// Represents a wallpaper based on an image. See [TLDef(0xA437C3ED)] @@ -2834,9 +2829,9 @@ namespace TL public abstract partial class Messages_DialogsBase : IObject, IPeerResolver { /// List of chats - public abstract DialogBase[] Dialogs { get; } + public virtual DialogBase[] Dialogs { get; } /// List of last messages from each chat - public abstract MessageBase[] Messages { get; } + public virtual MessageBase[] Messages { get; } /// returns a or for the given Peer public abstract IPeerInfo UserOrChat(Peer peer); } @@ -2873,9 +2868,6 @@ namespace TL { /// Number of dialogs found server-side by the query public int count; - - public override DialogBase[] Dialogs => default; - public override MessageBase[] Messages => default; /// returns a or for the given Peer public override IPeerInfo UserOrChat(Peer peer) => null; } @@ -2884,7 +2876,7 @@ namespace TL public abstract partial class Messages_MessagesBase : IObject, IPeerResolver { /// List of messages - public abstract MessageBase[] Messages { get; } + public virtual MessageBase[] Messages { get; } /// returns a or for the given Peer public abstract IPeerInfo UserOrChat(Peer peer); } @@ -2965,8 +2957,6 @@ namespace TL { /// Number of results found server-side by the given query public int count; - - public override MessageBase[] Messages => default; /// returns a or for the given Peer public override IPeerInfo UserOrChat(Peer peer) => null; } @@ -4271,17 +4261,20 @@ namespace TL /// The list of recent message reactions has changed See [TLDef(0x6F7863F4)] public class UpdateRecentReactions : Update { } - /// See + /// A stickerset was just moved to top, see here for more info » See [TLDef(0x86FCCF85)] public class UpdateMoveStickerSetToTop : Update { /// Flags, see TL conditional fields public Flags flags; + /// Stickerset ID public long stickerset; [Flags] public enum Flags : uint { + /// This update is referring to a mask stickerset masks = 0x1, + /// This update is referring to a custom emoji stickerset emojis = 0x2, } } @@ -4314,11 +4307,11 @@ namespace TL public abstract partial class Updates_DifferenceBase : IObject, IPeerResolver { /// List of new messages - public abstract MessageBase[] NewMessages { get; } + public virtual MessageBase[] NewMessages { get; } /// List of new encrypted secret chat messages - public abstract EncryptedMessageBase[] NewEncryptedMessages { get; } + public virtual EncryptedMessageBase[] NewEncryptedMessages { get; } /// List of updates - public abstract Update[] OtherUpdates { get; } + public virtual Update[] OtherUpdates { get; } /// returns a or for the given Peer public abstract IPeerInfo UserOrChat(Peer peer); } @@ -4395,10 +4388,6 @@ namespace TL { /// The new state to use. public int pts; - - public override MessageBase[] NewMessages => default; - public override EncryptedMessageBase[] NewEncryptedMessages => default; - public override Update[] OtherUpdates => default; /// returns a or for the given Peer public override IPeerInfo UserOrChat(Peer peer) => null; } @@ -4407,7 +4396,7 @@ namespace TL public abstract partial class UpdatesBase : IObject, IPeerResolver { /// date - public abstract DateTime Date { get; } + public virtual DateTime Date { get; } /// returns a or for the given Peer public abstract IPeerInfo UserOrChat(Peer peer); } @@ -4415,7 +4404,6 @@ namespace TL [TLDef(0xE317AF7E)] public partial class UpdatesTooLong : UpdatesBase, IPeerResolver { - public override DateTime Date => default; /// returns a or for the given Peer public override IPeerInfo UserOrChat(Peer peer) => null; } @@ -4910,7 +4898,7 @@ namespace TL public abstract class EncryptedChatBase : IObject { /// Chat ID - public abstract int ID { get; } + public virtual int ID { get; } } /// Empty constructor. See [TLDef(0xAB7EC0A0)] @@ -5043,7 +5031,7 @@ namespace TL public abstract class InputEncryptedFileBase : IObject { /// Random file ID created by client - public abstract long ID { get; } + public virtual long ID { get; } } /// Sets new encrypted file saved by parts using upload.saveFilePart method. See [TLDef(0x64BD0306)] @@ -5092,13 +5080,13 @@ namespace TL public abstract class EncryptedMessageBase : IObject { /// Random message ID, assigned by the author of message - public abstract long RandomId { get; } + public virtual long RandomId { get; } /// ID of encrypted chat - public abstract int ChatId { get; } + public virtual int ChatId { get; } /// Date of sending - public abstract DateTime Date { get; } + public virtual DateTime Date { get; } /// TL-serialization of type, encrypted with the key created at chat initialization - public abstract byte[] Bytes { get; } + public virtual byte[] Bytes { get; } } /// Encrypted message. See [TLDef(0xED18C118)] @@ -5692,7 +5680,7 @@ namespace TL public abstract class WebPageBase : IObject { /// Preview ID - public abstract long ID { get; } + public virtual long ID { get; } } /// No preview is available for the webpage See [TLDef(0xEB1477E8)] @@ -5804,8 +5792,6 @@ namespace TL /// Field has a value has_cached_page_views = 0x1, } - - public override long ID => default; } /// Logged-in session See @@ -6240,7 +6226,7 @@ namespace TL public abstract class KeyboardButtonBase : IObject { /// Button text - public abstract string Text { get; } + public virtual string Text { get; } } /// Bot keyboard button See [TLDef(0xA2FA4880)] @@ -6586,7 +6572,7 @@ namespace TL public abstract class InputChannelBase : IObject { /// Channel ID - public abstract long ChannelId { get; } + public virtual long ChannelId { get; } } /// Represents a channel See [TLDef(0xF35AEC28)] @@ -7148,9 +7134,9 @@ namespace TL public abstract class InputBotInlineResultBase : IObject { /// ID of result - public abstract string ID { get; } + public virtual string ID { get; } /// Message to send when the result is selected - public abstract InputBotInlineMessage SendMessage { get; } + public virtual InputBotInlineMessage SendMessage { get; } } /// An inline bot result See [TLDef(0x88BF9319)] @@ -7422,15 +7408,15 @@ namespace TL public abstract class BotInlineResultBase : IObject { /// Result ID - public abstract string ID { get; } + public virtual string ID { get; } /// Result type (see bot API docs) - public abstract string Type { get; } + public virtual string Type { get; } /// Result title - public abstract string Title { get; } + public virtual string Title { get; } /// Result description - public abstract string Description { get; } + public virtual string Description { get; } /// Message to send - public abstract BotInlineMessage SendMessage { get; } + public virtual BotInlineMessage SendMessage { get; } } /// Generic result See [TLDef(0x11965F3A)] @@ -7657,7 +7643,7 @@ namespace TL /// Prefix of the phone number from which the call will be made public string prefix; } - /// The code was sent via email See + /// The code was sent via the previously configured login email » See [TLDef(0x5A159841)] public class Auth_SentCodeTypeEmailCode : Auth_SentCodeType { @@ -7680,7 +7666,7 @@ namespace TL has_next_phone_login_date = 0x4, } } - /// The user should add and verify an email address in order to login See + /// The user should add and verify an email address in order to login as described here ». See [TLDef(0xA5491DEA)] public class Auth_SentCodeTypeSetUpEmailRequired : Auth_SentCodeType { @@ -7742,9 +7728,9 @@ namespace TL public abstract class InputBotInlineMessageIDBase : IObject { /// DC ID to use when working with this inline message - public abstract int DcId { get; } + public virtual int DcId { get; } /// Access hash of message - public abstract long AccessHash { get; } + public virtual long AccessHash { get; } } /// Represents a sent inline message from the perspective of a bot (legacy constructor) See [TLDef(0x890C3D89)] @@ -7988,7 +7974,7 @@ namespace TL public abstract class StickerSetCoveredBase : IObject { /// Stickerset - public abstract StickerSet Set { get; } + public virtual StickerSet Set { get; } } /// Stickerset with a single sticker as preview See [TLDef(0x6410A5D2)] @@ -8709,13 +8695,13 @@ namespace TL public abstract class WebDocumentBase : IObject { /// Document URL - public abstract string Url { get; } + public virtual string Url { get; } /// File size - public abstract int Size { get; } + public virtual int Size { get; } /// MIME type - public abstract string MimeType { get; } + public virtual string MimeType { get; } /// Attributes for media types - public abstract DocumentAttribute[] Attributes { get; } + public virtual DocumentAttribute[] Attributes { get; } } /// Remote document See [TLDef(0x1C570ED1)] @@ -9100,7 +9086,7 @@ namespace TL public abstract class PhoneCallBase : IObject { /// Call ID - public abstract long ID { get; } + public virtual long ID { get; } } /// Empty constructor See [TLDef(0x5366C915)] @@ -9277,13 +9263,13 @@ namespace TL public abstract class PhoneConnectionBase : IObject { /// Endpoint ID - public abstract long ID { get; } + public virtual long ID { get; } /// IP address of endpoint - public abstract string Ip { get; } + public virtual string Ip { get; } /// IPv6 address of endpoint - public abstract string Ipv6 { get; } + public virtual string Ipv6 { get; } /// Port ID - public abstract int Port { get; } + public virtual int Port { get; } } /// Identifies an endpoint that can be used to connect to the other user in a phone call See [TLDef(0x9CC123C7)] @@ -9425,7 +9411,7 @@ namespace TL public abstract class LangPackStringBase : IObject { /// Language key - public abstract string Key { get; } + public virtual string Key { get; } } /// Translated localization string See [TLDef(0xCAD181F6)] @@ -10141,7 +10127,7 @@ namespace TL public abstract class InputSecureFileBase : IObject { /// Secure file ID - public abstract long ID { get; } + public virtual long ID { get; } } /// Uploaded secure file, for more info see the passport docs » See [TLDef(0x3334B0F0)] @@ -10355,9 +10341,9 @@ namespace TL public abstract class SecureValueErrorBase : IObject { /// The section of the user's Telegram Passport which has the error, one of , , , , , - public abstract SecureValueType Type { get; } + public virtual SecureValueType Type { get; } /// Error message - public abstract string Text { get; } + public virtual string Text { get; } } /// Represents an issue in one of the data fields that was provided by the user. The error is considered resolved when the field's value changes. See [TLDef(0xE8A40BD9)] @@ -11390,7 +11376,7 @@ namespace TL public abstract class PeerLocatedBase : IObject { /// Validity period of current data - public abstract DateTime Expires { get; } + public virtual DateTime Expires { get; } } /// Peer geolocated nearby See [TLDef(0xCA461B5D)] @@ -11662,9 +11648,9 @@ namespace TL public abstract class MessageUserVoteBase : IObject { /// User ID - public abstract long UserId { get; } + public virtual long UserId { get; } /// When did the user cast the vote - public abstract DateTime Date { get; } + public virtual DateTime Date { get; } } /// How a user voted in a poll See [TLDef(0x34D247B4)] @@ -12288,9 +12274,9 @@ namespace TL public abstract class GroupCallBase : IObject { /// Group call ID - public abstract long ID { get; } + public virtual long ID { get; } /// Group call access hash - public abstract long AccessHash { get; } + public virtual long AccessHash { get; } } /// An ended group call See [TLDef(0x7780BCB4)] @@ -12580,9 +12566,9 @@ namespace TL public abstract class Messages_ExportedChatInviteBase : IObject { /// Info about the chat invite - public abstract ExportedChatInvite Invite { get; } + public virtual ExportedChatInvite Invite { get; } /// Mentioned users - public abstract Dictionary Users { get; } + public virtual Dictionary Users { get; } } /// Info about a chat invite See [TLDef(0x1871BE50)] @@ -12961,6 +12947,7 @@ namespace TL { /// Flags, see TL conditional fields public Flags flags; + /// If set, indicates that the current user also sent this reaction.
The integer value indicates when was the reaction added: the bigger the value, the newer the reaction.
[IfFlag(0)] public int chosen_order; /// Reaction (a UTF8 emoji) public Reaction reaction; @@ -13539,7 +13526,9 @@ namespace TL [TLDef(0x4345BE73)] public class EmailVerifyPurposeLoginSetup : EmailVerifyPurpose { + /// Phone number public string phone_number; + /// Phone code hash as specified by the documentation public string phone_code_hash; } /// Email verification purpose: change login email See diff --git a/src/TL.SchemaFuncs.cs b/src/TL.SchemaFuncs.cs index d5b7f7d..d6c90b4 100644 --- a/src/TL.SchemaFuncs.cs +++ b/src/TL.SchemaFuncs.cs @@ -1416,6 +1416,7 @@ namespace TL /// Send this message as background message /// Clear the draft field /// Only for bots, disallows forwarding and saving of the messages, even if the destination chat doesn't have content protection enabled + /// Whether to move used stickersets to top, see here for more info on this flag » /// The destination where the message will be sent /// The message ID to which this message will reply to /// The message @@ -1443,6 +1444,7 @@ namespace TL /// Send message in background /// Clear the draft /// Only for bots, disallows forwarding and saving of the messages, even if the destination chat doesn't have content protection enabled + /// Whether to move used stickersets to top, see here for more info on this flag » /// Destination /// Message ID to which this message should reply to /// Attached media @@ -1929,7 +1931,7 @@ namespace TL unsave = unsave, }); - /// Query an inline bot See Possible codes: 400,-503 (details) + /// Query an inline bot See Possible codes: -503,400 (details) /// The bot to query /// The currently opened chat /// The geolocation, if requested @@ -2040,7 +2042,7 @@ namespace TL entities = entities, }); - /// Press an inline callback button and get a callback answer from the bot See Possible codes: 400,-503 (details) + /// Press an inline callback button and get a callback answer from the bot See Possible codes: -503,400 (details) /// Whether this is a "play game" button /// Where was the inline keyboard sent /// ID of the Message with the inline keyboard @@ -2403,6 +2405,7 @@ namespace TL /// Send in background? /// Whether to clear drafts /// Only for bots, disallows forwarding and saving of the messages, even if the destination chat doesn't have content protection enabled + /// Whether to move used stickersets to top, see here for more info on this flag » /// The destination chat /// The message to reply to /// The medias to send @@ -3112,7 +3115,7 @@ namespace TL hash = hash, }); - /// Change default emoji reaction to use in the quick reaction menu: the value is synced across devices and can be fetched using help.getAppConfig, reactions_default field. See + /// Change default emoji reaction to use in the quick reaction menu: the value is synced across devices and can be fetched using help.getAppConfig, reactions_default field. See Possible codes: 400 (details) /// New emoji reaction public static Task Messages_SetDefaultReaction(this Client client, Reaction reaction) => client.Invoke(new Messages_SetDefaultReaction diff --git a/src/TL.Secret.cs b/src/TL.Secret.cs index 49d375d..5688752 100644 --- a/src/TL.Secret.cs +++ b/src/TL.Secret.cs @@ -6,7 +6,7 @@ namespace TL public abstract class DecryptedMessageBase : IObject { /// Random message ID, assigned by the author of message.
Must be equal to the ID passed to sending method.
- public abstract long RandomId { get; } + public virtual long RandomId { get; } } /// Object describes media contents of an encrypted message. See @@ -20,11 +20,11 @@ namespace TL public abstract class FileLocationBase : IObject { /// Server volume - public abstract long VolumeId { get; } + public virtual long VolumeId { get; } /// File ID - public abstract int LocalId { get; } + public virtual int LocalId { get; } /// Checksum to access the file - public abstract long Secret { get; } + public virtual long Secret { get; } } namespace Layer8