dailyhwm / AuctionPricePerBattle

// ==UserScript==
// @name AuctionPricePerBattle
// @namespace Price Per Battle
// @version 1.1.2
// @description Отображение ЦЗБ на рынке.
// @homepage https://greasyfork.org/ru/scripts/447481
// @author Tags
// @include /^https{0,1}:\/\/(www\.heroeswm\.ru|178\.248\.235\.15|my\.lordswm\.com)\/(auction.php\?*)/
// @require https://greasyfork.org/scripts/447488-hwm-resources/code/HWM_Resources.js?version=1154149
// @icon https://www.google.com/s2/favicons?sz=64&domain=heroeswm.ru
// @grant GM_addStyle
// @grant GM_deleteValue
// @grant GM_getValue
// @grant GM_listValues
// @license MIT
// ==/UserScript==
GM_addStyle(`.APPB-input {
  width: 52px;
}`);

async function GetItemJSON(itemLink) {
	let response = await fetch(`${itemLink}`)
	var buffer= await response.arrayBuffer();

	let decoder = new TextDecoder("windows-1251");
	var data = decoder.decode(buffer);

	//console.log(`fetch ${itemLink}`);
	//let data = await response.text();

	let LoadedData = new DOMParser().parseFromString(data, "text/html");


	let repair_price = parseInt(Array.from(LoadedData.querySelectorAll("table[cellspacing=\"0\"]")).pop().innerText.replaceAll(",",""));
	//console.log(`repair_price ${repair_price}`)

	var bold = Array.from(LoadedData.querySelectorAll('b'));
	//console.log(`bold ${bold}`)
	let baseDurability = parseInt(bold.find(el => { return el.textContent == 'Прочность:' || el.textContent == ' Прочность:'}).nextSibling.textContent.trim())
	let requredLevel = parseInt(bold.find(el => {return el.textContent == 'Требуемый уровень:'|| el.textContent == ' Требуемый уровень:'}).nextSibling.textContent.trim())
	let isSet = Array.from(LoadedData.querySelectorAll('font')).find(el => el.innerHTML.indexOf(`Составляющая часть комплекта`) !== -1||el.innerHTML.indexOf(`Один из артефактов комплекта`) !== -1||el.innerHTML.indexOf(`Подходит, как составляющая часть, к любому комплекту:`) !== -1).length!==0;
	let setName = Array.from(LoadedData.querySelectorAll('font')).find(el => el.innerHTML.indexOf(`Составляющая часть комплекта`) !== -1||el.innerHTML.indexOf(`Один из артефактов комплекта`) !== -1||el.innerHTML.indexOf(`Подходит, как составляющая часть, к любому комплекту:`) !== -1).childNodes[1].innerText;
	let isHunter = setName==="\"Великий охотник\""||setName==="\"Зверобой\""||setName==="\"Охотник\""||setName==="\"Охотник мастер\""||setName==="\"Охотника\"";
	let isShopItem = Array.from(LoadedData.querySelectorAll('div')).filter(el => el.textContent === 'В магазин').length>0;

	let attr_attack= 0; //значение атаки
	let attr_defense= 0; //значение защиты
	let attr_magicpower= 0; //значение силы магии
	let attr_knowledge= 0; //значение знаний
	let attr_initiative= 0; //значение инициативы
	let attr_fortune= 0; //значение удачи
	let attr_morale= 0; //значение морали

	let attr_oa = parseInt(Array.from(LoadedData.querySelectorAll('b')).find(el => el.textContent === ' Очки амуниции:' ||el.textContent === 'Очки амуниции:').nextSibling.textContent.trim());
	LoadedData.querySelectorAll(`[title="Защита"]`).forEach(function(item) {attr_defense =parseInt(item.parentNode.nextSibling.innerText)});
	LoadedData.querySelectorAll(`[title="Инициатива"]`).forEach(function(item) {attr_initiative =parseInt(item.parentNode.nextSibling.innerText)});
	LoadedData.querySelectorAll(`[title="Удача"]`).forEach(function(item) {attr_fortune =parseInt(item.parentNode.nextSibling.innerText)});
	LoadedData.querySelectorAll(`[title="Боевой дух"]`).forEach(function(item) {attr_morale =parseInt(item.parentNode.nextSibling.innerText)});
	LoadedData.querySelectorAll(`[title="Нападение"]`).forEach(function(item) {attr_attack =parseInt(item.parentNode.nextSibling.innerText)});
	LoadedData.querySelectorAll(`[title="Сила магии"]`).forEach(function(item) {attr_magicpower =parseInt(item.parentNode.nextSibling.innerText)});
	LoadedData.querySelectorAll(`[title="Знания"]`).forEach(function(item) {attr_knowledge =parseInt(item.parentNode.nextSibling.innerText)});


	return  {
		stats: { //параметры
			attr_attack: attr_attack, //значение атаки
			attr_defense: attr_defense, //значение защиты
			attr_magicpower: attr_magicpower, //значение силы магии
			attr_knowledge: attr_knowledge, //значение знаний
			attr_initiative: attr_initiative, //значение инициативы
			attr_fortune: attr_fortune, //значение удачи
			attr_morale: attr_morale, //значение морали
			attr_oa: attr_oa, //значение очков аммуниции
			additional_stats:["параметр_1","параметр_2"] //дополнительные эффекты
		},
		required_level: requredLevel, //требуемый уррвень
		base_durability: baseDurability, //базовая прочность
		repair_price: repair_price, //цена ремонта
		is_hunting_item: isHunter, //добывается ли предмет на охоте
		is_event_item: false, //ивентовый предмет
		is_set_part: isSet, //часть сета
		is_shop_item: isShopItem, //предмет из магазина
		is_shop_status:false, //предмет со статусом "из магазина"
		shop_price: 0, //цена в магазине
	};

};

(function() {
	'use strict';

	const GM_getValue = function(key, def) {
		//console.log(localStorage[key])
		return localStorage[key] || def;
	};
	const GM_setValue = function(key, value) {
		return (localStorage[key] = value);
	};
	const GM_deleteValue = function(key) {
		return delete localStorage[key];
	};

	const GM_addStyle = function(key) {
		let style = document.createElement('style');
		style.textContent = key;
		document.querySelector("head").appendChild(style);
	}

	if (typeof GM_listValues === 'undefined') {
		const GM_listValues = function() {
			const values = [];
			for (let i = 0; i < localStorage.length; i++) {
				values.push(localStorage.key(i));
			}
			return values;
		}
	}

	const repairPriceCoeffDiv = document.createElement("div");
	repairPriceCoeffDiv.appendChild(Object.assign(
		document.createTextNode("Цена ремонта\t"), {

		}));
	document.forms.sel.appendChild(repairPriceCoeffDiv);

	repairPriceCoeffDiv.appendChild(Object.assign(
		document.createElement("input"), {
			type: `number`,
			value: GM_getValue("repairPriceCoeff",101),
			min: "0",
			max: "200",
			className: "APPB-input",
			name:"repairPriceCoeff",
			onchange:function(e){GM_setValue("repairPriceCoeff",e.target.value); Recalc();},
			onkeyup:function(e){GM_setValue("repairPriceCoeff",e.target.value); Recalc();}

		}));
	repairPriceCoeffDiv.appendChild(Object.assign(
		document.createTextNode("%"), {

		}));

	const repairPercentDiv = document.createElement("div");

	repairPercentDiv.appendChild(Object.assign(
		document.createTextNode("Ремонт\t"), {

		}));
	repairPercentDiv.appendChild(Object.assign(
		document.createElement("input"), {
			type: `number`,
			value: GM_getValue("repairPercentage",90),
			min: "0",
			max: "90",
			step:"10",
			className: "APPB-input",
			name:"repairPercentage",
			onchange:function(e){GM_setValue("repairPercentage",e.target.value); Recalc();},
			onkeyup:function(e){GM_setValue("repairPercentage",e.target.value); Recalc();}
		}));
	repairPercentDiv.appendChild(Object.assign(
		document.createTextNode("%"), {

		}));

	document.forms.sel.appendChild(repairPercentDiv);

	function Recalc(){
		const itemNodes = document.querySelector(".wbwhite").querySelectorAll(".wb");
		const repairPriceCoeff = parseFloat (document.forms.sel.repairPriceCoeff.value/100);
		const repairPercentage = parseFloat (document.forms.sel.repairPercentage.value/100);

		for (let item of itemNodes) {

			let removable = item.querySelectorAll("[valign=top] .removable");
			for(let r of removable){
				r.remove();
			}
			const price = parseInt(item.querySelector("[align=left]").children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].innerText.replaceAll(",", ""));

			const nameContainer = item.querySelector("a[href][name]");
			if(!nameContainer){
				continue;
			}
			const itemName = item.querySelector("a[href][name]").name;


			/* item.onclick = async function(e){
				let repPrice = await GetItemJSON(item.querySelector("a[href][name]").href);

				navigator.clipboard.writeText(`${itemName}:${repPrice.repair_price},`)
			}*/

			if (!RepairPrices[itemName]) {
				continue;
			}

			// item.remove();
			// continue;

			const repairPrice = RepairPrices[itemName];
			const durability = item.querySelector("[valign=top]").innerText.split("Прочность:")[1];
			const durMin = parseInt(durability.split("/")[0]);
			let durMax = parseInt(durability.split("/")[1]);

			let battles = durMin;
			let PrevPrice = price / durMin;
			let repairs = 0;
			while (durMax > 0) {

				battles += Math.floor(durMax * repairPercentage);
				repairs++;
				let newPrice = (price + repairs * repairPrice * repairPriceCoeff) / battles;
				if (newPrice > PrevPrice) {
					battles -= Math.floor(durMax * repairPercentage);
					repairs--;
					break;
				}
				PrevPrice = newPrice;

				durMax--;
			}
			const el = Object.assign(
				document.createElement("div"), {
					innerHTML : `ЦЗБ: <b>${PrevPrice.toFixed(2)}</b>`,
					className:`removable`
				});
			const el1 = Object.assign(
				document.createElement("div"), {
					innerHTML : `Боев: <b>${battles}</b>`,
					className:`removable`
				})
			const el2 = Object.assign(
				document.createElement("div"), {
					innerHTML : `Ремонтов: <b>${repairs}</b>`,
					className:`removable`
				})
			item.querySelector("[valign=top]").appendChild(el);
			item.querySelector("[valign=top]").appendChild(el1);
			item.querySelector("[valign=top]").appendChild(el2);
		}

	}

	Recalc();

})();