// ==UserScript==
// @name DHM Fixed
// @namespace FileFace
// @version 0.6.2
// @description Improve the desktop experience of Diamond Hunt Mobile
// @author kape142
// @match *.diamondhunt.app/
// @grant none
// ==/UserScript==
/*jshint multistr: true */
/*jslint es5: true */
/*
TODO
Main:
Shortcuts:
More shortcuts
Documentation, either in-game or off site
Fixes:
Set standard values for menus manually, find good standards for this option
option to filter out loot from monsters unless they contain e.g. chests/sword/bow
ActivityLog:
Design work to make it less ugly
Chat/Wiki:
Better UI for showing/hiding
more options
DisableSell:
incorporate into Fixes, with toggles for this and every other fix individually
*/
(function() {
'use strict';
var Program = {};
//Main
Program.Main = {};
Program.Main.toggle = (key) => {
//console.log(key, window.localStorage.getItem(key));
if(window.localStorage.getItem(key) == 1){
window.localStorage.setItem(key, 0);
Program[key].destroy();
return false;
}else{
window.localStorage.setItem(key, 1);
Program[key].init();
return true;
}
}
Program.Main.decamelize = (str, separator) => {
separator = typeof separator === 'undefined' ? '_' : separator;
return str
.replace(/([a-z\d])([A-Z])/g, '$1' + separator + '$2')
.replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + separator + '$2')
.toLowerCase()
.replace(/^\w/, c => c.toUpperCase());
}
Program.Main.showDimmer = (id) => {
let dimmer = document.getElementById("timeMachine-dimmer");
dimmer.style.display = "";
dimmer.style.opacity = "0.7";
dimmer.style.backgroundColor = "black";
window.lastDialogueOpenedIdGlobal = id;
}
Program.Main.showSettingsDialogue = () => {
let buttons = [
Program.Main.createButtonModule("Shortcuts", "images/gold.png", ),
Program.Main.createButtonModule("Fixes", "images/promethium.png"),
Program.Main.createButtonModule("ActivityLog", "images/titanium.png"),
Program.Main.createButtonModule("Chat", "images/silver.png"),
Program.Main.createButtonModule("Wiki", "images/copper.png"),
Program.Main.createButtonModule("DisableSell", "images/iron.png"),
]
let dialogue = Program.Main.createDialogue("DHM Fixed", buttons)
let dp = document.getElementById("dialogue-profile");
let gs = dp.parentNode;
window.closeSmittysDialogue("dialogue-profile")
gs.insertBefore(dialogue, dp);
}
Program.Main.createDialogue = (title, elements, onClose) =>{
let div = document.createElement("div");
let id = `dialogue-${title.split(" ").join("-")}`
div.id = id;
div.className = "smittys-dialogues";
div.style.width = "400px";
div.style.top = "0px";
let center = document.createElement("center");
let h1 = document.createElement("h1");
h1.textContent = title;
center.appendChild(h1);
div.appendChild(center);
div.appendChild(document.createElement("hr"));
for(let i in elements){
div.appendChild(elements[i]);
}
div.appendChild(document.createElement("br"));
div.appendChild(document.createElement("br"));
let input = document.createElement("input");
input.onclick = onClose?onClose:() => document.getElementById(id).remove();
input.type = "button";
input.value = "Close";
input.style.cursor = "pointer";
div.appendChild(input);
return div;
}
Program.Main.createButtonModule = (key, imageURL) => {
let imgId = `img-${key}`;
let callback = () => {document.getElementById(imgId).src = Program.Main.toggle(key)?imageURL:"images/stone.png"};
return Program.Main.createButton(key, (window.localStorage.getItem(key)==1)?imageURL:"images/stone.png", callback);
}
Program.Main.createButton = (key, imageURL, callback) => {
let div = document.createElement("div");
let imgId = `img-${key}`;
div.onclick = callback;
div.className = "main-button";
div.style.cursor = "pointer";
let table = document.createElement("table");
let tbody = document.createElement("tbody");
let tr = document.createElement("tr");
let td1 = document.createElement("td");
let img = document.createElement("img");
img.src = imageURL;
img.className = "img-medium";
img.id = imgId;
td1.appendChild(img);
tr.appendChild(td1);
let td2 = document.createElement("td");
td2.style.textAlign = "right";
td2.style.paddingRight = "20px";
let split = key.split(".");
let name = split[split.length-1]
let textNode = document.createTextNode(name.toUpperCase());
td2.appendChild(textNode);
tr.appendChild(td2);
tbody.appendChild(tr);
table.appendChild(tbody);
div.appendChild(table);
return div;
}
Program.Main.addButtonToSettings = () => {
let div = Program.Main.createButton("DHM FIXED", "images/miningEngineer.png", ()=> Program.Main.showSettingsDialogue());
let parent = document.getElementById("dialogue-profile");
//console.log(parent, div);
parent.insertBefore(div, parent.children[8]);
}
Program.Main.init = () => {
Program.Main.addButtonToSettings();
}
//Chat
Program.Chat = {}
Program.Chat.visible = false;
Program.Chat.addChat = () => {
let div = document.createElement("div");
div.id = "chat";
div.style.width = "98%";
var iframe = document.createElement("iframe");
iframe.src = "https://diamondhunt.app/chat/";
iframe.style.position = "fixed";
iframe.style.top = "0";
iframe.style.right = "0";
iframe.style.width = (window.innerWidth-530)/2+"px";
iframe.style.height = "100%";
iframe.style.display = "none";
div.appendChild(iframe);
let btn = document.createElement("button");
btn.type = "button";
btn.id = "chatBtn";
btn.style.position = "fixed";
btn.style.right = ((window.innerWidth-530)/2)-50+"px";
btn.style.width = "50px";
btn.style.top = "4px";
btn.addEventListener("click", ()=>{
document.getElementById("chat").firstElementChild.style.display = Program.Chat.visible?"none":"";
Program.Chat.visible = !Program.Chat.visible;
});
let text = document.createTextNode("chat");
btn.appendChild(text);
div.appendChild(btn);
document.body.appendChild(div);
}
Program.Chat.windowListener = () => {
document.getElementById("chat").firstElementChild.style.width = (window.innerWidth-530)/2+"px";
document.getElementById("chatBtn").style.right = ((window.innerWidth-530)/2)-50+"px";
}
Program.Chat.init = ()=>{
Program.Chat.addChat();
window.addEventListener("resize", Program.Chat.windowListener);
}
Program.Chat.destroy = ()=>{
document.getElementById("chat").remove();
window.removeEventListener("resize", Program.Chat.windowListener);
}
//Wiki
Program.Wiki = {}
Program.Wiki.visible = false;
Program.Wiki.addWiki = () => {
let div = document.createElement("div");
div.id = "wiki";
div.style.width = "98%";
var iframe = document.createElement("iframe");
iframe.src = "https://diamondhuntmobile.fandom.com/wiki/Diamond_Hunt_Mobile_Wiki";
iframe.style.position = "fixed";
iframe.style.top = "0";
iframe.style.left = "0";
iframe.style.width = (window.innerWidth-530)/2+"px";
iframe.style.height = "100%";
iframe.style.display = "none";
div.appendChild(iframe);
let btn = document.createElement("button");
btn.type = "button";
btn.id = "wikiBtn";
btn.style.position = "fixed";
btn.style.left = ((window.innerWidth-530)/2)-50+"px";
btn.style.width = "50px";
btn.style.top = "4px";
btn.addEventListener("click", ()=>{
document.getElementById("wiki").firstElementChild.style.display = Program.Wiki.visible?"none":"";
Program.Wiki.visible = !Program.Wiki.visible;
});
let text = document.createTextNode("wiki");
btn.appendChild(text);
div.appendChild(btn);
document.body.appendChild(div);
}
Program.Wiki.windowListener = () => {
document.getElementById("wiki").firstElementChild.style.width = (window.innerWidth-530)/2+"px";
document.getElementById("wikiBtn").style.left = ((window.innerWidth-530)/2)-50+"px";
}
Program.Wiki.init = ()=>{
Program.Wiki.addWiki();
window.addEventListener("resize", Program.Wiki.windowListener);
}
Program.Wiki.destroy = ()=>{
document.getElementById("wiki").remove();
window.removeEventListener("resize", Program.Wiki.windowListener);
}
//ActivityLog
Program.ActivityLog = {}
Program.ActivityLog.visible = false;
Program.ActivityLog.saveHistory = (data) => {
if(!localStorage.getItem("ActivityLog")){
return;
}
let historyString = localStorage.getItem("ActivityLog.history."+window.username)
if(!historyString){
historyString = "[]";
}
let history = JSON.parse(historyString);
history.push(data);
if(history.length > 200){
history = history.slice(100,history.length);
}
localStorage.setItem("ActivityLog.history."+window.username, JSON.stringify(history));
let div = Program.ActivityLog.dataToDiv(data);
let parent = document.getElementById("dialogue-Activity-Log");
let first = parent.children[2];
parent.insertBefore(div,first);
return data;
}
Program.ActivityLog.dataToDiv = (data) => {
let array = data.split("~");
if(array.length<4){
return document.createElement("div");
}
let title = array[0];
let items = [];
for(let i = 1; i < array.length; i+=4){
items.push({
name: array[i],
amount: array[i+1],
backgroundColor: array[i+2],
borderColor: array[i+3]
});
}
let div = document.createElement("div");
div.style.color = "black";
div.style.border = "solid grey 1px";
div.style.backgroundColor = "white";
div.style.margin = "10px";
let h1 = document.createElement("h1");
h1.style.textAlign = "center";
h1.textContent = title;
div.appendChild(h1);
for(let key in items){
let item = items[key];
let span = document.createElement("span");
span.className = "loot-span";
span.style.backgroundColor = item.backgroundColor;
span.style.border = `1px solid ${item.borderColor}`;
let img = document.createElement("img");
img.className = "img-small-medium";
img.src = `images/${item.name}.png`;
let decamName = Program.Main.decamelize(item.name," ")
img.alt = decamName;
img.title = decamName;
span.appendChild(img);
let text = document.createTextNode(item.amount);
span.appendChild(text);
div.appendChild(span);
}
return div;
}
Program.ActivityLog.toggleLog = (event) => {
if(event.keyCode == 9 &&
!event.altKey &&
!event.ctrlKey &&
window.username){
event.preventDefault();
if(Program.ActivityLog.visible){
Program.ActivityLog.hideLog()
}else{
Program.ActivityLog.showLog();
}
}
}
Program.ActivityLog.createLog = () => {
let history = JSON.parse(localStorage.getItem("ActivityLog.history."+window.username));
if(!history){
history = [];
}
let elements = [];
for(let i = history.length-1; i >= 0; i--){
elements.push(Program.ActivityLog.dataToDiv(history[i]))
}
let dialogue = Program.Main.createDialogue("Activity Log", elements, Program.ActivityLog.hideLog);
dialogue.style.display = "none";
Program.ActivityLog.dialogueId = dialogue.id;
Program.ActivityLog.visible = false;
let dp = document.getElementById("dialogue-profile");
let gs = dp.parentNode;
gs.insertBefore(dialogue, dp);
}
Program.ActivityLog.showLog = () => {
Program.ActivityLog.visible = true;
Program.Main.showDimmer(Program.ActivityLog.dialogueId);
document.getElementById(Program.ActivityLog.dialogueId).style.display = "";
}
Program.ActivityLog.hideLog = () => {
Program.ActivityLog.visible = false;
document.getElementById("timeMachine-dimmer").style.display = "none";
document.getElementById(Program.ActivityLog.dialogueId).style.display = "none";
}
Program.ActivityLog.init = () => {
Program.WindowExtensions.add("lootDialogue", Program.ActivityLog.saveHistory);
const func = () => {
if(window.username){
//console.log("ok");
Program.ActivityLog.createLog();
}else{
//console.log("waiting");
setTimeout(func,1000);
}
}
func();
Program.WindowExtensions.add("closeSmittysDialogueGlobal",()=>{
if(window.lastDialogueOpenedIdGlobal == Program.ActivityLog.dialogueId){
Program.ActivityLog.visible = !Program.ActivityLog.visible;
}
Program.WindowExtensions._functions.closeSmittysDialogueGlobal();
});
document.addEventListener("keydown", Program.ActivityLog.toggleLog);
}
Program.ActivityLog.destroy = () => {
document.removeEventListener("keydown", Program.ActivityLog.toggleLog);
document.getElementById(Program.ActivityLog.dialogueId).remove();
}
//Fixes
Program.Fixes = {}
Program.Fixes.firstInit = true;
Program.Fixes.filterLootDialogue = (data) => {
if(localStorage.getItem("Fixes")==1){
let parts = data.split("~");
if(parts[0]=="Harvest All" || parts[0] == "Chop All"){
throw `Ignored loot dialogue: ${parts[0]}`;
}
}
return data;
}
Program.Fixes.init = ()=>{
Program.WindowExtensions.add("lootDialogue", Program.Fixes.filterLootDialogue);
}
Program.Fixes.destroy = ()=>{
}
//Shortcuts
Program.Shortcuts = {}
Program.Shortcuts.functions = [];
Program.Shortcuts.keyheld = [];
Program.Shortcuts.firstInit = true;
Program.Shortcuts.keyup = (event)=>{
Program.Shortcuts.keyheld[event.keyCode] = false;
return false;
};
Program.Shortcuts.keydown = (event)=>{
//console.log(String.fromCharCode(event.keyCode));
if(!Program.Shortcuts.keyheld[event.keyCode] &&
Program.Shortcuts.functions[event.keyCode] &&
document.getElementById("dialogue-tradingPost-tradeRequest").style.display=="none" &&
!event.ctrlKey &&
window.username){
if(Program.Shortcuts.functions[event.keyCode]()){
//console.log("ok");
event.preventDefault();
Program.Shortcuts.keyheld[event.keyCode] = true;
}
}
return false;
};
Program.Shortcuts.add = (letter, func) => {
let code = letter.charCodeAt(0);
if(Program.Shortcuts.functions[code]){
let _func = Program.Shortcuts.functions[code];
Program.Shortcuts.functions[code] = ()=>{return _func() || func()};
}else{
Program.Shortcuts.functions[code] = func;
}
}
Program.Shortcuts.init = ()=>{
document.addEventListener("keyup", Program.Shortcuts.keyup);
document.addEventListener("keydown", Program.Shortcuts.keydown);
if(Program.Shortcuts.firstInit){
Program.Shortcuts.firstInit = false;
Program.Shortcuts.add("M", ()=>{
window.navigate('mining');
return true;
});
Program.Shortcuts.add("C", ()=>{
if(document.getElementById("tab-crafting").style.display != "none"){
window.setCraftList('default');
window.navigate('craftingItems');
return true;
}
window.navigate('crafting');
return true;
});
Program.Shortcuts.add("W", ()=>{
window.navigate('woodcutting');
return true;
});
Program.Shortcuts.add("F", ()=>{
window.navigate('farming');
return true;
});
Program.Shortcuts.add("B", ()=>{
if(document.getElementById("dialogue-furnace1").style.display != "none"){
window.chooseOreForFurnace('copper');
window.closeSmittysDialogue('dialogue-furnace1');
return true;
}
window.navigate('brewing')
return true;
});
Program.Shortcuts.add("E", ()=>{
if(document.getElementById("tab-exploring").style.display != "none"){
window.navigate('explore');
return true;
}
window.navigate('exploring');
return true;
});
Program.Shortcuts.add("O", ()=>{
if(document.getElementById("dialogue-bob").style.display != "none"){
window.sendBytes('HARVEST_ALL');
window.closeSmittysDialogueGlobal();
return true;
}
if(document.getElementById("tab-cooking").style.display != "none"){
if(window.goldOven == 1){
window.clicksItem('goldOven');
}else if(window.silverOven == 1){
window.clicksItem('silverOven');
}else if(window.ironOven == 1){
window.clicksItem('ironOven');
}else if(window.bronzeOven == 1){
window.clicksItem('bronzeOven');
}else{
return false;
}
return true;
}
window.navigate('cooking');
return true;
});
Program.Shortcuts.add(" ", ()=>{
if(document.getElementById("dialogue-confirm").style.display != "none"){
document.getElementById("dialogue-confirm-yes").click();
return true;
}
if(document.getElementById("tab-explore").style.display != "none"){
document.getElementById("exploring-area-button").click();
document.getElementById("dialogue-confirm-no").blur();
return true;
}
if(document.getElementById("dialogue-exploring-openloot").style.display != "none"){
document.getElementById("open-one-loot-button").click();
return true;
}
if(document.getElementById("tab-craftingAnItem").style.display != "none"){
document.getElementById("tab-craftingAnItem").children[1].children[3].firstElementChild.click();
return true;
}
});
Program.Shortcuts.add("D", ()=>{
if(document.getElementById("dialogue-bob").style.display != "none"){
window.setBobsAutoReplantSeed("dottedGreenLeafSeeds")
return true;
}
if(document.getElementById("tab-farming").style.display != "none"){
window.clicksItem('dottedGreenLeafSeeds');
return true;
}
if(document.getElementById("tab-explore").style.display != "none"){
window.loadNextExploringArea();
return true;
}
});
Program.Shortcuts.add("A", ()=>{
if(document.getElementById("tab-explore").style.display != "none"){
window.loadPreviousExploringArea();
return true;
}
});
Program.Shortcuts.add("S", ()=>{
if(document.getElementById("dialogue-sellItem").style.display != "none"){
window.sendWidgetSellToServer();
window.closeSmittysDialogue('dialogue-sellItem');
return true;
}
if(document.getElementById("dialogue-convertArtifact").style.display != "none"){
window.sendBytes(window.amountWidgetGetCommand());
window.closeSmittysDialogue('dialogue-convertArtifact');
return true;
}
if(document.getElementById("dialogue-furnace2").style.display != "none"){
window.startSmelting();
window.closeSmittysDialogue('dialogue-furnace2');
return true;
}
if(document.getElementById("dialogue-furnace1").style.display != "none"){
window.chooseOreForFurnace('silver');
window.closeSmittysDialogue('dialogue-furnace1');
return true;
}
if(document.getElementById("dialogue-cook").style.display != "none"){
window.sendBytes(window.amountWidgetGetCommand());
window.closeSmittysDialogue('dialogue-cook');
return true;
}
if(document.getElementById("dialogue-oven2").style.display != "none"){
window.sendBytes(window.amountWidgetGetCommand());
window.closeSmittysDialogue('dialogue-oven2');
return true;
}
if(document.getElementById("dialogue-eat").style.display != "none"){
window.sendBytes(window.amountWidgetGetCommand());
window.closeSmittysDialogue('dialogue-eat');
return true;
}
if(document.getElementById("tab-crafting").style.display != "none"){
if(window.goldFurnace == 1){
window.clicksItem('goldFurnace');
}else if(window.silverFurnace == 1){
window.clicksItem('silverFurnace');
}else if(window.ironFurnace == 1){
window.clicksItem('ironFurnace');
}else if(window.bronzeFurnace == 1){
window.clicksItem('bronzeFurnace');
}else if(window.stoneFurnace == 1){
window.clicksItem('stoneFurnace');
}else{
return false;
}
return true;
}
if(document.getElementById("tab-woodcutting").style.display != "none"){
window.clicksItem('lumberjack');
return true;
}
if(document.getElementById("tab-exploring").style.display != "none"){
window.lookForFight();
return true;
}
if(document.getElementById("tab-craftingItems").style.display != "none"){
document.getElementById("item-section-crafting-3").firstElementChild.click();
return true;
}
});
Program.Shortcuts.add("L", ()=>{
if(document.getElementById("dialogue-bob").style.display != "none"){
window.setBobsAutoReplantSeed("limeLeafSeeds")
return true;
}
if(document.getElementById("tab-farming").style.display != "none"){
window.clicksItem('limeLeafSeeds');
return true;
}
});
Program.Shortcuts.add("I", ()=>{
if(document.getElementById("dialogue-furnace1").style.display != "none"){
window.chooseOreForFurnace('iron');
window.closeSmittysDialogue('dialogue-furnace1');
return true;
}
});
Program.Shortcuts.add("G", ()=>{
if(document.getElementById("dialogue-bob").style.display != "none"){
window.setBobsAutoReplantSeed("greenLeafSeeds")
return true;
}
if(document.getElementById("dialogue-furnace1").style.display != "none"){
window.chooseOreForFurnace('gold');
window.closeSmittysDialogue('dialogue-furnace1');
return true;
}
if(document.getElementById("tab-farming").style.display != "none"){
window.clicksItem('greenLeafSeeds');
return true;
}
});
Program.Shortcuts.add("H", ()=>{
if(document.getElementById("dialogue-confirm").style.display != "none" &&
document.getElementById("dialogue-confirm-text").firstElementChild.children[2].textContent == "Your farming patch automatically grows."){
document.getElementById("dialogue-confirm-yes").click();
return true;
}
if(document.getElementById("dialogue-bob").style.display != "none"){
window.sendBytes('HARVEST_AND_PLANT_ALL');
window.closeSmittysDialogueGlobal();
return true;
}
if(document.getElementById("tab-farming").style.display != "none"){
window.clicksItem('farmer');
return true;
}
});
for(let i = 1; i <=9;i++){
Program.Shortcuts.add(""+i, ()=>{
if(document.getElementById("tab-farmingPlant").style.display != "none"){
window.sendBytes('PLANT='+window.selectedSeedToPlantGlobal+'~'+i);
return true;
}
if(document.getElementById("dialogue-oven1").style.display != "none"){
document.getElementById("dialogue-oven1").children[i-1].firstElementChild.firstElementChild.firstElementChild.click();
return true;
}
});
}
Program.Shortcuts.add("R", ()=>{
if(document.getElementById("dialogue-bob").style.display != "none"){
window.setBobsAutoReplantSeed("redMushroomSeeds")
return true;
}
if(document.getElementById("tab-farming").style.display != "none"){
window.clicksItem('redMushroomSeeds');
return true;
}
if(document.getElementById("tab-woodcutting").style.display != "none"){
window.clicksItem('treeRoots');
return true;
}
});
}
}
Program.Shortcuts.destroy = ()=>{
document.removeEventListener("keyup", Program.Shortcuts.keyup);
document.removeEventListener("keydown", Program.Shortcuts.keydown);
}
Program.DisableSell = ()=>{}
Program.DisableSell.filter = (data) => {
if(localStorage.getItem("DisableSell")){
throw `Selling items to NPCs is disabled, not selling ${data}`
}
}
Program.DisableSell.init = () => {
Program.WindowExtensions.add("openSellDialogue", Program.DisableSell.filter);
}
Program.DisableSell.destroy = () => {}
//WindowExtensions
Program.WindowExtensions = {}
Program.WindowExtensions.functions = {}
Program.WindowExtensions._functions = {}
Program.WindowExtensions.add = (key, func) => {
if(Program.WindowExtensions.functions[key]){
let _func = Program.WindowExtensions.functions[key];
Program.WindowExtensions.functions[key] = (data)=>{return func(_func(data))};
}else{
Program.WindowExtensions.functions[key] = func;
}
}
Program.WindowExtensions.init = () => {
for(let key in Program.WindowExtensions.functions){
Program.WindowExtensions._functions[key] = window[key];
window[key] = (data) => {
try{
Program.WindowExtensions._functions[key](Program.WindowExtensions.functions[key](data));
} catch(err) {
console.log(err);
}
}
}
}
//init
for(let key in Program){
let stored = window.localStorage.getItem(key);
if(stored == 1){
Program[key].init();
console.log(`Module ${key} initiated`);
}else if(stored == 0){
console.log(`Module ${key} not initiated, toggled off`);
}else{
window.localStorage.setItem(key, 1);
Program[key].init();
console.log(`Module ${key} initiated, first time`);
}
}
})();