CF-Predictor

This extension predicts rating changes for Codeforces. It shows approximate deltas during and after the contest.

当前为 2018-02-01 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         CF-Predictor
// @version      1.2.1
// @description  This extension predicts rating changes for Codeforces. It shows approximate deltas during and after the contest.
// @author       Originally by WslF, Edited by ZZYSonny
// @match        http://codeforces.com/contest/*/standings*
// @connect      cf-predictor-frontend.herokuapp.com
// @grant        GM_xmlhttpRequest
// @namespace https://greasyfork.org/users/169007
// ==/UserScript==

(function() {
    'use strict';
    var partyNum = 0;
    var deltas = [];
    showDeltas();

    function modifyPartyHtml(index, elem) {
        var delta = 0;

        if (partyNum > 0) {
            var handle = $(elem).find("td:eq(1)").find("a").first().html();
            if (handle) {
                //next 2 lines - fix for legendary grandmaster
                handle = handle.replace('<span class="legendary-user-first-letter">','');
                handle = handle.replace('</span>','');
                if (handle in deltas) {
                    delta = Math.round(deltas[handle]);
                }
            }
        }

        var text;
        if (partyNum == 0) {
            text = "<th class='top right' style='width: 4em;'><span title='Rating change''>&Delta;</span></th>";
        } else {
            var darkClass = "";
            if (partyNum % 2 == 1) {
                darkClass = "dark ";
            }
            if (delta > 0) {
                text = "<td class='" + darkClass + "right'><span style='color:green;font-weight:bold;'>+" + delta + "</span></td>";
            } else {
                text = "<td class='" + darkClass + "right'><span style='color:gray;font-weight:bold;'>" + delta + "</span></td>";
            }
        }

        partyNum++;
        $(elem).append(text);
    }

    function showDeltas() {
        var count = $(".standings").find("tr").length;
        if (count > 2) {
            var contestId = document.location.href.replace(/\D+/ig, ',').substr(1).split(',')[0];
            getDeltas(contestId, function() {
                $(".standings").find("tr").first().find("th").last().removeClass("right");
                $(".standings").find("tr").find("td").removeClass("right");
                $(".standings").find("tr").each(modifyPartyHtml);
                if (count % 2 == 0) {
                    $(".standings").find("tr").last().find("td").last().replaceWith("<td class='smaller bottom dark right'> </td>");
                } else {
                    $(".standings").find("tr").last().find("td").last().replaceWith("<td class='smaller bottom right'> </td>");
                }
            });
        }
    }

    function getDeltas(contestId, callback) {
        var herokuServer = "https://cf-predictor-frontend.herokuapp.com/";
        var page = 	"GetNextRatingServlet?contestId=" + contestId;

        var server = herokuServer + page;
        GM_xmlhttpRequest({
            method: "GET",
            url: server,
            onload: function(res) {
                var text = res.responseText;
                var data = JSON.parse(text);
                for (var i = 0; i < data.result.length; i++) {
                    var handle = data.result[i].handle;
                    var delta = data.result[i].newRating - data.result[i].oldRating;
                    deltas[handle] = delta;
                }
                callback();
            }
        });
    }

})();