您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
The cheat script for DH3
当前为
// ==UserScript== // @name DH3 KindaSafe Cheat // @namespace http://tampermonkey.net/ // @version 1.2.1 // @description The cheat script for DH3 // @author Lasse Brustad // @match https://dh3.diamondhunt.co/ // @grant none // ==/UserScript== /* jshint esversion:6 */ (function() { 'use strict'; // config for cheats const cheats = { // auto fight, configs starting at line 45 autoCombat: !true, // auto smelt ores, click the ore under the mining tab to choose // will automatically fill the furnace to it's maximum capacity // configs starting at line 70 autoSmelt: !true, // auto chop trees, it's fully automated with a tiny issue that doesn't matter autoChop: !true, // auto farm, configs starting at line 76 - not ready yet autoFarm: !true, // auto consume stardust potions you have autoDrinkSD: !true, // auto send/collect the Oxygen Tank, you can't get any fish at all with this on autoOxy: !true, // auto send/collect the Row Boat, this is forced off if autoOxy is on autoRowBoat: !true, // auto send/collect the Canoe Boat, this is forced off if autoOxy or autoRowBoat is on autoCanoeBoat: !true }; const combatConfig = { areas: { // area name : energy cost // this shouldn't be a problem fields: 50, // don't forget your weapon forest: 200, // be prepared with armor and weapon caves: 500, // you might lose against the alien! lavaDungeon: 2e3, // this script will lose most likely 99% of all attempts northernFields: 5e3 }, // the area you want to fight automatically from the "areas" list area: 'fields' // prefer stored value, later changing the string here have no effect } // additional config for autoSmelt const smeltConfig = { // smelt all resources that can be smelted (not ready yet) smeltAllAvaliable: true } // additional configs for autoFarm const farmConfig = { // plant seeds even if they require bonemeal allowBonemealUsage: false, // fill bonemeal bin with fishbones, ashes, or bones when possible autoFillBonemealBin: false, // allow planting seeds that can die allowDyingPlants: false }; // config for legal mods const mods = { // right click the axe to chop down all fully grown trees chopTrees: true, // right click the rake to harvest all the ready farms harvestCrops: true }; /** * Code below here is functional code, but you can enable/disable everything in the configs above * * Remember, cheats is safe to use as it is, but if you mess with the code, * don't blame me if you get banned! Cheats is ofc not allowed, but who cares? */ // logging / debugging const debugLevels = [ 'silent', 'normal logging', 'additional logging', 'debugging' ]; let debugLevel = parseInt(localStorage.getItem('lbdata-debug')) || 1; window.setDebugLevel = (lvl = debugLevel) => { if (typeof lvl !== 'number' || (lvl < 0 && lvl > (debugLevels.length - 1))) { console.log(`Didn't change the logging level, it has to be a number between 0 and 3.`); return; } const previous = debugLevel; debugLevel = lvl; if (previous === debugLevel) { console.log(`Current debug level is: ${lvl} ~ ${debugLevels[lvl]}`); } else { console.log(`Debug level is now set to: ${lvl} ~ ${debugLevels[lvl]}`); } } // auto combat let willFightSoon = false; let fightingError = JSON.parse(localStorage.getItem('lbdata-combatError')) || false; function autoCombat() { // damn, didn't expect this function to require that much anti-fail testing if (fightingError) return; if (willFightSoon || window.getItem('heroCooldown') !== 0) return debug(3, `Combat isn't ready yet`); if (!Object.keys(combatConfig.areas).includes(combatConfig.area)) { fightingError = true; debug(2, `The script has no area called ${combatConfig.area} registered!`); return; } if (combatConfig.areas[combatConfig.area] > window.getItem('energy')) return debug(2, `You're low on energy! Eat some food to continue fighting!`);; // FIGHT!!! willFightSoon = true; safeDelay(() => { setTimeout(() => { willFightSoon = false; }, 30e3); if (window.getItem('heroCooldown') !== 0) return debug(3, `Combat isn't ready yet`); window.sendBytes(`FIGHT=${combatConfig.area}`); }) } // settings for autoCombat while playing window.setCombatStatus = (state = null) => { if (typeof state === 'boolean') { fightingError = !state; console.log(`Set the state to ${state ? 'active' : 'inactive'}`); } else if (typeof state === 'string' && typeof combatConfig.areas[state] === 'number') { combatConfig.area = state; console.log(`Set the area to ${state}`); } else if (state === null) { console.log(`Current state: Fighting ${combatConfig.area} is ${!fightingError ? 'active' : 'inactive'}`); } } unload(e => { localStorage.setItem('lbdata-combatError', JSON.stringify(fightingError)); localStorage.setItem('lbdata-combatArea', combatConfig.area); }); // auto smelt ores if (cheats.autoSmelt) { window.smeltOre = localStorage.getItem('lbdata-smeltOre') || 'copper'; // the ore to smelt unload(e => { localStorage.setItem('lbdata-smeltOre', window.smeltOre); }); } const ores = { sand: { oil: 1, time: 1 }, copper: { oil: 1, time: 1 }, iron: { oil: 5, time: 5 }, silver: { oil: 20, time: 20 }, gold: { oil: 100, time: 60 }, promethium: { oil: 1000, time: 200 } }; function cheatSmelt() { if (typeof ores[window.smeltOre] !== 'object') return debug(1, `Cheat - Unknown ore: "${window.smeltOre}"`); function doit() { if (window.isSmelting()) { // wait till current smelting is over const estimated = (window.var_smeltingRequestedAmount - window.var_smeltingCurrentAmount) * window.var_smeltingNeededTimer; debug(3, `isSmelting() === true, estimated time: ${estimated}s`); safeDelay(doit, estimated * 1e3 / 3); return; } const hasAmount = parseInt(window['var_' + window.smeltOre]), furnaceCapacity = parseInt(window.var_furnaceCapacity); if (isNaN(hasAmount) || hasAmount < furnaceCapacity || (ores[window.smeltOre].oil * furnaceCapacity) > parseInt(window.var_oil)) { debug(3, `have ${hasAmount} ${window.smeltOre} and ${window.var_oil} oil`); // wait even longer when stuff is missing safeDelay(doit, 6e3); return; } debug(2, `Starts smelting ${window.var_furnaceCapacity} ${window.smeltOre}!`); window.smelt(window.smeltOre, window.var_furnaceCapacity); safeDelay(cheatSmelt, ores[window.smeltOre].time * window.var_furnaceCapacity * 1e3); } safeDelay(doit); } function clicksItemMod() { const orig = window.clicksItem; window.clicksItem = (item, ...args) => { if (typeof ores[item] === 'object') { window.smeltOre = item; } orig(item, ...args); }; } // auto chop trees function cheatChop() { const treeData = { click(n) { debug(2, `Auto Chop - Chopping patch ${n}`); document.getElementById(`tree-section-${n}`).click(); setTimeout(() => window.closeDialogue('dialogue-confirm'), 1e3); }, timer(n) { return window[`var_treeTimer${n}`] * 1; }, isActive(n) { return window[`var_tree${n}`] !== 'none'; } }; const tasks = [null, false, false, false, false, false, false]; function chop(num, waitMinSec = 0) { if (tasks[num]) return; tasks[num] = true; safeDelay(() => { tasks[num] = false; if (!treeData.isActive(num)) return; treeData.click(num); }, waitMinSec * 1e3); } function loop() { for (let i = 1; i < tasks.length; i++) { const timeLeft = treeData.timer(i); if (timeLeft < 10) chop(i, timeLeft); } } setInterval(loop, 1e4); } // auto farm const seeds = { // named window.var_${key}Seeds // data found at https://anwinity.com/DH3/#farmingBrewing redMushroom: { // required level to plant lvlRequired: 1, // stops dying level stopsDying: 0, // bonemeal required bonemeal: 0, // time in minutes time: 15 }, stardust: { lvlRequired: 15, stopsDying: 0, bonemeal: 5, time: 30 }, dottedGreenLeaf: { lvlRequired: 1, stopsDying: 15, bonemeal: 0, time: 15 }, greenLeaf: { lvlRequired: 10, stopsDying: 25, bonemeal: 0, time: 30 }, limeLeaf: { lvlRequired: 30, stopsDying: 40, bonemeal: 5, time: 60 }, goldLeaf: { lvlRequired: 45, stopsDying: 55, bonemeal: 20, time: 120 }, crystalLeaf: { lvlRequired: 70, stopsDying: 80, bonemeal: 50, time: 300 }, // stripedGoldLeaf: { // lvlRequired: 80, // stopsDying: 88, // bonemeal: 120, // time: 600 // }, // stripedCrystalLeaf: { // lvlRequired: 90, // stopsDying: 95, // bonemeal: 200, // time: 960 // }, tree: { lvlRequired: 1, stopsDying: 10, bonemeal: 0, time: 60 }, oakTree: { lvlRequired: 15, stopsDying: 0, bonemeal: 5, time: 90 }, willowTree: { lvlRequired: 30, stopsDying: 40, bonemeal: 10, time: 120 }, bambooTree: { lvlRequired: 40, stopsDying: 50, bonemeal: 20, time: 140 }, mapleTree: { lvlRequired: 50, stopsDying: 60, bonemeal: 50, time: 220 }, lavaTree: { lvlRequired: 60, stopsDying: 70, bonemeal: 60, time: 300 }, pineTree: { lvlRequired: 65, stopsDying: 75, bonemeal: 75, time: 320 }, stardustTree: { lvlRequired: 70, stopsDying: 80, bonemeal: 100, time: 360 } // appleTree: { // lvlRequired: 45, // stopsDying: 55, // bonemeal: 30, // time: 163 // }, // bananaTree: { // lvlRequired: 63, // stopsDying: 73, // bonemeal: 65, // time: 175 // } }; const plots = [ window.getItem('plotTimer1') || null, window.getItem('plotTimer2') || null, window.getItem('plotTimer3') || null, window.getItem('plotTimer4') || null, window.getItem('plotTimer5') || null, window.getItem('plotTimer6') || null ]; function autoFarm() { function sortedSeeds() { const _seeds = []; for (let name of Object.keys(seeds)) { const owned = window.getItem(`${name}Seeds`); if (owned < 1) continue; _seeds.push({name, owned}); } return _seeds.sort((a, b) => a.name.localeCompare(b.name)); } } // auto drink stardust potion let willConsumeSDPot = false; function autoSDPot() { const timeLeft = parseInt(window.var_stardustPotionTimer); if (timeLeft <= (5 * 60) && parseInt(window.var_stardustPotion) > 0 && !willConsumeSDPot) { willConsumeSDPot = true; safeDelay(() => { window.sendBytes('DRINK=stardustPotion'); setTimeout(() => { willConsumeSDPot = false; }, 3e3); }); } } // auto boat let willUseBoat = false; function cheatAnyBoat(str = 'oxygenTank') { if (willUseBoat) return; const tLeft = window.getItem(str + "Timer"); if (tLeft > 2) return; let task = () => {}; switch (tLeft) { case 0: willUseBoat = true; task = () => window.sendBytes("SEND_BOAT=" + str); break; case 1: willUseBoat = true; task = () => window.sendBytes("COLLECT_BOAT=" + str); break; } safeDelay(() => { const timeLeft = window.getItem(str + "Timer"); if (timeLeft === tLeft) task(); willUseBoat = false; }); } function initCheats() { // combat if (cheats.autoCombat) { setInterval(autoCombat, 1e3); debug(1, 'Cheat - Initialized Auto Combat'); } // mining/crafting if (cheats.autoSmelt) { cheatSmelt(); clicksItemMod(); debug(1, 'Cheat - Initialized Auto Smelt'); } // woodcutting if (cheats.autoChop) { cheatChop(); debug(1, 'Cheat - Initialized Auto Chop'); } // farming if (cheats.autoFarm) { autoFarm(); debug(1, 'Cheat - Initialized Auto Farm'); } // brewing if (cheats.autoDrinkSD) { setInterval(autoSDPot, 2e3); debug(1, 'Cheat - Initialized Auto Drink Stardust Potion'); } // fishing if (cheats.autoOxy) { setInterval(cheatAnyBoat, 1e3); debug(1, 'Cheat - Initialized Auto Oxygen Tank'); } else if (cheats.autoRowBoat) { setInterval(() => cheatAnyBoat('rowBoat'), 1e3); debug(1, 'Cheat - Initialized Auto Row Boat'); } else if (cheats.autoCanoeBoat) { setInterval(() => cheatAnyBoat('canoeBoat'), 1e3); debug(1, 'Cheat - Initialized Auto Canoe Boat'); } } // mod 1 - RightClick axe to chop all trees function chopTrees(e) { const trees = getEls('#tree-section-woodcutting > center > div'); e.preventDefault(); trees.each(el => { const timeEl = el.querySelector('.tree-secton-timer'); const time = timeEl !== null ? timeEl.innerText : ''; if (time === 'READY') el.click(); }); debug(2, 'Chopped all trees'); } // mod 2 - RightClick rake to harvest the crops function harvestCrops(e) { const trees = getEls('#plot-section-farming > center > div'); e.preventDefault(); trees.each(el => { const timeEl = el.querySelector('.tree-secton-timer'); const time = timeEl !== null ? timeEl.innerText : ''; if (time === 'READY') el.click(); }); debug(2, 'Harvested all crops'); } function initMods() { if (mods.chopTrees) { // init mod 1 getEls('#item-section-woodcutting-1 [data-tooltip-id=tooltip-axe]') .each(el => el.addEventListener('contextmenu', chopTrees)); debug(1, 'Mod - Initialized Right Click Axe'); } if (mods.harvestCrops) { // init mod 2 getEls('#item-section-farming-1 [data-tooltip-id=tooltip-rake]') .each(el => el.addEventListener('contextmenu', harvestCrops)); debug(1, 'Mod - Initialized Right Click Rake'); } } function init() { if (typeof window.var_username === "string" && window.var_username.length >= 3) { initMods(); debug(1, 'Initialized Mods'); initCheats(); debug(1, 'Initialized Cheats'); } else { setTimeout(init, 2e3); } } setTimeout(init, 2e3); /** * minor functions for this script to work well with clean code */ function getEls(qSel) { let els = document.querySelectorAll(qSel); return { getRaw() { return els; }, getNum(x) { return els[x]; }, each(fn) { els.forEach(fn); }, ids() { let res = []; for (let key of els) res.push(key.id || 'none'); return res; } } } function debug(lvl, ...msg) { if (lvl > debugLevel) { return; } switch (lvl) { case 0: // silent return; case 1: // standard logging case 2: // additional logging return console.log('DH3 KindaSafe:', ...msg); case 3: // debugging return console.log('DH3 KindaSafe Debugging:', ...msg); } } function unload(fn) { window.addEventListener('unload', fn); } // A safe cheat delayer function safeDelay(fn, minTime = 0) { setTimeout(fn, Math.floor(Math.random() * 9e3) + 1e3 + minTime); } function smeltMax(resource) { if (window.isSmelting()) return `Your furnace in unavaliable!`; const cost = window.getOilCost(resource); if (cost === 0) return `Can't smelt "${resource}"`; let cap = window.getItem('furnaceCapacity'), max = window.getItem(resource) > cap ? cap : window.getItem(resource); if (max === 0) return `You don't have any ${resource}!`; const oil = window.getItem('oil'); max = (max * cost) < oil ? max : Math.min(oil / (max * cost)); if (max === 0) return `You don't have enought oil to smelt ${resource}`; window.smelt(resource, max); // will smelt maximum possible of resource } window.smeltMax = smeltMax; function smeltableResources() { const result = []; const _ores = Object.keys(ores).reverse(); for (let ore of _ores) { if (ore === window.smeltOre && cheats.autoSmelt) continue; if (window.getItem(ore) !== 0) result.push(ore); } return result; } window.smeltableResources = smeltableResources; function smeltAvaliable() { if (window.isSmelting()) return `Your furnace in unavaliable!`; const avaliable = smeltableResources(); if (avaliable.length === 0) return `You don't have any smeltable resources!`; smeltMax(avaliable[0]); } window.smeltAvaliable = smeltAvaliable; })();