您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Quality of Life changes for Diamond Hunt Online
当前为
// ==UserScript== // @name DHQoL // @namespace http://tampermonkey.net/ // @version 1.4 // @description Quality of Life changes for Diamond Hunt Online // @author John / WhoIsYou // @match http://*.diamondhunt.co/game.php // @match https://*.diamondhunt.co/game.php // @run-at document-idle // @grant none // @grant GM_getValue // @grant GM_setValue // ==/UserScript== /* jshint -W097 */ 'use strict'; /** FEATURES: - Clickable links in chat! Very simple regex pattern that won't catch ALL links, but it will catch the majority / common formats - Market exclusion list, to filter out users you don't like or don't want to see (such as justanoob) - Serves little purpose now do to recent updates - Market clutter remover, only shows the 5 first/cheapest listings for any single, item not counting your own items - Market inclusion list, doesn't count any offers by these users in the 5 offer limit per item (always shows these people's items) - Rocket timer that's fairly accurate (though RNG based) based on average distances traveled per second found via logging - Furnace timer (accurate) in addition to the percentage. Bar type text removed and iron furnace image replaced with current item being smelted - Improved timers for, fishing boat, rocket, robot, furnace, exploring, potions, farming (only if you have the donor perk), spells, and ancient crystal in the HH:MM:SS format - Farming, Furnace, and Exploring timers factor in the donor perks if you have them, giving much more accurate timers than the default (though farming is still slightly RNG based) - Prevents the selling of brewing ingredients in the brewing tab - Added indicators that let you know when you have Explorer's Potions or Artifact Potions active - Improved functionality for converting your coins to plat and plat to coins (left click them) - Removed binding of equal or lower tier furnaces and ovens if you have promethium or higher bound - Added the ability to craft multiple rocket fuel barrels, activate with 200m+ oil if you have an oil refinery, or 100m+ without, otherwise it crafts 1 per click like normal - Wealth Evaluator found under key items, click it to evaluate the value of all of your tradable items based on market prices - Added the ability to use "k" or "b" in market prices when listing an item as shorthand for "thousands" and "billions" respectively ("m" for millions exists) - Chat spam filter, filters out spammers, and automatically mutes and reports the worst offenders - Toggleable "darkmode" for the chatbox, changes the background colour and the colour of moderator text - PM viewing mode for the chatbox so you don't have to scroll up to see old PMs **/ /** CHANGELOG: v1.4 (Feb 20 2016) - Added a wealth evaluator, accessible from your key items - Added a spam filter to the chat - Improved furnace timer to take the donator perk into account more accurately - Delay for multiple rocket fuel barrel crafting doubled to avoid issues - Added the ability to use "k" or "b" in market prices when listing an item as shorthand for "thousands" and "billions" respectively ("m" for millions exists) - Added a toggleable darkmode to the chatbox - Added a tab to the chatbox that only displays private messages, sent and received - Market exclusion list cleared as it no longer serves a purpose v1.3b: (Feb 1 2016) - Fixed FireFox support by switching to @grant none, instead of unsafeWindow v1.3: (Feb 1 2016) - Improved coin swapping functionality, left click coins to convert to plat, left click plat to convert to coins - Dialog asking how many rocket fuel barrels you would like to craft if you're above a certain oil threshold, otherwise it crafts one like normal - Removed the ability to bind equal or lower tier ovens and furnaces if you have promethium or higher bound - Added users "faggots" and "nogresh" to the market exclusions list (they don't seem to play anymore) - Added formatting for magic spell timers - Added formatting for ancient crystal timer - Restructured some code v1.2a: (Jan 13 2016) - Updated code structure a little (not done yet) - Added timer formatting for the new fishing boat - Made items in the brewing tab unsellable on left click (req: https://redd.it/40uw3m) v1.1a: (Jan 8 2016) - Fixed furnace timer, no longer performs additional calculations for donator perk (this was default behaviour!) v1.0: (Jan 8 2016) - Release **/ var config = { ENABLE_LOGGING : true }; // Array of potions that use timers var TIMED_POTION_LIST = ["starDustPotion", "seedPotion", "smeltingPotion", "oilPotion", "miningPotion", "superStarDustPotion", "coinPotion", "compost", "fishingPotion", "essencePotion", "fastFurnacePotion", "superOilPotion", "megaStarDustPotion", "whaleFishingPotion", "megaOilPotion"]; // Array of spells that use timers var TIMED_SPELL_LIST = ["superDrills", "superGemFinder", "smallSips", "superPirate", "superCrushers", "sparklingCompostPotion", "superGiantDrills", "fastVendor", "superRoadHeaders", "animatedAxe", ]; // Users to be excluded from the market listing var MARKET_EXCLUSION_LIST = []; // Users to always be included in the market listing, useful if you have a habit of trading with a specific person var MARKET_INCLUSION_LIST = []; // Chatbox darkmode variables var chatboxDarkModeEnabled = GM_getValue("chatboxDarkModeEnabled", false); // Defaults to false if not set var modChatColor = "#669999"; var modChatDarkModeColor = "#44b9dc"; // Chat filter object, stores info on all chatting players to be checked against our spam filter var chatFilter = { }; // Immediately-invoked function expression (IIFE), runs once on page load (function() { cLog("Launching DH QoL! Welcome, " + window.username + "."); // Create new notification boxes for artifact and explorer's potions createNotificationBoxes(); // Disable the selling of brewing items disableBrewingItemSelling(); // Improve the coin swapping functionality when clicking on coin icons improveCoinSwap(); // Adds the ability to craft multiple rocket fuel barrels setCraftMultipleRocketFuel(); // Adds the wealth evaluator to key items addWealthEvaluator(); // Make the new private chat tab in the chat makePrivateChatTab(); // Create the chatbox darkmode toggle button and set the chatbox to darkmode if the setting is saved as on createDarkModeToggleButton(); if (chatboxDarkModeEnabled) { setChatboxDarkMode(); } // Remove the ability to bind furnaces and ovens if you have higher tier ones setTimeout(disableBindFurnacesAndOvens, 3000); // 3 second delay after page loads so our variables (such as bound items) can load from ajax requests })(); /* --- Market --- */ /* Make changes to #loadOffers to filter out unwanted market items from the market table Filters out any users in our MARKET_EXCLUSION_LIST and filters out all but the cheapest 5 offers for any item (your own items do not count towards this limit) Items in the MARKET_INCLUSION_LIST will always be shown even if they are not among the cheapest 5 */ window.loadOffers = function(unparsedData) { var lastItem = ""; var lastItemCount = ""; var dataArray = unparsedData.split("~"); var table = document.getElementById("market-buy-table"); resetGEBox(1); resetGEBox(2); resetGEBox(3); table.innerHTML = "<tr class='table-th'><th>Player</th><th>Item</th><th>Icon</th><th>Amount</th><th>Price each</th></tr>"; for(var i = 0; i < dataArray.length; i++) { var playerId = dataArray[i]; i++; var playerUsername = dataArray[i]; i++; var item = dataArray[i];i++; var total = dataArray[i];i++; var pricePer = dataArray[i];i++; var collect = dataArray[i];i++; var slot = dataArray[i];i++; var isPlatinum = dataArray[i];i++; var category = dataArray[i]; // Loads the items we're selling into our collection boxes if(playerUsername == username) { loadGEBoxSelling(item + "~" + total + "~" + pricePer + "~" + collect, slot); } // Adds offers to the market table as long as they're not in the excluded users list // Keeps tracks of how many offers exist for each individual type of item and only displays the first (cheapest) five not counting our own items if(total > 0 && MARKET_EXCLUSION_LIST.indexOf(playerUsername) < 0) { if (window.username != playerUsername && MARKET_INCLUSION_LIST.indexOf(playerUsername) < 0) { if (item == lastItem) { if (lastItemCount >= 5) { continue; } else { lastItemCount += 1; } } else { lastItem = item; lastItemCount = 1; } } // Adds any items that made it through the filter to the market table applyToBuyingTable(playerId, playerUsername, item, total, pricePer, slot, isPlatinum, category); } } };; /* Allows you to use "k" in the item price as an assignment for thousands Allows you to use "b" in the item price as an assignment for billions */ var originalSellOnGE = window.sellOnGE; window.sellOnGE = function(amount, pricePer) { pricePer = pricePer.toString().toLowerCase(); pricePer = (pricePer.indexOf("k") >= 0 ? (pricePer.replace("k", "") * 1000).toString() : pricePer.toString()); pricePer = (pricePer.indexOf("b") >= 0 ? (pricePer.replace("b", "") * 1000000000).toString() : pricePer.toString()); originalSellOnGE(amount, pricePer); }; /* --- Chat --- */ /* Hold the original #refreshChat function before any changes are made to it */ var originalRefreshChat = window.refreshChat; /* Make links in chat clickable, not 100% perfect regex pattern but it gets the job done */ function linkify(text) { text = text || ""; var pattern = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; text = text.replace(pattern, "<a href='$1' target='_blank'>$1</a>"); return text; } /* Allows you to click a player's name in chat to autofill "/pm username " in the text box Additionally, highlights your name in chat as red so you can easily find your own messages *********Unused, interferes with other name formatting (mods and such) */ function setClickNameToPM(text) { var indices = [text.indexOf("~"), text.indexOf(" ")]; var iconSplit = text.split("~"); if (iconSplit.length > 1) { var nameSplit = iconSplit[1].split(" "); if (nameSplit.length > 1) { var playerName = nameSplit[0]; console.log(text); console.log(playerName); // Strips additional tags from playernames if (playerName.startsWith("!!!yell")) { playerName = playerName.slice(7); } if (playerName.startsWith("!!!smitty")) { playerName.slice(3); } if (playerName.startsWith("|") || playerName.startsWith("*")) { playerName = playerName.slice(1); } // Adds our new element around playernames, including highlighting for your own name, and autofill PM on click for others var span = ""; if (playerName === window.username) { span = "<span style='color:red;'>" + playerName + "</span>"; } else { span = "<span onclick='\ var node = document.getElementById(\"textbox-chat\");\ if (node) {node.value = \"/pm " + playerName +" \";}'>" + playerName + "</span>"; } text = text.replace(playerName, span); } } return text; } /* Creates a private chat tab in the chatbox, and a new button to toggle it */ function makePrivateChatTab() { // Make the private chat tab var node = document.getElementById("chat-area-div"); if (node) { var newNode = node.cloneNode("false"); newNode.id = "chat-area-pm-div"; newNode.innerHTML = "[PM Mode] Thanks for using Diamond Hunt QoL by WhoIsYou!<br><br>"; newNode.style.display = "none"; var parentNode = node.parentNode; parentNode.insertBefore(newNode, node); } // Make the private chat toggle button var node = document.getElementById("chat-box-area"); var buttons = node.querySelectorAll("[type='button']"); if (buttons.length > 1) { var lastButton = buttons[buttons.length - 2]; var newButton = lastButton.cloneNode(false); newButton.setAttribute("value", "Toggle PM Mode"); newButton.removeAttribute("onclick"); newButton.addEventListener("click", function() { var node1 = document.getElementById("chat-area-div"); var node2 = document.getElementById("chat-area-pm-div"); if (node1 && node2) { node1.style.display == "none" ? node1.style.display = "block" : node1.style.display = "none"; node2.style.display == "none" ? node2.style.display = "block" : node2.style.display = "none"; } }); lastButton.parentNode.insertBefore(newButton, lastButton.nextSibling); } } /* Adds chat private messages to the new PM tab */ function addPmToPmTab(text) { if (text.startsWith("<span style='color:purple'>Private Message from") || text.startsWith("<span style='color:purple'>Sent to")) { var node = document.getElementById("chat-area-pm-div"); if (node) { if (window.showTimestamps === true) { var date = new Date(); var time = "[" + ("00" + date.getHours()).slice(-2) + ":" + ("00" + date.getMinutes()).slice(-2) + "] " text = time + text; } node.innerHTML += text + "<br>"; // Autoscroll the PM tab if (window.isAutoScrolling) { node.scrollTop = node.scrollHeight; } } } } /* Adjusts the PM chatbox height to match the normal chatbox height when the resize buttons are pressed */ var originalChatBoxZoom = window.chatBoxZoom; window.chatBoxZoom = function(zoom) { originalChatBoxZoom(zoom); var node1 = document.getElementById("chat-area-div"); var node2 = document.getElementById("chat-area-pm-div"); if (node1 && node2) { node2.style.height = node1.style.height; } } /* Changes the latest mod-colored text to an orange */ function outputDarkmodeChat() { var modText = document.querySelectorAll("[style='color:" + modChatColor +";']"); if (modText.length > 0) { var node = modText[modText.length - 1]; if (node) { node.style.color = modChatDarkModeColor; } } } /* Add the new functionality to the #refreshChat function, while maintaining the original functionality Adds URL linkification and darkmode output */ window.refreshChat = function(data) { if (spamCheck(data) === true) { // Linkify URLs data = linkify(data); // Add private messages to the private message tab addPmToPmTab(data); // Run the original #refreshChat originalRefreshChat(data); // Change the output to darkmode if darkmode is enabled if (chatboxDarkModeEnabled === true) { outputDarkmodeChat(); } } } /* Spam filter, if it returns false, the message is not rendered in chat */ function spamCheck(messageString) { // If the message isn't from smitty or the server (~ is filtered out serverside so this is fairly safe) if (messageString.indexOf("~!!!") === -1) { var playerName = ""; var message = ""; // Regex pattern, matches the sender's name (matches[1]), and the message (matches[2]); // First pattern is for normal messages, second pattern checks for private messages var matches = messageString.match(/~\*?\|?(.*) \([0-9]+\)\: (.*)/) || messageString.match(/<span style='color:purple'>Private Message from <b>(.*)<\/b>\: (.*)<\/span>/); if (matches !== null && matches.length >= 3) { if (window.username.toLowerCase() == matches[1].toLowerCase()) { // If it's us speaking, we won't spam check to avoid issues and confusion return true; } playerName = matches[1].replace(/ /g, "_"); // Replaces spaces in a player's name with underscores to be variable and report friendly message = matches[2]; // Create a new object within the chatFilter object for the talking player if one doesn't exist, otherwise check for spam if (!chatFilter.hasOwnProperty(playerName)) { chatFilter[playerName] = { filterTime : (new Date()).getTime(), messageCount : 1, lastMessage : message, isReported : false }; } else { // Player is already muted and reported, no additional steps are necessary if (chatFilter[playerName].isReported === true) { return false; } // Get the current time var date = new Date(); var time = date.getTime(); // Reset the filter time and message count if it's been more than 4 seconds since the last timer reset if (time - chatFilter[playerName].filterTime >= 4000) { chatFilter[playerName].filterTime = time; chatFilter[playerName].messageCount = 0; } // Increment the player's message count by 1 chatFilter[playerName].messageCount++; // If they've sent exactly 5 messages in the last 4 seconds, flag them as spam and don't show their message if (chatFilter[playerName].messageCount == 5) { if (chatFilter[playerName].messageCount >= 10) { chatFilter[playerName].isReported = true; } // Reset the timer without resetting message count chatFilter[playerName].filterTime = time; chatFilter[playerName].lastMessage = message; return false; } else if (chatFilter[playerName].messageCount >= 6) { if (chatFilter[playerName].messageCount == 10) { // Another 5 messages (10) have come in within another 4 seconds (8 total), auto-mute them and auto-report them window.sendChat("/mute " + playerName); window.sendChat("/report " + playerName + " [Automated spam report by DHQoL, please PM Wh0IsY0u on reddit if this becomes a problem!]"); chatFilter[playerName].isReported = true; } chatFilter[playerName].lastMessage = message; return false; } // If the message is over 40 characters but does not contain a space, it is likely spam if (message.length >= 40 && message.indexOf(" ") == -1) { chatFilter[playerName].lastMessage = message; return false; } // If the player's current message is the same as their last message then we don't need to see it if (chatFilter[playerName].lastMessage.toLowerCase() === message.toLowerCase()) { chatFilter[playerName].lastMessage = message; return false; } // Sets the player's last message sent to the current message since they've passed all checks chatFilter[playerName].lastMessage = message; } } } return true; } /* Toggles the chatbox between darkmode and normal */ function toggleChatboxColorMode() { if (chatboxDarkModeEnabled === false) { setChatboxDarkMode(); } else if (chatboxDarkModeEnabled === true) { resetChatboxMode(); } } /* Sets the chatbox to "darkmode" */ function setChatboxDarkMode() { var node = document.getElementById("chat-area-div"); var node2 = document.getElementById("chat-area-pm-div"); // DH QoL custom PM tab if (node) { // Set the chatbox background to grey node.style.backgroundColor = "#484848"; // Set the MOTD to black since it is normally grey node.getElementsByTagName("span")[0].style.color = "black"; // Replace ALL existing mod text with our new color var modText = document.getElementsByClassName("chat-tag-mod"); for (var i = 0; i < modText.length; i++) { var parent = modText[i].parentNode; parent.style.color = modChatDarkModeColor; } // Change the darkmode flag to true chatboxDarkModeEnabled = true; GM_setValue("chatboxDarkModeEnabled", true); // Set PM tab to dark mode if (node2) { node2.style.backgroundColor = "#484848"; } } } /* Resets the chatbox to the original mode */ function resetChatboxMode() { var node = document.getElementById("chat-area-div"); var node2 = document.getElementById("chat-area-pm-div"); if (node) { // Remove the custom background color (back to white) node.style.backgroundColor = ""; // Replace ALL existing mod text with the original color var modText = document.getElementsByClassName("chat-tag-mod"); for (var i = 0; i < modText.length; i++) { var parent = modText[i].parentNode; parent.style.color = modChatColor; } // Change the darkmode flag to false chatboxDarkModeEnabled = false; GM_setValue("chatboxDarkModeEnabled", false); // Set PM tab to dark mode if (node2) { node2.style.backgroundColor = ""; } } } /* Creates a button that toggles chatbox darkmode on and off and adds it to the chatbox header */ function createDarkModeToggleButton() { var node = document.getElementById("chat-box-area"); var buttons = node.querySelectorAll("[type='button']"); if (buttons.length > 1) { var lastButton = buttons[buttons.length - 2]; var newButton = lastButton.cloneNode(false); newButton.setAttribute("value", "Toggle Darkmode"); newButton.removeAttribute("onclick"); newButton.addEventListener("click", function() { toggleChatboxColorMode(); }); lastButton.parentNode.insertBefore(newButton, lastButton.nextSibling); } } /* --- Misc --- */ /* Removes the left click to sell item functionality from all brewing-tab items since you'd almost never want to sell these */ function disableBrewingItemSelling() { var brewingTabDoc = document.getElementById("brewing-tab"); if (brewingTabDoc) { var sellableItems = brewingTabDoc.getElementsByClassName("item-box-spot")[0].querySelectorAll("[onclick=\"sellDailog(this.id)\"]"); for (var i = 0; i < sellableItems.length; i++) { sellableItems[i].removeAttribute("onclick"); } } } /* Removes the default right and left click functionality when clicking on your money Left clicking your coins icon will convert up to 2B coins to plat Left clicking your plat icon will convert plat to coins until you're carrying up to 2B */ function improveCoinSwap() { var moneyDocList = document.querySelectorAll("[oncontextmenu=\"send('COINS_TO_PLATINUM='+parseInt(coins/1000000));return false;\"]"); if (moneyDocList.length > 0) { var moneyDoc = moneyDocList[0]; moneyDoc.removeAttribute("oncontextmenu"); moneyDoc.removeAttribute("onclick"); var coinsElement = moneyDoc.childNodes[0]; var platElement = document.getElementById("platinum-coins-status-bar-span").childNodes[0]; coinsElement.onclick = function() { var convert = Math.min(Math.floor(parseInt(window.coins / 1000000)), 2000); if (convert > 0 ) { window.send("COINS_TO_PLATINUM=" + convert); } }; platElement.onclick = function() { var convert = Math.min(parseInt(window.platinumCoins), Math.max(2000 - Math.floor(parseInt(window.coins / 1000000)), 0)); if (convert > 0 ) { window.send("PLATINUM_TO_COINS=" + convert); } } } } /* Allows you to craft more than one rocket fuel at a time if you're above a certain amount of oil, otherwise it crafts just one like normal */ function setCraftMultipleRocketFuel() { var node = document.getElementById("craft-rocketFuel"); var dialogNode = document.getElementById("dialog-craft-multi"); if (node && dialogNode) { var dialogConfirmButton = dialogNode.querySelectorAll("[type='button']")[0]; if (dialogConfirmButton) { // Add the craft multiple dialog to the rocket fuel crafting node.removeAttribute("onclick"); node.addEventListener("click", function() { var requiredOil = (bindedOilRefinery == 0 ? 100000000 : 200000000); if (oil >= requiredOil) { craftMultipleItem("rocketFuel"); } else { craftItem("rocketFuel"); } }); // Craft in a loop since #craftMultiple doesn't allow rocket fuel crafting for some reason dialogConfirmButton.removeAttribute("onclick"); dialogConfirmButton.addEventListener("click", function(){ if (document.getElementById('craft-multiple-item-hidden').value == "rocketFuel") { var amount = document.getElementById('craftMulti-amount-txt').value; var delay = 0; $(this).closest('.ui-dialog-content').dialog('close'); for (var i = 0; i < amount; i++) { setTimeout(function() { if (oil >= 50000000) { craftItem("rocketFuel"); } }, delay); delay += 100; } } else { craftMultiple(document.getElementById('craft-multiple-item-hidden').value, document.getElementById('craftMulti-amount-txt').value);$(this).closest('.ui-dialog-content').dialog('close') } }); } } } /* Removes the ability to left click / bind equal or lower tier furnaces and ovens if you have promethium or higher */ function disableBindFurnacesAndOvens() { var furnaceIds = ["item-stoneFurnace-box", "item-bronzeFurnace-box", "item-ironFurnace-box", "item-silverFurnace-box", "item-goldFurnace-box", "item-ancientFurnace-box", "item-promethiumFurnace-box"]; var ovenIds = ["item-bronzeOven-box", "item-ironOven-box", "item-silverOven-box", "item-goldOven-box", "item-promethiumOven-box", "item-ancientOven-box", "item-runiteOven-box"]; if (window.bindedFurnaceLevel >= 7) { // Remove the option to left click / bind prom or lower furnaces if we have a prom or higher furnace bound for (var i = 0; i < furnaceIds.length; i++) { var node = document.getElementById(furnaceIds[i]); if (node) { node.removeAttribute("onclick"); } } } if (window.bindedPromOven == 1 || window.bindedAncientOven == 1 || window.bindedRuniteOven == 1) { var boundOvenLevel = (window.bindedRuniteOven == 1 ? ovenIds.length : (window.bindedAncientOven == 1 ? ovenIds.length - 1 : ovenIds.length - 2)); for (i = 0; i < boundOvenLevel; i++) { var node = document.getElementById(ovenIds[i]); if (node) { node.removeAttribute("onclick"); } } } } /* Adds the wealth evaluator to the key items (clones the tutorial key item, edits, and appends it) */ function addWealthEvaluator() { var keyItemTabNode = document.getElementById("key-items-tab"); if (keyItemTabNode) { var keyItemTutorialNode = keyItemTabNode.querySelector("[tooltip='Click to read']"); if (keyItemTutorialNode) { var newNode = keyItemTutorialNode.cloneNode(true); newNode.setAttribute("tooltip", "Click me to evaluate your wealth!"); newNode.childNodes[0].id = "key-item-wealth-evaluator"; newNode.childNodes[0].onclick = ""; newNode.childNodes[0].addEventListener("click", function() { evaluateWealth(); }); var boxTitleNode = newNode.childNodes[0].querySelector(".item-box-title"); var boxImageNode = newNode.querySelector("[src]"); boxTitleNode.innerHTML = "Wealth Evaluator"; boxImageNode.src = "images/pic_coin.png"; newNode.childNodes[0].innerHTML = newNode.childNodes[0].innerHTML.replace("Click to Read", ""); // Append the new node to the document keyItemTabNode.appendChild(newNode); } } } /* Evaluates all of your tradable items and gives their total value based on the mininmum market price, maximum market price, and the average of the two Does not account for untradables, your platinum and coins, bound items, equipped items, or items currently listed on the market */ function evaluateWealth() { var networthMin = 0; var networthMax = networthMin; for (var i = 0; i < window.tradableItems.length; i++) { var itemData = window.tradableItems[i].split("~"); var item = itemData[0]; var minPrice = parseFloat(itemData[1]); var maxPrice = parseFloat(itemData[2]); if (window[item]) { networthMin += (window.platinumTradables.indexOf(item) >= 0 ? window[item] * minPrice * 1000000 : window[item] * minPrice); networthMax += (window.platinumTradables.indexOf(item) >= 0 ? window[item] * maxPrice * 1000000 : window[item] * maxPrice); } } window.alert("This is an evaluation of the value of your tradable items.\n\ Items that cannot be traded are not valued.\n\ Bound items, equipped items, coins/plat, and items currently listed on the market place are not valued.\n\n\ Your tradable items at minimum market price are worth: " + networthMin.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') + "\n\ Your tradable items at maximum market price are worth: " + networthMax.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') + "\n\ For an average of: " + ((networthMin + networthMax) / 2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')); } /* --- Timers --- */ /* Format seconds into HH:MM:SS format */ function formatTime(seconds) { var hours = Math.floor(seconds / 3600); var mins = Math.floor((seconds % 3600) / 60); var secs = Math.round(seconds % 60); var hourString = ("00" + hours.toString()).slice(-2) + ":"; var minString = ("00" + mins.toString()).slice(-2) + ":"; var secString = ("00" + secs.toString()).slice(-2); return hourString + minString + secString } /* Roughly calculate the time remaining until the rocket journey completes. Uses averages gathered so it may vary slightly. Rocket info (found from logging) that we need to know Rocket lifts off at a speed of 0-10km/s (averaging 5km/s) until there is about 383401km left in the trip The majority of the trip (~383100-~383125) is traveled at 25-75km/s (averaging 50km/s) At ~275-300km remaining the rocket slows down to 0-10km/s (averagig 5km/s) At ~30km remaining the rocket slows down to a constant 1km/s */ function getRocketTimer() { var totalDistanceRemaining = window.rocketTimer; var liftoffDistanceRemaining = Math.max((totalDistanceRemaining-383401), 0); var mainTravelDistanceRemaining = Math.max((totalDistanceRemaining-liftoffDistanceRemaining-300), 0); var endSlowdownDistanceRemaining = (totalDistanceRemaining > 300) ? 300-30 : Math.max((totalDistanceRemaining-30), 0); var landingDistanceRemaining = (totalDistanceRemaining > 30) ? 30 : totalDistanceRemaining; var averageSecondsRemaining = Math.ceil(liftoffDistanceRemaining/5) + Math.ceil(mainTravelDistanceRemaining/50) + Math.ceil(endSlowdownDistanceRemaining/5) + landingDistanceRemaining; return averageSecondsRemaining; } // Make changes to the document to replace our rocket timer, giving us an estimate time until completion based on average times to travel each kilometer (depending on the distance remaining) function replaceRocketTimer() { document.getElementById("notification-timer-span-rocket").innerHTML = formatTime(getRocketTimer()); } /* Calculates the time left until your furnace is done smelting the current load and formats the time into a string Attempts to more accurately display the time remaining when you have the furnace timer donor perk */ function getfurnaceTimer() { var timeRemaining = (window.furnaceTimer == "1" ? ((window.furnaceTotalTimer * 0.75) - ((window.furnaceCurrentTimer * 0.75))) : window.furnaceTotalTimer - window.furnaceCurrentTimer); return timeRemaining; } // Returns an image path based on the "furnaceBarId" variable (item you're currently smelting) function getProductImageByFurnaceId(id) { switch (window.furnaceBarId) { case "1": return "images/minerals/bronzeBar.png" case "2": return "images/minerals/ironBar.png" case "3": return "images/minerals/silverBar.png" case "4": return "images/minerals/goldBar.png" case "5": return "images/minerals/glass.png" case "6": return "images/minerals/promethiumBar.png" default: return "images/crafting/ironfurnace.gif" } } // Make changes to the document to replace our furnace timer with a new image and a time rather than just a percentage function replaceFurnaceTimer() { var furnaceNode = document.getElementById("furnace-timer"); var imageNode = document.getElementById("furnace-timer").childNodes[1]; var newImagePath = getProductImageByFurnaceId(window.furnaceBarId); if (imageNode.getAttribute("src") != newImagePath) { imageNode.setAttribute("src", newImagePath); } document.getElementById("notification-timer-span-furnace").innerHTML = formatTime(getfurnaceTimer()) + " (" + window.furnacePerc + "%)"; } // Loops through all potions which can have a timer (TIMED_POTION_LIST) and returns an array with timer variable name of those which are currently active function getActivePotionTimers() { var activePotions = []; for (var i = 0; i < TIMED_POTION_LIST.length; i++) { var potionTimer = TIMED_POTION_LIST[i] + "Timer"; if (window[potionTimer] > 0) { activePotions.push(TIMED_POTION_LIST[i]); } } return activePotions; } // Replaces the timers for all active potions with new timers formated as HH:MM:SS function replaceActivePotionTimers(activePotions) { for (var i = 0; i < activePotions.length; i++) { var activePotion = activePotions[i]; document.getElementById("notification-timer-span-" + activePotion).innerHTML = formatTime(window[activePotion + "Timer"]); } } // Loops through all spells which can have a timer (TIMED_SPELL_LIST) and returns an array with timer variable name of those which are currently active function getActiveSpellTimers() { var activeSpells = []; for (var i = 0; i < TIMED_SPELL_LIST.length; i++) { var spellTimer = TIMED_SPELL_LIST[i] + "Timer"; if (window[spellTimer] > 0) { activeSpells.push(TIMED_SPELL_LIST[i]); } } return activeSpells; } // Replaces the timers for all active spells with new timers formated as HH:MM:SS function replaceActiveSpellTimers(activeSpells) { for (var i = 0; i < activeSpells.length; i++) { var activeSpell = activeSpells[i]; document.getElementById("notification-timer-span-" + activeSpell).innerHTML = formatTime(window[activeSpell + "Timer"]); } } // Creates two new notification boxes, one for explorer's potions, and one for artifact potions. These are initially hidden until you have one active. function createNotificationBoxes() { // A little bit of voodoo to get the correct element to edit since it has no ID (smitty pls add ID). // This is prone to breaking fairly easily if any center tags are added or removed in the wrong order, but it's not a difficult fix. var mainGameElement = document.getElementById("main-game"); if (mainGameElement) { var centerElements = mainGameElement.getElementsByTagName("center"); if (centerElements && centerElements.length > 1) { var notificationElement = centerElements[1].getElementsByTagName("div"); if (notificationElement && notificationElement.length > 0) { var doc = notificationElement[0]; if (doc.innerHTML.indexOf("<!-- timer box -->")) { // Backslashes allow you to break lines in JS, neat thing to keep in mind doc.innerHTML += '\ <!-- (DH QOL) Explorer\'s Potion Notification -->\ <span class="notification-timer-box-potion" id="explorersPotion-notification-box" style="display: none;">\ <img width="30px" height="40px" style="vertical-align: middle;padding:5px 0px 5px 0px;" src="images/brewing/explorersPotion.png" title="Explorer\'s Potion">\ <span id="notification-span-explorersPotion"></span>\ </span>\ <!-- (DH QOL) End Notification -->\ \ <!-- (DH QOL) Artifact Potion Notification -->\ <span class="notification-timer-box-potion" id="artifactPotion-notification-box" style="display: none;">\ <img width="30px" height="40px" style="vertical-align: middle;padding:5px 0px 5px 0px;" src="images/brewing/artifactPotion.png" title="Artifact Potion">\ <span id="notification-span-artifactPotion"></span>\ </span>\ <!-- (DH QOL) End Notification -->\ '; } } } } } // Show or hide our custom potion notifications depending on whether or not those potions are active function updateCustomPotionNotification() { var explorerNotificationElement = document.getElementById("explorersPotion-notification-box"); var artifactNotificationElement = document.getElementById("artifactPotion-notification-box"); if (explorerNotificationElement) { if (window.explorersPotionOn > 0) { document.getElementById("notification-span-explorersPotion").innerHTML = window.explorersPotionOn + " Active"; explorerNotificationElement.style.display = "inline-block"; } else { explorerNotificationElement.style.display = "none"; } } if (artifactNotificationElement) { if (window.artifactPotionIsActivated > 0) { document.getElementById("notification-span-artifactPotion").innerHTML = window.artifactPotionIsActivated + " Active"; artifactNotificationElement.style.display = "inline-block"; } else { artifactNotificationElement.style.display = "none"; } } } // Get & format our robot timer function getRobotTimer() { var robotTime = window.robotTimer; var mins = Math.floor(robotTime / 60); var secs = Math.round(robotTime % 60); var minString = ("00" + mins.toString()).slice(-2) + ":"; var secString = ("00" + secs.toString()).slice(-2); return minString + secString } // Make changes to the document to replace our robot timer to be formatted in minutes and seconds rather than just seconds function replaceRobotTimer() { document.getElementById("notification-timer-span-robot").innerHTML = "Returns in " + getRobotTimer(); } // Get & format our fishing boat timer function getFishingBoatTimer() { return formatTime(window.fishingBoatTimer); } // Make changes to the document to replace our fishing boat timer to be formatted in HH:MM:SS rather than the default function replaceFishingBoatTimer() { document.getElementById("notification-timer-span-fishingBoat").innerHTML = getFishingBoatTimer(); } // Get & format our exploring timer, takes donor perk into account function getExploringTimer() { var exploringTime = (window.explorerTimer > 0) ? Math.round(window.exploringTimer * 0.8) : window.exploringTimer; return formatTime(exploringTime) } // Make changes to the document to replace our exploring timer to be formatted in HH:MM:SS rather than the default function replaceExploringTimer() { document.getElementById("notification-timer-span-exploring").innerHTML = getExploringTimer(); } // Get & format our magic cooldown timer function getMagicCooldown() { var mcd = window.magicCoolDown; return formatTime(mcd) } // Make changes to the document to replace our magic cooldown timer to be formatted in HH:MM:SS rather than the default function replaceMagicCooldownTimer() { document.getElementById("notification-timer-span-magicCoolDown").innerHTML = getMagicCooldown(); } // Format the ancient crystal timer in HH:MM:SS function replaceAncientCrystalTimer() { if (window.bindedAncientCrystal > 0 && window.ancientCrystalCooldown > 0) { var node = document.getElementById("ancientCrystalChargesSpan"); if (node) { node.innerHTML = formatTime(window.ancientCrystalCooldown); } } } // Replaces diamondhunt's "loadMiscVariabled()" function with a new one that updates our many timers to be more fancy var oldLoadMiscVariables = window.loadMiscVariables; window.loadMiscVariables = function() { oldLoadMiscVariables(); replaceRocketTimer(); replaceFurnaceTimer(); replaceRobotTimer(); replaceFishingBoatTimer(); replaceExploringTimer(); replaceMagicCooldownTimer(); replaceAncientCrystalTimer(); } // Replaces diamondhunt's "loadPotionTimers()" function with a new one that updates our potion timers to be more fancy // Also adds a notification for explorer's potions and artifact potions (#updateCustomePotionNotifications()) var oldLoadPotionTimers = window.loadPotionTimers; window.loadPotionTimers = function() { oldLoadPotionTimers(); replaceActivePotionTimers(getActivePotionTimers()); updateCustomPotionNotification() } /* Replaces Diamond Hunt's #loadNotifSpells function with a new one that formats our magic timers */ var oldLoadNotifSpells = window.loadNotifSpells; window.loadNotifSpells = function() { oldLoadNotifSpells(); replaceActiveSpellTimers(getActiveSpellTimers()); } // Replace the farming timers with new timers formated in HH:MM:SS, also more accurately estimates the time if you have the Gardener donor perk // Farming has slight RNG to it though, so it may not tick correctly every second function replaceFarmingTimers() { if (window.farmingTimer == 1) { var patchIDs = ["1", "2", "3", "4"]; (window.hasFarmingPatch5) ? patchIDs.push("5") : patchIDs; (window.hasFarmingPatch6) ? patchIDs.push("6") : patchIDs; for (var i = 0; i < patchIDs.length; i++) { var matches = document.getElementById("farming-patch-status-"+patchIDs[i]).innerHTML.match(/>(.* min remaining)/); if (matches != null) { var match = matches.pop(); var timeRemaining = window.gardenerTimer == "0" ? window["farmingPatchTimer"+patchIDs[i]] : Math.round(window["farmingPatchTimer"+patchIDs[i]] * 0.8); document.getElementById("farming-patch-status-"+patchIDs[i]).innerHTML = document.getElementById("farming-patch-status-"+patchIDs[i]).innerHTML.replace(match, formatTime(timeRemaining)); } } } } // Replaces diamondhunt's "refreshFarmingPatch()" function with a new one that updates our farming timers to be more fancy var oldRefreshFarmingPatch = window.refreshFarmingPatch; window.refreshFarmingPatch = function(patchId, seedId, seedName, deadCropImg) { oldRefreshFarmingPatch(patchId, seedId, seedName, deadCropImg); replaceFarmingTimers(); } /* --- Other --- */ /* Set and forget, logging that can be enabled or disabled through config */ function cLog(l) { if (config.ENABLE_LOGGING === true) { var date = new Date(); console.log(("00" + date.getHours()).slice(-2) + ":" + ("00" + date.getMinutes()).slice(-2) + ":" + ("00" + date.getSeconds()).slice(-2) + ": " + l); } }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址