diff --git a/README.md b/README.md index bc3ff4c..8cdba23 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![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 @@ -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); + } + } } } }