diff --git a/Apps/ClientConsoleApp/App.config b/Apps/ClientConsoleApp/App.config
new file mode 100644
index 0000000..bc5b438
--- /dev/null
+++ b/Apps/ClientConsoleApp/App.config
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Apps/ClientConsoleApp/ClientConsoleApp.csproj b/Apps/ClientConsoleApp/ClientConsoleApp.csproj
new file mode 100644
index 0000000..95ed837
--- /dev/null
+++ b/Apps/ClientConsoleApp/ClientConsoleApp.csproj
@@ -0,0 +1,63 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {15296FBD-23B9-4786-8CC0-65C872FBFDAC}
+ Exe
+ ClientConsoleApp
+ ClientConsoleApp
+ v4.6
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {d6144517-91d2-4880-86df-e9ff5d7f383a}
+ TeleSharp.TL
+
+
+ {400d2544-1cc6-4d8a-a62c-2292d9947a16}
+ TLSharp.Core
+
+
+
+
\ No newline at end of file
diff --git a/Apps/ClientConsoleApp/Program.cs b/Apps/ClientConsoleApp/Program.cs
new file mode 100644
index 0000000..378f411
--- /dev/null
+++ b/Apps/ClientConsoleApp/Program.cs
@@ -0,0 +1,117 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using TeleSharp.TL;
+using TLSharp.Core;
+
+namespace ClientConsoleApp
+{
+ class Program
+ {
+ private static string NumberToSendMessage => ConfigurationManager.AppSettings[nameof(NumberToSendMessage)];
+
+ static void Main(string[] args)
+ {
+ Thread.Sleep(2000);
+ Console.WriteLine("Hello World!");
+
+ //var tcpClient = new TcpClient();
+ //tcpClient.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5000));
+ //TestTcpClient(tcpClient);
+ //TestTcpClient(tcpClient);
+
+ TelegramClient client = GetTlgClient().Result;
+ var normalizedNumber = NumberToSendMessage.StartsWith("+") ?
+ NumberToSendMessage.Substring(1, NumberToSendMessage.Length - 1) :
+ NumberToSendMessage;
+
+ var result = client.GetContactsAsync().Result;
+
+ var user = result.Users
+ .OfType()
+ .FirstOrDefault(x => x.Phone == normalizedNumber);
+
+ var rr = client.SendTypingAsync(new TLInputPeerUser() { UserId = user.Id }).Result;
+ Thread.Sleep(3000);
+ var rrr = client.SendMessageAsync(new TLInputPeerUser() { UserId = user.Id }, "TEST").Result;
+ }
+ private static async Task GetTlgClient()
+ {
+ string ApiHash = ConfigurationManager.AppSettings["ApiHash"];
+ int ApiId = int.Parse(ConfigurationManager.AppSettings["ApiId"]);
+ //string AuthCode = ConfigurationManager.AppSettings["AuthCode"];
+ string MainPhoneNumber = ConfigurationManager.AppSettings["NumberToAuthenticate"];
+ var client = new TelegramClient(ApiId, ApiHash, null, "session", null, "127.0.0.1", 5000);//
+ var phoneCodeHash = string.Empty;
+ authenticated:
+ Console.WriteLine("Start app");
+ client.ConnectAsync().Wait();
+ Console.WriteLine("MakeAuthentication");
+ await MakeAuthentication(client, MainPhoneNumber);
+
+ Console.WriteLine("Connected");
+ if (!client.IsUserAuthorized())
+ {
+ Console.WriteLine("User not autorized");
+ if (string.IsNullOrEmpty(phoneCodeHash))
+ {
+ phoneCodeHash = await client.SendCodeRequestAsync(MainPhoneNumber);
+ goto authenticated;
+ }
+
+ Console.WriteLine("Plase enter new AuthCode:");
+ var AuthCode = Console.ReadLine();
+ var user = await client.MakeAuthAsync(MainPhoneNumber, phoneCodeHash, AuthCode);
+ Console.WriteLine("Login successfull.");
+ }
+
+ return client;
+ }
+
+ private static async Task MakeAuthentication(TLSharp.Core.TelegramClient client, string mainPhoneNumber)
+ {
+ var hash = await client.SendCodeRequestAsync(mainPhoneNumber);
+ Console.WriteLine("waiting for code");
+ var code = Console.ReadLine();
+ var user = await client.MakeAuthAsync(mainPhoneNumber, hash, code);
+ if (!client.IsUserAuthorized())
+ {
+ hash = await client.SendCodeRequestAsync(mainPhoneNumber);
+ Console.WriteLine("please try again.add code");
+ code = Console.ReadLine();
+ user = await client.MakeAuthAsync(mainPhoneNumber, hash, code);
+ }
+
+ }
+
+ private static void TestTcpClient(TcpClient tcpClient)
+ {
+ if (tcpClient.Connected)
+ {
+ using (var memoryStream = new MemoryStream())
+ {
+ using (var binaryWriter = new BinaryWriter(memoryStream))
+ {
+ binaryWriter.Write((long)0);
+ binaryWriter.Write(1234);
+ binaryWriter.Write(20);
+ binaryWriter.Write(8000);
+
+ byte[] packet = memoryStream.ToArray();
+
+ tcpClient.GetStream().WriteAsync(packet, 0, packet.Length).Wait();
+ }
+ }
+ }
+
+ Thread.Sleep(5000);
+ }
+ }
+}
diff --git a/Apps/ClientConsoleApp/Properties/AssemblyInfo.cs b/Apps/ClientConsoleApp/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..0f97770
--- /dev/null
+++ b/Apps/ClientConsoleApp/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ClientConsoleApp")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ClientConsoleApp")]
+[assembly: AssemblyCopyright("Copyright © 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("15296fbd-23b9-4786-8cc0-65c872fbfdac")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Apps/TlgListenerApplication/App.config b/Apps/TlgListenerApplication/App.config
new file mode 100644
index 0000000..8324aa6
--- /dev/null
+++ b/Apps/TlgListenerApplication/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Apps/TlgListenerApplication/Program.cs b/Apps/TlgListenerApplication/Program.cs
new file mode 100644
index 0000000..c43629d
--- /dev/null
+++ b/Apps/TlgListenerApplication/Program.cs
@@ -0,0 +1,442 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Runtime.Serialization.Formatters.Binary;
+using System.Text;
+using System.Threading.Tasks;
+using Ionic.Crc;
+using TLSharp.Core.Auth;
+using TLSharp.Core.MTProto;
+using TLSharp.Core.MTProto.Crypto;
+using TLSharp.Core.Network;
+using TLSharp.Core.Utils;
+
+namespace TlgListenerApplication
+{
+ class Program
+ {
+ private static int sequence = 0;
+ private static int timeOffset;
+ private static long lastMessageId;
+ private static Random random => new Random();
+
+ static void Main(string[] args)
+ {
+ Console.WriteLine("Listening...");
+ TcpListener();
+ Console.WriteLine("The end");
+ Console.ReadKey();
+ }
+
+ private static void TcpListener()
+ {
+ try
+ {
+ var tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 5000);
+ tcpListener.Start();
+ for (; ; )
+ {
+ if (tcpListener.Pending())
+ {
+ try
+ {
+ ProcessRequest(tcpListener);
+ }
+ catch (Exception e)
+ {
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.WriteLine(e);
+ Console.ForegroundColor = ConsoleColor.Gray;
+ }
+ }
+ }
+ }
+ catch (Exception exception)
+ {
+ Console.WriteLine(exception);
+ }
+ }
+
+ private static void ProcessRequest(TcpListener tcpListener)
+ {
+ Console.WriteLine("Processing...");
+ var tcpClient = tcpListener.AcceptTcpClient();
+ var netStream = tcpClient.GetStream();
+
+ //var getingCounter = 0;
+ //while (true)
+ //{
+ // if (!netStream.DataAvailable)
+ // continue;
+ // Console.WriteLine("Get data " + ++getingCounter);
+ //}
+
+ while (tcpClient.Connected)
+ {
+ System.Threading.Thread.Sleep(100);
+ if (!netStream.DataAvailable) continue;
+
+ byte[] nonceFromClient = new byte[16];
+ byte[] servernonce = new byte[16];
+ byte[] newNonce = new byte[32];
+ uint responseCode = 0;
+ const uint step1Constructor = 0x60469778;
+ const uint step2Constructor = 0xd712e4be;
+ const uint step3Constructor = 0xf5045f1f;
+
+ if (netStream.CanRead)
+ {
+ var bytes = new byte[tcpClient.ReceiveBufferSize];
+ netStream.Read(bytes, 0, (int)tcpClient.ReceiveBufferSize);
+ var tcpMessage = TcpMessage.Decode(bytes);
+ var binaryReader = new BinaryReader(new MemoryStream(tcpMessage.Body, false));
+
+ var authKeyId = binaryReader.ReadInt64();
+ if (authKeyId == 0)
+ {
+ var msgId = binaryReader.ReadInt64();
+ var datalength = binaryReader.ReadInt32();
+ var data = binaryReader.ReadBytes(datalength);
+
+ var binaryReader2 = new BinaryReader(new MemoryStream(data, false));
+
+ responseCode = binaryReader2.ReadUInt32();
+ Console.WriteLine("Request code: " + responseCode);
+ if (responseCode == step1Constructor) //---Step1_PQRequest
+ {
+ nonceFromClient = binaryReader2.ReadBytes(16);
+ }
+ else if (responseCode == step2Constructor) //---Step1_PQRequest
+ {
+ nonceFromClient = binaryReader2.ReadBytes(16);
+ servernonce = binaryReader2.ReadBytes(16);
+ var useless = binaryReader2.ReadBytes(13);
+ var ciphertext = binaryReader2.ReadBytes(500);
+ var newnoncetemp = new byte[32];
+ Array.Copy(ciphertext, ciphertext.Length - 32, newnoncetemp,0,32);
+ //ciphertext.CopyTo(newnoncetemp, ciphertext.Length - 32);
+ }
+ }
+ else
+ {
+ var decodeMessage = DecodeMessage(tcpMessage.Body);
+ var buffer = new byte[binaryReader.BaseStream.Length - 24];
+ int count;
+ using (var ms = new MemoryStream())
+ while ((count = binaryReader.Read(buffer, 0, buffer.Length)) != 0)
+ ms.Write(buffer, 0, count);
+
+ //var keyData = Helpers.CalcKey(buffer, messageKey, false);
+ //var data = AES.DecryptAES(keyData, buffer);
+ }
+
+ //var obj = new Step1_PQRequest().FromBytes(data);
+ //var rr = FromByteArray(data);
+
+ //var binaryReader = new BinaryReader(netStream);
+ //var a = binaryReader.ReadInt64();
+ //var b = binaryReader.ReadInt32();
+ //var c = binaryReader.ReadInt32();
+ //var d = binaryReader.ReadInt32();
+ }
+
+ if (netStream.CanWrite)
+ {
+
+ var fingerprint = StringToByteArray("216be86c022bb4c3");
+
+ byte[] outputdata = null;
+ if (responseCode == step1Constructor)
+ {
+ var nonce = new byte[16];
+ new Random().NextBytes(nonce);
+ outputdata = new Step1_Response()
+ {
+ Pq = new BigInteger(1, BitConverter.GetBytes(880)),
+ ServerNonce = nonceFromClient,
+ Nonce = nonce,
+ Fingerprints = new List() { fingerprint }
+ }.ToBytes();
+ }
+ else if (responseCode == step2Constructor)
+ {
+ //var nonce = new byte[16];
+ //new Random().NextBytes(nonce);
+
+ byte[] answer;
+ var hashsum = Encoding.UTF8.GetBytes("asdfghjklmnbvcxzasdf");
+ const uint innerCode = 0xb5890dba;
+ AESKeyData key = AES.GenerateKeyDataFromNonces(servernonce, newNonce);
+ using (var memoryStream = new MemoryStream())
+ {
+ using (var binaryWriter = new BinaryWriter(memoryStream))
+ {
+ binaryWriter.Write(hashsum);
+ binaryWriter.Write(innerCode);
+ binaryWriter.Write(nonceFromClient);
+ binaryWriter.Write(newNonce);
+ binaryWriter.Write(123456789);
+ Serializers.Bytes.write(binaryWriter, new BigInteger(1, BitConverter.GetBytes(777)).ToByteArrayUnsigned());
+ Serializers.Bytes.write(binaryWriter, new BigInteger(1, BitConverter.GetBytes(888)).ToByteArrayUnsigned());
+ answer = memoryStream.ToArray();
+ }
+ }
+
+ outputdata = new Step2_Response()
+ {
+ ServerNonce = nonceFromClient,
+ Nonce = servernonce,
+ NewNonce = newNonce,
+ EncryptedAnswer = AES.EncryptAES(key, answer)
+ }.ToBytes();
+ }
+ else if (responseCode == step3Constructor)
+ {
+ var newnonce = new byte[16];
+ new Random().NextBytes(newnonce);
+ const uint innerCode = 0x3bcbf734;
+ using (var memoryStream = new MemoryStream())
+ {
+ using (var binaryWriter = new BinaryWriter(memoryStream))
+ {
+ binaryWriter.Write(innerCode);
+ binaryWriter.Write(newnonce);
+ binaryWriter.Write(nonceFromClient);
+ binaryWriter.Write(newnonce);
+ outputdata = memoryStream.ToArray();
+ }
+ }
+ }
+
+ var bytes = PrepareToSend(outputdata);
+ var datatosend = Encode(bytes, 11);
+ netStream.Write(datatosend, 0, datatosend.Length);
+ }
+ else
+ {
+ Console.WriteLine("You cannot write data to this stream.");
+ tcpClient.Close();
+ netStream.Close();
+ }
+ }
+ }
+
+ private static void ProcessRequestSocket(TcpListener tcpListener)
+ {
+ Console.WriteLine("Processing...");
+ var tcpClient = tcpListener.AcceptSocket();
+
+ var bytes = new byte[tcpClient.ReceiveBufferSize];
+ var countbyte = tcpClient.Receive(bytes);
+
+ return;
+
+ byte[] nonceFromClient = new byte[16];
+ var tcpMessage = TcpMessage.Decode(bytes);
+ var binaryReader = new BinaryReader(new MemoryStream(tcpMessage.Body, false));
+ var a = binaryReader.ReadInt64();
+ var msgId = binaryReader.ReadInt64();
+ var datalength = binaryReader.ReadInt32();
+ var data = binaryReader.ReadBytes(datalength);
+
+ var binaryReader2 = new BinaryReader(new MemoryStream(data, false));
+ const int responseConstructorNumber = 0x60469778;
+ var responseCode = binaryReader2.ReadInt32();
+ Console.WriteLine("Request code: " + responseCode);
+ if (responseCode == responseConstructorNumber)//---Step1_PQRequest
+ {
+ nonceFromClient = binaryReader2.ReadBytes(16);
+ }
+
+ var nonce = new byte[16];
+ new Random().NextBytes(nonce);
+
+ var fingerprint = StringToByteArray("216be86c022bb4c3");
+ //var rr = BitConverter.ToString(fingerprint).Replace("-", "");
+
+ var step1 = new Step1_Response()
+ {
+ Pq = new BigInteger(1, BitConverter.GetBytes(880)),
+ ServerNonce = nonceFromClient,
+ Nonce = nonce,
+ Fingerprints = new List() { fingerprint }
+ };
+ var bytes1 = PrepareToSend(step1.ToBytes());
+ var datatosend = Encode(bytes1, 11);
+ //Byte[] sendBytes = Encoding.UTF8.GetBytes("Is anybody there?");
+ tcpClient.Send(datatosend, SocketFlags.Truncated);
+
+ //tcpClient.Close();
+ }
+
+ public static async Task Receieve(TcpClient tcpClient)
+ {
+ var stream = tcpClient.GetStream();
+
+ var packetLengthBytes = new byte[4];
+ if (await stream.ReadAsync(packetLengthBytes, 0, 4) != 4)
+ throw new InvalidOperationException("Couldn't read the packet length");
+ int packetLength = BitConverter.ToInt32(packetLengthBytes, 0);
+
+ var seqBytes = new byte[4];
+ if (await stream.ReadAsync(seqBytes, 0, 4) != 4)
+ throw new InvalidOperationException("Couldn't read the sequence");
+ int seq = BitConverter.ToInt32(seqBytes, 0);
+
+ int readBytes = 0;
+ var body = new byte[packetLength - 12];
+ int neededToRead = packetLength - 12;
+
+ do
+ {
+ var bodyByte = new byte[packetLength - 12];
+ var availableBytes = await stream.ReadAsync(bodyByte, 0, neededToRead);
+ neededToRead -= availableBytes;
+ Buffer.BlockCopy(bodyByte, 0, body, readBytes, availableBytes);
+ readBytes += availableBytes;
+ }
+ while (readBytes != packetLength - 12);
+
+ var crcBytes = new byte[4];
+ if (await stream.ReadAsync(crcBytes, 0, 4) != 4)
+ throw new InvalidOperationException("Couldn't read the crc");
+ int checksum = BitConverter.ToInt32(crcBytes, 0);
+
+ byte[] rv = new byte[packetLengthBytes.Length + seqBytes.Length + body.Length];
+
+ Buffer.BlockCopy(packetLengthBytes, 0, rv, 0, packetLengthBytes.Length);
+ Buffer.BlockCopy(seqBytes, 0, rv, packetLengthBytes.Length, seqBytes.Length);
+ Buffer.BlockCopy(body, 0, rv, packetLengthBytes.Length + seqBytes.Length, body.Length);
+ var crc32 = new Ionic.Crc.CRC32();
+ crc32.SlurpBlock(rv, 0, rv.Length);
+ var validChecksum = crc32.Crc32Result;
+
+ if (checksum != validChecksum)
+ {
+ throw new InvalidOperationException("invalid checksum! skip");
+ }
+
+ return new TcpMessage(seq, body);
+ }
+
+ public static byte[] PrepareToSend(byte[] data)
+ {
+ using (var memoryStream = new MemoryStream())
+ {
+ using (var binaryWriter = new BinaryWriter(memoryStream))
+ {
+ binaryWriter.Write((long)0);
+ binaryWriter.Write(GetNewMessageId());
+ binaryWriter.Write(data.Length);
+ binaryWriter.Write(data);
+
+ byte[] packet = memoryStream.ToArray();
+
+ return packet;
+ }
+ }
+ }
+
+ private static long GetNewMessageId()
+ {
+ long time = Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds);
+ long newMessageId = ((time / 1000 + timeOffset) << 32) |
+ ((time % 1000) << 22) |
+ (random.Next(524288) << 2); // 2^19
+ // [ unix timestamp : 32 bit] [ milliseconds : 10 bit ] [ buffer space : 1 bit ] [ random : 19 bit ] [ msg_id type : 2 bit ] = [ msg_id : 64 bit ]
+
+ if (lastMessageId >= newMessageId)
+ {
+ newMessageId = lastMessageId + 4;
+ }
+
+ lastMessageId = newMessageId;
+ return newMessageId;
+ }
+
+ private static Tuple DecodeMessage(byte[] body)
+ {
+ byte[] message;
+ ulong remoteMessageId;
+ int remoteSequence;
+
+ using (var inputStream = new MemoryStream(body))
+ using (var inputReader = new BinaryReader(inputStream))
+ {
+ if (inputReader.BaseStream.Length < 8)
+ throw new InvalidOperationException($"Can't decode packet");
+
+ ulong remoteAuthKeyId = inputReader.ReadUInt64(); // TODO: check auth key id
+ byte[] msgKey = inputReader.ReadBytes(16); // TODO: check msg_key correctness
+ AESKeyData keyData = Helpers.CalcKey(body, msgKey, false);
+
+ byte[] plaintext = AES.DecryptAES(keyData, inputReader.ReadBytes((int)(inputStream.Length - inputStream.Position)));
+
+ using (MemoryStream plaintextStream = new MemoryStream(plaintext))
+ using (BinaryReader plaintextReader = new BinaryReader(plaintextStream))
+ {
+ var remoteSalt = plaintextReader.ReadUInt64();
+ var remoteSessionId = plaintextReader.ReadUInt64();
+ remoteMessageId = plaintextReader.ReadUInt64();
+ remoteSequence = plaintextReader.ReadInt32();
+ int msgLen = plaintextReader.ReadInt32();
+ message = plaintextReader.ReadBytes(msgLen);
+ }
+ }
+ return new Tuple(message, remoteMessageId, remoteSequence);
+ }
+
+ private static byte[] Encode(byte[] body, int sequneceNumber)
+ {
+ using (var memoryStream = new MemoryStream())
+ {
+ using (var binaryWriter = new BinaryWriter(memoryStream))
+ {
+ // https://core.telegram.org/mtproto#tcp-transport
+ /*
+ 4 length bytes are added at the front
+ (to include the length, the sequence number, and CRC32; always divisible by 4)
+ and 4 bytes with the packet sequence number within this TCP connection
+ (the first packet sent is numbered 0, the next one 1, etc.),
+ and 4 CRC32 bytes at the end (length, sequence number, and payload together).
+ */
+ binaryWriter.Write(body.Length + 12);
+ binaryWriter.Write(sequneceNumber);
+ binaryWriter.Write(body);
+ var crc32 = new CRC32();
+ crc32.SlurpBlock(memoryStream.GetBuffer(), 0, 8 + body.Length);
+ binaryWriter.Write(crc32.Crc32Result);
+
+ var transportPacket = memoryStream.ToArray();
+
+ // Debug.WriteLine("Tcp packet #{0}\n{1}", SequneceNumber, BitConverter.ToString(transportPacket));
+
+ return transportPacket;
+ }
+ }
+ }
+
+ public static T FromByteArray(byte[] data)
+ {
+ if (data == null)
+ return default(T);
+ var bf = new BinaryFormatter();
+ using (var ms = new MemoryStream(data))
+ {
+ var obj = bf.Deserialize(ms);
+ return (T)obj;
+ }
+ }
+
+ public static byte[] StringToByteArray(string hex)
+ {
+ return Enumerable.Range(0, hex.Length)
+ .Where(x => x % 2 == 0)
+ .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
+ .ToArray();
+ }
+ }
+}
diff --git a/Apps/TlgListenerApplication/Properties/AssemblyInfo.cs b/Apps/TlgListenerApplication/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..519e112
--- /dev/null
+++ b/Apps/TlgListenerApplication/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("TlgListenerApplication")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("TlgListenerApplication")]
+[assembly: AssemblyCopyright("Copyright © 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("15f1cfa2-e099-48fd-97e7-be06aa5b3ea6")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Apps/TlgListenerApplication/TlgListenerApplication.csproj b/Apps/TlgListenerApplication/TlgListenerApplication.csproj
new file mode 100644
index 0000000..9dfe9e9
--- /dev/null
+++ b/Apps/TlgListenerApplication/TlgListenerApplication.csproj
@@ -0,0 +1,66 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {15F1CFA2-E099-48FD-97E7-BE06AA5B3EA6}
+ Exe
+ TlgListenerApplication
+ TlgListenerApplication
+ v4.6
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\MarkerMetro.Unity.Ionic.Zlib.2.0.0.14\lib\net35\Ionic.ZLib.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {d6144517-91d2-4880-86df-e9ff5d7f383a}
+ TeleSharp.TL
+
+
+ {400d2544-1cc6-4d8a-a62c-2292d9947a16}
+ TLSharp.Core
+
+
+
+
\ No newline at end of file
diff --git a/Apps/TlgListenerApplication/packages.config b/Apps/TlgListenerApplication/packages.config
new file mode 100644
index 0000000..a6d41ac
--- /dev/null
+++ b/Apps/TlgListenerApplication/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/TLSharp.Core/Auth/Step1_PQRequest.cs b/TLSharp.Core/Auth/Step1_PQRequest.cs
index 8d61d9a..24c97c1 100644
--- a/TLSharp.Core/Auth/Step1_PQRequest.cs
+++ b/TLSharp.Core/Auth/Step1_PQRequest.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Text;
using TLSharp.Core.MTProto;
using TLSharp.Core.MTProto.Crypto;
@@ -9,10 +10,43 @@ namespace TLSharp.Core.Auth
{
public class Step1_Response
{
+ public Step1_Response()
+ {
+ Nonce = new byte[16];
+ ServerNonce = new byte[16];
+ }
+
public byte[] Nonce { get; set; }
public byte[] ServerNonce { get; set; }
public BigInteger Pq { get; set; }
public List Fingerprints { get; set; }
+
+ public byte[] ToBytes()
+ {
+ new Random().NextBytes(Nonce);
+ const int constructorNumber = 0x05162463;
+ const int vectorConstructorNumber = 0x1cb5c415;
+
+
+ using (var memoryStream = new MemoryStream())
+ {
+ using (var binaryWriter = new BinaryWriter(memoryStream))
+ {
+ binaryWriter.Write(constructorNumber);
+ binaryWriter.Write(ServerNonce);
+ binaryWriter.Write(Nonce);
+ Serializers.Bytes.write(binaryWriter, Pq.ToByteArrayUnsigned());
+ binaryWriter.Write(vectorConstructorNumber);
+ binaryWriter.Write(Fingerprints.Count);
+ foreach (var fingerprint in Fingerprints)
+ {
+ binaryWriter.Write(fingerprint);
+ }
+
+ return memoryStream.ToArray();
+ }
+ }
+ }
}
public class Step1_PQRequest
@@ -62,7 +96,6 @@ namespace TLSharp.Core.Auth
{
throw new InvalidOperationException("invalid nonce from server");
}
-
var serverNonce = binaryReader.ReadBytes(16);
byte[] pqbytes = Serializers.Bytes.read(binaryReader);
@@ -92,5 +125,6 @@ namespace TLSharp.Core.Auth
}
}
}
+
}
}
diff --git a/TLSharp.Core/Auth/Step2_DHExchange.cs b/TLSharp.Core/Auth/Step2_DHExchange.cs
index 53b8016..0abb63c 100644
--- a/TLSharp.Core/Auth/Step2_DHExchange.cs
+++ b/TLSharp.Core/Auth/Step2_DHExchange.cs
@@ -12,6 +12,25 @@ namespace TLSharp.Core.Auth
public byte[] ServerNonce { get; set; }
public byte[] NewNonce { get; set; }
public byte[] EncryptedAnswer { get; set; }
+
+ public byte[] ToBytes()
+ {
+ const uint constructorNumber = 0xd0e8075c;
+
+ using (var memoryStream = new MemoryStream())
+ {
+ using (var binaryWriter = new BinaryWriter(memoryStream))
+ {
+ binaryWriter.Write(constructorNumber);
+ binaryWriter.Write(ServerNonce);
+ binaryWriter.Write(Nonce);
+ //binaryWriter.Write(EncryptedAnswer);
+ Serializers.Bytes.write(binaryWriter, EncryptedAnswer);
+
+ return memoryStream.ToArray();
+ }
+ }
+ }
}
public class Step2_DHExchange
@@ -48,7 +67,7 @@ namespace TLSharp.Core.Auth
foreach (byte[] fingerprint in fingerprints)
{
ciphertext = RSA.Encrypt(BitConverter.ToString(fingerprint).Replace("-", string.Empty),
- pqInnerData.GetBuffer(), 0, (int)pqInnerData.Position);
+ pqInnerData.GetBuffer(), 0, (int)pqInnerData.Position);
if (ciphertext != null)
{
targetFingerprint = fingerprint;
diff --git a/TLSharp.Core/Auth/Step3_CompleteDHExchange.cs b/TLSharp.Core/Auth/Step3_CompleteDHExchange.cs
index 8ba8f5a..c6c9a41 100644
--- a/TLSharp.Core/Auth/Step3_CompleteDHExchange.cs
+++ b/TLSharp.Core/Auth/Step3_CompleteDHExchange.cs
@@ -11,7 +11,6 @@ namespace TLSharp.Core.Auth
{
public AuthKey AuthKey { get; set; }
public int TimeOffset { get; set; }
-
}
public class Step3_CompleteDHExchange
diff --git a/TLSharp.Core/Network/MtProtoSender.cs b/TLSharp.Core/Network/MtProtoSender.cs
index 795e878..c3e1737 100644
--- a/TLSharp.Core/Network/MtProtoSender.cs
+++ b/TLSharp.Core/Network/MtProtoSender.cs
@@ -319,6 +319,10 @@ namespace TLSharp.Core.Network
{
throw new CloudPasswordNeededException("This Account has Cloud Password !");
}
+ else if (errorMessage == "MESSAGE_ID_INVALID")
+ {
+ throw new InvalidOperationException("The provided message id is invalid " + errorMessage);
+ }
else
{
throw new InvalidOperationException(errorMessage);
@@ -548,7 +552,7 @@ namespace TLSharp.Core.Network
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)
+ protected DataCenterMigrationException(string msg, int dc) : base(msg + REPORT_MESSAGE)
{
DC = dc;
}
@@ -557,7 +561,7 @@ namespace TLSharp.Core.Network
internal class PhoneMigrationException : DataCenterMigrationException
{
internal PhoneMigrationException(int dc)
- : base ($"Phone number registered to a different DC: {dc}.", dc)
+ : base($"Phone number registered to a different DC: {dc}.", dc)
{
}
}
@@ -565,7 +569,7 @@ namespace TLSharp.Core.Network
internal class FileMigrationException : DataCenterMigrationException
{
internal FileMigrationException(int dc)
- : base ($"File located on a different DC: {dc}.", dc)
+ : base($"File located on a different DC: {dc}.", dc)
{
}
}
@@ -577,7 +581,7 @@ namespace TLSharp.Core.Network
{
}
}
-
+
internal class NetworkMigrationException : DataCenterMigrationException
{
internal NetworkMigrationException(int dc)
diff --git a/TLSharp.Core/Network/TcpTransport.cs b/TLSharp.Core/Network/TcpTransport.cs
index 31bd6b4..4ba997f 100644
--- a/TLSharp.Core/Network/TcpTransport.cs
+++ b/TLSharp.Core/Network/TcpTransport.cs
@@ -1,89 +1,91 @@
-using System;
-using System.Net;
-using System.Net.Sockets;
-using System.Threading.Tasks;
-
-namespace TLSharp.Core.Network
-{
- public delegate TcpClient TcpClientConnectionHandler(string address, int port);
-
- public class TcpTransport : IDisposable
- {
- private readonly TcpClient _tcpClient;
- private int sendCounter = 0;
-
- public TcpTransport(string address, int port, TcpClientConnectionHandler handler = null)
- {
- if (handler == null)
- {
- _tcpClient = new TcpClient();
-
- var ipAddress = IPAddress.Parse(address);
- _tcpClient.Connect(ipAddress, port);
- }
- else
- _tcpClient = handler(address, port);
- }
-
- public async Task Send(byte[] packet)
- {
- if (!_tcpClient.Connected)
- throw new InvalidOperationException("Client not connected to server.");
-
- var tcpMessage = new TcpMessage(sendCounter, packet);
-
- await _tcpClient.GetStream().WriteAsync(tcpMessage.Encode(), 0, tcpMessage.Encode().Length);
- sendCounter++;
- }
-
- public async Task Receieve()
- {
- var stream = _tcpClient.GetStream();
-
- var packetLengthBytes = new byte[4];
- if (await stream.ReadAsync(packetLengthBytes, 0, 4) != 4)
- throw new InvalidOperationException("Couldn't read the packet length");
- int packetLength = BitConverter.ToInt32(packetLengthBytes, 0);
-
- var seqBytes = new byte[4];
- if (await stream.ReadAsync(seqBytes, 0, 4) != 4)
- throw new InvalidOperationException("Couldn't read the sequence");
- int seq = BitConverter.ToInt32(seqBytes, 0);
-
- int readBytes = 0;
- var body = new byte[packetLength - 12];
- int neededToRead = packetLength - 12;
-
- do
- {
- var bodyByte = new byte[packetLength - 12];
- var availableBytes = await stream.ReadAsync(bodyByte, 0, neededToRead);
- neededToRead -= availableBytes;
- Buffer.BlockCopy(bodyByte, 0, body, readBytes, availableBytes);
- readBytes += availableBytes;
- }
- while (readBytes != packetLength - 12);
-
- var crcBytes = new byte[4];
- if (await stream.ReadAsync(crcBytes, 0, 4) != 4)
- throw new InvalidOperationException("Couldn't read the crc");
- int checksum = BitConverter.ToInt32(crcBytes, 0);
-
- byte[] rv = new byte[packetLengthBytes.Length + seqBytes.Length + body.Length];
-
- Buffer.BlockCopy(packetLengthBytes, 0, rv, 0, packetLengthBytes.Length);
- Buffer.BlockCopy(seqBytes, 0, rv, packetLengthBytes.Length, seqBytes.Length);
- Buffer.BlockCopy(body, 0, rv, packetLengthBytes.Length + seqBytes.Length, body.Length);
- var crc32 = new Ionic.Crc.CRC32();
- crc32.SlurpBlock(rv, 0, rv.Length);
- var validChecksum = crc32.Crc32Result;
-
- if (checksum != validChecksum)
- {
- throw new InvalidOperationException("invalid checksum! skip");
- }
-
- return new TcpMessage(seq, body);
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading.Tasks;
+
+namespace TLSharp.Core.Network
+{
+ public delegate TcpClient TcpClientConnectionHandler(string address, int port);
+
+ public class TcpTransport : IDisposable
+ {
+ private readonly TcpClient _tcpClient;
+ private int sendCounter = 0;
+
+ public TcpTransport(string address, int port, TcpClientConnectionHandler handler = null)
+ {
+ if (handler == null)
+ {
+ _tcpClient = new TcpClient();
+
+ _tcpClient.Connect(IPAddress.Parse(address), port);
+ }
+ else
+ _tcpClient = handler(address, port);
+ }
+
+ public async Task Send(byte[] packet)
+ {
+ if (!_tcpClient.Connected)
+ throw new InvalidOperationException("Client not connected to server.");
+
+ var tcpMessage = new TcpMessage(sendCounter, packet);
+
+ await _tcpClient.GetStream().WriteAsync(tcpMessage.Encode(), 0, tcpMessage.Encode().Length);
+ sendCounter++;
+ }
+
+ public async Task Receieve()
+ {
+ if (!_tcpClient.Connected)
+ throw new InvalidOperationException("Client not connected to server.");
+
+ var stream = _tcpClient.GetStream();
+
+ var packetLengthBytes = new byte[4];
+ if (await stream.ReadAsync(packetLengthBytes, 0, 4) != 4)
+ throw new InvalidOperationException("Couldn't read the packet length");
+ int packetLength = BitConverter.ToInt32(packetLengthBytes, 0);
+
+ var seqBytes = new byte[4];
+ if (await stream.ReadAsync(seqBytes, 0, 4) != 4)
+ throw new InvalidOperationException("Couldn't read the sequence");
+ int seq = BitConverter.ToInt32(seqBytes, 0);
+
+ int readBytes = 0;
+ var body = new byte[packetLength - 12];
+ int neededToRead = packetLength - 12;
+
+ do
+ {
+ var bodyByte = new byte[packetLength - 12];
+ var availableBytes = await stream.ReadAsync(bodyByte, 0, neededToRead);
+ neededToRead -= availableBytes;
+ Buffer.BlockCopy(bodyByte, 0, body, readBytes, availableBytes);
+ readBytes += availableBytes;
+ }
+ while (readBytes != packetLength - 12);
+
+ var crcBytes = new byte[4];
+ if (await stream.ReadAsync(crcBytes, 0, 4) != 4)
+ throw new InvalidOperationException("Couldn't read the crc");
+ int checksum = BitConverter.ToInt32(crcBytes, 0);
+
+ byte[] rv = new byte[packetLengthBytes.Length + seqBytes.Length + body.Length];
+
+ Buffer.BlockCopy(packetLengthBytes, 0, rv, 0, packetLengthBytes.Length);
+ Buffer.BlockCopy(seqBytes, 0, rv, packetLengthBytes.Length, seqBytes.Length);
+ Buffer.BlockCopy(body, 0, rv, packetLengthBytes.Length + seqBytes.Length, body.Length);
+ var crc32 = new Ionic.Crc.CRC32();
+ crc32.SlurpBlock(rv, 0, rv.Length);
+ var validChecksum = crc32.Crc32Result;
+
+ if (checksum != validChecksum)
+ {
+ throw new InvalidOperationException("invalid checksum! skip");
+ }
+
+ return new TcpMessage(seq, body);
}
public bool IsConnected
@@ -95,10 +97,10 @@ namespace TLSharp.Core.Network
}
- public void Dispose()
- {
- if (_tcpClient.Connected)
- _tcpClient.Close();
+ public void Dispose()
+ {
+ if (_tcpClient.Connected)
+ _tcpClient.Close();
}
- }
-}
+ }
+}
diff --git a/TLSharp.Core/Session.cs b/TLSharp.Core/Session.cs
index 987c5d2..cb7c61e 100644
--- a/TLSharp.Core/Session.cs
+++ b/TLSharp.Core/Session.cs
@@ -54,9 +54,9 @@ namespace TLSharp.Core
public class Session
{
- private const string defaultConnectionAddress = "149.154.175.100";//"149.154.167.50";
+ private const string defaultConnectionAddress = "149.154.175.100";//"149.154.167.50";
- private const int defaultConnectionPort = 443;
+ private const int defaultConnectionPort = 443;
public string SessionUserId { get; set; }
public string ServerAddress { get; set; }
@@ -155,14 +155,14 @@ namespace TLSharp.Core
_store.Save(this);
}
- public static Session TryLoadOrCreateNew(ISessionStore store, string sessionUserId)
+ public static Session TryLoadOrCreateNew(ISessionStore store, string sessionUserId, string serverAddress = "", int? serverPort = null)
{
return store.Load(sessionUserId) ?? new Session(store)
{
Id = GenerateRandomUlong(),
SessionUserId = sessionUserId,
- ServerAddress = defaultConnectionAddress,
- Port = defaultConnectionPort
+ ServerAddress = string.IsNullOrEmpty(serverAddress) ? defaultConnectionAddress : serverAddress,
+ Port = serverPort ?? defaultConnectionPort
};
}
@@ -179,7 +179,7 @@ namespace TLSharp.Core
long newMessageId = ((time / 1000 + TimeOffset) << 32) |
((time % 1000) << 22) |
(random.Next(524288) << 2); // 2^19
- // [ unix timestamp : 32 bit] [ milliseconds : 10 bit ] [ buffer space : 1 bit ] [ random : 19 bit ] [ msg_id type : 2 bit ] = [ msg_id : 64 bit ]
+ // [ unix timestamp : 32 bit] [ milliseconds : 10 bit ] [ buffer space : 1 bit ] [ random : 19 bit ] [ msg_id type : 2 bit ] = [ msg_id : 64 bit ]
if (LastMessageId >= newMessageId)
{
diff --git a/TLSharp.Core/TelegramClient.cs b/TLSharp.Core/TelegramClient.cs
index 0692486..4cd7c9d 100644
--- a/TLSharp.Core/TelegramClient.cs
+++ b/TLSharp.Core/TelegramClient.cs
@@ -1,90 +1,90 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Security.Cryptography;
-using System.Text;
-using System.Threading.Tasks;
-using TeleSharp.TL;
-using TeleSharp.TL.Account;
-using TeleSharp.TL.Auth;
-using TeleSharp.TL.Contacts;
-using TeleSharp.TL.Help;
-using TeleSharp.TL.Messages;
-using TeleSharp.TL.Upload;
-using TLSharp.Core.Auth;
-using TLSharp.Core.MTProto.Crypto;
-using TLSharp.Core.Network;
-using TLSharp.Core.Utils;
-using TLAuthorization = TeleSharp.TL.Auth.TLAuthorization;
-
-namespace TLSharp.Core
-{
- public class TelegramClient : IDisposable
- {
- private MtProtoSender _sender;
- private AuthKey _key;
- private TcpTransport _transport;
- private string _apiHash = "";
- private int _apiId = 0;
- private Session _session;
- private List dcOptions;
- private TcpClientConnectionHandler _handler;
-
- public TelegramClient(int apiId, string apiHash,
- ISessionStore store = null, string sessionUserId = "session", TcpClientConnectionHandler handler = null)
- {
- 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;
- _handler = handler;
-
- _session = Session.TryLoadOrCreateNew(store, sessionUserId);
- _transport = new TcpTransport(_session.ServerAddress, _session.Port, _handler);
- }
-
- public async Task ConnectAsync(bool reconnect = false)
- {
- if (_session.AuthKey == null || reconnect)
- {
- var result = await Authenticator.DoAuthentication(_transport);
- _session.AuthKey = result.AuthKey;
- _session.TimeOffset = result.TimeOffset;
- }
-
- _sender = new MtProtoSender(_transport, _session);
-
- //set-up layer
- var config = new TLRequestGetConfig();
- var request = new TLRequestInitConnection()
- {
- ApiId = _apiId,
- AppVersion = "1.0.0",
- DeviceModel = "PC",
- LangCode = "en",
- Query = config,
- SystemVersion = "Win 10.0"
- };
- var invokewithLayer = new TLRequestInvokeWithLayer() { Layer = 66, Query = request };
- await _sender.Send(invokewithLayer);
- await _sender.Receive(invokewithLayer);
-
- dcOptions = ((TLConfig)invokewithLayer.Response).DcOptions.ToList();
-
- return true;
- }
-
- private async Task ReconnectToDcAsync(int dcId)
- {
- if (dcOptions == null || !dcOptions.Any())
- throw new InvalidOperationException($"Can't reconnect. Establish initial connection first.");
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+using TeleSharp.TL;
+using TeleSharp.TL.Account;
+using TeleSharp.TL.Auth;
+using TeleSharp.TL.Contacts;
+using TeleSharp.TL.Help;
+using TeleSharp.TL.Messages;
+using TeleSharp.TL.Upload;
+using TLSharp.Core.Auth;
+using TLSharp.Core.MTProto.Crypto;
+using TLSharp.Core.Network;
+using TLSharp.Core.Utils;
+using TLAuthorization = TeleSharp.TL.Auth.TLAuthorization;
+
+namespace TLSharp.Core
+{
+ public class TelegramClient : IDisposable
+ {
+ private MtProtoSender _sender;
+ private AuthKey _key;
+ private TcpTransport _transport;
+ private string _apiHash = "";
+ private int _apiId = 0;
+ private Session _session;
+ private List dcOptions;
+ private TcpClientConnectionHandler _handler;
+
+ public TelegramClient(int apiId, string apiHash,
+ ISessionStore store = null, string sessionUserId = "session", TcpClientConnectionHandler handler = null, string serverAddress = "", int? serverPort = null)
+ {
+ 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;
+ _handler = handler;
+
+ _session = Session.TryLoadOrCreateNew(store, sessionUserId, serverAddress, serverPort);
+ _transport = new TcpTransport(string.IsNullOrEmpty(serverAddress) ? _session.ServerAddress : serverAddress, serverPort ?? _session.Port, _handler);
+ }
+
+ public async Task ConnectAsync(bool reconnect = false)
+ {
+ if (_session.AuthKey == null || reconnect)
+ {
+ var result = await Authenticator.DoAuthentication(_transport);
+ _session.AuthKey = result.AuthKey;
+ _session.TimeOffset = result.TimeOffset;
+ }
+
+ _sender = new MtProtoSender(_transport, _session);
+
+ //set-up layer
+ var config = new TLRequestGetConfig();
+ var request = new TLRequestInitConnection()
+ {
+ ApiId = _apiId,
+ AppVersion = "1.0.0",
+ DeviceModel = "PC",
+ LangCode = "en",
+ Query = config,
+ SystemVersion = "Win 10.0"
+ };
+ var invokewithLayer = new TLRequestInvokeWithLayer() { Layer = 66, Query = request };
+ await _sender.Send(invokewithLayer);
+ await _sender.Receive(invokewithLayer);
+
+ dcOptions = ((TLConfig)invokewithLayer.Response).DcOptions.ToList();
+
+ return true;
+ }
+
+ private async Task ReconnectToDcAsync(int dcId)
+ {
+ if (dcOptions == null || !dcOptions.Any())
+ throw new InvalidOperationException($"Can't reconnect. Establish initial connection first.");
TLExportedAuthorization exported = null;
if (_session.TLUser != null)
@@ -92,13 +92,13 @@ namespace TLSharp.Core
TLRequestExportAuthorization exportAuthorization = new TLRequestExportAuthorization() { DcId = dcId };
exported = await SendRequestAsync(exportAuthorization);
}
-
- var dc = dcOptions.First(d => d.Id == dcId);
-
- _transport = new TcpTransport(dc.IpAddress, dc.Port, _handler);
- _session.ServerAddress = dc.IpAddress;
- _session.Port = dc.Port;
-
+
+ var dc = dcOptions.First(d => d.Id == dcId);
+
+ _transport = new TcpTransport(dc.IpAddress, dc.Port, _handler);
+ _session.ServerAddress = dc.IpAddress;
+ _session.Port = dc.Port;
+
await ConnectAsync(true);
if (_session.TLUser != null)
@@ -106,214 +106,229 @@ namespace TLSharp.Core
TLRequestImportAuthorization importAuthorization = new TLRequestImportAuthorization() { Id = exported.Id, Bytes = exported.Bytes };
var imported = await SendRequestAsync(importAuthorization);
OnUserAuthenticated(((TLUser)imported.User));
- }
- }
-
- private async Task RequestWithDcMigration(TLMethod request)
- {
- var completed = false;
- while(!completed)
- {
- try
- {
- await _sender.Send(request);
- await _sender.Receive(request);
- completed = true;
- }
- catch(DataCenterMigrationException e)
- {
- await ReconnectToDcAsync(e.DC);
- // prepare the request for another try
- request.ConfirmReceived = false;
- }
}
- }
-
- public bool IsUserAuthorized()
- {
- return _session.TLUser != null;
- }
-
- public async Task IsPhoneRegisteredAsync(string phoneNumber)
- {
- if (String.IsNullOrWhiteSpace(phoneNumber))
- throw new ArgumentNullException(nameof(phoneNumber));
-
- if (_sender == null)
- throw new InvalidOperationException("Not connected!");
-
- var authCheckPhoneRequest = new TLRequestCheckPhone() { PhoneNumber = phoneNumber };
-
- await RequestWithDcMigration(authCheckPhoneRequest);
-
- return authCheckPhoneRequest.Response.PhoneRegistered;
- }
-
- public async Task SendCodeRequestAsync(string phoneNumber)
- {
- if (String.IsNullOrWhiteSpace(phoneNumber))
- throw new ArgumentNullException(nameof(phoneNumber));
-
- var request = new TLRequestSendCode() { PhoneNumber = phoneNumber, ApiId = _apiId, ApiHash = _apiHash };
-
- await RequestWithDcMigration(request);
-
- return request.Response.PhoneCodeHash;
- }
-
- 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));
-
+ }
+
+ private async Task RequestWithDcMigration(TLMethod request)
+ {
+ var completed = false;
+ while (!completed)
+ {
+ try
+ {
+ await _sender.Send(request);
+ await _sender.Receive(request);
+ completed = true;
+ }
+ catch (DataCenterMigrationException e)
+ {
+ await ReconnectToDcAsync(e.DC);
+ // prepare the request for another try
+ request.ConfirmReceived = false;
+ }
+ }
+ }
+
+ public bool IsUserAuthorized()
+ {
+ return _session.TLUser != null;
+ }
+
+ public async Task IsPhoneRegisteredAsync(string phoneNumber)
+ {
+ if (String.IsNullOrWhiteSpace(phoneNumber))
+ throw new ArgumentNullException(nameof(phoneNumber));
+
+ if (_sender == null)
+ throw new InvalidOperationException("Not connected!");
+
+ var authCheckPhoneRequest = new TLRequestCheckPhone() { PhoneNumber = phoneNumber };
+
+ await RequestWithDcMigration(authCheckPhoneRequest);
+
+ return authCheckPhoneRequest.Response.PhoneRegistered;
+ }
+
+ public async Task SendCodeRequestAsync(string phoneNumber)
+ {
+ if (String.IsNullOrWhiteSpace(phoneNumber))
+ throw new ArgumentNullException(nameof(phoneNumber));
+
+ var request = new TLRequestSendCode() { PhoneNumber = phoneNumber, ApiId = _apiId, ApiHash = _apiHash };
+
+ await RequestWithDcMigration(request);
+
+ return request.Response.PhoneCodeHash;
+ }
+
+ 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() { PhoneNumber = phoneNumber, PhoneCodeHash = phoneCodeHash, PhoneCode = code };
- await RequestWithDcMigration(request);
-
- OnUserAuthenticated(((TLUser)request.Response.User));
-
- return ((TLUser)request.Response.User);
- }
-
- public async Task GetPasswordSetting()
- {
- var request = new TLRequestGetPassword();
-
- await RequestWithDcMigration(request);
-
- return ((TLPassword)request.Response);
- }
-
- public async Task MakeAuthWithPasswordAsync(TLPassword password, string password_str)
- {
-
- byte[] password_Bytes = Encoding.UTF8.GetBytes(password_str);
- IEnumerable rv = password.CurrentSalt.Concat(password_Bytes).Concat(password.CurrentSalt);
-
- SHA256Managed hashstring = new SHA256Managed();
- var password_hash = hashstring.ComputeHash(rv.ToArray());
-
- var request = new TLRequestCheckPassword() { PasswordHash = password_hash };
-
- await RequestWithDcMigration(request);
-
- OnUserAuthenticated(((TLUser)request.Response.User));
-
- return ((TLUser)request.Response.User);
- }
-
- public async Task SignUpAsync(string phoneNumber, string phoneCodeHash, string code, string firstName, string lastName)
- {
- var request = new TLRequestSignUp() { PhoneNumber = phoneNumber, PhoneCode = code, PhoneCodeHash = phoneCodeHash, FirstName = firstName, LastName = lastName };
-
- await RequestWithDcMigration(request);
-
- OnUserAuthenticated(((TLUser)request.Response.User));
-
- return ((TLUser)request.Response.User);
- }
- public async Task SendRequestAsync(TLMethod methodToExecute)
- {
- await RequestWithDcMigration(methodToExecute);
-
- var result = methodToExecute.GetType().GetProperty("Response").GetValue(methodToExecute);
-
- return (T)result;
- }
-
- public async Task GetContactsAsync()
- {
- if (!IsUserAuthorized())
- throw new InvalidOperationException("Authorize user first!");
-
- var req = new TLRequestGetContacts() { Hash = "" };
-
- return await SendRequestAsync(req);
- }
-
- public async Task SendMessageAsync(TLAbsInputPeer peer, string message)
- {
- if (!IsUserAuthorized())
- throw new InvalidOperationException("Authorize user first!");
-
- return await SendRequestAsync(
- new TLRequestSendMessage()
- {
- Peer = peer,
- Message = message,
- RandomId = Helpers.GenerateRandomLong()
- });
- }
-
- public async Task SendTypingAsync(TLAbsInputPeer peer)
- {
- var req = new TLRequestSetTyping()
- {
- Action = new TLSendMessageTypingAction(),
- Peer = peer
- };
- return await SendRequestAsync(req);
- }
-
- public async Task GetUserDialogsAsync()
- {
- var peer = new TLInputPeerSelf();
- return await SendRequestAsync(
- new TLRequestGetDialogs() { OffsetDate = 0, OffsetPeer = peer, Limit = 100 });
- }
-
- public async Task SendUploadedPhoto(TLAbsInputPeer peer, TLAbsInputFile file, string caption)
- {
- return await SendRequestAsync(new TLRequestSendMedia()
- {
- RandomId = Helpers.GenerateRandomLong(),
- Background = false,
- ClearDraft = false,
- Media = new TLInputMediaUploadedPhoto() { File = file, Caption = caption },
- Peer = peer
- });
- }
-
- public async Task SendUploadedDocument(
- TLAbsInputPeer peer, TLAbsInputFile file, string caption, string mimeType, TLVector attributes)
- {
- return await SendRequestAsync(new TLRequestSendMedia()
- {
- RandomId = Helpers.GenerateRandomLong(),
- Background = false,
- ClearDraft = false,
- Media = new TLInputMediaUploadedDocument()
- {
- File = file,
- Caption = caption,
- MimeType = mimeType,
- Attributes = attributes
- },
- Peer = peer
- });
- }
-
- public async Task GetFile(TLAbsInputFileLocation location, int filePartSize, int offset = 0)
- {
- TLFile result = null;
- result = await SendRequestAsync(new TLRequestGetFile()
- {
- Location = location,
- Limit = filePartSize,
- Offset = offset
- });
- return result;
- }
-
- public async Task SendPingAsync()
- {
- await _sender.SendPingAsync();
+ await RequestWithDcMigration(request);
+
+ OnUserAuthenticated(((TLUser)request.Response.User));
+
+ return ((TLUser)request.Response.User);
+ }
+
+ public async Task GetPasswordSetting()
+ {
+ var request = new TLRequestGetPassword();
+
+ await RequestWithDcMigration(request);
+
+ return ((TLPassword)request.Response);
+ }
+
+ public async Task MakeAuthWithPasswordAsync(TLPassword password, string password_str)
+ {
+
+ byte[] password_Bytes = Encoding.UTF8.GetBytes(password_str);
+ IEnumerable rv = password.CurrentSalt.Concat(password_Bytes).Concat(password.CurrentSalt);
+
+ SHA256Managed hashstring = new SHA256Managed();
+ var password_hash = hashstring.ComputeHash(rv.ToArray());
+
+ var request = new TLRequestCheckPassword() { PasswordHash = password_hash };
+
+ await RequestWithDcMigration(request);
+
+ OnUserAuthenticated(((TLUser)request.Response.User));
+
+ return ((TLUser)request.Response.User);
+ }
+
+ public async Task SignUpAsync(string phoneNumber, string phoneCodeHash, string code, string firstName, string lastName)
+ {
+ var request = new TLRequestSignUp() { PhoneNumber = phoneNumber, PhoneCode = code, PhoneCodeHash = phoneCodeHash, FirstName = firstName, LastName = lastName };
+
+ await RequestWithDcMigration(request);
+
+ OnUserAuthenticated(((TLUser)request.Response.User));
+
+ return ((TLUser)request.Response.User);
+ }
+ public async Task SendRequestAsync(TLMethod methodToExecute)
+ {
+ await RequestWithDcMigration(methodToExecute);
+
+ var result = methodToExecute.GetType().GetProperty("Response").GetValue(methodToExecute);
+
+ return (T)result;
+ }
+
+ public async Task GetContactsAsync()
+ {
+ if (!IsUserAuthorized())
+ throw new InvalidOperationException("Authorize user first!");
+
+ var req = new TLRequestGetContacts() { Hash = "" };
+
+ return await SendRequestAsync(req);
+ }
+
+ public async Task SendMessageAsync(TLAbsInputPeer peer, string message)
+ {
+ if (!IsUserAuthorized())
+ throw new InvalidOperationException("Authorize user first!");
+
+ return await SendRequestAsync(
+ new TLRequestSendMessage()
+ {
+ Peer = peer,
+ Message = message,
+ RandomId = Helpers.GenerateRandomLong()
+ });
+ }
+
+ public async Task ForwardMessageAsync(TLAbsInputPeer target, int messageId)
+ {
+ if (!IsUserAuthorized())
+ throw new InvalidOperationException("Authorize user first!");
+
+ return await SendRequestAsync(
+ new TLRequestForwardMessage()
+ {
+ Peer = target,
+ Id = messageId,
+ RandomId = Helpers.GenerateRandomLong()
+ });
+ }
+
+
+ public async Task SendTypingAsync(TLAbsInputPeer peer)
+ {
+ var req = new TLRequestSetTyping()
+ {
+ Action = new TLSendMessageTypingAction(),
+ Peer = peer
+ };
+ return await SendRequestAsync(req);
+ }
+
+ public async Task GetUserDialogsAsync()
+ {
+ var peer = new TLInputPeerSelf();
+ return await SendRequestAsync(
+ new TLRequestGetDialogs() { OffsetDate = 0, OffsetPeer = peer, Limit = 100 });
+ }
+
+ public async Task SendUploadedPhoto(TLAbsInputPeer peer, TLAbsInputFile file, string caption)
+ {
+ return await SendRequestAsync(new TLRequestSendMedia()
+ {
+ RandomId = Helpers.GenerateRandomLong(),
+ Background = false,
+ ClearDraft = false,
+ Media = new TLInputMediaUploadedPhoto() { File = file, Caption = caption },
+ Peer = peer
+ });
+ }
+
+ public async Task SendUploadedDocument(
+ TLAbsInputPeer peer, TLAbsInputFile file, string caption, string mimeType, TLVector attributes)
+ {
+ return await SendRequestAsync(new TLRequestSendMedia()
+ {
+ RandomId = Helpers.GenerateRandomLong(),
+ Background = false,
+ ClearDraft = false,
+ Media = new TLInputMediaUploadedDocument()
+ {
+ File = file,
+ Caption = caption,
+ MimeType = mimeType,
+ Attributes = attributes
+ },
+ Peer = peer
+ });
+ }
+
+ public async Task GetFile(TLAbsInputFileLocation location, int filePartSize, int offset = 0)
+ {
+ TLFile result = null;
+ result = await SendRequestAsync(new TLRequestGetFile()
+ {
+ Location = location,
+ Limit = filePartSize,
+ Offset = offset
+ });
+ return result;
+ }
+
+ public async Task SendPingAsync()
+ {
+ await _sender.SendPingAsync();
}
public async Task GetHistoryAsync(TLAbsInputPeer peer, int offset, int max_id, int limit)
@@ -329,31 +344,31 @@ namespace TLSharp.Core
Limit = limit
};
return await SendRequestAsync(req);
- }
-
- ///
- /// Serch user or chat. API: contacts.search#11f812d8 q:string limit:int = contacts.Found;
- ///
- /// User or chat name
- /// Max result count
- ///
- public async Task SearchUserAsync(string q, int limit = 10)
- {
- var r = new TeleSharp.TL.Contacts.TLRequestSearch
- {
- Q = q,
- Limit = limit
- };
-
- return await SendRequestAsync(r);
- }
-
- private void OnUserAuthenticated(TLUser TLUser)
- {
- _session.TLUser = TLUser;
- _session.SessionExpires = int.MaxValue;
-
- _session.Save();
+ }
+
+ ///
+ /// Serch user or chat. API: contacts.search#11f812d8 q:string limit:int = contacts.Found;
+ ///
+ /// User or chat name
+ /// Max result count
+ ///
+ public async Task SearchUserAsync(string q, int limit = 10)
+ {
+ var r = new TeleSharp.TL.Contacts.TLRequestSearch
+ {
+ Q = q,
+ Limit = limit
+ };
+
+ return await SendRequestAsync(r);
+ }
+
+ private void OnUserAuthenticated(TLUser TLUser)
+ {
+ _session.TLUser = TLUser;
+ _session.SessionExpires = int.MaxValue;
+
+ _session.Save();
}
public bool IsConnected
@@ -366,32 +381,32 @@ namespace TLSharp.Core
}
}
- public void Dispose()
- {
- if (_transport != null)
- {
- _transport.Dispose();
- _transport = null;
- }
- }
- }
-
- public class MissingApiConfigurationException : Exception
- {
- public const string InfoUrl = "https://github.com/sochix/TLSharp#quick-configuration";
-
- 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) { }
- }
- public class CloudPasswordNeededException : Exception
- {
- internal CloudPasswordNeededException(string msg) : base(msg) { }
- }
-}
+ public void Dispose()
+ {
+ if (_transport != null)
+ {
+ _transport.Dispose();
+ _transport = null;
+ }
+ }
+ }
+
+ public class MissingApiConfigurationException : Exception
+ {
+ public const string InfoUrl = "https://github.com/sochix/TLSharp#quick-configuration";
+
+ 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) { }
+ }
+ public class CloudPasswordNeededException : Exception
+ {
+ internal CloudPasswordNeededException(string msg) : base(msg) { }
+ }
+}
diff --git a/TLSharp.sln b/TLSharp.sln
index 4f55f1b..3e47bf8 100644
--- a/TLSharp.sln
+++ b/TLSharp.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.24720.0
+# Visual Studio 15
+VisualStudioVersion = 15.0.27004.2002
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TLSharp.Core", "TLSharp.Core\TLSharp.Core.csproj", "{400D2544-1CC6-4D8A-A62C-2292D9947A16}"
EndProject
@@ -15,6 +15,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TLSharp.Tests.VS", "TLSharp
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TLSharp.Tests.NUnit", "TLSharp.Tests.NUnit\TLSharp.Tests.NUnit.csproj", "{E90B705B-19FA-43BA-B952-69957976D12C}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Apps", "Apps", "{AECAC38E-472B-4D0A-94F7-C818DC71D3A6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClientConsoleApp", "Apps\ClientConsoleApp\ClientConsoleApp.csproj", "{15296FBD-23B9-4786-8CC0-65C872FBFDAC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TlgListenerApplication", "Apps\TlgListenerApplication\TlgListenerApplication.csproj", "{15F1CFA2-E099-48FD-97E7-BE06AA5B3EA6}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -45,6 +51,24 @@ Global
{E90B705B-19FA-43BA-B952-69957976D12C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E90B705B-19FA-43BA-B952-69957976D12C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E90B705B-19FA-43BA-B952-69957976D12C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {15296FBD-23B9-4786-8CC0-65C872FBFDAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {15296FBD-23B9-4786-8CC0-65C872FBFDAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {15296FBD-23B9-4786-8CC0-65C872FBFDAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {15296FBD-23B9-4786-8CC0-65C872FBFDAC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {15F1CFA2-E099-48FD-97E7-BE06AA5B3EA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {15F1CFA2-E099-48FD-97E7-BE06AA5B3EA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {15F1CFA2-E099-48FD-97E7-BE06AA5B3EA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {15F1CFA2-E099-48FD-97E7-BE06AA5B3EA6}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {15296FBD-23B9-4786-8CC0-65C872FBFDAC} = {AECAC38E-472B-4D0A-94F7-C818DC71D3A6}
+ {15F1CFA2-E099-48FD-97E7-BE06AA5B3EA6} = {AECAC38E-472B-4D0A-94F7-C818DC71D3A6}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {E4B0D0B6-F353-4A26-91A4-BCE2E1904E06}
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
Policies = $0
@@ -81,7 +105,4 @@ Global
$2.inheritsScope = text/x-csharp
$2.scope = text/x-csharp
EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
EndGlobal
diff --git a/TeleSharp.TL/TL/Messages/TLRequestForwardMessages.cs b/TeleSharp.TL/TL/Messages/TLRequestForwardMessages.cs
index ac85f71..ec4edf1 100644
--- a/TeleSharp.TL/TL/Messages/TLRequestForwardMessages.cs
+++ b/TeleSharp.TL/TL/Messages/TLRequestForwardMessages.cs
@@ -7,6 +7,76 @@ using System.Threading.Tasks;
using TeleSharp.TL;
namespace TeleSharp.TL.Messages
{
+ //[TLObject(0x708e0195)]
+ //public class TLRequestForwardMessages : TLMethod
+ //{
+ // // Methods
+ // public void ComputeFlags()
+ // {
+ // this.flags = 0;
+ // this.flags = this.silent ? (this.flags | 0x20) : (this.flags & -33);
+ // this.flags = this.background ? (this.flags | 0x40) : (this.flags & -65);
+ // this.flags = this.with_my_score ? (this.flags | 0x100) : (this.flags & -257);
+ // }
+
+ // public override void DeserializeBody(BinaryReader br)
+ // {
+ // this.flags = br.ReadInt32();
+ // this.silent = (this.flags & 0x20) > 0;
+ // this.background = (this.flags & 0x40) > 0;
+ // this.with_my_score = (this.flags & 0x100) > 0;
+ // this.from_peer = (TLAbsInputPeer)ObjectUtils.DeserializeObject(br);
+ // this.id = ObjectUtils.DeserializeVector(br);
+ // this.random_id = ObjectUtils.DeserializeVector(br);
+ // this.to_peer = (TLAbsInputPeer)ObjectUtils.DeserializeObject(br);
+ // }
+
+ // public override void DeserializeResponse(BinaryReader br)
+ // {
+ // this.Response = (TLAbsUpdates)ObjectUtils.DeserializeObject(br);
+ // }
+
+ // public override void SerializeBody(BinaryWriter bw)
+ // {
+ // bw.Write(this.Constructor);
+ // this.ComputeFlags();
+ // bw.Write(this.flags);
+ // ObjectUtils.SerializeObject(this.from_peer, bw);
+ // ObjectUtils.SerializeObject(this.id, bw);
+ // ObjectUtils.SerializeObject(this.random_id, bw);
+ // ObjectUtils.SerializeObject(this.to_peer, bw);
+ // }
+
+ // // Properties
+ // public bool background { get; set; }
+
+ // public override int Constructor
+ // {
+ // get
+ // {
+ // return 0x708e0195;
+ // }
+ // }
+
+ // public int flags { get; set; }
+
+ // public TLAbsInputPeer from_peer { get; set; }
+
+ // public TLVector id { get; set; }
+
+ // public TLVector random_id { get; set; }
+
+ // public TLAbsUpdates Response { get; set; }
+
+ // public bool silent { get; set; }
+
+ // public TLAbsInputPeer to_peer { get; set; }
+
+ // public bool with_my_score { get; set; }
+ //}
+
+
+
[TLObject(1888354709)]
public class TLRequestForwardMessages : TLMethod
{