|
@@ -1,29 +1,21 @@
|
|
|
package com.sg.answer.sg;
|
|
|
|
|
|
-import com.alibaba.fastjson.JSONException;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
|
|
-import com.sg.answer.core.HttpRequestConfig;
|
|
|
-import com.sg.answer.core.HttpRequestResult;
|
|
|
import com.sg.answer.core.SgEntity;
|
|
|
import com.sg.answer.core.UserInfoEntity;
|
|
|
import com.sg.answer.entity.JobTypeEntity;
|
|
|
import com.sg.answer.panel.PlaceComponents;
|
|
|
+import com.sg.answer.service.AnswerService;
|
|
|
import com.sg.answer.service.UserInfoService;
|
|
|
-import com.sg.answer.utils.HttpClientUtils;
|
|
|
import com.sg.answer.utils.ObjectUtils;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.apache.http.client.CookieStore;
|
|
|
-import org.apache.http.client.protocol.HttpClientContext;
|
|
|
-import org.apache.http.protocol.HttpContext;
|
|
|
|
|
|
import javax.swing.*;
|
|
|
-import java.io.IOException;
|
|
|
import java.text.DecimalFormat;
|
|
|
-import java.util.HashSet;
|
|
|
import java.util.Optional;
|
|
|
-import java.util.Random;
|
|
|
import java.util.Set;
|
|
|
import java.util.concurrent.*;
|
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
@@ -43,7 +35,9 @@ import static com.sg.answer.sg.Constant.answerNum;
|
|
|
@Slf4j
|
|
|
public class FrameManager {
|
|
|
|
|
|
- // 线程池配置
|
|
|
+ private static final int MAX_LEVEL = 10;
|
|
|
+ private static final DecimalFormat SCORE_FORMAT = new DecimalFormat("######0.00");
|
|
|
+ private static final Set<String> processedJobs = ConcurrentHashMap.newKeySet();
|
|
|
private static final ThreadPoolExecutor WORKER_POOL = new ThreadPoolExecutor(
|
|
|
10, 20, 30L, TimeUnit.SECONDS,
|
|
|
new LinkedBlockingQueue<>(100),
|
|
@@ -52,11 +46,10 @@ public class FrameManager {
|
|
|
|
|
|
public JPanel panel = new JPanel();
|
|
|
private CookieStore cookie;
|
|
|
- static Set<String> sets = new HashSet<>();
|
|
|
|
|
|
public void init() {
|
|
|
// 创建 JFrame 实例
|
|
|
- JFrame frame = new JFrame("全自动答题系统6.0.2 By 彭宇");
|
|
|
+ JFrame frame = new JFrame("全自动答题系统6.0.3 By 彭宇");
|
|
|
frame.setBounds(500, 250, 770, 550);
|
|
|
frame.setSize(770, 550);
|
|
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
@@ -81,11 +74,11 @@ public class FrameManager {
|
|
|
* @date 2019/7/5 15:30
|
|
|
*/
|
|
|
public void start(JButton loginButton, SgEntity sgEntity, UserInfoEntity userInfoEntity, JLabel statrScore, AtomicBoolean status, AtomicBoolean pause, Object lock) throws Exception {
|
|
|
- if (!validateCredentials(sgEntity)){
|
|
|
+ if (!validateCredentials(sgEntity)) {
|
|
|
return;
|
|
|
}
|
|
|
initializeSession(sgEntity);
|
|
|
- updateUIComponents(loginButton, true, "努力答题中……");
|
|
|
+ updateUIComponents(loginButton, false, "努力答题中……");
|
|
|
|
|
|
log.info("当前活动线程数量:{}", Thread.activeCount());
|
|
|
|
|
@@ -93,9 +86,8 @@ public class FrameManager {
|
|
|
try {
|
|
|
if (status.get()) {
|
|
|
cookie = login(sgEntity.getUserText().getText(), String.valueOf(sgEntity.getPasswordText().getPassword()));
|
|
|
- UserInfoService.getPersonalInfo(cookie, sgEntity, userInfoEntity);
|
|
|
- final String startScore = userInfoEntity.getIntegralDate().getText();
|
|
|
- statrScore.setText(startScore);
|
|
|
+ UserInfoService.refreshUserInfo(cookie, sgEntity, userInfoEntity);
|
|
|
+ statrScore.setText(userInfoEntity.getIntegralDate().getText());
|
|
|
anwser(cookie, sgEntity, userInfoEntity, statrScore, status, pause, lock);
|
|
|
} else {
|
|
|
log.info("答题已结束");
|
|
@@ -105,7 +97,7 @@ public class FrameManager {
|
|
|
JOptionPane.showMessageDialog(panel, sg.getMessage(), " stop", JOptionPane.ERROR_MESSAGE);
|
|
|
reset(loginButton, sgEntity, sg.getMessage());
|
|
|
} catch (Exception e) {
|
|
|
- log.info("未知异常:", e);
|
|
|
+ log.error("未知异常:", e);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
@@ -116,172 +108,96 @@ public class FrameManager {
|
|
|
if (!status.get()) {
|
|
|
return;
|
|
|
}
|
|
|
- HttpClientContext httpContext = new HttpClientContext();
|
|
|
- httpContext.setCookieStore(cookie);
|
|
|
- //获取当前答题进度关卡
|
|
|
+ //获取当前用户答题进度关卡
|
|
|
int gs = UserInfoService.getGKInfo(cookie, sgEntity);
|
|
|
+ AnswerService service = new AnswerService(cookie);
|
|
|
//外层循环控制1到10关,内存循环控制对应关数多少题数
|
|
|
- for (int i = 1; i <= 10; i++) {
|
|
|
+ while (status.get()) {
|
|
|
if (!status.get()) {
|
|
|
log.info("结束本次刷题");
|
|
|
break;
|
|
|
}
|
|
|
- sgEntity.getGkText().setText("第" + gs + "关" + "(" + sgEntity.getDifficulty() + ")");
|
|
|
- sgEntity.getTextArea().setText("开始第" + gs + "关答题:");
|
|
|
-
|
|
|
- /**获取用户历史答题关卡id*/
|
|
|
- int num;
|
|
|
- if (gs == 11) {
|
|
|
- num = 8 + sgEntity.getGz();
|
|
|
- } else if (gs == 12) {
|
|
|
- num = 9 + sgEntity.getGz();
|
|
|
- } else if (gs == 13) {
|
|
|
- num = 10 + sgEntity.getGz();
|
|
|
- } else {
|
|
|
- num = gs + sgEntity.getGz();
|
|
|
- }
|
|
|
- log.info("当前工种:{},开始第{}关答题,答题页面id:{}", currentJobType.getJobTypeNname(), gs, num);
|
|
|
- sets.add(currentJobType.getJobTypeNname().trim());
|
|
|
+ updateUIComponents(sgEntity.getGkText(), false, String.format("第%d关(%s)", gs, sgEntity.getDifficulty()));
|
|
|
+ updateUIComponents(sgEntity.getTextArea(), false, "开始第" + gs + "关答题:");
|
|
|
+
|
|
|
+ //获取用户历史答题关卡id
|
|
|
+ int levelId = calculateLevelId(gs, sgEntity.getGz());
|
|
|
+
|
|
|
+ log.info("当前工种:{},开始第{}关答题,答题页面id:{}", currentJobType.getJobTypeNname(), gs, levelId);
|
|
|
+ processedJobs.add(currentJobType.getJobTypeNname().trim());
|
|
|
+
|
|
|
+ //打开当前闯关页面(开始答题计时)*/
|
|
|
+ service.openAnswerHtml(levelId);
|
|
|
|
|
|
- /**打开当前闯关页面(开始答题计时)*/
|
|
|
- openAnswerHtml(httpContext, num);
|
|
|
//开始进行本官答题
|
|
|
- for (int j = 1; j <= answerNum.get(gs) + 10; j++) {
|
|
|
- if (!status.get()) {
|
|
|
- log.info("已结束本次刷题");
|
|
|
- break;
|
|
|
- }
|
|
|
- while (pause.get()) {
|
|
|
- sgEntity.apppendLogs(" 已暂停当前答题 ");
|
|
|
- onPause(lock, pause);
|
|
|
- }
|
|
|
- sgEntity.getTextArea().append(currentJobType.getJobTypeNname() + ":第" + j + "题,");
|
|
|
- sgEntity.getTextArea().setCaretPosition(sgEntity.getTextArea().getText().length());
|
|
|
- sgEntity.getTextArea().paintImmediately(sgEntity.getTextArea().getBounds());
|
|
|
- log.info("{}====================>第{}题", currentJobType.getJobTypeNname(), j);
|
|
|
-
|
|
|
- HttpRequestResult answeresult1;
|
|
|
- int ram = new Random().nextInt(50);
|
|
|
- String stem = stemList.get(ram);
|
|
|
- log.info("当前随机选择数字为:{},题干为:【{}】", ram, stem);
|
|
|
- /**循环答题(每2秒一次 )*/
|
|
|
- HttpRequestConfig answerConfig = HttpRequestConfig.create().url(API + "cglb/ajaxdt?passid=" + num + "&" + stem).context(httpContext);
|
|
|
- try {
|
|
|
- answeresult1 = HttpClientUtils.post(answerConfig);
|
|
|
- } catch (IOException e) {
|
|
|
- log.error("答题超时{},重新发起请求", e);
|
|
|
- Thread.sleep(10000);
|
|
|
- answeresult1 = HttpClientUtils.post(answerConfig);
|
|
|
- log.info("重新连接成功:{}", cookie);
|
|
|
- }
|
|
|
- JSONObject jb;
|
|
|
- try {
|
|
|
- jb = JSONObject.parseObject(answeresult1.getResponseText());
|
|
|
-// log.info("当前答题数量:{}",jb.get("isright"));
|
|
|
- } catch (JSONException exception) {
|
|
|
- log.error("json解析异常{}", exception.getMessage());
|
|
|
- if (exception.getMessage().contains("重新登录")) {
|
|
|
- throw new SgException(ErrorCode.LOGOUT.getCode(), ErrorCode.LOGOUT.getName());
|
|
|
- }
|
|
|
- Thread.sleep(10000);
|
|
|
- answeresult1 = HttpClientUtils.post(answerConfig);
|
|
|
- jb = JSONObject.parseObject(answeresult1.getResponseText());
|
|
|
- }
|
|
|
+ processLevels(sgEntity, status, pause, lock, gs, currentJobType, service, levelId);
|
|
|
|
|
|
- if (Integer.valueOf(jb.get("isright").toString()) == -1) {
|
|
|
- sgEntity.getTextArea().append("答题速度过快,直接进行下一题答题");
|
|
|
- continue;
|
|
|
- }
|
|
|
- if (Integer.valueOf(jb.get("right_num").toString()) >= answerNum.get(gs)) {
|
|
|
- log.info("当前关已答题{}道", Integer.valueOf(jb.get("right_num").toString()));
|
|
|
- break;
|
|
|
- }
|
|
|
- Thread.sleep(2000);
|
|
|
- }
|
|
|
- if (!sgEntity.getFlag()) {
|
|
|
- break;
|
|
|
- }
|
|
|
- //进行本本关结算
|
|
|
- sgEntity.getTextArea().append("开始第" + gkNum.get(gs) + "关结算");
|
|
|
- sgEntity.getTextArea().paintImmediately(sgEntity.getTextArea().getBounds());
|
|
|
- log.info("{} 开始第" + gkNum.get(gs) + "关结算," + "当前答题页面id:" + num + "闯关页面id:{}", currentJobType.getJobTypeNname(), sgEntity.getId());
|
|
|
- log.info("当前答题工种数量:{},当前答题工种为:{}:", sets.size(), StringUtils.join(sets.toArray(), ","));
|
|
|
+ log.info(String.format("%s 开始第%s关结算,当前答题页面id:%d,闯关页面id:%d",currentJobType.getJobTypeNname(), gkNum.get(gs), levelId, sgEntity.getId()));
|
|
|
+ log.info("当前答题工种数量:{},当前答题工种为:{}:", processedJobs.size(), StringUtils.join(processedJobs.toArray(), ","));
|
|
|
if (!status.get()) {
|
|
|
log.info("结束本次刷题,停止当前结算");
|
|
|
break;
|
|
|
}
|
|
|
- /**对当前关卡进行结算*/
|
|
|
- HttpRequestConfig answerConfig = HttpRequestConfig.create().url(API + "/cglb/passresult?passid=" + num + "&matchid=0").context(httpContext);
|
|
|
- HttpRequestResult answeresult1 = HttpClientUtils.post(answerConfig);
|
|
|
+ //更新UI答题进度
|
|
|
+ sgEntity.apppendLogs("开始第" + gkNum.get(gs) + "关结算");
|
|
|
+ //对当前关卡进行结算
|
|
|
+ service.gkSettlement(levelId);
|
|
|
|
|
|
- if (StringUtils.isEmpty(answeresult1.getResponseText())) {
|
|
|
- log.error("结算异常,再次发起结算请求……");
|
|
|
- answeresult1 = HttpClientUtils.post(answerConfig);
|
|
|
- }
|
|
|
- if (answeresult1.getResponseText().contains("只差一点点")) {
|
|
|
- log.error("错误题目过多,闯关失败……");
|
|
|
- }
|
|
|
- /**结算完成刷新个人信息答题成绩*/
|
|
|
- UserInfoService.getPersonalInfo(cookie, sgEntity, userInfoEntity);
|
|
|
-
|
|
|
- DecimalFormat df = new DecimalFormat("######0.00");
|
|
|
- Double xj = Double.parseDouble(userInfoEntity.getIntegralDate().getText()) - Double.parseDouble(statrScore.getText());
|
|
|
- log.info("增长分数:{}", xj);
|
|
|
- sgEntity.getXjText().setText(df.format(xj));
|
|
|
- sgEntity.getXjText().paintImmediately(sgEntity.getXjText().getBounds());
|
|
|
-// userInfoEntity.getIntegralDate().setText(Double.parseDouble(userInfoEntity.getIntegralDate().getText())+score+"");
|
|
|
- if (!ObjectUtils.isEmpty(sgEntity.getCoustomScore()) && xj >= sgEntity.getCoustomScore() && sgEntity.getCoustomScore() != 0.0) {
|
|
|
- status.set(false);
|
|
|
- log.info("已完成{}分刷分,如需继续请重新开始", sgEntity.getCoustomScore());
|
|
|
- throw new SgException(ErrorCode.SORCE_LIMT.getCode(), ErrorCode.SORCE_LIMT.getName());
|
|
|
+ //结算完成刷新个人信息答题成绩
|
|
|
+ UserInfoService.refreshUserInfo(cookie, sgEntity, userInfoEntity);
|
|
|
+
|
|
|
+ // 检查分数限制
|
|
|
+ checkScoreLimit(userInfoEntity, sgEntity, statrScore, status);
|
|
|
+
|
|
|
+ // 更新关卡计数
|
|
|
+ if (gs >= MAX_LEVEL) {
|
|
|
+ gs = 0;
|
|
|
}
|
|
|
+ gs++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void processLevels(SgEntity sgEntity, AtomicBoolean status, AtomicBoolean pause, Object lock, int gs, JobTypeEntity currentJobType, AnswerService service, int levelId) throws Exception {
|
|
|
+ for (int j = 1; j <= answerNum.get(gs) + 10; j++) {
|
|
|
if (!status.get()) {
|
|
|
- log.info("结束本次刷题,停止当前结算");
|
|
|
+ log.info("已结束本次刷题");
|
|
|
break;
|
|
|
}
|
|
|
- gs++;
|
|
|
- if (gs > 10) {
|
|
|
- log.info("一轮答题结束");
|
|
|
+ while (pause.get()) {
|
|
|
+ sgEntity.apppendLogs(" 已暂停当前答题 ");
|
|
|
+ onPause(lock);
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("{}====================>第{}题", currentJobType.getJobTypeNname(), j);
|
|
|
+ sgEntity.apppendLogs(currentJobType.getJobTypeNname() + ":第" + j + "题,");
|
|
|
+
|
|
|
+ JSONObject resJson = service.autoAnswer(stemList, levelId);
|
|
|
+
|
|
|
+ if (Integer.parseInt(resJson.get("isright").toString()) == -1) {
|
|
|
+ sgEntity.getTextArea().append("答题速度过快,直接进行下一题答题");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (Integer.parseInt(resJson.get("right_num").toString()) >= answerNum.get(gs)) {
|
|
|
+ log.info("当前关已答题{}道", Integer.valueOf(resJson.get("right_num").toString()));
|
|
|
break;
|
|
|
}
|
|
|
- }
|
|
|
- //一轮答题10关结束后,开始从第一关开始
|
|
|
- if (status.get()) {
|
|
|
- anwser(cookie, sgEntity, userInfoEntity, statrScore, status, pause, lock);
|
|
|
+ Thread.sleep(2000);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private static void openAnswerHtml(HttpContext httpContext, int num) throws Exception {
|
|
|
- String openAnswerUrl = ApiEndpoints.START_LEVEL + "?id=" + num + "&matchid=0";
|
|
|
- log.info("闯关页面请求地址:{}", openAnswerUrl);
|
|
|
- HttpRequestConfig openConfig = HttpRequestConfig.create().url(openAnswerUrl).context(httpContext);
|
|
|
- HttpRequestResult openResult = HttpClientUtils.post(openConfig);
|
|
|
- if (StringUtils.isEmpty(openResult.getResponseText())) {
|
|
|
- log.error("请求返回结果集为空");
|
|
|
- throw new SgException(ErrorCode.RESULT_EMPTY.getCode(), ErrorCode.RESULT_EMPTY.getName());
|
|
|
- }
|
|
|
- if (openResult.getResponseText().contains("今天的闯关时间已用尽")) {
|
|
|
- log.error("今天的闯关时间已用尽");
|
|
|
- throw new SgException(ErrorCode.TIME_Limit.getCode(), ErrorCode.TIME_Limit.getName());
|
|
|
- }
|
|
|
- if (openResult.getResponseText().contains("未解锁")) {
|
|
|
- log.error("当前关卡未解锁");
|
|
|
- throw new SgException(ErrorCode.LEVEL_NOT_UNLOCKED.getCode(), ErrorCode.LEVEL_NOT_UNLOCKED.getName());
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
- private static void onPause(Object lock, AtomicBoolean pause) {
|
|
|
+ private static void onPause(Object lock) {
|
|
|
synchronized (lock) {
|
|
|
try {
|
|
|
log.info("已暂停答题,等待线程唤醒");
|
|
|
lock.wait();
|
|
|
} catch (InterruptedException e) {
|
|
|
- e.printStackTrace();
|
|
|
+ log.error("暂停答题异常", e);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 验证凭证方法
|
|
|
+ // 登录严重
|
|
|
private boolean validateCredentials(SgEntity sgEntity) throws SgException {
|
|
|
String uname = Optional.ofNullable(sgEntity.getUserText())
|
|
|
.map(JTextField::getText)
|
|
@@ -292,7 +208,7 @@ public class FrameManager {
|
|
|
if (uname.isEmpty() || pwd.isEmpty()) {
|
|
|
SwingUtilities.invokeLater(() ->
|
|
|
JOptionPane.showMessageDialog(panel, "账号密码不能为空", "错误", JOptionPane.ERROR_MESSAGE));
|
|
|
- return false;
|
|
|
+ return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
@@ -301,6 +217,7 @@ public class FrameManager {
|
|
|
// 初始化管卡数据
|
|
|
private void initializeSession(SgEntity sgEntity) {
|
|
|
sgEntity.setFlag(true);
|
|
|
+ sgEntity.getTextArea().setText("");
|
|
|
//当前工种选项
|
|
|
JobTypeEntity currentJobType = (JobTypeEntity) sgEntity.getComboBox().getSelectedItem();
|
|
|
//获取当前当前选择工种第一关关卡id
|
|
@@ -330,7 +247,7 @@ public class FrameManager {
|
|
|
}
|
|
|
|
|
|
// UI组件更新方法
|
|
|
- private void updateUIComponents(JComponent component, boolean enabled, String text) {
|
|
|
+ private static void updateUIComponents(JComponent component, boolean enabled, String text) {
|
|
|
SwingUtilities.invokeLater(() -> {
|
|
|
if (component instanceof AbstractButton) {
|
|
|
component.setEnabled(enabled);
|
|
@@ -341,6 +258,25 @@ public class FrameManager {
|
|
|
((JButton) component).setText(text);
|
|
|
}
|
|
|
});
|
|
|
- }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static int calculateLevelId(int baseLevel, int difficulty) {
|
|
|
+ return (baseLevel > 10) ?
|
|
|
+ baseLevel + difficulty - 2 :
|
|
|
+ baseLevel + difficulty;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 检查分数限制
|
|
|
+ private static void checkScoreLimit(UserInfoEntity userInfoEntity, SgEntity sgEntity, JLabel statrScore, AtomicBoolean status) throws SgException {
|
|
|
+ Double xj = Double.parseDouble(userInfoEntity.getIntegralDate().getText()) - Double.parseDouble(statrScore.getText());
|
|
|
+ log.info("增长分数:{}", xj);
|
|
|
+ updateUIComponents(sgEntity.getXjText(), true, SCORE_FORMAT.format(xj));
|
|
|
|
|
|
- }
|
|
|
+ if (!ObjectUtils.isEmpty(sgEntity.getCoustomScore()) && xj >= sgEntity.getCoustomScore() && sgEntity.getCoustomScore() != 0.0) {
|
|
|
+ status.set(false);
|
|
|
+ log.info("已完成{}分刷分,如需继续请重新开始", sgEntity.getCoustomScore());
|
|
|
+ throw new SgException(ErrorCode.SORCE_LIMT.getCode(), ErrorCode.SORCE_LIMT.getName());
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|