您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
try to take over the world!
// ==UserScript== // @name HWM Pointer // @namespace https://gf.zukizuki.org/ru/scripts/424028-hwm-pointer // @version 0.4 // @description try to take over the world! // @author achepta // @include /^https{0,1}:\/\/((www|qrator|my)(\.heroeswm\.ru|\.lordswm\.com)|178\.248\.235\.15)\/war\.php.+/ // @grant unsafeWindow // @grant GM_xmlhttpRequest // @grant GM_log // @run-at document-end // ==/UserScript== (function (window, undefined) { //TODO add message processing queue let w; if (typeof unsafeWindow !== undefined) { w = unsafeWindow; } else { w = window; } if (w.self !== w.top) { return; } let allPlayers = getPlayers() let coordsData = "" let isPressed = false let allMessages = getAllMessages() let isSettingsOpened = false; let defaultSettings = getDefaultSettings() let settings = {} loadSettings() setInterval(checkChatForCoords, 300) function checkChatForCoords() { let newMessages = getAllMessages(); if (newMessages.length > allMessages.length) { allMessages = newMessages checkMessageForCoords(allMessages.slice(-1)[0]) } } function checkMessageForCoords(msg) { if (msg.includes("!")) { let coords = findAll(/\|(\d{1,2}):(\d{1,2})/, msg) if (coords.length > 0) { setChatCoordsListener(coords) highlightCoords(coords) } } } function setChatCoordsListener(coords) { let msgWithCoords = Array.from(getChat().getElementsByTagName("b")).slice(-1)[0] msgWithCoords.id = "coords" + allMessages.length $(`coords${allMessages.length}`).addEventListener('mouseover', () => showCoordsMouse(coords)) $(`coords${allMessages.length}`).addEventListener('mouseout', () => hideCoordsMouse(coords)) } function showCoordsMouse(coords) { coords.forEach(coordinate => { showCoords(coordinate) }) } function hideCoordsMouse(coords) { coords.forEach(coordinate => { hideCoords(coordinate) }) } function highlightCoords(coords) { coords.forEach(coordinate => { showCoords(coordinate) setTimeout(() => { hideCoords(coordinate) }, settings.duration) }) } function showCoords(coordinate) { shado[(coordinate[1] - 0) + (coordinate[2] - 0) * defxn].stroke(settings.color); shado[(coordinate[1] - 0) + (coordinate[2] - 0) * defxn].fill(settings.color); set_visible(shado[(coordinate[1] - 0) + (coordinate[2] - 0) * defxn], 1); } function hideCoords(coordinate) { shado[(coordinate[1] - 0) + (coordinate[2] - 0) * defxn].stroke('red'); shado[(coordinate[1] - 0) + (coordinate[2] - 0) * defxn].fill(null); set_visible(shado[(coordinate[1] - 0) + (coordinate[2] - 0) * defxn], 0); } window.addEventListener("keydown", e => { if ((document.querySelector("#chattext") !== document.activeElement) && (document.querySelector("#chattext_classic") !== document.activeElement)) { if (!isSettingsOpened && e.shiftKey && ["f", "F", "а", "А"].includes(e.key)) { isSettingsOpened = true; openSettings() e.preventDefault() return } if (!isSettingsOpened && ["f", "F", "а", "А"].includes(e.key)) { if (!isPressed) { coordsData = ""; coordsData += "|" + xr_last + ":" + yr_last isPressed = true } } } }) window.addEventListener("keyup", e => { if ((document.querySelector("#chattext") !== document.activeElement) && (document.querySelector("#chattext_classic") !== document.activeElement)) { if (!isSettingsOpened && ["f", "F", "а", "А"].includes(e.key)) { let newCoords = "|" + xr_last + ":" + yr_last if (newCoords !== coordsData) { coordsData += " " + newCoords } isPressed = false createAndSendMessage(); } } }) function openSettings() { showEmptyBackground(); document.body.insertAdjacentHTML('beforeend', getSettingsTemplate()) fillSettings() } function showEmptyBackground() { document.body.insertAdjacentHTML('beforeend', getEmptyBackgroundTemplate()); $('empty_background').addEventListener('click', handleOnBackgroundClick); } function hideEmptyBackground() { removeElement($('empty_background')) } function fillSettings() { $('coords-color').addEventListener('input', () => { handleChangeColor() }) $('coords-duration-btn').addEventListener('click', () => { handleChangeDuration() }) $('coords-duration').addEventListener('keyup', e => { if (e.key === 'Enter' || e.keyCode === 13) { handleChangeDuration() } }) } function handleChangeDuration() { let inputValue = $('coords-duration').value - 0 if (!isNaN(inputValue) && inputValue !== 0) { settings.duration = inputValue handleSettingsChange() } } function handleChangeColor() { settings.color = $('coords-color').value handleSettingsChange() } function handleSettingsChange() { set('hwm_pointer_settings', settings) } function hideSettings() { removeElement($('hwm_pointer_settings')) } function handleOnBackgroundClick() { isSettingsOpened = false; hideEmptyBackground(); hideSettings(); } function getEmptyBackgroundTemplate() { return ` <div id="empty_background" style=" position: fixed; left: 0; top: 0; width: 100%; height: 100%; background: #000000; opacity: 0.5; z-index: 11000001; "></div> ` } function getSettingsTemplate() { return ` <div id="hwm_pointer_settings" style=" position: fixed; left: ${(getClientWidth() - 300) / 2}px; top: ${window.pageYOffset + 155}px; width: 300px; background: #F6F3EA; z-index: 11000002; padding: 20px;"> <label for="coords-color">Select your favorite color:</label> <input type="color" id="coords-color" name="coords-color" value="${settings.color}"> <br> <span>Duration in ms <input id="coords-duration" type="text" style="width: 40px" value="${settings.duration}"> <button id="coords-duration-btn">OK</button></span> </div> ` } function createAndSendMessage() { if (allPlayers.includes(player.toString())) { coordsData = "!" + coordsData } sentCoords(coordsData) } function getPlayers() { let battleData = unsafeWindow.run_all.toString() let battlePlayers = findAll(/plid\d\|(\d{1,10})/, battleData) return battlePlayers.map(player => player[1]) } function getAllMessages() { return getChat().innerHTML.split("<br>").slice(0, -1) } function getChat() { if (isVisible(document.querySelector("#chat_inside"))) { return document.querySelector("#chat_inside") } else { return document.querySelector("#chat_classic_inside") } } function isVisible(element) { return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length); } function sentCoords(msg) { chatloader.loading = true; let formData = new FormData(); formData.append("warid", warid) formData.append("chat", 1) let pl_id = player; if (player2 > 0) { pl_id = player2; } formData.append("pl_id", pl_id) formData.append("mess", encodeURIComponent(getunicode(msg))) formData.append("lastturn", lastturn) formData.append("lastmess", lastmess) formData.append("lastmess2", lastmess2) if (crclink != 0) { formData.append("show_for_all", crclink) } const str = [...formData.entries()] .map(x => `${x[0]}=${x[1]}`) .join('&') chatloader_load(str); window.scrollTo(0, 0); } function findAll(regexPattern, sourceString) { let output = [] let match let regexPatternWithGlobal = RegExp(regexPattern, [...new Set("g" + regexPattern.flags)].join("")) while (match = regexPatternWithGlobal.exec(sourceString)) { delete match.input output.push(match) } return output } function removeElement(element) { element.parentNode.removeChild(element) } function $(id, where = document) { return where.querySelector(`#${id}`); } function get(key, def) { let result = JSON.parse(localStorage[key] === undefined ? null : localStorage[key]); return result == null ? def : result; } function set(key, val) { localStorage[key] = JSON.stringify(val); } function getClientWidth() { return document.compatMode === 'CSS1Compat' && document.documentElement ? document.documentElement.clientWidth : document.body.clientWidth; } function getDefaultSettings() { return { "color": "#FF0000", "duration": 2000 } } function loadSettings() { settings = get('hwm_pointer_settings', defaultSettings) for (const [key, value] of Object.entries(defaultSettings)) { if (settings[key] === undefined) { settings[key] = value } } } })(window);