// ==UserScript== // @name 雷速体育亚盘统计 // @namespace http://dol.freevar.com/ // @version 0.8 // @description 在雷速移动端网页展示指数Tab,并加入统计功能,点击统计会对当前赛事执行1次统计,可在多场赛事中执行统计累加。 // @author Dolphin // @match https://m.leisu.com/* // @grant GM_addStyle // @run-at document-start // @license MIT // @downloadURL none // ==/UserScript== (function () { 'use strict'; // 修改UserAgent Object.defineProperty(navigator, 'userAgent', { value: 'Mozilla/5.0 (Linux; Android 14; SM-G975F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Mobile Safari/537.36 MicroMessenger/6.7.3.1360(0x26070336) NetType/WIFI Language/zh_CN', configurable: true, writable: false, }); // 添加自定义样式 GM_addStyle(` #stats-table { border-collapse: collapse; margin: auto; } #stats-table tr:nth-child(even) {background-color: #fff;} #stats-table td, #stats-table th { text-align: center; border: 1px solid #ccf; } #button-container { text-align:center; } #button-container button { padding: 5px 15px; margin: 5px; border: none; border-radius: 8px; background-color: #4CAF50; color: white; cursor: pointer; transition: background-color 0.5s; } #button-container button:active { background-color: #45a049; } #button-container button:nth-child(2) { background-color: #2196F3; } #button-container button:nth-child(2):active { background-color: #1976D2; } #button-container button:nth-child(3) { background-color: #f44336; } #button-container button:nth-child(3):active { background-color: #d32f2f; } `); // 添加按钮 function addButtons() { const table = document.querySelector('.tab-team'); if (!table) return; const buttonContainer =table.parentNode.querySelector('#button-container'); if (buttonContainer) return; const container = document.createElement('div'); container.id = 'button-container'; container.innerHTML = ` `; table.insertAdjacentElement('afterend', container); document.getElementById('stats-btn')?.addEventListener('click', handleStats); document.getElementById('show-btn')?.addEventListener('click', showStats); document.getElementById('clear-btn')?.addEventListener('click', clearStats); } // 计算命中 function calculateHit(homeScore, awayScore, homeOdds, handicap, awayOdds) { const scoreDiff = homeScore - awayScore; const diff = scoreDiff - parseFloat(handicap); if (diff === 0) return true; if (parseFloat(homeOdds) === parseFloat(awayOdds)) return false; if (diff > 0) { return parseFloat(homeOdds) < parseFloat(awayOdds); } else { return parseFloat(awayOdds) < parseFloat(homeOdds); } } // 统计处理 function handleStats() { const scores = document.querySelectorAll('.score'); if (scores.length < 2) return; const homeScore = parseInt(scores[0].textContent); const awayScore = parseInt(scores[1].textContent); const rows = document.querySelectorAll('.tab-team tr'); let allMiss = true; const stats = JSON.parse(localStorage.getItem('asiaStats')) || {}; rows.forEach((row, index) => { if (index === 0) return; const company = row.querySelector('.w-77').textContent.trim(); // 处理初始数据 const initialData = row.querySelectorAll('td:nth-child(2) span'); const [homeOddsInitial, handicapInitial, awayOddsInitial] = Array.from(initialData).map(s => s.textContent); const isInitialHit = calculateHit(homeScore, awayScore, homeOddsInitial, handicapInitial, awayOddsInitial); if (isInitialHit) allMiss = false; // 处理赛前数据 const prematchData = row.querySelectorAll('td:nth-child(3) span'); const [homeOddsPre, handicapPre, awayOddsPre] = Array.from(prematchData).map(s => s.textContent); let isPrematchValid = true; let isPrematchHit = false; // 验证赛前数据是否有效 if ([homeOddsPre, handicapPre, awayOddsPre].every(v => !isNaN(v))) { isPrematchHit = calculateHit(homeScore, awayScore, homeOddsPre, handicapPre, awayOddsPre); if (isPrematchHit) allMiss = false; } else { isPrematchValid = false; } // 更新统计信息 if (!stats[company]) { stats[company] = { initial: { count: 0, hit: 0 }, prematch: { count: 0, hit: 0 } }; } // 更新初始统计 stats[company].initial.count++; if (isInitialHit) stats[company].initial.hit++; // 更新赛前统计(仅当数据有效时) if (isPrematchValid) { stats[company].prematch.count++; if (isPrematchHit) stats[company].prematch.hit++; } }); localStorage.setItem('asiaStats', JSON.stringify(stats)); if (allMiss) alert('本场比赛所有公司的初始和赛前亚盘均未命中!'); } // 显示统计 function showStats() { const existingTable = document.querySelector('#stats-table'); if (existingTable) existingTable.remove(); const stats = JSON.parse(localStorage.getItem('asiaStats')); if (!stats) return; const table = document.createElement('table'); table.id = 'stats-table'; table.innerHTML = ` 公司 初开 初中 命中率 临开 临中 命中率 `; Object.entries(stats).forEach(([company, data]) => { const row = document.createElement('tr'); row.innerHTML = ` ${company} ${data.initial.count} ${data.initial.hit} ${data.initial.count ? ((data.initial.hit / data.initial.count * 100).toFixed(1) + '%') : '0.0%'} ${data.prematch.count} ${data.prematch.hit} ${data.prematch.count ? ((data.prematch.hit / data.prematch.count * 100).toFixed(1) + '%') : '0.0%'} `; table.appendChild(row); }); const container = document.querySelector('.tab-team'); container.insertAdjacentElement('afterend', table); oddsBG(); } // 清除统计 function clearStats() { localStorage.removeItem('asiaStats'); const table = document.querySelector('#stats-table'); if (table) table.remove(); alert('已清除所有统计数据!'); } // 填充水位背景颜色 function oddsBG() { let table = document.querySelector('table.tab-team'); table.querySelectorAll('tr:not(:first-child)').forEach((tr) => { const initialTd = tr.querySelectorAll('td')[1]; if (!initialTd) return; const spans = initialTd.querySelectorAll('div.td-box-son > span'); if (spans.length < 3) return; const home = parseFloat(spans[0].textContent); const away = parseFloat(spans[2].textContent); if (home > away) { spans[0].style.backgroundColor = '#fcc'; spans[2].style.backgroundColor = '#cfc'; } else if (home < away) { spans[0].style.backgroundColor = '#cfc'; spans[2].style.backgroundColor = '#fcc'; } }); } // 初始化 setTimeout(() => { const zhishu = document.querySelector('a[href^="/live/odds"]'); if (zhishu) { // 创建事件对象 const mouseEventOptions = { bubbles: true, cancelable: true, }; zhishu.dispatchEvent(new MouseEvent('mousedown', mouseEventOptions)); zhishu.dispatchEvent(new MouseEvent('mouseup', mouseEventOptions)); } }, 2000); setInterval(() => { addButtons(); }, 2500); })();