hwmTavernFilter

Фильтр заявок в таверне

目前為 2023-04-19 提交的版本,檢視 最新版本

// ==UserScript==
// @name            hwmTavernFilter
// @author          Tamozhnya1
// @namespace       Tamozhnya1
// @version         2.0
// @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 TavernFilterOptionsId = "TavernFilterOptionsId";
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 hideOptions() {
    const backgroundOptionsPanel = document.getElementById(TavernFilterOptionsId + "1");
    const optionsPanel = document.getElementById(TavernFilterOptionsId + "2");
    backgroundOptionsPanel.style.display = optionsPanel.style.display = 'none';
}
function showOptions() {
    let backgroundOptionsPanel = document.getElementById(TavernFilterOptionsId + "1");
    let optionsPanel = document.getElementById(TavernFilterOptionsId + "2");
    if(backgroundOptionsPanel) {
        backgroundOptionsPanel.style.display = optionsPanel.style.display = 'block';
        return;
    }
    backgroundOptionsPanel = addElement("div", document.body, {id: TavernFilterOptionsId + "1"}, "position: absolute; left: 0pt; width: 100%; background: none repeat scroll 0% 0% gray; opacity: 0.5; top: 0px; height: 882px; display: block;");
    backgroundOptionsPanel.addEventListener("click", hideOptions, false);
 
    optionsPanel = addElement("div", document.body, {id: TavernFilterOptionsId + "2"}, "position: absolute; width: 650px; background: none repeat scroll 0% 0% rgb(246, 243, 234); left: " +
    ((document.body.offsetWidth - 650) / 2) + "px; top: 150px; display: block;");
    var div1 = addElement("div", optionsPanel, {id: TavernFilterOptionsId + "3"}, "border: 1px solid #abc; padding: 5px; margin: 2px;");
    
    var divClose = addElement("div", div1, {id: TavernFilterOptionsId + "close", title: "Close", innerHTML: "x"}, "float:right;border:1px solid #abc;width:15px;height:15px;text-align:center;cursor:pointer;");
    divClose.addEventListener("click", hideOptions, false);
    
    addElement("center", div1, {innerHTML: ustring("<b>Выберите районы</b>")});
    let table = addElement("table", div1);
    var i = 0;
    for(const key in areasVisibility) {
        i++;
        if(i % 4 == 1) {
            var tr = addElement("tr", table);
        }
        addElement("td", tr, {innerHTML: key})
        var td = addElement("td", tr);
        var checkbox = addElement("input", td, {type: "checkbox", area: key});
        if(areasVisibility[key]) {
            checkbox.setAttribute("checked", "checked");
        }
        checkbox.addEventListener("click", showFilterOptionsCheckArea, false);
    }
    // Уровень противника
    table = addElement("table", div1); 
    var tr = addElement("tr", table);
    addElement("td", tr, {innerHTML: ustring("<b>Уровень противника от: </b>")});
    var minLevel = addElement("select", addElement("td", tr));
    minLevel.addEventListener("change", function() {GM_setValue("minLevel", parseInt(this.value)); options.minLevel = parseInt(this.value);}, false);
 
    addElement("td", tr, {innerHTML: ustring("<b>до: </b>")});
    var maxLevel = addElement("select", addElement("td", tr));
    maxLevel.addEventListener("change", function() {GM_setValue("maxLevel", parseInt(this.value)); options.maxLevel = parseInt(this.value);}, false);
    var obj = {};
    obj[-1] = ustring("Любой");
    for(var i = 0; i <= 20; i++) {
        obj[i.toString()] = i.toString();
    }
    for(var key in obj) {
        var option = addElement("option", minLevel, {value: parseInt(key), innerHTML: obj[key]});
        if(key == options.minLevel) {
            option.setAttribute("selected", "selected");
        }
        var option = addElement("option", maxLevel, {value: parseInt(key), innerHTML: obj[key]});
        if(key == options.maxLevel) {
            option.setAttribute("selected", "selected");
        }
    }
    // Тип игры
    var tr = addElement("tr", table);
    addElement("td", tr, {innerHTML: ustring("<b>Тип игры: </b>")});
    var gameType = addElement("select", addElement("td", tr));
    gameType.addEventListener("change", function() { GM_setValue("gameType", parseInt(this.value)); options.gameType = parseInt(this.value); }, false);
    var obj = {"-1": ustring("Любой"), "1": ustring("Игра с одной колодой"), "8": ustring("Игра с бесконечной колодой")};
    for(var key in obj) {
        var option = addElement("option", gameType, {value: parseInt(key), innerHTML: obj[key]});
        if(key == options.gameType) {
            option.setAttribute("selected", "selected");
        }
    }
    // Время на ход
    var tr = addElement("tr", table);
    addElement("td", tr, {innerHTML: ustring("<b>Время на ход от: </b>")});
    var minTime = addElement("select", addElement("td", tr));
    minTime.addEventListener("change", function() {GM_setValue("minTime", parseInt(this.value)); options.minTime = parseInt(this.value);}, false);
 
    addElement("td", tr, {innerHTML: ustring("<b>до: </b>")});
    var maxTime = addElement("select", addElement("td", tr));
    maxTime.addEventListener("change", function() {GM_setValue("maxTime", parseInt(this.value)); options.maxTime = parseInt(this.value);}, false);
    var obj = {"-1": "Любая", "15": "15 сек.", "30": "30 сек.", "40": "40 сек."};
    for(var key in obj) {
        var option = addElement("option", minTime, {value: parseInt(key), innerHTML: ustring(obj[key])});
        if(key == options.minTime) {
            option.setAttribute("selected", "selected");
        }
        var option = addElement("option", maxTime, {value: parseInt(key), innerHTML: ustring(obj[key])});
        if(key == options.maxTime) {
            option.setAttribute("selected", "selected");
        }
    }
    // Величина ставки
    var tr = addElement("tr", table);
    addElement("td", tr, {innerHTML: ustring("<b>Величина ставки от: </b>")});
    var minBet = addElement("select", addElement("td", tr));
    minBet.addEventListener("change", function() {GM_setValue("minBet", parseInt(this.value)); options.minBet = parseInt(this.value);}, false);
 
    addElement("td", tr, {innerHTML: ustring("<b>до: </b>")});
    var maxBet = addElement("select", addElement("td", tr));
    maxBet.addEventListener("change", function() {GM_setValue("maxBet", parseInt(this.value)); options.maxBet = parseInt(this.value);}, false);
    var obj = { "-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 obj) {
        var option = addElement("option", minBet, {value: parseInt(key), innerHTML: ustring(obj[key])});
        if(key == options.minBet) {
            option.setAttribute("selected", "selected");
        }
        var option = addElement("option", maxBet, {value: parseInt(key), innerHTML: ustring(obj[key])});
        if(key == options.maxBet) {
            option.setAttribute("selected", "selected");
        }
    }	
}
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 addElement(type, parent, data, style) {
    var el = document.createElement(type);
    if(parent) {
        parent.appendChild(el);
    }
    if(data) for(var key in data) {
        if(key != "innerHTML") {
            el.setAttribute(key, data[key]);
        }
    }
    if(data && data.innerHTML) {
        el.innerHTML = data.innerHTML;
    }
    if(style && el.id) {
        if(typeof(style) == "string") {
            GM_addStyle("#" + el.id + "{" + style + "}");
        } else {
            var styleStr = "";
            for(var key in style) {
                styleStr += key + ": " + style[key] + "; ";
            }
            GM_addStyle("#" + el.id + "{" + styleStr + "}");
        }
    }
    return el;
}