您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Виджет для главной страницы ГВД
当前为
// ==UserScript== // @name hwmWidget // @include /^https{0,1}:\/\/((www|qrator)\.heroeswm\.ru|178\.248\.235\.15)\/home\.php/ // @description Виджет для главной страницы ГВД // @version 4.7 // @author Tamozhnya1 // @namespace Tamozhnya1 // @grant GM.xmlHttpRequest // @grant unsafeWindow // @grant GM_log // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // @license MIT // ==/UserScript== if(typeof GM_getValue != 'function') { this.GM_getValue = function (key,def) { return localStorage[key] || def; }; this.GM_setValue = function (key,value) { return localStorage[key] = value; }; this.GM_deleteValue = function (key) { return delete localStorage[key]; }; } 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": "ОиС" }; 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(` .hover-link:hover{ color: red } .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: 800px; height: 500px; z-index: 120; 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: 500px; height: 800px; } }`); const isNewPersonPage = document.querySelector("div#hwm_no_zoom") ? true : false; const isMobileInterface = document.querySelector("div#btnMenuGlobal") ? true : false; main(); async function main() { //const widgetContainer = isNewPersonPage ? document.querySelector("center > div") : document.querySelector("body > center > table:nth-child(2)"); let 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(isMobileInterface) { widgetContainer = isNewPersonPage ? document.querySelector("div#set_mobile_max_width") : document.querySelector("div#android_container > table > tbody > tr:nth-child(6) > td:nth-child(1)"); if(isNewPersonPage) { widgetContainer.style.flexWrap = "wrap"; addElement("div", widgetContainer, { style: "flex-basis: 100%; height: 0;"}); } } if(widgetContainer) { let divOuterInnerHTML = ` <div class="flex"> <div id="hwmWidget" class="flex"> <div id="hwmWidgetDailyPreviewTab" class="news-head active"> <span>📰</span> <h2 class="news-head__title" title="Новости HWM Daily">Новости HWM Daily</h2> </div> <h2 id="hwmWidgetPorumPreviewTab" class="news-head news-head__title mrgn-l" title="Последние темы форума">Последние темы форума</h2> <h2 id="hwmWidgetClanLettersPreviewTab" class="news-head news-head__title mrgn-l" title="Клановая рассылка">Клановая рассылка</h2> </div> <span id="hwmWidgetSwitcher" class="news-head__switch"></span> <span id="hwmWidgetSettings" 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="hwmWidgetSettingsPanel"> <div class="modal-block"> <div class="modal-block__head"> <h3 class="modal-block__title">Настройки виджета</h3> <button id="hwmWidgetSettingsPanelCloseButton" 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> <label for="ShowItemsAmountInput">Количество отображаемых сообщений</label><input type="number" id="ShowItemsAmountInput" value="${GM_getValue("ShowItemsAmount", 5)}" onfocus="this.select();"/> </div> </div>`; const divOuter = addElement('div', widgetContainer, { class: "div-style", innerHTML: divOuterInnerHTML }, GM_getValue("top", false)); fillClansList(); addElement('div', divOuter, { id: "hwmWidgetNewsPanel" }); addElement('div', divOuter, { id: "hwmWidgetResourcesPanel", 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 hwmWidgetSwitcher = document.getElementById('hwmWidgetSwitcher'); hwmWidgetSwitcher.addEventListener("click", function(event) { GM_setValue("Shown", 1 - Number(GM_getValue("Shown", 1))); show(); }, false); const hwmSettings = document.getElementById('hwmWidgetSettings'); hwmSettings.addEventListener("click", function(event) { document.querySelector("#hwmWidgetSettingsPanel").style.display = 'flex'; document.querySelector("html").style.overflowY = 'hidden'; }, false); const hwmWidgetDailyPreviewTab = document.getElementById('hwmWidgetDailyPreviewTab'); hwmWidgetDailyPreviewTab.addEventListener("click", function(event) { GM_setValue("SecondClick", parseInt(GM_getValue("SelectedTab", 0)) == 0); GM_setValue("SelectedTab", 0); show(); }, false); const hwmWidgetPorumPreviewTab = document.getElementById('hwmWidgetPorumPreviewTab'); hwmWidgetPorumPreviewTab.addEventListener("click", function(event) { GM_setValue("SecondClick", parseInt(GM_getValue("SelectedTab", 0)) == 1); GM_setValue("SelectedTab", 1); show(); }, false); const hwmWidgetClanLettersPreviewTab = document.getElementById('hwmWidgetClanLettersPreviewTab'); hwmWidgetClanLettersPreviewTab.addEventListener("click", function(event) { GM_setValue("SecondClick", parseInt(GM_getValue("SelectedTab", 0)) == 2); GM_setValue("SelectedTab", 2); show(); }, false); const closeSettings = document.getElementById('hwmWidgetSettingsPanelCloseButton'); closeSettings.addEventListener("click", function(event) { document.querySelector("#hwmWidgetSettingsPanel").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"); } GM_setValue("ShowItemsAmount", document.getElementById("ShowItemsAmountInput").value); show(); }, false); GM_setValue("SecondClick", false); show(); } } async function fillClansList() { const doc = await getRequest(`https://www.heroeswm.ru/pl_clans.php`); 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 clans = ''; for(const clanInfo of clanInfos) { clans += ` <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 = clans; } else { GM_deleteValue("ClanId"); document.querySelector(".clans-block").innerHTML = "Вы не состоите в кланах"; } } 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 hwmWidgetSwitcher = document.getElementById('hwmWidgetSwitcher'); const newsPanel = document.getElementById("hwmWidgetNewsPanel"); const resourcesPanel = document.getElementById("hwmWidgetResourcesPanel"); if(shown == 0) { hwmWidgetSwitcher.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 hwmWidgetDailyPreviewTab = document.getElementById('hwmWidgetDailyPreviewTab'); const hwmWidgetPorumPreviewTab = document.getElementById('hwmWidgetPorumPreviewTab'); const hwmWidgetClanLettersPreviewTab = document.getElementById('hwmWidgetClanLettersPreviewTab'); hwmWidgetDailyPreviewTab.style.background = "#eae8dd00"; hwmWidgetPorumPreviewTab.style.background = "#eae8dd00"; hwmWidgetClanLettersPreviewTab.style.background = "#eae8dd00"; switch(parseInt(GM_getValue("SelectedTab", 0))) { case 0: hwmWidgetDailyPreviewTab.style.background = "#eae8dd"; getDailyNews(); break; case 1: hwmWidgetPorumPreviewTab.style.background = "#eae8dd"; getForumNews(); break; case 2: hwmWidgetClanLettersPreviewTab.style.background = "#eae8dd"; getClanNews(); break; } hwmWidgetSwitcher.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 trimming(string, l) { //console.log(`string: ${string}, l: ${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, "&").replace(/>/g, ">").replace(/</g, "<"); } 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}) <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}) <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}) <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("hwmWidgetResourcesPanel"); resourcesPanel.innerHTML = getWheelImage(); 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; } async function getClanNews() { if(!GM_getValue("ClanId")) { document.getElementById("hwmWidgetNewsPanel").innerHTML = "Вы не состоите в кланах"; return; } const doc = await getRequest(`https://www.heroeswm.ru/sms_clans.php?clan_id=${GM_getValue("ClanId")}`); const letters = Array.from(doc.querySelectorAll("table.wbwhite a[href^='/sms_clans.php'][href*='read']")).map(x => { return { Title: x.innerHTML, Ref: x.href, DateText: x.parentNode.previousElementSibling.innerHTML, IsHot: (Date.now() - parseDate(x.parentNode.previousElementSibling.innerHTML, false, true).getTime()) / (1000 * 60 * 60) <= 12, }; }).slice(0, parseInt(GM_getValue("ShowItemsAmount", 5))); //console.log(letters); //console.log(`letters: ${letters.length}`); let clanLetters = ""; for(const letter of letters) { clanLetters += ` <div class='text-title'> <a class='hover-link' style='text-decoration:none; ${letter.IsHot ? "font-weight: bold; color: red;" : ""}' target='_blank' href='${letter.Ref}' title='${letter.Title}'>${letter.IsHot ? "📣 " : "• "}${letter.Title}</a> <div class='clan-style'> <span title='Дата' style='font-size:9px'>${letter.DateText}</span> </div> </div> `; } document.getElementById("hwmWidgetNewsPanel").innerHTML = clanLetters; } async function getForumNews() { const forumId = GM_getValue("ForumId", "2"); const doc = await getRequest(`https://www.heroeswm.ru/forum_thread.php?id=${forumId}`); const messages = Array.from(doc.querySelectorAll("tr > td:nth-child(1) > a[href^='forum_messages.php']")).map(x => { return { Fixed: getParent(x, "tr").querySelector("img[src*='skrepka.gif']") ? true : false, Title: x.innerHTML, Reference: x.href, LastCommentReference: getParent(x, "tr").querySelector("a[href^='forum_messages.php'][href*='page=last']"), CommentsAmount: parseInt(getParent(x, "tr").cells[2].innerHTML), IsHot: parseInt(getParent(x, "tr").cells[2].innerHTML) <= 20 };}).filter(x => !x.Fixed).slice(0, parseInt(GM_getValue("ShowItemsAmount", 5))); let forumNews = ""; for(const message of messages) { forumNews += ` <div class='text-title'> <a class='hover-link' style='text-decoration: none;${(message.IsHot ? ' font-weight: bold; color: #ff4d00' : '')}' target='_blank' href='${message.Reference}' title='${message.Title}'>${(message.IsHot ? "🔥" : "•")} ${message.Title} </a> <div style='display: inline-flex; background-color: #adadad40;padding: 3px 7px; margin-left: 7px; border: 0; border-radius: 4px; color: #592C08;'> <a href="${message.LastCommentReference}" title='Количество комментариев. Перейти к последнему.' target='_blank' style='font-size: 9px'>${message.CommentsAmount}</a> </div> </div>`; } document.getElementById("hwmWidgetNewsPanel").innerHTML = forumNews; } function getDailyNews() { const newsPanel = document.getElementById("hwmWidgetNewsPanel"); newsPanel.innerHTML = `${getWheelImage()} Загрузка списка новостей...`; 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 { const dailyUrlRegExp = /\/\/daily\.heroeswm\.ru\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*$/i; const previousMessageIds = GM_getValue("PreviousDailyMessageIds", "").split("|"); const messages = JSON.parse('[["' + response.responseText.replace(/"/g, "\\\"").replace(/\n/g, '"],["').replace(/;;/g, '","').replace(/'/g, "'") + '"]]').filter(x => x.length == 6).map(x => { return { Code: x[0], ImageUrl: x[1], Title: trimming(x[2], 255), Url: x[3], Id: x[4], CommentsAmount: x[5], IsHot: !previousMessageIds.includes(x[4]) };}).filter(x => dailyUrlRegExp.test(x.ImageUrl) && dailyUrlRegExp.test(x.Url) && /^[1-3]$/.test(x.Code)); GM_setValue("PreviousDailyMessageIds", messages.map(x => x.Id).join("|")); //console.log(messages); let newsText = ""; for(const message of messages) { newsText += ` <div class='text-title'> <a class='hover-link' style='text-decoration: none;${message.IsHot ? 'font-weight: bold; color:red' : ''}' target='_blank' href='${message.Url}'>${message.IsHot ? "⚡" : "•"} ${message.Title}</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'>${message.CommentsAmount}</span> </div> </div>`; } newsPanel.innerHTML = newsText; } catch(e) { newsPanel.innerHTML = `Ошибка при обработке данных: ${e}`; } }, onerror: function(response) { newsPanel.innerHTML = "Ошибка при получении данных с Daily"; } }); } 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 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 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 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); } }); }); } 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; } function parseDate(dateString, isFuture = false, isPast = false) { //console.log(dateString) if(!dateString) { return; } const dateStrings = dateString.split(" "); let hours = 0; let minutes = 0; let seconds = 0; const timePart = dateStrings.find(x => x.includes(":")); if(timePart) { var time = timePart.split(":"); hours = parseInt(time[0]); minutes = parseInt(time[1]); if(time.length > 2) { seconds = parseInt(time[2]); } } const now = new Date(); let year = now.getFullYear(); let month = now.getMonth(); let day = now.getDate(); const datePart = dateStrings.find(x => x.includes("-")); if(datePart) { const date = datePart.split("-"); month = parseInt(date[isEn ? (date.length == 3 ? 1 : 0) : 1]) - 1; day = parseInt(date[isEn ? (date.length == 3 ? 2 : 1) : 0]); if(date.length == 3) { year = isEn ? parseInt(date[0]) : parseInt(date[2]); if(year < 1000) { year += Math.floor((new Date()).getFullYear() / 1000) * 1000; } } else { if(isFuture && month == 0 && now.getMonth() == 11) { year += 1; } } } if(dateStrings.length > 2) { const letterDateExec = /(\d{2}):(\d{2}) (\d{2}) (.{3,4})/.exec(dateString); if(letterDateExec) { //console.log(letterDateExec) day = parseInt(letterDateExec[3]); //const monthNames = ['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря']; const monthShortNames = ['янв', 'фев', 'март', 'апр', 'май', 'июнь', 'июль', 'авг', 'сент', 'окт', 'ноя', 'дек']; month = monthShortNames.findIndex(x => x.toLowerCase() == letterDateExec[4].toLowerCase()); if(isPast && (new Date(year, month, day, hours, minutes, seconds)).getTime() > Date.now()) { year -= 1; } } } //console.log(`year: ${year}, month: ${month}, day: ${day}, time[0]: ${time[0]}, time[1]: ${time[1]}, ${new Date(year, month, day, parseInt(time[0]), parseInt(time[1]))}`); return new Date(year, month, day, hours, minutes, seconds); } function getParent(element, parentType, number = 1) { let result = element; let foundNumber = 0; while(result = result.parentNode) { if(result.nodeName.toLowerCase() == parentType.toLowerCase()) { foundNumber++; if(foundNumber == number) { return result; } } } }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址