您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
重複提出をチェックします。 Check for duplicate submissions.
当前为
// ==UserScript== // @name AtCoder Duplicate Checker // @namespace https://github.com/Raclamusi // @version 1.0.1 // @description 重複提出をチェックします。 Check for duplicate submissions. // @author Raclamusi // @supportURL https://github.com/Raclamusi/atcoder-duplicate-checker // @match https://atcoder.jp/contests/*/tasks/* // @match https://atcoder.jp/contests/*/submit* // @grant none // @license MIT // ==/UserScript== // AtCoder Duplicate Checker // // Copyright (c) 2022 Raclamusi // // This software is released under the MIT License, see https://github.com/Raclamusi/atcoder-duplicate-checker/blob/main/LICENSE . (function () { "use strict"; const getButtonText = lang => { const texts = { ja: "重複チェック中...", en: "Duplicate Checking...", }; return texts[lang in texts ? lang : "ja"]; }; const getMessage = (lang, time) => { const messages = { ja: ["過去に同じコードを提出しています。", "本当に提出しますか?"], en: ["You have submitted the same code before.", "Are you sure you want to submit it?"], }; const msg = messages[lang in messages ? lang : "ja"]; return `${msg[0]} (${time})\n${msg[1]}`; }; const getSubmissions = async contest => { const response = await fetch(`https://atcoder.jp/contests/${contest}/submissions/me`); const htmlText = await response.text(); const iter = htmlText.matchAll(/<tr(?:.|\s)*?<time[^>]*>(.+?)<\/time>(?:.|\s)*?submissions\/(\d+)(?:.|\s)*?<\/tr>/g); return [...iter].map(([_, time, id]) => ({ time, id })); }; const getSubmittedCode = async (contest, id) => { const response = await fetch(`https://atcoder.jp/contests/${contest}/submissions/${id}`); const htmlText = await response.text(); const escapedCode = htmlText.match(/<pre id="submission-code"[^>]*>([^<]*)<\/pre>/)[1]; const preElement = document.createElement("pre"); preElement.innerHTML = escapedCode; return preElement.textContent; }; const getDuplicateSubmisionTime = async code => { for (const { time, id } of await getSubmissions(contestScreenName)) { if (code === await getSubmittedCode(contestScreenName, id)) { return time; } } return null; }; const submitButton = document.getElementById("submit"); const submitButtonClickListener = e => { // チェックを待つため、一旦提出をキャンセル e.preventDefault(); // チェック中であれば即終了 if (submitButton.disabled) return; // 提出ボタンの表示を変更 submitButton.disabled = true; const buttonText = submitButton.textContent; submitButton.textContent = getButtonText(LANG); (async () => { // 重複チェック const time = await getDuplicateSubmisionTime(getSourceCode()); if (time === null || confirm(getMessage(LANG, time))) { // チェックが通ったら、このイベントリスナを外して本来の提出の処理をする submitButton.removeEventListener("click", submitButtonClickListener); setTimeout(() => submitButton.click()); } // 提出ボタンの表示を戻す submitButton.disabled = false; submitButton.textContent = buttonText; })(); }; submitButton.addEventListener("click", submitButtonClickListener, { passive: false }); })();