public TaskFeedback_Compile Compile(Problem problem, Record record) { if (!Authenticated) throw new FaultException<AccessDeniedError>(new AccessDeniedError()); return Env.Run(new Task { Problem = problem, Record = record, Type = TaskType.Compile },Callback) as TaskFeedback_Compile; }
public TaskFeedback_Hack Hack(Problem problem, Record record, Hack hack) { if (!Authenticated) throw new FaultException<AccessDeniedError>(new AccessDeniedError()); return Env.Run(new Task { Problem = problem, Record = record, Hack = hack, Type = TaskType.Hack }, Callback) as TaskFeedback_Hack; }
public int CreateProblem(int contestID, string title, string content, int score, int timeLimit, long memoryLimit, string std, string spj, string validator, ProgrammingLanguage? stdLanguage, ProgrammingLanguage? spjLanguage, ProgrammingLanguage? validatorLanguage, IEnumerable<ProgrammingLanguage> forbiddenLanguages) { using (DB db = new DB()) { CheckRole(db, UserRole.Manager); if (db.Contests.Find(contestID) == null) throw new FaultException<NotFoundError>(new NotFoundError { ID = contestID, Type = "Contest" }); Problem problem = new Problem { Title = title, Content = content, Score = score, ContestID = contestID, TimeLimit = timeLimit, MemoryLimit = memoryLimit, Std = std, Spj = spj, Validator = validator, StdLanguage = stdLanguage, SpjLanguage = spjLanguage, ValidatorLanguage = validatorLanguage, ForbiddenLanguages = forbiddenLanguages }; db.Problems.Add(problem); db.SaveChanges(); Bll.StandingsCache.Rebuild(problem.ContestID);//添加或删除题目后需要重新构建排名,这里必须是一个同步事件 foreach (var client in App.Clients.Values) { System.Threading.Tasks.Task.Factory.StartNew(() => client.Callback.RebuildStandings(problem.ContestID, StandingsCache.Standings[contestID] as List<Entity.StandingItem>)); } return problem.ID; } }
private void DoJudgeHack(int hackID) { using (DB db = new DB()) { Contest contest; Problem problem; Record record; Hack hack; var h = db.Hacks.Find(hackID); if (h == null) return; if (h.Status != HackStatus.Pending) return; h.Status = Entity.HackStatus.Running; db.SaveChanges(); hack = new Hack { ID = h.ID, DatamakerLanguage = h.DatamakerLanguage, DataOrDatamaker = h.DataOrDatamaker, HackeeID = h.Record.UserID, HackeeNickName = h.Record.User.NickName, HackerID = h.HackerID, HackerNickName = h.Hacker.NickName, RecordID = h.RecordID, Status = HackStatus.Running }; var r = h.Record; record = new Record { ID = r.ID, Code = r.Code, Language = r.Language, ProblemID = r.ProblemID, ProblemTitle = r.Problem.Title, Status = RecordStatus.Running, SubmissionTime = r.SubmissionTime, UserID = r.UserID, UserNickName = r.UserNickName }; var p = r.Problem; problem = new Problem { ID = p.ID, ContestID = p.ContestID, ContestTitle = p.Contest.Title, ForbiddenLanguages = p.ForbiddenLanguages, MemoryLimit = p.MemoryLimit, Score = p.Score, Spj = p.Spj, SpjLanguage = p.SpjLanguage, Std = p.Std, StdLanguage = p.StdLanguage, TestCasesCount = p.TestCases.Count, TimeLimit = p.TimeLimit, Title = p.Title, Validator = p.Validator, ValidatorLanguage = p.ValidatorLanguage }; using (var conn = GetFreestNode()) { var ret = conn.Hack(problem, record, hack); h.Status = ret.HackStatus; if (ret.HackStatus == HackStatus.Success) { h.Record.Status = RecordStatus.Hacked; var inputHash = MD5.Create().ComputeHash(ret.HackData.Input); var outputHash = MD5.Create().ComputeHash(ret.HackData.Output); bool existed = (from t in db.TestCases where t.ProblemID == p.ID && t.InputHash == inputHash select t).Any(); if (!existed) { var hackTestCase = new TestCase { Input = ret.HackData.Input, InputHash = inputHash, Output = ret.HackData.Output, OutputHash = outputHash, ProblemID = p.ID, Type = TestCaseType.Systemtest }; db.TestCases.Add(hackTestCase); db.SaveChanges(); hack.GeneratedTestCaseID = hackTestCase.ID; } } else { h.Detail = ret.CompilerOutput; } db.SaveChanges(); } } }
private void DoJudgeRecord(int recordID) { using (DB db = new DB()) { Contest contest; Problem problem; Record record; StringBuilder detail = new StringBuilder(); var r = db.Records.Find(recordID); if (r == null) return; if (r.Status != RecordStatus.Pending) return; r.Status = Entity.RecordStatus.Running; db.SaveChanges(); record = new Record { ID = r.ID, Code = r.Code, Language = r.Language, ProblemID = r.ProblemID, ProblemTitle = r.Problem.Title, Status = RecordStatus.Running, SubmissionTime = r.SubmissionTime, UserID = r.UserID, UserNickName = r.UserNickName }; var p = r.Problem; problem = new Problem { ID = p.ID, ContestID = p.ContestID, ContestTitle = p.Contest.Title, ForbiddenLanguages = p.ForbiddenLanguages, MemoryLimit = p.MemoryLimit, Score = p.Score, Spj = p.Spj, SpjLanguage = p.SpjLanguage, Std = p.Std, StdLanguage = p.StdLanguage, TestCasesCount = p.TestCases.Count, TimeLimit = p.TimeLimit, Title = p.Title, Validator = p.Validator, ValidatorLanguage = p.ValidatorLanguage }; contest = p.Contest; using (var node = GetFreestNode()) { var ret = node.Compile(problem, record); if (ret.RecordStatus == RecordStatus.SystemError) { System.Threading.Thread.Sleep(3000); App.Server.Rejudge(record.ID); return; } if (ret.RecordStatus != RecordStatus.Accepted) { r.Status = ret.RecordStatus; r.Detail = ret.CompilerOutput; db.SaveChanges(); return; } detail.AppendLine(ret.CompilerOutput); var testCases = from t in db.TestCases where t.ProblemID == problem.ID select t; if ((contest.Type == ContestType.Codeforces || contest.Type == ContestType.TopCoder) && contest.EndTime > DateTime.Now) { testCases = testCases.Where(t => t.TypeAsInt == (int)TestCaseType.Pretest); testCases = testCases.Union(from h in db.Hacks where h.Record.UserID == record.UserID && h.StatusAsInt == (int)HackStatus.Success && h.GeneratedTestCase != null && h.GeneratedTestCase.ProblemID == problem.ID select h.GeneratedTestCase); } var testCaseIDs = testCases.Select(t => t.ID); List<Task<TaskFeedback_Run>> runs = new List<Task<TaskFeedback_Run>>(); foreach (var id in testCaseIDs) { var _id = id; var run = System.Threading.Tasks.Task.Factory.StartNew(() => { return node.Run(problem, record, _id); }); runs.Add(run); } System.Threading.Tasks.Task.WaitAll(runs.ToArray()); RecordStatus finalStatus = RecordStatus.Accepted; int totalTime = 0; long maxMemory = 0; int account = 0; for (int i = 0; i < runs.Count; i++) { var result = runs[i].Result; if (result.RecordStatus == RecordStatus.SystemError) { System.Threading.Thread.Sleep(3000); App.Server.Rejudge(result.RecordID); return; } detail.AppendFormat("#{0} {1} ({2} ms, {3} KiB)\r\n", i, result.RecordStatus, result.TimeUsage, result.MemUsage / 1024); if (result.RecordStatus > finalStatus) { finalStatus = result.RecordStatus; } if (result.RecordStatus == RecordStatus.Accepted) account++; totalTime += result.TimeUsage; maxMemory = Math.Max((long)result.MemUsage, maxMemory); } r.Status = finalStatus; if (finalStatus == RecordStatus.Accepted) { r.Score = 100; } else { if (testCases.Count() == 0) r.Score = 0; else r.Score = 100 * account / testCases.Count(); } r.TimeUsage = totalTime; r.MemoryUsage = maxMemory; r.Detail = detail.ToString(); db.SaveChanges(); } } }
public TaskFeedback_Run Run(Problem problem, Record record, int testCaseID) { if (!Authenticated) throw new FaultException<AccessDeniedError>(new AccessDeniedError()); return Env.Run(new Task { Problem = problem, Record = record, TestCaseID = testCaseID, Type = TaskType.Run }, Callback) as TaskFeedback_Run; }