예제 #1
0
        /// <summary>
        /// 添加比赛
        /// </summary>
        /// <param name="contest"></param>
        /// <exception cref="UserNotLoginException"></exception>
        /// <exception cref="PermissionDeniedException"></exception>
        /// <exception cref="ContestNameExistedException"></exception>
        public static void Add(Contest contest)
        {
            if (null == User.CurrentUser)
                throw new UserNotLoginException();
            if (!contest.Owners.Contains(User.CurrentUser.name))
                throw new PermissionDeniedException();
            using (var db = new CHDB())
            {
                if (contest.IsOfficial && !User.CurrentUser.IsAdmin
                    && User.ByName(User.CurrentUser.name).Rating < 2100)
                    throw new PermissionDeniedException();
                contest.Name = Helper.GetLegalName(contest.Name);
                if ((from c in db.CONTESTs
                     where c.Name == contest.Name
                     select c).Any())
                    throw new ContestNameExistedException();
                var curContest = db.CONTESTs.Add(new CONTEST()
                {
                    ID = Guid.NewGuid(),
                    Name = Helper.GetLegalName(contest.Name),
                    StartTime = contest.AbsoluteStartTime,
                    EndTime = contest.AbsoluteEndTime,
                    Description = contest.Description,
                    Type = (int)contest.Type,
                    IsOfficial = contest.IsOfficial,
                    Weight = User.CurrentUser.IsAdmin ? contest.Weight : 16
                });

                foreach (string name in contest.Owners)
                {
                    curContest.OWNERs.Add(
                        (from u in db.USERs
                         where u.Name == name
                         select u).Single()
                        );
                }

                db.SaveChanges();
            }
        }
        List<TestCase> AddTestCase(Contest contest, Problem problem, HttpPostedFileBase file)
        {
            if (file == null)
            {
                ModelState.AddModelError("File", "请选择文件");
                return null;
            }
            Dictionary<int, byte[]> inputFiles = new Dictionary<int, byte[]>();
            Dictionary<int, byte[]> outputFiles = new Dictionary<int, byte[]>();

            if (new[] { "application/zip", "application/x-zip-compressed", "application/x-zip" }.Contains(file.ContentType)
                || file.ContentType == "application/octet-stream" && file.FileName.EndsWith(".zip", StringComparison.OrdinalIgnoreCase))
            {
                using (ZipInputStream stream = new ZipInputStream(file.InputStream))
                {
                    ZipEntry entry;
                    while ((entry = stream.GetNextEntry()) != null)
                    {
                        byte[] bytes;
                        using (MemoryStream mem = new MemoryStream())
                        {
                            stream.CopyTo(mem);
                            bytes = mem.ToArray();
                        }
                        if (!DealEntry(entry.Name, bytes, inputFiles, outputFiles))
                        {
                            return null;
                        }
                    }
                }
            }
            else if (file.FileName.EndsWith(".tgz") || file.FileName.EndsWith(".tar.gz"))
            {
                using (GZipStream stream = new GZipStream(file.InputStream, CompressionMode.Decompress))
                {
                    using (TarInputStream tar = new TarInputStream(stream))
                    {
                        TarEntry entry;
                        while ((entry = tar.GetNextEntry()) != null)
                        {
                            byte[] bytes;
                            using (MemoryStream mem = new MemoryStream())
                            {
                                tar.CopyTo(mem);
                                bytes = mem.ToArray();
                            }
                            if (!DealEntry(entry.Name, bytes, inputFiles, outputFiles))
                            {
                                return null;
                            }
                        }
                    }
                }
            }
            else if (file.FileName.EndsWith(".tar.bz2"))
            {
                using (BZip2InputStream stream = new BZip2InputStream(file.InputStream))
                {
                    using (TarInputStream tar = new TarInputStream(stream))
                    {
                        TarEntry entry;
                        while ((entry = tar.GetNextEntry()) != null)
                        {
                            byte[] bytes;
                            using (MemoryStream mem = new MemoryStream())
                            {
                                tar.CopyTo(mem);
                                bytes = mem.ToArray();
                            }
                            if (!DealEntry(entry.Name, bytes, inputFiles, outputFiles))
                            {
                                return null;
                            }
                        }
                    }
                }
            }
            else
            {
                ModelState.AddModelError("File", "不支持的压缩文件类型");
                return null;
            }

            if (!inputFiles.Keys.OrderBy(x => x).SequenceEqual(outputFiles.Keys.OrderBy(x => x)))
            {
                ModelState.AddModelError("File", "输入与输出文件没有一一对应");
                return null;
            }

            var testCases = inputFiles.Keys.Select(id => new TestCase
                {
                    Input = inputFiles[id],
                    Data = outputFiles[id],
                    MemoryLimit = DEFAULT_TEST_CASE_MEMORY_LIMIT,
                    TimeLimit = DEFAULT_TEST_CASE_TIME_LIMIT,
                    Available = contest.Type == Contest.ContestType.CF ? false : true
                }).ToList();
            foreach (var t in testCases)
            {
                t.ID = problem.AddTestCase(t);
            }
            return testCases;
        }