public async Task <IActionResult> Upload([FromServices] ManagementServiceClient mgmt) { var context = HttpContext; var file = context.Request.Form.Files["file"]; if (file != null) { var id = await mgmt.PutBlobAsync("joyoi_online_judge_upload_" + file.FileName, file.ReadAllBytes()); var f = new { Id = id, Time = DateTime.Now, ContentType = file.ContentType, ContentLength = file.Length, FileName = file.GetFileName(), Bytes = file.ReadAllBytes() }; return(Json(f)); } else { var blob = new Base64StringFile(context.Request.Form["file"]); var id = await mgmt.PutBlobAsync("joyoi_online_judge_upload_file", blob.AllBytes); var f = new { Id = id, Time = DateTime.Now, ContentType = blob.ContentType, ContentLength = blob.Base64String.Length, FileName = "file", Bytes = blob.AllBytes }; return(Json(f)); } }
public async Task <IActionResult> Put( [FromServices] IConfiguration Config, [FromServices] IServiceScopeFactory scopeFactory, [FromServices] StateMachineAwaiter awaiter, [FromServices] ManagementServiceClient MgmtSvc, [FromServices] IHubContext <OnlineJudgeHub> hub, [FromServices] ContestExecutorFactory cef, CancellationToken token) { var request = JsonConvert.DeserializeObject <JudgeRequest>(RequestBody); var problem = await DB.Problems .Include(x => x.TestCases) .SingleOrDefaultAsync(x => x.Id == request.problemId, token); if (problem == null) { return(Result(400, "The problem is not exist.")); } if (!problem.IsVisible && string.IsNullOrWhiteSpace(request.contestId) && !await HasPermissionToProblemAsync(problem.Id, token)) { return(Result(403, "You have no permission to the problem.")); } if (IsGroupRequest() && !await IsGroupMemberAsync(token)) { return(Result(401, "You are not a member of this group.")); } if (!Constants.SupportedLanguages.Contains(request.language)) { return(Result(400, "The language has not been supported.")); } if (string.IsNullOrEmpty(request.code)) { return(Result(400, "Code could not be empty.")); } if (!string.IsNullOrEmpty(request.contestId)) { var ce = cef.Create(request.contestId); if (!ce.IsContestInProgress(User.Current?.UserName)) { return(Result(400, "The contest is inactive.")); } if (request.isSelfTest) { return(Result(400, "You could not do a self test during the contest is in progress.")); } if (await DB.ContestProblemLastStatuses.AnyAsync(x => x.IsLocked && x.ContestId == request.contestId && User.Current.Id == x.UserId && x.ProblemId == request.problemId, token)) { return(Result(400, "You have locked this problem.")); } } if (!Constants.SupportedLanguages.Contains(request.language) && !Constants.UnsupportedLanguages.Contains(request.language) && problem.Source == ProblemSource.Local) { return(Result(400, "The programming language which you selected was not supported")); } if (request.isSelfTest && request.data.Count() == 0) { return(Result(400, "The self testing data has not been found")); } if (problem.Source != ProblemSource.Local && request.isSelfTest) { return(Result(400, "You could not use self data to test with a remote problem.")); } if (IsGroupRequest() && !await DB.GroupProblems.AnyAsync(x => x.ProblemId == problem.Id && x.GroupId == CurrentGroup.Id) && string.IsNullOrEmpty(request.contestId)) { return(Result(404, "The problem does not exist.")); } #region Local Judge if (problem.Source == ProblemSource.Local) { var blobs = new ConcurrentDictionary <int, BlobInfo[]>(); blobs.TryAdd(-1, new[] { new BlobInfo { Id = await MgmtSvc.PutBlobAsync("Main" + Constants.GetSourceExtension(request.language), Encoding.UTF8.GetBytes(request.code)), Name = "Main" + Constants.GetSourceExtension(request.language), Tag = "Problem=" + problem.Id } }); blobs.TryAdd(-2, new[] { new BlobInfo { Id = await MgmtSvc.PutBlobAsync("limit.json", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new { UserTime = problem.TimeLimitationPerCaseInMs, PhysicalTime = problem.TimeLimitationPerCaseInMs * 4, Memory = problem.MemoryLimitationPerCaseInByte }))), Name = "limit.json", Tag = "Problem=" + problem.Id } }); if (!problem.ValidatorBlobId.HasValue) { blobs.TryAdd(-3, new[] { new BlobInfo { Id = Guid.Parse(Config["JoyOI:StandardValidatorBlobId"]), Name = "Validator.out" } }); } else { blobs.TryAdd(-3, new[] { new BlobInfo { Id = problem.ValidatorBlobId.Value, Name = "Validator" + Constants.GetBinaryExtension(problem.ValidatorLanguage) } }); } List <TestCase> testCases = null; if (request.isSelfTest) { Parallel.For(0, request.data.Count(), i => { // Uploading custom data var inputId = MgmtSvc.PutBlobAsync($"input_{ i }.txt", Encoding.UTF8.GetBytes(request.data.ElementAt(i).input), token).Result; var outputId = MgmtSvc.PutBlobAsync($"output_{ i }.txt", Encoding.UTF8.GetBytes(request.data.ElementAt(i).output), token).Result; blobs.TryAdd(i, new[] { new BlobInfo { Id = inputId, Name = $"input_{ i }.txt", Tag = i.ToString() }, new BlobInfo { Id = outputId, Name = $"output_{ i }.txt", Tag = i.ToString() } }); }); } else { testCases = await DB.TestCases .Where(x => x.ProblemId == problem.Id && (x.Type == TestCaseType.Small || x.Type == TestCaseType.Large || x.Type == TestCaseType.Hack)) .ToListAsync(token); if (testCases.Count == 0) { return(Result(400, "No test case found.")); } for (var i = 0; i < testCases.Count; i++) { blobs.TryAdd(i, new[] { new BlobInfo { Id = testCases[i].InputBlobId, Name = $"input_{ i }.txt", Tag = i.ToString() }, new BlobInfo { Id = testCases[i].OutputBlobId, Name = $"output_{ i }.txt", Tag = i.ToString() } }); } } var stateMachineId = await MgmtSvc.PutStateMachineInstanceAsync("JudgeStateMachine", Config["ManagementService:CallBack"], blobs.SelectMany(x => x.Value), await CalculatePriorityAsync(), token); var substatuses = blobs .Where(x => x.Key >= 0) .Select(x => new SubJudgeStatus { SubId = x.Key, Result = JudgeResult.Pending, InputBlobId = x.Value.Single(y => y.Name.StartsWith("input_")).Id, OutputBlobId = x.Value.Single(y => y.Name.StartsWith("output_")).Id, TestCaseId = testCases != null ? (Guid?)testCases[x.Key].Id : null }) .ToList(); var status = new JudgeStatus { Code = request.code, Language = request.language, Result = JudgeResult.Pending, CreatedTime = DateTime.UtcNow, ContestId = request.contestId, SubStatuses = substatuses, ProblemId = problem.Id, UserId = User.Current.Id, IsSelfTest = request.isSelfTest, RelatedStateMachineIds = new List <JudgeStatusStateMachine> { new JudgeStatusStateMachine { StateMachine = new StateMachine { CreatedTime = DateTime.UtcNow, Name = "JudgeStateMachine", Id = stateMachineId }, StateMachineId = stateMachineId } }, }; if (IsGroupRequest()) { status.GroupId = CurrentGroup.Id; } DB.JudgeStatuses.Add(status); await DB.SaveChangesAsync(token); hub.Clients.All.InvokeAsync("ItemUpdated", "judge", status.Id); // For debugging if (Config["ManagementService:Mode"] == "Polling") { Task.Factory.StartNew(async() => { using (var scope = scopeFactory.CreateScope()) using (var db = scope.ServiceProvider.GetService <OnlineJudgeContext>()) { try { await awaiter.GetStateMachineResultAsync(stateMachineId); var handler = scope.ServiceProvider.GetService <JudgeStateMachineHandler>(); await handler.HandleJudgeResultAsync(stateMachineId, default(CancellationToken)); } catch (Exception ex) { Console.Error.WriteLine(ex); } } }); } return(Result(status.Id)); } #endregion #region Bzoj, LeetCode, CodeVS else if (problem.Source == ProblemSource.Bzoj || problem.Source == ProblemSource.LeetCode || problem.Source == ProblemSource.CodeVS) { var metadata = new { Source = problem.Source.ToString(), Language = request.language, Code = request.code, ProblemId = problem.Id.Replace(problem.Source.ToString().ToLower() + "-", "") }; var metadataBlob = new BlobInfo { Id = await MgmtSvc.PutBlobAsync("metadata.json", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(metadata)), token), Name = "metadata.json", Tag = "Problem=" + problem.Id }; var stateMachineId = await MgmtSvc.PutStateMachineInstanceAsync("VirtualJudgeStateMachine", Config["ManagementService:Callback"], new[] { metadataBlob }, await CalculatePriorityAsync(), token); var status = new JudgeStatus { Code = request.code, ContestId = request.contestId, Language = request.language, ProblemId = problem.Id, IsSelfTest = false, UserId = User.Current.Id, Result = JudgeResult.Pending, RelatedStateMachineIds = new List <JudgeStatusStateMachine> { new JudgeStatusStateMachine { StateMachine = new StateMachine { CreatedTime = DateTime.UtcNow, Name = "JudgeStateMachine", Id = stateMachineId }, StateMachineId = stateMachineId } } }; if (IsGroupRequest()) { status.GroupId = CurrentGroup.Id; } DB.JudgeStatuses.Add(status); await DB.SaveChangesAsync(token); // For debugging if (Config["ManagementService:Mode"] == "Polling") { Task.Factory.StartNew(async() => { using (var scope = scopeFactory.CreateScope()) { try { await awaiter.GetStateMachineResultAsync(stateMachineId); var handler = scope.ServiceProvider.GetService <JudgeStateMachineHandler>(); await handler.HandleJudgeResultAsync(stateMachineId, default(CancellationToken)); } catch (Exception ex) { Console.Error.WriteLine(ex); } } }); } hub.Clients.All.InvokeAsync("ItemUpdated", "judge", status.Id); return(Result(status.Id)); } #endregion #region Others else { throw new NotSupportedException(problem.Source.ToString() + " has not been supported yet."); } #endregion }
public async Task <IActionResult> Patch( string id, [FromServices] ManagementServiceClient MgmtSvc, [FromServices] StateMachineAwaiter Awaiter, [FromServices] IHubContext <OnlineJudgeHub> hub, CancellationToken token) { if (!await HasPermissionToProblemAsync(id, token)) { return(Result(401, "No Permission")); } else { var problem = await DB.Problems.SingleOrDefaultAsync(x => x.Id == id, token); if (problem == null) { return(Result(404, "Not Found")); } var fields = PatchEntity(problem, RequestBody); // Check difficulty range if (fields.Any(x => x == nameof(Problem.Difficulty)) && (problem.Difficulty < 0 || problem.Difficulty > 9)) { return(Result(400, "The difficulty must be 0-9.")); } // Update validator if (fields.Any(x => x == nameof(Problem.ValidatorCode)) || fields.Any(x => x == nameof(Problem.ValidatorLanguage))) { if (string.IsNullOrWhiteSpace(problem.ValidatorCode)) { problem.ValidatorBlobId = null; problem.ValidatorCode = null; problem.ValidatorError = null; problem.ValidatorLanguage = null; } else { var validatorCodeId = await MgmtSvc.PutBlobAsync("validator-" + problem.Id, Encoding.UTF8.GetBytes(problem.ValidatorCode), token); var stateMachineId = await MgmtSvc.PutStateMachineInstanceAsync("CompileOnlyStateMachine", Configuration["ManagementService:CallBack"], new BlobInfo[] { new BlobInfo(validatorCodeId, "Main" + Constants.GetSourceExtension(problem.ValidatorLanguage)) }); var result = await Awaiter.GetStateMachineResultAsync(stateMachineId, true, token); var runner = JsonConvert.DeserializeObject <dynamic>(Encoding.UTF8.GetString((await MgmtSvc.GetBlobAsync(result.StartedActors.Last().Outputs.Single(x => x.Name == "runner.json").Id, token)).Body)); if (result.StartedActors.Any(x => x.Name == "CompileActor" && runner.ExitCode == 0 && x.Status == JoyOI.ManagementService.Model.Enums.ActorStatus.Succeeded)) { problem.ValidatorBlobId = result.StartedActors.Last().Outputs.Single(x => x.Name.StartsWith("Main.")).Id; problem.ValidatorError = null; } else { problem.ValidatorBlobId = null; problem.ValidatorError = runner.Error; } } } // Update standard if (fields.Any(x => x == nameof(Problem.StandardCode)) || fields.Any(x => x == nameof(Problem.StandardLanguage))) { if (string.IsNullOrWhiteSpace(problem.StandardCode)) { problem.StandardBlobId = null; problem.StandardCode = null; problem.StandardError = null; problem.StandardLanguage = null; } else { var standardCodeId = await MgmtSvc.PutBlobAsync("standard-" + problem.Id, Encoding.UTF8.GetBytes(problem.StandardCode), token); var stateMachineId = await MgmtSvc.PutStateMachineInstanceAsync("CompileOnlyStateMachine", Configuration["ManagementService:CallBack"], new BlobInfo[] { new BlobInfo(standardCodeId, "Main" + Constants.GetSourceExtension(problem.StandardLanguage)) }); var result = await Awaiter.GetStateMachineResultAsync(stateMachineId, true, token); var runner = JsonConvert.DeserializeObject <dynamic>(Encoding.UTF8.GetString((await MgmtSvc.GetBlobAsync(result.StartedActors.Last().Outputs.Single(x => x.Name == "runner.json").Id, token)).Body)); if (result.StartedActors.Any(x => x.Name == "CompileActor" && runner.ExitCode == 0 && x.Status == JoyOI.ManagementService.Model.Enums.ActorStatus.Succeeded)) { problem.StandardBlobId = result.StartedActors.Last().Outputs.Single(x => x.Name.StartsWith("Main.")).Id; problem.StandardError = null; } else { problem.StandardBlobId = null; problem.StandardError = runner.Error; } } } // Update range if (fields.Any(x => x == nameof(Problem.RangeCode)) || fields.Any(x => x == nameof(Problem.RangeLanguage))) { if (string.IsNullOrWhiteSpace(problem.RangeCode)) { problem.RangeBlobId = null; problem.RangeCode = null; problem.RangeError = null; problem.RangeLanguage = null; } else { var rangeCodeId = await MgmtSvc.PutBlobAsync("range-" + problem.Id, Encoding.UTF8.GetBytes(problem.RangeCode), token); var stateMachineId = await MgmtSvc.PutStateMachineInstanceAsync("CompileOnlyStateMachine", Configuration["ManagementService:CallBack"], new BlobInfo[] { new BlobInfo(rangeCodeId, "Main" + Constants.GetSourceExtension(problem.RangeLanguage)) }); var result = await Awaiter.GetStateMachineResultAsync(stateMachineId, true, token); var runner = JsonConvert.DeserializeObject <dynamic>(Encoding.UTF8.GetString((await MgmtSvc.GetBlobAsync(result.StartedActors.Last().Outputs.Single(x => x.Name == "runner.json").Id, token)).Body)); if (result.StartedActors.Any(x => x.Name == "CompileActor" && runner.ExitCode == 0 && x.Status == JoyOI.ManagementService.Model.Enums.ActorStatus.Succeeded)) { problem.RangeBlobId = result.StartedActors.Last().Outputs.Single(x => x.Name.StartsWith("Main.")).Id; problem.RangeError = null; } else { problem.RangeBlobId = null; problem.RangeError = runner.Error; } } } if ((string.IsNullOrWhiteSpace(problem.Tags) || problem.Tags.IndexOf(LocalProblemSetTag) < 0) && problem.Source == ProblemSource.Local) { problem.Tags += "," + LocalProblemSetTag; problem.Tags = problem.Tags.Trim(','); } await DB.SaveChangesAsync(token); hub.Clients.All.InvokeAsync("ItemUpdated", "problem", problem.Id); if (fields.Any(x => x == nameof(Problem.Title)) || fields.Any(x => x == nameof(Problem.IsVisible))) { hub.Clients.All.InvokeAsync("ItemUpdated", "problem-list", problem.Id); } return(Result(200, "Patch Succeeded")); } }
public override void OnHackCompleted(HackStatus status) { if (status.Result == HackResult.Succeeded) { // 1. Set the status to be non-hackable DB.ContestProblemLastStatuses .Where(x => x.StatusId == status.JudgeStatusId && x.ContestId == ContestId) .SetField(x => x.IsHackable).WithValue(false) .SetField(x => x.IsHacked).WithValue(true) .Update(); // 2. Add the hack data to problem var input = status.HackDataBlobId.Value; var testCase = DB.TestCases.FirstOrDefault(x => x.InputBlobId == input && x.ProblemId == status.Status.ProblemId); var testCaseExisted = testCase != null; if (!testCaseExisted) { var inputLength = ManagementService.GetBlobAsync(input).Result.Body.Length; var stateMachine = ManagementService.GetStateMachineInstanceAsync(status.RelatedStateMachineIds.Last().StateMachineId).Result; var output = stateMachine.StartedActors.First(x => x.Tag == "Standard").Outputs.First(x => x.Name == "stdout.txt").Id; var outputLength = ManagementService.GetBlobAsync(output).Result.Body.Length; testCase = new TestCase { ContestId = ContestId, InputBlobId = input, InputSizeInByte = inputLength, OutputBlobId = output, OutputSizeInByte = outputLength, ProblemId = status.Status.ProblemId, Type = TestCaseType.Hack }; DB.TestCases.Add(testCase); DB.SaveChanges(); } // 3. Add the result into sub judge status if (!testCaseExisted) { var sub = new SubJudgeStatus { SubId = DB.SubJudgeStatuses.Where(x => x.StatusId == status.JudgeStatusId).Count(), Hint = status.Hint, MemoryUsedInByte = status.MemoryUsedInByte, TimeUsedInMs = status.TimeUsedInMs, Result = status.HackeeResult, InputBlobId = testCase.InputBlobId, OutputBlobId = testCase.OutputBlobId, TestCaseId = testCase.Id, StatusId = status.JudgeStatusId }; DB.SubJudgeStatuses.Add(sub); DB.SaveChanges(); } // 4. Add point for the hacker DB.ContestProblemLastStatuses .Where(x => x.ContestId == ContestId && x.ProblemId == status.Status.ProblemId && x.UserId == status.UserId) .SetField(x => x.Point2).Plus(1) .Update(); // 5. Hack all statuses if (!testCaseExisted && DB.Attendees.Any(x => x.ContestId == ContestId && x.UserId == status.UserId && !x.IsVirtual)) { var affectedStatuses = DB.ContestProblemLastStatuses .Include(x => x.Status) .Where(x => x.ProblemId == status.Status.ProblemId && x.ContestId == ContestId && x.Status.BinaryBlobId.HasValue && x.IsAccepted) .ToList(); var problem = DB.Problems.Single(x => x.Id == status.Status.ProblemId); var validatorId = problem.ValidatorBlobId.HasValue ? problem.ValidatorBlobId.Value : Guid.Parse(Configuration["JoyOI:StandardValidatorBlobId"]); var blobs = new List <BlobInfo>(affectedStatuses.Count + 10); blobs.Add(new BlobInfo { Id = ManagementService.PutBlobAsync("limit.json", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new { UserTime = status.Status.Problem.TimeLimitationPerCaseInMs, PhysicalTime = status.Status.Problem.TimeLimitationPerCaseInMs * 4, Memory = status.Status.Problem.MemoryLimitationPerCaseInByte }))).Result, Name = "limit.json", Tag = "Problem=" + status.Status.ProblemId }); blobs.Add(new BlobInfo(validatorId, problem.ValidatorBlobId.HasValue ? "Validator" + Constants.GetBinaryExtension(problem.ValidatorLanguage) : "Validator.out")); blobs.Add(new BlobInfo(status.HackDataBlobId.Value, "data.txt", testCase.Id.ToString())); blobs.Add(new BlobInfo(testCase.OutputBlobId, "std.txt", testCase.Id.ToString())); foreach (var x in affectedStatuses) { blobs.Add(new BlobInfo(x.Status.BinaryBlobId.Value, "Hackee" + Constants.GetBinaryExtension(x.Status.Language), x.StatusId.ToString())); } ManagementService.PutStateMachineInstanceAsync("HackAllStateMachine", Configuration["ManagementService:CallBack"], blobs, 2); } } else if (status.Result == HackResult.Failed) { DB.ContestProblemLastStatuses .Where(x => x.ContestId == ContestId && x.ProblemId == status.Status.ProblemId && x.UserId == status.UserId) .SetField(x => x.Point2).Subtract(1) .SetField(x => x.Point3).Plus(1) .Update(); } }
public async Task<IActionResult> Put( [FromServices] ContestExecutorFactory cef, [FromServices] ManagementServiceClient mgmt, [FromServices] IHubContext<OnlineJudgeHub> hub, CancellationToken token) { var request = JsonConvert.DeserializeObject<HackRequest>(RequestBody); if (!User.IsSignedIn()) { return Result(403, "Please login first."); } var judge = await DB.JudgeStatuses .Include(x => x.Problem) .SingleOrDefaultAsync(x => x.Id == request.JudgeStatusId, token); if (judge == null) { return Result(404, "The judge status is not found"); } if (!judge.BinaryBlobId.HasValue) { return Result(400, "The lagency status could not be hacked."); } if (judge.UserId == User.Current.Id) { return Result(400, "You cannot hack yourself."); } if (IsGroupRequest() && !await IsGroupMemberAsync(token)) { return Result(401, "You are not a member of this group."); } if (!string.IsNullOrEmpty(request.ContestId)) { var ce = cef.Create(request.ContestId); if (!ce.IsStatusHackable(judge) || !ce.IsContestInProgress()) { return Result(400, "You cannot hack this status"); } if (await DB.HackStatuses.AnyAsync(x => x.UserId == User.Current.Id && x.JudgeStatusId == request.JudgeStatusId && x.Result == HackResult.Succeeded && x.ContestId == request.ContestId, token)) { return Result(400, "You have already hacked this status."); } } // Upload hack data to management service if (request.IsBase64) { request.Data = request.Data.Substring(request.Data.IndexOf("base64,") + "base64,".Length); } var blobId = await mgmt.PutBlobAsync("data.txt", request.IsBase64 ? Convert.FromBase64String(request.Data) : Encoding.UTF8.GetBytes(request.Data), token); var hack = new HackStatus { ContestId = request.ContestId, JudgeStatusId = judge.Id, HackDataBlobId = blobId, Result = HackResult.Pending, Time = DateTime.UtcNow, UserId = User.Current.Id, HackeeResult = JudgeResult.Pending }; DB.HackStatuses.Add(hack); await DB.SaveChangesAsync(token); var blobs = new List<BlobInfo>(10); // Put the limit.json into blob collection blobs.Add(new BlobInfo { Id = await mgmt.PutBlobAsync("limit.json", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new { UserTime = judge.Problem.TimeLimitationPerCaseInMs, PhysicalTime = judge.Problem.TimeLimitationPerCaseInMs * 4, Memory = judge.Problem.MemoryLimitationPerCaseInByte }))), Name = "limit.json", Tag = "Problem=" + judge.ProblemId }); // Put the data into blob collection blobs.Add(new BlobInfo(blobId, "data.txt")); // Put the hackee program into blob collection blobs.Add(new BlobInfo(judge.BinaryBlobId.Value, "Hackee" + Constants.GetBinaryExtension(judge.Language), judge.Id.ToString())); // Put range validator program into blob collection if (judge.Problem.RangeBlobId.HasValue && string.IsNullOrEmpty(judge.Problem.RangeError)) { blobs.Add(new BlobInfo(judge.Problem.RangeBlobId.Value, "Range" + Constants.GetBinaryExtension(judge.Problem.RangeLanguage))); } // Put standard program into blob collection if (judge.Problem.StandardBlobId.HasValue && string.IsNullOrEmpty(judge.Problem.StandardError)) { blobs.Add(new BlobInfo(judge.Problem.StandardBlobId.Value, "Standard" + Constants.GetBinaryExtension(judge.Problem.StandardLanguage))); } else { // Get 3 accepted programs instead of standard program var statuses = await DB.JudgeStatuses .Where(x => x.Result == JudgeResult.Accepted && x.ProblemId == judge.ProblemId && x.BinaryBlobId.HasValue && x.Id != judge.Id) .OrderBy(x => x.TimeUsedInMs) .ThenBy(x => x.MemoryUsedInByte) .Take(3) .ToListAsync(token); if (statuses.Count == 0) { return Result(400, "Missing standard program, this status could not be hacked"); } var standards = statuses.Select(x => new BlobInfo(x.BinaryBlobId.Value, "Standard-" + x.Id.ToString().Substring(0,8) + Constants.GetBinaryExtension(x.Language), x.Id.ToString())); blobs.AddRange(standards); } // Put validator into blob collection if (judge.Problem.ValidatorBlobId.HasValue) { blobs.Add(new BlobInfo(judge.Problem.ValidatorBlobId.Value, "Validator" + Constants.GetBinaryExtension(judge.Problem.ValidatorLanguage))); } else { blobs.Add(new BlobInfo(Guid.Parse(Configuration["JoyOI:StandardValidatorBlobId"]), "Validator.out")); } // Start hack state machine var stateMachineId = await mgmt.PutStateMachineInstanceAsync("HackStateMachine", Configuration["ManagementService:CallBack"], blobs.ToArray(), 1, token); var stateMachine = new StateMachine { CreatedTime = DateTime.Now, Name = "HackStateMachine", Id = stateMachineId }; DB.StateMachines.Add(stateMachine); hack.RelatedStateMachineIds = new List<HackStatusStateMachine>(); hack.RelatedStateMachineIds.Add(new HackStatusStateMachine { StateMachineId = stateMachine.Id, StatusId = judge.Id }); await DB.SaveChangesAsync(token); hub.Clients.All.InvokeAsync("ItemUpdated", "hack", hack.Id); return Result(hack.Id); }
public async Task <ActionResult> Create(int problem_id, string code, int language_id, int?contest_id) { var problem = DbContext.Problems.Find(problem_id); var user = (User)ViewBag.CurrentUser; if (problem == null || (problem.Hide && !IsMaster() && CurrentUser.ID != problem.ID && !contest_id.HasValue)) { return(Content("Problem not existed")); } if (problem.VIP && user.Role < UserRole.VIP && problem.UserID != user.ID) { return(Content("Need VIP")); } Contest contest = new Contest(); if (contest_id != null) { contest = DbContext.Contests.Find(contest_id.Value); if (DateTime.Now < contest.Begin || DateTime.Now >= contest.End) { return(Content("Insufficient permissions")); } if (contest.ContestProblems.Where(x => x.ProblemID == problem_id).Count() == 0) { return(Content("Insufficient permissions")); } if (!Helpers.Contest.UserInContest(user.ID, contest_id.Value)) { return(Content("Insufficient permissions")); } ContestFormat[] SubmitAnyTime = { ContestFormat.ACM, ContestFormat.OI }; if (DateTime.Now < contest.Begin && user.Role < UserRole.Master && contest.UserID != user.ID) { return(Content("Insufficient permissions")); } if (contest.Format == ContestFormat.Codeforces && (from l in DbContext.Locks where l.ProblemID == problem_id && user.ID == l.UserID && l.ContestID == contest_id.Value select l).Count() > 0 && DateTime.Now < contest.End) { return(Content("Locked")); } } var status = new Status { Code = code, LanguageAsInt = language_id, ProblemID = problem_id, UserID = user.ID, Time = DateTime.Now, Result = JudgeResult.Pending, ContestID = contest_id, Score = 0, TimeUsage = 0, MemoryUsage = 0 }; DbContext.Statuses.Add(status); problem.SubmitCount++; user.SubmitCount++; var submitlist = Helpers.AcList.GetList(user.SubmitList); submitlist.Add(problem.ID); user.SubmitList = Helpers.AcList.ToString(submitlist); var _testcase_ids = (from tc in problem.TestCases where tc.Type != TestCaseType.Sample orderby tc.Type ascending select new { tc.ID, tc.InputBlobId }) .ToList(); var testcase_ids = _testcase_ids.Select(x => x.ID).ToList(); if (contest_id != null) { if (DateTime.Now < contest.Begin || DateTime.Now >= contest.End || contest.Format == ContestFormat.ACM || contest.Format == ContestFormat.OI) { testcase_ids = (from tc in problem.TestCases where tc.Type != TestCaseType.Sample orderby tc.Type ascending select tc.ID).ToList(); } else if (contest.Format == ContestFormat.Codeforces) { testcase_ids = (from tc in problem.TestCases where tc.Type == TestCaseType.Unilateralism orderby tc.Type ascending select tc.ID).ToList(); var statuses = (from s in DbContext.Statuses where s.ContestID == contest_id.Value && s.UserID == user.ID select s).ToList(); foreach (var s in statuses) { if (s.JudgeTasks == null) { continue; } foreach (var jt in s.JudgeTasks) { testcase_ids.Add(jt.TestCaseID); } } testcase_ids = testcase_ids.Distinct().ToList(); } foreach (var id in testcase_ids) { DbContext.JudgeTasks.Add(new JudgeTask { StatusID = status.ID, TestCaseID = id, Result = JudgeResult.Pending, MemoryUsage = 0, TimeUsage = 0, Hint = "" }); } DbContext.SaveChanges(); foreach (var jt in status.JudgeTasks) { try { var group = SignalR.JudgeHub.GetNode(); if (group == null) { return(Content("No Online Judger")); } SignalR.JudgeHub.context.Clients.Group(group).Judge(new CodeComb.Judge.Models.JudgeTask(jt)); SignalR.JudgeHub.ThreadBusy(group); } catch { } } SignalR.UserHub.context.Clients.Group("Status").onStatusCreated(new vStatus(status));//推送新状态 if (contest.Format == ContestFormat.OI && DateTime.Now >= contest.Begin && DateTime.Now < contest.End) { return(Content("OI")); } } else // 不是比赛任务 { var distinctSet = new HashSet <string>(); foreach (var id in _testcase_ids) { if (distinctSet.Any(x => x == id.InputBlobId && !string.IsNullOrWhiteSpace(id.InputBlobId))) { continue; } distinctSet.Add(id.InputBlobId); DbContext.JudgeTasks.Add(new JudgeTask { StatusID = status.ID, TestCaseID = id.ID, Result = JudgeResult.Pending, MemoryUsage = 0, TimeUsage = 0, Hint = "" }); } DbContext.SaveChanges(); if (string.IsNullOrWhiteSpace(problem.SpecialJudge) && (status.Language == Language.C || status.Language == Language.Cxx || status.Language == Language.Pascal || status.Language == Language.Cxx11 || status.Language == Language.Cxx14 || status.Language == Language.Java)) // 如果是c,c++,pascal则由JoyOI接管评测 { var sourceName = "Main"; // 拼接选手源代码文件名 if (status.Language == Language.C) { sourceName += ".c"; } else if (status.Language == Language.Cxx) { sourceName += ".cpp"; } else if (status.Language == Language.Cxx11) { sourceName += "11.cpp"; } else if (status.Language == Language.Cxx14) { sourceName += "14.cpp"; } else if (status.Language == Language.Java) { sourceName += ".java"; } else { sourceName += ".pas"; } var blobs = new List <BlobInfo>(20); blobs.Add(new BlobInfo { Id = Guid.Parse("0083ca85-9ede-1004-a386-ac64710fd926"), Name = "Validator.out" }); // 将标准比较器放入文件集合中 var sourceBlobId = await client.PutBlobAsync(sourceName, System.Text.Encoding.UTF8.GetBytes(status.Code)); // 将选手文件上传至Management Service blobs.Add(new BlobInfo { Id = sourceBlobId, Name = sourceName }); // 将选手代码放入文件集合中 // 准备测试用例 var caseIndex = 0; foreach (var jt in status.JudgeTasks) { if (string.IsNullOrWhiteSpace(jt.TestCase.InputBlobId)) // 如果Management Service没有该测试用例则上传 { var inputCaseBlobId = await client.PutBlobAsync("case_input_" + jt.TestCaseID + ".txt", System.Text.Encoding.UTF8.GetBytes(jt.TestCase.Input)); jt.TestCase.InputBlobId = inputCaseBlobId.ToString(); } if (string.IsNullOrWhiteSpace(jt.TestCase.OutputBlobId)) // 如果Management Service没有该测试用例则上传 { var outputCaseBlobId = await client.PutBlobAsync("case_output_" + jt.TestCaseID + ".txt", System.Text.Encoding.UTF8.GetBytes(jt.TestCase.Output)); jt.TestCase.OutputBlobId = outputCaseBlobId.ToString(); } if (!blobs.Any(x => x.Id == Guid.Parse(jt.TestCase.InputBlobId))) { blobs.Add(new BlobInfo { Id = Guid.Parse(jt.TestCase.InputBlobId), Name = "input_" + caseIndex + ".txt" }); blobs.Add(new BlobInfo { Id = Guid.Parse(jt.TestCase.OutputBlobId), Name = "output_" + caseIndex + ".txt" }); } else { continue; } ++caseIndex; } var stateMachineId = await client.PutStateMachineInstanceAsync("TyvjJudgeStateMachine", "http://tyvj.cn", blobs); // 创建StateMachine实例 status.StateMachineId = stateMachineId.ToString(); DbContext.SaveChanges(); } else { foreach (var jt in status.JudgeTasks) { try { var group = SignalR.JudgeHub.GetNode(); if (group == null) { return(Content("No Online Judger")); } SignalR.JudgeHub.context.Clients.Group(group).Judge(new CodeComb.Judge.Models.JudgeTask(jt)); SignalR.JudgeHub.ThreadBusy(group); } catch { } } } SignalR.UserHub.context.Clients.Group("Status").onStatusCreated(new vStatus(status));//推送新状态 } SignalR.UserHub.context.Clients.Group("Status").onStatusChanged(new vStatus(status)); GC.Collect(); return(Content(status.ID.ToString())); }