Onetricks.gg Score Calculation

Automatically scores OTPs based on win rate, games, LP, and play rate

当前为 2025-10-06 提交的版本,查看 最新版本

// ==UserScript==
// @name         Onetricks.gg Score Calculation        
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  Automatically scores OTPs based on win rate, games, LP, and play rate
// @author       Joshinon
// @match        https://www.onetricks.gg/*
// @grant        none
// @run-at       document-idle
// @license      MIT
// ==/UserScript==

// NOTE: THIS IS AN UNOFFICIAL COMMUNITY EXTENSION. IT IS NOT CREATED, ENDORSED, OR SUPPORTED BY ONETRICKS.GG. PLEASE USE RESPONSIBLY.

(function() {
    'use strict';

    const POLL_INTERVAL = 300;
    let headerAdded = false;

    function parseNumber(str) {
        return parseFloat(str.replace(/[,%LP\s]/g,'').trim());
    }

    function calculateScores() {
        const table = document.querySelector("table");
        if (!table) return;

        const tbody = table.querySelector("tbody");
        if (!tbody) return;

        const rows = Array.from(tbody.querySelectorAll("tr"));
        if (!rows.length) return;

        const headerRow = rows[0];
        const dataRows = rows.slice(1);

        if (!headerAdded && headerRow) {
            const headerCell = document.createElement("td");
            headerCell.className = "score-header";
            headerCell.innerText = "Score";
            headerCell.style.cursor = "pointer";
            headerRow.appendChild(headerCell);
            headerAdded = true;
        }

        const scoredRows = [];

        dataRows.forEach(row => {
            const cells = row.querySelectorAll("td");
            if (cells.length < 12) return;

            const playRate = parseNumber(cells[8]?.innerText || '');
            const games = parseNumber(cells[9]?.innerText || '');
            const winRate = parseNumber(cells[10]?.innerText || '');
            const lp = parseNumber(cells[7]?.innerText || '');

            if ([playRate, games, winRate, lp].some(isNaN)) return;

            const reliability = 1 - Math.exp(-games / 250);
            const winrateScore = Math.max(0, (winRate - 40) * 2);
            const playrateScore = Math.min(playRate, 15);
            const lpScore = Math.min(lp * 0.02, 30);
            const commitmentBonus = playRate >= 50 ? 5 : 0; // OTPs with higher playrate than 50 gets a flat bonus score (default: 5)

            // change this if you want any factor weights more/less (default: 0.8 0.15 0.3)
            const score = (winrateScore * reliability * 0.8) + (playrateScore * 0.15) + (lpScore * 0.3) + commitmentBonus; 

            let scoreCell = row.querySelector(".score-cell");
            if (!scoreCell) {
                scoreCell = document.createElement("td");
                scoreCell.className = "score-cell";
                row.appendChild(scoreCell);
            }

            scoreCell.innerText = score.toFixed(2);
            scoreCell.style.fontWeight = "bold";
            scoreCell.style.color = playRate >= 50 ? "#00ff88" : "#ffffff";

            row.dataset.score = score;
            scoredRows.push(row);
        });

        if (!scoredRows.length) return;

        const sorted = scoredRows.slice().sort((a,b) => b.dataset.score - a.dataset.score);
        const others = dataRows.filter(r => !scoredRows.includes(r));

        tbody.innerHTML = '';
        tbody.appendChild(headerRow);
        sorted.forEach(r => tbody.appendChild(r));
        others.forEach(r => tbody.appendChild(r));
    }

    setInterval(calculateScores, POLL_INTERVAL);
})();