From d631c2fd892c1671373dac7a9a5bfa7ad9002f4e Mon Sep 17 00:00:00 2001 From: Andrew Slobodyanuk Date: Thu, 7 Sep 2017 13:40:48 +0300 Subject: [PATCH] Added two methods - GetUserProfileImage and GetUserPhotos Had to write this for my project and now i suggest you adding them here. You may want to check catch blocks in my methods to ensure they are correct. There is quite a mess in GetUserProfileImage method but it seems to work properly, so that i decided to suggest it not matter what. --- TLSharp.Core/TelegramClient.cs | 886 ++++++++++++++++++--------------- 1 file changed, 495 insertions(+), 391 deletions(-) diff --git a/TLSharp.Core/TelegramClient.cs b/TLSharp.Core/TelegramClient.cs index a8f8842d..7febf2b7 100644 --- a/TLSharp.Core/TelegramClient.cs +++ b/TLSharp.Core/TelegramClient.cs @@ -1,170 +1,170 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Cryptography; -using System.Text; -using System.Threading.Tasks; -using TeleSharp.TL; -using TeleSharp.TL.Account; -using TeleSharp.TL.Auth; -using TeleSharp.TL.Contacts; -using TeleSharp.TL.Help; -using TeleSharp.TL.Messages; -using TeleSharp.TL.Upload; -using TLSharp.Core.Auth; -using TLSharp.Core.MTProto.Crypto; -using TLSharp.Core.Network; -using TLSharp.Core.Utils; -using TLAuthorization = TeleSharp.TL.Auth.TLAuthorization; - -namespace TLSharp.Core -{ - public class TelegramClient : IDisposable - { - private MtProtoSender _sender; - private AuthKey _key; - private TcpTransport _transport; - private string _apiHash = ""; - private int _apiId = 0; - private Session _session; - private List dcOptions; - private TcpClientConnectionHandler _handler; - - public TelegramClient(int apiId, string apiHash, - ISessionStore store = null, string sessionUserId = "session", TcpClientConnectionHandler handler = null) - { - if (apiId == default(int)) - throw new MissingApiConfigurationException("API_ID"); - if (string.IsNullOrEmpty(apiHash)) - throw new MissingApiConfigurationException("API_HASH"); - - if (store == null) - store = new FileSessionStore(); - - TLContext.Init(); - _apiHash = apiHash; - _apiId = apiId; - _handler = handler; - - _session = Session.TryLoadOrCreateNew(store, sessionUserId); - _transport = new TcpTransport(_session.ServerAddress, _session.Port, _handler); - } - - public async Task ConnectAsync(bool reconnect = false) - { - if (_session.AuthKey == null || reconnect) - { - var result = await Authenticator.DoAuthentication(_transport); - _session.AuthKey = result.AuthKey; - _session.TimeOffset = result.TimeOffset; - } - - _sender = new MtProtoSender(_transport, _session); - - //set-up layer - var config = new TLRequestGetConfig(); - var request = new TLRequestInitConnection() - { - api_id = _apiId, - app_version = "1.0.0", - device_model = "PC", - lang_code = "en", - query = config, - system_version = "Win 10.0" - }; - var invokewithLayer = new TLRequestInvokeWithLayer() { layer = 66, query = request }; - await _sender.Send(invokewithLayer); - await _sender.Receive(invokewithLayer); - - dcOptions = ((TLConfig)invokewithLayer.Response).dc_options.lists; - - return true; - } - - private async Task ReconnectToDcAsync(int dcId) - { - if (dcOptions == null || !dcOptions.Any()) - throw new InvalidOperationException($"Can't reconnect. Establish initial connection first."); - - var dc = dcOptions.First(d => d.id == dcId); - - _transport = new TcpTransport(dc.ip_address, dc.port, _handler); - _session.ServerAddress = dc.ip_address; - _session.Port = dc.port; - - await ConnectAsync(true); - } - - public bool IsUserAuthorized() - { - return _session.TLUser != null; - } - - public async Task IsPhoneRegisteredAsync(string phoneNumber) - { - if (String.IsNullOrWhiteSpace(phoneNumber)) - throw new ArgumentNullException(nameof(phoneNumber)); - - if (_sender == null) - throw new InvalidOperationException("Not connected!"); - - var authCheckPhoneRequest = new TLRequestCheckPhone() { phone_number = phoneNumber }; - var completed = false; - while(!completed) - { - try - { - await _sender.Send(authCheckPhoneRequest); - await _sender.Receive(authCheckPhoneRequest); - completed = true; - } - catch(PhoneMigrationException e) - { - await ReconnectToDcAsync(e.DC); - } - } - return authCheckPhoneRequest.Response.phone_registered; - } - - public async Task SendCodeRequestAsync(string phoneNumber) - { - if (String.IsNullOrWhiteSpace(phoneNumber)) - throw new ArgumentNullException(nameof(phoneNumber)); - - var completed = false; - - TLRequestSendCode request = null; - - while (!completed) - { - request = new TLRequestSendCode() { phone_number = phoneNumber, api_id = _apiId, api_hash = _apiHash }; - try - { - await _sender.Send(request); - await _sender.Receive(request); - - completed = true; - } - catch (PhoneMigrationException ex) - { - await ReconnectToDcAsync(ex.DC); - } - } - - return request.Response.phone_code_hash; - } - - public async Task MakeAuthAsync(string phoneNumber, string phoneCodeHash, string code) - { - if (String.IsNullOrWhiteSpace(phoneNumber)) - throw new ArgumentNullException(nameof(phoneNumber)); - - if (String.IsNullOrWhiteSpace(phoneCodeHash)) - throw new ArgumentNullException(nameof(phoneCodeHash)); - - if (String.IsNullOrWhiteSpace(code)) - throw new ArgumentNullException(nameof(code)); - +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using TeleSharp.TL; +using TeleSharp.TL.Account; +using TeleSharp.TL.Auth; +using TeleSharp.TL.Contacts; +using TeleSharp.TL.Help; +using TeleSharp.TL.Messages; +using TeleSharp.TL.Upload; +using TLSharp.Core.Auth; +using TLSharp.Core.MTProto.Crypto; +using TLSharp.Core.Network; +using TLSharp.Core.Utils; +using TLAuthorization = TeleSharp.TL.Auth.TLAuthorization; + +namespace TLSharp.Core +{ + public class TelegramClient : IDisposable + { + private MtProtoSender _sender; + private AuthKey _key; + private TcpTransport _transport; + private string _apiHash = ""; + private int _apiId = 0; + private Session _session; + private List dcOptions; + private TcpClientConnectionHandler _handler; + + public TelegramClient(int apiId, string apiHash, + ISessionStore store = null, string sessionUserId = "session", TcpClientConnectionHandler handler = null) + { + if (apiId == default(int)) + throw new MissingApiConfigurationException("API_ID"); + if (string.IsNullOrEmpty(apiHash)) + throw new MissingApiConfigurationException("API_HASH"); + + if (store == null) + store = new FileSessionStore(); + + TLContext.Init(); + _apiHash = apiHash; + _apiId = apiId; + _handler = handler; + + _session = Session.TryLoadOrCreateNew(store, sessionUserId); + _transport = new TcpTransport(_session.ServerAddress, _session.Port, _handler); + } + + public async Task ConnectAsync(bool reconnect = false) + { + if (_session.AuthKey == null || reconnect) + { + var result = await Authenticator.DoAuthentication(_transport); + _session.AuthKey = result.AuthKey; + _session.TimeOffset = result.TimeOffset; + } + + _sender = new MtProtoSender(_transport, _session); + + //set-up layer + var config = new TLRequestGetConfig(); + var request = new TLRequestInitConnection() + { + api_id = _apiId, + app_version = "1.0.0", + device_model = "PC", + lang_code = "en", + query = config, + system_version = "Win 10.0" + }; + var invokewithLayer = new TLRequestInvokeWithLayer() { layer = 66, query = request }; + await _sender.Send(invokewithLayer); + await _sender.Receive(invokewithLayer); + + dcOptions = ((TLConfig)invokewithLayer.Response).dc_options.lists; + + return true; + } + + private async Task ReconnectToDcAsync(int dcId) + { + if (dcOptions == null || !dcOptions.Any()) + throw new InvalidOperationException($"Can't reconnect. Establish initial connection first."); + + var dc = dcOptions.First(d => d.id == dcId); + + _transport = new TcpTransport(dc.ip_address, dc.port, _handler); + _session.ServerAddress = dc.ip_address; + _session.Port = dc.port; + + await ConnectAsync(true); + } + + public bool IsUserAuthorized() + { + return _session.TLUser != null; + } + + public async Task IsPhoneRegisteredAsync(string phoneNumber) + { + if (String.IsNullOrWhiteSpace(phoneNumber)) + throw new ArgumentNullException(nameof(phoneNumber)); + + if (_sender == null) + throw new InvalidOperationException("Not connected!"); + + var authCheckPhoneRequest = new TLRequestCheckPhone() { phone_number = phoneNumber }; + var completed = false; + while(!completed) + { + try + { + await _sender.Send(authCheckPhoneRequest); + await _sender.Receive(authCheckPhoneRequest); + completed = true; + } + catch(PhoneMigrationException e) + { + await ReconnectToDcAsync(e.DC); + } + } + return authCheckPhoneRequest.Response.phone_registered; + } + + public async Task SendCodeRequestAsync(string phoneNumber) + { + if (String.IsNullOrWhiteSpace(phoneNumber)) + throw new ArgumentNullException(nameof(phoneNumber)); + + var completed = false; + + TLRequestSendCode request = null; + + while (!completed) + { + request = new TLRequestSendCode() { phone_number = phoneNumber, api_id = _apiId, api_hash = _apiHash }; + try + { + await _sender.Send(request); + await _sender.Receive(request); + + completed = true; + } + catch (PhoneMigrationException ex) + { + await ReconnectToDcAsync(ex.DC); + } + } + + return request.Response.phone_code_hash; + } + + public async Task MakeAuthAsync(string phoneNumber, string phoneCodeHash, string code) + { + if (String.IsNullOrWhiteSpace(phoneNumber)) + throw new ArgumentNullException(nameof(phoneNumber)); + + if (String.IsNullOrWhiteSpace(phoneCodeHash)) + throw new ArgumentNullException(nameof(phoneCodeHash)); + + if (String.IsNullOrWhiteSpace(code)) + throw new ArgumentNullException(nameof(code)); + var request = new TLRequestSignIn() { phone_number = phoneNumber, phone_code_hash = phoneCodeHash, phone_code = code }; var completed = false; @@ -181,176 +181,280 @@ public async Task MakeAuthAsync(string phoneNumber, string phoneCodeHash { await ReconnectToDcAsync(e.DC); } - } - - OnUserAuthenticated(((TLUser)request.Response.user)); - - return ((TLUser)request.Response.user); - } - public async Task GetPasswordSetting() - { - var request = new TLRequestGetPassword(); - - await _sender.Send(request); - await _sender.Receive(request); - - return ((TLPassword)request.Response); - } - - public async Task MakeAuthWithPasswordAsync(TLPassword password, string password_str) - { - - byte[] password_bytes = Encoding.UTF8.GetBytes(password_str); - IEnumerable rv = password.current_salt.Concat(password_bytes).Concat(password.current_salt); - - SHA256Managed hashstring = new SHA256Managed(); - var password_hash = hashstring.ComputeHash(rv.ToArray()); - - var request = new TLRequestCheckPassword() { password_hash = password_hash }; - await _sender.Send(request); - await _sender.Receive(request); - - OnUserAuthenticated(((TLUser)request.Response.user)); - - return ((TLUser)request.Response.user); - } - - public async Task SignUpAsync(string phoneNumber, string phoneCodeHash, string code, string firstName, string lastName) - { - var request = new TLRequestSignUp() { phone_number = phoneNumber, phone_code = code, phone_code_hash = phoneCodeHash, first_name = firstName, last_name = lastName }; - await _sender.Send(request); - await _sender.Receive(request); - - OnUserAuthenticated(((TLUser)request.Response.user)); - - return ((TLUser)request.Response.user); - } - public async Task SendRequestAsync(TLMethod methodToExecute) - { - await _sender.Send(methodToExecute); - await _sender.Receive(methodToExecute); - - var result = methodToExecute.GetType().GetProperty("Response").GetValue(methodToExecute); - - return (T)result; - } - - public async Task GetContactsAsync() - { - if (!IsUserAuthorized()) - throw new InvalidOperationException("Authorize user first!"); - - var req = new TLRequestGetContacts() { hash = "" }; - - return await SendRequestAsync(req); - } - - public async Task SendMessageAsync(TLAbsInputPeer peer, string message) - { - if (!IsUserAuthorized()) - throw new InvalidOperationException("Authorize user first!"); - - return await SendRequestAsync( - new TLRequestSendMessage() - { - peer = peer, - message = message, - random_id = Helpers.GenerateRandomLong() - }); - } - - public async Task SendTypingAsync(TLAbsInputPeer peer) - { - var req = new TLRequestSetTyping() - { - action = new TLSendMessageTypingAction(), - peer = peer - }; - return await SendRequestAsync(req); - } - - public async Task GetUserDialogsAsync() - { - var peer = new TLInputPeerSelf(); - return await SendRequestAsync( - new TLRequestGetDialogs() { offset_date = 0, offset_peer = peer, limit = 100 }); - } - - public async Task SendUploadedPhoto(TLAbsInputPeer peer, TLAbsInputFile file, string caption) - { - return await SendRequestAsync(new TLRequestSendMedia() - { - random_id = Helpers.GenerateRandomLong(), - background = false, - clear_draft = false, - media = new TLInputMediaUploadedPhoto() { file = file, caption = caption }, - peer = peer - }); - } - - public async Task SendUploadedDocument( - TLAbsInputPeer peer, TLAbsInputFile file, string caption, string mimeType, TLVector attributes) - { - return await SendRequestAsync(new TLRequestSendMedia() - { - random_id = Helpers.GenerateRandomLong(), - background = false, - clear_draft = false, - media = new TLInputMediaUploadedDocument() - { - file = file, - caption = caption, - mime_type = mimeType, - attributes = attributes - }, - peer = peer - }); - } - - public async Task GetFile(TLAbsInputFileLocation location, int filePartSize, int offset = 0) - { - TLFile result = null; - try - { - result = await SendRequestAsync(new TLRequestGetFile() - { - location = location, - limit = filePartSize, - offset = offset - }); - } - catch (FileMigrationException ex) - { - var exportedAuth = await SendRequestAsync(new TLRequestExportAuthorization() { dc_id = ex.DC }); - - var authKey = _session.AuthKey; - var timeOffset = _session.TimeOffset; - var serverAddress = _session.ServerAddress; - var serverPort = _session.Port; - - await ReconnectToDcAsync(ex.DC); - var auth = await SendRequestAsync(new TLRequestImportAuthorization - { - bytes = exportedAuth.bytes, - id = exportedAuth.id - }); - result = await GetFile(location, filePartSize, offset); - - _session.AuthKey = authKey; - _session.TimeOffset = timeOffset; - _transport = new TcpTransport(serverAddress, serverPort); - _session.ServerAddress = serverAddress; - _session.Port = serverPort; - await ConnectAsync(); - - } - - return result; - } - - public async Task SendPingAsync() - { - await _sender.SendPingAsync(); + } + + OnUserAuthenticated(((TLUser)request.Response.user)); + + return ((TLUser)request.Response.user); + } + public async Task GetPasswordSetting() + { + var request = new TLRequestGetPassword(); + + await _sender.Send(request); + await _sender.Receive(request); + + return ((TLPassword)request.Response); + } + + public async Task MakeAuthWithPasswordAsync(TLPassword password, string password_str) + { + + byte[] password_bytes = Encoding.UTF8.GetBytes(password_str); + IEnumerable rv = password.current_salt.Concat(password_bytes).Concat(password.current_salt); + + SHA256Managed hashstring = new SHA256Managed(); + var password_hash = hashstring.ComputeHash(rv.ToArray()); + + var request = new TLRequestCheckPassword() { password_hash = password_hash }; + await _sender.Send(request); + await _sender.Receive(request); + + OnUserAuthenticated(((TLUser)request.Response.user)); + + return ((TLUser)request.Response.user); + } + + public async Task SignUpAsync(string phoneNumber, string phoneCodeHash, string code, string firstName, string lastName) + { + var request = new TLRequestSignUp() { phone_number = phoneNumber, phone_code = code, phone_code_hash = phoneCodeHash, first_name = firstName, last_name = lastName }; + await _sender.Send(request); + await _sender.Receive(request); + + OnUserAuthenticated(((TLUser)request.Response.user)); + + return ((TLUser)request.Response.user); + } + public async Task SendRequestAsync(TLMethod methodToExecute) + { + await _sender.Send(methodToExecute); + await _sender.Receive(methodToExecute); + + var result = methodToExecute.GetType().GetProperty("Response").GetValue(methodToExecute); + + return (T)result; + } + + public async Task GetContactsAsync() + { + if (!IsUserAuthorized()) + throw new InvalidOperationException("Authorize user first!"); + + var req = new TLRequestGetContacts() { hash = "" }; + + return await SendRequestAsync(req); + } + + public async Task SendMessageAsync(TLAbsInputPeer peer, string message) + { + if (!IsUserAuthorized()) + throw new InvalidOperationException("Authorize user first!"); + + return await SendRequestAsync( + new TLRequestSendMessage() + { + peer = peer, + message = message, + random_id = Helpers.GenerateRandomLong() + }); + } + + public async Task SendTypingAsync(TLAbsInputPeer peer) + { + var req = new TLRequestSetTyping() + { + action = new TLSendMessageTypingAction(), + peer = peer + }; + return await SendRequestAsync(req); + } + + public async Task GetUserDialogsAsync() + { + var peer = new TLInputPeerSelf(); + return await SendRequestAsync( + new TLRequestGetDialogs() { offset_date = 0, offset_peer = peer, limit = 100 }); + } + + public async Task SendUploadedPhoto(TLAbsInputPeer peer, TLAbsInputFile file, string caption) + { + return await SendRequestAsync(new TLRequestSendMedia() + { + random_id = Helpers.GenerateRandomLong(), + background = false, + clear_draft = false, + media = new TLInputMediaUploadedPhoto() { file = file, caption = caption }, + peer = peer + }); + } + + public async Task SendUploadedDocument( + TLAbsInputPeer peer, TLAbsInputFile file, string caption, string mimeType, TLVector attributes) + { + return await SendRequestAsync(new TLRequestSendMedia() + { + random_id = Helpers.GenerateRandomLong(), + background = false, + clear_draft = false, + media = new TLInputMediaUploadedDocument() + { + file = file, + caption = caption, + mime_type = mimeType, + attributes = attributes + }, + peer = peer + }); + } + + public async Task GetFile(TLAbsInputFileLocation location, int filePartSize, int offset = 0) + { + TLFile result = null; + try + { + result = await SendRequestAsync(new TLRequestGetFile() + { + location = location, + limit = filePartSize, + offset = offset + }); + } + catch (FileMigrationException ex) + { + var exportedAuth = await SendRequestAsync(new TLRequestExportAuthorization() { dc_id = ex.DC }); + + var authKey = _session.AuthKey; + var timeOffset = _session.TimeOffset; + var serverAddress = _session.ServerAddress; + var serverPort = _session.Port; + + await ReconnectToDcAsync(ex.DC); + var auth = await SendRequestAsync(new TLRequestImportAuthorization + { + bytes = exportedAuth.bytes, + id = exportedAuth.id + }); + result = await GetFile(location, filePartSize, offset); + + _session.AuthKey = authKey; + _session.TimeOffset = timeOffset; + _transport = new TcpTransport(serverAddress, serverPort); + _session.ServerAddress = serverAddress; + _session.Port = serverPort; + await ConnectAsync(); + + } + + return result; + } + + /// + /// Gets user avatar that is used now. + /// + /// Provide a number of maximum possible profile images user may have + /// + public async Task GetUserProfileImage(TLUser inputUser, int limit) + { + byte[] byteImage = null; + try + { + TLInputUser inputUserTL = new TLInputUser(); + inputUserTL.user_id = inputUser.id; + + TeleSharp.TL.Photos.TLPhotos photo = new TeleSharp.TL.Photos.TLPhotos(); + photo = await GetUserPhotos(inputUserTL, 0, 0, limit); + TeleSharp.TL.TLFileLocation fileLocation = new TLFileLocation(); + List photoList = photo.photos.lists; + TLPhoto photo1 = (TLPhoto)photoList[0]; + TLVector photoSizeList = photo1.sizes; + List photoSizeList2 = photoSizeList.lists; + TLPhotoSize size1 = (TLPhotoSize)photoSizeList2[0]; + TLFileLocation location1 = (TLFileLocation)size1.location; + + TLInputFileLocation inputLocation = new TLInputFileLocation() + { + volume_id = location1.volume_id, + local_id = location1.local_id, + secret = location1.secret + }; + + TeleSharp.TL.Upload.TLFile recievedFile = await GetFile(inputLocation, Convert.ToInt32(inputLocation.volume_id)); + byteImage = recievedFile.bytes; + } + catch (FileMigrationException ex) + { + var exportedAuth = await SendRequestAsync(new TLRequestExportAuthorization() { dc_id = ex.DC }); + + var authKey = _session.AuthKey; + var timeOffset = _session.TimeOffset; + var serverAddress = _session.ServerAddress; + var serverPort = _session.Port; + + await ReconnectToDcAsync(ex.DC); + var auth = await SendRequestAsync(new TLRequestImportAuthorization + { + bytes = exportedAuth.bytes, + id = exportedAuth.id + }); + + byteImage = await GetUserProfileImage(inputUser, limit); + + _session.AuthKey = authKey; + _session.TimeOffset = timeOffset; + _transport = new TcpTransport(serverAddress, serverPort); + _session.ServerAddress = serverAddress; + _session.Port = serverPort; + await ConnectAsync(); + } + + return byteImage; + } + + public async Task GetUserPhotos(TeleSharp.TL.TLInputUser user_id, int offset, long max_id, int limit) + { + TeleSharp.TL.Photos.TLPhotos resultPhoto = null; + try + { + resultPhoto = await SendRequestAsync(new TeleSharp.TL.Photos.TLRequestGetUserPhotos() + { + user_id = user_id, + offset = offset, + max_id = max_id, + limit = limit + }); + } + catch (FileMigrationException ex) + { + var exportedAuth = await SendRequestAsync(new TLRequestExportAuthorization() { dc_id = ex.DC }); + + var authKey = _session.AuthKey; + var timeOffset = _session.TimeOffset; + var serverAddress = _session.ServerAddress; + var serverPort = _session.Port; + + await ReconnectToDcAsync(ex.DC); + var auth = await SendRequestAsync(new TLRequestImportAuthorization + { + bytes = exportedAuth.bytes, + id = exportedAuth.id + }); + + resultPhoto = await GetUserPhotos(user_id, offset, max_id, limit); + + _session.AuthKey = authKey; + _session.TimeOffset = timeOffset; + _transport = new TcpTransport(serverAddress, serverPort); + _session.ServerAddress = serverAddress; + _session.Port = serverPort; + await ConnectAsync(); + } + + return resultPhoto; + } + + public async Task SendPingAsync() + { + await _sender.SendPingAsync(); } public async Task GetHistoryAsync(TLAbsInputPeer peer, int offset, int max_id, int limit) @@ -366,31 +470,31 @@ public async Task GetHistoryAsync(TLAbsInputPeer peer, int offset limit = limit }; return await SendRequestAsync(req); - } - - /// - /// Serch user or chat. API: contacts.search#11f812d8 q:string limit:int = contacts.Found; - /// - /// User or chat name - /// Max result count - /// - public async Task SearchUserAsync(string q, int limit = 10) - { - var r = new TeleSharp.TL.Contacts.TLRequestSearch - { - q = q, - limit = limit - }; - - return await SendRequestAsync(r); - } - - private void OnUserAuthenticated(TLUser TLUser) - { - _session.TLUser = TLUser; - _session.SessionExpires = int.MaxValue; - - _session.Save(); + } + + /// + /// Serch user or chat. API: contacts.search#11f812d8 q:string limit:int = contacts.Found; + /// + /// User or chat name + /// Max result count + /// + public async Task SearchUserAsync(string q, int limit = 10) + { + var r = new TeleSharp.TL.Contacts.TLRequestSearch + { + q = q, + limit = limit + }; + + return await SendRequestAsync(r); + } + + private void OnUserAuthenticated(TLUser TLUser) + { + _session.TLUser = TLUser; + _session.SessionExpires = int.MaxValue; + + _session.Save(); } public bool IsConnected @@ -403,32 +507,32 @@ public bool IsConnected } } - public void Dispose() - { - if (_transport != null) - { - _transport.Dispose(); - _transport = null; - } - } - } - - public class MissingApiConfigurationException : Exception - { - public const string InfoUrl = "https://github.com/sochix/TLSharp#quick-configuration"; - - internal MissingApiConfigurationException(string invalidParamName) : - base($"Your {invalidParamName} setting is missing. Adjust the configuration first, see {InfoUrl}") - { - } - } - - public class InvalidPhoneCodeException : Exception - { - internal InvalidPhoneCodeException(string msg) : base(msg) { } - } - public class CloudPasswordNeededException : Exception - { - internal CloudPasswordNeededException(string msg) : base(msg) { } - } -} + public void Dispose() + { + if (_transport != null) + { + _transport.Dispose(); + _transport = null; + } + } + } + + public class MissingApiConfigurationException : Exception + { + public const string InfoUrl = "https://github.com/sochix/TLSharp#quick-configuration"; + + internal MissingApiConfigurationException(string invalidParamName) : + base($"Your {invalidParamName} setting is missing. Adjust the configuration first, see {InfoUrl}") + { + } + } + + public class InvalidPhoneCodeException : Exception + { + internal InvalidPhoneCodeException(string msg) : base(msg) { } + } + public class CloudPasswordNeededException : Exception + { + internal CloudPasswordNeededException(string msg) : base(msg) { } + } +}