public IActionResult Index(PrivateViewModel request)
        {
            StartServerResponse viewModel;

            try
            {
                if (!ModelState.IsValid)
                {
                    throw new WebInterfaceException("Something went off the rails.");
                }

                if (_torCheckService.IsTorExit(HttpContext.Connection.RemoteIpAddress))
                {
                    throw new WebInterfaceException("Requesting private servers through Tor is not allowed.");
                }

                if (!_rateLimiterService.IsRequestAllowed(HttpContext.Connection.RemoteIpAddress))
                {
                    throw new WebInterfaceException("Sorry, you have requested too many servers recently, you need to wait some time.");
                }

                string tempFolderName = "";
                if ((request.FormFile?.Length ?? 0) > 0)
                {
                    tempFolderName = _customMapService.StoreTempCustomMap(request.FormFile);
                }

                var    spawnedServer = _privateServerService.SpawnNewPrivateServer(request.Players + 1, request.ModName, tempFolderName ?? "");
                string commandLine   = CommandLineUtils.GetClientLaunchCommand(HttpContext.Request.Host.Host,
                                                                               spawnedServer.Port,
                                                                               spawnedServer.Mod.CommandLine);

                viewModel = new StartServerResponse(spawnedServer.Port, commandLine);
            }
            catch (WebInterfaceException ex)
            {
                viewModel = new StartServerResponse(ex.Message);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                viewModel = new StartServerResponse("Internal server error.");
            }

            return(View("Result", viewModel));
        }
        public StartServerResponse StartServer([FromQuery] ServerParameters parameters)
        {
            try
            {
                if (parameters.ApiKey != _config.GetValue <string>("ApiKey"))
                {
                    return(new StartServerResponse("Invalid ApiKey."));
                }

                Stopwatch sw = Stopwatch.StartNew();
                while (_isBusy)
                {
                    Thread.Sleep(TimeSpan.FromSeconds(1));
                    if (sw.Elapsed.TotalSeconds > 5)
                    {
                        throw new Exception("Request timeout: the previous request hasn't finished yet.");
                    }
                }

                _isBusy = true;

                var serverProcess = _privateServerService.SpawnNewPrivateServer(parameters.Players, parameters.ModName);
                _logger.LogInformation("Server started waiting for {0} players on port {1}.",
                                       parameters.Players, serverProcess.Port);

                string commandLine = CommandLineUtils.GetClientLaunchCommand(HttpContext.Request.Host.Host,
                                                                             serverProcess.Port,
                                                                             serverProcess.Mod.CommandLine);

                Thread.Sleep(TimeSpan.FromSeconds(2));
                return(new StartServerResponse(serverProcess.Port, commandLine));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                return(new StartServerResponse(generalErrorMessage));
            }
            finally
            {
                _isBusy = false;
            }
        }