protected override async void HandleClient(SimpleSocket clientSocket, string url) { await AcceptConnection(clientSocket); var socketMessageLayer = new SocketMessageLayer(clientSocket, true); socketMessageLayer.AddPacketHandler<TestRegistrationRequest>(request => { if (request.Tester) { switch (request.Platform) { case (int)PlatformType.Windows: { Process process = null; var debugInfo = ""; try { var workingDir = Path.GetDirectoryName(request.Cmd); if (workingDir != null) { var start = new ProcessStartInfo { WorkingDirectory = workingDir, FileName = request.Cmd }; start.EnvironmentVariables["SiliconStudioXenkoDir"] = Environment.GetEnvironmentVariable("SiliconStudioXenkoDir"); start.UseShellExecute = false; start.RedirectStandardError = true; start.RedirectStandardOutput = true; debugInfo = "Starting process " + start.FileName + " with path " + start.WorkingDirectory; socketMessageLayer.Send(new LogRequest { Message = debugInfo }).Wait(); process = Process.Start(start); } } catch (Exception ex) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Launch exception: " + ex.Message }).Wait(); } if (process == null) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Failed to start game process. " + debugInfo }).Wait(); } else { process.OutputDataReceived += (sender, args) => { try { socketMessageLayer.Send(new LogRequest { Message = $"STDIO: {args.Data}" }).Wait(); } catch { } }; process.ErrorDataReceived += (sender, args) => { try { socketMessageLayer.Send(new LogRequest { Message = $"STDERR: {args.Data}" }).Wait(); } catch { } }; process.BeginOutputReadLine(); process.BeginErrorReadLine(); var currenTestPair = new TestPair { TesterSocket = socketMessageLayer, GameName = request.GameAssembly, Process = process }; processes[request.GameAssembly] = currenTestPair; testerToGame[socketMessageLayer] = currenTestPair; socketMessageLayer.Send(new LogRequest { Message = "Process created, id: " + process.Id.ToString() }).Wait(); } break; } case (int)PlatformType.Android: { Process process = null; try { process = Process.Start("cmd.exe", $"/C adb shell monkey -p {request.GameAssembly}.{request.GameAssembly} -c android.intent.category.LAUNCHER 1"); } catch (Exception ex) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Launch exception: " + ex.Message }).Wait(); } if (process == null) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Failed to start game process." }).Wait(); } else { lock (loggerLock) { currentTester = socketMessageLayer; } var currenTestPair = new TestPair { TesterSocket = socketMessageLayer, GameName = request.GameAssembly, Process = process }; processes[request.GameAssembly] = currenTestPair; testerToGame[socketMessageLayer] = currenTestPair; socketMessageLayer.Send(new LogRequest { Message = "Process created, id: " + process.Id.ToString() }).Wait(); } break; } case (int)PlatformType.iOS: { Process process = null; var debugInfo = ""; try { Thread.Sleep(5000); //ios processes might be slow to close, we must make sure that we start clean var start = new ProcessStartInfo { WorkingDirectory = $"{Environment.GetEnvironmentVariable("SiliconStudioXenkoDir")}\\Bin\\Windows-Direct3D11\\", FileName = $"{Environment.GetEnvironmentVariable("SiliconStudioXenkoDir")}\\Bin\\Windows-Direct3D11\\idevicedebug.exe", Arguments = $"run com.your-company.{request.GameAssembly}", UseShellExecute = false }; debugInfo = "Starting process " + start.FileName + " with path " + start.WorkingDirectory; process = Process.Start(start); } catch (Exception ex) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = $"Launch exception: {ex.Message} info: {debugInfo}" }).Wait(); } if (process == null) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Failed to start game process. " + debugInfo }).Wait(); } else { lock (loggerLock) { currentTester = socketMessageLayer; } var currenTestPair = new TestPair { TesterSocket = socketMessageLayer, GameName = request.GameAssembly, Process = process }; processes[request.GameAssembly] = currenTestPair; testerToGame[socketMessageLayer] = currenTestPair; socketMessageLayer.Send(new LogRequest { Message = "Process created, id: " + process.Id.ToString() }).Wait(); } break; } } } else //Game process { TestPair pair; if (!processes.TryGetValue(request.GameAssembly, out pair)) return; pair.GameSocket = socketMessageLayer; testerToGame[pair.TesterSocket] = pair; gameToTester[pair.GameSocket] = pair; pair.TesterSocket.Send(new StatusMessageRequest { Error = false, Message = "Start" }).Wait(); Console.WriteLine($"Starting test {request.GameAssembly}"); } }); socketMessageLayer.AddPacketHandler<KeySimulationRequest>(request => { var game = testerToGame[socketMessageLayer]; game.GameSocket.Send(request).Wait(); }); socketMessageLayer.AddPacketHandler<TapSimulationRequest>(request => { var game = testerToGame[socketMessageLayer]; game.GameSocket.Send(request).Wait(); }); socketMessageLayer.AddPacketHandler<ScreenshotRequest>(request => { var game = testerToGame[socketMessageLayer]; game.GameSocket.Send(request).Wait(); }); socketMessageLayer.AddPacketHandler<TestEndedRequest>(request => { var game = testerToGame[socketMessageLayer]; game.GameSocket.Send(request).Wait(); testerToGame.Remove(socketMessageLayer); gameToTester.Remove(game.GameSocket); processes.Remove(game.GameName); socketMessageLayer.Context.Dispose(); game.GameSocket.Context.Dispose(); game.Process.Kill(); game.Process.Dispose(); lock (loggerLock) { currentTester = null; } Console.WriteLine($"Finished test {game.GameName}"); }); socketMessageLayer.AddPacketHandler<TestAbortedRequest>(request => { var game = testerToGame[socketMessageLayer]; testerToGame.Remove(socketMessageLayer); processes.Remove(game.GameName); socketMessageLayer.Context.Dispose(); game.Process.Kill(); game.Process.Dispose(); lock (loggerLock) { currentTester = null; } Console.WriteLine($"Aborted test {game.GameName}"); }); socketMessageLayer.AddPacketHandler<ScreenShotPayload>(request => { var tester = gameToTester[socketMessageLayer]; var imageData = new TestResultImage(); var stream = new MemoryStream(request.Data); imageData.Read(new BinaryReader(stream)); stream.Dispose(); var resultFileStream = File.OpenWrite(request.FileName); imageData.Image.Save(resultFileStream, ImageFileType.Png); resultFileStream.Dispose(); tester.TesterSocket.Send(new ScreenshotStored()).Wait(); }); Task.Run(async () => { try { await socketMessageLayer.MessageLoop(); } catch { } }); }
protected override async void HandleClient(SimpleSocket clientSocket, string url) { await AcceptConnection(clientSocket); var socketMessageLayer = new SocketMessageLayer(clientSocket, true); socketMessageLayer.AddPacketHandler<TestRegistrationRequest>(request => { if (request.Tester) { switch (request.Platform) { case (int)PlatformType.Windows: { Process process = null; var debugInfo = ""; try { var start = new ProcessStartInfo { WorkingDirectory = Path.GetDirectoryName(request.Cmd), FileName = request.Cmd, }; start.EnvironmentVariables["SiliconStudioXenkoDir"] = Environment.GetEnvironmentVariable("SiliconStudioXenkoDir"); start.UseShellExecute = false; debugInfo = "Starting process " + start.FileName + " with path " + start.WorkingDirectory; socketMessageLayer.Send(new LogRequest { Message = debugInfo }).Wait(); process = Process.Start(start); } catch (Exception ex) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Launch exception: " + ex.Message }).Wait(); } if (process == null) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Failed to start game process. " + debugInfo }).Wait(); } else { processes[request.GameAssembly] = new TestProcess { Process = process, TesterSocket = socketMessageLayer }; socketMessageLayer.Send(new LogRequest { Message = "Process created, id: " + process.Id.ToString() }).Wait(); } break; } case (int)PlatformType.Android: { Process process = null; var debugInfo = ""; try { process = Process.Start("cmd.exe", $"/C adb shell monkey -p {request.GameAssembly}.{request.GameAssembly} -c android.intent.category.LAUNCHER 1"); } catch (Exception ex) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Launch exception: " + ex.Message }).Wait(); } if (process == null) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Failed to start game process. " + debugInfo }).Wait(); } else { processes[request.GameAssembly] = new TestProcess { Process = process, TesterSocket = socketMessageLayer }; socketMessageLayer.Send(new LogRequest { Message = "Process created, id: " + process.Id.ToString() }).Wait(); } break; } } } else //Game process { TestProcess process; if (processes.TryGetValue(request.GameAssembly, out process)) { process.GameSocket = socketMessageLayer; testerToGame[process.TesterSocket] = process.GameSocket; gameToTester[process.GameSocket] = process.TesterSocket; process.TesterSocket.Send(new StatusMessageRequest { Error = false, Message = "Start" }).Wait(); } } }); socketMessageLayer.AddPacketHandler<KeySimulationRequest>(request => { var game = testerToGame[socketMessageLayer]; game.Send(request).Wait(); }); socketMessageLayer.AddPacketHandler<TapSimulationRequest>(request => { var game = testerToGame[socketMessageLayer]; game.Send(request).Wait(); }); socketMessageLayer.AddPacketHandler<ScreenshotRequest>(request => { var game = testerToGame[socketMessageLayer]; game.Send(request).Wait(); }); socketMessageLayer.AddPacketHandler<TestEndedRequest>(request => { var game = testerToGame[socketMessageLayer]; game.Send(request).Wait(); testerToGame.Remove(socketMessageLayer); }); socketMessageLayer.AddPacketHandler<ScreenShotPayload>(request => { var tester = gameToTester[socketMessageLayer]; var imageData = new TestResultImage(); var stream = new MemoryStream(request.Data); imageData.Read(new BinaryReader(stream)); stream.Dispose(); var resultFileStream = File.OpenWrite(request.FileName); imageData.Image.Save(resultFileStream, ImageFileType.Png); resultFileStream.Dispose(); tester.Send(new ScreenshotStored()).Wait(); }); Task.Run(() => socketMessageLayer.MessageLoop()); }