diff --git a/README.md b/README.md
index bc3ff4c..8cdba23 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,7 @@
[](https://gitter.im/TLSharp/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[](https://ci.appveyor.com/project/sochix/tlsharp)
+[](https://badge.fury.io/nu/TLSharp)
_Unofficial_ Telegram (http://telegram.org) client library implemented in C#. Latest TL scheme supported, thanks to Afshin Arani
@@ -29,9 +30,13 @@ It's a perfect fit for any developer who would like to send data directly to Tel
# How do I add this to my project?
-Library _almost_ ready for production usage. We need contributors to make 1.0.0 release.
+Install via NuGet
-To use TLSharp follow next steps:
+```
+ > Install-Package TLSharp
+```
+
+or build from source
1. Clone TLSharp from GitHub
1. Compile source with VS2015 or MonoDevelop
@@ -155,6 +160,7 @@ For your convenience TLSharp have wrappers for several Telegram API methods. You
1. SendUploadedDocument
1. GetFile
1. UploadFile
+1. SendPingAsync
**What if you can't find needed method at the list?**
@@ -187,9 +193,9 @@ Contributing is highly appreciated!
### Release 1.0.0
* [DONE] Add PHONE_MIGRATE handling
-* Add FILE_MIGRATE handling
+* [DONE] Add FILE_MIGRATE handling
* Add Updates handling
-* Add NuGet package
+* [DONE] Add NuGet package
* [DONE] Add wrappers for media uploading and downloading
* Store user session as JSON
@@ -198,16 +204,16 @@ Contributing is highly appreciated!
#### What API layer is supported?
The latest one - 57. Thanks to Afshin Arani for his TLGenerator
-#### I get an error MIGRATE_X?
+#### I get a xxxMigrationException or a MIGRATE_X error!
-TLSharp library should automatically handle this errors. If you see such errors, pls create a new issue.
+TLSharp library should automatically handle these errors. If you see such errors, please open a new Github issue with the details (include a stacktrace, etc.).
#### I get an exception: System.IO.EndOfStreamException: Unable to read beyond the end of the stream. All test methos except that AuthenticationWorks and TestConnection return same error. I did every thing including setting api id and hash, and setting server address.-
You should create a Telegram session. See [configuration guide](#sending-messages-set-up)
-#### Why I get FLOOD_WAIT error?
-[It's Telegram restrictions](https://core.telegram.org/api/errors#420-flood)
+#### Why do I get a FloodException/FLOOD_WAIT error?
+It's likely [Telegram restrictions](https://core.telegram.org/api/errors#420-flood), or a bug in TLSharp (if you feel it's the latter, please open a Github issue). You can know the time to wait by accessing the FloodException::TimeToWait property.
#### Why does TLSharp lacks feature XXXX?
diff --git a/TLSharp.Core/Network/MtProtoSender.cs b/TLSharp.Core/Network/MtProtoSender.cs
index a8fd1ed..352e527 100644
--- a/TLSharp.Core/Network/MtProtoSender.cs
+++ b/TLSharp.Core/Network/MtProtoSender.cs
@@ -148,6 +148,19 @@ namespace TLSharp.Core.Network
return null;
}
+ public async Task SendPingAsync()
+ {
+ var pingRequest = new PingRequest();
+ using (var memory = new MemoryStream())
+ using (var writer = new BinaryWriter(memory))
+ {
+ pingRequest.SerializeBody(writer);
+ await Send(memory.ToArray(), pingRequest);
+ }
+
+ await Receive(pingRequest);
+ }
+
private bool processMessage(ulong messageId, int sequence, BinaryReader messageReader, TeleSharp.TL.TLMethod request)
{
// TODO: check salt
@@ -169,7 +182,7 @@ namespace TLSharp.Core.Network
return HandlePing(messageId, sequence, messageReader);
case 0x347773c5: // pong
//logger.debug("MSG pong");
- return HandlePong(messageId, sequence, messageReader);
+ return HandlePong(messageId, sequence, messageReader, request);
case 0xae500895: // future_salts
//logger.debug("MSG future_salts");
return HandleFutureSalts(messageId, sequence, messageReader);
@@ -272,14 +285,29 @@ namespace TLSharp.Core.Network
{
var resultString = Regex.Match(errorMessage, @"\d+").Value;
var seconds = int.Parse(resultString);
- Debug.WriteLine($"Should wait {seconds} sec.");
- Thread.Sleep(1000 * seconds);
+ throw new FloodException(TimeSpan.FromSeconds(seconds));
}
else if (errorMessage.StartsWith("PHONE_MIGRATE_"))
{
var resultString = Regex.Match(errorMessage, @"\d+").Value;
var dcIdx = int.Parse(resultString);
- throw new MigrationNeededException(dcIdx);
+ throw new PhoneMigrationException(dcIdx);
+ }
+ else if (errorMessage.StartsWith("FILE_MIGRATE_"))
+ {
+ var resultString = Regex.Match(errorMessage, @"\d+").Value;
+ var dcIdx = int.Parse(resultString);
+ throw new FileMigrationException(dcIdx);
+ }
+ else if (errorMessage.StartsWith("USER_MIGRATE_"))
+ {
+ var resultString = Regex.Match(errorMessage, @"\d+").Value;
+ var dcIdx = int.Parse(resultString);
+ throw new UserMigrationException(dcIdx);
+ }
+ else if (errorMessage == "PHONE_CODE_INVALID")
+ {
+ throw new InvalidPhoneCodeException("The numeric code used to authenticate does not match the numeric code sent by SMS/Telegram");
}
else
{
@@ -440,8 +468,16 @@ namespace TLSharp.Core.Network
return true;
}
- private bool HandlePong(ulong messageId, int sequence, BinaryReader messageReader)
+ private bool HandlePong(ulong messageId, int sequence, BinaryReader messageReader, TeleSharp.TL.TLMethod request)
{
+ uint code = messageReader.ReadUInt32();
+ ulong msgId = messageReader.ReadUInt64();
+
+ if (msgId == (ulong)request.MessageId)
+ {
+ request.ConfirmReceived = true;
+ }
+
return false;
}
@@ -483,14 +519,52 @@ namespace TLSharp.Core.Network
}
}
- internal class MigrationNeededException : Exception
+ public class FloodException : Exception
+ {
+ public TimeSpan TimeToWait { get; private set; }
+
+ internal FloodException(TimeSpan timeToWait)
+ : base($"Flood prevention. Telegram now requires your program to do requests again only after {timeToWait.TotalSeconds} seconds have passed ({nameof(TimeToWait)} property)." +
+ " If you think the culprit of this problem may lie in TLSharp's implementation, open a Github issue please.")
+ {
+ TimeToWait = timeToWait;
+ }
+ }
+
+ internal abstract class DataCenterMigrationException : Exception
{
internal int DC { get; private set; }
- internal MigrationNeededException(int dc)
- : base ($"Your phone number is registered to a different DC: {dc}. Please migrate.")
+ private const string REPORT_MESSAGE =
+ " See: https://github.com/sochix/TLSharp#i-get-a-xxxmigrationexception-or-a-migrate_x-error";
+
+ protected DataCenterMigrationException(string msg, int dc) : base (msg + REPORT_MESSAGE)
{
DC = dc;
}
}
+
+ internal class PhoneMigrationException : DataCenterMigrationException
+ {
+ internal PhoneMigrationException(int dc)
+ : base ($"Phone number registered to a different DC: {dc}.", dc)
+ {
+ }
+ }
+
+ internal class FileMigrationException : DataCenterMigrationException
+ {
+ internal FileMigrationException(int dc)
+ : base ($"File located on a different DC: {dc}.", dc)
+ {
+ }
+ }
+
+ internal class UserMigrationException : DataCenterMigrationException
+ {
+ internal UserMigrationException(int dc)
+ : base($"User located on a different DC: {dc}.", dc)
+ {
+ }
+ }
}
\ No newline at end of file
diff --git a/TLSharp.Core/Requests/PingRequest.cs b/TLSharp.Core/Requests/PingRequest.cs
new file mode 100644
index 0000000..48aa61b
--- /dev/null
+++ b/TLSharp.Core/Requests/PingRequest.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using TeleSharp.TL;
+using TLSharp.Core.Utils;
+
+namespace TLSharp.Core.Requests
+{
+ public class PingRequest : TeleSharp.TL.TLMethod
+ {
+ public PingRequest()
+ {
+ }
+
+ public override void SerializeBody(BinaryWriter writer)
+ {
+ writer.Write(Constructor);
+ writer.Write(Helpers.GenerateRandomLong());
+ }
+
+ public override void DeserializeBody(BinaryReader reader)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override void deserializeResponse(BinaryReader stream)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override int Constructor
+ {
+ get
+ {
+ return 0x7abe77ec;
+ }
+ }
+ }
+}
diff --git a/TLSharp.Core/TLSharp.Core.csproj b/TLSharp.Core/TLSharp.Core.csproj
index 0b8ac8d..fbef942 100644
--- a/TLSharp.Core/TLSharp.Core.csproj
+++ b/TLSharp.Core/TLSharp.Core.csproj
@@ -63,6 +63,7 @@
+
diff --git a/TLSharp.Core/TLSharp.Core.nuspec b/TLSharp.Core/TLSharp.Core.nuspec
new file mode 100644
index 0000000..921a4e2
--- /dev/null
+++ b/TLSharp.Core/TLSharp.Core.nuspec
@@ -0,0 +1,28 @@
+
+
+
+ TLSharp
+ 0.$APPVEYOR_BUILD_VERSION$
+ Telegram client library implemented in C#
+ Ilya P
+ Ilya P
+ http://sochix.github.io/TLSharp/
+ https://core.telegram.org/favicon.ico
+ false
+ Unofficial Telegram (http://telegram.org) client library implemented in C#. Latest TL scheme supported.
+
+Consider donation to speed up development process.
+
+Bitcoin wallet: 3K1ocweFgaHnAibJ3n6hX7RNZWFTFcJjUe
+
+It's a perfect fit for any developer who would like to send data directly to Telegram users or write own custom Telegram client.
+ telegram client, telegram API
+ Copyright 2016
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TLSharp.Core/TelegramClient.cs b/TLSharp.Core/TelegramClient.cs
index eeb72b5..ea4dd8c 100644
--- a/TLSharp.Core/TelegramClient.cs
+++ b/TLSharp.Core/TelegramClient.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Threading.Tasks;
using System.Web;
using TeleSharp.TL;
+using TeleSharp.TL.Account;
using TeleSharp.TL.Auth;
using TeleSharp.TL.Contacts;
using TeleSharp.TL.Help;
@@ -14,6 +15,7 @@ using TLSharp.Core.MTProto.Crypto;
using TLSharp.Core.Network;
using TLSharp.Core.Requests;
using TLSharp.Core.Utils;
+using TLAuthorization = TeleSharp.TL.Auth.TLAuthorization;
namespace TLSharp.Core
{
@@ -29,16 +31,17 @@ namespace TLSharp.Core
public TelegramClient(int apiId, string apiHash, ISessionStore store = null, string sessionUserId = "session")
{
+ 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;
- if (_apiId == default(int))
- throw new MissingApiConfigurationException("API_ID");
- if (string.IsNullOrEmpty(_apiHash))
- throw new MissingApiConfigurationException("API_HASH");
_session = Session.TryLoadOrCreateNew(store, sessionUserId);
_transport = new TcpTransport(_session.ServerAddress, _session.Port);
@@ -96,6 +99,9 @@ namespace TLSharp.Core
public async Task IsPhoneRegisteredAsync(string phoneNumber)
{
+ if (String.IsNullOrWhiteSpace(phoneNumber))
+ throw new ArgumentNullException(nameof(phoneNumber));
+
if (_sender == null)
throw new InvalidOperationException("Not connected!");
@@ -108,6 +114,9 @@ namespace TLSharp.Core
public async Task SendCodeRequestAsync(string phoneNumber)
{
+ if (String.IsNullOrWhiteSpace(phoneNumber))
+ throw new ArgumentNullException(nameof(phoneNumber));
+
var completed = false;
TLRequestSendCode request = null;
@@ -122,7 +131,7 @@ namespace TLSharp.Core
completed = true;
}
- catch (MigrationNeededException ex)
+ catch (PhoneMigrationException ex)
{
await ReconnectToDcAsync(ex.DC);
}
@@ -133,6 +142,15 @@ namespace TLSharp.Core
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 };
await _sender.Send(request);
await _sender.Receive(request);
@@ -152,12 +170,12 @@ namespace TLSharp.Core
return ((TLUser)request.Response.user);
}
- public async Task SendRequestAsync(TLMethod methodtoExceute)
+ public async Task SendRequestAsync(TLMethod methodToExecute)
{
- await _sender.Send(methodtoExceute);
- await _sender.Receive(methodtoExceute);
+ await _sender.Send(methodToExecute);
+ await _sender.Receive(methodToExecute);
- var result = methodtoExceute.GetType().GetProperty("Response").GetValue(methodtoExceute);
+ var result = methodToExecute.GetType().GetProperty("Response").GetValue(methodToExecute);
return (T)result;
}
@@ -196,15 +214,15 @@ namespace TLSharp.Core
return await SendRequestAsync(req);
}
- public async Task GetUserDialogsAsync()
+ public async Task GetUserDialogsAsync()
{
var peer = new TLInputPeerSelf();
- return await SendRequestAsync(
+ 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(),
@@ -218,7 +236,7 @@ namespace TLSharp.Core
public async Task SendUploadedDocument(
TLAbsInputPeer peer, TLAbsInputFile file, string caption, string mimeType, TLVector attributes)
{
- return await SendRequestAsync(new TLRequestSendMedia()
+ return await SendRequestAsync(new TLRequestSendMedia()
{
random_id = Helpers.GenerateRandomLong(),
background = false,
@@ -236,12 +254,48 @@ namespace TLSharp.Core
public async Task GetFile(TLAbsInputFileLocation location, int filePartSize)
{
- return await SendRequestAsync(new TLRequestGetFile()
+ TLFile result = null;
+ try
{
- location = location,
- limit = filePartSize
- });
- }
+ result = await SendRequestAsync(new TLRequestGetFile()
+ {
+ location = location,
+ limit = filePartSize
+ });
+ }
+ 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);
+
+ _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();
+ }
private void OnUserAuthenticated(TLUser TLUser)
{
@@ -256,9 +310,14 @@ namespace TLSharp.Core
{
public const string InfoUrl = "https://github.com/sochix/TLSharp#quick-configuration";
- internal MissingApiConfigurationException(string invalidParamName):
+ 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) { }
+ }
}
diff --git a/TLSharp.Tests/TLSharpTests.cs b/TLSharp.Tests/TLSharpTests.cs
index ccd88f1..3f7b594 100644
--- a/TLSharp.Tests/TLSharpTests.cs
+++ b/TLSharp.Tests/TLSharpTests.cs
@@ -24,6 +24,8 @@ namespace TLSharp.Tests
private string NumberToAuthenticate { get; set; }
+ private string CodeToAuthenticate { get; set; }
+
private string NotRegisteredNumberToSignUp { get; set; }
private string UserNameToSendMessage { get; set; }
@@ -58,39 +60,41 @@ namespace TLSharp.Tests
private void GatherTestConfiguration()
{
+ string appConfigMsgWarning = "{0} not configured in app.config! Some tests may fail.";
+
ApiHash = ConfigurationManager.AppSettings[nameof(ApiHash)];
if (string.IsNullOrEmpty(ApiHash))
- Debug.WriteLine("ApiHash not configured in app.config! Some tests may fail.");
+ Debug.WriteLine(appConfigMsgWarning, nameof(ApiHash));
var apiId = ConfigurationManager.AppSettings[nameof(ApiId)];
if (string.IsNullOrEmpty(apiId))
- Debug.WriteLine("ApiId not configured in app.config! Some tests may fail.");
+ Debug.WriteLine(appConfigMsgWarning, nameof(ApiId));
else
ApiId = int.Parse(apiId);
NumberToAuthenticate = ConfigurationManager.AppSettings[nameof(NumberToAuthenticate)];
if (string.IsNullOrEmpty(NumberToAuthenticate))
- Debug.WriteLine("NumberToAuthenticate not configured in app.config! Some tests may fail.");
+ Debug.WriteLine(appConfigMsgWarning, nameof(NumberToAuthenticate));
+
+ CodeToAuthenticate = ConfigurationManager.AppSettings[nameof(CodeToAuthenticate)];
+ if (string.IsNullOrEmpty(CodeToAuthenticate))
+ Debug.WriteLine(appConfigMsgWarning, nameof(CodeToAuthenticate));
NotRegisteredNumberToSignUp = ConfigurationManager.AppSettings[nameof(NotRegisteredNumberToSignUp)];
if (string.IsNullOrEmpty(NotRegisteredNumberToSignUp))
- Debug.WriteLine("NotRegisteredNumberToSignUp not configured in app.config! Some tests may fail.");
-
- NumberToSendMessage = ConfigurationManager.AppSettings[nameof(NumberToSendMessage)];
- if (string.IsNullOrEmpty(NumberToSendMessage))
- Debug.WriteLine("NumberToSendMessage not configured in app.config! Some tests may fail.");
+ Debug.WriteLine(appConfigMsgWarning, nameof(NotRegisteredNumberToSignUp));
UserNameToSendMessage = ConfigurationManager.AppSettings[nameof(UserNameToSendMessage)];
if (string.IsNullOrEmpty(UserNameToSendMessage))
- Debug.WriteLine("UserNameToSendMessage not configured in app.config! Some tests may fail.");
+ Debug.WriteLine(appConfigMsgWarning, nameof(UserNameToSendMessage));
NumberToGetUserFull = ConfigurationManager.AppSettings[nameof(NumberToGetUserFull)];
if (string.IsNullOrEmpty(NumberToGetUserFull))
- Debug.WriteLine("NumberToGetUserFull not configured in app.config! Some tests may fail.");
+ Debug.WriteLine(appConfigMsgWarning, nameof(NumberToGetUserFull));
NumberToAddToChat = ConfigurationManager.AppSettings[nameof(NumberToAddToChat)];
if (string.IsNullOrEmpty(NumberToAddToChat))
- Debug.WriteLine("NumberToAddToChat not configured in app.config! Some tests may fail.");
+ Debug.WriteLine(appConfigMsgWarning, nameof(NumberToAddToChat));
}
[TestMethod]
@@ -101,9 +105,23 @@ namespace TLSharp.Tests
await client.ConnectAsync();
var hash = await client.SendCodeRequestAsync(NumberToAuthenticate);
- var code = "93463"; // you can change code in debugger
+ var code = CodeToAuthenticate; // you can change code in debugger too
- var user = await client.MakeAuthAsync(NumberToAuthenticate, hash, code);
+ if (String.IsNullOrWhiteSpace(code))
+ {
+ throw new Exception("CodeToAuthenticate is empty in the app.config file, fill it with the code you just got now by SMS/Telegram");
+ }
+
+ TLUser user = null;
+ try
+ {
+ user = await client.MakeAuthAsync(NumberToAuthenticate, hash, code);
+ }
+ catch (InvalidPhoneCodeException ex)
+ {
+ throw new Exception("CodeToAuthenticate is wrong in the app.config file, fill it with the code you just got now by SMS/Telegram",
+ ex);
+ }
Assert.IsNotNull(user);
Assert.IsTrue(client.IsUserAuthorized());
@@ -112,6 +130,15 @@ namespace TLSharp.Tests
[TestMethod]
public async Task SendMessageTest()
{
+ NumberToSendMessage = ConfigurationManager.AppSettings[nameof(NumberToSendMessage)];
+ if (string.IsNullOrWhiteSpace(NumberToSendMessage))
+ throw new Exception($"Please fill the '{nameof(NumberToSendMessage)}' setting in app.config file first");
+
+ // this is because the contacts in the address come without the "+" prefix
+ var normalizedNumber = NumberToSendMessage.StartsWith("+") ?
+ NumberToSendMessage.Substring(1, NumberToSendMessage.Length - 1) :
+ NumberToSendMessage;
+
var client = NewClient();
await client.ConnectAsync();
@@ -121,7 +148,7 @@ namespace TLSharp.Tests
var user = result.users.lists
.Where(x => x.GetType() == typeof(TLUser))
.Cast()
- .FirstOrDefault(x => x.phone == NumberToSendMessage);
+ .FirstOrDefault(x => x.phone == normalizedNumber);
if (user == null)
{
@@ -131,7 +158,6 @@ namespace TLSharp.Tests
await client.SendTypingAsync(new TLInputPeerUser() { user_id = user.id });
Thread.Sleep(3000);
await client.SendMessageAsync(new TLInputPeerUser() { user_id = user.id }, "TEST");
-
}
[TestMethod]
@@ -141,7 +167,7 @@ namespace TLSharp.Tests
await client.ConnectAsync();
- var dialogs = await client.GetUserDialogsAsync();
+ var dialogs = (TLDialogs) await client.GetUserDialogsAsync();
var chat = dialogs.chats.lists
.Where(c => c.GetType() == typeof(TLChannel))
.Cast()
@@ -231,6 +257,36 @@ namespace TLSharp.Tests
Assert.IsTrue(resFile.bytes.Length > 0);
}
+
+ [TestMethod]
+ public async Task DownloadFileFromWrongLocationTest()
+ {
+ var client = NewClient();
+
+ await client.ConnectAsync();
+
+ var result = await client.GetContactsAsync();
+
+ var user = result.users.lists
+ .Where(x => x.GetType() == typeof(TLUser))
+ .Cast()
+ .FirstOrDefault(x => x.id == 5880094);
+
+ var photo = ((TLUserProfilePhoto)user.photo);
+ var photoLocation = (TLFileLocation) photo.photo_big;
+
+ var resFile = await client.GetFile(new TLInputFileLocation()
+ {
+ local_id = photoLocation.local_id,
+ secret = photoLocation.secret,
+ volume_id = photoLocation.volume_id
+ }, 1024);
+
+ var res = await client.GetUserDialogsAsync();
+
+ Assert.IsTrue(resFile.bytes.Length > 0);
+ }
+
[TestMethod]
public async Task SignUpNewUser()
{
diff --git a/TLSharp.Tests/app.config b/TLSharp.Tests/app.config
index 6fc79b3..941fdda 100644
--- a/TLSharp.Tests/app.config
+++ b/TLSharp.Tests/app.config
@@ -4,6 +4,7 @@
+
diff --git a/TLSharp.sln b/TLSharp.sln
index 504f779..3c9edb4 100644
--- a/TLSharp.sln
+++ b/TLSharp.sln
@@ -34,6 +34,41 @@ Global
{DE5C0467-EE99-4734-95F2-EFF7A0B99924}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DE5C0467-EE99-4734-95F2-EFF7A0B99924}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
+ GlobalSection(MonoDevelopProperties) = preSolution
+ Policies = $0
+ $0.TextStylePolicy = $1
+ $1.inheritsSet = VisualStudio
+ $1.inheritsScope = text/plain
+ $1.scope = text/x-csharp
+ $0.CSharpFormattingPolicy = $2
+ $2.IndentSwitchBody = True
+ $2.IndentBlocksInsideExpressions = True
+ $2.AnonymousMethodBraceStyle = NextLine
+ $2.PropertyBraceStyle = NextLine
+ $2.PropertyGetBraceStyle = NextLine
+ $2.PropertySetBraceStyle = NextLine
+ $2.EventBraceStyle = NextLine
+ $2.EventAddBraceStyle = NextLine
+ $2.EventRemoveBraceStyle = NextLine
+ $2.StatementBraceStyle = NextLine
+ $2.ElseNewLinePlacement = NewLine
+ $2.CatchNewLinePlacement = NewLine
+ $2.FinallyNewLinePlacement = NewLine
+ $2.WhileNewLinePlacement = DoNotCare
+ $2.ArrayInitializerWrapping = DoNotChange
+ $2.ArrayInitializerBraceStyle = NextLine
+ $2.BeforeMethodDeclarationParentheses = False
+ $2.BeforeMethodCallParentheses = False
+ $2.BeforeConstructorDeclarationParentheses = False
+ $2.NewLineBeforeConstructorInitializerColon = NewLine
+ $2.NewLineAfterConstructorInitializerColon = SameLine
+ $2.BeforeDelegateDeclarationParentheses = False
+ $2.NewParentheses = False
+ $2.SpacesBeforeBrackets = False
+ $2.inheritsSet = Mono
+ $2.inheritsScope = text/x-csharp
+ $2.scope = text/x-csharp
+ EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
diff --git a/TeleSharp.TL/TLVector.cs b/TeleSharp.TL/TLVector.cs
index 8f35b7d..08e8ae5 100644
--- a/TeleSharp.TL/TLVector.cs
+++ b/TeleSharp.TL/TLVector.cs
@@ -10,7 +10,7 @@ namespace TeleSharp.TL
public class TLVector : TLObject
{
[TLObject(481674261)]
- public List lists = new List() ;
+ public List lists = new List();
public override int Constructor
{
get
@@ -22,21 +22,21 @@ namespace TeleSharp.TL
public override void DeserializeBody(BinaryReader br)
{
int count = br.ReadInt32();
- for(int i= 0;i< count;i++)
+ for (var i = 0; i < count; i++)
{
if (typeof(T) == typeof(int))
{
- lists.Add((T)Convert.ChangeType(br.ReadInt32(),typeof(T)));
+ lists.Add((T)Convert.ChangeType(br.ReadInt32(), typeof(T)));
}
- else if (typeof(T)==typeof(long))
+ else if (typeof(T) == typeof(long))
{
lists.Add((T)Convert.ChangeType(br.ReadInt64(), typeof(T)));
}
- else if (typeof(T) ==typeof(string))
+ else if (typeof(T) == typeof(string))
{
lists.Add((T)Convert.ChangeType(StringUtil.Deserialize(br), typeof(T)));
}
- else if(typeof(T)==typeof(double))
+ else if (typeof(T) == typeof(double))
{
lists.Add((T)Convert.ChangeType(br.ReadDouble(), typeof(T)));
}
@@ -53,13 +53,38 @@ namespace TeleSharp.TL
public override void SerializeBody(BinaryWriter bw)
{
- bw.Write(Constructor);
+ bw.Write(Constructor);
bw.Write(lists.Count());
- foreach (var item in lists.Cast())
- {
- item.SerializeBody(bw);
- }
+ foreach (var item in lists)
+ {
+ if (typeof(T) == typeof(int))
+ {
+ var res = (int)Convert.ChangeType(item, typeof(int));
+
+ bw.Write(res);
+ }
+ else if (typeof(T) == typeof(long))
+ {
+ var res = (long)Convert.ChangeType(item, typeof(long));
+ bw.Write(res);
+ }
+ else if (typeof(T) == typeof(string))
+ {
+ var res = (string)(Convert.ChangeType(item, typeof(string)));
+ StringUtil.Serialize(res, bw);
+ }
+ else if (typeof(T) == typeof(double))
+ {
+ var res = (double)Convert.ChangeType(item, typeof(double));
+ bw.Write(res);
+ }
+ else if (typeof(T).BaseType == typeof(TLObject))
+ {
+ var res = (TLObject)(object)item;
+ res.SerializeBody(bw);
+ }
+ }
}
}
}