您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds an healthbar, energybar, links and other QOL to BiteFight
当前为
// ==UserScript== // @name Better BiteFight // @namespace https://lobby.bitefight.gameforge.com/ // @version 0.7.0 // @description Adds an healthbar, energybar, links and other QOL to BiteFight // @author Spychopat // @match https://*.bitefight.gameforge.com/* // @icon https://lobby.bitefight.gameforge.com/favicon.ico // @grant GM_getValue // @grant GM_setValue // @grant GM_addStyle // ==/UserScript== (function () { 'use strict'; // uncomment to reset character data if needed //GM_setValue('character', {}) // Script storage keys const KEY_CHARACTER = 'character'; const pageLoadTime = Date.now(); // Define character object const CHARACTER = GM_getValue(KEY_CHARACTER, { energy: 0, maxEnergy: 0, health: 0, maxHealth: 0, regenHealth: 0, potionCooldownEnd: 0, churchCooldownEnd: 0, autoRedirectGrotte: true, autoGrotto: [false, false, false], goldEarned: { 0: [], 1: [], 2: [] }, dmgTaken: { 0: [], 1: [], 2: [] } }); //console.log(parseInt(formatNumber(document.getElementsByClassName("gold")[1].firstChild.textContent.split("\n")[1]))); redirectAfterGrotteFight(); // run it first, because it has chances to redirect, so we don't work uselessly // early, to avoid the page jump as much as possible insertCSS(); addAdditionnalLink(); extractCharacterStats(); updatePotionTimer(); // Run the church cooldown update function if on the church page updateRegenHealth(); insertProgressBars(); // Insert progress bars after updating the character startHealthRegeneration(); // Start health regeneration on page load if (window.location.pathname.contains('/profile')){ moveGameEventDiv(); // move down the game event div } else if (window.location.pathname.contains('/city/church')){ updateChurchCooldownTimer(); } else if (window.location.pathname.contains('/city/grotte')){ addAutoGrottoButton(); autoFightGrotto(); } else if (window.location.pathname.contains('/city/shop')){ defaultNonPremiumShop(); } updateCharacter(); //console.log(CHARACTER); // make the overview link open the attributes by default document.querySelectorAll('#menuHead li a')[1].href="/profile/index#tabs-2"; function insertCSS() { GM_addStyle(` #upgrademsg { display: none; } #premium > img { display: none; } #mmonetbar { display: none !important; visibility: hidden; } `); } function extractCharacterStats(){ // Get Stats var allStatsElement = document.getElementsByClassName("gold")[0]; var statsValues = allStatsElement.textContent.split("\n"); statsValues = statsValues.map(value => value.trim()); statsValues.shift(); // Extract energy, fragments, gold, health, and hellStones var energy = statsValues[3].trim(); var currentEnergy = energy.split("/")[0]; var maxEnergy = energy.split("/")[1]; if (currentEnergy && maxEnergy) { CHARACTER.energy = parseInt(currentEnergy); // Use parseFloat to preserve decimals CHARACTER.maxEnergy = parseInt(maxEnergy); // Use parseFloat to preserve decimals } var health = statsValues[4].trim(); var currentHealth = formatNumber(health.split("/")[0]); var maxHealth = formatNumber(health.split("/")[1]); if (currentHealth && maxHealth) { CHARACTER.health = parseInt(currentHealth); CHARACTER.maxHealth = parseInt(maxHealth); } } // Format texts to return as numbers (no thousand separators) function formatNumber(value) { while (value.indexOf(".") > 0) value = value.replace(".", ""); return value; } function updateRegenHealth() { if (!window.location.pathname.endsWith('/profile/index')) return; var elements = document.getElementsByClassName("triggerTooltip"); // Loop through the elements for (let i = 0; i < elements.length; i++) { // Check if the inner text or inner HTML contains "/ h" if (elements[i].innerText.includes("/ h") || elements[i].innerHTML.includes("/ h")) { CHARACTER.regenHealth = parseInt(elements[i].textContent); //console.log("Regen per hour found : ", parseInt(elements[i].textContent)); break; // Exit the loop once the element is found } } } // Update character in local storage function updateCharacter() { GM_setValue(KEY_CHARACTER, CHARACTER); } function updatePotionTimer() { if (!window.location.pathname.endsWith('/profile/index')) return; // Ensure this only runs on the right page // Get all elements with the class "inactive" const inactiveElements = document.getElementsByClassName('inactive'); let targetElement = null; // Loop through each "inactive" element to find the target for (const inactiveElement of inactiveElements) { // Find elements with the class "countdown_row countdown_amount" within the current "inactive" element const matchingElements = inactiveElement.getElementsByClassName('countdown_row countdown_amount'); if (matchingElements.length > 0) { targetElement = matchingElements[0]; // Take the first matching element break; // Stop once we find the target } } if (targetElement) { // Get the current time and add the potion cooldown to get the end time const currentTime = new Date().getTime() / 1000; // Current time in seconds const cooldownTime = timeToSeconds(targetElement.textContent); // Convert cooldown time to seconds const endTime = currentTime + cooldownTime; // Calculate the end time // Save the end time to the character object CHARACTER.potionCooldownEnd = endTime; updateCharacter(); // Save updated character data } } function timeToSeconds(timeStr) { const [hours, minutes, seconds] = timeStr.split(':').map(Number); return (hours * 3600) + (minutes * 60) + seconds; } function insertProgressBars() { // Check if the layout container is already present if (document.getElementById('progressBarsTimersContainer')) { return; } // Create the main container for the layout let mainContainer = document.createElement('div'); mainContainer.id = 'progressBarsTimersContainer'; mainContainer.style.display = 'flex'; mainContainer.style.justifyContent = 'space-between'; mainContainer.style.alignItems = 'center'; mainContainer.style.marginTop = '3px'; // Left section for progress bars let progressBarsContainer = document.createElement('div'); progressBarsContainer.style.display = 'flex'; progressBarsContainer.style.flexDirection = 'column'; progressBarsContainer.style.alignItems = 'flex-start'; progressBarsContainer.style.paddingLeft = '50px'; // Create Health Progress Bar let healthBarContainer = document.createElement('div'); healthBarContainer.style.width = '250px'; healthBarContainer.style.position = 'relative'; healthBarContainer.id = 'healthProgressBar'; healthBarContainer.style.backgroundColor = 'black'; // Black background healthBarContainer.style.border = '3px solid rgb(117, 117, 117)'; // White outline let healthBar = document.createElement('div'); healthBar.style.height = '20px'; healthBar.style.width = `${(CHARACTER.health / CHARACTER.maxHealth) * 100}%`; healthBar.style.backgroundColor = '#b80000'; let healthText = document.createElement('div'); healthText.textContent = `${CHARACTER.health > 999 ? CHARACTER.health.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.') : CHARACTER.health}`; healthText.style.position = 'absolute'; healthText.style.top = '50%'; healthText.style.left = '50%'; healthText.style.transform = 'translate(-50%, -50%)'; healthText.style.color = 'white'; healthText.style.fontSize = '12px'; healthText.style.fontFamily = 'monospace'; healthBarContainer.appendChild(healthBar); healthBarContainer.appendChild(healthText); // Create Energy Progress Bar let energyBarContainer = document.createElement('div'); energyBarContainer.style.width = '250px'; energyBarContainer.style.marginBottom = '5px'; energyBarContainer.style.position = 'relative'; energyBarContainer.id = 'energyProgressBar'; energyBarContainer.style.backgroundColor = 'black'; // Black background energyBarContainer.style.borderLeft = '3px solid rgb(117, 117, 117)'; // White outline energyBarContainer.style.borderRight = '3px solid rgb(117, 117, 117)'; // White outline energyBarContainer.style.borderBottom = '3px solid rgb(117, 117, 117)'; // White outline let energyBar = document.createElement('div'); energyBar.style.height = '20px'; energyBar.style.width = `${(CHARACTER.energy / CHARACTER.maxEnergy) * 100}%`; energyBar.style.backgroundColor = '#0000a4'; let energyText = document.createElement('div'); energyText.textContent = `${CHARACTER.energy}`; energyText.style.position = 'absolute'; energyText.style.top = '50%'; energyText.style.left = '50%'; energyText.style.transform = 'translate(-50%, -50%)'; energyText.style.color = 'white'; energyText.style.fontSize = '12px'; energyText.style.fontFamily = 'monospace'; energyBarContainer.appendChild(energyBar); energyBarContainer.appendChild(energyText); progressBarsContainer.appendChild(healthBarContainer); progressBarsContainer.appendChild(energyBarContainer); // Right section for timers let timersContainer = document.createElement('div'); timersContainer.style.textAlign = 'center'; timersContainer.style.paddingRight = '50px'; timersContainer.style.width = '256px'; // Ensure timers are stacked vertically timersContainer.style.display = 'flex'; timersContainer.style.flexDirection = 'column'; // Stack vertically timersContainer.style.alignItems = 'center'; // Center align each timer // Potion Timer Link let potionTimer = document.createElement('a'); potionTimer.id = 'potionCooldownTimer'; potionTimer.style.color = 'white'; potionTimer.style.fontSize = '14px'; potionTimer.style.fontFamily = 'monospace'; potionTimer.style.margin = '0px'; //potionTimer.href = '/profile/index#potions'; potionTimer.href = '/profile/useItem/2/20'; potionTimer.textContent = 'Potion Cooldown: Calculating...'; // Church Timer Link let churchTimer = document.createElement('a'); churchTimer.id = 'churchCooldownTimer'; churchTimer.style.color = 'white'; churchTimer.style.fontSize = '14px'; churchTimer.style.fontFamily = 'monospace'; churchTimer.style.margin = '0px'; churchTimer.href = '/city/church'; churchTimer.textContent = 'Church Cooldown: Calculating...'; timersContainer.appendChild(potionTimer); timersContainer.appendChild(churchTimer); // Add both sections to the main container mainContainer.appendChild(progressBarsContainer); mainContainer.appendChild(timersContainer); // Append the main container to the desired parent element document.getElementsByClassName("gold")[0].appendChild(mainContainer); // Start updating the timers updatePotionCooldownDisplay(); setInterval(updatePotionCooldownDisplay, 1000); updateChurchCooldownDisplay(); setInterval(updateChurchCooldownDisplay, 1000); } function calculateCurrentHealth(){ const regenPerSecond = CHARACTER.regenHealth / 3600; // Convert regenHealth from per hour to per second // Calculate the total health regenerated since the page loaded const elapsedSeconds = (Date.now() - pageLoadTime) / 1000; // Time elapsed in seconds const regeneratedHealth = regenPerSecond * elapsedSeconds; // Calculate the updated health, without modifying the original CHARACTER.health const updatedHealth = Math.min( CHARACTER.health + regeneratedHealth, CHARACTER.maxHealth ); return updatedHealth; } // Start real-time health regeneration function startHealthRegeneration() { const regenInterval = 200; // Update every 200 ms setInterval(() => { // Update the progress bar with the calculated health updateProgressBars(calculateCurrentHealth()); }, regenInterval); } // Update the existing progress bars function updateProgressBars(calculatedHealth) { // Update Energy Progress Bar //const energyBar = document.getElementById('energyProgressBar').children[0]; //energyBar.style.width = `${(CHARACTER.energy / CHARACTER.maxEnergy) * 100}%`; //const energyText = document.getElementById('energyProgressBar').children[1]; //energyText.textContent = `${CHARACTER.energy}`; // Update Health Progress Bar const healthBar = document.getElementById('healthProgressBar').children[0]; healthBar.style.width = `${(calculatedHealth / CHARACTER.maxHealth) * 100}%`; const healthText = document.getElementById('healthProgressBar').children[1]; // Format the health value with thousands separators let healthWithoutDecimals = Math.floor(calculatedHealth); healthText.textContent = `${healthWithoutDecimals > 999 ? healthWithoutDecimals.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.'): healthWithoutDecimals}`; } // Function to update the timer display function updatePotionCooldownDisplay() { const timerElement = document.getElementById('potionCooldownTimer'); const currentTime = new Date().getTime() / 1000; // Current time in seconds if (CHARACTER.potionCooldownEnd > currentTime) { const remainingTime = CHARACTER.potionCooldownEnd - currentTime; // Remaining time in seconds const hours = Math.floor(remainingTime / 3600); const minutes = Math.floor((remainingTime % 3600) / 60); const seconds = Math.round(remainingTime % 60); timerElement.textContent = `Potion Cooldown: ${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; } else { timerElement.textContent = 'Potion Ready!'; } } // Add the church cooldown timer display function updateChurchCooldownTimer() { const churchCountdownElement = document.getElementsByClassName('hasCountdown')[0]; if (churchCountdownElement) { const cooldownTime = churchCountdownElement.textContent.trim(); const currentTime = new Date().getTime() / 1000; // Current time in seconds const cooldownSeconds = timeToSeconds(cooldownTime); // Convert cooldown time to seconds const endTime = currentTime + cooldownSeconds; // Calculate the end time // Save the end time to the character object CHARACTER.churchCooldownEnd = endTime; updateCharacter(); // Save updated character data } } // Function to update the church cooldown display function updateChurchCooldownDisplay() { const timerElement = document.getElementById('churchCooldownTimer'); const currentTime = new Date().getTime() / 1000; // Current time in seconds if (CHARACTER.churchCooldownEnd > currentTime) { const remainingTime = CHARACTER.churchCooldownEnd - currentTime; // Remaining time in seconds const hours = Math.floor(remainingTime / 3600); const minutes = Math.floor((remainingTime % 3600) / 60); const seconds = Math.round(remainingTime % 60); timerElement.textContent = `Church Cooldown: ${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; } else { timerElement.textContent = 'Church Ready!'; } } function addAdditionnalLink() { // Find the <li> containing the Chasse link const chasseListItem = document.querySelector('li.free-space > a[href$="/robbery/index"]'); if (chasseListItem) { // Navigate to the parent <li> element const chasseLi = chasseListItem.closest('li'); // Remove the class "free-space" chasseLi.removeAttribute('class'); if (window.location.pathname.contains('robbery')){ chasseLi.className = "active"; } // Create a new <li> for the Grotte link const grotteLi = document.createElement('li'); if (window.location.pathname.contains('/grotte')){ if (document.getElementsByClassName("active")[0])document.getElementsByClassName("active")[0].removeAttribute('class'); grotteLi.className = "active"; } grotteLi.innerHTML = '<a href="/city/grotte" target="_top">Grotto</a>'; const graveLi = document.createElement('li'); if (window.location.pathname.contains('/city/graveyard') || window.location.pathname.contains('/user/working')){ if (document.getElementsByClassName("active")[0])document.getElementsByClassName("active")[0].removeAttribute('class'); graveLi.className = "active"; } graveLi.innerHTML = '<a href="/city/graveyard" target="_top">Graveyard</a>'; const shopLi = document.createElement('li'); if (window.location.pathname.contains('/city/shop/')){ if (document.getElementsByClassName("active")[0])document.getElementsByClassName("active")[0].removeAttribute('class'); shopLi.className = "active"; } shopLi.innerHTML = '<a href="/city/shop/potions/&page=1&premiumfilter=nonpremium" target="_top">Shop</a>'; const questsLi = document.createElement('li'); questsLi.className = "free-space"; if (window.location.pathname.contains('/city/missions')){ if (document.getElementsByClassName("active")[0])document.getElementsByClassName("active")[0].removeAttribute('class'); questsLi.className = "active free-space"; } questsLi.innerHTML = '<a href="/city/missions" target="_top">Quests</a>'; // Insert the new links (in reverse) chasseLi.insertAdjacentElement('afterend', questsLi); chasseLi.insertAdjacentElement('afterend', shopLi); chasseLi.insertAdjacentElement('afterend', graveLi); chasseLi.insertAdjacentElement('afterend', grotteLi); } } function moveGameEventDiv() { const gameEventDiv = document.getElementById('gameEvent'); const itemsDiv = document.getElementById('items'); if (gameEventDiv && itemsDiv) { itemsDiv.insertAdjacentElement('afterend', gameEventDiv); } //scroll up after upgrading a skill if (window.location.hash=='#tabs-2') window.scrollTo(0, 0); //if (window.location.hash=='#potions') document.getElementsByClassName("ui-accordion-header")[2].scrollIntoView({ behavior: 'smooth' }); } function defaultNonPremiumShop() { const links = document.querySelectorAll('a'); // Select all anchor elements links.forEach(link => { // Check if the link href contains '/city/shop/' if (link.href.includes('/city/shop')) { // If the URL doesn't already have a query string, add it if (!link.href.includes('&premiumfilter=nonpremium')) { link.href += '&premiumfilter=nonpremium'; } } }); /* var premiumfilter = document.querySelector('select[name="premiumfilter"]'); // Replace with the correct selector if necessary if (premiumfilter) { premiumfilter.value = 'nonpremium'; // Set default value to 'nonpremium' }*/ } function redirectAfterGrotteFight() { if ((CHARACTER.autoRedirectGrotte || CHARACTER.autoGrotto[0] || CHARACTER.autoGrotto[1] || CHARACTER.autoGrotto[2]) && window.location.href.includes('report/fightreport/') && window.location.href.includes('/grotte')) { // Redirect to '/city/grotte' for (let index = 0; index < 3; index++) { if(CHARACTER.autoGrotto[index])saveGrottoGold(index); } window.location.href = '/city/grotte'; } // all below is to add the checkbox if (!window.location.pathname.contains('/city/grotte')) return; const buildingDescElement = document.getElementsByClassName('buildingDesc')[0]; if (!buildingDescElement) return; // Create the switch container const switchContainer = document.createElement('div'); switchContainer.classList.add('auto-redirect-switch'); switchContainer.style.marginTop = '10px'; // Create the label for the switch const label = document.createElement('label'); label.textContent = 'Auto redirect after fight'; label.style.marginRight = '10px'; // Create the switch itself const switchInput = document.createElement('input'); switchInput.type = 'checkbox'; switchInput.style.transform = 'scale(1.2)'; // Optional: make it slightly bigger switchInput.style.display = 'block'; switchInput.checked = CHARACTER.autoRedirectGrotte; // Get the saved state // Add change event to store the state of the switch switchInput.addEventListener('change', () => { CHARACTER.autoRedirectGrotte = switchInput.checked; updateCharacter(); // Implement logic for auto redirection here if needed }); // Append the label and input (switch) to the container switchContainer.appendChild(label); switchContainer.appendChild(switchInput); // Append the switch to the buildingDesc element buildingDescElement.appendChild(switchContainer); } function addAutoGrottoButton() { // make sure the variable is defined if (!Array.isArray(CHARACTER.autoGrotto)) { CHARACTER.autoGrotto = [false, false, false]; } if (!CHARACTER.goldEarned) { CHARACTER.goldEarned = {}; } if (!CHARACTER.dmgTaken) { CHARACTER.dmgTaken = {}; } for (let index = 0; index < 3; index++) { //const target = $(`table.noBackground form.clearfix div input`)[index]; const target = document.querySelectorAll('table.noBackground form.clearfix div input')[index]; if (!target) return; // Create the button const button = document.createElement("button"); if(CHARACTER.autoGrotto[index]){ button.textContent = "Auto : ON"; button.style.backgroundPosition = '0 -183px'; } else { button.textContent = "Auto : OFF"; //button.style.backgroundPosition = '0 -44px'; } button.className = "btn-small left btn-autoGrotto"; button.style.margin = "10px"; button.style.padding = "0 0 5px"; // Add a click event listener button.addEventListener("click", function (event) { event.preventDefault(); // Prevent default button behavior if(!CHARACTER.autoGrotto[index] && isReadyForGrotto()){ CHARACTER.autoGrotto[index] = true; updateCharacter(); button.textContent = "Auto : ON"; button.style.backgroundPosition = '0 -183px'; document.querySelectorAll('table.noBackground form.clearfix div input')[index].click(); } else { CHARACTER.autoGrotto[index] = false; updateCharacter(); button.textContent = "Auto : OFF"; button.style.backgroundPosition = '0 -44px'; } //console.log(`CHARACTER.autoGrotto[${index}] is now `, CHARACTER.autoGrotto); }); // Insert the button after the target element target.parentNode.insertBefore(button, target.nextSibling); displayGoldAverage(index); } } function autoFightGrotto() { if(!CHARACTER.autoGrotto[0] && !CHARACTER.autoGrotto[1] && !CHARACTER.autoGrotto[2]) return; const randomDelay = Math.random() * 1000 + 200; console.log(`Action will be executed after ${randomDelay.toFixed(0)}ms`); // Set the timeout setTimeout(() => { if(!isReadyForGrotto()){ CHARACTER.autoGrotto[0] = false; CHARACTER.autoGrotto[1] = false; CHARACTER.autoGrotto[2] = false; updateCharacter(); const buttons = document.querySelectorAll('.btn-autoGrotto'); buttons.forEach(button => { button.textContent = 'Auto : OFF'; button.style.backgroundPosition = '0 -44px'; }); } else { if(CHARACTER.autoGrotto[0])document.querySelectorAll('table.noBackground form.clearfix div input')[0].click(); if(CHARACTER.autoGrotto[1])document.querySelectorAll('table.noBackground form.clearfix div input')[1].click(); if(CHARACTER.autoGrotto[2])document.querySelectorAll('table.noBackground form.clearfix div input')[2].click(); } }, randomDelay); } function isReadyForGrotto() { return (calculateCurrentHealth() > 9000 && CHARACTER.energy > 0); } function saveGrottoGold(grottoDifficulty){ const goldEarned = parseInt(formatNumber(document.getElementsByClassName("gold")[1].firstChild.textContent.split("\n")[1])); // Ensure the goldEarned array for the selected difficulty exists if (!CHARACTER.goldEarned[grottoDifficulty]) { CHARACTER.goldEarned[grottoDifficulty] = []; } // Push the new gold earned value into the array CHARACTER.goldEarned[grottoDifficulty].push(goldEarned); // Keep only the last 20 entries for each difficulty if (CHARACTER.goldEarned[grottoDifficulty].length > 20) { CHARACTER.goldEarned[grottoDifficulty].shift(); // Remove the oldest entry } // Ensure the dmgTaken array for the selected difficulty exists if (!CHARACTER.dmgTaken[grottoDifficulty]) { CHARACTER.dmgTaken[grottoDifficulty] = []; } // Push the new dmg taken value into the array CHARACTER.dmgTaken[grottoDifficulty].push(getGrottoHealthDamage(goldEarned)); // Keep only the last 20 entries for each difficulty if (CHARACTER.dmgTaken[grottoDifficulty].length > 20) { CHARACTER.dmgTaken[grottoDifficulty].shift(); // Remove the oldest entry } // Update the character data with the new gold earnings updateCharacter(); } // This function calculates the average gold for a given difficulty function calculateGoldAverage(grottoDifficulty) { if (!CHARACTER.goldEarned[grottoDifficulty] || CHARACTER.goldEarned[grottoDifficulty].length < 1) return 0; let totalGold = 0; // Loop through the gold history for the given difficulty for (let i = 0; i < CHARACTER.goldEarned[grottoDifficulty].length; i++) { totalGold += CHARACTER.goldEarned[grottoDifficulty][i]; } return totalGold / CHARACTER.goldEarned[grottoDifficulty].length; } function calculateDamageAverage(grottoDifficulty) { if (!CHARACTER.dmgTaken[grottoDifficulty] || CHARACTER.dmgTaken[grottoDifficulty].length < 1) return 0; let totalDmg = 0; // Loop through the gold history for the given difficulty for (let i = 0; i < CHARACTER.dmgTaken[grottoDifficulty].length; i++) { totalDmg += CHARACTER.dmgTaken[grottoDifficulty][i]; } return totalDmg / CHARACTER.dmgTaken[grottoDifficulty].length; } // Function to display the average gold under each button function displayGoldAverage(grottoDifficulty) { //console.log("Average gold for difficult "+grottoDifficulty+" : "+calculateGoldAverage(grottoDifficulty)); const button = document.querySelectorAll('.btn-autoGrotto')[grottoDifficulty]; if (!button) return; let avgGoldText = `${calculateGoldAverage(grottoDifficulty).toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, '.')} `; let avgDmg = `${calculateDamageAverage(grottoDifficulty).toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, '.')} `; // Check if the display already exists, and update or create a new one let avgElement = button.querySelector('.gold-average'); avgElement = document.createElement('div'); avgElement.classList.add('gold-average'); avgElement.style.fontSize = '15px'; avgElement.style.marginLeft = '10px'; avgElement.style.textAlign = 'center'; // Center the text avgElement.style.display = 'block'; // Make sure it takes up the full width and goes below the button avgElement.style.width = '160px'; avgElement.style.textShadow = "0 0 4px #FF0000"; avgElement.style.fontFamily = 'monospace'; avgElement.style.fontWeight = 'bold'; avgElement.style.color = 'white'; avgElement.style.lineHeight = '25px'; button.parentNode.insertBefore(avgElement, button.nextSibling); avgElement.textContent = avgGoldText; // Create an image element and append it after the text let imgGold = document.createElement('img'); imgGold.src = '/img/symbols/res2.gif'; avgElement.appendChild(imgGold); imgGold.align = 'absmiddle'; var lineBreak = document.createElement('br'); avgElement.appendChild(lineBreak); var avgDmgText = document.createTextNode(avgDmg); avgElement.appendChild(avgDmgText); let imgHealth = document.createElement('img'); imgHealth.src = '/img/symbols/herz.png'; avgElement.appendChild(imgHealth); imgHealth.align = 'absmiddle'; } // if gold earned = 0, then it's lost,and the dmg taken is on left and not on right function getGrottoHealthDamage(goldEarned){ var win = 1; if(goldEarned == 0){ win = 0; } const wholeText = document.querySelectorAll('#reportResult div.wrap-left div.wrap-content p')[0].textContent; const extractedText = wholeText.match(/\(([^)]+)\)/)[1]; // Regular expression to match content between parentheses const numbers = extractedText.split(":"); return(parseInt(numbers[win])); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址