Merge branch 'master' of https://github.com/sochix/TLSharp into netstandard

This commit is contained in:
LORDofDOOM 2018-06-17 23:14:18 +02:00
commit b343c51723
6 changed files with 96 additions and 96 deletions

View file

@ -1,12 +1,13 @@
TLSharp 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) [![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) [![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 _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. 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: :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) - [First requests](#first-requests)
- [Working with files](#working-with-files) - [Working with files](#working-with-files)
- [Available Methods](#available-methods) - [Available Methods](#available-methods)
- [Contributing](#contributing) - [Contributors](#contributors)
- [FAQ](#faq) - [FAQ](#faq)
- [Donations](#donations) - [Donations](#donations)
- [Support](#support)
- [License](#license) - [License](#license)
# How do I add this to my project? # 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(); var result = await client.GetContactsAsync();
//find recipient in contacts //find recipient in contacts
var user = result.Users.lists var user = result.Users
.Where(x => x.GetType() == typeof (TLUser)) .Where(x => x.GetType() == typeof (TLUser))
.Cast<TLUser>() .Cast<TLUser>()
.FirstOrDefault(x => x.phone == "<recipient_phone>"); .FirstOrDefault(x => x.Phone == "<recipient_phone>");
//send message //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) 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: To send message to channel you could use the following code:
```csharp ```csharp
//get user dialogs //get user dialogs
var dialogs = await client.GetUserDialogsAsync(); var dialogs = (TLDialogsSlice) await client.GetUserDialogsAsync();
//find channel by title //find channel by title
var chat = dialogs.chats.lists var chat = dialogs.Chats
.Where(c => c.GetType() == typeof(TLChannel)) .Where(c => c.GetType() == typeof(TLChannel))
.Cast<TLChannel>() .Cast<TLChannel>()
.FirstOrDefault(c => c.title == "<channel_title>"); .FirstOrDefault(c => c.Title == "<channel_title>");
//send message //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) Full code you can see at [SendMessageToChannel test](https://github.com/sochix/TLSharp/blob/master/TLSharp.Tests/TLSharpTests.cs#L107)
## Working with files ## 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 TLSharp provides two wrappers for sending photo and document
```csharp ```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( await client.SendUploadedDocument(
new TLInputPeerUser() { user_id = user.id }, new TLInputPeerUser() { UserId = user.Id },
fileResult, fileResult,
"some zips", //caption "some zips", //caption
"application/zip", //mime-type "application/zip", //mime-type
@ -132,11 +134,11 @@ To download file you should call **GetFile** method
await client.GetFile( await client.GetFile(
new TLInputDocumentFileLocation() new TLInputDocumentFileLocation()
{ {
access_hash = document.access_hash, AccessHash = document.AccessHash,
id = document.id, Id = document.Id,
version = document.version 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) 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 //Create request
var req = new TLRequestSetTyping() var req = new TLRequestSetTyping()
{ {
action = new TLSendMessageTypingAction(), Action = new TLSendMessageTypingAction(),
peer = peer Peer = new TLInputPeerUser() { UserId = user.Id }
}; };
//run request, and deserialize response to Boolean //run request, and deserialize response to Boolean
return await SendRequestAsync<Boolean>(req); return await client.SendRequestAsync<Boolean>(req);
``` ```
**Where you can find a list of requests and its params?** **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? #### 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 #### Where else to ask for help?
Ask your question at gitter or create an issue in project bug tracker. 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**: **Attach following information**:
@ -231,6 +233,11 @@ Thanks for donations! It's highly appreciated.
List of donators: List of donators:
* [mtbitcoin](https://github.com/mtbitcoin) * [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 # Contributors
* [Afshin Arani](http://aarani.ir) - TLGenerator, and a lot of other usefull things * [Afshin Arani](http://aarani.ir) - TLGenerator, and a lot of other usefull things
* [Knocte](https://github.com/knocte) * [Knocte](https://github.com/knocte)

View file

@ -18,10 +18,10 @@ namespace TLSharp.Core.Network
{ {
//private ulong sessionId = GenerateRandomUlong(); //private ulong sessionId = GenerateRandomUlong();
private TcpTransport _transport; private readonly TcpTransport _transport;
private Session _session; private readonly Session _session;
public List<ulong> needConfirmation = new List<ulong>(); public readonly List<ulong> needConfirmation = new List<ulong>();
public MtProtoSender(TcpTransport transport, Session session) public MtProtoSender(TcpTransport transport, Session session)
{ {
@ -29,11 +29,6 @@ namespace TLSharp.Core.Network
_session = session; _session = session;
} }
public void ChangeTransport(TcpTransport transport)
{
_transport = transport;
}
private int GenerateSequence(bool confirmed) private int GenerateSequence(bool confirmed)
{ {
return confirmed ? _session.Sequence++ * 2 + 1 : _session.Sequence * 2; return confirmed ? _session.Sequence++ * 2 + 1 : _session.Sequence * 2;

View file

@ -84,21 +84,21 @@ namespace TLSharp.Core.Network
} }
return new TcpMessage(seq, body); return new TcpMessage(seq, body);
} }
public bool IsConnected public bool IsConnected
{ {
get get
{ {
return this._tcpClient.Connected; return this._tcpClient.Connected;
} }
} }
public void Dispose() public void Dispose()
{ {
if (_tcpClient.Connected) if (_tcpClient.Connected)
_tcpClient.Close(); _tcpClient.Close();
} }
} }
} }

View file

@ -41,7 +41,6 @@ namespace TLSharp.Core
if (store == null) if (store == null)
store = new FileSessionStore(); store = new FileSessionStore();
TLContext.Init();
_apiHash = apiHash; _apiHash = apiHash;
_apiId = apiId; _apiId = apiId;
_handler = handler; _handler = handler;
@ -50,7 +49,7 @@ namespace TLSharp.Core
_transport = new TcpTransport(_session.ServerAddress, _session.Port, _handler); _transport = new TcpTransport(_session.ServerAddress, _session.Port, _handler);
} }
public async Task<bool> ConnectAsync(bool reconnect = false) public async Task ConnectAsync(bool reconnect = false)
{ {
if (_session.AuthKey == null || reconnect) if (_session.AuthKey == null || reconnect)
{ {
@ -77,21 +76,19 @@ namespace TLSharp.Core
await _sender.Receive(invokewithLayer); await _sender.Receive(invokewithLayer);
dcOptions = ((TLConfig)invokewithLayer.Response).DcOptions.ToList(); dcOptions = ((TLConfig)invokewithLayer.Response).DcOptions.ToList();
return true;
} }
private async Task ReconnectToDcAsync(int dcId) private async Task ReconnectToDcAsync(int dcId)
{ {
if (dcOptions == null || !dcOptions.Any()) if (dcOptions == null || !dcOptions.Any())
throw new InvalidOperationException($"Can't reconnect. Establish initial connection first."); throw new InvalidOperationException($"Can't reconnect. Establish initial connection first.");
TLExportedAuthorization exported = null; TLExportedAuthorization exported = null;
if (_session.TLUser != null) if (_session.TLUser != null)
{ {
TLRequestExportAuthorization exportAuthorization = new TLRequestExportAuthorization() { DcId = dcId }; TLRequestExportAuthorization exportAuthorization = new TLRequestExportAuthorization() { DcId = dcId };
exported = await SendRequestAsync<TLExportedAuthorization>(exportAuthorization); exported = await SendRequestAsync<TLExportedAuthorization>(exportAuthorization);
} }
var dc = dcOptions.First(d => d.Id == dcId); var dc = dcOptions.First(d => d.Id == dcId);
@ -99,18 +96,21 @@ namespace TLSharp.Core
_session.ServerAddress = dc.IpAddress; _session.ServerAddress = dc.IpAddress;
_session.Port = dc.Port; _session.Port = dc.Port;
await ConnectAsync(true); await ConnectAsync(true);
if (_session.TLUser != null) if (_session.TLUser != null)
{ {
TLRequestImportAuthorization importAuthorization = new TLRequestImportAuthorization() { Id = exported.Id, Bytes = exported.Bytes }; TLRequestImportAuthorization importAuthorization = new TLRequestImportAuthorization() { Id = exported.Id, Bytes = exported.Bytes };
var imported = await SendRequestAsync<TLAuthorization>(importAuthorization); var imported = await SendRequestAsync<TLAuthorization>(importAuthorization);
OnUserAuthenticated(((TLUser)imported.User)); 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; var completed = false;
while(!completed) while(!completed)
{ {
@ -126,7 +126,7 @@ namespace TLSharp.Core
// prepare the request for another try // prepare the request for another try
request.ConfirmReceived = false; request.ConfirmReceived = false;
} }
} }
} }
public bool IsUserAuthorized() public bool IsUserAuthorized()
@ -139,9 +139,6 @@ namespace TLSharp.Core
if (String.IsNullOrWhiteSpace(phoneNumber)) if (String.IsNullOrWhiteSpace(phoneNumber))
throw new ArgumentNullException(nameof(phoneNumber)); throw new ArgumentNullException(nameof(phoneNumber));
if (_sender == null)
throw new InvalidOperationException("Not connected!");
var authCheckPhoneRequest = new TLRequestCheckPhone() { PhoneNumber = phoneNumber }; var authCheckPhoneRequest = new TLRequestCheckPhone() { PhoneNumber = phoneNumber };
await RequestWithDcMigration(authCheckPhoneRequest); await RequestWithDcMigration(authCheckPhoneRequest);
@ -172,8 +169,8 @@ namespace TLSharp.Core
if (String.IsNullOrWhiteSpace(code)) if (String.IsNullOrWhiteSpace(code))
throw new ArgumentNullException(nameof(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); await RequestWithDcMigration(request);
OnUserAuthenticated(((TLUser)request.Response.User)); OnUserAuthenticated(((TLUser)request.Response.User));
@ -314,21 +311,21 @@ namespace TLSharp.Core
public async Task SendPingAsync() public async Task SendPingAsync()
{ {
await _sender.SendPingAsync(); await _sender.SendPingAsync();
} }
public async Task<TLAbsMessages> GetHistoryAsync(TLAbsInputPeer peer, int offset, int max_id, int limit) public async Task<TLAbsMessages> GetHistoryAsync(TLAbsInputPeer peer, int offset, int max_id, int limit)
{ {
if (!IsUserAuthorized()) if (!IsUserAuthorized())
throw new InvalidOperationException("Authorize user first!"); throw new InvalidOperationException("Authorize user first!");
var req = new TLRequestGetHistory() var req = new TLRequestGetHistory()
{ {
Peer = peer, Peer = peer,
AddOffset = offset, AddOffset = offset,
MaxId = max_id, MaxId = max_id,
Limit = limit Limit = limit
}; };
return await SendRequestAsync<TLAbsMessages>(req); return await SendRequestAsync<TLAbsMessages>(req);
} }
/// <summary> /// <summary>
@ -354,18 +351,18 @@ namespace TLSharp.Core
_session.SessionExpires = int.MaxValue; _session.SessionExpires = int.MaxValue;
_session.Save(); _session.Save();
} }
public bool IsConnected public bool IsConnected
{ {
get get
{ {
if (_transport == null) if (_transport == null)
return false; return false;
return _transport.IsConnected; return _transport.IsConnected;
} }
} }
public void Dispose() public void Dispose()
{ {
if (_transport != null) if (_transport != null)

View file

@ -12,7 +12,7 @@ namespace TeleSharp.TL
{ {
private static Dictionary<int, Type> Types; private static Dictionary<int, Type> Types;
public static void Init() static TLContext()
{ {
Types = new Dictionary<int, Type>(); Types = new Dictionary<int, Type>();
Types = (from t in Assembly.GetExecutingAssembly().GetTypes() 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); select t).ToDictionary(x => ((TLObjectAttribute)x.GetCustomAttribute(typeof(TLObjectAttribute))).Constructor, x => x);
Types[481674261] = typeof(TLVector<>); Types[481674261] = typeof(TLVector<>);
} }
public static Type getType(int Constructor) public static Type getType(int Constructor)
{ {
return Types[Constructor]; return Types[Constructor];

View file

@ -31,7 +31,7 @@ namespace TeleSharp.TL
Serialize(bw); Serialize(bw);
bw.Close(); bw.Close();
m.Close(); m.Close();
return m.GetBuffer(); return m.ToArray();
} }
} }
public void Serialize(BinaryWriter writer) public void Serialize(BinaryWriter writer)