您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Show details about DC and RC upgrades
当前为
// ==UserScript== // @name DeepCo Upgrades Helper // @namespace https://deepco.app/ // @version 2025-07-19 // @description Show details about DC and RC upgrades // @author Corns // @match https://deepco.app/upgrades // @icon https://www.google.com/s2/favicons?sz=64&domain=deepco.app // @license MIT // ==/UserScript== (function() { 'use strict'; const INTERVAL_MS = 1000; new MutationObserver((mutation, observer) => { const main = document.getElementById('main-panel'); if (main) { console.log("[Upgrade] Loaded"); observer.disconnect(); startLoop(); } }).observe(document.body, { childList: true, subtree: true }); function startLoop() { addButtonInfo(); setInterval(() => { addButtonInfo(); }, INTERVAL_MS); } function addButtonInfo() { const dcFrame = document.querySelector('#deepcoin-upgrades'); if (!dcFrame) { console.log('[Upgrade] Upgrades panel not found.'); return; } const rcFrame = document.querySelector('#recursive-upgrades'); if (!rcFrame) { console.log('[Upgrade] Upgrades panel not found.'); return; } // Get base stats const clockSpeedMatch = dcFrame.innerText.match(/Clock Speed:\s*([\d.]+)s/); const overclockMatch = dcFrame.innerText.match(/Overclocking Chance:\s*(\d+)%/); const forkMatch = dcFrame.innerText.match(/Thread Fork Chance:\s*(\d+)%/); const minMatch = dcFrame.innerText.match(/Min Processing Power:\s*(\d+)/); const maxMatch = dcFrame.innerText.match(/Max Processing Power:\s*(\d+)/); const minBonusMatch = rcFrame.innerText.match(/Min Processing Bonus:\s*(\d+)%/); const maxBonusMatch = rcFrame.innerText.match(/Max Processing Bonus:\s*(\d+)%/); const totalBonusMatch = rcFrame.innerText.match(/Total Processing Bonus:\s*(\d+)%/); const dcYieldMatch = rcFrame.innerText.match(/DC Yield:\s*(\d+)%/); if (!clockSpeedMatch || !minMatch || !maxMatch) { console.log('[Upgrade] Missing base stats.'); return; } let clockSpeed = parseFloat(clockSpeedMatch[1]); const overclockChance = parseInt(overclockMatch?.[1] ?? '0', 10) / 100; const forkChance = parseInt(forkMatch?.[1] ?? '0', 10) / 100; let minPower = parseFloat(minMatch[1]); let maxPower = parseFloat(maxMatch[1]); const minBonus = (parseInt(minBonusMatch?.[1] ?? '0', 10) + 100) / 100; const maxBonus = (parseInt(maxBonusMatch?.[1] ?? '0', 10) + 100) / 100; const totalBonus = (parseInt(totalBonusMatch?.[1] ?? '0', 10) + 100) / 100; const dcYield = parseInt(dcYieldMatch?.[1] ?? '100', 10) / 100; const avgPower = (minPower + maxPower) / 2; const overclockMultiplier = 1 + overclockChance; const forkMultiplier = 2 / (2 - forkChance); const baseDPS = avgPower / clockSpeed * overclockMultiplier * forkMultiplier; // update recursion protocol menu // power changes over time so we assume maxed DC upgrades for calculations const recursiveButtons = rcFrame.querySelectorAll('button'); recursiveButtons.forEach(button => { if (!button.textContent.includes('Install')) return; const costMatch = button.textContent.match(/\+1%.*\(([\d.]+)\s*RC\)/); if (!costMatch) return; const rcCost = parseFloat(costMatch[1]); // Make a copy of the current bonuses const rawMinPower = 30; // statically set to maxed raw stat const rawMaxPower = 100; const basePower = (rawMinPower * minBonus + rawMaxPower * maxBonus) / 2 * totalBonus * dcYield; let newMinBonus = minBonus; let newMaxBonus = maxBonus; let newTotalBonus = totalBonus; let newDCYield = dcYield; if (button.textContent.includes('Min Processing')) { newMinBonus += 0.01; } else if (button.textContent.includes('Max Processing')) { newMaxBonus += 0.01; } else if (button.textContent.includes('Total Processing')) { newTotalBonus += 0.01; } else if (button.textContent.includes('DC Yield')) { newDCYield += 0.01; } const newAvgPower = (rawMinPower * newMinBonus + rawMaxPower * newMaxBonus) / 2 * newTotalBonus * newDCYield; const powerGain = (newAvgPower - basePower) / basePower * 100; const ratio = powerGain / rcCost; // Build new label // Extract "Install +1% Min Processing" const baseLabel = button.textContent.replace(/\s*\([\d.]+\s*RC\).*$/, '').trim(); button.textContent = `${baseLabel} (${rcCost.toFixed(2)} RC) | +${powerGain.toFixed(2)}% Power (${ratio.toFixed(4)}%/RC)`; }); // Scan all upgrades const DCButtons = dcFrame.querySelectorAll('.upgrade-buttons-group'); DCButtons.forEach(group => { const buttons = group.querySelectorAll('button.upgrade-button'); buttons.forEach(button => { if (!button.textContent.includes('+1 ')) { return; } const match = button.textContent.match(/\+1.*\((\d+)\s*DC\)/); if (!match) return; const cost = parseInt(match[1], 10); const isDisabled = button.disabled; let newClockSpeed = clockSpeed; let newMin = minPower; let newMax = maxPower; let newOverclockChance = overclockChance; let newForkChance = forkChance; if (button.parentElement.action.includes('/upgrades/speed')) { newClockSpeed = Math.max(0.5, clockSpeed - 0.1); } else if (button.parentElement.action.includes('/upgrades/min_damage')) { const increase = 1 * minBonus * totalBonus; newMin += increase; } else if (button.parentElement.action.includes('/upgrades/damage')) { const increase = 1 * maxBonus * totalBonus; newMax += increase; } else if (button.parentElement.action.includes('/upgrades/crit')) { newOverclockChance += 0.01; // Assume +1% chance per upgrade } else if (button.parentElement.action.includes('/upgrades/chain')) { newForkChance += 0.01; // Assume +1% chance per upgrade } const newAvgPower = (newMin + newMax) / 2; const newOverclockMultiplier = 1 + newOverclockChance; const newForkMultiplier = 2 / (2 - newForkChance); const newDPS = newAvgPower / newClockSpeed * newOverclockMultiplier * newForkMultiplier; const dpsGain = newDPS - baseDPS; const ratio = dpsGain / cost; // add label to reflect new info let infoText = button.parentElement.parentElement.parentElement.querySelector(`span[data-tag="${button.parentElement.action}"]`); if (!infoText) { infoText = document.createElement('span'); infoText.dataset.tag = button.parentElement.action; button.parentElement.parentElement.parentElement.insertBefore(infoText, button.parentElement.parentElement); } infoText.textContent = `+${dpsGain.toFixed(2)} DPS (${ratio.toFixed(2)} DPS/DC)`; }); }); } })();