public static TelegramSettings GenerateAuthentication(Service service)
 {
     try
     {
         service.DebugPrint("Fetching nearest DC...");
         var settings = new TelegramSettings();
         var authInfo = TelegramUtils.RunSynchronously(FetchNewAuthentication(DefaultTransportConfig));
         using (var client = new TelegramClient(DefaultTransportConfig, 
             new ConnectionConfig(authInfo.AuthKey, authInfo.Salt), AppInfo))
         {
             TelegramUtils.RunSynchronously(client.Connect());
             var nearestDcId = (NearestDc)TelegramUtils.RunSynchronously(client.Methods.HelpGetNearestDcAsync(new HelpGetNearestDcArgs{}));
             var config = (Config)TelegramUtils.RunSynchronously(client.Methods.HelpGetConfigAsync(new HelpGetConfigArgs{ }));
             var dcOption = config.DcOptions.OfType<DcOption>().FirstOrDefault(x => x.Id == nearestDcId.NearestDcProperty);
             settings.NearestDcId = nearestDcId.NearestDcProperty;
             settings.NearestDcIp = dcOption.IpAddress;
             settings.NearestDcPort = (int)dcOption.Port;
         }
         service.DebugPrint("Generating authentication on nearest DC...");
         var authInfo2 = TelegramUtils.RunSynchronously(FetchNewAuthentication(
             new TcpClientTransportConfig(settings.NearestDcIp, settings.NearestDcPort)));
         settings.AuthKey = authInfo2.AuthKey;
         settings.Salt = authInfo2.Salt;
         service.DebugPrint("Great! Ready for the service to start.");
         return settings;
     }
     catch (Exception ex)
     {
         service.DebugPrint("Error in GenerateAuthentication: " + ex);
     }
     return null;
 }
        public async void DoCommand(string[] args)
        {
            var command = args[0].ToLower();

            switch (command)
            {
				case "decrypt":
				{
					try
					{
						var bytes = Convert.FromBase64String("+MW7Btpz31b0gt9WN5d5vAEAAAAVxLUcCwAAAMzG2AUAAAAAAQAAAA4xNDkuMTU0LjE3NS41MAC7AQAAzMbYBQEAAAABAAAAJzIwMDE6MGIyODpmMjNkOmYwMDE6MDAwMDowMDAwOjAwMDA6MDAwYbsBAADMxtgFAAAAAAIAAAAOMTQ5LjE1NC4xNjcuNTEAuwEAAMzG2AUBAAAAAgAAACcyMDAxOjA2N2M6MDRlODpmMDAyOjAwMDA6MDAwMDowMDAwOjAwMGG7AQAAzMbYBQAAAAADAAAADzE0OS4xNTQuMTc1LjEwMLsBAADMxtgFAQAAAAMAAAAnMjAwMTowYjI4OmYyM2Q6ZjAwMzowMDAwOjAwMDA6MDAwMDowMDBhuwEAAMzG2AUAAAAABAAAAA4xNDkuMTU0LjE2Ny45MQC7AQAAzMbYBQEAAAAEAAAAJzIwMDE6MDY3YzowNGU4OmYwMDQ6MDAwMDowMDAwOjAwMDA6MDAwYbsBAADMxtgFAgAAAAQAAAAPMTQ5LjE1NC4xNjUuMTIwuwEAAMzG2AUAAAAABQAAAA05MS4xMDguNTYuMTgwAAC7AQAAzMbYBQEAAAAFAAAAJzIwMDE6MGIyODpmMjNmOmYwMDU6MDAwMDowMDAwOjAwMDA6MDAwYbsBAADIAAAA6AMAAGQAAADA1AEAiBMAADB1AADgkwQAMHUAANwFAAAKAAAAYOoAAAIAAADIAAAAFcS1HAAAAAA=");
						TLRig.Default.PrepareSerializersForAllTLObjectsInAssembly(typeof (IMTProtoAsyncMethods).Assembly);
						using (var streamer = new TLStreamer(bytes))
						{
							var newResult = TLRig.Default.Deserialize(streamer);
							int hi = 5;
						}
					}
					catch (Exception ex)
					{
						Console.WriteLine(ex);
					}
				}
				break;


                case "setup":
                    {
                        DebugPrint("Fetching nearest DC...");
                        var telegramSettings = new TelegramSettings();
                        var authInfo = await FetchNewAuthentication(DefaultTransportConfig);
                        using (var client = new TelegramClient(DefaultTransportConfig, 
                            new ConnectionConfig(authInfo.AuthKey, authInfo.Salt), AppInfo))
                        {
                            await client.Connect();
                            var nearestDcId = (NearestDc)await(client.Methods.HelpGetNearestDcAsync(new HelpGetNearestDcArgs{}));
                            var config = (Config)await(client.Methods.HelpGetConfigAsync(new HelpGetConfigArgs{ }));
                            var dcOption = config.DcOptions.OfType<DcOption>().FirstOrDefault(x => x.Id == nearestDcId.NearestDcProperty);
                            telegramSettings.NearestDcId = nearestDcId.NearestDcProperty;
                            telegramSettings.NearestDcIp = dcOption.IpAddress;
                            telegramSettings.NearestDcPort = (int)dcOption.Port;
                        }
                        DebugPrint("Generating authentication on nearest DC...");
                        var authInfo2 = await FetchNewAuthentication(
                            new TcpClientTransportConfig(telegramSettings.NearestDcIp, telegramSettings.NearestDcPort));
                        telegramSettings.AuthKey = authInfo2.AuthKey;
                        telegramSettings.Salt = authInfo2.Salt;
                        SettingsManager.Save(this, telegramSettings);
                        DebugPrint("Great! Ready for the service to start.");
                    }
                    break;
                case "sendcode":
                    {
                        var number = args[1];
                        var transportConfig = 
                            new TcpClientTransportConfig(_settings.NearestDcIp, _settings.NearestDcPort);
                        using (var client = new TelegramClient(transportConfig, 
                            new ConnectionConfig(_settings.AuthKey, _settings.Salt), AppInfo))
                        {
                            await client.Connect();
                            var result = await client.Methods.AuthSendCodeAsync(new AuthSendCodeArgs
                            {
                                PhoneNumber = number,
                                ApiId = AppInfo.ApiId,
                                ApiHash = "f8f2562579817ddcec76a8aae4cd86f6",
                            });
                            DebugPrint(ObjectDumper.Dump(result));
                        }
                    }
                    break;
                case "signin":
                    {
                        var number = args[1];
                        var hash = args[2];
                        var code = args[3];
                        var transportConfig = 
                            new TcpClientTransportConfig(_settings.NearestDcIp, _settings.NearestDcPort);
                        using (var client = new TelegramClient(transportConfig, 
                            new ConnectionConfig(_settings.AuthKey, _settings.Salt), AppInfo))
                        {
                            await client.Connect();
                            var result = (AuthAuthorization)await client.Methods.AuthSignInAsync(new AuthSignInArgs
                            {
                                PhoneNumber = number,
                                PhoneCodeHash = hash,
                                PhoneCode = code,
                            });
                            DebugPrint(ObjectDumper.Dump(result));
                        }
                    }
                    break;
                case "signup":
                    {
                        var number = args[1];
                        var hash = args[2];
                        var code = args[3];
                        var firstName = args[4];
                        var lastName = args[5];
                        var transportConfig = 
                            new TcpClientTransportConfig(_settings.NearestDcIp, _settings.NearestDcPort);
                        using (var client = new TelegramClient(transportConfig, 
                            new ConnectionConfig(_settings.AuthKey, _settings.Salt), AppInfo))
                        {
                            await client.Connect();
                            var result = (AuthAuthorization)await client.Methods.AuthSignUpAsync(new AuthSignUpArgs
                            {
                                PhoneNumber = number,
                                PhoneCodeHash = hash,
                                PhoneCode = code,
                                FirstName = firstName,
                                LastName = lastName,
                            });
                            DebugPrint(ObjectDumper.Dump(result));
                        }
                    }
                    break;
                case "getcontacts":
                    {
                        var result = await _fullClient.Methods.ContactsGetContactsAsync(new ContactsGetContactsArgs
                        {
                            Hash = string.Empty
                        });
                        DebugPrint(ObjectDumper.Dump(result));
                    }
                    break;
//                case "sendhello":
//                    {
//                        var contacts = (ContactsContacts)await _fullClient.Methods.ContactsGetContactsAsync(new ContactsGetContactsArgs
//                        {
//                            Hash = string.Empty
//                        });
//                        var counter = 0;
//                        Console.WriteLine("Pick a contact:");
//                        foreach (var icontact in contacts.Users)
//                        {
//                            var contact = icontact as UserContact;
//                            if (contact == null)
//                                continue;
//                            Console.WriteLine(counter++ + ") " + contact.FirstName + " " + contact.LastName);
//                        }
//                        var choice = int.Parse(Console.ReadLine());
//                        var chosenContact = (UserContact)contacts.Users[choice];
//                        var result = await _fullClient.Methods.MessagesSendMessageAsync(new MessagesSendMessageArgs
//                        {
//                            Peer = new InputPeerContact
//                            {
//                                UserId = chosenContact.Id,
//                            },
//                            Message = "Hello from Disa!",
//                            RandomId = (ulong)Time.GetNowUnixTimestamp(),
//                        });
//                        Console.WriteLine(ObjectDumper.Dump(result));
//                    }
//                    break;
            }

        }
Beispiel #3
0
 public FullClientDisposable(Telegram telegram)
 {
     if (telegram.IsFullClientConnected)
     {
         _client = telegram._fullClient;
         _isFullClient = true;
     }
     else
     {
         var transportConfig =
             new TcpClientTransportConfig(telegram._settings.NearestDcIp, telegram._settings.NearestDcPort);
         var client = new TelegramClient(transportConfig,
             new ConnectionConfig(telegram._settings.AuthKey, telegram._settings.Salt), AppInfo);
         var result = TelegramUtils.RunSynchronously(client.Connect());
         if (result != MTProtoConnectResult.Success)
         {
             throw new Exception("Failed to connect: " + result);
         }
         _client = client;
         _isFullClient = false;
     }
 }
Beispiel #4
0
        public override void Connect(WakeLock wakeLock)
        {
            Disconnect();
            var sessionId = GetRandomId();
            var transportConfig = 
                new TcpClientTransportConfig(_settings.NearestDcIp, _settings.NearestDcPort);
            using (var client = new TelegramClient(transportConfig, 
                                    new ConnectionConfig(_settings.AuthKey, _settings.Salt), AppInfo))
            {
                var result = TelegramUtils.RunSynchronously(client.Connect());
                if (result != MTProtoConnectResult.Success)
                {
                    throw new Exception("Failed to connect: " + result);
                }   
                DebugPrint("Registering long poller...");
                var registerDeviceResult = TelegramUtils.RunSynchronously(client.Methods.AccountRegisterDeviceAsync(
                    new AccountRegisterDeviceArgs
                {
                    TokenType = 7,
                    Token = sessionId.ToString(CultureInfo.InvariantCulture),
                }));
                if (!registerDeviceResult)
                {
                    throw new Exception("Failed to register long poller...");
                }

                DebugPrint(">>>>>>>>>>>>>> Fetching state!");
                FetchState(client);
                DebugPrint (">>>>>>>>>>>>>> Fetching dialogs!");
                GetDialogs(client);
                GetConfig(client);
            }

            DebugPrint("Starting long poller...");
            if (_longPollClient != null)
            {
                _longPollClient.OnUpdateTooLong -= OnLongPollClientUpdateTooLong;
                _longPollClient.OnClosedInternally -= OnLongPollClientClosed;
            }
            _longPollerAborted = false;
            _longPollClient = new TelegramClient(transportConfig, 
                new ConnectionConfig(_settings.AuthKey, _settings.Salt) { SessionId = sessionId }, AppInfo);
            var result2 = TelegramUtils.RunSynchronously(_longPollClient.Connect());
            if (result2 != MTProtoConnectResult.Success)
            {
                throw new Exception("Failed to connect long poll client: " + result2);
            } 
            _longPollClient.OnUpdateTooLong += OnLongPollClientUpdateTooLong;
            _longPollClient.OnClosedInternally += OnLongPollClientClosed;
           	ScheduleLongPollPing();
            DebugPrint("Long poller started!");
        }
Beispiel #5
0
 private void OnLongPollClientUpdateTooLong(object sender, EventArgs e)
 {
     if (IsFullClientConnected)
         return;
     Task.Factory.StartNew(() =>
     {
         var transportConfig = 
             new TcpClientTransportConfig(_settings.NearestDcIp, _settings.NearestDcPort);
         using (var client = new TelegramClient(transportConfig, 
             new ConnectionConfig(_settings.AuthKey, _settings.Salt), AppInfo))
         {
             MTProtoConnectResult result = MTProtoConnectResult.Other;
             try
             {
                 result = TelegramUtils.RunSynchronously(client.Connect());
             }
             catch (Exception ex)
             {
                 DebugPrint("Exception while connecting " + ex);
             }
             if (result != MTProtoConnectResult.Success)
             {
                 throw new Exception("Failed to connect: " + result);
             }  
             FetchState(client);
         }
     });
 }
Beispiel #6
0
        public async void DoCommand(string[] args)
        {
            var command = args[0].ToLower();

            switch (command)
            {
                case "setup":
                    {
                        DebugPrint("Fetching nearest DC...");
                        var telegramSettings = new TelegramSettings();
                        var authInfo = await FetchNewAuthentication(DefaultTransportConfig);
                        using (var client = new TelegramClient(DefaultTransportConfig, 
                            new ConnectionConfig(authInfo.AuthKey, authInfo.Salt), AppInfo))
                        {
                            await client.Connect();
                            var nearestDcId = (NearestDc)await(client.Methods.HelpGetNearestDcAsync(new HelpGetNearestDcArgs{}));
                            var config = (Config)await(client.Methods.HelpGetConfigAsync(new HelpGetConfigArgs{ }));
                            var dcOption = config.DcOptions.OfType<DcOption>().FirstOrDefault(x => x.Id == nearestDcId.NearestDcProperty);
                            telegramSettings.NearestDcId = nearestDcId.NearestDcProperty;
                            telegramSettings.NearestDcIp = dcOption.IpAddress;
                            telegramSettings.NearestDcPort = (int)dcOption.Port;
                        }
                        DebugPrint("Generating authentication on nearest DC...");
                        var authInfo2 = await FetchNewAuthentication(
                            new TcpClientTransportConfig(telegramSettings.NearestDcIp, telegramSettings.NearestDcPort));
                        telegramSettings.AuthKey = authInfo2.AuthKey;
                        telegramSettings.Salt = authInfo2.Salt;
                        SettingsManager.Save(this, telegramSettings);
                        DebugPrint("Great! Ready for the service to start.");
                    }
                    break;
                case "sendcode":
                    {
                        var number = args[1];
                        var transportConfig = 
                            new TcpClientTransportConfig(_settings.NearestDcIp, _settings.NearestDcPort);
                        using (var client = new TelegramClient(transportConfig, 
                                                new ConnectionConfig(_settings.AuthKey, _settings.Salt), AppInfo))
                        {
                            await client.Connect();
                            var result = await client.Methods.AuthSendCodeAsync(new AuthSendCodeArgs
                                {
                                    PhoneNumber = number,
                                    SmsType = 0,
                                    ApiId = AppInfo.ApiId,
                                    ApiHash = "f8f2562579817ddcec76a8aae4cd86f6",
                                    LangCode = PhoneBook.Language
                                });
                            DebugPrint(ObjectDumper.Dump(result));
                        }
                    }
                    break;
                case "signin":
                    {
                        var number = args[1];
                        var hash = args[2];
                        var code = args[3];
                        var transportConfig = 
                            new TcpClientTransportConfig(_settings.NearestDcIp, _settings.NearestDcPort);
                        using (var client = new TelegramClient(transportConfig, 
                                                new ConnectionConfig(_settings.AuthKey, _settings.Salt), AppInfo))
                        {
                            await client.Connect();
                            var result = (AuthAuthorization)await client.Methods.AuthSignInAsync(new AuthSignInArgs
                            {
                                PhoneNumber = number,
                                PhoneCodeHash = hash,
                                PhoneCode = code,
                            });
                            DebugPrint(ObjectDumper.Dump(result));
                        }
                    }
                    break;
                case "signup":
                    {
                        var number = args[1];
                        var hash = args[2];
                        var code = args[3];
                        var firstName = args[4];
                        var lastName = args[5];
                        var transportConfig = 
                            new TcpClientTransportConfig(_settings.NearestDcIp, _settings.NearestDcPort);
                        using (var client = new TelegramClient(transportConfig, 
                            new ConnectionConfig(_settings.AuthKey, _settings.Salt), AppInfo))
                        {
                            await client.Connect();
                            var result = (AuthAuthorization)await client.Methods.AuthSignUpAsync(new AuthSignUpArgs
                            {
                                PhoneNumber = number,
                                PhoneCodeHash = hash,
                                PhoneCode = code,
                                FirstName = firstName,
                                LastName = lastName,
                            });
                            DebugPrint(ObjectDumper.Dump(result));
                        }
                    }
                    break;
                case "getcontacts":
                    {
                        var result = await _fullClient.Methods.ContactsGetContactsAsync(new ContactsGetContactsArgs
                        {
                            Hash = string.Empty
                        });
                        DebugPrint(ObjectDumper.Dump(result));
                    }
                    break;
                case "sendhello":
                    {
                        var contacts = (ContactsContacts)await _fullClient.Methods.ContactsGetContactsAsync(new ContactsGetContactsArgs
                            {
                                Hash = string.Empty
                            });
                        var counter = 0;
                        Console.WriteLine("Pick a contact:");
                        foreach (var icontact in contacts.Users)
                        {
                            var contact = icontact as UserContact;
                            if (contact == null)
                                continue;
                            Console.WriteLine(counter++ + ") " + contact.FirstName + " " + contact.LastName);
                        }
                        var choice = int.Parse(Console.ReadLine());
                        var chosenContact = (UserContact)contacts.Users[choice];
                        var result = await _fullClient.Methods.MessagesSendMessageAsync(new MessagesSendMessageArgs
                            {
                                Peer = new InputPeerContact
                                    {
                                        UserId = chosenContact.Id,
                                    },
                                Message = "Hello from Disa!",
                                RandomId = (ulong)Time.GetNowUnixTimestamp(),
                            });
                        Console.WriteLine(ObjectDumper.Dump(result));
                    }
                    break;
            }

        }
Beispiel #7
0
        public static CodeRegister RegisterCode(Service service, TelegramSettings settings, string number, string codeHash, string code, string firstName, string lastName, bool signIn)
        {
            try
            {
                service.DebugPrint("Registering code...");
                var transportConfig = 
                    new TcpClientTransportConfig(settings.NearestDcIp, settings.NearestDcPort);
                using (var client = new TelegramClient(transportConfig,
                    new ConnectionConfig(settings.AuthKey, settings.Salt), AppInfo))
                {
                    TelegramUtils.RunSynchronously(client.Connect());

                    try
                    {
                        IAuthAuthorization iresult = null;
                        if (signIn)
                        {
                            iresult = TelegramUtils.RunSynchronously(client.Methods.AuthSignInAsync(new AuthSignInArgs
                                {
                                    PhoneNumber = number,
                                    PhoneCodeHash = codeHash,
                                    PhoneCode = code,
                                }));
                        }
                        else
                        {
                            iresult = TelegramUtils.RunSynchronously(client.Methods.AuthSignUpAsync(new AuthSignUpArgs
                                {
                                    PhoneNumber = number,
                                    PhoneCodeHash = codeHash,
                                    PhoneCode = code,
                                    FirstName = firstName,
                                    LastName = lastName,
                                }));
                        }
                        var result = (AuthAuthorization)iresult;
                        return new CodeRegister
                        {
                            AccountId = (result.User as UserSelf).Id,
                            Expires = result.Expires,
                            Response = CodeRegister.Type.Success,
                        };
                    }
                    catch (RpcErrorException ex)
                    {
                        var error = (RpcError)ex.Error;
                        var cr = new CodeRegister();
                        var response = CodeRegister.Type.Failure;
                        switch (error.ErrorMessage)
                        {
                            case "PHONE_NUMBER_INVALID":
                                cr.Response = CodeRegister.Type.NumberInvalid;
                                break;
                            case "PHONE_CODE_EMPTY":
                                cr.Response = CodeRegister.Type.CodeEmpty;
                                break;
                            case "PHONE_CODE_EXPIRED":
                                cr.Response = CodeRegister.Type.CodeExpired;
                                break;
                            case "PHONE_CODE_INVALID":
                                cr.Response = CodeRegister.Type.CodeInvalid;
                                break;
                            case "FIRSTNAME_INVALID":
                                cr.Response = CodeRegister.Type.FirstNameInvalid;
                                break;
                            case "LASTNAME_INVALID":
                                cr.Response = CodeRegister.Type.LastNameInvalid;
                                break;
                            default:
                                cr.Response = CodeRegister.Type.Failure;
                                break;
                        }
                        return cr;
                    }
                }
            }
            catch (Exception ex)
            {
                service.DebugPrint("Error in CodeRequest: " + ex);
            }
            return null;
        }
Beispiel #8
0
        public static CodeRequest RequestCode(Service service, string number, string codeHash, TelegramSettings settings, bool call)
        {
            try
            {
                service.DebugPrint("Requesting code...");
                var transportConfig = 
                    new TcpClientTransportConfig(settings.NearestDcIp, settings.NearestDcPort);
                using (var client = new TelegramClient(transportConfig,
                    new ConnectionConfig(settings.AuthKey, settings.Salt), AppInfo))
                {
                    TelegramUtils.RunSynchronously(client.Connect());

                    if (!call)
                    {
                        try
                        {
                            var result = TelegramUtils.RunSynchronously(client.Methods.AuthSendCodeAsync(new AuthSendCodeArgs
                            {
                                PhoneNumber = number,
                                SmsType = 0,
                                ApiId = AppInfo.ApiId,
                                ApiHash = "f8f2562579817ddcec76a8aae4cd86f6",
                                LangCode = PhoneBook.Language
                            })) as AuthSentCode;
                            return new CodeRequest
                            {
                                Registered = result.PhoneRegistered,
                                CodeHash = result.PhoneCodeHash,
                            };
                        }
                        catch (RpcErrorException ex)
                        {
                            var error = (RpcError)ex.Error;
                            var cr = new CodeRequest();
                            var response = CodeRequest.Type.Failure;
                            switch (error.ErrorCode)
                            {
                                case 400:
                                    cr.Response = CodeRequest.Type.NumberInvalid;
                                    break;
                                default:
                                    cr.Response = CodeRequest.Type.Failure;
                                    break;
                            }
                            return cr;
                        }
                    }
                    var result2 = (bool)TelegramUtils.RunSynchronously(client.Methods.AuthSendCallAsync(new AuthSendCallArgs
                    {
                        PhoneNumber = number,
                        PhoneCodeHash = codeHash,
                    }));
                    return new CodeRequest
                    {
                        Response = result2 ? CodeRequest.Type.Success : CodeRequest.Type.Failure
                    };
                }
            }
            catch (Exception ex)
            {
                service.DebugPrint("Error in CodeRequest: " + ex);
            }
            return null;
        }
        public static AuthExportedAuthorization GenerateExportedAuth(int migrateId, TelegramSettings settings)
        {
            var transportConfig =
                   new TcpClientTransportConfig(settings.NearestDcIp, settings.NearestDcPort);
            using (var client = new TelegramClient(transportConfig,
                                                   new ConnectionConfig(settings.AuthKey, settings.Salt), AppInfo))
            {
                TelegramUtils.RunSynchronously(client.Connect());
                var exportedAuth = (AuthExportedAuthorization)TelegramUtils.RunSynchronously(client.Methods.AuthExportAuthorizationAsync(
                            new SharpTelegram.Schema.AuthExportAuthorizationArgs
                            {
                                DcId = (uint)migrateId,
                            }));
                return exportedAuth;
            }


        }
 public static DcOption GetDcConfig(int migrateId, TelegramSettings settings)
 {
     var transportConfig =
             new TcpClientTransportConfig(settings.NearestDcIp, settings.NearestDcPort);
     using (var client = new TelegramClient(transportConfig,
                                            new ConnectionConfig(settings.AuthKey, settings.Salt), AppInfo)) 
     {
         TelegramUtils.RunSynchronously(client.Connect());
         var config = (Config)TelegramUtils.RunSynchronously(client.Methods.HelpGetConfigAsync(new HelpGetConfigArgs { }));
         var dcOption = config.DcOptions.OfType<DcOption>().FirstOrDefault(x => x.Id == migrateId);
         return dcOption;
     }
 }
        private TelegramClient SpinUpClient(int dc)
        {
            object dcLock;

            lock (_spinUpLocks)
            {
                if (_spinUpLocks.ContainsKey(dc))
                {
                    dcLock = _spinUpLocks[dc];
                }
                else
                {
                    dcLock = new object();
                    _spinUpLocks[dc] = dcLock;
                }
            }

            lock (dcLock)
            {
                var client = GetClientInternal(dc);
                if (client != null)
                    return client;

                if (_config == null)
                {
                    DebugPrint("Config is null. Unable to resolve DC information.");
                    return null;
                }

                var dcOption = _config.DcOptions.Cast<DcOption>().FirstOrDefault(x => x.Id == dc);

                if (dcOption == null)
                {
                    DebugPrint("Unable to find DC for DC ID: " + dc);
                    return null;
                }

                var dcCached = DcDatabase.Get(dc);

                var transportConfig = 
                    new TcpClientTransportConfig(dcOption.IpAddress, (int)dcOption.Port);

                SharpMTProto.Authentication.AuthInfo authInfo;
                AuthExportedAuthorization exportedAuth = null;

                if (dcCached == null)
                {
                    DebugPrint("Looks like we'll have to authenticate a new connection to: "
                    + ObjectDumper.Dump(dcOption));

                    DebugPrint(">>>>>>>> Exporting auth...");

                    using (var clientDisposable = new TelegramClientDisposable(this))
                    {
                        exportedAuth = (AuthExportedAuthorization)TelegramUtils.RunSynchronously(clientDisposable.Client.Methods.AuthExportAuthorizationAsync(
                            new SharpTelegram.Schema.Layer18.AuthExportAuthorizationArgs
                            {
                                DcId = (uint)dc,
                            }));
                    }

                    DebugPrint(">>>>>>> Got exported auth.");

                    if (exportedAuth == null)
                    {
                        DebugPrint("Exported auth is null for some weird reason. DC ID: " + dc);
                        return null;
                    }

                    DebugPrint(">>>>>>> Fetching new authentication...");

                    authInfo = TelegramUtils.RunSynchronously(FetchNewAuthentication(transportConfig));
                }
                else
                {
                    authInfo = new SharpMTProto.Authentication.AuthInfo(dcCached.Key,
                        BitConverter.ToUInt64(dcCached.Salt, 0));
                }

                DebugPrint(">>>>>>>> Starting new client...");

                var newClient = new TelegramClient(transportConfig, 
                    new ConnectionConfig(authInfo.AuthKey, authInfo.Salt), AppInfo);

                newClient.OnClosedInternally += (sender, e) =>
                {
                    DebugPrint("Removing connection to DC: "+ dc);
                    lock (_activeClients)
                    {
                        _activeClients.Remove(dc);
                    }
                };

                var result = TelegramUtils.RunSynchronously(newClient.Connect());
                if (result != MTProtoConnectResult.Success)
                {
                    DebugPrint("Failed to connect to DC: " + dc + ": " + result);
                    return null;
                }

                if (exportedAuth != null)
                {
                    TelegramUtils.RunSynchronously(newClient.Methods.AuthImportAuthorizationAsync(new AuthImportAuthorizationArgs
                        {
                            Id = exportedAuth.Id,
                            Bytes = exportedAuth.Bytes,
                        }));
                }

                PingDelay(client, 60);

                lock (_activeClients)
                {
                    _activeClients[dc] = newClient;
                }

                if (dcCached == null)
                {
                    DcDatabase.Set(new TelegramDc
                    {
                        Dc = dc,
                        Key = authInfo.AuthKey,
                        Salt = BitConverter.GetBytes(authInfo.Salt),
                    });
                }

                return newClient;
            }
        }