您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Automatically scores OTPs based on win rate, games, LP, and play rate
当前为
// ==UserScript== // @name Onetricks.gg Score Calculation // @namespace http://tampermonkey.net/ // @version 2.1 // @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; let table, tbody, headerRow; let sortDirection = 'desc'; // default sort: high → low let autoSortByScore = true; let scoreHeaderCell; function parseNumber(str) { return parseFloat(str.replace(/[,%LP\s]/g, '').trim()); } function init() { table = document.querySelector("table"); if (!table) return false; tbody = table.querySelector("tbody"); if (!tbody) return false; const rows = Array.from(tbody.querySelectorAll("tr")); if (!rows.length) return false; headerRow = rows[0]; if (!headerAdded) { scoreHeaderCell = document.createElement("td"); scoreHeaderCell.className = "score-header"; scoreHeaderCell.innerText = "Score ↓"; scoreHeaderCell.style.cursor = "pointer"; scoreHeaderCell.style.fontWeight = "bold"; scoreHeaderCell.style.userSelect = "none"; scoreHeaderCell.style.whiteSpace = "nowrap"; scoreHeaderCell.style.paddingLeft = "6px"; scoreHeaderCell.addEventListener("click", () => { sortDirection = sortDirection === 'desc' ? 'asc' : 'desc'; scoreHeaderCell.innerText = sortDirection === 'desc' ? "Score ↓" : "Score ↑"; autoSortByScore = true; calculateScores(true); }); headerRow.appendChild(scoreHeaderCell); const otherHeaders = headerRow.querySelectorAll("td:not(.score-header)"); otherHeaders.forEach(cell => { cell.addEventListener("click", () => { autoSortByScore = false; if (scoreHeaderCell) scoreHeaderCell.innerText = "Score"; }); }); headerAdded = true; } return true; } function calculateScores(forceSort = false) { if (!table && !init()) return; const rows = Array.from(tbody.querySelectorAll("tr")).slice(1); const scoredRows = []; rows.forEach((row, index) => { 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); // more games = more reliable score boost, full confidence at around 600 games const winrateScore = Math.max(0, (winRate - 40) * 2); // every 5% winrate = +10 points const lpScore = Math.min(lp * 0.012, 30); // 1.2 point every 100 lp, capped at 2500LP const commitmentBonus = playRate >= 50 ? 5 : 0; // + flat 5 if playrate >= 50 const score = (winrateScore * reliability * 0.8) + (lpScore * 0.45) + commitmentBonus; let scoreCell = row.querySelector(".score-cell"); if (!scoreCell) { scoreCell = document.createElement("td"); scoreCell.className = "score-cell"; row.appendChild(scoreCell); } const roundedScore = score.toFixed(2); scoreCell.innerText = roundedScore; scoreCell.style.fontWeight = "bold"; scoreCell.style.color = playRate >= 50 ? "#00ff88" : "#ffffff"; row.dataset.score = roundedScore; row.dataset.lp = lp; row.dataset.index = index; scoredRows.push(row); }); if (!scoredRows.length) return; // 🧠 Only auto-sort if we're sorting by Score if (!autoSortByScore && !forceSort) return; // ✅ Stable, reversible sort const sorted = scoredRows.sort((a, b) => { const scoreDiff = parseFloat(b.dataset.score) - parseFloat(a.dataset.score); if (Math.abs(scoreDiff) > 0.0001) return sortDirection === 'desc' ? scoreDiff : -scoreDiff; const lpDiff = parseFloat(b.dataset.lp) - parseFloat(a.dataset.lp); if (lpDiff !== 0) return sortDirection === 'desc' ? lpDiff : -lpDiff; return sortDirection === 'desc' ? a.dataset.index - b.dataset.index : b.dataset.index - a.dataset.index; }); const others = rows.filter(r => !scoredRows.includes(r)); const frag = document.createDocumentFragment(); frag.appendChild(headerRow); sorted.forEach(r => frag.appendChild(r)); others.forEach(r => frag.appendChild(r)); tbody.innerHTML = ''; tbody.appendChild(frag); } setInterval(calculateScores, POLL_INTERVAL); })();