From b06f8a8e1174f0d2580f36039054adb25d62403e Mon Sep 17 00:00:00 2001 From: Ilya P Date: Sat, 29 Oct 2016 11:47:18 +0300 Subject: [PATCH] Added File-Migrate feature --- TLSharp.Core/Network/MtProtoSender.cs | 34 +++++++++++++++ TLSharp.Core/TelegramClient.cs | 59 +++++++++++++++++++++------ TLSharp.Tests/TLSharpTests.cs | 30 ++++++++++++++ 3 files changed, 110 insertions(+), 13 deletions(-) diff --git a/TLSharp.Core/Network/MtProtoSender.cs b/TLSharp.Core/Network/MtProtoSender.cs index a8fd1ed..1f22aeb 100644 --- a/TLSharp.Core/Network/MtProtoSender.cs +++ b/TLSharp.Core/Network/MtProtoSender.cs @@ -281,6 +281,18 @@ namespace TLSharp.Core.Network var dcIdx = int.Parse(resultString); throw new MigrationNeededException(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 { throw new InvalidOperationException(errorMessage); @@ -493,4 +505,26 @@ namespace TLSharp.Core.Network DC = dc; } } + + internal class FileMigrationException : Exception + { + internal int DC { get; private set; } + + internal FileMigrationException(int dc) + : base ($"File is located on a different DC: {dc}. Please migrate.") + { + DC = dc; + } + } + + internal class UserMigrationException : Exception + { + internal int DC { get; private set; } + + internal UserMigrationException(int dc) + : base($"User is located on a different DC: {dc}. Please migrate.") + { + DC = dc; + } + } } \ No newline at end of file diff --git a/TLSharp.Core/TelegramClient.cs b/TLSharp.Core/TelegramClient.cs index 816c053..0c6f3c7 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 { @@ -152,12 +154,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); - - var result = methodtoExceute.GetType().GetProperty("Response").GetValue(methodtoExceute); + await _sender.Send(methodToExecute); + await _sender.Receive(methodToExecute); + + var result = methodToExecute.GetType().GetProperty("Response").GetValue(methodToExecute); return (T)result; } @@ -204,7 +206,7 @@ namespace TLSharp.Core } public async Task SendUploadedPhoto(TLAbsInputPeer peer, TLAbsInputFile file, string caption) - { + { return await SendRequestAsync(new TLRequestSendMedia() { random_id = Helpers.GenerateRandomLong(), @@ -218,7 +220,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 +238,43 @@ 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; + } private void OnUserAuthenticated(TLUser TLUser) { @@ -256,7 +289,7 @@ 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}") { } diff --git a/TLSharp.Tests/TLSharpTests.cs b/TLSharp.Tests/TLSharpTests.cs index 5da31bb..bb3284d 100644 --- a/TLSharp.Tests/TLSharpTests.cs +++ b/TLSharp.Tests/TLSharpTests.cs @@ -231,6 +231,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() {