您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Фильтр заявок в таверне
当前为
// ==UserScript== // @name hwmTavernFilter // @author Tamozhnya1 // @namespace Tamozhnya1 // @version 2.7 // @description Фильтр заявок в таверне // @include *heroeswm.ru/tavern.php* // @include *lordswm.com/tavern.php* // @grant GM_getValue // @grant GM_setValue // @grant GM_addStyle // @license MIT // ==/UserScript== const playerIdMatch = document.cookie.match(/pl_id=(\d+)/); if(!playerIdMatch) { return; } const PlayerId = playerIdMatch[1]; const areas = { "Empire Capital": { tower: 50, resources: 150 }, "Eagle Nest": { tower: 50, resources: 150 }, "Harbour City": { tower: 50, resources: 150 }, "East River": { tower: 75, resources: 200 }, "Portal Ruins": { tower: 75, resources: 200 }, "Mithril Coast": { tower: 75, resources: 200 }, "The Wilderness": { tower: 75, resources: 200 }, "Tiger Lake": { tower: 150, resources: 400 }, "Dragons' Caves": { tower: 150, resources: 400 }, "Great Wall": { tower: 150, resources: 400 }, "Sublime Arbor": { tower: 150, resources: 400 }, "Rogues' Wood": { tower: 100, resources: 300 }, "Shining Spring": { tower: 100, resources: 300 }, "Titans' Valley": { tower: 100, resources: 300 }, "Wolf Dale": { tower: 100, resources: 300 }, "Sunny City": { tower: 100, resources: 300 }, "Fishing Village": { tower: 100, resources: 300 }, "Peaceful Camp": { tower: 125, resources: 350 }, "Magma Mines": { tower: 125, resources: 350 }, "Kingdom Castle": { tower: 125, resources: 350 }, "Lizard Lowland": { tower: 200, resources: 500 }, "Bear Mountain": { tower: 200, resources: 500 }, "Ungovernable Steppe": { tower: 200, resources: 500 }, "Green Wood": { tower: 100, resources: 300 }, "Fairy Trees": { tower: 100, resources: 300 }, "Crystal Garden": { tower: 100, resources: 300 } }; const isEn = document.documentElement.lang == "en"; const locations = { "Empire Capital": "Столица Империи", "East River": "Восточная Река", "Tiger Lake": "Тигриное Озеро", "Rogues' Wood": "Лес Разбойников", "Wolf Dale": "Долина Волков", "Peaceful Camp": "Мирный Лагерь", "Lizard Lowland": "Равнина Ящеров", "Green Wood": "Зеленый Лес", "Eagle Nest": "Орлиное Гнездо", "Portal Ruins": "Руины Портала", "Dragons' Caves": "Пещеры Драконов", "Shining Spring": "Сияющий Родник", "Sunny City": "Солнечный Город", "Magma Mines": "Магма Шахты", "Bear Mountain": "Медвежья Гора", "Fairy Trees": "Магический Лес", "Harbour City": "Портовый Город", "Mithril Coast": "Мифриловый Берег", "Great Wall": "Великая Стена", "Titans' Valley": "Равнина Титанов", "Fishing Village": "Рыбачье село", "Kingdom Castle": "Замок Королевства", "Ungovernable Steppe": "Непокорная Степь", "Crystal Garden": "Кристальный Сад", "East Island": "Восточный Остров", "The Wilderness": "Дикие земли", "Sublime Arbor": "Великое Древо" }; main(); function main() { const tavernRef = document.querySelector("a[href='/tavern.php']"); if(tavernRef) { tavernRef.parentNode.appendChild(document.createTextNode(" / ")); const showOptionsRef = addElement("a", { href: "javascript:void(0)", innerHTML: isEn ? "Filter settings" : "Настрока фильтра" }, tavernRef.parentNode); showOptionsRef.addEventListener("click", showOptions); } applyFilter(); } function showOptions() { if(showPupupPanel(GM_info.script.name)) { return; } const fieldsMap = []; fieldsMap.push([addElement("b", { innerText: "Выберите районы" })]); let i = 0; let fieldsRow = []; for(const area in areas) { i++; const areaName = isEn ? area : locations[area]; const areaLabel = addElement("label", { for: `areaCheckbox${i}`, innerHTML: `${areaName} (${areas[area].tower}/${areas[area].resources})` }); const areaCheckbox = addElement("input", { id: `areaCheckbox${i}`, type: "checkbox" }); areaCheckbox.checked = getPlayerBool(`show${area}`, true); areaCheckbox.addEventListener("click", function() { setPlayerValue(`show${area}`, this.checked); }); fieldsRow.push(areaLabel); fieldsRow.push(areaCheckbox); if(i % 4 == 0) { fieldsMap.push(fieldsRow); fieldsRow = []; } } fieldsMap.push(fieldsRow); fieldsMap.push([]); // Уровень противника const levelFromCaption = addElement("b", { innerText: isEn ? "Partner level from" : "Уровень противника от" }); const minLevelSelect = addElement("select"); minLevelSelect.addEventListener("change", function() { setPlayerValue("minLevel", this.value); }); const levelToCaption = addElement("b", { innerText: isEn ? "to" : "до" }); const maxLevelSelect = addElement("select"); maxLevelSelect.addEventListener("change", function() { setPlayerValue("maxLevel", this.value); }); const opponentLevels = {}; opponentLevels[-1] = isEn ? "Any" : "Любой"; for(let i = 0; i <= 20; i++) { opponentLevels[i] = i.toString(); } for(const opponentLevel in opponentLevels) { let option = addElement("option", { value: opponentLevel, innerHTML: opponentLevels[opponentLevel] }, minLevelSelect); if(opponentLevel == getPlayerValue("minLevel", "-1")) { option.setAttribute("selected", "selected"); } option = addElement("option", { value: opponentLevel, innerHTML: opponentLevels[opponentLevel] }, maxLevelSelect); if(opponentLevel == getPlayerValue("maxLevel", "-1")) { option.setAttribute("selected", "selected"); } } fieldsMap.push([levelFromCaption, minLevelSelect, levelToCaption, maxLevelSelect]); // Тип игры const gameTypeCaption = addElement("b", { innerText: isEn ? "Game type" : "Тип игры" }); const gameTypeSelect = addElement("select"); gameTypeSelect.addEventListener("change", function() { setPlayerValue("gameType", this.value); }); const gameTypes = {"-1": isEn ? "Any" : "Любой", "1": isEn ? "One desk" : "Одна колода", "8": isEn ? "Infinite desk" : "Бесконечная колода"}; for(const gameType in gameTypes) { const option = addElement("option", { value: gameType, innerHTML: gameTypes[gameType] }, gameTypeSelect); if(gameType == getPlayerValue("gameType", "-1")) { option.setAttribute("selected", "selected"); } } fieldsMap.push([gameTypeCaption, gameTypeSelect]); // Время на ход const moveTimeFromCaption = addElement("b", { innerText: isEn ? "Turn time from" : "Время на ход от"}); const minTimeSelect = addElement("select"); minTimeSelect.addEventListener("change", function() { setPlayerValue("minTime", this.value); }); const moveTimeToCaption = addElement("b", { innerText: isEn ? "to" : "до" }); const maxTimeSelect = addElement("select"); maxTimeSelect.addEventListener("change", function() { setPlayerValue("maxTime", this.value); }); const moveTimes = {"-1": isEn ? "Any" : "Любая", "15": isEn ? "15 sec" :"15 сек.", "30": isEn ? "30 sec" : "30 сек.", "40": isEn ? "40 sec" : "40 сек."}; for(const moveTime in moveTimes) { let option = addElement("option", { value: moveTime, innerHTML: moveTimes[moveTime] }, minTimeSelect); if(moveTime == getPlayerValue("minTime", "-1")) { option.setAttribute("selected", "selected"); } option = addElement("option", { value: moveTime, innerHTML: moveTimes[moveTime] }, maxTimeSelect); if(moveTime == getPlayerValue("maxTime", "-1")) { option.setAttribute("selected", "selected"); } } fieldsMap.push([moveTimeFromCaption, minTimeSelect, moveTimeToCaption, maxTimeSelect]); // Величина ставки const betValueFromCaption = addElement("b", { innerText: isEn ? "Bet value from" : "Величина ставки от" }); const minBetSelect = addElement("select"); minBetSelect.addEventListener("change", function() { setPlayerValue("minBet", this.value); }); const betValueToCaption = addElement("b", { innerText: isEn ? "to" : "до" }); const maxBetSelect = addElement("select"); maxBetSelect.addEventListener("change", function() { setPlayerValue("maxBet", this.value); }); const betValues = { "-1": isEn ? "Any" : "Любая", "0": "0", "40": "40", "100": "100", "300": "300", "600": "600", "1000": "1000", "2000": "2000", "3000": "3000", "4000": "4000", "5000": "5000", "6000": "6000", "7000": "7000", "10000": "10000", "11000": "11000", "12000": "12000", "20000": "20000", "25000": "25000", "30000": "30000", "35000": "35000", "40000": "40000", "50000": "50000" }; for(const betValue in betValues) { let option = addElement("option", { value: betValue, innerHTML: betValues[betValue] }, minBetSelect); if(betValue == getPlayerValue("minBet", "-1")) { option.setAttribute("selected", "selected"); } option = addElement("option", { value: betValue, innerHTML: betValues[betValue] }, maxBetSelect); if(betValue == getPlayerValue("maxBet", "-1")) { option.setAttribute("selected", "selected"); } } fieldsMap.push([betValueFromCaption, minBetSelect, betValueToCaption, maxBetSelect]); createPupupPanel(GM_info.script.name, getScriptReferenceHtml() + " " + getSendErrorMailReferenceHtml(), fieldsMap, onScriptOptionToggle); } function onScriptOptionToggle(isShown) { if(isShown) { setTimeout("clearTimeout(Timer)", 0); // Вкл/выкл таймер обновления страницы (взаимодействие со скриптом на странице) } else { setTimeout("Refresh()", 0); applyFilter(); } } function applyFilter() { const options = { minBet: parseInt(getPlayerValue("minBet", "-1")), maxBet: parseInt(getPlayerValue("maxBet", "-1")), gameType: parseInt(getPlayerValue("gameType", -1)), minLevel: parseInt(getPlayerValue("minLevel", -1)), maxLevel: parseInt(getPlayerValue("maxLevel", -1)), minTime: parseInt(getPlayerValue("minTime", -1)), maxTime: parseInt(getPlayerValue("maxTime", -1)) }; //console.log(options); let currentTavern; const bets = Array.from(document.querySelectorAll("table[class='wb'] > tbody > tr")).filter(x => x.querySelector("img[src*='gold.png']")).map(x => { if(x.cells.length == 6) { if(!x.cells[0].hasAttribute("location")) { x.cells[0].setAttribute("location", x.cells[0].innerHTML); } currentTavern = x.cells[0].getAttribute("location"); const locationName = isEn ? currentTavern : locations[currentTavern]; x.cells[0].innerHTML = `${locationName}<br><span title="${isEn ? "Tower height" : "Высота башни"}">${areas[currentTavern].tower}</span> / <span title="${isEn ? "Resources" : "Ресурсов"}">${areas[currentTavern].resources}</span>`; } const bet = { tavern: currentTavern, level: parseInt(x.querySelector("a[href^='pl_info.php']").parentNode.querySelector("i").innerText.replace("(", "").replace(")", "")), gameType: x.querySelector("img[src*='1koloda']") ? 1 : 8, time: parseInt((new RegExp(`(\\d+) ${isEn ? "sec" : "сек"}.`)).exec(x.innerHTML)[1]), betValue: parseInt(x.querySelector("img[src*='gold.png']").parentNode.nextElementSibling.innerText.replace(",", "")), mayEnter: x.querySelector("a[href^='join_to_card_game.php']") ? true : false }; bet.enabled = bet.mayEnter && (options.gameType == -1 || options.gameType == bet.gameType) && (options.minLevel == -1 || options.minLevel <= bet.level) && (options.maxLevel == -1 || options.maxLevel >= bet.level) && (options.minTime == -1 || options.minTime <= bet.time) && (options.maxTime == -1 || options.maxTime >= bet.time) && (options.minBet == -1 || options.minBet <= bet.betValue) && (options.maxBet == -1 || options.maxBet >= bet.betValue); x.style.display = getPlayerBool(`show${bet.tavern}`, true) ? "" : "none"; x.style.backgroundColor = bet.enabled ? "green" : "gray"; if(bet.mayEnter) { x.querySelector("a[href^='join_to_card_game.php']").style.pointerEvents = bet.enabled ? "" : "none"; } //console.log(bet); return bet; }); } // API function createPupupPanel(panelName, panelTitle, fieldsMap, panelToggleHandler) { const backgroundPopupPanel = addElement("div", { id: panelName, style: "position: fixed; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgb(0,0,0); background-color: rgba(0,0,0,0.4); z-index: 200;" }, document.body); backgroundPopupPanel.addEventListener("click", function(e) { if(e.target == this) { hidePupupPanel(panelName, panelToggleHandler); }}); const contentDiv = addElement("div", { style: `top: 50%; transform: translateY(-50%); padding: 5px; display: flex; flex-wrap: wrap; position: relative; margin: auto; padding: 0; width: fit-content; background-image: linear-gradient(to right, #eea2a2 0%, #bbc1bf 19%, #57c6e1 42%, #b49fda 79%, #7ac5d8 100%); border: 1mm ridge rgb(211, 220, 50);` }, backgroundPopupPanel); if(panelTitle) { addElement("b", { innerHTML: panelTitle, style: "text-align: center; margin: auto; width: 90%; display: block;" }, contentDiv); } const divClose = addElement("span", { id: panelName + "close", title: isEn ? "Close" : "Закрыть", innerHTML: "×", style: "cursor: pointer; font-size: 20px; font-weight: bold;" }, contentDiv); divClose.addEventListener("click", function() { hidePupupPanel(panelName, panelToggleHandler); }); addElement("div", { style: "flex-basis: 100%; height: 0;"}, contentDiv); if(fieldsMap) { let contentTable = addElement("table", { style: "flex-basis: 100%; width: min-content;"}, contentDiv); for(const rowData of fieldsMap) { if(rowData.length == 0) { // Спомощью передачи пустой стороки-массива, указываем, что надо начать новую таблицу после брейка addElement("div", { style: "flex-basis: 100%; height: 0;"}, contentDiv); contentTable = addElement("table", undefined, contentDiv); continue; } const row = addElement("tr", undefined, contentTable); for(const cellData of rowData) { const cell = addElement("td", undefined, row); if(cellData) { if(typeof(cellData) == "string") { cell.innerText = cellData; } else { cell.appendChild(cellData); } } } } } if(panelToggleHandler) { panelToggleHandler(true); } return contentDiv; } function showPupupPanel(panelName, panelToggleHandler) { const backgroundPopupPanel = document.getElementById(panelName); if(backgroundPopupPanel) { backgroundPopupPanel.style.display = ''; if(panelToggleHandler) { panelToggleHandler(true); } return true; } return false; } function hidePupupPanel(panelName, panelToggleHandler) { const backgroundPopupPanel = document.getElementById(panelName); backgroundPopupPanel.style.display = 'none'; if(panelToggleHandler) { panelToggleHandler(false); } } function getValue(key, defaultValue) { return GM_getValue(key, defaultValue); }; function setValue(key, value) { GM_setValue(key, value); }; function deleteValue(key) { return GM_deleteValue(key); }; function getPlayerValue(key, defaultValue) { return GM_getValue(`${key}${PlayerId}`, defaultValue); }; function setPlayerValue(key, value) { GM_setValue(`${key}${PlayerId}`, value); }; function deletePlayerValue(key) { return GM_deleteValue(`${key}${PlayerId}`); }; function listValues() { return GM_listValues(); } function getPlayerBool(valueName, defaultValue = false) { return getBool(valueName + PlayerId, defaultValue); } function getBool(valueName, defaultValue = false) { const value = getValue(valueName); //console.log(`valueName: ${valueName}, value: ${value}, ${typeof(value)}`) if(value != undefined) { if(typeof(value) == "string") { return value == "true"; } if(typeof(value) == "boolean") { return value; } } return defaultValue; } function GM_addStyle(css) { addElement("style", { type: "text/css", innerHTML: css }, document.head); } 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) { parent.insertAdjacentElement(insertPosition, el); } return el; } function getScriptLastAuthor() { let authors = GM_info.script.author; if(!authors) { const authorsMatch = GM_info.scriptMetaStr.match(/@author(.+)\n/); authors = authorsMatch ? authorsMatch[1] : ""; } const authorsArr = authors.split(",").map(x => x.trim()).filter(x => x); return authorsArr[authorsArr.length - 1]; } function getDownloadUrl() { let result = GM_info.script.downloadURL; if(!result) { const downloadURLMatch = GM_info.scriptMetaStr.match(/@downloadURL(.+)\n/); result = downloadURLMatch ? downloadURLMatch[1] : ""; result = result.trim(); } return result; } function getScriptReferenceHtml() { return `<a href="${getDownloadUrl()}" title="${isEn ? "Check for update" : "Проверить обновление скрипта"}" target=_blanc>${GM_info.script.name} ${GM_info.script.version}</a>`; } function getSendErrorMailReferenceHtml() { return `<a href="sms-create.php?mailto=${getScriptLastAuthor()}&subject=${isEn ? "Error in" : "Ошибка в"} ${GM_info.script.name} ${GM_info.script.version} (${GM_info.scriptHandler} ${GM_info.version})" target=_blanc>${isEn ? "Bug report" : "Сообщить об ошибке"}</a>`; }