Greasy Fork is available in English.
Tracker for Chips farming and hourly rate estimation
// ==UserScript==
// @name Idle Hacking Chips Tracker
// @namespace http://tampermonkey.net/
// @version 1.23
// @description Tracker for Chips farming and hourly rate estimation
// @license MIT
// @author Tecycdan (Leviathan)
// @match *://www.idlehacking.com/*
// @match *://idlehacking.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
const CHIPS_SELECTOR = '#p-chips';
const theme = {
baseBeige: '#fceebd',
darkWarmBg: 'rgba(20, 18, 15, 0.90)',
dimBeige: '#c2b388',
neonGlowBox: '0 0 10px rgba(252, 238, 189, 0.4), 0 0 20px rgba(252, 238, 189, 0.2)',
neonGlowText: '0 0 5px rgba(252, 238, 189, 0.6), 0 0 10px rgba(252, 238, 189, 0.4)',
btnBg: '#2a2620'
};
let lastChips = null;
let totalGained = 0;
let startTime = null;
const container = document.createElement('div');
container.style.position = 'fixed';
container.style.bottom = '10px';
container.style.right = '10px';
container.style.padding = '12px';
container.style.backgroundColor = theme.darkWarmBg;
container.style.color = theme.baseBeige;
container.style.fontFamily = 'monospace';
container.style.fontSize = '13px';
container.style.zIndex = '9999';
container.style.borderRadius = '4px';
container.style.border = `1px solid ${theme.baseBeige}`;
container.style.boxShadow = theme.neonGlowBox;
const statsDisplay = document.createElement('div');
statsDisplay.innerHTML = 'Initializing intercept...';
statsDisplay.style.textShadow = theme.neonGlowText;
const resetBtn = document.createElement('button');
resetBtn.innerText = 'RESET';
resetBtn.style.marginTop = '10px';
resetBtn.style.width = '100%';
resetBtn.style.cursor = 'pointer';
resetBtn.style.background = theme.btnBg;
resetBtn.style.color = theme.baseBeige;
resetBtn.style.border = `1px solid ${theme.baseBeige}`;
resetBtn.style.borderRadius = '2px';
resetBtn.style.fontSize = '10px';
resetBtn.style.padding = '4px 0';
resetBtn.style.fontFamily = 'monospace';
resetBtn.style.textShadow = theme.neonGlowText;
resetBtn.style.boxShadow = '0 0 5px rgba(252, 238, 189, 0.2)';
resetBtn.style.transition = 'all 0.2s ease-in-out';
resetBtn.onmouseover = () => {
resetBtn.style.background = theme.baseBeige;
resetBtn.style.color = theme.darkWarmBg;
resetBtn.style.textShadow = 'none';
resetBtn.style.boxShadow = theme.neonGlowBox;
};
resetBtn.onmouseout = () => {
resetBtn.style.background = theme.btnBg;
resetBtn.style.color = theme.baseBeige;
resetBtn.style.textShadow = theme.neonGlowText;
resetBtn.style.boxShadow = '0 0 5px rgba(252, 238, 189, 0.2)';
};
resetBtn.onclick = () => {
lastChips = null;
totalGained = 0;
startTime = null;
statsDisplay.innerHTML = 'Tracker Reset...';
const el = document.querySelector(CHIPS_SELECTOR);
if (el) updateStats(el.innerText);
};
container.appendChild(statsDisplay);
container.appendChild(resetBtn);
document.body.appendChild(container);
function parseChips(text) {
if (!text) return 0;
let str = text.replace(/[^\d.,\-' ]/g, '').trim();
const lastComma = str.lastIndexOf(',');
const lastDot = str.lastIndexOf('.');
const hasComma = lastComma > -1;
const hasDot = lastDot > -1;
let decimalChar = null;
if (hasComma && hasDot) {
decimalChar = lastComma > lastDot ? ',' : '.';
} else if (hasComma) {
if (str.length - lastComma !== 4) decimalChar = ',';
} else if (hasDot) {
if (str.length - lastDot !== 4) decimalChar = '.';
}
str = str.replace(/[ '']/g, '');
if (decimalChar === ',') {
str = str.replace(/\./g, '');
str = str.replace(',', '.');
} else if (decimalChar === '.') {
str = str.replace(/,/g, '');
} else {
str = str.replace(/[.,]/g, '');
}
return parseFloat(str) || 0;
}
function updateStats(targetElement) {
const rawText = targetElement.getAttribute('data-tooltip') || targetElement.innerText;
const currentChips = parseChips(rawText);
if (lastChips === null) {
lastChips = currentChips;
startTime = Date.now();
return;
}
const diff = currentChips - lastChips;
if (diff > 0) {
totalGained += diff;
}
lastChips = currentChips;
const elapsedMs = Date.now() - startTime;
const elapsedHours = elapsedMs / (1000 * 60 * 60);
let chipsPerHour = 0;
if (elapsedHours > 0.0002) {
chipsPerHour = (totalGained / elapsedHours).toFixed(0);
}
if (typeof statsDisplay !== 'undefined') {
statsDisplay.innerHTML = `
<b style="color:${theme.dimBeige}; font-size: 10px; text-shadow: none;">Chips Tracker</b><br>
Current: ${currentChips.toLocaleString()}<br>
Gained: <span style="color:#ffffff; text-shadow: 0 0 8px #ffffff, 0 0 15px ${theme.baseBeige};">+${totalGained.toLocaleString()}</span><br>
Rate: ${parseInt(chipsPerHour).toLocaleString()} /hr
`;
}
}
const initObserver = setInterval(() => {
const targetElement = document.querySelector(CHIPS_SELECTOR);
if (targetElement) {
clearInterval(initObserver);
updateStats(targetElement);
const observer = new MutationObserver(() => {
updateStats(targetElement);
});
observer.observe(targetElement, {
characterData: true,
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['data-tooltip']
});
}
}, 1000);
})();