예제 #1
0
 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;
 }
예제 #2
0
 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;
 }
예제 #3
0
        public int Submit(int problemID, string code, ProgrammingLanguage language)
        {
            using (DB db = new DB())
            {
                CheckRole(db, UserRole.Competitor);

                var problem = db.Problems.Find(problemID);
                if (problem == null)
                    throw new FaultException<NotFoundError>(new NotFoundError { ID = problemID, Type = "Problem" });

                // Out of contest time
                if (CurrentUser.Role == UserRole.Competitor && (problem.Contest.StartTime > DateTime.Now || problem.Contest.EndTime < DateTime.Now))
                    throw new FaultException<AccessDeniedError>(new AccessDeniedError());

                // After TC rest time
                if (problem.Contest.Type == ContestType.TopCoder && CurrentUser.Role == UserRole.Competitor && problem.Contest.RestTime < DateTime.Now)
                    throw new FaultException<AccessDeniedError>(new AccessDeniedError(), "After tc rest time");

                // CF Locked
                if (problem.Contest.Type == ContestType.Codeforces && CurrentUser.Role == UserRole.Competitor && problem.LockedUsers.Contains(CurrentUser))
                    throw new FaultException<AccessDeniedError>(new AccessDeniedError(), "problem locked");

                var record = new Record
                {
                    Code = code,
                    Language = language,
                    ProblemID = problemID,
                    Status = RecordStatus.Pending,
                    SubmissionTime = DateTime.Now,
                    UserID = CurrentUser.ID,
                    UserNickName = CurrentUser.NickName,
                    Score = 0
                };

                db.Records.Add(record);
                db.SaveChanges();
                if (NewRecord != null)
                    System.Threading.Tasks.Task.Factory.StartNew(() => NewRecord(record.ID));
                return record.ID;
            }
        }
예제 #4
0
        public void NewRecord(int recordID)
        {
            using (DB db = new DB())
            {
                Record record = db.Records.Find(recordID);
                Record r = new Record
                {
                    ID = record.ID,
                    Code = record.Code,
                    Detail = record.Detail,
                    Language = record.Language,
                    MemoryUsage = record.MemoryUsage,
                    ProblemID = record.ProblemID,
                    ProblemTitle = record.Problem.Title,
                    Score = record.Score,
                    Status = record.Status,
                    SubmissionTime = record.SubmissionTime,
                    TimeUsage = record.TimeUsage,
                    UserID = record.UserID,
                    UserNickName = record.UserNickName
                };

                foreach (var s in App.Clients.Values.Where(s => s.SessionMode == LocalCenaServer.SessionType.Server))
                {
                    System.Threading.Tasks.Task.Factory.StartNew(() => s.Callback.NewRecord(r));
                }
            }
        }
예제 #5
0
파일: Judger.cs 프로젝트: wan-qy/CenaPlus
        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();
                }
            }
        }
예제 #6
0
파일: Judger.cs 프로젝트: wan-qy/CenaPlus
        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();
                }
            }
        }
예제 #7
0
 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;
 }