diff --git a/README.md b/README.md index cbee7f0..9d89a90 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ TLSharp ------------------------------- -[![Join the chat at https://gitter.im/TLSharp/Lobby](https://badges.gitter.im/TLSharp/Lobby.svg)](https://gitter.im/TLSharp/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build status](https://ci.appveyor.com/api/projects/status/95rl618ch5c4h2fa?svg=true)](https://ci.appveyor.com/project/sochix/tlsharp) [![NuGet version](https://badge.fury.io/nu/TLSharp.svg)](https://badge.fury.io/nu/TLSharp) _Unofficial_ Telegram (http://telegram.org) client library implemented in C#. Latest TL scheme supported, thanks to Afshin Arani +🚩 Check out [TeleJS](https://github.com/RD17/TeleJS) - a pure JavaScript implementation of Telegram MTP protocol + It's a perfect fit for any developer who would like to send data directly to Telegram users or write own custom Telegram client. :star2: If you :heart: library, please star it! :star2: @@ -20,9 +21,10 @@ It's a perfect fit for any developer who would like to send data directly to Tel - [First requests](#first-requests) - [Working with files](#working-with-files) - [Available Methods](#available-methods) -- [Contributing](#contributing) +- [Contributors](#contributors) - [FAQ](#faq) - [Donations](#donations) +- [Support](#support) - [License](#license) # How do I add this to my project? @@ -81,13 +83,13 @@ You can call any method on authenticated user. For example, let's send message t var result = await client.GetContactsAsync(); //find recipient in contacts - var user = result.Users.lists + var user = result.Users .Where(x => x.GetType() == typeof (TLUser)) .Cast() - .FirstOrDefault(x => x.phone == ""); + .FirstOrDefault(x => x.Phone == ""); //send message - await client.SendMessageAsync(new TLInputPeerUser() {user_id = user.id}, "OUR_MESSAGE"); + await client.SendMessageAsync(new TLInputPeerUser() {UserId = user.Id}, "OUR_MESSAGE"); ``` Full code you can see at [SendMessage test](https://github.com/sochix/TLSharp/blob/master/TLSharp.Tests/TLSharpTests.cs#L87) @@ -95,16 +97,16 @@ Full code you can see at [SendMessage test](https://github.com/sochix/TLSharp/bl To send message to channel you could use the following code: ```csharp //get user dialogs - var dialogs = await client.GetUserDialogsAsync(); + var dialogs = (TLDialogsSlice) await client.GetUserDialogsAsync(); //find channel by title - var chat = dialogs.chats.lists + var chat = dialogs.Chats .Where(c => c.GetType() == typeof(TLChannel)) .Cast() - .FirstOrDefault(c => c.title == ""); + .FirstOrDefault(c => c.Title == ""); //send message - await client.SendMessageAsync(new TLInputPeerChannel() { channel_id = chat.id, access_hash = chat.access_hash.Value }, "OUR_MESSAGE"); + await client.SendMessageAsync(new TLInputPeerChannel() { ChannelId = chat.Id, AccessHash = chat.AccessHash.Value }, "OUR_MESSAGE"); ``` Full code you can see at [SendMessageToChannel test](https://github.com/sochix/TLSharp/blob/master/TLSharp.Tests/TLSharpTests.cs#L107) ## Working with files @@ -117,9 +119,9 @@ Telegram separate files to two categories -> big file and small file. File is Bi TLSharp provides two wrappers for sending photo and document ```csharp - await client.SendUploadedPhoto(new TLInputPeerUser() { user_id = user.id }, fileResult, "kitty"); + await client.SendUploadedPhoto(new TLInputPeerUser() { UserId = user.Id }, fileResult, "kitty"); await client.SendUploadedDocument( - new TLInputPeerUser() { user_id = user.id }, + new TLInputPeerUser() { UserId = user.Id }, fileResult, "some zips", //caption "application/zip", //mime-type @@ -132,11 +134,11 @@ To download file you should call **GetFile** method await client.GetFile( new TLInputDocumentFileLocation() { - access_hash = document.access_hash, - id = document.id, - version = document.version + AccessHash = document.AccessHash, + Id = document.Id, + Version = document.Version }, - document.size); //size of fileChunk you want to retrieve + document.Size); //size of fileChunk you want to retrieve ``` Full code you can see at [DownloadFileFromContactTest](https://github.com/sochix/TLSharp/blob/master/TLSharp.Tests/TLSharpTests.cs#L167) @@ -169,12 +171,12 @@ Don't panic. You can call any method with help of `SendRequestAsync` function. F //Create request var req = new TLRequestSetTyping() { - action = new TLSendMessageTypingAction(), - peer = peer + Action = new TLSendMessageTypingAction(), + Peer = new TLInputPeerUser() { UserId = user.Id } }; //run request, and deserialize response to Boolean - return await SendRequestAsync(req); + return await client.SendRequestAsync(req); ``` **Where you can find a list of requests and its params?** @@ -211,10 +213,10 @@ It's likely [Telegram restrictions](https://core.telegram.org/api/errors#420-flo #### Why does TLSharp lacks feature XXXX? -Now TLSharp is basic realization of Telegram protocol, you can be a contributor or a sponsor to speed-up developemnt of any feature. +TLSharp only covers basic functionality of the Telegram protocol, you can be a contributor or a sponsor to speed-up developemnt of any more new features. -#### Nothing helps -Ask your question at gitter or create an issue in project bug tracker. +#### Where else to ask for help? +If you think you have found a bug in TLSharp, create a github issue. But if you just have questions about how to use TLSharp, use our gitter channel (https://gitter.im/TLSharp/Lobby) or our Telegram channel (https://t.me/joinchat/AgtDiBEqG1i-qPqttNFLbA). **Attach following information**: @@ -231,6 +233,11 @@ Thanks for donations! It's highly appreciated. List of donators: * [mtbitcoin](https://github.com/mtbitcoin) +# Support +If you have troubles while using TLSharp, I can help you for an additional fee. + +My pricing is **219$/hour**. I accept PayPal. To request a paid support write me at Telegram @sochix, start your message with phrase [PAID SUPPORT]. + # Contributors * [Afshin Arani](http://aarani.ir) - TLGenerator, and a lot of other usefull things * [Knocte](https://github.com/knocte) diff --git a/TLSharp.Core/Network/MtProtoSender.cs b/TLSharp.Core/Network/MtProtoSender.cs index 795e878..4bc8e84 100644 --- a/TLSharp.Core/Network/MtProtoSender.cs +++ b/TLSharp.Core/Network/MtProtoSender.cs @@ -18,10 +18,10 @@ namespace TLSharp.Core.Network { //private ulong sessionId = GenerateRandomUlong(); - private TcpTransport _transport; - private Session _session; + private readonly TcpTransport _transport; + private readonly Session _session; - public List needConfirmation = new List(); + public readonly List needConfirmation = new List(); public MtProtoSender(TcpTransport transport, Session session) { @@ -29,11 +29,6 @@ namespace TLSharp.Core.Network _session = session; } - public void ChangeTransport(TcpTransport transport) - { - _transport = transport; - } - private int GenerateSequence(bool confirmed) { return confirmed ? _session.Sequence++ * 2 + 1 : _session.Sequence * 2; diff --git a/TLSharp.Core/Network/TcpTransport.cs b/TLSharp.Core/Network/TcpTransport.cs index 31bd6b4..e0f6e1f 100644 --- a/TLSharp.Core/Network/TcpTransport.cs +++ b/TLSharp.Core/Network/TcpTransport.cs @@ -84,21 +84,21 @@ namespace TLSharp.Core.Network } return new TcpMessage(seq, body); - } - - public bool IsConnected - { - get - { - return this._tcpClient.Connected; - } - } - - + } + + public bool IsConnected + { + get + { + return this._tcpClient.Connected; + } + } + + public void Dispose() { if (_tcpClient.Connected) _tcpClient.Close(); - } + } } } diff --git a/TLSharp.Core/TelegramClient.cs b/TLSharp.Core/TelegramClient.cs index 0692486..3406ee9 100644 --- a/TLSharp.Core/TelegramClient.cs +++ b/TLSharp.Core/TelegramClient.cs @@ -41,7 +41,6 @@ namespace TLSharp.Core if (store == null) store = new FileSessionStore(); - TLContext.Init(); _apiHash = apiHash; _apiId = apiId; _handler = handler; @@ -50,7 +49,7 @@ namespace TLSharp.Core _transport = new TcpTransport(_session.ServerAddress, _session.Port, _handler); } - public async Task ConnectAsync(bool reconnect = false) + public async Task ConnectAsync(bool reconnect = false) { if (_session.AuthKey == null || reconnect) { @@ -77,21 +76,19 @@ namespace TLSharp.Core await _sender.Receive(invokewithLayer); dcOptions = ((TLConfig)invokewithLayer.Response).DcOptions.ToList(); - - return true; } private async Task ReconnectToDcAsync(int dcId) { if (dcOptions == null || !dcOptions.Any()) throw new InvalidOperationException($"Can't reconnect. Establish initial connection first."); - - TLExportedAuthorization exported = null; - if (_session.TLUser != null) - { - TLRequestExportAuthorization exportAuthorization = new TLRequestExportAuthorization() { DcId = dcId }; - exported = await SendRequestAsync(exportAuthorization); - } + + TLExportedAuthorization exported = null; + if (_session.TLUser != null) + { + TLRequestExportAuthorization exportAuthorization = new TLRequestExportAuthorization() { DcId = dcId }; + exported = await SendRequestAsync(exportAuthorization); + } var dc = dcOptions.First(d => d.Id == dcId); @@ -99,18 +96,21 @@ namespace TLSharp.Core _session.ServerAddress = dc.IpAddress; _session.Port = dc.Port; - await ConnectAsync(true); - - if (_session.TLUser != null) - { - TLRequestImportAuthorization importAuthorization = new TLRequestImportAuthorization() { Id = exported.Id, Bytes = exported.Bytes }; - var imported = await SendRequestAsync(importAuthorization); - OnUserAuthenticated(((TLUser)imported.User)); + await ConnectAsync(true); + + if (_session.TLUser != null) + { + TLRequestImportAuthorization importAuthorization = new TLRequestImportAuthorization() { Id = exported.Id, Bytes = exported.Bytes }; + var imported = await SendRequestAsync(importAuthorization); + OnUserAuthenticated(((TLUser)imported.User)); } } - private async Task RequestWithDcMigration(TLMethod request) - { + private async Task RequestWithDcMigration(TLMethod request) + { + if (_sender == null) + throw new InvalidOperationException("Not connected!"); + var completed = false; while(!completed) { @@ -126,7 +126,7 @@ namespace TLSharp.Core // prepare the request for another try request.ConfirmReceived = false; } - } + } } public bool IsUserAuthorized() @@ -139,9 +139,6 @@ namespace TLSharp.Core if (String.IsNullOrWhiteSpace(phoneNumber)) throw new ArgumentNullException(nameof(phoneNumber)); - if (_sender == null) - throw new InvalidOperationException("Not connected!"); - var authCheckPhoneRequest = new TLRequestCheckPhone() { PhoneNumber = phoneNumber }; await RequestWithDcMigration(authCheckPhoneRequest); @@ -172,8 +169,8 @@ namespace TLSharp.Core if (String.IsNullOrWhiteSpace(code)) throw new ArgumentNullException(nameof(code)); - var request = new TLRequestSignIn() { PhoneNumber = phoneNumber, PhoneCodeHash = phoneCodeHash, PhoneCode = code }; - + var request = new TLRequestSignIn() { PhoneNumber = phoneNumber, PhoneCodeHash = phoneCodeHash, PhoneCode = code }; + await RequestWithDcMigration(request); OnUserAuthenticated(((TLUser)request.Response.User)); @@ -314,21 +311,21 @@ namespace TLSharp.Core public async Task SendPingAsync() { await _sender.SendPingAsync(); - } - - public async Task GetHistoryAsync(TLAbsInputPeer peer, int offset, int max_id, int limit) - { - if (!IsUserAuthorized()) - throw new InvalidOperationException("Authorize user first!"); - - var req = new TLRequestGetHistory() - { - Peer = peer, - AddOffset = offset, - MaxId = max_id, - Limit = limit - }; - return await SendRequestAsync(req); + } + + public async Task GetHistoryAsync(TLAbsInputPeer peer, int offset, int max_id, int limit) + { + if (!IsUserAuthorized()) + throw new InvalidOperationException("Authorize user first!"); + + var req = new TLRequestGetHistory() + { + Peer = peer, + AddOffset = offset, + MaxId = max_id, + Limit = limit + }; + return await SendRequestAsync(req); } /// @@ -354,18 +351,18 @@ namespace TLSharp.Core _session.SessionExpires = int.MaxValue; _session.Save(); - } - - public bool IsConnected - { - get - { - if (_transport == null) - return false; - return _transport.IsConnected; - } - } - + } + + public bool IsConnected + { + get + { + if (_transport == null) + return false; + return _transport.IsConnected; + } + } + public void Dispose() { if (_transport != null) diff --git a/TeleSharp.TL/TLContext.cs b/TeleSharp.TL/TLContext.cs index f13d83e..8d2f9de 100644 --- a/TeleSharp.TL/TLContext.cs +++ b/TeleSharp.TL/TLContext.cs @@ -12,7 +12,7 @@ namespace TeleSharp.TL { private static Dictionary Types; - public static void Init() + static TLContext() { Types = new Dictionary(); Types = (from t in Assembly.GetExecutingAssembly().GetTypes() @@ -22,6 +22,7 @@ namespace TeleSharp.TL select t).ToDictionary(x => ((TLObjectAttribute)x.GetCustomAttribute(typeof(TLObjectAttribute))).Constructor, x => x); Types[481674261] = typeof(TLVector<>); } + public static Type getType(int Constructor) { return Types[Constructor]; diff --git a/TeleSharp.TL/TLObject.cs b/TeleSharp.TL/TLObject.cs index 3bc1476..f398ddf 100644 --- a/TeleSharp.TL/TLObject.cs +++ b/TeleSharp.TL/TLObject.cs @@ -31,7 +31,7 @@ namespace TeleSharp.TL Serialize(bw); bw.Close(); m.Close(); - return m.GetBuffer(); + return m.ToArray(); } } public void Serialize(BinaryWriter writer)