hwmWidget

Виджет для главной страницы ГВД

目前为 2023-11-24 提交的版本。查看 最新版本

// ==UserScript==
// @name        hwmWidget
// @include     /^https{0,1}:\/\/((www|qrator)\.heroeswm\.ru|178\.248\.235\.15)\/home\.php/
// @description Виджет для главной страницы ГВД
// @version     4.2
// @author      Tamozhnya1
// @namespace   Tamozhnya1
// @grant       GM.xmlHttpRequest
// @grant       unsafeWindow
// @grant       GM_log
// @grant       GM_setValue
// @grant       GM_getValue
// @grant       GM_addStyle
// @license     MIT
// ==/UserScript==
const LotType = { Purchase: 1, Auction: 2 };
var ElementsTypes = { "42": "abrasive", "43": "snake_poison", "46": "tiger_tusk", "44": "ice_crystal", "45": "moon_stone", "40": "fire_crystal", "37": "meteorit", "41": "witch_flower", "39": "wind_flower", "78": "fern_flower", "38": "badgrib" }
var ElementNames = ["abrasive", "snake_poison", "tiger_tusk", "ice_crystal", "moon_stone", "fire_crystal", "meteorit", "witch_flower", "wind_flower", "fern_flower", "badgrib"];
var ResourcesTypes = { "wood": { Type: "1", ImageName: "wood" }, "ore": { Type: "2", ImageName: "ore" }, "mercury": { Type: "3", ImageName: "mercury" }, "sulphur": { Type: "4", ImageName: "sulfur" }, "crystal": { Type: "5", ImageName: "crystals" }, "gem": { Type: "6", ImageName: "gems" } };
var forumNames = { "2": "ОиФ", "10": "ВиП", "24": "Турниры", "3": "ИиП", "12": "БиП", "11": "ФВТ", "27": "Встречи", "14": "Обычные артефакты", "21": "Аренда", "22": "УКиО", "23": "ПЭСиП", "25": "ПЗ(Бои)", "13": "ПЗ(Финансы)", "7": "ТП", "8": "ОиС" };
var forumStartRows = { "2": "4", "10": "8", "24": "4", "3": "5", "12": "3", "11": "4", "27": "3", "14": "4", "21": "3", "22": "3", "23": "4", "25": "4", "13": "5", "7": "5", "8": "4" };
const locations = {
    1: [50,50,"Empire Capital","EmC","Столица Империи"],
    2: [51,50,"East River","EsR","Восточная Река"],
    3: [50,49,"Tiger Lake","TgL","Тигриное Озеро"],
    4: [51,49,"Rogues' Wood","RgW","Лес Разбойников"],
    5: [50,51,"Wolf Dale","WoD","Долина Волков"],
    6: [50,48,"Peaceful Camp","PcC","Мирный Лагерь"],
    7: [49,51,"Lizard Lowland","LzL","Равнина Ящеров"],
    8: [49,50,"Green Wood","GrW","Зеленый Лес"],
    9: [49,48,"Eagle Nest","EgN","Орлиное Гнездо"],
    10: [50,52,"Portal Ruins","PoR","Руины Портала"],
    11: [51,51,"Dragons' Caves","DrC","Пещеры Драконов"],
    12: [49,49,"Shining Spring","ShS","Сияющий Родник"],
    13: [48,49,"Sunny City","SnC","Солнечный Город"],
    14: [52,50,"Magma Mines","MgM","Магма Шахты"],
    15: [52,49,"Bear Mountain","BrM","Медвежья Гора"],
    16: [52,48,"Fairy Trees","FrT","Магический Лес"],
    17: [53,50,"Harbour City","HrC","Портовый Город"],
    18: [53,49,"Mythril Coast","MfC","Мифриловый Берег"],
    19: [51,52,"Great Wall","GtW","Великая Стена"],
    20: [51,53,"Titans' Valley","TiV","Равнина Титанов"],
    21: [52,53,"Fishing Village","FsV","Рыбачье село"],
    22: [52,54,"Kingdom Castle","KiC","Замок Королевства"],
    23: [48,48,"Ungovernable Steppe","UnS","Непокорная Степь"],
    24: [51,48,"Crystal Garden","CrG","Кристальный Сад"],
    25: [53,52,"East Island","EsI","Восточный Остров"],
    26: [49,52,"The Wilderness","ThW","Дикие земли"],
    27: [48,50,"Sublime Arbor","SbA","Великое Древо"]
};
const isEn = document.documentElement.lang == "en";
const Strings = { "ru": { BuyNow: "Купить сразу!" }, "en": { BuyNow: "Buy now!" } };
const LocalizedString = Strings[document.documentElement.lang];
GM_addStyle(`

.news-head {
  text-decoration:none;
  align-self: center;
  border-radius: 1.5rem;
  padding: 0.25rem .75rem;
}

.active {
  background: #eae8dd;
}

.active:hover {
  background: #eae8dd80;
}

.news-head__title {
  display: inline;
  font-size: 12px;
  font-weight: normal;
  cursor: pointer;
}

.news-head__switch {
  cursor: pointer;
  align-self: center;
  color: #5D413A40;
  margin-left:10px;
}

.news-head__settings {
  cursor: pointer;
  align-self: center;
  color: #5D413A40;
  margin-left:10px;
  width: 1.5%;
}

.mrgn-l{
  margin-left: 5px;
}

.flex {
  display: flex;
}

.div-style {
  margin: 0 auto 10px;
  padding: 15px 25px 20px;
  overflow: hidden;
  min-width: 400px;
  border-radius: 5px;
  border: 0 #adadad solid;
  background: url(../i/inv_im/corner_lt2.png) no-repeat top left, url(../i/inv_im/corner_rt2.png) no-repeat top right, url(../i/inv_im/corner_lb2.png) no-repeat bottom left, url(../i/inv_im/corner_rb2.png) no-repeat bottom right #f5f3ea;
  background-size: 14px;
  box-shadow: inset 0 0 0 1px #b19673, 0 2px 5px rgb(0 0 0 / 25%);
}

.res-style {
  display: none;
  justify-content: space-around;
  height: 40px;
  background-color: #eae8dd;
  border-radius: 5px;
  border: 0 #adadad solid;
  margin-top: 10px;
}

.modal {
  width: 100%;
  height: 100%;
  z-index: 1000;
  position: fixed;
  top:0;
  left:0;
  background: #00000050;
  display: none;
  align-items: center;
}

.modal-block {
  display: flex;
  width: 400px;
  height: 300px;
  z-index: 1200;
  margin: 0 auto;
  position: relative;
  border-radius: 5px;
  border: 0 #adadad solid;
  background: url(../i/inv_im/corner_lt2.png) no-repeat top left, url(../i/inv_im/corner_rt2.png) no-repeat top right, url(../i/inv_im/corner_lb2.png) no-repeat bottom left, url(../i/inv_im/corner_rb2.png) no-repeat bottom right #f5f3ea;
  background-size: 14px;
  box-shadow: inset 0 0 0 1px #b19673, 0 2px 5px rgb(0 0 0 / 25%);
  padding: 15px;
  align-items: flex-start;
  flex-direction: column;
  overflow: scroll;
}

.modal-block__head {
  display: flex;
  align-items: center;
}

.modal-block__text {
  margin-top: 20px;
  color: #6e6e6e;
}

.modal-block__btn {
  padding: 5px 15px;
  white-space: nowrap;
  position: relative;
  text-align: center;
  color: #592C08;
  background: url(../i/shop_images/art_btn_bg_gold.png) #DAB761;
  background-size: 100% 100%;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border: 0 solid;
  border-radius: 5px;
  box-shadow: inset 0 0 0 1px #fce6b0, inset 0 0 0 2px #a78750, 0 0 0 1px rgb(0 0 0 / 13%);
  cursor: pointer;
  margin-left: 150px;
}

.modal-block__setting {
  display: flex;
  flex-wrap: wrap;
}

.modal-block__checkbox {
  display: flex;
  align-items: center;
  margin: 0 8px 8px 5px;
  padding: 0;
}

.clan-block {
  flex-direction: column;
}

.clan-style {
  display: inline-flex;
  background-color: #adadad40;
  padding: 3px 7px;
  margin-left: 7px;
  border: 0;
  border-radius: 4px;
  color: #592C08;
}

.res-style__elem {
  align-self: center;
  display: flex;
}

.text-title {
  text-align:left;
  padding-top: 6px;
}

@media screen and (min-width: 320px) and (max-width: 600px) {
  .div-style {
    width: auto;
  }
  
  .news-head__title {
    font-size: 10px;
  }
  
  .res-style {
    flex-wrap: wrap;
    height: auto;
    padding: 5px;
  }
  .res-style__elem {
    margin: 0 10px 10px 0;
    font-size: 12px;
  }
  .text-title {
    font-size: 12px;
  }
  .news-head__settings {
    width: 10%;
  }
  .modal-block {
    width: auto;
    height: 400px;
  }
}`);
GM_init();
var topics = {};
topics["1"] = { title: "Новости", link: "https://daily.heroeswm.ru/news/" };
topics["2"] = { title: "Горячие новости", link: "http://daily.heroeswm.ru/hn.php" };
topics["3"] = { title: "Зеркало", link: "http://daily.heroeswm.ru/mrrr.php" };
const isNewPersonPage = document.querySelector("div#hwm_no_zoom") ? true : false;

main();
function main() {
    //const widgetContainer = isNewPersonPage ? document.querySelector("center > div") : document.querySelector("body > center > table:nth-child(2)");
    const widgetContainer = isNewPersonPage ? document.querySelector("body > center") : document.querySelector("body > center > table:nth-child(2) > tbody > tr > td > table > tbody > tr:nth-child(6) > td:nth-child(1)");
    if(widgetContainer) {
        let divOuterInnerHTML = `
<div class="flex">
  <div id="widget" class="flex">
       <div id="prevDaily" class="news-head active">
           <span>📰</span>
           <h2 id="prevDaily_t" class="news-head__title" title="Новости HWM Daily">Новости HWM Daily</h2>
       </div>
       <h2 id="prevForum" class="news-head news-head__title mrgn-l" title="Последние темы форума">Последние темы форума</h2>
       <h2 id="prevClan" class="news-head news-head__title mrgn-l" title="Клановая рассылка">Клановая рассылка</h2>
  </div>
  <span id="switcher" class="news-head__switch"></span>
  <span id="hwm_settings" class="news-head__settings" title="Настройки"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="cog" class="svg-inline--fa fa-cog fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M487.4 315.7l-42.6-24.6c4.3-23.2 4.3-47 0-70.2l42.6-24.6c4.9-2.8 7.1-8.6 5.5-14-11.1-35.6-30-67.8-54.7-94.6-3.8-4.1-10-5.1-14.8-2.3L380.8 110c-17.9-15.4-38.5-27.3-60.8-35.1V25.8c0-5.6-3.9-10.5-9.4-11.7-36.7-8.2-74.3-7.8-109.2 0-5.5 1.2-9.4 6.1-9.4 11.7V75c-22.2 7.9-42.8 19.8-60.8 35.1L88.7 85.5c-4.9-2.8-11-1.9-14.8 2.3-24.7 26.7-43.6 58.9-54.7 94.6-1.7 5.4.6 11.2 5.5 14L67.3 221c-4.3 23.2-4.3 47 0 70.2l-42.6 24.6c-4.9 2.8-7.1 8.6-5.5 14 11.1 35.6 30 67.8 54.7 94.6 3.8 4.1 10 5.1 14.8 2.3l42.6-24.6c17.9 15.4 38.5 27.3 60.8 35.1v49.2c0 5.6 3.9 10.5 9.4 11.7 36.7 8.2 74.3 7.8 109.2 0 5.5-1.2 9.4-6.1 9.4-11.7v-49.2c22.2-7.9 42.8-19.8 60.8-35.1l42.6 24.6c4.9 2.8 11 1.9 14.8-2.3 24.7-26.7 43.6-58.9 54.7-94.6 1.5-5.5-.7-11.3-5.6-14.1zM256 336c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"></path></svg></span>
</div>
<div class="modal" id="modal">
  <div class="modal-block">
      <div class="modal-block__head">
        <h3 class="modal-block__title">Настройки виджета</h3>
        <button id="modal-close" class="modal-block__btn">Закрыть</button>
      </div>
      <form>
        <p class="modal-block__text">Выбор форума</p>
        <div class="modal-block__setting">`;
        for(const forumId of Object.keys(forumNames)) {
            divOuterInnerHTML += `<div class="modal-block__checkbox"><input type="radio" id="${forumId}" name="forum" ${GM_getValue("ForumId", "2") == forumId ? "checked" : ""}><label for="${forumId}">${forumNames[forumId]}</label></div>`;
        }
        divOuterInnerHTML += `</div>
      </form>
      <form>
        <p class="modal-block__text">Выбор клана</p>
        <div class="modal-block__setting clans-block">
        </div>
      </form>
  </div>
</div>`;
        const divOuter = addElement('div', widgetContainer, { class: "div-style", innerHTML: divOuterInnerHTML }, GM_getValue("top", false));
        addElement('div', divOuter, { id: "NewsPanel" });
        addElement('div', divOuter, { id: "ResourcesPanel", class: "res-style" });
        if(isNewPersonPage) {
            const anchorRect = document.querySelector("div#set_mobile_max_width").getBoundingClientRect();
            console.log(anchorRect.width)
            divOuter.style.width = `${anchorRect.width}px`;
        }
        const switcher = document.getElementById('switcher');
        switcher.addEventListener("click", function(event) { GM_setValue("Shown", 1 - Number(GM_getValue("Shown", 1))); show(); }, false);
        GM_setValue("SecondClick", false);
        show();
      
        const hwmSettings = document.getElementById('hwm_settings'); 
        hwmSettings.addEventListener("click", function(event) {
            document.querySelector("#modal").style.display = 'flex';
            document.querySelector("html").style.overflowY = 'hidden';
        }, false);
      
        const prevDaily = document.getElementById('prevDaily');
        prevDaily.addEventListener("click", function(event) { GM_setValue("SecondClick", parseInt(GM_getValue("SelectedTab", 0)) == 0); GM_setValue("SelectedTab", 0); show(); }, false);
        const prevForum = document.getElementById('prevForum');
        prevForum.addEventListener("click", function(event) { GM_setValue("SecondClick", parseInt(GM_getValue("SelectedTab", 0)) == 1); GM_setValue("SelectedTab", 1); show(); }, false);
        const prevClan = document.getElementById('prevClan');
        prevClan.addEventListener("click", function(event) { GM_setValue("SecondClick", parseInt(GM_getValue("SelectedTab", 0)) == 2); GM_setValue("SelectedTab", 2); show(); }, false);

        const closeSettings = document.getElementById('modal-close');
        closeSettings.addEventListener("click", function(event) {
            document.querySelector("#modal").style.display = 'none';
            document.querySelector("html").style.overflowY = 'overlay';
            GM_setValue("ForumId", document.querySelector(`input[name='forum']:checked`).id);
            const selectedClan = document.querySelector(".clans-block input[name='clan']:checked");
            if(selectedClan) {
                GM_setValue("ClanId", selectedClan.id);
            } else {
                GM_deleteValue("ClanId");
            }
            show();
        }, false);
    }
    parseClans();
}
function parseClans() {
    return new Promise(((resolve, reject) => {
        doGet(`https://www.heroeswm.ru/pl_clans.php`, doc => {
            const clanInfos = Array.from(doc.querySelectorAll("td > li > a[href^='clan_info.php']")).map(x => { return { Id: getUrlParamValue(x.href, "id"), Name: x.firstChild.innerText }; });
            if(clanInfos.length > 0) {
              if(!GM_getValue("ClanId") || !clanInfos.find(x => x.Id == GM_getValue("ClanId"))) {
                  GM_setValue("ClanId", clanInfos[0].Id);
              }
              let clan = '';
              for(const clanInfo of clanInfos) {
                  clan += `
<div class="modal-block__checkbox">
    <input type="radio" id="${clanInfo.Id}" name="clan" ${clanInfo.Id == GM_getValue("ClanId") ? "checked" : ""}>
    <label for="${clanInfo.Id}">#${clanInfo.Id} ${clanInfo.Name}</label>
</div>`;
              }
              document.querySelector(".clans-block").innerHTML = clan;
            } else {
                GM_deleteValue("ClanId");
                document.querySelector(".clans-block").innerHTML = "Вы не состоите в кланах";
            }
            resolve();
        })
    }))  
}
async function show() {
    //console.log(`Shown: ${GM_getValue("Shown")}, SelectedTab: ${GM_getValue("SelectedTab")}, SecondClick: ${GM_getValue("SecondClick")}`);
    if(gmGetBool("SecondClick")) {
        switch(parseInt(GM_getValue("SelectedTab", 0))) {
            case 0: window.open("https://daily.heroeswm.ru/", "_blank"); break;
            case 1: window.open(`https://www.heroeswm.ru/forum_thread.php?id=${GM_getValue("ForumId", "2")}`, "_blank"); break;
            case 2: window.open(`https://www.heroeswm.ru/sms_clans.php?clan_id=${GM_getValue("ClanId")}`, "_blank"); break;
        }
        return;
    }
    const shown = GM_getValue("Shown", 1);
    const switcher = document.getElementById('switcher');
    const newsPanel = document.getElementById("NewsPanel");
    const resourcesPanel = document.getElementById("ResourcesPanel");
    if (shown == 0) {
        switcher.innerHTML = '<img src="https://dcdn3.heroeswm.ru/i/inv_im/btn_expand.svg" style="-webkit-transform: rotate(90deg);transform: rotate(90deg);">';
        // <img src="https://dcdn3.heroeswm.ru/i/inv_im/btn_expand.svg" class="home_scroll_content_expand_sign inv_rotate90">
        newsPanel.style.display = "none";
        resourcesPanel.style.display = "none";
    } else {
        const prevDaily = document.getElementById('prevDaily');
        const prevForum = document.getElementById('prevForum');
        const prevClan = document.getElementById('prevClan');
        prevDaily.style.background = "#eae8dd00";
        prevForum.style.background = "#eae8dd00";
        prevClan.style.background = "#eae8dd00";
        switch(parseInt(GM_getValue("SelectedTab", 0))) {
            case 0: prevDaily.style.background = "#eae8dd"; getDailyNews(); break;
            case 1: prevForum.style.background = "#eae8dd"; getForumNews(); break;
            case 2: prevClan.style.background = "#eae8dd"; getClanNews(); break;
        }
        switcher.innerHTML = '<img src="https://dcdn3.heroeswm.ru/i/inv_im/btn_expand.svg" style="-webkit-transform: rotate(270deg);transform: rotate(270deg);">';
        newsPanel.style.display = "block";
        await getResources();
        resourcesPanel.style.display = 'flex'
    }
}
function GM_init() {
    if (typeof GM_deleteValue == 'undefined') {
        GM_getValue = function(name, defaultValue) {
            var value = localStorage.getItem(name);
            if (!value) return defaultValue;
            var type = value[0];
            value = value.substring(1);
            switch (type) {
                case 'b':
                    return value == 'true';
                case 'n':
                    return Number(value);
                default:
                    return value;
            }
        }
        GM_registerMenuCommand = function(name, funk) {;
        }
        GM_setValue = function(name, value) {
            value = (typeof value)[0] + value;
            localStorage.setItem(name, value);
        }
    }
}
function trimming(string, l) {
    var s = string;
    if (string.length > l) {
        for (var i = l; i >= 0; i--)
            if (string.charAt(i) == ' ') s = string.substr(0, i) + '...';
        s = string.substr(0, l) + '...';
    }
    return s.replace(/&[^#]/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;");
}
function doGet(url, callback) {
    GM.xmlHttpRequest({
        method: "GET",
        url: url,
        overrideMimeType: "text/xml; charset=windows-1251",
        headers:
        {
           'User-agent': 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.8.1)',
           'Accept': 'text/xml,text/html',
           'Content-Type': 'text/plain; charset=windows-1251'
        },
        synchronous: false,
        onload: function (res) {
            callback(new DOMParser().parseFromString(res.responseText, "text/html"))
        }
    });
}
function getRequest(url) {
    return new Promise((resolve, reject) => {
        GM.xmlHttpRequest({ method: "GET", url: url, overrideMimeType: "text/html; charset=windows-1251",
            onload: function(response) { resolve((new DOMParser).parseFromString(response.responseText, "text/html")); },
            onerror: function(error) { reject(error); }
        });
    });
}
async function getElementLots() {
    const doc = await getRequest(`https://www.heroeswm.ru/auction.php?cat=elements&sort=0`);
    const firstLotRow = doc.querySelector("center > table:nth-child(2) > tbody > tr > td > table > tbody > tr:nth-child(2) > td:nth-child(2) > table > tbody > tr:nth-child(3)");
    let arts = [];
    let row = firstLotRow;
    while(row = row.nextElementSibling) {
        const art = parseLotRow(row);
        if(art) {
            arts.push(art);
        }
    }
    const grouppedArts = groupBy(arts.filter(x => x.LotType == LotType.Purchase), "ArtId");
    return grouppedArts;
}
function parseLotRow(row) {
    if(!row || row.nodeName != "TR") {
        return;
    }
    const goldImageElement = row.querySelector("img[src*='gold.png']");
    if(!goldImageElement) {
        return;
    }
    const lotPrice = parseFloat(goldImageElement.parentNode.nextElementSibling.innerText.replace(/,/g, ""));
    let artId;
    let lotAmount = 1;
    const lotAmountExec = new RegExp(`(\\d+) ${isEn ? "pcs." : "шт."}`).exec(row.innerHTML);
    //console.log(lotAmountExec);
    if(lotAmountExec) {
        lotAmount = parseInt(lotAmountExec[1]);
    }
    const lotType = row.innerHTML.includes(LocalizedString.BuyNow) ? LotType.Purchase : LotType.Auction;
    const artImageRefElement = row.querySelector("a[href*='art_info.php']");
    if(!artImageRefElement) {
        const elementsList = Object.values(ElementsTypes).join("|");
        const elementParse = (new RegExp(`gn_res/(${elementsList}).png`)).exec(row.innerHTML);
        if(elementParse) {
            artId = elementParse[1];
        }
        if(row.innerHTML.includes("house_cert")) {
            const locationsList = Object.values(locations).map(x => x[2]).join("|");
            const sertParse = (new RegExp(`<br>(${locationsList})&nbsp;<b>`)).exec(row.innerHTML);    
            if(sertParse) {
                artId = getSertIdByLocationName(sertParse[1]);
            }
        }
        const resourcesList = Object.values(ResourcesTypes).map(x => x.ImageName).join("|");
        const resourceParse = (new RegExp(`/(${resourcesList}).png`)).exec(row.innerHTML);
        if(resourceParse) {
            artId = "res_" + resourceParse[1];
        }
        if(row.innerHTML.includes("auc_dom")) {
            const locationsList = Object.values(locations).map(x => x[2]).join("|");
            const sertParse = (new RegExp(`<br>(${locationsList})&nbsp;<b>`)).exec(row.innerHTML);    
            if(sertParse) {
                artId = getHouseIdByLocationName(sertParse[1]);
            }
        }
        if(row.innerHTML.includes("obj_share_pic")) {
            const locationsList = Object.values(locations).map(x => x[2]).join("|");
            const sertParse = (new RegExp(`<br>(${locationsList})&nbsp;<b>`)).exec(row.innerHTML);    
            if(sertParse) {
                artId = getShaIdByLocationName(sertParse[1]);
            }
        }
    } else {
        artId = getUrlParamValue(artImageRefElement.href, "id");
        var artUid = getUrlParamValue(artImageRefElement.href, "uid");;
        const strengthData = row.innerText.match(/\d+\/\d+/);
        var restLotStrength = parseInt(strengthData[0].split("/")[0]);
        var lotStrength = parseInt(strengthData[0].split("/")[1]);
    }
    const lotRef = row.querySelector("a[href^='auction_lot_protocol.php']");
    const lotId = getUrlParamValue(lotRef.href, "id");
    
    const imgR = row.querySelector("td:nth-child(1) > table > tbody > tr > td:nth-child(1) > img");
    
    return { ArtUid: artUid, ArtId: artId, LotStrength: lotStrength, RestLotStrength: restLotStrength, LotPrice: lotPrice, LotType: lotType, LotAmount: lotAmount, LotId: lotId, ImageUrl: imgR.getAttribute('src'), Title: imgR.getAttribute('title') };
}
async function getResources() {
    const resourcesPanel = document.getElementById("ResourcesPanel");
    resourcesPanel.innerHTML = getwheelimg();
    const grouppedArts = await getElementLots();
    const elementsData = [];
    for(const elementName of ElementNames)
    {
        const arts = grouppedArts[elementName]
        if(arts.length == 0) {
            continue;
        }
        const art = arts[0];
        let price = art.LotPrice;
        let secondLotPrice = price;
        if(arts.length > 1) {
            secondLotPrice = arts[1].LotPrice;
        }
        elementsData.push({ ElementName: elementName,
            Price: price,
            ImageUrl: art.ImageUrl,
            Title: art.Title,
            Diffrence: secondLotPrice - price,
            AuctionUrl: `https://www.heroeswm.ru/auction.php?cat=elements&sort=0&art_type=${elementName}`,
            NewAuctionUrl: `https://www.heroeswm.ru/auction_new_lot.php?${elementName}=${(price - 1)}`
        }); 
    }
    //console.log(elementsData);
    let res = "";
    for(const elementData of elementsData)
    {                                    
        res += `
<div class='res-style__elem'>
<div style='align-self: center;'>
    <a class='hover-link' href='${elementData.NewAuctionUrl}' target='_blank'>
        <img src='${elementData.ImageUrl}' width='20' heigth='20' border='0'>
    </a>
</div>
<a class='hover-link' target='_. blank' style='text-decoration: none; align-self: center; margin-left: 5px; font-size: 9px;' href='${elementData.AuctionUrl}' title='Разница первого и второго лотов: ${elementData.Diffrence}'>${elementData.Price}</a>
<div style='${(elementData.Diffrence >= 150 ? 'display: inline-flex; background-color: #f33800; padding: 5px;margin-left: 5px; border: 0; border-radius: 4px; color: #fff;' : 'display: none;')}'>
    <span title='' style='font-size: 8px; font-weight: bold;'>${elementData.Diffrence}</span>
</div>
</div>`;
    }
    resourcesPanel.innerHTML = res;
}
function getClanNews() {
    if(!GM_getValue("ClanId")) {
        document.getElementById("NewsPanel").innerHTML = "Вы не состоите в кланах";
        return;
    }
    return new Promise(((resolve, reject) => {
        doGet(`https://www.heroeswm.ru/sms_clans.php?clan_id=${GM_getValue("ClanId")}`, doc => {
            const v = (doc.querySelector("body > center > table > tbody > tr > td > table > tbody > tr > td:nth-child(2) > table > tbody > tr:nth-child(2) > td > center > b > font") !== null) ? 1 : 0;
            const u = [doc.querySelector(`tr:nth-child(${3+v}) > td:nth-child(3) > a`),
                       doc.querySelector(`tr:nth-child(${4+v}) > td:nth-child(3) > a`),
                       doc.querySelector(`tr:nth-child(${5+v}) > td:nth-child(3) > a`),
                       doc.querySelector(`tr:nth-child(${6+v}) > td:nth-child(3) > a`),
                       doc.querySelector(`tr:nth-child(${7+v}) > td:nth-child(3) > a`)];
            const d = [doc.querySelector(`tr:nth-child(${3+v}) > td:nth-child(2)`),
                       doc.querySelector(`tr:nth-child(${4+v}) > td:nth-child(2)`),
                       doc.querySelector(`tr:nth-child(${5+v}) > td:nth-child(2)`),
                       doc.querySelector(`tr:nth-child(${6+v}) > td:nth-child(2)`),
                       doc.querySelector(`tr:nth-child(${7+v}) > td:nth-child(2)`)];
            let clan = "";
            for(let i = 0; i < u.length; i++)
            {
                if(u[i] !== null) {
                    clan += `
<div class='text-title'>
    <a class='hover-link' style='text-decoration:none; ${(((Date.now() - Date.parse(d[i].innerHTML.replace(/<\/?[^>]+(>|$)/g, ''))) / (1000 * 60 * 60) - 4).toFixed(0) <= 1 ? ';font-weight: bold; color:red' : '')}' target='_blank' href='${u[i]}'
    title='${u[i].innerHTML.replace(/<\/?[^>]+(>|$)/g, '')}'>
    ${(((Date.now() - Date.parse(d[i].innerHTML.replace(/<\/?[^>]+(>|$)/g, ''))) / (1000 * 60 * 60) - 4).toFixed(0) <= 6 ? "📣 " : "• ")}
    ${u[i].innerHTML.replace(/<\/?[^>]+(>|$)/g, '')}
    </a>
    <div class='clan-style'>
        <span title='комментариев' style='font-size:9px'>${d[i].innerHTML.replace(/<\/?[^>]+(>|$)/g, '')}</span>
    </div>
</div>
`;
                }
                if(u.indexOf(null) == 0) {
                    clan = "<div>Новостей нет</div>";
                }
            }
            document.getElementById("NewsPanel").innerHTML = `<div>${clan}</div>`;
            resolve();
        })
    }))
}
function getForumNews() {
    return new Promise(((resolve, reject) => {
        const forumId = GM_getValue("ForumId", "2");
        const x = parseInt(forumStartRows[forumId]);
        doGet(`https://www.heroeswm.ru/forum_thread.php?id=${forumId}`, doc => {
            var u = [doc.querySelector(`tr:nth-child(${x}) > td:nth-child(1) > a`),
                       doc.querySelector(`tr:nth-child(${x+1}) > td:nth-child(1) > a`),
                       doc.querySelector(`tr:nth-child(${x+2}) > td:nth-child(1) > a`),
                       doc.querySelector(`tr:nth-child(${x+3}) > td:nth-child(1) > a`),
                       doc.querySelector(`tr:nth-child(${x+4}) > td:nth-child(1) > a`)];
            var d = [doc.querySelector(`tr:nth-child(${x}) > td:nth-child(3)`),
                       doc.querySelector(`tr:nth-child(${x+1}) > td:nth-child(3)`),
                       doc.querySelector(`tr:nth-child(${x+2}) > td:nth-child(3)`),
                       doc.querySelector(`tr:nth-child(${x+3}) > td:nth-child(3)`),
                       doc.querySelector(`tr:nth-child(${x+4}) > td:nth-child(3)`)];
            var forum = "";
            for(var i = 0; i < u.length; i++) {
                if(!u[i]) {
                    continue;
                }
                forum += `
<div class='text-title'>
    <a class='hover-link' style='text-decoration: none;${(d[i].innerHTML.replace(/<\/?[^>]+(>|$)/g, '') <= 10 ? ' font-weight: bold; color: #ff4d00' : '')}' target='_blank' href='${u[i]}' title='${u[i].innerHTML.replace(/<\/?[^>]+(>|$)/g, '')}'
    ${(d[i].innerHTML.replace(/<\/?[^>]+(>|$)/g, '') <= 20 ? ">🔥 " : ">• ")}
    ${u[i].innerHTML.replace(/<\/?[^>]+(>|$)/g, '')}
    </a>
    <div style='display: inline-flex; background-color: #adadad40;padding: 3px 7px; margin-left: 7px; border: 0; border-radius: 4px; color: #592C08;'>
        <span title='комментариев' style='font-size: 9px'>${d[i].innerHTML.replace(/<\/?[^>]+(>|$)/g, '')}</span>
    </div>
</div>`;
            }
            const newsPanel = document.getElementById("NewsPanel");
            newsPanel.innerHTML = `<div>${forum}</div>`;
            resolve()
        })
    }))
}
function getDailyNews() {
    const newsPanel = document.getElementById("NewsPanel");
    newsPanel.innerHTML = `${getwheelimg()}&nbsp;&nbsp;Загрузка списка новостей...`;
    GM.xmlHttpRequest({method: "GET", url: "https://daily.heroeswm.ru/news4script.txt?" + Date.now(), headers:
      {
         'User-agent': 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.8.1)',
         'Accept': 'text/xml,text/html',
         'Content-Type': 'text/plain; charset=windows-1251'
      },
      synchronous: false,
      overrideMimeType: 'text/plain; charset=windows-1251',
      onload: function(response)
      {
         try
         {
            var sPat = /\/\/daily\.heroeswm\.ru\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*$/i;
            var nData = JSON.parse('[["' + response.responseText.replace(/"/g, "\\\"").replace(/\n/g, '"],["').replace(/;;/g, '","').replace(/'/g, "&#39;") + '"]]');
            var s = "";
            var new_last = '';
            var last = GM_getValue("last", "0|1");
            var last_ar = last.split('|');
            for(var i = 0; i < nData.length - 1; i++)
            {
               if((sPat.test(nData[i][1])) && (sPat.test(nData[i][3])) && (/^[1-3]$/.test(nData[i][0])))
               {
                  var max = 25;
                  if(last_ar.indexOf(nData[i][4]) == -1) max = max - 3;
                  s += "<div class = 'text-title'><a class = 'hover-link' style = 'text-decoration:none"
                  + (last_ar.indexOf(nData[i][4]) == -1 ? ';font-weight: bold; color:red' : '')
                  + "' target='_blank' href='"
                  + nData[i][3]
                  + "' title='"
                  + trimming(nData[i][2], 255)
                  + (last_ar.indexOf(nData[i][4]) == -1 ? "'>⚡ " : "'>• ")
                  + trimming(nData[i][2], 255)
                  + "</a><div style = 'display: inline-flex;background-color: #adadad40;padding: 3px 7px;margin-left: 7px;border: 0;border-radius: 4px;color: #592C08;'><span title = 'комментариев' style = 'font-size:9px'>"
                  + nData[i][5]
                    + "</span></div></div>";
                  new_last += nData[i][4] + "|";
               }
            }
            var css = '.hover-link:hover{ color: red }';
            var style = document.createElement('style');

            if (style.styleSheet) {
                 style.styleSheet.cssText = css;
            } else {
                 style.appendChild(document.createTextNode(css));
            }

            document.getElementsByTagName('head')[0].appendChild(style);
            GM_setValue("last", new_last);
         } catch(e) {
            s = "<div>Что-то не то... Не получается новости подгрузить...</div>";
         } finally {
            newsPanel.innerHTML = "<div>" + s + "</div>";
         }
      },
      onerror: function(response) {
         newsPanel.innerHTML = "<div>Что-то не то... Не получается новости подгрузить...</div>";
      }
   });
}
function GM_addStyle(css) {
    var head = document.getElementsByTagName('head')[0];
    if (!head)
      return;
    var style = document.createElement('style');
    style.type = 'text/css';
    style.innerHTML = css;
    head.appendChild(style);
}
function addElement(type, parent, data, insertFirst = false) {
    let el = createElement(type, data);
    if(parent) {
        if(insertFirst) {
            parent.insertBefore(el, parent.firstChild);
        } else {
            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;
}
function getwheelimg() { 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 groupBy(list, key) { return list.reduce(function(rv, item) { (rv[item[key]] = rv[item[key]] || []).push(item); return rv; }, {}); };
function getSertIdByLocationNumber(locationNumber) { return "sec_" + (locationNumber.toString()).padStart(2, "0"); }
function getSertIdByLocationName(locationName) { 
    const locationNumber = Object.keys(locations).find(x => locations[x][2] == locationName);
    return getSertIdByLocationNumber(locationNumber);
}
function getHouseIdByLocationNumber(locationNumber) { return "dom_" + (locationNumber.toString()).padStart(2, "0"); }
function getHouseIdByLocationName(locationName) { 
    const locationNumber = Object.keys(locations).find(x => locations[x][2] == locationName);
    return getHouseIdByLocationNumber(locationNumber);
}
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 gmGetBool(valueName, defaultValue = false) {
    const value = GM_getValue(valueName);
    if(value) {
        if(typeof(value) == "string") {
            return value == "true";
        }
        if(typeof(value) == "boolean") {
            return value;
        }
    }
    return defaultValue;
}

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址