Search in sources :

Example 1 with Problem

use of top.hcode.hoj.pojo.entity.problem.Problem in project HOJ by HimitZH.

the class JudgeController method submitProblemJudge.

@PostMapping(value = "/judge")
public CommonResult submitProblemJudge(@RequestBody ToJudge toJudge) {
    if (!toJudge.getToken().equals(judgeToken)) {
        return CommonResult.errorResponse("对不起!您使用的判题服务调用凭证不正确!访问受限!", CommonResult.STATUS_ACCESS_DENIED);
    }
    Judge judge = toJudge.getJudge();
    if (judge == null || judge.getSubmitId() == null || judge.getUid() == null || judge.getPid() == null) {
        return CommonResult.errorResponse("调用参数错误!请检查您的调用参数!", CommonResult.STATUS_FAIL);
    }
    // 标志该判题过程进入编译阶段
    judge.setStatus(Constants.Judge.STATUS_COMPILING.getStatus());
    // 写入当前判题服务的名字
    judge.setJudger(name);
    judgeService.updateById(judge);
    // 进行判题操作
    Problem problem = problemService.getById(judge.getPid());
    Judge finalJudge = judgeService.Judge(problem, judge);
    // 更新该次提交
    judgeService.updateById(finalJudge);
    if (finalJudge.getStatus().intValue() != Constants.Judge.STATUS_SUBMITTED_FAILED.getStatus()) {
        // 更新其它表
        judgeService.updateOtherTable(finalJudge.getSubmitId(), finalJudge.getStatus(), finalJudge.getCid(), finalJudge.getUid(), finalJudge.getPid(), finalJudge.getScore(), finalJudge.getTime());
    }
    return CommonResult.successResponse(finalJudge, "判题机评测完成!");
}
Also used : Problem(top.hcode.hoj.pojo.entity.problem.Problem) ToJudge(top.hcode.hoj.pojo.entity.judge.ToJudge) Judge(top.hcode.hoj.pojo.entity.judge.Judge)

Example 2 with Problem

use of top.hcode.hoj.pojo.entity.problem.Problem in project HOJ by HimitZH.

the class JudgeController method resubmit.

/**
 * @MethodName resubmit
 * @Params * @param null
 * @Description 调用判题服务器提交失败超过60s后,用户点击按钮重新提交判题进入的方法
 * @Return
 * @Since 2021/2/12
 */
@RequiresAuthentication
@GetMapping(value = "/resubmit")
@Transactional(rollbackFor = Exception.class)
public CommonResult resubmit(@RequestParam("submitId") Long submitId, HttpServletRequest request) {
    Judge judge = judgeService.getById(submitId);
    if (judge == null) {
        return CommonResult.errorResponse("此提交数据不存在!");
    }
    HttpSession session = request.getSession();
    UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo");
    if (!judge.getUid().equals(userRolesVo.getUid())) {
        // 不是本人无法重新提交
        return CommonResult.errorResponse("对不起!您并非提交数据的本人,无法重新提交!");
    }
    Problem problem = problemService.getById(judge.getPid());
    // 如果是非比赛题目
    if (judge.getCid() == 0) {
        // 如果该题已经是AC通过状态,更新该题目的用户ac做题表 user_acproblem
        if (judge.getStatus().intValue() == Constants.Judge.STATUS_ACCEPTED.getStatus().intValue()) {
            QueryWrapper<UserAcproblem> userAcproblemQueryWrapper = new QueryWrapper<>();
            userAcproblemQueryWrapper.eq("submit_id", judge.getSubmitId());
            userAcproblemService.remove(userAcproblemQueryWrapper);
        }
    } else {
        if (problem.getIsRemote()) {
            // 将对应比赛记录设置成默认值
            UpdateWrapper<ContestRecord> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("submit_id", submitId).setSql("status=null,score=null");
            contestRecordService.update(updateWrapper);
        } else {
            return CommonResult.errorResponse("错误!非vJudge题目在比赛过程无权限重新提交");
        }
    }
    boolean isHasSubmitIdRemoteRejudge = false;
    if (Objects.nonNull(judge.getVjudgeSubmitId()) && (judge.getStatus().intValue() == Constants.Judge.STATUS_SUBMITTED_FAILED.getStatus() || judge.getStatus().intValue() == Constants.Judge.STATUS_PENDING.getStatus() || judge.getStatus().intValue() == Constants.Judge.STATUS_JUDGING.getStatus() || judge.getStatus().intValue() == Constants.Judge.STATUS_COMPILING.getStatus() || judge.getStatus().intValue() == Constants.Judge.STATUS_SYSTEM_ERROR.getStatus())) {
        isHasSubmitIdRemoteRejudge = true;
    }
    // 重新进入等待队列
    judge.setStatus(Constants.Judge.STATUS_PENDING.getStatus());
    judge.setVersion(judge.getVersion() + 1);
    judge.setErrorMessage(null).setOiRankScore(null).setScore(null).setTime(null).setJudger("").setMemory(null);
    judgeService.updateById(judge);
    // 将提交加入任务队列
    if (problem.getIsRemote()) {
        // 如果是远程oj判题
        remoteJudgeDispatcher.sendTask(judge, judgeToken, problem.getProblemId(), judge.getCid() != 0, isHasSubmitIdRemoteRejudge);
    } else {
        judgeDispatcher.sendTask(judge, judgeToken, judge.getCid() != 0);
    }
    return CommonResult.successResponse(judge, "重新提交成功!");
}
Also used : UpdateWrapper(com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper) QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) HttpSession(javax.servlet.http.HttpSession) UserRolesVo(top.hcode.hoj.pojo.vo.UserRolesVo) ContestRecord(top.hcode.hoj.pojo.entity.contest.ContestRecord) Problem(top.hcode.hoj.pojo.entity.problem.Problem) UserAcproblem(top.hcode.hoj.pojo.entity.user.UserAcproblem) Judge(top.hcode.hoj.pojo.entity.judge.Judge) RequiresAuthentication(org.apache.shiro.authz.annotation.RequiresAuthentication) Transactional(org.springframework.transaction.annotation.Transactional)

Example 3 with Problem

use of top.hcode.hoj.pojo.entity.problem.Problem in project HOJ by HimitZH.

the class JudgeController method getALLCaseResult.

/**
 * @MethodName getJudgeCase
 * @Params * @param null
 * @Description 获得指定提交id的测试样例结果,暂不支持查看测试数据,只可看测试点结果,时间,空间,或者IO得分
 * @Return
 * @Since 2020/10/29
 */
@GetMapping("/get-all-case-result")
public CommonResult getALLCaseResult(@RequestParam(value = "submitId", required = true) Long submitId, HttpServletRequest request) {
    Judge judge = judgeService.getById(submitId);
    if (judge == null) {
        return CommonResult.errorResponse("此提交数据不存在!");
    }
    Problem problem = problemService.getById(judge.getPid());
    // 如果该题不支持开放测试点结果查看
    if (!problem.getOpenCaseResult()) {
        return CommonResult.successResponse(null, "对不起,该题测试样例详情不支持开放!");
    }
    HttpSession session = request.getSession();
    UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo");
    // 是否为超级管理员
    boolean isRoot = SecurityUtils.getSubject().hasRole("root");
    if (judge.getCid() != 0 && userRolesVo != null && !isRoot) {
        Contest contest = contestService.getById(judge.getCid());
        // 如果不是比赛管理员 比赛封榜不能看
        if (!contest.getUid().equals(userRolesVo.getUid())) {
            // 当前是比赛期间 同时处于封榜时间
            if (contest.getSealRank() && contest.getStatus().intValue() == Constants.Contest.STATUS_RUNNING.getCode() && contest.getSealRankTime().before(new Date())) {
                return CommonResult.successResponse(null, "对不起,该题测试样例详情不能查看!");
            }
            // 若是比赛题目,只支持OI查看测试点情况,ACM强制禁止查看,比赛管理员除外
            if (problem.getType().intValue() == Constants.Contest.TYPE_ACM.getCode()) {
                return CommonResult.successResponse(null, "对不起,该题测试样例详情不能查看!");
            }
        }
    }
    QueryWrapper<JudgeCase> wrapper = new QueryWrapper<>();
    if (userRolesVo == null || (!isRoot && !SecurityUtils.getSubject().hasRole("admin") && !SecurityUtils.getSubject().hasRole("problem_admin"))) {
        wrapper.select("time", "memory", "score", "status", "user_output");
    }
    wrapper.eq("submit_id", submitId).last("order by length(input_data) asc,input_data asc");
    // 当前所有测试点只支持 空间 时间 状态码 IO得分 输出文件名 输入文件名和错误信息提示查看而已
    List<JudgeCase> judgeCaseList = judgeCaseService.list(wrapper);
    if (judgeCaseList.isEmpty()) {
        // 未查询到一条数据
        return CommonResult.successResponse(null, "暂无数据");
    } else {
        return CommonResult.successResponse(judgeCaseList, "获取成功");
    }
}
Also used : JudgeCase(top.hcode.hoj.pojo.entity.judge.JudgeCase) QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) HttpSession(javax.servlet.http.HttpSession) UserRolesVo(top.hcode.hoj.pojo.vo.UserRolesVo) Problem(top.hcode.hoj.pojo.entity.problem.Problem) Contest(top.hcode.hoj.pojo.entity.contest.Contest) Judge(top.hcode.hoj.pojo.entity.judge.Judge)

Example 4 with Problem

use of top.hcode.hoj.pojo.entity.problem.Problem in project HOJ by HimitZH.

the class AdminTrainingController method importTrainingRemoteOJProblem.

@GetMapping("/import-remote-oj-problem")
@RequiresAuthentication
@RequiresRoles(value = { "root", "admin", "problem_admin" }, logical = Logical.OR)
@Transactional(rollbackFor = Exception.class)
public CommonResult importTrainingRemoteOJProblem(@RequestParam("name") String name, @RequestParam("problemId") String problemId, @RequestParam("tid") Long tid, HttpServletRequest request) {
    QueryWrapper<Problem> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("problem_id", name.toUpperCase() + "-" + problemId);
    Problem problem = problemService.getOne(queryWrapper, false);
    // 如果该题目不存在,需要先导入
    if (problem == null) {
        HttpSession session = request.getSession();
        UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo");
        try {
            ProblemStrategy.RemoteProblemInfo otherOJProblemInfo = problemService.getOtherOJProblemInfo(name.toUpperCase(), problemId, userRolesVo.getUsername());
            if (otherOJProblemInfo != null) {
                problem = problemService.adminAddOtherOJProblem(otherOJProblemInfo, name);
                if (problem == null) {
                    return CommonResult.errorResponse("导入新题目失败!请重新尝试!");
                }
            } else {
                return CommonResult.errorResponse("导入新题目失败!原因:可能是与该OJ链接超时或题号格式错误!");
            }
        } catch (Exception e) {
            return CommonResult.errorResponse(e.getMessage());
        }
    }
    QueryWrapper<TrainingProblem> trainingProblemQueryWrapper = new QueryWrapper<>();
    Problem finalProblem = problem;
    trainingProblemQueryWrapper.eq("tid", tid).and(wrapper -> wrapper.eq("pid", finalProblem.getId()).or().eq("display_id", finalProblem.getProblemId()));
    TrainingProblem trainingProblem = trainingProblemService.getOne(trainingProblemQueryWrapper, false);
    if (trainingProblem != null) {
        return CommonResult.errorResponse("添加失败,该题目已添加或者题目的训练展示ID已存在!", CommonResult.STATUS_FAIL);
    }
    TrainingProblem newTProblem = new TrainingProblem();
    boolean result = trainingProblemService.saveOrUpdate(newTProblem.setTid(tid).setPid(problem.getId()).setDisplayId(problem.getProblemId()));
    if (result) {
        // 添加成功
        trainingRegisterService.syncAlreadyRegisterUserRecord(tid, problem.getId(), newTProblem.getId());
        return CommonResult.successResponse(null, "添加成功!");
    } else {
        return CommonResult.errorResponse("添加失败", CommonResult.STATUS_FAIL);
    }
}
Also used : QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) HttpSession(javax.servlet.http.HttpSession) UserRolesVo(top.hcode.hoj.pojo.vo.UserRolesVo) Problem(top.hcode.hoj.pojo.entity.problem.Problem) TrainingProblem(top.hcode.hoj.pojo.entity.training.TrainingProblem) ProblemStrategy(top.hcode.hoj.crawler.problem.ProblemStrategy) TrainingProblem(top.hcode.hoj.pojo.entity.training.TrainingProblem) RequiresAuthentication(org.apache.shiro.authz.annotation.RequiresAuthentication) RequiresRoles(org.apache.shiro.authz.annotation.RequiresRoles) Transactional(org.springframework.transaction.annotation.Transactional)

Example 5 with Problem

use of top.hcode.hoj.pojo.entity.problem.Problem in project HOJ by HimitZH.

the class ImportFpsController method parseFps.

private List<ProblemDto> parseFps(InputStream inputStream, String username) throws IOException {
    Document document = XmlUtil.readXML(inputStream);
    Element rootElement = XmlUtil.getRootElement(document);
    String version = rootElement.getAttribute("version");
    List<ProblemDto> problemDtoList = new ArrayList<>();
    String fileDirId = IdUtil.simpleUUID();
    String fileDir = Constants.File.TESTCASE_TMP_FOLDER.getPath() + File.separator + fileDirId;
    int index = 1;
    for (Element item : XmlUtil.getElements(rootElement, "item")) {
        Problem problem = new Problem();
        problem.setAuthor(username).setType(0).setIsUploadCase(true).setDifficulty(1).setIsRemoveEndBlank(true).setOpenCaseResult(true).setCodeShare(false).setIsRemote(false).setAuth(1).setProblemId(String.valueOf(System.currentTimeMillis()));
        Element title = XmlUtil.getElement(item, "title");
        // 标题
        problem.setTitle(title.getTextContent());
        HashMap<String, String> srcMapUrl = new HashMap<>();
        List<Element> images = XmlUtil.getElements(item, "img");
        for (Element img : images) {
            Element srcElement = XmlUtil.getElement(img, "src");
            if (srcElement == null) {
                continue;
            }
            String src = srcElement.getTextContent();
            String base64 = XmlUtil.getElement(img, "base64").getTextContent();
            String[] split = src.split("\\.");
            byte[] decode = Base64.getDecoder().decode(base64);
            String fileName = IdUtil.fastSimpleUUID() + "." + split[split.length - 1];
            FileUtil.writeBytes(decode, Constants.File.MARKDOWN_FILE_FOLDER.getPath() + File.separator + fileName);
            srcMapUrl.put(src, Constants.File.IMG_API.getPath() + fileName);
        }
        Element descriptionElement = XmlUtil.getElement(item, "description");
        String description = descriptionElement.getTextContent();
        for (Map.Entry<String, String> entry : srcMapUrl.entrySet()) {
            description = description.replaceAll(entry.getKey(), entry.getValue());
        }
        // 题目描述
        problem.setDescription(description);
        Element inputElement = XmlUtil.getElement(item, "input");
        String input = inputElement.getTextContent();
        for (Map.Entry<String, String> entry : srcMapUrl.entrySet()) {
            input = input.replaceAll(entry.getKey(), entry.getValue());
        }
        // 输入描述
        problem.setInput(input);
        Element outputElement = XmlUtil.getElement(item, "output");
        String output = outputElement.getTextContent();
        for (Map.Entry<String, String> entry : srcMapUrl.entrySet()) {
            output = output.replaceAll(entry.getKey(), entry.getValue());
        }
        // 输出描述
        problem.setOutput(output);
        // 提示
        Element hintElement = XmlUtil.getElement(item, "hint");
        String hint = hintElement.getTextContent();
        for (Map.Entry<String, String> entry : srcMapUrl.entrySet()) {
            hint = hint.replaceAll(entry.getKey(), entry.getValue());
        }
        problem.setHint(hint);
        // 来源
        Element sourceElement = XmlUtil.getElement(item, "source");
        String source = sourceElement.getTextContent();
        problem.setSource(source);
        // ms
        Integer timeLimit = getTimeLimit(version, item);
        problem.setTimeLimit(timeLimit);
        // mb
        Integer memoryLimit = getMemoryLimit(item);
        problem.setMemoryLimit(memoryLimit);
        // 题面用例
        List<Element> sampleInputs = XmlUtil.getElements(item, "sample_input");
        List<Element> sampleOutputs = XmlUtil.getElements(item, "sample_output");
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < sampleInputs.size(); i++) {
            sb.append("<input>").append(sampleInputs.get(i).getTextContent()).append("</input>");
            sb.append("<output>").append(sampleOutputs.get(i).getTextContent()).append("</output>");
        }
        problem.setExamples(sb.toString());
        QueryWrapper<Language> languageQueryWrapper = new QueryWrapper<>();
        languageQueryWrapper.eq("oj", "ME");
        List<Language> languageList = languageService.list(languageQueryWrapper);
        HashMap<String, Long> languageMap = new HashMap<>();
        for (Language language : languageList) {
            languageMap.put(language.getName(), language.getId());
        }
        // 题目模板
        List<Element> templateNodes = XmlUtil.getElements(item, "template");
        List<CodeTemplate> codeTemplates = new ArrayList<>();
        for (Element templateNode : templateNodes) {
            String templateLanguage = templateNode.getAttribute("language");
            String templateCode = templateNode.getTextContent();
            if (templateLanguage == null || templateCode == null) {
                continue;
            }
            String lang = fpsMapHOJ.get(templateLanguage);
            if (lang != null) {
                codeTemplates.add(new CodeTemplate().setCode(templateCode).setLid(languageMap.get(lang)));
            }
        }
        // spj
        Element spjNode = XmlUtil.getElement(item, "spj");
        if (spjNode != null) {
            String spjLanguage = spjNode.getAttribute("language");
            String spjCode = spjNode.getTextContent();
            if (("C".equals(spjLanguage) || "C++".equals(spjLanguage)) && !StringUtils.isEmpty(spjCode)) {
                problem.setSpjLanguage(spjLanguage).setSpjCode(spjCode);
            }
        }
        // 题目评测数据
        List<Element> testInputs = XmlUtil.getElements(item, "test_input");
        List<Element> testOutputs = XmlUtil.getElements(item, "test_output");
        List<ProblemCase> problemSamples = new LinkedList<>();
        String problemTestCaseDir = fileDir + File.separator + index;
        for (int i = 0; i < testInputs.size(); i++) {
            String infileName = (i + 1) + ".in";
            String outfileName = (i + 1) + ".out";
            FileWriter infileWriter = new FileWriter(problemTestCaseDir + File.separator + infileName);
            FileWriter outfileWriter = new FileWriter(problemTestCaseDir + File.separator + outfileName);
            infileWriter.write(testInputs.get(i).getTextContent());
            outfileWriter.write(testOutputs.get(i).getTextContent());
            problemSamples.add(new ProblemCase().setInput(infileName).setOutput(outfileName));
        }
        String mode = Constants.JudgeMode.DEFAULT.getMode();
        if (problem.getSpjLanguage() != null) {
            mode = Constants.JudgeMode.SPJ.getMode();
        }
        ProblemDto problemDto = new ProblemDto();
        problemDto.setSamples(problemSamples).setIsUploadTestCase(true).setUploadTestcaseDir(problemTestCaseDir).setLanguages(languageList).setTags(null).setJudgeMode(mode).setProblem(problem).setCodeTemplates(codeTemplates);
        problemDtoList.add(problemDto);
        index++;
    }
    return problemDtoList;
}
Also used : Element(org.w3c.dom.Element) FileWriter(cn.hutool.core.io.file.FileWriter) CodeTemplate(top.hcode.hoj.pojo.entity.problem.CodeTemplate) Document(org.w3c.dom.Document) Language(top.hcode.hoj.pojo.entity.problem.Language) ProblemDto(top.hcode.hoj.pojo.dto.ProblemDto) QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) ProblemCase(top.hcode.hoj.pojo.entity.problem.ProblemCase) Problem(top.hcode.hoj.pojo.entity.problem.Problem)

Aggregations

Problem (top.hcode.hoj.pojo.entity.problem.Problem)69 QueryWrapper (com.baomidou.mybatisplus.core.conditions.query.QueryWrapper)46 UserRolesVo (top.hcode.hoj.pojo.vo.UserRolesVo)35 StatusFailException (top.hcode.hoj.common.exception.StatusFailException)26 Session (org.apache.shiro.session.Session)25 Transactional (org.springframework.transaction.annotation.Transactional)24 StatusForbiddenException (top.hcode.hoj.common.exception.StatusForbiddenException)22 ContestProblem (top.hcode.hoj.pojo.entity.contest.ContestProblem)19 UpdateWrapper (com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper)15 StatusNotFoundException (top.hcode.hoj.common.exception.StatusNotFoundException)15 Judge (top.hcode.hoj.pojo.entity.judge.Judge)15 HttpSession (javax.servlet.http.HttpSession)13 RequiresAuthentication (org.apache.shiro.authz.annotation.RequiresAuthentication)13 Group (top.hcode.hoj.pojo.entity.group.Group)13 RequiresRoles (org.apache.shiro.authz.annotation.RequiresRoles)12 LinkedList (java.util.LinkedList)9 Contest (top.hcode.hoj.pojo.entity.contest.Contest)9 ContestRecord (top.hcode.hoj.pojo.entity.contest.ContestRecord)8 Tag (top.hcode.hoj.pojo.entity.problem.Tag)7 JudgeCase (top.hcode.hoj.pojo.entity.judge.JudgeCase)6