feat(remote_judger/codeforces): submit use own account
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Baoshuo Ren 2023-02-03 16:16:24 +08:00
parent a940ac3bbb
commit eead1d8c85
Signed by: baoshuo
GPG Key ID: 00CB9680AB29F51A
3 changed files with 77 additions and 6 deletions

View File

@ -11,7 +11,7 @@ import Logger from '../utils/logger';
proxy(superagent); proxy(superagent);
const logger = new Logger('remote/codeforces'); const logger = new Logger('remote/codeforces');
const langs_map = { const LANGS_MAP = {
C: { C: {
name: 'GNU GCC C11 5.1.0', name: 'GNU GCC C11 5.1.0',
id: 43, id: 43,
@ -88,7 +88,10 @@ export default class CodeforcesProvider implements IBasicProvider {
} }
static constructFromAccountData(data) { static constructFromAccountData(data) {
throw new Error('Method not implemented.'); return new this({
type: 'codeforces',
cookie: Object.entries(data).map(([key, value]) => `${key}=${value}`),
});
} }
cookie: string[] = []; cookie: string[] = [];
@ -166,23 +169,41 @@ export default class CodeforcesProvider implements IBasicProvider {
get loggedIn() { get loggedIn() {
return this.get('/enter').then(res => { return this.get('/enter').then(res => {
const html = res.text; const html = res.text;
if (html.includes('Login into Codeforces')) return false; if (html.includes('Login into Codeforces')) return false;
if (html.length < 1000 && html.includes('Redirecting...')) { if (html.length < 1000 && html.includes('Redirecting...')) {
logger.debug('Got a redirect', html); logger.debug('Got a redirect', html);
return false; return false;
} }
if (res.header['set-cookie']) {
const _39ce7 = this.getCookie.call(
{ cookie: res.header['set-cookie'] },
'39ce7'
);
if (_39ce7) this.setCookie('39ce7', _39ce7);
}
return true; return true;
}); });
} }
async ensureLogin() { async ensureLogin() {
if (await this.loggedIn) return true; if (await this.loggedIn) return true;
logger.info('retry normal login'); logger.info('retry normal login');
if (!this.account.handle) return false;
const [csrf, ftaa, bfaa] = await this.getCsrfToken('/enter'); const [csrf, ftaa, bfaa] = await this.getCsrfToken('/enter');
const { header } = await this.get('/enter'); const { header } = await this.get('/enter');
if (header['set-cookie']) { if (header['set-cookie']) {
this.cookie = header['set-cookie']; this.cookie = header['set-cookie'];
} }
const res = await this.post('/enter').send({ const res = await this.post('/enter').send({
csrf_token: csrf, csrf_token: csrf,
action: 'enter', action: 'enter',
@ -193,10 +214,13 @@ export default class CodeforcesProvider implements IBasicProvider {
remember: 'on', remember: 'on',
_tta: this.tta(this.getCookie('39ce7')), _tta: this.tta(this.getCookie('39ce7')),
}); });
const cookie = res.header['set-cookie']; const cookie = res.header['set-cookie'];
if (cookie) { if (cookie) {
this.cookie = cookie; this.cookie = cookie;
} }
if (await this.loggedIn) { if (await this.loggedIn) {
logger.success('Logged in'); logger.success('Logged in');
return true; return true;
@ -212,18 +236,32 @@ export default class CodeforcesProvider implements IBasicProvider {
next, next,
end end
) { ) {
const programType = langs_map[lang] || langs_map['C++']; if (!(await this.ensureLogin())) {
end({
error: true,
status: 'Judgment Failed',
message: 'Login failed',
});
return null;
}
const programType = LANGS_MAP[lang] || LANGS_MAP['C++'];
const comment = programType.comment; const comment = programType.comment;
if (comment) { if (comment) {
const msg = `S2OJ Submission #${submissionId} @ ${new Date().getTime()}`; const msg = `S2OJ Submission #${submissionId} @ ${new Date().getTime()}`;
if (typeof comment === 'string') code = `${comment} ${msg}\n${code}`; if (typeof comment === 'string') code = `${comment} ${msg}\n${code}`;
else if (comment instanceof Array) else if (comment instanceof Array)
code = `${comment[0]} ${msg} ${comment[1]}\n${code}`; code = `${comment[0]} ${msg} ${comment[1]}\n${code}`;
} }
const [type, contestId, problemId] = parseProblemId(id); const [type, contestId, problemId] = parseProblemId(id);
const [csrf, ftaa, bfaa] = await this.getCsrfToken( const [csrf, ftaa, bfaa] = await this.getCsrfToken(
type !== 'GYM' ? '/problemset/submit' : `/gym/${contestId}/submit` type !== 'GYM' ? '/problemset/submit' : `/gym/${contestId}/submit`
); );
logger.debug( logger.debug(
'Submitting', 'Submitting',
id, id,
@ -231,6 +269,7 @@ export default class CodeforcesProvider implements IBasicProvider {
lang, lang,
`(S2OJ Submission #${submissionId})` `(S2OJ Submission #${submissionId})`
); );
// TODO: check submit time to ensure submission // TODO: check submit time to ensure submission
const { text: submit, error } = await this.post( const { text: submit, error } = await this.post(
`/${ `/${

View File

@ -14,7 +14,7 @@ class UOJRemoteProblem {
'ограничение по времени на тест', 'ограничение по времени на тест',
], ],
'languages' => ['C', 'C++', 'C++17', 'C++20', 'Java17', 'Pascal', 'Python2', 'Python3'], 'languages' => ['C', 'C++', 'C++17', 'C++20', 'Java17', 'Pascal', 'Python2', 'Python3'],
'submit_type' => ['bot'], 'submit_type' => ['bot', 'my'],
], ],
'atcoder' => [ 'atcoder' => [
'name' => 'AtCoder', 'name' => 'AtCoder',

View File

@ -1026,15 +1026,47 @@ $.fn.remote_submit_type_group = function(oj, pid, url, submit_type) {
div_submit_type_my.append( div_submit_type_my.append(
$('<div class="row mt-3" />') $('<div class="row mt-3" />')
.append($('<div class="col-sm-2" />').append('<label for="input-luogu_uid" class="form-col-label">_uid</label>')) .append($('<div class="col-sm-2" />').append('<label for="input-luogu_uid" class="col-form-label">_uid</label>'))
.append($('<div class="col-sm-4" />').append(input_luogu_uid)) .append($('<div class="col-sm-4" />').append(input_luogu_uid))
.append($('<div class="col-sm-6" />').append($('<div class="form-text" />').append('请填入 Cookie 中的 <code>_uid</code>。'))) .append($('<div class="col-sm-6" />').append($('<div class="form-text" />').append('请填入 Cookie 中的 <code>_uid</code>。')))
).append( ).append(
$('<div class="row mt-3" />') $('<div class="row mt-3" />')
.append($('<div class="col-sm-2" />').append('<label for="input-luogu_client_id" class="form-col-label">__client_id</label>')) .append($('<div class="col-sm-2" />').append('<label for="input-luogu_client_id" class="col-form-label">__client_id</label>'))
.append($('<div class="col-sm-4" />').append(input_luogu_client_id)) .append($('<div class="col-sm-4" />').append(input_luogu_client_id))
.append($('<div class="col-sm-6" />').append($('<div class="form-text" />').append('请填入 Cookie 中的 <code>__client_id</code>。'))) .append($('<div class="col-sm-6" />').append($('<div class="form-text" />').append('请填入 Cookie 中的 <code>__client_id</code>。')))
).append(input_my_account_data); ).append(input_my_account_data);
} else if (oj == 'codeforces') {
var codeforces_account_data = {"JSESSIONID": ""};
var input_codeforces_jsessionid = $('<input class="form-control" type="text" name="codeforces_jsessionid" id="input-codeforces_jsessionid" />');
if ('localStorage' in window) {
try {
var codeforces_account_data_str = localStorage.getItem('uoj_remote_judge_codeforces_account_data');
if (codeforces_account_data_str) {
codeforces_account_data = JSON.parse(codeforces_account_data_str);
}
} catch (e) {}
var save_codeforces_account_data = function() {
localStorage.setItem('uoj_remote_judge_codeforces_account_data', JSON.stringify(codeforces_account_data));
}
}
input_codeforces_jsessionid.change(function() {
codeforces_account_data.JSESSIONID = $(this).val();
input_my_account_data.val(JSON.stringify(codeforces_account_data));
save_codeforces_account_data();
});
input_my_account_data.val(JSON.stringify(codeforces_account_data));
input_codeforces_jsessionid.val(codeforces_account_data.JSESSIONID);
div_submit_type_my.append(
$('<div class="row mt-3" />')
.append($('<div class="col-sm-2" />').append('<label for="input-codeforces_jsessionid" class="col-form-label">JSESSIONID</label>'))
.append($('<div class="col-sm-4" />').append(input_codeforces_jsessionid))
.append($('<div class="col-sm-6" />').append($('<div class="form-text" />').append('请填入 Cookie 中的 <code>JSESSIONID</code>。')))
).append(input_my_account_data);
} }
$(this).append( $(this).append(