Skip to content

Instantly share code, notes, and snippets.

@and7ey
Last active July 23, 2024 16:03
Show Gist options
  • Save and7ey/20ea7208e55e8088822ca91bd8222dfa to your computer and use it in GitHub Desktop.
Save and7ey/20ea7208e55e8088822ca91bd8222dfa to your computer and use it in GitHub Desktop.
Tampermonkey Chrome script to display best upgrades in Hamster Kombat
// ==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