DH2 Fixed

Improve Diamond Hunt 2

目前為 2017-02-24 提交的版本,檢視 最新版本

// ==UserScript==
// @name         DH2 Fixed
// @namespace    FileFace
// @description  Improve Diamond Hunt 2
// @version      0.4.0
// @author       Zorbing
// @grant        none
// @run-at       document-start
// @include      http://www.diamondhunt.co/game.php
// ==/UserScript==

(function ()
{
'use strict';

let styleElement = null;
function addStyle(styleCode)
{
	if (styleElement === null)
	{
		styleElement = document.createElement('style');
		document.head.appendChild(styleElement);
	}
	styleElement.innerHTML += styleCode;
}



/**
 * observer
 */

let observedKeys = new Map();
/**
 * Observes the given key for change
 * 
 * @param {string} key	The name of the variable
 * @param {Function} fn	The function which is called on change
 */
function observe(key, fn)
{
	if (key instanceof Array)
	{
		for (let k of key)
		{
			observe(k, fn);
		}
	}
	else
	{
		if (!observedKeys.has(key))
		{
			observedKeys.set(key, new Set());
		}
		observedKeys.get(key).add(fn);
	}
	return fn;
}
function unobserve(key, fn)
{
	if (key instanceof Array)
	{
		let ret = [];
		for (let k of key)
		{
			ret.push(unobserve(k, fn));
		}
		return ret;
	}
	if (!observedKeys.has(key))
	{
		return false;
	}
	return observedKeys.get(key).delete(fn);
}
function updateValue(key, newValue)
{
	const oldValue = window[key];
	window[key] = newValue;
	if (oldValue !== newValue)
	{
		(observedKeys.get(key) || []).forEach(fn => fn(key, oldValue, newValue));
	}
}



const furnaceLevels = ['stone', 'bronze', 'iron', 'silver', 'gold'];
const oilStorageLevelNum = 7;
function hideFurnaceRecipes(init)
{
	const keys2Observe = [];
	let maxFurnaceLevel = 0;
	for (let i = furnaceLevels.length-1; i >= 0; i--)
	{
		const level = i+1;
		const varName = furnaceLevels[i] + 'Furnace';
		const boundVarName = 'bound' + varName[0].toUpperCase() + varName.substr(1);
		keys2Observe.push(varName);
		keys2Observe.push(boundVarName);
		if (window[varName] > 0 || window[boundVarName])
		{
			maxFurnaceLevel = Math.max(maxFurnaceLevel, level);
		}

		const hide = level <= maxFurnaceLevel;
		const recipeRow = document.getElementById('crafting-' + varName);
		if (recipeRow)
		{
			recipeRow.style.display = hide ? 'none' : '';
		}
	}

	if (init)
	{
		observe(keys2Observe, () => hideFurnaceRecipes(false));
	}
}
function hideOilStorageRecipes(init)
{
	const keys2Observe = [];
	let maxOilStorageLevel = 0;
	for (let i = oilStorageLevelNum-1; i >= 0; i--)
	{
		const level = i+1;
		const varName = 'oilStorage' + level;
		const boundVarName = 'boundOilStorage' + level;
		keys2Observe.push(varName);
		keys2Observe.push(boundVarName);
		if (window[varName] > 0 || window[boundVarName])
		{
			maxOilStorageLevel = Math.max(maxOilStorageLevel, level);
		}

		const hide = level <= maxOilStorageLevel;
		const recipeRow = document.getElementById('crafting-' + varName);
		if (recipeRow)
		{
			recipeRow.style.display = hide ? 'none' : '';
		}
	}

	if (init)
	{
		observe(keys2Observe, () => hideOilStorageRecipes(false));
	}
}
function hideCraftedRecipes()
{
	hideFurnaceRecipes(true);
	hideOilStorageRecipes(true);

	const oldProcessCraftingTab = window.processCraftingTab;
	window.processCraftingTab = () =>
	{
		const reinit = !!window.refreshLoadCraftingTable;
		oldProcessCraftingTab();

		if (reinit)
		{
			hideFurnaceRecipes(false);
			hideOilStorageRecipes(false);
		}
	};
}



/**
 * fix wood cutting
 */

function fixWoodcutting()
{
	addStyle(`
img.woodcutting-tree-img
{
	border: 1px solid transparent;
}
	`);
}



/**
 * init
 */

function init()
{
	hideCraftedRecipes();
	fixWoodcutting();
}
document.addEventListener('DOMContentLoaded', () =>
{
	const oldDoCommand = window.doCommand;
	window.doCommand = (data) =>
	{
		if (data.startsWith('REFRESH_ITEMS='))
		{
			const itemDataValues = data.split('=')[1].split(';');
			const itemArray = [];
			for (var i = 0; i < itemDataValues.length; i++)
			{
				const [key, newValue] = itemDataValues[i].split('~');
				itemArray.push(key);
				updateValue(key, newValue);
			}

			window.refreshItemValues(itemArray, false);

			if (window.firstLoadGame)
			{
				window.loadInitial();
				window.firstLoadGame = false;
				init();
			}
			else
			{
				window.clientGameLoop();
			}
			return;
		}
		return oldDoCommand(data);
	};
});



/**
 * fix web socket errors
 */

function webSocketLoaded(event)
{
	if (window.webSocket == null)
	{
		console.error('no webSocket instance found!');
		return;
	}

	const messageQueue = [];
	const oldOnMessage = webSocket.onmessage;
	webSocket.onmessage = (event) => messageQueue.push(event);
	document.addEventListener('DOMContentLoaded', () =>
	{
		messageQueue.forEach(event => onMessage(event));
		webSocket.onmessage = oldOnMessage;
	});

	const commandQueue = [];
	const oldSendBytes = window.sendBytes;
	window.sendBytes = (command) => commandQueue.push(command);
	const oldOnOpen = webSocket.onopen;
	webSocket.onopen = (event) =>
	{
		window.sendBytes = oldSendBytes;
		commandQueue.forEach(command => window.sendBytes(command));
		return oldOnOpen(event);
	};
}
function isWebSocketScript(script)
{
	return script.src.includes('socket.js');
}
function fixWebSocketScript()
{
	if (!document.head)
	{
		return;
	}

	const scripts = document.head.querySelectorAll('script');
	let found = false;
	for (let i = 0; i < scripts.length; i++)
	{
		if (isWebSocketScript(scripts[i]))
		{
			// does this work?
			scripts[i].onload = webSocketLoaded;
			return;
		}
	}

	// create an observer instance
	const mutationObserver = new MutationObserver((mutationList) =>
	{
		mutationList.forEach((mutation) =>
		{
			if (mutation.addedNodes.length === 0)
			{
				return;
			}

			for (let i = 0; i < mutation.addedNodes.length; i++)
			{
				const node = mutation.addedNodes[i];
				if (node.tagName == 'SCRIPT' && isWebSocketScript(node))
				{
					mutationObserver.disconnect();
					node.onload = webSocketLoaded;
					return;
				}
			}
		});
	});
	mutationObserver.observe(document.head, {
		childList: true
	});
}
fixWebSocketScript();
})();