您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Информация о гильдии кузнецов/оружейников на странице персонажа.
// ==UserScript== // @name [HWM] SmithsGuildOnHome // @namespace [HWM] SmithsGuildOnHome // @version 0.4.0 // @description Информация о гильдии кузнецов/оружейников на странице персонажа. // @author Komdosh // @include http*://*.heroeswm.ru/* // @grant none // @license MIT // ==/UserScript== const SMITHS_GUILD_SETTINGS = 'SMITHS_GUILD_SETTINGS'; const SMITHS_GUILD_PARALLEL_WORK = 'SMITHS_GUILD_PARALLEL_WORK'; const SMITHS_GUILD_INFO_FIRST = 'SMITHS_GUILD_INFO_V4_1'; const SMITHS_GUILD_INFO_SECOND = 'SMITHS_GUILD_INFO_V4_2'; const SMITHS_GUILD_NOTIFICATION_IS_SHOWN = 'SMITHS_GUILD_NOTIFICATION_IS_SHOWN_V2'; const SMITH_FREE = '\u041A\u0443\u0437\u043D\u0438\u0446\u0430 \u0441\u0432\u043E\u0431\u043E\u0434\u043D\u0430!'; // Кузница свободна if (!/home.php/.test(location.href)) { initNotificationsOnNonHome(); return; } const smithsLevel = level("https://dcdn.heroeswm.ru/i/pl_info/icons/guild_blacksmiths.png"); const modLevel = level("https://dcdn.heroeswm.ru/i/pl_info/icons/guild_armourers.png"); const parallelWork = smithsLevel == 9 || modLevel == 5; localStorage.setItem(SMITHS_GUILD_PARALLEL_WORK, parallelWork); const smithGuildInfoContentDiv = createSmithsInfoDOM(); let finishScript = false; let savedGuildInfo = getWithExpiry(SMITHS_GUILD_INFO_FIRST); if (savedGuildInfo != null) { displaySmithsGuildInfo(savedGuildInfo.workedOnText, savedGuildInfo.timeToFinishText, savedGuildInfo.finishTimeValues); if (!parallelWork) { return; } finishScript = true; } else { localStorage.removeItem(SMITHS_GUILD_INFO_SECOND); } savedGuildInfo = getWithExpiry(SMITHS_GUILD_INFO_SECOND); if (savedGuildInfo != null) { smithGuildInfoContentDiv.append(document.createElement('hr')); displaySmithsGuildInfo(savedGuildInfo.workedOnText, savedGuildInfo.timeToFinishText, savedGuildInfo.finishTimeValues); finishScript = true; } else { localStorage.removeItem(SMITHS_GUILD_INFO_FIRST); } if (finishScript) { return; } requestSmithInfo(); //*************************************************************************** function createSmithsInfoDOM() { const smithGuildInfoDiv = document.createElement('div'); smithGuildInfoDiv.className += "home_container_block"; smithGuildInfoDiv.style = "align-items: left;" const smithGuildInfoHeader = document.createElement('div'); smithGuildInfoHeader.className += "global_container_block_header global_a_hover"; smithGuildInfoHeader.innerHTML = '<a href="/mod_workbench.php"">\u0413\u0438\u043B\u044C\u0434\u0438\u044F \u041A\u0443\u0437\u043D\u0435\u0446\u043E\u0432</a>'; //Гильдия Кузнецов smithGuildInfoDiv.append(smithGuildInfoHeader); const notifyMeLink = document.createElement('a'); notifyMeLink.style = 'cursor: pointer'; notifyMeLink.id = 'smithGuildNotifier'; smithGuildInfoHeader.append(notifyMeLink); const smithGuildInfoContentDiv = document.createElement('div'); smithGuildInfoContentDiv.className += "home_inside_margins global_a_hover"; smithGuildInfoDiv.append(smithGuildInfoContentDiv); const workerGuild = document.querySelector(".home_work_block"); workerGuild.after(smithGuildInfoDiv); return smithGuildInfoContentDiv; } //*************************************************************************** function requestSmithInfo() { const xhr = new XMLHttpRequest(); xhr.open('GET', encodeURI("/mod_workbench.php")); xhr.overrideMimeType('text/xml; charset=windows-1251'); xhr.onload = function () { if (xhr.status === 200) { const div = document.createElement('div'); div.id = 'kom-smiths'; div.style.display = 'none'; div.innerHTML = xhr.responseText; document.getElementsByTagName('body')[0].appendChild(div); const respDoc = document.getElementsByTagName('body')[0].lastChild; if (!/\u0418\u0434\u0435\u0442 \u0440\u0430\u0431\u043E\u0442\u0430 \u043D\u0430\u0434/.test(respDoc.innerText)) { //Идёт работа над const noWorkSpan = document.createElement('span'); noWorkSpan.innerHTML += SMITH_FREE; smithGuildInfoContentDiv.append(noWorkSpan); return; } const documentSmithTables = Array.from(respDoc.querySelectorAll("table[align=center]")); const smithTable = documentSmithTables[documentSmithTables.length - 1]; const { workedOnText, finishTimeValues, expiration } = saveSmithsTable(smithTable, SMITHS_GUILD_INFO_FIRST); displaySmithsGuildInfo(workedOnText, expiration, finishTimeValues); if(parallelWork){ const anotherSmithTable = documentSmithTables[documentSmithTables.length - 2] if (anotherSmithTable.querySelector("td[colspan]").innerText.trim() !== '') { const { workedOnText, finishTimeValues, expiration } = saveSmithsTable(anotherSmithTable, SMITHS_GUILD_INFO_SECOND); smithGuildInfoContentDiv.append(document.createElement('hr')); displaySmithsGuildInfo(workedOnText, expiration, finishTimeValues); } } respDoc.remove(); } else { console.log('Request failed. Returned status of ' + xhr.status); } }; xhr.send(); } //*************************************************************************** function displaySmithsGuildInfo(workedOnText, timeToFinishText, finishTimeValues) { const notifyMeLink = document.querySelector("#smithGuildNotifier"); let notificationCancellation = null; let isNotify = localStorage.getItem(SMITHS_GUILD_SETTINGS, 'false') == 'true'; notificationCancellation = createCancellableNotificationWithLink(isNotify, notificationCancellation, notifyMeLink, timeToFinishText - Date.now()); notifyMeLink.onclick = () => { isNotify = !isNotify; notificationCancellation = createCancellableNotificationWithLink(isNotify, notificationCancellation, notifyMeLink, timeToFinishText - Date.now()); localStorage.setItem(SMITHS_GUILD_SETTINGS, isNotify); }; const workedOnSpan = document.createElement('span'); workedOnSpan.innerText = workedOnText; smithGuildInfoContentDiv.append(workedOnSpan); smithGuildInfoContentDiv.append(document.createElement('br')); const timeToFinishSpan = document.createElement('span'); timeToFinishSpan.innerHTML = '\u0412 \u0440\u0435\u043C\u043E\u043D\u0442\u0435: \u0435\u0449\u0435 ' + formatFinishedTime(timeToFinishText); // В ремонте ещё smithGuildInfoContentDiv.append(timeToFinishSpan); smithGuildInfoContentDiv.append(document.createElement('br')); const finishTimeSpan = document.createElement('span'); const finishTimeText = finishTimeValues[0]; const finishDateTimeText = finishTimeValues[1]; finishTimeSpan.innerHTML = finishTimeText + ': <a href="/mod_workbench.php" style="text-decoration:underline;">' + finishDateTimeText + '</a>'; smithGuildInfoContentDiv.append(finishTimeSpan); } //*************************************************************************** function saveSmithsTable(smithTable, smithGuildInfoName) { const workedOnText = smithTable.querySelector("td[colspan]").innerText.trim(); const finishTimeValues = smithTable.querySelector("td>table").querySelector("td").innerText.split(': '); const expiration = parseGuildDateTime(finishTimeValues[1]).getTime() + 1000 * 60; localStorage.setItem(SMITHS_GUILD_NOTIFICATION_IS_SHOWN, 'false'); setWithExpiry(smithGuildInfoName, { workedOnText: workedOnText, timeToFinishText: expiration, finishTimeValues: finishTimeValues, }, expiration); return {workedOnText, finishTimeValues, expiration}; } //*************************************************************************** function formatFinishedTime(finishTime) { const diff = finishTime - Date.now(); const diffDays = Math.floor(diff / 86400000); // days const diffHrs = Math.floor((diff % 86400000) / 3600000); // hours const diffMins = Math.round(((diff % 86400000) % 3600000) / 60000); // minutes let dateString = ''; if (diffDays > 0) { dateString += diffDays + ' \u0434. '; } if (diffHrs > 0) { dateString += diffHrs + ' \u0447. '; } if (diffMins > 0) { dateString += diffMins + ' \u043C\u0438\u043D.'; } if(dateString == ''){ const diffSecs = Math.round((((diff % 86400000) % 3600000) % 60000)/1000); // seconds dateString += diffSecs + ' \u0441\u0435\u043a.'; } return dateString; } //*************************************************************************** function parseGuildDateTime(dateString) { dateString = dateString.split(' '); const datef = dateString[0].split('-'); const date = new Date(datef[1] + '-' + datef[0] + '-' + (new Date().getFullYear())); const time = dateString[1].split(':'); date.setHours(time[0], time[1], 0); return date; } //*************************************************************************** function setWithExpiry(key, value, expirationTime) { const item = { value: value, expiry: expirationTime, } localStorage.setItem(key, JSON.stringify(item)) } //*************************************************************************** function getWithExpiry(key) { const itemStr = localStorage.getItem(key); // if the item doesn't exist, return null if (!itemStr) { return null } const item = JSON.parse(itemStr); const now = new Date(); // compare the expiry time of the item with the current time if (now.getTime() > item.expiry) { // If the item is expired, delete the item from storage // and return null localStorage.removeItem(key); return null } return item.value } //*************************************************************************** function createCancellableNotificationWithLink(isNotify, notificationCancellation, notifyMeLink, delay) { if (isNotify) { notifyMeLink.innerHTML = ' (!)'; notifyMeLink.title = 'Уведомление об окончании работ: включено'; } else { notifyMeLink.innerHTML = ' (#)'; notifyMeLink.title = 'Уведомление об окончании работ: выключено'; } return createCancellableNotification(isNotify, notificationCancellation, delay); } function createCancellableNotification(isNotify, notificationCancellation, delay) { if (localStorage.getItem(SMITHS_GUILD_NOTIFICATION_IS_SHOWN) == 'true') { return null; } if (isNotify) { notificationCancellation = notifyAfter(delay, SMITH_FREE); } else { if (notificationCancellation != null) { clearTimeout(notificationCancellation); } } return notificationCancellation; } //*************************************************************************** function notifyAfter(delay, text) { let notify = alert; let cancellation = null; cancellation = setTimeout(() => { localStorage.setItem(SMITHS_GUILD_NOTIFICATION_IS_SHOWN, 'true'); notify(text) }, delay > 0 ? delay : 1000); Notification.requestPermission((permission) => { if (permission === 'granted') { notify = (text) => new Notification(text); } }); return cancellation; } //*************************************************************************** function level(link) { const levelText = document.body.querySelector('img[src="' + link + '"]').parentElement.parentElement.querySelector('#bartext').innerText; return parseInt(levelText); } //*************************************************************************** function initNotificationsOnNonHome() { const isNotify = localStorage.getItem(SMITHS_GUILD_SETTINGS, 'false') == 'true'; const parallelWork = localStorage.getItem(SMITHS_GUILD_PARALLEL_WORK, 'false') == 'true'; const savedGuildInfoFirst = getWithExpiry(SMITHS_GUILD_INFO_FIRST); if (savedGuildInfoFirst == null) { return; } createCancellableNotification(isNotify, null, savedGuildInfoFirst.timeToFinishText - Date.now()); if (!parallelWork) { return; } const savedGuildInfoSecond = getWithExpiry(SMITHS_GUILD_INFO_SECOND); if (savedGuildInfoSecond == null) { return; } createCancellableNotification(isNotify, null, savedGuildInfoSecond.timeToFinishText - Date.now()); return; }