private void Background() { var stopTask = task.Task; while (running) { var clientTask = listener.AcceptTcpClientAsync(); if (Task.WaitAny(stopTask, clientTask) == 0) { task = null; return; } var client = clientTask.Result; Task.Run(() => { try { var stream = client.GetStream(); var sel = new PacketSelector(stream); sel.Catch(); if (sel.ID != 0) { return; } var endPoint = (IPEndPoint)client.Client.RemoteEndPoint; var handshake = new HandshakePacket(sel); ServerShadow server; if (servers.ContainsKey(handshake.Address)) { server = servers[handshake.Address]; } else { server = standard; } server.NewConnetcion(handshake, endPoint, stopTask); stream.Close(); } catch (Exception exception) { Log.WriteWarn(exception.Message); } finally { client.Close(); } }); } }
public void NewConnetcion(HandshakePacket handshake, IPEndPoint endPoint, Task stopTask) { var stream = handshake.Stream; Task connection = null; TcpClient client = null; if (destination != null) { client = new TcpClient(); try { connection = client.ConnectAsync(destination.Address, destination.Port); } catch (Exception) { connection = null; } } var parser = new ParameterParser(new KeyValuePair <string, IParameterGroup>[] { new KeyValuePair <string, IParameterGroup>("hs", handshake), new KeyValuePair <string, IParameterGroup>("main", MainGroup.Instance), new KeyValuePair <string, IParameterGroup>("file", FileGroup.Instance), new KeyValuePair <string, IParameterGroup>("env", EnvGroup.Instance), new KeyValuePair <string, IParameterGroup>("sets", setsGroup) }); if (connection != null) { try { connection.Wait(); var realStream = client.GetStream(); handshake.Port = (ushort)destination.Port; handshake.Send(realStream); if (handshake.State == 2) { var loginPacket = new LoginStartPacket(stream); loginPacket.Send(realStream); log.WriteInfo($"Player '{loginPacket.PlayerName}' successfully login from {endPoint} to {record.Mask}."); } Task task1 = realStream.CopyToAsync(stream); Task task2 = stream.CopyToAsync(realStream); switch (Task.WaitAny(task1, task2, stopTask)) { case 0: Task.WaitAny(task2, stopTask); break; case 1: Task.WaitAny(task1, stopTask); break; case 2: default: break; } realStream.Close(); client.Close(); return; } catch (Exception) { } } var selector = new PacketSelector(stream); switch (handshake.State) { case 1: selector.Catch(); new RequestPacket(selector); var response = new ResponsePacket(parser, record.StatusPath); response.Send(stream); selector.Catch(); if (selector.ID == 1 && selector.Size == 9) { new PingPongPacket(selector).Send(stream); } break; case 2: var loginPacket = new LoginStartPacket(stream); new DisconnectPacket(parser, record.LoginPath).Send(stream); log.WriteInfo($"Player '{loginPacket.PlayerName}' tried to login from {endPoint} to {record.Mask}."); break; default: break; } }