您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Calculates OC Success Chance
当前为
// ==UserScript== // @name OC Success Chance 2.0 // @namespace http://tampermonkey.net/ // @version 2.0.6 // @description Calculates OC Success Chance // @author Allenone [2033011] // @match https://www.torn.com/factions.php?step=your* // @icon https://www.google.com/s2/favicons?sz=64&domain=torn.com // @connect tornprobability.com // @grant GM.xmlHttpRequest // @grant GM_info // ==/UserScript== (function () { 'use strict'; const ocs = new Map(); let observer; // Minimal error logging function function logError(message, data = null) { console.error(`[OC Success Chance] ${message}`, data); } // Wait for an element to appear in the DOM function waitForElement(selector, timeout = 10000) { return new Promise((resolve, reject) => { const startTime = Date.now(); const checkInterval = setInterval(() => { const element = document.querySelector(selector); if (element) { clearInterval(checkInterval); resolve(element); } else if (Date.now() - startTime > timeout) { clearInterval(checkInterval); reject(new Error(`Timeout waiting for element: ${selector}`)); } }, 500); }); } // Extract success chances from each OC element individually. function extractSuccessChances() { const ocElements = document.querySelectorAll('.wrapper___U2Ap7'); if (!ocElements.length) { return; } for (let element of ocElements) { // Skip if already processed if (element.dataset.ocProcessed) { continue; } const reactFiberKey = Object.keys(element).find(key => key.startsWith("__reactFiber$")); if (!reactFiberKey) { logError('React fiber key not found for element:', element); continue; } let ocName = element.querySelector('.panelTitle___aoGuV')?.innerText || "Unknown"; let slots = element.querySelectorAll('.wrapper___Lpz_D'); const successChances = {}; for (let slot of slots) { const slotFiberKey = Object.keys(slot).find(key => key.startsWith("__reactFiber$")); if (!slotFiberKey) { logError('Slot fiber key not found for slot:', slot); continue; } try { let fiberNode = slot[slotFiberKey]; let key = fiberNode.return.key; // e.g., slot-P1, slot-P2, etc. let chanceText = slot.querySelector('.successChance___ddHsR')?.innerText; if (key && chanceText) { successChances[key] = parseFloat(chanceText.replace('%', '')); } } catch (error) { logError('Error accessing React properties:', error); } } if (Object.keys(successChances).length > 0) { // Process this element’s OC data and mark it processed. processOC(element, ocName, successChances); element.dataset.ocProcessed = true; } } } // Process OC data and calculate success chance for a specific element. async function processOC(element, ocName, successChances) { if (ocName === 'Blast From The Past') { try { const success = await BFTP( successChances['slot-P1'], successChances['slot-P2'], successChances['slot-P3'], successChances['slot-P4'], successChances['slot-P5'], successChances['slot-P6'] ); if (success.successChance) { ocs.set(ocName, success.successChance); injectSuccessChance(element, success.successChance); } } catch (error) { logError('Error processing Blast From The Past:', error); } } else if (ocName === 'Break The Bank') { try { const success = await BTB( successChances['slot-P1'], successChances['slot-P2'], successChances['slot-P3'], successChances['slot-P4'], successChances['slot-P5'], successChances['slot-P6'] ); if (success.successChance) { ocs.set(ocName, success.successChance); injectSuccessChance(element, success.successChance); } } catch (error) { logError('Error processing Break The Bank:', error); } } else { // If unsupported, do nothing. return; } } // Inject success chance into the specific OC element. function injectSuccessChance(element, successChance) { const title = element.querySelector('.panelTitle___aoGuV'); if (title && !element.querySelector('.success-chance')) { const successChanceElement = document.createElement('p'); successChanceElement.innerText = `Success Chance: ${(successChance * 100).toFixed(2)}%`; successChanceElement.classList.add('success-chance'); title.after(successChanceElement); } } // API call for Blast From The Past async function BFTP(p1, p2, p3, p4, p5, p6) { return new Promise((resolve, reject) => { GM.xmlHttpRequest({ method: 'POST', url: 'https://tornprobability.com:3000/BlastFromThePast', headers: { 'Content-Type': 'application/json' }, data: JSON.stringify({ Picklock1: p1, Hacker1: p2, Engineer1: p3, Bomber1: p4, Muscle1: p5, Picklock2: p6 }), onload: (response) => { try { const data = JSON.parse(response.responseText); resolve(data); } catch (err) { logError('Error parsing BFTP response:', err); reject(err); } }, onerror: (err) => { logError('BFTP request failed:', err); reject(err); } }); }); } // API call for Break The Bank async function BTB(p1, p2, p3, p4, p5, p6) { return new Promise((resolve, reject) => { GM.xmlHttpRequest({ method: 'POST', url: 'https://tornprobability.com:3000/BreakTheBank', headers: { 'Content-Type': 'application/json' }, data: JSON.stringify({ Robber1: p1, Muscle1: p2, Muscle2: p3, Thief1: p4, Muscle3: p5, Thief2: p6 }), onload: (response) => { try { const data = JSON.parse(response.responseText); resolve(data); } catch (err) { logError('Error parsing BTB response:', err); reject(err); } }, onerror: (err) => { logError('BTB request failed:', err); reject(err); } }); }); } // Observe DOM changes and extract success chances. function observeDOM() { const targetNode = document.querySelector('#faction-crimes-root'); if (!targetNode) { logError('Faction crimes root not found for observation'); return; } observer = new MutationObserver(() => { extractSuccessChances(); }); observer.observe(targetNode, { childList: true, subtree: true }); } // Initialize the script. async function init() { try { await waitForElement('#faction-crimes-root'); await waitForElement('.wrapper___U2Ap7'); observeDOM(); extractSuccessChances(); } catch (error) { logError('Error during initialization:', error); } } init(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址