您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
OMCでユーザー名を検索できます
// ==UserScript== // @name OMC Standings Search // @namespace https://onlinemathcontest.com/ // @version 1.0 // @description OMCでユーザー名を検索できます // @match https://onlinemathcontest.com/contests/*/standings* // @grant none // @license MIT // ==/UserScript== (function () { 'use strict'; if (!/\/contests\/[^/]+\/standings/.test(location.href)) return; const contestMatch = location.href.match(/contests\/([^/]+)\/standings/); if (!contestMatch) return; const contestId = contestMatch[1]; const standingsApi = `/api/contests/${contestId}/standings`; fetch(`${standingsApi}?rated=0`) .then(res => res.json()) .then(data => { const standingsEl = document.getElementById('standings'); if (!standingsEl) return; const { isPast, is_point_visible } = data; if (!(isPast && is_point_visible)) return; const container = document.querySelector('div.container'); const form = container?.querySelector('form'); if (form) { form.insertAdjacentHTML('afterend', ` <div class="form-inline my-2" style="margin-bottom:1em;"> <input type="text" id="userSearchInput" placeholder="ユーザー名を入力" class="form-control mr-2"> <button id="userSearchBtn" class="btn btn-primary">Search</button> <span id="userSearchStatus" style="margin-left:1em;color:#666;"></span> </div> `); } const inputEl = document.getElementById('userSearchInput'); const searchBtn = document.getElementById('userSearchBtn'); const statusEl = document.getElementById('userSearchStatus'); const isRatedChecked = () => document.getElementById('ratedCheckbox')?.checked ? 1 : 0; async function searchUser(giveup) { const targetName = inputEl.value.trim().toLowerCase(); if (!targetName) return; searchBtn.disabled = true; statusEl.textContent = ''; try { const res = await fetch(`${standingsApi}?rated=${isRatedChecked()}`, { credentials: 'same-origin' }); const { standings } = await res.json(); const userIndex = standings.findIndex(s => s.user.id.toLowerCase() === targetName); if (userIndex === -1) { searchBtn.disabled = false; return; } const targetPage = Math.floor(userIndex / 20) + 1; const navigateToPage = () => { for (let trying=0; trying<10;trying++){ const currentPage = parseInt(document.querySelector('.page-item.active .page-link')?.textContent.trim(), 10); if (currentPage === targetPage) { setTimeout(() => { const rows = document.querySelectorAll('tbody tr'); let found = false; rows.forEach(row => { const link = row.querySelector('a.user-link'); const rank = parseInt(row.children[0].textContent, 10); if (link?.textContent.trim().toLowerCase() === targetName && rank === standings[userIndex].rank) { found = true; Array.from(row.children).forEach(cell => { if (!cell.classList.contains('table-danger')) { cell.style.backgroundColor = '#f4f6d8'; } }); row.scrollIntoView({ behavior: 'smooth', block: 'center' }); } else { Array.from(row.children).forEach(cell => { if (window.getComputedStyle(cell, null).getPropertyValue('background-color')==='rgb(244, 246, 216)') { cell.style.backgroundColor = '#ffffff'; } }); } }); searchBtn.disabled = false if (!found && !giveup){ retrySearch(); } }, 10); return; } const pageItems = [...document.querySelectorAll('ul.pagination .page-item')]; const closest = pageItems.reduce((best, item) => { const pageNum = parseInt(item.querySelector('.page-link')?.textContent.trim(), 10); const diff = Math.abs(pageNum - targetPage); return (!isNaN(pageNum) && diff < best.diff) ? { item, diff } : best; }, { item: null, diff: Infinity }); if (closest.item) { closest.item.querySelector('.page-link').click(); //setTimeout(navigateToPage, 50); } else { searchBtn.disabled = false; } } retrySearch(); }; navigateToPage(); } catch (e) { console.error(e); searchBtn.disabled = false; } } function retrySearch() { const nextBtn = document.querySelector('.btn.btn-outline-secondary'); if (!nextBtn) return; nextBtn.click(); const waitUntilReady = () => { if (nextBtn.disabled) { searchUser(true); } else { setTimeout(waitUntilReady, 50); } }; waitUntilReady(); } searchBtn.addEventListener('click', searchUser); inputEl.addEventListener('keydown', e => { if (e.key === 'Enter') { e.preventDefault(); searchUser(false); } }); }) .catch(err => console.error('Standings fetch error:', err)); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址