您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Время с секундами
当前为
// ==UserScript== // @name hwmTime // @author Tamozhnya1 // @namespace Tamozhnya1 // @description Время с секундами // @version 4.8 // @encoding utf-8 // @include *heroeswm.ru/* // @include *lordswm.com/* // @exclude */rightcol.php* // @exclude */ch_box.php* // @exclude */chat* // @exclude */ticker.html* // @exclude */frames* // @exclude */brd.php* // @grant GM_deleteValue // @grant GM_getValue // @grant GM_setValue // @license MIT // ==/UserScript== 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]; }; let timePanel; let online; let serverClientLastRequestedTimeDeltaMilliseconds; const ClientServerTimeDeltaRequestInterval = 60 * 60 * 1000; main(); function main() { if(document.querySelector("body")) { let timePanelData = findTimePanel(); if(!timePanelData) { return; } timePanel = timePanelData.TimePanel; online = timePanelData.Online; timePanel.addEventListener("click", showSettings, false); validateSavedInterval(timePanelData.PageEnterHours, timePanelData.PageEnterMinutes); refreshTimePanel(); } } function validateSavedInterval(pageEnterHours, pageEnterMinutes) { serverClientLastRequestedTimeDeltaMilliseconds = parseInt(GM_getValue("hwmTimeServerClientLastRequestedTimeDeltaMilliseconds", 0)); let forceServerIntervalRequest = false; if(!GM_getValue("hwmTimeServerClientLastRequestedTimeDeltaMilliseconds")) { forceServerIntervalRequest = true; } let badServerTimeApproximation = !validateEstimatedTimeByPageEnterTime(pageEnterHours, pageEnterMinutes); if(badServerTimeApproximation) { let clientNow = new Date(); let dirtyServerTime = new Date(clientNow.getFullYear(), clientNow.getMonth(), clientNow.getDate(), pageEnterHours, pageEnterMinutes); serverClientLastRequestedTimeDeltaMilliseconds = (new Date()).getTime() - dirtyServerTime.getTime(); GM_setValue("hwmTimeServerClientLastRequestedTimeDeltaMilliseconds", serverClientLastRequestedTimeDeltaMilliseconds); forceServerIntervalRequest = true; } requestServerTime(forceServerIntervalRequest); } function findTimePanel() { const isNewInterface = document.querySelector("div.mm_item") ? true : false; if(isNewInterface) { const timeTemplate = /(\d+):(\d+)(:\d{2})?/; let div1 = document.querySelector("div.sh_extra.sh_extra_right"); let divs = div1.querySelectorAll("div"); for(const div of divs) { if(/\d+:\d+(:\d{2})?/.test(div.innerHTML)) { let timeText = timeTemplate.exec(div.innerText); console.log([div.innerHTML, div.innerText, timeText]); let pageEnterHours = parseInt(timeText[1]); let pageEnterMinutes = parseInt(timeText[2]); return { TimePanel: div, PageEnterHours: pageEnterHours, PageEnterMinutes: pageEnterMinutes, Online: "" }; } } } else { const timeAndOnlineTemplate = /(\d+):(\d+)(:\d{2})?, \d+ online/; for(const currentCell of document.getElementsByTagName('td')) { if(currentCell.innerHTML.indexOf("<td") != -1 || currentCell.innerHTML.search(timeAndOnlineTemplate) == -1) { continue; } online = (/([^,]*)(, \d+ online.*)/.exec(currentCell.innerHTML))[2]; let timeText = timeAndOnlineTemplate.exec(currentCell.innerHTML); let pageEnterHours = parseInt(timeText[1]); let pageEnterMinutes = parseInt(timeText[2]); return { TimePanel: currentCell, PageEnterHours: pageEnterHours, PageEnterMinutes: pageEnterMinutes, Online: online }; } } const timeAndOnlineTemplate = /(\d+):(\d+)(:\d{2})?, \d+ online/; for(const currentCell of document.querySelectorAll('span')) { if(currentCell.innerHTML.indexOf("<span") != -1 || currentCell.innerHTML.search(timeAndOnlineTemplate) == -1) { continue; } online = (/([^,]*)(, \d+ online.*)/.exec(currentCell.innerHTML))[2]; let timeText = timeAndOnlineTemplate.exec(currentCell.innerHTML); let pageEnterHours = parseInt(timeText[1]); let pageEnterMinutes = parseInt(timeText[2]); return { TimePanel: currentCell, PageEnterHours: pageEnterHours, PageEnterMinutes: pageEnterMinutes, Online: online }; } } function validateEstimatedTimeByPageEnterTime(pageEnterHours, pageEnterMinutes) { // Правильным результатом считаем точное совпадение часов и минут, с учетом того, что нам нужна точность до милисекунды const trueTime = getEstimatedServerTime(); //console.log([pageEnterHours, trueTime.getHours(), pageEnterMinutes, trueTime.getMinutes()]); if(trueTime.getHours() == pageEnterHours && trueTime.getMinutes() == pageEnterMinutes) { return true; } // // Правильным результатом считаем разницу не более минуты, с учетом того, что время на странице имеет точность в минуту // if(trueTime.getHours() == pageEnterHours && Math.abs(trueTime.getMinutes() - pageEnterMinutes) == 1) { // return true; // } // if(trueTime.getHours() == pageEnterHours + 1 && trueTime.getMinutes() == 0 && pageEnterMinutes == 59) { // return true; // } // if(pageEnterHours == trueTime.getHours() + 1 && pageEnterMinutes == 0 && trueTime.getMinutes() == 59) { // return true; // } // if(trueTime.getHours() == 0 && pageEnterHours == 23 && trueTime.getMinutes() == 0 && pageEnterMinutes == 59) { // return true; // } // if(pageEnterHours == 0 && trueTime.getHours() == 23 && pageEnterMinutes == 0 && trueTime.getMinutes() == 59) { // return true; // } return false; } function requestServerTime(force) { if(force || parseInt(GM_getValue("hwmTimeLastSyncClientTimeMilliseconds", 0)) + ClientServerTimeDeltaRequestInterval < (new Date().getTime())) { GM_setValue("hwmTimeLastSyncClientTimeMilliseconds", new Date().getTime()); const objXMLHttpReqTime = new XMLHttpRequest(); objXMLHttpReqTime.open('GET', 'time.php?rand=' + (Math.random() * 1000000), true); objXMLHttpReqTime.onreadystatechange = function() { handleHttpResponseTime(objXMLHttpReqTime); } objXMLHttpReqTime.send(null); } else { setTimeout(function() { requestServerTime(); }, ClientServerTimeDeltaRequestInterval); } } function handleHttpResponseTime(obj) { if(obj.readyState == 4 && obj.status == 200) { let responseParcing = /now (\d+)/.exec(obj.responseText); //obj.responseText: now 1681711364 17-04-23 09:02 if(responseParcing) { let serverUtcTime = parseInt(responseParcing[1]) * 1000 + parseInt(GM_getValue("hwmTimeAddingIntervalMilliseconds", 0)); serverClientLastRequestedTimeDeltaMilliseconds = new Date().getTime() - serverUtcTime; GM_setValue("hwmTimeServerClientLastRequestedTimeDeltaMilliseconds", serverClientLastRequestedTimeDeltaMilliseconds); GM_deleteValue("hwmTimeServerResponseErrorsCount"); refreshTimePanel(); } else { GM_setValue("hwmTimeServerResponseErrorsCount", parseInt(GM_getValue("hwmTimeServerResponseErrorsCount", 0)) + 1); setTimeout(function() { requestServerTime(); }, 60 * 1000); } } } function refreshTimePanel() { const trueTime = getEstimatedServerTime(); timePanel.innerHTML = trueTime.getHours() + ':' + ( (trueTime.getMinutes() < 10) ? '0' : '' ) + trueTime.getMinutes() + ':' + (trueTime.getSeconds() < 10 ? '0' : '') + trueTime.getSeconds() + online; setTimeout(function() { refreshTimePanel(); }, 1000); } function getEstimatedServerTime() { return new Date((new Date().getTime()) - serverClientLastRequestedTimeDeltaMilliseconds); } function showSettings() { if(showPupupPanel(GM_info.script.name)) { return; } const fieldsMap = []; const isEn = document.documentElement.lang == "en"; fieldsMap.push(["ServerResponseErrorsCount:", `${parseInt(GM_getValue("hwmTimeServerResponseErrorsCount", 0))}`]); fieldsMap.push(["ClientServerLastRequestedTimeDifferenceMilliseconds:", `${parseInt(GM_getValue("hwmTimeServerClientLastRequestedTimeDeltaMilliseconds", 0))}`]); fieldsMap.push(["LastClientServerSyncDate:", `${new Date(parseInt(GM_getValue("hwmTimeLastSyncClientTimeMilliseconds", 0)))}`]); const hwmTimeAddingIntervalInput = createElement("input", { id: "hwmTimeAddingIntervalInput", type: "number", value: `${ GM_getValue("hwmTimeAddingIntervalMilliseconds", 0) }`, onfocus: `this.select();` }); hwmTimeAddingIntervalInput.addEventListener("change", function() { GM_setValue("hwmTimeAddingIntervalMilliseconds", parseInt(this.value)); }, false); fieldsMap.push([`${isEn ? 'Add time to page loading (ms.)' : ustring("Добавлять время на загрузку страницы (мс.)")}`, hwmTimeAddingIntervalInput]); const hwmTimeRestartScriptSubmit = createElement("input", { id: "hwmTimeRestartScriptSubmit", type: "submit", value: `${isEn ? 'Restart the script' : ustring("Перезапустить скрипт")}` }); hwmTimeRestartScriptSubmit.addEventListener("click", resetScript, false); fieldsMap.push([hwmTimeRestartScriptSubmit]); createPupupPanel(GM_info.script.name, "Настройки " + GM_info.script.name, fieldsMap); } function resetScript() { GM_deleteValue("hwmTimeServerResponseErrorsCount"); GM_deleteValue("hwmTimeServerClientLastRequestedTimeDeltaMilliseconds"); GM_deleteValue("hwmTimeLastSyncClientTimeMilliseconds"); hidePupupPanel(GM_info.script.name); main(); } function createPupupPanel(panelName, panelTitle, fieldsMap) { let backgroundPopupPanel = addElement("div", document.body, { id: panelName + "1", style: "position: absolute; left: 0pt; width: 100%; background: none repeat scroll 0% 0% gray; opacity: 0.5; top: 0px; height: 100%; display: block; z-index: 200;" }); backgroundPopupPanel.addEventListener("click", function() { hidePupupPanel(panelName); }, false); let popupPanel = addElement("div", document.body, { id: panelName + "2", style: `position: absolute; width: 650px; background: none repeat scroll 0% 0%; background-image: linear-gradient(to right, #eea2a2 0%, #bbc1bf 19%, #57c6e1 42%, #b49fda 79%, #7ac5d8 100%); left: ${((document.body.offsetWidth - 650) / 2)}px; top: 150px; display: block; z-index: 200; border: 4mm ridge rgba(211, 220, 50, .6);` }); let contentDiv = addElement("div", popupPanel, { id: panelName + "3", style: "border: 1px solid #abc; padding: 5px; margin: 2px; display: flex; flex-wrap: wrap;" }); if(panelTitle) { addElement("b", contentDiv, { innerText: panelTitle, style: "text-align: center; margin: auto; width: 90%; display: block;" }); } let divClose = addElement("div", contentDiv, {id: panelName + "close", title: "Close", innerText: "x", style: "border: 1px solid #abc; width: 15px; height: 15px; text-align: center; cursor: pointer;" }); divClose.addEventListener("click", function() { hidePupupPanel(panelName); }, false); addElement("div", contentDiv, { style: "flex-basis: 100%; height: 0;"}); if(fieldsMap) { let contentTable = addElement("table", contentDiv); for(let rowData of fieldsMap) { if(rowData.length == 0) { // Спомощью передачи пустой стороки-массива, указываем, что надо начать новую таблицу после брейка addElement("div", contentDiv, { style: "flex-basis: 100%; height: 0;"}); contentTable = addElement("table", contentDiv); continue; } const row = addElement("tr", contentTable); for(let cellData of rowData) { const cell = addElement("td", row); if(cellData) { if(typeof(cellData) == "string") { cell.innerText = cellData; } else { cell.appendChild(cellData); } } } } } return contentDiv; } function showPupupPanel(panelName) { let backgroundPopupPanel = document.getElementById(panelName + "1"); let popupPanel = document.getElementById(panelName + "2"); if(backgroundPopupPanel) { backgroundPopupPanel.style.display = popupPanel.style.display = 'block'; return true; } return false; } function hidePupupPanel(panelName) { let backgroundPopupPanel = document.getElementById(panelName + "1"); let popupPanel = document.getElementById(panelName + "2"); backgroundPopupPanel.style.display = popupPanel.style.display = 'none'; } function addElement(type, parent, data) { let el = createElement(type, data); if(parent) { parent.appendChild(el); } return el; } function createElement(type, data) { let el = document.createElement(type); if(data) { for(let key in data) { if(key == "innerText" || key == "innerHTML") { el[key] = data[key]; } else { el.setAttribute(key, data[key]); } } } return el; } 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); let result = ""; for(let i = 0; i < s.length; i++) { result += uchar(s[i]); } return result; }