diff --git a/packages/vjudge/package.json b/packages/vjudge/package.json index 5b5df94c5..0741a14c5 100644 --- a/packages/vjudge/package.json +++ b/packages/vjudge/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/vjudge", - "version": "1.4.12", + "version": "1.4.13", "description": "Submit problems to remote oj", "main": "package.json", "repository": "https://github.com/hydro-dev/Hydro.git", diff --git a/packages/vjudge/src/providers/codeforces.ts b/packages/vjudge/src/providers/codeforces.ts index 767306799..e451886f3 100644 --- a/packages/vjudge/src/providers/codeforces.ts +++ b/packages/vjudge/src/providers/codeforces.ts @@ -20,8 +20,6 @@ export default class CodeforcesProvider implements IBasicProvider { } cookie: string[] = []; - // @ts-ignore - ftaa = String.random(18, 'abcdef1234567890'); csrf: string; get(url: string) { @@ -40,6 +38,10 @@ export default class CodeforcesProvider implements IBasicProvider { return req; } + getCookie(target: string) { + return this.cookie.find((i) => i.startsWith(`${target}=`))?.split('=')[1]?.split(';')[0]; + } + tta(_39ce7: string) { let _tta = 0; for (let c = 0; c < _39ce7.length; c++) { @@ -58,10 +60,15 @@ export default class CodeforcesProvider implements IBasicProvider { if (document.body.children.length < 2 && html.length < 512) { throw new Error(document.body.textContent); } - return ( - document.querySelector('meta[name="X-Csrf-Token"]') - || document.querySelector('input[name="csrf_token"]') - )?.getAttribute('content'); + const ftaa = this.getCookie('70a7c28f3de'); + const bfaa = /_bfaa = "(.{32})"/.exec(html)?.[1] || this.getCookie('raa') || this.getCookie('bfaa'); + return [ + ( + document.querySelector('meta[name="X-Csrf-Token"]') + || document.querySelector('input[name="csrf_token"]') + )?.getAttribute('content'), + ftaa, bfaa, + ]; } get loggedIn() { @@ -74,11 +81,12 @@ export default class CodeforcesProvider implements IBasicProvider { async ensureLogin() { if (await this.loggedIn) return true; logger.info('retry login'); + const [csrf, ftaa, bfaa] = await this.getCsrfToken('/enter'); const res = await this.post('/enter').send({ - csrf_token: await this.getCsrfToken('/enter'), + csrf_token: csrf, action: 'enter', - ftaa: '', - bfaa: '', + ftaa, + bfaa, handleOrEmail: this.account.handle, password: this.account.password, remember: 'on', @@ -193,23 +201,19 @@ export default class CodeforcesProvider implements IBasicProvider { if (typeof comment === 'string') code = `${comment} ${msg}\n${code}`; else if (comment instanceof Array) code = `${comment[0]} ${msg} ${comment[1]}\n${code}`; } - const [, contestId, submittedProblemIndex] = id.startsWith('P921') - ? ['', '921', id.split('P921')[1]] - : /^P(\d+)([A-Z][0-9]*)$/.exec(id); - const csrf = await this.getCsrfToken('/problemset/submit'); + const [csrf, ftaa, bfaa] = await this.getCsrfToken('/problemset/submit'); // TODO check submit time to ensure submission await this.post(`/problemset/submit?csrf_token=${csrf}`).send({ csrf_token: csrf, - contestId, action: 'submitSolutionFormSubmitted', programTypeId, - submittedProblemIndex, + submittedProblemCode: id.split('P')[1], source: code, tabsize: 4, sourceFile: '', - ftaa: '', - bfaa: 'f1b3f18c715565b589b7823cda7448ce', - _tta: 140, + ftaa, + bfaa, + _tta: this.tta(this.getCookie('39ce7')), sourceCodeConfirmed: true, }); const { text: status } = await this.get('/problemset/status?my=on');