From 8da1019f765d39ffad9b142f82514633b17bc16c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=B5=A9=E6=96=8C?= Date: Thu, 22 Jun 2023 08:12:04 +0800 Subject: [PATCH 1/7] Create YBTJudge.java --- .../hoj/remoteJudge/task/Impl/YBTJudge.java | 226 ++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java diff --git a/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java b/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java new file mode 100644 index 000000000..480640eec --- /dev/null +++ b/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java @@ -0,0 +1,226 @@ +package top.hcode.hoj.remoteJudge.task.Impl; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ReUtil; +import cn.hutool.http.HtmlUtil; +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; +import lombok.extern.slf4j.Slf4j; +import org.jsoup.helper.Validate; +import top.hcode.hoj.remoteJudge.entity.RemoteJudgeDTO; +import top.hcode.hoj.remoteJudge.entity.RemoteJudgeRes; +import top.hcode.hoj.remoteJudge.task.RemoteJudgeStrategy; +import top.hcode.hoj.util.Constants; + +import java.net.HttpCookie; +import java.net.URLEncoder; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Slf4j(topic = "hoj") +public class YBTJudge extends RemoteJudgeStrategy { + public static final String HOST = "http://acm.hdu.edu.cn"; + public static final String LOGIN_URL = "/userloginex.php?action=login"; + public static final String SUBMIT_URL = "/submit.php?action=submit"; + public static final String STATUS_URL = "/status.php?user=%s&pid=%s"; + public static final String QUERY_URL = "/status.php?first=%d"; + public static final String ERROR_URL = "/viewerror.php?rid=%d"; + public static Map headers = MapUtil + .builder(new HashMap()) + .put("Host", "acm.hdu.edu.cn") + .put("origin", "https://acm.hdu.edu.cn") + .put("referer", "https://acm.hdu.edu.cn") + .put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36") + .map(); + + @Override + public void submit() { + + RemoteJudgeDTO remoteJudgeDTO = getRemoteJudgeDTO(); + + if (remoteJudgeDTO.getCompleteProblemId() == null || remoteJudgeDTO.getUserCode() == null) { + return; + } + + login(); + + List cookies = remoteJudgeDTO.getCookies(); + + HttpRequest request = HttpUtil.createPost(HOST + SUBMIT_URL) + .addHeaders(headers) + .form(MapUtil + .builder(new HashMap()) + .put("check", "0") + .put("language", getLanguage(remoteJudgeDTO.getLanguage())) + .put("problemid", remoteJudgeDTO.getCompleteProblemId()) + .put("_usercode", Base64.encode(URLEncoder.encode(remoteJudgeDTO.getUserCode() + getRandomBlankString()))) + .map()) + .cookie(cookies); + + HttpResponse response = request.execute(); + remoteJudgeDTO.setSubmitStatus(response.getStatus()); + // 提交频率限制了 等待5秒再次提交 + if (response.getStatus() == 200 && response.body() != null && response.body().contains("Please don't re-submit")) { + try { + TimeUnit.SECONDS.sleep(5); + } catch (InterruptedException e) { + e.printStackTrace(); + } + response = request.execute(); + remoteJudgeDTO.setSubmitStatus(response.getStatus()); + if (response.getStatus() != 302) { + String log = String.format("[HDU] [%s]: Failed to submit code, the http response status is [%s].", remoteJudgeDTO.getCompleteProblemId(), response.getStatus()); + throw new RuntimeException(log); + } + } else if (response.getStatus() != 302) { + String log = String.format("[HDU] [%s]: Failed to submit code, the http response status is [%s].", remoteJudgeDTO.getCompleteProblemId(), response.getStatus()); + throw new RuntimeException(log); + } + // 获取提交的题目id + Long maxRunId = getMaxRunId(remoteJudgeDTO.getUsername(), remoteJudgeDTO.getCompleteProblemId()); + if (maxRunId == -1L) { // 等待2s再次查询,如果还是失败,则表明提交失败了 + try { + TimeUnit.SECONDS.sleep(2); + } catch (InterruptedException e) { + e.printStackTrace(); + } + maxRunId = getMaxRunId(remoteJudgeDTO.getUsername(), remoteJudgeDTO.getCompleteProblemId()); + } + remoteJudgeDTO.setCookies(cookies) + .setSubmitId(maxRunId); + } + + @Override + public RemoteJudgeRes result() { + RemoteJudgeDTO remoteJudgeDTO = getRemoteJudgeDTO(); + String url = HOST + String.format(QUERY_URL, remoteJudgeDTO.getSubmitId()); + HttpRequest request = HttpUtil.createGet(url) + .cookie(remoteJudgeDTO.getCookies()) + .addHeaders(headers); + HttpResponse response = request.execute(); + // 1提交时间 2结果 3执行时间 4执行空间 5代码长度 + // 一般情况下 代码长度和提交时间不需要,想要也行,自行添加 + Pattern pattern = Pattern.compile(">" + remoteJudgeDTO.getSubmitId() + "[\\s\\S]*?([\\s\\S]*?)[\\s\\S]*?(\\d*?)MS(\\d*?)K"); + Matcher matcher = pattern.matcher(response.body()); + // 找到时 + Validate.isTrue(matcher.find()); + String rawStatus = matcher.group(1).replaceAll("<[\\s\\S]*?>", "").trim(); + Constants.Judge judgeStatus; + if (rawStatus.contains("Runtime Error")){ + judgeStatus = Constants.Judge.STATUS_RUNTIME_ERROR; + }else{ + judgeStatus = statusTypeMap.getOrDefault(rawStatus, Constants.Judge.STATUS_PENDING); + } + RemoteJudgeRes remoteJudgeRes = RemoteJudgeRes.builder() + .status(judgeStatus.getStatus()) + .build(); + + if (judgeStatus == Constants.Judge.STATUS_PENDING) { + return remoteJudgeRes; + } + + + // 获取其他信息 + String executionTime = matcher.group(2); + remoteJudgeRes.setTime(Integer.parseInt(executionTime)); + String executionMemory = matcher.group(3); + remoteJudgeRes.setMemory(Integer.parseInt(executionMemory)); + + // 如果CE了,则还需要获得错误信息 + if (judgeStatus == Constants.Judge.STATUS_COMPILE_ERROR) { + request.setUrl(HOST + String.format(ERROR_URL, remoteJudgeDTO.getSubmitId())); + String CEHtml = request.execute().body(); + String compilationErrorInfo = ReUtil.get("
([\\s\\S]*?)
", CEHtml, 1); + remoteJudgeRes.setErrorInfo(HtmlUtil.unescape(compilationErrorInfo)); + } + return remoteJudgeRes; + } + + + @Override + public void login() { + // 清除当前线程的cookies缓存 + HttpRequest.getCookieManager().getCookieStore().removeAll(); + RemoteJudgeDTO remoteJudgeDTO = getRemoteJudgeDTO(); + HttpRequest request = HttpUtil.createPost(HOST + LOGIN_URL).addHeaders(headers); + HttpResponse response = request.form(MapUtil + .builder(new HashMap()) + .put("username", remoteJudgeDTO.getUsername()) + .put("login", "Sign In") + .put("userpass", remoteJudgeDTO.getPassword()).map()) + .execute(); + if (response.getStatus() != 302) { + throw new RuntimeException("[HDU] Failed to login! The possible cause is connection failure, and the returned status code is " + response.getStatus()); + } + remoteJudgeDTO.setLoginStatus(response.getStatus()); + remoteJudgeDTO.setCookies(response.getCookies()); + } + + + @Override + public String getLanguage(String language) { + switch (language) { + case "G++": + return "0"; + case "GCC": + return "1"; + case "C++": + return "2"; + case "C": + return "3"; + case "Pascal": + return "4"; + case "Java": + return "5"; + case "C#": + return "6"; + default: + // TODO 抛出没有这个语言的异常 + return null; + } + } + + + public Long getMaxRunId(String userName, String problemId) { + String url = HOST + String.format(STATUS_URL, userName, problemId); + HttpResponse response = HttpUtil.createGet(url).addHeaders(headers).execute(); + String maxRunId = ReUtil.get("(\\d+)", response.body(), 1); + return maxRunId != null ? Long.parseLong(maxRunId) : -1L; + } + + + // TODO 添加结果对应的状态 + private static final Map statusTypeMap = new HashMap() { + { + put("Submitted", Constants.Judge.STATUS_PENDING); + put("Accepted", Constants.Judge.STATUS_ACCEPTED); + put("Wrong Answer", Constants.Judge.STATUS_WRONG_ANSWER); + put("Compilation Error", Constants.Judge.STATUS_COMPILE_ERROR); + put("Queuing", Constants.Judge.STATUS_PENDING); + put("Running", Constants.Judge.STATUS_JUDGING); + put("Compiling", Constants.Judge.STATUS_COMPILING); + put("Runtime Error", Constants.Judge.STATUS_RUNTIME_ERROR); + put("Time Limit Exceeded", Constants.Judge.STATUS_TIME_LIMIT_EXCEEDED); + put("Memory Limit Exceeded", Constants.Judge.STATUS_MEMORY_LIMIT_EXCEEDED); + put("Output Limit Exceeded", Constants.Judge.STATUS_RUNTIME_ERROR); + put("Presentation Error", Constants.Judge.STATUS_PRESENTATION_ERROR); + } + }; + + protected static String getRandomBlankString() { + StringBuilder string = new StringBuilder("\n"); + int random = new Random().nextInt(Integer.MAX_VALUE); + while (random > 0) { + string.append(random % 2 == 0 ? ' ' : '\t'); + random /= 2; + } + return string.toString(); + } +} From b26b7cbe8e6053ef7f397a79e16440a32757b800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=B5=A9=E6=96=8C?= Date: Thu, 22 Jun 2023 08:17:03 +0800 Subject: [PATCH 2/7] Update YBTJudge.java --- .../hoj/remoteJudge/task/Impl/YBTJudge.java | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java b/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java index 480640eec..04ffb1c68 100644 --- a/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java +++ b/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java @@ -26,12 +26,12 @@ @Slf4j(topic = "hoj") public class YBTJudge extends RemoteJudgeStrategy { - public static final String HOST = "http://acm.hdu.edu.cn"; - public static final String LOGIN_URL = "/userloginex.php?action=login"; - public static final String SUBMIT_URL = "/submit.php?action=submit"; - public static final String STATUS_URL = "/status.php?user=%s&pid=%s"; - public static final String QUERY_URL = "/status.php?first=%d"; - public static final String ERROR_URL = "/viewerror.php?rid=%d"; + public static final String HOST = "http://www.ssoier.cn:18087/pubtest"; + public static final String LOGIN_URL = ""; + public static final String SUBMIT_URL = "/acx.php"; + public static final String STATUS_URL = ""; + public static final String QUERY_URL = "/stux.php?first=%d"; + public static final String ERROR_URL = ""; public static Map headers = MapUtil .builder(new HashMap()) .put("Host", "acm.hdu.edu.cn") @@ -157,7 +157,7 @@ public void login() { .put("userpass", remoteJudgeDTO.getPassword()).map()) .execute(); if (response.getStatus() != 302) { - throw new RuntimeException("[HDU] Failed to login! The possible cause is connection failure, and the returned status code is " + response.getStatus()); + throw new RuntimeException("[YBT] not need login! submit user/pass with solution " + response.getStatus()); } remoteJudgeDTO.setLoginStatus(response.getStatus()); remoteJudgeDTO.setCookies(response.getCookies()); @@ -168,19 +168,15 @@ public void login() { public String getLanguage(String language) { switch (language) { case "G++": - return "0"; + return "7"; case "GCC": - return "1"; + return "7"; case "C++": - return "2"; + return "7"; case "C": - return "3"; - case "Pascal": - return "4"; - case "Java": + return "7"; + case "Python": return "5"; - case "C#": - return "6"; default: // TODO 抛出没有这个语言的异常 return null; From 66112e3efd9ad3ec04f2398ff184c502a20df5e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=B5=A9=E6=96=8C?= Date: Thu, 22 Jun 2023 08:20:49 +0800 Subject: [PATCH 3/7] Update YBTJudge.java --- .../hoj/remoteJudge/task/Impl/YBTJudge.java | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java b/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java index 04ffb1c68..eeff89414 100644 --- a/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java +++ b/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java @@ -34,9 +34,9 @@ public class YBTJudge extends RemoteJudgeStrategy { public static final String ERROR_URL = ""; public static Map headers = MapUtil .builder(new HashMap()) - .put("Host", "acm.hdu.edu.cn") - .put("origin", "https://acm.hdu.edu.cn") - .put("referer", "https://acm.hdu.edu.cn") + .put("Host", "www.ssoier.cn") + .put("origin", "http://www.ssoier.cn:18087/pubtest") + .put("referer", "http://www.ssoier.cn:18087/pubtest") .put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36") .map(); @@ -76,11 +76,11 @@ public void submit() { response = request.execute(); remoteJudgeDTO.setSubmitStatus(response.getStatus()); if (response.getStatus() != 302) { - String log = String.format("[HDU] [%s]: Failed to submit code, the http response status is [%s].", remoteJudgeDTO.getCompleteProblemId(), response.getStatus()); + String log = String.format("[YBT] [%s]: Failed to submit code, the http response status is [%s].", remoteJudgeDTO.getCompleteProblemId(), response.getStatus()); throw new RuntimeException(log); } } else if (response.getStatus() != 302) { - String log = String.format("[HDU] [%s]: Failed to submit code, the http response status is [%s].", remoteJudgeDTO.getCompleteProblemId(), response.getStatus()); + String log = String.format("[YBT] [%s]: Failed to submit code, the http response status is [%s].", remoteJudgeDTO.getCompleteProblemId(), response.getStatus()); throw new RuntimeException(log); } // 获取提交的题目id @@ -195,18 +195,15 @@ public Long getMaxRunId(String userName, String problemId) { // TODO 添加结果对应的状态 private static final Map statusTypeMap = new HashMap() { { - put("Submitted", Constants.Judge.STATUS_PENDING); - put("Accepted", Constants.Judge.STATUS_ACCEPTED); - put("Wrong Answer", Constants.Judge.STATUS_WRONG_ANSWER); - put("Compilation Error", Constants.Judge.STATUS_COMPILE_ERROR); - put("Queuing", Constants.Judge.STATUS_PENDING); - put("Running", Constants.Judge.STATUS_JUDGING); - put("Compiling", Constants.Judge.STATUS_COMPILING); - put("Runtime Error", Constants.Judge.STATUS_RUNTIME_ERROR); - put("Time Limit Exceeded", Constants.Judge.STATUS_TIME_LIMIT_EXCEEDED); - put("Memory Limit Exceeded", Constants.Judge.STATUS_MEMORY_LIMIT_EXCEEDED); - put("Output Limit Exceeded", Constants.Judge.STATUS_RUNTIME_ERROR); - put("Presentation Error", Constants.Judge.STATUS_PRESENTATION_ERROR); + put("AC", Constants.Judge.STATUS_ACCEPTED); + put("WA", Constants.Judge.STATUS_WRONG_ANSWER); + put("CE", Constants.Judge.STATUS_COMPILE_ERROR); + put("RE", Constants.Judge.STATUS_RUNTIME_ERROR); + put("RF", Constants.Judge.STATUS_RUNTIME_ERROR); + put("TLE", Constants.Judge.STATUS_TIME_LIMIT_EXCEEDED); + put("MLE", Constants.Judge.STATUS_MEMORY_LIMIT_EXCEEDED); + put("OLE", Constants.Judge.STATUS_RUNTIME_ERROR); + put("PE", Constants.Judge.STATUS_PRESENTATION_ERROR); } }; From d6cb1c464a6bee7f6b15bb64b5f7f48fd83117a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=B5=A9=E6=96=8C?= Date: Thu, 22 Jun 2023 08:27:26 +0800 Subject: [PATCH 4/7] Update YBTJudge.java --- .../top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java b/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java index eeff89414..46ce2e137 100644 --- a/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java +++ b/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java @@ -49,7 +49,7 @@ public void submit() { return; } - login(); + // login(); // YBT no need List cookies = remoteJudgeDTO.getCookies(); @@ -57,10 +57,13 @@ public void submit() { .addHeaders(headers) .form(MapUtil .builder(new HashMap()) - .put("check", "0") + .put("user_id", remoteJudgeDTO.getUsername()) + .put("password", remoteJudgeDTO.getPassword()).map()) // map() ? not sure .put("language", getLanguage(remoteJudgeDTO.getLanguage())) - .put("problemid", remoteJudgeDTO.getCompleteProblemId()) - .put("_usercode", Base64.encode(URLEncoder.encode(remoteJudgeDTO.getUserCode() + getRandomBlankString()))) + .put("problem_id", remoteJudgeDTO.getCompleteProblemId()) + .put("data_id", "bas") + .put("submit", "提交") + .put("source", Base64.encode(URLEncoder.encode(remoteJudgeDTO.getUserCode() + getRandomBlankString()))) .map()) .cookie(cookies); From 1a5aa734a74e45b6cbc8e7a3ccc8c01630cd4024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=B5=A9=E6=96=8C?= Date: Thu, 22 Jun 2023 08:28:16 +0800 Subject: [PATCH 5/7] Update YBTJudge.java --- .../main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java b/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java index 46ce2e137..e3ecdbc44 100644 --- a/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java +++ b/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java @@ -26,6 +26,8 @@ @Slf4j(topic = "hoj") public class YBTJudge extends RemoteJudgeStrategy { + // half done + // anyone continue this work , refer to https://github.com/zhblue/hustoj/blob/master/trunk/web/include/remote_bas.php public static final String HOST = "http://www.ssoier.cn:18087/pubtest"; public static final String LOGIN_URL = ""; public static final String SUBMIT_URL = "/acx.php"; From dac62882b257f97c222aa9005f0ca58c584c4fcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=B5=A9=E6=96=8C?= Date: Thu, 22 Jun 2023 08:31:16 +0800 Subject: [PATCH 6/7] Update YBTJudge.java --- .../top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java b/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java index e3ecdbc44..e01ab87e6 100644 --- a/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java +++ b/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/YBTJudge.java @@ -103,7 +103,7 @@ public void submit() { } @Override - public RemoteJudgeRes result() { + public RemoteJudgeRes result() { // YBT will need add login info here , change GET to POST, please RemoteJudgeDTO remoteJudgeDTO = getRemoteJudgeDTO(); String url = HOST + String.format(QUERY_URL, remoteJudgeDTO.getSubmitId()); HttpRequest request = HttpUtil.createGet(url) @@ -157,9 +157,9 @@ public void login() { HttpRequest request = HttpUtil.createPost(HOST + LOGIN_URL).addHeaders(headers); HttpResponse response = request.form(MapUtil .builder(new HashMap()) - .put("username", remoteJudgeDTO.getUsername()) - .put("login", "Sign In") - .put("userpass", remoteJudgeDTO.getPassword()).map()) + .put("user_id", remoteJudgeDTO.getUsername()) + .put("password", remoteJudgeDTO.getPassword()).map()) // map() ? not sure + .map()) .execute(); if (response.getStatus() != 302) { throw new RuntimeException("[YBT] not need login! submit user/pass with solution " + response.getStatus()); From ec9ac0865e4a6ed2334f69541564c1c9b0c2ad25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=B5=A9=E6=96=8C?= Date: Fri, 23 Jun 2023 06:35:56 +0800 Subject: [PATCH 7/7] Create YBTProblemStrategy.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 一本通启蒙题面爬虫,仅供参考 --- .../crawler/problem/YBTProblemStrategy.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/crawler/problem/YBTProblemStrategy.java diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/crawler/problem/YBTProblemStrategy.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/crawler/problem/YBTProblemStrategy.java new file mode 100644 index 000000000..f238c8342 --- /dev/null +++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/crawler/problem/YBTProblemStrategy.java @@ -0,0 +1,66 @@ +package top.hcode.hoj.crawler.problem; + +import cn.hutool.core.util.ReUtil; +import com.baomidou.mybatisplus.extension.api.R; +import org.jsoup.Connection; +import org.jsoup.nodes.Document; +import org.springframework.util.Assert; +import top.hcode.hoj.pojo.entity.problem.Problem; +import top.hcode.hoj.utils.Constants; +import top.hcode.hoj.utils.JsoupUtils; + +/** + * @Author: Himit_ZH + * @Date: 2021/2/17 22:42 + * @Description: + */ +public class YBTProblemStrategy extends ProblemStrategy { + public static final String JUDGE_NAME = "YBT"; + public static final String HOST = "http://ybt.ssoier.cn:8088"; + public static final String PROBLEM_URL = "/problem_show.php?pid=%s"; + + /** + * @param problemId String的原因是因为某些题库题号不是纯数字 + * @param author 导入该题目的管理员用户名 + * @return 返回Problem对象 + * @throws Exception + */ + @Override + public RemoteProblemInfo getProblemInfo(String problemId, String author) throws Exception { + // 验证题号是否符合规范 + Assert.isTrue(problemId.matches("[1-9]\\d*"), "YBT题号格式错误!"); + Problem info = new Problem(); + String url = HOST + String.format(PROBLEM_URL, problemId); + Connection connection = JsoupUtils.getConnectionFromUrl(url, null, null); + Document document = JsoupUtils.getDocument(connection, null); + String html = document.html(); + info.setProblemId(JUDGE_NAME + "-" + problemId); + info.setTitle(ReUtil.get("

([\\s\\S]*?)

", html, 1).trim()); + info.setTimeLimit(Integer.parseInt(ReUtil.get("时间限制: (\\d*) ms", html, 1))); + info.setMemoryLimit(Integer.parseInt(ReUtil.get("时间限制: (\\d*) KB", html, 1)) / 1024); + info.setDescription(ReUtil.get("【题目描述】([\\s\\S]*?)

【输入】

", html, 1) + .replaceAll("src=\"[../]*", "src=\"" + HOST + "/")); + info.setInput(ReUtil.get(""

【输入】

([\\s\\S]*?)

【输出】

", html, 1)); + info.setOutput(ReUtil.get("

【输出】

([\\s\\S]*?)

【输入样例】

", html, 1)); + StringBuilder sb = new StringBuilder(""); + sb.append(ReUtil.get("【输入样例】\n
([\\s\\S]*?)
", html, 1)); + sb.append(""); + sb.append(ReUtil.get("【输出样例】\n
([\\s\\S]*?)
", html, 1)); + info.setExamples(sb.toString()); + info.setHint(ReUtil.get("Hint([\\s\\S]*?)<[^<>]*?panel_title[^<>]*?>", html, 1)); + info.setIsRemote(true); + info.setSource(String.format("%s", url, JUDGE_NAME + "-" + problemId)); + info.setType(0) + .setAuth(1) + .setAuthor(author) + .setOpenCaseResult(false) + .setIsRemoveEndBlank(false) + .setIsGroup(false) + .setDifficulty(1); // 默认为简单 + + return new RemoteProblemInfo() + .setProblem(info) + .setTagList(null) + .setRemoteOJ(Constants.RemoteOJ.HDU); + } +}