Given_connection_in_Initial_status_When_receives_2_part_login_seed_second_part_appended_to_LoginRequest_Then_connection_enters_ServerLogin_status() { var inputStream = new TestPullStream(new List <byte[]> { new byte[] { 0xef }, new byte[] { 0x01, 0x38, 0xa8, 0xc0 }, new byte[] { 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x80, 0x42, 0x75, 0x74, 0x68, 0x72, 0x6F, 0x6D, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4A, 0x46, 0x6B, 0x72, 0x34, 0x33, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF }, }); int packetsReceived = 0; var connection = new UltimaClientConnection(UltimaClientConnectionStatus.Initial); connection.PacketReceived += (sender, packet) => packetsReceived++; connection.ReceiveBatch(inputStream, 1); inputStream.NextBatch(); connection.ReceiveBatch(inputStream, 4); inputStream.NextBatch(); connection.ReceiveBatch(inputStream, 78); inputStream.NextBatch(); connection.Status.Should().Be(UltimaClientConnectionStatus.ServerLogin); packetsReceived.Should().Be(2); }
private static void ClientLoop(ILogger packetLogger) { var diagnosticProvider = new InfusionDiagnosticPushStreamProvider(Configuration, Console); serverDiagnosticPushStream = new CompositeDiagnosticPushStream(new ConsoleDiagnosticPushStream(packetLogger, "proxy -> server"), new InfusionBinaryDiagnosticPushStream(DiagnosticStreamDirection.ClientToServer, diagnosticProvider.GetStream)); serverDiagnosticPullStream = new ConsoleDiagnosticPullStream(packetLogger, "server -> proxy"); serverConnection = new ServerConnection(ServerConnectionStatus.Initial, serverDiagnosticPullStream, serverDiagnosticPushStream); serverConnection.PacketReceived += ServerConnectionOnPacketReceived; clientConnection = new UltimaClientConnection(UltimaClientConnectionStatus.Initial, new ConsoleDiagnosticPullStream(packetLogger, "client -> proxy"), new CompositeDiagnosticPushStream(new ConsoleDiagnosticPushStream(packetLogger, "proxy -> client"), new InfusionBinaryDiagnosticPushStream(DiagnosticStreamDirection.ServerToClient, diagnosticProvider.GetStream))); clientConnection.PacketReceived += ClientConnectionOnPacketReceived; diagnosticProvider.ClientConnection = clientConnection; diagnosticProvider.ServerConnection = serverConnection; Task.Run(() => ServerLoop()); try { while (true) { var client = listener.AcceptTcpClient(); ClientStream = client.GetStream(); int receivedLength; var receiveBuffer = new byte[65535]; while ((receivedLength = ClientStream.Read(receiveBuffer, 0, receiveBuffer.Length)) > 0) { var memoryStream = new MemoryStream(receiveBuffer, 0, receivedLength, false); clientConnection.ReceiveBatch(new MemoryStreamToPullStreamAdapter(memoryStream)); } Thread.Yield(); } } catch (IOException ioex) when(ioex.InnerException is SocketException socex && socex.SocketErrorCode == SocketError.ConnectionReset) { Console.Error("Connection to client lost."); throw; } catch (Exception ex) { Console.Error(serverDiagnosticPullStream.Flush()); Console.Error(ex.ToString()); throw; } finally { diagnosticProvider.Dispose(); } }
public void Given_connection_in_GameLoign_status_When_receives_GameServerLoginRequest_Then_enters_Game_status() { var inputStream = new TestPullStream(new List <byte[]> { FakePackets.GameServerLoginRequest }); var connection = new UltimaClientConnection(UltimaClientConnectionStatus.GameLogin); connection.ReceiveBatch(inputStream, inputStream.Length); connection.Status.Should().Be(UltimaClientConnectionStatus.Game); }
Given_connection_in_PreGameLogin_status_When_receives_login_seed_Then_connection_enters_GameLogin_status() { var inpuStream = new TestPullStream(new List <byte[]> { FakePackets.LoginSeed }); var connection = new UltimaClientConnection(UltimaClientConnectionStatus.PreGameLogin); connection.ReceiveBatch(inpuStream, inpuStream.Length); connection.Status.Should().Be(UltimaClientConnectionStatus.GameLogin); }
Given_connection_in_Initial_status_When_receives_login_seed_Then_connection_enters_ServerLogin_status() { var inputStream = new TestPullStream(new List <byte[]> { FakePackets.InitialLoginSeed_Pre6060 }); var connection = new UltimaClientConnection(UltimaClientConnectionStatus.Initial); connection.ReceiveBatch(inputStream, inputStream.Length); connection.Status.Should().Be(UltimaClientConnectionStatus.AfterInitialSeed); }
Given_connection_in_ServerLogin_status_When_receives_SelectServerRequest_Then_enters_PreGameLogin_status() { var inputStream = new TestPullStream(new List <byte[]> { FakePackets.SelectServerRequest }); var connection = new UltimaClientConnection(UltimaClientConnectionStatus.ServerLogin); connection.ReceiveBatch(inputStream); connection.Status.Should().Be(UltimaClientConnectionStatus.PreGameLogin); }
public void Can_enter_Game_status_after_initial_sequence() { var inputStream = new TestPullStream(new List <byte[]> { FakePackets.InitialLoginSeed_Pre6060, FakePackets.InitialLoginRequest, FakePackets.ClientSpy, FakePackets.SelectServerRequest, FakePackets.LoginSeed, FakePackets.GameServerLoginRequest }); var connection = new UltimaClientConnection(UltimaClientConnectionStatus.Initial); connection.ReceiveBatch(inputStream, inputStream.Length); inputStream.NextBatch(); connection.ReceiveBatch(inputStream, inputStream.Length); inputStream.NextBatch(); connection.ReceiveBatch(inputStream, inputStream.Length); inputStream.NextBatch(); connection.ReceiveBatch(inputStream, inputStream.Length); inputStream.NextBatch(); connection.ReceiveBatch(inputStream, inputStream.Length); inputStream.NextBatch(); connection.ReceiveBatch(inputStream, inputStream.Length); connection.Status.Should().Be(UltimaClientConnectionStatus.Game); }
public void Can_receive_two_consecutive_batches() { var inputStream = new TestPullStream(new List <byte[]> { FakePackets.InitialLoginSeed_Pre6060, FakePackets.InitialLoginRequest }); var expectedPackets = new[] { new Packet(PacketDefinitions.LoginSeed.Id, FakePackets.InitialLoginSeed_Pre6060), new Packet(0x80, FakePackets.InitialLoginRequest) }; var connection = new UltimaClientConnection(); var receivedPackets = new List <Packet>(); connection.PacketReceived += (sender, packet) => receivedPackets.Add(packet); connection.ReceiveBatch(inputStream, inputStream.Length); inputStream.NextBatch(); connection.ReceiveBatch(inputStream, inputStream.Length); expectedPackets.AreEqual(receivedPackets); }
Given_connection_in_Initial_status_When_receives_3_part_login_seed_Then_connection_enters_ServerLogin_status() { var inputStream = new TestPullStream(new List <byte[]> { new byte[] { 0xef }, new byte[] { 0x01, 0x38, 0xa8, 0xc0 }, new byte[] { 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, }, }); var connection = new UltimaClientConnection(UltimaClientConnectionStatus.Initial); connection.ReceiveBatch(inputStream, 1); inputStream.NextBatch(); connection.ReceiveBatch(inputStream, 4); inputStream.NextBatch(); connection.ReceiveBatch(inputStream, 16); connection.Status.Should().Be(UltimaClientConnectionStatus.AfterInitialSeed); }
private void ClientLoopCore(TcpListener listener) { var client = listener.AcceptTcpClient(); try { lock (clientLock) { clientStream = client.GetStream(); } int receivedLength; var receiveBuffer = new byte[65535]; while ((receivedLength = clientStream.Read(receiveBuffer, 0, receiveBuffer.Length)) > 0) { #if DUMP_RAW Console.Info("client -> proxy"); Console.Info(receiveBuffer.Take(receivedLength).Select(x => x.ToString("X2")).Aggregate((l, r) => l + " " + r)); #endif var memoryStream = new MemoryStream(receiveBuffer, 0, receivedLength, false); clientConnection.ReceiveBatch(new MemoryStreamToPullStreamAdapter(memoryStream), receivedLength); disconnectTokenSource.Token.ThrowIfCancellationRequested(); Thread.Yield(); } } finally { client.Dispose(); lock (clientLock) { clientStream.Dispose(); clientStream = null; } } }
public void Can_receive_three_packets_in_one_batch() { var inputStream = new TestPullStream(new List <byte[]> { FakePackets.InitialLoginSeed_Pre6060 .Concat(FakePackets.InitialLoginRequest) .Concat(FakePackets.SelectServerRequest).ToArray() }); var expectedPackets = new[] { new Packet(PacketDefinitions.LoginSeed.Id, FakePackets.InitialLoginSeed_Pre6060), new Packet(0x80, FakePackets.InitialLoginRequest), new Packet(0xA0, FakePackets.SelectServerRequest) }; var connection = new UltimaClientConnection(); var receivedPackets = new List <Packet>(); connection.PacketReceived += (sender, packet) => receivedPackets.Add(packet); connection.ReceiveBatch(inputStream, inputStream.Length); expectedPackets.AreEqual(receivedPackets); }
private void ClientLoop(ILogger packetLogger) { var diagnosticProvider = new InfusionDiagnosticPushStreamProvider(LogConfig, Console); serverDiagnosticPushStream = new CompositeDiagnosticPushStream(new ConsoleDiagnosticPushStream(packetLogger, "proxy -> server", packetRegistry), new InfusionBinaryDiagnosticPushStream(DiagnosticStreamDirection.ClientToServer, diagnosticProvider.GetStream)); serverDiagnosticPullStream = new ConsoleDiagnosticPullStream(packetLogger, "server -> proxy", packetRegistry); serverConnection = new ServerConnection(ServerConnectionStatus.Initial, serverDiagnosticPullStream, serverDiagnosticPushStream, packetRegistry, proxyStartConfig.Encryption); serverConnection.PacketReceived += ServerConnectionOnPacketReceived; clientConnection = new UltimaClientConnection(UltimaClientConnectionStatus.Initial, new ConsoleDiagnosticPullStream(packetLogger, "client -> proxy", packetRegistry), new CompositeDiagnosticPushStream(new ConsoleDiagnosticPushStream(packetLogger, "proxy -> client", packetRegistry), new InfusionBinaryDiagnosticPushStream(DiagnosticStreamDirection.ServerToClient, diagnosticProvider.GetStream)), packetRegistry, proxyStartConfig.Encryption, proxyStartConfig.LoginEncryptionKey); clientConnection.PacketReceived += ClientConnectionOnPacketReceived; clientConnection.NewGameEncryptionStarted += ClientConnectionOnNewGameEncryptionStarted; clientConnection.LoginEncryptionStarted += ClientConnectionOnLoginEncryptionStarted; diagnosticProvider.ClientConnection = clientConnection; diagnosticProvider.ServerConnection = serverConnection; bool serverLoopStarted = false; try { while (true) { var client = listener.AcceptTcpClient(); ClientStream = client.GetStream(); lock (serverStreamLock) { if (ServerStream == null) { ServerStream = ConnectToServer(); } } if (!serverLoopStarted) { Task.Run(() => ServerLoop()); serverLoopStarted = true; } int receivedLength; var receiveBuffer = new byte[65535]; while ((receivedLength = ClientStream.Read(receiveBuffer, 0, receiveBuffer.Length)) > 0) { #if DUMP_RAW Console.Info("client -> proxy"); Console.Info(receiveBuffer.Take(receivedLength).Select(x => x.ToString("X2")).Aggregate((l, r) => l + " " + r)); #endif var memoryStream = new MemoryStream(receiveBuffer, 0, receivedLength, false); clientConnection.ReceiveBatch(new MemoryStreamToPullStreamAdapter(memoryStream), receivedLength); } lock (serverStreamLock) { DisconnectFromServer(); ServerStream = ConnectToServer(); } Thread.Yield(); } } catch (IOException ioex) when(ioex.InnerException is SocketException socex && socex.SocketErrorCode == SocketError.ConnectionReset) { Console.Error("Connection to client lost. Please restart infusion."); Console.Debug(socex.ToString()); } catch (Exception ex) { Console.Error("Connection to client lost. Please restart infusion."); Console.Debug(serverDiagnosticPullStream.Flush()); Console.Debug(ex.ToString()); throw; } finally { diagnosticProvider.Dispose(); } }