Last active
July 23, 2024 16:03
-
-
Save and7ey/20ea7208e55e8088822ca91bd8222dfa to your computer and use it in GitHub Desktop.
Tampermonkey Chrome script to display best upgrades in Hamster Kombat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name HamsterKombat Upgrades | |
// @namespace http://tampermonkey.net/ | |
// @version 0.4 | |
// @description Optimize upgrades based on profit/hour delta to price ratio | |
// @author You | |
// @match https://hamsterkombat.io/clicker/mine* | |
// @grant GM_xmlhttpRequest | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
function waitForMarketsElement(callback) { | |
const observer = new MutationObserver((mutationsList, observer) => { | |
for(let mutation of mutationsList) { | |
if (mutation.type === 'childList') { | |
const marketsElement = Array.from(mutation.addedNodes).find(node => node.nodeType === Node.ELEMENT_NODE && node.textContent.includes("Markets")); | |
if (marketsElement) { | |
observer.disconnect(); // Stop observing | |
callback(); // Execute the callback function | |
break; | |
} | |
} | |
} | |
}); | |
// Start observing the document with the configured parameters | |
observer.observe(document.body, { childList: true, subtree: true }); | |
} | |
function attachClickEventListeners() { | |
let tabItems = document.querySelectorAll('.tabs-item'); | |
tabItems.forEach(item => { | |
item.addEventListener('click', () => { | |
fetchUpgradesForBuy(); | |
}); | |
}); | |
} | |
waitForMarketsElement(() => { | |
fetchUpgradesForBuy(); | |
attachClickEventListeners(); // Also attach click event listeners after the initial load | |
}); | |
function fetchUpgradesForBuy() { | |
GM_xmlhttpRequest({ | |
method: "POST", | |
url: "https://api.hamsterkombat.io/clicker/upgrades-for-buy", | |
headers: { | |
"Authorization": "Bearer <YOUR_TOKEN>" // Replace with your actual token | |
}, | |
onload: function(response) { | |
let result = JSON.parse(response.responseText); | |
let upgrades = result.upgradesForBuy; | |
let availableUpgrades = upgrades.filter(upgrade => (upgrade.isAvailable === true && upgrade.isExpired === false)); | |
calculateProfitRatio(availableUpgrades); | |
} | |
}); | |
} | |
function calculateProfitRatio(upgrades) { | |
let sortedUpgrades = upgrades.sort((a, b) => (b.profitPerHourDelta / b.price) - (a.profitPerHourDelta / a.price)); | |
let top20 = sortedUpgrades.slice(0, 20); | |
top20.forEach((upgrade, index) => { | |
upgrade.rank = index + 1; // Ranking starts from 1 | |
}); | |
displayTopRatios(top20); | |
} | |
function reorderUpgradeItemsBasedOnRank(sortedUpgrades) { | |
// Find all upgrade items | |
let upgradeItemElements = Array.from(document.querySelectorAll('.upgrade-item, .upgrade-special, .upgrade-sport')); | |
// Create a map of upgrade names to their elements for easy lookup | |
let nameToElementMap = new Map(upgradeItemElements.map(item => { | |
let titleElement = item.querySelector('.upgrade-item-title, .upgrade-special-title, .upgrade-sport-title'); | |
return [titleElement.textContent.trim(), item]; | |
})); | |
let parentContainer = upgradeItemElements[0].parentNode; | |
// Reorder elements based on rank | |
for (let i = sortedUpgrades.length - 1; i >= 0; i--) { | |
let upgrade = sortedUpgrades[i]; | |
let targetElement = nameToElementMap.get(upgrade.name); | |
if(targetElement && parentContainer) { | |
// Insert the target element at the beginning of the parent container | |
parentContainer.insertBefore(targetElement, parentContainer.firstChild); | |
} | |
} | |
} | |
function displayTopRatios(topUpgrades) { | |
let titleElements = document.querySelectorAll('.upgrade-item-title, .upgrade-special-title, .upgrade-sport-title'); | |
// Remove previous output | |
var element = document.getElementById("upgradesOutput"); | |
if (element){ | |
element.remove(); | |
} | |
// Generate HTML string for output | |
let outputHTML = '<div id="upgradesOutput">'; | |
topUpgrades.forEach(upgrade => { | |
let ratio = Math.round(upgrade.profitPerHourDelta / upgrade.price * 100 * 100) / 100; | |
let nameLink = `<a href="#" class="upgrade-link" style="color: white" data-upgrade-name="${upgrade.name}">${upgrade.name}</a>`; | |
var priceK = Math.round(upgrade.price/1000); | |
outputHTML += `<p>${upgrade.rank}: ${upgrade.section} - ${nameLink}, ${ratio}, ${priceK}K</p>`; | |
}); | |
outputHTML += '</div>'; | |
// Insert generated HTML above 'user-balance-large' div | |
const userBalanceDiv = document.querySelector('.user-balance-large'); | |
userBalanceDiv.insertAdjacentHTML('beforebegin', outputHTML); | |
reorderUpgradeItemsBasedOnRank(topUpgrades); | |
topUpgrades.forEach(upgrade => { | |
// Iterate over all selected elements | |
titleElements.forEach(titleElement => { | |
// Check if the element's text content matches the upgrade name | |
if (titleElement.textContent.trim().toLowerCase() === upgrade.name.toLowerCase()) { | |
let ratio = Math.round(upgrade.profitPerHourDelta / upgrade.price * 100 * 100) / 100; | |
// Update the element's text content with the calculated ratio | |
titleElement.textContent += ` (${upgrade.rank}/20, ${ratio})`; | |
} | |
}); | |
}); | |
// Attach click event listeners to upgrade links | |
document.querySelectorAll('#upgradesOutput .upgrade-link').forEach(link => { | |
link.addEventListener('click', function(e) { | |
e.preventDefault(); | |
const targetName = this.getAttribute('data-upgrade-name'); | |
const targetElements = document.querySelectorAll(`.upgrade-item-title, .upgrade-special-title, .upgrade-sport-title`); // :contains(${targetName}) | |
const targetElement = [...targetElements].filter(e => e.innerText === targetName); | |
console.log(targetElement); | |
if(targetElement) { | |
console.log(targetElement); | |
targetElement[0].scrollIntoView({behavior: "smooth"}); | |
} | |
}); | |
}); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment