您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
AtCoderのACを超派手に演出する
// ==UserScript== // @name AC Super Ultra Many Very Happy Notification // @namespace http://tampermonkey.net/ // @version 2025-06-19 // @description AtCoderのACを超派手に演出する // @author Kicky1618 // @match https://atcoder.jp/contests/**/* // @grant none // @license MIT // ==/UserScript== /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ({ /***/ "./src/audio.ts": /*!**********************!*\ !*** ./src/audio.ts ***! \**********************/ /***/ ((__unused_webpack_module, exports) => { Object.defineProperty(exports, "__esModule", ({ value: true })); exports.audioText = void 0; exports.audioText = "https://kangping-git.github.io/boxes/keiosei.mp3"; /***/ }), /***/ "./src/index.ts": /*!**********************!*\ !*** ./src/index.ts ***! \**********************/ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); const audio_1 = __webpack_require__(/*! ./audio */ "./src/audio.ts"); function getNewSubmission(contestId) { return __awaiter(this, void 0, void 0, function* () { const response = yield fetch(`https://atcoder.jp/contests/${contestId}/submissions/me`); if (!response.ok) { throw new Error("Failed to fetch submissions"); } const data = yield response.text(); const $ = new DOMParser().parseFromString(data, "text/html"); const submissions = $.querySelectorAll(".table-responsive tbody tr"); const submissionList = []; submissions.forEach((submission) => { var _a; const cols = submission.querySelectorAll("td"); if (cols.length < 7) return; const submissionData = { id: cols[0].innerText.trim(), problem: ((_a = cols[1].querySelector("a")) === null || _a === void 0 ? void 0 : _a.href.split("/")[6].trim()) || "", result: cols[6].innerText.trim(), }; submissionList.push(submissionData); }); return submissionList; }); } function ACEffect(task) { const audio = new Audio(audio_1.audioText); audio.loop = true; audio.play(); h1.innerText = `Problem ${task.toUpperCase()} AC!`; h1.style.transition = "top 0.5s ease-in-out"; h1.style.top = "100px"; h1.style.color = "red"; h1.style.fontSize = "5vw"; setTimeout(() => { h1.style.top = "-100px"; h1.innerText = ""; mainContainer.style.background = ""; mainDiv.style.background = ""; chokudaiImage1.style.display = "none"; chokudaiImage2.style.display = "none"; audio.pause(); elements = []; }, 10000); const mainDiv = document.querySelector("#main-div"); const mainContainer = document.querySelector("#main-container"); setGradientStyleDom(mainDiv); setGradientStyleDom(mainContainer); chokudaiImage1.style.display = "block"; chokudaiImage2.style.display = "block"; } function setGradientStyleDom(element) { element.style.background = "linear-gradient(to right, #ff0000, #ff7f00, #ffff00, #00ff00, #0000ff, #4b0082, #9400d3, #ff0000)"; element.style.backgroundSize = "400% 400%"; elements.push(element); } let elements = []; function tick() { requestAnimationFrame(tick); elements.forEach((element) => { const now = Date.now() / 500; const offset = now % 5; element.style.backgroundPosition = `${offset * 100}% 50%`; }); chokudaiImage1.style.transform = `rotateZ(30deg) translateX(${Math.sin(Date.now() / 1000) * 10}px)`; chokudaiImage2.style.transform = `scaleX(-1) rotateZ(30deg) translateX(${Math.sin(Date.now() / 1000) * 10}px)`; chokudaiImage1.style.bottom = `${-200 + Math.sin(Date.now() / 300) * 300}px`; chokudaiImage2.style.bottom = `${-200 + Math.sin(Date.now() / 300 - Math.PI) * 300}px`; chokudaiImage1.style.left = `${-100 + Math.sin(Date.now() / 300) * 150}px`; chokudaiImage2.style.right = `${-100 + Math.sin(Date.now() / 300 - Math.PI) * 150}px`; } setInterval(() => __awaiter(void 0, void 0, void 0, function* () { if (!contestId) return; const lastUpdate = localStorage.getItem("atcoder_hightension_lastupdate_" + contestId); if (!lastUpdate || new Date(lastUpdate).getTime() < Date.now() - 1000 * 3) { const submissions = yield getNewSubmission(contestId); const lastSubmissionNow = submissions[0].id || "0"; if (submissions[0].result === "AC") { localStorage.setItem("atcoder_hightension_lastsubmission_" + contestId, lastSubmissionNow + "_" + submissions[0].problem); } } localStorage.setItem("atcoder_hightension_lastupdate_" + contestId, new Date().toISOString()); const lastSubmissionNow = localStorage.getItem("atcoder_hightension_lastsubmission_" + contestId); if (lastSubmissionNow && lastSubmissionNow !== lastSubmission && lastSubmissionNow !== "0") { const [submissionId, problemId] = lastSubmissionNow.split("_"); if (submissionId && problemId) { ACEffect(problemId); } } lastSubmission = lastSubmissionNow || "0"; }), 1000 * 5); const contestId = location.pathname.split("/")[2]; let lastSubmission = localStorage.getItem("atcoder_hightension_lastsubmission_" + contestId); if (!lastSubmission) { lastSubmission = "0"; } const h1 = document.createElement("h1"); h1.innerText = ""; h1.style.position = "fixed"; h1.style.top = "-100px"; h1.style.left = "50vw"; h1.style.transform = "translateX(-50%)"; h1.style.zIndex = "1000"; document.body.appendChild(h1); const chokudaiImage1 = document.createElement("img"); chokudaiImage1.src = "https://kangping-git.github.io/boxes/sfc.png"; chokudaiImage1.style.position = "fixed"; chokudaiImage1.style.bottom = "-200px"; chokudaiImage1.style.left = "-100px"; chokudaiImage1.style.zIndex = "1000"; chokudaiImage1.style.width = "400px"; chokudaiImage1.style.transform = "rotateX(-45deg)"; chokudaiImage1.style.display = "none"; document.body.appendChild(chokudaiImage1); const chokudaiImage2 = document.createElement("img"); chokudaiImage2.src = "https://kangping-git.github.io/boxes/sfc.png"; chokudaiImage2.style.position = "fixed"; chokudaiImage2.style.bottom = "-200px"; chokudaiImage2.style.right = "-100px"; chokudaiImage2.style.zIndex = "1000"; chokudaiImage2.style.width = "400px"; chokudaiImage2.style.transform = "scaleX(-1) rotateX(45deg)"; chokudaiImage2.style.display = "none"; document.body.appendChild(chokudaiImage2); tick(); /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /******/ // startup /******/ // Load entry module and return exports /******/ // This entry module is referenced by other modules so it can't be inlined /******/ var __webpack_exports__ = __webpack_require__("./src/index.ts"); /******/ /******/ })() ;