您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
提出一覧のユーザ名を色付けします
// ==UserScript== // @name AtCoder Submission User Colorizer // @namespace http://tampermonkey.net/ // @version 1.3 // @description 提出一覧のユーザ名を色付けします // @author morio_prog // @match https://atcoder.jp/contests/*/submissions* // @grant none // @license CC0 // @require https://unpkg.com/lscache/lscache.min.js // ==/UserScript== $(function() { 'use strict'; const lastUpdateKey = 'user-colorizer-ranking-last-update'; const rankingKey = 'user-colorizer-ranking'; const OUT_OF_RANK = Number.MAX_VALUE; // > 100 function getColor(rating) { if (rating >= 2800) return '#FF0000'; if (rating >= 2400) return '#FF8000'; if (rating >= 2000) return '#C0C000'; if (rating >= 1600) return '#0000FF'; if (rating >= 1200) return '#00C0C0'; if (rating >= 800) return '#008000'; if (rating >= 400) return '#804000'; if (rating > 0) return '#808080'; return '#000000'; } function getColorClass(rating) { if (rating >= 2800) return 'user-red'; if (rating >= 2400) return 'user-orange'; if (rating >= 2000) return 'user-yellow'; if (rating >= 1600) return 'user-blue'; if (rating >= 1200) return 'user-cyan'; if (rating >= 800) return 'user-green'; if (rating >= 400) return 'user-brown'; if (rating > 0) return 'user-gray'; return 'user-unrated'; } function getAchRate(rating) { const base = Math.floor(rating / 400) * 400; return ((rating - base) / 400) * 100; } function colorize(u, ranking, rating) { /* */if (ranking <= 1) $(u).before('<img style="vertical-align: middle;" src="//img.atcoder.jp/assets/icon/crown_champion.png"> '); else if (ranking <= 10) $(u).before('<img style="vertical-align: middle;" src="//img.atcoder.jp/assets/icon/crown_gold.png"> '); else if (ranking <= 30) $(u).before('<img style="vertical-align: middle;" src="//img.atcoder.jp/assets/icon/crown_silver.png"> '); else if (ranking <= 100) $(u).before('<img style="vertical-align: middle;" src="//img.atcoder.jp/assets/icon/crown_bronze.png"> '); else if (rating > 0) { const color = getColor(rating); const achRate = getAchRate(rating); $(u).before(` <span style=" display: inline-block; height: 12px; width: 12px; vertical-align: center; border-radius: 50%; border: solid 1px ${color}; background: -webkit-linear-gradient( bottom, ${color} 0%, ${color} ${achRate}%, rgba(255, 255, 255, 0.0) ${achRate}%, rgba(255, 255, 255, 0.0) 100%); "></span> `); } $(u).addClass(getColorClass(rating)); } function getRankingMap() { return new Promise(function(callback) { const currentTime = new Date().getTime(); const lastUpdateTime = localStorage.getItem(lastUpdateKey); // Update every 3 hours if (lastUpdateTime && currentTime < Number(lastUpdateTime) + 3 * 60 * 60 * 1000) { callback(JSON.parse(localStorage.getItem(rankingKey))); } else { let ranking = {}; $.ajax({ url: "https://atcoder.jp/ranking", type: 'GET', dataType: 'html' }) .done(function(data) { $($.parseHTML(data)).find('.username > span').each(function(idx) { const userName = $(this).text(); ranking[userName] = idx + 1; }); }) .then(function() { localStorage.setItem(lastUpdateKey, currentTime); localStorage.setItem(rankingKey, JSON.stringify(ranking)); callback(ranking); }); } }); } function getRanking(rankingMap, userName) { if (userName in rankingMap) return rankingMap[userName]; return OUT_OF_RANK; } lscache.flushExpired(); getRankingMap().then((rankingMap) => { let index = 0; $('a[href*="/users"]').each(function(_, u) { // Skip "My Profile" if ($(u).find('span').length) return true; const partUri = $(this).attr('href'); const userName = partUri.slice(7); const lskey = "rating-" + userName; const ranking = getRanking(rankingMap, userName); let rating = lscache.get(lskey); if (rating !== null) { colorize(u, ranking, rating); return; } index += 1; setTimeout(function() { $.ajax({ url: "https://atcoder.jp" + partUri + "/history/json", type: 'GET', dataType: 'json' }) .done(function(data) { const ratedCount = data.length; if (ratedCount == 0) { rating = 0; } else { rating = data[ratedCount - 1]["NewRating"]; } // Update every 3 hours lscache.set(lskey, rating, 3 * 60); }) .then(function() { colorize(u, ranking, rating); }); }, index * 300); }); }); });