您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Быстрые ссылки на итоги боя; начало, конец, чат боя
// ==UserScript== // @name hwmBattleLinks // @author Tamozhnya1 // @namespace Tamozhnya1 // @description Быстрые ссылки на итоги боя; начало, конец, чат боя // @version 4.9 // @encoding utf-8 // @include https://*.heroeswm.ru/* // @include https://*.lordswm.com/* // @include https://*hwmguide.ru/* // @exclude */rightcol.php* // @exclude */ch_box.php* // @exclude */chat* // @exclude */ticker.html* // @exclude */frames* // @exclude */brd.php* // @exclude */auction.php* // @grant GM_deleteValue // @grant GM_getValue // @grant GM_setValue // @grant GM.xmlHttpRequest // @license MIT // ==/UserScript== const isEn = document.documentElement.lang == "en"; main(); function main() { addStyle(`span.undecorated> a { text-decoration: none; }`); addStyle(`span.undecorated> a > span { rotate: 0.5 1 0 180deg; display: inline-block; }`); processWarReferences(); if(location.pathname == "/pl_warlog.php") { const hwm_no_zoom = document.querySelector("div#hwm_no_zoom"); if(hwm_no_zoom) { observe(hwm_no_zoom, processWarReferences); } } } function processWarReferences() { const warRefs = Array.from(document.querySelectorAll("a[href*='warid=']:not(:has(+span[name=battleLinksSpan])):not([name=battleLink])")).filter(x => !getUrlParamValue(x.href, "show_enemy")); //console.log(`processWarReferences warRefs: ${warRefs.length}`); //console.log(warRefs); for(const warRef of warRefs) { const warId = getUrlParamValue(warRef.href, "warid"); const show = getUrlParamValue(warRef.href, "show"); const showForAll = getUrlParamValue(warRef.href, "show_for_all"); const showForAllSnippet = (showForAll || show) ? `&show_for_all=${(showForAll || show)}` : ""; const battleLinksSpan = addElement('span', { name: "battleLinksSpan", class: "undecorated" }, warRef, "afterend"); battleLinksSpan.innerHTML = ` [<a name=battleLink href="/war.php?warid=${warId}<=-1${showForAllSnippet}" title="${isEn ? "War begin reference" : "Ссылка на начало боя"}" target="_blank"><span>🔫</span></a><a name=battleLink href="/battlechat.php?warid=${warId}${showForAllSnippet}" title="${isEn ? "War chat reference" : "Ссылка на чат боя"}" target="_blank">🗨</a><a name=battleLink href="/war.php?warid=${warId}${showForAllSnippet}" title="${isEn ? "War end reference" : "Ссылка на конец бой"}" target="_blank">🏁</a><a name=battleLink href="/battle.php?warid=${warId}&lastturn=-3${showForAllSnippet}" title="${isEn ? "War log end reference" : "Ссылка на конец лога боя"}" target="_blank">㏒</a>]`; warRef.addEventListener("click", function(e) { e.preventDefault(); showBattleResult(this); }); } } async function showBattleResult(warRef) { const warId = getUrlParamValue(warRef.href, "warid"); const show = getUrlParamValue(warRef.href, "show"); const showForAll = getUrlParamValue(warRef.href, "show_for_all"); const showForAllSnippet = (showForAll || show) ? `&show_for_all=${(showForAll || show)}` : ""; let battleContainer = document.getElementById(`battleContainer${warId}`); const isShown = battleContainer && battleContainer.style.display == "flex"; Array.from(document.querySelectorAll("div[id^='battleContainer']")).forEach(x => { x.style.display = "none"; }); if(battleContainer) { if(!isShown) { battleContainer.style.display = "flex"; } return; } const warRefRect = warRef.getBoundingClientRect(); battleContainer = addElement("div", { id: `battleContainer${warId}`, style: `position: absolute; left: ${warRefRect.left + window.scrollX + 10}px; top: ${warRefRect.bottom + window.scrollY + 1}px; border: 2px solid #000000; padding: 0; z-index: 3; background-image: linear-gradient(to right, #eea2a2 0%, #bbc1bf 19%, #57c6e1 42%, #b49fda 79%, #7ac5d8 100%); display: flex;` }, document.body); const battleResultContainer = addElement("div", { innerHTML: getWheelImage(), style: "text-align: center;" }, battleContainer); const divClose = addElement("div", { title: isEn ? "Close" : "Закрыть", innerText: "x", style: "border: 1px solid #abc; flex-basis: 15px; height: 15px; text-align: center; cursor: pointer;" }, battleContainer); divClose.addEventListener("click", function() { battleContainer.style.display = "none"; }, false); const responseText = await getRequestText(`/battle.php?warid=${warId}&lastturn=-2${showForAllSnippet}`, "text/html; charset=UTF-8"); const battleResultsStartIndex = responseText.indexOf("<font"); if(battleResultsStartIndex == -1) { battleResultContainer.innerHTML = `<br>${isEn ? "Parse error." : "Результаты боя не найдены."}`; return; } const battleResults = responseText.substring(battleResultsStartIndex); const battleResultsParts = battleResults.split("|#", 2); let battleResult = battleResultsParts[0]; if(isEn && battleResultsParts.length > 1 && battleResultsParts[1].startsWith("f_en")) { battleResult = battleResultsParts[1].substring(4); } battleResult = battleResult.replace(/ size="18"/g, '').replace(/font color="/g, 'font style="color: '); const battleResultParts = battleResult.split("<br />"); const regexp_exp = isEn ? /([\d\,]+) exp/ : /([\d\,]+) опыт/; const regexp_skill = isEn ? /(\d*\.?\d+) skill/ : /(\d*\.?\d+) умени/; let i = 0; for(const battleResultPart of battleResultParts) { const exp1 = regexp_exp.exec(battleResultPart); if(exp1) { const skillNumber = parseFloat(regexp_skill.exec(battleResultPart)[1]); if(skillNumber > 0) { battleResultParts[i] = `${battleResultPart} <span title="${isEn ? "Experience number per skill point" : "Количество опыта на одно очко умения"}">(${Math.round(parseFloat(exp1[1].replaceAll(",", "")) / skillNumber)})</span>`; } } i++; } battleResultContainer.innerHTML = battleResultParts.join("<br />"); } function getWheelImage() { return '<img border="0" align="absmiddle" height="11" src="https://dcdn.heroeswm.ru/css/loading.gif">'; } function getUrlParamValue(url, paramName) { return (new URLSearchParams(url.split("?")[1])).get(paramName); } function addElement(type, data = {}, parent = undefined, insertPosition = "beforeend") { const el = document.createElement(type); for(const key in data) { if(key == "innerText" || key == "innerHTML") { el[key] = data[key]; } else { el.setAttribute(key, data[key]); } } if(parent) { if(parent.insertAdjacentElement) { parent.insertAdjacentElement(insertPosition, el); } else if(parent.parentNode) { switch(insertPosition) { case "beforebegin": parent.parentNode.insertBefore(el, parent); break; case "afterend": parent.parentNode.insertBefore(el, parent.nextSibling); break; } } } return el; } function addStyle(css) { addElement("style", { type: "text/css", innerHTML: css }, document.head); } function getRequestText(url, overrideMimeType = "text/html; charset=windows-1251") { return new Promise((resolve, reject) => { GM.xmlHttpRequest({ method: "GET", url: url, overrideMimeType: overrideMimeType, onload: function(response) { resolve(response.responseText); }, onerror: function(error) { reject(error); } }); }); } // MutationObserver function observe(targets, handler, config = { childList: true, subtree: true }) { targets = Array.isArray(targets) ? targets : [targets]; targets = targets.map(x => { if(typeof x === 'function') { return x(document); } return x; }); // Можем передавать не элементы, а их селекторы const ob = new MutationObserver(async function(mut, observer) { //console.log(`Mutation start`); observer.disconnect(); if(handler.constructor.name === 'AsyncFunction') { await handler(); } else { handler(); } for(const target of targets) { if(target) { observer.observe(target, config); } } }); for(const target of targets) { if(target) { ob.observe(target, config); } } }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址