Compare commits

..

No commits in common. 'master' and 'feature/unlimited-reply' have entirely different histories.

  1. 31
      libs/judger.js
  2. 1
      libs/submissions_process.js
  3. 1
      models-built/contest_player.js.map
  4. 3
      models/contest_player.ts
  5. 3
      models/judge_state.ts
  6. 4
      modules/contest.js
  7. 21
      modules/practice.js
  8. 2
      modules/problem.js
  9. 4
      views/admin_classify.ejs
  10. 4
      views/header.ejs
  11. 1
      views/submission.ejs
  12. 1
      views/submission_contest.ejs
  13. 46
      views/submission_practice.ejs
  14. 1
      views/submissions.ejs
  15. 23
      views/submissions_item.ejs

31
libs/judger.js

@ -28,7 +28,7 @@ let judgeQueue;
async function connect() {
const JudgeState = syzoj.model('judge_state');
const blockableRedisClient = syzoj.redis.duplicate();
const blockableRedisClient = syzoj.redis.duplicate();
judgeQueue = {
redisZADD: util.promisify(syzoj.redis.zadd).bind(syzoj.redis),
redisBZPOPMAX: util.promisify(blockableRedisClient.bzpopmax).bind(blockableRedisClient),
@ -174,7 +174,7 @@ async function connect() {
if (!judge_state) return;
const problemId = judge_state.problem_id;
let problemQuery = await Problem.createQueryBuilder();
const problemInfo = await problemQuery.where("id = :id", {id: problemId}).getOne();
const problemInfo = await problemQuery.where("id = :id", { id: problemId }).getOne();
const problem_time_limit = problemInfo.time_limit;
const subtasksArray = convertedResult.result.judge ? convertedResult.result.judge.subtasks : [];
const timeArray = subtasksArray.map((subtasksItem) => {
@ -182,10 +182,9 @@ async function connect() {
return subtasksItemCases.result.time
})
});
function flat(array, result = []) {
for (let i = 0; i < array.length; i++) {
if (Array.isArray(array[i])) {
function flat(array, result=[]){
for (let i=0;i<array.length;i++){
if (Array.isArray(array[i])){
flat(array[i], result);
} else {
result.push(array[i]);
@ -193,27 +192,13 @@ async function connect() {
}
return result;
}
const flatTimeArray = flat(timeArray);
const maxItemTime = Math.max.apply(this, flatTimeArray);
let baseScore = 0;
if (judge_state.type === 0 || judge_state.type === 1) {
baseScore = 100;
}
if (judge_state.type === 2) {
baseScore = syzoj.config.practice_rating
}
if (convertedResult.statusString === 'Accepted' && maxItemTime < problem_time_limit * 0.9)
{
if (judge_state.type_info && convertedResult.statusString === 'Accepted' && maxItemTime < problem_time_limit * 0.9) {
const beyondTime = problem_time_limit - maxItemTime;
const extraScore = (beyondTime / problem_time_limit).toString().slice(0, 3) * baseScore;
if (judge_state.type === 2) {
judge_state.score = convertedResult.score + extraScore + syzoj.config.practice_rating;
}
const extraScore = (beyondTime / problem_time_limit).toString().slice(0,3)*100;
judge_state.score = convertedResult.score + extraScore;
}
else
{
} else {
judge_state.score = convertedResult.score;
}
judge_state.pending = false;

1
libs/submissions_process.js

@ -5,7 +5,6 @@ const getSubmissionInfo = (s, displayConfig) => {
return {
submissionId: s.id,
taskId: s.task_id,
type: s.type,
user: s.is_anonymous ? null: s.user.username,
userId: s.is_anonymous ? null : s.user_id,
problemName: s.problem.title,

1
models-built/contest_player.js.map

File diff suppressed because one or more lines are too long

3
models/contest_player.ts

@ -80,8 +80,9 @@ export default class ContestPlayer extends Model {
}
} else if (this.contest.type === 'noi') {
if (this.score_details[judge_state.problem_id] && this.score_details[judge_state.problem_id].judge_id > judge_state.id) return;
this.score_details[judge_state.problem_id] = {
score: this.score_details[judge_state.problem_id] ? Math.max(judge_state.score ,this.score_details[judge_state.problem_id].score) : judge_state.score,
score: Math.max(judge_state.score ,this.score_details[judge_state.problem_id].score),
judge_id: judge_state.id
};

3
models/judge_state.ts

@ -89,7 +89,6 @@ export default class JudgeState extends Model {
/*
* "type" indicate it's contest's submission(type = 1) or normal submission(type = 0)
* 2
* if it's contest's submission (type = 1), the type_info is contest_id
* use this way represent because it's easy to expand // Menci:这锅我不背,是 Chenyao 留下来的坑。
*/
@ -131,7 +130,7 @@ export default class JudgeState extends Model {
await this.loadRelationships();
if (user && user.id === this.problem.user_id) return true;
else if (this.type === 0 || this.type === 2) return this.problem.is_public || (user && (await user.hasPrivilege('manage_problem')));
else if (this.type === 0) return this.problem.is_public || (user && (await user.hasPrivilege('manage_problem')));
else if (this.type === 1) {
let contest = await Contest.findById(this.type_info);
if (contest.isRunning()) {

4
modules/contest.js

@ -207,7 +207,7 @@ app.get('/contest/:id', async (req, res) => {
for (let player of players) {
if (player.score_details[problem.problem.id]) {
problem.statistics.attempt++;
if ((contest.type === 'acm' && player.score_details[problem.problem.id].accepted) || ((contest.type === 'noi' || contest.type === 'ioi') && player.score_details[problem.problem.id].score >= 100)) {
if ((contest.type === 'acm' && player.score_details[problem.problem.id].accepted) || ((contest.type === 'noi' || contest.type === 'ioi') && player.score_details[problem.problem.id].score === 100)) {
problem.statistics.accepted++;
}
@ -458,12 +458,12 @@ app.get('/contest/submission/:id', async (req, res) => {
judge.problem_id = problems_id.indexOf(judge.problem_id) + 1;
judge.problem.title = syzoj.utils.removeTitleTag(judge.problem.title);
displayConfig.showUsage = true;
displayConfig.showResult=true;
displayConfig.showDetailResult=true;
if (judge.problem.type !== 'submit-answer') {
judge.codeLength = Buffer.from(judge.code).length;
judge.code = await syzoj.utils.highlight(judge.code, syzoj.languages[judge.language].highlight);
}
res.render('submission_contest', {
contest_id: contest.id,
info: getSubmissionInfo(judge, displayConfig),

21
modules/practice.js

@ -1,5 +1,4 @@
let Classify = syzoj.model('classify');
let JudgeState = syzoj.model('judge_state');
let Problem = syzoj.model('problem');
let CToP = syzoj.model('classify_to_problem');
let Article = syzoj.model('article');
@ -177,7 +176,6 @@ app.get('/api/pass/:cid/:pid/:sid',async (req, res) => {
let utopQuery = UToP.createQueryBuilder();
let query = Classify.createQueryBuilder();
let userQuery = User.createQueryBuilder();
let judgeStateQuery = JudgeState.createQueryBuilder();
let classify = await Classify.queryAll(query);
classify.sort(function(a,b) {
return a.order - b.order;
@ -201,26 +199,15 @@ app.get('/api/pass/:cid/:pid/:sid',async (req, res) => {
await utop.save();
}
let newutopQuery = UToP.createQueryBuilder();
let userACArray = await newutopQuery.select("p_id").where('u_id=:u_id',{u_id}).andWhere("is_finished=1").getRawMany();
let userACArray = await newutopQuery.where('u_id=:u_id',{u_id}).andWhere("is_finished=1").getMany();
console.log(userACArray.length);
if (syzoj.config.practice_rating) {
const scoreArray = await judgeStateQuery.select("score").addSelect("problem_id").where("user_id=:u_id",{u_id}).andWhere("type=2").andWhere("score>=100").getRawMany();
let newScore = 0;
if (scoreArray && scoreArray.length !== 0) {
let num = 0;
for(let i=0;i<userACArray.length;i++){
const problem_id = userACArray[i].p_id;
const item = scoreArray.find(item => item.problem_id === problem_id)
num+=parseInt(item.score);
}
newScore = num - userACArray.length * 100;
}
const originRating = syzoj.config.default.user.rating;
const newRating = originRating + newScore;
const newRating = originRating + userACArray.length * syzoj.config.practice_rating;
await userQuery.update(User).set({rating: newRating}).where('id=:u_id',{u_id}).execute();
res.send({newRating: newRating});
}
res.send();
} catch(e) {
console.log(e);
res.send({ error_code: e.errno, error_msg: '练习失败,请稍后重试' });
}
});

2
modules/problem.js

@ -633,7 +633,7 @@ app.post('/problem/practice/:pid/:cid/submit', app.multer.fields([{ name: 'answe
});
if (!await problem.isAllowedUseBy(curUser)) throw new ErrorMessage('您没有权限进行此操作。');
judge_state.type = 2;
judge_state.type = 0;
await judge_state.save();
await judge_state.updateRelatedInfo(true);

4
views/admin_classify.ejs

@ -109,10 +109,10 @@
</div>
</div>
</div>
<link href="https://cdn.bootcss.com/element-ui/2.13.0/theme-chalk/index.css" rel="stylesheet">
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://cdn.bootcss.com/element-ui/2.13.0/index.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<% include problem_table %>
<script>
new window.Vue({

4
views/header.ejs

@ -33,10 +33,10 @@
<link href="<%- this.builtInCdnUrl %>/google-fonts/exo-2.css" rel="stylesheet">
<% } %>
<script src="<%- lib('jquery/3.3.1/jquery.min.js') %>"></script>
<link href="https://cdn.bootcss.com/element-ui/2.13.0/theme-chalk/index.css" rel="stylesheet">
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" />
<!-- 引入组件库 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://cdn.bootcss.com/element-ui/2.13.0/index.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<% if (syzoj.config.google_analytics && syzoj.config.google_analytics !== 'UA-XXXXXXXX-X') { %>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){

1
views/submission.ejs

@ -36,7 +36,6 @@
<tr>
<th>已分享</th>
<th>编号</th>
<th>提交类型</th>
<th>题目</th>
<th>状态</th>
<th v-if="displayConfig.showScore">分数</th>

1
views/submission_contest.ejs

@ -37,7 +37,6 @@
<tr>
<th>已分享</th>
<th>编号</th>
<th>提交类型</th>
<th>题目</th>
<th>状态</th>
<th v-if="displayConfig.showScore">分数</th>

46
views/submission_practice.ejs

@ -37,9 +37,7 @@
<table class="ui very basic center aligned table" id="status_table">
<thead>
<tr>
<th>已分享</th>
<th>编号</th>
<th>提交类型</th>
<th>题目</th>
<th>状态</th>
<th v-if="displayConfig.showScore">分数</th>
@ -348,7 +346,7 @@ if (token != null) {
console.log("Judge finished");
vueApp.roughData.running = false;
vueApp.roughData.result = p.roughResult;
if (p.roughResult && p.roughResult.result === 'Accepted') {
if (p.roughResult.result === 'Accepted') {
$.ajax({
url: `/api/pass/${cid}/${pid}/${sid}`,
type: 'GET',
@ -384,32 +382,32 @@ if (token != null) {
// }
// data.running=false;
if (data && data.ok) {
if (data.roughResult && data.roughResult.result === 'Accepted') {
$.ajax({
url: `/api/pass/${cid}/${pid}/${sid}`,
type: 'GET',
success: function (data) {
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('练习功能发生故障');
}
});
} else {
$.ajax({
url: `/api/nopass/${cid}/${pid}/${sid}`,
type: 'GET',
success: function (data) {
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('练习功能发生故障');
}
});
}
if (data.finished) {
vueApp.roughData.result = data.roughResult;
// if (!data.result) location.reload(true);
vueApp.detailResult = data.result;
vueApp.roughData.running = false;
// if (data.roughResult.result === 'Accepted') {
// $.ajax({
// url: `/api/pass/${cid}/${pid}/${sid}`,
// type: 'GET',
// success: function (data) {
// },
// error: function (XMLHttpRequest, textStatus, errorThrown) {
// alert('练习功能发生故障');
// }
// });
// } else {
// $.ajax({
// url: `/api/nopass/${cid}/${pid}/${sid}`,
// type: 'GET',
// success: function (data) {
// },
// error: function (XMLHttpRequest, textStatus, errorThrown) {
// alert('练习功能发生故障');
// }
// });
// }
socket.close();
} else {
if (data.running) {

1
views/submissions.ejs

@ -108,7 +108,6 @@
<tr>
<th>已分享</th>
<th>编号</th>
<th>提交类型</th>
<th>题目</th>
<th>状态</th>
<th v-if="displayConfig.showScore">分数</th>

23
views/submissions_item.ejs

@ -22,16 +22,6 @@
template: '#submissionItemTemplate',
props: ['data', 'config', 'showRejudge', 'showShare', 'progress', 'compiling', 'rough'],
computed: {
type() {
let type = "";
switch(this.data.info.type) {
case 0: type = "普通提交";break;
case 1: type = "比赛提交";break;
case 2: type = "练习提交";break;
default:type="普通提交";
}
return type;
},
statusString() {
const data = this.data;
@ -83,15 +73,10 @@
<tr>
<td><i class="icon" :class="data.info.is_share ? 'smile outline success': 'meh outline'" style="font-size: 1.5em"></i></td>
<td><a :href="submissionLink"><b>#{{ data.info.submissionId }}</b></a></td>
<td>{{type}}</td>
<td ref="problemLabel">
<a ref="problemLabelTextFit"
style="width: 230px; height: 22px; display: block; margin: 0 auto; line-height: 22px;"
:href="problemLink"
>
<b>#{{ config.inContest ? alpha(data.info.problemId) : data.info.problemId }}.</b>
{{ data.info.problemName }}</a>
</td>
<td ref="problemLabel"><a ref="problemLabelTextFit"
style="width: 230px; height: 22px; display: block; margin: 0 auto; line-height: 22px;"
:href="problemLink"><b>#{{ config.inContest ? alpha(data.info.problemId) :
data.info.problemId }}.</b> {{ data.info.problemName }}</a></td>
<% if (active === 'submissions') { %>
<td><a :href="submissionLink"><b>
<status-label :status="statusString" :progress="progress"></status-label>

Loading…
Cancel
Save