您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Provides a leaders guild's army set bookmarks. Beta version.
// ==UserScript== // @name LWM_LGBookmarks // @name:ru Наборы армий гильдии лидеров. // @namespace saturn_hwm // @version 0.4 // @homepage https://greasyfork.org/ru/scripts/401090-lwm-lgbookmarks // @description Provides a leaders guild's army set bookmarks. Beta version. // @description:ru Предоставляет дюжину закладок для сохранения наборов войск гильдии лидеров и позволяет копировать и вставлять набор армии в текстовом виде. Бета версия. // @author saturn573 // @match https://*.heroeswm.ru/leader_guild.php* // @match https://*.heroeswm.ru/leader_army.php* // @match http://daily.heroeswm.ru/leader/lg_daily.php* // @grant GM_setClipboard // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // ==/UserScript== function LWMBookmarks() { this.update(); } LWMBookmarks.prototype = { applyOnce: undefined, availableArmy: undefined, store: function() { storeObj(this, undefined, true); }, update: function() { updateObj(this, undefined, true); }, getStorageKey: function() { return 'GlobalParam'; } }; function getStorageKey(objItem, storageKey, isCommon) { if (undefined == storageKey && undefined != objItem && 'function' == typeof objItem.getStorageKey) { storageKey = objItem.getStorageKey(); } storageKey = storageKey || 'params'; if (!isCommon) { let match = /pl_id\s*=\s*(\d+)/.exec(document.cookie); if (match) { storageKey += '_'+ match[1]; } else { console.log('Invalid cookie!'); } } if (!storageKey) { console.log('There is no storage key!'); } return storageKey; } function getStorableObj(objItem) { if (undefined == objItem) { return objItem; } let storableObj = {}; let keysCounter = 0; for (let key in objItem) { let keyValue = objItem[key]; if (undefined == keyValue || "function" == typeof keyValue) { continue; } storableObj[key] = keyValue; keysCounter++; } if (0 == keysCounter) { storableObj = undefined; } return storableObj; } function storeObj(objItem, storageKey, isCommon) { storageKey = getStorageKey(objItem, storageKey, isCommon); if (!storageKey) { return; } let value = getStorableObj(objItem); if (undefined == value) { GM_deleteValue(storageKey); } else { GM_setValue(storageKey, JSON.stringify(value)); } } function updateObj(objItem, storageKey, isCommon) { storageKey = getStorageKey(objItem, storageKey, isCommon); if (!storageKey) { return; } let storedObj = GM_getValue(storageKey); if (undefined == storedObj) { return; } try { storedObj = JSON.parse(storedObj); for (let key in storedObj) { objItem[key] = storedObj[key] } } catch (err) { console.log(err); } } function getElem(css, root) { if (!root) root = document; if (!root.querySelector) { console.log('Invalid root! %s', css); return; } return root.querySelector(css); } function getElems(css, root) { if (!root) root = document; if (!root.querySelectorAll) { console.log('Invalid root! %s', css); return []; } return root.querySelectorAll(css); } function addElem(tag, details) { let el = document.createElement(tag); if (details) { for (var key in details) { el[key] = details[key]; } } return el; } function addText(text) { return document.createTextNode(text); } function setEventHandler(elem, eventName, eventHandler) { let type = (typeof elem).toLowerCase(); if ('string' == type) { let el = getElems(elem); for (let ii = 0; ii < el.length; ii++) { el[ii].addEventListener(eventName, eventHandler); } } else if ('object' == type) { elem.addEventListener(eventName, eventHandler); } else { console.log('Unexpected elem type: %s of %o', type, elem); } } function addStyle(css) { document.head.appendChild(addElem('style', { innerHTML: css })); } function isAvailableStack(name, count, g) { if (undefined == g) { g = new LWMBookmarks(); } let army = g.availableArmy; if (undefined == army) { return false; } return (army[name] || 0) >= count; } function isAvailableArmy(text, g) { if (undefined == g) { g = new LWMBookmarks(); } if (undefined == g.availableArmy) { return false; } let army = g.availableArmy; let result = true; let pp = text.split(', '); if (pp && 2 < pp.length) { for (let ii = 0; ii < pp.length; ii++) { let nc = pp[ii].split('='); let count = parseInt(nc[1]); let aa = army[nc[0]] || 0; if (aa < count) { result = false; break; } } } return result; } function setupPageDailyTable() { let g = new LWMBookmarks(); const cnB = 'lwm-lgt-b'; const cnAllow = 'allow'; const cnDeny = 'deny'; addStyle('.' + cnB + ' { float: right; min-width: 1.4rem; margin-top: 0.8rem; margin-right: 0.4rem; text-align: center; }'); addStyle('.' + cnB + '.' + cnDeny + ' { background-color: lightpink; }'); addStyle('.' + cnB + '.' + cnAllow + ' { background-color: lawngreen; }'); let sb = getElems('div.spoiler-body-1'); if (!sb) { console.log('!sb'); return; } sb.forEach((el, ii) => { let tbl = el.firstChild; while (tbl) { let ttl = []; let ad = getElems('div.cre_creature', tbl); let cell; for (let ii = 0; ii < ad.length; ii++) { let img = getElem('a[href*="/army_info.php?name="] img[alt]', ad[ii]); let cnt = getElem('#add_now_count', ad[ii]); if (!img || !cnt) { continue; } cell = ad[ii].parentNode; let name = img.title; let count = parseInt(cnt.textContent); ttl.push(name + '=' + count); if (!isAvailableStack(name, count, g)){ cnt.style.color = 'red'; } } if (cell && ttl.length > 0) { let army = ttl.join(', '); let bс = addElem('button', { className: cnB, innerHTML: '\uD83D\uDCCB', title: 'Копировать', army: army } ); setEventHandler(bс, 'click', function() { GM_setClipboard(this.army); }); cell.appendChild(bс); let ba = addElem('button', { className: cnB, innerHTML: '\u2713', title: 'Установить', applyOnce: army } ); setEventHandler(ba, 'click', function() { let gg = new LWMBookmarks(); gg.applyOnce = this.applyOnce; gg.store(); location.assign('https://www.heroeswm.ru/leader_army.php'); }); if (isAvailableArmy(army, g)) { ba.classList.add(cnAllow); } else { ba.classList.add(cnDeny); } cell.appendChild(ba); } tbl = tbl.nextSibling; } }); } function setupPageLeaderGuild() { let lg = getElem('a[href*="lg_daily_rating.php?day="]'); if (lg) { lg.parentNode.insertBefore(addElem('a', { innerHTML: 'Таблица', href: 'http://daily.heroeswm.ru/leader/lg_daily.php' }), lg); lg.parentNode.insertBefore(addText('|'), lg); } } function getDamage(count, damage, attack, defence) { let modifier = 1; if (attack > defence) { modifier = 1 + ((attack - defence) * 0.05); } else if (attack < defence) { modifier = 1 / (1 + (defence - attack) * 0.05); } return Math.floor(count * parseInt(damage) * modifier).toFixed(0); } function initPercents() { let cs = getElem('div.content_separator'); if (!cs) { console.log('no cs'); return; } cs.style.height = '1.1rem'; addStyle('.lwm-lg-w { position: relative; width: 100%; margin-left: 1rem; }'); addStyle('.lwm-lg-w > creature_slider { text-align: center }'); let csw = addElem('div', { className: 'lwm-lg-w' }); for (let ii = 0; ii < 7; ii++) { csw.appendChild(addElem('div', { className: 'creature_slider', slotNum: ii + 1, id: 'perc' + ii })); } cs.appendChild(csw); range_link.rangeslider().on("input", onArmyChanged); setEventHandler('#reset_div', 'click', onArmyChanged); onArmyChanged(); } function getCurrentLeaderArmyText() { let res = []; for (let ii = 0; ii < obj_army.length; ii++) { let oa = obj_army[ii]; if (!oa || !oa.link || !oa.count) { continue; } let ob =obj[oa.link]; if (!ob || !ob.name) { continue; } res.push(ob.name + '=' + oa.count); } return res.join(', '); } function updateStatistics() { let percentDiv = []; for (let ii = 0; ii < 7; ii++) { let pd = getElem('#perc'+ii); percentDiv[pd.slotNum] = pd; } for (let ii = 0; ii < percentDiv.length; ii++) { let pd = percentDiv[ii]; if (!pd) { continue; } pd.innerHTML = ''; } for (let ii = 1; ii < obj_army.length; ii++) { let oa = obj_army[ii]; if (!oa || !oa.link) { continue; } let count = oa.count; let ob = obj[oa.link]; let cost = ob.cost; percentDiv[ii].innerHTML = (100 * count * cost / max_leader).toFixed(1) + '%'; let ttl = 'MAX: ' + (100 * count * cost / max_leader_by_stack).toFixed(1) + '%'; ttl += '\n HP: ' + count * ob.maxhealth; let dmg = ob.damage.split('-'); if (2 == dmg.length) { let attack = parseInt(ob.attack); let attackM = /\(\s*\+\s*(\d+)\s*\)/.exec(ob.attack); if (attackM) { attack += parseInt(attackM[1]); } ttl += '\n DMG: '; let defence = 0; while (defence <= 50) { ttl += '\nD' + defence + ': ' + getDamage(count, dmg[0], attack, defence) + ' - ' + getDamage(count, dmg[1], attack, defence); defence += 5; } } percentDiv[ii].title = ttl; } } function updateCurrentArmyBookmark() { const cnB = 'lwm-la-b'; const cnCurrent = 'current'; let ca = getCurrentLeaderArmyText(); getElems('.' + cnB).forEach(b => { let isArmyEqual = ca && ca == b.title; let isCurrent = b.classList.contains(cnCurrent) if ((isArmyEqual && !isCurrent) || (!isArmyEqual && isCurrent)) { b.classList.toggle(cnCurrent); } }); } function onArmyChanged() { updateCurrentArmyBookmark(); updateStatistics(); } function setElemsStyleDisplay(selector, display) { getElems(selector).forEach(xx => xx.style.display = display); } function showElems(selector, display) { setElemsStyleDisplay(selector, display || ''); } function hideElems(selector) { setElemsStyleDisplay(selector, 'none'); } function setLeaderArmy(text) { let cc = text.split(', '); if (!cc || 1 > cc.length) { console.log('Incorrect text: %s', text); return; } //reset for (let ii = 7; ii >= 1; ii--) { obj_army[ii].count = 0; } for (let ii = 0; ii < cc.length; ii++) { let c = cc[ii].split('='); let count = parseInt(c[1]); let name = c[0].trim(); let link = -1; for (let jj = 0; jj < obj.length; jj++) { let ob = obj[jj]; if (ob && ob.name == name) { link = jj; break; } } if (link >= 0) { let oa = obj_army[ii + 1]; oa.link = link; oa.count = count; } } army_try_to_submit(); show_details(-1); sliders_update(); hideElems('#apply_div, #info_content'); showElems('#reset_div'); onArmyChanged(); } function initPasteArea() { const dt = 'Вставить из буфера'; let hc = getElem('div.army_info_block1 > div.info_header_content'); if (!hc) { console.log('!hc'); return; } hc.setAttribute('contenteditable', true); hc.innerHTML = dt; setEventHandler(hc, 'focus', function() { setTimeout(() => { document.execCommand('selectAll', true, null); document.execCommand('paste', true, null); }, 100); }); let applyArmy = function() { if (dt == hc.textContent) { return; } hc.innerHTML = 'Вставить из буфера'; setLeaderArmy(hc.textContent); } setEventHandler(hc, 'blur', applyArmy); setEventHandler(hc, 'keydown', function(e) { if (e.keyCode == 13) { applyArmy(); } else { console.log('keydown event args: %o', e); } }); } function initLeaderArmyBookmarks() { let bookmarks = { update: function() { updateObj(this); }, store: function() { storeObj(this); }, getStorageKey: function() { return 'LeaderArmyBookmarks'; } }; bookmarks.update(); const cnB = 'lwm-la-b'; const cnCurrent = 'current'; const cnSet = 'set'; addStyle('.lwm-la-bw { position: absolute; top: 50%; right: -35px;\ -moz-transform: translate(0, -50%); -o-transform: translate(0, -50%);\ -ms-transform: translate(0, -50%); -webkit-transform: translate(0, -50%);\ transform: translate(0, -50%); }'); addStyle('.' + cnB + ' { width: 34px; height: 34px; background-color: silver; cursor: pointer;\ border: 1px solid #333; border-right: none; margin: -1px 0;\ -webkit-border-top-left-radius: 6px; -webkit-border-bottom-left-radius: 6px;\ -moz-border-radius-topleft: 6px; -moz-border-radius-bottomleft: 6px;\ border-top-left-radius: 6px; border-bottom-left-radius: 6px;\ transition-duration: .15s; -webkit-transition-duration: .15s;\ -moz-transition-duration: .15s; -o-transition-duration: .15s;\ -ms-transition-duration: .15s; font-size: x-large; filter: grayscale(100%); }'); addStyle('.' + cnB + '.' + cnSet + ' { filter: grayscale(0%); }'); addStyle('.' + cnB + ':hover { transform: scale(1.2); }'); addStyle('.' + cnB + '.' + cnCurrent + ' { filter: hue-rotate(185deg); }'); addStyle('.' + cnB + '.' + cnCurrent + ':hover { transform: translateX(3px); }'); addStyle('.' + cnB + '.' + cnCurrent + ':hover:after { content: "\u232B"; vertical-align: text-top; font-size: medium; color: #0ca86a; font-weight: bold; '); let bw = addElem('div', { className: 'lwm-la-bw' }); let slotContent = ['♈', '♉', '♊', '♋', '♌', '♍', '♎', '♏', '♐', '♑', '♒', '♓' ]; for (let ii = 0; ii < slotContent.length; ii++) { let b = addElem('div', { className: cnB, slotNum: ii+1, innerHTML: slotContent[ii] }); let txt = bookmarks[b.slotNum]; if (txt) { b.classList.toggle(cnSet); b.title = txt; } setEventHandler(b, 'click', function() { let toggle = false; let txt = getCurrentLeaderArmyText(); if (this.classList.contains(cnSet)) { if (txt == this.title) { if (confirm("Очистить эту закладку?")) { delete bookmarks[this.slotNum]; this.title = ''; toggle = true; } } else { setLeaderArmy(this.title); } } else if (txt) { this.title = txt; bookmarks[this.slotNum] = txt; toggle = true; } if (toggle) { bookmarks.store(); this.classList.toggle(cnSet); updateCurrentArmyBookmark(); } }); bw.appendChild(b); } army_info_div.appendChild(bw); updateCurrentArmyBookmark(); } function initGlobal() { let a = {}; for (let ii = 0; ii < obj.length; ii++) { let ob = obj[ii]; if (ob && ob.name && ob.count) { a[ob.name] = ob.count; } } let g = new LWMBookmarks(); g.availableArmy = a; if (g.applyOnce) { try { setLeaderArmy(g.applyOnce); delete g.applyOnce; } catch (err) { console.log(err); } } g.store(); } function setupPageLeaderArmy() { initPercents(); initPasteArea(); initLeaderArmyBookmarks(); initGlobal(); } (function main() { 'use strict'; let p = location.pathname; if (/lg_daily/.test(p)) { setupPageDailyTable(); } else if (/leader_guild/.test(p)) { setupPageLeaderGuild(); } else if (/leader_army/.test(p)) { setupPageLeaderArmy(); } else { console.log('Unexpected location: %o', location); } })();