您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Helper for TheresMoreGame
当前为
// ==UserScript== // @name TheresMoreHelp // @namespace TheresMoreGame.com // @match https://www.theresmoregame.com/play/ // @grant none // @version 1.19 // @description Helper for TheresMoreGame // @license MIT // @run-at document-idle // ==/UserScript== ;(async () => { let cheatsOff = true let scriptPaused = true let manualGold = false let haveManualResourceButtons = true let playingMarket = false const buildingsList = [ { name: 'City of Lights', alwaysBuild: true, isSafe: true }, { name: 'Harbor district', alwaysBuild: true, isSafe: true }, { name: 'Stock exchange', alwaysBuild: true, isSafe: true }, { name: 'Mana pit', alwaysBuild: true, isSafe: true }, { name: 'Great bombard', alwaysBuild: true, isSafe: true }, { name: 'Refugees district', alwaysBuild: true, isSafe: true }, { name: 'Academy of Freethinkers', alwaysBuild: true, isSafe: true }, { name: 'City center', alwaysBuild: true, isSafe: true }, { name: 'Cathedral', alwaysBuild: true, isSafe: true }, { name: 'Great fair', alwaysBuild: true, isSafe: true }, { name: 'Palisade', alwaysBuild: true, isSafe: true }, { name: 'Wall', alwaysBuild: true, isSafe: true }, { name: 'City of Lights part', alwaysBuild: true, isSafe: true }, { name: 'Harbor district part', alwaysBuild: true, isSafe: true }, { name: 'Stock exchange part', alwaysBuild: true, isSafe: true }, { name: 'Mana pit part', alwaysBuild: true, isSafe: true }, { name: 'Great bombard part', alwaysBuild: true, isSafe: true }, { name: 'Refugees district part', alwaysBuild: true, isSafe: true }, { name: 'A. of Freethinkers Part', alwaysBuild: true, isSafe: true }, { name: 'City center part', alwaysBuild: true, isSafe: true }, { name: 'Great fair unit', alwaysBuild: true, isSafe: true }, { name: 'Cathedral part', alwaysBuild: true, isSafe: true }, { name: 'Guild of craftsmen', alwaysBuild: true, isSafe: true }, { name: 'Machines of gods', alwaysBuild: true, isSafe: true }, { name: 'Library of Theresmore', alwaysBuild: true, isSafe: true }, { name: 'Monastery', alwaysBuild: true, isSafe: true }, { name: 'Watchman Outpost', alwaysBuild: true, isSafe: true }, { name: 'Hall of the dead', alwaysBuild: true, isSafe: true }, { name: 'Sawmill', alwaysBuild: true, isSafe: true }, { name: 'Monument', alwaysBuild: true, isSafe: true }, { name: 'Foundry', alwaysBuild: true, isSafe: true }, { name: 'Builder district', alwaysBuild: true, isSafe: true }, { name: 'Gan Eden', alwaysBuild: true, isSafe: true }, { name: 'Observatory', isSafe: true }, { name: 'The Vaults', isSafe: true }, { name: 'Credit union', isSafe: true }, { name: 'Canava trading post', isSafe: true }, { name: 'Bank', isSafe: true }, { name: 'Marketplace', isSafe: true }, { name: 'Artisan Workshop', isSafe: true }, { name: 'Granary', isSafe: true }, { name: 'School', isSafe: true }, { name: 'University', isSafe: true }, { name: 'Research plant', isSafe: true }, { name: 'Undead Herds', isSafe: true }, { name: 'Guarded warehouse', isSafe: true }, { name: 'Fiefdom', isSafe: true }, { name: 'Natronite refinery', isSafe: true }, { name: 'Alchemical laboratory', isSafe: true }, { name: 'Lumberjack Camp', isSafe: true }, { name: 'Quarry', isSafe: true }, { name: 'Mine', isSafe: true }, { name: 'Palisade part', isSafe: true }, { name: 'Wall part', isSafe: true }, { name: 'Farm', isSafe: true }, { name: 'Matter transmuter', isSafe: true }, { name: 'Stable', isSafe: true }, { name: 'Spiritual garden', isSafe: true }, { name: 'Conclave', isSafe: true }, { name: 'Magical tower', isSafe: true }, { name: 'Temple', isSafe: true }, { name: 'Altar of sacrifices', isSafe: true }, { name: 'Fountain of Prosperity', isSafe: true }, { name: 'Valley of plenty', isSafe: true }, { name: 'Tax revenue checkpoints', isSafe: true }, { name: 'Industrial plant', isSafe: true }, { name: 'Magic Circle', isSafe: true }, { name: 'Carpenter workshop', isSafe: true }, { name: 'Grocery', isSafe: true }, { name: 'Steelworks', isSafe: true }, { name: 'Military academy', isSafe: true }, { name: 'Ancient vault', isSafe: true }, { name: 'Recruit training center', isSafe: true }, { name: 'Officer training ground', isSafe: true }, { name: 'Mansion', isSafe: false, requires: { resource: 'Food', parameter: 'speed', minValue: 3 } }, { name: 'City Hall', isSafe: false, requires: { resource: 'Food', parameter: 'speed', minValue: 1.5 } }, { name: 'Residential block', isSafe: false, requires: { resource: 'Food', parameter: 'speed', minValue: 5 } }, { name: 'Common House', isSafe: false, requires: { resource: 'Food', parameter: 'speed', minValue: 1 } }, { name: 'Storage facility', isSafe: true }, { name: 'Ballista', isSafe: true }, { name: 'Large warehouse', isSafe: true }, { name: 'Large storehouse', isSafe: true }, { name: 'Store', isSafe: true }, { name: 'Natronite depot', isSafe: true }, { name: 'Barracks', isSafe: true }, { name: 'Minefield', isSafe: true }, { name: 'Natronite balloon', isSafe: true }, { name: 'Decryption of the portal', isSafe: true }, { name: 'Fortune grove', isSafe: true }, { name: 'Pillars of mana', isSafe: false, requires: { resource: 'Gold', parameter: 'speed', minValue: 100 } }, ].filter((building) => building.name) const modes = { RESEARCH: 'Research', GAIN_GOLD: 'Gain Gold', BUILD: 'Build', BUY_BATTLE_ANGEL: 'Buy BA', DEFAULT: 'Default', } let mode = modes.DEFAULT let marketPlaceAvailable = false const pages = { BUILD: 'Build', RESEARCH: 'Research', POPULATION: 'Population', ARMY: 'Army', MARKETPLACE: 'Marketplace', MAGIC: 'Magic', UNKNOWN: 'Unknown', } const resourcesToTrade = ['Cow', 'Horse', 'Food', 'Copper', 'Wood', 'Stone', 'Iron', 'Tools'] const timeToWaitUntilFullGold = 60 const sleep = (miliseconds) => new Promise((resolve) => setTimeout(resolve, miliseconds)) // https://stackoverflow.com/a/55366435 class NumberParser { constructor(locale) { const format = new Intl.NumberFormat(locale) const parts = format.formatToParts(12345.6) const numerals = Array.from({ length: 10 }).map((_, i) => format.format(i)) const index = new Map(numerals.map((d, i) => [d, i])) this._group = new RegExp(`[${parts.find((d) => d.type === 'group').value}]`, 'g') this._decimal = new RegExp(`[${parts.find((d) => d.type === 'decimal').value}]`) this._numeral = new RegExp(`[${numerals.join('')}]`, 'g') this._index = (d) => index.get(d) } parse(string) { let multiplier = 1 if (string.includes('K')) { multiplier = 1000 } else if (string.includes('M')) { multiplier = 1000000 } return (string = string.replace('K', '').replace('M', '').trim().replace(this._group, '').replace(this._decimal, '.').replace(this._numeral, this._index)) ? +string * multiplier : NaN } } const numberParser = new NumberParser() const formatTime = (timeToFormat) => { const timeValues = { seconds: 0, minutes: 0, hours: 0, days: 0, } let timeShort = '' let timeLong = '' timeValues.seconds = timeToFormat % 60 timeToFormat = (timeToFormat - (timeToFormat % 60)) / 60 timeValues.minutes = timeToFormat % 60 timeToFormat = (timeToFormat - (timeToFormat % 60)) / 60 timeValues.hours = timeToFormat % 24 timeToFormat = (timeToFormat - (timeToFormat % 24)) / 24 timeValues.days = timeToFormat if (timeValues.days) { timeShort += `${timeValues.days}d ` timeLong += `${timeValues.days} days ` } if (timeValues.hours) { timeShort += `${timeValues.hours}h ` timeLong += `${timeValues.hours} hrs ` } if (timeValues.minutes) { timeShort += `${timeValues.minutes}m ` timeLong += `${timeValues.minutes} min ` } if (timeValues.seconds) { timeShort += `${timeValues.seconds}s ` timeLong += `${timeValues.seconds} sec ` } timeShort = timeShort.trim() timeLong = timeLong.trim() return { timeShort, timeLong, timeValues, } } window.switchScriptState = () => { scriptPaused = !scriptPaused window.localStorage.setItem('TMH_cheatsOff', JSON.stringify(false)) window.localStorage.setItem('TMH_scriptPaused', JSON.stringify(scriptPaused)) if (!scriptPaused) { setTimeout(() => { window.location.reload() }, 60 * 60 * 1000) mode = modes.DEFAULT switchPage(pages.BUILD) } } window.switchManualGold = () => { manualGold = !manualGold window.localStorage.setItem('TMH_cheatsOff', JSON.stringify(false)) window.localStorage.setItem('TMH_manualGold', JSON.stringify(manualGold)) } const getAllButtons = () => { let buttonsList = [] document.querySelectorAll('#maintabs-container button.btn.btn-dark:not(.btn-off)').forEach((button) => buttonsList.push(button)) return buttonsList } const getResource = (resourceName = 'Gold') => { let resourceFound = false let resourceToFind = { name: resourceName, current: 0, max: 0, speed: 0, ttf: null, ttz: null } const resources = document.querySelectorAll('#root div > div > div > table > tbody > tr > td:nth-child(1) > span') resources.forEach((resource) => { if (resource.textContent.includes(resourceName)) { resourceFound = true const values = resource.parentNode.parentNode.childNodes[1].textContent .split('/') .map((x) => numberParser.parse(x.replace(/[^0-9KM\-,\.]/g, '').trim())) resourceToFind.current = values[0] resourceToFind.max = values[1] resourceToFind.speed = numberParser.parse(resource.parentNode.parentNode.childNodes[2].textContent.replace(/[^0-9KM\-,\.]/g, '').trim()) || 0 resourceToFind.ttf = resourceToFind.speed > 0 && resourceToFind.max !== resourceToFind.current ? formatTime(Math.ceil((resourceToFind.max - resourceToFind.current) / resourceToFind.speed)) : null resourceToFind.ttz = resourceToFind.speed < 0 && resourceToFind.current ? formatTime(Math.ceil(resourceToFind.current / (resourceToFind.speed * -1))) : null } }) return resourceFound ? resourceToFind : null } const getAllResources = () => { const resources = document.querySelectorAll('#root div > div > div > table > tbody > tr > td:nth-child(1) > span') const resourceNames = [] resources.forEach((resource) => resourceNames.push(resource.textContent.trim())) return resourceNames } const getPage = () => { let page = pages.UNKNOWN const pageSelectedSelector = document.querySelector('#main-tabs > div > button[aria-selected="true"]') if (pageSelectedSelector) { const pageSelected = pageSelectedSelector.textContent if (pageSelected.includes('Build')) { page = pages.BUILD } else if (pageSelected.includes('Research')) { page = pages.RESEARCH } else if (pageSelected.includes('Population')) { page = pages.POPULATION } else if (pageSelected.includes('Army')) { page = pages.ARMY } else if (pageSelected.includes('Marketplace')) { page = pages.MARKETPLACE } else if (pageSelected.includes('Magic')) { page = pages.MAGIC } } return page } const hasPage = (page) => { let foundPage = false const navButtons = document.querySelectorAll('#main-tabs > div > button') navButtons.forEach((button) => { if (button.innerText.includes(page)) { foundPage = true } }) return foundPage } const switchPage = async (page) => { if (cheatsOff) return if (scriptPaused) return let foundPage = hasPage(page) if (!foundPage) { mode = modes.DEFAULT switchPage(pages.BUILD) return } let switchedPage = false const navButtons = document.querySelectorAll('#main-tabs > div > button') navButtons.forEach((button) => { if (button.innerText.includes(page) && button.getAttribute('aria-selected') !== 'true') { button.click() switchedPage = true } }) if (switchedPage) { console.log(`$-> Switched page to ${page}`) await sleep(3500) } setTimeout(takePageAction, 1) } const takePageAction = async () => { if (cheatsOff) return if (scriptPaused) return let page = getPage() if (page !== pages.BUILD && mode === modes.BUILD) { switchPage(pages.BUILD) return } else if (page !== pages.RESEARCH && mode === modes.RESEARCH) { switchPage(pages.RESEARCH) return } else if (page !== pages.MARKETPLACE && mode === modes.GAIN_GOLD) { switchPage(pages.MARKETPLACE) return } else if (page !== pages.ARMY && mode === modes.BUY_BATTLE_ANGEL) { switchPage(pages.ARMY) return } if (page === pages.BUILD) { setTimeout(spendResourcesBuilding, 1) } else if (page === pages.RESEARCH) { setTimeout(performReserach, 1) } else if (page === pages.MARKETPLACE) { setTimeout(playMarket, 1) } else if (page === pages.ARMY) { setTimeout(buyArmy, 1) } else { setTimeout(takePageAction, 1000) } } const spendResourcesBuilding = async () => { if (cheatsOff) return if (scriptPaused) return if (getPage() !== pages.BUILD) { setTimeout(takePageAction, 1000) return } const buttonsList = getAllButtons() const buildingNames = [] buttonsList.forEach((button) => buildingNames.push(button.innerText.split('\n').shift())) let hasBuilt = false let shouldBuild = false for (let i = 0; i < buildingsList.length && !hasBuilt; i++) { if (hasBuilt) break const building = buildingsList[i] shouldBuild = buildingNames.includes(building.name) if (!building.isSafe) { const requiredResource = getResource(building.requires.resource) if (!requiredResource) { shouldBuild = false } else { shouldBuild = shouldBuild && requiredResource[building.requires.parameter] > building.requires.minValue } } if (shouldBuild) { if (building.alwaysBuild || mode === modes.BUILD) { buttonsList.find((button) => { if (button.innerText.split('\n').shift() === building.name) { button.click() hasBuilt = true mode = modes.DEFAULT console.log(`#-> Started building ${building.name}`) return true } }) } else { mode = modes.BUILD } } } await sleep(5000) if (mode === modes.BUILD || shouldBuild || hasBuilt) { spendResourcesBuilding() } else { const gold = getResource('Gold') let shouldSell = resourcesToTrade.find((resName) => { const res = getResource(resName) if (res && (res.current === res.max || res.current + res.speed * timeToWaitUntilFullGold >= res.max)) return true }) if (marketPlaceAvailable && gold.current + gold.speed * timeToWaitUntilFullGold < gold.max && shouldSell) { mode = modes.GAIN_GOLD switchPage(pages.MARKETPLACE) } else { if (hasPage(pages.ARMY)) { mode = modes.BUY_BATTLE_ANGEL switchPage(pages.ARMY) } else { mode = modes.RESEARCH switchPage(pages.RESEARCH) } } } } const performReserach = async () => { if (cheatsOff) return if (scriptPaused) return if (getPage() !== pages.RESEARCH) { setTimeout(takePageAction, 1000) return } const manualResearches = ['A moonlight night', 'Dragon assault', 'Mysterious robbery', 'The Fallen Angel reveal'] let didResearch = false const buttonsList = getAllButtons() const researchesList = [] buttonsList.forEach( (button) => !manualResearches.includes(button.innerText.split('\n').shift()) && researchesList.push(button.innerText.split('\n').shift()) ) if (researchesList.length) { while (!didResearch && researchesList.length) { const research = researchesList.shift() buttonsList.forEach((button) => { if (button.innerText.split('\n').shift() === research) { button.click() didResearch = true console.log(`%-> Researching ${research}`) } }) } } if (didResearch) { await sleep(5000) } else { await sleep(2000) } mode = modes.DEFAULT await switchPage(pages.BUILD) } const playMarket = async () => { if (cheatsOff) return if (playingMarket) return if (getPage() !== pages.MARKETPLACE) { setTimeout(takePageAction, 1000) return } let gold = getResource('Gold') let shouldSell = resourcesToTrade.find((resName) => { const res = getResource(resName) if (res && res.current === res.max) return true }) if (gold && gold.current < gold.max && shouldSell) { playingMarket = true const resourceHoldersQSA = document.querySelectorAll('div > div.tab-container > div > div > div') const resourceHolders = [] if (resourceHoldersQSA) { resourceHoldersQSA.forEach((resourceHolder) => { const resName = resourceHolder.querySelector('h5').innerText const res = getResource(resName) if (resourcesToTrade.includes(resName) && res && (res.current === res.max || res.current + res.speed * timeToWaitUntilFullGold >= res.max)) { resourceHolders.push(resourceHolder) } }) } for (let i = 0; i < resourceHolders.length; i++) { gold = getResource('Gold') const resourceHolder = resourceHolders[i] const resName = resourceHolder.querySelector('h5').innerText let res = getResource(resName) const initialPrice = numberParser.parse(resourceHolder.querySelector('div:nth-child(2) > div > table > tbody > tr > td:nth-child(2)').innerText) let price = initialPrice let sellButtons = resourceHolder.querySelectorAll('div:nth-child(2) > div.grid.gap-3 button:not(.btn-dark)') while (sellButtons && sellButtons.length && gold.current < gold.max && res.current + res.speed * timeToWaitUntilFullGold * 2 >= res.max) { let maxSellButton = 2 const missingResToSell = Math.ceil((gold.max - gold.current) / price) if (missingResToSell < 80) { maxSellButton = 0 } else if (missingResToSell < 800) { maxSellButton = 1 } maxSellButton = Math.min(maxSellButton, sellButtons.length - 1) sellButtons[maxSellButton].click() await sleep(10) sellButtons = resourceHolder.querySelectorAll('div:nth-child(2) > div.grid.gap-3 button:not(.btn-dark)') gold = getResource('Gold') res = getResource(resName) price = numberParser.parse(resourceHolder.querySelector('div:nth-child(2) > div > table > tbody > tr > td:nth-child(2)').innerText) await sleep(1) if (price / initialPrice < 0.1) { break } } } playingMarket = false } mode = modes.RESEARCH await switchPage(pages.RESEARCH) } const canAffordBA = () => { const faith = getResource('Faith') const mana = getResource('Mana') if (faith && mana) { if (faith.current >= 2000 && mana.current >= 600) { return true } } return false } const buyArmy = async () => { if (cheatsOff) return if (scriptPaused) return if (getPage() !== pages.ARMY) { setTimeout(takePageAction, 1000) return } if (canAffordBA()) { const allButtonsQSA = document.querySelectorAll('div > div > div > div > div > span > button:not(.btn-off)') let buyBAButton = null allButtonsQSA.forEach((button) => { if (button.innerText.includes('Battle Angel')) { buyBAButton = button } }) if (buyBAButton) { const mana = getResource('Mana') if (mana.speed >= 10) { buyBAButton.click() await sleep(5000) } } } mode = modes.RESEARCH await switchPage(pages.RESEARCH) } const managePanel = async () => { if (cheatsOff) return const controlPanel = document.querySelector('div#theresMoreHelpControlPanel') let scriptState = scriptPaused ? `▶️` : `⏸️` let manualGoldState = manualGold ? '🤑' : `😅` if (!controlPanel) { const controlPanelElement = document.createElement('div') controlPanelElement.id = 'theresMoreHelpControlPanel' controlPanelElement.classList.add('dark') controlPanelElement.classList.add('dark:bg-mydark-300') controlPanelElement.style.position = 'fixed' controlPanelElement.style.bottom = '10px' controlPanelElement.style.left = '10px' controlPanelElement.style.zIndex = '99999999' controlPanelElement.style.border = '1px black solid' controlPanelElement.style.padding = '10px' controlPanelElement.innerHTML = ` <p class="mb-2">TheresMoreHelp: <button onClick="window.switchScriptState()" title="Start/stop script" class="scriptState">${scriptState}</button> <button onClick="window.switchManualGold()" title="Always play market" class="manualGold">${manualGoldState}</button> </p> <p class="currentPage text-xs mb-2 text-orange-500">Page: ${getPage()}</p> <p class="currentAction text-xs text-orange-500">Mode: ${mode}</p> ` document.querySelector('div#root').insertAdjacentElement('afterend', controlPanelElement) } else { controlPanel.querySelector('.currentPage').textContent = `Page: ${getPage()}` controlPanel.querySelector('.currentAction').textContent = `Mode: ${mode}` controlPanel.querySelector('.scriptState').textContent = scriptState controlPanel.querySelector('.manualGold').textContent = manualGoldState } } const calculateTTF = () => { const resourceTrNodes = document.querySelectorAll('#root > div > div:not(#maintabs-container) > div > div > div > table:not(.hidden) > tbody > tr') resourceTrNodes.forEach((row) => { const cells = row.querySelectorAll('td') const resourceName = cells[0].textContent.trim() const resource = getResource(resourceName) let ttf = '' if (resource && resource.current < resource.max && resource.speed) { ttf = resource.ttf ? resource.ttf.timeLong : resource.ttz.timeLong } if (!cells[3]) { const ttfElement = document.createElement('td') ttfElement.className = 'px-3 3xl:px-5 py-3 lg:py-2 3xl:py-3 whitespace-nowrap w-1/3 text-right' ttfElement.textContent = ttf row.appendChild(ttfElement) } else { cells[3].textContent = ttf } }) } const calculateTippyTTF = () => { let potentialResourcesToFillTable = document.querySelectorAll('div.tippy-box > div.tippy-content > div > div > table') if (potentialResourcesToFillTable.length) { potentialResourcesToFillTable = potentialResourcesToFillTable[0] const rows = potentialResourcesToFillTable.querySelectorAll('tr') rows.forEach((row) => { const cells = row.querySelectorAll('td') const resourceName = cells[0].textContent.trim() const resource = getResource(resourceName) if (resource) { let ttf = '✅' const target = numberParser.parse( cells[1].textContent .split(' ') .shift() .replace(/[^0-9KM\-,\.]/g, '') .trim() ) if (target > resource.max || resource.speed <= 0) { ttf = 'never' } else if (target > resource.current) { ttf = formatTime(Math.ceil((target - resource.current) / resource.speed)).timeShort } if (!cells[2]) { const ttfElement = document.createElement('td') ttfElement.className = 'px-4 3xl:py-1 text-right' ttfElement.textContent = ttf row.appendChild(ttfElement) } else { cells[2].textContent = ttf } } }) } } const checkMarketplaceAvailable = async () => { let hasResourcesToTrade = false let hasMarketplaceEnabled = false resourcesToTrade.forEach((resName) => { const res = getResource(resName) if (res) { hasResourcesToTrade = true } }) const navButtons = document.querySelectorAll('#main-tabs > div > button') navButtons.forEach((button) => { if (button.innerText.includes('Marketplace') && button.getAttribute('aria-selected') !== 'true') { hasMarketplaceEnabled = true } }) marketPlaceAvailable = hasResourcesToTrade && hasMarketplaceEnabled } const tossACoinToYourClicker = () => { if (cheatsOff) return if (!haveManualResourceButtons) return if (scriptPaused) return const manualResources = ['Food', 'Wood', 'Stone'] const resourcesToClick = [] const buttonsToClick = [] const buttons = document.querySelectorAll( '#root > div.flex.flex-wrap.w-full.mx-auto.p-2 > div.w-full.lg\\:pl-2 > div > div.order-2.flex.flex-wrap.gap-3 > button' ) if (!buttons) { haveManualResourceButtons = false return } manualResources.forEach((resourceName) => { const resource = getResource(resourceName) if (resource && resource.current < resource.max && (!resource.speed || resource.speed <= 0)) { resourcesToClick.push(resourceName) } }) buttons.forEach((button) => { if (resourcesToClick.includes(button.innerText.trim())) { buttonsToClick.push(button) } }) while (buttonsToClick.length) { const buttonToClick = buttonsToClick.shift() buttonToClick.click() } } const checkToPlayMarket = () => { if (cheatsOff) return const page = getPage() if (scriptPaused && manualGold && marketPlaceAvailable && !playingMarket && page === pages.MARKETPLACE) { playMarket() } if (page !== pages.MARKETPLACE) { playingMarket = false } } const performRoutineTasks = () => { calculateTTF() if (!cheatsOff) { checkMarketplaceAvailable() managePanel() checkToPlayMarket() } } const performFastTasks = () => { calculateTippyTTF() if (!cheatsOff) { if (haveManualResourceButtons) tossACoinToYourClicker() } } window.setInterval(performRoutineTasks, 1000) window.setInterval(performFastTasks, 100) const loadSettingsFromLocalStorage = () => { const TMH_scriptPaused = window.localStorage.getItem('TMH_scriptPaused') const TMH_manualGold = window.localStorage.getItem('TMH_manualGold') const TMH_cheatsOff = window.localStorage.getItem('TMH_cheatsOff') if (TMH_cheatsOff) { cheatsOff = JSON.parse(TMH_cheatsOff) } if (TMH_scriptPaused) { scriptPaused = JSON.parse(TMH_scriptPaused) } if (TMH_manualGold) { manualGold = JSON.parse(TMH_manualGold) } } loadSettingsFromLocalStorage() if (!cheatsOff) { takePageAction() if (!scriptPaused) { setTimeout(() => { window.location.reload() }, 60 * 60 * 1000) } } })()