diff --git a/Connection forwarder/Connection forwarder.csproj b/Connection forwarder/Connection forwarder.csproj index f84b844..c7faae0 100644 --- a/Connection forwarder/Connection forwarder.csproj +++ b/Connection forwarder/Connection forwarder.csproj @@ -35,6 +35,9 @@ ..\..\..\..\..\Downloads\Cyotek.Data.Nbt-master\Cyotek.Data.Nbt-master\Cyotek.Data.Nbt\bin\Debug\Cyotek.Data.Nbt.dll + + ..\..\..\..\..\Downloads\Nito.Async.1.4\Nito.Async.dll + diff --git a/Connection forwarder/ConnectionThread.cs b/Connection forwarder/ConnectionThread.cs index c92db77..e1d23c9 100644 --- a/Connection forwarder/ConnectionThread.cs +++ b/Connection forwarder/ConnectionThread.cs @@ -6,84 +6,72 @@ using System.Text; using System.Threading.Tasks; using Cyotek.Data.Nbt; using System.Threading; +using System.Net; namespace Connection_forwarder { class ClientConnectionThread { - public void Run(object sckt) + public Int64 ClientID; + public bool DataChanged = false; + public byte[] DataBuffer; + public void Run(object obj) { - Thread.CurrentThread.Name = "ConnectionThread"; - Form1.Threads.Add(Thread.CurrentThread); - //var connsocket = ((Socket[])sckt)[0]; - object connsocket; - if (!Form1.PEVersion) - connsocket = ((object[])sckt)[0] as Socket; - else - connsocket = ((UdpClient)((object[])sckt)[0]); - //var serversock = new Socket(SocketType.Stream, ProtocolType.Tcp); - //serversock.Connect("localhost", Form1.PortNumber); - //while (connsocket.Available > 0) - var serversock = ((Socket)((object[])sckt)[1]); - //new NetworkStream(connsocket).CopyToAsync(new NetworkStream(serversock)); - //new NetworkStream(serversock).CopyTo(new NetworkStream(connsocket)); - if (!Form1.PEVersion) + Thread.CurrentThread.Name = "ClientConnectionThread"; + //Form1.Threads.Add(Thread.CurrentThread); + //IPEndPoint RemoteIP = (IPEndPoint)remip; + IPEndPoint RemoteIP = (IPEndPoint)((object[])obj)[0]; + UdpClient connection = (UdpClient)((object[])obj)[1]; + ClientID = (Int64)((object[])obj)[2]; + //Program.ConnThreads.Add(ClientID, new object[] { Thread.CurrentThread, this }); //Remove it over time + Program.ConnThreads.Add(RemoteIP, new object[] { Thread.CurrentThread, this }); //Remove it over time + //UdpClient listenclient; + //byte[] buffer; + //bool brvar = false; + //UdpClient sendsocket; + var lasttick = Environment.TickCount; + while (Environment.TickCount - lasttick < 60 * 1000) { - try - { - new NetworkStream(connsocket as Socket).CopyTo(new NetworkStream(serversock)); + if (DataChanged) + { //Now DataBuffer contains the received packet + Console.WriteLine("Data changed..."); + Console.WriteLine("PacketID: 0x{0:X}", DataBuffer[0]); + lasttick = Environment.TickCount; + DataChanged = false; //Finished working } - catch { } - (connsocket as Socket).Close(); - serversock.Close(); - } - else - { - + /*do + { + //new PEPackets(PEPackets.TOCLIENT_LoginStatusPacket, new object[] { 0 }, sendsocket, RemoteIP); + + //connsocket[1] = new Socket(SocketType.Stream, ProtocolType.Tcp); //We still need to connect to the server + //((Socket)connsocket[1]).Connect("localhost", Form1.PortNumber); + + //After login loop to receive all messages + } while (false);*/ } + Program.ConnThreads.Remove(RemoteIP); + } + /*private bool done = false; + void saea_Completed(object sender, SocketAsyncEventArgs e) + { + done = true; + }*/ + public void SendData(object data) + { + } } class ServerConnectionThread { public void Run(object sckt) { - Thread.CurrentThread.Name = "ConnectionThread"; - Form1.Threads.Add(Thread.CurrentThread); - object connsocket; - if (!Form1.PEVersion) - connsocket = ((object[])sckt)[0] as Socket; - else - connsocket = ((UdpClient)((object[])sckt)[0]); - //var serversock = new Socket(SocketType.Stream, ProtocolType.Tcp); - //serversock.Connect("localhost", Form1.PortNumber); - //while (connsocket.Available > 0) + Thread.CurrentThread.Name = "ServerConnectionThread"; + //Form1.Threads.Add(Thread.CurrentThread); + /*object connsocket; + connsocket = ((UdpClient)((object[])sckt)[0]); var serversock = ((Socket)((object[])sckt)[1]); - //new NetworkStream(connsocket).CopyToAsync(new NetworkStream(serversock)); - try - { - if (!Form1.PEVersion) - new NetworkStream(serversock).CopyTo(new NetworkStream(connsocket as Socket)); - - /*var nsc = new NetworkStream(connsocket); - var nss = new NetworkStream(serversock); - var tr = new BinaryTagReader(nss, NbtOptions.None); - var tw = new BinaryTagWriter(nsc, NbtOptions.None); - byte[] ba; - while (!tr.ReadString().Contains("Blocks")) - { - nss.CopyTo(nsc); - } - ba = tr.ReadByteArray(); - Console.WriteLine("Byte array: " + ba); - for (int i = 0; i < ba.Length; i++) - tw.Write(ba[i]);*/ - } - catch - { - - } (connsocket as Socket).Close(); - serversock.Close(); + serversock.Close();*/ } } } diff --git a/Connection forwarder/Form1.cs b/Connection forwarder/Form1.cs index 49ff76e..2724e25 100644 --- a/Connection forwarder/Form1.cs +++ b/Connection forwarder/Form1.cs @@ -17,19 +17,18 @@ namespace Connection_forwarder { public static int PortNumber; public static int PortNumber2; - public static bool PEVersion; - public static List Threads = new List(); + //public static bool PEVersion; + //public static List Threads = new List(); public Form1() { InitializeComponent(); - Threads.Add(Thread.CurrentThread); + //Threads.Add(Thread.CurrentThread); } private void startbtn_Click(object sender, EventArgs e) { var s = new Socket(SocketType.Stream, ProtocolType.Tcp); - //s.Connect("localhost", Int32.Parse(portBox.Text)); s.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), Int32.Parse(portBox.Text))); s.Listen(2); s = s.Accept(); @@ -45,25 +44,13 @@ namespace Connection_forwarder { PortNumber = Int32.Parse(portBox.Text); PortNumber2 = Int32.Parse(portBox2.Text); - PEVersion = radioButton2.Checked; + //PEVersion = radioButton2.Checked; new Thread(new ThreadStart(ListenThread.Run)).Start(); startforwardbtn.Enabled = false; } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { - /*for (int i = 1; i < Threads.Count; i++) //For a fairly long time it stopped itself, now it skips that... - { - try - { - Threads[i].Abort(); - } - catch - { - } - } - Application.Exit(); - Application.ExitThread();*/ Environment.Exit(0); } } diff --git a/Connection forwarder/ListenThread.cs b/Connection forwarder/ListenThread.cs index b84b01c..034e38d 100644 --- a/Connection forwarder/ListenThread.cs +++ b/Connection forwarder/ListenThread.cs @@ -1,4 +1,5 @@ -using System; +using Nito.Async; +using System; using System.Collections.Generic; using System.Linq; using System.Net; @@ -14,174 +15,178 @@ namespace Connection_forwarder public static void Run() { Thread.CurrentThread.Name = "ListenThread"; - Form1.Threads.Add(Thread.CurrentThread); - Socket listensocket; - //UdpClient listenclient = new UdpClient(Form1.PortNumber2); - UdpClient listenclient; - if (!Form1.PEVersion) - { - //var listensocket = new Socket(SocketType.Stream, ProtocolType.Tcp); - listensocket = new Socket(SocketType.Stream, ProtocolType.Tcp); - listensocket.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), Form1.PortNumber2)); - } - else - { - listensocket = new Socket(SocketType.Dgram, ProtocolType.Udp); //Just for it to not give "no object" error - //listensocket.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), Form1.PortNumber2)); - //listensocket.Bind(new IPEndPoint(Program.GetLocalIP(), Form1.PortNumber2)); - } + //Form1.Threads.Add(Thread.CurrentThread); + UdpClient connection; + var RemoteIP = new IPEndPoint(IPAddress.Any, Form1.PortNumber2); + connection = new UdpClient(Form1.PortNumber2); while (true) { - if (!Form1.PEVersion) - { - listensocket.Listen(10); - //var connsocket = listensocket.Accept(); - Socket[] connsocket = new Socket[2]; - connsocket[0] = listensocket.Accept(); - connsocket[1] = new Socket(SocketType.Stream, ProtocolType.Tcp); - connsocket[1].Connect("localhost", Form1.PortNumber); - new Thread(new ParameterizedThreadStart(new ClientConnectionThread().Run)).Start(connsocket); - new Thread(new ParameterizedThreadStart(new ServerConnectionThread().Run)).Start(connsocket); - } - else + /* + * PE connection: + * When player joins start a thread and open connection to server + * When player leaves or times out disconnect from the server with matching data sent + * + * So basically handle the PE join here to know when to start a new thread + */ + + do { + //connection.Connect(new IPEndPoint(IPAddress.Any, Form1.PortNumber2)); + byte[] buffer; + buffer = connection.Receive(ref RemoteIP); //Receive the packet ID to determine IP /* - * PE connection: - * When player joins start a thread and open connection to server - * When player leaves or times out disconnect from the server with matching data sent + * Or receive all data and send it to the matching ConnectionThread determined by Client ID * - * So basically handle the PE join here to know when to start a new thread + * Actually the Client ID is not used later on... + * So determine IP every time and send the packet to matching thread + */ + //connection.Connect(RemoteIP); + //connection.Send(buffer, buffer.Length); + //connection.Close(); + //if (Program.ConnThreads.ContainsKey(RemoteIP)) + //if (Program.ConnThreads.ContainsKey(PEPackets.GetClientID(buffer))) + //break; //Let the ConnectionThread handle the request - By detecting packet type... + + bool brvar = false; + //Int64 cid; + Console.WriteLine("Received packet: 0x{0:X}", buffer[0]); + //if (buffer[0] != PEPackets.TOSERVER_ID_OPEN_CONNECTION_REQUEST_1 && Program.ConnThreads.ContainsKey(cid = PEPackets.GetClientID(buffer))) + if (buffer[0] != PEPackets.TOSERVER_ID_OPEN_CONNECTION_REQUEST_1 && Program.ConnThreads.ContainsKey(RemoteIP)) + { + //Handle packets and send data to matching thread + //(new Task(((ClientConnectionThread)Program.ConnThreads[cid][1]).SendData, buffer)).Start(new LimitedConcurrencyLevelTaskScheduler(1)); + //new ListenThread().MemberwiseClone(); + while (((ClientConnectionThread)Program.ConnThreads[RemoteIP][1]).DataChanged) + ; //Wait until thread finishes + ((ClientConnectionThread)Program.ConnThreads[RemoteIP][1]).DataBuffer = buffer; + ((ClientConnectionThread)Program.ConnThreads[RemoteIP][1]).DataChanged = true; + break; + } + else if (buffer[0] != PEPackets.TOSERVER_ID_OPEN_CONNECTION_REQUEST_1) + break; + for (int i = 0; i < PEPackets.MAGIC.Length; i++) + { + if (buffer[i + 1] != PEPackets.MAGIC[i]) + { + Console.WriteLine("There is no magic for this client..."); + brvar = true; + break; + } + } + if (brvar) + break; + Console.WriteLine("Magic accepted."); + //var sendsocket = new UdpClient(Form1.PortNumber2); + //sendsocket.EnableBroadcast = true; + connection.Connect(RemoteIP); //Make it only communicate with the currently joining player + if (buffer[PEPackets.MAGIC.Length + 1] != PEPackets.ProtocolVer) + { + new PEPackets(PEPackets.TOCLIENT_ID_INCOMPATIBLE_PROTOCOL_VERSION, new object[] { PEPackets.ProtocolVer, PEPackets.MAGIC, 0x00000000372cdc9e }, connection, RemoteIP); //ID_INCOMPATIBLE_PROTOCOL_VERSION (0x1A) + break; + } + new PEPackets(PEPackets.TOCLIENT_ID_OPEN_CONNECTION_REPLY_1, new object[] { PEPackets.MAGIC, 0x00000000372cdc9e, 0, 1447 }, connection, RemoteIP); + //sendsocket.Close(); + Console.WriteLine("Open connection 1 succeed."); + + /* + * We must handle the open connection 2 here in order to obtain ClientID */ - //byte[] buffer = new byte[1500]; - byte[] buffer; - var RemoteIP=new IPEndPoint(IPAddress.Any, Form1.PortNumber2); - listenclient = new UdpClient(Form1.PortNumber2); - buffer = listenclient.Receive(ref RemoteIP); - listenclient.Close(); - //RemoteIP.Port = 19132; - //Console.WriteLine(String.Format("Hex: %x", buffer[0])); - //Console.WriteLine("Hex: {0:X}", buffer[0]); - //bool stop = false; + buffer = connection.Receive(ref RemoteIP); + Console.WriteLine("Received packet: " + buffer[0]); + if (buffer[0] != PEPackets.TOSERVER_ID_OPEN_CONNECTION_REQUEST_2) + break; + for (int i = 0; i < PEPackets.MAGIC.Length; i++) + { + if (buffer[i + 1] != PEPackets.MAGIC[i]) + { + Console.WriteLine("There is no magic for this client..."); + brvar = true; + break; + } + } + if (brvar) + break; + byte[] bufferPart = new byte[5]; + Console.WriteLine("Extracting data..."); + Array.Copy(buffer, PEPackets.MAGIC.Length + 1, bufferPart, 0, 5); + for (int i = 0; i < bufferPart.Length; i++) + { + if (bufferPart[i] != 0x00) + { + brvar = true; + break; + } + } + if (brvar) + break; + Array.Copy(buffer, PEPackets.MAGIC.Length + 6, bufferPart = new byte[2], 0, 2); + short ServerPortFromClient = BitConverter.ToInt16(bufferPart, 0); + Console.WriteLine("ServerPortFromClient: " + ServerPortFromClient); + Array.Copy(buffer, PEPackets.MAGIC.Length + 8, bufferPart, 0, 2); + short MTUSize = BitConverter.ToInt16(bufferPart, 0); + Console.WriteLine("MTUSize: " + MTUSize); + Array.Copy(buffer, PEPackets.MAGIC.Length + 10, bufferPart = new byte[8], 0, 8); + long ClientID = BitConverter.ToInt64(bufferPart, 0); + Console.WriteLine("ClientID: " + ClientID); + //sendsocket = new UdpClient(Form1.PortNumber2); + //sendsocket.Connect(RemoteIP); + new PEPackets(PEPackets.TOCLIENT_ID_OPEN_CONNECTION_REPLY_2, new object[] { PEPackets.MAGIC, 0x00000000372cdc9e, Form1.PortNumber2, 1464, 0 }, connection, RemoteIP); + //sendsocket.Close(); + + //listenclient = new UdpClient(Form1.PortNumber2); + //buffer = listenclient.Receive(ref RemoteIP); + buffer = connection.Receive(ref RemoteIP); + //Console.WriteLine("Received: 0x{0:X}", buffer[0]); + //Console.WriteLine("Second byte: 0x{0:X}", buffer[1]); + //listenclient.Close(); + while (buffer[0] != 0x84) + { //Send NACK back + Console.WriteLine("Received packet: 0x{0:X}", buffer[0]); + Console.WriteLine("Incorrect packet. Resending..."); + var tmpreta = PEPackets.DecodeDataPacket(buffer); + if (tmpreta == null) + break; + byte[] Counta = PEPackets.IntTo3Byte((int)tmpreta[1]); + //new PEPackets(0xA0, new object[] { (short)1, true, 0x84 }, connection, RemoteIP); + new PEPackets(0xA0, new object[] { (short)1, true, Counta }, connection, RemoteIP); + buffer = connection.Receive(ref RemoteIP); + } + /* + * Custom packet 0x84: + * Count field (3 bytes) and then data payload: + * Encapsulation ID (1 byte) (=0x00) and then length then data packet: + * Status (1 byte/8 bits) + */ + //var tmp = BitConverter.GetBytes(0x84).ToList(); + //Console.WriteLine("Remove 1st byte from: " + tmp[0] + ", " + tmp[1] + ", " + tmp[2] + ", " + tmp[3]); + //tmp.RemoveAt(3); //We only need 3 bytes + //new PEPackets(0xC0, new object[] { (short)1, true, tmp.ToArray() }, connection, RemoteIP); //Send ACK + var lasttick = Environment.TickCount; do { - bool brvar = false; - if (buffer[0] != PEPackets.TOSERVER_ID_OPEN_CONNECTION_REQUEST_1) + var tmpret = PEPackets.DecodeDataPacket(buffer); + if (tmpret == null) break; - for (int i = 0; i < PEPackets.MAGIC.Length; i++) - { - if (buffer[i + 1] != PEPackets.MAGIC[i]) - { - Console.WriteLine("There is no magic for this client..."); - brvar = true; - break; - } - } - if (brvar) - break; - Console.WriteLine("Magic accepted."); - //var sendsocket = new Socket(SocketType.Dgram, ProtocolType.Udp); - var sendsocket = new UdpClient(Form1.PortNumber2); - //sendsocket.Connect(RemoteIP); - sendsocket.EnableBroadcast = true; - //sendsocket.Connect(IPAddress.Broadcast, RemoteIP.Port); - sendsocket.Connect(RemoteIP); - if (buffer[PEPackets.MAGIC.Length + 1] != PEPackets.ProtocolVer) - { - new PEPackets(PEPackets.TOCLIENT_ID_INCOMPATIBLE_PROTOCOL_VERSION, new object[] { PEPackets.ProtocolVer, PEPackets.MAGIC, 0x00000000372cdc9e }, sendsocket, RemoteIP); //ID_INCOMPATIBLE_PROTOCOL_VERSION (0x1A) - break; - } - new PEPackets(PEPackets.TOCLIENT_ID_OPEN_CONNECTION_REPLY_1, new object[] { PEPackets.MAGIC, 0x00000000372cdc9e, 0, 1447 }, sendsocket, RemoteIP); - sendsocket.Close(); - Console.WriteLine("Open connection 1 succeed."); + Console.WriteLine("Count: " + (int)tmpret[1]); + Console.WriteLine("EncapsulationID: " + tmpret[0]); + Console.WriteLine("Count2: " + tmpret[3]); + byte[] Count = PEPackets.IntTo3Byte((int)tmpret[1]); + Console.WriteLine("Count 1st byte: " + Count[0]); + new PEPackets(0xC0, new object[] { (short)1, true, Count }, connection, RemoteIP); + } while ((buffer = connection.Receive(ref RemoteIP))[0] == 0x84 && Environment.TickCount - lasttick < 6000 * 1000); + //----------------------------- + var threadvar = new Object[3]; - listenclient = new UdpClient(Form1.PortNumber2); - buffer = listenclient.Receive(ref RemoteIP); - listenclient.Close(); - //RemoteIP.Port = 19132; - if (buffer[0] != PEPackets.TOSERVER_ID_OPEN_CONNECTION_REQUEST_2) - break; - brvar = false; - for (int i = 0; i < PEPackets.MAGIC.Length; i++) - { - if (buffer[i + 1] != PEPackets.MAGIC[i]) - { - Console.WriteLine("There is no magic for this client..."); - brvar = true; - break; - } - } - if (brvar) - break; - byte[] bufferPart = new byte[5]; - Array.Copy(buffer, PEPackets.MAGIC.Length + 1, bufferPart, 0, 5); - //if (bufferPart != BitConverter.GetBytes(0x043f57fefd)) - for (int i = 0; i < bufferPart.Length; i++) - { - if (bufferPart[i] != 0x00) - { - brvar = true; - break; - } - } - if (brvar) - break; - Array.Copy(buffer, PEPackets.MAGIC.Length + 6, bufferPart = new byte[2], 0, 2); - //if (bufferPart != BitConverter.GetBytes((short)19132)) - //var bytes = BitConverter.GetBytes((short)19132); - /*for (int i = 0; i < 2; i++) - { - if (bufferPart[i] != bytes[i]) - { - brvar = true; - break; - } - } - if (brvar) - break;*/ - short ServerPortFromClient = BitConverter.ToInt16(bufferPart, 0); - Console.WriteLine("ServerPortFromClient: " + ServerPortFromClient); - Array.Copy(buffer, PEPackets.MAGIC.Length + 8, bufferPart, 0, 2); - //if (bufferPart != BitConverter.GetBytes((short)1464)) - short MTUSize = BitConverter.ToInt16(bufferPart, 0); - Console.WriteLine("MTUSize: " + MTUSize); - Array.Copy(buffer, PEPackets.MAGIC.Length + 10, bufferPart = new byte[8], 0, 8); - //long ClientID = Convert.ToInt64(bufferPart); - long ClientID = BitConverter.ToInt64(bufferPart, 0); - Console.WriteLine("ClientID: " + ClientID); - sendsocket = new UdpClient(Form1.PortNumber2); - //sendsocket.EnableBroadcast = true; - sendsocket.Connect(RemoteIP); - new PEPackets(PEPackets.TOCLIENT_ID_OPEN_CONNECTION_REPLY_2, new object[] { PEPackets.MAGIC, 0x00000000372cdc9e, Form1.PortNumber2, 1464, 0 }, sendsocket, RemoteIP); - sendsocket.Close(); - - listenclient = new UdpClient(Form1.PortNumber2); - buffer = listenclient.Receive(ref RemoteIP); - Console.WriteLine("Received: 0x{0:X}", buffer[0]); - Console.WriteLine("Second byte: 0x{0:X}", buffer[1]); - listenclient.Close(); - - sendsocket = new UdpClient(Form1.PortNumber2); - //sendsocket.EnableBroadcast = true; - sendsocket.Connect(RemoteIP); - new PEPackets(PEPackets.TOCLIENT_LoginStatusPacket, new object[] { 0 }, sendsocket, RemoteIP); - sendsocket.Close(); - //----------------------------- - /*object[] connsocket = new object[2]; - //if(buffer[0]==PEPackets) - connsocket[0] = listenclient; - connsocket[1] = new Socket(SocketType.Stream, ProtocolType.Tcp); //We still need to connect to the server - ((Socket)connsocket[1]).Connect("localhost", Form1.PortNumber); - new Thread(new ParameterizedThreadStart(new ClientConnectionThread().Run)).Start(connsocket); - new Thread(new ParameterizedThreadStart(new ServerConnectionThread().Run)).Start(connsocket);*/ - } while (false); - } - //for (int i = 0; i < 2; i++) - //new Thread(new ParameterizedThreadStart(new ClientConnectionThread().Run)).Start(connsocket); - //var serversock = new Socket(SocketType.Stream, ProtocolType.Tcp); - //serversock.Connect("localhost", Form1.PortNumber); - //new Thread(new ParameterizedThreadStart(new ServerConnectionThread().Run)).Start(serversock); - //new Thread(new ParameterizedThreadStart(new ServerConnectionThread().Run)).Start(connsocket); + connection.Close(); + connection = new UdpClient(Form1.PortNumber2); + threadvar[0] = RemoteIP; + threadvar[1] = connection; + threadvar[2] = ClientID; + new Thread(new ParameterizedThreadStart(new ClientConnectionThread().Run)).Start(threadvar); + //new Thread(new ParameterizedThreadStart(new ServerConnectionThread().Run)).Start(threadvar); + //new ActionThread().Do(new ClientConnectionThread().Run(threadvar)); + } while (false); } } } diff --git a/Connection forwarder/PCPackets.cs b/Connection forwarder/PCPackets.cs index d2bf118..1ec7a6e 100644 --- a/Connection forwarder/PCPackets.cs +++ b/Connection forwarder/PCPackets.cs @@ -9,8 +9,6 @@ namespace Connection_forwarder { class PCPackets { - //public static List Packets = new List(); - //public static readonly Dictionary PacketNames = new Dictionary(); /* http://wiki.vg/Pre-release_protocol */ /// /// Gamemode Unsigned Byte 0: survival, 1: creative, 2: adventure. Bit 3 (0x8) is the hardcore flag @@ -139,13 +137,6 @@ namespace Connection_forwarder public PCPackets(byte packetid, object[] data, Socket sock) { - //Prepare all possible packets - //Packets.Add(new PCPacket(0x02, "Chat")); - //Packets[0].Function = Packets[0].Callback; - /*Packets[0].Function = delegate(object[] asd) - { - return; - };*/ var tmp=new List(); tmp.Add(packetid); for(int i=0; i @@ -50,7 +47,9 @@ namespace Connection_forwarder { if (!data[i].GetType().IsSubclassOf(typeof(Array))) { - if (data[i].GetType() == typeof(bool)) + if (data[i].GetType() == typeof(byte)) + tmp.Add((byte)data[i]); + else if (data[i].GetType() == typeof(bool)) tmp.AddRange(BitConverter.GetBytes((bool)data[i])); else if (data[i].GetType() == typeof(char)) tmp.AddRange(BitConverter.GetBytes((char)data[i])); @@ -70,14 +69,14 @@ namespace Connection_forwarder tmp.AddRange(BitConverter.GetBytes((ushort)data[i])); else if (data[i].GetType() == typeof(ushort)) tmp.AddRange(BitConverter.GetBytes((ushort)data[i])); - else if (data[i].GetType() == typeof(byte)) - tmp.Add((byte)data[i]); } else { for (int j = 0; j < ((Array)data[i]).Length; j++) { - if (((Array)data[i]).GetValue(j).GetType() == typeof(bool)) + if (((Array)data[i]).GetValue(j).GetType() == typeof(byte)) + tmp.Add((byte)((Array)data[i]).GetValue(j)); + else if (((Array)data[i]).GetValue(j).GetType() == typeof(bool)) tmp.AddRange(BitConverter.GetBytes((bool)((Array)data[i]).GetValue(j))); else if (((Array)data[i]).GetValue(j).GetType() == typeof(char)) tmp.AddRange(BitConverter.GetBytes((char)((Array)data[i]).GetValue(j))); @@ -97,23 +96,73 @@ namespace Connection_forwarder tmp.AddRange(BitConverter.GetBytes((ushort)((Array)data[i]).GetValue(j))); else if (((Array)data[i]).GetValue(j).GetType() == typeof(ushort)) tmp.AddRange(BitConverter.GetBytes((ushort)((Array)data[i]).GetValue(j))); - else if (((Array)data[i]).GetValue(j).GetType() == typeof(byte)) - tmp.Add((byte)((Array)data[i]).GetValue(j)); else Console.WriteLine("Unknown type in array: " + ((Array)data[i]).GetValue(j).GetType()); } } } - //sock.Send(tmp.ToArray()); - //sock.SendTo(tmp.ToArray(), ep); - //sock.Send(tmp.ToArray(), tmp.Count, ep); - sock.Send(tmp.ToArray(), tmp.Count); + try + { + sock.Send(tmp.ToArray(), tmp.Count, ep); + } + catch + { + sock.Send(tmp.ToArray(), tmp.Count); + } + } + + internal static Int64 GetClientID(byte[] buffer) + { //ClientID is in open connection request 2 and in data packets + switch(buffer[0]) + { + case 0x84: + byte[] tmp = new byte[8]; + Array.Copy(buffer, 17, tmp, 0, 8); + return BitConverter.ToInt64(tmp, 0); + default: + Console.WriteLine("Unable to get ClientID: " + buffer); + return 0; + } + } + public static object[] DecodeDataPacket(byte[] data) + { + byte[] tmp; + //Array.Copy(data, 1, tmp = new byte[4], 1, 3); //Leave the first byte 0 so it will (hopefully) give the correct 4-bit representation + Array.Copy(data, 1, tmp = new byte[4], 0, 3); //Nope, it starts at the first byte + int Count = BitConverter.ToInt32(tmp, 0); + byte EncapsulationID = data[4]; + short length; + int Count2; + int Unknown; + switch(EncapsulationID) + { + case 0x00: + length = BitConverter.ToInt16(data, 5); + Array.Copy(data, 7, tmp=new byte[data.Length-8], 0, data.Length-8); //7. byte: data +1 + return new object[] { EncapsulationID, Count, length, tmp }; + case 0x40: + length = BitConverter.ToInt16(data, 5); + Array.Copy(data, 7, tmp = new byte[4], 0, 3); //7. byte: Count(?) + Count2 = BitConverter.ToInt32(tmp, 0); + Array.Copy(data, 10, tmp=new byte[data.Length-11], 0, data.Length - 11); //10. byte: data + Count +1 + return new object[] { EncapsulationID, Count, length, Count2, tmp }; + case 0x60: + length = BitConverter.ToInt16(data, 5); + Array.Copy(data, 7, tmp = new byte[4], 0, 3); //7. byte: Count(?) + Count2 = BitConverter.ToInt32(tmp, 0); + Unknown = BitConverter.ToInt32(data, 10); //10. byte: Unknown + Array.Copy(data, 14, tmp=new byte[data.Length-15], 0, data.Length - 15); //14. byte: data +1 + return new object[] { EncapsulationID, Count, length, Count2, tmp }; + default: + return null; + } + } + public static byte[] IntTo3Byte(int i) + { + byte[] tmp = BitConverter.GetBytes(i); + byte[] ret = new byte[3]; + //Array.Copy(tmp, 1, ret, 0, 3); + Array.Copy(tmp, 0, ret, 0, 3); + return ret; } } - /*class MAGIC - { - public static implicit operator MAGIC(byte[] c) - { - return (MAGIC)c; - } - }*/ } diff --git a/Connection forwarder/Program.cs b/Connection forwarder/Program.cs index 3cc72bf..e3eeb33 100644 --- a/Connection forwarder/Program.cs +++ b/Connection forwarder/Program.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; +using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; @@ -29,11 +30,15 @@ namespace Connection_forwarder { if (ip.AddressFamily == AddressFamily.InterNetwork) { - //localIP = ip.ToString(); localIP = ip; } } return localIP; } + /// + //// Int64: ClientID + /// IP + /// + public static Dictionary ConnThreads = new Dictionary(); } }