Фильтр заявок в таверне
当前为
// ==UserScript==
// @name hwmTavernFilter
// @author Tamozhnya1
// @namespace Tamozhnya1
// @version 2.1
// @encoding utf-8
// @description Фильтр заявок в таверне
// @description В таверне появляется ссылка: "Настрока фильтра".
// @description Там надо выбрать желаемые районы и остальные параметры, например ставка от 0 до 0.
// @description Неотмеченные районы не отображаются.
// @description Заявки, соответствующие фильтру, подсвечиваются зелёным
// @include *heroeswm.ru/tavern.php*
// @include *lordswm.com/tavern.php*
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_addStyle
// @license MIT
// ==/UserScript==
const areas = ["Empire Capital", "Eagle Nest", "Harbour City",
"East River", "Portal Ruins", "Mithril Coast", "The Wilderness",
"Tiger Lake", "Dragons' Caves", "Great Wall", "Sublime Arbor",
"Rogues' Wood", "Shining Spring", "Titans' Valley", "Wolf Dale",
"Sunny City", "Fishing Village", "Peaceful Camp", "Magma Mines", "Kingdom Castle",
"Lizard Lowland", "Bear Mountain", "Ungovernable Steppe",
"Green Wood", "Fairy Trees", "Crystal Garden"];
this.GM_getValue = this.GM_getValue || function(key, def) { return localStorage[key] || def; };
this.GM_setValue = this.GM_setValue || function(key, value) { return localStorage[key] = value; };
this.GM_deleteValue = this.GM_deleteValue || function(key) { return delete localStorage[key]; };
const areasVisibility = {};
for(const area of areas) {
areasVisibility[area] = GM_getValue("show" + area) === "true";
}
const options = getOptions();
main();
function main() {
const tavernRef = document.querySelector("a[href='/tavern.php']");
if(tavernRef) {
tavernRef.parentNode.appendChild(document.createTextNode(" / "));
const showOptionsRef = addElement("a", tavernRef.parentNode, { href: "javascript:void(0)", innerHTML: ustring("Настрока фильтра") });
showOptionsRef.addEventListener("click", showOptions, false);
}
applyFilter();
}
function getOptions() {
return {
minBet: parseInt(GM_getValue("minBet", -1)),
maxBet: parseInt(GM_getValue("maxBet", -1)),
gameType: parseInt(GM_getValue("gameType", -1)),
minLevel: parseInt(GM_getValue("minLevel", -1)),
maxLevel: parseInt(GM_getValue("maxLevel", -1)),
minTime: parseInt(GM_getValue("minTime", -1)),
maxTime: parseInt(GM_getValue("maxTime", -1))
};
}
function showOptions() {
if(showPupupPanel(GM_info.script.name)) {
return;
}
const fieldsMap = [];
fieldsMap.push([createElement("b", { innerText: "Выберите районы" })]);
let i = 0;
let fieldsRow = [];
for(const key in areasVisibility) {
i++;
const areaCheckbox = createElement("input", { type: "checkbox", area: key });
if(areasVisibility[key]) {
areaCheckbox.setAttribute("checked", "checked");
}
areaCheckbox.addEventListener("click", showFilterOptionsCheckArea, false);
fieldsRow.push(key);
fieldsRow.push(areaCheckbox);
if(i % 4 == 0) {
fieldsMap.push(fieldsRow);
fieldsRow = [];
}
}
fieldsMap.push([]);
// Уровень противника
const levelFromCaption = createElement("b", { innerText: ustring("Уровень противника от:") });
const minLevel = createElement("select");
minLevel.addEventListener("change", function() { GM_setValue("minLevel", parseInt(this.value)); options.minLevel = parseInt(this.value); }, false);
const levelToCaption = createElement("b", { innerText: ustring("до:") });
const maxLevel = createElement("select");
maxLevel.addEventListener("change", function() { GM_setValue("maxLevel", parseInt(this.value)); options.maxLevel = parseInt(this.value); }, false);
const opponentLevels = {};
opponentLevels[-1] = ustring("Любой");
for(let i = 0; i <= 20; i++) {
opponentLevels[i.toString()] = i.toString();
}
for(let key in opponentLevels) {
let option = addElement("option", minLevel, { value: parseInt(key), innerHTML: opponentLevels[key] });
if(key == options.minLevel) {
option.setAttribute("selected", "selected");
}
option = addElement("option", maxLevel, { value: parseInt(key), innerHTML: opponentLevels[key] });
if(key == options.maxLevel) {
option.setAttribute("selected", "selected");
}
}
fieldsMap.push([levelFromCaption, minLevel, levelToCaption, maxLevel]);
// Тип игры
const gameTypeCaption = createElement("b", { innerText: ustring("Тип игры:") });
const gameType = createElement("select");
gameType.addEventListener("change", function() { GM_setValue("gameType", parseInt(this.value)); options.gameType = parseInt(this.value); }, false);
const gameTypes = {"-1": ustring("Любой"), "1": ustring("Игра с одной колодой"), "8": ustring("Игра с бесконечной колодой")};
for(let key in gameTypes) {
const option = addElement("option", gameType, { value: parseInt(key), innerHTML: gameTypes[key] });
if(key == options.gameType) {
option.setAttribute("selected", "selected");
}
}
fieldsMap.push([gameTypeCaption, gameType]);
// Время на ход
const moveTimeFromCaption = createElement("b", { innerText: ustring("Время на ход от:")});
const minTime = createElement("select");
minTime.addEventListener("change", function() { GM_setValue("minTime", parseInt(this.value)); options.minTime = parseInt(this.value); }, false);
const moveTimeToCaption = createElement("b", { innerText: ustring("до:") });
const maxTime = createElement("select");
maxTime.addEventListener("change", function() { GM_setValue("maxTime", parseInt(this.value)); options.maxTime = parseInt(this.value); }, false);
const moveTimes = {"-1": "Любая", "15": "15 сек.", "30": "30 сек.", "40": "40 сек."};
for(let key in moveTimes) {
let option = addElement("option", minTime, { value: parseInt(key), innerHTML: ustring(moveTimes[key]) });
if(key == options.minTime) {
option.setAttribute("selected", "selected");
}
option = addElement("option", maxTime, { value: parseInt(key), innerHTML: ustring(moveTimes[key]) });
if(key == options.maxTime) {
option.setAttribute("selected", "selected");
}
}
fieldsMap.push([moveTimeFromCaption, minTime, moveTimeToCaption, maxTime]);
// Величина ставки
const betValueFromCaption = createElement("b", { innerText: ustring("Величина ставки от:") });
const minBet = createElement("select");
minBet.addEventListener("change", function() { GM_setValue("minBet", parseInt(this.value)); options.minBet = parseInt(this.value); }, false);
const betValueToCaption = createElement("b", { innerText: ustring("до:") });
const maxBet = createElement("select");
maxBet.addEventListener("change", function() {GM_setValue("maxBet", parseInt(this.value)); options.maxBet = parseInt(this.value);}, false);
const betValues = { "-1": "Любая", "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 key in betValues) {
let option = addElement("option", minBet, { value: parseInt(key), innerHTML: ustring(betValues[key]) });
if(key == options.minBet) {
option.setAttribute("selected", "selected");
}
option = addElement("option", maxBet, { value: parseInt(key), innerHTML: ustring(betValues[key]) });
if(key == options.maxBet) {
option.setAttribute("selected", "selected");
}
}
fieldsMap.push([betValueFromCaption, minBet, betValueToCaption, maxBet]);
createPupupPanel(GM_info.script.name, "Настройки фильтра", fieldsMap);
}
function showFilterOptionsCheckArea() {
const area = this.getAttribute("area");
areasVisibility[area] = this.checked;
GM_setValue("show" + area, this.checked);
}
function getBets() {
const betsTable = document.querySelector("table[class='wb']");
if(!betsTable) {
console.log("Не найдена таблица ставок");
return;
}
const bets = [];
let currentTavern;
//console.log(betsTable.rows.length);
//let i = 0;
for(const row of betsTable.rows) {
//console.log([i++, row.cells.length, row.cells[0].getAttribute("colspan"), row.cells[0].className]);
if(row.cells.length < 5 || row.cells[0].hasAttribute("colspan") || row.cells[0].className == "wb") {
continue;
}
if(row.cells.length == 6) {
currentTavern = row.cells[0].innerHTML;
}
let offSet = row.cells.length == 5 ? 0 : 1;
const level = parseInt(row.cells[0 + offSet].querySelector("i").innerHTML.replace("(", "").replace(")", ""));
const gameType = row.cells[1 + offSet].querySelector("img[src*='1koloda']") ? 1 : 8;
const time = parseInt(row.cells[2 + offSet].innerHTML);
const betValue = parseInt(row.cells[3 + offSet].firstChild.firstChild.firstChild.firstChild.nextSibling.innerHTML.replace(",", ""));
const mayEnter = row.cells[4 + offSet].querySelector("a[href^='join_to_card_game.php']") ? true : false;
const bet = {
tavern: currentTavern,
level: level,
gameType: gameType,
time: time,
betValue: betValue,
mayEnter: mayEnter,
row: row,
}
//console.log(`currentTavern: ${currentTavern}, gameType: ${gameType}, time: ${time}, betValue: ${betValue}, mayEnter: ${mayEnter}, level: ${level}, bet: ${bet}`);
bets.push(bet);
}
return bets;
}
function applyFilter() {
//console.log(options);
for(const bet of getBets()) {
if(!areasVisibility[bet.tavern]) {
bet.row.style.display = "none";
}
//console.log([bet.betValue, options.minBet, options.maxBet, options.minBet <= bet.betValue, options.maxBet >= bet.betValue]);
if(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)) {
bet.row.style.backgroundColor = "green";
}
}
}
function uchar(s) {
switch (s[0]) {case "А": return "\u0410"; case "Б": return "\u0411"; case "В": return "\u0412"; case "Г": return "\u0413"; case "Д": return "\u0414"; case "Е": return "\u0415"; case "Ж": return "\u0416"; case "З": return "\u0417"; case "И": return "\u0418"; case "Й": return "\u0419"; case "К": return "\u041a"; case "Л": return "\u041b"; case "М": return "\u041c"; case "Н": return "\u041d"; case "О": return "\u041e"; case "П": return "\u041f"; case "Р": return "\u0420"; case "С": return "\u0421"; case "Т": return "\u0422"; case "У": return "\u0423"; case "Ф": return "\u0424"; case "Х": return "\u0425"; case "Ц": return "\u0426"; case "Ч": return "\u0427"; case "Ш": return "\u0428"; case "Щ": return "\u0429"; case "Ъ": return "\u042a"; case "Ы": return "\u042b"; case "Ь": return "\u042c"; case "Э": return "\u042d"; case "Ю": return "\u042e"; case "Я": return "\u042f"; case "а": return "\u0430"; case "б": return "\u0431"; case "в": return "\u0432"; case "г": return "\u0433"; case "д": return "\u0434"; case "е": return "\u0435"; case "ж": return "\u0436"; case "з": return "\u0437"; case "и": return "\u0438"; case "й": return "\u0439"; case "к": return "\u043a"; case "л": return "\u043b"; case "м": return "\u043c"; case "н": return "\u043d"; case "о": return "\u043e"; case "п": return "\u043f"; case "р": return "\u0440"; case "с": return "\u0441"; case "т": return "\u0442"; case "у": return "\u0443"; case "ф": return "\u0444"; case "х": return "\u0445"; case "ц": return "\u0446"; case "ч": return "\u0447"; case "ш": return "\u0448"; case "щ": return "\u0449"; case "ъ": return "\u044a"; case "ы": return "\u044b"; case "ь": return "\u044c"; case "э": return "\u044d"; case "ю": return "\u044e"; case "я": return "\u044f"; case "Ё": return "\u0401"; case "ё": return "\u0451"; default: return s[0];}}
function ustring(s) {
s = String(s);
var result = "";
for (var i = 0; i < s.length; i++)
result += uchar(s[i]);
return result;
}
function createPupupPanel(panelName, panelTitle, fieldsMap) {
let backgroundPopupPanel = addElement("div", document.body, { id: panelName + "1", style: "position: absolute; left: 0pt; width: 100%; background: none repeat scroll 0% 0% gray; opacity: 0.5; top: 0px; height: 100%; display: block; z-index: 200;" });
backgroundPopupPanel.addEventListener("click", function() { hidePupupPanel(panelName); }, false);
let popupPanel = addElement("div", document.body, { id: panelName + "2", style: `position: absolute; width: 650px; background: none repeat scroll 0% 0%; background-image: linear-gradient(to right, #eea2a2 0%, #bbc1bf 19%, #57c6e1 42%, #b49fda 79%, #7ac5d8 100%); left: ${((document.body.offsetWidth - 650) / 2)}px; top: 150px; display: block; z-index: 200; border: 4mm ridge rgba(211, 220, 50, .6);` });
let contentDiv = addElement("div", popupPanel, { id: panelName + "3", style: "border: 1px solid #abc; padding: 5px; margin: 2px; display: flex; flex-wrap: wrap;" });
if(panelTitle) {
addElement("b", contentDiv, { innerText: panelTitle, style: "text-align: center; margin: auto; width: 90%; display: block;" });
}
let divClose = addElement("div", contentDiv, {id: panelName + "close", title: "Close", innerText: "x", style: "border: 1px solid #abc; width: 15px; height: 15px; text-align: center; cursor: pointer;" });
divClose.addEventListener("click", function() { hidePupupPanel(panelName); }, false);
addElement("div", contentDiv, { style: "flex-basis: 100%; height: 0;"});
if(fieldsMap) {
let contentTable = addElement("table", contentDiv);
for(let rowData of fieldsMap) {
if(rowData.length == 0) { // Спомощью передачи пустой стороки-массива, указываем, что надо начать новую таблицу после брейка
addElement("div", contentDiv, { style: "flex-basis: 100%; height: 0;"});
contentTable = addElement("table", contentDiv);
continue;
}
const row = addElement("tr", contentTable);
for(let cellData of rowData) {
const cell = addElement("td", row);
if(cellData) {
if(typeof(cellData) == "string") {
cell.innerText = cellData;
} else {
cell.appendChild(cellData);
}
}
}
}
}
return contentDiv;
}
function showPupupPanel(panelName) {
let backgroundPopupPanel = document.getElementById(panelName + "1");
let popupPanel = document.getElementById(panelName + "2");
if(backgroundPopupPanel) {
backgroundPopupPanel.style.display = popupPanel.style.display = 'block';
return true;
}
return false;
}
function hidePupupPanel(panelName) {
let backgroundPopupPanel = document.getElementById(panelName + "1");
let popupPanel = document.getElementById(panelName + "2");
backgroundPopupPanel.style.display = popupPanel.style.display = 'none';
}
function addElement(type, parent, data) {
let el = createElement(type, data);
if(parent) {
parent.appendChild(el);
}
return el;
}
function createElement(type, data) {
let el = document.createElement(type);
if(data) {
for(let key in data) {
if(key == "innerText" || key == "innerHTML") {
el[key] = data[key];
} else {
el.setAttribute(key, data[key]);
}
}
}
return el;
}